金秋十月,在这国庆和中秋双节之际,首先祝福你们双节快乐。程序员
今天让咱们来聊聊MTU的话题。网络
相信不管网工仍是程序员,都会多多少少的碰到过由MTU引起的问题,也每每对MTU值的选择和计算头疼不已。ide
一般状况下,咱们能够经过调整TCP-MSS值的大小,或者使用Path-MTUDiscovery 等技术来解决处理。工具
可在某些环境较为复杂的状况下,这些工具可能就不那么好使了。性能
因此若是不完全了解MTU的定义以及相关工具的工做原理。出现问题后排错就显得尤其困难了。测试
为了完全搞懂MTU,我将用两篇文章给你们介绍什么是MTU以及相关工具的工做原理。spa
1. 第一篇文章主要内容为MTU的定义以及数据包分片技术细节。计算机网络
2. 第二篇文章将要介绍如何自动发现最佳MTU值以及相关工具,以及在特定场景下MTU所产生的问题以及解决方法,例如IPSec***,或者不一样网络环境OSPF,BGP对接等。3d
既然要讨论MTU工做原理,那首先须要明确MTU的定义。orm
相信你们都见过平常道路上的限高杆,其做用是限制道路上的车辆高度。在计算机网络环境里面,MTU就是链路上的限高杆,与现实世界的道路类似,在网络世界里面不一样介质的链路也存在不一样的MTU值。
严格来讲,虽然说单个IP数据包最大长度可达65535字节。而在传输过程当中,传输链路规定了单个数据包传输长度。当IP数据包长度超过此长度后,数据包将被切割为小于或等于链路规定长度的小IP包。
此规定长度就是MTU值,全名为:Maximum Transmission Unit 最大传输单元。
让咱们来看看通常状况下,各个介质下的MTU值。(单位:字节)
上图能够看出,不一样链路存在不一样的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头,四层或以上内容>
而1500为ISO模型第三层网络层的MTU,从“Protocol inet”能够看出,1500字节包含了全部网络层的数据,从IP包头到传输层UDP/TCP包头,甚至应用层的用户数据。
<3层IP头20字节>--<数据包负载1480字节:包含四层或者以上内容>
小结,MTU值取决于两个因素:
1. 不一样链路介质存在不一样MTU值
2. 相同链路下,不一样ISO层级也存在不一样MTU值,原则上低层级的MTU值是大于高层级的MTU值,为包含关系。
在理解MTU的定义之后,能够看出其实MTU就是一个普普统统的链路数据包大小阈值,就其自己而言,它没有任何定义上的错误,那为何江湖上还有这么多关于MTU引发的纷争呢?
缘由在于互联网世界中,不可能单存使用某一种介质的链路。
而就算在普遍使用的Ethernet以太网中,也存在了使用不一样技术从而致使MTU值不相同的例子,例如你们熟知的GRE隧道,IPsec隧道,PPPOE接口等虚拟逻辑接口等。
当数据包穿越不一样MTU值的链路时,每每就会出现各类问题。就比如高速路换普通公路必然会引发拥堵同样。MTU不匹配也会致使诸多问题。
如下为常见的MTU不匹配致使的网络问题:
1. 由于链路MTU不匹配问题致使网络产生大量分片数据包,从而影响路由器包转发效能。
2. 在IPsec ***环境下,一样由于分片包缘由,致使***吞吐量降低50%以上。
3. 二层链路MTU值低于三层链路MTU值从而致使数据包被丢弃。
4. 某些路由协议由于MTU值不匹配缘由致使协议创建不成功。
总的来讲,绝大部分仍是和数据包分片有关,所以这里有必要花点篇幅来讨论下数据包分片的细节。也为后续章节作准备。
为了便于理解,先来看一个由于MTU值缘由致使数据包传输过程当中被分片的案例:
lab@SRX01>ping 2.2.2.2 size 1500 source 1.1.1.1 count 2
一台名为SRX01的路由器ping了另一台路由器SRX02 两次,每一个ping数据包长度为1500字节。
中间链路抓包后,截图以下:
如上图所示,IP为1.1.1.1的主机ping了IP为2.2.2.2的主机两次。但因为数据包自己长度1500字节,额外还要加上IP和ICMP包头的长度,很明显总长度超过了网络层的MTU值1500字节,致使数据包被分片。
继续深刻分析:
你们请注意,在数据包长度部分(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字节,这个时候数据包面临两个选择:分仍是不分!
不分片,数据包就被无情被丢弃。
而分片就须要卸下负载(货物),换成小数据包在传输(大卡车换小面包车)。
那你说到底谁决定是否容许分片?
答案:决定数据包是否须要分片取决于始发地的主机A,主机A会往IP数据包里面写入一个叫作DF(don't-fragment)的字段告诉其余路由器是否容许对此数据包进行分片操做。
若是值设置为1,表示主机A不想让数据包被其余路由器分片。反之如何值为0,则容许分片。
例以下图,此数据包就被始发地A标记:请不要分片!
可是如设置了不想分片,那遇到链路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确定不接收货物。那么咱们颇有必要须要让其知道,中间大卡由于超载被强制换成小面包车了。
答案:当路由器在分片数据包的时候,会在IP包头处放置另一个标记:more fragment(更多分片)。
除了分片最末尾的数据包外,其余全部分片数据包都存在此标记。
而末尾数据包之因此不存在此标记,则是由于它是最后一个,后续再也没有分片数据包了。
同时,在分片过程当中,除了标记“更多分片”让主机B了解数据包被分片以外,咱们还须要告知主机B数据包的分片顺序。从而引出以下问题:
答案:当数据包被分片时,路由器会根据其IP包载荷计算每个包的起始位置,称做分片偏移量。接收端主机B会根据其偏移量来重组数据包。假如由于网络延迟缘由,分片最后一个包先于其余两个数据包到达。经过偏移量,主机B会等待全部数据包到达之后,重组数据包。
本例中,第一个包的起始位置为0,因此其offset偏移量为0。而第二个包起始位置为第一个包的末端。本例为1480字节。以此类推,第三个数据包起始位置为第二个数据包的末端,为2960字节。(第一个1480+第二个1480=2960字节)
数据包对好比下:
以上为第二个数据包的1480字节偏移量示例。
上图为三个分片数据包offset偏移量汇总,其结果与咱们所分析的彻底一致。
答案:有了上面介绍的offset偏移量之后,当主机B接收到分片数据包,它会在根据另一个参数最终确认全部的分片是否源自同一个源数据包,并完成重组。此参数为:Identification(数据包ID)。
以下图:
顾名思义,数据包ID相似于你们的×××同样,用来惟一标识某一个数据包。当数据包被分片后,同属于某一个源数据包的全部分片包将会使用同一个ID号。当数据包到达目的地主机B之后,主机B能够经过识别ID的方式在成千上万个不一样数据包流中识别出相同源的数据包流,完成数据包重组。
在咱们的示例中,当一个个的小面包车最后所有到达主机B之后。B站根据上面的信息把全部负载重组,并根据第一个小面包车的装箱单(第一个数据包的icmp 包头)把负载递交给上层协议ICMP,从而完成整个传输过程。
本篇咱们一块儿分析了MTU的定义,以及数据包在网络链路中出现的分片缘由以及计算方法等。
总的来讲,因为MTU不匹配的缘由,数据包会出现以下两种状况,
1. 数据包不能被分片,从而被丢弃。
由于数据包被丢弃,某些协议没法工做正常。同时也会影响例如对丢包很是敏感的TCP协议性能。
2. 数据包被分片并传输到目的地。
虽然数据包最终被完整的传输到目的地。但在分片过程当中,路由器不得不花费更多的硬件资源来处理并转发数据包。一方面引入了数据包的延迟,同时也增长了路由器的数据包转发量。
借用卡车的例子,在卡车卸货并装车过程当中,你们很容易想到这会须要花费更多的人工处理时间,同时把原来一辆车能处理的负载变为多辆车同时处理,无形中增长了后续传输道路的汽车拥堵程度。
上篇就此结束,下篇中我将要带领你们一块儿分析什么是TCP-MSS,Path-MTU Discovery。经过自动发现MTU值,从而尽量避免数据包分片的发生。同时简要分析三种MTU致使的常见问题,敬请期待。