博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
网络协议——最大传输单元 MTU
阅读量:4148 次
发布时间:2019-05-25

本文共 4516 字,大约阅读时间需要 15 分钟。

MTU

Maximum Transmission Unit,最大传输单元,指的是数据链路层的最大payload,由硬件网卡设置MTU,是一个硬性限制

Q&A

  • 1500字节包含链路层的头部和尾部吗?——不包含。
  • MTU里包含802.1Q的头部VLAN tag吗?——包含。当网卡配置VLAN tag时,VLAN tag + Data <= MTU,有时VLAN tag不只有一个,可能是双标签,那这个VLAN tag就是8个字节。
  • 网络分片是在哪一层完成的?——网络层。网络层必须将发给网卡API的包 <= MTU。网络层如果发现链路层的MTU小于IP包的大小(网络层可以调用函数获取链路层信息),也并不会立刻开始分片,还需要看IP包的是否允许分片位DF(Don’t Fragment),如果允许分片,就会分成多个ID一样的IP包
  • 对于TCP包,如果MTU = 1500,那么tcp payload最大值是多少,才可以不用分片?——MTU(1500) = IPHeader(20) + TCPHeader(20) + Data,Data = 1500 -20 - 20 = 1100
  • 对于ICMP request/reply包,如果MTU = 1500,那么 payload最大值是多少,才可以不用分片?——MTU(1500) = IPHeader(20) + ICMPHeader(20) + Data,Data = 1500 -20 - 20 = 1100
  • 对于UDP包,如果MTU = 1500,那么udp payload最大值是多少,才可以不用分片?——MTU(1500) = IPHeader(20) + UDPHeader(8) + Data,Data = 1500 -20 - 8 = 1472
  • UDP如何分片?——网络层并不会在每个分片里复制一次UDP头,它是把完整的UDP包切开,加上IP头发送出去,除了第一个分片有UDP头,后面的分片都不包含UDP头。(ICMP也是)
  • 目的主机的网络层接收到多个UDP分片包后,网络层必须重组才能交给上层,为什么?——因为多个分片包只有第一个是有UDP头的,它可以根据UDP头里的端口号通知相应的应用取走,但是后面的分片包由于没有UDP头,传输层无法把分片包交给正确的应用程序。所以UDP分片包必须在网络层重组成一个完整的UDP包,交给传输层处理
  • 网络层根据什么重组呢?——分片的时候会分成多个ID一样的IP包
  • 如果某些分片包没有被目的主机的网络层接收到,造成UDP包重组失败,接收方会丢弃整个数据包,这是UDP不可靠传输的一个表现。而TCP发生组包错误时,该包会被重传,保证可靠传输
  • mtu 不一致会出现什么问题?

MTU 对 TCP 的影响

TCP 的一个数据报不可能无限大,还是受制于 MTU,TCP 单个数据报的最大消息长度,称为 MSS。

TCP 在建立连接的过程中,双方会进行 MSS 协商。最理想的情况下,MSS 的值正好是在 IP 不会被分片处理的最大长度(这个长度受限于数据链路层的 MTU)。双方在发送 SYN 的时候会在 TCP 的头部写入字节能支持的 MSS 值,然后双方得知对方的 MSS 值之后,选择较小的作为最终 MSS,MMS 的值就在 TCP 首部的 40 字节变长选项中(kind=2)。MTU 通过限制 MSS(单个数据报的最大消息长度) 的取值,来限制单个 TCP 包的长度

MTU 和 MSS 的关系

MSS: Maxitum Segment Size 最大分段大小,为 TCP 数据包每次传输的最大数据分段大小。

为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。

分片包长

我们在用Socket编程时,UDP协议要求包小于64K。TCP没有限定,TCP包头中就没有“包长度”字段,而完全依靠IP层去处理分帧。这就是为什么TCP常常被称作一种“流协议”的原因,开发者在使用TCP服务的时候,不必去关心数据包的大小,只需讲SOCKET看作一条数据流的入口,往里面放数据就是了,TCP协议本身会进行拥塞/流量控制。

UDP数据报的长度是指包括报头和数据部分在内的总字节数,其中报头长度固定,数据部分可变。数据报的最大长度根据操作环境的不同而各异。从理论上说,包含报头在内的数据报的最大长度为65535字节(64K)。

  • 不分片(MTU=1500)
    UDP 包的大小就应该是 1500 - IP头(20) - UDP头(8) = 1472(Bytes)
    TCP 包的大小就应该是 1500 - IP头(20) - TCP头(20) = 1460 (Bytes)
    ICMP (Ping) 包的大小就应该是 1500 - IP头(20) - ICMP头(8) = 1472(Bytes)
ping  10.164.16.54  -s 1472  # 不分片 (以太包长度 1514 = IP头(20)+ ICMP(1480=类型(1)+ 代码(1))+ 校验和(2)+标识符(2)+序号(2)+ 1472)20:44:13.538154 08:00:27:27:50:1c > 08:00:27:3b:d9:78, ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 35178, offset 0, flags [DF], proto ICMP (1), length 1500)    10.164.16.57 > 10.164.16.54: ICMP echo request, id 1419, seq 1, length 148020:44:13.538244 08:00:27:3b:d9:78 > 08:00:27:27:50:1c, ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 58010, offset 0, flags [none], proto ICMP (1), length 1500)    10.164.16.54 > 10.164.16.57: ICMP echo reply, id 1419, seq 1, length 1480
  • 分片(f r a g m e n t a t i o n)(MTU=1500)
ping  10.164.16.54  -s 1500#  icmp 的payload=1500 (两个包 : (第一个包:以太包长度1514,IP包长度1500,ICMP payload:1472) +,第二个包:以太包长度:62,IP包长:48,ICMP payload:28 )20:06:09.820790 08:00:27:27:50:1c > 08:00:27:3b:d9:78, ethertype IPv4 (0x0800), length 1514: (tos 0x0, ttl 64, id 38220, offset 0, flags [+], proto ICMP (1), length 1500)    10.164.16.57 > 10.164.16.54: ICMP echo request, id 16849, seq 4, length 148020:06:09.820809 08:00:27:27:50:1c > 08:00:27:3b:d9:78, ethertype IPv4 (0x0800), length 62: (tos 0x0, ttl 64, id 38220, offset 1480, flags [none], proto ICMP (1), length 48)    10.164.16.57 > 10.164.16.54: ip-proto-1

路径 MTU

  • 重要的不是两台主机所在网络的 M T U 的值,重要的是两台通信主机路径中的最小 MTU。它被称作路径 MTU
  • 两台主机之间的路径 MTU不一定是个常数。它取决于当时所选择的路由。而选路不一定是对称的(从A到B的路由可能与从B到A的路由不同),因此路径MTU在两个方向上不一定是一致的。
  • traceroute 程序也是用这个方法来确定到达目的节点的路径 MTU

路径 MTU 发现机制:

在这里插入图片描述

neutron 中的那些 mtu

/etc/neutron/neutron.conf:12:global_physnet_mtu = 1550/etc/neutron/plugins/ml2/ml2_conf.ini:11:path_mtu = 1550/etc/neutron/plugins/ml2/ml2_conf.ini:12:physical_network_mtus = physnet1:1500,physnet2:1500/etc/neutron/plugins/ml2/ml2_conf.ini:16:flat_networks = physnet1/etc/neutron/plugins/ml2/ml2_conf.ini:18:network_vlan_ranges = physnet1:100:1000,physnet2:100:1000
  • global_physnet_mtu ,底层物理网络的MTU。Neutron使用这个值来计算所有虚拟网络组件的MTU。对于flat网络和VLAN网络,neutron直接使用这个值而不作修改。对于VXLAN等overlay网络,neutron会自动从这个值中减去 overlay 协议的开销(比如 )。默认为1500,这是以太网的标准值。
    在这里插入图片描述
# Default network MTU value when not configuredDEFAULT_NETWORK_MTU = 1500
  • physical_network_mtus,物理网络与MTU值的映射列表。映射的格式是<physnet>: <mtu val>。这种映射允许指定与默认的 global_physnet_mtu 值不同的物理网络 MTU 值。
    在这里插入图片描述
    path_mtu,在使用 overlay/tunnel 协议时,可以穿越底层物理网络基础设施而不产生碎片的IP数据包的最大尺寸(MTU)。 这个选项允许指定一个与默认的global_physnet_mtu值不同的物理网络MTU值。(如果配置了该值,计算overlay/tunnel 类型的mtu时以此为准,若未配置,则使用global_physnet_mtu的值来计算overlay/tunnel 类型的网络的mtu)
    在这里插入图片描述

转载地址:http://tviti.baihongyu.com/

你可能感兴趣的文章
带WiringPi库的交叉笔译如何处理二之软链接概念
查看>>
db db2_monitorTool IBM Rational Performace Tester
查看>>
postgresql监控工具pgstatspack的安装及使用
查看>>
【JAVA数据结构】双向链表
查看>>
【JAVA数据结构】先进先出队列
查看>>
Objective-C 基础入门(一)
查看>>
Flutter Boost的router管理
查看>>
C++模板
查看>>
【C#】如何实现一个迭代器
查看>>
【C#】利用Conditional属性完成编译忽略
查看>>
VUe+webpack构建单页router应用(一)
查看>>
(python版)《剑指Offer》JZ01:二维数组中的查找
查看>>
Spring MVC中使用Thymeleaf模板引擎
查看>>
深入了解php底层机制
查看>>
PHP中的stdClass 【转】
查看>>
XHProf-php轻量级的性能分析工具
查看>>
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
就在昨天,全球 42 亿 IPv4 地址宣告耗尽!
查看>>
Mysql复制表以及复制数据库
查看>>
Linux分区方案
查看>>