MPLS on MikroTik: A Complete Layer 3 VPN Configuration Guide
MPLS L3VPN is how service providers deliver private, isolated routing to customers over one shared core network. It is also one of the least documented corners of RouterOS v7 — the syntax changed significantly from v6, and most existing guides still show the old command structure.
This guide covers a full MPLS L3VPN build on RouterOS v7: the provider core (OSPF, LDP), VRFs for customer isolation, MP-BGP with the VPNv4 address family to carry customer routes across the core, CE-to-PE connectivity, and the verification steps that confirm each layer works before moving to the next.
Table of Contents
- What MPLS L3VPN Actually Solves
- Architecture: PE, P, and CE Roles
- Step 1: Build the Provider Core (Loopbacks and OSPF)
- Step 2: Enable MPLS and LDP
- Step 3: Create the Customer VRF
- Step 4: Configure iBGP Between PE Routers (VPNv4)
- Step 5: Connect the Customer Edge (CE) Router
- Route Distinguisher and Route Target Explained
- Running Multiple Customer VRFs on One PE
- Giving a VRF Internet Access
- Verification Commands at Each Layer
- Common Problems and Fixes
- Quick-Reference Configuration Cheat Sheet
- Deployment Checklist
- Conclusion
What MPLS L3VPN Actually Solves
A service provider running one physical MPLS core needs to give multiple customers private routing, without customer A ever seeing customer B’s routes — even when both customers use the exact same private IP ranges.
- Overlapping address space. Two customers both running
10.0.0.0/24internally is normal. MPLS L3VPN keeps their routing tables completely separate, so this never causes a conflict. - Label switching, not IP lookups, in the core. Once a packet enters the provider core, P routers forward it using MPLS labels, not IP routing table lookups — this is what makes MPLS fast and what allows customer routes to stay invisible to the core.
- One physical network, many virtual ones. The same physical links and P routers carry traffic for every customer VPN, each isolated by VRF and BGP route targets, without provisioning separate physical infrastructure per customer.
Architecture: PE, P, and CE Roles
- CE (Customer Edge) — the customer’s own router, connected to the provider network. The CE typically runs no MPLS at all; it just exchanges routes with the PE using static routing or a routing protocol like BGP.
- PE (Provider Edge) — the provider router directly connected to the customer. This is where VRFs live, where customer routes get imported into MP-BGP, and where MPLS labels get pushed onto customer traffic entering the core.
- P (Provider core) — interior routers that only forward MPLS-labeled traffic between PE routers. P routers never see customer routes directly; they only know how to reach PE loopback addresses via labels.
This guide builds a minimal topology: two PE routers (PE1, PE2), each with one CE router attached, connected through the provider core. Scale the pattern by adding more PE routers and repeating the VRF and BGP configuration per customer.
Step 1: Build the Provider Core (Loopbacks and OSPF)
Every PE and P router needs a loopback address, and the core needs an IGP — typically OSPF — to make every loopback reachable from every other router before MPLS or BGP can function.
# On each PE and P router
/interface bridge add name=loopback0
/ip address add address=10.255.255.1/32 interface=loopback0
/routing ospf instance add name=core disabled=no
/routing ospf area add instance=core name=backbone area-id=0.0.0.0
/routing ospf interface-template add interfaces=loopback0,ether1 area=backbone
- Use a unique loopback address on every router (
10.255.255.1,10.255.255.2, and so on) — this address becomes the router’s BGP identity and the target for LDP label distribution. - Confirm every loopback is reachable from every other router before proceeding — MPLS and BGP both depend on this baseline reachability.
/routing ospf neighbor print
/ping 10.255.255.2 src-address=10.255.255.1
Step 2: Enable MPLS and LDP
LDP (Label Distribution Protocol) automatically assigns and distributes MPLS labels between neighboring routers, building the label-switched path across the core:
# On each PE and P router
/mpls ldp set enabled=yes lsr-id=10.255.255.1 transport-address=10.255.255.1
/mpls ldp interface add interface=ether1
lsr-id— the Label Switch Router ID, matching the router’s loopback address for consistency across the core.- Add an
/mpls ldp interfaceentry for every core-facing interface — LDP only runs on interfaces explicitly added here, not automatically on every active interface.
Verify LDP neighbor sessions before moving forward:
/mpls ldp neighbor print
/mpls forwarding-table print
The forwarding table should show labels assigned for reaching every loopback address in the core once LDP sessions establish correctly.
Step 3: Create the Customer VRF
The VRF isolates a customer’s routing table from the main routing table and from every other customer’s VRF, on the PE routers only:
# On PE1
/ip vrf add name=cust-acme interfaces=ether5
/ip address add address=192.168.100.1/30 interface=ether5 vrf=cust-acme
interfaces=ether5— the interface facing the customer’s CE router. Assign this interface to the VRF so traffic arriving on it uses the customer’s isolated routing table.- Any route learned or configured on this interface lands in the VRF’s own routing table, separate from
main.
Step 4: Configure iBGP Between PE Routers (VPNv4)
MP-BGP with the VPNv4 address family carries customer routes across the provider core, tagged with route distinguishers so overlapping customer address space never collides:
# On PE1
/routing bgp connection add name=pe2-vpnv4 \
local.address=10.255.255.1 remote.address=10.255.255.2 \
as=65000 remote.as=65000 \
address-families=vpnv4 \
.role=ibgp
# On PE2 (mirrored)
/routing bgp connection add name=pe1-vpnv4 \
local.address=10.255.255.2 remote.address=10.255.255.1 \
as=65000 remote.as=65000 \
address-families=vpnv4 \
.role=ibgp
- Both PE routers use the same AS number — this is an internal BGP (iBGP) session within the provider’s own network, not a peering session with an external customer AS.
address-families=vpnv4is the key setting — this activates the extended NLRI format that carries the route distinguisher alongside the customer prefix, which is what allows overlapping customer address ranges to coexist in the same BGP session.- Larger deployments use a route reflector instead of a full mesh of iBGP sessions between every PE pair — worth planning for once you scale past two or three PE routers.
Bind the VRF to BGP so its routes actually get advertised into VPNv4:
/routing bgp connection add name=cust-acme-vrf vrf=cust-acme \
address-families=ip redistribute=connected .role=ibgp \
local.address=192.168.100.1
Step 5: Connect the Customer Edge (CE) Router
The CE router needs no MPLS configuration at all — from its perspective, it is just connecting to a normal router:
# On the customer's CE router (also RouterOS, in this example)
/ip address add address=192.168.100.2/30 interface=ether1
/ip route add dst-address=0.0.0.0/0 gateway=192.168.100.1
For a customer that wants dynamic routing instead of a static default route, run eBGP between CE and PE:
# On PE1, peering with the customer's CE
/routing bgp connection add name=cust-acme-ce vrf=cust-acme \
local.address=192.168.100.1 remote.address=192.168.100.2 \
as=65000 remote.as=65001 address-families=ip .role=ebgp
The customer’s routes learned via this eBGP session automatically redistribute into VPNv4 and reach the customer’s other sites through the provider core, without any additional configuration beyond this session.
Route Distinguisher and Route Target Explained
These two values are the mechanism that makes VPNv4 work, and they solve two different problems:
- Route Distinguisher (RD) — a unique prefix added to every customer route to make it unique in the global VPNv4 table, even when two customers use identical IP ranges. Format:
ASN:numberorIP-address:number, e.g.65000:100. - Route Target (RT) — a BGP extended community that controls which VRFs a route gets imported into. Export RT tags a route as it leaves a VRF; import RT determines which VRFs accept it.
For a simple, non-overlapping customer VPN (one customer, multiple sites, no route sharing with other customers), export and import RT are usually identical:
/ip vrf set cust-acme export-route-targets=65000:100 import-route-targets=65000:100
Different export and import RT values are how you build more advanced topologies — hub-and-spoke VPNs, extranets shared between two otherwise-isolated customers, and similar designs — by controlling exactly which VRFs accept which routes.
Running Multiple Customer VRFs on One PE
Adding a second customer on the same PE router just repeats Steps 3 and 4 with a new VRF name and a distinct RD:
/ip vrf add name=cust-globex interfaces=ether6
/ip address add address=192.168.200.1/30 interface=ether6 vrf=cust-globex
/ip vrf set cust-globex export-route-targets=65000:200 import-route-targets=65000:200
/routing bgp connection add name=cust-globex-vrf vrf=cust-globex \
address-families=ip redistribute=connected .role=ibgp \
local.address=192.168.200.1
Both customers can use overlapping IP ranges (even the same subnet) on their respective VRFs without any conflict, since the RD keeps them distinct inside VPNv4, and the RT keeps them isolated from each other’s routing tables entirely.
Giving a VRF Internet Access
A VRF has no internet access by default — it is intentionally isolated from the main routing table. Providing internet access requires a deliberate design decision, not a default:
- Dedicated PE-to-internet router. Route the VRF’s traffic to a router that sits between the MPLS network and the internet-facing router, performing NAT there before traffic reaches the public internet.
- At least one public IP per VRF needing internet access is required for the NAT translation at that boundary router.
- Route leaking, done deliberately. A default route can be leaked from the main table into the customer VRF, and the customer’s public-facing NAT’d address leaked back — but only as an explicit, intentional configuration, since uncontrolled leaking defeats the isolation VRFs exist to provide.
Verification Commands at Each Layer
# OSPF core reachability
/routing ospf neighbor print
# LDP label distribution
/mpls ldp neighbor print
/mpls forwarding-table print
# BGP VPNv4 sessions between PE routers
/routing bgp session print
# VRF routing table contents
/ip route print where routing-table=cust-acme
# End-to-end test from CE
/ping 192.168.200.2 vrf=cust-acme
Work through these in order — a VRF routing table with no routes almost always traces back to a problem at the BGP or LDP layer underneath it, not the VRF configuration itself.
Common Problems and Fixes
VRF has no routes at all
- Cause: The BGP connection redistributing the VRF’s connected routes into VPNv4 is missing or misconfigured.
- Fix: Confirm the VRF-bound BGP connection has
redistribute=connectedset and shows as established with/routing bgp session print.
PE routers cannot establish LDP neighbors
- Cause: OSPF has not converged, so loopback addresses are not yet reachable between routers — LDP depends on that reachability first.
- Fix: Confirm full OSPF neighbor adjacency with
/routing ospf neighbor printbefore troubleshooting LDP directly.
One customer sees another customer’s routes
- Cause: Import and export route targets are misconfigured, likely matching between VRFs that should stay isolated.
- Fix: Review
/ip vrf print detailon every VRF and confirm import/export RT values are unique per customer, unless a shared route is intentional (an extranet design).
CE-to-PE eBGP session never establishes
- Cause: AS number mismatch, or the BGP connection on the PE side is not correctly scoped to the customer VRF.
- Fix: Confirm the
vrf=parameter is set on the PE-side BGP connection and that the AS numbers on both sides match what each router expects (remote AS on one side equals local AS on the other).
Traffic reaches the PE but never crosses the core
- Cause: A P router in the path has no MPLS interface configured, breaking the label-switched path partway through the core.
- Fix: Confirm every core-facing interface on every P router has an
/mpls ldp interfaceentry, not just the PE routers at the edges.
Quick-Reference Configuration Cheat Sheet
# Core: loopback + OSPF (every PE/P router)
/ip address add address=10.255.255.X/32 interface=loopback0
/routing ospf interface-template add interfaces=loopback0,ether1 area=backbone
# MPLS: LDP (every PE/P router)
/mpls ldp set enabled=yes lsr-id=10.255.255.X transport-address=10.255.255.X
/mpls ldp interface add interface=ether1
# VRF: customer isolation (PE router)
/ip vrf add name=cust-name interfaces=ether5
/ip vrf set cust-name export-route-targets=65000:X import-route-targets=65000:X
# BGP: iBGP VPNv4 between PE routers
/routing bgp connection add local.address=10.255.255.1 remote.address=10.255.255.2 \
as=65000 remote.as=65000 address-families=vpnv4 .role=ibgp
# BGP: bind VRF to redistribute connected routes
/routing bgp connection add vrf=cust-name address-families=ip \
redistribute=connected .role=ibgp local.address=192.168.100.1
# Verify
/routing ospf neighbor print
/mpls ldp neighbor print
/routing bgp session print
/ip route print where routing-table=cust-name
Deployment Checklist
- Assign a unique loopback address to every PE and P router
- Confirm OSPF converges and every loopback is reachable core-wide
- Enable LDP on every core-facing interface, on every PE and P router
- Confirm LDP neighbor sessions and label distribution before building VRFs
- Create one VRF per customer, with a unique route distinguisher
- Set import/export route targets deliberately — matching for standard isolation, differing only for intentional route sharing
- Establish iBGP VPNv4 sessions between all PE routers (or a route reflector at scale)
- Bind each VRF to BGP with
redistribute=connected, or a routing protocol toward the CE - Design internet access for a VRF deliberately, through a dedicated NAT boundary — never assume default connectivity
- Verify layer by layer: OSPF, then LDP, then BGP, then the VRF routing table
Conclusion
MPLS L3VPN on RouterOS v7 breaks into four dependent layers: an IGP core for loopback reachability, LDP for label distribution, VRFs for customer isolation, and MP-BGP with VPNv4 to carry customer routes across the shared core. Each layer depends on the one below it working first — troubleshoot in that order, and most “the VRF isn’t working” problems turn out to be an LDP or OSPF issue instead. Once the pattern is running for one customer, adding the next is just repeating the VRF and BGP steps with a new route distinguisher.
Check our list of MikroTik guides