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 61c2463e2753..dc7c096ddfef 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; | |||
55 | int sysctl_tcp_tso_win_divisor __read_mostly = 3; | 55 | int sysctl_tcp_tso_win_divisor __read_mostly = 3; |
56 | 56 | ||
57 | int sysctl_tcp_mtu_probing __read_mostly = 0; | 57 | int sysctl_tcp_mtu_probing __read_mostly = 0; |
58 | int sysctl_tcp_base_mss __read_mostly = 512; | 58 | int sysctl_tcp_base_mss __read_mostly = TCP_BASE_MSS; |
59 | 59 | ||
60 | /* By default, RFC2861 behavior. */ | 60 | /* By default, RFC2861 behavior. */ |
61 | int sysctl_tcp_slow_start_after_idle __read_mostly = 1; | 61 | int sysctl_tcp_slow_start_after_idle __read_mostly = 1; |
@@ -119,9 +119,13 @@ static __u16 tcp_advertise_mss(struct sock *sk) | |||
119 | struct dst_entry *dst = __sk_dst_get(sk); | 119 | struct dst_entry *dst = __sk_dst_get(sk); |
120 | int mss = tp->advmss; | 120 | int mss = tp->advmss; |
121 | 121 | ||
122 | if (dst && dst_metric(dst, RTAX_ADVMSS) < mss) { | 122 | if (dst) { |
123 | mss = dst_metric(dst, RTAX_ADVMSS); | 123 | unsigned int metric = dst_metric_advmss(dst); |
124 | tp->advmss = mss; | 124 | |
125 | if (metric < mss) { | ||
126 | mss = metric; | ||
127 | tp->advmss = mss; | ||
128 | } | ||
125 | } | 129 | } |
126 | 130 | ||
127 | return (__u16)mss; | 131 | return (__u16)mss; |
@@ -224,10 +228,15 @@ void tcp_select_initial_window(int __space, __u32 mss, | |||
224 | } | 228 | } |
225 | } | 229 | } |
226 | 230 | ||
227 | /* Set initial window to value enough for senders, following RFC5681. */ | 231 | /* Set initial window to a value enough for senders starting with |
232 | * initial congestion window of TCP_DEFAULT_INIT_RCVWND. Place | ||
233 | * a limit on the initial window when mss is larger than 1460. | ||
234 | */ | ||
228 | if (mss > (1 << *rcv_wscale)) { | 235 | if (mss > (1 << *rcv_wscale)) { |
229 | int init_cwnd = rfc3390_bytes_to_packets(mss); | 236 | int init_cwnd = TCP_DEFAULT_INIT_RCVWND; |
230 | 237 | if (mss > 1460) | |
238 | init_cwnd = | ||
239 | max_t(u32, (1460 * TCP_DEFAULT_INIT_RCVWND) / mss, 2); | ||
231 | /* when initializing use the value from init_rcv_wnd | 240 | /* when initializing use the value from init_rcv_wnd |
232 | * rather than the default from above | 241 | * rather than the default from above |
233 | */ | 242 | */ |
@@ -824,8 +833,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
824 | &md5); | 833 | &md5); |
825 | tcp_header_size = tcp_options_size + sizeof(struct tcphdr); | 834 | tcp_header_size = tcp_options_size + sizeof(struct tcphdr); |
826 | 835 | ||
827 | if (tcp_packets_in_flight(tp) == 0) | 836 | if (tcp_packets_in_flight(tp) == 0) { |
828 | tcp_ca_event(sk, CA_EVENT_TX_START); | 837 | tcp_ca_event(sk, CA_EVENT_TX_START); |
838 | skb->ooo_okay = 1; | ||
839 | } else | ||
840 | skb->ooo_okay = 0; | ||
829 | 841 | ||
830 | skb_push(skb, tcp_header_size); | 842 | skb_push(skb, tcp_header_size); |
831 | skb_reset_transport_header(skb); | 843 | skb_reset_transport_header(skb); |
@@ -2419,7 +2431,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2419 | 2431 | ||
2420 | skb_dst_set(skb, dst_clone(dst)); | 2432 | skb_dst_set(skb, dst_clone(dst)); |
2421 | 2433 | ||
2422 | mss = dst_metric(dst, RTAX_ADVMSS); | 2434 | mss = dst_metric_advmss(dst); |
2423 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) | 2435 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) |
2424 | mss = tp->rx_opt.user_mss; | 2436 | mss = tp->rx_opt.user_mss; |
2425 | 2437 | ||
@@ -2553,7 +2565,7 @@ static void tcp_connect_init(struct sock *sk) | |||
2553 | 2565 | ||
2554 | if (!tp->window_clamp) | 2566 | if (!tp->window_clamp) |
2555 | tp->window_clamp = dst_metric(dst, RTAX_WINDOW); | 2567 | tp->window_clamp = dst_metric(dst, RTAX_WINDOW); |
2556 | tp->advmss = dst_metric(dst, RTAX_ADVMSS); | 2568 | tp->advmss = dst_metric_advmss(dst); |
2557 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss) | 2569 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss) |
2558 | tp->advmss = tp->rx_opt.user_mss; | 2570 | tp->advmss = tp->rx_opt.user_mss; |
2559 | 2571 | ||
@@ -2596,6 +2608,7 @@ int tcp_connect(struct sock *sk) | |||
2596 | { | 2608 | { |
2597 | struct tcp_sock *tp = tcp_sk(sk); | 2609 | struct tcp_sock *tp = tcp_sk(sk); |
2598 | struct sk_buff *buff; | 2610 | struct sk_buff *buff; |
2611 | int err; | ||
2599 | 2612 | ||
2600 | tcp_connect_init(sk); | 2613 | tcp_connect_init(sk); |
2601 | 2614 | ||
@@ -2618,7 +2631,9 @@ int tcp_connect(struct sock *sk) | |||
2618 | sk->sk_wmem_queued += buff->truesize; | 2631 | sk->sk_wmem_queued += buff->truesize; |
2619 | sk_mem_charge(sk, buff->truesize); | 2632 | sk_mem_charge(sk, buff->truesize); |
2620 | tp->packets_out += tcp_skb_pcount(buff); | 2633 | tp->packets_out += tcp_skb_pcount(buff); |
2621 | tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); | 2634 | err = tcp_transmit_skb(sk, buff, 1, sk->sk_allocation); |
2635 | if (err == -ECONNREFUSED) | ||
2636 | return err; | ||
2622 | 2637 | ||
2623 | /* We change tp->snd_nxt after the tcp_transmit_skb() call | 2638 | /* We change tp->snd_nxt after the tcp_transmit_skb() call |
2624 | * in order to make this packet get counted in tcpOutSegs. | 2639 | * in order to make this packet get counted in tcpOutSegs. |