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