Skip to content

Next-hop MTU in ICMP "Fragmentation Needed" packets is set to 0 #12568

@imax9000

Description

@imax9000

Description

Whenever gvisor responds with "Fragmentation Needed" messages, it leaves Next-hop MTU fields set to zero (copied from wireshark):

Frame 58: 596 bytes on wire (4768 bits), 596 bytes captured (4768 bits) on interface -, id 0
Linux cooked capture v2
Internet Protocol Version 4, Src: 172.17.0.3, Dst: 192.168.*.*
Internet Control Message Protocol
    Type: 3 (Destination unreachable)
    Code: 4 (Fragmentation needed)
    Checksum: 0x4d00 [correct]
    [Checksum Status: Good]
    Unused: 0000
    MTU of next hop: 0
    Internet Protocol Version 4, Src: 192.168.*.*, Dst: 172.17.0.3

This somewhat confuses the host and causes it to cache the minimal possible MTU of 552 for the container's IP address:

% ip route show cache
172.17.0.3 dev docker0 
    cache expires 537sec mtu lock 552 

While this cache entry exists, the host keeps replying to packets that would be sent to the container with "fragmentation needed" messages with Next-hop MTU of 552. This then can cause connectivity issues with remote hosts (in my case - github.com), if ICMP replies are filtered somewhere along the way, I suspect. github.com keep re-sending TCP packets of a totally reasonable size of 1476 bytes, which is a lot more than 552.

Steps to reproduce

Presumably, sending a large packet with "Don't fragment" bit should allow to see the returned Next-hop MTU.

I am still figuring out why such packets get generated in my setup, and why gvisor seems to accept most of them just fine, taking issue only with some.

runsc version

runsc version release-20260105.0
spec: 1.1.0-rc.1

docker version (if using docker)

Client: Docker Engine - Community
 Version:           27.4.0
 API version:       1.47
 Go version:        go1.22.10
 Git commit:        bde2b89
 Built:             Sat Dec  7 10:38:57 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          27.4.0
  API version:      1.47 (minimum version 1.24)
  Go version:       go1.22.10
  Git commit:       92a8393
  Built:            Sat Dec  7 10:38:57 2024
  OS/Arch:          linux/amd64
  Experimental:     true
 containerd:
  Version:          v2.2.1
  GitCommit:        dea7da592f5d1d2b7755e3a161be07f43fad8f75
 runc:
  Version:          1.3.4
  GitCommit:        v1.3.4-0-gd6d73eb8
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

uname

No response

kubectl (if using Kubernetes)

repo state (if built from source)

No response

runsc debug logs (if available)

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions