IPv6 — Addressing and SLAAC
Topic 16

IPv6 — Addressing and SLAAC

IPv6

IPv6 expands the address from 32 bits to 128 — enough addresses to give every device a globally routable one and abandon NAT entirely. The number is absurd on purpose: 2^128 is roughly 340 undecillion addresses, more than there are grains of sand on Earth by a wide margin, so scarcity is no longer the constraint that shapes the design.

The model differs from IPv4 by more than the bit count. There is no broadcast, addresses are usually self-assigned through SLAAC rather than handed out by a server, and the header is a fixed 40 bytes with no options in the base form. Adoption is uneven — much of the internet is still IPv4-only — so the working reality is dual-stack: every host runs both protocols at once, and you have to understand both to operate a network today.

IPv432-bit, scarce
4.3 billion addresses, long exhausted. Needs NAT to share public IPs, uses broadcast to reach a whole segment, and leans on DHCP for address assignment.
IPv6128-bit, abundant
~340 undecillion addresses, no scarcity. No NAT needed, no broadcast — uses multicast instead — and hosts self-assign via SLAAC autoconfiguration.

The 128-Bit Address

An IPv6 address is written as eight groups of four hex digits separated by colons: 2001:0db8:0000:0000:0000:ff00:0042:8329. Two compression rules make that bearable. Leading zeros in a group drop, and one run of all-zero groups collapses to a double colon :: — once per address, since two would be ambiguous. The example becomes 2001:db8::ff00:42:8329, and loopback 0000:...:0001 becomes simply ::1.

The subnet convention is rigid and worth internalizing: a /64 is the standard subnet size, always. The first 64 bits are the network prefix and the last 64 are the interface identifier. That is not a recommendation you tune — SLAAC depends on a 64-bit host part, so subnetting smaller than /64 breaks autoconfiguration. A site typically gets a /48 from its provider, which yields 65 536 /64 subnets to hand out.

# ip -6 addr shows the prefix length and address scope
ip -6 addr show eth0
# inet6 2001:db8:1:5::a3/64 scope global       <- global unicast, /64 subnet
# inet6 fe80::1c2b:9aff:fe44:5e10/64 scope link <- link-local, always present
# every interface auto-gets an fe80:: address even with no router

Address Types

IPv6 replaces broadcast with a set of scoped address types. A link-local address in fe80::/10 exists on every interface automatically and is valid only on the local segment — it is how neighbor discovery and routers talk before any global address is configured. A global unicast address (today carved from 2000::/3) is the routable one, the IPv6 equivalent of a public IPv4 address, except there are enough to go around.

Unique local addresses in fc00::/7 are the IPv6 analog of RFC 1918 private space — non-routable on the public internet, for internal use. And instead of broadcast, IPv6 uses multicast (ff00::/8): "all nodes on this link" is ff02::1, "all routers" is ff02::2. Replacing the blunt broadcast with targeted multicast is why an IPv6 segment generates far less noise than an IPv4 one.

SLAAC and NDP

A host can configure its own global address with no DHCP server at all. With SLAAC, the host sends a router solicitation, the router answers with a router advertisement carrying the /64 prefix, and the host appends its own 64-bit interface identifier to form a complete address. The router never tracks which addresses are in use — it just announces the prefix, and every host derives its own.

The mechanism underneath is the Neighbor Discovery Protocol, which replaces both ARP and the IPv4 router-discovery pieces. Where IPv4 broadcasts an ARP request to find a MAC, IPv6 sends a neighbor solicitation to a multicast group and gets a neighbor advertisement back. Duplicate address detection runs the same way before a host commits to an address. You inspect the resulting neighbor table the same way you would an ARP cache.

# the IPv6 neighbor table — NDP's answer to the ARP cache
ip -6 neigh show
# 2001:db8:1:5::1 dev eth0 lladdr 00:1c:2b:44:5e:01 REACHABLE  <- the router
# fe80::1c2b:9aff:fe44:5e10 dev eth0 lladdr 00:1c:2b:44:5e:10 STALE
# no ARP here — neighbor solicitation/advertisement over multicast

Dual-Stack and Transition

Because so much of the internet remains IPv4-only, the practical deployment is dual-stack: a host has both an IPv4 and an IPv6 address and chooses per destination. When a name resolves to both an A and an AAAA record, modern clients use Happy Eyeballs — they race a v6 and a v4 connection and take whichever answers first, so a broken IPv6 path falls back to IPv4 in milliseconds instead of timing out.

v6-only networks are still rare outside mobile carriers and large content providers, because too many services and appliances assume IPv4 to drop it entirely. The transition has been slow precisely because dual-stack works well enough that there is little forcing function — and it doubles the operational surface, since every firewall rule, every ACL, and every monitoring check now has to exist twice, once per protocol.

IPv4 vs IPv6

IPv4 has 32-bit addresses, a depleted space that forces NAT, a variable 20–60 byte header, ARP for address resolution, and broadcast for one-to-all on a segment. It is the incumbent — nearly everything speaks it, and most networks still default to it. Run it because the rest of the world still does, not because it is the better design.

IPv6 has 128-bit addresses, enough to drop NAT and give every host a routable address, a fixed 40-byte header, NDP in place of ARP, and multicast in place of broadcast. Hosts usually self-configure with SLAAC. Adopt it for public-facing and mobile workloads first, run it alongside IPv4 as dual-stack, and expect v6-only to stay rare for years.

Common Mistakes
  • Subnetting IPv6 like IPv4 with prefixes longer than /64. SLAAC requires a 64-bit interface identifier, so a /112 or /120 host subnet silently breaks autoconfiguration — stick to /64 per segment even though it feels enormous.
  • Forgetting that link-local always exists. Every interface has an fe80:: address whether or not you configured anything, and rules or scripts that assume an interface has no IPv6 address until you assign one will misbehave.
  • Writing firewall rules for IPv4 only on a dual-stack host. The v4 rules say nothing about v6, so a host hardened on IPv4 can sit wide open on IPv6 — every policy must be duplicated for both protocols or the gap is an open door.
  • Expecting ARP and broadcast to work on IPv6. There is no ARP and no broadcast; neighbor discovery uses multicast, so tools and assumptions built around arp or a broadcast ping find nothing and mislead the diagnosis.
  • Treating a broken IPv6 path as harmless because IPv4 still works. Without Happy Eyeballs or with a misconfigured client, traffic can stall on the dead v6 route before falling back, producing slow connections that look like a server problem.
Best Practices
  • Allocate a /64 per segment and a /48 per site, and never subnet longer than /64, so SLAAC keeps working and you still have 65 536 subnets to assign from a single site prefix.
  • Duplicate every firewall rule, ACL, and monitoring check across both protocols on any dual-stack host, since an IPv4-only policy leaves IPv6 unfiltered and that gap is invisible until something exploits it.
  • Test the IPv6 path explicitly with ping6 and ip -6 neigh rather than trusting that IPv4 success means both stacks work, because Happy Eyeballs can mask a broken v6 route for users while it quietly slows them down.
  • Use unique local fc00::/7 addresses for internal-only services that should never be globally reachable, the IPv6 way to get private scope without reintroducing NAT.
  • Enable IPv6 on public-facing and mobile-first services early, since mobile carriers increasingly run v6-only with v4 behind translation, and a v4-only service reaches those users through a slower carrier NAT.
Comparable conceptsIPv4 (the incumbent)SLAAC vs DHCPv6 (stateless vs stateful)

Knowledge Check

Why is /64 the standard IPv6 subnet size rather than something smaller to conserve addresses?

  • SLAAC needs a 64-bit interface identifier, so a longer prefix breaks autoconfiguration
  • A /64 is the smallest possible block that IPv6 routers are physically able to forward traffic toward
  • Routers can only advertise prefixes that are exactly /64 in length
  • Multicast requires every subnet to be /64 so groups map cleanly to it

What replaces ARP and broadcast in IPv6?

  • Neighbor Discovery over multicast for address resolution, with multicast groups replacing broadcast
  • A faster broadcast that reaches every node on the link in one frame
  • DHCPv6, which every host on the segment must query in order to resolve its neighbors' link-layer addresses
  • The original ARP, retained unchanged and carried inside IPv6 packets

What is the dual-stack firewall gap that catches operators?

  • IPv4 rules do not cover IPv6, so a host filtered on v4 can sit unprotected on v6
  • A single rule set automatically applies to both, causing rules to double-count traffic
  • IPv6 cannot be firewalled, so dual-stack hosts must disable it to stay safe
  • Link-local fe80:: addresses bypass all firewall rules by design

You got correct