Merge pull request #4349 from donaldsharp/bgp_reason

Bgp reason
This commit is contained in:
Sri Mohana Singamsetty 2019-05-17 09:51:17 -07:00 committed by GitHub
commit 02f4c3ab5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 185 additions and 27 deletions

View File

@ -681,7 +681,7 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
json_path = json_object_new_array();
if (detail)
route_vty_out_detail(vty, bgp, &rn->p, pi,
route_vty_out_detail(vty, bgp, rn, pi,
AFI_L2VPN, SAFI_EVPN,
json_path);
else
@ -2090,7 +2090,7 @@ static void evpn_show_route_vni_multicast(struct vty *vty, struct bgp *bgp,
if (json)
json_path = json_object_new_array();
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
route_vty_out_detail(vty, bgp, rn, pi, afi, safi,
json_path);
if (json)
@ -2160,7 +2160,7 @@ static void evpn_show_route_vni_macip(struct vty *vty, struct bgp *bgp,
if (json)
json_path = json_object_new_array();
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
route_vty_out_detail(vty, bgp, rn, pi, afi, safi,
json_path);
if (json)
@ -2267,7 +2267,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
if (json)
json_path = json_object_new_array();
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
route_vty_out_detail(vty, bgp, rn, pi, afi, safi,
json_path);
if (json)
@ -2372,7 +2372,7 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
if (json)
json_path = json_object_new_array();
route_vty_out_detail(vty, bgp, &rn->p, pi, afi, safi,
route_vty_out_detail(vty, bgp, rn, pi, afi, safi,
json_path);
if (json)
@ -2522,7 +2522,7 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
if (detail) {
route_vty_out_detail(
vty, bgp, &rn->p, pi, AFI_L2VPN,
vty, bgp, rn, pi, AFI_L2VPN,
SAFI_EVPN, json_path);
} else
route_vty_out(vty, &rn->p, pi, 0,

View File

@ -434,7 +434,8 @@ void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf)
static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
struct bgp_path_info *exist, int *paths_eq,
struct bgp_maxpaths_cfg *mpath_cfg, int debug,
char *pfx_buf, afi_t afi, safi_t safi)
char *pfx_buf, afi_t afi, safi_t safi,
enum bgp_path_selection_reason *reason)
{
struct attr *newattr, *existattr;
bgp_peer_sort_t new_sort;
@ -463,6 +464,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
/* 0. Null check. */
if (new == NULL) {
*reason = bgp_path_selection_none;
if (debug)
zlog_debug("%s: new is NULL", pfx_buf);
return 0;
@ -472,6 +474,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
bgp_path_info_path_with_addpath_rx_str(new, new_buf);
if (exist == NULL) {
*reason = bgp_path_selection_first;
if (debug)
zlog_debug("%s: %s is the initial bestpath", pfx_buf,
new_buf);
@ -514,6 +517,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (newattr->sticky && !existattr->sticky) {
*reason = bgp_path_selection_evpn_sticky_mac;
if (debug)
zlog_debug(
"%s: %s wins over %s due to sticky MAC flag",
@ -522,6 +526,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (!newattr->sticky && existattr->sticky) {
*reason = bgp_path_selection_evpn_sticky_mac;
if (debug)
zlog_debug(
"%s: %s loses to %s due to sticky MAC flag",
@ -534,6 +539,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
exist_mm_seq = mac_mobility_seqnum(existattr);
if (new_mm_seq > exist_mm_seq) {
*reason = bgp_path_selection_evpn_seq;
if (debug)
zlog_debug(
"%s: %s wins over %s due to MM seq %u > %u",
@ -543,6 +549,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (new_mm_seq < exist_mm_seq) {
*reason = bgp_path_selection_evpn_seq;
if (debug)
zlog_debug(
"%s: %s loses to %s due to MM seq %u < %u",
@ -557,6 +564,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
*/
nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
if (nh_cmp < 0) {
*reason = bgp_path_selection_evpn_lower_ip;
if (debug)
zlog_debug(
"%s: %s wins over %s due to same MM seq %u and lower IP %s",
@ -565,6 +573,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
return 1;
}
if (nh_cmp > 0) {
*reason = bgp_path_selection_evpn_lower_ip;
if (debug)
zlog_debug(
"%s: %s loses to %s due to same MM seq %u and higher IP %s",
@ -579,6 +588,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
exist_weight = existattr->weight;
if (new_weight > exist_weight) {
*reason = bgp_path_selection_weight;
if (debug)
zlog_debug("%s: %s wins over %s due to weight %d > %d",
pfx_buf, new_buf, exist_buf, new_weight,
@ -587,6 +597,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (new_weight < exist_weight) {
*reason = bgp_path_selection_weight;
if (debug)
zlog_debug("%s: %s loses to %s due to weight %d < %d",
pfx_buf, new_buf, exist_buf, new_weight,
@ -603,6 +614,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
exist_pref = existattr->local_pref;
if (new_pref > exist_pref) {
*reason = bgp_path_selection_local_pref;
if (debug)
zlog_debug(
"%s: %s wins over %s due to localpref %d > %d",
@ -612,6 +624,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (new_pref < exist_pref) {
*reason = bgp_path_selection_local_pref;
if (debug)
zlog_debug(
"%s: %s loses to %s due to localpref %d < %d",
@ -627,6 +640,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
*/
if (!(new->sub_type == BGP_ROUTE_NORMAL ||
new->sub_type == BGP_ROUTE_IMPORTED)) {
*reason = bgp_path_selection_local_route;
if (debug)
zlog_debug(
"%s: %s wins over %s due to preferred BGP_ROUTE type",
@ -636,6 +650,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
if (!(exist->sub_type == BGP_ROUTE_NORMAL ||
exist->sub_type == BGP_ROUTE_IMPORTED)) {
*reason = bgp_path_selection_local_route;
if (debug)
zlog_debug(
"%s: %s loses to %s due to preferred BGP_ROUTE type",
@ -655,6 +670,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
aspath_hops += aspath_count_confeds(newattr->aspath);
if (aspath_hops < (exist_hops + exist_confeds)) {
*reason = bgp_path_selection_confed_as_path;
if (debug)
zlog_debug(
"%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
@ -665,6 +681,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (aspath_hops > (exist_hops + exist_confeds)) {
*reason = bgp_path_selection_confed_as_path;
if (debug)
zlog_debug(
"%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
@ -677,6 +694,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
int newhops = aspath_count_hops(newattr->aspath);
if (newhops < exist_hops) {
*reason = bgp_path_selection_as_path;
if (debug)
zlog_debug(
"%s: %s wins over %s due to aspath hopcount %d < %d",
@ -686,6 +704,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (newhops > exist_hops) {
*reason = bgp_path_selection_as_path;
if (debug)
zlog_debug(
"%s: %s loses to %s due to aspath hopcount %d > %d",
@ -698,6 +717,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
/* 5. Origin check. */
if (newattr->origin < existattr->origin) {
*reason = bgp_path_selection_origin;
if (debug)
zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
pfx_buf, new_buf, exist_buf,
@ -707,6 +727,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (newattr->origin > existattr->origin) {
*reason = bgp_path_selection_origin;
if (debug)
zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
pfx_buf, new_buf, exist_buf,
@ -732,6 +753,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
exist_med = bgp_med_value(exist->attr, bgp);
if (new_med < exist_med) {
*reason = bgp_path_selection_med;
if (debug)
zlog_debug(
"%s: %s wins over %s due to MED %d < %d",
@ -741,6 +763,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (new_med > exist_med) {
*reason = bgp_path_selection_med;
if (debug)
zlog_debug(
"%s: %s loses to %s due to MED %d > %d",
@ -756,6 +779,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
if (new_sort == BGP_PEER_EBGP
&& (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
*reason = bgp_path_selection_peer;
if (debug)
zlog_debug(
"%s: %s wins over %s due to eBGP peer > iBGP peer",
@ -765,6 +789,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
if (exist_sort == BGP_PEER_EBGP
&& (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
*reason = bgp_path_selection_peer;
if (debug)
zlog_debug(
"%s: %s loses to %s due to iBGP peer < eBGP peer",
@ -834,6 +859,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
if (new_sort == BGP_PEER_CONFED
&& exist_sort == BGP_PEER_IBGP) {
*reason = bgp_path_selection_confed;
if (debug)
zlog_debug(
"%s: %s wins over %s due to confed-external peer > confed-internal peer",
@ -843,6 +869,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
if (exist_sort == BGP_PEER_CONFED
&& new_sort == BGP_PEER_IBGP) {
*reason = bgp_path_selection_confed;
if (debug)
zlog_debug(
"%s: %s loses to %s due to confed-internal peer < confed-external peer",
@ -918,6 +945,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
"%s: %s loses to %s after IGP metric comparison",
pfx_buf, new_buf, exist_buf);
}
*reason = bgp_path_selection_igp_metric;
return ret;
}
@ -928,6 +956,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
if (!bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)
&& new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
*reason = bgp_path_selection_older;
if (debug)
zlog_debug(
"%s: %s wins over %s due to oldest external",
@ -936,6 +965,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
*reason = bgp_path_selection_older;
if (debug)
zlog_debug(
"%s: %s loses to %s due to oldest external",
@ -959,6 +989,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
exist_id.s_addr = exist->peer->remote_id.s_addr;
if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
*reason = bgp_path_selection_router_id;
if (debug)
zlog_debug(
"%s: %s wins over %s due to Router-ID comparison",
@ -967,6 +998,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
*reason = bgp_path_selection_router_id;
if (debug)
zlog_debug(
"%s: %s loses to %s due to Router-ID comparison",
@ -979,6 +1011,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
if (new_cluster < exist_cluster) {
*reason = bgp_path_selection_cluster_length;
if (debug)
zlog_debug(
"%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
@ -988,6 +1021,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (new_cluster > exist_cluster) {
*reason = bgp_path_selection_cluster_length;
if (debug)
zlog_debug(
"%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
@ -1001,6 +1035,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
* valid peer information (as the connection may or may not be up).
*/
if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
*reason = bgp_path_selection_stale;
if (debug)
zlog_debug(
"%s: %s wins over %s due to latter path being STALE",
@ -1009,6 +1044,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
*reason = bgp_path_selection_stale;
if (debug)
zlog_debug(
"%s: %s loses to %s due to former path being STALE",
@ -1017,14 +1053,19 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
/* locally configured routes to advertise do not have su_remote */
if (new->peer->su_remote == NULL)
if (new->peer->su_remote == NULL) {
*reason = bgp_path_selection_local_configured;
return 0;
if (exist->peer->su_remote == NULL)
}
if (exist->peer->su_remote == NULL) {
*reason = bgp_path_selection_local_configured;
return 1;
}
ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
if (ret == 1) {
*reason = bgp_path_selection_neighbor_ip;
if (debug)
zlog_debug(
"%s: %s loses to %s due to Neighor IP comparison",
@ -1033,6 +1074,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
}
if (ret == -1) {
*reason = bgp_path_selection_neighbor_ip;
if (debug)
zlog_debug(
"%s: %s wins over %s due to Neighor IP comparison",
@ -1040,6 +1082,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
return 1;
}
*reason = bgp_path_selection_default;
if (debug)
zlog_debug("%s: %s wins over %s due to nothing left to compare",
pfx_buf, new_buf, exist_buf);
@ -1053,12 +1096,13 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
* This version is compatible with */
int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
struct bgp_path_info *exist, char *pfx_buf,
afi_t afi, safi_t safi)
afi_t afi, safi_t safi,
enum bgp_path_selection_reason *reason)
{
int paths_eq;
int ret;
ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
afi, safi);
afi, safi, reason);
if (paths_eq)
ret = 0;
@ -1970,7 +2014,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
if (bgp_path_info_cmp(
bgp, pi2, new_select,
&paths_eq, mpath_cfg, debug,
pfx_buf, afi, safi)) {
pfx_buf, afi, safi,
&rn->reason)) {
bgp_path_info_unset_flag(
rn, new_select,
BGP_PATH_DMED_SELECTED);
@ -2043,7 +2088,7 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
bgp_path_info_unset_flag(rn, pi, BGP_PATH_DMED_CHECK);
if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
debug, pfx_buf, afi, safi)) {
debug, pfx_buf, afi, safi, &rn->reason)) {
new_select = pi;
}
}
@ -2099,7 +2144,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
}
bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
mpath_cfg, debug, pfx_buf, afi, safi);
mpath_cfg, debug, pfx_buf, afi, safi,
&rn->reason);
if (paths_eq) {
if (debug)
@ -7888,9 +7934,82 @@ static void route_vty_out_tx_ids(struct vty *vty,
}
}
void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
struct bgp_path_info *path, afi_t afi, safi_t safi,
json_object *json_paths)
static const char *bgp_path_selection_reason2str(
enum bgp_path_selection_reason reason)
{
switch (reason) {
case bgp_path_selection_none:
return "Nothing to Select";
break;
case bgp_path_selection_first:
return "First path received";
break;
case bgp_path_selection_evpn_sticky_mac:
return "EVPN Sticky Mac";
break;
case bgp_path_selection_evpn_seq:
return "EVPN sequence number";
break;
case bgp_path_selection_evpn_lower_ip:
return "EVPN lower IP";
break;
case bgp_path_selection_weight:
return "Weight";
break;
case bgp_path_selection_local_pref:
return "Local Pref";
break;
case bgp_path_selection_local_route:
return "Local Route";
break;
case bgp_path_selection_confed_as_path:
return "Confederation based AS Path";
break;
case bgp_path_selection_as_path:
return "AS Path";
break;
case bgp_path_selection_origin:
return "Origin";
break;
case bgp_path_selection_med:
return "MED";
break;
case bgp_path_selection_peer:
return "Peer Type";
break;
case bgp_path_selection_confed:
return "Confed Peer Type";
break;
case bgp_path_selection_igp_metric:
return "IGP Metric";
break;
case bgp_path_selection_older:
return "Older Path";
break;
case bgp_path_selection_router_id:
return "Router ID";
break;
case bgp_path_selection_cluster_length:
return "Cluser length";
break;
case bgp_path_selection_stale:
return "Path Staleness";
break;
case bgp_path_selection_local_configured:
return "Locally configured route";
break;
case bgp_path_selection_neighbor_ip:
return "Neighbor IP";
break;
case bgp_path_selection_default:
return "Nothing left to compare";
break;
}
}
void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct bgp_node *bn, struct bgp_path_info *path,
afi_t afi, safi_t safi, json_object *json_paths)
{
char buf[INET6_ADDRSTRLEN];
char buf1[BUFSIZ];
@ -7930,7 +8049,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
if (!json_paths && safi == SAFI_EVPN) {
char tag_buf[30];
bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
buf2, sizeof(buf2));
vty_out(vty, " Route %s", buf2);
tag_buf[0] = '\0';
if (path->extra && path->extra->num_labels) {
@ -8045,8 +8165,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
/* Line2 display Next-hop, Neighbor, Router-id */
/* Display the nexthop */
if ((p->family == AF_INET || p->family == AF_ETHERNET
|| p->family == AF_EVPN)
if ((bn->p.family == AF_INET || bn->p.family == AF_ETHERNET
|| bn->p.family == AF_EVPN)
&& (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
|| safi == SAFI_EVPN
|| !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
@ -8128,7 +8248,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
if (path->peer == bgp->peer_self) {
if (safi == SAFI_EVPN
|| (p->family == AF_INET
|| (bn->p.family == AF_INET
&& !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
if (json_paths)
json_object_string_add(
@ -8482,8 +8602,14 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
json_object_new_object();
json_object_boolean_true_add(json_bestpath,
"overall");
} else
json_object_string_add(json_bestpath,
"selectionReason",
bgp_path_selection_reason2str(bn->reason));
} else {
vty_out(vty, ", best");
vty_out(vty, " (%s)",
bgp_path_selection_reason2str(bn->reason));
}
}
if (json_bestpath)
@ -9495,7 +9621,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
BGP_PATH_MULTIPATH)
|| CHECK_FLAG(pi->flags,
BGP_PATH_SELECTED))))
route_vty_out_detail(vty, bgp, &rm->p,
route_vty_out_detail(vty, bgp, rm,
pi, AFI_IP, safi,
json_paths);
}
@ -9539,7 +9665,7 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
pi->flags,
BGP_PATH_SELECTED))))
route_vty_out_detail(
vty, bgp, &rn->p, pi,
vty, bgp, rn, pi,
afi, safi, json_paths);
}
}

View File

@ -588,7 +588,8 @@ extern void bgp_path_info_restore(struct bgp_node *rn,
extern int bgp_path_info_cmp_compatible(struct bgp *bgp,
struct bgp_path_info *new,
struct bgp_path_info *exist,
char *pfx_buf, afi_t afi, safi_t safi);
char *pfx_buf, afi_t afi, safi_t safi,
enum bgp_path_selection_reason *reason);
extern void bgp_attr_add_gshut_community(struct attr *attr);
extern void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
@ -604,7 +605,8 @@ extern void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
struct prefix_rd *prd, afi_t afi,
safi_t safi, json_object *json);
extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
struct prefix *p, struct bgp_path_info *path,
struct bgp_node *bn,
struct bgp_path_info *path,
afi_t afi, safi_t safi,
json_object *json_paths);
extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,

View File

@ -42,6 +42,31 @@ struct bgp_table {
uint64_t version;
};
enum bgp_path_selection_reason {
bgp_path_selection_none,
bgp_path_selection_first,
bgp_path_selection_evpn_sticky_mac,
bgp_path_selection_evpn_seq,
bgp_path_selection_evpn_lower_ip,
bgp_path_selection_weight,
bgp_path_selection_local_pref,
bgp_path_selection_local_route,
bgp_path_selection_confed_as_path,
bgp_path_selection_as_path,
bgp_path_selection_origin,
bgp_path_selection_med,
bgp_path_selection_peer,
bgp_path_selection_confed,
bgp_path_selection_igp_metric,
bgp_path_selection_older,
bgp_path_selection_router_id,
bgp_path_selection_cluster_length,
bgp_path_selection_stale,
bgp_path_selection_local_configured,
bgp_path_selection_neighbor_ip,
bgp_path_selection_default,
};
struct bgp_node {
/*
* CAUTION
@ -72,6 +97,8 @@ struct bgp_node {
#define BGP_NODE_REGISTERED_FOR_LABEL (1 << 3)
struct bgp_addpath_node_data tx_addpath;
enum bgp_path_selection_reason reason;
};
/*

View File

@ -1984,11 +1984,14 @@ static void rfapiBgpInfoAttachSorted(struct agg_node *rn,
for (prev = NULL, next = rn->info; next;
prev = next, next = next->next) {
enum bgp_path_selection_reason reason;
if (!bgp
|| (!CHECK_FLAG(info_new->flags, BGP_PATH_REMOVED)
&& CHECK_FLAG(next->flags, BGP_PATH_REMOVED))
|| bgp_path_info_cmp_compatible(bgp, info_new, next,
pfx_buf, afi, safi)
pfx_buf, afi, safi,
&reason)
== -1) { /* -1 if 1st is better */
break;
}