diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
| -rw-r--r-- | net/ipv6/ip6_output.c | 9 | 
1 files changed, 7 insertions, 2 deletions
| diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 528b3c1f3fde..58f6288e9ba5 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -768,13 +768,14 @@ slow_path:  	 *	Fragment the datagram.  	 */ -	*prevhdr = NEXTHDR_FRAGMENT;  	troom = rt->dst.dev->needed_tailroom;  	/*  	 *	Keep copying data until we run out.  	 */  	while (left > 0)	{ +		u8 *fragnexthdr_offset; +  		len = left;  		/* IF: it doesn't fit, use 'mtu' - the data space left */  		if (len > mtu) @@ -819,6 +820,10 @@ slow_path:  		 */  		skb_copy_from_linear_data(skb, skb_network_header(frag), hlen); +		fragnexthdr_offset = skb_network_header(frag); +		fragnexthdr_offset += prevhdr - skb_network_header(skb); +		*fragnexthdr_offset = NEXTHDR_FRAGMENT; +  		/*  		 *	Build fragment header.  		 */ @@ -1385,7 +1390,7 @@ emsgsize:  	if ((((length + fragheaderlen) > mtu) ||  	     (skb && skb_is_gso(skb))) &&  	    (sk->sk_protocol == IPPROTO_UDP) && -	    (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len && +	    (rt->dst.dev->features & NETIF_F_UFO) && !dst_xfrm(&rt->dst) &&  	    (sk->sk_type == SOCK_DGRAM) && !udp_get_no_check6_tx(sk)) {  		err = ip6_ufo_append_data(sk, queue, getfrag, from, length,  					  hh_len, fragheaderlen, exthdrlen, |