diff options
author | Tom Herbert <therbert@google.com> | 2014-05-03 01:29:58 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-05 21:26:30 +0200 |
commit | 4068579e1e098fa81d48db9ba4432ab664c58561 (patch) | |
tree | 19aa4761b4381904203def58cf90abb6ae96cebe /net/ipv6/ip6_checksum.c | |
parent | net: Call skb_checksum_init in IPv6 (diff) | |
download | linux-4068579e1e098fa81d48db9ba4432ab664c58561.tar.xz linux-4068579e1e098fa81d48db9ba4432ab664c58561.zip |
net: Implmement RFC 6936 (zero RX csums for UDP/IPv6)
RFC 6936 relaxes the requirement of RFC 2460 that UDP/IPv6 packets which
are received with a zero UDP checksum value must be dropped. RFC 6936
allows zero checksums to support tunnels over UDP.
When sk_no_check is set we allow on a socket we allow a zero IPv6
UDP checksum. This is for both sending zero checksum and accepting
a zero checksum on receive.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_checksum.c')
-rw-r--r-- | net/ipv6/ip6_checksum.c | 18 |
1 files changed, 7 insertions, 11 deletions
diff --git a/net/ipv6/ip6_checksum.c b/net/ipv6/ip6_checksum.c index c69fe37b8104..da26224a5993 100644 --- a/net/ipv6/ip6_checksum.c +++ b/net/ipv6/ip6_checksum.c @@ -75,16 +75,12 @@ int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto) return err; } - if (uh->check == 0) { - /* RFC 2460 section 8.1 says that we SHOULD log - this error. Well, it is reasonable. - */ - LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0 for [%pI6c]:%u->[%pI6c]:%u\n", - &ipv6_hdr(skb)->saddr, ntohs(uh->source), - &ipv6_hdr(skb)->daddr, ntohs(uh->dest)); - return 1; - } - - return skb_checksum_init(skb, IPPROTO_UDP, ip6_compute_pseudo); + /* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels) + * we accept a checksum of zero here. When we find the socket + * for the UDP packet we'll check if that socket allows zero checksum + * for IPv6 (set by socket option). + */ + return skb_checksum_init_zero_check(skb, proto, uh->check, + ip6_compute_pseudo); } EXPORT_SYMBOL(udp6_csum_init); |