diff options
Diffstat (limited to 'bgpd/bgp_route.c')
| -rw-r--r-- | bgpd/bgp_route.c | 99 |
1 files changed, 75 insertions, 24 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7cc51331a5..f4118952fd 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3760,7 +3760,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, if (old_select || new_select) { bgp_bump_version(dest); - if (!bgp->t_rmap_def_originate_eval) + if (!bgp->t_rmap_def_originate_eval && + bgp->rmap_def_originate_eval_timer) event_add_timer( bm->master, update_group_refresh_default_originate_route_map, @@ -4014,8 +4015,9 @@ static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp) return pqnode; } -void bgp_process(struct bgp *bgp, struct bgp_dest *dest, - struct bgp_path_info *pi, afi_t afi, safi_t safi) +static void bgp_process_internal(struct bgp *bgp, struct bgp_dest *dest, + struct bgp_path_info *pi, afi_t afi, + safi_t safi, bool early_process) { #define ARBITRARY_PROCESS_QLEN 10000 struct work_queue *wq = bgp->process_queue; @@ -4078,9 +4080,8 @@ void bgp_process(struct bgp *bgp, struct bgp_dest *dest, struct work_queue_item *item = work_queue_last_item(wq); pqnode = item->data; - if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER) - || pqnode->bgp != bgp - || pqnode->queued >= ARBITRARY_PROCESS_QLEN) + if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER) || + (pqnode->queued >= ARBITRARY_PROCESS_QLEN && !early_process)) pqnode = bgp_processq_alloc(bgp); else pqnode_reuse = 1; @@ -4094,7 +4095,10 @@ void bgp_process(struct bgp *bgp, struct bgp_dest *dest, /* can't be enqueued twice */ assert(STAILQ_NEXT(dest, pq) == NULL); - STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq); + if (early_process) + STAILQ_INSERT_HEAD(&pqnode->pqueue, dest, pq); + else + STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq); pqnode->queued++; if (!pqnode_reuse) @@ -4103,6 +4107,18 @@ void bgp_process(struct bgp *bgp, struct bgp_dest *dest, return; } +void bgp_process(struct bgp *bgp, struct bgp_dest *dest, + struct bgp_path_info *pi, afi_t afi, safi_t safi) +{ + bgp_process_internal(bgp, dest, pi, afi, safi, false); +} + +void bgp_process_early(struct bgp *bgp, struct bgp_dest *dest, + struct bgp_path_info *pi, afi_t afi, safi_t safi) +{ + bgp_process_internal(bgp, dest, pi, afi, safi, true); +} + void bgp_add_eoiu_mark(struct bgp *bgp) { struct bgp_process_queue *pqnode; @@ -4637,7 +4653,22 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (aspath_get_last_as(attr->aspath) == bgp->as) do_loop_check = 0; - if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)) + /* When using bgp ipv4 labeled session, the local prefix is + * received by a peer, and finds out that the proposed prefix + * and its next-hop are the same. To avoid a route loop locally, + * no nexthop entry is referenced for that prefix, and the route + * will not be selected. + * + * As it has been done for ipv4-unicast, apply the following fix + * for labeled address families: when the received peer is + * a route reflector, the prefix has to be selected, even if the + * route can not be installed locally. + */ + if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT) || + (safi == SAFI_UNICAST && !peer->afc[afi][safi] && + peer->afc[afi][SAFI_LABELED_UNICAST] && + CHECK_FLAG(peer->af_flags[afi][SAFI_LABELED_UNICAST], + PEER_FLAG_REFLECTOR_CLIENT))) bgp_nht_param_prefix = NULL; else bgp_nht_param_prefix = p; @@ -11921,10 +11952,9 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa if (!use_json) route_vty_out_detail_header( vty, bgp, dest, - bgp_dest_get_prefix( - dest), + bgp_dest_get_prefix(dest), prd, table->afi, safi, - NULL, false); + NULL, false, false); route_vty_out_detail( vty, bgp, dest, dest_p, pi, @@ -11997,10 +12027,12 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t sa prd = bgp_rd_from_dest(dest, safi); - route_vty_out_detail_header( - vty, bgp, dest, - bgp_dest_get_prefix(dest), prd, - table->afi, safi, json_paths, true); + route_vty_out_detail_header(vty, bgp, dest, + bgp_dest_get_prefix( + dest), + prd, table->afi, + safi, json_paths, + true, false); vty_out(vty, "\"paths\": "); json_detail_header_used = true; @@ -12206,7 +12238,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, struct bgp_dest *dest, const struct prefix *p, const struct prefix_rd *prd, afi_t afi, safi_t safi, json_object *json, - bool incremental_print) + bool incremental_print, bool local_table) { struct bgp_path_info *pi; struct peer *peer; @@ -12424,8 +12456,14 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp, json_object_object_add(json, "advertisedTo", json_adv_to); } else { - if (!json && first) - vty_out(vty, " Not advertised to any peer"); + if (!json && first) { + if (!local_table) + vty_out(vty, + " Not advertised to any peer"); + else + vty_out(vty, + " Local BGP table not advertised"); + } vty_out(vty, "\n"); } } @@ -12464,10 +12502,10 @@ static void bgp_show_path_info(const struct prefix_rd *pfx_rd, } if (header) { - route_vty_out_detail_header( - vty, bgp, bgp_node, - bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP, - safi, json_header, false); + route_vty_out_detail_header(vty, bgp, bgp_node, + bgp_dest_get_prefix(bgp_node), + pfx_rd, AFI_IP, safi, + json_header, false, false); header = 0; } (*display)++; @@ -12937,7 +12975,7 @@ DEFUN (show_ip_bgp_l2vpn_evpn_statistics, struct json_object *json_afi_safi = NULL, *json = NULL; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp, false); + &bgp, uj); if (!idx) return CMD_WARNING; @@ -12975,7 +13013,7 @@ DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd, struct json_object *json_afi_safi = NULL, *json = NULL; bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi, - &bgp, false); + &bgp, uj); if (!idx) return CMD_WARNING; @@ -13638,6 +13676,8 @@ enum bgp_stats { BGP_STATS_ASPATH_MAXSIZE, BGP_STATS_ASPATH_TOTSIZE, BGP_STATS_ASN_HIGHEST, + BGP_STATS_REDISTRIBUTED, + BGP_STATS_LOCAL_AGGREGATES, BGP_STATS_MAX, }; @@ -13667,6 +13707,8 @@ static const char *table_stats_strs[][2] = { [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)", "averageAsPathSizeBytes"}, [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"}, + [BGP_STATS_REDISTRIBUTED] = {"Redistributed routes", "totalRedistributed"}, + [BGP_STATS_LOCAL_AGGREGATES] = {"Local aggregates", "totalLocalAggregates"}, [BGP_STATS_MAX] = {NULL, NULL} }; @@ -13716,6 +13758,15 @@ static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top, ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))) ts->counts[BGP_STATS_AGGREGATES]++; + if (pi->peer == ts->table->bgp->peer_self) { + if (pi->sub_type == BGP_ROUTE_REDISTRIBUTE) + ts->counts[BGP_STATS_REDISTRIBUTED]++; + + if ((pi->type == ZEBRA_ROUTE_BGP) && + (pi->sub_type == BGP_ROUTE_AGGREGATE)) + ts->counts[BGP_STATS_LOCAL_AGGREGATES]++; + } + /* as-path stats */ if (pi->attr->aspath) { unsigned int hops = aspath_count_hops(pi->attr->aspath); |
