From: Eric Dumazet Date: Fri, 18 May 2012 11:02:15 +0000 (+0000) Subject: ipv6: ip6_fragment() should check CHECKSUM_PARTIAL X-Git-Tag: v3.5-rc1~191^2~21 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=72e843bb09d4533208aa5573861a983c46914019;p=~emulex%2Finfiniband.git ipv6: ip6_fragment() should check CHECKSUM_PARTIAL Quoting Tore Anderson from : If the allfrag feature has been set on a host route (due to an ICMPv6 Packet Too Big received indicating a MTU of less than 1280), TCP SYN/ACK packets to that destination appears to get an incorrect TCP checksum. This in turn means they are thrown away as invalid. In the case of an IPv4 client behind a link with a MTU of less than 1260, accessing an IPv6 server through a stateless translator, this means that the client can only download a single large file from the server, because once it is in the server's routing cache with the allfrag feature set, new TCP connections can no longer be established. It appears ip6_fragment() doesn't handle CHECKSUM_PARTIAL properly. As network drivers are not prepared to fetch correct transport header, a safe fix is to call skb_checksum_help() before fragmenting packet. Reported-by: Tore Anderson Signed-off-by: Eric Dumazet Tested-by: Tore Anderson Signed-off-by: David S. Miller --- diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index a254e4b5d96..3dc633f3937 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -788,6 +788,10 @@ slow_path_clean: } slow_path: + if ((skb->ip_summed == CHECKSUM_PARTIAL) && + skb_checksum_help(skb)) + goto fail; + left = skb->len - hlen; /* Space per frame */ ptr = hlen; /* Where to start from */