Files
fips/src
Johnathan Corgan ffe4ff6c71 Bound a remote-supplied path MTU, and give the cache a way back
The path_mtu field is an unsigned per-hop transit annotation carried
outside the signed proof, and the MtuExceeded and PathBroken signals
arrive unencrypted with no sender check, so any forwarder could lower it
and it was accepted with no minimum. A single MtuExceeded carrying a very
small value drove a session's path MTU to zero, after which every packet
to that destination was answered with an ICMPv6 Packet Too Big instead of
being sent: a blackhole lasting until the daemon restarted. The same
value reached the SYN-time TCP MSS clamp, where anything at or below 137
saturates to a segment size of zero and the band just above it yields
single digits.

Ignore values below an actionable minimum rather than applying or storing
them, at the three places a remote value is acted on: the path MTU state
machine, the reactive MtuExceeded write, and the discovery response,
whose coordinates are still cached so refusing the annotation cannot
become a way to deny discovery. The MSS clamp additionally refuses to
write a zero. Ignoring rather than clamping is deliberate: a clamp would
fabricate an estimate the node has no basis for.

Release a stored per-destination path MTU when the path is invalidated by
a PathBroken report, by session idle expiry, or by handshake timeout, and
reseed the link MTU read from local configuration in its place, so a
directly connected peer does not lose its own measurement along with the
remote claim. Locally derived MTUs are not subject to the minimum, and
adaptation to hops well below the IPv6 minimum continues to work.

Count and name the path MTU values ignored as below the floor

Three sites ignore a remote-supplied path MTU below the actionable floor
and one releases a stale entry, and an operator had no way to see any of
it happening. Count each site and log the value seen with the destination,
so a node being fed poison is distinguishable from a node on a quiet link.

Clamp on the degenerate case, not on the remote floor

The floor guard at the MSS clamp site tested the stored value alone, with
no test of where it came from, so it also rejected the link MTU the node
seeds from its own transport. That contradicts the contract the constant's
own doc states, and it bites hardest on BLE, where the seeded value is
negotiated with the peer rather than read from config: a peer whose
effective MTU negotiated to 240 lost a correct 103-byte clamp and got the
1143-byte conservative ceiling, after which every full-size segment was
refused by the transport with no signal and no feedback to the application.

Every remote value is already refused at the three ingress guards, so a
sub-floor value reaching the clamp is by construction a local one. The
clamp therefore needs only to refuse the degenerate case it was really
about, where no payload byte survives the arithmetic at all.

Also retarget the seed-site warning, which fired on the same wrong
threshold and advised checking a transport setting that a negotiated link
does not have, and correct the constant's doc, which contradicted its own
formula about where the single-digit band ends.
2026-08-13 21:13:22 +00:00
..