关于MTU、IP MTU和MPLS MTU的概念,以及mpls mtu override 1504这条命令的作用,这里不再复述,详情请看:《【实验】关于MPLS MTU的实验》
| FCS | Data | TCP | IP | Label | Eth | | MTU (default 1500 byte) | | IP MTU | | MPLS MTU | (注:上面的图是拿字符画的,手机上一自动换行就乱了,如果出现了变形,请在电脑上观看,下同)
实验环境:
操作系统:Windows 10(1607,14393.351,当时最新测试版),模拟器:GNS3 IOU for Windows 1.5.2(当时最新正式版)
注:当然,只要有思科模拟器都可以做这个实验

实验需求:
本实验借用了《【实验】MPLS L2VPN下,Point-to-Point的AToM实验》的实验拓扑和配置来完成。强烈建议您先看看这篇文章,尤其文章结尾的数据包包头分析部分。
实验步骤:
1、先配置IP地址、IGP(OSPF 234)和 MPLS:
IOU2:
conf t int e 0/2 ip cef int e 0/2 router ospf 234 int r e 0/2 , l 0 |
IOU3:
conf t int e 0/2 int e 0/3 ip cef int r e 0/2-3 router ospf 234 int r e 0/2-3 , l 0 |
IOU4:
conf t int e 0/3 ip cef int e 0/3 router ospf 234 int r e 0/3 , l 0 |
|
IOU1:
conf t |
IOU7:
conf t |
IOU5:
conf t |
IOU6:
conf t |
IOU8:
conf t |
IOU9:
conf t |
2、配置IOU1和IOU7上的MPLS / AToM:
IOU2:
int s 2/0 |
IOU4:
int s 2/0 |
3、配置IOU5和IOU6上的MPLS / AToM:
IOU2:
pseudowire-class T56 int e 0/1 |
IOU4:
pseudowire-class T56 int s 2/1 |
4、配置IOU8和IOU9上的MPLS / AToM:
IOU2:
pseudowire-class T89 int e 1/0 |
IOU4:
pseudowire-class T89 int e 1/0 |
实验现象:
1、关于IOU1和IOU7之间的MPLS L2VPN的MTU(HDLC <······> HDLC):

我们先测试IOU1和IOU7之间的连通性:
IOU1#ping 10.1.1.7 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 10.1.1.7, timeout is 2 seconds: !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 17/18/19 ms
如果我们在IOU1上ping 10.1.1.7 size 1500,会发现不通:
IOU1#ping 10.1.1.7 size 1500 Type escape sequence to abort. Sending 5, 1500-byte ICMP Echos to 10.1.1.7, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)
问题一:首先,仔细观察的盆友会发现这个ping命令并没有设置df-bit(不允许分片),那为什么在没有设置df-bit的情况下数据包也不通呢?
| FCS | ICMP | IP | HDLC | 伪线控制字段 | 内层MPLS标签 | 外层MPLS标签 | Ethernet |
| IP MTU |
| <———————————————— MTU (default 1500 byte) ———————————————> |
回答:因为数据包从IOU1到达IOU2后,来自IOU1的数据包连带HDLC二层头部都会原封不动地封装进MPLS标签(如上图所示)。当所有头部封装完毕后,在转发的时候才发现MTU过大,而MPLS转发机制和常见的二层头部均是没有分片功能的,IP头部又隐藏在最里面最里面估计难以再次拆封出来做分片,所以就丢包了。
如果你还有疑惑,那你首先要明白这是MPLS L2VPN,不是L3VPN。IOU2虽然是三层路由器,但是在L2VPN环境下IOU2会像二层交换机一样仅会对二层数据进行阅读和处理,三层IP头部被隐藏到了二层头部中,IOU2自然不能阅读和修改(也不需要阅读和修改)数据包里的三层IP头部,那分片自然就没法做了。
如果你还是有很大的疑惑,那没办法了,谁让当年设计的时候就是这个样子的:从客户路由器(IOU1、IOU6和IOU8等)来的数据包,就是不对三层做任何修改,二层看伪线的配置可能还会处理一下,然后打上MPLS标签就准备转发给下一跳,准备转发的时候MTU默认只要大于1500字节就丢包。
问题二:那为什么MTU设置成1500字节,IOU2会认为MTU太大呢?
回答:ping命令设置的size其实是IP MTU,而MTU是要将MPLS标签包含在内的(如下图所示)。
| FCS | Data | TCP | IP | Label | Eth | | MTU (default 1500 byte) | | IP MTU | | MPLS MTU |
因为MTU最大是1500字节,IP MTU都设置成1500字节了,那就没有剩余的空间来放置MPLS标签了,IOU2自然也就丢包了。
其他相关文章:
- 关于MTU、IP MTU和MPLS MTU的概念,以及mpls mtu override 1504这条命令的作用,这里不再复述,详情请看:《【实验】关于MPLS MTU的实验》
问题三:那MTU实际大了多少呢?
回答:当数据包从IOU1到达IOU2后,IOU2准备将数据包发往IOU3时,数据包所包含的报头是这样的:
| FCS | ICMP | IP | HDLC | 伪线控制字段 | 内层MPLS标签 | 外层MPLS标签 | Ethernet |
| IP MTU |
| <———————————————— MTU (default 1500 byte) ———————————————> |
由上图可知,数据包不仅多了两个MPLS标签,在MPLS标签和HDLC二层头部之间其实还有一个伪线控制字段,最后还有一个HDLC二层头部。其中,一个MPLS标签占4个字节,一个HDLC二层头部占4个字节,一个伪线控制字段占4个字节(伪线控制字段如下图所示)。

两个MPLS标签占了8个字节,伪线控制字段占了4个字节,HDLC二层头部占了4个字节,这就意味着多了8 + 4 + 4 = 16字节。
综上所述,要想IP MTU为1500字节的数据包通过,MTU就必须要扩大到1516字节。
问题四:看到这里有人肯定要问,HDLC帧格式不是8个字节嘛,怎么这里说是4个字节?

回答:由上图可知,两个Flag(帧前后各有一个Flag字段)、Address和Control各占1个字节,Protocol和FCS各占2个字节,4 x 1 + 2 x 2 = 8字节,所以HDLC帧格式确实是8个字节。
但是在算MTU的时候,前面1个字节的Flag不算,后面2个字节的FCS和1个字节的Flag也不算,所以只剩4个字节。接下来我们抓个包看一下:
如下图所示,我在IOU2的s 2/0接口上抓包,然后在IOU1上ping 10.1.1.7 size 1500,你会发现整个数据包的大小是1504字节,而不是1508字节。而且选中“Cisco HDLC”后发现,HDLC确实只占了4个字节。

如上面抓包的截图所示,数据帧最开头的四个字节是十六进制的:0F 00 08 00。按理来说HDLC帧的开头是一个二进制为01111110(即十六进制为7E)的Flag字段才对,显然Flag字段被省略掉了。

如上图所示,数据帧也是以AB CD AB CD这种ping中的填充字符结尾,所以HDLC帧最末尾的FCS字段和另一个Flag字段也被省略掉了。
综上所述,虽然HDLC帧格式共有8个字节,但是在算MTU的时候,HDLC头部只算4个字节。
其他相关文章:
- 如果您想了解HDLC封装的报文格式,请看:《链路层常见报文格式及长度》
问题五:回到上上一个问题(问题三),路由器是可以处理小巨型帧的,如果硬是要让MTU = 1516字节的数据包通过可不可以呢?
回答:可以的。如果在IOU2、IOU3和IOU4的相应接口上配置了mpls mtu override 1516这条命令就可以实现上述需求。
mpls mtu override 1516这条命令的含义就是调整MPLS MTU的大小为1516字节,同时将这些带有MPLS标签的数据包当做小巨型帧来处理。由下图可知,MPLS MTU = MTU,调整了MPLS MTU的大小就相当于调整了MTU的大小。
| FCS | Data | TCP | IP | Label | Eth | | MTU (default 1500 byte) | | IP MTU | | MPLS MTU |
我们现在来实现这个需求:
IOU2(config)#int e 0/2 IOU2(config-if)#mpls mtu override 1516 IOU2(config-if)# *Nov 8 12:32:57.349: %MFI-3-MPLS_MTU_SET: Setting mpls mtu to 1516 on Ethernet0/2 which is higher than the interface mtu 1500. This could lead to packet forwarding problems including packet drops. IOU3(config)#int r e 0/2-3 IOU3(config-if-range)#mpls mtu override 1516 IOU4(config)#int e 0/3 IOU4(config-if)#mpls mtu override 1516
在IOU1上再ping一下:
IOU1#ping 10.1.1.7 size 1500
Type escape sequence to abort.
Sending 5, 1500-byte ICMP Echos to 10.1.1.7, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 37/38/40 ms
IOU1#ping 10.1.1.7 size 1500 df-bit
Type escape sequence to abort.
Sending 5, 1500-byte ICMP Echos to 10.1.1.7, timeout is 2 seconds:
Packet sent with the DF bit set
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 38/39/41 ms
通了!设置了df-bit(不允许分片)也是可以通的。
那如果我们把MPLS MTU修改成1515字节,就是少一个字节,还会不会通呢?
IOU2(config)#int e 0/2 IOU2(config-if)#mpls mtu override 1515 IOU2(config-if)# *Nov 8 12:36:03.428: %MFI-3-MPLS_MTU_SET: Setting mpls mtu to 1515 on Ethernet0/2 which is higher than the interface mtu 1500. This could lead to packet forwarding problems including packet drops. IOU3(config)#int r e 0/2-3 IOU3(config-if-range)#mpls mtu override 1515 IOU4(config)#int e 0/3 IOU4(config-if)#mpls mtu override 1515
显然,通不了。
IOU1#ping 10.1.1.7 size 1500 Type escape sequence to abort. Sending 5, 1500-byte ICMP Echos to 10.1.1.7, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)
2、关于IOU5和IOU6之间的MPLS L2VPN的MTU(PPP <······> Ethernet):

当数据包从IOU6到达IOU2后,IOU2准备将数据包发往IOU3时,数据包所包含的报头是这样的:
| FCS | ICMP | IP | 伪线控制字段 | 内层MPLS标签 | 外层MPLS标签 | Ethernet |
| IP MTU |
| <———————————— MTU (default 1500 byte) ————————————> |
为什么IP报头和伪线控制字段之间没有二层报头?因为IOU2上为这条伪线配置了interworking ip,所以二层报头被IOU2抹去了。
其他相关文章:
- 为什么IP报头和伪线控制字段之间没有二层报头?关于报头变化的问题,详情请看:《【实验】MPLS L2VPN下,Point-to-Point的AToM实验》
- 如果您想了解PPP封装的报文格式,请看:《链路层常见报文格式及长度》
显然,对于IOU5和IOU6的伪线来说,这个数据包多出了两个MPLS标签(共8个字节)和一个伪线控制字段(4个字节),所以只需要把MPLS MTU设置为1512字节就可以让IP MTU = 1500字节的数据包通过了:
IOU2(config)#int e 0/2 IOU2(config-if)#mpls mtu override 1512 IOU2(config-if)# *Nov 9 06:25:34.539: %MFI-3-MPLS_MTU_SET: Setting mpls mtu to 1512 on Ethernet0/2 which is higher than the interface mtu 1500. This could lead to packet forwarding problems including packet drops. IOU3(config)#int r e 0/2-3 IOU3(config-if-range)#mpls mtu override 1512 IOU4(config)#int e 0/3 IOU4(config-if)#mpls mtu override 1512
在IOU6上ping一下:
IOU6#ping 100.1.1.5 size 1500
Type escape sequence to abort.
Sending 5, 1500-byte ICMP Echos to 100.1.1.5, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 21/21/21 ms
IOU6#ping 100.1.1.5 size 1500 df-bit
Type escape sequence to abort.
Sending 5, 1500-byte ICMP Echos to 100.1.1.5, timeout is 2 seconds:
Packet sent with the DF bit set
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 19/21/23 ms
通了!设置了df-bit(不允许分片)也是可以通的。
那如果我们把MPLS MTU修改成1511字节,就是少一个字节,还会不会通呢?
IOU2(config)#int e 0/2 IOU2(config-if)#mpls mtu override 1511 IOU2(config-if)# *Nov 9 06:29:11.275: %MFI-3-MPLS_MTU_SET: Setting mpls mtu to 1511 on Ethernet0/2 which is higher than the interface mtu 1500. This could lead to packet forwarding problems including packet drops. IOU3(config)#int r e 0/2-3 IOU3(config-if-range)#mpls mtu override 1511 IOU4(config)#int e 0/3 IOU4(config-if)#mpls mtu override 1511
显然,通不了。
IOU6#ping 100.1.1.5 size 1500 Type escape sequence to abort. Sending 5, 1500-byte ICMP Echos to 100.1.1.5, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)
3、关于IOU8和IOU9之间的MPLS L2VPN的MTU(802.1Q <······> 802.1Q):

当数据包从IOU8发给IOU2时,数据包所包含的报头是这样的:
| FCS | ICMP | IP | 802.1Q | Ethernet |
当数据包从IOU8到达IOU2后,IOU2准备将数据包发往IOU3时,数据包所包含的报头是这样的:
| FCS | ICMP | IP | Ethernet | 伪线控制字段 | 内层MPLS标签 | 外层MPLS标签 | Eth |
| IP MTU |
| <—————————————————— MTU (default 1500 byte) —————————————————> |
为什么IP报头和伪线控制字段之间的802.1Q数据帧没有了?因为IOU2上为这条伪线配置了interworking ethernet,所以4个字节的802.1Q帧被抹去了,剩下Ethernet报头。
如下图所示,在IOU2的e 0/2口上抓包,然后在IOU8上ping 200.1.1.9 size 1500,我们能看到非常清晰的数据包的结构:

如下图所示,内层的Ethernet二层报头中并没有夹带4个字节的802.1Q数据帧:

其他相关文章:
- 为什么IP报头和伪线控制字段之间的802.1Q数据帧没有了?关于报头变化的问题,详情请看:《【实验】MPLS L2VPN下,Point-to-Point的AToM实验》
- 如果您想了解Ethernet封装和802.1Q封装的报文格式,请看:《链路层常见报文格式及长度》
显然,对于IOU8和IOU9的伪线来说,这个数据包多出了两个MPLS标签(共8个字节)、一个伪线控制字段(4个字节)和一个Ethernet报头(14个字节),所以只需要把MPLS MTU设置为1526字节就可以让IP MTU = 1500字节的数据包通过了:
IOU2(config)#int e 0/2 IOU2(config-if)#mpls mtu override 1526 IOU2(config-if)# *Nov 9 06:51:56.708: %MFI-3-MPLS_MTU_SET: Setting mpls mtu to 1526 on Ethernet0/2 which is higher than the interface mtu 1500. This could lead to packet forwarding problems including packet drops. IOU3(config)#int r e 0/2-3 IOU3(config-if-range)#mpls mtu override 1526 IOU4(config)#int e 0/3 IOU4(config-if)#mpls mtu override 1526
在IOU8上ping一下:
IOU8#ping 200.1.1.9 size 1500 Type escape sequence to abort. Sending 5, 1500-byte ICMP Echos to 200.1.1.9, timeout is 2 seconds: .!!!! Success rate is 80 percent (4/5), round-trip min/avg/max = 1/1/2 ms IOU8#ping 200.1.1.9 size 1500 df-bit Type escape sequence to abort. Sending 5, 1500-byte ICMP Echos to 200.1.1.9, timeout is 2 seconds: Packet sent with the DF bit set !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms
通了!设置了df-bit(不允许分片)也是可以通的。
那如果我们把MPLS MTU修改成1525字节,就是少一个字节,还会不会通呢?
IOU2(config)#int e 0/2 IOU2(config-if)#mpls mtu override 1525 IOU2(config-if)# *Nov 9 06:54:16.004: %MFI-3-MPLS_MTU_SET: Setting mpls mtu to 1525 on Ethernet0/3 which is higher than the interface mtu 1500. This could lead to packet forwarding problems including packet drops. IOU3(config)#int r e 0/2-3 IOU3(config-if-range)#mpls mtu override 1525 IOU4(config)#int e 0/3 IOU4(config-if)#mpls mtu override 1525
显然,通不了。
IOU8#ping 200.1.1.9 size 1500 Type escape sequence to abort. Sending 5, 1500-byte ICMP Echos to 200.1.1.9, timeout is 2 seconds: ..... Success rate is 0 percent (0/5)
其他相关文章:
- 这是一篇姊妹篇:《【实验】关于 L2TPv3 L2VPN MTU 的实验》
本文完。如有疑问,欢迎在下方留言;如本文有什么错误,欢迎在下方留言指正,谢谢。
发表评论?