diff options
Diffstat (limited to 'net/ipv4/tcp_input.c')
| -rw-r--r-- | net/ipv4/tcp_input.c | 20 | 
1 files changed, 13 insertions, 7 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index eb82e01da911..0cbf81bf3d45 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -243,9 +243,15 @@ static void tcp_measure_rcv_mss(struct sock *sk, const struct sk_buff *skb)  			do_div(val, skb->truesize);  			tcp_sk(sk)->scaling_ratio = val ? val : 1; -			if (old_ratio != tcp_sk(sk)->scaling_ratio) -				WRITE_ONCE(tcp_sk(sk)->window_clamp, -					   tcp_win_from_space(sk, sk->sk_rcvbuf)); +			if (old_ratio != tcp_sk(sk)->scaling_ratio) { +				struct tcp_sock *tp = tcp_sk(sk); + +				val = tcp_win_from_space(sk, sk->sk_rcvbuf); +				tcp_set_window_clamp(sk, val); + +				if (tp->window_clamp < tp->rcvq_space.space) +					tp->rcvq_space.space = tp->window_clamp; +			}  		}  		icsk->icsk_ack.rcv_mss = min_t(unsigned int, len,  					       tcp_sk(sk)->advmss); @@ -4970,7 +4976,7 @@ static void tcp_ofo_queue(struct sock *sk)  		tcp_rcv_nxt_update(tp, TCP_SKB_CB(skb)->end_seq);  		fin = TCP_SKB_CB(skb)->tcp_flags & TCPHDR_FIN;  		if (!eaten) -			__skb_queue_tail(&sk->sk_receive_queue, skb); +			tcp_add_receive_queue(sk, skb);  		else  			kfree_skb_partial(skb, fragstolen); @@ -5162,7 +5168,7 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb,  				  skb, fragstolen)) ? 1 : 0;  	tcp_rcv_nxt_update(tcp_sk(sk), TCP_SKB_CB(skb)->end_seq);  	if (!eaten) { -		__skb_queue_tail(&sk->sk_receive_queue, skb); +		tcp_add_receive_queue(sk, skb);  		skb_set_owner_r(skb, sk);  	}  	return eaten; @@ -5245,7 +5251,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)  		__kfree_skb(skb);  		return;  	} -	skb_dst_drop(skb); +	tcp_cleanup_skb(skb);  	__skb_pull(skb, tcp_hdr(skb)->doff * 4);  	reason = SKB_DROP_REASON_NOT_SPECIFIED; @@ -6226,7 +6232,7 @@ void tcp_rcv_established(struct sock *sk, struct sk_buff *skb)  			NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPHPHITS);  			/* Bulk data transfer: receiver */ -			skb_dst_drop(skb); +			tcp_cleanup_skb(skb);  			__skb_pull(skb, tcp_header_len);  			eaten = tcp_queue_rcv(sk, skb, &fragstolen);  | 
