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