XG-140G-TF 光猫启用 IPv6 PD 前缀分发
家里的电信光猫使用路由模式,由光猫完成 PPPoE 拨号,下游再连接自己的路由器。这样的配置方式 IPv4 使用起来没什么问题,IPv6 也可以拿到地址,但是实际使用时却发现了一个问题:光猫已经从电信获得了一个/60 IPv6 前缀,直连光猫的设备也有 IPv6,但下游 OpenWrt 只能在 WAN 口获得一个/64地址,LAN 侧始终没有公网 IPv6 前缀。换句话说,光猫默认没有启用下游 IPv6 PD 前缀分发。这对于 Tailscale 之类需要打洞的场景不友好:OpenWrt 的 LAN 侧只能使用 ULA、NAT66 或 IPv6 Relay,也失去了利用原生 IPv6 进行 Tailscale 直连的条件。
把光猫改成桥接、由主路由拨号当然可以解决 IPv6 前缀分配问题,但 XG-140G-TF 本身的转发性能足够,而主路由是软路由,PPPoE 本身也非常吃单核性能,所以我还是希望保留光猫拨号。进一步检查后发现,XG-140G-TF 的固件中其实包含下游 DHCPv6-PD Server,只是电信配置默认没有开启对应的产品级开关。
本文记录如何在保留光猫拨号的情况下,开启 XG-140G-TF 的 IPv6 PD 前缀分发。光猫的管理员登录、Telnet 开启和 root 密码获取方法,请先参考配置 XG-140G-TF 光猫。
问题现象
光猫的 IPv6 状态显示,WAN 连接已经通过 Prefix Delegation 从电信取得了/60前缀,例如:1
2001:db8:1234:690::/60
一个/60可以划分为 16 个/64子网。在这个例子中,范围是:1
2
3
42001:db8:1234:690::/64
2001:db8:1234:691::/64
……
2001:db8:1234:69f::/64
光猫使用第一个690::/64作为自己的 LAN 网段,通过 RA 广播给直连设备。但在修改前,下游 OpenWrt 的 WAN6 状态只有一个地址:1
2001:db8:1234:690:6c59:4eff:fecb:61f4/64
容易产生误解的是,这只是 OpenWrt WAN 接口通过 SLAAC 获得的一个 IPv6 地址,并不是可供 OpenWrt 继续划分给 LAN 的前缀。检查 WAN6 状态时可以看到:1
"ipv6-prefix": []
由于没有获得 IA_PD,OpenWrt 的 LAN 只能继续使用 ULA 地址,日志中还会出现:1
A default route is present but there is no public prefix on lan
Web 界面的 DHCPv6 设置不是 PD Server
XG-140G-TF 的「IPv6 LAN 侧主机设置」页面中有「启用 DHCPv6 服务器」「前缀来源」和 RA 标志等选项。这些选项负责向普通 LAN 终端提供地址、DNS 信息,以及把光猫使用的一个/64通过 RA 广播出去。
它们并不负责响应下游路由器的 IA_PD 请求。即使勾选「启用 DHCPv6 服务器」,下游路由器也可能只获得 WAN 地址,而没有IPv6-PD。真正的下游 PD Server 在数据模型中是另一个对象:1
InternetGatewayDevice.LANDevice.1.X_CMCC_DHCPv6PDServer
固件中的该对象默认已经是Enable=True,但还有一个产品级总开关默认关闭:1
InternetGatewayDevice.X_ASB_COM_PreConfig.X_ASB_COM_WANPreConfig.X_ASB_COM_DHCPv6PDServerEnable
开启下游 PD Server
修改前建议先备份光猫配置,并确认光猫从运营商获得的前缀短于/64,例如/60或/56。如果运营商只分配一个/64,就没有额外的标准/64子网可以继续委派。
首先 Telnet 登录光猫并取得 root 权限,然后执行:1
cfgcli -s InternetGatewayDevice.X_ASB_COM_PreConfig.X_ASB_COM_WANPreConfig.X_ASB_COM_DHCPv6PDServerEnable True
命令应当返回类似结果:1
set InternetGatewayDevice.X_ASB_COM_PreConfig.X_ASB_COM_WANPreConfig.X_ASB_COM_DHCPv6PDServerEnable=True success!
这个参数位于PreConfig中,设置后不会立即热加载,需要普通重启光猫:1
reboot
这里只需要重启,不要恢复出厂设置。该参数会写入配置数据库,正常情况下重启后仍然保留。
让下游重新申请前缀
光猫重新联网并再次获得上游/60后,下游路由器还需要发起一轮新的 DHCPv6 Solicit。实际测试中,OpenWrt 保留了启用 PD Server 之前建立的 WAN6 会话,单纯等待或执行 Renew 仍然没有获得前缀。
确认 OpenWrt 的 WAN6 使用 DHCPv6 客户端并请求前缀:1
uci show network.wan6
典型配置如下:1
2
3network.wan6.proto='dhcpv6'
network.wan6.reqaddress='try'
network.wan6.reqprefix='auto'
然后完整重连 WAN6:1
2ifdown wan6
ifup wan6
其他品牌的下游路由器也应当启用 WAN 侧的「获取前缀」「Prefix Delegation」或「IA_PD」功能。如果没有单独的重连按钮,可以在光猫恢复联网后重启下游路由器。
验证结果
在 OpenWrt 中执行:1
ifstatus wan6
或者:1
ubus call network.interface.wan6 status
成功后,ipv6-prefix不再为空。我的实测结果是光猫把第二个/64委派给了 OpenWrt,并由 OpenWrt 自动分配给 LAN:1
2
3
4
5
6
7
8
9
10
11
12"ipv6-prefix": [
{
"address": "2001:db8:1234:691::",
"mask": 64,
"assigned": {
"lan": {
"address": "2001:db8:1234:691::",
"mask": 64
}
}
}
]
此时网络关系如下:1
2
3
4
5电信下发: 2001:db8:1234:690::/60
光猫LAN: 2001:db8:1234:690::/64
OpenWrt WAN: 690网段中的地址
OpenWrt IA_PD:2001:db8:1234:691::/64
OpenWrt LAN: 2001:db8:1234:691::1/64
下游获得的是公网 IPv6 地址,最终确保光猫和 OpenWrt 的 IPv6 防火墙保持开启即可。