Moving routes between a VRF and the global (default) RIB – Part 1 – Cisco IOS

Part 1 – Cisco IOS
Part 2 – Brocade Netiron
Part 3 – Juniper Junos

I don’t think there is a standard name for the initial route-table on a router. Junos calls it inet.0, Netiron has no name, and it’s also the no name VRF in IOS. I’ll simple be calling it the ‘global’ table for these and all future posts.

It’s easy to share routes between VRFs by manipulating route-targets. It’s not so easy when you try to do this with the global table as there are no route-targets associated with the global RIB. While there is a standard for moving routes between named VRFs, there is no such standard for moving routes in and out of the global table in this way.

As there is no standard, all three vendors take different approaches to doing this.

You can do this via static routes, but this is less than ideal. What happens if the CE device is multihomed to two different PE devices? I want to be able to import/export dynamic routes.

Let’s take the following diagram as an example:

R6 is a CE device. It is multihomed to two PE routers, R4 and R5. R1 is acting as a server connected to R2. This server is not in a vrf. i.e. all routers in the core are able to get to R1 as it’s simply an address in the global IGP table.

This particular server is running a service that the customer needs to get to. They should only be able to get to R1 via 6.6.6.6, it’s loopback address. Essentially we need the PE’s to leak the dynamically learned 6.6.6.6/32 from the VRF into the global table. At the same time we need to leak R1’s address into the VRF.

Copying global routes to VRF

First, let’s check the VRF route-table on R4 to make sure we don’t have any global routes in the vrf yet. R1’s address is 10.0.12.1/24:

R4#sh ip route vrf CUS1 | beg Gate
Gateway of last resort is not set

      6.0.0.0/32 is subnetted, 1 subnets
B        6.6.6.6 [20/0] via 10.0.46.6, 00:00:31
      10.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
C        10.0.46.0/24 is directly connected, FastEthernet1/1
L        10.0.46.4/32 is directly connected, FastEthernet1/1

You’ve been able to do this on IOS for some time. Under your vrf definition, type import map ipv4 unicast route-map:

ip prefix-list ISP_SERVER seq 5 permit 10.0.12.0/24
!
route-map MAP_ISP_SERVER permit 10
 match ip address prefix-list ISP_SERVER
!
vrf definition CUS1
 !
 address-family ipv4
  import ipv4 unicast map MAP_ISP_SERVER

Do we see the routes in the VRF?

R4#sh ip route vrf CUS1 10.0.12.0

Routing Table: CUS1
% Subnet not in table

No. Why not? Well if you read the command reference, the import map calls this the ‘BGP Support for IP Prefix Import from Global Table into a VRF Table feature’ – R1’s address is not currently a BGP route, its an internal IGP route. We need to ensure the PEs see this route as a BGP route. Note that the BGP route itself doesn’t need to be active, it just needs to be in the BGP table and valid. On R2 I’m running regular ipv4 unicast BGP and will advertise that subnet into BGP:

R2#sh run | sec router bgp
router bgp 100
!
 address-family ipv4
  network 10.0.12.0 mask 255.255.255.0

That global route should now be imported into the vrf:

R4#sh ip route vrf CUS1 10.0.12.0

Routing Table: CUS1
Routing entry for 10.0.12.0/24
  Known via "bgp 100", distance 200, metric 0, type internal
  Last update from 2.2.2.2 00:00:35 ago
  Routing Descriptor Blocks:
  * 2.2.2.2 (default), from 2.2.2.2, 00:00:35 ago
      Route metric is 0, traffic share count is 1
      AS Hops 0
      MPLS label: none

Note that this command has been with us since IOS release 12.0(5)T

Copying VRF routes to global

Copying routes this way was a LOT more tricky, until very recently. Cisco has finally given us the export ipv4 unicast map command. This command has only existed from IOS release 15.2(4)S – A very recent release. Odd since the import command has existed for many years.

The use of this command is very similar to the import. Let’s match R6’s loopback via a prefix-list, match that in a route-map, and export from the vrf to the global through the vrf defination:

ip prefix-list CUS1_PREFIX seq 5 permit 6.6.6.6/32
!
route-map MAP_CUS1_PREFIX permit 10
 match ip address prefix-list CUS1_PREFIX
!
vrf definition CUS1
 !
 address-family ipv4
  export ipv4 unicast map MAP_CUS1_PREFIX

Just like the import command, this command export the route into the global BGP table. This means I could either redistribute the BGP route into my IGP, or use the existing BGP session I have with R2. Let’s check on R2 to see if I have R6’s loopback:

R2#sh ip route 6.6.6.6
% Network not in table

It’s not there. But is it in my BGP table?

R2#show ip bgp 6.6.6.6
BGP routing table entry for 6.6.6.6/32, version 6
Paths: (1 available, no best path)
  Not advertised to any peer
  Refresh Epoch 1
  6
    10.0.46.6 (inaccessible) from 4.4.4.4 (4.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal
      rx pathid: 0, tx pathid: 0

It’s there, but the next-hop is inaccessible. R4 is treating this as a regular eBGP update and so does not change the next-hop to itself as it would with a VPNv4 route. This can be easily fixed:

R4#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
R4(config)#router bgp 100
R4(config-router)#address-family ipv4 unicast
R4(config-router-af)#neighbor 2.2.2.2 next-hop-self

We should now see the valid route on R2:

R2#show ip bgp 6.6.6.6
BGP routing table entry for 6.6.6.6/32, version 7
Paths: (1 available, best #1, table default)
  Not advertised to any peer
  Refresh Epoch 1
  6
    4.4.4.4 (metric 3) from 4.4.4.4 (4.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      rx pathid: 0, tx pathid: 0x0

Verification

So at the end of all of this, R6 should be able to ping R1’s interface, but only if it sources the ping from 6.6.6.6. Let’s confirm this:

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

Which is exactly what we see.

Final Notes

With IOS, in order to move routes between the global and vrf tables, you need to invoke the import [ipv6|ipv4] unicast command. There is another import map command under the vrf, but that command does NOT move routes between the vrf and global. That command is there to have finer control of which vrf routes are imported/exported between MP-BGP and the vrf.

The export ipv4/ipv6 unicast command is only a very recent command, but at least supports both address families. The import command has been around for years, yet oddly does not support ipv6:

R4#sh ver | include IOS
Cisco IOS Software, 7200 Software (C7200-ADVENTERPRISEK9-M), Version 15.2(4)S2, RELEASE SOFTWARE

R4(config-vrf)#address-family ipv4

R4(config-vrf-af)#export ?
  ipv4  Address family based VRF export
  map   Route-map based VRF export

R4(config-vrf-af)#import ?
  ipv4  Address family based VRF import
  map   Route-map based VRF import


R4(config-vrf-af)#address-family ipv6
R4(config-vrf-af)#export ?
  ipv6  Address family based VRF export
  map   Route-map based VRF export

R4(config-vrf-af)#import ?
  map  Route-map based VRF import

© 2009-2018 Darren O'Connor All Rights Reserved -- Copyright notice by Blog Copyright