MTU 和数据包丢失有何神奇之处?

MTU 和数据包丢失有何神奇之处?

默认 MTU 如下所示:

hosta$ ifconfig eth0 | grep mtu
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

我可以使用 1500 个有效载荷从另一台服务器进行 ping

hostb$ ping -s 1500 -c 2 hosta
PING hosta (hosta) 1500(1528) bytes of data.
1508 bytes from hosta: icmp_seq=1 ttl=64 time=0.273 ms
1508 bytes from hosta: icmp_seq=2 ttl=64 time=0.314 ms

--- 玉簪 ping 统计 ---

2 packets transmitted, 2 received, 0% packet loss, time 1025ms
rtt min/avg/max/mdev = 0.273/0.293/0.314/0.020 ms

hosta 上的 tcpdump 一切正常

12:01:40.237047 IP hostb > hosta: ICMP echo request, id 3052, seq 1, length 1480
12:01:40.237048 IP hostb  > hosta: icmp
12:01:40.237116 IP hosta > hostb: ICMP echo reply, id 3052, seq 1, length 1480

我可以将 hosta 上的 MTU 降低到 1488,并且 1500 有效载荷 ping 可以工作。

神奇数字是 MTU=1487

hosta $ ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1487
<snip>

当我发送 1500 字节 ping(不干扰碎片标志)时,没有响应

hosb $ ping -s 1500 -c 2 hosta
PING hosta (hosta) 1500(1528) bytes of data.

--- hosta ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1032ms

hosta 上的 tcpdump 如下所示:

12:01:07.421196 IP hostb > hosta: icmp
12:01:08.443698 IP hostb > hosta: icmp

玉簪秀

net.ipv4.ip_forward_use_pmtu = 0
net.ipv4.ip_no_pmtu_disc = 0
net.ipv4.route.min_pmtu = 552
net.ipv4.route.mtu_expires = 600
net.ipv4.tcp_mtu_probe_floor = 48
net.ipv4.tcp_mtu_probing = 0
net.ipv4.icmp_echo_ignore_all = 0
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.icmp_errors_use_inbound_ifaddr = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.icmp_msgs_burst = 50
net.ipv4.icmp_msgs_per_sec = 1000
net.ipv4.icmp_ratelimit = 1000
net.ipv4.icmp_ratemask = 6168

注意,如果输出看起来有点奇怪,我会用正确的主机名替换 IP 地址。

我很困惑为什么将 MTU 降低到低于某个阈值的任何数字都会导致 ping 得不到任何响应。尽管我没有弄乱碎片位。

如果我对 1500 字节数据包使用 do/want/dont 的 -M 选项,我会得到响应,直到 hosta MTU 保持在 1488 以上,但是一旦将其设置为 1487 或以下,do/want/dont 都不会得到响应。

对此进行进一步的跟踪。当 MTU=1487 时,该主机(=10.50.107.129)上的 tcpdump 显示传入的 1 个 IP 数据包

1   2023-02-15 22:40:24.095129  10.50.107.83    10.50.107.129   IPv4    562 Fragmented IP protocol (proto=ICMP 1, off=1480, ID=1fb9)

这是唯一一行。表示它是碎片化的,但显示长度为 562 字节,与下面 #3 中显示的长度相同。

接下来我改变 MTU=1500,我看到有效载荷被碎片化并被确认,如下所示。

2   2023-02-15 22:40:42.093639  10.50.107.83    10.50.107.129   IPv4    1514    Fragmented IP protocol (proto=ICMP 1, off=0, ID=2c62) [Reassembled in #3]
3   2023-02-15 22:40:42.093639  10.50.107.83    10.50.107.129   ICMP    562 Echo (ping) request  id=0x1004, seq=1/256, ttl=64 (reply in 5)
4   2023-02-15 22:40:42.093698  10.50.107.129   10.50.107.83    IPv4    1514    Fragmented IP protocol (proto=ICMP 1, off=0, ID=fe1a) [Reassembled in #5]
5   2023-02-15 22:40:42.093717  10.50.107.129   10.50.107.83    ICMP    562 Echo (ping) reply    id=0x1004, seq=1/256, ttl=64 (request in 3)

我检查了 #1 中的数据,并与 #4 中的数据进行了比较,它们不是 +/- 3 个字节(ping 将十六进制 00 到 ff 作为有效载荷)。因此,要么发送方没有发送第一个片段,要么接收方没有读取第一个片段,要么发生了其他事情。

两台服务器的构建方式与运行 Ubuntu 的虚拟机相同。因此,通过 消除了一侧。

如果我通过 vpn/防火墙/etc/etc 从我的笔记本电脑运行 ping 命令,我就可以 ping MTU=1487 的主机。

很困惑,如果有人能提供任何建议我将非常感激。

相关内容