Why IPv6 Finally Matters (Even in Your Lab)
The “we’ll migrate to IPv6 someday” conversation has been happening in network meetings for two decades. That day has arrived — not as a distant migration but as an operational reality. ISPs are running dual-stack, cloud providers are prioritizing IPv6 endpoints, and carrier networks are deploying IPv6-only segments with NAT64 translation for legacy services. If you manage Cisco gear running IOS-XE and you haven’t gotten hands-on with IPv6, this guide is for you.
We’re going to cover the full stack: enabling IPv6 on IOS-XE interfaces, configuring OSPFv3 for IPv6 routing, setting up DHCPv6 prefix delegation for downstream devices, and verifying everything with real show commands and their expected output. No hand-waving — every command block is tested syntax you can paste into a terminal.
IPv6 Address Types You Need to Know
Before touching a router, you need a firm mental model of IPv6 address types, because IOS-XE will generate some automatically and you need to know what’s what.
- Link-Local (FE80::/10): Auto-generated on every IPv6-enabled interface. Used for neighbor discovery and routing protocol hellos — they never leave the local segment. Format:
FE80::xxxx/64 - Global Unicast (2000::/3): The routable internet-facing addresses. Think of these as the IPv6 equivalent of public IPv4 addresses.
- Unique Local (FC00::/7): Similar to RFC 1918 private space, but rarely used in enterprise WAN designs. You’ll see these in lab environments.
- Multicast (FF00::/8): Replaces IPv4 broadcast. Routing protocols like OSPFv3 use multicast groups (FF02::5 for all OSPF routers, FF02::6 for DR/BDR).
A key concept: every interface running IPv6 gets a link-local address whether you configure one or not. That link-local address is what OSPF and neighbor discovery will use on the local segment, which is why you’ll see FE80::... addresses appear in routing tables as next-hops.
Enabling IPv6 on IOS-XE
By default, IOS-XE has IPv6 CEF disabled. Step one on any device is:
Router# configure terminal
Router(config)# ipv6 unicast-routing
Router(config)# ipv6 cef
ipv6 unicast-routing enables the IPv6 routing engine. Without it, the router will drop transit IPv6 packets. ipv6 cef enables Cisco Express Forwarding for IPv6, which is critical for performance on any production box.
Now assign addresses to interfaces. We’ll configure a dual-stack scenario — a core router with two Layer 3 interfaces, each carrying both IPv4 and IPv6:
Router(config)# interface GigabitEthernet0/0/0
Router(config-if)# description WAN Uplink - ISP1
Router(config-if)# ip address 203.0.113.2 255.255.255.252
Router(config-if)# ipv6 address 2001:DB8:CAFE:1::2/64
Router(config-if)# ipv6 enable
Router(config-if)# no shutdown
Router(config)# interface GigabitEthernet0/0/1
Router(config-if)# description LAN - Access Layer
Router(config-if)# ip address 10.10.10.1 255.255.255.0
Router(config-if)# ipv6 address 2001:DB8:CAFE:A::1/64
Router(config-if)# ipv6 enable
Router(config-if)# no shutdown
The ipv6 enable command ensures the link-local address is generated even if you also configure a global unicast address manually. It’s good practice to include it explicitly.
Verifying Interface Configuration
Router# show ipv6 interface GigabitEthernet0/0/1
GigabitEthernet0/0/1 is up, line protocol is up
IPv6 is enabled, link-local address is FE80::1:2:3:4
No Virtual link-local address(es):
Global unicast address(es):
2001:DB8:CAFE:A::1, subnet is 2001:DB8:CAFE:A::/64
Joined group address(es):
FF02::1
FF02::2
FF02::1:FF00:1
FF02::1:FF03:4
MTU is 1500 bytes
ICMP error messages limited to one every 100 milliseconds
ICMP redirects are enabled
ICMP unreachables are sent
ND DAD is enabled, number of DAD attempts: 1
ND reachable time is 30000 milliseconds (using 30000)
ND NS retransmit interval is 1000 milliseconds
Note the multicast groups joined automatically: FF02::1 (all nodes) and FF02::2 (all routers). The solicited-node multicast addresses (FF02::1:FFxx:xxxx) are derived from the interface address and used for Neighbor Discovery — the IPv6 replacement for ARP.
SLAAC vs DHCPv6: Choosing Your Address Assignment Model
IPv6 gives you three ways to assign addresses to hosts: SLAAC (Stateless Address Autoconfiguration), stateful DHCPv6, and stateless DHCPv6. Understanding the difference matters for designing your deployment.
SLAAC lets hosts construct their own global address from the prefix advertised in Router Advertisements (RAs) combined with a locally-generated interface ID. No server required. Configure RA advertisements on the IOS-XE interface:
Router(config)# interface GigabitEthernet0/0/1
Router(config-if)# ipv6 nd prefix 2001:DB8:CAFE:A::/64
Router(config-if)# no ipv6 nd ra suppress
Hosts on the LAN segment will pick up the 2001:DB8:CAFE:A::/64 prefix and generate their own /128 address. Simple and stateless — but you lose visibility into which host has which address.
Stateful DHCPv6 works like IPv4 DHCP: a server assigns full addresses and tracks leases. Configure a DHCPv6 pool on IOS-XE:
Router(config)# ipv6 dhcp pool LAN-POOL
Router(config-dhcpv6)# address prefix 2001:DB8:CAFE:A::/64 lifetime 86400 43200
Router(config-dhcpv6)# dns-server 2001:4860:4860::8888
Router(config-dhcpv6)# domain-name ignaonline.lab
Router(config)# interface GigabitEthernet0/0/1
Router(config-if)# ipv6 dhcp server LAN-POOL
Router(config-if)# ipv6 nd managed-config-flag
Router(config-if)# ipv6 nd other-config-flag
The managed-config-flag (M flag) in RA messages tells hosts to use DHCPv6 for address assignment. The other-config-flag (O flag) tells hosts to use DHCPv6 for other parameters (DNS, domain name) even if they SLAAC their address.
DHCPv6 Prefix Delegation (PD) — The Real Enterprise Use Case
Prefix Delegation is where IPv6 routing gets interesting. Instead of routing a /64 to every subnet and subnetting from there, ISPs delegate a larger prefix (typically /48 or /56) to customer routers, which then subnet it for their internal networks. This is how cable modems and enterprise edge routers get IPv6 today.
Here’s how to configure IOS-XE as a DHCPv6-PD client (receiving a prefix from the ISP) and then as a DHCPv6-PD server (delegating sub-prefixes to downstream routers). For the client side, no pool definition is required — the PD request is configured directly on the WAN interface:
! WAN interface: request a prefix from ISP via DHCPv6-PD
! Client mode needs no ipv6 dhcp pool — interface config only
Router(config)# interface GigabitEthernet0/0/0
Router(config-if)# ipv6 address autoconfig
Router(config-if)# ipv6 dhcp client pd ISP-PREFIX rapid-commit
! Now delegate sub-prefixes to downstream routers
Router(config)# ipv6 local pool DELEGATE-POOL 2001:DB8:ACAD::/48 56
! (pool prefix/len, prefix to delegate/len)
Router(config)# ipv6 dhcp pool DOWNSTREAM-PD
Router(config-dhcpv6)# prefix-delegation pool DELEGATE-POOL lifetime 172800 86400
Router(config)# interface GigabitEthernet0/0/2
Router(config-if)# description Downstream to Branch Router
Router(config-if)# ipv6 dhcp server DOWNSTREAM-PD
A downstream branch router would be configured as a PD client:
! Branch router WAN interface
Branch(config)# interface GigabitEthernet0/0/0
Branch(config-if)# ipv6 address autoconfig
Branch(config-if)# ipv6 dhcp client pd SITE-PREFIX
! Apply delegated prefix to LAN interface (uses ::1 as host ID)
Branch(config)# interface GigabitEthernet0/0/1
Branch(config-if)# ipv6 address SITE-PREFIX ::1:0:0:0:1/64
Verify the delegated prefix is being handed out:
Router# show ipv6 dhcp binding
Client: FE80::2:3:4:5
DUID: 00030001AABBCCDDEEFF
Username : unassigned
VRF : default
Interface : GigabitEthernet0/0/2
IA PD: IA ID 0x00000001, T1 86400, T2 86400
Prefix: 2001:DB8:ACAD:0100::/56
preferred lifetime 86400, valid lifetime 172800
expires at Jul 25 2026 03:24 AM
OSPFv3 for IPv6 Routing
If you’re comfortable with OSPFv2 for IPv4, OSPFv3 will feel familiar but has a few key differences. OSPFv3 operates over link-local addresses, supports multiple address families (IPv4 and IPv6 simultaneously with the AF extension), and uses a different LSA type set.
Configure OSPFv3 in address-family mode (the modern IOS-XE approach for IOS-XE 3.x and later):
Router(config)# router ospfv3 1
Router(config-router)# router-id 1.1.1.1
Router(config-router)# address-family ipv6 unicast
Router(config-router-af)# passive-interface default
Router(config-router-af)# no passive-interface GigabitEthernet0/0/0
Router(config-router-af)# no passive-interface GigabitEthernet0/0/1
Router(config-router-af)# exit-address-family
! Apply OSPFv3 to interfaces
Router(config)# interface GigabitEthernet0/0/0
Router(config-if)# ospfv3 1 ipv6 area 0
Router(config)# interface GigabitEthernet0/0/1
Router(config-if)# ospfv3 1 ipv6 area 0
The alternative legacy syntax (ipv6 ospf 1 area 0 under the interface) still works but the address-family model is preferred in modern IOS-XE because it supports both IPv4 and IPv6 under the same OSPF process.
Verifying OSPFv3 Neighbors and Routes
Router# show ospfv3 neighbor
OSPFv3 1 address-family ipv6 (router-id 1.1.1.1)
Neighbor ID Pri State Dead Time Interface ID Interface
2.2.2.2 1 FULL/BDR 00:00:36 5 GigabitEthernet0/0/0
3.3.3.3 1 FULL/DR 00:00:32 6 GigabitEthernet0/0/1
Router# show ipv6 route ospf
IPv6 Routing Table - default - 8 entries
Codes: C - Connected, L - Local, S - Static, U - Per-user Static route
B - BGP, R - RIP, H - NHRP, I1 - ISIS L1, I2 - ISIS L2, IA - ISIS interarea
IS - ISIS summary, D - EIGRP, EX - EIGRP external, ND - ND Default
NDp - ND Prefix, DCE - Destination, NDr - Redirect, RL - RPL
O - OSPF Intra, OI - OSPF Inter, OE1 - OSPF ext 1, OE2 - OSPF ext 2
ON1 - OSPF NSSA ext 1, ON2 - OSPF NSSA ext 2, la - LISP alt
lr - LISP site-registrations, ld - LISP dyn-eid, lA - LISP away
O 2001:DB8:CAFE:B::/64 [110/2]
via FE80::2:3:4:5, GigabitEthernet0/0/0
O 2001:DB8:CAFE:C::/64 [110/2]
via FE80::6:7:8:9, GigabitEthernet0/0/1
Notice that OSPFv3 next-hops are link-local addresses — this is expected and correct. When a packet arrives destined for 2001:DB8:CAFE:B::/64, IOS-XE knows to forward it out Gi0/0/0 toward neighbor FE80::2:3:4:5.
Common IOS-XE IPv6 Troubleshooting Commands
Here are the essential verification and troubleshooting commands you’ll reach for daily:
! Check IPv6 interface status and addresses
show ipv6 interface brief
! Show full IPv6 routing table
show ipv6 route
! Verify OSPFv3 process and database
show ospfv3 1 ipv6 database
! Check neighbor discovery cache (IPv6 equivalent of ARP table)
show ipv6 neighbors
! Debug ND (use with caution in production)
debug ipv6 nd
! Verify DHCPv6 server operation
show ipv6 dhcp pool
show ipv6 dhcp binding
! Check IPv6 CEF forwarding entries
show ipv6 cef
! Ping with specific source
ping ipv6 2001:DB8:CAFE:B::1 source GigabitEthernet0/0/1 repeat 5
! Traceroute in IPv6
traceroute ipv6 2001:DB8:CAFE:C::1
IPv6 ACLs on IOS-XE
IPv6 ACLs work similarly to named IPv4 ACLs. One important difference: you must explicitly permit ICMPv6 for Neighbor Discovery to work. Blocking all ICMPv6 will break connectivity even if your data plane rules look correct.
Router(config)# ipv6 access-list BLOCK-UNWANTED-V6
Router(config-ipv6-acl)# permit icmp any any nd-na
Router(config-ipv6-acl)# permit icmp any any nd-ns
Router(config-ipv6-acl)# permit tcp 2001:DB8:CAFE::/48 any eq 22
Router(config-ipv6-acl)# permit tcp 2001:DB8:CAFE::/48 any eq 443
Router(config-ipv6-acl)# permit icmp any any echo
Router(config-ipv6-acl)# permit icmp any any echo-reply
Router(config-ipv6-acl)# deny ipv6 any any log
Router(config)# interface GigabitEthernet0/0/0
Router(config-if)# ipv6 traffic-filter BLOCK-UNWANTED-V6 in
The nd-na (Neighbor Advertisement) and nd-ns (Neighbor Solicitation) permits are mandatory. Without them, hosts can’t resolve link-layer addresses and traffic dies silently.
Gotchas and Real-World Issues
Router Advertisement flooding: If you have Windows or Linux hosts generating rogue RAs on a segment, use RA Guard on downstream switches to block unauthorized advertisements. On IOS-XE switches:
Switch(config)# ipv6 nd raguard policy BLOCK-ROGUE
Switch(config-nd-raguard)# device-role host
Switch(config)# interface GigabitEthernet1/0/1
Switch(config-if)# ipv6 nd raguard attach-policy BLOCK-ROGUE
MTU issues: IPv6 requires a minimum MTU of 1280 bytes. Unlike IPv4, IPv6 routers don’t fragment packets — only the source host does. If your path MTU discovery (PMTUD) is broken (firewalls blocking ICMPv6 “Packet Too Big”), connections will hang. Always permit ICMPv6 type 2 through firewalls.
Link-local in routing tables: New engineers are sometimes alarmed to see FE80::xxxx as OSPF next-hops. This is correct behavior — link-locals are valid next-hops because the outbound interface is also specified. Don’t add static routes to fix this; it’s not broken.
Duplicate Address Detection (DAD) failures: If an interface is flapping up/down, DAD may not complete and the global unicast address won’t enter service. Check with show ipv6 interface GigabitEthernet0/0/0 | include tentative. If you see “tentative”, wait or increase DAD retries: ipv6 nd dad attempts 3.
Putting It All Together: A Reference Topology
For a typical dual-stack enterprise edge config with OSPFv3, here’s the complete minimal configuration for a core router:
! Global IPv6 enablement
ipv6 unicast-routing
ipv6 cef
! WAN interface
interface GigabitEthernet0/0/0
description ISP Uplink
ip address 203.0.113.2 255.255.255.252
ipv6 address 2001:DB8:1:1::2/64
ipv6 enable
ospfv3 1 ipv6 area 0
no shutdown
! LAN interface
interface GigabitEthernet0/0/1
description Access LAN
ip address 10.0.1.1 255.255.255.0
ipv6 address 2001:DB8:1:A::1/64
ipv6 enable
ipv6 nd managed-config-flag
ipv6 dhcp server LAN-POOL
ospfv3 1 ipv6 area 0
no shutdown
! DHCPv6 for LAN hosts
ipv6 dhcp pool LAN-POOL
address prefix 2001:DB8:1:A::/64 lifetime 86400 43200
dns-server 2001:4860:4860::8888
domain-name ignaonline.lab
! OSPFv3
router ospfv3 1
router-id 1.1.1.1
address-family ipv6 unicast
passive-interface default
no passive-interface GigabitEthernet0/0/0
no passive-interface GigabitEthernet0/0/1
What’s Next
IPv6 deployment on IOS-XE is approachable once you understand the address model and how ND replaces ARP. The big operational shift is in your ACLs and firewall rules — permitting the right ICMPv6 types is non-negotiable, and many IPv6 outages trace back to overly aggressive ICMP blocking.
If you’re building this into a larger network, pair your IPv6 routing with solid monitoring. I covered SNMP v3 and LibreNMS for Cisco monitoring in an earlier post — most modern NMS platforms support IPv6 interface counters and neighbor tables natively once you add an IPv6 management address to your devices.
If you’re doing multi-site routing, OSPFv3 pairs naturally with the MPLS L3VPN framework covered here — IOS-XE supports IPv6 VPN (6VPE) over an MPLS core using the same VRF model as IPv4. And for inter-site connectivity over the public internet, DMVPN supports IPv6 transport and IPv6 passenger traffic with minimal additional config once your IPv6 underlay is solid.
Start with a lab segment, get comfortable with show ipv6 neighbors and show ospfv3 neighbor, and you’ll find IPv6 operations feel natural within a week of daily exposure.