From c4172cf85db0eceb0b3dd74a59076d1a52857ff5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 26 Apr 2011 15:14:17 +0200 Subject: Make modquicktun work on all kernels 2.6.{32..39} --- Makefile | 2 +- compat.h | 36 ++++++++++++++++++++++++++++++++++++ quicktun.c | 13 +++++++------ 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) { -- cgit v1.2.3