In the last article, we discussed the basic configuration of MPLS Layer 3 VPN. Part 2 will cover the following tasks and topics on how to share routing information between difference customers or VRF in an MPLS VPN network:

  1. Configure static routes between two VRFs CUST-B and global routing table Customer C.
  2. Configure a VPNv4 route-reflector.
  3. Import routes between Customer A and B using route-target functionality.
  4. Filter the routes imported routes through the use of import-maps.

Sharing routing information through two VRFs is known as “route-leaking”. The basic behavior of MPLS VPN is that every customer has a unique routing table and this table is not visible to the other customers. Route-leaking comes into play when there is a need to share routing information from one customer to another. A good example, where route-leaking is used in real life is when two companies decide to have a B2B (Business to Business) connection in order for them to share data and applications. A company might be providing services to another and it happens that both of them are using MPLS of the same provider or different MPLS providers but with interconnectivity with each other. To interconnect them right away is to route-leak the information vice-versa. One thing to watch out for is that the routes must be unique to each of the customers. Most often, customers who want to have routes interconnected in the MPLS cloud NATs their IP addresses before sharing to their partners.

Figure 1. MPLS VPN Topology

We will be using the similar topology in Part 1 and we will configure it where we left off. The only difference here is an additional Customer C router. You can download the GNS files below.

Task 1: Configure VRF static routes between two VRF’s.

Customer B and Customer C wants to have connectivity between their servers 8.8.8.8/32 and 9.9.9.9/32 respectively. Let’s provide connectivity between these two networks through the use of VRF static routes. By the way, if you hear the term “VRF-Lite”, it simply means using VRF without MPLS. Customer C is not under any VRF but is in the global routing table. We will leak out the global routing table to VRF CUST-B and vice-versa.

R2(config)#ip route 8.8.8.8 255.255.255.255 fa1/0 28.28.28.8
R2(config)#ip route vrf CUST-B 9.9.9.9 255.255.255.255 fa2/0 29.29.29.9 global

R2#sh ip route 8.8.8.8
Routing entry for 8.8.8.8/32
Known via “static”, distance 1, metric 0
Routing Descriptor Blocks:
* 28.28.28.8, via FastEthernet1/0
Route metric is 0, traffic share count is 1

R2#sh ip route vrf CUST-B 9.9.9.9
Routing entry for 9.9.9.9/32
Known via “static”, distance 1, metric 0
Routing Descriptor Blocks:
* 29.29.29.9 (Default-IP-Routing-Table), via FastEthernet2/0
Route metric is 0, traffic share count is 1

CUST_B-R1#ping 9.9.9.9 source 8.8.8.8
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 9.9.9.9, timeout is 2 seconds:
Packet sent with a source address of 8.8.8.8
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 20/30/48 ms
CUST_B-R1#traceroute 9.9.9.9 source 8.8.8.8

Type escape sequence to abort.
Tracing the route to 9.9.9.9

1 28.28.28.2 32 msec 20 msec 20 msec
2 29.29.29.9 36 msec 24 msec 28 msec

In the configuration part, we configured two static routes to tell the router how to route from global to VRF. In the VRF CUST-B static route, the “global” keyword and basically instructed the router that the route is in the global routing table. On the other hand, the global static route pointing to 8.8.8.8/32 with the next-hop of 28.28.28.8 was configured normally. This is still accepted by the router even though that IP is in VRF CUST-B. What if there are many interfaces configured as 28.28.28.0/24, how will the router know where to route it? This is handled by specifying the outgoing interface in the static route command.

Our ping works because the CE routers have been configured with default route. Let’s remove the default routes in the CE and in R2 we will redistribute the routes into the respective BGP address-families so the CE’s will learn the exact route from BGP.

CUST_B-R1(config)#no ip route 0.0.0.0 0.0.0.0 28.28.28.2
CUST_C(config)#no ip route 0.0.0.0 0.0.0.0 29.29.29.2

R2(config-router-af)#exit
R2(config-router)#router bgp 65001
R2(config-router)#redistribute static
R2(config-router)#address-family ipv4 vrf CUST-B
R2(config-router-af)#redistribute static

CUST_C#ping 8.8.8.8 source 9.9.9.9

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds:
Packet sent with a source address of 9.9.9.9
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 28/44/52 ms
CUST_C#sh ip bgp
BGP table version is 4, local router ID is 99.99.99.99
Status codes: s suppressed, d damped, h history, * valid, > best, i – internal,
r RIB-failure, S Stale
Origin codes: i – IGP, e – EGP, ? – incomplete

Network Next Hop Metric LocPrf Weight Path
*> 8.8.8.8/32 29.29.29.2 0 0 65001 ?
*> 9.9.9.9/32 0.0.0.0 0 32768 i
*> 99.99.99.99/32 0.0.0.0 0 32768 i

Task 2: Configure a VPNv4 Route-Reflector

Before we move on to the third task, we need to prepare the network for three routers now to share routes. In Part 1, we didn’t configure VPNv4 Route-Reflector because we are only having two PE routers. VPNv4 route-reflector works the same way as a normal BGP RR. VPNv4 Route Reflector contains all the routes collected from different VRFs. We will configure R2 as the VPNv4 RR in this case.

R2(config)#router bgp 65001
R2(config-router)#address-family vpnv4
R2(config-router)#neigh 1.1.1.1 remote-as 65001
R2(config-router)#neigh 4.4.4.4 remote-as 65001
R2(config-router)#neigh 1.1.1.1 update-source Loopback0
R2(config-router)#neigh 4.4.4.4 update-source Loopback0
R2(config-router)#address-family vpnv4
R2(config-router-af)#neighbor 1.1.1.1 activate
R2(config-router-af)#neighbor 4.4.4.4 activate
R2(config-router-af)#neigh 1.1.1.1 route-reflector-client
R2(config-router-af)#neigh 4.4.4.4 route-reflector-client
R2(config-router-af)#neigh 1.1.1.1 send-community extended
R2(config-router-af)#neigh 4.4.4.4 send-community extended

R1(config)#router bgp 65001
R1(config-router)#neigh 2.2.2.2 remote 65001
R1(config-router)#neighbor 2.2.2.2 next-hop-self
R1(config-router)#neighbor 2.2.2.2 update-source Loopback0
R1(config-router)#address-family vpnv4
R1(config-router-af)#neigh 2.2.2.2 activate
R1(config-router-af)#neigh 2.2.2.2 send-community extended

R4(config)#router bgp 65001
R4(config-router)#neigh 2.2.2.2 remote 65001
R4(config-router)#neighbor 2.2.2.2 next-hop-self
R4(config-router)#neighbor 2.2.2.2 update-source Loopback0
R4(config-router)#address-family vpnv4
R4(config-router-af)#neigh 2.2.2.2 activate
R4(config-router-af)#neigh 2.2.2.2 send-community extended

R2#sh ip bgp vpnv4 all sum | beg Neighbor
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
1.1.1.1 4 65001 10 15 13 0 0 00:05:52 2
4.4.4.4 4 65001 6 11 13 0 0 00:01:49 2
28.28.28.8 4 65003 69 69 13 0 0 01:03:51 2

Task 3: Import routes between Customer A and B

We will do what is called “route-leaking” and will be configuring the PEs R1, R2 and R4. Remember in VRF we have what we call route-target. “Route-target export” command will mark the routes under that specific VRF which the route-target value specified. This feature is actually a MP-BGP extended community. “Route-target” import on the other hand means that all routes with those route-target values will be imported into the VRF routing table. Let’s proceed into the configuration.

R1#sh run | sec vrf
ip vrf CUST-A
rd 65002:1
route-target export 65002:1
route-target import 65002:1
ip vrf forwarding CUST-A
address-family ipv4 vrf CUST-A
R1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R1(config)#ip vrf CUST-A
R1(config-vrf)#route-target import 65002:2

R2#sh run | sec vrf
ip vrf CUST-B
rd 65002:2
ip vrf forwarding CUST-B
address-family ipv4 vrf CUST-B
ip route vrf CUST-B 9.9.9.9 255.255.255.255 FastEthernet2/0 29.29.29.9 global
R2#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R2(config)#ip vrf CUST-B
R2(config-vrf)#route-target export 65002:2
R2(config-vrf)#route-t
*Mar 1 00:09:56.459: %BGP-5-ADJCHANGE: neighbor 28.28.28.8 vpn vrf CUST-B Down VRF config change
R2(config-vrf)#route-targ
*Mar 1 00:09:57.967: %BGP-5-ADJCHANGE: neighbor 28.28.28.8 vpn vrf CUST-B Up
R2(config-vrf)#route-target import 65002:2
R2(config-vrf)#route-target import 65002:1

R4#sh run | sec vrf
ip vrf CUST-A
rd 65002:1
route-target export 65002:1
route-target import 65002:1
ip vrf forwarding CUST-A
address-family ipv4 vrf CUST-A
R4#conf t
Enter configuration commands, one per line. End with CNTL/Z.
R4(config)#ip vrf CUST-A
R4(config-vrf)#route-target import 65002:2

On the diagram below, we can see how this route-leaking works. R1 is exporting its routes from VRF CUST-A with a route-target value of 65002:1. In order for R2 to receive R1’s routes, it needs to import the same values. The same goes vice versa, R1 needs to import R2’s route-target for that specific VRF. If R1 is not importing R2s routes with route-target value of 65002:2, there will be no reachability between the two VRFs. R2 will be able to see R1’s route but not vice-versa.

Drawing1

Let’s check if the there is full reachability between CUST_A-R1, CUST_A-R2 and CUST_B-R1.

CUST_A-R1#sh ip bgp
BGP table version is 28, local router ID is 55.55.55.55
Status codes: s suppressed, d damped, h history, * valid, > best, i – internal,
r RIB-failure, S Stale
Origin codes: i – IGP, e – EGP, ? – incomplete

Network Next Hop Metric LocPrf Weight Path
*> 5.5.5.5/32 0.0.0.0 0 32768 i
*> 6.6.6.6/32 15.15.15.1 0 65001 65001 i
*> 8.8.8.8/32 15.15.15.1 0 65001 65003 i
*> 9.9.9.9/32 15.15.15.1 0 65001 ?
*> 55.55.55.55/32 0.0.0.0 0 32768 i
*> 66.66.66.66/32 15.15.15.1 0 65001 65001 i
*> 88.88.88.88/32 15.15.15.1 0 65001 65003 i
CUST_A-R1#ping 8.8.8.8 source 5.5.5.5

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds:
Packet sent with a source address of 5.5.5.5
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 60/64/80 ms

CUST_B-R1#sh ip bgp
BGP table version is 16, local router ID is 88.88.88.88
Status codes: s suppressed, d damped, h history, * valid, > best, i – internal,
r RIB-failure, S Stale
Origin codes: i – IGP, e – EGP, ? – incomplete

Network Next Hop Metric LocPrf Weight Path
*> 5.5.5.5/32 28.28.28.2 0 65001 65002 i
*> 6.6.6.6/32 28.28.28.2 0 65001 65002 i
*> 8.8.8.8/32 0.0.0.0 0 32768 i
*> 9.9.9.9/32 28.28.28.2 0 0 65001 ?
*> 55.55.55.55/32 28.28.28.2 0 65001 65002 i
*> 66.66.66.66/32 28.28.28.2 0 65001 65002 i
*> 88.88.88.88/32 0.0.0.0 0 32768 i

CUST_B-R1#ping 5.5.5.5 source 8.8.8.8

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 5.5.5.5, timeout is 2 seconds:
Packet sent with a source address of 8.8.8.8
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 48/67/92 ms
CUST_B-R1#ping 6.6.6.6 source 8.8.8.8

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 6.6.6.6, timeout is 2 seconds:
Packet sent with a source address of 8.8.8.8
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 80/89/104 ms

Task 4: Filter the routes imported routes through the use of import-maps

In this task, we will configure R1 to filter 8.8.8.8/32 from being imported to VRF CUST-A using an import map statement.

The command below can be used on the PE to check the current BGP prefixes under a specific VRF. We can see that 8.8.8.8/32 has already been imported to vrf CUST-A.

R1#sh ip bgp vpnv4 vrf CUST-A
BGP table version is 29, local router ID is 1.1.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, i – internal,
r RIB-failure, S Stale
Origin codes: i – IGP, e – EGP, ? – incomplete

Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: 65002:1 (default for vrf CUST-A)
*> 5.5.5.5/32 15.15.15.5 0 0 65002 i
* i6.6.6.6/32 4.4.4.4 0 100 0 65002 i
*>i 4.4.4.4 0 100 0 65002 i
*>i8.8.8.8/32 2.2.2.2 0 100 0 65003 i
*>i9.9.9.9/32 2.2.2.2 0 100 0 ?
*> 55.55.55.55/32 15.15.15.5 0 0 65002 i
* i66.66.66.66/32 4.4.4.4 0 100 0 65002 i
*>i 4.4.4.4 0 100 0 65002 i
*>i88.88.88.88/32 2.2.2.2 0 100 0 65003 i

Now let’s configure an import-map statement denying 8.8.8.8/32 from being imported.

R1(config)#ip prefix-list DENY8 seq 5 permit 8.8.8.8/32
R1(config)#no route-map DENY8
R1(config)#route-map DENY8 deny 5
R1(config-route-map)#match ip address prefi
R1(config-route-map)#match ip address prefix-list DENY8
R1(config-route-map)#route-map DENY8 permit 10
R1(config)#ip vrf CUST-A
R1(config-vrf)#import map DENY8

R1#sh ip bgp vpnv4 vrf CUST-A
BGP table version is 12, local router ID is 1.1.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, i – internal,
r RIB-failure, S Stale
Origin codes: i – IGP, e – EGP, ? – incomplete

Network Next Hop Metric LocPrf Weight Path
Route Distinguisher: 65002:1 (default for vrf CUST-A)
*> 5.5.5.5/32 15.15.15.5 0 0 65002 i
*>i6.6.6.6/32 4.4.4.4 0 100 0 65002 i
* i 4.4.4.4 0 100 0 65002 i
*>i9.9.9.9/32 2.2.2.2 0 100 0 ?
*> 55.55.55.55/32 15.15.15.5 0 0 65002 i
*>i66.66.66.66/32 4.4.4.4 0 100 0 65002 i
* i 4.4.4.4 0 100 0 65002 i
*>i88.88.88.88/32 2.2.2.2 0 100 0 65003 i

8.8.8.8/32 now is not being imported into the VRF! What was done here was configuring a prefix-list matching 8.8.8.8/32. Then create a route-map DENY8 denying the prefix list DENY8 which matches 8.8.8.8/32. The last statement on the route-map should be an explicit permit to allow other routes to be imported. Lastly, under VRF CUST-A specify an import map that references to DENY8.

References:

http://www.cisco.com/c/en/us/support/docs/multiprotocol-label-switching-mpls/mpls/13733-mpls-vpn-basic.html

http://www.cisco.com/c/en/us/td/docs/ios-xml/ios/mp_l3_vpns/configuration/15-mt/mp-l3-vpns-15-mt-book/mp-bgp-mpls-vpn.html