Linux 上 IPv6 的 RFC4821 路径 MTU 发现

Linux 上 IPv6 的 RFC4821 路径 MTU 发现

我已通过 Hurricane Electric 在我的 Linux 计算机上配置了 IPv6-over-IPv4 隧道。虽然我可以 ping ipv6.google.com:

bash-4.4# ping ipv6.google.com
PING ipv6.google.com(lhr48s09-in-x0e.1e100.net (2a00:1450:4009:819::200e)) 56 data bytes
64 bytes from lhr48s09-in-x0e.1e100.net (2a00:1450:4009:819::200e): icmp_seq=1 ttl=57 time=10.9 ms
64 bytes from lhr48s09-in-x0e.1e100.net (2a00:1450:4009:819::200e): icmp_seq=2 ttl=57 time=10.7 ms

通过 IPv6 的 HTTPS 请求似乎超时:

bash-4.4# curl --happy-eyeballs-timeout-ms 60000 'https://mirrors.fedoraproject.org/metalink?repo=fedora-modular-29&arch=x86_64'
curl: (28) Operation timed out after 300258 milliseconds with 0 out of 0 bytes received

这是 MTU 问题的典型迹象,因此我怀疑是 MTU 问题,果然:

[user@nuc ~]$ tracepath6 mirrors.fedoraproject.org
 1?: [LOCALHOST]                        0.004ms pmtu 1480
 1:  xxxxxxxxxxxx-pt.tunnel.tserv1.lon2.ipv6.he.net        0.057ms pmtu 1472
 1:  xxxxxxxxxxxx.tunnel.tserv1.lon2.ipv6.he.net          22.524ms 
 2:  10ge3-20.core1.lon2.he.net                           20.266ms 
 3:  100ge7-1.core1.fra1.he.net                           32.051ms 
 4:  bb01.muc01.net.internetx.com                         47.579ms asymm  6 
 5:  no reply
 6:  no reply
 7:  no reply
 8:  no reply
 9:  no reply
10:  no reply
11:  no reply
12:  no reply
13:  no reply
14:  no reply
15:  no reply
16:  no reply
17:  no reply
18:  no reply
19:  no reply
20:  no reply
21:  no reply
22:  no reply
23:  no reply
24:  no reply
25:  no reply
26:  no reply
27:  no reply
28:  no reply
29:  no reply
30:  no reply
     Too many hops: pmtu 1472
     Resume: pmtu 1472 

我的连接的 MTU 设置得太高(1480 而不是 1472)。 (低于预期的 MTU 可能与我的 PC 和主路由器之间有 WiFi 连接有关。)

但是,此tracepath6命令无法查看完整路径,因此理论上,沿途仍然可能存在pmtu更低的路径。我发现 RFC4821 描述了一种即使在存在 ICMP 黑洞的情况下也能进行路径 MTU 发现的方法,我似乎在这里遇到了这种情况,但我还没有在 Linux 中找到用于 IPv6 的 RFC4821 的软件实现。对于 IPv4,可以在 sysctl 中设置net.ipv4.tcp_mtu_probing1,这将使内核通过探测透明地修复 MTU 问题。但我还没有找到任何类似的 Linux 的 IPv6 设置 - 或用户层软件。

那么如何在 Linux 上对 IPv6 进行 RFC4821 式路径 MTU 探测呢?

答案1

你可以试试:

$ sudo ping -6 -s <size> -M do <destination>

这将检查定义的段是否<size>能够到达目的地

例如:

$ sudo ping -6 -s 1452 -M do destination.com

请记住,IPv6 标头默认有 40 个字节或更多(如果存在选项),ICMP 标头有 8 个字节

这样命令中的 1452 意味着 1452 + 40 + 8 = 1500 字节

相关内容