IPv6 — Why and How
128-bit addresses, simplified header, no fragmentation by routers, IPv4 exhaustion as the forcing function.
What it is#
IPv6 is the successor to IPv4 — a 128-bit addressing-and-forwarding protocol designed in the mid-1990s to solve the IPv4 address-exhaustion crisis before it actually arrived. It replaces the 32-bit address space (~4.3 billion) with a 128-bit one (~3.4 * 10^38), simplifies the header, eliminates router-driven fragmentation, drops the header checksum, and bakes in autoconfiguration that does not require DHCP.
The wire format is incompatible with IPv4: an IPv6 packet has Ethertype 0x86DD instead of 0x0800. Hosts and routers must implement both protocols to participate in today’s Internet, a deployment shape known as dual-stack. The migration has been slow — IPv6 was specified in RFC 1883 in 1995 and finalised in RFC 8200 in 2017 — but adoption now exceeds 40% globally (as measured by Google’s IPv6 statistics page) with mobile carriers and large clouds leading.
The motivating constraint is arithmetic: every device, every container, every IoT sensor wants an address. IPv4 plus NAT papered over the gap; IPv6 fixes it structurally.
When to use it#
Reach for IPv6 when you control the network and want to avoid NAT, or when you operate at a scale where IPv4 leases are a budget line:
- Datacenter fabrics and Kubernetes clusters. Pod-per-IP demands huge address space;
10.0.0.0/8(16M addresses) runs out at planet-scale. Many fabrics are IPv6-only internally with dual-stack at the edge. - Mobile carriers. T-Mobile USA, Reliance Jio, and Verizon LTE run IPv6 as the default; IPv4 reaches legacy destinations via NAT64.
- Anything peer-to-peer. End-to-end reachability without hole-punching: WebRTC, IoT, gaming, mesh networks.
- Public services where dual-stack costs nothing. A
AAAArecord alongside theArecord gives IPv6-only clients a fast path. Cloudflare, Google, and Facebook publish both.
Stay on IPv4 (or dual-stack) when middleboxes in your path are IPv4-only, when legacy applications hard-code IPv4 socket APIs, or when an ISP charges extra for IPv6 transit (rare but real on small business links).
How it works#
Addresses#
128 bits, written as eight colon-separated 16-bit hextets: 2001:0db8:85a3:0000:0000:8a2e:0370:7334. Two compression rules shorten the notation:
- Leading zeros in a hextet are dropped:
0db8becomesdb8. - The longest run of all-zero hextets is replaced by
::(once per address): the example becomes2001:db8:85a3::8a2e:370:7334.
The address is split into a 64-bit network prefix and a 64-bit interface identifier. Subnets are conventionally /64 — every subnet has 2^64 host addresses, which is approximately 18 quintillion. The /64 boundary is load-bearing: SLAAC, multicast address derivation, and many ND mechanisms assume it.
Special ranges worth memorising:
::/128 — unspecified (analogous to 0.0.0.0)::1/128 — loopback (analogous to 127.0.0.1)fe80::/10 — link-local (every interface has one, auto-generated)fc00::/7 — unique local addresses (RFC 4193, analogous to RFC 1918)2000::/3 — global unicast (the public Internet)ff00::/8 — multicast (no broadcast in IPv6)2001:db8::/32 — documentation prefix (RFC 3849)There is no broadcast in IPv6 — its role is taken by well-known multicast groups (ff02::1 is “all nodes on this link”).
The IPv6 header#
40 bytes, fixed length. Variable-length information moves into optional extension headers chained after the main header.
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Version| Traffic Class | Flow Label |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Payload Length | Next Header | Hop Limit |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| |+ +| |+ Source Address (128 bits) +| |+ +| |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| |+ +| |+ Destination Address (128 bits) +| |+ +| |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Compared with IPv4: no IHL (fixed length), no Identification/Flags/Fragment Offset (no router fragmentation), no header checksum (relies on link CRC and upper-layer checksums), no Options field (replaced by extension headers). The Next Header field plays the role of IPv4’s Protocol — 6 for TCP, 17 for UDP, 58 for ICMPv6 — or names the next extension header.
Autoconfiguration (SLAAC)#
A host coming up on an IPv6 link:
- Generates a link-local address
fe80::/64from its MAC (modified EUI-64) or a random 64-bit identifier (RFC 7217 / privacy extensions). - Performs Duplicate Address Detection by multicasting a Neighbor Solicitation for that address; if no reply, the address is unique.
- Sends a Router Solicitation to
ff02::2(all routers). - Receives a Router Advertisement carrying the on-link prefix(es) and gateway. Configures a global unicast address by combining the prefix with its interface identifier.
No DHCP server is required for plain address assignment. DHCPv6 still exists for handing out DNS resolvers and other configuration (stateful DHCPv6), or hosts can use Recursive DNS Server (RDNSS) options inside Router Advertisements.
Neighbor Discovery and ICMPv6#
IPv6 collapses ARP, ICMP, and parts of IGMP into ICMPv6. Neighbor Solicitation / Neighbor Advertisement messages resolve link-layer addresses (replacing ARP). Router Solicitation / Router Advertisement handle gateway discovery. Redirect, Packet Too Big, and Time Exceeded messages carry the same diagnostics as IPv4 ICMP.
Fragmentation#
IPv6 routers never fragment. If a packet is too big for an outgoing link, the router drops it and sends ICMPv6 Packet Too Big back to the source. The source then either fragments at the source (via a Fragment extension header) or reduces its segment size. PMTUD is mandatory rather than optional.
Variants#
- Dual-stack. Hosts run IPv4 and IPv6 simultaneously. Applications use Happy Eyeballs (RFC 8305) to race the two stacks and pick the faster one — typically IPv6 wins by
~50ms. - IPv6-only with NAT64 / DNS64. Internal network is IPv6; a gateway synthesizes IPv4 destinations into IPv6 (
64:ff9b::/96) and translates packets. Common on iOS and inside large clouds. - 464XLAT (RFC 6877). Mobile carriers use this on IPv6-only access: a customer-side translator presents IPv4 to legacy apps, encapsulates into IPv6 to the carrier NAT64.
- Tunnels — 6in4, 6to4, Teredo. Encapsulate IPv6 inside IPv4 to traverse IPv4-only paths. 6to4 (
2002::/16) is mostly deprecated; managed tunnels from Hurricane Electric remain useful for testing. - SLAAC vs DHCPv6. Stateless (SLAAC + RDNSS) is simplest. Stateful DHCPv6 is preferred in enterprises that need lease records and per-host policy. Android famously refuses to implement DHCPv6 — SLAAC only.
- Unique Local Addresses (
fc00::/7). The IPv6 analogue of RFC 1918; non-routable on the public Internet, used for internal-only services.
Trade-offs#
Other tensions:
- Header simplicity vs flexibility. Extension headers move options out of the main header but some firewalls drop packets with unfamiliar extension headers — making the option mechanism less usable than designed.
- No NAT by default. Restored reachability is good for protocols but security-policy work that NAT incidentally enforced (random hosts cannot dial in) must now be explicit firewall rules.
/64per subnet always. Generous on address space but operationally weird — even a point-to-point link burns a/64(or by convention a/127).- Privacy. EUI-64 addresses encode the device MAC; trackable across networks. RFC 7217 stable-but-opaque identifiers and the temporary-address mechanism (RFC 8981) fix this.
Why did IPv6 take 25+ years to deploy?
The protocol was finalised in 1995, but until IPv4 exhaustion bit hard there was no carrot or stick. NAT plus CGNAT papered over the shortage cheaply enough that every individual operator had a rational reason to defer the migration. Network effects worked against IPv6 too — there was no point reaching IPv6-only destinations until they existed. Adoption finally accelerated when (a) mobile carriers ran out of IPv4 (~2012), (b) cloud providers started charging for IPv4 addresses (AWS made public IPv4 paid in 2024), and (c) Happy Eyeballs made dual-stack safe to ship by default.
Common pitfalls#
- Filtering ICMPv6 like ICMP. Breaks PMTUD, Neighbor Discovery, and SLAAC. Whitelist the types RFC 4890 requires.
- Hard-coding
/64-or-shorter assumptions. Some applications crash on/127point-to-point links; some on prefixes longer than/64. Test before deploying tight prefixes. - Treating link-local addresses as routable.
fe80::addresses are valid only on the interface they were generated for. They must be written with a zone index (fe80::1%eth0). - Forgetting dual-stack means dual-firewall.
iptablesandip6tablesare separate rule sets on Linux;nftablesunifies them. A rule that blocks SSH on IPv4 does nothing to IPv6 by default. - Believing IPv6 is automatically more secure. It restores reachability that NAT incidentally hid. Without explicit firewall rules, every internal host is dialable from outside. Treat IPv6 firewalls as required, not optional.
- DNS reverse-zone confusion. IPv4 reverse is
in-addr.arpa; IPv6 isip6.arpawith nibble-by-nibble reversal. Most engineers script-generate these and skip the by-hand drill. - Address allocation that wastes /48s. RIRs hand out
/32to small ISPs and/48to organisations; using a single/64for a whole site is fine for home but wasteful at scale — reserve/48per site for future subnetting. - Confusing
::(any) with::1(loopback). One letter, opposite meanings.
Related building blocks#