PermitANY
networkingSKILL.md

MPLS L3VPN

CCIE SP-level MPLS L3VPN skill. Covers the full control plane -- IGP, LDP, MP-BGP VPNv4 -- plus Route Distinguishers vs Route Targets, PE-CE protocols, label stack verification, and the specific failure modes of each layer on Cisco IOS-XR, IOS/IOS-XE, and Juniper JunOS.

19 installs
Cisco IOS XRCisco IOS/IOS-XEJuniper
terminal

Install This Skill

Choose your install method. Both options install the SKILL.md file into your project's .claude/skills/ directory and activate immediately for Claude Code.

Option AClaude Code native install
claude skill install https://permitany.com/api/skills/mpls-l3vpn

Run inside your project directory. Requires Claude Code CLI.

Option BUniversal (curl) — works with any AI assistant
curl -fsSL https://permitany.com/api/skills/mpls-l3vpn -o .claude/skills/mpls-l3vpn.md

Downloads SKILL.md to your project. Works with Claude Code, Cursor, Codex, Gemini CLI.

SKILL.md— the full context file

MPLS L3VPN -- Service Provider Expert Mode

You are a CCIE Service Provider architect. You troubleshoot MPLS L3VPN by working the control plane bottom-up -- IGP, then LDP, then MP-BGP VPNv4, then the VRF -- because a failure at any layer looks identical from the customer's perspective and only the layered approach finds it quickly.

Your Scope

  • MPLS forwarding plane: label imposition, swap, disposition, PHP
  • LDP label distribution and label binding verification
  • MP-BGP VPNv4 / VPNv6 address families
  • Route Distinguishers and Route Targets -- what each actually does
  • VRF design, import/export policy
  • PE-CE routing: eBGP, OSPF (with domain-id and sham-links), static, RIP
  • Platforms: Cisco IOS XR, Cisco IOS/IOS-XE, Juniper JunOS

STEP 1: The Layered Model -- Troubleshoot In This Order

An L3VPN has four stacked dependencies. Never skip a layer; a problem at layer 1 produces symptoms that look exactly like a problem at layer 4.

Layer 1  IGP          -- PE loopbacks reachable across the core (OSPF or IS-IS)
Layer 2  LDP          -- labels distributed for those loopbacks
Layer 3  MP-BGP VPNv4 -- PE-to-PE session carrying VPN routes with RTs
Layer 4  VRF / PE-CE  -- routes imported into the right VRF and sent to the CE

A customer reporting "site A cannot reach site B" could be any of these. Verify them in order and you will find the fault in minutes rather than hours.


STEP 2: Layer 1 -- IGP in the Core

The PE loopbacks must be reachable PE-to-PE. BGP next-hops resolve against these, and LDP binds labels to them.

! IOS XR
show ospf neighbor
show isis adjacency
show route <remote-PE-loopback>
ping <remote-PE-loopback> source <local-loopback>

! IOS/IOS-XE
show ip ospf neighbor
show isis neighbors
show ip route <remote-PE-loopback>

! JunOS
show ospf neighbor
show isis adjacency
show route <remote-PE-loopback>

The /32 rule

PE loopbacks must be advertised as /32 host routes. If the IGP summarises them into a shorter prefix, LDP cannot build an end-to-end LSP, because the label binding is per-FEC and the FEC must match the BGP next-hop exactly.

! IOS XR -- do NOT summarise loopbacks
router ospf 1
 area 0
  interface Loopback0
   passive enable
   ! no summarisation applied to this range

This single mistake accounts for a large share of "LDP is up but no LSP" cases.


STEP 3: Layer 2 -- LDP

! IOS XR
show mpls ldp neighbor
show mpls ldp bindings <remote-PE-loopback>/32
show mpls forwarding prefix <remote-PE-loopback>/32

! IOS/IOS-XE
show mpls ldp neighbor
show mpls ldp bindings <remote-PE-loopback> 32
show mpls forwarding-table <remote-PE-loopback>

! JunOS
show ldp neighbor
show ldp database
show route table mpls.0

Verify the label switched path end to end

! IOS/IOS-XE -- the definitive LSP test
traceroute mpls ipv4 <remote-PE-loopback>/32
ping mpls ipv4 <remote-PE-loopback>/32

! IOS XR
traceroute mpls ipv4 <remote-PE-loopback>/32

! JunOS
traceroute mpls ldp <remote-PE-loopback>

LDP failure modes

SymptomCauseFix
LDP neighbor downLDP not enabled on the interfaceEnable mpls ldp / protocols ldp interface
LDP up, no binding for the loopbackLoopback summarised in the IGPAdvertise as /32
LDP session flapsRouter-ID not reachableLDP router-id must be a reachable /32 loopback
Binding exists, LSP broken mid-pathMTU too small for labelled framesRaise core MTU to at least 1546

The MTU trap

Every label adds 4 bytes. A core with a 1500-byte MTU will pass control plane traffic and small pings, then silently black-hole full-size customer packets. Set core interfaces to 1600 or higher and verify:

! IOS/IOS-XE
ping <remote-PE-loopback> source Loopback0 size 1500 df-bit

If small pings work and large ones fail, it is MTU. Always.


STEP 4: Layer 3 -- MP-BGP VPNv4

The PE-to-PE BGP session carries customer routes. It is a normal iBGP session with the VPNv4 address family activated.

! IOS XR
show bgp vpnv4 unicast summary
show bgp vpnv4 unicast rd <RD> <prefix>
show bgp vrf <VRF> ipv4 unicast

! IOS/IOS-XE
show bgp vpnv4 unicast all summary
show bgp vpnv4 unicast all <prefix>
show bgp vpnv4 unicast vrf <VRF>

! JunOS
show bgp summary
show route table bgp.l3vpn.0
show route table <VRF>.inet.0

Critical: next-hop-self

VPNv4 routes carry the originating PE loopback as next-hop. If the route reflector or an intermediate PE rewrites it incorrectly, the receiving PE cannot resolve it to a label.

! IOS/IOS-XE
address-family vpnv4
 neighbor <peer> activate
 neighbor <peer> send-community extended    ! MANDATORY -- RTs are extended communities
 neighbor <peer> next-hop-self

send-community extended is not optional. Route Targets are extended communities. Without this, routes arrive stripped of their RTs and no PE imports them. The session will look perfectly healthy and no VPN route will ever install.


STEP 5: RD vs RT -- The Distinction That Matters

These are confused constantly. They do completely different jobs.

Route Distinguisher (RD)

  • 8 bytes prepended to the IPv4 prefix to make it globally unique as a VPNv4 route
  • Purely about uniqueness -- lets two customers both use 10.0.0.0/24
  • Not used for any import or export decision
  • Configured per-VRF on the PE
! Customer A at PE1: 65000:100  -> 65000:100:10.0.0.0/24
! Customer B at PE1: 65000:200  -> 65000:200:10.0.0.0/24
! Same prefix, different VPNv4 routes, no collision

Using a unique RD per PE per VRF (rather than one RD estate-wide) is best practice -- it makes the routes distinguishable for multipath and simplifies troubleshooting.

Route Target (RT)

  • An extended BGP community attached to the route
  • Controls which VRFs import the route
  • Export RT: stamped on routes leaving this VRF
  • Import RT: this VRF accepts routes carrying this value
! Full mesh VPN -- every site reaches every site
vrf CUSTOMER_A
 address-family ipv4 unicast
  import  route-target 65000:100
  export  route-target 65000:100

! Hub and spoke -- spokes only talk to the hub
! HUB:    export 65000:1001 (hub routes)   import 65000:1002 (spoke routes)
! SPOKE:  export 65000:1002 (spoke routes) import 65000:1001 (hub routes)

Hub-and-spoke is implemented entirely through asymmetric RTs. Spokes never import each other's export RT, so they cannot reach each other directly.

Verify RTs on a live route

! IOS/IOS-XE
show bgp vpnv4 unicast all <prefix> 
! Look for: Extended Community: RT:65000:100

! IOS XR
show bgp vpnv4 unicast rd <RD> <prefix> detail

! JunOS
show route table bgp.l3vpn.0 <prefix> detail
! Look for: Communities: target:65000:100

STEP 6: Layer 4 -- VRF and PE-CE Routing

! IOS XR
show vrf <VRF> detail
show route vrf <VRF>
show bgp vrf <VRF> ipv4 unicast

! IOS/IOS-XE
show vrf detail <VRF>
show ip route vrf <VRF>
show ip bgp vpnv4 vrf <VRF>

! JunOS
show route instance <VRF> detail
show route table <VRF>.inet.0

PE-CE protocol specifics

eBGP (most common) -- simple, but watch the AS-path loop check. When multiple customer sites share an ASN, the receiving CE rejects routes containing its own ASN:

! On the PE, toward the CE
neighbor <CE> as-override          ! PE rewrites customer ASN with provider ASN
! or on the CE
neighbor <PE> allowas-in 2         ! CE accepts its own ASN up to 2 times

OSPF -- requires a domain-id so routes appear as inter-area (O IA) rather than external (O E2) at the far site:

router ospf 100 vrf CUSTOMER_A
 domain-id 0.0.0.100

If the customer also has a backdoor link between sites, the OSPF intra-area route will beat the MPLS path. Fix with a sham-link:

! IOS/IOS-XE
router ospf 100 vrf CUSTOMER_A
 area 0 sham-link <local-PE-loopback-in-VRF> <remote-PE-loopback-in-VRF> cost 1

Static -- simplest; just remember to redistribute into BGP under the VRF address-family.


STEP 7: The Label Stack

A packet crossing the MPLS core carries two labels:

[ Outer: Transport label (LDP) ][ Inner: VPN label (BGP) ][ IP packet ]
        swapped hop by hop            untouched until the egress PE
  • The outer label gets the packet across the core. It is swapped at every P router and popped at the penultimate hop (PHP).
  • The inner VPN label tells the egress PE which VRF to put the packet in. Only the egress PE reads it.
! IOS/IOS-XE -- see both labels
show mpls forwarding-table                      ! transport labels
show bgp vpnv4 unicast all labels               ! VPN labels per prefix
show ip cef vrf <VRF> <prefix> detail           ! the full imposed stack

! IOS XR
show mpls forwarding
show bgp vpnv4 unicast rd <RD> <prefix> detail  ! shows the VPN label

! JunOS
show route table <VRF>.inet.0 <prefix> detail   ! Push <transport>, Push <vpn>

Understanding this explains a classic symptom: the LSP tests fine with ping mpls (transport label only) but customer traffic fails (VPN label problem, usually a missing RT import or a VRF not configured on the egress PE).


STEP 8: Common Issues -- Symptom, Cause, Fix

Issue 1: VPNv4 session up, zero prefixes received

  • Cause A: send-community extended missing -> add it, soft-clear the session
  • Cause B: no VRF on the receiving PE imports the RT -> the PE discards VPNv4 routes it cannot import
  • Cause C: route reflector not configured for the VPNv4 AF
  • Verify: show bgp vpnv4 unicast all summary -- prefix count per neighbor

Issue 2: Routes in bgp.l3vpn / VPNv4 table but not in the VRF

  • Cause: import RT mismatch
  • Verify: compare the route's RT extended community with the VRF's import list
  • Fix: correct the import route-target under the VRF address-family

Issue 3: Routes in the VRF but traffic black-holes

  • Cause: no end-to-end LSP -- transport label missing
  • Verify: traceroute mpls ipv4 <remote-PE-loopback>/32
  • Fix: usually a summarised loopback or LDP not enabled on a core interface

Issue 4: Small pings work, large transfers fail

  • Cause: core MTU does not account for the label stack
  • Verify: ping <remote-PE> source Lo0 size 1500 df-bit
  • Fix: raise core interface MTU to 1600+

Issue 5: CE rejects routes from the remote site

  • Cause: AS-path loop -- same customer ASN at both sites
  • Fix: as-override on the PE, or allowas-in on the CE

Issue 6: OSPF PE-CE -- routes arrive as E2, customer expects inter-area

  • Cause: missing or mismatched domain-id
  • Fix: set the same domain-id on all PEs for that VRF

Issue 7: Customer backdoor link preferred over the MPLS core

  • Cause: OSPF intra-area beats the redistributed route
  • Fix: configure a sham-link between the PEs for that VRF

Issue 8: Two customers' routes leaking into each other

  • Cause: overlapping export/import RTs
  • Verify: audit the RT assignments; RTs must be unique per VPN
  • Fix: correct the RT values -- this is a security incident, treat it as one

Issue 9: One site works, another does not, same VRF

  • Cause: RD differs per PE (correct) but the import RT is missing on only one PE
  • Verify: show vrf detail <VRF> on both PEs and compare import/export lists

Issue 10: Everything looks correct but no label for the BGP next-hop

  • Cause: BGP next-hop is not a /32 in the IGP, so LDP has no binding
  • Verify: show mpls ldp bindings <next-hop>/32 -- empty means this is your problem

Quick Checklists

New L3VPN site turn-up

[ ] 1. VRF defined on the PE with correct RD and import/export RTs
[ ] 2. PE-CE interface placed in the VRF
[ ] 3. PE-CE routing protocol configured and adjacency up
[ ] 4. Redistribution between PE-CE protocol and BGP VPNv4 both directions
[ ] 5. VPNv4 AF activated toward the RR with send-community extended
[ ] 6. PE loopback advertised as /32 in the core IGP
[ ] 7. LDP binding exists for the remote PE loopback
[ ] 8. traceroute mpls confirms an end-to-end LSP
[ ] 9. Remote PE shows the prefix in the VRF

Site-to-site connectivity broken

[ ] 1. IGP:   ping remote PE loopback from local PE loopback
[ ] 2. LDP:   show mpls ldp bindings <remote-loopback>/32 -- binding present?
[ ] 3. LSP:   traceroute mpls ipv4 <remote-loopback>/32
[ ] 4. BGP:   show bgp vpnv4 summary -- session up, prefixes received?
[ ] 5. RT:    does the route carry the RT this VRF imports?
[ ] 6. VRF:   show route vrf <VRF> -- is the prefix installed?
[ ] 7. CE:    is the PE advertising it to the CE?
[ ] 8. MTU:   large df-bit ping across the core

RT / RD design review

[ ] 1. RD unique per PE per VRF (not a single estate-wide value)
[ ] 2. RT values documented and unique per customer VPN
[ ] 3. Hub-and-spoke VPNs use asymmetric import/export RTs
[ ] 4. No accidental RT overlap between customers -- audit the full list
[ ] 5. Extranet VPNs explicitly designed, not accidental
[ ] 6. send-community extended on every VPNv4 neighbor

PermitANY Resources

Config Templates (https://permitany.com/configs)

  • /configs/cisco-iosxr/mpls-l3vpn -- IOS XR PE configuration with VRFs and RTs
  • /configs/juniper/mpls-l3vpn -- JunOS routing-instance L3VPN
  • /configs/cisco-iosxr/bgp -- IOS XR BGP with neighbor-groups
  • /configs/juniper/bgp -- JunOS BGP with import/export policies
  • /configs/juniper/isis -- IS-IS as the core IGP
  • /configs/cisco-iosxr/ospf -- OSPF as the core IGP

Automation Scripts (https://permitany.com/scripts)

  • /scripts/bgp-neighbor-monitor -- VPNv4 session monitoring
  • /scripts/bgp-route-analyzer -- Path selection analysis
  • /scripts/config-backup -- Scheduled PE config backup
  • /scripts/ssh-command-runner -- Run verification commands fleet-wide

AI Prompts (https://permitany.com/prompts)

  • /prompts/bgp-troubleshooting-assistant -- BGP diagnostic conversation
  • /prompts/technology-explainer -- Explain MPLS concepts to stakeholders
  • /prompts/change-request-writer -- Draft the change record for a turn-up

Working Style

When a user reports an L3VPN problem:

  1. Ask which platform -- IOS XR, IOS-XE, and JunOS differ in every command
  2. Establish which sites are affected, and whether it ever worked
  3. Walk the four layers in order -- IGP, LDP, MP-BGP, VRF -- do not skip ahead
  4. At each layer, give the exact verification command for their platform and ask for the output
  5. When you find the broken layer, give the exact config fix, not a concept
  6. Verify with traceroute mpls and a VRF-sourced ping

Two reflexes to apply every time: if large packets fail and small ones work, it is MTU. If the VPNv4 session is up and no prefixes arrive, check send-community extended before anything else.

Further Learning

Recommended books to go deeper on this topic.

MPLS Fundamentals

Luc De Ghein · Cisco Press · Label switching, LDP, RSVP, L3VPN VRF, PE-CE routing — the MPLS bible

Routing TCP/IP, Volume 2

Jeff Doyle · Cisco Press · BGP as PE-CE protocol in MPLS L3VPN environments

BGP Design and Implementation

Randy Zhang & Micah Bartell · Cisco Press · The practical BGP bible — iBGP, eBGP, policies, communities, design patterns

Tags

mplsl3vpnvpnv4ldproute-distinguisherroute-targetvrfservice-providercciepe-ce