From: Shashank Mohan Jain <jain.sm@gmail.com>
To: Eric Dumazet <edumazet@kernel.org>,
Neal Cardwell <ncardwell@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
"David S. Miller" <davem@davemloft.net>
Cc: Kuniyuki Iwashima <kuniyu@google.com>,
Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH net-next v4 0/2] tcp: keep the route window metric when SO_RCVBUF is set before connect
Date: Wed, 21 Oct 2026 21:27:13 +0530 [thread overview]
Message-ID: <20261021155715.30094-1-jain.sm@gmail.com> (raw)
Since commit b025461303d8 ("tcp: update window_clamp when SO_RCVBUF is
set"), SO_RCVBUF set before connect() or on a listener leaves a non-zero
window_clamp behind. The SYN, SYN-ACK and SYN cookie paths take that for
a TCP_WINDOW_CLAMP set by the user, so the route "window" metric
(RTAX_WINDOW) is skipped, and a real TCP_WINDOW_CLAMP set before
SO_RCVBUF is overwritten.
Patch 1 records the clamp the user set with TCP_WINDOW_CLAMP in a new
field and keys the SYN, SYN-ACK and SYN cookie paths off it. Patch 2
adds nine packetdrill tests (active open, passive open, SYN cookies over
IPv4 and IPv6, TCP_WINDOW_CLAMP reset, SO_RCVBUF raise on an established
socket). All nine fail on net-next without patch 1 and pass with it.
As Jakub asked, the commit message of patch 1 now says how the problem
was found and how it was tested.
Changes since v3, all from the AI review of v3 (each point was checked
against net-next before acting on it):
- SYN cookies: cookie_v4_check() and cookie_v6_check() still used
"window_clamp ?: RTAX_WINDOW". With SO_RCVBUF on the listener and a
route window metric, v3 sent a SYN-ACK with wscale 0 while the cookie
child used rcv_wscale 5 (reproduced on the wire with v3, and by the
new cookie tests). The SYN-ACK path and both cookie paths now use
one helper, tcp_req_window_clamp().
- A single bit could leave window_clamp too low: v3's tcp_set_rcvbuf()
returned early once TCP_WINDOW_CLAMP was set, so after
tcp_init_buffer_space() lowered window_clamp, a larger SO_RCVBUF
could not raise it again. v4 stores the requested clamp (u32
window_clamp_user) and lets SO_RCVBUF move window_clamp up to it.
- Lockless read of a bitfield: the listener side now reads a separate
u32 with READ_ONCE(), written with WRITE_ONCE(), instead of a bit in
a byte shared with nonagle and rate_app_limited.
- window_clamp_user is listed in net_cachelines/tcp_sock.rst. It sits
in the cold part of struct tcp_sock; pahole shows the size (2432
bytes on x86_64, with and without MPTCP) and the fast path groups
unchanged.
- Selftests: symbolic TCP_FASTOPEN_CONNECT and TCP_FASTOPEN_NO_COOKIE
(TCP_WINDOW_CLAMP stays numeric because packetdrill has no symbol for
it, and the comment no longer refers to a local build); new listener
tests for SO_RCVBUF alone and for TCP_WINDOW_CLAMP then SO_RCVBUF;
SYN cookie tests for IPv4 and IPv6 that check tcpi_rcv_wscale of the
child; a TCP_WINDOW_CLAMP=0 reset test; a test that SO_RCVBUF raises
window_clamp up to the user's clamp and not above it.
- Patch 1 changelog: how the bug was found and tested; the cookie paths
are named.
- Rebased on current net-next.
Link: https://lore.kernel.org/all/20261012132622.48550-1-jain.sm@gmail.com/ (v3)
Changes since v2:
- track a user TCP_WINDOW_CLAMP instead of checking the socket state,
so the TCP_SYN_SENT paths (TCP_FASTOPEN_CONNECT, sock_ops) are fixed
too; corrected the changelog; two more selftests.
Changes since v1 (single [PATCH net]):
- retargeted from net to net-next, added the packetdrill selftest, and
rewrote the changelog.
Shashank Mohan Jain (2):
tcp: keep the route window metric when SO_RCVBUF is set before connect
selftests/net/packetdrill: cover SO_RCVBUF vs the route window clamp
.../networking/net_cachelines/tcp_sock.rst | 1 +
include/linux/tcp.h | 1 +
include/net/tcp.h | 14 ++++++++++
net/ipv4/syncookies.c | 3 +--
net/ipv4/tcp.c | 14 +++++++++-
net/ipv4/tcp_minisocks.c | 4 +--
net/ipv4/tcp_output.c | 2 +-
net/ipv6/syncookies.c | 2 +-
.../tcp_fastopen_connect_rcvbuf_window.pkt | 21 +++++++++++++++
.../tcp_rcvbuf_before_connect_window.pkt | 27 +++++++++++++++++++
.../tcp_rcvbuf_listener_window.pkt | 20 ++++++++++++++
.../tcp_syncookies_rcvbuf_window_ip4.pkt | 22 +++++++++++++++
.../tcp_syncookies_rcvbuf_window_ip6.pkt | 22 +++++++++++++++
.../tcp_window_clamp_rcvbuf_raise.pkt | 27 +++++++++++++++++++
.../tcp_window_clamp_reset_rcvbuf.pkt | 22 +++++++++++++++
.../tcp_window_clamp_vs_rcvbuf.pkt | 23 ++++++++++++++++
.../tcp_window_clamp_vs_rcvbuf_listener.pkt | 25 +++++++++++++++++
17 files changed, 242 insertions(+), 8 deletions(-)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_fastopen_connect_rcvbuf_window.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_rcvbuf_before_connect_window.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_rcvbuf_listener_window.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_syncookies_rcvbuf_window_ip4.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_syncookies_rcvbuf_window_ip6.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_window_clamp_rcvbuf_raise.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_window_clamp_reset_rcvbuf.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_window_clamp_vs_rcvbuf.pkt
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_window_clamp_vs_rcvbuf_listener.pkt
base-commit: 279d5c8afcd38bd841832a39bfe1aa4f8518d98e
--
2.43.0
next reply other threads:[~2026-10-21 15:57 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 15:57 Shashank Mohan Jain [this message]
2026-10-21 15:57 ` [PATCH net-next v4 1/2] tcp: keep the route window metric when SO_RCVBUF is set before connect Shashank Mohan Jain
2026-10-21 20:51 ` Jakub Kicinski
2026-10-26 1:15 ` shashank Jain
2026-10-25 16:35 ` netdev-bot+sashiko
2026-10-21 15:57 ` [PATCH net-next v4 2/2] selftests/net/packetdrill: cover SO_RCVBUF vs the route window clamp Shashank Mohan Jain
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261021155715.30094-1-jain.sm@gmail.com \
--to=jain.sm@gmail.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ncardwell@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.