目录
IPv4 报文的格式
IPv4 Header
-
Version(版本号)(4bits):值的 4,表示 IPv4。
-
Header Length(IPv4 Header 的长度)(4bits):IPv4 Header 不是固定长度的,存在一些可选字段。
- 最小值为 5:代表头部长度为 20Bytes(5×4)。如果没有可选字段,那么它的值就是 5。
- 最大值为 15(2^4-1):代表头部长度为 60Bytes(15×4)。
-
TOS(Type of Service,IPv4 承载的上层业务类型)(8bits):用于 QoS 场景。
- TOC 模式:前 3bit 用于标识优先级(Precedence),4-7bit 分别同于标识时延、吞吐量、可靠性、开销(一个数据包只能有一位生效),最后 1bit 备用。
- DSCP(差分服务代码点)模式:使用 0-5bit 表示 64 种业务类型,最后 2bit 备用。
-
Total Length(IP Packet 的总长度)(16bits):最大长度为 65535Bytes(2^16-1)。
-
Identification(IP Packet 唯一标识)(16bits):在 IP Fragment and Reassembly(分片与重组)中,用于标识多个分片来自同一个 Packet,以此进行重组。
-
IP Flags(标志位)(3bits):标识 IP Packet 是否被分片。
- MF(More Fragments):为 1 时表示还有更多的分片;
- DF(Don’t Fragment):为 1 时表示这个数据包不能被分片;
- Reserved(保留)
-
Fragment Offset(分片偏移量)(13bits):用于指明分片在原始数据包中位置。Receiver 在进行分片重组时,以此来确定多个分片间的顺序。偏移量的单位为 8Bytes。
-
TTL(Time to Live,生存时间)(8bits):指明了 IP Packet 可以经过的路由器数量,防止数据包被无休止的传播。初始值由 Sender 设置(通常为 32 或 64),每经过一个路由器,该字段值就会 -1。如果 TTL 减至 0,那么路由器会丢弃该数据包并发送一个 ICMP 超时消息给 Sender。
-
Protocol(上层协议类型)(8bits):标识上层协议的类型,例如:ICMP、TCP、UDP 等等。
-
Header Checksum(首部校验和)(16bits):根据 IP Header 所计算出来的校验和,用于确定数据没有被篡改。
-
Source Address(源 IP 地址)(32bits):Sender 的 IP 地址,用于回包。
-
Destination Address(目标 IP 地址)(32bits):Receiver 的 IP 地址,用于下一跳路由。
-
Option(选项)(可选,可变长度):包含一些特定的高级功能和参数,例如:路径记录、时间戳等。
-
填充(Padding)(可变长度):用于将 IPv4 Header 的长度调整为 4Bytes 的倍数。
IP 报文的分片和重组
IP MTU
IP MTU(Maximum transmission unit,最大传输单元)用于指示 IP Packet 的最大长度,是一种物理限制,即:Network Interface 一次所能传输的最大的 Packet 大小。
所以当一个 IP Packet 的 Total Length > IP MTU 时,就必须要进行分片,然后才能在 Network devices 中传输。L3 以此来适应不同的 L2 网络设备,进而屏蔽了底层网络的差异。
另外,MTU 的大和小并没有直接的好坏之外,更大的 MTU(通常是 9000)意味着更低的额外开销,更小的 MTU(通常是 1500)意味着更低的网络延迟,需要根据实际的应用场景来进行配置。
IP Fragment and Reassembly
IP Fragment and Reassembly(分片和重组)都是对于 IP Packet 而言的,将 Packet 从术语上进行区分:
-
IP Datagram:长度大于 IP MTU 的原始数据包。将一个大的 IP Datagram 切分为多个小的 IP Fragments。
-
IP Fragments:长度等于小于 IP MTU 的数据包分片。它们的 Header 具有以下特征:
- Identification 都一致。
- Flags MF 都为 1(more fragments),只有最后一个分片为 0(last fragment)。
- Fragment Offset 顺序排列。
举例来说。
第一个表格中:IP Datagram 的 Total Length 为 5140(IP Header 20 + IP Payload 5120)。
- DF = 0, 允许分包;
- MF = 0, 未做分包。
第二个表格中:
- 0-0:IP Fragment Total Length 为 1500(IP Header 20 + IP Payload 1480,Offset 为 0 = 0 / 8)
- 0-1:IP Fragment Total Length 为 1500(IP Header 20 + IP Payload 1480,Offset 为 185 = 1480 / 8)
- 0-2:IP Fragment Total Length 为 1500(IP Header 20 + IP Payload 1480,Offset 为 370 = 185 + 1480 / 8)
- 0-3:IP Fragment Total Length 为 700 (IP Header 20 + IP Payload 680,Offset 为 555 = 370 + 1480 / 8)
Path MTU Discovery(路径 MTU 发现)
IP Fragment 机制存在 2 点显著问题:
- 加重了路由器的工作负载;
- 在分片传输中,一旦某个分片丢失,会造成整个 IP Packet 作废。
为了解决这些问题,就要避免 IP Pakcet 进行 Fragment。最理想的情况下,当然就是要求传输链路上的所有网络中间节点的 MTU 都是一致的。这在数据中心内,通过统一的 MTU 规划或许可以做到。
但在复杂的公网中,还是得依靠 PMTUD(Path MTU Discovery,路径 MTU 发现)技术。顾名思义,PMTUD,通过主动去 Discovery 整个传输链路上存在的最小 MTU,继而在 Host 发送时 IP Packet 时就事先完成了分片,那么网络中间件就无需再进行分片了。
PMTUD 由 ICMP 协议支持。
-
srcHost 向 dstHost 发送 IP Header 中 DF(Don’t Fragment,不分片)控制位为 1 的 Packet。
-
路径上的网络设备根据 IP Packet 的大小和自身的 MTU 做出不同的决定:
- 如果 IP Packet 大于设备的 MTU,就丢弃 Packet,并返回一个包含了该设备 MTU 的 ICMP 消息;
- 如果 IP Packet 小于设备的 MTU,就继续向 dstHost 传递;
- srcHost 收到 ICMP 消息后,会不断使用新的 MTU 发送 IP Packets,直到某个大小的 IP Packet 符合为止。
Path MTU 值至少可以缓存约 10 分钟,在这 10 分钟内使用刚得到的 MTU 值,过了 10 分钟后就重新做一次路径 MTU 发现。