How to Build a Layer 3 MPLS VPN in Cisco Modeling Labs

Overview

Cisco Modeling Labs (CML) can be used to build a Layer 3 MPLS VPN using PE routers, P routers, MP-BGP, LDP, and customer edge routers. This lab demonstrates end-to-end connectivity between customer sites while maintaining route separation through VRFs. You can download the lab.yaml file and router configuration files to get started with here.

Scenario

Customer A and Customer B both have 2 sites in different cities. Both customers have requested private Layer 3 VPNs between their respective offices from their service provider. Neither customer will be able to see each other’s routes, despite connecting to the same equipment at the service provider.

Method

To accomplish this we will first construct a service provider MPLS core. I’ve made a separate post on how to do this since it is pretty involved. You can find that post here.

The provider edge (PE) routers will participate in routing with the customer edge (CE) routers using VRFs to keep the routes separate. They will then use MP-BGP to share the customers routes with each other via VPNv4. The customer routes and traffic will transit the core via MPLS, and the provider (P) routers will not see customer routes, only transport labels. The end result is that CE-1A and CE-2A can communicate with each other, and CE-1B and CE-2B can as well. Customer A’s routers will not be able to communicate with Customer B’s routers or see their routes.

Equipment

  • Customer Edge Routers (iOSv)
    • CE-1A
    • CE-1B
    • CE-2A
    • CE-2B
  • Provider Edge Routers (XRd)
    • PE-1
    • PE-2
  • Provider Core Routers (XRd)
    • P1
    • P2

Step 1 – Adding the Customer Routers

We will add four IOSv images to the topology and connect them to the provider core. CE-1A and CE-1B will connect to PE-1 and CE-2A and CE-2B will connect to PE-2. We will configure them with IP’s on the interfaces connecting to the service provider as well as loopbacks for easier identification. I’m using /32s for the point-to point links. Because the routes will be isolated from the other customer as well as the service provider core, it is safe to use overlapping loopback addresses as long as they are unique within the VRF. Here’s an example on CE-1A:

conf t
!
hostname CE-1A
!
ip domain-name nickdoeslabs.com
!
interface gigabitEthernet0/0
  no shutdown
  ip address 10.0.0.1 255.255.255.252
  description link to PE-1 
!
interface Loopback 0
  no shutdown
  ip address 1.1.1.1 255.255.255.255
!
end
! 
wr mem
RouterLoopbackGi0/0Next Hop
CE-1A1.1.1.1 /3210.0.0.1 /3010.0.0.2
CE-1B2.2.2.2 /3210.0.0.5 /3010.0.0.6
CE-2A1.1.1.1 /3210.0.0.9 /3010.0.0.10
CE-2B2.2.2.2 /3210.0.0.13 /3010.0.0.14

The resulting topology looks like this:

Step 2 – Basic Connectivity to the Provider Edge Routers

First we will assign the IP addresses on the links to the customer routers. These will be assigned as follows:

RouterG0/1 IPG0/3 IP
PE-110.0.0.2 /3010.0.0.6 /30
PE-210.0.0.10 /3010.0.0.14 /30

We will also create our VRFs and assign the appropriate interfaces to them. VRFs will provide a virtual routing table, keeping customer routes and traffic isolated from other customers or the core. This is analogous to the VLAN at layer 2. Our VRF assignments will be:

RouterG0/1 VRFG0/3 VRF
PE-1CUSTOMER_ACUSTOMER_B
PE-2CUSTOMER_ACUSTOMER_B

For each router we will enter a config like this to make this happen:

!!!! PE-1 !!!!!
config
!
VRF CUSTOMER_A
VRF CUSTOMER_B
commit
!
int gi0/0/0/1
  ip address 10.0.0.2 255.255.255.252
  no shutdown
  vrf CUSTOMER_A
!
int gi0/0/0/3
  ip address 10.0.0.6 255.255.255.252
  no shutdown
  vrf CUSTOMER_B
!
commit
!!!! PE-2 !!!!
config
!
VRF CUSTOMER_A
VRF CUSTOMER_B
commit
!
int gi0/0/0/1
  ip address 10.0.0.10 255.255.255.252
  no shutdown
  vrf CUSTOMER_A
!
int gi0/0/0/3
  ip address 10.0.0.14 255.255.255.252
  no shutdown
  vrf CUSTOMER_B
!
commit

At this point both PE routers can ping their directly connected customer routers.

This is a good time to take note of the isolation that VRF’s provide. We can only ping each customer within it’s respective VRF. Pinging between VRF’s will fail. In this example, because the 10.0.0.1 route belongs to the CUSTOMER_A VRF, we cannot ping it from the CUSTOMER_B VRF.

You can also see that we have different routing tables.

Step 3 – Configuring OSPF Between the Customer and Provider Edge Routers

Next we need a way for the customer to share its routes to the service provider. While this can be done with any routing protocol, because this is a VPN I’m going to use an IGP (OSPF). This will allow the routes to flow across the VPN without ever leaving OSPF from the customers point of view.

The routers are backbone routers so they will be in area 0. The only network we are advertising is our loopback and the interface connected to the service provider. The router IDs have to be unique, unlike the loopbacks because OSPF will flag them as duplicate router IDs even though they are in separate processes. This is because OSPF uses the router-id to form the neighborship and one neighbor can’t exist in more than one place.

!!!CE-1A!!!
!
conf t
! 
router ospf 1
  router-id 10.10.10.10
  network 1.1.1.1 0.0.0.0 area 0
  network 10.0.0.0 0.0.0.3 area 0
  passive-interface Lo0
!
end
!
wr mem
!!!CE-1B!!!
!
conf t
! 
router ospf 1
  router-id 11.11.11.11
  network 1.1.1.1 0.0.0.0 area 0
  network 10.0.0.4 0.0.0.3 area 0
  passive-interface Lo0
!
end
!
wr mem
!!!CE-2A!!!
!
conf t
! 
router ospf 1
  router-id 12.12.12.12
  network 2.2.2.2 0.0.0.0 area 0
  network 10.0.0.8 0.0.0.3 area 0
  passive-interface Lo0
!
end
!
wr mem
!!!CE-2B!!!
!
conf t
! 
router ospf 1
  router-id 13.13.13.13
  network 2.2.2.2 0.0.0.0 area 0
  network 10.0.0.12 0.0.0.3 area 0
  passive-interface Lo0
!
end
!
wr mem

Next we will configure the provider edge routers. For these we will need to configure a separate process within each customer’s VRF to keep the processes separate. The PE routers can use the same Router ID to identify themselves for each process.

!!! PE-1 !!!
config
!
router ospf CUSTOMER_A
  router-id 1.1.1.1
  vrf CUSTOMER_A 
  area 0
  int gi0/0/0/1
!!
router ospf CUSTOMER_B
  router-id 1.1.1.1
  vrf CUSTOMER_B
  area 0 
  int gi0/0/0/3
!!
commit
end
!!! PE-2 !!!
config
!
router ospf CUSTOMER_A
  router-id 3.3.3.3
  vrf CUSTOMER_A 
  area 0
  int gi0/0/0/1
!!
router ospf CUSTOMER_B
  router-id 3.3.3.3
  vrf CUSTOMER_B
  area 0 
  int gi0/0/0/3
!!
commit
end

At this point we can run “show ip route vrf CUSTOMER_*” and confirm that we have learned the customer’s loopback routes via ospf in each VRF.

Step 3 – Configuring BGP Between the Provider Edge Routers

At this point both PE routers know about the customer routes through their directly connected OSPF neighbor (CE Router). Our goal is to get PE-1 and PE-1 to exchange those routes with each other. BGP is perfect for two huge reasons. First, BGP allows remote peering which means we can peer the two PE routers even though they are in different cities, or even countries. As long as we have routed connectivity between them (we do through IS-IS) we can make them BGP neighbors. More importantly, BGP is the only routing protocol that supports VPNV4 (via MP-BGP) which will allow us to keep our customer’s traffic separate from each other while it passes through the provider core.

We’ll start by configuring the peering between PE-1 and PE-2 with the following commands:

!!! PE-1 !!!
config
!
router bgp 500
  address-family vpnv4 unicast
  neighbor 3.3.3.3 
    address-family vpnv4 unicast
    remote-as 500
    update-source Lo0
!
commit
!
end
!!! PE-2 !!!
config
!
router bgp 500
  address-family vpnv4 unicast
  neighbor 1.1.1.1 
    address-family vpnv4 unicast
    remote-as 500
    update-source Lo0
!
commit
!
end

Once this is done we can verify the neighborship using “show bgp vpnv4 unicast neighbors brief”.

Now we just need to pass the customer routes from the OSPF process we share with the customer into our internal BGP VPNV4 process and vice versa. But before we do that we need to add unique route distinguishers and route targets to our VRFs.

Step 4 – Adding Route Distinguishers and Route Targets

Route distinguishers and route targets are components of VPNv4 which help keep customer routes and traffic segregated. The route distinguisher is a unique label which is added to customer routes to distinguish them from each other. This allows for what we call overlapping routes, customers using the same IPs. Because the IP is encapsulated in a route distinguisher, it doesn’t cause conflicts. Route targets tell the PE router which VRF to import the customer route to. These topics are much more intricate than this so I’ve gone into more detail in this post: Provider Networking – Route Distinguishers vs Route Targets.

To configure the route distinguishers and route targets we will use the following commands on both PE routers. Import route-target tells the router which routes to bring in to the VRF and export route target tells the router what to label them as they leave the VRF. Also note that we are using address-family ipv4 since the customer routes getting put in the VRF will be ipv4, not to be confused with vpnv4 which we are using to transport them.

config
!
vrf CUSTOMER_A
 rd 500:1
 address-family ipv4 unicast
  import route-target
   100:100
  !
  export route-target
   100:100
  !
!
vrf CUSTOMER_B
 rd 500:2
 address-family ipv4 unicast 
  import route-target
   200:200
  !
  export route-target
   200:200
  !
!
commit
!
end
VRF NameRoute DistinguisherRoute Target
CUSTOMER_A500:1100:100
CUSTOMER_B500:2200:200

Step 5 – Redistributing Routes

This final part is pretty straightforward. We have 2 routing protocols running. OSPF knows the path to each customer router but not the path through the provider network. BGP knows the path through the provider network but not to the customer routers. We are going to redistribute routes from each OSPF process into BGP, separating them by VRF. We are also going to do the reverse, and redistribute routes from BGP into OSPF. Running these commands on both routers will accomplish this.

config
router bgp 500
  vrf CUSTOMER_A
    address-family ipv4 unicast
      redistribute ospf CUSTOMER_A
!
  vrf CUSTOMER_B
    address-family ipv4 unicast
      redistribute ospf CUSTOMER_B
!
router ospf CUSTOMER_A
  address-family ipv4 unicast
    vrf CUSTOMER_A
      redistribute bgp 500
!
router ospf CUSTOMER_B
  address-family ipv4 unicast
    vrf CUSTOMER_B  
     redistribute bgp 500
!
commit
end

At this point we can verify that our PE routers now see the routes from the other side of the VPN by running show ip route vrf *.

As we can see each PE router has learned the directly connected customer loopback through OSPF, and the remote customer loopback (and interface subnet) through BGP. The routes have been segregated into separate routing tables that are private to each VRF.

Step 6 – Verification

First we are going to go to each CE router and make sure we can ping the remote CE router through the VPN.

Pings are successful between the CE routers across the VPN. We can also check the routing tables on each CE router and we will see the remote routes marked as OSPF Inter Area since they were redistributed into OSPF.

And that’s it! We have successfully configured private layer 3 VPN services for 2 customers and verified that they are working properly. We used VPNv4 (via MP-BGP), OSPF, VRFs, Route Distinguishers, and Route Targets to accomplish this, on top of our existing core that is running MPLS-LDP and IS-IS.

If you’d like to download the lab.yaml file for this lab as well as the router configurations, they are available for free here. Want notifications when new labs are released? Join the newsletter.

Leave a Comment