Juniper to MikroTik – MPLS and VPNv4 interop

Juniper to MikroTik – a new series

Previously, I’ve written a number of articles that compared syntax between Cisco and MikroTik and have received some great feedback on them.

As such, I decided to begin a series on Juniper to MikroTik starting with MPLS and L3VPN interop as it related to a project I was working on last year.

In the world of network engineering, learning a new syntax for a NOS can be overwhelming if you need a specific set of config in a short timeframe. The command structure for RouterOS can be a bit challenging if you are used to Juniper CLI commands.

If you’ve worked with Juniper gear and are comfortable with how to deploy that vendor, it is helpful to draw comparisons between the commands, especially if you are trying to build a network with a MikroTik and Juniper router.

Lab Overview

The lab consists of (3) Juniper P routers and (2) MikroTik PE routers. Although we did not get into L3VPN in this particular lab, the layout is the same.

A note on route-targets

It seems that the format of the route-target has some bearing on this being successful. Normally i’ll use a format like 8675309:1 but in this case, I had some interop issues with making that work so we used dotted decimal.

Some of the results when searching seem to suggest that platforms like Juniper and Cisco reverse the RT string in the packet while MikroTik uses it in sequential order

To work around that, the format we used was the same forwards and backwards – 1.1.1.1:1

MPLS and VPNv4 use case

MPLS is often used in service provider and data center networks to provide multi-tenancy.

VPNv4 specifically allows for separate routing tables to be created (VRFs) and advertised via BGP using the VPNv4 address family.

This address family relies on MPLS to assign a VPN label and route target as an extended community to the route which keeps it isolated from routes in other VRFs.

Practical Use

Many service provider networks rely on Juniper for the edge and core roles.

However, increasingly, ISPs want to save money on last mile and smaller aggregation points.

MikroTik is an effective choice for more simplistic MPLS capabilities as it’s inexpensive and interops with Juniper.

This creates a variety of low cost deployment options as a manged CE router, GPON aggregation in the last mile, managed CE for enterprise customers….and so on.

Command comparison

Juniper commandMikroTik Command
> show ldp neighbormpls ldp neighbor print
> show mpls interfacempls ldp interface print
> show route table mpls.0mpls forwarding-table print
> show ldp databasempls remote-bindings print
> show ldp databasempls local-bindings print
> show mpls label usage label-rangempls print
> show ldp overviewmpls ldp print
# set interfaces ge-0/0/0 unit 0 family mpls
# set protocols mpls interface ge-0/0/0.0
# set protocols ldp interface ge-0/0/0.0
/mpls ldp interface
add interface=ether1
{ inherited from loopback }/mpls ldp
set enabled=yes lsr-id=10.1.1.3

Testing connectivity

MikroTik – mpls forwarding table and vrf routes

MikroTik – Ping PE2 through Juniper MPLS network

Juniper – mpls forwarding table and vrf routes

Juniper – Ping PE2 from Juniper MPLS network

Router configs

MPLS-PE-RouterOS-1

/interface bridge
 add name=lo0
 add name=lo1
 /interface wireless security-profiles
 set [ find default=yes ] supplicant-identity=MikroTik
 /routing bgp instance
 set default as=8675309
 /ip address
 add address=10.1.1.1/29 interface=ether1 network=10.1.1.0
 add address=192.168.1.1 interface=lo1 network=192.168.1.1
 add address=172.16.1.1 interface=lo0 network=172.16.1.1
 /ip dhcp-client
 add disabled=no interface=ether1
 /ip route vrf
 add export-route-targets=1.1.1.1:1 import-route-targets=1.1.1.1:1 interfaces=\
     lo1 route-distinguisher=1.1.1.1:1 routing-mark=vrf-1
 /mpls ldp
 set enabled=yes lsr-id=172.16.1.1 transport-address=172.16.1.1
 /mpls ldp interface
 add interface=ether1
 /routing bgp instance vrf
 add redistribute-connected=yes routing-mark=vrf-1
 /routing bgp peer
 add address-families=ip,vpnv4 name=peer1 remote-address=172.16.1.3 remote-as=\
     8675309 update-source=lo0
 /routing ospf network
 add area=backbone network=10.1.1.0/29
 add area=backbone network=172.16.1.1/32
 /system identity
 set name=MPLS-PE-RouterOS-1
 

MPLS-PE-RouterOS-2

/interface bridge
 add name=lo0
 add name=lo1
 /interface wireless security-profiles
 set [ find default=yes ] supplicant-identity=MikroTik
 /routing bgp instance
 set default as=8675309
 /ip address
 add address=10.1.4.2/29 interface=ether1 network=10.1.4.0
 add address=192.168.1.5 interface=lo1 network=192.168.1.5
 add address=172.16.1.5 interface=lo0 network=172.16.1.5
 /ip dhcp-client
 add disabled=no interface=ether1
 /ip route vrf
 add export-route-targets=1.1.1.1:1 import-route-targets=1.1.1.1:1 interfaces=lo1 route-distinguisher=1.1.1.1:1 routing-mark=vrf-1
 /mpls ldp
 set enabled=yes lsr-id=172.16.1.5 transport-address=172.16.1.5
 /mpls ldp interface
 add interface=ether1
 /routing bgp instance vrf
 add redistribute-connected=yes routing-mark=vrf-1
 /routing bgp peer
 add address-families=ip,vpnv4 name=peer1 remote-address=172.16.1.3 remote-as=8675309 update-source=lo0
 /routing ospf network
 add area=backbone network=10.1.4.0/29
 add area=backbone network=172.16.1.5/32
 /system identity
 set name=MPLS-PE-RouterOS-2

MPLS-P-JunOS-1

version 14.1R1.10;
 system {
     host-name MPLS-P-JunOS-1;
     root-authentication {
         encrypted-password "$1$kj9Pva8c$R0knN0l873H.UaBUUNYA00"; ## SECRET-DATA
     }
     syslog {
         user * {
             any emergency;
         }
         file messages {
             any notice;
             authorization info;
         }
         file interactive-commands {
             interactive-commands any;
         }
     }
 }
 interfaces {
     ge-0/0/0 {
         unit 0 {
             family inet {
                 address 10.1.1.2/29;
             }
             family mpls;
         }
     }
     ge-0/0/1 {
         unit 0 {
             family inet {
                 address 10.1.2.1/29;
             }
             family mpls;
         }
     }
     lo0 {
         unit 0 {
             family inet {
                 address 172.16.1.2/32;
             }
         }
         unit 1 {
             family inet {
                 address 192.168.1.2/32;
             }
         }
     }
 }
 routing-options {
     router-id 172.16.1.2;
     route-distinguisher-id 172.16.1.2;
     autonomous-system 8675309;
 }
 protocols {
     mpls {
         traffic-engineering mpls-forwarding;
         interface ge-0/0/0.0;
         interface ge-0/0/1.0;
     }
     bgp {
         group rr {
             type internal;
             local-address 172.16.1.2;
             family inet-vpn {
                 unicast;
             }
             neighbor 172.16.1.3 {
                 peer-as 8675309;
             }
         }
     }
     ospf {
         traffic-engineering;
         area 0.0.0.0 {
             interface ge-0/0/0.0;
             interface ge-0/0/1.0;
             interface lo0.0;
         }
     }
     ldp {
         interface ge-0/0/0.0;
         interface ge-0/0/1.0;
     }
 }
 routing-instances {
     vrf-1 {
         instance-type vrf;
         interface lo0.1;
         route-distinguisher 1.1.1.1:1;
         vrf-target target:1.1.1.1:1;
         vrf-table-label;
     }
 }

MPLS-P-JunOS-2

version 14.1R1.10;
 system {
     host-name MPLS-P-JunOS-2;
     root-authentication {
         encrypted-password "$1$g6tJMNPd$f35BMnnPgit/YLshrXd/L1"; ## SECRET-DATA
     }
     services {
         ssh;
     }
     syslog {
         user * {
             any emergency;
         }
         file messages {
             any notice;
             authorization info;
         }
         file interactive-commands {
             interactive-commands any;
         }
     }
 }
 interfaces {
     ge-0/0/0 {
         unit 0 {
             family inet {
                 address 10.1.2.2/29;
             }
             family mpls;
         }
     }
     ge-0/0/1 {
         unit 0 {
             family inet {
                 address 10.1.3.1/29;
             }
             family mpls;
         }
     }
     lo0 {
         unit 0 {
             family inet {
                 address 172.16.1.3/32;
             }
         }
         unit 1 {
             family inet {
                 address 192.168.1.3/32;
             }
         }
     }
 }
 routing-options {
     router-id 172.16.1.3;
     route-distinguisher-id 172.16.1.3;
     autonomous-system 8675309;
 }
 protocols {
     mpls {
         traffic-engineering mpls-forwarding;
         interface ge-0/0/0.0;
         interface ge-0/0/1.0;
     }
     bgp {
         group rr {
             type internal;
             local-address 172.16.1.3;
             family inet-vpn {
                 unicast;
             }
             cluster 1.1.1.1;
             neighbor 172.16.1.2 {
                 peer-as 8675309;
             }
             neighbor 172.16.1.1 {
                 peer-as 8675309;
             }
             neighbor 172.16.1.3 {
                 peer-as 8675309;
             }
             neighbor 172.16.1.4 {
                 peer-as 8675309;
             }
             neighbor 172.16.1.5 {
                 peer-as 8675309;
             }
         }
     }
     ospf {
         traffic-engineering;
         area 0.0.0.0 {
             interface ge-0/0/0.0;
             interface ge-0/0/1.0;
             interface lo0.0;
         }
     }
     ldp {
         interface ge-0/0/0.0;
         interface ge-0/0/1.0;
     }
 }
 policy-options {
     policy-statement import-vrf1 {
         term import-term-connected {
             from protocol direct;
             then accept;
         }
         term term-reject {
             then reject;
         }
     }
 }
 routing-instances {
     vrf-1 {
         instance-type vrf;
         interface lo0.1;
         route-distinguisher 1.1.1.1:1;
         vrf-target target:1.1.1.1:1;
         vrf-table-label;
     }
 }

MPLS-P-JunOS-3

version 14.1R1.10;
 system {
     host-name MPLS-P-JunOS-3;
     root-authentication {
         encrypted-password "$1$kj9Pva8c$R0knN0l873H.UaBUUNYA00"; ## SECRET-DATA
     }
     syslog {
         user * {
             any emergency;
         }
         file messages {
             any notice;
             authorization info;
         }
         file interactive-commands {
             interactive-commands any;
         }
     }
 }
 interfaces {
     ge-0/0/0 {
         unit 0 {
             family inet {
                 address 10.1.3.2/29;
             }
             family mpls;
         }
     }
     ge-0/0/1 {
         unit 0 {
             family inet {
                 address 10.1.4.1/29;
             }
             family mpls;
         }
     }
     lo0 {
         unit 0 {
             family inet {
                 address 172.16.1.4/32;
             }
         }
         unit 1 {
             family inet {
                 address 192.168.1.4/32;
             }
         }
     }
 }
 routing-options {
     router-id 172.16.1.4;
     route-distinguisher-id 172.16.1.4;
     autonomous-system 8675309;
 }
 protocols {
     mpls {
         traffic-engineering mpls-forwarding;
         interface ge-0/0/0.0;
         interface ge-0/0/1.0;
     }
     bgp {
         group rr {
             type internal;
             local-address 172.16.1.4;
             family inet-vpn {
                 unicast;
             }
             neighbor 172.16.1.3 {
                 peer-as 8675309;
             }
         }
     }
     ospf {
         traffic-engineering;
         area 0.0.0.0 {
             interface ge-0/0/0.0;
             interface ge-0/0/1.0;
             interface lo0.0;
         }
     }
     ldp {
         interface ge-0/0/0.0;
         interface ge-0/0/1.0;
     }
 }
 routing-instances {
     vrf-1 {
         instance-type vrf;
         interface lo0.1;
         route-distinguisher 1.1.1.1:1;
         vrf-target target:1.1.1.1:1;
         vrf-table-label;
     }
 }

Cisco to MikroTik – Switching and VLANs

About the Cisco to MikroTik series

One of the most difficult configuration challenges for MikroTik equipment seems to be switching and VLANs in the CRS series. Admittedly, the revamp of VLAN configuration for MikroTik CRS switches in early 2018 made things a lot easier. But, sometimes there is still confusion on how to configure VLANs and IP addresses in VLANs with MikroTik RouterOS operating on a switch.

This will only cover VLAN configuration for CRS 3xx series switches in RouterOS as SwitchOS is not nearly as common in operational deployments.

CRS 1xx/2xx series use an older style of configuration and seem to be on the way out so I’m not 100% sure whether or not i’ll write a similar guide on that series.

If you’ve been in networking for a while, you probably started with learning the Cisco CLI. Therefore, it is helpful to compare the commands if you want to implement a network with a MikroTik and Cisco switches.

This is the fourth post in a series that creates a Rosetta stone between IOS and RouterOS. Here are some of the others:

Click here for the first article in this series – “Cisco to MikroTik BGP command translation”
Click here for the second article in this series – “Cisco to MikroTik OSPF command translation”
Click here for the third article in the series – “Cisco to MikroTik MPLS command translation”

While many commands have almost the exact same information, others are as close as possible. Since there isn’t always an exact match, sometimes you may have to run two or three commands to get the information needed.

Hardware for testing

In the last article, we began using EVE-NG instead of GNS3 to emulate both Cisco IOS and RouterOS so we could compare the different commands and ensure the translation was as close as possible. However in switching, we still have to use real hardware at least in the realm of MikroTik – Cisco has IOSvL2 images that can be used in EVE-NG for switching.

Notes on hardware bridging in the CRS series

Bridging is a very confusing topic within the realm of MikroTik equipment. It is often associated with CPU forwarding and is generally seen as something to be avoided if at all possible.

There are a few reasons for this…

1. Within routers, bridging generally does rely on the CPU for forwarding and the throughput is limited to the size of the CPU.

2. In the previous generation of CRS configuration, bridging was not the best way to configure the switch – using the port master/slave option would trigger hardware forwarding.

After MikroTik revamped the switch config for VLANs in 2018 to utilize the bridge, it more closely resembles the style of configuration for Metro Ethernet Layer 2 as well as vendors like Juniper that use the ‘bridge-domain’ style of config.

Using the bridge for hardware offload of L2 traffic

Note the Hw. Offload verification under this bridge port in the CRS317

It is important to realize that bridging in the CRS, when used for VLAN configuration is actually using the switch ASIC to forward traffic and not the CPU.

In this instance, the bridge is merely used as a familiar configuration tool to tie ports and VLANs together but does in fact allow for the forwarding of traffic in hardware at wirespeed.

Cisco to MikroTik – command translation

Cisco commandMikroTik Command
interface FastEthernet5/0/47
switchport access vlan 100
switchport mode access
end
/interface bridge port
add bridge=bridge1 interface=sfp-sfpplus1 pvid=100
interface GigabitEthernet5/0/4
switchport trunk encapsulation dot1q
switchport trunk allowed vlan 200
switchport mode trunk
end
/interface bridge vlan
add bridge=bridge1 tagged=sfp-sfpplus1 vlan-ids=200
interface Vlan200
ip address 172.16.1.254 255.255.255.0
end
/interface vlan
add interface=bridge1 name=vlan200 vlan-id=200
/interface bridge vlan
add bridge=bridge1 tagged=sfp-sfpplus1,bridge1 vlan-ids=200
/ip address
add address=172.16.1.254/24 interface=vlan200 network=172.16.1.0
spanning-tree mode mst
/interface bridge
add fast-forward=no name=bridge1 priority=0 protocol-mode=mstp region-name=main vlan-filtering=yes
interface FastEthernet5/0/47
switchport access vlan 200
switchport mode access
spanning-tree portfast
end
interface bridge port set edge=yes-discover
interface GigabitEthernet5/0/4
switchport trunk encapsulation dot1q
switchport trunk allowed vlan 200
switchport mode trunk
channel-group 1 mode active
end

interface Port-channel1
switchport trunk encapsulation dot1q
switchport trunk allowed vlan 200
switchport mode trunk
end
interface bonding
add mode=802.3ad name=Po1 slaves=sfp-sfpplus1,sfp-sfpplus3 \
transmit-hash-policy=layer-2-and-3

/interface bridge vlan
add bridge=bridge1 tagged=Po1,bridge1 vlan-ids=200
show mac address-tableinterface bridge host print
show mac address-table vlan 200interface bridge host print where vid=200
show mac address-table interface Gi5/0/4interface bridge host print where interface=sfp-sfpplus1
show interfaces trunk
show vlan
interface bridge vlan print
show spanning-tree
interface bridge monitor
show etherchannel summaryinterface bonding print detail


Examples of the MikroTik RouterOS commands from the table above



Untagged switch port

This command will create an untagged or “access” switch port on VLAN 100

[admin@MikroTik] > /interface bridge port add bridge=bridge1 interface=sfp-sfpplus1 pvid=100

Tagged switch port

This command will create a tagged or “trunk” switch port on VLAN 200. Additional VLANs can be tagged on a port by using the same syntax and adding a new VLAN number.

[admin@MikroTik] > /interface bridge vlan add bridge=bridge1 tagged=sfp-sfpplus1 vlan-ids=200

Layer 3 VLAN Interface

Similar to a Cisco SVI (but dependent on the CPU and not an ASIC) this command will create a layer 3 interface on VLAN 200

[admin@MikroTik] >

/interface vlan add interface=bridge1 name=vlan200 vlan-id=200
/interface bridge vlan
add bridge=bridge1 tagged=sfp-sfpplus1,bridge1 vlan-ids=200
/ip address
add address=172.16.1.254/24 interface=vlan200 network=172.16.1.0

Multiple STP

This command will set the bridge loop prevention protocol to Multiple Spanning Tree. As a general observation, MSTP tends to be the most compatible across vendors as some vendors like Cisco use a proprietary version of Rapid STP.

[admin@MikroTik] > /interface bridge add fast-forward=no name=bridge1 priority=0 protocol-mode=mstp region-name=main vlan-filtering=yes

STP Edge port

This is referred to as “portfast” in the Cisco world and allows a port facing a device that isn’t a bridge or a switch to transition immediately to forwarding but if it detects a BPDU, it will revert to normal STP operation. (this is the difference between edge=yes and edge=yes-discover)

[admin@MikroTik] > /interface bridge port set edge=yes-discover

LACP Bonding

This command will create a bonding interface which is similar to a Port Channel in Cisco’s switches. Two or more physical interfaces can be selected to bond together and then the 802.3ad mode is selected which is LACP. You can also select the hashing policy and ideally it should match what the device on the other end is set for to get the best distribution of traffic and avoid interoperability issues.

[admin@MikroTik] >
/interface bonding
add mode=802.3ad name=Po1 slaves=sfp-sfpplus1,sfp-sfpplus3 \
transmit-hash-policy=layer-2-and-3

/interface bridge vlan
add bridge=bridge1 tagged=Po1,bridge1 vlan-ids=200

View the MAC table of the switch

This print command will show all learned MAC addresses and associated VLANs in the CAM table of the switch

[admin@IPA-LAB-CRS-317] > interface bridge host print
Flags: X - disabled, I - invalid, D - dynamic, L - local, E - external 
 #       MAC-ADDRESS        VID ON-INTERFACE      BRIDGE     AGE                 
 0   DL  64:D1:54:F0:0E:46      Po1               bridge1   
 1   DL  64:D1:54:F0:0E:47      sfp-sfpplus2      bridge1   
 2   D E 04:FE:7F:5C:5D:9C    1 Po1               bridge1   
 3   DL  64:D1:54:F0:0E:46    1 Po1               bridge1   
 4   D   00:0C:42:B2:A6:3D  200 sfp-sfpplus2      bridge1    52s                 
 5   D E 4C:5E:0C:23:DF:50  200 Po1               bridge1   
 6   DL  64:D1:54:F0:0E:46  200 bridge1           bridge1   
 7   DL  64:D1:54:F0:0E:47  200 sfp-sfpplus2      bridge1

View the MAC table for VLAN 200 in the switch

This print command will show all learned MAC addresses in VLAN 200.

[admin@IPA-LAB-CRS-317] > interface bridge host print where vid=200
Flags: X - disabled, I - invalid, D - dynamic, L - local, E - external 
 #       MAC-ADDRESS        VID ON-INTERFACE           BRIDGE           AGE                 
 0   D   00:0C:42:B2:A6:3D  200 sfp-sfpplus2           bridge1          51s                 
 1   D E 4C:5E:0C:23:DF:50  200 Po1                    bridge1         
 2   DL  64:D1:54:F0:0E:46  200 bridge1                bridge1         
 3   DL  64:D1:54:F0:0E:47  200 sfp-sfpplus2           bridge1

View the MAC table for bonding interface Po1 in the switch

This print command will show all learned MAC addresses on port Po1.

[admin@IPA-LAB-CRS-317] > interface bridge host print where interface=Po1         
Flags: X - disabled, I - invalid, D - dynamic, L - local, E - external 
 #       MAC-ADDRESS        VID ON-INTERFACE           BRIDGE           AGE                 
 0   DL  64:D1:54:F0:0E:46      Po1                    bridge1         
 1   D E 04:FE:7F:5C:5D:9C    1 Po1                    bridge1         
 2   DL  64:D1:54:F0:0E:46    1 Po1                    bridge1         
 3   D E 4C:5E:0C:23:DF:50  200 Po1                    bridge1

View the current VLANs configured in the switch 

The bridge vlan print command will show all configured VLANs in the switch.

[admin@IPA-LAB-CRS-317] > interface bridge vlan print
Flags: X - disabled, D - dynamic 
 #   BRIDGE              VLAN-IDS  CURRENT-TAGGED              CURRENT-UNTAGGED             
 0   bridge1             200       bridge1                     sfp-sfpplus2                 
                                   Po1                        
 1 D bridge1             1                                     bridge1                      
                                                               Po1

View Bridge Spanning Tree information 

The bridge monitor command will show the configuration details and current state of spanning tree including the root bridge and root port

[admin@IPA-LAB-CRS-317] >  interface bridge monitor
numbers: 0
                    state: enabled
      current-mac-address: 64:D1:54:F0:0E:46
              root-bridge: yes
           root-bridge-id: 0.64:D1:54:F0:0E:46
  regional-root-bridge-id: 0.64:D1:54:F0:0E:46
           root-path-cost: 0
                root-port: none
               port-count: 2
    designated-port-count: 2
        mst-config-digest: ac36177f50283cd4b83821d8ab26de62

LACP Bonding information

This command will show the details of the LACP configuration and whether the bonding interface is running which indicates a valid LACP neighbor.

[admin@IPA-LAB-CRS-317] > interface bonding print detail
Flags: X - disabled, R - running 
 0  R name="Po1" mtu=1500 mac-address=64:D1:54:F0:0E:46 arp=enabled arp-timeout=auto 
      slaves=sfp-sfpplus1,sfp-sfpplus3 mode=802.3ad primary=none link-monitoring=mii 
      arp-interval=100ms arp-ip-targets="" mii-interval=100ms down-delay=0ms up-delay=0ms 
      lacp-rate=30secs transmit-hash-policy=layer-2-and-3 min-links=0