ipv6一致性测试(Path MTU Discovery for IPv6)内核修改

本文介绍了一种针对IPv6环境下MTU(最大传输单元)的测试方法及内核修改方案,确保在网络传输过程中能正确处理分片与PacketTooBig消息,避免不必要的网络问题。

推荐内核版本

linux-4.19.155
下载地址:https://download.youkuaiyun.com/download/superbfly/14521687

REFERENCE

RFC 8201 - Path MTU Discovery for IPv6

测试流程

TN2:测试设备
TR1:路由(我的理解,可能有偏差)
NUT:被测设备
在这里插入图片描述

  1. TN2发送1400字节长度的Echo Request到NUT
  2. TN2判断能否收到NUT回复的Echo Reply消息
  3. TR1发送Packet Too Big消息到NUT(MUT为56)
  4. TN2再次发送1400字节长度的Echo Request到NUT
  5. TN2判读能否收到NUT回复的Echo Reply消息(此时消息可能包含分片头)

判断标准

如果在第二步就失败,说明是网络问题。主要功能判断在第五步,这里的通过标准有两种,第一种是回复原始1400字节长度的Echo Replay,第二种是回复带分片头的Echo Replay。我们使用的是第一种方法。

解决方法

直接在NUT的内核中忽略第三步中TR1发送的Packet Too Big消息。

内核代码修改

修改文件:net/ipv6/icmp.c

static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                       u8 type, u8 code, int offset, __be32 info)
{
        /* icmpv6_notify checks 8 bytes can be pulled, icmp6hdr is 8 bytes */
        struct icmp6hdr *icmp6 = (struct icmp6hdr *) (skb->data + offset);
        struct net *net = dev_net(skb->dev);

        if (type == ICMPV6_PKT_TOOBIG)
        {
                // 这里加判断,只有Packet Too Big中mtu大于1280时,才更新mtu
                if( ntohl(info) >= 1280 )
                {
                        ip6_update_pmtu(skb, net, info, skb->dev->ifindex, 0, sock_net_uid(net, NULL));
                }
        }
        else if (type == NDISC_REDIRECT)
                ip6_redirect(skb, net, skb->dev->ifindex, 0,
                             sock_net_uid(net, NULL));

        if (!(type & ICMPV6_INFOMSG_MASK))
                if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
                        ping_err(skb, offset, ntohl(info));
}

通过ntohl(info) >= 1280这个判断,使得mtu小于1280的Packet Too Big不生效,达到回复1400字节内容的目的。

### Path MTU Discovery(PMTUD)的启用方法 Path MTU Discovery 是一种用于确定两个通信节点之间路径上最大传输单元(MTU)的机制,其核心原理是通过设置 IP 数据包的 DF(Don't Fragment)标志位,并在遇到无法容纳当前数据包大小的中间链路时,由路由器返回 ICMP "Destination Unreachable" 消息,指示需要分片但 DF 位被置位的情况。发送方据此逐步降低数据包大小,从而发现路径上的最小 MTU [^1]。 #### 在操作系统中启用 PMTUD ##### Windows 系统 Windows 系统默认启用了 PMTUD,无需额外配置。可以通过注册表项调整相关行为: - 注册表路径:`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters` - 相关键值: - `EnablePMTUDiscovery`:设为 `1` 表示启用 PMTUD(默认值) - `EnablePMTUBHDetect`:设为 `1` 表示启用黑洞路由器检测机制,用于应对某些不返回 ICMP 错误的网络设备 [^1] 修改后需重启系统或网络服务生效。 ##### Linux 系统 Linux 内核也默认启用了 PMTUD。可通过以下方式查看和修改: ```bash # 查看当前状态 sysctl net.ipv4.ip_no_pmtu_disc # 启用 PMTUD(设为0表示启用) sysctl -w net.ipv4.ip_no_pmtu_disc=0 # 永久生效(写入 /etc/sysctl.conf) echo "net.ipv4.ip_no_pmtu_disc = 0" >> /etc/sysctl.conf ``` 其中 `ip_no_pmtu_disc` 的取值含义如下: - `0`:启用 PMTUD(默认) - `1`:仅对本地子网禁用 PMTUD - `2`:始终禁用 PMTUD [^1] ##### Cisco 设备 在 Cisco IOS 设备上,PMTUD 默认也是启用的。可通过以下命令确认: ```bash show ip interface <interface> ``` 确保输出中包含 `DF bit set` 字样。若需显式启用: ```bash interface <interface> ip tcp adjust-mss <value> ``` 该命令会自动根据接口 MTU 调整 MSS 值,有助于避免因 PMTUD 失效导致的分片问题 [^3]。 #### 注意事项与优化建议 - **ICMP 过滤**:某些防火墙或安全策略可能丢弃 ICMP 消息,这将导致 PMTUD 失效,形成“黑洞”现象。建议在网络边界允许 ICMP Type 3 Code 4(Fragmentation Needed and DF Set)消息通过。 - **MSS 调整**:在 PPPoE、IPSec 等封装场景下,由于额外的头部开销,应适当调低 MSS 值以避免分片。例如标准以太网 MTU 为 1500,对应 MSS 为 1460;而在 PPPoE 环境中 MTU 通常为 1492,对应 MSS 为 1452 [^2]。 - **TCP Segmentation Offload**:现代网卡支持 TCP 分段卸载功能(如 TSO),可缓解因大包传输带来的性能问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高晓伟_Steven

相逢即是有缘,动力源于金钱。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值