Skip to content

MPLS Basics

For the impatient: basic LDP setup between two routers.

# Create loopback interface for stable LDP sessions
/interface/bridge/add name=lo
/ip/address/add address=1.1.1.1/32 interface=lo
# Configure LDP instance
/mpls/ldp/add lsr-id=1.1.1.1 transport-addresses=1.1.1.1
# Enable LDP on interfaces connected to MPLS network
/mpls/ldp/interface/add interface=ether1
/mpls/ldp/interface/add interface=ether2
# Verify LDP neighbors
/mpls/ldp/neighbor/print

Verify with:

/mpls/forwarding-table/print
# Should show labels assigned to routes

What this does: MPLS (MultiProtocol Label Switching) replaces traditional IP routing lookups with efficient label-based forwarding. Instead of examining destination IP addresses at each hop, routers swap short fixed-length labels, enabling faster forwarding decisions.

When to use this:

  • Building service provider networks with traffic engineering
  • Creating Layer 2 VPNs (VPLS) across routed networks
  • Implementing MPLS IP VPN for customer isolation
  • Optimizing forwarding in large networks
  • Traffic engineering with explicit path control (RSVP-TE)

Prerequisites:

  • IGP routing configured (OSPF or static routes) between all MPLS routers
  • Loopback interfaces for stable LDP sessions
  • Understanding of basic routing concepts

MPLS Limitations

MPLS forwarding bypasses IP header processing. NAT, firewall filters, and mangle rules do not apply to MPLS-switched traffic. These must be applied at ingress/egress points of the MPLS network.

Traditional IP routing examines the destination address of every packet at every hop, performing a longest-prefix match against the routing table. MPLS simplifies this by attaching a short label to packets. Routers then make forwarding decisions based on the label alone—a simple table lookup rather than a complex routing decision.

An LSP is the path a labeled packet takes through the MPLS network:

Label Switched Path showing ingress router pushing label, transit router swapping label, and egress router popping label
  1. Ingress (Push): First router determines packet should use MPLS, pushes a label
  2. Transit (Swap): Intermediate routers swap incoming label for outgoing label
  3. Egress (Pop): Final router removes the label and delivers via normal IP routing
Label Distribution Protocol (LDP) diagram

LDP automatically distributes labels between routers. When LDP neighbors establish a session, they exchange label bindings for routes in their routing tables. This creates the label mappings needed for LSPs to form.

PHP is an optimization where the second-to-last router removes the MPLS label instead of the egress router. The egress router receives an unlabeled packet, saving it from doing both label lookup and IP lookup. RouterOS uses PHP by default (advertises implicit-null label).

Any router participating in MPLS label switching. The LSR-ID uniquely identifies each router in the MPLS domain—typically the loopback address.

Before configuring, ensure:

  • All routers have IGP connectivity (OSPF recommended)
  • Each router has a unique loopback address
  • Loopbacks are reachable from all other routers

Create a loopback for stable LDP sessions. LDP sessions should use loopbacks, not physical interfaces, because loopbacks don’t go down when a single link fails:

/interface/bridge/add name=lo
/ip/address/add address=1.1.1.1/32 interface=lo

Ensure the loopback is advertised in your IGP (OSPF/static routes).

Create the LDP instance with your loopback as both LSR-ID and transport address:

/mpls/ldp/add lsr-id=1.1.1.1 transport-addresses=1.1.1.1
ParameterPurpose
lsr-idUnique identifier for this router in MPLS domain
transport-addressesSource address for LDP TCP sessions

Enable LDP on interfaces connecting to other MPLS routers:

/mpls/ldp/interface/add interface=ether1
/mpls/ldp/interface/add interface=ether2

LDP sends hello packets on these interfaces to discover neighbors.

Check that LDP sessions have established:

/mpls/ldp/neighbor/print

Expected output:

# PEER LOCAL-TRANSPORT OPERATIONAL DYNAMIC
0 2.2.2.2:0 1.1.1.1 yes yes
1 3.3.3.3:0 1.1.1.1 yes yes

operational=yes indicates an active LDP session.

Check that labels have been assigned to routes:

/mpls/forwarding-table/print

Expected output:

# PREFIX LABEL OUT-LABEL NEXTHOPS
0 2.2.2.2/32 17 impl-null ether1
1 3.3.3.3/32 18 19 ether1
  • impl-null = Penultimate hop popping (you’re the second-to-last hop)
  • Numeric label = Push this label when forwarding
Scenario: three-router MPLS backbone diagram

Set up MPLS between three routers (R1-R2-R3):

Router R1 (1.1.1.1):

/interface/bridge/add name=lo
/ip/address/add address=1.1.1.1/32 interface=lo
/mpls/ldp/add lsr-id=1.1.1.1 transport-addresses=1.1.1.1
/mpls/ldp/interface/add interface=ether1

Router R2 (2.2.2.2):

/interface/bridge/add name=lo
/ip/address/add address=2.2.2.2/32 interface=lo
/mpls/ldp/add lsr-id=2.2.2.2 transport-addresses=2.2.2.2
/mpls/ldp/interface/add interface=ether1
/mpls/ldp/interface/add interface=ether2

Router R3 (3.3.3.3):

/interface/bridge/add name=lo
/ip/address/add address=3.3.3.3/32 interface=lo
/mpls/ldp/add lsr-id=3.3.3.3 transport-addresses=3.3.3.3
/mpls/ldp/interface/add interface=ether1

If your network doesn’t support jumbo frames, set MPLS MTU to 1500:

/mpls/interface/add interface=ether1 mpls-mtu=1500
/mpls/interface/add interface=ether2 mpls-mtu=1500

MPLS adds 4 bytes per label. Default MTU is 1508, which may cause silent drops on networks with 1500-byte MTU limits.

Disable TTL propagation to hide internal MPLS topology:

/mpls/settings/set propagate-ttl=no

With this setting, traceroute shows only ingress and egress routers, not transit hops.

Reduce label distribution to only loopback addresses (recommended for large networks):

# Only advertise labels for loopbacks
/mpls/ldp/advertise-filter/add prefix=1.1.1.0/24 advertise=yes
/mpls/ldp/advertise-filter/add prefix=0.0.0.0/0 advertise=no
# Only accept labels for loopbacks
/mpls/ldp/accept-filter/add prefix=1.1.1.0/24 accept=yes
/mpls/ldp/accept-filter/add prefix=0.0.0.0/0 accept=no

Configure LDP for both address families:

/mpls/ldp/add afi=ip,ipv6 lsr-id=1.1.1.1 \
transport-addresses=1.1.1.1,2001:db8::1 preferred-afi=ipv6

Prevent label conflicts during network convergence:

# Router 1
/mpls/settings/set dynamic-label-range=4096-8191
# Router 2
/mpls/settings/set dynamic-label-range=8192-12287
# Router 3
/mpls/settings/set dynamic-label-range=12288-16383

Confirm your MPLS configuration is working:

/mpls/ldp/neighbor/print

Expected: All neighbors show operational=yes.

/mpls/ldp/local-mapping/print

Expected: Labels assigned to your routes.

/mpls/ldp/remote-mapping/print

Expected: Labels received from neighbors.

/mpls/forwarding-table/print

Expected: Entries with labels and next-hops for remote destinations.

Test end-to-end connectivity using loopbacks:

/ping 3.3.3.3 src-address=1.1.1.1

Traffic should be label-switched through the network.

Troubleshooting diagram
SymptomCauseSolution
LDP neighbor not formingNo route to transport addressVerify IGP routes to loopbacks exist
LDP interface shows “invalid”Interface is a bridge slaveUse the bridge interface, not slave ports
Forwarding table emptyLDP not distributing labelsCheck LDP instance and interface config
Packets dropped silentlyMPLS MTU larger than link MTUSet mpls-mtu=1500 on all interfaces
LDP session flappingMismatched timersAlign hello-interval and hold-time with IGP
Filter changes not appliedExisting bindings not updatedRestart LDP neighbor or instance
No route through MPLSLDP only follows active IGP routesVerify OSPF/static routes exist
/mpls/ldp/neighbor/print detail

Look for:

  • operational=yes — Session established
  • throttled=yes — Session failed, in backoff (up to 120s)
  • dynamic=yes — Discovered via hello packets
/mpls/ldp/interface/print

Interfaces should not show “invalid” status.

LDP only distributes labels for active routes (not BGP by default):

/ip/route/print where dst-address~"2.2.2.2"

The route must exist before LDP will create a label binding.

Common Mistakes

  • Using physical interface IPs as transport-addresses — Use loopbacks for stability
  • Forgetting to advertise loopbacks in IGP — LDP needs routes to form sessions
  • Enabling LDP on bridge slave ports — Use the bridge interface instead
  • Expecting NAT/firewall to work on MPLS traffic — They don’t; apply at ingress/egress
  • Mismatched MPLS MTU — Causes silent packet drops for large packets
  • Not setting unique label ranges — Can cause issues during convergence
MPLS domain architecture showing Customer Edge routers connected to Provider Edge routers at network edges, with Provider routers in the transit core
  • CE routers connect customers to the MPLS network
  • PE routers push/pop labels at network edges
  • P routers only swap labels (fastest operation)
Device TypeMPLS Support
CCR seriesYes
RB series (most)Yes
CRS seriesYes
CHRYes
hAP lite, hAP lite TC, hAP miniNo (SMIPS devices)

Check with: /system/resource/print — SMIPS architecture cannot run MPLS.

  • OSPF - IGP commonly used with MPLS
  • BGP - MP-BGP for MPLS VPN signaling
  • Static Routes - basic routing for MPLS
CommandRequired ArgsOptional ArgsNotes
/mpls/ldp/addlsr-id, transport-addressesafi, vrf, disabledCreate LDP instance
/mpls/ldp/interface/addinterfacehello-interval, hold-timeEnable LDP on interface
/mpls/ldp/neighbor/print-detailShow LDP neighbors
/mpls/ldp/local-mapping/print--Show locally assigned labels
/mpls/ldp/remote-mapping/print--Show labels from neighbors
/mpls/forwarding-table/print--Show MPLS forwarding entries
/mpls/settings/print--Show global MPLS settings
PropertyTypeDefaultDescription
lsr-idIP-Label Switch Router identifier (required)
transport-addressesIP list-Source addresses for LDP sessions (required)
afiip/ipv6/ip,ipv6ipAddress families for label distribution
distribute-for-defaultyes/nonoDistribute labels for default route
use-explicit-nullyes/nonoAdvertise explicit-null instead of implicit-null
vrfstringmainVRF table for this instance

LDP interface properties (/mpls/ldp/interface)

Section titled “LDP interface properties (/mpls/ldp/interface)”
PropertyTypeDefaultDescription
interfacestring-Interface name (required)
hello-intervaltime5sInterval between hello packets
hold-timetime15sNeighbor timeout
accept-dynamic-neighborsyes/noyesAccept discovered neighbors
PropertyTypeDefaultDescription
dynamic-label-rangerange16-1048575Label allocation range
propagate-ttlyes/noyesCopy TTL from IP to MPLS header
allow-fast-pathyes/noyesEnable MPLS FastPath