Netdev Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH net] tcp: skip DSACKs with dubious sequence ranges
@ 2020-09-24 22:23 Priyaranjan Jha
2020-09-25 3:16 ` David Miller
0 siblings, 1 reply; 2+ messages in thread
From: Priyaranjan Jha @ 2020-09-24 22:23 UTC (permalink / raw)
To: David Miller
Cc: netdev, Priyaranjan Jha, Neal Cardwell, Yuchung Cheng, Eric Dumazet
From: Priyaranjan Jha <priyarjha@google.com>
Currently, we use length of DSACKed range to compute number of
delivered packets. And if sequence range in DSACK is corrupted,
we can get bogus dsacked/acked count, and bogus cwnd.
This patch put bounds on DSACKed range to skip update of data
delivery and spurious retransmission information, if the DSACK
is unlikely caused by sender's action:
- DSACKed range shouldn't be greater than maximum advertised rwnd.
- Total no. of DSACKed segments shouldn't be greater than total
no. of retransmitted segs. Unlike spurious retransmits, network
duplicates or corrupted DSACKs shouldn't be counted as delivery.
Signed-off-by: Priyaranjan Jha <priyarjha@google.com>
Signed-off-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/uapi/linux/snmp.h | 1 +
net/ipv4/proc.c | 1 +
net/ipv4/tcp_input.c | 32 +++++++++++++++++++++++++-------
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
index cee9f8e6fce3..f84e7bcad6de 100644
--- a/include/uapi/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
@@ -288,6 +288,7 @@ enum
LINUX_MIB_TCPTIMEOUTREHASH, /* TCPTimeoutRehash */
LINUX_MIB_TCPDUPLICATEDATAREHASH, /* TCPDuplicateDataRehash */
LINUX_MIB_TCPDSACKRECVSEGS, /* TCPDSACKRecvSegs */
+ LINUX_MIB_TCPDSACKIGNOREDDUBIOUS, /* TCPDSACKIgnoredDubious */
__LINUX_MIB_MAX
};
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 1074df726ec0..8d5e1695b9aa 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -293,6 +293,7 @@ static const struct snmp_mib snmp4_net_list[] = {
SNMP_MIB_ITEM("TcpTimeoutRehash", LINUX_MIB_TCPTIMEOUTREHASH),
SNMP_MIB_ITEM("TcpDuplicateDataRehash", LINUX_MIB_TCPDUPLICATEDATAREHASH),
SNMP_MIB_ITEM("TCPDSACKRecvSegs", LINUX_MIB_TCPDSACKRECVSEGS),
+ SNMP_MIB_ITEM("TCPDSACKIgnoredDubious", LINUX_MIB_TCPDSACKIGNOREDDUBIOUS),
SNMP_MIB_SENTINEL
};
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 184ea556f50e..b1ce2054291d 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -885,21 +885,34 @@ struct tcp_sacktag_state {
struct rate_sample *rate;
};
-/* Take a notice that peer is sending D-SACKs */
+/* Take a notice that peer is sending D-SACKs. Skip update of data delivery
+ * and spurious retransmission information if this DSACK is unlikely caused by
+ * sender's action:
+ * - DSACKed sequence range is larger than maximum receiver's window.
+ * - Total no. of DSACKed segments exceed the total no. of retransmitted segs.
+ */
static u32 tcp_dsack_seen(struct tcp_sock *tp, u32 start_seq,
u32 end_seq, struct tcp_sacktag_state *state)
{
u32 seq_len, dup_segs = 1;
- if (before(start_seq, end_seq)) {
- seq_len = end_seq - start_seq;
- if (seq_len > tp->mss_cache)
- dup_segs = DIV_ROUND_UP(seq_len, tp->mss_cache);
- }
+ if (!before(start_seq, end_seq))
+ return 0;
+
+ seq_len = end_seq - start_seq;
+ /* Dubious DSACK: DSACKed range greater than maximum advertised rwnd */
+ if (seq_len > tp->max_window)
+ return 0;
+ if (seq_len > tp->mss_cache)
+ dup_segs = DIV_ROUND_UP(seq_len, tp->mss_cache);
+
+ tp->dsack_dups += dup_segs;
+ /* Skip the DSACK if dup segs weren't retransmitted by sender */
+ if (tp->dsack_dups > tp->total_retrans)
+ return 0;
tp->rx_opt.sack_ok |= TCP_DSACK_SEEN;
tp->rack.dsack_seen = 1;
- tp->dsack_dups += dup_segs;
state->flag |= FLAG_DSACKING_ACK;
/* A spurious retransmission is delivered */
@@ -1153,6 +1166,11 @@ static bool tcp_check_dsack(struct sock *sk, const struct sk_buff *ack_skb,
}
dup_segs = tcp_dsack_seen(tp, start_seq_0, end_seq_0, state);
+ if (!dup_segs) { /* Skip dubious DSACK */
+ NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPDSACKIGNOREDDUBIOUS);
+ return false;
+ }
+
NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPDSACKRECVSEGS, dup_segs);
/* D-SACK for already forgotten data... Do dumb counting. */
--
2.28.0.681.g6f77f65b4e-goog
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH net] tcp: skip DSACKs with dubious sequence ranges
2020-09-24 22:23 [PATCH net] tcp: skip DSACKs with dubious sequence ranges Priyaranjan Jha
@ 2020-09-25 3:16 ` David Miller
0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2020-09-25 3:16 UTC (permalink / raw)
To: priyarjha.kernel; +Cc: netdev, priyarjha, ncardwell, ycheng, edumazet
From: Priyaranjan Jha <priyarjha.kernel@gmail.com>
Date: Thu, 24 Sep 2020 15:23:14 -0700
> From: Priyaranjan Jha <priyarjha@google.com>
>
> Currently, we use length of DSACKed range to compute number of
> delivered packets. And if sequence range in DSACK is corrupted,
> we can get bogus dsacked/acked count, and bogus cwnd.
>
> This patch put bounds on DSACKed range to skip update of data
> delivery and spurious retransmission information, if the DSACK
> is unlikely caused by sender's action:
> - DSACKed range shouldn't be greater than maximum advertised rwnd.
> - Total no. of DSACKed segments shouldn't be greater than total
> no. of retransmitted segs. Unlike spurious retransmits, network
> duplicates or corrupted DSACKs shouldn't be counted as delivery.
>
> Signed-off-by: Priyaranjan Jha <priyarjha@google.com>
> Signed-off-by: Neal Cardwell <ncardwell@google.com>
> Signed-off-by: Yuchung Cheng <ycheng@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-09-25 3:16 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-24 22:23 [PATCH net] tcp: skip DSACKs with dubious sequence ranges Priyaranjan Jha
2020-09-25 3:16 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).