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