Commit 3ba07527 authored by Eric Dumazet's avatar Eric Dumazet Committed by Jakub Kicinski
Browse files

tcp: be less liberal in TSEcr received while in SYN_RECV state

Yong-Hao Zou mentioned that linux was not strict as other OS in 3WHS,
for flows using TCP TS option (RFC 7323)

As hinted by an old comment in tcp_check_req(),
we can check the TSEcr value in the incoming packet corresponds
to one of the SYNACK TSval values we have sent.

In this patch, I record the oldest and most recent values
that SYNACK packets have used.

Send a challenge ACK if we receive a TSEcr outside
of this range, and increase a new SNMP counter.

nstat -az | grep TSEcrRejected
TcpExtTSEcrRejected            0                  0.0

Due to TCP fastopen implementation, do not apply yet these checks
for fastopen flows.

v2: No longer use req->num_timeout, but treq->snt_tsval_first
    to detect when first SYNACK is prepared. This means
    we make sure to not send an initial zero TSval.
    Make sure MPTCP and TCP selftests are passing.
    Change MIB name to TcpExtTSEcrRejected

v1: https://lore.kernel.org/netdev/CADVnQykD8i4ArpSZaPKaoNxLJ2if2ts9m4As+=Jvdkrgx1qMHw@mail.gmail.com/T/



Reported-by: default avatarYong-Hao Zou <yonghaoz1994@gmail.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarMatthieu Baerts (NGI0) <matttbe@kernel.org>
Reviewed-by: default avatarNeal Cardwell <ncardwell@google.com>
Reviewed-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250225171048.3105061-1-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 91c8d8e4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ unsigned_long LINUX_MIB_TIMEWAITRECYCLED
unsigned_long  LINUX_MIB_TIMEWAITKILLED
unsigned_long  LINUX_MIB_PAWSACTIVEREJECTED
unsigned_long  LINUX_MIB_PAWSESTABREJECTED
unsigned_long  LINUX_MIB_TSECR_REJECTED
unsigned_long  LINUX_MIB_DELAYEDACKLOST
unsigned_long  LINUX_MIB_LISTENOVERFLOWS
unsigned_long  LINUX_MIB_LISTENDROPS
+2 −0
Original line number Diff line number Diff line
@@ -160,6 +160,8 @@ struct tcp_request_sock {
	u32				rcv_isn;
	u32				snt_isn;
	u32				ts_off;
	u32				snt_tsval_first;
	u32				snt_tsval_last;
	u32				last_oow_ack_time; /* last SYNACK */
	u32				rcv_nxt; /* the ack # by SYNACK. For
						  * FastOpen it's the seq#
+1 −0
Original line number Diff line number Diff line
@@ -186,6 +186,7 @@ enum
	LINUX_MIB_TIMEWAITKILLED,		/* TimeWaitKilled */
	LINUX_MIB_PAWSACTIVEREJECTED,		/* PAWSActiveRejected */
	LINUX_MIB_PAWSESTABREJECTED,		/* PAWSEstabRejected */
	LINUX_MIB_TSECRREJECTED,		/* TSEcrRejected */
	LINUX_MIB_PAWS_OLD_ACK,			/* PAWSOldAck */
	LINUX_MIB_DELAYEDACKS,			/* DelayedACKs */
	LINUX_MIB_DELAYEDACKLOCKED,		/* DelayedACKLocked */
+1 −0
Original line number Diff line number Diff line
@@ -189,6 +189,7 @@ static const struct snmp_mib snmp4_net_list[] = {
	SNMP_MIB_ITEM("TWKilled", LINUX_MIB_TIMEWAITKILLED),
	SNMP_MIB_ITEM("PAWSActive", LINUX_MIB_PAWSACTIVEREJECTED),
	SNMP_MIB_ITEM("PAWSEstab", LINUX_MIB_PAWSESTABREJECTED),
	SNMP_MIB_ITEM("TSEcrRejected", LINUX_MIB_TSECRREJECTED),
	SNMP_MIB_ITEM("PAWSOldAck", LINUX_MIB_PAWS_OLD_ACK),
	SNMP_MIB_ITEM("DelayedACKs", LINUX_MIB_DELAYEDACKS),
	SNMP_MIB_ITEM("DelayedACKLocked", LINUX_MIB_DELAYEDACKLOCKED),
+1 −0
Original line number Diff line number Diff line
@@ -279,6 +279,7 @@ static int cookie_tcp_reqsk_init(struct sock *sk, struct sk_buff *skb,
		ireq->smc_ok = 0;

	treq->snt_synack = 0;
	treq->snt_tsval_first = 0;
	treq->tfo_listener = false;
	treq->txhash = net_tx_rndhash();
	treq->rcv_isn = ntohl(th->seq) - 1;
Loading