跳到内容

第 4 卷 / 第 8 章 / 第 3 课

8.3 MTU、IP fragmentation 与 Path MTU Discovery ​

最大传输单元(MTU)表示链路或接口一次可承载的网络层数据包上限。路径 MTU(PMTU)取源端到目的端沿途各跳 MTU 的最小值;反向路径可能不同,需要分别判断。应用消息可以跨越多个数据包,因此不能把 MTU 当成消息长度限制,也不能据此规定每次 TCP send() 的写入大小。

1. 先分开 frame、IP packet、TCP segment 和 application write ​

text
application bytes
    ↓ stream/message framing
TCP segment or UDP datagram
    ↓ IP header
IP packet
    ↓ link header/trailer
Ethernet/Wi-Fi/tunnel frame

Ethernet 常见 IP MTU 为 1500,但 jumbo frame、PPPoE、VPN/overlay 和 cloud encapsulation 都可改变可用 MTU。不能用某类 Wi-Fi 帧“frame body 最大 2304”推断 host 的 IP MTU 就是 2304:802.11 MAC frame 开销、LLC/SNAP、aggregation 和 bridge conversion 与 IP interface MTU 是不同边界。

TCP 可将 byte stream 切成 segment,segmentation offload 还可使 packet capture 在 host 某一侧看到大于 wire MTU 的 logical packet。观察时要注明 capture point 和 NIC offload state。

2. IPv4 fragmentation 取决于 DF 与 packet size ​

IPv4 router 收到大于 outgoing-link MTU 的 packet 时:

  • DF(Don't Fragment)为 0:router 可 fragment;
  • DF 为 1:router 不能 fragment,丢 packet 并应返回 ICMP Destination Unreachable / Fragmentation Needed(Type 3, Code 4),包含 next-hop MTU information。

Fragment 在原 IP datagram 的目的端重组,不在普通转发路由器上逐跳重组;隧道外层目的端可能正好是一台路由器,要区分内外层 IP。丢一个 fragment 会让整个 original datagram 无法重组,而 middlebox、NAT 和 firewall 对 fragment 的处理也更复杂。因此现代传输协议通常尽量避免依赖途中 IPv4 分片。

例如一个总长 4000 bytes、无 IP options 的 IPv4 datagram,经 MTU 1500 的链路分片。原载荷为 3980 bytes;非末片载荷须是 8 bytes 的倍数,Fragment Offset 也以 8 bytes 为单位:

分片IP 载荷含 20-byte 首部的总长Offset / MF
1148015000 / 1
214801500185 / 1
310201040370 / 0

三个分片使用相同 Identification,MF=0 标明末片。Offset 185 指的是原载荷第 1480 字节,不能当成字节偏移直接拼接。

3. IPv6 router 不做 in-path fragmentation ​

IPv6 router 遇到 oversized packet 时丢弃并返回 ICMPv6 Packet Too Big(Type 2)。只有 source 可使用 Fragment extension header 发 fragments,router 不会像 IPv4 DF=0 那样现场切 packet。

IPv6 要求每条 link 支持 1280-byte minimum MTU。如果 link 无法 native 承载,link layer 必须在 IPv6 之下提供 fragmentation/reassembly。“IPv6 minimum MTU 1280”不等于所有 IPv6 path 的 PMTU 永远只能用 1280。

4. Classic PMTUD 依赖 ICMP feedback ​

IPv4 PMTUD 通常发 DF packet,根据 ICMP Fragmentation Needed 降低 PMTU estimate。IPv6 PMTUD 根据 ICMPv6 Packet Too Big 更新 estimate。Estimate 需要有 lifetime 并允许 path 变化后重新提高,否则一次旧 bottleneck 可让连接长期停在过小 packet size。

Equal-cost multipath、route change 和 tunnel 可让不同 flow/time 的 PMTU 不同。PMTU 不应被当作 host pair 的永久常量。

ICMP message 要做 validity check,rate limit 与 policy filtering,但粗暴丢弃所有 ICMP/ICMPv6 会破坏 PMTUD。

5. MTU black hole 是“小包通,大包沉默”的候选原因 ​

Typical failure chain:

  1. Source 发了 oversized non-fragmentable packet;
  2. Router/tunnel endpoint 丢 packet 并生成 ICMP Too Big/Fragmentation Needed;
  3. ICMP 被中间 policy 丢弃,或 sender 无法将它关联到 flow;
  4. Sender 不降低 packet size,重传继续失败。

Symptom 可是 TCP handshake 成功、small request 成功,一到 certificate chain、large response 或 upload 就 timeout。但相同 symptom 也可来自 application timeout、proxy body limit、packet loss 或 flow-control bug,不能只靠“大 file 不通”就定性为 MTU black hole。

Evidence 应包含:

  • Interface/tunnel MTU 和 route;
  • Packet capture 中的 packet size、DF/IPv6、retransmission;
  • ICMP too-big message 是否生成/到达;
  • 不同 probe size 的结果;
  • 调低 MTU/MSS 后问题是否可重现地消失。

6. PLPMTUD 不把 ICMP 当成唯一信号 ​

Packetization Layer PMTUD(PLPMTUD)由 transport/application packetization layer 发送不同大小的 probe,用 acknowledgement/loss behavior 推断 supported size,不必完全依赖 ICMP。

但 probe loss 可能只是 congestion,不一定是 MTU limit。Algorithm 需要 search state、confirmation、fallback base size 和 black-hole detection,不是“对 packet size 做一次 binary search”就完成。RFC 4821 给出了适用于 TCP 的 PLPMTUD guidance,Datagram transport/application 可按 RFC 8899 设计 Datagram PLPMTUD。QUIC 也有自己的 datagram size / path validation requirement。

7. TCP MSS 与 MSS clamping ​

TCP MSS option 出现在 SYN(包括 SYN-ACK)中,声明发送此选项的一端能接收的最大 TCP 数据长度,不包含 IP/TCP 首部。通告值通常从有效 MTU 只扣固定首部:IPv4 扣 20+20 bytes,IPv6 扣 40+20 bytes。根据 RFC 6691,不应预先在 MSS 中再扣可能出现的 options;实际发送者要为自己加入的 options/扩展首部减少数据长度。

例如 MTU 1500 的普通 IPv4 路径可通告 MSS 1460;若某个数据段的 TCP options 占 12 bytes,该包最多放 1448 bytes 的 TCP 数据。对端 MSS 和已发现的 PMTU 都会限制实际分段,MSS 也不是一次 send() 必须写满的长度。

MSS clamping 在路由器/firewall 经过 SYN 时降低 advertised MSS,可作为 tunnel/PMTUD black-hole 的 mitigation。它只影响 TCP,不修复 UDP/ICMP/other IP traffic,也不应代替正确 link MTU 和 ICMP policy。随手把 MSS clamp 到极小值会增加 packet/CPU overhead。

8. Tunnel overhead 要做显式 budget ​

Inner packet 进入 tunnel 后多出 outer IP、UDP/GRE/ESP 和 tunnel-specific header/tag。精确 overhead 取决于 IPv4/IPv6、encryption mode、option 和 implementation,不应用“VPN 都是 50–70 bytes”作为配置依据。

一个简单 budget calculator 可迫使 configuration 显式列出每层 overhead:

python
def inner_mtu(outer_mtu: int, overheads: list[tuple[str, int]]) -> int:
    if outer_mtu <= 0:
        raise ValueError("outer_mtu must be positive")
    total = 0
    for name, size in overheads:
        if size < 0:
            raise ValueError(f"negative overhead for {name}")
        total += size
    result = outer_mtu - total
    if result <= 0:
        raise ValueError("overhead leaves no room for an inner packet")
    if result < 1280:
        print("warning: result is below the IPv6 minimum link MTU")
    return result

# 数值必须来自你实际使用的 tunnel format,下面只是算法示例。
headers = [("outer IP", 20), ("UDP", 8), ("tunnel data header/tag", 32)]
assert inner_mtu(1500, headers) == 1440

这里的 outer_mtu 从外层 IP 开始计数,不再扣已经排除的外层 Ethernet 首部。载荷类型也要写清:承载完整 Ethernet frame 的隧道还需给内层 Ethernet 首部留空间。变长 padding、嵌套隧道与运营商限制要按实际格式补入,必要时取最大开销。NIC offload 可能改变本机抓包形态,但不会凭空省掉线上封装字节。

低于 1280 的结果只是预算告警,不能直接当作可用的 IPv6 link MTU 配置;需要支持 IPv6 以下的适配机制,或调整封装/外层路径。最终预算仍须端到端验证。

9. Linux 诊断工具 ​

bash
ip link show
ip route get 203.0.113.10
tracepath 203.0.113.10

# IPv4:不允许 fragment,ICMP payload 1472 + IPv4 20 + ICMP 8 = 1500
ping -4 -M do -c 3 -W 2 -s 1472 203.0.113.10

先把 203.0.113.10 替换为你控制的实际端点。此处 ping -M do 会受本机已知 PMTU 限制,可能在本地就返回 “message too long”,并不代表探针已经到达远端。Command option 和 privilege 因 OS 而异,ping 成功也不证明 TCP/UDP 使用同一 path/policy。IPv4 header 有 options 时 1472 计算也要改变。实验只对自己有权测试的 endpoint 进行,并与 packet capture/counter 结合。

10. 验收问题 ​

  1. IPv4 DF=0 和 DF=1 遇到小 outgoing MTU 时有何不同?
  2. IPv6 router 为什么不做 in-path fragmentation?
  3. 区分 classic PMTUD 与 PLPMTUD 的 feedback source。
  4. 为什么 MSS clamping 不能修复 UDP MTU black hole?
  5. 给出能支持 MTU-black-hole 结论的至少三项证据。

参考 ​

Built with VitePress | Software Systems Atlas