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 184.108.40.206, it’s loopback address. Essentially we need the PE’s to leak the dynamically learned 220.127.116.11/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 18.104.22.168/32 is subnetted, 1 subnets B 22.214.171.124 [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 126.96.36.199 00:00:35 ago Routing Descriptor Blocks: * 188.8.131.52 (default), from 184.108.40.206, 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 220.127.116.11/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 18.104.22.168 % Network not in table
It’s not there. But is it in my BGP table?
R2#show ip bgp 22.214.171.124 BGP routing table entry for 126.96.36.199/32, version 6 Paths: (1 available, no best path) Not advertised to any peer Refresh Epoch 1 6 10.0.46.6 (inaccessible) from 188.8.131.52 (184.108.40.206) 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 220.127.116.11 next-hop-self
We should now see the valid route on R2:
R2#show ip bgp 18.104.22.168 BGP routing table entry for 22.214.171.124/32, version 7 Paths: (1 available, best #1, table default) Not advertised to any peer Refresh Epoch 1 6 126.96.36.199 (metric 3) from 188.8.131.52 (184.108.40.206) Origin IGP, metric 0, localpref 100, valid, internal, best rx pathid: 0, tx pathid: 0x0
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 220.127.116.11. 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 18.104.22.168 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 22.214.171.124 !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 80/93/112 ms
Which is exactly what we see.
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