]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #12646 from pguibert6WIND/mpls_alloc_per_nh
[mirror_frr.git] / bgpd / bgp_route.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP routing information
3 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
4 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 */
6
7 #include <zebra.h>
8 #include <math.h>
9
10 #include "printfrr.h"
11 #include "frrstr.h"
12 #include "prefix.h"
13 #include "linklist.h"
14 #include "memory.h"
15 #include "command.h"
16 #include "stream.h"
17 #include "filter.h"
18 #include "log.h"
19 #include "routemap.h"
20 #include "buffer.h"
21 #include "sockunion.h"
22 #include "plist.h"
23 #include "frrevent.h"
24 #include "workqueue.h"
25 #include "queue.h"
26 #include "memory.h"
27 #include "srv6.h"
28 #include "lib/json.h"
29 #include "lib_errors.h"
30 #include "zclient.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_regex.h"
39 #include "bgpd/bgp_community.h"
40 #include "bgpd/bgp_community_alias.h"
41 #include "bgpd/bgp_ecommunity.h"
42 #include "bgpd/bgp_lcommunity.h"
43 #include "bgpd/bgp_clist.h"
44 #include "bgpd/bgp_packet.h"
45 #include "bgpd/bgp_filter.h"
46 #include "bgpd/bgp_fsm.h"
47 #include "bgpd/bgp_mplsvpn.h"
48 #include "bgpd/bgp_nexthop.h"
49 #include "bgpd/bgp_damp.h"
50 #include "bgpd/bgp_advertise.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_vty.h"
53 #include "bgpd/bgp_mpath.h"
54 #include "bgpd/bgp_nht.h"
55 #include "bgpd/bgp_updgrp.h"
56 #include "bgpd/bgp_label.h"
57 #include "bgpd/bgp_addpath.h"
58 #include "bgpd/bgp_mac.h"
59 #include "bgpd/bgp_network.h"
60 #include "bgpd/bgp_trace.h"
61 #include "bgpd/bgp_rpki.h"
62
63 #ifdef ENABLE_BGP_VNC
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #include "bgpd/rfapi/vnc_import_bgp.h"
66 #include "bgpd/rfapi/vnc_export_bgp.h"
67 #endif
68 #include "bgpd/bgp_encap_types.h"
69 #include "bgpd/bgp_encap_tlv.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_evpn_mh.h"
72 #include "bgpd/bgp_evpn_vty.h"
73 #include "bgpd/bgp_flowspec.h"
74 #include "bgpd/bgp_flowspec_util.h"
75 #include "bgpd/bgp_pbr.h"
76
77 #include "bgpd/bgp_route_clippy.c"
78
79 DEFINE_HOOK(bgp_snmp_update_stats,
80 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
81 (rn, pi, added));
82
83 DEFINE_HOOK(bgp_rpki_prefix_status,
84 (struct peer *peer, struct attr *attr,
85 const struct prefix *prefix),
86 (peer, attr, prefix));
87
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str[];
90 extern const char *bgp_origin_long_str[];
91
92 /* PMSI strings. */
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str[] = {
96 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
104 {0}
105 };
106
107 #define VRFID_NONE_STR "-"
108 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
109
110 DEFINE_HOOK(bgp_process,
111 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
112 struct peer *peer, bool withdraw),
113 (bgp, afi, safi, bn, peer, withdraw));
114
115 /** Test if path is suppressed. */
116 static bool bgp_path_suppressed(struct bgp_path_info *pi)
117 {
118 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
119 return false;
120
121 return listcount(pi->extra->aggr_suppressors) > 0;
122 }
123
124 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
125 safi_t safi, const struct prefix *p,
126 struct prefix_rd *prd)
127 {
128 struct bgp_dest *dest;
129 struct bgp_dest *pdest = NULL;
130
131 assert(table);
132
133 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
134 || (safi == SAFI_EVPN)) {
135 pdest = bgp_node_get(table, (struct prefix *)prd);
136
137 if (!bgp_dest_has_bgp_path_info_data(pdest))
138 bgp_dest_set_bgp_table_info(
139 pdest, bgp_table_init(table->bgp, afi, safi));
140 else
141 bgp_dest_unlock_node(pdest);
142 table = bgp_dest_get_bgp_table_info(pdest);
143 }
144
145 dest = bgp_node_get(table, p);
146
147 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
148 || (safi == SAFI_EVPN))
149 dest->pdest = pdest;
150
151 return dest;
152 }
153
154 struct bgp_dest *bgp_safi_node_lookup(struct bgp_table *table, safi_t safi,
155 const struct prefix *p,
156 struct prefix_rd *prd)
157 {
158 struct bgp_dest *dest;
159 struct bgp_dest *pdest = NULL;
160
161 if (!table)
162 return NULL;
163
164 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
165 || (safi == SAFI_EVPN)) {
166 pdest = bgp_node_lookup(table, (struct prefix *)prd);
167 if (!pdest)
168 return NULL;
169
170 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
171 bgp_dest_unlock_node(pdest);
172 return NULL;
173 }
174
175 table = bgp_dest_get_bgp_table_info(pdest);
176 }
177
178 dest = bgp_node_lookup(table, p);
179
180 return dest;
181 }
182
183 /* Allocate bgp_path_info_extra */
184 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
185 {
186 struct bgp_path_info_extra *new;
187 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
188 sizeof(struct bgp_path_info_extra));
189 new->label[0] = MPLS_INVALID_LABEL;
190 new->num_labels = 0;
191 new->bgp_fs_pbr = NULL;
192 new->bgp_fs_iprule = NULL;
193 return new;
194 }
195
196 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
197 {
198 struct bgp_path_info_extra *e;
199
200 if (!extra || !*extra)
201 return;
202
203 e = *extra;
204 if (e->damp_info)
205 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
206 e->damp_info->safi);
207
208 e->damp_info = NULL;
209 if (e->parent) {
210 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
211
212 if (bpi->net) {
213 /* FIXME: since multiple e may have the same e->parent
214 * and e->parent->net is holding a refcount for each
215 * of them, we need to do some fudging here.
216 *
217 * WARNING: if bpi->net->lock drops to 0, bpi may be
218 * freed as well (because bpi->net was holding the
219 * last reference to bpi) => write after free!
220 */
221 unsigned refcount;
222
223 bpi = bgp_path_info_lock(bpi);
224 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
225 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
226 if (!refcount)
227 bpi->net = NULL;
228 bgp_path_info_unlock(bpi);
229 }
230 bgp_path_info_unlock(e->parent);
231 e->parent = NULL;
232 }
233
234 if (e->bgp_orig)
235 bgp_unlock(e->bgp_orig);
236
237 if (e->peer_orig)
238 peer_unlock(e->peer_orig);
239
240 if (e->aggr_suppressors)
241 list_delete(&e->aggr_suppressors);
242
243 if (e->mh_info)
244 bgp_evpn_path_mh_info_free(e->mh_info);
245
246 if ((*extra)->bgp_fs_iprule)
247 list_delete(&((*extra)->bgp_fs_iprule));
248 if ((*extra)->bgp_fs_pbr)
249 list_delete(&((*extra)->bgp_fs_pbr));
250 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
251 }
252
253 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
254 * allocated if required.
255 */
256 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
257 {
258 if (!pi->extra)
259 pi->extra = bgp_path_info_extra_new();
260 return pi->extra;
261 }
262
263 /* Free bgp route information. */
264 void bgp_path_info_free_with_caller(const char *name,
265 struct bgp_path_info *path)
266 {
267 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
268 bgp_attr_unintern(&path->attr);
269
270 bgp_unlink_nexthop(path);
271 bgp_path_info_extra_free(&path->extra);
272 bgp_path_info_mpath_free(&path->mpath);
273 if (path->net)
274 bgp_addpath_free_info_data(&path->tx_addpath,
275 &path->net->tx_addpath);
276
277 peer_unlock(path->peer); /* bgp_path_info peer reference */
278
279 XFREE(MTYPE_BGP_ROUTE, path);
280 }
281
282 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
283 {
284 path->lock++;
285 return path;
286 }
287
288 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
289 {
290 assert(path && path->lock > 0);
291 path->lock--;
292
293 if (path->lock == 0) {
294 bgp_path_info_free(path);
295 return NULL;
296 }
297
298 return path;
299 }
300
301 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
302 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
303 {
304 struct peer *peer;
305 struct bgp_path_info *old_pi, *nextpi;
306 bool set_flag = false;
307 struct bgp *bgp = NULL;
308 struct bgp_table *table = NULL;
309 afi_t afi = 0;
310 safi_t safi = 0;
311
312 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
313 * then the route selection is deferred
314 */
315 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
316 return 0;
317
318 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
319 if (BGP_DEBUG(update, UPDATE_OUT)) {
320 table = bgp_dest_table(dest);
321 if (table)
322 bgp = table->bgp;
323
324 zlog_debug(
325 "Route %pBD(%s) is in workqueue and being processed, not deferred.",
326 dest, bgp ? bgp->name_pretty : "(Unknown)");
327 }
328
329 return 0;
330 }
331
332 table = bgp_dest_table(dest);
333 if (table) {
334 bgp = table->bgp;
335 afi = table->afi;
336 safi = table->safi;
337 }
338
339 for (old_pi = bgp_dest_get_bgp_path_info(dest);
340 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
341 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
342 continue;
343
344 /* Route selection is deferred if there is a stale path which
345 * which indicates peer is in restart mode
346 */
347 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
348 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
349 set_flag = true;
350 } else {
351 /* If the peer is graceful restart capable and peer is
352 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
353 */
354 peer = old_pi->peer;
355 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
356 && BGP_PEER_RESTARTING_MODE(peer)
357 && (old_pi
358 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
359 set_flag = true;
360 }
361 }
362 if (set_flag)
363 break;
364 }
365
366 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
367 * is active
368 */
369 if (set_flag && table) {
370 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
371 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
372 bgp->gr_info[afi][safi].gr_deferred++;
373 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
374 if (BGP_DEBUG(update, UPDATE_OUT))
375 zlog_debug("DEFER route %pBD(%s), dest %p",
376 dest, bgp->name_pretty, dest);
377 return 0;
378 }
379 }
380 return -1;
381 }
382
383 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
384 struct bgp_path_info *pi)
385 {
386 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
387 struct bgp_path_info *top;
388
389 top = bgp_dest_get_bgp_path_info(dest);
390
391 pi->next = top;
392 pi->prev = NULL;
393 if (top)
394 top->prev = pi;
395 bgp_dest_set_bgp_path_info(dest, pi);
396
397 bgp_path_info_lock(pi);
398 bgp_dest_lock_node(dest);
399 peer_lock(pi->peer); /* bgp_path_info peer reference */
400 bgp_dest_set_defer_flag(dest, false);
401 hook_call(bgp_snmp_update_stats, dest, pi, true);
402 }
403
404 /* Do the actual removal of info from RIB, for use by bgp_process
405 completion callback *only* */
406 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
407 {
408 if (pi->next)
409 pi->next->prev = pi->prev;
410 if (pi->prev)
411 pi->prev->next = pi->next;
412 else
413 bgp_dest_set_bgp_path_info(dest, pi->next);
414
415 bgp_path_info_mpath_dequeue(pi);
416 bgp_path_info_unlock(pi);
417 hook_call(bgp_snmp_update_stats, dest, pi, false);
418 bgp_dest_unlock_node(dest);
419 }
420
421 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
422 {
423 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
424 /* set of previous already took care of pcount */
425 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
426 }
427
428 /* undo the effects of a previous call to bgp_path_info_delete; typically
429 called when a route is deleted and then quickly re-added before the
430 deletion has been processed */
431 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
432 {
433 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
434 /* unset of previous already took care of pcount */
435 SET_FLAG(pi->flags, BGP_PATH_VALID);
436 }
437
438 /* Adjust pcount as required */
439 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
440 {
441 struct bgp_table *table;
442
443 assert(dest && bgp_dest_table(dest));
444 assert(pi && pi->peer && pi->peer->bgp);
445
446 table = bgp_dest_table(dest);
447
448 if (pi->peer == pi->peer->bgp->peer_self)
449 return;
450
451 if (!BGP_PATH_COUNTABLE(pi)
452 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
453
454 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
455
456 /* slight hack, but more robust against errors. */
457 if (pi->peer->pcount[table->afi][table->safi])
458 pi->peer->pcount[table->afi][table->safi]--;
459 else
460 flog_err(EC_LIB_DEVELOPMENT,
461 "Asked to decrement 0 prefix count for peer");
462 } else if (BGP_PATH_COUNTABLE(pi)
463 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
464 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
465 pi->peer->pcount[table->afi][table->safi]++;
466 }
467 }
468
469 static int bgp_label_index_differs(struct bgp_path_info *pi1,
470 struct bgp_path_info *pi2)
471 {
472 return (!(pi1->attr->label_index == pi2->attr->label_index));
473 }
474
475 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
476 * This is here primarily to keep prefix-count in check.
477 */
478 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
479 uint32_t flag)
480 {
481 SET_FLAG(pi->flags, flag);
482
483 /* early bath if we know it's not a flag that changes countability state
484 */
485 if (!CHECK_FLAG(flag,
486 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
487 return;
488
489 bgp_pcount_adjust(dest, pi);
490 }
491
492 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
493 uint32_t flag)
494 {
495 UNSET_FLAG(pi->flags, flag);
496
497 /* early bath if we know it's not a flag that changes countability state
498 */
499 if (!CHECK_FLAG(flag,
500 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
501 return;
502
503 bgp_pcount_adjust(dest, pi);
504 }
505
506 /* Get MED value. If MED value is missing and "bgp bestpath
507 missing-as-worst" is specified, treat it as the worst value. */
508 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
509 {
510 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
511 return attr->med;
512 else {
513 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
514 return BGP_MED_MAX;
515 else
516 return 0;
517 }
518 }
519
520 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
521 size_t buf_len)
522 {
523 struct peer *peer;
524
525 if (pi->sub_type == BGP_ROUTE_IMPORTED &&
526 bgp_get_imported_bpi_ultimate(pi))
527 peer = bgp_get_imported_bpi_ultimate(pi)->peer;
528 else
529 peer = pi->peer;
530
531 if (pi->addpath_rx_id)
532 snprintf(buf, buf_len, "path %s (addpath rxid %d)", peer->host,
533 pi->addpath_rx_id);
534 else
535 snprintf(buf, buf_len, "path %s", peer->host);
536 }
537
538
539 /*
540 * Get the ultimate path info.
541 */
542 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
543 {
544 struct bgp_path_info *bpi_ultimate;
545
546 if (info->sub_type != BGP_ROUTE_IMPORTED)
547 return info;
548
549 for (bpi_ultimate = info;
550 bpi_ultimate->extra && bpi_ultimate->extra->parent;
551 bpi_ultimate = bpi_ultimate->extra->parent)
552 ;
553
554 return bpi_ultimate;
555 }
556
557 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
558 */
559 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
560 struct bgp_path_info *exist, int *paths_eq,
561 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
562 char *pfx_buf, afi_t afi, safi_t safi,
563 enum bgp_path_selection_reason *reason)
564 {
565 const struct prefix *new_p;
566 struct attr *newattr, *existattr;
567 enum bgp_peer_sort new_sort;
568 enum bgp_peer_sort exist_sort;
569 uint32_t new_pref;
570 uint32_t exist_pref;
571 uint32_t new_med;
572 uint32_t exist_med;
573 uint32_t new_weight;
574 uint32_t exist_weight;
575 uint32_t newm, existm;
576 struct in_addr new_id;
577 struct in_addr exist_id;
578 int new_cluster;
579 int exist_cluster;
580 int internal_as_route;
581 int confed_as_route;
582 int ret = 0;
583 int igp_metric_ret = 0;
584 int peer_sort_ret = -1;
585 char new_buf[PATH_ADDPATH_STR_BUFFER];
586 char exist_buf[PATH_ADDPATH_STR_BUFFER];
587 uint32_t new_mm_seq;
588 uint32_t exist_mm_seq;
589 int nh_cmp;
590 esi_t *exist_esi;
591 esi_t *new_esi;
592 bool same_esi;
593 bool old_proxy;
594 bool new_proxy;
595 bool new_origin, exist_origin;
596 struct bgp_path_info *bpi_ultimate;
597 struct peer *peer_new, *peer_exist;
598
599 *paths_eq = 0;
600
601 /* 0. Null check. */
602 if (new == NULL) {
603 *reason = bgp_path_selection_none;
604 if (debug)
605 zlog_debug("%s: new is NULL", pfx_buf);
606 return 0;
607 }
608
609 if (debug) {
610 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
611 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
612 sizeof(new_buf));
613 }
614
615 if (exist == NULL) {
616 *reason = bgp_path_selection_first;
617 if (debug)
618 zlog_debug("%s(%s): %s is the initial bestpath",
619 pfx_buf, bgp->name_pretty, new_buf);
620 return 1;
621 }
622
623 if (debug) {
624 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
625 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
626 sizeof(exist_buf));
627 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
628 pfx_buf, bgp->name_pretty, new_buf, new->flags,
629 exist_buf, exist->flags);
630 }
631
632 newattr = new->attr;
633 existattr = exist->attr;
634
635 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
636 * Capability" to a neighbor MUST perform the following upon receiving
637 * a route from that neighbor with the "LLGR_STALE" community, or upon
638 * attaching the "LLGR_STALE" community itself per Section 4.2:
639 *
640 * Treat the route as the least-preferred in route selection (see
641 * below). See the Risks of Depreferencing Routes section (Section 5.2)
642 * for a discussion of potential risks inherent in doing this.
643 */
644 if (bgp_attr_get_community(newattr) &&
645 community_include(bgp_attr_get_community(newattr),
646 COMMUNITY_LLGR_STALE)) {
647 if (debug)
648 zlog_debug(
649 "%s: %s wins over %s due to LLGR_STALE community",
650 pfx_buf, new_buf, exist_buf);
651 return 0;
652 }
653
654 if (bgp_attr_get_community(existattr) &&
655 community_include(bgp_attr_get_community(existattr),
656 COMMUNITY_LLGR_STALE)) {
657 if (debug)
658 zlog_debug(
659 "%s: %s loses to %s due to LLGR_STALE community",
660 pfx_buf, new_buf, exist_buf);
661 return 1;
662 }
663
664 new_p = bgp_dest_get_prefix(new->net);
665
666 /* For EVPN routes, we cannot just go by local vs remote, we have to
667 * look at the MAC mobility sequence number, if present.
668 */
669 if ((safi == SAFI_EVPN)
670 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
671 /* This is an error condition described in RFC 7432 Section
672 * 15.2. The RFC
673 * states that in this scenario "the PE MUST alert the operator"
674 * but it
675 * does not state what other action to take. In order to provide
676 * some
677 * consistency in this scenario we are going to prefer the path
678 * with the
679 * sticky flag.
680 */
681 if (newattr->sticky != existattr->sticky) {
682 if (!debug) {
683 prefix2str(new_p, pfx_buf,
684 sizeof(*pfx_buf)
685 * PREFIX2STR_BUFFER);
686 bgp_path_info_path_with_addpath_rx_str(
687 new, new_buf, sizeof(new_buf));
688 bgp_path_info_path_with_addpath_rx_str(
689 exist, exist_buf, sizeof(exist_buf));
690 }
691
692 if (newattr->sticky && !existattr->sticky) {
693 *reason = bgp_path_selection_evpn_sticky_mac;
694 if (debug)
695 zlog_debug(
696 "%s: %s wins over %s due to sticky MAC flag",
697 pfx_buf, new_buf, exist_buf);
698 return 1;
699 }
700
701 if (!newattr->sticky && existattr->sticky) {
702 *reason = bgp_path_selection_evpn_sticky_mac;
703 if (debug)
704 zlog_debug(
705 "%s: %s loses to %s due to sticky MAC flag",
706 pfx_buf, new_buf, exist_buf);
707 return 0;
708 }
709 }
710
711 new_esi = bgp_evpn_attr_get_esi(newattr);
712 exist_esi = bgp_evpn_attr_get_esi(existattr);
713 if (bgp_evpn_is_esi_valid(new_esi) &&
714 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
715 same_esi = true;
716 } else {
717 same_esi = false;
718 }
719
720 /* If both paths have the same non-zero ES and
721 * one path is local it wins.
722 * PS: Note the local path wins even if the remote
723 * has the higher MM seq. The local path's
724 * MM seq will be fixed up to match the highest
725 * rem seq, subsequently.
726 */
727 if (same_esi) {
728 char esi_buf[ESI_STR_LEN];
729
730 if (bgp_evpn_is_path_local(bgp, new)) {
731 *reason = bgp_path_selection_evpn_local_path;
732 if (debug)
733 zlog_debug(
734 "%s: %s wins over %s as ES %s is same and local",
735 pfx_buf, new_buf, exist_buf,
736 esi_to_str(new_esi, esi_buf,
737 sizeof(esi_buf)));
738 return 1;
739 }
740 if (bgp_evpn_is_path_local(bgp, exist)) {
741 *reason = bgp_path_selection_evpn_local_path;
742 if (debug)
743 zlog_debug(
744 "%s: %s loses to %s as ES %s is same and local",
745 pfx_buf, new_buf, exist_buf,
746 esi_to_str(new_esi, esi_buf,
747 sizeof(esi_buf)));
748 return 0;
749 }
750 }
751
752 new_mm_seq = mac_mobility_seqnum(newattr);
753 exist_mm_seq = mac_mobility_seqnum(existattr);
754
755 if (new_mm_seq > exist_mm_seq) {
756 *reason = bgp_path_selection_evpn_seq;
757 if (debug)
758 zlog_debug(
759 "%s: %s wins over %s due to MM seq %u > %u",
760 pfx_buf, new_buf, exist_buf, new_mm_seq,
761 exist_mm_seq);
762 return 1;
763 }
764
765 if (new_mm_seq < exist_mm_seq) {
766 *reason = bgp_path_selection_evpn_seq;
767 if (debug)
768 zlog_debug(
769 "%s: %s loses to %s due to MM seq %u < %u",
770 pfx_buf, new_buf, exist_buf, new_mm_seq,
771 exist_mm_seq);
772 return 0;
773 }
774
775 /* if the sequence numbers and ESI are the same and one path
776 * is non-proxy it wins (over proxy)
777 */
778 new_proxy = bgp_evpn_attr_is_proxy(newattr);
779 old_proxy = bgp_evpn_attr_is_proxy(existattr);
780 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
781 old_proxy != new_proxy) {
782 if (!new_proxy) {
783 *reason = bgp_path_selection_evpn_non_proxy;
784 if (debug)
785 zlog_debug(
786 "%s: %s wins over %s, same seq/es and non-proxy",
787 pfx_buf, new_buf, exist_buf);
788 return 1;
789 }
790
791 *reason = bgp_path_selection_evpn_non_proxy;
792 if (debug)
793 zlog_debug(
794 "%s: %s loses to %s, same seq/es and non-proxy",
795 pfx_buf, new_buf, exist_buf);
796 return 0;
797 }
798
799 /*
800 * if sequence numbers are the same path with the lowest IP
801 * wins
802 */
803 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
804 if (nh_cmp < 0) {
805 *reason = bgp_path_selection_evpn_lower_ip;
806 if (debug)
807 zlog_debug(
808 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
809 pfx_buf, new_buf, exist_buf, new_mm_seq,
810 &new->attr->nexthop);
811 return 1;
812 }
813 if (nh_cmp > 0) {
814 *reason = bgp_path_selection_evpn_lower_ip;
815 if (debug)
816 zlog_debug(
817 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
818 pfx_buf, new_buf, exist_buf, new_mm_seq,
819 &new->attr->nexthop);
820 return 0;
821 }
822 }
823
824 /* 1. Weight check. */
825 new_weight = newattr->weight;
826 exist_weight = existattr->weight;
827
828 if (new_weight > exist_weight) {
829 *reason = bgp_path_selection_weight;
830 if (debug)
831 zlog_debug("%s: %s wins over %s due to weight %d > %d",
832 pfx_buf, new_buf, exist_buf, new_weight,
833 exist_weight);
834 return 1;
835 }
836
837 if (new_weight < exist_weight) {
838 *reason = bgp_path_selection_weight;
839 if (debug)
840 zlog_debug("%s: %s loses to %s due to weight %d < %d",
841 pfx_buf, new_buf, exist_buf, new_weight,
842 exist_weight);
843 return 0;
844 }
845
846 /* 2. Local preference check. */
847 new_pref = exist_pref = bgp->default_local_pref;
848
849 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
850 new_pref = newattr->local_pref;
851 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
852 exist_pref = existattr->local_pref;
853
854 if (new_pref > exist_pref) {
855 *reason = bgp_path_selection_local_pref;
856 if (debug)
857 zlog_debug(
858 "%s: %s wins over %s due to localpref %d > %d",
859 pfx_buf, new_buf, exist_buf, new_pref,
860 exist_pref);
861 return 1;
862 }
863
864 if (new_pref < exist_pref) {
865 *reason = bgp_path_selection_local_pref;
866 if (debug)
867 zlog_debug(
868 "%s: %s loses to %s due to localpref %d < %d",
869 pfx_buf, new_buf, exist_buf, new_pref,
870 exist_pref);
871 return 0;
872 }
873
874 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
875 * extensions defined in this document, the following step is inserted
876 * after the LOCAL_PREF comparison step in the BGP decision process:
877 * When comparing a pair of routes for a BGP destination, the
878 * route with the ACCEPT_OWN community attached is preferred over
879 * the route that does not have the community.
880 * This extra step MUST only be invoked during the best path selection
881 * process of VPN-IP routes.
882 */
883 if (safi == SAFI_MPLS_VPN &&
884 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
885 CHECK_FLAG(exist->peer->af_flags[afi][safi],
886 PEER_FLAG_ACCEPT_OWN))) {
887 bool new_accept_own = false;
888 bool exist_accept_own = false;
889 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
890
891 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
892 new_accept_own = community_include(
893 bgp_attr_get_community(newattr), accept_own);
894 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
895 exist_accept_own = community_include(
896 bgp_attr_get_community(existattr), accept_own);
897
898 if (new_accept_own && !exist_accept_own) {
899 *reason = bgp_path_selection_accept_own;
900 if (debug)
901 zlog_debug(
902 "%s: %s wins over %s due to accept-own",
903 pfx_buf, new_buf, exist_buf);
904 return 1;
905 }
906
907 if (!new_accept_own && exist_accept_own) {
908 *reason = bgp_path_selection_accept_own;
909 if (debug)
910 zlog_debug(
911 "%s: %s loses to %s due to accept-own",
912 pfx_buf, new_buf, exist_buf);
913 return 0;
914 }
915 }
916
917 /* Tie-breaker - AIGP (Metric TLV) attribute */
918 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
919 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
920 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
921 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
922 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
923
924 if (new_aigp < exist_aigp) {
925 *reason = bgp_path_selection_aigp;
926 if (debug)
927 zlog_debug(
928 "%s: %s wins over %s due to AIGP %" PRIu64
929 " < %" PRIu64,
930 pfx_buf, new_buf, exist_buf, new_aigp,
931 exist_aigp);
932 return 1;
933 }
934
935 if (new_aigp > exist_aigp) {
936 *reason = bgp_path_selection_aigp;
937 if (debug)
938 zlog_debug(
939 "%s: %s loses to %s due to AIGP %" PRIu64
940 " > %" PRIu64,
941 pfx_buf, new_buf, exist_buf, new_aigp,
942 exist_aigp);
943 return 0;
944 }
945 }
946
947 /* 3. Local route check. We prefer:
948 * - BGP_ROUTE_STATIC
949 * - BGP_ROUTE_AGGREGATE
950 * - BGP_ROUTE_REDISTRIBUTE
951 */
952 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
953 new->sub_type == BGP_ROUTE_IMPORTED);
954 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
955 exist->sub_type == BGP_ROUTE_IMPORTED);
956
957 if (new_origin && !exist_origin) {
958 *reason = bgp_path_selection_local_route;
959 if (debug)
960 zlog_debug(
961 "%s: %s wins over %s due to preferred BGP_ROUTE type",
962 pfx_buf, new_buf, exist_buf);
963 return 1;
964 }
965
966 if (!new_origin && exist_origin) {
967 *reason = bgp_path_selection_local_route;
968 if (debug)
969 zlog_debug(
970 "%s: %s loses to %s due to preferred BGP_ROUTE type",
971 pfx_buf, new_buf, exist_buf);
972 return 0;
973 }
974
975 /* Here if these are imported routes then get ultimate pi for
976 * path compare.
977 */
978 new = bgp_get_imported_bpi_ultimate(new);
979 exist = bgp_get_imported_bpi_ultimate(exist);
980 newattr = new->attr;
981 existattr = exist->attr;
982
983 /* 4. AS path length check. */
984 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
985 int exist_hops = aspath_count_hops(existattr->aspath);
986 int exist_confeds = aspath_count_confeds(existattr->aspath);
987
988 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
989 int aspath_hops;
990
991 aspath_hops = aspath_count_hops(newattr->aspath);
992 aspath_hops += aspath_count_confeds(newattr->aspath);
993
994 if (aspath_hops < (exist_hops + exist_confeds)) {
995 *reason = bgp_path_selection_confed_as_path;
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
999 pfx_buf, new_buf, exist_buf,
1000 aspath_hops,
1001 (exist_hops + exist_confeds));
1002 return 1;
1003 }
1004
1005 if (aspath_hops > (exist_hops + exist_confeds)) {
1006 *reason = bgp_path_selection_confed_as_path;
1007 if (debug)
1008 zlog_debug(
1009 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1010 pfx_buf, new_buf, exist_buf,
1011 aspath_hops,
1012 (exist_hops + exist_confeds));
1013 return 0;
1014 }
1015 } else {
1016 int newhops = aspath_count_hops(newattr->aspath);
1017
1018 if (newhops < exist_hops) {
1019 *reason = bgp_path_selection_as_path;
1020 if (debug)
1021 zlog_debug(
1022 "%s: %s wins over %s due to aspath hopcount %d < %d",
1023 pfx_buf, new_buf, exist_buf,
1024 newhops, exist_hops);
1025 return 1;
1026 }
1027
1028 if (newhops > exist_hops) {
1029 *reason = bgp_path_selection_as_path;
1030 if (debug)
1031 zlog_debug(
1032 "%s: %s loses to %s due to aspath hopcount %d > %d",
1033 pfx_buf, new_buf, exist_buf,
1034 newhops, exist_hops);
1035 return 0;
1036 }
1037 }
1038 }
1039
1040 /* 5. Origin check. */
1041 if (newattr->origin < existattr->origin) {
1042 *reason = bgp_path_selection_origin;
1043 if (debug)
1044 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1045 pfx_buf, new_buf, exist_buf,
1046 bgp_origin_long_str[newattr->origin],
1047 bgp_origin_long_str[existattr->origin]);
1048 return 1;
1049 }
1050
1051 if (newattr->origin > existattr->origin) {
1052 *reason = bgp_path_selection_origin;
1053 if (debug)
1054 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1055 pfx_buf, new_buf, exist_buf,
1056 bgp_origin_long_str[newattr->origin],
1057 bgp_origin_long_str[existattr->origin]);
1058 return 0;
1059 }
1060
1061 /* 6. MED check. */
1062 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1063 && aspath_count_hops(existattr->aspath) == 0);
1064 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1065 && aspath_count_confeds(existattr->aspath) > 0
1066 && aspath_count_hops(newattr->aspath) == 0
1067 && aspath_count_hops(existattr->aspath) == 0);
1068
1069 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1070 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1071 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1072 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1073 || internal_as_route) {
1074 new_med = bgp_med_value(new->attr, bgp);
1075 exist_med = bgp_med_value(exist->attr, bgp);
1076
1077 if (new_med < exist_med) {
1078 *reason = bgp_path_selection_med;
1079 if (debug)
1080 zlog_debug(
1081 "%s: %s wins over %s due to MED %d < %d",
1082 pfx_buf, new_buf, exist_buf, new_med,
1083 exist_med);
1084 return 1;
1085 }
1086
1087 if (new_med > exist_med) {
1088 *reason = bgp_path_selection_med;
1089 if (debug)
1090 zlog_debug(
1091 "%s: %s loses to %s due to MED %d > %d",
1092 pfx_buf, new_buf, exist_buf, new_med,
1093 exist_med);
1094 return 0;
1095 }
1096 }
1097
1098 if (exist->sub_type == BGP_ROUTE_IMPORTED) {
1099 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
1100 peer_exist = bpi_ultimate->peer;
1101 } else
1102 peer_exist = exist->peer;
1103
1104 if (new->sub_type == BGP_ROUTE_IMPORTED) {
1105 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
1106 peer_new = bpi_ultimate->peer;
1107 } else
1108 peer_new = new->peer;
1109
1110 /* 7. Peer type check. */
1111 new_sort = peer_new->sort;
1112 exist_sort = peer_exist->sort;
1113
1114 if (new_sort == BGP_PEER_EBGP
1115 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1116 *reason = bgp_path_selection_peer;
1117 if (debug)
1118 zlog_debug(
1119 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1120 pfx_buf, new_buf, exist_buf);
1121 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_EBGP
1127 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1128 *reason = bgp_path_selection_peer;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1134 return 0;
1135 peer_sort_ret = 0;
1136 }
1137
1138 /* 8. IGP metric check. */
1139 newm = existm = 0;
1140
1141 if (new->extra)
1142 newm = new->extra->igpmetric;
1143 if (exist->extra)
1144 existm = exist->extra->igpmetric;
1145
1146 if (newm < existm) {
1147 if (debug && peer_sort_ret < 0)
1148 zlog_debug(
1149 "%s: %s wins over %s due to IGP metric %u < %u",
1150 pfx_buf, new_buf, exist_buf, newm, existm);
1151 igp_metric_ret = 1;
1152 }
1153
1154 if (newm > existm) {
1155 if (debug && peer_sort_ret < 0)
1156 zlog_debug(
1157 "%s: %s loses to %s due to IGP metric %u > %u",
1158 pfx_buf, new_buf, exist_buf, newm, existm);
1159 igp_metric_ret = 0;
1160 }
1161
1162 /* 9. Same IGP metric. Compare the cluster list length as
1163 representative of IGP hops metric. Rewrite the metric value
1164 pair (newm, existm) with the cluster list length. Prefer the
1165 path with smaller cluster list length. */
1166 if (newm == existm) {
1167 if (peer_sort_lookup(peer_new) == BGP_PEER_IBGP &&
1168 peer_sort_lookup(peer_exist) == BGP_PEER_IBGP &&
1169 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1170 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1171 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1172
1173 if (newm < existm) {
1174 if (debug && peer_sort_ret < 0)
1175 zlog_debug(
1176 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1177 pfx_buf, new_buf, exist_buf,
1178 newm, existm);
1179 igp_metric_ret = 1;
1180 }
1181
1182 if (newm > existm) {
1183 if (debug && peer_sort_ret < 0)
1184 zlog_debug(
1185 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1186 pfx_buf, new_buf, exist_buf,
1187 newm, existm);
1188 igp_metric_ret = 0;
1189 }
1190 }
1191 }
1192
1193 /* 10. confed-external vs. confed-internal */
1194 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1195 if (new_sort == BGP_PEER_CONFED
1196 && exist_sort == BGP_PEER_IBGP) {
1197 *reason = bgp_path_selection_confed;
1198 if (debug)
1199 zlog_debug(
1200 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1201 pfx_buf, new_buf, exist_buf);
1202 if (!CHECK_FLAG(bgp->flags,
1203 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1204 return 1;
1205 peer_sort_ret = 1;
1206 }
1207
1208 if (exist_sort == BGP_PEER_CONFED
1209 && new_sort == BGP_PEER_IBGP) {
1210 *reason = bgp_path_selection_confed;
1211 if (debug)
1212 zlog_debug(
1213 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1214 pfx_buf, new_buf, exist_buf);
1215 if (!CHECK_FLAG(bgp->flags,
1216 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1217 return 0;
1218 peer_sort_ret = 0;
1219 }
1220 }
1221
1222 /* 11. Maximum path check. */
1223 if (newm == existm) {
1224 /* If one path has a label but the other does not, do not treat
1225 * them as equals for multipath
1226 */
1227 int newl, existl;
1228
1229 newl = existl = 0;
1230
1231 if (new->extra)
1232 newl = new->extra->num_labels;
1233 if (exist->extra)
1234 existl = exist->extra->num_labels;
1235 if (((new->extra &&bgp_is_valid_label(&new->extra->label[0])) !=
1236 (exist->extra &&
1237 bgp_is_valid_label(&exist->extra->label[0]))) ||
1238 (newl != existl)) {
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1242 pfx_buf, new_buf, exist_buf);
1243 } else if (CHECK_FLAG(bgp->flags,
1244 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1245
1246 /*
1247 * For the two paths, all comparison steps till IGP
1248 * metric
1249 * have succeeded - including AS_PATH hop count. Since
1250 * 'bgp
1251 * bestpath as-path multipath-relax' knob is on, we
1252 * don't need
1253 * an exact match of AS_PATH. Thus, mark the paths are
1254 * equal.
1255 * That will trigger both these paths to get into the
1256 * multipath
1257 * array.
1258 */
1259 *paths_eq = 1;
1260
1261 if (debug)
1262 zlog_debug(
1263 "%s: %s and %s are equal via multipath-relax",
1264 pfx_buf, new_buf, exist_buf);
1265 } else if (peer_new->sort == BGP_PEER_IBGP) {
1266 if (aspath_cmp(new->attr->aspath,
1267 exist->attr->aspath)) {
1268 *paths_eq = 1;
1269
1270 if (debug)
1271 zlog_debug(
1272 "%s: %s and %s are equal via matching aspaths",
1273 pfx_buf, new_buf, exist_buf);
1274 }
1275 } else if (peer_new->as == peer_exist->as) {
1276 *paths_eq = 1;
1277
1278 if (debug)
1279 zlog_debug(
1280 "%s: %s and %s are equal via same remote-as",
1281 pfx_buf, new_buf, exist_buf);
1282 }
1283 } else {
1284 /*
1285 * TODO: If unequal cost ibgp multipath is enabled we can
1286 * mark the paths as equal here instead of returning
1287 */
1288
1289 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1290 * if either step 7 or 10 (peer type checks) yielded a winner,
1291 * that result was returned immediately. Returning from step 10
1292 * ignored the return value computed in steps 8 and 9 (IGP
1293 * metric checks). In order to preserve that behavior, if
1294 * peer_sort_ret is set, return that rather than igp_metric_ret.
1295 */
1296 ret = peer_sort_ret;
1297 if (peer_sort_ret < 0) {
1298 ret = igp_metric_ret;
1299 if (debug) {
1300 if (ret == 1)
1301 zlog_debug(
1302 "%s: %s wins over %s after IGP metric comparison",
1303 pfx_buf, new_buf, exist_buf);
1304 else
1305 zlog_debug(
1306 "%s: %s loses to %s after IGP metric comparison",
1307 pfx_buf, new_buf, exist_buf);
1308 }
1309 *reason = bgp_path_selection_igp_metric;
1310 }
1311 return ret;
1312 }
1313
1314 /*
1315 * At this point, the decision whether to set *paths_eq = 1 has been
1316 * completed. If we deferred returning because of bestpath peer-type
1317 * relax configuration, return now.
1318 */
1319 if (peer_sort_ret >= 0)
1320 return peer_sort_ret;
1321
1322 /* 12. If both paths are external, prefer the path that was received
1323 first (the oldest one). This step minimizes route-flap, since a
1324 newer path won't displace an older one, even if it was the
1325 preferred route based on the additional decision criteria below. */
1326 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1327 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1328 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1329 *reason = bgp_path_selection_older;
1330 if (debug)
1331 zlog_debug(
1332 "%s: %s wins over %s due to oldest external",
1333 pfx_buf, new_buf, exist_buf);
1334 return 1;
1335 }
1336
1337 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1338 *reason = bgp_path_selection_older;
1339 if (debug)
1340 zlog_debug(
1341 "%s: %s loses to %s due to oldest external",
1342 pfx_buf, new_buf, exist_buf);
1343 return 0;
1344 }
1345 }
1346
1347 /* 13. Router-ID comparison. */
1348 /* If one of the paths is "stale", the corresponding peer router-id will
1349 * be 0 and would always win over the other path. If originator id is
1350 * used for the comparison, it will decide which path is better.
1351 */
1352 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1353 new_id.s_addr = newattr->originator_id.s_addr;
1354 else
1355 new_id.s_addr = peer_new->remote_id.s_addr;
1356 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1357 exist_id.s_addr = existattr->originator_id.s_addr;
1358 else
1359 exist_id.s_addr = peer_exist->remote_id.s_addr;
1360
1361 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1362 *reason = bgp_path_selection_router_id;
1363 if (debug)
1364 zlog_debug(
1365 "%s: %s wins over %s due to Router-ID comparison",
1366 pfx_buf, new_buf, exist_buf);
1367 return 1;
1368 }
1369
1370 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1371 *reason = bgp_path_selection_router_id;
1372 if (debug)
1373 zlog_debug(
1374 "%s: %s loses to %s due to Router-ID comparison",
1375 pfx_buf, new_buf, exist_buf);
1376 return 0;
1377 }
1378
1379 /* 14. Cluster length comparison. */
1380 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1381 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1382
1383 if (new_cluster < exist_cluster) {
1384 *reason = bgp_path_selection_cluster_length;
1385 if (debug)
1386 zlog_debug(
1387 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1388 pfx_buf, new_buf, exist_buf, new_cluster,
1389 exist_cluster);
1390 return 1;
1391 }
1392
1393 if (new_cluster > exist_cluster) {
1394 *reason = bgp_path_selection_cluster_length;
1395 if (debug)
1396 zlog_debug(
1397 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1398 pfx_buf, new_buf, exist_buf, new_cluster,
1399 exist_cluster);
1400 return 0;
1401 }
1402
1403 /* 15. Neighbor address comparison. */
1404 /* Do this only if neither path is "stale" as stale paths do not have
1405 * valid peer information (as the connection may or may not be up).
1406 */
1407 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1408 *reason = bgp_path_selection_stale;
1409 if (debug)
1410 zlog_debug(
1411 "%s: %s wins over %s due to latter path being STALE",
1412 pfx_buf, new_buf, exist_buf);
1413 return 1;
1414 }
1415
1416 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1417 *reason = bgp_path_selection_stale;
1418 if (debug)
1419 zlog_debug(
1420 "%s: %s loses to %s due to former path being STALE",
1421 pfx_buf, new_buf, exist_buf);
1422 return 0;
1423 }
1424
1425 /* locally configured routes to advertise do not have su_remote */
1426 if (peer_new->su_remote == NULL) {
1427 *reason = bgp_path_selection_local_configured;
1428 return 0;
1429 }
1430
1431 if (peer_exist->su_remote == NULL) {
1432 *reason = bgp_path_selection_local_configured;
1433 return 1;
1434 }
1435
1436 ret = sockunion_cmp(peer_new->su_remote, peer_exist->su_remote);
1437
1438 if (ret == 1) {
1439 *reason = bgp_path_selection_neighbor_ip;
1440 if (debug)
1441 zlog_debug(
1442 "%s: %s loses to %s due to Neighor IP comparison",
1443 pfx_buf, new_buf, exist_buf);
1444 return 0;
1445 }
1446
1447 if (ret == -1) {
1448 *reason = bgp_path_selection_neighbor_ip;
1449 if (debug)
1450 zlog_debug(
1451 "%s: %s wins over %s due to Neighor IP comparison",
1452 pfx_buf, new_buf, exist_buf);
1453 return 1;
1454 }
1455
1456 *reason = bgp_path_selection_default;
1457 if (debug)
1458 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1459 pfx_buf, new_buf, exist_buf);
1460
1461 return 1;
1462 }
1463
1464
1465 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1466 struct bgp_path_info *exist, int *paths_eq)
1467 {
1468 enum bgp_path_selection_reason reason;
1469 char pfx_buf[PREFIX2STR_BUFFER];
1470
1471 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1472 AFI_L2VPN, SAFI_EVPN, &reason);
1473 }
1474
1475 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1476 * is preferred, or 0 if they are the same (usually will only occur if
1477 * multipath is enabled
1478 * This version is compatible with */
1479 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1480 struct bgp_path_info *exist, char *pfx_buf,
1481 afi_t afi, safi_t safi,
1482 enum bgp_path_selection_reason *reason)
1483 {
1484 int paths_eq;
1485 int ret;
1486 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1487 afi, safi, reason);
1488
1489 if (paths_eq)
1490 ret = 0;
1491 else {
1492 if (ret == 1)
1493 ret = -1;
1494 else
1495 ret = 1;
1496 }
1497 return ret;
1498 }
1499
1500 static enum filter_type bgp_input_filter(struct peer *peer,
1501 const struct prefix *p,
1502 struct attr *attr, afi_t afi,
1503 safi_t safi)
1504 {
1505 struct bgp_filter *filter;
1506 enum filter_type ret = FILTER_PERMIT;
1507
1508 filter = &peer->filter[afi][safi];
1509
1510 #define FILTER_EXIST_WARN(F, f, filter) \
1511 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1512 zlog_debug("%s: Could not find configured input %s-list %s!", \
1513 peer->host, #f, F##_IN_NAME(filter));
1514
1515 if (DISTRIBUTE_IN_NAME(filter)) {
1516 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1517
1518 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1519 == FILTER_DENY) {
1520 ret = FILTER_DENY;
1521 goto done;
1522 }
1523 }
1524
1525 if (PREFIX_LIST_IN_NAME(filter)) {
1526 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1527
1528 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1529 == PREFIX_DENY) {
1530 ret = FILTER_DENY;
1531 goto done;
1532 }
1533 }
1534
1535 if (FILTER_LIST_IN_NAME(filter)) {
1536 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1537
1538 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1539 == AS_FILTER_DENY) {
1540 ret = FILTER_DENY;
1541 goto done;
1542 }
1543 }
1544
1545 done:
1546 if (frrtrace_enabled(frr_bgp, input_filter)) {
1547 char pfxprint[PREFIX2STR_BUFFER];
1548
1549 prefix2str(p, pfxprint, sizeof(pfxprint));
1550 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1551 ret == FILTER_PERMIT ? "permit" : "deny");
1552 }
1553
1554 return ret;
1555 #undef FILTER_EXIST_WARN
1556 }
1557
1558 static enum filter_type bgp_output_filter(struct peer *peer,
1559 const struct prefix *p,
1560 struct attr *attr, afi_t afi,
1561 safi_t safi)
1562 {
1563 struct bgp_filter *filter;
1564 enum filter_type ret = FILTER_PERMIT;
1565
1566 filter = &peer->filter[afi][safi];
1567
1568 #define FILTER_EXIST_WARN(F, f, filter) \
1569 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1570 zlog_debug("%s: Could not find configured output %s-list %s!", \
1571 peer->host, #f, F##_OUT_NAME(filter));
1572
1573 if (DISTRIBUTE_OUT_NAME(filter)) {
1574 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1575
1576 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1577 == FILTER_DENY) {
1578 ret = FILTER_DENY;
1579 goto done;
1580 }
1581 }
1582
1583 if (PREFIX_LIST_OUT_NAME(filter)) {
1584 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1585
1586 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1587 == PREFIX_DENY) {
1588 ret = FILTER_DENY;
1589 goto done;
1590 }
1591 }
1592
1593 if (FILTER_LIST_OUT_NAME(filter)) {
1594 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1595
1596 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1597 == AS_FILTER_DENY) {
1598 ret = FILTER_DENY;
1599 goto done;
1600 }
1601 }
1602
1603 if (frrtrace_enabled(frr_bgp, output_filter)) {
1604 char pfxprint[PREFIX2STR_BUFFER];
1605
1606 prefix2str(p, pfxprint, sizeof(pfxprint));
1607 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1608 ret == FILTER_PERMIT ? "permit" : "deny");
1609 }
1610
1611 done:
1612 return ret;
1613 #undef FILTER_EXIST_WARN
1614 }
1615
1616 /* If community attribute includes no_export then return 1. */
1617 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1618 {
1619 if (bgp_attr_get_community(attr)) {
1620 /* NO_ADVERTISE check. */
1621 if (community_include(bgp_attr_get_community(attr),
1622 COMMUNITY_NO_ADVERTISE))
1623 return true;
1624
1625 /* NO_EXPORT check. */
1626 if (peer->sort == BGP_PEER_EBGP &&
1627 community_include(bgp_attr_get_community(attr),
1628 COMMUNITY_NO_EXPORT))
1629 return true;
1630
1631 /* NO_EXPORT_SUBCONFED check. */
1632 if (peer->sort == BGP_PEER_EBGP
1633 || peer->sort == BGP_PEER_CONFED)
1634 if (community_include(bgp_attr_get_community(attr),
1635 COMMUNITY_NO_EXPORT_SUBCONFED))
1636 return true;
1637 }
1638 return false;
1639 }
1640
1641 /* Route reflection loop check. */
1642 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1643 {
1644 struct in_addr cluster_id;
1645 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1646
1647 if (cluster) {
1648 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1649 cluster_id = peer->bgp->cluster_id;
1650 else
1651 cluster_id = peer->bgp->router_id;
1652
1653 if (cluster_loop_check(cluster, cluster_id))
1654 return true;
1655 }
1656 return false;
1657 }
1658
1659 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1660 {
1661 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1662 if (peer->local_role == ROLE_PROVIDER ||
1663 peer->local_role == ROLE_RS_SERVER)
1664 return true;
1665 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1666 return true;
1667 return false;
1668 }
1669 if (peer->local_role == ROLE_CUSTOMER ||
1670 peer->local_role == ROLE_PEER ||
1671 peer->local_role == ROLE_RS_CLIENT) {
1672 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1673 attr->otc = peer->as;
1674 }
1675 return false;
1676 }
1677
1678 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1679 {
1680 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1681 if (peer->local_role == ROLE_CUSTOMER ||
1682 peer->local_role == ROLE_RS_CLIENT ||
1683 peer->local_role == ROLE_PEER)
1684 return true;
1685 return false;
1686 }
1687 if (peer->local_role == ROLE_PROVIDER ||
1688 peer->local_role == ROLE_PEER ||
1689 peer->local_role == ROLE_RS_SERVER) {
1690 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1691 attr->otc = peer->bgp->as;
1692 }
1693 return false;
1694 }
1695
1696 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1697 {
1698 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1699 }
1700
1701 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1702 struct attr *attr, afi_t afi, safi_t safi,
1703 const char *rmap_name, mpls_label_t *label,
1704 uint32_t num_labels, struct bgp_dest *dest)
1705 {
1706 struct bgp_filter *filter;
1707 struct bgp_path_info rmap_path = { 0 };
1708 struct bgp_path_info_extra extra = { 0 };
1709 route_map_result_t ret;
1710 struct route_map *rmap = NULL;
1711
1712 filter = &peer->filter[afi][safi];
1713
1714 /* Apply default weight value. */
1715 if (peer->weight[afi][safi])
1716 attr->weight = peer->weight[afi][safi];
1717
1718 if (rmap_name) {
1719 rmap = route_map_lookup_by_name(rmap_name);
1720
1721 if (rmap == NULL)
1722 return RMAP_DENY;
1723 } else {
1724 if (ROUTE_MAP_IN_NAME(filter)) {
1725 rmap = ROUTE_MAP_IN(filter);
1726
1727 if (rmap == NULL)
1728 return RMAP_DENY;
1729 }
1730 }
1731
1732 /* Route map apply. */
1733 if (rmap) {
1734 memset(&rmap_path, 0, sizeof(rmap_path));
1735 /* Duplicate current value to new structure for modification. */
1736 rmap_path.peer = peer;
1737 rmap_path.attr = attr;
1738 rmap_path.extra = &extra;
1739 rmap_path.net = dest;
1740
1741 extra.num_labels = num_labels;
1742 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1743 memcpy(extra.label, label,
1744 num_labels * sizeof(mpls_label_t));
1745
1746 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1747
1748 /* Apply BGP route map to the attribute. */
1749 ret = route_map_apply(rmap, p, &rmap_path);
1750
1751 peer->rmap_type = 0;
1752
1753 if (ret == RMAP_DENYMATCH)
1754 return RMAP_DENY;
1755 }
1756 return RMAP_PERMIT;
1757 }
1758
1759 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1760 struct attr *attr, afi_t afi, safi_t safi,
1761 const char *rmap_name)
1762 {
1763 struct bgp_path_info rmap_path;
1764 route_map_result_t ret;
1765 struct route_map *rmap = NULL;
1766 uint8_t rmap_type;
1767
1768 /*
1769 * So if we get to this point and have no rmap_name
1770 * we want to just show the output as it currently
1771 * exists.
1772 */
1773 if (!rmap_name)
1774 return RMAP_PERMIT;
1775
1776 /* Apply default weight value. */
1777 if (peer->weight[afi][safi])
1778 attr->weight = peer->weight[afi][safi];
1779
1780 rmap = route_map_lookup_by_name(rmap_name);
1781
1782 /*
1783 * If we have a route map name and we do not find
1784 * the routemap that means we have an implicit
1785 * deny.
1786 */
1787 if (rmap == NULL)
1788 return RMAP_DENY;
1789
1790 memset(&rmap_path, 0, sizeof(rmap_path));
1791 /* Route map apply. */
1792 /* Duplicate current value to new structure for modification. */
1793 rmap_path.peer = peer;
1794 rmap_path.attr = attr;
1795
1796 rmap_type = peer->rmap_type;
1797 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1798
1799 /* Apply BGP route map to the attribute. */
1800 ret = route_map_apply(rmap, p, &rmap_path);
1801
1802 peer->rmap_type = rmap_type;
1803
1804 if (ret == RMAP_DENYMATCH)
1805 /*
1806 * caller has multiple error paths with bgp_attr_flush()
1807 */
1808 return RMAP_DENY;
1809
1810 return RMAP_PERMIT;
1811 }
1812
1813 /* If this is an EBGP peer with remove-private-AS */
1814 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1815 struct peer *peer, struct attr *attr)
1816 {
1817 if (peer->sort == BGP_PEER_EBGP
1818 && (peer_af_flag_check(peer, afi, safi,
1819 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1820 || peer_af_flag_check(peer, afi, safi,
1821 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1822 || peer_af_flag_check(peer, afi, safi,
1823 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1824 || peer_af_flag_check(peer, afi, safi,
1825 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1826 // Take action on the entire aspath
1827 if (peer_af_flag_check(peer, afi, safi,
1828 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1829 || peer_af_flag_check(peer, afi, safi,
1830 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1831 if (peer_af_flag_check(
1832 peer, afi, safi,
1833 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1834 attr->aspath = aspath_replace_private_asns(
1835 attr->aspath, bgp->as, peer->as);
1836
1837 /*
1838 * Even if the aspath consists of just private ASNs we
1839 * need to walk the AS-Path to maintain all instances
1840 * of the peer's ASN to break possible loops.
1841 */
1842 else
1843 attr->aspath = aspath_remove_private_asns(
1844 attr->aspath, peer->as);
1845 }
1846
1847 // 'all' was not specified so the entire aspath must be private
1848 // ASNs
1849 // for us to do anything
1850 else if (aspath_private_as_check(attr->aspath)) {
1851 if (peer_af_flag_check(
1852 peer, afi, safi,
1853 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1854 attr->aspath = aspath_replace_private_asns(
1855 attr->aspath, bgp->as, peer->as);
1856 else
1857 /*
1858 * Walk the aspath to retain any instances of
1859 * the peer_asn
1860 */
1861 attr->aspath = aspath_remove_private_asns(
1862 attr->aspath, peer->as);
1863 }
1864 }
1865 }
1866
1867 /* If this is an EBGP peer with as-override */
1868 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1869 struct peer *peer, struct attr *attr)
1870 {
1871 struct aspath *aspath;
1872
1873 if (peer->sort == BGP_PEER_EBGP &&
1874 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1875 if (attr->aspath->refcnt)
1876 aspath = aspath_dup(attr->aspath);
1877 else
1878 aspath = attr->aspath;
1879
1880 attr->aspath = aspath_intern(
1881 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1882
1883 aspath_free(aspath);
1884 }
1885 }
1886
1887 void bgp_attr_add_llgr_community(struct attr *attr)
1888 {
1889 struct community *old;
1890 struct community *new;
1891 struct community *merge;
1892 struct community *llgr;
1893
1894 old = bgp_attr_get_community(attr);
1895 llgr = community_str2com("llgr-stale");
1896
1897 assert(llgr);
1898
1899 if (old) {
1900 merge = community_merge(community_dup(old), llgr);
1901
1902 if (old->refcnt == 0)
1903 community_free(&old);
1904
1905 new = community_uniq_sort(merge);
1906 community_free(&merge);
1907 } else {
1908 new = community_dup(llgr);
1909 }
1910
1911 community_free(&llgr);
1912
1913 bgp_attr_set_community(attr, new);
1914 }
1915
1916 void bgp_attr_add_gshut_community(struct attr *attr)
1917 {
1918 struct community *old;
1919 struct community *new;
1920 struct community *merge;
1921 struct community *gshut;
1922
1923 old = bgp_attr_get_community(attr);
1924 gshut = community_str2com("graceful-shutdown");
1925
1926 assert(gshut);
1927
1928 if (old) {
1929 merge = community_merge(community_dup(old), gshut);
1930
1931 if (old->refcnt == 0)
1932 community_free(&old);
1933
1934 new = community_uniq_sort(merge);
1935 community_free(&merge);
1936 } else {
1937 new = community_dup(gshut);
1938 }
1939
1940 community_free(&gshut);
1941 bgp_attr_set_community(attr, new);
1942
1943 /* When we add the graceful-shutdown community we must also
1944 * lower the local-preference */
1945 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1946 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1947 }
1948
1949
1950 /* Notify BGP Conditional advertisement scanner process. */
1951 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1952 {
1953 struct peer *peer = SUBGRP_PEER(subgrp);
1954 afi_t afi = SUBGRP_AFI(subgrp);
1955 safi_t safi = SUBGRP_SAFI(subgrp);
1956 struct bgp_filter *filter = &peer->filter[afi][safi];
1957
1958 if (!ADVERTISE_MAP_NAME(filter))
1959 return;
1960
1961 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1962 return;
1963
1964 peer->advmap_table_change = true;
1965 }
1966
1967
1968 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1969 {
1970 if (family == AF_INET) {
1971 attr->nexthop.s_addr = INADDR_ANY;
1972 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1973 }
1974 if (family == AF_INET6)
1975 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1976 if (family == AF_EVPN)
1977 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1978 }
1979
1980 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1981 struct update_subgroup *subgrp,
1982 const struct prefix *p, struct attr *attr,
1983 struct attr *post_attr)
1984 {
1985 struct bgp_filter *filter;
1986 struct peer *from;
1987 struct peer *peer;
1988 struct peer *onlypeer;
1989 struct bgp *bgp;
1990 struct attr *piattr;
1991 route_map_result_t ret;
1992 int transparent;
1993 int reflect;
1994 afi_t afi;
1995 safi_t safi;
1996 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1997 bool nh_reset = false;
1998 uint64_t cum_bw;
1999
2000 if (DISABLE_BGP_ANNOUNCE)
2001 return false;
2002
2003 afi = SUBGRP_AFI(subgrp);
2004 safi = SUBGRP_SAFI(subgrp);
2005 peer = SUBGRP_PEER(subgrp);
2006 onlypeer = NULL;
2007 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2008 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2009
2010 from = pi->peer;
2011 filter = &peer->filter[afi][safi];
2012 bgp = SUBGRP_INST(subgrp);
2013 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2014 : pi->attr;
2015
2016 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2017 peer->pmax_out[afi][safi] != 0 &&
2018 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2019 if (BGP_DEBUG(update, UPDATE_OUT) ||
2020 BGP_DEBUG(update, UPDATE_PREFIX)) {
2021 zlog_debug("%s reached maximum prefix to be send (%u)",
2022 peer->host, peer->pmax_out[afi][safi]);
2023 }
2024 return false;
2025 }
2026
2027 #ifdef ENABLE_BGP_VNC
2028 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2029 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2030 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2031
2032 /*
2033 * direct and direct_ext type routes originate internally even
2034 * though they can have peer pointers that reference other
2035 * systems
2036 */
2037 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2038 __func__, p);
2039 samepeer_safe = 1;
2040 }
2041 #endif
2042
2043 if (((afi == AFI_IP) || (afi == AFI_IP6))
2044 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2045 && (pi->type == ZEBRA_ROUTE_BGP)
2046 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2047
2048 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2049
2050 samepeer_safe = 1;
2051 }
2052
2053 /* With addpath we may be asked to TX all kinds of paths so make sure
2054 * pi is valid */
2055 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2056 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2057 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2058 return false;
2059 }
2060
2061 /* If this is not the bestpath then check to see if there is an enabled
2062 * addpath
2063 * feature that requires us to advertise it */
2064 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2065 if (!bgp_addpath_capable(pi, peer, afi, safi))
2066 return false;
2067
2068 /* Aggregate-address suppress check. */
2069 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2070 return false;
2071
2072 /*
2073 * If we are doing VRF 2 VRF leaking via the import
2074 * statement, we want to prevent the route going
2075 * off box as that the RT and RD created are localy
2076 * significant and globaly useless.
2077 */
2078 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2079 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2080 return false;
2081
2082 /* If it's labeled safi, make sure the route has a valid label. */
2083 if (safi == SAFI_LABELED_UNICAST) {
2084 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2085 if (!bgp_is_valid_label(&label)) {
2086 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2087 zlog_debug("u%" PRIu64 ":s%" PRIu64
2088 " %pFX is filtered - no label (%p)",
2089 subgrp->update_group->id, subgrp->id,
2090 p, &label);
2091 return false;
2092 }
2093 }
2094
2095 /* Do not send back route to sender. */
2096 if (onlypeer && from == onlypeer) {
2097 return false;
2098 }
2099
2100 /* Do not send the default route in the BGP table if the neighbor is
2101 * configured for default-originate */
2102 if (CHECK_FLAG(peer->af_flags[afi][safi],
2103 PEER_FLAG_DEFAULT_ORIGINATE)) {
2104 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2105 return false;
2106 else if (p->family == AF_INET6 && p->prefixlen == 0)
2107 return false;
2108 }
2109
2110 /* Transparency check. */
2111 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2112 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2113 transparent = 1;
2114 else
2115 transparent = 0;
2116
2117 /* If community is not disabled check the no-export and local. */
2118 if (!transparent && bgp_community_filter(peer, piattr)) {
2119 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2120 zlog_debug("%s: community filter check fail for %pFX",
2121 __func__, p);
2122 return false;
2123 }
2124
2125 /* If the attribute has originator-id and it is same as remote
2126 peer's id. */
2127 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2128 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2129 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2130 zlog_debug(
2131 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2132 onlypeer, p);
2133 return false;
2134 }
2135
2136 /* ORF prefix-list filter check */
2137 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2138 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2139 || CHECK_FLAG(peer->af_cap[afi][safi],
2140 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2141 if (peer->orf_plist[afi][safi]) {
2142 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2143 == PREFIX_DENY) {
2144 if (bgp_debug_update(NULL, p,
2145 subgrp->update_group, 0))
2146 zlog_debug(
2147 "%pBP [Update:SEND] %pFX is filtered via ORF",
2148 peer, p);
2149 return false;
2150 }
2151 }
2152
2153 /* Output filter check. */
2154 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2155 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2156 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2157 p);
2158 return false;
2159 }
2160
2161 /* AS path loop check. */
2162 if (peer->as_path_loop_detection &&
2163 aspath_loop_check(piattr->aspath, peer->as)) {
2164 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2165 zlog_debug(
2166 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2167 peer, peer->as);
2168 return false;
2169 }
2170
2171 /* If we're a CONFED we need to loop check the CONFED ID too */
2172 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2173 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2174 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2175 zlog_debug(
2176 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2177 peer, bgp->confed_id);
2178 return false;
2179 }
2180 }
2181
2182 /* Route-Reflect check. */
2183 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2184 reflect = 1;
2185 else
2186 reflect = 0;
2187
2188 /* IBGP reflection check. */
2189 if (reflect && !samepeer_safe) {
2190 /* A route from a Client peer. */
2191 if (CHECK_FLAG(from->af_flags[afi][safi],
2192 PEER_FLAG_REFLECTOR_CLIENT)) {
2193 /* Reflect to all the Non-Client peers and also to the
2194 Client peers other than the originator. Originator
2195 check
2196 is already done. So there is noting to do. */
2197 /* no bgp client-to-client reflection check. */
2198 if (CHECK_FLAG(bgp->flags,
2199 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2200 if (CHECK_FLAG(peer->af_flags[afi][safi],
2201 PEER_FLAG_REFLECTOR_CLIENT))
2202 return false;
2203 } else {
2204 /* A route from a Non-client peer. Reflect to all other
2205 clients. */
2206 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2207 PEER_FLAG_REFLECTOR_CLIENT))
2208 return false;
2209 }
2210 }
2211
2212 /* For modify attribute, copy it to temporary structure.
2213 * post_attr comes from BGP conditional advertisements, where
2214 * attributes are already processed by advertise-map route-map,
2215 * and this needs to be saved instead of overwriting from the
2216 * path attributes.
2217 */
2218 if (post_attr)
2219 *attr = *post_attr;
2220 else
2221 *attr = *piattr;
2222
2223 /* If local-preference is not set. */
2224 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2225 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2226 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2227 attr->local_pref = bgp->default_local_pref;
2228 }
2229
2230 /* If originator-id is not set and the route is to be reflected,
2231 set the originator id */
2232 if (reflect
2233 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2234 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2235 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2236 }
2237
2238 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2239 */
2240 if (peer->sort == BGP_PEER_EBGP
2241 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2242 if (from != bgp->peer_self && !transparent
2243 && !CHECK_FLAG(peer->af_flags[afi][safi],
2244 PEER_FLAG_MED_UNCHANGED))
2245 attr->flag &=
2246 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2247 }
2248
2249 /* Since the nexthop attribute can vary per peer, it is not explicitly
2250 * set
2251 * in announce check, only certain flags and length (or number of
2252 * nexthops
2253 * -- for IPv6/MP_REACH) are set here in order to guide the update
2254 * formation
2255 * code in setting the nexthop(s) on a per peer basis in
2256 * reformat_peer().
2257 * Typically, the source nexthop in the attribute is preserved but in
2258 * the
2259 * scenarios where we know it will always be overwritten, we reset the
2260 * nexthop to "0" in an attempt to achieve better Update packing. An
2261 * example of this is when a prefix from each of 2 IBGP peers needs to
2262 * be
2263 * announced to an EBGP peer (and they have the same attributes barring
2264 * their nexthop).
2265 */
2266 if (reflect)
2267 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2268
2269 #define NEXTHOP_IS_V6 \
2270 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2271 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2272 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2273 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2274
2275 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2276 * if
2277 * the peer (group) is configured to receive link-local nexthop
2278 * unchanged
2279 * and it is available in the prefix OR we're not reflecting the route,
2280 * link-local nexthop address is valid and
2281 * the peer (group) to whom we're going to announce is on a shared
2282 * network
2283 * and this is either a self-originated route or the peer is EBGP.
2284 * By checking if nexthop LL address is valid we are sure that
2285 * we do not announce LL address as `::`.
2286 */
2287 if (NEXTHOP_IS_V6) {
2288 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2289 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2290 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2291 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2292 || (!reflect && !transparent
2293 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2294 && peer->shared_network
2295 && (from == bgp->peer_self
2296 || peer->sort == BGP_PEER_EBGP))) {
2297 if (safi == SAFI_MPLS_VPN)
2298 attr->mp_nexthop_len =
2299 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2300 else
2301 attr->mp_nexthop_len =
2302 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2303 }
2304
2305 /* Clear off link-local nexthop in source, whenever it is not
2306 * needed to
2307 * ensure more prefixes share the same attribute for
2308 * announcement.
2309 */
2310 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2311 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2312 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2313 }
2314
2315 if (bgp_check_role_applicability(afi, safi) &&
2316 bgp_otc_egress(peer, attr))
2317 return false;
2318
2319 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2320 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2321
2322 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2323 filter->advmap.aname &&
2324 route_map_lookup_by_name(filter->advmap.aname)) {
2325 struct bgp_path_info rmap_path = {0};
2326 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2327 struct attr dummy_attr = *attr;
2328
2329 /* Fill temp path_info */
2330 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2331 pi, peer, &dummy_attr);
2332
2333 struct route_map *amap =
2334 route_map_lookup_by_name(filter->advmap.aname);
2335
2336 ret = route_map_apply(amap, p, &rmap_path);
2337
2338 bgp_attr_flush(&dummy_attr);
2339
2340 /*
2341 * The conditional advertisement mode is Withdraw and this
2342 * prefix is a conditional prefix. Don't advertise it
2343 */
2344 if (ret == RMAP_PERMITMATCH)
2345 return false;
2346 }
2347
2348 /* Route map & unsuppress-map apply. */
2349 if (!post_attr &&
2350 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2351 struct bgp_path_info rmap_path = {0};
2352 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2353 struct attr dummy_attr = {0};
2354
2355 /* Fill temp path_info */
2356 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2357 pi, peer, attr);
2358
2359 /* don't confuse inbound and outbound setting */
2360 RESET_FLAG(attr->rmap_change_flags);
2361
2362 /*
2363 * The route reflector is not allowed to modify the attributes
2364 * of the reflected IBGP routes unless explicitly allowed.
2365 */
2366 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2367 && !CHECK_FLAG(bgp->flags,
2368 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2369 dummy_attr = *attr;
2370 rmap_path.attr = &dummy_attr;
2371 }
2372
2373 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2374
2375 if (bgp_path_suppressed(pi))
2376 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2377 &rmap_path);
2378 else
2379 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2380 &rmap_path);
2381
2382 bgp_attr_flush(&dummy_attr);
2383 peer->rmap_type = 0;
2384
2385 if (ret == RMAP_DENYMATCH) {
2386 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2387 zlog_debug(
2388 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2389 peer, p,
2390 bgp_path_suppressed(pi)
2391 ? UNSUPPRESS_MAP_NAME(filter)
2392 : ROUTE_MAP_OUT_NAME(filter));
2393 bgp_attr_flush(rmap_path.attr);
2394 return false;
2395 }
2396 }
2397
2398 /* RFC 8212 to prevent route leaks.
2399 * This specification intends to improve this situation by requiring the
2400 * explicit configuration of both BGP Import and Export Policies for any
2401 * External BGP (EBGP) session such as customers, peers, or
2402 * confederation boundaries for all enabled address families. Through
2403 * codification of the aforementioned requirement, operators will
2404 * benefit from consistent behavior across different BGP
2405 * implementations.
2406 */
2407 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2408 if (!bgp_outbound_policy_exists(peer, filter)) {
2409 if (monotime_since(&bgp->ebgprequirespolicywarning,
2410 NULL) > FIFTEENMINUTE2USEC ||
2411 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2412 zlog_warn(
2413 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2414 monotime(&bgp->ebgprequirespolicywarning);
2415 }
2416 return false;
2417 }
2418
2419 /* draft-ietf-idr-deprecate-as-set-confed-set
2420 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2421 * Eventually, This document (if approved) updates RFC 4271
2422 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2423 * and obsoletes RFC 6472.
2424 */
2425 if (peer->bgp->reject_as_sets)
2426 if (aspath_check_as_sets(attr->aspath))
2427 return false;
2428
2429 /* If neighbor soo is configured, then check if the route has
2430 * SoO extended community and validate against the configured
2431 * one. If they match, do not announce, to prevent routing
2432 * loops.
2433 */
2434 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2435 peer->soo[afi][safi]) {
2436 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2437 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2438
2439 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2440 ECOMMUNITY_SITE_ORIGIN) ||
2441 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2442 ECOMMUNITY_SITE_ORIGIN) ||
2443 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2444 ECOMMUNITY_SITE_ORIGIN)) &&
2445 ecommunity_include(ecomm, ecomm_soo)) {
2446 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2447 zlog_debug(
2448 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2449 peer, p, ecommunity_str(ecomm_soo));
2450 return false;
2451 }
2452 }
2453
2454 /* Codification of AS 0 Processing */
2455 if (aspath_check_as_zero(attr->aspath))
2456 return false;
2457
2458 if (bgp_in_graceful_shutdown(bgp)) {
2459 if (peer->sort == BGP_PEER_IBGP
2460 || peer->sort == BGP_PEER_CONFED) {
2461 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2462 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2463 } else {
2464 bgp_attr_add_gshut_community(attr);
2465 }
2466 }
2467
2468 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2469 * Capability" to a neighbor MUST perform the following upon receiving
2470 * a route from that neighbor with the "LLGR_STALE" community, or upon
2471 * attaching the "LLGR_STALE" community itself per Section 4.2:
2472 *
2473 * The route SHOULD NOT be advertised to any neighbor from which the
2474 * Long-lived Graceful Restart Capability has not been received.
2475 */
2476 if (bgp_attr_get_community(attr) &&
2477 community_include(bgp_attr_get_community(attr),
2478 COMMUNITY_LLGR_STALE) &&
2479 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2480 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2481 return false;
2482
2483 /* After route-map has been applied, we check to see if the nexthop to
2484 * be carried in the attribute (that is used for the announcement) can
2485 * be cleared off or not. We do this in all cases where we would be
2486 * setting the nexthop to "ourselves". For IPv6, we only need to
2487 * consider
2488 * the global nexthop here; the link-local nexthop would have been
2489 * cleared
2490 * already, and if not, it is required by the update formation code.
2491 * Also see earlier comments in this function.
2492 */
2493 /*
2494 * If route-map has performed some operation on the nexthop or the peer
2495 * configuration says to pass it unchanged, we cannot reset the nexthop
2496 * here, so only attempt to do it if these aren't true. Note that the
2497 * route-map handler itself might have cleared the nexthop, if for
2498 * example,
2499 * it is configured as 'peer-address'.
2500 */
2501 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2502 piattr->rmap_change_flags)
2503 && !transparent
2504 && !CHECK_FLAG(peer->af_flags[afi][safi],
2505 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2506 /* We can reset the nexthop, if setting (or forcing) it to
2507 * 'self' */
2508 if (CHECK_FLAG(peer->af_flags[afi][safi],
2509 PEER_FLAG_NEXTHOP_SELF)
2510 || CHECK_FLAG(peer->af_flags[afi][safi],
2511 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2512 if (!reflect
2513 || CHECK_FLAG(peer->af_flags[afi][safi],
2514 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2515 subgroup_announce_reset_nhop(
2516 (peer_cap_enhe(peer, afi, safi)
2517 ? AF_INET6
2518 : p->family),
2519 attr);
2520 nh_reset = true;
2521 }
2522 } else if (peer->sort == BGP_PEER_EBGP) {
2523 /* Can also reset the nexthop if announcing to EBGP, but
2524 * only if
2525 * no peer in the subgroup is on a shared subnet.
2526 * Note: 3rd party nexthop currently implemented for
2527 * IPv4 only.
2528 */
2529 if ((p->family == AF_INET) &&
2530 (!bgp_subgrp_multiaccess_check_v4(
2531 piattr->nexthop,
2532 subgrp, from))) {
2533 subgroup_announce_reset_nhop(
2534 (peer_cap_enhe(peer, afi, safi)
2535 ? AF_INET6
2536 : p->family),
2537 attr);
2538 nh_reset = true;
2539 }
2540
2541 if ((p->family == AF_INET6) &&
2542 (!bgp_subgrp_multiaccess_check_v6(
2543 piattr->mp_nexthop_global,
2544 subgrp, from))) {
2545 subgroup_announce_reset_nhop(
2546 (peer_cap_enhe(peer, afi, safi)
2547 ? AF_INET6
2548 : p->family),
2549 attr);
2550 nh_reset = true;
2551 }
2552
2553
2554
2555 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2556 /*
2557 * This flag is used for leaked vpn-vrf routes
2558 */
2559 int family = p->family;
2560
2561 if (peer_cap_enhe(peer, afi, safi))
2562 family = AF_INET6;
2563
2564 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2565 zlog_debug(
2566 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2567 __func__, p, family2str(family));
2568 subgroup_announce_reset_nhop(family, attr);
2569 nh_reset = true;
2570 }
2571 }
2572
2573 /* If IPv6/MP and nexthop does not have any override and happens
2574 * to
2575 * be a link-local address, reset it so that we don't pass along
2576 * the
2577 * source's link-local IPv6 address to recipients who may not be
2578 * on
2579 * the same interface.
2580 */
2581 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2582 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2583 subgroup_announce_reset_nhop(AF_INET6, attr);
2584 nh_reset = true;
2585 }
2586 }
2587
2588 /* If this is an iBGP, send Origin Validation State (OVS)
2589 * extended community (rfc8097).
2590 */
2591 if (peer->sort == BGP_PEER_IBGP) {
2592 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2593
2594 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2595
2596 if (rpki_state != RPKI_NOT_BEING_USED)
2597 bgp_attr_set_ecommunity(
2598 attr, ecommunity_add_origin_validation_state(
2599 rpki_state,
2600 bgp_attr_get_ecommunity(attr)));
2601 }
2602
2603 /*
2604 * When the next hop is set to ourselves, if all multipaths have
2605 * link-bandwidth announce the cumulative bandwidth as that makes
2606 * the most sense. However, don't modify if the link-bandwidth has
2607 * been explicitly set by user policy.
2608 */
2609 if (nh_reset &&
2610 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2611 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2612 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2613 bgp_attr_set_ecommunity(
2614 attr,
2615 ecommunity_replace_linkbw(
2616 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2617 CHECK_FLAG(
2618 peer->flags,
2619 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2620
2621 return true;
2622 }
2623
2624 static void bgp_route_select_timer_expire(struct event *thread)
2625 {
2626 struct afi_safi_info *info;
2627 afi_t afi;
2628 safi_t safi;
2629 struct bgp *bgp;
2630
2631 info = EVENT_ARG(thread);
2632 afi = info->afi;
2633 safi = info->safi;
2634 bgp = info->bgp;
2635
2636 bgp->gr_info[afi][safi].t_route_select = NULL;
2637 XFREE(MTYPE_TMP, info);
2638
2639 /* Best path selection */
2640 bgp_best_path_select_defer(bgp, afi, safi);
2641 }
2642
2643 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2644 struct bgp_maxpaths_cfg *mpath_cfg,
2645 struct bgp_path_info_pair *result, afi_t afi,
2646 safi_t safi)
2647 {
2648 struct bgp_path_info *new_select;
2649 struct bgp_path_info *old_select;
2650 struct bgp_path_info *pi;
2651 struct bgp_path_info *pi1;
2652 struct bgp_path_info *pi2;
2653 struct bgp_path_info *nextpi = NULL;
2654 int paths_eq, do_mpath, debug;
2655 struct list mp_list;
2656 char pfx_buf[PREFIX2STR_BUFFER];
2657 char path_buf[PATH_ADDPATH_STR_BUFFER];
2658
2659 bgp_mp_list_init(&mp_list);
2660 do_mpath =
2661 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2662
2663 debug = bgp_debug_bestpath(dest);
2664
2665 if (debug)
2666 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2667
2668 dest->reason = bgp_path_selection_none;
2669 /* bgp deterministic-med */
2670 new_select = NULL;
2671 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2672
2673 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2674 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2675 pi1 = pi1->next)
2676 bgp_path_info_unset_flag(dest, pi1,
2677 BGP_PATH_DMED_SELECTED);
2678
2679 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2680 pi1 = pi1->next) {
2681 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2682 continue;
2683 if (BGP_PATH_HOLDDOWN(pi1))
2684 continue;
2685 if (pi1->peer != bgp->peer_self &&
2686 !CHECK_FLAG(pi1->peer->sflags,
2687 PEER_STATUS_NSF_WAIT)) {
2688 if (!peer_established(pi1->peer))
2689 continue;
2690 }
2691
2692 new_select = pi1;
2693 if (pi1->next) {
2694 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2695 if (CHECK_FLAG(pi2->flags,
2696 BGP_PATH_DMED_CHECK))
2697 continue;
2698 if (BGP_PATH_HOLDDOWN(pi2))
2699 continue;
2700 if (pi2->peer != bgp->peer_self
2701 && !CHECK_FLAG(
2702 pi2->peer->sflags,
2703 PEER_STATUS_NSF_WAIT))
2704 if (pi2->peer->status
2705 != Established)
2706 continue;
2707
2708 if (!aspath_cmp_left(pi1->attr->aspath,
2709 pi2->attr->aspath)
2710 && !aspath_cmp_left_confed(
2711 pi1->attr->aspath,
2712 pi2->attr->aspath))
2713 continue;
2714
2715 if (bgp_path_info_cmp(
2716 bgp, pi2, new_select,
2717 &paths_eq, mpath_cfg, debug,
2718 pfx_buf, afi, safi,
2719 &dest->reason)) {
2720 bgp_path_info_unset_flag(
2721 dest, new_select,
2722 BGP_PATH_DMED_SELECTED);
2723 new_select = pi2;
2724 }
2725
2726 bgp_path_info_set_flag(
2727 dest, pi2, BGP_PATH_DMED_CHECK);
2728 }
2729 }
2730 bgp_path_info_set_flag(dest, new_select,
2731 BGP_PATH_DMED_CHECK);
2732 bgp_path_info_set_flag(dest, new_select,
2733 BGP_PATH_DMED_SELECTED);
2734
2735 if (debug) {
2736 bgp_path_info_path_with_addpath_rx_str(
2737 new_select, path_buf, sizeof(path_buf));
2738 zlog_debug(
2739 "%pBD(%s): %s is the bestpath from AS %u",
2740 dest, bgp->name_pretty, path_buf,
2741 aspath_get_first_as(
2742 new_select->attr->aspath));
2743 }
2744 }
2745 }
2746
2747 /* Check old selected route and new selected route. */
2748 old_select = NULL;
2749 new_select = NULL;
2750 for (pi = bgp_dest_get_bgp_path_info(dest);
2751 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2752 enum bgp_path_selection_reason reason;
2753
2754 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2755 old_select = pi;
2756
2757 if (BGP_PATH_HOLDDOWN(pi)) {
2758 /* reap REMOVED routes, if needs be
2759 * selected route must stay for a while longer though
2760 */
2761 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2762 && (pi != old_select))
2763 bgp_path_info_reap(dest, pi);
2764
2765 if (debug)
2766 zlog_debug(
2767 "%s: %pBD(%s) pi from %s in holddown",
2768 __func__, dest, bgp->name_pretty,
2769 pi->peer->host);
2770
2771 continue;
2772 }
2773
2774 if (pi->peer && pi->peer != bgp->peer_self
2775 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2776 if (!peer_established(pi->peer)) {
2777
2778 if (debug)
2779 zlog_debug(
2780 "%s: %pBD(%s) non self peer %s not estab state",
2781 __func__, dest,
2782 bgp->name_pretty,
2783 pi->peer->host);
2784
2785 continue;
2786 }
2787
2788 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2789 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2790 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2791 if (debug)
2792 zlog_debug("%s: %pBD(%s) pi %s dmed", __func__,
2793 dest, bgp->name_pretty,
2794 pi->peer->host);
2795 continue;
2796 }
2797
2798 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2799
2800 reason = dest->reason;
2801 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2802 debug, pfx_buf, afi, safi,
2803 &dest->reason)) {
2804 if (new_select == NULL &&
2805 reason != bgp_path_selection_none)
2806 dest->reason = reason;
2807 new_select = pi;
2808 }
2809 }
2810
2811 /* Now that we know which path is the bestpath see if any of the other
2812 * paths
2813 * qualify as multipaths
2814 */
2815 if (debug) {
2816 if (new_select)
2817 bgp_path_info_path_with_addpath_rx_str(
2818 new_select, path_buf, sizeof(path_buf));
2819 else
2820 snprintf(path_buf, sizeof(path_buf), "NONE");
2821 zlog_debug(
2822 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2823 dest, bgp->name_pretty, path_buf,
2824 old_select ? old_select->peer->host : "NONE");
2825 }
2826
2827 if (do_mpath && new_select) {
2828 for (pi = bgp_dest_get_bgp_path_info(dest);
2829 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2830
2831 if (debug)
2832 bgp_path_info_path_with_addpath_rx_str(
2833 pi, path_buf, sizeof(path_buf));
2834
2835 if (pi == new_select) {
2836 if (debug)
2837 zlog_debug(
2838 "%pBD(%s): %s is the bestpath, add to the multipath list",
2839 dest, bgp->name_pretty,
2840 path_buf);
2841 bgp_mp_list_add(&mp_list, pi);
2842 continue;
2843 }
2844
2845 if (BGP_PATH_HOLDDOWN(pi))
2846 continue;
2847
2848 if (pi->peer && pi->peer != bgp->peer_self
2849 && !CHECK_FLAG(pi->peer->sflags,
2850 PEER_STATUS_NSF_WAIT))
2851 if (!peer_established(pi->peer))
2852 continue;
2853
2854 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2855 if (debug)
2856 zlog_debug(
2857 "%pBD(%s): %s has the same nexthop as the bestpath, skip it",
2858 dest, bgp->name_pretty,
2859 path_buf);
2860 continue;
2861 }
2862
2863 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2864 mpath_cfg, debug, pfx_buf, afi, safi,
2865 &dest->reason);
2866
2867 if (paths_eq) {
2868 if (debug)
2869 zlog_debug(
2870 "%pBD(%s): %s is equivalent to the bestpath, add to the multipath list",
2871 dest, bgp->name_pretty,
2872 path_buf);
2873 bgp_mp_list_add(&mp_list, pi);
2874 }
2875 }
2876 }
2877
2878 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2879 mpath_cfg);
2880 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2881 bgp_mp_list_clear(&mp_list);
2882
2883 bgp_addpath_update_ids(bgp, dest, afi, safi);
2884
2885 result->old = old_select;
2886 result->new = new_select;
2887
2888 return;
2889 }
2890
2891 /*
2892 * A new route/change in bestpath of an existing route. Evaluate the path
2893 * for advertisement to the subgroup.
2894 */
2895 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2896 struct bgp_path_info *selected,
2897 struct bgp_dest *dest,
2898 uint32_t addpath_tx_id)
2899 {
2900 const struct prefix *p;
2901 struct peer *onlypeer;
2902 struct attr attr;
2903 afi_t afi;
2904 safi_t safi;
2905 struct bgp *bgp;
2906 bool advertise;
2907
2908 p = bgp_dest_get_prefix(dest);
2909 afi = SUBGRP_AFI(subgrp);
2910 safi = SUBGRP_SAFI(subgrp);
2911 bgp = SUBGRP_INST(subgrp);
2912 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2913 : NULL);
2914
2915 if (BGP_DEBUG(update, UPDATE_OUT))
2916 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2917
2918 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2919 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2920 PEER_STATUS_ORF_WAIT_REFRESH))
2921 return;
2922
2923 memset(&attr, 0, sizeof(attr));
2924 /* It's initialized in bgp_announce_check() */
2925
2926 /* Announcement to the subgroup. If the route is filtered withdraw it.
2927 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2928 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2929 * route
2930 */
2931 advertise = bgp_check_advertise(bgp, dest);
2932
2933 if (selected) {
2934 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2935 NULL)) {
2936 /* Route is selected, if the route is already installed
2937 * in FIB, then it is advertised
2938 */
2939 if (advertise) {
2940 if (!bgp_check_withdrawal(bgp, dest)) {
2941 struct attr *adv_attr =
2942 bgp_attr_intern(&attr);
2943
2944 bgp_adj_out_set_subgroup(dest, subgrp,
2945 adv_attr,
2946 selected);
2947 } else
2948 bgp_adj_out_unset_subgroup(
2949 dest, subgrp, 1, addpath_tx_id);
2950 }
2951 } else
2952 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2953 addpath_tx_id);
2954 }
2955
2956 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2957 else {
2958 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2959 }
2960 }
2961
2962 /*
2963 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2964 * This is called at the end of route processing.
2965 */
2966 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2967 {
2968 struct bgp_path_info *pi;
2969
2970 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2971 if (BGP_PATH_HOLDDOWN(pi))
2972 continue;
2973 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2974 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2975 }
2976 }
2977
2978 /*
2979 * Has the route changed from the RIB's perspective? This is invoked only
2980 * if the route selection returns the same best route as earlier - to
2981 * determine if we need to update zebra or not.
2982 */
2983 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2984 {
2985 struct bgp_path_info *mpinfo;
2986
2987 /* If this is multipath, check all selected paths for any nexthop
2988 * change or attribute change. Some attribute changes (e.g., community)
2989 * aren't of relevance to the RIB, but we'll update zebra to ensure
2990 * we handle the case of BGP nexthop change. This is the behavior
2991 * when the best path has an attribute change anyway.
2992 */
2993 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2994 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2995 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2996 return true;
2997
2998 /*
2999 * If this is multipath, check all selected paths for any nexthop change
3000 */
3001 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
3002 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3003 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3004 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3005 return true;
3006 }
3007
3008 /* Nothing has changed from the RIB's perspective. */
3009 return false;
3010 }
3011
3012 struct bgp_process_queue {
3013 struct bgp *bgp;
3014 STAILQ_HEAD(, bgp_dest) pqueue;
3015 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3016 unsigned int flags;
3017 unsigned int queued;
3018 };
3019
3020 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3021 safi_t safi, struct bgp_dest *dest,
3022 struct bgp_path_info *new_select,
3023 struct bgp_path_info *old_select)
3024 {
3025 const struct prefix *p = bgp_dest_get_prefix(dest);
3026
3027 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3028 return;
3029
3030 if (advertise_type5_routes(bgp, afi) && new_select
3031 && is_route_injectable_into_evpn(new_select)) {
3032
3033 /* apply the route-map */
3034 if (bgp->adv_cmd_rmap[afi][safi].map) {
3035 route_map_result_t ret;
3036 struct bgp_path_info rmap_path;
3037 struct bgp_path_info_extra rmap_path_extra;
3038 struct attr dummy_attr;
3039
3040 dummy_attr = *new_select->attr;
3041
3042 /* Fill temp path_info */
3043 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3044 new_select, new_select->peer,
3045 &dummy_attr);
3046
3047 RESET_FLAG(dummy_attr.rmap_change_flags);
3048
3049 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3050 p, &rmap_path);
3051
3052 if (ret == RMAP_DENYMATCH) {
3053 bgp_attr_flush(&dummy_attr);
3054 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3055 safi);
3056 } else
3057 bgp_evpn_advertise_type5_route(
3058 bgp, p, &dummy_attr, afi, safi);
3059 } else {
3060 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3061 afi, safi);
3062 }
3063 } else if (advertise_type5_routes(bgp, afi) && old_select
3064 && is_route_injectable_into_evpn(old_select))
3065 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3066 }
3067
3068 /*
3069 * Utility to determine whether a particular path_info should use
3070 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3071 * in a path where we basically _know_ this is a BGP-LU route.
3072 */
3073 static bool bgp_lu_need_null_label(struct bgp *bgp,
3074 const struct bgp_path_info *new_select,
3075 afi_t afi, mpls_label_t *label)
3076 {
3077 /* Certain types get imp null; so do paths where the nexthop is
3078 * not labeled.
3079 */
3080 if (new_select->sub_type == BGP_ROUTE_STATIC
3081 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3082 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3083 goto need_null_label;
3084 else if (new_select->extra &&
3085 bgp_is_valid_label(&new_select->extra->label[0]))
3086 return false;
3087 need_null_label:
3088 if (label == NULL)
3089 return true;
3090 /* Disable PHP : explicit-null */
3091 if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_IPV4_EXPLICIT_NULL) &&
3092 afi == AFI_IP)
3093 *label = MPLS_LABEL_IPV4_EXPLICIT_NULL;
3094 else if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_IPV6_EXPLICIT_NULL) &&
3095 afi == AFI_IP6)
3096 *label = MPLS_LABEL_IPV6_EXPLICIT_NULL;
3097 else
3098 /* Enforced PHP popping: implicit-null */
3099 *label = MPLS_LABEL_IMPLICIT_NULL;
3100
3101 return true;
3102 }
3103
3104 /*
3105 * old_select = The old best path
3106 * new_select = the new best path
3107 *
3108 * if (!old_select && new_select)
3109 * We are sending new information on.
3110 *
3111 * if (old_select && new_select) {
3112 * if (new_select != old_select)
3113 * We have a new best path send a change
3114 * else
3115 * We've received a update with new attributes that needs
3116 * to be passed on.
3117 * }
3118 *
3119 * if (old_select && !new_select)
3120 * We have no eligible route that we can announce or the rn
3121 * is being removed.
3122 */
3123 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3124 afi_t afi, safi_t safi)
3125 {
3126 struct bgp_path_info *new_select;
3127 struct bgp_path_info *old_select;
3128 struct bgp_path_info_pair old_and_new;
3129 int debug = 0;
3130 mpls_label_t mpls_label_null;
3131
3132 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3133 if (dest)
3134 debug = bgp_debug_bestpath(dest);
3135 if (debug)
3136 zlog_debug(
3137 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3138 __func__, dest, bgp->name_pretty);
3139 return;
3140 }
3141 /* Is it end of initial update? (after startup) */
3142 if (!dest) {
3143 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3144 sizeof(bgp->update_delay_zebra_resume_time));
3145
3146 bgp->main_zebra_update_hold = 0;
3147 FOREACH_AFI_SAFI (afi, safi) {
3148 if (bgp_fibupd_safi(safi))
3149 bgp_zebra_announce_table(bgp, afi, safi);
3150 }
3151 bgp->main_peers_update_hold = 0;
3152
3153 bgp_start_routeadv(bgp);
3154 return;
3155 }
3156
3157 const struct prefix *p = bgp_dest_get_prefix(dest);
3158
3159 debug = bgp_debug_bestpath(dest);
3160 if (debug)
3161 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3162 dest, bgp->name_pretty, afi2str(afi),
3163 safi2str(safi));
3164
3165 /* The best path calculation for the route is deferred if
3166 * BGP_NODE_SELECT_DEFER is set
3167 */
3168 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3169 if (BGP_DEBUG(update, UPDATE_OUT))
3170 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3171 dest, bgp->name_pretty);
3172 return;
3173 }
3174
3175 /* Best path selection. */
3176 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3177 afi, safi);
3178 old_select = old_and_new.old;
3179 new_select = old_and_new.new;
3180
3181 /* Do we need to allocate or free labels?
3182 * Right now, since we only deal with per-prefix labels, it is not
3183 * necessary to do this upon changes to best path. Exceptions:
3184 * - label index has changed -> recalculate resulting label
3185 * - path_info sub_type changed -> switch to/from null label value
3186 * - no valid label (due to removed static label binding) -> get new one
3187 */
3188 if (bgp->allocate_mpls_labels[afi][safi]) {
3189 if (new_select) {
3190 if (!old_select
3191 || bgp_label_index_differs(new_select, old_select)
3192 || new_select->sub_type != old_select->sub_type
3193 || !bgp_is_valid_label(&dest->local_label)) {
3194 /* control label imposition for local routes,
3195 * aggregate and redistributed routes
3196 */
3197 mpls_label_null = MPLS_LABEL_IMPLICIT_NULL;
3198 if (bgp_lu_need_null_label(bgp, new_select, afi,
3199 &mpls_label_null)) {
3200 if (CHECK_FLAG(
3201 dest->flags,
3202 BGP_NODE_REGISTERED_FOR_LABEL)
3203 || CHECK_FLAG(
3204 dest->flags,
3205 BGP_NODE_LABEL_REQUESTED))
3206 bgp_unregister_for_label(dest);
3207 dest->local_label = mpls_lse_encode(
3208 mpls_label_null, 0, 0, 1);
3209 bgp_set_valid_label(&dest->local_label);
3210 } else
3211 bgp_register_for_label(dest,
3212 new_select);
3213 }
3214 } else if (CHECK_FLAG(dest->flags,
3215 BGP_NODE_REGISTERED_FOR_LABEL)
3216 || CHECK_FLAG(dest->flags,
3217 BGP_NODE_LABEL_REQUESTED)) {
3218 bgp_unregister_for_label(dest);
3219 }
3220 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3221 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3222 bgp_unregister_for_label(dest);
3223 }
3224
3225 if (debug)
3226 zlog_debug(
3227 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3228 __func__, dest, bgp->name_pretty, afi2str(afi),
3229 safi2str(safi), old_select, new_select);
3230
3231 /* If best route remains the same and this is not due to user-initiated
3232 * clear, see exactly what needs to be done.
3233 */
3234 if (old_select && old_select == new_select
3235 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3236 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3237 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3238 if (bgp_zebra_has_route_changed(old_select)) {
3239 #ifdef ENABLE_BGP_VNC
3240 vnc_import_bgp_add_route(bgp, p, old_select);
3241 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3242 #endif
3243 if (bgp_fibupd_safi(safi)
3244 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3245
3246 if (new_select->type == ZEBRA_ROUTE_BGP
3247 && (new_select->sub_type == BGP_ROUTE_NORMAL
3248 || new_select->sub_type
3249 == BGP_ROUTE_IMPORTED))
3250
3251 bgp_zebra_announce(dest, p, old_select,
3252 bgp, afi, safi);
3253 }
3254 }
3255
3256 /* If there is a change of interest to peers, reannounce the
3257 * route. */
3258 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3259 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3260 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3261 group_announce_route(bgp, afi, safi, dest, new_select);
3262
3263 /* unicast routes must also be annouced to
3264 * labeled-unicast update-groups */
3265 if (safi == SAFI_UNICAST)
3266 group_announce_route(bgp, afi,
3267 SAFI_LABELED_UNICAST, dest,
3268 new_select);
3269
3270 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3271 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3272 }
3273
3274 /* advertise/withdraw type-5 routes */
3275 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3276 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3277 bgp_process_evpn_route_injection(
3278 bgp, afi, safi, dest, old_select, old_select);
3279
3280 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3281 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3282 bgp_zebra_clear_route_change_flags(dest);
3283 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3284 return;
3285 }
3286
3287 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3288 */
3289 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3290
3291 /* bestpath has changed; bump version */
3292 if (old_select || new_select) {
3293 bgp_bump_version(dest);
3294
3295 if (!bgp->t_rmap_def_originate_eval) {
3296 bgp_lock(bgp);
3297 event_add_timer(
3298 bm->master,
3299 update_group_refresh_default_originate_route_map,
3300 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3301 &bgp->t_rmap_def_originate_eval);
3302 }
3303 }
3304
3305 if (old_select)
3306 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3307 if (new_select) {
3308 if (debug)
3309 zlog_debug("%s: setting SELECTED flag", __func__);
3310 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3311 bgp_path_info_unset_flag(dest, new_select,
3312 BGP_PATH_ATTR_CHANGED);
3313 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3314 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3315 }
3316
3317 #ifdef ENABLE_BGP_VNC
3318 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3319 if (old_select != new_select) {
3320 if (old_select) {
3321 vnc_import_bgp_exterior_del_route(bgp, p,
3322 old_select);
3323 vnc_import_bgp_del_route(bgp, p, old_select);
3324 }
3325 if (new_select) {
3326 vnc_import_bgp_exterior_add_route(bgp, p,
3327 new_select);
3328 vnc_import_bgp_add_route(bgp, p, new_select);
3329 }
3330 }
3331 }
3332 #endif
3333
3334 group_announce_route(bgp, afi, safi, dest, new_select);
3335
3336 /* unicast routes must also be annouced to labeled-unicast update-groups
3337 */
3338 if (safi == SAFI_UNICAST)
3339 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3340 new_select);
3341
3342 /* FIB update. */
3343 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3344 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3345
3346 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3347 && (new_select->sub_type == BGP_ROUTE_NORMAL
3348 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3349 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3350
3351 /* if this is an evpn imported type-5 prefix,
3352 * we need to withdraw the route first to clear
3353 * the nh neigh and the RMAC entry.
3354 */
3355 if (old_select &&
3356 is_route_parent_evpn(old_select))
3357 bgp_zebra_withdraw(p, old_select, bgp, safi);
3358
3359 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3360 } else {
3361 /* Withdraw the route from the kernel. */
3362 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3363 && (old_select->sub_type == BGP_ROUTE_NORMAL
3364 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3365 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3366
3367 bgp_zebra_withdraw(p, old_select, bgp, safi);
3368 }
3369 }
3370
3371 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3372 old_select);
3373
3374 /* Clear any route change flags. */
3375 bgp_zebra_clear_route_change_flags(dest);
3376
3377 /* Reap old select bgp_path_info, if it has been removed */
3378 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3379 bgp_path_info_reap(dest, old_select);
3380
3381 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3382 return;
3383 }
3384
3385 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3386 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3387 {
3388 struct bgp_dest *dest;
3389 int cnt = 0;
3390 struct afi_safi_info *thread_info;
3391
3392 if (bgp->gr_info[afi][safi].t_route_select) {
3393 struct event *t = bgp->gr_info[afi][safi].t_route_select;
3394
3395 thread_info = EVENT_ARG(t);
3396 XFREE(MTYPE_TMP, thread_info);
3397 EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
3398 }
3399
3400 if (BGP_DEBUG(update, UPDATE_OUT)) {
3401 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3402 get_afi_safi_str(afi, safi, false),
3403 bgp->gr_info[afi][safi].gr_deferred);
3404 }
3405
3406 /* Process the route list */
3407 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3408 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3409 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3410 dest = bgp_route_next(dest)) {
3411 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3412 continue;
3413
3414 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3415 bgp->gr_info[afi][safi].gr_deferred--;
3416 bgp_process_main_one(bgp, dest, afi, safi);
3417 cnt++;
3418 }
3419 /* If iteration stopped before the entire table was traversed then the
3420 * node needs to be unlocked.
3421 */
3422 if (dest) {
3423 bgp_dest_unlock_node(dest);
3424 dest = NULL;
3425 }
3426
3427 /* Send EOR message when all routes are processed */
3428 if (!bgp->gr_info[afi][safi].gr_deferred) {
3429 bgp_send_delayed_eor(bgp);
3430 /* Send route processing complete message to RIB */
3431 bgp_zebra_update(bgp, afi, safi,
3432 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3433 return;
3434 }
3435
3436 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3437
3438 thread_info->afi = afi;
3439 thread_info->safi = safi;
3440 thread_info->bgp = bgp;
3441
3442 /* If there are more routes to be processed, start the
3443 * selection timer
3444 */
3445 event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3446 BGP_ROUTE_SELECT_DELAY,
3447 &bgp->gr_info[afi][safi].t_route_select);
3448 }
3449
3450 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3451 {
3452 struct bgp_process_queue *pqnode = data;
3453 struct bgp *bgp = pqnode->bgp;
3454 struct bgp_table *table;
3455 struct bgp_dest *dest;
3456
3457 /* eoiu marker */
3458 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3459 bgp_process_main_one(bgp, NULL, 0, 0);
3460 /* should always have dedicated wq call */
3461 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3462 return WQ_SUCCESS;
3463 }
3464
3465 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3466 dest = STAILQ_FIRST(&pqnode->pqueue);
3467 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3468 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3469 table = bgp_dest_table(dest);
3470 /* note, new DESTs may be added as part of processing */
3471 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3472
3473 bgp_dest_unlock_node(dest);
3474 bgp_table_unlock(table);
3475 }
3476
3477 return WQ_SUCCESS;
3478 }
3479
3480 static void bgp_processq_del(struct work_queue *wq, void *data)
3481 {
3482 struct bgp_process_queue *pqnode = data;
3483
3484 bgp_unlock(pqnode->bgp);
3485
3486 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3487 }
3488
3489 void bgp_process_queue_init(struct bgp *bgp)
3490 {
3491 if (!bgp->process_queue) {
3492 char name[BUFSIZ];
3493
3494 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3495 bgp->process_queue = work_queue_new(bm->master, name);
3496 }
3497
3498 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3499 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3500 bgp->process_queue->spec.max_retries = 0;
3501 bgp->process_queue->spec.hold = 50;
3502 /* Use a higher yield value of 50ms for main queue processing */
3503 bgp->process_queue->spec.yield = 50 * 1000L;
3504 }
3505
3506 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3507 {
3508 struct bgp_process_queue *pqnode;
3509
3510 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3511 sizeof(struct bgp_process_queue));
3512
3513 /* unlocked in bgp_processq_del */
3514 pqnode->bgp = bgp_lock(bgp);
3515 STAILQ_INIT(&pqnode->pqueue);
3516
3517 return pqnode;
3518 }
3519
3520 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3521 {
3522 #define ARBITRARY_PROCESS_QLEN 10000
3523 struct work_queue *wq = bgp->process_queue;
3524 struct bgp_process_queue *pqnode;
3525 int pqnode_reuse = 0;
3526
3527 /* already scheduled for processing? */
3528 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3529 return;
3530
3531 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3532 * the workqueue
3533 */
3534 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3535 if (BGP_DEBUG(update, UPDATE_OUT))
3536 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3537 dest);
3538 return;
3539 }
3540
3541 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3542 if (BGP_DEBUG(update, UPDATE_OUT))
3543 zlog_debug(
3544 "Soft reconfigure table in progress for route %p",
3545 dest);
3546 return;
3547 }
3548
3549 if (wq == NULL)
3550 return;
3551
3552 /* Add route nodes to an existing work queue item until reaching the
3553 limit only if is from the same BGP view and it's not an EOIU marker
3554 */
3555 if (work_queue_item_count(wq)) {
3556 struct work_queue_item *item = work_queue_last_item(wq);
3557 pqnode = item->data;
3558
3559 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3560 || pqnode->bgp != bgp
3561 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3562 pqnode = bgp_processq_alloc(bgp);
3563 else
3564 pqnode_reuse = 1;
3565 } else
3566 pqnode = bgp_processq_alloc(bgp);
3567 /* all unlocked in bgp_process_wq */
3568 bgp_table_lock(bgp_dest_table(dest));
3569
3570 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3571 bgp_dest_lock_node(dest);
3572
3573 /* can't be enqueued twice */
3574 assert(STAILQ_NEXT(dest, pq) == NULL);
3575 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3576 pqnode->queued++;
3577
3578 if (!pqnode_reuse)
3579 work_queue_add(wq, pqnode);
3580
3581 return;
3582 }
3583
3584 void bgp_add_eoiu_mark(struct bgp *bgp)
3585 {
3586 struct bgp_process_queue *pqnode;
3587
3588 if (bgp->process_queue == NULL)
3589 return;
3590
3591 pqnode = bgp_processq_alloc(bgp);
3592
3593 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3594 work_queue_add(bgp->process_queue, pqnode);
3595 }
3596
3597 static void bgp_maximum_prefix_restart_timer(struct event *thread)
3598 {
3599 struct peer *peer;
3600
3601 peer = EVENT_ARG(thread);
3602 peer->t_pmax_restart = NULL;
3603
3604 if (bgp_debug_neighbor_events(peer))
3605 zlog_debug(
3606 "%s Maximum-prefix restart timer expired, restore peering",
3607 peer->host);
3608
3609 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3610 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3611 }
3612
3613 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3614 safi_t safi)
3615 {
3616 uint32_t count = 0;
3617 bool filtered = false;
3618 struct bgp_dest *dest;
3619 struct bgp_adj_in *ain;
3620 struct attr attr = {};
3621 struct bgp_table *table = peer->bgp->rib[afi][safi];
3622
3623 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3624 for (ain = dest->adj_in; ain; ain = ain->next) {
3625 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3626
3627 attr = *ain->attr;
3628
3629 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3630 == FILTER_DENY)
3631 filtered = true;
3632
3633 if (bgp_input_modifier(
3634 peer, rn_p, &attr, afi, safi,
3635 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3636 NULL, 0, NULL)
3637 == RMAP_DENY)
3638 filtered = true;
3639
3640 if (filtered)
3641 count++;
3642
3643 bgp_attr_flush(&attr);
3644 }
3645 }
3646
3647 return count;
3648 }
3649
3650 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3651 int always)
3652 {
3653 iana_afi_t pkt_afi;
3654 iana_safi_t pkt_safi;
3655 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3656 PEER_FLAG_MAX_PREFIX_FORCE))
3657 ? bgp_filtered_routes_count(peer, afi, safi)
3658 + peer->pcount[afi][safi]
3659 : peer->pcount[afi][safi];
3660
3661 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3662 return false;
3663
3664 if (pcount > peer->pmax[afi][safi]) {
3665 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3666 PEER_STATUS_PREFIX_LIMIT)
3667 && !always)
3668 return false;
3669
3670 zlog_info(
3671 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3672 get_afi_safi_str(afi, safi, false), peer, pcount,
3673 peer->pmax[afi][safi]);
3674 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3675
3676 if (CHECK_FLAG(peer->af_flags[afi][safi],
3677 PEER_FLAG_MAX_PREFIX_WARNING))
3678 return false;
3679
3680 /* Convert AFI, SAFI to values for packet. */
3681 pkt_afi = afi_int2iana(afi);
3682 pkt_safi = safi_int2iana(safi);
3683 {
3684 uint8_t ndata[7];
3685
3686 ndata[0] = (pkt_afi >> 8);
3687 ndata[1] = pkt_afi;
3688 ndata[2] = pkt_safi;
3689 ndata[3] = (peer->pmax[afi][safi] >> 24);
3690 ndata[4] = (peer->pmax[afi][safi] >> 16);
3691 ndata[5] = (peer->pmax[afi][safi] >> 8);
3692 ndata[6] = (peer->pmax[afi][safi]);
3693
3694 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3695 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3696 BGP_NOTIFY_CEASE_MAX_PREFIX,
3697 ndata, 7);
3698 }
3699
3700 /* Dynamic peers will just close their connection. */
3701 if (peer_dynamic_neighbor(peer))
3702 return true;
3703
3704 /* restart timer start */
3705 if (peer->pmax_restart[afi][safi]) {
3706 peer->v_pmax_restart =
3707 peer->pmax_restart[afi][safi] * 60;
3708
3709 if (bgp_debug_neighbor_events(peer))
3710 zlog_debug(
3711 "%pBP Maximum-prefix restart timer started for %d secs",
3712 peer, peer->v_pmax_restart);
3713
3714 BGP_TIMER_ON(peer->t_pmax_restart,
3715 bgp_maximum_prefix_restart_timer,
3716 peer->v_pmax_restart);
3717 }
3718
3719 return true;
3720 } else
3721 UNSET_FLAG(peer->af_sflags[afi][safi],
3722 PEER_STATUS_PREFIX_LIMIT);
3723
3724 if (pcount
3725 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3726 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3727 PEER_STATUS_PREFIX_THRESHOLD)
3728 && !always)
3729 return false;
3730
3731 zlog_info(
3732 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3733 get_afi_safi_str(afi, safi, false), peer, pcount,
3734 peer->pmax[afi][safi]);
3735 SET_FLAG(peer->af_sflags[afi][safi],
3736 PEER_STATUS_PREFIX_THRESHOLD);
3737 } else
3738 UNSET_FLAG(peer->af_sflags[afi][safi],
3739 PEER_STATUS_PREFIX_THRESHOLD);
3740 return false;
3741 }
3742
3743 /* Unconditionally remove the route from the RIB, without taking
3744 * damping into consideration (eg, because the session went down)
3745 */
3746 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3747 struct peer *peer, afi_t afi, safi_t safi)
3748 {
3749
3750 struct bgp *bgp = NULL;
3751 bool delete_route = false;
3752
3753 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3754 safi);
3755
3756 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3757 bgp_path_info_delete(dest, pi); /* keep historical info */
3758
3759 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3760 * flag
3761 */
3762 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3763 delete_route = true;
3764 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3765 delete_route = true;
3766 if (delete_route) {
3767 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3768 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3769 bgp = pi->peer->bgp;
3770 bgp->gr_info[afi][safi].gr_deferred--;
3771 }
3772 }
3773 }
3774
3775 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3776 bgp_process(peer->bgp, dest, afi, safi);
3777 }
3778
3779 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3780 struct peer *peer, afi_t afi, safi_t safi,
3781 struct prefix_rd *prd)
3782 {
3783 const struct prefix *p = bgp_dest_get_prefix(dest);
3784
3785 /* apply dampening, if result is suppressed, we'll be retaining
3786 * the bgp_path_info in the RIB for historical reference.
3787 */
3788 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3789 && peer->sort == BGP_PEER_EBGP)
3790 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3791 == BGP_DAMP_SUPPRESSED) {
3792 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3793 safi);
3794 return;
3795 }
3796
3797 #ifdef ENABLE_BGP_VNC
3798 if (safi == SAFI_MPLS_VPN) {
3799 struct bgp_dest *pdest = NULL;
3800 struct bgp_table *table = NULL;
3801
3802 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3803 (struct prefix *)prd);
3804 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3805 table = bgp_dest_get_bgp_table_info(pdest);
3806
3807 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3808 peer->bgp, prd, table, p, pi);
3809 }
3810 bgp_dest_unlock_node(pdest);
3811 }
3812 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3813 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3814
3815 vnc_import_bgp_del_route(peer->bgp, p, pi);
3816 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3817 }
3818 }
3819 #endif
3820
3821 /* If this is an EVPN route, process for un-import. */
3822 if (safi == SAFI_EVPN)
3823 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3824
3825 bgp_rib_remove(dest, pi, peer, afi, safi);
3826 }
3827
3828 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3829 struct peer *peer, struct attr *attr,
3830 struct bgp_dest *dest)
3831 {
3832 struct bgp_path_info *new;
3833
3834 /* Make new BGP info. */
3835 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3836 new->type = type;
3837 new->instance = instance;
3838 new->sub_type = sub_type;
3839 new->peer = peer;
3840 new->attr = attr;
3841 new->uptime = monotime(NULL);
3842 new->net = dest;
3843 return new;
3844 }
3845
3846 /* Check if received nexthop is valid or not. */
3847 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3848 uint8_t type, uint8_t stype, struct attr *attr,
3849 struct bgp_dest *dest)
3850 {
3851 bool ret = false;
3852 bool is_bgp_static_route =
3853 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3854 : false;
3855
3856 /* If `bgp allow-martian-nexthop` is turned on, return next-hop
3857 * as good.
3858 */
3859 if (bgp->allow_martian)
3860 return false;
3861
3862 /*
3863 * Only validated for unicast and multicast currently.
3864 * Also valid for EVPN where the nexthop is an IP address.
3865 * If we are a bgp static route being checked then there is
3866 * no need to check to see if the nexthop is martian as
3867 * that it should be ok.
3868 */
3869 if (is_bgp_static_route ||
3870 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3871 return false;
3872
3873 /* If NEXT_HOP is present, validate it. */
3874 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3875 if (attr->nexthop.s_addr == INADDR_ANY ||
3876 !ipv4_unicast_valid(&attr->nexthop) ||
3877 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3878 return true;
3879 }
3880
3881 /* If MP_NEXTHOP is present, validate it. */
3882 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3883 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3884 * it is not an IPv6 link-local address.
3885 *
3886 * If we receive an UPDATE with nexthop length set to 32 bytes
3887 * we shouldn't discard an UPDATE if it's set to (::).
3888 * The link-local (2st) is validated along the code path later.
3889 */
3890 if (attr->mp_nexthop_len) {
3891 switch (attr->mp_nexthop_len) {
3892 case BGP_ATTR_NHLEN_IPV4:
3893 case BGP_ATTR_NHLEN_VPNV4:
3894 ret = (attr->mp_nexthop_global_in.s_addr ==
3895 INADDR_ANY ||
3896 !ipv4_unicast_valid(
3897 &attr->mp_nexthop_global_in) ||
3898 bgp_nexthop_self(bgp, afi, type, stype, attr,
3899 dest));
3900 break;
3901
3902 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3903 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3904 ret = (IN6_IS_ADDR_UNSPECIFIED(
3905 &attr->mp_nexthop_global)
3906 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3907 || IN6_IS_ADDR_MULTICAST(
3908 &attr->mp_nexthop_global)
3909 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3910 dest));
3911 break;
3912 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3913 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3914 || IN6_IS_ADDR_MULTICAST(
3915 &attr->mp_nexthop_global)
3916 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3917 dest));
3918 break;
3919
3920 default:
3921 ret = true;
3922 break;
3923 }
3924 }
3925
3926 return ret;
3927 }
3928
3929 static void bgp_attr_add_no_export_community(struct attr *attr)
3930 {
3931 struct community *old;
3932 struct community *new;
3933 struct community *merge;
3934 struct community *no_export;
3935
3936 old = bgp_attr_get_community(attr);
3937 no_export = community_str2com("no-export");
3938
3939 assert(no_export);
3940
3941 if (old) {
3942 merge = community_merge(community_dup(old), no_export);
3943
3944 if (!old->refcnt)
3945 community_free(&old);
3946
3947 new = community_uniq_sort(merge);
3948 community_free(&merge);
3949 } else {
3950 new = community_dup(no_export);
3951 }
3952
3953 community_free(&no_export);
3954
3955 bgp_attr_set_community(attr, new);
3956 }
3957
3958 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3959 struct attr *attr, const struct prefix *prefix,
3960 int *sub_type)
3961 {
3962 struct listnode *node, *nnode;
3963 struct bgp *bgp;
3964 bool accept_own_found = false;
3965
3966 if (safi != SAFI_MPLS_VPN)
3967 return false;
3968
3969 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3970 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3971 return false;
3972
3973 /* The route in question carries the ACCEPT_OWN community */
3974 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3975 struct community *comm = bgp_attr_get_community(attr);
3976
3977 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3978 accept_own_found = true;
3979 }
3980
3981 /* The route in question is targeted to one or more destination VRFs
3982 * on the router (as determined by inspecting the Route Target(s)).
3983 */
3984 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3985 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3986 continue;
3987
3988 if (accept_own_found &&
3989 ecommunity_include(
3990 bgp->vpn_policy[afi]
3991 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3992 bgp_attr_get_ecommunity(attr))) {
3993 if (bgp_debug_update(peer, prefix, NULL, 1))
3994 zlog_debug(
3995 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3996 peer, prefix);
3997
3998 /* Treat this route as imported, because it's leaked
3999 * already from another VRF, and we got an updated
4000 * version from route-reflector with ACCEPT_OWN
4001 * community.
4002 */
4003 *sub_type = BGP_ROUTE_IMPORTED;
4004
4005 return true;
4006 }
4007 }
4008
4009 return false;
4010 }
4011
4012 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4013 struct attr *attr, afi_t afi, safi_t safi, int type,
4014 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4015 uint32_t num_labels, int soft_reconfig,
4016 struct bgp_route_evpn *evpn)
4017 {
4018 int ret;
4019 int aspath_loop_count = 0;
4020 struct bgp_dest *dest;
4021 struct bgp *bgp;
4022 struct attr new_attr;
4023 struct attr *attr_new;
4024 struct bgp_path_info *pi;
4025 struct bgp_path_info *new = NULL;
4026 struct bgp_path_info_extra *extra;
4027 const char *reason;
4028 char pfx_buf[BGP_PRD_PATH_STRLEN];
4029 int connected = 0;
4030 int do_loop_check = 1;
4031 int has_valid_label = 0;
4032 afi_t nh_afi;
4033 bool force_evpn_import = false;
4034 safi_t orig_safi = safi;
4035 bool leak_success = true;
4036 int allowas_in = 0;
4037
4038 if (frrtrace_enabled(frr_bgp, process_update)) {
4039 char pfxprint[PREFIX2STR_BUFFER];
4040
4041 prefix2str(p, pfxprint, sizeof(pfxprint));
4042 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4043 afi, safi, attr);
4044 }
4045
4046 #ifdef ENABLE_BGP_VNC
4047 int vnc_implicit_withdraw = 0;
4048 #endif
4049 int same_attr = 0;
4050 const struct prefix *bgp_nht_param_prefix;
4051
4052 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4053 if (orig_safi == SAFI_LABELED_UNICAST)
4054 safi = SAFI_UNICAST;
4055
4056 memset(&new_attr, 0, sizeof(new_attr));
4057 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4058 new_attr.label = MPLS_INVALID_LABEL;
4059
4060 bgp = peer->bgp;
4061 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4062 /* TODO: Check to see if we can get rid of "is_valid_label" */
4063 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4064 has_valid_label = (num_labels > 0) ? 1 : 0;
4065 else
4066 has_valid_label = bgp_is_valid_label(label);
4067
4068 if (has_valid_label)
4069 assert(label != NULL);
4070
4071
4072 /* When peer's soft reconfiguration enabled. Record input packet in
4073 Adj-RIBs-In. */
4074 if (!soft_reconfig &&
4075 CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG) &&
4076 peer != bgp->peer_self) {
4077 /*
4078 * If the trigger is not from soft_reconfig and if
4079 * PEER_FLAG_SOFT_RECONFIG is enabled for the peer, then attr
4080 * will not be interned. In which case, it is ok to update the
4081 * attr->evpn_overlay, so that, this can be stored in adj_in.
4082 */
4083 if ((afi == AFI_L2VPN) && evpn) {
4084 memcpy(&attr->evpn_overlay, evpn,
4085 sizeof(struct bgp_route_evpn));
4086 }
4087 bgp_adj_in_set(dest, peer, attr, addpath_id);
4088 }
4089
4090 /* Update permitted loop count */
4091 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4092 allowas_in = peer->allowas_in[afi][safi];
4093
4094 /* Check previously received route. */
4095 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4096 if (pi->peer == peer && pi->type == type
4097 && pi->sub_type == sub_type
4098 && pi->addpath_rx_id == addpath_id)
4099 break;
4100
4101 /* AS path local-as loop check. */
4102 if (peer->change_local_as) {
4103 if (allowas_in)
4104 aspath_loop_count = allowas_in;
4105 else if (!CHECK_FLAG(peer->flags,
4106 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4107 aspath_loop_count = 1;
4108
4109 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4110 > aspath_loop_count) {
4111 peer->stat_pfx_aspath_loop++;
4112 reason = "as-path contains our own AS;";
4113 goto filtered;
4114 }
4115 }
4116
4117 /* If the peer is configured for "allowas-in origin" and the last ASN in
4118 * the
4119 * as-path is our ASN then we do not need to call aspath_loop_check
4120 */
4121 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4122 if (aspath_get_last_as(attr->aspath) == bgp->as)
4123 do_loop_check = 0;
4124
4125 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4126 bgp_nht_param_prefix = NULL;
4127 else
4128 bgp_nht_param_prefix = p;
4129
4130 /* AS path loop check. */
4131 if (do_loop_check) {
4132 if (aspath_loop_check(attr->aspath, bgp->as) >
4133 peer->allowas_in[afi][safi]) {
4134 peer->stat_pfx_aspath_loop++;
4135 reason = "as-path contains our own AS;";
4136 goto filtered;
4137 }
4138 }
4139
4140 /* If we're a CONFED we need to loop check the CONFED ID too */
4141 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4142 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4143 peer->allowas_in[afi][safi]) {
4144 peer->stat_pfx_aspath_loop++;
4145 reason = "as-path contains our own confed AS;";
4146 goto filtered;
4147 }
4148
4149 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4150 * enabled, then take care of that too.
4151 */
4152 bool accept_own = false;
4153
4154 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4155 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4156 accept_own =
4157 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4158 if (!accept_own) {
4159 peer->stat_pfx_originator_loop++;
4160 reason = "originator is us;";
4161 goto filtered;
4162 }
4163 }
4164
4165 /* Route reflector cluster ID check. */
4166 if (bgp_cluster_filter(peer, attr)) {
4167 peer->stat_pfx_cluster_loop++;
4168 reason = "reflected from the same cluster;";
4169 goto filtered;
4170 }
4171
4172 /* Apply incoming filter. */
4173 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4174 peer->stat_pfx_filter++;
4175 reason = "filter;";
4176 goto filtered;
4177 }
4178
4179 /* If the route has Node Target Extended Communities, check
4180 * if it's allowed to be installed locally.
4181 */
4182 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4183 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
4184
4185 if (ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
4186 ECOMMUNITY_NODE_TARGET) &&
4187 !ecommunity_node_target_match(ecomm, &peer->local_id)) {
4188 reason =
4189 "Node-Target Extended Communities do not contain own BGP Identifier;";
4190 goto filtered;
4191 }
4192 }
4193
4194 /* RFC 8212 to prevent route leaks.
4195 * This specification intends to improve this situation by requiring the
4196 * explicit configuration of both BGP Import and Export Policies for any
4197 * External BGP (EBGP) session such as customers, peers, or
4198 * confederation boundaries for all enabled address families. Through
4199 * codification of the aforementioned requirement, operators will
4200 * benefit from consistent behavior across different BGP
4201 * implementations.
4202 */
4203 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4204 if (!bgp_inbound_policy_exists(peer,
4205 &peer->filter[afi][safi])) {
4206 reason = "inbound policy missing";
4207 if (monotime_since(&bgp->ebgprequirespolicywarning,
4208 NULL) > FIFTEENMINUTE2USEC ||
4209 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4210 zlog_warn(
4211 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4212 monotime(&bgp->ebgprequirespolicywarning);
4213 }
4214 goto filtered;
4215 }
4216
4217 /* draft-ietf-idr-deprecate-as-set-confed-set
4218 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4219 * Eventually, This document (if approved) updates RFC 4271
4220 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4221 * and obsoletes RFC 6472.
4222 */
4223 if (peer->bgp->reject_as_sets)
4224 if (aspath_check_as_sets(attr->aspath)) {
4225 reason =
4226 "as-path contains AS_SET or AS_CONFED_SET type;";
4227 goto filtered;
4228 }
4229
4230 new_attr = *attr;
4231 /*
4232 * If bgp_update is called with soft_reconfig set then
4233 * attr is interned. In this case, do not overwrite the
4234 * attr->evpn_overlay with evpn directly. Instead memcpy
4235 * evpn to new_atr.evpn_overlay before it is interned.
4236 */
4237 if (soft_reconfig && (afi == AFI_L2VPN) && evpn)
4238 memcpy(&new_attr.evpn_overlay, evpn,
4239 sizeof(struct bgp_route_evpn));
4240
4241 /* Apply incoming route-map.
4242 * NB: new_attr may now contain newly allocated values from route-map
4243 * "set"
4244 * commands, so we need bgp_attr_flush in the error paths, until we
4245 * intern
4246 * the attr (which takes over the memory references) */
4247 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4248 num_labels, dest)
4249 == RMAP_DENY) {
4250 peer->stat_pfx_filter++;
4251 reason = "route-map;";
4252 bgp_attr_flush(&new_attr);
4253 goto filtered;
4254 }
4255
4256 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4257 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4258 /* remove from RIB previous entry */
4259 bgp_zebra_withdraw(p, pi, bgp, safi);
4260 }
4261
4262 if (peer->sort == BGP_PEER_EBGP) {
4263
4264 /* rfc7999:
4265 * A BGP speaker receiving an announcement tagged with the
4266 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4267 * NO_EXPORT community as defined in RFC1997, or a
4268 * similar community, to prevent propagation of the
4269 * prefix outside the local AS. The community to prevent
4270 * propagation SHOULD be chosen according to the operator's
4271 * routing policy.
4272 */
4273 if (bgp_attr_get_community(&new_attr) &&
4274 community_include(bgp_attr_get_community(&new_attr),
4275 COMMUNITY_BLACKHOLE))
4276 bgp_attr_add_no_export_community(&new_attr);
4277
4278 /* If we receive the graceful-shutdown community from an eBGP
4279 * peer we must lower local-preference */
4280 if (bgp_attr_get_community(&new_attr) &&
4281 community_include(bgp_attr_get_community(&new_attr),
4282 COMMUNITY_GSHUT)) {
4283 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4284 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4285
4286 /* If graceful-shutdown is configured globally or
4287 * per neighbor, then add the GSHUT community to
4288 * all paths received from eBGP peers. */
4289 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4290 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4291 bgp_attr_add_gshut_community(&new_attr);
4292 }
4293
4294 /* next hop check. */
4295 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4296 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4297 &new_attr, dest)) {
4298 peer->stat_pfx_nh_invalid++;
4299 reason = "martian or self next-hop;";
4300 bgp_attr_flush(&new_attr);
4301 goto filtered;
4302 }
4303
4304 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4305 peer->stat_pfx_nh_invalid++;
4306 reason = "self mac;";
4307 bgp_attr_flush(&new_attr);
4308 goto filtered;
4309 }
4310
4311 if (bgp_check_role_applicability(afi, safi) &&
4312 bgp_otc_filter(peer, &new_attr)) {
4313 reason = "failing otc validation";
4314 bgp_attr_flush(&new_attr);
4315 goto filtered;
4316 }
4317
4318 /* If neighbor soo is configured, tag all incoming routes with
4319 * this SoO tag and then filter out advertisements in
4320 * subgroup_announce_check() if it matches the configured SoO
4321 * on the other peer.
4322 */
4323 if (peer->soo[afi][safi]) {
4324 struct ecommunity *old_ecomm =
4325 bgp_attr_get_ecommunity(&new_attr);
4326 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4327 struct ecommunity *new_ecomm;
4328
4329 if (old_ecomm) {
4330 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4331 ecomm_soo);
4332
4333 if (!old_ecomm->refcnt)
4334 ecommunity_free(&old_ecomm);
4335 } else {
4336 new_ecomm = ecommunity_dup(ecomm_soo);
4337 }
4338
4339 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4340 }
4341
4342 attr_new = bgp_attr_intern(&new_attr);
4343
4344 /* If the update is implicit withdraw. */
4345 if (pi) {
4346 pi->uptime = monotime(NULL);
4347 same_attr = attrhash_cmp(pi->attr, attr_new);
4348
4349 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4350
4351 /* Same attribute comes in. */
4352 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4353 && same_attr
4354 && (!has_valid_label
4355 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4356 num_labels * sizeof(mpls_label_t))
4357 == 0)) {
4358 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4359 BGP_CONFIG_DAMPENING)
4360 && peer->sort == BGP_PEER_EBGP
4361 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4362 if (bgp_debug_update(peer, p, NULL, 1)) {
4363 bgp_debug_rdpfxpath2str(
4364 afi, safi, prd, p, label,
4365 num_labels, addpath_id ? 1 : 0,
4366 addpath_id, evpn, pfx_buf,
4367 sizeof(pfx_buf));
4368 zlog_debug("%pBP rcvd %s", peer,
4369 pfx_buf);
4370 }
4371
4372 if (bgp_damp_update(pi, dest, afi, safi)
4373 != BGP_DAMP_SUPPRESSED) {
4374 bgp_aggregate_increment(bgp, p, pi, afi,
4375 safi);
4376 bgp_process(bgp, dest, afi, safi);
4377 }
4378 } else /* Duplicate - odd */
4379 {
4380 if (bgp_debug_update(peer, p, NULL, 1)) {
4381 if (!peer->rcvd_attr_printed) {
4382 zlog_debug(
4383 "%pBP rcvd UPDATE w/ attr: %s",
4384 peer,
4385 peer->rcvd_attr_str);
4386 peer->rcvd_attr_printed = 1;
4387 }
4388
4389 bgp_debug_rdpfxpath2str(
4390 afi, safi, prd, p, label,
4391 num_labels, addpath_id ? 1 : 0,
4392 addpath_id, evpn, pfx_buf,
4393 sizeof(pfx_buf));
4394 zlog_debug(
4395 "%pBP rcvd %s...duplicate ignored",
4396 peer, pfx_buf);
4397 }
4398
4399 /* graceful restart STALE flag unset. */
4400 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4401 bgp_path_info_unset_flag(
4402 dest, pi, BGP_PATH_STALE);
4403 bgp_dest_set_defer_flag(dest, false);
4404 bgp_process(bgp, dest, afi, safi);
4405 }
4406 }
4407
4408 bgp_dest_unlock_node(dest);
4409 bgp_attr_unintern(&attr_new);
4410
4411 return;
4412 }
4413
4414 /* Withdraw/Announce before we fully processed the withdraw */
4415 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4416 if (bgp_debug_update(peer, p, NULL, 1)) {
4417 bgp_debug_rdpfxpath2str(
4418 afi, safi, prd, p, label, num_labels,
4419 addpath_id ? 1 : 0, addpath_id, evpn,
4420 pfx_buf, sizeof(pfx_buf));
4421 zlog_debug(
4422 "%pBP rcvd %s, flapped quicker than processing",
4423 peer, pfx_buf);
4424 }
4425
4426 bgp_path_info_restore(dest, pi);
4427
4428 /*
4429 * If the BGP_PATH_REMOVED flag is set, then EVPN
4430 * routes would have been unimported already when a
4431 * prior BGP withdraw processing happened. Such routes
4432 * need to be imported again, so flag accordingly.
4433 */
4434 force_evpn_import = true;
4435 } else {
4436 /* implicit withdraw, decrement aggregate and pcount
4437 * here. only if update is accepted, they'll increment
4438 * below.
4439 */
4440 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4441 }
4442
4443 /* Received Logging. */
4444 if (bgp_debug_update(peer, p, NULL, 1)) {
4445 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4446 num_labels, addpath_id ? 1 : 0,
4447 addpath_id, evpn, pfx_buf,
4448 sizeof(pfx_buf));
4449 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4450 }
4451
4452 /* graceful restart STALE flag unset. */
4453 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4454 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4455 bgp_dest_set_defer_flag(dest, false);
4456 }
4457
4458 /* The attribute is changed. */
4459 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4460
4461 /* Update bgp route dampening information. */
4462 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4463 && peer->sort == BGP_PEER_EBGP) {
4464 /* This is implicit withdraw so we should update
4465 dampening
4466 information. */
4467 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4468 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4469 }
4470 #ifdef ENABLE_BGP_VNC
4471 if (safi == SAFI_MPLS_VPN) {
4472 struct bgp_dest *pdest = NULL;
4473 struct bgp_table *table = NULL;
4474
4475 pdest = bgp_node_get(bgp->rib[afi][safi],
4476 (struct prefix *)prd);
4477 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4478 table = bgp_dest_get_bgp_table_info(pdest);
4479
4480 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4481 bgp, prd, table, p, pi);
4482 }
4483 bgp_dest_unlock_node(pdest);
4484 }
4485 if ((afi == AFI_IP || afi == AFI_IP6)
4486 && (safi == SAFI_UNICAST)) {
4487 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4488 /*
4489 * Implicit withdraw case.
4490 */
4491 ++vnc_implicit_withdraw;
4492 vnc_import_bgp_del_route(bgp, p, pi);
4493 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4494 }
4495 }
4496 #endif
4497
4498 /* Special handling for EVPN update of an existing route. If the
4499 * extended community attribute has changed, we need to
4500 * un-import
4501 * the route using its existing extended community. It will be
4502 * subsequently processed for import with the new extended
4503 * community.
4504 */
4505 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4506 && !same_attr) {
4507 if ((pi->attr->flag
4508 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4509 && (attr_new->flag
4510 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4511 int cmp;
4512
4513 cmp = ecommunity_cmp(
4514 bgp_attr_get_ecommunity(pi->attr),
4515 bgp_attr_get_ecommunity(attr_new));
4516 if (!cmp) {
4517 if (bgp_debug_update(peer, p, NULL, 1))
4518 zlog_debug(
4519 "Change in EXT-COMM, existing %s new %s",
4520 ecommunity_str(
4521 bgp_attr_get_ecommunity(
4522 pi->attr)),
4523 ecommunity_str(
4524 bgp_attr_get_ecommunity(
4525 attr_new)));
4526 if (safi == SAFI_EVPN)
4527 bgp_evpn_unimport_route(
4528 bgp, afi, safi, p, pi);
4529 else /* SAFI_MPLS_VPN */
4530 vpn_leak_to_vrf_withdraw(pi);
4531 }
4532 }
4533 }
4534
4535 /* Update to new attribute. */
4536 bgp_attr_unintern(&pi->attr);
4537 pi->attr = attr_new;
4538
4539 /* Update MPLS label */
4540 if (has_valid_label) {
4541 extra = bgp_path_info_extra_get(pi);
4542 if (extra->label != label) {
4543 memcpy(&extra->label, label,
4544 num_labels * sizeof(mpls_label_t));
4545 extra->num_labels = num_labels;
4546 }
4547 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4548 bgp_set_valid_label(&extra->label[0]);
4549 }
4550
4551 /* Update SRv6 SID */
4552 if (attr->srv6_l3vpn) {
4553 extra = bgp_path_info_extra_get(pi);
4554 if (sid_diff(&extra->sid[0].sid,
4555 &attr->srv6_l3vpn->sid)) {
4556 sid_copy(&extra->sid[0].sid,
4557 &attr->srv6_l3vpn->sid);
4558 extra->num_sids = 1;
4559
4560 extra->sid[0].loc_block_len = 0;
4561 extra->sid[0].loc_node_len = 0;
4562 extra->sid[0].func_len = 0;
4563 extra->sid[0].arg_len = 0;
4564 extra->sid[0].transposition_len = 0;
4565 extra->sid[0].transposition_offset = 0;
4566
4567 if (attr->srv6_l3vpn->loc_block_len != 0) {
4568 extra->sid[0].loc_block_len =
4569 attr->srv6_l3vpn->loc_block_len;
4570 extra->sid[0].loc_node_len =
4571 attr->srv6_l3vpn->loc_node_len;
4572 extra->sid[0].func_len =
4573 attr->srv6_l3vpn->func_len;
4574 extra->sid[0].arg_len =
4575 attr->srv6_l3vpn->arg_len;
4576 extra->sid[0].transposition_len =
4577 attr->srv6_l3vpn
4578 ->transposition_len;
4579 extra->sid[0].transposition_offset =
4580 attr->srv6_l3vpn
4581 ->transposition_offset;
4582 }
4583 }
4584 } else if (attr->srv6_vpn) {
4585 extra = bgp_path_info_extra_get(pi);
4586 if (sid_diff(&extra->sid[0].sid,
4587 &attr->srv6_vpn->sid)) {
4588 sid_copy(&extra->sid[0].sid,
4589 &attr->srv6_vpn->sid);
4590 extra->num_sids = 1;
4591 }
4592 }
4593
4594 #ifdef ENABLE_BGP_VNC
4595 if ((afi == AFI_IP || afi == AFI_IP6)
4596 && (safi == SAFI_UNICAST)) {
4597 if (vnc_implicit_withdraw) {
4598 /*
4599 * Add back the route with its new attributes
4600 * (e.g., nexthop).
4601 * The route is still selected, until the route
4602 * selection
4603 * queued by bgp_process actually runs. We have
4604 * to make this
4605 * update to the VNC side immediately to avoid
4606 * racing against
4607 * configuration changes (e.g., route-map
4608 * changes) which
4609 * trigger re-importation of the entire RIB.
4610 */
4611 vnc_import_bgp_add_route(bgp, p, pi);
4612 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4613 }
4614 }
4615 #endif
4616
4617 /* Update bgp route dampening information. */
4618 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4619 && peer->sort == BGP_PEER_EBGP) {
4620 /* Now we do normal update dampening. */
4621 ret = bgp_damp_update(pi, dest, afi, safi);
4622 if (ret == BGP_DAMP_SUPPRESSED) {
4623 bgp_dest_unlock_node(dest);
4624 return;
4625 }
4626 }
4627
4628 /* Nexthop reachability check - for unicast and
4629 * labeled-unicast.. */
4630 if (((afi == AFI_IP || afi == AFI_IP6)
4631 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4632 || (safi == SAFI_EVPN &&
4633 bgp_evpn_is_prefix_nht_supported(p))) {
4634 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4635 && peer->ttl == BGP_DEFAULT_TTL
4636 && !CHECK_FLAG(peer->flags,
4637 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4638 && !CHECK_FLAG(bgp->flags,
4639 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4640 connected = 1;
4641 else
4642 connected = 0;
4643
4644 struct bgp *bgp_nexthop = bgp;
4645
4646 if (pi->extra && pi->extra->bgp_orig)
4647 bgp_nexthop = pi->extra->bgp_orig;
4648
4649 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4650
4651 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4652 safi, pi, NULL, connected,
4653 bgp_nht_param_prefix) ||
4654 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4655 bgp_path_info_set_flag(dest, pi,
4656 BGP_PATH_VALID);
4657 else {
4658 if (BGP_DEBUG(nht, NHT)) {
4659 zlog_debug("%s(%pI4): NH unresolved",
4660 __func__,
4661 (in_addr_t *)&attr_new->nexthop);
4662 }
4663 bgp_path_info_unset_flag(dest, pi,
4664 BGP_PATH_VALID);
4665 }
4666 } else {
4667 if (accept_own)
4668 bgp_path_info_set_flag(dest, pi,
4669 BGP_PATH_ACCEPT_OWN);
4670
4671 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4672 }
4673
4674 #ifdef ENABLE_BGP_VNC
4675 if (safi == SAFI_MPLS_VPN) {
4676 struct bgp_dest *pdest = NULL;
4677 struct bgp_table *table = NULL;
4678
4679 pdest = bgp_node_get(bgp->rib[afi][safi],
4680 (struct prefix *)prd);
4681 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4682 table = bgp_dest_get_bgp_table_info(pdest);
4683
4684 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4685 bgp, prd, table, p, pi);
4686 }
4687 bgp_dest_unlock_node(pdest);
4688 }
4689 #endif
4690
4691 /* If this is an EVPN route and some attribute has changed,
4692 * or we are explicitly told to perform a route import, process
4693 * route for import. If the extended community has changed, we
4694 * would
4695 * have done the un-import earlier and the import would result
4696 * in the
4697 * route getting injected into appropriate L2 VNIs. If it is
4698 * just
4699 * some other attribute change, the import will result in
4700 * updating
4701 * the attributes for the route in the VNI(s).
4702 */
4703 if (safi == SAFI_EVPN &&
4704 (!same_attr || force_evpn_import) &&
4705 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4706 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4707
4708 /* Process change. */
4709 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4710
4711 bgp_process(bgp, dest, afi, safi);
4712 bgp_dest_unlock_node(dest);
4713
4714 if (SAFI_UNICAST == safi
4715 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4716 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4717
4718 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4719 }
4720 if ((SAFI_MPLS_VPN == safi)
4721 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4722 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4723 }
4724
4725 #ifdef ENABLE_BGP_VNC
4726 if (SAFI_MPLS_VPN == safi) {
4727 mpls_label_t label_decoded = decode_label(label);
4728
4729 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4730 type, sub_type, &label_decoded);
4731 }
4732 if (SAFI_ENCAP == safi) {
4733 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4734 type, sub_type, NULL);
4735 }
4736 #endif
4737 if ((safi == SAFI_MPLS_VPN) &&
4738 !CHECK_FLAG(bgp->af_flags[afi][safi],
4739 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4740 !leak_success) {
4741 bgp_unlink_nexthop(pi);
4742 bgp_path_info_delete(dest, pi);
4743 }
4744 return;
4745 } // End of implicit withdraw
4746
4747 /* Received Logging. */
4748 if (bgp_debug_update(peer, p, NULL, 1)) {
4749 if (!peer->rcvd_attr_printed) {
4750 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4751 peer->rcvd_attr_str);
4752 peer->rcvd_attr_printed = 1;
4753 }
4754
4755 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4756 addpath_id ? 1 : 0, addpath_id, evpn,
4757 pfx_buf, sizeof(pfx_buf));
4758 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4759 }
4760
4761 /* Make new BGP info. */
4762 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4763
4764 /* Update MPLS label */
4765 if (has_valid_label) {
4766 extra = bgp_path_info_extra_get(new);
4767 if (extra->label != label) {
4768 memcpy(&extra->label, label,
4769 num_labels * sizeof(mpls_label_t));
4770 extra->num_labels = num_labels;
4771 }
4772 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4773 bgp_set_valid_label(&extra->label[0]);
4774 }
4775
4776 /* Update SRv6 SID */
4777 if (safi == SAFI_MPLS_VPN) {
4778 extra = bgp_path_info_extra_get(new);
4779 if (attr->srv6_l3vpn) {
4780 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4781 extra->num_sids = 1;
4782
4783 extra->sid[0].loc_block_len =
4784 attr->srv6_l3vpn->loc_block_len;
4785 extra->sid[0].loc_node_len =
4786 attr->srv6_l3vpn->loc_node_len;
4787 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4788 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4789 extra->sid[0].transposition_len =
4790 attr->srv6_l3vpn->transposition_len;
4791 extra->sid[0].transposition_offset =
4792 attr->srv6_l3vpn->transposition_offset;
4793 } else if (attr->srv6_vpn) {
4794 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4795 extra->num_sids = 1;
4796 }
4797 }
4798
4799 /* Nexthop reachability check. */
4800 if (((afi == AFI_IP || afi == AFI_IP6)
4801 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4802 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4803 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4804 && peer->ttl == BGP_DEFAULT_TTL
4805 && !CHECK_FLAG(peer->flags,
4806 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4807 && !CHECK_FLAG(bgp->flags,
4808 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4809 connected = 1;
4810 else
4811 connected = 0;
4812
4813 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4814
4815 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4816 connected, bgp_nht_param_prefix) ||
4817 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4818 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4819 else {
4820 if (BGP_DEBUG(nht, NHT))
4821 zlog_debug("%s(%pI4): NH unresolved", __func__,
4822 &attr_new->nexthop);
4823 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4824 }
4825 } else {
4826 if (accept_own)
4827 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4828
4829 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4830 }
4831
4832 /* If maximum prefix count is configured and current prefix
4833 * count exeed it.
4834 */
4835 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4836 reason = "maximum-prefix overflow";
4837 bgp_attr_flush(&new_attr);
4838 goto filtered;
4839 }
4840
4841 /* Addpath ID */
4842 new->addpath_rx_id = addpath_id;
4843
4844 /* Increment prefix */
4845 bgp_aggregate_increment(bgp, p, new, afi, safi);
4846
4847 /* Register new BGP information. */
4848 bgp_path_info_add(dest, new);
4849
4850 /* route_node_get lock */
4851 bgp_dest_unlock_node(dest);
4852
4853 #ifdef ENABLE_BGP_VNC
4854 if (safi == SAFI_MPLS_VPN) {
4855 struct bgp_dest *pdest = NULL;
4856 struct bgp_table *table = NULL;
4857
4858 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4859 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4860 table = bgp_dest_get_bgp_table_info(pdest);
4861
4862 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4863 bgp, prd, table, p, new);
4864 }
4865 bgp_dest_unlock_node(pdest);
4866 }
4867 #endif
4868
4869 /* If this is an EVPN route, process for import. */
4870 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4871 bgp_evpn_import_route(bgp, afi, safi, p, new);
4872
4873 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4874
4875 /* Process change. */
4876 bgp_process(bgp, dest, afi, safi);
4877
4878 if (SAFI_UNICAST == safi
4879 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4880 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4881 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4882 }
4883 if ((SAFI_MPLS_VPN == safi)
4884 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4885 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4886 }
4887 #ifdef ENABLE_BGP_VNC
4888 if (SAFI_MPLS_VPN == safi) {
4889 mpls_label_t label_decoded = decode_label(label);
4890
4891 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4892 sub_type, &label_decoded);
4893 }
4894 if (SAFI_ENCAP == safi) {
4895 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4896 sub_type, NULL);
4897 }
4898 #endif
4899 if ((safi == SAFI_MPLS_VPN) &&
4900 !CHECK_FLAG(bgp->af_flags[afi][safi],
4901 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4902 !leak_success) {
4903 bgp_unlink_nexthop(new);
4904 bgp_path_info_delete(dest, new);
4905 }
4906
4907 return;
4908
4909 /* This BGP update is filtered. Log the reason then update BGP
4910 entry. */
4911 filtered:
4912 if (new) {
4913 bgp_unlink_nexthop(new);
4914 bgp_path_info_delete(dest, new);
4915 bgp_path_info_extra_free(&new->extra);
4916 XFREE(MTYPE_BGP_ROUTE, new);
4917 }
4918
4919 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4920
4921 if (bgp_debug_update(peer, p, NULL, 1)) {
4922 if (!peer->rcvd_attr_printed) {
4923 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4924 peer->rcvd_attr_str);
4925 peer->rcvd_attr_printed = 1;
4926 }
4927
4928 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4929 addpath_id ? 1 : 0, addpath_id, evpn,
4930 pfx_buf, sizeof(pfx_buf));
4931 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4932 peer, pfx_buf, reason);
4933 }
4934
4935 if (pi) {
4936 /* If this is an EVPN route, un-import it as it is now filtered.
4937 */
4938 if (safi == SAFI_EVPN)
4939 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4940
4941 if (SAFI_UNICAST == safi
4942 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4943 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4944
4945 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4946 }
4947 if ((SAFI_MPLS_VPN == safi)
4948 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4949
4950 vpn_leak_to_vrf_withdraw(pi);
4951 }
4952
4953 bgp_rib_remove(dest, pi, peer, afi, safi);
4954 }
4955
4956 bgp_dest_unlock_node(dest);
4957
4958 #ifdef ENABLE_BGP_VNC
4959 /*
4960 * Filtered update is treated as an implicit withdrawal (see
4961 * bgp_rib_remove()
4962 * a few lines above)
4963 */
4964 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4965 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4966 0);
4967 }
4968 #endif
4969
4970 return;
4971 }
4972
4973 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4974 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4975 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4976 uint32_t num_labels, struct bgp_route_evpn *evpn)
4977 {
4978 struct bgp *bgp;
4979 char pfx_buf[BGP_PRD_PATH_STRLEN];
4980 struct bgp_dest *dest;
4981 struct bgp_path_info *pi;
4982
4983 #ifdef ENABLE_BGP_VNC
4984 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4985 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4986 0);
4987 }
4988 #endif
4989
4990 bgp = peer->bgp;
4991
4992 /* Lookup node. */
4993 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4994
4995 /* If peer is soft reconfiguration enabled. Record input packet for
4996 * further calculation.
4997 *
4998 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4999 * routes that are filtered. This tanks out Quagga RS pretty badly due
5000 * to
5001 * the iteration over all RS clients.
5002 * Since we need to remove the entry from adj_in anyway, do that first
5003 * and
5004 * if there was no entry, we don't need to do anything more.
5005 */
5006 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
5007 && peer != bgp->peer_self)
5008 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
5009 peer->stat_pfx_dup_withdraw++;
5010
5011 if (bgp_debug_update(peer, p, NULL, 1)) {
5012 bgp_debug_rdpfxpath2str(
5013 afi, safi, prd, p, label, num_labels,
5014 addpath_id ? 1 : 0, addpath_id, NULL,
5015 pfx_buf, sizeof(pfx_buf));
5016 zlog_debug(
5017 "%s withdrawing route %s not in adj-in",
5018 peer->host, pfx_buf);
5019 }
5020 bgp_dest_unlock_node(dest);
5021 return;
5022 }
5023
5024 /* Lookup withdrawn route. */
5025 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5026 if (pi->peer == peer && pi->type == type
5027 && pi->sub_type == sub_type
5028 && pi->addpath_rx_id == addpath_id)
5029 break;
5030
5031 /* Logging. */
5032 if (bgp_debug_update(peer, p, NULL, 1)) {
5033 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5034 addpath_id ? 1 : 0, addpath_id, NULL,
5035 pfx_buf, sizeof(pfx_buf));
5036 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
5037 pfx_buf);
5038 }
5039
5040 /* Withdraw specified route from routing table. */
5041 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
5042 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
5043 if (SAFI_UNICAST == safi
5044 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5045 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5046 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5047 }
5048 if ((SAFI_MPLS_VPN == safi)
5049 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5050
5051 vpn_leak_to_vrf_withdraw(pi);
5052 }
5053 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5054 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5055 addpath_id ? 1 : 0, addpath_id, NULL,
5056 pfx_buf, sizeof(pfx_buf));
5057 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5058 }
5059
5060 /* Unlock bgp_node_get() lock. */
5061 bgp_dest_unlock_node(dest);
5062
5063 return;
5064 }
5065
5066 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5067 int withdraw)
5068 {
5069 struct update_subgroup *subgrp;
5070 subgrp = peer_subgroup(peer, afi, safi);
5071 subgroup_default_originate(subgrp, withdraw);
5072 }
5073
5074
5075 /*
5076 * bgp_stop_announce_route_timer
5077 */
5078 void bgp_stop_announce_route_timer(struct peer_af *paf)
5079 {
5080 if (!paf->t_announce_route)
5081 return;
5082
5083 EVENT_OFF(paf->t_announce_route);
5084 }
5085
5086 /*
5087 * bgp_announce_route_timer_expired
5088 *
5089 * Callback that is invoked when the route announcement timer for a
5090 * peer_af expires.
5091 */
5092 static void bgp_announce_route_timer_expired(struct event *t)
5093 {
5094 struct peer_af *paf;
5095 struct peer *peer;
5096
5097 paf = EVENT_ARG(t);
5098 peer = paf->peer;
5099
5100 if (!peer_established(peer))
5101 return;
5102
5103 if (!peer->afc_nego[paf->afi][paf->safi])
5104 return;
5105
5106 peer_af_announce_route(paf, 1);
5107
5108 /* Notify BGP conditional advertisement scanner percess */
5109 peer->advmap_config_change[paf->afi][paf->safi] = true;
5110 }
5111
5112 /*
5113 * bgp_announce_route
5114 *
5115 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5116 *
5117 * if force is true we will force an update even if the update
5118 * limiting code is attempted to kick in.
5119 */
5120 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5121 {
5122 struct peer_af *paf;
5123 struct update_subgroup *subgrp;
5124
5125 paf = peer_af_find(peer, afi, safi);
5126 if (!paf)
5127 return;
5128 subgrp = PAF_SUBGRP(paf);
5129
5130 /*
5131 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5132 * or a refresh has already been triggered.
5133 */
5134 if (!subgrp || paf->t_announce_route)
5135 return;
5136
5137 if (force)
5138 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5139
5140 /*
5141 * Start a timer to stagger/delay the announce. This serves
5142 * two purposes - announcement can potentially be combined for
5143 * multiple peers and the announcement doesn't happen in the
5144 * vty context.
5145 */
5146 event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5147 (subgrp->peer_count == 1)
5148 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5149 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5150 &paf->t_announce_route);
5151 }
5152
5153 /*
5154 * Announce routes from all AF tables to a peer.
5155 *
5156 * This should ONLY be called when there is a need to refresh the
5157 * routes to the peer based on a policy change for this peer alone
5158 * or a route refresh request received from the peer.
5159 * The operation will result in splitting the peer from its existing
5160 * subgroups and putting it in new subgroups.
5161 */
5162 void bgp_announce_route_all(struct peer *peer)
5163 {
5164 afi_t afi;
5165 safi_t safi;
5166
5167 FOREACH_AFI_SAFI (afi, safi)
5168 bgp_announce_route(peer, afi, safi, false);
5169 }
5170
5171 /* Flag or unflag bgp_dest to determine whether it should be treated by
5172 * bgp_soft_reconfig_table_task.
5173 * Flag if flag is true. Unflag if flag is false.
5174 */
5175 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5176 {
5177 struct bgp_dest *dest;
5178 struct bgp_adj_in *ain;
5179
5180 if (!table)
5181 return;
5182
5183 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5184 for (ain = dest->adj_in; ain; ain = ain->next) {
5185 if (ain->peer != NULL)
5186 break;
5187 }
5188 if (flag && ain != NULL && ain->peer != NULL)
5189 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5190 else
5191 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5192 }
5193 }
5194
5195 static void bgp_soft_reconfig_table_update(struct peer *peer,
5196 struct bgp_dest *dest,
5197 struct bgp_adj_in *ain, afi_t afi,
5198 safi_t safi, struct prefix_rd *prd)
5199 {
5200 struct bgp_path_info *pi;
5201 uint32_t num_labels = 0;
5202 mpls_label_t *label_pnt = NULL;
5203 struct bgp_route_evpn evpn;
5204
5205 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5206 if (pi->peer == peer)
5207 break;
5208
5209 if (pi && pi->extra)
5210 num_labels = pi->extra->num_labels;
5211 if (num_labels)
5212 label_pnt = &pi->extra->label[0];
5213 if (pi)
5214 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5215 sizeof(evpn));
5216 else
5217 memset(&evpn, 0, sizeof(evpn));
5218
5219 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5220 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5221 label_pnt, num_labels, 1, &evpn);
5222 }
5223
5224 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5225 struct bgp_table *table,
5226 struct prefix_rd *prd)
5227 {
5228 struct bgp_dest *dest;
5229 struct bgp_adj_in *ain;
5230
5231 if (!table)
5232 table = peer->bgp->rib[afi][safi];
5233
5234 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5235 for (ain = dest->adj_in; ain; ain = ain->next) {
5236 if (ain->peer != peer)
5237 continue;
5238
5239 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5240 safi, prd);
5241 }
5242 }
5243
5244 /* Do soft reconfig table per bgp table.
5245 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5246 * when BGP_NODE_SOFT_RECONFIG is set,
5247 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5248 * Schedule a new thread to continue the job.
5249 * Without splitting the full job into several part,
5250 * vtysh waits for the job to finish before responding to a BGP command
5251 */
5252 static void bgp_soft_reconfig_table_task(struct event *thread)
5253 {
5254 uint32_t iter, max_iter;
5255 struct bgp_dest *dest;
5256 struct bgp_adj_in *ain;
5257 struct peer *peer;
5258 struct bgp_table *table;
5259 struct prefix_rd *prd;
5260 struct listnode *node, *nnode;
5261
5262 table = EVENT_ARG(thread);
5263 prd = NULL;
5264
5265 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5266 if (table->soft_reconfig_init) {
5267 /* first call of the function with a new srta structure.
5268 * Don't do any treatment this time on nodes
5269 * in order vtysh to respond quickly
5270 */
5271 max_iter = 0;
5272 }
5273
5274 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5275 dest = bgp_route_next(dest)) {
5276 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5277 continue;
5278
5279 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5280
5281 for (ain = dest->adj_in; ain; ain = ain->next) {
5282 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5283 nnode, peer)) {
5284 if (ain->peer != peer)
5285 continue;
5286
5287 bgp_soft_reconfig_table_update(
5288 peer, dest, ain, table->afi,
5289 table->safi, prd);
5290 iter++;
5291 }
5292 }
5293 }
5294
5295 /* we're either starting the initial iteration,
5296 * or we're going to continue an ongoing iteration
5297 */
5298 if (dest || table->soft_reconfig_init) {
5299 table->soft_reconfig_init = false;
5300 event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
5301 0, &table->soft_reconfig_thread);
5302 return;
5303 }
5304 /* we're done, clean up the background iteration context info and
5305 schedule route annoucement
5306 */
5307 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5308 listnode_delete(table->soft_reconfig_peers, peer);
5309 bgp_announce_route(peer, table->afi, table->safi, false);
5310 }
5311
5312 list_delete(&table->soft_reconfig_peers);
5313 }
5314
5315
5316 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5317 * and peer.
5318 * - bgp cannot be NULL
5319 * - if table and peer are NULL, cancel all threads within the bgp instance
5320 * - if table is NULL and peer is not,
5321 * remove peer in all threads within the bgp instance
5322 * - if peer is NULL, cancel all threads matching table within the bgp instance
5323 */
5324 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5325 const struct bgp_table *table,
5326 const struct peer *peer)
5327 {
5328 struct peer *npeer;
5329 struct listnode *node, *nnode;
5330 int afi, safi;
5331 struct bgp_table *ntable;
5332
5333 if (!bgp)
5334 return;
5335
5336 FOREACH_AFI_SAFI (afi, safi) {
5337 ntable = bgp->rib[afi][safi];
5338 if (!ntable)
5339 continue;
5340 if (table && table != ntable)
5341 continue;
5342
5343 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5344 npeer)) {
5345 if (peer && peer != npeer)
5346 continue;
5347 listnode_delete(ntable->soft_reconfig_peers, npeer);
5348 }
5349
5350 if (!ntable->soft_reconfig_peers
5351 || !list_isempty(ntable->soft_reconfig_peers))
5352 continue;
5353
5354 list_delete(&ntable->soft_reconfig_peers);
5355 bgp_soft_reconfig_table_flag(ntable, false);
5356 EVENT_OFF(ntable->soft_reconfig_thread);
5357 }
5358 }
5359
5360 /*
5361 * Returns false if the peer is not configured for soft reconfig in
5362 */
5363 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5364 {
5365 struct bgp_dest *dest;
5366 struct bgp_table *table;
5367 struct listnode *node, *nnode;
5368 struct peer *npeer;
5369 struct peer_af *paf;
5370
5371 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5372 return false;
5373
5374 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5375 && (safi != SAFI_EVPN)) {
5376 table = peer->bgp->rib[afi][safi];
5377 if (!table)
5378 return true;
5379
5380 table->soft_reconfig_init = true;
5381
5382 if (!table->soft_reconfig_peers)
5383 table->soft_reconfig_peers = list_new();
5384 npeer = NULL;
5385 /* add peer to the table soft_reconfig_peers if not already
5386 * there
5387 */
5388 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5389 npeer)) {
5390 if (peer == npeer)
5391 break;
5392 }
5393 if (peer != npeer)
5394 listnode_add(table->soft_reconfig_peers, peer);
5395
5396 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5397 * on table would start back at the beginning.
5398 */
5399 bgp_soft_reconfig_table_flag(table, true);
5400
5401 if (!table->soft_reconfig_thread)
5402 event_add_event(bm->master,
5403 bgp_soft_reconfig_table_task, table, 0,
5404 &table->soft_reconfig_thread);
5405 /* Cancel bgp_announce_route_timer_expired threads.
5406 * bgp_announce_route_timer_expired threads have been scheduled
5407 * to announce routes as soon as the soft_reconfigure process
5408 * finishes.
5409 * In this case, soft_reconfigure is also scheduled by using
5410 * a thread but is planned after the
5411 * bgp_announce_route_timer_expired threads. It means that,
5412 * without cancelling the threads, the route announcement task
5413 * would run before the soft reconfiguration one. That would
5414 * useless and would block vtysh during several seconds. Route
5415 * announcements are rescheduled as soon as the soft_reconfigure
5416 * process finishes.
5417 */
5418 paf = peer_af_find(peer, afi, safi);
5419 if (paf)
5420 bgp_stop_announce_route_timer(paf);
5421 } else
5422 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5423 dest = bgp_route_next(dest)) {
5424 table = bgp_dest_get_bgp_table_info(dest);
5425
5426 if (table == NULL)
5427 continue;
5428
5429 const struct prefix *p = bgp_dest_get_prefix(dest);
5430 struct prefix_rd prd;
5431
5432 prd.family = AF_UNSPEC;
5433 prd.prefixlen = 64;
5434 memcpy(&prd.val, p->u.val, 8);
5435
5436 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5437 }
5438
5439 return true;
5440 }
5441
5442
5443 struct bgp_clear_node_queue {
5444 struct bgp_dest *dest;
5445 };
5446
5447 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5448 {
5449 struct bgp_clear_node_queue *cnq = data;
5450 struct bgp_dest *dest = cnq->dest;
5451 struct peer *peer = wq->spec.data;
5452 struct bgp_path_info *pi;
5453 struct bgp *bgp;
5454 afi_t afi = bgp_dest_table(dest)->afi;
5455 safi_t safi = bgp_dest_table(dest)->safi;
5456
5457 assert(dest && peer);
5458 bgp = peer->bgp;
5459
5460 /* It is possible that we have multiple paths for a prefix from a peer
5461 * if that peer is using AddPath.
5462 */
5463 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5464 if (pi->peer != peer)
5465 continue;
5466
5467 /* graceful restart STALE flag set. */
5468 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5469 && peer->nsf[afi][safi])
5470 || CHECK_FLAG(peer->af_sflags[afi][safi],
5471 PEER_STATUS_ENHANCED_REFRESH))
5472 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5473 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5474 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5475 else {
5476 /* If this is an EVPN route, process for
5477 * un-import. */
5478 if (safi == SAFI_EVPN)
5479 bgp_evpn_unimport_route(
5480 bgp, afi, safi,
5481 bgp_dest_get_prefix(dest), pi);
5482 /* Handle withdraw for VRF route-leaking and L3VPN */
5483 if (SAFI_UNICAST == safi
5484 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5485 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5486 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5487 bgp, pi);
5488 }
5489 if (SAFI_MPLS_VPN == safi &&
5490 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5491 vpn_leak_to_vrf_withdraw(pi);
5492 }
5493
5494 bgp_rib_remove(dest, pi, peer, afi, safi);
5495 }
5496 }
5497 return WQ_SUCCESS;
5498 }
5499
5500 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5501 {
5502 struct bgp_clear_node_queue *cnq = data;
5503 struct bgp_dest *dest = cnq->dest;
5504 struct bgp_table *table = bgp_dest_table(dest);
5505
5506 bgp_dest_unlock_node(dest);
5507 bgp_table_unlock(table);
5508 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5509 }
5510
5511 static void bgp_clear_node_complete(struct work_queue *wq)
5512 {
5513 struct peer *peer = wq->spec.data;
5514
5515 /* Tickle FSM to start moving again */
5516 BGP_EVENT_ADD(peer, Clearing_Completed);
5517
5518 peer_unlock(peer); /* bgp_clear_route */
5519 }
5520
5521 static void bgp_clear_node_queue_init(struct peer *peer)
5522 {
5523 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5524
5525 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5526 #undef CLEAR_QUEUE_NAME_LEN
5527
5528 peer->clear_node_queue = work_queue_new(bm->master, wname);
5529 peer->clear_node_queue->spec.hold = 10;
5530 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5531 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5532 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5533 peer->clear_node_queue->spec.max_retries = 0;
5534
5535 /* we only 'lock' this peer reference when the queue is actually active
5536 */
5537 peer->clear_node_queue->spec.data = peer;
5538 }
5539
5540 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5541 struct bgp_table *table)
5542 {
5543 struct bgp_dest *dest;
5544 int force = peer->bgp->process_queue ? 0 : 1;
5545
5546 if (!table)
5547 table = peer->bgp->rib[afi][safi];
5548
5549 /* If still no table => afi/safi isn't configured at all or smth. */
5550 if (!table)
5551 return;
5552
5553 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5554 struct bgp_path_info *pi, *next;
5555 struct bgp_adj_in *ain;
5556 struct bgp_adj_in *ain_next;
5557
5558 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5559 * queued for every clearing peer, regardless of whether it is
5560 * relevant to the peer at hand.
5561 *
5562 * Overview: There are 3 different indices which need to be
5563 * scrubbed, potentially, when a peer is removed:
5564 *
5565 * 1 peer's routes visible via the RIB (ie accepted routes)
5566 * 2 peer's routes visible by the (optional) peer's adj-in index
5567 * 3 other routes visible by the peer's adj-out index
5568 *
5569 * 3 there is no hurry in scrubbing, once the struct peer is
5570 * removed from bgp->peer, we could just GC such deleted peer's
5571 * adj-outs at our leisure.
5572 *
5573 * 1 and 2 must be 'scrubbed' in some way, at least made
5574 * invisible via RIB index before peer session is allowed to be
5575 * brought back up. So one needs to know when such a 'search' is
5576 * complete.
5577 *
5578 * Ideally:
5579 *
5580 * - there'd be a single global queue or a single RIB walker
5581 * - rather than tracking which route_nodes still need to be
5582 * examined on a peer basis, we'd track which peers still
5583 * aren't cleared
5584 *
5585 * Given that our per-peer prefix-counts now should be reliable,
5586 * this may actually be achievable. It doesn't seem to be a huge
5587 * problem at this time,
5588 *
5589 * It is possible that we have multiple paths for a prefix from
5590 * a peer
5591 * if that peer is using AddPath.
5592 */
5593 ain = dest->adj_in;
5594 while (ain) {
5595 ain_next = ain->next;
5596
5597 if (ain->peer == peer)
5598 bgp_adj_in_remove(dest, ain);
5599
5600 ain = ain_next;
5601 }
5602
5603 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5604 next = pi->next;
5605 if (pi->peer != peer)
5606 continue;
5607
5608 if (force)
5609 bgp_path_info_reap(dest, pi);
5610 else {
5611 struct bgp_clear_node_queue *cnq;
5612
5613 /* both unlocked in bgp_clear_node_queue_del */
5614 bgp_table_lock(bgp_dest_table(dest));
5615 bgp_dest_lock_node(dest);
5616 cnq = XCALLOC(
5617 MTYPE_BGP_CLEAR_NODE_QUEUE,
5618 sizeof(struct bgp_clear_node_queue));
5619 cnq->dest = dest;
5620 work_queue_add(peer->clear_node_queue, cnq);
5621 break;
5622 }
5623 }
5624 }
5625 return;
5626 }
5627
5628 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5629 {
5630 struct bgp_dest *dest;
5631 struct bgp_table *table;
5632
5633 if (peer->clear_node_queue == NULL)
5634 bgp_clear_node_queue_init(peer);
5635
5636 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5637 * Idle until it receives a Clearing_Completed event. This protects
5638 * against peers which flap faster than we can we clear, which could
5639 * lead to:
5640 *
5641 * a) race with routes from the new session being installed before
5642 * clear_route_node visits the node (to delete the route of that
5643 * peer)
5644 * b) resource exhaustion, clear_route_node likely leads to an entry
5645 * on the process_main queue. Fast-flapping could cause that queue
5646 * to grow and grow.
5647 */
5648
5649 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5650 * the unlock will happen upon work-queue completion; other wise, the
5651 * unlock happens at the end of this function.
5652 */
5653 if (!peer->clear_node_queue->thread)
5654 peer_lock(peer);
5655
5656 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5657 bgp_clear_route_table(peer, afi, safi, NULL);
5658 else
5659 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5660 dest = bgp_route_next(dest)) {
5661 table = bgp_dest_get_bgp_table_info(dest);
5662 if (!table)
5663 continue;
5664
5665 bgp_clear_route_table(peer, afi, safi, table);
5666 }
5667
5668 /* unlock if no nodes got added to the clear-node-queue. */
5669 if (!peer->clear_node_queue->thread)
5670 peer_unlock(peer);
5671 }
5672
5673 void bgp_clear_route_all(struct peer *peer)
5674 {
5675 afi_t afi;
5676 safi_t safi;
5677
5678 FOREACH_AFI_SAFI (afi, safi)
5679 bgp_clear_route(peer, afi, safi);
5680
5681 #ifdef ENABLE_BGP_VNC
5682 rfapiProcessPeerDown(peer);
5683 #endif
5684 }
5685
5686 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5687 {
5688 struct bgp_table *table;
5689 struct bgp_dest *dest;
5690 struct bgp_adj_in *ain;
5691 struct bgp_adj_in *ain_next;
5692
5693 table = peer->bgp->rib[afi][safi];
5694
5695 /* It is possible that we have multiple paths for a prefix from a peer
5696 * if that peer is using AddPath.
5697 */
5698 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5699 ain = dest->adj_in;
5700
5701 while (ain) {
5702 ain_next = ain->next;
5703
5704 if (ain->peer == peer)
5705 bgp_adj_in_remove(dest, ain);
5706
5707 ain = ain_next;
5708 }
5709 }
5710 }
5711
5712 /* If any of the routes from the peer have been marked with the NO_LLGR
5713 * community, either as sent by the peer, or as the result of a configured
5714 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5715 * operation of [RFC4271].
5716 */
5717 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5718 {
5719 struct bgp_dest *dest;
5720 struct bgp_path_info *pi;
5721 struct bgp_table *table;
5722
5723 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5724 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5725 dest = bgp_route_next(dest)) {
5726 struct bgp_dest *rm;
5727
5728 /* look for neighbor in tables */
5729 table = bgp_dest_get_bgp_table_info(dest);
5730 if (!table)
5731 continue;
5732
5733 for (rm = bgp_table_top(table); rm;
5734 rm = bgp_route_next(rm))
5735 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5736 pi = pi->next) {
5737 if (pi->peer != peer)
5738 continue;
5739 if (CHECK_FLAG(
5740 peer->af_sflags[afi][safi],
5741 PEER_STATUS_LLGR_WAIT) &&
5742 bgp_attr_get_community(pi->attr) &&
5743 !community_include(
5744 bgp_attr_get_community(
5745 pi->attr),
5746 COMMUNITY_NO_LLGR))
5747 continue;
5748 if (!CHECK_FLAG(pi->flags,
5749 BGP_PATH_STALE))
5750 continue;
5751
5752 /*
5753 * If this is VRF leaked route
5754 * process for withdraw.
5755 */
5756 if (pi->sub_type ==
5757 BGP_ROUTE_IMPORTED &&
5758 peer->bgp->inst_type ==
5759 BGP_INSTANCE_TYPE_DEFAULT)
5760 vpn_leak_to_vrf_withdraw(pi);
5761
5762 bgp_rib_remove(rm, pi, peer, afi, safi);
5763 break;
5764 }
5765 }
5766 } else {
5767 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5768 dest = bgp_route_next(dest))
5769 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5770 pi = pi->next) {
5771 if (pi->peer != peer)
5772 continue;
5773 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5774 PEER_STATUS_LLGR_WAIT) &&
5775 bgp_attr_get_community(pi->attr) &&
5776 !community_include(
5777 bgp_attr_get_community(pi->attr),
5778 COMMUNITY_NO_LLGR))
5779 continue;
5780 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5781 continue;
5782 if (safi == SAFI_UNICAST &&
5783 (peer->bgp->inst_type ==
5784 BGP_INSTANCE_TYPE_VRF ||
5785 peer->bgp->inst_type ==
5786 BGP_INSTANCE_TYPE_DEFAULT))
5787 vpn_leak_from_vrf_withdraw(
5788 bgp_get_default(), peer->bgp,
5789 pi);
5790
5791 bgp_rib_remove(dest, pi, peer, afi, safi);
5792 break;
5793 }
5794 }
5795 }
5796
5797 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5798 {
5799 struct bgp_dest *dest, *ndest;
5800 struct bgp_path_info *pi;
5801 struct bgp_table *table;
5802
5803 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5804 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5805 dest = bgp_route_next(dest)) {
5806 table = bgp_dest_get_bgp_table_info(dest);
5807 if (!table)
5808 continue;
5809
5810 for (ndest = bgp_table_top(table); ndest;
5811 ndest = bgp_route_next(ndest)) {
5812 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5813 pi = pi->next) {
5814 if (pi->peer != peer)
5815 continue;
5816
5817 if ((CHECK_FLAG(
5818 peer->af_sflags[afi][safi],
5819 PEER_STATUS_ENHANCED_REFRESH))
5820 && !CHECK_FLAG(pi->flags,
5821 BGP_PATH_STALE)
5822 && !CHECK_FLAG(
5823 pi->flags,
5824 BGP_PATH_UNUSEABLE)) {
5825 if (bgp_debug_neighbor_events(
5826 peer))
5827 zlog_debug(
5828 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5829 peer,
5830 afi2str(afi),
5831 safi2str(safi),
5832 bgp_dest_get_prefix(
5833 ndest));
5834
5835 bgp_path_info_set_flag(
5836 ndest, pi,
5837 BGP_PATH_STALE);
5838 }
5839 }
5840 }
5841 }
5842 } else {
5843 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5844 dest = bgp_route_next(dest)) {
5845 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5846 pi = pi->next) {
5847 if (pi->peer != peer)
5848 continue;
5849
5850 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5851 PEER_STATUS_ENHANCED_REFRESH))
5852 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5853 && !CHECK_FLAG(pi->flags,
5854 BGP_PATH_UNUSEABLE)) {
5855 if (bgp_debug_neighbor_events(peer))
5856 zlog_debug(
5857 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5858 peer, afi2str(afi),
5859 safi2str(safi),
5860 bgp_dest_get_prefix(
5861 dest));
5862
5863 bgp_path_info_set_flag(dest, pi,
5864 BGP_PATH_STALE);
5865 }
5866 }
5867 }
5868 }
5869 }
5870
5871 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5872 {
5873 if (peer->sort == BGP_PEER_IBGP)
5874 return true;
5875
5876 if (peer->sort == BGP_PEER_EBGP
5877 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5878 || FILTER_LIST_OUT_NAME(filter)
5879 || DISTRIBUTE_OUT_NAME(filter)))
5880 return true;
5881 return false;
5882 }
5883
5884 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5885 {
5886 if (peer->sort == BGP_PEER_IBGP)
5887 return true;
5888
5889 if (peer->sort == BGP_PEER_EBGP
5890 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5891 || FILTER_LIST_IN_NAME(filter)
5892 || DISTRIBUTE_IN_NAME(filter)))
5893 return true;
5894 return false;
5895 }
5896
5897 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5898 safi_t safi)
5899 {
5900 struct bgp_dest *dest;
5901 struct bgp_path_info *pi;
5902 struct bgp_path_info *next;
5903
5904 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5905 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5906 const struct prefix *p = bgp_dest_get_prefix(dest);
5907
5908 next = pi->next;
5909
5910 /* Unimport EVPN routes from VRFs */
5911 if (safi == SAFI_EVPN)
5912 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5913 SAFI_EVPN, p, pi);
5914
5915 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5916 && pi->type == ZEBRA_ROUTE_BGP
5917 && (pi->sub_type == BGP_ROUTE_NORMAL
5918 || pi->sub_type == BGP_ROUTE_AGGREGATE
5919 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5920
5921 if (bgp_fibupd_safi(safi))
5922 bgp_zebra_withdraw(p, pi, bgp, safi);
5923 }
5924
5925 bgp_path_info_reap(dest, pi);
5926 }
5927 }
5928
5929 /* Delete all kernel routes. */
5930 void bgp_cleanup_routes(struct bgp *bgp)
5931 {
5932 afi_t afi;
5933 struct bgp_dest *dest;
5934 struct bgp_table *table;
5935
5936 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5937 if (afi == AFI_L2VPN)
5938 continue;
5939 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5940 SAFI_UNICAST);
5941 /*
5942 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5943 */
5944 if (afi != AFI_L2VPN) {
5945 safi_t safi;
5946 safi = SAFI_MPLS_VPN;
5947 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5948 dest = bgp_route_next(dest)) {
5949 table = bgp_dest_get_bgp_table_info(dest);
5950 if (table != NULL) {
5951 bgp_cleanup_table(bgp, table, safi);
5952 bgp_table_finish(&table);
5953 bgp_dest_set_bgp_table_info(dest, NULL);
5954 bgp_dest_unlock_node(dest);
5955 }
5956 }
5957 safi = SAFI_ENCAP;
5958 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5959 dest = bgp_route_next(dest)) {
5960 table = bgp_dest_get_bgp_table_info(dest);
5961 if (table != NULL) {
5962 bgp_cleanup_table(bgp, table, safi);
5963 bgp_table_finish(&table);
5964 bgp_dest_set_bgp_table_info(dest, NULL);
5965 bgp_dest_unlock_node(dest);
5966 }
5967 }
5968 }
5969 }
5970 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5971 dest = bgp_route_next(dest)) {
5972 table = bgp_dest_get_bgp_table_info(dest);
5973 if (table != NULL) {
5974 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5975 bgp_table_finish(&table);
5976 bgp_dest_set_bgp_table_info(dest, NULL);
5977 bgp_dest_unlock_node(dest);
5978 }
5979 }
5980 }
5981
5982 void bgp_reset(void)
5983 {
5984 vty_reset();
5985 bgp_zclient_reset();
5986 access_list_reset();
5987 prefix_list_reset();
5988 }
5989
5990 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5991 {
5992 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5993 && CHECK_FLAG(peer->af_cap[afi][safi],
5994 PEER_CAP_ADDPATH_AF_TX_RCV));
5995 }
5996
5997 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5998 value. */
5999 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
6000 struct bgp_nlri *packet)
6001 {
6002 uint8_t *pnt;
6003 uint8_t *lim;
6004 struct prefix p;
6005 int psize;
6006 afi_t afi;
6007 safi_t safi;
6008 bool addpath_capable;
6009 uint32_t addpath_id;
6010
6011 pnt = packet->nlri;
6012 lim = pnt + packet->length;
6013 afi = packet->afi;
6014 safi = packet->safi;
6015 addpath_id = 0;
6016 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
6017
6018 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
6019 syntactic validity. If the field is syntactically incorrect,
6020 then the Error Subcode is set to Invalid Network Field. */
6021 for (; pnt < lim; pnt += psize) {
6022 /* Clear prefix structure. */
6023 memset(&p, 0, sizeof(p));
6024
6025 if (addpath_capable) {
6026
6027 /* When packet overflow occurs return immediately. */
6028 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
6029 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6030
6031 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
6032 addpath_id = ntohl(addpath_id);
6033 pnt += BGP_ADDPATH_ID_LEN;
6034 }
6035
6036 /* Fetch prefix length. */
6037 p.prefixlen = *pnt++;
6038 /* afi/safi validity already verified by caller,
6039 * bgp_update_receive */
6040 p.family = afi2family(afi);
6041
6042 /* Prefix length check. */
6043 if (p.prefixlen > prefix_blen(&p) * 8) {
6044 flog_err(
6045 EC_BGP_UPDATE_RCV,
6046 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6047 peer->host, p.prefixlen, packet->afi);
6048 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6049 }
6050
6051 /* Packet size overflow check. */
6052 psize = PSIZE(p.prefixlen);
6053
6054 /* When packet overflow occur return immediately. */
6055 if (pnt + psize > lim) {
6056 flog_err(
6057 EC_BGP_UPDATE_RCV,
6058 "%s [Error] Update packet error (prefix length %d overflows packet)",
6059 peer->host, p.prefixlen);
6060 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6061 }
6062
6063 /* Defensive coding, double-check the psize fits in a struct
6064 * prefix for the v4 and v6 afi's and unicast/multicast */
6065 if (psize > (ssize_t)sizeof(p.u.val)) {
6066 flog_err(
6067 EC_BGP_UPDATE_RCV,
6068 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6069 peer->host, p.prefixlen, sizeof(p.u.val));
6070 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6071 }
6072
6073 /* Fetch prefix from NLRI packet. */
6074 memcpy(p.u.val, pnt, psize);
6075
6076 /* Check address. */
6077 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6078 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6079 /* From RFC4271 Section 6.3:
6080 *
6081 * If a prefix in the NLRI field is semantically
6082 * incorrect
6083 * (e.g., an unexpected multicast IP address),
6084 * an error SHOULD
6085 * be logged locally, and the prefix SHOULD be
6086 * ignored.
6087 */
6088 flog_err(
6089 EC_BGP_UPDATE_RCV,
6090 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6091 peer->host, &p.u.prefix4);
6092 continue;
6093 }
6094 }
6095
6096 /* Check address. */
6097 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6098 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6099 flog_err(
6100 EC_BGP_UPDATE_RCV,
6101 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6102 peer->host, &p.u.prefix6);
6103
6104 continue;
6105 }
6106 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6107 flog_err(
6108 EC_BGP_UPDATE_RCV,
6109 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6110 peer->host, &p.u.prefix6);
6111
6112 continue;
6113 }
6114 }
6115
6116 /* Normal process. */
6117 if (attr)
6118 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6119 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6120 NULL, 0, 0, NULL);
6121 else
6122 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6123 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6124 NULL, 0, NULL);
6125
6126 /* Do not send BGP notification twice when maximum-prefix count
6127 * overflow. */
6128 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6129 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6130 }
6131
6132 /* Packet length consistency check. */
6133 if (pnt != lim) {
6134 flog_err(
6135 EC_BGP_UPDATE_RCV,
6136 "%s [Error] Update packet error (prefix length mismatch with total length)",
6137 peer->host);
6138 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6139 }
6140
6141 return BGP_NLRI_PARSE_OK;
6142 }
6143
6144 static struct bgp_static *bgp_static_new(void)
6145 {
6146 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6147 }
6148
6149 static void bgp_static_free(struct bgp_static *bgp_static)
6150 {
6151 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6152 route_map_counter_decrement(bgp_static->rmap.map);
6153
6154 if (bgp_static->prd_pretty)
6155 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6156 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6157 XFREE(MTYPE_BGP_STATIC, bgp_static);
6158 }
6159
6160 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6161 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6162 {
6163 struct bgp_dest *dest;
6164 struct bgp_path_info *pi;
6165 struct bgp_path_info *new;
6166 struct bgp_path_info rmap_path;
6167 struct attr attr;
6168 struct attr *attr_new;
6169 route_map_result_t ret;
6170 #ifdef ENABLE_BGP_VNC
6171 int vnc_implicit_withdraw = 0;
6172 #endif
6173
6174 assert(bgp_static);
6175
6176 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6177
6178 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6179
6180 attr.nexthop = bgp_static->igpnexthop;
6181 attr.med = bgp_static->igpmetric;
6182 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6183
6184 if (afi == AFI_IP)
6185 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6186
6187 if (bgp_static->igpmetric)
6188 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6189
6190 if (bgp_static->atomic)
6191 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6192
6193 /* Store label index, if required. */
6194 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6195 attr.label_index = bgp_static->label_index;
6196 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6197 }
6198
6199 /* Apply route-map. */
6200 if (bgp_static->rmap.name) {
6201 struct attr attr_tmp = attr;
6202
6203 memset(&rmap_path, 0, sizeof(rmap_path));
6204 rmap_path.peer = bgp->peer_self;
6205 rmap_path.attr = &attr_tmp;
6206
6207 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6208
6209 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6210
6211 bgp->peer_self->rmap_type = 0;
6212
6213 if (ret == RMAP_DENYMATCH) {
6214 /* Free uninterned attribute. */
6215 bgp_attr_flush(&attr_tmp);
6216
6217 /* Unintern original. */
6218 aspath_unintern(&attr.aspath);
6219 bgp_static_withdraw(bgp, p, afi, safi);
6220 bgp_dest_unlock_node(dest);
6221 return;
6222 }
6223
6224 if (bgp_in_graceful_shutdown(bgp))
6225 bgp_attr_add_gshut_community(&attr_tmp);
6226
6227 attr_new = bgp_attr_intern(&attr_tmp);
6228 } else {
6229
6230 if (bgp_in_graceful_shutdown(bgp))
6231 bgp_attr_add_gshut_community(&attr);
6232
6233 attr_new = bgp_attr_intern(&attr);
6234 }
6235
6236 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6237 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6238 && pi->sub_type == BGP_ROUTE_STATIC)
6239 break;
6240
6241 if (pi) {
6242 if (attrhash_cmp(pi->attr, attr_new)
6243 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6244 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6245 bgp_dest_unlock_node(dest);
6246 bgp_attr_unintern(&attr_new);
6247 aspath_unintern(&attr.aspath);
6248 return;
6249 } else {
6250 /* The attribute is changed. */
6251 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6252
6253 /* Rewrite BGP route information. */
6254 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6255 bgp_path_info_restore(dest, pi);
6256 else
6257 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6258 #ifdef ENABLE_BGP_VNC
6259 if ((afi == AFI_IP || afi == AFI_IP6)
6260 && (safi == SAFI_UNICAST)) {
6261 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6262 /*
6263 * Implicit withdraw case.
6264 * We have to do this before pi is
6265 * changed
6266 */
6267 ++vnc_implicit_withdraw;
6268 vnc_import_bgp_del_route(bgp, p, pi);
6269 vnc_import_bgp_exterior_del_route(
6270 bgp, p, pi);
6271 }
6272 }
6273 #endif
6274 bgp_attr_unintern(&pi->attr);
6275 pi->attr = attr_new;
6276 pi->uptime = monotime(NULL);
6277 #ifdef ENABLE_BGP_VNC
6278 if ((afi == AFI_IP || afi == AFI_IP6)
6279 && (safi == SAFI_UNICAST)) {
6280 if (vnc_implicit_withdraw) {
6281 vnc_import_bgp_add_route(bgp, p, pi);
6282 vnc_import_bgp_exterior_add_route(
6283 bgp, p, pi);
6284 }
6285 }
6286 #endif
6287
6288 /* Nexthop reachability check. */
6289 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6290 && (safi == SAFI_UNICAST
6291 || safi == SAFI_LABELED_UNICAST)) {
6292
6293 struct bgp *bgp_nexthop = bgp;
6294
6295 if (pi->extra && pi->extra->bgp_orig)
6296 bgp_nexthop = pi->extra->bgp_orig;
6297
6298 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6299 afi, safi, pi, NULL,
6300 0, p))
6301 bgp_path_info_set_flag(dest, pi,
6302 BGP_PATH_VALID);
6303 else {
6304 if (BGP_DEBUG(nht, NHT)) {
6305 char buf1[INET6_ADDRSTRLEN];
6306 inet_ntop(p->family,
6307 &p->u.prefix, buf1,
6308 sizeof(buf1));
6309 zlog_debug(
6310 "%s(%s): Route not in table, not advertising",
6311 __func__, buf1);
6312 }
6313 bgp_path_info_unset_flag(
6314 dest, pi, BGP_PATH_VALID);
6315 }
6316 } else {
6317 /* Delete the NHT structure if any, if we're
6318 * toggling between
6319 * enabling/disabling import check. We
6320 * deregister the route
6321 * from NHT to avoid overloading NHT and the
6322 * process interaction
6323 */
6324 bgp_unlink_nexthop(pi);
6325 bgp_path_info_set_flag(dest, pi,
6326 BGP_PATH_VALID);
6327 }
6328 /* Process change. */
6329 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6330 bgp_process(bgp, dest, afi, safi);
6331
6332 if (SAFI_UNICAST == safi
6333 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6334 || bgp->inst_type
6335 == BGP_INSTANCE_TYPE_DEFAULT)) {
6336 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6337 pi);
6338 }
6339
6340 bgp_dest_unlock_node(dest);
6341 aspath_unintern(&attr.aspath);
6342 return;
6343 }
6344 }
6345
6346 /* Make new BGP info. */
6347 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6348 attr_new, dest);
6349 /* Nexthop reachability check. */
6350 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6351 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6352 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6353 p))
6354 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6355 else {
6356 if (BGP_DEBUG(nht, NHT)) {
6357 char buf1[INET6_ADDRSTRLEN];
6358
6359 inet_ntop(p->family, &p->u.prefix, buf1,
6360 sizeof(buf1));
6361 zlog_debug(
6362 "%s(%s): Route not in table, not advertising",
6363 __func__, buf1);
6364 }
6365 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6366 }
6367 } else {
6368 /* Delete the NHT structure if any, if we're toggling between
6369 * enabling/disabling import check. We deregister the route
6370 * from NHT to avoid overloading NHT and the process interaction
6371 */
6372 bgp_unlink_nexthop(new);
6373
6374 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6375 }
6376
6377 /* Aggregate address increment. */
6378 bgp_aggregate_increment(bgp, p, new, afi, safi);
6379
6380 /* Register new BGP information. */
6381 bgp_path_info_add(dest, new);
6382
6383 /* route_node_get lock */
6384 bgp_dest_unlock_node(dest);
6385
6386 /* Process change. */
6387 bgp_process(bgp, dest, afi, safi);
6388
6389 if (SAFI_UNICAST == safi
6390 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6391 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6392 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6393 }
6394
6395 /* Unintern original. */
6396 aspath_unintern(&attr.aspath);
6397 }
6398
6399 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6400 safi_t safi)
6401 {
6402 struct bgp_dest *dest;
6403 struct bgp_path_info *pi;
6404
6405 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6406
6407 /* Check selected route and self inserted route. */
6408 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6409 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6410 && pi->sub_type == BGP_ROUTE_STATIC)
6411 break;
6412
6413 /* Withdraw static BGP route from routing table. */
6414 if (pi) {
6415 if (SAFI_UNICAST == safi
6416 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6417 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6418 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6419 }
6420 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6421 bgp_unlink_nexthop(pi);
6422 bgp_path_info_delete(dest, pi);
6423 bgp_process(bgp, dest, afi, safi);
6424 }
6425
6426 /* Unlock bgp_node_lookup. */
6427 bgp_dest_unlock_node(dest);
6428 }
6429
6430 /*
6431 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6432 */
6433 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6434 afi_t afi, safi_t safi,
6435 struct prefix_rd *prd)
6436 {
6437 struct bgp_dest *dest;
6438 struct bgp_path_info *pi;
6439
6440 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6441
6442 /* Check selected route and self inserted route. */
6443 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6444 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6445 && pi->sub_type == BGP_ROUTE_STATIC)
6446 break;
6447
6448 /* Withdraw static BGP route from routing table. */
6449 if (pi) {
6450 #ifdef ENABLE_BGP_VNC
6451 rfapiProcessWithdraw(
6452 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6453 1); /* Kill, since it is an administrative change */
6454 #endif
6455 if (SAFI_MPLS_VPN == safi
6456 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6457 vpn_leak_to_vrf_withdraw(pi);
6458 }
6459 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6460 bgp_path_info_delete(dest, pi);
6461 bgp_process(bgp, dest, afi, safi);
6462 }
6463
6464 /* Unlock bgp_node_lookup. */
6465 bgp_dest_unlock_node(dest);
6466 }
6467
6468 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6469 struct bgp_static *bgp_static, afi_t afi,
6470 safi_t safi)
6471 {
6472 struct bgp_dest *dest;
6473 struct bgp_path_info *new;
6474 struct attr *attr_new;
6475 struct attr attr = {0};
6476 struct bgp_path_info *pi;
6477 #ifdef ENABLE_BGP_VNC
6478 mpls_label_t label = 0;
6479 #endif
6480 uint32_t num_labels = 0;
6481
6482 assert(bgp_static);
6483
6484 if (bgp_static->label != MPLS_INVALID_LABEL)
6485 num_labels = 1;
6486 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6487 &bgp_static->prd);
6488
6489 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6490
6491 attr.nexthop = bgp_static->igpnexthop;
6492 attr.med = bgp_static->igpmetric;
6493 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6494
6495 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6496 || (safi == SAFI_ENCAP)) {
6497 if (afi == AFI_IP) {
6498 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6499 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6500 }
6501 }
6502 if (afi == AFI_L2VPN) {
6503 if (bgp_static->gatewayIp.family == AF_INET) {
6504 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6505 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6506 &bgp_static->gatewayIp.u.prefix4,
6507 IPV4_MAX_BYTELEN);
6508 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6509 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6510 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6511 &bgp_static->gatewayIp.u.prefix6,
6512 IPV6_MAX_BYTELEN);
6513 }
6514 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6515 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6516 struct bgp_encap_type_vxlan bet;
6517 memset(&bet, 0, sizeof(bet));
6518 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6519 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6520 }
6521 if (bgp_static->router_mac) {
6522 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6523 }
6524 }
6525 /* Apply route-map. */
6526 if (bgp_static->rmap.name) {
6527 struct attr attr_tmp = attr;
6528 struct bgp_path_info rmap_path;
6529 route_map_result_t ret;
6530
6531 rmap_path.peer = bgp->peer_self;
6532 rmap_path.attr = &attr_tmp;
6533
6534 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6535
6536 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6537
6538 bgp->peer_self->rmap_type = 0;
6539
6540 if (ret == RMAP_DENYMATCH) {
6541 /* Free uninterned attribute. */
6542 bgp_attr_flush(&attr_tmp);
6543
6544 /* Unintern original. */
6545 aspath_unintern(&attr.aspath);
6546 bgp_static_withdraw_safi(bgp, p, afi, safi,
6547 &bgp_static->prd);
6548 bgp_dest_unlock_node(dest);
6549 return;
6550 }
6551
6552 attr_new = bgp_attr_intern(&attr_tmp);
6553 } else {
6554 attr_new = bgp_attr_intern(&attr);
6555 }
6556
6557 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6558 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6559 && pi->sub_type == BGP_ROUTE_STATIC)
6560 break;
6561
6562 if (pi) {
6563 if (attrhash_cmp(pi->attr, attr_new)
6564 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6565 bgp_dest_unlock_node(dest);
6566 bgp_attr_unintern(&attr_new);
6567 aspath_unintern(&attr.aspath);
6568 return;
6569 } else {
6570 /* The attribute is changed. */
6571 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6572
6573 /* Rewrite BGP route information. */
6574 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6575 bgp_path_info_restore(dest, pi);
6576 else
6577 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6578 bgp_attr_unintern(&pi->attr);
6579 pi->attr = attr_new;
6580 pi->uptime = monotime(NULL);
6581 #ifdef ENABLE_BGP_VNC
6582 if (pi->extra)
6583 label = decode_label(&pi->extra->label[0]);
6584 #endif
6585
6586 /* Process change. */
6587 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6588 bgp_process(bgp, dest, afi, safi);
6589
6590 if (SAFI_MPLS_VPN == safi
6591 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6592 vpn_leak_to_vrf_update(bgp, pi,
6593 &bgp_static->prd);
6594 }
6595 #ifdef ENABLE_BGP_VNC
6596 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6597 pi->attr, afi, safi, pi->type,
6598 pi->sub_type, &label);
6599 #endif
6600 bgp_dest_unlock_node(dest);
6601 aspath_unintern(&attr.aspath);
6602 return;
6603 }
6604 }
6605
6606
6607 /* Make new BGP info. */
6608 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6609 attr_new, dest);
6610 SET_FLAG(new->flags, BGP_PATH_VALID);
6611 bgp_path_info_extra_get(new);
6612 if (num_labels) {
6613 new->extra->label[0] = bgp_static->label;
6614 new->extra->num_labels = num_labels;
6615 }
6616 #ifdef ENABLE_BGP_VNC
6617 label = decode_label(&bgp_static->label);
6618 #endif
6619
6620 /* Aggregate address increment. */
6621 bgp_aggregate_increment(bgp, p, new, afi, safi);
6622
6623 /* Register new BGP information. */
6624 bgp_path_info_add(dest, new);
6625 /* route_node_get lock */
6626 bgp_dest_unlock_node(dest);
6627
6628 /* Process change. */
6629 bgp_process(bgp, dest, afi, safi);
6630
6631 if (SAFI_MPLS_VPN == safi
6632 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6633 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6634 }
6635 #ifdef ENABLE_BGP_VNC
6636 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6637 safi, new->type, new->sub_type, &label);
6638 #endif
6639
6640 /* Unintern original. */
6641 aspath_unintern(&attr.aspath);
6642 }
6643
6644 /* Configure static BGP network. When user don't run zebra, static
6645 route should be installed as valid. */
6646 static int bgp_static_set(struct vty *vty, const char *negate,
6647 const char *ip_str, afi_t afi, safi_t safi,
6648 const char *rmap, int backdoor, uint32_t label_index)
6649 {
6650 VTY_DECLVAR_CONTEXT(bgp, bgp);
6651 int ret;
6652 struct prefix p;
6653 struct bgp_static *bgp_static;
6654 struct bgp_dest *dest;
6655 uint8_t need_update = 0;
6656
6657 /* Convert IP prefix string to struct prefix. */
6658 ret = str2prefix(ip_str, &p);
6659 if (!ret) {
6660 vty_out(vty, "%% Malformed prefix\n");
6661 return CMD_WARNING_CONFIG_FAILED;
6662 }
6663 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6664 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6665 return CMD_WARNING_CONFIG_FAILED;
6666 }
6667
6668 apply_mask(&p);
6669
6670 if (negate) {
6671
6672 /* Set BGP static route configuration. */
6673 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6674
6675 if (!dest) {
6676 vty_out(vty, "%% Can't find static route specified\n");
6677 return CMD_WARNING_CONFIG_FAILED;
6678 }
6679
6680 bgp_static = bgp_dest_get_bgp_static_info(dest);
6681
6682 if ((label_index != BGP_INVALID_LABEL_INDEX)
6683 && (label_index != bgp_static->label_index)) {
6684 vty_out(vty,
6685 "%% label-index doesn't match static route\n");
6686 bgp_dest_unlock_node(dest);
6687 return CMD_WARNING_CONFIG_FAILED;
6688 }
6689
6690 if ((rmap && bgp_static->rmap.name)
6691 && strcmp(rmap, bgp_static->rmap.name)) {
6692 vty_out(vty,
6693 "%% route-map name doesn't match static route\n");
6694 bgp_dest_unlock_node(dest);
6695 return CMD_WARNING_CONFIG_FAILED;
6696 }
6697
6698 /* Update BGP RIB. */
6699 if (!bgp_static->backdoor)
6700 bgp_static_withdraw(bgp, &p, afi, safi);
6701
6702 /* Clear configuration. */
6703 bgp_static_free(bgp_static);
6704 bgp_dest_set_bgp_static_info(dest, NULL);
6705 bgp_dest_unlock_node(dest);
6706 bgp_dest_unlock_node(dest);
6707 } else {
6708
6709 /* Set BGP static route configuration. */
6710 dest = bgp_node_get(bgp->route[afi][safi], &p);
6711 bgp_static = bgp_dest_get_bgp_static_info(dest);
6712 if (bgp_static) {
6713 /* Configuration change. */
6714 /* Label index cannot be changed. */
6715 if (bgp_static->label_index != label_index) {
6716 vty_out(vty, "%% cannot change label-index\n");
6717 bgp_dest_unlock_node(dest);
6718 return CMD_WARNING_CONFIG_FAILED;
6719 }
6720
6721 /* Check previous routes are installed into BGP. */
6722 if (bgp_static->valid
6723 && bgp_static->backdoor != backdoor)
6724 need_update = 1;
6725
6726 bgp_static->backdoor = backdoor;
6727
6728 if (rmap) {
6729 XFREE(MTYPE_ROUTE_MAP_NAME,
6730 bgp_static->rmap.name);
6731 route_map_counter_decrement(
6732 bgp_static->rmap.map);
6733 bgp_static->rmap.name =
6734 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6735 bgp_static->rmap.map =
6736 route_map_lookup_by_name(rmap);
6737 route_map_counter_increment(
6738 bgp_static->rmap.map);
6739 } else {
6740 XFREE(MTYPE_ROUTE_MAP_NAME,
6741 bgp_static->rmap.name);
6742 route_map_counter_decrement(
6743 bgp_static->rmap.map);
6744 bgp_static->rmap.map = NULL;
6745 bgp_static->valid = 0;
6746 }
6747 bgp_dest_unlock_node(dest);
6748 } else {
6749 /* New configuration. */
6750 bgp_static = bgp_static_new();
6751 bgp_static->backdoor = backdoor;
6752 bgp_static->valid = 0;
6753 bgp_static->igpmetric = 0;
6754 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6755 bgp_static->label_index = label_index;
6756
6757 if (rmap) {
6758 XFREE(MTYPE_ROUTE_MAP_NAME,
6759 bgp_static->rmap.name);
6760 route_map_counter_decrement(
6761 bgp_static->rmap.map);
6762 bgp_static->rmap.name =
6763 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6764 bgp_static->rmap.map =
6765 route_map_lookup_by_name(rmap);
6766 route_map_counter_increment(
6767 bgp_static->rmap.map);
6768 }
6769 bgp_dest_set_bgp_static_info(dest, bgp_static);
6770 }
6771
6772 bgp_static->valid = 1;
6773 if (need_update)
6774 bgp_static_withdraw(bgp, &p, afi, safi);
6775
6776 if (!bgp_static->backdoor)
6777 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6778 }
6779
6780 return CMD_SUCCESS;
6781 }
6782
6783 void bgp_static_add(struct bgp *bgp)
6784 {
6785 afi_t afi;
6786 safi_t safi;
6787 struct bgp_dest *dest;
6788 struct bgp_dest *rm;
6789 struct bgp_table *table;
6790 struct bgp_static *bgp_static;
6791
6792 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6793 FOREACH_AFI_SAFI (afi, safi)
6794 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6795 dest = bgp_route_next(dest)) {
6796 if (!bgp_dest_has_bgp_path_info_data(dest))
6797 continue;
6798
6799 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6800 || (safi == SAFI_EVPN)) {
6801 table = bgp_dest_get_bgp_table_info(dest);
6802
6803 for (rm = bgp_table_top(table); rm;
6804 rm = bgp_route_next(rm)) {
6805 bgp_static =
6806 bgp_dest_get_bgp_static_info(
6807 rm);
6808 bgp_static_update_safi(
6809 bgp, bgp_dest_get_prefix(rm),
6810 bgp_static, afi, safi);
6811 }
6812 } else {
6813 bgp_static_update(
6814 bgp, bgp_dest_get_prefix(dest),
6815 bgp_dest_get_bgp_static_info(dest), afi,
6816 safi);
6817 }
6818 }
6819 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6820 }
6821
6822 /* Called from bgp_delete(). Delete all static routes from the BGP
6823 instance. */
6824 void bgp_static_delete(struct bgp *bgp)
6825 {
6826 afi_t afi;
6827 safi_t safi;
6828 struct bgp_dest *dest;
6829 struct bgp_dest *rm;
6830 struct bgp_table *table;
6831 struct bgp_static *bgp_static;
6832
6833 FOREACH_AFI_SAFI (afi, safi)
6834 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6835 dest = bgp_route_next(dest)) {
6836 if (!bgp_dest_has_bgp_path_info_data(dest))
6837 continue;
6838
6839 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6840 || (safi == SAFI_EVPN)) {
6841 table = bgp_dest_get_bgp_table_info(dest);
6842
6843 for (rm = bgp_table_top(table); rm;
6844 rm = bgp_route_next(rm)) {
6845 bgp_static =
6846 bgp_dest_get_bgp_static_info(
6847 rm);
6848 if (!bgp_static)
6849 continue;
6850
6851 bgp_static_withdraw_safi(
6852 bgp, bgp_dest_get_prefix(rm),
6853 AFI_IP, safi,
6854 (struct prefix_rd *)
6855 bgp_dest_get_prefix(
6856 dest));
6857 bgp_static_free(bgp_static);
6858 bgp_dest_set_bgp_static_info(rm,
6859 NULL);
6860 bgp_dest_unlock_node(rm);
6861 }
6862 } else {
6863 bgp_static = bgp_dest_get_bgp_static_info(dest);
6864 bgp_static_withdraw(bgp,
6865 bgp_dest_get_prefix(dest),
6866 afi, safi);
6867 bgp_static_free(bgp_static);
6868 bgp_dest_set_bgp_static_info(dest, NULL);
6869 bgp_dest_unlock_node(dest);
6870 }
6871 }
6872 }
6873
6874 void bgp_static_redo_import_check(struct bgp *bgp)
6875 {
6876 afi_t afi;
6877 safi_t safi;
6878 struct bgp_dest *dest;
6879 struct bgp_dest *rm;
6880 struct bgp_table *table;
6881 struct bgp_static *bgp_static;
6882
6883 /* Use this flag to force reprocessing of the route */
6884 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6885 FOREACH_AFI_SAFI (afi, safi) {
6886 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6887 dest = bgp_route_next(dest)) {
6888 if (!bgp_dest_has_bgp_path_info_data(dest))
6889 continue;
6890
6891 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6892 || (safi == SAFI_EVPN)) {
6893 table = bgp_dest_get_bgp_table_info(dest);
6894
6895 for (rm = bgp_table_top(table); rm;
6896 rm = bgp_route_next(rm)) {
6897 bgp_static =
6898 bgp_dest_get_bgp_static_info(
6899 rm);
6900 bgp_static_update_safi(
6901 bgp, bgp_dest_get_prefix(rm),
6902 bgp_static, afi, safi);
6903 }
6904 } else {
6905 bgp_static = bgp_dest_get_bgp_static_info(dest);
6906 bgp_static_update(bgp,
6907 bgp_dest_get_prefix(dest),
6908 bgp_static, afi, safi);
6909 }
6910 }
6911 }
6912 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6913 }
6914
6915 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6916 safi_t safi)
6917 {
6918 struct bgp_table *table;
6919 struct bgp_dest *dest;
6920 struct bgp_path_info *pi;
6921
6922 /* Do not install the aggregate route if BGP is in the
6923 * process of termination.
6924 */
6925 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6926 || (bgp->peer_self == NULL))
6927 return;
6928
6929 table = bgp->rib[afi][safi];
6930 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6931 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6932 if (pi->peer == bgp->peer_self
6933 && ((pi->type == ZEBRA_ROUTE_BGP
6934 && pi->sub_type == BGP_ROUTE_STATIC)
6935 || (pi->type != ZEBRA_ROUTE_BGP
6936 && pi->sub_type
6937 == BGP_ROUTE_REDISTRIBUTE))) {
6938 bgp_aggregate_decrement(
6939 bgp, bgp_dest_get_prefix(dest), pi, afi,
6940 safi);
6941 bgp_unlink_nexthop(pi);
6942 bgp_path_info_delete(dest, pi);
6943 bgp_process(bgp, dest, afi, safi);
6944 }
6945 }
6946 }
6947 }
6948
6949 /*
6950 * Purge all networks and redistributed routes from routing table.
6951 * Invoked upon the instance going down.
6952 */
6953 void bgp_purge_static_redist_routes(struct bgp *bgp)
6954 {
6955 afi_t afi;
6956 safi_t safi;
6957
6958 FOREACH_AFI_SAFI (afi, safi)
6959 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6960 }
6961
6962 /*
6963 * gpz 110624
6964 * Currently this is used to set static routes for VPN and ENCAP.
6965 * I think it can probably be factored with bgp_static_set.
6966 */
6967 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6968 const char *ip_str, const char *rd_str,
6969 const char *label_str, const char *rmap_str,
6970 int evpn_type, const char *esi, const char *gwip,
6971 const char *ethtag, const char *routermac)
6972 {
6973 VTY_DECLVAR_CONTEXT(bgp, bgp);
6974 int ret;
6975 struct prefix p;
6976 struct prefix_rd prd;
6977 struct bgp_dest *pdest;
6978 struct bgp_dest *dest;
6979 struct bgp_table *table;
6980 struct bgp_static *bgp_static;
6981 mpls_label_t label = MPLS_INVALID_LABEL;
6982 struct prefix gw_ip;
6983
6984 /* validate ip prefix */
6985 ret = str2prefix(ip_str, &p);
6986 if (!ret) {
6987 vty_out(vty, "%% Malformed prefix\n");
6988 return CMD_WARNING_CONFIG_FAILED;
6989 }
6990 apply_mask(&p);
6991 if ((afi == AFI_L2VPN)
6992 && (bgp_build_evpn_prefix(evpn_type,
6993 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6994 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6995 return CMD_WARNING_CONFIG_FAILED;
6996 }
6997
6998 ret = str2prefix_rd(rd_str, &prd);
6999 if (!ret) {
7000 vty_out(vty, "%% Malformed rd\n");
7001 return CMD_WARNING_CONFIG_FAILED;
7002 }
7003
7004 if (label_str) {
7005 unsigned long label_val;
7006 label_val = strtoul(label_str, NULL, 10);
7007 encode_label(label_val, &label);
7008 }
7009
7010 if (safi == SAFI_EVPN) {
7011 if (esi && str2esi(esi, NULL) == 0) {
7012 vty_out(vty, "%% Malformed ESI\n");
7013 return CMD_WARNING_CONFIG_FAILED;
7014 }
7015 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
7016 vty_out(vty, "%% Malformed Router MAC\n");
7017 return CMD_WARNING_CONFIG_FAILED;
7018 }
7019 if (gwip) {
7020 memset(&gw_ip, 0, sizeof(gw_ip));
7021 ret = str2prefix(gwip, &gw_ip);
7022 if (!ret) {
7023 vty_out(vty, "%% Malformed GatewayIp\n");
7024 return CMD_WARNING_CONFIG_FAILED;
7025 }
7026 if ((gw_ip.family == AF_INET
7027 && is_evpn_prefix_ipaddr_v6(
7028 (struct prefix_evpn *)&p))
7029 || (gw_ip.family == AF_INET6
7030 && is_evpn_prefix_ipaddr_v4(
7031 (struct prefix_evpn *)&p))) {
7032 vty_out(vty,
7033 "%% GatewayIp family differs with IP prefix\n");
7034 return CMD_WARNING_CONFIG_FAILED;
7035 }
7036 }
7037 }
7038 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7039 if (!bgp_dest_has_bgp_path_info_data(pdest))
7040 bgp_dest_set_bgp_table_info(pdest,
7041 bgp_table_init(bgp, afi, safi));
7042 table = bgp_dest_get_bgp_table_info(pdest);
7043
7044 dest = bgp_node_get(table, &p);
7045
7046 if (bgp_dest_has_bgp_path_info_data(dest)) {
7047 vty_out(vty, "%% Same network configuration exists\n");
7048 bgp_dest_unlock_node(dest);
7049 } else {
7050 /* New configuration. */
7051 bgp_static = bgp_static_new();
7052 bgp_static->backdoor = 0;
7053 bgp_static->valid = 0;
7054 bgp_static->igpmetric = 0;
7055 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7056 bgp_static->label = label;
7057 bgp_static->prd = prd;
7058
7059 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
7060
7061 if (rmap_str) {
7062 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7063 route_map_counter_decrement(bgp_static->rmap.map);
7064 bgp_static->rmap.name =
7065 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7066 bgp_static->rmap.map =
7067 route_map_lookup_by_name(rmap_str);
7068 route_map_counter_increment(bgp_static->rmap.map);
7069 }
7070
7071 if (safi == SAFI_EVPN) {
7072 if (esi) {
7073 bgp_static->eth_s_id =
7074 XCALLOC(MTYPE_ATTR,
7075 sizeof(esi_t));
7076 str2esi(esi, bgp_static->eth_s_id);
7077 }
7078 if (routermac) {
7079 bgp_static->router_mac =
7080 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7081 (void)prefix_str2mac(routermac,
7082 bgp_static->router_mac);
7083 }
7084 if (gwip)
7085 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7086 }
7087 bgp_dest_set_bgp_static_info(dest, bgp_static);
7088
7089 bgp_static->valid = 1;
7090 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7091 }
7092
7093 return CMD_SUCCESS;
7094 }
7095
7096 /* Configure static BGP network. */
7097 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7098 const char *ip_str, const char *rd_str,
7099 const char *label_str, int evpn_type, const char *esi,
7100 const char *gwip, const char *ethtag)
7101 {
7102 VTY_DECLVAR_CONTEXT(bgp, bgp);
7103 int ret;
7104 struct prefix p;
7105 struct prefix_rd prd;
7106 struct bgp_dest *pdest;
7107 struct bgp_dest *dest;
7108 struct bgp_table *table;
7109 struct bgp_static *bgp_static;
7110 mpls_label_t label = MPLS_INVALID_LABEL;
7111
7112 /* Convert IP prefix string to struct prefix. */
7113 ret = str2prefix(ip_str, &p);
7114 if (!ret) {
7115 vty_out(vty, "%% Malformed prefix\n");
7116 return CMD_WARNING_CONFIG_FAILED;
7117 }
7118 apply_mask(&p);
7119 if ((afi == AFI_L2VPN)
7120 && (bgp_build_evpn_prefix(evpn_type,
7121 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7122 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7123 return CMD_WARNING_CONFIG_FAILED;
7124 }
7125 ret = str2prefix_rd(rd_str, &prd);
7126 if (!ret) {
7127 vty_out(vty, "%% Malformed rd\n");
7128 return CMD_WARNING_CONFIG_FAILED;
7129 }
7130
7131 if (label_str) {
7132 unsigned long label_val;
7133 label_val = strtoul(label_str, NULL, 10);
7134 encode_label(label_val, &label);
7135 }
7136
7137 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7138 if (!bgp_dest_has_bgp_path_info_data(pdest))
7139 bgp_dest_set_bgp_table_info(pdest,
7140 bgp_table_init(bgp, afi, safi));
7141 else
7142 bgp_dest_unlock_node(pdest);
7143 table = bgp_dest_get_bgp_table_info(pdest);
7144
7145 dest = bgp_node_lookup(table, &p);
7146
7147 if (dest) {
7148 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7149
7150 bgp_static = bgp_dest_get_bgp_static_info(dest);
7151 bgp_static_free(bgp_static);
7152 bgp_dest_set_bgp_static_info(dest, NULL);
7153 bgp_dest_unlock_node(dest);
7154 bgp_dest_unlock_node(dest);
7155 } else
7156 vty_out(vty, "%% Can't find the route\n");
7157
7158 return CMD_SUCCESS;
7159 }
7160
7161 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7162 const char *rmap_name)
7163 {
7164 VTY_DECLVAR_CONTEXT(bgp, bgp);
7165 struct bgp_rmap *rmap;
7166
7167 rmap = &bgp->table_map[afi][safi];
7168 if (rmap_name) {
7169 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7170 route_map_counter_decrement(rmap->map);
7171 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7172 rmap->map = route_map_lookup_by_name(rmap_name);
7173 route_map_counter_increment(rmap->map);
7174 } else {
7175 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7176 route_map_counter_decrement(rmap->map);
7177 rmap->map = NULL;
7178 }
7179
7180 if (bgp_fibupd_safi(safi))
7181 bgp_zebra_announce_table(bgp, afi, safi);
7182
7183 return CMD_SUCCESS;
7184 }
7185
7186 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7187 const char *rmap_name)
7188 {
7189 VTY_DECLVAR_CONTEXT(bgp, bgp);
7190 struct bgp_rmap *rmap;
7191
7192 rmap = &bgp->table_map[afi][safi];
7193 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7194 route_map_counter_decrement(rmap->map);
7195 rmap->map = NULL;
7196
7197 if (bgp_fibupd_safi(safi))
7198 bgp_zebra_announce_table(bgp, afi, safi);
7199
7200 return CMD_SUCCESS;
7201 }
7202
7203 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7204 safi_t safi)
7205 {
7206 if (bgp->table_map[afi][safi].name) {
7207 vty_out(vty, " table-map %s\n",
7208 bgp->table_map[afi][safi].name);
7209 }
7210 }
7211
7212 DEFUN (bgp_table_map,
7213 bgp_table_map_cmd,
7214 "table-map WORD",
7215 "BGP table to RIB route download filter\n"
7216 "Name of the route map\n")
7217 {
7218 int idx_word = 1;
7219 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7220 argv[idx_word]->arg);
7221 }
7222 DEFUN (no_bgp_table_map,
7223 no_bgp_table_map_cmd,
7224 "no table-map WORD",
7225 NO_STR
7226 "BGP table to RIB route download filter\n"
7227 "Name of the route map\n")
7228 {
7229 int idx_word = 2;
7230 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7231 argv[idx_word]->arg);
7232 }
7233
7234 DEFPY(bgp_network,
7235 bgp_network_cmd,
7236 "[no] network \
7237 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7238 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7239 backdoor$backdoor}]",
7240 NO_STR
7241 "Specify a network to announce via BGP\n"
7242 "IPv4 prefix\n"
7243 "Network number\n"
7244 "Network mask\n"
7245 "Network mask\n"
7246 "Route-map to modify the attributes\n"
7247 "Name of the route map\n"
7248 "Label index to associate with the prefix\n"
7249 "Label index value\n"
7250 "Specify a BGP backdoor route\n")
7251 {
7252 char addr_prefix_str[BUFSIZ];
7253
7254 if (address_str) {
7255 int ret;
7256
7257 ret = netmask_str2prefix_str(address_str, netmask_str,
7258 addr_prefix_str,
7259 sizeof(addr_prefix_str));
7260 if (!ret) {
7261 vty_out(vty, "%% Inconsistent address and mask\n");
7262 return CMD_WARNING_CONFIG_FAILED;
7263 }
7264 }
7265
7266 return bgp_static_set(
7267 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7268 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7269 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7270 }
7271
7272 DEFPY(ipv6_bgp_network,
7273 ipv6_bgp_network_cmd,
7274 "[no] network X:X::X:X/M$prefix \
7275 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7276 NO_STR
7277 "Specify a network to announce via BGP\n"
7278 "IPv6 prefix\n"
7279 "Route-map to modify the attributes\n"
7280 "Name of the route map\n"
7281 "Label index to associate with the prefix\n"
7282 "Label index value\n")
7283 {
7284 return bgp_static_set(
7285 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7286 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7287 }
7288
7289 static struct bgp_aggregate *bgp_aggregate_new(void)
7290 {
7291 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7292 }
7293
7294 void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7295 {
7296 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7297 route_map_counter_decrement(aggregate->suppress_map);
7298 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7299 route_map_counter_decrement(aggregate->rmap.map);
7300 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7301 }
7302
7303 /**
7304 * Helper function to avoid repeated code: prepare variables for a
7305 * `route_map_apply` call.
7306 *
7307 * \returns `true` on route map match, otherwise `false`.
7308 */
7309 static bool aggr_suppress_map_test(struct bgp *bgp,
7310 struct bgp_aggregate *aggregate,
7311 struct bgp_path_info *pi)
7312 {
7313 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7314 route_map_result_t rmr = RMAP_DENYMATCH;
7315 struct bgp_path_info rmap_path = {};
7316 struct attr attr = {};
7317
7318 /* No route map entries created, just don't match. */
7319 if (aggregate->suppress_map == NULL)
7320 return false;
7321
7322 /* Call route map matching and return result. */
7323 attr.aspath = aspath_empty(bgp->asnotation);
7324 rmap_path.peer = bgp->peer_self;
7325 rmap_path.attr = &attr;
7326
7327 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7328 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7329 bgp->peer_self->rmap_type = 0;
7330
7331 bgp_attr_flush(&attr);
7332 aspath_unintern(&attr.aspath);
7333
7334 return rmr == RMAP_PERMITMATCH;
7335 }
7336
7337 /** Test whether the aggregation has suppressed this path or not. */
7338 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7339 struct bgp_path_info *pi)
7340 {
7341 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7342 return false;
7343
7344 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7345 }
7346
7347 /**
7348 * Suppress this path and keep the reference.
7349 *
7350 * \returns `true` if needs processing otherwise `false`.
7351 */
7352 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7353 struct bgp_path_info *pi)
7354 {
7355 struct bgp_path_info_extra *pie;
7356
7357 /* Path is already suppressed by this aggregation. */
7358 if (aggr_suppress_exists(aggregate, pi))
7359 return false;
7360
7361 pie = bgp_path_info_extra_get(pi);
7362
7363 /* This is the first suppression, allocate memory and list it. */
7364 if (pie->aggr_suppressors == NULL)
7365 pie->aggr_suppressors = list_new();
7366
7367 listnode_add(pie->aggr_suppressors, aggregate);
7368
7369 /* Only mark for processing if suppressed. */
7370 if (listcount(pie->aggr_suppressors) == 1) {
7371 if (BGP_DEBUG(update, UPDATE_OUT))
7372 zlog_debug("aggregate-address suppressing: %pFX",
7373 bgp_dest_get_prefix(pi->net));
7374
7375 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7376 return true;
7377 }
7378
7379 return false;
7380 }
7381
7382 /**
7383 * Unsuppress this path and remove the reference.
7384 *
7385 * \returns `true` if needs processing otherwise `false`.
7386 */
7387 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7388 struct bgp_path_info *pi)
7389 {
7390 /* Path wasn't suppressed. */
7391 if (!aggr_suppress_exists(aggregate, pi))
7392 return false;
7393
7394 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7395
7396 /* Unsuppress and free extra memory if last item. */
7397 if (listcount(pi->extra->aggr_suppressors) == 0) {
7398 if (BGP_DEBUG(update, UPDATE_OUT))
7399 zlog_debug("aggregate-address unsuppressing: %pFX",
7400 bgp_dest_get_prefix(pi->net));
7401
7402 list_delete(&pi->extra->aggr_suppressors);
7403 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7404 return true;
7405 }
7406
7407 return false;
7408 }
7409
7410 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7411 struct aspath *aspath,
7412 struct community *comm,
7413 struct ecommunity *ecomm,
7414 struct lcommunity *lcomm)
7415 {
7416 static struct aspath *ae = NULL;
7417 enum asnotation_mode asnotation;
7418
7419 asnotation = bgp_get_asnotation(NULL);
7420
7421 if (!ae)
7422 ae = aspath_empty(asnotation);
7423
7424 if (!pi)
7425 return false;
7426
7427 if (origin != pi->attr->origin)
7428 return false;
7429
7430 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7431 return false;
7432
7433 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7434 return false;
7435
7436 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7437 return false;
7438
7439 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7440 return false;
7441
7442 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7443 return false;
7444
7445 return true;
7446 }
7447
7448 static void bgp_aggregate_install(
7449 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7450 uint8_t origin, struct aspath *aspath, struct community *community,
7451 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7452 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7453 {
7454 struct bgp_dest *dest;
7455 struct bgp_table *table;
7456 struct bgp_path_info *pi, *orig, *new;
7457 struct attr *attr;
7458
7459 table = bgp->rib[afi][safi];
7460
7461 dest = bgp_node_get(table, p);
7462
7463 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7464 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7465 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7466 break;
7467
7468 /*
7469 * If we have paths with different MEDs, then don't install
7470 * (or uninstall) the aggregate route.
7471 */
7472 if (aggregate->match_med && aggregate->med_mismatched)
7473 goto uninstall_aggregate_route;
7474
7475 if (aggregate->count > 0) {
7476 /*
7477 * If the aggregate information has not changed
7478 * no need to re-install it again.
7479 */
7480 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7481 ecommunity, lcommunity)) {
7482 bgp_dest_unlock_node(dest);
7483
7484 if (aspath)
7485 aspath_free(aspath);
7486 if (community)
7487 community_free(&community);
7488 if (ecommunity)
7489 ecommunity_free(&ecommunity);
7490 if (lcommunity)
7491 lcommunity_free(&lcommunity);
7492
7493 return;
7494 }
7495
7496 /*
7497 * Mark the old as unusable
7498 */
7499 if (pi)
7500 bgp_path_info_delete(dest, pi);
7501
7502 attr = bgp_attr_aggregate_intern(
7503 bgp, origin, aspath, community, ecommunity, lcommunity,
7504 aggregate, atomic_aggregate, p);
7505
7506 if (!attr) {
7507 aspath_free(aspath);
7508 community_free(&community);
7509 ecommunity_free(&ecommunity);
7510 lcommunity_free(&lcommunity);
7511 bgp_dest_unlock_node(dest);
7512 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7513 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7514 zlog_debug("%s: %pFX null attribute", __func__,
7515 p);
7516 return;
7517 }
7518
7519 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7520 bgp->peer_self, attr, dest);
7521
7522 SET_FLAG(new->flags, BGP_PATH_VALID);
7523
7524 bgp_path_info_add(dest, new);
7525 bgp_process(bgp, dest, afi, safi);
7526 } else {
7527 uninstall_aggregate_route:
7528 for (pi = orig; pi; pi = pi->next)
7529 if (pi->peer == bgp->peer_self
7530 && pi->type == ZEBRA_ROUTE_BGP
7531 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7532 break;
7533
7534 /* Withdraw static BGP route from routing table. */
7535 if (pi) {
7536 bgp_path_info_delete(dest, pi);
7537 bgp_process(bgp, dest, afi, safi);
7538 }
7539 }
7540
7541 bgp_dest_unlock_node(dest);
7542 }
7543
7544 /**
7545 * Check if the current path has different MED than other known paths.
7546 *
7547 * \returns `true` if the MED matched the others else `false`.
7548 */
7549 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7550 struct bgp *bgp, struct bgp_path_info *pi)
7551 {
7552 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7553
7554 /* This is the first route being analyzed. */
7555 if (!aggregate->med_initialized) {
7556 aggregate->med_initialized = true;
7557 aggregate->med_mismatched = false;
7558 aggregate->med_matched_value = cur_med;
7559 } else {
7560 /* Check if routes with different MED showed up. */
7561 if (cur_med != aggregate->med_matched_value)
7562 aggregate->med_mismatched = true;
7563 }
7564
7565 return !aggregate->med_mismatched;
7566 }
7567
7568 /**
7569 * Initializes and tests all routes in the aggregate address path for MED
7570 * values.
7571 *
7572 * \returns `true` if all MEDs are the same otherwise `false`.
7573 */
7574 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7575 struct bgp *bgp, const struct prefix *p,
7576 afi_t afi, safi_t safi)
7577 {
7578 struct bgp_table *table = bgp->rib[afi][safi];
7579 const struct prefix *dest_p;
7580 struct bgp_dest *dest, *top;
7581 struct bgp_path_info *pi;
7582 bool med_matched = true;
7583
7584 aggregate->med_initialized = false;
7585
7586 top = bgp_node_get(table, p);
7587 for (dest = bgp_node_get(table, p); dest;
7588 dest = bgp_route_next_until(dest, top)) {
7589 dest_p = bgp_dest_get_prefix(dest);
7590 if (dest_p->prefixlen <= p->prefixlen)
7591 continue;
7592
7593 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7594 if (BGP_PATH_HOLDDOWN(pi))
7595 continue;
7596 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7597 continue;
7598 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7599 med_matched = false;
7600 break;
7601 }
7602 }
7603 if (!med_matched)
7604 break;
7605 }
7606 bgp_dest_unlock_node(top);
7607
7608 return med_matched;
7609 }
7610
7611 /**
7612 * Toggles the route suppression status for this aggregate address
7613 * configuration.
7614 */
7615 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7616 struct bgp *bgp, const struct prefix *p,
7617 afi_t afi, safi_t safi, bool suppress)
7618 {
7619 struct bgp_table *table = bgp->rib[afi][safi];
7620 const struct prefix *dest_p;
7621 struct bgp_dest *dest, *top;
7622 struct bgp_path_info *pi;
7623 bool toggle_suppression;
7624
7625 /* We've found a different MED we must revert any suppressed routes. */
7626 top = bgp_node_get(table, p);
7627 for (dest = bgp_node_get(table, p); dest;
7628 dest = bgp_route_next_until(dest, top)) {
7629 dest_p = bgp_dest_get_prefix(dest);
7630 if (dest_p->prefixlen <= p->prefixlen)
7631 continue;
7632
7633 toggle_suppression = false;
7634 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7635 if (BGP_PATH_HOLDDOWN(pi))
7636 continue;
7637 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7638 continue;
7639
7640 /* We are toggling suppression back. */
7641 if (suppress) {
7642 /* Suppress route if not suppressed already. */
7643 if (aggr_suppress_path(aggregate, pi))
7644 toggle_suppression = true;
7645 continue;
7646 }
7647
7648 /* Install route if there is no more suppression. */
7649 if (aggr_unsuppress_path(aggregate, pi))
7650 toggle_suppression = true;
7651 }
7652
7653 if (toggle_suppression)
7654 bgp_process(bgp, dest, afi, safi);
7655 }
7656 bgp_dest_unlock_node(top);
7657 }
7658
7659 /**
7660 * Aggregate address MED matching incremental test: this function is called
7661 * when the initial aggregation occurred and we are only testing a single
7662 * new path.
7663 *
7664 * In addition to testing and setting the MED validity it also installs back
7665 * suppressed routes (if summary is configured).
7666 *
7667 * Must not be called in `bgp_aggregate_route`.
7668 */
7669 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7670 struct bgp *bgp, const struct prefix *p,
7671 afi_t afi, safi_t safi,
7672 struct bgp_path_info *pi)
7673 {
7674 /* MED matching disabled. */
7675 if (!aggregate->match_med)
7676 return;
7677
7678 /* Aggregation with different MED, recheck if we have got equal MEDs
7679 * now.
7680 */
7681 if (aggregate->med_mismatched &&
7682 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7683 aggregate->summary_only)
7684 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7685 true);
7686 else
7687 bgp_aggregate_med_match(aggregate, bgp, pi);
7688
7689 /* No mismatches, just quit. */
7690 if (!aggregate->med_mismatched)
7691 return;
7692
7693 /* Route summarization is disabled. */
7694 if (!aggregate->summary_only)
7695 return;
7696
7697 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7698 }
7699
7700 /* Update an aggregate as routes are added/removed from the BGP table */
7701 bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7702 safi_t safi, struct bgp_aggregate *aggregate)
7703 {
7704 struct bgp_table *table;
7705 struct bgp_dest *top;
7706 struct bgp_dest *dest;
7707 uint8_t origin;
7708 struct aspath *aspath = NULL;
7709 struct community *community = NULL;
7710 struct ecommunity *ecommunity = NULL;
7711 struct lcommunity *lcommunity = NULL;
7712 struct bgp_path_info *pi;
7713 unsigned long match = 0;
7714 uint8_t atomic_aggregate = 0;
7715
7716 /* If the bgp instance is being deleted or self peer is deleted
7717 * then do not create aggregate route
7718 */
7719 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
7720 bgp->peer_self == NULL)
7721 return false;
7722
7723 /* Initialize and test routes for MED difference. */
7724 if (aggregate->match_med)
7725 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7726
7727 /*
7728 * Reset aggregate count: we might've been called from route map
7729 * update so in that case we must retest all more specific routes.
7730 *
7731 * \see `bgp_route_map_process_update`.
7732 */
7733 aggregate->count = 0;
7734 aggregate->incomplete_origin_count = 0;
7735 aggregate->incomplete_origin_count = 0;
7736 aggregate->egp_origin_count = 0;
7737
7738 /* ORIGIN attribute: If at least one route among routes that are
7739 aggregated has ORIGIN with the value INCOMPLETE, then the
7740 aggregated route must have the ORIGIN attribute with the value
7741 INCOMPLETE. Otherwise, if at least one route among routes that
7742 are aggregated has ORIGIN with the value EGP, then the aggregated
7743 route must have the origin attribute with the value EGP. In all
7744 other case the value of the ORIGIN attribute of the aggregated
7745 route is INTERNAL. */
7746 origin = BGP_ORIGIN_IGP;
7747
7748 table = bgp->rib[afi][safi];
7749
7750 top = bgp_node_get(table, p);
7751 for (dest = bgp_node_get(table, p); dest;
7752 dest = bgp_route_next_until(dest, top)) {
7753 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7754
7755 if (dest_p->prefixlen <= p->prefixlen)
7756 continue;
7757
7758 /* If suppress fib is enabled and route not installed
7759 * in FIB, skip the route
7760 */
7761 if (!bgp_check_advertise(bgp, dest))
7762 continue;
7763
7764 match = 0;
7765
7766 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7767 if (BGP_PATH_HOLDDOWN(pi))
7768 continue;
7769
7770 if (pi->attr->flag
7771 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7772 atomic_aggregate = 1;
7773
7774 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7775 continue;
7776
7777 /*
7778 * summary-only aggregate route suppress
7779 * aggregated route announcements.
7780 *
7781 * MED matching:
7782 * Don't create summaries if MED didn't match
7783 * otherwise neither the specific routes and the
7784 * aggregation will be announced.
7785 */
7786 if (aggregate->summary_only
7787 && AGGREGATE_MED_VALID(aggregate)) {
7788 if (aggr_suppress_path(aggregate, pi))
7789 match++;
7790 }
7791
7792 /*
7793 * Suppress more specific routes that match the route
7794 * map results.
7795 *
7796 * MED matching:
7797 * Don't suppress routes if MED matching is enabled and
7798 * it mismatched otherwise we might end up with no
7799 * routes for this path.
7800 */
7801 if (aggregate->suppress_map_name
7802 && AGGREGATE_MED_VALID(aggregate)
7803 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7804 if (aggr_suppress_path(aggregate, pi))
7805 match++;
7806 }
7807
7808 aggregate->count++;
7809
7810 /*
7811 * If at least one route among routes that are
7812 * aggregated has ORIGIN with the value INCOMPLETE,
7813 * then the aggregated route MUST have the ORIGIN
7814 * attribute with the value INCOMPLETE. Otherwise, if
7815 * at least one route among routes that are aggregated
7816 * has ORIGIN with the value EGP, then the aggregated
7817 * route MUST have the ORIGIN attribute with the value
7818 * EGP.
7819 */
7820 switch (pi->attr->origin) {
7821 case BGP_ORIGIN_INCOMPLETE:
7822 aggregate->incomplete_origin_count++;
7823 break;
7824 case BGP_ORIGIN_EGP:
7825 aggregate->egp_origin_count++;
7826 break;
7827 default:
7828 /*Do nothing.
7829 */
7830 break;
7831 }
7832
7833 if (!aggregate->as_set)
7834 continue;
7835
7836 /*
7837 * as-set aggregate route generate origin, as path,
7838 * and community aggregation.
7839 */
7840 /* Compute aggregate route's as-path.
7841 */
7842 bgp_compute_aggregate_aspath_hash(aggregate,
7843 pi->attr->aspath);
7844
7845 /* Compute aggregate route's community.
7846 */
7847 if (bgp_attr_get_community(pi->attr))
7848 bgp_compute_aggregate_community_hash(
7849 aggregate,
7850 bgp_attr_get_community(pi->attr));
7851
7852 /* Compute aggregate route's extended community.
7853 */
7854 if (bgp_attr_get_ecommunity(pi->attr))
7855 bgp_compute_aggregate_ecommunity_hash(
7856 aggregate,
7857 bgp_attr_get_ecommunity(pi->attr));
7858
7859 /* Compute aggregate route's large community.
7860 */
7861 if (bgp_attr_get_lcommunity(pi->attr))
7862 bgp_compute_aggregate_lcommunity_hash(
7863 aggregate,
7864 bgp_attr_get_lcommunity(pi->attr));
7865 }
7866 if (match)
7867 bgp_process(bgp, dest, afi, safi);
7868 }
7869 if (aggregate->as_set) {
7870 bgp_compute_aggregate_aspath_val(aggregate);
7871 bgp_compute_aggregate_community_val(aggregate);
7872 bgp_compute_aggregate_ecommunity_val(aggregate);
7873 bgp_compute_aggregate_lcommunity_val(aggregate);
7874 }
7875
7876
7877 bgp_dest_unlock_node(top);
7878
7879
7880 if (aggregate->incomplete_origin_count > 0)
7881 origin = BGP_ORIGIN_INCOMPLETE;
7882 else if (aggregate->egp_origin_count > 0)
7883 origin = BGP_ORIGIN_EGP;
7884
7885 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7886 origin = aggregate->origin;
7887
7888 if (aggregate->as_set) {
7889 if (aggregate->aspath)
7890 /* Retrieve aggregate route's as-path.
7891 */
7892 aspath = aspath_dup(aggregate->aspath);
7893
7894 if (aggregate->community)
7895 /* Retrieve aggregate route's community.
7896 */
7897 community = community_dup(aggregate->community);
7898
7899 if (aggregate->ecommunity)
7900 /* Retrieve aggregate route's ecommunity.
7901 */
7902 ecommunity = ecommunity_dup(aggregate->ecommunity);
7903
7904 if (aggregate->lcommunity)
7905 /* Retrieve aggregate route's lcommunity.
7906 */
7907 lcommunity = lcommunity_dup(aggregate->lcommunity);
7908 }
7909
7910 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7911 ecommunity, lcommunity, atomic_aggregate,
7912 aggregate);
7913
7914 return true;
7915 }
7916
7917 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7918 safi_t safi, struct bgp_aggregate *aggregate)
7919 {
7920 struct bgp_table *table;
7921 struct bgp_dest *top;
7922 struct bgp_dest *dest;
7923 struct bgp_path_info *pi;
7924 unsigned long match;
7925
7926 table = bgp->rib[afi][safi];
7927
7928 /* If routes exists below this node, generate aggregate routes. */
7929 top = bgp_node_get(table, p);
7930 for (dest = bgp_node_get(table, p); dest;
7931 dest = bgp_route_next_until(dest, top)) {
7932 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7933
7934 if (dest_p->prefixlen <= p->prefixlen)
7935 continue;
7936 match = 0;
7937
7938 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7939 if (BGP_PATH_HOLDDOWN(pi))
7940 continue;
7941
7942 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7943 continue;
7944
7945 /*
7946 * This route is suppressed: attempt to unsuppress it.
7947 *
7948 * `aggr_unsuppress_path` will fail if this particular
7949 * aggregate route was not the suppressor.
7950 */
7951 if (pi->extra && pi->extra->aggr_suppressors &&
7952 listcount(pi->extra->aggr_suppressors)) {
7953 if (aggr_unsuppress_path(aggregate, pi))
7954 match++;
7955 }
7956
7957 aggregate->count--;
7958
7959 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7960 aggregate->incomplete_origin_count--;
7961 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7962 aggregate->egp_origin_count--;
7963
7964 if (aggregate->as_set) {
7965 /* Remove as-path from aggregate.
7966 */
7967 bgp_remove_aspath_from_aggregate_hash(
7968 aggregate,
7969 pi->attr->aspath);
7970
7971 if (bgp_attr_get_community(pi->attr))
7972 /* Remove community from aggregate.
7973 */
7974 bgp_remove_comm_from_aggregate_hash(
7975 aggregate,
7976 bgp_attr_get_community(
7977 pi->attr));
7978
7979 if (bgp_attr_get_ecommunity(pi->attr))
7980 /* Remove ecommunity from aggregate.
7981 */
7982 bgp_remove_ecomm_from_aggregate_hash(
7983 aggregate,
7984 bgp_attr_get_ecommunity(
7985 pi->attr));
7986
7987 if (bgp_attr_get_lcommunity(pi->attr))
7988 /* Remove lcommunity from aggregate.
7989 */
7990 bgp_remove_lcomm_from_aggregate_hash(
7991 aggregate,
7992 bgp_attr_get_lcommunity(
7993 pi->attr));
7994 }
7995 }
7996
7997 /* If this node was suppressed, process the change. */
7998 if (match)
7999 bgp_process(bgp, dest, afi, safi);
8000 }
8001 if (aggregate->as_set) {
8002 aspath_free(aggregate->aspath);
8003 aggregate->aspath = NULL;
8004 if (aggregate->community)
8005 community_free(&aggregate->community);
8006 if (aggregate->ecommunity)
8007 ecommunity_free(&aggregate->ecommunity);
8008 if (aggregate->lcommunity)
8009 lcommunity_free(&aggregate->lcommunity);
8010 }
8011
8012 bgp_dest_unlock_node(top);
8013 }
8014
8015 static void bgp_add_route_to_aggregate(struct bgp *bgp,
8016 const struct prefix *aggr_p,
8017 struct bgp_path_info *pinew, afi_t afi,
8018 safi_t safi,
8019 struct bgp_aggregate *aggregate)
8020 {
8021 uint8_t origin;
8022 struct aspath *aspath = NULL;
8023 uint8_t atomic_aggregate = 0;
8024 struct community *community = NULL;
8025 struct ecommunity *ecommunity = NULL;
8026 struct lcommunity *lcommunity = NULL;
8027
8028 /* If the bgp instance is being deleted or self peer is deleted
8029 * then do not create aggregate route
8030 */
8031 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8032 || (bgp->peer_self == NULL))
8033 return;
8034
8035 /* ORIGIN attribute: If at least one route among routes that are
8036 * aggregated has ORIGIN with the value INCOMPLETE, then the
8037 * aggregated route must have the ORIGIN attribute with the value
8038 * INCOMPLETE. Otherwise, if at least one route among routes that
8039 * are aggregated has ORIGIN with the value EGP, then the aggregated
8040 * route must have the origin attribute with the value EGP. In all
8041 * other case the value of the ORIGIN attribute of the aggregated
8042 * route is INTERNAL.
8043 */
8044 origin = BGP_ORIGIN_IGP;
8045
8046 aggregate->count++;
8047
8048 /*
8049 * This must be called before `summary` check to avoid
8050 * "suppressing" twice.
8051 */
8052 if (aggregate->match_med)
8053 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8054 pinew);
8055
8056 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8057 aggr_suppress_path(aggregate, pinew);
8058
8059 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8060 && aggr_suppress_map_test(bgp, aggregate, pinew))
8061 aggr_suppress_path(aggregate, pinew);
8062
8063 switch (pinew->attr->origin) {
8064 case BGP_ORIGIN_INCOMPLETE:
8065 aggregate->incomplete_origin_count++;
8066 break;
8067 case BGP_ORIGIN_EGP:
8068 aggregate->egp_origin_count++;
8069 break;
8070 default:
8071 /* Do nothing.
8072 */
8073 break;
8074 }
8075
8076 if (aggregate->incomplete_origin_count > 0)
8077 origin = BGP_ORIGIN_INCOMPLETE;
8078 else if (aggregate->egp_origin_count > 0)
8079 origin = BGP_ORIGIN_EGP;
8080
8081 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8082 origin = aggregate->origin;
8083
8084 if (aggregate->as_set) {
8085 /* Compute aggregate route's as-path.
8086 */
8087 bgp_compute_aggregate_aspath(aggregate,
8088 pinew->attr->aspath);
8089
8090 /* Compute aggregate route's community.
8091 */
8092 if (bgp_attr_get_community(pinew->attr))
8093 bgp_compute_aggregate_community(
8094 aggregate, bgp_attr_get_community(pinew->attr));
8095
8096 /* Compute aggregate route's extended community.
8097 */
8098 if (bgp_attr_get_ecommunity(pinew->attr))
8099 bgp_compute_aggregate_ecommunity(
8100 aggregate,
8101 bgp_attr_get_ecommunity(pinew->attr));
8102
8103 /* Compute aggregate route's large community.
8104 */
8105 if (bgp_attr_get_lcommunity(pinew->attr))
8106 bgp_compute_aggregate_lcommunity(
8107 aggregate,
8108 bgp_attr_get_lcommunity(pinew->attr));
8109
8110 /* Retrieve aggregate route's as-path.
8111 */
8112 if (aggregate->aspath)
8113 aspath = aspath_dup(aggregate->aspath);
8114
8115 /* Retrieve aggregate route's community.
8116 */
8117 if (aggregate->community)
8118 community = community_dup(aggregate->community);
8119
8120 /* Retrieve aggregate route's ecommunity.
8121 */
8122 if (aggregate->ecommunity)
8123 ecommunity = ecommunity_dup(aggregate->ecommunity);
8124
8125 /* Retrieve aggregate route's lcommunity.
8126 */
8127 if (aggregate->lcommunity)
8128 lcommunity = lcommunity_dup(aggregate->lcommunity);
8129 }
8130
8131 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8132 aspath, community, ecommunity,
8133 lcommunity, atomic_aggregate, aggregate);
8134 }
8135
8136 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8137 safi_t safi,
8138 struct bgp_path_info *pi,
8139 struct bgp_aggregate *aggregate,
8140 const struct prefix *aggr_p)
8141 {
8142 uint8_t origin;
8143 struct aspath *aspath = NULL;
8144 uint8_t atomic_aggregate = 0;
8145 struct community *community = NULL;
8146 struct ecommunity *ecommunity = NULL;
8147 struct lcommunity *lcommunity = NULL;
8148 unsigned long match = 0;
8149
8150 /* If the bgp instance is being deleted or self peer is deleted
8151 * then do not create aggregate route
8152 */
8153 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8154 || (bgp->peer_self == NULL))
8155 return;
8156
8157 if (BGP_PATH_HOLDDOWN(pi))
8158 return;
8159
8160 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8161 return;
8162
8163 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8164 if (aggr_unsuppress_path(aggregate, pi))
8165 match++;
8166
8167 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8168 && aggr_suppress_map_test(bgp, aggregate, pi))
8169 if (aggr_unsuppress_path(aggregate, pi))
8170 match++;
8171
8172 /*
8173 * This must be called after `summary`, `suppress-map` check to avoid
8174 * "unsuppressing" twice.
8175 */
8176 if (aggregate->match_med)
8177 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8178
8179 if (aggregate->count > 0)
8180 aggregate->count--;
8181
8182 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8183 aggregate->incomplete_origin_count--;
8184 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8185 aggregate->egp_origin_count--;
8186
8187 if (aggregate->as_set) {
8188 /* Remove as-path from aggregate.
8189 */
8190 bgp_remove_aspath_from_aggregate(aggregate,
8191 pi->attr->aspath);
8192
8193 if (bgp_attr_get_community(pi->attr))
8194 /* Remove community from aggregate.
8195 */
8196 bgp_remove_community_from_aggregate(
8197 aggregate, bgp_attr_get_community(pi->attr));
8198
8199 if (bgp_attr_get_ecommunity(pi->attr))
8200 /* Remove ecommunity from aggregate.
8201 */
8202 bgp_remove_ecommunity_from_aggregate(
8203 aggregate, bgp_attr_get_ecommunity(pi->attr));
8204
8205 if (bgp_attr_get_lcommunity(pi->attr))
8206 /* Remove lcommunity from aggregate.
8207 */
8208 bgp_remove_lcommunity_from_aggregate(
8209 aggregate, bgp_attr_get_lcommunity(pi->attr));
8210 }
8211
8212 /* If this node was suppressed, process the change. */
8213 if (match)
8214 bgp_process(bgp, pi->net, afi, safi);
8215
8216 origin = BGP_ORIGIN_IGP;
8217 if (aggregate->incomplete_origin_count > 0)
8218 origin = BGP_ORIGIN_INCOMPLETE;
8219 else if (aggregate->egp_origin_count > 0)
8220 origin = BGP_ORIGIN_EGP;
8221
8222 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8223 origin = aggregate->origin;
8224
8225 if (aggregate->as_set) {
8226 /* Retrieve aggregate route's as-path.
8227 */
8228 if (aggregate->aspath)
8229 aspath = aspath_dup(aggregate->aspath);
8230
8231 /* Retrieve aggregate route's community.
8232 */
8233 if (aggregate->community)
8234 community = community_dup(aggregate->community);
8235
8236 /* Retrieve aggregate route's ecommunity.
8237 */
8238 if (aggregate->ecommunity)
8239 ecommunity = ecommunity_dup(aggregate->ecommunity);
8240
8241 /* Retrieve aggregate route's lcommunity.
8242 */
8243 if (aggregate->lcommunity)
8244 lcommunity = lcommunity_dup(aggregate->lcommunity);
8245 }
8246
8247 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8248 aspath, community, ecommunity,
8249 lcommunity, atomic_aggregate, aggregate);
8250 }
8251
8252 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8253 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8254 {
8255 struct bgp_dest *child;
8256 struct bgp_dest *dest;
8257 struct bgp_aggregate *aggregate;
8258 struct bgp_table *table;
8259
8260 table = bgp->aggregate[afi][safi];
8261
8262 /* No aggregates configured. */
8263 if (bgp_table_top_nolock(table) == NULL)
8264 return;
8265
8266 if (p->prefixlen == 0)
8267 return;
8268
8269 if (BGP_PATH_HOLDDOWN(pi))
8270 return;
8271
8272 /* If suppress fib is enabled and route not installed
8273 * in FIB, do not update the aggregate route
8274 */
8275 if (!bgp_check_advertise(bgp, pi->net))
8276 return;
8277
8278 child = bgp_node_get(table, p);
8279
8280 /* Aggregate address configuration check. */
8281 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8282 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8283
8284 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8285 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8286 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8287 aggregate);
8288 }
8289 }
8290 bgp_dest_unlock_node(child);
8291 }
8292
8293 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8294 struct bgp_path_info *del, afi_t afi, safi_t safi)
8295 {
8296 struct bgp_dest *child;
8297 struct bgp_dest *dest;
8298 struct bgp_aggregate *aggregate;
8299 struct bgp_table *table;
8300
8301 table = bgp->aggregate[afi][safi];
8302
8303 /* No aggregates configured. */
8304 if (bgp_table_top_nolock(table) == NULL)
8305 return;
8306
8307 if (p->prefixlen == 0)
8308 return;
8309
8310 child = bgp_node_get(table, p);
8311
8312 /* Aggregate address configuration check. */
8313 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8314 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8315
8316 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8317 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8318 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8319 aggregate, dest_p);
8320 }
8321 }
8322 bgp_dest_unlock_node(child);
8323 }
8324
8325 /* Aggregate route attribute. */
8326 #define AGGREGATE_SUMMARY_ONLY 1
8327 #define AGGREGATE_AS_SET 1
8328 #define AGGREGATE_AS_UNSET 0
8329
8330 static const char *bgp_origin2str(uint8_t origin)
8331 {
8332 switch (origin) {
8333 case BGP_ORIGIN_IGP:
8334 return "igp";
8335 case BGP_ORIGIN_EGP:
8336 return "egp";
8337 case BGP_ORIGIN_INCOMPLETE:
8338 return "incomplete";
8339 }
8340 return "n/a";
8341 }
8342
8343 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8344 {
8345 switch (v_state) {
8346 case RPKI_NOT_BEING_USED:
8347 return "not used";
8348 case RPKI_VALID:
8349 return "valid";
8350 case RPKI_NOTFOUND:
8351 return "not found";
8352 case RPKI_INVALID:
8353 return "invalid";
8354 }
8355
8356 assert(!"We should never get here this is a dev escape");
8357 return "ERROR";
8358 }
8359
8360 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8361 afi_t afi, safi_t safi)
8362 {
8363 VTY_DECLVAR_CONTEXT(bgp, bgp);
8364 int ret;
8365 struct prefix p;
8366 struct bgp_dest *dest;
8367 struct bgp_aggregate *aggregate;
8368
8369 /* Convert string to prefix structure. */
8370 ret = str2prefix(prefix_str, &p);
8371 if (!ret) {
8372 vty_out(vty, "Malformed prefix\n");
8373 return CMD_WARNING_CONFIG_FAILED;
8374 }
8375 apply_mask(&p);
8376
8377 /* Old configuration check. */
8378 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8379 if (!dest) {
8380 vty_out(vty,
8381 "%% There is no aggregate-address configuration.\n");
8382 return CMD_WARNING_CONFIG_FAILED;
8383 }
8384
8385 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8386 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8387 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8388 NULL, NULL, 0, aggregate);
8389
8390 /* Unlock aggregate address configuration. */
8391 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8392
8393 bgp_free_aggregate_info(aggregate);
8394 bgp_dest_unlock_node(dest);
8395 bgp_dest_unlock_node(dest);
8396
8397 return CMD_SUCCESS;
8398 }
8399
8400 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8401 safi_t safi, const char *rmap,
8402 uint8_t summary_only, uint8_t as_set,
8403 uint8_t origin, bool match_med,
8404 const char *suppress_map)
8405 {
8406 VTY_DECLVAR_CONTEXT(bgp, bgp);
8407 int ret;
8408 struct prefix p;
8409 struct bgp_dest *dest;
8410 struct bgp_aggregate *aggregate;
8411 uint8_t as_set_new = as_set;
8412
8413 if (suppress_map && summary_only) {
8414 vty_out(vty,
8415 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8416 return CMD_WARNING_CONFIG_FAILED;
8417 }
8418
8419 /* Convert string to prefix structure. */
8420 ret = str2prefix(prefix_str, &p);
8421 if (!ret) {
8422 vty_out(vty, "Malformed prefix\n");
8423 return CMD_WARNING_CONFIG_FAILED;
8424 }
8425 apply_mask(&p);
8426
8427 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8428 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8429 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8430 prefix_str);
8431 return CMD_WARNING_CONFIG_FAILED;
8432 }
8433
8434 /* Old configuration check. */
8435 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8436 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8437
8438 if (aggregate) {
8439 vty_out(vty, "There is already same aggregate network.\n");
8440 /* try to remove the old entry */
8441 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8442 if (ret) {
8443 vty_out(vty, "Error deleting aggregate.\n");
8444 bgp_dest_unlock_node(dest);
8445 return CMD_WARNING_CONFIG_FAILED;
8446 }
8447 }
8448
8449 /* Make aggregate address structure. */
8450 aggregate = bgp_aggregate_new();
8451 aggregate->summary_only = summary_only;
8452 aggregate->match_med = match_med;
8453
8454 /* Network operators MUST NOT locally generate any new
8455 * announcements containing AS_SET or AS_CONFED_SET. If they have
8456 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8457 * SHOULD withdraw those routes and re-announce routes for the
8458 * aggregate or component prefixes (i.e., the more-specific routes
8459 * subsumed by the previously aggregated route) without AS_SET
8460 * or AS_CONFED_SET in the updates.
8461 */
8462 if (bgp->reject_as_sets) {
8463 if (as_set == AGGREGATE_AS_SET) {
8464 as_set_new = AGGREGATE_AS_UNSET;
8465 zlog_warn(
8466 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8467 __func__);
8468 vty_out(vty,
8469 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8470 }
8471 }
8472
8473 aggregate->as_set = as_set_new;
8474 aggregate->safi = safi;
8475 /* Override ORIGIN attribute if defined.
8476 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8477 * to IGP which is not what rfc4271 says.
8478 * This enables the same behavior, optionally.
8479 */
8480 aggregate->origin = origin;
8481
8482 if (rmap) {
8483 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8484 route_map_counter_decrement(aggregate->rmap.map);
8485 aggregate->rmap.name =
8486 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8487 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8488 route_map_counter_increment(aggregate->rmap.map);
8489 }
8490
8491 if (suppress_map) {
8492 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8493 route_map_counter_decrement(aggregate->suppress_map);
8494
8495 aggregate->suppress_map_name =
8496 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8497 aggregate->suppress_map =
8498 route_map_lookup_by_name(aggregate->suppress_map_name);
8499 route_map_counter_increment(aggregate->suppress_map);
8500 }
8501
8502 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8503
8504 /* Aggregate address insert into BGP routing table. */
8505 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8506 bgp_aggregate_free(aggregate);
8507 bgp_dest_unlock_node(dest);
8508 }
8509
8510 return CMD_SUCCESS;
8511 }
8512
8513 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8514 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8515 "as-set$as_set_s"
8516 "|summary-only$summary_only"
8517 "|route-map RMAP_NAME$rmap_name"
8518 "|origin <egp|igp|incomplete>$origin_s"
8519 "|matching-MED-only$match_med"
8520 "|suppress-map RMAP_NAME$suppress_map"
8521 "}]",
8522 NO_STR
8523 "Configure BGP aggregate entries\n"
8524 "Aggregate prefix\n"
8525 "Aggregate address\n"
8526 "Aggregate mask\n"
8527 "Generate AS set path information\n"
8528 "Filter more specific routes from updates\n"
8529 "Apply route map to aggregate network\n"
8530 "Route map name\n"
8531 "BGP origin code\n"
8532 "Remote EGP\n"
8533 "Local IGP\n"
8534 "Unknown heritage\n"
8535 "Only aggregate routes with matching MED\n"
8536 "Suppress the selected more specific routes\n"
8537 "Route map with the route selectors\n")
8538 {
8539 const char *prefix_s = NULL;
8540 safi_t safi = bgp_node_safi(vty);
8541 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8542 int as_set = AGGREGATE_AS_UNSET;
8543 char prefix_buf[PREFIX2STR_BUFFER];
8544
8545 if (addr_str) {
8546 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8547 sizeof(prefix_buf))
8548 == 0) {
8549 vty_out(vty, "%% Inconsistent address and mask\n");
8550 return CMD_WARNING_CONFIG_FAILED;
8551 }
8552 prefix_s = prefix_buf;
8553 } else
8554 prefix_s = prefix_str;
8555
8556 if (origin_s) {
8557 if (strcmp(origin_s, "egp") == 0)
8558 origin = BGP_ORIGIN_EGP;
8559 else if (strcmp(origin_s, "igp") == 0)
8560 origin = BGP_ORIGIN_IGP;
8561 else if (strcmp(origin_s, "incomplete") == 0)
8562 origin = BGP_ORIGIN_INCOMPLETE;
8563 }
8564
8565 if (as_set_s)
8566 as_set = AGGREGATE_AS_SET;
8567
8568 /* Handle configuration removal, otherwise installation. */
8569 if (no)
8570 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8571
8572 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8573 summary_only != NULL, as_set, origin,
8574 match_med != NULL, suppress_map);
8575 }
8576
8577 void bgp_free_aggregate_info(struct bgp_aggregate *aggregate)
8578 {
8579 if (aggregate->community)
8580 community_free(&aggregate->community);
8581
8582 hash_clean_and_free(&aggregate->community_hash,
8583 bgp_aggr_community_remove);
8584
8585 if (aggregate->ecommunity)
8586 ecommunity_free(&aggregate->ecommunity);
8587
8588 hash_clean_and_free(&aggregate->ecommunity_hash,
8589 bgp_aggr_ecommunity_remove);
8590
8591 if (aggregate->lcommunity)
8592 lcommunity_free(&aggregate->lcommunity);
8593
8594 hash_clean_and_free(&aggregate->lcommunity_hash,
8595 bgp_aggr_lcommunity_remove);
8596
8597 if (aggregate->aspath)
8598 aspath_free(aggregate->aspath);
8599
8600 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8601
8602 bgp_aggregate_free(aggregate);
8603 }
8604
8605 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8606 "[no] aggregate-address X:X::X:X/M$prefix [{"
8607 "as-set$as_set_s"
8608 "|summary-only$summary_only"
8609 "|route-map RMAP_NAME$rmap_name"
8610 "|origin <egp|igp|incomplete>$origin_s"
8611 "|matching-MED-only$match_med"
8612 "|suppress-map RMAP_NAME$suppress_map"
8613 "}]",
8614 NO_STR
8615 "Configure BGP aggregate entries\n"
8616 "Aggregate prefix\n"
8617 "Generate AS set path information\n"
8618 "Filter more specific routes from updates\n"
8619 "Apply route map to aggregate network\n"
8620 "Route map name\n"
8621 "BGP origin code\n"
8622 "Remote EGP\n"
8623 "Local IGP\n"
8624 "Unknown heritage\n"
8625 "Only aggregate routes with matching MED\n"
8626 "Suppress the selected more specific routes\n"
8627 "Route map with the route selectors\n")
8628 {
8629 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8630 int as_set = AGGREGATE_AS_UNSET;
8631
8632 if (origin_s) {
8633 if (strcmp(origin_s, "egp") == 0)
8634 origin = BGP_ORIGIN_EGP;
8635 else if (strcmp(origin_s, "igp") == 0)
8636 origin = BGP_ORIGIN_IGP;
8637 else if (strcmp(origin_s, "incomplete") == 0)
8638 origin = BGP_ORIGIN_INCOMPLETE;
8639 }
8640
8641 if (as_set_s)
8642 as_set = AGGREGATE_AS_SET;
8643
8644 /* Handle configuration removal, otherwise installation. */
8645 if (no)
8646 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8647 SAFI_UNICAST);
8648
8649 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8650 rmap_name, summary_only != NULL, as_set,
8651 origin, match_med != NULL, suppress_map);
8652 }
8653
8654 /* Redistribute route treatment. */
8655 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8656 const union g_addr *nexthop, ifindex_t ifindex,
8657 enum nexthop_types_t nhtype, uint8_t distance,
8658 enum blackhole_type bhtype, uint32_t metric,
8659 uint8_t type, unsigned short instance,
8660 route_tag_t tag)
8661 {
8662 struct bgp_path_info *new;
8663 struct bgp_path_info *bpi;
8664 struct bgp_path_info rmap_path;
8665 struct bgp_dest *bn;
8666 struct attr attr;
8667 struct attr *new_attr;
8668 afi_t afi;
8669 route_map_result_t ret;
8670 struct bgp_redist *red;
8671
8672 /* Make default attribute. */
8673 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8674 /*
8675 * This must not be NULL to satisfy Coverity SA
8676 */
8677 assert(attr.aspath);
8678
8679 if (p->family == AF_INET6)
8680 UNSET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP));
8681
8682 switch (nhtype) {
8683 case NEXTHOP_TYPE_IFINDEX:
8684 switch (p->family) {
8685 case AF_INET:
8686 attr.nexthop.s_addr = INADDR_ANY;
8687 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8688 attr.mp_nexthop_global_in.s_addr = INADDR_ANY;
8689 break;
8690 case AF_INET6:
8691 memset(&attr.mp_nexthop_global, 0,
8692 sizeof(attr.mp_nexthop_global));
8693 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8694 break;
8695 }
8696 break;
8697 case NEXTHOP_TYPE_IPV4:
8698 case NEXTHOP_TYPE_IPV4_IFINDEX:
8699 attr.nexthop = nexthop->ipv4;
8700 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8701 attr.mp_nexthop_global_in = nexthop->ipv4;
8702 break;
8703 case NEXTHOP_TYPE_IPV6:
8704 case NEXTHOP_TYPE_IPV6_IFINDEX:
8705 attr.mp_nexthop_global = nexthop->ipv6;
8706 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8707 break;
8708 case NEXTHOP_TYPE_BLACKHOLE:
8709 switch (p->family) {
8710 case AF_INET:
8711 attr.nexthop.s_addr = INADDR_ANY;
8712 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8713 attr.mp_nexthop_global_in.s_addr = INADDR_ANY;
8714 break;
8715 case AF_INET6:
8716 memset(&attr.mp_nexthop_global, 0,
8717 sizeof(attr.mp_nexthop_global));
8718 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8719 break;
8720 }
8721 attr.bh_type = bhtype;
8722 break;
8723 }
8724 attr.nh_type = nhtype;
8725 attr.nh_ifindex = ifindex;
8726
8727 attr.med = metric;
8728 attr.distance = distance;
8729 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8730 attr.tag = tag;
8731
8732 if (metric)
8733 bgp_attr_set_aigp_metric(&attr, metric);
8734
8735 afi = family2afi(p->family);
8736
8737 red = bgp_redist_lookup(bgp, afi, type, instance);
8738 if (red) {
8739 struct attr attr_new;
8740
8741 /* Copy attribute for modification. */
8742 attr_new = attr;
8743
8744 if (red->redist_metric_flag) {
8745 attr_new.med = red->redist_metric;
8746 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8747 }
8748
8749 /* Apply route-map. */
8750 if (red->rmap.name) {
8751 memset(&rmap_path, 0, sizeof(rmap_path));
8752 rmap_path.peer = bgp->peer_self;
8753 rmap_path.attr = &attr_new;
8754
8755 SET_FLAG(bgp->peer_self->rmap_type,
8756 PEER_RMAP_TYPE_REDISTRIBUTE);
8757
8758 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8759
8760 bgp->peer_self->rmap_type = 0;
8761
8762 if (ret == RMAP_DENYMATCH) {
8763 /* Free uninterned attribute. */
8764 bgp_attr_flush(&attr_new);
8765
8766 /* Unintern original. */
8767 aspath_unintern(&attr.aspath);
8768 bgp_redistribute_delete(bgp, p, type, instance);
8769 return;
8770 }
8771 }
8772
8773 if (bgp_in_graceful_shutdown(bgp))
8774 bgp_attr_add_gshut_community(&attr_new);
8775
8776 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8777 SAFI_UNICAST, p, NULL);
8778
8779 new_attr = bgp_attr_intern(&attr_new);
8780
8781 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8782 if (bpi->peer == bgp->peer_self
8783 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8784 break;
8785
8786 if (bpi) {
8787 /* Ensure the (source route) type is updated. */
8788 bpi->type = type;
8789 if (attrhash_cmp(bpi->attr, new_attr)
8790 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8791 bgp_attr_unintern(&new_attr);
8792 aspath_unintern(&attr.aspath);
8793 bgp_dest_unlock_node(bn);
8794 return;
8795 } else {
8796 /* The attribute is changed. */
8797 bgp_path_info_set_flag(bn, bpi,
8798 BGP_PATH_ATTR_CHANGED);
8799
8800 /* Rewrite BGP route information. */
8801 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8802 bgp_path_info_restore(bn, bpi);
8803 else
8804 bgp_aggregate_decrement(
8805 bgp, p, bpi, afi, SAFI_UNICAST);
8806 bgp_attr_unintern(&bpi->attr);
8807 bpi->attr = new_attr;
8808 bpi->uptime = monotime(NULL);
8809
8810 /* Process change. */
8811 bgp_aggregate_increment(bgp, p, bpi, afi,
8812 SAFI_UNICAST);
8813 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8814 bgp_dest_unlock_node(bn);
8815 aspath_unintern(&attr.aspath);
8816
8817 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8818 || (bgp->inst_type
8819 == BGP_INSTANCE_TYPE_DEFAULT)) {
8820
8821 vpn_leak_from_vrf_update(
8822 bgp_get_default(), bgp, bpi);
8823 }
8824 return;
8825 }
8826 }
8827
8828 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8829 bgp->peer_self, new_attr, bn);
8830 SET_FLAG(new->flags, BGP_PATH_VALID);
8831
8832 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8833 bgp_path_info_add(bn, new);
8834 bgp_dest_unlock_node(bn);
8835 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8836 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8837
8838 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8839 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8840
8841 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8842 }
8843 }
8844
8845 /* Unintern original. */
8846 aspath_unintern(&attr.aspath);
8847 }
8848
8849 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8850 unsigned short instance)
8851 {
8852 afi_t afi;
8853 struct bgp_dest *dest;
8854 struct bgp_path_info *pi;
8855 struct bgp_redist *red;
8856
8857 afi = family2afi(p->family);
8858
8859 red = bgp_redist_lookup(bgp, afi, type, instance);
8860 if (red) {
8861 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8862 SAFI_UNICAST, p, NULL);
8863
8864 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8865 if (pi->peer == bgp->peer_self && pi->type == type)
8866 break;
8867
8868 if (pi) {
8869 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8870 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8871
8872 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8873 bgp, pi);
8874 }
8875 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8876 bgp_path_info_delete(dest, pi);
8877 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8878 }
8879 bgp_dest_unlock_node(dest);
8880 }
8881 }
8882
8883 /* Withdraw specified route type's route. */
8884 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8885 unsigned short instance)
8886 {
8887 struct bgp_dest *dest;
8888 struct bgp_path_info *pi;
8889 struct bgp_table *table;
8890
8891 table = bgp->rib[afi][SAFI_UNICAST];
8892
8893 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8894 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8895 if (pi->peer == bgp->peer_self && pi->type == type
8896 && pi->instance == instance)
8897 break;
8898
8899 if (pi) {
8900 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8901 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8902
8903 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8904 bgp, pi);
8905 }
8906 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8907 pi, afi, SAFI_UNICAST);
8908 bgp_path_info_delete(dest, pi);
8909 if (!CHECK_FLAG(bgp->flags,
8910 BGP_FLAG_DELETE_IN_PROGRESS))
8911 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8912 else
8913 bgp_path_info_reap(dest, pi);
8914 }
8915 }
8916 }
8917
8918 /* Static function to display route. */
8919 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8920 struct vty *vty, json_object *json, bool wide)
8921 {
8922 int len = 0;
8923 char buf[INET6_ADDRSTRLEN];
8924
8925 if (p->family == AF_INET) {
8926 if (!json) {
8927 len = vty_out(vty, "%pFX", p);
8928 } else {
8929 json_object_string_add(json, "prefix",
8930 inet_ntop(p->family,
8931 &p->u.prefix, buf,
8932 sizeof(buf)));
8933 json_object_int_add(json, "prefixLen", p->prefixlen);
8934 json_object_string_addf(json, "network", "%pFX", p);
8935 json_object_int_add(json, "version", dest->version);
8936 }
8937 } else if (p->family == AF_ETHERNET) {
8938 len = vty_out(vty, "%pFX", p);
8939 } else if (p->family == AF_EVPN) {
8940 if (!json)
8941 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8942 else
8943 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8944 } else if (p->family == AF_FLOWSPEC) {
8945 route_vty_out_flowspec(vty, p, NULL,
8946 json ?
8947 NLRI_STRING_FORMAT_JSON_SIMPLE :
8948 NLRI_STRING_FORMAT_MIN, json);
8949 } else {
8950 if (!json)
8951 len = vty_out(vty, "%pFX", p);
8952 else {
8953 json_object_string_add(json, "prefix",
8954 inet_ntop(p->family,
8955 &p->u.prefix, buf,
8956 sizeof(buf)));
8957 json_object_int_add(json, "prefixLen", p->prefixlen);
8958 json_object_string_addf(json, "network", "%pFX", p);
8959 json_object_int_add(json, "version", dest->version);
8960 }
8961 }
8962
8963 if (!json) {
8964 len = wide ? (45 - len) : (17 - len);
8965 if (len < 1)
8966 vty_out(vty, "\n%*s", 20, " ");
8967 else
8968 vty_out(vty, "%*s", len, " ");
8969 }
8970 }
8971
8972 enum bgp_display_type {
8973 normal_list,
8974 };
8975
8976 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8977 {
8978 switch (reason) {
8979 case bgp_path_selection_none:
8980 return "Nothing to Select";
8981 case bgp_path_selection_first:
8982 return "First path received";
8983 case bgp_path_selection_evpn_sticky_mac:
8984 return "EVPN Sticky Mac";
8985 case bgp_path_selection_evpn_seq:
8986 return "EVPN sequence number";
8987 case bgp_path_selection_evpn_lower_ip:
8988 return "EVPN lower IP";
8989 case bgp_path_selection_evpn_local_path:
8990 return "EVPN local ES path";
8991 case bgp_path_selection_evpn_non_proxy:
8992 return "EVPN non proxy";
8993 case bgp_path_selection_weight:
8994 return "Weight";
8995 case bgp_path_selection_local_pref:
8996 return "Local Pref";
8997 case bgp_path_selection_accept_own:
8998 return "Accept Own";
8999 case bgp_path_selection_local_route:
9000 return "Local Route";
9001 case bgp_path_selection_aigp:
9002 return "AIGP";
9003 case bgp_path_selection_confed_as_path:
9004 return "Confederation based AS Path";
9005 case bgp_path_selection_as_path:
9006 return "AS Path";
9007 case bgp_path_selection_origin:
9008 return "Origin";
9009 case bgp_path_selection_med:
9010 return "MED";
9011 case bgp_path_selection_peer:
9012 return "Peer Type";
9013 case bgp_path_selection_confed:
9014 return "Confed Peer Type";
9015 case bgp_path_selection_igp_metric:
9016 return "IGP Metric";
9017 case bgp_path_selection_older:
9018 return "Older Path";
9019 case bgp_path_selection_router_id:
9020 return "Router ID";
9021 case bgp_path_selection_cluster_length:
9022 return "Cluster length";
9023 case bgp_path_selection_stale:
9024 return "Path Staleness";
9025 case bgp_path_selection_local_configured:
9026 return "Locally configured route";
9027 case bgp_path_selection_neighbor_ip:
9028 return "Neighbor IP";
9029 case bgp_path_selection_default:
9030 return "Nothing left to compare";
9031 }
9032 return "Invalid (internal error)";
9033 }
9034
9035 /* Print the short form route status for a bgp_path_info */
9036 static void route_vty_short_status_out(struct vty *vty,
9037 struct bgp_path_info *path,
9038 const struct prefix *p,
9039 json_object *json_path)
9040 {
9041 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9042
9043 if (json_path) {
9044
9045 /* Route status display. */
9046 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9047 json_object_boolean_true_add(json_path, "removed");
9048
9049 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9050 json_object_boolean_true_add(json_path, "stale");
9051
9052 if (path->extra && bgp_path_suppressed(path))
9053 json_object_boolean_true_add(json_path, "suppressed");
9054
9055 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9056 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9057 json_object_boolean_true_add(json_path, "valid");
9058
9059 /* Selected */
9060 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9061 json_object_boolean_true_add(json_path, "history");
9062
9063 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9064 json_object_boolean_true_add(json_path, "damped");
9065
9066 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9067 json_object_boolean_true_add(json_path, "bestpath");
9068 json_object_string_add(json_path, "selectionReason",
9069 bgp_path_selection_reason2str(
9070 path->net->reason));
9071 }
9072
9073 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9074 json_object_boolean_true_add(json_path, "multipath");
9075
9076 /* Internal route. */
9077 if ((path->peer->as)
9078 && (path->peer->as == path->peer->local_as))
9079 json_object_string_add(json_path, "pathFrom",
9080 "internal");
9081 else
9082 json_object_string_add(json_path, "pathFrom",
9083 "external");
9084
9085 return;
9086 }
9087
9088 /* RPKI validation state */
9089 rpki_state =
9090 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9091
9092 if (rpki_state == RPKI_VALID)
9093 vty_out(vty, "V");
9094 else if (rpki_state == RPKI_INVALID)
9095 vty_out(vty, "I");
9096 else if (rpki_state == RPKI_NOTFOUND)
9097 vty_out(vty, "N");
9098 else
9099 vty_out(vty, " ");
9100
9101 /* Route status display. */
9102 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9103 vty_out(vty, "R");
9104 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9105 vty_out(vty, "S");
9106 else if (bgp_path_suppressed(path))
9107 vty_out(vty, "s");
9108 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9109 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9110 vty_out(vty, "*");
9111 else
9112 vty_out(vty, " ");
9113
9114 /* Selected */
9115 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9116 vty_out(vty, "h");
9117 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9118 vty_out(vty, "d");
9119 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9120 vty_out(vty, ">");
9121 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9122 vty_out(vty, "=");
9123 else
9124 vty_out(vty, " ");
9125
9126 /* Internal route. */
9127 if (path->peer && (path->peer->as)
9128 && (path->peer->as == path->peer->local_as))
9129 vty_out(vty, "i");
9130 else
9131 vty_out(vty, " ");
9132 }
9133
9134 static char *bgp_nexthop_hostname(struct peer *peer,
9135 struct bgp_nexthop_cache *bnc)
9136 {
9137 if (peer->hostname
9138 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9139 return peer->hostname;
9140 return NULL;
9141 }
9142
9143 /* called from terminal list command */
9144 void route_vty_out(struct vty *vty, const struct prefix *p,
9145 struct bgp_path_info *path, int display, safi_t safi,
9146 json_object *json_paths, bool wide)
9147 {
9148 int len;
9149 struct attr *attr = path->attr;
9150 json_object *json_path = NULL;
9151 json_object *json_nexthops = NULL;
9152 json_object *json_nexthop_global = NULL;
9153 json_object *json_nexthop_ll = NULL;
9154 json_object *json_ext_community = NULL;
9155 char vrf_id_str[VRF_NAMSIZ] = {0};
9156 bool nexthop_self =
9157 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9158 bool nexthop_othervrf = false;
9159 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9160 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9161 char *nexthop_hostname =
9162 bgp_nexthop_hostname(path->peer, path->nexthop);
9163 char esi_buf[ESI_STR_LEN];
9164
9165 if (json_paths)
9166 json_path = json_object_new_object();
9167
9168 /* short status lead text */
9169 route_vty_short_status_out(vty, path, p, json_path);
9170
9171 if (!json_paths) {
9172 /* print prefix and mask */
9173 if (!display)
9174 route_vty_out_route(path->net, p, vty, json_path, wide);
9175 else
9176 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9177 } else {
9178 route_vty_out_route(path->net, p, vty, json_path, wide);
9179 }
9180
9181 /*
9182 * If vrf id of nexthop is different from that of prefix,
9183 * set up printable string to append
9184 */
9185 if (path->extra && path->extra->bgp_orig) {
9186 const char *self = "";
9187
9188 if (nexthop_self)
9189 self = "<";
9190
9191 nexthop_othervrf = true;
9192 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9193
9194 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9195 snprintf(vrf_id_str, sizeof(vrf_id_str),
9196 "@%s%s", VRFID_NONE_STR, self);
9197 else
9198 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9199 path->extra->bgp_orig->vrf_id, self);
9200
9201 if (path->extra->bgp_orig->inst_type
9202 != BGP_INSTANCE_TYPE_DEFAULT)
9203
9204 nexthop_vrfname = path->extra->bgp_orig->name;
9205 } else {
9206 const char *self = "";
9207
9208 if (nexthop_self)
9209 self = "<";
9210
9211 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9212 }
9213
9214 /*
9215 * For ENCAP and EVPN routes, nexthop address family is not
9216 * neccessarily the same as the prefix address family.
9217 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9218 * EVPN routes are also exchanged with a MP nexthop. Currently,
9219 * this
9220 * is only IPv4, the value will be present in either
9221 * attr->nexthop or
9222 * attr->mp_nexthop_global_in
9223 */
9224 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9225 char nexthop[128];
9226 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9227
9228 switch (af) {
9229 case AF_INET:
9230 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9231 &attr->mp_nexthop_global_in);
9232 break;
9233 case AF_INET6:
9234 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9235 &attr->mp_nexthop_global);
9236 break;
9237 default:
9238 snprintf(nexthop, sizeof(nexthop), "?");
9239 break;
9240 }
9241
9242 if (json_paths) {
9243 json_nexthop_global = json_object_new_object();
9244
9245 json_object_string_add(json_nexthop_global, "ip",
9246 nexthop);
9247
9248 if (path->peer->hostname)
9249 json_object_string_add(json_nexthop_global,
9250 "hostname",
9251 path->peer->hostname);
9252
9253 json_object_string_add(json_nexthop_global, "afi",
9254 (af == AF_INET) ? "ipv4"
9255 : "ipv6");
9256 json_object_boolean_true_add(json_nexthop_global,
9257 "used");
9258 } else {
9259 if (nexthop_hostname)
9260 len = vty_out(vty, "%s(%s)%s", nexthop,
9261 nexthop_hostname, vrf_id_str);
9262 else
9263 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9264
9265 len = wide ? (41 - len) : (16 - len);
9266 if (len < 1)
9267 vty_out(vty, "\n%*s", 36, " ");
9268 else
9269 vty_out(vty, "%*s", len, " ");
9270 }
9271 } else if (safi == SAFI_EVPN) {
9272 if (json_paths) {
9273 json_nexthop_global = json_object_new_object();
9274
9275 json_object_string_addf(json_nexthop_global, "ip",
9276 "%pI4",
9277 &attr->mp_nexthop_global_in);
9278
9279 if (path->peer->hostname)
9280 json_object_string_add(json_nexthop_global,
9281 "hostname",
9282 path->peer->hostname);
9283
9284 json_object_string_add(json_nexthop_global, "afi",
9285 "ipv4");
9286 json_object_boolean_true_add(json_nexthop_global,
9287 "used");
9288 } else {
9289 if (nexthop_hostname)
9290 len = vty_out(vty, "%pI4(%s)%s",
9291 &attr->mp_nexthop_global_in,
9292 nexthop_hostname, vrf_id_str);
9293 else
9294 len = vty_out(vty, "%pI4%s",
9295 &attr->mp_nexthop_global_in,
9296 vrf_id_str);
9297
9298 len = wide ? (41 - len) : (16 - len);
9299 if (len < 1)
9300 vty_out(vty, "\n%*s", 36, " ");
9301 else
9302 vty_out(vty, "%*s", len, " ");
9303 }
9304 } else if (safi == SAFI_FLOWSPEC) {
9305 if (attr->nexthop.s_addr != INADDR_ANY) {
9306 if (json_paths) {
9307 json_nexthop_global = json_object_new_object();
9308
9309 json_object_string_add(json_nexthop_global,
9310 "afi", "ipv4");
9311 json_object_string_addf(json_nexthop_global,
9312 "ip", "%pI4",
9313 &attr->nexthop);
9314
9315 if (path->peer->hostname)
9316 json_object_string_add(
9317 json_nexthop_global, "hostname",
9318 path->peer->hostname);
9319
9320 json_object_boolean_true_add(
9321 json_nexthop_global,
9322 "used");
9323 } else {
9324 if (nexthop_hostname)
9325 len = vty_out(vty, "%pI4(%s)%s",
9326 &attr->nexthop,
9327 nexthop_hostname,
9328 vrf_id_str);
9329 else
9330 len = vty_out(vty, "%pI4%s",
9331 &attr->nexthop,
9332 vrf_id_str);
9333
9334 len = wide ? (41 - len) : (16 - len);
9335 if (len < 1)
9336 vty_out(vty, "\n%*s", 36, " ");
9337 else
9338 vty_out(vty, "%*s", len, " ");
9339 }
9340 }
9341 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9342 if (json_paths) {
9343 json_nexthop_global = json_object_new_object();
9344
9345 json_object_string_addf(json_nexthop_global, "ip",
9346 "%pI4", &attr->nexthop);
9347
9348 if (path->peer->hostname)
9349 json_object_string_add(json_nexthop_global,
9350 "hostname",
9351 path->peer->hostname);
9352
9353 json_object_string_add(json_nexthop_global, "afi",
9354 "ipv4");
9355 json_object_boolean_true_add(json_nexthop_global,
9356 "used");
9357 } else {
9358 if (nexthop_hostname)
9359 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9360 nexthop_hostname, vrf_id_str);
9361 else
9362 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9363 vrf_id_str);
9364
9365 len = wide ? (41 - len) : (16 - len);
9366 if (len < 1)
9367 vty_out(vty, "\n%*s", 36, " ");
9368 else
9369 vty_out(vty, "%*s", len, " ");
9370 }
9371 }
9372
9373 /* IPv6 Next Hop */
9374 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9375 if (json_paths) {
9376 json_nexthop_global = json_object_new_object();
9377 json_object_string_addf(json_nexthop_global, "ip",
9378 "%pI6",
9379 &attr->mp_nexthop_global);
9380
9381 if (path->peer->hostname)
9382 json_object_string_add(json_nexthop_global,
9383 "hostname",
9384 path->peer->hostname);
9385
9386 json_object_string_add(json_nexthop_global, "afi",
9387 "ipv6");
9388 json_object_string_add(json_nexthop_global, "scope",
9389 "global");
9390
9391 /* We display both LL & GL if both have been
9392 * received */
9393 if ((attr->mp_nexthop_len
9394 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9395 || (path->peer->conf_if)) {
9396 json_nexthop_ll = json_object_new_object();
9397 json_object_string_addf(
9398 json_nexthop_ll, "ip", "%pI6",
9399 &attr->mp_nexthop_local);
9400
9401 if (path->peer->hostname)
9402 json_object_string_add(
9403 json_nexthop_ll, "hostname",
9404 path->peer->hostname);
9405
9406 json_object_string_add(json_nexthop_ll, "afi",
9407 "ipv6");
9408 json_object_string_add(json_nexthop_ll, "scope",
9409 "link-local");
9410
9411 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9412 &attr->mp_nexthop_local)
9413 != 0)
9414 && !attr->mp_nexthop_prefer_global)
9415 json_object_boolean_true_add(
9416 json_nexthop_ll, "used");
9417 else
9418 json_object_boolean_true_add(
9419 json_nexthop_global, "used");
9420 } else
9421 json_object_boolean_true_add(
9422 json_nexthop_global, "used");
9423 } else {
9424 /* Display LL if LL/Global both in table unless
9425 * prefer-global is set */
9426 if (((attr->mp_nexthop_len
9427 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9428 && !attr->mp_nexthop_prefer_global)
9429 || (path->peer->conf_if)) {
9430 if (path->peer->conf_if) {
9431 len = vty_out(vty, "%s",
9432 path->peer->conf_if);
9433 /* len of IPv6 addr + max len of def
9434 * ifname */
9435 len = wide ? (41 - len) : (16 - len);
9436
9437 if (len < 1)
9438 vty_out(vty, "\n%*s", 36, " ");
9439 else
9440 vty_out(vty, "%*s", len, " ");
9441 } else {
9442 if (nexthop_hostname)
9443 len = vty_out(
9444 vty, "%pI6(%s)%s",
9445 &attr->mp_nexthop_local,
9446 nexthop_hostname,
9447 vrf_id_str);
9448 else
9449 len = vty_out(
9450 vty, "%pI6%s",
9451 &attr->mp_nexthop_local,
9452 vrf_id_str);
9453
9454 len = wide ? (41 - len) : (16 - len);
9455
9456 if (len < 1)
9457 vty_out(vty, "\n%*s", 36, " ");
9458 else
9459 vty_out(vty, "%*s", len, " ");
9460 }
9461 } else {
9462 if (nexthop_hostname)
9463 len = vty_out(vty, "%pI6(%s)%s",
9464 &attr->mp_nexthop_global,
9465 nexthop_hostname,
9466 vrf_id_str);
9467 else
9468 len = vty_out(vty, "%pI6%s",
9469 &attr->mp_nexthop_global,
9470 vrf_id_str);
9471
9472 len = wide ? (41 - len) : (16 - len);
9473
9474 if (len < 1)
9475 vty_out(vty, "\n%*s", 36, " ");
9476 else
9477 vty_out(vty, "%*s", len, " ");
9478 }
9479 }
9480 }
9481
9482 /* MED/Metric */
9483 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9484 if (json_paths)
9485 json_object_int_add(json_path, "metric", attr->med);
9486 else if (wide)
9487 vty_out(vty, "%7u", attr->med);
9488 else
9489 vty_out(vty, "%10u", attr->med);
9490 else if (!json_paths) {
9491 if (wide)
9492 vty_out(vty, "%*s", 7, " ");
9493 else
9494 vty_out(vty, "%*s", 10, " ");
9495 }
9496
9497 /* Local Pref */
9498 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9499 if (json_paths)
9500 json_object_int_add(json_path, "locPrf",
9501 attr->local_pref);
9502 else
9503 vty_out(vty, "%7u", attr->local_pref);
9504 else if (!json_paths)
9505 vty_out(vty, " ");
9506
9507 if (json_paths)
9508 json_object_int_add(json_path, "weight", attr->weight);
9509 else
9510 vty_out(vty, "%7u ", attr->weight);
9511
9512 if (json_paths)
9513 json_object_string_addf(json_path, "peerId", "%pSU",
9514 &path->peer->su);
9515
9516 /* Print aspath */
9517 if (attr->aspath) {
9518 if (json_paths)
9519 json_object_string_add(json_path, "path",
9520 attr->aspath->str);
9521 else
9522 aspath_print_vty(vty, attr->aspath);
9523 }
9524
9525 /* Print origin */
9526 if (json_paths)
9527 json_object_string_add(json_path, "origin",
9528 bgp_origin_long_str[attr->origin]);
9529 else
9530 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9531
9532 if (json_paths) {
9533 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9534 json_object_string_add(json_path, "esi",
9535 esi_to_str(&attr->esi,
9536 esi_buf, sizeof(esi_buf)));
9537 }
9538 if (safi == SAFI_EVPN &&
9539 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9540 json_ext_community = json_object_new_object();
9541 json_object_string_add(
9542 json_ext_community, "string",
9543 bgp_attr_get_ecommunity(attr)->str);
9544 json_object_object_add(json_path,
9545 "extendedCommunity",
9546 json_ext_community);
9547 }
9548
9549 if (nexthop_self)
9550 json_object_boolean_true_add(json_path,
9551 "announceNexthopSelf");
9552 if (nexthop_othervrf) {
9553 json_object_string_add(json_path, "nhVrfName",
9554 nexthop_vrfname);
9555
9556 json_object_int_add(json_path, "nhVrfId",
9557 ((nexthop_vrfid == VRF_UNKNOWN)
9558 ? -1
9559 : (int)nexthop_vrfid));
9560 }
9561 }
9562
9563 if (json_paths) {
9564 if (json_nexthop_global || json_nexthop_ll) {
9565 json_nexthops = json_object_new_array();
9566
9567 if (json_nexthop_global)
9568 json_object_array_add(json_nexthops,
9569 json_nexthop_global);
9570
9571 if (json_nexthop_ll)
9572 json_object_array_add(json_nexthops,
9573 json_nexthop_ll);
9574
9575 json_object_object_add(json_path, "nexthops",
9576 json_nexthops);
9577 }
9578
9579 json_object_array_add(json_paths, json_path);
9580 } else {
9581 vty_out(vty, "\n");
9582
9583 if (safi == SAFI_EVPN) {
9584 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9585 /* XXX - add these params to the json out */
9586 vty_out(vty, "%*s", 20, " ");
9587 vty_out(vty, "ESI:%s",
9588 esi_to_str(&attr->esi, esi_buf,
9589 sizeof(esi_buf)));
9590
9591 vty_out(vty, "\n");
9592 }
9593 if (attr->flag &
9594 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9595 vty_out(vty, "%*s", 20, " ");
9596 vty_out(vty, "%s\n",
9597 bgp_attr_get_ecommunity(attr)->str);
9598 }
9599 }
9600
9601 #ifdef ENABLE_BGP_VNC
9602 /* prints an additional line, indented, with VNC info, if
9603 * present */
9604 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9605 rfapi_vty_out_vncinfo(vty, p, path, safi);
9606 #endif
9607 }
9608 }
9609
9610 /* called from terminal list command */
9611 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9612 const struct prefix *p, struct attr *attr, safi_t safi,
9613 bool use_json, json_object *json_ar, bool wide)
9614 {
9615 json_object *json_status = NULL;
9616 json_object *json_net = NULL;
9617 int len;
9618 char buff[BUFSIZ];
9619
9620 /* Route status display. */
9621 if (use_json) {
9622 json_status = json_object_new_object();
9623 json_net = json_object_new_object();
9624 } else {
9625 vty_out(vty, " *");
9626 vty_out(vty, ">");
9627 vty_out(vty, " ");
9628 }
9629
9630 /* print prefix and mask */
9631 if (use_json) {
9632 if (safi == SAFI_EVPN)
9633 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9634 else if (p->family == AF_INET || p->family == AF_INET6) {
9635 json_object_string_add(
9636 json_net, "addrPrefix",
9637 inet_ntop(p->family, &p->u.prefix, buff,
9638 BUFSIZ));
9639 json_object_int_add(json_net, "prefixLen",
9640 p->prefixlen);
9641 json_object_string_addf(json_net, "network", "%pFX", p);
9642 }
9643 } else
9644 route_vty_out_route(dest, p, vty, NULL, wide);
9645
9646 /* Print attribute */
9647 if (attr) {
9648 if (use_json) {
9649 if (p->family == AF_INET &&
9650 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9651 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9652 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9653 json_object_string_addf(
9654 json_net, "nextHop", "%pI4",
9655 &attr->mp_nexthop_global_in);
9656 else
9657 json_object_string_addf(
9658 json_net, "nextHop", "%pI4",
9659 &attr->nexthop);
9660 } else if (p->family == AF_INET6 ||
9661 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9662 json_object_string_addf(
9663 json_net, "nextHopGlobal", "%pI6",
9664 &attr->mp_nexthop_global);
9665 } else if (p->family == AF_EVPN &&
9666 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9667 json_object_string_addf(
9668 json_net, "nextHop", "%pI4",
9669 &attr->mp_nexthop_global_in);
9670 }
9671
9672 if (attr->flag
9673 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9674 json_object_int_add(json_net, "metric",
9675 attr->med);
9676
9677 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9678 json_object_int_add(json_net, "locPrf",
9679 attr->local_pref);
9680
9681 json_object_int_add(json_net, "weight", attr->weight);
9682
9683 /* Print aspath */
9684 if (attr->aspath)
9685 json_object_string_add(json_net, "path",
9686 attr->aspath->str);
9687
9688 /* Print origin */
9689 #if CONFDATE > 20231208
9690 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9691 #endif
9692 json_object_string_add(json_net, "bgpOriginCode",
9693 bgp_origin_str[attr->origin]);
9694 json_object_string_add(
9695 json_net, "origin",
9696 bgp_origin_long_str[attr->origin]);
9697 } else {
9698 if (p->family == AF_INET &&
9699 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9700 safi == SAFI_EVPN ||
9701 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9702 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9703 || safi == SAFI_EVPN)
9704 vty_out(vty, "%-16pI4",
9705 &attr->mp_nexthop_global_in);
9706 else if (wide)
9707 vty_out(vty, "%-41pI4", &attr->nexthop);
9708 else
9709 vty_out(vty, "%-16pI4", &attr->nexthop);
9710 } else if (p->family == AF_INET6 ||
9711 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9712 len = vty_out(vty, "%pI6",
9713 &attr->mp_nexthop_global);
9714 len = wide ? (41 - len) : (16 - len);
9715 if (len < 1)
9716 vty_out(vty, "\n%*s", 36, " ");
9717 else
9718 vty_out(vty, "%*s", len, " ");
9719 }
9720 if (attr->flag
9721 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9722 if (wide)
9723 vty_out(vty, "%7u", attr->med);
9724 else
9725 vty_out(vty, "%10u", attr->med);
9726 else if (wide)
9727 vty_out(vty, " ");
9728 else
9729 vty_out(vty, " ");
9730
9731 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9732 vty_out(vty, "%7u", attr->local_pref);
9733 else
9734 vty_out(vty, " ");
9735
9736 vty_out(vty, "%7u ", attr->weight);
9737
9738 /* Print aspath */
9739 if (attr->aspath)
9740 aspath_print_vty(vty, attr->aspath);
9741
9742 /* Print origin */
9743 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9744 }
9745 }
9746 if (use_json) {
9747 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9748
9749 #if CONFDATE > 20231208
9750 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9751 #endif
9752 json_object_boolean_true_add(json_status, "*");
9753 json_object_boolean_true_add(json_status, ">");
9754 json_object_boolean_true_add(json_net, "valid");
9755 json_object_boolean_true_add(json_net, "best");
9756
9757 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9758 json_object_boolean_true_add(json_status, "=");
9759 json_object_boolean_true_add(json_net, "multipath");
9760 }
9761 json_object_object_add(json_net, "appliedStatusSymbols",
9762 json_status);
9763 json_object_object_addf(json_ar, json_net, "%pFX", p);
9764 } else
9765 vty_out(vty, "\n");
9766 }
9767
9768 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9769 struct bgp_path_info *path, int display, safi_t safi,
9770 json_object *json)
9771 {
9772 json_object *json_out = NULL;
9773 struct attr *attr;
9774 mpls_label_t label = MPLS_INVALID_LABEL;
9775
9776 if (!path->extra)
9777 return;
9778
9779 if (json)
9780 json_out = json_object_new_object();
9781
9782 /* short status lead text */
9783 route_vty_short_status_out(vty, path, p, json_out);
9784
9785 /* print prefix and mask */
9786 if (json == NULL) {
9787 if (!display)
9788 route_vty_out_route(path->net, p, vty, NULL, false);
9789 else
9790 vty_out(vty, "%*s", 17, " ");
9791 }
9792
9793 /* Print attribute */
9794 attr = path->attr;
9795 if (((p->family == AF_INET) &&
9796 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9797 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9798 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9799 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9800 || safi == SAFI_EVPN) {
9801 if (json)
9802 json_object_string_addf(
9803 json_out, "mpNexthopGlobalIn", "%pI4",
9804 &attr->mp_nexthop_global_in);
9805 else
9806 vty_out(vty, "%-16pI4",
9807 &attr->mp_nexthop_global_in);
9808 } else {
9809 if (json)
9810 json_object_string_addf(json_out, "nexthop",
9811 "%pI4", &attr->nexthop);
9812 else
9813 vty_out(vty, "%-16pI4", &attr->nexthop);
9814 }
9815 } else if (((p->family == AF_INET6) &&
9816 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9817 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9818 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9819 char buf_a[512];
9820
9821 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9822 if (json)
9823 json_object_string_addf(
9824 json_out, "mpNexthopGlobalIn", "%pI6",
9825 &attr->mp_nexthop_global);
9826 else
9827 vty_out(vty, "%s",
9828 inet_ntop(AF_INET6,
9829 &attr->mp_nexthop_global,
9830 buf_a, sizeof(buf_a)));
9831 } else if (attr->mp_nexthop_len
9832 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9833 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9834 &attr->mp_nexthop_global,
9835 &attr->mp_nexthop_local);
9836 if (json)
9837 json_object_string_add(json_out,
9838 "mpNexthopGlobalLocal",
9839 buf_a);
9840 else
9841 vty_out(vty, "%s", buf_a);
9842 }
9843 }
9844
9845 label = decode_label(&path->extra->label[0]);
9846
9847 if (bgp_is_valid_label(&label)) {
9848 if (json) {
9849 json_object_int_add(json_out, "notag", label);
9850 json_object_array_add(json, json_out);
9851 } else {
9852 vty_out(vty, "notag/%d", label);
9853 vty_out(vty, "\n");
9854 }
9855 } else if (!json)
9856 vty_out(vty, "\n");
9857 }
9858
9859 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9860 struct bgp_path_info *path, int display,
9861 json_object *json_paths)
9862 {
9863 struct attr *attr;
9864 json_object *json_path = NULL;
9865 json_object *json_nexthop = NULL;
9866 json_object *json_overlay = NULL;
9867
9868 if (!path->extra)
9869 return;
9870
9871 if (json_paths) {
9872 json_path = json_object_new_object();
9873 json_overlay = json_object_new_object();
9874 json_nexthop = json_object_new_object();
9875 }
9876
9877 /* short status lead text */
9878 route_vty_short_status_out(vty, path, p, json_path);
9879
9880 /* print prefix and mask */
9881 if (!display)
9882 route_vty_out_route(path->net, p, vty, json_path, false);
9883 else
9884 vty_out(vty, "%*s", 17, " ");
9885
9886 /* Print attribute */
9887 attr = path->attr;
9888 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9889
9890 switch (af) {
9891 case AF_INET:
9892 if (!json_path) {
9893 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9894 } else {
9895 json_object_string_addf(json_nexthop, "ip", "%pI4",
9896 &attr->mp_nexthop_global_in);
9897
9898 json_object_string_add(json_nexthop, "afi", "ipv4");
9899
9900 json_object_object_add(json_path, "nexthop",
9901 json_nexthop);
9902 }
9903 break;
9904 case AF_INET6:
9905 if (!json_path) {
9906 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9907 &attr->mp_nexthop_local);
9908 } else {
9909 json_object_string_addf(json_nexthop, "ipv6Global",
9910 "%pI6",
9911 &attr->mp_nexthop_global);
9912
9913 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9914 "%pI6",
9915 &attr->mp_nexthop_local);
9916
9917 json_object_string_add(json_nexthop, "afi", "ipv6");
9918
9919 json_object_object_add(json_path, "nexthop",
9920 json_nexthop);
9921 }
9922 break;
9923 default:
9924 if (!json_path) {
9925 vty_out(vty, "?");
9926 } else {
9927 json_object_string_add(json_nexthop, "error",
9928 "Unsupported address-family");
9929 }
9930 }
9931
9932 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9933
9934 if (!json_path)
9935 vty_out(vty, "/%pIA", &eo->gw_ip);
9936 else
9937 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9938
9939 if (bgp_attr_get_ecommunity(attr)) {
9940 char *mac = NULL;
9941 struct ecommunity_val *routermac = ecommunity_lookup(
9942 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9943 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9944
9945 if (routermac)
9946 mac = ecom_mac2str((char *)routermac->val);
9947 if (mac) {
9948 if (!json_path) {
9949 vty_out(vty, "/%s", mac);
9950 } else {
9951 json_object_string_add(json_overlay, "rmac",
9952 mac);
9953 }
9954 XFREE(MTYPE_TMP, mac);
9955 }
9956 }
9957
9958 if (!json_path) {
9959 vty_out(vty, "\n");
9960 } else {
9961 json_object_object_add(json_path, "overlay", json_overlay);
9962
9963 json_object_array_add(json_paths, json_path);
9964 }
9965 }
9966
9967 /* dampening route */
9968 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9969 struct bgp_path_info *path, int display,
9970 afi_t afi, safi_t safi, bool use_json,
9971 json_object *json_paths)
9972 {
9973 struct attr *attr = path->attr;
9974 int len;
9975 char timebuf[BGP_UPTIME_LEN];
9976 json_object *json_path = NULL;
9977
9978 if (use_json)
9979 json_path = json_object_new_object();
9980
9981 /* short status lead text */
9982 route_vty_short_status_out(vty, path, p, json_path);
9983
9984 /* print prefix and mask */
9985 if (!use_json) {
9986 if (!display)
9987 route_vty_out_route(path->net, p, vty, NULL, false);
9988 else
9989 vty_out(vty, "%*s", 17, " ");
9990
9991 len = vty_out(vty, "%s", path->peer->host);
9992 len = 17 - len;
9993
9994 if (len < 1)
9995 vty_out(vty, "\n%*s", 34, " ");
9996 else
9997 vty_out(vty, "%*s", len, " ");
9998
9999 vty_out(vty, "%s ",
10000 bgp_damp_reuse_time_vty(vty, path, timebuf,
10001 BGP_UPTIME_LEN, afi, safi,
10002 use_json, NULL));
10003
10004 if (attr->aspath)
10005 aspath_print_vty(vty, attr->aspath);
10006
10007 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10008
10009 vty_out(vty, "\n");
10010 } else {
10011 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
10012 safi, use_json, json_path);
10013
10014 if (attr->aspath)
10015 json_object_string_add(json_path, "asPath",
10016 attr->aspath->str);
10017
10018 json_object_string_add(json_path, "origin",
10019 bgp_origin_str[attr->origin]);
10020 json_object_string_add(json_path, "peerHost", path->peer->host);
10021
10022 json_object_array_add(json_paths, json_path);
10023 }
10024 }
10025
10026 /* flap route */
10027 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
10028 struct bgp_path_info *path, int display,
10029 afi_t afi, safi_t safi, bool use_json,
10030 json_object *json_paths)
10031 {
10032 struct attr *attr = path->attr;
10033 struct bgp_damp_info *bdi;
10034 char timebuf[BGP_UPTIME_LEN];
10035 int len;
10036 json_object *json_path = NULL;
10037
10038 if (!path->extra)
10039 return;
10040
10041 if (use_json)
10042 json_path = json_object_new_object();
10043
10044 bdi = path->extra->damp_info;
10045
10046 /* short status lead text */
10047 route_vty_short_status_out(vty, path, p, json_path);
10048
10049 if (!use_json) {
10050 if (!display)
10051 route_vty_out_route(path->net, p, vty, NULL, false);
10052 else
10053 vty_out(vty, "%*s", 17, " ");
10054
10055 len = vty_out(vty, "%s", path->peer->host);
10056 len = 16 - len;
10057 if (len < 1)
10058 vty_out(vty, "\n%*s", 33, " ");
10059 else
10060 vty_out(vty, "%*s", len, " ");
10061
10062 len = vty_out(vty, "%d", bdi->flap);
10063 len = 5 - len;
10064 if (len < 1)
10065 vty_out(vty, " ");
10066 else
10067 vty_out(vty, "%*s", len, " ");
10068
10069 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10070 BGP_UPTIME_LEN, 0, NULL));
10071
10072 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10073 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10074 vty_out(vty, "%s ",
10075 bgp_damp_reuse_time_vty(vty, path, timebuf,
10076 BGP_UPTIME_LEN, afi,
10077 safi, use_json, NULL));
10078 else
10079 vty_out(vty, "%*s ", 8, " ");
10080
10081 if (attr->aspath)
10082 aspath_print_vty(vty, attr->aspath);
10083
10084 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10085
10086 vty_out(vty, "\n");
10087 } else {
10088 json_object_string_add(json_path, "peerHost", path->peer->host);
10089 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10090
10091 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10092 json_path);
10093
10094 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10095 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10096 bgp_damp_reuse_time_vty(vty, path, timebuf,
10097 BGP_UPTIME_LEN, afi, safi,
10098 use_json, json_path);
10099
10100 if (attr->aspath)
10101 json_object_string_add(json_path, "asPath",
10102 attr->aspath->str);
10103
10104 json_object_string_add(json_path, "origin",
10105 bgp_origin_str[attr->origin]);
10106
10107 json_object_array_add(json_paths, json_path);
10108 }
10109 }
10110
10111 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10112 int *first, const char *header,
10113 json_object *json_adv_to)
10114 {
10115 json_object *json_peer = NULL;
10116
10117 if (json_adv_to) {
10118 /* 'advertised-to' is a dictionary of peers we have advertised
10119 * this
10120 * prefix too. The key is the peer's IP or swpX, the value is
10121 * the
10122 * hostname if we know it and "" if not.
10123 */
10124 json_peer = json_object_new_object();
10125
10126 if (peer->hostname)
10127 json_object_string_add(json_peer, "hostname",
10128 peer->hostname);
10129
10130 if (peer->conf_if)
10131 json_object_object_add(json_adv_to, peer->conf_if,
10132 json_peer);
10133 else
10134 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10135 &peer->su);
10136 } else {
10137 if (*first) {
10138 vty_out(vty, "%s", header);
10139 *first = 0;
10140 }
10141
10142 if (peer->hostname
10143 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10144 if (peer->conf_if)
10145 vty_out(vty, " %s(%s)", peer->hostname,
10146 peer->conf_if);
10147 else
10148 vty_out(vty, " %s(%pSU)", peer->hostname,
10149 &peer->su);
10150 } else {
10151 if (peer->conf_if)
10152 vty_out(vty, " %s", peer->conf_if);
10153 else
10154 vty_out(vty, " %pSU", &peer->su);
10155 }
10156 }
10157 }
10158
10159 static void route_vty_out_tx_ids(struct vty *vty,
10160 struct bgp_addpath_info_data *d)
10161 {
10162 int i;
10163
10164 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10165 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10166 d->addpath_tx_id[i],
10167 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10168 }
10169 }
10170
10171 static void route_vty_out_detail_es_info(struct vty *vty,
10172 struct bgp_path_info *pi,
10173 struct attr *attr,
10174 json_object *json_path)
10175 {
10176 char esi_buf[ESI_STR_LEN];
10177 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10178 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10179 ATTR_ES_PEER_ROUTER);
10180 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10181 ATTR_ES_PEER_ACTIVE);
10182 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10183 ATTR_ES_PEER_PROXY);
10184 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10185 if (json_path) {
10186 json_object *json_es_info = NULL;
10187
10188 json_object_string_add(
10189 json_path, "esi",
10190 esi_buf);
10191 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10192 json_es_info = json_object_new_object();
10193 if (es_local)
10194 json_object_boolean_true_add(
10195 json_es_info, "localEs");
10196 if (peer_active)
10197 json_object_boolean_true_add(
10198 json_es_info, "peerActive");
10199 if (peer_proxy)
10200 json_object_boolean_true_add(
10201 json_es_info, "peerProxy");
10202 if (peer_router)
10203 json_object_boolean_true_add(
10204 json_es_info, "peerRouter");
10205 if (attr->mm_sync_seqnum)
10206 json_object_int_add(
10207 json_es_info, "peerSeq",
10208 attr->mm_sync_seqnum);
10209 json_object_object_add(
10210 json_path, "es_info",
10211 json_es_info);
10212 }
10213 } else {
10214 if (bgp_evpn_attr_is_sync(attr))
10215 vty_out(vty,
10216 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10217 esi_buf,
10218 es_local ? "local-es":"",
10219 peer_proxy ? "proxy " : "",
10220 peer_active ? "active ":"",
10221 peer_router ? "router ":"",
10222 attr->mm_sync_seqnum);
10223 else
10224 vty_out(vty, " ESI %s %s\n",
10225 esi_buf,
10226 es_local ? "local-es":"");
10227 }
10228 }
10229
10230 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10231 const struct prefix *p, struct bgp_path_info *path,
10232 afi_t afi, safi_t safi,
10233 enum rpki_states rpki_curr_state,
10234 json_object *json_paths)
10235 {
10236 char buf[INET6_ADDRSTRLEN];
10237 char tag_buf[30];
10238 struct attr *attr = path->attr;
10239 time_t tbuf;
10240 json_object *json_bestpath = NULL;
10241 json_object *json_cluster_list = NULL;
10242 json_object *json_cluster_list_list = NULL;
10243 json_object *json_ext_community = NULL;
10244 json_object *json_last_update = NULL;
10245 json_object *json_pmsi = NULL;
10246 json_object *json_nexthop_global = NULL;
10247 json_object *json_nexthop_ll = NULL;
10248 json_object *json_nexthops = NULL;
10249 json_object *json_path = NULL;
10250 json_object *json_peer = NULL;
10251 json_object *json_string = NULL;
10252 json_object *json_adv_to = NULL;
10253 int first = 0;
10254 struct listnode *node, *nnode;
10255 struct peer *peer;
10256 bool addpath_capable;
10257 int has_adj;
10258 unsigned int first_as;
10259 bool nexthop_self =
10260 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10261 int i;
10262 char *nexthop_hostname =
10263 bgp_nexthop_hostname(path->peer, path->nexthop);
10264 uint32_t ttl = 0;
10265 uint32_t bos = 0;
10266 uint32_t exp = 0;
10267 mpls_label_t label = MPLS_INVALID_LABEL;
10268 tag_buf[0] = '\0';
10269 struct bgp_path_info *bpi_ultimate =
10270 bgp_get_imported_bpi_ultimate(path);
10271
10272 if (json_paths) {
10273 json_path = json_object_new_object();
10274 json_peer = json_object_new_object();
10275 json_nexthop_global = json_object_new_object();
10276 }
10277
10278 if (safi == SAFI_EVPN) {
10279 if (!json_paths)
10280 vty_out(vty, " Route %pFX", p);
10281 }
10282
10283 if (path->extra) {
10284 if (path->extra && path->extra->num_labels) {
10285 bgp_evpn_label2str(path->extra->label,
10286 path->extra->num_labels, tag_buf,
10287 sizeof(tag_buf));
10288 }
10289 if (safi == SAFI_EVPN) {
10290 if (!json_paths) {
10291 if (tag_buf[0] != '\0')
10292 vty_out(vty, " VNI %s", tag_buf);
10293 } else {
10294 if (tag_buf[0])
10295 json_object_string_add(json_path, "vni",
10296 tag_buf);
10297 }
10298 }
10299 }
10300
10301 if (safi == SAFI_EVPN
10302 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10303 char gwip_buf[INET6_ADDRSTRLEN];
10304
10305 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10306 sizeof(gwip_buf));
10307
10308 if (json_paths)
10309 json_object_string_add(json_path, "gatewayIP",
10310 gwip_buf);
10311 else
10312 vty_out(vty, " Gateway IP %s", gwip_buf);
10313 }
10314
10315 if (safi == SAFI_EVPN && !json_path)
10316 vty_out(vty, "\n");
10317
10318
10319 if (path->extra && path->extra->parent && !json_paths) {
10320 struct bgp_path_info *parent_ri;
10321 struct bgp_dest *dest, *pdest;
10322
10323 parent_ri = (struct bgp_path_info *)path->extra->parent;
10324 dest = parent_ri->net;
10325 if (dest && dest->pdest) {
10326 pdest = dest->pdest;
10327 if (is_pi_family_evpn(parent_ri)) {
10328 vty_out(vty, " Imported from ");
10329 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10330 (struct prefix_rd *)bgp_dest_get_prefix(
10331 pdest));
10332 vty_out(vty, ":%pFX, VNI %s",
10333 (struct prefix_evpn *)
10334 bgp_dest_get_prefix(dest),
10335 tag_buf);
10336 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10337 vty_out(vty, ", L3NHG %s",
10338 CHECK_FLAG(
10339 attr->es_flags,
10340 ATTR_ES_L3_NHG_ACTIVE)
10341 ? "active"
10342 : "inactive");
10343 vty_out(vty, "\n");
10344
10345 } else {
10346 vty_out(vty, " Imported from ");
10347 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10348 (struct prefix_rd *)bgp_dest_get_prefix(
10349 pdest));
10350 vty_out(vty, ":%pFX\n",
10351 (struct prefix_evpn *)
10352 bgp_dest_get_prefix(dest));
10353 }
10354 }
10355 }
10356
10357 /* Line1 display AS-path, Aggregator */
10358 if (attr->aspath) {
10359 if (json_paths) {
10360 if (!attr->aspath->json)
10361 aspath_str_update(attr->aspath, true);
10362 json_object_lock(attr->aspath->json);
10363 json_object_object_add(json_path, "aspath",
10364 attr->aspath->json);
10365 } else {
10366 if (attr->aspath->segments)
10367 vty_out(vty, " %s", attr->aspath->str);
10368 else
10369 vty_out(vty, " Local");
10370 }
10371 }
10372
10373 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10374 if (json_paths)
10375 json_object_boolean_true_add(json_path, "removed");
10376 else
10377 vty_out(vty, ", (removed)");
10378 }
10379
10380 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10381 if (json_paths)
10382 json_object_boolean_true_add(json_path, "stale");
10383 else
10384 vty_out(vty, ", (stale)");
10385 }
10386
10387 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10388 if (json_paths) {
10389 json_object_int_add(json_path, "aggregatorAs",
10390 attr->aggregator_as);
10391 json_object_string_addf(json_path, "aggregatorId",
10392 "%pI4", &attr->aggregator_addr);
10393 } else {
10394 vty_out(vty, ", (aggregated by %u %pI4)",
10395 attr->aggregator_as, &attr->aggregator_addr);
10396 }
10397 }
10398
10399 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10400 PEER_FLAG_REFLECTOR_CLIENT)) {
10401 if (json_paths)
10402 json_object_boolean_true_add(json_path,
10403 "rxedFromRrClient");
10404 else
10405 vty_out(vty, ", (Received from a RR-client)");
10406 }
10407
10408 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10409 PEER_FLAG_RSERVER_CLIENT)) {
10410 if (json_paths)
10411 json_object_boolean_true_add(json_path,
10412 "rxedFromRsClient");
10413 else
10414 vty_out(vty, ", (Received from a RS-client)");
10415 }
10416
10417 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10418 if (json_paths)
10419 json_object_boolean_true_add(json_path,
10420 "dampeningHistoryEntry");
10421 else
10422 vty_out(vty, ", (history entry)");
10423 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10424 if (json_paths)
10425 json_object_boolean_true_add(json_path,
10426 "dampeningSuppressed");
10427 else
10428 vty_out(vty, ", (suppressed due to dampening)");
10429 }
10430
10431 if (!json_paths)
10432 vty_out(vty, "\n");
10433
10434 /* Line2 display Next-hop, Neighbor, Router-id */
10435 /* Display the nexthop */
10436
10437 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10438 p->family == AF_EVPN) &&
10439 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10440 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10441 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10442 || safi == SAFI_EVPN) {
10443 if (json_paths) {
10444 json_object_string_addf(
10445 json_nexthop_global, "ip", "%pI4",
10446 &attr->mp_nexthop_global_in);
10447
10448 if (path->peer->hostname)
10449 json_object_string_add(
10450 json_nexthop_global, "hostname",
10451 path->peer->hostname);
10452 } else {
10453 if (nexthop_hostname)
10454 vty_out(vty, " %pI4(%s)",
10455 &attr->mp_nexthop_global_in,
10456 nexthop_hostname);
10457 else
10458 vty_out(vty, " %pI4",
10459 &attr->mp_nexthop_global_in);
10460 }
10461 } else {
10462 if (json_paths) {
10463 json_object_string_addf(json_nexthop_global,
10464 "ip", "%pI4",
10465 &attr->nexthop);
10466
10467 if (path->peer->hostname)
10468 json_object_string_add(
10469 json_nexthop_global, "hostname",
10470 path->peer->hostname);
10471 } else {
10472 if (nexthop_hostname)
10473 vty_out(vty, " %pI4(%s)",
10474 &attr->nexthop,
10475 nexthop_hostname);
10476 else
10477 vty_out(vty, " %pI4",
10478 &attr->nexthop);
10479 }
10480 }
10481
10482 if (json_paths)
10483 json_object_string_add(json_nexthop_global, "afi",
10484 "ipv4");
10485 } else {
10486 if (json_paths) {
10487 json_object_string_addf(json_nexthop_global, "ip",
10488 "%pI6",
10489 &attr->mp_nexthop_global);
10490
10491 if (path->peer->hostname)
10492 json_object_string_add(json_nexthop_global,
10493 "hostname",
10494 path->peer->hostname);
10495
10496 json_object_string_add(json_nexthop_global, "afi",
10497 "ipv6");
10498 json_object_string_add(json_nexthop_global, "scope",
10499 "global");
10500 } else {
10501 if (nexthop_hostname)
10502 vty_out(vty, " %pI6(%s)",
10503 &attr->mp_nexthop_global,
10504 nexthop_hostname);
10505 else
10506 vty_out(vty, " %pI6",
10507 &attr->mp_nexthop_global);
10508 }
10509 }
10510
10511 /* Display the IGP cost or 'inaccessible' */
10512 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10513 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10514
10515 if (json_paths) {
10516 json_object_boolean_false_add(json_nexthop_global,
10517 "accessible");
10518 json_object_boolean_add(json_nexthop_global,
10519 "importCheckEnabled", import);
10520 } else {
10521 vty_out(vty, " (inaccessible%s)",
10522 import ? ", import-check enabled" : "");
10523 }
10524 } else {
10525 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10526 if (json_paths)
10527 json_object_int_add(
10528 json_nexthop_global, "metric",
10529 bpi_ultimate->extra->igpmetric);
10530 else
10531 vty_out(vty, " (metric %u)",
10532 bpi_ultimate->extra->igpmetric);
10533 }
10534
10535 /* IGP cost is 0, display this only for json */
10536 else {
10537 if (json_paths)
10538 json_object_int_add(json_nexthop_global,
10539 "metric", 0);
10540 }
10541
10542 if (json_paths)
10543 json_object_boolean_true_add(json_nexthop_global,
10544 "accessible");
10545 }
10546
10547 /* Display peer "from" output */
10548 /* This path was originated locally */
10549 if (path->peer == bgp->peer_self) {
10550
10551 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10552 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10553 if (json_paths)
10554 json_object_string_add(json_peer, "peerId",
10555 "0.0.0.0");
10556 else
10557 vty_out(vty, " from 0.0.0.0 ");
10558 } else {
10559 if (json_paths)
10560 json_object_string_add(json_peer, "peerId",
10561 "::");
10562 else
10563 vty_out(vty, " from :: ");
10564 }
10565
10566 if (json_paths)
10567 json_object_string_addf(json_peer, "routerId", "%pI4",
10568 &bgp->router_id);
10569 else
10570 vty_out(vty, "(%pI4)", &bgp->router_id);
10571 }
10572
10573 /* We RXed this path from one of our peers */
10574 else {
10575
10576 if (json_paths) {
10577 json_object_string_addf(json_peer, "peerId", "%pSU",
10578 &path->peer->su);
10579 json_object_string_addf(json_peer, "routerId", "%pI4",
10580 &path->peer->remote_id);
10581
10582 if (path->peer->hostname)
10583 json_object_string_add(json_peer, "hostname",
10584 path->peer->hostname);
10585
10586 if (path->peer->domainname)
10587 json_object_string_add(json_peer, "domainname",
10588 path->peer->domainname);
10589
10590 if (path->peer->conf_if)
10591 json_object_string_add(json_peer, "interface",
10592 path->peer->conf_if);
10593 } else {
10594 if (path->peer->conf_if) {
10595 if (path->peer->hostname
10596 && CHECK_FLAG(path->peer->bgp->flags,
10597 BGP_FLAG_SHOW_HOSTNAME))
10598 vty_out(vty, " from %s(%s)",
10599 path->peer->hostname,
10600 path->peer->conf_if);
10601 else
10602 vty_out(vty, " from %s",
10603 path->peer->conf_if);
10604 } else {
10605 if (path->peer->hostname
10606 && CHECK_FLAG(path->peer->bgp->flags,
10607 BGP_FLAG_SHOW_HOSTNAME))
10608 vty_out(vty, " from %s(%s)",
10609 path->peer->hostname,
10610 path->peer->host);
10611 else
10612 vty_out(vty, " from %pSU",
10613 &path->peer->su);
10614 }
10615
10616 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10617 vty_out(vty, " (%pI4)", &attr->originator_id);
10618 else
10619 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10620 }
10621 }
10622
10623 /*
10624 * Note when vrfid of nexthop is different from that of prefix
10625 */
10626 if (path->extra && path->extra->bgp_orig) {
10627 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10628
10629 if (json_paths) {
10630 const char *vn;
10631
10632 if (path->extra->bgp_orig->inst_type
10633 == BGP_INSTANCE_TYPE_DEFAULT)
10634 vn = VRF_DEFAULT_NAME;
10635 else
10636 vn = path->extra->bgp_orig->name;
10637
10638 json_object_string_add(json_path, "nhVrfName", vn);
10639
10640 if (nexthop_vrfid == VRF_UNKNOWN) {
10641 json_object_int_add(json_path, "nhVrfId", -1);
10642 } else {
10643 json_object_int_add(json_path, "nhVrfId",
10644 (int)nexthop_vrfid);
10645 }
10646 } else {
10647 if (nexthop_vrfid == VRF_UNKNOWN)
10648 vty_out(vty, " vrf ?");
10649 else {
10650 struct vrf *vrf;
10651
10652 vrf = vrf_lookup_by_id(nexthop_vrfid);
10653 vty_out(vty, " vrf %s(%u)",
10654 VRF_LOGNAME(vrf), nexthop_vrfid);
10655 }
10656 }
10657 }
10658
10659 if (nexthop_self) {
10660 if (json_paths) {
10661 json_object_boolean_true_add(json_path,
10662 "announceNexthopSelf");
10663 } else {
10664 vty_out(vty, " announce-nh-self");
10665 }
10666 }
10667
10668 if (!json_paths)
10669 vty_out(vty, "\n");
10670
10671 /* display the link-local nexthop */
10672 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10673 if (json_paths) {
10674 json_nexthop_ll = json_object_new_object();
10675 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10676 &attr->mp_nexthop_local);
10677
10678 if (path->peer->hostname)
10679 json_object_string_add(json_nexthop_ll,
10680 "hostname",
10681 path->peer->hostname);
10682
10683 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10684 json_object_string_add(json_nexthop_ll, "scope",
10685 "link-local");
10686
10687 json_object_boolean_true_add(json_nexthop_ll,
10688 "accessible");
10689
10690 if (!attr->mp_nexthop_prefer_global)
10691 json_object_boolean_true_add(json_nexthop_ll,
10692 "used");
10693 else
10694 json_object_boolean_true_add(
10695 json_nexthop_global, "used");
10696 } else {
10697 vty_out(vty, " (%s) %s\n",
10698 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10699 buf, INET6_ADDRSTRLEN),
10700 attr->mp_nexthop_prefer_global
10701 ? "(prefer-global)"
10702 : "(used)");
10703 }
10704 }
10705 /* If we do not have a link-local nexthop then we must flag the
10706 global as "used" */
10707 else {
10708 if (json_paths)
10709 json_object_boolean_true_add(json_nexthop_global,
10710 "used");
10711 }
10712
10713 if (safi == SAFI_EVPN &&
10714 bgp_evpn_is_esi_valid(&attr->esi)) {
10715 route_vty_out_detail_es_info(vty, path, attr, json_path);
10716 }
10717
10718 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10719 * Int/Ext/Local, Atomic, best */
10720 if (json_paths)
10721 json_object_string_add(json_path, "origin",
10722 bgp_origin_long_str[attr->origin]);
10723 else
10724 vty_out(vty, " Origin %s",
10725 bgp_origin_long_str[attr->origin]);
10726
10727 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10728 if (json_paths)
10729 json_object_int_add(json_path, "metric", attr->med);
10730 else
10731 vty_out(vty, ", metric %u", attr->med);
10732 }
10733
10734 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10735 if (json_paths)
10736 json_object_int_add(json_path, "locPrf",
10737 attr->local_pref);
10738 else
10739 vty_out(vty, ", localpref %u", attr->local_pref);
10740 }
10741
10742 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10743 if (json_paths)
10744 json_object_int_add(json_path, "aigpMetric",
10745 bgp_attr_get_aigp_metric(attr));
10746 else
10747 vty_out(vty, ", aigp-metric %" PRIu64,
10748 bgp_attr_get_aigp_metric(attr));
10749 }
10750
10751 if (attr->weight != 0) {
10752 if (json_paths)
10753 json_object_int_add(json_path, "weight", attr->weight);
10754 else
10755 vty_out(vty, ", weight %u", attr->weight);
10756 }
10757
10758 if (attr->tag != 0) {
10759 if (json_paths)
10760 json_object_int_add(json_path, "tag", attr->tag);
10761 else
10762 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10763 }
10764
10765 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10766 if (json_paths)
10767 json_object_boolean_false_add(json_path, "valid");
10768 else
10769 vty_out(vty, ", invalid");
10770 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10771 if (json_paths)
10772 json_object_boolean_true_add(json_path, "valid");
10773 else
10774 vty_out(vty, ", valid");
10775 }
10776
10777 if (json_paths)
10778 json_object_int_add(json_path, "version", bn->version);
10779
10780 if (path->peer != bgp->peer_self) {
10781 if (path->peer->as == path->peer->local_as) {
10782 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10783 if (json_paths)
10784 json_object_string_add(
10785 json_peer, "type",
10786 "confed-internal");
10787 else
10788 vty_out(vty, ", confed-internal");
10789 } else {
10790 if (json_paths)
10791 json_object_string_add(
10792 json_peer, "type", "internal");
10793 else
10794 vty_out(vty, ", internal");
10795 }
10796 } else {
10797 if (bgp_confederation_peers_check(bgp,
10798 path->peer->as)) {
10799 if (json_paths)
10800 json_object_string_add(
10801 json_peer, "type",
10802 "confed-external");
10803 else
10804 vty_out(vty, ", confed-external");
10805 } else {
10806 if (json_paths)
10807 json_object_string_add(
10808 json_peer, "type", "external");
10809 else
10810 vty_out(vty, ", external");
10811 }
10812 }
10813 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10814 if (json_paths) {
10815 json_object_boolean_true_add(json_path, "aggregated");
10816 json_object_boolean_true_add(json_path, "local");
10817 } else {
10818 vty_out(vty, ", aggregated, local");
10819 }
10820 } else if (path->type != ZEBRA_ROUTE_BGP) {
10821 if (json_paths)
10822 json_object_boolean_true_add(json_path, "sourced");
10823 else
10824 vty_out(vty, ", sourced");
10825 } else {
10826 if (json_paths) {
10827 json_object_boolean_true_add(json_path, "sourced");
10828 json_object_boolean_true_add(json_path, "local");
10829 } else {
10830 vty_out(vty, ", sourced, local");
10831 }
10832 }
10833
10834 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10835 if (json_paths)
10836 json_object_boolean_true_add(json_path,
10837 "atomicAggregate");
10838 else
10839 vty_out(vty, ", atomic-aggregate");
10840 }
10841
10842 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10843 if (json_paths)
10844 json_object_int_add(json_path, "otc", attr->otc);
10845 else
10846 vty_out(vty, ", otc %u", attr->otc);
10847 }
10848
10849 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10850 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10851 && bgp_path_info_mpath_count(path))) {
10852 if (json_paths)
10853 json_object_boolean_true_add(json_path, "multipath");
10854 else
10855 vty_out(vty, ", multipath");
10856 }
10857
10858 // Mark the bestpath(s)
10859 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10860 first_as = aspath_get_first_as(attr->aspath);
10861
10862 if (json_paths) {
10863 if (!json_bestpath)
10864 json_bestpath = json_object_new_object();
10865 json_object_int_add(json_bestpath, "bestpathFromAs",
10866 first_as);
10867 } else {
10868 if (first_as)
10869 vty_out(vty, ", bestpath-from-AS %u", first_as);
10870 else
10871 vty_out(vty, ", bestpath-from-AS Local");
10872 }
10873 }
10874
10875 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10876 if (json_paths) {
10877 if (!json_bestpath)
10878 json_bestpath = json_object_new_object();
10879 json_object_boolean_true_add(json_bestpath, "overall");
10880 json_object_string_add(
10881 json_bestpath, "selectionReason",
10882 bgp_path_selection_reason2str(bn->reason));
10883 } else {
10884 vty_out(vty, ", best");
10885 vty_out(vty, " (%s)",
10886 bgp_path_selection_reason2str(bn->reason));
10887 }
10888 }
10889
10890 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10891 if (json_paths)
10892 json_object_string_add(
10893 json_path, "rpkiValidationState",
10894 bgp_rpki_validation2str(rpki_curr_state));
10895 else
10896 vty_out(vty, ", rpki validation-state: %s",
10897 bgp_rpki_validation2str(rpki_curr_state));
10898 }
10899
10900 if (json_bestpath)
10901 json_object_object_add(json_path, "bestpath", json_bestpath);
10902
10903 if (!json_paths)
10904 vty_out(vty, "\n");
10905
10906 /* Line 4 display Community */
10907 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10908 if (json_paths) {
10909 if (!bgp_attr_get_community(attr)->json)
10910 community_str(bgp_attr_get_community(attr),
10911 true, true);
10912 json_object_lock(bgp_attr_get_community(attr)->json);
10913 json_object_object_add(
10914 json_path, "community",
10915 bgp_attr_get_community(attr)->json);
10916 } else {
10917 vty_out(vty, " Community: %s\n",
10918 bgp_attr_get_community(attr)->str);
10919 }
10920 }
10921
10922 /* Line 5 display Extended-community */
10923 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10924 if (json_paths) {
10925 json_ext_community = json_object_new_object();
10926 json_object_string_add(
10927 json_ext_community, "string",
10928 bgp_attr_get_ecommunity(attr)->str);
10929 json_object_object_add(json_path, "extendedCommunity",
10930 json_ext_community);
10931 } else {
10932 vty_out(vty, " Extended Community: %s\n",
10933 bgp_attr_get_ecommunity(attr)->str);
10934 }
10935 }
10936
10937 /* Line 6 display Large community */
10938 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10939 if (json_paths) {
10940 if (!bgp_attr_get_lcommunity(attr)->json)
10941 lcommunity_str(bgp_attr_get_lcommunity(attr),
10942 true, true);
10943 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10944 json_object_object_add(
10945 json_path, "largeCommunity",
10946 bgp_attr_get_lcommunity(attr)->json);
10947 } else {
10948 vty_out(vty, " Large Community: %s\n",
10949 bgp_attr_get_lcommunity(attr)->str);
10950 }
10951 }
10952
10953 /* Line 7 display Originator, Cluster-id */
10954 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10955 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10956 char buf[BUFSIZ] = {0};
10957
10958 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10959 if (json_paths)
10960 json_object_string_addf(json_path,
10961 "originatorId", "%pI4",
10962 &attr->originator_id);
10963 else
10964 vty_out(vty, " Originator: %pI4",
10965 &attr->originator_id);
10966 }
10967
10968 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10969 struct cluster_list *cluster =
10970 bgp_attr_get_cluster(attr);
10971 int i;
10972
10973 if (json_paths) {
10974 json_cluster_list = json_object_new_object();
10975 json_cluster_list_list =
10976 json_object_new_array();
10977
10978 for (i = 0; i < cluster->length / 4; i++) {
10979 json_string = json_object_new_string(
10980 inet_ntop(AF_INET,
10981 &cluster->list[i],
10982 buf, sizeof(buf)));
10983 json_object_array_add(
10984 json_cluster_list_list,
10985 json_string);
10986 }
10987
10988 /*
10989 * struct cluster_list does not have
10990 * "str" variable like aspath and community
10991 * do. Add this someday if someone asks
10992 * for it.
10993 * json_object_string_add(json_cluster_list,
10994 * "string", cluster->str);
10995 */
10996 json_object_object_add(json_cluster_list,
10997 "list",
10998 json_cluster_list_list);
10999 json_object_object_add(json_path, "clusterList",
11000 json_cluster_list);
11001 } else {
11002 vty_out(vty, ", Cluster list: ");
11003
11004 for (i = 0; i < cluster->length / 4; i++) {
11005 vty_out(vty, "%pI4 ",
11006 &cluster->list[i]);
11007 }
11008 }
11009 }
11010
11011 if (!json_paths)
11012 vty_out(vty, "\n");
11013 }
11014
11015 if (path->extra && path->extra->damp_info)
11016 bgp_damp_info_vty(vty, path, afi, safi, json_path);
11017
11018 /* Remote Label */
11019 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
11020 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
11021 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
11022 &bos);
11023
11024 if (json_paths)
11025 json_object_int_add(json_path, "remoteLabel", label);
11026 else
11027 vty_out(vty, " Remote label: %d\n", label);
11028 }
11029
11030 /* Remote SID */
11031 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
11032 if (json_paths)
11033 json_object_string_addf(json_path, "remoteSid", "%pI6",
11034 &path->extra->sid[0].sid);
11035 else
11036 vty_out(vty, " Remote SID: %pI6\n",
11037 &path->extra->sid[0].sid);
11038 }
11039
11040 /* Label Index */
11041 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11042 if (json_paths)
11043 json_object_int_add(json_path, "labelIndex",
11044 attr->label_index);
11045 else
11046 vty_out(vty, " Label Index: %d\n",
11047 attr->label_index);
11048 }
11049
11050 /* Line 8 display Addpath IDs */
11051 if (path->addpath_rx_id
11052 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11053 if (json_paths) {
11054 json_object_int_add(json_path, "addpathRxId",
11055 path->addpath_rx_id);
11056
11057 /* Keep backwards compatibility with the old API
11058 * by putting TX All's ID in the old field
11059 */
11060 json_object_int_add(
11061 json_path, "addpathTxId",
11062 path->tx_addpath
11063 .addpath_tx_id[BGP_ADDPATH_ALL]);
11064
11065 /* ... but create a specific field for each
11066 * strategy
11067 */
11068 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11069 json_object_int_add(
11070 json_path,
11071 bgp_addpath_names(i)->id_json_name,
11072 path->tx_addpath.addpath_tx_id[i]);
11073 }
11074 } else {
11075 vty_out(vty, " AddPath ID: RX %u, ",
11076 path->addpath_rx_id);
11077
11078 route_vty_out_tx_ids(vty, &path->tx_addpath);
11079 }
11080 }
11081
11082 /* If we used addpath to TX a non-bestpath we need to display
11083 * "Advertised to" on a path-by-path basis
11084 */
11085 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11086 first = 1;
11087
11088 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11089 addpath_capable =
11090 bgp_addpath_encode_tx(peer, afi, safi);
11091 has_adj = bgp_adj_out_lookup(
11092 peer, path->net,
11093 bgp_addpath_id_for_peer(peer, afi, safi,
11094 &path->tx_addpath));
11095
11096 if ((addpath_capable && has_adj)
11097 || (!addpath_capable && has_adj
11098 && CHECK_FLAG(path->flags,
11099 BGP_PATH_SELECTED))) {
11100 if (json_path && !json_adv_to)
11101 json_adv_to = json_object_new_object();
11102
11103 route_vty_out_advertised_to(
11104 vty, peer, &first,
11105 " Advertised to:", json_adv_to);
11106 }
11107 }
11108
11109 if (json_path) {
11110 if (json_adv_to) {
11111 json_object_object_add(
11112 json_path, "advertisedTo", json_adv_to);
11113 }
11114 } else {
11115 if (!first) {
11116 vty_out(vty, "\n");
11117 }
11118 }
11119 }
11120
11121 /* Line 9 display Uptime */
11122 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11123 if (json_paths) {
11124 json_last_update = json_object_new_object();
11125 json_object_int_add(json_last_update, "epoch", tbuf);
11126 json_object_string_add(json_last_update, "string",
11127 ctime(&tbuf));
11128 json_object_object_add(json_path, "lastUpdate",
11129 json_last_update);
11130 } else
11131 vty_out(vty, " Last update: %s", ctime(&tbuf));
11132
11133 /* Line 10 display PMSI tunnel attribute, if present */
11134 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11135 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11136 bgp_attr_get_pmsi_tnl_type(attr),
11137 PMSI_TNLTYPE_STR_DEFAULT);
11138
11139 if (json_paths) {
11140 json_pmsi = json_object_new_object();
11141 json_object_string_add(json_pmsi, "tunnelType", str);
11142 json_object_int_add(json_pmsi, "label",
11143 label2vni(&attr->label));
11144 json_object_object_add(json_path, "pmsi", json_pmsi);
11145 } else
11146 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11147 str, label2vni(&attr->label));
11148 }
11149
11150 if (path->peer->t_gr_restart &&
11151 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11152 unsigned long gr_remaining =
11153 event_timer_remain_second(path->peer->t_gr_restart);
11154
11155 if (json_paths) {
11156 json_object_int_add(json_path,
11157 "gracefulRestartSecondsRemaining",
11158 gr_remaining);
11159 } else
11160 vty_out(vty,
11161 " Time until Graceful Restart stale route deleted: %lu\n",
11162 gr_remaining);
11163 }
11164
11165 if (path->peer->t_llgr_stale[afi][safi] &&
11166 bgp_attr_get_community(attr) &&
11167 community_include(bgp_attr_get_community(attr),
11168 COMMUNITY_LLGR_STALE)) {
11169 unsigned long llgr_remaining = event_timer_remain_second(
11170 path->peer->t_llgr_stale[afi][safi]);
11171
11172 if (json_paths) {
11173 json_object_int_add(json_path, "llgrSecondsRemaining",
11174 llgr_remaining);
11175 } else
11176 vty_out(vty,
11177 " Time until Long-lived stale route deleted: %lu\n",
11178 llgr_remaining);
11179 }
11180
11181 /* Output some debug about internal state of the dest flags */
11182 if (json_paths) {
11183 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11184 json_object_boolean_true_add(json_path, "processScheduled");
11185 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11186 json_object_boolean_true_add(json_path, "userCleared");
11187 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11188 json_object_boolean_true_add(json_path, "labelChanged");
11189 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11190 json_object_boolean_true_add(json_path, "registeredForLabel");
11191 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11192 json_object_boolean_true_add(json_path, "selectDefered");
11193 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11194 json_object_boolean_true_add(json_path, "fibInstalled");
11195 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11196 json_object_boolean_true_add(json_path, "fibPending");
11197
11198 if (json_nexthop_global || json_nexthop_ll) {
11199 json_nexthops = json_object_new_array();
11200
11201 if (json_nexthop_global)
11202 json_object_array_add(json_nexthops,
11203 json_nexthop_global);
11204
11205 if (json_nexthop_ll)
11206 json_object_array_add(json_nexthops,
11207 json_nexthop_ll);
11208
11209 json_object_object_add(json_path, "nexthops",
11210 json_nexthops);
11211 }
11212
11213 json_object_object_add(json_path, "peer", json_peer);
11214 json_object_array_add(json_paths, json_path);
11215 }
11216 }
11217
11218 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11219 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11220 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11221
11222 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11223 afi_t afi, safi_t safi, enum bgp_show_type type,
11224 bool use_json);
11225 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11226 const char *comstr, int exact, afi_t afi,
11227 safi_t safi, uint16_t show_flags);
11228
11229 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11230 struct bgp_table *table, enum bgp_show_type type,
11231 void *output_arg, const char *rd, int is_last,
11232 unsigned long *output_cum, unsigned long *total_cum,
11233 unsigned long *json_header_depth, uint16_t show_flags,
11234 enum rpki_states rpki_target_state)
11235 {
11236 struct bgp_path_info *pi;
11237 struct bgp_dest *dest;
11238 bool header = true;
11239 bool json_detail_header = false;
11240 int display;
11241 unsigned long output_count = 0;
11242 unsigned long total_count = 0;
11243 struct prefix *p;
11244 json_object *json_paths = NULL;
11245 int first = 1;
11246 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11247 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11248 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11249 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11250 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11251
11252 if (output_cum && *output_cum != 0)
11253 header = false;
11254
11255 if (use_json && !*json_header_depth) {
11256 if (all)
11257 *json_header_depth = 1;
11258 else {
11259 vty_out(vty, "{\n");
11260 *json_header_depth = 2;
11261 }
11262 vty_out(vty,
11263 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11264 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11265 " \"localAS\": ",
11266 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11267 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11268 ? VRF_DEFAULT_NAME
11269 : bgp->name,
11270 table->version, &bgp->router_id,
11271 bgp->default_local_pref);
11272 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11273 ((bgp->asnotation == ASNOTATION_DOT) &&
11274 (bgp->as < UINT16_MAX)))
11275 vty_out(vty, "%u", bgp->as);
11276 else {
11277 vty_out(vty, "\"");
11278 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11279 vty_out(vty, "\"");
11280 }
11281 vty_out(vty, ",\n \"routes\": { ");
11282 if (rd) {
11283 vty_out(vty, " \"routeDistinguishers\" : {");
11284 ++*json_header_depth;
11285 }
11286 }
11287
11288 if (use_json && rd) {
11289 vty_out(vty, " \"%s\" : { ", rd);
11290 }
11291
11292 /* Check for 'json detail', where we need header output once per dest */
11293 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11294 type != bgp_show_type_damp_neighbor &&
11295 type != bgp_show_type_flap_statistics &&
11296 type != bgp_show_type_flap_neighbor)
11297 json_detail_header = true;
11298
11299 /* Start processing of routes. */
11300 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11301 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11302 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11303 bool json_detail_header_used = false;
11304
11305 pi = bgp_dest_get_bgp_path_info(dest);
11306 if (pi == NULL)
11307 continue;
11308
11309 display = 0;
11310 if (use_json)
11311 json_paths = json_object_new_array();
11312 else
11313 json_paths = NULL;
11314
11315 for (; pi; pi = pi->next) {
11316 struct community *picomm = NULL;
11317
11318 picomm = bgp_attr_get_community(pi->attr);
11319
11320 total_count++;
11321
11322 if (type == bgp_show_type_prefix_version) {
11323 uint32_t version =
11324 strtoul(output_arg, NULL, 10);
11325 if (dest->version < version)
11326 continue;
11327 }
11328
11329 if (type == bgp_show_type_community_alias) {
11330 char *alias = output_arg;
11331 char **communities;
11332 int num;
11333 bool found = false;
11334
11335 if (picomm) {
11336 frrstr_split(picomm->str, " ",
11337 &communities, &num);
11338 for (int i = 0; i < num; i++) {
11339 const char *com2alias =
11340 bgp_community2alias(
11341 communities[i]);
11342 if (!found
11343 && strcmp(alias, com2alias)
11344 == 0)
11345 found = true;
11346 XFREE(MTYPE_TMP,
11347 communities[i]);
11348 }
11349 XFREE(MTYPE_TMP, communities);
11350 }
11351
11352 if (!found &&
11353 bgp_attr_get_lcommunity(pi->attr)) {
11354 frrstr_split(bgp_attr_get_lcommunity(
11355 pi->attr)
11356 ->str,
11357 " ", &communities, &num);
11358 for (int i = 0; i < num; i++) {
11359 const char *com2alias =
11360 bgp_community2alias(
11361 communities[i]);
11362 if (!found
11363 && strcmp(alias, com2alias)
11364 == 0)
11365 found = true;
11366 XFREE(MTYPE_TMP,
11367 communities[i]);
11368 }
11369 XFREE(MTYPE_TMP, communities);
11370 }
11371
11372 if (!found)
11373 continue;
11374 }
11375
11376 if (type == bgp_show_type_rpki) {
11377 if (dest_p->family == AF_INET
11378 || dest_p->family == AF_INET6)
11379 rpki_curr_state = hook_call(
11380 bgp_rpki_prefix_status,
11381 pi->peer, pi->attr, dest_p);
11382 if (rpki_target_state != RPKI_NOT_BEING_USED
11383 && rpki_curr_state != rpki_target_state)
11384 continue;
11385 }
11386
11387 if (type == bgp_show_type_flap_statistics
11388 || type == bgp_show_type_flap_neighbor
11389 || type == bgp_show_type_dampend_paths
11390 || type == bgp_show_type_damp_neighbor) {
11391 if (!(pi->extra && pi->extra->damp_info))
11392 continue;
11393 }
11394 if (type == bgp_show_type_regexp) {
11395 regex_t *regex = output_arg;
11396
11397 if (bgp_regexec(regex, pi->attr->aspath)
11398 == REG_NOMATCH)
11399 continue;
11400 }
11401 if (type == bgp_show_type_prefix_list) {
11402 struct prefix_list *plist = output_arg;
11403
11404 if (prefix_list_apply(plist, dest_p)
11405 != PREFIX_PERMIT)
11406 continue;
11407 }
11408 if (type == bgp_show_type_access_list) {
11409 struct access_list *alist = output_arg;
11410
11411 if (access_list_apply(alist, dest_p) !=
11412 FILTER_PERMIT)
11413 continue;
11414 }
11415 if (type == bgp_show_type_filter_list) {
11416 struct as_list *as_list = output_arg;
11417
11418 if (as_list_apply(as_list, pi->attr->aspath)
11419 != AS_FILTER_PERMIT)
11420 continue;
11421 }
11422 if (type == bgp_show_type_route_map) {
11423 struct route_map *rmap = output_arg;
11424 struct bgp_path_info path;
11425 struct bgp_path_info_extra extra;
11426 struct attr dummy_attr = {};
11427 route_map_result_t ret;
11428
11429 dummy_attr = *pi->attr;
11430
11431 prep_for_rmap_apply(&path, &extra, dest, pi,
11432 pi->peer, &dummy_attr);
11433
11434 ret = route_map_apply(rmap, dest_p, &path);
11435 bgp_attr_flush(&dummy_attr);
11436 if (ret == RMAP_DENYMATCH)
11437 continue;
11438 }
11439 if (type == bgp_show_type_neighbor
11440 || type == bgp_show_type_flap_neighbor
11441 || type == bgp_show_type_damp_neighbor) {
11442 union sockunion *su = output_arg;
11443
11444 if (pi->peer == NULL
11445 || pi->peer->su_remote == NULL
11446 || !sockunion_same(pi->peer->su_remote, su))
11447 continue;
11448 }
11449 if (type == bgp_show_type_cidr_only) {
11450 uint32_t destination;
11451
11452 destination = ntohl(dest_p->u.prefix4.s_addr);
11453 if (IN_CLASSC(destination)
11454 && dest_p->prefixlen == 24)
11455 continue;
11456 if (IN_CLASSB(destination)
11457 && dest_p->prefixlen == 16)
11458 continue;
11459 if (IN_CLASSA(destination)
11460 && dest_p->prefixlen == 8)
11461 continue;
11462 }
11463 if (type == bgp_show_type_prefix_longer) {
11464 p = output_arg;
11465 if (!prefix_match(p, dest_p))
11466 continue;
11467 }
11468 if (type == bgp_show_type_community_all) {
11469 if (!picomm)
11470 continue;
11471 }
11472 if (type == bgp_show_type_community) {
11473 struct community *com = output_arg;
11474
11475 if (!picomm || !community_match(picomm, com))
11476 continue;
11477 }
11478 if (type == bgp_show_type_community_exact) {
11479 struct community *com = output_arg;
11480
11481 if (!picomm || !community_cmp(picomm, com))
11482 continue;
11483 }
11484 if (type == bgp_show_type_community_list) {
11485 struct community_list *list = output_arg;
11486
11487 if (!community_list_match(picomm, list))
11488 continue;
11489 }
11490 if (type == bgp_show_type_community_list_exact) {
11491 struct community_list *list = output_arg;
11492
11493 if (!community_list_exact_match(picomm, list))
11494 continue;
11495 }
11496 if (type == bgp_show_type_lcommunity) {
11497 struct lcommunity *lcom = output_arg;
11498
11499 if (!bgp_attr_get_lcommunity(pi->attr) ||
11500 !lcommunity_match(
11501 bgp_attr_get_lcommunity(pi->attr),
11502 lcom))
11503 continue;
11504 }
11505
11506 if (type == bgp_show_type_lcommunity_exact) {
11507 struct lcommunity *lcom = output_arg;
11508
11509 if (!bgp_attr_get_lcommunity(pi->attr) ||
11510 !lcommunity_cmp(
11511 bgp_attr_get_lcommunity(pi->attr),
11512 lcom))
11513 continue;
11514 }
11515 if (type == bgp_show_type_lcommunity_list) {
11516 struct community_list *list = output_arg;
11517
11518 if (!lcommunity_list_match(
11519 bgp_attr_get_lcommunity(pi->attr),
11520 list))
11521 continue;
11522 }
11523 if (type
11524 == bgp_show_type_lcommunity_list_exact) {
11525 struct community_list *list = output_arg;
11526
11527 if (!lcommunity_list_exact_match(
11528 bgp_attr_get_lcommunity(pi->attr),
11529 list))
11530 continue;
11531 }
11532 if (type == bgp_show_type_lcommunity_all) {
11533 if (!bgp_attr_get_lcommunity(pi->attr))
11534 continue;
11535 }
11536 if (type == bgp_show_type_dampend_paths
11537 || type == bgp_show_type_damp_neighbor) {
11538 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11539 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11540 continue;
11541 }
11542 if (type == bgp_show_type_self_originated) {
11543 if (pi->peer != bgp->peer_self)
11544 continue;
11545 }
11546
11547 if (!use_json && header) {
11548 vty_out(vty,
11549 "BGP table version is %" PRIu64
11550 ", local router ID is %pI4, vrf id ",
11551 table->version, &bgp->router_id);
11552 if (bgp->vrf_id == VRF_UNKNOWN)
11553 vty_out(vty, "%s", VRFID_NONE_STR);
11554 else
11555 vty_out(vty, "%u", bgp->vrf_id);
11556 vty_out(vty, "\n");
11557 vty_out(vty, "Default local pref %u, ",
11558 bgp->default_local_pref);
11559 vty_out(vty, "local AS ");
11560 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11561 &bgp->as);
11562 vty_out(vty, "\n");
11563 if (!detail_routes) {
11564 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11565 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11566 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11567 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11568 }
11569 if (type == bgp_show_type_dampend_paths
11570 || type == bgp_show_type_damp_neighbor)
11571 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11572 else if (type == bgp_show_type_flap_statistics
11573 || type == bgp_show_type_flap_neighbor)
11574 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11575 else if (!detail_routes)
11576 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11577 : BGP_SHOW_HEADER));
11578 header = false;
11579
11580 }
11581 if (rd != NULL && !display && !output_count) {
11582 if (!use_json)
11583 vty_out(vty,
11584 "Route Distinguisher: %s\n",
11585 rd);
11586 }
11587 if (type == bgp_show_type_dampend_paths
11588 || type == bgp_show_type_damp_neighbor)
11589 damp_route_vty_out(vty, dest_p, pi, display,
11590 AFI_IP, safi, use_json,
11591 json_paths);
11592 else if (type == bgp_show_type_flap_statistics
11593 || type == bgp_show_type_flap_neighbor)
11594 flap_route_vty_out(vty, dest_p, pi, display,
11595 AFI_IP, safi, use_json,
11596 json_paths);
11597 else {
11598 if (detail_routes || detail_json) {
11599 const struct prefix_rd *prd = NULL;
11600
11601 if (dest->pdest)
11602 prd = bgp_rd_from_dest(
11603 dest->pdest, safi);
11604
11605 if (!use_json)
11606 route_vty_out_detail_header(
11607 vty, bgp, dest,
11608 bgp_dest_get_prefix(
11609 dest),
11610 prd, table->afi, safi,
11611 NULL, false);
11612
11613 route_vty_out_detail(
11614 vty, bgp, dest, dest_p, pi,
11615 family2afi(dest_p->family),
11616 safi, RPKI_NOT_BEING_USED,
11617 json_paths);
11618 } else {
11619 route_vty_out(vty, dest_p, pi, display,
11620 safi, json_paths, wide);
11621 }
11622 }
11623 display++;
11624 }
11625
11626 if (display) {
11627 output_count++;
11628 if (!use_json)
11629 continue;
11630
11631 /* encode prefix */
11632 if (dest_p->family == AF_FLOWSPEC) {
11633 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11634
11635
11636 bgp_fs_nlri_get_string(
11637 (unsigned char *)
11638 dest_p->u.prefix_flowspec.ptr,
11639 dest_p->u.prefix_flowspec.prefixlen,
11640 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11641 family2afi(dest_p->u
11642 .prefix_flowspec.family));
11643 if (first)
11644 vty_out(vty, "\"%s/%d\": ", retstr,
11645 dest_p->u.prefix_flowspec
11646 .prefixlen);
11647 else
11648 vty_out(vty, ",\"%s/%d\": ", retstr,
11649 dest_p->u.prefix_flowspec
11650 .prefixlen);
11651 } else {
11652 if (first)
11653 vty_out(vty, "\"%pFX\": ", dest_p);
11654 else
11655 vty_out(vty, ",\"%pFX\": ", dest_p);
11656 }
11657
11658 /* This is used for 'json detail' vty keywords.
11659 *
11660 * In plain 'json' the per-prefix header is encoded
11661 * as a standalone dictionary in the first json_paths
11662 * array element:
11663 * "<prefix>": [{header}, {path-1}, {path-N}]
11664 * (which is confusing and borderline broken)
11665 *
11666 * For 'json detail' this changes the value
11667 * of each prefix-key to be a dictionary where each
11668 * header item has its own key, and json_paths is
11669 * tucked under the "paths" key:
11670 * "<prefix>": {
11671 * "<header-key-1>": <header-val-1>,
11672 * "<header-key-N>": <header-val-N>,
11673 * "paths": [{path-1}, {path-N}]
11674 * }
11675 */
11676 if (json_detail_header && json_paths != NULL) {
11677 const struct prefix_rd *prd;
11678
11679 /* Start per-prefix dictionary */
11680 vty_out(vty, "{\n");
11681
11682 prd = bgp_rd_from_dest(dest, safi);
11683
11684 route_vty_out_detail_header(
11685 vty, bgp, dest,
11686 bgp_dest_get_prefix(dest), prd,
11687 table->afi, safi, json_paths, true);
11688
11689 vty_out(vty, "\"paths\": ");
11690 json_detail_header_used = true;
11691 }
11692
11693 /*
11694 * We are using no_pretty here because under
11695 * extremely high settings( say lots and lots of
11696 * routes with lots and lots of ways to reach
11697 * that route via different paths ) this can
11698 * save several minutes of output when FRR
11699 * is run on older cpu's or more underperforming
11700 * routers out there
11701 */
11702 vty_json_no_pretty(vty, json_paths);
11703
11704 /* End per-prefix dictionary */
11705 if (json_detail_header_used)
11706 vty_out(vty, "} ");
11707
11708 json_paths = NULL;
11709 first = 0;
11710 } else
11711 json_object_free(json_paths);
11712 }
11713
11714 if (output_cum) {
11715 output_count += *output_cum;
11716 *output_cum = output_count;
11717 }
11718 if (total_cum) {
11719 total_count += *total_cum;
11720 *total_cum = total_count;
11721 }
11722 if (use_json) {
11723 if (rd) {
11724 vty_out(vty, " }%s ", (is_last ? "" : ","));
11725 }
11726 if (is_last) {
11727 unsigned long i;
11728 for (i = 0; i < *json_header_depth; ++i)
11729 vty_out(vty, " } ");
11730 if (!all)
11731 vty_out(vty, "\n");
11732 }
11733 } else {
11734 if (is_last) {
11735 /* No route is displayed */
11736 if (output_count == 0) {
11737 if (type == bgp_show_type_normal)
11738 vty_out(vty,
11739 "No BGP prefixes displayed, %ld exist\n",
11740 total_count);
11741 } else
11742 vty_out(vty,
11743 "\nDisplayed %ld routes and %ld total paths\n",
11744 output_count, total_count);
11745 }
11746 }
11747
11748 return CMD_SUCCESS;
11749 }
11750
11751 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11752 struct bgp_table *table, struct prefix_rd *prd_match,
11753 enum bgp_show_type type, void *output_arg,
11754 uint16_t show_flags)
11755 {
11756 struct bgp_dest *dest, *next;
11757 unsigned long output_cum = 0;
11758 unsigned long total_cum = 0;
11759 unsigned long json_header_depth = 0;
11760 struct bgp_table *itable;
11761 bool show_msg;
11762 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11763
11764 show_msg = (!use_json && type == bgp_show_type_normal);
11765
11766 for (dest = bgp_table_top(table); dest; dest = next) {
11767 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11768
11769 next = bgp_route_next(dest);
11770 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11771 continue;
11772
11773 itable = bgp_dest_get_bgp_table_info(dest);
11774 if (itable != NULL) {
11775 struct prefix_rd prd;
11776 char rd[RD_ADDRSTRLEN];
11777
11778 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11779 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11780 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11781 rd, next == NULL, &output_cum,
11782 &total_cum, &json_header_depth,
11783 show_flags, RPKI_NOT_BEING_USED);
11784 if (next == NULL)
11785 show_msg = false;
11786 }
11787 }
11788 if (show_msg) {
11789 if (output_cum == 0)
11790 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11791 total_cum);
11792 else
11793 vty_out(vty,
11794 "\nDisplayed %ld routes and %ld total paths\n",
11795 output_cum, total_cum);
11796 } else {
11797 if (use_json && output_cum == 0)
11798 vty_out(vty, "{}\n");
11799 }
11800 return CMD_SUCCESS;
11801 }
11802
11803 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11804 enum bgp_show_type type, void *output_arg,
11805 uint16_t show_flags, enum rpki_states rpki_target_state)
11806 {
11807 struct bgp_table *table;
11808 unsigned long json_header_depth = 0;
11809 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11810
11811 if (bgp == NULL) {
11812 bgp = bgp_get_default();
11813 }
11814
11815 if (bgp == NULL) {
11816 if (!use_json)
11817 vty_out(vty, "No BGP process is configured\n");
11818 else
11819 vty_out(vty, "{}\n");
11820 return CMD_WARNING;
11821 }
11822
11823 /* Labeled-unicast routes live in the unicast table. */
11824 if (safi == SAFI_LABELED_UNICAST)
11825 safi = SAFI_UNICAST;
11826
11827 table = bgp->rib[afi][safi];
11828 /* use MPLS and ENCAP specific shows until they are merged */
11829 if (safi == SAFI_MPLS_VPN) {
11830 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11831 output_arg, show_flags);
11832 }
11833
11834 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11835 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11836 output_arg, use_json,
11837 1, NULL, NULL);
11838 }
11839
11840 if (safi == SAFI_EVPN)
11841 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11842
11843 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11844 NULL, NULL, &json_header_depth, show_flags,
11845 rpki_target_state);
11846 }
11847
11848 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11849 safi_t safi, uint16_t show_flags)
11850 {
11851 struct listnode *node, *nnode;
11852 struct bgp *bgp;
11853 int is_first = 1;
11854 bool route_output = false;
11855 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11856
11857 if (use_json)
11858 vty_out(vty, "{\n");
11859
11860 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11861 route_output = true;
11862 if (use_json) {
11863 if (!is_first)
11864 vty_out(vty, ",\n");
11865 else
11866 is_first = 0;
11867
11868 vty_out(vty, "\"%s\":",
11869 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11870 ? VRF_DEFAULT_NAME
11871 : bgp->name);
11872 } else {
11873 vty_out(vty, "\nInstance %s:\n",
11874 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11875 ? VRF_DEFAULT_NAME
11876 : bgp->name);
11877 }
11878 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11879 show_flags, RPKI_NOT_BEING_USED);
11880 }
11881
11882 if (use_json)
11883 vty_out(vty, "}\n");
11884 else if (!route_output)
11885 vty_out(vty, "%% BGP instance not found\n");
11886 }
11887
11888 /* Header of detailed BGP route information */
11889 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11890 struct bgp_dest *dest, const struct prefix *p,
11891 const struct prefix_rd *prd, afi_t afi,
11892 safi_t safi, json_object *json,
11893 bool incremental_print)
11894 {
11895 struct bgp_path_info *pi;
11896 struct peer *peer;
11897 struct listnode *node, *nnode;
11898 char buf1[RD_ADDRSTRLEN];
11899 int count = 0;
11900 int best = 0;
11901 int suppress = 0;
11902 int accept_own = 0;
11903 int route_filter_translated_v4 = 0;
11904 int route_filter_v4 = 0;
11905 int route_filter_translated_v6 = 0;
11906 int route_filter_v6 = 0;
11907 int llgr_stale = 0;
11908 int no_llgr = 0;
11909 int accept_own_nexthop = 0;
11910 int blackhole = 0;
11911 int no_export = 0;
11912 int no_advertise = 0;
11913 int local_as = 0;
11914 int no_peer = 0;
11915 int first = 1;
11916 int has_valid_label = 0;
11917 mpls_label_t label = 0;
11918 json_object *json_adv_to = NULL;
11919 uint32_t ttl = 0;
11920 uint32_t bos = 0;
11921 uint32_t exp = 0;
11922
11923 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11924
11925 has_valid_label = bgp_is_valid_label(&label);
11926
11927 if (safi == SAFI_EVPN) {
11928 if (!json) {
11929 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11930 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11931 bgp->asnotation)
11932 : "",
11933 prd ? ":" : "", (struct prefix_evpn *)p);
11934 } else {
11935 json_object_string_add(
11936 json, "rd",
11937 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11938 bgp->asnotation)
11939 : "");
11940 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11941 }
11942 } else {
11943 if (!json) {
11944 vty_out(vty,
11945 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11946 "\n",
11947 (((safi == SAFI_MPLS_VPN ||
11948 safi == SAFI_ENCAP) &&
11949 prd)
11950 ? prefix_rd2str(prd, buf1,
11951 sizeof(buf1),
11952 bgp->asnotation)
11953 : ""),
11954 safi == SAFI_MPLS_VPN && prd ? ":" : "", p,
11955 dest->version);
11956
11957 } else {
11958 if (incremental_print) {
11959 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11960 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11961 dest->version);
11962 } else {
11963 json_object_string_addf(json, "prefix", "%pFX",
11964 p);
11965 json_object_int_add(json, "version",
11966 dest->version);
11967 }
11968 }
11969 }
11970
11971 if (has_valid_label) {
11972 if (json) {
11973 if (incremental_print)
11974 vty_out(vty, "\"localLabel\": \"%u\",\n",
11975 label);
11976 else
11977 json_object_int_add(json, "localLabel", label);
11978 } else
11979 vty_out(vty, "Local label: %d\n", label);
11980 }
11981
11982 if (!json)
11983 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11984 vty_out(vty, "not allocated\n");
11985
11986 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11987 struct community *picomm = NULL;
11988
11989 picomm = bgp_attr_get_community(pi->attr);
11990
11991 count++;
11992 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11993 best = count;
11994 if (bgp_path_suppressed(pi))
11995 suppress = 1;
11996
11997 if (!picomm)
11998 continue;
11999
12000 no_advertise += community_include(
12001 picomm, COMMUNITY_NO_ADVERTISE);
12002 no_export +=
12003 community_include(picomm, COMMUNITY_NO_EXPORT);
12004 local_as +=
12005 community_include(picomm, COMMUNITY_LOCAL_AS);
12006 accept_own +=
12007 community_include(picomm, COMMUNITY_ACCEPT_OWN);
12008 route_filter_translated_v4 += community_include(
12009 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
12010 route_filter_translated_v6 += community_include(
12011 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
12012 route_filter_v4 += community_include(
12013 picomm, COMMUNITY_ROUTE_FILTER_v4);
12014 route_filter_v6 += community_include(
12015 picomm, COMMUNITY_ROUTE_FILTER_v6);
12016 llgr_stale +=
12017 community_include(picomm, COMMUNITY_LLGR_STALE);
12018 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
12019 accept_own_nexthop += community_include(
12020 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
12021 blackhole +=
12022 community_include(picomm, COMMUNITY_BLACKHOLE);
12023 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
12024 }
12025 }
12026
12027 if (!json) {
12028 vty_out(vty, "Paths: (%d available", count);
12029 if (best) {
12030 vty_out(vty, ", best #%d", best);
12031 if (safi == SAFI_UNICAST) {
12032 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
12033 vty_out(vty, ", table %s",
12034 VRF_DEFAULT_NAME);
12035 else
12036 vty_out(vty, ", vrf %s",
12037 bgp->name);
12038 }
12039 } else
12040 vty_out(vty, ", no best path");
12041
12042 if (accept_own)
12043 vty_out(vty,
12044 ", accept own local route exported and imported in different VRF");
12045 else if (route_filter_translated_v4)
12046 vty_out(vty,
12047 ", mark translated RTs for VPNv4 route filtering");
12048 else if (route_filter_v4)
12049 vty_out(vty,
12050 ", attach RT as-is for VPNv4 route filtering");
12051 else if (route_filter_translated_v6)
12052 vty_out(vty,
12053 ", mark translated RTs for VPNv6 route filtering");
12054 else if (route_filter_v6)
12055 vty_out(vty,
12056 ", attach RT as-is for VPNv6 route filtering");
12057 else if (llgr_stale)
12058 vty_out(vty,
12059 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
12060 else if (no_llgr)
12061 vty_out(vty,
12062 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
12063 else if (accept_own_nexthop)
12064 vty_out(vty,
12065 ", accept local nexthop");
12066 else if (blackhole)
12067 vty_out(vty, ", inform peer to blackhole prefix");
12068 else if (no_export)
12069 vty_out(vty, ", not advertised to EBGP peer");
12070 else if (no_advertise)
12071 vty_out(vty, ", not advertised to any peer");
12072 else if (local_as)
12073 vty_out(vty, ", not advertised outside local AS");
12074 else if (no_peer)
12075 vty_out(vty,
12076 ", inform EBGP peer not to advertise to their EBGP peers");
12077
12078 if (suppress)
12079 vty_out(vty,
12080 ", Advertisements suppressed by an aggregate.");
12081 vty_out(vty, ")\n");
12082 }
12083
12084 /* If we are not using addpath then we can display Advertised to and
12085 * that will
12086 * show what peers we advertised the bestpath to. If we are using
12087 * addpath
12088 * though then we must display Advertised to on a path-by-path basis. */
12089 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12090 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12091 if (bgp_adj_out_lookup(peer, dest, 0)) {
12092 if (json && !json_adv_to)
12093 json_adv_to = json_object_new_object();
12094
12095 route_vty_out_advertised_to(
12096 vty, peer, &first,
12097 " Advertised to non peer-group peers:\n ",
12098 json_adv_to);
12099 }
12100 }
12101
12102 if (json && json_adv_to) {
12103 if (incremental_print) {
12104 vty_out(vty, "\"advertisedTo\": ");
12105 vty_json(vty, json_adv_to);
12106 vty_out(vty, ",");
12107 } else
12108 json_object_object_add(json, "advertisedTo",
12109 json_adv_to);
12110 } else {
12111 if (!json && first)
12112 vty_out(vty, " Not advertised to any peer");
12113 vty_out(vty, "\n");
12114 }
12115 }
12116 }
12117
12118 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12119 struct bgp_dest *bgp_node, struct vty *vty,
12120 struct bgp *bgp, afi_t afi, safi_t safi,
12121 json_object *json, enum bgp_path_type pathtype,
12122 int *display, enum rpki_states rpki_target_state)
12123 {
12124 struct bgp_path_info *pi;
12125 int header = 1;
12126 json_object *json_header = NULL;
12127 json_object *json_paths = NULL;
12128 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12129
12130 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12131 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12132
12133 if (p->family == AF_INET || p->family == AF_INET6)
12134 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12135 pi->peer, pi->attr, p);
12136
12137 if (rpki_target_state != RPKI_NOT_BEING_USED
12138 && rpki_curr_state != rpki_target_state)
12139 continue;
12140
12141 if (json && !json_paths) {
12142 /* Instantiate json_paths only if path is valid */
12143 json_paths = json_object_new_array();
12144 if (pfx_rd)
12145 json_header = json_object_new_object();
12146 else
12147 json_header = json;
12148 }
12149
12150 if (header) {
12151 route_vty_out_detail_header(
12152 vty, bgp, bgp_node,
12153 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12154 safi, json_header, false);
12155 header = 0;
12156 }
12157 (*display)++;
12158
12159 if (pathtype == BGP_PATH_SHOW_ALL
12160 || (pathtype == BGP_PATH_SHOW_BESTPATH
12161 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12162 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12163 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12164 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12165 route_vty_out_detail(vty, bgp, bgp_node,
12166 bgp_dest_get_prefix(bgp_node), pi,
12167 AFI_IP, safi, rpki_curr_state,
12168 json_paths);
12169 }
12170
12171 if (json && json_paths) {
12172 json_object_object_add(json_header, "paths", json_paths);
12173
12174 if (pfx_rd)
12175 json_object_object_addf(
12176 json, json_header,
12177 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12178 }
12179 }
12180
12181 /*
12182 * Return rd based on safi
12183 */
12184 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12185 safi_t safi)
12186 {
12187 switch (safi) {
12188 case SAFI_MPLS_VPN:
12189 case SAFI_ENCAP:
12190 case SAFI_EVPN:
12191 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12192 case SAFI_UNSPEC:
12193 case SAFI_UNICAST:
12194 case SAFI_MULTICAST:
12195 case SAFI_LABELED_UNICAST:
12196 case SAFI_FLOWSPEC:
12197 case SAFI_MAX:
12198 return NULL;
12199 }
12200
12201 assert(!"Reached end of function when we were not expecting it");
12202 }
12203
12204 /* Display specified route of BGP table. */
12205 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12206 struct bgp_table *rib, const char *ip_str,
12207 afi_t afi, safi_t safi,
12208 enum rpki_states rpki_target_state,
12209 struct prefix_rd *prd, int prefix_check,
12210 enum bgp_path_type pathtype, bool use_json)
12211 {
12212 int ret;
12213 int display = 0;
12214 struct prefix match;
12215 struct bgp_dest *dest;
12216 struct bgp_dest *rm;
12217 struct bgp_table *table;
12218 json_object *json = NULL;
12219 json_object *json_paths = NULL;
12220
12221 /* Check IP address argument. */
12222 ret = str2prefix(ip_str, &match);
12223 if (!ret) {
12224 vty_out(vty, "address is malformed\n");
12225 return CMD_WARNING;
12226 }
12227
12228 match.family = afi2family(afi);
12229
12230 if (use_json)
12231 json = json_object_new_object();
12232
12233 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12234 for (dest = bgp_table_top(rib); dest;
12235 dest = bgp_route_next(dest)) {
12236 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12237
12238 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12239 continue;
12240 table = bgp_dest_get_bgp_table_info(dest);
12241 if (!table)
12242 continue;
12243
12244 rm = bgp_node_match(table, &match);
12245 if (rm == NULL)
12246 continue;
12247
12248 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12249 if (prefix_check
12250 && rm_p->prefixlen != match.prefixlen) {
12251 bgp_dest_unlock_node(rm);
12252 continue;
12253 }
12254
12255 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12256 bgp, afi, safi, json, pathtype,
12257 &display, rpki_target_state);
12258
12259 bgp_dest_unlock_node(rm);
12260 }
12261 } else if (safi == SAFI_EVPN) {
12262 struct bgp_dest *longest_pfx;
12263 bool is_exact_pfxlen_match = false;
12264
12265 for (dest = bgp_table_top(rib); dest;
12266 dest = bgp_route_next(dest)) {
12267 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12268
12269 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12270 continue;
12271 table = bgp_dest_get_bgp_table_info(dest);
12272 if (!table)
12273 continue;
12274
12275 longest_pfx = NULL;
12276 is_exact_pfxlen_match = false;
12277 /*
12278 * Search through all the prefixes for a match. The
12279 * pfx's are enumerated in ascending order of pfxlens.
12280 * So, the last pfx match is the longest match. Set
12281 * is_exact_pfxlen_match when we get exact pfxlen match
12282 */
12283 for (rm = bgp_table_top(table); rm;
12284 rm = bgp_route_next(rm)) {
12285 const struct prefix *rm_p =
12286 bgp_dest_get_prefix(rm);
12287 /*
12288 * Get prefixlen of the ip-prefix within type5
12289 * evpn route
12290 */
12291 if (evpn_type5_prefix_match(rm_p, &match)
12292 && rm->info) {
12293 longest_pfx = rm;
12294 int type5_pfxlen =
12295 bgp_evpn_get_type5_prefixlen(
12296 rm_p);
12297 if (type5_pfxlen == match.prefixlen) {
12298 is_exact_pfxlen_match = true;
12299 bgp_dest_unlock_node(rm);
12300 break;
12301 }
12302 }
12303 }
12304
12305 if (!longest_pfx)
12306 continue;
12307
12308 if (prefix_check && !is_exact_pfxlen_match)
12309 continue;
12310
12311 rm = longest_pfx;
12312 bgp_dest_lock_node(rm);
12313
12314 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12315 bgp, afi, safi, json, pathtype,
12316 &display, rpki_target_state);
12317
12318 bgp_dest_unlock_node(rm);
12319 }
12320 } else if (safi == SAFI_FLOWSPEC) {
12321 if (use_json)
12322 json_paths = json_object_new_array();
12323
12324 display = bgp_flowspec_display_match_per_ip(afi, rib,
12325 &match, prefix_check,
12326 vty,
12327 use_json,
12328 json_paths);
12329 if (use_json) {
12330 if (display)
12331 json_object_object_add(json, "paths",
12332 json_paths);
12333 else
12334 json_object_free(json_paths);
12335 }
12336 } else {
12337 dest = bgp_node_match(rib, &match);
12338 if (dest != NULL) {
12339 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12340 if (!prefix_check
12341 || dest_p->prefixlen == match.prefixlen) {
12342 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12343 safi, json, pathtype,
12344 &display, rpki_target_state);
12345 }
12346
12347 bgp_dest_unlock_node(dest);
12348 }
12349 }
12350
12351 if (use_json) {
12352 vty_json(vty, json);
12353 } else {
12354 if (!display) {
12355 vty_out(vty, "%% Network not in table\n");
12356 return CMD_WARNING;
12357 }
12358 }
12359
12360 return CMD_SUCCESS;
12361 }
12362
12363 /* Display specified route of Main RIB */
12364 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12365 afi_t afi, safi_t safi, struct prefix_rd *prd,
12366 int prefix_check, enum bgp_path_type pathtype,
12367 enum rpki_states rpki_target_state, bool use_json)
12368 {
12369 if (!bgp) {
12370 bgp = bgp_get_default();
12371 if (!bgp) {
12372 if (!use_json)
12373 vty_out(vty, "No BGP process is configured\n");
12374 else
12375 vty_out(vty, "{}\n");
12376 return CMD_WARNING;
12377 }
12378 }
12379
12380 /* labeled-unicast routes live in the unicast table */
12381 if (safi == SAFI_LABELED_UNICAST)
12382 safi = SAFI_UNICAST;
12383
12384 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12385 afi, safi, rpki_target_state, prd,
12386 prefix_check, pathtype, use_json);
12387 }
12388
12389 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12390 struct cmd_token **argv, bool exact, afi_t afi,
12391 safi_t safi, bool uj)
12392 {
12393 struct lcommunity *lcom;
12394 struct buffer *b;
12395 int i;
12396 char *str;
12397 int first = 0;
12398 uint16_t show_flags = 0;
12399 int ret;
12400
12401 if (uj)
12402 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12403
12404 b = buffer_new(1024);
12405 for (i = 0; i < argc; i++) {
12406 if (first)
12407 buffer_putc(b, ' ');
12408 else {
12409 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12410 first = 1;
12411 buffer_putstr(b, argv[i]->arg);
12412 }
12413 }
12414 }
12415 buffer_putc(b, '\0');
12416
12417 str = buffer_getstr(b);
12418 buffer_free(b);
12419
12420 lcom = lcommunity_str2com(str);
12421 XFREE(MTYPE_TMP, str);
12422 if (!lcom) {
12423 vty_out(vty, "%% Large-community malformed\n");
12424 return CMD_WARNING;
12425 }
12426
12427 ret = bgp_show(vty, bgp, afi, safi,
12428 (exact ? bgp_show_type_lcommunity_exact
12429 : bgp_show_type_lcommunity),
12430 lcom, show_flags, RPKI_NOT_BEING_USED);
12431
12432 lcommunity_free(&lcom);
12433 return ret;
12434 }
12435
12436 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12437 const char *lcom, bool exact, afi_t afi,
12438 safi_t safi, bool uj)
12439 {
12440 struct community_list *list;
12441 uint16_t show_flags = 0;
12442
12443 if (uj)
12444 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12445
12446
12447 list = community_list_lookup(bgp_clist, lcom, 0,
12448 LARGE_COMMUNITY_LIST_MASTER);
12449 if (list == NULL) {
12450 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12451 lcom);
12452 return CMD_WARNING;
12453 }
12454
12455 return bgp_show(vty, bgp, afi, safi,
12456 (exact ? bgp_show_type_lcommunity_list_exact
12457 : bgp_show_type_lcommunity_list),
12458 list, show_flags, RPKI_NOT_BEING_USED);
12459 }
12460
12461 DEFUN (show_ip_bgp_large_community_list,
12462 show_ip_bgp_large_community_list_cmd,
12463 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|LCOMMUNITY_LIST_NAME> [exact-match] [json]",
12464 SHOW_STR
12465 IP_STR
12466 BGP_STR
12467 BGP_INSTANCE_HELP_STR
12468 BGP_AFI_HELP_STR
12469 BGP_SAFI_WITH_LABEL_HELP_STR
12470 "Display routes matching the large-community-list\n"
12471 "large-community-list number\n"
12472 "large-community-list name\n"
12473 "Exact match of the large-communities\n"
12474 JSON_STR)
12475 {
12476 afi_t afi = AFI_IP6;
12477 safi_t safi = SAFI_UNICAST;
12478 int idx = 0;
12479 bool exact_match = 0;
12480 struct bgp *bgp = NULL;
12481 bool uj = use_json(argc, argv);
12482
12483 if (uj)
12484 argc--;
12485
12486 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12487 &bgp, uj);
12488 if (!idx)
12489 return CMD_WARNING;
12490
12491 argv_find(argv, argc, "large-community-list", &idx);
12492
12493 const char *clist_number_or_name = argv[++idx]->arg;
12494
12495 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12496 exact_match = 1;
12497
12498 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12499 exact_match, afi, safi, uj);
12500 }
12501 DEFUN (show_ip_bgp_large_community,
12502 show_ip_bgp_large_community_cmd,
12503 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12504 SHOW_STR
12505 IP_STR
12506 BGP_STR
12507 BGP_INSTANCE_HELP_STR
12508 BGP_AFI_HELP_STR
12509 BGP_SAFI_WITH_LABEL_HELP_STR
12510 "Display routes matching the large-communities\n"
12511 "List of large-community numbers\n"
12512 "Exact match of the large-communities\n"
12513 JSON_STR)
12514 {
12515 afi_t afi = AFI_IP6;
12516 safi_t safi = SAFI_UNICAST;
12517 int idx = 0;
12518 bool exact_match = 0;
12519 struct bgp *bgp = NULL;
12520 bool uj = use_json(argc, argv);
12521 uint16_t show_flags = 0;
12522
12523 if (uj) {
12524 argc--;
12525 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12526 }
12527
12528 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12529 &bgp, uj);
12530 if (!idx)
12531 return CMD_WARNING;
12532
12533 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12534 if (argv_find(argv, argc, "exact-match", &idx)) {
12535 argc--;
12536 exact_match = 1;
12537 }
12538 return bgp_show_lcommunity(vty, bgp, argc, argv,
12539 exact_match, afi, safi, uj);
12540 } else
12541 return bgp_show(vty, bgp, afi, safi,
12542 bgp_show_type_lcommunity_all, NULL, show_flags,
12543 RPKI_NOT_BEING_USED);
12544 }
12545
12546 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12547 safi_t safi, struct json_object *json_array);
12548 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12549 safi_t safi, struct json_object *json);
12550
12551
12552 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12553 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12554 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12555 "Display number of prefixes for all afi/safi\n" JSON_STR)
12556 {
12557 bool uj = use_json(argc, argv);
12558 struct bgp *bgp = NULL;
12559 safi_t safi = SAFI_UNICAST;
12560 afi_t afi = AFI_IP6;
12561 int idx = 0;
12562 struct json_object *json_all = NULL;
12563 struct json_object *json_afi_safi = NULL;
12564
12565 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12566 &bgp, false);
12567 if (!idx)
12568 return CMD_WARNING;
12569
12570 if (uj)
12571 json_all = json_object_new_object();
12572
12573 FOREACH_AFI_SAFI (afi, safi) {
12574 /*
12575 * So limit output to those afi/safi pairs that
12576 * actually have something interesting in them
12577 */
12578 if (strmatch(get_afi_safi_str(afi, safi, true),
12579 "Unknown")) {
12580 continue;
12581 }
12582 if (uj) {
12583 json_afi_safi = json_object_new_array();
12584 json_object_object_add(
12585 json_all,
12586 get_afi_safi_str(afi, safi, true),
12587 json_afi_safi);
12588 } else {
12589 json_afi_safi = NULL;
12590 }
12591
12592 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12593 }
12594
12595 if (uj)
12596 vty_json(vty, json_all);
12597
12598 return CMD_SUCCESS;
12599 }
12600
12601 /* BGP route print out function without JSON */
12602 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12603 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12604 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12605 SHOW_STR
12606 IP_STR
12607 BGP_STR
12608 BGP_INSTANCE_HELP_STR
12609 L2VPN_HELP_STR
12610 EVPN_HELP_STR
12611 "BGP RIB advertisement statistics\n"
12612 JSON_STR)
12613 {
12614 afi_t afi = AFI_IP6;
12615 safi_t safi = SAFI_UNICAST;
12616 struct bgp *bgp = NULL;
12617 int idx = 0, ret;
12618 bool uj = use_json(argc, argv);
12619 struct json_object *json_afi_safi = NULL, *json = NULL;
12620
12621 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12622 &bgp, false);
12623 if (!idx)
12624 return CMD_WARNING;
12625
12626 if (uj)
12627 json_afi_safi = json_object_new_array();
12628 else
12629 json_afi_safi = NULL;
12630
12631 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12632
12633 if (uj) {
12634 json = json_object_new_object();
12635 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12636 json_afi_safi);
12637 vty_json(vty, json);
12638 }
12639 return ret;
12640 }
12641
12642 /* BGP route print out function without JSON */
12643 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12644 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12645 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12646 "]]\
12647 statistics [json]",
12648 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12649 BGP_SAFI_WITH_LABEL_HELP_STR
12650 "BGP RIB advertisement statistics\n" JSON_STR)
12651 {
12652 afi_t afi = AFI_IP6;
12653 safi_t safi = SAFI_UNICAST;
12654 struct bgp *bgp = NULL;
12655 int idx = 0, ret;
12656 bool uj = use_json(argc, argv);
12657 struct json_object *json_afi_safi = NULL, *json = NULL;
12658
12659 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12660 &bgp, false);
12661 if (!idx)
12662 return CMD_WARNING;
12663
12664 if (uj)
12665 json_afi_safi = json_object_new_array();
12666 else
12667 json_afi_safi = NULL;
12668
12669 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12670
12671 if (uj) {
12672 json = json_object_new_object();
12673 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12674 json_afi_safi);
12675 vty_json(vty, json);
12676 }
12677 return ret;
12678 }
12679
12680 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12681 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12682 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12683 "]] [all$all] dampening parameters [json]",
12684 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12685 BGP_SAFI_WITH_LABEL_HELP_STR
12686 "Display the entries for all address families\n"
12687 "Display detailed information about dampening\n"
12688 "Display detail of configured dampening parameters\n"
12689 JSON_STR)
12690 {
12691 afi_t afi = AFI_IP6;
12692 safi_t safi = SAFI_UNICAST;
12693 struct bgp *bgp = NULL;
12694 int idx = 0;
12695 uint16_t show_flags = 0;
12696 bool uj = use_json(argc, argv);
12697
12698 if (uj) {
12699 argc--;
12700 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12701 }
12702
12703 /* [<ipv4|ipv6> [all]] */
12704 if (all) {
12705 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12706 if (argv_find(argv, argc, "ipv4", &idx))
12707 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12708
12709 if (argv_find(argv, argc, "ipv6", &idx))
12710 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12711 }
12712
12713 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12714 &bgp, false);
12715 if (!idx)
12716 return CMD_WARNING;
12717
12718 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12719 }
12720
12721 /* BGP route print out function */
12722 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12723 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12724 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12725 "]]\
12726 [all$all]\
12727 [cidr-only\
12728 |dampening <flap-statistics|dampened-paths>\
12729 |community [AA:NN|local-AS|no-advertise|no-export\
12730 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12731 |accept-own|accept-own-nexthop|route-filter-v6\
12732 |route-filter-v4|route-filter-translated-v6\
12733 |route-filter-translated-v4] [exact-match]\
12734 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12735 |filter-list AS_PATH_FILTER_NAME\
12736 |prefix-list WORD\
12737 |access-list ACCESSLIST_NAME\
12738 |route-map RMAP_NAME\
12739 |rpki <invalid|valid|notfound>\
12740 |version (1-4294967295)\
12741 |alias ALIAS_NAME\
12742 |A.B.C.D/M longer-prefixes\
12743 |X:X::X:X/M longer-prefixes\
12744 |"BGP_SELF_ORIG_CMD_STR"\
12745 |detail-routes$detail_routes\
12746 ] [json$uj [detail$detail_json] | wide$wide]",
12747 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12748 BGP_SAFI_WITH_LABEL_HELP_STR
12749 "Display the entries for all address families\n"
12750 "Display only routes with non-natural netmasks\n"
12751 "Display detailed information about dampening\n"
12752 "Display flap statistics of routes\n"
12753 "Display paths suppressed due to dampening\n"
12754 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12755 "Do not send outside local AS (well-known community)\n"
12756 "Do not advertise to any peer (well-known community)\n"
12757 "Do not export to next AS (well-known community)\n"
12758 "Graceful shutdown (well-known community)\n"
12759 "Do not export to any peer (well-known community)\n"
12760 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12761 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12762 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12763 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12764 "Should accept VPN route with local nexthop (well-known community)\n"
12765 "RT VPNv6 route filtering (well-known community)\n"
12766 "RT VPNv4 route filtering (well-known community)\n"
12767 "RT translated VPNv6 route filtering (well-known community)\n"
12768 "RT translated VPNv4 route filtering (well-known community)\n"
12769 "Exact match of the communities\n"
12770 "Community-list number\n"
12771 "Community-list name\n"
12772 "Display routes matching the community-list\n"
12773 "Exact match of the communities\n"
12774 "Display routes conforming to the filter-list\n"
12775 "Regular expression access list name\n"
12776 "Display routes conforming to the prefix-list\n"
12777 "Prefix-list name\n"
12778 "Display routes conforming to the access-list\n"
12779 "Access-list name\n"
12780 "Display routes matching the route-map\n"
12781 "A route-map to match on\n"
12782 "RPKI route types\n"
12783 "A valid path as determined by rpki\n"
12784 "A invalid path as determined by rpki\n"
12785 "A path that has no rpki data\n"
12786 "Display prefixes with matching version numbers\n"
12787 "Version number and above\n"
12788 "Display prefixes with matching BGP community alias\n"
12789 "BGP community alias\n"
12790 "IPv4 prefix\n"
12791 "Display route and more specific routes\n"
12792 "IPv6 prefix\n"
12793 "Display route and more specific routes\n"
12794 BGP_SELF_ORIG_HELP_STR
12795 "Display detailed version of all routes\n"
12796 JSON_STR
12797 "Display detailed version of JSON output\n"
12798 "Increase table width for longer prefixes\n")
12799 {
12800 afi_t afi = AFI_IP6;
12801 safi_t safi = SAFI_UNICAST;
12802 enum bgp_show_type sh_type = bgp_show_type_normal;
12803 void *output_arg = NULL;
12804 struct bgp *bgp = NULL;
12805 int idx = 0;
12806 int exact_match = 0;
12807 char *community = NULL;
12808 bool first = true;
12809 uint16_t show_flags = 0;
12810 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12811 struct prefix p;
12812
12813 if (uj) {
12814 argc--;
12815 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12816 }
12817
12818 if (detail_json)
12819 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12820
12821 if (detail_routes)
12822 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12823
12824 /* [<ipv4|ipv6> [all]] */
12825 if (all) {
12826 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12827
12828 if (argv_find(argv, argc, "ipv4", &idx))
12829 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12830
12831 if (argv_find(argv, argc, "ipv6", &idx))
12832 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12833 }
12834
12835 if (wide)
12836 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12837
12838 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12839 &bgp, uj);
12840 if (!idx)
12841 return CMD_WARNING;
12842
12843 if (argv_find(argv, argc, "cidr-only", &idx))
12844 sh_type = bgp_show_type_cidr_only;
12845
12846 if (argv_find(argv, argc, "dampening", &idx)) {
12847 if (argv_find(argv, argc, "dampened-paths", &idx))
12848 sh_type = bgp_show_type_dampend_paths;
12849 else if (argv_find(argv, argc, "flap-statistics", &idx))
12850 sh_type = bgp_show_type_flap_statistics;
12851 }
12852
12853 if (argv_find(argv, argc, "community", &idx)) {
12854 char *maybecomm = NULL;
12855
12856 if (idx + 1 < argc) {
12857 if (argv[idx + 1]->type == VARIABLE_TKN)
12858 maybecomm = argv[idx + 1]->arg;
12859 else
12860 maybecomm = argv[idx + 1]->text;
12861 }
12862
12863 if (maybecomm && !strmatch(maybecomm, "json")
12864 && !strmatch(maybecomm, "exact-match"))
12865 community = maybecomm;
12866
12867 if (argv_find(argv, argc, "exact-match", &idx))
12868 exact_match = 1;
12869
12870 if (!community)
12871 sh_type = bgp_show_type_community_all;
12872 }
12873
12874 if (argv_find(argv, argc, "community-list", &idx)) {
12875 const char *clist_number_or_name = argv[++idx]->arg;
12876 struct community_list *list;
12877
12878 if (argv_find(argv, argc, "exact-match", &idx))
12879 exact_match = 1;
12880
12881 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12882 COMMUNITY_LIST_MASTER);
12883 if (list == NULL) {
12884 vty_out(vty, "%% %s community-list not found\n",
12885 clist_number_or_name);
12886 return CMD_WARNING;
12887 }
12888
12889 if (exact_match)
12890 sh_type = bgp_show_type_community_list_exact;
12891 else
12892 sh_type = bgp_show_type_community_list;
12893 output_arg = list;
12894 }
12895
12896 if (argv_find(argv, argc, "filter-list", &idx)) {
12897 const char *filter = argv[++idx]->arg;
12898 struct as_list *as_list;
12899
12900 as_list = as_list_lookup(filter);
12901 if (as_list == NULL) {
12902 vty_out(vty, "%% %s AS-path access-list not found\n",
12903 filter);
12904 return CMD_WARNING;
12905 }
12906
12907 sh_type = bgp_show_type_filter_list;
12908 output_arg = as_list;
12909 }
12910
12911 if (argv_find(argv, argc, "prefix-list", &idx)) {
12912 const char *prefix_list_str = argv[++idx]->arg;
12913 struct prefix_list *plist;
12914
12915 plist = prefix_list_lookup(afi, prefix_list_str);
12916 if (plist == NULL) {
12917 vty_out(vty, "%% %s prefix-list not found\n",
12918 prefix_list_str);
12919 return CMD_WARNING;
12920 }
12921
12922 sh_type = bgp_show_type_prefix_list;
12923 output_arg = plist;
12924 }
12925
12926 if (argv_find(argv, argc, "access-list", &idx)) {
12927 const char *access_list_str = argv[++idx]->arg;
12928 struct access_list *alist;
12929
12930 alist = access_list_lookup(afi, access_list_str);
12931 if (!alist) {
12932 vty_out(vty, "%% %s access-list not found\n",
12933 access_list_str);
12934 return CMD_WARNING;
12935 }
12936
12937 sh_type = bgp_show_type_access_list;
12938 output_arg = alist;
12939 }
12940
12941 if (argv_find(argv, argc, "route-map", &idx)) {
12942 const char *rmap_str = argv[++idx]->arg;
12943 struct route_map *rmap;
12944
12945 rmap = route_map_lookup_by_name(rmap_str);
12946 if (!rmap) {
12947 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12948 return CMD_WARNING;
12949 }
12950
12951 sh_type = bgp_show_type_route_map;
12952 output_arg = rmap;
12953 }
12954
12955 if (argv_find(argv, argc, "rpki", &idx)) {
12956 sh_type = bgp_show_type_rpki;
12957 if (argv_find(argv, argc, "valid", &idx))
12958 rpki_target_state = RPKI_VALID;
12959 else if (argv_find(argv, argc, "invalid", &idx))
12960 rpki_target_state = RPKI_INVALID;
12961 }
12962
12963 /* Display prefixes with matching version numbers */
12964 if (argv_find(argv, argc, "version", &idx)) {
12965 sh_type = bgp_show_type_prefix_version;
12966 output_arg = argv[idx + 1]->arg;
12967 }
12968
12969 /* Display prefixes with matching BGP community alias */
12970 if (argv_find(argv, argc, "alias", &idx)) {
12971 sh_type = bgp_show_type_community_alias;
12972 output_arg = argv[idx + 1]->arg;
12973 }
12974
12975 /* prefix-longer */
12976 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12977 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12978 const char *prefix_str = argv[idx]->arg;
12979
12980 if (!str2prefix(prefix_str, &p)) {
12981 vty_out(vty, "%% Malformed Prefix\n");
12982 return CMD_WARNING;
12983 }
12984
12985 sh_type = bgp_show_type_prefix_longer;
12986 output_arg = &p;
12987 }
12988
12989 /* self originated only */
12990 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12991 sh_type = bgp_show_type_self_originated;
12992
12993 if (!all) {
12994 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12995 if (community)
12996 return bgp_show_community(vty, bgp, community,
12997 exact_match, afi, safi,
12998 show_flags);
12999 else
13000 return bgp_show(vty, bgp, afi, safi, sh_type,
13001 output_arg, show_flags,
13002 rpki_target_state);
13003 } else {
13004 struct listnode *node;
13005 struct bgp *abgp;
13006 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
13007 * AFI_IP6 */
13008
13009 if (uj)
13010 vty_out(vty, "{\n");
13011
13012 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13013 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
13014 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13015 ? AFI_IP
13016 : AFI_IP6;
13017 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13018 FOREACH_SAFI (safi) {
13019 if (!bgp_afi_safi_peer_exists(abgp, afi,
13020 safi))
13021 continue;
13022
13023 if (uj) {
13024 if (first)
13025 first = false;
13026 else
13027 vty_out(vty, ",\n");
13028 vty_out(vty, "\"%s\":{\n",
13029 get_afi_safi_str(afi,
13030 safi,
13031 true));
13032 } else
13033 vty_out(vty,
13034 "\nFor address family: %s\n",
13035 get_afi_safi_str(
13036 afi, safi,
13037 false));
13038
13039 if (community)
13040 bgp_show_community(
13041 vty, abgp, community,
13042 exact_match, afi, safi,
13043 show_flags);
13044 else
13045 bgp_show(vty, abgp, afi, safi,
13046 sh_type, output_arg,
13047 show_flags,
13048 rpki_target_state);
13049 if (uj)
13050 vty_out(vty, "}\n");
13051 }
13052 }
13053 } else {
13054 /* show <ip> bgp all: for each AFI and SAFI*/
13055 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13056 FOREACH_AFI_SAFI (afi, safi) {
13057 if (!bgp_afi_safi_peer_exists(abgp, afi,
13058 safi))
13059 continue;
13060
13061 if (uj) {
13062 if (first)
13063 first = false;
13064 else
13065 vty_out(vty, ",\n");
13066
13067 vty_out(vty, "\"%s\":{\n",
13068 get_afi_safi_str(afi,
13069 safi,
13070 true));
13071 } else
13072 vty_out(vty,
13073 "\nFor address family: %s\n",
13074 get_afi_safi_str(
13075 afi, safi,
13076 false));
13077
13078 if (community)
13079 bgp_show_community(
13080 vty, abgp, community,
13081 exact_match, afi, safi,
13082 show_flags);
13083 else
13084 bgp_show(vty, abgp, afi, safi,
13085 sh_type, output_arg,
13086 show_flags,
13087 rpki_target_state);
13088 if (uj)
13089 vty_out(vty, "}\n");
13090 }
13091 }
13092 }
13093 if (uj)
13094 vty_out(vty, "}\n");
13095 }
13096 return CMD_SUCCESS;
13097 }
13098
13099 DEFUN (show_ip_bgp_route,
13100 show_ip_bgp_route_cmd,
13101 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]]<A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [<bestpath|multipath>] [rpki <valid|invalid|notfound>] [json]",
13102 SHOW_STR
13103 IP_STR
13104 BGP_STR
13105 BGP_INSTANCE_HELP_STR
13106 BGP_AFI_HELP_STR
13107 BGP_SAFI_WITH_LABEL_HELP_STR
13108 "Network in the BGP routing table to display\n"
13109 "IPv4 prefix\n"
13110 "Network in the BGP routing table to display\n"
13111 "IPv6 prefix\n"
13112 "Display only the bestpath\n"
13113 "Display only multipaths\n"
13114 "Display only paths that match the specified rpki state\n"
13115 "A valid path as determined by rpki\n"
13116 "A invalid path as determined by rpki\n"
13117 "A path that has no rpki data\n"
13118 JSON_STR)
13119 {
13120 int prefix_check = 0;
13121
13122 afi_t afi = AFI_IP6;
13123 safi_t safi = SAFI_UNICAST;
13124 char *prefix = NULL;
13125 struct bgp *bgp = NULL;
13126 enum bgp_path_type path_type;
13127 bool uj = use_json(argc, argv);
13128
13129 int idx = 0;
13130
13131 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13132 &bgp, uj);
13133 if (!idx)
13134 return CMD_WARNING;
13135
13136 if (!bgp) {
13137 vty_out(vty,
13138 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13139 return CMD_WARNING;
13140 }
13141
13142 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13143 if (argv_find(argv, argc, "A.B.C.D", &idx)
13144 || argv_find(argv, argc, "X:X::X:X", &idx))
13145 prefix_check = 0;
13146 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13147 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13148 prefix_check = 1;
13149
13150 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13151 && afi != AFI_IP6) {
13152 vty_out(vty,
13153 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13154 return CMD_WARNING;
13155 }
13156 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13157 && afi != AFI_IP) {
13158 vty_out(vty,
13159 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13160 return CMD_WARNING;
13161 }
13162
13163 prefix = argv[idx]->arg;
13164
13165 /* [<bestpath|multipath>] */
13166 if (argv_find(argv, argc, "bestpath", &idx))
13167 path_type = BGP_PATH_SHOW_BESTPATH;
13168 else if (argv_find(argv, argc, "multipath", &idx))
13169 path_type = BGP_PATH_SHOW_MULTIPATH;
13170 else
13171 path_type = BGP_PATH_SHOW_ALL;
13172
13173 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13174 path_type, RPKI_NOT_BEING_USED, uj);
13175 }
13176
13177 DEFUN (show_ip_bgp_regexp,
13178 show_ip_bgp_regexp_cmd,
13179 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13180 SHOW_STR
13181 IP_STR
13182 BGP_STR
13183 BGP_INSTANCE_HELP_STR
13184 BGP_AFI_HELP_STR
13185 BGP_SAFI_WITH_LABEL_HELP_STR
13186 "Display routes matching the AS path regular expression\n"
13187 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13188 JSON_STR)
13189 {
13190 afi_t afi = AFI_IP6;
13191 safi_t safi = SAFI_UNICAST;
13192 struct bgp *bgp = NULL;
13193 bool uj = use_json(argc, argv);
13194 char *regstr = NULL;
13195
13196 int idx = 0;
13197 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13198 &bgp, false);
13199 if (!idx)
13200 return CMD_WARNING;
13201
13202 // get index of regex
13203 if (argv_find(argv, argc, "REGEX", &idx))
13204 regstr = argv[idx]->arg;
13205
13206 assert(regstr);
13207 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13208 bgp_show_type_regexp, uj);
13209 }
13210
13211 DEFPY (show_ip_bgp_instance_all,
13212 show_ip_bgp_instance_all_cmd,
13213 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13214 SHOW_STR
13215 IP_STR
13216 BGP_STR
13217 BGP_INSTANCE_ALL_HELP_STR
13218 BGP_AFI_HELP_STR
13219 BGP_SAFI_WITH_LABEL_HELP_STR
13220 JSON_STR
13221 "Increase table width for longer prefixes\n")
13222 {
13223 afi_t afi = AFI_IP6;
13224 safi_t safi = SAFI_UNICAST;
13225 struct bgp *bgp = NULL;
13226 int idx = 0;
13227 uint16_t show_flags = 0;
13228
13229 if (uj) {
13230 argc--;
13231 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13232 }
13233
13234 if (wide)
13235 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13236
13237 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13238 &bgp, uj);
13239 if (!idx)
13240 return CMD_WARNING;
13241
13242 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13243 return CMD_SUCCESS;
13244 }
13245
13246 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13247 afi_t afi, safi_t safi, enum bgp_show_type type,
13248 bool use_json)
13249 {
13250 regex_t *regex;
13251 int rc;
13252 uint16_t show_flags = 0;
13253
13254 if (use_json)
13255 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13256
13257 if (!config_bgp_aspath_validate(regstr)) {
13258 vty_out(vty, "Invalid character in REGEX %s\n",
13259 regstr);
13260 return CMD_WARNING_CONFIG_FAILED;
13261 }
13262
13263 regex = bgp_regcomp(regstr);
13264 if (!regex) {
13265 vty_out(vty, "Can't compile regexp %s\n", regstr);
13266 return CMD_WARNING;
13267 }
13268
13269 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13270 RPKI_NOT_BEING_USED);
13271 bgp_regex_free(regex);
13272 return rc;
13273 }
13274
13275 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13276 const char *comstr, int exact, afi_t afi,
13277 safi_t safi, uint16_t show_flags)
13278 {
13279 struct community *com;
13280 int ret = 0;
13281
13282 com = community_str2com(comstr);
13283 if (!com) {
13284 vty_out(vty, "%% Community malformed: %s\n", comstr);
13285 return CMD_WARNING;
13286 }
13287
13288 ret = bgp_show(vty, bgp, afi, safi,
13289 (exact ? bgp_show_type_community_exact
13290 : bgp_show_type_community),
13291 com, show_flags, RPKI_NOT_BEING_USED);
13292 community_free(&com);
13293
13294 return ret;
13295 }
13296
13297 enum bgp_stats {
13298 BGP_STATS_MAXBITLEN = 0,
13299 BGP_STATS_RIB,
13300 BGP_STATS_PREFIXES,
13301 BGP_STATS_TOTPLEN,
13302 BGP_STATS_UNAGGREGATEABLE,
13303 BGP_STATS_MAX_AGGREGATEABLE,
13304 BGP_STATS_AGGREGATES,
13305 BGP_STATS_SPACE,
13306 BGP_STATS_ASPATH_COUNT,
13307 BGP_STATS_ASPATH_MAXHOPS,
13308 BGP_STATS_ASPATH_TOTHOPS,
13309 BGP_STATS_ASPATH_MAXSIZE,
13310 BGP_STATS_ASPATH_TOTSIZE,
13311 BGP_STATS_ASN_HIGHEST,
13312 BGP_STATS_MAX,
13313 };
13314
13315 #define TABLE_STATS_IDX_VTY 0
13316 #define TABLE_STATS_IDX_JSON 1
13317
13318 static const char *table_stats_strs[][2] = {
13319 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13320 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13321 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13322 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13323 "unaggregateablePrefixes"},
13324 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13325 "maximumAggregateablePrefixes"},
13326 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13327 "bgpAggregateAdvertisements"},
13328 [BGP_STATS_SPACE] = {"Address space advertised",
13329 "addressSpaceAdvertised"},
13330 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13331 "advertisementsWithPaths"},
13332 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13333 "longestAsPath"},
13334 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13335 "largestAsPath"},
13336 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13337 "averageAsPathLengthHops"},
13338 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13339 "averageAsPathSizeBytes"},
13340 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13341 [BGP_STATS_MAX] = {NULL, NULL}
13342 };
13343
13344 struct bgp_table_stats {
13345 struct bgp_table *table;
13346 unsigned long long counts[BGP_STATS_MAX];
13347
13348 unsigned long long
13349 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13350 1];
13351
13352 double total_space;
13353 };
13354
13355 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13356 struct bgp_table_stats *ts, unsigned int space)
13357 {
13358 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13359 struct bgp_path_info *pi;
13360 const struct prefix *rn_p;
13361
13362 if (!bgp_dest_has_bgp_path_info_data(dest))
13363 return;
13364
13365 rn_p = bgp_dest_get_prefix(dest);
13366 ts->counts[BGP_STATS_PREFIXES]++;
13367 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13368
13369 ts->prefix_len_count[rn_p->prefixlen]++;
13370 /* check if the prefix is included by any other announcements */
13371 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13372 pdest = bgp_dest_parent_nolock(pdest);
13373
13374 if (pdest == NULL || pdest == top) {
13375 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13376 /* announced address space */
13377 if (space)
13378 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13379 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13380 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13381
13382
13383 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13384 ts->counts[BGP_STATS_RIB]++;
13385
13386 if (CHECK_FLAG(pi->attr->flag,
13387 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13388 ts->counts[BGP_STATS_AGGREGATES]++;
13389
13390 /* as-path stats */
13391 if (pi->attr->aspath) {
13392 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13393 unsigned int size = aspath_size(pi->attr->aspath);
13394 as_t highest = aspath_highest(pi->attr->aspath);
13395
13396 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13397
13398 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13399 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13400
13401 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13402 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13403
13404 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13405 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13406 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13407 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13408 }
13409 }
13410 }
13411
13412 static void bgp_table_stats_walker(struct event *t)
13413 {
13414 struct bgp_dest *dest, *ndest;
13415 struct bgp_dest *top;
13416 struct bgp_table_stats *ts = EVENT_ARG(t);
13417 unsigned int space = 0;
13418
13419 if (!(top = bgp_table_top(ts->table)))
13420 return;
13421
13422 switch (ts->table->afi) {
13423 case AFI_IP:
13424 space = IPV4_MAX_BITLEN;
13425 break;
13426 case AFI_IP6:
13427 space = IPV6_MAX_BITLEN;
13428 break;
13429 case AFI_L2VPN:
13430 space = EVPN_ROUTE_PREFIXLEN;
13431 break;
13432 case AFI_UNSPEC:
13433 case AFI_MAX:
13434 return;
13435 }
13436
13437 ts->counts[BGP_STATS_MAXBITLEN] = space;
13438
13439 for (dest = top; dest; dest = bgp_route_next(dest)) {
13440 if (ts->table->safi == SAFI_MPLS_VPN
13441 || ts->table->safi == SAFI_ENCAP
13442 || ts->table->safi == SAFI_EVPN) {
13443 struct bgp_table *table;
13444
13445 table = bgp_dest_get_bgp_table_info(dest);
13446 if (!table)
13447 continue;
13448
13449 top = bgp_table_top(table);
13450 for (ndest = bgp_table_top(table); ndest;
13451 ndest = bgp_route_next(ndest))
13452 bgp_table_stats_rn(ndest, top, ts, space);
13453 } else {
13454 bgp_table_stats_rn(dest, top, ts, space);
13455 }
13456 }
13457 }
13458
13459 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13460 struct json_object *json_array)
13461 {
13462 struct listnode *node, *nnode;
13463 struct bgp *bgp;
13464
13465 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13466 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13467 }
13468
13469 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13470 safi_t safi, struct json_object *json_array)
13471 {
13472 struct bgp_table_stats ts;
13473 unsigned int i;
13474 int ret = CMD_SUCCESS;
13475 char temp_buf[20];
13476 struct json_object *json = NULL;
13477 uint32_t bitlen = 0;
13478 struct json_object *json_bitlen;
13479
13480 if (json_array)
13481 json = json_object_new_object();
13482
13483 if (!bgp->rib[afi][safi]) {
13484 char warning_msg[50];
13485
13486 snprintf(warning_msg, sizeof(warning_msg),
13487 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13488 safi);
13489
13490 if (!json)
13491 vty_out(vty, "%s\n", warning_msg);
13492 else
13493 json_object_string_add(json, "warning", warning_msg);
13494
13495 ret = CMD_WARNING;
13496 goto end_table_stats;
13497 }
13498
13499 if (!json)
13500 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13501 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13502 else
13503 json_object_string_add(json, "instance", bgp->name_pretty);
13504
13505 /* labeled-unicast routes live in the unicast table */
13506 if (safi == SAFI_LABELED_UNICAST)
13507 safi = SAFI_UNICAST;
13508
13509 memset(&ts, 0, sizeof(ts));
13510 ts.table = bgp->rib[afi][safi];
13511 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13512
13513 for (i = 0; i < BGP_STATS_MAX; i++) {
13514 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13515 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13516 continue;
13517
13518 switch (i) {
13519 case BGP_STATS_ASPATH_TOTHOPS:
13520 case BGP_STATS_ASPATH_TOTSIZE:
13521 if (!json) {
13522 snprintf(
13523 temp_buf, sizeof(temp_buf), "%12.2f",
13524 ts.counts[i]
13525 ? (float)ts.counts[i]
13526 / (float)ts.counts
13527 [BGP_STATS_ASPATH_COUNT]
13528 : 0);
13529 vty_out(vty, "%-30s: %s",
13530 table_stats_strs[i]
13531 [TABLE_STATS_IDX_VTY],
13532 temp_buf);
13533 } else {
13534 json_object_double_add(
13535 json,
13536 table_stats_strs[i]
13537 [TABLE_STATS_IDX_JSON],
13538 ts.counts[i]
13539 ? (double)ts.counts[i]
13540 / (double)ts.counts
13541 [BGP_STATS_ASPATH_COUNT]
13542 : 0);
13543 }
13544 break;
13545 case BGP_STATS_TOTPLEN:
13546 if (!json) {
13547 snprintf(
13548 temp_buf, sizeof(temp_buf), "%12.2f",
13549 ts.counts[i]
13550 ? (float)ts.counts[i]
13551 / (float)ts.counts
13552 [BGP_STATS_PREFIXES]
13553 : 0);
13554 vty_out(vty, "%-30s: %s",
13555 table_stats_strs[i]
13556 [TABLE_STATS_IDX_VTY],
13557 temp_buf);
13558 } else {
13559 json_object_double_add(
13560 json,
13561 table_stats_strs[i]
13562 [TABLE_STATS_IDX_JSON],
13563 ts.counts[i]
13564 ? (double)ts.counts[i]
13565 / (double)ts.counts
13566 [BGP_STATS_PREFIXES]
13567 : 0);
13568 }
13569 break;
13570 case BGP_STATS_SPACE:
13571 if (!json) {
13572 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13573 ts.total_space);
13574 vty_out(vty, "%-30s: %s\n",
13575 table_stats_strs[i]
13576 [TABLE_STATS_IDX_VTY],
13577 temp_buf);
13578 } else {
13579 json_object_double_add(
13580 json,
13581 table_stats_strs[i]
13582 [TABLE_STATS_IDX_JSON],
13583 (double)ts.total_space);
13584 }
13585 if (afi == AFI_IP6) {
13586 if (!json) {
13587 snprintf(temp_buf, sizeof(temp_buf),
13588 "%12g",
13589 ts.total_space
13590 * pow(2.0, -128 + 32));
13591 vty_out(vty, "%30s: %s\n",
13592 "/32 equivalent %s\n",
13593 temp_buf);
13594 } else {
13595 json_object_double_add(
13596 json, "/32equivalent",
13597 (double)(ts.total_space
13598 * pow(2.0,
13599 -128 + 32)));
13600 }
13601 if (!json) {
13602 snprintf(temp_buf, sizeof(temp_buf),
13603 "%12g",
13604 ts.total_space
13605 * pow(2.0, -128 + 48));
13606 vty_out(vty, "%30s: %s\n",
13607 "/48 equivalent %s\n",
13608 temp_buf);
13609 } else {
13610 json_object_double_add(
13611 json, "/48equivalent",
13612 (double)(ts.total_space
13613 * pow(2.0,
13614 -128 + 48)));
13615 }
13616 } else {
13617 if (!json) {
13618 snprintf(temp_buf, sizeof(temp_buf),
13619 "%12.2f",
13620 ts.total_space * 100.
13621 * pow(2.0, -32));
13622 vty_out(vty, "%30s: %s\n",
13623 "% announced ", temp_buf);
13624 } else {
13625 json_object_double_add(
13626 json, "%announced",
13627 (double)(ts.total_space * 100.
13628 * pow(2.0, -32)));
13629 }
13630 if (!json) {
13631 snprintf(temp_buf, sizeof(temp_buf),
13632 "%12.2f",
13633 ts.total_space
13634 * pow(2.0, -32 + 8));
13635 vty_out(vty, "%30s: %s\n",
13636 "/8 equivalent ", temp_buf);
13637 } else {
13638 json_object_double_add(
13639 json, "/8equivalent",
13640 (double)(ts.total_space
13641 * pow(2.0, -32 + 8)));
13642 }
13643 if (!json) {
13644 snprintf(temp_buf, sizeof(temp_buf),
13645 "%12.2f",
13646 ts.total_space
13647 * pow(2.0, -32 + 24));
13648 vty_out(vty, "%30s: %s\n",
13649 "/24 equivalent ", temp_buf);
13650 } else {
13651 json_object_double_add(
13652 json, "/24equivalent",
13653 (double)(ts.total_space
13654 * pow(2.0, -32 + 24)));
13655 }
13656 }
13657 break;
13658 default:
13659 if (!json) {
13660 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13661 ts.counts[i]);
13662 vty_out(vty, "%-30s: %s",
13663 table_stats_strs[i]
13664 [TABLE_STATS_IDX_VTY],
13665 temp_buf);
13666 } else {
13667 json_object_int_add(
13668 json,
13669 table_stats_strs[i]
13670 [TABLE_STATS_IDX_JSON],
13671 ts.counts[i]);
13672 }
13673 }
13674 if (!json)
13675 vty_out(vty, "\n");
13676 }
13677
13678 switch (afi) {
13679 case AFI_IP:
13680 bitlen = IPV4_MAX_BITLEN;
13681 break;
13682 case AFI_IP6:
13683 bitlen = IPV6_MAX_BITLEN;
13684 break;
13685 case AFI_L2VPN:
13686 bitlen = EVPN_ROUTE_PREFIXLEN;
13687 break;
13688 case AFI_UNSPEC:
13689 case AFI_MAX:
13690 break;
13691 }
13692
13693 if (json) {
13694 json_bitlen = json_object_new_array();
13695
13696 for (i = 0; i <= bitlen; i++) {
13697 struct json_object *ind_bit = json_object_new_object();
13698
13699 if (!ts.prefix_len_count[i])
13700 continue;
13701
13702 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13703 json_object_int_add(ind_bit, temp_buf,
13704 ts.prefix_len_count[i]);
13705 json_object_array_add(json_bitlen, ind_bit);
13706 }
13707 json_object_object_add(json, "prefixLength", json_bitlen);
13708 }
13709
13710 end_table_stats:
13711 if (json)
13712 json_object_array_add(json_array, json);
13713 return ret;
13714 }
13715
13716 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13717 safi_t safi, struct json_object *json_array)
13718 {
13719 if (!bgp) {
13720 bgp_table_stats_all(vty, afi, safi, json_array);
13721 return CMD_SUCCESS;
13722 }
13723
13724 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13725 }
13726
13727 enum bgp_pcounts {
13728 PCOUNT_ADJ_IN = 0,
13729 PCOUNT_DAMPED,
13730 PCOUNT_REMOVED,
13731 PCOUNT_HISTORY,
13732 PCOUNT_STALE,
13733 PCOUNT_VALID,
13734 PCOUNT_ALL,
13735 PCOUNT_COUNTED,
13736 PCOUNT_BPATH_SELECTED,
13737 PCOUNT_PFCNT, /* the figure we display to users */
13738 PCOUNT_MAX,
13739 };
13740
13741 static const char *const pcount_strs[] = {
13742 [PCOUNT_ADJ_IN] = "Adj-in",
13743 [PCOUNT_DAMPED] = "Damped",
13744 [PCOUNT_REMOVED] = "Removed",
13745 [PCOUNT_HISTORY] = "History",
13746 [PCOUNT_STALE] = "Stale",
13747 [PCOUNT_VALID] = "Valid",
13748 [PCOUNT_ALL] = "All RIB",
13749 [PCOUNT_COUNTED] = "PfxCt counted",
13750 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13751 [PCOUNT_PFCNT] = "Useable",
13752 [PCOUNT_MAX] = NULL,
13753 };
13754
13755 struct peer_pcounts {
13756 unsigned int count[PCOUNT_MAX];
13757 const struct peer *peer;
13758 const struct bgp_table *table;
13759 safi_t safi;
13760 };
13761
13762 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13763 {
13764 const struct bgp_adj_in *ain;
13765 const struct bgp_path_info *pi;
13766 const struct peer *peer = pc->peer;
13767
13768 for (ain = rn->adj_in; ain; ain = ain->next)
13769 if (ain->peer == peer)
13770 pc->count[PCOUNT_ADJ_IN]++;
13771
13772 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13773
13774 if (pi->peer != peer)
13775 continue;
13776
13777 pc->count[PCOUNT_ALL]++;
13778
13779 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13780 pc->count[PCOUNT_DAMPED]++;
13781 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13782 pc->count[PCOUNT_HISTORY]++;
13783 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13784 pc->count[PCOUNT_REMOVED]++;
13785 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13786 pc->count[PCOUNT_STALE]++;
13787 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13788 pc->count[PCOUNT_VALID]++;
13789 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13790 pc->count[PCOUNT_PFCNT]++;
13791 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13792 pc->count[PCOUNT_BPATH_SELECTED]++;
13793
13794 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13795 pc->count[PCOUNT_COUNTED]++;
13796 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13797 flog_err(
13798 EC_LIB_DEVELOPMENT,
13799 "Attempting to count but flags say it is unusable");
13800 } else {
13801 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13802 flog_err(
13803 EC_LIB_DEVELOPMENT,
13804 "Not counted but flags say we should");
13805 }
13806 }
13807 }
13808
13809 static void bgp_peer_count_walker(struct event *t)
13810 {
13811 struct bgp_dest *rn, *rm;
13812 const struct bgp_table *table;
13813 struct peer_pcounts *pc = EVENT_ARG(t);
13814
13815 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13816 || pc->safi == SAFI_EVPN) {
13817 /* Special handling for 2-level routing tables. */
13818 for (rn = bgp_table_top(pc->table); rn;
13819 rn = bgp_route_next(rn)) {
13820 table = bgp_dest_get_bgp_table_info(rn);
13821 if (table != NULL)
13822 for (rm = bgp_table_top(table); rm;
13823 rm = bgp_route_next(rm))
13824 bgp_peer_count_proc(rm, pc);
13825 }
13826 } else
13827 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13828 bgp_peer_count_proc(rn, pc);
13829 }
13830
13831 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13832 safi_t safi, bool use_json)
13833 {
13834 struct peer_pcounts pcounts = {.peer = peer};
13835 unsigned int i;
13836 json_object *json = NULL;
13837 json_object *json_loop = NULL;
13838
13839 if (use_json) {
13840 json = json_object_new_object();
13841 json_loop = json_object_new_object();
13842 }
13843
13844 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13845 || !peer->bgp->rib[afi][safi]) {
13846 if (use_json) {
13847 json_object_string_add(
13848 json, "warning",
13849 "No such neighbor or address family");
13850 vty_out(vty, "%s\n", json_object_to_json_string(json));
13851 json_object_free(json);
13852 json_object_free(json_loop);
13853 } else
13854 vty_out(vty, "%% No such neighbor or address family\n");
13855
13856 return CMD_WARNING;
13857 }
13858
13859 memset(&pcounts, 0, sizeof(pcounts));
13860 pcounts.peer = peer;
13861 pcounts.table = peer->bgp->rib[afi][safi];
13862 pcounts.safi = safi;
13863
13864 /* in-place call via thread subsystem so as to record execution time
13865 * stats for the thread-walk (i.e. ensure this can't be blamed on
13866 * on just vty_read()).
13867 */
13868 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13869
13870 if (use_json) {
13871 json_object_string_add(json, "prefixCountsFor", peer->host);
13872 json_object_string_add(json, "multiProtocol",
13873 get_afi_safi_str(afi, safi, true));
13874 json_object_int_add(json, "pfxCounter",
13875 peer->pcount[afi][safi]);
13876
13877 for (i = 0; i < PCOUNT_MAX; i++)
13878 json_object_int_add(json_loop, pcount_strs[i],
13879 pcounts.count[i]);
13880
13881 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13882
13883 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13884 json_object_string_add(json, "pfxctDriftFor",
13885 peer->host);
13886 json_object_string_add(
13887 json, "recommended",
13888 "Please report this bug, with the above command output");
13889 }
13890 vty_json(vty, json);
13891 } else {
13892
13893 if (peer->hostname
13894 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13895 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13896 peer->hostname, peer->host,
13897 get_afi_safi_str(afi, safi, false));
13898 } else {
13899 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13900 get_afi_safi_str(afi, safi, false));
13901 }
13902
13903 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13904 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13905
13906 for (i = 0; i < PCOUNT_MAX; i++)
13907 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13908 pcounts.count[i]);
13909
13910 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13911 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13912 vty_out(vty,
13913 "Please report this bug, with the above command output\n");
13914 }
13915 }
13916
13917 return CMD_SUCCESS;
13918 }
13919
13920 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13921 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13922 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13923 SHOW_STR
13924 IP_STR
13925 BGP_STR
13926 BGP_INSTANCE_HELP_STR
13927 BGP_AFI_HELP_STR
13928 BGP_SAFI_HELP_STR
13929 "Detailed information on TCP and BGP neighbor connections\n"
13930 "Neighbor to display information about\n"
13931 "Neighbor to display information about\n"
13932 "Neighbor on BGP configured interface\n"
13933 "Display detailed prefix count information\n"
13934 JSON_STR)
13935 {
13936 afi_t afi = AFI_IP6;
13937 safi_t safi = SAFI_UNICAST;
13938 struct peer *peer;
13939 int idx = 0;
13940 struct bgp *bgp = NULL;
13941 bool uj = use_json(argc, argv);
13942
13943 if (uj)
13944 argc--;
13945
13946 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13947 &bgp, uj);
13948 if (!idx)
13949 return CMD_WARNING;
13950
13951 argv_find(argv, argc, "neighbors", &idx);
13952 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13953 if (!peer)
13954 return CMD_WARNING;
13955
13956 return bgp_peer_counts(vty, peer, afi, safi, uj);
13957 }
13958
13959 #ifdef KEEP_OLD_VPN_COMMANDS
13960 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13961 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13962 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13963 SHOW_STR
13964 IP_STR
13965 BGP_STR
13966 BGP_VPNVX_HELP_STR
13967 "Display information about all VPNv4 NLRIs\n"
13968 "Detailed information on TCP and BGP neighbor connections\n"
13969 "Neighbor to display information about\n"
13970 "Neighbor to display information about\n"
13971 "Neighbor on BGP configured interface\n"
13972 "Display detailed prefix count information\n"
13973 JSON_STR)
13974 {
13975 int idx_peer = 6;
13976 struct peer *peer;
13977 bool uj = use_json(argc, argv);
13978
13979 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13980 if (!peer)
13981 return CMD_WARNING;
13982
13983 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13984 }
13985
13986 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13987 show_ip_bgp_vpn_all_route_prefix_cmd,
13988 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13989 SHOW_STR
13990 IP_STR
13991 BGP_STR
13992 BGP_VPNVX_HELP_STR
13993 "Display information about all VPNv4 NLRIs\n"
13994 "Network in the BGP routing table to display\n"
13995 "Network in the BGP routing table to display\n"
13996 JSON_STR)
13997 {
13998 int idx = 0;
13999 char *network = NULL;
14000 struct bgp *bgp = bgp_get_default();
14001 if (!bgp) {
14002 vty_out(vty, "Can't find default instance\n");
14003 return CMD_WARNING;
14004 }
14005
14006 if (argv_find(argv, argc, "A.B.C.D", &idx))
14007 network = argv[idx]->arg;
14008 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
14009 network = argv[idx]->arg;
14010 else {
14011 vty_out(vty, "Unable to figure out Network\n");
14012 return CMD_WARNING;
14013 }
14014
14015 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
14016 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14017 use_json(argc, argv));
14018 }
14019 #endif /* KEEP_OLD_VPN_COMMANDS */
14020
14021 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
14022 show_bgp_l2vpn_evpn_route_prefix_cmd,
14023 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
14024 SHOW_STR
14025 BGP_STR
14026 L2VPN_HELP_STR
14027 EVPN_HELP_STR
14028 "Network in the BGP routing table to display\n"
14029 "Network in the BGP routing table to display\n"
14030 "Network in the BGP routing table to display\n"
14031 "Network in the BGP routing table to display\n"
14032 JSON_STR)
14033 {
14034 int idx = 0;
14035 char *network = NULL;
14036 int prefix_check = 0;
14037
14038 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
14039 argv_find(argv, argc, "X:X::X:X", &idx))
14040 network = argv[idx]->arg;
14041 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
14042 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
14043 network = argv[idx]->arg;
14044 prefix_check = 1;
14045 } else {
14046 vty_out(vty, "Unable to figure out Network\n");
14047 return CMD_WARNING;
14048 }
14049 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
14050 prefix_check, BGP_PATH_SHOW_ALL,
14051 RPKI_NOT_BEING_USED, use_json(argc, argv));
14052 }
14053
14054 static void show_adj_route_header(struct vty *vty, struct peer *peer,
14055 struct bgp_table *table, int *header1,
14056 int *header2, json_object *json,
14057 json_object *json_scode,
14058 json_object *json_ocode, bool wide,
14059 bool detail)
14060 {
14061 uint64_t version = table ? table->version : 0;
14062
14063 if (*header1) {
14064 if (json) {
14065 json_object_int_add(json, "bgpTableVersion", version);
14066 json_object_string_addf(json, "bgpLocalRouterId",
14067 "%pI4", &peer->bgp->router_id);
14068 json_object_int_add(json, "defaultLocPrf",
14069 peer->bgp->default_local_pref);
14070 json_object_int_add(json, "localAS",
14071 peer->change_local_as
14072 ? peer->change_local_as
14073 : peer->local_as);
14074 json_object_object_add(json, "bgpStatusCodes",
14075 json_scode);
14076 json_object_object_add(json, "bgpOriginCodes",
14077 json_ocode);
14078 } else {
14079 vty_out(vty,
14080 "BGP table version is %" PRIu64
14081 ", local router ID is %pI4, vrf id ",
14082 version, &peer->bgp->router_id);
14083 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14084 vty_out(vty, "%s", VRFID_NONE_STR);
14085 else
14086 vty_out(vty, "%u", peer->bgp->vrf_id);
14087 vty_out(vty, "\n");
14088 vty_out(vty, "Default local pref %u, ",
14089 peer->bgp->default_local_pref);
14090 vty_out(vty, "local AS %u\n",
14091 peer->change_local_as ? peer->change_local_as
14092 : peer->local_as);
14093 if (!detail) {
14094 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14095 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14096 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14097 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14098 }
14099 }
14100 *header1 = 0;
14101 }
14102 if (*header2) {
14103 if (!json && !detail)
14104 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14105 : BGP_SHOW_HEADER));
14106 *header2 = 0;
14107 }
14108 }
14109
14110 static void
14111 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14112 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14113 const char *rmap_name, json_object *json, json_object *json_ar,
14114 json_object *json_scode, json_object *json_ocode,
14115 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14116 const struct prefix *match, unsigned long *output_count,
14117 unsigned long *filtered_count)
14118 {
14119 struct bgp_adj_in *ain = NULL;
14120 struct bgp_adj_out *adj = NULL;
14121 struct bgp_dest *dest;
14122 struct bgp *bgp;
14123 struct attr attr;
14124 int ret;
14125 struct update_subgroup *subgrp;
14126 struct peer_af *paf = NULL;
14127 bool route_filtered;
14128 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14129 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14130 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14131 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14132 || (safi == SAFI_EVPN))
14133 ? true
14134 : false;
14135 int display = 0;
14136 json_object *json_net = NULL;
14137
14138 bgp = peer->bgp;
14139
14140 /* If the user supplied a prefix, look for a matching route instead
14141 * of walking the whole table.
14142 */
14143 if (match) {
14144 dest = bgp_node_match(table, match);
14145 if (!dest) {
14146 if (!use_json)
14147 vty_out(vty, "Network not in table\n");
14148 return;
14149 }
14150
14151 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14152
14153 if (rn_p->prefixlen != match->prefixlen) {
14154 if (!use_json)
14155 vty_out(vty, "Network not in table\n");
14156 bgp_dest_unlock_node(dest);
14157 return;
14158 }
14159
14160 if (type == bgp_show_adj_route_received ||
14161 type == bgp_show_adj_route_filtered) {
14162 for (ain = dest->adj_in; ain; ain = ain->next) {
14163 if (ain->peer == peer) {
14164 attr = *ain->attr;
14165 break;
14166 }
14167 }
14168 /* bail out if if adj_out is empty, or
14169 * if the prefix isn't in this peer's
14170 * adj_in
14171 */
14172 if (!ain || ain->peer != peer) {
14173 if (!use_json)
14174 vty_out(vty, "Network not in table\n");
14175 bgp_dest_unlock_node(dest);
14176 return;
14177 }
14178 } else if (type == bgp_show_adj_route_advertised) {
14179 bool peer_found = false;
14180
14181 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14182 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14183 if (paf->peer == peer && adj->attr) {
14184 attr = *adj->attr;
14185 peer_found = true;
14186 break;
14187 }
14188 }
14189 if (peer_found)
14190 break;
14191 }
14192 /* bail out if if adj_out is empty, or
14193 * if the prefix isn't in this peer's
14194 * adj_out
14195 */
14196 if (!paf || !peer_found) {
14197 if (!use_json)
14198 vty_out(vty, "Network not in table\n");
14199 bgp_dest_unlock_node(dest);
14200 return;
14201 }
14202 }
14203
14204 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14205 rmap_name);
14206
14207 if (ret != RMAP_DENY) {
14208 show_adj_route_header(vty, peer, table, header1,
14209 header2, json, json_scode,
14210 json_ocode, wide, detail);
14211
14212 if (use_json)
14213 json_net = json_object_new_object();
14214
14215 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14216 afi, safi, json_net,
14217 BGP_PATH_SHOW_ALL, &display,
14218 RPKI_NOT_BEING_USED);
14219 if (use_json)
14220 json_object_object_addf(json_ar, json_net,
14221 "%pFX", rn_p);
14222 (*output_count)++;
14223 } else
14224 (*filtered_count)++;
14225
14226 bgp_attr_flush(&attr);
14227 bgp_dest_unlock_node(dest);
14228 return;
14229 }
14230
14231
14232 subgrp = peer_subgroup(peer, afi, safi);
14233
14234 if (type == bgp_show_adj_route_advertised && subgrp
14235 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14236 if (use_json) {
14237 json_object_int_add(json, "bgpTableVersion",
14238 table->version);
14239 json_object_string_addf(json, "bgpLocalRouterId",
14240 "%pI4", &bgp->router_id);
14241 json_object_int_add(json, "defaultLocPrf",
14242 bgp->default_local_pref);
14243 json_object_int_add(json, "localAS",
14244 peer->change_local_as
14245 ? peer->change_local_as
14246 : peer->local_as);
14247 json_object_object_add(json, "bgpStatusCodes",
14248 json_scode);
14249 json_object_object_add(json, "bgpOriginCodes",
14250 json_ocode);
14251 json_object_string_add(
14252 json, "bgpOriginatingDefaultNetwork",
14253 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14254 } else {
14255 vty_out(vty,
14256 "BGP table version is %" PRIu64
14257 ", local router ID is %pI4, vrf id ",
14258 table->version, &bgp->router_id);
14259 if (bgp->vrf_id == VRF_UNKNOWN)
14260 vty_out(vty, "%s", VRFID_NONE_STR);
14261 else
14262 vty_out(vty, "%u", bgp->vrf_id);
14263 vty_out(vty, "\n");
14264 vty_out(vty, "Default local pref %u, ",
14265 bgp->default_local_pref);
14266 vty_out(vty, "local AS %u\n",
14267 peer->change_local_as ? peer->change_local_as
14268 : peer->local_as);
14269 if (!detail) {
14270 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14271 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14272 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14273 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14274 }
14275
14276 vty_out(vty, "Originating default network %s\n\n",
14277 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14278 }
14279 (*output_count)++;
14280 *header1 = 0;
14281 }
14282
14283 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14284 if (type == bgp_show_adj_route_received
14285 || type == bgp_show_adj_route_filtered) {
14286 for (ain = dest->adj_in; ain; ain = ain->next) {
14287 if (ain->peer != peer)
14288 continue;
14289 show_adj_route_header(vty, peer, table, header1,
14290 header2, json, json_scode,
14291 json_ocode, wide, detail);
14292
14293 if ((safi == SAFI_MPLS_VPN)
14294 || (safi == SAFI_ENCAP)
14295 || (safi == SAFI_EVPN)) {
14296 if (use_json)
14297 json_object_string_add(
14298 json_ar, "rd", rd_str);
14299 else if (show_rd && rd_str) {
14300 vty_out(vty,
14301 "Route Distinguisher: %s\n",
14302 rd_str);
14303 show_rd = false;
14304 }
14305 }
14306
14307 attr = *ain->attr;
14308 route_filtered = false;
14309
14310 /* Filter prefix using distribute list,
14311 * filter list or prefix list
14312 */
14313 const struct prefix *rn_p =
14314 bgp_dest_get_prefix(dest);
14315 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14316 safi))
14317 == FILTER_DENY)
14318 route_filtered = true;
14319
14320 /* Filter prefix using route-map */
14321 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14322 safi, rmap_name, NULL,
14323 0, NULL);
14324
14325 if (type == bgp_show_adj_route_filtered &&
14326 !route_filtered && ret != RMAP_DENY) {
14327 bgp_attr_flush(&attr);
14328 continue;
14329 }
14330
14331 if (type == bgp_show_adj_route_received
14332 && (route_filtered || ret == RMAP_DENY))
14333 (*filtered_count)++;
14334
14335 if (detail) {
14336 if (use_json)
14337 json_net =
14338 json_object_new_object();
14339
14340 struct bgp_path_info bpi;
14341 struct bgp_dest buildit = *dest;
14342 struct bgp_dest *pass_in;
14343
14344 if (route_filtered ||
14345 ret == RMAP_DENY) {
14346 bpi.attr = &attr;
14347 bpi.peer = peer;
14348 buildit.info = &bpi;
14349
14350 pass_in = &buildit;
14351 } else
14352 pass_in = dest;
14353 bgp_show_path_info(
14354 NULL, pass_in, vty, bgp, afi,
14355 safi, json_net,
14356 BGP_PATH_SHOW_ALL, &display,
14357 RPKI_NOT_BEING_USED);
14358 if (use_json)
14359 json_object_object_addf(
14360 json_ar, json_net,
14361 "%pFX", rn_p);
14362 } else
14363 route_vty_out_tmp(vty, dest, rn_p,
14364 &attr, safi, use_json,
14365 json_ar, wide);
14366 bgp_attr_flush(&attr);
14367 (*output_count)++;
14368 }
14369 } else if (type == bgp_show_adj_route_advertised) {
14370 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14371 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14372 if (paf->peer != peer || !adj->attr)
14373 continue;
14374
14375 show_adj_route_header(
14376 vty, peer, table, header1,
14377 header2, json, json_scode,
14378 json_ocode, wide, detail);
14379
14380 const struct prefix *rn_p =
14381 bgp_dest_get_prefix(dest);
14382
14383 attr = *adj->attr;
14384 ret = bgp_output_modifier(
14385 peer, rn_p, &attr, afi, safi,
14386 rmap_name);
14387
14388 if (ret != RMAP_DENY) {
14389 if ((safi == SAFI_MPLS_VPN)
14390 || (safi == SAFI_ENCAP)
14391 || (safi == SAFI_EVPN)) {
14392 if (use_json)
14393 json_object_string_add(
14394 json_ar,
14395 "rd",
14396 rd_str);
14397 else if (show_rd
14398 && rd_str) {
14399 vty_out(vty,
14400 "Route Distinguisher: %s\n",
14401 rd_str);
14402 show_rd = false;
14403 }
14404 }
14405 if (detail) {
14406 if (use_json)
14407 json_net =
14408 json_object_new_object();
14409 bgp_show_path_info(
14410 NULL /* prefix_rd
14411 */
14412 ,
14413 dest, vty, bgp,
14414 afi, safi,
14415 json_net,
14416 BGP_PATH_SHOW_ALL,
14417 &display,
14418 RPKI_NOT_BEING_USED);
14419 if (use_json)
14420 json_object_object_addf(
14421 json_ar,
14422 json_net,
14423 "%pFX",
14424 rn_p);
14425 } else
14426 route_vty_out_tmp(
14427 vty, dest, rn_p,
14428 &attr, safi,
14429 use_json,
14430 json_ar, wide);
14431 (*output_count)++;
14432 } else {
14433 (*filtered_count)++;
14434 }
14435
14436 bgp_attr_flush(&attr);
14437 }
14438 } else if (type == bgp_show_adj_route_bestpath) {
14439 struct bgp_path_info *pi;
14440
14441 show_adj_route_header(vty, peer, table, header1,
14442 header2, json, json_scode,
14443 json_ocode, wide, detail);
14444
14445 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14446
14447 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14448 pi = pi->next) {
14449 if (pi->peer != peer)
14450 continue;
14451
14452 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14453 continue;
14454
14455 if (detail) {
14456 if (use_json)
14457 json_net =
14458 json_object_new_object();
14459 bgp_show_path_info(
14460 NULL /* prefix_rd */, dest, vty,
14461 bgp, afi, safi, json_net,
14462 BGP_PATH_SHOW_BESTPATH,
14463 &display, RPKI_NOT_BEING_USED);
14464 if (use_json)
14465 json_object_object_addf(
14466 json_ar, json_net,
14467 "%pFX", rn_p);
14468 } else
14469 route_vty_out_tmp(
14470 vty, dest, rn_p, pi->attr, safi,
14471 use_json, json_ar, wide);
14472 (*output_count)++;
14473 }
14474 }
14475 }
14476 }
14477
14478 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14479 safi_t safi, enum bgp_show_adj_route_type type,
14480 const char *rmap_name, const struct prefix *match,
14481 uint16_t show_flags)
14482 {
14483 struct bgp *bgp;
14484 struct bgp_table *table;
14485 json_object *json = NULL;
14486 json_object *json_scode = NULL;
14487 json_object *json_ocode = NULL;
14488 json_object *json_ar = NULL;
14489 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14490
14491 /* Init BGP headers here so they're only displayed once
14492 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14493 */
14494 int header1 = 1;
14495 int header2 = 1;
14496
14497 /*
14498 * Initialize variables for each RD
14499 * All prefixes under an RD is aggregated within "json_routes"
14500 */
14501 char rd_str[BUFSIZ] = {0};
14502 json_object *json_routes = NULL;
14503
14504
14505 /* For 2-tier tables, prefix counts need to be
14506 * maintained across multiple runs of show_adj_route()
14507 */
14508 unsigned long output_count_per_rd;
14509 unsigned long filtered_count_per_rd;
14510 unsigned long output_count = 0;
14511 unsigned long filtered_count = 0;
14512
14513 if (use_json) {
14514 json = json_object_new_object();
14515 json_ar = json_object_new_object();
14516 json_scode = json_object_new_object();
14517 json_ocode = json_object_new_object();
14518 #if CONFDATE > 20231208
14519 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14520 #endif
14521 json_object_string_add(json_scode, "suppressed", "s");
14522 json_object_string_add(json_scode, "damped", "d");
14523 json_object_string_add(json_scode, "history", "h");
14524 json_object_string_add(json_scode, "valid", "*");
14525 json_object_string_add(json_scode, "best", ">");
14526 json_object_string_add(json_scode, "multipath", "=");
14527 json_object_string_add(json_scode, "internal", "i");
14528 json_object_string_add(json_scode, "ribFailure", "r");
14529 json_object_string_add(json_scode, "stale", "S");
14530 json_object_string_add(json_scode, "removed", "R");
14531
14532 #if CONFDATE > 20231208
14533 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14534 #endif
14535 json_object_string_add(json_ocode, "igp", "i");
14536 json_object_string_add(json_ocode, "egp", "e");
14537 json_object_string_add(json_ocode, "incomplete", "?");
14538 }
14539
14540 if (!peer || !peer->afc[afi][safi]) {
14541 if (use_json) {
14542 json_object_string_add(
14543 json, "warning",
14544 "No such neighbor or address family");
14545 vty_out(vty, "%s\n", json_object_to_json_string(json));
14546 json_object_free(json);
14547 json_object_free(json_ar);
14548 json_object_free(json_scode);
14549 json_object_free(json_ocode);
14550 } else
14551 vty_out(vty, "%% No such neighbor or address family\n");
14552
14553 return CMD_WARNING;
14554 }
14555
14556 if ((type == bgp_show_adj_route_received
14557 || type == bgp_show_adj_route_filtered)
14558 && !CHECK_FLAG(peer->af_flags[afi][safi],
14559 PEER_FLAG_SOFT_RECONFIG)) {
14560 if (use_json) {
14561 json_object_string_add(
14562 json, "warning",
14563 "Inbound soft reconfiguration not enabled");
14564 vty_out(vty, "%s\n", json_object_to_json_string(json));
14565 json_object_free(json);
14566 json_object_free(json_ar);
14567 json_object_free(json_scode);
14568 json_object_free(json_ocode);
14569 } else
14570 vty_out(vty,
14571 "%% Inbound soft reconfiguration not enabled\n");
14572
14573 return CMD_WARNING;
14574 }
14575
14576 bgp = peer->bgp;
14577
14578 /* labeled-unicast routes live in the unicast table */
14579 if (safi == SAFI_LABELED_UNICAST)
14580 table = bgp->rib[afi][SAFI_UNICAST];
14581 else
14582 table = bgp->rib[afi][safi];
14583
14584 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14585 || (safi == SAFI_EVPN)) {
14586
14587 struct bgp_dest *dest;
14588
14589 for (dest = bgp_table_top(table); dest;
14590 dest = bgp_route_next(dest)) {
14591 table = bgp_dest_get_bgp_table_info(dest);
14592 if (!table)
14593 continue;
14594
14595 output_count_per_rd = 0;
14596 filtered_count_per_rd = 0;
14597
14598 if (use_json)
14599 json_routes = json_object_new_object();
14600
14601 const struct prefix_rd *prd;
14602 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14603 dest);
14604
14605 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14606 bgp->asnotation);
14607
14608 show_adj_route(
14609 vty, peer, table, afi, safi, type, rmap_name,
14610 json, json_routes, json_scode, json_ocode,
14611 show_flags, &header1, &header2, rd_str, match,
14612 &output_count_per_rd, &filtered_count_per_rd);
14613
14614 /* Don't include an empty RD in the output! */
14615 if (json_routes && (output_count_per_rd > 0))
14616 json_object_object_add(json_ar, rd_str,
14617 json_routes);
14618
14619 output_count += output_count_per_rd;
14620 filtered_count += filtered_count_per_rd;
14621 }
14622 } else
14623 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14624 json, json_ar, json_scode, json_ocode,
14625 show_flags, &header1, &header2, rd_str, match,
14626 &output_count, &filtered_count);
14627
14628 if (use_json) {
14629 if (type == bgp_show_adj_route_advertised)
14630 json_object_object_add(json, "advertisedRoutes",
14631 json_ar);
14632 else
14633 json_object_object_add(json, "receivedRoutes", json_ar);
14634 json_object_int_add(json, "totalPrefixCounter", output_count);
14635 json_object_int_add(json, "filteredPrefixCounter",
14636 filtered_count);
14637
14638 /*
14639 * These fields only give up ownership to `json` when `header1`
14640 * is used (set to zero). See code in `show_adj_route` and
14641 * `show_adj_route_header`.
14642 */
14643 if (header1 == 1) {
14644 json_object_free(json_scode);
14645 json_object_free(json_ocode);
14646 }
14647
14648 vty_json(vty, json);
14649 } else if (output_count > 0) {
14650 if (!match && filtered_count > 0)
14651 vty_out(vty,
14652 "\nTotal number of prefixes %ld (%ld filtered)\n",
14653 output_count, filtered_count);
14654 else
14655 vty_out(vty, "\nTotal number of prefixes %ld\n",
14656 output_count);
14657 }
14658
14659 return CMD_SUCCESS;
14660 }
14661
14662 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14663 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14664 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR " [" BGP_SAFI_WITH_LABEL_CMD_STR "]] neighbors <A.B.C.D|X:X::X:X|WORD> bestpath-routes [detail$detail] [json$uj | wide$wide]",
14665 SHOW_STR
14666 IP_STR
14667 BGP_STR
14668 BGP_INSTANCE_HELP_STR
14669 BGP_AFI_HELP_STR
14670 BGP_SAFI_WITH_LABEL_HELP_STR
14671 "Detailed information on TCP and BGP neighbor connections\n"
14672 "Neighbor to display information about\n"
14673 "Neighbor to display information about\n"
14674 "Neighbor on BGP configured interface\n"
14675 "Display the routes selected by best path\n"
14676 "Display detailed version of routes\n"
14677 JSON_STR
14678 "Increase table width for longer prefixes\n")
14679 {
14680 afi_t afi = AFI_IP6;
14681 safi_t safi = SAFI_UNICAST;
14682 char *rmap_name = NULL;
14683 char *peerstr = NULL;
14684 struct bgp *bgp = NULL;
14685 struct peer *peer;
14686 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14687 int idx = 0;
14688 uint16_t show_flags = 0;
14689
14690 if (detail)
14691 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14692
14693 if (uj)
14694 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14695
14696 if (wide)
14697 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14698
14699 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14700 &bgp, uj);
14701
14702 if (!idx)
14703 return CMD_WARNING;
14704
14705 argv_find(argv, argc, "neighbors", &idx);
14706 peerstr = argv[++idx]->arg;
14707
14708 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14709 if (!peer)
14710 return CMD_WARNING;
14711
14712 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14713 show_flags);
14714 }
14715
14716 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14717 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14718 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR " [" BGP_SAFI_WITH_LABEL_CMD_STR "]] [all$all] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map RMAP_NAME$route_map] [<A.B.C.D/M|X:X::X:X/M>$prefix | detail$detail] [json$uj | wide$wide]",
14719 SHOW_STR
14720 IP_STR
14721 BGP_STR
14722 BGP_INSTANCE_HELP_STR
14723 BGP_AFI_HELP_STR
14724 BGP_SAFI_WITH_LABEL_HELP_STR
14725 "Display the entries for all address families\n"
14726 "Detailed information on TCP and BGP neighbor connections\n"
14727 "Neighbor to display information about\n"
14728 "Neighbor to display information about\n"
14729 "Neighbor on BGP configured interface\n"
14730 "Display the routes advertised to a BGP neighbor\n"
14731 "Display the received routes from neighbor\n"
14732 "Display the filtered routes received from neighbor\n"
14733 "Route-map to modify the attributes\n"
14734 "Name of the route map\n"
14735 "IPv4 prefix\n"
14736 "IPv6 prefix\n"
14737 "Display detailed version of routes\n"
14738 JSON_STR
14739 "Increase table width for longer prefixes\n")
14740 {
14741 afi_t afi = AFI_IP6;
14742 safi_t safi = SAFI_UNICAST;
14743 char *peerstr = NULL;
14744 struct bgp *bgp = NULL;
14745 struct peer *peer;
14746 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14747 int idx = 0;
14748 bool first = true;
14749 uint16_t show_flags = 0;
14750 struct listnode *node;
14751 struct bgp *abgp;
14752
14753 if (detail || prefix_str)
14754 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14755
14756 if (uj) {
14757 argc--;
14758 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14759 }
14760
14761 if (all) {
14762 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14763 if (argv_find(argv, argc, "ipv4", &idx))
14764 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14765
14766 if (argv_find(argv, argc, "ipv6", &idx))
14767 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14768 }
14769
14770 if (wide)
14771 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14772
14773 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14774 &bgp, uj);
14775 if (!idx)
14776 return CMD_WARNING;
14777
14778 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14779 argv_find(argv, argc, "neighbors", &idx);
14780 peerstr = argv[++idx]->arg;
14781
14782 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14783 if (!peer)
14784 return CMD_WARNING;
14785
14786 if (argv_find(argv, argc, "advertised-routes", &idx))
14787 type = bgp_show_adj_route_advertised;
14788 else if (argv_find(argv, argc, "received-routes", &idx))
14789 type = bgp_show_adj_route_received;
14790 else if (argv_find(argv, argc, "filtered-routes", &idx))
14791 type = bgp_show_adj_route_filtered;
14792
14793 if (!all)
14794 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14795 prefix_str ? prefix : NULL, show_flags);
14796 if (uj)
14797 vty_out(vty, "{\n");
14798
14799 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14800 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14801 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14802 : AFI_IP6;
14803 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14804 FOREACH_SAFI (safi) {
14805 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14806 continue;
14807
14808 if (uj) {
14809 if (first)
14810 first = false;
14811 else
14812 vty_out(vty, ",\n");
14813 vty_out(vty, "\"%s\":",
14814 get_afi_safi_str(afi, safi,
14815 true));
14816 } else
14817 vty_out(vty,
14818 "\nFor address family: %s\n",
14819 get_afi_safi_str(afi, safi,
14820 false));
14821
14822 peer_adj_routes(vty, peer, afi, safi, type,
14823 route_map, prefix, show_flags);
14824 }
14825 }
14826 } else {
14827 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14828 FOREACH_AFI_SAFI (afi, safi) {
14829 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14830 continue;
14831
14832 if (uj) {
14833 if (first)
14834 first = false;
14835 else
14836 vty_out(vty, ",\n");
14837 vty_out(vty, "\"%s\":",
14838 get_afi_safi_str(afi, safi,
14839 true));
14840 } else
14841 vty_out(vty,
14842 "\nFor address family: %s\n",
14843 get_afi_safi_str(afi, safi,
14844 false));
14845
14846 peer_adj_routes(vty, peer, afi, safi, type,
14847 route_map, prefix, show_flags);
14848 }
14849 }
14850 }
14851 if (uj)
14852 vty_out(vty, "}\n");
14853
14854 return CMD_SUCCESS;
14855 }
14856
14857 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14858 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14859 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14860 SHOW_STR
14861 IP_STR
14862 BGP_STR
14863 BGP_INSTANCE_HELP_STR
14864 BGP_AF_STR
14865 BGP_AF_STR
14866 BGP_AF_MODIFIER_STR
14867 "Detailed information on TCP and BGP neighbor connections\n"
14868 "Neighbor to display information about\n"
14869 "Neighbor to display information about\n"
14870 "Neighbor on BGP configured interface\n"
14871 "Display information received from a BGP neighbor\n"
14872 "Display the prefixlist filter\n"
14873 JSON_STR)
14874 {
14875 afi_t afi = AFI_IP6;
14876 safi_t safi = SAFI_UNICAST;
14877 char *peerstr = NULL;
14878 char name[BUFSIZ];
14879 struct peer *peer;
14880 int count;
14881 int idx = 0;
14882 struct bgp *bgp = NULL;
14883 bool uj = use_json(argc, argv);
14884
14885 if (uj)
14886 argc--;
14887
14888 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14889 &bgp, uj);
14890 if (!idx)
14891 return CMD_WARNING;
14892
14893 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14894 argv_find(argv, argc, "neighbors", &idx);
14895 peerstr = argv[++idx]->arg;
14896
14897 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14898 if (!peer)
14899 return CMD_WARNING;
14900
14901 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14902 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14903 if (count) {
14904 if (!uj)
14905 vty_out(vty, "Address Family: %s\n",
14906 get_afi_safi_str(afi, safi, false));
14907 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14908 } else {
14909 if (uj)
14910 vty_out(vty, "{}\n");
14911 else
14912 vty_out(vty, "No functional output\n");
14913 }
14914
14915 return CMD_SUCCESS;
14916 }
14917
14918 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14919 afi_t afi, safi_t safi,
14920 enum bgp_show_type type, bool use_json)
14921 {
14922 uint16_t show_flags = 0;
14923
14924 if (use_json)
14925 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14926
14927 if (!peer || !peer->afc[afi][safi]) {
14928 if (use_json) {
14929 json_object *json_no = NULL;
14930 json_no = json_object_new_object();
14931 json_object_string_add(
14932 json_no, "warning",
14933 "No such neighbor or address family");
14934 vty_out(vty, "%s\n",
14935 json_object_to_json_string(json_no));
14936 json_object_free(json_no);
14937 } else
14938 vty_out(vty, "%% No such neighbor or address family\n");
14939 return CMD_WARNING;
14940 }
14941
14942 /* labeled-unicast routes live in the unicast table */
14943 if (safi == SAFI_LABELED_UNICAST)
14944 safi = SAFI_UNICAST;
14945
14946 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14947 RPKI_NOT_BEING_USED);
14948 }
14949
14950 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14951 show_ip_bgp_flowspec_routes_detailed_cmd,
14952 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14953 SHOW_STR
14954 IP_STR
14955 BGP_STR
14956 BGP_INSTANCE_HELP_STR
14957 BGP_AFI_HELP_STR
14958 "SAFI Flowspec\n"
14959 "Detailed information on flowspec entries\n"
14960 JSON_STR)
14961 {
14962 afi_t afi = AFI_IP6;
14963 safi_t safi = SAFI_UNICAST;
14964 struct bgp *bgp = NULL;
14965 int idx = 0;
14966 bool uj = use_json(argc, argv);
14967 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14968
14969 if (uj) {
14970 argc--;
14971 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14972 }
14973
14974 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14975 &bgp, uj);
14976 if (!idx)
14977 return CMD_WARNING;
14978
14979 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14980 show_flags, RPKI_NOT_BEING_USED);
14981 }
14982
14983 DEFUN (show_ip_bgp_neighbor_routes,
14984 show_ip_bgp_neighbor_routes_cmd,
14985 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] neighbors <A.B.C.D|X:X::X:X|WORD> <flap-statistics|dampened-routes|routes> [json]",
14986 SHOW_STR
14987 IP_STR
14988 BGP_STR
14989 BGP_INSTANCE_HELP_STR
14990 BGP_AFI_HELP_STR
14991 BGP_SAFI_WITH_LABEL_HELP_STR
14992 "Detailed information on TCP and BGP neighbor connections\n"
14993 "Neighbor to display information about\n"
14994 "Neighbor to display information about\n"
14995 "Neighbor on BGP configured interface\n"
14996 "Display flap statistics of the routes learned from neighbor\n"
14997 "Display the dampened routes received from neighbor\n"
14998 "Display routes learned from neighbor\n"
14999 JSON_STR)
15000 {
15001 char *peerstr = NULL;
15002 struct bgp *bgp = NULL;
15003 afi_t afi = AFI_IP6;
15004 safi_t safi = SAFI_UNICAST;
15005 struct peer *peer;
15006 enum bgp_show_type sh_type = bgp_show_type_neighbor;
15007 int idx = 0;
15008 bool uj = use_json(argc, argv);
15009
15010 if (uj)
15011 argc--;
15012
15013 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
15014 &bgp, uj);
15015 if (!idx)
15016 return CMD_WARNING;
15017
15018 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
15019 argv_find(argv, argc, "neighbors", &idx);
15020 peerstr = argv[++idx]->arg;
15021
15022 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
15023 if (!peer)
15024 return CMD_WARNING;
15025
15026 if (argv_find(argv, argc, "flap-statistics", &idx))
15027 sh_type = bgp_show_type_flap_neighbor;
15028 else if (argv_find(argv, argc, "dampened-routes", &idx))
15029 sh_type = bgp_show_type_damp_neighbor;
15030 else if (argv_find(argv, argc, "routes", &idx))
15031 sh_type = bgp_show_type_neighbor;
15032
15033 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
15034 }
15035
15036 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
15037
15038 struct bgp_distance {
15039 /* Distance value for the IP source prefix. */
15040 uint8_t distance;
15041
15042 /* Name of the access-list to be matched. */
15043 char *access_list;
15044 };
15045
15046 DEFUN (show_bgp_afi_vpn_rd_route,
15047 show_bgp_afi_vpn_rd_route_cmd,
15048 "show bgp "BGP_AFI_CMD_STR" vpn rd <ASN:NN_OR_IP-ADDRESS:NN|all> <A.B.C.D/M|X:X::X:X/M> [json]",
15049 SHOW_STR
15050 BGP_STR
15051 BGP_AFI_HELP_STR
15052 BGP_AF_MODIFIER_STR
15053 "Display information for a route distinguisher\n"
15054 "Route Distinguisher\n"
15055 "All Route Distinguishers\n"
15056 "Network in the BGP routing table to display\n"
15057 "Network in the BGP routing table to display\n"
15058 JSON_STR)
15059 {
15060 int ret;
15061 struct prefix_rd prd;
15062 afi_t afi = AFI_MAX;
15063 int idx = 0;
15064
15065 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
15066 vty_out(vty, "%% Malformed Address Family\n");
15067 return CMD_WARNING;
15068 }
15069
15070 if (!strcmp(argv[5]->arg, "all"))
15071 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
15072 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
15073 RPKI_NOT_BEING_USED,
15074 use_json(argc, argv));
15075
15076 ret = str2prefix_rd(argv[5]->arg, &prd);
15077 if (!ret) {
15078 vty_out(vty, "%% Malformed Route Distinguisher\n");
15079 return CMD_WARNING;
15080 }
15081
15082 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
15083 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
15084 use_json(argc, argv));
15085 }
15086
15087 static struct bgp_distance *bgp_distance_new(void)
15088 {
15089 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
15090 }
15091
15092 static void bgp_distance_free(struct bgp_distance *bdistance)
15093 {
15094 XFREE(MTYPE_BGP_DISTANCE, bdistance);
15095 }
15096
15097 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15098 const char *ip_str, const char *access_list_str)
15099 {
15100 int ret;
15101 afi_t afi;
15102 safi_t safi;
15103 struct prefix p;
15104 uint8_t distance;
15105 struct bgp_dest *dest;
15106 struct bgp_distance *bdistance;
15107
15108 afi = bgp_node_afi(vty);
15109 safi = bgp_node_safi(vty);
15110
15111 ret = str2prefix(ip_str, &p);
15112 if (ret == 0) {
15113 vty_out(vty, "Malformed prefix\n");
15114 return CMD_WARNING_CONFIG_FAILED;
15115 }
15116
15117 distance = atoi(distance_str);
15118
15119 /* Get BGP distance node. */
15120 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15121 bdistance = bgp_dest_get_bgp_distance_info(dest);
15122 if (bdistance)
15123 bgp_dest_unlock_node(dest);
15124 else {
15125 bdistance = bgp_distance_new();
15126 bgp_dest_set_bgp_distance_info(dest, bdistance);
15127 }
15128
15129 /* Set distance value. */
15130 bdistance->distance = distance;
15131
15132 /* Reset access-list configuration. */
15133 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15134 if (access_list_str)
15135 bdistance->access_list =
15136 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15137
15138 return CMD_SUCCESS;
15139 }
15140
15141 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15142 const char *ip_str, const char *access_list_str)
15143 {
15144 int ret;
15145 afi_t afi;
15146 safi_t safi;
15147 struct prefix p;
15148 int distance;
15149 struct bgp_dest *dest;
15150 struct bgp_distance *bdistance;
15151
15152 afi = bgp_node_afi(vty);
15153 safi = bgp_node_safi(vty);
15154
15155 ret = str2prefix(ip_str, &p);
15156 if (ret == 0) {
15157 vty_out(vty, "Malformed prefix\n");
15158 return CMD_WARNING_CONFIG_FAILED;
15159 }
15160
15161 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15162 if (!dest) {
15163 vty_out(vty, "Can't find specified prefix\n");
15164 return CMD_WARNING_CONFIG_FAILED;
15165 }
15166
15167 bdistance = bgp_dest_get_bgp_distance_info(dest);
15168 distance = atoi(distance_str);
15169
15170 if (bdistance->distance != distance) {
15171 vty_out(vty, "Distance does not match configured\n");
15172 bgp_dest_unlock_node(dest);
15173 return CMD_WARNING_CONFIG_FAILED;
15174 }
15175
15176 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15177 bgp_distance_free(bdistance);
15178
15179 bgp_dest_set_bgp_path_info(dest, NULL);
15180 bgp_dest_unlock_node(dest);
15181 bgp_dest_unlock_node(dest);
15182
15183 return CMD_SUCCESS;
15184 }
15185
15186 /* Apply BGP information to distance method. */
15187 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15188 afi_t afi, safi_t safi, struct bgp *bgp)
15189 {
15190 struct bgp_dest *dest;
15191 struct prefix q = {0};
15192 struct peer *peer;
15193 struct bgp_distance *bdistance;
15194 struct access_list *alist;
15195 struct bgp_static *bgp_static;
15196 struct bgp_path_info *bpi_ultimate;
15197
15198 if (!bgp)
15199 return 0;
15200
15201 peer = pinfo->peer;
15202
15203 if (pinfo->attr->distance)
15204 return pinfo->attr->distance;
15205
15206 /* get peer origin to calculate appropriate distance */
15207 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15208 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15209 peer = bpi_ultimate->peer;
15210 }
15211
15212 /* Check source address.
15213 * Note: for aggregate route, peer can have unspec af type.
15214 */
15215 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15216 && !sockunion2hostprefix(&peer->su, &q))
15217 return 0;
15218
15219 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15220 if (dest) {
15221 bdistance = bgp_dest_get_bgp_distance_info(dest);
15222 bgp_dest_unlock_node(dest);
15223
15224 if (bdistance->access_list) {
15225 alist = access_list_lookup(afi, bdistance->access_list);
15226 if (alist
15227 && access_list_apply(alist, p) == FILTER_PERMIT)
15228 return bdistance->distance;
15229 } else
15230 return bdistance->distance;
15231 }
15232
15233 /* Backdoor check. */
15234 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15235 if (dest) {
15236 bgp_static = bgp_dest_get_bgp_static_info(dest);
15237 bgp_dest_unlock_node(dest);
15238
15239 if (bgp_static->backdoor) {
15240 if (bgp->distance_local[afi][safi])
15241 return bgp->distance_local[afi][safi];
15242 else
15243 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15244 }
15245 }
15246
15247 if (peer->sort == BGP_PEER_EBGP) {
15248 if (bgp->distance_ebgp[afi][safi])
15249 return bgp->distance_ebgp[afi][safi];
15250 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15251 } else if (peer->sort == BGP_PEER_IBGP) {
15252 if (bgp->distance_ibgp[afi][safi])
15253 return bgp->distance_ibgp[afi][safi];
15254 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15255 } else {
15256 if (bgp->distance_local[afi][safi])
15257 return bgp->distance_local[afi][safi];
15258 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15259 }
15260 }
15261
15262 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15263 * we should tell ZEBRA update the routes for a specific
15264 * AFI/SAFI to reflect changes in RIB.
15265 */
15266 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15267 afi_t update_afi,
15268 safi_t update_safi)
15269 {
15270 afi_t afi;
15271 safi_t safi;
15272
15273 FOREACH_AFI_SAFI (afi, safi) {
15274 if (!bgp_fibupd_safi(safi))
15275 continue;
15276
15277 if (afi != update_afi && safi != update_safi)
15278 continue;
15279
15280 if (BGP_DEBUG(zebra, ZEBRA))
15281 zlog_debug(
15282 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15283 __func__, afi, safi);
15284 bgp_zebra_announce_table(bgp, afi, safi);
15285 }
15286 }
15287
15288 DEFUN (bgp_distance,
15289 bgp_distance_cmd,
15290 "distance bgp (1-255) (1-255) (1-255)",
15291 "Define an administrative distance\n"
15292 "BGP distance\n"
15293 "Distance for routes external to the AS\n"
15294 "Distance for routes internal to the AS\n"
15295 "Distance for local routes\n")
15296 {
15297 VTY_DECLVAR_CONTEXT(bgp, bgp);
15298 int idx_number = 2;
15299 int idx_number_2 = 3;
15300 int idx_number_3 = 4;
15301 int distance_ebgp = atoi(argv[idx_number]->arg);
15302 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15303 int distance_local = atoi(argv[idx_number_3]->arg);
15304 afi_t afi;
15305 safi_t safi;
15306
15307 afi = bgp_node_afi(vty);
15308 safi = bgp_node_safi(vty);
15309
15310 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15311 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15312 || bgp->distance_local[afi][safi] != distance_local) {
15313 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15314 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15315 bgp->distance_local[afi][safi] = distance_local;
15316 bgp_announce_routes_distance_update(bgp, afi, safi);
15317 }
15318 return CMD_SUCCESS;
15319 }
15320
15321 DEFUN (no_bgp_distance,
15322 no_bgp_distance_cmd,
15323 "no distance bgp [(1-255) (1-255) (1-255)]",
15324 NO_STR
15325 "Define an administrative distance\n"
15326 "BGP distance\n"
15327 "Distance for routes external to the AS\n"
15328 "Distance for routes internal to the AS\n"
15329 "Distance for local routes\n")
15330 {
15331 VTY_DECLVAR_CONTEXT(bgp, bgp);
15332 afi_t afi;
15333 safi_t safi;
15334
15335 afi = bgp_node_afi(vty);
15336 safi = bgp_node_safi(vty);
15337
15338 if (bgp->distance_ebgp[afi][safi] != 0
15339 || bgp->distance_ibgp[afi][safi] != 0
15340 || bgp->distance_local[afi][safi] != 0) {
15341 bgp->distance_ebgp[afi][safi] = 0;
15342 bgp->distance_ibgp[afi][safi] = 0;
15343 bgp->distance_local[afi][safi] = 0;
15344 bgp_announce_routes_distance_update(bgp, afi, safi);
15345 }
15346 return CMD_SUCCESS;
15347 }
15348
15349
15350 DEFUN (bgp_distance_source,
15351 bgp_distance_source_cmd,
15352 "distance (1-255) A.B.C.D/M",
15353 "Define an administrative distance\n"
15354 "Administrative distance\n"
15355 "IP source prefix\n")
15356 {
15357 int idx_number = 1;
15358 int idx_ipv4_prefixlen = 2;
15359 bgp_distance_set(vty, argv[idx_number]->arg,
15360 argv[idx_ipv4_prefixlen]->arg, NULL);
15361 return CMD_SUCCESS;
15362 }
15363
15364 DEFUN (no_bgp_distance_source,
15365 no_bgp_distance_source_cmd,
15366 "no distance (1-255) A.B.C.D/M",
15367 NO_STR
15368 "Define an administrative distance\n"
15369 "Administrative distance\n"
15370 "IP source prefix\n")
15371 {
15372 int idx_number = 2;
15373 int idx_ipv4_prefixlen = 3;
15374 bgp_distance_unset(vty, argv[idx_number]->arg,
15375 argv[idx_ipv4_prefixlen]->arg, NULL);
15376 return CMD_SUCCESS;
15377 }
15378
15379 DEFUN (bgp_distance_source_access_list,
15380 bgp_distance_source_access_list_cmd,
15381 "distance (1-255) A.B.C.D/M WORD",
15382 "Define an administrative distance\n"
15383 "Administrative distance\n"
15384 "IP source prefix\n"
15385 "Access list name\n")
15386 {
15387 int idx_number = 1;
15388 int idx_ipv4_prefixlen = 2;
15389 int idx_word = 3;
15390 bgp_distance_set(vty, argv[idx_number]->arg,
15391 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15392 return CMD_SUCCESS;
15393 }
15394
15395 DEFUN (no_bgp_distance_source_access_list,
15396 no_bgp_distance_source_access_list_cmd,
15397 "no distance (1-255) A.B.C.D/M WORD",
15398 NO_STR
15399 "Define an administrative distance\n"
15400 "Administrative distance\n"
15401 "IP source prefix\n"
15402 "Access list name\n")
15403 {
15404 int idx_number = 2;
15405 int idx_ipv4_prefixlen = 3;
15406 int idx_word = 4;
15407 bgp_distance_unset(vty, argv[idx_number]->arg,
15408 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15409 return CMD_SUCCESS;
15410 }
15411
15412 DEFUN (ipv6_bgp_distance_source,
15413 ipv6_bgp_distance_source_cmd,
15414 "distance (1-255) X:X::X:X/M",
15415 "Define an administrative distance\n"
15416 "Administrative distance\n"
15417 "IP source prefix\n")
15418 {
15419 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15420 return CMD_SUCCESS;
15421 }
15422
15423 DEFUN (no_ipv6_bgp_distance_source,
15424 no_ipv6_bgp_distance_source_cmd,
15425 "no distance (1-255) X:X::X:X/M",
15426 NO_STR
15427 "Define an administrative distance\n"
15428 "Administrative distance\n"
15429 "IP source prefix\n")
15430 {
15431 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15432 return CMD_SUCCESS;
15433 }
15434
15435 DEFUN (ipv6_bgp_distance_source_access_list,
15436 ipv6_bgp_distance_source_access_list_cmd,
15437 "distance (1-255) X:X::X:X/M WORD",
15438 "Define an administrative distance\n"
15439 "Administrative distance\n"
15440 "IP source prefix\n"
15441 "Access list name\n")
15442 {
15443 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15444 return CMD_SUCCESS;
15445 }
15446
15447 DEFUN (no_ipv6_bgp_distance_source_access_list,
15448 no_ipv6_bgp_distance_source_access_list_cmd,
15449 "no distance (1-255) X:X::X:X/M WORD",
15450 NO_STR
15451 "Define an administrative distance\n"
15452 "Administrative distance\n"
15453 "IP source prefix\n"
15454 "Access list name\n")
15455 {
15456 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15457 return CMD_SUCCESS;
15458 }
15459
15460 DEFUN (bgp_damp_set,
15461 bgp_damp_set_cmd,
15462 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15463 "BGP Specific commands\n"
15464 "Enable route-flap dampening\n"
15465 "Half-life time for the penalty\n"
15466 "Value to start reusing a route\n"
15467 "Value to start suppressing a route\n"
15468 "Maximum duration to suppress a stable route\n")
15469 {
15470 VTY_DECLVAR_CONTEXT(bgp, bgp);
15471 int idx_half_life = 2;
15472 int idx_reuse = 3;
15473 int idx_suppress = 4;
15474 int idx_max_suppress = 5;
15475 int half = DEFAULT_HALF_LIFE * 60;
15476 int reuse = DEFAULT_REUSE;
15477 int suppress = DEFAULT_SUPPRESS;
15478 int max = 4 * half;
15479
15480 if (argc == 6) {
15481 half = atoi(argv[idx_half_life]->arg) * 60;
15482 reuse = atoi(argv[idx_reuse]->arg);
15483 suppress = atoi(argv[idx_suppress]->arg);
15484 max = atoi(argv[idx_max_suppress]->arg) * 60;
15485 } else if (argc == 3) {
15486 half = atoi(argv[idx_half_life]->arg) * 60;
15487 max = 4 * half;
15488 }
15489
15490 /*
15491 * These can't be 0 but our SA doesn't understand the
15492 * way our cli is constructed
15493 */
15494 assert(reuse);
15495 assert(half);
15496 if (suppress < reuse) {
15497 vty_out(vty,
15498 "Suppress value cannot be less than reuse value \n");
15499 return 0;
15500 }
15501
15502 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15503 reuse, suppress, max);
15504 }
15505
15506 DEFUN (bgp_damp_unset,
15507 bgp_damp_unset_cmd,
15508 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15509 NO_STR
15510 "BGP Specific commands\n"
15511 "Enable route-flap dampening\n"
15512 "Half-life time for the penalty\n"
15513 "Value to start reusing a route\n"
15514 "Value to start suppressing a route\n"
15515 "Maximum duration to suppress a stable route\n")
15516 {
15517 VTY_DECLVAR_CONTEXT(bgp, bgp);
15518 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15519 }
15520
15521 /* Display specified route of BGP table. */
15522 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15523 const char *ip_str, afi_t afi, safi_t safi,
15524 struct prefix_rd *prd, int prefix_check)
15525 {
15526 int ret;
15527 struct prefix match;
15528 struct bgp_dest *dest;
15529 struct bgp_dest *rm;
15530 struct bgp_path_info *pi;
15531 struct bgp_path_info *pi_temp;
15532 struct bgp *bgp;
15533 struct bgp_table *table;
15534
15535 /* BGP structure lookup. */
15536 if (view_name) {
15537 bgp = bgp_lookup_by_name(view_name);
15538 if (bgp == NULL) {
15539 vty_out(vty, "%% Can't find BGP instance %s\n",
15540 view_name);
15541 return CMD_WARNING;
15542 }
15543 } else {
15544 bgp = bgp_get_default();
15545 if (bgp == NULL) {
15546 vty_out(vty, "%% No BGP process is configured\n");
15547 return CMD_WARNING;
15548 }
15549 }
15550
15551 /* Check IP address argument. */
15552 ret = str2prefix(ip_str, &match);
15553 if (!ret) {
15554 vty_out(vty, "%% address is malformed\n");
15555 return CMD_WARNING;
15556 }
15557
15558 match.family = afi2family(afi);
15559
15560 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15561 || (safi == SAFI_EVPN)) {
15562 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15563 dest = bgp_route_next(dest)) {
15564 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15565
15566 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15567 continue;
15568 table = bgp_dest_get_bgp_table_info(dest);
15569 if (!table)
15570 continue;
15571 rm = bgp_node_match(table, &match);
15572 if (rm == NULL)
15573 continue;
15574
15575 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15576
15577 if (!prefix_check
15578 || rm_p->prefixlen == match.prefixlen) {
15579 pi = bgp_dest_get_bgp_path_info(rm);
15580 while (pi) {
15581 if (pi->extra && pi->extra->damp_info) {
15582 pi_temp = pi->next;
15583 bgp_damp_info_free(
15584 pi->extra->damp_info,
15585 1, afi, safi);
15586 pi = pi_temp;
15587 } else
15588 pi = pi->next;
15589 }
15590 }
15591
15592 bgp_dest_unlock_node(rm);
15593 }
15594 } else {
15595 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15596 if (dest != NULL) {
15597 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15598
15599 if (!prefix_check
15600 || dest_p->prefixlen == match.prefixlen) {
15601 pi = bgp_dest_get_bgp_path_info(dest);
15602 while (pi) {
15603 if (pi->extra && pi->extra->damp_info) {
15604 pi_temp = pi->next;
15605 bgp_damp_info_free(
15606 pi->extra->damp_info,
15607 1, afi, safi);
15608 pi = pi_temp;
15609 } else
15610 pi = pi->next;
15611 }
15612 }
15613
15614 bgp_dest_unlock_node(dest);
15615 }
15616 }
15617
15618 return CMD_SUCCESS;
15619 }
15620
15621 DEFUN (clear_ip_bgp_dampening,
15622 clear_ip_bgp_dampening_cmd,
15623 "clear ip bgp dampening",
15624 CLEAR_STR
15625 IP_STR
15626 BGP_STR
15627 "Clear route flap dampening information\n")
15628 {
15629 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15630 return CMD_SUCCESS;
15631 }
15632
15633 DEFUN (clear_ip_bgp_dampening_prefix,
15634 clear_ip_bgp_dampening_prefix_cmd,
15635 "clear ip bgp dampening A.B.C.D/M",
15636 CLEAR_STR
15637 IP_STR
15638 BGP_STR
15639 "Clear route flap dampening information\n"
15640 "IPv4 prefix\n")
15641 {
15642 int idx_ipv4_prefixlen = 4;
15643 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15644 AFI_IP, SAFI_UNICAST, NULL, 1);
15645 }
15646
15647 DEFUN (clear_ip_bgp_dampening_address,
15648 clear_ip_bgp_dampening_address_cmd,
15649 "clear ip bgp dampening A.B.C.D",
15650 CLEAR_STR
15651 IP_STR
15652 BGP_STR
15653 "Clear route flap dampening information\n"
15654 "Network to clear damping information\n")
15655 {
15656 int idx_ipv4 = 4;
15657 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15658 SAFI_UNICAST, NULL, 0);
15659 }
15660
15661 DEFUN (clear_ip_bgp_dampening_address_mask,
15662 clear_ip_bgp_dampening_address_mask_cmd,
15663 "clear ip bgp dampening A.B.C.D A.B.C.D",
15664 CLEAR_STR
15665 IP_STR
15666 BGP_STR
15667 "Clear route flap dampening information\n"
15668 "Network to clear damping information\n"
15669 "Network mask\n")
15670 {
15671 int idx_ipv4 = 4;
15672 int idx_ipv4_2 = 5;
15673 int ret;
15674 char prefix_str[BUFSIZ];
15675
15676 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15677 prefix_str, sizeof(prefix_str));
15678 if (!ret) {
15679 vty_out(vty, "%% Inconsistent address and mask\n");
15680 return CMD_WARNING;
15681 }
15682
15683 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15684 NULL, 0);
15685 }
15686
15687 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15688 {
15689 struct vty *vty = arg;
15690 struct peer *peer = bucket->data;
15691
15692 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15693 }
15694
15695 DEFUN (show_bgp_listeners,
15696 show_bgp_listeners_cmd,
15697 "show bgp listeners",
15698 SHOW_STR
15699 BGP_STR
15700 "Display Listen Sockets and who created them\n")
15701 {
15702 bgp_dump_listener_info(vty);
15703
15704 return CMD_SUCCESS;
15705 }
15706
15707 DEFUN (show_bgp_peerhash,
15708 show_bgp_peerhash_cmd,
15709 "show bgp peerhash",
15710 SHOW_STR
15711 BGP_STR
15712 "Display information about the BGP peerhash\n")
15713 {
15714 struct list *instances = bm->bgp;
15715 struct listnode *node;
15716 struct bgp *bgp;
15717
15718 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15719 vty_out(vty, "BGP: %s\n", bgp->name);
15720 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15721 vty);
15722 }
15723
15724 return CMD_SUCCESS;
15725 }
15726
15727 /* also used for encap safi */
15728 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15729 afi_t afi, safi_t safi)
15730 {
15731 struct bgp_dest *pdest;
15732 struct bgp_dest *dest;
15733 struct bgp_table *table;
15734 const struct prefix *p;
15735 struct bgp_static *bgp_static;
15736 mpls_label_t label;
15737
15738 /* Network configuration. */
15739 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15740 pdest = bgp_route_next(pdest)) {
15741 table = bgp_dest_get_bgp_table_info(pdest);
15742 if (!table)
15743 continue;
15744
15745 for (dest = bgp_table_top(table); dest;
15746 dest = bgp_route_next(dest)) {
15747 bgp_static = bgp_dest_get_bgp_static_info(dest);
15748 if (bgp_static == NULL)
15749 continue;
15750
15751 p = bgp_dest_get_prefix(dest);
15752
15753 /* "network" configuration display. */
15754 label = decode_label(&bgp_static->label);
15755
15756 vty_out(vty, " network %pFX rd %s", p,
15757 bgp_static->prd_pretty);
15758 if (safi == SAFI_MPLS_VPN)
15759 vty_out(vty, " label %u", label);
15760
15761 if (bgp_static->rmap.name)
15762 vty_out(vty, " route-map %s",
15763 bgp_static->rmap.name);
15764
15765 if (bgp_static->backdoor)
15766 vty_out(vty, " backdoor");
15767
15768 vty_out(vty, "\n");
15769 }
15770 }
15771 }
15772
15773 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15774 afi_t afi, safi_t safi)
15775 {
15776 struct bgp_dest *pdest;
15777 struct bgp_dest *dest;
15778 struct bgp_table *table;
15779 const struct prefix *p;
15780 struct bgp_static *bgp_static;
15781 char buf[PREFIX_STRLEN * 2];
15782 char buf2[SU_ADDRSTRLEN];
15783 char esi_buf[ESI_STR_LEN];
15784
15785 /* Network configuration. */
15786 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15787 pdest = bgp_route_next(pdest)) {
15788 table = bgp_dest_get_bgp_table_info(pdest);
15789 if (!table)
15790 continue;
15791
15792 for (dest = bgp_table_top(table); dest;
15793 dest = bgp_route_next(dest)) {
15794 bgp_static = bgp_dest_get_bgp_static_info(dest);
15795 if (bgp_static == NULL)
15796 continue;
15797
15798 char *macrouter = NULL;
15799
15800 if (bgp_static->router_mac)
15801 macrouter = prefix_mac2str(
15802 bgp_static->router_mac, NULL, 0);
15803 if (bgp_static->eth_s_id)
15804 esi_to_str(bgp_static->eth_s_id,
15805 esi_buf, sizeof(esi_buf));
15806 p = bgp_dest_get_prefix(dest);
15807
15808 /* "network" configuration display. */
15809 if (p->u.prefix_evpn.route_type == 5) {
15810 char local_buf[PREFIX_STRLEN];
15811
15812 uint8_t family = is_evpn_prefix_ipaddr_v4((
15813 struct prefix_evpn *)p)
15814 ? AF_INET
15815 : AF_INET6;
15816 inet_ntop(family,
15817 &p->u.prefix_evpn.prefix_addr.ip.ip
15818 .addr,
15819 local_buf, sizeof(local_buf));
15820 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15821 p->u.prefix_evpn.prefix_addr
15822 .ip_prefix_length);
15823 } else {
15824 prefix2str(p, buf, sizeof(buf));
15825 }
15826
15827 if (bgp_static->gatewayIp.family == AF_INET
15828 || bgp_static->gatewayIp.family == AF_INET6)
15829 inet_ntop(bgp_static->gatewayIp.family,
15830 &bgp_static->gatewayIp.u.prefix, buf2,
15831 sizeof(buf2));
15832 vty_out(vty,
15833 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15834 buf, bgp_static->prd_pretty,
15835 p->u.prefix_evpn.prefix_addr.eth_tag,
15836 decode_label(&bgp_static->label), esi_buf, buf2,
15837 macrouter);
15838
15839 XFREE(MTYPE_TMP, macrouter);
15840 }
15841 }
15842 }
15843
15844 /* Configuration of static route announcement and aggregate
15845 information. */
15846 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15847 safi_t safi)
15848 {
15849 struct bgp_dest *dest;
15850 const struct prefix *p;
15851 struct bgp_static *bgp_static;
15852 struct bgp_aggregate *bgp_aggregate;
15853
15854 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15855 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15856 return;
15857 }
15858
15859 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15860 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15861 return;
15862 }
15863
15864 /* Network configuration. */
15865 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15866 dest = bgp_route_next(dest)) {
15867 bgp_static = bgp_dest_get_bgp_static_info(dest);
15868 if (bgp_static == NULL)
15869 continue;
15870
15871 p = bgp_dest_get_prefix(dest);
15872
15873 vty_out(vty, " network %pFX", p);
15874
15875 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15876 vty_out(vty, " label-index %u",
15877 bgp_static->label_index);
15878
15879 if (bgp_static->rmap.name)
15880 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15881
15882 if (bgp_static->backdoor)
15883 vty_out(vty, " backdoor");
15884
15885 vty_out(vty, "\n");
15886 }
15887
15888 /* Aggregate-address configuration. */
15889 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15890 dest = bgp_route_next(dest)) {
15891 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15892 if (bgp_aggregate == NULL)
15893 continue;
15894
15895 p = bgp_dest_get_prefix(dest);
15896
15897 vty_out(vty, " aggregate-address %pFX", p);
15898
15899 if (bgp_aggregate->as_set)
15900 vty_out(vty, " as-set");
15901
15902 if (bgp_aggregate->summary_only)
15903 vty_out(vty, " summary-only");
15904
15905 if (bgp_aggregate->rmap.name)
15906 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15907
15908 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15909 vty_out(vty, " origin %s",
15910 bgp_origin2str(bgp_aggregate->origin));
15911
15912 if (bgp_aggregate->match_med)
15913 vty_out(vty, " matching-MED-only");
15914
15915 if (bgp_aggregate->suppress_map_name)
15916 vty_out(vty, " suppress-map %s",
15917 bgp_aggregate->suppress_map_name);
15918
15919 vty_out(vty, "\n");
15920 }
15921 }
15922
15923 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15924 safi_t safi)
15925 {
15926 struct bgp_dest *dest;
15927 struct bgp_distance *bdistance;
15928
15929 /* Distance configuration. */
15930 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15931 && bgp->distance_local[afi][safi]
15932 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15933 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15934 || bgp->distance_local[afi][safi]
15935 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15936 vty_out(vty, " distance bgp %d %d %d\n",
15937 bgp->distance_ebgp[afi][safi],
15938 bgp->distance_ibgp[afi][safi],
15939 bgp->distance_local[afi][safi]);
15940 }
15941
15942 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15943 dest = bgp_route_next(dest)) {
15944 bdistance = bgp_dest_get_bgp_distance_info(dest);
15945 if (bdistance != NULL)
15946 vty_out(vty, " distance %d %pBD %s\n",
15947 bdistance->distance, dest,
15948 bdistance->access_list ? bdistance->access_list
15949 : "");
15950 }
15951 }
15952
15953 /* Allocate routing table structure and install commands. */
15954 void bgp_route_init(void)
15955 {
15956 afi_t afi;
15957 safi_t safi;
15958
15959 /* Init BGP distance table. */
15960 FOREACH_AFI_SAFI (afi, safi)
15961 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15962
15963 /* IPv4 BGP commands. */
15964 install_element(BGP_NODE, &bgp_table_map_cmd);
15965 install_element(BGP_NODE, &bgp_network_cmd);
15966 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15967
15968 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15969
15970 /* IPv4 unicast configuration. */
15971 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15972 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15973 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15974
15975 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15976
15977 /* IPv4 multicast configuration. */
15978 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15979 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15980 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15981 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15982
15983 /* IPv4 labeled-unicast configuration. */
15984 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15985 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15986
15987 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15988 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15989 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15990 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15991 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15992 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15993 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15994 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15995
15996 install_element(VIEW_NODE,
15997 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15998 install_element(VIEW_NODE,
15999 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
16000 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
16001 install_element(VIEW_NODE,
16002 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
16003 #ifdef KEEP_OLD_VPN_COMMANDS
16004 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
16005 #endif /* KEEP_OLD_VPN_COMMANDS */
16006 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
16007 install_element(VIEW_NODE,
16008 &show_bgp_l2vpn_evpn_route_prefix_cmd);
16009
16010 /* BGP dampening clear commands */
16011 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
16012 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
16013
16014 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
16015 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
16016
16017 /* prefix count */
16018 install_element(ENABLE_NODE,
16019 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
16020 #ifdef KEEP_OLD_VPN_COMMANDS
16021 install_element(ENABLE_NODE,
16022 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
16023 #endif /* KEEP_OLD_VPN_COMMANDS */
16024
16025 /* New config IPv6 BGP commands. */
16026 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
16027 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
16028 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
16029
16030 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
16031
16032 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
16033
16034 /* IPv6 labeled unicast address family. */
16035 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
16036 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
16037
16038 install_element(BGP_NODE, &bgp_distance_cmd);
16039 install_element(BGP_NODE, &no_bgp_distance_cmd);
16040 install_element(BGP_NODE, &bgp_distance_source_cmd);
16041 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
16042 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
16043 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
16044 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
16045 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
16046 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
16047 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
16048 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
16049 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
16050 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
16051 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
16052 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
16053 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
16054 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
16055 install_element(BGP_IPV4M_NODE,
16056 &no_bgp_distance_source_access_list_cmd);
16057 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
16058 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
16059 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
16060 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
16061 install_element(BGP_IPV6_NODE,
16062 &ipv6_bgp_distance_source_access_list_cmd);
16063 install_element(BGP_IPV6_NODE,
16064 &no_ipv6_bgp_distance_source_access_list_cmd);
16065 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
16066 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
16067 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
16068 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
16069 install_element(BGP_IPV6M_NODE,
16070 &ipv6_bgp_distance_source_access_list_cmd);
16071 install_element(BGP_IPV6M_NODE,
16072 &no_ipv6_bgp_distance_source_access_list_cmd);
16073
16074 /* BGP dampening */
16075 install_element(BGP_NODE, &bgp_damp_set_cmd);
16076 install_element(BGP_NODE, &bgp_damp_unset_cmd);
16077 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
16078 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
16079 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
16080 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
16081 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
16082 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
16083 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
16084 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
16085 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
16086 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
16087 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
16088 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
16089
16090 /* Large Communities */
16091 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
16092 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
16093
16094 /* show bgp ipv4 flowspec detailed */
16095 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
16096
16097 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16098 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16099 }
16100
16101 void bgp_route_finish(void)
16102 {
16103 afi_t afi;
16104 safi_t safi;
16105
16106 FOREACH_AFI_SAFI (afi, safi) {
16107 bgp_table_unlock(bgp_distance_table[afi][safi]);
16108 bgp_distance_table[afi][safi] = NULL;
16109 }
16110 }