IPv6 works on Windows but not Linux and Android

My ISP gives /64 IPv6 address and I set up odhcpd to relay RA/DHCPv6/NDP requests. My windows laptop works fine and has IPv6 access all the time but for my other clients, the IPv6 connection is unstable.

My Android and iOS devices get 2-3 IPv6 addresses, but they cannot ping or open IPv6 websites. And some time after connecting to the network, i can access ipv6 but as soon as i restart the network, ipv6 connection lost (i.e. ipv6 won't work on boot but it may work after some time)

For linux devices, some don't get IPv6 address at all (seems to fail by DAD) and some get one but can only ping router and lan addresses. These clients also get IPv6 connection after some time but lose it immediately after reboot. I do have one Linux host that can connect to IPv6 all the time, though.

Is there a way for me to debug this?

Anything different between this host and the other Linux devices? That can give you a clue as to what's going on.

In any case, you may find it helpful to run a capture session using Wireshark on one of the affected machines. In particular I would pay attention to the Neighbor Discovery ICMPv6 packets.

Also please tell us your OpenWrt version and DHCP configuration. SSH into the router and invoke this command:

ubus call system board

and this command:

cat /etc/config/dhcp

Paste the output of those two commands here. Please be sure to use the </> button in the editor toolbar to correctly display the command outputs.

Have you considered specifying only one type of relaying via odhcp? Per android does not use dhcpv6 and must use slaac.

By enforcing odhcpd to use only one kind of relay/configuration method to a 'lowest common denominator' you will simplify troubleshooting.

Hi! Thanks a lot for your guidance.

For ubus call system board, I got

{
        "kernel": "5.15.137",
        "hostname": "H3C-Magic-NX30-Pro",
        "system": "ARMv8 Processor rev 4",
        "model": "H3C Magic NX30 Pro",
        "board_name": "h3c,magic-nx30-pro",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "23.05.2",
                "revision": "r23630-842932a63d",
                "target": "mediatek/filogic",
                "description": "OpenWrt 23.05.2 r23630-842932a63d"
        }
}

And for cat /etc/config/dhcp, I got

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'
        option sequential_ip '1'
        option allservers '1'

config dhcp 'lan'
        option interface 'lan'
        option start '201'
        option limit '250'
        option leasetime '12h'
        option dhcpv4 'server'
        option ra 'relay'
        option force '1'
        option dhcpv6 'relay'
        list dhcp_option '3,192.168.1.1'
        list dhcp_option '6,192.168.1.1'
        option ndp 'relay'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'
        option master '1'
        option ra 'relay'
        option dhcpv6 'relay'
        option ndp 'relay'

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

Anything different between this host and the other Linux devices?

Besides the very host has tailscale setup, i haven't think of any other differences yet.

In any case, you may find it helpful to run a capture session using Wireshark on one of the affected machines. In particular I would pay attention to the Neighbor Discovery ICMPv6 packets.

tcpdump -i eth0 -n -vv '(udp port 546 or 547) or icmp6' Does this command do the same work or wireshark is better?

Hi! I've tried to disable DHCPv6 and that didn't help. Is their another way to relay SLAAC only? Btw, this issue does not limit to Android but all devices (seemingly) except windows

You've set the IPv4 WAN interface as the designated master for the IPv6 relay function, which doesn't make sense. This should be on the IPv6 WAN6 interface instead.

Put the WAN interface back to the default configuration. I believe it should be:

config dhcp 'wan'
    option interface 'wan'
    option ignore '1'

Then append a section for WAN6, in the same /etc/config/dhcp file:

config dhcp 'wan6'
    option interface 'wan6'
    option ignore '1'
    option master 1'
    option ra 'relay'
    option dhcpv6 'relay'
    option ndp 'relay'

Then reboot the router and reconnect the clients.

Hi! I've updated dhcp conf to the following:

config dnsmasq
        option domainneeded '1'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option cachesize '1000'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option localservice '1'
        option ednspacket_max '1232'
        option sequential_ip '1'
        option allservers '1'

config dhcp 'lan'
        option interface 'lan'
        option start '201'
        option limit '250'
        option leasetime '12h'
        option dhcpv4 'server'
        option ra 'relay'
        option force '1'
        option dhcpv6 'relay'
        list dhcp_option '3,192.168.1.1'
        list dhcp_option '6,192.168.1.1'
        option ndp 'relay'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

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


config dhcp 'wan6'
        option interface 'wan6'
        option ignore '1'
        option master '1'
        option ra 'relay'
        option dhcpv6 'relay'
        option ndp 'relay'

And rebooted router, hosts. However, the host still won't connect to IPv6 after reboot for example
curl: (7) Failed to connect to ip.sb port 80: Network is unreachable

ping6 ip.sb
PING ip.sb(2606:4700:20::681a:d1f (2606:4700:20::681a:d1f)) 56 data bytes
From _gateway (local ipv6 addr%eth0) icmp_seq=1 Destination unreachable: No route
From _gateway (local ipv6 addr%eth0) icmp_seq=2 Destination unreachable: No route
From _gateway (local ipv6 addr%eth0) icmp_seq=3 Destination unreachable: No route
From _gateway (local ipv6 addr%eth0) icmp_seq=4 Destination unreachable: No route

--- ip.sb ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3060ms

Also, the host gets IPv6 after some time during my experiment but lost when device reboots (but ipv6 persists after systemctl restart NetworkManager)

Share the output of ifstatus wan6

My host's NetworkManager seems to get stuck in such a cycle:

platform-linux: do-add-ip6-address[2: xxxx]: success
ndisc-lndp["eth0"]: processing libndp events
platform: (eth0) signal: address 6 removed: 
l3cfg[d0ef2b1e1521ce3f,ifindex=2]: obj-state: remove from platform: 
ndisc-lndp["eth0"]: processing libndp events
ndisc-lndp["eth0"]: received router advertisement at timestamp 520.825 seconds
ndisc["eth0"]: router-data: next lifetime expiration will happen: in 1800.000 seconds

per this rfc the managed flag being set is a problem for android:

https://issuetracker.google.com/issues/36949085

https://openwrt.org/docs/techref/odhcpd

Thank you.

My ifstatus wan6 has the following output:

{
        "up": true,
        "pending": false,
        "available": true,
        "autostart": true,
        "dynamic": false,
        "uptime": 1070,
        "l3_device": "eth1",
        "proto": "dhcpv6",
        "device": "eth1",
        "metric": 0,
        "dns_metric": 0,
        "delegation": true,
        "ipv4-address": [

        ],
        "ipv6-address": [
                {
                        "address": "local address",
                        "mask": 64,
                        "preferred": 172776,
                        "valid": 259176
                }
        ],
        "ipv6-prefix": [

        ],
        "ipv6-prefix-assignment": [

        ],
        "route": [
                {
                        "target": "xxx",
                        "mask": 64,
                        "nexthop": "::",
                        "metric": 256,
                        "valid": 259176,
                        "source": "::/0"
                },
                {
                        "target": "::",
                        "mask": 0,
                        "nexthop": "xx",
                        "metric": 512,
                        "valid": 1776,
                        "source": "xx/64"
                }
        ],
        "dns-server": [

        ],
        "dns-search": [

        ],
        "neighbors": [

        ],
        "inactive": {
                "ipv4-address": [

                ],
                "ipv6-address": [

                ],
                "route": [

                ],
                "dns-server": [

                ],
                "dns-search": [

                ],
                "neighbors": [

                ]
        },
        "data": {

        }
}

Should I try the config you previously posted?

Hi! Is it possible to relay in slaac mode?

Maybe the problem with Android doesn't matter most, my Linux device also failed. I am curious how Linux/Android/macOS's implementation differs from that of Windows.

yes, please do

Edit /etc/config/network file and put this under wan6 interface.
option ip6prefix 'aaa:bbb:ccc:ddd::/64'

Where aaa:bbb:ccc:ddd is your first 64bits wan6 address.

In Lan Ra and dhcpv6 to server mode (can also be in relay mode but for Android clients need to be server)and ndp to relay mode, in wan6 all to relay mode.

After adding the above line , be sure to restart interface. And hopefully it would work.

1 Like

After changing LAN's RA/DHCPv6 to server mode, my host receives a local IPv6 and a global IPv6 address (the global one with DADFAILED flag), and I still cannot connect to external wan.

    inet6 global_address/64 scope global dadfailed tentative noprefixroute 
       valid_lft forever preferred_lft forever
    inet6 local_address/64 scope global noprefixroute 
       valid_lft forever preferred_lft forever

My guess is that somehow NDP relay was not working and DAD gets false positives?

I think the host gets IPv6 after some time is because it succeeds DAD after some time.

Will ndp be cached in my upstream NDP? How should I monitor ndp protocal and see how the messages were transmitted?

What's the current status of ifstatus wan6 after modification?

"ipv6-prefix": [
                {
                        "address": "The prefix specified",
                        "mask": 64,
                        "class": "wan6",
                        "assigned": {
                                "lan": {
                                        "address": "The prefix specified",
                                        "mask": 64
                                }
                        }
                }
        ],

I received one prefix and the rest looks the same

After all this experimenting and different addresses being assigned to different hardware, the ISP could have some type of fail2ban or blocks automatically raised (firewall).

If you have any rooted android there are tools available in play store and elsewhere for troublshooting ipv6.

On your linux machine you can test with some of these commands:

https://tldp.org/HOWTO/Linux+IPv6-HOWTO/ch04s03.html

Maybe all this clients reconnects too fast, and after reboot IPv6 is disabled. And after some time, the ban was lift, thus the device can connect again.

But why windows is not limited by this?