Back to Blog
Tutorial9 min

MPLS L3VPN Lab: PE/CE, VPNv4 Route Reflectors & VRFs

Build a multi-vendor MPLS L3VPN — LDP core, a VPNv4 route reflector, VRFs with route-targets, and PE-CE routing — then verify customer isolation.

D
David Kim
DevOps Engineer

MPLS L3VPN is the protocol stack that carries enterprise WANs and provider VPN services — and it's notoriously hard to lab, because every piece (IGP, LDP, MP-BGP VPNv4, VRFs, route-targets, PE-CE routing) has to line up before a single customer ping works. This lab builds a multi-vendor L3VPN with a Cisco IOL (BYOI) PE, a Juniper cRPD (BYOI) PE, and a route reflector in the core, so you can see exactly where the chain breaks.

Bottom line: A working MPLS L3VPN lab means an OSPF+LDP core, a VPNv4 route reflector, VRFs with matching route-targets on two vendors, and PE-CE routing — a lot to wire by hand. As of 2026, NetPilot deploys this exact topology with real CLIs in ~2 minutes — grab the prompt at the bottom.

Lab topology

A three-router core (OSPF + LDP) with a route reflector in the middle. Customer A has two sites, one behind each PE, in VRF CUSTA.

   [CE1]---[PE1 Cisco]======[RR/P Cisco]======[PE2 Juniper]---[CE2]
  10.1.1/24   1.1.1.1          3.3.3.3            2.2.2.2     10.2.2/24
   VRF CUSTA   RD 65000:100    VPNv4 RR           RD 65000:200  VRF CUSTA
              RT 65000:100     (reflects VPNv4)   RT 65000:100
            <------------- OSPF area 0 + LDP ------------->
  • Core: OSPF area 0 for loopback reachability, LDP for label distribution.
  • Overlay: MP-iBGP VPNv4 from each PE to the route reflector.
  • VPN: VRF CUSTA on both PEs; the RD differs per PE (uniqueness), the RT is shared (65000:100) — that's what stitches the two sites together.

PE1 — Cisco IOL

ip vrf CUSTA
 rd 65000:100
 route-target export 65000:100
 route-target import 65000:100
!
interface Loopback0
 ip address 1.1.1.1 255.255.255.255
 ip ospf 1 area 0
!
interface Ethernet0/0
 description core to RR
 ip address 10.0.13.1 255.255.255.0
 ip ospf 1 area 0
 mpls ip
!
interface Ethernet0/1
 description to CE1
 ip vrf forwarding CUSTA
 ip address 10.1.0.1 255.255.255.0
!
router ospf 1
 router-id 1.1.1.1
mpls ldp router-id Loopback0 force
!
router bgp 65000
 neighbor 3.3.3.3 remote-as 65000
 neighbor 3.3.3.3 update-source Loopback0
 address-family vpnv4
  neighbor 3.3.3.3 activate
  neighbor 3.3.3.3 send-community extended
 address-family ipv4 vrf CUSTA
  redistribute connected
  redistribute static
!
ip route vrf CUSTA 10.1.1.0 255.255.255.0 10.1.0.2
  • mpls ip on the core interface turns on LDP labeling — miss it and BGP next-hops resolve but packets have no transport label.
  • send-community extended is mandatory: VPNv4 routes carry their route-targets as extended communities. Forget it and the RR/PE silently drops the prefixes.

RR / P — Cisco IOL (route reflector)

interface Loopback0
 ip address 3.3.3.3 255.255.255.255
 ip ospf 1 area 0
!
interface Ethernet0/0
 ip address 10.0.13.3 255.255.255.0
 ip ospf 1 area 0
 mpls ip
interface Ethernet0/1
 ip address 10.0.23.3 255.255.255.0
 ip ospf 1 area 0
 mpls ip
!
router ospf 1
 router-id 3.3.3.3
mpls ldp router-id Loopback0 force
!
router bgp 65000
 no bgp default route-target filter
 neighbor 1.1.1.1 remote-as 65000
 neighbor 1.1.1.1 update-source Loopback0
 neighbor 2.2.2.2 remote-as 65000
 neighbor 2.2.2.2 update-source Loopback0
 address-family vpnv4
  neighbor 1.1.1.1 activate
  neighbor 1.1.1.1 route-reflector-client
  neighbor 1.1.1.1 send-community extended
  neighbor 2.2.2.2 activate
  neighbor 2.2.2.2 route-reflector-client
  neighbor 2.2.2.2 send-community extended
  • no bgp default route-target filter is the line everyone forgets on a pure route reflector — without it the RR drops VPNv4 routes whose RTs it doesn't locally import (it has no VRFs), and the VPN never forms.

PE2 — Juniper cRPD

set interfaces lo0 unit 0 family inet address 2.2.2.2/32
set interfaces ge-0/0/0 unit 0 family inet address 10.0.23.2/24
set interfaces ge-0/0/1 unit 0 family inet address 10.2.0.1/24
set routing-options router-id 2.2.2.2
set routing-options autonomous-system 65000
 
set protocols mpls interface ge-0/0/0.0
set protocols ldp interface ge-0/0/0.0
set protocols ldp interface lo0.0
set protocols ospf area 0.0.0.0 interface lo0.0 passive
set protocols ospf area 0.0.0.0 interface ge-0/0/0.0
 
set protocols bgp group vpn type internal
set protocols bgp group vpn local-address 2.2.2.2
set protocols bgp group vpn family inet-vpn unicast
set protocols bgp group vpn neighbor 3.3.3.3
 
set routing-instances CUSTA instance-type vrf
set routing-instances CUSTA interface ge-0/0/1.0
set routing-instances CUSTA route-distinguisher 65000:200
set routing-instances CUSTA vrf-target target:65000:100
set routing-instances CUSTA routing-options static route 10.2.2.0/24 next-hop 10.2.0.2
  • routing-options autonomous-system 65000 is mandatory — Junos derives the local AS for the internal VPNv4 session from it, and the core-facing ge-0/0/0 carries OSPF + LDP for the underlay (the VRF's ge-0/0/1 stays inside the routing-instance).
  • Junos rolls VRF, RD, and RT into one routing-instances stanza; vrf-target target:65000:100 covers both import and export.
  • family inet-vpn unicast is Junos' equivalent of Cisco's address-family vpnv4 — the multi-vendor naming is exactly the kind of thing the agent translates for you.
  • cRPD is containerized, so the ge-0/0/0 / ge-0/0/1 names shown here map to the container's underlying Linux interfaces (cRPD images may also expose eth-style names) — NetPilot wires that mapping for you, so you write standard Junos config and it lands on the right container link.

PE-CE here is static for clarity; in production it's usually eBGP or OSPF between PE and CE — ask the agent to swap it in.

CE1 and CE2 — Cisco IOL

The CEs are plain customer routers — no MPLS, no VRF awareness. Each has a link to its PE and a Loopback0 standing in for the customer LAN (the host the far side pings), plus a default route toward the PE. The PE static routes above point at these CE LANs, so the topology only closes once the CEs exist.

! CE1 (behind PE1) — customer site 1
interface Ethernet0/0
 description to PE1
 ip address 10.1.0.2 255.255.255.0
!
interface Loopback0
 description customer LAN 10.1.1.0/24
 ip address 10.1.1.1 255.255.255.0
!
ip route 0.0.0.0 0.0.0.0 10.1.0.1
! CE2 (behind PE2) — customer site 2
interface Ethernet0/0
 description to PE2
 ip address 10.2.0.2 255.255.255.0
!
interface Loopback0
 description customer LAN 10.2.2.0/24
 ip address 10.2.2.1 255.255.255.0
!
ip route 0.0.0.0 0.0.0.0 10.2.0.1

The Loopback0 /24 mask makes each loopback represent the whole customer LAN, so PE1's 10.1.1.0/24 static and PE2's 10.2.2.0/24 static resolve to a real next hop (10.1.0.2 / 10.2.0.2) and 10.2.2.1 is reachable end to end across the L3VPN.

Verification

Lead with the agent — one prompt walks the whole control plane and translates each vendor's output:

"Verify the MPLS L3VPN: OSPF + LDP in the core, VPNv4 routes on both PEs via the route reflector, and end-to-end reachability between CUSTA site 1 and site 2."

NetPilot checks each layer across all four routers in parallel and flags the first place the chain breaks. To verify by hand:

! PE1 (Cisco)
show mpls ldp neighbor
show bgp vpnv4 unicast all summary
show ip route vrf CUSTA
ping vrf CUSTA 10.2.2.1 source 10.1.0.1
# PE2 (Juniper)
show ldp neighbor
show route table bgp.l3vpn.0
show route table CUSTA.inet.0

Expected: LDP neighbors up across the core, the remote site's prefix in each PE's VRF table (learned via VPNv4), and a successful customer ping across the provider core — with the traffic carrying two labels (transport + VPN).

Common MPLS L3VPN gotchas

  1. Route-target mismatch. Import/export RTs must line up between the two PEs. A typo here is the classic "BGP is up, VPNv4 routes exist, but they're not in the VRF."
  2. Missing send-community extended. No extended communities means no route-targets travel — the VPN silently fails.
  3. RR drops VPNv4 routes. Without no bgp default route-target filter, a route reflector with no local VRFs filters everything. Set it on every RR.
  4. LDP not running on a core link. BGP next-hops resolve via the IGP, but with no label there's no LSP — packets are dropped at the first P hop. Check show mpls ldp neighbor end to end.
  5. RD reused incorrectly. RDs only need to be unique to keep overlapping customer prefixes distinct; they do not control VPN membership — that's the RT's job. Mixing the two up is the most common conceptual error.

Build this lab with AI

Skip the four-router wiring and describe the service:

"Build a multi-vendor MPLS L3VPN. Cisco IOL PE1 and Juniper cRPD PE2 with a Cisco route reflector in the core. Run OSPF + LDP in the core, MP-BGP VPNv4 to the RR, and a VRF 'CUSTA' (RT 65000:100) with a CE site behind each PE. Verify customer site-to-site reachability and isolation from a second VRF."

NetPilot generates the core, the VPNv4 route reflector, the per-vendor VRFs, and PE-CE routing, deploys to cloud ContainerLab, and confirms the customer reachability — then you SSH in and trace the label stack yourself.


Copy-paste ready: Grab the MPLS L3VPN prompt from our example library — RD/RT variants and a second customer VRF included.

Want to lab MPLS without the setup? Run it in an online network lab, or let the AI network emulator generate the PE/CE configs from a prompt. Related: EVPN-VXLAN Data Center Fabric and FRRouting in the Cloud. Try NetPilot — describe any provider topology and get a working multi-vendor lab in ~2 minutes.

Try NetPilot Free

Build enterprise-grade network labs in seconds with AI assistance

Get Started Free