Simple Cisco MPLS Core w/ L3VPN (Part 2)

Introduction

In the last post, Simple Cisco MPLS Core w/ L3VPN (Part 1), we created a simple MPLS core using Cisco CSR1000v routers which was similar to the Simple Juniper MPLS Core w/ L3VPN (Part 1).  Now that the basics are in working order (remember, the simple core does not do anything special such as resiliency), let’s move on to the next step which is to create a Layer 3 VPN (L3VPN) for our customer.  This will allow routing between R7 (CE-A) and R8 (CE-A)’s loopback address over the MPLS core.

Provider Edge Customer Virtual Route Forwarder

Just like the Juniper scenario, when you make a connection between the Customer Edge (CE) and Provider Edge (PE) router, you use an external Border Gateway Protocol (eBGP) connection to exchange routes.  This will allow the CE router to advertise any routes via eBGP to the PE which will then, in turn, advertise the prefixes over the core to the other PE and CE.  Below is the topology in case you forgot what it looks like:

Simple Cisco MPLS core diagram
Simple Cisco MPLS core diagram

Right now, we are not going to concern ourselves with the multicast source and receiver on each end of the CE as that will come via another tutorial.  Just make not of the various loopbacks and transits that are between the CE’s and PE’s.  Before we make the connections between the CE’s and PE’s we are going to create the Virtual Route Forwarder (VRF) for Customer A on each PE, advertise the loopback16 prefix on each PE into the core and make sure we can ping each over the core.  The configuration looks like the following.  Make note that all we are doing on the PE’s are as follows:

  • Create the Customer-A VRF (with route distinguisher and vrf-target import/export)
  • Create loopback that belongs to the VRF
  • Create transit that belongs to the VRF which connects to the local CE
  • Create a VRF address-family for Customer-A

Now that you have the basics, have a look at the configuration for both R1 (PE) and R5 (PE):

R1 (PE)

ip vrf CUSTOMER-A
  rd 100:16
  route-target export 100:16
  route-target import 100:16
!
interface Loopback16
  ip vrf forwarding CUSTOMER-A
  ip address 16.16.1.1 255.255.255.255
!
interface GigabitEthernet1.16
  encapsulation dot1Q 16
  ip vrf forwarding CUSTOMER-A
  ip address 172.16.1.1 255.255.255.252
!
router bgp 100
  address-family ipv4 vrf CUSTOMER-A
    network 16.16.1.1 mask 255.255.255.255
    network 172.16.1.0 mask 255.255.255.252
    neighbor 172.16.1.2 remote-as 65161
    neighbor 172.16.1.2 activate
  exit-address-family
!

 

R5 (PE)

ip vrf CUSTOMER-A
  rd 100:16
  route-target export 100:16
  route-target import 100:16
!
interface Loopback16
  ip vrf forwarding CUSTOMER-A
  ip address 16.16.2.1 255.255.255.255
!
interface GigabitEthernet1.16
  encapsulation dot1Q 16
  ip vrf forwarding CUSTOMER-A
  ip address 172.16.2.1 255.255.255.252
!
router bgp 100
  address-family ipv4 vrf CUSTOMER-A
    network 16.16.2.1 mask 255.255.255.255
    network 172.16.2.0 mask 255.255.255.252
    neighbor 172.16.2.2 remote-as 65162
    neighbor 172.16.2.2 activate
  exit-address-family
!

 

Again, if you followed the Juniper L3VPN tutorial, this will look similar (albeit in the Cisco format) but let’s go over it real quick.  The first we do is create the VRF definition for Customer-A.  This includes the RD and route-targets.  The RD distinguishes prefixes so that they only belong to the Customer-A VRF and not any others (including the global routing table).  The route-target exports states that prefixes exported from this PE should be tagged with 100:16 and routes that get imported into the VRF should also be tagged with 100:16.

Next, we create the loopback and transit for each PE and place it in the Customer-A VRF via the ip vrf forwarding CUSTOMER-A command.  Note that this will need to be configured before the IP address is applied as the previous command will wipe out any address already assigned to the interface.  If there is an interface already assigned and you use the ip vrf forwarding CUSTOMER-A command, it will take a few minutes before you can apply the IP address again to the interface as it takes some time to get removed from the VRF instance.

Finally, we create the VRF under the BGP routing process.  This is done by creating a new address-family but this time, adding the vrf CUSTOMER-A identifier.  Once that is done, the rest of the configuration is similar to creating an eBGP connection…define the neighbor with the remote-AS identifier and advertise any prefixes into the BGP routing process (in this case, the loopback prefixes for the Customer-A VRF).

Now that is done, let’s perform a few show commands and test ping to verify connection across the MPLS core.  First thing we can do is check the local forwarding table for the CUSTOMER-A VRF and check to see that we are advertising the local loopback prefix over the MPLS core using the command show mpls forwarding-table vrf CUSTOMER-A detail:

R1#show mpls forwarding-table vrf CUSTOMER-A detail
Local Outgoing Prefix Bytes Label Outgoing Next Hop
Label Label or Tunnel Id Switched interface
30 Pop Label 16.16.1.1/32[V] 0 aggregate/CUSTOMER-A
 MAC/Encaps=0/0, MRU=0, Label Stack{}
 VPN route: CUSTOMER-A
 No output feature configured
31 No Label 172.16.1.0/30[V] 0 aggregate/CUSTOMER-A
 MAC/Encaps=0/0, MRU=0, Label Stack{}
 VPN route: CUSTOMER-A
 No output feature configured

As you can see, we have R1 (PE)’s loopback and transit towards R7 (CE-A) in the forwarding table for the CUSTOMER-A VRF.  If we wanted to see what label is being used when sending packets towards R5 (PE)’s loopback address of 16.16.2.1/32, use the command show mpls forwarding-table vrf CUSTOMER-A 16.16.2.1 32 which will give you the following output:

R1#show mpls forwarding-table vrf CUSTOMER-A 16.16.2.1
Local Outgoing Prefix Bytes Label Outgoing Next Hop
Label Label or Tunnel Id Switched interface
None 31 16.16.2.1/32[V] 0

We can confirm that out packets are traversing the MPLS core by pinging from R1 (PE)’s loopback16 towards R5 (PE)’s loopback16 address:

R1#ping vrf CUSTOMER-A 16.16.2.1 source loopback 16
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 16.16.2.1, timeout is 2 seconds:
Packet sent with a source address of 16.16.1.1
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/2/6 ms

You can also check the routing table by using the command show ip route vrf CUSTOMER-A but for now, I will leave that and move on to making the connections to the CE routers to complete this tutorial.

Customer Edge Prefix Adverisement

Connecting the CE router to the PE router is simple.  Since the CE router has no idea of MPLS nor VRF, we just create a eBGP peering between it and the PE router.  Since the transit interface on the PE router has already been created and placed in the VRF instance as well as the BGP peerings, once we create everything on the CE routers, we should have full connectivity to the PE’s and across the MPLS core.  The following is the configuration for R7 (CE-A) and R8 (CE-A) which is, again, simple:

R7 (CE-A)

interface Loopback0
  ip address 16.16.1.2 255.255.255.255
!
interface GigabitEthernet1.16
  encapsulation dot1Q 16
  ip address 172.16.1.2 255.255.255.252
!
router bgp 65161
  bgp log-neighbor-changes
  network 16.16.1.2 mask 255.255.255.255
  network 172.16.1.0 mask 255.255.255.252
  neighbor 172.16.1.1 remote-as 100
!

R8 (CE-A)

interface Loopback0
  ip address 16.16.2.2 255.255.255.255
!
interface GigabitEthernet1.16
  encapsulation dot1Q 16
  ip address 172.16.2.2 255.255.255.252
!
router bgp 65162
  bgp log-neighbor-changes
  network 16.16.2.2 mask 255.255.255.255
  network 172.16.2.0 mask 255.255.255.252
  neighbor 172.16.2.1 remote-as 100
!

As you can see, it is just a simple eBGP peering so if we use the command show ip bgp summary, we should see the peering with R1 (PE) as up and exchanging prefixes:

R7#sh ip bgp summary
BGP router identifier 16.16.1.2, local AS number 65161
BGP table version is 7, main routing table version 7
6 network entries using 1488 bytes of memory
7 path entries using 840 bytes of memory
4/4 BGP path/bestpath attribute entries using 960 bytes of memory
2 BGP AS-PATH entries using 64 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 3352 total bytes of memory
BGP activity 6/0 prefixes, 7/0 paths, scan interval 60 secs

Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
172.16.1.1 4 100 4927 4931 7 0 0 3d02h 5

If we check the routing table on R7 (CE-A), we should see not only the prefixes that are being advertised from R1 (PE) but also R5 (PE) and R8 (CE-A):

R7#show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
 D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
 N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
 E1 - OSPF external type 1, E2 - OSPF external type 2
 i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
 ia - IS-IS inter area, * - candidate default, U - per-user static route
 o - ODR, P - periodic downloaded static route, H - NHRP, l - LISP
 a - application route
 + - replicated route, % - next hop override

Gateway of last resort is 10.207.123.1 to network 0.0.0.0

S* 0.0.0.0/0 [254/0] via 10.207.123.1
 10.0.0.0/8 is variably subnetted, 3 subnets, 2 masks
S 10.207.122.7/32 [254/0] via 10.207.123.1, GigabitEthernet2
C 10.207.123.0/24 is directly connected, GigabitEthernet2
L 10.207.123.107/32 is directly connected, GigabitEthernet2
 16.0.0.0/32 is subnetted, 4 subnets
B 16.16.1.1 [20/0] via 172.16.1.1, 3d02h
C 16.16.1.2 is directly connected, Loopback0
B 16.16.2.1 [20/0] via 172.16.1.1, 3d02h
B 16.16.2.2 [20/0] via 172.16.1.1, 3d02h
 172.16.0.0/16 is variably subnetted, 3 subnets, 2 masks
C 172.16.1.0/30 is directly connected, GigabitEthernet1.16
L 172.16.1.2/32 is directly connected, GigabitEthernet1.16
B 172.16.2.0/30 [20/0] via 172.16.1.1, 3d02h

I see the routes that would expect.  Now, let’s perform a ping from the loopback on R7 (CE-A) and the loopback on R8 (CE-A):

R7#ping 16.16.2.2 source loopback 0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 16.16.2.2, timeout is 2 seconds:
Packet sent with a source address of 16.16.1.2
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/2 ms

Finally, if we perform a traceroute, again, to/from the CE loopbacks we can see it traversing the MPLS core:

R7#traceroute 16.16.2.2 source loopback 0
Type escape sequence to abort.
Tracing the route to 16.16.2.2
VRF info: (vrf in name/id, vrf out name/id)
 1 172.16.1.1 1 msec 1 msec 0 msec
 2 10.0.0.6 [MPLS: Labels 26/32 Exp 0] 2 msec 2 msec 1 msec
 3 172.16.2.1 [AS 100] [MPLS: Label 32 Exp 0] 2 msec 1 msec 1 msec
 4 172.16.2.2 [AS 100] 2 msec * 1 msec

Conclusion

In this tutorial and the last, we have created an MPLS core using Cisco CSR1000v routers, created a CUSTOMER-A VRF and advertised prefixes between the CE and PE routers.  If you wanted to expand on this, you could create another connection to another set of routers, create a new VRF and then have two VRF’s on each PE router so show the separation of the VRF routing tables and how they work on the same devices.  But, for now, we just want to keep it simple.  Obviously there is a lot more working under the hood relating to how labels are assigned, how prefixes are separated into their VRFs and how prefixes are advertised across the MPLS core.

If you wish to learn more about what goes on under the hood, I recommend reading the Cisco documentation or pick up the book MPLS Fundamentals by Luc De Ghein.

Troy Perkins

Leave a Reply

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