summaryrefslogtreecommitdiff
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c99
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);