linux ping mtu 和碎片

网络工程 linux
2021-07-25 23:01:08

我一直在 Linux 上试验 ping 实用程序。我在路由器上设置了 500 字节的 mtu。现在,当我 ping 到外部主机时,我得到以下输出:

ping -c 3 -s 1300 10.0.2.1        
PING 10.0.2.1 (10.0.2.1) 1300(1328) bytes of data. 
From 10.0.1.254 icmp_seq=1 Frag needed and DF set (mtu = 500)
1308 bytes from 10.0.2.1: icmp_seq=2 ttl=62 time=1.12 ms 
1308 bytes from 10.0.2.1: icmp_seq=3 ttl=62 time=1.14 ms

--- 10.0.2.1 ping statistics --- 3 packets transmitted, 2 received, +1 errors, 33% packet loss, time 2000ms rtt min/avg/max/mdev = 1.123/1.134/1.146/0.035 ms

因此,第一条消息被路由器丢弃,因为超出了接口的 mtu。这是意料之中的,因为 DF 标志是默认设置的。因此,他无法碎片并且出现错误,到目前为止一切顺利。但是另外两个数据包发生了什么?他们为什么能通过?我可以想象 ping 工具在收到 ICMP 错误后不会在进一步的数据包中设置 DF 标志,因此它们可以被分段。是对的吗?我在哪里可以找到对此的“官方”解释?

非常感谢你!

解决方案:它是 PMTUD 协议的一部分。 http://www.cisco.com/c/en/us/support/docs/ip/generic-routing-encapsulation-gre/25885-pmtud-ipfrag.html#t4

1个回答

当路由器应该分段但它接收到设置了 DF 标志的 IP 数据报时,它会向源发送 ICMP(类型应该分段但设置了 DF)。然后源调整 MTU 并再次发送数据报。这就是 PMTUD 的工作原理。

这里发生的情况是,在您从路由器收到 ICMP 后,将路径的 MTU 调整为 500,因此您发送的以下 Ping 请求设置了 DF 标志,但它们在源头上是碎片化的(意味着您的机器正在发送 Ping请求分成几个数据报)。