IPv6 addressing — global unicast, ULA, link-local, multicast, anycast, prefix delegation
What you'll learn
- Distinguish global unicast, ULA, link-local, multicast, and anycast by prefix
- Allocate a /48 site prefix and carve /64 subnets for production VLANs
- Configure global unicast and link-local on a VyOS interface
- Recognise the address-type errors that surface as routing incidents
Prerequisites
Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling) · 2026-08-15
IPv6 addressing — global unicast, ULA, link-local, multicast, anycast, prefix delegation
A production IPv6 deployment uses every address type the protocol defines, each for a specific job. Global unicast carries public traffic. ULA (Unique Local Addresses) numbers internal infrastructure without colliding with the public internet. Link-local addresses are the on-wire identifiers every interface needs. Multicast replaces broadcast and reaches specific scopes. Anycast picks the nearest of a set of receivers. Prefix delegation lets the upstream hand the downstream a block to subnet.
A routing engineer who treats IPv6 as “bigger IPv4 with /64 everywhere” misses the structure. Each address type has rules about where it can be routed, where it can be the source or destination of a packet, and how it interacts with firewall and NAT policy.
The IPv6 address space at a glance
flowchart TB
subgraph ALL["::/0 - the entire IPv6 space"]
direction LR
GLB["2000::/3<br/>Global Unicast<br/>public, globally routable"]
ULA["fc00::/7<br/>Unique Local<br/>fc00::/8 + fd00::/8<br/>internal, not routed on the public internet"]
LL["fe80::/10<br/>Link-Local<br/>on-link only, never routed"]
MC["ff00::/8<br/>Multicast<br/>one-to-many or many-to-many"]
LG["::/3 - ::/4<br/>Reserved / Unallocated"]
end
The rest of the space — everything outside these blocks — is
reserved, unallocated, or used for special purposes (loopback
::1/128, unspecified ::/128, documentation prefixes
2001:db8::/32, IPv4-mapped ::ffff:0:0/96, discard
100::/64).
Global Unicast in a production estate
flowchart LR
A[IANA<br/>allocates] --> B[RIR<br/>e.g. RIPE]
B --> C[LIR / ISP<br/>/32 or /48]
C --> D[Enterprise site<br/>/48]
D --> E[VLAN 10<br/>2001:db8:1::/64]
D --> F[VLAN 20<br/>2001:db8:2::/64]
D --> G[VLAN 30<br/>2001:db8:3::/64]
A site gets a /48 from its upstream. Inside the /48, the operator carves /64s — one per subnet, one per VLAN. The /64 is the natural unit of IPv6 subnetting because SLAAC and most IPv6 autoconfiguration mechanisms depend on the interface ID being 64 bits wide.
A /48 contains 65536 /64s. That is enough subnets for any realistic production estate without further summarisation.
set interfaces ethernet eth0 ipv6 address '2001:db8:1::1/64'
set interfaces ethernet eth1 ipv6 address '2001:db8:2::1/64'
set interfaces ethernet eth2 ipv6 address '2001:db8:3::1/64'
commit
save
Unique Local Addresses (ULA) — internal numbering
ULA is the right answer when the operator wants stable internal addresses that do not depend on the upstream prefix. If the operator changes ISP, the public prefix changes but the ULA prefix stays. Internal services keep their URLs.
flowchart LR
A[Generate /48 with random global ID] --> B[fd00:1234:5678::/48]
B --> C[Server farm /64<br/>fd00:1234:5678:1::/64]
B --> D[Management /64<br/>fd00:1234:5678:2::/64]
B --> E[Lab /64<br/>fd00:1234:5678:3::/64]
The global ID is a random 40-bit value that makes a ULA /48 collision-free in practice. A common generator:
python3 -c "import random; print('fd' + ''.join(random.choice('0123456789abcdef') for _ in range(10)))"
This produces a candidate global ID. Real generators that
implement RFC 4193 use /dev/urandom and produce a fd followed
by 10 hex characters.
set interfaces ethernet eth0 ipv6 address 'fd00:1234:5678:1::1/64'
set interfaces ethernet eth1 ipv6 address 'fd00:1234:5678:2::1/64'
commit
save
ULA must not be advertised to the public internet. A common mistake is to redistribute a ULA prefix into BGP and have it leak upstream; the upstream’s prefix-list blocks /32 of fc00::/8 and the operator’s traffic blackholes.
Link-Local — automatic and essential
Every IPv6 interface automatically assigns itself a link-local
address from fe80::/10. The interface identifier is built
from the MAC (EUI-64) or from a random number
(addrgenmode=random, default in modern kernels for privacy).
vyos@vyos:~$ show ipv6
Interface Address
--------- -------
eth0 2001:db8:1::1/64
eth0 fe80::5054:ff:fe12:3456/64
The VyOS operator rarely sets a link-local explicitly. It is always present. The exception is when the operator needs a stable link-local for a routing-protocol configuration — in which case the operator sets a “router-advert” link-local or overrides EUI-64:
set interfaces ethernet eth0 ipv6 address 'fe80::1/64'
commit
save
The fe80::/64 notation is allowed; the operator is choosing
the interface ID ::1 instead of letting EUI-64 generate one.
This is the typical pattern for the VyOS box that wants its
upstream router to learn a predictable next-hop.
Multicast — replacing broadcast
IPv6 has no broadcast. Every “send to everyone” use case is
expressed as a multicast to a well-known group. Multicast
addresses start with ff.
flowchart TB
subgraph M["ff00::/8 - Multicast"]
F1["ff02::1<br/>All nodes (link-local)"]
F2["ff02::2<br/>All routers (link-local)"]
F3["ff02::1:ffXX:XXXX<br/>Solicited-node<br/>last 24 bits of target unicast"]
F4["ff05::2<br/>All routers (site-local)"]
F5["ff0e::/16<br/>Global multicast<br/>e.g. NTP, mDNS"]
end
A host joins the solicited-node multicast group for every
unicast address it has. Joining means the kernel installs a
multicast filter on the NIC, so the host only processes packets
destined for groups it has joined. When Host A wants the MAC for
2001:db8:1::5, Host A sends the NS to ff02::1:ff00:5; only
the host whose address ends in ::5 listens to that group, and
only that host processes the NS.
Multicast scope is encoded in the second-lowest-order nibble:
ff01— interface-local (loopback only)ff02— link-local (the segment)ff05— site-local (the routing domain)ff0e— global (the internet)
VyOS subscribes to the relevant scopes for each protocol it
runs. OSPFv3 joins ff02::5 (all-OSPF-routers) and ff02::6
(all-OSPF-designated-routers). BGP does not use multicast
(it uses TCP over a unicast destination).
Anycast — one-to-nearest
Anycast addresses are syntactically identical to unicast addresses but are advertised by multiple routers. The network delivers the packet to the nearest instance (by routing metric). Use cases:
- DNS root servers (each root is
2001:503:ba3e::2:30from anycast) - DNS resolvers (an ISP anycasts its resolver across the globe)
- Service discovery (an internal anycast VIP for the closest proxy)
set interfaces ethernet eth0 ipv6 address '2001:db8:99::1/64'
set protocols static route '2001:db8:99::1/128' interface eth0
The operator advertises the /128 from multiple routers. BGP selects the nearest. The operator must advertise only the /128 and not a covering prefix that would attract traffic for hosts that are not part of the anycast service.
Prefix Delegation — handing subnets to downstream
sequenceDiagram
autonumber
participant ISP as ISP router
participant CPE as Customer VyOS
participant LAN as LAN hosts
ISP->>CPE: RA with prefix 2001:db8:abcd::/48
CPE->>ISP: DHCPv6 Solicit with IA_PD
ISP-->>CPE: DHCPv6 Advertise with IA_PD 2001:db8:abcd::/48
CPE->>ISP: DHCPv6 Request
ISP-->>CPE: DHCPv6 Reply
Note over CPE: assigns 2001:db8:abcd:0::/64 to LAN1<br/>2001:db8:abcd:1::/64 to LAN2
LAN->>CPE: SLAAC or DHCPv6 to learn address
Prefix delegation (PD) is how the upstream hands the downstream a block to subnet. The downstream asks for a prefix via DHCPv6 IA_PD (Identity Association for Prefix Delegation), receives a /48 (typical) or a /56 (smaller sites), and carves /64s for its LANs.
set interfaces ethernet eth0 dhcpv6-options parameters 1
set interfaces ethernet eth0 dhcpv6-options pd 0 length 56
set interfaces ethernet eth0 dhcpv6-options pd 0 interface eth1 prefix ::1/64
set interfaces ethernet eth0 dhcpv6-options pd 0 interface eth2 prefix ::1/64
commit
save
The VyOS asks for a /56 prefix delegation, then assigns
::1/64 from that prefix to LAN interfaces eth1 and eth2.
The lesson vyos-xi-04-dhcpv6 covers PD in depth.
How the address configuration is applied
configure
set interfaces ethernet eth0 ipv6 address '2001:db8:1::1/64'
set interfaces ethernet eth0 ipv6 address 'fd00:1234:5678:1::1/64'
set interfaces ethernet eth1 ipv6 address '2001:db8:2::1/64'
set interfaces ethernet eth1 ipv6 address 'fe80::1/64'
commit
save
A single interface can have multiple IPv6 addresses. The kernel and FRR treat each as a separate source. The operator typically configures:
- A GUA on every interface that needs to be reachable from the public internet
- A ULA on internal-only interfaces
- An explicit or auto link-local on every interface
How the result is validated
show ipv6
show interfaces ethernet eth0
ip -6 addr show
ip -6 route show
ping6 2001:db8:1::1
ping6 fd00:1234:5678:1::1
traceroute6 2001:db8:1::1
The first command shows all IPv6 addresses on all interfaces. The second shows the per-interface details. The third and fourth are the Linux kernel view. The fifth and sixth prove reachability to specific addresses. The seventh proves the forwarding path.
How it fails
The production failure modes the engineer must recognise:
- ULA advertised upstream. A route-map that does not filter
fc00::/7lets ULA into BGP. Upstream providers reject, but the local IGP carries the prefix and traffic stays inside the local AS — unless redistribution sends it further. - GUA mistaken for ULA in firewall rules. A rule that
matches
fc00::/7allows only ULA. A service that should be reachable from the public internet on a GUA is blocked. - Solicited-node multicast filtered. A firewall that does not understand NDP drops the multicast NS. Neighbour resolution fails and unicast traffic fails.
- Wrong prefix length on a downstream interface. A /65 defeats SLAAC (which assumes /64) and breaks PMTUD on some implementations. VyOS 1.5 accepts /65 but warns; operators must use /64 for host subnets.
- /127 used where /64 expected. Some operators use /127 on point-to-point links (RFC 6164). VyOS supports this, but a number of hosts assume /64 for SLAAC and fail to configure their addresses correctly.
Rollback
The recovery from a bad IPv6 address configuration:
- Wrong address:
delete interfaces ethernet eth0 ipv6 address '...'and re-add the correct one beforecommit; save. - Wrong prefix length:
set interfaces ethernet eth0 ipv6 address '2001:db8:1::1/64'with the correct /64. - ULA advertised: add
route-map FILTER-ULA deny 10 match ipv6 address prefix-list BLOCK-ULAand apply to the BGP outbound policy.
Production discipline
Cross-course references
The Linux course’s XIX-Linux-NetFoundations covers the kernel
IPv6 address model and the addrgenmode knobs. The Proxmox
course’s XXIX-Proxmox-Networking covers the host-side IPv6
allocation in the hypervisor. The OPNsense course’s
I-OPNsense-NetFoundations covers the firewall-side
equivalent. The VyOS lesson vyos-xi-01-ipv6-fundamentals
covers the header and ICMPv6 that this lesson assumes.
Quiz
Knowledge check · 4 questions
Q1. Which prefix is the IANA-allocated block for Global Unicast Addresses?
Q2. A /48 site prefix contains 65536 /64 subnets.
Q3. An operator configures a /65 prefix on a customer LAN interface. Hosts that rely on SLAAC fail to autoconfigure their addresses. Why?
SLAAC depends on the subnet prefix being exactly /64 so the interface identifier is 64 bits wide. A /65 splits the address differently and most SLAAC implementations either refuse or compute the wrong identifier.
Q4. An operator generates a ULA prefix and redistributes it into BGP. The upstream provider's prefix-list blocks it, but the operator's own IGP advertises it across the local AS. What is the operational risk?
ULA prefixes are meant for internal use. If they leak into the public BGP, operators on the internet would see traffic for an address space that is not globally routable and would drop it. Even when blocked upstream, internal leakage means internal services are reachable on their ULA addresses from across the corporate AS but not from outside - which is intended, but the operator must ensure no service relies on the ULA being reachable from outside.
Passing score: 75%. Answers are checked in this browser.