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

--- Hosta 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 tcpdump (=10.50.107.129) 顯示此傳入 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,我可以使用 MTU=1487 ping 主機。

很難過,如果有人有任何建議,我將不勝感激。

相關內容