1. 程式人生 > >踢走絆腳石,MTU解析與常見問題匯總-上篇

踢走絆腳石,MTU解析與常見問題匯總-上篇

mtu tcp-mss path mtu

金秋十月,在這國慶和中秋雙節之際,首先祝福大家雙節快樂。

今天讓我們來聊聊MTU的話題。


相信無論網工還是程序員,都會多多少少的碰到過由MTU引發的問題,也往往對MTU值的選擇和計算頭疼不已。

通常情況下,我們可以通過調整TCP-MSS值的大小,或者使用Path-MTUDiscovery 等技術來解決處理。

可在某些環境較為復雜的情況下,這些工具可能就不那麽好使了。

所以如果不徹底了解MTU的定義以及相關工具的工作原理。出現問題後排錯就顯得尤為困難了。

為了徹底搞懂MTU,我將用兩篇文章給大家介紹什麽是MTU以及相關工具的工作原理。

1. 第一篇文章主要內容為MTU的定義以及數據包分片技術細節。

2. 第二篇文章將要介紹如何自動發現最佳MTU值以及相關工具,以及在特定場景下MTU所產生的問題以及解決方法,例如IPSecVPN,或者不同網絡環境OSPFBGP對接等。

上篇:MTU的工作原理以及數據包分片細節

既然要討論MTU工作原理,那首先需要明確MTU的定義。

那什麽是MTU

相信大家都見過日常道路上的限高桿,其作用是限制道路上的車輛高度。在計算機網絡環境裏面,MTU就是鏈路上的限高桿,與現實世界的道路相似,在網絡世界裏面不同介質的鏈路也存在不同的MTU值。

技術分享

嚴格來說,雖說單個IP數據包最大長度可達65535字節。而在傳輸過程中,傳輸鏈路規定了單個數據包傳輸長度。當IP數據包長度超過此長度後,數據包將被切割為小於或等於鏈路規定長度的小IP包。

此規定長度就是MTU值,全名為:Maximum Transmission Unit 最大傳輸單元。

讓我們來看看一般情況下,各個介質下的MTU值。(單位:字節)

技術分享

上圖可以看出,不同鏈路存在不同的MTU值,以常見的以太網MTU值為例,其MTU值一般為1500字節。那這1500字節都包含了些什麽?

如下,以Juniper SRX接口輸出內容為例:

[email protected]> show interfaces ge-0/0/2

Physical interface: ge-0/0/2, Enabled, Physical link is Up

Interface index:136, SNMP ifIndex: 519

Link-level type:Ethernet, MTU:1514, Link-mode: Full-duplex, Speed: 1000mbps

<此處省略多余輸出>

Logical interfacege-0/0/2.0 (Index 72) (SNMP ifIndex 528)

<此處省略多余輸出>

Protocol inet, MTU:1500

Flags:Sendbcast-pkt-to-re

Addresses,Flags: Is-Preferred Is-Primary

Destination:1.1.1/24, Local: 1.1.1.1, Broadcast: 1.1.1.255

<此處省略多余輸出>

大家可以看到,上面提到了兩個MTU值,分別是1514 1500

先說說1514,從“Link-level type:Ethernet”可以看出,它是ISO模型第二層鏈路層的MTU值。1514字節包含了如下內容:

<二層以太網幀頭14字節> --<數據包負載1500字節:包含三層IP頭,四層或以上內容>

1500ISO模型第三層網絡層的MTU,從“Protocolinet”可以看出,1500字節包含了所有網絡層的數據,從IP包頭到傳輸層UDP/TCP包頭,甚至應用層的用戶數據。

<3IP20字節>--<數據包負載1480字節:包含四層或者以上內容>

小結,MTU值取決於兩個因素:

1. 不同鏈路介質存在不同MTU

2. 相同鏈路下,不同ISO層級也存在不同MTU值,原則上低層級的MTU值是大於高層級的MTU值,為包含關系。

在理解MTU的定義以後,可以看出其實MTU就是一個普普通通的鏈路數據包大小閾值,就其本身而言,它沒有任何定義上的錯誤,那為什麽江湖上還有這麽多關於MTU引起的紛爭呢?

原因在於互聯網世界中,不可能單存使用某一種介質的鏈路。

而就算在廣泛使用的Ethernet以太網中,也存在了使用不同技術從而導致MTU值不相同的例子,例如大家熟知的GRE隧道,IPsec隧道,PPPOE接口等虛擬邏輯接口等。

當數據包穿越不同MTU值的鏈路時,往往就會出現各種問題。就好比高速路換普通公路必然會引起擁堵一樣。MTU不匹配也會導致諸多問題。

MTU導致的問題

以下為常見的MTU不匹配導致的網絡問題:

1. 因為鏈路MTU不匹配問題導致網絡產生大量分片數據包,從而影響路由器包轉發效能。

2. IPsec VPN環境下,同樣因為分片包原因,導致VPN吞吐量下降50%以上。

3. 二層鏈路MTU值低於三層鏈路MTU值從而導致數據包被丟棄。

4. 某些路由協議因為MTU值不匹配原因導致協議建立不成功。

總的來說,絕大部分還是和數據包分片有關,因此這裏有必要花點篇幅來討論下數據包分片的細節。也為後續章節做準備。

MTU分片包示例

為了便於理解,先來看一個因為MTU值原因導致數據包傳輸過程中被分片的案例:

[email protected]>ping 2.2.2.2 size 1500 source 1.1.1.1 count 2

一臺名為SRX01的路由器ping了另外一臺路由器SRX02 兩次,每個ping數據包長度為1500字節。

中間鏈路抓包後,截圖如下:

技術分享

如上圖所示,IP1.1.1.1的主機pingIP2.2.2.2的主機兩次。但由於數據包本身長度1500字節,額外還要加上IPICMP包頭的長度,很明顯總長度超過了網絡層的MTU1500字節,導致數據包被分片。

繼續深入分析:

大家請註意,在數據包長度部分(Length),第一個數據包總長為1514字節,第二個數據包總長為62字節。那這長度是怎麽計算的?

在開始計算之前,再次強調ping 數據包長度為1500字節,不包含IP頭長度以及ICMP頭長度。

先看看第一個數據包的1514怎麽計算:

首先1514字節包含了二層鏈路幀頭,三層IP包頭,以及ICMP包頭,最後是ping 的數據等。

用一個等式可以輕松理解1514的計算方法:

1514字節=14字節以太網二層幀 + 20字節三層IP包頭 +8字節ICMP包頭+1472字節數據包。

那接下來剩下的62字節分片數據包怎麽計算?答案如下:

62字節= 14字節以太網二層幀 + 20字節三層IP包頭 + 剩余28字節數據包

(註:28字節=總長1500字節數據包已經傳輸的1472字節數據包)

數據包分片技術細節

咋看之下,IP數據包分片不就是數據包大於MTU就被切割傳輸了?

但是仔細想想,很多問題還沒有解釋清楚?

例如:

1. 誰決定了到底是否分片,中間鏈路的路由器還是收發端?

2. 數據包接收方怎麽知道這是不是分片包?

3. 因為時延的問題導致數據包到達順序不一致,接收方怎麽正確重組數據包?

4. 當有成千上萬個不同流量的分片數據包同時到達接收方,因為分片數據包只存在IP包頭+剩余數據,而缺少傳輸層包頭,那接收方怎麽甄別數據包屬於某個上層協議?

為了回答以上問題,我們需要詳細理解IP分片包的工作機制。

還是以Ping測試為例,本案中主機A向主機B Ping 4000字節數據包。網絡中間鏈路MTU為標準的1500字節。

借助一個形象化的比喻:我們可以把一個數據包比喻為一輛貨車,如下圖。主機A點發出了一個黃色大卡車,攜帶貨物為4000字節長度,大卡準備駛向主機B點。同時為了讓主機B點知曉貨物內容以及收貨人具體信息等,在這4000字節長度的貨物上又封裝了一個裝箱單。

技術分享

數據包生產過程:

主機A在產生數據包的時候會一次性把所有數據塞進一個完整的數據包(黃色大卡車),此數據包包含了二層幀頭,三層IP頭(黃色大卡車頭),ICMP頭(裝箱單),同時也包含了有效載荷4000字節(貨物)。

數據包傳輸過程:

當數據包通過途中某個鏈路時,三層網絡層鏈路MTU(道路限高)為1500字節。因為包大小4000字節大於1500字節,這個時候數據包面臨兩個選擇:分還是不分!

不分片,數據包就被無情被丟棄。

而分片就需要卸下負載(貨物),換成小數據包在傳輸(大卡車換小面包車)。

那你說到底誰決定是否允許分片?

問題1:誰決定了數據包是否分片,中間鏈路的路由器還是收發端?

答案:決定數據包是否需要分片取決於始發地的主機A,主機A會往IP數據包裏面寫入一個字段告訴其他路由器是否允許對此數據包進行分片操作。

例如下圖,此數據包就被始發地A標記:請不要分片!

技術分享

但是如設置了不想分片,那遇到鏈路MTU值比數據包小的情況下,數據包就會被中途的路由器丟棄。

在這裏,我們假設始發地A允許分片。

分片本質上就是把數據包的負載(大卡車上的貨物+裝箱單)卸下後,根據鏈路限高來分割負載(貨物+裝箱單)並換成更小的數據包(面包車)來運輸。但隨之而來的問題是:分割後的每一個數據包都需要一個新包IP包頭來運輸數據包(每一輛面包車的車頭),所以在計算整體數據包大小是否滿足鏈路MTU值的時候,新IP包頭大小也得計算在內,畢竟過限高桿的時候車頭大小也是需要考慮的。

在本例中,以網絡層1500字節MTU為標準,4000字節加上包頭的數據包被分為了三個小數據包,大小如下:

  • 第一個包:1514字節(包含14字節二層幀)

包內容:14字節以太網幀頭+20字節IP+8字節ICMP+1472字節負載

  • 第二個包:1514字節(包含14字節二層幀)

包內容:14字節以太網幀頭+20字節IP+1480字節

  • 第三個包:1082字節(包含14字節二層幀)

包內容:14字節以太網幀頭+20字節IP+1048字節

大家有沒有發現,只有第一個包存在ICMP包頭,後續的數據包不再封裝ICMP包頭。其實很簡單,借用我們的比喻,這ICMP包頭就是裝箱單,在貨物被切割的是,裝箱單就跟著第一個數據包走了,我們總不至於把裝箱單撕成碎片分別放到不同的小面包車上吧。

另外一個問題,因為分片是在途中發生,接收方的主機B完全不知情。本來主機B希望進門的是一個黃色大卡,結果來了幾輛小面包車,如果不說明清楚主機B肯定不接收貨物。那麽我們很有必要需要讓其知道,中間大卡因為超載被強制換成小面包車了。

問題2:數據包接收方怎麽知道這是不是分片包?

答案:當路由器在分片數據包的時候,會在IP包頭處放置另外一個標記:more fragment(更多分片)。

技術分享

除了分片最末尾的數據包外,其他所有分片數據包都存在此標記。

而末尾數據包之所以不存在此標記,則是因為它是最後一個,後續再也沒有分片數據包了。

同時,在分片過程中,除了標記“更多分片”讓主機B了解數據包被分片之外,我們還需要告知主機B數據包的分片順序。從而引出如下問題:

問題3:因為時延的問題導致數據包到達順序不一致,接收方怎麽正確重組數據包?

答案:當數據包被分片時,路由器會根據其IP包載荷計算每一個包的起始位置,稱作分片偏移量。接收端主機B會根據其偏移量來重組數據包。假如因為網絡延遲原因,分片最後一個包先於其他兩個數據包到達。通過偏移量,主機B會等待所有數據包到達以後,重組數據包。

本例中,第一個包的起始位置為0,所以其offset偏移量為0。而第二個包起始位置為第一個包的末端。本例為1480字節。以此類推,第三個數據包起始位置為第二個數據包的末端,為2960字節。(第一個1480+第二個1480=2960字節)

數據包對比如下:

技術分享

以上為第二個數據包的1480字節偏移量示例。

技術分享

上圖為三個分片數據包offset偏移量匯總,其結果與我們所分析的完全一致。

問題4:當有成千上萬個不同流量的分片數據包同時到達接收方,因為分片數據包只存在IP包頭+剩余數據,而缺少傳輸層包頭,那接收方怎麽知曉此數據包是否屬於某個上層協議?

答案:有了上面介紹的offset偏移量以後,當主機B接收到分片數據包,它會在根據另外一個參數最終確認所有的分片是否源自同一個源數據包,並完成重組。此參數為:Identification(數據包ID)。

如下圖:

技術分享

顧名思義,數據包ID類似於大家的身份證一樣,用來唯一標識某一個數據包。當數據包被分片後,同屬於某一個源數據包的所有分片包將會使用同一個ID號。當數據包到達目的地主機B以後,主機B可以通過識別ID的方式在成千上萬個不同數據包流中識別出相同源的數據包流,完成數據包重組。

在我們的示例中,當一個個的小面包車最後全部到達主機B以後。B站根據上面的信息把所有負載重組,並根據第一個小面包車的裝箱單(第一個數據包的icmp 包頭)把負載遞交給上層協議ICMP,從而完成整個傳輸過程。

小結:

本篇我們一起分析了MTU的定義,以及數據包在網絡鏈路中出現的分片原因以及計算方法等。

總的來說,由於MTU不匹配的原因,數據包會出現如下兩種情況,

  1. 1. 數據包不能被分片,從而被丟棄。

因為數據包被丟棄,某些協議無法工作正常。同時也會影響例如對丟包非常敏感的TCP協議性能。

  1. 2. 數據包被分片並傳輸到目的地。

雖然數據包最終被完整的傳輸到目的地。但在分片過程中,路由器不得不花費更多的硬件資源來處理並轉發數據包。一方面引入了數據包的延遲,同時也增加了路由器的數據包轉發量。

借用卡車的例子,在卡車卸貨並裝車過程中,大家很容易想到這會需要花費更多的人工處理時間,同時把原來一輛車能處理的負載變為多輛車同時處理,無形中增加了後續傳輸道路的汽車擁堵程度。

上篇就此結束,下篇中我將要帶領大家一起分析什麽是TCP-MSSPath-MTU Discovery。通過自動發現MTU值,從而盡可能避免數據包分片的發生。同時簡要分析三種MTU導致的常見問題,敬請期待。


本文出自 “新西蘭資深網工的日常” 博客,請務必保留此出處http://gingerbeer.blog.51cto.com/625855/1970602

踢走絆腳石,MTU解析與常見問題匯總-上篇