Skip to content

tcpip: fix IP_MTU_DISCOVER for locally-originated packets - #14143

Open
Ar1es-XD wants to merge 1 commit into
google:masterfrom
Ar1es-XD:fix-ip-mtu-discover
Open

tcpip: fix IP_MTU_DISCOVER for locally-originated packets#14143
Ar1es-XD wants to merge 1 commit into
google:masterfrom
Ar1es-XD:fix-ip-mtu-discover

Conversation

@Ar1es-XD

@Ar1es-XD Ar1es-XD commented Aug 16, 2026

Copy link
Copy Markdown

Fixes #12319

Problem

tracepath fails with tracepath: IP_MTU_DISCOVER: Operation not supported because setsockopt(IP_MTU_DISCOVER, IP_PMTUDISC_DO) and IP_PMTUDISC_PROBE previously returned ENOTSUP.
A previous attempt to support this in PR #12366 was rolled back because of a regression where large UDP datagrams failed with EMSGSIZE (#12479).

Solution

  1. pkg/tcpip/network/ipv4/ipv4.go:
    Remove the IsForwardedPacket guard from the DontFragment check. When the Don't Fragment (DF) bit is set and the packet exceeds the MTU, return ErrMessageTooLong (EMSGSIZE), matching Linux kernel semantics.

    • Sockets using default UDP strategy (IP_PMTUDISC_DONT, 0) have DF=false, so large datagrams continue to be fragmented locally without error, preventing regressions for workloads such as Java DatagramChannel (Java runtime tests fail on buildkite #12479).
  2. pkg/tcpip/transport/udp/endpoint.go:
    When UDP WritePacket fails with ErrMessageTooLong, queue a local error on the socket's error queue if IP_RECVERR / IPV6_RECVERR is enabled. This mirrors Linux net/ipv4/udp.c:udp_send_skb() behaviour, allowing tracepath to receive the error via MSG_ERRQUEUE.

  3. test/packetimpact/tests/ipv4_id_uniqueness_test.go:
    Clean up stale TODO comment as IP_PMTUDISC_DONT is supported.

Verification

All unit tests, integration tests, and static checks passed:

  • //pkg/tcpip/network/ipv4:ipv4_test (passes all fragmentation & forwarding test cases)
  • //pkg/tcpip/network/ipv4:ipv4_unit_test
  • //pkg/tcpip/transport/udp:udp_x_test
  • //pkg/tcpip/transport/internal/network:network_test
  • //pkg/tcpip/transport/tcp:tcp_test
  • //pkg/tcpip/tests/integration:...
  • nogo static analysis for all modified packages

Assisted-by: Gemini CLI

Fixes google#12319

When IP_MTU_DISCOVER is set to IP_PMTUDISC_DO or IP_PMTUDISC_PROBE,
locally-originated packets exceeding the MTU should return ErrMessageTooLong
(EMSGSIZE), matching Linux kernel semantics.

Changes:
1. pkg/tcpip/network/ipv4/ipv4.go:
   Remove the IsForwardedPacket guard from the DF+fragmentation check. When
   the Don't Fragment bit is set, packets exceeding network MTU return
   ErrMessageTooLong.
   Default UDP sockets maintain PMTUDiscoveryDont (DF=false), preventing
   regressions for large unfragmented UDP datagrams (google#12479).

2. pkg/tcpip/transport/udp/endpoint.go:
   When UDP WritePacket fails with ErrMessageTooLong, queue a local error on
   the socket error queue when IP_RECVERR is enabled, matching Linux
   net/ipv4/udp.c:udp_send_skb().

3. test/packetimpact/tests/ipv4_id_uniqueness_test.go:
   Update comment now that IP_PMTUDISC_DONT is supported.

Assisted-by: Gemini CLI
@Ar1es-XD
Ar1es-XD force-pushed the fix-ip-mtu-discover branch from bc2a83d to 5374207 Compare August 16, 2026 18:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support IP_MTU_DISCOVER

2 participants