Berik Ashimov // senior.it.engineer
Download CV
POSTS / MIKROTIK

VPLS on RouterOS 7: Layer 2 Over MPLS, With the MTU Math Done Right

// series · MikroTik RouterOS 7 Guide part 17 of 35
  1. ... 14 earlier
  2. VRFs on RouterOS 7: Real Separation, Not Firewall Hope
  3. MPLS and LDP on RouterOS 7: Labels on a Budget
  4. VPLS on RouterOS 7: Layer 2 Over MPLS, With the MTU Math Done Right
  5. VXLAN on RouterOS 7: Layer 2 Over Any IP Network
  6. GRE, IPIP and EoIP on RouterOS 7: Picking the Right Dumb Tunnel
  7. ... 16 later
view the full series →

Stretching Layer 2 between sites is one of those requests that never dies. Someone needs the same VLAN in two datacenters, a legacy application discovers its peers by broadcast, or a customer just wants “one big LAN” across a metro network. You can refuse — often the right answer — or you can do it properly. On an MPLS backbone, “properly” is VPLS: pseudowires that carry Ethernet frames across your labeled core, terminating in bridges at each edge.

I covered LDP and the MPLS data plane in the previous article. VPLS builds directly on it: if your LSPs aren’t up and your MPLS MTU isn’t right, stop here and fix that first — VPLS inherits every underlay problem and adds its own four bytes of ways to fail.

What VPLS Actually Is

A VPLS instance is a mesh of point-to-point pseudowires between PE routers. Each pseudowire is an MPLS tunnel carrying Ethernet frames with two labels: the outer transport label (from LDP, getting the packet to the far PE) and the inner VC label (identifying which VPLS instance the frame belongs to). At each PE, the pseudowire terminates in a bridge alongside the local customer ports.

The negotiation of VC labels can be done by targeted LDP sessions or by MP-BGP. On RouterOS, LDP-signaled is the mature, predictable path and what I’ll use here. BGP-signaled VPLS exists for interop scenarios, but its RouterOS 7 support arrived late and rough — if you’re building MikroTik-to-MikroTik, use LDP signaling and keep your life simple.

LDP-Signaled VPLS

Assume the MPLS articles’ underlay: loopbacks exchanged via OSPF, LDP running between PE1 (10.255.0.1) and PE2 (10.255.0.2). The VPLS interface on each side points at the other’s loopback:

Terminal window
# PE1
/interface vpls add name=vpls-cust1 peer=10.255.0.2 vpls-id=65000:100 \
pw-type=tagged-ethernet disabled=no comment="Customer 1 L2 - to PE2"
# PE2 — mirror image
/interface vpls add name=vpls-cust1 peer=10.255.0.1 vpls-id=65000:100 \
pw-type=tagged-ethernet disabled=no comment="Customer 1 L2 - to PE1"

The vpls-id must match on both ends — it’s the identity of the circuit, conventionally <your-ASN>:<circuit-number>. When both sides are configured, a targeted LDP session forms between the loopbacks and the pseudowire negotiates its VC labels.

pw-type matters more than it looks: tagged-ethernet carries VLAN tags through the pseudowire, raw-ethernet expects untagged frames. Mismatch it and one direction of traffic silently loses (or unexpectedly keeps) its tags.

Verify before bridging anything:

Terminal window
/interface vpls print detail
/interface vpls monitor vpls-cust1 once
# look for: remote-label, local-label, transport learned via LDP
/mpls forwarding-table print

If the pseudowire won’t come up, it’s almost always one of: no LDP session to the peer loopback (check /mpls ldp neighbor print), the peer address not being the loopback LDP actually runs on, or mismatched vpls-id.

Bridge Integration and Split Horizon

The pseudowire is just an interface. Bridge it with the customer-facing port:

Terminal window
/interface bridge add name=br-cust1 comment="Customer 1 VPLS bridge"
/interface bridge port add bridge=br-cust1 interface=ether5
/interface bridge port add bridge=br-cust1 interface=vpls-cust1 horizon=1

That horizon=1 is the line that prevents your metro network from becoming a broadcast centrifuge. With three or more PEs, VPLS builds a full mesh of pseudowires — every PE has a wire to every other PE. If PE1 floods a broadcast to PE2, and PE2 re-floods it out its pseudowire to PE3, you have a loop the moment PE1 also delivered it to PE3 directly.

Split horizon fixes this: bridge ports sharing the same horizon value never forward to each other. Put all pseudowires in a VPLS instance on the same horizon number, and customer-facing ports on none. Frames from a customer port flood to all pseudowires; frames arriving on a pseudowire flood only to local customer ports, never back into the mesh. Full mesh plus split horizon means loop-free without running spanning tree across your core — which you absolutely do not want.

The MTU Math, Again

MPLS killed more VPLS deployments via MTU than every other cause combined. The arithmetic:

Customer frame (1500 bytes IP) + Ethernet header (14) + VC label (4) + transport label (4) = your core links need to carry at least 1522 bytes of L2 payload, more with VLAN tags on the wire (+4) or more labels in the stack (fast reroute, another +4 each).

Practical rule: set core interface l2mtu as high as the hardware allows and configure MPLS MTU explicitly with headroom:

Terminal window
# On all core-facing interfaces (check l2mtu capability with /interface print)
/interface ethernet set ether1 l2mtu=1580
/mpls settings set mpls-mtu=1560

On the VPLS interface, pw-l2mtu advertises the L2MTU to the remote peer. Both ends should agree, and it must fit inside what the core actually carries. The failure mode of getting this wrong is the nastiest kind: pings work, SSH works, and anything with full-size frames — file transfers, HTTPS with real payloads — hangs. If a customer says “it’s slow”, test with actual full-size frames:

Terminal window
/ping 192.168.50.2 size=1500 do-not-fragment

from a host inside the L2 domain, not from the router.

When VPLS Still Wins

Given that the VXLAN article is right after this one, an honest comparison:

VPLS wins when you already run an MPLS core: it rides the LSPs you have, converges with your IGP, gives per-circuit pseudowires with clean demarcation, and carries no IP/UDP overhead in the core — labels only. Adding circuit #47 is two add lines.

VXLAN wins when there is no MPLS and no appetite for it: it needs nothing but IP reachability between VTEPs, crosses third-party networks and the internet (add WireGuard for confidentiality), and it’s where the industry — and MikroTik’s hardware-offload work — is heading.

EoIP wins at exactly one thing: a quick MikroTik-to-MikroTik L2 hack over any IP path with zero prerequisites. It’s proprietary and per-tunnel; the tunnels article covers where that’s acceptable.

The trap to avoid is running VPLS because it’s there on a network with three sites and no other MPLS use case. LDP, label MTU discipline, and mesh horizon management are an operational tax; pay it when you’re a service provider or metro operator amortizing it across many circuits, not for one stretched VLAN.

Closing Thoughts

VPLS on RouterOS 7 is unglamorous and solid: build the LDP underlay honestly, mirror the vpls-id on both ends, put every pseudowire on the same bridge horizon, and do the MTU arithmetic on paper before you ship frames. The circuits then run for years without attention. Most of the outages you’ll ever see on it are the underlay’s — which is exactly why the previous article insisted you verify LSPs end-to-end before layering customers on top.

// share