MTU,MPLS MTU,IP MTU深入讨论
关于MTU,我在之前的文章《MPLS Basic <2>》里介绍过,但不是很详细,现在总结下,并把新的理解写出来,跟大家探讨。
我做了3个实验来测试MTU的具体含义。详细看以下实验及总结:
环境:
1. MPLS环境,注意没有VPN,因此只有1层标签(适合1-3)。
2. R1和R3分别设有环回口,用于测试,普通的环回口及地址,没有特殊配置。
3. MPLS VPN环境,2层标签。(适合4,适合2010.7.16更新中的5,6两种情况)
1.默认mtu和mpls mtu
|MTU:1500 1500| |1500 1500| R1-+----------------------+-R2-+------------+-R3 |MPLS MTU:1500 1500| |1500 1500|
“ping 3.3.3.3 si 1500 df“ Fail
frame: 1500 + 4 = 1504 > (MTU or MPLS MTU)
2009-9-24 更新:
针对L2的MTU,他只是payload,是不加2层帧头(14Byte)和CRC(4Byte)的,另外不同的厂商对MTU的定义也是不同的,有的厂商是把帧头放入MTU中计算的,CISCO的是不计算帧头的。
Ethernet最大能支持1518就是这么来的,如果数据帧带着4Byte的vlan标示(802.1q),Ethernet(标准以太网)接收了此帧(1522),就会丢弃。这就是为什么标准以太网不支持trunk的原因,只要能使trunk的交换机,都会通过1522的帧,只不过这4个字节是算在2层帧头的,不算在payload里的!
另外,在计算吞吐量时,整个数据帧的大小不仅仅是MTU+L2帧头+CRC的大小,还要加上8Byte的前导符和12Byte的帧间隙。这样整个数据帧的实际大小 = MTU+L2+CRC+8Byte+12Byte吞吐量的计算可以参考我之前的文章《http://www.zhaocs.info/net_units_detail_explain.html》
2010-3-12 更新:
注意在普通PC上payload是不加3层包头的。
例如:
PC——-Router
在PC上ping x.x.x.x -l 1472 -f,发现这样是ok的,但是大于1472就不行了,原因就在于这里没有加18个字节的2层包头,20个字节的ip 3层包头,也没有加ICMP的8个字节。另外这里需要再强调下,交换机和路由器的设计是不一样的,所以mtu也有一定的区别。
在2层口上设置2层MTU完全要看硬件是否支持,也就是端口的buffer是否足够大。
在3层口上设置2层MTU就没有限制(也有最大值),具体算法没研究过。有兴趣的在三层交换机上设置3层或2层端口,然后改下mtu。
2.改变路由器的MPLS MTU为1504
|MTU:1500 1500| |1500 1500| R1-+----------------------+-R2-+------------+-R3 |MPLS MTU:1504 1504| |1504 1504|
“ping 3.3.3.3 si 1500 df“ Ok
frame: 1500 + 4 = 1504 MPLS MTU = 1504 > MTU
3.改变路由器 的MPLS MTU为1505
|MTU:1500 1500| |1500 1500| R1-+----------------------+-R2-+------------+-R3 |MPLS MTU:1505 1505| |1505 1505|
“ping 3.3.3.3 si 1501 df“ Fail
frame: 1501 + 4 = 1505 1505 > (MTU or MPLS MTU)

以下是ping失败返回的包,可以看到回来的是IP包不是MPLS包

4.改变路由器的MPLS MTU为1508,使用2层标签
|MTU:1500 1500| |1500 1500| R1-+----------------------+-R2-+------------+-R3 |MPLS MTU:1508 1508| |1508 1508|
“ping vrf test 33.33.33.33 si 1500 df “ OK
如果把R1的MPLS MTU改为1507,就会Fail。另外由于R2弹出标签,所以在R2上更改MPLS MTU没有意义,可以通过”show mpls for de”来查看MTU。
总结:
MTU = 3层及3层以上数据包的大小总和?
MPLS MTU = MTU + Label ?
例:如果是”ping 3.3.3.3 si 1500 df”,那么:
Layer 3 : ip(20byte) + icmp(1480byte) = 1500 byte
Layer2.5: mpls label = 1 lable = 4 byte
Layer 2 : mac(14byte)+ crc(4byte) = 18 byte
<-- 14 --> <-- 1504 -------------> <-- 4 --> +---------+-----------------------+--------+ | MAC | TAGs + Data (MTU) | CRC | +---------+-----------------------+--------+
那IP MTU是哪段呢?
经过查找及确认,发现从12.2(27)SBC, 12.2(33)SRA, 12.4(11)T, 12.2(33)SXH
以前的IOS是允许配置MPLS MTU > MTU,但这样可能会导致丢包、High cpu等问题。换句话说,出现上面第三种情况,也可以想象,如果是2个标签,就算mpls mtu到了1508,数据仍然是不能通过的并且被丢弃。
但为什么会出现第二种和第四种情况?
当端口收到数据时,他会查找相应的字段去匹配相应的数值,而不是完全根据OSI七层模型一层一层拆封装。
例如当端口收到2层以太网的信息,他会直接匹配2层MTU,收到2.5层的MPLS,他会直接匹配MPLS的MTU,他们没有先后(所以有第二种和第四种情况发生)!但由于传统的2层MTU包括IP包头及上层数据,所以只要IP数据小于1500就能通过,如果大于1500就出现第三种情况。关于Lable的大小就有MPLS MTU来评定。
但这样容易让客户误以为更改了MPLS MTU就解决了所有问题,并且只要用户有巨型帧(大于1500)通过该端口,就会被丢弃并导致其他问题。为了防止这种情况及更规范MPLS,所以CISCO在新的IOS里设置了限制:MPLS MTU只能小于并等于2层MTU。其实换个角度想想,MPLS是后来者,是硬插到2层和3层之间的,所以才会有这样的奇怪的问题出现。
同理,IP MTU也是一样要小于等于2层MTU!甚至在一些ME的交换机中,只能全局更改2层MTU,使其支持巨型帧,然后MPLS MTU及IP MTU自动更改并等于2层MTU。
以下是关于MPLS MTU命令的详细文档,不同IOS版本可能有些区别,但是大同小异:
MPLS MTU Command Changes 12.2SB
注意:我这里只是拿了12.2SB这个train来说明,根据不同的IOS可能会有不同的情况。
最后还是用之前的那句话概括:2层MTU就是盒子,只有盒子够大,MPLS 的MTU和3层MTU才能装下。
2010-07-16 更新:
在新的IOS上,除了以更改2层MTU来同时改变IP和MPLS的MTU外(其实在新建的网络里,建议直接更改2层MTU来使整网MTU达到统一;但是在现网中,往往不推荐。因为如果客户用的IGP是OSPF,你把PE的2层MTU改了,会导致3层的MTU也随之跟着更改,最终导致与上联P设备的OSPF邻居中断),加了一个新的命令,可以使MPLS MTU大于2层MTU,但在配置完后会提示告警信息:
%MFI-3-MPLS_MTU_SET: Setting mpls mtu to 1508 on Serial1/0 which is higher than the interface mtu 1500. This could lead to packet forwarding problems including packet drops.对于此文章提到的4种情况,我再加2种比较实际的情况:
5. 三个路由器互联,MPLS VPN环境
|MTU:1500 1500| |1500 1500| R1-+----------------------+-R2-+------------+-R3 |MPLS MTU:1508 1500| |1500 1508|“Ping vrf test 33.33.33.33 si 1496 df” Ok (1496+8=1504)
“Ping vrf test 33.33.33.33 si 1497 df” Fail(1497+8=1505)在R2对R1的互联端口抓包:
发现当发生1496的包时,能抓到1504,并正常转发。
发现当发生1497的包时,能抓到1505,并发送ICMP信息-需要分片转发。6. 四个路由器互联,MPLS VPN环境
|MTU:1500 1500| |1500 1500| |1500 1500| R1-+----------------------+-R2-+------------+-R3-+-------------+ |MPLS MTU:1508 1500| |1500 1500| |1500 1508|“Ping vrf test 33.33.33.33 si 1492 df” Ok (1492+8=1500)
“Ping vrf test 33.33.33.33 si 1493 df” Fail(1493+8=1501)在R2对R1的互联端口抓包:
发现当发生1492的包时,能抓到1500,并正常转发。
发现当发生1493的包时,能抓到1501,并发送ICMP信息-需要分片转发。结论:从上面两种情况得出,当数据包进来后会先处理MPLS标签,然后在确认MPLS的MTU,然后是2层MTU(也许就像我上面说的,根本就没有顺序)。如果遇到弹出,就先弹出,然后在一一确认。
如第一种情况:R1发的1504的数据包到达R2后,先收到(1504)—>弹出标签(1500)—>确认MPLS MTU(1500)—>通过
如第二种情况:R1发送1501的数据包到达R2后,先受到(1501)—>标签交换(1501)—>确认MPLS MTU(1500)—>失败
nice blog
受益了,谢谢分享!
假如我的二层mtu不能更改,那么mpls mtu最高能生效的值是多少呢
二层mtu只是3层有效负载和包头,不包括2层包头和2.5层mpls包头,所以你的mpls mtu设多大都可以,但是你的有效负载只能1500,多出的那些mpls mtu只是给mpls label提供的。另外能否使mpls mtu大于2层mtu,这也取决IOS的版本。
分析的非常好