summaryrefslogtreecommitdiff
path: root/net/ipv6/netfilter.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-04-14 03:50:43 -0700
committerDavid S. Miller <davem@davemloft.net>2008-04-14 03:50:43 -0700
commit334f8b2afd9652e20f67ddee4fec483ed860425b (patch)
tree35d4fb46a9dc145e831fe5da026f2bfd9ee6657c /net/ipv6/netfilter.c
parent7477fd2e6b676fcd15861c2a96a7172f71afe0a5 (diff)
parentef1a5a50bbd509b8697dcd4d13017e9e0053867b (diff)
downloadlinux-334f8b2afd9652e20f67ddee4fec483ed860425b.tar.gz
linux-334f8b2afd9652e20f67ddee4fec483ed860425b.tar.bz2
linux-334f8b2afd9652e20f67ddee4fec483ed860425b.zip
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.26
Diffstat (limited to 'net/ipv6/netfilter.c')
-rw-r--r--net/ipv6/netfilter.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index aed51bcc66b4..8c6c5e71f210 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -121,16 +121,44 @@ __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
}
return csum;
}
-
EXPORT_SYMBOL(nf_ip6_checksum);
+static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook,
+ unsigned int dataoff, unsigned int len,
+ u_int8_t protocol)
+{
+ struct ipv6hdr *ip6h = ipv6_hdr(skb);
+ __wsum hsum;
+ __sum16 csum = 0;
+
+ switch (skb->ip_summed) {
+ case CHECKSUM_COMPLETE:
+ if (len == skb->len - dataoff)
+ return nf_ip6_checksum(skb, hook, dataoff, protocol);
+ /* fall through */
+ case CHECKSUM_NONE:
+ hsum = skb_checksum(skb, 0, dataoff, 0);
+ skb->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
+ &ip6h->daddr,
+ skb->len - dataoff,
+ protocol,
+ csum_sub(0, hsum)));
+ skb->ip_summed = CHECKSUM_NONE;
+ csum = __skb_checksum_complete_head(skb, dataoff + len);
+ if (!csum)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+ return csum;
+};
+
static const struct nf_afinfo nf_ip6_afinfo = {
- .family = AF_INET6,
- .checksum = nf_ip6_checksum,
- .route = nf_ip6_route,
- .saveroute = nf_ip6_saveroute,
- .reroute = nf_ip6_reroute,
- .route_key_size = sizeof(struct ip6_rt_info),
+ .family = AF_INET6,
+ .checksum = nf_ip6_checksum,
+ .checksum_partial = nf_ip6_checksum_partial,
+ .route = nf_ip6_route,
+ .saveroute = nf_ip6_saveroute,
+ .reroute = nf_ip6_reroute,
+ .route_key_size = sizeof(struct ip6_rt_info),
};
int __init ipv6_netfilter_init(void)