From bc9885b22e79ac14fd931517582d0d6d80f68c85 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 11 Apr 2024 10:46:46 -0400 Subject: [PATCH] bgpd: Fix display when using `missing-as-worst` The usage of the `bgp bestpath med missing-as-worst` command was being accepted and applied during bestpath, but during output of the routes affected by this it would not give any indication that this was happening or what med value was being used. Fixes: #15718 Signed-off-by: Donald Sharp --- bgpd/bgp_route.c | 75 +++++++++++++++++++++++++++---------------- bgpd/bgp_route.h | 8 ++--- bgpd/bgp_updgrp_adv.c | 13 ++++---- bgpd/bgp_vpn.c | 2 +- doc/user/bgp.rst | 5 +++ 5 files changed, 65 insertions(+), 38 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 0a865d7098..9f864a172f 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -553,6 +553,15 @@ void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi, bgp_pcount_adjust(dest, pi); } +static bool use_bgp_med_value(struct attr *attr, struct bgp *bgp) +{ + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) || + CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST)) + return true; + + return false; +} + /* Get MED value. If MED value is missing and "bgp bestpath missing-as-worst" is specified, treat it as the worst value. */ static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp) @@ -9407,14 +9416,16 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } /* MED/Metric */ - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) + if (use_bgp_med_value(attr, path->peer->bgp)) { + uint32_t value = bgp_med_value(attr, path->peer->bgp); + if (json_paths) - json_object_int_add(json_path, "metric", attr->med); + json_object_int_add(json_path, "metric", value); else if (wide) - vty_out(vty, "%7u", attr->med); + vty_out(vty, "%7u", value); else - vty_out(vty, "%10u", attr->med); - else if (!json_paths) { + vty_out(vty, "%10u", value); + } else if (!json_paths) { if (wide) vty_out(vty, "%*s", 7, " "); else @@ -9535,7 +9546,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p, } /* called from terminal list command */ -void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, +void route_vty_out_tmp(struct vty *vty, struct bgp *bgp, struct bgp_dest *dest, const struct prefix *p, struct attr *attr, safi_t safi, bool use_json, json_object *json_ar, bool wide) { @@ -9594,10 +9605,11 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, &attr->mp_nexthop_global_in); } - if (attr->flag - & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) - json_object_int_add(json_net, "metric", - attr->med); + if (use_bgp_med_value(attr, bgp)) { + uint32_t value = bgp_med_value(attr, bgp); + + json_object_int_add(json_net, "metric", value); + } if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) json_object_int_add(json_net, "locPrf", @@ -9637,13 +9649,15 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, else vty_out(vty, "%*s", len, " "); } - if (attr->flag - & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) + + if (use_bgp_med_value(attr, bgp)) { + uint32_t value = bgp_med_value(attr, bgp); + if (wide) - vty_out(vty, "%7u", attr->med); + vty_out(vty, "%7u", value); else - vty_out(vty, "%10u", attr->med); - else if (wide) + vty_out(vty, "%10u", value); + } else if (wide) vty_out(vty, " "); else vty_out(vty, " "); @@ -10640,11 +10654,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, vty_out(vty, " Origin %s", bgp_origin_long_str[attr->origin]); - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) { + if (use_bgp_med_value(attr, bgp)) { + uint32_t value = bgp_med_value(attr, bgp); + if (json_paths) - json_object_int_add(json_path, "metric", attr->med); + json_object_int_add(json_path, "metric", value); else - vty_out(vty, ", metric %u", attr->med); + vty_out(vty, ", metric %u", value); } if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { @@ -14288,7 +14304,7 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, json_ar, json_net, "%pFX", rn_p); } else - route_vty_out_tmp(vty, dest, rn_p, + route_vty_out_tmp(vty, bgp, dest, rn_p, &attr, safi, use_json, json_ar, wide); bgp_attr_flush(&attr); @@ -14351,11 +14367,15 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, "%pFX", rn_p); } else - route_vty_out_tmp( - vty, dest, rn_p, - &attr, safi, - use_json, - json_ar, wide); + route_vty_out_tmp(vty, + bgp, + dest, + rn_p, + &attr, + safi, + use_json, + json_ar, + wide); (*output_count)++; } else { (*filtered_count)++; @@ -14393,9 +14413,10 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table, json_ar, json_net, "%pFX", rn_p); } else - route_vty_out_tmp( - vty, dest, rn_p, pi->attr, safi, - use_json, json_ar, wide); + route_vty_out_tmp(vty, bgp, dest, rn_p, + pi->attr, safi, + use_json, json_ar, + wide); (*output_count)++; } } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 9be3f063f3..75f9bbab94 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -845,10 +845,10 @@ extern void route_vty_out(struct vty *vty, const struct prefix *p, extern void route_vty_out_tag(struct vty *vty, const struct prefix *p, struct bgp_path_info *path, int display, safi_t safi, json_object *json); -extern void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, - const struct prefix *p, struct attr *attr, - safi_t safi, bool use_json, json_object *json_ar, - bool wide); +extern void route_vty_out_tmp(struct vty *vty, struct bgp *bgp, + struct bgp_dest *dest, const struct prefix *p, + struct attr *attr, safi_t safi, bool use_json, + json_object *json_ar, bool wide); extern void route_vty_out_overlay(struct vty *vty, const struct prefix *p, struct bgp_path_info *path, int display, json_object *json); diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 5d7a8b2ba1..0a852c75de 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -328,15 +328,16 @@ static void subgrp_show_adjq_vty(struct update_subgroup *subgrp, } if ((flags & UPDWALK_FLAGS_ADVQUEUE) && adj->adv && adj->adv->baa) { - route_vty_out_tmp( - vty, dest, dest_p, adj->adv->baa->attr, - SUBGRP_SAFI(subgrp), 0, NULL, false); + route_vty_out_tmp(vty, bgp, dest, dest_p, + adj->adv->baa->attr, + SUBGRP_SAFI(subgrp), 0, NULL, + false); output_count++; } if ((flags & UPDWALK_FLAGS_ADVERTISED) && adj->attr) { - route_vty_out_tmp(vty, dest, dest_p, adj->attr, - SUBGRP_SAFI(subgrp), 0, NULL, - false); + route_vty_out_tmp(vty, bgp, dest, dest_p, + adj->attr, SUBGRP_SAFI(subgrp), + 0, NULL, false); output_count++; } } diff --git a/bgpd/bgp_vpn.c b/bgpd/bgp_vpn.c index 8fe24ebe20..2470fb8844 100644 --- a/bgpd/bgp_vpn.c +++ b/bgpd/bgp_vpn.c @@ -191,7 +191,7 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer, } rd_header = 0; } - route_vty_out_tmp(vty, rm, bgp_dest_get_prefix(rm), + route_vty_out_tmp(vty, bgp, rm, bgp_dest_get_prefix(rm), attr, safi, use_json, json_routes, false); output_count++; diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst index 4619fec6a7..68ae796bc9 100644 --- a/doc/user/bgp.rst +++ b/doc/user/bgp.rst @@ -425,6 +425,11 @@ Route Selection Disabled by default. +.. clicmd:: bgp bestpath med missing-as-worst + + If the paths MED value is missing and this command is configured + then treat it as the worse possible value that it can be. + .. clicmd:: maximum-paths (1-128) Sets the maximum-paths value used for ecmp calculations for this