IPv6 routing does not work on LAN, but does work from router

Okay, more investigation.

I've looked at /etc/config/network and found this directive:

config globals 'globals'
	option ula_prefix 'fd11:2198:bc83::/48'

Which makes sense as my VLANs are on fd11:2198:bc83::/64 and fd11:2198:bc83:1::/64 respectively.

But for some reason the default IPv6 route that OpenWrt configured is using a source-based policy to only route packets from 2607:f598:b150:252::/64, as if it somehow expects my VLANs to not be using ULAs (i.e., addresses in the fd00::/8 range), even though OpenWrt is what configured them to be ULAs in the first place.

In forum post Understanding IPv6 routes in web UI I see that the OP has a different routing table setup. Two blocks assigned to their LAN, one ULA and one GUA?

I see also in a hitherto-unexplored config section that the wan6 interface has an option IPv6 source routing enabled, with the comment Automatically handle multiple uplink interfaces using source-based policy routing. I didn't enable this, it came with OpenWrt on initial configuration. When disabling that config option, the unexpected source filter goes away in the route table rules. Still, no correct routing.

Ok, I look at WireGuard again while enabling my wireless interface. The RA packet uses ICMPv6 option "Route Information", which I presume is what tells Linux to create the default route. The option includes info on the range fd11:2198:bc83::/48, and indeed I do see this in my device route table:

fd11:2198:bc83::/48 via fe80::8269:1aff:fe23:8d76 dev enx70886b8d150d proto ra metric 100 pref medium
fd11:2198:bc83::/48 via fe80::8269:1aff:fe23:8d76 dev wlp0s20f3 proto ra metric 600 pref medium

So why is OpenWrt not responding with RA establishing a default route, and instead only suggesting that packets can route within/between its VLANs...?

I see in https://datatracker.ietf.org/doc/html/rfc4191#section-2.2 that there is explicit support in the protocol for communicating a default route to clients, but OpenWrt is not making use of this apparently.

Ok, back to the test I ran earlier, now that the OpenWrt route table is fixed to not reject all outbound traffic using source-based policy. Now if I add default routes manually, then trying to curl an IPv6 endpoint hangs, rather than rejecting immediately. Progress? The traceroute does this:

{raxod502@cephandrius} ~ % traceroute -6 example.com
traceroute to example.com (2606:2800:21f:cb07:6820:80da:af6b:8b2c), 30 hops max, 80 byte packets
 1  yumi.lan (fd11:2198:bc83::1)  2.039 ms  1.957 ms  1.912 ms
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  * * *
 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

No ICMP is coming back from the router. I guess my traffic is just going into a blackhole.

Relevant settings, maybe:

  • Network > Interfaces > Interfaces > lan > DHCP Server > IPv6 RA Settings > Default router: Set by default to "automatic", which will not announce as default router unless a default IPv6 route is available. Default route appears to be available on the router itself, so that seems not relevant.
  • Network > Interfaces > Global network options > IPv6 ULA-Prefix: Aha! I was wondering where that came from since I didn't set it. This prefix is randomly generated at first install, it says.
  • Network > Firewall > wan > Advanced Settings > IPv6 Masquerading: Disabled. Maybe needed?

Is it possible that OpenWrt is just yeeting my packets out to the public internet without translating them from ULA? How on earth would that be supposed to work? It would certainly explain why they reach the router and then drop off, though. Both the blackholing behavior here and the source-based routing filter line up properly with the assumption that no address translation is happening.

I mean, it would certainly make sense if my devices were addressed based on the IPv6 subnet that is delegated to me from the ISP, but that is not what OpenWrt is doing, at least by default it is using ULA, so are the defaults for some reason configured to be a broken mix between the two? Where it numbers with ULA but then does not enable the needed address translation?

Looking at https://openwrt.org/docs/guide-user/network/ipv6/ipv6.nat6 and thinking about the best practices for an IPv6-network, I would expect that the issue here is that GUA address blocks are not being handed out to my VLANs, and only the ULAs are being used, and that is the source of the problems. (Presumably I can then re-enable source-based IPv6 routing.)

Maybe prefix delegation just needs to be enabled somewhere that it is not?

Aha! Ok, I pulled up some old screenshots of OpenWrt config screens and I noticed that for working VLANs, there are 2 CIDR ranges delegated, one ULA and one GUA. For broken VLANs there is only 1 range, the ULA. Right now I have ULA only assigned to both, which explains things being broken.

Btw, looking at the old screenshots, I can confirm that this is not the ISP changing the prefix they are delegating to me, that was 2607:f598:b150:252:8269:fe23:8d75/64 months ago just as it is now.

Ah. I think I understand the issue. I only get a /64 from my ISP, therefore VLANs cannot be configured at all, because IPv6 "basically" doesn't support subnets smaller than /64. See https://serverfault.com/a/875443.

I think IPv6 was broken on the guest network most likely, but I do not have any critical devices on there, so I didn't notice. Then something flip-flopped internally to OpenWrt and now the internal network is broken but the guest network was working.

I guess I'll request a larger address block from my ISP, and in the meantime, collapse my SSIDs into the same VLAN, and set up firewall rules based on MAC address to isolate devices that should not talk to each other. Lame, but I don't know a better workaround.

Update: Then again, I see https://openwrt.org/docs/guide-user/network/ipv6/ipv6.nat6 which links to https://openwrt.org/docs/guide-user/network/ipv6/configuration#ipv6_relay on the wiki and suggests that VLANs could be configured in DHCPv6 relay mode if receiving only /64 from an ISP. Maybe a better option.

I disable prefix delegation on wan6 and prefix assignment on lan, then reconfigure wan6, lan, and guest all to use relay mode for RA and DHCPv6. Okay, this gets IPv6 GUAs assigned to my devices on VLANs, finally. But requests to IPv6 hosts still hang.

So, what now? (It'd be really great if the wiki explained clearly what configuration is necessary to set up a basic IPv6 network, since the defaults don't appear to work even with extensive fiddling.)

https://github.com/openwrt/openwrt/issues/9881 does not look good... does IPv6 subnetting of a /64 work in OpenWrt?

Edit: Wtf! https://github.com/openwrt/openwrt/issues/9881#issuecomment-1711820408 is buried, but it is correct, removing the ULA prefix from settings causes connectivity to immediately work! Seems like a bug in OpenWrt then?