From owner-dev-commits-src-all@freebsd.org Thu Jan 14 19:39:26 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id CD88B4EC20D; Thu, 14 Jan 2021 19:39:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4DGvlL5RqMz4qyK; Thu, 14 Jan 2021 19:39:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id ADA18744D; Thu, 14 Jan 2021 19:39:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 10EJdQFc043932; Thu, 14 Jan 2021 19:39:26 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 10EJdQQw043931; Thu, 14 Jan 2021 19:39:26 GMT (envelope-from git) Date: Thu, 14 Jan 2021 19:39:26 GMT Message-Id: <202101141939.10EJdQQw043931@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Michael Tuexen Subject: git: d2b3ceddccac - main - tcp: add sysctl to tolerate TCP segments missing timestamps MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: tuexen X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: d2b3ceddccac60b563f642898e3a314647666a10 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2021 19:39:26 -0000 The branch main has been updated by tuexen: URL: https://cgit.FreeBSD.org/src/commit/?id=d2b3ceddccac60b563f642898e3a314647666a10 commit d2b3ceddccac60b563f642898e3a314647666a10 Author: Michael Tuexen AuthorDate: 2021-01-13 21:48:17 +0000 Commit: Michael Tuexen CommitDate: 2021-01-14 18:28:25 +0000 tcp: add sysctl to tolerate TCP segments missing timestamps When timestamp support has been negotiated, TCP segements received without a timestamp should be discarded. However, there are broken TCP implementations (for example, stacks used by Omniswitch 63xx and 64xx models), which send TCP segments without timestamps although they negotiated timestamp support. This patch adds a sysctl variable which tolerates such TCP segments and allows to interoperate with broken stacks. Reviewed by: jtl@, rscheff@ Differential Revision: https://reviews.freebsd.org/D28142 Sponsored by: Netflix, Inc. PR: 252449 MFC after: 1 week --- share/man/man4/tcp.4 | 23 ++++++++++++++++++++--- sys/netinet/tcp_input.c | 5 +++-- sys/netinet/tcp_stacks/bbr.c | 5 +++-- sys/netinet/tcp_stacks/rack.c | 5 +++-- sys/netinet/tcp_subr.c | 5 +++++ sys/netinet/tcp_syncache.c | 26 +++++++++++++++++++------- sys/netinet/tcp_timewait.c | 5 +++-- sys/netinet/tcp_var.h | 2 ++ 8 files changed, 58 insertions(+), 18 deletions(-) diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4 index 24b2e2d24d19..dee4040c0a98 100644 --- a/share/man/man4/tcp.4 +++ b/share/man/man4/tcp.4 @@ -34,7 +34,7 @@ .\" From: @(#)tcp.4 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd December 19, 2020 +.Dd January 14, 2021 .Dt TCP 4 .Os .Sh NAME @@ -369,8 +369,17 @@ MIB. .Bl -tag -width ".Va TCPCTL_DO_RFC1323" .It Dv TCPCTL_DO_RFC1323 .Pq Va rfc1323 -Implement the window scaling and timestamp options of RFC 1323 +Implement the window scaling and timestamp options of RFC 1323/RFC 7323 (default is true). +.It Va tolerate_missing_ts +Tolerate the missing of timestamps (RFC 1323/RFC 7323) for +.Tn TCP +segments belonging to +.Tn TCP +connections for which support of +.Tn TCP +timestamps has been negotiated. +(default is 0, i.e., the missing of timestamps is not tolerated). .It Dv TCPCTL_MSSDFLT .Pq Va mssdflt The default value used for the maximum segment size @@ -728,12 +737,20 @@ when trying to use a TCP function block that is not available; .Xr tcp_functions 9 .Rs .%A "V. Jacobson" -.%A "R. Braden" +.%A "B. Braden" .%A "D. Borman" .%T "TCP Extensions for High Performance" .%O "RFC 1323" .Re .Rs +.%A "D. Borman" +.%A "B. Braden" +.%A "V. Jacobson" +.%A "R. Scheffenegger" +.%T "TCP Extensions for High Performance" +.%O "RFC 7323" +.Re +.Rs .%A "A. Heffernan" .%T "Protection of BGP Sessions via the TCP MD5 Signature Option" .%O "RFC 2385" diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index dda37d4795c9..283d42b594bd 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1692,11 +1692,12 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop - * the segment, unless it is a RST segment. + * the segment, unless it is a RST segment or missing timestamps are + * tolerated. * See section 3.2 of RFC 7323. */ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS)) { - if ((thflags & TH_RST) != 0) { + if (((thflags & TH_RST) != 0) || V_tcp_tolerate_missing_ts) { if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { log(LOG_DEBUG, "%s; %s: Timestamp missing, " "segment processed normally\n", diff --git a/sys/netinet/tcp_stacks/bbr.c b/sys/netinet/tcp_stacks/bbr.c index e59d9b9ff168..49ed7e992fba 100644 --- a/sys/netinet/tcp_stacks/bbr.c +++ b/sys/netinet/tcp_stacks/bbr.c @@ -11463,11 +11463,12 @@ bbr_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so, /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop - * the segment, unless it is a RST segment. + * the segment, unless it is a RST segment or missing timestamps are + * tolerated. * See section 3.2 of RFC 7323. */ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS) && - ((thflags & TH_RST) == 0)) { + ((thflags & TH_RST) == 0) && (V_tcp_tolerate_missing_ts == 0)) { retval = 0; goto done_with_input; } diff --git a/sys/netinet/tcp_stacks/rack.c b/sys/netinet/tcp_stacks/rack.c index 7c81e8b3a2bc..8e00cae85496 100644 --- a/sys/netinet/tcp_stacks/rack.c +++ b/sys/netinet/tcp_stacks/rack.c @@ -10879,11 +10879,12 @@ rack_do_segment_nounlock(struct mbuf *m, struct tcphdr *th, struct socket *so, /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop - * the segment, unless it is a RST segment. + * the segment, unless it is a RST segment or missing timestamps are + * tolerated. * See section 3.2 of RFC 7323. */ if ((tp->t_flags & TF_RCVD_TSTMP) && !(to.to_flags & TOF_TS) && - ((thflags & TH_RST) == 0)) { + ((thflags & TH_RST) == 0) && (V_tcp_tolerate_missing_ts == 0)) { way_out = 5; retval = 0; goto done_with_input; diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index b1ccb9a1acbe..b39d2b43d3a2 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -256,6 +256,11 @@ SYSCTL_INT(_net_inet_tcp, TCPCTL_DO_RFC1323, rfc1323, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_do_rfc1323), 0, "Enable rfc1323 (high performance TCP) extensions"); +VNET_DEFINE(int, tcp_tolerate_missing_ts) = 0; +SYSCTL_INT(_net_inet_tcp, OID_AUTO, tolerate_missing_ts, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(tcp_tolerate_missing_ts), 0, + "Tolerate missing TCP timestamps"); + VNET_DEFINE(int, tcp_ts_offset_per_conn) = 1; SYSCTL_INT(_net_inet_tcp, OID_AUTO, ts_offset_per_conn, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_ts_offset_per_conn), 0, diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 4697374084ab..e59a41fc1102 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1231,18 +1231,30 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop - * the segment. + * the segment, unless the missing timestamps are tolerated. * See section 3.2 of RFC 7323. */ if ((sc->sc_flags & SCF_TIMESTAMP) && !(to->to_flags & TOF_TS)) { - SCH_UNLOCK(sch); - if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { - log(LOG_DEBUG, "%s; %s: Timestamp missing, " - "segment silently dropped\n", s, __func__); - free(s, M_TCPLOG); + if (V_tcp_tolerate_missing_ts) { + if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { + log(LOG_DEBUG, + "%s; %s: Timestamp missing, " + "segment processed normally\n", + s, __func__); + free(s, M_TCPLOG); + } + } else { + SCH_UNLOCK(sch); + if ((s = tcp_log_addrs(inc, th, NULL, NULL))) { + log(LOG_DEBUG, + "%s; %s: Timestamp missing, " + "segment silently dropped\n", + s, __func__); + free(s, M_TCPLOG); + } + return (-1); /* Do not send RST */ } - return (-1); /* Do not send RST */ } /* diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c index d7e3cce44b89..f98927b196fc 100644 --- a/sys/netinet/tcp_timewait.c +++ b/sys/netinet/tcp_timewait.c @@ -451,10 +451,11 @@ tcp_twcheck(struct inpcb *inp, struct tcpopt *to, struct tcphdr *th, /* * If timestamps were negotiated during SYN/ACK and a * segment without a timestamp is received, silently drop - * the segment. + * the segment, unless the missing timestamps are tolerated. * See section 3.2 of RFC 7323. */ - if (((to->to_flags & TOF_TS) == 0) && (tw->t_recent != 0)) { + if (((to->to_flags & TOF_TS) == 0) && (tw->t_recent != 0) && + (V_tcp_tolerate_missing_ts == 0)) { goto drop; } diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index d9235f23706c..6e22d75ac441 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -840,6 +840,7 @@ VNET_DECLARE(int, tcp_do_autosndbuf); VNET_DECLARE(int, tcp_do_ecn); VNET_DECLARE(int, tcp_do_newcwv); VNET_DECLARE(int, tcp_do_rfc1323); +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); @@ -883,6 +884,7 @@ VNET_DECLARE(struct inpcbinfo, tcbinfo); #define V_tcp_do_autosndbuf VNET(tcp_do_autosndbuf) #define V_tcp_do_ecn VNET(tcp_do_ecn) #define V_tcp_do_rfc1323 VNET(tcp_do_rfc1323) +#define V_tcp_tolerate_missing_ts VNET(tcp_tolerate_missing_ts) #define V_tcp_ts_offset_per_conn VNET(tcp_ts_offset_per_conn) #define V_tcp_do_rfc3042 VNET(tcp_do_rfc3042) #define V_tcp_do_rfc3390 VNET(tcp_do_rfc3390)