]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #13438 from gpnaveen/vrf_on_loopback
[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 switch (nhtype) {
8680 case NEXTHOP_TYPE_IFINDEX:
8681 switch (p->family) {
8682 case AF_INET:
8683 attr.nexthop.s_addr = INADDR_ANY;
8684 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8685 break;
8686 case AF_INET6:
8687 memset(&attr.mp_nexthop_global, 0,
8688 sizeof(attr.mp_nexthop_global));
8689 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8690 break;
8691 }
8692 break;
8693 case NEXTHOP_TYPE_IPV4:
8694 case NEXTHOP_TYPE_IPV4_IFINDEX:
8695 attr.nexthop = nexthop->ipv4;
8696 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8697 break;
8698 case NEXTHOP_TYPE_IPV6:
8699 case NEXTHOP_TYPE_IPV6_IFINDEX:
8700 attr.mp_nexthop_global = nexthop->ipv6;
8701 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8702 break;
8703 case NEXTHOP_TYPE_BLACKHOLE:
8704 switch (p->family) {
8705 case AF_INET:
8706 attr.nexthop.s_addr = INADDR_ANY;
8707 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8708 break;
8709 case AF_INET6:
8710 memset(&attr.mp_nexthop_global, 0,
8711 sizeof(attr.mp_nexthop_global));
8712 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8713 break;
8714 }
8715 attr.bh_type = bhtype;
8716 break;
8717 }
8718 attr.nh_type = nhtype;
8719 attr.nh_ifindex = ifindex;
8720
8721 attr.med = metric;
8722 attr.distance = distance;
8723 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8724 attr.tag = tag;
8725
8726 if (metric)
8727 bgp_attr_set_aigp_metric(&attr, metric);
8728
8729 afi = family2afi(p->family);
8730
8731 red = bgp_redist_lookup(bgp, afi, type, instance);
8732 if (red) {
8733 struct attr attr_new;
8734
8735 /* Copy attribute for modification. */
8736 attr_new = attr;
8737
8738 if (red->redist_metric_flag) {
8739 attr_new.med = red->redist_metric;
8740 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8741 }
8742
8743 /* Apply route-map. */
8744 if (red->rmap.name) {
8745 memset(&rmap_path, 0, sizeof(rmap_path));
8746 rmap_path.peer = bgp->peer_self;
8747 rmap_path.attr = &attr_new;
8748
8749 SET_FLAG(bgp->peer_self->rmap_type,
8750 PEER_RMAP_TYPE_REDISTRIBUTE);
8751
8752 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8753
8754 bgp->peer_self->rmap_type = 0;
8755
8756 if (ret == RMAP_DENYMATCH) {
8757 /* Free uninterned attribute. */
8758 bgp_attr_flush(&attr_new);
8759
8760 /* Unintern original. */
8761 aspath_unintern(&attr.aspath);
8762 bgp_redistribute_delete(bgp, p, type, instance);
8763 return;
8764 }
8765 }
8766
8767 if (bgp_in_graceful_shutdown(bgp))
8768 bgp_attr_add_gshut_community(&attr_new);
8769
8770 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8771 SAFI_UNICAST, p, NULL);
8772
8773 new_attr = bgp_attr_intern(&attr_new);
8774
8775 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8776 if (bpi->peer == bgp->peer_self
8777 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8778 break;
8779
8780 if (bpi) {
8781 /* Ensure the (source route) type is updated. */
8782 bpi->type = type;
8783 if (attrhash_cmp(bpi->attr, new_attr)
8784 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8785 bgp_attr_unintern(&new_attr);
8786 aspath_unintern(&attr.aspath);
8787 bgp_dest_unlock_node(bn);
8788 return;
8789 } else {
8790 /* The attribute is changed. */
8791 bgp_path_info_set_flag(bn, bpi,
8792 BGP_PATH_ATTR_CHANGED);
8793
8794 /* Rewrite BGP route information. */
8795 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8796 bgp_path_info_restore(bn, bpi);
8797 else
8798 bgp_aggregate_decrement(
8799 bgp, p, bpi, afi, SAFI_UNICAST);
8800 bgp_attr_unintern(&bpi->attr);
8801 bpi->attr = new_attr;
8802 bpi->uptime = monotime(NULL);
8803
8804 /* Process change. */
8805 bgp_aggregate_increment(bgp, p, bpi, afi,
8806 SAFI_UNICAST);
8807 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8808 bgp_dest_unlock_node(bn);
8809 aspath_unintern(&attr.aspath);
8810
8811 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8812 || (bgp->inst_type
8813 == BGP_INSTANCE_TYPE_DEFAULT)) {
8814
8815 vpn_leak_from_vrf_update(
8816 bgp_get_default(), bgp, bpi);
8817 }
8818 return;
8819 }
8820 }
8821
8822 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8823 bgp->peer_self, new_attr, bn);
8824 SET_FLAG(new->flags, BGP_PATH_VALID);
8825
8826 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8827 bgp_path_info_add(bn, new);
8828 bgp_dest_unlock_node(bn);
8829 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8830 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8831
8832 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8833 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8834
8835 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8836 }
8837 }
8838
8839 /* Unintern original. */
8840 aspath_unintern(&attr.aspath);
8841 }
8842
8843 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8844 unsigned short instance)
8845 {
8846 afi_t afi;
8847 struct bgp_dest *dest;
8848 struct bgp_path_info *pi;
8849 struct bgp_redist *red;
8850
8851 afi = family2afi(p->family);
8852
8853 red = bgp_redist_lookup(bgp, afi, type, instance);
8854 if (red) {
8855 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8856 SAFI_UNICAST, p, NULL);
8857
8858 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8859 if (pi->peer == bgp->peer_self && pi->type == type)
8860 break;
8861
8862 if (pi) {
8863 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8864 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8865
8866 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8867 bgp, pi);
8868 }
8869 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8870 bgp_path_info_delete(dest, pi);
8871 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8872 }
8873 bgp_dest_unlock_node(dest);
8874 }
8875 }
8876
8877 /* Withdraw specified route type's route. */
8878 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8879 unsigned short instance)
8880 {
8881 struct bgp_dest *dest;
8882 struct bgp_path_info *pi;
8883 struct bgp_table *table;
8884
8885 table = bgp->rib[afi][SAFI_UNICAST];
8886
8887 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8888 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8889 if (pi->peer == bgp->peer_self && pi->type == type
8890 && pi->instance == instance)
8891 break;
8892
8893 if (pi) {
8894 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8895 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8896
8897 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8898 bgp, pi);
8899 }
8900 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8901 pi, afi, SAFI_UNICAST);
8902 bgp_path_info_delete(dest, pi);
8903 if (!CHECK_FLAG(bgp->flags,
8904 BGP_FLAG_DELETE_IN_PROGRESS))
8905 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8906 else
8907 bgp_path_info_reap(dest, pi);
8908 }
8909 }
8910 }
8911
8912 /* Static function to display route. */
8913 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8914 struct vty *vty, json_object *json, bool wide)
8915 {
8916 int len = 0;
8917 char buf[INET6_ADDRSTRLEN];
8918
8919 if (p->family == AF_INET) {
8920 if (!json) {
8921 len = vty_out(vty, "%pFX", p);
8922 } else {
8923 json_object_string_add(json, "prefix",
8924 inet_ntop(p->family,
8925 &p->u.prefix, buf,
8926 sizeof(buf)));
8927 json_object_int_add(json, "prefixLen", p->prefixlen);
8928 json_object_string_addf(json, "network", "%pFX", p);
8929 json_object_int_add(json, "version", dest->version);
8930 }
8931 } else if (p->family == AF_ETHERNET) {
8932 len = vty_out(vty, "%pFX", p);
8933 } else if (p->family == AF_EVPN) {
8934 if (!json)
8935 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8936 else
8937 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8938 } else if (p->family == AF_FLOWSPEC) {
8939 route_vty_out_flowspec(vty, p, NULL,
8940 json ?
8941 NLRI_STRING_FORMAT_JSON_SIMPLE :
8942 NLRI_STRING_FORMAT_MIN, json);
8943 } else {
8944 if (!json)
8945 len = vty_out(vty, "%pFX", p);
8946 else {
8947 json_object_string_add(json, "prefix",
8948 inet_ntop(p->family,
8949 &p->u.prefix, buf,
8950 sizeof(buf)));
8951 json_object_int_add(json, "prefixLen", p->prefixlen);
8952 json_object_string_addf(json, "network", "%pFX", p);
8953 json_object_int_add(json, "version", dest->version);
8954 }
8955 }
8956
8957 if (!json) {
8958 len = wide ? (45 - len) : (17 - len);
8959 if (len < 1)
8960 vty_out(vty, "\n%*s", 20, " ");
8961 else
8962 vty_out(vty, "%*s", len, " ");
8963 }
8964 }
8965
8966 enum bgp_display_type {
8967 normal_list,
8968 };
8969
8970 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8971 {
8972 switch (reason) {
8973 case bgp_path_selection_none:
8974 return "Nothing to Select";
8975 case bgp_path_selection_first:
8976 return "First path received";
8977 case bgp_path_selection_evpn_sticky_mac:
8978 return "EVPN Sticky Mac";
8979 case bgp_path_selection_evpn_seq:
8980 return "EVPN sequence number";
8981 case bgp_path_selection_evpn_lower_ip:
8982 return "EVPN lower IP";
8983 case bgp_path_selection_evpn_local_path:
8984 return "EVPN local ES path";
8985 case bgp_path_selection_evpn_non_proxy:
8986 return "EVPN non proxy";
8987 case bgp_path_selection_weight:
8988 return "Weight";
8989 case bgp_path_selection_local_pref:
8990 return "Local Pref";
8991 case bgp_path_selection_accept_own:
8992 return "Accept Own";
8993 case bgp_path_selection_local_route:
8994 return "Local Route";
8995 case bgp_path_selection_aigp:
8996 return "AIGP";
8997 case bgp_path_selection_confed_as_path:
8998 return "Confederation based AS Path";
8999 case bgp_path_selection_as_path:
9000 return "AS Path";
9001 case bgp_path_selection_origin:
9002 return "Origin";
9003 case bgp_path_selection_med:
9004 return "MED";
9005 case bgp_path_selection_peer:
9006 return "Peer Type";
9007 case bgp_path_selection_confed:
9008 return "Confed Peer Type";
9009 case bgp_path_selection_igp_metric:
9010 return "IGP Metric";
9011 case bgp_path_selection_older:
9012 return "Older Path";
9013 case bgp_path_selection_router_id:
9014 return "Router ID";
9015 case bgp_path_selection_cluster_length:
9016 return "Cluster length";
9017 case bgp_path_selection_stale:
9018 return "Path Staleness";
9019 case bgp_path_selection_local_configured:
9020 return "Locally configured route";
9021 case bgp_path_selection_neighbor_ip:
9022 return "Neighbor IP";
9023 case bgp_path_selection_default:
9024 return "Nothing left to compare";
9025 }
9026 return "Invalid (internal error)";
9027 }
9028
9029 /* Print the short form route status for a bgp_path_info */
9030 static void route_vty_short_status_out(struct vty *vty,
9031 struct bgp_path_info *path,
9032 const struct prefix *p,
9033 json_object *json_path)
9034 {
9035 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9036
9037 if (json_path) {
9038
9039 /* Route status display. */
9040 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9041 json_object_boolean_true_add(json_path, "removed");
9042
9043 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9044 json_object_boolean_true_add(json_path, "stale");
9045
9046 if (path->extra && bgp_path_suppressed(path))
9047 json_object_boolean_true_add(json_path, "suppressed");
9048
9049 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9050 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9051 json_object_boolean_true_add(json_path, "valid");
9052
9053 /* Selected */
9054 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9055 json_object_boolean_true_add(json_path, "history");
9056
9057 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9058 json_object_boolean_true_add(json_path, "damped");
9059
9060 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9061 json_object_boolean_true_add(json_path, "bestpath");
9062 json_object_string_add(json_path, "selectionReason",
9063 bgp_path_selection_reason2str(
9064 path->net->reason));
9065 }
9066
9067 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9068 json_object_boolean_true_add(json_path, "multipath");
9069
9070 /* Internal route. */
9071 if ((path->peer->as)
9072 && (path->peer->as == path->peer->local_as))
9073 json_object_string_add(json_path, "pathFrom",
9074 "internal");
9075 else
9076 json_object_string_add(json_path, "pathFrom",
9077 "external");
9078
9079 return;
9080 }
9081
9082 /* RPKI validation state */
9083 rpki_state =
9084 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9085
9086 if (rpki_state == RPKI_VALID)
9087 vty_out(vty, "V");
9088 else if (rpki_state == RPKI_INVALID)
9089 vty_out(vty, "I");
9090 else if (rpki_state == RPKI_NOTFOUND)
9091 vty_out(vty, "N");
9092 else
9093 vty_out(vty, " ");
9094
9095 /* Route status display. */
9096 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9097 vty_out(vty, "R");
9098 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9099 vty_out(vty, "S");
9100 else if (bgp_path_suppressed(path))
9101 vty_out(vty, "s");
9102 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9103 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9104 vty_out(vty, "*");
9105 else
9106 vty_out(vty, " ");
9107
9108 /* Selected */
9109 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9110 vty_out(vty, "h");
9111 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9112 vty_out(vty, "d");
9113 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9114 vty_out(vty, ">");
9115 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9116 vty_out(vty, "=");
9117 else
9118 vty_out(vty, " ");
9119
9120 /* Internal route. */
9121 if (path->peer && (path->peer->as)
9122 && (path->peer->as == path->peer->local_as))
9123 vty_out(vty, "i");
9124 else
9125 vty_out(vty, " ");
9126 }
9127
9128 static char *bgp_nexthop_hostname(struct peer *peer,
9129 struct bgp_nexthop_cache *bnc)
9130 {
9131 if (peer->hostname
9132 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9133 return peer->hostname;
9134 return NULL;
9135 }
9136
9137 /* called from terminal list command */
9138 void route_vty_out(struct vty *vty, const struct prefix *p,
9139 struct bgp_path_info *path, int display, safi_t safi,
9140 json_object *json_paths, bool wide)
9141 {
9142 int len;
9143 struct attr *attr = path->attr;
9144 json_object *json_path = NULL;
9145 json_object *json_nexthops = NULL;
9146 json_object *json_nexthop_global = NULL;
9147 json_object *json_nexthop_ll = NULL;
9148 json_object *json_ext_community = NULL;
9149 char vrf_id_str[VRF_NAMSIZ] = {0};
9150 bool nexthop_self =
9151 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9152 bool nexthop_othervrf = false;
9153 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9154 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9155 char *nexthop_hostname =
9156 bgp_nexthop_hostname(path->peer, path->nexthop);
9157 char esi_buf[ESI_STR_LEN];
9158
9159 if (json_paths)
9160 json_path = json_object_new_object();
9161
9162 /* short status lead text */
9163 route_vty_short_status_out(vty, path, p, json_path);
9164
9165 if (!json_paths) {
9166 /* print prefix and mask */
9167 if (!display)
9168 route_vty_out_route(path->net, p, vty, json_path, wide);
9169 else
9170 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9171 } else {
9172 route_vty_out_route(path->net, p, vty, json_path, wide);
9173 }
9174
9175 /*
9176 * If vrf id of nexthop is different from that of prefix,
9177 * set up printable string to append
9178 */
9179 if (path->extra && path->extra->bgp_orig) {
9180 const char *self = "";
9181
9182 if (nexthop_self)
9183 self = "<";
9184
9185 nexthop_othervrf = true;
9186 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9187
9188 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9189 snprintf(vrf_id_str, sizeof(vrf_id_str),
9190 "@%s%s", VRFID_NONE_STR, self);
9191 else
9192 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9193 path->extra->bgp_orig->vrf_id, self);
9194
9195 if (path->extra->bgp_orig->inst_type
9196 != BGP_INSTANCE_TYPE_DEFAULT)
9197
9198 nexthop_vrfname = path->extra->bgp_orig->name;
9199 } else {
9200 const char *self = "";
9201
9202 if (nexthop_self)
9203 self = "<";
9204
9205 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9206 }
9207
9208 /*
9209 * For ENCAP and EVPN routes, nexthop address family is not
9210 * neccessarily the same as the prefix address family.
9211 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9212 * EVPN routes are also exchanged with a MP nexthop. Currently,
9213 * this
9214 * is only IPv4, the value will be present in either
9215 * attr->nexthop or
9216 * attr->mp_nexthop_global_in
9217 */
9218 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9219 char nexthop[128];
9220 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9221
9222 switch (af) {
9223 case AF_INET:
9224 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9225 &attr->mp_nexthop_global_in);
9226 break;
9227 case AF_INET6:
9228 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9229 &attr->mp_nexthop_global);
9230 break;
9231 default:
9232 snprintf(nexthop, sizeof(nexthop), "?");
9233 break;
9234 }
9235
9236 if (json_paths) {
9237 json_nexthop_global = json_object_new_object();
9238
9239 json_object_string_add(json_nexthop_global, "ip",
9240 nexthop);
9241
9242 if (path->peer->hostname)
9243 json_object_string_add(json_nexthop_global,
9244 "hostname",
9245 path->peer->hostname);
9246
9247 json_object_string_add(json_nexthop_global, "afi",
9248 (af == AF_INET) ? "ipv4"
9249 : "ipv6");
9250 json_object_boolean_true_add(json_nexthop_global,
9251 "used");
9252 } else {
9253 if (nexthop_hostname)
9254 len = vty_out(vty, "%s(%s)%s", nexthop,
9255 nexthop_hostname, vrf_id_str);
9256 else
9257 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9258
9259 len = wide ? (41 - len) : (16 - len);
9260 if (len < 1)
9261 vty_out(vty, "\n%*s", 36, " ");
9262 else
9263 vty_out(vty, "%*s", len, " ");
9264 }
9265 } else if (safi == SAFI_EVPN) {
9266 if (json_paths) {
9267 json_nexthop_global = json_object_new_object();
9268
9269 json_object_string_addf(json_nexthop_global, "ip",
9270 "%pI4",
9271 &attr->mp_nexthop_global_in);
9272
9273 if (path->peer->hostname)
9274 json_object_string_add(json_nexthop_global,
9275 "hostname",
9276 path->peer->hostname);
9277
9278 json_object_string_add(json_nexthop_global, "afi",
9279 "ipv4");
9280 json_object_boolean_true_add(json_nexthop_global,
9281 "used");
9282 } else {
9283 if (nexthop_hostname)
9284 len = vty_out(vty, "%pI4(%s)%s",
9285 &attr->mp_nexthop_global_in,
9286 nexthop_hostname, vrf_id_str);
9287 else
9288 len = vty_out(vty, "%pI4%s",
9289 &attr->mp_nexthop_global_in,
9290 vrf_id_str);
9291
9292 len = wide ? (41 - len) : (16 - len);
9293 if (len < 1)
9294 vty_out(vty, "\n%*s", 36, " ");
9295 else
9296 vty_out(vty, "%*s", len, " ");
9297 }
9298 } else if (safi == SAFI_FLOWSPEC) {
9299 if (attr->nexthop.s_addr != INADDR_ANY) {
9300 if (json_paths) {
9301 json_nexthop_global = json_object_new_object();
9302
9303 json_object_string_add(json_nexthop_global,
9304 "afi", "ipv4");
9305 json_object_string_addf(json_nexthop_global,
9306 "ip", "%pI4",
9307 &attr->nexthop);
9308
9309 if (path->peer->hostname)
9310 json_object_string_add(
9311 json_nexthop_global, "hostname",
9312 path->peer->hostname);
9313
9314 json_object_boolean_true_add(
9315 json_nexthop_global,
9316 "used");
9317 } else {
9318 if (nexthop_hostname)
9319 len = vty_out(vty, "%pI4(%s)%s",
9320 &attr->nexthop,
9321 nexthop_hostname,
9322 vrf_id_str);
9323 else
9324 len = vty_out(vty, "%pI4%s",
9325 &attr->nexthop,
9326 vrf_id_str);
9327
9328 len = wide ? (41 - len) : (16 - len);
9329 if (len < 1)
9330 vty_out(vty, "\n%*s", 36, " ");
9331 else
9332 vty_out(vty, "%*s", len, " ");
9333 }
9334 }
9335 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9336 if (json_paths) {
9337 json_nexthop_global = json_object_new_object();
9338
9339 json_object_string_addf(json_nexthop_global, "ip",
9340 "%pI4", &attr->nexthop);
9341
9342 if (path->peer->hostname)
9343 json_object_string_add(json_nexthop_global,
9344 "hostname",
9345 path->peer->hostname);
9346
9347 json_object_string_add(json_nexthop_global, "afi",
9348 "ipv4");
9349 json_object_boolean_true_add(json_nexthop_global,
9350 "used");
9351 } else {
9352 if (nexthop_hostname)
9353 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9354 nexthop_hostname, vrf_id_str);
9355 else
9356 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9357 vrf_id_str);
9358
9359 len = wide ? (41 - len) : (16 - len);
9360 if (len < 1)
9361 vty_out(vty, "\n%*s", 36, " ");
9362 else
9363 vty_out(vty, "%*s", len, " ");
9364 }
9365 }
9366
9367 /* IPv6 Next Hop */
9368 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9369 if (json_paths) {
9370 json_nexthop_global = json_object_new_object();
9371 json_object_string_addf(json_nexthop_global, "ip",
9372 "%pI6",
9373 &attr->mp_nexthop_global);
9374
9375 if (path->peer->hostname)
9376 json_object_string_add(json_nexthop_global,
9377 "hostname",
9378 path->peer->hostname);
9379
9380 json_object_string_add(json_nexthop_global, "afi",
9381 "ipv6");
9382 json_object_string_add(json_nexthop_global, "scope",
9383 "global");
9384
9385 /* We display both LL & GL if both have been
9386 * received */
9387 if ((attr->mp_nexthop_len
9388 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9389 || (path->peer->conf_if)) {
9390 json_nexthop_ll = json_object_new_object();
9391 json_object_string_addf(
9392 json_nexthop_ll, "ip", "%pI6",
9393 &attr->mp_nexthop_local);
9394
9395 if (path->peer->hostname)
9396 json_object_string_add(
9397 json_nexthop_ll, "hostname",
9398 path->peer->hostname);
9399
9400 json_object_string_add(json_nexthop_ll, "afi",
9401 "ipv6");
9402 json_object_string_add(json_nexthop_ll, "scope",
9403 "link-local");
9404
9405 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9406 &attr->mp_nexthop_local)
9407 != 0)
9408 && !attr->mp_nexthop_prefer_global)
9409 json_object_boolean_true_add(
9410 json_nexthop_ll, "used");
9411 else
9412 json_object_boolean_true_add(
9413 json_nexthop_global, "used");
9414 } else
9415 json_object_boolean_true_add(
9416 json_nexthop_global, "used");
9417 } else {
9418 /* Display LL if LL/Global both in table unless
9419 * prefer-global is set */
9420 if (((attr->mp_nexthop_len
9421 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9422 && !attr->mp_nexthop_prefer_global)
9423 || (path->peer->conf_if)) {
9424 if (path->peer->conf_if) {
9425 len = vty_out(vty, "%s",
9426 path->peer->conf_if);
9427 /* len of IPv6 addr + max len of def
9428 * ifname */
9429 len = wide ? (41 - len) : (16 - len);
9430
9431 if (len < 1)
9432 vty_out(vty, "\n%*s", 36, " ");
9433 else
9434 vty_out(vty, "%*s", len, " ");
9435 } else {
9436 if (nexthop_hostname)
9437 len = vty_out(
9438 vty, "%pI6(%s)%s",
9439 &attr->mp_nexthop_local,
9440 nexthop_hostname,
9441 vrf_id_str);
9442 else
9443 len = vty_out(
9444 vty, "%pI6%s",
9445 &attr->mp_nexthop_local,
9446 vrf_id_str);
9447
9448 len = wide ? (41 - len) : (16 - len);
9449
9450 if (len < 1)
9451 vty_out(vty, "\n%*s", 36, " ");
9452 else
9453 vty_out(vty, "%*s", len, " ");
9454 }
9455 } else {
9456 if (nexthop_hostname)
9457 len = vty_out(vty, "%pI6(%s)%s",
9458 &attr->mp_nexthop_global,
9459 nexthop_hostname,
9460 vrf_id_str);
9461 else
9462 len = vty_out(vty, "%pI6%s",
9463 &attr->mp_nexthop_global,
9464 vrf_id_str);
9465
9466 len = wide ? (41 - len) : (16 - len);
9467
9468 if (len < 1)
9469 vty_out(vty, "\n%*s", 36, " ");
9470 else
9471 vty_out(vty, "%*s", len, " ");
9472 }
9473 }
9474 }
9475
9476 /* MED/Metric */
9477 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9478 if (json_paths)
9479 json_object_int_add(json_path, "metric", attr->med);
9480 else if (wide)
9481 vty_out(vty, "%7u", attr->med);
9482 else
9483 vty_out(vty, "%10u", attr->med);
9484 else if (!json_paths) {
9485 if (wide)
9486 vty_out(vty, "%*s", 7, " ");
9487 else
9488 vty_out(vty, "%*s", 10, " ");
9489 }
9490
9491 /* Local Pref */
9492 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9493 if (json_paths)
9494 json_object_int_add(json_path, "locPrf",
9495 attr->local_pref);
9496 else
9497 vty_out(vty, "%7u", attr->local_pref);
9498 else if (!json_paths)
9499 vty_out(vty, " ");
9500
9501 if (json_paths)
9502 json_object_int_add(json_path, "weight", attr->weight);
9503 else
9504 vty_out(vty, "%7u ", attr->weight);
9505
9506 if (json_paths)
9507 json_object_string_addf(json_path, "peerId", "%pSU",
9508 &path->peer->su);
9509
9510 /* Print aspath */
9511 if (attr->aspath) {
9512 if (json_paths)
9513 json_object_string_add(json_path, "path",
9514 attr->aspath->str);
9515 else
9516 aspath_print_vty(vty, attr->aspath);
9517 }
9518
9519 /* Print origin */
9520 if (json_paths)
9521 json_object_string_add(json_path, "origin",
9522 bgp_origin_long_str[attr->origin]);
9523 else
9524 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9525
9526 if (json_paths) {
9527 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9528 json_object_string_add(json_path, "esi",
9529 esi_to_str(&attr->esi,
9530 esi_buf, sizeof(esi_buf)));
9531 }
9532 if (safi == SAFI_EVPN &&
9533 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9534 json_ext_community = json_object_new_object();
9535 json_object_string_add(
9536 json_ext_community, "string",
9537 bgp_attr_get_ecommunity(attr)->str);
9538 json_object_object_add(json_path,
9539 "extendedCommunity",
9540 json_ext_community);
9541 }
9542
9543 if (nexthop_self)
9544 json_object_boolean_true_add(json_path,
9545 "announceNexthopSelf");
9546 if (nexthop_othervrf) {
9547 json_object_string_add(json_path, "nhVrfName",
9548 nexthop_vrfname);
9549
9550 json_object_int_add(json_path, "nhVrfId",
9551 ((nexthop_vrfid == VRF_UNKNOWN)
9552 ? -1
9553 : (int)nexthop_vrfid));
9554 }
9555 }
9556
9557 if (json_paths) {
9558 if (json_nexthop_global || json_nexthop_ll) {
9559 json_nexthops = json_object_new_array();
9560
9561 if (json_nexthop_global)
9562 json_object_array_add(json_nexthops,
9563 json_nexthop_global);
9564
9565 if (json_nexthop_ll)
9566 json_object_array_add(json_nexthops,
9567 json_nexthop_ll);
9568
9569 json_object_object_add(json_path, "nexthops",
9570 json_nexthops);
9571 }
9572
9573 json_object_array_add(json_paths, json_path);
9574 } else {
9575 vty_out(vty, "\n");
9576
9577 if (safi == SAFI_EVPN) {
9578 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9579 /* XXX - add these params to the json out */
9580 vty_out(vty, "%*s", 20, " ");
9581 vty_out(vty, "ESI:%s",
9582 esi_to_str(&attr->esi, esi_buf,
9583 sizeof(esi_buf)));
9584
9585 vty_out(vty, "\n");
9586 }
9587 if (attr->flag &
9588 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9589 vty_out(vty, "%*s", 20, " ");
9590 vty_out(vty, "%s\n",
9591 bgp_attr_get_ecommunity(attr)->str);
9592 }
9593 }
9594
9595 #ifdef ENABLE_BGP_VNC
9596 /* prints an additional line, indented, with VNC info, if
9597 * present */
9598 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9599 rfapi_vty_out_vncinfo(vty, p, path, safi);
9600 #endif
9601 }
9602 }
9603
9604 /* called from terminal list command */
9605 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9606 const struct prefix *p, struct attr *attr, safi_t safi,
9607 bool use_json, json_object *json_ar, bool wide)
9608 {
9609 json_object *json_status = NULL;
9610 json_object *json_net = NULL;
9611 int len;
9612 char buff[BUFSIZ];
9613
9614 /* Route status display. */
9615 if (use_json) {
9616 json_status = json_object_new_object();
9617 json_net = json_object_new_object();
9618 } else {
9619 vty_out(vty, " *");
9620 vty_out(vty, ">");
9621 vty_out(vty, " ");
9622 }
9623
9624 /* print prefix and mask */
9625 if (use_json) {
9626 if (safi == SAFI_EVPN)
9627 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9628 else if (p->family == AF_INET || p->family == AF_INET6) {
9629 json_object_string_add(
9630 json_net, "addrPrefix",
9631 inet_ntop(p->family, &p->u.prefix, buff,
9632 BUFSIZ));
9633 json_object_int_add(json_net, "prefixLen",
9634 p->prefixlen);
9635 json_object_string_addf(json_net, "network", "%pFX", p);
9636 }
9637 } else
9638 route_vty_out_route(dest, p, vty, NULL, wide);
9639
9640 /* Print attribute */
9641 if (attr) {
9642 if (use_json) {
9643 if (p->family == AF_INET &&
9644 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9645 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9646 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9647 json_object_string_addf(
9648 json_net, "nextHop", "%pI4",
9649 &attr->mp_nexthop_global_in);
9650 else
9651 json_object_string_addf(
9652 json_net, "nextHop", "%pI4",
9653 &attr->nexthop);
9654 } else if (p->family == AF_INET6 ||
9655 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9656 json_object_string_addf(
9657 json_net, "nextHopGlobal", "%pI6",
9658 &attr->mp_nexthop_global);
9659 } else if (p->family == AF_EVPN &&
9660 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9661 json_object_string_addf(
9662 json_net, "nextHop", "%pI4",
9663 &attr->mp_nexthop_global_in);
9664 }
9665
9666 if (attr->flag
9667 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9668 json_object_int_add(json_net, "metric",
9669 attr->med);
9670
9671 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9672 json_object_int_add(json_net, "locPrf",
9673 attr->local_pref);
9674
9675 json_object_int_add(json_net, "weight", attr->weight);
9676
9677 /* Print aspath */
9678 if (attr->aspath)
9679 json_object_string_add(json_net, "path",
9680 attr->aspath->str);
9681
9682 /* Print origin */
9683 #if CONFDATE > 20231208
9684 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9685 #endif
9686 json_object_string_add(json_net, "bgpOriginCode",
9687 bgp_origin_str[attr->origin]);
9688 json_object_string_add(
9689 json_net, "origin",
9690 bgp_origin_long_str[attr->origin]);
9691 } else {
9692 if (p->family == AF_INET &&
9693 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9694 safi == SAFI_EVPN ||
9695 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9696 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9697 || safi == SAFI_EVPN)
9698 vty_out(vty, "%-16pI4",
9699 &attr->mp_nexthop_global_in);
9700 else if (wide)
9701 vty_out(vty, "%-41pI4", &attr->nexthop);
9702 else
9703 vty_out(vty, "%-16pI4", &attr->nexthop);
9704 } else if (p->family == AF_INET6 ||
9705 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9706 len = vty_out(vty, "%pI6",
9707 &attr->mp_nexthop_global);
9708 len = wide ? (41 - len) : (16 - len);
9709 if (len < 1)
9710 vty_out(vty, "\n%*s", 36, " ");
9711 else
9712 vty_out(vty, "%*s", len, " ");
9713 }
9714 if (attr->flag
9715 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9716 if (wide)
9717 vty_out(vty, "%7u", attr->med);
9718 else
9719 vty_out(vty, "%10u", attr->med);
9720 else if (wide)
9721 vty_out(vty, " ");
9722 else
9723 vty_out(vty, " ");
9724
9725 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9726 vty_out(vty, "%7u", attr->local_pref);
9727 else
9728 vty_out(vty, " ");
9729
9730 vty_out(vty, "%7u ", attr->weight);
9731
9732 /* Print aspath */
9733 if (attr->aspath)
9734 aspath_print_vty(vty, attr->aspath);
9735
9736 /* Print origin */
9737 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9738 }
9739 }
9740 if (use_json) {
9741 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9742
9743 #if CONFDATE > 20231208
9744 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9745 #endif
9746 json_object_boolean_true_add(json_status, "*");
9747 json_object_boolean_true_add(json_status, ">");
9748 json_object_boolean_true_add(json_net, "valid");
9749 json_object_boolean_true_add(json_net, "best");
9750
9751 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9752 json_object_boolean_true_add(json_status, "=");
9753 json_object_boolean_true_add(json_net, "multipath");
9754 }
9755 json_object_object_add(json_net, "appliedStatusSymbols",
9756 json_status);
9757 json_object_object_addf(json_ar, json_net, "%pFX", p);
9758 } else
9759 vty_out(vty, "\n");
9760 }
9761
9762 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9763 struct bgp_path_info *path, int display, safi_t safi,
9764 json_object *json)
9765 {
9766 json_object *json_out = NULL;
9767 struct attr *attr;
9768 mpls_label_t label = MPLS_INVALID_LABEL;
9769
9770 if (!path->extra)
9771 return;
9772
9773 if (json)
9774 json_out = json_object_new_object();
9775
9776 /* short status lead text */
9777 route_vty_short_status_out(vty, path, p, json_out);
9778
9779 /* print prefix and mask */
9780 if (json == NULL) {
9781 if (!display)
9782 route_vty_out_route(path->net, p, vty, NULL, false);
9783 else
9784 vty_out(vty, "%*s", 17, " ");
9785 }
9786
9787 /* Print attribute */
9788 attr = path->attr;
9789 if (((p->family == AF_INET) &&
9790 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9791 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9792 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9793 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9794 || safi == SAFI_EVPN) {
9795 if (json)
9796 json_object_string_addf(
9797 json_out, "mpNexthopGlobalIn", "%pI4",
9798 &attr->mp_nexthop_global_in);
9799 else
9800 vty_out(vty, "%-16pI4",
9801 &attr->mp_nexthop_global_in);
9802 } else {
9803 if (json)
9804 json_object_string_addf(json_out, "nexthop",
9805 "%pI4", &attr->nexthop);
9806 else
9807 vty_out(vty, "%-16pI4", &attr->nexthop);
9808 }
9809 } else if (((p->family == AF_INET6) &&
9810 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9811 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9812 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9813 char buf_a[512];
9814
9815 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9816 if (json)
9817 json_object_string_addf(
9818 json_out, "mpNexthopGlobalIn", "%pI6",
9819 &attr->mp_nexthop_global);
9820 else
9821 vty_out(vty, "%s",
9822 inet_ntop(AF_INET6,
9823 &attr->mp_nexthop_global,
9824 buf_a, sizeof(buf_a)));
9825 } else if (attr->mp_nexthop_len
9826 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9827 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9828 &attr->mp_nexthop_global,
9829 &attr->mp_nexthop_local);
9830 if (json)
9831 json_object_string_add(json_out,
9832 "mpNexthopGlobalLocal",
9833 buf_a);
9834 else
9835 vty_out(vty, "%s", buf_a);
9836 }
9837 }
9838
9839 label = decode_label(&path->extra->label[0]);
9840
9841 if (bgp_is_valid_label(&label)) {
9842 if (json) {
9843 json_object_int_add(json_out, "notag", label);
9844 json_object_array_add(json, json_out);
9845 } else {
9846 vty_out(vty, "notag/%d", label);
9847 vty_out(vty, "\n");
9848 }
9849 } else if (!json)
9850 vty_out(vty, "\n");
9851 }
9852
9853 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9854 struct bgp_path_info *path, int display,
9855 json_object *json_paths)
9856 {
9857 struct attr *attr;
9858 json_object *json_path = NULL;
9859 json_object *json_nexthop = NULL;
9860 json_object *json_overlay = NULL;
9861
9862 if (!path->extra)
9863 return;
9864
9865 if (json_paths) {
9866 json_path = json_object_new_object();
9867 json_overlay = json_object_new_object();
9868 json_nexthop = json_object_new_object();
9869 }
9870
9871 /* short status lead text */
9872 route_vty_short_status_out(vty, path, p, json_path);
9873
9874 /* print prefix and mask */
9875 if (!display)
9876 route_vty_out_route(path->net, p, vty, json_path, false);
9877 else
9878 vty_out(vty, "%*s", 17, " ");
9879
9880 /* Print attribute */
9881 attr = path->attr;
9882 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9883
9884 switch (af) {
9885 case AF_INET:
9886 if (!json_path) {
9887 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9888 } else {
9889 json_object_string_addf(json_nexthop, "ip", "%pI4",
9890 &attr->mp_nexthop_global_in);
9891
9892 json_object_string_add(json_nexthop, "afi", "ipv4");
9893
9894 json_object_object_add(json_path, "nexthop",
9895 json_nexthop);
9896 }
9897 break;
9898 case AF_INET6:
9899 if (!json_path) {
9900 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9901 &attr->mp_nexthop_local);
9902 } else {
9903 json_object_string_addf(json_nexthop, "ipv6Global",
9904 "%pI6",
9905 &attr->mp_nexthop_global);
9906
9907 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9908 "%pI6",
9909 &attr->mp_nexthop_local);
9910
9911 json_object_string_add(json_nexthop, "afi", "ipv6");
9912
9913 json_object_object_add(json_path, "nexthop",
9914 json_nexthop);
9915 }
9916 break;
9917 default:
9918 if (!json_path) {
9919 vty_out(vty, "?");
9920 } else {
9921 json_object_string_add(json_nexthop, "error",
9922 "Unsupported address-family");
9923 }
9924 }
9925
9926 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9927
9928 if (!json_path)
9929 vty_out(vty, "/%pIA", &eo->gw_ip);
9930 else
9931 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9932
9933 if (bgp_attr_get_ecommunity(attr)) {
9934 char *mac = NULL;
9935 struct ecommunity_val *routermac = ecommunity_lookup(
9936 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9937 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9938
9939 if (routermac)
9940 mac = ecom_mac2str((char *)routermac->val);
9941 if (mac) {
9942 if (!json_path) {
9943 vty_out(vty, "/%s", mac);
9944 } else {
9945 json_object_string_add(json_overlay, "rmac",
9946 mac);
9947 }
9948 XFREE(MTYPE_TMP, mac);
9949 }
9950 }
9951
9952 if (!json_path) {
9953 vty_out(vty, "\n");
9954 } else {
9955 json_object_object_add(json_path, "overlay", json_overlay);
9956
9957 json_object_array_add(json_paths, json_path);
9958 }
9959 }
9960
9961 /* dampening route */
9962 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9963 struct bgp_path_info *path, int display,
9964 afi_t afi, safi_t safi, bool use_json,
9965 json_object *json_paths)
9966 {
9967 struct attr *attr = path->attr;
9968 int len;
9969 char timebuf[BGP_UPTIME_LEN];
9970 json_object *json_path = NULL;
9971
9972 if (use_json)
9973 json_path = json_object_new_object();
9974
9975 /* short status lead text */
9976 route_vty_short_status_out(vty, path, p, json_path);
9977
9978 /* print prefix and mask */
9979 if (!use_json) {
9980 if (!display)
9981 route_vty_out_route(path->net, p, vty, NULL, false);
9982 else
9983 vty_out(vty, "%*s", 17, " ");
9984
9985 len = vty_out(vty, "%s", path->peer->host);
9986 len = 17 - len;
9987
9988 if (len < 1)
9989 vty_out(vty, "\n%*s", 34, " ");
9990 else
9991 vty_out(vty, "%*s", len, " ");
9992
9993 vty_out(vty, "%s ",
9994 bgp_damp_reuse_time_vty(vty, path, timebuf,
9995 BGP_UPTIME_LEN, afi, safi,
9996 use_json, NULL));
9997
9998 if (attr->aspath)
9999 aspath_print_vty(vty, attr->aspath);
10000
10001 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10002
10003 vty_out(vty, "\n");
10004 } else {
10005 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
10006 safi, use_json, json_path);
10007
10008 if (attr->aspath)
10009 json_object_string_add(json_path, "asPath",
10010 attr->aspath->str);
10011
10012 json_object_string_add(json_path, "origin",
10013 bgp_origin_str[attr->origin]);
10014 json_object_string_add(json_path, "peerHost", path->peer->host);
10015
10016 json_object_array_add(json_paths, json_path);
10017 }
10018 }
10019
10020 /* flap route */
10021 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
10022 struct bgp_path_info *path, int display,
10023 afi_t afi, safi_t safi, bool use_json,
10024 json_object *json_paths)
10025 {
10026 struct attr *attr = path->attr;
10027 struct bgp_damp_info *bdi;
10028 char timebuf[BGP_UPTIME_LEN];
10029 int len;
10030 json_object *json_path = NULL;
10031
10032 if (!path->extra)
10033 return;
10034
10035 if (use_json)
10036 json_path = json_object_new_object();
10037
10038 bdi = path->extra->damp_info;
10039
10040 /* short status lead text */
10041 route_vty_short_status_out(vty, path, p, json_path);
10042
10043 if (!use_json) {
10044 if (!display)
10045 route_vty_out_route(path->net, p, vty, NULL, false);
10046 else
10047 vty_out(vty, "%*s", 17, " ");
10048
10049 len = vty_out(vty, "%s", path->peer->host);
10050 len = 16 - len;
10051 if (len < 1)
10052 vty_out(vty, "\n%*s", 33, " ");
10053 else
10054 vty_out(vty, "%*s", len, " ");
10055
10056 len = vty_out(vty, "%d", bdi->flap);
10057 len = 5 - len;
10058 if (len < 1)
10059 vty_out(vty, " ");
10060 else
10061 vty_out(vty, "%*s", len, " ");
10062
10063 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10064 BGP_UPTIME_LEN, 0, NULL));
10065
10066 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10067 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10068 vty_out(vty, "%s ",
10069 bgp_damp_reuse_time_vty(vty, path, timebuf,
10070 BGP_UPTIME_LEN, afi,
10071 safi, use_json, NULL));
10072 else
10073 vty_out(vty, "%*s ", 8, " ");
10074
10075 if (attr->aspath)
10076 aspath_print_vty(vty, attr->aspath);
10077
10078 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10079
10080 vty_out(vty, "\n");
10081 } else {
10082 json_object_string_add(json_path, "peerHost", path->peer->host);
10083 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10084
10085 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10086 json_path);
10087
10088 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10089 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10090 bgp_damp_reuse_time_vty(vty, path, timebuf,
10091 BGP_UPTIME_LEN, afi, safi,
10092 use_json, json_path);
10093
10094 if (attr->aspath)
10095 json_object_string_add(json_path, "asPath",
10096 attr->aspath->str);
10097
10098 json_object_string_add(json_path, "origin",
10099 bgp_origin_str[attr->origin]);
10100
10101 json_object_array_add(json_paths, json_path);
10102 }
10103 }
10104
10105 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10106 int *first, const char *header,
10107 json_object *json_adv_to)
10108 {
10109 json_object *json_peer = NULL;
10110
10111 if (json_adv_to) {
10112 /* 'advertised-to' is a dictionary of peers we have advertised
10113 * this
10114 * prefix too. The key is the peer's IP or swpX, the value is
10115 * the
10116 * hostname if we know it and "" if not.
10117 */
10118 json_peer = json_object_new_object();
10119
10120 if (peer->hostname)
10121 json_object_string_add(json_peer, "hostname",
10122 peer->hostname);
10123
10124 if (peer->conf_if)
10125 json_object_object_add(json_adv_to, peer->conf_if,
10126 json_peer);
10127 else
10128 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10129 &peer->su);
10130 } else {
10131 if (*first) {
10132 vty_out(vty, "%s", header);
10133 *first = 0;
10134 }
10135
10136 if (peer->hostname
10137 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10138 if (peer->conf_if)
10139 vty_out(vty, " %s(%s)", peer->hostname,
10140 peer->conf_if);
10141 else
10142 vty_out(vty, " %s(%pSU)", peer->hostname,
10143 &peer->su);
10144 } else {
10145 if (peer->conf_if)
10146 vty_out(vty, " %s", peer->conf_if);
10147 else
10148 vty_out(vty, " %pSU", &peer->su);
10149 }
10150 }
10151 }
10152
10153 static void route_vty_out_tx_ids(struct vty *vty,
10154 struct bgp_addpath_info_data *d)
10155 {
10156 int i;
10157
10158 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10159 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10160 d->addpath_tx_id[i],
10161 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10162 }
10163 }
10164
10165 static void route_vty_out_detail_es_info(struct vty *vty,
10166 struct bgp_path_info *pi,
10167 struct attr *attr,
10168 json_object *json_path)
10169 {
10170 char esi_buf[ESI_STR_LEN];
10171 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10172 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10173 ATTR_ES_PEER_ROUTER);
10174 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10175 ATTR_ES_PEER_ACTIVE);
10176 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10177 ATTR_ES_PEER_PROXY);
10178 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10179 if (json_path) {
10180 json_object *json_es_info = NULL;
10181
10182 json_object_string_add(
10183 json_path, "esi",
10184 esi_buf);
10185 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10186 json_es_info = json_object_new_object();
10187 if (es_local)
10188 json_object_boolean_true_add(
10189 json_es_info, "localEs");
10190 if (peer_active)
10191 json_object_boolean_true_add(
10192 json_es_info, "peerActive");
10193 if (peer_proxy)
10194 json_object_boolean_true_add(
10195 json_es_info, "peerProxy");
10196 if (peer_router)
10197 json_object_boolean_true_add(
10198 json_es_info, "peerRouter");
10199 if (attr->mm_sync_seqnum)
10200 json_object_int_add(
10201 json_es_info, "peerSeq",
10202 attr->mm_sync_seqnum);
10203 json_object_object_add(
10204 json_path, "es_info",
10205 json_es_info);
10206 }
10207 } else {
10208 if (bgp_evpn_attr_is_sync(attr))
10209 vty_out(vty,
10210 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10211 esi_buf,
10212 es_local ? "local-es":"",
10213 peer_proxy ? "proxy " : "",
10214 peer_active ? "active ":"",
10215 peer_router ? "router ":"",
10216 attr->mm_sync_seqnum);
10217 else
10218 vty_out(vty, " ESI %s %s\n",
10219 esi_buf,
10220 es_local ? "local-es":"");
10221 }
10222 }
10223
10224 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10225 const struct prefix *p, struct bgp_path_info *path,
10226 afi_t afi, safi_t safi,
10227 enum rpki_states rpki_curr_state,
10228 json_object *json_paths)
10229 {
10230 char buf[INET6_ADDRSTRLEN];
10231 char tag_buf[30];
10232 struct attr *attr = path->attr;
10233 time_t tbuf;
10234 json_object *json_bestpath = NULL;
10235 json_object *json_cluster_list = NULL;
10236 json_object *json_cluster_list_list = NULL;
10237 json_object *json_ext_community = NULL;
10238 json_object *json_last_update = NULL;
10239 json_object *json_pmsi = NULL;
10240 json_object *json_nexthop_global = NULL;
10241 json_object *json_nexthop_ll = NULL;
10242 json_object *json_nexthops = NULL;
10243 json_object *json_path = NULL;
10244 json_object *json_peer = NULL;
10245 json_object *json_string = NULL;
10246 json_object *json_adv_to = NULL;
10247 int first = 0;
10248 struct listnode *node, *nnode;
10249 struct peer *peer;
10250 bool addpath_capable;
10251 int has_adj;
10252 unsigned int first_as;
10253 bool nexthop_self =
10254 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10255 int i;
10256 char *nexthop_hostname =
10257 bgp_nexthop_hostname(path->peer, path->nexthop);
10258 uint32_t ttl = 0;
10259 uint32_t bos = 0;
10260 uint32_t exp = 0;
10261 mpls_label_t label = MPLS_INVALID_LABEL;
10262 tag_buf[0] = '\0';
10263 struct bgp_path_info *bpi_ultimate =
10264 bgp_get_imported_bpi_ultimate(path);
10265
10266 if (json_paths) {
10267 json_path = json_object_new_object();
10268 json_peer = json_object_new_object();
10269 json_nexthop_global = json_object_new_object();
10270 }
10271
10272 if (safi == SAFI_EVPN) {
10273 if (!json_paths)
10274 vty_out(vty, " Route %pFX", p);
10275 }
10276
10277 if (path->extra) {
10278 if (path->extra && path->extra->num_labels) {
10279 bgp_evpn_label2str(path->extra->label,
10280 path->extra->num_labels, tag_buf,
10281 sizeof(tag_buf));
10282 }
10283 if (safi == SAFI_EVPN) {
10284 if (!json_paths) {
10285 if (tag_buf[0] != '\0')
10286 vty_out(vty, " VNI %s", tag_buf);
10287 } else {
10288 if (tag_buf[0])
10289 json_object_string_add(json_path, "vni",
10290 tag_buf);
10291 }
10292 }
10293 }
10294
10295 if (safi == SAFI_EVPN
10296 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10297 char gwip_buf[INET6_ADDRSTRLEN];
10298
10299 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10300 sizeof(gwip_buf));
10301
10302 if (json_paths)
10303 json_object_string_add(json_path, "gatewayIP",
10304 gwip_buf);
10305 else
10306 vty_out(vty, " Gateway IP %s", gwip_buf);
10307 }
10308
10309 if (safi == SAFI_EVPN && !json_path)
10310 vty_out(vty, "\n");
10311
10312
10313 if (path->extra && path->extra->parent && !json_paths) {
10314 struct bgp_path_info *parent_ri;
10315 struct bgp_dest *dest, *pdest;
10316
10317 parent_ri = (struct bgp_path_info *)path->extra->parent;
10318 dest = parent_ri->net;
10319 if (dest && dest->pdest) {
10320 pdest = dest->pdest;
10321 if (is_pi_family_evpn(parent_ri)) {
10322 vty_out(vty, " Imported from ");
10323 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10324 (struct prefix_rd *)bgp_dest_get_prefix(
10325 pdest));
10326 vty_out(vty, ":%pFX, VNI %s",
10327 (struct prefix_evpn *)
10328 bgp_dest_get_prefix(dest),
10329 tag_buf);
10330 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10331 vty_out(vty, ", L3NHG %s",
10332 CHECK_FLAG(
10333 attr->es_flags,
10334 ATTR_ES_L3_NHG_ACTIVE)
10335 ? "active"
10336 : "inactive");
10337 vty_out(vty, "\n");
10338
10339 } else {
10340 vty_out(vty, " Imported from ");
10341 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10342 (struct prefix_rd *)bgp_dest_get_prefix(
10343 pdest));
10344 vty_out(vty, ":%pFX\n",
10345 (struct prefix_evpn *)
10346 bgp_dest_get_prefix(dest));
10347 }
10348 }
10349 }
10350
10351 /* Line1 display AS-path, Aggregator */
10352 if (attr->aspath) {
10353 if (json_paths) {
10354 if (!attr->aspath->json)
10355 aspath_str_update(attr->aspath, true);
10356 json_object_lock(attr->aspath->json);
10357 json_object_object_add(json_path, "aspath",
10358 attr->aspath->json);
10359 } else {
10360 if (attr->aspath->segments)
10361 vty_out(vty, " %s", attr->aspath->str);
10362 else
10363 vty_out(vty, " Local");
10364 }
10365 }
10366
10367 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10368 if (json_paths)
10369 json_object_boolean_true_add(json_path, "removed");
10370 else
10371 vty_out(vty, ", (removed)");
10372 }
10373
10374 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10375 if (json_paths)
10376 json_object_boolean_true_add(json_path, "stale");
10377 else
10378 vty_out(vty, ", (stale)");
10379 }
10380
10381 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10382 if (json_paths) {
10383 json_object_int_add(json_path, "aggregatorAs",
10384 attr->aggregator_as);
10385 json_object_string_addf(json_path, "aggregatorId",
10386 "%pI4", &attr->aggregator_addr);
10387 } else {
10388 vty_out(vty, ", (aggregated by %u %pI4)",
10389 attr->aggregator_as, &attr->aggregator_addr);
10390 }
10391 }
10392
10393 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10394 PEER_FLAG_REFLECTOR_CLIENT)) {
10395 if (json_paths)
10396 json_object_boolean_true_add(json_path,
10397 "rxedFromRrClient");
10398 else
10399 vty_out(vty, ", (Received from a RR-client)");
10400 }
10401
10402 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10403 PEER_FLAG_RSERVER_CLIENT)) {
10404 if (json_paths)
10405 json_object_boolean_true_add(json_path,
10406 "rxedFromRsClient");
10407 else
10408 vty_out(vty, ", (Received from a RS-client)");
10409 }
10410
10411 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10412 if (json_paths)
10413 json_object_boolean_true_add(json_path,
10414 "dampeningHistoryEntry");
10415 else
10416 vty_out(vty, ", (history entry)");
10417 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10418 if (json_paths)
10419 json_object_boolean_true_add(json_path,
10420 "dampeningSuppressed");
10421 else
10422 vty_out(vty, ", (suppressed due to dampening)");
10423 }
10424
10425 if (!json_paths)
10426 vty_out(vty, "\n");
10427
10428 /* Line2 display Next-hop, Neighbor, Router-id */
10429 /* Display the nexthop */
10430
10431 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10432 p->family == AF_EVPN) &&
10433 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10434 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10435 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10436 || safi == SAFI_EVPN) {
10437 if (json_paths) {
10438 json_object_string_addf(
10439 json_nexthop_global, "ip", "%pI4",
10440 &attr->mp_nexthop_global_in);
10441
10442 if (path->peer->hostname)
10443 json_object_string_add(
10444 json_nexthop_global, "hostname",
10445 path->peer->hostname);
10446 } else {
10447 if (nexthop_hostname)
10448 vty_out(vty, " %pI4(%s)",
10449 &attr->mp_nexthop_global_in,
10450 nexthop_hostname);
10451 else
10452 vty_out(vty, " %pI4",
10453 &attr->mp_nexthop_global_in);
10454 }
10455 } else {
10456 if (json_paths) {
10457 json_object_string_addf(json_nexthop_global,
10458 "ip", "%pI4",
10459 &attr->nexthop);
10460
10461 if (path->peer->hostname)
10462 json_object_string_add(
10463 json_nexthop_global, "hostname",
10464 path->peer->hostname);
10465 } else {
10466 if (nexthop_hostname)
10467 vty_out(vty, " %pI4(%s)",
10468 &attr->nexthop,
10469 nexthop_hostname);
10470 else
10471 vty_out(vty, " %pI4",
10472 &attr->nexthop);
10473 }
10474 }
10475
10476 if (json_paths)
10477 json_object_string_add(json_nexthop_global, "afi",
10478 "ipv4");
10479 } else {
10480 if (json_paths) {
10481 json_object_string_addf(json_nexthop_global, "ip",
10482 "%pI6",
10483 &attr->mp_nexthop_global);
10484
10485 if (path->peer->hostname)
10486 json_object_string_add(json_nexthop_global,
10487 "hostname",
10488 path->peer->hostname);
10489
10490 json_object_string_add(json_nexthop_global, "afi",
10491 "ipv6");
10492 json_object_string_add(json_nexthop_global, "scope",
10493 "global");
10494 } else {
10495 if (nexthop_hostname)
10496 vty_out(vty, " %pI6(%s)",
10497 &attr->mp_nexthop_global,
10498 nexthop_hostname);
10499 else
10500 vty_out(vty, " %pI6",
10501 &attr->mp_nexthop_global);
10502 }
10503 }
10504
10505 /* Display the IGP cost or 'inaccessible' */
10506 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10507 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10508
10509 if (json_paths) {
10510 json_object_boolean_false_add(json_nexthop_global,
10511 "accessible");
10512 json_object_boolean_add(json_nexthop_global,
10513 "importCheckEnabled", import);
10514 } else {
10515 vty_out(vty, " (inaccessible%s)",
10516 import ? ", import-check enabled" : "");
10517 }
10518 } else {
10519 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10520 if (json_paths)
10521 json_object_int_add(
10522 json_nexthop_global, "metric",
10523 bpi_ultimate->extra->igpmetric);
10524 else
10525 vty_out(vty, " (metric %u)",
10526 bpi_ultimate->extra->igpmetric);
10527 }
10528
10529 /* IGP cost is 0, display this only for json */
10530 else {
10531 if (json_paths)
10532 json_object_int_add(json_nexthop_global,
10533 "metric", 0);
10534 }
10535
10536 if (json_paths)
10537 json_object_boolean_true_add(json_nexthop_global,
10538 "accessible");
10539 }
10540
10541 /* Display peer "from" output */
10542 /* This path was originated locally */
10543 if (path->peer == bgp->peer_self) {
10544
10545 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10546 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10547 if (json_paths)
10548 json_object_string_add(json_peer, "peerId",
10549 "0.0.0.0");
10550 else
10551 vty_out(vty, " from 0.0.0.0 ");
10552 } else {
10553 if (json_paths)
10554 json_object_string_add(json_peer, "peerId",
10555 "::");
10556 else
10557 vty_out(vty, " from :: ");
10558 }
10559
10560 if (json_paths)
10561 json_object_string_addf(json_peer, "routerId", "%pI4",
10562 &bgp->router_id);
10563 else
10564 vty_out(vty, "(%pI4)", &bgp->router_id);
10565 }
10566
10567 /* We RXed this path from one of our peers */
10568 else {
10569
10570 if (json_paths) {
10571 json_object_string_addf(json_peer, "peerId", "%pSU",
10572 &path->peer->su);
10573 json_object_string_addf(json_peer, "routerId", "%pI4",
10574 &path->peer->remote_id);
10575
10576 if (path->peer->hostname)
10577 json_object_string_add(json_peer, "hostname",
10578 path->peer->hostname);
10579
10580 if (path->peer->domainname)
10581 json_object_string_add(json_peer, "domainname",
10582 path->peer->domainname);
10583
10584 if (path->peer->conf_if)
10585 json_object_string_add(json_peer, "interface",
10586 path->peer->conf_if);
10587 } else {
10588 if (path->peer->conf_if) {
10589 if (path->peer->hostname
10590 && CHECK_FLAG(path->peer->bgp->flags,
10591 BGP_FLAG_SHOW_HOSTNAME))
10592 vty_out(vty, " from %s(%s)",
10593 path->peer->hostname,
10594 path->peer->conf_if);
10595 else
10596 vty_out(vty, " from %s",
10597 path->peer->conf_if);
10598 } else {
10599 if (path->peer->hostname
10600 && CHECK_FLAG(path->peer->bgp->flags,
10601 BGP_FLAG_SHOW_HOSTNAME))
10602 vty_out(vty, " from %s(%s)",
10603 path->peer->hostname,
10604 path->peer->host);
10605 else
10606 vty_out(vty, " from %pSU",
10607 &path->peer->su);
10608 }
10609
10610 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10611 vty_out(vty, " (%pI4)", &attr->originator_id);
10612 else
10613 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10614 }
10615 }
10616
10617 /*
10618 * Note when vrfid of nexthop is different from that of prefix
10619 */
10620 if (path->extra && path->extra->bgp_orig) {
10621 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10622
10623 if (json_paths) {
10624 const char *vn;
10625
10626 if (path->extra->bgp_orig->inst_type
10627 == BGP_INSTANCE_TYPE_DEFAULT)
10628 vn = VRF_DEFAULT_NAME;
10629 else
10630 vn = path->extra->bgp_orig->name;
10631
10632 json_object_string_add(json_path, "nhVrfName", vn);
10633
10634 if (nexthop_vrfid == VRF_UNKNOWN) {
10635 json_object_int_add(json_path, "nhVrfId", -1);
10636 } else {
10637 json_object_int_add(json_path, "nhVrfId",
10638 (int)nexthop_vrfid);
10639 }
10640 } else {
10641 if (nexthop_vrfid == VRF_UNKNOWN)
10642 vty_out(vty, " vrf ?");
10643 else {
10644 struct vrf *vrf;
10645
10646 vrf = vrf_lookup_by_id(nexthop_vrfid);
10647 vty_out(vty, " vrf %s(%u)",
10648 VRF_LOGNAME(vrf), nexthop_vrfid);
10649 }
10650 }
10651 }
10652
10653 if (nexthop_self) {
10654 if (json_paths) {
10655 json_object_boolean_true_add(json_path,
10656 "announceNexthopSelf");
10657 } else {
10658 vty_out(vty, " announce-nh-self");
10659 }
10660 }
10661
10662 if (!json_paths)
10663 vty_out(vty, "\n");
10664
10665 /* display the link-local nexthop */
10666 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10667 if (json_paths) {
10668 json_nexthop_ll = json_object_new_object();
10669 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10670 &attr->mp_nexthop_local);
10671
10672 if (path->peer->hostname)
10673 json_object_string_add(json_nexthop_ll,
10674 "hostname",
10675 path->peer->hostname);
10676
10677 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10678 json_object_string_add(json_nexthop_ll, "scope",
10679 "link-local");
10680
10681 json_object_boolean_true_add(json_nexthop_ll,
10682 "accessible");
10683
10684 if (!attr->mp_nexthop_prefer_global)
10685 json_object_boolean_true_add(json_nexthop_ll,
10686 "used");
10687 else
10688 json_object_boolean_true_add(
10689 json_nexthop_global, "used");
10690 } else {
10691 vty_out(vty, " (%s) %s\n",
10692 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10693 buf, INET6_ADDRSTRLEN),
10694 attr->mp_nexthop_prefer_global
10695 ? "(prefer-global)"
10696 : "(used)");
10697 }
10698 }
10699 /* If we do not have a link-local nexthop then we must flag the
10700 global as "used" */
10701 else {
10702 if (json_paths)
10703 json_object_boolean_true_add(json_nexthop_global,
10704 "used");
10705 }
10706
10707 if (safi == SAFI_EVPN &&
10708 bgp_evpn_is_esi_valid(&attr->esi)) {
10709 route_vty_out_detail_es_info(vty, path, attr, json_path);
10710 }
10711
10712 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10713 * Int/Ext/Local, Atomic, best */
10714 if (json_paths)
10715 json_object_string_add(json_path, "origin",
10716 bgp_origin_long_str[attr->origin]);
10717 else
10718 vty_out(vty, " Origin %s",
10719 bgp_origin_long_str[attr->origin]);
10720
10721 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10722 if (json_paths)
10723 json_object_int_add(json_path, "metric", attr->med);
10724 else
10725 vty_out(vty, ", metric %u", attr->med);
10726 }
10727
10728 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10729 if (json_paths)
10730 json_object_int_add(json_path, "locPrf",
10731 attr->local_pref);
10732 else
10733 vty_out(vty, ", localpref %u", attr->local_pref);
10734 }
10735
10736 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10737 if (json_paths)
10738 json_object_int_add(json_path, "aigpMetric",
10739 bgp_attr_get_aigp_metric(attr));
10740 else
10741 vty_out(vty, ", aigp-metric %" PRIu64,
10742 bgp_attr_get_aigp_metric(attr));
10743 }
10744
10745 if (attr->weight != 0) {
10746 if (json_paths)
10747 json_object_int_add(json_path, "weight", attr->weight);
10748 else
10749 vty_out(vty, ", weight %u", attr->weight);
10750 }
10751
10752 if (attr->tag != 0) {
10753 if (json_paths)
10754 json_object_int_add(json_path, "tag", attr->tag);
10755 else
10756 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10757 }
10758
10759 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10760 if (json_paths)
10761 json_object_boolean_false_add(json_path, "valid");
10762 else
10763 vty_out(vty, ", invalid");
10764 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10765 if (json_paths)
10766 json_object_boolean_true_add(json_path, "valid");
10767 else
10768 vty_out(vty, ", valid");
10769 }
10770
10771 if (json_paths)
10772 json_object_int_add(json_path, "version", bn->version);
10773
10774 if (path->peer != bgp->peer_self) {
10775 if (path->peer->as == path->peer->local_as) {
10776 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10777 if (json_paths)
10778 json_object_string_add(
10779 json_peer, "type",
10780 "confed-internal");
10781 else
10782 vty_out(vty, ", confed-internal");
10783 } else {
10784 if (json_paths)
10785 json_object_string_add(
10786 json_peer, "type", "internal");
10787 else
10788 vty_out(vty, ", internal");
10789 }
10790 } else {
10791 if (bgp_confederation_peers_check(bgp,
10792 path->peer->as)) {
10793 if (json_paths)
10794 json_object_string_add(
10795 json_peer, "type",
10796 "confed-external");
10797 else
10798 vty_out(vty, ", confed-external");
10799 } else {
10800 if (json_paths)
10801 json_object_string_add(
10802 json_peer, "type", "external");
10803 else
10804 vty_out(vty, ", external");
10805 }
10806 }
10807 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10808 if (json_paths) {
10809 json_object_boolean_true_add(json_path, "aggregated");
10810 json_object_boolean_true_add(json_path, "local");
10811 } else {
10812 vty_out(vty, ", aggregated, local");
10813 }
10814 } else if (path->type != ZEBRA_ROUTE_BGP) {
10815 if (json_paths)
10816 json_object_boolean_true_add(json_path, "sourced");
10817 else
10818 vty_out(vty, ", sourced");
10819 } else {
10820 if (json_paths) {
10821 json_object_boolean_true_add(json_path, "sourced");
10822 json_object_boolean_true_add(json_path, "local");
10823 } else {
10824 vty_out(vty, ", sourced, local");
10825 }
10826 }
10827
10828 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10829 if (json_paths)
10830 json_object_boolean_true_add(json_path,
10831 "atomicAggregate");
10832 else
10833 vty_out(vty, ", atomic-aggregate");
10834 }
10835
10836 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10837 if (json_paths)
10838 json_object_int_add(json_path, "otc", attr->otc);
10839 else
10840 vty_out(vty, ", otc %u", attr->otc);
10841 }
10842
10843 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10844 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10845 && bgp_path_info_mpath_count(path))) {
10846 if (json_paths)
10847 json_object_boolean_true_add(json_path, "multipath");
10848 else
10849 vty_out(vty, ", multipath");
10850 }
10851
10852 // Mark the bestpath(s)
10853 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10854 first_as = aspath_get_first_as(attr->aspath);
10855
10856 if (json_paths) {
10857 if (!json_bestpath)
10858 json_bestpath = json_object_new_object();
10859 json_object_int_add(json_bestpath, "bestpathFromAs",
10860 first_as);
10861 } else {
10862 if (first_as)
10863 vty_out(vty, ", bestpath-from-AS %u", first_as);
10864 else
10865 vty_out(vty, ", bestpath-from-AS Local");
10866 }
10867 }
10868
10869 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10870 if (json_paths) {
10871 if (!json_bestpath)
10872 json_bestpath = json_object_new_object();
10873 json_object_boolean_true_add(json_bestpath, "overall");
10874 json_object_string_add(
10875 json_bestpath, "selectionReason",
10876 bgp_path_selection_reason2str(bn->reason));
10877 } else {
10878 vty_out(vty, ", best");
10879 vty_out(vty, " (%s)",
10880 bgp_path_selection_reason2str(bn->reason));
10881 }
10882 }
10883
10884 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10885 if (json_paths)
10886 json_object_string_add(
10887 json_path, "rpkiValidationState",
10888 bgp_rpki_validation2str(rpki_curr_state));
10889 else
10890 vty_out(vty, ", rpki validation-state: %s",
10891 bgp_rpki_validation2str(rpki_curr_state));
10892 }
10893
10894 if (json_bestpath)
10895 json_object_object_add(json_path, "bestpath", json_bestpath);
10896
10897 if (!json_paths)
10898 vty_out(vty, "\n");
10899
10900 /* Line 4 display Community */
10901 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10902 if (json_paths) {
10903 if (!bgp_attr_get_community(attr)->json)
10904 community_str(bgp_attr_get_community(attr),
10905 true, true);
10906 json_object_lock(bgp_attr_get_community(attr)->json);
10907 json_object_object_add(
10908 json_path, "community",
10909 bgp_attr_get_community(attr)->json);
10910 } else {
10911 vty_out(vty, " Community: %s\n",
10912 bgp_attr_get_community(attr)->str);
10913 }
10914 }
10915
10916 /* Line 5 display Extended-community */
10917 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10918 if (json_paths) {
10919 json_ext_community = json_object_new_object();
10920 json_object_string_add(
10921 json_ext_community, "string",
10922 bgp_attr_get_ecommunity(attr)->str);
10923 json_object_object_add(json_path, "extendedCommunity",
10924 json_ext_community);
10925 } else {
10926 vty_out(vty, " Extended Community: %s\n",
10927 bgp_attr_get_ecommunity(attr)->str);
10928 }
10929 }
10930
10931 /* Line 6 display Large community */
10932 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10933 if (json_paths) {
10934 if (!bgp_attr_get_lcommunity(attr)->json)
10935 lcommunity_str(bgp_attr_get_lcommunity(attr),
10936 true, true);
10937 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10938 json_object_object_add(
10939 json_path, "largeCommunity",
10940 bgp_attr_get_lcommunity(attr)->json);
10941 } else {
10942 vty_out(vty, " Large Community: %s\n",
10943 bgp_attr_get_lcommunity(attr)->str);
10944 }
10945 }
10946
10947 /* Line 7 display Originator, Cluster-id */
10948 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10949 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10950 char buf[BUFSIZ] = {0};
10951
10952 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10953 if (json_paths)
10954 json_object_string_addf(json_path,
10955 "originatorId", "%pI4",
10956 &attr->originator_id);
10957 else
10958 vty_out(vty, " Originator: %pI4",
10959 &attr->originator_id);
10960 }
10961
10962 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10963 struct cluster_list *cluster =
10964 bgp_attr_get_cluster(attr);
10965 int i;
10966
10967 if (json_paths) {
10968 json_cluster_list = json_object_new_object();
10969 json_cluster_list_list =
10970 json_object_new_array();
10971
10972 for (i = 0; i < cluster->length / 4; i++) {
10973 json_string = json_object_new_string(
10974 inet_ntop(AF_INET,
10975 &cluster->list[i],
10976 buf, sizeof(buf)));
10977 json_object_array_add(
10978 json_cluster_list_list,
10979 json_string);
10980 }
10981
10982 /*
10983 * struct cluster_list does not have
10984 * "str" variable like aspath and community
10985 * do. Add this someday if someone asks
10986 * for it.
10987 * json_object_string_add(json_cluster_list,
10988 * "string", cluster->str);
10989 */
10990 json_object_object_add(json_cluster_list,
10991 "list",
10992 json_cluster_list_list);
10993 json_object_object_add(json_path, "clusterList",
10994 json_cluster_list);
10995 } else {
10996 vty_out(vty, ", Cluster list: ");
10997
10998 for (i = 0; i < cluster->length / 4; i++) {
10999 vty_out(vty, "%pI4 ",
11000 &cluster->list[i]);
11001 }
11002 }
11003 }
11004
11005 if (!json_paths)
11006 vty_out(vty, "\n");
11007 }
11008
11009 if (path->extra && path->extra->damp_info)
11010 bgp_damp_info_vty(vty, path, afi, safi, json_path);
11011
11012 /* Remote Label */
11013 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
11014 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
11015 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
11016 &bos);
11017
11018 if (json_paths)
11019 json_object_int_add(json_path, "remoteLabel", label);
11020 else
11021 vty_out(vty, " Remote label: %d\n", label);
11022 }
11023
11024 /* Remote SID */
11025 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
11026 if (json_paths)
11027 json_object_string_addf(json_path, "remoteSid", "%pI6",
11028 &path->extra->sid[0].sid);
11029 else
11030 vty_out(vty, " Remote SID: %pI6\n",
11031 &path->extra->sid[0].sid);
11032 }
11033
11034 /* Label Index */
11035 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11036 if (json_paths)
11037 json_object_int_add(json_path, "labelIndex",
11038 attr->label_index);
11039 else
11040 vty_out(vty, " Label Index: %d\n",
11041 attr->label_index);
11042 }
11043
11044 /* Line 8 display Addpath IDs */
11045 if (path->addpath_rx_id
11046 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11047 if (json_paths) {
11048 json_object_int_add(json_path, "addpathRxId",
11049 path->addpath_rx_id);
11050
11051 /* Keep backwards compatibility with the old API
11052 * by putting TX All's ID in the old field
11053 */
11054 json_object_int_add(
11055 json_path, "addpathTxId",
11056 path->tx_addpath
11057 .addpath_tx_id[BGP_ADDPATH_ALL]);
11058
11059 /* ... but create a specific field for each
11060 * strategy
11061 */
11062 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11063 json_object_int_add(
11064 json_path,
11065 bgp_addpath_names(i)->id_json_name,
11066 path->tx_addpath.addpath_tx_id[i]);
11067 }
11068 } else {
11069 vty_out(vty, " AddPath ID: RX %u, ",
11070 path->addpath_rx_id);
11071
11072 route_vty_out_tx_ids(vty, &path->tx_addpath);
11073 }
11074 }
11075
11076 /* If we used addpath to TX a non-bestpath we need to display
11077 * "Advertised to" on a path-by-path basis
11078 */
11079 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11080 first = 1;
11081
11082 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11083 addpath_capable =
11084 bgp_addpath_encode_tx(peer, afi, safi);
11085 has_adj = bgp_adj_out_lookup(
11086 peer, path->net,
11087 bgp_addpath_id_for_peer(peer, afi, safi,
11088 &path->tx_addpath));
11089
11090 if ((addpath_capable && has_adj)
11091 || (!addpath_capable && has_adj
11092 && CHECK_FLAG(path->flags,
11093 BGP_PATH_SELECTED))) {
11094 if (json_path && !json_adv_to)
11095 json_adv_to = json_object_new_object();
11096
11097 route_vty_out_advertised_to(
11098 vty, peer, &first,
11099 " Advertised to:", json_adv_to);
11100 }
11101 }
11102
11103 if (json_path) {
11104 if (json_adv_to) {
11105 json_object_object_add(
11106 json_path, "advertisedTo", json_adv_to);
11107 }
11108 } else {
11109 if (!first) {
11110 vty_out(vty, "\n");
11111 }
11112 }
11113 }
11114
11115 /* Line 9 display Uptime */
11116 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11117 if (json_paths) {
11118 json_last_update = json_object_new_object();
11119 json_object_int_add(json_last_update, "epoch", tbuf);
11120 json_object_string_add(json_last_update, "string",
11121 ctime(&tbuf));
11122 json_object_object_add(json_path, "lastUpdate",
11123 json_last_update);
11124 } else
11125 vty_out(vty, " Last update: %s", ctime(&tbuf));
11126
11127 /* Line 10 display PMSI tunnel attribute, if present */
11128 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11129 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11130 bgp_attr_get_pmsi_tnl_type(attr),
11131 PMSI_TNLTYPE_STR_DEFAULT);
11132
11133 if (json_paths) {
11134 json_pmsi = json_object_new_object();
11135 json_object_string_add(json_pmsi, "tunnelType", str);
11136 json_object_int_add(json_pmsi, "label",
11137 label2vni(&attr->label));
11138 json_object_object_add(json_path, "pmsi", json_pmsi);
11139 } else
11140 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11141 str, label2vni(&attr->label));
11142 }
11143
11144 if (path->peer->t_gr_restart &&
11145 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11146 unsigned long gr_remaining =
11147 event_timer_remain_second(path->peer->t_gr_restart);
11148
11149 if (json_paths) {
11150 json_object_int_add(json_path,
11151 "gracefulRestartSecondsRemaining",
11152 gr_remaining);
11153 } else
11154 vty_out(vty,
11155 " Time until Graceful Restart stale route deleted: %lu\n",
11156 gr_remaining);
11157 }
11158
11159 if (path->peer->t_llgr_stale[afi][safi] &&
11160 bgp_attr_get_community(attr) &&
11161 community_include(bgp_attr_get_community(attr),
11162 COMMUNITY_LLGR_STALE)) {
11163 unsigned long llgr_remaining = event_timer_remain_second(
11164 path->peer->t_llgr_stale[afi][safi]);
11165
11166 if (json_paths) {
11167 json_object_int_add(json_path, "llgrSecondsRemaining",
11168 llgr_remaining);
11169 } else
11170 vty_out(vty,
11171 " Time until Long-lived stale route deleted: %lu\n",
11172 llgr_remaining);
11173 }
11174
11175 /* Output some debug about internal state of the dest flags */
11176 if (json_paths) {
11177 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11178 json_object_boolean_true_add(json_path, "processScheduled");
11179 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11180 json_object_boolean_true_add(json_path, "userCleared");
11181 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11182 json_object_boolean_true_add(json_path, "labelChanged");
11183 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11184 json_object_boolean_true_add(json_path, "registeredForLabel");
11185 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11186 json_object_boolean_true_add(json_path, "selectDefered");
11187 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11188 json_object_boolean_true_add(json_path, "fibInstalled");
11189 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11190 json_object_boolean_true_add(json_path, "fibPending");
11191
11192 if (json_nexthop_global || json_nexthop_ll) {
11193 json_nexthops = json_object_new_array();
11194
11195 if (json_nexthop_global)
11196 json_object_array_add(json_nexthops,
11197 json_nexthop_global);
11198
11199 if (json_nexthop_ll)
11200 json_object_array_add(json_nexthops,
11201 json_nexthop_ll);
11202
11203 json_object_object_add(json_path, "nexthops",
11204 json_nexthops);
11205 }
11206
11207 json_object_object_add(json_path, "peer", json_peer);
11208 json_object_array_add(json_paths, json_path);
11209 }
11210 }
11211
11212 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11213 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11214 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11215
11216 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11217 afi_t afi, safi_t safi, enum bgp_show_type type,
11218 bool use_json);
11219 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11220 const char *comstr, int exact, afi_t afi,
11221 safi_t safi, uint16_t show_flags);
11222
11223 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11224 struct bgp_table *table, enum bgp_show_type type,
11225 void *output_arg, const char *rd, int is_last,
11226 unsigned long *output_cum, unsigned long *total_cum,
11227 unsigned long *json_header_depth, uint16_t show_flags,
11228 enum rpki_states rpki_target_state)
11229 {
11230 struct bgp_path_info *pi;
11231 struct bgp_dest *dest;
11232 bool header = true;
11233 bool json_detail_header = false;
11234 int display;
11235 unsigned long output_count = 0;
11236 unsigned long total_count = 0;
11237 struct prefix *p;
11238 json_object *json_paths = NULL;
11239 int first = 1;
11240 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11241 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11242 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11243 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11244 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11245
11246 if (output_cum && *output_cum != 0)
11247 header = false;
11248
11249 if (use_json && !*json_header_depth) {
11250 if (all)
11251 *json_header_depth = 1;
11252 else {
11253 vty_out(vty, "{\n");
11254 *json_header_depth = 2;
11255 }
11256 vty_out(vty,
11257 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11258 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11259 " \"localAS\": ",
11260 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11261 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11262 ? VRF_DEFAULT_NAME
11263 : bgp->name,
11264 table->version, &bgp->router_id,
11265 bgp->default_local_pref);
11266 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11267 ((bgp->asnotation == ASNOTATION_DOT) &&
11268 (bgp->as < UINT16_MAX)))
11269 vty_out(vty, "%u", bgp->as);
11270 else {
11271 vty_out(vty, "\"");
11272 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11273 vty_out(vty, "\"");
11274 }
11275 vty_out(vty, ",\n \"routes\": { ");
11276 if (rd) {
11277 vty_out(vty, " \"routeDistinguishers\" : {");
11278 ++*json_header_depth;
11279 }
11280 }
11281
11282 if (use_json && rd) {
11283 vty_out(vty, " \"%s\" : { ", rd);
11284 }
11285
11286 /* Check for 'json detail', where we need header output once per dest */
11287 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11288 type != bgp_show_type_damp_neighbor &&
11289 type != bgp_show_type_flap_statistics &&
11290 type != bgp_show_type_flap_neighbor)
11291 json_detail_header = true;
11292
11293 /* Start processing of routes. */
11294 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11295 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11296 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11297 bool json_detail_header_used = false;
11298
11299 pi = bgp_dest_get_bgp_path_info(dest);
11300 if (pi == NULL)
11301 continue;
11302
11303 display = 0;
11304 if (use_json)
11305 json_paths = json_object_new_array();
11306 else
11307 json_paths = NULL;
11308
11309 for (; pi; pi = pi->next) {
11310 struct community *picomm = NULL;
11311
11312 picomm = bgp_attr_get_community(pi->attr);
11313
11314 total_count++;
11315
11316 if (type == bgp_show_type_prefix_version) {
11317 uint32_t version =
11318 strtoul(output_arg, NULL, 10);
11319 if (dest->version < version)
11320 continue;
11321 }
11322
11323 if (type == bgp_show_type_community_alias) {
11324 char *alias = output_arg;
11325 char **communities;
11326 int num;
11327 bool found = false;
11328
11329 if (picomm) {
11330 frrstr_split(picomm->str, " ",
11331 &communities, &num);
11332 for (int i = 0; i < num; i++) {
11333 const char *com2alias =
11334 bgp_community2alias(
11335 communities[i]);
11336 if (!found
11337 && strcmp(alias, com2alias)
11338 == 0)
11339 found = true;
11340 XFREE(MTYPE_TMP,
11341 communities[i]);
11342 }
11343 XFREE(MTYPE_TMP, communities);
11344 }
11345
11346 if (!found &&
11347 bgp_attr_get_lcommunity(pi->attr)) {
11348 frrstr_split(bgp_attr_get_lcommunity(
11349 pi->attr)
11350 ->str,
11351 " ", &communities, &num);
11352 for (int i = 0; i < num; i++) {
11353 const char *com2alias =
11354 bgp_community2alias(
11355 communities[i]);
11356 if (!found
11357 && strcmp(alias, com2alias)
11358 == 0)
11359 found = true;
11360 XFREE(MTYPE_TMP,
11361 communities[i]);
11362 }
11363 XFREE(MTYPE_TMP, communities);
11364 }
11365
11366 if (!found)
11367 continue;
11368 }
11369
11370 if (type == bgp_show_type_rpki) {
11371 if (dest_p->family == AF_INET
11372 || dest_p->family == AF_INET6)
11373 rpki_curr_state = hook_call(
11374 bgp_rpki_prefix_status,
11375 pi->peer, pi->attr, dest_p);
11376 if (rpki_target_state != RPKI_NOT_BEING_USED
11377 && rpki_curr_state != rpki_target_state)
11378 continue;
11379 }
11380
11381 if (type == bgp_show_type_flap_statistics
11382 || type == bgp_show_type_flap_neighbor
11383 || type == bgp_show_type_dampend_paths
11384 || type == bgp_show_type_damp_neighbor) {
11385 if (!(pi->extra && pi->extra->damp_info))
11386 continue;
11387 }
11388 if (type == bgp_show_type_regexp) {
11389 regex_t *regex = output_arg;
11390
11391 if (bgp_regexec(regex, pi->attr->aspath)
11392 == REG_NOMATCH)
11393 continue;
11394 }
11395 if (type == bgp_show_type_prefix_list) {
11396 struct prefix_list *plist = output_arg;
11397
11398 if (prefix_list_apply(plist, dest_p)
11399 != PREFIX_PERMIT)
11400 continue;
11401 }
11402 if (type == bgp_show_type_access_list) {
11403 struct access_list *alist = output_arg;
11404
11405 if (access_list_apply(alist, dest_p) !=
11406 FILTER_PERMIT)
11407 continue;
11408 }
11409 if (type == bgp_show_type_filter_list) {
11410 struct as_list *as_list = output_arg;
11411
11412 if (as_list_apply(as_list, pi->attr->aspath)
11413 != AS_FILTER_PERMIT)
11414 continue;
11415 }
11416 if (type == bgp_show_type_route_map) {
11417 struct route_map *rmap = output_arg;
11418 struct bgp_path_info path;
11419 struct bgp_path_info_extra extra;
11420 struct attr dummy_attr = {};
11421 route_map_result_t ret;
11422
11423 dummy_attr = *pi->attr;
11424
11425 prep_for_rmap_apply(&path, &extra, dest, pi,
11426 pi->peer, &dummy_attr);
11427
11428 ret = route_map_apply(rmap, dest_p, &path);
11429 bgp_attr_flush(&dummy_attr);
11430 if (ret == RMAP_DENYMATCH)
11431 continue;
11432 }
11433 if (type == bgp_show_type_neighbor
11434 || type == bgp_show_type_flap_neighbor
11435 || type == bgp_show_type_damp_neighbor) {
11436 union sockunion *su = output_arg;
11437
11438 if (pi->peer == NULL
11439 || pi->peer->su_remote == NULL
11440 || !sockunion_same(pi->peer->su_remote, su))
11441 continue;
11442 }
11443 if (type == bgp_show_type_cidr_only) {
11444 uint32_t destination;
11445
11446 destination = ntohl(dest_p->u.prefix4.s_addr);
11447 if (IN_CLASSC(destination)
11448 && dest_p->prefixlen == 24)
11449 continue;
11450 if (IN_CLASSB(destination)
11451 && dest_p->prefixlen == 16)
11452 continue;
11453 if (IN_CLASSA(destination)
11454 && dest_p->prefixlen == 8)
11455 continue;
11456 }
11457 if (type == bgp_show_type_prefix_longer) {
11458 p = output_arg;
11459 if (!prefix_match(p, dest_p))
11460 continue;
11461 }
11462 if (type == bgp_show_type_community_all) {
11463 if (!picomm)
11464 continue;
11465 }
11466 if (type == bgp_show_type_community) {
11467 struct community *com = output_arg;
11468
11469 if (!picomm || !community_match(picomm, com))
11470 continue;
11471 }
11472 if (type == bgp_show_type_community_exact) {
11473 struct community *com = output_arg;
11474
11475 if (!picomm || !community_cmp(picomm, com))
11476 continue;
11477 }
11478 if (type == bgp_show_type_community_list) {
11479 struct community_list *list = output_arg;
11480
11481 if (!community_list_match(picomm, list))
11482 continue;
11483 }
11484 if (type == bgp_show_type_community_list_exact) {
11485 struct community_list *list = output_arg;
11486
11487 if (!community_list_exact_match(picomm, list))
11488 continue;
11489 }
11490 if (type == bgp_show_type_lcommunity) {
11491 struct lcommunity *lcom = output_arg;
11492
11493 if (!bgp_attr_get_lcommunity(pi->attr) ||
11494 !lcommunity_match(
11495 bgp_attr_get_lcommunity(pi->attr),
11496 lcom))
11497 continue;
11498 }
11499
11500 if (type == bgp_show_type_lcommunity_exact) {
11501 struct lcommunity *lcom = output_arg;
11502
11503 if (!bgp_attr_get_lcommunity(pi->attr) ||
11504 !lcommunity_cmp(
11505 bgp_attr_get_lcommunity(pi->attr),
11506 lcom))
11507 continue;
11508 }
11509 if (type == bgp_show_type_lcommunity_list) {
11510 struct community_list *list = output_arg;
11511
11512 if (!lcommunity_list_match(
11513 bgp_attr_get_lcommunity(pi->attr),
11514 list))
11515 continue;
11516 }
11517 if (type
11518 == bgp_show_type_lcommunity_list_exact) {
11519 struct community_list *list = output_arg;
11520
11521 if (!lcommunity_list_exact_match(
11522 bgp_attr_get_lcommunity(pi->attr),
11523 list))
11524 continue;
11525 }
11526 if (type == bgp_show_type_lcommunity_all) {
11527 if (!bgp_attr_get_lcommunity(pi->attr))
11528 continue;
11529 }
11530 if (type == bgp_show_type_dampend_paths
11531 || type == bgp_show_type_damp_neighbor) {
11532 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11533 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11534 continue;
11535 }
11536 if (type == bgp_show_type_self_originated) {
11537 if (pi->peer != bgp->peer_self)
11538 continue;
11539 }
11540
11541 if (!use_json && header) {
11542 vty_out(vty,
11543 "BGP table version is %" PRIu64
11544 ", local router ID is %pI4, vrf id ",
11545 table->version, &bgp->router_id);
11546 if (bgp->vrf_id == VRF_UNKNOWN)
11547 vty_out(vty, "%s", VRFID_NONE_STR);
11548 else
11549 vty_out(vty, "%u", bgp->vrf_id);
11550 vty_out(vty, "\n");
11551 vty_out(vty, "Default local pref %u, ",
11552 bgp->default_local_pref);
11553 vty_out(vty, "local AS ");
11554 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11555 &bgp->as);
11556 vty_out(vty, "\n");
11557 if (!detail_routes) {
11558 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11559 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11560 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11561 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11562 }
11563 if (type == bgp_show_type_dampend_paths
11564 || type == bgp_show_type_damp_neighbor)
11565 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11566 else if (type == bgp_show_type_flap_statistics
11567 || type == bgp_show_type_flap_neighbor)
11568 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11569 else if (!detail_routes)
11570 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11571 : BGP_SHOW_HEADER));
11572 header = false;
11573
11574 }
11575 if (rd != NULL && !display && !output_count) {
11576 if (!use_json)
11577 vty_out(vty,
11578 "Route Distinguisher: %s\n",
11579 rd);
11580 }
11581 if (type == bgp_show_type_dampend_paths
11582 || type == bgp_show_type_damp_neighbor)
11583 damp_route_vty_out(vty, dest_p, pi, display,
11584 AFI_IP, safi, use_json,
11585 json_paths);
11586 else if (type == bgp_show_type_flap_statistics
11587 || type == bgp_show_type_flap_neighbor)
11588 flap_route_vty_out(vty, dest_p, pi, display,
11589 AFI_IP, safi, use_json,
11590 json_paths);
11591 else {
11592 if (detail_routes || detail_json) {
11593 const struct prefix_rd *prd = NULL;
11594
11595 if (dest->pdest)
11596 prd = bgp_rd_from_dest(
11597 dest->pdest, safi);
11598
11599 if (!use_json)
11600 route_vty_out_detail_header(
11601 vty, bgp, dest,
11602 bgp_dest_get_prefix(
11603 dest),
11604 prd, table->afi, safi,
11605 NULL, false);
11606
11607 route_vty_out_detail(
11608 vty, bgp, dest, dest_p, pi,
11609 family2afi(dest_p->family),
11610 safi, RPKI_NOT_BEING_USED,
11611 json_paths);
11612 } else {
11613 route_vty_out(vty, dest_p, pi, display,
11614 safi, json_paths, wide);
11615 }
11616 }
11617 display++;
11618 }
11619
11620 if (display) {
11621 output_count++;
11622 if (!use_json)
11623 continue;
11624
11625 /* encode prefix */
11626 if (dest_p->family == AF_FLOWSPEC) {
11627 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11628
11629
11630 bgp_fs_nlri_get_string(
11631 (unsigned char *)
11632 dest_p->u.prefix_flowspec.ptr,
11633 dest_p->u.prefix_flowspec.prefixlen,
11634 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11635 family2afi(dest_p->u
11636 .prefix_flowspec.family));
11637 if (first)
11638 vty_out(vty, "\"%s/%d\": ", retstr,
11639 dest_p->u.prefix_flowspec
11640 .prefixlen);
11641 else
11642 vty_out(vty, ",\"%s/%d\": ", retstr,
11643 dest_p->u.prefix_flowspec
11644 .prefixlen);
11645 } else {
11646 if (first)
11647 vty_out(vty, "\"%pFX\": ", dest_p);
11648 else
11649 vty_out(vty, ",\"%pFX\": ", dest_p);
11650 }
11651
11652 /* This is used for 'json detail' vty keywords.
11653 *
11654 * In plain 'json' the per-prefix header is encoded
11655 * as a standalone dictionary in the first json_paths
11656 * array element:
11657 * "<prefix>": [{header}, {path-1}, {path-N}]
11658 * (which is confusing and borderline broken)
11659 *
11660 * For 'json detail' this changes the value
11661 * of each prefix-key to be a dictionary where each
11662 * header item has its own key, and json_paths is
11663 * tucked under the "paths" key:
11664 * "<prefix>": {
11665 * "<header-key-1>": <header-val-1>,
11666 * "<header-key-N>": <header-val-N>,
11667 * "paths": [{path-1}, {path-N}]
11668 * }
11669 */
11670 if (json_detail_header && json_paths != NULL) {
11671 const struct prefix_rd *prd;
11672
11673 /* Start per-prefix dictionary */
11674 vty_out(vty, "{\n");
11675
11676 prd = bgp_rd_from_dest(dest, safi);
11677
11678 route_vty_out_detail_header(
11679 vty, bgp, dest,
11680 bgp_dest_get_prefix(dest), prd,
11681 table->afi, safi, json_paths, true);
11682
11683 vty_out(vty, "\"paths\": ");
11684 json_detail_header_used = true;
11685 }
11686
11687 /*
11688 * We are using no_pretty here because under
11689 * extremely high settings( say lots and lots of
11690 * routes with lots and lots of ways to reach
11691 * that route via different paths ) this can
11692 * save several minutes of output when FRR
11693 * is run on older cpu's or more underperforming
11694 * routers out there
11695 */
11696 vty_json_no_pretty(vty, json_paths);
11697
11698 /* End per-prefix dictionary */
11699 if (json_detail_header_used)
11700 vty_out(vty, "} ");
11701
11702 json_paths = NULL;
11703 first = 0;
11704 } else
11705 json_object_free(json_paths);
11706 }
11707
11708 if (output_cum) {
11709 output_count += *output_cum;
11710 *output_cum = output_count;
11711 }
11712 if (total_cum) {
11713 total_count += *total_cum;
11714 *total_cum = total_count;
11715 }
11716 if (use_json) {
11717 if (rd) {
11718 vty_out(vty, " }%s ", (is_last ? "" : ","));
11719 }
11720 if (is_last) {
11721 unsigned long i;
11722 for (i = 0; i < *json_header_depth; ++i)
11723 vty_out(vty, " } ");
11724 if (!all)
11725 vty_out(vty, "\n");
11726 }
11727 } else {
11728 if (is_last) {
11729 /* No route is displayed */
11730 if (output_count == 0) {
11731 if (type == bgp_show_type_normal)
11732 vty_out(vty,
11733 "No BGP prefixes displayed, %ld exist\n",
11734 total_count);
11735 } else
11736 vty_out(vty,
11737 "\nDisplayed %ld routes and %ld total paths\n",
11738 output_count, total_count);
11739 }
11740 }
11741
11742 return CMD_SUCCESS;
11743 }
11744
11745 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11746 struct bgp_table *table, struct prefix_rd *prd_match,
11747 enum bgp_show_type type, void *output_arg,
11748 uint16_t show_flags)
11749 {
11750 struct bgp_dest *dest, *next;
11751 unsigned long output_cum = 0;
11752 unsigned long total_cum = 0;
11753 unsigned long json_header_depth = 0;
11754 struct bgp_table *itable;
11755 bool show_msg;
11756 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11757
11758 show_msg = (!use_json && type == bgp_show_type_normal);
11759
11760 for (dest = bgp_table_top(table); dest; dest = next) {
11761 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11762
11763 next = bgp_route_next(dest);
11764 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11765 continue;
11766
11767 itable = bgp_dest_get_bgp_table_info(dest);
11768 if (itable != NULL) {
11769 struct prefix_rd prd;
11770 char rd[RD_ADDRSTRLEN];
11771
11772 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11773 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11774 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11775 rd, next == NULL, &output_cum,
11776 &total_cum, &json_header_depth,
11777 show_flags, RPKI_NOT_BEING_USED);
11778 if (next == NULL)
11779 show_msg = false;
11780 }
11781 }
11782 if (show_msg) {
11783 if (output_cum == 0)
11784 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11785 total_cum);
11786 else
11787 vty_out(vty,
11788 "\nDisplayed %ld routes and %ld total paths\n",
11789 output_cum, total_cum);
11790 } else {
11791 if (use_json && output_cum == 0)
11792 vty_out(vty, "{}\n");
11793 }
11794 return CMD_SUCCESS;
11795 }
11796
11797 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11798 enum bgp_show_type type, void *output_arg,
11799 uint16_t show_flags, enum rpki_states rpki_target_state)
11800 {
11801 struct bgp_table *table;
11802 unsigned long json_header_depth = 0;
11803 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11804
11805 if (bgp == NULL) {
11806 bgp = bgp_get_default();
11807 }
11808
11809 if (bgp == NULL) {
11810 if (!use_json)
11811 vty_out(vty, "No BGP process is configured\n");
11812 else
11813 vty_out(vty, "{}\n");
11814 return CMD_WARNING;
11815 }
11816
11817 /* Labeled-unicast routes live in the unicast table. */
11818 if (safi == SAFI_LABELED_UNICAST)
11819 safi = SAFI_UNICAST;
11820
11821 table = bgp->rib[afi][safi];
11822 /* use MPLS and ENCAP specific shows until they are merged */
11823 if (safi == SAFI_MPLS_VPN) {
11824 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11825 output_arg, show_flags);
11826 }
11827
11828 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11829 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11830 output_arg, use_json,
11831 1, NULL, NULL);
11832 }
11833
11834 if (safi == SAFI_EVPN)
11835 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11836
11837 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11838 NULL, NULL, &json_header_depth, show_flags,
11839 rpki_target_state);
11840 }
11841
11842 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11843 safi_t safi, uint16_t show_flags)
11844 {
11845 struct listnode *node, *nnode;
11846 struct bgp *bgp;
11847 int is_first = 1;
11848 bool route_output = false;
11849 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11850
11851 if (use_json)
11852 vty_out(vty, "{\n");
11853
11854 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11855 route_output = true;
11856 if (use_json) {
11857 if (!is_first)
11858 vty_out(vty, ",\n");
11859 else
11860 is_first = 0;
11861
11862 vty_out(vty, "\"%s\":",
11863 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11864 ? VRF_DEFAULT_NAME
11865 : bgp->name);
11866 } else {
11867 vty_out(vty, "\nInstance %s:\n",
11868 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11869 ? VRF_DEFAULT_NAME
11870 : bgp->name);
11871 }
11872 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11873 show_flags, RPKI_NOT_BEING_USED);
11874 }
11875
11876 if (use_json)
11877 vty_out(vty, "}\n");
11878 else if (!route_output)
11879 vty_out(vty, "%% BGP instance not found\n");
11880 }
11881
11882 /* Header of detailed BGP route information */
11883 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11884 struct bgp_dest *dest, const struct prefix *p,
11885 const struct prefix_rd *prd, afi_t afi,
11886 safi_t safi, json_object *json,
11887 bool incremental_print)
11888 {
11889 struct bgp_path_info *pi;
11890 struct peer *peer;
11891 struct listnode *node, *nnode;
11892 char buf1[RD_ADDRSTRLEN];
11893 int count = 0;
11894 int best = 0;
11895 int suppress = 0;
11896 int accept_own = 0;
11897 int route_filter_translated_v4 = 0;
11898 int route_filter_v4 = 0;
11899 int route_filter_translated_v6 = 0;
11900 int route_filter_v6 = 0;
11901 int llgr_stale = 0;
11902 int no_llgr = 0;
11903 int accept_own_nexthop = 0;
11904 int blackhole = 0;
11905 int no_export = 0;
11906 int no_advertise = 0;
11907 int local_as = 0;
11908 int no_peer = 0;
11909 int first = 1;
11910 int has_valid_label = 0;
11911 mpls_label_t label = 0;
11912 json_object *json_adv_to = NULL;
11913 uint32_t ttl = 0;
11914 uint32_t bos = 0;
11915 uint32_t exp = 0;
11916
11917 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11918
11919 has_valid_label = bgp_is_valid_label(&label);
11920
11921 if (safi == SAFI_EVPN) {
11922 if (!json) {
11923 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11924 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11925 bgp->asnotation)
11926 : "",
11927 prd ? ":" : "", (struct prefix_evpn *)p);
11928 } else {
11929 json_object_string_add(
11930 json, "rd",
11931 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11932 bgp->asnotation)
11933 : "");
11934 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11935 }
11936 } else {
11937 if (!json) {
11938 vty_out(vty,
11939 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11940 "\n",
11941 (((safi == SAFI_MPLS_VPN ||
11942 safi == SAFI_ENCAP) &&
11943 prd)
11944 ? prefix_rd2str(prd, buf1,
11945 sizeof(buf1),
11946 bgp->asnotation)
11947 : ""),
11948 safi == SAFI_MPLS_VPN && prd ? ":" : "", p,
11949 dest->version);
11950
11951 } else {
11952 if (incremental_print) {
11953 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11954 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11955 dest->version);
11956 } else {
11957 json_object_string_addf(json, "prefix", "%pFX",
11958 p);
11959 json_object_int_add(json, "version",
11960 dest->version);
11961 }
11962 }
11963 }
11964
11965 if (has_valid_label) {
11966 if (json) {
11967 if (incremental_print)
11968 vty_out(vty, "\"localLabel\": \"%u\",\n",
11969 label);
11970 else
11971 json_object_int_add(json, "localLabel", label);
11972 } else
11973 vty_out(vty, "Local label: %d\n", label);
11974 }
11975
11976 if (!json)
11977 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11978 vty_out(vty, "not allocated\n");
11979
11980 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11981 struct community *picomm = NULL;
11982
11983 picomm = bgp_attr_get_community(pi->attr);
11984
11985 count++;
11986 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11987 best = count;
11988 if (bgp_path_suppressed(pi))
11989 suppress = 1;
11990
11991 if (!picomm)
11992 continue;
11993
11994 no_advertise += community_include(
11995 picomm, COMMUNITY_NO_ADVERTISE);
11996 no_export +=
11997 community_include(picomm, COMMUNITY_NO_EXPORT);
11998 local_as +=
11999 community_include(picomm, COMMUNITY_LOCAL_AS);
12000 accept_own +=
12001 community_include(picomm, COMMUNITY_ACCEPT_OWN);
12002 route_filter_translated_v4 += community_include(
12003 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
12004 route_filter_translated_v6 += community_include(
12005 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
12006 route_filter_v4 += community_include(
12007 picomm, COMMUNITY_ROUTE_FILTER_v4);
12008 route_filter_v6 += community_include(
12009 picomm, COMMUNITY_ROUTE_FILTER_v6);
12010 llgr_stale +=
12011 community_include(picomm, COMMUNITY_LLGR_STALE);
12012 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
12013 accept_own_nexthop += community_include(
12014 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
12015 blackhole +=
12016 community_include(picomm, COMMUNITY_BLACKHOLE);
12017 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
12018 }
12019 }
12020
12021 if (!json) {
12022 vty_out(vty, "Paths: (%d available", count);
12023 if (best) {
12024 vty_out(vty, ", best #%d", best);
12025 if (safi == SAFI_UNICAST) {
12026 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
12027 vty_out(vty, ", table %s",
12028 VRF_DEFAULT_NAME);
12029 else
12030 vty_out(vty, ", vrf %s",
12031 bgp->name);
12032 }
12033 } else
12034 vty_out(vty, ", no best path");
12035
12036 if (accept_own)
12037 vty_out(vty,
12038 ", accept own local route exported and imported in different VRF");
12039 else if (route_filter_translated_v4)
12040 vty_out(vty,
12041 ", mark translated RTs for VPNv4 route filtering");
12042 else if (route_filter_v4)
12043 vty_out(vty,
12044 ", attach RT as-is for VPNv4 route filtering");
12045 else if (route_filter_translated_v6)
12046 vty_out(vty,
12047 ", mark translated RTs for VPNv6 route filtering");
12048 else if (route_filter_v6)
12049 vty_out(vty,
12050 ", attach RT as-is for VPNv6 route filtering");
12051 else if (llgr_stale)
12052 vty_out(vty,
12053 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
12054 else if (no_llgr)
12055 vty_out(vty,
12056 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
12057 else if (accept_own_nexthop)
12058 vty_out(vty,
12059 ", accept local nexthop");
12060 else if (blackhole)
12061 vty_out(vty, ", inform peer to blackhole prefix");
12062 else if (no_export)
12063 vty_out(vty, ", not advertised to EBGP peer");
12064 else if (no_advertise)
12065 vty_out(vty, ", not advertised to any peer");
12066 else if (local_as)
12067 vty_out(vty, ", not advertised outside local AS");
12068 else if (no_peer)
12069 vty_out(vty,
12070 ", inform EBGP peer not to advertise to their EBGP peers");
12071
12072 if (suppress)
12073 vty_out(vty,
12074 ", Advertisements suppressed by an aggregate.");
12075 vty_out(vty, ")\n");
12076 }
12077
12078 /* If we are not using addpath then we can display Advertised to and
12079 * that will
12080 * show what peers we advertised the bestpath to. If we are using
12081 * addpath
12082 * though then we must display Advertised to on a path-by-path basis. */
12083 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12084 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12085 if (bgp_adj_out_lookup(peer, dest, 0)) {
12086 if (json && !json_adv_to)
12087 json_adv_to = json_object_new_object();
12088
12089 route_vty_out_advertised_to(
12090 vty, peer, &first,
12091 " Advertised to non peer-group peers:\n ",
12092 json_adv_to);
12093 }
12094 }
12095
12096 if (json && json_adv_to) {
12097 if (incremental_print) {
12098 vty_out(vty, "\"advertisedTo\": ");
12099 vty_json(vty, json_adv_to);
12100 vty_out(vty, ",");
12101 } else
12102 json_object_object_add(json, "advertisedTo",
12103 json_adv_to);
12104 } else {
12105 if (!json && first)
12106 vty_out(vty, " Not advertised to any peer");
12107 vty_out(vty, "\n");
12108 }
12109 }
12110 }
12111
12112 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12113 struct bgp_dest *bgp_node, struct vty *vty,
12114 struct bgp *bgp, afi_t afi, safi_t safi,
12115 json_object *json, enum bgp_path_type pathtype,
12116 int *display, enum rpki_states rpki_target_state)
12117 {
12118 struct bgp_path_info *pi;
12119 int header = 1;
12120 json_object *json_header = NULL;
12121 json_object *json_paths = NULL;
12122 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12123
12124 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12125 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12126
12127 if (p->family == AF_INET || p->family == AF_INET6)
12128 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12129 pi->peer, pi->attr, p);
12130
12131 if (rpki_target_state != RPKI_NOT_BEING_USED
12132 && rpki_curr_state != rpki_target_state)
12133 continue;
12134
12135 if (json && !json_paths) {
12136 /* Instantiate json_paths only if path is valid */
12137 json_paths = json_object_new_array();
12138 if (pfx_rd)
12139 json_header = json_object_new_object();
12140 else
12141 json_header = json;
12142 }
12143
12144 if (header) {
12145 route_vty_out_detail_header(
12146 vty, bgp, bgp_node,
12147 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12148 safi, json_header, false);
12149 header = 0;
12150 }
12151 (*display)++;
12152
12153 if (pathtype == BGP_PATH_SHOW_ALL
12154 || (pathtype == BGP_PATH_SHOW_BESTPATH
12155 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12156 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12157 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12158 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12159 route_vty_out_detail(vty, bgp, bgp_node,
12160 bgp_dest_get_prefix(bgp_node), pi,
12161 AFI_IP, safi, rpki_curr_state,
12162 json_paths);
12163 }
12164
12165 if (json && json_paths) {
12166 json_object_object_add(json_header, "paths", json_paths);
12167
12168 if (pfx_rd)
12169 json_object_object_addf(
12170 json, json_header,
12171 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12172 }
12173 }
12174
12175 /*
12176 * Return rd based on safi
12177 */
12178 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12179 safi_t safi)
12180 {
12181 switch (safi) {
12182 case SAFI_MPLS_VPN:
12183 case SAFI_ENCAP:
12184 case SAFI_EVPN:
12185 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12186 case SAFI_UNSPEC:
12187 case SAFI_UNICAST:
12188 case SAFI_MULTICAST:
12189 case SAFI_LABELED_UNICAST:
12190 case SAFI_FLOWSPEC:
12191 case SAFI_MAX:
12192 return NULL;
12193 }
12194
12195 assert(!"Reached end of function when we were not expecting it");
12196 }
12197
12198 /* Display specified route of BGP table. */
12199 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12200 struct bgp_table *rib, const char *ip_str,
12201 afi_t afi, safi_t safi,
12202 enum rpki_states rpki_target_state,
12203 struct prefix_rd *prd, int prefix_check,
12204 enum bgp_path_type pathtype, bool use_json)
12205 {
12206 int ret;
12207 int display = 0;
12208 struct prefix match;
12209 struct bgp_dest *dest;
12210 struct bgp_dest *rm;
12211 struct bgp_table *table;
12212 json_object *json = NULL;
12213 json_object *json_paths = NULL;
12214
12215 /* Check IP address argument. */
12216 ret = str2prefix(ip_str, &match);
12217 if (!ret) {
12218 vty_out(vty, "address is malformed\n");
12219 return CMD_WARNING;
12220 }
12221
12222 match.family = afi2family(afi);
12223
12224 if (use_json)
12225 json = json_object_new_object();
12226
12227 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12228 for (dest = bgp_table_top(rib); dest;
12229 dest = bgp_route_next(dest)) {
12230 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12231
12232 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12233 continue;
12234 table = bgp_dest_get_bgp_table_info(dest);
12235 if (!table)
12236 continue;
12237
12238 rm = bgp_node_match(table, &match);
12239 if (rm == NULL)
12240 continue;
12241
12242 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12243 if (prefix_check
12244 && rm_p->prefixlen != match.prefixlen) {
12245 bgp_dest_unlock_node(rm);
12246 continue;
12247 }
12248
12249 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12250 bgp, afi, safi, json, pathtype,
12251 &display, rpki_target_state);
12252
12253 bgp_dest_unlock_node(rm);
12254 }
12255 } else if (safi == SAFI_EVPN) {
12256 struct bgp_dest *longest_pfx;
12257 bool is_exact_pfxlen_match = false;
12258
12259 for (dest = bgp_table_top(rib); dest;
12260 dest = bgp_route_next(dest)) {
12261 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12262
12263 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12264 continue;
12265 table = bgp_dest_get_bgp_table_info(dest);
12266 if (!table)
12267 continue;
12268
12269 longest_pfx = NULL;
12270 is_exact_pfxlen_match = false;
12271 /*
12272 * Search through all the prefixes for a match. The
12273 * pfx's are enumerated in ascending order of pfxlens.
12274 * So, the last pfx match is the longest match. Set
12275 * is_exact_pfxlen_match when we get exact pfxlen match
12276 */
12277 for (rm = bgp_table_top(table); rm;
12278 rm = bgp_route_next(rm)) {
12279 const struct prefix *rm_p =
12280 bgp_dest_get_prefix(rm);
12281 /*
12282 * Get prefixlen of the ip-prefix within type5
12283 * evpn route
12284 */
12285 if (evpn_type5_prefix_match(rm_p, &match)
12286 && rm->info) {
12287 longest_pfx = rm;
12288 int type5_pfxlen =
12289 bgp_evpn_get_type5_prefixlen(
12290 rm_p);
12291 if (type5_pfxlen == match.prefixlen) {
12292 is_exact_pfxlen_match = true;
12293 bgp_dest_unlock_node(rm);
12294 break;
12295 }
12296 }
12297 }
12298
12299 if (!longest_pfx)
12300 continue;
12301
12302 if (prefix_check && !is_exact_pfxlen_match)
12303 continue;
12304
12305 rm = longest_pfx;
12306 bgp_dest_lock_node(rm);
12307
12308 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12309 bgp, afi, safi, json, pathtype,
12310 &display, rpki_target_state);
12311
12312 bgp_dest_unlock_node(rm);
12313 }
12314 } else if (safi == SAFI_FLOWSPEC) {
12315 if (use_json)
12316 json_paths = json_object_new_array();
12317
12318 display = bgp_flowspec_display_match_per_ip(afi, rib,
12319 &match, prefix_check,
12320 vty,
12321 use_json,
12322 json_paths);
12323 if (use_json) {
12324 if (display)
12325 json_object_object_add(json, "paths",
12326 json_paths);
12327 else
12328 json_object_free(json_paths);
12329 }
12330 } else {
12331 dest = bgp_node_match(rib, &match);
12332 if (dest != NULL) {
12333 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12334 if (!prefix_check
12335 || dest_p->prefixlen == match.prefixlen) {
12336 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12337 safi, json, pathtype,
12338 &display, rpki_target_state);
12339 }
12340
12341 bgp_dest_unlock_node(dest);
12342 }
12343 }
12344
12345 if (use_json) {
12346 vty_json(vty, json);
12347 } else {
12348 if (!display) {
12349 vty_out(vty, "%% Network not in table\n");
12350 return CMD_WARNING;
12351 }
12352 }
12353
12354 return CMD_SUCCESS;
12355 }
12356
12357 /* Display specified route of Main RIB */
12358 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12359 afi_t afi, safi_t safi, struct prefix_rd *prd,
12360 int prefix_check, enum bgp_path_type pathtype,
12361 enum rpki_states rpki_target_state, bool use_json)
12362 {
12363 if (!bgp) {
12364 bgp = bgp_get_default();
12365 if (!bgp) {
12366 if (!use_json)
12367 vty_out(vty, "No BGP process is configured\n");
12368 else
12369 vty_out(vty, "{}\n");
12370 return CMD_WARNING;
12371 }
12372 }
12373
12374 /* labeled-unicast routes live in the unicast table */
12375 if (safi == SAFI_LABELED_UNICAST)
12376 safi = SAFI_UNICAST;
12377
12378 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12379 afi, safi, rpki_target_state, prd,
12380 prefix_check, pathtype, use_json);
12381 }
12382
12383 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12384 struct cmd_token **argv, bool exact, afi_t afi,
12385 safi_t safi, bool uj)
12386 {
12387 struct lcommunity *lcom;
12388 struct buffer *b;
12389 int i;
12390 char *str;
12391 int first = 0;
12392 uint16_t show_flags = 0;
12393 int ret;
12394
12395 if (uj)
12396 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12397
12398 b = buffer_new(1024);
12399 for (i = 0; i < argc; i++) {
12400 if (first)
12401 buffer_putc(b, ' ');
12402 else {
12403 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12404 first = 1;
12405 buffer_putstr(b, argv[i]->arg);
12406 }
12407 }
12408 }
12409 buffer_putc(b, '\0');
12410
12411 str = buffer_getstr(b);
12412 buffer_free(b);
12413
12414 lcom = lcommunity_str2com(str);
12415 XFREE(MTYPE_TMP, str);
12416 if (!lcom) {
12417 vty_out(vty, "%% Large-community malformed\n");
12418 return CMD_WARNING;
12419 }
12420
12421 ret = bgp_show(vty, bgp, afi, safi,
12422 (exact ? bgp_show_type_lcommunity_exact
12423 : bgp_show_type_lcommunity),
12424 lcom, show_flags, RPKI_NOT_BEING_USED);
12425
12426 lcommunity_free(&lcom);
12427 return ret;
12428 }
12429
12430 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12431 const char *lcom, bool exact, afi_t afi,
12432 safi_t safi, bool uj)
12433 {
12434 struct community_list *list;
12435 uint16_t show_flags = 0;
12436
12437 if (uj)
12438 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12439
12440
12441 list = community_list_lookup(bgp_clist, lcom, 0,
12442 LARGE_COMMUNITY_LIST_MASTER);
12443 if (list == NULL) {
12444 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12445 lcom);
12446 return CMD_WARNING;
12447 }
12448
12449 return bgp_show(vty, bgp, afi, safi,
12450 (exact ? bgp_show_type_lcommunity_list_exact
12451 : bgp_show_type_lcommunity_list),
12452 list, show_flags, RPKI_NOT_BEING_USED);
12453 }
12454
12455 DEFUN (show_ip_bgp_large_community_list,
12456 show_ip_bgp_large_community_list_cmd,
12457 "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]",
12458 SHOW_STR
12459 IP_STR
12460 BGP_STR
12461 BGP_INSTANCE_HELP_STR
12462 BGP_AFI_HELP_STR
12463 BGP_SAFI_WITH_LABEL_HELP_STR
12464 "Display routes matching the large-community-list\n"
12465 "large-community-list number\n"
12466 "large-community-list name\n"
12467 "Exact match of the large-communities\n"
12468 JSON_STR)
12469 {
12470 afi_t afi = AFI_IP6;
12471 safi_t safi = SAFI_UNICAST;
12472 int idx = 0;
12473 bool exact_match = 0;
12474 struct bgp *bgp = NULL;
12475 bool uj = use_json(argc, argv);
12476
12477 if (uj)
12478 argc--;
12479
12480 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12481 &bgp, uj);
12482 if (!idx)
12483 return CMD_WARNING;
12484
12485 argv_find(argv, argc, "large-community-list", &idx);
12486
12487 const char *clist_number_or_name = argv[++idx]->arg;
12488
12489 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12490 exact_match = 1;
12491
12492 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12493 exact_match, afi, safi, uj);
12494 }
12495 DEFUN (show_ip_bgp_large_community,
12496 show_ip_bgp_large_community_cmd,
12497 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12498 SHOW_STR
12499 IP_STR
12500 BGP_STR
12501 BGP_INSTANCE_HELP_STR
12502 BGP_AFI_HELP_STR
12503 BGP_SAFI_WITH_LABEL_HELP_STR
12504 "Display routes matching the large-communities\n"
12505 "List of large-community numbers\n"
12506 "Exact match of the large-communities\n"
12507 JSON_STR)
12508 {
12509 afi_t afi = AFI_IP6;
12510 safi_t safi = SAFI_UNICAST;
12511 int idx = 0;
12512 bool exact_match = 0;
12513 struct bgp *bgp = NULL;
12514 bool uj = use_json(argc, argv);
12515 uint16_t show_flags = 0;
12516
12517 if (uj) {
12518 argc--;
12519 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12520 }
12521
12522 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12523 &bgp, uj);
12524 if (!idx)
12525 return CMD_WARNING;
12526
12527 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12528 if (argv_find(argv, argc, "exact-match", &idx)) {
12529 argc--;
12530 exact_match = 1;
12531 }
12532 return bgp_show_lcommunity(vty, bgp, argc, argv,
12533 exact_match, afi, safi, uj);
12534 } else
12535 return bgp_show(vty, bgp, afi, safi,
12536 bgp_show_type_lcommunity_all, NULL, show_flags,
12537 RPKI_NOT_BEING_USED);
12538 }
12539
12540 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12541 safi_t safi, struct json_object *json_array);
12542 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12543 safi_t safi, struct json_object *json);
12544
12545
12546 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12547 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12548 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12549 "Display number of prefixes for all afi/safi\n" JSON_STR)
12550 {
12551 bool uj = use_json(argc, argv);
12552 struct bgp *bgp = NULL;
12553 safi_t safi = SAFI_UNICAST;
12554 afi_t afi = AFI_IP6;
12555 int idx = 0;
12556 struct json_object *json_all = NULL;
12557 struct json_object *json_afi_safi = NULL;
12558
12559 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12560 &bgp, false);
12561 if (!idx)
12562 return CMD_WARNING;
12563
12564 if (uj)
12565 json_all = json_object_new_object();
12566
12567 FOREACH_AFI_SAFI (afi, safi) {
12568 /*
12569 * So limit output to those afi/safi pairs that
12570 * actually have something interesting in them
12571 */
12572 if (strmatch(get_afi_safi_str(afi, safi, true),
12573 "Unknown")) {
12574 continue;
12575 }
12576 if (uj) {
12577 json_afi_safi = json_object_new_array();
12578 json_object_object_add(
12579 json_all,
12580 get_afi_safi_str(afi, safi, true),
12581 json_afi_safi);
12582 } else {
12583 json_afi_safi = NULL;
12584 }
12585
12586 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12587 }
12588
12589 if (uj)
12590 vty_json(vty, json_all);
12591
12592 return CMD_SUCCESS;
12593 }
12594
12595 /* BGP route print out function without JSON */
12596 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12597 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12598 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12599 SHOW_STR
12600 IP_STR
12601 BGP_STR
12602 BGP_INSTANCE_HELP_STR
12603 L2VPN_HELP_STR
12604 EVPN_HELP_STR
12605 "BGP RIB advertisement statistics\n"
12606 JSON_STR)
12607 {
12608 afi_t afi = AFI_IP6;
12609 safi_t safi = SAFI_UNICAST;
12610 struct bgp *bgp = NULL;
12611 int idx = 0, ret;
12612 bool uj = use_json(argc, argv);
12613 struct json_object *json_afi_safi = NULL, *json = NULL;
12614
12615 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12616 &bgp, false);
12617 if (!idx)
12618 return CMD_WARNING;
12619
12620 if (uj)
12621 json_afi_safi = json_object_new_array();
12622 else
12623 json_afi_safi = NULL;
12624
12625 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12626
12627 if (uj) {
12628 json = json_object_new_object();
12629 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12630 json_afi_safi);
12631 vty_json(vty, json);
12632 }
12633 return ret;
12634 }
12635
12636 /* BGP route print out function without JSON */
12637 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12638 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12639 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12640 "]]\
12641 statistics [json]",
12642 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12643 BGP_SAFI_WITH_LABEL_HELP_STR
12644 "BGP RIB advertisement statistics\n" JSON_STR)
12645 {
12646 afi_t afi = AFI_IP6;
12647 safi_t safi = SAFI_UNICAST;
12648 struct bgp *bgp = NULL;
12649 int idx = 0, ret;
12650 bool uj = use_json(argc, argv);
12651 struct json_object *json_afi_safi = NULL, *json = NULL;
12652
12653 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12654 &bgp, false);
12655 if (!idx)
12656 return CMD_WARNING;
12657
12658 if (uj)
12659 json_afi_safi = json_object_new_array();
12660 else
12661 json_afi_safi = NULL;
12662
12663 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12664
12665 if (uj) {
12666 json = json_object_new_object();
12667 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12668 json_afi_safi);
12669 vty_json(vty, json);
12670 }
12671 return ret;
12672 }
12673
12674 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12675 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12676 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12677 "]] [all$all] dampening parameters [json]",
12678 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12679 BGP_SAFI_WITH_LABEL_HELP_STR
12680 "Display the entries for all address families\n"
12681 "Display detailed information about dampening\n"
12682 "Display detail of configured dampening parameters\n"
12683 JSON_STR)
12684 {
12685 afi_t afi = AFI_IP6;
12686 safi_t safi = SAFI_UNICAST;
12687 struct bgp *bgp = NULL;
12688 int idx = 0;
12689 uint16_t show_flags = 0;
12690 bool uj = use_json(argc, argv);
12691
12692 if (uj) {
12693 argc--;
12694 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12695 }
12696
12697 /* [<ipv4|ipv6> [all]] */
12698 if (all) {
12699 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12700 if (argv_find(argv, argc, "ipv4", &idx))
12701 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12702
12703 if (argv_find(argv, argc, "ipv6", &idx))
12704 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12705 }
12706
12707 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12708 &bgp, false);
12709 if (!idx)
12710 return CMD_WARNING;
12711
12712 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12713 }
12714
12715 /* BGP route print out function */
12716 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12717 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12718 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12719 "]]\
12720 [all$all]\
12721 [cidr-only\
12722 |dampening <flap-statistics|dampened-paths>\
12723 |community [AA:NN|local-AS|no-advertise|no-export\
12724 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12725 |accept-own|accept-own-nexthop|route-filter-v6\
12726 |route-filter-v4|route-filter-translated-v6\
12727 |route-filter-translated-v4] [exact-match]\
12728 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12729 |filter-list AS_PATH_FILTER_NAME\
12730 |prefix-list WORD\
12731 |access-list ACCESSLIST_NAME\
12732 |route-map RMAP_NAME\
12733 |rpki <invalid|valid|notfound>\
12734 |version (1-4294967295)\
12735 |alias ALIAS_NAME\
12736 |A.B.C.D/M longer-prefixes\
12737 |X:X::X:X/M longer-prefixes\
12738 |"BGP_SELF_ORIG_CMD_STR"\
12739 |detail-routes$detail_routes\
12740 ] [json$uj [detail$detail_json] | wide$wide]",
12741 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12742 BGP_SAFI_WITH_LABEL_HELP_STR
12743 "Display the entries for all address families\n"
12744 "Display only routes with non-natural netmasks\n"
12745 "Display detailed information about dampening\n"
12746 "Display flap statistics of routes\n"
12747 "Display paths suppressed due to dampening\n"
12748 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12749 "Do not send outside local AS (well-known community)\n"
12750 "Do not advertise to any peer (well-known community)\n"
12751 "Do not export to next AS (well-known community)\n"
12752 "Graceful shutdown (well-known community)\n"
12753 "Do not export to any peer (well-known community)\n"
12754 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12755 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12756 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12757 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12758 "Should accept VPN route with local nexthop (well-known community)\n"
12759 "RT VPNv6 route filtering (well-known community)\n"
12760 "RT VPNv4 route filtering (well-known community)\n"
12761 "RT translated VPNv6 route filtering (well-known community)\n"
12762 "RT translated VPNv4 route filtering (well-known community)\n"
12763 "Exact match of the communities\n"
12764 "Community-list number\n"
12765 "Community-list name\n"
12766 "Display routes matching the community-list\n"
12767 "Exact match of the communities\n"
12768 "Display routes conforming to the filter-list\n"
12769 "Regular expression access list name\n"
12770 "Display routes conforming to the prefix-list\n"
12771 "Prefix-list name\n"
12772 "Display routes conforming to the access-list\n"
12773 "Access-list name\n"
12774 "Display routes matching the route-map\n"
12775 "A route-map to match on\n"
12776 "RPKI route types\n"
12777 "A valid path as determined by rpki\n"
12778 "A invalid path as determined by rpki\n"
12779 "A path that has no rpki data\n"
12780 "Display prefixes with matching version numbers\n"
12781 "Version number and above\n"
12782 "Display prefixes with matching BGP community alias\n"
12783 "BGP community alias\n"
12784 "IPv4 prefix\n"
12785 "Display route and more specific routes\n"
12786 "IPv6 prefix\n"
12787 "Display route and more specific routes\n"
12788 BGP_SELF_ORIG_HELP_STR
12789 "Display detailed version of all routes\n"
12790 JSON_STR
12791 "Display detailed version of JSON output\n"
12792 "Increase table width for longer prefixes\n")
12793 {
12794 afi_t afi = AFI_IP6;
12795 safi_t safi = SAFI_UNICAST;
12796 enum bgp_show_type sh_type = bgp_show_type_normal;
12797 void *output_arg = NULL;
12798 struct bgp *bgp = NULL;
12799 int idx = 0;
12800 int exact_match = 0;
12801 char *community = NULL;
12802 bool first = true;
12803 uint16_t show_flags = 0;
12804 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12805 struct prefix p;
12806
12807 if (uj) {
12808 argc--;
12809 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12810 }
12811
12812 if (detail_json)
12813 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12814
12815 if (detail_routes)
12816 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12817
12818 /* [<ipv4|ipv6> [all]] */
12819 if (all) {
12820 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12821
12822 if (argv_find(argv, argc, "ipv4", &idx))
12823 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12824
12825 if (argv_find(argv, argc, "ipv6", &idx))
12826 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12827 }
12828
12829 if (wide)
12830 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12831
12832 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12833 &bgp, uj);
12834 if (!idx)
12835 return CMD_WARNING;
12836
12837 if (argv_find(argv, argc, "cidr-only", &idx))
12838 sh_type = bgp_show_type_cidr_only;
12839
12840 if (argv_find(argv, argc, "dampening", &idx)) {
12841 if (argv_find(argv, argc, "dampened-paths", &idx))
12842 sh_type = bgp_show_type_dampend_paths;
12843 else if (argv_find(argv, argc, "flap-statistics", &idx))
12844 sh_type = bgp_show_type_flap_statistics;
12845 }
12846
12847 if (argv_find(argv, argc, "community", &idx)) {
12848 char *maybecomm = NULL;
12849
12850 if (idx + 1 < argc) {
12851 if (argv[idx + 1]->type == VARIABLE_TKN)
12852 maybecomm = argv[idx + 1]->arg;
12853 else
12854 maybecomm = argv[idx + 1]->text;
12855 }
12856
12857 if (maybecomm && !strmatch(maybecomm, "json")
12858 && !strmatch(maybecomm, "exact-match"))
12859 community = maybecomm;
12860
12861 if (argv_find(argv, argc, "exact-match", &idx))
12862 exact_match = 1;
12863
12864 if (!community)
12865 sh_type = bgp_show_type_community_all;
12866 }
12867
12868 if (argv_find(argv, argc, "community-list", &idx)) {
12869 const char *clist_number_or_name = argv[++idx]->arg;
12870 struct community_list *list;
12871
12872 if (argv_find(argv, argc, "exact-match", &idx))
12873 exact_match = 1;
12874
12875 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12876 COMMUNITY_LIST_MASTER);
12877 if (list == NULL) {
12878 vty_out(vty, "%% %s community-list not found\n",
12879 clist_number_or_name);
12880 return CMD_WARNING;
12881 }
12882
12883 if (exact_match)
12884 sh_type = bgp_show_type_community_list_exact;
12885 else
12886 sh_type = bgp_show_type_community_list;
12887 output_arg = list;
12888 }
12889
12890 if (argv_find(argv, argc, "filter-list", &idx)) {
12891 const char *filter = argv[++idx]->arg;
12892 struct as_list *as_list;
12893
12894 as_list = as_list_lookup(filter);
12895 if (as_list == NULL) {
12896 vty_out(vty, "%% %s AS-path access-list not found\n",
12897 filter);
12898 return CMD_WARNING;
12899 }
12900
12901 sh_type = bgp_show_type_filter_list;
12902 output_arg = as_list;
12903 }
12904
12905 if (argv_find(argv, argc, "prefix-list", &idx)) {
12906 const char *prefix_list_str = argv[++idx]->arg;
12907 struct prefix_list *plist;
12908
12909 plist = prefix_list_lookup(afi, prefix_list_str);
12910 if (plist == NULL) {
12911 vty_out(vty, "%% %s prefix-list not found\n",
12912 prefix_list_str);
12913 return CMD_WARNING;
12914 }
12915
12916 sh_type = bgp_show_type_prefix_list;
12917 output_arg = plist;
12918 }
12919
12920 if (argv_find(argv, argc, "access-list", &idx)) {
12921 const char *access_list_str = argv[++idx]->arg;
12922 struct access_list *alist;
12923
12924 alist = access_list_lookup(afi, access_list_str);
12925 if (!alist) {
12926 vty_out(vty, "%% %s access-list not found\n",
12927 access_list_str);
12928 return CMD_WARNING;
12929 }
12930
12931 sh_type = bgp_show_type_access_list;
12932 output_arg = alist;
12933 }
12934
12935 if (argv_find(argv, argc, "route-map", &idx)) {
12936 const char *rmap_str = argv[++idx]->arg;
12937 struct route_map *rmap;
12938
12939 rmap = route_map_lookup_by_name(rmap_str);
12940 if (!rmap) {
12941 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12942 return CMD_WARNING;
12943 }
12944
12945 sh_type = bgp_show_type_route_map;
12946 output_arg = rmap;
12947 }
12948
12949 if (argv_find(argv, argc, "rpki", &idx)) {
12950 sh_type = bgp_show_type_rpki;
12951 if (argv_find(argv, argc, "valid", &idx))
12952 rpki_target_state = RPKI_VALID;
12953 else if (argv_find(argv, argc, "invalid", &idx))
12954 rpki_target_state = RPKI_INVALID;
12955 }
12956
12957 /* Display prefixes with matching version numbers */
12958 if (argv_find(argv, argc, "version", &idx)) {
12959 sh_type = bgp_show_type_prefix_version;
12960 output_arg = argv[idx + 1]->arg;
12961 }
12962
12963 /* Display prefixes with matching BGP community alias */
12964 if (argv_find(argv, argc, "alias", &idx)) {
12965 sh_type = bgp_show_type_community_alias;
12966 output_arg = argv[idx + 1]->arg;
12967 }
12968
12969 /* prefix-longer */
12970 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12971 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12972 const char *prefix_str = argv[idx]->arg;
12973
12974 if (!str2prefix(prefix_str, &p)) {
12975 vty_out(vty, "%% Malformed Prefix\n");
12976 return CMD_WARNING;
12977 }
12978
12979 sh_type = bgp_show_type_prefix_longer;
12980 output_arg = &p;
12981 }
12982
12983 /* self originated only */
12984 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12985 sh_type = bgp_show_type_self_originated;
12986
12987 if (!all) {
12988 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12989 if (community)
12990 return bgp_show_community(vty, bgp, community,
12991 exact_match, afi, safi,
12992 show_flags);
12993 else
12994 return bgp_show(vty, bgp, afi, safi, sh_type,
12995 output_arg, show_flags,
12996 rpki_target_state);
12997 } else {
12998 struct listnode *node;
12999 struct bgp *abgp;
13000 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
13001 * AFI_IP6 */
13002
13003 if (uj)
13004 vty_out(vty, "{\n");
13005
13006 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13007 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
13008 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13009 ? AFI_IP
13010 : AFI_IP6;
13011 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13012 FOREACH_SAFI (safi) {
13013 if (!bgp_afi_safi_peer_exists(abgp, afi,
13014 safi))
13015 continue;
13016
13017 if (uj) {
13018 if (first)
13019 first = false;
13020 else
13021 vty_out(vty, ",\n");
13022 vty_out(vty, "\"%s\":{\n",
13023 get_afi_safi_str(afi,
13024 safi,
13025 true));
13026 } else
13027 vty_out(vty,
13028 "\nFor address family: %s\n",
13029 get_afi_safi_str(
13030 afi, safi,
13031 false));
13032
13033 if (community)
13034 bgp_show_community(
13035 vty, abgp, community,
13036 exact_match, afi, safi,
13037 show_flags);
13038 else
13039 bgp_show(vty, abgp, afi, safi,
13040 sh_type, output_arg,
13041 show_flags,
13042 rpki_target_state);
13043 if (uj)
13044 vty_out(vty, "}\n");
13045 }
13046 }
13047 } else {
13048 /* show <ip> bgp all: for each AFI and SAFI*/
13049 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13050 FOREACH_AFI_SAFI (afi, safi) {
13051 if (!bgp_afi_safi_peer_exists(abgp, afi,
13052 safi))
13053 continue;
13054
13055 if (uj) {
13056 if (first)
13057 first = false;
13058 else
13059 vty_out(vty, ",\n");
13060
13061 vty_out(vty, "\"%s\":{\n",
13062 get_afi_safi_str(afi,
13063 safi,
13064 true));
13065 } else
13066 vty_out(vty,
13067 "\nFor address family: %s\n",
13068 get_afi_safi_str(
13069 afi, safi,
13070 false));
13071
13072 if (community)
13073 bgp_show_community(
13074 vty, abgp, community,
13075 exact_match, afi, safi,
13076 show_flags);
13077 else
13078 bgp_show(vty, abgp, afi, safi,
13079 sh_type, output_arg,
13080 show_flags,
13081 rpki_target_state);
13082 if (uj)
13083 vty_out(vty, "}\n");
13084 }
13085 }
13086 }
13087 if (uj)
13088 vty_out(vty, "}\n");
13089 }
13090 return CMD_SUCCESS;
13091 }
13092
13093 DEFUN (show_ip_bgp_route,
13094 show_ip_bgp_route_cmd,
13095 "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]",
13096 SHOW_STR
13097 IP_STR
13098 BGP_STR
13099 BGP_INSTANCE_HELP_STR
13100 BGP_AFI_HELP_STR
13101 BGP_SAFI_WITH_LABEL_HELP_STR
13102 "Network in the BGP routing table to display\n"
13103 "IPv4 prefix\n"
13104 "Network in the BGP routing table to display\n"
13105 "IPv6 prefix\n"
13106 "Display only the bestpath\n"
13107 "Display only multipaths\n"
13108 "Display only paths that match the specified rpki state\n"
13109 "A valid path as determined by rpki\n"
13110 "A invalid path as determined by rpki\n"
13111 "A path that has no rpki data\n"
13112 JSON_STR)
13113 {
13114 int prefix_check = 0;
13115
13116 afi_t afi = AFI_IP6;
13117 safi_t safi = SAFI_UNICAST;
13118 char *prefix = NULL;
13119 struct bgp *bgp = NULL;
13120 enum bgp_path_type path_type;
13121 bool uj = use_json(argc, argv);
13122
13123 int idx = 0;
13124
13125 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13126 &bgp, uj);
13127 if (!idx)
13128 return CMD_WARNING;
13129
13130 if (!bgp) {
13131 vty_out(vty,
13132 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13133 return CMD_WARNING;
13134 }
13135
13136 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13137 if (argv_find(argv, argc, "A.B.C.D", &idx)
13138 || argv_find(argv, argc, "X:X::X:X", &idx))
13139 prefix_check = 0;
13140 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13141 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13142 prefix_check = 1;
13143
13144 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13145 && afi != AFI_IP6) {
13146 vty_out(vty,
13147 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13148 return CMD_WARNING;
13149 }
13150 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13151 && afi != AFI_IP) {
13152 vty_out(vty,
13153 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13154 return CMD_WARNING;
13155 }
13156
13157 prefix = argv[idx]->arg;
13158
13159 /* [<bestpath|multipath>] */
13160 if (argv_find(argv, argc, "bestpath", &idx))
13161 path_type = BGP_PATH_SHOW_BESTPATH;
13162 else if (argv_find(argv, argc, "multipath", &idx))
13163 path_type = BGP_PATH_SHOW_MULTIPATH;
13164 else
13165 path_type = BGP_PATH_SHOW_ALL;
13166
13167 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13168 path_type, RPKI_NOT_BEING_USED, uj);
13169 }
13170
13171 DEFUN (show_ip_bgp_regexp,
13172 show_ip_bgp_regexp_cmd,
13173 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13174 SHOW_STR
13175 IP_STR
13176 BGP_STR
13177 BGP_INSTANCE_HELP_STR
13178 BGP_AFI_HELP_STR
13179 BGP_SAFI_WITH_LABEL_HELP_STR
13180 "Display routes matching the AS path regular expression\n"
13181 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13182 JSON_STR)
13183 {
13184 afi_t afi = AFI_IP6;
13185 safi_t safi = SAFI_UNICAST;
13186 struct bgp *bgp = NULL;
13187 bool uj = use_json(argc, argv);
13188 char *regstr = NULL;
13189
13190 int idx = 0;
13191 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13192 &bgp, false);
13193 if (!idx)
13194 return CMD_WARNING;
13195
13196 // get index of regex
13197 if (argv_find(argv, argc, "REGEX", &idx))
13198 regstr = argv[idx]->arg;
13199
13200 assert(regstr);
13201 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13202 bgp_show_type_regexp, uj);
13203 }
13204
13205 DEFPY (show_ip_bgp_instance_all,
13206 show_ip_bgp_instance_all_cmd,
13207 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13208 SHOW_STR
13209 IP_STR
13210 BGP_STR
13211 BGP_INSTANCE_ALL_HELP_STR
13212 BGP_AFI_HELP_STR
13213 BGP_SAFI_WITH_LABEL_HELP_STR
13214 JSON_STR
13215 "Increase table width for longer prefixes\n")
13216 {
13217 afi_t afi = AFI_IP6;
13218 safi_t safi = SAFI_UNICAST;
13219 struct bgp *bgp = NULL;
13220 int idx = 0;
13221 uint16_t show_flags = 0;
13222
13223 if (uj) {
13224 argc--;
13225 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13226 }
13227
13228 if (wide)
13229 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13230
13231 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13232 &bgp, uj);
13233 if (!idx)
13234 return CMD_WARNING;
13235
13236 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13237 return CMD_SUCCESS;
13238 }
13239
13240 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13241 afi_t afi, safi_t safi, enum bgp_show_type type,
13242 bool use_json)
13243 {
13244 regex_t *regex;
13245 int rc;
13246 uint16_t show_flags = 0;
13247
13248 if (use_json)
13249 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13250
13251 if (!config_bgp_aspath_validate(regstr)) {
13252 vty_out(vty, "Invalid character in REGEX %s\n",
13253 regstr);
13254 return CMD_WARNING_CONFIG_FAILED;
13255 }
13256
13257 regex = bgp_regcomp(regstr);
13258 if (!regex) {
13259 vty_out(vty, "Can't compile regexp %s\n", regstr);
13260 return CMD_WARNING;
13261 }
13262
13263 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13264 RPKI_NOT_BEING_USED);
13265 bgp_regex_free(regex);
13266 return rc;
13267 }
13268
13269 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13270 const char *comstr, int exact, afi_t afi,
13271 safi_t safi, uint16_t show_flags)
13272 {
13273 struct community *com;
13274 int ret = 0;
13275
13276 com = community_str2com(comstr);
13277 if (!com) {
13278 vty_out(vty, "%% Community malformed: %s\n", comstr);
13279 return CMD_WARNING;
13280 }
13281
13282 ret = bgp_show(vty, bgp, afi, safi,
13283 (exact ? bgp_show_type_community_exact
13284 : bgp_show_type_community),
13285 com, show_flags, RPKI_NOT_BEING_USED);
13286 community_free(&com);
13287
13288 return ret;
13289 }
13290
13291 enum bgp_stats {
13292 BGP_STATS_MAXBITLEN = 0,
13293 BGP_STATS_RIB,
13294 BGP_STATS_PREFIXES,
13295 BGP_STATS_TOTPLEN,
13296 BGP_STATS_UNAGGREGATEABLE,
13297 BGP_STATS_MAX_AGGREGATEABLE,
13298 BGP_STATS_AGGREGATES,
13299 BGP_STATS_SPACE,
13300 BGP_STATS_ASPATH_COUNT,
13301 BGP_STATS_ASPATH_MAXHOPS,
13302 BGP_STATS_ASPATH_TOTHOPS,
13303 BGP_STATS_ASPATH_MAXSIZE,
13304 BGP_STATS_ASPATH_TOTSIZE,
13305 BGP_STATS_ASN_HIGHEST,
13306 BGP_STATS_MAX,
13307 };
13308
13309 #define TABLE_STATS_IDX_VTY 0
13310 #define TABLE_STATS_IDX_JSON 1
13311
13312 static const char *table_stats_strs[][2] = {
13313 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13314 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13315 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13316 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13317 "unaggregateablePrefixes"},
13318 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13319 "maximumAggregateablePrefixes"},
13320 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13321 "bgpAggregateAdvertisements"},
13322 [BGP_STATS_SPACE] = {"Address space advertised",
13323 "addressSpaceAdvertised"},
13324 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13325 "advertisementsWithPaths"},
13326 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13327 "longestAsPath"},
13328 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13329 "largestAsPath"},
13330 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13331 "averageAsPathLengthHops"},
13332 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13333 "averageAsPathSizeBytes"},
13334 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13335 [BGP_STATS_MAX] = {NULL, NULL}
13336 };
13337
13338 struct bgp_table_stats {
13339 struct bgp_table *table;
13340 unsigned long long counts[BGP_STATS_MAX];
13341
13342 unsigned long long
13343 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13344 1];
13345
13346 double total_space;
13347 };
13348
13349 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13350 struct bgp_table_stats *ts, unsigned int space)
13351 {
13352 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13353 struct bgp_path_info *pi;
13354 const struct prefix *rn_p;
13355
13356 if (!bgp_dest_has_bgp_path_info_data(dest))
13357 return;
13358
13359 rn_p = bgp_dest_get_prefix(dest);
13360 ts->counts[BGP_STATS_PREFIXES]++;
13361 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13362
13363 ts->prefix_len_count[rn_p->prefixlen]++;
13364 /* check if the prefix is included by any other announcements */
13365 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13366 pdest = bgp_dest_parent_nolock(pdest);
13367
13368 if (pdest == NULL || pdest == top) {
13369 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13370 /* announced address space */
13371 if (space)
13372 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13373 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13374 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13375
13376
13377 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13378 ts->counts[BGP_STATS_RIB]++;
13379
13380 if (CHECK_FLAG(pi->attr->flag,
13381 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13382 ts->counts[BGP_STATS_AGGREGATES]++;
13383
13384 /* as-path stats */
13385 if (pi->attr->aspath) {
13386 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13387 unsigned int size = aspath_size(pi->attr->aspath);
13388 as_t highest = aspath_highest(pi->attr->aspath);
13389
13390 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13391
13392 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13393 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13394
13395 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13396 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13397
13398 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13399 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13400 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13401 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13402 }
13403 }
13404 }
13405
13406 static void bgp_table_stats_walker(struct event *t)
13407 {
13408 struct bgp_dest *dest, *ndest;
13409 struct bgp_dest *top;
13410 struct bgp_table_stats *ts = EVENT_ARG(t);
13411 unsigned int space = 0;
13412
13413 if (!(top = bgp_table_top(ts->table)))
13414 return;
13415
13416 switch (ts->table->afi) {
13417 case AFI_IP:
13418 space = IPV4_MAX_BITLEN;
13419 break;
13420 case AFI_IP6:
13421 space = IPV6_MAX_BITLEN;
13422 break;
13423 case AFI_L2VPN:
13424 space = EVPN_ROUTE_PREFIXLEN;
13425 break;
13426 case AFI_UNSPEC:
13427 case AFI_MAX:
13428 return;
13429 }
13430
13431 ts->counts[BGP_STATS_MAXBITLEN] = space;
13432
13433 for (dest = top; dest; dest = bgp_route_next(dest)) {
13434 if (ts->table->safi == SAFI_MPLS_VPN
13435 || ts->table->safi == SAFI_ENCAP
13436 || ts->table->safi == SAFI_EVPN) {
13437 struct bgp_table *table;
13438
13439 table = bgp_dest_get_bgp_table_info(dest);
13440 if (!table)
13441 continue;
13442
13443 top = bgp_table_top(table);
13444 for (ndest = bgp_table_top(table); ndest;
13445 ndest = bgp_route_next(ndest))
13446 bgp_table_stats_rn(ndest, top, ts, space);
13447 } else {
13448 bgp_table_stats_rn(dest, top, ts, space);
13449 }
13450 }
13451 }
13452
13453 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13454 struct json_object *json_array)
13455 {
13456 struct listnode *node, *nnode;
13457 struct bgp *bgp;
13458
13459 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13460 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13461 }
13462
13463 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13464 safi_t safi, struct json_object *json_array)
13465 {
13466 struct bgp_table_stats ts;
13467 unsigned int i;
13468 int ret = CMD_SUCCESS;
13469 char temp_buf[20];
13470 struct json_object *json = NULL;
13471 uint32_t bitlen = 0;
13472 struct json_object *json_bitlen;
13473
13474 if (json_array)
13475 json = json_object_new_object();
13476
13477 if (!bgp->rib[afi][safi]) {
13478 char warning_msg[50];
13479
13480 snprintf(warning_msg, sizeof(warning_msg),
13481 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13482 safi);
13483
13484 if (!json)
13485 vty_out(vty, "%s\n", warning_msg);
13486 else
13487 json_object_string_add(json, "warning", warning_msg);
13488
13489 ret = CMD_WARNING;
13490 goto end_table_stats;
13491 }
13492
13493 if (!json)
13494 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13495 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13496 else
13497 json_object_string_add(json, "instance", bgp->name_pretty);
13498
13499 /* labeled-unicast routes live in the unicast table */
13500 if (safi == SAFI_LABELED_UNICAST)
13501 safi = SAFI_UNICAST;
13502
13503 memset(&ts, 0, sizeof(ts));
13504 ts.table = bgp->rib[afi][safi];
13505 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13506
13507 for (i = 0; i < BGP_STATS_MAX; i++) {
13508 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13509 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13510 continue;
13511
13512 switch (i) {
13513 case BGP_STATS_ASPATH_TOTHOPS:
13514 case BGP_STATS_ASPATH_TOTSIZE:
13515 if (!json) {
13516 snprintf(
13517 temp_buf, sizeof(temp_buf), "%12.2f",
13518 ts.counts[i]
13519 ? (float)ts.counts[i]
13520 / (float)ts.counts
13521 [BGP_STATS_ASPATH_COUNT]
13522 : 0);
13523 vty_out(vty, "%-30s: %s",
13524 table_stats_strs[i]
13525 [TABLE_STATS_IDX_VTY],
13526 temp_buf);
13527 } else {
13528 json_object_double_add(
13529 json,
13530 table_stats_strs[i]
13531 [TABLE_STATS_IDX_JSON],
13532 ts.counts[i]
13533 ? (double)ts.counts[i]
13534 / (double)ts.counts
13535 [BGP_STATS_ASPATH_COUNT]
13536 : 0);
13537 }
13538 break;
13539 case BGP_STATS_TOTPLEN:
13540 if (!json) {
13541 snprintf(
13542 temp_buf, sizeof(temp_buf), "%12.2f",
13543 ts.counts[i]
13544 ? (float)ts.counts[i]
13545 / (float)ts.counts
13546 [BGP_STATS_PREFIXES]
13547 : 0);
13548 vty_out(vty, "%-30s: %s",
13549 table_stats_strs[i]
13550 [TABLE_STATS_IDX_VTY],
13551 temp_buf);
13552 } else {
13553 json_object_double_add(
13554 json,
13555 table_stats_strs[i]
13556 [TABLE_STATS_IDX_JSON],
13557 ts.counts[i]
13558 ? (double)ts.counts[i]
13559 / (double)ts.counts
13560 [BGP_STATS_PREFIXES]
13561 : 0);
13562 }
13563 break;
13564 case BGP_STATS_SPACE:
13565 if (!json) {
13566 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13567 ts.total_space);
13568 vty_out(vty, "%-30s: %s\n",
13569 table_stats_strs[i]
13570 [TABLE_STATS_IDX_VTY],
13571 temp_buf);
13572 } else {
13573 json_object_double_add(
13574 json,
13575 table_stats_strs[i]
13576 [TABLE_STATS_IDX_JSON],
13577 (double)ts.total_space);
13578 }
13579 if (afi == AFI_IP6) {
13580 if (!json) {
13581 snprintf(temp_buf, sizeof(temp_buf),
13582 "%12g",
13583 ts.total_space
13584 * pow(2.0, -128 + 32));
13585 vty_out(vty, "%30s: %s\n",
13586 "/32 equivalent %s\n",
13587 temp_buf);
13588 } else {
13589 json_object_double_add(
13590 json, "/32equivalent",
13591 (double)(ts.total_space
13592 * pow(2.0,
13593 -128 + 32)));
13594 }
13595 if (!json) {
13596 snprintf(temp_buf, sizeof(temp_buf),
13597 "%12g",
13598 ts.total_space
13599 * pow(2.0, -128 + 48));
13600 vty_out(vty, "%30s: %s\n",
13601 "/48 equivalent %s\n",
13602 temp_buf);
13603 } else {
13604 json_object_double_add(
13605 json, "/48equivalent",
13606 (double)(ts.total_space
13607 * pow(2.0,
13608 -128 + 48)));
13609 }
13610 } else {
13611 if (!json) {
13612 snprintf(temp_buf, sizeof(temp_buf),
13613 "%12.2f",
13614 ts.total_space * 100.
13615 * pow(2.0, -32));
13616 vty_out(vty, "%30s: %s\n",
13617 "% announced ", temp_buf);
13618 } else {
13619 json_object_double_add(
13620 json, "%announced",
13621 (double)(ts.total_space * 100.
13622 * pow(2.0, -32)));
13623 }
13624 if (!json) {
13625 snprintf(temp_buf, sizeof(temp_buf),
13626 "%12.2f",
13627 ts.total_space
13628 * pow(2.0, -32 + 8));
13629 vty_out(vty, "%30s: %s\n",
13630 "/8 equivalent ", temp_buf);
13631 } else {
13632 json_object_double_add(
13633 json, "/8equivalent",
13634 (double)(ts.total_space
13635 * pow(2.0, -32 + 8)));
13636 }
13637 if (!json) {
13638 snprintf(temp_buf, sizeof(temp_buf),
13639 "%12.2f",
13640 ts.total_space
13641 * pow(2.0, -32 + 24));
13642 vty_out(vty, "%30s: %s\n",
13643 "/24 equivalent ", temp_buf);
13644 } else {
13645 json_object_double_add(
13646 json, "/24equivalent",
13647 (double)(ts.total_space
13648 * pow(2.0, -32 + 24)));
13649 }
13650 }
13651 break;
13652 default:
13653 if (!json) {
13654 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13655 ts.counts[i]);
13656 vty_out(vty, "%-30s: %s",
13657 table_stats_strs[i]
13658 [TABLE_STATS_IDX_VTY],
13659 temp_buf);
13660 } else {
13661 json_object_int_add(
13662 json,
13663 table_stats_strs[i]
13664 [TABLE_STATS_IDX_JSON],
13665 ts.counts[i]);
13666 }
13667 }
13668 if (!json)
13669 vty_out(vty, "\n");
13670 }
13671
13672 switch (afi) {
13673 case AFI_IP:
13674 bitlen = IPV4_MAX_BITLEN;
13675 break;
13676 case AFI_IP6:
13677 bitlen = IPV6_MAX_BITLEN;
13678 break;
13679 case AFI_L2VPN:
13680 bitlen = EVPN_ROUTE_PREFIXLEN;
13681 break;
13682 case AFI_UNSPEC:
13683 case AFI_MAX:
13684 break;
13685 }
13686
13687 if (json) {
13688 json_bitlen = json_object_new_array();
13689
13690 for (i = 0; i <= bitlen; i++) {
13691 struct json_object *ind_bit = json_object_new_object();
13692
13693 if (!ts.prefix_len_count[i])
13694 continue;
13695
13696 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13697 json_object_int_add(ind_bit, temp_buf,
13698 ts.prefix_len_count[i]);
13699 json_object_array_add(json_bitlen, ind_bit);
13700 }
13701 json_object_object_add(json, "prefixLength", json_bitlen);
13702 }
13703
13704 end_table_stats:
13705 if (json)
13706 json_object_array_add(json_array, json);
13707 return ret;
13708 }
13709
13710 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13711 safi_t safi, struct json_object *json_array)
13712 {
13713 if (!bgp) {
13714 bgp_table_stats_all(vty, afi, safi, json_array);
13715 return CMD_SUCCESS;
13716 }
13717
13718 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13719 }
13720
13721 enum bgp_pcounts {
13722 PCOUNT_ADJ_IN = 0,
13723 PCOUNT_DAMPED,
13724 PCOUNT_REMOVED,
13725 PCOUNT_HISTORY,
13726 PCOUNT_STALE,
13727 PCOUNT_VALID,
13728 PCOUNT_ALL,
13729 PCOUNT_COUNTED,
13730 PCOUNT_BPATH_SELECTED,
13731 PCOUNT_PFCNT, /* the figure we display to users */
13732 PCOUNT_MAX,
13733 };
13734
13735 static const char *const pcount_strs[] = {
13736 [PCOUNT_ADJ_IN] = "Adj-in",
13737 [PCOUNT_DAMPED] = "Damped",
13738 [PCOUNT_REMOVED] = "Removed",
13739 [PCOUNT_HISTORY] = "History",
13740 [PCOUNT_STALE] = "Stale",
13741 [PCOUNT_VALID] = "Valid",
13742 [PCOUNT_ALL] = "All RIB",
13743 [PCOUNT_COUNTED] = "PfxCt counted",
13744 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13745 [PCOUNT_PFCNT] = "Useable",
13746 [PCOUNT_MAX] = NULL,
13747 };
13748
13749 struct peer_pcounts {
13750 unsigned int count[PCOUNT_MAX];
13751 const struct peer *peer;
13752 const struct bgp_table *table;
13753 safi_t safi;
13754 };
13755
13756 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13757 {
13758 const struct bgp_adj_in *ain;
13759 const struct bgp_path_info *pi;
13760 const struct peer *peer = pc->peer;
13761
13762 for (ain = rn->adj_in; ain; ain = ain->next)
13763 if (ain->peer == peer)
13764 pc->count[PCOUNT_ADJ_IN]++;
13765
13766 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13767
13768 if (pi->peer != peer)
13769 continue;
13770
13771 pc->count[PCOUNT_ALL]++;
13772
13773 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13774 pc->count[PCOUNT_DAMPED]++;
13775 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13776 pc->count[PCOUNT_HISTORY]++;
13777 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13778 pc->count[PCOUNT_REMOVED]++;
13779 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13780 pc->count[PCOUNT_STALE]++;
13781 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13782 pc->count[PCOUNT_VALID]++;
13783 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13784 pc->count[PCOUNT_PFCNT]++;
13785 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13786 pc->count[PCOUNT_BPATH_SELECTED]++;
13787
13788 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13789 pc->count[PCOUNT_COUNTED]++;
13790 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13791 flog_err(
13792 EC_LIB_DEVELOPMENT,
13793 "Attempting to count but flags say it is unusable");
13794 } else {
13795 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13796 flog_err(
13797 EC_LIB_DEVELOPMENT,
13798 "Not counted but flags say we should");
13799 }
13800 }
13801 }
13802
13803 static void bgp_peer_count_walker(struct event *t)
13804 {
13805 struct bgp_dest *rn, *rm;
13806 const struct bgp_table *table;
13807 struct peer_pcounts *pc = EVENT_ARG(t);
13808
13809 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13810 || pc->safi == SAFI_EVPN) {
13811 /* Special handling for 2-level routing tables. */
13812 for (rn = bgp_table_top(pc->table); rn;
13813 rn = bgp_route_next(rn)) {
13814 table = bgp_dest_get_bgp_table_info(rn);
13815 if (table != NULL)
13816 for (rm = bgp_table_top(table); rm;
13817 rm = bgp_route_next(rm))
13818 bgp_peer_count_proc(rm, pc);
13819 }
13820 } else
13821 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13822 bgp_peer_count_proc(rn, pc);
13823 }
13824
13825 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13826 safi_t safi, bool use_json)
13827 {
13828 struct peer_pcounts pcounts = {.peer = peer};
13829 unsigned int i;
13830 json_object *json = NULL;
13831 json_object *json_loop = NULL;
13832
13833 if (use_json) {
13834 json = json_object_new_object();
13835 json_loop = json_object_new_object();
13836 }
13837
13838 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13839 || !peer->bgp->rib[afi][safi]) {
13840 if (use_json) {
13841 json_object_string_add(
13842 json, "warning",
13843 "No such neighbor or address family");
13844 vty_out(vty, "%s\n", json_object_to_json_string(json));
13845 json_object_free(json);
13846 json_object_free(json_loop);
13847 } else
13848 vty_out(vty, "%% No such neighbor or address family\n");
13849
13850 return CMD_WARNING;
13851 }
13852
13853 memset(&pcounts, 0, sizeof(pcounts));
13854 pcounts.peer = peer;
13855 pcounts.table = peer->bgp->rib[afi][safi];
13856 pcounts.safi = safi;
13857
13858 /* in-place call via thread subsystem so as to record execution time
13859 * stats for the thread-walk (i.e. ensure this can't be blamed on
13860 * on just vty_read()).
13861 */
13862 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13863
13864 if (use_json) {
13865 json_object_string_add(json, "prefixCountsFor", peer->host);
13866 json_object_string_add(json, "multiProtocol",
13867 get_afi_safi_str(afi, safi, true));
13868 json_object_int_add(json, "pfxCounter",
13869 peer->pcount[afi][safi]);
13870
13871 for (i = 0; i < PCOUNT_MAX; i++)
13872 json_object_int_add(json_loop, pcount_strs[i],
13873 pcounts.count[i]);
13874
13875 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13876
13877 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13878 json_object_string_add(json, "pfxctDriftFor",
13879 peer->host);
13880 json_object_string_add(
13881 json, "recommended",
13882 "Please report this bug, with the above command output");
13883 }
13884 vty_json(vty, json);
13885 } else {
13886
13887 if (peer->hostname
13888 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13889 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13890 peer->hostname, peer->host,
13891 get_afi_safi_str(afi, safi, false));
13892 } else {
13893 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13894 get_afi_safi_str(afi, safi, false));
13895 }
13896
13897 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13898 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13899
13900 for (i = 0; i < PCOUNT_MAX; i++)
13901 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13902 pcounts.count[i]);
13903
13904 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13905 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13906 vty_out(vty,
13907 "Please report this bug, with the above command output\n");
13908 }
13909 }
13910
13911 return CMD_SUCCESS;
13912 }
13913
13914 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13915 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13916 "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]",
13917 SHOW_STR
13918 IP_STR
13919 BGP_STR
13920 BGP_INSTANCE_HELP_STR
13921 BGP_AFI_HELP_STR
13922 BGP_SAFI_HELP_STR
13923 "Detailed information on TCP and BGP neighbor connections\n"
13924 "Neighbor to display information about\n"
13925 "Neighbor to display information about\n"
13926 "Neighbor on BGP configured interface\n"
13927 "Display detailed prefix count information\n"
13928 JSON_STR)
13929 {
13930 afi_t afi = AFI_IP6;
13931 safi_t safi = SAFI_UNICAST;
13932 struct peer *peer;
13933 int idx = 0;
13934 struct bgp *bgp = NULL;
13935 bool uj = use_json(argc, argv);
13936
13937 if (uj)
13938 argc--;
13939
13940 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13941 &bgp, uj);
13942 if (!idx)
13943 return CMD_WARNING;
13944
13945 argv_find(argv, argc, "neighbors", &idx);
13946 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13947 if (!peer)
13948 return CMD_WARNING;
13949
13950 return bgp_peer_counts(vty, peer, afi, safi, uj);
13951 }
13952
13953 #ifdef KEEP_OLD_VPN_COMMANDS
13954 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13955 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13956 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13957 SHOW_STR
13958 IP_STR
13959 BGP_STR
13960 BGP_VPNVX_HELP_STR
13961 "Display information about all VPNv4 NLRIs\n"
13962 "Detailed information on TCP and BGP neighbor connections\n"
13963 "Neighbor to display information about\n"
13964 "Neighbor to display information about\n"
13965 "Neighbor on BGP configured interface\n"
13966 "Display detailed prefix count information\n"
13967 JSON_STR)
13968 {
13969 int idx_peer = 6;
13970 struct peer *peer;
13971 bool uj = use_json(argc, argv);
13972
13973 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13974 if (!peer)
13975 return CMD_WARNING;
13976
13977 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13978 }
13979
13980 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13981 show_ip_bgp_vpn_all_route_prefix_cmd,
13982 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13983 SHOW_STR
13984 IP_STR
13985 BGP_STR
13986 BGP_VPNVX_HELP_STR
13987 "Display information about all VPNv4 NLRIs\n"
13988 "Network in the BGP routing table to display\n"
13989 "Network in the BGP routing table to display\n"
13990 JSON_STR)
13991 {
13992 int idx = 0;
13993 char *network = NULL;
13994 struct bgp *bgp = bgp_get_default();
13995 if (!bgp) {
13996 vty_out(vty, "Can't find default instance\n");
13997 return CMD_WARNING;
13998 }
13999
14000 if (argv_find(argv, argc, "A.B.C.D", &idx))
14001 network = argv[idx]->arg;
14002 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
14003 network = argv[idx]->arg;
14004 else {
14005 vty_out(vty, "Unable to figure out Network\n");
14006 return CMD_WARNING;
14007 }
14008
14009 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
14010 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14011 use_json(argc, argv));
14012 }
14013 #endif /* KEEP_OLD_VPN_COMMANDS */
14014
14015 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
14016 show_bgp_l2vpn_evpn_route_prefix_cmd,
14017 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
14018 SHOW_STR
14019 BGP_STR
14020 L2VPN_HELP_STR
14021 EVPN_HELP_STR
14022 "Network in the BGP routing table to display\n"
14023 "Network in the BGP routing table to display\n"
14024 "Network in the BGP routing table to display\n"
14025 "Network in the BGP routing table to display\n"
14026 JSON_STR)
14027 {
14028 int idx = 0;
14029 char *network = NULL;
14030 int prefix_check = 0;
14031
14032 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
14033 argv_find(argv, argc, "X:X::X:X", &idx))
14034 network = argv[idx]->arg;
14035 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
14036 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
14037 network = argv[idx]->arg;
14038 prefix_check = 1;
14039 } else {
14040 vty_out(vty, "Unable to figure out Network\n");
14041 return CMD_WARNING;
14042 }
14043 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
14044 prefix_check, BGP_PATH_SHOW_ALL,
14045 RPKI_NOT_BEING_USED, use_json(argc, argv));
14046 }
14047
14048 static void show_adj_route_header(struct vty *vty, struct peer *peer,
14049 struct bgp_table *table, int *header1,
14050 int *header2, json_object *json,
14051 json_object *json_scode,
14052 json_object *json_ocode, bool wide,
14053 bool detail)
14054 {
14055 uint64_t version = table ? table->version : 0;
14056
14057 if (*header1) {
14058 if (json) {
14059 json_object_int_add(json, "bgpTableVersion", version);
14060 json_object_string_addf(json, "bgpLocalRouterId",
14061 "%pI4", &peer->bgp->router_id);
14062 json_object_int_add(json, "defaultLocPrf",
14063 peer->bgp->default_local_pref);
14064 json_object_int_add(json, "localAS",
14065 peer->change_local_as
14066 ? peer->change_local_as
14067 : peer->local_as);
14068 json_object_object_add(json, "bgpStatusCodes",
14069 json_scode);
14070 json_object_object_add(json, "bgpOriginCodes",
14071 json_ocode);
14072 } else {
14073 vty_out(vty,
14074 "BGP table version is %" PRIu64
14075 ", local router ID is %pI4, vrf id ",
14076 version, &peer->bgp->router_id);
14077 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14078 vty_out(vty, "%s", VRFID_NONE_STR);
14079 else
14080 vty_out(vty, "%u", peer->bgp->vrf_id);
14081 vty_out(vty, "\n");
14082 vty_out(vty, "Default local pref %u, ",
14083 peer->bgp->default_local_pref);
14084 vty_out(vty, "local AS %u\n",
14085 peer->change_local_as ? peer->change_local_as
14086 : peer->local_as);
14087 if (!detail) {
14088 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14089 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14090 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14091 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14092 }
14093 }
14094 *header1 = 0;
14095 }
14096 if (*header2) {
14097 if (!json && !detail)
14098 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14099 : BGP_SHOW_HEADER));
14100 *header2 = 0;
14101 }
14102 }
14103
14104 static void
14105 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14106 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14107 const char *rmap_name, json_object *json, json_object *json_ar,
14108 json_object *json_scode, json_object *json_ocode,
14109 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14110 const struct prefix *match, unsigned long *output_count,
14111 unsigned long *filtered_count)
14112 {
14113 struct bgp_adj_in *ain = NULL;
14114 struct bgp_adj_out *adj = NULL;
14115 struct bgp_dest *dest;
14116 struct bgp *bgp;
14117 struct attr attr;
14118 int ret;
14119 struct update_subgroup *subgrp;
14120 struct peer_af *paf = NULL;
14121 bool route_filtered;
14122 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14123 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14124 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14125 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14126 || (safi == SAFI_EVPN))
14127 ? true
14128 : false;
14129 int display = 0;
14130 json_object *json_net = NULL;
14131
14132 bgp = peer->bgp;
14133
14134 /* If the user supplied a prefix, look for a matching route instead
14135 * of walking the whole table.
14136 */
14137 if (match) {
14138 dest = bgp_node_match(table, match);
14139 if (!dest) {
14140 if (!use_json)
14141 vty_out(vty, "Network not in table\n");
14142 return;
14143 }
14144
14145 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14146
14147 if (rn_p->prefixlen != match->prefixlen) {
14148 if (!use_json)
14149 vty_out(vty, "Network not in table\n");
14150 bgp_dest_unlock_node(dest);
14151 return;
14152 }
14153
14154 if (type == bgp_show_adj_route_received ||
14155 type == bgp_show_adj_route_filtered) {
14156 for (ain = dest->adj_in; ain; ain = ain->next) {
14157 if (ain->peer == peer) {
14158 attr = *ain->attr;
14159 break;
14160 }
14161 }
14162 /* bail out if if adj_out is empty, or
14163 * if the prefix isn't in this peer's
14164 * adj_in
14165 */
14166 if (!ain || ain->peer != peer) {
14167 if (!use_json)
14168 vty_out(vty, "Network not in table\n");
14169 bgp_dest_unlock_node(dest);
14170 return;
14171 }
14172 } else if (type == bgp_show_adj_route_advertised) {
14173 bool peer_found = false;
14174
14175 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14176 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14177 if (paf->peer == peer && adj->attr) {
14178 attr = *adj->attr;
14179 peer_found = true;
14180 break;
14181 }
14182 }
14183 if (peer_found)
14184 break;
14185 }
14186 /* bail out if if adj_out is empty, or
14187 * if the prefix isn't in this peer's
14188 * adj_out
14189 */
14190 if (!paf || !peer_found) {
14191 if (!use_json)
14192 vty_out(vty, "Network not in table\n");
14193 bgp_dest_unlock_node(dest);
14194 return;
14195 }
14196 }
14197
14198 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14199 rmap_name);
14200
14201 if (ret != RMAP_DENY) {
14202 show_adj_route_header(vty, peer, table, header1,
14203 header2, json, json_scode,
14204 json_ocode, wide, detail);
14205
14206 if (use_json)
14207 json_net = json_object_new_object();
14208
14209 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14210 afi, safi, json_net,
14211 BGP_PATH_SHOW_ALL, &display,
14212 RPKI_NOT_BEING_USED);
14213 if (use_json)
14214 json_object_object_addf(json_ar, json_net,
14215 "%pFX", rn_p);
14216 (*output_count)++;
14217 } else
14218 (*filtered_count)++;
14219
14220 bgp_attr_flush(&attr);
14221 bgp_dest_unlock_node(dest);
14222 return;
14223 }
14224
14225
14226 subgrp = peer_subgroup(peer, afi, safi);
14227
14228 if (type == bgp_show_adj_route_advertised && subgrp
14229 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14230 if (use_json) {
14231 json_object_int_add(json, "bgpTableVersion",
14232 table->version);
14233 json_object_string_addf(json, "bgpLocalRouterId",
14234 "%pI4", &bgp->router_id);
14235 json_object_int_add(json, "defaultLocPrf",
14236 bgp->default_local_pref);
14237 json_object_int_add(json, "localAS",
14238 peer->change_local_as
14239 ? peer->change_local_as
14240 : peer->local_as);
14241 json_object_object_add(json, "bgpStatusCodes",
14242 json_scode);
14243 json_object_object_add(json, "bgpOriginCodes",
14244 json_ocode);
14245 json_object_string_add(
14246 json, "bgpOriginatingDefaultNetwork",
14247 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14248 } else {
14249 vty_out(vty,
14250 "BGP table version is %" PRIu64
14251 ", local router ID is %pI4, vrf id ",
14252 table->version, &bgp->router_id);
14253 if (bgp->vrf_id == VRF_UNKNOWN)
14254 vty_out(vty, "%s", VRFID_NONE_STR);
14255 else
14256 vty_out(vty, "%u", bgp->vrf_id);
14257 vty_out(vty, "\n");
14258 vty_out(vty, "Default local pref %u, ",
14259 bgp->default_local_pref);
14260 vty_out(vty, "local AS %u\n",
14261 peer->change_local_as ? peer->change_local_as
14262 : peer->local_as);
14263 if (!detail) {
14264 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14265 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14266 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14267 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14268 }
14269
14270 vty_out(vty, "Originating default network %s\n\n",
14271 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14272 }
14273 (*output_count)++;
14274 *header1 = 0;
14275 }
14276
14277 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14278 if (type == bgp_show_adj_route_received
14279 || type == bgp_show_adj_route_filtered) {
14280 for (ain = dest->adj_in; ain; ain = ain->next) {
14281 if (ain->peer != peer)
14282 continue;
14283 show_adj_route_header(vty, peer, table, header1,
14284 header2, json, json_scode,
14285 json_ocode, wide, detail);
14286
14287 if ((safi == SAFI_MPLS_VPN)
14288 || (safi == SAFI_ENCAP)
14289 || (safi == SAFI_EVPN)) {
14290 if (use_json)
14291 json_object_string_add(
14292 json_ar, "rd", rd_str);
14293 else if (show_rd && rd_str) {
14294 vty_out(vty,
14295 "Route Distinguisher: %s\n",
14296 rd_str);
14297 show_rd = false;
14298 }
14299 }
14300
14301 attr = *ain->attr;
14302 route_filtered = false;
14303
14304 /* Filter prefix using distribute list,
14305 * filter list or prefix list
14306 */
14307 const struct prefix *rn_p =
14308 bgp_dest_get_prefix(dest);
14309 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14310 safi))
14311 == FILTER_DENY)
14312 route_filtered = true;
14313
14314 /* Filter prefix using route-map */
14315 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14316 safi, rmap_name, NULL,
14317 0, NULL);
14318
14319 if (type == bgp_show_adj_route_filtered &&
14320 !route_filtered && ret != RMAP_DENY) {
14321 bgp_attr_flush(&attr);
14322 continue;
14323 }
14324
14325 if (type == bgp_show_adj_route_received
14326 && (route_filtered || ret == RMAP_DENY))
14327 (*filtered_count)++;
14328
14329 if (detail) {
14330 if (use_json)
14331 json_net =
14332 json_object_new_object();
14333
14334 struct bgp_path_info bpi;
14335 struct bgp_dest buildit = *dest;
14336 struct bgp_dest *pass_in;
14337
14338 if (route_filtered ||
14339 ret == RMAP_DENY) {
14340 bpi.attr = &attr;
14341 bpi.peer = peer;
14342 buildit.info = &bpi;
14343
14344 pass_in = &buildit;
14345 } else
14346 pass_in = dest;
14347 bgp_show_path_info(
14348 NULL, pass_in, vty, bgp, afi,
14349 safi, json_net,
14350 BGP_PATH_SHOW_ALL, &display,
14351 RPKI_NOT_BEING_USED);
14352 if (use_json)
14353 json_object_object_addf(
14354 json_ar, json_net,
14355 "%pFX", rn_p);
14356 } else
14357 route_vty_out_tmp(vty, dest, rn_p,
14358 &attr, safi, use_json,
14359 json_ar, wide);
14360 bgp_attr_flush(&attr);
14361 (*output_count)++;
14362 }
14363 } else if (type == bgp_show_adj_route_advertised) {
14364 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14365 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14366 if (paf->peer != peer || !adj->attr)
14367 continue;
14368
14369 show_adj_route_header(
14370 vty, peer, table, header1,
14371 header2, json, json_scode,
14372 json_ocode, wide, detail);
14373
14374 const struct prefix *rn_p =
14375 bgp_dest_get_prefix(dest);
14376
14377 attr = *adj->attr;
14378 ret = bgp_output_modifier(
14379 peer, rn_p, &attr, afi, safi,
14380 rmap_name);
14381
14382 if (ret != RMAP_DENY) {
14383 if ((safi == SAFI_MPLS_VPN)
14384 || (safi == SAFI_ENCAP)
14385 || (safi == SAFI_EVPN)) {
14386 if (use_json)
14387 json_object_string_add(
14388 json_ar,
14389 "rd",
14390 rd_str);
14391 else if (show_rd
14392 && rd_str) {
14393 vty_out(vty,
14394 "Route Distinguisher: %s\n",
14395 rd_str);
14396 show_rd = false;
14397 }
14398 }
14399 if (detail) {
14400 if (use_json)
14401 json_net =
14402 json_object_new_object();
14403 bgp_show_path_info(
14404 NULL /* prefix_rd
14405 */
14406 ,
14407 dest, vty, bgp,
14408 afi, safi,
14409 json_net,
14410 BGP_PATH_SHOW_ALL,
14411 &display,
14412 RPKI_NOT_BEING_USED);
14413 if (use_json)
14414 json_object_object_addf(
14415 json_ar,
14416 json_net,
14417 "%pFX",
14418 rn_p);
14419 } else
14420 route_vty_out_tmp(
14421 vty, dest, rn_p,
14422 &attr, safi,
14423 use_json,
14424 json_ar, wide);
14425 (*output_count)++;
14426 } else {
14427 (*filtered_count)++;
14428 }
14429
14430 bgp_attr_flush(&attr);
14431 }
14432 } else if (type == bgp_show_adj_route_bestpath) {
14433 struct bgp_path_info *pi;
14434
14435 show_adj_route_header(vty, peer, table, header1,
14436 header2, json, json_scode,
14437 json_ocode, wide, detail);
14438
14439 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14440
14441 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14442 pi = pi->next) {
14443 if (pi->peer != peer)
14444 continue;
14445
14446 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14447 continue;
14448
14449 if (detail) {
14450 if (use_json)
14451 json_net =
14452 json_object_new_object();
14453 bgp_show_path_info(
14454 NULL /* prefix_rd */, dest, vty,
14455 bgp, afi, safi, json_net,
14456 BGP_PATH_SHOW_BESTPATH,
14457 &display, RPKI_NOT_BEING_USED);
14458 if (use_json)
14459 json_object_object_addf(
14460 json_ar, json_net,
14461 "%pFX", rn_p);
14462 } else
14463 route_vty_out_tmp(
14464 vty, dest, rn_p, pi->attr, safi,
14465 use_json, json_ar, wide);
14466 (*output_count)++;
14467 }
14468 }
14469 }
14470 }
14471
14472 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14473 safi_t safi, enum bgp_show_adj_route_type type,
14474 const char *rmap_name, const struct prefix *match,
14475 uint16_t show_flags)
14476 {
14477 struct bgp *bgp;
14478 struct bgp_table *table;
14479 json_object *json = NULL;
14480 json_object *json_scode = NULL;
14481 json_object *json_ocode = NULL;
14482 json_object *json_ar = NULL;
14483 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14484
14485 /* Init BGP headers here so they're only displayed once
14486 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14487 */
14488 int header1 = 1;
14489 int header2 = 1;
14490
14491 /*
14492 * Initialize variables for each RD
14493 * All prefixes under an RD is aggregated within "json_routes"
14494 */
14495 char rd_str[BUFSIZ] = {0};
14496 json_object *json_routes = NULL;
14497
14498
14499 /* For 2-tier tables, prefix counts need to be
14500 * maintained across multiple runs of show_adj_route()
14501 */
14502 unsigned long output_count_per_rd;
14503 unsigned long filtered_count_per_rd;
14504 unsigned long output_count = 0;
14505 unsigned long filtered_count = 0;
14506
14507 if (use_json) {
14508 json = json_object_new_object();
14509 json_ar = json_object_new_object();
14510 json_scode = json_object_new_object();
14511 json_ocode = json_object_new_object();
14512 #if CONFDATE > 20231208
14513 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14514 #endif
14515 json_object_string_add(json_scode, "suppressed", "s");
14516 json_object_string_add(json_scode, "damped", "d");
14517 json_object_string_add(json_scode, "history", "h");
14518 json_object_string_add(json_scode, "valid", "*");
14519 json_object_string_add(json_scode, "best", ">");
14520 json_object_string_add(json_scode, "multipath", "=");
14521 json_object_string_add(json_scode, "internal", "i");
14522 json_object_string_add(json_scode, "ribFailure", "r");
14523 json_object_string_add(json_scode, "stale", "S");
14524 json_object_string_add(json_scode, "removed", "R");
14525
14526 #if CONFDATE > 20231208
14527 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14528 #endif
14529 json_object_string_add(json_ocode, "igp", "i");
14530 json_object_string_add(json_ocode, "egp", "e");
14531 json_object_string_add(json_ocode, "incomplete", "?");
14532 }
14533
14534 if (!peer || !peer->afc[afi][safi]) {
14535 if (use_json) {
14536 json_object_string_add(
14537 json, "warning",
14538 "No such neighbor or address family");
14539 vty_out(vty, "%s\n", json_object_to_json_string(json));
14540 json_object_free(json);
14541 json_object_free(json_ar);
14542 json_object_free(json_scode);
14543 json_object_free(json_ocode);
14544 } else
14545 vty_out(vty, "%% No such neighbor or address family\n");
14546
14547 return CMD_WARNING;
14548 }
14549
14550 if ((type == bgp_show_adj_route_received
14551 || type == bgp_show_adj_route_filtered)
14552 && !CHECK_FLAG(peer->af_flags[afi][safi],
14553 PEER_FLAG_SOFT_RECONFIG)) {
14554 if (use_json) {
14555 json_object_string_add(
14556 json, "warning",
14557 "Inbound soft reconfiguration not enabled");
14558 vty_out(vty, "%s\n", json_object_to_json_string(json));
14559 json_object_free(json);
14560 json_object_free(json_ar);
14561 json_object_free(json_scode);
14562 json_object_free(json_ocode);
14563 } else
14564 vty_out(vty,
14565 "%% Inbound soft reconfiguration not enabled\n");
14566
14567 return CMD_WARNING;
14568 }
14569
14570 bgp = peer->bgp;
14571
14572 /* labeled-unicast routes live in the unicast table */
14573 if (safi == SAFI_LABELED_UNICAST)
14574 table = bgp->rib[afi][SAFI_UNICAST];
14575 else
14576 table = bgp->rib[afi][safi];
14577
14578 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14579 || (safi == SAFI_EVPN)) {
14580
14581 struct bgp_dest *dest;
14582
14583 for (dest = bgp_table_top(table); dest;
14584 dest = bgp_route_next(dest)) {
14585 table = bgp_dest_get_bgp_table_info(dest);
14586 if (!table)
14587 continue;
14588
14589 output_count_per_rd = 0;
14590 filtered_count_per_rd = 0;
14591
14592 if (use_json)
14593 json_routes = json_object_new_object();
14594
14595 const struct prefix_rd *prd;
14596 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14597 dest);
14598
14599 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14600 bgp->asnotation);
14601
14602 show_adj_route(
14603 vty, peer, table, afi, safi, type, rmap_name,
14604 json, json_routes, json_scode, json_ocode,
14605 show_flags, &header1, &header2, rd_str, match,
14606 &output_count_per_rd, &filtered_count_per_rd);
14607
14608 /* Don't include an empty RD in the output! */
14609 if (json_routes && (output_count_per_rd > 0))
14610 json_object_object_add(json_ar, rd_str,
14611 json_routes);
14612
14613 output_count += output_count_per_rd;
14614 filtered_count += filtered_count_per_rd;
14615 }
14616 } else
14617 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14618 json, json_ar, json_scode, json_ocode,
14619 show_flags, &header1, &header2, rd_str, match,
14620 &output_count, &filtered_count);
14621
14622 if (use_json) {
14623 if (type == bgp_show_adj_route_advertised)
14624 json_object_object_add(json, "advertisedRoutes",
14625 json_ar);
14626 else
14627 json_object_object_add(json, "receivedRoutes", json_ar);
14628 json_object_int_add(json, "totalPrefixCounter", output_count);
14629 json_object_int_add(json, "filteredPrefixCounter",
14630 filtered_count);
14631
14632 /*
14633 * These fields only give up ownership to `json` when `header1`
14634 * is used (set to zero). See code in `show_adj_route` and
14635 * `show_adj_route_header`.
14636 */
14637 if (header1 == 1) {
14638 json_object_free(json_scode);
14639 json_object_free(json_ocode);
14640 }
14641
14642 vty_json(vty, json);
14643 } else if (output_count > 0) {
14644 if (!match && filtered_count > 0)
14645 vty_out(vty,
14646 "\nTotal number of prefixes %ld (%ld filtered)\n",
14647 output_count, filtered_count);
14648 else
14649 vty_out(vty, "\nTotal number of prefixes %ld\n",
14650 output_count);
14651 }
14652
14653 return CMD_SUCCESS;
14654 }
14655
14656 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14657 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14658 "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]",
14659 SHOW_STR
14660 IP_STR
14661 BGP_STR
14662 BGP_INSTANCE_HELP_STR
14663 BGP_AFI_HELP_STR
14664 BGP_SAFI_WITH_LABEL_HELP_STR
14665 "Detailed information on TCP and BGP neighbor connections\n"
14666 "Neighbor to display information about\n"
14667 "Neighbor to display information about\n"
14668 "Neighbor on BGP configured interface\n"
14669 "Display the routes selected by best path\n"
14670 "Display detailed version of routes\n"
14671 JSON_STR
14672 "Increase table width for longer prefixes\n")
14673 {
14674 afi_t afi = AFI_IP6;
14675 safi_t safi = SAFI_UNICAST;
14676 char *rmap_name = NULL;
14677 char *peerstr = NULL;
14678 struct bgp *bgp = NULL;
14679 struct peer *peer;
14680 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14681 int idx = 0;
14682 uint16_t show_flags = 0;
14683
14684 if (detail)
14685 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14686
14687 if (uj)
14688 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14689
14690 if (wide)
14691 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14692
14693 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14694 &bgp, uj);
14695
14696 if (!idx)
14697 return CMD_WARNING;
14698
14699 argv_find(argv, argc, "neighbors", &idx);
14700 peerstr = argv[++idx]->arg;
14701
14702 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14703 if (!peer)
14704 return CMD_WARNING;
14705
14706 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14707 show_flags);
14708 }
14709
14710 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14711 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14712 "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]",
14713 SHOW_STR
14714 IP_STR
14715 BGP_STR
14716 BGP_INSTANCE_HELP_STR
14717 BGP_AFI_HELP_STR
14718 BGP_SAFI_WITH_LABEL_HELP_STR
14719 "Display the entries for all address families\n"
14720 "Detailed information on TCP and BGP neighbor connections\n"
14721 "Neighbor to display information about\n"
14722 "Neighbor to display information about\n"
14723 "Neighbor on BGP configured interface\n"
14724 "Display the routes advertised to a BGP neighbor\n"
14725 "Display the received routes from neighbor\n"
14726 "Display the filtered routes received from neighbor\n"
14727 "Route-map to modify the attributes\n"
14728 "Name of the route map\n"
14729 "IPv4 prefix\n"
14730 "IPv6 prefix\n"
14731 "Display detailed version of routes\n"
14732 JSON_STR
14733 "Increase table width for longer prefixes\n")
14734 {
14735 afi_t afi = AFI_IP6;
14736 safi_t safi = SAFI_UNICAST;
14737 char *peerstr = NULL;
14738 struct bgp *bgp = NULL;
14739 struct peer *peer;
14740 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14741 int idx = 0;
14742 bool first = true;
14743 uint16_t show_flags = 0;
14744 struct listnode *node;
14745 struct bgp *abgp;
14746
14747 if (detail || prefix_str)
14748 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14749
14750 if (uj) {
14751 argc--;
14752 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14753 }
14754
14755 if (all) {
14756 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14757 if (argv_find(argv, argc, "ipv4", &idx))
14758 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14759
14760 if (argv_find(argv, argc, "ipv6", &idx))
14761 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14762 }
14763
14764 if (wide)
14765 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14766
14767 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14768 &bgp, uj);
14769 if (!idx)
14770 return CMD_WARNING;
14771
14772 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14773 argv_find(argv, argc, "neighbors", &idx);
14774 peerstr = argv[++idx]->arg;
14775
14776 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14777 if (!peer)
14778 return CMD_WARNING;
14779
14780 if (argv_find(argv, argc, "advertised-routes", &idx))
14781 type = bgp_show_adj_route_advertised;
14782 else if (argv_find(argv, argc, "received-routes", &idx))
14783 type = bgp_show_adj_route_received;
14784 else if (argv_find(argv, argc, "filtered-routes", &idx))
14785 type = bgp_show_adj_route_filtered;
14786
14787 if (!all)
14788 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14789 prefix_str ? prefix : NULL, show_flags);
14790 if (uj)
14791 vty_out(vty, "{\n");
14792
14793 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14794 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14795 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14796 : AFI_IP6;
14797 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14798 FOREACH_SAFI (safi) {
14799 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14800 continue;
14801
14802 if (uj) {
14803 if (first)
14804 first = false;
14805 else
14806 vty_out(vty, ",\n");
14807 vty_out(vty, "\"%s\":",
14808 get_afi_safi_str(afi, safi,
14809 true));
14810 } else
14811 vty_out(vty,
14812 "\nFor address family: %s\n",
14813 get_afi_safi_str(afi, safi,
14814 false));
14815
14816 peer_adj_routes(vty, peer, afi, safi, type,
14817 route_map, prefix, show_flags);
14818 }
14819 }
14820 } else {
14821 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14822 FOREACH_AFI_SAFI (afi, safi) {
14823 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14824 continue;
14825
14826 if (uj) {
14827 if (first)
14828 first = false;
14829 else
14830 vty_out(vty, ",\n");
14831 vty_out(vty, "\"%s\":",
14832 get_afi_safi_str(afi, safi,
14833 true));
14834 } else
14835 vty_out(vty,
14836 "\nFor address family: %s\n",
14837 get_afi_safi_str(afi, safi,
14838 false));
14839
14840 peer_adj_routes(vty, peer, afi, safi, type,
14841 route_map, prefix, show_flags);
14842 }
14843 }
14844 }
14845 if (uj)
14846 vty_out(vty, "}\n");
14847
14848 return CMD_SUCCESS;
14849 }
14850
14851 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14852 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14853 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14854 SHOW_STR
14855 IP_STR
14856 BGP_STR
14857 BGP_INSTANCE_HELP_STR
14858 BGP_AF_STR
14859 BGP_AF_STR
14860 BGP_AF_MODIFIER_STR
14861 "Detailed information on TCP and BGP neighbor connections\n"
14862 "Neighbor to display information about\n"
14863 "Neighbor to display information about\n"
14864 "Neighbor on BGP configured interface\n"
14865 "Display information received from a BGP neighbor\n"
14866 "Display the prefixlist filter\n"
14867 JSON_STR)
14868 {
14869 afi_t afi = AFI_IP6;
14870 safi_t safi = SAFI_UNICAST;
14871 char *peerstr = NULL;
14872 char name[BUFSIZ];
14873 struct peer *peer;
14874 int count;
14875 int idx = 0;
14876 struct bgp *bgp = NULL;
14877 bool uj = use_json(argc, argv);
14878
14879 if (uj)
14880 argc--;
14881
14882 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14883 &bgp, uj);
14884 if (!idx)
14885 return CMD_WARNING;
14886
14887 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14888 argv_find(argv, argc, "neighbors", &idx);
14889 peerstr = argv[++idx]->arg;
14890
14891 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14892 if (!peer)
14893 return CMD_WARNING;
14894
14895 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14896 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14897 if (count) {
14898 if (!uj)
14899 vty_out(vty, "Address Family: %s\n",
14900 get_afi_safi_str(afi, safi, false));
14901 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14902 } else {
14903 if (uj)
14904 vty_out(vty, "{}\n");
14905 else
14906 vty_out(vty, "No functional output\n");
14907 }
14908
14909 return CMD_SUCCESS;
14910 }
14911
14912 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14913 afi_t afi, safi_t safi,
14914 enum bgp_show_type type, bool use_json)
14915 {
14916 uint16_t show_flags = 0;
14917
14918 if (use_json)
14919 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14920
14921 if (!peer || !peer->afc[afi][safi]) {
14922 if (use_json) {
14923 json_object *json_no = NULL;
14924 json_no = json_object_new_object();
14925 json_object_string_add(
14926 json_no, "warning",
14927 "No such neighbor or address family");
14928 vty_out(vty, "%s\n",
14929 json_object_to_json_string(json_no));
14930 json_object_free(json_no);
14931 } else
14932 vty_out(vty, "%% No such neighbor or address family\n");
14933 return CMD_WARNING;
14934 }
14935
14936 /* labeled-unicast routes live in the unicast table */
14937 if (safi == SAFI_LABELED_UNICAST)
14938 safi = SAFI_UNICAST;
14939
14940 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14941 RPKI_NOT_BEING_USED);
14942 }
14943
14944 /*
14945 * Used for "detailed" output for cmds like show bgp <afi> <safi> (or)
14946 * show bgp <vrf> (or) show bgp <vrf> <afi> <safi>
14947 */
14948 DEFPY(show_ip_bgp_vrf_afi_safi_routes_detailed,
14949 show_ip_bgp_vrf_afi_safi_routes_detailed_cmd,
14950 "show [ip] bgp [<view|vrf> VIEWVRFNAME$vrf_name] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] detail [json$uj]",
14951 SHOW_STR
14952 IP_STR
14953 BGP_STR
14954 BGP_INSTANCE_HELP_STR
14955 BGP_AFI_HELP_STR
14956 BGP_SAFI_WITH_LABEL_HELP_STR
14957 "Detailed information\n"
14958 JSON_STR)
14959 {
14960 afi_t afi = AFI_IP6;
14961 safi_t safi = SAFI_UNICAST;
14962 struct bgp *bgp = NULL;
14963 int idx = 0;
14964 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14965
14966 if (uj)
14967 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14968
14969 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14970 &bgp, uj);
14971 if (!idx)
14972 return CMD_WARNING;
14973 /* 'vrf all' case to iterate all vrfs & show output per vrf instance */
14974 if (vrf_name && strmatch(vrf_name, "all")) {
14975 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
14976 return CMD_SUCCESS;
14977 }
14978
14979 /* All other cases except vrf all */
14980 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14981 show_flags, RPKI_NOT_BEING_USED);
14982 }
14983
14984 DEFUN (show_ip_bgp_neighbor_routes,
14985 show_ip_bgp_neighbor_routes_cmd,
14986 "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]",
14987 SHOW_STR
14988 IP_STR
14989 BGP_STR
14990 BGP_INSTANCE_HELP_STR
14991 BGP_AFI_HELP_STR
14992 BGP_SAFI_WITH_LABEL_HELP_STR
14993 "Detailed information on TCP and BGP neighbor connections\n"
14994 "Neighbor to display information about\n"
14995 "Neighbor to display information about\n"
14996 "Neighbor on BGP configured interface\n"
14997 "Display flap statistics of the routes learned from neighbor\n"
14998 "Display the dampened routes received from neighbor\n"
14999 "Display routes learned from neighbor\n"
15000 JSON_STR)
15001 {
15002 char *peerstr = NULL;
15003 struct bgp *bgp = NULL;
15004 afi_t afi = AFI_IP6;
15005 safi_t safi = SAFI_UNICAST;
15006 struct peer *peer;
15007 enum bgp_show_type sh_type = bgp_show_type_neighbor;
15008 int idx = 0;
15009 bool uj = use_json(argc, argv);
15010
15011 if (uj)
15012 argc--;
15013
15014 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
15015 &bgp, uj);
15016 if (!idx)
15017 return CMD_WARNING;
15018
15019 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
15020 argv_find(argv, argc, "neighbors", &idx);
15021 peerstr = argv[++idx]->arg;
15022
15023 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
15024 if (!peer)
15025 return CMD_WARNING;
15026
15027 if (argv_find(argv, argc, "flap-statistics", &idx))
15028 sh_type = bgp_show_type_flap_neighbor;
15029 else if (argv_find(argv, argc, "dampened-routes", &idx))
15030 sh_type = bgp_show_type_damp_neighbor;
15031 else if (argv_find(argv, argc, "routes", &idx))
15032 sh_type = bgp_show_type_neighbor;
15033
15034 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
15035 }
15036
15037 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
15038
15039 struct bgp_distance {
15040 /* Distance value for the IP source prefix. */
15041 uint8_t distance;
15042
15043 /* Name of the access-list to be matched. */
15044 char *access_list;
15045 };
15046
15047 DEFUN (show_bgp_afi_vpn_rd_route,
15048 show_bgp_afi_vpn_rd_route_cmd,
15049 "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]",
15050 SHOW_STR
15051 BGP_STR
15052 BGP_AFI_HELP_STR
15053 BGP_AF_MODIFIER_STR
15054 "Display information for a route distinguisher\n"
15055 "Route Distinguisher\n"
15056 "All Route Distinguishers\n"
15057 "Network in the BGP routing table to display\n"
15058 "Network in the BGP routing table to display\n"
15059 JSON_STR)
15060 {
15061 int ret;
15062 struct prefix_rd prd;
15063 afi_t afi = AFI_MAX;
15064 int idx = 0;
15065
15066 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
15067 vty_out(vty, "%% Malformed Address Family\n");
15068 return CMD_WARNING;
15069 }
15070
15071 if (!strcmp(argv[5]->arg, "all"))
15072 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
15073 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
15074 RPKI_NOT_BEING_USED,
15075 use_json(argc, argv));
15076
15077 ret = str2prefix_rd(argv[5]->arg, &prd);
15078 if (!ret) {
15079 vty_out(vty, "%% Malformed Route Distinguisher\n");
15080 return CMD_WARNING;
15081 }
15082
15083 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
15084 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
15085 use_json(argc, argv));
15086 }
15087
15088 static struct bgp_distance *bgp_distance_new(void)
15089 {
15090 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
15091 }
15092
15093 static void bgp_distance_free(struct bgp_distance *bdistance)
15094 {
15095 XFREE(MTYPE_BGP_DISTANCE, bdistance);
15096 }
15097
15098 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15099 const char *ip_str, const char *access_list_str)
15100 {
15101 int ret;
15102 afi_t afi;
15103 safi_t safi;
15104 struct prefix p;
15105 uint8_t distance;
15106 struct bgp_dest *dest;
15107 struct bgp_distance *bdistance;
15108
15109 afi = bgp_node_afi(vty);
15110 safi = bgp_node_safi(vty);
15111
15112 ret = str2prefix(ip_str, &p);
15113 if (ret == 0) {
15114 vty_out(vty, "Malformed prefix\n");
15115 return CMD_WARNING_CONFIG_FAILED;
15116 }
15117
15118 distance = atoi(distance_str);
15119
15120 /* Get BGP distance node. */
15121 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15122 bdistance = bgp_dest_get_bgp_distance_info(dest);
15123 if (bdistance)
15124 bgp_dest_unlock_node(dest);
15125 else {
15126 bdistance = bgp_distance_new();
15127 bgp_dest_set_bgp_distance_info(dest, bdistance);
15128 }
15129
15130 /* Set distance value. */
15131 bdistance->distance = distance;
15132
15133 /* Reset access-list configuration. */
15134 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15135 if (access_list_str)
15136 bdistance->access_list =
15137 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15138
15139 return CMD_SUCCESS;
15140 }
15141
15142 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15143 const char *ip_str, const char *access_list_str)
15144 {
15145 int ret;
15146 afi_t afi;
15147 safi_t safi;
15148 struct prefix p;
15149 int distance;
15150 struct bgp_dest *dest;
15151 struct bgp_distance *bdistance;
15152
15153 afi = bgp_node_afi(vty);
15154 safi = bgp_node_safi(vty);
15155
15156 ret = str2prefix(ip_str, &p);
15157 if (ret == 0) {
15158 vty_out(vty, "Malformed prefix\n");
15159 return CMD_WARNING_CONFIG_FAILED;
15160 }
15161
15162 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15163 if (!dest) {
15164 vty_out(vty, "Can't find specified prefix\n");
15165 return CMD_WARNING_CONFIG_FAILED;
15166 }
15167
15168 bdistance = bgp_dest_get_bgp_distance_info(dest);
15169 distance = atoi(distance_str);
15170
15171 if (bdistance->distance != distance) {
15172 vty_out(vty, "Distance does not match configured\n");
15173 bgp_dest_unlock_node(dest);
15174 return CMD_WARNING_CONFIG_FAILED;
15175 }
15176
15177 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15178 bgp_distance_free(bdistance);
15179
15180 bgp_dest_set_bgp_path_info(dest, NULL);
15181 bgp_dest_unlock_node(dest);
15182 bgp_dest_unlock_node(dest);
15183
15184 return CMD_SUCCESS;
15185 }
15186
15187 /* Apply BGP information to distance method. */
15188 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15189 afi_t afi, safi_t safi, struct bgp *bgp)
15190 {
15191 struct bgp_dest *dest;
15192 struct prefix q = {0};
15193 struct peer *peer;
15194 struct bgp_distance *bdistance;
15195 struct access_list *alist;
15196 struct bgp_static *bgp_static;
15197 struct bgp_path_info *bpi_ultimate;
15198
15199 if (!bgp)
15200 return 0;
15201
15202 peer = pinfo->peer;
15203
15204 if (pinfo->attr->distance)
15205 return pinfo->attr->distance;
15206
15207 /* get peer origin to calculate appropriate distance */
15208 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15209 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15210 peer = bpi_ultimate->peer;
15211 }
15212
15213 /* Check source address.
15214 * Note: for aggregate route, peer can have unspec af type.
15215 */
15216 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15217 && !sockunion2hostprefix(&peer->su, &q))
15218 return 0;
15219
15220 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15221 if (dest) {
15222 bdistance = bgp_dest_get_bgp_distance_info(dest);
15223 bgp_dest_unlock_node(dest);
15224
15225 if (bdistance->access_list) {
15226 alist = access_list_lookup(afi, bdistance->access_list);
15227 if (alist
15228 && access_list_apply(alist, p) == FILTER_PERMIT)
15229 return bdistance->distance;
15230 } else
15231 return bdistance->distance;
15232 }
15233
15234 /* Backdoor check. */
15235 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15236 if (dest) {
15237 bgp_static = bgp_dest_get_bgp_static_info(dest);
15238 bgp_dest_unlock_node(dest);
15239
15240 if (bgp_static->backdoor) {
15241 if (bgp->distance_local[afi][safi])
15242 return bgp->distance_local[afi][safi];
15243 else
15244 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15245 }
15246 }
15247
15248 if (peer->sort == BGP_PEER_EBGP) {
15249 if (bgp->distance_ebgp[afi][safi])
15250 return bgp->distance_ebgp[afi][safi];
15251 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15252 } else if (peer->sort == BGP_PEER_IBGP) {
15253 if (bgp->distance_ibgp[afi][safi])
15254 return bgp->distance_ibgp[afi][safi];
15255 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15256 } else {
15257 if (bgp->distance_local[afi][safi])
15258 return bgp->distance_local[afi][safi];
15259 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15260 }
15261 }
15262
15263 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15264 * we should tell ZEBRA update the routes for a specific
15265 * AFI/SAFI to reflect changes in RIB.
15266 */
15267 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15268 afi_t update_afi,
15269 safi_t update_safi)
15270 {
15271 afi_t afi;
15272 safi_t safi;
15273
15274 FOREACH_AFI_SAFI (afi, safi) {
15275 if (!bgp_fibupd_safi(safi))
15276 continue;
15277
15278 if (afi != update_afi && safi != update_safi)
15279 continue;
15280
15281 if (BGP_DEBUG(zebra, ZEBRA))
15282 zlog_debug(
15283 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15284 __func__, afi, safi);
15285 bgp_zebra_announce_table(bgp, afi, safi);
15286 }
15287 }
15288
15289 DEFUN (bgp_distance,
15290 bgp_distance_cmd,
15291 "distance bgp (1-255) (1-255) (1-255)",
15292 "Define an administrative distance\n"
15293 "BGP distance\n"
15294 "Distance for routes external to the AS\n"
15295 "Distance for routes internal to the AS\n"
15296 "Distance for local routes\n")
15297 {
15298 VTY_DECLVAR_CONTEXT(bgp, bgp);
15299 int idx_number = 2;
15300 int idx_number_2 = 3;
15301 int idx_number_3 = 4;
15302 int distance_ebgp = atoi(argv[idx_number]->arg);
15303 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15304 int distance_local = atoi(argv[idx_number_3]->arg);
15305 afi_t afi;
15306 safi_t safi;
15307
15308 afi = bgp_node_afi(vty);
15309 safi = bgp_node_safi(vty);
15310
15311 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15312 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15313 || bgp->distance_local[afi][safi] != distance_local) {
15314 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15315 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15316 bgp->distance_local[afi][safi] = distance_local;
15317 bgp_announce_routes_distance_update(bgp, afi, safi);
15318 }
15319 return CMD_SUCCESS;
15320 }
15321
15322 DEFUN (no_bgp_distance,
15323 no_bgp_distance_cmd,
15324 "no distance bgp [(1-255) (1-255) (1-255)]",
15325 NO_STR
15326 "Define an administrative distance\n"
15327 "BGP distance\n"
15328 "Distance for routes external to the AS\n"
15329 "Distance for routes internal to the AS\n"
15330 "Distance for local routes\n")
15331 {
15332 VTY_DECLVAR_CONTEXT(bgp, bgp);
15333 afi_t afi;
15334 safi_t safi;
15335
15336 afi = bgp_node_afi(vty);
15337 safi = bgp_node_safi(vty);
15338
15339 if (bgp->distance_ebgp[afi][safi] != 0
15340 || bgp->distance_ibgp[afi][safi] != 0
15341 || bgp->distance_local[afi][safi] != 0) {
15342 bgp->distance_ebgp[afi][safi] = 0;
15343 bgp->distance_ibgp[afi][safi] = 0;
15344 bgp->distance_local[afi][safi] = 0;
15345 bgp_announce_routes_distance_update(bgp, afi, safi);
15346 }
15347 return CMD_SUCCESS;
15348 }
15349
15350
15351 DEFUN (bgp_distance_source,
15352 bgp_distance_source_cmd,
15353 "distance (1-255) A.B.C.D/M",
15354 "Define an administrative distance\n"
15355 "Administrative distance\n"
15356 "IP source prefix\n")
15357 {
15358 int idx_number = 1;
15359 int idx_ipv4_prefixlen = 2;
15360 bgp_distance_set(vty, argv[idx_number]->arg,
15361 argv[idx_ipv4_prefixlen]->arg, NULL);
15362 return CMD_SUCCESS;
15363 }
15364
15365 DEFUN (no_bgp_distance_source,
15366 no_bgp_distance_source_cmd,
15367 "no distance (1-255) A.B.C.D/M",
15368 NO_STR
15369 "Define an administrative distance\n"
15370 "Administrative distance\n"
15371 "IP source prefix\n")
15372 {
15373 int idx_number = 2;
15374 int idx_ipv4_prefixlen = 3;
15375 bgp_distance_unset(vty, argv[idx_number]->arg,
15376 argv[idx_ipv4_prefixlen]->arg, NULL);
15377 return CMD_SUCCESS;
15378 }
15379
15380 DEFUN (bgp_distance_source_access_list,
15381 bgp_distance_source_access_list_cmd,
15382 "distance (1-255) A.B.C.D/M WORD",
15383 "Define an administrative distance\n"
15384 "Administrative distance\n"
15385 "IP source prefix\n"
15386 "Access list name\n")
15387 {
15388 int idx_number = 1;
15389 int idx_ipv4_prefixlen = 2;
15390 int idx_word = 3;
15391 bgp_distance_set(vty, argv[idx_number]->arg,
15392 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15393 return CMD_SUCCESS;
15394 }
15395
15396 DEFUN (no_bgp_distance_source_access_list,
15397 no_bgp_distance_source_access_list_cmd,
15398 "no distance (1-255) A.B.C.D/M WORD",
15399 NO_STR
15400 "Define an administrative distance\n"
15401 "Administrative distance\n"
15402 "IP source prefix\n"
15403 "Access list name\n")
15404 {
15405 int idx_number = 2;
15406 int idx_ipv4_prefixlen = 3;
15407 int idx_word = 4;
15408 bgp_distance_unset(vty, argv[idx_number]->arg,
15409 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15410 return CMD_SUCCESS;
15411 }
15412
15413 DEFUN (ipv6_bgp_distance_source,
15414 ipv6_bgp_distance_source_cmd,
15415 "distance (1-255) X:X::X:X/M",
15416 "Define an administrative distance\n"
15417 "Administrative distance\n"
15418 "IP source prefix\n")
15419 {
15420 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15421 return CMD_SUCCESS;
15422 }
15423
15424 DEFUN (no_ipv6_bgp_distance_source,
15425 no_ipv6_bgp_distance_source_cmd,
15426 "no distance (1-255) X:X::X:X/M",
15427 NO_STR
15428 "Define an administrative distance\n"
15429 "Administrative distance\n"
15430 "IP source prefix\n")
15431 {
15432 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15433 return CMD_SUCCESS;
15434 }
15435
15436 DEFUN (ipv6_bgp_distance_source_access_list,
15437 ipv6_bgp_distance_source_access_list_cmd,
15438 "distance (1-255) X:X::X:X/M WORD",
15439 "Define an administrative distance\n"
15440 "Administrative distance\n"
15441 "IP source prefix\n"
15442 "Access list name\n")
15443 {
15444 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15445 return CMD_SUCCESS;
15446 }
15447
15448 DEFUN (no_ipv6_bgp_distance_source_access_list,
15449 no_ipv6_bgp_distance_source_access_list_cmd,
15450 "no distance (1-255) X:X::X:X/M WORD",
15451 NO_STR
15452 "Define an administrative distance\n"
15453 "Administrative distance\n"
15454 "IP source prefix\n"
15455 "Access list name\n")
15456 {
15457 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15458 return CMD_SUCCESS;
15459 }
15460
15461 DEFUN (bgp_damp_set,
15462 bgp_damp_set_cmd,
15463 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15464 "BGP Specific commands\n"
15465 "Enable route-flap dampening\n"
15466 "Half-life time for the penalty\n"
15467 "Value to start reusing a route\n"
15468 "Value to start suppressing a route\n"
15469 "Maximum duration to suppress a stable route\n")
15470 {
15471 VTY_DECLVAR_CONTEXT(bgp, bgp);
15472 int idx_half_life = 2;
15473 int idx_reuse = 3;
15474 int idx_suppress = 4;
15475 int idx_max_suppress = 5;
15476 int half = DEFAULT_HALF_LIFE * 60;
15477 int reuse = DEFAULT_REUSE;
15478 int suppress = DEFAULT_SUPPRESS;
15479 int max = 4 * half;
15480
15481 if (argc == 6) {
15482 half = atoi(argv[idx_half_life]->arg) * 60;
15483 reuse = atoi(argv[idx_reuse]->arg);
15484 suppress = atoi(argv[idx_suppress]->arg);
15485 max = atoi(argv[idx_max_suppress]->arg) * 60;
15486 } else if (argc == 3) {
15487 half = atoi(argv[idx_half_life]->arg) * 60;
15488 max = 4 * half;
15489 }
15490
15491 /*
15492 * These can't be 0 but our SA doesn't understand the
15493 * way our cli is constructed
15494 */
15495 assert(reuse);
15496 assert(half);
15497 if (suppress < reuse) {
15498 vty_out(vty,
15499 "Suppress value cannot be less than reuse value \n");
15500 return 0;
15501 }
15502
15503 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15504 reuse, suppress, max);
15505 }
15506
15507 DEFUN (bgp_damp_unset,
15508 bgp_damp_unset_cmd,
15509 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15510 NO_STR
15511 "BGP Specific commands\n"
15512 "Enable route-flap dampening\n"
15513 "Half-life time for the penalty\n"
15514 "Value to start reusing a route\n"
15515 "Value to start suppressing a route\n"
15516 "Maximum duration to suppress a stable route\n")
15517 {
15518 VTY_DECLVAR_CONTEXT(bgp, bgp);
15519 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15520 }
15521
15522 /* Display specified route of BGP table. */
15523 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15524 const char *ip_str, afi_t afi, safi_t safi,
15525 struct prefix_rd *prd, int prefix_check)
15526 {
15527 int ret;
15528 struct prefix match;
15529 struct bgp_dest *dest;
15530 struct bgp_dest *rm;
15531 struct bgp_path_info *pi;
15532 struct bgp_path_info *pi_temp;
15533 struct bgp *bgp;
15534 struct bgp_table *table;
15535
15536 /* BGP structure lookup. */
15537 if (view_name) {
15538 bgp = bgp_lookup_by_name(view_name);
15539 if (bgp == NULL) {
15540 vty_out(vty, "%% Can't find BGP instance %s\n",
15541 view_name);
15542 return CMD_WARNING;
15543 }
15544 } else {
15545 bgp = bgp_get_default();
15546 if (bgp == NULL) {
15547 vty_out(vty, "%% No BGP process is configured\n");
15548 return CMD_WARNING;
15549 }
15550 }
15551
15552 /* Check IP address argument. */
15553 ret = str2prefix(ip_str, &match);
15554 if (!ret) {
15555 vty_out(vty, "%% address is malformed\n");
15556 return CMD_WARNING;
15557 }
15558
15559 match.family = afi2family(afi);
15560
15561 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15562 || (safi == SAFI_EVPN)) {
15563 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15564 dest = bgp_route_next(dest)) {
15565 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15566
15567 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15568 continue;
15569 table = bgp_dest_get_bgp_table_info(dest);
15570 if (!table)
15571 continue;
15572 rm = bgp_node_match(table, &match);
15573 if (rm == NULL)
15574 continue;
15575
15576 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15577
15578 if (!prefix_check
15579 || rm_p->prefixlen == match.prefixlen) {
15580 pi = bgp_dest_get_bgp_path_info(rm);
15581 while (pi) {
15582 if (pi->extra && pi->extra->damp_info) {
15583 pi_temp = pi->next;
15584 bgp_damp_info_free(
15585 pi->extra->damp_info,
15586 1, afi, safi);
15587 pi = pi_temp;
15588 } else
15589 pi = pi->next;
15590 }
15591 }
15592
15593 bgp_dest_unlock_node(rm);
15594 }
15595 } else {
15596 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15597 if (dest != NULL) {
15598 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15599
15600 if (!prefix_check
15601 || dest_p->prefixlen == match.prefixlen) {
15602 pi = bgp_dest_get_bgp_path_info(dest);
15603 while (pi) {
15604 if (pi->extra && pi->extra->damp_info) {
15605 pi_temp = pi->next;
15606 bgp_damp_info_free(
15607 pi->extra->damp_info,
15608 1, afi, safi);
15609 pi = pi_temp;
15610 } else
15611 pi = pi->next;
15612 }
15613 }
15614
15615 bgp_dest_unlock_node(dest);
15616 }
15617 }
15618
15619 return CMD_SUCCESS;
15620 }
15621
15622 DEFUN (clear_ip_bgp_dampening,
15623 clear_ip_bgp_dampening_cmd,
15624 "clear ip bgp dampening",
15625 CLEAR_STR
15626 IP_STR
15627 BGP_STR
15628 "Clear route flap dampening information\n")
15629 {
15630 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15631 return CMD_SUCCESS;
15632 }
15633
15634 DEFUN (clear_ip_bgp_dampening_prefix,
15635 clear_ip_bgp_dampening_prefix_cmd,
15636 "clear ip bgp dampening A.B.C.D/M",
15637 CLEAR_STR
15638 IP_STR
15639 BGP_STR
15640 "Clear route flap dampening information\n"
15641 "IPv4 prefix\n")
15642 {
15643 int idx_ipv4_prefixlen = 4;
15644 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15645 AFI_IP, SAFI_UNICAST, NULL, 1);
15646 }
15647
15648 DEFUN (clear_ip_bgp_dampening_address,
15649 clear_ip_bgp_dampening_address_cmd,
15650 "clear ip bgp dampening A.B.C.D",
15651 CLEAR_STR
15652 IP_STR
15653 BGP_STR
15654 "Clear route flap dampening information\n"
15655 "Network to clear damping information\n")
15656 {
15657 int idx_ipv4 = 4;
15658 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15659 SAFI_UNICAST, NULL, 0);
15660 }
15661
15662 DEFUN (clear_ip_bgp_dampening_address_mask,
15663 clear_ip_bgp_dampening_address_mask_cmd,
15664 "clear ip bgp dampening A.B.C.D A.B.C.D",
15665 CLEAR_STR
15666 IP_STR
15667 BGP_STR
15668 "Clear route flap dampening information\n"
15669 "Network to clear damping information\n"
15670 "Network mask\n")
15671 {
15672 int idx_ipv4 = 4;
15673 int idx_ipv4_2 = 5;
15674 int ret;
15675 char prefix_str[BUFSIZ];
15676
15677 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15678 prefix_str, sizeof(prefix_str));
15679 if (!ret) {
15680 vty_out(vty, "%% Inconsistent address and mask\n");
15681 return CMD_WARNING;
15682 }
15683
15684 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15685 NULL, 0);
15686 }
15687
15688 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15689 {
15690 struct vty *vty = arg;
15691 struct peer *peer = bucket->data;
15692
15693 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15694 }
15695
15696 DEFUN (show_bgp_listeners,
15697 show_bgp_listeners_cmd,
15698 "show bgp listeners",
15699 SHOW_STR
15700 BGP_STR
15701 "Display Listen Sockets and who created them\n")
15702 {
15703 bgp_dump_listener_info(vty);
15704
15705 return CMD_SUCCESS;
15706 }
15707
15708 DEFUN (show_bgp_peerhash,
15709 show_bgp_peerhash_cmd,
15710 "show bgp peerhash",
15711 SHOW_STR
15712 BGP_STR
15713 "Display information about the BGP peerhash\n")
15714 {
15715 struct list *instances = bm->bgp;
15716 struct listnode *node;
15717 struct bgp *bgp;
15718
15719 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15720 vty_out(vty, "BGP: %s\n", bgp->name);
15721 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15722 vty);
15723 }
15724
15725 return CMD_SUCCESS;
15726 }
15727
15728 /* also used for encap safi */
15729 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15730 afi_t afi, safi_t safi)
15731 {
15732 struct bgp_dest *pdest;
15733 struct bgp_dest *dest;
15734 struct bgp_table *table;
15735 const struct prefix *p;
15736 struct bgp_static *bgp_static;
15737 mpls_label_t label;
15738
15739 /* Network configuration. */
15740 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15741 pdest = bgp_route_next(pdest)) {
15742 table = bgp_dest_get_bgp_table_info(pdest);
15743 if (!table)
15744 continue;
15745
15746 for (dest = bgp_table_top(table); dest;
15747 dest = bgp_route_next(dest)) {
15748 bgp_static = bgp_dest_get_bgp_static_info(dest);
15749 if (bgp_static == NULL)
15750 continue;
15751
15752 p = bgp_dest_get_prefix(dest);
15753
15754 /* "network" configuration display. */
15755 label = decode_label(&bgp_static->label);
15756
15757 vty_out(vty, " network %pFX rd %s", p,
15758 bgp_static->prd_pretty);
15759 if (safi == SAFI_MPLS_VPN)
15760 vty_out(vty, " label %u", label);
15761
15762 if (bgp_static->rmap.name)
15763 vty_out(vty, " route-map %s",
15764 bgp_static->rmap.name);
15765
15766 if (bgp_static->backdoor)
15767 vty_out(vty, " backdoor");
15768
15769 vty_out(vty, "\n");
15770 }
15771 }
15772 }
15773
15774 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15775 afi_t afi, safi_t safi)
15776 {
15777 struct bgp_dest *pdest;
15778 struct bgp_dest *dest;
15779 struct bgp_table *table;
15780 const struct prefix *p;
15781 struct bgp_static *bgp_static;
15782 char buf[PREFIX_STRLEN * 2];
15783 char buf2[SU_ADDRSTRLEN];
15784 char esi_buf[ESI_STR_LEN];
15785
15786 /* Network configuration. */
15787 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15788 pdest = bgp_route_next(pdest)) {
15789 table = bgp_dest_get_bgp_table_info(pdest);
15790 if (!table)
15791 continue;
15792
15793 for (dest = bgp_table_top(table); dest;
15794 dest = bgp_route_next(dest)) {
15795 bgp_static = bgp_dest_get_bgp_static_info(dest);
15796 if (bgp_static == NULL)
15797 continue;
15798
15799 char *macrouter = NULL;
15800
15801 if (bgp_static->router_mac)
15802 macrouter = prefix_mac2str(
15803 bgp_static->router_mac, NULL, 0);
15804 if (bgp_static->eth_s_id)
15805 esi_to_str(bgp_static->eth_s_id,
15806 esi_buf, sizeof(esi_buf));
15807 p = bgp_dest_get_prefix(dest);
15808
15809 /* "network" configuration display. */
15810 if (p->u.prefix_evpn.route_type == 5) {
15811 char local_buf[PREFIX_STRLEN];
15812
15813 uint8_t family = is_evpn_prefix_ipaddr_v4((
15814 struct prefix_evpn *)p)
15815 ? AF_INET
15816 : AF_INET6;
15817 inet_ntop(family,
15818 &p->u.prefix_evpn.prefix_addr.ip.ip
15819 .addr,
15820 local_buf, sizeof(local_buf));
15821 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15822 p->u.prefix_evpn.prefix_addr
15823 .ip_prefix_length);
15824 } else {
15825 prefix2str(p, buf, sizeof(buf));
15826 }
15827
15828 if (bgp_static->gatewayIp.family == AF_INET
15829 || bgp_static->gatewayIp.family == AF_INET6)
15830 inet_ntop(bgp_static->gatewayIp.family,
15831 &bgp_static->gatewayIp.u.prefix, buf2,
15832 sizeof(buf2));
15833 vty_out(vty,
15834 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15835 buf, bgp_static->prd_pretty,
15836 p->u.prefix_evpn.prefix_addr.eth_tag,
15837 decode_label(&bgp_static->label), esi_buf, buf2,
15838 macrouter);
15839
15840 XFREE(MTYPE_TMP, macrouter);
15841 }
15842 }
15843 }
15844
15845 /* Configuration of static route announcement and aggregate
15846 information. */
15847 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15848 safi_t safi)
15849 {
15850 struct bgp_dest *dest;
15851 const struct prefix *p;
15852 struct bgp_static *bgp_static;
15853 struct bgp_aggregate *bgp_aggregate;
15854
15855 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15856 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15857 return;
15858 }
15859
15860 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15861 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15862 return;
15863 }
15864
15865 /* Network configuration. */
15866 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15867 dest = bgp_route_next(dest)) {
15868 bgp_static = bgp_dest_get_bgp_static_info(dest);
15869 if (bgp_static == NULL)
15870 continue;
15871
15872 p = bgp_dest_get_prefix(dest);
15873
15874 vty_out(vty, " network %pFX", p);
15875
15876 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15877 vty_out(vty, " label-index %u",
15878 bgp_static->label_index);
15879
15880 if (bgp_static->rmap.name)
15881 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15882
15883 if (bgp_static->backdoor)
15884 vty_out(vty, " backdoor");
15885
15886 vty_out(vty, "\n");
15887 }
15888
15889 /* Aggregate-address configuration. */
15890 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15891 dest = bgp_route_next(dest)) {
15892 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15893 if (bgp_aggregate == NULL)
15894 continue;
15895
15896 p = bgp_dest_get_prefix(dest);
15897
15898 vty_out(vty, " aggregate-address %pFX", p);
15899
15900 if (bgp_aggregate->as_set)
15901 vty_out(vty, " as-set");
15902
15903 if (bgp_aggregate->summary_only)
15904 vty_out(vty, " summary-only");
15905
15906 if (bgp_aggregate->rmap.name)
15907 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15908
15909 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15910 vty_out(vty, " origin %s",
15911 bgp_origin2str(bgp_aggregate->origin));
15912
15913 if (bgp_aggregate->match_med)
15914 vty_out(vty, " matching-MED-only");
15915
15916 if (bgp_aggregate->suppress_map_name)
15917 vty_out(vty, " suppress-map %s",
15918 bgp_aggregate->suppress_map_name);
15919
15920 vty_out(vty, "\n");
15921 }
15922 }
15923
15924 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15925 safi_t safi)
15926 {
15927 struct bgp_dest *dest;
15928 struct bgp_distance *bdistance;
15929
15930 /* Distance configuration. */
15931 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15932 && bgp->distance_local[afi][safi]
15933 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15934 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15935 || bgp->distance_local[afi][safi]
15936 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15937 vty_out(vty, " distance bgp %d %d %d\n",
15938 bgp->distance_ebgp[afi][safi],
15939 bgp->distance_ibgp[afi][safi],
15940 bgp->distance_local[afi][safi]);
15941 }
15942
15943 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15944 dest = bgp_route_next(dest)) {
15945 bdistance = bgp_dest_get_bgp_distance_info(dest);
15946 if (bdistance != NULL)
15947 vty_out(vty, " distance %d %pBD %s\n",
15948 bdistance->distance, dest,
15949 bdistance->access_list ? bdistance->access_list
15950 : "");
15951 }
15952 }
15953
15954 /* Allocate routing table structure and install commands. */
15955 void bgp_route_init(void)
15956 {
15957 afi_t afi;
15958 safi_t safi;
15959
15960 /* Init BGP distance table. */
15961 FOREACH_AFI_SAFI (afi, safi)
15962 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15963
15964 /* IPv4 BGP commands. */
15965 install_element(BGP_NODE, &bgp_table_map_cmd);
15966 install_element(BGP_NODE, &bgp_network_cmd);
15967 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15968
15969 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15970
15971 /* IPv4 unicast configuration. */
15972 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15973 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15974 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15975
15976 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15977
15978 /* IPv4 multicast configuration. */
15979 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15980 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15981 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15982 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15983
15984 /* IPv4 labeled-unicast configuration. */
15985 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15986 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15987
15988 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15989 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15990 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15991 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15992 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15993 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15994 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15995 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15996
15997 install_element(VIEW_NODE,
15998 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15999 install_element(VIEW_NODE,
16000 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
16001 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
16002 install_element(VIEW_NODE,
16003 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
16004 #ifdef KEEP_OLD_VPN_COMMANDS
16005 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
16006 #endif /* KEEP_OLD_VPN_COMMANDS */
16007 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
16008 install_element(VIEW_NODE,
16009 &show_bgp_l2vpn_evpn_route_prefix_cmd);
16010
16011 /* BGP dampening clear commands */
16012 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
16013 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
16014
16015 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
16016 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
16017
16018 /* prefix count */
16019 install_element(ENABLE_NODE,
16020 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
16021 #ifdef KEEP_OLD_VPN_COMMANDS
16022 install_element(ENABLE_NODE,
16023 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
16024 #endif /* KEEP_OLD_VPN_COMMANDS */
16025
16026 /* New config IPv6 BGP commands. */
16027 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
16028 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
16029 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
16030
16031 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
16032
16033 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
16034
16035 /* IPv6 labeled unicast address family. */
16036 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
16037 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
16038
16039 install_element(BGP_NODE, &bgp_distance_cmd);
16040 install_element(BGP_NODE, &no_bgp_distance_cmd);
16041 install_element(BGP_NODE, &bgp_distance_source_cmd);
16042 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
16043 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
16044 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
16045 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
16046 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
16047 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
16048 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
16049 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
16050 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
16051 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
16052 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
16053 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
16054 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
16055 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
16056 install_element(BGP_IPV4M_NODE,
16057 &no_bgp_distance_source_access_list_cmd);
16058 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
16059 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
16060 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
16061 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
16062 install_element(BGP_IPV6_NODE,
16063 &ipv6_bgp_distance_source_access_list_cmd);
16064 install_element(BGP_IPV6_NODE,
16065 &no_ipv6_bgp_distance_source_access_list_cmd);
16066 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
16067 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
16068 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
16069 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
16070 install_element(BGP_IPV6M_NODE,
16071 &ipv6_bgp_distance_source_access_list_cmd);
16072 install_element(BGP_IPV6M_NODE,
16073 &no_ipv6_bgp_distance_source_access_list_cmd);
16074
16075 /* BGP dampening */
16076 install_element(BGP_NODE, &bgp_damp_set_cmd);
16077 install_element(BGP_NODE, &bgp_damp_unset_cmd);
16078 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
16079 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
16080 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
16081 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
16082 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
16083 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
16084 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
16085 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
16086 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
16087 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
16088 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
16089 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
16090
16091 /* Large Communities */
16092 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
16093 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
16094
16095 /* show bgp vrf <afi> <safi> detailed */
16096 install_element(VIEW_NODE,
16097 &show_ip_bgp_vrf_afi_safi_routes_detailed_cmd);
16098
16099 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16100 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16101 }
16102
16103 void bgp_route_finish(void)
16104 {
16105 afi_t afi;
16106 safi_t safi;
16107
16108 FOREACH_AFI_SAFI (afi, safi) {
16109 bgp_table_unlock(bgp_distance_table[afi][safi]);
16110 bgp_distance_table[afi][safi] = NULL;
16111 }
16112 }