diff options
author | Patrick McHardy <kaber@trash.net> | 2008-03-20 15:15:53 +0100 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2008-04-14 11:15:49 +0200 |
commit | d63a650736f566a1f9e9434725d2089597c0d2cc (patch) | |
tree | f0a3d5dbc9ced46f95582e4133b55bb70a1ae365 /net/netfilter/nf_conntrack_proto_udplite.c | |
parent | 6185f870e293a0a3eae5c81eb0106480cf03dfde (diff) | |
download | linux-stable-d63a650736f566a1f9e9434725d2089597c0d2cc.tar.gz linux-stable-d63a650736f566a1f9e9434725d2089597c0d2cc.tar.bz2 linux-stable-d63a650736f566a1f9e9434725d2089597c0d2cc.zip |
[NETFILTER]: Add partial checksum validation helper
Move the UDP-Lite conntrack checksum validation to a generic helper
similar to nf_checksum() and make it fall back to nf_checksum()
in case the full packet is to be checksummed and hardware checksums
are available. This is to be used by DCCP conntrack, which also
needs to verify partial checksums.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter/nf_conntrack_proto_udplite.c')
-rw-r--r-- | net/netfilter/nf_conntrack_proto_udplite.c | 33 |
1 files changed, 7 insertions, 26 deletions
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c index 9dd03c7aeac6..c3eaee6afffd 100644 --- a/net/netfilter/nf_conntrack_proto_udplite.c +++ b/net/netfilter/nf_conntrack_proto_udplite.c @@ -127,32 +127,13 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff, } /* Checksum invalid? Ignore. */ - if (nf_conntrack_checksum && !skb_csum_unnecessary(skb) && - hooknum == NF_INET_PRE_ROUTING) { - if (pf == PF_INET) { - struct iphdr *iph = ip_hdr(skb); - - skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, - udplen, IPPROTO_UDPLITE, 0); - } else { - struct ipv6hdr *ipv6h = ipv6_hdr(skb); - __wsum hsum = skb_checksum(skb, 0, dataoff, 0); - - skb->csum = ~csum_unfold( - csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, - udplen, IPPROTO_UDPLITE, - csum_sub(0, hsum))); - } - - skb->ip_summed = CHECKSUM_NONE; - if (__skb_checksum_complete_head(skb, dataoff + cscov)) { - if (LOG_INVALID(IPPROTO_UDPLITE)) - nf_log_packet(pf, 0, skb, NULL, NULL, NULL, - "nf_ct_udplite: bad UDPLite " - "checksum "); - return -NF_ACCEPT; - } - skb->ip_summed = CHECKSUM_UNNECESSARY; + if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && + nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP, + pf)) { + if (LOG_INVALID(IPPROTO_UDPLITE)) + nf_log_packet(pf, 0, skb, NULL, NULL, NULL, + "nf_ct_udplite: bad UDPLite checksum "); + return -NF_ACCEPT; } return NF_ACCEPT; |