Turris won't route IPv6 packets to WAN

My ISP provides native (dual stack) IPv6. Their DHCPv6 server offers a /56 prefix (2001:bb6:) via IA-PD but does not offer IA-NA, so no client IP address is provided. The delegated prefix appears to be properly configured into my router, but there is no IPv6 address on the WAN interface. Might this be the reason why I have no IPv6 connectivity to the internet?

A default route is present:

default from 2001:bb6:1205:8700::/56 via fe80::ea4:2ff:feea:355b dev eth1 proto static metric 512

but any attempt to send packets to internet IP addresses (e.g. Google), whether locally on the router or from another LAN node, generates a ‘network unreachable’ error. As you can see the default gateway is a link-local (fe80:) address and I cannot even ping it unless I manually add a route for that address targeting eth1. Otherwise the kernel sends the packets out br-lan like all other fe80 addresses.

Basically there’s a lot of weirdness going on and I don’t know the root cause, but I have to wonder if it might all come down to the WAN interface not having an IPv6 address. When no client address is provided by IA-NA, should the router assign itself an address from the delegated prefix? This appears to be what the ISP-provided router does. And (or?) is the link-local default gateway address making things worse?

Some relevant tcpdump output follows. Anyone got any advice?

21:13:47.272380 IP6 (flowlabel 0x9d2db, hlim 255, next-header ICMPv6 (58) payload length: 16) fe80::da58:d7ff:fe00:4480 > ff02::2: [icmp6 sum ok] ICMP6, router solicitation, length 16 source link-address option (1), length 8 (1): d8:58:d7:00:44:80 21:13:47.274458 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::1 > fe80::da58:d7ff:fe00:4480: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::da58:d7ff:fe00:4480 source link-address option (1), length 8 (1): 84:be:52:1a:92:04 21:13:47.987644 IP6 (flowlabel 0x99180, hlim 1, next-header UDP (17) payload length: 98) fe80::da58:d7ff:fe00:4480.546 > ff02::1:2.547: [udp sum ok] dhcp6 solicit (xid=8b9b3a (elapsed-time 0) (option-request SIP-servers-domain SIP-servers-address DNS-server DNS-search-list SNTP-servers NTP-server AFTR-Name opt_67 opt_82 opt_83 opt_94 opt_95 opt_96) (client-ID hwaddr type 1 d858d7004480) (reconfigure-accept) (IA_NA IAID:1 T1:0 T2:0) (IA_PD IAID:1 T1:0 T2:0)) 21:13:48.008443 IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 174) fe80::ea4:2ff:feea:355b.547 > fe80::da58:d7ff:fe00:4480.546: [udp sum ok] dhcp6 advertise (xid=8b9b3a (server-ID hwaddr type 1 0ca402ea355b) (client-ID hwaddr type 1 d858d7004480) (IA_NA IAID:1 T1:0 T2:0 (status-code NoAddrsAvail)) (IA_PD IAID:1 T1:1800 T2:2880 (IA_PD-prefix 2001:bb6:1205:8a00::/56 pltime:3600 vltime:3600)) (DNS-server 2001:bb0::1 2001:bb0::2)) 21:13:49.399242 IP6 (flowlabel 0x99180, hlim 1, next-header UDP (17) payload length: 82) fe80::da58:d7ff:fe00:4480.546 > ff02::1:2.547: [udp sum ok] dhcp6 solicit (xid=652d48 (elapsed-time 0) (option-request SIP-servers-domain SIP-servers-address DNS-server DNS-search-list SNTP-servers NTP-server AFTR-Name opt_67 opt_82 opt_83 opt_94 opt_95 opt_96) (client-ID hwaddr type 1 d858d7004480) (reconfigure-accept) (IA_PD IAID:1 T1:0 T2:0)) 21:13:49.416571 IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 121) fe80::ea4:2ff:feea:355b.547 > fe80::da58:d7ff:fe00:4480.546: [udp sum ok] dhcp6 advertise (xid=652d48 (server-ID hwaddr type 1 0ca402ea355b) (client-ID hwaddr type 1 d858d7004480) (IA_PD IAID:1 T1:1800 T2:2880 (IA_PD-prefix 2001:bb6:1205:8a00::/56 pltime:3600 vltime:3600)) (DNS-server 2001:bb0::1 2001:bb0::2)) 21:13:51.031267 IP6 (flowlabel 0x99180, hlim 1, next-header UDP (17) payload length: 125) fe80::da58:d7ff:fe00:4480.546 > ff02::1:2.547: [udp sum ok] dhcp6 request (xid=f7b435 (elapsed-time 0) (option-request SIP-servers-domain SIP-servers-address DNS-server DNS-search-list SNTP-servers NTP-server AFTR-Name opt_67 opt_82 opt_83 opt_94 opt_95 opt_96) (client-ID hwaddr type 1 d858d7004480) (server-ID hwaddr type 1 0ca402ea355b) (reconfigure-accept) (IA_PD IAID:1 T1:0 T2:0 (IA_PD-prefix 2001:bb6:1205:8a00::/56 pltime:3600 vltime:3600))) 21:13:51.274578 IP6 (flowlabel 0x9d2db, hlim 255, next-header ICMPv6 (58) payload length: 8) fe80::da58:d7ff:fe00:4480 > ff02::2: [icmp6 sum ok] ICMP6, router solicitation, length 8 21:13:51.276449 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::1 > fe80::da58:d7ff:fe00:4480: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::da58:d7ff:fe00:4480 source link-address option (1), length 8 (1): 84:be:52:1a:92:04 21:13:51.408037 IP6 (class 0xe0, hlim 255, next-header UDP (17) payload length: 121) fe80::ea4:2ff:feea:355b.547 > fe80::da58:d7ff:fe00:4480.546: [udp sum ok] dhcp6 reply (xid=f7b435 (server-ID hwaddr type 1 0ca402ea355b) (client-ID hwaddr type 1 d858d7004480) (IA_PD IAID:1 T1:1800 T2:2880 (IA_PD-prefix 2001:bb6:1205:8a00::/56 pltime:3600 vltime:3600)) (DNS-server 2001:bb0::1 2001:bb0::2)) 21:13:52.272808 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::1 > fe80::da58:d7ff:fe00:4480: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::da58:d7ff:fe00:4480 source link-address option (1), length 8 (1): 84:be:52:1a:92:04 21:13:52.285846 IP6 (class 0xe0, hlim 255, next-header ICMPv6 (58) payload length: 24) fe80::ea4:2ff:feea:355b > fe80::da58:d7ff:fe00:4480: [icmp6 sum ok] ICMP6, router advertisement, length 24 hop limit 64, Flags [none], pref medium, router lifetime 4500s, reachable time 0s, retrans time 0s source link-address option (1), length 8 (1): 0c:a4:02:ea:37:16

Link-Local routing is something really cool and nasty. It won’t give you a globally routable IP but will save IP space.
Your problem is not the link-local routing but some of the effects of it.

This route allows IPs from your assigned prefix to reach the internet.

There may even be the same link-local IP on multiple interfaces but you may have some problems with your network then.
To ping the link-local address of your providers router you should use ping fe80::ea4:2ff:feea:355b%eth1 or ping fe80::ea4:2ff:feea:355b -I eth1
You cannot reach internet addresses not on the same link using a link-local IP. To reach them from you router select a subnet from you delegation and assign it to your wan interface.

For reference here are the link-local routing entries from my Omnia:

fe80::/64 dev eth1 proto kernel metric 256 pref medium
fe80::/64 dev eth2 proto kernel metric 256 pref medium
fe80::/64 dev wlp2s0 proto kernel metric 256 pref medium

In the end your router itself cannot reach the internet because it has no global IP on its own. If your LAN interface gets a prefix assigned and Router Advertisement works then your LAN devices should still be able to reach the internet. If your router itself should be able to reach the internet then assigning a subnet from your delegated prefix is the simple option and works.

The link-local gateway does not make things worse. In my opinion it is even a good thing as it allows to use a /64 delegation without Proxy-NDP.

What I meant by suggesting the link-local gateway might be making things worse is the clear trouble that the device has with communicating with the default gateway. It seems to want to send all-link local traffic out a single interface (br-lan), even including traffic for the default gateway which is not on that interface. I was able to work around this by manually adding a static route for the default gateway’s address attached to the correct (WAN) interface, but this did not fix anything other than making it possible for me to ping the gateway.

At this point my core problem seems to be that the kernel simply will not route packets to public (internet) IP addresses. This is the case both for traffic originating from the router itself (with the source address set to that of the br-lan interface, which is properly assigned out of my delegated prefix) and for traffic originating from other nodes on my LAN (the router sends back an ICMP “unreachable route” message). ip -6 route get indicates that the default outbound route should be getting used, but the kernel simply will not route the packets for no reason I can figure out. This remains true even when I manually assign a (temporary) public address to the WAN interface.

If your router itself should be able to reach the internet then assigning a subnet from your delegated prefix is the simple option and works.

As I asked, “should the router assign itself an address from the delegated prefix?” I rather feel like it should. This is certainly not something I can do statically, as my prefix is dynamically allocated via DHCPv6 and subject to change.

There should never be a need to add or change link-local routes apart from the autogenerated scope kernel ones.

Something crazy seems to go on. I would start with the LAN devices trying to access the internet. Dump the traffic on the LAN interface on the router and on the WAN interface on the router. This way you see how the packets reach you and if and how they go out and if they are altered.

But if found something else in your capture: d8:58:d7:00:44:80 never answers the neighbor solicitation from 84:be:52:1a:92:04 or 0c:a4:02:ea:37:16. This way your packets may go out but never come back or even never go out if your router does not know the other routers.

ip -6 neigh should show your known neighbors.

Like I said, there is no traffic on the WAN interface. None. The router refuses to route any traffic out to that interface with an “unreachable route” error, even though the routing table correctly indicates the packets should be going out that interface.

d8:58:d7:00:44:80 is my Turris’s WAN interface. 84:be:52:1a:92:04 is my ISP-provided modem/router which is set to bridged mode, so we don’t really care about that as a neighbour. 0c:a4:02:ea:37:16 is the default gateway and appears correctly in my neighbour table and I can ping it successfully:

fe80::ea4:2ff:feea:355b dev eth1 lladdr 0c:a4:02:ea:37:16 router REACHABLE

Nevertheless, the router won’t send any traffic out that interface whether it originates locally…

root@turris:~# ping -I 2001:bb6:1205:9600::1 2a00:1450:400b:c00::5e PING 2a00:1450:400b:c00::5e (2a00:1450:400b:c00::5e) from 2001:bb6:1205:9600::1: 56 data bytes ping: sendto: Network unreachable

root@turris:~# ip -6 route get 2a00:1450:400b:c00::5e from 2001:bb6:1205:9600::1 2a00:1450:400b:c00::5e from 2001:bb6:1205:9600::1 via fe80::ea4:2ff:feea:355b dev eth1 proto static src 2001:bb6:1205:9600::1 metric 512

…or from the LAN.

13:54:26.317519 IP6 2001:bb6:1205:9600:b853:909f:8962:9d51 > 2a00:1450:400b:c00::5e: ICMP6, echo request, seq 12, length 16 13:54:26.319371 IP6 2001:bb6:1205:9600::1 > 2001:bb6:1205:9600:b853:909f:8962:9d51: ICMP6, destination unreachable, unreachable route 2a00:1450:400b:c00::5e, length 64

root@turris:~# ip -6 route get 2a00:1450:400b:c00::5e from 2001:bb6:1205:9600:b853:909f:8962:9d51 2a00:1450:400b:c00::5e from 2001:bb6:1205:9600:b853:909f:8962:9d51 via fe80::ea4:2ff:feea:355b dev eth1 proto static src 2001:bb6:1205:9600::1 metric 512