巨型帧不会让 VPN 路径承载 9000 字节的报文
大 MTU 只是本地链路的约定。在抬高内层接口之前,先从路径上最小的链路中减去隧道开销。
你在局域网里启用了 9000 字节的帧,本以为 VPN 会更快。结果它变慢了,甚至完全无法传输大文件。巨型帧只是本地链路的约定;它们不会扩大隧道所穿越的路径。
可用预算由路径上最小的边界决定,其中也包括隧道增加的封装。
巨型帧究竟改变了什么
MTU 是单个接口的属性。在服务器和它的交换机上抬高它,意味着这两者可以在不分片的情况下交换更大的帧。这与交换机之后的下一跳路由器、运营商,或隧道的另一端毫无关系。那些设备各有各的上限,超过其中任何一个的报文都会按你并未设定的规则被丢弃或分片。
本地约定,全局后果。困惑就在这里。
封装税
隧道把你的报文包进另一个报文里。IPv4 上的 UDP 里,WireGuard 大约增加 60 字节开销;OpenVPN 的 UDP 模式也在这个范围内,而 IPsec 随模式和算法变化。这些字节来自外层路径的预算,而不是凭空出现。
所以,一旦加上隧道头部,1500 字节的外层链路就装不下 1500 字节的内层报文。
这笔算术值得算一次。在 1500 字节的路径上,WireGuard 接口希望 MTU 约为 1420,好让封装后的报文放得下。把内层接口设成 9000,每个大报文都需要隧道无法完成的分片,或者直接被丢弃。
找出路径上最小的链路
沿着路由走一遍,找出最低的 MTU。局域网通常是 1500 或 9000,广域网通常是 1500,移动链路或 PPP 链路还可能更低。然后减去隧道开销。如果结果小于内层接口的 MTU,答案就出来了。路径 MTU 发现可以自动找到它,但前提是它所依赖的 ICMP 消息被允许通过。
ICMP 被过滤,是“小请求正常、大传输卡死”这一经典现象的原因。
在不扩大改动的前提下测试尺寸依赖
用一次有代表性的传输,并保留原始值以便还原。ping -M do -s 1472 在置位 DF 位的情况下测试 1500 字节的报文;不断减小尺寸直到通过。如果只有大报文失败,你面对的是尺寸问题,而不是路由问题。
读取抓包时要留神主机侧的 offload。分段 offload 可能显示出比实际经过线缆的帧大得多的帧,于是一条正常的路径看起来像坏掉,而坏掉的路径却显得正常。
什么时候大 MTU 才是正确的设计
受控的专用网络确实可以端到端地跑更大的帧,前提是路径上每台设备都同意,并且把隧道开销计算在内。那是一种细粒度、按链路记录数值的协同设计,而不是往客户端里填一个大数字。
对于普通的公网出口,按 1500 或更小来假设,让隧道去挑选安全的内层 MTU。RFC 8201 涉及 IPv6 情形下的路径 MTU 发现,是了解这套反馈机制应当如何工作的有用参考。