精确计算每个隧道/封装层从 MTU 里吃掉多少字节,以及 TCP 会话实际得到的 MSS。
为什么重要。 标准以太网 MTU 是 1500 字节。一旦叠加隧道(GRE、VXLAN、WireGuard、IPSec),每层都会偷走头部字节。内层 TCP 以为自己的 MSS 是 1460,但外层帧已经超过了路径 MTU——包被分片,或者设了 DF 时被悄悄丢弃。路径 MTU 黑洞是 SD-WAN、k8s CNI overlay 和 IPSec VPN 上"诡异、间歇性"连通问题的最常见原因之一。
工作原理。 从接口 MTU(最外层帧的负载预算)开始,按"从外到内"的顺序依次减去每层的封装开销。所有层减完后剩下的就是内层 IP 包可用的 MTU。再减去 IP 头(IPv4 为 20 字节,IPv6 为 40)和 TCP 头(默认 20 字节)就得到有效 MSS。
使用的开销表(每层,来自 RFC):
- 以太网头不计入——MTU 本来就指 L3 负载。
- VLAN 802.1Q — 4 字节。
- Q-in-Q — 8 字节(两个 VLAN 标签)。
- PPPoE — 8 字节(6 字节 PPPoE 头 + 2 字节 PPP 协议)。
- GRE — 最少 4 字节;带 Checksum/Key/Sequence 选项时 +4。
- VXLAN — 8 字节。
- Geneve — 基础 8 字节(不含可变 TLV)。
- WireGuard — IPv4 上 80 字节(32 外层 IP + 8 外层 UDP + 32 WG 数据消息 + 8 poly1305 标签),IPv6 上 100(60 外层 IP + 8 外层 UDP + 32 WG 数据消息)。
- IPSec ESP — 取决于加密 + 认证 + 尾部。传输模式 AES-GCM ≈ 55 字节;隧道模式 ≈ +20(新外层 IP 头)。
诊断输出。 对每个栈报告:
- 每层开销和累计总数;
- 封装后剩余 MTU;
- 减去 IP + TCP 头后的有效 MSS;
- 用
ping -M do -s <大小>(Linux)或 ping -f -l <大小>(Windows)探测路径 MTU 的精确 DF 探测大小;
- 当有效 MSS 低于 1360 时告警(可能导致 TCP 性能问题或 PMTUD 失败)。
小贴士。
- WireGuard 用户:把 WG 接口 MTU 设为
外层 MTU − 80(IPv4)或 − 100(IPv6),避免双重分片。
- 数据中心 VXLAN:1500 字节底层时把 overlay MTU 设为 1450。
- PPPoE DSL:在 WAN 侧
ping -M do -s 1472 得到 PPPoE 再扣 8 字节之前的真实路径 MTU。