MPLS

RD vs RT: The Most Confused Concepts in MPLS L3VPN

Route distinguisher vs route target: the same prefix under two RDs with different route targets
In: MPLS, BGP

Ask ten network engineers to explain the difference between a route distinguisher and a route target and you will get four confident wrong answers, three "they're basically the same thing," and maybe three correct ones. The confusion is understandable: they look identical (65000:1), they are configured three lines apart, and in a simple any-to-any VPN they are usually set to the same value.

They do completely unrelated jobs. This article proves it with a single BGP table containing the same prefix twice. If you need the surrounding configuration, see MPLS L3VPN configuration step by step and the MPLS cluster guide.

One Sentence Each

Route Distinguisher (RD)
Makes a prefix unique so two customers can both use 10.20.20.0/24 without BGP treating them as the same route. Part of the route's identity. Carried in the NLRI.
Route Target (RT)
Decides who gets the route. An extended community tagged on export and filtered on import. Carried as a BGP attribute. This is what builds VPN topology.

Or, more bluntly: RD is identity, RT is policy. The RD answers "which route is this?" The RT answers "which VRFs should install it?"

Everything else in this article is a consequence of those two sentences.

The Problem the RD Solves

BGP carries routes. A route is a prefix plus attributes. If two customers both use 10.20.20.0/24 (and they will, because RFC 1918 space is not that big and everyone picks 10.x), then BGP sees two updates for the same prefix, runs the best-path algorithm, picks one, and throws the other away. Customer B's route is gone.

The route distinguisher fixes this by making the prefix longer. An RD is 64 bits. Glue it to the front of a 32-bit IPv4 prefix and you get a 96-bit VPNv4 prefix:

IPv4 prefix   :               10.20.20.0/24
RD            : 65000:1
VPNv4 prefix  : 65000:1:10.20.20.0/24     <-- what BGP actually carries

Now customer A's route is 65000:1:10.20.20.0/24 and customer B's is 65000:2:10.20.20.0/24. Different prefixes. BGP keeps both. No best-path contest, no lost route.

That is the entire job. The RD is a uniqueness prefix. It carries no meaning, controls nothing, and is not used in any import or export decision.

Seeing it in one table

This is PE1 from the lab. VRF CUST-A (RD 65000:1) has learned 10.20.20.0/24 from the remote site over MP-BGP. VRF CUST-B (RD 65000:2) has 10.20.20.0/24 as a directly connected interface. Same prefix, same router, same BGP table:

PE1#show ip bgp vpnv4 all
     Network          Next Hop            Metric LocPrf Weight Path
Route Distinguisher: 65000:1 (default for vrf CUST-A)
 *>   1.1.1.1/32       10.20.1.2                0             0 65001 i
 *>i  2.2.2.2/32       10.255.0.2               0    100      0 65001 i
 *>   10.20.1.0/30     0.0.0.0                  0         32768 ?
 *>i  10.20.2.0/30     10.255.0.2               0    100      0 ?
 *>i  10.20.20.0/24    10.255.0.2               0    100      0 65001 i
 *>   192.168.99.0     10.20.1.2                0             0 65001 i
Route Distinguisher: 65000:2 (default for vrf CUST-B)
 *>   10.20.20.0/24    0.0.0.0                  0         32768 ?
 *>i  10.20.99.0/24    10.255.0.2               0    100      0 ?

Both 10.20.20.0/24 entries are present, both marked best (*>). Nothing was suppressed. Without the RD, one of them would be gone.

Drill into the prefix and the mechanism is explicit:

PE1#show ip bgp vpnv4 all 10.20.20.0/24
BGP routing table entry for 65000:1:10.20.20.0/24, version 13
Paths: (1 available, best #1, table CUST-A)
    10.255.0.2 (metric 21) (via default) from 10.255.0.2 (10.255.0.2)
      Origin incomplete, metric 0, localpref 100, valid, internal, best
      Extended Community: RT:65000:1
      mpls labels in/out nolabel/22

BGP routing table entry for 65000:2:10.20.20.0/24, version 2
Paths: (1 available, best #1, table CUST-B)
    0.0.0.0 (via vrf CUST-B) from 0.0.0.0 (10.255.0.1)
      Origin incomplete, metric 0, localpref 100, weight 32768, valid, sourced, best
      Extended Community: RT:65000:2
      mpls labels in/out 19/nolabel(CUST-B)

Two distinct BGP table entries, keyed by 65000:1:10.20.20.0/24 and 65000:2:10.20.20.0/24. Each carries its own RT and its own VPN label. And the forwarding follows straight through:

PE1#show ip route vrf CUST-A 10.20.20.0 255.255.255.0
Routing entry for 10.20.20.0/24
  Known via "bgp 65000", distance 200, metric 0, type internal
  * 10.255.0.2 (default), from 10.255.0.2
      MPLS label: 22
      MPLS Flags: MPLS Required

PE1#show ip route vrf CUST-B 10.20.20.0 255.255.255.0
Routing entry for 10.20.20.0/24
  Known via "connected", distance 0, metric 0 (connected, via interface)
  * directly connected, via Loopback11

Identical destination address, one router, two entirely different forwarding decisions. In CUST-A the packet gets VPN label 22 and crosses the MPLS core to PE2. In CUST-B it goes out a local interface. Neither customer knows the other exists.

The Problem the RT Solves

The RD made the routes unique. It did not decide who should receive them. That is the route target's job.

An RT is a BGP extended community, an 8-byte tag attached to the route as an attribute. It works in two halves:

route-target export 65000:1"When I send a route out of this VRF, stamp it with RT 65000:1."
route-target import 65000:1"When a VPNv4 route arrives carrying RT 65000:1, install it in this VRF."

That is the whole mechanism, and it is more powerful than it looks. Import and export lists are independent, and each can hold multiple values. The set of RTs a VRF exports and imports is the VPN topology:

Any-to-any (full mesh)
Every site exports RT 65000:1 and imports RT 65000:1. Everyone sees everyone.
Hub and spoke
Spokes export RT 1 and import RT 2. Hub exports RT 2 and imports RT 1. Spokes reach the hub; spokes cannot reach each other.
Extranet / shared services
The shared-services VRF exports RT 999. Every customer VRF adds import 999 alongside its own RT. Everyone reaches the shared service; nobody reaches each other.

Not one line of that requires touching the RD. You build hub-and-spoke, extranets, management VRFs, and selective route leaking purely by editing import and export lists. This is why the RT is the interesting one and the RD is the plumbing.

Break the RT Import and Watch the VPN Die

Theory is cheap. Here is the same lab with one line removed from PE1's CUST-A VRF:

PE1(config)# vrf definition CUST-A
PE1(config-vrf)#  address-family ipv4
PE1(config-vrf-af)#   no route-target import 65000:1

The export is still there. The RD is unchanged. The BGP session is untouched. Watch what happens:

PE1#show vrf detail CUST-A | include Export|Import|VRF
VRF CUST-A (VRF Id = 1); default RD 65000:1; default VPNID <not set>
  Export VPN route-target communities
  No Import VPN route-target communities
  VRF label distribution protocol: not configured

PE1#show ip bgp vpnv4 all summary
Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.20.1.2       4        65001       6      12       43    0    0 00:01:33        2
10.255.0.2      4        65000      24      19       43    0    0 00:07:35        1

PE1#show ip bgp vpnv4 rd 65000:1 10.20.20.0/24
BGP routing table entry for 65000:1:10.20.20.0/24, version 42
Paths: (0 available, no best path)
  Not advertised to any peer

Three things to read there. No Import VPN route-target communities is the smoking gun. The prefix count from the remote PE has collapsed from 4 to 1, because the RT filter is now rejecting almost everything at the door. And the prefix entry still exists in the table but with 0 available, no best path: BGP knows about the route, it just has no VRF willing to accept it.

From the customer's point of view, the VPN is simply broken:

j@llmbits:~$ ping -c 3 10.20.20.1
PING 10.20.20.1 (10.20.20.1) 56(84) bytes of data.
From 192.168.99.1 icmp_seq=1 Destination Host Unreachable
From 192.168.99.1 icmp_seq=2 Destination Host Unreachable
From 192.168.99.1 icmp_seq=3 Destination Host Unreachable

--- 10.20.20.1 ping statistics ---
3 packets transmitted, 0 received, +3 errors, 100% packet loss

MP-BGP is up. LDP is up. The IGP is up. The routes are being advertised. And the customer cannot pass a packet, because one import statement is missing. This is the single most common L3VPN misconfiguration, and the reason show vrf detail should be the second command you run when a VPN is broken. There is a full methodology in Troubleshooting MPLS L3VPN: where VPN routes go missing.

Because RTs are extended communities, they only survive the trip between PEs if the BGP session is configured to send them. Drop send-community extended from PE2's VPNv4 neighbor statement and the routes still get advertised, but with the RTs stripped off:

PE1#show ip bgp vpnv4 all summary
Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.255.0.2      4        65000      44      25       56    0    0 00:12:24        0

Zero prefixes received. Not because the session is down (it is up, and messages are flowing) but because every arriving route has no RT and therefore matches no import list. Same symptom as a missing import, different cause. Both live in the RT half of the world; neither has anything to do with the RD.

If They Do Different Jobs, Why Are They Usually the Same Number?

Because in a plain any-to-any VPN, one value works for both and nobody has a reason to complicate it. rd 65000:1, route-target both 65000:1, done.

The moment you build a hub-and-spoke or an extranet, they diverge, and the fact that they were never related becomes obvious. You will have one RD per VRF (often one per VRF per PE, which is a deliberate design for load-balancing and CE multihoming, since two different RDs on the same prefix let a route reflector keep both paths instead of picking one) and a whole set of RTs describing the topology.

The habit worth building: read rd as "identity" and route-target as "policy," even when the numbers match.

FAQ

Is the RD carried in BGP?

Yes, but as part of the prefix itself (the NLRI), not as an attribute. That is precisely why it makes the route unique. The RT is carried separately, as an extended community attribute.

Can two VRFs on the same PE use the same RD?

Technically yes if the prefixes never overlap, but do not. The RD's whole purpose is disambiguation; reusing it removes the safety net for zero benefit.

Can one VRF import multiple RTs?

Yes, and this is how extranets and shared services work. A VRF can import as many RTs as you like, and export more than one too.

Does the RD affect which VRF a route lands in?

No. That is the single most common misconception. Import is decided entirely by the RT. A route with the "wrong" RD but a matching RT will be imported; a route with a matching RD but no matching RT will not.

What format should I use?

ASN:number (65000:1) is by far the most common. IP:number (10.255.0.1:1) is also valid and is sometimes used so the RD identifies the originating PE at a glance.

Key Takeaways

  • RD is identity. It prepends 64 bits to the IPv4 prefix, making a 96-bit VPNv4 route so overlapping customer address space does not collide in BGP.
  • RT is policy. It is an extended community, stamped on export and filtered on import, and it alone decides which VRFs install a route.
  • The RD plays no part in import decisions. Ever.
  • VPN topology (any-to-any, hub-and-spoke, extranet) is built entirely from RT import and export lists.
  • A missing route-target import kills the VPN while every other check looks healthy. So does a missing send-community extended, because RTs are extended communities.
  • They are usually the same number in simple VPNs. That is a coincidence of convenience, not a relationship.

Next: build the whole thing from scratch, or read the MPLS cluster guide.

Written by
More from Ping Labz
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.