举一个我们常见的的场景,我们在办公室使用电脑上网,电脑链接交换机,交换机连接路由器,路由器连接电信网络,然后访问了www.sina.com.cn,从电脑发出的数据总共经过了以下路径:
其中,每个节点都有一个MTU值,如下:
假设现在EG的MTU最大值设置成了1400,然后电脑发送了一个ip数据包(2000)到达EG后,因为链路的MTU是取当前链路的最小值(EG的1400小于接入交换机的1460,且同时小于核心交换机的1500,所以去EG的值作为内网链路的MTU),这时候EG往电信外网传输IP数据包会按照EG的MTU被拆成2个包,大小分别是一个1400,另外一个600,然后进行传输。
电信外网接收到了一个1400的帧,电信设备会发现大于自己设置的最大值:1200,如果IP包不允许分片的话,那么运营商的设备会直接就把这个包丢弃了,根本就不会到达新浪网的服务器,因此,到这里我们就会发现,MTU其实就是在每一个节点的管控值,只要是大于这个值的数据帧,要么IP数据所到的设备选择分片再传输,要么直接丢弃。
疑问1:那么MTU的值为什么是1500?
由于以太网EthernetII规定最大的数据帧是1518Bytes,除去以太网帧的帧头
(DMAC目的MAC地址6Bytes+SMAC源MAC地址6Bytes+Type域2bytes=14Bytes)和帧尾CRC校验部分4Bytes (这个部份有时候大家也把它叫做FCS),RFC标准的MTU范围为64-1500字节。那么剩下承载上层协议的地方也就是Data域最大就只能有1500Bytes。
疑问2:那么为什么有时候IP报文不能被分片呢?
分片最大的坏处就是降低了传输性能,本来一次可以搞定的事情,分成多次搞定,影响效率!因此,在网络层更高一层(就是传输层)往往会对此加以注意!有些高层因为某些原因就会要求我这个报文不能数据包,他们要完整地数据包,所以会在IP数据包包头里面加上一个标签:DF(Donot
Fragment)。这样当这个IP数据包在一大段网络(水管里面)传输的时候,如果遇到MTU小于IP数据包的情况,转发设备就会根据要求丢弃这个数据包,然后返回一个错误信息给发送者。
疑问3:我们应该怎么去探测链路中的MTU值呢?
1、Ping是用来检测TCP/IP链接问题的诊断工具,可以检查两端网络连接的状况。同时我们可以利用Ping命令的MTU探测功能进行MTU值的测量。我们在windows主机(或设备),通常使用ping命令并设置不允许数据进行分片,在不断调整报文长度的过程中如果大字节报文一直可以无法ping通,则需要继续较少报文长度直到ping通为止,即可判断中间线路的MTU最小值(路径MTU)。举例如下:
1)Windows电脑上:ping <目标IP地址> -l <字节数,一般从1500开始往下测试>
-f
ping 114.114.114.114 -l 1400 -f
注:l表示长度,f表示不分片
2)EG路由器上:ping <目标IP地址> length <字节数,一般从1500开始往下测试>
df-bit
ping 114.114.114.114 length 1400 df-bit
注:length表示长度,df-bit表示不分片
通过以上的案例,我们引出,我们EG在部署网监过程中遇到的运营商MTU问题导致网监发送失败的案例,如下: