IPv6 has been "coming next year" since about 1998. By now, it is genuinely deployed: mobile networks run IPv6-only with NAT64 for legacy IPv4 services, every major cloud provider supports dual-stack VPCs, and Apple's App Store has required IPv6 compatibility since 2016. If your career as a network engineer is going to outlast IPv4 (it probably is), you need to understand IPv6.
The good news: IPv6 is conceptually simpler than IPv4 once you adopt it. No NAT, no broadcasts, no address scarcity, no classful baggage. The bad news: 30 years of accumulated IPv4 muscle memory has to be unlearned for some parts. This guide walks through the differences that matter for daily network engineering work.
Address format and notation
An IPv6 address is 128 bits — four times the size of IPv4. Written as eight groups of four hex digits separated by colons: 2001:0db8:0000:0000:0000:0000:0000:0001.
That is too much to type, so IPv6 has two compression rules:
- Drop leading zeros in each group:
2001:0db8:0000:0000:0000:0000:0000:0001becomes2001:db8:0:0:0:0:0:1. - Compress one run of all-zero groups to
:::2001:db8:0:0:0:0:0:1becomes2001:db8::1.
You can only use :: once per address, otherwise the count of zero groups is ambiguous. So 2001::1::5 is invalid.
For practice and documentation, always use the RFC 3849 documentation prefix 2001:db8::/32. It is the IPv6 equivalent of the TEST-NETs in IPv4 — blackhole-routed, safe to use in examples, and will never be assigned to a real network.
The /64 rule: every LAN is exactly a /64
This is the single most important IPv6 concept to internalize. Every IPv6 LAN segment is exactly a /64. Not /63, not /65, not /48 — exactly /64.
This is structural, not a recommendation. SLAAC (stateless address autoconfiguration), privacy extensions, and EUI-64 all require exactly 64 bits for the interface ID. If your LAN is a /65, SLAAC breaks. If it is a /48, SLAAC works but you have wasted a 16-bit chunk of address space that could have been used for additional subnets.
Engineers coming from IPv4 panic at the apparent waste. A /64 contains 2^64 = 18 quintillion addresses for one LAN of a few hundred hosts. But IPv6 addresses are practically infinite — there are 3.4 × 10^38 total IPv6 addresses. Even with /64 per LAN, you cannot run out at any imaginable scale.
The IPv6 allocation hierarchy
/48 one site (your organization's allocation)
/56 one branch office or sub-site (256 LANs)
/64 one LAN segment (a VLAN, a broadcast domain)
If your ISP only gives you a /64 for a business connection, push back. The standard expectation is a /48 for businesses and /56 or /60 for residential connections. A /64 allocation means you cannot subnet internally — every device shares one LAN, which is operationally constraining.
Address types you need to know
| Range | Name | Equivalent in IPv4 |
|---|---|---|
| 2000::/3 | Global Unicast (GUA) | Public addresses |
| fc00::/7 | Unique Local (ULA) | RFC 1918 (10/8, 172.16/12, 192.168/16) |
| fe80::/10 | Link-local | 169.254.0.0/16 (APIPA) |
| ::1/128 | Loopback | 127.0.0.1 |
| ::/0 | Default route | 0.0.0.0/0 |
| ff00::/8 | Multicast | 224.0.0.0/4 |
| 2001:db8::/32 | Documentation | 192.0.2.0/24 (RFC 5737) |
ULA: the IPv6 RFC 1918
For private networks (the IPv6 equivalent of your 10.0.0.0/8 internal range), use ULA from the fd00::/8 half of the fc00::/7 block.
Critically, ULA addresses are structured as fd + 40-bit random Global ID + 16-bit subnet + 64-bit interface ID. The Global ID must be random. RFC 4193 explicitly forbids memorable values like fd00:1::, because randomness prevents collisions when companies later interconnect. If two organizations both use fd00:1::/48 and merge, they have a re-IPing event on their hands — exactly the IPv4 RFC 1918 problem that prompted ULA to add randomness in the first place.
Generate a ULA prefix with: openssl rand -hex 5. Use those 5 bytes (40 bits) as your Global ID. Result: something like fd7a:c9b1:e3f2::/48 — your private allocation for the lifetime of the organization.
Link-local: always present
Every IPv6 interface automatically has a link-local address in fe80::/10. This exists before any DHCPv6 or SLAAC has happened, derived from the MAC address (EUI-64) or randomly assigned.
Link-local is used by IPv6's neighbor discovery protocol (NDP, the ARP replacement), router advertisements, and IGP control planes (OSPFv3 peers over link-local). You cannot route link-local traffic. To ping a link-local address, you must specify the interface: ping fe80::1%eth0.
SLAAC vs DHCPv6
In IPv4, you got an address from DHCP. In IPv6, hosts can self-configure two ways:
- SLAAC (Stateless Address Autoconfiguration) — the router announces the /64 prefix in a Router Advertisement, and the host appends its own 64-bit interface ID (random or EUI-64). No central server needed. Works out of the box on any modern OS.
- DHCPv6 — works like IPv4 DHCP, with a server tracking leases. Required for fixed-address assignment and for getting DNS server info on platforms that do not support RDNSS (Router Advertisement DNS).
Production networks often run both: SLAAC for the address itself (so hosts work even if DHCP is down) and DHCPv6-stateless for DNS server info. Note that Android historically did not support stateful DHCPv6 at all; this has only recently been changing.
NDP replaces ARP
IPv4's ARP is replaced by NDP (Neighbor Discovery Protocol), which runs over ICMPv6. Five NDP message types:
- Router Solicitation (RS) — host asks "are there any routers?"
- Router Advertisement (RA) — router announces itself and the /64 prefix
- Neighbor Solicitation (NS) — "who has this IP?" (like ARP request)
- Neighbor Advertisement (NA) — "I do" (like ARP reply)
- Redirect — "use a better gateway"
NS and NA use solicited-node multicast (ff02::1:ff00:0/104) instead of broadcast, which is more efficient than ARP at scale because only hosts with matching solicited-node addresses process the packet.
Privacy extensions: rotating temporary addresses
The original SLAAC algorithm derived the 64-bit interface ID from the MAC address (EUI-64). This is bad for privacy — every site you visit can correlate you across networks because your interface ID never changes.
RFC 4941 (privacy extensions) fixes this by generating random interface IDs that rotate on a schedule (typical default: 24 hours). Modern operating systems enable this by default.
The side effect: a host has multiple IPv6 addresses simultaneously. A stable EUI-64 address for inbound services, plus one or more temporary addresses used for outbound traffic. ip -6 addr show on Linux reveals both. This is normal and expected.
NAT64: connecting IPv6 hosts to IPv4 services
Mobile carriers (T-Mobile US, Reliance Jio) have deployed IPv6-only networks since the mid-2010s. To let those devices reach legacy IPv4 services, they use NAT64 with the well-known prefix 64:ff9b::/96 (RFC 6052).
An IPv6 client looks up example.com via DNS64, receives a synthesized AAAA record like 64:ff9b::93.184.216.34 (the IPv4 address embedded in the last 32 bits of the IPv6 address), and connects. The NAT64 gateway intercepts that traffic, extracts the IPv4 destination, and forwards the connection over IPv4 to the real server.
This is how IPv6-only deployment works at scale today. The transition to fully IPv6-only is a generational change, but the mechanisms are in place.
Operational differences from IPv4
No broadcast
IPv6 eliminated broadcast entirely. The equivalent operations use multicast in ff00::/8. ff02::1 sends to all nodes on the link. ff02::2 sends to all routers. This is more efficient because only hosts subscribed to a group process the multicast — no broadcast storms.
No NAT
Every host gets a real, globally unique address. NAT exists in IPv6 (NAT66, NPTv6) but is generally discouraged. The combination of ULA for private networks and GUA for public addressing makes NAT unnecessary in most cases.
Larger MTU minimum
IPv4 must support a minimum MTU of 68 bytes. IPv6 mandates a minimum of 1280 bytes. This simplifies fragmentation: routers no longer fragment packets in transit; only endpoints fragment. If a router gets a packet too large for the next-hop MTU, it sends ICMPv6 "Packet Too Big" and drops it. The sender shrinks future packets accordingly.
Stateful routing protocols changed
Most IPv4 routing protocols have IPv6 versions: OSPFv2 → OSPFv3, EIGRPv4 → EIGRPv6, RIPv2 → RIPng. Modern designs lean toward IS-IS (always multi-protocol) and BGP (which carries IPv6 prefixes in the multiprotocol extension).
Common IPv6 mistakes
- Treating /64 as wasteful. It is mandatory. Always /64 per LAN.
- Using memorable ULA prefixes. Defeats the purpose. Use
openssl rand. - Filtering all ICMPv6 at the firewall. NDP and Path MTU Discovery depend on ICMPv6. You must allow neighbor discovery messages and "Packet Too Big" (type 2). RFC 4890 documents what to allow.
- Hardcoding IPv4 assumptions in scripts. Regex for "an IP address" usually matches
123.45.67.89but not2001:db8::1. Audit your tooling. - Not testing dual-stack. A host can have working IPv4 and broken IPv6 (or vice versa). Test both, because clients with broken IPv6 fall back slowly and your service appears slow.
Calculator support
Our CIDR calculator supports IPv6 alongside IPv4. Enter any IPv6 CIDR like 2001:db8::/48 and you get the prefix length, total addresses, and subnet breakdown. The VLSM Designer supports IPv6 prefix planning if you need to allocate multiple /64s from a /48 site allocation.
Key takeaways
- Every IPv6 LAN is exactly a /64. Not an option.
- Hierarchy: /48 site → /56 site or /60 residential → /64 LAN.
- Use ULA from fd00::/8 with a random Global ID for private networks. Never invent memorable prefixes.
- Link-local addresses (fe80::/10) are always present; you can ping them but must specify the interface.
- SLAAC autoconfigures addresses without a server. DHCPv6 exists for stateful assignment and DNS info.
- NDP replaces ARP. NAT64 bridges IPv6-only clients to IPv4 servers.
- Allow ICMPv6 in firewalls (selectively — see RFC 4890). It is not the same as IPv4 ICMP.