An In-Depth Look at RD and RT, Pt. 1

In this article, we will explore RD (route distinguishers) and RT (route targets) in depth. We will answer question such as:

  • Why do we need both an RD and an RT? Why can’t we use a single value?

  • What happens if we have different RDs on two PEs for the same VRF?

  • What happens if we use the same RD for two different VRFs?

  • What happens if we export or import multiple RTs?

Before we start, you should have a basic understanding of L3VPNs.

Route Distinguishers

An RD is prepended to an IPv4 or IPv6 prefix to make it globally unique within the vpnv4 table.

To appreciate this, realize that the vpnv4 or vpnv6 table is a global table on all routers of an SP’s internal MPLS network. The RR is going to recieve all routes from all PEs, and it may or may not have the actual VRFs for the various vpnv4 routes configured locally. The RR needs to distinguish between the same prefix from different customers. This global vpnv4 or vpnv6 table is going to contain every prefix from all VRFs. If 200 customers advertise 10.0.0.0/24, the global vpnv4 table is going to contain 200 10.0.0.0/24 prefixes. But we need a way to make sure that the RR considers each 10.0.0.0/24 unique, and doesn’t just choose the best 10.0.0.0/24 among all 200 10.0.0.0/24 routes. (That is the way BGP would behave by default, if there were no RDs).

To make these 10.0.0.0/24 routes unique, the prefixes become [Customer A RD]:10.0.0.0/24 and [Customer B RD]:10.0.0.0/24. Now these routes are completely different, so the RR accepts all routes and reflects them all to its clients. Each 10.0.0.0/24 is actually a completely different route now, with the RD appended to it.

The RD is 8 bytes, and is appened to a 4 byte IPv4 address, resulting in a 12 byte vpnv4 prefix.

There are three types of RDs:

Type

Field 1

Colon

Field 2

0

AS Number (2 bytes)

:

Assigned Number (4 bytes)

1

IPv4 address (4 bytes)

:

Assigned Number (2 bytes)

2

AS Number (4 bytes)

:

Assigned Number (2 bytes)

The type field is 2 bytes, totaling 8 bytes for the RD.

You don’t have to specify the RD type within IOS though. The types are essentially just cosmetic, and used to give SPs a flexible way to adminstratively control the RD number space. The RD itself is really just a flat integer. BGP doesn’t care whether you are using type 0 or type 1 or you mix and match RD types for different VRFs. BGP just looks at the entire number overall, and uses that value prepended to the IPv4 prefix to consider it unique.

The RD is configured under the VRF itself in IOS-XE. In IOS-XR, the RD is configured under the VRF or under the VRF in BGP. (On XRv, you can only configure the RD in the BGP process, under the VRF. On XR9000v, you can also configure the RD under the VRF as you would in IOS-XE).

Router(config-vrf)#rd ?
  ASN:nn, IP-address:nn or 4BASN:nn  VPN Route Distinguisher
RP/0/0/CPU0:ios(config)#router bgp 123 vrf CUSTOMER_A
RP/0/0/CPU0:ios(config-bgp-vrf)#rd ?
  <1-65535>.<0-65535>:<0-65535>  4-byte AS number in asdot (X.Y) format
  <1-65535>:                     2-byte AS number
  <65536-4294967295>:            4-byte AS number in asplain format
  A.B.C.D:                       IPv4 address
  auto                           Automatic route distinguisher

Notice that IOS-XE gives you the three types you can configure the RD as, but you never actually specify the type code. So you wouldn’t do 1:1.2.3.4:100, you just use 1.2.3.4:100.

The context-sensitive help on IOS-XR can automatically determine whether your first field was a 2 byte AS, 4 byte AS, or IPv4 address:

RP/0/0/CPU0:ios(config-bgp-vrf)#rd 123:?
  <0-4294967295>  ASN2:index (hex or decimal format)
RP/0/0/CPU0:ios(config-bgp-vrf)#rd 66000:?
  <0-65535>  ASN4:index (hex or decimal format)

On IOS-XR, the type field is still not populated on the RD on BGP updates. The types are just a way for you to organize your RD values on all of your VRFs.

The RD is prepended to the IPv4 address only when advertised to vpnv4 peers. So instead of advertising 10.0.0.0/24, the PE advertises 123:100:10.0.0.0/24, or RD=123:100, prefix=10.0.0.0/24

Route Targets

The RD simply makes prefixes unique in the global vpnv4 or vpnv6 table. However, the RD doesn’t instruct a PE to import the associated routes into a VRF. That is the purpose of a route-target.

You may wonder, why do we need route targets at all? Why can’t we just match on the RD of the prefix, and import routes with the same RD into the VRF?

The reason is that sometimes we might want import routes from one VRF into multiple VRFs. This might happen if you have a “shared services” VRF, and you want to import routes from the shared services VRF into every other VRF.

You can’t do that with RD, since each VRF gets only a single RD value. Instead you would define multiple import route target values on each VRF.

Another reason you don’t want to use RD for importing prefixes into a VRF, is that each PE is free to use a different RD for the same VRF for the purpose of traffic engineering. We’ll look at this scenario in a later section in more detail.

The route target is an extended community in BGP. This is just extra information about the route that needs to be carried in the BGP update.

The export route target(s) are added to the BGP update when the PE advertises the route to its RR.

The import route target(s) are used to match on BGP updates that contain those RT values. The PE imports the matching routes into the VRF locally.

The types of route targets are the same as the RD types we saw earlier:

Type

Field 1

Colon

Field 2

0

AS Number (2 bytes)

:

Assigned Number (4 bytes)

1

IPv4 address (4 bytes)

:

Assigned Number (2 bytes)

2

AS Number (4 bytes)

:

Assigned Number (2 bytes)

The difference is that the type is actually specified in the extended community.

IOS-XE and IOS-XR still do not make you specify the route-target type. The router can determine the type from the value that you use:

Router(config-vrf)#route-target ?
  ASN:nn or IP-address:nn  Target VPN Extended Community
  both                     Both import and export Target-VPN community
  export                   Export Target-VPN community
  import                   Import Target-VPN community

RP/0/0/CPU0:ios(config-vrf-af)#import route-target ?
  <1-65535>:           2-byte AS number
  <65536-4294967295>:  4-byte AS number in asplain format
  A.B.C.D:             IPv4 address
  <cr>

When the PE advertises a vpnv4 route to the RR, the extended community is present, with the associated type (0, 1, or 2).

RD and RT Configuration Examples

IOS-XE

vrf definition SHARED
 rd 123:1
 route-target export 123:1
 route-target import 123:100
 route-target import 123:101
 !
 address-family ipv4
 exit-address-family
!
vrf definition CUSTOMER_A
 rd 123:100
 route-target export 123:100
 route-target import 123:100
 route-target import 123:1
 !
 address-family ipv4
 exit-address-family
!
vrf definition CUSTOMER_B
 rd 123:101
 route-target export 123:101
 route-target import 123:101
 route-target import 123:1
 !
 address-family ipv4
 exit-address-family

IOS-XR

vrf SHARED
 address-family ipv4 unicast
  import route-target
   123:100
	 123:101
  !
  export route-target
   123:1
  !
 !
!
vrf CUSTOMER_A
 address-family ipv4 unicast
  import route-target
   123:1
	 123:100
  !
  export route-target
   123:100
  !
 !
!
vrf CUSTOMER_B
 address-family ipv4 unicast
  import route-target
   123:1
	 123:101
  !
  export route-target
   123:101
  !
 !
!
router bgp 123 vrf CUSTOMER_A
 rd 123:100
!
router bgp 123 vrf CUSTOMER_B
 rd 123:101
!
router bgp 123 vrf SHARED
 rd 123:1

In both of these examples, the SHARED VRF imports routes from both CUSTOMER_A and CUSTOMER_B. The two VRFs for CUSTOMER_A and CUSTOMER_B both import routes from the SHARED VRF.

Of couse, if there are overlapping routes in CUSTOMER_A and CUSTOMER_B, this will be a problem when they get imported into the SHARED VRF. In this case, you might use a route-policy to only import certain prefixes from the CUSTOMER VRFs into the SHARED VRFs, but this is beyond the scope of this article.

Lab

We’ll use this topology to explore how RD and RT work:

PE1, P3, and PE2 run OSPF, LDP, and iBGP. P3 is the RR. PE2 is an IOS-XR router.

PE1

interface Loopback0
 ip address 1.1.1.1 255.255.255.255
!
interface GigabitEthernet1
 ip address 10.1.3.1 255.255.255.0
 mpls ip
!
router ospf 1
 network 1.1.1.1 0.0.0.0 area 0
 network 10.1.3.0 0.0.0.255 area 0
!
router bgp 123
 bgp log-neighbor-changes
 neighbor 3.3.3.3 remote-as 123
 !
 address-family vpnv4
  neighbor 3.3.3.3 activate
  neighbor 3.3.3.3 send-community extended
 exit-address-family

P3

interface Loopback0
 ip address 3.3.3.3 255.255.255.255
!
interface GigabitEthernet1
 ip address 10.1.3.3 255.255.255.0
 mpls ip
!
interface GigabitEthernet2
 ip address 10.2.3.3 255.255.255.0
 mpls ip
!
router ospf 1
 network 3.3.3.3 0.0.0.0 area 0
 network 10.0.0.0 0.255.255.255 area 0
!
router bgp 123
 bgp log-neighbor-changes
 neighbor 1.1.1.1 remote-as 123
 neighbor 1.1.1.1 update-source Loopback0
 neighbor 2.2.2.2 remote-as 123
 neighbor 2.2.2.2 update-source Loopback0
 !
 address-family vpnv4
  neighbor 1.1.1.1 activate
  neighbor 1.1.1.1 send-community extended
  neighbor 1.1.1.1 route-reflector-client
  neighbor 2.2.2.2 activate
  neighbor 2.2.2.2 send-community extended
  neighbor 2.2.2.2 route-reflector-client
 exit-address-family
!

PE2


hostname PE2
interface Loopback0
 ipv4 address 2.2.2.2 255.255.255.255
!
interface GigabitEthernet0/0/0/0
 ipv4 address 10.2.3.2 255.255.255.0
!
router ospf 1
 area 0
  interface Loopback0
  !
  interface GigabitEthernet0/0/0/0
  !
 !
!
router bgp 123
 address-family vpnv4 unicast
 !
 neighbor 3.3.3.3
  remote-as 123
  update-source Loopback0
  address-family vpnv4 unicast
  !
 !
!
mpls ldp
 interface GigabitEthernet0/0/0/0
 !
!

Make sure that the iBGP sessions for the vpnv4 unicast address family are Established before proceeding:

P3#show bgp vpnv4 uni all sum
BGP router identifier 3.3.3.3, local AS number 123
BGP table version is 1, main routing table version 1

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
1.1.1.1         4          123      11      11        1    0    0 00:06:50        0
2.2.2.2         4          123       5       5        1    0    0 00:03:37        0

Let’s configure the PE-CE IPs as the following, with the PE having the lower IP in the /30 subnet:

We’ll first configure the CEs, and run eBGP with the PE:

#CE1 (CUSTOMER_A)
int Gi0/0
 ip address 100.64.1.2 255.255.255.252
 no shut
!
int lo0
 ip address 10.0.0.1 255.255.255.0
!
router bgp 65000
 bgp router-id 100.64.1.2
 neighbor 100.64.1.1 remote-as 123
 network 10.0.0.0 mask 255.255.255.0

#CE3 (CUSTOMER_A)
int Gi0/0
 ip address 100.64.1.6 255.255.255.252
 no shut
!
int lo0
 ip address 10.0.1.1 255.255.255.0
!
router bgp 65001
 bgp router-id 100.64.1.2
 neighbor 100.64.1.5 remote-as 123
 network 10.0.1.0 mask 255.255.255.0

#CE2 (CUSTOMER_B)
int Gi0/0
 ip address 100.64.2.2 255.255.255.252
 no shut
!
int lo0
 ip address 10.0.0.1 255.255.255.0
!
router bgp 65000
 bgp router-id 100.64.2.2
 neighbor 100.64.2.1 remote-as 123
 network 10.0.0.0 mask 255.255.255.0

#CE4 (CUSTOMER_B)
int Gi0/0
 ip address 100.64.2.6 255.255.255.252
 no shut
!
int lo0
 ip address 10.0.1.1 255.255.255.0
!
router bgp 65001
 bgp router-id 100.64.2.2
 neighbor 100.64.2.5 remote-as 123
 network 10.0.1.0 mask 255.255.255.0
 

Configuring PE1

Now we’ll define the VRFs on PE1, and enable BGP for the VRF, peering with the CEs. We’ll configure RD and RT values “normally” to start. 123:100 for CUSTOMER_A and 123:200 for CUSTOMER_B for both the RD and import/export RT.

#PE1
vrf definition CUSTOMER_A
 rd 123:100
 route-target export 123:100
 route-target import 123:100
 address-family ipv4 unicast
!
vrf definition CUSTOMER_B
 rd 123:200
 route-target export 123:200
 route-target import 123:200
 address-family ipv4 unicast
!
int Gi2
 vrf forwarding CUSTOMER_A
 ip address 100.64.1.1 255.255.255.252
 no shut
!
int Gi3
 vrf forwarding CUSTOMER_B
 ip address 100.64.2.1 255.255.255.252
 no shut
!
router bgp 123
 address-family ipv4 unicast vrf CUSTOMER_A
  neighbor 100.64.1.2 remote-as 65000
 address-family ipv4 unicast vrf CUSTOMER_B
  neighbor 100.64.2.2 remote-as 65000
!

On PE1 you should see routes received from the CEs:

PE1#show bgp vpnv4 unicast vrf CUSTOMER_A | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 123:100 (default for vrf CUSTOMER_A)
 *>   10.0.0.0/24      100.64.1.2               0             0 65000 i

PE1#show bgp vpnv4 unicast vrf CUSTOMER_B | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 123:200 (default for vrf CUSTOMER_B)
 *>   10.0.0.0/24      100.64.2.2               0             0 65000 i

PE1 will automatically advertise routes learned from the CEs into vpnv4 to the RR (P3)

P3#show bgp vpnv4 uni all | begin Network
     Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 123:100
 *>i  10.0.0.0/24      1.1.1.1                  0    100      0 65000 i
Route Distinguisher: 123:200
 *>i  10.0.0.0/24      1.1.1.1                  0    100      0 65000 i

Remember, vpnv4 is a global table. P3 has two routes for 10.0.0.0/24 but with different RDs (123:100 and 123:200).

Looking at PE1’s Update to P3

Here is the Update for the CUSTOMER_A route. As you can see, the RD does not have a type field. It is simply the value itself, 123:100. However, the RT does have a type field. The router determined that we are using type 0 (2 byte ASN: NN ) automatically, and set the type code on the ext community when advertising the Update.

You might wonder how the RR knows that the prefix 10.0.0.0 is a /24. The prefix length field on the NLRI is 112, so where does /24 come from?

The answer is that the prefix length is the total length of the label, RD, and IPv4 prefix. The lengths of all three are added together, but since the label and RD are fixed length, the router can determine the IPv4 prefix length. The label is always 3 bytes (24 bits), and the RD is always 8 bytes (64bits). Therefore, the router will subtract 88 (64 + 24) from the prefix length to determine the IPv4 prefix length. 112 - 88 = 24. This works because only the IPv4 prefix length is variable.

Configuring PE2

Before we configure PE2, let’s see if it has already learned the vpnv4 routes. Remember that we have already peered PE2 to P3 via iBGP, and since P3 is a RR, it should reflects the routes to PE2. Do you think PE2 will have two routes received?

The answer is no, it does not have any routes received so far:

RP/0/0/CPU0:PE2#show bgp vpnv4 uni sum | be Neigh  
Sun Jul 17 23:38:27.282 UTC
Neighbor        Spk    AS MsgRcvd MsgSent   TblVer  InQ OutQ  Up/Down  St/PfxRcd
3.3.3.3           0   123     486     438        1    0    0 07:16:26          0

Why is this? Shouldn’t P3 reflect the vpnv4 routes it has learned from PE1 to PE2, since both PEs are RR clients?

The answer to why PE2 has no recieved routes, is due to a feature that is enabled by default, called bgp route target filter. When this feature is enable, the router will filter out vpnv4 routes if it does not have a VRF that imports the route-targets of the received vpnv4 routes. This frees up memory, because the router is not storing Updates that it won’t use. What about P3 though? Why does the RR accept the route by default if it doesn’t have a VRF that imports the RT? This is because when you configure an RR (by configuring peers as clients), it automatically disables the route target filter.

Now we know that P3 is actually sending the routes to PE2 as it should, but PE2 filters them inbound since the route-target does not match an import route target of a locally configured VRF.

To prove this, let’s confirm that P3 is actually sending the routes to PE2:

P3#show bgp vpnv4 uni all neighbors 2.2.2.2 advertised-routes | be Network
     Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 123:100
 *>i  10.0.0.0/24      1.1.1.1                  0    100      0 65000 i
Route Distinguisher: 123:200
 *>i  10.0.0.0/24      1.1.1.1                  0    100      0 65000 i

Total number of prefixes 2 

Let’s configure only the VRFs on PE2 and see if PE2 will accept the routes immediately upon commit.

PE2#
vrf CUSTOMER_A
 address-family ipv4 unicast
  import route-target 123:100
  export route-target 123:100
!
vrf CUSTOMER_B
 address-family ipv4 unicast
  import route-target 123:200
  export route-target 123:200
!
commit

Simply configuring the VRFs with the import route-target instructs the router to stop filtering the vpnv4 routes received from the RR:

RP/0/0/CPU0:PE2#show bgp vpnv4 uni | be Network
Sun Jul 17 23:44:49.616 UTC
   Network            Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 123:100
*>i10.0.0.0/24        1.1.1.1                  0    100      0 65000 i
Route Distinguisher: 123:200
*>i10.0.0.0/24        1.1.1.1                  0    100      0 65000 i

Let’s now configure the interfaces and BGP. Remember that on IOS-XR, the RD is configured under BGP, not under the VRF. On IOS-XR we also need to activate the ipv4 unicast family globally before using it under a VRF. Finally we will need a route-policy since the CEs are eBGP peers.

int gi0/0/0/1
 ipv4 address 100.64.1.5/30
 vrf CUSTOMER_A
 no shut
!
int gi0/0/0/2
 ipv4 address 100.64.2.5/30
 vrf CUSTOMER_B
 no shut
!
router bgp 123
 address-family ipv4 unicast
!
router bgp 123 vrf CUSTOMER_A
 rd 123:100
 address-family ipv4 unicast
 neighbor 100.64.1.6
  remote-as 65001
  address-family ipv4 unicast
    route-policy PASS_ALL in
    route-policy PASS_ALL out
!
router bgp 123 vrf CUSTOMER_B
 rd 123:200
 address-family ipv4 unicast
 neighbor 100.64.2.6
  remote-as 65001
  address-family ipv4 unicast
    route-policy PASS_ALL in
    route-policy PASS_ALL out
!
route-policy PASS_ALL
 pass
end-policy

The RR now has two routes per RD:

P3#show bgp vpnv4 uni all | be Network
     Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 123:100
 *>i  10.0.0.0/24      1.1.1.1                  0    100      0 65000 i
 *>i  10.0.1.0/24      2.2.2.2                  0    100      0 65001 i
Route Distinguisher: 123:200
 *>i  10.0.0.0/24      1.1.1.1                  0    100      0 65000 i
 *>i  10.0.1.0/24      2.2.2.2                  0    100      0 65001 i

Our L3VPN service is now up and running. Feel free to verify that the CEs of each customer can reach other on their loopbacks (which are being advertised into BGP).

In part two, we’ll play around with RD and RT values and see how our changes impact the behaviour of BGP.

Last updated