關於MTU,這裏也許有你不知道的地方

MTU(Maximum Transmission Unit) 大小指的是一個以太幀(Ethernet Frame)能攜帶的最大數據部分(payload)的大小, 當MTU值設置爲9000 Bytes的時候也叫作巨型幀(Jumbo Frame):centos

以太幀(Ethernet Frame)
clipboard.png服務器

通常狀況下網卡的MTU大小是1500(最大可配置到9000),而後爲了在高性能的網絡環境下調數據的傳輸效率,能夠經過增長MTU只來實現,換句話說經過MTU的增長,每幀(Frame)傳輸的數據量就會更大。 這就比如用麪包車運輸對比用大貨車運輸的區別。網絡

然而要實現大MTU須要網絡裏的每一個設備都必須支持巨型幀,包括髮送主機,目標主機以及網絡中的路由器等。tcp

本文主要是記錄如何探測網絡中的MTU設置已經錯誤配置MTU帶來的影響。性能

爲了探測兩個不一樣實驗室的機器之間的網絡是否支持Jumbo Frame, 我從實驗室A的Centos主機(client) 發送ping命令到實驗室B的服務器(server), 首先檢查client的MTU配置:大數據

[root@centos ~]# ifconfig eno16777736
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

能夠看到默認的MTU值爲1500, 此時咱們發送一個大小爲100B的ICMP數據包到目標server.spa

[root@centos  ~]# ping -s 100 -c 1 10.245.194.61
PING 10.245.194.61 (10.245.194.61) 100(128) bytes of data.
108 bytes from 10.245.194.61: icmp_seq=1 ttl=50 time=23.0 ms

能夠看到小於MTU的數據包(128 = 100 + 20(ip header) + 8(icmp header))成功地發出並獲得服務器迴應, 接着咱們增大包的大小到2000,超過了1500的MTU值, 一樣數據ping成功ping發送並獲得迴應:code

[root@centos ~]# ping -s 2000 -c 1 10.245.194.61
PING 10.245.194.61 (10.245.194.61) 2000(2028) bytes of data.
2008 bytes from 10.245.194.61: icmp_seq=1 ttl=50 time=24.2 ms

或許這裏會有疑問,不是說最大隻能發送1500字節的包嗎? 爲什麼2000字節也能成功發出?爲了解答這個問題,咱們經過wireshark抓個包來看看怎麼回事server

[root@centos ~]# tcpdump -i eno16777736 -s 50 -w mtu_1500.pcap
[root@centos ~]# tshark -t ud -P -O icmp,ip -Y "ip.addr==10.245.194.61" -r mtu_1500.pcap000>>mtu_1500.txt

打開mtu_1500.txt,找到ICMP包:
icmp 幀
clipboard.pngblog

能夠看到,即便咱們指定的數據包大小是2000字節,可是IP層會根據當前MTU的設置對超過的ICMP數據進行分片(Fragmentation),以知足發送方的MTU設置要求。那麼接收方是如何斷定當前IP包是否被分片過?能夠經過More Fragments 標誌位(上圖93行)和Flags字段(上圖第90行)的值來判斷,, 當接收方的IP層收到最後一個切片後(More Fragments: Not set),就會組裝收到的全部切片包而後交給上層協議, 這裏咱們停下來想想,IP層如何保證切片重組的順序?其實很簡單,IP包裏有個Fragment offset屬性,接收方可根據此屬性的順序重組切片, 此列中,理論上應當只有兩個切片(1500 + 500 =2000), 因此接下來的一個Frame就是最後一個IP 切片:

第二個Fragment
clipboard.png

上圖第二個切邊也是最後一個,其IP包的大小爲548字節,也就是着總的數據傳輸量爲2048(1500+548)字節,其中1個icmp頭(8B), 2個ip頭(20B+20B)和icmp的數據部分(2000). 因此能夠看到,即使發送數據量超過了MTU的值,在IP層也會進行切片來適配所設置的MTU大小。
那麼將發送發的MTU設置爲9000字節啓用巨型幀的話,會出現什麼結果呢?

[root@centos ~]# ifconfig eno16777736 mtu 9000 up
[root@centos ~]# ifconfig eno16777736
eno16777736: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9000

設置好巨型幀之後,再來ping一個大數據包看看此次結果有什麼不同。

[root@centos ~]# ping -s 2000 -c 1 10.245.194.61
PING 10.245.194.61 (10.245.194.61) 2000(2028) bytes of data.

--- 10.245.194.61 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

額。。。 增大了MTU以後,反而ping不成功!這是怎麼回事??? 在看看網絡包:

ping with jumbo frame
clipboard.png

嗯,沒問題,MTU設置應該是成功的,此次IP層沒有分片,發送的數據也是2000字節,可是爲何服務器沒有迴應呢?

其實,這偏偏說明了此網絡是不支持巨型幀的,只有網絡裏有一個轉發節點的MTU值不是9000B而且發送方要求不分片(第170行, DF: Set)的狀況下,轉發節點會丟棄該報文。這也就是爲何會返回超時丟包的錯誤了。簡單來講,當一個轉發點收到一個IP報文之後,先檢查該報文的大小是否超過本身的MTU值,若是超過,再檢查是否設置了DF標誌(Don't Fragment), 若是設置,此報文將會被直接丟棄,若是沒有設置Don't Fragment,那麼該節點會對報文進行切片後再轉發到下一個路由節點。

相關文章
相關標籤/搜索