IPv6 not working on Android, no default route?

There are several topics similar to this one, but none of the answers provided there solved my problem.

Summary: IPv6 works fine, both DHCPv6 and SLAAC, for all devices on my LAN except Android devices. I'm using dnsmasq for IPv4 and odhcpd for IPv6.

IPv6 on the same Android devices works on other networks. It used to work on those Android devices, and either a change to Android, OpenWRT, or my settings broke it. I know Android has the SLAAC only IPv6 setup, so I have confirmed that IPv6 works with other devices when I force them to use SLAAC.

My ISP gives me a /60, and my OpenWRT router picks a /64 for LAN and uses that to hand addresses out to various devices. All sensible and normal.

Android devices receive two GUA addresses and a ULA address, but cannot use IPv6. This seems to be because no default IPv6 route is set.

Android routes when IPv6 does NOT work
Route: fe80::/64 -> :: wlan1 mtu 0
Route: 2001:db8:6500:ae97::/60 -> fe80::f6f2:6dff:fe70:3132 wlan1 mtu 0
Route: 2001:db8:6500:ae97::/64 -> :: wlan1 mtu 0
Route: 192.168.1.0/24 -> 0.0.0.0 wlan1 mtu 0
Route: 0.0.0.0/0 -> 192.168.1.6 wlan1 mtu 0
Gateway: 192.168.1.6
Android routes when IPv6 does work
Route: fe80::/64 -> :: wlan1 mtu 0
Route: ::/0 -> fe80::9258:51ff:febb:b19c wlan1 mtu 0
Route: 2001:db8:4650:08dc::/64 -> :: wlan1 mtu 0
Route: 10.0.0.0/24 -> 0.0.0.0 wlan1 mtu 0
Route: 0.0.0.0/0 -> 10.0.0.1 wlan1 mtu 0
Gateway: 10.0.0.1

The missing ::/0 route probably explains why Android can't use IPv6, but why is the route missing?

Here are the relevant configuration sections from my router:

/etc/config/network
config interface 'lan'
	option proto 'static'
	option ipaddr '192.168.169.6'
	option netmask '255.255.255.0'
	option ip6assign '64'
	option stp '1'
	option device 'br-lan'
	option delegate '0'

config interface 'wan6'
	option proto 'dhcpv6'
	list dns '2606:4700:4700::1111'
	list dns '2606:4700:4700::1001'
	option reqaddress 'try'
	option peerdns '0'
	option reqprefix 'auto'
	option device 'eth0.2'
/etc/config/dhcp
config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '1h'
	option ra 'server'
	option dhcpv6 'server'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option ra_maxinterval '600'
	option ra_mininterval '200'
	option ra_lifetime '1800'
	option ra_mtu '1500'
	option ra_hoplimit '64'

config odhcpd 'odhcpd'
	option maindhcp '0'
	option leasefile '/tmp/hosts/odhcpd'
	option leasetrigger '/usr/sbin/odhcpd-update'
	option loglevel '6'


Anything obviously wrong? Tips to debug this? Solutions?

I have a /60 also with an android phone on the lan and IPv6 always seems to get a route out, so I'm assuming my default is in place the whole time. (How do I see the default route on android? I can only find my IPv4 and IPv6 host addresses but not the routing table.)

In any case, I see one suspicious difference between our dhcp lan settings. Yours is missing the "option ra_default '2' " .

config dhcp 'lan'
	option interface 'lan'
	option start '100'
	option limit '150'
	option leasetime '12h'
	option dhcpv4 'server'
	option ra 'server'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option ra_default '2'

Use RA only (disable DHCPv6) and enable SLAAC

config dhcp 'lan'
	option interface 'lan'
	option leasetime '1h'
	option dhcpv4 'server'
	option start '100'
	option limit '150'
	option ra 'server'
	option ra_slaac '0'

I use the Ping & Net app. The interface takes a few minutes to figure out, but it is very useful for network debugging. The routes are under the "Network Info" button.

If I'm understanding correctly, that has to do with announcing a route (sounds promising). In luci 2 is described as "force announcing a route," but on the odhcpd docs page 2 is "ignore all".

For me, it causes odhcpd to log (split for readability)

odhcpd[21017]: Address 2001:db8:6500:ae97::1
(dprefix 0, valid 417829) not suitable as RA route on lan

Is that just because the route should be to the link-local address, or does it represent a different problem?

Toggling the value of ra_default does not fix IPv6 on Android.

Is that just a typo, doesn't 0 disable slaac? I tried 0 (with DHCPv6 off), and that disables IPv6 completely for downstream devices.

I turned off DHCPv6, and went slaac only (ra_slaac=1), and my ipad was able to use IPv6, but it's still not working on Android.

Thank you for the suggestions.

True, my mistake, sorry.
Shound be:

config dhcp 'lan'
	option interface 'lan'
	option leasetime '1h'
	option dhcpv4 'server'
	option start '100'
	option limit '150'
	option ra 'server'

Unfortunately that doesn't work either. Other devices are happy with slaac only, but Android refuses to participate.

I didn't edit the config files directly but used the luci web interface. That might have done extra compatibility changes elsewhere.

interfaces -> lan -> use default gw: checked
interfaces -> lan -> delegate IPv6 Prefixes: checked
interfaces -> lan -> DHCP Server -> IPv6 Settings -> RA-Service: server mode
interfaces -> lan -> DHCP Server -> IPv6 RA Settings -> Default Router: forced
interfaces -> lan -> DHCP Server -> IPv6 RA Settings -> Enable SLAAC: checked
interfaces -> lan -> DHCP Server -> IPv6 RA Settings -> RA Flags: Managed config (M) other config (O)

Those are the settings I have with two (maybe important?) differences.

I only get a /60 from my ISP (it used to be a /56, why the shrinkage Comcast?), so I was not delegating from lan to downstream hosts. I turned on delegation just to see what would happen, and it did not fix the Android problem. It also offered the same /64 delegated to lan to clients, which is not good.

I also have default router set to automatic. I can set it to forced, and that gets me the error about the GUA address on lan not being a suitable route, and it doesn't fix the Android problem. Everything else still works, so I assume it's offering the link local address as a route, but I haven't verified that.

Just as an aside, the /64 delegated to the lan is exactly what you want. The rest of the /60 pool you have is space that you can use to give to any downstream routers for their prefix-delegations.

It's been awhile, but I want to come back to this, because I believe I found the solution, and it's not OpenWRT related, though testing tricked me into thinking it was.

The cause I've identified is the "Proxy ARP"[1] option on my Ubiquiti Unifi APs. Turning this option on breaks SLAAC on Android, but not on other devices. Turning it off gets IPv6 working again. Proxy ARP breaks IPv6 on Android, even if connected to a non-Unifi AP on the same network.

Long story:

Between the original post and now I changed ISPs from Comcast Business to Xfinity Residential, and stopped using my OpenWRT based router. Using the ISP's equipment I thought would definitely make IPV6 work on Android (that's not why I switched), but it was still broken.

My original setup was OpenWRT router (no wifi) to Unifi APs. My current setup is ISP's router (no wifi) to Unifi APs. In both cases Android IPV6 does not work on the Unifi APs and if I (turn on and) connect directly to the WiFi on the router (either OpenWRT or ISP's). You can see how this result would leave me to believe the Unifi APs didn't matter---I can take them out of the mix, and still see the problem.

I have another location with the ISP's router and Unifi APs and Android IPv6 does work there. I compared the WiFi configuration at each location, and found Proxy ARP was the important difference. I do not know exactly how Proxy ARP is breaking IPv6 on Android, or why non-Android devices using SLAAC work fine when Proxy ARP is enabled.


  1. Reduce airtime by allowing APs to "proxy" common broadcast frames as unicast. The reduction in airtime usage can improve latency, however this may cause connectivity issues in some networks. ↩ī¸Ž

Why do you have proxy arp in place in the first place?!

1 Like

It is just an option when configuring WiIFi on Unifi. It is recommended for large and complex installations. Two APs and 30 some clients is neither large nor complex, but other than IPv6 with Android, it had no negative impacts I detected.

My suspicion, and I have no evidence of this, just vague memory, is that something on OpenWRT or Android changed, causing IPv6 on Android to stop working (passive voice...it could have been a change with an update, or something that I changed for some reason). Knowing it was some sort of issues with broadcasts, I turned on Proxy ARP, as it is supposed to help with broadcast latency. Once that was on, nothing was going to fix the IPv6 on Android issue.

Perhaps whatever was wrong on OpenWRT was fixed, perhaps not. Because of my new ISP I'm not able to test my old OpenWRT router with my known-working Unifi setup.

What I do find interesting is that when Proxy ARP is enabled, IPv6 is broken on Android devices even when they are connected to a WiFi network originating on the OpenWRT router or the LAN WiFi network originating on the Xfinity residential router. However, when using the "xfinity" public WiFi on the Xfinity router, which is completely isolated from my LAN, IPv6 on Android does work.

Mostly this and my other reply today are Google fodder. Based on my searches trying to solve my issues the Android IPv6 is a delicate flower that is easily broken. I'm sure my solution will not fix everyone's problems, but at least it can put a conclusion on this thread.

Says who? 'cause I doubt that...

It sounds to me that you are not right sure about what Proxy ARP actually does? Do you?

TL;DR; with Proxy ARP the router does answer all ARP Requests with its own mac address. So yes, this could lower "latency" on the local network, but, if you have "latency" issues on a LAN segment, I think you have other issues to solve, and Proxy ARP hardly does not seam to be the correct solution...


And it makes absolutely no sense why Proxy ARP would break IPv6 in the first place and at all.
IPv4 and IPv6 are two completely independent protocols. IPv4 uses ARP to fill the (layer-2) neighbor table, but IPv6 uses Neighbor Discovery Protocol (NHP) to build the (layer-2) neighbor table.

It's on this Ubiquiti best practices document, for one thing. Though for "very large networks".

Do you? The name is probably very poorly chosen, but I didn't pick it. On Ubiquiti "Proxy ARP" is really ARP caching. Broadcast packets on WiFi slow things down, so the AP answers ARP requests itself instead of sending a broadcast out, because the AP already knows the MAC address of all it's wireless clients.

No, it does not, which is why it took me so long to see it as a problem. It was only when I compared working and non-working configurations that I found "Proxy ARP" to be the difference. If it had been something like "Proxy NDP" I probably would have found the problem right away.

I've not bothered to do packet captures to see what is going on, but the cause and effect is very clear. Proxy ARP on = no IPv6 on Android; Proxy ARP off = IPv6 on Android. The state of Proxy ARP does not cause a problem with SLAAC on Mac, Linux, Windows, or IOS, just Android.

First, I don't wanted to sound rude. Sorry if that's was the case. I was just curious :slight_smile:

Mhm, yes I see that proxy arp is just a step while enabling arp cache. Normal people would have just called it a "timer" which every managed switch and AP already has. So I don't get their intention either.

I hopefully do because I had to use it a few times so get either legacy deployments running or enable them to move to newer deployments. But it's anyway every time a crude hack.

Yes I get to idea. BUT this is anyway just for the first time an IP address is used, either from a sender or when used as a destination. After the initial answering the ARP and NHS information is in the neighbor table and it's cached because it has a timeout.... So I still don't get ubnts intention.
And just in case: I don't wanna argument against you.

@Phaquum
Do you have by any chance a capture of the router advertisement sent?

For everyone else still reading and is not sure about it, see https://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.bridging.proxy-arp.html which is kinda old but still good to use.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.