DHCPv6 from upstream /64 prefix from ISP's LTE router

I am using OpenWrt 21.02 and trying to assign IPv6 addresses from a /64 prefix provided by the ISP to devices on the LAN.

My ISP device happens to be a portable Android-based LTE hotspot device that is plugged into the router's USB port, so it behaves very similar to an Android phone with USB tethering turned on. An Android device doesn't support DHCPv6 or PD, and it announces the /64 prefix directly in the RA.

Below is a screenshot of the RA captured by Wireshark when the device is plugged into a PC's USB port:

What I aim to do:

Use DHCPv6 to have more control over how the /64 prefix is utilised downstream and do stuff like:

  • Use PD to delegate the prefix to downstream routers
  • Have control over which devices are assigned what address by tuning parameters like ip6hint
  • Customise options like DNS servers in the RA
  • ... and so on

My configuration:

  • usb6 is my WAN IPv6 interface (network.usb6=interface)
  • network.globals.ula_prefix is empty as I want only global routable addresses and no ULA in my LAN
  • usb6 interface is added to the firewall's wan zone
  • The default Allow-ICMPv6-Input and Allow-ICMPv6-Forward firewall rules are intact as they are necessary to work with RAs, but Allow-DHCPv6-Input is redundant and hence, removed.

What I tried:

  1. When I use proto dhcpv6 on usb6, an IPv6 address is assigned to the interface, however the prefix is not announced or assigned using DHCPv6 on the LAN side (despite using dhcpv6 server and ra server in DHCP lan configuration).

  2. Enabling IPv6 RA relay as mentioned here works: all devices on the LAN derive their addresses from the /64 that was announced, but that doesn't leave me with any control over how the prefix is utilised.

I further dug into how DHCPv6 works in OpenWrt and found that odhcp6c obtains information from the WAN IPv6 interface and calls the script /lib/netifd/dhcpv6.script with the obtained information in environment variables and the action performed in the arguments.

My findings:

I created the custom script /etc/odhcp6c.user that prints the output of set to a file so that I could see what is happening under the hood.

In the dhcpv6.script file,

  • The environment variable PREFIXES is supposed to contain the list of prefixes obtained from prefix delegation, and it can be further utilised by DHCPv6. In my case, this variable was not set, probably because the prefix came from RA, and not from PD.

  • Further below, I found this interesting part that talks about RFC 7278. This seemed to be exactly what I wanted - extending the /64 prefix that is recieved on the WAN. On inspecting using my custom script, I noticed that the $EXTENDPREFIX variable was not set. Where did this come from? :thinking:

I searched through OpenWrt's commit history and found 2 commits (at the time of writing) related to this.

An option called extendprefix seems to be introduced in this commit that is setting the $EXTENDPREFIX variable to 1. This option is not documented in the wiki for IPv6 configuration.

I changed my network.usb6 configuration to include network.usb6.extendprefix='1' and set dhcp.lan.dhcpv6 and dhcp.lan.ra back to 'server', and now it works!

I believe this missing option should be added to the wiki.

2 Likes

Another heads-up for anyone trying to achieve a similar configuration with an upstream /64 prefix from the ISP's router:

Most likely in such a configuration, the ndp relay must be active for internet to work, otherwise you'll get Request timed out errors for all traffic going out of your prefix

config dhcp lan
    option interface lan
    ...
    option ndp relay
    option ndproxy_slave 1   # optional

config dhcp usb6
    option interface usb6
    option ignore 1          # https://github.com/openwrt/openwrt/issues/5723
    option ndp relay
    option master 1

This is essential for the neighbour discovery messages to pass between the WAN interface and LAN so that when a packet is routed towards the ISP device from the internet, it can be routed to the device on the LAN which has the address from the /64 prefix, else it is dropped.

1 Like

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