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 <prefix>' 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 <louis.scalbert@6wind.com>
This commit is contained in:
Louis Scalbert 2022-04-29 14:26:04 +02:00
parent d0a55f87e9
commit 1e24860bf7
4 changed files with 37 additions and 2 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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
*

View File

@ -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);