MPLS L3VPN
MPLS L3VPN
Section titled “MPLS L3VPN”MPLS Layer 3 VPN (L3VPN) provides isolated routed connectivity between customer sites over a shared MPLS infrastructure. Each customer receives a dedicated Virtual Routing and Forwarding (VRF) instance on every Provider Edge (PE) router, keeping customer routes completely separate from the provider backbone and from other customers. Customer prefixes are distributed between PE routers using MP-BGP with the VPNv4 address family, carried across the MPLS core using a two-label stack.
RouterOS v7 implements RFC 4364 MPLS L3VPN. The solution requires LDP (or another label distribution mechanism) running in the core alongside MP-BGP between PE routers. Provider (P) routers in the core require no VPN awareness — they only perform label switching on the outer transport label.
Prerequisites
Section titled “Prerequisites”- RouterOS v7 on all PE and P routers
- IGP (OSPF or IS-IS) providing reachability between PE loopback addresses
- MPLS enabled and LDP running on all core-facing interfaces
- PE loopback addresses advertised into the IGP
- BGP AS number assigned to the provider network
Concepts
Section titled “Concepts”Network roles
Section titled “Network roles”| Role | Function |
|---|---|
| CE (Customer Edge) | Customer router. Connects to the PE via a customer-facing interface. Has no MPLS awareness. |
| PE (Provider Edge) | Provider router at the edge. Maintains per-customer VRFs, runs MP-BGP VPNv4 with other PEs. |
| P (Provider) | Core provider router. Performs label switching only. No VRF state. |
Virtual Routing and Forwarding (VRF)
Section titled “Virtual Routing and Forwarding (VRF)”A VRF is an isolated routing table on a PE router. Each customer site connected to a PE is associated with a VRF. Interfaces assigned to a VRF participate only in that VRF’s routing table. Multiple customers can use overlapping address space because their VRFs are completely independent.
VRFs in RouterOS are configured under /ip vrf. Each VRF has:
- A route distinguisher (RD) that makes VPN routes globally unique when advertised in MP-BGP
- Import and export route targets (RT) that control which VPN routes are installed into which VRFs
Route Distinguisher (RD)
Section titled “Route Distinguisher (RD)”The RD is prepended to a customer prefix to produce a unique VPNv4 prefix (RD:IP/prefix). This prevents address conflicts when multiple customers use overlapping addresses. The RD is locally significant to the originating PE and does not control route distribution.
Format: AS:nn (e.g. 65000:1) or IP:nn (e.g. 10.0.0.1:1). Each PE should use a unique RD per VRF.
Route Targets (RT)
Section titled “Route Targets (RT)”Route targets are BGP extended communities that control which VPN routes are imported into which VRFs:
- export-route-targets: attached to routes when they are advertised into MP-BGP
- import-route-targets: a VRF imports routes whose exported RT matches any value in this list
A simple full-mesh topology uses the same RT for both import and export across all PEs. More complex topologies (hub-and-spoke, extranet) use different RT values.
MP-BGP VPNv4
Section titled “MP-BGP VPNv4”PE routers exchange customer routes using BGP with the VPNv4 address family (AFI 1, SAFI 128). Each VPNv4 route carries the full VPNv4 prefix (RD:IP/prefix), the VPN label (assigned by the egress PE), and the export route target communities. Route reflectors are used in larger deployments to avoid full-mesh BGP peering.
Label stack
Section titled “Label stack”An L3VPN packet carries two MPLS labels:
| Label | Assigned by | Purpose |
|---|---|---|
| Outer (transport) | LDP/RSVP-TE | Routes the packet across the MPLS core to the egress PE |
| Inner (VPN) | Egress PE via MP-BGP | Identifies the destination VRF on the egress PE |
The ingress PE imposes both labels. P routers swap only the outer label. The penultimate P router pops the outer label (PHP — Penultimate Hop Popping), so the egress PE receives the packet with only the VPN label and forwards it into the correct VRF.
Reference topology
Section titled “Reference topology”This guide uses the following topology throughout all examples:
CE-A ─── PE1 ─── P ─── PE2 ─── CE-B (10.0.0.1) (10.0.0.2) └──── RR (10.0.0.10) ────┘ (iBGP route reflector)| Device | Loopback | AS | Role |
|---|---|---|---|
| PE1 | 10.0.0.1/32 | 65000 | Provider Edge |
| PE2 | 10.0.0.2/32 | 65000 | Provider Edge |
| RR | 10.0.0.10/32 | 65000 | BGP Route Reflector |
| P | 10.0.0.254/32 | — | Core label-switching |
| CE-A | 192.168.1.1 | 65001 | Customer A site 1 |
| CE-B | 192.168.2.1 | 65001 | Customer A site 2 |
Customer A uses VRF CUST-A with RD unique per PE and route target 65000:100.
Step 1 — Enable MPLS and LDP on core interfaces
Section titled “Step 1 — Enable MPLS and LDP on core interfaces”Configure MPLS forwarding and LDP on all PE and P routers. The LDP transport address should be set to the loopback to keep sessions stable if a core link fails.
PE1:
# Enable MPLS on core-facing interfaces/mpls interfaceadd interface=ether1add interface=ether2
# Enable LDP with loopback as transport address/mpls ldpset enabled=yes lsr-id=10.0.0.1 transport-addresses=10.0.0.1
# Enable LDP on core-facing interfaces/mpls ldp interfaceadd interface=ether1add interface=ether2PE2 (same pattern, loopback 10.0.0.2):
/mpls interfaceadd interface=ether1add interface=ether2
/mpls ldpset enabled=yes lsr-id=10.0.0.2 transport-addresses=10.0.0.2
/mpls ldp interfaceadd interface=ether1add interface=ether2Verify LDP sessions form between PE1, P, and PE2 before proceeding:
/mpls ldp neighbor printStep 2 — Create VRF instances
Section titled “Step 2 — Create VRF instances”Create a VRF on each PE for each customer. The RD must be unique per PE per VRF. The route targets control which routes are shared.
PE1 — create VRF for Customer A:
/ip vrfadd name=CUST-A \ interfaces=ether10 \ route-distinguisher=65000:1 \ export-route-targets=65000:100 \ import-route-targets=65000:100PE2 — create VRF for Customer A (different RD, same RT):
/ip vrfadd name=CUST-A \ interfaces=ether10 \ route-distinguisher=65000:2 \ export-route-targets=65000:100 \ import-route-targets=65000:100Verify the VRF is active:
/ip vrf print detailStep 3 — CE-PE routing
Section titled “Step 3 — CE-PE routing”The PE needs to learn customer prefixes in the VRF. Choose the method based on your CE equipment and requirements.
Static routes in VRF
Section titled “Static routes in VRF”For simple CE devices that cannot run BGP or OSPF, add static routes pointing into the VRF:
# On PE1 — CE-A LAN behind ether10/ip routeadd dst-address=192.168.1.0/24 gateway=ether10 routing-table=CUST-A
# On PE2 — CE-B LAN behind ether10/ip routeadd dst-address=192.168.2.0/24 gateway=ether10 routing-table=CUST-AVerify the route appears in the VRF routing table:
/ip route print where routing-table=CUST-ABGP CE-PE
Section titled “BGP CE-PE”BGP CE-PE is the most flexible CE-PE method. The CE runs eBGP to the PE using the customer AS, and the PE peers into the VRF routing table.
On PE1 — BGP connection to CE-A, inside the VRF:
/routing bgp templateadd name=ce-pe-template as=65000 address-families=ip
/routing bgp connectionadd name=to-ce-a \ remote.address=192.168.1.1 remote.as=65001 \ local.role=ebgp \ vrf=CUST-A \ templates=ce-pe-templateOn CE-A — eBGP to PE1:
/routing bgp connectionadd name=to-pe1 \ remote.address=192.168.0.1 remote.as=65000 \ local.role=ebgpVerify the CE-PE session and received routes:
/routing bgp session print where name=to-ce-a/ip route print where routing-table=CUST-AStep 4 — MP-BGP VPNv4 between PE routers
Section titled “Step 4 — MP-BGP VPNv4 between PE routers”PE routers exchange VRF routes using iBGP with the vpnv4 address family. For larger deployments use a route reflector. For small labs two PEs can peer directly.
With a Route Reflector (recommended)
Section titled “With a Route Reflector (recommended)”On RR (10.0.0.10):
/routing bgp templateadd name=rr-client-template as=65000 router-id=10.0.0.10 \ address-families=vpnv4,ip
/routing bgp connectionadd name=to-pe1 \ remote.address=10.0.0.1 remote.as=65000 \ local.role=ibgp-rr \ templates=rr-client-template
add name=to-pe2 \ remote.address=10.0.0.2 remote.as=65000 \ local.role=ibgp-rr \ templates=rr-client-templateOn PE1:
/routing bgp templateadd name=ibgp-vpn as=65000 router-id=10.0.0.1 \ address-families=vpnv4,ip
/routing bgp connectionadd name=to-rr \ remote.address=10.0.0.10 remote.as=65000 \ local.role=ibgp-rr-client \ templates=ibgp-vpnOn PE2:
/routing bgp templateadd name=ibgp-vpn as=65000 router-id=10.0.0.2 \ address-families=vpnv4,ip
/routing bgp connectionadd name=to-rr \ remote.address=10.0.0.10 remote.as=65000 \ local.role=ibgp-rr-client \ templates=ibgp-vpnDirect PE-to-PE (small lab, no RR)
Section titled “Direct PE-to-PE (small lab, no RR)”# On PE1/routing bgp connectionadd name=to-pe2 \ remote.address=10.0.0.2 remote.as=65000 \ local.role=ibgp \ templates=ibgp-vpn
# On PE2/routing bgp connectionadd name=to-pe1 \ remote.address=10.0.0.1 remote.as=65000 \ local.role=ibgp \ templates=ibgp-vpnEnd-to-end traffic flow
Section titled “End-to-end traffic flow”When CE-A (192.168.1.0/24) sends a packet to CE-B (192.168.2.0/24):
- CE-A sends the packet to PE1 as the next hop.
- PE1 (ingress PE) looks up 192.168.2.0/24 in VRF
CUST-A. Finds a VPNv4 route learned from PE2 with VPN labelL_vpnand next-hop 10.0.0.2. LDP provides transport labelL_ldpto reach 10.0.0.2. PE1 imposes both labels: outerL_ldp, innerL_vpn. - P routers swap only the outer label
L_ldpas the packet traverses the core. - Penultimate P router pops the outer label (PHP — Penultimate Hop Popping), forwarding the packet to PE2 with only the VPN label
L_vpn. - PE2 (egress PE) receives the packet, looks up VPN label
L_vpn, identifies VRFCUST-A, pops the VPN label, and forwards the plain IP packet outether10to CE-B. - CE-B receives the original IP packet.
P routers have no knowledge of customer VRFs or VPN labels — they perform only label-switching operations on the transport label.
Verification
Section titled “Verification”# Check VRF configuration and interface assignment/ip vrf print detail
# Verify routes in customer VRF/ip route print where routing-table=CUST-A
# Check VPNv4 routes in BGP/routing route print where afi=vpnv4
# Check BGP sessions/routing bgp session print
# Inspect MPLS forwarding table/mpls forwarding-table print
# Check LDP label bindings/mpls ldp binding print
# Verify LDP neighbor sessions/mpls ldp neighbor printTroubleshooting
Section titled “Troubleshooting”VPNv4 routes not appearing on remote PE
Section titled “VPNv4 routes not appearing on remote PE”Check that the BGP session is established and the VPNv4 address family is negotiated:
/routing bgp session print detail where name=to-rrIf the session is up but no VPNv4 routes are present, confirm the VRF route targets match on both PEs:
/ip vrf print detailThe export-route-targets on PE1 must match the import-route-targets on PE2 for routes to flow.
Traffic reaches the egress PE but is not forwarded to CE
Section titled “Traffic reaches the egress PE but is not forwarded to CE”Verify the VPN label is present in the forwarding table and the VRF routing table has the destination:
/mpls forwarding-table print/ip route print where routing-table=CUST-AAlso confirm the CE-facing interface is assigned to the correct VRF:
/ip vrf print detailLDP sessions not forming
Section titled “LDP sessions not forming”LDP sessions require IP reachability between transport addresses. Verify the loopback is reachable and the IGP is advertising it:
/ping 10.0.0.2 routing-table=main/mpls ldp neighbor printMPLS labels not being swapped in the core
Section titled “MPLS labels not being swapped in the core”Confirm MPLS is enabled on the core interfaces and that the LDP binding exists for the PE loopback:
/mpls interface print/mpls ldp binding print where prefix=10.0.0.2/32Inter-VRF route leaking
Section titled “Inter-VRF route leaking”Route leaking lets routes from one VRF be visible in another VRF on the same or a remote PE. This is controlled entirely by route targets — there is no separate mechanism. A VRF imports any VPNv4 route whose exported RT matches any value in its import-route-targets list.
Shared services VRF
Section titled “Shared services VRF”A common use case is a shared services VRF (DNS, NTP, management) that every customer VRF can reach, but customers cannot reach each other.
RT plan:
| VRF | export-route-targets | import-route-targets |
|---|---|---|
CUST-A | 65000:100 | 65000:100, 65000:999 |
CUST-B | 65000:200 | 65000:200, 65000:999 |
SHARED | 65000:999 | (none — shared services do not need to reach customers) |
PE1 — create the VRFs:
/ip vrfadd name=CUST-A \ interfaces=ether10 \ route-distinguisher=65000:1 \ export-route-targets=65000:100 \ import-route-targets=65000:100,65000:999
add name=CUST-B \ interfaces=ether11 \ route-distinguisher=65000:3 \ export-route-targets=65000:200 \ import-route-targets=65000:200,65000:999
add name=SHARED \ interfaces=ether12 \ route-distinguisher=65000:5 \ export-route-targets=65000:999 \ import-route-targets=65000:999With this configuration CUST-A and CUST-B each import the SHARED VRF’s routes (RT 65000:999), but neither imports the other customer’s routes.
Hub-and-spoke topology
Section titled “Hub-and-spoke topology”In a hub-and-spoke L3VPN all inter-spoke traffic is forced through a hub site. Spokes do not import each other’s routes directly.
RT plan:
| VRF | export-route-targets | import-route-targets |
|---|---|---|
HUB | 65000:100 | 65000:101, 65000:102 |
SPOKE1 | 65000:101 | 65000:100 |
SPOKE2 | 65000:102 | 65000:100 |
/ip vrfadd name=HUB \ interfaces=ether10 \ route-distinguisher=65000:10 \ export-route-targets=65000:100 \ import-route-targets=65000:101,65000:102
add name=SPOKE1 \ interfaces=ether11 \ route-distinguisher=65000:11 \ export-route-targets=65000:101 \ import-route-targets=65000:100
add name=SPOKE2 \ interfaces=ether12 \ route-distinguisher=65000:12 \ export-route-targets=65000:102 \ import-route-targets=65000:100Spoke1 and Spoke2 each import only the Hub’s routes (RT 65000:100). The Hub imports both spoke RTs. Traffic between Spoke1 and Spoke2 is routed through the Hub site.
Verifying leaked routes
Section titled “Verifying leaked routes”After configuring asymmetric RTs, confirm the expected routes appear in each VRF’s routing table:
# Routes visible in CUST-A (should include SHARED prefixes)/ip route print where routing-table=CUST-A
# Routes visible in SHARED (should not include customer prefixes)/ip route print where routing-table=SHARED
# All VPNv4 routes in BGP (check RT communities)/routing route print where afi=vpnv4See Also
Section titled “See Also”- Multi-Protocol Label Switching (MPLS) — MPLS fundamentals, LDP, and label forwarding
- VPLS — Layer 2 VPN over MPLS
- BGP — BGP configuration including address families and route reflection
- Virtual Routing and Forwarding (VRF) — VRF fundamentals and VRF-lite usage