VRF's do a good job of keeping routes separate. Each VRF represents a different routing table, allowing isolation between tenants.
But now imagine that you're a small service provider. You have VRF's for your customers and an extra VRF for your own services. How do you share routes to your services with your customers?
One way is to use MP-BGP to leak routes between VRF's. In this scenario, BGP is aware of each of the VRF's and their contents. It selectively shares routes between them.
In this article, we'll run through a simple lab, and show how to use MP-BGP to leak routes. You can also use the skills you learn here in MPLS networks.
This is going to be a simple lab. In fact, we'll only use one router. Keep in mind that in the real world, the solution will encompass many routers.
As shown below, our router has three VRF's. Each VRF has three networks, implemented as loopback interfaces. Initially, loopbacks in one VRF will not be able to ping loopbacks in another VRF.
The initial configuration also includes an empty instance of BGP, using AS 65535.
The initial Config Files are available for download.
The goals of this lab are:
- All networks in VRF-C should be available to the other two VRF's
- All networks in VRF-A and VRF-B should be available in VRF-C
- VRF-A and VRF-B should remain isolated from each other
Prefixes from many VRF's can be added into BGP. This raises the question, 'how does BGP keep the prefixes separate?'
This is especially interesting if you have overlapping IP spaces. The answer is Route Distinguishers.
Key Concept: Route Distinguishers keep routes unique
This means that in the BGP database, the RD distinguishes one VRF from another.
The RD is a 64-bit value, which you can format in a few different ways. The most common way is to break it into two 32-bit values, separated by a colon.
Generally, the first value is the ASN. The second value is assignable by you. For example, you may use an RD of 65000:10 in AS 65000.
When you start adding RD information to prefixes, these become VPNv4 or VPNv6 routes in BGP. This is commonly seen in MPLS networks.
An RD is configured within the VRF with the rd keyword. This can be verified with show ip vrf.
Router(config)#vrf definition VRF-A Router(config-vrf)#rd 65535:1 Router(config)#vrf definition VRF-B Router(config-vrf)#rd 65535:2 Router(config)#vrf definition VRF-C Router(config-vrf)#rd 65535:3 Router#show ip vrf Name Default RD Interfaces VRF-A 65535:1 Lo10 Lo11 Lo12 VRF-B 65535:2 Lo20 Lo21 Lo22 VRF-C 65535:3 Lo30 Lo31 Lo32
Now that our VRF's have an RD associated with them, we need to get the prefixes into BGP. BGP treats each VRF as a separate address-family. From here, we can redistribute connected routes into BGP.
Router(config)#router bgp 65535 Router(config-router)#address-family ipv4 vrf VRF-A Router(config-router-af)#redistribute connected Router(config-router)#address-family ipv4 vrf VRF-B Router(config-router-af)#redistribute connected Router(config-router)#address-family ipv4 vrf VRF-C Router(config-router-af)#redistribute connected
To verify this, use the show ip bgp vpnv4 all command. This will show all prefixes, their RD, and the associated VRF.
Keep in mind that so far, all we've done is make prefixes unique in BGP. We have not enabled leaking between VRF's yet.
Router#show ip bgp vpnv4 all BGP table version is 10, local router ID is 188.8.131.52 Status codes: s suppressed, d damped, h history, * valid, > best, i - internal, r RIB-failure, S Stale, m multipath, b backup-path, f RT-Filter, x best-external, a additional-path, c RIB-compressed, Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found Network Next Hop Metric LocPrf Weight Path Route Distinguisher: 65535:1 (default for vrf VRF-A) *> 172.16.1.0/24 0.0.0.0 0 32768 ? *> 172.16.2.0/24 0.0.0.0 0 32768 ? *> 172.16.3.0/24 0.0.0.0 0 32768 ? Route Distinguisher: 65535:2 (default for vrf VRF-B) *> 192.168.1.0 0.0.0.0 0 32768 ? *> 192.168.2.0 0.0.0.0 0 32768 ? *> 192.168.3.0 0.0.0.0 0 32768 ? Route Distinguisher: 65535:3 (default for vrf VRF-C) *> 10.10.1.0/24 0.0.0.0 0 32768 ? *> 10.10.2.0/24 0.0.0.0 0 32768 ? *> 10.10.3.0/24 0.0.0.0 0 32768 ?
Key Concept: Route Targets Import and Export Routes
An RT specifies which VRF's to export routes from, and which VRF's to import routes into. They use the same formatting as RD's, and they often use the same values. While they may look the same, it's important to remember that they're different things.
Exporting tags a prefix with the RT value. This is entered into BGP, and shared with other routers as extended communities. Hint: Make sure you enable extended communities!
Importing selects routes based on their RT, and inserts them into a VRF.
We start by assigning a tag to the routes in each VRF. This is done with the route-target export command.
Under the hood, this creates a BGP community that is sent to neighbours along with the prefix.
Router(config)#vrf definition VRF-A Router(config-vrf)#route-target export 65535:1 Router(config)#vrf definition VRF-B Router(config-vrf)#route-target export 65535:2 Router(config)#vrf definition VRF-C Router(config-vrf)#route-target export 65535:3
Use the show ip bgp vpnv4 all detail command, and you will be able to see the extended community that it's using.
Router#show ip bgp vpnv4 all detail Route Distinguisher: 65535:1 (default for vrf VRF-A) BGP routing table entry for 65535:1:172.16.1.0/24, version 11 Paths: (1 available, best #1, table VRF-A) Not advertised to any peer Refresh Epoch 1 Local 0.0.0.0 (via vrf VRF-A) from 0.0.0.0 (184.108.40.206) Origin incomplete, metric 0, localpref 100, weight 32768, valid, sourced, best Extended Community: RT:65535:1 rx pathid: 0, tx pathid: 0x0 ! Additional output omitted for brevity
We import routes by looking for any prefixes with a certain 'tag'. In this example, we import routes into VRF-C by looking for VRF-A and VRF-B's Route Target.
This is where the route leaking happens. Notice that we don't share routes between VRF-A and VRF-B.
Router(config)#vrf definition VRF-C Router(config-vrf)#route-target import 65535:1 Router(config-vrf)#route-target import 65535:2 Router(config)#vrf definition VRF-A Router(config-vrf)#route-target import 65535:3 Router(config)#vrf definition VRF-B Router(config-vrf)#route-target import 65535:3
To verify this, simply look at the route tables.
Router#show ip route vrf VRF-A Routing Table: VRF-A ! Output omitted for brevity 10.0.0.0/8 is variably subnetted, 6 subnets, 2 masks B 10.10.1.0/24 is directly connected, 00:00:48, Loopback30 L 10.10.1.1/32 is directly connected, Loopback30 B 10.10.2.0/24 is directly connected, 00:00:48, Loopback31 L 10.10.2.1/32 is directly connected, Loopback31 B 10.10.3.0/24 is directly connected, 00:00:48, Loopback32 L 10.10.3.1/32 is directly connected, Loopback32 172.16.0.0/16 is variably subnetted, 6 subnets, 2 masks C 172.16.1.0/24 is directly connected, Loopback10 L 172.16.1.1/32 is directly connected, Loopback10 C 172.16.2.0/24 is directly connected, Loopback11 L 172.16.2.1/32 is directly connected, Loopback11 C 172.16.3.0/24 is directly connected, Loopback12 L 172.16.3.1/32 is directly connected, Loopback12
Optionally, you can use route-target both. The both keyword imports and exports at the same time.
Some implementations (such as IOS-XR and NXOS) let you use the auto keyword. This generates an RT value for you, based on the router-id rather than AS number.
As a final thought, you may be wondering if we can selectively import and export routes. After all, you may not want to leak every route in your VRF.
The answer is yes. This can be done with an export-map. But, that's a story for another time...
Packet Life - Inter-VRF Routing with VRF Lite
Packet Life - Route Distinguishers and Route Targets
Last update 2017-12-05 16:08