深入理解Linux网络技术内幕——IPv4 分段与重组


封包的分段和重组是IP协议最重要的工作之一。

深入理解Linux网络技术内幕——IPv4 分段与重组_第1张图片

IPv4报头中有一个len字段(用于表示报文的总长度,单位:字节)占16bit,因此,封包的最大尺寸定义为64K,(2^16/1024=64)。

但是,在实际网络传输中,没有几个网络接口能够传输64K这么大的封包,而是有一个MTU表示其最大传输单元。这样,当要传输的封包大于MTU时,就需要对封包进行分段。 这里需要说明,我们指的MTU,不仅仅是出口设备的MTU,它取决于很多因素,如路由表项所用的MTU、出口设备的MTU等。

我们先不用过多与关注MTU如何计算,而应该注意,当封包大于MTU时,需要将封包分为一些大小相等(MTU大小)的片段,然后再分别进行传输。(当然,封包不一定能以MTU大小等分, 因而最后一个封包的大小可能达不到MTU这一尺寸)。

分段后的封包一般传输到目的主机后才进行重组,但是一些中间设备(如防火墙、NAT路由器设备)可能需要查看封包的完整内容,这是也可以对封包进行重组。

分段与重组对上层的影响

分段和重组是会占用CPU和内存,消耗带宽等,过多的分段和重组工作可能会影响系统整体性能,如果我们能够做一些优化,避免不必要的分段重组,就可以减少一些开销。优化工作在上层(L4、L5)进行。

我们举个例子看下一些不必要的分段:

A->B->C :   封包(1000字节)从系统A要经过B传给目的系统C,A->B  MTU为 800字节, B->C的MTU为512

在没有优化的情况下,在A->B时,先根据A->B的MTU将封包分段为800字节和200字节,在B->C时,在根据其MTU,包A传来的800字节的封包在分段为512字节和188字节。

而如果我们做一些优化,实现了解到A->B->C这一路径的MTU为512(取800和512的较小值),那么在A主机上直接将分包分为512字节和488字节。如此,就只需要进行一次分段,减少了系统开销。

TCP和UDP是不了解分段和重组的过程的,但是应用层却可以了解。

路径MTU发现功能可以发现整条路径的MTU(PMTU)。

RFC也规定主机至少要能接收576大小的封包,因而也可以吧MTU设置为576这一安全值。

分段与重组的实现

IPv4报头中,有一些字段用于分段和重组

Flags :─ 由3位字段构成,其中最低位(MF)控制分片,存在下一个分片置为1,否则置0代表结束分片。中间位(DF)指出数据包是否可进行分片。第三位即最高位保留不使用,但是必须为0。
Fragment Offset :─ 13位字段,指出与源数据报的起始端相关的分片数据位置,支持目标IP适当重建源数据报。



你可能感兴趣的:(Linux网络内核协议栈)