From 3840a8193ea9dcc3a8b61cd4a5d890879878986e Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 7 Jun 2022 22:12:07 +0300 Subject: [PATCH] bgpd: Withdraw implicitly old paths from VRFs when import/export list changes If we overwrite import/export RT list via route-maps or even flush by using `set extcommunity none`, then we must withdraw old paths from VRFs to avoid stale paths. For example using: ``` router bgp 65500 vrf vrf1 bgp router-id 10.180.1.1 ! address-family ipv4 unicast network 192.168.100.100/32 route-map rm rd vpn export 65500:10001 rt vpn import 65500:10000 65500:10990 rt vpn export 65500:10000 export vpn import vpn exit-address-family exit ! router bgp 65500 vrf vrf2 bgp router-id 10.180.1.1 ! address-family ipv4 unicast rd vpn export 65500:11001 rt vpn import 65500:11000 65500:11990 rt vpn export 65500:11000 export vpn import vpn exit-address-family exit ! route-map rm permit 10 set extcommunity rt 65500:10100 65500:12990 65500:13990 65500:11990 exit ``` If we strip extcommunities using: ``` route-map rm permit 10 set extcommunity none exit ``` or ``` route-map rm permit 10 set extcommunity rt 65500:10100 65500:12990 65500:13990 ``` Routes that are imported with 65500:11990 (192.168.100.100/32 from vrf1) becomes stale. Signed-off-by: Donatas Abraitis --- bgpd/bgp_mplsvpn.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index d1a6daa8f5..23d554c05c 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -844,6 +844,26 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ return NULL; } + /* If the RT was changed via extended communities as an + * import/export list, we should withdraw implicitly the old + * path from VRFs. + * For instance, RT list was modified using route-maps: + * route-map test permit 10 + * set extcommunity rt none + */ + if (CHECK_FLAG(bpi->attr->flag, + ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) && + CHECK_FLAG(new_attr->flag, + ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) { + if (!ecommunity_cmp( + bgp_attr_get_ecommunity(bpi->attr), + bgp_attr_get_ecommunity(new_attr))) { + vpn_leak_to_vrf_withdraw(bgp, bpi); + bgp_aggregate_decrement(bgp, p, bpi, afi, safi); + bgp_path_info_delete(bn, bpi); + } + } + /* attr is changed */ bgp_path_info_set_flag(bn, bpi, BGP_PATH_ATTR_CHANGED);