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

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

 

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


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

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

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

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

 

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

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

 

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

 

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

 

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

那什麼是MTU

 

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

wKioL1nYV4PABc7zAABmIoKz3jM718.jpg-wh_50

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

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

 

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

wKioL1nYVuKCuGvfAABiYnwEdXY250.png

 

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

 

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

lab@SRX01> 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,從“Protocol inet”可以看出,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 ***環境下,同樣因爲分片包原因,導致***吞吐量下降50%以上。

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

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

 

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

 

MTU分片包示例

 

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

lab@SRX01>ping 2.2.2.2 size 1500 source 1.1.1.1 count 2   

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

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

wKiom1nYV1DxL9jDAADpVebbsDc188.png

 

如上圖所示,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字節長度的貨物上又封裝了一個裝箱單。

wKioL1nYV2zzSkZNAAQxb2XkSDI752.png

數據包生產過程:

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

 

數據包傳輸過程:

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

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

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

 

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

 

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

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

如果值設置爲1,表示主機A不想讓數據包被其他路由器分片。反之如何值爲0,則允許分片。

 

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

wKiom1nYWDSi-Q1EAAL5as8nbUM976.png-wh_50

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

 

在這裏,我們假設始發地A允許分片。(DF=0)

分片本質上就是把數據包的負載(大卡車上的貨物+裝箱單)卸下後,根據鏈路限高來分割負載(貨物+裝箱單)並換成更小的數據包(麪包車)來運輸。但隨之而來的問題是:分割後的每一個數據包都需要一個新包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(更多分片)。

wKiom1nYWDXRXFHZAABa1ZigGCc420.png-wh_50

 

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

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

 

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

 

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

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

 

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

數據包對比如下:

wKioL1nYV-jyJevhAABahpAq8B4690.png-wh_50

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

wKiom1nYWDaQ4gHuAAAmG0qTWNg445.png-wh_50

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

 

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

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

如下圖:


wKioL1nbSqrTMGJ3AADF-Fr839U040.png

 

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

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

 

 

小結:

 

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

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

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

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

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

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

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

 

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章