什么是 MTU ?
我们通常意义上的说的以太网 MTU 是指不包含以太网 Header 和 FCS (帧检验序列:Frame Check Sequence)的以太网 Payload (有效载荷)部分,IEEE802 规定了大小为0~1500字节。这个长度不包含链路层,MTU是链路层对上层网络层的设计。所以,二层以太网帧长应该为这个长度加上18 bytes,该18 bytes 由 6 bytes的目的MAC地址-DA、6bytes的源MAC地址-SA和 2 bytes的上层协议类型以及 4 bytes 的FCS组成。FCS 由硬件计算,被添加到帧的最后,帧校验可以判断数据包是否由于噪声而被破坏出现了乱码位。根据上述,一个以太网数据帧,最大可达到1500 + 18 = 1518 字节。
这里还有一个 MSS 的概念:TCP 有一个最大分段大小,用来在网络传输中通知传输双方每个分段中能发送的最大 TCP 数据量。我们可以从上图中清晰的看到 MSS 表示的数据。通常网络情况下,TCP MSS = MTU - IP Header 长度 - TCP Header 长度
MTU 的大小也跟我们上网的方式有关系,不同的上网方式支持不同的 MTU。
比如一般的EtherNet(以太网,默认值):1500
PPPoE(PPP Over Ethernet在以太网上承载PPP协议)/ADSL:1492
Dial Up/Modem:576
定义 MTU 的意义
MTU约束了 MAC 帧中数据部分(payload)的大小也就是说限定了 IP 封包的大小,这个大小包括 IP 封包的包头;而最终 IP 包是要放进 MAC 帧中的。
所以我们可以认为MTU = IP封包的大小
IP报文的分片和重组
路径 MTU 发现
在因特网协议中,一条因特网传输路径的“路径最大传输单元”被定义为从源地址到目标地址所经过路径上到所有 IP 跳到最大传输单元到最小值。举个例子,一个很长的水管,由不同粗细的水管组成,那么单位时间内通过该长水管的最大水量必定由最细的水管来决定。
我们结合上图说下,路径 MTU 发现的工作原理:
1.在发送端主机发送 IP 数据报时将首部的分片禁止标志位设置为1。(Don’t fragment = 1,我们可以从 Wireshark中很容易看到该设置)。由于设置为了1,表明途中遇到的路由器不能私自将巨型包分片,而是直接将包丢弃。
2.丢弃之后,通过 ICMP 消息将数据链路上的 MTU 值发给发送主机。
3.发送端主机将从 ICMP 消息中获得的 MTU 值设定为当前 MTU,然后根据当前 MTU 对数据报进行重新发送。
Internet网络层的设计有10大原则,其中一个原则就是『避免静态选项和参数』:如果不可避免要使用参数的话,比如最大数据包的长度,最好的办法就是让发送方和接收方协商一个数值,而不是直接使用定义好的固定的值。路径 MTU 发现要求发送端和接收端中间的网络路径是那个的设备都要支持 MTU 协商,如果有其中一台不支持,就无法协商到最小的 MTU。有时候也因为安全等原因,ICMP 消息被禁用导致路径 MTU 发现也不能生效。
注意
出于安全的考虑,比如防范 DDOS 攻击,有些网络域禁止了 ICMP 的传输,导致路径 MTU 发现功能无法正常运行,会造成用户的使用网络出现故障。常见的一个表现就是,在低数据流量低情况下可以正常工作,但在有大量数据发送的时候,网络就会没有响应。
MTU值设置不当会引起什么问题
MTU值引起的常见现象:
- 部分网站无法访问
- 上网速度很慢
- 部分网络应用无法使用
- 图片不能上传等等
如何确定 MTU 值?
在 OSX 系统中,我们可以通过 ping 命令来发送特定大小的 ICMP 消息包。如上图所示,我刚开始使用来 packet size 为 1465 bytes 大小来 ping,数据包直接是被 100% 丢失的,而使用来 1464 bytes 来 ping,便发送接受正常。我家里使用的 PPPoE 网络,所以根据我们上面计算方式,1464 + ICMP Header(8 bytes)+ IP Header(20 bytes)= 1492,这便是 IP 封包的大小,也就是 MTU 的大小。跟 1500 bytes 相差的便是 PPPoE 网络带来的 8 bytes,由PPPoE Header(6 bytes)+ PPPID(2 bytes)得来。