mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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. </endquote> 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 <tore@fud.no> Signed-off-by: Eric Dumazet <edumazet@google.com> Tested-by: Tore Anderson <tore@fud.no> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									6fba180ee8
								
							
						
					
					
						commit
						72e843bb09
					
				
					 1 changed files with 4 additions and 0 deletions
				
			
		| 
						 | 
					@ -788,6 +788,10 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
slow_path:
 | 
					slow_path:
 | 
				
			||||||
 | 
						if ((skb->ip_summed == CHECKSUM_PARTIAL) &&
 | 
				
			||||||
 | 
						    skb_checksum_help(skb))
 | 
				
			||||||
 | 
							goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	left = skb->len - hlen;		/* Space per frame */
 | 
						left = skb->len - hlen;		/* Space per frame */
 | 
				
			||||||
	ptr = hlen;			/* Where to start from */
 | 
						ptr = hlen;			/* Where to start from */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue