diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 10 | 
1 files changed, 7 insertions, 3 deletions
| diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index f429e856e263..00c01a01b547 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1296,6 +1296,11 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,  	if (nsize < 0)  		nsize = 0; +	if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) { +		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG); +		return -ENOMEM; +	} +  	if (skb_unclone(skb, gfp))  		return -ENOMEM; @@ -1454,8 +1459,7 @@ static inline int __tcp_mtu_to_mss(struct sock *sk, int pmtu)  	mss_now -= icsk->icsk_ext_hdr_len;  	/* Then reserve room for full set of TCP options and 8 bytes of data */ -	if (mss_now < 48) -		mss_now = 48; +	mss_now = max(mss_now, sock_net(sk)->ipv4.sysctl_tcp_min_snd_mss);  	return mss_now;  } @@ -2747,7 +2751,7 @@ static bool tcp_collapse_retrans(struct sock *sk, struct sk_buff *skb)  		if (next_skb_size <= skb_availroom(skb))  			skb_copy_bits(next_skb, 0, skb_put(skb, next_skb_size),  				      next_skb_size); -		else if (!skb_shift(skb, next_skb, next_skb_size)) +		else if (!tcp_skb_shift(skb, next_skb, 1, next_skb_size))  			return false;  	}  	tcp_highest_sack_replace(sk, next_skb, skb); | 

