Yesterday I posted a tricky question to Twitter. If you have a working VPNv4 environment and create a VRF with only a Route Distinguisher (RD) but without Route Targets (RT), will the route be exported? The answer may surprise you! The configuration supplied in the question was similar to the one below:
vrf definition QUIZ rd 198.51.100.1:100 ! address-family ipv4 exit-address-family ! interface GigabitEthernet2 vrf forwarding QUIZ ip address 203.0.113.1 255.255.255.0 ! router bgp 65000 ! address-family ipv4 vrf QUIZ network 203.0.113.0
Notice how this VRF has a RD but no RT. Will this router, PE1, advertise the route into VPNv4? Most would say no, but the answer is yes. Let’s first check that we see the route locally on PE1 in VRF QUIZ:
PE1#show bgp vpnv4 uni vrf QUIZ 203.0.113.0 BGP routing table entry for 198.51.100.1:100:203.0.113.0/24, version 4 Paths: (1 available, best #1, table QUIZ) Advertised to update-groups: 1 Refresh Epoch 1 Local 0.0.0.0 (via vrf QUIZ) from 0.0.0.0 (198.51.100.1) Origin IGP, metric 0, localpref 100, weight 32768, valid, sourced, local, best mpls labels in/out 18/nolabel(QUIZ) rx pathid: 0, tx pathid: 0x0 Updated on Jan 2 2024 06:32:17 UTC
The route is there but has no RT. Is it being advertised?
PE1#show bgp vpnv4 uni all nei 198.51.100.2 adv 203.0.113.0/24 Route Distinguisher: 198.51.100.1:100 (default for vrf QUIZ) BGP routing table entry for 198.51.100.1:100:203.0.113.0/24, version 4 Paths: (1 available, best #1, table QUIZ) Advertised Attributes Local Preference: 100 Metric: 0 Origin: IGP Nexthop: 198.51.100.1
Yes, it is being advertised. Without RT, PE2 will not import it, though:
*Jan 2 06:37:17.920: BGP(4): 198.51.100.1 rcvd UPDATE w/ attr: nexthop 198.51.100.1, origin i, localpref 100, metric 0 *Jan 2 06:37:17.921: BGP(4): 198.51.100.1 rcvd 198.51.100.1:100:203.0.113.0/24, label 18 (0x12) -- DENIED due to: extended community not supported;
A packet capture shows the VPNv4 update and that there is no RT:
Now let’s add the RT at PE1:
PE1(config)#vrf definition QUIZ PE1(config-vrf)#route-target both 65000:100
This prefix now has an RT:
PE1#show bgp vpnv4 uni all 203.0.113.0 BGP routing table entry for 198.51.100.1:100:203.0.113.0/24, version 7 Paths: (1 available, best #1, table QUIZ) Advertised to update-groups: 1 Refresh Epoch 1 Local 0.0.0.0 (via vrf QUIZ) from 0.0.0.0 (198.51.100.1) Origin IGP, metric 0, localpref 100, weight 32768, valid, sourced, local, best Extended Community: RT:65000:100 mpls labels in/out 18/nolabel(QUIZ) rx pathid: 0, tx pathid: 0x0 Updated on Jan 2 2024 06:42:05 UTC
The debug shows that the prefix is now being imported on PE2:
*Jan 2 06:42:05.962: BGP(4): 198.51.100.1 rcvd UPDATE w/ attr: nexthop 198.51.100.1, origin i, localpref 100, metric 0, extended community RT:65000:100 *Jan 2 06:42:05.962: BGP(4): 198.51.100.1 rcvd 198.51.100.1:100:203.0.113.0/24, label 18 (0x12) *Jan 2 06:42:05.963: BGP VPN-IMP: VPNv4 Unicast:base 198.51.100.1:100:203.0.113.0/24 Marking path (passed into bestpath). *Jan 2 06:42:05.969: BGP: IMP Process work queue. *Jan 2 06:42:05.969: BGP: tbl VPNv4 Unicast:base IMP Incremental export. *Jan 2 06:42:05.969: BGP VPN-IMP: VPNv4 Unicast:base 198.51.100.1:100:203.0.113.0/24 Exporting doing PATHS. *Jan 2 06:42:05.972: BGP VPN-IMP: VPNv4 Unicast:base Building ETL from VPN *Jan 2 06:42:05.972: BGP VPN-IMP: VPNv4 Unicast:base GBL Building ETL. *Jan 2 06:42:05.972: BGP VPN-IMP: VPNv4 Unicast:base -> global:IPv4 Unicast:base Creating Import Topo. *Jan 2 06:42:05.972: BGP VPN-IMP: VPNv4 Unicast:base -> global:IPv4 Unicast:base GBL Adding topology IPv4 Unicast to ETL. *Jan 2 06:42:05.972: BGP VPN-IMP: VPNv4 Unicast:base -> global:IPv4 Multicast:base Creating Import Topo. *Jan 2 06:42:05.972: BGP VPN-IMP: VPNv4 Unicast:base -> global:IPv4 Multicast:base GBL Adding to ETL. *Jan 2 06:42:05.972: BGP VPN-IMP: VPNv4 Unicast:base Building GBL ETL done. *Jan 2 06:42:05.973: BGP VPN-IMP: VPNv4 Unicast:base Before adding to ETL bgp_topo_afi 0, is found *Jan 2 06:42:05.973: BGP VPN-IMP: VPNv4 Unicast:base -> QUIZ:VPNv4 Unicast:base Adding to ETL. *Jan 2 06:42:05.973: BGP VPN-IMP: VPNv4 Unicast:base 198.51.100.1:100:203.0.113.0/24 -> IPv4 Multicast:base Not importing in new table, not importing any paths. *Jan 2 06:42:05.973: BGP VPN-IMP: VPNv4 Unicast:base 198.51.100.1:100:203.0.113.0/24 -> IPv4 Unicast:base Not importing in new table, not importing any paths. *Jan 2 06:42:05.973: BGP VPN-IMP: global:VPNv4 Unicast:base 198.51.100.1:100:203.0.113.0/24 -> QUIZ:base Creating importing net. *Jan 2 06:42:05.973: BGP VPN-IMP: QUIZ:VPNv4 Unicast:base 198.51.100.2:100:203.0.113.0/24 -> base Importing net created. *Jan 2 06:42:05.974: BGP VPN-IMP: global:VPNv4 Unicast:base 198.51.100.1:100:203.0.113.0/24 198.51.100.1 -> QUIZ:base Called path modify. *Jan 2 06:42:05.974: BGP VPN-IMP: global:VPNv4 Unicast:base 198.51.100.1:100:203.0.113.0/24 198.51.100.1 -> QUIZ:base Imported new path nexthop (198.51.100.1) *Jan 2 06:42:05.974: BGP VPN-IMP: global:VPNv4 Unicast:base 198.51.100.1:100:203.0.113.0/24 198.51.100.1 -> QUIZ:base Creating imported path id 0. *Jan 2 06:42:05.974: BGP VPN-IMP: VPNv4 Unicast:base Export time record 5 (0) msec for net 198.51.100.1:100:203.0.113.0/24 (1/3). *Jan 2 06:42:05.974: BGP: IMP Work queue processed. *Jan 2 06:42:05.975: BGP(4): Revise route installing 1 of 1 routes for 203.0.113.0/24 -> 198.51.100.1(QUIZ) to QUIZ IP table
The prefix is indeed in the BGP table now on PE2:
PE2#show bgp vpnv4 uni vrf QUIZ 203.0.113.0 BGP routing table entry for 198.51.100.2:100:203.0.113.0/24, version 3 Paths: (1 available, best #1, table QUIZ) Flag: 0x100 Not advertised to any peer Refresh Epoch 2 Local, imported path from 198.51.100.1:100:203.0.113.0/24 (global) 198.51.100.1 (metric 3) (via default) from 198.51.100.1 (198.51.100.1) Origin IGP, metric 0, localpref 100, valid, internal, best Extended Community: RT:65000:100 mpls labels in/out nolabel/18 rx pathid: 0, tx pathid: 0x0 Updated on Jan 2 2024 06:42:05 UTC
It has also been installed into the RIB:
PE2#show ip route vrf QUIZ Routing Table: QUIZ Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2 E1 - OSPF external type 1, E2 - OSPF external type 2, m - OMP n - NAT, Ni - NAT inside, No - NAT outside, Nd - NAT DIA i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2 ia - IS-IS inter area, * - candidate default, U - per-user static route H - NHRP, G - NHRP registered, g - NHRP registration summary o - ODR, P - periodic downloaded static route, l - LISP a - application route + - replicated route, % - next hop override, p - overrides from PfR & - replicated local route overrides by connected Gateway of last resort is not set B 203.0.113.0/24 [200/0] via 198.51.100.1, 00:19:37
For completeness, here is BGP Update from packet capture now that RT has been set:
What did we learn? Be careful with assumptions. One would assume that RT is mandatory to get a route exported, but it’s not. Obviously another router won’t be able to import the route but it will be advertised. What we went through today will give you a deeper understanding of VPNv4 and being less focused on working configurations and more focused on how all the pieces interact.
In case you are interested in testing something similar, I have posted my initial configurations below. My test setup was a simple topology of three routers, PE1, P1, and PE2, running in CML:
PE1:
hostname PE1 ! vrf definition QUIZ rd 198.51.100.1:100 ! address-family ipv4 exit-address-family ! interface Loopback0 ip address 198.51.100.1 255.255.255.255 ip ospf 1 area 0 ! interface GigabitEthernet1 ip address 192.0.2.1 255.255.255.254 ip ospf network point-to-point ip ospf 1 area 0 mpls ip ! interface GigabitEthernet2 vrf forwarding QUIZ ip address 203.0.113.1 255.255.255.0 ! router ospf 1 ! router bgp 65000 bgp log-neighbor-changes no bgp default ipv4-unicast neighbor 198.51.100.2 remote-as 65000 neighbor 198.51.100.2 update-source Loopback0 ! address-family ipv4 exit-address-family ! address-family vpnv4 neighbor 198.51.100.2 activate neighbor 198.51.100.2 send-community extended exit-address-family ! address-family ipv4 vrf QUIZ network 203.0.113.0 exit-address-family
P1:
hostname P1 ! interface GigabitEthernet1 ip address 192.0.2.0 255.255.255.254 ip ospf network point-to-point ip ospf 1 area 0 mpls ip ! interface GigabitEthernet2 ip address 192.0.2.2 255.255.255.254 ip ospf network point-to-point ip ospf 1 area 0 mpls ip ! router ospf 1
PE2:
hostname PE2 ! vrf definition QUIZ rd 198.51.100.2:100 route-target export 65000:100 route-target import 65000:100 ! address-family ipv4 exit-address-family ! interface Loopback0 ip address 198.51.100.2 255.255.255.255 ip ospf 1 area 0 ! interface GigabitEthernet1 ip address 192.0.2.3 255.255.255.254 ip ospf network point-to-point ip ospf 1 area 0 mpls ip ! router ospf 1 ! router bgp 65000 bgp log-neighbor-changes no bgp default ipv4-unicast neighbor 198.51.100.1 remote-as 65000 neighbor 198.51.100.1 update-source Loopback0 ! address-family ipv4 exit-address-family ! address-family vpnv4 neighbor 198.51.100.1 activate neighbor 198.51.100.1 send-community extended exit-address-family
Thanks Daniel, I have learnt a lot from this exercise.
Awesome! It’s a tricky one. I learned a bit myself.
nice, this question itsef is tricky 😉 . if the question was like “what if there is no RT, will vpnv4 route be exchanged in route-table: 😀
Thanks for bringing it up.
Here, route will be advertized, but remote PE has policy that says, check BGP Adj-rib in and if routes matches extended community ( Import RT), then accept.
Thanks! Tricky inded. I would probably have gotten it wrong myself if I hadn’t tested it 🙂
If you have a network statement and there’s a matching route for that network in the RIB, it will get advertised. Normal BGP behavior.
This does not scale well in larger LSP deployments with thousands of customer VRF’s with PE’s having to potentially process hundreds of thousands of prefixes for which no VRF is importing on.
To mitigate this issue, SAFI 132(route target constrain) was encoded into the VPNv4 implementation.
When the rt-filter address-family is enabled, the RR will only forward prefixes to another PE if it is importing on them.
Not sure how RTC would work with direct PE-PE peering(your lab) as I have never done it.
As a matter of fact I don’t think I’ve ever seen it either without the RR(s) in the middle.
Great, now I’m going to have to lab it up or I won’t sleep tonight. Needing empirical proof for everything can be a real PITA sometimes. You know what I mean?
I know what you mean! I think that is a common trait for people that excel at what they do that they spend time researching things until they feel they have come to an end.
I think I have a RTC blog post from some years ago.
Btw, my test is not probably representative for how things SHOULD work, but how it does work on this one implementation. Interesting nonetheless.
Long time awaited but I tired this lab in EVE-NG Cisco IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(2)T.
Unless I attached the RT under the vrf statement the route was not advt to the neighbor.
Daniel:
After reading numerous incorrect public posts by Cisco employees on this same topic–and shaking my head at them–I came across your write-up while doing a lab in Cisco Modeling Labs (C.M.L.).
Yes, the route is exported.
One thing to add to what you have written, however, is that the route will be imported via VPNv4 or -v6 if a V.R.F. definition on the receiving router has the same route distinguisher (at least using IOSv version 15). I can send you my C.M.L. file if you would like. (Cisco hosts C.M.L. gratis in its cloud for anyone with a C.C.O. ID.)
This presents a serious security issue in, e.g., inter-A.S. M.P.L.S. A well-positioned attacker could inject a route into another customer’s V.R.F…
And within an A.S. or B.G.P. confederation–where a consistent RD for each customer is possible and arguably advisable–this behavior largely, if not entirely, negates the need to define route-targets for most customers’ M.P.L.S. networks.
With regards from across the Atlantic,
by /s/ Martin “MartyG” Gottesfeld, **alleged** Anonymous hacker and Rolling Stone’s “Hacker Who Cared Too Much.”
Upon further inspection, the import occurs when using “no bgp default route-target filter”.
That said, various Cisco documents direct the use of “no bgp default route-target filter” in specific circumstances for inter-A.S. M.P.L.S. See, e.g., https://www.cisco.com/c/en/us/td/docs/switches/lan/catalyst9300/software/release/17-4/configuration_guide/mpls/b_174_mpls_9300_cg/configuring_mpls_vpn_interas_options.html (specifying to enter “no bgp default route-target filter” in “Configuring InterAS Option B using the Next-Hop-Self Method”).
Thus “no bgp default route-target filter” is likely used in the wild in a non-trivial number of sensitive places.
To address the security implications, Cisco likely should, e.g., provide a way to specify a manual route-target filter. As it stands, one must either use the automatic filter or disable route-target filtering entirely. The result is that whenever the automatic filter presents an issue, filtering is likely to be disabled entirely.
And I have not tested absent “no bgp default route-target filter.” The route **may** be imported even without it. See, e.g., https://community.cisco.com/t5/mpls/bgp-default-route-target-filter/td-p/1162402 (a Cisco employee wrote, “This check is disabled by default on a VPNv4 [route reflector] because by definition it has to re-transmit to his clients any updates received from a MP-eBGP peer or another client.” (alteration [] added)).
–MartyG.