[TCP]: DSACK signals data receival, be conservative

In case a DSACK is received, it's better to lower cwnd as it's
a sign of data receival.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Ilpo Järvinen and committed by David S. Miller 49ff4bb4 2e605294

+4 -1
+4 -1
net/ipv4/tcp_input.c
··· 103 #define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ 104 #define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */ 105 #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ 106 107 #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) 108 #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) ··· 967 968 /* Check for D-SACK. */ 969 if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) { 970 found_dup_sack = 1; 971 tp->rx_opt.sack_ok |= 4; 972 NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); 973 } else if (num_sacks > 1 && 974 !after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) && 975 !before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) { 976 found_dup_sack = 1; 977 tp->rx_opt.sack_ok |= 4; 978 NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); ··· 1861 struct tcp_sock *tp = tcp_sk(sk); 1862 int decr = tp->snd_cwnd_cnt + 1; 1863 1864 - if ((flag&FLAG_ANY_PROGRESS) || 1865 (IsReno(tp) && !(flag&FLAG_NOT_DUP))) { 1866 tp->snd_cwnd_cnt = decr&1; 1867 decr >>= 1;
··· 103 #define FLAG_SLOWPATH 0x100 /* Do not skip RFC checks for window update.*/ 104 #define FLAG_ONLY_ORIG_SACKED 0x200 /* SACKs only non-rexmit sent before RTO */ 105 #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ 106 + #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained DSACK info */ 107 108 #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) 109 #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) ··· 966 967 /* Check for D-SACK. */ 968 if (before(ntohl(sp[0].start_seq), TCP_SKB_CB(ack_skb)->ack_seq)) { 969 + flag |= FLAG_DSACKING_ACK; 970 found_dup_sack = 1; 971 tp->rx_opt.sack_ok |= 4; 972 NET_INC_STATS_BH(LINUX_MIB_TCPDSACKRECV); 973 } else if (num_sacks > 1 && 974 !after(ntohl(sp[0].end_seq), ntohl(sp[1].end_seq)) && 975 !before(ntohl(sp[0].start_seq), ntohl(sp[1].start_seq))) { 976 + flag |= FLAG_DSACKING_ACK; 977 found_dup_sack = 1; 978 tp->rx_opt.sack_ok |= 4; 979 NET_INC_STATS_BH(LINUX_MIB_TCPDSACKOFORECV); ··· 1858 struct tcp_sock *tp = tcp_sk(sk); 1859 int decr = tp->snd_cwnd_cnt + 1; 1860 1861 + if ((flag&(FLAG_ANY_PROGRESS|FLAG_DSACKING_ACK)) || 1862 (IsReno(tp) && !(flag&FLAG_NOT_DUP))) { 1863 tp->snd_cwnd_cnt = decr&1; 1864 decr >>= 1;