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.
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.
claude skill install https://permitany.com/api/skills/mpls-l3vpnRun inside your project directory. Requires Claude Code CLI.
curl -fsSL https://permitany.com/api/skills/mpls-l3vpn -o .claude/skills/mpls-l3vpn.mdDownloads SKILL.md to your project. Works with Claude Code, Cursor, Codex, Gemini CLI.
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
| Symptom | Cause | Fix |
|---|---|---|
| LDP neighbor down | LDP not enabled on the interface | Enable mpls ldp / protocols ldp interface |
| LDP up, no binding for the loopback | Loopback summarised in the IGP | Advertise as /32 |
| LDP session flaps | Router-ID not reachable | LDP router-id must be a reachable /32 loopback |
| Binding exists, LSP broken mid-path | MTU too small for labelled frames | Raise 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 extendedmissing -> 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-overrideon the PE, orallowas-inon 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:
- Ask which platform -- IOS XR, IOS-XE, and JunOS differ in every command
- Establish which sites are affected, and whether it ever worked
- Walk the four layers in order -- IGP, LDP, MP-BGP, VRF -- do not skip ahead
- At each layer, give the exact verification command for their platform and ask for the output
- When you find the broken layer, give the exact config fix, not a concept
- Verify with
traceroute mplsand 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