[Bug 296656] IPv6 ND SIOCSIFINFO_IN6 cannot raise stale nd_linkmtu above already-clamped in6_ifmtu()
[email protected] Fri, 10 Jul 2026 01:29:35 +0000
| Newsgroups | gmane.os.freebsd.bugs |
|---|---|
| Message-ID | <[email protected]/bugzilla/> |
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=296656
Bug ID: 296656
Summary: IPv6 ND SIOCSIFINFO_IN6 cannot raise stale nd_linkmtu
above already-clamped in6_ifmtu()
Product: Base System
Version: 16.0-CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Many People
Priority: ---
Component: kern
Assignee: [email protected]
Reporter: [email protected]
Created attachment 272677
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=272677&action=edit
nd6_linkmtu_ioctl.patch
I found an IPv6 ND link-MTU recovery problem on FreeBSD 16.0-CURRENT.
System:
FreeBSD 16.0-CURRENT
Interface: rge0
Driver: if_rge
Interface MTU: 4074
The machine is directly connected to another FreeBSD machine over Ethernet.
The physical link and driver can pass larger frames; for example,
large IPv6 pings succeed.
Problem state:
ifconfig rge0
shows:
rge0 ... mtu 4074
but:
ndp -i rge0
shows:
linkmtu=1500, maxmtu=4074
This affects TCP. A packet capture of an IPv6 TCP handshake showed the peer
sending mss 4014, but this machine replied with:
options [mss 1440,...]
even though the interface MTU was 4074 and large IPv6 ping packets worked.
I tried disabling RA, removing the autoconf global IPv6 address, flushing NDP
entries, flushing prefixes/default routers, disabling/re-enabling
IPv6 on the interface, and changing MTU 1500 -> 4074 -> 9000 -> 4074. The
effective ND link MTU stayed stuck at 1500.
The kernel source appears to contain a self-clamping validation problem in
sys/netinet6/nd6.c:
if (ND.linkmtu < IPV6_MMTU ||
ND.linkmtu > in6_ifmtu(ifp)) {
error = EINVAL;
break;
}
in6_ifmtu(ifp) already returns the lower stale nd_linkmtu when it is below
if_mtu, so once nd_linkmtu is 1500, userland cannot raise it to a
valid value such as 4074 via SIOCSIFINFO_IN6.
I tested the attached patch, which validates against the interface’s allowed
maximum MTU instead of the already-clamped effective MTU, and calls
rt_updatemtu(ifp) when nd_linkmtu changes.
Runtime test after patch:
/tmp/set_nd_linkmtu rge0 1500
rge0 linkmtu=1500 maxmtu=4074
/tmp/set_nd_linkmtu rge0 4074
rge0 linkmtu=4074 maxmtu=4074
After raising linkmtu to 4074, tcpdump showed the IPv6 TCP SYN-ACK correctly
advertising:
options [mss 4014,...]
instead of mss 1440.
IPv6 iperf also improved from about 2.0 Gbit/s to about 2.28 Gbit/s on this
direct 2.5G link.
I am attaching the patch I tested.
--
You are receiving this mail because:
You are the assignee for the bug.