(This article assumes some understanding of MPLS VPNs)
The different methods to attach MPLS VPN RTs when routes are exported from a VRF table can be confusing.
This could be done in two ways with additional options.
- The default ‘all’ export RT could be used.
- Or the RTs could be attached using an export-map.
The first method is the most common and the easiest to understand. The command below will attach the configured RT to any routes exported from the router’s VRF RIB table into the MPBGP table for advertising.
route-target export {asn:xx}
But what if another RT should be attached in place of, or additionally but for only one prefix?
This is where the second method becomes necessary. By using an export-map one can selectively attach RTs to individual prefixes, separate or in conjunction with the default export if it is configured. This usually raises the question of when the ‘additive’ keyword is needed.
Allow me to explain by using the following diagram :

- R2 is a MPLS PE router.
- Attached to R2 in VRF-RED are 3 prefixes that different clients might need access to.
- The 3 prefixes of VRF-RED should be exported with the following RT combinations:
- 100.100.33.0/24 – Must only have the default RT (100:1) attached.
- 100.100.100.0/24 – Must only have one new RT (100:100) attached.
- 100.100.200.0/24 – Must have a new RT (100:200) and the default RT (100:1) attached.
Option-1. Here the default ‘all’ export option will attach RT 100:1 to all routes which are exported from the VRF-RED table to MPBGP:
ip vrf RED rd 100:1 route-target export 100:1 route-target import 100:2
By looking at one of the prefixes this is visible:
Rack6R2#sh ip bgp vpnv4 vrf RED 100.100.33.0 BGP routing table entry for 100:1:100.100.33.0/24, version 8 Paths: (1 available, best #1, table RED) 10.5.12.1 from 10.5.12.1 (10.0.0.1) Origin IGP, metric 0, localpref 100, valid, external, best Extended Community: RT:100:1 '<-- ONLY THE DEFAULT RT IS ATTACHED' mpls labels in/out 16/nolabel
.
To meet the second and third requirements a export-map statement is used that references a normal route-map:
ip prefix-list RANGE100 seq 5 permit 100.100.100.0/24 ip prefix-list RANGE200 seq 5 permit 100.100.200.0/24 ! route-map R2export permit 10 match ip address prefix-list RANGE100 set extcommunity rt 100:100 '<--Clears any attached RTS and attaches only 100:100' ! route-map R2export permit 20 match ip address prefix-list RANGE200 set extcommunity rt 100:200 additive '<--Attaches 100:200 additionally' ! ip vrf RED rd 100:1 export map R2export '<--Specifies the export route-map' route-target export 100:1 '<--Attached default during RT export' route-target import 100:2
The first sequence of the route-map will attach RT 100:100 to the matching prefix 100.100.100.0/24. As with any route-map no further processing is done once a match. So this prefix will have ONLY one RT attached. Notice that the default RT is not attached. See the output at the below:
Rack6R2#sh ip bgp vpnv4 vrf RED 100.100.100.0 BGP routing table entry for 100:1:100.100.100.0/24, version 2 Paths: (1 available, best #1, table RED) 10.5.12.1 from 10.5.12.1 (10.0.0.1) Origin IGP, metric 0, localpref 100, valid, external, best Extended Community: RT:100:100 '<-- ONLY ONE RT IS ATTACHED' mpls labels in/out 21/nolabel
The second sequence of the route-map will attach RT 100:200 to the matching prefix 100.100.200.0/24. In addition, since the ‘additive’ keyword was used, RT 100:200 and the default RT 100:1 is attached during export :
Rack6R2#sh ip bgp vpnv4 vrf RED 100.100.200.0 BGP routing table entry for 100:1:100.100.200.0/24, version 3 Paths: (1 available, best #1, table RED) 10.5.12.1 from 10.5.12.1 (10.0.0.1) Origin IGP, metric 0, localpref 100, valid, external, best Extended Community: RT:100:1 RT:100:200 '<-- ATTACHES BOTH RTs' mpls labels in/out 22/nolabel
A couple things to take note of:
- Any of these steps could have been done by using only an export-map with no default export statement.
- Unlike normal route-map use, the export-map conditionally ignores the implicit deny at the end. Thus if a prefix is not matched by any export-map statement, it will still be exported on the condition that the default export statement is specified. If no default export is specified, non-matching prefix will be denied from being exported.
Awesome stuff.
Saved me couple of hours of testing on real equipment.