Photoincat 2 IPv6 PPPoE:修订间差异

来自Photonicat Wiki
跳转到导航 跳转到搜索
C2h2留言 | 贡献
无编辑摘要
C2h2留言 | 贡献
Add one-shot setup script section (pcat2_pppoe_ipv6.sh, 中英双语) / automatic setup script
 
(未显示2个用户的10个中间版本)
第1行: 第1行:
== PPPoE 与 IPv6 配置指南 ==
{| class="wikitable"
|-
! 适用版本 / Applies to
| photonicatWrt '''26.04.1''' (r7720, OpenWrt 24+ base, fw4/nftables, odhcpd) — 更新于 2026-07 / Updated 2026-07
|-
! 旧版指南 / Older firmware
| 2023–2024 固件请参考本页面历史版本 / For 2023–2024 firmware see the page history
|}


=== WAN 接口设置 (/cgi-bin/luci/admin/network/network) WAN===
* 本文说明如何在 photonicat (photonicatWrt 26.04.x) 上配置基于 '''PPPoE 的原生 IPv6''',让内网设备通过 '''SLAAC / DHCPv6''' 获得公网 (GUA) 地址,全球直连、无需 NAT6。
# 进入 '''网络 → 接口 → WAN'''
* This document explains how to configure '''native IPv6 over PPPoE''' on photonicat (photonicatWrt 26.04.x), so LAN clients get global (GUA) addresses via '''SLAAC / DHCPv6''' — direct global connectivity, no NAT6 required.
# 在 IPv6 设置中:
## 获取 IPv6 地址 → '''手动''' (在 PPP 链路上启用 IPv6 协商)。
## 委托 IPv6 前缀 → '''启用'''


; 说明
== 一键配置脚本 / Automatic setup script ==
: WAN 是拨号接口,必须让 PPPoE 连接时顺便协商 IPv6 地址,并把上级分配的 IPv6 前缀传递下去,这样内网才能用到公网 IPv6。
无需手动执行下面的步骤,可以直接运行一键脚本自动完成全部配置(自动备份、应用、验证)。 / Instead of the manual steps below, you can run a one-shot script that applies all of them for you (backup, apply, verify).


=== WAN6 接口设置 (/cgi-bin/luci/admin/network/network) WAN6 ===
SSH 登录路由器后运行 / SSH into the router and run:
# 进入 '''网络 → 接口 → WAN6'''。
<pre>
# 设备选择 → '''pppoe-wan''' (原本默认为 eth0)。
cd /tmp
wget -O pcat2_pppoe_ipv6.sh https://gist.githubusercontent.com/c2h2/ae07a4c818457b4cf3f087bf164059f8/raw/pcat2_pppoe_ipv6.sh
sh pcat2_pppoe_ipv6.sh
</pre>


; 说明
* 脚本会先把当前配置备份到 <code>/tmp</code>,应用时 PPPoE 会短暂断线重连几秒,随后自动等待前缀下发并测试 IPv6 连通性。 / The script backs up your config to <code>/tmp</code> first, briefly restarts the PPPoE session, then waits for the delegated prefix and tests IPv6 connectivity.
: WAN6 不是单独的物理口,而是跟随 PPPoE 拨号逻辑口。把它绑到 pppoe-wan 才能正确收发 IPv6 数据。
* 可选参数 / Options: <code>--ra-high</code>(多路由/多 RA 环境,见下文第 3 节 / multi-router LANs, see section 3)、<code>--force</code>(非 PPPoE WAN / non-PPPoE WAN)、<code>--no-ping</code>(跳过连通性测试 / skip the connectivity test)。运行 / Run <code>sh pcat2_pppoe_ipv6.sh --help</code> 查看帮助。
* 脚本源码 / Script source: [https://gist.github.com/c2h2/ae07a4c818457b4cf3f087bf164059f8 GitHub Gist]。中国大陆用户如无法访问 gist,请按下文手动配置。 / If the gist is unreachable from mainland China, follow the manual steps below.


=== LAN 接口设置 (/cgi-bin/luci/admin/network/network) LAN ===
== 中文指南 ==
在 DHCPv6 相关配置中:
* RA 服务:'''服务器模式'''
* DHCPv6 服务:'''服务器模式'''
* NDP 代理:'''混合模式'''


; 说明
=== 1. WAN 接口(PPPoE) ===
: LAN 要作为 IPv6 地址分配的服务器,把前缀通过 RA 和 DHCPv6 分发给局域网设备。混合模式的 NDP 可以同时兼容静态地址和 DHCPv6 分配。
新版固件下 '''不需要手动创建绑定 eth0 的 WAN6 接口'''。只要 WAN 口开启 IPv6 协商,netifd 会自动在 PPPoE 逻辑口上创建动态别名接口 <code>wan_6</code>(注意是下划线),负责 DHCPv6 / 前缀委托。


=== 防火墙规则 (/cgi-bin/luci/admin/network/firewall/rules) ===
LuCI: '''网络 → 接口 WAN → 高级设置'''
为了保证 IPv6 入站访问正常,需要添加一条入站规则:
* 获取 IPv6 地址 → '''自动'''
# 进入 '''网络 → 防火墙 自定义规则'''
* 委托 IPv6 前缀 → '''启用'''
# 添加新规则:
* 名称:'''Allow-IPv6-Inbound'''
* 区域:'''wan'''
* 协议:'''IPv6'''
* 来源区域:'''wan'''
* 目标区域:'''device/lan'''
* 动作:'''ACCEPT'''
# 保存并应用。


; 说明
或使用 UCI:
: 默认防火墙会拦截来自外部的 IPv6 流量。添加这条规则是为了让 IPv6 入站流量能通过,保证公网可以访问到内网设备(如服务器或 NAS)。
<pre>
uci set network.wan.ipv6='auto'
uci commit network
ifup wan
</pre>


----
; 注意 如果系统里遗留了一个绑定 <code>eth0</code> 的 WAN6 接口(老指南的做法),它在 PPPoE 线路上会一直处于 pending 状态。建议直接禁用:
<pre>
uci set network.wan6.auto='0'
uci commit network
</pre>


=== 说明 ===
=== 2. LAN 接口 ===
* WAN 接口(pppoe-wan)负责拨号并启用 IPv6 协商。
LuCI: '''网络 → 接口 → LAN'''
* WAN6 接口绑定到 PPPoE 逻辑接口,而不是物理网口 eth0。
* IPv6 分配长度 (ip6assign) → '''60'''(运营商一般下发 /56 或 /60)
* LAN 接口通过 RA DHCPv6 向内网设备下发 IPv6 地址和前缀。
* '''IPv6 前缀过滤器 (ip6class) → 必须留空!'''
* 防火墙规则确保外部 IPv6 流量可以按需进入 LAN/设备。
 
<pre>
uci set network.lan.ip6assign='60'
uci -q delete network.lan.ip6class
uci commit network
ifup lan
</pre>
 
; ⚠ 最常见故障 如果 <code>ip6class</code> 被设为 <code>local</code>,LAN 只会分配 ULA(fd00::/8 私有前缀),运营商委托的公网前缀'''永远不会'''下发到 br-lan,内网设备就只有 fdxx 地址、无法访问 IPv6 互联网。删除该选项即可恢复。
 
=== 3. RA / DHCPv6(SLAAC) ===
LuCI: '''网络 → 接口 → LAN → DHCP 服务器 → IPv6 设置'''
* RA 服务:'''混合模式''' (SLAAC 默认开启,即 RA 前缀带 A 标志)
* DHCPv6 服务:'''混合模式'''
* NDP 代理:'''混合模式'''(旁路由/中继场景才需要)
 
<pre>
uci set dhcp.lan.ra='hybrid'
uci set dhcp.lan.dhcpv6='hybrid'
uci commit dhcp
/etc/init.d/odhcpd reload
</pre>
 
; 提示 若局域网内还有其它设备也在发 RA(多路由/多线路环境),把 photonicat 的路由优先级调高,客户端会优先选它作为默认网关:
<pre>
uci set dhcp.lan.ra_preference='high'
uci commit dhcp && /etc/init.d/odhcpd reload
</pre>
 
=== 4. Docker 与 IPv6 转发(26.04 版重要坑) ===
photonicatWrt 自带 Docker(27.x)。Docker 27+ 默认启用 ip6tables,会创建 <code>ip6 filter FORWARD</code> 链且'''策略为 drop''' —— 它会丢弃'''所有'''转发的 IPv6 流量,即使 fw4 防火墙已放行 lan→wan。症状:路由器本机 <code>ping6</code> 正常,内网设备拿到了公网 IPv6 却 ping 不通外网。
 
检查:
<pre>
nft list chain ip6 filter FORWARD
# 如果看到 policy drop 且计数一直增长,即中招
</pre>
 
永久修复:在 <code>/etc/docker/daemon.json</code> 的'''出厂内容基础上'''加一行 <code>"ip6tables": false</code>(不影响 IPv4 容器网络):
<pre>
cat > /etc/docker/daemon.json <<'EOF'
{
"data-root": "/opt/",
"log-level": "warn",
"ip6tables": false
}
EOF
/etc/init.d/docker restart
</pre>
; ⚠ 注意 photonicatWrt 实际由 <code>/etc/init.d/docker</code>(而非 dockerd)以 <code>--iptables=false</code> 参数启动 Docker。'''不要'''在 daemon.json 里添加 <code>"iptables"</code> 键,也不要改动出厂的 <code>data-root</code> —— 与启动参数冲突会导致 Docker 开机无法启动,改 data-root 会导致已有镜像"消失"。详见 [[Photonicat 2 Docker 使用指南]]。
 
=== 5. 防火墙 ===
fw4 默认已放行 lan→wan 的 IPv6 转发和必要的 ICMPv6,'''出站上网无需额外规则'''。只有当你需要'''从公网主动访问内网设备'''(自建服务器/NAS)时才添加入站规则,且建议按端口精确放行,不要整段 ACCEPT 全部入站 IPv6。
 
=== 6. 验证 ===
路由器上:
<pre>
ifstatus wan_6 | grep -A6 ipv6-prefix    # 应看到运营商委托的 /56 或 /60
ifstatus lan | grep -A8 ipv6-prefix-assignment  # 应看到公网前缀已分配给 br-lan
ping -6 -c3 photonicat.com
</pre>
内网设备上:
<pre>
ip -6 addr show  # 应有公网 (如 240e:/2408:/2409: 等) SLAAC 地址
ping -6 -c3 photonicat.com
</pre>
 
=== 7. 多出口/多 RA 环境排障 ===
如果局域网里有多台设备宣告 RA(例如另一台 5G 网关、Proxmox 虚拟机等),Linux 客户端会把多个默认网关做 ECMP 负载均衡,流量可能被分到没有 IPv6 上行的网关而'''间歇性丢包''';或者源地址选择与网关不匹配(photonicat 的默认路由是按源前缀限定的 <code>from 240e:xxxx::/56</code>),返回 "Destination unreachable: No route"。
 
* 首选:让没有上行的设备停止宣告默认路由(router lifetime 设为 0)。
* 客户端(systemd-networkd)也可固定网关并用地址标签固定源地址选择:
<pre>
# /etc/systemd/network/eth0.network.d/50-ipv6-gateway.conf
[IPv6AcceptRA]
UseGateway=false
 
[Route]
Gateway=fe80::xxxx:xxxx:xxxx:xxxx  # photonicat br-lan 的链路本地地址
 
[IPv6AddressLabel]
Label=99
Prefix=2409::/16    # 不希望选为源地址的运营商前缀
</pre>
 
== English Guide ==
 
=== 1. WAN interface (PPPoE) ===
On current firmware you '''no longer need a manual WAN6 interface bound to eth0'''. With IPv6 negotiation enabled on WAN, netifd automatically spawns a dynamic alias interface <code>wan_6</code> (with an underscore) on the PPPoE logical interface, which handles DHCPv6 and prefix delegation.
 
LuCI: '''Network → Interfaces → WAN → Advanced'''
* Obtain IPv6 address → '''Automatic'''
* Delegate IPv6 prefix → '''Enabled'''
 
Or via UCI:
<pre>
uci set network.wan.ipv6='auto'
uci commit network
ifup wan
</pre>
 
; Note If a legacy WAN6 interface bound to <code>eth0</code> exists (as older guides suggested), it will sit in "pending" forever on a PPPoE line. Disable it:
<pre>
uci set network.wan6.auto='0'
uci commit network
</pre>
 
=== 2. LAN interface ===
* IPv6 assignment length (ip6assign) → '''60''' (ISPs typically delegate a /56 or /60)
* '''IPv6 prefix filter (ip6class) → must be left EMPTY!'''
 
<pre>
uci set network.lan.ip6assign='60'
uci -q delete network.lan.ip6class
uci commit network
ifup lan
</pre>
 
; ⚠ Most common failure If <code>ip6class</code> is set to <code>local</code>, the LAN only gets ULA (fd00::/8) prefixes — the ISP-delegated global prefix is '''never''' assigned to br-lan, so clients only get fdxx addresses and cannot reach the IPv6 internet. Deleting this option fixes it.
 
=== 3. RA / DHCPv6 (SLAAC) ===
* RA-Service: '''hybrid''' (SLAAC is on by default — RA prefixes carry the A flag)
* DHCPv6-Service: '''hybrid'''
* NDP-Proxy: '''hybrid''' (only needed for relay/bridge setups)
 
<pre>
uci set dhcp.lan.ra='hybrid'
uci set dhcp.lan.dhcpv6='hybrid'
uci commit dhcp
/etc/init.d/odhcpd reload
</pre>
 
; Tip If other devices on the LAN also send RAs (multi-router / multi-uplink environments), raise the photonicat's router preference so clients prefer it as default gateway:
<pre>
uci set dhcp.lan.ra_preference='high'
uci commit dhcp && /etc/init.d/odhcpd reload
</pre>
 
=== 4. Docker vs IPv6 forwarding (important 26.04 pitfall) ===
photonicatWrt ships Docker (27.x). Docker 27+ enables ip6tables by default and creates an <code>ip6 filter FORWARD</code> chain with '''policy drop''' — it silently drops '''all''' forwarded IPv6, even though fw4 correctly allows lan→wan. Symptom: <code>ping6</code> works from the router itself, LAN clients get global IPv6 addresses but cannot reach the internet.
 
Check:
<pre>
nft list chain ip6 filter FORWARD
# if you see "policy drop" and a growing counter, this is your problem
</pre>
 
Permanent fix: add <code>"ip6tables": false</code> to <code>/etc/docker/daemon.json</code> '''while keeping the factory keys''' (IPv4 container networking is unaffected):
<pre>
cat > /etc/docker/daemon.json <<'EOF'
{
"data-root": "/opt/",
"log-level": "warn",
"ip6tables": false
}
EOF
/etc/init.d/docker restart
</pre>
; ⚠ Note On photonicatWrt, Docker is actually launched by <code>/etc/init.d/docker</code> (not dockerd) with <code>--iptables=false</code>. Do '''not''' add an <code>"iptables"</code> key to daemon.json and do not change the factory <code>data-root</code> — a flag/config conflict prevents Docker from starting at boot, and a changed data-root makes existing images "disappear". See [[Photonicat 2 Docker 使用指南]].
 
=== 5. Firewall ===
fw4 already allows IPv6 lan→wan forwarding and the required ICMPv6 by default — '''no extra rules are needed for outbound connectivity'''. Only add inbound rules when you need to reach LAN devices from the internet (self-hosted servers/NAS), and prefer precise per-port rules over a blanket ACCEPT of all inbound IPv6.
 
=== 6. Verification ===
On the router:
<pre>
ifstatus wan_6 | grep -A6 ipv6-prefix    # ISP-delegated /56 or /60 should appear
ifstatus lan | grep -A8 ipv6-prefix-assignment  # the global prefix should be assigned to br-lan
ping -6 -c3 photonicat.com
</pre>
On a LAN client:
<pre>
ip -6 addr show  # expect a global (e.g. 240e:/2408:/2409:) SLAAC address
ping -6 -c3 photonicat.com
</pre>
 
=== 7. Troubleshooting multi-uplink / multi-RA LANs ===
If several devices advertise RAs on the LAN (another 5G gateway, Proxmox VMs, …), Linux clients install an ECMP default route across all of them; flows hashed to a gateway without IPv6 upstream '''blackhole intermittently'''. Source-address selection can also mismatch the gateway (the photonicat's upstream default route is source-restricted, e.g. <code>from 240e:xxxx::/56</code>), yielding "Destination unreachable: No route".
 
* Preferred fix: make routers without upstream stop advertising a default route (router lifetime 0).
* On a systemd-networkd client you can pin the gateway and steer source selection:
<pre>
# /etc/systemd/network/eth0.network.d/50-ipv6-gateway.conf
[IPv6AcceptRA]
UseGateway=false
 
[Route]
Gateway=fe80::xxxx:xxxx:xxxx:xxxx  # photonicat br-lan link-local address
 
[IPv6AddressLabel]
Label=99
Prefix=2409::/16    # ISP prefix you do NOT want chosen as source
</pre>
 
== IPv6 地址说明 / Understanding the addresses ==
一个接口同时拥有多个 IPv6 地址是正常现象 / Multiple IPv6 addresses on one interface is normal:
* <code>240e:xxxx:xxxx:xx00:xxxx:xxff:fexx:xxxx/64</code> → 公网地址,SLAAC 由 RA 前缀+接口标识自动生成 / global address, auto-generated via SLAAC
* <code>240e:xxxx:xxxx:xx00::2e9/128</code> → DHCPv6 下发的公网地址 / global address assigned by stateful DHCPv6
* <code>fdxx:....../64</code> → ULA 私有地址,仅内网使用,不上公网 / ULA private address, LAN-only
* <code>fe80::/64</code> → 链路本地地址,用于邻居发现/网关 / link-local, used for NDP and as gateway
只有 global (GUA) 地址可用于公网通信;“全球直连”意味着设备在公网可见,请合理配置防火墙。 / Only GUA addresses reach the internet; being globally reachable means you should keep the firewall sensible.

2026年7月13日 (一) 10:01的最新版本

适用版本 / Applies to photonicatWrt 26.04.1 (r7720, OpenWrt 24+ base, fw4/nftables, odhcpd) — 更新于 2026-07 / Updated 2026-07
旧版指南 / Older firmware 2023–2024 固件请参考本页面历史版本 / For 2023–2024 firmware see the page history
  • 本文说明如何在 photonicat (photonicatWrt 26.04.x) 上配置基于 PPPoE 的原生 IPv6,让内网设备通过 SLAAC / DHCPv6 获得公网 (GUA) 地址,全球直连、无需 NAT6。
  • This document explains how to configure native IPv6 over PPPoE on photonicat (photonicatWrt 26.04.x), so LAN clients get global (GUA) addresses via SLAAC / DHCPv6 — direct global connectivity, no NAT6 required.

一键配置脚本 / Automatic setup script

无需手动执行下面的步骤,可以直接运行一键脚本自动完成全部配置(自动备份、应用、验证)。 / Instead of the manual steps below, you can run a one-shot script that applies all of them for you (backup, apply, verify).

SSH 登录路由器后运行 / SSH into the router and run:

cd /tmp
wget -O pcat2_pppoe_ipv6.sh https://gist.githubusercontent.com/c2h2/ae07a4c818457b4cf3f087bf164059f8/raw/pcat2_pppoe_ipv6.sh
sh pcat2_pppoe_ipv6.sh
  • 脚本会先把当前配置备份到 /tmp,应用时 PPPoE 会短暂断线重连几秒,随后自动等待前缀下发并测试 IPv6 连通性。 / The script backs up your config to /tmp first, briefly restarts the PPPoE session, then waits for the delegated prefix and tests IPv6 connectivity.
  • 可选参数 / Options: --ra-high(多路由/多 RA 环境,见下文第 3 节 / multi-router LANs, see section 3)、--force(非 PPPoE WAN / non-PPPoE WAN)、--no-ping(跳过连通性测试 / skip the connectivity test)。运行 / Run sh pcat2_pppoe_ipv6.sh --help 查看帮助。
  • 脚本源码 / Script source: GitHub Gist。中国大陆用户如无法访问 gist,请按下文手动配置。 / If the gist is unreachable from mainland China, follow the manual steps below.

中文指南

1. WAN 接口(PPPoE)

新版固件下 不需要手动创建绑定 eth0 的 WAN6 接口。只要 WAN 口开启 IPv6 协商,netifd 会自动在 PPPoE 逻辑口上创建动态别名接口 wan_6(注意是下划线),负责 DHCPv6 / 前缀委托。

LuCI: 网络 → 接口 → WAN → 高级设置

  • 获取 IPv6 地址 → 自动
  • 委托 IPv6 前缀 → 启用

或使用 UCI:

uci set network.wan.ipv6='auto'
uci commit network
ifup wan
注意 如果系统里遗留了一个绑定 eth0 的 WAN6 接口(老指南的做法),它在 PPPoE 线路上会一直处于 pending 状态。建议直接禁用:
uci set network.wan6.auto='0'
uci commit network

2. LAN 接口

LuCI: 网络 → 接口 → LAN

  • IPv6 分配长度 (ip6assign) → 60(运营商一般下发 /56 或 /60)
  • IPv6 前缀过滤器 (ip6class) → 必须留空!
uci set network.lan.ip6assign='60'
uci -q delete network.lan.ip6class
uci commit network
ifup lan
⚠ 最常见故障 如果 ip6class 被设为 local,LAN 只会分配 ULA(fd00
:/8 私有前缀),运营商委托的公网前缀永远不会下发到 br-lan,内网设备就只有 fdxx 地址、无法访问 IPv6 互联网。删除该选项即可恢复。

3. RA / DHCPv6(SLAAC)

LuCI: 网络 → 接口 → LAN → DHCP 服务器 → IPv6 设置

  • RA 服务:混合模式 (SLAAC 默认开启,即 RA 前缀带 A 标志)
  • DHCPv6 服务:混合模式
  • NDP 代理:混合模式(旁路由/中继场景才需要)
uci set dhcp.lan.ra='hybrid'
uci set dhcp.lan.dhcpv6='hybrid'
uci commit dhcp
/etc/init.d/odhcpd reload
提示 若局域网内还有其它设备也在发 RA(多路由/多线路环境),把 photonicat 的路由优先级调高,客户端会优先选它作为默认网关:
uci set dhcp.lan.ra_preference='high'
uci commit dhcp && /etc/init.d/odhcpd reload

4. Docker 与 IPv6 转发(26.04 版重要坑)

photonicatWrt 自带 Docker(27.x)。Docker 27+ 默认启用 ip6tables,会创建 ip6 filter FORWARD 链且策略为 drop —— 它会丢弃所有转发的 IPv6 流量,即使 fw4 防火墙已放行 lan→wan。症状:路由器本机 ping6 正常,内网设备拿到了公网 IPv6 却 ping 不通外网。

检查:

nft list chain ip6 filter FORWARD
# 如果看到 policy drop 且计数一直增长,即中招

永久修复:在 /etc/docker/daemon.json出厂内容基础上加一行 "ip6tables": false(不影响 IPv4 容器网络):

cat > /etc/docker/daemon.json <<'EOF'
{
"data-root": "/opt/",
"log-level": "warn",
"ip6tables": false
}
EOF
/etc/init.d/docker restart
⚠ 注意 photonicatWrt 实际由 /etc/init.d/docker(而非 dockerd)以 --iptables=false 参数启动 Docker。不要在 daemon.json 里添加 "iptables" 键,也不要改动出厂的 data-root —— 与启动参数冲突会导致 Docker 开机无法启动,改 data-root 会导致已有镜像"消失"。详见 Photonicat 2 Docker 使用指南

5. 防火墙

fw4 默认已放行 lan→wan 的 IPv6 转发和必要的 ICMPv6,出站上网无需额外规则。只有当你需要从公网主动访问内网设备(自建服务器/NAS)时才添加入站规则,且建议按端口精确放行,不要整段 ACCEPT 全部入站 IPv6。

6. 验证

路由器上:

ifstatus wan_6 | grep -A6 ipv6-prefix     # 应看到运营商委托的 /56 或 /60
ifstatus lan | grep -A8 ipv6-prefix-assignment   # 应看到公网前缀已分配给 br-lan
ping -6 -c3 photonicat.com

内网设备上:

ip -6 addr show   # 应有公网 (如 240e:/2408:/2409: 等) SLAAC 地址
ping -6 -c3 photonicat.com

7. 多出口/多 RA 环境排障

如果局域网里有多台设备宣告 RA(例如另一台 5G 网关、Proxmox 虚拟机等),Linux 客户端会把多个默认网关做 ECMP 负载均衡,流量可能被分到没有 IPv6 上行的网关而间歇性丢包;或者源地址选择与网关不匹配(photonicat 的默认路由是按源前缀限定的 from 240e:xxxx::/56),返回 "Destination unreachable: No route"。

  • 首选:让没有上行的设备停止宣告默认路由(router lifetime 设为 0)。
  • 客户端(systemd-networkd)也可固定网关并用地址标签固定源地址选择:
# /etc/systemd/network/eth0.network.d/50-ipv6-gateway.conf
[IPv6AcceptRA]
UseGateway=false

[Route]
Gateway=fe80::xxxx:xxxx:xxxx:xxxx   # photonicat br-lan 的链路本地地址

[IPv6AddressLabel]
Label=99
Prefix=2409::/16    # 不希望选为源地址的运营商前缀

English Guide

1. WAN interface (PPPoE)

On current firmware you no longer need a manual WAN6 interface bound to eth0. With IPv6 negotiation enabled on WAN, netifd automatically spawns a dynamic alias interface wan_6 (with an underscore) on the PPPoE logical interface, which handles DHCPv6 and prefix delegation.

LuCI: Network → Interfaces → WAN → Advanced

  • Obtain IPv6 address → Automatic
  • Delegate IPv6 prefix → Enabled

Or via UCI:

uci set network.wan.ipv6='auto'
uci commit network
ifup wan
Note If a legacy WAN6 interface bound to eth0 exists (as older guides suggested), it will sit in "pending" forever on a PPPoE line. Disable it
uci set network.wan6.auto='0'
uci commit network

2. LAN interface

  • IPv6 assignment length (ip6assign) → 60 (ISPs typically delegate a /56 or /60)
  • IPv6 prefix filter (ip6class) → must be left EMPTY!
uci set network.lan.ip6assign='60'
uci -q delete network.lan.ip6class
uci commit network
ifup lan
⚠ Most common failure If ip6class is set to local, the LAN only gets ULA (fd00
:/8) prefixes — the ISP-delegated global prefix is never assigned to br-lan, so clients only get fdxx addresses and cannot reach the IPv6 internet. Deleting this option fixes it.

3. RA / DHCPv6 (SLAAC)

  • RA-Service: hybrid (SLAAC is on by default — RA prefixes carry the A flag)
  • DHCPv6-Service: hybrid
  • NDP-Proxy: hybrid (only needed for relay/bridge setups)
uci set dhcp.lan.ra='hybrid'
uci set dhcp.lan.dhcpv6='hybrid'
uci commit dhcp
/etc/init.d/odhcpd reload
Tip If other devices on the LAN also send RAs (multi-router / multi-uplink environments), raise the photonicat's router preference so clients prefer it as default gateway
uci set dhcp.lan.ra_preference='high'
uci commit dhcp && /etc/init.d/odhcpd reload

4. Docker vs IPv6 forwarding (important 26.04 pitfall)

photonicatWrt ships Docker (27.x). Docker 27+ enables ip6tables by default and creates an ip6 filter FORWARD chain with policy drop — it silently drops all forwarded IPv6, even though fw4 correctly allows lan→wan. Symptom: ping6 works from the router itself, LAN clients get global IPv6 addresses but cannot reach the internet.

Check:

nft list chain ip6 filter FORWARD
# if you see "policy drop" and a growing counter, this is your problem

Permanent fix: add "ip6tables": false to /etc/docker/daemon.json while keeping the factory keys (IPv4 container networking is unaffected):

cat > /etc/docker/daemon.json <<'EOF'
{
"data-root": "/opt/",
"log-level": "warn",
"ip6tables": false
}
EOF
/etc/init.d/docker restart
⚠ Note On photonicatWrt, Docker is actually launched by /etc/init.d/docker (not dockerd) with --iptables=false. Do not add an "iptables" key to daemon.json and do not change the factory data-root — a flag/config conflict prevents Docker from starting at boot, and a changed data-root makes existing images "disappear". See Photonicat 2 Docker 使用指南.

5. Firewall

fw4 already allows IPv6 lan→wan forwarding and the required ICMPv6 by default — no extra rules are needed for outbound connectivity. Only add inbound rules when you need to reach LAN devices from the internet (self-hosted servers/NAS), and prefer precise per-port rules over a blanket ACCEPT of all inbound IPv6.

6. Verification

On the router:

ifstatus wan_6 | grep -A6 ipv6-prefix     # ISP-delegated /56 or /60 should appear
ifstatus lan | grep -A8 ipv6-prefix-assignment   # the global prefix should be assigned to br-lan
ping -6 -c3 photonicat.com

On a LAN client:

ip -6 addr show   # expect a global (e.g. 240e:/2408:/2409:) SLAAC address
ping -6 -c3 photonicat.com

If several devices advertise RAs on the LAN (another 5G gateway, Proxmox VMs, …), Linux clients install an ECMP default route across all of them; flows hashed to a gateway without IPv6 upstream blackhole intermittently. Source-address selection can also mismatch the gateway (the photonicat's upstream default route is source-restricted, e.g. from 240e:xxxx::/56), yielding "Destination unreachable: No route".

  • Preferred fix: make routers without upstream stop advertising a default route (router lifetime 0).
  • On a systemd-networkd client you can pin the gateway and steer source selection:
# /etc/systemd/network/eth0.network.d/50-ipv6-gateway.conf
[IPv6AcceptRA]
UseGateway=false

[Route]
Gateway=fe80::xxxx:xxxx:xxxx:xxxx   # photonicat br-lan link-local address

[IPv6AddressLabel]
Label=99
Prefix=2409::/16    # ISP prefix you do NOT want chosen as source

IPv6 地址说明 / Understanding the addresses

一个接口同时拥有多个 IPv6 地址是正常现象 / Multiple IPv6 addresses on one interface is normal:

  • 240e:xxxx:xxxx:xx00:xxxx:xxff:fexx:xxxx/64 → 公网地址,SLAAC 由 RA 前缀+接口标识自动生成 / global address, auto-generated via SLAAC
  • 240e:xxxx:xxxx:xx00::2e9/128 → DHCPv6 下发的公网地址 / global address assigned by stateful DHCPv6
  • fdxx:....../64 → ULA 私有地址,仅内网使用,不上公网 / ULA private address, LAN-only
  • fe80::/64 → 链路本地地址,用于邻居发现/网关 / link-local, used for NDP and as gateway

只有 global (GUA) 地址可用于公网通信;“全球直连”意味着设备在公网可见,请合理配置防火墙。 / Only GUA addresses reach the internet; being globally reachable means you should keep the firewall sensible.