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 は 16 進数の 00 から ff をペイロードとして挿入します)。つまり、送信側が最初のフラグメントを送信しなかったか、受信側が最初のフラグメントを読み取らなかったか、あるいは他の何かが起こっているかのいずれかです。

両方のサーバーは、Ubuntu を実行する VM と同じように構築されています。そのため、片側は によって削除されました。

ラップトップから VPN/ファイアウォールなどを介して ping を実行すると、MTU=1487 でホストに ping できます。

困惑しており、誰かが何か提案をしてくれるとありがたいです。

関連情報