IPv6 fundamentals — 128-bit addressing, headers, ICMPv6, NDP
What you'll learn
- Explain why IPv6 uses 128-bit addresses and a simplified 40-byte header
- Describe the ICMPv6 role that subsumes ARP, router discovery, redirect, and PMTUD
- Identify link-local addresses (fe80::/10) and how EUI-64 builds an interface identifier from a MAC
- Read the IPv6 header and the most common extension headers in a packet capture
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 fundamentals — 128-bit addressing, headers, ICMPv6, NDP
IPv6 is not IPv4 with longer addresses. It is a redesign that takes the lessons of thirty years of IPv4 and bakes them into the protocol. The header is fixed at 40 bytes and fit into the minimum Ethernet MTU. ARP is gone; ICMPv6 takes its place alongside router discovery and redirect. Address assignment is intended to be stateless. The broadcast address disappears and is replaced with a structured multicast architecture.
A production routing engineer who treats IPv6 as “just turn on another address family” gets surprised by every one of these differences. The lesson walks through them so the rest of Part XI — addressing, router advertisements, DHCPv6, routing, and troubleshooting — has a solid foundation to build on.
How an IPv4 packet differs from an IPv6 packet
flowchart LR
subgraph V4["IPv4 header (20-60 bytes)"]
V40[Version 4] --> V41[IHL]
V41 --> V42[TOS / DSCP]
V42 --> V43[Total Length]
V43 --> V44[Identification]
V44 --> V45[Flags + Fragment Offset]
V45 --> V46[TTL]
V46 --> V47[Protocol]
V47 --> V48[Header Checksum]
V48 --> V49[Src / Dst IPv4 32-bit]
end
subgraph V6["IPv6 header (fixed 40 bytes)"]
V60[Version 6] --> V61[Traffic Class]
V61 --> V62[Flow Label]
V62 --> V63[Payload Length]
V63 --> V64[Next Header]
V64 --> V65[Hop Limit]
V65 --> V66[Src / Dst IPv6 128-bit]
end
The IPv4 header is variable-length because of options and the header checksum. The IPv6 header is fixed at 40 bytes. Options that were in the IPv4 header are now chained as extension headers behind the main header. There is no header checksum — the link layer and the transport layer (TCP, UDP) check their own integrity, and removing the checksum from the network header saves work on every hop.
Extension headers replace IPv4 options
flowchart LR
M[Main IPv6 header<br/>Next Header = Routing] --> R[Routing header]
R --> F[Fragment header]
F --> D[Destination Options header]
D --> P[Upper-layer payload<br/>TCP or UDP]
Extension headers are daisy-chained. Each one has its own “Next Header” field that names the next one. The chain ends at the upper-layer protocol. Routers along the path only inspect the main header and any Hop-by-Hop header; everything else is read only by the endpoints. This is why IPv6 forwarding is faster than IPv4 forwarding in many implementations.
The Fragment header is one of the most operationally important.
IPv6 routers do not fragment transit packets — fragmentation is
the sender’s responsibility, using a Path MTU Discovery mechanism
the host runs. If a packet is too big for the path, the router
sends an ICMPv6 Packet Too Big back to the source and drops the
packet. Lesson vyos-xi-06-ipv6-troubleshoot covers PMTUD
failures in detail.
ICMPv6 — three protocols in one
In IPv4, three separate protocols handle what ICMPv6 does alone:
- ARP (Layer 2 / Layer 3 address resolution)
- ICMP (router discovery redirects, unreachable, PMTUD)
- IGMP (multicast group management)
flowchart TB
subgraph ICMPv6[ICMPv6 - protocol number 58]
ND[NDP<br/>type 135 / 136<br/>neighbor solicit / advertise]
RA[Router Advertisement<br/>type 134]
RS[Router Solicitation<br/>type 133]
RED[Redirect<br/>type 137]
TB[Packet Too Big<br/>type 2]
U[Destination Unreachable<br/>type 1]
MLD[MLD<br/>multicast listener discovery]
end
N[IPv6 Node] --> ND
N --> RA
N --> RS
N --> RED
N --> TB
N --> U
N --> MLD
NDP (Neighbor Discovery Protocol) replaces ARP. RA / RS replace the ICMPv4 Router Discovery messages that RFC 1256 added later and that IPv6 builds in from day one. MLD replaces IGMP. Every IPv6 control-plane protocol the operator relies on runs inside ICMPv6.
NDP replaces ARP
sequenceDiagram
autonumber
participant H as Host A<br/>fe80::1
participant R as Router<br/>fe80::2
participant N as Next-hop B<br/>2001:db8::1
H->>R: RS (ICMPv6 type 133)<br/>multicast ff02::2
R-->>H: RA (ICMPv6 type 134)<br/>prefix, lifetime, MTU
Note over H: builds default route to R<br/>with link-local as next-hop
H->>N: NS (ICMPv6 type 135)<br/>who has 2001:db8::1?<br/>solicited-node multicast ff02::1:ff00:1
N-->>H: NA (ICMPv6 type 136)<br/>2001:db8::1 is at MAC
Note over H: kernel caches NA in neighbour table
NDP runs over ICMPv6, which runs over IPv6. It uses
solicited-node multicast instead of broadcast. When Host A wants
the MAC for 2001:db8::1, the kernel computes
ff02::1:ff00:0001 (the last 24 bits of the target address
appended to ff02::1:ff), joins that multicast group on the
interface, and sends the Neighbor Solicitation to that group.
Only the host whose IPv6 ends in ::1 listens to that group, so
the request is delivered without disturbing every host on the
segment.
The Reply is unicast. The host installs the entry in the Linux
neighbour cache, which ip -6 neigh show displays.
Link-local addresses — fe80::/10
Every IPv6 interface that supports multicast automatically
assigns itself a link-local address from fe80::/10. The
interface identifier is built from the MAC using EUI-64 (or
from a random number in modern kernels with
addrgenmode=random).
vyos@vyos:~$ ip -6 addr show eth0
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
inet6 fe80::5054:ff:fe12:3456/64 scope link
inet6 2001:db8::1/64 scope global
The scope link keyword on fe80::5054:ff:fe12:3456 is
Linux’s way of saying “this address is valid only on this link”.
Routers must not forward packets with link-local source or
destination addresses. They are used for:
- Neighbor Discovery (NS / NA)
- Router Solicitation / Router Advertisement
- Routing protocols (OSPFv3, BGP) on the wire — the TCP/UDP sessions use link-local source and destination
EUI-64 from a 48-bit MAC
flowchart LR
A[48-bit MAC<br/>52:54:00:12:34:56] --> B[Insert FF:FE in the middle<br/>52:54:00 FF:FE 12:34:56]
B --> C[Flip bit 6 of byte 0<br/>52→50<br/>50:54:00:FF:FE:12:34:56]
C --> D[Colon form<br/>50:54:00:ff:fe:12:34:56]
D --> E[IPv6 form<br/>fe80::5054:ff:fe12:3456]
The conversion rule:
- Split the MAC in half:
52:54:00and12:34:56. - Insert
FF:FEin the middle. - Flip the Universal/Local bit (bit 6, counting from 1) of the
first byte.
52binary is01010010; flipping bit 6 gives01000010=50. - Combine:
50:54:00:FF:FE:12:34:56. - Prepend
fe80::to get the link-local address.
This is how 52:54:00:12:34:56 becomes
fe80::5054:ff:fe12:3456. The pattern is mechanically
recognisable: every VyOS link-local address on a hypervisor VM
ends in ff:fe followed by the last four bytes of the MAC.
Why IPv6 was redesigned
The IPv4 design problems IPv6 fixed:
- Address exhaustion. 32 bits was a comfortable size in 1980.
By 2010 the free pool was exhausted. 128 bits gives
3.4 × 10^38addresses — enough to give every atom on the Earth’s surface several addresses. - Fragmentation in transit. IPv4 routers fragment packets that are too big for the next link. This is expensive on modern routers with hardware-based forwarding. IPv6 only fragments at the source, using PMTUD.
- Header complexity. IPv4 options are processed by every router along the path. IPv6 extension headers are processed only by the endpoints (except Hop-by-Hop).
- Broadcast. ARP requests broadcast; IPv6 uses solicited-node multicast, so a host only processes the NS for the address it cares about.
- NAT. IPv6’s address space is large enough that every device can have a globally routable address. NAT is not part of the design. (Operators still use NAT66 in narrow cases, but the protocol does not require it.)
How VyOS exposes IPv6 state
vyos@vyos:~$ show ipv6
Interface Address
--------- -------
eth0 2001:db8::1/64
eth0 fe80::5054:ff:fe12:3456/64
lo ::1/128
vyos@vyos:~$ show ipv6 neighbor
IPv6 Address MAC Address Interface
----------- ------------- ---------
fe80::1 52:54:00:aa:bb:cc eth0
2001:db8::5 52:54:00:11:22:33 eth0
INCOMPLETE entries: 0
INCOMPLETE means a Neighbor Solicitation has been sent and no
Neighbor Advertisement has come back. STALE means the entry
is valid but unused for a while. REACHABLE means used within
the last reachable-time window. DELAY and PROBE mean the
kernel is verifying the entry is still valid.
How the result is validated
show ipv6
show ipv6 neighbor
ip -6 addr show
ip -6 neigh show
ip -6 route show
ping6 fe80::1%eth0
ping6 2001:db8::1
traceroute6 2001:db8::1
tcpdump -n -i eth0 ip6
The first two are the VyOS view; the next three are the Linux kernel view; the next two prove reachability; the last one proves the packets are on the wire. The VyOS view and the Linux view must agree. A neighbour entry that shows in one but not the other is a state divergence that needs investigation.
How it fails
The production failure modes the engineer must recognise:
- ICMPv6 blocked on the firewall. NDP fails. The host has no default route and no working neighbour cache. All unicast IPv6 traffic fails.
- Duplicate link-local from EUI-64. Two VyOS VMs with the same MAC (a hypervisor misconfiguration) generate the same link-local. NDP sees the second advertisement and flips the neighbour cache. Traffic alternates between the two hosts.
- Link-local filtered as “private”. A firewall rule
dropping
fe80::/10breaks router discovery. Hosts default to link-local-only addresses and cannot reach the global internet. - MTU 1280 missed. IPv6 requires the path to carry 1280
bytes minimum. A tunnel with lower MTU that does not run
PMTUD correctly silently drops packets larger than its MTU.
Lesson
vyos-li-03-pmtudcovers PMTUD in depth. - No IPv6 default route. RAs suppressed, RS unanswered, or default router flag (router-lifetime) cleared. Hosts have addresses but no route off-link.
Rollback
The recovery from a bad IPv6 fundamentals state:
- ICMPv6 blocked:
delete firewall name ... rule ...and the allow rule re-added beforecommit; save. - Duplicate link-local: regenerate the MAC at the hypervisor and reboot the VM.
- Wrong link-local filter: remove the offending rule,
commit; save. - Missing MTU: reconfigure the tunnel MTU to at least 1280 and verify PMTUD is functional.
Production discipline
Cross-course references
The Linux course’s XIX-Linux-NetFoundations covers the kernel
IPv6 stack and sysctl knobs in detail. The Proxmox course’s
XXIX-Proxmox-Networking covers the host-side IPv6 in the
hypervisor. The OPNsense course’s I-OPNsense-NetFoundations
covers the equivalent IPv6 concepts from the firewall
perspective. The VyOS lesson vyos-i-06-arp-vs-ndp covers the
ARP-vs-NDP comparison that this lesson builds on.
Quiz
Knowledge check · 4 questions
Q1. Which protocol replaces ARP for IPv6?
Q2. An IPv6 router that receives a transit packet too large for the next link drops it and returns ICMPv6 Packet Too Big rather than fragmenting it.
Q3. A host has an IPv6 address but no default route and cannot reach the global internet. The RA flag on the upstream router is set to router-lifetime=0. What does that mean?
Routers send Router Advertisement messages with a Router Lifetime field. Zero means the router is telling hosts to remove it from the default router list. Hosts that see this stop using the router as a default.
Q4. An operator turns off ICMPv6 on the firewall for security. After the change, IPv6 traffic stops working but IPv4 traffic is fine. Why?
ICMPv6 carries NDP, Router Advertisement, and PMTUD. Blocking all ICMPv6 breaks neighbour resolution, which breaks all unicast IPv6. IPv4 still works because its critical protocols (ARP, ICMPv4) are different.
Passing score: 75%. Answers are checked in this browser.