aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2026-05-18 14:50:14 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2026-05-18 14:50:14 +0000
commit2af70d7a384934cee497fb6d75678e04f1416287 (patch)
tree5c1c31d3cef252f93f5c5a4b94269026a0c9909e /sys/netinet
parent3abc07947c14f5c30e5328d56a2da8dbf8412ebf (diff)
tcp: Make RFC 6191 support configurable
Add a default-on per-VIMAGE sysctl for RFC 6191 connection recycling. This makes it possible to merge the change to older branches where it can be switched off by default to minimize risk. MFC after: 1 week Sponsored by: Klara, Inc. Sponsored by: Modirum MDPay Reviewed by: pouria, marius.h_lden.org, tuexen Differential Revision: https://reviews.freebsd.org/D57045
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/tcp_timewait.c58
-rw-r--r--sys/netinet/tcp_var.h2
2 files changed, 39 insertions, 21 deletions
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 4f4ca445fa46..276733066c30 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -91,6 +91,11 @@
#include <security/mac/mac_framework.h>
+VNET_DEFINE(int, tcp_do_rfc6191) = 1;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, rfc3465, CTLFLAG_VNET | CTLFLAG_RW,
+ &VNET_NAME(tcp_do_rfc6191), 0,
+ "Enable RFC 6191 (Reduced TIME-WAIT State)");
+
static u_int
tcp_eff_msl(struct tcpcb *tp)
{
@@ -223,29 +228,40 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th,
}
/*
- * If a new connection request is received
- * while in TIME_WAIT, drop the old connection
- * and start over if allowed by RFC 6191.
+ * If a new connection request is received while in TIME_WAIT,
+ * drop the old connection and start over if appropriate.
+ *
+ * The original rule is to start over if and only if the sequence
+ * number of the new connection is greater than the last sequence
+ * number seen on the old connection.
+ *
+ * Additionally, RFC 6191 allows restarting if the new connection
+ * has TCP timestamps enabled and either the old one didn't, or it
+ * did but the timestamp on the incoming SYN is greater than the
+ * last timestamp seen on the old connection.
+ *
* Allow UDP port number changes in this case.
*/
- if (((thflags & (TH_SYN | TH_ACK)) == TH_SYN) &&
- ((((tp->t_flags & TF_RCVD_TSTMP) != 0) &&
- ((to->to_flags & TOF_TS) != 0) &&
- TSTMP_LT(tp->ts_recent, to->to_tsval)) ||
- (((tp->t_flags & TF_RCVD_TSTMP) == 0) &&
- ((to->to_flags & TOF_TS) != 0) &&
- (V_tcp_tolerate_missing_ts == 0)) ||
- SEQ_GT(th->th_seq, tp->rcv_nxt))) {
- /*
- * In case we can't upgrade our lock just pretend we have
- * lost this packet.
- */
- if (INP_TRY_UPGRADE(inp) == 0)
- goto drop;
- if ((tp = tcp_close(tp)) != NULL)
- INP_WUNLOCK(inp);
- TCPSTAT_INC(tcps_tw_recycles);
- return (true);
+ if ((thflags & (TH_SYN | TH_ACK)) == TH_SYN) {
+ bool rfc6191 = false;
+
+ if ((to->to_flags & TOF_TS) != 0 && V_tcp_do_rfc6191) {
+ rfc6191 = (tp->t_flags & TF_RCVD_TSTMP) != 0 ?
+ TSTMP_LT(tp->ts_recent, to->to_tsval) :
+ V_tcp_tolerate_missing_ts == 0;
+ }
+ if (rfc6191 || SEQ_GT(th->th_seq, tp->rcv_nxt)) {
+ /*
+ * In case we can't upgrade our lock just pretend
+ * we have lost this packet.
+ */
+ if (INP_TRY_UPGRADE(inp) == 0)
+ goto drop;
+ if ((tp = tcp_close(tp)) != NULL)
+ INP_WUNLOCK(inp);
+ TCPSTAT_INC(tcps_tw_recycles);
+ return (true);
+ }
}
/*
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index a1b0519ceac3..5b3733e8e91e 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -1308,6 +1308,7 @@ VNET_DECLARE(int, tcp_tolerate_missing_ts);
VNET_DECLARE(int, tcp_do_rfc3042);
VNET_DECLARE(int, tcp_do_rfc3390);
VNET_DECLARE(int, tcp_do_rfc3465);
+VNET_DECLARE(int, tcp_do_rfc6191);
VNET_DECLARE(int, tcp_do_sack);
VNET_DECLARE(int, tcp_do_tso);
VNET_DECLARE(int, tcp_ecn_maxretries);
@@ -1358,6 +1359,7 @@ VNET_DECLARE(struct inpcbinfo, tcbinfo);
#define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042)
#define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390)
#define V_tcp_do_rfc3465 VNET(tcp_do_rfc3465)
+#define V_tcp_do_rfc6191 VNET(tcp_do_rfc6191)
#define V_tcp_do_sack VNET(tcp_do_sack)
#define V_tcp_do_tso VNET(tcp_do_tso)
#define V_tcp_ecn_maxretries VNET(tcp_ecn_maxretries)