diff options
| author | Russ White <russ@riw.us> | 2023-06-20 09:20:36 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-20 09:20:36 -0400 |
| commit | 4d9fb376c8c4feab96a9ea53e5da9c7d3ba91da1 (patch) | |
| tree | 3a50402c04d3883125c23614b8de1fb5ca63e6cf /bgpd/bgp_updgrp_adv.c | |
| parent | 554c2e0350f59bbdc4fb38fea91cafb13acdd319 (diff) | |
| parent | 78981a80c7457b96e73c108280577d4cbb8aee03 (diff) | |
Merge pull request #13728 from opensourcerouting/fix/addpath_drop_non_best_addpaths
bgpd: Implement neighbor X addpath-tx-best-selected command
Diffstat (limited to 'bgpd/bgp_updgrp_adv.c')
| -rw-r--r-- | bgpd/bgp_updgrp_adv.c | 92 |
1 files changed, 73 insertions, 19 deletions
diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index b412fa6b20..68fd11a042 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -87,6 +87,67 @@ static void adj_free(struct bgp_adj_out *adj) XFREE(MTYPE_BGP_ADJ_OUT, adj); } +static void +subgrp_announce_addpath_best_selected(struct bgp_dest *dest, + struct update_subgroup *subgrp) +{ + afi_t afi = SUBGRP_AFI(subgrp); + safi_t safi = SUBGRP_SAFI(subgrp); + struct peer *peer = SUBGRP_PEER(subgrp); + enum bgp_path_selection_reason reason; + char pfx_buf[PREFIX2STR_BUFFER] = {}; + int paths_eq = 0; + int best_path_count = 0; + struct list *list = list_new(); + struct bgp_path_info *pi = NULL; + + if (peer->addpath_type[afi][safi] == BGP_ADDPATH_BEST_SELECTED) { + while (best_path_count++ < + peer->addpath_best_selected[afi][safi]) { + struct bgp_path_info *exist = NULL; + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; + pi = pi->next) { + if (listnode_lookup(list, pi)) + continue; + + if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) + continue; + + if (bgp_path_info_cmp(peer->bgp, pi, exist, + &paths_eq, NULL, 0, + pfx_buf, afi, safi, + &reason)) + exist = pi; + } + + if (exist) + listnode_add(list, exist); + } + } + + for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { + uint32_t id = bgp_addpath_id_for_peer(peer, afi, safi, + &pi->tx_addpath); + + if (peer->addpath_type[afi][safi] == + BGP_ADDPATH_BEST_SELECTED) { + if (listnode_lookup(list, pi)) + subgroup_process_announce_selected( + subgrp, pi, dest, afi, safi, id); + else + subgroup_process_announce_selected( + subgrp, NULL, dest, afi, safi, id); + } else { + subgroup_process_announce_selected(subgrp, pi, dest, + afi, safi, id); + } + } + + if (list) + list_delete(&list); +} + static void subgrp_withdraw_stale_addpath(struct updwalk_context *ctx, struct update_subgroup *subgrp) { @@ -125,7 +186,6 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg) { struct updwalk_context *ctx = arg; struct update_subgroup *subgrp; - struct bgp_path_info *pi; afi_t afi; safi_t safi; struct peer *peer; @@ -143,7 +203,6 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg) bgp_dest_to_rnode(ctx->dest)); UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) { - /* * Skip the subgroups that have coalesce timer running. We will * walk the entire prefix table for those subgroups when the @@ -155,19 +214,8 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg) if (addpath_capable) { subgrp_withdraw_stale_addpath(ctx, subgrp); - for (pi = bgp_dest_get_bgp_path_info(ctx->dest); - pi; pi = pi->next) { - /* Skip the bestpath for now */ - if (pi == ctx->pi) - continue; - - subgroup_process_announce_selected( - subgrp, pi, ctx->dest, afi, - safi, - bgp_addpath_id_for_peer( - peer, afi, safi, - &pi->tx_addpath)); - } + subgrp_announce_addpath_best_selected(ctx->dest, + subgrp); /* Process the bestpath last so the "show [ip] * bgp neighbor x.x.x.x advertised" @@ -689,6 +737,10 @@ void subgroup_announce_table(struct update_subgroup *subgrp, SET_FLAG(subgrp->sflags, SUBGRP_STATUS_TABLE_REPARSING); for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) { + + if (addpath_capable) + subgrp_announce_addpath_best_selected(dest, subgrp); + for (ri = bgp_dest_get_bgp_path_info(dest); ri; ri = ri->next) { if (!bgp_check_selected(ri, peer, addpath_capable, afi, @@ -706,10 +758,12 @@ void subgroup_announce_table(struct update_subgroup *subgrp, is_default_prefix(bgp_dest_get_prefix(dest))) break; - subgroup_process_announce_selected( - subgrp, ri, dest, afi, safi_rib, - bgp_addpath_id_for_peer(peer, afi, safi_rib, - &ri->tx_addpath)); + if (CHECK_FLAG(ri->flags, BGP_PATH_SELECTED)) + subgroup_process_announce_selected( + subgrp, ri, dest, afi, safi_rib, + bgp_addpath_id_for_peer( + peer, afi, safi_rib, + &ri->tx_addpath)); } } UNSET_FLAG(subgrp->sflags, SUBGRP_STATUS_TABLE_REPARSING); |
