diff options
Diffstat (limited to 'bgpd/bgp_route.c')
| -rw-r--r-- | bgpd/bgp_route.c | 352 |
1 files changed, 252 insertions, 100 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 4713452d5e..b637191d10 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -116,6 +116,14 @@ DEFINE_HOOK(bgp_process, struct peer *peer, bool withdraw), (bgp, afi, safi, bn, peer, withdraw)) +/** Test if path is suppressed. */ +static bool bgp_path_suppressed(struct bgp_path_info *pi) +{ + if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL) + return false; + + return listcount(pi->extra->aggr_suppressors) > 0; +} struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi, safi_t safi, const struct prefix *p, @@ -1740,10 +1748,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, } /* Aggregate-address suppress check. */ - if (pi->extra && pi->extra->suppress) - if (!UNSUPPRESS_MAP_NAME(filter)) { - return false; - } + if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter)) + return false; /* * If we are doing VRF 2 VRF leaking via the import @@ -1980,7 +1986,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, bgp_peer_as_override(bgp, afi, safi, peer, attr); /* Route map & unsuppress-map apply. */ - if (ROUTE_MAP_OUT_NAME(filter) || (pi->extra && pi->extra->suppress)) { + if (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi)) { struct bgp_path_info rmap_path = {0}; struct bgp_path_info_extra dummy_rmap_path_extra = {0}; struct attr dummy_attr = {0}; @@ -2005,7 +2011,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT); - if (pi->extra && pi->extra->suppress) + if (bgp_path_suppressed(pi)) ret = route_map_apply(UNSUPPRESS_MAP(filter), p, RMAP_BGP, &rmap_path); else @@ -2464,12 +2470,8 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer : NULL); - if (BGP_DEBUG(update, UPDATE_OUT)) { - char buf_prefix[PREFIX_STRLEN]; - prefix2str(p, buf_prefix, sizeof(buf_prefix)); - zlog_debug("%s: p=%s, selected=%p", __func__, buf_prefix, - selected); - } + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected); /* First update is deferred until ORF or ROUTE-REFRESH is received */ if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi], @@ -2973,18 +2975,21 @@ static void bgp_processq_del(struct work_queue *wq, void *data) XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode); } -void bgp_process_queue_init(void) +void bgp_process_queue_init(struct bgp *bgp) { - if (!bm->process_main_queue) - bm->process_main_queue = - work_queue_new(bm->master, "process_main_queue"); + if (!bgp->process_queue) { + char name[BUFSIZ]; + + snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty); + bgp->process_queue = work_queue_new(bm->master, name); + } - bm->process_main_queue->spec.workfunc = &bgp_process_wq; - bm->process_main_queue->spec.del_item_data = &bgp_processq_del; - bm->process_main_queue->spec.max_retries = 0; - bm->process_main_queue->spec.hold = 50; + bgp->process_queue->spec.workfunc = &bgp_process_wq; + bgp->process_queue->spec.del_item_data = &bgp_processq_del; + bgp->process_queue->spec.max_retries = 0; + bgp->process_queue->spec.hold = 50; /* Use a higher yield value of 50ms for main queue processing */ - bm->process_main_queue->spec.yield = 50 * 1000L; + bgp->process_queue->spec.yield = 50 * 1000L; } static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp) @@ -3004,7 +3009,7 @@ static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp) void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi) { #define ARBITRARY_PROCESS_QLEN 10000 - struct work_queue *wq = bm->process_main_queue; + struct work_queue *wq = bgp->process_queue; struct bgp_process_queue *pqnode; int pqnode_reuse = 0; @@ -3061,13 +3066,13 @@ void bgp_add_eoiu_mark(struct bgp *bgp) { struct bgp_process_queue *pqnode; - if (bm->process_main_queue == NULL) + if (bgp->process_queue == NULL) return; pqnode = bgp_processq_alloc(bgp); SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER); - work_queue_add(bm->process_main_queue, pqnode); + work_queue_add(bgp->process_queue, pqnode); } static int bgp_maximum_prefix_restart_timer(struct thread *thread) @@ -4328,7 +4333,7 @@ void bgp_stop_announce_route_timer(struct peer_af *paf) if (!paf->t_announce_route) return; - THREAD_TIMER_OFF(paf->t_announce_route); + thread_cancel(&paf->t_announce_route); } /* @@ -4587,7 +4592,7 @@ static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi, struct bgp_table *table) { struct bgp_dest *dest; - int force = bm->process_main_queue ? 0 : 1; + int force = peer->bgp->process_queue ? 0 : 1; if (!table) table = peer->bgp->rib[afi][safi]; @@ -5786,9 +5791,9 @@ void bgp_static_delete(struct bgp *bgp) bgp_dest_get_prefix( dest)); bgp_static_free(bgp_static); - bgp_dest_set_bgp_static_info(dest, + bgp_dest_set_bgp_static_info(rm, NULL); - bgp_dest_unlock_node(dest); + bgp_dest_unlock_node(rm); } } else { bgp_static = bgp_dest_get_bgp_static_info(dest); @@ -6221,11 +6226,119 @@ static struct bgp_aggregate *bgp_aggregate_new(void) static void bgp_aggregate_free(struct bgp_aggregate *aggregate) { + XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name); + route_map_counter_decrement(aggregate->suppress_map); XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name); route_map_counter_decrement(aggregate->rmap.map); XFREE(MTYPE_BGP_AGGREGATE, aggregate); } +/** + * Helper function to avoid repeated code: prepare variables for a + * `route_map_apply` call. + * + * \returns `true` on route map match, otherwise `false`. + */ +static bool aggr_suppress_map_test(struct bgp *bgp, + struct bgp_aggregate *aggregate, + struct bgp_path_info *pi) +{ + const struct prefix *p = bgp_dest_get_prefix(pi->net); + route_map_result_t rmr = RMAP_DENYMATCH; + struct bgp_path_info rmap_path = {}; + struct attr attr = {}; + + /* No route map entries created, just don't match. */ + if (aggregate->suppress_map == NULL) + return false; + + /* Call route map matching and return result. */ + attr.aspath = aspath_empty(); + rmap_path.peer = bgp->peer_self; + rmap_path.attr = &attr; + + SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE); + rmr = route_map_apply(aggregate->suppress_map, p, RMAP_BGP, &rmap_path); + bgp->peer_self->rmap_type = 0; + + bgp_attr_flush(&attr); + + return rmr == RMAP_PERMITMATCH; +} + +/** Test whether the aggregation has suppressed this path or not. */ +static bool aggr_suppress_exists(struct bgp_aggregate *aggregate, + struct bgp_path_info *pi) +{ + if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL) + return false; + + return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL; +} + +/** + * Suppress this path and keep the reference. + * + * \returns `true` if needs processing otherwise `false`. + */ +static bool aggr_suppress_path(struct bgp_aggregate *aggregate, + struct bgp_path_info *pi) +{ + struct bgp_path_info_extra *pie; + + /* Path is already suppressed by this aggregation. */ + if (aggr_suppress_exists(aggregate, pi)) + return false; + + pie = bgp_path_info_extra_get(pi); + + /* This is the first suppression, allocate memory and list it. */ + if (pie->aggr_suppressors == NULL) + pie->aggr_suppressors = list_new(); + + listnode_add(pie->aggr_suppressors, aggregate); + + /* Only mark for processing if suppressed. */ + if (listcount(pie->aggr_suppressors) == 1) { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("aggregate-address suppressing: %pFX", + bgp_dest_get_prefix(pi->net)); + + bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED); + return true; + } + + return false; +} + +/** + * Unsuppress this path and remove the reference. + * + * \returns `true` if needs processing otherwise `false`. + */ +static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate, + struct bgp_path_info *pi) +{ + /* Path wasn't suppressed. */ + if (!aggr_suppress_exists(aggregate, pi)) + return false; + + listnode_delete(pi->extra->aggr_suppressors, aggregate); + + /* Unsuppress and free extra memory if last item. */ + if (listcount(pi->extra->aggr_suppressors) == 0) { + if (BGP_DEBUG(update, UPDATE_OUT)) + zlog_debug("aggregate-address unsuppressing: %pFX", + bgp_dest_get_prefix(pi->net)); + + list_delete(&pi->extra->aggr_suppressors); + bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED); + return true; + } + + return false; +} + static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin, struct aspath *aspath, struct community *comm, @@ -6420,13 +6533,11 @@ static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate, * Toggles the route suppression status for this aggregate address * configuration. */ -static void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, - struct bgp *bgp, - const struct prefix *p, afi_t afi, - safi_t safi, bool suppress) +void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, + struct bgp *bgp, const struct prefix *p, + afi_t afi, safi_t safi, bool suppress) { struct bgp_table *table = bgp->rib[afi][safi]; - struct bgp_path_info_extra *pie; const struct prefix *dest_p; struct bgp_dest *dest, *top; struct bgp_path_info *pi; @@ -6447,32 +6558,17 @@ static void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, if (pi->sub_type == BGP_ROUTE_AGGREGATE) continue; - /* - * On installation it is possible that pi->extra is - * set to NULL, otherwise it must exists. - */ - assert(!suppress && pi->extra != NULL); - /* We are toggling suppression back. */ if (suppress) { - pie = bgp_path_info_extra_get(pi); /* Suppress route if not suppressed already. */ - pie->suppress++; - bgp_path_info_set_flag(dest, pi, - BGP_PATH_ATTR_CHANGED); - toggle_suppression = true; + if (aggr_suppress_path(aggregate, pi)) + toggle_suppression = true; continue; } - pie = pi->extra; - assert(pie->suppress > 0); - pie->suppress--; /* Install route if there is no more suppression. */ - if (pie->suppress == 0) { - bgp_path_info_set_flag(dest, pi, - BGP_PATH_ATTR_CHANGED); + if (aggr_unsuppress_path(aggregate, pi)) toggle_suppression = true; - } } if (toggle_suppression) @@ -6559,6 +6655,17 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, if (aggregate->match_med) bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi); + /* + * Reset aggregate count: we might've been called from route map + * update so in that case we must retest all more specific routes. + * + * \see `bgp_route_map_process_update`. + */ + aggregate->count = 0; + aggregate->incomplete_origin_count = 0; + aggregate->incomplete_origin_count = 0; + aggregate->egp_origin_count = 0; + /* ORIGIN attribute: If at least one route among routes that are aggregated has ORIGIN with the value INCOMPLETE, then the aggregated route must have the ORIGIN attribute with the value @@ -6603,10 +6710,24 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, */ if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) { - (bgp_path_info_extra_get(pi))->suppress++; - bgp_path_info_set_flag(dest, pi, - BGP_PATH_ATTR_CHANGED); - match++; + if (aggr_suppress_path(aggregate, pi)) + match++; + } + + /* + * Suppress more specific routes that match the route + * map results. + * + * MED matching: + * Don't suppress routes if MED matching is enabled and + * it mismatched otherwise we might end up with no + * routes for this path. + */ + if (aggregate->suppress_map_name + && AGGREGATE_MED_VALID(aggregate) + && aggr_suppress_map_test(bgp, aggregate, pi)) { + if (aggr_suppress_path(aggregate, pi)) + match++; } aggregate->count++; @@ -6746,15 +6867,17 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi, if (aggregate->summary_only && pi->extra && AGGREGATE_MED_VALID(aggregate)) { - pi->extra->suppress--; + if (aggr_unsuppress_path(aggregate, pi)) + match++; + } - if (pi->extra->suppress == 0) { - bgp_path_info_set_flag( - dest, pi, - BGP_PATH_ATTR_CHANGED); + if (aggregate->suppress_map_name + && AGGREGATE_MED_VALID(aggregate) + && aggr_suppress_map_test(bgp, aggregate, pi)) { + if (aggr_unsuppress_path(aggregate, pi)) match++; - } } + aggregate->count--; if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE) @@ -6845,7 +6968,11 @@ static void bgp_add_route_to_aggregate(struct bgp *bgp, pinew, true); if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) - (bgp_path_info_extra_get(pinew))->suppress++; + aggr_suppress_path(aggregate, pinew); + + if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate) + && aggr_suppress_map_test(bgp, aggregate, pinew)) + aggr_suppress_path(aggregate, pinew); switch (pinew->attr->origin) { case BGP_ORIGIN_INCOMPLETE: @@ -6941,19 +7068,17 @@ static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi, if (pi->sub_type == BGP_ROUTE_AGGREGATE) return; - if (aggregate->summary_only && pi->extra && pi->extra->suppress > 0 - && AGGREGATE_MED_VALID(aggregate)) { - pi->extra->suppress--; + if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) + if (aggr_unsuppress_path(aggregate, pi)) + match++; - if (pi->extra->suppress == 0) { - bgp_path_info_set_flag(pi->net, pi, - BGP_PATH_ATTR_CHANGED); + if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate) + && aggr_suppress_map_test(bgp, aggregate, pi)) + if (aggr_unsuppress_path(aggregate, pi)) match++; - } - } /* - * This must be called after `summary` check to avoid + * This must be called after `summary`, `suppress-map` check to avoid * "unsuppressing" twice. */ if (aggregate->match_med) @@ -7216,7 +7341,8 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str, static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, safi_t safi, const char *rmap, uint8_t summary_only, uint8_t as_set, - uint8_t origin, bool match_med) + uint8_t origin, bool match_med, + const char *suppress_map) { VTY_DECLVAR_CONTEXT(bgp, bgp); int ret; @@ -7225,6 +7351,12 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, struct bgp_aggregate *aggregate; uint8_t as_set_new = as_set; + if (suppress_map && summary_only) { + vty_out(vty, + "'summary-only' and 'suppress-map' can't be used at the same time\n"); + return CMD_WARNING_CONFIG_FAILED; + } + /* Convert string to prefix structure. */ ret = str2prefix(prefix_str, &p); if (!ret) { @@ -7296,6 +7428,18 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, aggregate->rmap.map = route_map_lookup_by_name(rmap); route_map_counter_increment(aggregate->rmap.map); } + + if (suppress_map) { + XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name); + route_map_counter_decrement(aggregate->suppress_map); + + aggregate->suppress_map_name = + XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map); + aggregate->suppress_map = + route_map_lookup_by_name(aggregate->suppress_map_name); + route_map_counter_increment(aggregate->suppress_map); + } + bgp_dest_set_bgp_aggregate_info(dest, aggregate); /* Aggregate address insert into BGP routing table. */ @@ -7311,6 +7455,7 @@ DEFPY(aggregate_addressv4, aggregate_addressv4_cmd, "|route-map WORD$rmap_name" "|origin <egp|igp|incomplete>$origin_s" "|matching-MED-only$match_med" + "|suppress-map WORD$suppress_map" "}", NO_STR "Configure BGP aggregate entries\n" @@ -7323,7 +7468,9 @@ DEFPY(aggregate_addressv4, aggregate_addressv4_cmd, "Remote EGP\n" "Local IGP\n" "Unknown heritage\n" - "Only aggregate routes with matching MED\n") + "Only aggregate routes with matching MED\n" + "Suppress the selected more specific routes\n" + "Route map with the route selectors\n") { const char *prefix_s = NULL; safi_t safi = bgp_node_safi(vty); @@ -7359,7 +7506,7 @@ DEFPY(aggregate_addressv4, aggregate_addressv4_cmd, return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name, summary_only != NULL, as_set, origin, - match_med != NULL); + match_med != NULL, suppress_map); } DEFPY(aggregate_addressv6, aggregate_addressv6_cmd, @@ -7369,6 +7516,7 @@ DEFPY(aggregate_addressv6, aggregate_addressv6_cmd, "|route-map WORD$rmap_name" "|origin <egp|igp|incomplete>$origin_s" "|matching-MED-only$match_med" + "|suppress-map WORD$suppress_map" "}", NO_STR "Configure BGP aggregate entries\n" @@ -7381,7 +7529,9 @@ DEFPY(aggregate_addressv6, aggregate_addressv6_cmd, "Remote EGP\n" "Local IGP\n" "Unknown heritage\n" - "Only aggregate routes with matching MED\n") + "Only aggregate routes with matching MED\n" + "Suppress the selected more specific routes\n" + "Route map with the route selectors\n") { uint8_t origin = BGP_ORIGIN_UNSPECIFIED; int as_set = AGGREGATE_AS_UNSET; @@ -7405,7 +7555,7 @@ DEFPY(aggregate_addressv6, aggregate_addressv6_cmd, return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST, rmap_name, summary_only != NULL, as_set, - origin, match_med != NULL); + origin, match_med != NULL, suppress_map); } /* Redistribute route treatment. */ @@ -7661,13 +7811,10 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty, json_object_string_add(json, "network", buf2); } } else if (p->family == AF_ETHERNET) { - prefix2str(p, buf, PREFIX_STRLEN); len = vty_out(vty, "%pFX", p); } else if (p->family == AF_EVPN) { if (!json) - len = vty_out(vty, "%s", - prefix2str((struct prefix_evpn *)p, buf, - BUFSIZ)); + len = vty_out(vty, "%pFX", (struct prefix_evpn *)p); else bgp_evpn_route2json((struct prefix_evpn *)p, json); } else if (p->family == AF_FLOWSPEC) { @@ -7716,7 +7863,7 @@ static void route_vty_short_status_out(struct vty *vty, if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) json_object_boolean_true_add(json_path, "stale"); - if (path->extra && path->extra->suppress) + if (path->extra && bgp_path_suppressed(path)) json_object_boolean_true_add(json_path, "suppressed"); if (CHECK_FLAG(path->flags, BGP_PATH_VALID) @@ -7753,7 +7900,7 @@ static void route_vty_short_status_out(struct vty *vty, vty_out(vty, "R"); else if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) vty_out(vty, "S"); - else if (path->extra && path->extra->suppress) + else if (bgp_path_suppressed(path)) vty_out(vty, "s"); else if (CHECK_FLAG(path->flags, BGP_PATH_VALID) && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) @@ -8995,7 +9142,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, { char buf[INET6_ADDRSTRLEN]; char buf1[BUFSIZ]; - char buf2[EVPN_ROUTE_STRLEN]; struct attr *attr = path->attr; int sockunion_vty_out(struct vty *, union sockunion *); time_t tbuf; @@ -9033,7 +9179,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, if (path->extra) { char tag_buf[30]; - buf2[0] = '\0'; tag_buf[0] = '\0'; if (path->extra && path->extra->num_labels) { bgp_evpn_label2str(path->extra->label, @@ -9042,10 +9187,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, } if (safi == SAFI_EVPN) { if (!json_paths) { - prefix2str((struct prefix_evpn *) - bgp_dest_get_prefix(bn), - buf2, sizeof(buf2)); - vty_out(vty, " Route %s", buf2); + vty_out(vty, " Route %pFX", + (struct prefix_evpn *) + bgp_dest_get_prefix(bn)); if (tag_buf[0] != '\0') vty_out(vty, " VNI %s", tag_buf); vty_out(vty, "\n"); @@ -9069,13 +9213,20 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, pdest), buf1, sizeof(buf1)); if (is_pi_family_evpn(parent_ri)) { - prefix2str((struct prefix_evpn *) - bgp_dest_get_prefix( - dest), - buf2, sizeof(buf2)); - vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf); + vty_out(vty, + " Imported from %s:%pFX, VNI %s\n", + buf1, + (struct prefix_evpn *) + bgp_dest_get_prefix( + dest), + tag_buf); } else - vty_out(vty, " Imported from %s:%s\n", buf1, buf2); + vty_out(vty, + " Imported from %s:%pFX\n", + buf1, + (struct prefix_evpn *) + bgp_dest_get_prefix( + dest)); } } } @@ -10407,7 +10558,6 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, struct peer *peer; struct listnode *node, *nnode; char buf1[RD_ADDRSTRLEN]; - char buf3[EVPN_ROUTE_STRLEN]; char prefix_str[BUFSIZ]; int count = 0; int best = 0; @@ -10439,12 +10589,10 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, if (safi == SAFI_EVPN) { if (!json) { - vty_out(vty, "BGP routing table entry for %s%s%s\n", + vty_out(vty, "BGP routing table entry for %s%s%pFX\n", prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) : "", - prd ? ":" : "", - prefix2str((struct prefix_evpn *)p, buf3, - sizeof(buf3))); + prd ? ":" : "", (struct prefix_evpn *)p); } else { json_object_string_add(json, "rd", prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) : @@ -10480,7 +10628,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, count++; if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) { best = count; - if (pi->extra && pi->extra->suppress) + if (bgp_path_suppressed(pi)) suppress = 1; if (pi->attr->community == NULL) @@ -14045,6 +14193,10 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi, if (bgp_aggregate->match_med) vty_out(vty, " matching-MED-only"); + if (bgp_aggregate->suppress_map_name) + vty_out(vty, " suppress-map %s", + bgp_aggregate->suppress_map_name); + vty_out(vty, "\n"); } } |
