* [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect
@ 2026-10-11 11:16 Shashank Mohan Jain
2026-10-11 11:16 ` [PATCH net-next 1/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected Shashank Mohan Jain
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Shashank Mohan Jain @ 2026-10-11 11:16 UTC (permalink / raw)
To: Eric Dumazet, Neal Cardwell, Jakub Kicinski, Paolo Abeni,
David S. Miller
Cc: Kuniyuki Iwashima, Simon Horman, netdev, linux-kernel
v1 was a single [PATCH net] with only the fix. Eric Dumazet pointed out
that the changelog overstated the effect (TCP_WINDOW_CLAMP does not
persist past the first data segments), that "no window scaling" was
inaccurate (the option is still sent, with a shift of 0), and asked for
a packetdrill test and for the series to target net-next. This v2
rewrites the changelog accordingly, leads with the common
SO_RCVBUF-before-connect / listener case, adds a packetdrill test, and
is based on net-next.
Patch 1 is the fix: setsockopt(SO_RCVBUF) must not write tp->window_clamp
while the socket is in TCP_CLOSE or TCP_LISTEN, so that
tcp_connect_init() and tcp_openreq_init_rwin() still apply the route
window metric (RTAX_WINDOW) and the defaults to the SYN / SYN-ACK window
and window scale.
Patch 2 adds a packetdrill test: with "window 4096" on the route to the
peer and SO_RCVBUF set before connect(), the SYN must advertise the
route-clamped window and window scale 0. On an unpatched net-next kernel
the SYN carries win 65535, wscale 5; with patch 1 it carries win 2920,
wscale 0.
Changes since v1 (single [PATCH net]):
- changelog: say the patch restores the SYN/SYN-ACK window and window
scale, not a persistent clamp; note that since a2cbb1603943
tcp_measure_rcv_mss() recomputes window_clamp from sk_rcvbuf anyway.
- changelog: "wscale 0 (option still sent, shift 0)" instead of "no
window scaling"; lead with the SO_RCVBUF-before-connect / listener
case.
- add the packetdrill selftest (patch 2).
- retarget from net to net-next.
Shashank Mohan Jain (2):
tcp: don't set window_clamp from SO_RCVBUF before the socket is
connected
selftests/net/packetdrill: test SO_RCVBUF before connect keeps route
window
net/ipv4/tcp.c | 8 ++++++
.../tcp_rcvbuf_before_connect_window.pkt | 27 +++++++++++++++++++
2 files changed, 35 insertions(+)
create mode 100644 tools/testing/selftests/net/packetdrill/tcp_rcvbuf_before_connect_window.pkt
base-commit: d8674294aefef02266c4d47ad10131f1bffbe534
--
2.43.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH net-next 1/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected 2026-10-11 11:16 [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect Shashank Mohan Jain @ 2026-10-11 11:16 ` Shashank Mohan Jain 2026-10-12 11:18 ` netdev-bot+sashiko 2026-10-11 11:16 ` [PATCH net-next 2/2] selftests/net/packetdrill: test SO_RCVBUF before connect keeps route window Shashank Mohan Jain 2026-10-11 11:19 ` [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect netdev-bot+sinfo 2 siblings, 1 reply; 9+ messages in thread From: Shashank Mohan Jain @ 2026-10-11 11:16 UTC (permalink / raw) To: Eric Dumazet, Neal Cardwell, Jakub Kicinski, Paolo Abeni, David S. Miller Cc: Kuniyuki Iwashima, Simon Horman, netdev, linux-kernel Since commit b025461303d8 ("tcp: update window_clamp when SO_RCVBUF is set"), setsockopt(SO_RCVBUF) stores tp->window_clamp in every socket state, including TCP_CLOSE and TCP_LISTEN. tcp_connect_init() and tcp_openreq_init_rwin() treat a non-zero window_clamp as a user clamp and, in that case, skip the route window metric (RTAX_WINDOW, "ip route ... window N"). A clamp left behind by an SO_RCVBUF call made before connect(), or on a listener, therefore changes the window and window scale advertised in the SYN and SYN-ACK: the route metric is no longer applied, and even without a route metric the advertised window and scale come from SO_RCVBUF instead of the defaults. This affects any application that sets SO_RCVBUF before connect() or listen(), which is more common than using the route metric. Example: two netns joined by a veth pair, "ip route ... window 4096" on both sides, SO_RCVBUF set to 1 MiB before connect(): before: SYN win 65535, wscale 5 after: SYN win 2920, wscale 0 wscale 0 means the window scale option is still sent, with a shift of 0. The "after" values match a kernel with b025461303d8 reverted; with no route metric the SYN window and scale are the defaults in both cases. This only concerns the handshake. Since commit a2cbb1603943 ("tcp: Update window clamping condition") tcp_measure_rcv_mss() recomputes window_clamp from sk_rcvbuf once the scaling ratio changes, so TCP_WINDOW_CLAMP does not persist past the first data segments, with or without this patch. Only update window_clamp from SO_RCVBUF once the socket is being set up: skip it in TCP_CLOSE and TCP_LISTEN. When the connection is established with SOCK_RCVBUF_LOCK set, both functions already clamp window_clamp to tcp_full_space() (the value tcp_set_rcvbuf() computes), so nothing is lost. Fixes: b025461303d8 ("tcp: update window_clamp when SO_RCVBUF is set") Assisted-by: LLM Signed-off-by: Shashank Mohan Jain <jain.sm@gmail.com> --- net/ipv4/tcp.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f4c9101e5..e523cb71b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1858,6 +1858,14 @@ int tcp_set_rcvlowat(struct sock *sk, int val) void tcp_set_rcvbuf(struct sock *sk, int val) { + /* Without a connection there is no clamp to update: it is chosen + * from the route's window metric and the buffer size when the + * connection is set up, see tcp_connect_init() and + * tcp_openreq_init_rwin(). + */ + if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) + return; + tcp_set_window_clamp(sk, tcp_win_from_space(sk, val)); } -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 1/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected 2026-10-11 11:16 ` [PATCH net-next 1/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected Shashank Mohan Jain @ 2026-10-12 11:18 ` netdev-bot+sashiko 2026-10-12 11:22 ` shashank Jain 2026-10-12 13:25 ` [PATCH net-next v2 0/2] " Shashank Mohan Jain 0 siblings, 2 replies; 9+ messages in thread From: netdev-bot+sashiko @ 2026-10-12 11:18 UTC (permalink / raw) To: jain.sm Cc: edumazet, ncardwell, kuba, pabeni, davem, kuniyu, horms, netdev, linux-kernel Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider. Critical: 0 · High: 1 · Medium: 1 · Low: 0 If you believe none of the issues are legitimate, please reply to each issue of Medium severity or higher and explain why the AI is wrong. If any of them are legitimate and you plan to respin, please let patchwork know by including "pw-bot: cr" as a separate line at the end of your reply (one such reply per series is enough). - [High] The fix is incomplete. - [Medium] The commit message misstates and overstates the impact. -- tcp: don't set window_clamp from SO_RCVBUF before the socket is connected This patch makes tcp_set_rcvbuf() skip the window_clamp update while the socket is in TCP_CLOSE or TCP_LISTEN. The aim is to stop a clamp derived from SO_RCVBUF from overriding the RTAX_WINDOW route metric in tcp_connect_init() and tcp_openreq_init_rwin(). > tcp_connect_init() and tcp_openreq_init_rwin() treat a non-zero > window_clamp as a user clamp and, in that case, skip the route window > metric (RTAX_WINDOW, "ip route ... window N"). A clamp left behind by an > SO_RCVBUF call made before connect(), or on a listener, therefore > changes the window and window scale advertised in the SYN and SYN-ACK: > the route metric is no longer applied, and even without a route metric > the advertised window and scale come from SO_RCVBUF instead of the > defaults. This affects any application that sets SO_RCVBUF before > connect() or listen(), which is more common than using the route metric. [Severity: Medium] Is the part about the case without a route metric accurate? __sock_set_rcvbuf() always sets SOCK_RCVBUF_LOCK and then calls tcp_set_rcvbuf(sk, sk->sk_rcvbuf). On the old kernel, the clamp left behind is therefore tcp_win_from_space(sk, sk_rcvbuf), which equals tcp_full_space(), or SOCK_MIN_RCVBUF / 2 if that is larger. scaling_ratio cannot change before connect. With no RTAX_WINDOW metric, the patched kernel sees window_clamp == 0 and reads a zero metric. Then this block runs: net/ipv4/tcp_output.c:tcp_connect_init() { ... if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && (tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0)) WRITE_ONCE(tp->window_clamp, tcp_full_space(sk)); ... } The old kernel reaches the same tcp_full_space() value through the "window_clamp > tcp_full_space(sk)" branch. tcp_openreq_init_rwin() does the same for req->rsk_window_clamp. Wouldn't both kernels then pass the same window_clamp to tcp_select_initial_window(), and advertise the same window and wscale in the SYN and SYN-ACK? If so, the visible change is limited to two cases: - routes with an RTAX_WINDOW metric - TCP_WINDOW_CLAMP followed by SO_RCVBUF on an unconnected socket or listener, where SO_RCVBUF no longer overwrites the clamp The message does not mention the second case. Neither case is "any application that sets SO_RCVBUF before connect() or listen()". The message also seems to contradict itself further down: > The "after" values match a kernel with b025461303d8 reverted; with no > route metric the SYN window and scale are the defaults in both cases. In both cases, wouldn't the values come from SO_RCVBUF via tcp_full_space() rather than from the defaults? > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > index f4c9101e5996..e523cb71b905 100644 > --- a/net/ipv4/tcp.c > +++ b/net/ipv4/tcp.c > @@ -1858,6 +1858,14 @@ int tcp_set_rcvlowat(struct sock *sk, int val) > > void tcp_set_rcvbuf(struct sock *sk, int val) > { > + /* Without a connection there is no clamp to update: it is chosen > + * from the route's window metric and the buffer size when the > + * connection is set up, see tcp_connect_init() and > + * tcp_openreq_init_rwin(). > + */ > + if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) > + return; [Severity: High] Does this check cover every case where SO_RCVBUF is applied before tcp_connect_init() runs? tcp_v4_connect() and tcp_v6_connect() switch the socket to TCP_SYN_SENT before tcp_connect()->tcp_connect_init(). A clamp written in that gap still passes this check, and there seem to be two ways to get there. The first is TCP_FASTOPEN_CONNECT with a cached cookie, where connect() returns early: net/ipv4/tcp_ipv4.c:tcp_v4_connect() { ... tcp_set_state(sk, TCP_SYN_SENT); ... if (tcp_fastopen_defer_connect(sk, &err)) return err; ... } If the application calls setsockopt(SO_RCVBUF) before its first write(), tcp_set_rcvbuf() sees TCP_SYN_SENT and stores a non-zero window_clamp. tcp_sendmsg_fastopen() later calls tcp_connect()->tcp_connect_init(). The second is a sock_ops BPF program. tcp_connect() runs the callback before tcp_connect_init(): net/ipv4/tcp_output.c:tcp_connect() { ... tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_CONNECT_CB, 0, NULL); ... tcp_connect_init(sk); ... } sol_socket_sockopt() allows SO_RCVBUF for bpf_setsockopt(). That call reaches __sock_set_rcvbuf()->tcp_set_rcvbuf() while the socket is in TCP_SYN_SENT. samples/bpf/tcp_bufs_kern.c, tcp_clamp_kern.c and tcp_iw_kern.c all use this pattern. In both cases tcp_connect_init() then skips the route metric: if (!tp->window_clamp) WRITE_ONCE(tp->window_clamp, dst_metric(dst, RTAX_WINDOW)); The SOCK_RCVBUF_LOCK block afterwards can only lower the clamp to tcp_full_space(). Doesn't that leave the b025461303d8 regression in place on these paths, even though this patch carries the Fixes: tag for it? The selftest in this series only covers SO_RCVBUF set before connect(). Would it work to base the check on whether tcp_connect_init() has run yet? Another option would be to let tcp_connect_init() and tcp_openreq_init_rwin() tell a TCP_WINDOW_CLAMP value apart from one derived from sk_rcvbuf. > + > tcp_set_window_clamp(sk, tcp_win_from_space(sk, val)); > } -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261011111606.14753-1-jain.sm%40gmail.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 1/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected 2026-10-12 11:18 ` netdev-bot+sashiko @ 2026-10-12 11:22 ` shashank Jain 2026-10-12 13:25 ` [PATCH net-next v2 0/2] " Shashank Mohan Jain 1 sibling, 0 replies; 9+ messages in thread From: shashank Jain @ 2026-10-12 11:22 UTC (permalink / raw) To: netdev-bot+sashiko Cc: edumazet, ncardwell, kuba, pabeni, davem, kuniyu, horms, netdev, linux-kernel On Mon, Oct 12, 2026, netdev-bot+sashiko@kernel.org wrote: > [High] Does this check cover every case where SO_RCVBUF is applied > before tcp_connect_init() runs? You are right, it does not. The socket is already in TCP_SYN_SENT before tcp_connect_init() runs, so SO_RCVBUF applied in that gap - via TCP_FASTOPEN_CONNECT before the first write, or via bpf_setsockopt() in a BPF_SOCK_OPS_TCP_CONNECT_CB program (as samples/bpf/tcp_clamp_kern.c and friends do) - still writes window_clamp and still overrides the route metric, and a state-based check cannot tell that SYN_SENT apart from a post-init one. v3 will instead distinguish a user TCP_WINDOW_CLAMP from an sk_rcvbuf-derived clamp, so tcp_connect_init() and tcp_openreq_init_rwin() apply the route metric whenever the clamp was not set via TCP_WINDOW_CLAMP; the selftest will cover the fastopen and sock_ops paths. > [Medium] Is the part about the case without a route metric accurate? No, you are correct. With no RTAX_WINDOW metric both the old and the patched kernel end at tcp_full_space() - the old kernel through the "window_clamp > tcp_full_space()" branch, the patched one through "window_clamp == 0" - so the advertised window and wscale are identical and derived from sk_rcvbuf, not from the defaults; the patch changes nothing there. The real impact is only (1) routes with an RTAX_WINDOW metric and (2) a TCP_WINDOW_CLAMP that a later SO_RCVBUF on an unconnected socket or listener overwrites. v3's changelog will say exactly that and drop the "any application" / "without a metric" claims. pw-bot: cr Thanks for the careful review. Shashank On Mon, Oct 12, 2026 at 4:48 PM <netdev-bot+sashiko@kernel.org> wrote: > > Thank you for your contribution! Sashiko AI review found 2 potential > issue(s) to consider. > > Critical: 0 · High: 1 · Medium: 1 · Low: 0 > > If you believe none of the issues are legitimate, please reply to each > issue of Medium severity or higher and explain why the AI is wrong. > If any of them are legitimate and you plan to respin, please let patchwork > know by including "pw-bot: cr" as a separate line at the end of your reply > (one such reply per series is enough). > > - [High] The fix is incomplete. > - [Medium] The commit message misstates and overstates the impact. > > -- > > tcp: don't set window_clamp from SO_RCVBUF before the socket is connected > > This patch makes tcp_set_rcvbuf() skip the window_clamp update while the > socket is in TCP_CLOSE or TCP_LISTEN. The aim is to stop a clamp derived > from SO_RCVBUF from overriding the RTAX_WINDOW route metric in > tcp_connect_init() and tcp_openreq_init_rwin(). > > > tcp_connect_init() and tcp_openreq_init_rwin() treat a non-zero > > window_clamp as a user clamp and, in that case, skip the route window > > metric (RTAX_WINDOW, "ip route ... window N"). A clamp left behind by an > > SO_RCVBUF call made before connect(), or on a listener, therefore > > changes the window and window scale advertised in the SYN and SYN-ACK: > > the route metric is no longer applied, and even without a route metric > > the advertised window and scale come from SO_RCVBUF instead of the > > defaults. This affects any application that sets SO_RCVBUF before > > connect() or listen(), which is more common than using the route metric. > > [Severity: Medium] > Is the part about the case without a route metric accurate? > > __sock_set_rcvbuf() always sets SOCK_RCVBUF_LOCK and then calls > tcp_set_rcvbuf(sk, sk->sk_rcvbuf). On the old kernel, the clamp left > behind is therefore tcp_win_from_space(sk, sk_rcvbuf), which equals > tcp_full_space(), or SOCK_MIN_RCVBUF / 2 if that is larger. > scaling_ratio cannot change before connect. > > With no RTAX_WINDOW metric, the patched kernel sees window_clamp == 0 and > reads a zero metric. Then this block runs: > > net/ipv4/tcp_output.c:tcp_connect_init() { > ... > if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && > (tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0)) > WRITE_ONCE(tp->window_clamp, tcp_full_space(sk)); > ... > } > > The old kernel reaches the same tcp_full_space() value through the > "window_clamp > tcp_full_space(sk)" branch. tcp_openreq_init_rwin() does > the same for req->rsk_window_clamp. > > Wouldn't both kernels then pass the same window_clamp to > tcp_select_initial_window(), and advertise the same window and wscale in > the SYN and SYN-ACK? > > If so, the visible change is limited to two cases: > > - routes with an RTAX_WINDOW metric > - TCP_WINDOW_CLAMP followed by SO_RCVBUF on an unconnected socket or > listener, where SO_RCVBUF no longer overwrites the clamp > > The message does not mention the second case. Neither case is "any > application that sets SO_RCVBUF before connect() or listen()". > > The message also seems to contradict itself further down: > > > The "after" values match a kernel with b025461303d8 reverted; with no > > route metric the SYN window and scale are the defaults in both cases. > > In both cases, wouldn't the values come from SO_RCVBUF via > tcp_full_space() rather than from the defaults? > > > diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c > > index f4c9101e5996..e523cb71b905 100644 > > --- a/net/ipv4/tcp.c > > +++ b/net/ipv4/tcp.c > > @@ -1858,6 +1858,14 @@ int tcp_set_rcvlowat(struct sock *sk, int val) > > > > void tcp_set_rcvbuf(struct sock *sk, int val) > > { > > + /* Without a connection there is no clamp to update: it is chosen > > + * from the route's window metric and the buffer size when the > > + * connection is set up, see tcp_connect_init() and > > + * tcp_openreq_init_rwin(). > > + */ > > + if ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) > > + return; > > [Severity: High] > Does this check cover every case where SO_RCVBUF is applied before > tcp_connect_init() runs? > > tcp_v4_connect() and tcp_v6_connect() switch the socket to TCP_SYN_SENT > before tcp_connect()->tcp_connect_init(). A clamp written in that gap > still passes this check, and there seem to be two ways to get there. > > The first is TCP_FASTOPEN_CONNECT with a cached cookie, where connect() > returns early: > > net/ipv4/tcp_ipv4.c:tcp_v4_connect() { > ... > tcp_set_state(sk, TCP_SYN_SENT); > ... > if (tcp_fastopen_defer_connect(sk, &err)) > return err; > ... > } > > If the application calls setsockopt(SO_RCVBUF) before its first write(), > tcp_set_rcvbuf() sees TCP_SYN_SENT and stores a non-zero window_clamp. > tcp_sendmsg_fastopen() later calls tcp_connect()->tcp_connect_init(). > > The second is a sock_ops BPF program. tcp_connect() runs the callback > before tcp_connect_init(): > > net/ipv4/tcp_output.c:tcp_connect() { > ... > tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_CONNECT_CB, 0, NULL); > ... > tcp_connect_init(sk); > ... > } > > sol_socket_sockopt() allows SO_RCVBUF for bpf_setsockopt(). That call > reaches __sock_set_rcvbuf()->tcp_set_rcvbuf() while the socket is in > TCP_SYN_SENT. samples/bpf/tcp_bufs_kern.c, tcp_clamp_kern.c and > tcp_iw_kern.c all use this pattern. > > In both cases tcp_connect_init() then skips the route metric: > > if (!tp->window_clamp) > WRITE_ONCE(tp->window_clamp, dst_metric(dst, RTAX_WINDOW)); > > The SOCK_RCVBUF_LOCK block afterwards can only lower the clamp to > tcp_full_space(). > > Doesn't that leave the b025461303d8 regression in place on these paths, > even though this patch carries the Fixes: tag for it? The selftest in this > series only covers SO_RCVBUF set before connect(). > > Would it work to base the check on whether tcp_connect_init() has run yet? > Another option would be to let tcp_connect_init() and > tcp_openreq_init_rwin() tell a TCP_WINDOW_CLAMP value apart from one > derived from sk_rcvbuf. > > > + > > tcp_set_window_clamp(sk, tcp_win_from_space(sk, val)); > > } > > -- > Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261011111606.14753-1-jain.sm%40gmail.com ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next v2 0/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected 2026-10-12 11:18 ` netdev-bot+sashiko 2026-10-12 11:22 ` shashank Jain @ 2026-10-12 13:25 ` Shashank Mohan Jain 1 sibling, 0 replies; 9+ messages in thread From: Shashank Mohan Jain @ 2026-10-12 13:25 UTC (permalink / raw) To: Eric Dumazet, Neal Cardwell, Jakub Kicinski, Paolo Abeni, David S. Miller Cc: Kuniyuki Iwashima, Simon Horman, netdev, linux-kernel On Mon, Oct 12, 2026, netdev-bot+sashiko@kernel.org wrote: > [High] Does this check cover every case where SO_RCVBUF is applied > before tcp_connect_init() runs? You are right, it does not. The socket is already in TCP_SYN_SENT before tcp_connect_init() runs, so SO_RCVBUF applied in that gap - via TCP_FASTOPEN_CONNECT before the first write, or via bpf_setsockopt() in a BPF_SOCK_OPS_TCP_CONNECT_CB program (as samples/bpf/tcp_clamp_kern.c and friends do) - still writes window_clamp and still overrides the route metric, and a state-based check cannot tell that SYN_SENT apart from a post-init one. v3 will instead distinguish a user TCP_WINDOW_CLAMP from an sk_rcvbuf-derived clamp, so tcp_connect_init() and tcp_openreq_init_rwin() apply the route metric whenever the clamp was not set via TCP_WINDOW_CLAMP; the selftest will cover the fastopen and sock_ops paths. > [Medium] Is the part about the case without a route metric accurate? No, you are correct. With no RTAX_WINDOW metric both the old and the patched kernel end at tcp_full_space() - the old kernel through the "window_clamp > tcp_full_space()" branch, the patched one through "window_clamp == 0" - so the advertised window and wscale are identical and derived from sk_rcvbuf, not from the defaults; the patch changes nothing there. The real impact is only (1) routes with an RTAX_WINDOW metric and (2) a TCP_WINDOW_CLAMP that a later SO_RCVBUF on an unconnected socket or listener overwrites. v3's changelog will say exactly that and drop the "any application" / "without a metric" claims. pw-bot: cr Thanks for the careful review. Shashank ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH net-next 2/2] selftests/net/packetdrill: test SO_RCVBUF before connect keeps route window 2026-10-11 11:16 [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect Shashank Mohan Jain 2026-10-11 11:16 ` [PATCH net-next 1/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected Shashank Mohan Jain @ 2026-10-11 11:16 ` Shashank Mohan Jain 2026-10-11 11:19 ` [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect netdev-bot+sinfo 2 siblings, 0 replies; 9+ messages in thread From: Shashank Mohan Jain @ 2026-10-11 11:16 UTC (permalink / raw) To: Eric Dumazet, Neal Cardwell, Jakub Kicinski, Paolo Abeni, David S. Miller Cc: Kuniyuki Iwashima, Simon Horman, netdev, linux-kernel Add a packetdrill test for the SYN window and window scale when SO_RCVBUF is set before connect() and the route to the peer carries a "window" metric (RTAX_WINDOW). The test puts "window 4096" on the route to the peer, sets SO_RCVBUF, connects, and checks that the SYN advertises the route-clamped window and a window scale of 0. Without the first patch of this series the SYN carried win 65535, wscale 5, because setsockopt(SO_RCVBUF) had written tp->window_clamp while the socket was still in TCP_CLOSE and tcp_connect_init() then skipped the route metric. The test is picked up automatically by the packetdrill selftest Makefile (TEST_PROGS := $(wildcard *.pkt)). Assisted-by: LLM Signed-off-by: Shashank Mohan Jain <jain.sm@gmail.com> --- .../tcp_rcvbuf_before_connect_window.pkt | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tools/testing/selftests/net/packetdrill/tcp_rcvbuf_before_connect_window.pkt diff --git a/tools/testing/selftests/net/packetdrill/tcp_rcvbuf_before_connect_window.pkt b/tools/testing/selftests/net/packetdrill/tcp_rcvbuf_before_connect_window.pkt new file mode 100644 index 000000000..a3557ce80 --- /dev/null +++ b/tools/testing/selftests/net/packetdrill/tcp_rcvbuf_before_connect_window.pkt @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +// Setting SO_RCVBUF before connect() must not defeat the route "window" +// metric on the SYN. +// +// The route to the peer carries "window 4096" (RTAX_WINDOW). With SO_RCVBUF +// also set before connect(), the SYN the kernel sends must still advertise +// the small, route-clamped receive window and a window scale of 0 (the +// window scale option is sent, with a shift of 0). +// +// Since commit b025461303d8 ("tcp: update window_clamp when SO_RCVBUF is +// set"), setsockopt(SO_RCVBUF) wrote tp->window_clamp while the socket was +// still in TCP_CLOSE. tcp_connect_init() then treated that as a user clamp +// and skipped RTAX_WINDOW, so the SYN carried win 65535, wscale 5 instead. +--ip_version=ipv4 + +`./defaults.sh +ip route change 192.0.2.1 via 192.168.0.1 dev tun0 window 4096` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [1048576], 4) = 0 + +0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 + +0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) + +// The SYN must advertise the route-clamped window and window scale 0. + +0 > S 0:0(0) win 2920 <mss 1460,sackOK,TS val 0 ecr 0,nop,wscale 0> + +.1 < S. 0:0(0) ack 1 win 65535 <mss 1460,nop,wscale 7> + +0 > . 1:1(0) ack 1 -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect 2026-10-11 11:16 [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect Shashank Mohan Jain 2026-10-11 11:16 ` [PATCH net-next 1/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected Shashank Mohan Jain 2026-10-11 11:16 ` [PATCH net-next 2/2] selftests/net/packetdrill: test SO_RCVBUF before connect keeps route window Shashank Mohan Jain @ 2026-10-11 11:19 ` netdev-bot+sinfo 2026-10-11 11:23 ` shashank Jain 2026-10-12 4:57 ` Shashank Mohan Jain 2 siblings, 2 replies; 9+ messages in thread From: netdev-bot+sinfo @ 2026-10-11 11:19 UTC (permalink / raw) To: Shashank Mohan Jain Cc: Eric Dumazet, Neal Cardwell, Jakub Kicinski, Paolo Abeni, David S. Miller, Kuniyuki Iwashima, Simon Horman, netdev, linux-kernel Hi! This is an automated message. This series looks like a fix, but its commit messages seem to be missing some information: - How the issue was discovered, e.g. hit in production, hit during development, syzbot report, manual code inspection, LLM or static analysis tool scan. Please do not repost the series just to address the above. Instead, reply to this email with the missing information, so that reviewers can take it into account. If the series needs another revision for other reasons, please include the information in the commit messages then. The evaluation is done by an LLM so it may be wrong, if you think that is the case please reply and explain. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect 2026-10-11 11:19 ` [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect netdev-bot+sinfo @ 2026-10-11 11:23 ` shashank Jain 2026-10-12 4:57 ` Shashank Mohan Jain 1 sibling, 0 replies; 9+ messages in thread From: shashank Jain @ 2026-10-11 11:23 UTC (permalink / raw) To: netdev-bot+sinfo Cc: Eric Dumazet, Neal Cardwell, Jakub Kicinski, Paolo Abeni, David S. Miller, Kuniyuki Iwashima, Simon Horman, netdev, linux-kernel On Sun, Oct 11, 2026, netdev-bot+sinfo@kernel.org wrote: > This is an automated message. This series looks like a fix, but its > commit messages seem to be missing some information: > - How the issue was discovered ... Found by manual code inspection assisted by an LLM (Claude Code, Claude Opus) while reviewing the networking changes that set window_clamp on unconnected sockets, then confirmed before posting with the packetdrill test included as patch 2/2 and a veth/netns reproducer. The patches carry an "Assisted-by: LLM" tag for that reason. Thanks, Shashank On Sun, Oct 11, 2026 at 4:49 PM <netdev-bot+sinfo@kernel.org> wrote: > > Hi! > > This is an automated message. This series looks like a fix, but its > commit messages seem to be missing some information: > > - How the issue was discovered, e.g. hit in production, hit during > development, syzbot report, manual code inspection, LLM or static > analysis tool scan. > > Please do not repost the series just to address the above. Instead, > reply to this email with the missing information, so that reviewers > can take it into account. If the series needs another revision for > other reasons, please include the information in the commit messages > then. > > The evaluation is done by an LLM so it may be wrong, if you think > that is the case please reply and explain. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect 2026-10-11 11:19 ` [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect netdev-bot+sinfo 2026-10-11 11:23 ` shashank Jain @ 2026-10-12 4:57 ` Shashank Mohan Jain 1 sibling, 0 replies; 9+ messages in thread From: Shashank Mohan Jain @ 2026-10-12 4:57 UTC (permalink / raw) To: Eric Dumazet, Neal Cardwell, Jakub Kicinski, Paolo Abeni, David S. Miller Cc: Kuniyuki Iwashima, Simon Horman, netdev, linux-kernel On Sun, Oct 11, 2026, netdev-bot+sinfo@kernel.org wrote: > This is an automated message. This series looks like a fix, but its > commit messages seem to be missing some information: > - How the issue was discovered ... Found by manual code inspection assisted by an LLM (Claude Code, Claude Opus) while reviewing the networking changes that set window_clamp on unconnected sockets, then confirmed before posting with the packetdrill test included as patch 2/2 and a veth/netns reproducer. The patches carry an "Assisted-by: LLM" tag for that reason. Thanks, Shashank ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-10-12 13:25 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-10-11 11:16 [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect Shashank Mohan Jain 2026-10-11 11:16 ` [PATCH net-next 1/2] tcp: don't set window_clamp from SO_RCVBUF before the socket is connected Shashank Mohan Jain 2026-10-12 11:18 ` netdev-bot+sashiko 2026-10-12 11:22 ` shashank Jain 2026-10-12 13:25 ` [PATCH net-next v2 0/2] " Shashank Mohan Jain 2026-10-11 11:16 ` [PATCH net-next 2/2] selftests/net/packetdrill: test SO_RCVBUF before connect keeps route window Shashank Mohan Jain 2026-10-11 11:19 ` [PATCH net-next 0/2] tcp: keep the route window on the SYN when SO_RCVBUF is set before connect netdev-bot+sinfo 2026-10-11 11:23 ` shashank Jain 2026-10-12 4:57 ` Shashank Mohan Jain
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox