談談MTU和ping的那些事

有段時間沒更新專欄文章了,前兩篇講ACL和四層碎片關係、BGP pre-bestpath cost community的技術文章有人說太過深奧,也有人說工作中不太會碰到,那今天就來一篇通俗易懂又兼具實用性的,對,就是MTU和ping。

MTU, (Maximum Transmission Unit 最大傳輸單元)是幹什麼用的大家都懂,想必各位也都知道可以用ping命令來測試網路設備MTU的大小來達到排錯的目的,所以關於MTU和ping的具體原理就不講了,今天主要講下不同廠商設備(Cisco和Juniper)對待MTU的不同「態度」以及在C家和J家的設備商上使用ping這個命令時的一些細微差異。

先來說說Juniper。J家的Junos是搭建在FreeBSD上的(更精確點說,Junos的控制平面就是FreeBSD的kernal)。FreeBSD和Windows一樣,用戶在用ping這個命令的時候,實際的ping包大小是不包含20 Byte的IP header和8 Byte的ICMP header的。也就是說操作系統會自動給你的ping包加上這28 Byte,然後再將你的ping包發出去。什麼意思呢? 我們來做個實驗:

在Windows上做三次ping,分別指定ping包大小為1500、1473和1472Byte, 三次ping均開啟df-bit。

Windows

X:>ping 192.168.1.1 -l 1500 -fnnPinging 192.168.1.1 with 1500 bytes of data:nPacket needs to be fragmented but DF set.nPacket needs to be fragmented but DF set.nPacket needs to be fragmented but DF set.nPacket needs to be fragmented but DF set.nPing statistics for 192.168.1.1:nPackets: Sent = 4, Received = 0, Lost = 4 (100% loss),nnX:>ping 192.168.1.1 -l 1473 -fnnPinging 192.168.1.1 with 1473 bytes of data:nPacket needs to be fragmented but DF set.nPacket needs to be fragmented but DF set.nPacket needs to be fragmented but DF set.nPacket needs to be fragmented but DF set.nPing statistics for 192.168.1.1:nPackets: Sent = 4, Received = 0, Lost = 4 (100% loss),nnX:>ping 192.168.1.1 -l 1472 -fnnPinging 192.168.1.1 with 1472 bytes of data:nReply from 192.168.1.1: bytes=1472 time=25ms TTL=255nReply from 192.168.1.1: bytes=1472 time=4ms TTL=255nReply from 192.168.1.1: bytes=1472 time=4ms TTL=255nReply from 192.168.1.1: bytes=1472 time=3ms TTL=255nPing statistics for 192.168.1.1:nPackets: Sent = 4, Received = 4, Lost = 0 (0% loss),nApproximate round trip times in milli-seconds:nMinimum = 3ms, Maximum = 25ms, Average = 9msn

為什麼ping包大小為1500,1473 Byte的時候ping不通呢?原理前面提到了,這是因為Windows「偷偷」地給你的ping包加上了28 Byte。所以你前兩次ping包的實際大小為1528和1501 Byte,已經超出了默認的MTU (1500), 並且因為開啟了df-bit,導致ping包無法被分片而被丟棄。而第三次當你指定ping包為1472的時候,加上windows給你的加上的28 Byte, 你的實際PING包大小剛好等於1500 byte,所以ping 通了。

同樣的原理也適用於Junos:

JUNOS

root@Junos# run ping 10.10.1.2 size 1500 do-not-fragment rapidnPING 10.10.1.2 (10.10.1.2): 1500 data bytesnping: sendto: Message too longn.ping: sendto: Message too longn.ping: sendto: Message too longn.ping: sendto: Message too longn.ping: sendto: Message too longn.n— 10.10.1.2 ping statistics —n5 packets transmitted, 0 packets received, 100% packet lossnnroot@Junos# run ping 10.10.1.2 size 1473 do-not-fragment rapidnPING 10.10.1.2 (10.10.1.2): 1473 data bytesnping: sendto: Message too longn.ping: sendto: Message too longn.ping: sendto: Message too longn.ping: sendto: Message too longn.ping: sendto: Message too longn.n— 10.10.1.2 ping statistics —n5 packets transmitted, 0 packets received, 100% packet lossnnroot@Junos# run ping 10.10.1.2 size 1472 do-not-fragmentrapidnPING 10.10.1.2 (10.10.1.2): 1472 data bytesn!!!!!n— 10.10.1.2 ping statistics —n5 packets transmitted, 5 packets received, 0% packet lossnround-trip min/avg/max/stddev = 0.861/0.908/1.065/0.079 msn

但是思科不一樣,不論是C家的IOS還是IOS-XR,用戶所指定ping包的大小已經包含了那個多出來的28byte (20 byte的IP header,8 byte 的ICMP header),也就是說在C家的設備上的ping才是包含了各種header的完整的ping。

下面分別在C家的IOS和IOS-XR來做測試,測試結果證明了這點。

IOS

Router#ping 10.10.1.1 size 1500 df-bitnType escape sequence to abort.nSending 5, 1500-byte ICMP Echos to 10.10.1.1, timeout is 2 seconds:nPacket sent with the DF bit setn!!!!!nSuccess rate is 100 percent (5/5), round-trip min/avg/max = 1/1/4 msnnRouter#ping 10.10.1.1 size 1501 df-bitnType escape sequence to abort.nSending 5, 1501-byte ICMP Echos to 10.10.1.1, timeout is 2 seconds:nPacket sent with the DF bit setn…..nSuccess rate is 0 percent (0/5)n

IOS XR

RP/0/RP0/CPU0:P2#ping 20.20.20.1 size 1500 donnotfragnSun Feb 7 07:13:57.440 UTCnType escape sequence to abort.nSending 5, 1500-byte ICMP Echos to 20.20.20.1, timeout is 2 seconds:n!!!!!nSuccess rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 msnnRP/0/RP0/CPU0:P2#ping 20.20.20.1 size 1501 donnotfragnSun Feb 7 07:14:09.290 UTCnType escape sequence to abort.nSending 5, 1501-byte ICMP Echos to 20.20.20.1, timeout is 2 seconds:nM.M.MnSuccess rate is 0 percent (0/5)n

前面講到的是3層的ping包,在2層環境中,數據包還會被封裝上一個14byte的Ethernet Header,因為這個14byte,導致埠MTU在C家和J家的設別上又有十分微妙的不同。

運行IOS的C家設備的埠MTU是不包括這個14byte的,但是IOS-XR和JUNOS卻又相反,啥意思呢?還是舉例來看吧:

Cisco IOS

router#sh ip interface g0/1 | i MTU

MTU is 1500 bytes

Cisco IOS XR

RP/0/RP0/CPU0:router#sh ip interface g0/1/0/1 | i MTU

MTU is 1514 (1500 is available to IP)

JUNOS

root@router# run show interfaces ge-0/0/1 | match MTU

Link-level type: Ethernet, MTU: 1514, Speed: 1000mbps, BPDU Error: None,MAC-REWRITE Error: None, Loopback: Disabled,

Protocol inet, MTU: 1500

Protocol iso, MTU: 1497

Protocol mpls, MTU: 1488

Protocol multiservice, MTU: Unlimited

另外一點,在你手動改變埠MTU大小的時候,IOS, IOS-XR, JUNOS之間也有很大的差異。舉個例子,在使用dot1q的環境下,dot1q會給包額外加入一個4byte的VLAN tag,加上之前提到的2層封裝的14byte,這樣MTU變成了1518byte,在對待這個4byte的tag時,IOS和JUNOS不會理會它,你必須手添加這4個byte,而IOS-XR則不需要。

啥意思呢?也就是說在使用dot1q的環境中,如果你現在在IOS或者JUNOS設備上手動把埠MTU從1500改成1514,IOS和JUNOS會繼續使用1514,不做任何改變。而IOS-XR不同,IOS-XR會主動為子埠(什麼?為啥是子埠?你忘了啥叫「獨臂路由」了嗎)加上4byte,將子埠的MTU變成1518byte (主埠的MTU依然是1514byte)。

Cisco IOS

router#sh interfaces g0/1 | i MTU

MTU 1514 bytes, BW 100000 Kbit, DLY 100 usec,

router#sh ip interface g0/1.1 | i MTU

MTU is 1514 bytes

JUNOS

root@router# run show interfaces ge-0/0/1 | match MTU

Link-level type: Ethernet, MTU: 1514, Speed: 1000mbps, BPDU Error: None,MAC-REWRITE Error: None, Loopback: Disabled,

Protocol inet, MTU: 1500

Protocol iso, MTU: 1497

Protocol mpls, MTU: 1488

Protocol multiservice, MTU: Unlimited

Cisco IOS XR

RP/0/RP0/CPU0:router#sh ip int g0/1/0/9 | i MTU

Wed Oct 6 21:35:07.274 CLT

MTU is 1514 (1500 is available to IP)

RP/0/RP0/CPU0:router#sh ip int g0/1/0/9.1 | i MTU

Wed Oct 6 21:35:11.972 CLT

MTU is 1518 (1500 is available to IP) --------- 看到變化了嗎?

不要小看這些細小的差距,細微之處見真功夫,任何涉及到MTU的網路問題都不簡單,與大家共勉。


推薦閱讀:

【乾貨】公司的網路規劃(二)
谷歌的BGP可以讓日本800萬網民斷網一小時,中國網民卻笑了
路由基礎(三)靜態現網用法
網路工程師的HCNP數通認證要具備哪些專業能力?
網路工程師已經淪為IT從業人員最底層打工者了么?

TAG:网络工程师 | 计算机网络工程专业 | 网络工程 |