解决 FTTR 升级后的 IPv6 适配:关于 OpenWrt RA 冲突与 SLAAC 机制的深度复盘 解决 FTTR 升级后的 IPv6 适配:关于 OpenWrt RA 冲突与 SLAAC 机制的深度复盘

解决 FTTR 升级后的 IPv6 适配:关于 OpenWrt RA 冲突与 SLAAC 机制的深度复盘

最近由于家里换了运营商的千兆 FTTR 融合套餐,网络拓扑发生了一些变化。原本作为主控核心的 OpenWrt 现在更多地是作为一个旁路网关接入,而所有的 IPv6 地址分发逻辑则回归到了光猫端。在使用过程中,我发现了一些很有意思的技术细节,特别是在 IPv6 的配置适配上,即便我们认为已经配置妥当,底层逻辑依然可能存在一些预期之外的表现。

局域网内的 DHCP 竞争

在刚切换到 FTTR 架构时,我发现局域网设备的 IPv6 访问并不稳定。排查后发现,由于 OpenWrt 默认的路由通告(RA)与主光猫发出的 RA 产生了广播冲突,导致局域网设备收到了两份不同的指令。

这实际上就是一种典型的局域网 DHCP 竞争。虽然理论上光猫是当前的层级拨号者,但处于同一二层网络下的 OpenWrt 如果不进行手动干预,它依然会执着地尝试建立自己的 IPv6 逻辑,从而引发路由表紊乱。

为何关闭网卡 DHCP 后,依旧无法触发 SLAAC?

这是我折腾过程中最深刻的一个发现。在大多数人的直觉中,只要在 Web UI 里勾选掉“请求地址”和“获取前缀”,OpenWrt 就会自动退回到纯粹的 SLAAC 客户端模式。

但经过实际测试,底层的协议逻辑并非如此:

  1. odhcp6c 的贪婪特性:当你的接口协议定义为 proto 'dhcpv6' 时,底层的客户端进程在启动时默认会处于一种“等待有状态反馈”的状态。
  2. 触发死锁:如果上级 FTTR 光猫被配置为纯无状态(SLAAC ONLY)分发,那么 OpenWrt 的 DHCPv6 客户端就会因为拿不到 Managed 标志的地址响应,而迟迟不肯去触发内核的 SLAAC 获取流程。
  3. 副作用:更严重的是,即便 OpenWrt 没拿到公网地址,它依然可能根据默认规则发出不完整的 RA,这进一步加剧了局域网内的 DHCP 竞争。

实现稳健的“客户端模式”配置

为了打破这种协议层面的死锁,我们必须显式地定义接口行为。通过修改 /etc/config/network,我们可以让 OpenWrt 真正安静下来,做一个纯净的 IPv6 获取者。

核心配置

Terminal window
config interface 'v6'
option proto 'dhcpv6'
option device 'eth0'
# ---------------------------------------------------------
# 强制修正协议行为,打破 SLAAC 触发死锁
# ---------------------------------------------------------
option reqaddress 'none' # 显式禁止 Address 请求,强制内核直接触发 SLAAC
option reqprefix 'no' # 显式禁止 PD 前缀请求,彻底放弃子网委派
option delegate '0' # 彻底禁止向下游委派,保持扁平化
option force_link '1'
# 彻底关闭接口的 RA 通告发射,消除竞争
option ra 'disabled'
option dhcpv6 'disabled'
option ra_management '0'

个人复盘总结

这次调优让我重新审视了那套看似自动化的协议逻辑。在 FTTR 这种特殊的网关环境下,我们需要从更底层的角度去修剪设备的路由器属性,而不是单纯依赖 UI 的复选框。

  • 耐心是前提:理解 option reqaddress 'none' 这样的细节,往往需要从多次抓包尝试中沉淀出来。
  • 关于环境兼容性:Android 对 DHCPv6 的缺失是已知的,因此在一个单一且安分的 SLAAC 环境下工作,是全家设备稳定上网的基础。

希望能给同样在调优网络环境的朋友们提供一些参考。修改完成后建议重启网络服务测试。

祝大家折腾愉快!


← Back to blog