v6 为什么不分片
IPv6 规定中间路由器不分片:超过路径最大传输单元的包会被直接丢弃,并回一条「包太大」的 ICMPv6 消息(类型 2),其中携带下一跳的 MTU 值,发送方据此调整包长(RFC 8201)。这与 IPv4 由中间路由器分片的行为完全不同。
黑洞从哪来
如果这条 ICMPv6 消息被防火墙拦掉,发送方收不到任何反馈,就会反复重发同样过大的包,表现为「小请求正常、大响应超时」——这就是经典的 MTU 黑洞。IPv4 里对应的消息是「需要分片但被禁止」的类型 3 代码 4。
基本信息
| 消息类型 | ICMPv6 类型 2 Packet Too Big |
|---|---|
| 携带内容 | 下一跳的 MTU 值 |
| IPv4 对应 | 类型 3 代码 4(需要分片但设置了禁止分片) |
| 关键风险 | 该消息被拦截即形成 MTU 黑洞 |
典型使用场景
- 隧道(6in4、VPN)场景下的 MTU 规划与验证
- 排查「能 ping 小包、传大文件就断」这类疑难问题
- 防火墙策略评审:确认允许必要的 ICMPv6 差错消息
- 云上与容器叠加网络的封装开销计算
观察与验证
观察与验证
ping6 -c 3 -s 1400 2400:3200::1 # 逐步加大包长定位阈值
tcpdump -nn 'icmp6 and ip6[40] == 2' -c 5 # 抓「包太大」消息
sysctl net.ipv6.conf.all.mtu # 查看接口 MTU 设置
ip -6 route show | head # 看路由与 MTU 提示封装开销估算
| 场景 | 额外开销 | 说明 |
|---|---|---|
| 纯 IPv6 | 40 字节头 | 基础值 1500 的网络可以直接使用 |
| 6in4 隧道 | IPv6 头加 IPv4 头 | 通常把隧道口 MTU 降到 1480 或更低 |
| GRE 或 IPsec 隧道 | 按封装方式增加若干字节 | 需按实际封装精确计算 |
| 容器叠加网络 | 按 overlay 方案增加若干字节 | 调小容器网卡 MTU 常能立刻缓解 |
隧道场景要同时考虑内外层头部开销:MTU 不匹配时的典型表现是「小页面能打开、大资源加载失败」。
部分老设备会把 ICMPv6 类型 2 当成未知报文直接丢弃,这是 IPv6 网络「能 ping 却不能传输」的经典根因。防火墙策略必须显式允许这类差错消息。
用 ping6 的包长参数逐步加大,可以在不抓包的情况下快速找到链路还能通过的阈值;把隧道口或接口 MTU 设成略小于该阈值,通常比贴着上限更稳妥。