aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_input.c')
-rw-r--r--net/ipv4/tcp_input.c66
1 files changed, 35 insertions, 31 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 52b5c2d0ecd0..2877c3e09587 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -322,7 +322,7 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb)
322 /* Check #1 */ 322 /* Check #1 */
323 if (tp->rcv_ssthresh < tp->window_clamp && 323 if (tp->rcv_ssthresh < tp->window_clamp &&
324 (int)tp->rcv_ssthresh < tcp_space(sk) && 324 (int)tp->rcv_ssthresh < tcp_space(sk) &&
325 !tcp_memory_pressure) { 325 !sk_under_memory_pressure(sk)) {
326 int incr; 326 int incr;
327 327
328 /* Check #2. Increase window, if skb with such overhead 328 /* Check #2. Increase window, if skb with such overhead
@@ -411,8 +411,8 @@ static void tcp_clamp_window(struct sock *sk)
411 411
412 if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] && 412 if (sk->sk_rcvbuf < sysctl_tcp_rmem[2] &&
413 !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) && 413 !(sk->sk_userlocks & SOCK_RCVBUF_LOCK) &&
414 !tcp_memory_pressure && 414 !sk_under_memory_pressure(sk) &&
415 atomic_long_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { 415 sk_memory_allocated(sk) < sk_prot_mem_limits(sk, 0)) {
416 sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc), 416 sk->sk_rcvbuf = min(atomic_read(&sk->sk_rmem_alloc),
417 sysctl_tcp_rmem[2]); 417 sysctl_tcp_rmem[2]);
418 } 418 }
@@ -865,13 +865,13 @@ static void tcp_disable_fack(struct tcp_sock *tp)
865 /* RFC3517 uses different metric in lost marker => reset on change */ 865 /* RFC3517 uses different metric in lost marker => reset on change */
866 if (tcp_is_fack(tp)) 866 if (tcp_is_fack(tp))
867 tp->lost_skb_hint = NULL; 867 tp->lost_skb_hint = NULL;
868 tp->rx_opt.sack_ok &= ~2; 868 tp->rx_opt.sack_ok &= ~TCP_FACK_ENABLED;
869} 869}
870 870
871/* Take a notice that peer is sending D-SACKs */ 871/* Take a notice that peer is sending D-SACKs */
872static void tcp_dsack_seen(struct tcp_sock *tp) 872static void tcp_dsack_seen(struct tcp_sock *tp)
873{ 873{
874 tp->rx_opt.sack_ok |= 4; 874 tp->rx_opt.sack_ok |= TCP_DSACK_SEEN;
875} 875}
876 876
877/* Initialize metrics on socket. */ 877/* Initialize metrics on socket. */
@@ -2663,7 +2663,7 @@ static void DBGUNDO(struct sock *sk, const char *msg)
2663 tp->snd_ssthresh, tp->prior_ssthresh, 2663 tp->snd_ssthresh, tp->prior_ssthresh,
2664 tp->packets_out); 2664 tp->packets_out);
2665 } 2665 }
2666#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 2666#if IS_ENABLED(CONFIG_IPV6)
2667 else if (sk->sk_family == AF_INET6) { 2667 else if (sk->sk_family == AF_INET6) {
2668 struct ipv6_pinfo *np = inet6_sk(sk); 2668 struct ipv6_pinfo *np = inet6_sk(sk);
2669 printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n", 2669 printk(KERN_DEBUG "Undo %s %pI6/%u c%u l%u ss%u/%u p%u\n",
@@ -2858,7 +2858,7 @@ static void tcp_try_keep_open(struct sock *sk)
2858 struct tcp_sock *tp = tcp_sk(sk); 2858 struct tcp_sock *tp = tcp_sk(sk);
2859 int state = TCP_CA_Open; 2859 int state = TCP_CA_Open;
2860 2860
2861 if (tcp_left_out(tp) || tcp_any_retrans_done(sk) || tp->undo_marker) 2861 if (tcp_left_out(tp) || tcp_any_retrans_done(sk))
2862 state = TCP_CA_Disorder; 2862 state = TCP_CA_Disorder;
2863 2863
2864 if (inet_csk(sk)->icsk_ca_state != state) { 2864 if (inet_csk(sk)->icsk_ca_state != state) {
@@ -2881,7 +2881,8 @@ static void tcp_try_to_open(struct sock *sk, int flag)
2881 2881
2882 if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) { 2882 if (inet_csk(sk)->icsk_ca_state != TCP_CA_CWR) {
2883 tcp_try_keep_open(sk); 2883 tcp_try_keep_open(sk);
2884 tcp_moderate_cwnd(tp); 2884 if (inet_csk(sk)->icsk_ca_state != TCP_CA_Open)
2885 tcp_moderate_cwnd(tp);
2885 } else { 2886 } else {
2886 tcp_cwnd_down(sk, flag); 2887 tcp_cwnd_down(sk, flag);
2887 } 2888 }
@@ -3009,11 +3010,11 @@ static void tcp_update_cwnd_in_recovery(struct sock *sk, int newly_acked_sacked,
3009 * tcp_xmit_retransmit_queue(). 3010 * tcp_xmit_retransmit_queue().
3010 */ 3011 */
3011static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, 3012static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
3012 int newly_acked_sacked, int flag) 3013 int newly_acked_sacked, bool is_dupack,
3014 int flag)
3013{ 3015{
3014 struct inet_connection_sock *icsk = inet_csk(sk); 3016 struct inet_connection_sock *icsk = inet_csk(sk);
3015 struct tcp_sock *tp = tcp_sk(sk); 3017 struct tcp_sock *tp = tcp_sk(sk);
3016 int is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
3017 int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) && 3018 int do_lost = is_dupack || ((flag & FLAG_DATA_SACKED) &&
3018 (tcp_fackets_out(tp) > tp->reordering)); 3019 (tcp_fackets_out(tp) > tp->reordering));
3019 int fast_rexmit = 0, mib_idx; 3020 int fast_rexmit = 0, mib_idx;
@@ -3066,17 +3067,6 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
3066 } 3067 }
3067 break; 3068 break;
3068 3069
3069 case TCP_CA_Disorder:
3070 tcp_try_undo_dsack(sk);
3071 if (!tp->undo_marker ||
3072 /* For SACK case do not Open to allow to undo
3073 * catching for all duplicate ACKs. */
3074 tcp_is_reno(tp) || tp->snd_una != tp->high_seq) {
3075 tp->undo_marker = 0;
3076 tcp_set_ca_state(sk, TCP_CA_Open);
3077 }
3078 break;
3079
3080 case TCP_CA_Recovery: 3070 case TCP_CA_Recovery:
3081 if (tcp_is_reno(tp)) 3071 if (tcp_is_reno(tp))
3082 tcp_reset_reno_sack(tp); 3072 tcp_reset_reno_sack(tp);
@@ -3117,7 +3107,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
3117 tcp_add_reno_sack(sk); 3107 tcp_add_reno_sack(sk);
3118 } 3108 }
3119 3109
3120 if (icsk->icsk_ca_state == TCP_CA_Disorder) 3110 if (icsk->icsk_ca_state <= TCP_CA_Disorder)
3121 tcp_try_undo_dsack(sk); 3111 tcp_try_undo_dsack(sk);
3122 3112
3123 if (!tcp_time_to_recover(sk)) { 3113 if (!tcp_time_to_recover(sk)) {
@@ -3681,10 +3671,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3681 u32 prior_snd_una = tp->snd_una; 3671 u32 prior_snd_una = tp->snd_una;
3682 u32 ack_seq = TCP_SKB_CB(skb)->seq; 3672 u32 ack_seq = TCP_SKB_CB(skb)->seq;
3683 u32 ack = TCP_SKB_CB(skb)->ack_seq; 3673 u32 ack = TCP_SKB_CB(skb)->ack_seq;
3674 bool is_dupack = false;
3684 u32 prior_in_flight; 3675 u32 prior_in_flight;
3685 u32 prior_fackets; 3676 u32 prior_fackets;
3686 int prior_packets; 3677 int prior_packets;
3687 int prior_sacked = tp->sacked_out; 3678 int prior_sacked = tp->sacked_out;
3679 int pkts_acked = 0;
3688 int newly_acked_sacked = 0; 3680 int newly_acked_sacked = 0;
3689 int frto_cwnd = 0; 3681 int frto_cwnd = 0;
3690 3682
@@ -3757,6 +3749,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3757 /* See if we can take anything off of the retransmit queue. */ 3749 /* See if we can take anything off of the retransmit queue. */
3758 flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); 3750 flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
3759 3751
3752 pkts_acked = prior_packets - tp->packets_out;
3760 newly_acked_sacked = (prior_packets - prior_sacked) - 3753 newly_acked_sacked = (prior_packets - prior_sacked) -
3761 (tp->packets_out - tp->sacked_out); 3754 (tp->packets_out - tp->sacked_out);
3762 3755
@@ -3771,8 +3764,9 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3771 if ((flag & FLAG_DATA_ACKED) && !frto_cwnd && 3764 if ((flag & FLAG_DATA_ACKED) && !frto_cwnd &&
3772 tcp_may_raise_cwnd(sk, flag)) 3765 tcp_may_raise_cwnd(sk, flag))
3773 tcp_cong_avoid(sk, ack, prior_in_flight); 3766 tcp_cong_avoid(sk, ack, prior_in_flight);
3774 tcp_fastretrans_alert(sk, prior_packets - tp->packets_out, 3767 is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
3775 newly_acked_sacked, flag); 3768 tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked,
3769 is_dupack, flag);
3776 } else { 3770 } else {
3777 if ((flag & FLAG_DATA_ACKED) && !frto_cwnd) 3771 if ((flag & FLAG_DATA_ACKED) && !frto_cwnd)
3778 tcp_cong_avoid(sk, ack, prior_in_flight); 3772 tcp_cong_avoid(sk, ack, prior_in_flight);
@@ -3784,6 +3778,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3784 return 1; 3778 return 1;
3785 3779
3786no_queue: 3780no_queue:
3781 /* If data was DSACKed, see if we can undo a cwnd reduction. */
3782 if (flag & FLAG_DSACKING_ACK)
3783 tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked,
3784 is_dupack, flag);
3787 /* If this ack opens up a zero window, clear backoff. It was 3785 /* If this ack opens up a zero window, clear backoff. It was
3788 * being used to time the probes, and is probably far higher than 3786 * being used to time the probes, and is probably far higher than
3789 * it needs to be for normal retransmission. 3787 * it needs to be for normal retransmission.
@@ -3797,10 +3795,14 @@ invalid_ack:
3797 return -1; 3795 return -1;
3798 3796
3799old_ack: 3797old_ack:
3798 /* If data was SACKed, tag it and see if we should send more data.
3799 * If data was DSACKed, see if we can undo a cwnd reduction.
3800 */
3800 if (TCP_SKB_CB(skb)->sacked) { 3801 if (TCP_SKB_CB(skb)->sacked) {
3801 tcp_sacktag_write_queue(sk, skb, prior_snd_una); 3802 flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);
3802 if (icsk->icsk_ca_state == TCP_CA_Open) 3803 newly_acked_sacked = tp->sacked_out - prior_sacked;
3803 tcp_try_keep_open(sk); 3804 tcp_fastretrans_alert(sk, pkts_acked, newly_acked_sacked,
3805 is_dupack, flag);
3804 } 3806 }
3805 3807
3806 SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt); 3808 SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt);
@@ -3876,7 +3878,7 @@ void tcp_parse_options(const struct sk_buff *skb, struct tcp_options_received *o
3876 case TCPOPT_SACK_PERM: 3878 case TCPOPT_SACK_PERM:
3877 if (opsize == TCPOLEN_SACK_PERM && th->syn && 3879 if (opsize == TCPOLEN_SACK_PERM && th->syn &&
3878 !estab && sysctl_tcp_sack) { 3880 !estab && sysctl_tcp_sack) {
3879 opt_rx->sack_ok = 1; 3881 opt_rx->sack_ok = TCP_SACK_SEEN;
3880 tcp_sack_reset(opt_rx); 3882 tcp_sack_reset(opt_rx);
3881 } 3883 }
3882 break; 3884 break;
@@ -4864,7 +4866,7 @@ static int tcp_prune_queue(struct sock *sk)
4864 4866
4865 if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) 4867 if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
4866 tcp_clamp_window(sk); 4868 tcp_clamp_window(sk);
4867 else if (tcp_memory_pressure) 4869 else if (sk_under_memory_pressure(sk))
4868 tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss); 4870 tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss);
4869 4871
4870 tcp_collapse_ofo_queue(sk); 4872 tcp_collapse_ofo_queue(sk);
@@ -4930,11 +4932,11 @@ static int tcp_should_expand_sndbuf(const struct sock *sk)
4930 return 0; 4932 return 0;
4931 4933
4932 /* If we are under global TCP memory pressure, do not expand. */ 4934 /* If we are under global TCP memory pressure, do not expand. */
4933 if (tcp_memory_pressure) 4935 if (sk_under_memory_pressure(sk))
4934 return 0; 4936 return 0;
4935 4937
4936 /* If we are under soft global TCP memory pressure, do not expand. */ 4938 /* If we are under soft global TCP memory pressure, do not expand. */
4937 if (atomic_long_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) 4939 if (sk_memory_allocated(sk) >= sk_prot_mem_limits(sk, 0))
4938 return 0; 4940 return 0;
4939 4941
4940 /* If we filled the congestion window, do not expand. */ 4942 /* If we filled the congestion window, do not expand. */
@@ -5809,6 +5811,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5809 goto discard; 5811 goto discard;
5810 5812
5811 if (th->syn) { 5813 if (th->syn) {
5814 if (th->fin)
5815 goto discard;
5812 if (icsk->icsk_af_ops->conn_request(sk, skb) < 0) 5816 if (icsk->icsk_af_ops->conn_request(sk, skb) < 0)
5813 return 1; 5817 return 1;
5814 5818