From: Louis Scalbert Date: Fri, 29 Apr 2022 12:26:04 +0000 (+0200) Subject: bgpd: fix prefix VRF leaking with 'network import-check' (4/5) X-Git-Tag: base_8.5~109^2~18 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=1e24860bf7042a96bc0f22df60f73e7aa04f31f6;p=mirror%2Ffrr.git bgpd: fix prefix VRF leaking with 'network import-check' (4/5) If 'network import-check' is defined on the source BGP session, prefixes that are stated in the network command cannot be leaked to the other VRFs BGP table even if they are present in the origin VRF RIB if the 'rt import' statement is defined after the 'network ' ones. When a prefix nexthop is updated, update the prefix route leaking. The current state of nexthop validation is now stored in the attributes of the bgp path info. Attributes are compared with the previous ones at route leaking update so that a nexthop validation change now triggers the update of destination VRF BGP table. Signed-off-by: Louis Scalbert --- diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 337a82b945..47775e1412 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -866,6 +866,7 @@ bool attrhash_cmp(const void *p1, const void *p2) && attr1->df_pref == attr2->df_pref && attr1->df_alg == attr2->df_alg && attr1->nh_ifindex == attr2->nh_ifindex + && attr1->nh_flag == attr2->nh_flag && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex && attr1->distance == attr2->distance && srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn) diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index a34da1a6de..575b10541e 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -170,6 +170,9 @@ struct attr { uint32_t med; uint32_t local_pref; ifindex_t nh_ifindex; + uint8_t nh_flag; + +#define BGP_ATTR_NH_VALID 0x01 /* Path origin attribute */ uint8_t origin; diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 84fbfbe259..42ae3562c2 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1878,6 +1878,7 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ uint32_t num_labels = 0; int nexthop_self_flag = 1; struct bgp_path_info *bpi_ultimate = NULL; + struct bgp_path_info *bpi; int origin_local = 0; struct bgp *src_vrf; @@ -1960,6 +1961,18 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */ community_strip_accept_own(&static_attr); + for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { + if (bpi->extra && bpi->extra->parent == path_vpn) + break; + } + + if (bpi && + leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi, + path_vpn, bpi, src_vrf, p, debug)) + SET_FLAG(static_attr.nh_flag, BGP_ATTR_NH_VALID); + else + UNSET_FLAG(static_attr.nh_flag, BGP_ATTR_NH_VALID); + /* * Nexthop: stash and clear * diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 78482aeb40..d7707a8c0c 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -46,6 +46,7 @@ #include "bgpd/bgp_flowspec_util.h" #include "bgpd/bgp_evpn.h" #include "bgpd/bgp_rd.h" +#include "bgpd/bgp_mplsvpn.h" extern struct zclient *zclient; @@ -834,10 +835,13 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) { struct bgp_nexthop_cache_head *tree = NULL; struct bgp_nexthop_cache *bnc_nhc, *bnc_import; + struct bgp_path_info *pi; + struct bgp_dest *dest; struct bgp *bgp; struct prefix match; struct zapi_route nhr; afi_t afi; + safi_t safi; bgp = bgp_lookup_by_vrf_id(vrf_id); if (!bgp) { @@ -868,9 +872,23 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id) tree = &bgp->import_check_table[afi]; bnc_import = bnc_find(tree, &match, nhr.srte_color, 0); - if (bnc_import) + if (bnc_import) { bgp_process_nexthop_update(bnc_import, &nhr, true); - else if (BGP_DEBUG(nht, NHT)) + + safi = nhr.safi; + if (bgp->rib[afi][safi]) { + dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, + &match, NULL); + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; + pi = pi->next) + if (pi->peer == bgp->peer_self && + pi->type == ZEBRA_ROUTE_BGP && + pi->sub_type == BGP_ROUTE_STATIC) + vpn_leak_from_vrf_update( + bgp_get_default(), bgp, pi); + } + } else if (BGP_DEBUG(nht, NHT)) zlog_debug( "parse nexthop update(%pFX(%u)(%s)): bnc info not found for import check", &nhr.prefix, nhr.srte_color, bgp->name_pretty);