Skip to content

Instantly share code, notes, and snippets.

@dfxdj
Created March 3, 2026 13:23
Show Gist options
  • Select an option

  • Save dfxdj/e4edcc87c64969ac64cc99e2e7c12046 to your computer and use it in GitHub Desktop.

Select an option

Save dfxdj/e4edcc87c64969ac64cc99e2e7c12046 to your computer and use it in GitHub Desktop.
Enabling IPv6 for WiFi-to-USB tethering on Android using proxy NDP

On your phone, pull up ip a ls and note the relevant interfaces (WiFi and the USB port):

panther:/ # ip a ls
...
48: wlan1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 86:45:56:22:79:e4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.166/24 brd 192.168.1.255 scope global wlan1
       valid_lft forever preferred_lft forever
    inet6 2001:470:5:401:534:654:dbe:43/64 scope global 
       valid_lft forever preferred_lft forever
    inet6 fe80::8445:56ff:fe22:79e4/64 scope link 
       valid_lft forever preferred_lft forever
50: ncm0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 12:58:65:04:4b:40 brd ff:ff:ff:ff:ff:ff
    inet 10.41.41.179/24 brd 10.41.41.255 scope global ncm0
       valid_lft forever preferred_lft forever
    inet6 fe80::1058:65ff:fe04:4b40/64 scope link 
       valid_lft forever preferred_lft forever
...

Inspect the state of policy routing with ip rule ls. If the phone has multiple routing tables, you will see a long list, including entries referencing the network interfaces:

panther:/ # ip rule ls
...
17000:	from all iif lo oif ncm0 lookup ncm0 
17000:	from all iif lo oif wlan1 lookup wlan1 
21000:	from all iif ncm0 lookup wlan1 
...

If present, note the name of the tables (lookup ...).

Check that IPv6 forwarding is enabled:

panther:/ # cat /proc/sys/net/ipv6/conf/all/forwarding                                                                              
1
panther:/ # 

Enable proxy NDP:

panther:/ # echo 1 > /proc/sys/net/ipv6/conf/all/proxy_ndp
panther:/ # 

Pick an address from your IPv6 prefix. My prefix is 2001:470:5:401::/64 so I will pick 2001:470:5:401::aaaa. Add this as a proxy neighbour on the WiFi interface:

panther:/ # ip neigh add proxy 2001:470:5:401::aaaa dev wlan1
panther:/ # 

Finally add a route for this address pointing to the USB interface. Note the use of /128 as prefix length. If your phone does not have policy routing and multiple routing tables, omit the table ncm0 portion. Use the appropriate table name if different from the interface name.

panther:/ # ip -6 r add 2001:470:5:401::aaaa/128 dev ncm0 table ncm0
panther:/ # 

On your PC, add the address to its USB interface. Also use /128 as prefix length.

rainbow:~$ sudo ip -6 a add 2001:470:5:401::aaaa/128 dev enx52263dffa7fb
rainbow:~$ 

Finally add a default gateway. Use the phone's link-local address from its USB interface:

rainbow:~$ sudo ip -6 r add default via fe80::1058:65ff:fe04:4b40 dev enx52263dffa7fb
rainbow:~$ 

These last two steps can be done through NetworkManager or whatever else handles static IPv6 configuration.

You should now have working IPv6.

rainbow:~$ ping google.com
PING google.com (2607:f8b0:4008:809::200e) 56 data bytes
64 bytes from lcmiaa-al-in-x0e.1e100.net (2607:f8b0:4008:809::200e): icmp_seq=1 ttl=119 time=52.6 ms
64 bytes from lcmiaa-al-in-x0e.1e100.net (2607:f8b0:4008:809::200e): icmp_seq=2 ttl=119 time=45.3 ms
64 bytes from lcmiaa-al-in-x0e.1e100.net (2607:f8b0:4008:809::200e): icmp_seq=3 ttl=119 time=49.9 ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment