From 72e843bb09d4533208aa5573861a983c46914019 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 18 May 2012 11:02:15 +0000 Subject: 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 --- net/ipv6/ip6_output.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'net') diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index a254e4b5d968..3dc633f39372 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 */ -- cgit v1.2.3-59-g8ed1b