Using DHCPv6-PD on Ubuntu 20.04 with systemd-networkd to route multiple prefixes

Note that this post assumes you already have extensive experience with Linux and IPv6. Most people are much better off using a distribution such as OpenWRT that handles all of this complexity for you. If you want to know why IPv6 matters, check out Akamai's blog post on "10 Years Since World IPv6 Launch".


The systemd-networkd service in Ubuntu 20.04 has enough support for DHCPv6-PD to obtain a prefix from an upstream ISP and subdivide it across local subnets, providing a /64 per subnet. For example, Comcast provides a /60 which has enough space for 16 subnets.

As far as I can tell, the ability to debug what is going on here or obtain state is almost entirely lacking. This makes it very hard to use troubleshoot issues or even tell what is going on.

Because netplan doesn't have enough features to configure DHCPv6-PD yet (see, some of the configuration needs to live in systemd-networkd overrides.

Configuring the Interfaces

I am assuming starting with a netplan configuration like the following:



    eno1:    # ISP1
      dhcp4: true
      dhcp6: true
      accept-ra: true
      ipv6-privacy: false
        search: [ ]
        use-dns: false
        use-hostname: false
        use-ntp: false
        use-dns: false
        use-hostname: false
        use-ntp: false

    eno2:    # LAN
      dhcp4: false
      optional: true

  version: 2


      id: 6
      link: eno2
      dhcp4: no
      optional: true

      id: 7
      link: eno2
      dhcp4: no
      optional: true

This has interfaces:

  • eno1 = WAN
  • eno2 = Primary LAN
  • en-main = Main VLAN
  • en-guest = Guest VLAN

While netplan and systemd-networkd somehow collaborate to put this netplan config into files such as /run/systemd/network/, there is no way to get the rules needed for enabling DHCPv6-PD into those dynamically generated files in /run.

Thankfully, you can put overrides in that systemd-networkd will read. See the man page for more details on all of the options available for these files.

To configure a DHCPv6-PD client on the WAN interface (eno1 in my case), create /etc/systemd/network/ :



You can specify a smaller value for PrefixDelegationHint if needed (eg, /60 for Comcast Residential).

For each of the LAN interfaces, create files such as /etc/systemd/network/ and /etc/systemd/network/ with:



Note that if you want to use both DHCPv6 provided addresses and your own (eg, to mix in ULA) this may be possible by setting IPv6PrefixDelegation=true, but I have not tried this.

Loading Changes

You can either reboot, or you can restart systemd-networkd with:

systemctl restart systemd-networkd


Some big caveats I've noticed:

  • The IPv6 address on the WAN link (eg, eno1) comes from an RA ND assignment, not a DHCPv6 prefix
  • The individual LANs/VLANs don't appear to get IPv6 addresses assigned. I haven't yet figured out how to get on-link addresses. As such, ip addr won't show addresses on those links.

Testing and Debugging

As of the systemd-networkd in Ubuntu 20.04 there aren't good ways to tell what is going on. In particular, networkctl status provides either no information or misleading information.

Some things that may be helpful:

  • ip -6 route list will list the prefixes assigned to the interfaces
  • rdisc6 en-guest will do router discovery on that interface (eg, en-guest in this case) and will show the assigned prefix
  • Doing a tcpdump -s 1500 -vvv -i eno1 port 546 or port 547 and then a systemctl restart systemd-networkd will show the DHCPv6-PD lease including prefix length received from the WAN ISP
  • Doing journalctl -xeu systemd-networkd will give some logging information from systemd-networkd but I have yet to figure out how to get the most relevant parts logged.

More network logging

Doing systemctl edit systemd-networkd to add in:


And restart systemd-networkd service and looking at logs:

systemctl restart systemd-networkd
journalctl -b -u systemd-networkd

Shows a little more info, but still not some of the things that I'd hope to see from looking at the systemd-networkd code.


I'll update this when I upgrade to Ubuntu 22.04 as hopefully it has some more features. If you have any suggestions for better ways of doing things above, they are welcome. I'm unfortunately unable to provide tech support for anything in the above, however...

tags: LinuxIPv6