]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #13246 from opensourcerouting/rip-bfd
[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 if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL))
3091 /* Disable PHP : explicit-null */
3092 *label = afi == AFI_IP ? MPLS_LABEL_IPV4_EXPLICIT_NULL
3093 : MPLS_LABEL_IPV6_EXPLICIT_NULL;
3094 else
3095 /* Enforced PHP popping: implicit-null */
3096 *label = MPLS_LABEL_IMPLICIT_NULL;
3097
3098 return true;
3099 }
3100
3101 /*
3102 * old_select = The old best path
3103 * new_select = the new best path
3104 *
3105 * if (!old_select && new_select)
3106 * We are sending new information on.
3107 *
3108 * if (old_select && new_select) {
3109 * if (new_select != old_select)
3110 * We have a new best path send a change
3111 * else
3112 * We've received a update with new attributes that needs
3113 * to be passed on.
3114 * }
3115 *
3116 * if (old_select && !new_select)
3117 * We have no eligible route that we can announce or the rn
3118 * is being removed.
3119 */
3120 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3121 afi_t afi, safi_t safi)
3122 {
3123 struct bgp_path_info *new_select;
3124 struct bgp_path_info *old_select;
3125 struct bgp_path_info_pair old_and_new;
3126 int debug = 0;
3127 mpls_label_t mpls_label_null;
3128
3129 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3130 if (dest)
3131 debug = bgp_debug_bestpath(dest);
3132 if (debug)
3133 zlog_debug(
3134 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3135 __func__, dest, bgp->name_pretty);
3136 return;
3137 }
3138 /* Is it end of initial update? (after startup) */
3139 if (!dest) {
3140 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3141 sizeof(bgp->update_delay_zebra_resume_time));
3142
3143 bgp->main_zebra_update_hold = 0;
3144 FOREACH_AFI_SAFI (afi, safi) {
3145 if (bgp_fibupd_safi(safi))
3146 bgp_zebra_announce_table(bgp, afi, safi);
3147 }
3148 bgp->main_peers_update_hold = 0;
3149
3150 bgp_start_routeadv(bgp);
3151 return;
3152 }
3153
3154 const struct prefix *p = bgp_dest_get_prefix(dest);
3155
3156 debug = bgp_debug_bestpath(dest);
3157 if (debug)
3158 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3159 dest, bgp->name_pretty, afi2str(afi),
3160 safi2str(safi));
3161
3162 /* The best path calculation for the route is deferred if
3163 * BGP_NODE_SELECT_DEFER is set
3164 */
3165 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3166 if (BGP_DEBUG(update, UPDATE_OUT))
3167 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3168 dest, bgp->name_pretty);
3169 return;
3170 }
3171
3172 /* Best path selection. */
3173 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3174 afi, safi);
3175 old_select = old_and_new.old;
3176 new_select = old_and_new.new;
3177
3178 /* Do we need to allocate or free labels?
3179 * Right now, since we only deal with per-prefix labels, it is not
3180 * necessary to do this upon changes to best path. Exceptions:
3181 * - label index has changed -> recalculate resulting label
3182 * - path_info sub_type changed -> switch to/from null label value
3183 * - no valid label (due to removed static label binding) -> get new one
3184 */
3185 if (bgp->allocate_mpls_labels[afi][safi]) {
3186 if (new_select) {
3187 if (!old_select
3188 || bgp_label_index_differs(new_select, old_select)
3189 || new_select->sub_type != old_select->sub_type
3190 || !bgp_is_valid_label(&dest->local_label)) {
3191 /* control label imposition for local routes,
3192 * aggregate and redistributed routes
3193 */
3194 mpls_label_null = MPLS_LABEL_IMPLICIT_NULL;
3195 if (bgp_lu_need_null_label(bgp, new_select, afi,
3196 &mpls_label_null)) {
3197 if (CHECK_FLAG(
3198 dest->flags,
3199 BGP_NODE_REGISTERED_FOR_LABEL)
3200 || CHECK_FLAG(
3201 dest->flags,
3202 BGP_NODE_LABEL_REQUESTED))
3203 bgp_unregister_for_label(dest);
3204 dest->local_label = mpls_lse_encode(
3205 mpls_label_null, 0, 0, 1);
3206 bgp_set_valid_label(&dest->local_label);
3207 } else
3208 bgp_register_for_label(dest,
3209 new_select);
3210 }
3211 } else if (CHECK_FLAG(dest->flags,
3212 BGP_NODE_REGISTERED_FOR_LABEL)
3213 || CHECK_FLAG(dest->flags,
3214 BGP_NODE_LABEL_REQUESTED)) {
3215 bgp_unregister_for_label(dest);
3216 }
3217 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3218 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3219 bgp_unregister_for_label(dest);
3220 }
3221
3222 if (debug)
3223 zlog_debug(
3224 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3225 __func__, dest, bgp->name_pretty, afi2str(afi),
3226 safi2str(safi), old_select, new_select);
3227
3228 /* If best route remains the same and this is not due to user-initiated
3229 * clear, see exactly what needs to be done.
3230 */
3231 if (old_select && old_select == new_select
3232 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3233 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3234 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3235 if (bgp_zebra_has_route_changed(old_select)) {
3236 #ifdef ENABLE_BGP_VNC
3237 vnc_import_bgp_add_route(bgp, p, old_select);
3238 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3239 #endif
3240 if (bgp_fibupd_safi(safi)
3241 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3242
3243 if (new_select->type == ZEBRA_ROUTE_BGP
3244 && (new_select->sub_type == BGP_ROUTE_NORMAL
3245 || new_select->sub_type
3246 == BGP_ROUTE_IMPORTED))
3247
3248 bgp_zebra_announce(dest, p, old_select,
3249 bgp, afi, safi);
3250 }
3251 }
3252
3253 /* If there is a change of interest to peers, reannounce the
3254 * route. */
3255 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3256 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3257 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3258 group_announce_route(bgp, afi, safi, dest, new_select);
3259
3260 /* unicast routes must also be annouced to
3261 * labeled-unicast update-groups */
3262 if (safi == SAFI_UNICAST)
3263 group_announce_route(bgp, afi,
3264 SAFI_LABELED_UNICAST, dest,
3265 new_select);
3266
3267 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3268 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3269 }
3270
3271 /* advertise/withdraw type-5 routes */
3272 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3273 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3274 bgp_process_evpn_route_injection(
3275 bgp, afi, safi, dest, old_select, old_select);
3276
3277 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3278 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3279 bgp_zebra_clear_route_change_flags(dest);
3280 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3281 return;
3282 }
3283
3284 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3285 */
3286 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3287
3288 /* bestpath has changed; bump version */
3289 if (old_select || new_select) {
3290 bgp_bump_version(dest);
3291
3292 if (!bgp->t_rmap_def_originate_eval) {
3293 bgp_lock(bgp);
3294 event_add_timer(
3295 bm->master,
3296 update_group_refresh_default_originate_route_map,
3297 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3298 &bgp->t_rmap_def_originate_eval);
3299 }
3300 }
3301
3302 if (old_select)
3303 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3304 if (new_select) {
3305 if (debug)
3306 zlog_debug("%s: setting SELECTED flag", __func__);
3307 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3308 bgp_path_info_unset_flag(dest, new_select,
3309 BGP_PATH_ATTR_CHANGED);
3310 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3311 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3312 }
3313
3314 #ifdef ENABLE_BGP_VNC
3315 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3316 if (old_select != new_select) {
3317 if (old_select) {
3318 vnc_import_bgp_exterior_del_route(bgp, p,
3319 old_select);
3320 vnc_import_bgp_del_route(bgp, p, old_select);
3321 }
3322 if (new_select) {
3323 vnc_import_bgp_exterior_add_route(bgp, p,
3324 new_select);
3325 vnc_import_bgp_add_route(bgp, p, new_select);
3326 }
3327 }
3328 }
3329 #endif
3330
3331 group_announce_route(bgp, afi, safi, dest, new_select);
3332
3333 /* unicast routes must also be annouced to labeled-unicast update-groups
3334 */
3335 if (safi == SAFI_UNICAST)
3336 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3337 new_select);
3338
3339 /* FIB update. */
3340 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3341 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3342
3343 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3344 && (new_select->sub_type == BGP_ROUTE_NORMAL
3345 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3346 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3347
3348 /* if this is an evpn imported type-5 prefix,
3349 * we need to withdraw the route first to clear
3350 * the nh neigh and the RMAC entry.
3351 */
3352 if (old_select &&
3353 is_route_parent_evpn(old_select))
3354 bgp_zebra_withdraw(p, old_select, bgp, safi);
3355
3356 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3357 } else {
3358 /* Withdraw the route from the kernel. */
3359 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3360 && (old_select->sub_type == BGP_ROUTE_NORMAL
3361 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3362 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3363
3364 bgp_zebra_withdraw(p, old_select, bgp, safi);
3365 }
3366 }
3367
3368 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3369 old_select);
3370
3371 /* Clear any route change flags. */
3372 bgp_zebra_clear_route_change_flags(dest);
3373
3374 /* Reap old select bgp_path_info, if it has been removed */
3375 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3376 bgp_path_info_reap(dest, old_select);
3377
3378 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3379 return;
3380 }
3381
3382 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3383 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3384 {
3385 struct bgp_dest *dest;
3386 int cnt = 0;
3387 struct afi_safi_info *thread_info;
3388
3389 if (bgp->gr_info[afi][safi].t_route_select) {
3390 struct event *t = bgp->gr_info[afi][safi].t_route_select;
3391
3392 thread_info = EVENT_ARG(t);
3393 XFREE(MTYPE_TMP, thread_info);
3394 EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
3395 }
3396
3397 if (BGP_DEBUG(update, UPDATE_OUT)) {
3398 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3399 get_afi_safi_str(afi, safi, false),
3400 bgp->gr_info[afi][safi].gr_deferred);
3401 }
3402
3403 /* Process the route list */
3404 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3405 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3406 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3407 dest = bgp_route_next(dest)) {
3408 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3409 continue;
3410
3411 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3412 bgp->gr_info[afi][safi].gr_deferred--;
3413 bgp_process_main_one(bgp, dest, afi, safi);
3414 cnt++;
3415 }
3416 /* If iteration stopped before the entire table was traversed then the
3417 * node needs to be unlocked.
3418 */
3419 if (dest) {
3420 bgp_dest_unlock_node(dest);
3421 dest = NULL;
3422 }
3423
3424 /* Send EOR message when all routes are processed */
3425 if (!bgp->gr_info[afi][safi].gr_deferred) {
3426 bgp_send_delayed_eor(bgp);
3427 /* Send route processing complete message to RIB */
3428 bgp_zebra_update(bgp, afi, safi,
3429 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3430 return;
3431 }
3432
3433 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3434
3435 thread_info->afi = afi;
3436 thread_info->safi = safi;
3437 thread_info->bgp = bgp;
3438
3439 /* If there are more routes to be processed, start the
3440 * selection timer
3441 */
3442 event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3443 BGP_ROUTE_SELECT_DELAY,
3444 &bgp->gr_info[afi][safi].t_route_select);
3445 }
3446
3447 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3448 {
3449 struct bgp_process_queue *pqnode = data;
3450 struct bgp *bgp = pqnode->bgp;
3451 struct bgp_table *table;
3452 struct bgp_dest *dest;
3453
3454 /* eoiu marker */
3455 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3456 bgp_process_main_one(bgp, NULL, 0, 0);
3457 /* should always have dedicated wq call */
3458 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3459 return WQ_SUCCESS;
3460 }
3461
3462 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3463 dest = STAILQ_FIRST(&pqnode->pqueue);
3464 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3465 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3466 table = bgp_dest_table(dest);
3467 /* note, new DESTs may be added as part of processing */
3468 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3469
3470 bgp_dest_unlock_node(dest);
3471 bgp_table_unlock(table);
3472 }
3473
3474 return WQ_SUCCESS;
3475 }
3476
3477 static void bgp_processq_del(struct work_queue *wq, void *data)
3478 {
3479 struct bgp_process_queue *pqnode = data;
3480
3481 bgp_unlock(pqnode->bgp);
3482
3483 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3484 }
3485
3486 void bgp_process_queue_init(struct bgp *bgp)
3487 {
3488 if (!bgp->process_queue) {
3489 char name[BUFSIZ];
3490
3491 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3492 bgp->process_queue = work_queue_new(bm->master, name);
3493 }
3494
3495 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3496 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3497 bgp->process_queue->spec.max_retries = 0;
3498 bgp->process_queue->spec.hold = 50;
3499 /* Use a higher yield value of 50ms for main queue processing */
3500 bgp->process_queue->spec.yield = 50 * 1000L;
3501 }
3502
3503 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3504 {
3505 struct bgp_process_queue *pqnode;
3506
3507 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3508 sizeof(struct bgp_process_queue));
3509
3510 /* unlocked in bgp_processq_del */
3511 pqnode->bgp = bgp_lock(bgp);
3512 STAILQ_INIT(&pqnode->pqueue);
3513
3514 return pqnode;
3515 }
3516
3517 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3518 {
3519 #define ARBITRARY_PROCESS_QLEN 10000
3520 struct work_queue *wq = bgp->process_queue;
3521 struct bgp_process_queue *pqnode;
3522 int pqnode_reuse = 0;
3523
3524 /* already scheduled for processing? */
3525 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3526 return;
3527
3528 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3529 * the workqueue
3530 */
3531 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3532 if (BGP_DEBUG(update, UPDATE_OUT))
3533 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3534 dest);
3535 return;
3536 }
3537
3538 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3539 if (BGP_DEBUG(update, UPDATE_OUT))
3540 zlog_debug(
3541 "Soft reconfigure table in progress for route %p",
3542 dest);
3543 return;
3544 }
3545
3546 if (wq == NULL)
3547 return;
3548
3549 /* Add route nodes to an existing work queue item until reaching the
3550 limit only if is from the same BGP view and it's not an EOIU marker
3551 */
3552 if (work_queue_item_count(wq)) {
3553 struct work_queue_item *item = work_queue_last_item(wq);
3554 pqnode = item->data;
3555
3556 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3557 || pqnode->bgp != bgp
3558 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3559 pqnode = bgp_processq_alloc(bgp);
3560 else
3561 pqnode_reuse = 1;
3562 } else
3563 pqnode = bgp_processq_alloc(bgp);
3564 /* all unlocked in bgp_process_wq */
3565 bgp_table_lock(bgp_dest_table(dest));
3566
3567 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3568 bgp_dest_lock_node(dest);
3569
3570 /* can't be enqueued twice */
3571 assert(STAILQ_NEXT(dest, pq) == NULL);
3572 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3573 pqnode->queued++;
3574
3575 if (!pqnode_reuse)
3576 work_queue_add(wq, pqnode);
3577
3578 return;
3579 }
3580
3581 void bgp_add_eoiu_mark(struct bgp *bgp)
3582 {
3583 struct bgp_process_queue *pqnode;
3584
3585 if (bgp->process_queue == NULL)
3586 return;
3587
3588 pqnode = bgp_processq_alloc(bgp);
3589
3590 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3591 work_queue_add(bgp->process_queue, pqnode);
3592 }
3593
3594 static void bgp_maximum_prefix_restart_timer(struct event *thread)
3595 {
3596 struct peer *peer;
3597
3598 peer = EVENT_ARG(thread);
3599 peer->t_pmax_restart = NULL;
3600
3601 if (bgp_debug_neighbor_events(peer))
3602 zlog_debug(
3603 "%s Maximum-prefix restart timer expired, restore peering",
3604 peer->host);
3605
3606 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3607 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3608 }
3609
3610 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3611 safi_t safi)
3612 {
3613 uint32_t count = 0;
3614 bool filtered = false;
3615 struct bgp_dest *dest;
3616 struct bgp_adj_in *ain;
3617 struct attr attr = {};
3618 struct bgp_table *table = peer->bgp->rib[afi][safi];
3619
3620 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3621 for (ain = dest->adj_in; ain; ain = ain->next) {
3622 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3623
3624 attr = *ain->attr;
3625
3626 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3627 == FILTER_DENY)
3628 filtered = true;
3629
3630 if (bgp_input_modifier(
3631 peer, rn_p, &attr, afi, safi,
3632 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3633 NULL, 0, NULL)
3634 == RMAP_DENY)
3635 filtered = true;
3636
3637 if (filtered)
3638 count++;
3639
3640 bgp_attr_flush(&attr);
3641 }
3642 }
3643
3644 return count;
3645 }
3646
3647 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3648 int always)
3649 {
3650 iana_afi_t pkt_afi;
3651 iana_safi_t pkt_safi;
3652 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3653 PEER_FLAG_MAX_PREFIX_FORCE))
3654 ? bgp_filtered_routes_count(peer, afi, safi)
3655 + peer->pcount[afi][safi]
3656 : peer->pcount[afi][safi];
3657
3658 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3659 return false;
3660
3661 if (pcount > peer->pmax[afi][safi]) {
3662 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3663 PEER_STATUS_PREFIX_LIMIT)
3664 && !always)
3665 return false;
3666
3667 zlog_info(
3668 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3669 get_afi_safi_str(afi, safi, false), peer, pcount,
3670 peer->pmax[afi][safi]);
3671 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3672
3673 if (CHECK_FLAG(peer->af_flags[afi][safi],
3674 PEER_FLAG_MAX_PREFIX_WARNING))
3675 return false;
3676
3677 /* Convert AFI, SAFI to values for packet. */
3678 pkt_afi = afi_int2iana(afi);
3679 pkt_safi = safi_int2iana(safi);
3680 {
3681 uint8_t ndata[7];
3682
3683 ndata[0] = (pkt_afi >> 8);
3684 ndata[1] = pkt_afi;
3685 ndata[2] = pkt_safi;
3686 ndata[3] = (peer->pmax[afi][safi] >> 24);
3687 ndata[4] = (peer->pmax[afi][safi] >> 16);
3688 ndata[5] = (peer->pmax[afi][safi] >> 8);
3689 ndata[6] = (peer->pmax[afi][safi]);
3690
3691 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3692 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3693 BGP_NOTIFY_CEASE_MAX_PREFIX,
3694 ndata, 7);
3695 }
3696
3697 /* Dynamic peers will just close their connection. */
3698 if (peer_dynamic_neighbor(peer))
3699 return true;
3700
3701 /* restart timer start */
3702 if (peer->pmax_restart[afi][safi]) {
3703 peer->v_pmax_restart =
3704 peer->pmax_restart[afi][safi] * 60;
3705
3706 if (bgp_debug_neighbor_events(peer))
3707 zlog_debug(
3708 "%pBP Maximum-prefix restart timer started for %d secs",
3709 peer, peer->v_pmax_restart);
3710
3711 BGP_TIMER_ON(peer->t_pmax_restart,
3712 bgp_maximum_prefix_restart_timer,
3713 peer->v_pmax_restart);
3714 }
3715
3716 return true;
3717 } else
3718 UNSET_FLAG(peer->af_sflags[afi][safi],
3719 PEER_STATUS_PREFIX_LIMIT);
3720
3721 if (pcount
3722 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3723 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3724 PEER_STATUS_PREFIX_THRESHOLD)
3725 && !always)
3726 return false;
3727
3728 zlog_info(
3729 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3730 get_afi_safi_str(afi, safi, false), peer, pcount,
3731 peer->pmax[afi][safi]);
3732 SET_FLAG(peer->af_sflags[afi][safi],
3733 PEER_STATUS_PREFIX_THRESHOLD);
3734 } else
3735 UNSET_FLAG(peer->af_sflags[afi][safi],
3736 PEER_STATUS_PREFIX_THRESHOLD);
3737 return false;
3738 }
3739
3740 /* Unconditionally remove the route from the RIB, without taking
3741 * damping into consideration (eg, because the session went down)
3742 */
3743 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3744 struct peer *peer, afi_t afi, safi_t safi)
3745 {
3746
3747 struct bgp *bgp = NULL;
3748 bool delete_route = false;
3749
3750 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3751 safi);
3752
3753 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3754 bgp_path_info_delete(dest, pi); /* keep historical info */
3755
3756 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3757 * flag
3758 */
3759 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3760 delete_route = true;
3761 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3762 delete_route = true;
3763 if (delete_route) {
3764 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3765 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3766 bgp = pi->peer->bgp;
3767 bgp->gr_info[afi][safi].gr_deferred--;
3768 }
3769 }
3770 }
3771
3772 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3773 bgp_process(peer->bgp, dest, afi, safi);
3774 }
3775
3776 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3777 struct peer *peer, afi_t afi, safi_t safi,
3778 struct prefix_rd *prd)
3779 {
3780 const struct prefix *p = bgp_dest_get_prefix(dest);
3781
3782 /* apply dampening, if result is suppressed, we'll be retaining
3783 * the bgp_path_info in the RIB for historical reference.
3784 */
3785 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3786 && peer->sort == BGP_PEER_EBGP)
3787 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3788 == BGP_DAMP_SUPPRESSED) {
3789 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3790 safi);
3791 return;
3792 }
3793
3794 #ifdef ENABLE_BGP_VNC
3795 if (safi == SAFI_MPLS_VPN) {
3796 struct bgp_dest *pdest = NULL;
3797 struct bgp_table *table = NULL;
3798
3799 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3800 (struct prefix *)prd);
3801 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3802 table = bgp_dest_get_bgp_table_info(pdest);
3803
3804 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3805 peer->bgp, prd, table, p, pi);
3806 }
3807 bgp_dest_unlock_node(pdest);
3808 }
3809 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3810 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3811
3812 vnc_import_bgp_del_route(peer->bgp, p, pi);
3813 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3814 }
3815 }
3816 #endif
3817
3818 /* If this is an EVPN route, process for un-import. */
3819 if (safi == SAFI_EVPN)
3820 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3821
3822 bgp_rib_remove(dest, pi, peer, afi, safi);
3823 }
3824
3825 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3826 struct peer *peer, struct attr *attr,
3827 struct bgp_dest *dest)
3828 {
3829 struct bgp_path_info *new;
3830
3831 /* Make new BGP info. */
3832 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3833 new->type = type;
3834 new->instance = instance;
3835 new->sub_type = sub_type;
3836 new->peer = peer;
3837 new->attr = attr;
3838 new->uptime = monotime(NULL);
3839 new->net = dest;
3840 return new;
3841 }
3842
3843 /* Check if received nexthop is valid or not. */
3844 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3845 uint8_t type, uint8_t stype, struct attr *attr,
3846 struct bgp_dest *dest)
3847 {
3848 bool ret = false;
3849 bool is_bgp_static_route =
3850 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3851 : false;
3852
3853 /* If `bgp allow-martian-nexthop` is turned on, return next-hop
3854 * as good.
3855 */
3856 if (bgp->allow_martian)
3857 return false;
3858
3859 /*
3860 * Only validated for unicast and multicast currently.
3861 * Also valid for EVPN where the nexthop is an IP address.
3862 * If we are a bgp static route being checked then there is
3863 * no need to check to see if the nexthop is martian as
3864 * that it should be ok.
3865 */
3866 if (is_bgp_static_route ||
3867 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3868 return false;
3869
3870 /* If NEXT_HOP is present, validate it. */
3871 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3872 if (attr->nexthop.s_addr == INADDR_ANY ||
3873 !ipv4_unicast_valid(&attr->nexthop) ||
3874 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3875 return true;
3876 }
3877
3878 /* If MP_NEXTHOP is present, validate it. */
3879 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3880 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3881 * it is not an IPv6 link-local address.
3882 *
3883 * If we receive an UPDATE with nexthop length set to 32 bytes
3884 * we shouldn't discard an UPDATE if it's set to (::).
3885 * The link-local (2st) is validated along the code path later.
3886 */
3887 if (attr->mp_nexthop_len) {
3888 switch (attr->mp_nexthop_len) {
3889 case BGP_ATTR_NHLEN_IPV4:
3890 case BGP_ATTR_NHLEN_VPNV4:
3891 ret = (attr->mp_nexthop_global_in.s_addr ==
3892 INADDR_ANY ||
3893 !ipv4_unicast_valid(
3894 &attr->mp_nexthop_global_in) ||
3895 bgp_nexthop_self(bgp, afi, type, stype, attr,
3896 dest));
3897 break;
3898
3899 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3900 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3901 ret = (IN6_IS_ADDR_UNSPECIFIED(
3902 &attr->mp_nexthop_global)
3903 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3904 || IN6_IS_ADDR_MULTICAST(
3905 &attr->mp_nexthop_global)
3906 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3907 dest));
3908 break;
3909 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3910 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3911 || IN6_IS_ADDR_MULTICAST(
3912 &attr->mp_nexthop_global)
3913 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3914 dest));
3915 break;
3916
3917 default:
3918 ret = true;
3919 break;
3920 }
3921 }
3922
3923 return ret;
3924 }
3925
3926 static void bgp_attr_add_no_export_community(struct attr *attr)
3927 {
3928 struct community *old;
3929 struct community *new;
3930 struct community *merge;
3931 struct community *no_export;
3932
3933 old = bgp_attr_get_community(attr);
3934 no_export = community_str2com("no-export");
3935
3936 assert(no_export);
3937
3938 if (old) {
3939 merge = community_merge(community_dup(old), no_export);
3940
3941 if (!old->refcnt)
3942 community_free(&old);
3943
3944 new = community_uniq_sort(merge);
3945 community_free(&merge);
3946 } else {
3947 new = community_dup(no_export);
3948 }
3949
3950 community_free(&no_export);
3951
3952 bgp_attr_set_community(attr, new);
3953 }
3954
3955 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3956 struct attr *attr, const struct prefix *prefix,
3957 int *sub_type)
3958 {
3959 struct listnode *node, *nnode;
3960 struct bgp *bgp;
3961 bool accept_own_found = false;
3962
3963 if (safi != SAFI_MPLS_VPN)
3964 return false;
3965
3966 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3967 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3968 return false;
3969
3970 /* The route in question carries the ACCEPT_OWN community */
3971 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3972 struct community *comm = bgp_attr_get_community(attr);
3973
3974 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3975 accept_own_found = true;
3976 }
3977
3978 /* The route in question is targeted to one or more destination VRFs
3979 * on the router (as determined by inspecting the Route Target(s)).
3980 */
3981 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3982 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3983 continue;
3984
3985 if (accept_own_found &&
3986 ecommunity_include(
3987 bgp->vpn_policy[afi]
3988 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3989 bgp_attr_get_ecommunity(attr))) {
3990 if (bgp_debug_update(peer, prefix, NULL, 1))
3991 zlog_debug(
3992 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3993 peer, prefix);
3994
3995 /* Treat this route as imported, because it's leaked
3996 * already from another VRF, and we got an updated
3997 * version from route-reflector with ACCEPT_OWN
3998 * community.
3999 */
4000 *sub_type = BGP_ROUTE_IMPORTED;
4001
4002 return true;
4003 }
4004 }
4005
4006 return false;
4007 }
4008
4009 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4010 struct attr *attr, afi_t afi, safi_t safi, int type,
4011 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4012 uint32_t num_labels, int soft_reconfig,
4013 struct bgp_route_evpn *evpn)
4014 {
4015 int ret;
4016 int aspath_loop_count = 0;
4017 struct bgp_dest *dest;
4018 struct bgp *bgp;
4019 struct attr new_attr;
4020 struct attr *attr_new;
4021 struct bgp_path_info *pi;
4022 struct bgp_path_info *new = NULL;
4023 struct bgp_path_info_extra *extra;
4024 const char *reason;
4025 char pfx_buf[BGP_PRD_PATH_STRLEN];
4026 int connected = 0;
4027 int do_loop_check = 1;
4028 int has_valid_label = 0;
4029 afi_t nh_afi;
4030 bool force_evpn_import = false;
4031 safi_t orig_safi = safi;
4032 bool leak_success = true;
4033 int allowas_in = 0;
4034
4035 if (frrtrace_enabled(frr_bgp, process_update)) {
4036 char pfxprint[PREFIX2STR_BUFFER];
4037
4038 prefix2str(p, pfxprint, sizeof(pfxprint));
4039 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4040 afi, safi, attr);
4041 }
4042
4043 #ifdef ENABLE_BGP_VNC
4044 int vnc_implicit_withdraw = 0;
4045 #endif
4046 int same_attr = 0;
4047 const struct prefix *bgp_nht_param_prefix;
4048
4049 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4050 if (orig_safi == SAFI_LABELED_UNICAST)
4051 safi = SAFI_UNICAST;
4052
4053 memset(&new_attr, 0, sizeof(new_attr));
4054 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4055 new_attr.label = MPLS_INVALID_LABEL;
4056
4057 bgp = peer->bgp;
4058 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4059 /* TODO: Check to see if we can get rid of "is_valid_label" */
4060 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4061 has_valid_label = (num_labels > 0) ? 1 : 0;
4062 else
4063 has_valid_label = bgp_is_valid_label(label);
4064
4065 if (has_valid_label)
4066 assert(label != NULL);
4067
4068
4069 /* When peer's soft reconfiguration enabled. Record input packet in
4070 Adj-RIBs-In. */
4071 if (!soft_reconfig &&
4072 CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG) &&
4073 peer != bgp->peer_self) {
4074 /*
4075 * If the trigger is not from soft_reconfig and if
4076 * PEER_FLAG_SOFT_RECONFIG is enabled for the peer, then attr
4077 * will not be interned. In which case, it is ok to update the
4078 * attr->evpn_overlay, so that, this can be stored in adj_in.
4079 */
4080 if ((afi == AFI_L2VPN) && evpn) {
4081 memcpy(&attr->evpn_overlay, evpn,
4082 sizeof(struct bgp_route_evpn));
4083 }
4084 bgp_adj_in_set(dest, peer, attr, addpath_id);
4085 }
4086
4087 /* Update permitted loop count */
4088 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4089 allowas_in = peer->allowas_in[afi][safi];
4090
4091 /* Check previously received route. */
4092 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4093 if (pi->peer == peer && pi->type == type
4094 && pi->sub_type == sub_type
4095 && pi->addpath_rx_id == addpath_id)
4096 break;
4097
4098 /* AS path local-as loop check. */
4099 if (peer->change_local_as) {
4100 if (allowas_in)
4101 aspath_loop_count = allowas_in;
4102 else if (!CHECK_FLAG(peer->flags,
4103 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4104 aspath_loop_count = 1;
4105
4106 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4107 > aspath_loop_count) {
4108 peer->stat_pfx_aspath_loop++;
4109 reason = "as-path contains our own AS;";
4110 goto filtered;
4111 }
4112 }
4113
4114 /* If the peer is configured for "allowas-in origin" and the last ASN in
4115 * the
4116 * as-path is our ASN then we do not need to call aspath_loop_check
4117 */
4118 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4119 if (aspath_get_last_as(attr->aspath) == bgp->as)
4120 do_loop_check = 0;
4121
4122 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4123 bgp_nht_param_prefix = NULL;
4124 else
4125 bgp_nht_param_prefix = p;
4126
4127 /* AS path loop check. */
4128 if (do_loop_check) {
4129 if (aspath_loop_check(attr->aspath, bgp->as) >
4130 peer->allowas_in[afi][safi]) {
4131 peer->stat_pfx_aspath_loop++;
4132 reason = "as-path contains our own AS;";
4133 goto filtered;
4134 }
4135 }
4136
4137 /* If we're a CONFED we need to loop check the CONFED ID too */
4138 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4139 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4140 peer->allowas_in[afi][safi]) {
4141 peer->stat_pfx_aspath_loop++;
4142 reason = "as-path contains our own confed AS;";
4143 goto filtered;
4144 }
4145
4146 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4147 * enabled, then take care of that too.
4148 */
4149 bool accept_own = false;
4150
4151 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4152 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4153 accept_own =
4154 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4155 if (!accept_own) {
4156 peer->stat_pfx_originator_loop++;
4157 reason = "originator is us;";
4158 goto filtered;
4159 }
4160 }
4161
4162 /* Route reflector cluster ID check. */
4163 if (bgp_cluster_filter(peer, attr)) {
4164 peer->stat_pfx_cluster_loop++;
4165 reason = "reflected from the same cluster;";
4166 goto filtered;
4167 }
4168
4169 /* Apply incoming filter. */
4170 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4171 peer->stat_pfx_filter++;
4172 reason = "filter;";
4173 goto filtered;
4174 }
4175
4176 /* If the route has Node Target Extended Communities, check
4177 * if it's allowed to be installed locally.
4178 */
4179 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4180 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
4181
4182 if (ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
4183 ECOMMUNITY_NODE_TARGET) &&
4184 !ecommunity_node_target_match(ecomm, &peer->local_id)) {
4185 reason =
4186 "Node-Target Extended Communities do not contain own BGP Identifier;";
4187 goto filtered;
4188 }
4189 }
4190
4191 /* RFC 8212 to prevent route leaks.
4192 * This specification intends to improve this situation by requiring the
4193 * explicit configuration of both BGP Import and Export Policies for any
4194 * External BGP (EBGP) session such as customers, peers, or
4195 * confederation boundaries for all enabled address families. Through
4196 * codification of the aforementioned requirement, operators will
4197 * benefit from consistent behavior across different BGP
4198 * implementations.
4199 */
4200 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4201 if (!bgp_inbound_policy_exists(peer,
4202 &peer->filter[afi][safi])) {
4203 reason = "inbound policy missing";
4204 if (monotime_since(&bgp->ebgprequirespolicywarning,
4205 NULL) > FIFTEENMINUTE2USEC ||
4206 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4207 zlog_warn(
4208 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4209 monotime(&bgp->ebgprequirespolicywarning);
4210 }
4211 goto filtered;
4212 }
4213
4214 /* draft-ietf-idr-deprecate-as-set-confed-set
4215 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4216 * Eventually, This document (if approved) updates RFC 4271
4217 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4218 * and obsoletes RFC 6472.
4219 */
4220 if (peer->bgp->reject_as_sets)
4221 if (aspath_check_as_sets(attr->aspath)) {
4222 reason =
4223 "as-path contains AS_SET or AS_CONFED_SET type;";
4224 goto filtered;
4225 }
4226
4227 new_attr = *attr;
4228 /*
4229 * If bgp_update is called with soft_reconfig set then
4230 * attr is interned. In this case, do not overwrite the
4231 * attr->evpn_overlay with evpn directly. Instead memcpy
4232 * evpn to new_atr.evpn_overlay before it is interned.
4233 */
4234 if (soft_reconfig && (afi == AFI_L2VPN) && evpn)
4235 memcpy(&new_attr.evpn_overlay, evpn,
4236 sizeof(struct bgp_route_evpn));
4237
4238 /* Apply incoming route-map.
4239 * NB: new_attr may now contain newly allocated values from route-map
4240 * "set"
4241 * commands, so we need bgp_attr_flush in the error paths, until we
4242 * intern
4243 * the attr (which takes over the memory references) */
4244 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4245 num_labels, dest)
4246 == RMAP_DENY) {
4247 peer->stat_pfx_filter++;
4248 reason = "route-map;";
4249 bgp_attr_flush(&new_attr);
4250 goto filtered;
4251 }
4252
4253 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4254 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4255 /* remove from RIB previous entry */
4256 bgp_zebra_withdraw(p, pi, bgp, safi);
4257 }
4258
4259 if (peer->sort == BGP_PEER_EBGP) {
4260
4261 /* rfc7999:
4262 * A BGP speaker receiving an announcement tagged with the
4263 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4264 * NO_EXPORT community as defined in RFC1997, or a
4265 * similar community, to prevent propagation of the
4266 * prefix outside the local AS. The community to prevent
4267 * propagation SHOULD be chosen according to the operator's
4268 * routing policy.
4269 */
4270 if (bgp_attr_get_community(&new_attr) &&
4271 community_include(bgp_attr_get_community(&new_attr),
4272 COMMUNITY_BLACKHOLE))
4273 bgp_attr_add_no_export_community(&new_attr);
4274
4275 /* If we receive the graceful-shutdown community from an eBGP
4276 * peer we must lower local-preference */
4277 if (bgp_attr_get_community(&new_attr) &&
4278 community_include(bgp_attr_get_community(&new_attr),
4279 COMMUNITY_GSHUT)) {
4280 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4281 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4282
4283 /* If graceful-shutdown is configured globally or
4284 * per neighbor, then add the GSHUT community to
4285 * all paths received from eBGP peers. */
4286 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4287 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4288 bgp_attr_add_gshut_community(&new_attr);
4289 }
4290
4291 /* next hop check. */
4292 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4293 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4294 &new_attr, dest)) {
4295 peer->stat_pfx_nh_invalid++;
4296 reason = "martian or self next-hop;";
4297 bgp_attr_flush(&new_attr);
4298 goto filtered;
4299 }
4300
4301 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4302 peer->stat_pfx_nh_invalid++;
4303 reason = "self mac;";
4304 bgp_attr_flush(&new_attr);
4305 goto filtered;
4306 }
4307
4308 if (bgp_check_role_applicability(afi, safi) &&
4309 bgp_otc_filter(peer, &new_attr)) {
4310 reason = "failing otc validation";
4311 bgp_attr_flush(&new_attr);
4312 goto filtered;
4313 }
4314
4315 /* If neighbor soo is configured, tag all incoming routes with
4316 * this SoO tag and then filter out advertisements in
4317 * subgroup_announce_check() if it matches the configured SoO
4318 * on the other peer.
4319 */
4320 if (peer->soo[afi][safi]) {
4321 struct ecommunity *old_ecomm =
4322 bgp_attr_get_ecommunity(&new_attr);
4323 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4324 struct ecommunity *new_ecomm;
4325
4326 if (old_ecomm) {
4327 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4328 ecomm_soo);
4329
4330 if (!old_ecomm->refcnt)
4331 ecommunity_free(&old_ecomm);
4332 } else {
4333 new_ecomm = ecommunity_dup(ecomm_soo);
4334 }
4335
4336 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4337 }
4338
4339 attr_new = bgp_attr_intern(&new_attr);
4340
4341 /* If the update is implicit withdraw. */
4342 if (pi) {
4343 pi->uptime = monotime(NULL);
4344 same_attr = attrhash_cmp(pi->attr, attr_new);
4345
4346 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4347
4348 /* Same attribute comes in. */
4349 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4350 && same_attr
4351 && (!has_valid_label
4352 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4353 num_labels * sizeof(mpls_label_t))
4354 == 0)) {
4355 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4356 BGP_CONFIG_DAMPENING)
4357 && peer->sort == BGP_PEER_EBGP
4358 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4359 if (bgp_debug_update(peer, p, NULL, 1)) {
4360 bgp_debug_rdpfxpath2str(
4361 afi, safi, prd, p, label,
4362 num_labels, addpath_id ? 1 : 0,
4363 addpath_id, evpn, pfx_buf,
4364 sizeof(pfx_buf));
4365 zlog_debug("%pBP rcvd %s", peer,
4366 pfx_buf);
4367 }
4368
4369 if (bgp_damp_update(pi, dest, afi, safi)
4370 != BGP_DAMP_SUPPRESSED) {
4371 bgp_aggregate_increment(bgp, p, pi, afi,
4372 safi);
4373 bgp_process(bgp, dest, afi, safi);
4374 }
4375 } else /* Duplicate - odd */
4376 {
4377 if (bgp_debug_update(peer, p, NULL, 1)) {
4378 if (!peer->rcvd_attr_printed) {
4379 zlog_debug(
4380 "%pBP rcvd UPDATE w/ attr: %s",
4381 peer,
4382 peer->rcvd_attr_str);
4383 peer->rcvd_attr_printed = 1;
4384 }
4385
4386 bgp_debug_rdpfxpath2str(
4387 afi, safi, prd, p, label,
4388 num_labels, addpath_id ? 1 : 0,
4389 addpath_id, evpn, pfx_buf,
4390 sizeof(pfx_buf));
4391 zlog_debug(
4392 "%pBP rcvd %s...duplicate ignored",
4393 peer, pfx_buf);
4394 }
4395
4396 /* graceful restart STALE flag unset. */
4397 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4398 bgp_path_info_unset_flag(
4399 dest, pi, BGP_PATH_STALE);
4400 bgp_dest_set_defer_flag(dest, false);
4401 bgp_process(bgp, dest, afi, safi);
4402 }
4403 }
4404
4405 bgp_dest_unlock_node(dest);
4406 bgp_attr_unintern(&attr_new);
4407
4408 return;
4409 }
4410
4411 /* Withdraw/Announce before we fully processed the withdraw */
4412 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4413 if (bgp_debug_update(peer, p, NULL, 1)) {
4414 bgp_debug_rdpfxpath2str(
4415 afi, safi, prd, p, label, num_labels,
4416 addpath_id ? 1 : 0, addpath_id, evpn,
4417 pfx_buf, sizeof(pfx_buf));
4418 zlog_debug(
4419 "%pBP rcvd %s, flapped quicker than processing",
4420 peer, pfx_buf);
4421 }
4422
4423 bgp_path_info_restore(dest, pi);
4424
4425 /*
4426 * If the BGP_PATH_REMOVED flag is set, then EVPN
4427 * routes would have been unimported already when a
4428 * prior BGP withdraw processing happened. Such routes
4429 * need to be imported again, so flag accordingly.
4430 */
4431 force_evpn_import = true;
4432 } else {
4433 /* implicit withdraw, decrement aggregate and pcount
4434 * here. only if update is accepted, they'll increment
4435 * below.
4436 */
4437 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4438 }
4439
4440 /* Received Logging. */
4441 if (bgp_debug_update(peer, p, NULL, 1)) {
4442 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4443 num_labels, addpath_id ? 1 : 0,
4444 addpath_id, evpn, pfx_buf,
4445 sizeof(pfx_buf));
4446 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4447 }
4448
4449 /* graceful restart STALE flag unset. */
4450 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4451 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4452 bgp_dest_set_defer_flag(dest, false);
4453 }
4454
4455 /* The attribute is changed. */
4456 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4457
4458 /* Update bgp route dampening information. */
4459 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4460 && peer->sort == BGP_PEER_EBGP) {
4461 /* This is implicit withdraw so we should update
4462 dampening
4463 information. */
4464 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4465 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4466 }
4467 #ifdef ENABLE_BGP_VNC
4468 if (safi == SAFI_MPLS_VPN) {
4469 struct bgp_dest *pdest = NULL;
4470 struct bgp_table *table = NULL;
4471
4472 pdest = bgp_node_get(bgp->rib[afi][safi],
4473 (struct prefix *)prd);
4474 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4475 table = bgp_dest_get_bgp_table_info(pdest);
4476
4477 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4478 bgp, prd, table, p, pi);
4479 }
4480 bgp_dest_unlock_node(pdest);
4481 }
4482 if ((afi == AFI_IP || afi == AFI_IP6)
4483 && (safi == SAFI_UNICAST)) {
4484 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4485 /*
4486 * Implicit withdraw case.
4487 */
4488 ++vnc_implicit_withdraw;
4489 vnc_import_bgp_del_route(bgp, p, pi);
4490 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4491 }
4492 }
4493 #endif
4494
4495 /* Special handling for EVPN update of an existing route. If the
4496 * extended community attribute has changed, we need to
4497 * un-import
4498 * the route using its existing extended community. It will be
4499 * subsequently processed for import with the new extended
4500 * community.
4501 */
4502 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4503 && !same_attr) {
4504 if ((pi->attr->flag
4505 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4506 && (attr_new->flag
4507 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4508 int cmp;
4509
4510 cmp = ecommunity_cmp(
4511 bgp_attr_get_ecommunity(pi->attr),
4512 bgp_attr_get_ecommunity(attr_new));
4513 if (!cmp) {
4514 if (bgp_debug_update(peer, p, NULL, 1))
4515 zlog_debug(
4516 "Change in EXT-COMM, existing %s new %s",
4517 ecommunity_str(
4518 bgp_attr_get_ecommunity(
4519 pi->attr)),
4520 ecommunity_str(
4521 bgp_attr_get_ecommunity(
4522 attr_new)));
4523 if (safi == SAFI_EVPN)
4524 bgp_evpn_unimport_route(
4525 bgp, afi, safi, p, pi);
4526 else /* SAFI_MPLS_VPN */
4527 vpn_leak_to_vrf_withdraw(pi);
4528 }
4529 }
4530 }
4531
4532 /* Update to new attribute. */
4533 bgp_attr_unintern(&pi->attr);
4534 pi->attr = attr_new;
4535
4536 /* Update MPLS label */
4537 if (has_valid_label) {
4538 extra = bgp_path_info_extra_get(pi);
4539 if (extra->label != label) {
4540 memcpy(&extra->label, label,
4541 num_labels * sizeof(mpls_label_t));
4542 extra->num_labels = num_labels;
4543 }
4544 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4545 bgp_set_valid_label(&extra->label[0]);
4546 }
4547
4548 /* Update SRv6 SID */
4549 if (attr->srv6_l3vpn) {
4550 extra = bgp_path_info_extra_get(pi);
4551 if (sid_diff(&extra->sid[0].sid,
4552 &attr->srv6_l3vpn->sid)) {
4553 sid_copy(&extra->sid[0].sid,
4554 &attr->srv6_l3vpn->sid);
4555 extra->num_sids = 1;
4556
4557 extra->sid[0].loc_block_len = 0;
4558 extra->sid[0].loc_node_len = 0;
4559 extra->sid[0].func_len = 0;
4560 extra->sid[0].arg_len = 0;
4561 extra->sid[0].transposition_len = 0;
4562 extra->sid[0].transposition_offset = 0;
4563
4564 if (attr->srv6_l3vpn->loc_block_len != 0) {
4565 extra->sid[0].loc_block_len =
4566 attr->srv6_l3vpn->loc_block_len;
4567 extra->sid[0].loc_node_len =
4568 attr->srv6_l3vpn->loc_node_len;
4569 extra->sid[0].func_len =
4570 attr->srv6_l3vpn->func_len;
4571 extra->sid[0].arg_len =
4572 attr->srv6_l3vpn->arg_len;
4573 extra->sid[0].transposition_len =
4574 attr->srv6_l3vpn
4575 ->transposition_len;
4576 extra->sid[0].transposition_offset =
4577 attr->srv6_l3vpn
4578 ->transposition_offset;
4579 }
4580 }
4581 } else if (attr->srv6_vpn) {
4582 extra = bgp_path_info_extra_get(pi);
4583 if (sid_diff(&extra->sid[0].sid,
4584 &attr->srv6_vpn->sid)) {
4585 sid_copy(&extra->sid[0].sid,
4586 &attr->srv6_vpn->sid);
4587 extra->num_sids = 1;
4588 }
4589 }
4590
4591 #ifdef ENABLE_BGP_VNC
4592 if ((afi == AFI_IP || afi == AFI_IP6)
4593 && (safi == SAFI_UNICAST)) {
4594 if (vnc_implicit_withdraw) {
4595 /*
4596 * Add back the route with its new attributes
4597 * (e.g., nexthop).
4598 * The route is still selected, until the route
4599 * selection
4600 * queued by bgp_process actually runs. We have
4601 * to make this
4602 * update to the VNC side immediately to avoid
4603 * racing against
4604 * configuration changes (e.g., route-map
4605 * changes) which
4606 * trigger re-importation of the entire RIB.
4607 */
4608 vnc_import_bgp_add_route(bgp, p, pi);
4609 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4610 }
4611 }
4612 #endif
4613
4614 /* Update bgp route dampening information. */
4615 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4616 && peer->sort == BGP_PEER_EBGP) {
4617 /* Now we do normal update dampening. */
4618 ret = bgp_damp_update(pi, dest, afi, safi);
4619 if (ret == BGP_DAMP_SUPPRESSED) {
4620 bgp_dest_unlock_node(dest);
4621 return;
4622 }
4623 }
4624
4625 /* Nexthop reachability check - for unicast and
4626 * labeled-unicast.. */
4627 if (((afi == AFI_IP || afi == AFI_IP6)
4628 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4629 || (safi == SAFI_EVPN &&
4630 bgp_evpn_is_prefix_nht_supported(p))) {
4631 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4632 && peer->ttl == BGP_DEFAULT_TTL
4633 && !CHECK_FLAG(peer->flags,
4634 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4635 && !CHECK_FLAG(bgp->flags,
4636 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4637 connected = 1;
4638 else
4639 connected = 0;
4640
4641 struct bgp *bgp_nexthop = bgp;
4642
4643 if (pi->extra && pi->extra->bgp_orig)
4644 bgp_nexthop = pi->extra->bgp_orig;
4645
4646 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4647
4648 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4649 safi, pi, NULL, connected,
4650 bgp_nht_param_prefix) ||
4651 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4652 bgp_path_info_set_flag(dest, pi,
4653 BGP_PATH_VALID);
4654 else {
4655 if (BGP_DEBUG(nht, NHT)) {
4656 zlog_debug("%s(%pI4): NH unresolved",
4657 __func__,
4658 (in_addr_t *)&attr_new->nexthop);
4659 }
4660 bgp_path_info_unset_flag(dest, pi,
4661 BGP_PATH_VALID);
4662 }
4663 } else {
4664 if (accept_own)
4665 bgp_path_info_set_flag(dest, pi,
4666 BGP_PATH_ACCEPT_OWN);
4667
4668 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4669 }
4670
4671 #ifdef ENABLE_BGP_VNC
4672 if (safi == SAFI_MPLS_VPN) {
4673 struct bgp_dest *pdest = NULL;
4674 struct bgp_table *table = NULL;
4675
4676 pdest = bgp_node_get(bgp->rib[afi][safi],
4677 (struct prefix *)prd);
4678 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4679 table = bgp_dest_get_bgp_table_info(pdest);
4680
4681 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4682 bgp, prd, table, p, pi);
4683 }
4684 bgp_dest_unlock_node(pdest);
4685 }
4686 #endif
4687
4688 /* If this is an EVPN route and some attribute has changed,
4689 * or we are explicitly told to perform a route import, process
4690 * route for import. If the extended community has changed, we
4691 * would
4692 * have done the un-import earlier and the import would result
4693 * in the
4694 * route getting injected into appropriate L2 VNIs. If it is
4695 * just
4696 * some other attribute change, the import will result in
4697 * updating
4698 * the attributes for the route in the VNI(s).
4699 */
4700 if (safi == SAFI_EVPN &&
4701 (!same_attr || force_evpn_import) &&
4702 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4703 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4704
4705 /* Process change. */
4706 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4707
4708 bgp_process(bgp, dest, afi, safi);
4709 bgp_dest_unlock_node(dest);
4710
4711 if (SAFI_UNICAST == safi
4712 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4713 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4714
4715 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4716 }
4717 if ((SAFI_MPLS_VPN == safi)
4718 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4719 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4720 }
4721
4722 #ifdef ENABLE_BGP_VNC
4723 if (SAFI_MPLS_VPN == safi) {
4724 mpls_label_t label_decoded = decode_label(label);
4725
4726 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4727 type, sub_type, &label_decoded);
4728 }
4729 if (SAFI_ENCAP == safi) {
4730 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4731 type, sub_type, NULL);
4732 }
4733 #endif
4734 if ((safi == SAFI_MPLS_VPN) &&
4735 !CHECK_FLAG(bgp->af_flags[afi][safi],
4736 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4737 !leak_success) {
4738 bgp_unlink_nexthop(pi);
4739 bgp_path_info_delete(dest, pi);
4740 }
4741 return;
4742 } // End of implicit withdraw
4743
4744 /* Received Logging. */
4745 if (bgp_debug_update(peer, p, NULL, 1)) {
4746 if (!peer->rcvd_attr_printed) {
4747 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4748 peer->rcvd_attr_str);
4749 peer->rcvd_attr_printed = 1;
4750 }
4751
4752 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4753 addpath_id ? 1 : 0, addpath_id, evpn,
4754 pfx_buf, sizeof(pfx_buf));
4755 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4756 }
4757
4758 /* Make new BGP info. */
4759 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4760
4761 /* Update MPLS label */
4762 if (has_valid_label) {
4763 extra = bgp_path_info_extra_get(new);
4764 if (extra->label != label) {
4765 memcpy(&extra->label, label,
4766 num_labels * sizeof(mpls_label_t));
4767 extra->num_labels = num_labels;
4768 }
4769 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4770 bgp_set_valid_label(&extra->label[0]);
4771 }
4772
4773 /* Update SRv6 SID */
4774 if (safi == SAFI_MPLS_VPN) {
4775 extra = bgp_path_info_extra_get(new);
4776 if (attr->srv6_l3vpn) {
4777 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4778 extra->num_sids = 1;
4779
4780 extra->sid[0].loc_block_len =
4781 attr->srv6_l3vpn->loc_block_len;
4782 extra->sid[0].loc_node_len =
4783 attr->srv6_l3vpn->loc_node_len;
4784 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4785 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4786 extra->sid[0].transposition_len =
4787 attr->srv6_l3vpn->transposition_len;
4788 extra->sid[0].transposition_offset =
4789 attr->srv6_l3vpn->transposition_offset;
4790 } else if (attr->srv6_vpn) {
4791 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4792 extra->num_sids = 1;
4793 }
4794 }
4795
4796 /* Nexthop reachability check. */
4797 if (((afi == AFI_IP || afi == AFI_IP6)
4798 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4799 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4800 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4801 && peer->ttl == BGP_DEFAULT_TTL
4802 && !CHECK_FLAG(peer->flags,
4803 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4804 && !CHECK_FLAG(bgp->flags,
4805 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4806 connected = 1;
4807 else
4808 connected = 0;
4809
4810 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4811
4812 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4813 connected, bgp_nht_param_prefix) ||
4814 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4815 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4816 else {
4817 if (BGP_DEBUG(nht, NHT))
4818 zlog_debug("%s(%pI4): NH unresolved", __func__,
4819 &attr_new->nexthop);
4820 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4821 }
4822 } else {
4823 if (accept_own)
4824 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4825
4826 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4827 }
4828
4829 /* If maximum prefix count is configured and current prefix
4830 * count exeed it.
4831 */
4832 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4833 reason = "maximum-prefix overflow";
4834 bgp_attr_flush(&new_attr);
4835 goto filtered;
4836 }
4837
4838 /* Addpath ID */
4839 new->addpath_rx_id = addpath_id;
4840
4841 /* Increment prefix */
4842 bgp_aggregate_increment(bgp, p, new, afi, safi);
4843
4844 /* Register new BGP information. */
4845 bgp_path_info_add(dest, new);
4846
4847 /* route_node_get lock */
4848 bgp_dest_unlock_node(dest);
4849
4850 #ifdef ENABLE_BGP_VNC
4851 if (safi == SAFI_MPLS_VPN) {
4852 struct bgp_dest *pdest = NULL;
4853 struct bgp_table *table = NULL;
4854
4855 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4856 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4857 table = bgp_dest_get_bgp_table_info(pdest);
4858
4859 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4860 bgp, prd, table, p, new);
4861 }
4862 bgp_dest_unlock_node(pdest);
4863 }
4864 #endif
4865
4866 /* If this is an EVPN route, process for import. */
4867 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4868 bgp_evpn_import_route(bgp, afi, safi, p, new);
4869
4870 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4871
4872 /* Process change. */
4873 bgp_process(bgp, dest, afi, safi);
4874
4875 if (SAFI_UNICAST == safi
4876 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4877 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4878 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4879 }
4880 if ((SAFI_MPLS_VPN == safi)
4881 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4882 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4883 }
4884 #ifdef ENABLE_BGP_VNC
4885 if (SAFI_MPLS_VPN == safi) {
4886 mpls_label_t label_decoded = decode_label(label);
4887
4888 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4889 sub_type, &label_decoded);
4890 }
4891 if (SAFI_ENCAP == safi) {
4892 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4893 sub_type, NULL);
4894 }
4895 #endif
4896 if ((safi == SAFI_MPLS_VPN) &&
4897 !CHECK_FLAG(bgp->af_flags[afi][safi],
4898 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4899 !leak_success) {
4900 bgp_unlink_nexthop(new);
4901 bgp_path_info_delete(dest, new);
4902 }
4903
4904 return;
4905
4906 /* This BGP update is filtered. Log the reason then update BGP
4907 entry. */
4908 filtered:
4909 if (new) {
4910 bgp_unlink_nexthop(new);
4911 bgp_path_info_delete(dest, new);
4912 bgp_path_info_extra_free(&new->extra);
4913 XFREE(MTYPE_BGP_ROUTE, new);
4914 }
4915
4916 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4917
4918 if (bgp_debug_update(peer, p, NULL, 1)) {
4919 if (!peer->rcvd_attr_printed) {
4920 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4921 peer->rcvd_attr_str);
4922 peer->rcvd_attr_printed = 1;
4923 }
4924
4925 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4926 addpath_id ? 1 : 0, addpath_id, evpn,
4927 pfx_buf, sizeof(pfx_buf));
4928 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4929 peer, pfx_buf, reason);
4930 }
4931
4932 if (pi) {
4933 /* If this is an EVPN route, un-import it as it is now filtered.
4934 */
4935 if (safi == SAFI_EVPN)
4936 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4937
4938 if (SAFI_UNICAST == safi
4939 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4940 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4941
4942 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4943 }
4944 if ((SAFI_MPLS_VPN == safi)
4945 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4946
4947 vpn_leak_to_vrf_withdraw(pi);
4948 }
4949
4950 bgp_rib_remove(dest, pi, peer, afi, safi);
4951 }
4952
4953 bgp_dest_unlock_node(dest);
4954
4955 #ifdef ENABLE_BGP_VNC
4956 /*
4957 * Filtered update is treated as an implicit withdrawal (see
4958 * bgp_rib_remove()
4959 * a few lines above)
4960 */
4961 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4962 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4963 0);
4964 }
4965 #endif
4966
4967 return;
4968 }
4969
4970 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4971 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4972 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4973 uint32_t num_labels, struct bgp_route_evpn *evpn)
4974 {
4975 struct bgp *bgp;
4976 char pfx_buf[BGP_PRD_PATH_STRLEN];
4977 struct bgp_dest *dest;
4978 struct bgp_path_info *pi;
4979
4980 #ifdef ENABLE_BGP_VNC
4981 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4982 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4983 0);
4984 }
4985 #endif
4986
4987 bgp = peer->bgp;
4988
4989 /* Lookup node. */
4990 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4991
4992 /* If peer is soft reconfiguration enabled. Record input packet for
4993 * further calculation.
4994 *
4995 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4996 * routes that are filtered. This tanks out Quagga RS pretty badly due
4997 * to
4998 * the iteration over all RS clients.
4999 * Since we need to remove the entry from adj_in anyway, do that first
5000 * and
5001 * if there was no entry, we don't need to do anything more.
5002 */
5003 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
5004 && peer != bgp->peer_self)
5005 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
5006 peer->stat_pfx_dup_withdraw++;
5007
5008 if (bgp_debug_update(peer, p, NULL, 1)) {
5009 bgp_debug_rdpfxpath2str(
5010 afi, safi, prd, p, label, num_labels,
5011 addpath_id ? 1 : 0, addpath_id, NULL,
5012 pfx_buf, sizeof(pfx_buf));
5013 zlog_debug(
5014 "%s withdrawing route %s not in adj-in",
5015 peer->host, pfx_buf);
5016 }
5017 bgp_dest_unlock_node(dest);
5018 return;
5019 }
5020
5021 /* Lookup withdrawn route. */
5022 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5023 if (pi->peer == peer && pi->type == type
5024 && pi->sub_type == sub_type
5025 && pi->addpath_rx_id == addpath_id)
5026 break;
5027
5028 /* Logging. */
5029 if (bgp_debug_update(peer, p, NULL, 1)) {
5030 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5031 addpath_id ? 1 : 0, addpath_id, NULL,
5032 pfx_buf, sizeof(pfx_buf));
5033 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
5034 pfx_buf);
5035 }
5036
5037 /* Withdraw specified route from routing table. */
5038 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
5039 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
5040 if (SAFI_UNICAST == safi
5041 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5042 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5043 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5044 }
5045 if ((SAFI_MPLS_VPN == safi)
5046 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5047
5048 vpn_leak_to_vrf_withdraw(pi);
5049 }
5050 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5051 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5052 addpath_id ? 1 : 0, addpath_id, NULL,
5053 pfx_buf, sizeof(pfx_buf));
5054 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5055 }
5056
5057 /* Unlock bgp_node_get() lock. */
5058 bgp_dest_unlock_node(dest);
5059
5060 return;
5061 }
5062
5063 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5064 int withdraw)
5065 {
5066 struct update_subgroup *subgrp;
5067 subgrp = peer_subgroup(peer, afi, safi);
5068 subgroup_default_originate(subgrp, withdraw);
5069 }
5070
5071
5072 /*
5073 * bgp_stop_announce_route_timer
5074 */
5075 void bgp_stop_announce_route_timer(struct peer_af *paf)
5076 {
5077 if (!paf->t_announce_route)
5078 return;
5079
5080 EVENT_OFF(paf->t_announce_route);
5081 }
5082
5083 /*
5084 * bgp_announce_route_timer_expired
5085 *
5086 * Callback that is invoked when the route announcement timer for a
5087 * peer_af expires.
5088 */
5089 static void bgp_announce_route_timer_expired(struct event *t)
5090 {
5091 struct peer_af *paf;
5092 struct peer *peer;
5093
5094 paf = EVENT_ARG(t);
5095 peer = paf->peer;
5096
5097 if (!peer_established(peer))
5098 return;
5099
5100 if (!peer->afc_nego[paf->afi][paf->safi])
5101 return;
5102
5103 peer_af_announce_route(paf, 1);
5104
5105 /* Notify BGP conditional advertisement scanner percess */
5106 peer->advmap_config_change[paf->afi][paf->safi] = true;
5107 }
5108
5109 /*
5110 * bgp_announce_route
5111 *
5112 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5113 *
5114 * if force is true we will force an update even if the update
5115 * limiting code is attempted to kick in.
5116 */
5117 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5118 {
5119 struct peer_af *paf;
5120 struct update_subgroup *subgrp;
5121
5122 paf = peer_af_find(peer, afi, safi);
5123 if (!paf)
5124 return;
5125 subgrp = PAF_SUBGRP(paf);
5126
5127 /*
5128 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5129 * or a refresh has already been triggered.
5130 */
5131 if (!subgrp || paf->t_announce_route)
5132 return;
5133
5134 if (force)
5135 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5136
5137 /*
5138 * Start a timer to stagger/delay the announce. This serves
5139 * two purposes - announcement can potentially be combined for
5140 * multiple peers and the announcement doesn't happen in the
5141 * vty context.
5142 */
5143 event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5144 (subgrp->peer_count == 1)
5145 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5146 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5147 &paf->t_announce_route);
5148 }
5149
5150 /*
5151 * Announce routes from all AF tables to a peer.
5152 *
5153 * This should ONLY be called when there is a need to refresh the
5154 * routes to the peer based on a policy change for this peer alone
5155 * or a route refresh request received from the peer.
5156 * The operation will result in splitting the peer from its existing
5157 * subgroups and putting it in new subgroups.
5158 */
5159 void bgp_announce_route_all(struct peer *peer)
5160 {
5161 afi_t afi;
5162 safi_t safi;
5163
5164 FOREACH_AFI_SAFI (afi, safi)
5165 bgp_announce_route(peer, afi, safi, false);
5166 }
5167
5168 /* Flag or unflag bgp_dest to determine whether it should be treated by
5169 * bgp_soft_reconfig_table_task.
5170 * Flag if flag is true. Unflag if flag is false.
5171 */
5172 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5173 {
5174 struct bgp_dest *dest;
5175 struct bgp_adj_in *ain;
5176
5177 if (!table)
5178 return;
5179
5180 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5181 for (ain = dest->adj_in; ain; ain = ain->next) {
5182 if (ain->peer != NULL)
5183 break;
5184 }
5185 if (flag && ain != NULL && ain->peer != NULL)
5186 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5187 else
5188 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5189 }
5190 }
5191
5192 static void bgp_soft_reconfig_table_update(struct peer *peer,
5193 struct bgp_dest *dest,
5194 struct bgp_adj_in *ain, afi_t afi,
5195 safi_t safi, struct prefix_rd *prd)
5196 {
5197 struct bgp_path_info *pi;
5198 uint32_t num_labels = 0;
5199 mpls_label_t *label_pnt = NULL;
5200 struct bgp_route_evpn evpn;
5201
5202 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5203 if (pi->peer == peer)
5204 break;
5205
5206 if (pi && pi->extra)
5207 num_labels = pi->extra->num_labels;
5208 if (num_labels)
5209 label_pnt = &pi->extra->label[0];
5210 if (pi)
5211 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5212 sizeof(evpn));
5213 else
5214 memset(&evpn, 0, sizeof(evpn));
5215
5216 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5217 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5218 label_pnt, num_labels, 1, &evpn);
5219 }
5220
5221 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5222 struct bgp_table *table,
5223 struct prefix_rd *prd)
5224 {
5225 struct bgp_dest *dest;
5226 struct bgp_adj_in *ain;
5227
5228 if (!table)
5229 table = peer->bgp->rib[afi][safi];
5230
5231 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5232 for (ain = dest->adj_in; ain; ain = ain->next) {
5233 if (ain->peer != peer)
5234 continue;
5235
5236 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5237 safi, prd);
5238 }
5239 }
5240
5241 /* Do soft reconfig table per bgp table.
5242 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5243 * when BGP_NODE_SOFT_RECONFIG is set,
5244 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5245 * Schedule a new thread to continue the job.
5246 * Without splitting the full job into several part,
5247 * vtysh waits for the job to finish before responding to a BGP command
5248 */
5249 static void bgp_soft_reconfig_table_task(struct event *thread)
5250 {
5251 uint32_t iter, max_iter;
5252 struct bgp_dest *dest;
5253 struct bgp_adj_in *ain;
5254 struct peer *peer;
5255 struct bgp_table *table;
5256 struct prefix_rd *prd;
5257 struct listnode *node, *nnode;
5258
5259 table = EVENT_ARG(thread);
5260 prd = NULL;
5261
5262 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5263 if (table->soft_reconfig_init) {
5264 /* first call of the function with a new srta structure.
5265 * Don't do any treatment this time on nodes
5266 * in order vtysh to respond quickly
5267 */
5268 max_iter = 0;
5269 }
5270
5271 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5272 dest = bgp_route_next(dest)) {
5273 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5274 continue;
5275
5276 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5277
5278 for (ain = dest->adj_in; ain; ain = ain->next) {
5279 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5280 nnode, peer)) {
5281 if (ain->peer != peer)
5282 continue;
5283
5284 bgp_soft_reconfig_table_update(
5285 peer, dest, ain, table->afi,
5286 table->safi, prd);
5287 iter++;
5288 }
5289 }
5290 }
5291
5292 /* we're either starting the initial iteration,
5293 * or we're going to continue an ongoing iteration
5294 */
5295 if (dest || table->soft_reconfig_init) {
5296 table->soft_reconfig_init = false;
5297 event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
5298 0, &table->soft_reconfig_thread);
5299 return;
5300 }
5301 /* we're done, clean up the background iteration context info and
5302 schedule route annoucement
5303 */
5304 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5305 listnode_delete(table->soft_reconfig_peers, peer);
5306 bgp_announce_route(peer, table->afi, table->safi, false);
5307 }
5308
5309 list_delete(&table->soft_reconfig_peers);
5310 }
5311
5312
5313 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5314 * and peer.
5315 * - bgp cannot be NULL
5316 * - if table and peer are NULL, cancel all threads within the bgp instance
5317 * - if table is NULL and peer is not,
5318 * remove peer in all threads within the bgp instance
5319 * - if peer is NULL, cancel all threads matching table within the bgp instance
5320 */
5321 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5322 const struct bgp_table *table,
5323 const struct peer *peer)
5324 {
5325 struct peer *npeer;
5326 struct listnode *node, *nnode;
5327 int afi, safi;
5328 struct bgp_table *ntable;
5329
5330 if (!bgp)
5331 return;
5332
5333 FOREACH_AFI_SAFI (afi, safi) {
5334 ntable = bgp->rib[afi][safi];
5335 if (!ntable)
5336 continue;
5337 if (table && table != ntable)
5338 continue;
5339
5340 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5341 npeer)) {
5342 if (peer && peer != npeer)
5343 continue;
5344 listnode_delete(ntable->soft_reconfig_peers, npeer);
5345 }
5346
5347 if (!ntable->soft_reconfig_peers
5348 || !list_isempty(ntable->soft_reconfig_peers))
5349 continue;
5350
5351 list_delete(&ntable->soft_reconfig_peers);
5352 bgp_soft_reconfig_table_flag(ntable, false);
5353 EVENT_OFF(ntable->soft_reconfig_thread);
5354 }
5355 }
5356
5357 /*
5358 * Returns false if the peer is not configured for soft reconfig in
5359 */
5360 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5361 {
5362 struct bgp_dest *dest;
5363 struct bgp_table *table;
5364 struct listnode *node, *nnode;
5365 struct peer *npeer;
5366 struct peer_af *paf;
5367
5368 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5369 return false;
5370
5371 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5372 && (safi != SAFI_EVPN)) {
5373 table = peer->bgp->rib[afi][safi];
5374 if (!table)
5375 return true;
5376
5377 table->soft_reconfig_init = true;
5378
5379 if (!table->soft_reconfig_peers)
5380 table->soft_reconfig_peers = list_new();
5381 npeer = NULL;
5382 /* add peer to the table soft_reconfig_peers if not already
5383 * there
5384 */
5385 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5386 npeer)) {
5387 if (peer == npeer)
5388 break;
5389 }
5390 if (peer != npeer)
5391 listnode_add(table->soft_reconfig_peers, peer);
5392
5393 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5394 * on table would start back at the beginning.
5395 */
5396 bgp_soft_reconfig_table_flag(table, true);
5397
5398 if (!table->soft_reconfig_thread)
5399 event_add_event(bm->master,
5400 bgp_soft_reconfig_table_task, table, 0,
5401 &table->soft_reconfig_thread);
5402 /* Cancel bgp_announce_route_timer_expired threads.
5403 * bgp_announce_route_timer_expired threads have been scheduled
5404 * to announce routes as soon as the soft_reconfigure process
5405 * finishes.
5406 * In this case, soft_reconfigure is also scheduled by using
5407 * a thread but is planned after the
5408 * bgp_announce_route_timer_expired threads. It means that,
5409 * without cancelling the threads, the route announcement task
5410 * would run before the soft reconfiguration one. That would
5411 * useless and would block vtysh during several seconds. Route
5412 * announcements are rescheduled as soon as the soft_reconfigure
5413 * process finishes.
5414 */
5415 paf = peer_af_find(peer, afi, safi);
5416 if (paf)
5417 bgp_stop_announce_route_timer(paf);
5418 } else
5419 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5420 dest = bgp_route_next(dest)) {
5421 table = bgp_dest_get_bgp_table_info(dest);
5422
5423 if (table == NULL)
5424 continue;
5425
5426 const struct prefix *p = bgp_dest_get_prefix(dest);
5427 struct prefix_rd prd;
5428
5429 prd.family = AF_UNSPEC;
5430 prd.prefixlen = 64;
5431 memcpy(&prd.val, p->u.val, 8);
5432
5433 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5434 }
5435
5436 return true;
5437 }
5438
5439
5440 struct bgp_clear_node_queue {
5441 struct bgp_dest *dest;
5442 };
5443
5444 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5445 {
5446 struct bgp_clear_node_queue *cnq = data;
5447 struct bgp_dest *dest = cnq->dest;
5448 struct peer *peer = wq->spec.data;
5449 struct bgp_path_info *pi;
5450 struct bgp *bgp;
5451 afi_t afi = bgp_dest_table(dest)->afi;
5452 safi_t safi = bgp_dest_table(dest)->safi;
5453
5454 assert(dest && peer);
5455 bgp = peer->bgp;
5456
5457 /* It is possible that we have multiple paths for a prefix from a peer
5458 * if that peer is using AddPath.
5459 */
5460 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5461 if (pi->peer != peer)
5462 continue;
5463
5464 /* graceful restart STALE flag set. */
5465 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5466 && peer->nsf[afi][safi])
5467 || CHECK_FLAG(peer->af_sflags[afi][safi],
5468 PEER_STATUS_ENHANCED_REFRESH))
5469 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5470 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5471 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5472 else {
5473 /* If this is an EVPN route, process for
5474 * un-import. */
5475 if (safi == SAFI_EVPN)
5476 bgp_evpn_unimport_route(
5477 bgp, afi, safi,
5478 bgp_dest_get_prefix(dest), pi);
5479 /* Handle withdraw for VRF route-leaking and L3VPN */
5480 if (SAFI_UNICAST == safi
5481 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5482 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5483 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5484 bgp, pi);
5485 }
5486 if (SAFI_MPLS_VPN == safi &&
5487 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5488 vpn_leak_to_vrf_withdraw(pi);
5489 }
5490
5491 bgp_rib_remove(dest, pi, peer, afi, safi);
5492 }
5493 }
5494 return WQ_SUCCESS;
5495 }
5496
5497 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5498 {
5499 struct bgp_clear_node_queue *cnq = data;
5500 struct bgp_dest *dest = cnq->dest;
5501 struct bgp_table *table = bgp_dest_table(dest);
5502
5503 bgp_dest_unlock_node(dest);
5504 bgp_table_unlock(table);
5505 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5506 }
5507
5508 static void bgp_clear_node_complete(struct work_queue *wq)
5509 {
5510 struct peer *peer = wq->spec.data;
5511
5512 /* Tickle FSM to start moving again */
5513 BGP_EVENT_ADD(peer, Clearing_Completed);
5514
5515 peer_unlock(peer); /* bgp_clear_route */
5516 }
5517
5518 static void bgp_clear_node_queue_init(struct peer *peer)
5519 {
5520 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5521
5522 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5523 #undef CLEAR_QUEUE_NAME_LEN
5524
5525 peer->clear_node_queue = work_queue_new(bm->master, wname);
5526 peer->clear_node_queue->spec.hold = 10;
5527 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5528 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5529 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5530 peer->clear_node_queue->spec.max_retries = 0;
5531
5532 /* we only 'lock' this peer reference when the queue is actually active
5533 */
5534 peer->clear_node_queue->spec.data = peer;
5535 }
5536
5537 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5538 struct bgp_table *table)
5539 {
5540 struct bgp_dest *dest;
5541 int force = peer->bgp->process_queue ? 0 : 1;
5542
5543 if (!table)
5544 table = peer->bgp->rib[afi][safi];
5545
5546 /* If still no table => afi/safi isn't configured at all or smth. */
5547 if (!table)
5548 return;
5549
5550 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5551 struct bgp_path_info *pi, *next;
5552 struct bgp_adj_in *ain;
5553 struct bgp_adj_in *ain_next;
5554
5555 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5556 * queued for every clearing peer, regardless of whether it is
5557 * relevant to the peer at hand.
5558 *
5559 * Overview: There are 3 different indices which need to be
5560 * scrubbed, potentially, when a peer is removed:
5561 *
5562 * 1 peer's routes visible via the RIB (ie accepted routes)
5563 * 2 peer's routes visible by the (optional) peer's adj-in index
5564 * 3 other routes visible by the peer's adj-out index
5565 *
5566 * 3 there is no hurry in scrubbing, once the struct peer is
5567 * removed from bgp->peer, we could just GC such deleted peer's
5568 * adj-outs at our leisure.
5569 *
5570 * 1 and 2 must be 'scrubbed' in some way, at least made
5571 * invisible via RIB index before peer session is allowed to be
5572 * brought back up. So one needs to know when such a 'search' is
5573 * complete.
5574 *
5575 * Ideally:
5576 *
5577 * - there'd be a single global queue or a single RIB walker
5578 * - rather than tracking which route_nodes still need to be
5579 * examined on a peer basis, we'd track which peers still
5580 * aren't cleared
5581 *
5582 * Given that our per-peer prefix-counts now should be reliable,
5583 * this may actually be achievable. It doesn't seem to be a huge
5584 * problem at this time,
5585 *
5586 * It is possible that we have multiple paths for a prefix from
5587 * a peer
5588 * if that peer is using AddPath.
5589 */
5590 ain = dest->adj_in;
5591 while (ain) {
5592 ain_next = ain->next;
5593
5594 if (ain->peer == peer)
5595 bgp_adj_in_remove(dest, ain);
5596
5597 ain = ain_next;
5598 }
5599
5600 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5601 next = pi->next;
5602 if (pi->peer != peer)
5603 continue;
5604
5605 if (force)
5606 bgp_path_info_reap(dest, pi);
5607 else {
5608 struct bgp_clear_node_queue *cnq;
5609
5610 /* both unlocked in bgp_clear_node_queue_del */
5611 bgp_table_lock(bgp_dest_table(dest));
5612 bgp_dest_lock_node(dest);
5613 cnq = XCALLOC(
5614 MTYPE_BGP_CLEAR_NODE_QUEUE,
5615 sizeof(struct bgp_clear_node_queue));
5616 cnq->dest = dest;
5617 work_queue_add(peer->clear_node_queue, cnq);
5618 break;
5619 }
5620 }
5621 }
5622 return;
5623 }
5624
5625 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5626 {
5627 struct bgp_dest *dest;
5628 struct bgp_table *table;
5629
5630 if (peer->clear_node_queue == NULL)
5631 bgp_clear_node_queue_init(peer);
5632
5633 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5634 * Idle until it receives a Clearing_Completed event. This protects
5635 * against peers which flap faster than we can we clear, which could
5636 * lead to:
5637 *
5638 * a) race with routes from the new session being installed before
5639 * clear_route_node visits the node (to delete the route of that
5640 * peer)
5641 * b) resource exhaustion, clear_route_node likely leads to an entry
5642 * on the process_main queue. Fast-flapping could cause that queue
5643 * to grow and grow.
5644 */
5645
5646 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5647 * the unlock will happen upon work-queue completion; other wise, the
5648 * unlock happens at the end of this function.
5649 */
5650 if (!peer->clear_node_queue->thread)
5651 peer_lock(peer);
5652
5653 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5654 bgp_clear_route_table(peer, afi, safi, NULL);
5655 else
5656 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5657 dest = bgp_route_next(dest)) {
5658 table = bgp_dest_get_bgp_table_info(dest);
5659 if (!table)
5660 continue;
5661
5662 bgp_clear_route_table(peer, afi, safi, table);
5663 }
5664
5665 /* unlock if no nodes got added to the clear-node-queue. */
5666 if (!peer->clear_node_queue->thread)
5667 peer_unlock(peer);
5668 }
5669
5670 void bgp_clear_route_all(struct peer *peer)
5671 {
5672 afi_t afi;
5673 safi_t safi;
5674
5675 FOREACH_AFI_SAFI (afi, safi)
5676 bgp_clear_route(peer, afi, safi);
5677
5678 #ifdef ENABLE_BGP_VNC
5679 rfapiProcessPeerDown(peer);
5680 #endif
5681 }
5682
5683 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5684 {
5685 struct bgp_table *table;
5686 struct bgp_dest *dest;
5687 struct bgp_adj_in *ain;
5688 struct bgp_adj_in *ain_next;
5689
5690 table = peer->bgp->rib[afi][safi];
5691
5692 /* It is possible that we have multiple paths for a prefix from a peer
5693 * if that peer is using AddPath.
5694 */
5695 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5696 ain = dest->adj_in;
5697
5698 while (ain) {
5699 ain_next = ain->next;
5700
5701 if (ain->peer == peer)
5702 bgp_adj_in_remove(dest, ain);
5703
5704 ain = ain_next;
5705 }
5706 }
5707 }
5708
5709 /* If any of the routes from the peer have been marked with the NO_LLGR
5710 * community, either as sent by the peer, or as the result of a configured
5711 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5712 * operation of [RFC4271].
5713 */
5714 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5715 {
5716 struct bgp_dest *dest;
5717 struct bgp_path_info *pi;
5718 struct bgp_table *table;
5719
5720 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5721 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5722 dest = bgp_route_next(dest)) {
5723 struct bgp_dest *rm;
5724
5725 /* look for neighbor in tables */
5726 table = bgp_dest_get_bgp_table_info(dest);
5727 if (!table)
5728 continue;
5729
5730 for (rm = bgp_table_top(table); rm;
5731 rm = bgp_route_next(rm))
5732 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5733 pi = pi->next) {
5734 if (pi->peer != peer)
5735 continue;
5736 if (CHECK_FLAG(
5737 peer->af_sflags[afi][safi],
5738 PEER_STATUS_LLGR_WAIT) &&
5739 bgp_attr_get_community(pi->attr) &&
5740 !community_include(
5741 bgp_attr_get_community(
5742 pi->attr),
5743 COMMUNITY_NO_LLGR))
5744 continue;
5745 if (!CHECK_FLAG(pi->flags,
5746 BGP_PATH_STALE))
5747 continue;
5748
5749 /*
5750 * If this is VRF leaked route
5751 * process for withdraw.
5752 */
5753 if (pi->sub_type ==
5754 BGP_ROUTE_IMPORTED &&
5755 peer->bgp->inst_type ==
5756 BGP_INSTANCE_TYPE_DEFAULT)
5757 vpn_leak_to_vrf_withdraw(pi);
5758
5759 bgp_rib_remove(rm, pi, peer, afi, safi);
5760 break;
5761 }
5762 }
5763 } else {
5764 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5765 dest = bgp_route_next(dest))
5766 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5767 pi = pi->next) {
5768 if (pi->peer != peer)
5769 continue;
5770 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5771 PEER_STATUS_LLGR_WAIT) &&
5772 bgp_attr_get_community(pi->attr) &&
5773 !community_include(
5774 bgp_attr_get_community(pi->attr),
5775 COMMUNITY_NO_LLGR))
5776 continue;
5777 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5778 continue;
5779 if (safi == SAFI_UNICAST &&
5780 (peer->bgp->inst_type ==
5781 BGP_INSTANCE_TYPE_VRF ||
5782 peer->bgp->inst_type ==
5783 BGP_INSTANCE_TYPE_DEFAULT))
5784 vpn_leak_from_vrf_withdraw(
5785 bgp_get_default(), peer->bgp,
5786 pi);
5787
5788 bgp_rib_remove(dest, pi, peer, afi, safi);
5789 break;
5790 }
5791 }
5792 }
5793
5794 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5795 {
5796 struct bgp_dest *dest, *ndest;
5797 struct bgp_path_info *pi;
5798 struct bgp_table *table;
5799
5800 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5801 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5802 dest = bgp_route_next(dest)) {
5803 table = bgp_dest_get_bgp_table_info(dest);
5804 if (!table)
5805 continue;
5806
5807 for (ndest = bgp_table_top(table); ndest;
5808 ndest = bgp_route_next(ndest)) {
5809 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5810 pi = pi->next) {
5811 if (pi->peer != peer)
5812 continue;
5813
5814 if ((CHECK_FLAG(
5815 peer->af_sflags[afi][safi],
5816 PEER_STATUS_ENHANCED_REFRESH))
5817 && !CHECK_FLAG(pi->flags,
5818 BGP_PATH_STALE)
5819 && !CHECK_FLAG(
5820 pi->flags,
5821 BGP_PATH_UNUSEABLE)) {
5822 if (bgp_debug_neighbor_events(
5823 peer))
5824 zlog_debug(
5825 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5826 peer,
5827 afi2str(afi),
5828 safi2str(safi),
5829 bgp_dest_get_prefix(
5830 ndest));
5831
5832 bgp_path_info_set_flag(
5833 ndest, pi,
5834 BGP_PATH_STALE);
5835 }
5836 }
5837 }
5838 }
5839 } else {
5840 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5841 dest = bgp_route_next(dest)) {
5842 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5843 pi = pi->next) {
5844 if (pi->peer != peer)
5845 continue;
5846
5847 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5848 PEER_STATUS_ENHANCED_REFRESH))
5849 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5850 && !CHECK_FLAG(pi->flags,
5851 BGP_PATH_UNUSEABLE)) {
5852 if (bgp_debug_neighbor_events(peer))
5853 zlog_debug(
5854 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5855 peer, afi2str(afi),
5856 safi2str(safi),
5857 bgp_dest_get_prefix(
5858 dest));
5859
5860 bgp_path_info_set_flag(dest, pi,
5861 BGP_PATH_STALE);
5862 }
5863 }
5864 }
5865 }
5866 }
5867
5868 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5869 {
5870 if (peer->sort == BGP_PEER_IBGP)
5871 return true;
5872
5873 if (peer->sort == BGP_PEER_EBGP
5874 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5875 || FILTER_LIST_OUT_NAME(filter)
5876 || DISTRIBUTE_OUT_NAME(filter)))
5877 return true;
5878 return false;
5879 }
5880
5881 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5882 {
5883 if (peer->sort == BGP_PEER_IBGP)
5884 return true;
5885
5886 if (peer->sort == BGP_PEER_EBGP
5887 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5888 || FILTER_LIST_IN_NAME(filter)
5889 || DISTRIBUTE_IN_NAME(filter)))
5890 return true;
5891 return false;
5892 }
5893
5894 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5895 safi_t safi)
5896 {
5897 struct bgp_dest *dest;
5898 struct bgp_path_info *pi;
5899 struct bgp_path_info *next;
5900
5901 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5902 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5903 const struct prefix *p = bgp_dest_get_prefix(dest);
5904
5905 next = pi->next;
5906
5907 /* Unimport EVPN routes from VRFs */
5908 if (safi == SAFI_EVPN)
5909 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5910 SAFI_EVPN, p, pi);
5911
5912 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5913 && pi->type == ZEBRA_ROUTE_BGP
5914 && (pi->sub_type == BGP_ROUTE_NORMAL
5915 || pi->sub_type == BGP_ROUTE_AGGREGATE
5916 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5917
5918 if (bgp_fibupd_safi(safi))
5919 bgp_zebra_withdraw(p, pi, bgp, safi);
5920 }
5921
5922 bgp_path_info_reap(dest, pi);
5923 }
5924 }
5925
5926 /* Delete all kernel routes. */
5927 void bgp_cleanup_routes(struct bgp *bgp)
5928 {
5929 afi_t afi;
5930 struct bgp_dest *dest;
5931 struct bgp_table *table;
5932
5933 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5934 if (afi == AFI_L2VPN)
5935 continue;
5936 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5937 SAFI_UNICAST);
5938 /*
5939 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5940 */
5941 if (afi != AFI_L2VPN) {
5942 safi_t safi;
5943 safi = SAFI_MPLS_VPN;
5944 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5945 dest = bgp_route_next(dest)) {
5946 table = bgp_dest_get_bgp_table_info(dest);
5947 if (table != NULL) {
5948 bgp_cleanup_table(bgp, table, safi);
5949 bgp_table_finish(&table);
5950 bgp_dest_set_bgp_table_info(dest, NULL);
5951 bgp_dest_unlock_node(dest);
5952 }
5953 }
5954 safi = SAFI_ENCAP;
5955 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5956 dest = bgp_route_next(dest)) {
5957 table = bgp_dest_get_bgp_table_info(dest);
5958 if (table != NULL) {
5959 bgp_cleanup_table(bgp, table, safi);
5960 bgp_table_finish(&table);
5961 bgp_dest_set_bgp_table_info(dest, NULL);
5962 bgp_dest_unlock_node(dest);
5963 }
5964 }
5965 }
5966 }
5967 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5968 dest = bgp_route_next(dest)) {
5969 table = bgp_dest_get_bgp_table_info(dest);
5970 if (table != NULL) {
5971 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5972 bgp_table_finish(&table);
5973 bgp_dest_set_bgp_table_info(dest, NULL);
5974 bgp_dest_unlock_node(dest);
5975 }
5976 }
5977 }
5978
5979 void bgp_reset(void)
5980 {
5981 vty_reset();
5982 bgp_zclient_reset();
5983 access_list_reset();
5984 prefix_list_reset();
5985 }
5986
5987 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5988 {
5989 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5990 && CHECK_FLAG(peer->af_cap[afi][safi],
5991 PEER_CAP_ADDPATH_AF_TX_RCV));
5992 }
5993
5994 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5995 value. */
5996 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5997 struct bgp_nlri *packet)
5998 {
5999 uint8_t *pnt;
6000 uint8_t *lim;
6001 struct prefix p;
6002 int psize;
6003 afi_t afi;
6004 safi_t safi;
6005 bool addpath_capable;
6006 uint32_t addpath_id;
6007
6008 pnt = packet->nlri;
6009 lim = pnt + packet->length;
6010 afi = packet->afi;
6011 safi = packet->safi;
6012 addpath_id = 0;
6013 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
6014
6015 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
6016 syntactic validity. If the field is syntactically incorrect,
6017 then the Error Subcode is set to Invalid Network Field. */
6018 for (; pnt < lim; pnt += psize) {
6019 /* Clear prefix structure. */
6020 memset(&p, 0, sizeof(p));
6021
6022 if (addpath_capable) {
6023
6024 /* When packet overflow occurs return immediately. */
6025 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
6026 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6027
6028 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
6029 addpath_id = ntohl(addpath_id);
6030 pnt += BGP_ADDPATH_ID_LEN;
6031 }
6032
6033 /* Fetch prefix length. */
6034 p.prefixlen = *pnt++;
6035 /* afi/safi validity already verified by caller,
6036 * bgp_update_receive */
6037 p.family = afi2family(afi);
6038
6039 /* Prefix length check. */
6040 if (p.prefixlen > prefix_blen(&p) * 8) {
6041 flog_err(
6042 EC_BGP_UPDATE_RCV,
6043 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6044 peer->host, p.prefixlen, packet->afi);
6045 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6046 }
6047
6048 /* Packet size overflow check. */
6049 psize = PSIZE(p.prefixlen);
6050
6051 /* When packet overflow occur return immediately. */
6052 if (pnt + psize > lim) {
6053 flog_err(
6054 EC_BGP_UPDATE_RCV,
6055 "%s [Error] Update packet error (prefix length %d overflows packet)",
6056 peer->host, p.prefixlen);
6057 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6058 }
6059
6060 /* Defensive coding, double-check the psize fits in a struct
6061 * prefix for the v4 and v6 afi's and unicast/multicast */
6062 if (psize > (ssize_t)sizeof(p.u.val)) {
6063 flog_err(
6064 EC_BGP_UPDATE_RCV,
6065 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6066 peer->host, p.prefixlen, sizeof(p.u.val));
6067 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6068 }
6069
6070 /* Fetch prefix from NLRI packet. */
6071 memcpy(p.u.val, pnt, psize);
6072
6073 /* Check address. */
6074 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6075 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6076 /* From RFC4271 Section 6.3:
6077 *
6078 * If a prefix in the NLRI field is semantically
6079 * incorrect
6080 * (e.g., an unexpected multicast IP address),
6081 * an error SHOULD
6082 * be logged locally, and the prefix SHOULD be
6083 * ignored.
6084 */
6085 flog_err(
6086 EC_BGP_UPDATE_RCV,
6087 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6088 peer->host, &p.u.prefix4);
6089 continue;
6090 }
6091 }
6092
6093 /* Check address. */
6094 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6095 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6096 flog_err(
6097 EC_BGP_UPDATE_RCV,
6098 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6099 peer->host, &p.u.prefix6);
6100
6101 continue;
6102 }
6103 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6104 flog_err(
6105 EC_BGP_UPDATE_RCV,
6106 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6107 peer->host, &p.u.prefix6);
6108
6109 continue;
6110 }
6111 }
6112
6113 /* Normal process. */
6114 if (attr)
6115 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6116 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6117 NULL, 0, 0, NULL);
6118 else
6119 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6120 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6121 NULL, 0, NULL);
6122
6123 /* Do not send BGP notification twice when maximum-prefix count
6124 * overflow. */
6125 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6126 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6127 }
6128
6129 /* Packet length consistency check. */
6130 if (pnt != lim) {
6131 flog_err(
6132 EC_BGP_UPDATE_RCV,
6133 "%s [Error] Update packet error (prefix length mismatch with total length)",
6134 peer->host);
6135 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6136 }
6137
6138 return BGP_NLRI_PARSE_OK;
6139 }
6140
6141 static struct bgp_static *bgp_static_new(void)
6142 {
6143 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6144 }
6145
6146 static void bgp_static_free(struct bgp_static *bgp_static)
6147 {
6148 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6149 route_map_counter_decrement(bgp_static->rmap.map);
6150
6151 if (bgp_static->prd_pretty)
6152 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6153 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6154 XFREE(MTYPE_BGP_STATIC, bgp_static);
6155 }
6156
6157 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6158 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6159 {
6160 struct bgp_dest *dest;
6161 struct bgp_path_info *pi;
6162 struct bgp_path_info *new;
6163 struct bgp_path_info rmap_path;
6164 struct attr attr;
6165 struct attr *attr_new;
6166 route_map_result_t ret;
6167 #ifdef ENABLE_BGP_VNC
6168 int vnc_implicit_withdraw = 0;
6169 #endif
6170
6171 assert(bgp_static);
6172
6173 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6174
6175 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6176
6177 attr.nexthop = bgp_static->igpnexthop;
6178 attr.med = bgp_static->igpmetric;
6179 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6180
6181 if (afi == AFI_IP)
6182 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6183
6184 if (bgp_static->igpmetric)
6185 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6186
6187 if (bgp_static->atomic)
6188 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6189
6190 /* Store label index, if required. */
6191 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6192 attr.label_index = bgp_static->label_index;
6193 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6194 }
6195
6196 /* Apply route-map. */
6197 if (bgp_static->rmap.name) {
6198 struct attr attr_tmp = attr;
6199
6200 memset(&rmap_path, 0, sizeof(rmap_path));
6201 rmap_path.peer = bgp->peer_self;
6202 rmap_path.attr = &attr_tmp;
6203
6204 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6205
6206 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6207
6208 bgp->peer_self->rmap_type = 0;
6209
6210 if (ret == RMAP_DENYMATCH) {
6211 /* Free uninterned attribute. */
6212 bgp_attr_flush(&attr_tmp);
6213
6214 /* Unintern original. */
6215 aspath_unintern(&attr.aspath);
6216 bgp_static_withdraw(bgp, p, afi, safi);
6217 bgp_dest_unlock_node(dest);
6218 return;
6219 }
6220
6221 if (bgp_in_graceful_shutdown(bgp))
6222 bgp_attr_add_gshut_community(&attr_tmp);
6223
6224 attr_new = bgp_attr_intern(&attr_tmp);
6225 } else {
6226
6227 if (bgp_in_graceful_shutdown(bgp))
6228 bgp_attr_add_gshut_community(&attr);
6229
6230 attr_new = bgp_attr_intern(&attr);
6231 }
6232
6233 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6234 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6235 && pi->sub_type == BGP_ROUTE_STATIC)
6236 break;
6237
6238 if (pi) {
6239 if (attrhash_cmp(pi->attr, attr_new)
6240 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6241 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6242 bgp_dest_unlock_node(dest);
6243 bgp_attr_unintern(&attr_new);
6244 aspath_unintern(&attr.aspath);
6245 return;
6246 } else {
6247 /* The attribute is changed. */
6248 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6249
6250 /* Rewrite BGP route information. */
6251 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6252 bgp_path_info_restore(dest, pi);
6253 else
6254 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6255 #ifdef ENABLE_BGP_VNC
6256 if ((afi == AFI_IP || afi == AFI_IP6)
6257 && (safi == SAFI_UNICAST)) {
6258 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6259 /*
6260 * Implicit withdraw case.
6261 * We have to do this before pi is
6262 * changed
6263 */
6264 ++vnc_implicit_withdraw;
6265 vnc_import_bgp_del_route(bgp, p, pi);
6266 vnc_import_bgp_exterior_del_route(
6267 bgp, p, pi);
6268 }
6269 }
6270 #endif
6271 bgp_attr_unintern(&pi->attr);
6272 pi->attr = attr_new;
6273 pi->uptime = monotime(NULL);
6274 #ifdef ENABLE_BGP_VNC
6275 if ((afi == AFI_IP || afi == AFI_IP6)
6276 && (safi == SAFI_UNICAST)) {
6277 if (vnc_implicit_withdraw) {
6278 vnc_import_bgp_add_route(bgp, p, pi);
6279 vnc_import_bgp_exterior_add_route(
6280 bgp, p, pi);
6281 }
6282 }
6283 #endif
6284
6285 /* Nexthop reachability check. */
6286 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6287 && (safi == SAFI_UNICAST
6288 || safi == SAFI_LABELED_UNICAST)) {
6289
6290 struct bgp *bgp_nexthop = bgp;
6291
6292 if (pi->extra && pi->extra->bgp_orig)
6293 bgp_nexthop = pi->extra->bgp_orig;
6294
6295 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6296 afi, safi, pi, NULL,
6297 0, p))
6298 bgp_path_info_set_flag(dest, pi,
6299 BGP_PATH_VALID);
6300 else {
6301 if (BGP_DEBUG(nht, NHT)) {
6302 char buf1[INET6_ADDRSTRLEN];
6303 inet_ntop(p->family,
6304 &p->u.prefix, buf1,
6305 sizeof(buf1));
6306 zlog_debug(
6307 "%s(%s): Route not in table, not advertising",
6308 __func__, buf1);
6309 }
6310 bgp_path_info_unset_flag(
6311 dest, pi, BGP_PATH_VALID);
6312 }
6313 } else {
6314 /* Delete the NHT structure if any, if we're
6315 * toggling between
6316 * enabling/disabling import check. We
6317 * deregister the route
6318 * from NHT to avoid overloading NHT and the
6319 * process interaction
6320 */
6321 bgp_unlink_nexthop(pi);
6322 bgp_path_info_set_flag(dest, pi,
6323 BGP_PATH_VALID);
6324 }
6325 /* Process change. */
6326 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6327 bgp_process(bgp, dest, afi, safi);
6328
6329 if (SAFI_UNICAST == safi
6330 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6331 || bgp->inst_type
6332 == BGP_INSTANCE_TYPE_DEFAULT)) {
6333 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6334 pi);
6335 }
6336
6337 bgp_dest_unlock_node(dest);
6338 aspath_unintern(&attr.aspath);
6339 return;
6340 }
6341 }
6342
6343 /* Make new BGP info. */
6344 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6345 attr_new, dest);
6346 /* Nexthop reachability check. */
6347 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6348 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6349 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6350 p))
6351 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6352 else {
6353 if (BGP_DEBUG(nht, NHT)) {
6354 char buf1[INET6_ADDRSTRLEN];
6355
6356 inet_ntop(p->family, &p->u.prefix, buf1,
6357 sizeof(buf1));
6358 zlog_debug(
6359 "%s(%s): Route not in table, not advertising",
6360 __func__, buf1);
6361 }
6362 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6363 }
6364 } else {
6365 /* Delete the NHT structure if any, if we're toggling between
6366 * enabling/disabling import check. We deregister the route
6367 * from NHT to avoid overloading NHT and the process interaction
6368 */
6369 bgp_unlink_nexthop(new);
6370
6371 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6372 }
6373
6374 /* Aggregate address increment. */
6375 bgp_aggregate_increment(bgp, p, new, afi, safi);
6376
6377 /* Register new BGP information. */
6378 bgp_path_info_add(dest, new);
6379
6380 /* route_node_get lock */
6381 bgp_dest_unlock_node(dest);
6382
6383 /* Process change. */
6384 bgp_process(bgp, dest, afi, safi);
6385
6386 if (SAFI_UNICAST == safi
6387 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6388 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6389 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6390 }
6391
6392 /* Unintern original. */
6393 aspath_unintern(&attr.aspath);
6394 }
6395
6396 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6397 safi_t safi)
6398 {
6399 struct bgp_dest *dest;
6400 struct bgp_path_info *pi;
6401
6402 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6403
6404 /* Check selected route and self inserted route. */
6405 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6406 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6407 && pi->sub_type == BGP_ROUTE_STATIC)
6408 break;
6409
6410 /* Withdraw static BGP route from routing table. */
6411 if (pi) {
6412 if (SAFI_UNICAST == safi
6413 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6414 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6415 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6416 }
6417 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6418 bgp_unlink_nexthop(pi);
6419 bgp_path_info_delete(dest, pi);
6420 bgp_process(bgp, dest, afi, safi);
6421 }
6422
6423 /* Unlock bgp_node_lookup. */
6424 bgp_dest_unlock_node(dest);
6425 }
6426
6427 /*
6428 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6429 */
6430 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6431 afi_t afi, safi_t safi,
6432 struct prefix_rd *prd)
6433 {
6434 struct bgp_dest *dest;
6435 struct bgp_path_info *pi;
6436
6437 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6438
6439 /* Check selected route and self inserted route. */
6440 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6441 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6442 && pi->sub_type == BGP_ROUTE_STATIC)
6443 break;
6444
6445 /* Withdraw static BGP route from routing table. */
6446 if (pi) {
6447 #ifdef ENABLE_BGP_VNC
6448 rfapiProcessWithdraw(
6449 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6450 1); /* Kill, since it is an administrative change */
6451 #endif
6452 if (SAFI_MPLS_VPN == safi
6453 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6454 vpn_leak_to_vrf_withdraw(pi);
6455 }
6456 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6457 bgp_path_info_delete(dest, pi);
6458 bgp_process(bgp, dest, afi, safi);
6459 }
6460
6461 /* Unlock bgp_node_lookup. */
6462 bgp_dest_unlock_node(dest);
6463 }
6464
6465 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6466 struct bgp_static *bgp_static, afi_t afi,
6467 safi_t safi)
6468 {
6469 struct bgp_dest *dest;
6470 struct bgp_path_info *new;
6471 struct attr *attr_new;
6472 struct attr attr = {0};
6473 struct bgp_path_info *pi;
6474 #ifdef ENABLE_BGP_VNC
6475 mpls_label_t label = 0;
6476 #endif
6477 uint32_t num_labels = 0;
6478
6479 assert(bgp_static);
6480
6481 if (bgp_static->label != MPLS_INVALID_LABEL)
6482 num_labels = 1;
6483 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6484 &bgp_static->prd);
6485
6486 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6487
6488 attr.nexthop = bgp_static->igpnexthop;
6489 attr.med = bgp_static->igpmetric;
6490 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6491
6492 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6493 || (safi == SAFI_ENCAP)) {
6494 if (afi == AFI_IP) {
6495 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6496 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6497 }
6498 }
6499 if (afi == AFI_L2VPN) {
6500 if (bgp_static->gatewayIp.family == AF_INET) {
6501 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6502 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6503 &bgp_static->gatewayIp.u.prefix4,
6504 IPV4_MAX_BYTELEN);
6505 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6506 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6507 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6508 &bgp_static->gatewayIp.u.prefix6,
6509 IPV6_MAX_BYTELEN);
6510 }
6511 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6512 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6513 struct bgp_encap_type_vxlan bet;
6514 memset(&bet, 0, sizeof(bet));
6515 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6516 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6517 }
6518 if (bgp_static->router_mac) {
6519 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6520 }
6521 }
6522 /* Apply route-map. */
6523 if (bgp_static->rmap.name) {
6524 struct attr attr_tmp = attr;
6525 struct bgp_path_info rmap_path;
6526 route_map_result_t ret;
6527
6528 rmap_path.peer = bgp->peer_self;
6529 rmap_path.attr = &attr_tmp;
6530
6531 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6532
6533 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6534
6535 bgp->peer_self->rmap_type = 0;
6536
6537 if (ret == RMAP_DENYMATCH) {
6538 /* Free uninterned attribute. */
6539 bgp_attr_flush(&attr_tmp);
6540
6541 /* Unintern original. */
6542 aspath_unintern(&attr.aspath);
6543 bgp_static_withdraw_safi(bgp, p, afi, safi,
6544 &bgp_static->prd);
6545 bgp_dest_unlock_node(dest);
6546 return;
6547 }
6548
6549 attr_new = bgp_attr_intern(&attr_tmp);
6550 } else {
6551 attr_new = bgp_attr_intern(&attr);
6552 }
6553
6554 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6555 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6556 && pi->sub_type == BGP_ROUTE_STATIC)
6557 break;
6558
6559 if (pi) {
6560 if (attrhash_cmp(pi->attr, attr_new)
6561 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6562 bgp_dest_unlock_node(dest);
6563 bgp_attr_unintern(&attr_new);
6564 aspath_unintern(&attr.aspath);
6565 return;
6566 } else {
6567 /* The attribute is changed. */
6568 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6569
6570 /* Rewrite BGP route information. */
6571 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6572 bgp_path_info_restore(dest, pi);
6573 else
6574 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6575 bgp_attr_unintern(&pi->attr);
6576 pi->attr = attr_new;
6577 pi->uptime = monotime(NULL);
6578 #ifdef ENABLE_BGP_VNC
6579 if (pi->extra)
6580 label = decode_label(&pi->extra->label[0]);
6581 #endif
6582
6583 /* Process change. */
6584 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6585 bgp_process(bgp, dest, afi, safi);
6586
6587 if (SAFI_MPLS_VPN == safi
6588 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6589 vpn_leak_to_vrf_update(bgp, pi,
6590 &bgp_static->prd);
6591 }
6592 #ifdef ENABLE_BGP_VNC
6593 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6594 pi->attr, afi, safi, pi->type,
6595 pi->sub_type, &label);
6596 #endif
6597 bgp_dest_unlock_node(dest);
6598 aspath_unintern(&attr.aspath);
6599 return;
6600 }
6601 }
6602
6603
6604 /* Make new BGP info. */
6605 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6606 attr_new, dest);
6607 SET_FLAG(new->flags, BGP_PATH_VALID);
6608 bgp_path_info_extra_get(new);
6609 if (num_labels) {
6610 new->extra->label[0] = bgp_static->label;
6611 new->extra->num_labels = num_labels;
6612 }
6613 #ifdef ENABLE_BGP_VNC
6614 label = decode_label(&bgp_static->label);
6615 #endif
6616
6617 /* Aggregate address increment. */
6618 bgp_aggregate_increment(bgp, p, new, afi, safi);
6619
6620 /* Register new BGP information. */
6621 bgp_path_info_add(dest, new);
6622 /* route_node_get lock */
6623 bgp_dest_unlock_node(dest);
6624
6625 /* Process change. */
6626 bgp_process(bgp, dest, afi, safi);
6627
6628 if (SAFI_MPLS_VPN == safi
6629 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6630 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6631 }
6632 #ifdef ENABLE_BGP_VNC
6633 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6634 safi, new->type, new->sub_type, &label);
6635 #endif
6636
6637 /* Unintern original. */
6638 aspath_unintern(&attr.aspath);
6639 }
6640
6641 /* Configure static BGP network. When user don't run zebra, static
6642 route should be installed as valid. */
6643 static int bgp_static_set(struct vty *vty, const char *negate,
6644 const char *ip_str, afi_t afi, safi_t safi,
6645 const char *rmap, int backdoor, uint32_t label_index)
6646 {
6647 VTY_DECLVAR_CONTEXT(bgp, bgp);
6648 int ret;
6649 struct prefix p;
6650 struct bgp_static *bgp_static;
6651 struct bgp_dest *dest;
6652 uint8_t need_update = 0;
6653
6654 /* Convert IP prefix string to struct prefix. */
6655 ret = str2prefix(ip_str, &p);
6656 if (!ret) {
6657 vty_out(vty, "%% Malformed prefix\n");
6658 return CMD_WARNING_CONFIG_FAILED;
6659 }
6660 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6661 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6662 return CMD_WARNING_CONFIG_FAILED;
6663 }
6664
6665 apply_mask(&p);
6666
6667 if (negate) {
6668
6669 /* Set BGP static route configuration. */
6670 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6671
6672 if (!dest) {
6673 vty_out(vty, "%% Can't find static route specified\n");
6674 return CMD_WARNING_CONFIG_FAILED;
6675 }
6676
6677 bgp_static = bgp_dest_get_bgp_static_info(dest);
6678
6679 if ((label_index != BGP_INVALID_LABEL_INDEX)
6680 && (label_index != bgp_static->label_index)) {
6681 vty_out(vty,
6682 "%% label-index doesn't match static route\n");
6683 bgp_dest_unlock_node(dest);
6684 return CMD_WARNING_CONFIG_FAILED;
6685 }
6686
6687 if ((rmap && bgp_static->rmap.name)
6688 && strcmp(rmap, bgp_static->rmap.name)) {
6689 vty_out(vty,
6690 "%% route-map name doesn't match static route\n");
6691 bgp_dest_unlock_node(dest);
6692 return CMD_WARNING_CONFIG_FAILED;
6693 }
6694
6695 /* Update BGP RIB. */
6696 if (!bgp_static->backdoor)
6697 bgp_static_withdraw(bgp, &p, afi, safi);
6698
6699 /* Clear configuration. */
6700 bgp_static_free(bgp_static);
6701 bgp_dest_set_bgp_static_info(dest, NULL);
6702 bgp_dest_unlock_node(dest);
6703 bgp_dest_unlock_node(dest);
6704 } else {
6705
6706 /* Set BGP static route configuration. */
6707 dest = bgp_node_get(bgp->route[afi][safi], &p);
6708 bgp_static = bgp_dest_get_bgp_static_info(dest);
6709 if (bgp_static) {
6710 /* Configuration change. */
6711 /* Label index cannot be changed. */
6712 if (bgp_static->label_index != label_index) {
6713 vty_out(vty, "%% cannot change label-index\n");
6714 bgp_dest_unlock_node(dest);
6715 return CMD_WARNING_CONFIG_FAILED;
6716 }
6717
6718 /* Check previous routes are installed into BGP. */
6719 if (bgp_static->valid
6720 && bgp_static->backdoor != backdoor)
6721 need_update = 1;
6722
6723 bgp_static->backdoor = backdoor;
6724
6725 if (rmap) {
6726 XFREE(MTYPE_ROUTE_MAP_NAME,
6727 bgp_static->rmap.name);
6728 route_map_counter_decrement(
6729 bgp_static->rmap.map);
6730 bgp_static->rmap.name =
6731 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6732 bgp_static->rmap.map =
6733 route_map_lookup_by_name(rmap);
6734 route_map_counter_increment(
6735 bgp_static->rmap.map);
6736 } else {
6737 XFREE(MTYPE_ROUTE_MAP_NAME,
6738 bgp_static->rmap.name);
6739 route_map_counter_decrement(
6740 bgp_static->rmap.map);
6741 bgp_static->rmap.map = NULL;
6742 bgp_static->valid = 0;
6743 }
6744 bgp_dest_unlock_node(dest);
6745 } else {
6746 /* New configuration. */
6747 bgp_static = bgp_static_new();
6748 bgp_static->backdoor = backdoor;
6749 bgp_static->valid = 0;
6750 bgp_static->igpmetric = 0;
6751 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6752 bgp_static->label_index = label_index;
6753
6754 if (rmap) {
6755 XFREE(MTYPE_ROUTE_MAP_NAME,
6756 bgp_static->rmap.name);
6757 route_map_counter_decrement(
6758 bgp_static->rmap.map);
6759 bgp_static->rmap.name =
6760 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6761 bgp_static->rmap.map =
6762 route_map_lookup_by_name(rmap);
6763 route_map_counter_increment(
6764 bgp_static->rmap.map);
6765 }
6766 bgp_dest_set_bgp_static_info(dest, bgp_static);
6767 }
6768
6769 bgp_static->valid = 1;
6770 if (need_update)
6771 bgp_static_withdraw(bgp, &p, afi, safi);
6772
6773 if (!bgp_static->backdoor)
6774 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6775 }
6776
6777 return CMD_SUCCESS;
6778 }
6779
6780 void bgp_static_add(struct bgp *bgp)
6781 {
6782 afi_t afi;
6783 safi_t safi;
6784 struct bgp_dest *dest;
6785 struct bgp_dest *rm;
6786 struct bgp_table *table;
6787 struct bgp_static *bgp_static;
6788
6789 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6790 FOREACH_AFI_SAFI (afi, safi)
6791 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6792 dest = bgp_route_next(dest)) {
6793 if (!bgp_dest_has_bgp_path_info_data(dest))
6794 continue;
6795
6796 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6797 || (safi == SAFI_EVPN)) {
6798 table = bgp_dest_get_bgp_table_info(dest);
6799
6800 for (rm = bgp_table_top(table); rm;
6801 rm = bgp_route_next(rm)) {
6802 bgp_static =
6803 bgp_dest_get_bgp_static_info(
6804 rm);
6805 bgp_static_update_safi(
6806 bgp, bgp_dest_get_prefix(rm),
6807 bgp_static, afi, safi);
6808 }
6809 } else {
6810 bgp_static_update(
6811 bgp, bgp_dest_get_prefix(dest),
6812 bgp_dest_get_bgp_static_info(dest), afi,
6813 safi);
6814 }
6815 }
6816 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6817 }
6818
6819 /* Called from bgp_delete(). Delete all static routes from the BGP
6820 instance. */
6821 void bgp_static_delete(struct bgp *bgp)
6822 {
6823 afi_t afi;
6824 safi_t safi;
6825 struct bgp_dest *dest;
6826 struct bgp_dest *rm;
6827 struct bgp_table *table;
6828 struct bgp_static *bgp_static;
6829
6830 FOREACH_AFI_SAFI (afi, safi)
6831 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6832 dest = bgp_route_next(dest)) {
6833 if (!bgp_dest_has_bgp_path_info_data(dest))
6834 continue;
6835
6836 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6837 || (safi == SAFI_EVPN)) {
6838 table = bgp_dest_get_bgp_table_info(dest);
6839
6840 for (rm = bgp_table_top(table); rm;
6841 rm = bgp_route_next(rm)) {
6842 bgp_static =
6843 bgp_dest_get_bgp_static_info(
6844 rm);
6845 if (!bgp_static)
6846 continue;
6847
6848 bgp_static_withdraw_safi(
6849 bgp, bgp_dest_get_prefix(rm),
6850 AFI_IP, safi,
6851 (struct prefix_rd *)
6852 bgp_dest_get_prefix(
6853 dest));
6854 bgp_static_free(bgp_static);
6855 bgp_dest_set_bgp_static_info(rm,
6856 NULL);
6857 bgp_dest_unlock_node(rm);
6858 }
6859 } else {
6860 bgp_static = bgp_dest_get_bgp_static_info(dest);
6861 bgp_static_withdraw(bgp,
6862 bgp_dest_get_prefix(dest),
6863 afi, safi);
6864 bgp_static_free(bgp_static);
6865 bgp_dest_set_bgp_static_info(dest, NULL);
6866 bgp_dest_unlock_node(dest);
6867 }
6868 }
6869 }
6870
6871 void bgp_static_redo_import_check(struct bgp *bgp)
6872 {
6873 afi_t afi;
6874 safi_t safi;
6875 struct bgp_dest *dest;
6876 struct bgp_dest *rm;
6877 struct bgp_table *table;
6878 struct bgp_static *bgp_static;
6879
6880 /* Use this flag to force reprocessing of the route */
6881 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6882 FOREACH_AFI_SAFI (afi, safi) {
6883 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6884 dest = bgp_route_next(dest)) {
6885 if (!bgp_dest_has_bgp_path_info_data(dest))
6886 continue;
6887
6888 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6889 || (safi == SAFI_EVPN)) {
6890 table = bgp_dest_get_bgp_table_info(dest);
6891
6892 for (rm = bgp_table_top(table); rm;
6893 rm = bgp_route_next(rm)) {
6894 bgp_static =
6895 bgp_dest_get_bgp_static_info(
6896 rm);
6897 bgp_static_update_safi(
6898 bgp, bgp_dest_get_prefix(rm),
6899 bgp_static, afi, safi);
6900 }
6901 } else {
6902 bgp_static = bgp_dest_get_bgp_static_info(dest);
6903 bgp_static_update(bgp,
6904 bgp_dest_get_prefix(dest),
6905 bgp_static, afi, safi);
6906 }
6907 }
6908 }
6909 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6910 }
6911
6912 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6913 safi_t safi)
6914 {
6915 struct bgp_table *table;
6916 struct bgp_dest *dest;
6917 struct bgp_path_info *pi;
6918
6919 /* Do not install the aggregate route if BGP is in the
6920 * process of termination.
6921 */
6922 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6923 || (bgp->peer_self == NULL))
6924 return;
6925
6926 table = bgp->rib[afi][safi];
6927 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6928 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6929 if (pi->peer == bgp->peer_self
6930 && ((pi->type == ZEBRA_ROUTE_BGP
6931 && pi->sub_type == BGP_ROUTE_STATIC)
6932 || (pi->type != ZEBRA_ROUTE_BGP
6933 && pi->sub_type
6934 == BGP_ROUTE_REDISTRIBUTE))) {
6935 bgp_aggregate_decrement(
6936 bgp, bgp_dest_get_prefix(dest), pi, afi,
6937 safi);
6938 bgp_unlink_nexthop(pi);
6939 bgp_path_info_delete(dest, pi);
6940 bgp_process(bgp, dest, afi, safi);
6941 }
6942 }
6943 }
6944 }
6945
6946 /*
6947 * Purge all networks and redistributed routes from routing table.
6948 * Invoked upon the instance going down.
6949 */
6950 void bgp_purge_static_redist_routes(struct bgp *bgp)
6951 {
6952 afi_t afi;
6953 safi_t safi;
6954
6955 FOREACH_AFI_SAFI (afi, safi)
6956 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6957 }
6958
6959 /*
6960 * gpz 110624
6961 * Currently this is used to set static routes for VPN and ENCAP.
6962 * I think it can probably be factored with bgp_static_set.
6963 */
6964 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6965 const char *ip_str, const char *rd_str,
6966 const char *label_str, const char *rmap_str,
6967 int evpn_type, const char *esi, const char *gwip,
6968 const char *ethtag, const char *routermac)
6969 {
6970 VTY_DECLVAR_CONTEXT(bgp, bgp);
6971 int ret;
6972 struct prefix p;
6973 struct prefix_rd prd;
6974 struct bgp_dest *pdest;
6975 struct bgp_dest *dest;
6976 struct bgp_table *table;
6977 struct bgp_static *bgp_static;
6978 mpls_label_t label = MPLS_INVALID_LABEL;
6979 struct prefix gw_ip;
6980
6981 /* validate ip prefix */
6982 ret = str2prefix(ip_str, &p);
6983 if (!ret) {
6984 vty_out(vty, "%% Malformed prefix\n");
6985 return CMD_WARNING_CONFIG_FAILED;
6986 }
6987 apply_mask(&p);
6988 if ((afi == AFI_L2VPN)
6989 && (bgp_build_evpn_prefix(evpn_type,
6990 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6991 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6992 return CMD_WARNING_CONFIG_FAILED;
6993 }
6994
6995 ret = str2prefix_rd(rd_str, &prd);
6996 if (!ret) {
6997 vty_out(vty, "%% Malformed rd\n");
6998 return CMD_WARNING_CONFIG_FAILED;
6999 }
7000
7001 if (label_str) {
7002 unsigned long label_val;
7003 label_val = strtoul(label_str, NULL, 10);
7004 encode_label(label_val, &label);
7005 }
7006
7007 if (safi == SAFI_EVPN) {
7008 if (esi && str2esi(esi, NULL) == 0) {
7009 vty_out(vty, "%% Malformed ESI\n");
7010 return CMD_WARNING_CONFIG_FAILED;
7011 }
7012 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
7013 vty_out(vty, "%% Malformed Router MAC\n");
7014 return CMD_WARNING_CONFIG_FAILED;
7015 }
7016 if (gwip) {
7017 memset(&gw_ip, 0, sizeof(gw_ip));
7018 ret = str2prefix(gwip, &gw_ip);
7019 if (!ret) {
7020 vty_out(vty, "%% Malformed GatewayIp\n");
7021 return CMD_WARNING_CONFIG_FAILED;
7022 }
7023 if ((gw_ip.family == AF_INET
7024 && is_evpn_prefix_ipaddr_v6(
7025 (struct prefix_evpn *)&p))
7026 || (gw_ip.family == AF_INET6
7027 && is_evpn_prefix_ipaddr_v4(
7028 (struct prefix_evpn *)&p))) {
7029 vty_out(vty,
7030 "%% GatewayIp family differs with IP prefix\n");
7031 return CMD_WARNING_CONFIG_FAILED;
7032 }
7033 }
7034 }
7035 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7036 if (!bgp_dest_has_bgp_path_info_data(pdest))
7037 bgp_dest_set_bgp_table_info(pdest,
7038 bgp_table_init(bgp, afi, safi));
7039 table = bgp_dest_get_bgp_table_info(pdest);
7040
7041 dest = bgp_node_get(table, &p);
7042
7043 if (bgp_dest_has_bgp_path_info_data(dest)) {
7044 vty_out(vty, "%% Same network configuration exists\n");
7045 bgp_dest_unlock_node(dest);
7046 } else {
7047 /* New configuration. */
7048 bgp_static = bgp_static_new();
7049 bgp_static->backdoor = 0;
7050 bgp_static->valid = 0;
7051 bgp_static->igpmetric = 0;
7052 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7053 bgp_static->label = label;
7054 bgp_static->prd = prd;
7055
7056 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
7057
7058 if (rmap_str) {
7059 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7060 route_map_counter_decrement(bgp_static->rmap.map);
7061 bgp_static->rmap.name =
7062 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7063 bgp_static->rmap.map =
7064 route_map_lookup_by_name(rmap_str);
7065 route_map_counter_increment(bgp_static->rmap.map);
7066 }
7067
7068 if (safi == SAFI_EVPN) {
7069 if (esi) {
7070 bgp_static->eth_s_id =
7071 XCALLOC(MTYPE_ATTR,
7072 sizeof(esi_t));
7073 str2esi(esi, bgp_static->eth_s_id);
7074 }
7075 if (routermac) {
7076 bgp_static->router_mac =
7077 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7078 (void)prefix_str2mac(routermac,
7079 bgp_static->router_mac);
7080 }
7081 if (gwip)
7082 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7083 }
7084 bgp_dest_set_bgp_static_info(dest, bgp_static);
7085
7086 bgp_static->valid = 1;
7087 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7088 }
7089
7090 return CMD_SUCCESS;
7091 }
7092
7093 /* Configure static BGP network. */
7094 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7095 const char *ip_str, const char *rd_str,
7096 const char *label_str, int evpn_type, const char *esi,
7097 const char *gwip, const char *ethtag)
7098 {
7099 VTY_DECLVAR_CONTEXT(bgp, bgp);
7100 int ret;
7101 struct prefix p;
7102 struct prefix_rd prd;
7103 struct bgp_dest *pdest;
7104 struct bgp_dest *dest;
7105 struct bgp_table *table;
7106 struct bgp_static *bgp_static;
7107 mpls_label_t label = MPLS_INVALID_LABEL;
7108
7109 /* Convert IP prefix string to struct prefix. */
7110 ret = str2prefix(ip_str, &p);
7111 if (!ret) {
7112 vty_out(vty, "%% Malformed prefix\n");
7113 return CMD_WARNING_CONFIG_FAILED;
7114 }
7115 apply_mask(&p);
7116 if ((afi == AFI_L2VPN)
7117 && (bgp_build_evpn_prefix(evpn_type,
7118 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7119 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7120 return CMD_WARNING_CONFIG_FAILED;
7121 }
7122 ret = str2prefix_rd(rd_str, &prd);
7123 if (!ret) {
7124 vty_out(vty, "%% Malformed rd\n");
7125 return CMD_WARNING_CONFIG_FAILED;
7126 }
7127
7128 if (label_str) {
7129 unsigned long label_val;
7130 label_val = strtoul(label_str, NULL, 10);
7131 encode_label(label_val, &label);
7132 }
7133
7134 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7135 if (!bgp_dest_has_bgp_path_info_data(pdest))
7136 bgp_dest_set_bgp_table_info(pdest,
7137 bgp_table_init(bgp, afi, safi));
7138 else
7139 bgp_dest_unlock_node(pdest);
7140 table = bgp_dest_get_bgp_table_info(pdest);
7141
7142 dest = bgp_node_lookup(table, &p);
7143
7144 if (dest) {
7145 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7146
7147 bgp_static = bgp_dest_get_bgp_static_info(dest);
7148 bgp_static_free(bgp_static);
7149 bgp_dest_set_bgp_static_info(dest, NULL);
7150 bgp_dest_unlock_node(dest);
7151 bgp_dest_unlock_node(dest);
7152 } else
7153 vty_out(vty, "%% Can't find the route\n");
7154
7155 return CMD_SUCCESS;
7156 }
7157
7158 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7159 const char *rmap_name)
7160 {
7161 VTY_DECLVAR_CONTEXT(bgp, bgp);
7162 struct bgp_rmap *rmap;
7163
7164 rmap = &bgp->table_map[afi][safi];
7165 if (rmap_name) {
7166 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7167 route_map_counter_decrement(rmap->map);
7168 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7169 rmap->map = route_map_lookup_by_name(rmap_name);
7170 route_map_counter_increment(rmap->map);
7171 } else {
7172 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7173 route_map_counter_decrement(rmap->map);
7174 rmap->map = NULL;
7175 }
7176
7177 if (bgp_fibupd_safi(safi))
7178 bgp_zebra_announce_table(bgp, afi, safi);
7179
7180 return CMD_SUCCESS;
7181 }
7182
7183 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7184 const char *rmap_name)
7185 {
7186 VTY_DECLVAR_CONTEXT(bgp, bgp);
7187 struct bgp_rmap *rmap;
7188
7189 rmap = &bgp->table_map[afi][safi];
7190 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7191 route_map_counter_decrement(rmap->map);
7192 rmap->map = NULL;
7193
7194 if (bgp_fibupd_safi(safi))
7195 bgp_zebra_announce_table(bgp, afi, safi);
7196
7197 return CMD_SUCCESS;
7198 }
7199
7200 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7201 safi_t safi)
7202 {
7203 if (bgp->table_map[afi][safi].name) {
7204 vty_out(vty, " table-map %s\n",
7205 bgp->table_map[afi][safi].name);
7206 }
7207 }
7208
7209 DEFUN (bgp_table_map,
7210 bgp_table_map_cmd,
7211 "table-map WORD",
7212 "BGP table to RIB route download filter\n"
7213 "Name of the route map\n")
7214 {
7215 int idx_word = 1;
7216 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7217 argv[idx_word]->arg);
7218 }
7219 DEFUN (no_bgp_table_map,
7220 no_bgp_table_map_cmd,
7221 "no table-map WORD",
7222 NO_STR
7223 "BGP table to RIB route download filter\n"
7224 "Name of the route map\n")
7225 {
7226 int idx_word = 2;
7227 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7228 argv[idx_word]->arg);
7229 }
7230
7231 DEFPY(bgp_network,
7232 bgp_network_cmd,
7233 "[no] network \
7234 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7235 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7236 backdoor$backdoor}]",
7237 NO_STR
7238 "Specify a network to announce via BGP\n"
7239 "IPv4 prefix\n"
7240 "Network number\n"
7241 "Network mask\n"
7242 "Network mask\n"
7243 "Route-map to modify the attributes\n"
7244 "Name of the route map\n"
7245 "Label index to associate with the prefix\n"
7246 "Label index value\n"
7247 "Specify a BGP backdoor route\n")
7248 {
7249 char addr_prefix_str[BUFSIZ];
7250
7251 if (address_str) {
7252 int ret;
7253
7254 ret = netmask_str2prefix_str(address_str, netmask_str,
7255 addr_prefix_str,
7256 sizeof(addr_prefix_str));
7257 if (!ret) {
7258 vty_out(vty, "%% Inconsistent address and mask\n");
7259 return CMD_WARNING_CONFIG_FAILED;
7260 }
7261 }
7262
7263 return bgp_static_set(
7264 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7265 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7266 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7267 }
7268
7269 DEFPY(ipv6_bgp_network,
7270 ipv6_bgp_network_cmd,
7271 "[no] network X:X::X:X/M$prefix \
7272 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7273 NO_STR
7274 "Specify a network to announce via BGP\n"
7275 "IPv6 prefix\n"
7276 "Route-map to modify the attributes\n"
7277 "Name of the route map\n"
7278 "Label index to associate with the prefix\n"
7279 "Label index value\n")
7280 {
7281 return bgp_static_set(
7282 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7283 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7284 }
7285
7286 static struct bgp_aggregate *bgp_aggregate_new(void)
7287 {
7288 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7289 }
7290
7291 void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7292 {
7293 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7294 route_map_counter_decrement(aggregate->suppress_map);
7295 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7296 route_map_counter_decrement(aggregate->rmap.map);
7297 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7298 }
7299
7300 /**
7301 * Helper function to avoid repeated code: prepare variables for a
7302 * `route_map_apply` call.
7303 *
7304 * \returns `true` on route map match, otherwise `false`.
7305 */
7306 static bool aggr_suppress_map_test(struct bgp *bgp,
7307 struct bgp_aggregate *aggregate,
7308 struct bgp_path_info *pi)
7309 {
7310 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7311 route_map_result_t rmr = RMAP_DENYMATCH;
7312 struct bgp_path_info rmap_path = {};
7313 struct attr attr = {};
7314
7315 /* No route map entries created, just don't match. */
7316 if (aggregate->suppress_map == NULL)
7317 return false;
7318
7319 /* Call route map matching and return result. */
7320 attr.aspath = aspath_empty(bgp->asnotation);
7321 rmap_path.peer = bgp->peer_self;
7322 rmap_path.attr = &attr;
7323
7324 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7325 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7326 bgp->peer_self->rmap_type = 0;
7327
7328 bgp_attr_flush(&attr);
7329 aspath_unintern(&attr.aspath);
7330
7331 return rmr == RMAP_PERMITMATCH;
7332 }
7333
7334 /** Test whether the aggregation has suppressed this path or not. */
7335 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7336 struct bgp_path_info *pi)
7337 {
7338 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7339 return false;
7340
7341 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7342 }
7343
7344 /**
7345 * Suppress this path and keep the reference.
7346 *
7347 * \returns `true` if needs processing otherwise `false`.
7348 */
7349 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7350 struct bgp_path_info *pi)
7351 {
7352 struct bgp_path_info_extra *pie;
7353
7354 /* Path is already suppressed by this aggregation. */
7355 if (aggr_suppress_exists(aggregate, pi))
7356 return false;
7357
7358 pie = bgp_path_info_extra_get(pi);
7359
7360 /* This is the first suppression, allocate memory and list it. */
7361 if (pie->aggr_suppressors == NULL)
7362 pie->aggr_suppressors = list_new();
7363
7364 listnode_add(pie->aggr_suppressors, aggregate);
7365
7366 /* Only mark for processing if suppressed. */
7367 if (listcount(pie->aggr_suppressors) == 1) {
7368 if (BGP_DEBUG(update, UPDATE_OUT))
7369 zlog_debug("aggregate-address suppressing: %pFX",
7370 bgp_dest_get_prefix(pi->net));
7371
7372 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7373 return true;
7374 }
7375
7376 return false;
7377 }
7378
7379 /**
7380 * Unsuppress this path and remove the reference.
7381 *
7382 * \returns `true` if needs processing otherwise `false`.
7383 */
7384 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7385 struct bgp_path_info *pi)
7386 {
7387 /* Path wasn't suppressed. */
7388 if (!aggr_suppress_exists(aggregate, pi))
7389 return false;
7390
7391 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7392
7393 /* Unsuppress and free extra memory if last item. */
7394 if (listcount(pi->extra->aggr_suppressors) == 0) {
7395 if (BGP_DEBUG(update, UPDATE_OUT))
7396 zlog_debug("aggregate-address unsuppressing: %pFX",
7397 bgp_dest_get_prefix(pi->net));
7398
7399 list_delete(&pi->extra->aggr_suppressors);
7400 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7401 return true;
7402 }
7403
7404 return false;
7405 }
7406
7407 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7408 struct aspath *aspath,
7409 struct community *comm,
7410 struct ecommunity *ecomm,
7411 struct lcommunity *lcomm)
7412 {
7413 static struct aspath *ae = NULL;
7414 enum asnotation_mode asnotation;
7415
7416 asnotation = bgp_get_asnotation(NULL);
7417
7418 if (!ae)
7419 ae = aspath_empty(asnotation);
7420
7421 if (!pi)
7422 return false;
7423
7424 if (origin != pi->attr->origin)
7425 return false;
7426
7427 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7428 return false;
7429
7430 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7431 return false;
7432
7433 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7434 return false;
7435
7436 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7437 return false;
7438
7439 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7440 return false;
7441
7442 return true;
7443 }
7444
7445 static void bgp_aggregate_install(
7446 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7447 uint8_t origin, struct aspath *aspath, struct community *community,
7448 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7449 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7450 {
7451 struct bgp_dest *dest;
7452 struct bgp_table *table;
7453 struct bgp_path_info *pi, *orig, *new;
7454 struct attr *attr;
7455
7456 table = bgp->rib[afi][safi];
7457
7458 dest = bgp_node_get(table, p);
7459
7460 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7461 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7462 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7463 break;
7464
7465 /*
7466 * If we have paths with different MEDs, then don't install
7467 * (or uninstall) the aggregate route.
7468 */
7469 if (aggregate->match_med && aggregate->med_mismatched)
7470 goto uninstall_aggregate_route;
7471
7472 if (aggregate->count > 0) {
7473 /*
7474 * If the aggregate information has not changed
7475 * no need to re-install it again.
7476 */
7477 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7478 ecommunity, lcommunity)) {
7479 bgp_dest_unlock_node(dest);
7480
7481 if (aspath)
7482 aspath_free(aspath);
7483 if (community)
7484 community_free(&community);
7485 if (ecommunity)
7486 ecommunity_free(&ecommunity);
7487 if (lcommunity)
7488 lcommunity_free(&lcommunity);
7489
7490 return;
7491 }
7492
7493 /*
7494 * Mark the old as unusable
7495 */
7496 if (pi)
7497 bgp_path_info_delete(dest, pi);
7498
7499 attr = bgp_attr_aggregate_intern(
7500 bgp, origin, aspath, community, ecommunity, lcommunity,
7501 aggregate, atomic_aggregate, p);
7502
7503 if (!attr) {
7504 aspath_free(aspath);
7505 community_free(&community);
7506 ecommunity_free(&ecommunity);
7507 lcommunity_free(&lcommunity);
7508 bgp_dest_unlock_node(dest);
7509 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7510 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7511 zlog_debug("%s: %pFX null attribute", __func__,
7512 p);
7513 return;
7514 }
7515
7516 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7517 bgp->peer_self, attr, dest);
7518
7519 SET_FLAG(new->flags, BGP_PATH_VALID);
7520
7521 bgp_path_info_add(dest, new);
7522 bgp_process(bgp, dest, afi, safi);
7523 } else {
7524 uninstall_aggregate_route:
7525 for (pi = orig; pi; pi = pi->next)
7526 if (pi->peer == bgp->peer_self
7527 && pi->type == ZEBRA_ROUTE_BGP
7528 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7529 break;
7530
7531 /* Withdraw static BGP route from routing table. */
7532 if (pi) {
7533 bgp_path_info_delete(dest, pi);
7534 bgp_process(bgp, dest, afi, safi);
7535 }
7536 }
7537
7538 bgp_dest_unlock_node(dest);
7539 }
7540
7541 /**
7542 * Check if the current path has different MED than other known paths.
7543 *
7544 * \returns `true` if the MED matched the others else `false`.
7545 */
7546 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7547 struct bgp *bgp, struct bgp_path_info *pi)
7548 {
7549 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7550
7551 /* This is the first route being analyzed. */
7552 if (!aggregate->med_initialized) {
7553 aggregate->med_initialized = true;
7554 aggregate->med_mismatched = false;
7555 aggregate->med_matched_value = cur_med;
7556 } else {
7557 /* Check if routes with different MED showed up. */
7558 if (cur_med != aggregate->med_matched_value)
7559 aggregate->med_mismatched = true;
7560 }
7561
7562 return !aggregate->med_mismatched;
7563 }
7564
7565 /**
7566 * Initializes and tests all routes in the aggregate address path for MED
7567 * values.
7568 *
7569 * \returns `true` if all MEDs are the same otherwise `false`.
7570 */
7571 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7572 struct bgp *bgp, const struct prefix *p,
7573 afi_t afi, safi_t safi)
7574 {
7575 struct bgp_table *table = bgp->rib[afi][safi];
7576 const struct prefix *dest_p;
7577 struct bgp_dest *dest, *top;
7578 struct bgp_path_info *pi;
7579 bool med_matched = true;
7580
7581 aggregate->med_initialized = false;
7582
7583 top = bgp_node_get(table, p);
7584 for (dest = bgp_node_get(table, p); dest;
7585 dest = bgp_route_next_until(dest, top)) {
7586 dest_p = bgp_dest_get_prefix(dest);
7587 if (dest_p->prefixlen <= p->prefixlen)
7588 continue;
7589
7590 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7591 if (BGP_PATH_HOLDDOWN(pi))
7592 continue;
7593 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7594 continue;
7595 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7596 med_matched = false;
7597 break;
7598 }
7599 }
7600 if (!med_matched)
7601 break;
7602 }
7603 bgp_dest_unlock_node(top);
7604
7605 return med_matched;
7606 }
7607
7608 /**
7609 * Toggles the route suppression status for this aggregate address
7610 * configuration.
7611 */
7612 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7613 struct bgp *bgp, const struct prefix *p,
7614 afi_t afi, safi_t safi, bool suppress)
7615 {
7616 struct bgp_table *table = bgp->rib[afi][safi];
7617 const struct prefix *dest_p;
7618 struct bgp_dest *dest, *top;
7619 struct bgp_path_info *pi;
7620 bool toggle_suppression;
7621
7622 /* We've found a different MED we must revert any suppressed routes. */
7623 top = bgp_node_get(table, p);
7624 for (dest = bgp_node_get(table, p); dest;
7625 dest = bgp_route_next_until(dest, top)) {
7626 dest_p = bgp_dest_get_prefix(dest);
7627 if (dest_p->prefixlen <= p->prefixlen)
7628 continue;
7629
7630 toggle_suppression = false;
7631 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7632 if (BGP_PATH_HOLDDOWN(pi))
7633 continue;
7634 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7635 continue;
7636
7637 /* We are toggling suppression back. */
7638 if (suppress) {
7639 /* Suppress route if not suppressed already. */
7640 if (aggr_suppress_path(aggregate, pi))
7641 toggle_suppression = true;
7642 continue;
7643 }
7644
7645 /* Install route if there is no more suppression. */
7646 if (aggr_unsuppress_path(aggregate, pi))
7647 toggle_suppression = true;
7648 }
7649
7650 if (toggle_suppression)
7651 bgp_process(bgp, dest, afi, safi);
7652 }
7653 bgp_dest_unlock_node(top);
7654 }
7655
7656 /**
7657 * Aggregate address MED matching incremental test: this function is called
7658 * when the initial aggregation occurred and we are only testing a single
7659 * new path.
7660 *
7661 * In addition to testing and setting the MED validity it also installs back
7662 * suppressed routes (if summary is configured).
7663 *
7664 * Must not be called in `bgp_aggregate_route`.
7665 */
7666 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7667 struct bgp *bgp, const struct prefix *p,
7668 afi_t afi, safi_t safi,
7669 struct bgp_path_info *pi)
7670 {
7671 /* MED matching disabled. */
7672 if (!aggregate->match_med)
7673 return;
7674
7675 /* Aggregation with different MED, recheck if we have got equal MEDs
7676 * now.
7677 */
7678 if (aggregate->med_mismatched &&
7679 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7680 aggregate->summary_only)
7681 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7682 true);
7683 else
7684 bgp_aggregate_med_match(aggregate, bgp, pi);
7685
7686 /* No mismatches, just quit. */
7687 if (!aggregate->med_mismatched)
7688 return;
7689
7690 /* Route summarization is disabled. */
7691 if (!aggregate->summary_only)
7692 return;
7693
7694 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7695 }
7696
7697 /* Update an aggregate as routes are added/removed from the BGP table */
7698 bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7699 safi_t safi, struct bgp_aggregate *aggregate)
7700 {
7701 struct bgp_table *table;
7702 struct bgp_dest *top;
7703 struct bgp_dest *dest;
7704 uint8_t origin;
7705 struct aspath *aspath = NULL;
7706 struct community *community = NULL;
7707 struct ecommunity *ecommunity = NULL;
7708 struct lcommunity *lcommunity = NULL;
7709 struct bgp_path_info *pi;
7710 unsigned long match = 0;
7711 uint8_t atomic_aggregate = 0;
7712
7713 /* If the bgp instance is being deleted or self peer is deleted
7714 * then do not create aggregate route
7715 */
7716 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
7717 bgp->peer_self == NULL)
7718 return false;
7719
7720 /* Initialize and test routes for MED difference. */
7721 if (aggregate->match_med)
7722 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7723
7724 /*
7725 * Reset aggregate count: we might've been called from route map
7726 * update so in that case we must retest all more specific routes.
7727 *
7728 * \see `bgp_route_map_process_update`.
7729 */
7730 aggregate->count = 0;
7731 aggregate->incomplete_origin_count = 0;
7732 aggregate->incomplete_origin_count = 0;
7733 aggregate->egp_origin_count = 0;
7734
7735 /* ORIGIN attribute: If at least one route among routes that are
7736 aggregated has ORIGIN with the value INCOMPLETE, then the
7737 aggregated route must have the ORIGIN attribute with the value
7738 INCOMPLETE. Otherwise, if at least one route among routes that
7739 are aggregated has ORIGIN with the value EGP, then the aggregated
7740 route must have the origin attribute with the value EGP. In all
7741 other case the value of the ORIGIN attribute of the aggregated
7742 route is INTERNAL. */
7743 origin = BGP_ORIGIN_IGP;
7744
7745 table = bgp->rib[afi][safi];
7746
7747 top = bgp_node_get(table, p);
7748 for (dest = bgp_node_get(table, p); dest;
7749 dest = bgp_route_next_until(dest, top)) {
7750 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7751
7752 if (dest_p->prefixlen <= p->prefixlen)
7753 continue;
7754
7755 /* If suppress fib is enabled and route not installed
7756 * in FIB, skip the route
7757 */
7758 if (!bgp_check_advertise(bgp, dest))
7759 continue;
7760
7761 match = 0;
7762
7763 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7764 if (BGP_PATH_HOLDDOWN(pi))
7765 continue;
7766
7767 if (pi->attr->flag
7768 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7769 atomic_aggregate = 1;
7770
7771 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7772 continue;
7773
7774 /*
7775 * summary-only aggregate route suppress
7776 * aggregated route announcements.
7777 *
7778 * MED matching:
7779 * Don't create summaries if MED didn't match
7780 * otherwise neither the specific routes and the
7781 * aggregation will be announced.
7782 */
7783 if (aggregate->summary_only
7784 && AGGREGATE_MED_VALID(aggregate)) {
7785 if (aggr_suppress_path(aggregate, pi))
7786 match++;
7787 }
7788
7789 /*
7790 * Suppress more specific routes that match the route
7791 * map results.
7792 *
7793 * MED matching:
7794 * Don't suppress routes if MED matching is enabled and
7795 * it mismatched otherwise we might end up with no
7796 * routes for this path.
7797 */
7798 if (aggregate->suppress_map_name
7799 && AGGREGATE_MED_VALID(aggregate)
7800 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7801 if (aggr_suppress_path(aggregate, pi))
7802 match++;
7803 }
7804
7805 aggregate->count++;
7806
7807 /*
7808 * If at least one route among routes that are
7809 * aggregated has ORIGIN with the value INCOMPLETE,
7810 * then the aggregated route MUST have the ORIGIN
7811 * attribute with the value INCOMPLETE. Otherwise, if
7812 * at least one route among routes that are aggregated
7813 * has ORIGIN with the value EGP, then the aggregated
7814 * route MUST have the ORIGIN attribute with the value
7815 * EGP.
7816 */
7817 switch (pi->attr->origin) {
7818 case BGP_ORIGIN_INCOMPLETE:
7819 aggregate->incomplete_origin_count++;
7820 break;
7821 case BGP_ORIGIN_EGP:
7822 aggregate->egp_origin_count++;
7823 break;
7824 default:
7825 /*Do nothing.
7826 */
7827 break;
7828 }
7829
7830 if (!aggregate->as_set)
7831 continue;
7832
7833 /*
7834 * as-set aggregate route generate origin, as path,
7835 * and community aggregation.
7836 */
7837 /* Compute aggregate route's as-path.
7838 */
7839 bgp_compute_aggregate_aspath_hash(aggregate,
7840 pi->attr->aspath);
7841
7842 /* Compute aggregate route's community.
7843 */
7844 if (bgp_attr_get_community(pi->attr))
7845 bgp_compute_aggregate_community_hash(
7846 aggregate,
7847 bgp_attr_get_community(pi->attr));
7848
7849 /* Compute aggregate route's extended community.
7850 */
7851 if (bgp_attr_get_ecommunity(pi->attr))
7852 bgp_compute_aggregate_ecommunity_hash(
7853 aggregate,
7854 bgp_attr_get_ecommunity(pi->attr));
7855
7856 /* Compute aggregate route's large community.
7857 */
7858 if (bgp_attr_get_lcommunity(pi->attr))
7859 bgp_compute_aggregate_lcommunity_hash(
7860 aggregate,
7861 bgp_attr_get_lcommunity(pi->attr));
7862 }
7863 if (match)
7864 bgp_process(bgp, dest, afi, safi);
7865 }
7866 if (aggregate->as_set) {
7867 bgp_compute_aggregate_aspath_val(aggregate);
7868 bgp_compute_aggregate_community_val(aggregate);
7869 bgp_compute_aggregate_ecommunity_val(aggregate);
7870 bgp_compute_aggregate_lcommunity_val(aggregate);
7871 }
7872
7873
7874 bgp_dest_unlock_node(top);
7875
7876
7877 if (aggregate->incomplete_origin_count > 0)
7878 origin = BGP_ORIGIN_INCOMPLETE;
7879 else if (aggregate->egp_origin_count > 0)
7880 origin = BGP_ORIGIN_EGP;
7881
7882 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7883 origin = aggregate->origin;
7884
7885 if (aggregate->as_set) {
7886 if (aggregate->aspath)
7887 /* Retrieve aggregate route's as-path.
7888 */
7889 aspath = aspath_dup(aggregate->aspath);
7890
7891 if (aggregate->community)
7892 /* Retrieve aggregate route's community.
7893 */
7894 community = community_dup(aggregate->community);
7895
7896 if (aggregate->ecommunity)
7897 /* Retrieve aggregate route's ecommunity.
7898 */
7899 ecommunity = ecommunity_dup(aggregate->ecommunity);
7900
7901 if (aggregate->lcommunity)
7902 /* Retrieve aggregate route's lcommunity.
7903 */
7904 lcommunity = lcommunity_dup(aggregate->lcommunity);
7905 }
7906
7907 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7908 ecommunity, lcommunity, atomic_aggregate,
7909 aggregate);
7910
7911 return true;
7912 }
7913
7914 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7915 safi_t safi, struct bgp_aggregate *aggregate)
7916 {
7917 struct bgp_table *table;
7918 struct bgp_dest *top;
7919 struct bgp_dest *dest;
7920 struct bgp_path_info *pi;
7921 unsigned long match;
7922
7923 table = bgp->rib[afi][safi];
7924
7925 /* If routes exists below this node, generate aggregate routes. */
7926 top = bgp_node_get(table, p);
7927 for (dest = bgp_node_get(table, p); dest;
7928 dest = bgp_route_next_until(dest, top)) {
7929 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7930
7931 if (dest_p->prefixlen <= p->prefixlen)
7932 continue;
7933 match = 0;
7934
7935 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7936 if (BGP_PATH_HOLDDOWN(pi))
7937 continue;
7938
7939 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7940 continue;
7941
7942 /*
7943 * This route is suppressed: attempt to unsuppress it.
7944 *
7945 * `aggr_unsuppress_path` will fail if this particular
7946 * aggregate route was not the suppressor.
7947 */
7948 if (pi->extra && pi->extra->aggr_suppressors &&
7949 listcount(pi->extra->aggr_suppressors)) {
7950 if (aggr_unsuppress_path(aggregate, pi))
7951 match++;
7952 }
7953
7954 aggregate->count--;
7955
7956 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7957 aggregate->incomplete_origin_count--;
7958 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7959 aggregate->egp_origin_count--;
7960
7961 if (aggregate->as_set) {
7962 /* Remove as-path from aggregate.
7963 */
7964 bgp_remove_aspath_from_aggregate_hash(
7965 aggregate,
7966 pi->attr->aspath);
7967
7968 if (bgp_attr_get_community(pi->attr))
7969 /* Remove community from aggregate.
7970 */
7971 bgp_remove_comm_from_aggregate_hash(
7972 aggregate,
7973 bgp_attr_get_community(
7974 pi->attr));
7975
7976 if (bgp_attr_get_ecommunity(pi->attr))
7977 /* Remove ecommunity from aggregate.
7978 */
7979 bgp_remove_ecomm_from_aggregate_hash(
7980 aggregate,
7981 bgp_attr_get_ecommunity(
7982 pi->attr));
7983
7984 if (bgp_attr_get_lcommunity(pi->attr))
7985 /* Remove lcommunity from aggregate.
7986 */
7987 bgp_remove_lcomm_from_aggregate_hash(
7988 aggregate,
7989 bgp_attr_get_lcommunity(
7990 pi->attr));
7991 }
7992 }
7993
7994 /* If this node was suppressed, process the change. */
7995 if (match)
7996 bgp_process(bgp, dest, afi, safi);
7997 }
7998 if (aggregate->as_set) {
7999 aspath_free(aggregate->aspath);
8000 aggregate->aspath = NULL;
8001 if (aggregate->community)
8002 community_free(&aggregate->community);
8003 if (aggregate->ecommunity)
8004 ecommunity_free(&aggregate->ecommunity);
8005 if (aggregate->lcommunity)
8006 lcommunity_free(&aggregate->lcommunity);
8007 }
8008
8009 bgp_dest_unlock_node(top);
8010 }
8011
8012 static void bgp_add_route_to_aggregate(struct bgp *bgp,
8013 const struct prefix *aggr_p,
8014 struct bgp_path_info *pinew, afi_t afi,
8015 safi_t safi,
8016 struct bgp_aggregate *aggregate)
8017 {
8018 uint8_t origin;
8019 struct aspath *aspath = NULL;
8020 uint8_t atomic_aggregate = 0;
8021 struct community *community = NULL;
8022 struct ecommunity *ecommunity = NULL;
8023 struct lcommunity *lcommunity = NULL;
8024
8025 /* If the bgp instance is being deleted or self peer is deleted
8026 * then do not create aggregate route
8027 */
8028 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8029 || (bgp->peer_self == NULL))
8030 return;
8031
8032 /* ORIGIN attribute: If at least one route among routes that are
8033 * aggregated has ORIGIN with the value INCOMPLETE, then the
8034 * aggregated route must have the ORIGIN attribute with the value
8035 * INCOMPLETE. Otherwise, if at least one route among routes that
8036 * are aggregated has ORIGIN with the value EGP, then the aggregated
8037 * route must have the origin attribute with the value EGP. In all
8038 * other case the value of the ORIGIN attribute of the aggregated
8039 * route is INTERNAL.
8040 */
8041 origin = BGP_ORIGIN_IGP;
8042
8043 aggregate->count++;
8044
8045 /*
8046 * This must be called before `summary` check to avoid
8047 * "suppressing" twice.
8048 */
8049 if (aggregate->match_med)
8050 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8051 pinew);
8052
8053 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8054 aggr_suppress_path(aggregate, pinew);
8055
8056 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8057 && aggr_suppress_map_test(bgp, aggregate, pinew))
8058 aggr_suppress_path(aggregate, pinew);
8059
8060 switch (pinew->attr->origin) {
8061 case BGP_ORIGIN_INCOMPLETE:
8062 aggregate->incomplete_origin_count++;
8063 break;
8064 case BGP_ORIGIN_EGP:
8065 aggregate->egp_origin_count++;
8066 break;
8067 default:
8068 /* Do nothing.
8069 */
8070 break;
8071 }
8072
8073 if (aggregate->incomplete_origin_count > 0)
8074 origin = BGP_ORIGIN_INCOMPLETE;
8075 else if (aggregate->egp_origin_count > 0)
8076 origin = BGP_ORIGIN_EGP;
8077
8078 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8079 origin = aggregate->origin;
8080
8081 if (aggregate->as_set) {
8082 /* Compute aggregate route's as-path.
8083 */
8084 bgp_compute_aggregate_aspath(aggregate,
8085 pinew->attr->aspath);
8086
8087 /* Compute aggregate route's community.
8088 */
8089 if (bgp_attr_get_community(pinew->attr))
8090 bgp_compute_aggregate_community(
8091 aggregate, bgp_attr_get_community(pinew->attr));
8092
8093 /* Compute aggregate route's extended community.
8094 */
8095 if (bgp_attr_get_ecommunity(pinew->attr))
8096 bgp_compute_aggregate_ecommunity(
8097 aggregate,
8098 bgp_attr_get_ecommunity(pinew->attr));
8099
8100 /* Compute aggregate route's large community.
8101 */
8102 if (bgp_attr_get_lcommunity(pinew->attr))
8103 bgp_compute_aggregate_lcommunity(
8104 aggregate,
8105 bgp_attr_get_lcommunity(pinew->attr));
8106
8107 /* Retrieve aggregate route's as-path.
8108 */
8109 if (aggregate->aspath)
8110 aspath = aspath_dup(aggregate->aspath);
8111
8112 /* Retrieve aggregate route's community.
8113 */
8114 if (aggregate->community)
8115 community = community_dup(aggregate->community);
8116
8117 /* Retrieve aggregate route's ecommunity.
8118 */
8119 if (aggregate->ecommunity)
8120 ecommunity = ecommunity_dup(aggregate->ecommunity);
8121
8122 /* Retrieve aggregate route's lcommunity.
8123 */
8124 if (aggregate->lcommunity)
8125 lcommunity = lcommunity_dup(aggregate->lcommunity);
8126 }
8127
8128 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8129 aspath, community, ecommunity,
8130 lcommunity, atomic_aggregate, aggregate);
8131 }
8132
8133 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8134 safi_t safi,
8135 struct bgp_path_info *pi,
8136 struct bgp_aggregate *aggregate,
8137 const struct prefix *aggr_p)
8138 {
8139 uint8_t origin;
8140 struct aspath *aspath = NULL;
8141 uint8_t atomic_aggregate = 0;
8142 struct community *community = NULL;
8143 struct ecommunity *ecommunity = NULL;
8144 struct lcommunity *lcommunity = NULL;
8145 unsigned long match = 0;
8146
8147 /* If the bgp instance is being deleted or self peer is deleted
8148 * then do not create aggregate route
8149 */
8150 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8151 || (bgp->peer_self == NULL))
8152 return;
8153
8154 if (BGP_PATH_HOLDDOWN(pi))
8155 return;
8156
8157 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8158 return;
8159
8160 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8161 if (aggr_unsuppress_path(aggregate, pi))
8162 match++;
8163
8164 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8165 && aggr_suppress_map_test(bgp, aggregate, pi))
8166 if (aggr_unsuppress_path(aggregate, pi))
8167 match++;
8168
8169 /*
8170 * This must be called after `summary`, `suppress-map` check to avoid
8171 * "unsuppressing" twice.
8172 */
8173 if (aggregate->match_med)
8174 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8175
8176 if (aggregate->count > 0)
8177 aggregate->count--;
8178
8179 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8180 aggregate->incomplete_origin_count--;
8181 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8182 aggregate->egp_origin_count--;
8183
8184 if (aggregate->as_set) {
8185 /* Remove as-path from aggregate.
8186 */
8187 bgp_remove_aspath_from_aggregate(aggregate,
8188 pi->attr->aspath);
8189
8190 if (bgp_attr_get_community(pi->attr))
8191 /* Remove community from aggregate.
8192 */
8193 bgp_remove_community_from_aggregate(
8194 aggregate, bgp_attr_get_community(pi->attr));
8195
8196 if (bgp_attr_get_ecommunity(pi->attr))
8197 /* Remove ecommunity from aggregate.
8198 */
8199 bgp_remove_ecommunity_from_aggregate(
8200 aggregate, bgp_attr_get_ecommunity(pi->attr));
8201
8202 if (bgp_attr_get_lcommunity(pi->attr))
8203 /* Remove lcommunity from aggregate.
8204 */
8205 bgp_remove_lcommunity_from_aggregate(
8206 aggregate, bgp_attr_get_lcommunity(pi->attr));
8207 }
8208
8209 /* If this node was suppressed, process the change. */
8210 if (match)
8211 bgp_process(bgp, pi->net, afi, safi);
8212
8213 origin = BGP_ORIGIN_IGP;
8214 if (aggregate->incomplete_origin_count > 0)
8215 origin = BGP_ORIGIN_INCOMPLETE;
8216 else if (aggregate->egp_origin_count > 0)
8217 origin = BGP_ORIGIN_EGP;
8218
8219 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8220 origin = aggregate->origin;
8221
8222 if (aggregate->as_set) {
8223 /* Retrieve aggregate route's as-path.
8224 */
8225 if (aggregate->aspath)
8226 aspath = aspath_dup(aggregate->aspath);
8227
8228 /* Retrieve aggregate route's community.
8229 */
8230 if (aggregate->community)
8231 community = community_dup(aggregate->community);
8232
8233 /* Retrieve aggregate route's ecommunity.
8234 */
8235 if (aggregate->ecommunity)
8236 ecommunity = ecommunity_dup(aggregate->ecommunity);
8237
8238 /* Retrieve aggregate route's lcommunity.
8239 */
8240 if (aggregate->lcommunity)
8241 lcommunity = lcommunity_dup(aggregate->lcommunity);
8242 }
8243
8244 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8245 aspath, community, ecommunity,
8246 lcommunity, atomic_aggregate, aggregate);
8247 }
8248
8249 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8250 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8251 {
8252 struct bgp_dest *child;
8253 struct bgp_dest *dest;
8254 struct bgp_aggregate *aggregate;
8255 struct bgp_table *table;
8256
8257 table = bgp->aggregate[afi][safi];
8258
8259 /* No aggregates configured. */
8260 if (bgp_table_top_nolock(table) == NULL)
8261 return;
8262
8263 if (p->prefixlen == 0)
8264 return;
8265
8266 if (BGP_PATH_HOLDDOWN(pi))
8267 return;
8268
8269 /* If suppress fib is enabled and route not installed
8270 * in FIB, do not update the aggregate route
8271 */
8272 if (!bgp_check_advertise(bgp, pi->net))
8273 return;
8274
8275 child = bgp_node_get(table, p);
8276
8277 /* Aggregate address configuration check. */
8278 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8279 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8280
8281 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8282 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8283 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8284 aggregate);
8285 }
8286 }
8287 bgp_dest_unlock_node(child);
8288 }
8289
8290 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8291 struct bgp_path_info *del, afi_t afi, safi_t safi)
8292 {
8293 struct bgp_dest *child;
8294 struct bgp_dest *dest;
8295 struct bgp_aggregate *aggregate;
8296 struct bgp_table *table;
8297
8298 table = bgp->aggregate[afi][safi];
8299
8300 /* No aggregates configured. */
8301 if (bgp_table_top_nolock(table) == NULL)
8302 return;
8303
8304 if (p->prefixlen == 0)
8305 return;
8306
8307 child = bgp_node_get(table, p);
8308
8309 /* Aggregate address configuration check. */
8310 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8311 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8312
8313 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8314 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8315 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8316 aggregate, dest_p);
8317 }
8318 }
8319 bgp_dest_unlock_node(child);
8320 }
8321
8322 /* Aggregate route attribute. */
8323 #define AGGREGATE_SUMMARY_ONLY 1
8324 #define AGGREGATE_AS_SET 1
8325 #define AGGREGATE_AS_UNSET 0
8326
8327 static const char *bgp_origin2str(uint8_t origin)
8328 {
8329 switch (origin) {
8330 case BGP_ORIGIN_IGP:
8331 return "igp";
8332 case BGP_ORIGIN_EGP:
8333 return "egp";
8334 case BGP_ORIGIN_INCOMPLETE:
8335 return "incomplete";
8336 }
8337 return "n/a";
8338 }
8339
8340 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8341 {
8342 switch (v_state) {
8343 case RPKI_NOT_BEING_USED:
8344 return "not used";
8345 case RPKI_VALID:
8346 return "valid";
8347 case RPKI_NOTFOUND:
8348 return "not found";
8349 case RPKI_INVALID:
8350 return "invalid";
8351 }
8352
8353 assert(!"We should never get here this is a dev escape");
8354 return "ERROR";
8355 }
8356
8357 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8358 afi_t afi, safi_t safi)
8359 {
8360 VTY_DECLVAR_CONTEXT(bgp, bgp);
8361 int ret;
8362 struct prefix p;
8363 struct bgp_dest *dest;
8364 struct bgp_aggregate *aggregate;
8365
8366 /* Convert string to prefix structure. */
8367 ret = str2prefix(prefix_str, &p);
8368 if (!ret) {
8369 vty_out(vty, "Malformed prefix\n");
8370 return CMD_WARNING_CONFIG_FAILED;
8371 }
8372 apply_mask(&p);
8373
8374 /* Old configuration check. */
8375 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8376 if (!dest) {
8377 vty_out(vty,
8378 "%% There is no aggregate-address configuration.\n");
8379 return CMD_WARNING_CONFIG_FAILED;
8380 }
8381
8382 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8383 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8384 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8385 NULL, NULL, 0, aggregate);
8386
8387 /* Unlock aggregate address configuration. */
8388 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8389
8390 bgp_free_aggregate_info(aggregate);
8391 bgp_dest_unlock_node(dest);
8392 bgp_dest_unlock_node(dest);
8393
8394 return CMD_SUCCESS;
8395 }
8396
8397 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8398 safi_t safi, const char *rmap,
8399 uint8_t summary_only, uint8_t as_set,
8400 uint8_t origin, bool match_med,
8401 const char *suppress_map)
8402 {
8403 VTY_DECLVAR_CONTEXT(bgp, bgp);
8404 int ret;
8405 struct prefix p;
8406 struct bgp_dest *dest;
8407 struct bgp_aggregate *aggregate;
8408 uint8_t as_set_new = as_set;
8409
8410 if (suppress_map && summary_only) {
8411 vty_out(vty,
8412 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8413 return CMD_WARNING_CONFIG_FAILED;
8414 }
8415
8416 /* Convert string to prefix structure. */
8417 ret = str2prefix(prefix_str, &p);
8418 if (!ret) {
8419 vty_out(vty, "Malformed prefix\n");
8420 return CMD_WARNING_CONFIG_FAILED;
8421 }
8422 apply_mask(&p);
8423
8424 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8425 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8426 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8427 prefix_str);
8428 return CMD_WARNING_CONFIG_FAILED;
8429 }
8430
8431 /* Old configuration check. */
8432 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8433 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8434
8435 if (aggregate) {
8436 vty_out(vty, "There is already same aggregate network.\n");
8437 /* try to remove the old entry */
8438 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8439 if (ret) {
8440 vty_out(vty, "Error deleting aggregate.\n");
8441 bgp_dest_unlock_node(dest);
8442 return CMD_WARNING_CONFIG_FAILED;
8443 }
8444 }
8445
8446 /* Make aggregate address structure. */
8447 aggregate = bgp_aggregate_new();
8448 aggregate->summary_only = summary_only;
8449 aggregate->match_med = match_med;
8450
8451 /* Network operators MUST NOT locally generate any new
8452 * announcements containing AS_SET or AS_CONFED_SET. If they have
8453 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8454 * SHOULD withdraw those routes and re-announce routes for the
8455 * aggregate or component prefixes (i.e., the more-specific routes
8456 * subsumed by the previously aggregated route) without AS_SET
8457 * or AS_CONFED_SET in the updates.
8458 */
8459 if (bgp->reject_as_sets) {
8460 if (as_set == AGGREGATE_AS_SET) {
8461 as_set_new = AGGREGATE_AS_UNSET;
8462 zlog_warn(
8463 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8464 __func__);
8465 vty_out(vty,
8466 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8467 }
8468 }
8469
8470 aggregate->as_set = as_set_new;
8471 aggregate->safi = safi;
8472 /* Override ORIGIN attribute if defined.
8473 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8474 * to IGP which is not what rfc4271 says.
8475 * This enables the same behavior, optionally.
8476 */
8477 aggregate->origin = origin;
8478
8479 if (rmap) {
8480 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8481 route_map_counter_decrement(aggregate->rmap.map);
8482 aggregate->rmap.name =
8483 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8484 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8485 route_map_counter_increment(aggregate->rmap.map);
8486 }
8487
8488 if (suppress_map) {
8489 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8490 route_map_counter_decrement(aggregate->suppress_map);
8491
8492 aggregate->suppress_map_name =
8493 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8494 aggregate->suppress_map =
8495 route_map_lookup_by_name(aggregate->suppress_map_name);
8496 route_map_counter_increment(aggregate->suppress_map);
8497 }
8498
8499 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8500
8501 /* Aggregate address insert into BGP routing table. */
8502 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8503 bgp_aggregate_free(aggregate);
8504 bgp_dest_unlock_node(dest);
8505 }
8506
8507 return CMD_SUCCESS;
8508 }
8509
8510 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8511 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8512 "as-set$as_set_s"
8513 "|summary-only$summary_only"
8514 "|route-map RMAP_NAME$rmap_name"
8515 "|origin <egp|igp|incomplete>$origin_s"
8516 "|matching-MED-only$match_med"
8517 "|suppress-map RMAP_NAME$suppress_map"
8518 "}]",
8519 NO_STR
8520 "Configure BGP aggregate entries\n"
8521 "Aggregate prefix\n"
8522 "Aggregate address\n"
8523 "Aggregate mask\n"
8524 "Generate AS set path information\n"
8525 "Filter more specific routes from updates\n"
8526 "Apply route map to aggregate network\n"
8527 "Route map name\n"
8528 "BGP origin code\n"
8529 "Remote EGP\n"
8530 "Local IGP\n"
8531 "Unknown heritage\n"
8532 "Only aggregate routes with matching MED\n"
8533 "Suppress the selected more specific routes\n"
8534 "Route map with the route selectors\n")
8535 {
8536 const char *prefix_s = NULL;
8537 safi_t safi = bgp_node_safi(vty);
8538 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8539 int as_set = AGGREGATE_AS_UNSET;
8540 char prefix_buf[PREFIX2STR_BUFFER];
8541
8542 if (addr_str) {
8543 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8544 sizeof(prefix_buf))
8545 == 0) {
8546 vty_out(vty, "%% Inconsistent address and mask\n");
8547 return CMD_WARNING_CONFIG_FAILED;
8548 }
8549 prefix_s = prefix_buf;
8550 } else
8551 prefix_s = prefix_str;
8552
8553 if (origin_s) {
8554 if (strcmp(origin_s, "egp") == 0)
8555 origin = BGP_ORIGIN_EGP;
8556 else if (strcmp(origin_s, "igp") == 0)
8557 origin = BGP_ORIGIN_IGP;
8558 else if (strcmp(origin_s, "incomplete") == 0)
8559 origin = BGP_ORIGIN_INCOMPLETE;
8560 }
8561
8562 if (as_set_s)
8563 as_set = AGGREGATE_AS_SET;
8564
8565 /* Handle configuration removal, otherwise installation. */
8566 if (no)
8567 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8568
8569 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8570 summary_only != NULL, as_set, origin,
8571 match_med != NULL, suppress_map);
8572 }
8573
8574 void bgp_free_aggregate_info(struct bgp_aggregate *aggregate)
8575 {
8576 if (aggregate->community)
8577 community_free(&aggregate->community);
8578
8579 hash_clean_and_free(&aggregate->community_hash,
8580 bgp_aggr_community_remove);
8581
8582 if (aggregate->ecommunity)
8583 ecommunity_free(&aggregate->ecommunity);
8584
8585 hash_clean_and_free(&aggregate->ecommunity_hash,
8586 bgp_aggr_ecommunity_remove);
8587
8588 if (aggregate->lcommunity)
8589 lcommunity_free(&aggregate->lcommunity);
8590
8591 hash_clean_and_free(&aggregate->lcommunity_hash,
8592 bgp_aggr_lcommunity_remove);
8593
8594 if (aggregate->aspath)
8595 aspath_free(aggregate->aspath);
8596
8597 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8598
8599 bgp_aggregate_free(aggregate);
8600 }
8601
8602 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8603 "[no] aggregate-address X:X::X:X/M$prefix [{"
8604 "as-set$as_set_s"
8605 "|summary-only$summary_only"
8606 "|route-map RMAP_NAME$rmap_name"
8607 "|origin <egp|igp|incomplete>$origin_s"
8608 "|matching-MED-only$match_med"
8609 "|suppress-map RMAP_NAME$suppress_map"
8610 "}]",
8611 NO_STR
8612 "Configure BGP aggregate entries\n"
8613 "Aggregate prefix\n"
8614 "Generate AS set path information\n"
8615 "Filter more specific routes from updates\n"
8616 "Apply route map to aggregate network\n"
8617 "Route map name\n"
8618 "BGP origin code\n"
8619 "Remote EGP\n"
8620 "Local IGP\n"
8621 "Unknown heritage\n"
8622 "Only aggregate routes with matching MED\n"
8623 "Suppress the selected more specific routes\n"
8624 "Route map with the route selectors\n")
8625 {
8626 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8627 int as_set = AGGREGATE_AS_UNSET;
8628
8629 if (origin_s) {
8630 if (strcmp(origin_s, "egp") == 0)
8631 origin = BGP_ORIGIN_EGP;
8632 else if (strcmp(origin_s, "igp") == 0)
8633 origin = BGP_ORIGIN_IGP;
8634 else if (strcmp(origin_s, "incomplete") == 0)
8635 origin = BGP_ORIGIN_INCOMPLETE;
8636 }
8637
8638 if (as_set_s)
8639 as_set = AGGREGATE_AS_SET;
8640
8641 /* Handle configuration removal, otherwise installation. */
8642 if (no)
8643 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8644 SAFI_UNICAST);
8645
8646 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8647 rmap_name, summary_only != NULL, as_set,
8648 origin, match_med != NULL, suppress_map);
8649 }
8650
8651 /* Redistribute route treatment. */
8652 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8653 const union g_addr *nexthop, ifindex_t ifindex,
8654 enum nexthop_types_t nhtype, uint8_t distance,
8655 enum blackhole_type bhtype, uint32_t metric,
8656 uint8_t type, unsigned short instance,
8657 route_tag_t tag)
8658 {
8659 struct bgp_path_info *new;
8660 struct bgp_path_info *bpi;
8661 struct bgp_path_info rmap_path;
8662 struct bgp_dest *bn;
8663 struct attr attr;
8664 struct attr *new_attr;
8665 afi_t afi;
8666 route_map_result_t ret;
8667 struct bgp_redist *red;
8668
8669 /* Make default attribute. */
8670 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8671 /*
8672 * This must not be NULL to satisfy Coverity SA
8673 */
8674 assert(attr.aspath);
8675
8676 switch (nhtype) {
8677 case NEXTHOP_TYPE_IFINDEX:
8678 switch (p->family) {
8679 case AF_INET:
8680 attr.nexthop.s_addr = INADDR_ANY;
8681 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8682 break;
8683 case AF_INET6:
8684 memset(&attr.mp_nexthop_global, 0,
8685 sizeof(attr.mp_nexthop_global));
8686 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8687 break;
8688 }
8689 break;
8690 case NEXTHOP_TYPE_IPV4:
8691 case NEXTHOP_TYPE_IPV4_IFINDEX:
8692 attr.nexthop = nexthop->ipv4;
8693 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8694 break;
8695 case NEXTHOP_TYPE_IPV6:
8696 case NEXTHOP_TYPE_IPV6_IFINDEX:
8697 attr.mp_nexthop_global = nexthop->ipv6;
8698 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8699 break;
8700 case NEXTHOP_TYPE_BLACKHOLE:
8701 switch (p->family) {
8702 case AF_INET:
8703 attr.nexthop.s_addr = INADDR_ANY;
8704 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8705 break;
8706 case AF_INET6:
8707 memset(&attr.mp_nexthop_global, 0,
8708 sizeof(attr.mp_nexthop_global));
8709 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8710 break;
8711 }
8712 attr.bh_type = bhtype;
8713 break;
8714 }
8715 attr.nh_type = nhtype;
8716 attr.nh_ifindex = ifindex;
8717
8718 attr.med = metric;
8719 attr.distance = distance;
8720 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8721 attr.tag = tag;
8722
8723 if (metric)
8724 bgp_attr_set_aigp_metric(&attr, metric);
8725
8726 afi = family2afi(p->family);
8727
8728 red = bgp_redist_lookup(bgp, afi, type, instance);
8729 if (red) {
8730 struct attr attr_new;
8731
8732 /* Copy attribute for modification. */
8733 attr_new = attr;
8734
8735 if (red->redist_metric_flag) {
8736 attr_new.med = red->redist_metric;
8737 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8738 }
8739
8740 /* Apply route-map. */
8741 if (red->rmap.name) {
8742 memset(&rmap_path, 0, sizeof(rmap_path));
8743 rmap_path.peer = bgp->peer_self;
8744 rmap_path.attr = &attr_new;
8745
8746 SET_FLAG(bgp->peer_self->rmap_type,
8747 PEER_RMAP_TYPE_REDISTRIBUTE);
8748
8749 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8750
8751 bgp->peer_self->rmap_type = 0;
8752
8753 if (ret == RMAP_DENYMATCH) {
8754 /* Free uninterned attribute. */
8755 bgp_attr_flush(&attr_new);
8756
8757 /* Unintern original. */
8758 aspath_unintern(&attr.aspath);
8759 bgp_redistribute_delete(bgp, p, type, instance);
8760 return;
8761 }
8762 }
8763
8764 if (bgp_in_graceful_shutdown(bgp))
8765 bgp_attr_add_gshut_community(&attr_new);
8766
8767 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8768 SAFI_UNICAST, p, NULL);
8769
8770 new_attr = bgp_attr_intern(&attr_new);
8771
8772 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8773 if (bpi->peer == bgp->peer_self
8774 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8775 break;
8776
8777 if (bpi) {
8778 /* Ensure the (source route) type is updated. */
8779 bpi->type = type;
8780 if (attrhash_cmp(bpi->attr, new_attr)
8781 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8782 bgp_attr_unintern(&new_attr);
8783 aspath_unintern(&attr.aspath);
8784 bgp_dest_unlock_node(bn);
8785 return;
8786 } else {
8787 /* The attribute is changed. */
8788 bgp_path_info_set_flag(bn, bpi,
8789 BGP_PATH_ATTR_CHANGED);
8790
8791 /* Rewrite BGP route information. */
8792 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8793 bgp_path_info_restore(bn, bpi);
8794 else
8795 bgp_aggregate_decrement(
8796 bgp, p, bpi, afi, SAFI_UNICAST);
8797 bgp_attr_unintern(&bpi->attr);
8798 bpi->attr = new_attr;
8799 bpi->uptime = monotime(NULL);
8800
8801 /* Process change. */
8802 bgp_aggregate_increment(bgp, p, bpi, afi,
8803 SAFI_UNICAST);
8804 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8805 bgp_dest_unlock_node(bn);
8806 aspath_unintern(&attr.aspath);
8807
8808 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8809 || (bgp->inst_type
8810 == BGP_INSTANCE_TYPE_DEFAULT)) {
8811
8812 vpn_leak_from_vrf_update(
8813 bgp_get_default(), bgp, bpi);
8814 }
8815 return;
8816 }
8817 }
8818
8819 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8820 bgp->peer_self, new_attr, bn);
8821 SET_FLAG(new->flags, BGP_PATH_VALID);
8822
8823 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8824 bgp_path_info_add(bn, new);
8825 bgp_dest_unlock_node(bn);
8826 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8827 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8828
8829 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8830 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8831
8832 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8833 }
8834 }
8835
8836 /* Unintern original. */
8837 aspath_unintern(&attr.aspath);
8838 }
8839
8840 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8841 unsigned short instance)
8842 {
8843 afi_t afi;
8844 struct bgp_dest *dest;
8845 struct bgp_path_info *pi;
8846 struct bgp_redist *red;
8847
8848 afi = family2afi(p->family);
8849
8850 red = bgp_redist_lookup(bgp, afi, type, instance);
8851 if (red) {
8852 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8853 SAFI_UNICAST, p, NULL);
8854
8855 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8856 if (pi->peer == bgp->peer_self && pi->type == type)
8857 break;
8858
8859 if (pi) {
8860 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8861 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8862
8863 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8864 bgp, pi);
8865 }
8866 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8867 bgp_path_info_delete(dest, pi);
8868 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8869 }
8870 bgp_dest_unlock_node(dest);
8871 }
8872 }
8873
8874 /* Withdraw specified route type's route. */
8875 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8876 unsigned short instance)
8877 {
8878 struct bgp_dest *dest;
8879 struct bgp_path_info *pi;
8880 struct bgp_table *table;
8881
8882 table = bgp->rib[afi][SAFI_UNICAST];
8883
8884 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8885 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8886 if (pi->peer == bgp->peer_self && pi->type == type
8887 && pi->instance == instance)
8888 break;
8889
8890 if (pi) {
8891 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8892 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8893
8894 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8895 bgp, pi);
8896 }
8897 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8898 pi, afi, SAFI_UNICAST);
8899 bgp_path_info_delete(dest, pi);
8900 if (!CHECK_FLAG(bgp->flags,
8901 BGP_FLAG_DELETE_IN_PROGRESS))
8902 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8903 else
8904 bgp_path_info_reap(dest, pi);
8905 }
8906 }
8907 }
8908
8909 /* Static function to display route. */
8910 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8911 struct vty *vty, json_object *json, bool wide)
8912 {
8913 int len = 0;
8914 char buf[INET6_ADDRSTRLEN];
8915
8916 if (p->family == AF_INET) {
8917 if (!json) {
8918 len = vty_out(vty, "%pFX", p);
8919 } else {
8920 json_object_string_add(json, "prefix",
8921 inet_ntop(p->family,
8922 &p->u.prefix, buf,
8923 sizeof(buf)));
8924 json_object_int_add(json, "prefixLen", p->prefixlen);
8925 json_object_string_addf(json, "network", "%pFX", p);
8926 json_object_int_add(json, "version", dest->version);
8927 }
8928 } else if (p->family == AF_ETHERNET) {
8929 len = vty_out(vty, "%pFX", p);
8930 } else if (p->family == AF_EVPN) {
8931 if (!json)
8932 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8933 else
8934 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8935 } else if (p->family == AF_FLOWSPEC) {
8936 route_vty_out_flowspec(vty, p, NULL,
8937 json ?
8938 NLRI_STRING_FORMAT_JSON_SIMPLE :
8939 NLRI_STRING_FORMAT_MIN, json);
8940 } else {
8941 if (!json)
8942 len = vty_out(vty, "%pFX", p);
8943 else {
8944 json_object_string_add(json, "prefix",
8945 inet_ntop(p->family,
8946 &p->u.prefix, buf,
8947 sizeof(buf)));
8948 json_object_int_add(json, "prefixLen", p->prefixlen);
8949 json_object_string_addf(json, "network", "%pFX", p);
8950 json_object_int_add(json, "version", dest->version);
8951 }
8952 }
8953
8954 if (!json) {
8955 len = wide ? (45 - len) : (17 - len);
8956 if (len < 1)
8957 vty_out(vty, "\n%*s", 20, " ");
8958 else
8959 vty_out(vty, "%*s", len, " ");
8960 }
8961 }
8962
8963 enum bgp_display_type {
8964 normal_list,
8965 };
8966
8967 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8968 {
8969 switch (reason) {
8970 case bgp_path_selection_none:
8971 return "Nothing to Select";
8972 case bgp_path_selection_first:
8973 return "First path received";
8974 case bgp_path_selection_evpn_sticky_mac:
8975 return "EVPN Sticky Mac";
8976 case bgp_path_selection_evpn_seq:
8977 return "EVPN sequence number";
8978 case bgp_path_selection_evpn_lower_ip:
8979 return "EVPN lower IP";
8980 case bgp_path_selection_evpn_local_path:
8981 return "EVPN local ES path";
8982 case bgp_path_selection_evpn_non_proxy:
8983 return "EVPN non proxy";
8984 case bgp_path_selection_weight:
8985 return "Weight";
8986 case bgp_path_selection_local_pref:
8987 return "Local Pref";
8988 case bgp_path_selection_accept_own:
8989 return "Accept Own";
8990 case bgp_path_selection_local_route:
8991 return "Local Route";
8992 case bgp_path_selection_aigp:
8993 return "AIGP";
8994 case bgp_path_selection_confed_as_path:
8995 return "Confederation based AS Path";
8996 case bgp_path_selection_as_path:
8997 return "AS Path";
8998 case bgp_path_selection_origin:
8999 return "Origin";
9000 case bgp_path_selection_med:
9001 return "MED";
9002 case bgp_path_selection_peer:
9003 return "Peer Type";
9004 case bgp_path_selection_confed:
9005 return "Confed Peer Type";
9006 case bgp_path_selection_igp_metric:
9007 return "IGP Metric";
9008 case bgp_path_selection_older:
9009 return "Older Path";
9010 case bgp_path_selection_router_id:
9011 return "Router ID";
9012 case bgp_path_selection_cluster_length:
9013 return "Cluster length";
9014 case bgp_path_selection_stale:
9015 return "Path Staleness";
9016 case bgp_path_selection_local_configured:
9017 return "Locally configured route";
9018 case bgp_path_selection_neighbor_ip:
9019 return "Neighbor IP";
9020 case bgp_path_selection_default:
9021 return "Nothing left to compare";
9022 }
9023 return "Invalid (internal error)";
9024 }
9025
9026 /* Print the short form route status for a bgp_path_info */
9027 static void route_vty_short_status_out(struct vty *vty,
9028 struct bgp_path_info *path,
9029 const struct prefix *p,
9030 json_object *json_path)
9031 {
9032 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9033
9034 if (json_path) {
9035
9036 /* Route status display. */
9037 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9038 json_object_boolean_true_add(json_path, "removed");
9039
9040 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9041 json_object_boolean_true_add(json_path, "stale");
9042
9043 if (path->extra && bgp_path_suppressed(path))
9044 json_object_boolean_true_add(json_path, "suppressed");
9045
9046 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9047 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9048 json_object_boolean_true_add(json_path, "valid");
9049
9050 /* Selected */
9051 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9052 json_object_boolean_true_add(json_path, "history");
9053
9054 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9055 json_object_boolean_true_add(json_path, "damped");
9056
9057 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9058 json_object_boolean_true_add(json_path, "bestpath");
9059 json_object_string_add(json_path, "selectionReason",
9060 bgp_path_selection_reason2str(
9061 path->net->reason));
9062 }
9063
9064 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9065 json_object_boolean_true_add(json_path, "multipath");
9066
9067 /* Internal route. */
9068 if ((path->peer->as)
9069 && (path->peer->as == path->peer->local_as))
9070 json_object_string_add(json_path, "pathFrom",
9071 "internal");
9072 else
9073 json_object_string_add(json_path, "pathFrom",
9074 "external");
9075
9076 return;
9077 }
9078
9079 /* RPKI validation state */
9080 rpki_state =
9081 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9082
9083 if (rpki_state == RPKI_VALID)
9084 vty_out(vty, "V");
9085 else if (rpki_state == RPKI_INVALID)
9086 vty_out(vty, "I");
9087 else if (rpki_state == RPKI_NOTFOUND)
9088 vty_out(vty, "N");
9089 else
9090 vty_out(vty, " ");
9091
9092 /* Route status display. */
9093 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9094 vty_out(vty, "R");
9095 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9096 vty_out(vty, "S");
9097 else if (bgp_path_suppressed(path))
9098 vty_out(vty, "s");
9099 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9100 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9101 vty_out(vty, "*");
9102 else
9103 vty_out(vty, " ");
9104
9105 /* Selected */
9106 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9107 vty_out(vty, "h");
9108 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9109 vty_out(vty, "d");
9110 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9111 vty_out(vty, ">");
9112 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9113 vty_out(vty, "=");
9114 else
9115 vty_out(vty, " ");
9116
9117 /* Internal route. */
9118 if (path->peer && (path->peer->as)
9119 && (path->peer->as == path->peer->local_as))
9120 vty_out(vty, "i");
9121 else
9122 vty_out(vty, " ");
9123 }
9124
9125 static char *bgp_nexthop_hostname(struct peer *peer,
9126 struct bgp_nexthop_cache *bnc)
9127 {
9128 if (peer->hostname
9129 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9130 return peer->hostname;
9131 return NULL;
9132 }
9133
9134 /* called from terminal list command */
9135 void route_vty_out(struct vty *vty, const struct prefix *p,
9136 struct bgp_path_info *path, int display, safi_t safi,
9137 json_object *json_paths, bool wide)
9138 {
9139 int len;
9140 struct attr *attr = path->attr;
9141 json_object *json_path = NULL;
9142 json_object *json_nexthops = NULL;
9143 json_object *json_nexthop_global = NULL;
9144 json_object *json_nexthop_ll = NULL;
9145 json_object *json_ext_community = NULL;
9146 char vrf_id_str[VRF_NAMSIZ] = {0};
9147 bool nexthop_self =
9148 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9149 bool nexthop_othervrf = false;
9150 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9151 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9152 char *nexthop_hostname =
9153 bgp_nexthop_hostname(path->peer, path->nexthop);
9154 char esi_buf[ESI_STR_LEN];
9155
9156 if (json_paths)
9157 json_path = json_object_new_object();
9158
9159 /* short status lead text */
9160 route_vty_short_status_out(vty, path, p, json_path);
9161
9162 if (!json_paths) {
9163 /* print prefix and mask */
9164 if (!display)
9165 route_vty_out_route(path->net, p, vty, json_path, wide);
9166 else
9167 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9168 } else {
9169 route_vty_out_route(path->net, p, vty, json_path, wide);
9170 }
9171
9172 /*
9173 * If vrf id of nexthop is different from that of prefix,
9174 * set up printable string to append
9175 */
9176 if (path->extra && path->extra->bgp_orig) {
9177 const char *self = "";
9178
9179 if (nexthop_self)
9180 self = "<";
9181
9182 nexthop_othervrf = true;
9183 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9184
9185 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9186 snprintf(vrf_id_str, sizeof(vrf_id_str),
9187 "@%s%s", VRFID_NONE_STR, self);
9188 else
9189 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9190 path->extra->bgp_orig->vrf_id, self);
9191
9192 if (path->extra->bgp_orig->inst_type
9193 != BGP_INSTANCE_TYPE_DEFAULT)
9194
9195 nexthop_vrfname = path->extra->bgp_orig->name;
9196 } else {
9197 const char *self = "";
9198
9199 if (nexthop_self)
9200 self = "<";
9201
9202 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9203 }
9204
9205 /*
9206 * For ENCAP and EVPN routes, nexthop address family is not
9207 * neccessarily the same as the prefix address family.
9208 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9209 * EVPN routes are also exchanged with a MP nexthop. Currently,
9210 * this
9211 * is only IPv4, the value will be present in either
9212 * attr->nexthop or
9213 * attr->mp_nexthop_global_in
9214 */
9215 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9216 char nexthop[128];
9217 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9218
9219 switch (af) {
9220 case AF_INET:
9221 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9222 &attr->mp_nexthop_global_in);
9223 break;
9224 case AF_INET6:
9225 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9226 &attr->mp_nexthop_global);
9227 break;
9228 default:
9229 snprintf(nexthop, sizeof(nexthop), "?");
9230 break;
9231 }
9232
9233 if (json_paths) {
9234 json_nexthop_global = json_object_new_object();
9235
9236 json_object_string_add(json_nexthop_global, "ip",
9237 nexthop);
9238
9239 if (path->peer->hostname)
9240 json_object_string_add(json_nexthop_global,
9241 "hostname",
9242 path->peer->hostname);
9243
9244 json_object_string_add(json_nexthop_global, "afi",
9245 (af == AF_INET) ? "ipv4"
9246 : "ipv6");
9247 json_object_boolean_true_add(json_nexthop_global,
9248 "used");
9249 } else {
9250 if (nexthop_hostname)
9251 len = vty_out(vty, "%s(%s)%s", nexthop,
9252 nexthop_hostname, vrf_id_str);
9253 else
9254 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9255
9256 len = wide ? (41 - len) : (16 - len);
9257 if (len < 1)
9258 vty_out(vty, "\n%*s", 36, " ");
9259 else
9260 vty_out(vty, "%*s", len, " ");
9261 }
9262 } else if (safi == SAFI_EVPN) {
9263 if (json_paths) {
9264 json_nexthop_global = json_object_new_object();
9265
9266 json_object_string_addf(json_nexthop_global, "ip",
9267 "%pI4",
9268 &attr->mp_nexthop_global_in);
9269
9270 if (path->peer->hostname)
9271 json_object_string_add(json_nexthop_global,
9272 "hostname",
9273 path->peer->hostname);
9274
9275 json_object_string_add(json_nexthop_global, "afi",
9276 "ipv4");
9277 json_object_boolean_true_add(json_nexthop_global,
9278 "used");
9279 } else {
9280 if (nexthop_hostname)
9281 len = vty_out(vty, "%pI4(%s)%s",
9282 &attr->mp_nexthop_global_in,
9283 nexthop_hostname, vrf_id_str);
9284 else
9285 len = vty_out(vty, "%pI4%s",
9286 &attr->mp_nexthop_global_in,
9287 vrf_id_str);
9288
9289 len = wide ? (41 - len) : (16 - len);
9290 if (len < 1)
9291 vty_out(vty, "\n%*s", 36, " ");
9292 else
9293 vty_out(vty, "%*s", len, " ");
9294 }
9295 } else if (safi == SAFI_FLOWSPEC) {
9296 if (attr->nexthop.s_addr != INADDR_ANY) {
9297 if (json_paths) {
9298 json_nexthop_global = json_object_new_object();
9299
9300 json_object_string_add(json_nexthop_global,
9301 "afi", "ipv4");
9302 json_object_string_addf(json_nexthop_global,
9303 "ip", "%pI4",
9304 &attr->nexthop);
9305
9306 if (path->peer->hostname)
9307 json_object_string_add(
9308 json_nexthop_global, "hostname",
9309 path->peer->hostname);
9310
9311 json_object_boolean_true_add(
9312 json_nexthop_global,
9313 "used");
9314 } else {
9315 if (nexthop_hostname)
9316 len = vty_out(vty, "%pI4(%s)%s",
9317 &attr->nexthop,
9318 nexthop_hostname,
9319 vrf_id_str);
9320 else
9321 len = vty_out(vty, "%pI4%s",
9322 &attr->nexthop,
9323 vrf_id_str);
9324
9325 len = wide ? (41 - len) : (16 - len);
9326 if (len < 1)
9327 vty_out(vty, "\n%*s", 36, " ");
9328 else
9329 vty_out(vty, "%*s", len, " ");
9330 }
9331 }
9332 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9333 if (json_paths) {
9334 json_nexthop_global = json_object_new_object();
9335
9336 json_object_string_addf(json_nexthop_global, "ip",
9337 "%pI4", &attr->nexthop);
9338
9339 if (path->peer->hostname)
9340 json_object_string_add(json_nexthop_global,
9341 "hostname",
9342 path->peer->hostname);
9343
9344 json_object_string_add(json_nexthop_global, "afi",
9345 "ipv4");
9346 json_object_boolean_true_add(json_nexthop_global,
9347 "used");
9348 } else {
9349 if (nexthop_hostname)
9350 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9351 nexthop_hostname, vrf_id_str);
9352 else
9353 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9354 vrf_id_str);
9355
9356 len = wide ? (41 - len) : (16 - len);
9357 if (len < 1)
9358 vty_out(vty, "\n%*s", 36, " ");
9359 else
9360 vty_out(vty, "%*s", len, " ");
9361 }
9362 }
9363
9364 /* IPv6 Next Hop */
9365 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9366 if (json_paths) {
9367 json_nexthop_global = json_object_new_object();
9368 json_object_string_addf(json_nexthop_global, "ip",
9369 "%pI6",
9370 &attr->mp_nexthop_global);
9371
9372 if (path->peer->hostname)
9373 json_object_string_add(json_nexthop_global,
9374 "hostname",
9375 path->peer->hostname);
9376
9377 json_object_string_add(json_nexthop_global, "afi",
9378 "ipv6");
9379 json_object_string_add(json_nexthop_global, "scope",
9380 "global");
9381
9382 /* We display both LL & GL if both have been
9383 * received */
9384 if ((attr->mp_nexthop_len
9385 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9386 || (path->peer->conf_if)) {
9387 json_nexthop_ll = json_object_new_object();
9388 json_object_string_addf(
9389 json_nexthop_ll, "ip", "%pI6",
9390 &attr->mp_nexthop_local);
9391
9392 if (path->peer->hostname)
9393 json_object_string_add(
9394 json_nexthop_ll, "hostname",
9395 path->peer->hostname);
9396
9397 json_object_string_add(json_nexthop_ll, "afi",
9398 "ipv6");
9399 json_object_string_add(json_nexthop_ll, "scope",
9400 "link-local");
9401
9402 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9403 &attr->mp_nexthop_local)
9404 != 0)
9405 && !attr->mp_nexthop_prefer_global)
9406 json_object_boolean_true_add(
9407 json_nexthop_ll, "used");
9408 else
9409 json_object_boolean_true_add(
9410 json_nexthop_global, "used");
9411 } else
9412 json_object_boolean_true_add(
9413 json_nexthop_global, "used");
9414 } else {
9415 /* Display LL if LL/Global both in table unless
9416 * prefer-global is set */
9417 if (((attr->mp_nexthop_len
9418 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9419 && !attr->mp_nexthop_prefer_global)
9420 || (path->peer->conf_if)) {
9421 if (path->peer->conf_if) {
9422 len = vty_out(vty, "%s",
9423 path->peer->conf_if);
9424 /* len of IPv6 addr + max len of def
9425 * ifname */
9426 len = wide ? (41 - len) : (16 - len);
9427
9428 if (len < 1)
9429 vty_out(vty, "\n%*s", 36, " ");
9430 else
9431 vty_out(vty, "%*s", len, " ");
9432 } else {
9433 if (nexthop_hostname)
9434 len = vty_out(
9435 vty, "%pI6(%s)%s",
9436 &attr->mp_nexthop_local,
9437 nexthop_hostname,
9438 vrf_id_str);
9439 else
9440 len = vty_out(
9441 vty, "%pI6%s",
9442 &attr->mp_nexthop_local,
9443 vrf_id_str);
9444
9445 len = wide ? (41 - len) : (16 - len);
9446
9447 if (len < 1)
9448 vty_out(vty, "\n%*s", 36, " ");
9449 else
9450 vty_out(vty, "%*s", len, " ");
9451 }
9452 } else {
9453 if (nexthop_hostname)
9454 len = vty_out(vty, "%pI6(%s)%s",
9455 &attr->mp_nexthop_global,
9456 nexthop_hostname,
9457 vrf_id_str);
9458 else
9459 len = vty_out(vty, "%pI6%s",
9460 &attr->mp_nexthop_global,
9461 vrf_id_str);
9462
9463 len = wide ? (41 - len) : (16 - len);
9464
9465 if (len < 1)
9466 vty_out(vty, "\n%*s", 36, " ");
9467 else
9468 vty_out(vty, "%*s", len, " ");
9469 }
9470 }
9471 }
9472
9473 /* MED/Metric */
9474 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9475 if (json_paths)
9476 json_object_int_add(json_path, "metric", attr->med);
9477 else if (wide)
9478 vty_out(vty, "%7u", attr->med);
9479 else
9480 vty_out(vty, "%10u", attr->med);
9481 else if (!json_paths) {
9482 if (wide)
9483 vty_out(vty, "%*s", 7, " ");
9484 else
9485 vty_out(vty, "%*s", 10, " ");
9486 }
9487
9488 /* Local Pref */
9489 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9490 if (json_paths)
9491 json_object_int_add(json_path, "locPrf",
9492 attr->local_pref);
9493 else
9494 vty_out(vty, "%7u", attr->local_pref);
9495 else if (!json_paths)
9496 vty_out(vty, " ");
9497
9498 if (json_paths)
9499 json_object_int_add(json_path, "weight", attr->weight);
9500 else
9501 vty_out(vty, "%7u ", attr->weight);
9502
9503 if (json_paths)
9504 json_object_string_addf(json_path, "peerId", "%pSU",
9505 &path->peer->su);
9506
9507 /* Print aspath */
9508 if (attr->aspath) {
9509 if (json_paths)
9510 json_object_string_add(json_path, "path",
9511 attr->aspath->str);
9512 else
9513 aspath_print_vty(vty, attr->aspath);
9514 }
9515
9516 /* Print origin */
9517 if (json_paths)
9518 json_object_string_add(json_path, "origin",
9519 bgp_origin_long_str[attr->origin]);
9520 else
9521 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9522
9523 if (json_paths) {
9524 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9525 json_object_string_add(json_path, "esi",
9526 esi_to_str(&attr->esi,
9527 esi_buf, sizeof(esi_buf)));
9528 }
9529 if (safi == SAFI_EVPN &&
9530 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9531 json_ext_community = json_object_new_object();
9532 json_object_string_add(
9533 json_ext_community, "string",
9534 bgp_attr_get_ecommunity(attr)->str);
9535 json_object_object_add(json_path,
9536 "extendedCommunity",
9537 json_ext_community);
9538 }
9539
9540 if (nexthop_self)
9541 json_object_boolean_true_add(json_path,
9542 "announceNexthopSelf");
9543 if (nexthop_othervrf) {
9544 json_object_string_add(json_path, "nhVrfName",
9545 nexthop_vrfname);
9546
9547 json_object_int_add(json_path, "nhVrfId",
9548 ((nexthop_vrfid == VRF_UNKNOWN)
9549 ? -1
9550 : (int)nexthop_vrfid));
9551 }
9552 }
9553
9554 if (json_paths) {
9555 if (json_nexthop_global || json_nexthop_ll) {
9556 json_nexthops = json_object_new_array();
9557
9558 if (json_nexthop_global)
9559 json_object_array_add(json_nexthops,
9560 json_nexthop_global);
9561
9562 if (json_nexthop_ll)
9563 json_object_array_add(json_nexthops,
9564 json_nexthop_ll);
9565
9566 json_object_object_add(json_path, "nexthops",
9567 json_nexthops);
9568 }
9569
9570 json_object_array_add(json_paths, json_path);
9571 } else {
9572 vty_out(vty, "\n");
9573
9574 if (safi == SAFI_EVPN) {
9575 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9576 /* XXX - add these params to the json out */
9577 vty_out(vty, "%*s", 20, " ");
9578 vty_out(vty, "ESI:%s",
9579 esi_to_str(&attr->esi, esi_buf,
9580 sizeof(esi_buf)));
9581
9582 vty_out(vty, "\n");
9583 }
9584 if (attr->flag &
9585 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9586 vty_out(vty, "%*s", 20, " ");
9587 vty_out(vty, "%s\n",
9588 bgp_attr_get_ecommunity(attr)->str);
9589 }
9590 }
9591
9592 #ifdef ENABLE_BGP_VNC
9593 /* prints an additional line, indented, with VNC info, if
9594 * present */
9595 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9596 rfapi_vty_out_vncinfo(vty, p, path, safi);
9597 #endif
9598 }
9599 }
9600
9601 /* called from terminal list command */
9602 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9603 const struct prefix *p, struct attr *attr, safi_t safi,
9604 bool use_json, json_object *json_ar, bool wide)
9605 {
9606 json_object *json_status = NULL;
9607 json_object *json_net = NULL;
9608 int len;
9609 char buff[BUFSIZ];
9610
9611 /* Route status display. */
9612 if (use_json) {
9613 json_status = json_object_new_object();
9614 json_net = json_object_new_object();
9615 } else {
9616 vty_out(vty, " *");
9617 vty_out(vty, ">");
9618 vty_out(vty, " ");
9619 }
9620
9621 /* print prefix and mask */
9622 if (use_json) {
9623 if (safi == SAFI_EVPN)
9624 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9625 else if (p->family == AF_INET || p->family == AF_INET6) {
9626 json_object_string_add(
9627 json_net, "addrPrefix",
9628 inet_ntop(p->family, &p->u.prefix, buff,
9629 BUFSIZ));
9630 json_object_int_add(json_net, "prefixLen",
9631 p->prefixlen);
9632 json_object_string_addf(json_net, "network", "%pFX", p);
9633 }
9634 } else
9635 route_vty_out_route(dest, p, vty, NULL, wide);
9636
9637 /* Print attribute */
9638 if (attr) {
9639 if (use_json) {
9640 if (p->family == AF_INET &&
9641 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9642 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9643 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9644 json_object_string_addf(
9645 json_net, "nextHop", "%pI4",
9646 &attr->mp_nexthop_global_in);
9647 else
9648 json_object_string_addf(
9649 json_net, "nextHop", "%pI4",
9650 &attr->nexthop);
9651 } else if (p->family == AF_INET6 ||
9652 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9653 json_object_string_addf(
9654 json_net, "nextHopGlobal", "%pI6",
9655 &attr->mp_nexthop_global);
9656 } else if (p->family == AF_EVPN &&
9657 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9658 json_object_string_addf(
9659 json_net, "nextHop", "%pI4",
9660 &attr->mp_nexthop_global_in);
9661 }
9662
9663 if (attr->flag
9664 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9665 json_object_int_add(json_net, "metric",
9666 attr->med);
9667
9668 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9669 json_object_int_add(json_net, "locPrf",
9670 attr->local_pref);
9671
9672 json_object_int_add(json_net, "weight", attr->weight);
9673
9674 /* Print aspath */
9675 if (attr->aspath)
9676 json_object_string_add(json_net, "path",
9677 attr->aspath->str);
9678
9679 /* Print origin */
9680 #if CONFDATE > 20231208
9681 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9682 #endif
9683 json_object_string_add(json_net, "bgpOriginCode",
9684 bgp_origin_str[attr->origin]);
9685 json_object_string_add(
9686 json_net, "origin",
9687 bgp_origin_long_str[attr->origin]);
9688 } else {
9689 if (p->family == AF_INET &&
9690 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9691 safi == SAFI_EVPN ||
9692 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9693 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9694 || safi == SAFI_EVPN)
9695 vty_out(vty, "%-16pI4",
9696 &attr->mp_nexthop_global_in);
9697 else if (wide)
9698 vty_out(vty, "%-41pI4", &attr->nexthop);
9699 else
9700 vty_out(vty, "%-16pI4", &attr->nexthop);
9701 } else if (p->family == AF_INET6 ||
9702 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9703 len = vty_out(vty, "%pI6",
9704 &attr->mp_nexthop_global);
9705 len = wide ? (41 - len) : (16 - len);
9706 if (len < 1)
9707 vty_out(vty, "\n%*s", 36, " ");
9708 else
9709 vty_out(vty, "%*s", len, " ");
9710 }
9711 if (attr->flag
9712 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9713 if (wide)
9714 vty_out(vty, "%7u", attr->med);
9715 else
9716 vty_out(vty, "%10u", attr->med);
9717 else if (wide)
9718 vty_out(vty, " ");
9719 else
9720 vty_out(vty, " ");
9721
9722 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9723 vty_out(vty, "%7u", attr->local_pref);
9724 else
9725 vty_out(vty, " ");
9726
9727 vty_out(vty, "%7u ", attr->weight);
9728
9729 /* Print aspath */
9730 if (attr->aspath)
9731 aspath_print_vty(vty, attr->aspath);
9732
9733 /* Print origin */
9734 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9735 }
9736 }
9737 if (use_json) {
9738 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9739
9740 #if CONFDATE > 20231208
9741 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9742 #endif
9743 json_object_boolean_true_add(json_status, "*");
9744 json_object_boolean_true_add(json_status, ">");
9745 json_object_boolean_true_add(json_net, "valid");
9746 json_object_boolean_true_add(json_net, "best");
9747
9748 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9749 json_object_boolean_true_add(json_status, "=");
9750 json_object_boolean_true_add(json_net, "multipath");
9751 }
9752 json_object_object_add(json_net, "appliedStatusSymbols",
9753 json_status);
9754 json_object_object_addf(json_ar, json_net, "%pFX", p);
9755 } else
9756 vty_out(vty, "\n");
9757 }
9758
9759 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9760 struct bgp_path_info *path, int display, safi_t safi,
9761 json_object *json)
9762 {
9763 json_object *json_out = NULL;
9764 struct attr *attr;
9765 mpls_label_t label = MPLS_INVALID_LABEL;
9766
9767 if (!path->extra)
9768 return;
9769
9770 if (json)
9771 json_out = json_object_new_object();
9772
9773 /* short status lead text */
9774 route_vty_short_status_out(vty, path, p, json_out);
9775
9776 /* print prefix and mask */
9777 if (json == NULL) {
9778 if (!display)
9779 route_vty_out_route(path->net, p, vty, NULL, false);
9780 else
9781 vty_out(vty, "%*s", 17, " ");
9782 }
9783
9784 /* Print attribute */
9785 attr = path->attr;
9786 if (((p->family == AF_INET) &&
9787 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9788 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9789 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9790 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9791 || safi == SAFI_EVPN) {
9792 if (json)
9793 json_object_string_addf(
9794 json_out, "mpNexthopGlobalIn", "%pI4",
9795 &attr->mp_nexthop_global_in);
9796 else
9797 vty_out(vty, "%-16pI4",
9798 &attr->mp_nexthop_global_in);
9799 } else {
9800 if (json)
9801 json_object_string_addf(json_out, "nexthop",
9802 "%pI4", &attr->nexthop);
9803 else
9804 vty_out(vty, "%-16pI4", &attr->nexthop);
9805 }
9806 } else if (((p->family == AF_INET6) &&
9807 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9808 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9809 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9810 char buf_a[512];
9811
9812 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9813 if (json)
9814 json_object_string_addf(
9815 json_out, "mpNexthopGlobalIn", "%pI6",
9816 &attr->mp_nexthop_global);
9817 else
9818 vty_out(vty, "%s",
9819 inet_ntop(AF_INET6,
9820 &attr->mp_nexthop_global,
9821 buf_a, sizeof(buf_a)));
9822 } else if (attr->mp_nexthop_len
9823 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9824 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9825 &attr->mp_nexthop_global,
9826 &attr->mp_nexthop_local);
9827 if (json)
9828 json_object_string_add(json_out,
9829 "mpNexthopGlobalLocal",
9830 buf_a);
9831 else
9832 vty_out(vty, "%s", buf_a);
9833 }
9834 }
9835
9836 label = decode_label(&path->extra->label[0]);
9837
9838 if (bgp_is_valid_label(&label)) {
9839 if (json) {
9840 json_object_int_add(json_out, "notag", label);
9841 json_object_array_add(json, json_out);
9842 } else {
9843 vty_out(vty, "notag/%d", label);
9844 vty_out(vty, "\n");
9845 }
9846 } else if (!json)
9847 vty_out(vty, "\n");
9848 }
9849
9850 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9851 struct bgp_path_info *path, int display,
9852 json_object *json_paths)
9853 {
9854 struct attr *attr;
9855 json_object *json_path = NULL;
9856 json_object *json_nexthop = NULL;
9857 json_object *json_overlay = NULL;
9858
9859 if (!path->extra)
9860 return;
9861
9862 if (json_paths) {
9863 json_path = json_object_new_object();
9864 json_overlay = json_object_new_object();
9865 json_nexthop = json_object_new_object();
9866 }
9867
9868 /* short status lead text */
9869 route_vty_short_status_out(vty, path, p, json_path);
9870
9871 /* print prefix and mask */
9872 if (!display)
9873 route_vty_out_route(path->net, p, vty, json_path, false);
9874 else
9875 vty_out(vty, "%*s", 17, " ");
9876
9877 /* Print attribute */
9878 attr = path->attr;
9879 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9880
9881 switch (af) {
9882 case AF_INET:
9883 if (!json_path) {
9884 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9885 } else {
9886 json_object_string_addf(json_nexthop, "ip", "%pI4",
9887 &attr->mp_nexthop_global_in);
9888
9889 json_object_string_add(json_nexthop, "afi", "ipv4");
9890
9891 json_object_object_add(json_path, "nexthop",
9892 json_nexthop);
9893 }
9894 break;
9895 case AF_INET6:
9896 if (!json_path) {
9897 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9898 &attr->mp_nexthop_local);
9899 } else {
9900 json_object_string_addf(json_nexthop, "ipv6Global",
9901 "%pI6",
9902 &attr->mp_nexthop_global);
9903
9904 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9905 "%pI6",
9906 &attr->mp_nexthop_local);
9907
9908 json_object_string_add(json_nexthop, "afi", "ipv6");
9909
9910 json_object_object_add(json_path, "nexthop",
9911 json_nexthop);
9912 }
9913 break;
9914 default:
9915 if (!json_path) {
9916 vty_out(vty, "?");
9917 } else {
9918 json_object_string_add(json_nexthop, "error",
9919 "Unsupported address-family");
9920 }
9921 }
9922
9923 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9924
9925 if (!json_path)
9926 vty_out(vty, "/%pIA", &eo->gw_ip);
9927 else
9928 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9929
9930 if (bgp_attr_get_ecommunity(attr)) {
9931 char *mac = NULL;
9932 struct ecommunity_val *routermac = ecommunity_lookup(
9933 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9934 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9935
9936 if (routermac)
9937 mac = ecom_mac2str((char *)routermac->val);
9938 if (mac) {
9939 if (!json_path) {
9940 vty_out(vty, "/%s", mac);
9941 } else {
9942 json_object_string_add(json_overlay, "rmac",
9943 mac);
9944 }
9945 XFREE(MTYPE_TMP, mac);
9946 }
9947 }
9948
9949 if (!json_path) {
9950 vty_out(vty, "\n");
9951 } else {
9952 json_object_object_add(json_path, "overlay", json_overlay);
9953
9954 json_object_array_add(json_paths, json_path);
9955 }
9956 }
9957
9958 /* dampening route */
9959 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9960 struct bgp_path_info *path, int display,
9961 afi_t afi, safi_t safi, bool use_json,
9962 json_object *json_paths)
9963 {
9964 struct attr *attr = path->attr;
9965 int len;
9966 char timebuf[BGP_UPTIME_LEN];
9967 json_object *json_path = NULL;
9968
9969 if (use_json)
9970 json_path = json_object_new_object();
9971
9972 /* short status lead text */
9973 route_vty_short_status_out(vty, path, p, json_path);
9974
9975 /* print prefix and mask */
9976 if (!use_json) {
9977 if (!display)
9978 route_vty_out_route(path->net, p, vty, NULL, false);
9979 else
9980 vty_out(vty, "%*s", 17, " ");
9981
9982 len = vty_out(vty, "%s", path->peer->host);
9983 len = 17 - len;
9984
9985 if (len < 1)
9986 vty_out(vty, "\n%*s", 34, " ");
9987 else
9988 vty_out(vty, "%*s", len, " ");
9989
9990 vty_out(vty, "%s ",
9991 bgp_damp_reuse_time_vty(vty, path, timebuf,
9992 BGP_UPTIME_LEN, afi, safi,
9993 use_json, NULL));
9994
9995 if (attr->aspath)
9996 aspath_print_vty(vty, attr->aspath);
9997
9998 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9999
10000 vty_out(vty, "\n");
10001 } else {
10002 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
10003 safi, use_json, json_path);
10004
10005 if (attr->aspath)
10006 json_object_string_add(json_path, "asPath",
10007 attr->aspath->str);
10008
10009 json_object_string_add(json_path, "origin",
10010 bgp_origin_str[attr->origin]);
10011 json_object_string_add(json_path, "peerHost", path->peer->host);
10012
10013 json_object_array_add(json_paths, json_path);
10014 }
10015 }
10016
10017 /* flap route */
10018 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
10019 struct bgp_path_info *path, int display,
10020 afi_t afi, safi_t safi, bool use_json,
10021 json_object *json_paths)
10022 {
10023 struct attr *attr = path->attr;
10024 struct bgp_damp_info *bdi;
10025 char timebuf[BGP_UPTIME_LEN];
10026 int len;
10027 json_object *json_path = NULL;
10028
10029 if (!path->extra)
10030 return;
10031
10032 if (use_json)
10033 json_path = json_object_new_object();
10034
10035 bdi = path->extra->damp_info;
10036
10037 /* short status lead text */
10038 route_vty_short_status_out(vty, path, p, json_path);
10039
10040 if (!use_json) {
10041 if (!display)
10042 route_vty_out_route(path->net, p, vty, NULL, false);
10043 else
10044 vty_out(vty, "%*s", 17, " ");
10045
10046 len = vty_out(vty, "%s", path->peer->host);
10047 len = 16 - len;
10048 if (len < 1)
10049 vty_out(vty, "\n%*s", 33, " ");
10050 else
10051 vty_out(vty, "%*s", len, " ");
10052
10053 len = vty_out(vty, "%d", bdi->flap);
10054 len = 5 - len;
10055 if (len < 1)
10056 vty_out(vty, " ");
10057 else
10058 vty_out(vty, "%*s", len, " ");
10059
10060 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10061 BGP_UPTIME_LEN, 0, NULL));
10062
10063 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10064 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10065 vty_out(vty, "%s ",
10066 bgp_damp_reuse_time_vty(vty, path, timebuf,
10067 BGP_UPTIME_LEN, afi,
10068 safi, use_json, NULL));
10069 else
10070 vty_out(vty, "%*s ", 8, " ");
10071
10072 if (attr->aspath)
10073 aspath_print_vty(vty, attr->aspath);
10074
10075 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10076
10077 vty_out(vty, "\n");
10078 } else {
10079 json_object_string_add(json_path, "peerHost", path->peer->host);
10080 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10081
10082 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10083 json_path);
10084
10085 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10086 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10087 bgp_damp_reuse_time_vty(vty, path, timebuf,
10088 BGP_UPTIME_LEN, afi, safi,
10089 use_json, json_path);
10090
10091 if (attr->aspath)
10092 json_object_string_add(json_path, "asPath",
10093 attr->aspath->str);
10094
10095 json_object_string_add(json_path, "origin",
10096 bgp_origin_str[attr->origin]);
10097
10098 json_object_array_add(json_paths, json_path);
10099 }
10100 }
10101
10102 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10103 int *first, const char *header,
10104 json_object *json_adv_to)
10105 {
10106 json_object *json_peer = NULL;
10107
10108 if (json_adv_to) {
10109 /* 'advertised-to' is a dictionary of peers we have advertised
10110 * this
10111 * prefix too. The key is the peer's IP or swpX, the value is
10112 * the
10113 * hostname if we know it and "" if not.
10114 */
10115 json_peer = json_object_new_object();
10116
10117 if (peer->hostname)
10118 json_object_string_add(json_peer, "hostname",
10119 peer->hostname);
10120
10121 if (peer->conf_if)
10122 json_object_object_add(json_adv_to, peer->conf_if,
10123 json_peer);
10124 else
10125 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10126 &peer->su);
10127 } else {
10128 if (*first) {
10129 vty_out(vty, "%s", header);
10130 *first = 0;
10131 }
10132
10133 if (peer->hostname
10134 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10135 if (peer->conf_if)
10136 vty_out(vty, " %s(%s)", peer->hostname,
10137 peer->conf_if);
10138 else
10139 vty_out(vty, " %s(%pSU)", peer->hostname,
10140 &peer->su);
10141 } else {
10142 if (peer->conf_if)
10143 vty_out(vty, " %s", peer->conf_if);
10144 else
10145 vty_out(vty, " %pSU", &peer->su);
10146 }
10147 }
10148 }
10149
10150 static void route_vty_out_tx_ids(struct vty *vty,
10151 struct bgp_addpath_info_data *d)
10152 {
10153 int i;
10154
10155 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10156 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10157 d->addpath_tx_id[i],
10158 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10159 }
10160 }
10161
10162 static void route_vty_out_detail_es_info(struct vty *vty,
10163 struct bgp_path_info *pi,
10164 struct attr *attr,
10165 json_object *json_path)
10166 {
10167 char esi_buf[ESI_STR_LEN];
10168 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10169 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10170 ATTR_ES_PEER_ROUTER);
10171 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10172 ATTR_ES_PEER_ACTIVE);
10173 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10174 ATTR_ES_PEER_PROXY);
10175 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10176 if (json_path) {
10177 json_object *json_es_info = NULL;
10178
10179 json_object_string_add(
10180 json_path, "esi",
10181 esi_buf);
10182 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10183 json_es_info = json_object_new_object();
10184 if (es_local)
10185 json_object_boolean_true_add(
10186 json_es_info, "localEs");
10187 if (peer_active)
10188 json_object_boolean_true_add(
10189 json_es_info, "peerActive");
10190 if (peer_proxy)
10191 json_object_boolean_true_add(
10192 json_es_info, "peerProxy");
10193 if (peer_router)
10194 json_object_boolean_true_add(
10195 json_es_info, "peerRouter");
10196 if (attr->mm_sync_seqnum)
10197 json_object_int_add(
10198 json_es_info, "peerSeq",
10199 attr->mm_sync_seqnum);
10200 json_object_object_add(
10201 json_path, "es_info",
10202 json_es_info);
10203 }
10204 } else {
10205 if (bgp_evpn_attr_is_sync(attr))
10206 vty_out(vty,
10207 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10208 esi_buf,
10209 es_local ? "local-es":"",
10210 peer_proxy ? "proxy " : "",
10211 peer_active ? "active ":"",
10212 peer_router ? "router ":"",
10213 attr->mm_sync_seqnum);
10214 else
10215 vty_out(vty, " ESI %s %s\n",
10216 esi_buf,
10217 es_local ? "local-es":"");
10218 }
10219 }
10220
10221 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10222 const struct prefix *p, struct bgp_path_info *path,
10223 afi_t afi, safi_t safi,
10224 enum rpki_states rpki_curr_state,
10225 json_object *json_paths)
10226 {
10227 char buf[INET6_ADDRSTRLEN];
10228 char tag_buf[30];
10229 struct attr *attr = path->attr;
10230 time_t tbuf;
10231 json_object *json_bestpath = NULL;
10232 json_object *json_cluster_list = NULL;
10233 json_object *json_cluster_list_list = NULL;
10234 json_object *json_ext_community = NULL;
10235 json_object *json_last_update = NULL;
10236 json_object *json_pmsi = NULL;
10237 json_object *json_nexthop_global = NULL;
10238 json_object *json_nexthop_ll = NULL;
10239 json_object *json_nexthops = NULL;
10240 json_object *json_path = NULL;
10241 json_object *json_peer = NULL;
10242 json_object *json_string = NULL;
10243 json_object *json_adv_to = NULL;
10244 int first = 0;
10245 struct listnode *node, *nnode;
10246 struct peer *peer;
10247 bool addpath_capable;
10248 int has_adj;
10249 unsigned int first_as;
10250 bool nexthop_self =
10251 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10252 int i;
10253 char *nexthop_hostname =
10254 bgp_nexthop_hostname(path->peer, path->nexthop);
10255 uint32_t ttl = 0;
10256 uint32_t bos = 0;
10257 uint32_t exp = 0;
10258 mpls_label_t label = MPLS_INVALID_LABEL;
10259 tag_buf[0] = '\0';
10260 struct bgp_path_info *bpi_ultimate =
10261 bgp_get_imported_bpi_ultimate(path);
10262
10263 if (json_paths) {
10264 json_path = json_object_new_object();
10265 json_peer = json_object_new_object();
10266 json_nexthop_global = json_object_new_object();
10267 }
10268
10269 if (safi == SAFI_EVPN) {
10270 if (!json_paths)
10271 vty_out(vty, " Route %pFX", p);
10272 }
10273
10274 if (path->extra) {
10275 if (path->extra && path->extra->num_labels) {
10276 bgp_evpn_label2str(path->extra->label,
10277 path->extra->num_labels, tag_buf,
10278 sizeof(tag_buf));
10279 }
10280 if (safi == SAFI_EVPN) {
10281 if (!json_paths) {
10282 if (tag_buf[0] != '\0')
10283 vty_out(vty, " VNI %s", tag_buf);
10284 } else {
10285 if (tag_buf[0])
10286 json_object_string_add(json_path, "vni",
10287 tag_buf);
10288 }
10289 }
10290 }
10291
10292 if (safi == SAFI_EVPN
10293 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10294 char gwip_buf[INET6_ADDRSTRLEN];
10295
10296 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10297 sizeof(gwip_buf));
10298
10299 if (json_paths)
10300 json_object_string_add(json_path, "gatewayIP",
10301 gwip_buf);
10302 else
10303 vty_out(vty, " Gateway IP %s", gwip_buf);
10304 }
10305
10306 if (safi == SAFI_EVPN && !json_path)
10307 vty_out(vty, "\n");
10308
10309
10310 if (path->extra && path->extra->parent && !json_paths) {
10311 struct bgp_path_info *parent_ri;
10312 struct bgp_dest *dest, *pdest;
10313
10314 parent_ri = (struct bgp_path_info *)path->extra->parent;
10315 dest = parent_ri->net;
10316 if (dest && dest->pdest) {
10317 pdest = dest->pdest;
10318 if (is_pi_family_evpn(parent_ri)) {
10319 vty_out(vty, " Imported from ");
10320 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10321 (struct prefix_rd *)bgp_dest_get_prefix(
10322 pdest));
10323 vty_out(vty, ":%pFX, VNI %s",
10324 (struct prefix_evpn *)
10325 bgp_dest_get_prefix(dest),
10326 tag_buf);
10327 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10328 vty_out(vty, ", L3NHG %s",
10329 CHECK_FLAG(
10330 attr->es_flags,
10331 ATTR_ES_L3_NHG_ACTIVE)
10332 ? "active"
10333 : "inactive");
10334 vty_out(vty, "\n");
10335
10336 } else {
10337 vty_out(vty, " Imported from ");
10338 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10339 (struct prefix_rd *)bgp_dest_get_prefix(
10340 pdest));
10341 vty_out(vty, ":%pFX\n",
10342 (struct prefix_evpn *)
10343 bgp_dest_get_prefix(dest));
10344 }
10345 }
10346 }
10347
10348 /* Line1 display AS-path, Aggregator */
10349 if (attr->aspath) {
10350 if (json_paths) {
10351 if (!attr->aspath->json)
10352 aspath_str_update(attr->aspath, true);
10353 json_object_lock(attr->aspath->json);
10354 json_object_object_add(json_path, "aspath",
10355 attr->aspath->json);
10356 } else {
10357 if (attr->aspath->segments)
10358 vty_out(vty, " %s", attr->aspath->str);
10359 else
10360 vty_out(vty, " Local");
10361 }
10362 }
10363
10364 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10365 if (json_paths)
10366 json_object_boolean_true_add(json_path, "removed");
10367 else
10368 vty_out(vty, ", (removed)");
10369 }
10370
10371 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10372 if (json_paths)
10373 json_object_boolean_true_add(json_path, "stale");
10374 else
10375 vty_out(vty, ", (stale)");
10376 }
10377
10378 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10379 if (json_paths) {
10380 json_object_int_add(json_path, "aggregatorAs",
10381 attr->aggregator_as);
10382 json_object_string_addf(json_path, "aggregatorId",
10383 "%pI4", &attr->aggregator_addr);
10384 } else {
10385 vty_out(vty, ", (aggregated by %u %pI4)",
10386 attr->aggregator_as, &attr->aggregator_addr);
10387 }
10388 }
10389
10390 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10391 PEER_FLAG_REFLECTOR_CLIENT)) {
10392 if (json_paths)
10393 json_object_boolean_true_add(json_path,
10394 "rxedFromRrClient");
10395 else
10396 vty_out(vty, ", (Received from a RR-client)");
10397 }
10398
10399 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10400 PEER_FLAG_RSERVER_CLIENT)) {
10401 if (json_paths)
10402 json_object_boolean_true_add(json_path,
10403 "rxedFromRsClient");
10404 else
10405 vty_out(vty, ", (Received from a RS-client)");
10406 }
10407
10408 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10409 if (json_paths)
10410 json_object_boolean_true_add(json_path,
10411 "dampeningHistoryEntry");
10412 else
10413 vty_out(vty, ", (history entry)");
10414 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10415 if (json_paths)
10416 json_object_boolean_true_add(json_path,
10417 "dampeningSuppressed");
10418 else
10419 vty_out(vty, ", (suppressed due to dampening)");
10420 }
10421
10422 if (!json_paths)
10423 vty_out(vty, "\n");
10424
10425 /* Line2 display Next-hop, Neighbor, Router-id */
10426 /* Display the nexthop */
10427
10428 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10429 p->family == AF_EVPN) &&
10430 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10431 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10432 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10433 || safi == SAFI_EVPN) {
10434 if (json_paths) {
10435 json_object_string_addf(
10436 json_nexthop_global, "ip", "%pI4",
10437 &attr->mp_nexthop_global_in);
10438
10439 if (path->peer->hostname)
10440 json_object_string_add(
10441 json_nexthop_global, "hostname",
10442 path->peer->hostname);
10443 } else {
10444 if (nexthop_hostname)
10445 vty_out(vty, " %pI4(%s)",
10446 &attr->mp_nexthop_global_in,
10447 nexthop_hostname);
10448 else
10449 vty_out(vty, " %pI4",
10450 &attr->mp_nexthop_global_in);
10451 }
10452 } else {
10453 if (json_paths) {
10454 json_object_string_addf(json_nexthop_global,
10455 "ip", "%pI4",
10456 &attr->nexthop);
10457
10458 if (path->peer->hostname)
10459 json_object_string_add(
10460 json_nexthop_global, "hostname",
10461 path->peer->hostname);
10462 } else {
10463 if (nexthop_hostname)
10464 vty_out(vty, " %pI4(%s)",
10465 &attr->nexthop,
10466 nexthop_hostname);
10467 else
10468 vty_out(vty, " %pI4",
10469 &attr->nexthop);
10470 }
10471 }
10472
10473 if (json_paths)
10474 json_object_string_add(json_nexthop_global, "afi",
10475 "ipv4");
10476 } else {
10477 if (json_paths) {
10478 json_object_string_addf(json_nexthop_global, "ip",
10479 "%pI6",
10480 &attr->mp_nexthop_global);
10481
10482 if (path->peer->hostname)
10483 json_object_string_add(json_nexthop_global,
10484 "hostname",
10485 path->peer->hostname);
10486
10487 json_object_string_add(json_nexthop_global, "afi",
10488 "ipv6");
10489 json_object_string_add(json_nexthop_global, "scope",
10490 "global");
10491 } else {
10492 if (nexthop_hostname)
10493 vty_out(vty, " %pI6(%s)",
10494 &attr->mp_nexthop_global,
10495 nexthop_hostname);
10496 else
10497 vty_out(vty, " %pI6",
10498 &attr->mp_nexthop_global);
10499 }
10500 }
10501
10502 /* Display the IGP cost or 'inaccessible' */
10503 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10504 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10505
10506 if (json_paths) {
10507 json_object_boolean_false_add(json_nexthop_global,
10508 "accessible");
10509 json_object_boolean_add(json_nexthop_global,
10510 "importCheckEnabled", import);
10511 } else {
10512 vty_out(vty, " (inaccessible%s)",
10513 import ? ", import-check enabled" : "");
10514 }
10515 } else {
10516 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10517 if (json_paths)
10518 json_object_int_add(
10519 json_nexthop_global, "metric",
10520 bpi_ultimate->extra->igpmetric);
10521 else
10522 vty_out(vty, " (metric %u)",
10523 bpi_ultimate->extra->igpmetric);
10524 }
10525
10526 /* IGP cost is 0, display this only for json */
10527 else {
10528 if (json_paths)
10529 json_object_int_add(json_nexthop_global,
10530 "metric", 0);
10531 }
10532
10533 if (json_paths)
10534 json_object_boolean_true_add(json_nexthop_global,
10535 "accessible");
10536 }
10537
10538 /* Display peer "from" output */
10539 /* This path was originated locally */
10540 if (path->peer == bgp->peer_self) {
10541
10542 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10543 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10544 if (json_paths)
10545 json_object_string_add(json_peer, "peerId",
10546 "0.0.0.0");
10547 else
10548 vty_out(vty, " from 0.0.0.0 ");
10549 } else {
10550 if (json_paths)
10551 json_object_string_add(json_peer, "peerId",
10552 "::");
10553 else
10554 vty_out(vty, " from :: ");
10555 }
10556
10557 if (json_paths)
10558 json_object_string_addf(json_peer, "routerId", "%pI4",
10559 &bgp->router_id);
10560 else
10561 vty_out(vty, "(%pI4)", &bgp->router_id);
10562 }
10563
10564 /* We RXed this path from one of our peers */
10565 else {
10566
10567 if (json_paths) {
10568 json_object_string_addf(json_peer, "peerId", "%pSU",
10569 &path->peer->su);
10570 json_object_string_addf(json_peer, "routerId", "%pI4",
10571 &path->peer->remote_id);
10572
10573 if (path->peer->hostname)
10574 json_object_string_add(json_peer, "hostname",
10575 path->peer->hostname);
10576
10577 if (path->peer->domainname)
10578 json_object_string_add(json_peer, "domainname",
10579 path->peer->domainname);
10580
10581 if (path->peer->conf_if)
10582 json_object_string_add(json_peer, "interface",
10583 path->peer->conf_if);
10584 } else {
10585 if (path->peer->conf_if) {
10586 if (path->peer->hostname
10587 && CHECK_FLAG(path->peer->bgp->flags,
10588 BGP_FLAG_SHOW_HOSTNAME))
10589 vty_out(vty, " from %s(%s)",
10590 path->peer->hostname,
10591 path->peer->conf_if);
10592 else
10593 vty_out(vty, " from %s",
10594 path->peer->conf_if);
10595 } else {
10596 if (path->peer->hostname
10597 && CHECK_FLAG(path->peer->bgp->flags,
10598 BGP_FLAG_SHOW_HOSTNAME))
10599 vty_out(vty, " from %s(%s)",
10600 path->peer->hostname,
10601 path->peer->host);
10602 else
10603 vty_out(vty, " from %pSU",
10604 &path->peer->su);
10605 }
10606
10607 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10608 vty_out(vty, " (%pI4)", &attr->originator_id);
10609 else
10610 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10611 }
10612 }
10613
10614 /*
10615 * Note when vrfid of nexthop is different from that of prefix
10616 */
10617 if (path->extra && path->extra->bgp_orig) {
10618 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10619
10620 if (json_paths) {
10621 const char *vn;
10622
10623 if (path->extra->bgp_orig->inst_type
10624 == BGP_INSTANCE_TYPE_DEFAULT)
10625 vn = VRF_DEFAULT_NAME;
10626 else
10627 vn = path->extra->bgp_orig->name;
10628
10629 json_object_string_add(json_path, "nhVrfName", vn);
10630
10631 if (nexthop_vrfid == VRF_UNKNOWN) {
10632 json_object_int_add(json_path, "nhVrfId", -1);
10633 } else {
10634 json_object_int_add(json_path, "nhVrfId",
10635 (int)nexthop_vrfid);
10636 }
10637 } else {
10638 if (nexthop_vrfid == VRF_UNKNOWN)
10639 vty_out(vty, " vrf ?");
10640 else {
10641 struct vrf *vrf;
10642
10643 vrf = vrf_lookup_by_id(nexthop_vrfid);
10644 vty_out(vty, " vrf %s(%u)",
10645 VRF_LOGNAME(vrf), nexthop_vrfid);
10646 }
10647 }
10648 }
10649
10650 if (nexthop_self) {
10651 if (json_paths) {
10652 json_object_boolean_true_add(json_path,
10653 "announceNexthopSelf");
10654 } else {
10655 vty_out(vty, " announce-nh-self");
10656 }
10657 }
10658
10659 if (!json_paths)
10660 vty_out(vty, "\n");
10661
10662 /* display the link-local nexthop */
10663 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10664 if (json_paths) {
10665 json_nexthop_ll = json_object_new_object();
10666 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10667 &attr->mp_nexthop_local);
10668
10669 if (path->peer->hostname)
10670 json_object_string_add(json_nexthop_ll,
10671 "hostname",
10672 path->peer->hostname);
10673
10674 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10675 json_object_string_add(json_nexthop_ll, "scope",
10676 "link-local");
10677
10678 json_object_boolean_true_add(json_nexthop_ll,
10679 "accessible");
10680
10681 if (!attr->mp_nexthop_prefer_global)
10682 json_object_boolean_true_add(json_nexthop_ll,
10683 "used");
10684 else
10685 json_object_boolean_true_add(
10686 json_nexthop_global, "used");
10687 } else {
10688 vty_out(vty, " (%s) %s\n",
10689 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10690 buf, INET6_ADDRSTRLEN),
10691 attr->mp_nexthop_prefer_global
10692 ? "(prefer-global)"
10693 : "(used)");
10694 }
10695 }
10696 /* If we do not have a link-local nexthop then we must flag the
10697 global as "used" */
10698 else {
10699 if (json_paths)
10700 json_object_boolean_true_add(json_nexthop_global,
10701 "used");
10702 }
10703
10704 if (safi == SAFI_EVPN &&
10705 bgp_evpn_is_esi_valid(&attr->esi)) {
10706 route_vty_out_detail_es_info(vty, path, attr, json_path);
10707 }
10708
10709 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10710 * Int/Ext/Local, Atomic, best */
10711 if (json_paths)
10712 json_object_string_add(json_path, "origin",
10713 bgp_origin_long_str[attr->origin]);
10714 else
10715 vty_out(vty, " Origin %s",
10716 bgp_origin_long_str[attr->origin]);
10717
10718 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10719 if (json_paths)
10720 json_object_int_add(json_path, "metric", attr->med);
10721 else
10722 vty_out(vty, ", metric %u", attr->med);
10723 }
10724
10725 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10726 if (json_paths)
10727 json_object_int_add(json_path, "locPrf",
10728 attr->local_pref);
10729 else
10730 vty_out(vty, ", localpref %u", attr->local_pref);
10731 }
10732
10733 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10734 if (json_paths)
10735 json_object_int_add(json_path, "aigpMetric",
10736 bgp_attr_get_aigp_metric(attr));
10737 else
10738 vty_out(vty, ", aigp-metric %" PRIu64,
10739 bgp_attr_get_aigp_metric(attr));
10740 }
10741
10742 if (attr->weight != 0) {
10743 if (json_paths)
10744 json_object_int_add(json_path, "weight", attr->weight);
10745 else
10746 vty_out(vty, ", weight %u", attr->weight);
10747 }
10748
10749 if (attr->tag != 0) {
10750 if (json_paths)
10751 json_object_int_add(json_path, "tag", attr->tag);
10752 else
10753 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10754 }
10755
10756 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10757 if (json_paths)
10758 json_object_boolean_false_add(json_path, "valid");
10759 else
10760 vty_out(vty, ", invalid");
10761 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10762 if (json_paths)
10763 json_object_boolean_true_add(json_path, "valid");
10764 else
10765 vty_out(vty, ", valid");
10766 }
10767
10768 if (json_paths)
10769 json_object_int_add(json_path, "version", bn->version);
10770
10771 if (path->peer != bgp->peer_self) {
10772 if (path->peer->as == path->peer->local_as) {
10773 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10774 if (json_paths)
10775 json_object_string_add(
10776 json_peer, "type",
10777 "confed-internal");
10778 else
10779 vty_out(vty, ", confed-internal");
10780 } else {
10781 if (json_paths)
10782 json_object_string_add(
10783 json_peer, "type", "internal");
10784 else
10785 vty_out(vty, ", internal");
10786 }
10787 } else {
10788 if (bgp_confederation_peers_check(bgp,
10789 path->peer->as)) {
10790 if (json_paths)
10791 json_object_string_add(
10792 json_peer, "type",
10793 "confed-external");
10794 else
10795 vty_out(vty, ", confed-external");
10796 } else {
10797 if (json_paths)
10798 json_object_string_add(
10799 json_peer, "type", "external");
10800 else
10801 vty_out(vty, ", external");
10802 }
10803 }
10804 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10805 if (json_paths) {
10806 json_object_boolean_true_add(json_path, "aggregated");
10807 json_object_boolean_true_add(json_path, "local");
10808 } else {
10809 vty_out(vty, ", aggregated, local");
10810 }
10811 } else if (path->type != ZEBRA_ROUTE_BGP) {
10812 if (json_paths)
10813 json_object_boolean_true_add(json_path, "sourced");
10814 else
10815 vty_out(vty, ", sourced");
10816 } else {
10817 if (json_paths) {
10818 json_object_boolean_true_add(json_path, "sourced");
10819 json_object_boolean_true_add(json_path, "local");
10820 } else {
10821 vty_out(vty, ", sourced, local");
10822 }
10823 }
10824
10825 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10826 if (json_paths)
10827 json_object_boolean_true_add(json_path,
10828 "atomicAggregate");
10829 else
10830 vty_out(vty, ", atomic-aggregate");
10831 }
10832
10833 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10834 if (json_paths)
10835 json_object_int_add(json_path, "otc", attr->otc);
10836 else
10837 vty_out(vty, ", otc %u", attr->otc);
10838 }
10839
10840 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10841 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10842 && bgp_path_info_mpath_count(path))) {
10843 if (json_paths)
10844 json_object_boolean_true_add(json_path, "multipath");
10845 else
10846 vty_out(vty, ", multipath");
10847 }
10848
10849 // Mark the bestpath(s)
10850 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10851 first_as = aspath_get_first_as(attr->aspath);
10852
10853 if (json_paths) {
10854 if (!json_bestpath)
10855 json_bestpath = json_object_new_object();
10856 json_object_int_add(json_bestpath, "bestpathFromAs",
10857 first_as);
10858 } else {
10859 if (first_as)
10860 vty_out(vty, ", bestpath-from-AS %u", first_as);
10861 else
10862 vty_out(vty, ", bestpath-from-AS Local");
10863 }
10864 }
10865
10866 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10867 if (json_paths) {
10868 if (!json_bestpath)
10869 json_bestpath = json_object_new_object();
10870 json_object_boolean_true_add(json_bestpath, "overall");
10871 json_object_string_add(
10872 json_bestpath, "selectionReason",
10873 bgp_path_selection_reason2str(bn->reason));
10874 } else {
10875 vty_out(vty, ", best");
10876 vty_out(vty, " (%s)",
10877 bgp_path_selection_reason2str(bn->reason));
10878 }
10879 }
10880
10881 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10882 if (json_paths)
10883 json_object_string_add(
10884 json_path, "rpkiValidationState",
10885 bgp_rpki_validation2str(rpki_curr_state));
10886 else
10887 vty_out(vty, ", rpki validation-state: %s",
10888 bgp_rpki_validation2str(rpki_curr_state));
10889 }
10890
10891 if (json_bestpath)
10892 json_object_object_add(json_path, "bestpath", json_bestpath);
10893
10894 if (!json_paths)
10895 vty_out(vty, "\n");
10896
10897 /* Line 4 display Community */
10898 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10899 if (json_paths) {
10900 if (!bgp_attr_get_community(attr)->json)
10901 community_str(bgp_attr_get_community(attr),
10902 true, true);
10903 json_object_lock(bgp_attr_get_community(attr)->json);
10904 json_object_object_add(
10905 json_path, "community",
10906 bgp_attr_get_community(attr)->json);
10907 } else {
10908 vty_out(vty, " Community: %s\n",
10909 bgp_attr_get_community(attr)->str);
10910 }
10911 }
10912
10913 /* Line 5 display Extended-community */
10914 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10915 if (json_paths) {
10916 json_ext_community = json_object_new_object();
10917 json_object_string_add(
10918 json_ext_community, "string",
10919 bgp_attr_get_ecommunity(attr)->str);
10920 json_object_object_add(json_path, "extendedCommunity",
10921 json_ext_community);
10922 } else {
10923 vty_out(vty, " Extended Community: %s\n",
10924 bgp_attr_get_ecommunity(attr)->str);
10925 }
10926 }
10927
10928 /* Line 6 display Large community */
10929 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10930 if (json_paths) {
10931 if (!bgp_attr_get_lcommunity(attr)->json)
10932 lcommunity_str(bgp_attr_get_lcommunity(attr),
10933 true, true);
10934 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10935 json_object_object_add(
10936 json_path, "largeCommunity",
10937 bgp_attr_get_lcommunity(attr)->json);
10938 } else {
10939 vty_out(vty, " Large Community: %s\n",
10940 bgp_attr_get_lcommunity(attr)->str);
10941 }
10942 }
10943
10944 /* Line 7 display Originator, Cluster-id */
10945 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10946 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10947 char buf[BUFSIZ] = {0};
10948
10949 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10950 if (json_paths)
10951 json_object_string_addf(json_path,
10952 "originatorId", "%pI4",
10953 &attr->originator_id);
10954 else
10955 vty_out(vty, " Originator: %pI4",
10956 &attr->originator_id);
10957 }
10958
10959 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10960 struct cluster_list *cluster =
10961 bgp_attr_get_cluster(attr);
10962 int i;
10963
10964 if (json_paths) {
10965 json_cluster_list = json_object_new_object();
10966 json_cluster_list_list =
10967 json_object_new_array();
10968
10969 for (i = 0; i < cluster->length / 4; i++) {
10970 json_string = json_object_new_string(
10971 inet_ntop(AF_INET,
10972 &cluster->list[i],
10973 buf, sizeof(buf)));
10974 json_object_array_add(
10975 json_cluster_list_list,
10976 json_string);
10977 }
10978
10979 /*
10980 * struct cluster_list does not have
10981 * "str" variable like aspath and community
10982 * do. Add this someday if someone asks
10983 * for it.
10984 * json_object_string_add(json_cluster_list,
10985 * "string", cluster->str);
10986 */
10987 json_object_object_add(json_cluster_list,
10988 "list",
10989 json_cluster_list_list);
10990 json_object_object_add(json_path, "clusterList",
10991 json_cluster_list);
10992 } else {
10993 vty_out(vty, ", Cluster list: ");
10994
10995 for (i = 0; i < cluster->length / 4; i++) {
10996 vty_out(vty, "%pI4 ",
10997 &cluster->list[i]);
10998 }
10999 }
11000 }
11001
11002 if (!json_paths)
11003 vty_out(vty, "\n");
11004 }
11005
11006 if (path->extra && path->extra->damp_info)
11007 bgp_damp_info_vty(vty, path, afi, safi, json_path);
11008
11009 /* Remote Label */
11010 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
11011 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
11012 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
11013 &bos);
11014
11015 if (json_paths)
11016 json_object_int_add(json_path, "remoteLabel", label);
11017 else
11018 vty_out(vty, " Remote label: %d\n", label);
11019 }
11020
11021 /* Remote SID */
11022 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
11023 if (json_paths)
11024 json_object_string_addf(json_path, "remoteSid", "%pI6",
11025 &path->extra->sid[0].sid);
11026 else
11027 vty_out(vty, " Remote SID: %pI6\n",
11028 &path->extra->sid[0].sid);
11029 }
11030
11031 /* Label Index */
11032 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11033 if (json_paths)
11034 json_object_int_add(json_path, "labelIndex",
11035 attr->label_index);
11036 else
11037 vty_out(vty, " Label Index: %d\n",
11038 attr->label_index);
11039 }
11040
11041 /* Line 8 display Addpath IDs */
11042 if (path->addpath_rx_id
11043 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11044 if (json_paths) {
11045 json_object_int_add(json_path, "addpathRxId",
11046 path->addpath_rx_id);
11047
11048 /* Keep backwards compatibility with the old API
11049 * by putting TX All's ID in the old field
11050 */
11051 json_object_int_add(
11052 json_path, "addpathTxId",
11053 path->tx_addpath
11054 .addpath_tx_id[BGP_ADDPATH_ALL]);
11055
11056 /* ... but create a specific field for each
11057 * strategy
11058 */
11059 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11060 json_object_int_add(
11061 json_path,
11062 bgp_addpath_names(i)->id_json_name,
11063 path->tx_addpath.addpath_tx_id[i]);
11064 }
11065 } else {
11066 vty_out(vty, " AddPath ID: RX %u, ",
11067 path->addpath_rx_id);
11068
11069 route_vty_out_tx_ids(vty, &path->tx_addpath);
11070 }
11071 }
11072
11073 /* If we used addpath to TX a non-bestpath we need to display
11074 * "Advertised to" on a path-by-path basis
11075 */
11076 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11077 first = 1;
11078
11079 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11080 addpath_capable =
11081 bgp_addpath_encode_tx(peer, afi, safi);
11082 has_adj = bgp_adj_out_lookup(
11083 peer, path->net,
11084 bgp_addpath_id_for_peer(peer, afi, safi,
11085 &path->tx_addpath));
11086
11087 if ((addpath_capable && has_adj)
11088 || (!addpath_capable && has_adj
11089 && CHECK_FLAG(path->flags,
11090 BGP_PATH_SELECTED))) {
11091 if (json_path && !json_adv_to)
11092 json_adv_to = json_object_new_object();
11093
11094 route_vty_out_advertised_to(
11095 vty, peer, &first,
11096 " Advertised to:", json_adv_to);
11097 }
11098 }
11099
11100 if (json_path) {
11101 if (json_adv_to) {
11102 json_object_object_add(
11103 json_path, "advertisedTo", json_adv_to);
11104 }
11105 } else {
11106 if (!first) {
11107 vty_out(vty, "\n");
11108 }
11109 }
11110 }
11111
11112 /* Line 9 display Uptime */
11113 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11114 if (json_paths) {
11115 json_last_update = json_object_new_object();
11116 json_object_int_add(json_last_update, "epoch", tbuf);
11117 json_object_string_add(json_last_update, "string",
11118 ctime(&tbuf));
11119 json_object_object_add(json_path, "lastUpdate",
11120 json_last_update);
11121 } else
11122 vty_out(vty, " Last update: %s", ctime(&tbuf));
11123
11124 /* Line 10 display PMSI tunnel attribute, if present */
11125 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11126 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11127 bgp_attr_get_pmsi_tnl_type(attr),
11128 PMSI_TNLTYPE_STR_DEFAULT);
11129
11130 if (json_paths) {
11131 json_pmsi = json_object_new_object();
11132 json_object_string_add(json_pmsi, "tunnelType", str);
11133 json_object_int_add(json_pmsi, "label",
11134 label2vni(&attr->label));
11135 json_object_object_add(json_path, "pmsi", json_pmsi);
11136 } else
11137 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11138 str, label2vni(&attr->label));
11139 }
11140
11141 if (path->peer->t_gr_restart &&
11142 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11143 unsigned long gr_remaining =
11144 event_timer_remain_second(path->peer->t_gr_restart);
11145
11146 if (json_paths) {
11147 json_object_int_add(json_path,
11148 "gracefulRestartSecondsRemaining",
11149 gr_remaining);
11150 } else
11151 vty_out(vty,
11152 " Time until Graceful Restart stale route deleted: %lu\n",
11153 gr_remaining);
11154 }
11155
11156 if (path->peer->t_llgr_stale[afi][safi] &&
11157 bgp_attr_get_community(attr) &&
11158 community_include(bgp_attr_get_community(attr),
11159 COMMUNITY_LLGR_STALE)) {
11160 unsigned long llgr_remaining = event_timer_remain_second(
11161 path->peer->t_llgr_stale[afi][safi]);
11162
11163 if (json_paths) {
11164 json_object_int_add(json_path, "llgrSecondsRemaining",
11165 llgr_remaining);
11166 } else
11167 vty_out(vty,
11168 " Time until Long-lived stale route deleted: %lu\n",
11169 llgr_remaining);
11170 }
11171
11172 /* Output some debug about internal state of the dest flags */
11173 if (json_paths) {
11174 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11175 json_object_boolean_true_add(json_path, "processScheduled");
11176 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11177 json_object_boolean_true_add(json_path, "userCleared");
11178 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11179 json_object_boolean_true_add(json_path, "labelChanged");
11180 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11181 json_object_boolean_true_add(json_path, "registeredForLabel");
11182 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11183 json_object_boolean_true_add(json_path, "selectDefered");
11184 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11185 json_object_boolean_true_add(json_path, "fibInstalled");
11186 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11187 json_object_boolean_true_add(json_path, "fibPending");
11188
11189 if (json_nexthop_global || json_nexthop_ll) {
11190 json_nexthops = json_object_new_array();
11191
11192 if (json_nexthop_global)
11193 json_object_array_add(json_nexthops,
11194 json_nexthop_global);
11195
11196 if (json_nexthop_ll)
11197 json_object_array_add(json_nexthops,
11198 json_nexthop_ll);
11199
11200 json_object_object_add(json_path, "nexthops",
11201 json_nexthops);
11202 }
11203
11204 json_object_object_add(json_path, "peer", json_peer);
11205 json_object_array_add(json_paths, json_path);
11206 }
11207 }
11208
11209 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11210 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11211 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11212
11213 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11214 afi_t afi, safi_t safi, enum bgp_show_type type,
11215 bool use_json);
11216 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11217 const char *comstr, int exact, afi_t afi,
11218 safi_t safi, uint16_t show_flags);
11219
11220 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11221 struct bgp_table *table, enum bgp_show_type type,
11222 void *output_arg, const char *rd, int is_last,
11223 unsigned long *output_cum, unsigned long *total_cum,
11224 unsigned long *json_header_depth, uint16_t show_flags,
11225 enum rpki_states rpki_target_state)
11226 {
11227 struct bgp_path_info *pi;
11228 struct bgp_dest *dest;
11229 bool header = true;
11230 bool json_detail_header = false;
11231 int display;
11232 unsigned long output_count = 0;
11233 unsigned long total_count = 0;
11234 struct prefix *p;
11235 json_object *json_paths = NULL;
11236 int first = 1;
11237 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11238 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11239 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11240 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11241 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11242
11243 if (output_cum && *output_cum != 0)
11244 header = false;
11245
11246 if (use_json && !*json_header_depth) {
11247 if (all)
11248 *json_header_depth = 1;
11249 else {
11250 vty_out(vty, "{\n");
11251 *json_header_depth = 2;
11252 }
11253 vty_out(vty,
11254 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11255 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11256 " \"localAS\": ",
11257 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11258 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11259 ? VRF_DEFAULT_NAME
11260 : bgp->name,
11261 table->version, &bgp->router_id,
11262 bgp->default_local_pref);
11263 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11264 ((bgp->asnotation == ASNOTATION_DOT) &&
11265 (bgp->as < UINT16_MAX)))
11266 vty_out(vty, "%u", bgp->as);
11267 else {
11268 vty_out(vty, "\"");
11269 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11270 vty_out(vty, "\"");
11271 }
11272 vty_out(vty, ",\n \"routes\": { ");
11273 if (rd) {
11274 vty_out(vty, " \"routeDistinguishers\" : {");
11275 ++*json_header_depth;
11276 }
11277 }
11278
11279 if (use_json && rd) {
11280 vty_out(vty, " \"%s\" : { ", rd);
11281 }
11282
11283 /* Check for 'json detail', where we need header output once per dest */
11284 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11285 type != bgp_show_type_damp_neighbor &&
11286 type != bgp_show_type_flap_statistics &&
11287 type != bgp_show_type_flap_neighbor)
11288 json_detail_header = true;
11289
11290 /* Start processing of routes. */
11291 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11292 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11293 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11294 bool json_detail_header_used = false;
11295
11296 pi = bgp_dest_get_bgp_path_info(dest);
11297 if (pi == NULL)
11298 continue;
11299
11300 display = 0;
11301 if (use_json)
11302 json_paths = json_object_new_array();
11303 else
11304 json_paths = NULL;
11305
11306 for (; pi; pi = pi->next) {
11307 struct community *picomm = NULL;
11308
11309 picomm = bgp_attr_get_community(pi->attr);
11310
11311 total_count++;
11312
11313 if (type == bgp_show_type_prefix_version) {
11314 uint32_t version =
11315 strtoul(output_arg, NULL, 10);
11316 if (dest->version < version)
11317 continue;
11318 }
11319
11320 if (type == bgp_show_type_community_alias) {
11321 char *alias = output_arg;
11322 char **communities;
11323 int num;
11324 bool found = false;
11325
11326 if (picomm) {
11327 frrstr_split(picomm->str, " ",
11328 &communities, &num);
11329 for (int i = 0; i < num; i++) {
11330 const char *com2alias =
11331 bgp_community2alias(
11332 communities[i]);
11333 if (!found
11334 && strcmp(alias, com2alias)
11335 == 0)
11336 found = true;
11337 XFREE(MTYPE_TMP,
11338 communities[i]);
11339 }
11340 XFREE(MTYPE_TMP, communities);
11341 }
11342
11343 if (!found &&
11344 bgp_attr_get_lcommunity(pi->attr)) {
11345 frrstr_split(bgp_attr_get_lcommunity(
11346 pi->attr)
11347 ->str,
11348 " ", &communities, &num);
11349 for (int i = 0; i < num; i++) {
11350 const char *com2alias =
11351 bgp_community2alias(
11352 communities[i]);
11353 if (!found
11354 && strcmp(alias, com2alias)
11355 == 0)
11356 found = true;
11357 XFREE(MTYPE_TMP,
11358 communities[i]);
11359 }
11360 XFREE(MTYPE_TMP, communities);
11361 }
11362
11363 if (!found)
11364 continue;
11365 }
11366
11367 if (type == bgp_show_type_rpki) {
11368 if (dest_p->family == AF_INET
11369 || dest_p->family == AF_INET6)
11370 rpki_curr_state = hook_call(
11371 bgp_rpki_prefix_status,
11372 pi->peer, pi->attr, dest_p);
11373 if (rpki_target_state != RPKI_NOT_BEING_USED
11374 && rpki_curr_state != rpki_target_state)
11375 continue;
11376 }
11377
11378 if (type == bgp_show_type_flap_statistics
11379 || type == bgp_show_type_flap_neighbor
11380 || type == bgp_show_type_dampend_paths
11381 || type == bgp_show_type_damp_neighbor) {
11382 if (!(pi->extra && pi->extra->damp_info))
11383 continue;
11384 }
11385 if (type == bgp_show_type_regexp) {
11386 regex_t *regex = output_arg;
11387
11388 if (bgp_regexec(regex, pi->attr->aspath)
11389 == REG_NOMATCH)
11390 continue;
11391 }
11392 if (type == bgp_show_type_prefix_list) {
11393 struct prefix_list *plist = output_arg;
11394
11395 if (prefix_list_apply(plist, dest_p)
11396 != PREFIX_PERMIT)
11397 continue;
11398 }
11399 if (type == bgp_show_type_access_list) {
11400 struct access_list *alist = output_arg;
11401
11402 if (access_list_apply(alist, dest_p) !=
11403 FILTER_PERMIT)
11404 continue;
11405 }
11406 if (type == bgp_show_type_filter_list) {
11407 struct as_list *as_list = output_arg;
11408
11409 if (as_list_apply(as_list, pi->attr->aspath)
11410 != AS_FILTER_PERMIT)
11411 continue;
11412 }
11413 if (type == bgp_show_type_route_map) {
11414 struct route_map *rmap = output_arg;
11415 struct bgp_path_info path;
11416 struct bgp_path_info_extra extra;
11417 struct attr dummy_attr = {};
11418 route_map_result_t ret;
11419
11420 dummy_attr = *pi->attr;
11421
11422 prep_for_rmap_apply(&path, &extra, dest, pi,
11423 pi->peer, &dummy_attr);
11424
11425 ret = route_map_apply(rmap, dest_p, &path);
11426 bgp_attr_flush(&dummy_attr);
11427 if (ret == RMAP_DENYMATCH)
11428 continue;
11429 }
11430 if (type == bgp_show_type_neighbor
11431 || type == bgp_show_type_flap_neighbor
11432 || type == bgp_show_type_damp_neighbor) {
11433 union sockunion *su = output_arg;
11434
11435 if (pi->peer == NULL
11436 || pi->peer->su_remote == NULL
11437 || !sockunion_same(pi->peer->su_remote, su))
11438 continue;
11439 }
11440 if (type == bgp_show_type_cidr_only) {
11441 uint32_t destination;
11442
11443 destination = ntohl(dest_p->u.prefix4.s_addr);
11444 if (IN_CLASSC(destination)
11445 && dest_p->prefixlen == 24)
11446 continue;
11447 if (IN_CLASSB(destination)
11448 && dest_p->prefixlen == 16)
11449 continue;
11450 if (IN_CLASSA(destination)
11451 && dest_p->prefixlen == 8)
11452 continue;
11453 }
11454 if (type == bgp_show_type_prefix_longer) {
11455 p = output_arg;
11456 if (!prefix_match(p, dest_p))
11457 continue;
11458 }
11459 if (type == bgp_show_type_community_all) {
11460 if (!picomm)
11461 continue;
11462 }
11463 if (type == bgp_show_type_community) {
11464 struct community *com = output_arg;
11465
11466 if (!picomm || !community_match(picomm, com))
11467 continue;
11468 }
11469 if (type == bgp_show_type_community_exact) {
11470 struct community *com = output_arg;
11471
11472 if (!picomm || !community_cmp(picomm, com))
11473 continue;
11474 }
11475 if (type == bgp_show_type_community_list) {
11476 struct community_list *list = output_arg;
11477
11478 if (!community_list_match(picomm, list))
11479 continue;
11480 }
11481 if (type == bgp_show_type_community_list_exact) {
11482 struct community_list *list = output_arg;
11483
11484 if (!community_list_exact_match(picomm, list))
11485 continue;
11486 }
11487 if (type == bgp_show_type_lcommunity) {
11488 struct lcommunity *lcom = output_arg;
11489
11490 if (!bgp_attr_get_lcommunity(pi->attr) ||
11491 !lcommunity_match(
11492 bgp_attr_get_lcommunity(pi->attr),
11493 lcom))
11494 continue;
11495 }
11496
11497 if (type == bgp_show_type_lcommunity_exact) {
11498 struct lcommunity *lcom = output_arg;
11499
11500 if (!bgp_attr_get_lcommunity(pi->attr) ||
11501 !lcommunity_cmp(
11502 bgp_attr_get_lcommunity(pi->attr),
11503 lcom))
11504 continue;
11505 }
11506 if (type == bgp_show_type_lcommunity_list) {
11507 struct community_list *list = output_arg;
11508
11509 if (!lcommunity_list_match(
11510 bgp_attr_get_lcommunity(pi->attr),
11511 list))
11512 continue;
11513 }
11514 if (type
11515 == bgp_show_type_lcommunity_list_exact) {
11516 struct community_list *list = output_arg;
11517
11518 if (!lcommunity_list_exact_match(
11519 bgp_attr_get_lcommunity(pi->attr),
11520 list))
11521 continue;
11522 }
11523 if (type == bgp_show_type_lcommunity_all) {
11524 if (!bgp_attr_get_lcommunity(pi->attr))
11525 continue;
11526 }
11527 if (type == bgp_show_type_dampend_paths
11528 || type == bgp_show_type_damp_neighbor) {
11529 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11530 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11531 continue;
11532 }
11533 if (type == bgp_show_type_self_originated) {
11534 if (pi->peer != bgp->peer_self)
11535 continue;
11536 }
11537
11538 if (!use_json && header) {
11539 vty_out(vty,
11540 "BGP table version is %" PRIu64
11541 ", local router ID is %pI4, vrf id ",
11542 table->version, &bgp->router_id);
11543 if (bgp->vrf_id == VRF_UNKNOWN)
11544 vty_out(vty, "%s", VRFID_NONE_STR);
11545 else
11546 vty_out(vty, "%u", bgp->vrf_id);
11547 vty_out(vty, "\n");
11548 vty_out(vty, "Default local pref %u, ",
11549 bgp->default_local_pref);
11550 vty_out(vty, "local AS ");
11551 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11552 &bgp->as);
11553 vty_out(vty, "\n");
11554 if (!detail_routes) {
11555 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11556 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11557 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11558 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11559 }
11560 if (type == bgp_show_type_dampend_paths
11561 || type == bgp_show_type_damp_neighbor)
11562 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11563 else if (type == bgp_show_type_flap_statistics
11564 || type == bgp_show_type_flap_neighbor)
11565 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11566 else if (!detail_routes)
11567 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11568 : BGP_SHOW_HEADER));
11569 header = false;
11570
11571 }
11572 if (rd != NULL && !display && !output_count) {
11573 if (!use_json)
11574 vty_out(vty,
11575 "Route Distinguisher: %s\n",
11576 rd);
11577 }
11578 if (type == bgp_show_type_dampend_paths
11579 || type == bgp_show_type_damp_neighbor)
11580 damp_route_vty_out(vty, dest_p, pi, display,
11581 AFI_IP, safi, use_json,
11582 json_paths);
11583 else if (type == bgp_show_type_flap_statistics
11584 || type == bgp_show_type_flap_neighbor)
11585 flap_route_vty_out(vty, dest_p, pi, display,
11586 AFI_IP, safi, use_json,
11587 json_paths);
11588 else {
11589 if (detail_routes || detail_json) {
11590 const struct prefix_rd *prd = NULL;
11591
11592 if (dest->pdest)
11593 prd = bgp_rd_from_dest(
11594 dest->pdest, safi);
11595
11596 if (!use_json)
11597 route_vty_out_detail_header(
11598 vty, bgp, dest,
11599 bgp_dest_get_prefix(
11600 dest),
11601 prd, table->afi, safi,
11602 NULL, false);
11603
11604 route_vty_out_detail(
11605 vty, bgp, dest, dest_p, pi,
11606 family2afi(dest_p->family),
11607 safi, RPKI_NOT_BEING_USED,
11608 json_paths);
11609 } else {
11610 route_vty_out(vty, dest_p, pi, display,
11611 safi, json_paths, wide);
11612 }
11613 }
11614 display++;
11615 }
11616
11617 if (display) {
11618 output_count++;
11619 if (!use_json)
11620 continue;
11621
11622 /* encode prefix */
11623 if (dest_p->family == AF_FLOWSPEC) {
11624 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11625
11626
11627 bgp_fs_nlri_get_string(
11628 (unsigned char *)
11629 dest_p->u.prefix_flowspec.ptr,
11630 dest_p->u.prefix_flowspec.prefixlen,
11631 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11632 family2afi(dest_p->u
11633 .prefix_flowspec.family));
11634 if (first)
11635 vty_out(vty, "\"%s/%d\": ", retstr,
11636 dest_p->u.prefix_flowspec
11637 .prefixlen);
11638 else
11639 vty_out(vty, ",\"%s/%d\": ", retstr,
11640 dest_p->u.prefix_flowspec
11641 .prefixlen);
11642 } else {
11643 if (first)
11644 vty_out(vty, "\"%pFX\": ", dest_p);
11645 else
11646 vty_out(vty, ",\"%pFX\": ", dest_p);
11647 }
11648
11649 /* This is used for 'json detail' vty keywords.
11650 *
11651 * In plain 'json' the per-prefix header is encoded
11652 * as a standalone dictionary in the first json_paths
11653 * array element:
11654 * "<prefix>": [{header}, {path-1}, {path-N}]
11655 * (which is confusing and borderline broken)
11656 *
11657 * For 'json detail' this changes the value
11658 * of each prefix-key to be a dictionary where each
11659 * header item has its own key, and json_paths is
11660 * tucked under the "paths" key:
11661 * "<prefix>": {
11662 * "<header-key-1>": <header-val-1>,
11663 * "<header-key-N>": <header-val-N>,
11664 * "paths": [{path-1}, {path-N}]
11665 * }
11666 */
11667 if (json_detail_header && json_paths != NULL) {
11668 const struct prefix_rd *prd;
11669
11670 /* Start per-prefix dictionary */
11671 vty_out(vty, "{\n");
11672
11673 prd = bgp_rd_from_dest(dest, safi);
11674
11675 route_vty_out_detail_header(
11676 vty, bgp, dest,
11677 bgp_dest_get_prefix(dest), prd,
11678 table->afi, safi, json_paths, true);
11679
11680 vty_out(vty, "\"paths\": ");
11681 json_detail_header_used = true;
11682 }
11683
11684 /*
11685 * We are using no_pretty here because under
11686 * extremely high settings( say lots and lots of
11687 * routes with lots and lots of ways to reach
11688 * that route via different paths ) this can
11689 * save several minutes of output when FRR
11690 * is run on older cpu's or more underperforming
11691 * routers out there
11692 */
11693 vty_json_no_pretty(vty, json_paths);
11694
11695 /* End per-prefix dictionary */
11696 if (json_detail_header_used)
11697 vty_out(vty, "} ");
11698
11699 json_paths = NULL;
11700 first = 0;
11701 } else
11702 json_object_free(json_paths);
11703 }
11704
11705 if (output_cum) {
11706 output_count += *output_cum;
11707 *output_cum = output_count;
11708 }
11709 if (total_cum) {
11710 total_count += *total_cum;
11711 *total_cum = total_count;
11712 }
11713 if (use_json) {
11714 if (rd) {
11715 vty_out(vty, " }%s ", (is_last ? "" : ","));
11716 }
11717 if (is_last) {
11718 unsigned long i;
11719 for (i = 0; i < *json_header_depth; ++i)
11720 vty_out(vty, " } ");
11721 if (!all)
11722 vty_out(vty, "\n");
11723 }
11724 } else {
11725 if (is_last) {
11726 /* No route is displayed */
11727 if (output_count == 0) {
11728 if (type == bgp_show_type_normal)
11729 vty_out(vty,
11730 "No BGP prefixes displayed, %ld exist\n",
11731 total_count);
11732 } else
11733 vty_out(vty,
11734 "\nDisplayed %ld routes and %ld total paths\n",
11735 output_count, total_count);
11736 }
11737 }
11738
11739 return CMD_SUCCESS;
11740 }
11741
11742 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11743 struct bgp_table *table, struct prefix_rd *prd_match,
11744 enum bgp_show_type type, void *output_arg,
11745 uint16_t show_flags)
11746 {
11747 struct bgp_dest *dest, *next;
11748 unsigned long output_cum = 0;
11749 unsigned long total_cum = 0;
11750 unsigned long json_header_depth = 0;
11751 struct bgp_table *itable;
11752 bool show_msg;
11753 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11754
11755 show_msg = (!use_json && type == bgp_show_type_normal);
11756
11757 for (dest = bgp_table_top(table); dest; dest = next) {
11758 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11759
11760 next = bgp_route_next(dest);
11761 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11762 continue;
11763
11764 itable = bgp_dest_get_bgp_table_info(dest);
11765 if (itable != NULL) {
11766 struct prefix_rd prd;
11767 char rd[RD_ADDRSTRLEN];
11768
11769 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11770 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11771 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11772 rd, next == NULL, &output_cum,
11773 &total_cum, &json_header_depth,
11774 show_flags, RPKI_NOT_BEING_USED);
11775 if (next == NULL)
11776 show_msg = false;
11777 }
11778 }
11779 if (show_msg) {
11780 if (output_cum == 0)
11781 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11782 total_cum);
11783 else
11784 vty_out(vty,
11785 "\nDisplayed %ld routes and %ld total paths\n",
11786 output_cum, total_cum);
11787 } else {
11788 if (use_json && output_cum == 0)
11789 vty_out(vty, "{}\n");
11790 }
11791 return CMD_SUCCESS;
11792 }
11793
11794 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11795 enum bgp_show_type type, void *output_arg,
11796 uint16_t show_flags, enum rpki_states rpki_target_state)
11797 {
11798 struct bgp_table *table;
11799 unsigned long json_header_depth = 0;
11800 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11801
11802 if (bgp == NULL) {
11803 bgp = bgp_get_default();
11804 }
11805
11806 if (bgp == NULL) {
11807 if (!use_json)
11808 vty_out(vty, "No BGP process is configured\n");
11809 else
11810 vty_out(vty, "{}\n");
11811 return CMD_WARNING;
11812 }
11813
11814 /* Labeled-unicast routes live in the unicast table. */
11815 if (safi == SAFI_LABELED_UNICAST)
11816 safi = SAFI_UNICAST;
11817
11818 table = bgp->rib[afi][safi];
11819 /* use MPLS and ENCAP specific shows until they are merged */
11820 if (safi == SAFI_MPLS_VPN) {
11821 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11822 output_arg, show_flags);
11823 }
11824
11825 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11826 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11827 output_arg, use_json,
11828 1, NULL, NULL);
11829 }
11830
11831 if (safi == SAFI_EVPN)
11832 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11833
11834 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11835 NULL, NULL, &json_header_depth, show_flags,
11836 rpki_target_state);
11837 }
11838
11839 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11840 safi_t safi, uint16_t show_flags)
11841 {
11842 struct listnode *node, *nnode;
11843 struct bgp *bgp;
11844 int is_first = 1;
11845 bool route_output = false;
11846 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11847
11848 if (use_json)
11849 vty_out(vty, "{\n");
11850
11851 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11852 route_output = true;
11853 if (use_json) {
11854 if (!is_first)
11855 vty_out(vty, ",\n");
11856 else
11857 is_first = 0;
11858
11859 vty_out(vty, "\"%s\":",
11860 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11861 ? VRF_DEFAULT_NAME
11862 : bgp->name);
11863 } else {
11864 vty_out(vty, "\nInstance %s:\n",
11865 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11866 ? VRF_DEFAULT_NAME
11867 : bgp->name);
11868 }
11869 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11870 show_flags, RPKI_NOT_BEING_USED);
11871 }
11872
11873 if (use_json)
11874 vty_out(vty, "}\n");
11875 else if (!route_output)
11876 vty_out(vty, "%% BGP instance not found\n");
11877 }
11878
11879 /* Header of detailed BGP route information */
11880 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11881 struct bgp_dest *dest, const struct prefix *p,
11882 const struct prefix_rd *prd, afi_t afi,
11883 safi_t safi, json_object *json,
11884 bool incremental_print)
11885 {
11886 struct bgp_path_info *pi;
11887 struct peer *peer;
11888 struct listnode *node, *nnode;
11889 char buf1[RD_ADDRSTRLEN];
11890 int count = 0;
11891 int best = 0;
11892 int suppress = 0;
11893 int accept_own = 0;
11894 int route_filter_translated_v4 = 0;
11895 int route_filter_v4 = 0;
11896 int route_filter_translated_v6 = 0;
11897 int route_filter_v6 = 0;
11898 int llgr_stale = 0;
11899 int no_llgr = 0;
11900 int accept_own_nexthop = 0;
11901 int blackhole = 0;
11902 int no_export = 0;
11903 int no_advertise = 0;
11904 int local_as = 0;
11905 int no_peer = 0;
11906 int first = 1;
11907 int has_valid_label = 0;
11908 mpls_label_t label = 0;
11909 json_object *json_adv_to = NULL;
11910 uint32_t ttl = 0;
11911 uint32_t bos = 0;
11912 uint32_t exp = 0;
11913
11914 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11915
11916 has_valid_label = bgp_is_valid_label(&label);
11917
11918 if (safi == SAFI_EVPN) {
11919 if (!json) {
11920 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11921 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11922 bgp->asnotation)
11923 : "",
11924 prd ? ":" : "", (struct prefix_evpn *)p);
11925 } else {
11926 json_object_string_add(
11927 json, "rd",
11928 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11929 bgp->asnotation)
11930 : "");
11931 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11932 }
11933 } else {
11934 if (!json) {
11935 vty_out(vty,
11936 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11937 "\n",
11938 (((safi == SAFI_MPLS_VPN ||
11939 safi == SAFI_ENCAP) &&
11940 prd)
11941 ? prefix_rd2str(prd, buf1,
11942 sizeof(buf1),
11943 bgp->asnotation)
11944 : ""),
11945 safi == SAFI_MPLS_VPN && prd ? ":" : "", p,
11946 dest->version);
11947
11948 } else {
11949 if (incremental_print) {
11950 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11951 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11952 dest->version);
11953 } else {
11954 json_object_string_addf(json, "prefix", "%pFX",
11955 p);
11956 json_object_int_add(json, "version",
11957 dest->version);
11958 }
11959 }
11960 }
11961
11962 if (has_valid_label) {
11963 if (json) {
11964 if (incremental_print)
11965 vty_out(vty, "\"localLabel\": \"%u\",\n",
11966 label);
11967 else
11968 json_object_int_add(json, "localLabel", label);
11969 } else
11970 vty_out(vty, "Local label: %d\n", label);
11971 }
11972
11973 if (!json)
11974 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11975 vty_out(vty, "not allocated\n");
11976
11977 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11978 struct community *picomm = NULL;
11979
11980 picomm = bgp_attr_get_community(pi->attr);
11981
11982 count++;
11983 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11984 best = count;
11985 if (bgp_path_suppressed(pi))
11986 suppress = 1;
11987
11988 if (!picomm)
11989 continue;
11990
11991 no_advertise += community_include(
11992 picomm, COMMUNITY_NO_ADVERTISE);
11993 no_export +=
11994 community_include(picomm, COMMUNITY_NO_EXPORT);
11995 local_as +=
11996 community_include(picomm, COMMUNITY_LOCAL_AS);
11997 accept_own +=
11998 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11999 route_filter_translated_v4 += community_include(
12000 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
12001 route_filter_translated_v6 += community_include(
12002 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
12003 route_filter_v4 += community_include(
12004 picomm, COMMUNITY_ROUTE_FILTER_v4);
12005 route_filter_v6 += community_include(
12006 picomm, COMMUNITY_ROUTE_FILTER_v6);
12007 llgr_stale +=
12008 community_include(picomm, COMMUNITY_LLGR_STALE);
12009 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
12010 accept_own_nexthop += community_include(
12011 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
12012 blackhole +=
12013 community_include(picomm, COMMUNITY_BLACKHOLE);
12014 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
12015 }
12016 }
12017
12018 if (!json) {
12019 vty_out(vty, "Paths: (%d available", count);
12020 if (best) {
12021 vty_out(vty, ", best #%d", best);
12022 if (safi == SAFI_UNICAST) {
12023 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
12024 vty_out(vty, ", table %s",
12025 VRF_DEFAULT_NAME);
12026 else
12027 vty_out(vty, ", vrf %s",
12028 bgp->name);
12029 }
12030 } else
12031 vty_out(vty, ", no best path");
12032
12033 if (accept_own)
12034 vty_out(vty,
12035 ", accept own local route exported and imported in different VRF");
12036 else if (route_filter_translated_v4)
12037 vty_out(vty,
12038 ", mark translated RTs for VPNv4 route filtering");
12039 else if (route_filter_v4)
12040 vty_out(vty,
12041 ", attach RT as-is for VPNv4 route filtering");
12042 else if (route_filter_translated_v6)
12043 vty_out(vty,
12044 ", mark translated RTs for VPNv6 route filtering");
12045 else if (route_filter_v6)
12046 vty_out(vty,
12047 ", attach RT as-is for VPNv6 route filtering");
12048 else if (llgr_stale)
12049 vty_out(vty,
12050 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
12051 else if (no_llgr)
12052 vty_out(vty,
12053 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
12054 else if (accept_own_nexthop)
12055 vty_out(vty,
12056 ", accept local nexthop");
12057 else if (blackhole)
12058 vty_out(vty, ", inform peer to blackhole prefix");
12059 else if (no_export)
12060 vty_out(vty, ", not advertised to EBGP peer");
12061 else if (no_advertise)
12062 vty_out(vty, ", not advertised to any peer");
12063 else if (local_as)
12064 vty_out(vty, ", not advertised outside local AS");
12065 else if (no_peer)
12066 vty_out(vty,
12067 ", inform EBGP peer not to advertise to their EBGP peers");
12068
12069 if (suppress)
12070 vty_out(vty,
12071 ", Advertisements suppressed by an aggregate.");
12072 vty_out(vty, ")\n");
12073 }
12074
12075 /* If we are not using addpath then we can display Advertised to and
12076 * that will
12077 * show what peers we advertised the bestpath to. If we are using
12078 * addpath
12079 * though then we must display Advertised to on a path-by-path basis. */
12080 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12081 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12082 if (bgp_adj_out_lookup(peer, dest, 0)) {
12083 if (json && !json_adv_to)
12084 json_adv_to = json_object_new_object();
12085
12086 route_vty_out_advertised_to(
12087 vty, peer, &first,
12088 " Advertised to non peer-group peers:\n ",
12089 json_adv_to);
12090 }
12091 }
12092
12093 if (json && json_adv_to) {
12094 if (incremental_print) {
12095 vty_out(vty, "\"advertisedTo\": ");
12096 vty_json(vty, json_adv_to);
12097 vty_out(vty, ",");
12098 } else
12099 json_object_object_add(json, "advertisedTo",
12100 json_adv_to);
12101 } else {
12102 if (!json && first)
12103 vty_out(vty, " Not advertised to any peer");
12104 vty_out(vty, "\n");
12105 }
12106 }
12107 }
12108
12109 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12110 struct bgp_dest *bgp_node, struct vty *vty,
12111 struct bgp *bgp, afi_t afi, safi_t safi,
12112 json_object *json, enum bgp_path_type pathtype,
12113 int *display, enum rpki_states rpki_target_state)
12114 {
12115 struct bgp_path_info *pi;
12116 int header = 1;
12117 json_object *json_header = NULL;
12118 json_object *json_paths = NULL;
12119 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12120
12121 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12122 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12123
12124 if (p->family == AF_INET || p->family == AF_INET6)
12125 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12126 pi->peer, pi->attr, p);
12127
12128 if (rpki_target_state != RPKI_NOT_BEING_USED
12129 && rpki_curr_state != rpki_target_state)
12130 continue;
12131
12132 if (json && !json_paths) {
12133 /* Instantiate json_paths only if path is valid */
12134 json_paths = json_object_new_array();
12135 if (pfx_rd)
12136 json_header = json_object_new_object();
12137 else
12138 json_header = json;
12139 }
12140
12141 if (header) {
12142 route_vty_out_detail_header(
12143 vty, bgp, bgp_node,
12144 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12145 safi, json_header, false);
12146 header = 0;
12147 }
12148 (*display)++;
12149
12150 if (pathtype == BGP_PATH_SHOW_ALL
12151 || (pathtype == BGP_PATH_SHOW_BESTPATH
12152 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12153 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12154 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12155 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12156 route_vty_out_detail(vty, bgp, bgp_node,
12157 bgp_dest_get_prefix(bgp_node), pi,
12158 AFI_IP, safi, rpki_curr_state,
12159 json_paths);
12160 }
12161
12162 if (json && json_paths) {
12163 json_object_object_add(json_header, "paths", json_paths);
12164
12165 if (pfx_rd)
12166 json_object_object_addf(
12167 json, json_header,
12168 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12169 }
12170 }
12171
12172 /*
12173 * Return rd based on safi
12174 */
12175 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12176 safi_t safi)
12177 {
12178 switch (safi) {
12179 case SAFI_MPLS_VPN:
12180 case SAFI_ENCAP:
12181 case SAFI_EVPN:
12182 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12183 case SAFI_UNSPEC:
12184 case SAFI_UNICAST:
12185 case SAFI_MULTICAST:
12186 case SAFI_LABELED_UNICAST:
12187 case SAFI_FLOWSPEC:
12188 case SAFI_MAX:
12189 return NULL;
12190 }
12191
12192 assert(!"Reached end of function when we were not expecting it");
12193 }
12194
12195 /* Display specified route of BGP table. */
12196 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12197 struct bgp_table *rib, const char *ip_str,
12198 afi_t afi, safi_t safi,
12199 enum rpki_states rpki_target_state,
12200 struct prefix_rd *prd, int prefix_check,
12201 enum bgp_path_type pathtype, bool use_json)
12202 {
12203 int ret;
12204 int display = 0;
12205 struct prefix match;
12206 struct bgp_dest *dest;
12207 struct bgp_dest *rm;
12208 struct bgp_table *table;
12209 json_object *json = NULL;
12210 json_object *json_paths = NULL;
12211
12212 /* Check IP address argument. */
12213 ret = str2prefix(ip_str, &match);
12214 if (!ret) {
12215 vty_out(vty, "address is malformed\n");
12216 return CMD_WARNING;
12217 }
12218
12219 match.family = afi2family(afi);
12220
12221 if (use_json)
12222 json = json_object_new_object();
12223
12224 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12225 for (dest = bgp_table_top(rib); dest;
12226 dest = bgp_route_next(dest)) {
12227 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12228
12229 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12230 continue;
12231 table = bgp_dest_get_bgp_table_info(dest);
12232 if (!table)
12233 continue;
12234
12235 rm = bgp_node_match(table, &match);
12236 if (rm == NULL)
12237 continue;
12238
12239 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12240 if (prefix_check
12241 && rm_p->prefixlen != match.prefixlen) {
12242 bgp_dest_unlock_node(rm);
12243 continue;
12244 }
12245
12246 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12247 bgp, afi, safi, json, pathtype,
12248 &display, rpki_target_state);
12249
12250 bgp_dest_unlock_node(rm);
12251 }
12252 } else if (safi == SAFI_EVPN) {
12253 struct bgp_dest *longest_pfx;
12254 bool is_exact_pfxlen_match = false;
12255
12256 for (dest = bgp_table_top(rib); dest;
12257 dest = bgp_route_next(dest)) {
12258 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12259
12260 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12261 continue;
12262 table = bgp_dest_get_bgp_table_info(dest);
12263 if (!table)
12264 continue;
12265
12266 longest_pfx = NULL;
12267 is_exact_pfxlen_match = false;
12268 /*
12269 * Search through all the prefixes for a match. The
12270 * pfx's are enumerated in ascending order of pfxlens.
12271 * So, the last pfx match is the longest match. Set
12272 * is_exact_pfxlen_match when we get exact pfxlen match
12273 */
12274 for (rm = bgp_table_top(table); rm;
12275 rm = bgp_route_next(rm)) {
12276 const struct prefix *rm_p =
12277 bgp_dest_get_prefix(rm);
12278 /*
12279 * Get prefixlen of the ip-prefix within type5
12280 * evpn route
12281 */
12282 if (evpn_type5_prefix_match(rm_p, &match)
12283 && rm->info) {
12284 longest_pfx = rm;
12285 int type5_pfxlen =
12286 bgp_evpn_get_type5_prefixlen(
12287 rm_p);
12288 if (type5_pfxlen == match.prefixlen) {
12289 is_exact_pfxlen_match = true;
12290 bgp_dest_unlock_node(rm);
12291 break;
12292 }
12293 }
12294 }
12295
12296 if (!longest_pfx)
12297 continue;
12298
12299 if (prefix_check && !is_exact_pfxlen_match)
12300 continue;
12301
12302 rm = longest_pfx;
12303 bgp_dest_lock_node(rm);
12304
12305 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12306 bgp, afi, safi, json, pathtype,
12307 &display, rpki_target_state);
12308
12309 bgp_dest_unlock_node(rm);
12310 }
12311 } else if (safi == SAFI_FLOWSPEC) {
12312 if (use_json)
12313 json_paths = json_object_new_array();
12314
12315 display = bgp_flowspec_display_match_per_ip(afi, rib,
12316 &match, prefix_check,
12317 vty,
12318 use_json,
12319 json_paths);
12320 if (use_json) {
12321 if (display)
12322 json_object_object_add(json, "paths",
12323 json_paths);
12324 else
12325 json_object_free(json_paths);
12326 }
12327 } else {
12328 dest = bgp_node_match(rib, &match);
12329 if (dest != NULL) {
12330 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12331 if (!prefix_check
12332 || dest_p->prefixlen == match.prefixlen) {
12333 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12334 safi, json, pathtype,
12335 &display, rpki_target_state);
12336 }
12337
12338 bgp_dest_unlock_node(dest);
12339 }
12340 }
12341
12342 if (use_json) {
12343 vty_json(vty, json);
12344 } else {
12345 if (!display) {
12346 vty_out(vty, "%% Network not in table\n");
12347 return CMD_WARNING;
12348 }
12349 }
12350
12351 return CMD_SUCCESS;
12352 }
12353
12354 /* Display specified route of Main RIB */
12355 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12356 afi_t afi, safi_t safi, struct prefix_rd *prd,
12357 int prefix_check, enum bgp_path_type pathtype,
12358 enum rpki_states rpki_target_state, bool use_json)
12359 {
12360 if (!bgp) {
12361 bgp = bgp_get_default();
12362 if (!bgp) {
12363 if (!use_json)
12364 vty_out(vty, "No BGP process is configured\n");
12365 else
12366 vty_out(vty, "{}\n");
12367 return CMD_WARNING;
12368 }
12369 }
12370
12371 /* labeled-unicast routes live in the unicast table */
12372 if (safi == SAFI_LABELED_UNICAST)
12373 safi = SAFI_UNICAST;
12374
12375 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12376 afi, safi, rpki_target_state, prd,
12377 prefix_check, pathtype, use_json);
12378 }
12379
12380 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12381 struct cmd_token **argv, bool exact, afi_t afi,
12382 safi_t safi, bool uj)
12383 {
12384 struct lcommunity *lcom;
12385 struct buffer *b;
12386 int i;
12387 char *str;
12388 int first = 0;
12389 uint16_t show_flags = 0;
12390 int ret;
12391
12392 if (uj)
12393 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12394
12395 b = buffer_new(1024);
12396 for (i = 0; i < argc; i++) {
12397 if (first)
12398 buffer_putc(b, ' ');
12399 else {
12400 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12401 first = 1;
12402 buffer_putstr(b, argv[i]->arg);
12403 }
12404 }
12405 }
12406 buffer_putc(b, '\0');
12407
12408 str = buffer_getstr(b);
12409 buffer_free(b);
12410
12411 lcom = lcommunity_str2com(str);
12412 XFREE(MTYPE_TMP, str);
12413 if (!lcom) {
12414 vty_out(vty, "%% Large-community malformed\n");
12415 return CMD_WARNING;
12416 }
12417
12418 ret = bgp_show(vty, bgp, afi, safi,
12419 (exact ? bgp_show_type_lcommunity_exact
12420 : bgp_show_type_lcommunity),
12421 lcom, show_flags, RPKI_NOT_BEING_USED);
12422
12423 lcommunity_free(&lcom);
12424 return ret;
12425 }
12426
12427 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12428 const char *lcom, bool exact, afi_t afi,
12429 safi_t safi, bool uj)
12430 {
12431 struct community_list *list;
12432 uint16_t show_flags = 0;
12433
12434 if (uj)
12435 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12436
12437
12438 list = community_list_lookup(bgp_clist, lcom, 0,
12439 LARGE_COMMUNITY_LIST_MASTER);
12440 if (list == NULL) {
12441 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12442 lcom);
12443 return CMD_WARNING;
12444 }
12445
12446 return bgp_show(vty, bgp, afi, safi,
12447 (exact ? bgp_show_type_lcommunity_list_exact
12448 : bgp_show_type_lcommunity_list),
12449 list, show_flags, RPKI_NOT_BEING_USED);
12450 }
12451
12452 DEFUN (show_ip_bgp_large_community_list,
12453 show_ip_bgp_large_community_list_cmd,
12454 "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]",
12455 SHOW_STR
12456 IP_STR
12457 BGP_STR
12458 BGP_INSTANCE_HELP_STR
12459 BGP_AFI_HELP_STR
12460 BGP_SAFI_WITH_LABEL_HELP_STR
12461 "Display routes matching the large-community-list\n"
12462 "large-community-list number\n"
12463 "large-community-list name\n"
12464 "Exact match of the large-communities\n"
12465 JSON_STR)
12466 {
12467 afi_t afi = AFI_IP6;
12468 safi_t safi = SAFI_UNICAST;
12469 int idx = 0;
12470 bool exact_match = 0;
12471 struct bgp *bgp = NULL;
12472 bool uj = use_json(argc, argv);
12473
12474 if (uj)
12475 argc--;
12476
12477 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12478 &bgp, uj);
12479 if (!idx)
12480 return CMD_WARNING;
12481
12482 argv_find(argv, argc, "large-community-list", &idx);
12483
12484 const char *clist_number_or_name = argv[++idx]->arg;
12485
12486 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12487 exact_match = 1;
12488
12489 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12490 exact_match, afi, safi, uj);
12491 }
12492 DEFUN (show_ip_bgp_large_community,
12493 show_ip_bgp_large_community_cmd,
12494 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12495 SHOW_STR
12496 IP_STR
12497 BGP_STR
12498 BGP_INSTANCE_HELP_STR
12499 BGP_AFI_HELP_STR
12500 BGP_SAFI_WITH_LABEL_HELP_STR
12501 "Display routes matching the large-communities\n"
12502 "List of large-community numbers\n"
12503 "Exact match of the large-communities\n"
12504 JSON_STR)
12505 {
12506 afi_t afi = AFI_IP6;
12507 safi_t safi = SAFI_UNICAST;
12508 int idx = 0;
12509 bool exact_match = 0;
12510 struct bgp *bgp = NULL;
12511 bool uj = use_json(argc, argv);
12512 uint16_t show_flags = 0;
12513
12514 if (uj) {
12515 argc--;
12516 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12517 }
12518
12519 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12520 &bgp, uj);
12521 if (!idx)
12522 return CMD_WARNING;
12523
12524 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12525 if (argv_find(argv, argc, "exact-match", &idx)) {
12526 argc--;
12527 exact_match = 1;
12528 }
12529 return bgp_show_lcommunity(vty, bgp, argc, argv,
12530 exact_match, afi, safi, uj);
12531 } else
12532 return bgp_show(vty, bgp, afi, safi,
12533 bgp_show_type_lcommunity_all, NULL, show_flags,
12534 RPKI_NOT_BEING_USED);
12535 }
12536
12537 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12538 safi_t safi, struct json_object *json_array);
12539 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12540 safi_t safi, struct json_object *json);
12541
12542
12543 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12544 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12545 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12546 "Display number of prefixes for all afi/safi\n" JSON_STR)
12547 {
12548 bool uj = use_json(argc, argv);
12549 struct bgp *bgp = NULL;
12550 safi_t safi = SAFI_UNICAST;
12551 afi_t afi = AFI_IP6;
12552 int idx = 0;
12553 struct json_object *json_all = NULL;
12554 struct json_object *json_afi_safi = NULL;
12555
12556 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12557 &bgp, false);
12558 if (!idx)
12559 return CMD_WARNING;
12560
12561 if (uj)
12562 json_all = json_object_new_object();
12563
12564 FOREACH_AFI_SAFI (afi, safi) {
12565 /*
12566 * So limit output to those afi/safi pairs that
12567 * actually have something interesting in them
12568 */
12569 if (strmatch(get_afi_safi_str(afi, safi, true),
12570 "Unknown")) {
12571 continue;
12572 }
12573 if (uj) {
12574 json_afi_safi = json_object_new_array();
12575 json_object_object_add(
12576 json_all,
12577 get_afi_safi_str(afi, safi, true),
12578 json_afi_safi);
12579 } else {
12580 json_afi_safi = NULL;
12581 }
12582
12583 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12584 }
12585
12586 if (uj)
12587 vty_json(vty, json_all);
12588
12589 return CMD_SUCCESS;
12590 }
12591
12592 /* BGP route print out function without JSON */
12593 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12594 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12595 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12596 SHOW_STR
12597 IP_STR
12598 BGP_STR
12599 BGP_INSTANCE_HELP_STR
12600 L2VPN_HELP_STR
12601 EVPN_HELP_STR
12602 "BGP RIB advertisement statistics\n"
12603 JSON_STR)
12604 {
12605 afi_t afi = AFI_IP6;
12606 safi_t safi = SAFI_UNICAST;
12607 struct bgp *bgp = NULL;
12608 int idx = 0, ret;
12609 bool uj = use_json(argc, argv);
12610 struct json_object *json_afi_safi = NULL, *json = NULL;
12611
12612 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12613 &bgp, false);
12614 if (!idx)
12615 return CMD_WARNING;
12616
12617 if (uj)
12618 json_afi_safi = json_object_new_array();
12619 else
12620 json_afi_safi = NULL;
12621
12622 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12623
12624 if (uj) {
12625 json = json_object_new_object();
12626 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12627 json_afi_safi);
12628 vty_json(vty, json);
12629 }
12630 return ret;
12631 }
12632
12633 /* BGP route print out function without JSON */
12634 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12635 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12636 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12637 "]]\
12638 statistics [json]",
12639 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12640 BGP_SAFI_WITH_LABEL_HELP_STR
12641 "BGP RIB advertisement statistics\n" JSON_STR)
12642 {
12643 afi_t afi = AFI_IP6;
12644 safi_t safi = SAFI_UNICAST;
12645 struct bgp *bgp = NULL;
12646 int idx = 0, ret;
12647 bool uj = use_json(argc, argv);
12648 struct json_object *json_afi_safi = NULL, *json = NULL;
12649
12650 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12651 &bgp, false);
12652 if (!idx)
12653 return CMD_WARNING;
12654
12655 if (uj)
12656 json_afi_safi = json_object_new_array();
12657 else
12658 json_afi_safi = NULL;
12659
12660 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12661
12662 if (uj) {
12663 json = json_object_new_object();
12664 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12665 json_afi_safi);
12666 vty_json(vty, json);
12667 }
12668 return ret;
12669 }
12670
12671 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12672 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12673 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12674 "]] [all$all] dampening parameters [json]",
12675 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12676 BGP_SAFI_WITH_LABEL_HELP_STR
12677 "Display the entries for all address families\n"
12678 "Display detailed information about dampening\n"
12679 "Display detail of configured dampening parameters\n"
12680 JSON_STR)
12681 {
12682 afi_t afi = AFI_IP6;
12683 safi_t safi = SAFI_UNICAST;
12684 struct bgp *bgp = NULL;
12685 int idx = 0;
12686 uint16_t show_flags = 0;
12687 bool uj = use_json(argc, argv);
12688
12689 if (uj) {
12690 argc--;
12691 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12692 }
12693
12694 /* [<ipv4|ipv6> [all]] */
12695 if (all) {
12696 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12697 if (argv_find(argv, argc, "ipv4", &idx))
12698 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12699
12700 if (argv_find(argv, argc, "ipv6", &idx))
12701 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12702 }
12703
12704 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12705 &bgp, false);
12706 if (!idx)
12707 return CMD_WARNING;
12708
12709 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12710 }
12711
12712 /* BGP route print out function */
12713 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12714 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12715 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12716 "]]\
12717 [all$all]\
12718 [cidr-only\
12719 |dampening <flap-statistics|dampened-paths>\
12720 |community [AA:NN|local-AS|no-advertise|no-export\
12721 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12722 |accept-own|accept-own-nexthop|route-filter-v6\
12723 |route-filter-v4|route-filter-translated-v6\
12724 |route-filter-translated-v4] [exact-match]\
12725 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12726 |filter-list AS_PATH_FILTER_NAME\
12727 |prefix-list WORD\
12728 |access-list ACCESSLIST_NAME\
12729 |route-map RMAP_NAME\
12730 |rpki <invalid|valid|notfound>\
12731 |version (1-4294967295)\
12732 |alias ALIAS_NAME\
12733 |A.B.C.D/M longer-prefixes\
12734 |X:X::X:X/M longer-prefixes\
12735 |"BGP_SELF_ORIG_CMD_STR"\
12736 |detail-routes$detail_routes\
12737 ] [json$uj [detail$detail_json] | wide$wide]",
12738 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12739 BGP_SAFI_WITH_LABEL_HELP_STR
12740 "Display the entries for all address families\n"
12741 "Display only routes with non-natural netmasks\n"
12742 "Display detailed information about dampening\n"
12743 "Display flap statistics of routes\n"
12744 "Display paths suppressed due to dampening\n"
12745 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12746 "Do not send outside local AS (well-known community)\n"
12747 "Do not advertise to any peer (well-known community)\n"
12748 "Do not export to next AS (well-known community)\n"
12749 "Graceful shutdown (well-known community)\n"
12750 "Do not export to any peer (well-known community)\n"
12751 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12752 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12753 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12754 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12755 "Should accept VPN route with local nexthop (well-known community)\n"
12756 "RT VPNv6 route filtering (well-known community)\n"
12757 "RT VPNv4 route filtering (well-known community)\n"
12758 "RT translated VPNv6 route filtering (well-known community)\n"
12759 "RT translated VPNv4 route filtering (well-known community)\n"
12760 "Exact match of the communities\n"
12761 "Community-list number\n"
12762 "Community-list name\n"
12763 "Display routes matching the community-list\n"
12764 "Exact match of the communities\n"
12765 "Display routes conforming to the filter-list\n"
12766 "Regular expression access list name\n"
12767 "Display routes conforming to the prefix-list\n"
12768 "Prefix-list name\n"
12769 "Display routes conforming to the access-list\n"
12770 "Access-list name\n"
12771 "Display routes matching the route-map\n"
12772 "A route-map to match on\n"
12773 "RPKI route types\n"
12774 "A valid path as determined by rpki\n"
12775 "A invalid path as determined by rpki\n"
12776 "A path that has no rpki data\n"
12777 "Display prefixes with matching version numbers\n"
12778 "Version number and above\n"
12779 "Display prefixes with matching BGP community alias\n"
12780 "BGP community alias\n"
12781 "IPv4 prefix\n"
12782 "Display route and more specific routes\n"
12783 "IPv6 prefix\n"
12784 "Display route and more specific routes\n"
12785 BGP_SELF_ORIG_HELP_STR
12786 "Display detailed version of all routes\n"
12787 JSON_STR
12788 "Display detailed version of JSON output\n"
12789 "Increase table width for longer prefixes\n")
12790 {
12791 afi_t afi = AFI_IP6;
12792 safi_t safi = SAFI_UNICAST;
12793 enum bgp_show_type sh_type = bgp_show_type_normal;
12794 void *output_arg = NULL;
12795 struct bgp *bgp = NULL;
12796 int idx = 0;
12797 int exact_match = 0;
12798 char *community = NULL;
12799 bool first = true;
12800 uint16_t show_flags = 0;
12801 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12802 struct prefix p;
12803
12804 if (uj) {
12805 argc--;
12806 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12807 }
12808
12809 if (detail_json)
12810 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12811
12812 if (detail_routes)
12813 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12814
12815 /* [<ipv4|ipv6> [all]] */
12816 if (all) {
12817 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12818
12819 if (argv_find(argv, argc, "ipv4", &idx))
12820 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12821
12822 if (argv_find(argv, argc, "ipv6", &idx))
12823 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12824 }
12825
12826 if (wide)
12827 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12828
12829 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12830 &bgp, uj);
12831 if (!idx)
12832 return CMD_WARNING;
12833
12834 if (argv_find(argv, argc, "cidr-only", &idx))
12835 sh_type = bgp_show_type_cidr_only;
12836
12837 if (argv_find(argv, argc, "dampening", &idx)) {
12838 if (argv_find(argv, argc, "dampened-paths", &idx))
12839 sh_type = bgp_show_type_dampend_paths;
12840 else if (argv_find(argv, argc, "flap-statistics", &idx))
12841 sh_type = bgp_show_type_flap_statistics;
12842 }
12843
12844 if (argv_find(argv, argc, "community", &idx)) {
12845 char *maybecomm = NULL;
12846
12847 if (idx + 1 < argc) {
12848 if (argv[idx + 1]->type == VARIABLE_TKN)
12849 maybecomm = argv[idx + 1]->arg;
12850 else
12851 maybecomm = argv[idx + 1]->text;
12852 }
12853
12854 if (maybecomm && !strmatch(maybecomm, "json")
12855 && !strmatch(maybecomm, "exact-match"))
12856 community = maybecomm;
12857
12858 if (argv_find(argv, argc, "exact-match", &idx))
12859 exact_match = 1;
12860
12861 if (!community)
12862 sh_type = bgp_show_type_community_all;
12863 }
12864
12865 if (argv_find(argv, argc, "community-list", &idx)) {
12866 const char *clist_number_or_name = argv[++idx]->arg;
12867 struct community_list *list;
12868
12869 if (argv_find(argv, argc, "exact-match", &idx))
12870 exact_match = 1;
12871
12872 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12873 COMMUNITY_LIST_MASTER);
12874 if (list == NULL) {
12875 vty_out(vty, "%% %s community-list not found\n",
12876 clist_number_or_name);
12877 return CMD_WARNING;
12878 }
12879
12880 if (exact_match)
12881 sh_type = bgp_show_type_community_list_exact;
12882 else
12883 sh_type = bgp_show_type_community_list;
12884 output_arg = list;
12885 }
12886
12887 if (argv_find(argv, argc, "filter-list", &idx)) {
12888 const char *filter = argv[++idx]->arg;
12889 struct as_list *as_list;
12890
12891 as_list = as_list_lookup(filter);
12892 if (as_list == NULL) {
12893 vty_out(vty, "%% %s AS-path access-list not found\n",
12894 filter);
12895 return CMD_WARNING;
12896 }
12897
12898 sh_type = bgp_show_type_filter_list;
12899 output_arg = as_list;
12900 }
12901
12902 if (argv_find(argv, argc, "prefix-list", &idx)) {
12903 const char *prefix_list_str = argv[++idx]->arg;
12904 struct prefix_list *plist;
12905
12906 plist = prefix_list_lookup(afi, prefix_list_str);
12907 if (plist == NULL) {
12908 vty_out(vty, "%% %s prefix-list not found\n",
12909 prefix_list_str);
12910 return CMD_WARNING;
12911 }
12912
12913 sh_type = bgp_show_type_prefix_list;
12914 output_arg = plist;
12915 }
12916
12917 if (argv_find(argv, argc, "access-list", &idx)) {
12918 const char *access_list_str = argv[++idx]->arg;
12919 struct access_list *alist;
12920
12921 alist = access_list_lookup(afi, access_list_str);
12922 if (!alist) {
12923 vty_out(vty, "%% %s access-list not found\n",
12924 access_list_str);
12925 return CMD_WARNING;
12926 }
12927
12928 sh_type = bgp_show_type_access_list;
12929 output_arg = alist;
12930 }
12931
12932 if (argv_find(argv, argc, "route-map", &idx)) {
12933 const char *rmap_str = argv[++idx]->arg;
12934 struct route_map *rmap;
12935
12936 rmap = route_map_lookup_by_name(rmap_str);
12937 if (!rmap) {
12938 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12939 return CMD_WARNING;
12940 }
12941
12942 sh_type = bgp_show_type_route_map;
12943 output_arg = rmap;
12944 }
12945
12946 if (argv_find(argv, argc, "rpki", &idx)) {
12947 sh_type = bgp_show_type_rpki;
12948 if (argv_find(argv, argc, "valid", &idx))
12949 rpki_target_state = RPKI_VALID;
12950 else if (argv_find(argv, argc, "invalid", &idx))
12951 rpki_target_state = RPKI_INVALID;
12952 }
12953
12954 /* Display prefixes with matching version numbers */
12955 if (argv_find(argv, argc, "version", &idx)) {
12956 sh_type = bgp_show_type_prefix_version;
12957 output_arg = argv[idx + 1]->arg;
12958 }
12959
12960 /* Display prefixes with matching BGP community alias */
12961 if (argv_find(argv, argc, "alias", &idx)) {
12962 sh_type = bgp_show_type_community_alias;
12963 output_arg = argv[idx + 1]->arg;
12964 }
12965
12966 /* prefix-longer */
12967 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12968 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12969 const char *prefix_str = argv[idx]->arg;
12970
12971 if (!str2prefix(prefix_str, &p)) {
12972 vty_out(vty, "%% Malformed Prefix\n");
12973 return CMD_WARNING;
12974 }
12975
12976 sh_type = bgp_show_type_prefix_longer;
12977 output_arg = &p;
12978 }
12979
12980 /* self originated only */
12981 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12982 sh_type = bgp_show_type_self_originated;
12983
12984 if (!all) {
12985 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12986 if (community)
12987 return bgp_show_community(vty, bgp, community,
12988 exact_match, afi, safi,
12989 show_flags);
12990 else
12991 return bgp_show(vty, bgp, afi, safi, sh_type,
12992 output_arg, show_flags,
12993 rpki_target_state);
12994 } else {
12995 struct listnode *node;
12996 struct bgp *abgp;
12997 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12998 * AFI_IP6 */
12999
13000 if (uj)
13001 vty_out(vty, "{\n");
13002
13003 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13004 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
13005 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13006 ? AFI_IP
13007 : AFI_IP6;
13008 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13009 FOREACH_SAFI (safi) {
13010 if (!bgp_afi_safi_peer_exists(abgp, afi,
13011 safi))
13012 continue;
13013
13014 if (uj) {
13015 if (first)
13016 first = false;
13017 else
13018 vty_out(vty, ",\n");
13019 vty_out(vty, "\"%s\":{\n",
13020 get_afi_safi_str(afi,
13021 safi,
13022 true));
13023 } else
13024 vty_out(vty,
13025 "\nFor address family: %s\n",
13026 get_afi_safi_str(
13027 afi, safi,
13028 false));
13029
13030 if (community)
13031 bgp_show_community(
13032 vty, abgp, community,
13033 exact_match, afi, safi,
13034 show_flags);
13035 else
13036 bgp_show(vty, abgp, afi, safi,
13037 sh_type, output_arg,
13038 show_flags,
13039 rpki_target_state);
13040 if (uj)
13041 vty_out(vty, "}\n");
13042 }
13043 }
13044 } else {
13045 /* show <ip> bgp all: for each AFI and SAFI*/
13046 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13047 FOREACH_AFI_SAFI (afi, safi) {
13048 if (!bgp_afi_safi_peer_exists(abgp, afi,
13049 safi))
13050 continue;
13051
13052 if (uj) {
13053 if (first)
13054 first = false;
13055 else
13056 vty_out(vty, ",\n");
13057
13058 vty_out(vty, "\"%s\":{\n",
13059 get_afi_safi_str(afi,
13060 safi,
13061 true));
13062 } else
13063 vty_out(vty,
13064 "\nFor address family: %s\n",
13065 get_afi_safi_str(
13066 afi, safi,
13067 false));
13068
13069 if (community)
13070 bgp_show_community(
13071 vty, abgp, community,
13072 exact_match, afi, safi,
13073 show_flags);
13074 else
13075 bgp_show(vty, abgp, afi, safi,
13076 sh_type, output_arg,
13077 show_flags,
13078 rpki_target_state);
13079 if (uj)
13080 vty_out(vty, "}\n");
13081 }
13082 }
13083 }
13084 if (uj)
13085 vty_out(vty, "}\n");
13086 }
13087 return CMD_SUCCESS;
13088 }
13089
13090 DEFUN (show_ip_bgp_route,
13091 show_ip_bgp_route_cmd,
13092 "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]",
13093 SHOW_STR
13094 IP_STR
13095 BGP_STR
13096 BGP_INSTANCE_HELP_STR
13097 BGP_AFI_HELP_STR
13098 BGP_SAFI_WITH_LABEL_HELP_STR
13099 "Network in the BGP routing table to display\n"
13100 "IPv4 prefix\n"
13101 "Network in the BGP routing table to display\n"
13102 "IPv6 prefix\n"
13103 "Display only the bestpath\n"
13104 "Display only multipaths\n"
13105 "Display only paths that match the specified rpki state\n"
13106 "A valid path as determined by rpki\n"
13107 "A invalid path as determined by rpki\n"
13108 "A path that has no rpki data\n"
13109 JSON_STR)
13110 {
13111 int prefix_check = 0;
13112
13113 afi_t afi = AFI_IP6;
13114 safi_t safi = SAFI_UNICAST;
13115 char *prefix = NULL;
13116 struct bgp *bgp = NULL;
13117 enum bgp_path_type path_type;
13118 bool uj = use_json(argc, argv);
13119
13120 int idx = 0;
13121
13122 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13123 &bgp, uj);
13124 if (!idx)
13125 return CMD_WARNING;
13126
13127 if (!bgp) {
13128 vty_out(vty,
13129 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13130 return CMD_WARNING;
13131 }
13132
13133 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13134 if (argv_find(argv, argc, "A.B.C.D", &idx)
13135 || argv_find(argv, argc, "X:X::X:X", &idx))
13136 prefix_check = 0;
13137 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13138 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13139 prefix_check = 1;
13140
13141 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13142 && afi != AFI_IP6) {
13143 vty_out(vty,
13144 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13145 return CMD_WARNING;
13146 }
13147 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13148 && afi != AFI_IP) {
13149 vty_out(vty,
13150 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13151 return CMD_WARNING;
13152 }
13153
13154 prefix = argv[idx]->arg;
13155
13156 /* [<bestpath|multipath>] */
13157 if (argv_find(argv, argc, "bestpath", &idx))
13158 path_type = BGP_PATH_SHOW_BESTPATH;
13159 else if (argv_find(argv, argc, "multipath", &idx))
13160 path_type = BGP_PATH_SHOW_MULTIPATH;
13161 else
13162 path_type = BGP_PATH_SHOW_ALL;
13163
13164 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13165 path_type, RPKI_NOT_BEING_USED, uj);
13166 }
13167
13168 DEFUN (show_ip_bgp_regexp,
13169 show_ip_bgp_regexp_cmd,
13170 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13171 SHOW_STR
13172 IP_STR
13173 BGP_STR
13174 BGP_INSTANCE_HELP_STR
13175 BGP_AFI_HELP_STR
13176 BGP_SAFI_WITH_LABEL_HELP_STR
13177 "Display routes matching the AS path regular expression\n"
13178 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13179 JSON_STR)
13180 {
13181 afi_t afi = AFI_IP6;
13182 safi_t safi = SAFI_UNICAST;
13183 struct bgp *bgp = NULL;
13184 bool uj = use_json(argc, argv);
13185 char *regstr = NULL;
13186
13187 int idx = 0;
13188 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13189 &bgp, false);
13190 if (!idx)
13191 return CMD_WARNING;
13192
13193 // get index of regex
13194 if (argv_find(argv, argc, "REGEX", &idx))
13195 regstr = argv[idx]->arg;
13196
13197 assert(regstr);
13198 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13199 bgp_show_type_regexp, uj);
13200 }
13201
13202 DEFPY (show_ip_bgp_instance_all,
13203 show_ip_bgp_instance_all_cmd,
13204 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13205 SHOW_STR
13206 IP_STR
13207 BGP_STR
13208 BGP_INSTANCE_ALL_HELP_STR
13209 BGP_AFI_HELP_STR
13210 BGP_SAFI_WITH_LABEL_HELP_STR
13211 JSON_STR
13212 "Increase table width for longer prefixes\n")
13213 {
13214 afi_t afi = AFI_IP6;
13215 safi_t safi = SAFI_UNICAST;
13216 struct bgp *bgp = NULL;
13217 int idx = 0;
13218 uint16_t show_flags = 0;
13219
13220 if (uj) {
13221 argc--;
13222 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13223 }
13224
13225 if (wide)
13226 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13227
13228 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13229 &bgp, uj);
13230 if (!idx)
13231 return CMD_WARNING;
13232
13233 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13234 return CMD_SUCCESS;
13235 }
13236
13237 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13238 afi_t afi, safi_t safi, enum bgp_show_type type,
13239 bool use_json)
13240 {
13241 regex_t *regex;
13242 int rc;
13243 uint16_t show_flags = 0;
13244
13245 if (use_json)
13246 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13247
13248 if (!config_bgp_aspath_validate(regstr)) {
13249 vty_out(vty, "Invalid character in REGEX %s\n",
13250 regstr);
13251 return CMD_WARNING_CONFIG_FAILED;
13252 }
13253
13254 regex = bgp_regcomp(regstr);
13255 if (!regex) {
13256 vty_out(vty, "Can't compile regexp %s\n", regstr);
13257 return CMD_WARNING;
13258 }
13259
13260 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13261 RPKI_NOT_BEING_USED);
13262 bgp_regex_free(regex);
13263 return rc;
13264 }
13265
13266 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13267 const char *comstr, int exact, afi_t afi,
13268 safi_t safi, uint16_t show_flags)
13269 {
13270 struct community *com;
13271 int ret = 0;
13272
13273 com = community_str2com(comstr);
13274 if (!com) {
13275 vty_out(vty, "%% Community malformed: %s\n", comstr);
13276 return CMD_WARNING;
13277 }
13278
13279 ret = bgp_show(vty, bgp, afi, safi,
13280 (exact ? bgp_show_type_community_exact
13281 : bgp_show_type_community),
13282 com, show_flags, RPKI_NOT_BEING_USED);
13283 community_free(&com);
13284
13285 return ret;
13286 }
13287
13288 enum bgp_stats {
13289 BGP_STATS_MAXBITLEN = 0,
13290 BGP_STATS_RIB,
13291 BGP_STATS_PREFIXES,
13292 BGP_STATS_TOTPLEN,
13293 BGP_STATS_UNAGGREGATEABLE,
13294 BGP_STATS_MAX_AGGREGATEABLE,
13295 BGP_STATS_AGGREGATES,
13296 BGP_STATS_SPACE,
13297 BGP_STATS_ASPATH_COUNT,
13298 BGP_STATS_ASPATH_MAXHOPS,
13299 BGP_STATS_ASPATH_TOTHOPS,
13300 BGP_STATS_ASPATH_MAXSIZE,
13301 BGP_STATS_ASPATH_TOTSIZE,
13302 BGP_STATS_ASN_HIGHEST,
13303 BGP_STATS_MAX,
13304 };
13305
13306 #define TABLE_STATS_IDX_VTY 0
13307 #define TABLE_STATS_IDX_JSON 1
13308
13309 static const char *table_stats_strs[][2] = {
13310 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13311 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13312 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13313 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13314 "unaggregateablePrefixes"},
13315 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13316 "maximumAggregateablePrefixes"},
13317 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13318 "bgpAggregateAdvertisements"},
13319 [BGP_STATS_SPACE] = {"Address space advertised",
13320 "addressSpaceAdvertised"},
13321 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13322 "advertisementsWithPaths"},
13323 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13324 "longestAsPath"},
13325 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13326 "largestAsPath"},
13327 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13328 "averageAsPathLengthHops"},
13329 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13330 "averageAsPathSizeBytes"},
13331 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13332 [BGP_STATS_MAX] = {NULL, NULL}
13333 };
13334
13335 struct bgp_table_stats {
13336 struct bgp_table *table;
13337 unsigned long long counts[BGP_STATS_MAX];
13338
13339 unsigned long long
13340 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13341 1];
13342
13343 double total_space;
13344 };
13345
13346 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13347 struct bgp_table_stats *ts, unsigned int space)
13348 {
13349 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13350 struct bgp_path_info *pi;
13351 const struct prefix *rn_p;
13352
13353 if (!bgp_dest_has_bgp_path_info_data(dest))
13354 return;
13355
13356 rn_p = bgp_dest_get_prefix(dest);
13357 ts->counts[BGP_STATS_PREFIXES]++;
13358 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13359
13360 ts->prefix_len_count[rn_p->prefixlen]++;
13361 /* check if the prefix is included by any other announcements */
13362 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13363 pdest = bgp_dest_parent_nolock(pdest);
13364
13365 if (pdest == NULL || pdest == top) {
13366 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13367 /* announced address space */
13368 if (space)
13369 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13370 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13371 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13372
13373
13374 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13375 ts->counts[BGP_STATS_RIB]++;
13376
13377 if (CHECK_FLAG(pi->attr->flag,
13378 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13379 ts->counts[BGP_STATS_AGGREGATES]++;
13380
13381 /* as-path stats */
13382 if (pi->attr->aspath) {
13383 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13384 unsigned int size = aspath_size(pi->attr->aspath);
13385 as_t highest = aspath_highest(pi->attr->aspath);
13386
13387 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13388
13389 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13390 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13391
13392 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13393 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13394
13395 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13396 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13397 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13398 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13399 }
13400 }
13401 }
13402
13403 static void bgp_table_stats_walker(struct event *t)
13404 {
13405 struct bgp_dest *dest, *ndest;
13406 struct bgp_dest *top;
13407 struct bgp_table_stats *ts = EVENT_ARG(t);
13408 unsigned int space = 0;
13409
13410 if (!(top = bgp_table_top(ts->table)))
13411 return;
13412
13413 switch (ts->table->afi) {
13414 case AFI_IP:
13415 space = IPV4_MAX_BITLEN;
13416 break;
13417 case AFI_IP6:
13418 space = IPV6_MAX_BITLEN;
13419 break;
13420 case AFI_L2VPN:
13421 space = EVPN_ROUTE_PREFIXLEN;
13422 break;
13423 case AFI_UNSPEC:
13424 case AFI_MAX:
13425 return;
13426 }
13427
13428 ts->counts[BGP_STATS_MAXBITLEN] = space;
13429
13430 for (dest = top; dest; dest = bgp_route_next(dest)) {
13431 if (ts->table->safi == SAFI_MPLS_VPN
13432 || ts->table->safi == SAFI_ENCAP
13433 || ts->table->safi == SAFI_EVPN) {
13434 struct bgp_table *table;
13435
13436 table = bgp_dest_get_bgp_table_info(dest);
13437 if (!table)
13438 continue;
13439
13440 top = bgp_table_top(table);
13441 for (ndest = bgp_table_top(table); ndest;
13442 ndest = bgp_route_next(ndest))
13443 bgp_table_stats_rn(ndest, top, ts, space);
13444 } else {
13445 bgp_table_stats_rn(dest, top, ts, space);
13446 }
13447 }
13448 }
13449
13450 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13451 struct json_object *json_array)
13452 {
13453 struct listnode *node, *nnode;
13454 struct bgp *bgp;
13455
13456 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13457 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13458 }
13459
13460 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13461 safi_t safi, struct json_object *json_array)
13462 {
13463 struct bgp_table_stats ts;
13464 unsigned int i;
13465 int ret = CMD_SUCCESS;
13466 char temp_buf[20];
13467 struct json_object *json = NULL;
13468 uint32_t bitlen = 0;
13469 struct json_object *json_bitlen;
13470
13471 if (json_array)
13472 json = json_object_new_object();
13473
13474 if (!bgp->rib[afi][safi]) {
13475 char warning_msg[50];
13476
13477 snprintf(warning_msg, sizeof(warning_msg),
13478 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13479 safi);
13480
13481 if (!json)
13482 vty_out(vty, "%s\n", warning_msg);
13483 else
13484 json_object_string_add(json, "warning", warning_msg);
13485
13486 ret = CMD_WARNING;
13487 goto end_table_stats;
13488 }
13489
13490 if (!json)
13491 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13492 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13493 else
13494 json_object_string_add(json, "instance", bgp->name_pretty);
13495
13496 /* labeled-unicast routes live in the unicast table */
13497 if (safi == SAFI_LABELED_UNICAST)
13498 safi = SAFI_UNICAST;
13499
13500 memset(&ts, 0, sizeof(ts));
13501 ts.table = bgp->rib[afi][safi];
13502 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13503
13504 for (i = 0; i < BGP_STATS_MAX; i++) {
13505 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13506 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13507 continue;
13508
13509 switch (i) {
13510 case BGP_STATS_ASPATH_TOTHOPS:
13511 case BGP_STATS_ASPATH_TOTSIZE:
13512 if (!json) {
13513 snprintf(
13514 temp_buf, sizeof(temp_buf), "%12.2f",
13515 ts.counts[i]
13516 ? (float)ts.counts[i]
13517 / (float)ts.counts
13518 [BGP_STATS_ASPATH_COUNT]
13519 : 0);
13520 vty_out(vty, "%-30s: %s",
13521 table_stats_strs[i]
13522 [TABLE_STATS_IDX_VTY],
13523 temp_buf);
13524 } else {
13525 json_object_double_add(
13526 json,
13527 table_stats_strs[i]
13528 [TABLE_STATS_IDX_JSON],
13529 ts.counts[i]
13530 ? (double)ts.counts[i]
13531 / (double)ts.counts
13532 [BGP_STATS_ASPATH_COUNT]
13533 : 0);
13534 }
13535 break;
13536 case BGP_STATS_TOTPLEN:
13537 if (!json) {
13538 snprintf(
13539 temp_buf, sizeof(temp_buf), "%12.2f",
13540 ts.counts[i]
13541 ? (float)ts.counts[i]
13542 / (float)ts.counts
13543 [BGP_STATS_PREFIXES]
13544 : 0);
13545 vty_out(vty, "%-30s: %s",
13546 table_stats_strs[i]
13547 [TABLE_STATS_IDX_VTY],
13548 temp_buf);
13549 } else {
13550 json_object_double_add(
13551 json,
13552 table_stats_strs[i]
13553 [TABLE_STATS_IDX_JSON],
13554 ts.counts[i]
13555 ? (double)ts.counts[i]
13556 / (double)ts.counts
13557 [BGP_STATS_PREFIXES]
13558 : 0);
13559 }
13560 break;
13561 case BGP_STATS_SPACE:
13562 if (!json) {
13563 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13564 ts.total_space);
13565 vty_out(vty, "%-30s: %s\n",
13566 table_stats_strs[i]
13567 [TABLE_STATS_IDX_VTY],
13568 temp_buf);
13569 } else {
13570 json_object_double_add(
13571 json,
13572 table_stats_strs[i]
13573 [TABLE_STATS_IDX_JSON],
13574 (double)ts.total_space);
13575 }
13576 if (afi == AFI_IP6) {
13577 if (!json) {
13578 snprintf(temp_buf, sizeof(temp_buf),
13579 "%12g",
13580 ts.total_space
13581 * pow(2.0, -128 + 32));
13582 vty_out(vty, "%30s: %s\n",
13583 "/32 equivalent %s\n",
13584 temp_buf);
13585 } else {
13586 json_object_double_add(
13587 json, "/32equivalent",
13588 (double)(ts.total_space
13589 * pow(2.0,
13590 -128 + 32)));
13591 }
13592 if (!json) {
13593 snprintf(temp_buf, sizeof(temp_buf),
13594 "%12g",
13595 ts.total_space
13596 * pow(2.0, -128 + 48));
13597 vty_out(vty, "%30s: %s\n",
13598 "/48 equivalent %s\n",
13599 temp_buf);
13600 } else {
13601 json_object_double_add(
13602 json, "/48equivalent",
13603 (double)(ts.total_space
13604 * pow(2.0,
13605 -128 + 48)));
13606 }
13607 } else {
13608 if (!json) {
13609 snprintf(temp_buf, sizeof(temp_buf),
13610 "%12.2f",
13611 ts.total_space * 100.
13612 * pow(2.0, -32));
13613 vty_out(vty, "%30s: %s\n",
13614 "% announced ", temp_buf);
13615 } else {
13616 json_object_double_add(
13617 json, "%announced",
13618 (double)(ts.total_space * 100.
13619 * pow(2.0, -32)));
13620 }
13621 if (!json) {
13622 snprintf(temp_buf, sizeof(temp_buf),
13623 "%12.2f",
13624 ts.total_space
13625 * pow(2.0, -32 + 8));
13626 vty_out(vty, "%30s: %s\n",
13627 "/8 equivalent ", temp_buf);
13628 } else {
13629 json_object_double_add(
13630 json, "/8equivalent",
13631 (double)(ts.total_space
13632 * pow(2.0, -32 + 8)));
13633 }
13634 if (!json) {
13635 snprintf(temp_buf, sizeof(temp_buf),
13636 "%12.2f",
13637 ts.total_space
13638 * pow(2.0, -32 + 24));
13639 vty_out(vty, "%30s: %s\n",
13640 "/24 equivalent ", temp_buf);
13641 } else {
13642 json_object_double_add(
13643 json, "/24equivalent",
13644 (double)(ts.total_space
13645 * pow(2.0, -32 + 24)));
13646 }
13647 }
13648 break;
13649 default:
13650 if (!json) {
13651 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13652 ts.counts[i]);
13653 vty_out(vty, "%-30s: %s",
13654 table_stats_strs[i]
13655 [TABLE_STATS_IDX_VTY],
13656 temp_buf);
13657 } else {
13658 json_object_int_add(
13659 json,
13660 table_stats_strs[i]
13661 [TABLE_STATS_IDX_JSON],
13662 ts.counts[i]);
13663 }
13664 }
13665 if (!json)
13666 vty_out(vty, "\n");
13667 }
13668
13669 switch (afi) {
13670 case AFI_IP:
13671 bitlen = IPV4_MAX_BITLEN;
13672 break;
13673 case AFI_IP6:
13674 bitlen = IPV6_MAX_BITLEN;
13675 break;
13676 case AFI_L2VPN:
13677 bitlen = EVPN_ROUTE_PREFIXLEN;
13678 break;
13679 case AFI_UNSPEC:
13680 case AFI_MAX:
13681 break;
13682 }
13683
13684 if (json) {
13685 json_bitlen = json_object_new_array();
13686
13687 for (i = 0; i <= bitlen; i++) {
13688 struct json_object *ind_bit = json_object_new_object();
13689
13690 if (!ts.prefix_len_count[i])
13691 continue;
13692
13693 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13694 json_object_int_add(ind_bit, temp_buf,
13695 ts.prefix_len_count[i]);
13696 json_object_array_add(json_bitlen, ind_bit);
13697 }
13698 json_object_object_add(json, "prefixLength", json_bitlen);
13699 }
13700
13701 end_table_stats:
13702 if (json)
13703 json_object_array_add(json_array, json);
13704 return ret;
13705 }
13706
13707 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13708 safi_t safi, struct json_object *json_array)
13709 {
13710 if (!bgp) {
13711 bgp_table_stats_all(vty, afi, safi, json_array);
13712 return CMD_SUCCESS;
13713 }
13714
13715 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13716 }
13717
13718 enum bgp_pcounts {
13719 PCOUNT_ADJ_IN = 0,
13720 PCOUNT_DAMPED,
13721 PCOUNT_REMOVED,
13722 PCOUNT_HISTORY,
13723 PCOUNT_STALE,
13724 PCOUNT_VALID,
13725 PCOUNT_ALL,
13726 PCOUNT_COUNTED,
13727 PCOUNT_BPATH_SELECTED,
13728 PCOUNT_PFCNT, /* the figure we display to users */
13729 PCOUNT_MAX,
13730 };
13731
13732 static const char *const pcount_strs[] = {
13733 [PCOUNT_ADJ_IN] = "Adj-in",
13734 [PCOUNT_DAMPED] = "Damped",
13735 [PCOUNT_REMOVED] = "Removed",
13736 [PCOUNT_HISTORY] = "History",
13737 [PCOUNT_STALE] = "Stale",
13738 [PCOUNT_VALID] = "Valid",
13739 [PCOUNT_ALL] = "All RIB",
13740 [PCOUNT_COUNTED] = "PfxCt counted",
13741 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13742 [PCOUNT_PFCNT] = "Useable",
13743 [PCOUNT_MAX] = NULL,
13744 };
13745
13746 struct peer_pcounts {
13747 unsigned int count[PCOUNT_MAX];
13748 const struct peer *peer;
13749 const struct bgp_table *table;
13750 safi_t safi;
13751 };
13752
13753 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13754 {
13755 const struct bgp_adj_in *ain;
13756 const struct bgp_path_info *pi;
13757 const struct peer *peer = pc->peer;
13758
13759 for (ain = rn->adj_in; ain; ain = ain->next)
13760 if (ain->peer == peer)
13761 pc->count[PCOUNT_ADJ_IN]++;
13762
13763 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13764
13765 if (pi->peer != peer)
13766 continue;
13767
13768 pc->count[PCOUNT_ALL]++;
13769
13770 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13771 pc->count[PCOUNT_DAMPED]++;
13772 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13773 pc->count[PCOUNT_HISTORY]++;
13774 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13775 pc->count[PCOUNT_REMOVED]++;
13776 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13777 pc->count[PCOUNT_STALE]++;
13778 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13779 pc->count[PCOUNT_VALID]++;
13780 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13781 pc->count[PCOUNT_PFCNT]++;
13782 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13783 pc->count[PCOUNT_BPATH_SELECTED]++;
13784
13785 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13786 pc->count[PCOUNT_COUNTED]++;
13787 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13788 flog_err(
13789 EC_LIB_DEVELOPMENT,
13790 "Attempting to count but flags say it is unusable");
13791 } else {
13792 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13793 flog_err(
13794 EC_LIB_DEVELOPMENT,
13795 "Not counted but flags say we should");
13796 }
13797 }
13798 }
13799
13800 static void bgp_peer_count_walker(struct event *t)
13801 {
13802 struct bgp_dest *rn, *rm;
13803 const struct bgp_table *table;
13804 struct peer_pcounts *pc = EVENT_ARG(t);
13805
13806 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13807 || pc->safi == SAFI_EVPN) {
13808 /* Special handling for 2-level routing tables. */
13809 for (rn = bgp_table_top(pc->table); rn;
13810 rn = bgp_route_next(rn)) {
13811 table = bgp_dest_get_bgp_table_info(rn);
13812 if (table != NULL)
13813 for (rm = bgp_table_top(table); rm;
13814 rm = bgp_route_next(rm))
13815 bgp_peer_count_proc(rm, pc);
13816 }
13817 } else
13818 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13819 bgp_peer_count_proc(rn, pc);
13820 }
13821
13822 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13823 safi_t safi, bool use_json)
13824 {
13825 struct peer_pcounts pcounts = {.peer = peer};
13826 unsigned int i;
13827 json_object *json = NULL;
13828 json_object *json_loop = NULL;
13829
13830 if (use_json) {
13831 json = json_object_new_object();
13832 json_loop = json_object_new_object();
13833 }
13834
13835 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13836 || !peer->bgp->rib[afi][safi]) {
13837 if (use_json) {
13838 json_object_string_add(
13839 json, "warning",
13840 "No such neighbor or address family");
13841 vty_out(vty, "%s\n", json_object_to_json_string(json));
13842 json_object_free(json);
13843 json_object_free(json_loop);
13844 } else
13845 vty_out(vty, "%% No such neighbor or address family\n");
13846
13847 return CMD_WARNING;
13848 }
13849
13850 memset(&pcounts, 0, sizeof(pcounts));
13851 pcounts.peer = peer;
13852 pcounts.table = peer->bgp->rib[afi][safi];
13853 pcounts.safi = safi;
13854
13855 /* in-place call via thread subsystem so as to record execution time
13856 * stats for the thread-walk (i.e. ensure this can't be blamed on
13857 * on just vty_read()).
13858 */
13859 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13860
13861 if (use_json) {
13862 json_object_string_add(json, "prefixCountsFor", peer->host);
13863 json_object_string_add(json, "multiProtocol",
13864 get_afi_safi_str(afi, safi, true));
13865 json_object_int_add(json, "pfxCounter",
13866 peer->pcount[afi][safi]);
13867
13868 for (i = 0; i < PCOUNT_MAX; i++)
13869 json_object_int_add(json_loop, pcount_strs[i],
13870 pcounts.count[i]);
13871
13872 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13873
13874 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13875 json_object_string_add(json, "pfxctDriftFor",
13876 peer->host);
13877 json_object_string_add(
13878 json, "recommended",
13879 "Please report this bug, with the above command output");
13880 }
13881 vty_json(vty, json);
13882 } else {
13883
13884 if (peer->hostname
13885 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13886 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13887 peer->hostname, peer->host,
13888 get_afi_safi_str(afi, safi, false));
13889 } else {
13890 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13891 get_afi_safi_str(afi, safi, false));
13892 }
13893
13894 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13895 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13896
13897 for (i = 0; i < PCOUNT_MAX; i++)
13898 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13899 pcounts.count[i]);
13900
13901 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13902 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13903 vty_out(vty,
13904 "Please report this bug, with the above command output\n");
13905 }
13906 }
13907
13908 return CMD_SUCCESS;
13909 }
13910
13911 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13912 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13913 "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]",
13914 SHOW_STR
13915 IP_STR
13916 BGP_STR
13917 BGP_INSTANCE_HELP_STR
13918 BGP_AFI_HELP_STR
13919 BGP_SAFI_HELP_STR
13920 "Detailed information on TCP and BGP neighbor connections\n"
13921 "Neighbor to display information about\n"
13922 "Neighbor to display information about\n"
13923 "Neighbor on BGP configured interface\n"
13924 "Display detailed prefix count information\n"
13925 JSON_STR)
13926 {
13927 afi_t afi = AFI_IP6;
13928 safi_t safi = SAFI_UNICAST;
13929 struct peer *peer;
13930 int idx = 0;
13931 struct bgp *bgp = NULL;
13932 bool uj = use_json(argc, argv);
13933
13934 if (uj)
13935 argc--;
13936
13937 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13938 &bgp, uj);
13939 if (!idx)
13940 return CMD_WARNING;
13941
13942 argv_find(argv, argc, "neighbors", &idx);
13943 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13944 if (!peer)
13945 return CMD_WARNING;
13946
13947 return bgp_peer_counts(vty, peer, afi, safi, uj);
13948 }
13949
13950 #ifdef KEEP_OLD_VPN_COMMANDS
13951 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13952 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13953 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13954 SHOW_STR
13955 IP_STR
13956 BGP_STR
13957 BGP_VPNVX_HELP_STR
13958 "Display information about all VPNv4 NLRIs\n"
13959 "Detailed information on TCP and BGP neighbor connections\n"
13960 "Neighbor to display information about\n"
13961 "Neighbor to display information about\n"
13962 "Neighbor on BGP configured interface\n"
13963 "Display detailed prefix count information\n"
13964 JSON_STR)
13965 {
13966 int idx_peer = 6;
13967 struct peer *peer;
13968 bool uj = use_json(argc, argv);
13969
13970 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13971 if (!peer)
13972 return CMD_WARNING;
13973
13974 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13975 }
13976
13977 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13978 show_ip_bgp_vpn_all_route_prefix_cmd,
13979 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13980 SHOW_STR
13981 IP_STR
13982 BGP_STR
13983 BGP_VPNVX_HELP_STR
13984 "Display information about all VPNv4 NLRIs\n"
13985 "Network in the BGP routing table to display\n"
13986 "Network in the BGP routing table to display\n"
13987 JSON_STR)
13988 {
13989 int idx = 0;
13990 char *network = NULL;
13991 struct bgp *bgp = bgp_get_default();
13992 if (!bgp) {
13993 vty_out(vty, "Can't find default instance\n");
13994 return CMD_WARNING;
13995 }
13996
13997 if (argv_find(argv, argc, "A.B.C.D", &idx))
13998 network = argv[idx]->arg;
13999 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
14000 network = argv[idx]->arg;
14001 else {
14002 vty_out(vty, "Unable to figure out Network\n");
14003 return CMD_WARNING;
14004 }
14005
14006 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
14007 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14008 use_json(argc, argv));
14009 }
14010 #endif /* KEEP_OLD_VPN_COMMANDS */
14011
14012 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
14013 show_bgp_l2vpn_evpn_route_prefix_cmd,
14014 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
14015 SHOW_STR
14016 BGP_STR
14017 L2VPN_HELP_STR
14018 EVPN_HELP_STR
14019 "Network in the BGP routing table to display\n"
14020 "Network in the BGP routing table to display\n"
14021 "Network in the BGP routing table to display\n"
14022 "Network in the BGP routing table to display\n"
14023 JSON_STR)
14024 {
14025 int idx = 0;
14026 char *network = NULL;
14027 int prefix_check = 0;
14028
14029 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
14030 argv_find(argv, argc, "X:X::X:X", &idx))
14031 network = argv[idx]->arg;
14032 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
14033 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
14034 network = argv[idx]->arg;
14035 prefix_check = 1;
14036 } else {
14037 vty_out(vty, "Unable to figure out Network\n");
14038 return CMD_WARNING;
14039 }
14040 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
14041 prefix_check, BGP_PATH_SHOW_ALL,
14042 RPKI_NOT_BEING_USED, use_json(argc, argv));
14043 }
14044
14045 static void show_adj_route_header(struct vty *vty, struct peer *peer,
14046 struct bgp_table *table, int *header1,
14047 int *header2, json_object *json,
14048 json_object *json_scode,
14049 json_object *json_ocode, bool wide,
14050 bool detail)
14051 {
14052 uint64_t version = table ? table->version : 0;
14053
14054 if (*header1) {
14055 if (json) {
14056 json_object_int_add(json, "bgpTableVersion", version);
14057 json_object_string_addf(json, "bgpLocalRouterId",
14058 "%pI4", &peer->bgp->router_id);
14059 json_object_int_add(json, "defaultLocPrf",
14060 peer->bgp->default_local_pref);
14061 json_object_int_add(json, "localAS",
14062 peer->change_local_as
14063 ? peer->change_local_as
14064 : peer->local_as);
14065 json_object_object_add(json, "bgpStatusCodes",
14066 json_scode);
14067 json_object_object_add(json, "bgpOriginCodes",
14068 json_ocode);
14069 } else {
14070 vty_out(vty,
14071 "BGP table version is %" PRIu64
14072 ", local router ID is %pI4, vrf id ",
14073 version, &peer->bgp->router_id);
14074 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14075 vty_out(vty, "%s", VRFID_NONE_STR);
14076 else
14077 vty_out(vty, "%u", peer->bgp->vrf_id);
14078 vty_out(vty, "\n");
14079 vty_out(vty, "Default local pref %u, ",
14080 peer->bgp->default_local_pref);
14081 vty_out(vty, "local AS %u\n",
14082 peer->change_local_as ? peer->change_local_as
14083 : peer->local_as);
14084 if (!detail) {
14085 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14086 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14087 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14088 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14089 }
14090 }
14091 *header1 = 0;
14092 }
14093 if (*header2) {
14094 if (!json && !detail)
14095 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14096 : BGP_SHOW_HEADER));
14097 *header2 = 0;
14098 }
14099 }
14100
14101 static void
14102 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14103 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14104 const char *rmap_name, json_object *json, json_object *json_ar,
14105 json_object *json_scode, json_object *json_ocode,
14106 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14107 const struct prefix *match, unsigned long *output_count,
14108 unsigned long *filtered_count)
14109 {
14110 struct bgp_adj_in *ain = NULL;
14111 struct bgp_adj_out *adj = NULL;
14112 struct bgp_dest *dest;
14113 struct bgp *bgp;
14114 struct attr attr;
14115 int ret;
14116 struct update_subgroup *subgrp;
14117 struct peer_af *paf = NULL;
14118 bool route_filtered;
14119 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14120 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14121 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14122 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14123 || (safi == SAFI_EVPN))
14124 ? true
14125 : false;
14126 int display = 0;
14127 json_object *json_net = NULL;
14128
14129 bgp = peer->bgp;
14130
14131 /* If the user supplied a prefix, look for a matching route instead
14132 * of walking the whole table.
14133 */
14134 if (match) {
14135 dest = bgp_node_match(table, match);
14136 if (!dest) {
14137 if (!use_json)
14138 vty_out(vty, "Network not in table\n");
14139 return;
14140 }
14141
14142 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14143
14144 if (rn_p->prefixlen != match->prefixlen) {
14145 if (!use_json)
14146 vty_out(vty, "Network not in table\n");
14147 bgp_dest_unlock_node(dest);
14148 return;
14149 }
14150
14151 if (type == bgp_show_adj_route_received ||
14152 type == bgp_show_adj_route_filtered) {
14153 for (ain = dest->adj_in; ain; ain = ain->next) {
14154 if (ain->peer == peer) {
14155 attr = *ain->attr;
14156 break;
14157 }
14158 }
14159 /* bail out if if adj_out is empty, or
14160 * if the prefix isn't in this peer's
14161 * adj_in
14162 */
14163 if (!ain || ain->peer != peer) {
14164 if (!use_json)
14165 vty_out(vty, "Network not in table\n");
14166 bgp_dest_unlock_node(dest);
14167 return;
14168 }
14169 } else if (type == bgp_show_adj_route_advertised) {
14170 bool peer_found = false;
14171
14172 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14173 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14174 if (paf->peer == peer && adj->attr) {
14175 attr = *adj->attr;
14176 peer_found = true;
14177 break;
14178 }
14179 }
14180 if (peer_found)
14181 break;
14182 }
14183 /* bail out if if adj_out is empty, or
14184 * if the prefix isn't in this peer's
14185 * adj_out
14186 */
14187 if (!paf || !peer_found) {
14188 if (!use_json)
14189 vty_out(vty, "Network not in table\n");
14190 bgp_dest_unlock_node(dest);
14191 return;
14192 }
14193 }
14194
14195 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14196 rmap_name);
14197
14198 if (ret != RMAP_DENY) {
14199 show_adj_route_header(vty, peer, table, header1,
14200 header2, json, json_scode,
14201 json_ocode, wide, detail);
14202
14203 if (use_json)
14204 json_net = json_object_new_object();
14205
14206 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14207 afi, safi, json_net,
14208 BGP_PATH_SHOW_ALL, &display,
14209 RPKI_NOT_BEING_USED);
14210 if (use_json)
14211 json_object_object_addf(json_ar, json_net,
14212 "%pFX", rn_p);
14213 (*output_count)++;
14214 } else
14215 (*filtered_count)++;
14216
14217 bgp_attr_flush(&attr);
14218 bgp_dest_unlock_node(dest);
14219 return;
14220 }
14221
14222
14223 subgrp = peer_subgroup(peer, afi, safi);
14224
14225 if (type == bgp_show_adj_route_advertised && subgrp
14226 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14227 if (use_json) {
14228 json_object_int_add(json, "bgpTableVersion",
14229 table->version);
14230 json_object_string_addf(json, "bgpLocalRouterId",
14231 "%pI4", &bgp->router_id);
14232 json_object_int_add(json, "defaultLocPrf",
14233 bgp->default_local_pref);
14234 json_object_int_add(json, "localAS",
14235 peer->change_local_as
14236 ? peer->change_local_as
14237 : peer->local_as);
14238 json_object_object_add(json, "bgpStatusCodes",
14239 json_scode);
14240 json_object_object_add(json, "bgpOriginCodes",
14241 json_ocode);
14242 json_object_string_add(
14243 json, "bgpOriginatingDefaultNetwork",
14244 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14245 } else {
14246 vty_out(vty,
14247 "BGP table version is %" PRIu64
14248 ", local router ID is %pI4, vrf id ",
14249 table->version, &bgp->router_id);
14250 if (bgp->vrf_id == VRF_UNKNOWN)
14251 vty_out(vty, "%s", VRFID_NONE_STR);
14252 else
14253 vty_out(vty, "%u", bgp->vrf_id);
14254 vty_out(vty, "\n");
14255 vty_out(vty, "Default local pref %u, ",
14256 bgp->default_local_pref);
14257 vty_out(vty, "local AS %u\n",
14258 peer->change_local_as ? peer->change_local_as
14259 : peer->local_as);
14260 if (!detail) {
14261 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14262 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14263 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14264 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14265 }
14266
14267 vty_out(vty, "Originating default network %s\n\n",
14268 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14269 }
14270 (*output_count)++;
14271 *header1 = 0;
14272 }
14273
14274 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14275 if (type == bgp_show_adj_route_received
14276 || type == bgp_show_adj_route_filtered) {
14277 for (ain = dest->adj_in; ain; ain = ain->next) {
14278 if (ain->peer != peer)
14279 continue;
14280
14281 show_adj_route_header(vty, peer, table, header1,
14282 header2, json, json_scode,
14283 json_ocode, wide, detail);
14284
14285 if ((safi == SAFI_MPLS_VPN)
14286 || (safi == SAFI_ENCAP)
14287 || (safi == SAFI_EVPN)) {
14288 if (use_json)
14289 json_object_string_add(
14290 json_ar, "rd", rd_str);
14291 else if (show_rd && rd_str) {
14292 vty_out(vty,
14293 "Route Distinguisher: %s\n",
14294 rd_str);
14295 show_rd = false;
14296 }
14297 }
14298
14299 attr = *ain->attr;
14300 route_filtered = false;
14301
14302 /* Filter prefix using distribute list,
14303 * filter list or prefix list
14304 */
14305 const struct prefix *rn_p =
14306 bgp_dest_get_prefix(dest);
14307 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14308 safi))
14309 == FILTER_DENY)
14310 route_filtered = true;
14311
14312 /* Filter prefix using route-map */
14313 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14314 safi, rmap_name, NULL,
14315 0, NULL);
14316
14317 if (type == bgp_show_adj_route_filtered &&
14318 !route_filtered && ret != RMAP_DENY) {
14319 bgp_attr_flush(&attr);
14320 continue;
14321 }
14322
14323 if (type == bgp_show_adj_route_received
14324 && (route_filtered || ret == RMAP_DENY))
14325 (*filtered_count)++;
14326
14327 if (detail) {
14328 if (use_json)
14329 json_net =
14330 json_object_new_object();
14331 bgp_show_path_info(
14332 NULL /* prefix_rd */, dest, vty,
14333 bgp, afi, safi, json_net,
14334 BGP_PATH_SHOW_ALL, &display,
14335 RPKI_NOT_BEING_USED);
14336 if (use_json)
14337 json_object_object_addf(
14338 json_ar, json_net,
14339 "%pFX", rn_p);
14340 } else
14341 route_vty_out_tmp(vty, dest, rn_p,
14342 &attr, safi, use_json,
14343 json_ar, wide);
14344 bgp_attr_flush(&attr);
14345 (*output_count)++;
14346 }
14347 } else if (type == bgp_show_adj_route_advertised) {
14348 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14349 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14350 if (paf->peer != peer || !adj->attr)
14351 continue;
14352
14353 show_adj_route_header(
14354 vty, peer, table, header1,
14355 header2, json, json_scode,
14356 json_ocode, wide, detail);
14357
14358 const struct prefix *rn_p =
14359 bgp_dest_get_prefix(dest);
14360
14361 attr = *adj->attr;
14362 ret = bgp_output_modifier(
14363 peer, rn_p, &attr, afi, safi,
14364 rmap_name);
14365
14366 if (ret != RMAP_DENY) {
14367 if ((safi == SAFI_MPLS_VPN)
14368 || (safi == SAFI_ENCAP)
14369 || (safi == SAFI_EVPN)) {
14370 if (use_json)
14371 json_object_string_add(
14372 json_ar,
14373 "rd",
14374 rd_str);
14375 else if (show_rd
14376 && rd_str) {
14377 vty_out(vty,
14378 "Route Distinguisher: %s\n",
14379 rd_str);
14380 show_rd = false;
14381 }
14382 }
14383 if (detail) {
14384 if (use_json)
14385 json_net =
14386 json_object_new_object();
14387 bgp_show_path_info(
14388 NULL /* prefix_rd
14389 */
14390 ,
14391 dest, vty, bgp,
14392 afi, safi,
14393 json_net,
14394 BGP_PATH_SHOW_ALL,
14395 &display,
14396 RPKI_NOT_BEING_USED);
14397 if (use_json)
14398 json_object_object_addf(
14399 json_ar,
14400 json_net,
14401 "%pFX",
14402 rn_p);
14403 } else
14404 route_vty_out_tmp(
14405 vty, dest, rn_p,
14406 &attr, safi,
14407 use_json,
14408 json_ar, wide);
14409 (*output_count)++;
14410 } else {
14411 (*filtered_count)++;
14412 }
14413
14414 bgp_attr_flush(&attr);
14415 }
14416 } else if (type == bgp_show_adj_route_bestpath) {
14417 struct bgp_path_info *pi;
14418
14419 show_adj_route_header(vty, peer, table, header1,
14420 header2, json, json_scode,
14421 json_ocode, wide, detail);
14422
14423 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14424
14425 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14426 pi = pi->next) {
14427 if (pi->peer != peer)
14428 continue;
14429
14430 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14431 continue;
14432
14433 if (detail) {
14434 if (use_json)
14435 json_net =
14436 json_object_new_object();
14437 bgp_show_path_info(
14438 NULL /* prefix_rd */, dest, vty,
14439 bgp, afi, safi, json_net,
14440 BGP_PATH_SHOW_BESTPATH,
14441 &display, RPKI_NOT_BEING_USED);
14442 if (use_json)
14443 json_object_object_addf(
14444 json_ar, json_net,
14445 "%pFX", rn_p);
14446 } else
14447 route_vty_out_tmp(
14448 vty, dest, rn_p, pi->attr, safi,
14449 use_json, json_ar, wide);
14450 (*output_count)++;
14451 }
14452 }
14453 }
14454 }
14455
14456 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14457 safi_t safi, enum bgp_show_adj_route_type type,
14458 const char *rmap_name, const struct prefix *match,
14459 uint16_t show_flags)
14460 {
14461 struct bgp *bgp;
14462 struct bgp_table *table;
14463 json_object *json = NULL;
14464 json_object *json_scode = NULL;
14465 json_object *json_ocode = NULL;
14466 json_object *json_ar = NULL;
14467 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14468
14469 /* Init BGP headers here so they're only displayed once
14470 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14471 */
14472 int header1 = 1;
14473 int header2 = 1;
14474
14475 /*
14476 * Initialize variables for each RD
14477 * All prefixes under an RD is aggregated within "json_routes"
14478 */
14479 char rd_str[BUFSIZ] = {0};
14480 json_object *json_routes = NULL;
14481
14482
14483 /* For 2-tier tables, prefix counts need to be
14484 * maintained across multiple runs of show_adj_route()
14485 */
14486 unsigned long output_count_per_rd;
14487 unsigned long filtered_count_per_rd;
14488 unsigned long output_count = 0;
14489 unsigned long filtered_count = 0;
14490
14491 if (use_json) {
14492 json = json_object_new_object();
14493 json_ar = json_object_new_object();
14494 json_scode = json_object_new_object();
14495 json_ocode = json_object_new_object();
14496 #if CONFDATE > 20231208
14497 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14498 #endif
14499 json_object_string_add(json_scode, "suppressed", "s");
14500 json_object_string_add(json_scode, "damped", "d");
14501 json_object_string_add(json_scode, "history", "h");
14502 json_object_string_add(json_scode, "valid", "*");
14503 json_object_string_add(json_scode, "best", ">");
14504 json_object_string_add(json_scode, "multipath", "=");
14505 json_object_string_add(json_scode, "internal", "i");
14506 json_object_string_add(json_scode, "ribFailure", "r");
14507 json_object_string_add(json_scode, "stale", "S");
14508 json_object_string_add(json_scode, "removed", "R");
14509
14510 #if CONFDATE > 20231208
14511 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14512 #endif
14513 json_object_string_add(json_ocode, "igp", "i");
14514 json_object_string_add(json_ocode, "egp", "e");
14515 json_object_string_add(json_ocode, "incomplete", "?");
14516 }
14517
14518 if (!peer || !peer->afc[afi][safi]) {
14519 if (use_json) {
14520 json_object_string_add(
14521 json, "warning",
14522 "No such neighbor or address family");
14523 vty_out(vty, "%s\n", json_object_to_json_string(json));
14524 json_object_free(json);
14525 json_object_free(json_ar);
14526 json_object_free(json_scode);
14527 json_object_free(json_ocode);
14528 } else
14529 vty_out(vty, "%% No such neighbor or address family\n");
14530
14531 return CMD_WARNING;
14532 }
14533
14534 if ((type == bgp_show_adj_route_received
14535 || type == bgp_show_adj_route_filtered)
14536 && !CHECK_FLAG(peer->af_flags[afi][safi],
14537 PEER_FLAG_SOFT_RECONFIG)) {
14538 if (use_json) {
14539 json_object_string_add(
14540 json, "warning",
14541 "Inbound soft reconfiguration not enabled");
14542 vty_out(vty, "%s\n", json_object_to_json_string(json));
14543 json_object_free(json);
14544 json_object_free(json_ar);
14545 json_object_free(json_scode);
14546 json_object_free(json_ocode);
14547 } else
14548 vty_out(vty,
14549 "%% Inbound soft reconfiguration not enabled\n");
14550
14551 return CMD_WARNING;
14552 }
14553
14554 bgp = peer->bgp;
14555
14556 /* labeled-unicast routes live in the unicast table */
14557 if (safi == SAFI_LABELED_UNICAST)
14558 table = bgp->rib[afi][SAFI_UNICAST];
14559 else
14560 table = bgp->rib[afi][safi];
14561
14562 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14563 || (safi == SAFI_EVPN)) {
14564
14565 struct bgp_dest *dest;
14566
14567 for (dest = bgp_table_top(table); dest;
14568 dest = bgp_route_next(dest)) {
14569 table = bgp_dest_get_bgp_table_info(dest);
14570 if (!table)
14571 continue;
14572
14573 output_count_per_rd = 0;
14574 filtered_count_per_rd = 0;
14575
14576 if (use_json)
14577 json_routes = json_object_new_object();
14578
14579 const struct prefix_rd *prd;
14580 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14581 dest);
14582
14583 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14584 bgp->asnotation);
14585
14586 show_adj_route(
14587 vty, peer, table, afi, safi, type, rmap_name,
14588 json, json_routes, json_scode, json_ocode,
14589 show_flags, &header1, &header2, rd_str, match,
14590 &output_count_per_rd, &filtered_count_per_rd);
14591
14592 /* Don't include an empty RD in the output! */
14593 if (json_routes && (output_count_per_rd > 0))
14594 json_object_object_add(json_ar, rd_str,
14595 json_routes);
14596
14597 output_count += output_count_per_rd;
14598 filtered_count += filtered_count_per_rd;
14599 }
14600 } else
14601 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14602 json, json_ar, json_scode, json_ocode,
14603 show_flags, &header1, &header2, rd_str, match,
14604 &output_count, &filtered_count);
14605
14606 if (use_json) {
14607 if (type == bgp_show_adj_route_advertised)
14608 json_object_object_add(json, "advertisedRoutes",
14609 json_ar);
14610 else
14611 json_object_object_add(json, "receivedRoutes", json_ar);
14612 json_object_int_add(json, "totalPrefixCounter", output_count);
14613 json_object_int_add(json, "filteredPrefixCounter",
14614 filtered_count);
14615
14616 /*
14617 * These fields only give up ownership to `json` when `header1`
14618 * is used (set to zero). See code in `show_adj_route` and
14619 * `show_adj_route_header`.
14620 */
14621 if (header1 == 1) {
14622 json_object_free(json_scode);
14623 json_object_free(json_ocode);
14624 }
14625
14626 vty_json(vty, json);
14627 } else if (output_count > 0) {
14628 if (!match && filtered_count > 0)
14629 vty_out(vty,
14630 "\nTotal number of prefixes %ld (%ld filtered)\n",
14631 output_count, filtered_count);
14632 else
14633 vty_out(vty, "\nTotal number of prefixes %ld\n",
14634 output_count);
14635 }
14636
14637 return CMD_SUCCESS;
14638 }
14639
14640 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14641 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14642 "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]",
14643 SHOW_STR
14644 IP_STR
14645 BGP_STR
14646 BGP_INSTANCE_HELP_STR
14647 BGP_AFI_HELP_STR
14648 BGP_SAFI_WITH_LABEL_HELP_STR
14649 "Detailed information on TCP and BGP neighbor connections\n"
14650 "Neighbor to display information about\n"
14651 "Neighbor to display information about\n"
14652 "Neighbor on BGP configured interface\n"
14653 "Display the routes selected by best path\n"
14654 "Display detailed version of routes\n"
14655 JSON_STR
14656 "Increase table width for longer prefixes\n")
14657 {
14658 afi_t afi = AFI_IP6;
14659 safi_t safi = SAFI_UNICAST;
14660 char *rmap_name = NULL;
14661 char *peerstr = NULL;
14662 struct bgp *bgp = NULL;
14663 struct peer *peer;
14664 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14665 int idx = 0;
14666 uint16_t show_flags = 0;
14667
14668 if (detail)
14669 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14670
14671 if (uj)
14672 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14673
14674 if (wide)
14675 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14676
14677 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14678 &bgp, uj);
14679
14680 if (!idx)
14681 return CMD_WARNING;
14682
14683 argv_find(argv, argc, "neighbors", &idx);
14684 peerstr = argv[++idx]->arg;
14685
14686 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14687 if (!peer)
14688 return CMD_WARNING;
14689
14690 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14691 show_flags);
14692 }
14693
14694 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14695 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14696 "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]",
14697 SHOW_STR
14698 IP_STR
14699 BGP_STR
14700 BGP_INSTANCE_HELP_STR
14701 BGP_AFI_HELP_STR
14702 BGP_SAFI_WITH_LABEL_HELP_STR
14703 "Display the entries for all address families\n"
14704 "Detailed information on TCP and BGP neighbor connections\n"
14705 "Neighbor to display information about\n"
14706 "Neighbor to display information about\n"
14707 "Neighbor on BGP configured interface\n"
14708 "Display the routes advertised to a BGP neighbor\n"
14709 "Display the received routes from neighbor\n"
14710 "Display the filtered routes received from neighbor\n"
14711 "Route-map to modify the attributes\n"
14712 "Name of the route map\n"
14713 "IPv4 prefix\n"
14714 "IPv6 prefix\n"
14715 "Display detailed version of routes\n"
14716 JSON_STR
14717 "Increase table width for longer prefixes\n")
14718 {
14719 afi_t afi = AFI_IP6;
14720 safi_t safi = SAFI_UNICAST;
14721 char *peerstr = NULL;
14722 struct bgp *bgp = NULL;
14723 struct peer *peer;
14724 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14725 int idx = 0;
14726 bool first = true;
14727 uint16_t show_flags = 0;
14728 struct listnode *node;
14729 struct bgp *abgp;
14730
14731 if (detail || prefix_str)
14732 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14733
14734 if (uj) {
14735 argc--;
14736 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14737 }
14738
14739 if (all) {
14740 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14741 if (argv_find(argv, argc, "ipv4", &idx))
14742 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14743
14744 if (argv_find(argv, argc, "ipv6", &idx))
14745 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14746 }
14747
14748 if (wide)
14749 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14750
14751 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14752 &bgp, uj);
14753 if (!idx)
14754 return CMD_WARNING;
14755
14756 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14757 argv_find(argv, argc, "neighbors", &idx);
14758 peerstr = argv[++idx]->arg;
14759
14760 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14761 if (!peer)
14762 return CMD_WARNING;
14763
14764 if (argv_find(argv, argc, "advertised-routes", &idx))
14765 type = bgp_show_adj_route_advertised;
14766 else if (argv_find(argv, argc, "received-routes", &idx))
14767 type = bgp_show_adj_route_received;
14768 else if (argv_find(argv, argc, "filtered-routes", &idx))
14769 type = bgp_show_adj_route_filtered;
14770
14771 if (!all)
14772 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14773 prefix_str ? prefix : NULL, show_flags);
14774 if (uj)
14775 vty_out(vty, "{\n");
14776
14777 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14778 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14779 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14780 : AFI_IP6;
14781 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14782 FOREACH_SAFI (safi) {
14783 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14784 continue;
14785
14786 if (uj) {
14787 if (first)
14788 first = false;
14789 else
14790 vty_out(vty, ",\n");
14791 vty_out(vty, "\"%s\":",
14792 get_afi_safi_str(afi, safi,
14793 true));
14794 } else
14795 vty_out(vty,
14796 "\nFor address family: %s\n",
14797 get_afi_safi_str(afi, safi,
14798 false));
14799
14800 peer_adj_routes(vty, peer, afi, safi, type,
14801 route_map, prefix, show_flags);
14802 }
14803 }
14804 } else {
14805 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14806 FOREACH_AFI_SAFI (afi, safi) {
14807 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14808 continue;
14809
14810 if (uj) {
14811 if (first)
14812 first = false;
14813 else
14814 vty_out(vty, ",\n");
14815 vty_out(vty, "\"%s\":",
14816 get_afi_safi_str(afi, safi,
14817 true));
14818 } else
14819 vty_out(vty,
14820 "\nFor address family: %s\n",
14821 get_afi_safi_str(afi, safi,
14822 false));
14823
14824 peer_adj_routes(vty, peer, afi, safi, type,
14825 route_map, prefix, show_flags);
14826 }
14827 }
14828 }
14829 if (uj)
14830 vty_out(vty, "}\n");
14831
14832 return CMD_SUCCESS;
14833 }
14834
14835 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14836 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14837 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14838 SHOW_STR
14839 IP_STR
14840 BGP_STR
14841 BGP_INSTANCE_HELP_STR
14842 BGP_AF_STR
14843 BGP_AF_STR
14844 BGP_AF_MODIFIER_STR
14845 "Detailed information on TCP and BGP neighbor connections\n"
14846 "Neighbor to display information about\n"
14847 "Neighbor to display information about\n"
14848 "Neighbor on BGP configured interface\n"
14849 "Display information received from a BGP neighbor\n"
14850 "Display the prefixlist filter\n"
14851 JSON_STR)
14852 {
14853 afi_t afi = AFI_IP6;
14854 safi_t safi = SAFI_UNICAST;
14855 char *peerstr = NULL;
14856 char name[BUFSIZ];
14857 struct peer *peer;
14858 int count;
14859 int idx = 0;
14860 struct bgp *bgp = NULL;
14861 bool uj = use_json(argc, argv);
14862
14863 if (uj)
14864 argc--;
14865
14866 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14867 &bgp, uj);
14868 if (!idx)
14869 return CMD_WARNING;
14870
14871 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14872 argv_find(argv, argc, "neighbors", &idx);
14873 peerstr = argv[++idx]->arg;
14874
14875 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14876 if (!peer)
14877 return CMD_WARNING;
14878
14879 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14880 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14881 if (count) {
14882 if (!uj)
14883 vty_out(vty, "Address Family: %s\n",
14884 get_afi_safi_str(afi, safi, false));
14885 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14886 } else {
14887 if (uj)
14888 vty_out(vty, "{}\n");
14889 else
14890 vty_out(vty, "No functional output\n");
14891 }
14892
14893 return CMD_SUCCESS;
14894 }
14895
14896 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14897 afi_t afi, safi_t safi,
14898 enum bgp_show_type type, bool use_json)
14899 {
14900 uint16_t show_flags = 0;
14901
14902 if (use_json)
14903 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14904
14905 if (!peer || !peer->afc[afi][safi]) {
14906 if (use_json) {
14907 json_object *json_no = NULL;
14908 json_no = json_object_new_object();
14909 json_object_string_add(
14910 json_no, "warning",
14911 "No such neighbor or address family");
14912 vty_out(vty, "%s\n",
14913 json_object_to_json_string(json_no));
14914 json_object_free(json_no);
14915 } else
14916 vty_out(vty, "%% No such neighbor or address family\n");
14917 return CMD_WARNING;
14918 }
14919
14920 /* labeled-unicast routes live in the unicast table */
14921 if (safi == SAFI_LABELED_UNICAST)
14922 safi = SAFI_UNICAST;
14923
14924 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14925 RPKI_NOT_BEING_USED);
14926 }
14927
14928 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14929 show_ip_bgp_flowspec_routes_detailed_cmd,
14930 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14931 SHOW_STR
14932 IP_STR
14933 BGP_STR
14934 BGP_INSTANCE_HELP_STR
14935 BGP_AFI_HELP_STR
14936 "SAFI Flowspec\n"
14937 "Detailed information on flowspec entries\n"
14938 JSON_STR)
14939 {
14940 afi_t afi = AFI_IP6;
14941 safi_t safi = SAFI_UNICAST;
14942 struct bgp *bgp = NULL;
14943 int idx = 0;
14944 bool uj = use_json(argc, argv);
14945 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14946
14947 if (uj) {
14948 argc--;
14949 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14950 }
14951
14952 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14953 &bgp, uj);
14954 if (!idx)
14955 return CMD_WARNING;
14956
14957 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14958 show_flags, RPKI_NOT_BEING_USED);
14959 }
14960
14961 DEFUN (show_ip_bgp_neighbor_routes,
14962 show_ip_bgp_neighbor_routes_cmd,
14963 "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]",
14964 SHOW_STR
14965 IP_STR
14966 BGP_STR
14967 BGP_INSTANCE_HELP_STR
14968 BGP_AFI_HELP_STR
14969 BGP_SAFI_WITH_LABEL_HELP_STR
14970 "Detailed information on TCP and BGP neighbor connections\n"
14971 "Neighbor to display information about\n"
14972 "Neighbor to display information about\n"
14973 "Neighbor on BGP configured interface\n"
14974 "Display flap statistics of the routes learned from neighbor\n"
14975 "Display the dampened routes received from neighbor\n"
14976 "Display routes learned from neighbor\n"
14977 JSON_STR)
14978 {
14979 char *peerstr = NULL;
14980 struct bgp *bgp = NULL;
14981 afi_t afi = AFI_IP6;
14982 safi_t safi = SAFI_UNICAST;
14983 struct peer *peer;
14984 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14985 int idx = 0;
14986 bool uj = use_json(argc, argv);
14987
14988 if (uj)
14989 argc--;
14990
14991 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14992 &bgp, uj);
14993 if (!idx)
14994 return CMD_WARNING;
14995
14996 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14997 argv_find(argv, argc, "neighbors", &idx);
14998 peerstr = argv[++idx]->arg;
14999
15000 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
15001 if (!peer)
15002 return CMD_WARNING;
15003
15004 if (argv_find(argv, argc, "flap-statistics", &idx))
15005 sh_type = bgp_show_type_flap_neighbor;
15006 else if (argv_find(argv, argc, "dampened-routes", &idx))
15007 sh_type = bgp_show_type_damp_neighbor;
15008 else if (argv_find(argv, argc, "routes", &idx))
15009 sh_type = bgp_show_type_neighbor;
15010
15011 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
15012 }
15013
15014 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
15015
15016 struct bgp_distance {
15017 /* Distance value for the IP source prefix. */
15018 uint8_t distance;
15019
15020 /* Name of the access-list to be matched. */
15021 char *access_list;
15022 };
15023
15024 DEFUN (show_bgp_afi_vpn_rd_route,
15025 show_bgp_afi_vpn_rd_route_cmd,
15026 "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]",
15027 SHOW_STR
15028 BGP_STR
15029 BGP_AFI_HELP_STR
15030 BGP_AF_MODIFIER_STR
15031 "Display information for a route distinguisher\n"
15032 "Route Distinguisher\n"
15033 "All Route Distinguishers\n"
15034 "Network in the BGP routing table to display\n"
15035 "Network in the BGP routing table to display\n"
15036 JSON_STR)
15037 {
15038 int ret;
15039 struct prefix_rd prd;
15040 afi_t afi = AFI_MAX;
15041 int idx = 0;
15042
15043 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
15044 vty_out(vty, "%% Malformed Address Family\n");
15045 return CMD_WARNING;
15046 }
15047
15048 if (!strcmp(argv[5]->arg, "all"))
15049 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
15050 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
15051 RPKI_NOT_BEING_USED,
15052 use_json(argc, argv));
15053
15054 ret = str2prefix_rd(argv[5]->arg, &prd);
15055 if (!ret) {
15056 vty_out(vty, "%% Malformed Route Distinguisher\n");
15057 return CMD_WARNING;
15058 }
15059
15060 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
15061 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
15062 use_json(argc, argv));
15063 }
15064
15065 static struct bgp_distance *bgp_distance_new(void)
15066 {
15067 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
15068 }
15069
15070 static void bgp_distance_free(struct bgp_distance *bdistance)
15071 {
15072 XFREE(MTYPE_BGP_DISTANCE, bdistance);
15073 }
15074
15075 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15076 const char *ip_str, const char *access_list_str)
15077 {
15078 int ret;
15079 afi_t afi;
15080 safi_t safi;
15081 struct prefix p;
15082 uint8_t distance;
15083 struct bgp_dest *dest;
15084 struct bgp_distance *bdistance;
15085
15086 afi = bgp_node_afi(vty);
15087 safi = bgp_node_safi(vty);
15088
15089 ret = str2prefix(ip_str, &p);
15090 if (ret == 0) {
15091 vty_out(vty, "Malformed prefix\n");
15092 return CMD_WARNING_CONFIG_FAILED;
15093 }
15094
15095 distance = atoi(distance_str);
15096
15097 /* Get BGP distance node. */
15098 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15099 bdistance = bgp_dest_get_bgp_distance_info(dest);
15100 if (bdistance)
15101 bgp_dest_unlock_node(dest);
15102 else {
15103 bdistance = bgp_distance_new();
15104 bgp_dest_set_bgp_distance_info(dest, bdistance);
15105 }
15106
15107 /* Set distance value. */
15108 bdistance->distance = distance;
15109
15110 /* Reset access-list configuration. */
15111 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15112 if (access_list_str)
15113 bdistance->access_list =
15114 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15115
15116 return CMD_SUCCESS;
15117 }
15118
15119 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15120 const char *ip_str, const char *access_list_str)
15121 {
15122 int ret;
15123 afi_t afi;
15124 safi_t safi;
15125 struct prefix p;
15126 int distance;
15127 struct bgp_dest *dest;
15128 struct bgp_distance *bdistance;
15129
15130 afi = bgp_node_afi(vty);
15131 safi = bgp_node_safi(vty);
15132
15133 ret = str2prefix(ip_str, &p);
15134 if (ret == 0) {
15135 vty_out(vty, "Malformed prefix\n");
15136 return CMD_WARNING_CONFIG_FAILED;
15137 }
15138
15139 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15140 if (!dest) {
15141 vty_out(vty, "Can't find specified prefix\n");
15142 return CMD_WARNING_CONFIG_FAILED;
15143 }
15144
15145 bdistance = bgp_dest_get_bgp_distance_info(dest);
15146 distance = atoi(distance_str);
15147
15148 if (bdistance->distance != distance) {
15149 vty_out(vty, "Distance does not match configured\n");
15150 bgp_dest_unlock_node(dest);
15151 return CMD_WARNING_CONFIG_FAILED;
15152 }
15153
15154 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15155 bgp_distance_free(bdistance);
15156
15157 bgp_dest_set_bgp_path_info(dest, NULL);
15158 bgp_dest_unlock_node(dest);
15159 bgp_dest_unlock_node(dest);
15160
15161 return CMD_SUCCESS;
15162 }
15163
15164 /* Apply BGP information to distance method. */
15165 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15166 afi_t afi, safi_t safi, struct bgp *bgp)
15167 {
15168 struct bgp_dest *dest;
15169 struct prefix q = {0};
15170 struct peer *peer;
15171 struct bgp_distance *bdistance;
15172 struct access_list *alist;
15173 struct bgp_static *bgp_static;
15174 struct bgp_path_info *bpi_ultimate;
15175
15176 if (!bgp)
15177 return 0;
15178
15179 peer = pinfo->peer;
15180
15181 if (pinfo->attr->distance)
15182 return pinfo->attr->distance;
15183
15184 /* get peer origin to calculate appropriate distance */
15185 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15186 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15187 peer = bpi_ultimate->peer;
15188 }
15189
15190 /* Check source address.
15191 * Note: for aggregate route, peer can have unspec af type.
15192 */
15193 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15194 && !sockunion2hostprefix(&peer->su, &q))
15195 return 0;
15196
15197 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15198 if (dest) {
15199 bdistance = bgp_dest_get_bgp_distance_info(dest);
15200 bgp_dest_unlock_node(dest);
15201
15202 if (bdistance->access_list) {
15203 alist = access_list_lookup(afi, bdistance->access_list);
15204 if (alist
15205 && access_list_apply(alist, p) == FILTER_PERMIT)
15206 return bdistance->distance;
15207 } else
15208 return bdistance->distance;
15209 }
15210
15211 /* Backdoor check. */
15212 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15213 if (dest) {
15214 bgp_static = bgp_dest_get_bgp_static_info(dest);
15215 bgp_dest_unlock_node(dest);
15216
15217 if (bgp_static->backdoor) {
15218 if (bgp->distance_local[afi][safi])
15219 return bgp->distance_local[afi][safi];
15220 else
15221 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15222 }
15223 }
15224
15225 if (peer->sort == BGP_PEER_EBGP) {
15226 if (bgp->distance_ebgp[afi][safi])
15227 return bgp->distance_ebgp[afi][safi];
15228 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15229 } else if (peer->sort == BGP_PEER_IBGP) {
15230 if (bgp->distance_ibgp[afi][safi])
15231 return bgp->distance_ibgp[afi][safi];
15232 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15233 } else {
15234 if (bgp->distance_local[afi][safi])
15235 return bgp->distance_local[afi][safi];
15236 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15237 }
15238 }
15239
15240 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15241 * we should tell ZEBRA update the routes for a specific
15242 * AFI/SAFI to reflect changes in RIB.
15243 */
15244 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15245 afi_t update_afi,
15246 safi_t update_safi)
15247 {
15248 afi_t afi;
15249 safi_t safi;
15250
15251 FOREACH_AFI_SAFI (afi, safi) {
15252 if (!bgp_fibupd_safi(safi))
15253 continue;
15254
15255 if (afi != update_afi && safi != update_safi)
15256 continue;
15257
15258 if (BGP_DEBUG(zebra, ZEBRA))
15259 zlog_debug(
15260 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15261 __func__, afi, safi);
15262 bgp_zebra_announce_table(bgp, afi, safi);
15263 }
15264 }
15265
15266 DEFUN (bgp_distance,
15267 bgp_distance_cmd,
15268 "distance bgp (1-255) (1-255) (1-255)",
15269 "Define an administrative distance\n"
15270 "BGP distance\n"
15271 "Distance for routes external to the AS\n"
15272 "Distance for routes internal to the AS\n"
15273 "Distance for local routes\n")
15274 {
15275 VTY_DECLVAR_CONTEXT(bgp, bgp);
15276 int idx_number = 2;
15277 int idx_number_2 = 3;
15278 int idx_number_3 = 4;
15279 int distance_ebgp = atoi(argv[idx_number]->arg);
15280 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15281 int distance_local = atoi(argv[idx_number_3]->arg);
15282 afi_t afi;
15283 safi_t safi;
15284
15285 afi = bgp_node_afi(vty);
15286 safi = bgp_node_safi(vty);
15287
15288 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15289 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15290 || bgp->distance_local[afi][safi] != distance_local) {
15291 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15292 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15293 bgp->distance_local[afi][safi] = distance_local;
15294 bgp_announce_routes_distance_update(bgp, afi, safi);
15295 }
15296 return CMD_SUCCESS;
15297 }
15298
15299 DEFUN (no_bgp_distance,
15300 no_bgp_distance_cmd,
15301 "no distance bgp [(1-255) (1-255) (1-255)]",
15302 NO_STR
15303 "Define an administrative distance\n"
15304 "BGP distance\n"
15305 "Distance for routes external to the AS\n"
15306 "Distance for routes internal to the AS\n"
15307 "Distance for local routes\n")
15308 {
15309 VTY_DECLVAR_CONTEXT(bgp, bgp);
15310 afi_t afi;
15311 safi_t safi;
15312
15313 afi = bgp_node_afi(vty);
15314 safi = bgp_node_safi(vty);
15315
15316 if (bgp->distance_ebgp[afi][safi] != 0
15317 || bgp->distance_ibgp[afi][safi] != 0
15318 || bgp->distance_local[afi][safi] != 0) {
15319 bgp->distance_ebgp[afi][safi] = 0;
15320 bgp->distance_ibgp[afi][safi] = 0;
15321 bgp->distance_local[afi][safi] = 0;
15322 bgp_announce_routes_distance_update(bgp, afi, safi);
15323 }
15324 return CMD_SUCCESS;
15325 }
15326
15327
15328 DEFUN (bgp_distance_source,
15329 bgp_distance_source_cmd,
15330 "distance (1-255) A.B.C.D/M",
15331 "Define an administrative distance\n"
15332 "Administrative distance\n"
15333 "IP source prefix\n")
15334 {
15335 int idx_number = 1;
15336 int idx_ipv4_prefixlen = 2;
15337 bgp_distance_set(vty, argv[idx_number]->arg,
15338 argv[idx_ipv4_prefixlen]->arg, NULL);
15339 return CMD_SUCCESS;
15340 }
15341
15342 DEFUN (no_bgp_distance_source,
15343 no_bgp_distance_source_cmd,
15344 "no distance (1-255) A.B.C.D/M",
15345 NO_STR
15346 "Define an administrative distance\n"
15347 "Administrative distance\n"
15348 "IP source prefix\n")
15349 {
15350 int idx_number = 2;
15351 int idx_ipv4_prefixlen = 3;
15352 bgp_distance_unset(vty, argv[idx_number]->arg,
15353 argv[idx_ipv4_prefixlen]->arg, NULL);
15354 return CMD_SUCCESS;
15355 }
15356
15357 DEFUN (bgp_distance_source_access_list,
15358 bgp_distance_source_access_list_cmd,
15359 "distance (1-255) A.B.C.D/M WORD",
15360 "Define an administrative distance\n"
15361 "Administrative distance\n"
15362 "IP source prefix\n"
15363 "Access list name\n")
15364 {
15365 int idx_number = 1;
15366 int idx_ipv4_prefixlen = 2;
15367 int idx_word = 3;
15368 bgp_distance_set(vty, argv[idx_number]->arg,
15369 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15370 return CMD_SUCCESS;
15371 }
15372
15373 DEFUN (no_bgp_distance_source_access_list,
15374 no_bgp_distance_source_access_list_cmd,
15375 "no distance (1-255) A.B.C.D/M WORD",
15376 NO_STR
15377 "Define an administrative distance\n"
15378 "Administrative distance\n"
15379 "IP source prefix\n"
15380 "Access list name\n")
15381 {
15382 int idx_number = 2;
15383 int idx_ipv4_prefixlen = 3;
15384 int idx_word = 4;
15385 bgp_distance_unset(vty, argv[idx_number]->arg,
15386 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15387 return CMD_SUCCESS;
15388 }
15389
15390 DEFUN (ipv6_bgp_distance_source,
15391 ipv6_bgp_distance_source_cmd,
15392 "distance (1-255) X:X::X:X/M",
15393 "Define an administrative distance\n"
15394 "Administrative distance\n"
15395 "IP source prefix\n")
15396 {
15397 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15398 return CMD_SUCCESS;
15399 }
15400
15401 DEFUN (no_ipv6_bgp_distance_source,
15402 no_ipv6_bgp_distance_source_cmd,
15403 "no distance (1-255) X:X::X:X/M",
15404 NO_STR
15405 "Define an administrative distance\n"
15406 "Administrative distance\n"
15407 "IP source prefix\n")
15408 {
15409 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15410 return CMD_SUCCESS;
15411 }
15412
15413 DEFUN (ipv6_bgp_distance_source_access_list,
15414 ipv6_bgp_distance_source_access_list_cmd,
15415 "distance (1-255) X:X::X:X/M WORD",
15416 "Define an administrative distance\n"
15417 "Administrative distance\n"
15418 "IP source prefix\n"
15419 "Access list name\n")
15420 {
15421 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15422 return CMD_SUCCESS;
15423 }
15424
15425 DEFUN (no_ipv6_bgp_distance_source_access_list,
15426 no_ipv6_bgp_distance_source_access_list_cmd,
15427 "no distance (1-255) X:X::X:X/M WORD",
15428 NO_STR
15429 "Define an administrative distance\n"
15430 "Administrative distance\n"
15431 "IP source prefix\n"
15432 "Access list name\n")
15433 {
15434 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15435 return CMD_SUCCESS;
15436 }
15437
15438 DEFUN (bgp_damp_set,
15439 bgp_damp_set_cmd,
15440 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15441 "BGP Specific commands\n"
15442 "Enable route-flap dampening\n"
15443 "Half-life time for the penalty\n"
15444 "Value to start reusing a route\n"
15445 "Value to start suppressing a route\n"
15446 "Maximum duration to suppress a stable route\n")
15447 {
15448 VTY_DECLVAR_CONTEXT(bgp, bgp);
15449 int idx_half_life = 2;
15450 int idx_reuse = 3;
15451 int idx_suppress = 4;
15452 int idx_max_suppress = 5;
15453 int half = DEFAULT_HALF_LIFE * 60;
15454 int reuse = DEFAULT_REUSE;
15455 int suppress = DEFAULT_SUPPRESS;
15456 int max = 4 * half;
15457
15458 if (argc == 6) {
15459 half = atoi(argv[idx_half_life]->arg) * 60;
15460 reuse = atoi(argv[idx_reuse]->arg);
15461 suppress = atoi(argv[idx_suppress]->arg);
15462 max = atoi(argv[idx_max_suppress]->arg) * 60;
15463 } else if (argc == 3) {
15464 half = atoi(argv[idx_half_life]->arg) * 60;
15465 max = 4 * half;
15466 }
15467
15468 /*
15469 * These can't be 0 but our SA doesn't understand the
15470 * way our cli is constructed
15471 */
15472 assert(reuse);
15473 assert(half);
15474 if (suppress < reuse) {
15475 vty_out(vty,
15476 "Suppress value cannot be less than reuse value \n");
15477 return 0;
15478 }
15479
15480 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15481 reuse, suppress, max);
15482 }
15483
15484 DEFUN (bgp_damp_unset,
15485 bgp_damp_unset_cmd,
15486 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15487 NO_STR
15488 "BGP Specific commands\n"
15489 "Enable route-flap dampening\n"
15490 "Half-life time for the penalty\n"
15491 "Value to start reusing a route\n"
15492 "Value to start suppressing a route\n"
15493 "Maximum duration to suppress a stable route\n")
15494 {
15495 VTY_DECLVAR_CONTEXT(bgp, bgp);
15496 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15497 }
15498
15499 /* Display specified route of BGP table. */
15500 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15501 const char *ip_str, afi_t afi, safi_t safi,
15502 struct prefix_rd *prd, int prefix_check)
15503 {
15504 int ret;
15505 struct prefix match;
15506 struct bgp_dest *dest;
15507 struct bgp_dest *rm;
15508 struct bgp_path_info *pi;
15509 struct bgp_path_info *pi_temp;
15510 struct bgp *bgp;
15511 struct bgp_table *table;
15512
15513 /* BGP structure lookup. */
15514 if (view_name) {
15515 bgp = bgp_lookup_by_name(view_name);
15516 if (bgp == NULL) {
15517 vty_out(vty, "%% Can't find BGP instance %s\n",
15518 view_name);
15519 return CMD_WARNING;
15520 }
15521 } else {
15522 bgp = bgp_get_default();
15523 if (bgp == NULL) {
15524 vty_out(vty, "%% No BGP process is configured\n");
15525 return CMD_WARNING;
15526 }
15527 }
15528
15529 /* Check IP address argument. */
15530 ret = str2prefix(ip_str, &match);
15531 if (!ret) {
15532 vty_out(vty, "%% address is malformed\n");
15533 return CMD_WARNING;
15534 }
15535
15536 match.family = afi2family(afi);
15537
15538 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15539 || (safi == SAFI_EVPN)) {
15540 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15541 dest = bgp_route_next(dest)) {
15542 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15543
15544 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15545 continue;
15546 table = bgp_dest_get_bgp_table_info(dest);
15547 if (!table)
15548 continue;
15549 rm = bgp_node_match(table, &match);
15550 if (rm == NULL)
15551 continue;
15552
15553 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15554
15555 if (!prefix_check
15556 || rm_p->prefixlen == match.prefixlen) {
15557 pi = bgp_dest_get_bgp_path_info(rm);
15558 while (pi) {
15559 if (pi->extra && pi->extra->damp_info) {
15560 pi_temp = pi->next;
15561 bgp_damp_info_free(
15562 pi->extra->damp_info,
15563 1, afi, safi);
15564 pi = pi_temp;
15565 } else
15566 pi = pi->next;
15567 }
15568 }
15569
15570 bgp_dest_unlock_node(rm);
15571 }
15572 } else {
15573 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15574 if (dest != NULL) {
15575 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15576
15577 if (!prefix_check
15578 || dest_p->prefixlen == match.prefixlen) {
15579 pi = bgp_dest_get_bgp_path_info(dest);
15580 while (pi) {
15581 if (pi->extra && pi->extra->damp_info) {
15582 pi_temp = pi->next;
15583 bgp_damp_info_free(
15584 pi->extra->damp_info,
15585 1, afi, safi);
15586 pi = pi_temp;
15587 } else
15588 pi = pi->next;
15589 }
15590 }
15591
15592 bgp_dest_unlock_node(dest);
15593 }
15594 }
15595
15596 return CMD_SUCCESS;
15597 }
15598
15599 DEFUN (clear_ip_bgp_dampening,
15600 clear_ip_bgp_dampening_cmd,
15601 "clear ip bgp dampening",
15602 CLEAR_STR
15603 IP_STR
15604 BGP_STR
15605 "Clear route flap dampening information\n")
15606 {
15607 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15608 return CMD_SUCCESS;
15609 }
15610
15611 DEFUN (clear_ip_bgp_dampening_prefix,
15612 clear_ip_bgp_dampening_prefix_cmd,
15613 "clear ip bgp dampening A.B.C.D/M",
15614 CLEAR_STR
15615 IP_STR
15616 BGP_STR
15617 "Clear route flap dampening information\n"
15618 "IPv4 prefix\n")
15619 {
15620 int idx_ipv4_prefixlen = 4;
15621 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15622 AFI_IP, SAFI_UNICAST, NULL, 1);
15623 }
15624
15625 DEFUN (clear_ip_bgp_dampening_address,
15626 clear_ip_bgp_dampening_address_cmd,
15627 "clear ip bgp dampening A.B.C.D",
15628 CLEAR_STR
15629 IP_STR
15630 BGP_STR
15631 "Clear route flap dampening information\n"
15632 "Network to clear damping information\n")
15633 {
15634 int idx_ipv4 = 4;
15635 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15636 SAFI_UNICAST, NULL, 0);
15637 }
15638
15639 DEFUN (clear_ip_bgp_dampening_address_mask,
15640 clear_ip_bgp_dampening_address_mask_cmd,
15641 "clear ip bgp dampening A.B.C.D A.B.C.D",
15642 CLEAR_STR
15643 IP_STR
15644 BGP_STR
15645 "Clear route flap dampening information\n"
15646 "Network to clear damping information\n"
15647 "Network mask\n")
15648 {
15649 int idx_ipv4 = 4;
15650 int idx_ipv4_2 = 5;
15651 int ret;
15652 char prefix_str[BUFSIZ];
15653
15654 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15655 prefix_str, sizeof(prefix_str));
15656 if (!ret) {
15657 vty_out(vty, "%% Inconsistent address and mask\n");
15658 return CMD_WARNING;
15659 }
15660
15661 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15662 NULL, 0);
15663 }
15664
15665 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15666 {
15667 struct vty *vty = arg;
15668 struct peer *peer = bucket->data;
15669
15670 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15671 }
15672
15673 DEFUN (show_bgp_listeners,
15674 show_bgp_listeners_cmd,
15675 "show bgp listeners",
15676 SHOW_STR
15677 BGP_STR
15678 "Display Listen Sockets and who created them\n")
15679 {
15680 bgp_dump_listener_info(vty);
15681
15682 return CMD_SUCCESS;
15683 }
15684
15685 DEFUN (show_bgp_peerhash,
15686 show_bgp_peerhash_cmd,
15687 "show bgp peerhash",
15688 SHOW_STR
15689 BGP_STR
15690 "Display information about the BGP peerhash\n")
15691 {
15692 struct list *instances = bm->bgp;
15693 struct listnode *node;
15694 struct bgp *bgp;
15695
15696 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15697 vty_out(vty, "BGP: %s\n", bgp->name);
15698 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15699 vty);
15700 }
15701
15702 return CMD_SUCCESS;
15703 }
15704
15705 /* also used for encap safi */
15706 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15707 afi_t afi, safi_t safi)
15708 {
15709 struct bgp_dest *pdest;
15710 struct bgp_dest *dest;
15711 struct bgp_table *table;
15712 const struct prefix *p;
15713 struct bgp_static *bgp_static;
15714 mpls_label_t label;
15715
15716 /* Network configuration. */
15717 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15718 pdest = bgp_route_next(pdest)) {
15719 table = bgp_dest_get_bgp_table_info(pdest);
15720 if (!table)
15721 continue;
15722
15723 for (dest = bgp_table_top(table); dest;
15724 dest = bgp_route_next(dest)) {
15725 bgp_static = bgp_dest_get_bgp_static_info(dest);
15726 if (bgp_static == NULL)
15727 continue;
15728
15729 p = bgp_dest_get_prefix(dest);
15730
15731 /* "network" configuration display. */
15732 label = decode_label(&bgp_static->label);
15733
15734 vty_out(vty, " network %pFX rd %s", p,
15735 bgp_static->prd_pretty);
15736 if (safi == SAFI_MPLS_VPN)
15737 vty_out(vty, " label %u", label);
15738
15739 if (bgp_static->rmap.name)
15740 vty_out(vty, " route-map %s",
15741 bgp_static->rmap.name);
15742
15743 if (bgp_static->backdoor)
15744 vty_out(vty, " backdoor");
15745
15746 vty_out(vty, "\n");
15747 }
15748 }
15749 }
15750
15751 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15752 afi_t afi, safi_t safi)
15753 {
15754 struct bgp_dest *pdest;
15755 struct bgp_dest *dest;
15756 struct bgp_table *table;
15757 const struct prefix *p;
15758 struct bgp_static *bgp_static;
15759 char buf[PREFIX_STRLEN * 2];
15760 char buf2[SU_ADDRSTRLEN];
15761 char esi_buf[ESI_STR_LEN];
15762
15763 /* Network configuration. */
15764 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15765 pdest = bgp_route_next(pdest)) {
15766 table = bgp_dest_get_bgp_table_info(pdest);
15767 if (!table)
15768 continue;
15769
15770 for (dest = bgp_table_top(table); dest;
15771 dest = bgp_route_next(dest)) {
15772 bgp_static = bgp_dest_get_bgp_static_info(dest);
15773 if (bgp_static == NULL)
15774 continue;
15775
15776 char *macrouter = NULL;
15777
15778 if (bgp_static->router_mac)
15779 macrouter = prefix_mac2str(
15780 bgp_static->router_mac, NULL, 0);
15781 if (bgp_static->eth_s_id)
15782 esi_to_str(bgp_static->eth_s_id,
15783 esi_buf, sizeof(esi_buf));
15784 p = bgp_dest_get_prefix(dest);
15785
15786 /* "network" configuration display. */
15787 if (p->u.prefix_evpn.route_type == 5) {
15788 char local_buf[PREFIX_STRLEN];
15789
15790 uint8_t family = is_evpn_prefix_ipaddr_v4((
15791 struct prefix_evpn *)p)
15792 ? AF_INET
15793 : AF_INET6;
15794 inet_ntop(family,
15795 &p->u.prefix_evpn.prefix_addr.ip.ip
15796 .addr,
15797 local_buf, sizeof(local_buf));
15798 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15799 p->u.prefix_evpn.prefix_addr
15800 .ip_prefix_length);
15801 } else {
15802 prefix2str(p, buf, sizeof(buf));
15803 }
15804
15805 if (bgp_static->gatewayIp.family == AF_INET
15806 || bgp_static->gatewayIp.family == AF_INET6)
15807 inet_ntop(bgp_static->gatewayIp.family,
15808 &bgp_static->gatewayIp.u.prefix, buf2,
15809 sizeof(buf2));
15810 vty_out(vty,
15811 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15812 buf, bgp_static->prd_pretty,
15813 p->u.prefix_evpn.prefix_addr.eth_tag,
15814 decode_label(&bgp_static->label), esi_buf, buf2,
15815 macrouter);
15816
15817 XFREE(MTYPE_TMP, macrouter);
15818 }
15819 }
15820 }
15821
15822 /* Configuration of static route announcement and aggregate
15823 information. */
15824 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15825 safi_t safi)
15826 {
15827 struct bgp_dest *dest;
15828 const struct prefix *p;
15829 struct bgp_static *bgp_static;
15830 struct bgp_aggregate *bgp_aggregate;
15831
15832 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15833 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15834 return;
15835 }
15836
15837 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15838 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15839 return;
15840 }
15841
15842 /* Network configuration. */
15843 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15844 dest = bgp_route_next(dest)) {
15845 bgp_static = bgp_dest_get_bgp_static_info(dest);
15846 if (bgp_static == NULL)
15847 continue;
15848
15849 p = bgp_dest_get_prefix(dest);
15850
15851 vty_out(vty, " network %pFX", p);
15852
15853 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15854 vty_out(vty, " label-index %u",
15855 bgp_static->label_index);
15856
15857 if (bgp_static->rmap.name)
15858 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15859
15860 if (bgp_static->backdoor)
15861 vty_out(vty, " backdoor");
15862
15863 vty_out(vty, "\n");
15864 }
15865
15866 /* Aggregate-address configuration. */
15867 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15868 dest = bgp_route_next(dest)) {
15869 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15870 if (bgp_aggregate == NULL)
15871 continue;
15872
15873 p = bgp_dest_get_prefix(dest);
15874
15875 vty_out(vty, " aggregate-address %pFX", p);
15876
15877 if (bgp_aggregate->as_set)
15878 vty_out(vty, " as-set");
15879
15880 if (bgp_aggregate->summary_only)
15881 vty_out(vty, " summary-only");
15882
15883 if (bgp_aggregate->rmap.name)
15884 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15885
15886 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15887 vty_out(vty, " origin %s",
15888 bgp_origin2str(bgp_aggregate->origin));
15889
15890 if (bgp_aggregate->match_med)
15891 vty_out(vty, " matching-MED-only");
15892
15893 if (bgp_aggregate->suppress_map_name)
15894 vty_out(vty, " suppress-map %s",
15895 bgp_aggregate->suppress_map_name);
15896
15897 vty_out(vty, "\n");
15898 }
15899 }
15900
15901 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15902 safi_t safi)
15903 {
15904 struct bgp_dest *dest;
15905 struct bgp_distance *bdistance;
15906
15907 /* Distance configuration. */
15908 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15909 && bgp->distance_local[afi][safi]
15910 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15911 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15912 || bgp->distance_local[afi][safi]
15913 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15914 vty_out(vty, " distance bgp %d %d %d\n",
15915 bgp->distance_ebgp[afi][safi],
15916 bgp->distance_ibgp[afi][safi],
15917 bgp->distance_local[afi][safi]);
15918 }
15919
15920 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15921 dest = bgp_route_next(dest)) {
15922 bdistance = bgp_dest_get_bgp_distance_info(dest);
15923 if (bdistance != NULL)
15924 vty_out(vty, " distance %d %pBD %s\n",
15925 bdistance->distance, dest,
15926 bdistance->access_list ? bdistance->access_list
15927 : "");
15928 }
15929 }
15930
15931 /* Allocate routing table structure and install commands. */
15932 void bgp_route_init(void)
15933 {
15934 afi_t afi;
15935 safi_t safi;
15936
15937 /* Init BGP distance table. */
15938 FOREACH_AFI_SAFI (afi, safi)
15939 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15940
15941 /* IPv4 BGP commands. */
15942 install_element(BGP_NODE, &bgp_table_map_cmd);
15943 install_element(BGP_NODE, &bgp_network_cmd);
15944 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15945
15946 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15947
15948 /* IPv4 unicast configuration. */
15949 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15950 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15951 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15952
15953 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15954
15955 /* IPv4 multicast configuration. */
15956 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15957 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15958 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15959 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15960
15961 /* IPv4 labeled-unicast configuration. */
15962 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15963 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15964
15965 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15966 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15967 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15968 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15969 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15970 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15971 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15972 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15973
15974 install_element(VIEW_NODE,
15975 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15976 install_element(VIEW_NODE,
15977 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15978 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15979 install_element(VIEW_NODE,
15980 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15981 #ifdef KEEP_OLD_VPN_COMMANDS
15982 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15983 #endif /* KEEP_OLD_VPN_COMMANDS */
15984 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15985 install_element(VIEW_NODE,
15986 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15987
15988 /* BGP dampening clear commands */
15989 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15990 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15991
15992 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15993 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15994
15995 /* prefix count */
15996 install_element(ENABLE_NODE,
15997 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15998 #ifdef KEEP_OLD_VPN_COMMANDS
15999 install_element(ENABLE_NODE,
16000 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
16001 #endif /* KEEP_OLD_VPN_COMMANDS */
16002
16003 /* New config IPv6 BGP commands. */
16004 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
16005 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
16006 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
16007
16008 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
16009
16010 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
16011
16012 /* IPv6 labeled unicast address family. */
16013 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
16014 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
16015
16016 install_element(BGP_NODE, &bgp_distance_cmd);
16017 install_element(BGP_NODE, &no_bgp_distance_cmd);
16018 install_element(BGP_NODE, &bgp_distance_source_cmd);
16019 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
16020 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
16021 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
16022 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
16023 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
16024 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
16025 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
16026 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
16027 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
16028 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
16029 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
16030 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
16031 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
16032 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
16033 install_element(BGP_IPV4M_NODE,
16034 &no_bgp_distance_source_access_list_cmd);
16035 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
16036 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
16037 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
16038 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
16039 install_element(BGP_IPV6_NODE,
16040 &ipv6_bgp_distance_source_access_list_cmd);
16041 install_element(BGP_IPV6_NODE,
16042 &no_ipv6_bgp_distance_source_access_list_cmd);
16043 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
16044 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
16045 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
16046 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
16047 install_element(BGP_IPV6M_NODE,
16048 &ipv6_bgp_distance_source_access_list_cmd);
16049 install_element(BGP_IPV6M_NODE,
16050 &no_ipv6_bgp_distance_source_access_list_cmd);
16051
16052 /* BGP dampening */
16053 install_element(BGP_NODE, &bgp_damp_set_cmd);
16054 install_element(BGP_NODE, &bgp_damp_unset_cmd);
16055 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
16056 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
16057 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
16058 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
16059 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
16060 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
16061 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
16062 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
16063 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
16064 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
16065 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
16066 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
16067
16068 /* Large Communities */
16069 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
16070 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
16071
16072 /* show bgp ipv4 flowspec detailed */
16073 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
16074
16075 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16076 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16077 }
16078
16079 void bgp_route_finish(void)
16080 {
16081 afi_t afi;
16082 safi_t safi;
16083
16084 FOREACH_AFI_SAFI (afi, safi) {
16085 bgp_table_unlock(bgp_distance_table[afi][safi]);
16086 bgp_distance_table[afi][safi] = NULL;
16087 }
16088 }