aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c79
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;
55int sysctl_tcp_tso_win_divisor __read_mostly = 3; 55int sysctl_tcp_tso_win_divisor __read_mostly = 3;
56 56
57int sysctl_tcp_mtu_probing __read_mostly = 0; 57int sysctl_tcp_mtu_probing __read_mostly = 0;
58int sysctl_tcp_base_mss __read_mostly = 512; 58int sysctl_tcp_base_mss __read_mostly = TCP_BASE_MSS;
59 59
60/* By default, RFC2861 behavior. */ 60/* By default, RFC2861 behavior. */
61int sysctl_tcp_slow_start_after_idle __read_mostly = 1; 61int 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 */
387static u8 tcp_cookie_size_check(u8 desired) 395static 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.