diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
| -rw-r--r-- | net/ipv6/ip6_output.c | 16 | 
1 files changed, 10 insertions, 6 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index d5d20cde8d92..6e3ddf806ec2 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1098,11 +1098,12 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,  	return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;  } -static void ip6_append_data_mtu(int *mtu, +static void ip6_append_data_mtu(unsigned int *mtu,  				int *maxfraglen,  				unsigned int fragheaderlen,  				struct sk_buff *skb, -				struct rt6_info *rt) +				struct rt6_info *rt, +				bool pmtuprobe)  {  	if (!(rt->dst.flags & DST_XFRM_TUNNEL)) {  		if (skb == NULL) { @@ -1114,7 +1115,9 @@ static void ip6_append_data_mtu(int *mtu,  			 * this fragment is not first, the headers  			 * space is regarded as data space.  			 */ -			*mtu = dst_mtu(rt->dst.path); +			*mtu = min(*mtu, pmtuprobe ? +				   rt->dst.dev->mtu : +				   dst_mtu(rt->dst.path));  		}  		*maxfraglen = ((*mtu - fragheaderlen) & ~7)  			      + fragheaderlen - sizeof(struct frag_hdr); @@ -1131,11 +1134,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,  	struct ipv6_pinfo *np = inet6_sk(sk);  	struct inet_cork *cork;  	struct sk_buff *skb, *skb_prev = NULL; -	unsigned int maxfraglen, fragheaderlen; +	unsigned int maxfraglen, fragheaderlen, mtu;  	int exthdrlen;  	int dst_exthdrlen;  	int hh_len; -	int mtu;  	int copy;  	int err;  	int offset = 0; @@ -1292,7 +1294,9 @@ alloc_new_skb:  			/* update mtu and maxfraglen if necessary */  			if (skb == NULL || skb_prev == NULL)  				ip6_append_data_mtu(&mtu, &maxfraglen, -						    fragheaderlen, skb, rt); +						    fragheaderlen, skb, rt, +						    np->pmtudisc == +						    IPV6_PMTUDISC_PROBE);  			skb_prev = skb;  | 
