摘要

  • RFC 1191 让 IPv4 source 设置 Don't Fragment;遇到更小出口的 router 通过 ICMP 返回 next-hop MTU,endpoint 再降低估值。证据来自路径,处置权留在端点。
  • RFC 2923 记录了反馈消失后的 PMTUD black hole:TCP 可以完成 handshake,也能传小 packet,却在较大 segment 出现后停住。MSS 并不能完整替代路径信息。
  • Cloudflare 2015 年的复盘显示,ICMP 不一定被挡在网络之外。TCP 与 ICMP 的 ECMP hash 不同,合法告警可能落到不持有连接状态的 backend。
  • PLPMTUD 与 DPLPMTUD 允许 endpoint 以 probe 和送达确认自行寻找可用大小,不再依赖 ICMP 必须到达;代价是新增流量、状态,以及区分 MTU 与其他 packet loss 的责任。

一条告警在同一座数据中心里失去了对象

Cloudflare 在 2015 年 2 月发表的复盘中说明,其内部 BGP 负载均衡扩大使用 ECMP。TCP packet 以 source IP、source port、destination IP、destination port 组成的 tuple 做 hash,因此同一连接通常会回到同一 backend。

ICMP 走的是另一套条件。Cloudflare 记录,ECMP 对这些 packet 只使用 source 与 destination IP。Packet Too Big 于是可能被送到与 TCP flow 不同的服务器。该公司明确写道,这正是其事件中发生的情况。

报告只提到两名通过 IPv6 tunnel 访问的用户反映问题,不能据此推算全网发生率。它能证明的是一个具体的权力断裂:告警并未完全丢失,组织也拥有修复连接的技术能力,但证据与状态没有在同一台机器相遇。

临时方案是把全部 IPv6 路径 MTU 降到 1280,并在 IPv4 启用 RFC 4821 的 probing。长期方案则用 pmtud daemon 捕获 IPv4 fragmentation-needed 和 IPv6 Packet Too Big,再通过 Ethernet broadcast 让所有 backend 都能收到。

公开 repository 同时给单一 source 设了每秒一包、单一 interface 每秒十包的默认上限。这不是通用安全结论,却说明“让证据共享”本身也产生了验证、容量与滥用边界。Cloudflare 解决了自己架构中的归属冲突,没有替其他网络定义唯一答案。

1990 年之前的取舍:少发,或让路径拆分

RFC 1191 把 Path MTU 定义为 source 到 destination 各 hop MTU 的最小值。它不是 address、prefix 或 endpoint 的永久属性。route 改变后,最小的 link 也可能改变;tunnel 加入 header 后,原 packet 可使用的空间还会再次缩小。

早期做法常取 576 与 first-hop MTU 中较小者。保守大小避免端点预设未知路径能够承载大 datagram,却也会在更宽的路径上浪费容量;如果后续 hop 更小,router 仍可能进行 IPv4 fragmentation。

fragmentation 把工作留给网络。一个 datagram 被分为多片,到 destination 才能 reassemble;其中一片丢失即可让原 datagram 失败。后来 RFC 8900 还记录了 stateful firewall、不等路径、filter、tunnel 与 fragment 处理之间的脆弱组合。

因此 1990 年的选择并不是“先进 PMTUD”对“落后 fragmentation”。可行路径至少包括固定小 packet、允许 router fragment、由路径返回明确限制,或在失败后混合降级。RFC 1191 选择反馈机制,是为了既接近真实路径容量,又不把 routine fragmentation 变成默认代价。

RFC 1191 把观察权交给 router,把决定权留给 endpoint

经典 IPv4 PMTUD 的逻辑很短。source 设置 Don't Fragment。某个 router 发现 packet 无法在 next hop 原样转发,就丢弃它并返回 ICMP Destination Unreachable 中的 fragmentation needed code。

RFC 1191 要求消息携带 next-hop MTU。endpoint 收到后必须降低自己的 path estimate,可以减小 packet,也可以停止设置 DF。router 有权报告其本地接口限制,却无权替 transport 选择长期发送策略。

这种分工看似克制,却把可用性压在一条控制通道上。router 直接观察限制,endpoint 持有 packetization state;任何一方都无法单独完成恢复。ICMP 不是附加说明,而是连接证据与处置权的制度桥梁。

标准对“变大”尤其谨慎。endpoint 不得因为 ICMP 声称一个更大数值就提高估值,只能随后主动试探。RFC 1191 建议降低后至少等待五分钟、最好十分钟,再尝试更大 packet。这些数字是历史实现建议,并非当前全球 stack 的测量。

约束背后的理由仍然有效:route 会变化,control message 可能过时,也可能被伪造。一次观察只能在有限时间与上下文中成立。

IPv6 取消了中间 router 的 fragmentation,却没有取消发现

当前 IPv6 base specification 要求每条 link 能承载 1280-octet packet;无法直接做到的 link 必须在 IP 以下提供自己的 fragmentation 与 reassembly。IPv6 router 不会拆分转发中的 packet,只有 source 能加入 Fragment header。

RFC 8200 强烈建议实现 PMTUD,才能利用大于 1280 的路径。minimal implementation 也可以永远不发送超过 1280 的 packet。这是以效率换确定性的合法退出,并不表示所有路径 MTU 都等于 1280。

按照 RFC 8201,router 无法转发时发送 ICMPv6 Packet Too Big。endpoint 必须验证消息引用的 packet 确实来自自己。合法 PTB 可以降低估值,但不得把它降到 IPv6 的 1280 下限以下。

PTB 也不能直接提高估值。降低后要重新向上 probe,频率不得短于五分钟,建议十分钟。router 声明一个局部事实,endpoint 检查来源并决定缓存多久;两种 authority 没有合并。

RFC 4890 把 Packet Too Big 列入 firewall “must not be dropped”的 ICMPv6 类别,因为阻挡会阻止或严重损害通信。这是明确的操作建议,不是所有 firewall 已经遵守的证据,更不是要求无差别放行全部 ICMP。

当解释被过滤,silence 就被误当成路径

RFC 2923 在 2000 年记录 PMTUD black hole:router、kernel fault、configuration 或 firewall 没有把 ICMP error 送回 source,endpoint 便持续重发路径无法承载的 packet。

TCP 可能先成功。SYN 与早期数据较小,握手完成;较大 segment 出现后,路径把它丢弃,retransmission 再次采用同样大小,连接于是看似冻结。RFC 2923 以 FTP 为例:小 control connection 工作,bulk transfer 失败。

这种现象只是调查 trigger。congestion、corruption、asymmetric policy 或按内容 filter 也可能造成相似 loss。可靠判断需要 packet size、address family、DF/Fragment、重传模式与 ICMP 引用内容,不能由一次下载失败直接推出 MTU。

MSS 同样不是完整答案。它表达 receiver 愿意接受的最大 TCP payload,是接收方向的 transport bound;它不知道 forward path 上每个 tunnel 与 link,也无法保证 reverse path 相同。

RFC 2923 首选修复 ICMP black hole。endpoint 也可在多次 timeout 后降低 packet,恢复当前 session。代价是额外数秒,并把仍会伤害其他 traffic 的 path defect 隐藏在本地降级之后。

filter 可以合法,却不能把沉默写成事实

firewall operator 可以对自己管理的网络拥有合法政策权。现有资料不能证明某次 filter 是恶意、违法或出于特定私人动机。真正可核验的问题是,这项权力能够证明什么。

丢弃 PTB 并不会让较大的 packet 突然可转发。它只让 endpoint 无法看见限制。local discretion 因此可以否决 adaptation,却没有获得 constricting router 的知识,也没有承担 transport 的全部恢复义务。

tunnel 会在 endpoint packetization 之后加入 header,ECMP 与 anycast 又可能让 data 与 error packet 取得不同 instance identity。同一个 MTU 数值如果缺少时间、方向、flow 与 encapsulation context,就不是关于一段 address space 的稳定证据。

这对 number-resource holder 尤其重要。RIR 分配 address resource,不认证某个 holder 在每条 route 上的 end-to-end MTU。服务可在 prefix 与 IP 完全不变时,因为 tunnel、firewall 或 load-balancing 修改而发生 partial reachability。

PLPMTUD 让 endpoint 自己做实验

RFC 4821 在 2007 年改变证据来源。Packetization Layer PMTUD 从较小 packet 开始,逐步发送更大的 probe,依据 transport 或 packetization layer 的 delivery feedback 判断哪些大小有效。即使 ICMP 从未到达,endpoint 仍有退出路径。

probe 不是 certainty。一次孤立的大 probe 丢失可以被视为越过 MTU;如果附近 packet 也在丢失,congestion 等原因会让结论不确定。algorithm 必须保留 search state、设置 timer,并避免把普通 loss 永久编码为过小 PMTU。

IETF PMTUD Working Group charter 把旧 PMTUD 的 weakness 记为新 link 与 tunnel 部署的长期障碍,并把“不依赖 ICMP、从小到大 probe”列为工作方向。这份 charter 证明 institutional scope,不证明所有 participant、operator 或 implementation 已形成统一 mandate。

RFC 8899 又把这种方法带到 datagram packetization layer。DPLPMTUD 测试特定大小,获得送达确认后提高 confirmed size,检测到 black hole 后降低。经过验证的 PTB 可以辅助,但不能成为唯一依据,更不能用来提高 size。

UDP 自己没有 acknowledgement,因此 application 或其 packetization layer 必须提供 probe confirmation。权力上移的成本由此显现:原本只发送 datagram 的软件现在可能需要维护 state,解释 loss,并安排额外 traffic。

今天保留的是并存,而不是一次替换

当前 TCP specification 强烈建议 PMTUD,也建议 PLPMTUD。固定小 size 仍是 fallback,RFC 9293 同时指出只发小 packet 会损害 performance。制度没有把 router feedback 一次性淘汰,而是在其旁边加上 endpoint escape。

当前 Linux 文档展示了 operator surface。tcp_mtu_probing=0 关闭 TCP probing;mode 1 平时关闭,在检测到 ICMP black hole 后启用;mode 2 始终启用,并从配置的 base MSS 开始。tcp_probe_interval 文档默认十分钟。

这些值不能证明全球 enablement,也不能代表所有 kernel version。它们证明 installed software 仍保留不同策略。一个 host 可以使用合法 ICMP、在 silence 后 probe,也可以根本不启用 probing。

锁定由此形成:firewall、tunnel、kernel、transport 与 application 不会在同一天整体升级。RFC 8900 因而没有宣布 fragmentation 已被废除,而是要求 upper layer 减少依赖。旧 signal、验证、probe escape 与 conservative fallback 被同时保留下来。