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 <sharpd@nvidia.com>
This commit is contained in:
Donald Sharp 2024-04-11 10:46:46 -04:00
parent 572b6f3145
commit bc9885b22e
5 changed files with 65 additions and 38 deletions

View file

@ -553,6 +553,15 @@ void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
bgp_pcount_adjust(dest, 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 /* Get MED value. If MED value is missing and "bgp bestpath
missing-as-worst" is specified, treat it as the worst value. */ missing-as-worst" is specified, treat it as the worst value. */
static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp) 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 */ /* 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) if (json_paths)
json_object_int_add(json_path, "metric", attr->med); json_object_int_add(json_path, "metric", value);
else if (wide) else if (wide)
vty_out(vty, "%7u", attr->med); vty_out(vty, "%7u", value);
else else
vty_out(vty, "%10u", attr->med); vty_out(vty, "%10u", value);
else if (!json_paths) { } else if (!json_paths) {
if (wide) if (wide)
vty_out(vty, "%*s", 7, " "); vty_out(vty, "%*s", 7, " ");
else else
@ -9535,7 +9546,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
} }
/* called from terminal list command */ /* 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, const struct prefix *p, struct attr *attr, safi_t safi,
bool use_json, json_object *json_ar, bool wide) 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); &attr->mp_nexthop_global_in);
} }
if (attr->flag if (use_bgp_med_value(attr, bgp)) {
& ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) uint32_t value = bgp_med_value(attr, bgp);
json_object_int_add(json_net, "metric",
attr->med); json_object_int_add(json_net, "metric", value);
}
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
json_object_int_add(json_net, "locPrf", json_object_int_add(json_net, "locPrf",
@ -9637,13 +9649,15 @@ void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
else else
vty_out(vty, "%*s", len, " "); 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) if (wide)
vty_out(vty, "%7u", attr->med); vty_out(vty, "%7u", value);
else else
vty_out(vty, "%10u", attr->med); vty_out(vty, "%10u", value);
else if (wide) } else if (wide)
vty_out(vty, " "); vty_out(vty, " ");
else else
vty_out(vty, " "); 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", vty_out(vty, " Origin %s",
bgp_origin_long_str[attr->origin]); 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) if (json_paths)
json_object_int_add(json_path, "metric", attr->med); json_object_int_add(json_path, "metric", value);
else else
vty_out(vty, ", metric %u", attr->med); vty_out(vty, ", metric %u", value);
} }
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) { 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, json_ar, json_net,
"%pFX", rn_p); "%pFX", rn_p);
} else } else
route_vty_out_tmp(vty, dest, rn_p, route_vty_out_tmp(vty, bgp, dest, rn_p,
&attr, safi, use_json, &attr, safi, use_json,
json_ar, wide); json_ar, wide);
bgp_attr_flush(&attr); bgp_attr_flush(&attr);
@ -14351,11 +14367,15 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
"%pFX", "%pFX",
rn_p); rn_p);
} else } else
route_vty_out_tmp( route_vty_out_tmp(vty,
vty, dest, rn_p, bgp,
&attr, safi, dest,
rn_p,
&attr,
safi,
use_json, use_json,
json_ar, wide); json_ar,
wide);
(*output_count)++; (*output_count)++;
} else { } else {
(*filtered_count)++; (*filtered_count)++;
@ -14393,9 +14413,10 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
json_ar, json_net, json_ar, json_net,
"%pFX", rn_p); "%pFX", rn_p);
} else } else
route_vty_out_tmp( route_vty_out_tmp(vty, bgp, dest, rn_p,
vty, dest, rn_p, pi->attr, safi, pi->attr, safi,
use_json, json_ar, wide); use_json, json_ar,
wide);
(*output_count)++; (*output_count)++;
} }
} }

View file

@ -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, extern void route_vty_out_tag(struct vty *vty, const struct prefix *p,
struct bgp_path_info *path, int display, struct bgp_path_info *path, int display,
safi_t safi, json_object *json); safi_t safi, json_object *json);
extern void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest, extern void route_vty_out_tmp(struct vty *vty, struct bgp *bgp,
const struct prefix *p, struct attr *attr, struct bgp_dest *dest, const struct prefix *p,
safi_t safi, bool use_json, json_object *json_ar, struct attr *attr, safi_t safi, bool use_json,
bool wide); json_object *json_ar, bool wide);
extern void route_vty_out_overlay(struct vty *vty, const struct prefix *p, extern void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
struct bgp_path_info *path, int display, struct bgp_path_info *path, int display,
json_object *json); json_object *json);

View file

@ -328,15 +328,16 @@ static void subgrp_show_adjq_vty(struct update_subgroup *subgrp,
} }
if ((flags & UPDWALK_FLAGS_ADVQUEUE) && adj->adv && if ((flags & UPDWALK_FLAGS_ADVQUEUE) && adj->adv &&
adj->adv->baa) { adj->adv->baa) {
route_vty_out_tmp( route_vty_out_tmp(vty, bgp, dest, dest_p,
vty, dest, dest_p, adj->adv->baa->attr, adj->adv->baa->attr,
SUBGRP_SAFI(subgrp), 0, NULL, false); SUBGRP_SAFI(subgrp), 0, NULL,
false);
output_count++; output_count++;
} }
if ((flags & UPDWALK_FLAGS_ADVERTISED) && adj->attr) { if ((flags & UPDWALK_FLAGS_ADVERTISED) && adj->attr) {
route_vty_out_tmp(vty, dest, dest_p, adj->attr, route_vty_out_tmp(vty, bgp, dest, dest_p,
SUBGRP_SAFI(subgrp), 0, NULL, adj->attr, SUBGRP_SAFI(subgrp),
false); 0, NULL, false);
output_count++; output_count++;
} }
} }

View file

@ -191,7 +191,7 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
} }
rd_header = 0; 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, attr, safi, use_json, json_routes,
false); false);
output_count++; output_count++;

View file

@ -425,6 +425,11 @@ Route Selection
Disabled by default. 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) .. clicmd:: maximum-paths (1-128)
Sets the maximum-paths value used for ecmp calculations for this Sets the maximum-paths value used for ecmp calculations for this