summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_attr.c1
-rw-r--r--bgpd/bgp_attr.h3
-rw-r--r--bgpd/bgp_mplsvpn.c17
-rw-r--r--bgpd/bgp_nht.c24
4 files changed, 40 insertions, 5 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 75aa2ac7c..edfbc6c83 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -864,6 +864,7 @@ bool attrhash_cmp(const void *p1, const void *p2)
attr1->df_alg == attr2->df_alg &&
attr1->nh_ifindex == attr2->nh_ifindex &&
attr1->nh_lla_ifindex == attr2->nh_lla_ifindex &&
+ attr1->nh_flags == attr2->nh_flags &&
attr1->distance == attr2->distance &&
srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn) &&
srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn) &&
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index d30155e6d..5a39f734d 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -155,6 +155,9 @@ struct attr {
uint32_t med;
uint32_t local_pref;
ifindex_t nh_ifindex;
+ uint8_t nh_flags;
+
+#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 2353910ea..32436861f 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -2090,6 +2090,7 @@ static void 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;
struct interface *ifp;
@@ -2179,6 +2180,20 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
community_strip_accept_own(&static_attr);
+ bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL);
+
+ for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
+ if (bpi->extra && bpi->extra->vrfleak &&
+ bpi->extra->vrfleak->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_flags, BGP_ATTR_NH_VALID);
+ else
+ UNSET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID);
+
/*
* Nexthop: stash and clear
*
@@ -2271,8 +2286,6 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
new_attr = bgp_attr_intern(&static_attr);
bgp_attr_flush(&static_attr);
- bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL);
-
/*
* ensure labels are copied
*
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index dbf1fd2ea..b6697568c 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -903,7 +903,10 @@ void bgp_nexthop_update(struct vrf *vrf, struct prefix *match,
{
struct bgp_nexthop_cache_head *tree = NULL;
struct bgp_nexthop_cache *bnc_nhc, *bnc_import;
- struct bgp *bgp;
+ struct bgp *bgp, *bgp_default;
+ struct bgp_path_info *pi;
+ struct bgp_dest *dest;
+ safi_t safi;
afi_t afi;
if (!vrf->info) {
@@ -928,9 +931,24 @@ void bgp_nexthop_update(struct vrf *vrf, struct prefix *match,
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))
+
+ bgp_default = bgp_get_default();
+ safi = nhr->safi;
+ if (bgp != bgp_default && 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_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);