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 brd scope global eth0.2
       valid_lft forever preferred_lft forever

(Potentially sensitive values have been replaced. 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. 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. ↩︎

Not with a bang, but an insult

I’ve had very few negative experiences in the open source software world. Though that’s not an experience shared by all, I’m no doubt spared much by my gender—my tendency to be shy and reserved contributes of course.

In years past I developed WordPress plugins and themes with PHP being my most familiar language—I’ve forgotten more PHP by now than I ever knew in the first place. I published a total of three plugins for WordPress circa 2010 when I was just 13 years old. I’d update them again several years later in 2013, but this would prove to be the end of my time shared with WordPress.

WordPress was a bit of Wild West when I knew it, plugins would walk all over each other and code quality was seldom high, and my plugins were no different—they’d be improved in their respective ‘version 2.0s’. I’d hope things had improved since then.

Eventually my plugins rotted; they hadn’t been updated in over five years and I have no doubt it showed. While I’d long discarded the code I was once proud of, others hadn’t. My most popular plugin still shows 7000+ active installs—something, something, vulnerable software.

GitHub introduced archived repositories that are well worth using for that long forgotten code.

We’ve all found that project that is just right for us, that project that does exactly what you need, but as is often the case, that project is simply dead. That tends to be clear when you see the date on that last commit and you know to keep searching. Some people chose a different response.

Until this year my plugin had only one review, of 4 stars:

"Such an Awesome plugin!" review

That changed six months ago when the following two reviews, both one star, were left:

"Useless shit" review
"Useless dangerous plugin" review

It ought to have been obvious to anyone that the plugin was long since past being maintained, and ought to have been passed by. even go to the trouble of warning users that a plugin is outdated[1], so it surprises me that people would go out of their way to denigrate it.

If you’ve read this far, you’re probably wondering what my point was in writing this. Truth be told, I’m not quite sure I have one.

There’s a point to made about civility, and one to be made about riding other people’s coat tails without compensation, and a point to be made about expectations we put on others. I’m not about to make those points, at least not today.

I suppose the most fitting conclusion to this post is a simple email exchange, a rather unfitting goodbye.

Date: Thu, 03 May 2018 20:52:20 +0930
Subject: Close old plugins


I’d like to request the following three of my plugins be closed:

This is the procedure outlined in:

Kind Regards,
Tom Thorogood.

Date: Thu, 3 May 2018 14:05:26 +0000
Subject: Re: Close old plugins

Per your request, the plugin page has been closed. Please note it will remain available via SVN, but it will no longer be downloadable from the directory.

Please note: By asking for your plugin to be removed you are asking for a permanent change. This is not meant to be a stop-gap so you can work on a new version, it’s intended as a final closure for code that you will no longer work on. Should you return and ask us to reopen it, be prepared to justify your initial request and explain in detail the reasons you would like the plugin listing back.

Ipstenu (Mika Epstein)

  1. Unmaintained plugin notice ↩︎