MPLS: IPv6 over MPLS (6PE)
After a long time without writing, I decided to come back and continue posting some of the topics that were waiting on my backlog. This is the first one of them.
Service providers that run an IPv4/MPLS core face a practical problem when customers start asking for IPv6 connectivity: how to transport IPv6 traffic without deploying IPv6 (or MPLS for IPv6) on every router of the backbone. One of the cleanest solutions for this scenario is 6PE (IPv6 Provider Edge), defined in RFC 4798.
With 6PE, only the PE routers are dual-stack. They exchange the customer IPv6 prefixes between them using MP-iBGP with the labeled-unicast capability (the send-label option in IOS), while the P routers in the core keep doing what they already do: label switching based on LDP. The core never learns a single IPv6 route.
Two details are the heart of 6PE:
- IPv4-mapped next hop: the iBGP sessions between PEs run over IPv4, so the next hop of an IPv6 route is encoded as an IPv4-mapped IPv6 address, for example ::FFFF:3.3.3.3. The ingress PE resolves it to the IPv4 loopback of the egress PE and to the LDP label that reaches that loopback.
- Two-label stack: the outer label is the LDP transport label towards the egress PE. The inner label is the BGP label advertised with the prefix via send-label. This inner label is necessary because of penultimate hop popping: the last P router removes the transport label, and without the BGP label the egress PE would receive a raw IPv6 packet arriving from a core interface that has no IPv6 enabled. The BGP label tells the egress PE that the payload is IPv6 and how to forward it.
In a real network, a full-mesh of iBGP sessions between all the PEs does not scale, so in this lab the prefix distribution is centralized on a Route Reflector (RR) running on the P router, the same design used on the MPLS L3VPN posts.
Demonstrating: 6PE

The scenario uses five routers and the following design:
- IPv4 core: PE1 (1.1.1.1), P (2.2.2.2) and PE2 (3.3.3.3) run OSPF area 0 and LDP. The links are 10.1.2.0/24 (PE1-P) and 10.2.3.0/24 (P-PE2). There is no IPv6 in the core.
- Route Reflector: the P router is the RR for the IPv6 labeled-unicast routes. The PEs establish the iBGP session only with 2.2.2.2.
- PE-CE routing: native IPv6 links running eBGP. The provider runs AS 3549 and both customer sites belong to the same AS 8048: CE1 connects to PE1 over 2001:db8:12::/64 and CE2 connects to PE2 over 2001:db8:23::/64. The loopbacks 2001:db8:1::1/128 (CE1) and 2001:db8:2::2/128 (CE2) are the prefixes exchanged through the core.
P (core router and Route Reflector)
The P router has no IPv6 address on any interface. Its only special role is reflecting the labeled IPv6 routes between the PEs, so the send-label option must also be present on the RR sessions.
hostname P
!
interface Loopback0
ip address 2.2.2.2 255.255.255.255
!
interface Ethernet0/0
description Link to PE1
ip address 10.1.2.2 255.255.255.0
mpls ip
!
interface Ethernet0/1
description Link to PE2
ip address 10.2.3.2 255.255.255.0
mpls ip
!
mpls ldp router-id Loopback0
!
router ospf 1
network 2.2.2.2 0.0.0.0 area 0
network 10.1.2.0 0.0.0.255 area 0
network 10.2.3.0 0.0.0.255 area 0
!
router bgp 3549
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 1.1.1.1 remote-as 3549
neighbor 1.1.1.1 update-source Loopback0
neighbor 3.3.3.3 remote-as 3549
neighbor 3.3.3.3 update-source Loopback0
!
address-family ipv6
neighbor 1.1.1.1 activate
neighbor 1.1.1.1 route-reflector-client
neighbor 1.1.1.1 send-label
neighbor 3.3.3.3 activate
neighbor 3.3.3.3 route-reflector-client
neighbor 3.3.3.3 send-label
exit-address-family
!
PE1
PE1 is dual-stack: IPv4 towards the core, IPv6 towards the customer. The 6PE behavior is enabled by the send-label option under the IPv6 address-family of the iBGP session. The next-hop-self is also important here: the routes learned from CE1 via eBGP carry the CE link address as next hop, which is not reachable from the core, so the PE must rewrite the next hop with its own loopback before advertising to the RR.
hostname PE1
!
ipv6 unicast-routing
!
interface Loopback0
ip address 1.1.1.1 255.255.255.255
!
interface Ethernet0/0
description Link to P
ip address 10.1.2.1 255.255.255.0
mpls ip
!
interface Ethernet0/1
description Link to CE1 (Native IPv6)
ipv6 address 2001:db8:12::1/64
!
mpls ldp router-id Loopback0
!
router ospf 1
network 1.1.1.1 0.0.0.0 area 0
network 10.1.2.0 0.0.0.255 area 0
!
router bgp 3549
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 2.2.2.2 remote-as 3549
neighbor 2.2.2.2 update-source Loopback0
neighbor 2001:db8:12::2 remote-as 8048
!
address-family ipv6
neighbor 2.2.2.2 activate
neighbor 2.2.2.2 send-label
neighbor 2.2.2.2 next-hop-self
neighbor 2001:db8:12::2 activate
exit-address-family
!
PE2
PE2 mirrors PE1, with its own addressing and the eBGP session to CE2.
hostname PE2
!
ipv6 unicast-routing
!
interface Loopback0
ip address 3.3.3.3 255.255.255.255
!
interface Ethernet0/0
description Link to P
ip address 10.2.3.3 255.255.255.0
mpls ip
!
interface Ethernet0/1
description Link to CE2 (Native IPv6)
ipv6 address 2001:db8:23::1/64
!
mpls ldp router-id Loopback0
!
router ospf 1
network 3.3.3.3 0.0.0.0 area 0
network 10.2.3.0 0.0.0.255 area 0
!
router bgp 3549
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 2.2.2.2 remote-as 3549
neighbor 2.2.2.2 update-source Loopback0
neighbor 2001:db8:23::2 remote-as 8048
!
address-family ipv6
neighbor 2.2.2.2 activate
neighbor 2.2.2.2 send-label
neighbor 2.2.2.2 next-hop-self
neighbor 2001:db8:23::2 activate
exit-address-family
!
CE1 and CE2
The customer routers only speak native IPv6 and have no idea that the provider backbone runs MPLS. Each one advertises its loopback via eBGP. Two details are easy to forget here. First, since both sites use the same AS 8048, each CE would silently reject the routes of the other site because of the BGP AS-path loop prevention, so the allowas-in option is required (the alternative would be as-override on the PEs, but on IOS that option is only available for VRF sessions, which is not the case in 6PE). Second, these routers have no IPv4 addresses at all, so BGP cannot elect a router-id by itself and the session never comes up; it must be configured manually.
hostname CE1
!
ipv6 unicast-routing
!
interface Loopback0
ipv6 address 2001:db8:1::1/128
!
interface Ethernet0/1
description Link to PE1
ipv6 address 2001:db8:12::2/64
!
router bgp 8048
bgp router-id 11.11.11.11
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 2001:db8:12::1 remote-as 3549
!
address-family ipv6
neighbor 2001:db8:12::1 activate
neighbor 2001:db8:12::1 allowas-in 1
network 2001:db8:1::1/128
exit-address-family
!
hostname CE2
!
ipv6 unicast-routing
!
interface Loopback0
ipv6 address 2001:db8:2::2/128
!
interface Ethernet0/1
description Link to PE2
ipv6 address 2001:db8:23::2/64
!
router bgp 8048
bgp router-id 22.22.22.22
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 2001:db8:23::1 remote-as 3549
!
address-family ipv6
neighbor 2001:db8:23::1 activate
neighbor 2001:db8:23::1 allowas-in 1
network 2001:db8:2::2/128
exit-address-family
!
Once the devices are configured, it is possible to verify the labeled IPv6 routes on the Route Reflector, the label stack programmed in CEF on the ingress PE, and the end-to-end connectivity between the two IPv6 islands.
Verifying the control plane on the Route Reflector
One advantage of the RR design is that the control plane verification is centralized: the P router sees every 6PE route of the network.
P#show bgp ipv6 unicast 2001:DB8:2::2/128
BGP routing table entry for 2001:DB8:2::2/128, version 12
Paths: (1 available, best #1, table default)
Advertised to update-groups:
1
Refresh Epoch 1
8048, (Received from a RR-client)
::FFFF:3.3.3.3 (metric 21) from 3.3.3.3 (3.3.3.3)
Origin IGP, metric 0, localpref 100, valid, internal, best
mpls labels in/out nolabel/24
The RR received the prefix of CE2 from PE2 with the BGP label 24 and the next hop ::FFFF:3.3.3.3, the IPv4-mapped representation of the PE2 loopback. As a normal Route Reflector, it reflects this route to PE1 without modifying the next hop or the label.
Checking the CEF entry on PE1
On PE1, the reflected route must be installed in CEF with the complete two-label stack.
PE1#show ipv6 cef 2001:DB8:2::2/128
2001:DB8:2::2/128
nexthop 10.1.2.2 Ethernet0/0 label 16 24
- Label 16 (outer, transport): learned via LDP, it takes the packet across the core to the loopback of PE2 (3.3.3.3).
- Label 24 (inner, BGP): advertised by PE2 through the send-label option, it identifies the IPv6 destination on egress.
Verifying connectivity between the two IPv6 islands
CE1#ping 2001:DB8:2::2 source Loopback0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:DB8:2::2, timeout is 2 seconds:
Packet sent with a source address of 2001:DB8:1::1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/5 ms
Analyzing the label stack with traceroute
A traceroute from CE1 shows the two-label stack while the packet crosses the IPv4 core.
CE1#traceroute 2001:DB8:2::2 source Loopback0
Type escape sequence to abort.
Tracing the route to 2001:DB8:2::2
1 2001:DB8:12::1 2 msec 1 msec 1 msec
2 ::FFFF:10.1.2.2 [MPLS: Labels 16/24 Exp 0] 5 msec 4 msec 4 msec
3 2001:DB8:23::1 [MPLS: Label 24 Exp 0] 4 msec 3 msec 4 msec
4 2001:DB8:2::2 4 msec 3 msec 3 msec
- Hop 1: PE1 answers from its customer-facing interface, the packet is still native IPv6.
- Hop 2: the P router has no IPv6 configuration, but it still answers the traceroute. The TTL expired in the middle of the LSP, so the P router builds the ICMPv6 time-exceeded using the IPv4-mapped address of its interface (::FFFF:10.1.2.2) and forwards it to the end of the LSP, where PE2 routes it back to CE1. Both labels are visible: 16 for transport and 24 for BGP.
- Hop 3: the P router already removed the transport label (penultimate hop popping), so PE2 received the packet carrying only the BGP label 24.
- Hop 4: PE2 removed the BGP label and delivered the native IPv6 packet to CE2.
In summary, 6PE allows a provider to offer IPv6 connectivity reusing the IPv4/MPLS backbone exactly as it is: same IGP, same LDP, and P routers that never touch an IPv6 route. The limitation is that all the customers share the global IPv6 routing table of the provider; there is no isolation and no support for overlapping address spaces. When those requirements appear, the answer is 6VPE, which is the topic of the next post.
References