IP addresses and subnets
Read an IPv6 address and prefix
Read compressed IPv6 notation, recognize a prefix, and distinguish global, link-local, and loopback scope.
8 minute lesson
An IPv6 address contains 128 bits and is written in hexadecimal groups of 16 bits, separated by colons. Full addresses are long, so the notation has two shortcuts: leading zeros in a group can be dropped, and one run of zero groups can be compressed with ::. That makes 2001:db8::20 a complete address — it expands to 2001:0db8:0000:0000:0000:0000:0000:0020.
The :: trick is allowed once per address. If it appeared twice, you couldn’t tell how many zero groups each one hides.
IPv6 interfaces also use prefix lengths, and they work exactly like IPv4 CIDR: the prefix names the network, the rest identifies the interface. A /64 leaves 64 bits for the interface identifier and is the usual subnet size for normal LANs. You’ll rarely see anything else on an end-user network.
Read your own addresses
ip -6 address show
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>
inet6 2a01:e0a:4f2:1:8c3a:11ff:fe2b:940c/64 scope global dynamic
inet6 fe80::8c3a:11ff:fe2b:940c/64 scope link
On macOS, ifconfig en0 | grep inet6 shows the same thing. Notice you have more than one IPv6 address, and that’s normal. The scope labels tell you what each is for.
Three scopes to recognize
Addresses beginning with fe80::/10 are link-local and always have local-link scope. Every IPv6 interface gives itself one automatically. It works only on the directly attached link and is never routed anywhere.
::1 is loopback, the IPv6 equivalent of 127.0.0.1:
ping6 -c 1 ::1
# 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.045 ms
Global unicast addresses — in practice, addresses starting with 2 or 3 — can be routed beyond the local network. The 2a01:... address above is what remote servers see when this machine connects over IPv6.
The zone identifier
When a link-local destination could exist on more than one interface, commands may require a zone identifier such as fe80::1%en0. The reason: fe80:: addresses exist per link, so fe80::1 on your Wi-Fi and fe80::1 on your Ethernet are different machines. The %en0 suffix says which interface you mean.
ping6 -c 1 fe80::1%en0
# 64 bytes from fe80::1%en0: icmp_seq=1 ttl=64 time=2.1 ms
Without the zone, the same command typically fails with an Invalid argument style error, because the system can’t pick an interface on its own. If an IPv6 command fails with an odd error on a fe80:: address, a missing zone identifier is the first thing to check.
Lesson completed