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