summaryrefslogtreecommitdiff
path: root/net/netfilter
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-03-20 15:15:53 +0100
committerPatrick McHardy <kaber@trash.net>2008-04-14 11:15:49 +0200
commitd63a650736f566a1f9e9434725d2089597c0d2cc (patch)
treef0a3d5dbc9ced46f95582e4133b55bb70a1ae365 /net/netfilter
parent6185f870e293a0a3eae5c81eb0106480cf03dfde (diff)
[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')
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c33
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 9dd03c7aeac..c3eaee6afff 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;