The branch main has been updated by des:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=2af70d7a384934cee497fb6d75678e04f1416287

commit 2af70d7a384934cee497fb6d75678e04f1416287
Author:     Dag-Erling Smørgrav <[email protected]>
AuthorDate: 2026-05-18 14:50:14 +0000
Commit:     Dag-Erling Smørgrav <[email protected]>
CommitDate: 2026-05-18 14:50:14 +0000

    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
---
 share/man/man4/tcp.4       | 11 ++++++++-
 sys/netinet/tcp_timewait.c | 58 +++++++++++++++++++++++++++++-----------------
 sys/netinet/tcp_var.h      |  2 ++
 3 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4
index 4c01daf4e14e..8bc1eb858a07 100644
--- a/share/man/man4/tcp.4
+++ b/share/man/man4/tcp.4
@@ -31,7 +31,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd May 7, 2026
+.Dd May 17, 2026
 .Dt TCP 4
 .Os
 .Sh NAME
@@ -940,6 +940,10 @@ maximum segment size.
 This helps throughput in general, but
 particularly affects short transfers and high-bandwidth large
 propagation-delay connections.
+.It Va rfc6191
+Enable RFC 6191 connection recycling, which allows faster connection
+recycling in certain circumstances when the new connection has TCP
+timestamps enabled.
 .It Va sack.enable
 Enable support for RFC 2018, TCP Selective Acknowledgment option,
 which allows the receiver to inform the sender about all successfully
@@ -1145,6 +1149,11 @@ when trying to use a TCP function block that is not 
available;
 .%T "Improving TCP's Robustness to Blind In-Window Attacks"
 .%O "RFC 5961"
 .Re
+.Rs
+.%A "F. Gont"
+.%T "Reducing the TIME-WAIT State Using TCP Timestamps"
+.%O "RFC 6191"
+.Re
 .Sh HISTORY
 The
 .Tn TCP
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)

Reply via email to