summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--compat.h36
-rw-r--r--quicktun.c13
3 files changed, 44 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index a26b6e8..a29db2e 100644
--- a/Makefile
+++ b/Makefile
@@ -16,4 +16,4 @@ endif
.PHONY: clean
clean:
- rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c *.markers *.symvers *.order
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c *.markers *.symvers *.order qtctl
diff --git a/compat.h b/compat.h
index 39cb8ac..b012255 100644
--- a/compat.h
+++ b/compat.h
@@ -7,6 +7,7 @@
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39)
+
static inline struct rtable *ip_route_output_ports(struct net *net, struct sock *sk,
__be32 daddr, __be32 saddr,
__be16 dport, __be16 sport,
@@ -31,6 +32,41 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct sock
return rt;
}
+
+#endif
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
+
+static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
+{
+ skb->dev = dev;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
+ skb->rxhash = 0;
+#endif
+
+ skb_set_queue_mapping(skb, 0);
+ skb_dst_drop(skb);
+ nf_reset(skb);
+}
+
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
+
+#define RTABLE_DST(rtable) (&(rtable)->u.dst)
+
+#else
+
+#define RTABLE_DST(rtable) (&(rtable)->dst)
+
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
+
+#define rcu_dereference_protected(p, c) rcu_dereference(p)
+
#endif
#endif /* __QUICKTUN_COMPAT_H */
diff --git a/quicktun.c b/quicktun.c
index 5d9724e..c44b2f1 100644
--- a/quicktun.c
+++ b/quicktun.c
@@ -74,14 +74,14 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev
goto error;
}
- if (rt->dst.dev == dev) {
+ if (RTABLE_DST(rt)->dev == dev) {
tun->dev->stats.collisions++;
goto error;
}
- if (skb_headroom(skb) < (LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) + sizeof(struct udphdr))
+ if (skb_headroom(skb) < (LL_RESERVED_SPACE(RTABLE_DST(rt)->dev) + sizeof(struct iphdr) + sizeof(struct udphdr))
|| skb_shared(skb) || (skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
- struct sk_buff *new_skb = skb_realloc_headroom(skb, LL_RESERVED_SPACE(rt->dst.dev) + sizeof(struct iphdr) + sizeof(struct udphdr));
+ struct sk_buff *new_skb = skb_realloc_headroom(skb, LL_RESERVED_SPACE(RTABLE_DST(rt)->dev) + sizeof(struct iphdr) + sizeof(struct udphdr));
if (!new_skb) {
tun->dev->stats.tx_dropped++;
goto error;
@@ -97,7 +97,7 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev
skb_reset_network_header(skb);
skb_dst_drop(skb);
- skb_dst_set(skb, &rt->dst);
+ skb_dst_set(skb, RTABLE_DST(rt));
iph = (struct iphdr *)skb->data;
iph->version = 4;
@@ -117,7 +117,7 @@ static netdev_tx_t quicktun_net_xmit(struct sk_buff *skb, struct net_device *dev
udph->len = htons(len + sizeof(struct udphdr));
udph->check = 0;
- ip_select_ident(ip_hdr(skb), &rt->dst, NULL);
+ ip_select_ident(ip_hdr(skb), RTABLE_DST(rt), NULL);
csum = csum_partial(udph, ntohs(udph->len), 0);
udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, ntohs(udph->len), IPPROTO_UDP, csum);
@@ -230,6 +230,8 @@ static void quicktun_udp_data_ready(struct sock *sk, int bytes)
len = skb->len;
+ __skb_tunnel_rx(skb, tun->dev);
+
switch (tun->flags & QUICKTUN_MODE_MASK) {
case QUICKTUN_MODE_ETHERNET:
if (len < ETH_HLEN)
@@ -241,7 +243,6 @@ static void quicktun_udp_data_ready(struct sock *sk, int bytes)
if (len < sizeof(struct iphdr))
goto drop;
- __skb_tunnel_rx(skb, tun->dev);
skb_reset_network_header(skb);
switch (skb->data[0] & 0xf0) {