MTU 与 IP 分片 · 完全图解

MSS 和 MTU 差多少?为什么要拼命避免分片?PMTU 黑洞是什么鬼

MTU 1500 MSS 1460 DF / MF / 片偏移 PMTUD 黑洞

①MTU:一条链路一次能装多少

MTU(Maximum Transmission Unit,最大传输单元)是数据链路层的概念,指一个数据帧能承载的最大数据部分(payload)字节数。以太网的 MTU 标准是 1500 字节。

当一个 IP 数据报比链路的 MTU 大时,就装不进一个帧里,必须进行处理——这就是 IP 分片的由来。

以太网帧的 1500 字节限制 以太网帧总长 1518 字节 帧头 14 数据部分(IP 数据报)最大 1500 ← 这就是 MTU FCS 4 14 + 1500 + 4 = 1518 字节 超过 1500 的 IP 数据报 → 必须分片,或由发送端提前切小

常见 MTU 值

以太网 1500;PPPoE 拨号 1492(多 8 字节 PPPoE 头);部分隧道/VPN 会更小(因为要再封装一层头)。

巨型帧(Jumbo Frame)

数据中心内部网络可把 MTU 调到 9000,减少包数量与中断开销,提升吞吐。但要求整条路径都支持。

②MSS 与 MTU:差的那 40 字节去哪了

公式(背下来):MSS = MTU − IP头部(20) − TCP头部(20) = 1500 − 40 = 1460
MSS(Maximum Segment Size)是 TCP 层的概念,表示一个 TCP 报文段中数据部分(不含头)的最大长度。
为什么要减掉 40?因为 IP 数据报 = IP 头(20) + TCP 头(20) + 数据。要让整个 IP 数据报 ≤ 1500,数据部分就最多 1460。(若有 IP 或 TCP 选项,头部会变长,MSS 相应更小。)
MTU 与 MSS 的包含关系 以太网帧载荷上限 = MTU = 1500 字节 IP 数据报(总长 ≤ 1500) IP 头 20 TCP 头 20 数据部分 ≤ 1460 ← 这就是 MSS 20 + 20 + 1460 = 1500
MSS 在哪协商?在 TCP 三次握手的 SYN 报文里,通过 TCP 选项互相通告。双方取较小值使用。目的就是让 TCP 层提前把数据切好,从而避免 IP 层分片——这是理解本节的核心。

③IP 分片:靠三个字段拼回去

当 IP 数据报大于链路 MTU 且允许分片时,路由器会把它切开。为了在目的地能正确重组,IP 头部有三个专门的字段:

字段位数作用
标识(Identification)16同一个原始数据报的所有分片共享同一个 ID,目的地据此判断哪些片属于一起。
标志(Flags)3DF(Don't Fragment):置 1 表示不许分片;MF(More Fragments):置 1 表示“后面还有分片”,最后一个片 MF=0。
片偏移(Fragment Offset)13该分片的数据在原数据报中的位置,单位是 8 字节。因此除最后一片外,每片数据长度必须是 8 的倍数。
4000 字节的 IP 数据报被切成 3 片(MTU 1500) 原始 IP 数据报:总长 4020(IP头20 + 数据4000) 分片 1 偏移 0 · MF=1 · 1480 数据 分片 2 偏移 185 · MF=1 · 1480 数据 分片 3 偏移 370 · MF=0 · 1040 数据 1480 + 20 = 1500 1480 + 20 = 1500 1040 + 20 = 1060 片偏移单位是 8 字节:1480 ÷ 8 = 185,所以第二片偏移 = 185 重组只在目的地主机进行,中间路由器不重组
重组在哪发生?只在最终目的主机。中间路由器只负责切,不负责拼——这让路由器可以独立转发每个分片(甚至走不同路径)。

④为什么大家拼命想避免分片

丢一片 = 全报废

IP 层没有重传机制。任何一个分片丢失,目的主机就无法重组,整个原始数据报被丢弃。对 TCP 来说,这意味着整个 TCP 段重传(而不是只重传丢的那一片)。

重组有开销与风险

目的主机要缓存分片、启动定时器等待,消耗内存;还可能被分片攻击(如泪滴攻击 Teardrop)利用。

IPv6 直接不让中间分片

IPv6 取消了路由器分片能力:中间路由器遇到太大的包直接丢弃并回 ICMPv6 错误,只由源端负责分片。因此必须依赖 PMTUD。

所以核心策略是:TCP 在握手时用 MSS 协商好尺寸,从源头就把数据切成不会触发分片的大小——把问题消灭在 IP 层之前。这也是 MSS 存在的意义。

⑤路径 MTU 发现(PMTUD)

互联网上一段路径可能经过多条不同 MTU 的链路(比如经过 PPPoE 的 1492、隧道的 1400)。整条路径上最小的那个 MTU 叫做 路径 MTU(PMTU)。源主机需要知道它,才能发出“刚刚好不分片”的包。

PMTUD 的做法:发送方把 IP 包的 DF 标志置 1(不许分片)。如果路径上某台路由器发现这个包大于自己出接口的 MTU,它就丢弃该包,并回一个 ICMP「需要分片」差错报文(Type 3, Code 4),里面带上它自己的 MTU。源主机收到后调小发送尺寸并重试,逐步探测出整条路径的 PMTU。
PMTUD:DF=1 的包遇到小 MTU 链路 → 回 ICMP 告知 源主机 路由器 A MTU 1500 ✓ 路由器 B MTU 1400 ✗ 太小 目标主机 DF=1, 1500 字节 ICMP Type3/Code4:“需要分片,我的 MTU=1400” 源主机重发:DF=1, 1400 字节 → 顺利通过 结果:源主机记下 PMTU=1400,后续都按这个尺寸发,不再分片

⑥PMTU 黑洞:防火墙好心办坏事

问题来了:很多网络管理员出于“安全”考虑,在防火墙上一律丢弃 ICMP 报文。于是路由器发回的「需要分片」ICMP 被无情丢掉,源主机永远收不到,也就不知道该调小尺寸。

结果:源主机一直发 DF=1 的大包,路由器的链路一直装不下,包被一直丢弃——连接看起来“建立了却传不了数据”。这就是著名的 PMTU 黑洞(PMTU Black Hole)。

典型症状(面试描述题):
  • 能 ping 通(小包没问题),但打不开网页 / 下载不了大文件(大包过不去)。
  • 三次握手能建立,但一传数据就卡住。
  • 部分网站正常、部分不正常。
排查与解决:用 ping -s <size> -M do 手动测不同大小的 DF 包;在防火墙上放行 ICMP Type 3 Code 4;或在服务器上调小 MSS(MSS Clamping,如设为 1400 / 1360)。
# 手动探测 PMTU:DF=1,payload 1472 + IP头20 + ICMP头8 = 1500
ping -M do -s 1472 8.8.8.8      # 通 → MTU ≥ 1500
ping -M do -s 1400 8.8.8.8      # 逐步调小找到临界值

# 若返回 "Frag needed and DF set" → 说明被 PMTU 限制

# 常见缓解:MSS Clamping(在网关/防火墙上改小 MSS)
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
         -j TCPMSS --set-mss 1360
为什么 VPN / 隧道经常遇到这个问题?因为隧道会在原 IP 包外面再封装一层头(如 GRE、IPsec、WireGuard),实际可用 MTU 变小。若没相应调小 MSS,就容易触发 PMTU 黑洞,表现为“连上 VPN 后某些网站打不开”。

⑦面试高频追问

Q1:MTU 和 MSS 分别是什么?关系是?
MTU 是数据链路层一次能承载的最大数据量(以太网 1500);MSS 是 TCP 段中数据部分的最大长度。MSS = MTU − IP头(20) − TCP头(20),以太网下为 1460。
Q2:MSS 在哪里协商?
在 TCP 三次握手的 SYN 报文中通过 TCP 选项互相通告,双方取较小值。目的是让 TCP 层提前切好数据,避免 IP 层分片。
Q3:IP 分片靠哪几个字段重组?
标识(Identification)判断哪些片属于同一个包;MF 标志判断是否还有后续分片;片偏移确定该片在原数据中的位置(单位是 8 字节)。重组只在目的主机进行。
Q4:为什么要尽量避免 IP 分片?
IP 层没有重传机制:丢一个分片 → 整个 IP 数据报无法重组被丢弃 → TCP 要重传整个段,效率极低。此外重组消耗资源且存在分片攻击风险。IPv6 更是取消了路由器分片。
Q5:什么是 PMTUD?
路径 MTU 发现:发送方置 DF=1 禁止分片;路径上 MTU 不足的路由器丢弃并回 ICMP Type 3 Code 4(需要分片)并告知自己的 MTU;源主机据此调小发送尺寸,最终得到整条路径的 PMTU。
Q6:什么是 PMTU 黑洞?怎么解决?
防火墙屏蔽了 ICMP,源主机收不到“需要分片”通知,一直发过大的 DF 包导致数据传不动。症状:ping 通但网页打不开、大文件传不了。解决:防火墙放行 ICMP Type 3 Code 4;或用 MSS Clamping 调小 MSS。
Q7:IPv6 在分片上有什么不同?
IPv6 中间路由器不再分片,遇到超大的包直接丢弃并回 ICMPv6「Packet Too Big」。分片只由源端进行,因此 PMTUD 成为必需而非可选。
Q8:为什么连上 VPN 后有些网站打不开?
VPN/隧道会在原包外再封装一层头,使实际可用 MTU 变小。若未同步调小 MSS 且 ICMP 被拦,就会触发 PMTU 黑洞:小包(握手)能过、大包(数据)过不去。

✓一句话速记

MTU 1500(链路)、MSS 1460(TCP 数据);MSS 在握手时协商,目的就是提前切好、躲开 IP 分片;分片靠标识+MF+片偏移重组、丢一片全丢所以很贵;PMTUD 靠 DF=1 探测路径最小 MTU,而 ICMP 被拦就会造成“ping 通但打不开网页”的 PMTU 黑洞。