diff options
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r-- | net/ipv4/tcp_output.c | 79 |
1 files changed, 49 insertions, 30 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 05b1ecf36763..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,18 +228,22 @@ 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 | */ |
234 | if (init_rcv_wnd && | 243 | if (init_rcv_wnd) |
235 | (*rcv_wnd > init_rcv_wnd * mss)) | 244 | *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss); |
236 | *rcv_wnd = init_rcv_wnd * mss; | 245 | else |
237 | else if (*rcv_wnd > init_cwnd * mss) | 246 | *rcv_wnd = min(*rcv_wnd, init_cwnd * mss); |
238 | *rcv_wnd = init_cwnd * mss; | ||
239 | } | 247 | } |
240 | 248 | ||
241 | /* Set the clamp no higher than max representable value */ | 249 | /* Set the clamp no higher than max representable value */ |
@@ -386,27 +394,30 @@ struct tcp_out_options { | |||
386 | */ | 394 | */ |
387 | static u8 tcp_cookie_size_check(u8 desired) | 395 | static u8 tcp_cookie_size_check(u8 desired) |
388 | { | 396 | { |
389 | if (desired > 0) { | 397 | int cookie_size; |
398 | |||
399 | if (desired > 0) | ||
390 | /* previously specified */ | 400 | /* previously specified */ |
391 | return desired; | 401 | return desired; |
392 | } | 402 | |
393 | if (sysctl_tcp_cookie_size <= 0) { | 403 | cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); |
404 | if (cookie_size <= 0) | ||
394 | /* no default specified */ | 405 | /* no default specified */ |
395 | return 0; | 406 | return 0; |
396 | } | 407 | |
397 | if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) { | 408 | if (cookie_size <= TCP_COOKIE_MIN) |
398 | /* value too small, specify minimum */ | 409 | /* value too small, specify minimum */ |
399 | return TCP_COOKIE_MIN; | 410 | return TCP_COOKIE_MIN; |
400 | } | 411 | |
401 | if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) { | 412 | if (cookie_size >= TCP_COOKIE_MAX) |
402 | /* value too large, specify maximum */ | 413 | /* value too large, specify maximum */ |
403 | return TCP_COOKIE_MAX; | 414 | return TCP_COOKIE_MAX; |
404 | } | 415 | |
405 | if (0x1 & sysctl_tcp_cookie_size) { | 416 | if (cookie_size & 1) |
406 | /* 8-bit multiple, illegal, fix it */ | 417 | /* 8-bit multiple, illegal, fix it */ |
407 | return (u8)(sysctl_tcp_cookie_size + 0x1); | 418 | cookie_size++; |
408 | } | 419 | |
409 | return (u8)sysctl_tcp_cookie_size; | 420 | return (u8)cookie_size; |
410 | } | 421 | } |
411 | 422 | ||
412 | /* Write previously computed TCP options to the packet. | 423 | /* Write previously computed TCP options to the packet. |
@@ -822,8 +833,11 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
822 | &md5); | 833 | &md5); |
823 | tcp_header_size = tcp_options_size + sizeof(struct tcphdr); | 834 | tcp_header_size = tcp_options_size + sizeof(struct tcphdr); |
824 | 835 | ||
825 | if (tcp_packets_in_flight(tp) == 0) | 836 | if (tcp_packets_in_flight(tp) == 0) { |
826 | 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; | ||
827 | 841 | ||
828 | skb_push(skb, tcp_header_size); | 842 | skb_push(skb, tcp_header_size); |
829 | skb_reset_transport_header(skb); | 843 | skb_reset_transport_header(skb); |
@@ -1513,6 +1527,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1513 | struct tcp_sock *tp = tcp_sk(sk); | 1527 | struct tcp_sock *tp = tcp_sk(sk); |
1514 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1528 | const struct inet_connection_sock *icsk = inet_csk(sk); |
1515 | u32 send_win, cong_win, limit, in_flight; | 1529 | u32 send_win, cong_win, limit, in_flight; |
1530 | int win_divisor; | ||
1516 | 1531 | ||
1517 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) | 1532 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) |
1518 | goto send_now; | 1533 | goto send_now; |
@@ -1544,13 +1559,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1544 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) | 1559 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) |
1545 | goto send_now; | 1560 | goto send_now; |
1546 | 1561 | ||
1547 | if (sysctl_tcp_tso_win_divisor) { | 1562 | win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor); |
1563 | if (win_divisor) { | ||
1548 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 1564 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
1549 | 1565 | ||
1550 | /* If at least some fraction of a window is available, | 1566 | /* If at least some fraction of a window is available, |
1551 | * just use it. | 1567 | * just use it. |
1552 | */ | 1568 | */ |
1553 | chunk /= sysctl_tcp_tso_win_divisor; | 1569 | chunk /= win_divisor; |
1554 | if (limit >= chunk) | 1570 | if (limit >= chunk) |
1555 | goto send_now; | 1571 | goto send_now; |
1556 | } else { | 1572 | } else { |
@@ -2415,7 +2431,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2415 | 2431 | ||
2416 | skb_dst_set(skb, dst_clone(dst)); | 2432 | skb_dst_set(skb, dst_clone(dst)); |
2417 | 2433 | ||
2418 | mss = dst_metric(dst, RTAX_ADVMSS); | 2434 | mss = dst_metric_advmss(dst); |
2419 | 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) |
2420 | mss = tp->rx_opt.user_mss; | 2436 | mss = tp->rx_opt.user_mss; |
2421 | 2437 | ||
@@ -2549,7 +2565,7 @@ static void tcp_connect_init(struct sock *sk) | |||
2549 | 2565 | ||
2550 | if (!tp->window_clamp) | 2566 | if (!tp->window_clamp) |
2551 | tp->window_clamp = dst_metric(dst, RTAX_WINDOW); | 2567 | tp->window_clamp = dst_metric(dst, RTAX_WINDOW); |
2552 | tp->advmss = dst_metric(dst, RTAX_ADVMSS); | 2568 | tp->advmss = dst_metric_advmss(dst); |
2553 | 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) |
2554 | tp->advmss = tp->rx_opt.user_mss; | 2570 | tp->advmss = tp->rx_opt.user_mss; |
2555 | 2571 | ||
@@ -2592,6 +2608,7 @@ int tcp_connect(struct sock *sk) | |||
2592 | { | 2608 | { |
2593 | struct tcp_sock *tp = tcp_sk(sk); | 2609 | struct tcp_sock *tp = tcp_sk(sk); |
2594 | struct sk_buff *buff; | 2610 | struct sk_buff *buff; |
2611 | int err; | ||
2595 | 2612 | ||
2596 | tcp_connect_init(sk); | 2613 | tcp_connect_init(sk); |
2597 | 2614 | ||
@@ -2614,7 +2631,9 @@ int tcp_connect(struct sock *sk) | |||
2614 | sk->sk_wmem_queued += buff->truesize; | 2631 | sk->sk_wmem_queued += buff->truesize; |
2615 | sk_mem_charge(sk, buff->truesize); | 2632 | sk_mem_charge(sk, buff->truesize); |
2616 | tp->packets_out += tcp_skb_pcount(buff); | 2633 | tp->packets_out += tcp_skb_pcount(buff); |
2617 | 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; | ||
2618 | 2637 | ||
2619 | /* We change tp->snd_nxt after the tcp_transmit_skb() call | 2638 | /* We change tp->snd_nxt after the tcp_transmit_skb() call |
2620 | * in order to make this packet get counted in tcpOutSegs. | 2639 | * in order to make this packet get counted in tcpOutSegs. |