IPv6 host addressing is where a lot of otherwise competent engineers quietly lose confidence, because there are three mechanisms that can all be running at once, they interact through two obscure flag bits in a router advertisement, and a host can end up with several addresses from different sources simultaneously. That is not a bug. It is the design.
This article untangles SLAAC, stateless DHCPv6, and stateful DHCPv6, shows the M and O flags that arbitrate between them, and builds a working stateful server with a relay on Cisco IOS XE, with a real Linux client acquiring a real lease. It extends the IPv6 cluster guide and the IP Services cluster guide.
Start Here: IPv6 Hosts Do Not Need DHCP
In IPv4, a host with no DHCP server has no address. Full stop. That assumption is baked so deeply into most engineers' instincts that IPv6's model feels wrong at first.
In IPv6, the router is the primary source of addressing information, not a server. A router periodically multicasts a Router Advertisement (RA) containing the on-link prefix, and any host that hears it can build itself a working global address without asking anyone. That is SLAAC (Stateless Address Autoconfiguration), and it is the default behaviour of essentially every IPv6 host on earth.
You can watch it happen. Here is a Linux host in the lab that has been given no DHCP configuration whatsoever, moments after being connected:
$ ip -br addr show eth0
eth0@if49 UP 10.0.10.100/24 2001:db8:10:0:5054:ff:fe79:35a2/64 fe80::5054:ff:fe79:35a2/64The IPv4 address was configured manually. The IPv6 global address 2001:db8:10:0:5054:ff:fe79:35a2/64 appeared on its own, because the router advertised the prefix 2001:db8:10::/64 and the host did the rest.
Look at the interface identifier: 5054:ff:fe79:35a2. That ff:fe in the middle is the signature of EUI-64: the host took its 48-bit MAC address (52:54:00:79:35:a2), split it in half, jammed ff:fe into the gap, and flipped the seventh bit. If you see ff:fe in an IPv6 address, you are looking at an EUI-64 SLAAC address and you can read the MAC straight out of it. (Which is exactly why RFC 4941 privacy addresses exist, and why most desktop OSes now use random identifiers instead by default.)
The Two Flags That Decide Everything
The RA carries two bits that tell the host what else to do. Getting these right is the whole game.
Those two bits produce the three deployment models, and the names finally make sense:
"Stateless" and "stateful" refer to the server's state, not the client's. A stateless DHCPv6 server hands out DNS servers and forgets you exist. A stateful one records who has which address, which is what you need if you want to answer "which machine was 2001:db8::42 last Tuesday."
One critical subtlety: setting the M flag does not automatically stop SLAAC. If the RA still carries a prefix with the autonomous flag set, a host will build a SLAAC address and ask DHCPv6 for one, and end up with both. If you want DHCPv6 to be the only source, you must explicitly tell the router to stop advertising the prefix as autoconfigurable.
Building Stateful DHCPv6 with a Relay
The lab: a client on the 2001:db8:10::/64 LAN behind R1, and the DHCPv6 server on R2, one hop away. This is the realistic topology, because your DHCP server is essentially never on the same segment as your clients.
The server (R2)
R2(config)# ipv6 dhcp pool PINGLABZ-STATEFUL
R2(config-dhcpv6)# address prefix 2001:DB8:10:AAAA::/64 lifetime 3600 1800
R2(config-dhcpv6)# dns-server 2001:4860:4860::8888
R2(config-dhcpv6)# domain-name pinglabz.local
!
R2(config)# interface Ethernet0/1
R2(config-if)# ipv6 dhcp server PINGLABZ-STATEFULThe two lifetimes are valid (3600) and preferred (1800), in that order. An address past its preferred lifetime is "deprecated": still usable for existing connections, but not chosen for new ones. Past the valid lifetime it is gone. This graceful two-stage expiry has no IPv4 equivalent and is one of the genuinely nice parts of IPv6.
The relay and the flags (R1)
R1(config)# interface Ethernet0/2
R1(config-if)# ipv6 nd managed-config-flag
R1(config-if)# ipv6 nd other-config-flag
R1(config-if)# ipv6 nd prefix 2001:DB8:10::/64 no-autoconfig
R1(config-if)# ipv6 dhcp relay destination 2001:DB8:12::2 Ethernet0/1Four lines, four distinct jobs:
managed-config-flagsets M. Hosts will now solicit an address from DHCPv6.other-config-flagsets O. Hosts will take DNS and domain from DHCPv6 too.prefix ... no-autoconfigclears the autonomous bit on the advertised prefix. This is the line everyone forgets. Without it, hosts keep building SLAAC addresses alongside their DHCPv6 lease, and you have two addresses per host and no idea which one traffic will use.ipv6 dhcp relay destinationforwards the client's solicit (sent to the link-local multicast group ff02::1:2, which does not route) onward to the actual server as unicast.
The Exchange
DHCPv6 uses four messages, and if you know DHCPv4's DORA they map cleanly:
The client in the lab is a Linux host running udhcpc6. Here it is doing exactly that:
$ udhcpc6 -i eth0
udhcpc6: started, v1.36.1
udhcpc6: sending discover
udhcpc6: sending discover
udhcpc6: sending select
udhcpc6: IPv6 obtained, lease time 3600Solicit, solicit (the first went unanswered while the relay warmed up), select, and a lease with the 3600-second lifetime configured on the server. The client is on one subnet, the server is on another, and the relay carried the conversation between them.
The Binding: What the Server Remembers
This is where "stateful" earns its name:
R2#show ipv6 dhcp binding
Client: FE80::5054:FF:FE79:35A2
DUID: 000300015254007935A2
Username : unassigned
VRF : default
IA NA: IA ID 0x8FFD7C11, T1 900, T2 1440
Address: 2001:DB8:10:AAAA:31E0:5957:EFD4:7F52
preferred lifetime 1800, valid lifetime 3600
expires at Jul 12 2026 01:54 AM (3587 seconds)Several things worth reading properly:
- DUID (DHCP Unique Identifier) is how DHCPv6 identifies a client, and it is not the MAC address. It is generated once by the client and persists across reboots and NIC changes. This breaks every IPv4 habit you have around MAC-based reservations. Here the DUID happens to embed the MAC (
5254007935A2) because it is DUID type 3 (link-layer), but that is a client choice, not a guarantee. - IA_NA (Identity Association for Non-temporary Addresses) is the container for the leased address. A client can hold several.
- T1 (900) and T2 (1440) are the renew and rebind timers, defaulting to 50% and 80% of the preferred lifetime. At T1 the client asks the same server to renew. At T2 it gives up on that server and asks any server.
- The allocated address is
2001:DB8:10:AAAA:31E0:5957:EFD4:7F52. Note the host portion is random, not EUI-64. There is noff:fe. That is the fingerprint of a DHCPv6-assigned address versus a SLAAC one, and it is the quickest way to tell at a glance which mechanism gave a host its address.
R2#show ipv6 dhcp pool
DHCPv6 pool: PINGLABZ-STATEFUL
Address allocation prefix: 2001:DB8:10:AAAA::/64 valid 3600 preferred 1800 (1 in use, 0 conflicts)
DNS server: 2001:4860:4860::8888
Domain name: pinglabz.local
Active clients: 1DHCPv6-PD, Briefly
One more mode exists and it has no IPv4 analogue at all. Prefix Delegation hands a client an entire prefix (a /56 or /48) rather than a single address, so the client can subnet it and hand addresses to devices behind it.
This is how your home router gets IPv6 from your ISP: it does not receive one address, it receives a /56, and it then advertises /64s from that block onto your home LANs. Configured with prefix-delegation pool on the server side and ipv6 dhcp client pd on the client interface. It is the standard model for any downstream router, not just consumer kit.
When It Does Not Work
ipv6 nd prefix ... no-autoconfig.ipv6 unicast-routing on? Without it the router sends no RAs and the host has nothing to react to.show ipv6 dhcp interface on both ends.And a security note: an RA is unauthenticated, and any host on the segment can send one. A rogue RA (malicious or, far more commonly, a misconfigured Windows box with sharing enabled) will reconfigure every host on the VLAN. The defence is RA Guard on the access switch, which belongs to the IPv6 first-hop security toolkit.
FAQ
Which should I use?
Stateful DHCPv6 if you need to know which device had which address (most enterprises, for audit and forensics). SLAAC plus stateless DHCPv6 if you just need working hosts and DNS with minimal infrastructure. Pure SLAAC for simple or transit segments.
Can a host get DNS without any DHCPv6 at all?
Yes. The RDNSS option in the RA (RFC 8106) carries DNS servers directly. Modern OSes support it; some older ones ignore it, which is why stateless DHCPv6 still exists.
Why is my client's address not EUI-64 even with SLAAC?
Privacy extensions (RFC 4941). Most desktop OSes generate random, rotating interface identifiers by default rather than embedding the MAC. This is a feature.
Does DHCPv6 give out a default gateway?
No, and this surprises people. There is no gateway option in DHCPv6. The default route always comes from the Router Advertisement. You cannot run DHCPv6 without RAs.
What is T1 and T2?
Renew (T1) and rebind (T2) timers, defaulting to 50% and 80% of the preferred lifetime. At T1 the client renews with the same server; at T2 it broadcasts for any server.
Key Takeaways
- IPv6 hosts get addresses from Router Advertisements by default. DHCPv6 is optional, and layered on top.
- The M flag means "get your address from DHCPv6." The O flag means "get your other config from DHCPv6." Those two bits define all three models.
- Setting M does not stop SLAAC. You must also set
ipv6 nd prefix ... no-autoconfig, or hosts end up with two addresses. - An
ff:fein the middle of the host portion means EUI-64 SLAAC. A random host portion means DHCPv6 assigned it. You can diagnose the mechanism from the address alone. - DHCPv6 identifies clients by DUID, not MAC. Every MAC-based reservation habit you have from IPv4 is wrong here.
- DHCPv6 never provides a default gateway. The default route always comes from the RA.
- Solicits go to ff02::1:2, which is link-local. Off-segment servers require a relay.
Next: the IPv6 cluster guide, or the IP Services cluster guide.