Getting to the bottom of an OpenWRT IPv6 problem

It’s been quite a while since I’ve had a working IPv6 connection which is quite unforgivable in 2021. My ISP launched IPv6 support (in beta) back in 2018, but had to suspend the trial several times due to numerous bugs in Cisco’s routers.

Ultimately I ended up forgetting about IPv6 entirely during one of these periods and accepted that I was relegated to a world of legacy IPv4 addresses. That is until today when I decided to finally get IPv6 working again. It looked like my ISP had their IPv6 support back in full swing so it should have been easy.

The thing is though, I shouldn’t actually have had to do anything. I have a pretty simple setup, an old TP-Link wireless router flashed with OpenWRT is all that sits between me and the NBN NTD. OpenWRT was close to up-to-date and had an IPv6 WAN interface all ready to go, but for some reason it just wasn’t working.

I tried updating from 19.07.2 to the latest 19.07.5, but that made no difference.

Taking a look through the router’s system log showed a number of entries like this:

Tue Jan  5 02:50:00 2021 daemon.notice netifd: Interface 'wan6' has link connectivity
Tue Jan  5 02:50:00 2021 daemon.notice netifd: Interface 'wan6' is setting up now
Tue Jan  5 02:50:01 2021 daemon.err odhcp6c[5860]: Failed to send RS (Permission denied)
Tue Jan  5 02:50:02 2021 daemon.err odhcp6c[5860]: Failed to send DHCPV6 message to ff02::1:2 (Permission denied)
Tue Jan  5 02:50:03 2021 daemon.err odhcp6c[5860]: Failed to send DHCPV6 message to ff02::1:2 (Permission denied)
Tue Jan  5 02:50:05 2021 daemon.err odhcp6c[5860]: Failed to send RS (Permission denied)
Tue Jan  5 02:50:05 2021 daemon.err odhcp6c[5860]: Failed to send DHCPV6 message to ff02::1:2 (Permission denied)
Tue Jan  5 02:50:09 2021 daemon.err odhcp6c[5860]: Failed to send RS (Permission denied)
Tue Jan  5 02:50:09 2021 daemon.err odhcp6c[5860]: Failed to send DHCPV6 message to ff02::1:2 (Permission denied)
Tue Jan  5 02:50:13 2021 daemon.err odhcp6c[5860]: Failed to send RS (Permission denied)
Tue Jan  5 02:50:17 2021 daemon.err odhcp6c[5860]: Failed to send DHCPV6 message to ff02::1:2 (Permission denied)
Tue Jan  5 02:50:35 2021 daemon.err odhcp6c[5860]: Failed to send DHCPV6 message to ff02::1:2 (Permission denied)

An hour or more of Googling various words and phrases from those messages came up with nothing. Not one solution seemed to help. Nobody else who suffered from “Permission denied” errors or “Failed to send” errors seemed to have the same problem as I did.

After a bit of poking around in an ssh session[1] I noticed something quite unusual: the eth0.2 interface, a VLAN interface used by wan and wan6, didn’t have an IPv6 link-local address. Without that there was no way for the router to establish an DHCPv6 connection to the NBN NTD. Interestingly enough the eth0 interface did have a IPv6 link-local address.

root@OpenWrt:~# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000
    link/ether 00:00:5e:00:53:00 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::5eff:fe00:5300/64 scope link 
       valid_lft forever preferred_lft forever
root@OpenWrt:~# ip addr show eth0.2
9: eth0.2@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
    link/ether 00:00:5e:00:53:00 brd ff:ff:ff:ff:ff:ff
    inet 192.0.2.69/21 brd 192.0.2.1 scope global eth0.2
       valid_lft forever preferred_lft forever

(Potentially sensitive values have been replaced. 192.0.2.69 would be my public IPv4 address).

This seemed really strange. A bit more Googling led me to a blog post suggesting the net.ipv6.conf.*.addr_gen_mode sysctl could be to blame and that changing that setting could provide the missing link-local address I was searching for. I queried the settings associated with the eth0.2 interface and… well… something else jumped out at me.

root@OpenWrt:~# sysctl net.ipv6.conf.eth0.2
net.ipv6.conf.eth0.2.accept_dad = 1
net.ipv6.conf.eth0.2.accept_ra = 0
net.ipv6.conf.eth0.2.accept_ra_defrtr = 1
net.ipv6.conf.eth0.2.accept_ra_from_local = 0
net.ipv6.conf.eth0.2.accept_ra_min_hop_limit = 1
net.ipv6.conf.eth0.2.accept_ra_mtu = 1
net.ipv6.conf.eth0.2.accept_ra_pinfo = 1
net.ipv6.conf.eth0.2.accept_redirects = 1
net.ipv6.conf.eth0.2.accept_source_route = 0
net.ipv6.conf.eth0.2.addr_gen_mode = 0
net.ipv6.conf.eth0.2.autoconf = 1
net.ipv6.conf.eth0.2.dad_transmits = 1
net.ipv6.conf.eth0.2.disable_ipv6 = 1
net.ipv6.conf.eth0.2.disable_policy = 0
net.ipv6.conf.eth0.2.drop_unicast_in_l2_multicast = 0
net.ipv6.conf.eth0.2.drop_unsolicited_na = 0
net.ipv6.conf.eth0.2.enhanced_dad = 1
net.ipv6.conf.eth0.2.force_mld_version = 0
net.ipv6.conf.eth0.2.force_tllao = 0
net.ipv6.conf.eth0.2.forwarding = 1
net.ipv6.conf.eth0.2.hop_limit = 64
net.ipv6.conf.eth0.2.ignore_routes_with_linkdown = 0
net.ipv6.conf.eth0.2.keep_addr_on_down = 0
net.ipv6.conf.eth0.2.max_addresses = 16
net.ipv6.conf.eth0.2.max_desync_factor = 600
net.ipv6.conf.eth0.2.mc_forwarding = 0
net.ipv6.conf.eth0.2.mldv1_unsolicited_report_interval = 10000
net.ipv6.conf.eth0.2.mldv2_unsolicited_report_interval = 1000
net.ipv6.conf.eth0.2.mtu = 1500
net.ipv6.conf.eth0.2.ndisc_notify = 0
net.ipv6.conf.eth0.2.proxy_ndp = 0
net.ipv6.conf.eth0.2.regen_max_retry = 3
net.ipv6.conf.eth0.2.router_solicitation_delay = 1
net.ipv6.conf.eth0.2.router_solicitation_interval = 4
net.ipv6.conf.eth0.2.router_solicitation_max_interval = 3600
net.ipv6.conf.eth0.2.router_solicitations = -1
net.ipv6.conf.eth0.2.seg6_enabled = 0
sysctl: error reading key 'net.ipv6.conf.eth0.2.stable_secret': I/O error
net.ipv6.conf.eth0.2.suppress_frag_ndisc = 1
net.ipv6.conf.eth0.2.temp_prefered_lft = 86400
net.ipv6.conf.eth0.2.temp_valid_lft = 604800
net.ipv6.conf.eth0.2.use_oif_addrs_only = 0
net.ipv6.conf.eth0.2.use_tempaddr = 0

Spotted it? This little guy:

net.ipv6.conf.eth0.2.disable_ipv6 = 1

The network interface that I had been trying to establish an IPv6 connection with for months on end, had IPv6 entirely disabled. Could it really be that easy? It turns out yes. It was exactly that easy.

A simple command to re-enable IPv6:

root@OpenWrt:~# sysctl -w net.ipv6.conf.eth0.2.disable_ipv6=0

…and restart the wan6 interface.

OpenWRT WAN6 interface showing IPv6 address and IPv6-PD prefix.
1.1.1.1/help showing successful IPv6 connections.

Voila! A working IPv6 internet connection.

The only thing left to do was to add the setting to /etc/sysctl.conf[2] so it would persist across reboots. (I think this step was necessary anyway).

I really have no idea what changed since I last had IPv6 working, perhaps an OpenWRT update broke things. I’m not the first person to stumble upon this strange default setting though, someone posted about it on the OpenWRT forum back in August of 2020. (fantom-x I hope you figured it out too).

It seems like the OpenWRT kernel might be automatically disabling IPv6 support on any VLAN-ed interface. Who knows why. Perhaps my configuration isn’t quite standard, though I don’t see how.

In the end I now have a working IPv6 internet connection and it only took until 2021. This year’s already improving.


  1. After applying the workaround in this issue to connect to the rather out-of-date ssh daemon. ↩︎

  2. I installed nano to do this because I will never understand vim. ↩︎