IPv6 was designed to solve IPv4 address exhaustion, and it does: there are about 3.4 × 10³⁸ addresses, enough that every device can have a globally unique one. But it is not just IPv4 with longer addresses. A few mechanisms work differently, and if you come to IPv6 from IPv4 those differences cause most of the confusion: addresses have types with different scopes, a device normally has several addresses at once, there is no broadcast and no ARP, and a host can configure itself without DHCP.
This primer covers the basics you need to read IPv6 configuration and output with confidence: how addresses are written, what the different address types are for, how hosts get an address, and how DHCPv6 differs from the DHCP you know.
Reading an address
An IPv6 address is 128 bits, written as eight groups of four hexadecimal digits separated by colons:
2001:0db8:0000:0000:0000:0000:0000:0001
Two rules shorten it:
- In each group, leading zeros can be dropped:
0db8becomesdb8,0000becomes0. - One run of consecutive all-zero groups can be replaced by
::. This can be used only once in an address, otherwise it would be ambiguous how many groups each::stands for.
Applying both gives:
2001:db8::1
The usual convention (RFC 5952) is lowercase, and :: replaces the longest run of zero groups. These are all the same address, and the last one is the form you will see in practice:
2001:0db8:0000:0000:0000:0000:0000:0001
2001:db8:0:0:0:0:0:1
2001:db8::1
Prefixes and subnets
Like IPv4 with CIDR, an address is split into a network prefix and the rest, and the prefix length is written after a slash. 2001:db8:1:1::/64 means the first 64 bits are the network and the remaining 64 identify a host on it.
The standard layout is:
| 48 bits | 16 bits | 64 bits |
| global routing prefix | subnet | interface identifier |
An ISP typically hands a site a prefix such as a /48 (a home connection often gets a /56). The site splits it into /64 subnets, one per network segment. A /48 gives 65,536 of them. The last 64 bits identify the interface on that subnet.
Use a /64 for every subnet that hosts connect to. Autoconfiguration, covered below, depends on it. The one common exception is point-to-point router links, where longer prefixes such as /127 are used.
Address types
IPv4 has public, private and a few special ranges. IPv6 has more kinds of address, defined by prefix, and each has a scope, meaning how far it is meant to reach.
| Type | Prefix | Scope | Used for |
|---|---|---|---|
| Global unicast (GUA) | 2000::/3 | The internet | Publicly routable addresses |
| Unique local (ULA) | fc00::/7 (in practice fd00::/8) | Your own networks | Private addressing, not routed on the internet |
| Link-local | fe80::/10 | One link | Neighbor discovery, router advertisements, next hops |
| Multicast | ff00::/8 | Depends on the address | One-to-many delivery, replacing broadcast |
| Loopback | ::1/128 | The host itself | Same role as 127.0.0.1 |
| Unspecified | ::/128 | “No address yet”, used as a source during startup | |
| Documentation | 2001:db8::/32 | Examples and labs, never routed |
Global unicast (GUA) addresses are the IPv6 equivalent of public IPv4 addresses. Today they are allocated out of 2000::/3, so they start with 2 or 3. They are assigned by your provider or a registry, and they are unique and routable across the internet.
Unique local addresses (ULA) are the nearest thing to RFC 1918 private space such as 10.0.0.0/8. They are meant for traffic that stays inside your own networks, and the internet doesn’t route them. Only fd00::/8 is used, and a ULA prefix has the form fd plus a 40-bit random global ID, then a 16-bit subnet ID. The ID is random so that two organizations that later merge networks are unlikely to have picked the same prefix. A device can have a ULA and a GUA at the same time, and often does.
Link-local addresses exist on every IPv6 interface, automatically, even with no other configuration. They are valid only on the directly connected link, so a router never forwards a packet with a link-local source or destination. Every link uses the same fe80::/64, so a link-local address alone is ambiguous: when you use one you must also name the interface, as in ping fe80::1%eth0. Routers send their router advertisements from link-local addresses, and they use them as next hops.
Multicast replaces broadcast, which does not exist in IPv6. The scope is part of the address: ff02:: addresses stay on the local link. Two you will meet constantly are ff02::1 (all nodes on the link) and ff02::2 (all routers on the link).
Anycast isn’t a separate range. It is a unicast address assigned to more than one device, and routing delivers a packet to the nearest one.
Documentation addresses in 2001:db8::/32 play the role of 192.0.2.0/24 in IPv4. Any example or lab you see written with 2001:db8:: uses them because they can never collide with real networks.
One interface, several addresses
A device normally has more than one IPv6 address per interface. This is a Linux interface that I gave a documentation-range address and a ULA:
ip -6 addr show dev d0
2: d0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
inet6 fd12:3456:789a:1::10/64 scope global
valid_lft forever preferred_lft forever
inet6 2001:db8:1:1::10/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::8447:19ff:feff:30ac/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
Three addresses are on the interface, and only two of them were configured by hand. The third, fe80::…, is the link-local address the kernel created on its own. Note that Linux reports both the ULA and the 2001:db8:: address as scope global: the kernel’s scope only distinguishes link, host and everything else, and it doesn’t separate ULA from GUA. The prefix tells you which is which.
The routing table is built the same way as in IPv4, with one connected route per prefix, including the link-local one:
2001:db8:1:1::/64 dev d0 proto kernel metric 256 pref medium
fd12:3456:789a:1::/64 dev d0 proto kernel metric 256 pref medium
fe80::/64 dev d0 proto kernel metric 256 pref medium
How a host gets an address
An IPv6 host can configure itself using only what the routers on its link tell it. This is SLAAC, stateless address autoconfiguration, and it relies on a set of ICMPv6 messages called the Neighbor Discovery Protocol (NDP). NDP does the jobs ARP and part of DHCPv4 do in IPv4.
| Message | ICMPv6 type | Purpose |
|---|---|---|
| Router Solicitation (RS) | 133 | A host asks “are there any routers here?” |
| Router Advertisement (RA) | 134 | A router announces prefixes and parameters |
| Neighbor Solicitation (NS) | 135 | “Who has this address?” (replaces ARP requests) |
| Neighbor Advertisement (NA) | 136 | “I do.” (replaces ARP replies) |
Router advertisements
The router advertisement is the central message. A router sends one periodically to ff02::1, and also in answer to a host’s router solicitation, which hosts send to ff02::2 when they come up. An RA carries:
- Prefix information: the prefixes on this link, with their lifetimes, and two flags. The L flag says the prefix is on-link, so destinations inside it are reached directly. The A flag says hosts may build their own address from it using SLAAC.
- Router lifetime: whether the sender is a default router for this link, and for how long. This is how a host learns its default gateway.
- The M and O flags, which tell the host whether to use DHCPv6, covered in the next section.
- Optional extras such as the link MTU and DNS servers.
What a host does
The sequence when an interface comes up:
- The host forms a link-local address,
fe80::plus an interface identifier. - It checks that nobody else on the link has it, using duplicate address detection (DAD): a neighbor solicitation for its own address. If no one answers, the address is its own.
- It sends a router solicitation, and the router replies with an RA.
- For each prefix with the A flag set, the host appends an interface identifier to the 64-bit prefix to make an address, and runs DAD on it too.
- It installs a default route to the router that sent the RA, using the router’s link-local address as the next hop.
No server tracks which host got which address, which is why this is called stateless.
The interface identifier
The last 64 bits of a SLAAC address can be generated in different ways:
- EUI-64 derives it from the interface’s MAC address, inserting
ff:fein the middle and flipping one bit. The link-local address in the capture above was generated this way, and you can see theff:feinfe80::8447:19ff:feff:30ac. It is predictable, and because it is tied to the hardware it lets a device be tracked as it moves between networks. - Stable privacy addresses (RFC 7217) derive the identifier from a secret and the network prefix. The address is stable on one network and different on another, and it doesn’t reveal the MAC. Many current systems use this by default.
- Temporary addresses (RFC 8981) are random identifiers that change over time and are used for outgoing connections, to make long-term tracking harder.
Hosts and routers
Linux treats the two roles differently. IPv6 forwarding is off by default (net.ipv6.conf.all.forwarding = 0), so a Linux machine doesn’t route IPv6 until you turn it on. And a host accepts router advertisements by default only while forwarding is disabled, because a router is expected to be configured rather than to configure itself from someone else’s advertisements.
DHCPv6 and how it differs from DHCP
SLAAC gives a host an address and a default route, but not everything. Sometimes you want central control over addresses, or you need to hand out other information. DHCPv6 exists for that, and it works differently from DHCPv4 in ways that are easy to miss.
An RA decides whether DHCPv6 is used at all. The M (managed) flag in the RA tells hosts to get their addresses from DHCPv6. The O (other configuration) flag tells hosts to get other settings, such as DNS servers, from DHCPv6 while still building their address with SLAAC. If neither is set, a host normally uses SLAAC alone and doesn’t speak DHCPv6. In IPv4, by contrast, a host that isn’t configured statically always starts by looking for a DHCP server.
The common combinations:
| What the RA says | Address | Other settings (DNS etc.) |
|---|---|---|
| Neither M nor O | SLAAC (if the prefix has the A flag) | From the RA itself, if it carries DNS options |
| O flag set | SLAAC (if the prefix has the A flag) | DHCPv6 (called stateless DHCPv6) |
| M flag set | DHCPv6 | DHCPv6 (called stateful DHCPv6) |
The main technical differences from DHCPv4:
| DHCPv4 | DHCPv6 | |
|---|---|---|
| Finding a server | Broadcast | Multicast to ff02::1:2 |
| Ports | Server UDP 67, client UDP 68 | Server UDP 547, client UDP 546 |
| Messages | DISCOVER, OFFER, REQUEST, ACK | SOLICIT, ADVERTISE, REQUEST, REPLY |
| Client identity | The MAC address | A DHCP Unique Identifier (DUID) |
| Default gateway | Provided by the server | Never provided: it always comes from the RA |
| Prefix length | Provided as a subnet mask | Never provided: it comes from the prefix in the RA |
| Prefix delegation | Not supported | Supported: a router can request a whole prefix to hand out |
Two of those rows matter most. A DHCPv6 server can’t tell a client its default gateway, so even with stateful DHCPv6 you still need router advertisements on the link. And a DHCPv6 server hands out an address without a prefix length, so the host learns the on-link prefix from the RA too. In IPv6, the router advertisement is never optional, and DHCPv6 only adds to it.
DHCPv6’s prefix delegation is how an ISP gives your home router a prefix, such as a /56, which the router then splits into /64s for your networks.
What to take away
- An address is 128 bits, written in hexadecimal and shortened by dropping leading zeros and using
::once. - Subnets are /64. A site gets a larger prefix and carves /64s from it.
- Addresses have types and scopes: GUA for the internet, ULA for private use, link-local for the local link, multicast instead of broadcast.
- A device has several addresses per interface, always including a link-local one.
- Router advertisements drive everything: prefixes, default gateway, and whether to use DHCPv6.
- NDP replaces ARP, and DHCPv6 supplements router advertisements rather than replacing them.