Simple Juniper MPLS Core w/ L3VPN (Part 1)

Introduction

Setting up a simple MPLS core using virtual SRX’s is simple and only limited by the hardware which you run the virtual machines (other limitations exist for MPLS using vSRX’s including not being able to run Layer 2 services such as VPLS and L2circuts).  Using these virtual machines, we can create a complete MPLS core and test things such as Label Distribution Protocol (LDP), Label Switched Paths (LSP), and Resource Reservation Protocol (RSVP).  Other topics such as operation of allocating labels and creating things like LSPs will be in another post so at this time, we will  keep things basic.

Topology

For the topology, I am using a lab of virtualized Juniper vSRX’s running in packet mode (default mode is flow mode).  Again, to keep things simple in this topology, we will be utilizing a few routers performing the following roles:

  • Provider Edge – PE-R1, PE-R2, PE-R3, and PE-R4 will be configured as Provider Edge routers connecting to the service provider network.  This will perform the MP-BGP peering to the Customer Edge routers and other Provider Edge routers.
  • Provider – These routers will perform the core routing and exchanging/managing labels for the core network.
  • Customer Edge – These routers will act as the customer routers that connect to the service provider network.  These will perform BGP peering with the Provider Edge routers and advertise connected routes into the network for testing.

Juniper MPLS Diagram

Please refer to the diagram (and subsequent configurations) for the IP addressing of transit and loopback interfaces for the core network.  Once we get into the configuration of the customer devices and provider edge devices, another diagram will be provided.

Configure Interfaces for Core Network

The first thing we will want to do is configure the interfaces with the appropriate ip addresses (for both transit interfaces and loopbacks) as well as enabling MPLS for each interface that connects to the core and LDP.   Once we do this, we can test a few links and perform a simple ping to see if we get a response back from the other side.

PE-R1

set interface loopback0 unit 0 family inet address 100.1.1.1/32
set interfaces ge-0/0/0 unit 0 family inet address 10.0.0.1/30
set interfaces ge-0/0/0 unit 0 family mpls
set interfaces ge-0/0/1 unit 0 family inet address 10.0.0.5/30
set interfaces ge-0/0/1 unit 0 family mpls
set interfaces ge-0/0/2 unit 0 family inet address 10.0.0.9/30
set interfaces ge-0/0/2 unit 0 family mpls
set interfaces ge-0/0/3 unit 16 family inet address 172.16.1.1/30
set interfaces ge-0/0/3 unit 17 family inet address 172.17.1.1/30

PE-R2

set interface loopback0 unit 0 family inet address 100.1.1.2/32
set interfaces ge-0/0/0 unit 0 family inet address 10.0.0.10/30
set interfaces ge-0/0/0 unit 0 family mpls
set interfaces ge-0/0/1 unit 0 family inet address 10.0.0.13/30
set interfaces ge-0/0/1 unit 0 family mpls
set interfaces ge-0/0/2 unit 0 family inet address 10.0.0.17/30
set interfaces ge-0/0/2 unit 0 family mpls

PE-R3

set interface loopback0 unit 0 family inet address 100.1.1.5/32
set interfaces ge-0/0/0 unit 0 family inet address 10.0.0.26/30
set interfaces ge-0/0/0 unit 0 family mpls
set interfaces ge-0/0/1 unit 0 family inet address 10.0.0.34/30
set interfaces ge-0/0/1 unit 0 family mpls
set interfaces ge-0/0/2 unit 0 family inet address 10.0.0.41/30
set interfaces ge-0/0/2 unit 0 family mpls
set interfaces ge-0/0/3 unit 16 family inet address 172.16.2.1/30
set interfaces ge-0/0/3 unit 17 family inet address 172.17.2.1/30

PE-R4

set interface loopback0 unit 0 family inet address 100.1.1.6/32
set interfaces ge-0/0/0 unit 0 family inet address 10.0.0.38/30
set interfaces ge-0/0/0 unit 0 family mpls
set interfaces ge-0/0/1 unit 0 family inet address 10.0.0.30/30
set interfaces ge-0/0/1 unit 0 family mpls
set interfaces ge-0/0/2 unit 0 family inet address 10.0.0.42/30
set interfaces ge-0/0/2 unit 0 family mpls

P-R1

set interface loopback0 unit 0 family inet address 100.1.1.3/32
set interfaces ge-0/0/0 unit 0 family inet address 10.0.0.2/30
set interfaces ge-0/0/0 unit 0 family mpls
set interfaces ge-0/0/1 unit 0 family inet address 10.0.0.14/30
set interfaces ge-0/0/1 unit 0 family mpls
set interfaces ge-0/0/2 unit 0 family inet address 10.0.0.21/30
set interfaces ge-0/0/2 unit 0 family mpls
set interfaces ge-0/0/3 unit 0 family inet address 10.0.0.29/30
set interfaces ge-0/0/3 unit 0 family mpls
set interfaces ge-0/0/4 unit 0 family inet address 10.0.0.25/30
set interfaces ge-0/0/4 unit 0 family mpls

P-R2

set interface loopback0 unit 0 family inet address 100.1.1.4/32
set interfaces ge-0/0/0 unit 0 family inet address 10.0.0.18/30
set interfaces ge-0/0/0 unit 0 family mpls
set interfaces ge-0/0/1 unit 0 family inet address 10.0.0.6/30
set interfaces ge-0/0/1 unit 0 family mpls
set interfaces ge-0/0/2 unit 0 family inet address 10.0.0.22/30
set interfaces ge-0/0/2 unit 0 family mpls
set interfaces ge-0/0/3 unit 0 family inet address 10.0.0.33/30
set interfaces ge-0/0/3 unit 0 family mpls
set interfaces ge-0/0/4 unit 0 family inet address 10.0.0.37/30
set interfaces ge-0/0/4 unit 0 family mpls

Now that we have the core devices configured with their transit and loopback interfaces, we will take a look at the ARP tables for both P-R1 and P-R2 (since they are the transit routers in the topology we should see complete ARP entries for each of the five interfaces):

root@P-R1> show arp
MAC Address Address Name Interface Flags
00:0c:29:eb:5a:a4 10.0.0.1 10.0.0.1 ge-0/0/0.0 none
00:0c:29:b8:e5:0a 10.0.0.13 10.0.0.13 ge-0/0/1.0 none
00:0c:29:55:e6:83 10.0.0.22 10.0.0.22 ge-0/0/2.0 none
00:0c:29:23:3f:c2 10.0.0.26 10.0.0.26 ge-0/0/4.0 none
00:0c:29:af:f1:b0 10.0.0.30 10.0.0.30 ge-0/0/3.0 none
<output omitted for brevity>
root@P-R2> show arp
MAC Address Address Name Interface Flags
00:0c:29:eb:5a:ae 10.0.0.5 10.0.0.5 ge-0/0/1.0 none
00:0c:29:b8:e5:14 10.0.0.17 10.0.0.17 ge-0/0/0.0 none
00:0c:29:67:4d:0a 10.0.0.21 10.0.0.21 ge-0/0/2.0 none
00:0c:29:23:3f:cc 10.0.0.34 10.0.0.34 ge-0/0/3.0 none
00:0c:29:af:f1:a6 10.0.0.38 10.0.0.38 ge-0/0/4.0 none
<output omitted for brevity>

Configure Open Shortest Path First (OSPF)

Now that we have the interfaces connected and reachable for each neighbor, we need to enable OSPF to perform routing in the core.  This is also a very simple process to both implement and test as we are going to enable interface to participate in OSPF while putting any management interfaces into passive mode.  First, we will enable the OSPF process on the PE-R1, PE-R2, PE-R3, and PE-R4 routers:

set protocols ospf area 0.0.0.0 interface all
set protocols ospf area 0.0.0.0 interface ge-0/0/3.0 passive
set protocols ospf area 0.0.0.0 interface ge-0/0/4.0 passive

Next, we will enable OSPF on P-R1 and P-R2:

set protocols ospf area 0.0.0.0 interace all
set protocols ospf area 0.0.0.0 interface ge-0/0/5.0 passive

Now that OSPF have been enabled, we can check the OSPF neighbor database and check the routing table for OSPF routes.  Once OSPF has converged, we should see transit addresses and each routers loopback addresses in the inet.0 table:

root@P-R1> show ospf neighbor
Address Interface State ID Pri Dead
10.0.0.1 ge-0/0/0.0 Full 100.1.1.1 128 33
10.0.0.13 ge-0/0/1.0 Full 100.1.1.2 128 38
10.0.0.22 ge-0/0/2.0 Full 100.1.1.4 128 37
10.0.0.30 ge-0/0/3.0 Full 100.1.1.6 128 30
10.0.0.26 ge-0/0/4.0 Full 100.1.1.5 128 36

root@P-R1> show route table inet.0 protocol ospf

inet.0: 27 destinations, 27 routes (27 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

<output omitted for brevity>
10.0.0.4/30 *[OSPF/10] 00:26:47, metric 2
 to 10.0.0.1 via ge-0/0/0.0
 > to 10.0.0.22 via ge-0/0/2.0
10.0.0.36/30 *[OSPF/10] 00:27:00, metric 2
 > to 10.0.0.22 via ge-0/0/2.0
100.1.1.1/32 *[OSPF/10] 00:26:47, metric 1
 > to 10.0.0.1 via ge-0/0/0.0
100.1.1.2/32 *[OSPF/10] 00:27:00, metric 1
 > to 10.0.0.13 via ge-0/0/1.0
<output omitted for brevity>
root@P-R2> show ospf neighbor
Address Interface State ID Pri Dead
10.0.0.17 ge-0/0/0.0 Full 100.1.1.2 128 34
10.0.0.5 ge-0/0/1.0 Full 100.1.1.1 128 32
10.0.0.21 ge-0/0/2.0 Full 100.1.1.3 128 31
10.0.0.34 ge-0/0/3.0 Full 100.1.1.5 128 33
10.0.0.38 ge-0/0/4.0 Full 100.1.1.6 128 33

root@P-R2> show route table inet.0 protocol ospf

inet.0: 27 destinations, 27 routes (27 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

<output omitted for brevity>
10.0.0.24/30 *[OSPF/10] 00:28:00, metric 2
 to 10.0.0.21 via ge-0/0/2.0
 > to 10.0.0.34 via ge-0/0/3.0
10.0.0.28/30 *[OSPF/10] 00:28:00, metric 2
 > to 10.0.0.21 via ge-0/0/2.0
 to 10.0.0.38 via ge-0/0/4.0
100.1.1.1/32 *[OSPF/10] 00:28:00, metric 1
 > to 10.0.0.5 via ge-0/0/1.0
100.1.1.2/32 *[OSPF/10] 01:09:50, metric 1
 > to 10.0.0.17 via ge-0/0/0.0
<output omitted for brevity>

Enabling MPLS and LDP

Now that we have OSPF completely converged, we can move on to enabling MPLS and LDP to complete the basic setup of our MPLS core network.  Just like OSPF, a simple setup is simply defining the interfaces that will participate in each protocol.  When you are configuring these protocols, do not get overwhelmed by the shear number of configuration options that are available for each protocol.  Many of the options available are for advanced topics and not really relevant to us right now.  First, let’s configure MPLS and LDP for each of our provider edge routers:

set protocols mpls interface all
set protocols mpls interface ge-0/0/3.0 disable
set protocols mpls interface ge-0/0/4.0 disable
set protocols ldp interface all
set protocols ldp interface ge-0/0/3.0 disable
set protocols ldp interface ge-0/0/4.0 disable

As noted prior, we are enabling MPLS and LDP for all interfaces and then disabling the functionality on interfaces connecting to customer edge devices and our management interfaces.  Let’s configure the two provider routers:

set protocols mpls interface all
set protocols mpls interface ge-0/0/5.0 disable
set protocols ldp interface all
set protocols ldp interface ge-0/0/5.0 disable

Now, to confirm that MPLS is working as expected, we can check to make sure all the appropriate interfaces are in the UP state:

root@P-R1> show mpls interface
Interface State Administrative groups (x: extended)
ge-0/0/0.0 Up <none>
ge-0/0/1.0 Up <none>
ge-0/0/2.0 Up <none>
ge-0/0/3.0 Up <none>
ge-0/0/4.0 Up <none>
root@P-R2> show mpls interface
Interface State Administrative groups (x: extended)
ge-0/0/0.0 Up <none>
ge-0/0/1.0 Up <none>
ge-0/0/2.0 Up <none>
ge-0/0/3.0 Up <none>
ge-0/0/4.0 Up <none>

Since everything looks good there, let make sure that the provider routers are exchanging labels with not only each other, but the four provider edge routers:

root@P-R1> show ldp neighbor
Address Interface Label space ID Hold time
10.0.0.1 ge-0/0/0.0 100.1.1.1:0 13
10.0.0.13 ge-0/0/1.0 100.1.1.2:0 10
10.0.0.22 ge-0/0/2.0 100.1.1.4:0 11
10.0.0.30 ge-0/0/3.0 100.1.1.6:0 14
10.0.0.26 ge-0/0/4.0 100.1.1.5:0 13
root@P-R2> show ldp neighbor
Address Interface Label space ID Hold time
10.0.0.17 ge-0/0/0.0 100.1.1.2:0 10
10.0.0.5 ge-0/0/1.0 100.1.1.1:0 14
10.0.0.21 ge-0/0/2.0 100.1.1.3:0 12
10.0.0.34 ge-0/0/3.0 100.1.1.5:0 13
10.0.0.38 ge-0/0/4.0 100.1.1.6:0 11

Now that the LDP protocol is working correctly, we now have a fully functioning (although very basic) MPLS topology.  If you are curious and would like to see the labels that are being exchanged between each neighbor, you can run the command show ldp database which will give you the output below:

root@P-R1> show ldp database
Input label database, 100.1.1.3:0--100.1.1.1:0
 Label Prefix
 3 100.1.1.1/32
 299840 100.1.1.2/32
 299776 100.1.1.3/32
 299792 100.1.1.4/32
 299808 100.1.1.5/32
 299824 100.1.1.6/32
Output label database, 100.1.1.3:0--100.1.1.1:0
 Label Prefix
 299776 100.1.1.1/32
 299840 100.1.1.2/32
 3 100.1.1.3/32
 299792 100.1.1.4/32
 299808 100.1.1.5/32
 299824 100.1.1.6/32
<output omitted for brevity>

In this output, we see that from the router P-R1’s perspective, it has successfully created labels for PE-R1 to use to get to the prefixes it knows (I.E. for PE-R1 to get to 100.1.1.6/32 it should PUSH the label 299824 when seeing packets to P-R1).  On the other side, if P-R1 wants to send packets to 100.1.1.1/32, it should PUSH the label 299776.  If you would like to know more about label allocation in JunOS, please refer to the MPLS Label Allocation page at juniper.net.

Conclusion

As you can see, the basic configuration of an MPLS core is fairly simple and straight-forward if you are familiar with the basics of Layer2/Layer 3 topologies and basic routing protocols.  In the next section, we will go further and make our connections to the customer edge devices, create a routing instance for each customer (L3VPN) and show how we can perform routing across the core.

Troy Perkins

4 comments

  1. Nice lab you got there 🙂

    Just a quick question, how did you connect PE-R1 to CE-A-R1 and CE-B-R1 to the same interface ge-0/0/3 ? IS there a switch between CPE and PE ? and if so can you post the config ?

    Regards
    Sean

    1. Sean,

      Thanks for the comment! You can either have a switch in between the devices or you can mess around with using the subinterfaces (interface unit numbers) and a shared ESX virtual network that all the devices use. Just an FYI, I will be redirecting this domain to my permanent domain packetsandflows.cloud so please make sure to start using that URL if you wish to comment on other posts.

      Troy

Leave a Reply

Your email address will not be published. Required fields are marked *