Disable IPv6 with OpenWRT

When I use stock Linksys firmware on my router, my networked devices properly use IPv4 only to access the Internet.

When I use OpenWRT 15.05.1, the devices try to connect to various sites using IPv6 addresses, which would be great if my ISP provided IPv6 service, which it doesn't.

I've tried a few things which haven't worked: turning off DHCPv6, disabling the DNS caching of dnsmasq, setting dnsmasq's DHCP server to provide a static DNS server address (8.8.8.8), and setting OpenWRT's internal DNS server setting to use that DNS server.

How do I get OpenWRT to stop telling devices that it's OK to use IPv6?

Results of commands on one of the networked devices

The results of ip addr are:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp6s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:1a:80:7a:4e:47 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.107/24 brd 192.168.1.255 scope global dynamic enp6s0
       valid_lft 42521sec preferred_lft 42521sec
    inet6 fd7f:77c6:629f::9e8/128 scope global 
       valid_lft forever preferred_lft forever
    inet6 fd7f:77c6:629f::4e3/128 scope global 
       valid_lft forever preferred_lft forever
    inet6 fd7f:77c6:629f:0:21a:80ff:fe7a:4e47/64 scope global noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 fe80::21a:80ff:fe7a:4e47/64 scope link 
       valid_lft forever preferred_lft forever
3: wlp2s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:1d:e0:44:04:57 brd ff:ff:ff:ff:ff:ff

The results of route -6 are:

Kernel IPv6 routing table
Destination                    Next Hop                   Flag Met Ref Use If
fd7f:77c6:629f::4e3/128        ::                         U    256 0     0 enp6s0
fd7f:77c6:629f::9e8/128        ::                         U    256 0     0 enp6s0
fd7f:77c6:629f::/64            ::                         U    100 1     3 enp6s0
fd7f:77c6:629f::/48            fe80::c256:27ff:fe77:37a7  UG   100 0     0 enp6s0
fe80::/64                      ::                         U    256 2    10 enp6s0
::/0                           ::                         !n   -1  1   729 lo
::1/128                        ::                         Un   0   3     6 lo
fd7f:77c6:629f::4e3/128        ::                         Un   0   1     0 lo
fd7f:77c6:629f::9e8/128        ::                         Un   0   1     0 lo
fd7f:77c6:629f:0:21a:80ff:fe7a:4e47/128 ::                         Un   0   2     3 lo
fe80::21a:80ff:fe7a:4e47/128   ::                         Un   0   2    30 lo
ff00::/8                       ::                         U    256 2    67 enp6s0
::/0                           ::                         !n   -1  1   729 lo

The results of both ping6 google.com and ping6 2607:f8b0:4008:808::200e are:

connect: Network is unreachable

On initial installation (or settings reset) OpenWrt generates a Unique Local Address prefix and assigns ULAs to all the devices in the network, allowing them to communicate internally via IPv6 even without global IPv6 connectivity.

This generally works fine, except in two scenarios:

  1. An end device attempts to route global IPv6 traffic anyway, despite this address range not being usable for that purpose. Your routing table doesn't indicate that this is what is happening, and no commonly used operating system from the last decade or so would be doing this.
  2. An application misbehaves, and attempts to make global IPv6 connections when the computer does not have global IPv6 connectivity (or more specifically, a default route). From your description, this seems to be what is going on.

To be explicit: By advertising a ULA prefix, OpenWrt is not telling your devices that it's OK to access the Internet via IPv6. It is only telling them that it's OK to access your home network via IPv6.

The long-term solution is to fix the misbehaving applications. If you have run into this behavior in a particular application, you should report it as a bug to its developers.

The short-term workaround is to have OpenWrt not advertise a ULA prefix. You can go to Network > Interfaces, blank out the IPv6 ULA-Prefix box, and click Save & Apply. This will prevent OpenWrt from advertising a ULA prefix. If you ever reset your router's settings to defaults, you may need to do this again.


A simpler approach would be to SSH into your OpenWrt router and execute the following commands:

uci set 'network.lan.ipv6=off'
uci set 'network.wan.ipv6=off'
uci set 'dhcp.lan.dhcpv6=disabled'
/etc/init.d/odhcpd disable
uci commit

The first command disables the IPv6 LAN interface, the second the IPv6 WAN interface, the third and fourth disables the DHCPv6 Server and uci commit commits the changes.

UPDATE

It seems my information has not aged well... The settings are a bit different and these are additional bits. The information should now be up to date for 2021.

The syntax got changed a bit:

uci set 'network.lan.ipv6=0'
uci set 'network.wan.ipv6=0'
uci set 'dhcp.lan.dhcpv6=disabled'
/etc/init.d/odhcpd disable
uci commit

and then disable RA and DHCPv6 so no IPv6 IPs are handed out:

uci -q delete dhcp.lan.dhcpv6
uci -q delete dhcp.lan.ra
uci commit dhcp
/etc/init.d/odhcpd restart

You can now disable the LAN delegation:

uci set network.lan.delegate="0"
uci commit network
/etc/init.d/network restart

You might as well disable odhcpd:

/etc/init.d/odhcpd disable
/etc/init.d/odhcpd stop

And finally you can delete the IPv6 ULA Prefix:

uci -q delete network.globals.ula_prefix
uci commit network
/etc/init.d/network restart