DHCPv6 (Dynamic Host Configuration Protocol for IPv6) is a network protocol used to automatically configure IPv6 network settings on client devices. While conceptually similar to DHCPv4, DHCPv6 has fundamental architectural differences and works alongside other IPv6 autoconfiguration mechanisms. This guide covers server and client configuration, architectural decisions, and troubleshooting.
Despite sharing similar names and purposes, DHCPv6 (RFC 3315) and DHCPv4 (RFC 2132) are completely separate protocols with significant differences:
Client Identification
Default Gateway Configuration
Network Communication
Port Numbers
Lease Times
DHCPv6 operates in two distinct modes, fundamentally changing what information the server provides:
In stateless mode, DHCPv6 does not provide IPv6 addresses. Instead, it provides "other configuration information" such as:
Clients obtain their IPv6 addresses through SLAAC (Stateless Address Autoconfiguration) using Router Advertisements. The DHCPv6 server does not track which hosts have which addresses - hence "stateless."
Use Case: Networks where SLAAC provides addressing, but centralized DNS and other configuration is desired.
In stateful mode, DHCPv6 provides both IPv6 addresses and additional configuration information. The server maintains a database of address assignments, tracking:
Use Case: Environments requiring centralized address management, address tracking, stable address assignments, or compatibility with systems that expect DHCP-based addressing.
Unlike IPv4, which relies primarily on DHCP, IPv6 introduces SLAAC as the native autoconfiguration mechanism. Understanding how DHCPv6 and SLAAC interact is critical for proper network configuration.
Router Advertisement messages contain flags that control client behavior:
M Flag (Managed Address Configuration)
O Flag (Other Configuration)
A Flag (Autonomous Address Configuration)
L Flag (On-Link)
| M Flag | O Flag | A Flag | Result |
|---|---|---|---|
| 0 | 0 | 1 | SLAAC only, no DHCPv6 |
| 0 | 1 | 1 | SLAAC for addresses, stateless DHCPv6 for DNS/other config |
| 1 | 0/1 | 1 | Dual-stack addressing: SLAAC + stateful DHCPv6 (client may use both) |
| 1 | 0/1 | 0 | Stateful DHCPv6 only (no SLAAC) |
Important Note: Setting M=1 alone does not prevent SLAAC. To enforce DHCPv6-only addressing, you must set M=1 AND A=0. Some operating systems (notably Windows 7+) will create both SLAAC addresses (privacy extensions) and DHCPv6 addresses simultaneously unless SLAAC is explicitly disabled.
RFC 8106 introduced RDNSS (Recursive DNS Server) and DNSSL (DNS Search List) options for Router Advertisements. These options allow routers to advertise DNS configuration directly in RA messages, reducing the need for stateless DHCPv6 in many scenarios.
Compatibility Consideration: Older client operating systems may not support RDNSS/DNSSL and will require stateless DHCPv6 for DNS configuration.
ISC DHCP is the most widely deployed DHCPv6 server implementation on Linux/Unix systems.
# Debian/Ubuntu
apt-get install isc-dhcp-server
# RHEL/CentOS/Rocky
yum install dhcp-server
# Arch Linux
pacman -S dhcp
Configuration file: /etc/dhcp/dhcpd6.conf
# Global options
default-lease-time 2592000; # 30 days
preferred-lifetime 604800; # 7 days (preferred lifetime)
option dhcp-renewal-time 3600; # T1: 1 hour
option dhcp-rebinding-time 7200; # T2: 2 hours
# Enable DHCPv6 rapid commit (2-message exchange)
option dhcp6.rapid-commit;
# Define subnet and address range
subnet6 2001:db8:1:0::/64 {
# Address range for dynamic assignment
range6 2001:db8:1:0::100 2001:db8:1:0::500;
# DNS servers
option dhcp6.name-servers 2001:4860:4860::8888, 2001:4860:4860::8844;
# Domain search list
option dhcp6.domain-search "example.com", "example.net";
}
# Static address assignment (reserved by DUID)
host server1 {
host-identifier option dhcp6.client-id 00:01:00:01:1c:2e:ff:9a:00:11:22:33:44:55;
fixed-address6 2001:db8:1:0::10;
}
# Stateless DHCPv6 - no address assignment
option dhcp6.name-servers 2001:4860:4860::8888, 2001:4860:4860::8844;
option dhcp6.domain-search "example.com";
subnet6 2001:db8:1:0::/64 {
# No range6 defined - stateless operation
}
For delegating prefixes to downstream routers (common in ISP scenarios):
subnet6 2001:db8::/32 {
# Delegate /56 prefixes to requesting routers
prefix6 2001:db8:0:100:: 2001:db8:0:1ff:: /56;
}
ISC DHCP requires the -6 flag to operate in IPv6 mode:
# Create lease file if it doesn't exist
touch /var/lib/dhcp/dhcpd6.leases
# Start DHCPv6 server on specific interface
dhcpd -6 -cf /etc/dhcp/dhcpd6.conf -lf /var/lib/dhcp/dhcpd6.leases eth0
# Using systemd (most distributions)
systemctl enable --now isc-dhcp-server6
# or
systemctl enable --now dhcpd6
Note: ISC DHCP can only serve one protocol version at a time. To support both IPv4 and IPv6, run two separate daemon instances.
dnsmasq is a lightweight alternative providing DNS, DHCP, and TFTP services. It's commonly used in embedded systems, home routers (OpenWrt), and small networks.
Configuration file: /etc/dnsmasq.conf
# Enable DHCPv6 rapid commit
dhcp-rapid-commit
# Enable IPv6 Router Advertisements
enable-ra
# DHCPv6 range with SLAAC support
# Constructor: automatically detects interface prefix
dhcp-range=::100,::500,constructor:eth0,ra-stateless,12h
# For stateful DHCPv6 (addresses assigned by DHCPv6)
dhcp-range=::100,::500,constructor:eth0,ra-names,64,12h
# DNS servers provided via DHCPv6
dhcp-option=option6:dns-server,[2001:4860:4860::8888],[2001:4860:4860::8844]
# Domain search list
dhcp-option=option6:domain-search,example.com
# Static assignment by DUID
dhcp-host=id:00:01:00:01:1c:2e:ff:9a:00:11:22:33:44:55,[2001:db8:1::10]
# Combine SLAAC with DNS names (ra-names option)
# Clients get SLAAC addresses registered in DNS
dhcp-range=::,constructor:eth0,ra-names,slaac,12h
# Test configuration
dnsmasq --test
# Start service
systemctl enable --now dnsmasq
Key dnsmasq Features:
ra-names: Provides DNS names for SLAAC addressesra-stateless: Enables stateless DHCPv6 modeconstructor:: Automatically constructs IPv6 range from interface configurationCisco routers can function as DHCPv6 servers:
ipv6 unicast-routing
! Define DHCPv6 pool
ipv6 dhcp pool STATELESS-POOL
dns-server 2001:4860:4860::8888
domain-name example.com
! Apply to interface
interface GigabitEthernet0/0
ipv6 address 2001:db8:1::1/64
ipv6 dhcp server STATELESS-POOL
ipv6 nd other-config-flag
ipv6 unicast-routing
! Define DHCPv6 pool
ipv6 dhcp pool STATEFUL-POOL
address prefix 2001:db8:1::/64 lifetime 2592000 604800
dns-server 2001:4860:4860::8888
domain-name example.com
! Apply to interface with managed flag
interface GigabitEthernet0/0
ipv6 address 2001:db8:1::1/64
ipv6 dhcp server STATEFUL-POOL
ipv6 nd managed-config-flag
ipv6 nd prefix default no-autoconfig
Most modern Linux distributions use NetworkManager or systemd-networkd for network management, both of which support DHCPv6.
NetworkManager handles DHCPv6 automatically when:
Check DHCPv6 status:
nmcli device show eth0 | grep -i dhcp6
Manual configuration:
nmcli connection modify eth0 ipv6.method auto
nmcli connection modify eth0 ipv6.dhcp-duid ll # Link-layer DUID type
nmcli connection up eth0
Configuration file: /etc/systemd/network/20-eth0.network
[Match]
Name=eth0
[Network]
DHCP=ipv6
# Or DHCP=yes for both IPv4 and IPv6
[DHCPv6]
UseAddress=yes
UseDNS=yes
UseDomains=yes
Restart service:
systemctl restart systemd-networkd
For manual DHCPv6 client operation:
# Request DHCPv6 address
dhclient -6 -v eth0
# Release DHCPv6 address
dhclient -6 -r eth0
# Check leases
cat /var/lib/NetworkManager/dhclient6-*.lease
# or
cat /var/lib/dhcp/dhclient6.leases
Configuration file: /etc/wide-dhcpv6/dhcp6c.conf
interface eth0 {
send ia-na 0;
send rapid-commit;
request domain-name-servers;
request domain-name;
};
id-assoc na 0 {
};
Start client:
dhcp6c -c /etc/wide-dhcpv6/dhcp6c.conf eth0
Windows has built-in DHCPv6 client support that operates automatically based on Router Advertisement flags.
ipconfig /all
Look for:
# Release all DHCP leases (IPv4 and IPv6)
ipconfig /release
# Renew all DHCP leases
ipconfig /renew
# View DHCPv6 configuration
Get-NetIPInterface -AddressFamily IPv6 | Select-Object InterfaceAlias, Dhcp
# View DHCPv6-assigned addresses
Get-NetIPAddress -AddressFamily IPv6 -PrefixOrigin Dhcp
# Restart DHCPv6 on interface
Restart-NetAdapter -Name "Ethernet"
Windows Behavior Notes:
Critical Compatibility Issue: Android does not support DHCPv6. Android devices only support SLAAC (with RDNSS for DNS configuration) and cannot obtain addresses via DHCPv6.
If your network needs to support Android devices, you must deploy SLAAC (with A=1 in Router Advertisements) and use RDNSS/DNSSL for DNS configuration.
Enable verbose logging:
# Run in foreground with debugging
dhcpd -6 -d -f -cf /etc/dhcp/dhcpd6.conf eth0
# Check system logs
journalctl -u isc-dhcp-server6 -f
# or
tail -f /var/log/syslog | grep dhcp6
# Run with verbose logging
dnsmasq --log-dhcp --log-queries --no-daemon
# Or enable in config
# log-dhcp
# log-queries
# Check DHCPv6 server listening on port 547
ss -ulnp | grep 547
# or
netstat -ulnp | grep 547
# Linux
ip -6 addr show
ip -6 route show
# Windows
ipconfig /all
netsh interface ipv6 show address
# Linux - check if DHCPv6 client is running
ps aux | grep dhclient6
ps aux | grep dhcp6c
# Check for NetworkManager DHCPv6 activity
journalctl -u NetworkManager -f
Use tcpdump or Wireshark to analyze DHCPv6 message exchange:
# Capture DHCPv6 traffic
tcpdump -i eth0 -vvv port 546 or port 547
# More specific filter for DHCPv6
tcpdump -i eth0 -vvv 'udp port 546 or udp port 547'
DHCPv6 message flow (stateful):
With rapid-commit enabled:
Verify RA flags are correctly set:
# Install radvdump (Debian/Ubuntu)
apt-get install radvd
# Capture and display Router Advertisements
radvdump
# Alternative: tcpdump
tcpdump -i eth0 -vvv icmp6 and 'ip6[40] = 134'
Look for:
Diagnosis:
radvdump)ss -ulnp | grep 547)Solution:
# Enable M flag in Router Advertisements
# Linux with radvd - /etc/radvd.conf
interface eth0 {
AdvManagedFlag on;
AdvOtherConfigFlag on;
prefix 2001:db8:1::/64 {
AdvOnLink on;
AdvAutonomous off; # Disable SLAAC if DHCPv6-only desired
};
};
# Restart services
systemctl restart radvd
systemctl restart isc-dhcp-server6
Diagnosis: O flag may not be set, or client doesn't support stateless DHCPv6
Solution: Enable O flag in Router Advertisements and verify client supports DHCPv6
Diagnosis:
Solution:
# Linux firewall - allow DHCPv6
firewall-cmd --permanent --add-service=dhcpv6-client
firewall-cmd --reload
# Or with iptables
ip6tables -A INPUT -p udp --dport 546 -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 547 -j ACCEPT
Diagnosis: Both A flag and M flag are set
Solution: Choose one addressing method:
# Verify DHCPv6 address assignment
ip -6 addr show | grep -i dynamic
# Check DHCPv6 lease database (ISC DHCP)
cat /var/lib/dhcp/dhcpd6.leases
# Show DHCPv6 pool status (Cisco)
show ipv6 dhcp pool
show ipv6 dhcp binding
After configuring DHCPv6, test connectivity and proper IPv6 behavior using:
test-ipv6.run - A comprehensive IPv6 connectivity testing tool that checks:
Visit https://test-ipv6.run in your browser to verify your DHCPv6 configuration is working correctly and that clients have proper IPv6 connectivity.