From 56bcfabd2edcc4457d9c6753ec66e62e6358cc4d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 4 Mar 2024 10:41:13 -0500 Subject: [PATCH] bgpd: Add pi to bgp_process This will allow a consistency of approach to adding/removing pi's to from the workqueue for processing as well as properly handling the dest->info pi list more appropriately. Signed-off-by: Donald Sharp --- bgpd/bgp_damp.c | 4 +-- bgpd/bgp_evpn.c | 24 +++++++-------- bgpd/bgp_evpn_mh.c | 8 ++--- bgpd/bgp_label.c | 2 +- bgpd/bgp_mplsvpn.c | 14 ++++----- bgpd/bgp_nht.c | 2 +- bgpd/bgp_route.c | 77 ++++++++++++++++++++-------------------------- bgpd/bgp_route.h | 3 +- bgpd/bgp_vty.c | 9 ++++-- bgpd/bgp_zebra.c | 2 +- bgpd/bgpd.c | 16 +++++++--- bgpd/rfapi/rfapi.c | 6 ++-- 12 files changed, 85 insertions(+), 82 deletions(-) diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 7893884fa651..6b6387b1b517 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -150,7 +150,7 @@ static void bgp_reuse_timer(struct event *t) bgp_aggregate_increment( bgp, bgp_dest_get_prefix(bdi->dest), bdi->path, bdi->afi, bdi->safi); - bgp_process(bgp, bdi->dest, bdi->afi, + bgp_process(bgp, bdi->dest, bdi->path, bdi->afi, bdi->safi); } @@ -308,7 +308,7 @@ void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw, afi_t afi, if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) { bgp_path_info_delete(bdi->dest, path); - bgp_process(path->peer->bgp, bdi->dest, afi, safi); + bgp_process(path->peer->bgp, bdi->dest, path, afi, safi); } XFREE(MTYPE_BGP_DAMP_INFO, bdi); diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 8f9a4dbab2f2..fc077ebd17de 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1424,7 +1424,7 @@ static void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn, * this table. */ if (pi) - bgp_process(bgp, global_dest, afi, safi); + bgp_process(bgp, global_dest, pi, afi, safi); bgp_dest_unlock_node(global_dest); } @@ -1725,7 +1725,7 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, /* schedule for processing and unlock node */ if (route_changed) { - bgp_process(bgp_evpn, dest, afi, safi); + bgp_process(bgp_evpn, dest, pi, afi, safi); bgp_dest_unlock_node(dest); } @@ -2273,7 +2273,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, false /* setup_sync */, NULL /* old_is_sync */); /* Schedule for processing and unlock node. */ - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, global_pi, afi, safi); bgp_dest_unlock_node(dest); } @@ -2333,7 +2333,7 @@ static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp) delete_evpn_route_entry(bgp_evpn, afi, safi, dest, &pi); if (pi) - bgp_process(bgp_evpn, dest, afi, safi); + bgp_process(bgp_evpn, dest, pi, afi, safi); bgp_dest_unlock_node(dest); return 0; } @@ -2373,7 +2373,7 @@ static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, * this table. */ if (pi) - bgp_process(bgp, global_dest, afi, safi); + bgp_process(bgp, global_dest, pi, afi, safi); bgp_dest_unlock_node(global_dest); } @@ -2536,7 +2536,7 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, NULL /* old_is_sync */); /* Schedule for processing and unlock node. */ - bgp_process(bgp, global_dest, afi, safi); + bgp_process(bgp, global_dest, global_pi, afi, safi); bgp_dest_unlock_node(global_dest); } @@ -2621,7 +2621,7 @@ static void delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) delete_evpn_route_entry(bgp, afi, safi, dest, &pi); if (pi) - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, pi, afi, safi); } /* Unlock RD node. */ @@ -3075,7 +3075,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, safi); /* Perform route selection and update zebra, if required. */ - bgp_process(bgp_vrf, dest, afi, safi); + bgp_process(bgp_vrf, dest, pi, afi, safi); /* Process for route leaking. */ vpn_leak_from_vrf_update(bgp_get_default(), bgp_vrf, pi); @@ -3437,7 +3437,7 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, bgp_evpn_path_nh_del(bgp_vrf, pi); /* Perform route selection and update zebra, if required. */ - bgp_process(bgp_vrf, dest, afi, safi); + bgp_process(bgp_vrf, dest, pi, afi, safi); /* Unlock route node. */ bgp_dest_unlock_node(dest); @@ -4434,7 +4434,7 @@ static void update_advertise_vni_route(struct bgp *bgp, struct bgpevpn *vpn, } /* Schedule for processing and unlock node. */ - bgp_process(bgp, global_dest, afi, safi); + bgp_process(bgp, global_dest, global_pi, afi, safi); bgp_dest_unlock_node(global_dest); } @@ -4484,7 +4484,7 @@ static void update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) false /* setup_sync */, NULL /* old_is_sync */); /* Schedule for processing and unlock node. */ - bgp_process(bgp, global_dest, afi, safi); + bgp_process(bgp, global_dest, pi, afi, safi); bgp_dest_unlock_node(global_dest); } @@ -4529,7 +4529,7 @@ static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) * this table. */ if (pi) - bgp_process(bgp, global_dest, afi, safi); + bgp_process(bgp, global_dest, pi, afi, safi); bgp_dest_unlock_node(global_dest); } diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index d88c52d1f6d9..9347adea767a 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -511,7 +511,7 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es, * this table. */ if (pi) - bgp_process(bgp, global_dest, afi, safi); + bgp_process(bgp, global_dest, pi, afi, safi); bgp_dest_unlock_node(global_dest); } @@ -562,7 +562,7 @@ int delete_global_ead_evi_routes(struct bgp *bgp, struct bgpevpn *vpn) delete_evpn_route_entry(bgp, afi, safi, bd, &pi); if (pi) - bgp_process(bgp, bd, afi, safi); + bgp_process(bgp, bd, pi, afi, safi); } } @@ -686,7 +686,7 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp, attr_new, &global_pi, &route_changed); /* Schedule for processing and unlock node. */ - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, global_pi, afi, safi); bgp_dest_unlock_node(dest); } @@ -1025,7 +1025,7 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp, struct bgp_evpn_es *es, attr_new, &global_pi, &route_changed); /* Schedule for processing and unlock node. */ - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, global_pi, afi, safi); bgp_dest_unlock_node(dest); } diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c index 7327ab51826a..68104967b2fd 100644 --- a/bgpd/bgp_label.c +++ b/bgpd/bgp_label.c @@ -74,7 +74,7 @@ int bgp_parse_fec_update(void) bgp_set_valid_label(&dest->local_label); } SET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, NULL, afi, safi); bgp_dest_unlock_node(dest); return 1; } diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 91bc3b1a888e..a0fed85d3b9a 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1201,7 +1201,7 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, /* Process change. */ bgp_aggregate_increment(to_bgp, p, bpi, afi, safi); - bgp_process(to_bgp, bn, afi, safi); + bgp_process(to_bgp, bn, bpi, afi, safi); if (debug) zlog_debug("%s: ->%s: %pBD Found route, changed attr", @@ -1263,7 +1263,7 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn, bgp_aggregate_increment(to_bgp, p, new, afi, safi); bgp_path_info_add(bn, new); - bgp_process(to_bgp, bn, afi, safi); + bgp_process(to_bgp, bn, new, afi, safi); if (debug) zlog_debug("%s: ->%s: %pBD: Added new route", __func__, @@ -1949,7 +1949,7 @@ void vpn_leak_from_vrf_withdraw(struct bgp *to_bgp, /* to */ bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi); bgp_path_info_delete(bn, bpi); - bgp_process(to_bgp, bn, afi, safi); + bgp_process(to_bgp, bn, bpi, afi, safi); } bgp_dest_unlock_node(bn); } @@ -2005,7 +2005,7 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *to_bgp, struct bgp *from_bgp, to_bgp, bgp_dest_get_prefix(bn), bpi, afi, safi); bgp_path_info_delete(bn, bpi); - bgp_process(to_bgp, bn, afi, safi); + bgp_process(to_bgp, bn, bpi, afi, safi); bgp_mplsvpn_path_nh_label_unlink( bpi->extra->vrfleak->parent); } @@ -2499,7 +2499,7 @@ void vpn_leak_to_vrf_withdraw(struct bgp_path_info *path_vpn) bpi); bgp_aggregate_decrement(bgp, p, bpi, afi, safi); bgp_path_info_delete(bn, bpi); - bgp_process(bgp, bn, afi, safi); + bgp_process(bgp, bn, bpi, afi, safi); } bgp_dest_unlock_node(bn); } @@ -2531,7 +2531,7 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi) bgp_dest_get_prefix(bn), bpi, afi, safi); bgp_path_info_delete(bn, bpi); - bgp_process(to_bgp, bn, afi, safi); + bgp_process(to_bgp, bn, bpi, afi, safi); } } } @@ -4182,7 +4182,7 @@ static int bgp_mplsvpn_nh_label_bind_get_local_label_cb(mpls_label_t label, if (!table) continue; SET_FLAG(pi->net->flags, BGP_NODE_LABEL_CHANGED); - bgp_process(table->bgp, pi->net, table->afi, table->safi); + bgp_process(table->bgp, pi->net, pi, table->afi, table->safi); } return 0; diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 786d07c5a946..8d7c08928489 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -1432,7 +1432,7 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc) } } - bgp_process(bgp_path, dest, afi, safi); + bgp_process(bgp_path, dest, path, afi, safi); } if (peer) { diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index e22e2ddb9926..252742c2d6de 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2882,6 +2882,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest, (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) { enum bgp_path_selection_reason reason; + UNSET_FLAG(pi->flags, BGP_PATH_UNSORTED); if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) old_select = pi; @@ -3733,13 +3734,22 @@ static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp) return pqnode; } -void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi) +void bgp_process(struct bgp *bgp, struct bgp_dest *dest, + struct bgp_path_info *pi, afi_t afi, safi_t safi) { #define ARBITRARY_PROCESS_QLEN 10000 struct work_queue *wq = bgp->process_queue; struct bgp_process_queue *pqnode; int pqnode_reuse = 0; + /* + * Indicate that *this* pi is in an unsorted + * situation, even if the node is already + * scheduled. + */ + if (pi) + SET_FLAG(pi->flags, BGP_PATH_UNSORTED); + /* already scheduled for processing? */ if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) return; @@ -3988,7 +3998,7 @@ void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi, } hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true); - bgp_process(peer->bgp, dest, afi, safi); + bgp_process(peer->bgp, dest, pi, afi, safi); } static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi, @@ -4593,7 +4603,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, != BGP_DAMP_SUPPRESSED) { bgp_aggregate_increment(bgp, p, pi, afi, safi); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, pi, afi, safi); } } else /* Duplicate - odd */ { @@ -4621,7 +4631,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_path_info_unset_flag( dest, pi, BGP_PATH_STALE); bgp_dest_set_defer_flag(dest, false); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, pi, afi, safi); } } @@ -4911,7 +4921,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Process change. */ bgp_aggregate_increment(bgp, p, pi, afi, safi); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, pi, afi, safi); bgp_dest_unlock_node(dest); if (SAFI_UNICAST == safi @@ -5056,7 +5066,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, hook_call(bgp_process, bgp, afi, safi, dest, peer, false); /* Process change. */ - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, new, afi, safi); if (SAFI_UNICAST == safi && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF @@ -6564,7 +6574,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, /* Process change. */ bgp_aggregate_increment(bgp, p, pi, afi, safi); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, pi, afi, safi); if (SAFI_MPLS_VPN == safi && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) { @@ -6622,7 +6632,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p, bgp_dest_unlock_node(dest); /* Process change. */ - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, new, afi, safi); if (SAFI_UNICAST == safi && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || @@ -6679,7 +6689,7 @@ void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi, bgp_aggregate_decrement(bgp, p, pi, afi, safi); bgp_unlink_nexthop(pi); bgp_path_info_delete(dest, pi); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, pi, afi, safi); } /* Unlock bgp_node_lookup. */ @@ -7080,7 +7090,7 @@ static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi, safi); bgp_unlink_nexthop(pi); bgp_path_info_delete(dest, pi); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, pi, afi, safi); } } } @@ -7469,7 +7479,7 @@ static void bgp_aggregate_install( SET_FLAG(new->flags, BGP_PATH_VALID); bgp_path_info_add(dest, new); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, new, afi, safi); } else { uninstall_aggregate_route: for (pi = orig; pi; pi = pi->next) @@ -7481,7 +7491,7 @@ static void bgp_aggregate_install( /* Withdraw static BGP route from routing table. */ if (pi) { bgp_path_info_delete(dest, pi); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, pi, afi, safi); } } @@ -7567,7 +7577,6 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, const struct prefix *dest_p; struct bgp_dest *dest, *top; struct bgp_path_info *pi; - bool toggle_suppression; /* We've found a different MED we must revert any suppressed routes. */ top = bgp_node_get(table, p); @@ -7577,7 +7586,6 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, if (dest_p->prefixlen <= p->prefixlen) continue; - toggle_suppression = false; for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { if (BGP_PATH_HOLDDOWN(pi)) continue; @@ -7588,17 +7596,14 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, if (suppress) { /* Suppress route if not suppressed already. */ if (aggr_suppress_path(aggregate, pi)) - toggle_suppression = true; + bgp_process(bgp, dest, pi, afi, safi); continue; } /* Install route if there is no more suppression. */ if (aggr_unsuppress_path(aggregate, pi)) - toggle_suppression = true; + bgp_process(bgp, dest, pi, afi, safi); } - - if (toggle_suppression) - bgp_process(bgp, dest, afi, safi); } bgp_dest_unlock_node(top); } @@ -7657,7 +7662,6 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, struct ecommunity *ecommunity = NULL; struct lcommunity *lcommunity = NULL; struct bgp_path_info *pi; - unsigned long match = 0; uint8_t atomic_aggregate = 0; /* If the bgp instance is being deleted or self peer is deleted @@ -7707,8 +7711,6 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, if (!bgp_check_advertise(bgp, dest, safi)) continue; - match = 0; - for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { if (BGP_PATH_HOLDDOWN(pi)) continue; @@ -7732,7 +7734,7 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) { if (aggr_suppress_path(aggregate, pi)) - match++; + bgp_process(bgp, dest, pi, afi, safi); } /* @@ -7748,7 +7750,7 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, && AGGREGATE_MED_VALID(aggregate) && aggr_suppress_map_test(bgp, aggregate, pi)) { if (aggr_suppress_path(aggregate, pi)) - match++; + bgp_process(bgp, dest, pi, afi, safi); } aggregate->count++; @@ -7809,8 +7811,6 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, aggregate, bgp_attr_get_lcommunity(pi->attr)); } - if (match) - bgp_process(bgp, dest, afi, safi); } if (aggregate->as_set) { bgp_compute_aggregate_aspath_val(aggregate); @@ -7870,7 +7870,6 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi, struct bgp_dest *top; struct bgp_dest *dest; struct bgp_path_info *pi; - unsigned long match; table = bgp->rib[afi][safi]; @@ -7882,7 +7881,6 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi, if (dest_p->prefixlen <= p->prefixlen) continue; - match = 0; for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { if (BGP_PATH_HOLDDOWN(pi)) @@ -7900,7 +7898,7 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi, if (pi->extra && pi->extra->aggr_suppressors && listcount(pi->extra->aggr_suppressors)) { if (aggr_unsuppress_path(aggregate, pi)) - match++; + bgp_process(bgp, dest, pi, afi, safi); } aggregate->count--; @@ -7942,10 +7940,6 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi, pi->attr)); } } - - /* If this node was suppressed, process the change. */ - if (match) - bgp_process(bgp, dest, afi, safi); } if (aggregate->as_set) { aspath_free(aggregate->aspath); @@ -8094,7 +8088,6 @@ static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi, struct community *community = NULL; struct ecommunity *ecommunity = NULL; struct lcommunity *lcommunity = NULL; - unsigned long match = 0; /* If the bgp instance is being deleted or self peer is deleted * then do not create aggregate route @@ -8111,12 +8104,12 @@ static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi, if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) if (aggr_unsuppress_path(aggregate, pi)) - match++; + bgp_process(bgp, pi->net, pi, afi, safi); if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate) && aggr_suppress_map_test(bgp, aggregate, pi)) if (aggr_unsuppress_path(aggregate, pi)) - match++; + bgp_process(bgp, pi->net, pi, afi, safi); /* * This must be called after `summary`, `suppress-map` check to avoid @@ -8158,10 +8151,6 @@ static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi, aggregate, bgp_attr_get_lcommunity(pi->attr)); } - /* If this node was suppressed, process the change. */ - if (match) - bgp_process(bgp, pi->net, afi, safi); - origin = BGP_ORIGIN_IGP; if (aggregate->incomplete_origin_count > 0) origin = BGP_ORIGIN_INCOMPLETE; @@ -8771,7 +8760,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, /* Process change. */ bgp_aggregate_increment(bgp, p, bpi, afi, SAFI_UNICAST); - bgp_process(bgp, bn, afi, SAFI_UNICAST); + bgp_process(bgp, bn, bpi, afi, SAFI_UNICAST); bgp_dest_unlock_node(bn); aspath_unintern(&attr.aspath); @@ -8794,7 +8783,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p, bgp_path_info_add(bn, new); bgp_dest_unlock_node(bn); SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED); - bgp_process(bgp, bn, afi, SAFI_UNICAST); + bgp_process(bgp, bn, new, afi, SAFI_UNICAST); if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF) || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) { @@ -8835,7 +8824,7 @@ void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type, } bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST); bgp_path_info_delete(dest, pi); - bgp_process(bgp, dest, afi, SAFI_UNICAST); + bgp_process(bgp, dest, pi, afi, SAFI_UNICAST); } bgp_dest_unlock_node(dest); } @@ -8869,7 +8858,7 @@ void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type, bgp_path_info_delete(dest, pi); if (!CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) - bgp_process(bgp, dest, afi, SAFI_UNICAST); + bgp_process(bgp, dest, pi, afi, SAFI_UNICAST); else { dest = bgp_path_info_reap(dest, pi); assert(dest); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 1aad5c4c8e96..25eb0755eba3 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -802,7 +802,8 @@ extern void bgp_withdraw(struct peer *peer, const struct prefix *p, struct bgp_route_evpn *evpn); /* for bgp_nexthop and bgp_damp */ -extern void bgp_process(struct bgp *, struct bgp_dest *, afi_t, safi_t); +extern void bgp_process(struct bgp *bgp, struct bgp_dest *dest, + struct bgp_path_info *pi, afi_t afi, safi_t safi); /* * Add an end-of-initial-update marker to the process queue. This is just a diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index b1f6e2d82874..cf2b40079c0a 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10713,7 +10713,10 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name, if (rm_p->prefixlen == match.prefixlen) { SET_FLAG(rm->flags, BGP_NODE_USER_CLEAR); - bgp_process(bgp, rm, afi, safi); + bgp_process(bgp, rm, + bgp_dest_get_bgp_path_info( + rm), + afi, safi); } bgp_dest_unlock_node(rm); } @@ -10725,7 +10728,9 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name, if (dest_p->prefixlen == match.prefixlen) { SET_FLAG(dest->flags, BGP_NODE_USER_CLEAR); - bgp_process(bgp, dest, afi, safi); + bgp_process(bgp, dest, + bgp_dest_get_bgp_path_info(dest), + afi, safi); } bgp_dest_unlock_node(dest); } diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 26194f8601ba..329c89f845f2 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1981,7 +1981,7 @@ bool bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red, bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED); - bgp_process(bgp, dest, afi, SAFI_UNICAST); + bgp_process(bgp, dest, pi, afi, SAFI_UNICAST); } } } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 57a59f2de09e..fb9f360154b5 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1850,6 +1850,7 @@ void bgp_peer_conf_if_to_su_update(struct peer_connection *connection) void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi, safi_t safi) { struct bgp_dest *dest, *ndest; + struct bgp_path_info *pi, *next; struct bgp_table *table; for (dest = bgp_table_top(bgp->rib[afi][safi]); dest; @@ -1864,10 +1865,17 @@ void bgp_recalculate_afi_safi_bestpaths(struct bgp *bgp, afi_t afi, safi_t safi) if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) { for (ndest = bgp_table_top(table); ndest; - ndest = bgp_route_next(ndest)) - bgp_process(bgp, ndest, afi, safi); - } else - bgp_process(bgp, dest, afi, safi); + ndest = bgp_route_next(ndest)) { + for (pi = bgp_dest_get_bgp_path_info(ndest); + (pi != NULL) && (next = pi->next, 1); + pi = next) + bgp_process(bgp, ndest, pi, afi, safi); + } + } else { + for (pi = bgp_dest_get_bgp_path_info(dest); + (pi != NULL) && (next = pi->next, 1); pi = next) + bgp_process(bgp, dest, pi, afi, safi); + } } } diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c index 382af05c245a..ae899daf82d3 100644 --- a/bgpd/rfapi/rfapi.c +++ b/bgpd/rfapi/rfapi.c @@ -463,7 +463,7 @@ void del_vnc_route(struct rfapi_descriptor *rfd, bgp_aggregate_decrement(bgp, p, bpi, afi, safi); bgp_path_info_delete(bn, bpi); - bgp_process(bgp, bn, afi, safi); + bgp_process(bgp, bn, bpi, afi, safi); } else { vnc_zlog_debug_verbose( "%s: Couldn't find route (safi=%d) at prefix %pFX", @@ -1001,7 +1001,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ /* Process change. */ bgp_aggregate_increment(bgp, p, bpi, afi, safi); - bgp_process(bgp, bn, afi, safi); + bgp_process(bgp, bn, bpi, afi, safi); bgp_dest_unlock_node(bn); vnc_zlog_debug_any( @@ -1046,7 +1046,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */ } bgp_dest_unlock_node(bn); - bgp_process(bgp, bn, afi, safi); + bgp_process(bgp, bn, new, afi, safi); vnc_zlog_debug_any( "%s: Added route (safi=%s) at prefix %s (bn=%p, prd=%pRDP)",