Photoincat 2 IPv6 PPPoE:修订间差异

来自Photonicat Wiki
跳转到导航 跳转到搜索
Monstercat留言 | 贡献
C2h2留言 | 贡献
Update guide for photonicatWrt 26.04.1: auto wan_6 alias (no manual eth0 wan6), ip6class pitfall, Docker ip6tables FORWARD drop fix, ra_preference, verification & multi-RA troubleshooting
第1行: 第1行:
* 本文件说明如何在 OpenWrt 上配置 基于 PPPoE 的 IPv6。
{| class="wikitable"
* 在某些情况下,如果直接通过家庭光猫/路由器接入,运营商可能会自动提供 IPv6,并默认开启 '''NAT6'''。
|-
* 但是,在 PPPoE 拨号连接(常见于 FTTH/DSL 场景)中,则需要手动配置 IPv6 协商、前缀委托以及 LAN 分发。
! 适用版本 / Applies to
* This document explains how to configure IPv6 with PPPoE on OpenWrt.
| photonicatWrt '''26.04.1''' (r7720, OpenWrt 24+ base, fw4/nftables, odhcpd) — 更新于 2026-07 / Updated 2026-07
* In some cases, if you connect directly through a home modem/router, IPv6 may be provided automatically with '''NAT6''' enabled by default.
|-
* However, for PPPoE connections (typical in FTTH/DSL setups), you need to manually configure IPv6 negotiation, prefix delegation, and LAN distribution.
! 旧版指南 / Older firmware
| 2023–2024 固件请参考本页面历史版本 / For 2023–2024 firmware see the page history
|}


== PPPoE IPv6 配置指南 ==
* 本文说明如何在 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.


=== WAN 接口设置 (http://172.16.0.1:8080/cgi-bin/luci/admin/network/network) WAN===
== 中文指南 ==
# 进入 '''网络 → 接口 → WAN'''。
# 在 IPv6 设置中:
## 获取 IPv6 地址 → '''手动''' (在 PPP 链路上启用 IPv6 协商)。
## 委托 IPv6 前缀 → '''启用'''。


; 说明 WAN 是拨号接口,必须让 PPPoE 连接时顺便协商 IPv6 地址,并把上级分配的 IPv6 前缀传递下去,这样内网才能用到公网 IPv6。
=== 1. WAN 接口(PPPoE) ===
新版固件下 '''不需要手动创建绑定 eth0 的 WAN6 接口'''。只要 WAN 口开启 IPv6 协商,netifd 会自动在 PPPoE 逻辑口上创建动态别名接口 <code>wan_6</code>(注意是下划线),负责 DHCPv6 / 前缀委托。


=== WAN6 接口设置 (http://172.16.0.1:8080/cgi-bin/luci/admin/network/network) WAN6 ===
LuCI: '''网络 → 接口 → WAN → 高级设置'''
# 进入 '''网络 → 接口 → WAN6'''
* 获取 IPv6 地址 → '''自动'''
# 设备选择 → '''pppoe-wan''' (原本默认为 eth0)。
* 委托 IPv6 前缀 → '''启用'''


; 说明 WAN6 不是单独的物理口,而是跟随 PPPoE 拨号逻辑口。把它绑到 pppoe-wan 才能正确收发 IPv6 数据。
或使用 UCI:
<pre>
uci set network.wan.ipv6='auto'
uci commit network
ifup wan
</pre>


=== LAN 接口设置 (http://172.16.0.1:8080/cgi-bin/luci/admin/network/network) LAN ===
; 注意 如果系统里遗留了一个绑定 <code>eth0</code> 的 WAN6 接口(老指南的做法),它在 PPPoE 线路上会一直处于 pending 状态。建议直接禁用:
在高级设置中:
<pre>
* IPv6 前缀过滤器:不设定,或设置为wan6
uci set network.wan6.auto='0'
uci commit network
</pre>


在 DHCPv6 相关配置中:
=== 2. LAN 接口 ===
* RA 服务:'''混合模式'''
LuCI: '''网络 → 接口 → LAN'''
* IPv6 分配长度 (ip6assign) → '''60'''(运营商一般下发 /56 或 /60)
* '''IPv6 前缀过滤器 (ip6class) → 必须留空!'''
 
<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 服务:'''混合模式'''
* DHCPv6 服务:'''混合模式'''
* NDP 代理:'''混合模式'''
* 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 不通外网。


; 说明 LAN 要作为 IPv6 地址分配的服务器,把前缀通过 RA 和 DHCPv6 分发给局域网设备。混合模式的 NDP 可以同时兼容静态地址和 DHCPv6 分配。
检查:
<pre>
nft list chain ip6 filter FORWARD
# 如果看到 policy drop 且计数一直增长,即中招
</pre>


=== 防火墙规则 (http://172.16.0.1:8080/cgi-bin/luci/admin/network/firewall/rules) ===
永久修复(禁用 Docker 的 ip6tables 管理,不影响 IPv4 容器网络):
为了保证 IPv6 入站访问正常,需要添加一条入站规则:
<pre>
# 进入 '''网络 → 防火墙 → 自定义规则'''。
cat > /etc/docker/daemon.json <<'EOF'
# 添加新规则:
{ "data-root": "/opt/docker/", "log-level": "warn", "iptables": true, "ip6tables": false }
* 名称:'''Allow-IPv6-Inbound'''
EOF
* 区域:'''wan'''
uci set dockerd.globals.alt_config_file='/etc/docker/daemon.json'
* 协议:'''IPv6'''
uci commit dockerd
* 来源区域:'''wan'''
/etc/init.d/dockerd restart
* 目标区域:'''device/lan'''
</pre>
* 动作:'''ACCEPT'''
# 保存并应用。


; 说明 默认防火墙会拦截来自外部的 IPv6 流量。添加这条规则是为了让 IPv6 入站流量能通过,保证公网可以访问到内网设备(如服务器或 NAS)。
=== 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 环境排障 ===
* WAN 接口(pppoe-wan)负责拨号并启用 IPv6 协商。
如果局域网里有多台设备宣告 RA(例如另一台 5G 网关、Proxmox 虚拟机等),Linux 客户端会把多个默认网关做 ECMP 负载均衡,流量可能被分到没有 IPv6 上行的网关而'''间歇性丢包''';或者源地址选择与网关不匹配(photonicat 的默认路由是按源前缀限定的 <code>from 240e:xxxx::/56</code>),返回 "Destination unreachable: No route"。
* WAN6 接口绑定到 PPPoE 逻辑接口,而不是物理网口 eth0。
* LAN 接口通过 RA 和 DHCPv6 向内网设备下发 IPv6 地址和前缀。
* 防火墙规则确保外部 IPv6 流量可以按需进入 LAN/设备。


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


在查看接口(例如 '''eth0''')时,可能会看到多个 IPv6 地址。 
[Route]
这是正常的,因为 IPv6 允许同一个接口同时拥有多个地址。
Gateway=fe80::xxxx:xxxx:xxxx:xxxx  # photonicat br-lan 的链路本地地址


=== 示例输出 ===
[IPv6AddressLabel]
<code>
Label=99
ifconfig eth0
Prefix=2409::/16    # 不希望选为源地址的运营商前缀
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
</pre>
  inet 172.16.8.37  netmask 255.255.252.0  broadcast 172.16.11.255
  inet6 240e:32c:8d2d:f900::2e9/128  scopeid 0x0<global>
  inet6 240e:32c:8d2d:f900:be24:11ff:fe75:97aa/64  scopeid 0x0<global>
  inet6 fe80::be24:11ff:fe75:97aa/64  scopeid 0x20<link>
  inet6 240e:32c:8cfb:2500:be24:11ff:fe75:97aa/64  scopeid 0x0<global>
  ...
</code>


=== 地址类型解释 ===
== English Guide ==
* '''240e:32c:8d2d:f900::2e9/128''' → 主机专用 IPv6 地址(点对点)。 
* '''240e:32c:8d2d:f900:be24:11ff:fe75:97aa/64''' → 全球 IPv6 地址,由网卡 MAC 自动生成(SLAAC)。 
* '''fe80::be24:11ff:fe75:97aa/64''' → 链路本地地址(Link-local),只在本链路内有效,用于路由邻居发现等。 
* '''240e:32c:8cfb:2500:be24:11ff:fe75:97aa/64''' → 另一个由运营商下发的全球 IPv6 前缀(可能分配多个子网)。 


=== 什么是 “全球直连” ===
=== 1. WAN interface (PPPoE) ===
* 所有标记为 '''<global>''' IPv6 地址(如 240e::/64 开头)都是 '''全球单播地址'''。 
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.
* 意味着设备可以直接通过公网 IPv6 访问,无需 NAT 转换。 
* 这就是所谓的 **“全球直连”** —— 每个设备都能在互联网上直接通信。 
* 不像 IPv4 需要 NAT 才能共享公网 IP,IPv6 让每个设备都能拥有自己独立的公网地址。 


=== 客户提示 ===
LuCI: '''Network → Interfaces → WAN → Advanced'''
* 一个接口上有多个 IPv6 地址是正常现象。 
* Obtain IPv6 address → '''Automatic'''
* 只有 '''global''' 类型地址(例如 240e::/64)可以用于公网通信。 
* Delegate IPv6 prefix → '''Enabled'''
* '''link-local (fe80::/64)''' 地址仅用于本地链路内的通信,不会上公网。 
* “全球直连” 表示设备已经在公网可见,因此需要合理配置防火墙,避免不必要的服务暴露。 


== PPPoE and IPv6 Configuration Guide ==
Or via UCI:
<pre>
uci set network.wan.ipv6='auto'
uci commit network
ifup wan
</pre>


=== WAN Interface Settings (http://172.16.0.1:8080/cgi-bin/luci/admin/network/network) WAN ===
; 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:
# Go to '''Network → Interfaces → WAN'''.
<pre>
# Under IPv6 settings:
uci set network.wan6.auto='0'
## Obtain IPv6 address → '''Manual''' (enable IPv6 negotiation on the PPP link).
uci commit network
## Delegate IPv6 prefix → '''Enable'''.
</pre>


; Note The WAN is the dialing interface. PPPoE must also negotiate an IPv6 address and pass down the delegated IPv6 prefix from the ISP, so the LAN can use global IPv6.
=== 2. LAN interface ===
* IPv6 assignment length (ip6assign) → '''60''' (ISPs typically delegate a /56 or /60)
* '''IPv6 prefix filter (ip6class) → must be left EMPTY!'''


=== WAN6 Interface Settings (http://172.16.0.1:8080/cgi-bin/luci/admin/network/network) WAN6 ===
<pre>
# Go to '''Network → Interfaces → WAN6'''.
uci set network.lan.ip6assign='60'
# Set device → '''pppoe-wan''' (instead of the default eth0).
uci -q delete network.lan.ip6class
uci commit network
ifup lan
</pre>


; Note WAN6 is not a separate physical port. It follows the PPPoE logical interface. Binding it to pppoe-wan ensures IPv6 traffic can be sent and received correctly.
; ⚠ 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.


=== LAN Interface Settings (http://172.16.0.1:8080/cgi-bin/luci/admin/network/network) LAN ===
=== 3. RA / DHCPv6 (SLAAC) ===
In Advanced Settings:
* RA-Service: '''hybrid''' (SLAAC is on by default — RA prefixes carry the A flag)
* IPv6 prefix filter: no filter, or wan6
* DHCPv6-Service: '''hybrid'''
* NDP-Proxy: '''hybrid''' (only needed for relay/bridge setups)


In the DHCPv6-related settings:
<pre>
* RA Service: '''Hybrid mode'''
uci set dhcp.lan.ra='hybrid'
* DHCPv6 Service: '''Hybrid mode'''
uci set dhcp.lan.dhcpv6='hybrid'
* NDP Proxy: '''Hybrid mode'''
uci commit dhcp
/etc/init.d/odhcpd reload
</pre>


; Note The LAN must act as an IPv6 address distributor, passing prefixes to internal devices via RA and DHCPv6. Hybrid NDP mode allows compatibility with both static and DHCPv6-assigned addresses.
; 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>


=== Firewall Rule (http://172.16.0.1:8080/cgi-bin/luci/admin/network/firewall/rules) ===
=== 4. Docker vs IPv6 forwarding (important 26.04 pitfall) ===
To ensure inbound IPv6 traffic works properly, add an inbound rule:
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.
# Go to '''Network → Firewall → Custom Rules'''.
# Add a new rule:
* Name: '''Allow-IPv6-Inbound'''
* Zone: '''wan'''
* Protocol: '''IPv6'''
* Source zone: '''wan'''
* Destination zone: '''device/lan'''
* Action: '''ACCEPT'''
# Save and apply.


; Note By default, the firewall blocks inbound IPv6 traffic. This rule ensures inbound IPv6 can pass through, allowing public access to internal devices (e.g., server or NAS).
Check:
<pre>
nft list chain ip6 filter FORWARD
# if you see "policy drop" and a growing counter, this is your problem
</pre>


----
Permanent fix (disable Docker's ip6tables management; IPv4 container networking is unaffected):
<pre>
cat > /etc/docker/daemon.json <<'EOF'
{ "data-root": "/opt/docker/", "log-level": "warn", "iptables": true, "ip6tables": false }
EOF
uci set dockerd.globals.alt_config_file='/etc/docker/daemon.json'
uci commit dockerd
/etc/init.d/dockerd restart
</pre>


=== Summary ===
=== 5. Firewall ===
* The WAN interface (pppoe-wan) is responsible for dialing and enabling IPv6 negotiation.
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.
* The WAN6 interface must be bound to the PPPoE logical interface, not a physical port like eth0. 
* The LAN interface distributes IPv6 addresses and prefixes to internal devices via RA and DHCPv6. 
* The firewall rule ensures external IPv6 traffic can reach LAN devices as needed.


== IPv6 Address Explanation ==
=== 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>


When inspecting an interface (such as '''eth0'''), you may see multiple IPv6 addresses.
=== 7. Troubleshooting multi-uplink / multi-RA LANs ===
This is normal, since IPv6 allows a single interface to hold multiple addresses.
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".


=== Example Output ===
* Preferred fix: make routers without upstream stop advertising a default route (router lifetime 0).
<code>
* On a systemd-networkd client you can pin the gateway and steer source selection:
ifconfig eth0
<pre>
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
# /etc/systemd/network/eth0.network.d/50-ipv6-gateway.conf
  inet 172.16.8.37  netmask 255.255.252.0 broadcast 172.16.11.255
[IPv6AcceptRA]
  inet6 240e:32c:8d2d:f900::2e9/128  scopeid 0x0<global>
UseGateway=false
  inet6 240e:32c:8d2d:f900:be24:11ff:fe75:97aa/64  scopeid 0x0<global>
  inet6 fe80::be24:11ff:fe75:97aa/64  scopeid 0x20<link>
  inet6 240e:32c:8cfb:2500:be24:11ff:fe75:97aa/64  scopeid 0x0<global>
  ...
</code>


=== Address Types Explained ===
[Route]
* '''240e:32c:8d2d:f900::2e9/128''' → Host-specific IPv6 address (point-to-point). 
Gateway=fe80::xxxx:xxxx:xxxx:xxxx  # photonicat br-lan link-local address
* '''240e:32c:8d2d:f900:be24:11ff:fe75:97aa/64''' → Global IPv6 address, auto-generated from the NIC MAC (SLAAC). 
* '''fe80::be24:11ff:fe75:97aa/64''' → Link-local address, only valid within the same link, used for routing neighbor discovery. 
* '''240e:32c:8cfb:2500:be24:11ff:fe75:97aa/64''' → Another global IPv6 prefix delegated by the ISP (possibly multiple subnets). 


=== What is "Global Direct Connection"? ===
[IPv6AddressLabel]
* Any IPv6 address marked as '''<global>''' (such as those starting with 240e::/64) is a '''Global Unicast Address'''. 
Label=99
* This means the device can be accessed directly from the public Internet, without NAT. 
Prefix=2409::/16    # ISP prefix you do NOT want chosen as source
* This is known as **“Global Direct Connection”** — every device can communicate directly on the Internet. 
</pre>
* Unlike IPv4, which usually requires NAT to share a public IP, IPv6 gives each device its own public address. 


=== Customer Notes ===
== IPv6 地址说明 / Understanding the addresses ==
* Having multiple IPv6 addresses on one interface is normal
一个接口同时拥有多个 IPv6 地址是正常现象 / Multiple IPv6 addresses on one interface is normal:
* Only '''global''' addresses (e.g., 240e::/64) are usable for Internet communication. 
* <code>240e:xxxx:xxxx:xx00:xxxx:xxff:fexx:xxxx/64</code> → 公网地址,SLAAC 由 RA 前缀+接口标识自动生成 / global address, auto-generated via SLAAC
* The '''link-local (fe80::/64)''' address is only for communication within the local link and never goes out to the Internet. 
* <code>240e:xxxx:xxxx:xx00::2e9/128</code> → DHCPv6 下发的公网地址 / global address assigned by stateful DHCPv6
* “Global Direct Connection” means the device is already reachable on the public Internet, so proper firewall configuration is important to avoid exposing unwanted services.
* <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日 (一) 00:07的版本

适用版本 / 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.

中文指南

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 且计数一直增长,即中招

永久修复(禁用 Docker 的 ip6tables 管理,不影响 IPv4 容器网络):

cat > /etc/docker/daemon.json <<'EOF'
{ "data-root": "/opt/docker/", "log-level": "warn", "iptables": true, "ip6tables": false }
EOF
uci set dockerd.globals.alt_config_file='/etc/docker/daemon.json'
uci commit dockerd
/etc/init.d/dockerd restart

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 (disable Docker's ip6tables management; IPv4 container networking is unaffected):

cat > /etc/docker/daemon.json <<'EOF'
{ "data-root": "/opt/docker/", "log-level": "warn", "iptables": true, "ip6tables": false }
EOF
uci set dockerd.globals.alt_config_file='/etc/docker/daemon.json'
uci commit dockerd
/etc/init.d/dockerd restart

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.