Re: [PATCH net 2/2] Revert "net: advertise TCP MSS from the configured MTU, not the learned PMTU"

From: Jiayuan Chen

Date: Tue Oct 27 2026 - 08:54:13 EST



On 10/26/26 3:23 PM, Esko Mobius via B4 Relay wrote:
From: Esko Mobius <echoowall@xxxxxxxxx>

This reverts commit 2640e6419594 ("net: advertise TCP MSS from the
configured MTU, not the learned PMTU").

That commit stopped the learned PMTU from lowering the MSS we advertise
in SYN and SYN-ACK. For symmetric paths it argued that "the peer runs
its own PMTU discovery and usually already knows the real path MTU".
That only holds if ICMP "fragmentation needed" can reach the peer. When
the peer sits behind a firewall that drops inbound ICMP, its PMTU
discovery is a black hole (RFC 2923, section 2.1), and the smaller MSS
we advertised was the only thing keeping its full-size segments off the
narrow hop.


A client that cannot receive ICMP is broken beyond this: QUIC's DPLPMTUD
hits the same black hole, and nothing the server advertises can help it.



Inbound ICMP filtering is very common in enterprise and carrier
networks, and it is pervasive in mainland China. We hit this in
production after the commit was backported to 6.12.111: TCP connections
that reach a server through a relay with a smaller-MTU hop complete the
handshake, then stall as soon as the client sends full-size segments.



The learned PMTU is keyed per destination address. If your relay
masquerades the clients, the server sees a single address, and one
client's download seeds the entry for everyone behind it. That is why
this looked reliable. Once the clients are spread over their own
addresses, each one needs its own fresh entry and it falls apart. The
old behaviour was never a mechanism for this.


Clients on networks that let ICMP through, and connections that bypass
the relay, are unaffected, which made it hard to trace back to the
kernel.

Reproducer, network namespaces on a single host:

cli --(1500)-- r1 --(1456)-- r2 --(1500)-- srv

r1 drops ICMP frag-needed towards cli. srv has already learned PMTU
1456 towards cli, then cli uploads 1 MB to srv:


This precondition does all the work. The server only learns the PMTU
when it sends a full-size segment itself. If it only sends ACKs or small
replies it never learns it, the SYN-ACK MSS is 1460 on 6.12.107 as well,
and the upload stalls the same way. The entry also expires after 10
minutes (ip_rt_mtu_expires), so the server must have received a
frag-needed within the last 10 minutes before each new connection.

Please re-run the 6.12.107 case without seeding the PMTU.



kernel SYN-ACK MSS 1 MB upload
6.12.107 1416 OK
6.12.111 1460 stalls, times out
7.3-rc7 1460 stalls, times out
7.3-rc7 + this revert 1416 OK

The asymmetric case the commit was written for does not need a new
default: the advertised MSS can already be set per route with the
advmss metric, which takes precedence over default_advmss(). With this
revert applied, on an asymmetric path where srv learned PMTU 1456
towards cli while cli->srv is 1500 end to end:

srv route to cli SYN-ACK MSS largest cli->srv segment
default 1416 1404
advmss 1460 1460 1448

So DSR-style setups can opt in with "ip route ... advmss <mss>", while
hosts whose peers cannot complete PMTU discovery keep working by
default.

Fixes: 2640e6419594 ("net: advertise TCP MSS from the configured MTU, not the learned PMTU")
Reported-by: Esko Mobius <echoowall@xxxxxxxxx>
Closes: https://lore.kernel.org/regressions/4F0FAEB6-A13B-47F3-BFF1-C706686C6F64@xxxxxxxxx/
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Esko Mobius <echoowall@xxxxxxxxx>




Maybe a better way out than a plain revert:

Revert in stable, and in net-next add a sysctl, something like net.ipv4.tcp_advmss_use_pmtu,
that decides whether an endpoint uses the PMTU it learned on its send
side for the MSS it advertises (even though these are two opposite
directions). Default on keeps your setup working, DSR-style setups turn
it off