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。

2012-8-23 更新:IOX中的端口MTU
– In IOS-XR this command is used to configure the L2 MTU.
– In IOS this command is used to configure the L3 payload size.

In other words in IOS-XR we include L2 headers as part of interface MTU command, which is not the case in IOS. This implies that in order to achieve the same MTU setting between IOS and IOS-XR, IOS-XR interface MTU has to be 14B (bytes) higher for Ethernet and 4B higher for POS interfaces compared to IOS setting.

IOS POS MTU = 4470
IOS-XR POS MTU = 4474

IOS Ethernet MTU = 1500
IOS-XR Ethernet MTU = 1514

So IOS Ethernet to IOS-XR Ethernet needs to have the following MTU
IOS(1500)——-(1514)IOS-XR

2013-11-30 更新:VPLS MTU Issue
如果客户不熟悉VPLS的网络,很可能会因为MTU设置问题,导致两边LAN的TCP流量过不去。同样的问题也发生在MPLS VPN的网络环境,就此不多解释。这里主要说明下VPLS数据平面的结构(注意:默认在ASR9k上,VPLS默认PW都是Type5):
Topology:

[CE-1——–ASR9k-1———7609———ASR9k-2———–CE-2]

在7609和ASR9k-1之间抓包,BGP auto-discovery/sig,AC没有配置任何rewrite命令
Assume CE can send 1500 ip packets, that mean it l2 mtu is 1504.
After arrived to asr9k-1, include 2 label, 1 l2 header and 1 vlan tag:
(1504+14)+8+14=1540
vpls-mtu-01
If config “rewrite ingress tag pop 1 symmetric”, you will not need carry vlan tag.
Assume CE can send 1500 ip packets, that mean it l2 mtu is 1504.
After arrived to asr9k-1, include 2 label and 1 l2 header:
(1500+14)+8+14=1536
vpls-mtu-02

2012-10-1 更新:TCP MSS
关于MSS,很早就遇到过,网上也有很多资料,我就不用费力气总结了,仅仅说一句:
对于MSS Feature,仅仅在2层MTU是默认的1500时才会起作用;如果2层MTU可以调更大,那么这个feature反而会降低效率。例如在GRE的环境,如果端口不能改变MTU,并且配置MSS,服务器只能发送1436的包[1436(Payload)+20(IP Header)+20(TCP Header)+24(GRE header)=1500],如果2层MTU可以改变,那么服务器会发送最大的1460的包,这样即使封装GRE,也可以通过。
另外对于tcp adjust-mss feature,只要整个路径上有一个端口配置了,那么双向都会生效,但网上有人测试得出以下总结:
在路由器接口上配置的tcp mss命令仅对出接口方向的syn报文和syn+ack报文有效,对于入接口方向的syn和syn+ack报文无效。详细看这里

可能上面的作者总结的是其他厂商的设备。下面是我在lab测试的结果
asr9k(12.2)—–(mss 500)7200(16.1)——(16.2)PC
1. 9k ftp to PC, PC server,在PC上抓包
发现9k发给server的syn mss仍然被改变了成500了,看tcp-mss.cap
2. PC ftp to 9k(9k已经换成pc), 9k server, 在pc上抓包
发现PC发送的syn的包是1260,这是始发的9k回的syn ack包已经变成是500,看tcp-mss-2

关于MSS的相关文章:
Adjusting IP MTU, TCP MSS, and PMTUD on Windows and Sun Systems
Resolve IP Fragmentation, MTU, MSS, and PMTUD Issues with GRE and IPSEC

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_1501
以下是ping失败返回的包,可以看到回来的是IP包不是MPLS包
ping_1501_fail

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
MPLS MTU Command Changes 12.2SR

注意:我这里只是拿了12.2SB和12.2SR这两个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也随之跟着更改,当交换DB报文时,由于MTU不对等,最终导致与上联P设备的OSPF邻居中断,关于OSPF DB报文中MTU的详细内容,可以看我的另一篇总结《CCIE SP-OSPF 小结》),加了一个新的命令“mpls mtu override”,可以使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)—>失败

anyShare分享到:
你可以留言,或者trackback 从你的网站

11 Responses to “MTU,MPLS MTU,IP MTU深入讨论”

  1. cheneytac说道:

    受益了,谢谢分享!

  2. wx说道:

    假如我的二层mtu不能更改,那么mpls mtu最高能生效的值是多少呢

  3. frank说道:

    二层mtu只是3层有效负载和包头,不包括2层包头和2.5层mpls包头,所以你的mpls mtu设多大都可以,但是你的有效负载只能1500,多出的那些mpls mtu只是给mpls label提供的。另外能否使mpls mtu大于2层mtu,这也取决IOS的版本。

  4. sjm说道:

    分析的非常好

  5. denk说道:

    你好 ,我有几个问题想和你讨论一下 , 你对2层mtu理解是只是3层有效负载和包头?那么ip mtu 是哪里呢? 和2层mtu范围一样? 这样说不通啊,比如vlan4字节算到2层帧头里,你去改大2层mtu 1504 还是没有包括这4字节啊 请回答 谢谢

  6. frank说道:

    1. 你仔细看下,“针对L2的MTU,他只是payload,是不加2层帧头”,payload包括除2层包头外所有的信息
    2. ip mtu是不包括3层的包头,只包括3层以上的payload,你可以看我的另一篇文章,文中有。
    3. 对于vlan的4byte(802.1q)是2层的payload,2层包头只包含原和目的mac address

  7. denk说道:

    朋友 我理解你的1,3 我也这么理解的 可是你说的2 我一直认为IP mtu是包括3层包头的
    刚做了个实验 纯一层mpls标签 ping size1500 抓包后,它分片 total lenth 是1492 是按照1492分片的 而 pingsize 1496 就已经不分片了 一层标签是4字节 我就不理解为什么不按照1496去分片呢 是不是设计的时候已经为2层mpls vpn 预留的4字节?

  8. frank说道:

    关于IP MTU的问题,你可以参考当有GRE的情况下,IP MTU会配置成1476,加上3层包头和4byte的GRE头,正好是24byte,加起来总共1500。
    关于你说的另一个问题,正常情况下应该不会出现吧,我没有注意过这个,也不好评价,有时间可以再确认下。

  9. blakegao说道:

    你说的2层mtu是ip的整个包大小是有问题的,mtu就是所在层面整个传输单元的大小,所以ip的mtu叫做三层mtu,而MPLS的mtu就是mpls帧的整个大小,mss是三层负载,第一次在tcp/ip协议卷一中tcp的路径发现mss中提到过,不包括包头,所以cisco的命令是ip mtu 和mpls mtu,如果二层的mtu你把它定义为是ip包的整个大小也就是2层有效负载,那么为什么mpls的mtu不去定义为mpls的有效负载,两者不会定义的不一致的。。个人认为。。

  10. frank说道:

    没明白你的疑问,mpls mtu就是定义mpls的大小,ip mtu就是定义ip的大小,2层是所有的大小。你直接把它想成2层的mtu是抽屉,抽屉里有个盒子是mpls mtu;盒子里放着一盒火柴,这盒火柴就是ip mtu。

留言哦