In modern IPv6 networking, internet service providers (ISPs) and enterprise upstream routers allocate IPv6 address space to edge gateways using DHCPv6 Prefix Delegation (DHCPv6-PD, RFC 8415). Instead of assigning a single IPv6 address, the upstream provider delegates a routed address block — typically a /56 or /64 prefix — to the customer premises equipment (CPE) or border server. The gateway machine must then divide this delegated pool into individual /64 subnets, assign them across internal LAN interfaces or VLAN bridges, and broadcast IPv6 Router Advertisements (RA) to downstream clients.
On Ubuntu Server, this entire prefix delegation, subnet splitting, and router advertisement pipeline can be configured natively through systemd-networkd without installing external daemons such as radvd, dhcp6c, or dibbler. By declaring prefix delegation directives within network files in /etc/systemd/network/, network administrators can build resilient, zero-maintenance IPv6 routing gateways.
Understanding DHCPv6 Prefix Delegation Architecture in systemd-networkd
When operating an Ubuntu machine as a multi-homed IPv6 router, systemd-networkd manages prefix delegation across two primary roles:
- Upstream WAN Interface (DHCPv6 Client): Requests and leases an IPv6 delegated prefix from the ISP’s DHCPv6 server using the
[DHCPv6]section. The requested prefix length is specified usingPrefixDelegationHint=. - Downstream LAN/VLAN Interfaces (DHCPv6-PD Server & RA Broadcaster): Receives sliced sub-prefixes via
[DHCPv6PrefixDelegation]stanzas, generates unique local interface addresses, and announces the prefixes to local devices via the internal IPv6 Router Advertisement engine ([IPv6SendRA]).
For example, if your upstream ISP delegates a 2001:db8:1234:5600::/56 block, systemd-networkd automatically slices it into distinct /64 subnets (e.g. ...:5601::/64 for corporate LAN, ...:5602::/64 for guest Wi-Fi, and ...:5603::/64 for IoT VLANs) based on configured subnet IDs.
Enabling IPv6 Packet Forwarding on Ubuntu
Before configuring systemd-networkd to route IPv6 traffic, verify that kernel IPv6 packet forwarding is enabled system-wide. Open or create /etc/sysctl.d/99-ipv6-forwarding.conf:
sudo nano /etc/sysctl.d/99-ipv6-forwarding.conf
Insert the following sysctl parameters:
net.ipv6.conf.all.forwarding=1
net.ipv6.conf.default.forwarding=1
Apply the sysctl parameters immediately without rebooting:
sudo sysctl --system
Confirm the kernel accepts forwarded IPv6 datagrams:
sysctl net.ipv6.conf.all.forwarding
Configuring the Upstream WAN Interface for Prefix Delegation
Assume the upstream physical interface connected to the ISP modem or optical ONT is named enp1s0. Create or edit /etc/systemd/network/10-wan.network:
sudo nano /etc/systemd/network/10-wan.network
Populate the file with the WAN configuration:
[Match]
Name=enp1s0
[Network]
Description=Upstream WAN Gateway with DHCPv6-PD
DHCP=ipv6
LinkLocalAddressing=ipv6
IPv6AcceptRA=yes
[IPv6AcceptRA]
UseDNS=yes
[DHCPv6]
WithoutRA=solicit
PrefixDelegationHint=::/56
UseDNS=yes
UseNTP=yes
Configuration details explained:
DHCP=ipv6: Configures the interface to run a DHCPv6 client.IPv6AcceptRA=yes: Accepts default IPv6 routes and router flags advertised by the upstream gateway.PrefixDelegationHint=::/56: Explicitly hints to the ISP’s DHCPv6 server that this router requests a/56delegated prefix block.WithoutRA=solicit: Ensures the DHCPv6 client initiates a solicit exchange even if the upstream router advertisement omits the managed (M) or other configuration (O) flags.
Configuring Downstream LAN Interfaces to Consume Delegated Prefixes
Now configure the internal network interfaces that will distribute the delegated subnets to client computers and mobile devices. In this architecture, assume the internal corporate network is connected to enp2s0, and an internal server network is connected to enp3s0.
Create the network configuration file for enp2s0 (/etc/systemd/network/20-lan.network):
sudo nano /etc/systemd/network/20-lan.network
Insert the following configuration:
[Match]
Name=enp2s0
[Network]
Description=Internal Corporate LAN
LinkLocalAddressing=ipv6
IPv6SendRA=yes
DHCPv6PrefixDelegation=yes
[DHCPv6PrefixDelegation]
SubnetId=0x1
Announce=yes
[IPv6SendRA]
Managed=no
OtherInformation=no
RouterLifetimeSec=1800
EmitDNS=yes
DNS=2606:4700:4700::1111
Create the configuration for the secondary downstream interface enp3s0 (/etc/systemd/network/21-servers.network):
sudo nano /etc/systemd/network/21-servers.network
[Match]
Name=enp3s0
[Network]
Description=Internal Server Subnet
LinkLocalAddressing=ipv6
IPv6SendRA=yes
DHCPv6PrefixDelegation=yes
[DHCPv6PrefixDelegation]
SubnetId=0x2
Announce=yes
[IPv6SendRA]
RouterLifetimeSec=1800
Key parameters explained:
DHCPv6PrefixDelegation=yes: Instructssystemd-networkdto automatically bind a portion of the prefix acquired on the WAN interface to this link.SubnetId=0x1and0x2: Specifies the hexadecimal offset applied to the delegated base prefix, guaranteeing that each downstream interface receives a non-overlapping, unique/64subnet.IPv6SendRA=yes: Enables the internal Router Advertisement daemon, allowing client endpoints on the LAN to auto-configure their own IPv6 addresses using SLAAC (Stateless Address Autoconfiguration).
Applying Configuration and Validating IPv6 Prefix Allocation
Restart systemd-networkd to apply the configuration and initiate the upstream prefix negotiation:
sudo systemctl restart systemd-networkd
Check the status of the WAN interface using networkctl:
networkctl status enp1s0
Look for the DHCPv6 Client status block. The output will show the assigned prefix (e.g. Prefix: 2001:db8:abcd:1200::/56) and lease expiration timers.
Inspect the downstream LAN interface:
networkctl status enp2s0
The output will confirm that systemd-networkd has generated an interface IP within the delegated subnet (e.g. 2001:db8:abcd:1201::1/64) and is actively transmitting Router Advertisements.
Verify that kernel routes are installed properly:
ip -6 route show
From a client machine connected to the downstream LAN, confirm that SLAAC has assigned an address and test end-to-end global connectivity:
ping -6 -c 4 cloudflare.com
Troubleshooting Common Prefix Delegation Issues
If downstream interfaces do not acquire prefixes or clients lose IPv6 connectivity, evaluate these common causes:
- Firewall Filtering DHCPv6 Packets: Ensure
ufwornftableson the Ubuntu router does not block incoming UDP port546on the WAN interface:sudo ufw allow in on enp1s0 proto udp to any port 546 comment "DHCPv6 Client Ingress" - Inconsistent DUID (DHCP Unique Identifier): Some cable and fibre ISPs bind delegated prefixes strictly to the client DUID. If the DUID changes on reboot, the ISP rejects the request. Enforce a static DUID in
/etc/systemd/networkd.conf:[DHCPv6] DUIDType=vendor - Missing Default IPv6 Route: If the WAN interface receives a delegated prefix but cannot route packets externally, verify that the ISP’s router advertisements are not being ignored by checking
sysctl net.ipv6.conf.enp1s0.accept_ra(which must be set to2when forwarding is enabled system-wide).