diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
| -rw-r--r-- | net/ipv4/tcp_output.c | 37 | 
1 files changed, 26 insertions, 11 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 8750d4050b4..406f320336e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -55,7 +55,7 @@ int sysctl_tcp_workaround_signed_windows __read_mostly = 0;  int sysctl_tcp_tso_win_divisor __read_mostly = 3;  int sysctl_tcp_mtu_probing __read_mostly = 0; -int sysctl_tcp_base_mss __read_mostly = 512; +int sysctl_tcp_base_mss __read_mostly = TCP_BASE_MSS;  /* By default, RFC2861 behavior.  */  int sysctl_tcp_slow_start_after_idle __read_mostly = 1; @@ -119,9 +119,13 @@ static __u16 tcp_advertise_mss(struct sock *sk)  	struct dst_entry *dst = __sk_dst_get(sk);  	int mss = tp->advmss; -	if (dst && dst_metric(dst, RTAX_ADVMSS) < mss) { -		mss = dst_metric(dst, RTAX_ADVMSS); -		tp->advmss = mss; +	if (dst) { +		unsigned int metric = dst_metric_advmss(dst); + +		if (metric < mss) { +			mss = metric; +			tp->advmss = mss; +		}  	}  	return (__u16)mss; @@ -224,10 +228,15 @@ void tcp_select_initial_window(int __space, __u32 mss,  		}  	} -	/* Set initial window to value enough for senders, following RFC5681. */ +	/* Set initial window to a value enough for senders starting with +	 * initial congestion window of TCP_DEFAULT_INIT_RCVWND. Place +	 * a limit on the initial window when mss is larger than 1460. +	 */  	if (mss > (1 << *rcv_wscale)) { -		int init_cwnd = rfc3390_bytes_to_packets(mss); - +		int init_cwnd = TCP_DEFAULT_INIT_RCVWND; +		if (mss > 1460) +			init_cwnd = +			max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2);  		/* when initializing use the value from init_rcv_wnd  		 * rather than the default from above  		 */ @@ -824,8 +833,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,  							   &md5);  	tcp_header_size = tcp_options_size + sizeof(struct tcphdr); -	if (tcp_packets_in_flight(tp) == 0) +	if (tcp_packets_in_flight(tp) == 0) {  		tcp_ca_event(sk, CA_EVENT_TX_START); +		skb->ooo_okay = 1; +	} else +		skb->ooo_okay = 0;  	skb_push(skb, tcp_header_size);  	skb_reset_transport_header(skb); @@ -2419,7 +2431,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,  	skb_dst_set(skb, dst_clone(dst)); -	mss = dst_metric(dst, RTAX_ADVMSS); +	mss = dst_metric_advmss(dst);  	if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)  		mss = tp->rx_opt.user_mss; @@ -2553,7 +2565,7 @@ static void tcp_connect_init(struct sock *sk)  	if (!tp->window_clamp)  		tp->window_clamp = dst_metric(dst, RTAX_WINDOW); -	tp->advmss = dst_metric(dst, RTAX_ADVMSS); +	tp->advmss = dst_metric_advmss(dst);  	if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss)  		tp->advmss = tp->rx_opt.user_mss; @@ -2596,6 +2608,7 @@ int tcp_connect(struct sock *sk)  {  	struct tcp_sock *tp = tcp_sk(sk);  	struct sk_buff *buff; +	int err;  	tcp_connect_init(sk); @@ -2618,7 +2631,9 @@ int tcp_connect(struct sock *sk)  	sk->sk_wmem_queued += buff->truesize;  	sk_mem_charge(sk, buff->truesize);  	tp->packets_out += tcp_skb_pcount(buff); -	tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); +	err = tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); +	if (err == -ECONNREFUSED) +		return err;  	/* We change tp->snd_nxt after the tcp_transmit_skb() call  	 * in order to make this packet get counted in tcpOutSegs.  |