128 bits, written in hex
IPv6 addresses are 128 bits, giving 2¹²⁸ possible addresses, which is about 3.4 × 10³⁸. That is not a slightly larger pool, it is a number with no practical limit, and the design assumes addresses are free.
Writing 128 bits needs a compact notation, so IPv6 uses eight groups of four hex digits separated by colons.
2001:0db8:0000:0000:0000:ff00:0042:8329
Two compression rules make that readable, and both are worth practicing.
Rule 1, drop leading zeros within each group.
2001:db8:0:0:0:ff00:42:8329
Rule 2, replace one run of consecutive all zero groups with ::. It may be
used only once per address, because otherwise the number of zeros it stands for
would be ambiguous.
2001:db8::ff00:42:8329
Expanding back is the same rules in reverse. Count the groups present, and ::
fills the gap with as many zero groups as are missing to reach eight. So fe80::1
has two written groups and expands to
fe80:0000:0000:0000:0000:0000:0000:0001.
One notation detail that bites in configuration files and URLs: because a colon already separates a host from a port, an IPv6 literal in a URL goes in square brackets.
http://[2001:db8::1]:8080/statusThe address types
IPv6 has no broadcast at all. Anything that would have been a broadcast is a multicast to a well known group, which is more efficient because uninterested interfaces ignore it in hardware.
| Prefix | Name | Purpose |
|---|---|---|
| 2000::/3 | global unicast | routable on the internet, the normal case |
| fe80::/10 | link local | auto configured, valid on one link only |
| fc00::/7 | unique local | the private range, roughly like RFC 1918 |
| ff00::/8 | multicast | group delivery |
| ::1/128 | loopback | the equivalent of 127.0.0.1 |
| ::/128 | unspecified | "no address yet", used as a source during setup |
| 64:ff9b::/96 | NAT64 | wraps an IPv4 address inside an IPv6 one |
Three multicast groups you will see in captures: ff02::1 is all nodes on the
link, ff02::2 is all routers on the link, and ff02::1:ff00:0/104 is the
solicited node range, where each host joins a group derived from the last 24
bits of its own address so neighbor lookups reach almost nobody else.
The prefix arithmetic is simpler than IPv4 because it is standardized rather than squeezed:
| Prefix | Who holds it | Contains |
|---|---|---|
| /32 | an ISP allocation | 65,536 /48 sites |
| /48 | one site or customer | 65,536 /64 subnets |
| /64 | one subnet, always | 2⁶⁴ addresses, more than the whole IPv4 space |
Every ordinary subnet is a /64, without exception, because address autoconfiguration below depends on 64 host bits. So subnetting an IPv6 network is not arithmetic about host counts, it is only about how many /64 subnets you want. There is no "we only need 30 hosts here, use a /27". That habit does not transfer.
SLAAC: configuring without a server
IPv6 hosts can configure themselves, which is called SLAAC (stateless address autoconfiguration). It uses NDP (neighbor discovery protocol), which is built from ICMPv6 messages and replaces ARP entirely.
| ICMPv6 type | Name | Replaces or does |
|---|---|---|
| 133 | router solicitation | "any routers here?" |
| 134 | router advertisement | "yes, and the prefix on this link is X" |
| 135 | neighbor solicitation | ARP request |
| 136 | neighbor advertisement | ARP reply |
The startup sequence for a fresh interface:
1. Build a link local address from fe80::/64 plus a 64 bit interface
identifier. This works with no help from anybody.
2. Run DAD (duplicate address detection) by sending a neighbor solicitation for
that address. Silence means nobody else has it.
3. Send a router solicitation to ff02::2.
4. Receive a router advertisement carrying the /64 prefix for the link, the
router's address as the default gateway, and flags saying what else to use.
5. Combine the advertised prefix with the interface identifier to form a global
address, run DAD on it too, and start using it.
Where does the interface identifier come from? Historically from the MAC address
via EUI-64, which inserts fffe in the middle and flips one bit. That is
stable and therefore a privacy problem, because it puts a hardware serial number in
every packet you send from any network. Modern hosts instead generate randomized
identifiers, and typically hold two addresses at once, a stable one for incoming
connections and temporary ones that rotate for outgoing traffic.
DHCPv6 still exists for networks that want central control and record keeping, and the two coexist: the router advertisement's flags tell hosts whether to use SLAAC, DHCPv6, or both. A common combination is SLAAC for addresses and DHCPv6 only for DNS resolvers.
ip -6 addr show dev eth0inet6 2001:db8:acad:1:8a2e:37ff:fe4b:1c09/64 scope global dynamic inet6 2001:db8:acad:1:b41f:52a9:0e77:3d18/64 scope global temporary inet6 fe80::8a2e:37ff:fe4b:1c09/64 scope link
Three addresses on one interface is normal, and having many is expected in IPv6 rather than exceptional.
Living with both, and why it has taken decades
IPv6 was specified in 1998, and it still carries a minority of internet traffic. The reasons are worth understanding, because they are about incentives more than technology.
- The two protocols cannot talk to each other. An IPv6 only host and an IPv4 only server have no common language, so IPv6 was never a drop in upgrade. It is a parallel internet that has to be built alongside the old one. - NAT relieved the pressure. Once one public address could serve a household, the shortage stopped being an emergency for most users, which removed the urgency. - Every layer has to be ready. Operating systems, routers, firewalls, monitoring tools, log parsers, and application code that stores addresses in a 32 bit column. One unprepared component blocks the whole path. - There is no reward for going first. A site that enables IPv6 gains nothing unless clients have it, and clients gain nothing unless sites do.
The transition mechanisms in real use:
| Mechanism | What it does |
|---|---|
| Dual stack | run both protocols on every host, the mainstream approach |
| NAT64 with DNS64 | translate IPv6 only clients onto the IPv4 internet |
| 464XLAT | carry IPv4 applications across an IPv6 only mobile network |
Dual stack raises a question: with both an A and an AAAA record available, which does a client use? The answer is Happy Eyeballs, which starts connection attempts on both, prefers IPv6 slightly, and uses whichever completes first. It exists because a broken IPv6 path used to make sites appear down for a subset of users while IPv4 worked perfectly, and users blamed the site.
Two practical notes to end on. Mobile networks are largely IPv6 only internally already, with 464XLAT carrying legacy applications, so IPv6 is the majority path for a great deal of real traffic even where nobody notices. And because every device can hold a globally routable address, there is no NAT in IPv6 by design, so the accidental firewall from Lesson 6-2 is gone and a stateful firewall rule set becomes mandatory rather than optional. That is Unit 9.