PMTU 机制原理
PMTU(Path Maximum Transmission Unit,路径最大传输单元)发现机制 是一种用于动态探测从源主机到目的主机之间整条网络路径上最小 MTU 值的技术,目的是避免 IP 数据包在传输过程中被分片。
✅ 核心目标
确保发送的数据包大小不超过路径中任何一跳链路的 MTU,从而避免分片,提升网络效率和可靠性。
🔧 工作原理(以 IPv4 和 IPv6 为例)
-
设置“不分片”标志(DF=1)
- 发送方在发送 IP 报文时,在 IP 头部设置 DF(Don't Fragment)标志位为 1,表示该报文不允许在网络中被分片。
-
初始假设 PMTU = 出接口 MTU
- 源主机通常先假设路径 MTU 等于其本地接口的 MTU(如 1500 字节),并据此发送数据包。
-
遇到较小 MTU 链路时丢包并返回 ICMP 错误
- 当报文经过某个中间路由器时,如果该链路的 MTU 小于报文长度:
- 路由器会丢弃该报文。
- 向源主机发送一个 ICMP 差错报文:
- IPv4:
ICMP Type 3, Code 4
—— “Fragmentation needed but DF set”(需要分片但 DF 标志已设置) - IPv6:
ICMPv6 Type 2, Code 0
—— “Packet Too Big”,且必须携带该链路的 MTU 值
- IPv4:
- 当报文经过某个中间路由器时,如果该链路的 MTU 小于报文长度:
-
源主机收到 ICMP 后更新 PMTU 缓存
- 源主机解析 ICMP 报文中的 MTU 值,并将其作为当前路径的 PMTU。
- 后续发往同一目的地的数据包将按此更小的 MTU 进行分片或调整(如 TCP 调整 MSS)。
-
缓存与老化
- 操作系统会将探测到的 PMTU 值缓存在路由表中,用于后续通信。
- 一段时间后或路径变化时,PMTU 可能重新探测。
📌 示例流程:
text编辑源 → [MTU=1500] → [MTU=1400] → [MTU=1300] → 目的1. 源发 1500B 报文(DF=1)→ 在 MTU=1400 链路被丢弃 2. 路由器回 ICMP:MTU=1400 3. 源改发 1400B 报文 → 在 MTU=1300 链路被丢弃 4. 路由器回 ICMP:MTU=1300 5. 源最终使用 PMTU=1300 发送 → 成功到达
🌐 PMTU 在 TCP 中的应用
- TCP 在建立连接时会协商 MSS(Maximum Segment Size)。
- 操作系统根据 PMTU 自动计算 MSS:
MSS = PMTU - IP头(20B) - TCP头(20B) = PMTU - 40
- 例如:PMTU=1400 → MSS=1360,确保整个 IP 报文 ≤ 1400B,避免分片。
PMTU 机制可能存在的风险与问题
尽管 PMTU 是优化网络的重要机制,但在实际部署中存在以下主要风险:
⚠️ 1. PMTUD 黑洞(PMTU Black Hole)
这是最常见的问题。
- 现象:大报文被丢弃,但源主机收不到 ICMP “Too Big” 报文。
- 原因:
- 防火墙、安全组或路由器过滤了 ICMP 报文(尤其是 Type 3 Code 4 或 ICMPv6 Type 2)。
- 管理员出于“安全”考虑禁用了 ICMP 响应。
- 后果:
- 源主机无法得知需要减小报文大小。
- 连接建立成功(小包能通),但传输大数据时卡死或超时。
- 表现为:网页打不开、SSH 卡顿、大文件传输失败等。
⚠️ 2. 路径动态变化导致 PMTU 过时
- 网络拓扑变化后,新的路径可能有更小或更大的 MTU。
- 操作系统缓存的 PMTU 未及时更新,导致次优或失败通信。
- 虽然 PMTU 有老化机制,但周期较长(如 Linux 默认 10 分钟),无法即时适应。
⚠️ 3. IPv6 环境下 PMTUD 不可绕过
- 在 IPv6 中,中间设备不允许对报文进行分片,必须依赖 PMTUD。
- 所有 IPv6 主机必须支持 PMTUD。
- 一旦 ICMPv6 “Packet Too Big” 被阻断,通信将完全失败,没有退路。
⚠️ 4. 应用层未处理 ICMP 错误
- 某些应用程序或操作系统内核未能正确处理 ICMP 差错报文。
- 导致无法调整发送窗口或 MSS,继续发送超大报文,造成持续丢包。
⚠️ 5. 多路径与非对称路由问题
- 往返路径 MTU 不一致(非对称路由),可能导致 PMTU 探测不准确。
- 某些路径上的最小 MTU 未被探测到。
✅ 如何缓解 PMTUD 风险?
风险 | 解决方案 |
---|---|
PMTUD 黑洞 | - 允许 ICMP Type 3 Code 4 / ICMPv6 Type 2 通过防火墙 - 在隧道接口手动设置 MTU 和 MSS(如 mtu 1400 , mss 1360 ) |
动态路径变化 | 定期探测或使用更激进的老化策略 |
IPv6 安全过滤 | 避免过度过滤 ICMPv6,特别是 Type 2 |
应用兼容性 | 使用支持 PMTUD 的 TCP 协议栈,或在网关启用 MSS 调整 |
✅ 最佳实践建议
- 在 IPSec、GRE、VXLAN 等隧道接口上手动设置 MTU 为 1400 或 1300
- 配置
tcp adjust-mss 1360
(适用于 TCP 流量) - 确保安全设备允许关键 ICMP 报文通过
- 避免在公网路径上完全禁用 ICMP
- 使用
ping
命令手动探测 PMTU(如ping -f -l 1472 目的IP
)
总结
项目 | 内容 |
---|---|
PMTU 原理 | 利用 DF 标志 + ICMP 错误报文动态发现路径最小 MTU |
优点 | 避免分片、提高效率、自动适应网络 |
主要风险 | PMTUD 黑洞(ICMP 被过滤)、路径变化、IPv6 依赖性强 |
推荐做法 | 结合 PMTUD + 手动 MTU/MSS 调整,避免单点依赖 |
💡 一句话总结:
PMTUD 是理想的机制,但在现实网络中常因安全策略失效。最稳妥的做法是:在隧道或关键链路上手动设置 MTU 和 TCP MSS,作为 PMTUD 的补充或替代。