diff --git a/extensions/compat_xtables.c b/extensions/compat_xtables.c index 438047a..9ab4785 100644 --- a/extensions/compat_xtables.c +++ b/extensions/compat_xtables.c @@ -20,11 +20,6 @@ #include "compat_skbuff.h" #include "compat_xtnu.h" -#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19) -typedef __u16 __bitwise __sum16; -typedef __u32 __bitwise __wsum; -#endif - #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 22) static int xtnu_match_run(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, @@ -452,17 +447,23 @@ void xtnu_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb, __be32 from, __be32 to, bool pseudohdr) { __be32 diff[] = {~from, to}; + const void *dv = diff; /* kludge for < v2.6.19-555-g72685fc */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) if (skb->ip_summed != CHECKSUM_PARTIAL) { - *sum = csum_fold(csum_partial(diff, sizeof(diff), + *sum = csum_fold(csum_partial(dv, sizeof(diff), ~csum_unfold(*sum))); if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) - skb->csum = ~csum_partial(diff, sizeof(diff), + skb->csum = ~csum_partial(dv, sizeof(diff), ~skb->csum); } else if (pseudohdr) { - *sum = ~csum_fold(csum_partial(diff, sizeof(diff), + *sum = ~csum_fold(csum_partial(dv, sizeof(diff), csum_unfold(*sum))); } +#else + *sum = csum_fold(csum_partial(dv, sizeof(diff), + ~csum_unfold(*sum))); +#endif } EXPORT_SYMBOL_GPL(xtnu_proto_csum_replace4); #endif diff --git a/extensions/compat_xtables.h b/extensions/compat_xtables.h index 1187dfa..77ea3b4 100644 --- a/extensions/compat_xtables.h +++ b/extensions/compat_xtables.h @@ -37,6 +37,7 @@ #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19) # define neigh_hh_output xtnu_neigh_hh_output # define IPPROTO_UDPLITE 136 +# define CSUM_MANGLED_0 ((__force __sum16)0xffff) #endif #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24) @@ -70,6 +71,7 @@ #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19) # define csum_replace2 xtnu_csum_replace2 # define csum_replace4 xtnu_csum_replace4 +# define inet_proto_csum_replace4 xtnu_proto_csum_replace4 #elif LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24) # define csum_replace2 nf_csum_replace2 # define csum_replace4 nf_csum_replace4 diff --git a/extensions/compat_xtnu.h b/extensions/compat_xtnu.h index 0a19082..6e6620a 100644 --- a/extensions/compat_xtnu.h +++ b/extensions/compat_xtnu.h @@ -9,6 +9,10 @@ typedef _Bool bool; enum { false = 0, true = 1, }; #endif +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19) +typedef __u16 __bitwise __sum16; +typedef __u32 __bitwise __wsum; +#endif struct flowi; struct hh_cache; @@ -122,6 +126,13 @@ static inline struct xtnu_target *xtcompat_nutarget(const struct xt_target *t) return q; } +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 19) +static inline __wsum csum_unfold(__sum16 n) +{ + return (__force __wsum)n; +} +#endif + extern int xtnu_ip_local_out(struct sk_buff *); extern int xtnu_ip_route_me_harder(struct sk_buff **, unsigned int); extern int xtnu_skb_make_writable(struct sk_buff **, unsigned int); diff --git a/extensions/xt_RAWNAT.c b/extensions/xt_RAWNAT.c index 6184524..18661a9 100644 --- a/extensions/xt_RAWNAT.c +++ b/extensions/xt_RAWNAT.c @@ -79,6 +79,7 @@ static void rawnat4_update_l4(struct sk_buff *skb, __be32 oldip, __be32 newip) void *transport_hdr = (void *)iph + ip_hdrlen(skb); struct tcphdr *tcph; struct udphdr *udph; + bool cond; switch (iph->protocol) { case IPPROTO_TCP: @@ -88,7 +89,11 @@ static void rawnat4_update_l4(struct sk_buff *skb, __be32 oldip, __be32 newip) case IPPROTO_UDP: case IPPROTO_UDPLITE: udph = transport_hdr; - if (udph->check != 0 || skb->ip_summed == CHECKSUM_PARTIAL) { + cond = udph->check != 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + cond |= skb->ip_summed == CHECKSUM_PARTIAL; +#endif + if (cond) { inet_proto_csum_replace4(&udph->check, skb, oldip, newip, true); if (udph->check == 0) @@ -200,6 +205,7 @@ static void rawnat6_update_l4(struct sk_buff *skb, unsigned int l4proto, struct tcphdr *tcph; struct udphdr *udph; unsigned int i; + bool cond; switch (l4proto) { case IPPROTO_TCP: @@ -211,7 +217,11 @@ static void rawnat6_update_l4(struct sk_buff *skb, unsigned int l4proto, case IPPROTO_UDP: case IPPROTO_UDPLITE: udph = (void *)iph + l4offset; - if (udph->check != 0 || skb->ip_summed == CHECKSUM_PARTIAL) { + cond = udph->check; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + cond |= skb->ip_summed == CHECKSUM_PARTIAL; +#endif + if (cond) { for (i = 0; i < 4; ++i) inet_proto_csum_replace4(&udph->check, skb, oldip->s6_addr32[i],