macOS:
ping lvv.me -D -s 1464
Linux:
ping -4 lvv.me -M do -s 1464
Windows:
ping -4 lvv.me -f -l 1464
Linux 和 Windows 的 ping 的 -4
参数表示对 IPv4 地址进行测试,因为设置 Don't Fragment bit
仅在 IPv4 下支持。
如果数字设置过大 ping
就会失败,找到最大的可以 ping
的通的数字,最后加上 28
就是最佳的 MTU 了。
如果使用的是 1464
可以 ping
的通,调整到 1465
就失败了,就可以确定当前最佳的 MTU 应该配置为: 1492
(1464
+ 28
)。
Tips:不要在虚拟机中测试 MTU 的值,结果是不准确的。
MSS 和 MTU 的关系
IPv4: MSS
= MTU
- 40
, 40
= (20
IP header + 20
TCP header)
IPv6: MSS
= MTU
- 60
, 60
= (40
IP header + 20
TCP header)
参考资料:
TCP 最大报文段长度 MSS(Max Segment Size)是 TCP 协议里面定义的一个选项,表示可以被对端设备接收的最大 TCP 报文段的长度。通信双方在建立 TCP 连接时会协商出 MSS 值,以确定 TCP 报文段的最大数据长度。这样,当对端发送的 TCP 报文段的长度超过协商出来的 MSS,报文会进行分片处理。
注意事项
为了保证 TCP 报文不分片,配置过程中需要注意 MSS 与 MTU 的关系。最大传输单元 MTU(Maximum Transmission Unit)是用来标识 IP 报文是否分片的选项。如果对端发送的 IP 报文长度超过 MTU 值,则 IP 报文会进行分片处理。一般情况下,为了不影响报文传输,MSS 值加上报文开销(TCP 首部、IP 首部等)不超过 MTU 值。例如,一个 CAPWAP 封装的 TCP 报文构成为:IP 封装(20 字节)+ UDP 封装(8 字节)+ CAPWAP 封装(8 字节)+ ETH 封装(18 字节)+ IP 封装(20 字节)+ TCP 封装(20 字节)+ TCP 数据报文。设备上默认的 MTU 值为 1500 ,为了保证 CAPWAP 封装的 TCP 报文不分片,MSS 值的最大配置值为 1406,但 CAPWAP 首部或 TCP 首部均可能携带选项字段,推荐用户配置 MSS 值为 1380 字节。
Ref: tcp adjust-mss
Linux 中开启 PMTU 发现功能:
$ sudo vi /etc/sysctl.d/10-pmtu.conf
net.ipv4.ip_no_pmtu_disc = 0
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_base_mss = 1200
FreeBSD 中开启 PMTU 发现功能:
$ sudo vi /etc/sysctl.d/10-pmtu.conf
net.inet.tcp.path_mtu_discovery = 1
net.inet.tcp.pmtud_blackhole_detection = 1
net.inet.tcp.pmtud_blackhole_mss = 1200
相关资源
Linux 系统
可以使用 tracepath
命令跟踪 PMTU 发现功能:
sudo apt install iputils-tracepath
使用 tracepath
:
tracepath -n lvv.me
Windows 系统
有开源的小工具 mturoute
使用方法:
mturoute -t lvv.me