V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
87728854
V2EX  ›  宽带症候群

涉及两级路由的 IPv6 前缀下发(委派)问题求助

  •  
  •   87728854 · 2022-07-03 12:27:17 +08:00 · 3815 次点击
    这是一个创建于 909 天前的主题,其中的信息可能已经有所发展或是发生改变。
    1. 家用宽带,光猫桥接模式;
    2. 使用路由器( OPNsense ) PPPoE 拨号;
    3. WAN 口使用 DHCPv6 成功从运营商获取到 IPv6 地址,同时获取到一个 2001:aaaa:bbbb:7890::/60 的 IPv6 前缀;
    4. LAN 口也成功分配到 IPv6 地址 2001:aaaa:bbbb:7890:cccc:dddd:eeee:1/64;
    5. LAN 口接了一个下级路由;
    6. LAN 口开启 DHCPv6 服务,前缀委派范围 ::8 至 ::c, 长度 62, 为下级路由分配 2001:aaaa:aaaa:7894::/62 的前缀;
    7. 下级路由 WAN 口同样使用 DHCPv6 向上级路由 LAN 口获取 IPv6 地址和前缀;
    8. 下级路成功获取到 2001:aaaa:bbbb:780c::/62 这个前缀.

    请问下级路由获取到的前缀为什么不是 2001:aaaa:bbbb:789c::/62 ?

    26 条回复    2023-08-14 21:46:47 +08:00
    pcslide
        1
    pcslide  
       2022-07-03 13:25:06 +08:00
    2001:aaaa:bbbb:7890::/60 网下分配可以到 2001:aaaa:bbbb:780c::/62
    ????????????
    87728854
        2
    87728854  
    OP
       2022-07-03 13:35:28 +08:00
    是的,这就是奇怪的地方,理论上 789 是不应该变动的,由于指定了委派范围 ::8 至 ::C ,应该是 7898::/62 或 789C::/62 任意一个。
    87728854
        3
    87728854  
    OP
       2022-07-03 13:35:46 +08:00
    @pcslide 是的,这就是奇怪的地方,理论上 789 是不应该变动的,由于指定了委派范围 ::8 至 ::C ,应该是 7898::/62 或 789C::/62 任意一个。
    smallthing
        4
    smallthing  
       2022-07-03 13:59:17 +08:00
    1.你的一级路由有问题 分配的范围错了
    2.你运营商的 dhcpv6 有问题 然后你一级路由也有问题 穿透到二级
    raysonx
        5
    raysonx  
       2022-07-03 14:06:52 +08:00   ❤️ 4
    巧了,我以前折腾过 OPNSense 的 DHCPv6-PD 功能,也遇到过类似的问题,读过那部分代码,结论是代码里有 bug ,它直接硬编码了几个 prefix 的长度作的掩码运算,没有 honor 你的 /62.
    我当时手动 hack 了那部分代码解决的问题。
    时间太久了,我无法直接找到当时的修改了。修那个 bug 时让我觉得代码质量太差,后来直接换 VyOS 了。
    其实最新的 OpenWRT 也不错,特别是最新的 22.03 RC ,对 IPv6 的支持我觉得是普通用户能接触到的固件里面最好的了。
    raysonx
        6
    raysonx  
       2022-07-03 14:13:23 +08:00
    我印象中它的 IPv6 前缀运算那部分用的是字符串截取和拼接,而不是转为 long int 形式做数学运算。在从 WAN 口拿到 PD 前缀后截取一部分字符串,再拼上后缀。然后我记得它只处理了 /48 ,/56 等几种情况,对 /60 或者其他长度的前缀处理会出错。
    87728854
        7
    87728854  
    OP
       2022-07-03 14:50:48 +08:00
    @raysonx 我还以为我对 IPV6 前缀委派理解有问题,把 《 IPV6 技术精要》涉及的章节翻来覆去看了几遍。。。这个问题已经困扰我两周了。话说你是什么时候遇到的,这都 2022 年了还没修复,真是坑啊。。。
    raysonx
        8
    raysonx  
       2022-07-03 15:43:53 +08:00 via iPad
    @87728854 有两三年了吧,不知道你用的什么版本,如果不是最新版可以尝试一下最新版本看看修了没。我不确定能否找到当时的 patch 。
    87728854
        9
    87728854  
    OP
       2022-07-03 15:55:56 +08:00
    @raysonx 因为怀疑有 BUG ,我更新的最新版,我准备测试下 pfsense ,主要是比较喜欢 freebsd 。。。
    raysonx
        10
    raysonx  
       2022-07-03 16:19:12 +08:00
    pfSense 好像好多年不怎么维护了,netgate 把重点转向 TNSR 了,别抱太大指望。
    我找到当时 patch 的位置了,下面两行: https://github.com/opnsense/core/blob/98fe7a38813a78ab818d215bde530711d5676818/src/etc/inc/plugins.inc.d/dhcpd.inc#L1371
    https://github.com/opnsense/core/blob/98fe7a38813a78ab818d215bde530711d5676818/src/etc/inc/plugins.inc.d/dhcpd.inc#L1373

    可以看到对于前缀长度 60-64 的情况下,比如你举例的 2001:aaaa:bbbb:7890::/60 ,它直接截取了 7890 中的 78 ,然后拼接你指定的 08 (一直到 0C),得到 7808 至 780C 。

    一个简单的 hack 是把 substr($pd_prefix_from_array_out[3], 0, 2)改为 substr($pd_prefix_from_array_out[3], 0, 3),把 substr($pd_prefix_to_array_out[3], 0, 2)改为 substr($pd_prefix_to_array_out[3], 0, 3)。当然这只针对你的使用情况,换成其他长度的前缀或者两位数的范围会出错。
    raysonx
        11
    raysonx  
       2022-07-03 16:20:43 +08:00
    哦,还有去掉这两行,防止把“范围”扩展为两位数:

    $pd_prefix_from_array[2] = sprintf("%02s", $pd_prefix_from_array[2]);
    $pd_prefix_to_array[2] = sprintf("%02s", $pd_prefix_to_array[2]);
    87728854
        12
    87728854  
    OP
       2022-07-03 16:33:00 +08:00
    @raysonx 找到了,非常感谢!

    1412 switch ($pdval) {
    1413 // For PD sizes of /60 through /64, the user must do the math!
    1414 case 60:
    1415 case 62:
    1416 case 63:
    1417 case 64: // 3&4th bytes on 4th array
    1418 $pd_prefix_from_array_out[3] = sprintf("%04s", $ifcfgipv6arr[3]); // make it 4 bytes
    1419 $pd_prefix_from_array_out[3] = substr($pd_prefix_from_array_out[3], 0, 2) . $pd_prefix_from_array[2];
    1420 $pd_prefix_to_array_out[3] = sprintf("%04s", $ifcfgipv6arr[3]); // make it 4 bytes
    1421 $pd_prefix_to_array_out[3] = substr($pd_prefix_to_array_out[3], 0, 2) . $pd_prefix_to_array[2];
    1422 break;
    1423 case 56: // 1st&2nd bytes on 4th array
    1424 $pd_prefix_from_array[2] = str_pad($pd_prefix_from_array[2], 4, "0");
    1425 $pd_prefix_from_array_out[3] = sprintf("%s", $pd_prefix_from_array[2]); // make it 4 bytes
    1426 $pd_prefix_to_array[2] = str_pad($pd_prefix_to_array[2], 4, "0");
    1427 $pd_prefix_to_array_out[3] = sprintf("%s", $pd_prefix_to_array[2]); // make it 4 bytes
    1428 break;
    1429 case 52: // 1st byte on 4th array only, 0 to f, we only want one byte, but lookout for the user entering more
    1430 $len = strlen($pd_prefix_from_array[2]);
    1431 $pd_prefix_from_array[2] = substr($pd_prefix_from_array[2], $len - 1, 1);
    1432 $pd_prefix_from_array_out[3] = sprintf("%s000", substr($pd_prefix_from_array[2], 0, 1)); // first byte from entered value
    1433 $len = strlen($pd_prefix_to_array[2]);
    1434 $pd_prefix_to_array[2] = substr($pd_prefix_to_array[2], $len - 1, 1);
    1435 $pd_prefix_to_array_out[3] = sprintf("%s000", substr($pd_prefix_to_array[2], 0, 1));
    1436 break;
    1437 case 48: // 4th byte on 2nd array
    1438 $pd_prefix_from_array[2] = substr($pd_prefix_from_array[2], 0, 1);
    1439 $pd_prefix_from_array_out[1] = substr(sprintf("%03s", $ifcfgipv6arr[1]), 0, 3) . $pd_prefix_from_array[2]; // get 1st 3 byte + nibble
    1440 $pd_prefix_to_array[2] = substr($pd_prefix_to_array[2], 0, 1);
    1441 $pd_prefix_to_array_out[1] = substr(sprintf("%03s", $ifcfgipv6arr[1]), 0, 3) . $pd_prefix_to_array[2]; // get 1st 3 byte + nibble
    1442 break;
    1443 }
    87728854
        13
    87728854  
    OP
       2022-07-03 16:59:49 +08:00
    @raysonx
    我当前用的版本 22.1.9_1 ,修改 /usr/local/etc/inc/plugins.inc.d/dhcpd.inc 文件:
    注释掉 1399 和 1400 行。
    修改 1419 和 1421 行,经测试向下级路由委派到正确的前缀,再次感谢!
    cnbatch
        14
    cnbatch  
       2022-07-03 18:04:27 +08:00
    我给 opnsense 仓库提交了 issue ,接下来就看他们会不会处理
    https://github.com/opnsense/core/issues/5847
    gearfox
        15
    gearfox  
       2022-07-03 18:31:08 +08:00
    @cnbatch 你的 vyos 用的啥版本的?
    cnbatch
        16
    cnbatch  
       2022-07-03 18:51:47 +08:00
    @gearfox
    at 错人了,应该
    @raysonx
    raysonx
        17
    raysonx  
       2022-07-03 20:16:17 +08:00
    感谢,我加了一条回复,看有没有人修吧。
    我已不用 OPNsense 多年,自己是懒得修了(实在不想去写和调试 PHP 代码)。
    raysonx
        18
    raysonx  
       2022-07-03 22:12:51 +08:00
    @gearfox 1.3
    402159806
        19
    402159806  
       2022-07-04 08:51:45 +08:00
    我用光猫拨号 openwrt ipv6 中继 用起来很稳定
    gearfox
        20
    gearfox  
       2022-07-04 09:01:55 +08:00
    @cnbatch 哈哈哈 ,好
    gearfox
        21
    gearfox  
       2022-07-04 09:02:10 +08:00
    @raysonx 好的,谢谢
    acbot
        22
    acbot  
       2022-07-05 11:26:36 +08:00
    @raysonx “...最新的 OpenWRT 也不错...” 是的,OP 18.06 官方版本使用几年了 IPv6 都很正常, 不是需要新的软件版本完全都可以不升级
    raysonx
        23
    raysonx  
       2022-07-05 11:43:39 +08:00 via iPad
    @acbot 推荐最新版是因为 22.03 多了很多细化的设置,当然老版本对多数人也够用了
    cnbatch
        24
    cnbatch  
       2022-07-17 16:57:31 +08:00
    @raysonx 不好意思这回要特意 at 一下你,OPNSense 那边的人改完代码后正在征询意见:
    https://github.com/opnsense/core/issues/5847
    87728854
        25
    87728854  
    OP
       2023-08-14 21:41:59 +08:00
    最近升级新版本,发现已经彻底解决了这个问题,在不手动修改代码的情况下,前缀成功下发到下一级路由,下级路由也成功给每台电脑分配了期望的 IPV6 地址,可以成功访问互联网。不过有个新问题:下级电脑无法使用 IPv6 访问上级路由 LAN 口连接的电脑,防火墙全部放开也不行。

    比如:
    一级路由 WAN 口获取 IPV6 地址:240e:55e:304:f97b:62be:b4ff:fe03:a49a/64
    一级路由 WN 口同时从运营商获取到前缀:240e:55f:34f:f970::/60
    一级路由 LAN 口分配到 IPV6 地址:240e:55f:34f:f970:62be:b4ff:fe03:a49c/64
    一级路由 LAN 口使用 DHCPv6 继续向二级路由下发前缀,长度设定为 62 ,范围为:::8 至 ::c

    二级路由 WAN 口成功从一级路由获取到前缀 240e:55f:34f:f97c::/62
    二级路由 LAN 接口及连接的电脑分配到前缀为 240e:55f:34f:f97c::/64 的 IPV6 地址,可以正常访问互联网。

    问题:
    二级路由 LAN 口连接的所有电脑均无法访问一级路由 LAN 口下接入的 240e:55f:34f:f970::/64 这个段的电脑。
    87728854
        26
    87728854  
    OP
       2023-08-14 21:46:47 +08:00
    @87728854 补充一下,二级路由 WAN 口成功从一级路由获取到 IPv6 地址 240e:55f:34f:f970::61:a/128
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1708 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:39 · PVG 00:39 · LAX 08:39 · JFK 11:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.