]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
2544ea520872d9410a332051be50396735dc0d53
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23 #include <math.h>
24
25 #include "printfrr.h"
26 #include "frrstr.h"
27 #include "prefix.h"
28 #include "linklist.h"
29 #include "memory.h"
30 #include "command.h"
31 #include "stream.h"
32 #include "filter.h"
33 #include "log.h"
34 #include "routemap.h"
35 #include "buffer.h"
36 #include "sockunion.h"
37 #include "plist.h"
38 #include "thread.h"
39 #include "workqueue.h"
40 #include "queue.h"
41 #include "memory.h"
42 #include "srv6.h"
43 #include "lib/json.h"
44 #include "lib_errors.h"
45 #include "zclient.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_route.h"
49 #include "bgpd/bgp_attr.h"
50 #include "bgpd/bgp_debug.h"
51 #include "bgpd/bgp_errors.h"
52 #include "bgpd/bgp_aspath.h"
53 #include "bgpd/bgp_regex.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_community_alias.h"
56 #include "bgpd/bgp_ecommunity.h"
57 #include "bgpd/bgp_lcommunity.h"
58 #include "bgpd/bgp_clist.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_filter.h"
61 #include "bgpd/bgp_fsm.h"
62 #include "bgpd/bgp_mplsvpn.h"
63 #include "bgpd/bgp_nexthop.h"
64 #include "bgpd/bgp_damp.h"
65 #include "bgpd/bgp_advertise.h"
66 #include "bgpd/bgp_zebra.h"
67 #include "bgpd/bgp_vty.h"
68 #include "bgpd/bgp_mpath.h"
69 #include "bgpd/bgp_nht.h"
70 #include "bgpd/bgp_updgrp.h"
71 #include "bgpd/bgp_label.h"
72 #include "bgpd/bgp_addpath.h"
73 #include "bgpd/bgp_mac.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_trace.h"
76 #include "bgpd/bgp_rpki.h"
77
78 #ifdef ENABLE_BGP_VNC
79 #include "bgpd/rfapi/rfapi_backend.h"
80 #include "bgpd/rfapi/vnc_import_bgp.h"
81 #include "bgpd/rfapi/vnc_export_bgp.h"
82 #endif
83 #include "bgpd/bgp_encap_types.h"
84 #include "bgpd/bgp_encap_tlv.h"
85 #include "bgpd/bgp_evpn.h"
86 #include "bgpd/bgp_evpn_mh.h"
87 #include "bgpd/bgp_evpn_vty.h"
88 #include "bgpd/bgp_flowspec.h"
89 #include "bgpd/bgp_flowspec_util.h"
90 #include "bgpd/bgp_pbr.h"
91
92 #ifndef VTYSH_EXTRACT_PL
93 #include "bgpd/bgp_route_clippy.c"
94 #endif
95
96 DEFINE_HOOK(bgp_snmp_update_stats,
97 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
98 (rn, pi, added));
99
100 DEFINE_HOOK(bgp_rpki_prefix_status,
101 (struct peer *peer, struct attr *attr,
102 const struct prefix *prefix),
103 (peer, attr, prefix));
104
105 /* Render dest to prefix_rd based on safi */
106 static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
107 safi_t safi);
108
109 /* Extern from bgp_dump.c */
110 extern const char *bgp_origin_str[];
111 extern const char *bgp_origin_long_str[];
112
113 /* PMSI strings. */
114 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
115 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
116 static const struct message bgp_pmsi_tnltype_str[] = {
117 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
118 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
119 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
120 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
121 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
122 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
123 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
124 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
125 {0}
126 };
127
128 #define VRFID_NONE_STR "-"
129 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
130
131 DEFINE_HOOK(bgp_process,
132 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
133 struct peer *peer, bool withdraw),
134 (bgp, afi, safi, bn, peer, withdraw));
135
136 /** Test if path is suppressed. */
137 static bool bgp_path_suppressed(struct bgp_path_info *pi)
138 {
139 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
140 return false;
141
142 return listcount(pi->extra->aggr_suppressors) > 0;
143 }
144
145 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
146 safi_t safi, const struct prefix *p,
147 struct prefix_rd *prd)
148 {
149 struct bgp_dest *dest;
150 struct bgp_dest *pdest = NULL;
151
152 assert(table);
153
154 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
155 || (safi == SAFI_EVPN)) {
156 pdest = bgp_node_get(table, (struct prefix *)prd);
157
158 if (!bgp_dest_has_bgp_path_info_data(pdest))
159 bgp_dest_set_bgp_table_info(
160 pdest, bgp_table_init(table->bgp, afi, safi));
161 else
162 bgp_dest_unlock_node(pdest);
163 table = bgp_dest_get_bgp_table_info(pdest);
164 }
165
166 dest = bgp_node_get(table, p);
167
168 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
169 || (safi == SAFI_EVPN))
170 dest->pdest = pdest;
171
172 return dest;
173 }
174
175 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
176 safi_t safi, const struct prefix *p,
177 struct prefix_rd *prd)
178 {
179 struct bgp_dest *dest;
180 struct bgp_dest *pdest = NULL;
181
182 if (!table)
183 return NULL;
184
185 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
186 || (safi == SAFI_EVPN)) {
187 pdest = bgp_node_lookup(table, (struct prefix *)prd);
188 if (!pdest)
189 return NULL;
190
191 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
192 bgp_dest_unlock_node(pdest);
193 return NULL;
194 }
195
196 table = bgp_dest_get_bgp_table_info(pdest);
197 }
198
199 dest = bgp_node_lookup(table, p);
200
201 return dest;
202 }
203
204 /* Allocate bgp_path_info_extra */
205 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
206 {
207 struct bgp_path_info_extra *new;
208 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
209 sizeof(struct bgp_path_info_extra));
210 new->label[0] = MPLS_INVALID_LABEL;
211 new->num_labels = 0;
212 new->bgp_fs_pbr = NULL;
213 new->bgp_fs_iprule = NULL;
214 return new;
215 }
216
217 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
218 {
219 struct bgp_path_info_extra *e;
220
221 if (!extra || !*extra)
222 return;
223
224 e = *extra;
225 if (e->damp_info)
226 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
227 e->damp_info->safi);
228
229 e->damp_info = NULL;
230 if (e->parent) {
231 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
232
233 if (bpi->net) {
234 /* FIXME: since multiple e may have the same e->parent
235 * and e->parent->net is holding a refcount for each
236 * of them, we need to do some fudging here.
237 *
238 * WARNING: if bpi->net->lock drops to 0, bpi may be
239 * freed as well (because bpi->net was holding the
240 * last reference to bpi) => write after free!
241 */
242 unsigned refcount;
243
244 bpi = bgp_path_info_lock(bpi);
245 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
246 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
247 if (!refcount)
248 bpi->net = NULL;
249 bgp_path_info_unlock(bpi);
250 }
251 bgp_path_info_unlock(e->parent);
252 e->parent = NULL;
253 }
254
255 if (e->bgp_orig)
256 bgp_unlock(e->bgp_orig);
257
258 if (e->aggr_suppressors)
259 list_delete(&e->aggr_suppressors);
260
261 if (e->mh_info)
262 bgp_evpn_path_mh_info_free(e->mh_info);
263
264 if ((*extra)->bgp_fs_iprule)
265 list_delete(&((*extra)->bgp_fs_iprule));
266 if ((*extra)->bgp_fs_pbr)
267 list_delete(&((*extra)->bgp_fs_pbr));
268 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
269 }
270
271 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
272 * allocated if required.
273 */
274 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
275 {
276 if (!pi->extra)
277 pi->extra = bgp_path_info_extra_new();
278 return pi->extra;
279 }
280
281 /* Free bgp route information. */
282 static void bgp_path_info_free(struct bgp_path_info *path)
283 {
284 bgp_attr_unintern(&path->attr);
285
286 bgp_unlink_nexthop(path);
287 bgp_path_info_extra_free(&path->extra);
288 bgp_path_info_mpath_free(&path->mpath);
289 if (path->net)
290 bgp_addpath_free_info_data(&path->tx_addpath,
291 &path->net->tx_addpath);
292
293 peer_unlock(path->peer); /* bgp_path_info peer reference */
294
295 XFREE(MTYPE_BGP_ROUTE, path);
296 }
297
298 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
299 {
300 path->lock++;
301 return path;
302 }
303
304 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
305 {
306 assert(path && path->lock > 0);
307 path->lock--;
308
309 if (path->lock == 0) {
310 bgp_path_info_free(path);
311 return NULL;
312 }
313
314 return path;
315 }
316
317 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
318 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
319 {
320 struct peer *peer;
321 struct bgp_path_info *old_pi, *nextpi;
322 bool set_flag = false;
323 struct bgp *bgp = NULL;
324 struct bgp_table *table = NULL;
325 afi_t afi = 0;
326 safi_t safi = 0;
327
328 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
329 * then the route selection is deferred
330 */
331 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
332 return 0;
333
334 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
335 if (BGP_DEBUG(update, UPDATE_OUT))
336 zlog_debug(
337 "Route %pBD is in workqueue and being processed, not deferred.",
338 dest);
339
340 return 0;
341 }
342
343 table = bgp_dest_table(dest);
344 if (table) {
345 bgp = table->bgp;
346 afi = table->afi;
347 safi = table->safi;
348 }
349
350 for (old_pi = bgp_dest_get_bgp_path_info(dest);
351 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
352 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
353 continue;
354
355 /* Route selection is deferred if there is a stale path which
356 * which indicates peer is in restart mode
357 */
358 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
359 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
360 set_flag = true;
361 } else {
362 /* If the peer is graceful restart capable and peer is
363 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
364 */
365 peer = old_pi->peer;
366 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
367 && BGP_PEER_RESTARTING_MODE(peer)
368 && (old_pi
369 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
370 set_flag = true;
371 }
372 }
373 if (set_flag)
374 break;
375 }
376
377 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
378 * is active
379 */
380 if (set_flag && table) {
381 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
382 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
383 bgp->gr_info[afi][safi].gr_deferred++;
384 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
385 if (BGP_DEBUG(update, UPDATE_OUT))
386 zlog_debug("DEFER route %pBD, dest %p", dest,
387 dest);
388 return 0;
389 }
390 }
391 return -1;
392 }
393
394 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
395 {
396 struct bgp_path_info *top;
397
398 top = bgp_dest_get_bgp_path_info(dest);
399
400 pi->next = top;
401 pi->prev = NULL;
402 if (top)
403 top->prev = pi;
404 bgp_dest_set_bgp_path_info(dest, pi);
405
406 bgp_path_info_lock(pi);
407 bgp_dest_lock_node(dest);
408 peer_lock(pi->peer); /* bgp_path_info peer reference */
409 bgp_dest_set_defer_flag(dest, false);
410 hook_call(bgp_snmp_update_stats, dest, pi, true);
411 }
412
413 /* Do the actual removal of info from RIB, for use by bgp_process
414 completion callback *only* */
415 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
416 {
417 if (pi->next)
418 pi->next->prev = pi->prev;
419 if (pi->prev)
420 pi->prev->next = pi->next;
421 else
422 bgp_dest_set_bgp_path_info(dest, pi->next);
423
424 bgp_path_info_mpath_dequeue(pi);
425 bgp_path_info_unlock(pi);
426 hook_call(bgp_snmp_update_stats, dest, pi, false);
427 bgp_dest_unlock_node(dest);
428 }
429
430 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
431 {
432 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
433 /* set of previous already took care of pcount */
434 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
435 }
436
437 /* undo the effects of a previous call to bgp_path_info_delete; typically
438 called when a route is deleted and then quickly re-added before the
439 deletion has been processed */
440 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
441 {
442 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
443 /* unset of previous already took care of pcount */
444 SET_FLAG(pi->flags, BGP_PATH_VALID);
445 }
446
447 /* Adjust pcount as required */
448 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
449 {
450 struct bgp_table *table;
451
452 assert(dest && bgp_dest_table(dest));
453 assert(pi && pi->peer && pi->peer->bgp);
454
455 table = bgp_dest_table(dest);
456
457 if (pi->peer == pi->peer->bgp->peer_self)
458 return;
459
460 if (!BGP_PATH_COUNTABLE(pi)
461 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
462
463 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
464
465 /* slight hack, but more robust against errors. */
466 if (pi->peer->pcount[table->afi][table->safi])
467 pi->peer->pcount[table->afi][table->safi]--;
468 else
469 flog_err(EC_LIB_DEVELOPMENT,
470 "Asked to decrement 0 prefix count for peer");
471 } else if (BGP_PATH_COUNTABLE(pi)
472 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
473 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
474 pi->peer->pcount[table->afi][table->safi]++;
475 }
476 }
477
478 static int bgp_label_index_differs(struct bgp_path_info *pi1,
479 struct bgp_path_info *pi2)
480 {
481 return (!(pi1->attr->label_index == pi2->attr->label_index));
482 }
483
484 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
485 * This is here primarily to keep prefix-count in check.
486 */
487 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
488 uint32_t flag)
489 {
490 SET_FLAG(pi->flags, flag);
491
492 /* early bath if we know it's not a flag that changes countability state
493 */
494 if (!CHECK_FLAG(flag,
495 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
496 return;
497
498 bgp_pcount_adjust(dest, pi);
499 }
500
501 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
502 uint32_t flag)
503 {
504 UNSET_FLAG(pi->flags, flag);
505
506 /* early bath if we know it's not a flag that changes countability state
507 */
508 if (!CHECK_FLAG(flag,
509 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
510 return;
511
512 bgp_pcount_adjust(dest, pi);
513 }
514
515 /* Get MED value. If MED value is missing and "bgp bestpath
516 missing-as-worst" is specified, treat it as the worst value. */
517 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
518 {
519 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
520 return attr->med;
521 else {
522 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
523 return BGP_MED_MAX;
524 else
525 return 0;
526 }
527 }
528
529 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
530 size_t buf_len)
531 {
532 if (pi->addpath_rx_id)
533 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
534 pi->peer->host, pi->addpath_rx_id);
535 else
536 snprintf(buf, buf_len, "path %s", pi->peer->host);
537 }
538
539
540 /*
541 * Get the ultimate path info.
542 */
543 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
544 {
545 struct bgp_path_info *bpi_ultimate;
546
547 if (info->sub_type != BGP_ROUTE_IMPORTED)
548 return info;
549
550 for (bpi_ultimate = info;
551 bpi_ultimate->extra && bpi_ultimate->extra->parent;
552 bpi_ultimate = bpi_ultimate->extra->parent)
553 ;
554
555 return bpi_ultimate;
556 }
557
558 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
559 */
560 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
561 struct bgp_path_info *exist, int *paths_eq,
562 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
563 char *pfx_buf, afi_t afi, safi_t safi,
564 enum bgp_path_selection_reason *reason)
565 {
566 const struct prefix *new_p;
567 struct attr *newattr, *existattr;
568 enum bgp_peer_sort new_sort;
569 enum bgp_peer_sort exist_sort;
570 uint32_t new_pref;
571 uint32_t exist_pref;
572 uint32_t new_med;
573 uint32_t exist_med;
574 uint32_t new_weight;
575 uint32_t exist_weight;
576 uint32_t newm, existm;
577 struct in_addr new_id;
578 struct in_addr exist_id;
579 int new_cluster;
580 int exist_cluster;
581 int internal_as_route;
582 int confed_as_route;
583 int ret = 0;
584 int igp_metric_ret = 0;
585 int peer_sort_ret = -1;
586 char new_buf[PATH_ADDPATH_STR_BUFFER];
587 char exist_buf[PATH_ADDPATH_STR_BUFFER];
588 uint32_t new_mm_seq;
589 uint32_t exist_mm_seq;
590 int nh_cmp;
591 esi_t *exist_esi;
592 esi_t *new_esi;
593 bool same_esi;
594 bool old_proxy;
595 bool new_proxy;
596 bool new_origin, exist_origin;
597 struct bgp_path_info *bpi_ultimate;
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 /* 3. Local route check. We prefer:
875 * - BGP_ROUTE_STATIC
876 * - BGP_ROUTE_AGGREGATE
877 * - BGP_ROUTE_REDISTRIBUTE
878 */
879 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
880 new->sub_type == BGP_ROUTE_IMPORTED);
881 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
882 exist->sub_type == BGP_ROUTE_IMPORTED);
883
884 if (new_origin && !exist_origin) {
885 *reason = bgp_path_selection_local_route;
886 if (debug)
887 zlog_debug(
888 "%s: %s wins over %s due to preferred BGP_ROUTE type",
889 pfx_buf, new_buf, exist_buf);
890 return 1;
891 }
892
893 if (!new_origin && exist_origin) {
894 *reason = bgp_path_selection_local_route;
895 if (debug)
896 zlog_debug(
897 "%s: %s loses to %s due to preferred BGP_ROUTE type",
898 pfx_buf, new_buf, exist_buf);
899 return 0;
900 }
901
902 /* Here if these are imported routes then get ultimate pi for
903 * path compare.
904 */
905 new = bgp_get_imported_bpi_ultimate(new);
906 exist = bgp_get_imported_bpi_ultimate(exist);
907 newattr = new->attr;
908 existattr = exist->attr;
909
910 /* 4. AS path length check. */
911 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
912 int exist_hops = aspath_count_hops(existattr->aspath);
913 int exist_confeds = aspath_count_confeds(existattr->aspath);
914
915 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
916 int aspath_hops;
917
918 aspath_hops = aspath_count_hops(newattr->aspath);
919 aspath_hops += aspath_count_confeds(newattr->aspath);
920
921 if (aspath_hops < (exist_hops + exist_confeds)) {
922 *reason = bgp_path_selection_confed_as_path;
923 if (debug)
924 zlog_debug(
925 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
926 pfx_buf, new_buf, exist_buf,
927 aspath_hops,
928 (exist_hops + exist_confeds));
929 return 1;
930 }
931
932 if (aspath_hops > (exist_hops + exist_confeds)) {
933 *reason = bgp_path_selection_confed_as_path;
934 if (debug)
935 zlog_debug(
936 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
937 pfx_buf, new_buf, exist_buf,
938 aspath_hops,
939 (exist_hops + exist_confeds));
940 return 0;
941 }
942 } else {
943 int newhops = aspath_count_hops(newattr->aspath);
944
945 if (newhops < exist_hops) {
946 *reason = bgp_path_selection_as_path;
947 if (debug)
948 zlog_debug(
949 "%s: %s wins over %s due to aspath hopcount %d < %d",
950 pfx_buf, new_buf, exist_buf,
951 newhops, exist_hops);
952 return 1;
953 }
954
955 if (newhops > exist_hops) {
956 *reason = bgp_path_selection_as_path;
957 if (debug)
958 zlog_debug(
959 "%s: %s loses to %s due to aspath hopcount %d > %d",
960 pfx_buf, new_buf, exist_buf,
961 newhops, exist_hops);
962 return 0;
963 }
964 }
965 }
966
967 /* 5. Origin check. */
968 if (newattr->origin < existattr->origin) {
969 *reason = bgp_path_selection_origin;
970 if (debug)
971 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
972 pfx_buf, new_buf, exist_buf,
973 bgp_origin_long_str[newattr->origin],
974 bgp_origin_long_str[existattr->origin]);
975 return 1;
976 }
977
978 if (newattr->origin > existattr->origin) {
979 *reason = bgp_path_selection_origin;
980 if (debug)
981 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
982 pfx_buf, new_buf, exist_buf,
983 bgp_origin_long_str[newattr->origin],
984 bgp_origin_long_str[existattr->origin]);
985 return 0;
986 }
987
988 /* 6. MED check. */
989 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
990 && aspath_count_hops(existattr->aspath) == 0);
991 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
992 && aspath_count_confeds(existattr->aspath) > 0
993 && aspath_count_hops(newattr->aspath) == 0
994 && aspath_count_hops(existattr->aspath) == 0);
995
996 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
997 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
998 || aspath_cmp_left(newattr->aspath, existattr->aspath)
999 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1000 || internal_as_route) {
1001 new_med = bgp_med_value(new->attr, bgp);
1002 exist_med = bgp_med_value(exist->attr, bgp);
1003
1004 if (new_med < exist_med) {
1005 *reason = bgp_path_selection_med;
1006 if (debug)
1007 zlog_debug(
1008 "%s: %s wins over %s due to MED %d < %d",
1009 pfx_buf, new_buf, exist_buf, new_med,
1010 exist_med);
1011 return 1;
1012 }
1013
1014 if (new_med > exist_med) {
1015 *reason = bgp_path_selection_med;
1016 if (debug)
1017 zlog_debug(
1018 "%s: %s loses to %s due to MED %d > %d",
1019 pfx_buf, new_buf, exist_buf, new_med,
1020 exist_med);
1021 return 0;
1022 }
1023 }
1024
1025 /* 7. Peer type check. */
1026 new_sort = new->peer->sort;
1027 exist_sort = exist->peer->sort;
1028
1029 if (new_sort == BGP_PEER_EBGP
1030 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1031 *reason = bgp_path_selection_peer;
1032 if (debug)
1033 zlog_debug(
1034 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1035 pfx_buf, new_buf, exist_buf);
1036 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1037 return 1;
1038 peer_sort_ret = 1;
1039 }
1040
1041 if (exist_sort == BGP_PEER_EBGP
1042 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1043 *reason = bgp_path_selection_peer;
1044 if (debug)
1045 zlog_debug(
1046 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1047 pfx_buf, new_buf, exist_buf);
1048 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1049 return 0;
1050 peer_sort_ret = 0;
1051 }
1052
1053 /* 8. IGP metric check. */
1054 newm = existm = 0;
1055
1056 if (new->extra)
1057 newm = new->extra->igpmetric;
1058 if (exist->extra)
1059 existm = exist->extra->igpmetric;
1060
1061 if (newm < existm) {
1062 if (debug && peer_sort_ret < 0)
1063 zlog_debug(
1064 "%s: %s wins over %s due to IGP metric %u < %u",
1065 pfx_buf, new_buf, exist_buf, newm, existm);
1066 igp_metric_ret = 1;
1067 }
1068
1069 if (newm > existm) {
1070 if (debug && peer_sort_ret < 0)
1071 zlog_debug(
1072 "%s: %s loses to %s due to IGP metric %u > %u",
1073 pfx_buf, new_buf, exist_buf, newm, existm);
1074 igp_metric_ret = 0;
1075 }
1076
1077 /* 9. Same IGP metric. Compare the cluster list length as
1078 representative of IGP hops metric. Rewrite the metric value
1079 pair (newm, existm) with the cluster list length. Prefer the
1080 path with smaller cluster list length. */
1081 if (newm == existm) {
1082 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
1083 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
1084 && (mpath_cfg == NULL
1085 || CHECK_FLAG(
1086 mpath_cfg->ibgp_flags,
1087 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
1088 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1089 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1090
1091 if (newm < existm) {
1092 if (debug && peer_sort_ret < 0)
1093 zlog_debug(
1094 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1095 pfx_buf, new_buf, exist_buf,
1096 newm, existm);
1097 igp_metric_ret = 1;
1098 }
1099
1100 if (newm > existm) {
1101 if (debug && peer_sort_ret < 0)
1102 zlog_debug(
1103 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1104 pfx_buf, new_buf, exist_buf,
1105 newm, existm);
1106 igp_metric_ret = 0;
1107 }
1108 }
1109 }
1110
1111 /* 10. confed-external vs. confed-internal */
1112 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1113 if (new_sort == BGP_PEER_CONFED
1114 && exist_sort == BGP_PEER_IBGP) {
1115 *reason = bgp_path_selection_confed;
1116 if (debug)
1117 zlog_debug(
1118 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1119 pfx_buf, new_buf, exist_buf);
1120 if (!CHECK_FLAG(bgp->flags,
1121 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_CONFED
1127 && new_sort == BGP_PEER_IBGP) {
1128 *reason = bgp_path_selection_confed;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags,
1134 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1135 return 0;
1136 peer_sort_ret = 0;
1137 }
1138 }
1139
1140 /* 11. Maximum path check. */
1141 if (newm == existm) {
1142 /* If one path has a label but the other does not, do not treat
1143 * them as equals for multipath
1144 */
1145 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1146 != (exist->extra
1147 && bgp_is_valid_label(&exist->extra->label[0]))) {
1148 if (debug)
1149 zlog_debug(
1150 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1151 pfx_buf, new_buf, exist_buf);
1152 } else if (CHECK_FLAG(bgp->flags,
1153 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1154
1155 /*
1156 * For the two paths, all comparison steps till IGP
1157 * metric
1158 * have succeeded - including AS_PATH hop count. Since
1159 * 'bgp
1160 * bestpath as-path multipath-relax' knob is on, we
1161 * don't need
1162 * an exact match of AS_PATH. Thus, mark the paths are
1163 * equal.
1164 * That will trigger both these paths to get into the
1165 * multipath
1166 * array.
1167 */
1168 *paths_eq = 1;
1169
1170 if (debug)
1171 zlog_debug(
1172 "%s: %s and %s are equal via multipath-relax",
1173 pfx_buf, new_buf, exist_buf);
1174 } else if (new->peer->sort == BGP_PEER_IBGP) {
1175 if (aspath_cmp(new->attr->aspath,
1176 exist->attr->aspath)) {
1177 *paths_eq = 1;
1178
1179 if (debug)
1180 zlog_debug(
1181 "%s: %s and %s are equal via matching aspaths",
1182 pfx_buf, new_buf, exist_buf);
1183 }
1184 } else if (new->peer->as == exist->peer->as) {
1185 *paths_eq = 1;
1186
1187 if (debug)
1188 zlog_debug(
1189 "%s: %s and %s are equal via same remote-as",
1190 pfx_buf, new_buf, exist_buf);
1191 }
1192 } else {
1193 /*
1194 * TODO: If unequal cost ibgp multipath is enabled we can
1195 * mark the paths as equal here instead of returning
1196 */
1197
1198 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1199 * if either step 7 or 10 (peer type checks) yielded a winner,
1200 * that result was returned immediately. Returning from step 10
1201 * ignored the return value computed in steps 8 and 9 (IGP
1202 * metric checks). In order to preserve that behavior, if
1203 * peer_sort_ret is set, return that rather than igp_metric_ret.
1204 */
1205 ret = peer_sort_ret;
1206 if (peer_sort_ret < 0) {
1207 ret = igp_metric_ret;
1208 if (debug) {
1209 if (ret == 1)
1210 zlog_debug(
1211 "%s: %s wins over %s after IGP metric comparison",
1212 pfx_buf, new_buf, exist_buf);
1213 else
1214 zlog_debug(
1215 "%s: %s loses to %s after IGP metric comparison",
1216 pfx_buf, new_buf, exist_buf);
1217 }
1218 *reason = bgp_path_selection_igp_metric;
1219 }
1220 return ret;
1221 }
1222
1223 /*
1224 * At this point, the decision whether to set *paths_eq = 1 has been
1225 * completed. If we deferred returning because of bestpath peer-type
1226 * relax configuration, return now.
1227 */
1228 if (peer_sort_ret >= 0)
1229 return peer_sort_ret;
1230
1231 /* 12. If both paths are external, prefer the path that was received
1232 first (the oldest one). This step minimizes route-flap, since a
1233 newer path won't displace an older one, even if it was the
1234 preferred route based on the additional decision criteria below. */
1235 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1236 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1237 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1238 *reason = bgp_path_selection_older;
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s wins over %s due to oldest external",
1242 pfx_buf, new_buf, exist_buf);
1243 return 1;
1244 }
1245
1246 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1247 *reason = bgp_path_selection_older;
1248 if (debug)
1249 zlog_debug(
1250 "%s: %s loses to %s due to oldest external",
1251 pfx_buf, new_buf, exist_buf);
1252 return 0;
1253 }
1254 }
1255
1256 /* 13. Router-ID comparison. */
1257 /* If one of the paths is "stale", the corresponding peer router-id will
1258 * be 0 and would always win over the other path. If originator id is
1259 * used for the comparison, it will decide which path is better.
1260 */
1261 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1262 new_id.s_addr = newattr->originator_id.s_addr;
1263 else
1264 new_id.s_addr = new->peer->remote_id.s_addr;
1265 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1266 exist_id.s_addr = existattr->originator_id.s_addr;
1267 else
1268 exist_id.s_addr = exist->peer->remote_id.s_addr;
1269
1270 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1271 *reason = bgp_path_selection_router_id;
1272 if (debug)
1273 zlog_debug(
1274 "%s: %s wins over %s due to Router-ID comparison",
1275 pfx_buf, new_buf, exist_buf);
1276 return 1;
1277 }
1278
1279 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1280 *reason = bgp_path_selection_router_id;
1281 if (debug)
1282 zlog_debug(
1283 "%s: %s loses to %s due to Router-ID comparison",
1284 pfx_buf, new_buf, exist_buf);
1285 return 0;
1286 }
1287
1288 /* 14. Cluster length comparison. */
1289 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1290 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1291
1292 if (new_cluster < exist_cluster) {
1293 *reason = bgp_path_selection_cluster_length;
1294 if (debug)
1295 zlog_debug(
1296 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1297 pfx_buf, new_buf, exist_buf, new_cluster,
1298 exist_cluster);
1299 return 1;
1300 }
1301
1302 if (new_cluster > exist_cluster) {
1303 *reason = bgp_path_selection_cluster_length;
1304 if (debug)
1305 zlog_debug(
1306 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1307 pfx_buf, new_buf, exist_buf, new_cluster,
1308 exist_cluster);
1309 return 0;
1310 }
1311
1312 /* 15. Neighbor address comparison. */
1313 /* Do this only if neither path is "stale" as stale paths do not have
1314 * valid peer information (as the connection may or may not be up).
1315 */
1316 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1317 *reason = bgp_path_selection_stale;
1318 if (debug)
1319 zlog_debug(
1320 "%s: %s wins over %s due to latter path being STALE",
1321 pfx_buf, new_buf, exist_buf);
1322 return 1;
1323 }
1324
1325 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1326 *reason = bgp_path_selection_stale;
1327 if (debug)
1328 zlog_debug(
1329 "%s: %s loses to %s due to former path being STALE",
1330 pfx_buf, new_buf, exist_buf);
1331 return 0;
1332 }
1333
1334 /* locally configured routes to advertise do not have su_remote */
1335 if (new->peer->su_remote == NULL) {
1336 *reason = bgp_path_selection_local_configured;
1337 return 0;
1338 }
1339 if (exist->peer->su_remote == NULL) {
1340 *reason = bgp_path_selection_local_configured;
1341 return 1;
1342 }
1343
1344 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1345
1346 if (ret == 1) {
1347 *reason = bgp_path_selection_neighbor_ip;
1348 if (debug)
1349 zlog_debug(
1350 "%s: %s loses to %s due to Neighor IP comparison",
1351 pfx_buf, new_buf, exist_buf);
1352 return 0;
1353 }
1354
1355 if (ret == -1) {
1356 *reason = bgp_path_selection_neighbor_ip;
1357 if (debug)
1358 zlog_debug(
1359 "%s: %s wins over %s due to Neighor IP comparison",
1360 pfx_buf, new_buf, exist_buf);
1361 return 1;
1362 }
1363
1364 *reason = bgp_path_selection_default;
1365 if (debug)
1366 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1367 pfx_buf, new_buf, exist_buf);
1368
1369 return 1;
1370 }
1371
1372
1373 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1374 struct bgp_path_info *exist, int *paths_eq)
1375 {
1376 enum bgp_path_selection_reason reason;
1377 char pfx_buf[PREFIX2STR_BUFFER];
1378
1379 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1380 AFI_L2VPN, SAFI_EVPN, &reason);
1381 }
1382
1383 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1384 * is preferred, or 0 if they are the same (usually will only occur if
1385 * multipath is enabled
1386 * This version is compatible with */
1387 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1388 struct bgp_path_info *exist, char *pfx_buf,
1389 afi_t afi, safi_t safi,
1390 enum bgp_path_selection_reason *reason)
1391 {
1392 int paths_eq;
1393 int ret;
1394 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1395 afi, safi, reason);
1396
1397 if (paths_eq)
1398 ret = 0;
1399 else {
1400 if (ret == 1)
1401 ret = -1;
1402 else
1403 ret = 1;
1404 }
1405 return ret;
1406 }
1407
1408 static enum filter_type bgp_input_filter(struct peer *peer,
1409 const struct prefix *p,
1410 struct attr *attr, afi_t afi,
1411 safi_t safi)
1412 {
1413 struct bgp_filter *filter;
1414 enum filter_type ret = FILTER_PERMIT;
1415
1416 filter = &peer->filter[afi][safi];
1417
1418 #define FILTER_EXIST_WARN(F, f, filter) \
1419 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1420 zlog_debug("%s: Could not find configured input %s-list %s!", \
1421 peer->host, #f, F##_IN_NAME(filter));
1422
1423 if (DISTRIBUTE_IN_NAME(filter)) {
1424 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1425
1426 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1427 == FILTER_DENY) {
1428 ret = FILTER_DENY;
1429 goto done;
1430 }
1431 }
1432
1433 if (PREFIX_LIST_IN_NAME(filter)) {
1434 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1435
1436 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1437 == PREFIX_DENY) {
1438 ret = FILTER_DENY;
1439 goto done;
1440 }
1441 }
1442
1443 if (FILTER_LIST_IN_NAME(filter)) {
1444 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1445
1446 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1447 == AS_FILTER_DENY) {
1448 ret = FILTER_DENY;
1449 goto done;
1450 }
1451 }
1452
1453 done:
1454 if (frrtrace_enabled(frr_bgp, input_filter)) {
1455 char pfxprint[PREFIX2STR_BUFFER];
1456
1457 prefix2str(p, pfxprint, sizeof(pfxprint));
1458 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1459 ret == FILTER_PERMIT ? "permit" : "deny");
1460 }
1461
1462 return ret;
1463 #undef FILTER_EXIST_WARN
1464 }
1465
1466 static enum filter_type bgp_output_filter(struct peer *peer,
1467 const struct prefix *p,
1468 struct attr *attr, afi_t afi,
1469 safi_t safi)
1470 {
1471 struct bgp_filter *filter;
1472 enum filter_type ret = FILTER_PERMIT;
1473
1474 filter = &peer->filter[afi][safi];
1475
1476 #define FILTER_EXIST_WARN(F, f, filter) \
1477 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1478 zlog_debug("%s: Could not find configured output %s-list %s!", \
1479 peer->host, #f, F##_OUT_NAME(filter));
1480
1481 if (DISTRIBUTE_OUT_NAME(filter)) {
1482 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1483
1484 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1485 == FILTER_DENY) {
1486 ret = FILTER_DENY;
1487 goto done;
1488 }
1489 }
1490
1491 if (PREFIX_LIST_OUT_NAME(filter)) {
1492 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1493
1494 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1495 == PREFIX_DENY) {
1496 ret = FILTER_DENY;
1497 goto done;
1498 }
1499 }
1500
1501 if (FILTER_LIST_OUT_NAME(filter)) {
1502 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1503
1504 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1505 == AS_FILTER_DENY) {
1506 ret = FILTER_DENY;
1507 goto done;
1508 }
1509 }
1510
1511 if (frrtrace_enabled(frr_bgp, output_filter)) {
1512 char pfxprint[PREFIX2STR_BUFFER];
1513
1514 prefix2str(p, pfxprint, sizeof(pfxprint));
1515 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1516 ret == FILTER_PERMIT ? "permit" : "deny");
1517 }
1518
1519 done:
1520 return ret;
1521 #undef FILTER_EXIST_WARN
1522 }
1523
1524 /* If community attribute includes no_export then return 1. */
1525 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1526 {
1527 if (bgp_attr_get_community(attr)) {
1528 /* NO_ADVERTISE check. */
1529 if (community_include(bgp_attr_get_community(attr),
1530 COMMUNITY_NO_ADVERTISE))
1531 return true;
1532
1533 /* NO_EXPORT check. */
1534 if (peer->sort == BGP_PEER_EBGP &&
1535 community_include(bgp_attr_get_community(attr),
1536 COMMUNITY_NO_EXPORT))
1537 return true;
1538
1539 /* NO_EXPORT_SUBCONFED check. */
1540 if (peer->sort == BGP_PEER_EBGP
1541 || peer->sort == BGP_PEER_CONFED)
1542 if (community_include(bgp_attr_get_community(attr),
1543 COMMUNITY_NO_EXPORT_SUBCONFED))
1544 return true;
1545 }
1546 return false;
1547 }
1548
1549 /* Route reflection loop check. */
1550 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1551 {
1552 struct in_addr cluster_id;
1553 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1554
1555 if (cluster) {
1556 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1557 cluster_id = peer->bgp->cluster_id;
1558 else
1559 cluster_id = peer->bgp->router_id;
1560
1561 if (cluster_loop_check(cluster, cluster_id))
1562 return true;
1563 }
1564 return false;
1565 }
1566
1567 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1568 struct attr *attr, afi_t afi, safi_t safi,
1569 const char *rmap_name, mpls_label_t *label,
1570 uint32_t num_labels, struct bgp_dest *dest)
1571 {
1572 struct bgp_filter *filter;
1573 struct bgp_path_info rmap_path = { 0 };
1574 struct bgp_path_info_extra extra = { 0 };
1575 route_map_result_t ret;
1576 struct route_map *rmap = NULL;
1577
1578 filter = &peer->filter[afi][safi];
1579
1580 /* Apply default weight value. */
1581 if (peer->weight[afi][safi])
1582 attr->weight = peer->weight[afi][safi];
1583
1584 if (rmap_name) {
1585 rmap = route_map_lookup_by_name(rmap_name);
1586
1587 if (rmap == NULL)
1588 return RMAP_DENY;
1589 } else {
1590 if (ROUTE_MAP_IN_NAME(filter)) {
1591 rmap = ROUTE_MAP_IN(filter);
1592
1593 if (rmap == NULL)
1594 return RMAP_DENY;
1595 }
1596 }
1597
1598 /* Route map apply. */
1599 if (rmap) {
1600 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1601 /* Duplicate current value to new structure for modification. */
1602 rmap_path.peer = peer;
1603 rmap_path.attr = attr;
1604 rmap_path.extra = &extra;
1605 rmap_path.net = dest;
1606
1607 extra.num_labels = num_labels;
1608 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1609 memcpy(extra.label, label,
1610 num_labels * sizeof(mpls_label_t));
1611
1612 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1613
1614 /* Apply BGP route map to the attribute. */
1615 ret = route_map_apply(rmap, p, &rmap_path);
1616
1617 peer->rmap_type = 0;
1618
1619 if (ret == RMAP_DENYMATCH)
1620 return RMAP_DENY;
1621 }
1622 return RMAP_PERMIT;
1623 }
1624
1625 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1626 struct attr *attr, afi_t afi, safi_t safi,
1627 const char *rmap_name)
1628 {
1629 struct bgp_path_info rmap_path;
1630 route_map_result_t ret;
1631 struct route_map *rmap = NULL;
1632 uint8_t rmap_type;
1633
1634 /*
1635 * So if we get to this point and have no rmap_name
1636 * we want to just show the output as it currently
1637 * exists.
1638 */
1639 if (!rmap_name)
1640 return RMAP_PERMIT;
1641
1642 /* Apply default weight value. */
1643 if (peer->weight[afi][safi])
1644 attr->weight = peer->weight[afi][safi];
1645
1646 rmap = route_map_lookup_by_name(rmap_name);
1647
1648 /*
1649 * If we have a route map name and we do not find
1650 * the routemap that means we have an implicit
1651 * deny.
1652 */
1653 if (rmap == NULL)
1654 return RMAP_DENY;
1655
1656 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1657 /* Route map apply. */
1658 /* Duplicate current value to new structure for modification. */
1659 rmap_path.peer = peer;
1660 rmap_path.attr = attr;
1661
1662 rmap_type = peer->rmap_type;
1663 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1664
1665 /* Apply BGP route map to the attribute. */
1666 ret = route_map_apply(rmap, p, &rmap_path);
1667
1668 peer->rmap_type = rmap_type;
1669
1670 if (ret == RMAP_DENYMATCH)
1671 /*
1672 * caller has multiple error paths with bgp_attr_flush()
1673 */
1674 return RMAP_DENY;
1675
1676 return RMAP_PERMIT;
1677 }
1678
1679 /* If this is an EBGP peer with remove-private-AS */
1680 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1681 struct peer *peer, struct attr *attr)
1682 {
1683 if (peer->sort == BGP_PEER_EBGP
1684 && (peer_af_flag_check(peer, afi, safi,
1685 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1686 || peer_af_flag_check(peer, afi, safi,
1687 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1688 || peer_af_flag_check(peer, afi, safi,
1689 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1690 || peer_af_flag_check(peer, afi, safi,
1691 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1692 // Take action on the entire aspath
1693 if (peer_af_flag_check(peer, afi, safi,
1694 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1695 || peer_af_flag_check(peer, afi, safi,
1696 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1697 if (peer_af_flag_check(
1698 peer, afi, safi,
1699 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1700 attr->aspath = aspath_replace_private_asns(
1701 attr->aspath, bgp->as, peer->as);
1702
1703 /*
1704 * Even if the aspath consists of just private ASNs we
1705 * need to walk the AS-Path to maintain all instances
1706 * of the peer's ASN to break possible loops.
1707 */
1708 else
1709 attr->aspath = aspath_remove_private_asns(
1710 attr->aspath, peer->as);
1711 }
1712
1713 // 'all' was not specified so the entire aspath must be private
1714 // ASNs
1715 // for us to do anything
1716 else if (aspath_private_as_check(attr->aspath)) {
1717 if (peer_af_flag_check(
1718 peer, afi, safi,
1719 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1720 attr->aspath = aspath_replace_private_asns(
1721 attr->aspath, bgp->as, peer->as);
1722 else
1723 /*
1724 * Walk the aspath to retain any instances of
1725 * the peer_asn
1726 */
1727 attr->aspath = aspath_remove_private_asns(
1728 attr->aspath, peer->as);
1729 }
1730 }
1731 }
1732
1733 /* If this is an EBGP peer with as-override */
1734 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1735 struct peer *peer, struct attr *attr)
1736 {
1737 if (peer->sort == BGP_PEER_EBGP
1738 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1739 if (aspath_single_asn_check(attr->aspath, peer->as))
1740 attr->aspath = aspath_replace_specific_asn(
1741 attr->aspath, peer->as, bgp->as);
1742 }
1743 }
1744
1745 void bgp_attr_add_llgr_community(struct attr *attr)
1746 {
1747 struct community *old;
1748 struct community *new;
1749 struct community *merge;
1750 struct community *llgr;
1751
1752 old = bgp_attr_get_community(attr);
1753 llgr = community_str2com("llgr-stale");
1754
1755 assert(llgr);
1756
1757 if (old) {
1758 merge = community_merge(community_dup(old), llgr);
1759
1760 if (old->refcnt == 0)
1761 community_free(&old);
1762
1763 new = community_uniq_sort(merge);
1764 community_free(&merge);
1765 } else {
1766 new = community_dup(llgr);
1767 }
1768
1769 community_free(&llgr);
1770
1771 bgp_attr_set_community(attr, new);
1772 }
1773
1774 void bgp_attr_add_gshut_community(struct attr *attr)
1775 {
1776 struct community *old;
1777 struct community *new;
1778 struct community *merge;
1779 struct community *gshut;
1780
1781 old = bgp_attr_get_community(attr);
1782 gshut = community_str2com("graceful-shutdown");
1783
1784 assert(gshut);
1785
1786 if (old) {
1787 merge = community_merge(community_dup(old), gshut);
1788
1789 if (old->refcnt == 0)
1790 community_free(&old);
1791
1792 new = community_uniq_sort(merge);
1793 community_free(&merge);
1794 } else {
1795 new = community_dup(gshut);
1796 }
1797
1798 community_free(&gshut);
1799 bgp_attr_set_community(attr, new);
1800
1801 /* When we add the graceful-shutdown community we must also
1802 * lower the local-preference */
1803 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1804 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1805 }
1806
1807
1808 /* Notify BGP Conditional advertisement scanner process. */
1809 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1810 {
1811 struct peer *peer = SUBGRP_PEER(subgrp);
1812 afi_t afi = SUBGRP_AFI(subgrp);
1813 safi_t safi = SUBGRP_SAFI(subgrp);
1814 struct bgp_filter *filter = &peer->filter[afi][safi];
1815
1816 if (!ADVERTISE_MAP_NAME(filter))
1817 return;
1818
1819 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1820 return;
1821
1822 peer->advmap_table_change = true;
1823 }
1824
1825
1826 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1827 {
1828 if (family == AF_INET) {
1829 attr->nexthop.s_addr = INADDR_ANY;
1830 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1831 }
1832 if (family == AF_INET6)
1833 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1834 if (family == AF_EVPN)
1835 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1836 }
1837
1838 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1839 struct update_subgroup *subgrp,
1840 const struct prefix *p, struct attr *attr,
1841 struct attr *post_attr)
1842 {
1843 struct bgp_filter *filter;
1844 struct peer *from;
1845 struct peer *peer;
1846 struct peer *onlypeer;
1847 struct bgp *bgp;
1848 struct attr *piattr;
1849 route_map_result_t ret;
1850 int transparent;
1851 int reflect;
1852 afi_t afi;
1853 safi_t safi;
1854 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1855 bool nh_reset = false;
1856 uint64_t cum_bw;
1857
1858 if (DISABLE_BGP_ANNOUNCE)
1859 return false;
1860
1861 afi = SUBGRP_AFI(subgrp);
1862 safi = SUBGRP_SAFI(subgrp);
1863 peer = SUBGRP_PEER(subgrp);
1864 onlypeer = NULL;
1865 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1866 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1867
1868 from = pi->peer;
1869 filter = &peer->filter[afi][safi];
1870 bgp = SUBGRP_INST(subgrp);
1871 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1872 : pi->attr;
1873
1874 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
1875 peer->pmax_out[afi][safi] != 0 &&
1876 subgrp->pscount >= peer->pmax_out[afi][safi]) {
1877 if (BGP_DEBUG(update, UPDATE_OUT) ||
1878 BGP_DEBUG(update, UPDATE_PREFIX)) {
1879 zlog_debug("%s reached maximum prefix to be send (%u)",
1880 peer->host, peer->pmax_out[afi][safi]);
1881 }
1882 return false;
1883 }
1884
1885 #ifdef ENABLE_BGP_VNC
1886 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1887 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1888 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1889
1890 /*
1891 * direct and direct_ext type routes originate internally even
1892 * though they can have peer pointers that reference other
1893 * systems
1894 */
1895 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1896 __func__, p);
1897 samepeer_safe = 1;
1898 }
1899 #endif
1900
1901 if (((afi == AFI_IP) || (afi == AFI_IP6))
1902 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1903 && (pi->type == ZEBRA_ROUTE_BGP)
1904 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1905
1906 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1907
1908 samepeer_safe = 1;
1909 }
1910
1911 /* With addpath we may be asked to TX all kinds of paths so make sure
1912 * pi is valid */
1913 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1914 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1915 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1916 return false;
1917 }
1918
1919 /* If this is not the bestpath then check to see if there is an enabled
1920 * addpath
1921 * feature that requires us to advertise it */
1922 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1923 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1924 return false;
1925 }
1926 }
1927
1928 /* Aggregate-address suppress check. */
1929 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1930 return false;
1931
1932 /*
1933 * If we are doing VRF 2 VRF leaking via the import
1934 * statement, we want to prevent the route going
1935 * off box as that the RT and RD created are localy
1936 * significant and globaly useless.
1937 */
1938 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1939 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1940 return false;
1941
1942 /* If it's labeled safi, make sure the route has a valid label. */
1943 if (safi == SAFI_LABELED_UNICAST) {
1944 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1945 if (!bgp_is_valid_label(&label)) {
1946 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1947 zlog_debug("u%" PRIu64 ":s%" PRIu64
1948 " %pFX is filtered - no label (%p)",
1949 subgrp->update_group->id, subgrp->id,
1950 p, &label);
1951 return false;
1952 }
1953 }
1954
1955 /* Do not send back route to sender. */
1956 if (onlypeer && from == onlypeer) {
1957 return false;
1958 }
1959
1960 /* Do not send the default route in the BGP table if the neighbor is
1961 * configured for default-originate */
1962 if (CHECK_FLAG(peer->af_flags[afi][safi],
1963 PEER_FLAG_DEFAULT_ORIGINATE)) {
1964 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1965 return false;
1966 else if (p->family == AF_INET6 && p->prefixlen == 0)
1967 return false;
1968 }
1969
1970 /* Transparency check. */
1971 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1972 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1973 transparent = 1;
1974 else
1975 transparent = 0;
1976
1977 /* If community is not disabled check the no-export and local. */
1978 if (!transparent && bgp_community_filter(peer, piattr)) {
1979 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1980 zlog_debug("%s: community filter check fail for %pFX",
1981 __func__, p);
1982 return false;
1983 }
1984
1985 /* If the attribute has originator-id and it is same as remote
1986 peer's id. */
1987 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1988 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1989 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1990 zlog_debug(
1991 "%s [Update:SEND] %pFX originator-id is same as remote router-id",
1992 onlypeer->host, p);
1993 return false;
1994 }
1995
1996 /* ORF prefix-list filter check */
1997 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1998 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1999 || CHECK_FLAG(peer->af_cap[afi][safi],
2000 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2001 if (peer->orf_plist[afi][safi]) {
2002 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2003 == PREFIX_DENY) {
2004 if (bgp_debug_update(NULL, p,
2005 subgrp->update_group, 0))
2006 zlog_debug(
2007 "%s [Update:SEND] %pFX is filtered via ORF",
2008 peer->host, p);
2009 return false;
2010 }
2011 }
2012
2013 /* Output filter check. */
2014 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2015 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2016 zlog_debug("%s [Update:SEND] %pFX is filtered",
2017 peer->host, p);
2018 return false;
2019 }
2020
2021 /* AS path loop check. */
2022 if (onlypeer && onlypeer->as_path_loop_detection
2023 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2024 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2025 zlog_debug(
2026 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2027 onlypeer->host, onlypeer->as);
2028 return false;
2029 }
2030
2031 /* If we're a CONFED we need to loop check the CONFED ID too */
2032 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2033 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
2034 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2035 zlog_debug(
2036 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
2037 peer->host, bgp->confed_id);
2038 return false;
2039 }
2040 }
2041
2042 /* Route-Reflect check. */
2043 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2044 reflect = 1;
2045 else
2046 reflect = 0;
2047
2048 /* IBGP reflection check. */
2049 if (reflect && !samepeer_safe) {
2050 /* A route from a Client peer. */
2051 if (CHECK_FLAG(from->af_flags[afi][safi],
2052 PEER_FLAG_REFLECTOR_CLIENT)) {
2053 /* Reflect to all the Non-Client peers and also to the
2054 Client peers other than the originator. Originator
2055 check
2056 is already done. So there is noting to do. */
2057 /* no bgp client-to-client reflection check. */
2058 if (CHECK_FLAG(bgp->flags,
2059 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2060 if (CHECK_FLAG(peer->af_flags[afi][safi],
2061 PEER_FLAG_REFLECTOR_CLIENT))
2062 return false;
2063 } else {
2064 /* A route from a Non-client peer. Reflect to all other
2065 clients. */
2066 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2067 PEER_FLAG_REFLECTOR_CLIENT))
2068 return false;
2069 }
2070 }
2071
2072 /* For modify attribute, copy it to temporary structure.
2073 * post_attr comes from BGP conditional advertisements, where
2074 * attributes are already processed by advertise-map route-map,
2075 * and this needs to be saved instead of overwriting from the
2076 * path attributes.
2077 */
2078 if (post_attr)
2079 *attr = *post_attr;
2080 else
2081 *attr = *piattr;
2082
2083 /* If local-preference is not set. */
2084 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2085 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2086 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2087 attr->local_pref = bgp->default_local_pref;
2088 }
2089
2090 /* If originator-id is not set and the route is to be reflected,
2091 set the originator id */
2092 if (reflect
2093 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2094 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2095 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2096 }
2097
2098 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2099 */
2100 if (peer->sort == BGP_PEER_EBGP
2101 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2102 if (from != bgp->peer_self && !transparent
2103 && !CHECK_FLAG(peer->af_flags[afi][safi],
2104 PEER_FLAG_MED_UNCHANGED))
2105 attr->flag &=
2106 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2107 }
2108
2109 /* Since the nexthop attribute can vary per peer, it is not explicitly
2110 * set
2111 * in announce check, only certain flags and length (or number of
2112 * nexthops
2113 * -- for IPv6/MP_REACH) are set here in order to guide the update
2114 * formation
2115 * code in setting the nexthop(s) on a per peer basis in
2116 * reformat_peer().
2117 * Typically, the source nexthop in the attribute is preserved but in
2118 * the
2119 * scenarios where we know it will always be overwritten, we reset the
2120 * nexthop to "0" in an attempt to achieve better Update packing. An
2121 * example of this is when a prefix from each of 2 IBGP peers needs to
2122 * be
2123 * announced to an EBGP peer (and they have the same attributes barring
2124 * their nexthop).
2125 */
2126 if (reflect)
2127 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2128
2129 #define NEXTHOP_IS_V6 \
2130 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2131 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2132 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2133 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2134
2135 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2136 * if
2137 * the peer (group) is configured to receive link-local nexthop
2138 * unchanged
2139 * and it is available in the prefix OR we're not reflecting the route,
2140 * link-local nexthop address is valid and
2141 * the peer (group) to whom we're going to announce is on a shared
2142 * network
2143 * and this is either a self-originated route or the peer is EBGP.
2144 * By checking if nexthop LL address is valid we are sure that
2145 * we do not announce LL address as `::`.
2146 */
2147 if (NEXTHOP_IS_V6) {
2148 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2149 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2150 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2151 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2152 || (!reflect && !transparent
2153 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2154 && peer->shared_network
2155 && (from == bgp->peer_self
2156 || peer->sort == BGP_PEER_EBGP))) {
2157 attr->mp_nexthop_len =
2158 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2159 }
2160
2161 /* Clear off link-local nexthop in source, whenever it is not
2162 * needed to
2163 * ensure more prefixes share the same attribute for
2164 * announcement.
2165 */
2166 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2167 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2168 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2169 }
2170
2171 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2172 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2173
2174 /* Route map & unsuppress-map apply. */
2175 if (!post_attr &&
2176 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2177 struct bgp_path_info rmap_path = {0};
2178 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2179 struct attr dummy_attr = {0};
2180
2181 /* Fill temp path_info */
2182 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2183 pi, peer, attr);
2184
2185 /* don't confuse inbound and outbound setting */
2186 RESET_FLAG(attr->rmap_change_flags);
2187
2188 /*
2189 * The route reflector is not allowed to modify the attributes
2190 * of the reflected IBGP routes unless explicitly allowed.
2191 */
2192 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2193 && !CHECK_FLAG(bgp->flags,
2194 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2195 dummy_attr = *attr;
2196 rmap_path.attr = &dummy_attr;
2197 }
2198
2199 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2200
2201 if (bgp_path_suppressed(pi))
2202 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2203 &rmap_path);
2204 else
2205 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2206 &rmap_path);
2207
2208 bgp_attr_flush(&dummy_attr);
2209 peer->rmap_type = 0;
2210
2211 if (ret == RMAP_DENYMATCH) {
2212 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2213 zlog_debug(
2214 "%s [Update:SEND] %pFX is filtered by route-map '%s'",
2215 peer->host, p,
2216 ROUTE_MAP_OUT_NAME(filter));
2217
2218 return false;
2219 }
2220 }
2221
2222 /* RFC 8212 to prevent route leaks.
2223 * This specification intends to improve this situation by requiring the
2224 * explicit configuration of both BGP Import and Export Policies for any
2225 * External BGP (EBGP) session such as customers, peers, or
2226 * confederation boundaries for all enabled address families. Through
2227 * codification of the aforementioned requirement, operators will
2228 * benefit from consistent behavior across different BGP
2229 * implementations.
2230 */
2231 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2232 if (!bgp_outbound_policy_exists(peer, filter)) {
2233 if (monotime_since(&bgp->ebgprequirespolicywarning,
2234 NULL) > FIFTEENMINUTE2USEC ||
2235 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2236 zlog_warn(
2237 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2238 monotime(&bgp->ebgprequirespolicywarning);
2239 }
2240 return false;
2241 }
2242
2243 /* draft-ietf-idr-deprecate-as-set-confed-set
2244 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2245 * Eventually, This document (if approved) updates RFC 4271
2246 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2247 * and obsoletes RFC 6472.
2248 */
2249 if (peer->bgp->reject_as_sets)
2250 if (aspath_check_as_sets(attr->aspath))
2251 return false;
2252
2253 /* Codification of AS 0 Processing */
2254 if (aspath_check_as_zero(attr->aspath))
2255 return false;
2256
2257 if (bgp_in_graceful_shutdown(bgp)) {
2258 if (peer->sort == BGP_PEER_IBGP
2259 || peer->sort == BGP_PEER_CONFED) {
2260 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2261 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2262 } else {
2263 bgp_attr_add_gshut_community(attr);
2264 }
2265 }
2266
2267 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2268 * Capability" to a neighbor MUST perform the following upon receiving
2269 * a route from that neighbor with the "LLGR_STALE" community, or upon
2270 * attaching the "LLGR_STALE" community itself per Section 4.2:
2271 *
2272 * The route SHOULD NOT be advertised to any neighbor from which the
2273 * Long-lived Graceful Restart Capability has not been received.
2274 */
2275 if (bgp_attr_get_community(attr) &&
2276 community_include(bgp_attr_get_community(attr),
2277 COMMUNITY_LLGR_STALE) &&
2278 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2279 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2280 return false;
2281
2282 /* After route-map has been applied, we check to see if the nexthop to
2283 * be carried in the attribute (that is used for the announcement) can
2284 * be cleared off or not. We do this in all cases where we would be
2285 * setting the nexthop to "ourselves". For IPv6, we only need to
2286 * consider
2287 * the global nexthop here; the link-local nexthop would have been
2288 * cleared
2289 * already, and if not, it is required by the update formation code.
2290 * Also see earlier comments in this function.
2291 */
2292 /*
2293 * If route-map has performed some operation on the nexthop or the peer
2294 * configuration says to pass it unchanged, we cannot reset the nexthop
2295 * here, so only attempt to do it if these aren't true. Note that the
2296 * route-map handler itself might have cleared the nexthop, if for
2297 * example,
2298 * it is configured as 'peer-address'.
2299 */
2300 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2301 piattr->rmap_change_flags)
2302 && !transparent
2303 && !CHECK_FLAG(peer->af_flags[afi][safi],
2304 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2305 /* We can reset the nexthop, if setting (or forcing) it to
2306 * 'self' */
2307 if (CHECK_FLAG(peer->af_flags[afi][safi],
2308 PEER_FLAG_NEXTHOP_SELF)
2309 || CHECK_FLAG(peer->af_flags[afi][safi],
2310 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2311 if (!reflect
2312 || CHECK_FLAG(peer->af_flags[afi][safi],
2313 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2314 subgroup_announce_reset_nhop(
2315 (peer_cap_enhe(peer, afi, safi)
2316 ? AF_INET6
2317 : p->family),
2318 attr);
2319 nh_reset = true;
2320 }
2321 } else if (peer->sort == BGP_PEER_EBGP) {
2322 /* Can also reset the nexthop if announcing to EBGP, but
2323 * only if
2324 * no peer in the subgroup is on a shared subnet.
2325 * Note: 3rd party nexthop currently implemented for
2326 * IPv4 only.
2327 */
2328 if ((p->family == AF_INET) &&
2329 (!bgp_subgrp_multiaccess_check_v4(
2330 piattr->nexthop,
2331 subgrp, from))) {
2332 subgroup_announce_reset_nhop(
2333 (peer_cap_enhe(peer, afi, safi)
2334 ? AF_INET6
2335 : p->family),
2336 attr);
2337 nh_reset = true;
2338 }
2339
2340 if ((p->family == AF_INET6) &&
2341 (!bgp_subgrp_multiaccess_check_v6(
2342 piattr->mp_nexthop_global,
2343 subgrp, from))) {
2344 subgroup_announce_reset_nhop(
2345 (peer_cap_enhe(peer, afi, safi)
2346 ? AF_INET6
2347 : p->family),
2348 attr);
2349 nh_reset = true;
2350 }
2351
2352
2353
2354 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2355 /*
2356 * This flag is used for leaked vpn-vrf routes
2357 */
2358 int family = p->family;
2359
2360 if (peer_cap_enhe(peer, afi, safi))
2361 family = AF_INET6;
2362
2363 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2364 zlog_debug(
2365 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2366 __func__, family2str(family));
2367 subgroup_announce_reset_nhop(family, attr);
2368 nh_reset = true;
2369 }
2370 }
2371
2372 /* If IPv6/MP and nexthop does not have any override and happens
2373 * to
2374 * be a link-local address, reset it so that we don't pass along
2375 * the
2376 * source's link-local IPv6 address to recipients who may not be
2377 * on
2378 * the same interface.
2379 */
2380 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2381 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2382 subgroup_announce_reset_nhop(AF_INET6, attr);
2383 nh_reset = true;
2384 }
2385 }
2386
2387 /*
2388 * When the next hop is set to ourselves, if all multipaths have
2389 * link-bandwidth announce the cumulative bandwidth as that makes
2390 * the most sense. However, don't modify if the link-bandwidth has
2391 * been explicitly set by user policy.
2392 */
2393 if (nh_reset &&
2394 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2395 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2396 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2397 bgp_attr_set_ecommunity(
2398 attr,
2399 ecommunity_replace_linkbw(
2400 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2401 CHECK_FLAG(
2402 peer->flags,
2403 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2404
2405 return true;
2406 }
2407
2408 static void bgp_route_select_timer_expire(struct thread *thread)
2409 {
2410 struct afi_safi_info *info;
2411 afi_t afi;
2412 safi_t safi;
2413 struct bgp *bgp;
2414
2415 info = THREAD_ARG(thread);
2416 afi = info->afi;
2417 safi = info->safi;
2418 bgp = info->bgp;
2419
2420 if (BGP_DEBUG(update, UPDATE_OUT))
2421 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2422 safi);
2423
2424 bgp->gr_info[afi][safi].t_route_select = NULL;
2425
2426 XFREE(MTYPE_TMP, info);
2427
2428 /* Best path selection */
2429 bgp_best_path_select_defer(bgp, afi, safi);
2430 }
2431
2432 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2433 struct bgp_maxpaths_cfg *mpath_cfg,
2434 struct bgp_path_info_pair *result, afi_t afi,
2435 safi_t safi)
2436 {
2437 struct bgp_path_info *new_select;
2438 struct bgp_path_info *old_select;
2439 struct bgp_path_info *pi;
2440 struct bgp_path_info *pi1;
2441 struct bgp_path_info *pi2;
2442 struct bgp_path_info *nextpi = NULL;
2443 int paths_eq, do_mpath, debug;
2444 struct list mp_list;
2445 char pfx_buf[PREFIX2STR_BUFFER];
2446 char path_buf[PATH_ADDPATH_STR_BUFFER];
2447
2448 bgp_mp_list_init(&mp_list);
2449 do_mpath =
2450 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2451
2452 debug = bgp_debug_bestpath(dest);
2453
2454 if (debug)
2455 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2456
2457 dest->reason = bgp_path_selection_none;
2458 /* bgp deterministic-med */
2459 new_select = NULL;
2460 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2461
2462 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2463 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2464 pi1 = pi1->next)
2465 bgp_path_info_unset_flag(dest, pi1,
2466 BGP_PATH_DMED_SELECTED);
2467
2468 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2469 pi1 = pi1->next) {
2470 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2471 continue;
2472 if (BGP_PATH_HOLDDOWN(pi1))
2473 continue;
2474 if (pi1->peer != bgp->peer_self)
2475 if (!peer_established(pi1->peer))
2476 continue;
2477
2478 new_select = pi1;
2479 if (pi1->next) {
2480 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2481 if (CHECK_FLAG(pi2->flags,
2482 BGP_PATH_DMED_CHECK))
2483 continue;
2484 if (BGP_PATH_HOLDDOWN(pi2))
2485 continue;
2486 if (pi2->peer != bgp->peer_self
2487 && !CHECK_FLAG(
2488 pi2->peer->sflags,
2489 PEER_STATUS_NSF_WAIT))
2490 if (pi2->peer->status
2491 != Established)
2492 continue;
2493
2494 if (!aspath_cmp_left(pi1->attr->aspath,
2495 pi2->attr->aspath)
2496 && !aspath_cmp_left_confed(
2497 pi1->attr->aspath,
2498 pi2->attr->aspath))
2499 continue;
2500
2501 if (bgp_path_info_cmp(
2502 bgp, pi2, new_select,
2503 &paths_eq, mpath_cfg, debug,
2504 pfx_buf, afi, safi,
2505 &dest->reason)) {
2506 bgp_path_info_unset_flag(
2507 dest, new_select,
2508 BGP_PATH_DMED_SELECTED);
2509 new_select = pi2;
2510 }
2511
2512 bgp_path_info_set_flag(
2513 dest, pi2, BGP_PATH_DMED_CHECK);
2514 }
2515 }
2516 bgp_path_info_set_flag(dest, new_select,
2517 BGP_PATH_DMED_CHECK);
2518 bgp_path_info_set_flag(dest, new_select,
2519 BGP_PATH_DMED_SELECTED);
2520
2521 if (debug) {
2522 bgp_path_info_path_with_addpath_rx_str(
2523 new_select, path_buf, sizeof(path_buf));
2524 zlog_debug(
2525 "%pBD(%s): %s is the bestpath from AS %u",
2526 dest, bgp->name_pretty, path_buf,
2527 aspath_get_first_as(
2528 new_select->attr->aspath));
2529 }
2530 }
2531 }
2532
2533 /* Check old selected route and new selected route. */
2534 old_select = NULL;
2535 new_select = NULL;
2536 for (pi = bgp_dest_get_bgp_path_info(dest);
2537 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2538 enum bgp_path_selection_reason reason;
2539
2540 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2541 old_select = pi;
2542
2543 if (BGP_PATH_HOLDDOWN(pi)) {
2544 /* reap REMOVED routes, if needs be
2545 * selected route must stay for a while longer though
2546 */
2547 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2548 && (pi != old_select))
2549 bgp_path_info_reap(dest, pi);
2550
2551 if (debug)
2552 zlog_debug("%s: pi %p in holddown", __func__,
2553 pi);
2554
2555 continue;
2556 }
2557
2558 if (pi->peer && pi->peer != bgp->peer_self
2559 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2560 if (!peer_established(pi->peer)) {
2561
2562 if (debug)
2563 zlog_debug(
2564 "%s: pi %p non self peer %s not estab state",
2565 __func__, pi, pi->peer->host);
2566
2567 continue;
2568 }
2569
2570 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2571 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2572 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2573 if (debug)
2574 zlog_debug("%s: pi %p dmed", __func__, pi);
2575 continue;
2576 }
2577
2578 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2579
2580 reason = dest->reason;
2581 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2582 debug, pfx_buf, afi, safi,
2583 &dest->reason)) {
2584 if (new_select == NULL &&
2585 reason != bgp_path_selection_none)
2586 dest->reason = reason;
2587 new_select = pi;
2588 }
2589 }
2590
2591 /* Now that we know which path is the bestpath see if any of the other
2592 * paths
2593 * qualify as multipaths
2594 */
2595 if (debug) {
2596 if (new_select)
2597 bgp_path_info_path_with_addpath_rx_str(
2598 new_select, path_buf, sizeof(path_buf));
2599 else
2600 snprintf(path_buf, sizeof(path_buf), "NONE");
2601 zlog_debug(
2602 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2603 dest, bgp->name_pretty, path_buf,
2604 old_select ? old_select->peer->host : "NONE");
2605 }
2606
2607 if (do_mpath && new_select) {
2608 for (pi = bgp_dest_get_bgp_path_info(dest);
2609 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2610
2611 if (debug)
2612 bgp_path_info_path_with_addpath_rx_str(
2613 pi, path_buf, sizeof(path_buf));
2614
2615 if (pi == new_select) {
2616 if (debug)
2617 zlog_debug(
2618 "%pBD(%s): %s is the bestpath, add to the multipath list",
2619 dest, bgp->name_pretty,
2620 path_buf);
2621 bgp_mp_list_add(&mp_list, pi);
2622 continue;
2623 }
2624
2625 if (BGP_PATH_HOLDDOWN(pi))
2626 continue;
2627
2628 if (pi->peer && pi->peer != bgp->peer_self
2629 && !CHECK_FLAG(pi->peer->sflags,
2630 PEER_STATUS_NSF_WAIT))
2631 if (!peer_established(pi->peer))
2632 continue;
2633
2634 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2635 if (debug)
2636 zlog_debug(
2637 "%pBD: %s has the same nexthop as the bestpath, skip it",
2638 dest, path_buf);
2639 continue;
2640 }
2641
2642 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2643 mpath_cfg, debug, pfx_buf, afi, safi,
2644 &dest->reason);
2645
2646 if (paths_eq) {
2647 if (debug)
2648 zlog_debug(
2649 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2650 dest, path_buf);
2651 bgp_mp_list_add(&mp_list, pi);
2652 }
2653 }
2654 }
2655
2656 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2657 mpath_cfg);
2658 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2659 bgp_mp_list_clear(&mp_list);
2660
2661 bgp_addpath_update_ids(bgp, dest, afi, safi);
2662
2663 result->old = old_select;
2664 result->new = new_select;
2665
2666 return;
2667 }
2668
2669 /*
2670 * A new route/change in bestpath of an existing route. Evaluate the path
2671 * for advertisement to the subgroup.
2672 */
2673 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2674 struct bgp_path_info *selected,
2675 struct bgp_dest *dest,
2676 uint32_t addpath_tx_id)
2677 {
2678 const struct prefix *p;
2679 struct peer *onlypeer;
2680 struct attr attr;
2681 afi_t afi;
2682 safi_t safi;
2683 struct bgp *bgp;
2684 bool advertise;
2685
2686 p = bgp_dest_get_prefix(dest);
2687 afi = SUBGRP_AFI(subgrp);
2688 safi = SUBGRP_SAFI(subgrp);
2689 bgp = SUBGRP_INST(subgrp);
2690 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2691 : NULL);
2692
2693 if (BGP_DEBUG(update, UPDATE_OUT))
2694 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2695
2696 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2697 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2698 PEER_STATUS_ORF_WAIT_REFRESH))
2699 return;
2700
2701 memset(&attr, 0, sizeof(struct attr));
2702 /* It's initialized in bgp_announce_check() */
2703
2704 /* Announcement to the subgroup. If the route is filtered withdraw it.
2705 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2706 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2707 * route
2708 */
2709 advertise = bgp_check_advertise(bgp, dest);
2710
2711 if (selected) {
2712 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2713 NULL)) {
2714 /* Route is selected, if the route is already installed
2715 * in FIB, then it is advertised
2716 */
2717 if (advertise) {
2718 if (!bgp_check_withdrawal(bgp, dest))
2719 bgp_adj_out_set_subgroup(
2720 dest, subgrp, &attr, selected);
2721 else
2722 bgp_adj_out_unset_subgroup(
2723 dest, subgrp, 1, addpath_tx_id);
2724 }
2725 } else
2726 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2727 addpath_tx_id);
2728 }
2729
2730 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2731 else {
2732 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2733 }
2734 }
2735
2736 /*
2737 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2738 * This is called at the end of route processing.
2739 */
2740 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2741 {
2742 struct bgp_path_info *pi;
2743
2744 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2745 if (BGP_PATH_HOLDDOWN(pi))
2746 continue;
2747 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2748 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2749 }
2750 }
2751
2752 /*
2753 * Has the route changed from the RIB's perspective? This is invoked only
2754 * if the route selection returns the same best route as earlier - to
2755 * determine if we need to update zebra or not.
2756 */
2757 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2758 {
2759 struct bgp_path_info *mpinfo;
2760
2761 /* If this is multipath, check all selected paths for any nexthop
2762 * change or attribute change. Some attribute changes (e.g., community)
2763 * aren't of relevance to the RIB, but we'll update zebra to ensure
2764 * we handle the case of BGP nexthop change. This is the behavior
2765 * when the best path has an attribute change anyway.
2766 */
2767 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2768 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2769 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2770 return true;
2771
2772 /*
2773 * If this is multipath, check all selected paths for any nexthop change
2774 */
2775 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2776 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2777 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2778 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2779 return true;
2780 }
2781
2782 /* Nothing has changed from the RIB's perspective. */
2783 return false;
2784 }
2785
2786 struct bgp_process_queue {
2787 struct bgp *bgp;
2788 STAILQ_HEAD(, bgp_dest) pqueue;
2789 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2790 unsigned int flags;
2791 unsigned int queued;
2792 };
2793
2794 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2795 safi_t safi, struct bgp_dest *dest,
2796 struct bgp_path_info *new_select,
2797 struct bgp_path_info *old_select)
2798 {
2799 const struct prefix *p = bgp_dest_get_prefix(dest);
2800
2801 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2802 return;
2803
2804 if (advertise_type5_routes(bgp, afi) && new_select
2805 && is_route_injectable_into_evpn(new_select)) {
2806
2807 /* apply the route-map */
2808 if (bgp->adv_cmd_rmap[afi][safi].map) {
2809 route_map_result_t ret;
2810 struct bgp_path_info rmap_path;
2811 struct bgp_path_info_extra rmap_path_extra;
2812 struct attr dummy_attr;
2813
2814 dummy_attr = *new_select->attr;
2815
2816 /* Fill temp path_info */
2817 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2818 new_select, new_select->peer,
2819 &dummy_attr);
2820
2821 RESET_FLAG(dummy_attr.rmap_change_flags);
2822
2823 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2824 p, &rmap_path);
2825
2826 if (ret == RMAP_DENYMATCH) {
2827 bgp_attr_flush(&dummy_attr);
2828 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2829 safi);
2830 } else
2831 bgp_evpn_advertise_type5_route(
2832 bgp, p, &dummy_attr, afi, safi);
2833 } else {
2834 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2835 afi, safi);
2836 }
2837 } else if (advertise_type5_routes(bgp, afi) && old_select
2838 && is_route_injectable_into_evpn(old_select))
2839 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2840 }
2841
2842 /*
2843 * Utility to determine whether a particular path_info should use
2844 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
2845 * in a path where we basically _know_ this is a BGP-LU route.
2846 */
2847 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
2848 {
2849 /* Certain types get imp null; so do paths where the nexthop is
2850 * not labeled.
2851 */
2852 if (new_select->sub_type == BGP_ROUTE_STATIC
2853 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2854 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
2855 return true;
2856 else if (new_select->extra == NULL ||
2857 !bgp_is_valid_label(&new_select->extra->label[0]))
2858 /* TODO -- should be configurable? */
2859 return true;
2860 else
2861 return false;
2862 }
2863
2864 /*
2865 * old_select = The old best path
2866 * new_select = the new best path
2867 *
2868 * if (!old_select && new_select)
2869 * We are sending new information on.
2870 *
2871 * if (old_select && new_select) {
2872 * if (new_select != old_select)
2873 * We have a new best path send a change
2874 * else
2875 * We've received a update with new attributes that needs
2876 * to be passed on.
2877 * }
2878 *
2879 * if (old_select && !new_select)
2880 * We have no eligible route that we can announce or the rn
2881 * is being removed.
2882 */
2883 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2884 afi_t afi, safi_t safi)
2885 {
2886 struct bgp_path_info *new_select;
2887 struct bgp_path_info *old_select;
2888 struct bgp_path_info_pair old_and_new;
2889 int debug = 0;
2890
2891 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2892 if (dest)
2893 debug = bgp_debug_bestpath(dest);
2894 if (debug)
2895 zlog_debug(
2896 "%s: bgp delete in progress, ignoring event, p=%pBD",
2897 __func__, dest);
2898 return;
2899 }
2900 /* Is it end of initial update? (after startup) */
2901 if (!dest) {
2902 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
2903 sizeof(bgp->update_delay_zebra_resume_time));
2904
2905 bgp->main_zebra_update_hold = 0;
2906 FOREACH_AFI_SAFI (afi, safi) {
2907 if (bgp_fibupd_safi(safi))
2908 bgp_zebra_announce_table(bgp, afi, safi);
2909 }
2910 bgp->main_peers_update_hold = 0;
2911
2912 bgp_start_routeadv(bgp);
2913 return;
2914 }
2915
2916 const struct prefix *p = bgp_dest_get_prefix(dest);
2917
2918 debug = bgp_debug_bestpath(dest);
2919 if (debug)
2920 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
2921 dest, bgp->name_pretty, afi2str(afi),
2922 safi2str(safi));
2923
2924 /* The best path calculation for the route is deferred if
2925 * BGP_NODE_SELECT_DEFER is set
2926 */
2927 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2928 if (BGP_DEBUG(update, UPDATE_OUT))
2929 zlog_debug("SELECT_DEFER flag set for route %p", dest);
2930 return;
2931 }
2932
2933 /* Best path selection. */
2934 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2935 afi, safi);
2936 old_select = old_and_new.old;
2937 new_select = old_and_new.new;
2938
2939 /* Do we need to allocate or free labels?
2940 * Right now, since we only deal with per-prefix labels, it is not
2941 * necessary to do this upon changes to best path. Exceptions:
2942 * - label index has changed -> recalculate resulting label
2943 * - path_info sub_type changed -> switch to/from implicit-null
2944 * - no valid label (due to removed static label binding) -> get new one
2945 */
2946 if (bgp->allocate_mpls_labels[afi][safi]) {
2947 if (new_select) {
2948 if (!old_select
2949 || bgp_label_index_differs(new_select, old_select)
2950 || new_select->sub_type != old_select->sub_type
2951 || !bgp_is_valid_label(&dest->local_label)) {
2952 /* Enforced penultimate hop popping:
2953 * implicit-null for local routes, aggregate
2954 * and redistributed routes
2955 */
2956 if (bgp_lu_need_imp_null(new_select)) {
2957 if (CHECK_FLAG(
2958 dest->flags,
2959 BGP_NODE_REGISTERED_FOR_LABEL)
2960 || CHECK_FLAG(
2961 dest->flags,
2962 BGP_NODE_LABEL_REQUESTED))
2963 bgp_unregister_for_label(dest);
2964 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2965 &dest->local_label);
2966 bgp_set_valid_label(&dest->local_label);
2967 } else
2968 bgp_register_for_label(dest,
2969 new_select);
2970 }
2971 } else if (CHECK_FLAG(dest->flags,
2972 BGP_NODE_REGISTERED_FOR_LABEL)
2973 || CHECK_FLAG(dest->flags,
2974 BGP_NODE_LABEL_REQUESTED)) {
2975 bgp_unregister_for_label(dest);
2976 }
2977 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
2978 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
2979 bgp_unregister_for_label(dest);
2980 }
2981
2982 if (debug)
2983 zlog_debug(
2984 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
2985 __func__, dest, bgp->name_pretty, afi2str(afi),
2986 safi2str(safi), old_select, new_select);
2987
2988 /* If best route remains the same and this is not due to user-initiated
2989 * clear, see exactly what needs to be done.
2990 */
2991 if (old_select && old_select == new_select
2992 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2993 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2994 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2995 if (bgp_zebra_has_route_changed(old_select)) {
2996 #ifdef ENABLE_BGP_VNC
2997 vnc_import_bgp_add_route(bgp, p, old_select);
2998 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2999 #endif
3000 if (bgp_fibupd_safi(safi)
3001 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3002
3003 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3004 && new_select->sub_type == BGP_ROUTE_NORMAL)
3005 SET_FLAG(dest->flags,
3006 BGP_NODE_FIB_INSTALL_PENDING);
3007
3008 if (new_select->type == ZEBRA_ROUTE_BGP
3009 && (new_select->sub_type == BGP_ROUTE_NORMAL
3010 || new_select->sub_type
3011 == BGP_ROUTE_IMPORTED))
3012
3013 bgp_zebra_announce(dest, p, old_select,
3014 bgp, afi, safi);
3015 }
3016 }
3017
3018 /* If there is a change of interest to peers, reannounce the
3019 * route. */
3020 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3021 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3022 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3023 group_announce_route(bgp, afi, safi, dest, new_select);
3024
3025 /* unicast routes must also be annouced to
3026 * labeled-unicast update-groups */
3027 if (safi == SAFI_UNICAST)
3028 group_announce_route(bgp, afi,
3029 SAFI_LABELED_UNICAST, dest,
3030 new_select);
3031
3032 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3033 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3034 }
3035
3036 /* advertise/withdraw type-5 routes */
3037 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3038 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3039 bgp_process_evpn_route_injection(
3040 bgp, afi, safi, dest, old_select, old_select);
3041
3042 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3043 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3044 bgp_zebra_clear_route_change_flags(dest);
3045 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3046 return;
3047 }
3048
3049 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3050 */
3051 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3052
3053 /* bestpath has changed; bump version */
3054 if (old_select || new_select) {
3055 bgp_bump_version(dest);
3056
3057 if (!bgp->t_rmap_def_originate_eval) {
3058 bgp_lock(bgp);
3059 thread_add_timer(
3060 bm->master,
3061 update_group_refresh_default_originate_route_map,
3062 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3063 &bgp->t_rmap_def_originate_eval);
3064 }
3065 }
3066
3067 if (old_select)
3068 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3069 if (new_select) {
3070 if (debug)
3071 zlog_debug("%s: setting SELECTED flag", __func__);
3072 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3073 bgp_path_info_unset_flag(dest, new_select,
3074 BGP_PATH_ATTR_CHANGED);
3075 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3076 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3077 }
3078
3079 #ifdef ENABLE_BGP_VNC
3080 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3081 if (old_select != new_select) {
3082 if (old_select) {
3083 vnc_import_bgp_exterior_del_route(bgp, p,
3084 old_select);
3085 vnc_import_bgp_del_route(bgp, p, old_select);
3086 }
3087 if (new_select) {
3088 vnc_import_bgp_exterior_add_route(bgp, p,
3089 new_select);
3090 vnc_import_bgp_add_route(bgp, p, new_select);
3091 }
3092 }
3093 }
3094 #endif
3095
3096 group_announce_route(bgp, afi, safi, dest, new_select);
3097
3098 /* unicast routes must also be annouced to labeled-unicast update-groups
3099 */
3100 if (safi == SAFI_UNICAST)
3101 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3102 new_select);
3103
3104 /* FIB update. */
3105 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3106 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3107
3108 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3109 && (new_select->sub_type == BGP_ROUTE_NORMAL
3110 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3111 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3112
3113 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3114 SET_FLAG(dest->flags,
3115 BGP_NODE_FIB_INSTALL_PENDING);
3116
3117 /* if this is an evpn imported type-5 prefix,
3118 * we need to withdraw the route first to clear
3119 * the nh neigh and the RMAC entry.
3120 */
3121 if (old_select &&
3122 is_route_parent_evpn(old_select))
3123 bgp_zebra_withdraw(p, old_select, bgp, safi);
3124
3125 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3126 } else {
3127 /* Withdraw the route from the kernel. */
3128 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3129 && (old_select->sub_type == BGP_ROUTE_NORMAL
3130 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3131 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3132
3133 bgp_zebra_withdraw(p, old_select, bgp, safi);
3134 }
3135 }
3136
3137 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3138 old_select);
3139
3140 /* Clear any route change flags. */
3141 bgp_zebra_clear_route_change_flags(dest);
3142
3143 /* Reap old select bgp_path_info, if it has been removed */
3144 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3145 bgp_path_info_reap(dest, old_select);
3146
3147 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3148 return;
3149 }
3150
3151 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3152 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3153 {
3154 struct bgp_dest *dest;
3155 int cnt = 0;
3156 struct afi_safi_info *thread_info;
3157
3158 if (bgp->gr_info[afi][safi].t_route_select) {
3159 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3160
3161 thread_info = THREAD_ARG(t);
3162 XFREE(MTYPE_TMP, thread_info);
3163 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
3164 }
3165
3166 if (BGP_DEBUG(update, UPDATE_OUT)) {
3167 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3168 get_afi_safi_str(afi, safi, false),
3169 bgp->gr_info[afi][safi].gr_deferred);
3170 }
3171
3172 /* Process the route list */
3173 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3174 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3175 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3176 dest = bgp_route_next(dest)) {
3177 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3178 continue;
3179
3180 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3181 bgp->gr_info[afi][safi].gr_deferred--;
3182 bgp_process_main_one(bgp, dest, afi, safi);
3183 cnt++;
3184 }
3185 /* If iteration stopped before the entire table was traversed then the
3186 * node needs to be unlocked.
3187 */
3188 if (dest) {
3189 bgp_dest_unlock_node(dest);
3190 dest = NULL;
3191 }
3192
3193 /* Send EOR message when all routes are processed */
3194 if (!bgp->gr_info[afi][safi].gr_deferred) {
3195 bgp_send_delayed_eor(bgp);
3196 /* Send route processing complete message to RIB */
3197 bgp_zebra_update(afi, safi, bgp->vrf_id,
3198 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3199 return 0;
3200 }
3201
3202 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3203
3204 thread_info->afi = afi;
3205 thread_info->safi = safi;
3206 thread_info->bgp = bgp;
3207
3208 /* If there are more routes to be processed, start the
3209 * selection timer
3210 */
3211 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3212 BGP_ROUTE_SELECT_DELAY,
3213 &bgp->gr_info[afi][safi].t_route_select);
3214 return 0;
3215 }
3216
3217 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3218 {
3219 struct bgp_process_queue *pqnode = data;
3220 struct bgp *bgp = pqnode->bgp;
3221 struct bgp_table *table;
3222 struct bgp_dest *dest;
3223
3224 /* eoiu marker */
3225 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3226 bgp_process_main_one(bgp, NULL, 0, 0);
3227 /* should always have dedicated wq call */
3228 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3229 return WQ_SUCCESS;
3230 }
3231
3232 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3233 dest = STAILQ_FIRST(&pqnode->pqueue);
3234 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3235 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3236 table = bgp_dest_table(dest);
3237 /* note, new DESTs may be added as part of processing */
3238 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3239
3240 bgp_dest_unlock_node(dest);
3241 bgp_table_unlock(table);
3242 }
3243
3244 return WQ_SUCCESS;
3245 }
3246
3247 static void bgp_processq_del(struct work_queue *wq, void *data)
3248 {
3249 struct bgp_process_queue *pqnode = data;
3250
3251 bgp_unlock(pqnode->bgp);
3252
3253 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3254 }
3255
3256 void bgp_process_queue_init(struct bgp *bgp)
3257 {
3258 if (!bgp->process_queue) {
3259 char name[BUFSIZ];
3260
3261 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3262 bgp->process_queue = work_queue_new(bm->master, name);
3263 }
3264
3265 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3266 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3267 bgp->process_queue->spec.max_retries = 0;
3268 bgp->process_queue->spec.hold = 50;
3269 /* Use a higher yield value of 50ms for main queue processing */
3270 bgp->process_queue->spec.yield = 50 * 1000L;
3271 }
3272
3273 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3274 {
3275 struct bgp_process_queue *pqnode;
3276
3277 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3278 sizeof(struct bgp_process_queue));
3279
3280 /* unlocked in bgp_processq_del */
3281 pqnode->bgp = bgp_lock(bgp);
3282 STAILQ_INIT(&pqnode->pqueue);
3283
3284 return pqnode;
3285 }
3286
3287 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3288 {
3289 #define ARBITRARY_PROCESS_QLEN 10000
3290 struct work_queue *wq = bgp->process_queue;
3291 struct bgp_process_queue *pqnode;
3292 int pqnode_reuse = 0;
3293
3294 /* already scheduled for processing? */
3295 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3296 return;
3297
3298 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3299 * the workqueue
3300 */
3301 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3302 if (BGP_DEBUG(update, UPDATE_OUT))
3303 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3304 dest);
3305 return;
3306 }
3307
3308 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3309 if (BGP_DEBUG(update, UPDATE_OUT))
3310 zlog_debug(
3311 "Soft reconfigure table in progress for route %p",
3312 dest);
3313 return;
3314 }
3315
3316 if (wq == NULL)
3317 return;
3318
3319 /* Add route nodes to an existing work queue item until reaching the
3320 limit only if is from the same BGP view and it's not an EOIU marker
3321 */
3322 if (work_queue_item_count(wq)) {
3323 struct work_queue_item *item = work_queue_last_item(wq);
3324 pqnode = item->data;
3325
3326 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3327 || pqnode->bgp != bgp
3328 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3329 pqnode = bgp_processq_alloc(bgp);
3330 else
3331 pqnode_reuse = 1;
3332 } else
3333 pqnode = bgp_processq_alloc(bgp);
3334 /* all unlocked in bgp_process_wq */
3335 bgp_table_lock(bgp_dest_table(dest));
3336
3337 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3338 bgp_dest_lock_node(dest);
3339
3340 /* can't be enqueued twice */
3341 assert(STAILQ_NEXT(dest, pq) == NULL);
3342 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3343 pqnode->queued++;
3344
3345 if (!pqnode_reuse)
3346 work_queue_add(wq, pqnode);
3347
3348 return;
3349 }
3350
3351 void bgp_add_eoiu_mark(struct bgp *bgp)
3352 {
3353 struct bgp_process_queue *pqnode;
3354
3355 if (bgp->process_queue == NULL)
3356 return;
3357
3358 pqnode = bgp_processq_alloc(bgp);
3359
3360 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3361 work_queue_add(bgp->process_queue, pqnode);
3362 }
3363
3364 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3365 {
3366 struct peer *peer;
3367
3368 peer = THREAD_ARG(thread);
3369 peer->t_pmax_restart = NULL;
3370
3371 if (bgp_debug_neighbor_events(peer))
3372 zlog_debug(
3373 "%s Maximum-prefix restart timer expired, restore peering",
3374 peer->host);
3375
3376 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3377 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3378 }
3379
3380 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3381 safi_t safi)
3382 {
3383 uint32_t count = 0;
3384 bool filtered = false;
3385 struct bgp_dest *dest;
3386 struct bgp_adj_in *ain;
3387 struct attr attr = {};
3388 struct bgp_table *table = peer->bgp->rib[afi][safi];
3389
3390 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3391 for (ain = dest->adj_in; ain; ain = ain->next) {
3392 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3393
3394 attr = *ain->attr;
3395
3396 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3397 == FILTER_DENY)
3398 filtered = true;
3399
3400 if (bgp_input_modifier(
3401 peer, rn_p, &attr, afi, safi,
3402 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3403 NULL, 0, NULL)
3404 == RMAP_DENY)
3405 filtered = true;
3406
3407 if (filtered)
3408 count++;
3409
3410 bgp_attr_flush(&attr);
3411 }
3412 }
3413
3414 return count;
3415 }
3416
3417 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3418 int always)
3419 {
3420 iana_afi_t pkt_afi;
3421 iana_safi_t pkt_safi;
3422 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3423 PEER_FLAG_MAX_PREFIX_FORCE))
3424 ? bgp_filtered_routes_count(peer, afi, safi)
3425 + peer->pcount[afi][safi]
3426 : peer->pcount[afi][safi];
3427
3428 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3429 return false;
3430
3431 if (pcount > peer->pmax[afi][safi]) {
3432 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3433 PEER_STATUS_PREFIX_LIMIT)
3434 && !always)
3435 return false;
3436
3437 zlog_info(
3438 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3439 get_afi_safi_str(afi, safi, false), peer, pcount,
3440 peer->pmax[afi][safi]);
3441 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3442
3443 if (CHECK_FLAG(peer->af_flags[afi][safi],
3444 PEER_FLAG_MAX_PREFIX_WARNING))
3445 return false;
3446
3447 /* Convert AFI, SAFI to values for packet. */
3448 pkt_afi = afi_int2iana(afi);
3449 pkt_safi = safi_int2iana(safi);
3450 {
3451 uint8_t ndata[7];
3452
3453 ndata[0] = (pkt_afi >> 8);
3454 ndata[1] = pkt_afi;
3455 ndata[2] = pkt_safi;
3456 ndata[3] = (peer->pmax[afi][safi] >> 24);
3457 ndata[4] = (peer->pmax[afi][safi] >> 16);
3458 ndata[5] = (peer->pmax[afi][safi] >> 8);
3459 ndata[6] = (peer->pmax[afi][safi]);
3460
3461 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3462 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3463 BGP_NOTIFY_CEASE_MAX_PREFIX,
3464 ndata, 7);
3465 }
3466
3467 /* Dynamic peers will just close their connection. */
3468 if (peer_dynamic_neighbor(peer))
3469 return true;
3470
3471 /* restart timer start */
3472 if (peer->pmax_restart[afi][safi]) {
3473 peer->v_pmax_restart =
3474 peer->pmax_restart[afi][safi] * 60;
3475
3476 if (bgp_debug_neighbor_events(peer))
3477 zlog_debug(
3478 "%pBP Maximum-prefix restart timer started for %d secs",
3479 peer, peer->v_pmax_restart);
3480
3481 BGP_TIMER_ON(peer->t_pmax_restart,
3482 bgp_maximum_prefix_restart_timer,
3483 peer->v_pmax_restart);
3484 }
3485
3486 return true;
3487 } else
3488 UNSET_FLAG(peer->af_sflags[afi][safi],
3489 PEER_STATUS_PREFIX_LIMIT);
3490
3491 if (pcount
3492 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3493 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3494 PEER_STATUS_PREFIX_THRESHOLD)
3495 && !always)
3496 return false;
3497
3498 zlog_info(
3499 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3500 get_afi_safi_str(afi, safi, false), peer, pcount,
3501 peer->pmax[afi][safi]);
3502 SET_FLAG(peer->af_sflags[afi][safi],
3503 PEER_STATUS_PREFIX_THRESHOLD);
3504 } else
3505 UNSET_FLAG(peer->af_sflags[afi][safi],
3506 PEER_STATUS_PREFIX_THRESHOLD);
3507 return false;
3508 }
3509
3510 /* Unconditionally remove the route from the RIB, without taking
3511 * damping into consideration (eg, because the session went down)
3512 */
3513 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3514 struct peer *peer, afi_t afi, safi_t safi)
3515 {
3516
3517 struct bgp *bgp = NULL;
3518 bool delete_route = false;
3519
3520 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3521 safi);
3522
3523 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3524 bgp_path_info_delete(dest, pi); /* keep historical info */
3525
3526 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3527 * flag
3528 */
3529 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3530 delete_route = true;
3531 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3532 delete_route = true;
3533 if (delete_route) {
3534 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3535 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3536 bgp = pi->peer->bgp;
3537 bgp->gr_info[afi][safi].gr_deferred--;
3538 }
3539 }
3540 }
3541
3542 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3543 bgp_process(peer->bgp, dest, afi, safi);
3544 }
3545
3546 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3547 struct peer *peer, afi_t afi, safi_t safi,
3548 struct prefix_rd *prd)
3549 {
3550 const struct prefix *p = bgp_dest_get_prefix(dest);
3551
3552 /* apply dampening, if result is suppressed, we'll be retaining
3553 * the bgp_path_info in the RIB for historical reference.
3554 */
3555 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3556 && peer->sort == BGP_PEER_EBGP)
3557 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3558 == BGP_DAMP_SUPPRESSED) {
3559 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3560 safi);
3561 return;
3562 }
3563
3564 #ifdef ENABLE_BGP_VNC
3565 if (safi == SAFI_MPLS_VPN) {
3566 struct bgp_dest *pdest = NULL;
3567 struct bgp_table *table = NULL;
3568
3569 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3570 (struct prefix *)prd);
3571 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3572 table = bgp_dest_get_bgp_table_info(pdest);
3573
3574 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3575 peer->bgp, prd, table, p, pi);
3576 }
3577 bgp_dest_unlock_node(pdest);
3578 }
3579 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3580 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3581
3582 vnc_import_bgp_del_route(peer->bgp, p, pi);
3583 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3584 }
3585 }
3586 #endif
3587
3588 /* If this is an EVPN route, process for un-import. */
3589 if (safi == SAFI_EVPN)
3590 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3591
3592 bgp_rib_remove(dest, pi, peer, afi, safi);
3593 }
3594
3595 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3596 struct peer *peer, struct attr *attr,
3597 struct bgp_dest *dest)
3598 {
3599 struct bgp_path_info *new;
3600
3601 /* Make new BGP info. */
3602 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3603 new->type = type;
3604 new->instance = instance;
3605 new->sub_type = sub_type;
3606 new->peer = peer;
3607 new->attr = attr;
3608 new->uptime = bgp_clock();
3609 new->net = dest;
3610 return new;
3611 }
3612
3613 /* Check if received nexthop is valid or not. */
3614 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3615 uint8_t type, uint8_t stype, struct attr *attr,
3616 struct bgp_dest *dest)
3617 {
3618 bool ret = false;
3619 bool is_bgp_static_route =
3620 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3621 : false;
3622
3623 /*
3624 * Only validated for unicast and multicast currently.
3625 * Also valid for EVPN where the nexthop is an IP address.
3626 * If we are a bgp static route being checked then there is
3627 * no need to check to see if the nexthop is martian as
3628 * that it should be ok.
3629 */
3630 if (is_bgp_static_route ||
3631 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3632 return false;
3633
3634 /* If NEXT_HOP is present, validate it. */
3635 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3636 if (attr->nexthop.s_addr == INADDR_ANY
3637 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3638 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3639 return true;
3640 }
3641
3642 /* If MP_NEXTHOP is present, validate it. */
3643 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3644 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3645 * it is not an IPv6 link-local address.
3646 *
3647 * If we receive an UPDATE with nexthop length set to 32 bytes
3648 * we shouldn't discard an UPDATE if it's set to (::).
3649 * The link-local (2st) is validated along the code path later.
3650 */
3651 if (attr->mp_nexthop_len) {
3652 switch (attr->mp_nexthop_len) {
3653 case BGP_ATTR_NHLEN_IPV4:
3654 case BGP_ATTR_NHLEN_VPNV4:
3655 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3656 || IPV4_CLASS_DE(
3657 ntohl(attr->mp_nexthop_global_in.s_addr))
3658 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3659 dest));
3660 break;
3661
3662 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3663 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3664 ret = (IN6_IS_ADDR_UNSPECIFIED(
3665 &attr->mp_nexthop_global)
3666 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3667 || IN6_IS_ADDR_MULTICAST(
3668 &attr->mp_nexthop_global)
3669 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3670 dest));
3671 break;
3672 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3673 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3674 || IN6_IS_ADDR_MULTICAST(
3675 &attr->mp_nexthop_global)
3676 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3677 dest));
3678 break;
3679
3680 default:
3681 ret = true;
3682 break;
3683 }
3684 }
3685
3686 return ret;
3687 }
3688
3689 static void bgp_attr_add_no_export_community(struct attr *attr)
3690 {
3691 struct community *old;
3692 struct community *new;
3693 struct community *merge;
3694 struct community *no_export;
3695
3696 old = bgp_attr_get_community(attr);
3697 no_export = community_str2com("no-export");
3698
3699 assert(no_export);
3700
3701 if (old) {
3702 merge = community_merge(community_dup(old), no_export);
3703
3704 if (!old->refcnt)
3705 community_free(&old);
3706
3707 new = community_uniq_sort(merge);
3708 community_free(&merge);
3709 } else {
3710 new = community_dup(no_export);
3711 }
3712
3713 community_free(&no_export);
3714
3715 bgp_attr_set_community(attr, new);
3716 }
3717
3718 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3719 struct attr *attr, afi_t afi, safi_t safi, int type,
3720 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3721 uint32_t num_labels, int soft_reconfig,
3722 struct bgp_route_evpn *evpn)
3723 {
3724 int ret;
3725 int aspath_loop_count = 0;
3726 struct bgp_dest *dest;
3727 struct bgp *bgp;
3728 struct attr new_attr;
3729 struct attr *attr_new;
3730 struct bgp_path_info *pi;
3731 struct bgp_path_info *new;
3732 struct bgp_path_info_extra *extra;
3733 const char *reason;
3734 char pfx_buf[BGP_PRD_PATH_STRLEN];
3735 int connected = 0;
3736 int do_loop_check = 1;
3737 int has_valid_label = 0;
3738 afi_t nh_afi;
3739 uint8_t pi_type = 0;
3740 uint8_t pi_sub_type = 0;
3741 bool force_evpn_import = false;
3742 safi_t orig_safi = safi;
3743
3744 if (frrtrace_enabled(frr_bgp, process_update)) {
3745 char pfxprint[PREFIX2STR_BUFFER];
3746
3747 prefix2str(p, pfxprint, sizeof(pfxprint));
3748 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3749 afi, safi, attr);
3750 }
3751
3752 #ifdef ENABLE_BGP_VNC
3753 int vnc_implicit_withdraw = 0;
3754 #endif
3755 int same_attr = 0;
3756
3757 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
3758 if (orig_safi == SAFI_LABELED_UNICAST)
3759 safi = SAFI_UNICAST;
3760
3761 memset(&new_attr, 0, sizeof(struct attr));
3762 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3763 new_attr.label = MPLS_INVALID_LABEL;
3764
3765 bgp = peer->bgp;
3766 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3767 /* TODO: Check to see if we can get rid of "is_valid_label" */
3768 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3769 has_valid_label = (num_labels > 0) ? 1 : 0;
3770 else
3771 has_valid_label = bgp_is_valid_label(label);
3772
3773 if (has_valid_label)
3774 assert(label != NULL);
3775
3776 /* Update overlay index of the attribute */
3777 if (afi == AFI_L2VPN && evpn)
3778 memcpy(&attr->evpn_overlay, evpn,
3779 sizeof(struct bgp_route_evpn));
3780
3781 /* When peer's soft reconfiguration enabled. Record input packet in
3782 Adj-RIBs-In. */
3783 if (!soft_reconfig
3784 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3785 && peer != bgp->peer_self)
3786 bgp_adj_in_set(dest, peer, attr, addpath_id);
3787
3788 /* Check previously received route. */
3789 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3790 if (pi->peer == peer && pi->type == type
3791 && pi->sub_type == sub_type
3792 && pi->addpath_rx_id == addpath_id)
3793 break;
3794
3795 /* AS path local-as loop check. */
3796 if (peer->change_local_as) {
3797 if (peer->allowas_in[afi][safi])
3798 aspath_loop_count = peer->allowas_in[afi][safi];
3799 else if (!CHECK_FLAG(peer->flags,
3800 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3801 aspath_loop_count = 1;
3802
3803 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3804 > aspath_loop_count) {
3805 peer->stat_pfx_aspath_loop++;
3806 reason = "as-path contains our own AS;";
3807 goto filtered;
3808 }
3809 }
3810
3811 /* If the peer is configured for "allowas-in origin" and the last ASN in
3812 * the
3813 * as-path is our ASN then we do not need to call aspath_loop_check
3814 */
3815 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3816 if (aspath_get_last_as(attr->aspath) == bgp->as)
3817 do_loop_check = 0;
3818
3819 /* AS path loop check. */
3820 if (do_loop_check) {
3821 if (aspath_loop_check(attr->aspath, bgp->as)
3822 > peer->allowas_in[afi][safi]
3823 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3824 && aspath_loop_check(attr->aspath, bgp->confed_id)
3825 > peer->allowas_in[afi][safi])) {
3826 peer->stat_pfx_aspath_loop++;
3827 reason = "as-path contains our own AS;";
3828 goto filtered;
3829 }
3830 }
3831
3832 /* Route reflector originator ID check. */
3833 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3834 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3835 peer->stat_pfx_originator_loop++;
3836 reason = "originator is us;";
3837 goto filtered;
3838 }
3839
3840 /* Route reflector cluster ID check. */
3841 if (bgp_cluster_filter(peer, attr)) {
3842 peer->stat_pfx_cluster_loop++;
3843 reason = "reflected from the same cluster;";
3844 goto filtered;
3845 }
3846
3847 /* Apply incoming filter. */
3848 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
3849 peer->stat_pfx_filter++;
3850 reason = "filter;";
3851 goto filtered;
3852 }
3853
3854 /* RFC 8212 to prevent route leaks.
3855 * This specification intends to improve this situation by requiring the
3856 * explicit configuration of both BGP Import and Export Policies for any
3857 * External BGP (EBGP) session such as customers, peers, or
3858 * confederation boundaries for all enabled address families. Through
3859 * codification of the aforementioned requirement, operators will
3860 * benefit from consistent behavior across different BGP
3861 * implementations.
3862 */
3863 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3864 if (!bgp_inbound_policy_exists(peer,
3865 &peer->filter[afi][safi])) {
3866 reason = "inbound policy missing";
3867 if (monotime_since(&bgp->ebgprequirespolicywarning,
3868 NULL) > FIFTEENMINUTE2USEC ||
3869 bgp->ebgprequirespolicywarning.tv_sec == 0) {
3870 zlog_warn(
3871 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
3872 monotime(&bgp->ebgprequirespolicywarning);
3873 }
3874 goto filtered;
3875 }
3876
3877 /* draft-ietf-idr-deprecate-as-set-confed-set
3878 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3879 * Eventually, This document (if approved) updates RFC 4271
3880 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3881 * and obsoletes RFC 6472.
3882 */
3883 if (peer->bgp->reject_as_sets)
3884 if (aspath_check_as_sets(attr->aspath)) {
3885 reason =
3886 "as-path contains AS_SET or AS_CONFED_SET type;";
3887 goto filtered;
3888 }
3889
3890 new_attr = *attr;
3891
3892 /* Apply incoming route-map.
3893 * NB: new_attr may now contain newly allocated values from route-map
3894 * "set"
3895 * commands, so we need bgp_attr_flush in the error paths, until we
3896 * intern
3897 * the attr (which takes over the memory references) */
3898 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
3899 num_labels, dest)
3900 == RMAP_DENY) {
3901 peer->stat_pfx_filter++;
3902 reason = "route-map;";
3903 bgp_attr_flush(&new_attr);
3904 goto filtered;
3905 }
3906
3907 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3908 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3909 /* remove from RIB previous entry */
3910 bgp_zebra_withdraw(p, pi, bgp, safi);
3911 }
3912
3913 if (peer->sort == BGP_PEER_EBGP) {
3914
3915 /* rfc7999:
3916 * A BGP speaker receiving an announcement tagged with the
3917 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
3918 * NO_EXPORT community as defined in RFC1997, or a
3919 * similar community, to prevent propagation of the
3920 * prefix outside the local AS. The community to prevent
3921 * propagation SHOULD be chosen according to the operator's
3922 * routing policy.
3923 */
3924 if (bgp_attr_get_community(&new_attr) &&
3925 community_include(bgp_attr_get_community(&new_attr),
3926 COMMUNITY_BLACKHOLE))
3927 bgp_attr_add_no_export_community(&new_attr);
3928
3929 /* If we receive the graceful-shutdown community from an eBGP
3930 * peer we must lower local-preference */
3931 if (bgp_attr_get_community(&new_attr) &&
3932 community_include(bgp_attr_get_community(&new_attr),
3933 COMMUNITY_GSHUT)) {
3934 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3935 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3936
3937 /* If graceful-shutdown is configured then add the GSHUT
3938 * community to all paths received from eBGP peers */
3939 } else if (bgp_in_graceful_shutdown(peer->bgp))
3940 bgp_attr_add_gshut_community(&new_attr);
3941 }
3942
3943 if (pi) {
3944 pi_type = pi->type;
3945 pi_sub_type = pi->sub_type;
3946 }
3947
3948 /* next hop check. */
3949 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3950 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3951 &new_attr, dest)) {
3952 peer->stat_pfx_nh_invalid++;
3953 reason = "martian or self next-hop;";
3954 bgp_attr_flush(&new_attr);
3955 goto filtered;
3956 }
3957
3958 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3959 peer->stat_pfx_nh_invalid++;
3960 reason = "self mac;";
3961 bgp_attr_flush(&new_attr);
3962 goto filtered;
3963 }
3964
3965 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
3966 * condition :
3967 * Suppress fib is enabled
3968 * BGP_OPT_NO_FIB is not enabled
3969 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
3970 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
3971 */
3972 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
3973 && (sub_type == BGP_ROUTE_NORMAL)
3974 && (!bgp_option_check(BGP_OPT_NO_FIB))
3975 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
3976 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
3977
3978 /* If maximum prefix count is configured and current prefix
3979 * count exeed it.
3980 */
3981 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
3982 bgp_attr_flush(&new_attr);
3983 return -1;
3984 }
3985
3986 attr_new = bgp_attr_intern(&new_attr);
3987
3988 /* If the update is implicit withdraw. */
3989 if (pi) {
3990 pi->uptime = bgp_clock();
3991 same_attr = attrhash_cmp(pi->attr, attr_new);
3992
3993 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3994
3995 /* Same attribute comes in. */
3996 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3997 && same_attr
3998 && (!has_valid_label
3999 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4000 num_labels * sizeof(mpls_label_t))
4001 == 0)) {
4002 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4003 BGP_CONFIG_DAMPENING)
4004 && peer->sort == BGP_PEER_EBGP
4005 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4006 if (bgp_debug_update(peer, p, NULL, 1)) {
4007 bgp_debug_rdpfxpath2str(
4008 afi, safi, prd, p, label,
4009 num_labels, addpath_id ? 1 : 0,
4010 addpath_id, evpn, pfx_buf,
4011 sizeof(pfx_buf));
4012 zlog_debug("%pBP rcvd %s", peer,
4013 pfx_buf);
4014 }
4015
4016 if (bgp_damp_update(pi, dest, afi, safi)
4017 != BGP_DAMP_SUPPRESSED) {
4018 bgp_aggregate_increment(bgp, p, pi, afi,
4019 safi);
4020 bgp_process(bgp, dest, afi, safi);
4021 }
4022 } else /* Duplicate - odd */
4023 {
4024 if (bgp_debug_update(peer, p, NULL, 1)) {
4025 if (!peer->rcvd_attr_printed) {
4026 zlog_debug(
4027 "%pBP rcvd UPDATE w/ attr: %s",
4028 peer,
4029 peer->rcvd_attr_str);
4030 peer->rcvd_attr_printed = 1;
4031 }
4032
4033 bgp_debug_rdpfxpath2str(
4034 afi, safi, prd, p, label,
4035 num_labels, addpath_id ? 1 : 0,
4036 addpath_id, evpn, pfx_buf,
4037 sizeof(pfx_buf));
4038 zlog_debug(
4039 "%pBP rcvd %s...duplicate ignored",
4040 peer, pfx_buf);
4041 }
4042
4043 /* graceful restart STALE flag unset. */
4044 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4045 bgp_path_info_unset_flag(
4046 dest, pi, BGP_PATH_STALE);
4047 bgp_dest_set_defer_flag(dest, false);
4048 bgp_process(bgp, dest, afi, safi);
4049 }
4050 }
4051
4052 bgp_dest_unlock_node(dest);
4053 bgp_attr_unintern(&attr_new);
4054
4055 return 0;
4056 }
4057
4058 /* Withdraw/Announce before we fully processed the withdraw */
4059 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4060 if (bgp_debug_update(peer, p, NULL, 1)) {
4061 bgp_debug_rdpfxpath2str(
4062 afi, safi, prd, p, label, num_labels,
4063 addpath_id ? 1 : 0, addpath_id, evpn,
4064 pfx_buf, sizeof(pfx_buf));
4065 zlog_debug(
4066 "%pBP rcvd %s, flapped quicker than processing",
4067 peer, pfx_buf);
4068 }
4069
4070 bgp_path_info_restore(dest, pi);
4071
4072 /*
4073 * If the BGP_PATH_REMOVED flag is set, then EVPN
4074 * routes would have been unimported already when a
4075 * prior BGP withdraw processing happened. Such routes
4076 * need to be imported again, so flag accordingly.
4077 */
4078 force_evpn_import = true;
4079 }
4080
4081 /* Received Logging. */
4082 if (bgp_debug_update(peer, p, NULL, 1)) {
4083 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4084 num_labels, addpath_id ? 1 : 0,
4085 addpath_id, evpn, pfx_buf,
4086 sizeof(pfx_buf));
4087 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4088 }
4089
4090 /* graceful restart STALE flag unset. */
4091 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4092 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4093 bgp_dest_set_defer_flag(dest, false);
4094 }
4095
4096 /* The attribute is changed. */
4097 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4098
4099 /* implicit withdraw, decrement aggregate and pcount here.
4100 * only if update is accepted, they'll increment below.
4101 */
4102 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4103
4104 /* Update bgp route dampening information. */
4105 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4106 && peer->sort == BGP_PEER_EBGP) {
4107 /* This is implicit withdraw so we should update
4108 dampening
4109 information. */
4110 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4111 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4112 }
4113 #ifdef ENABLE_BGP_VNC
4114 if (safi == SAFI_MPLS_VPN) {
4115 struct bgp_dest *pdest = NULL;
4116 struct bgp_table *table = NULL;
4117
4118 pdest = bgp_node_get(bgp->rib[afi][safi],
4119 (struct prefix *)prd);
4120 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4121 table = bgp_dest_get_bgp_table_info(pdest);
4122
4123 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4124 bgp, prd, table, p, pi);
4125 }
4126 bgp_dest_unlock_node(pdest);
4127 }
4128 if ((afi == AFI_IP || afi == AFI_IP6)
4129 && (safi == SAFI_UNICAST)) {
4130 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4131 /*
4132 * Implicit withdraw case.
4133 */
4134 ++vnc_implicit_withdraw;
4135 vnc_import_bgp_del_route(bgp, p, pi);
4136 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4137 }
4138 }
4139 #endif
4140
4141 /* Special handling for EVPN update of an existing route. If the
4142 * extended community attribute has changed, we need to
4143 * un-import
4144 * the route using its existing extended community. It will be
4145 * subsequently processed for import with the new extended
4146 * community.
4147 */
4148 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4149 && !same_attr) {
4150 if ((pi->attr->flag
4151 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4152 && (attr_new->flag
4153 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4154 int cmp;
4155
4156 cmp = ecommunity_cmp(
4157 bgp_attr_get_ecommunity(pi->attr),
4158 bgp_attr_get_ecommunity(attr_new));
4159 if (!cmp) {
4160 if (bgp_debug_update(peer, p, NULL, 1))
4161 zlog_debug(
4162 "Change in EXT-COMM, existing %s new %s",
4163 ecommunity_str(
4164 bgp_attr_get_ecommunity(
4165 pi->attr)),
4166 ecommunity_str(
4167 bgp_attr_get_ecommunity(
4168 attr_new)));
4169 if (safi == SAFI_EVPN)
4170 bgp_evpn_unimport_route(
4171 bgp, afi, safi, p, pi);
4172 else /* SAFI_MPLS_VPN */
4173 vpn_leak_to_vrf_withdraw(bgp,
4174 pi);
4175 }
4176 }
4177 }
4178
4179 /* Update to new attribute. */
4180 bgp_attr_unintern(&pi->attr);
4181 pi->attr = attr_new;
4182
4183 /* Update MPLS label */
4184 if (has_valid_label) {
4185 extra = bgp_path_info_extra_get(pi);
4186 if (extra->label != label) {
4187 memcpy(&extra->label, label,
4188 num_labels * sizeof(mpls_label_t));
4189 extra->num_labels = num_labels;
4190 }
4191 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4192 bgp_set_valid_label(&extra->label[0]);
4193 }
4194
4195 /* Update SRv6 SID */
4196 if (attr->srv6_l3vpn) {
4197 extra = bgp_path_info_extra_get(pi);
4198 if (sid_diff(&extra->sid[0].sid,
4199 &attr->srv6_l3vpn->sid)) {
4200 sid_copy(&extra->sid[0].sid,
4201 &attr->srv6_l3vpn->sid);
4202 extra->num_sids = 1;
4203
4204 extra->sid[0].loc_block_len = 0;
4205 extra->sid[0].loc_node_len = 0;
4206 extra->sid[0].func_len = 0;
4207 extra->sid[0].arg_len = 0;
4208 extra->sid[0].transposition_len = 0;
4209 extra->sid[0].transposition_offset = 0;
4210
4211 if (attr->srv6_l3vpn->loc_block_len != 0) {
4212 extra->sid[0].loc_block_len =
4213 attr->srv6_l3vpn->loc_block_len;
4214 extra->sid[0].loc_node_len =
4215 attr->srv6_l3vpn->loc_node_len;
4216 extra->sid[0].func_len =
4217 attr->srv6_l3vpn->func_len;
4218 extra->sid[0].arg_len =
4219 attr->srv6_l3vpn->arg_len;
4220 extra->sid[0].transposition_len =
4221 attr->srv6_l3vpn
4222 ->transposition_len;
4223 extra->sid[0].transposition_offset =
4224 attr->srv6_l3vpn
4225 ->transposition_offset;
4226 }
4227 }
4228 } else if (attr->srv6_vpn) {
4229 extra = bgp_path_info_extra_get(pi);
4230 if (sid_diff(&extra->sid[0].sid,
4231 &attr->srv6_vpn->sid)) {
4232 sid_copy(&extra->sid[0].sid,
4233 &attr->srv6_vpn->sid);
4234 extra->num_sids = 1;
4235 }
4236 }
4237
4238 #ifdef ENABLE_BGP_VNC
4239 if ((afi == AFI_IP || afi == AFI_IP6)
4240 && (safi == SAFI_UNICAST)) {
4241 if (vnc_implicit_withdraw) {
4242 /*
4243 * Add back the route with its new attributes
4244 * (e.g., nexthop).
4245 * The route is still selected, until the route
4246 * selection
4247 * queued by bgp_process actually runs. We have
4248 * to make this
4249 * update to the VNC side immediately to avoid
4250 * racing against
4251 * configuration changes (e.g., route-map
4252 * changes) which
4253 * trigger re-importation of the entire RIB.
4254 */
4255 vnc_import_bgp_add_route(bgp, p, pi);
4256 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4257 }
4258 }
4259 #endif
4260
4261 /* Update bgp route dampening information. */
4262 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4263 && peer->sort == BGP_PEER_EBGP) {
4264 /* Now we do normal update dampening. */
4265 ret = bgp_damp_update(pi, dest, afi, safi);
4266 if (ret == BGP_DAMP_SUPPRESSED) {
4267 bgp_dest_unlock_node(dest);
4268 return 0;
4269 }
4270 }
4271
4272 /* Nexthop reachability check - for unicast and
4273 * labeled-unicast.. */
4274 if (((afi == AFI_IP || afi == AFI_IP6)
4275 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4276 || (safi == SAFI_EVPN &&
4277 bgp_evpn_is_prefix_nht_supported(p))) {
4278 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4279 && peer->ttl == BGP_DEFAULT_TTL
4280 && !CHECK_FLAG(peer->flags,
4281 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4282 && !CHECK_FLAG(bgp->flags,
4283 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4284 connected = 1;
4285 else
4286 connected = 0;
4287
4288 struct bgp *bgp_nexthop = bgp;
4289
4290 if (pi->extra && pi->extra->bgp_orig)
4291 bgp_nexthop = pi->extra->bgp_orig;
4292
4293 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4294
4295 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4296 safi, pi, NULL, connected,
4297 p)
4298 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4299 bgp_path_info_set_flag(dest, pi,
4300 BGP_PATH_VALID);
4301 else {
4302 if (BGP_DEBUG(nht, NHT)) {
4303 zlog_debug("%s(%pI4): NH unresolved",
4304 __func__,
4305 (in_addr_t *)&attr_new->nexthop);
4306 }
4307 bgp_path_info_unset_flag(dest, pi,
4308 BGP_PATH_VALID);
4309 }
4310 } else
4311 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4312
4313 #ifdef ENABLE_BGP_VNC
4314 if (safi == SAFI_MPLS_VPN) {
4315 struct bgp_dest *pdest = NULL;
4316 struct bgp_table *table = NULL;
4317
4318 pdest = bgp_node_get(bgp->rib[afi][safi],
4319 (struct prefix *)prd);
4320 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4321 table = bgp_dest_get_bgp_table_info(pdest);
4322
4323 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4324 bgp, prd, table, p, pi);
4325 }
4326 bgp_dest_unlock_node(pdest);
4327 }
4328 #endif
4329
4330 /* If this is an EVPN route and some attribute has changed,
4331 * or we are explicitly told to perform a route import, process
4332 * route for import. If the extended community has changed, we
4333 * would
4334 * have done the un-import earlier and the import would result
4335 * in the
4336 * route getting injected into appropriate L2 VNIs. If it is
4337 * just
4338 * some other attribute change, the import will result in
4339 * updating
4340 * the attributes for the route in the VNI(s).
4341 */
4342 if (safi == SAFI_EVPN &&
4343 (!same_attr || force_evpn_import) &&
4344 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4345 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4346
4347 /* Process change. */
4348 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4349
4350 bgp_process(bgp, dest, afi, safi);
4351 bgp_dest_unlock_node(dest);
4352
4353 if (SAFI_UNICAST == safi
4354 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4355 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4356
4357 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4358 }
4359 if ((SAFI_MPLS_VPN == safi)
4360 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4361
4362 vpn_leak_to_vrf_update(bgp, pi);
4363 }
4364
4365 #ifdef ENABLE_BGP_VNC
4366 if (SAFI_MPLS_VPN == safi) {
4367 mpls_label_t label_decoded = decode_label(label);
4368
4369 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4370 type, sub_type, &label_decoded);
4371 }
4372 if (SAFI_ENCAP == safi) {
4373 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4374 type, sub_type, NULL);
4375 }
4376 #endif
4377
4378 return 0;
4379 } // End of implicit withdraw
4380
4381 /* Received Logging. */
4382 if (bgp_debug_update(peer, p, NULL, 1)) {
4383 if (!peer->rcvd_attr_printed) {
4384 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4385 peer->rcvd_attr_str);
4386 peer->rcvd_attr_printed = 1;
4387 }
4388
4389 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4390 addpath_id ? 1 : 0, addpath_id, evpn,
4391 pfx_buf, sizeof(pfx_buf));
4392 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4393 }
4394
4395 /* Make new BGP info. */
4396 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4397
4398 /* Update MPLS label */
4399 if (has_valid_label) {
4400 extra = bgp_path_info_extra_get(new);
4401 if (extra->label != label) {
4402 memcpy(&extra->label, label,
4403 num_labels * sizeof(mpls_label_t));
4404 extra->num_labels = num_labels;
4405 }
4406 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4407 bgp_set_valid_label(&extra->label[0]);
4408 }
4409
4410 /* Update SRv6 SID */
4411 if (safi == SAFI_MPLS_VPN) {
4412 extra = bgp_path_info_extra_get(new);
4413 if (attr->srv6_l3vpn) {
4414 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4415 extra->num_sids = 1;
4416
4417 extra->sid[0].loc_block_len =
4418 attr->srv6_l3vpn->loc_block_len;
4419 extra->sid[0].loc_node_len =
4420 attr->srv6_l3vpn->loc_node_len;
4421 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4422 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4423 extra->sid[0].transposition_len =
4424 attr->srv6_l3vpn->transposition_len;
4425 extra->sid[0].transposition_offset =
4426 attr->srv6_l3vpn->transposition_offset;
4427 } else if (attr->srv6_vpn) {
4428 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4429 extra->num_sids = 1;
4430 }
4431 }
4432
4433 /* Nexthop reachability check. */
4434 if (((afi == AFI_IP || afi == AFI_IP6)
4435 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4436 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4437 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4438 && peer->ttl == BGP_DEFAULT_TTL
4439 && !CHECK_FLAG(peer->flags,
4440 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4441 && !CHECK_FLAG(bgp->flags,
4442 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4443 connected = 1;
4444 else
4445 connected = 0;
4446
4447 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4448
4449 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4450 connected, p)
4451 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4452 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4453 else {
4454 if (BGP_DEBUG(nht, NHT)) {
4455 char buf1[INET6_ADDRSTRLEN];
4456 inet_ntop(AF_INET,
4457 (const void *)&attr_new->nexthop,
4458 buf1, INET6_ADDRSTRLEN);
4459 zlog_debug("%s(%s): NH unresolved", __func__,
4460 buf1);
4461 }
4462 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4463 }
4464 } else
4465 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4466
4467 /* Addpath ID */
4468 new->addpath_rx_id = addpath_id;
4469
4470 /* Increment prefix */
4471 bgp_aggregate_increment(bgp, p, new, afi, safi);
4472
4473 /* Register new BGP information. */
4474 bgp_path_info_add(dest, new);
4475
4476 /* route_node_get lock */
4477 bgp_dest_unlock_node(dest);
4478
4479 #ifdef ENABLE_BGP_VNC
4480 if (safi == SAFI_MPLS_VPN) {
4481 struct bgp_dest *pdest = NULL;
4482 struct bgp_table *table = NULL;
4483
4484 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4485 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4486 table = bgp_dest_get_bgp_table_info(pdest);
4487
4488 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4489 bgp, prd, table, p, new);
4490 }
4491 bgp_dest_unlock_node(pdest);
4492 }
4493 #endif
4494
4495 /* If this is an EVPN route, process for import. */
4496 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4497 bgp_evpn_import_route(bgp, afi, safi, p, new);
4498
4499 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4500
4501 /* Process change. */
4502 bgp_process(bgp, dest, afi, safi);
4503
4504 if (SAFI_UNICAST == safi
4505 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4506 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4507 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4508 }
4509 if ((SAFI_MPLS_VPN == safi)
4510 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4511
4512 vpn_leak_to_vrf_update(bgp, new);
4513 }
4514 #ifdef ENABLE_BGP_VNC
4515 if (SAFI_MPLS_VPN == safi) {
4516 mpls_label_t label_decoded = decode_label(label);
4517
4518 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4519 sub_type, &label_decoded);
4520 }
4521 if (SAFI_ENCAP == safi) {
4522 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4523 sub_type, NULL);
4524 }
4525 #endif
4526
4527 return 0;
4528
4529 /* This BGP update is filtered. Log the reason then update BGP
4530 entry. */
4531 filtered:
4532 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4533
4534 if (bgp_debug_update(peer, p, NULL, 1)) {
4535 if (!peer->rcvd_attr_printed) {
4536 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4537 peer->rcvd_attr_str);
4538 peer->rcvd_attr_printed = 1;
4539 }
4540
4541 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4542 addpath_id ? 1 : 0, addpath_id, evpn,
4543 pfx_buf, sizeof(pfx_buf));
4544 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4545 peer, pfx_buf, reason);
4546 }
4547
4548 if (pi) {
4549 /* If this is an EVPN route, un-import it as it is now filtered.
4550 */
4551 if (safi == SAFI_EVPN)
4552 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4553
4554 if (SAFI_UNICAST == safi
4555 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4556 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4557
4558 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4559 }
4560 if ((SAFI_MPLS_VPN == safi)
4561 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4562
4563 vpn_leak_to_vrf_withdraw(bgp, pi);
4564 }
4565
4566 bgp_rib_remove(dest, pi, peer, afi, safi);
4567 }
4568
4569 bgp_dest_unlock_node(dest);
4570
4571 #ifdef ENABLE_BGP_VNC
4572 /*
4573 * Filtered update is treated as an implicit withdrawal (see
4574 * bgp_rib_remove()
4575 * a few lines above)
4576 */
4577 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4578 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4579 0);
4580 }
4581 #endif
4582
4583 return 0;
4584 }
4585
4586 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4587 struct attr *attr, afi_t afi, safi_t safi, int type,
4588 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4589 uint32_t num_labels, struct bgp_route_evpn *evpn)
4590 {
4591 struct bgp *bgp;
4592 char pfx_buf[BGP_PRD_PATH_STRLEN];
4593 struct bgp_dest *dest;
4594 struct bgp_path_info *pi;
4595
4596 #ifdef ENABLE_BGP_VNC
4597 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4598 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4599 0);
4600 }
4601 #endif
4602
4603 bgp = peer->bgp;
4604
4605 /* Lookup node. */
4606 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4607
4608 /* If peer is soft reconfiguration enabled. Record input packet for
4609 * further calculation.
4610 *
4611 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4612 * routes that are filtered. This tanks out Quagga RS pretty badly due
4613 * to
4614 * the iteration over all RS clients.
4615 * Since we need to remove the entry from adj_in anyway, do that first
4616 * and
4617 * if there was no entry, we don't need to do anything more.
4618 */
4619 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4620 && peer != bgp->peer_self)
4621 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4622 peer->stat_pfx_dup_withdraw++;
4623
4624 if (bgp_debug_update(peer, p, NULL, 1)) {
4625 bgp_debug_rdpfxpath2str(
4626 afi, safi, prd, p, label, num_labels,
4627 addpath_id ? 1 : 0, addpath_id, NULL,
4628 pfx_buf, sizeof(pfx_buf));
4629 zlog_debug(
4630 "%s withdrawing route %s not in adj-in",
4631 peer->host, pfx_buf);
4632 }
4633 bgp_dest_unlock_node(dest);
4634 return 0;
4635 }
4636
4637 /* Lookup withdrawn route. */
4638 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4639 if (pi->peer == peer && pi->type == type
4640 && pi->sub_type == sub_type
4641 && pi->addpath_rx_id == addpath_id)
4642 break;
4643
4644 /* Logging. */
4645 if (bgp_debug_update(peer, p, NULL, 1)) {
4646 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4647 addpath_id ? 1 : 0, addpath_id, NULL,
4648 pfx_buf, sizeof(pfx_buf));
4649 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4650 pfx_buf);
4651 }
4652
4653 /* Withdraw specified route from routing table. */
4654 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4655 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4656 if (SAFI_UNICAST == safi
4657 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4658 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4659 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4660 }
4661 if ((SAFI_MPLS_VPN == safi)
4662 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4663
4664 vpn_leak_to_vrf_withdraw(bgp, pi);
4665 }
4666 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4667 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4668 addpath_id ? 1 : 0, addpath_id, NULL,
4669 pfx_buf, sizeof(pfx_buf));
4670 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4671 }
4672
4673 /* Unlock bgp_node_get() lock. */
4674 bgp_dest_unlock_node(dest);
4675
4676 return 0;
4677 }
4678
4679 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4680 int withdraw)
4681 {
4682 struct update_subgroup *subgrp;
4683 subgrp = peer_subgroup(peer, afi, safi);
4684 subgroup_default_originate(subgrp, withdraw);
4685 }
4686
4687
4688 /*
4689 * bgp_stop_announce_route_timer
4690 */
4691 void bgp_stop_announce_route_timer(struct peer_af *paf)
4692 {
4693 if (!paf->t_announce_route)
4694 return;
4695
4696 thread_cancel(&paf->t_announce_route);
4697 }
4698
4699 /*
4700 * bgp_announce_route_timer_expired
4701 *
4702 * Callback that is invoked when the route announcement timer for a
4703 * peer_af expires.
4704 */
4705 static void bgp_announce_route_timer_expired(struct thread *t)
4706 {
4707 struct peer_af *paf;
4708 struct peer *peer;
4709
4710 paf = THREAD_ARG(t);
4711 peer = paf->peer;
4712
4713 if (!peer_established(peer))
4714 return;
4715
4716 if (!peer->afc_nego[paf->afi][paf->safi])
4717 return;
4718
4719 peer_af_announce_route(paf, 1);
4720
4721 /* Notify BGP conditional advertisement scanner percess */
4722 peer->advmap_config_change[paf->afi][paf->safi] = true;
4723 }
4724
4725 /*
4726 * bgp_announce_route
4727 *
4728 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4729 *
4730 * if force is true we will force an update even if the update
4731 * limiting code is attempted to kick in.
4732 */
4733 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
4734 {
4735 struct peer_af *paf;
4736 struct update_subgroup *subgrp;
4737
4738 paf = peer_af_find(peer, afi, safi);
4739 if (!paf)
4740 return;
4741 subgrp = PAF_SUBGRP(paf);
4742
4743 /*
4744 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4745 * or a refresh has already been triggered.
4746 */
4747 if (!subgrp || paf->t_announce_route)
4748 return;
4749
4750 if (force)
4751 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
4752
4753 /*
4754 * Start a timer to stagger/delay the announce. This serves
4755 * two purposes - announcement can potentially be combined for
4756 * multiple peers and the announcement doesn't happen in the
4757 * vty context.
4758 */
4759 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4760 (subgrp->peer_count == 1)
4761 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4762 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4763 &paf->t_announce_route);
4764 }
4765
4766 /*
4767 * Announce routes from all AF tables to a peer.
4768 *
4769 * This should ONLY be called when there is a need to refresh the
4770 * routes to the peer based on a policy change for this peer alone
4771 * or a route refresh request received from the peer.
4772 * The operation will result in splitting the peer from its existing
4773 * subgroups and putting it in new subgroups.
4774 */
4775 void bgp_announce_route_all(struct peer *peer)
4776 {
4777 afi_t afi;
4778 safi_t safi;
4779
4780 FOREACH_AFI_SAFI (afi, safi)
4781 bgp_announce_route(peer, afi, safi, false);
4782 }
4783
4784 /* Flag or unflag bgp_dest to determine whether it should be treated by
4785 * bgp_soft_reconfig_table_task.
4786 * Flag if flag is true. Unflag if flag is false.
4787 */
4788 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
4789 {
4790 struct bgp_dest *dest;
4791 struct bgp_adj_in *ain;
4792
4793 if (!table)
4794 return;
4795
4796 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4797 for (ain = dest->adj_in; ain; ain = ain->next) {
4798 if (ain->peer != NULL)
4799 break;
4800 }
4801 if (flag && ain != NULL && ain->peer != NULL)
4802 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4803 else
4804 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4805 }
4806 }
4807
4808 static int bgp_soft_reconfig_table_update(struct peer *peer,
4809 struct bgp_dest *dest,
4810 struct bgp_adj_in *ain, afi_t afi,
4811 safi_t safi, struct prefix_rd *prd)
4812 {
4813 struct bgp_path_info *pi;
4814 uint32_t num_labels = 0;
4815 mpls_label_t *label_pnt = NULL;
4816 struct bgp_route_evpn evpn;
4817
4818 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4819 if (pi->peer == peer)
4820 break;
4821
4822 if (pi && pi->extra)
4823 num_labels = pi->extra->num_labels;
4824 if (num_labels)
4825 label_pnt = &pi->extra->label[0];
4826 if (pi)
4827 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
4828 sizeof(evpn));
4829 else
4830 memset(&evpn, 0, sizeof(evpn));
4831
4832 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
4833 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
4834 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
4835 &evpn);
4836 }
4837
4838 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4839 struct bgp_table *table,
4840 struct prefix_rd *prd)
4841 {
4842 int ret;
4843 struct bgp_dest *dest;
4844 struct bgp_adj_in *ain;
4845
4846 if (!table)
4847 table = peer->bgp->rib[afi][safi];
4848
4849 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4850 for (ain = dest->adj_in; ain; ain = ain->next) {
4851 if (ain->peer != peer)
4852 continue;
4853
4854 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
4855 afi, safi, prd);
4856
4857 if (ret < 0) {
4858 bgp_dest_unlock_node(dest);
4859 return;
4860 }
4861 }
4862 }
4863
4864 /* Do soft reconfig table per bgp table.
4865 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
4866 * when BGP_NODE_SOFT_RECONFIG is set,
4867 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
4868 * Schedule a new thread to continue the job.
4869 * Without splitting the full job into several part,
4870 * vtysh waits for the job to finish before responding to a BGP command
4871 */
4872 static void bgp_soft_reconfig_table_task(struct thread *thread)
4873 {
4874 uint32_t iter, max_iter;
4875 int ret;
4876 struct bgp_dest *dest;
4877 struct bgp_adj_in *ain;
4878 struct peer *peer;
4879 struct bgp_table *table;
4880 struct prefix_rd *prd;
4881 struct listnode *node, *nnode;
4882
4883 table = THREAD_ARG(thread);
4884 prd = NULL;
4885
4886 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
4887 if (table->soft_reconfig_init) {
4888 /* first call of the function with a new srta structure.
4889 * Don't do any treatment this time on nodes
4890 * in order vtysh to respond quickly
4891 */
4892 max_iter = 0;
4893 }
4894
4895 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
4896 dest = bgp_route_next(dest)) {
4897 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
4898 continue;
4899
4900 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4901
4902 for (ain = dest->adj_in; ain; ain = ain->next) {
4903 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
4904 nnode, peer)) {
4905 if (ain->peer != peer)
4906 continue;
4907
4908 ret = bgp_soft_reconfig_table_update(
4909 peer, dest, ain, table->afi,
4910 table->safi, prd);
4911 iter++;
4912
4913 if (ret < 0) {
4914 bgp_dest_unlock_node(dest);
4915 listnode_delete(
4916 table->soft_reconfig_peers,
4917 peer);
4918 bgp_announce_route(peer, table->afi,
4919 table->safi, false);
4920 if (list_isempty(
4921 table->soft_reconfig_peers)) {
4922 list_delete(
4923 &table->soft_reconfig_peers);
4924 bgp_soft_reconfig_table_flag(
4925 table, false);
4926 return;
4927 }
4928 }
4929 }
4930 }
4931 }
4932
4933 /* we're either starting the initial iteration,
4934 * or we're going to continue an ongoing iteration
4935 */
4936 if (dest || table->soft_reconfig_init) {
4937 table->soft_reconfig_init = false;
4938 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
4939 table, 0, &table->soft_reconfig_thread);
4940 return;
4941 }
4942 /* we're done, clean up the background iteration context info and
4943 schedule route annoucement
4944 */
4945 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
4946 listnode_delete(table->soft_reconfig_peers, peer);
4947 bgp_announce_route(peer, table->afi, table->safi, false);
4948 }
4949
4950 list_delete(&table->soft_reconfig_peers);
4951 }
4952
4953
4954 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
4955 * and peer.
4956 * - bgp cannot be NULL
4957 * - if table and peer are NULL, cancel all threads within the bgp instance
4958 * - if table is NULL and peer is not,
4959 * remove peer in all threads within the bgp instance
4960 * - if peer is NULL, cancel all threads matching table within the bgp instance
4961 */
4962 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
4963 const struct bgp_table *table,
4964 const struct peer *peer)
4965 {
4966 struct peer *npeer;
4967 struct listnode *node, *nnode;
4968 int afi, safi;
4969 struct bgp_table *ntable;
4970
4971 if (!bgp)
4972 return;
4973
4974 FOREACH_AFI_SAFI (afi, safi) {
4975 ntable = bgp->rib[afi][safi];
4976 if (!ntable)
4977 continue;
4978 if (table && table != ntable)
4979 continue;
4980
4981 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
4982 npeer)) {
4983 if (peer && peer != npeer)
4984 continue;
4985 listnode_delete(ntable->soft_reconfig_peers, npeer);
4986 }
4987
4988 if (!ntable->soft_reconfig_peers
4989 || !list_isempty(ntable->soft_reconfig_peers))
4990 continue;
4991
4992 list_delete(&ntable->soft_reconfig_peers);
4993 bgp_soft_reconfig_table_flag(ntable, false);
4994 BGP_TIMER_OFF(ntable->soft_reconfig_thread);
4995 }
4996 }
4997
4998 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4999 {
5000 struct bgp_dest *dest;
5001 struct bgp_table *table;
5002 struct listnode *node, *nnode;
5003 struct peer *npeer;
5004 struct peer_af *paf;
5005
5006 if (!peer_established(peer))
5007 return;
5008
5009 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5010 && (safi != SAFI_EVPN)) {
5011 table = peer->bgp->rib[afi][safi];
5012 if (!table)
5013 return;
5014
5015 table->soft_reconfig_init = true;
5016
5017 if (!table->soft_reconfig_peers)
5018 table->soft_reconfig_peers = list_new();
5019 npeer = NULL;
5020 /* add peer to the table soft_reconfig_peers if not already
5021 * there
5022 */
5023 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5024 npeer)) {
5025 if (peer == npeer)
5026 break;
5027 }
5028 if (peer != npeer)
5029 listnode_add(table->soft_reconfig_peers, peer);
5030
5031 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5032 * on table would start back at the beginning.
5033 */
5034 bgp_soft_reconfig_table_flag(table, true);
5035
5036 if (!table->soft_reconfig_thread)
5037 thread_add_event(bm->master,
5038 bgp_soft_reconfig_table_task, table, 0,
5039 &table->soft_reconfig_thread);
5040 /* Cancel bgp_announce_route_timer_expired threads.
5041 * bgp_announce_route_timer_expired threads have been scheduled
5042 * to announce routes as soon as the soft_reconfigure process
5043 * finishes.
5044 * In this case, soft_reconfigure is also scheduled by using
5045 * a thread but is planned after the
5046 * bgp_announce_route_timer_expired threads. It means that,
5047 * without cancelling the threads, the route announcement task
5048 * would run before the soft reconfiguration one. That would
5049 * useless and would block vtysh during several seconds. Route
5050 * announcements are rescheduled as soon as the soft_reconfigure
5051 * process finishes.
5052 */
5053 paf = peer_af_find(peer, afi, safi);
5054 if (paf)
5055 bgp_stop_announce_route_timer(paf);
5056 } else
5057 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5058 dest = bgp_route_next(dest)) {
5059 table = bgp_dest_get_bgp_table_info(dest);
5060
5061 if (table == NULL)
5062 continue;
5063
5064 const struct prefix *p = bgp_dest_get_prefix(dest);
5065 struct prefix_rd prd;
5066
5067 prd.family = AF_UNSPEC;
5068 prd.prefixlen = 64;
5069 memcpy(&prd.val, p->u.val, 8);
5070
5071 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5072 }
5073 }
5074
5075
5076 struct bgp_clear_node_queue {
5077 struct bgp_dest *dest;
5078 };
5079
5080 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5081 {
5082 struct bgp_clear_node_queue *cnq = data;
5083 struct bgp_dest *dest = cnq->dest;
5084 struct peer *peer = wq->spec.data;
5085 struct bgp_path_info *pi;
5086 struct bgp *bgp;
5087 afi_t afi = bgp_dest_table(dest)->afi;
5088 safi_t safi = bgp_dest_table(dest)->safi;
5089
5090 assert(dest && peer);
5091 bgp = peer->bgp;
5092
5093 /* It is possible that we have multiple paths for a prefix from a peer
5094 * if that peer is using AddPath.
5095 */
5096 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5097 if (pi->peer != peer)
5098 continue;
5099
5100 /* graceful restart STALE flag set. */
5101 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5102 && peer->nsf[afi][safi])
5103 || CHECK_FLAG(peer->af_sflags[afi][safi],
5104 PEER_STATUS_ENHANCED_REFRESH))
5105 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5106 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5107 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5108 else {
5109 /* If this is an EVPN route, process for
5110 * un-import. */
5111 if (safi == SAFI_EVPN)
5112 bgp_evpn_unimport_route(
5113 bgp, afi, safi,
5114 bgp_dest_get_prefix(dest), pi);
5115 /* Handle withdraw for VRF route-leaking and L3VPN */
5116 if (SAFI_UNICAST == safi
5117 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5118 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5119 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5120 bgp, pi);
5121 }
5122 if (SAFI_MPLS_VPN == safi &&
5123 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5124 vpn_leak_to_vrf_withdraw(bgp, pi);
5125 }
5126
5127 bgp_rib_remove(dest, pi, peer, afi, safi);
5128 }
5129 }
5130 return WQ_SUCCESS;
5131 }
5132
5133 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5134 {
5135 struct bgp_clear_node_queue *cnq = data;
5136 struct bgp_dest *dest = cnq->dest;
5137 struct bgp_table *table = bgp_dest_table(dest);
5138
5139 bgp_dest_unlock_node(dest);
5140 bgp_table_unlock(table);
5141 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5142 }
5143
5144 static void bgp_clear_node_complete(struct work_queue *wq)
5145 {
5146 struct peer *peer = wq->spec.data;
5147
5148 /* Tickle FSM to start moving again */
5149 BGP_EVENT_ADD(peer, Clearing_Completed);
5150
5151 peer_unlock(peer); /* bgp_clear_route */
5152 }
5153
5154 static void bgp_clear_node_queue_init(struct peer *peer)
5155 {
5156 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5157
5158 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5159 #undef CLEAR_QUEUE_NAME_LEN
5160
5161 peer->clear_node_queue = work_queue_new(bm->master, wname);
5162 peer->clear_node_queue->spec.hold = 10;
5163 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5164 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5165 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5166 peer->clear_node_queue->spec.max_retries = 0;
5167
5168 /* we only 'lock' this peer reference when the queue is actually active
5169 */
5170 peer->clear_node_queue->spec.data = peer;
5171 }
5172
5173 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5174 struct bgp_table *table)
5175 {
5176 struct bgp_dest *dest;
5177 int force = peer->bgp->process_queue ? 0 : 1;
5178
5179 if (!table)
5180 table = peer->bgp->rib[afi][safi];
5181
5182 /* If still no table => afi/safi isn't configured at all or smth. */
5183 if (!table)
5184 return;
5185
5186 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5187 struct bgp_path_info *pi, *next;
5188 struct bgp_adj_in *ain;
5189 struct bgp_adj_in *ain_next;
5190
5191 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5192 * queued for every clearing peer, regardless of whether it is
5193 * relevant to the peer at hand.
5194 *
5195 * Overview: There are 3 different indices which need to be
5196 * scrubbed, potentially, when a peer is removed:
5197 *
5198 * 1 peer's routes visible via the RIB (ie accepted routes)
5199 * 2 peer's routes visible by the (optional) peer's adj-in index
5200 * 3 other routes visible by the peer's adj-out index
5201 *
5202 * 3 there is no hurry in scrubbing, once the struct peer is
5203 * removed from bgp->peer, we could just GC such deleted peer's
5204 * adj-outs at our leisure.
5205 *
5206 * 1 and 2 must be 'scrubbed' in some way, at least made
5207 * invisible via RIB index before peer session is allowed to be
5208 * brought back up. So one needs to know when such a 'search' is
5209 * complete.
5210 *
5211 * Ideally:
5212 *
5213 * - there'd be a single global queue or a single RIB walker
5214 * - rather than tracking which route_nodes still need to be
5215 * examined on a peer basis, we'd track which peers still
5216 * aren't cleared
5217 *
5218 * Given that our per-peer prefix-counts now should be reliable,
5219 * this may actually be achievable. It doesn't seem to be a huge
5220 * problem at this time,
5221 *
5222 * It is possible that we have multiple paths for a prefix from
5223 * a peer
5224 * if that peer is using AddPath.
5225 */
5226 ain = dest->adj_in;
5227 while (ain) {
5228 ain_next = ain->next;
5229
5230 if (ain->peer == peer)
5231 bgp_adj_in_remove(dest, ain);
5232
5233 ain = ain_next;
5234 }
5235
5236 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5237 next = pi->next;
5238 if (pi->peer != peer)
5239 continue;
5240
5241 if (force)
5242 bgp_path_info_reap(dest, pi);
5243 else {
5244 struct bgp_clear_node_queue *cnq;
5245
5246 /* both unlocked in bgp_clear_node_queue_del */
5247 bgp_table_lock(bgp_dest_table(dest));
5248 bgp_dest_lock_node(dest);
5249 cnq = XCALLOC(
5250 MTYPE_BGP_CLEAR_NODE_QUEUE,
5251 sizeof(struct bgp_clear_node_queue));
5252 cnq->dest = dest;
5253 work_queue_add(peer->clear_node_queue, cnq);
5254 break;
5255 }
5256 }
5257 }
5258 return;
5259 }
5260
5261 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5262 {
5263 struct bgp_dest *dest;
5264 struct bgp_table *table;
5265
5266 if (peer->clear_node_queue == NULL)
5267 bgp_clear_node_queue_init(peer);
5268
5269 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5270 * Idle until it receives a Clearing_Completed event. This protects
5271 * against peers which flap faster than we can we clear, which could
5272 * lead to:
5273 *
5274 * a) race with routes from the new session being installed before
5275 * clear_route_node visits the node (to delete the route of that
5276 * peer)
5277 * b) resource exhaustion, clear_route_node likely leads to an entry
5278 * on the process_main queue. Fast-flapping could cause that queue
5279 * to grow and grow.
5280 */
5281
5282 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5283 * the unlock will happen upon work-queue completion; other wise, the
5284 * unlock happens at the end of this function.
5285 */
5286 if (!peer->clear_node_queue->thread)
5287 peer_lock(peer);
5288
5289 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5290 bgp_clear_route_table(peer, afi, safi, NULL);
5291 else
5292 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5293 dest = bgp_route_next(dest)) {
5294 table = bgp_dest_get_bgp_table_info(dest);
5295 if (!table)
5296 continue;
5297
5298 bgp_clear_route_table(peer, afi, safi, table);
5299 }
5300
5301 /* unlock if no nodes got added to the clear-node-queue. */
5302 if (!peer->clear_node_queue->thread)
5303 peer_unlock(peer);
5304 }
5305
5306 void bgp_clear_route_all(struct peer *peer)
5307 {
5308 afi_t afi;
5309 safi_t safi;
5310
5311 FOREACH_AFI_SAFI (afi, safi)
5312 bgp_clear_route(peer, afi, safi);
5313
5314 #ifdef ENABLE_BGP_VNC
5315 rfapiProcessPeerDown(peer);
5316 #endif
5317 }
5318
5319 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5320 {
5321 struct bgp_table *table;
5322 struct bgp_dest *dest;
5323 struct bgp_adj_in *ain;
5324 struct bgp_adj_in *ain_next;
5325
5326 table = peer->bgp->rib[afi][safi];
5327
5328 /* It is possible that we have multiple paths for a prefix from a peer
5329 * if that peer is using AddPath.
5330 */
5331 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5332 ain = dest->adj_in;
5333
5334 while (ain) {
5335 ain_next = ain->next;
5336
5337 if (ain->peer == peer)
5338 bgp_adj_in_remove(dest, ain);
5339
5340 ain = ain_next;
5341 }
5342 }
5343 }
5344
5345 /* If any of the routes from the peer have been marked with the NO_LLGR
5346 * community, either as sent by the peer, or as the result of a configured
5347 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5348 * operation of [RFC4271].
5349 */
5350 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5351 {
5352 struct bgp_dest *dest;
5353 struct bgp_path_info *pi;
5354 struct bgp_table *table;
5355
5356 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5357 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5358 dest = bgp_route_next(dest)) {
5359 struct bgp_dest *rm;
5360
5361 /* look for neighbor in tables */
5362 table = bgp_dest_get_bgp_table_info(dest);
5363 if (!table)
5364 continue;
5365
5366 for (rm = bgp_table_top(table); rm;
5367 rm = bgp_route_next(rm))
5368 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5369 pi = pi->next) {
5370 if (pi->peer != peer)
5371 continue;
5372 if (CHECK_FLAG(
5373 peer->af_sflags[afi][safi],
5374 PEER_STATUS_LLGR_WAIT) &&
5375 bgp_attr_get_community(pi->attr) &&
5376 !community_include(
5377 bgp_attr_get_community(
5378 pi->attr),
5379 COMMUNITY_NO_LLGR))
5380 continue;
5381 if (!CHECK_FLAG(pi->flags,
5382 BGP_PATH_STALE))
5383 continue;
5384
5385 /*
5386 * If this is VRF leaked route
5387 * process for withdraw.
5388 */
5389 if (pi->sub_type ==
5390 BGP_ROUTE_IMPORTED &&
5391 peer->bgp->inst_type ==
5392 BGP_INSTANCE_TYPE_DEFAULT)
5393 vpn_leak_to_vrf_withdraw(
5394 peer->bgp, pi);
5395
5396 bgp_rib_remove(rm, pi, peer, afi, safi);
5397 break;
5398 }
5399 }
5400 } else {
5401 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5402 dest = bgp_route_next(dest))
5403 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5404 pi = pi->next) {
5405 if (pi->peer != peer)
5406 continue;
5407 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5408 PEER_STATUS_LLGR_WAIT) &&
5409 bgp_attr_get_community(pi->attr) &&
5410 !community_include(
5411 bgp_attr_get_community(pi->attr),
5412 COMMUNITY_NO_LLGR))
5413 continue;
5414 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5415 continue;
5416 if (safi == SAFI_UNICAST &&
5417 (peer->bgp->inst_type ==
5418 BGP_INSTANCE_TYPE_VRF ||
5419 peer->bgp->inst_type ==
5420 BGP_INSTANCE_TYPE_DEFAULT))
5421 vpn_leak_from_vrf_withdraw(
5422 bgp_get_default(), peer->bgp,
5423 pi);
5424
5425 bgp_rib_remove(dest, pi, peer, afi, safi);
5426 break;
5427 }
5428 }
5429 }
5430
5431 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5432 {
5433 struct bgp_dest *dest, *ndest;
5434 struct bgp_path_info *pi;
5435 struct bgp_table *table;
5436
5437 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5438 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5439 dest = bgp_route_next(dest)) {
5440 table = bgp_dest_get_bgp_table_info(dest);
5441 if (!table)
5442 continue;
5443
5444 for (ndest = bgp_table_top(table); ndest;
5445 ndest = bgp_route_next(ndest)) {
5446 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5447 pi = pi->next) {
5448 if (pi->peer != peer)
5449 continue;
5450
5451 if ((CHECK_FLAG(
5452 peer->af_sflags[afi][safi],
5453 PEER_STATUS_ENHANCED_REFRESH))
5454 && !CHECK_FLAG(pi->flags,
5455 BGP_PATH_STALE)
5456 && !CHECK_FLAG(
5457 pi->flags,
5458 BGP_PATH_UNUSEABLE)) {
5459 if (bgp_debug_neighbor_events(
5460 peer))
5461 zlog_debug(
5462 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5463 peer->host,
5464 afi2str(afi),
5465 safi2str(safi),
5466 bgp_dest_get_prefix(
5467 ndest));
5468
5469 bgp_path_info_set_flag(
5470 ndest, pi,
5471 BGP_PATH_STALE);
5472 }
5473 }
5474 }
5475 }
5476 } else {
5477 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5478 dest = bgp_route_next(dest)) {
5479 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5480 pi = pi->next) {
5481 if (pi->peer != peer)
5482 continue;
5483
5484 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5485 PEER_STATUS_ENHANCED_REFRESH))
5486 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5487 && !CHECK_FLAG(pi->flags,
5488 BGP_PATH_UNUSEABLE)) {
5489 if (bgp_debug_neighbor_events(peer))
5490 zlog_debug(
5491 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5492 peer->host,
5493 afi2str(afi),
5494 safi2str(safi),
5495 bgp_dest_get_prefix(
5496 dest));
5497
5498 bgp_path_info_set_flag(dest, pi,
5499 BGP_PATH_STALE);
5500 }
5501 }
5502 }
5503 }
5504 }
5505
5506 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5507 {
5508 if (peer->sort == BGP_PEER_IBGP)
5509 return true;
5510
5511 if (peer->sort == BGP_PEER_EBGP
5512 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5513 || FILTER_LIST_OUT_NAME(filter)
5514 || DISTRIBUTE_OUT_NAME(filter)))
5515 return true;
5516 return false;
5517 }
5518
5519 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5520 {
5521 if (peer->sort == BGP_PEER_IBGP)
5522 return true;
5523
5524 if (peer->sort == BGP_PEER_EBGP
5525 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5526 || FILTER_LIST_IN_NAME(filter)
5527 || DISTRIBUTE_IN_NAME(filter)))
5528 return true;
5529 return false;
5530 }
5531
5532 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5533 safi_t safi)
5534 {
5535 struct bgp_dest *dest;
5536 struct bgp_path_info *pi;
5537 struct bgp_path_info *next;
5538
5539 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5540 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5541 const struct prefix *p = bgp_dest_get_prefix(dest);
5542
5543 next = pi->next;
5544
5545 /* Unimport EVPN routes from VRFs */
5546 if (safi == SAFI_EVPN)
5547 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5548 SAFI_EVPN, p, pi);
5549
5550 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5551 && pi->type == ZEBRA_ROUTE_BGP
5552 && (pi->sub_type == BGP_ROUTE_NORMAL
5553 || pi->sub_type == BGP_ROUTE_AGGREGATE
5554 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5555
5556 if (bgp_fibupd_safi(safi))
5557 bgp_zebra_withdraw(p, pi, bgp, safi);
5558 }
5559
5560 bgp_path_info_reap(dest, pi);
5561 }
5562 }
5563
5564 /* Delete all kernel routes. */
5565 void bgp_cleanup_routes(struct bgp *bgp)
5566 {
5567 afi_t afi;
5568 struct bgp_dest *dest;
5569 struct bgp_table *table;
5570
5571 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5572 if (afi == AFI_L2VPN)
5573 continue;
5574 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5575 SAFI_UNICAST);
5576 /*
5577 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5578 */
5579 if (afi != AFI_L2VPN) {
5580 safi_t safi;
5581 safi = SAFI_MPLS_VPN;
5582 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5583 dest = bgp_route_next(dest)) {
5584 table = bgp_dest_get_bgp_table_info(dest);
5585 if (table != NULL) {
5586 bgp_cleanup_table(bgp, table, safi);
5587 bgp_table_finish(&table);
5588 bgp_dest_set_bgp_table_info(dest, NULL);
5589 bgp_dest_unlock_node(dest);
5590 }
5591 }
5592 safi = SAFI_ENCAP;
5593 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5594 dest = bgp_route_next(dest)) {
5595 table = bgp_dest_get_bgp_table_info(dest);
5596 if (table != NULL) {
5597 bgp_cleanup_table(bgp, table, safi);
5598 bgp_table_finish(&table);
5599 bgp_dest_set_bgp_table_info(dest, NULL);
5600 bgp_dest_unlock_node(dest);
5601 }
5602 }
5603 }
5604 }
5605 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5606 dest = bgp_route_next(dest)) {
5607 table = bgp_dest_get_bgp_table_info(dest);
5608 if (table != NULL) {
5609 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5610 bgp_table_finish(&table);
5611 bgp_dest_set_bgp_table_info(dest, NULL);
5612 bgp_dest_unlock_node(dest);
5613 }
5614 }
5615 }
5616
5617 void bgp_reset(void)
5618 {
5619 vty_reset();
5620 bgp_zclient_reset();
5621 access_list_reset();
5622 prefix_list_reset();
5623 }
5624
5625 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5626 {
5627 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5628 && CHECK_FLAG(peer->af_cap[afi][safi],
5629 PEER_CAP_ADDPATH_AF_TX_RCV));
5630 }
5631
5632 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5633 value. */
5634 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5635 struct bgp_nlri *packet)
5636 {
5637 uint8_t *pnt;
5638 uint8_t *lim;
5639 struct prefix p;
5640 int psize;
5641 int ret;
5642 afi_t afi;
5643 safi_t safi;
5644 bool addpath_capable;
5645 uint32_t addpath_id;
5646
5647 pnt = packet->nlri;
5648 lim = pnt + packet->length;
5649 afi = packet->afi;
5650 safi = packet->safi;
5651 addpath_id = 0;
5652 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5653
5654 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5655 syntactic validity. If the field is syntactically incorrect,
5656 then the Error Subcode is set to Invalid Network Field. */
5657 for (; pnt < lim; pnt += psize) {
5658 /* Clear prefix structure. */
5659 memset(&p, 0, sizeof(struct prefix));
5660
5661 if (addpath_capable) {
5662
5663 /* When packet overflow occurs return immediately. */
5664 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5665 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5666
5667 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5668 addpath_id = ntohl(addpath_id);
5669 pnt += BGP_ADDPATH_ID_LEN;
5670 }
5671
5672 /* Fetch prefix length. */
5673 p.prefixlen = *pnt++;
5674 /* afi/safi validity already verified by caller,
5675 * bgp_update_receive */
5676 p.family = afi2family(afi);
5677
5678 /* Prefix length check. */
5679 if (p.prefixlen > prefix_blen(&p) * 8) {
5680 flog_err(
5681 EC_BGP_UPDATE_RCV,
5682 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5683 peer->host, p.prefixlen, packet->afi);
5684 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5685 }
5686
5687 /* Packet size overflow check. */
5688 psize = PSIZE(p.prefixlen);
5689
5690 /* When packet overflow occur return immediately. */
5691 if (pnt + psize > lim) {
5692 flog_err(
5693 EC_BGP_UPDATE_RCV,
5694 "%s [Error] Update packet error (prefix length %d overflows packet)",
5695 peer->host, p.prefixlen);
5696 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5697 }
5698
5699 /* Defensive coding, double-check the psize fits in a struct
5700 * prefix */
5701 if (psize > (ssize_t)sizeof(p.u)) {
5702 flog_err(
5703 EC_BGP_UPDATE_RCV,
5704 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5705 peer->host, p.prefixlen, sizeof(p.u));
5706 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5707 }
5708
5709 /* Fetch prefix from NLRI packet. */
5710 memcpy(p.u.val, pnt, psize);
5711
5712 /* Check address. */
5713 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5714 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5715 /* From RFC4271 Section 6.3:
5716 *
5717 * If a prefix in the NLRI field is semantically
5718 * incorrect
5719 * (e.g., an unexpected multicast IP address),
5720 * an error SHOULD
5721 * be logged locally, and the prefix SHOULD be
5722 * ignored.
5723 */
5724 flog_err(
5725 EC_BGP_UPDATE_RCV,
5726 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5727 peer->host, &p.u.prefix4);
5728 continue;
5729 }
5730 }
5731
5732 /* Check address. */
5733 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5734 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5735 flog_err(
5736 EC_BGP_UPDATE_RCV,
5737 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
5738 peer->host, &p.u.prefix6);
5739
5740 continue;
5741 }
5742 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5743 flog_err(
5744 EC_BGP_UPDATE_RCV,
5745 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
5746 peer->host, &p.u.prefix6);
5747
5748 continue;
5749 }
5750 }
5751
5752 /* Normal process. */
5753 if (attr)
5754 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5755 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5756 NULL, NULL, 0, 0, NULL);
5757 else
5758 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5759 safi, ZEBRA_ROUTE_BGP,
5760 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5761 NULL);
5762
5763 /* Do not send BGP notification twice when maximum-prefix count
5764 * overflow. */
5765 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5766 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5767
5768 /* Address family configuration mismatch. */
5769 if (ret < 0)
5770 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5771 }
5772
5773 /* Packet length consistency check. */
5774 if (pnt != lim) {
5775 flog_err(
5776 EC_BGP_UPDATE_RCV,
5777 "%s [Error] Update packet error (prefix length mismatch with total length)",
5778 peer->host);
5779 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5780 }
5781
5782 return BGP_NLRI_PARSE_OK;
5783 }
5784
5785 static struct bgp_static *bgp_static_new(void)
5786 {
5787 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5788 }
5789
5790 static void bgp_static_free(struct bgp_static *bgp_static)
5791 {
5792 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5793 route_map_counter_decrement(bgp_static->rmap.map);
5794
5795 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5796 XFREE(MTYPE_BGP_STATIC, bgp_static);
5797 }
5798
5799 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5800 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5801 {
5802 struct bgp_dest *dest;
5803 struct bgp_path_info *pi;
5804 struct bgp_path_info *new;
5805 struct bgp_path_info rmap_path;
5806 struct attr attr;
5807 struct attr *attr_new;
5808 route_map_result_t ret;
5809 #ifdef ENABLE_BGP_VNC
5810 int vnc_implicit_withdraw = 0;
5811 #endif
5812
5813 assert(bgp_static);
5814
5815 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5816
5817 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5818
5819 attr.nexthop = bgp_static->igpnexthop;
5820 attr.med = bgp_static->igpmetric;
5821 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5822
5823 if (bgp_static->atomic)
5824 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5825
5826 /* Store label index, if required. */
5827 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5828 attr.label_index = bgp_static->label_index;
5829 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5830 }
5831
5832 /* Apply route-map. */
5833 if (bgp_static->rmap.name) {
5834 struct attr attr_tmp = attr;
5835
5836 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5837 rmap_path.peer = bgp->peer_self;
5838 rmap_path.attr = &attr_tmp;
5839
5840 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5841
5842 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5843
5844 bgp->peer_self->rmap_type = 0;
5845
5846 if (ret == RMAP_DENYMATCH) {
5847 /* Free uninterned attribute. */
5848 bgp_attr_flush(&attr_tmp);
5849
5850 /* Unintern original. */
5851 aspath_unintern(&attr.aspath);
5852 bgp_static_withdraw(bgp, p, afi, safi);
5853 return;
5854 }
5855
5856 if (bgp_in_graceful_shutdown(bgp))
5857 bgp_attr_add_gshut_community(&attr_tmp);
5858
5859 attr_new = bgp_attr_intern(&attr_tmp);
5860 } else {
5861
5862 if (bgp_in_graceful_shutdown(bgp))
5863 bgp_attr_add_gshut_community(&attr);
5864
5865 attr_new = bgp_attr_intern(&attr);
5866 }
5867
5868 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5869 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5870 && pi->sub_type == BGP_ROUTE_STATIC)
5871 break;
5872
5873 if (pi) {
5874 if (attrhash_cmp(pi->attr, attr_new)
5875 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5876 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5877 bgp_dest_unlock_node(dest);
5878 bgp_attr_unintern(&attr_new);
5879 aspath_unintern(&attr.aspath);
5880 return;
5881 } else {
5882 /* The attribute is changed. */
5883 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5884
5885 /* Rewrite BGP route information. */
5886 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5887 bgp_path_info_restore(dest, pi);
5888 else
5889 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5890 #ifdef ENABLE_BGP_VNC
5891 if ((afi == AFI_IP || afi == AFI_IP6)
5892 && (safi == SAFI_UNICAST)) {
5893 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5894 /*
5895 * Implicit withdraw case.
5896 * We have to do this before pi is
5897 * changed
5898 */
5899 ++vnc_implicit_withdraw;
5900 vnc_import_bgp_del_route(bgp, p, pi);
5901 vnc_import_bgp_exterior_del_route(
5902 bgp, p, pi);
5903 }
5904 }
5905 #endif
5906 bgp_attr_unintern(&pi->attr);
5907 pi->attr = attr_new;
5908 pi->uptime = bgp_clock();
5909 #ifdef ENABLE_BGP_VNC
5910 if ((afi == AFI_IP || afi == AFI_IP6)
5911 && (safi == SAFI_UNICAST)) {
5912 if (vnc_implicit_withdraw) {
5913 vnc_import_bgp_add_route(bgp, p, pi);
5914 vnc_import_bgp_exterior_add_route(
5915 bgp, p, pi);
5916 }
5917 }
5918 #endif
5919
5920 /* Nexthop reachability check. */
5921 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5922 && (safi == SAFI_UNICAST
5923 || safi == SAFI_LABELED_UNICAST)) {
5924
5925 struct bgp *bgp_nexthop = bgp;
5926
5927 if (pi->extra && pi->extra->bgp_orig)
5928 bgp_nexthop = pi->extra->bgp_orig;
5929
5930 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5931 afi, safi, pi, NULL,
5932 0, p))
5933 bgp_path_info_set_flag(dest, pi,
5934 BGP_PATH_VALID);
5935 else {
5936 if (BGP_DEBUG(nht, NHT)) {
5937 char buf1[INET6_ADDRSTRLEN];
5938 inet_ntop(p->family,
5939 &p->u.prefix, buf1,
5940 INET6_ADDRSTRLEN);
5941 zlog_debug(
5942 "%s(%s): Route not in table, not advertising",
5943 __func__, buf1);
5944 }
5945 bgp_path_info_unset_flag(
5946 dest, pi, BGP_PATH_VALID);
5947 }
5948 } else {
5949 /* Delete the NHT structure if any, if we're
5950 * toggling between
5951 * enabling/disabling import check. We
5952 * deregister the route
5953 * from NHT to avoid overloading NHT and the
5954 * process interaction
5955 */
5956 bgp_unlink_nexthop(pi);
5957 bgp_path_info_set_flag(dest, pi,
5958 BGP_PATH_VALID);
5959 }
5960 /* Process change. */
5961 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5962 bgp_process(bgp, dest, afi, safi);
5963
5964 if (SAFI_UNICAST == safi
5965 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5966 || bgp->inst_type
5967 == BGP_INSTANCE_TYPE_DEFAULT)) {
5968 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5969 pi);
5970 }
5971
5972 bgp_dest_unlock_node(dest);
5973 aspath_unintern(&attr.aspath);
5974 return;
5975 }
5976 }
5977
5978 /* Make new BGP info. */
5979 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5980 attr_new, dest);
5981 /* Nexthop reachability check. */
5982 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5983 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5984 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
5985 p))
5986 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5987 else {
5988 if (BGP_DEBUG(nht, NHT)) {
5989 char buf1[INET6_ADDRSTRLEN];
5990 inet_ntop(p->family, &p->u.prefix, buf1,
5991 INET6_ADDRSTRLEN);
5992 zlog_debug(
5993 "%s(%s): Route not in table, not advertising",
5994 __func__, buf1);
5995 }
5996 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5997 }
5998 } else {
5999 /* Delete the NHT structure if any, if we're toggling between
6000 * enabling/disabling import check. We deregister the route
6001 * from NHT to avoid overloading NHT and the process interaction
6002 */
6003 bgp_unlink_nexthop(new);
6004
6005 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6006 }
6007
6008 /* Aggregate address increment. */
6009 bgp_aggregate_increment(bgp, p, new, afi, safi);
6010
6011 /* Register new BGP information. */
6012 bgp_path_info_add(dest, new);
6013
6014 /* route_node_get lock */
6015 bgp_dest_unlock_node(dest);
6016
6017 /* Process change. */
6018 bgp_process(bgp, dest, afi, safi);
6019
6020 if (SAFI_UNICAST == safi
6021 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6022 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6023 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6024 }
6025
6026 /* Unintern original. */
6027 aspath_unintern(&attr.aspath);
6028 }
6029
6030 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6031 safi_t safi)
6032 {
6033 struct bgp_dest *dest;
6034 struct bgp_path_info *pi;
6035
6036 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6037
6038 /* Check selected route and self inserted route. */
6039 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6040 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6041 && pi->sub_type == BGP_ROUTE_STATIC)
6042 break;
6043
6044 /* Withdraw static BGP route from routing table. */
6045 if (pi) {
6046 if (SAFI_UNICAST == safi
6047 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6048 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6049 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6050 }
6051 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6052 bgp_unlink_nexthop(pi);
6053 bgp_path_info_delete(dest, pi);
6054 bgp_process(bgp, dest, afi, safi);
6055 }
6056
6057 /* Unlock bgp_node_lookup. */
6058 bgp_dest_unlock_node(dest);
6059 }
6060
6061 /*
6062 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6063 */
6064 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6065 afi_t afi, safi_t safi,
6066 struct prefix_rd *prd)
6067 {
6068 struct bgp_dest *dest;
6069 struct bgp_path_info *pi;
6070
6071 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6072
6073 /* Check selected route and self inserted route. */
6074 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6075 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6076 && pi->sub_type == BGP_ROUTE_STATIC)
6077 break;
6078
6079 /* Withdraw static BGP route from routing table. */
6080 if (pi) {
6081 #ifdef ENABLE_BGP_VNC
6082 rfapiProcessWithdraw(
6083 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6084 1); /* Kill, since it is an administrative change */
6085 #endif
6086 if (SAFI_MPLS_VPN == safi
6087 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6088 vpn_leak_to_vrf_withdraw(bgp, pi);
6089 }
6090 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6091 bgp_path_info_delete(dest, pi);
6092 bgp_process(bgp, dest, afi, safi);
6093 }
6094
6095 /* Unlock bgp_node_lookup. */
6096 bgp_dest_unlock_node(dest);
6097 }
6098
6099 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6100 struct bgp_static *bgp_static, afi_t afi,
6101 safi_t safi)
6102 {
6103 struct bgp_dest *dest;
6104 struct bgp_path_info *new;
6105 struct attr *attr_new;
6106 struct attr attr = {0};
6107 struct bgp_path_info *pi;
6108 #ifdef ENABLE_BGP_VNC
6109 mpls_label_t label = 0;
6110 #endif
6111 uint32_t num_labels = 0;
6112
6113 assert(bgp_static);
6114
6115 if (bgp_static->label != MPLS_INVALID_LABEL)
6116 num_labels = 1;
6117 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6118 &bgp_static->prd);
6119
6120 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
6121
6122 attr.nexthop = bgp_static->igpnexthop;
6123 attr.med = bgp_static->igpmetric;
6124 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6125
6126 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6127 || (safi == SAFI_ENCAP)) {
6128 if (afi == AFI_IP) {
6129 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6130 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6131 }
6132 }
6133 if (afi == AFI_L2VPN) {
6134 if (bgp_static->gatewayIp.family == AF_INET) {
6135 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6136 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6137 &bgp_static->gatewayIp.u.prefix4,
6138 IPV4_MAX_BYTELEN);
6139 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6140 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6141 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6142 &bgp_static->gatewayIp.u.prefix6,
6143 IPV6_MAX_BYTELEN);
6144 }
6145 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6146 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6147 struct bgp_encap_type_vxlan bet;
6148 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
6149 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6150 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6151 }
6152 if (bgp_static->router_mac) {
6153 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6154 }
6155 }
6156 /* Apply route-map. */
6157 if (bgp_static->rmap.name) {
6158 struct attr attr_tmp = attr;
6159 struct bgp_path_info rmap_path;
6160 route_map_result_t ret;
6161
6162 rmap_path.peer = bgp->peer_self;
6163 rmap_path.attr = &attr_tmp;
6164
6165 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6166
6167 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6168
6169 bgp->peer_self->rmap_type = 0;
6170
6171 if (ret == RMAP_DENYMATCH) {
6172 /* Free uninterned attribute. */
6173 bgp_attr_flush(&attr_tmp);
6174
6175 /* Unintern original. */
6176 aspath_unintern(&attr.aspath);
6177 bgp_static_withdraw_safi(bgp, p, afi, safi,
6178 &bgp_static->prd);
6179 return;
6180 }
6181
6182 attr_new = bgp_attr_intern(&attr_tmp);
6183 } else {
6184 attr_new = bgp_attr_intern(&attr);
6185 }
6186
6187 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6188 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6189 && pi->sub_type == BGP_ROUTE_STATIC)
6190 break;
6191
6192 if (pi) {
6193 if (attrhash_cmp(pi->attr, attr_new)
6194 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6195 bgp_dest_unlock_node(dest);
6196 bgp_attr_unintern(&attr_new);
6197 aspath_unintern(&attr.aspath);
6198 return;
6199 } else {
6200 /* The attribute is changed. */
6201 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6202
6203 /* Rewrite BGP route information. */
6204 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6205 bgp_path_info_restore(dest, pi);
6206 else
6207 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6208 bgp_attr_unintern(&pi->attr);
6209 pi->attr = attr_new;
6210 pi->uptime = bgp_clock();
6211 #ifdef ENABLE_BGP_VNC
6212 if (pi->extra)
6213 label = decode_label(&pi->extra->label[0]);
6214 #endif
6215
6216 /* Process change. */
6217 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6218 bgp_process(bgp, dest, afi, safi);
6219
6220 if (SAFI_MPLS_VPN == safi
6221 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6222 vpn_leak_to_vrf_update(bgp, pi);
6223 }
6224 #ifdef ENABLE_BGP_VNC
6225 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6226 pi->attr, afi, safi, pi->type,
6227 pi->sub_type, &label);
6228 #endif
6229 bgp_dest_unlock_node(dest);
6230 aspath_unintern(&attr.aspath);
6231 return;
6232 }
6233 }
6234
6235
6236 /* Make new BGP info. */
6237 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6238 attr_new, dest);
6239 SET_FLAG(new->flags, BGP_PATH_VALID);
6240 bgp_path_info_extra_get(new);
6241 if (num_labels) {
6242 new->extra->label[0] = bgp_static->label;
6243 new->extra->num_labels = num_labels;
6244 }
6245 #ifdef ENABLE_BGP_VNC
6246 label = decode_label(&bgp_static->label);
6247 #endif
6248
6249 /* Aggregate address increment. */
6250 bgp_aggregate_increment(bgp, p, new, afi, safi);
6251
6252 /* Register new BGP information. */
6253 bgp_path_info_add(dest, new);
6254 /* route_node_get lock */
6255 bgp_dest_unlock_node(dest);
6256
6257 /* Process change. */
6258 bgp_process(bgp, dest, afi, safi);
6259
6260 if (SAFI_MPLS_VPN == safi
6261 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6262 vpn_leak_to_vrf_update(bgp, new);
6263 }
6264 #ifdef ENABLE_BGP_VNC
6265 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6266 safi, new->type, new->sub_type, &label);
6267 #endif
6268
6269 /* Unintern original. */
6270 aspath_unintern(&attr.aspath);
6271 }
6272
6273 /* Configure static BGP network. When user don't run zebra, static
6274 route should be installed as valid. */
6275 static int bgp_static_set(struct vty *vty, const char *negate,
6276 const char *ip_str, afi_t afi, safi_t safi,
6277 const char *rmap, int backdoor, uint32_t label_index)
6278 {
6279 VTY_DECLVAR_CONTEXT(bgp, bgp);
6280 int ret;
6281 struct prefix p;
6282 struct bgp_static *bgp_static;
6283 struct bgp_dest *dest;
6284 uint8_t need_update = 0;
6285
6286 /* Convert IP prefix string to struct prefix. */
6287 ret = str2prefix(ip_str, &p);
6288 if (!ret) {
6289 vty_out(vty, "%% Malformed prefix\n");
6290 return CMD_WARNING_CONFIG_FAILED;
6291 }
6292 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6293 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6294 return CMD_WARNING_CONFIG_FAILED;
6295 }
6296
6297 apply_mask(&p);
6298
6299 if (negate) {
6300
6301 /* Set BGP static route configuration. */
6302 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6303
6304 if (!dest) {
6305 vty_out(vty, "%% Can't find static route specified\n");
6306 return CMD_WARNING_CONFIG_FAILED;
6307 }
6308
6309 bgp_static = bgp_dest_get_bgp_static_info(dest);
6310
6311 if ((label_index != BGP_INVALID_LABEL_INDEX)
6312 && (label_index != bgp_static->label_index)) {
6313 vty_out(vty,
6314 "%% label-index doesn't match static route\n");
6315 bgp_dest_unlock_node(dest);
6316 return CMD_WARNING_CONFIG_FAILED;
6317 }
6318
6319 if ((rmap && bgp_static->rmap.name)
6320 && strcmp(rmap, bgp_static->rmap.name)) {
6321 vty_out(vty,
6322 "%% route-map name doesn't match static route\n");
6323 bgp_dest_unlock_node(dest);
6324 return CMD_WARNING_CONFIG_FAILED;
6325 }
6326
6327 /* Update BGP RIB. */
6328 if (!bgp_static->backdoor)
6329 bgp_static_withdraw(bgp, &p, afi, safi);
6330
6331 /* Clear configuration. */
6332 bgp_static_free(bgp_static);
6333 bgp_dest_set_bgp_static_info(dest, NULL);
6334 bgp_dest_unlock_node(dest);
6335 bgp_dest_unlock_node(dest);
6336 } else {
6337
6338 /* Set BGP static route configuration. */
6339 dest = bgp_node_get(bgp->route[afi][safi], &p);
6340 bgp_static = bgp_dest_get_bgp_static_info(dest);
6341 if (bgp_static) {
6342 /* Configuration change. */
6343 /* Label index cannot be changed. */
6344 if (bgp_static->label_index != label_index) {
6345 vty_out(vty, "%% cannot change label-index\n");
6346 return CMD_WARNING_CONFIG_FAILED;
6347 }
6348
6349 /* Check previous routes are installed into BGP. */
6350 if (bgp_static->valid
6351 && bgp_static->backdoor != backdoor)
6352 need_update = 1;
6353
6354 bgp_static->backdoor = backdoor;
6355
6356 if (rmap) {
6357 XFREE(MTYPE_ROUTE_MAP_NAME,
6358 bgp_static->rmap.name);
6359 route_map_counter_decrement(
6360 bgp_static->rmap.map);
6361 bgp_static->rmap.name =
6362 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6363 bgp_static->rmap.map =
6364 route_map_lookup_by_name(rmap);
6365 route_map_counter_increment(
6366 bgp_static->rmap.map);
6367 } else {
6368 XFREE(MTYPE_ROUTE_MAP_NAME,
6369 bgp_static->rmap.name);
6370 route_map_counter_decrement(
6371 bgp_static->rmap.map);
6372 bgp_static->rmap.map = NULL;
6373 bgp_static->valid = 0;
6374 }
6375 bgp_dest_unlock_node(dest);
6376 } else {
6377 /* New configuration. */
6378 bgp_static = bgp_static_new();
6379 bgp_static->backdoor = backdoor;
6380 bgp_static->valid = 0;
6381 bgp_static->igpmetric = 0;
6382 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6383 bgp_static->label_index = label_index;
6384
6385 if (rmap) {
6386 XFREE(MTYPE_ROUTE_MAP_NAME,
6387 bgp_static->rmap.name);
6388 route_map_counter_decrement(
6389 bgp_static->rmap.map);
6390 bgp_static->rmap.name =
6391 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6392 bgp_static->rmap.map =
6393 route_map_lookup_by_name(rmap);
6394 route_map_counter_increment(
6395 bgp_static->rmap.map);
6396 }
6397 bgp_dest_set_bgp_static_info(dest, bgp_static);
6398 }
6399
6400 bgp_static->valid = 1;
6401 if (need_update)
6402 bgp_static_withdraw(bgp, &p, afi, safi);
6403
6404 if (!bgp_static->backdoor)
6405 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6406 }
6407
6408 return CMD_SUCCESS;
6409 }
6410
6411 void bgp_static_add(struct bgp *bgp)
6412 {
6413 afi_t afi;
6414 safi_t safi;
6415 struct bgp_dest *dest;
6416 struct bgp_dest *rm;
6417 struct bgp_table *table;
6418 struct bgp_static *bgp_static;
6419
6420 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6421 FOREACH_AFI_SAFI (afi, safi)
6422 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6423 dest = bgp_route_next(dest)) {
6424 if (!bgp_dest_has_bgp_path_info_data(dest))
6425 continue;
6426
6427 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6428 || (safi == SAFI_EVPN)) {
6429 table = bgp_dest_get_bgp_table_info(dest);
6430
6431 for (rm = bgp_table_top(table); rm;
6432 rm = bgp_route_next(rm)) {
6433 bgp_static =
6434 bgp_dest_get_bgp_static_info(
6435 rm);
6436 bgp_static_update_safi(
6437 bgp, bgp_dest_get_prefix(rm),
6438 bgp_static, afi, safi);
6439 }
6440 } else {
6441 bgp_static_update(
6442 bgp, bgp_dest_get_prefix(dest),
6443 bgp_dest_get_bgp_static_info(dest), afi,
6444 safi);
6445 }
6446 }
6447 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6448 }
6449
6450 /* Called from bgp_delete(). Delete all static routes from the BGP
6451 instance. */
6452 void bgp_static_delete(struct bgp *bgp)
6453 {
6454 afi_t afi;
6455 safi_t safi;
6456 struct bgp_dest *dest;
6457 struct bgp_dest *rm;
6458 struct bgp_table *table;
6459 struct bgp_static *bgp_static;
6460
6461 FOREACH_AFI_SAFI (afi, safi)
6462 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6463 dest = bgp_route_next(dest)) {
6464 if (!bgp_dest_has_bgp_path_info_data(dest))
6465 continue;
6466
6467 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6468 || (safi == SAFI_EVPN)) {
6469 table = bgp_dest_get_bgp_table_info(dest);
6470
6471 for (rm = bgp_table_top(table); rm;
6472 rm = bgp_route_next(rm)) {
6473 bgp_static =
6474 bgp_dest_get_bgp_static_info(
6475 rm);
6476 if (!bgp_static)
6477 continue;
6478
6479 bgp_static_withdraw_safi(
6480 bgp, bgp_dest_get_prefix(rm),
6481 AFI_IP, safi,
6482 (struct prefix_rd *)
6483 bgp_dest_get_prefix(
6484 dest));
6485 bgp_static_free(bgp_static);
6486 bgp_dest_set_bgp_static_info(rm,
6487 NULL);
6488 bgp_dest_unlock_node(rm);
6489 }
6490 } else {
6491 bgp_static = bgp_dest_get_bgp_static_info(dest);
6492 bgp_static_withdraw(bgp,
6493 bgp_dest_get_prefix(dest),
6494 afi, safi);
6495 bgp_static_free(bgp_static);
6496 bgp_dest_set_bgp_static_info(dest, NULL);
6497 bgp_dest_unlock_node(dest);
6498 }
6499 }
6500 }
6501
6502 void bgp_static_redo_import_check(struct bgp *bgp)
6503 {
6504 afi_t afi;
6505 safi_t safi;
6506 struct bgp_dest *dest;
6507 struct bgp_dest *rm;
6508 struct bgp_table *table;
6509 struct bgp_static *bgp_static;
6510
6511 /* Use this flag to force reprocessing of the route */
6512 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6513 FOREACH_AFI_SAFI (afi, safi) {
6514 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6515 dest = bgp_route_next(dest)) {
6516 if (!bgp_dest_has_bgp_path_info_data(dest))
6517 continue;
6518
6519 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6520 || (safi == SAFI_EVPN)) {
6521 table = bgp_dest_get_bgp_table_info(dest);
6522
6523 for (rm = bgp_table_top(table); rm;
6524 rm = bgp_route_next(rm)) {
6525 bgp_static =
6526 bgp_dest_get_bgp_static_info(
6527 rm);
6528 bgp_static_update_safi(
6529 bgp, bgp_dest_get_prefix(rm),
6530 bgp_static, afi, safi);
6531 }
6532 } else {
6533 bgp_static = bgp_dest_get_bgp_static_info(dest);
6534 bgp_static_update(bgp,
6535 bgp_dest_get_prefix(dest),
6536 bgp_static, afi, safi);
6537 }
6538 }
6539 }
6540 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6541 }
6542
6543 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6544 safi_t safi)
6545 {
6546 struct bgp_table *table;
6547 struct bgp_dest *dest;
6548 struct bgp_path_info *pi;
6549
6550 /* Do not install the aggregate route if BGP is in the
6551 * process of termination.
6552 */
6553 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6554 || (bgp->peer_self == NULL))
6555 return;
6556
6557 table = bgp->rib[afi][safi];
6558 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6559 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6560 if (pi->peer == bgp->peer_self
6561 && ((pi->type == ZEBRA_ROUTE_BGP
6562 && pi->sub_type == BGP_ROUTE_STATIC)
6563 || (pi->type != ZEBRA_ROUTE_BGP
6564 && pi->sub_type
6565 == BGP_ROUTE_REDISTRIBUTE))) {
6566 bgp_aggregate_decrement(
6567 bgp, bgp_dest_get_prefix(dest), pi, afi,
6568 safi);
6569 bgp_unlink_nexthop(pi);
6570 bgp_path_info_delete(dest, pi);
6571 bgp_process(bgp, dest, afi, safi);
6572 }
6573 }
6574 }
6575 }
6576
6577 /*
6578 * Purge all networks and redistributed routes from routing table.
6579 * Invoked upon the instance going down.
6580 */
6581 void bgp_purge_static_redist_routes(struct bgp *bgp)
6582 {
6583 afi_t afi;
6584 safi_t safi;
6585
6586 FOREACH_AFI_SAFI (afi, safi)
6587 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6588 }
6589
6590 /*
6591 * gpz 110624
6592 * Currently this is used to set static routes for VPN and ENCAP.
6593 * I think it can probably be factored with bgp_static_set.
6594 */
6595 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6596 const char *ip_str, const char *rd_str,
6597 const char *label_str, const char *rmap_str,
6598 int evpn_type, const char *esi, const char *gwip,
6599 const char *ethtag, const char *routermac)
6600 {
6601 VTY_DECLVAR_CONTEXT(bgp, bgp);
6602 int ret;
6603 struct prefix p;
6604 struct prefix_rd prd;
6605 struct bgp_dest *pdest;
6606 struct bgp_dest *dest;
6607 struct bgp_table *table;
6608 struct bgp_static *bgp_static;
6609 mpls_label_t label = MPLS_INVALID_LABEL;
6610 struct prefix gw_ip;
6611
6612 /* validate ip prefix */
6613 ret = str2prefix(ip_str, &p);
6614 if (!ret) {
6615 vty_out(vty, "%% Malformed prefix\n");
6616 return CMD_WARNING_CONFIG_FAILED;
6617 }
6618 apply_mask(&p);
6619 if ((afi == AFI_L2VPN)
6620 && (bgp_build_evpn_prefix(evpn_type,
6621 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6622 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6623 return CMD_WARNING_CONFIG_FAILED;
6624 }
6625
6626 ret = str2prefix_rd(rd_str, &prd);
6627 if (!ret) {
6628 vty_out(vty, "%% Malformed rd\n");
6629 return CMD_WARNING_CONFIG_FAILED;
6630 }
6631
6632 if (label_str) {
6633 unsigned long label_val;
6634 label_val = strtoul(label_str, NULL, 10);
6635 encode_label(label_val, &label);
6636 }
6637
6638 if (safi == SAFI_EVPN) {
6639 if (esi && str2esi(esi, NULL) == 0) {
6640 vty_out(vty, "%% Malformed ESI\n");
6641 return CMD_WARNING_CONFIG_FAILED;
6642 }
6643 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6644 vty_out(vty, "%% Malformed Router MAC\n");
6645 return CMD_WARNING_CONFIG_FAILED;
6646 }
6647 if (gwip) {
6648 memset(&gw_ip, 0, sizeof(struct prefix));
6649 ret = str2prefix(gwip, &gw_ip);
6650 if (!ret) {
6651 vty_out(vty, "%% Malformed GatewayIp\n");
6652 return CMD_WARNING_CONFIG_FAILED;
6653 }
6654 if ((gw_ip.family == AF_INET
6655 && is_evpn_prefix_ipaddr_v6(
6656 (struct prefix_evpn *)&p))
6657 || (gw_ip.family == AF_INET6
6658 && is_evpn_prefix_ipaddr_v4(
6659 (struct prefix_evpn *)&p))) {
6660 vty_out(vty,
6661 "%% GatewayIp family differs with IP prefix\n");
6662 return CMD_WARNING_CONFIG_FAILED;
6663 }
6664 }
6665 }
6666 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6667 if (!bgp_dest_has_bgp_path_info_data(pdest))
6668 bgp_dest_set_bgp_table_info(pdest,
6669 bgp_table_init(bgp, afi, safi));
6670 table = bgp_dest_get_bgp_table_info(pdest);
6671
6672 dest = bgp_node_get(table, &p);
6673
6674 if (bgp_dest_has_bgp_path_info_data(dest)) {
6675 vty_out(vty, "%% Same network configuration exists\n");
6676 bgp_dest_unlock_node(dest);
6677 } else {
6678 /* New configuration. */
6679 bgp_static = bgp_static_new();
6680 bgp_static->backdoor = 0;
6681 bgp_static->valid = 0;
6682 bgp_static->igpmetric = 0;
6683 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6684 bgp_static->label = label;
6685 bgp_static->prd = prd;
6686
6687 if (rmap_str) {
6688 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6689 route_map_counter_decrement(bgp_static->rmap.map);
6690 bgp_static->rmap.name =
6691 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6692 bgp_static->rmap.map =
6693 route_map_lookup_by_name(rmap_str);
6694 route_map_counter_increment(bgp_static->rmap.map);
6695 }
6696
6697 if (safi == SAFI_EVPN) {
6698 if (esi) {
6699 bgp_static->eth_s_id =
6700 XCALLOC(MTYPE_ATTR,
6701 sizeof(esi_t));
6702 str2esi(esi, bgp_static->eth_s_id);
6703 }
6704 if (routermac) {
6705 bgp_static->router_mac =
6706 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6707 (void)prefix_str2mac(routermac,
6708 bgp_static->router_mac);
6709 }
6710 if (gwip)
6711 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6712 }
6713 bgp_dest_set_bgp_static_info(dest, bgp_static);
6714
6715 bgp_static->valid = 1;
6716 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6717 }
6718
6719 return CMD_SUCCESS;
6720 }
6721
6722 /* Configure static BGP network. */
6723 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6724 const char *ip_str, const char *rd_str,
6725 const char *label_str, int evpn_type, const char *esi,
6726 const char *gwip, const char *ethtag)
6727 {
6728 VTY_DECLVAR_CONTEXT(bgp, bgp);
6729 int ret;
6730 struct prefix p;
6731 struct prefix_rd prd;
6732 struct bgp_dest *pdest;
6733 struct bgp_dest *dest;
6734 struct bgp_table *table;
6735 struct bgp_static *bgp_static;
6736 mpls_label_t label = MPLS_INVALID_LABEL;
6737
6738 /* Convert IP prefix string to struct prefix. */
6739 ret = str2prefix(ip_str, &p);
6740 if (!ret) {
6741 vty_out(vty, "%% Malformed prefix\n");
6742 return CMD_WARNING_CONFIG_FAILED;
6743 }
6744 apply_mask(&p);
6745 if ((afi == AFI_L2VPN)
6746 && (bgp_build_evpn_prefix(evpn_type,
6747 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6748 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6749 return CMD_WARNING_CONFIG_FAILED;
6750 }
6751 ret = str2prefix_rd(rd_str, &prd);
6752 if (!ret) {
6753 vty_out(vty, "%% Malformed rd\n");
6754 return CMD_WARNING_CONFIG_FAILED;
6755 }
6756
6757 if (label_str) {
6758 unsigned long label_val;
6759 label_val = strtoul(label_str, NULL, 10);
6760 encode_label(label_val, &label);
6761 }
6762
6763 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6764 if (!bgp_dest_has_bgp_path_info_data(pdest))
6765 bgp_dest_set_bgp_table_info(pdest,
6766 bgp_table_init(bgp, afi, safi));
6767 else
6768 bgp_dest_unlock_node(pdest);
6769 table = bgp_dest_get_bgp_table_info(pdest);
6770
6771 dest = bgp_node_lookup(table, &p);
6772
6773 if (dest) {
6774 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6775
6776 bgp_static = bgp_dest_get_bgp_static_info(dest);
6777 bgp_static_free(bgp_static);
6778 bgp_dest_set_bgp_static_info(dest, NULL);
6779 bgp_dest_unlock_node(dest);
6780 bgp_dest_unlock_node(dest);
6781 } else
6782 vty_out(vty, "%% Can't find the route\n");
6783
6784 return CMD_SUCCESS;
6785 }
6786
6787 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6788 const char *rmap_name)
6789 {
6790 VTY_DECLVAR_CONTEXT(bgp, bgp);
6791 struct bgp_rmap *rmap;
6792
6793 rmap = &bgp->table_map[afi][safi];
6794 if (rmap_name) {
6795 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6796 route_map_counter_decrement(rmap->map);
6797 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6798 rmap->map = route_map_lookup_by_name(rmap_name);
6799 route_map_counter_increment(rmap->map);
6800 } else {
6801 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6802 route_map_counter_decrement(rmap->map);
6803 rmap->map = NULL;
6804 }
6805
6806 if (bgp_fibupd_safi(safi))
6807 bgp_zebra_announce_table(bgp, afi, safi);
6808
6809 return CMD_SUCCESS;
6810 }
6811
6812 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6813 const char *rmap_name)
6814 {
6815 VTY_DECLVAR_CONTEXT(bgp, bgp);
6816 struct bgp_rmap *rmap;
6817
6818 rmap = &bgp->table_map[afi][safi];
6819 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6820 route_map_counter_decrement(rmap->map);
6821 rmap->map = NULL;
6822
6823 if (bgp_fibupd_safi(safi))
6824 bgp_zebra_announce_table(bgp, afi, safi);
6825
6826 return CMD_SUCCESS;
6827 }
6828
6829 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6830 safi_t safi)
6831 {
6832 if (bgp->table_map[afi][safi].name) {
6833 vty_out(vty, " table-map %s\n",
6834 bgp->table_map[afi][safi].name);
6835 }
6836 }
6837
6838 DEFUN (bgp_table_map,
6839 bgp_table_map_cmd,
6840 "table-map WORD",
6841 "BGP table to RIB route download filter\n"
6842 "Name of the route map\n")
6843 {
6844 int idx_word = 1;
6845 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6846 argv[idx_word]->arg);
6847 }
6848 DEFUN (no_bgp_table_map,
6849 no_bgp_table_map_cmd,
6850 "no table-map WORD",
6851 NO_STR
6852 "BGP table to RIB route download filter\n"
6853 "Name of the route map\n")
6854 {
6855 int idx_word = 2;
6856 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6857 argv[idx_word]->arg);
6858 }
6859
6860 DEFPY(bgp_network,
6861 bgp_network_cmd,
6862 "[no] network \
6863 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6864 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6865 backdoor$backdoor}]",
6866 NO_STR
6867 "Specify a network to announce via BGP\n"
6868 "IPv4 prefix\n"
6869 "Network number\n"
6870 "Network mask\n"
6871 "Network mask\n"
6872 "Route-map to modify the attributes\n"
6873 "Name of the route map\n"
6874 "Label index to associate with the prefix\n"
6875 "Label index value\n"
6876 "Specify a BGP backdoor route\n")
6877 {
6878 char addr_prefix_str[BUFSIZ];
6879
6880 if (address_str) {
6881 int ret;
6882
6883 ret = netmask_str2prefix_str(address_str, netmask_str,
6884 addr_prefix_str,
6885 sizeof(addr_prefix_str));
6886 if (!ret) {
6887 vty_out(vty, "%% Inconsistent address and mask\n");
6888 return CMD_WARNING_CONFIG_FAILED;
6889 }
6890 }
6891
6892 return bgp_static_set(
6893 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
6894 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
6895 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6896 }
6897
6898 DEFPY(ipv6_bgp_network,
6899 ipv6_bgp_network_cmd,
6900 "[no] network X:X::X:X/M$prefix \
6901 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6902 NO_STR
6903 "Specify a network to announce via BGP\n"
6904 "IPv6 prefix\n"
6905 "Route-map to modify the attributes\n"
6906 "Name of the route map\n"
6907 "Label index to associate with the prefix\n"
6908 "Label index value\n")
6909 {
6910 return bgp_static_set(
6911 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
6912 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6913 }
6914
6915 static struct bgp_aggregate *bgp_aggregate_new(void)
6916 {
6917 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6918 }
6919
6920 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6921 {
6922 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
6923 route_map_counter_decrement(aggregate->suppress_map);
6924 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6925 route_map_counter_decrement(aggregate->rmap.map);
6926 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6927 }
6928
6929 /**
6930 * Helper function to avoid repeated code: prepare variables for a
6931 * `route_map_apply` call.
6932 *
6933 * \returns `true` on route map match, otherwise `false`.
6934 */
6935 static bool aggr_suppress_map_test(struct bgp *bgp,
6936 struct bgp_aggregate *aggregate,
6937 struct bgp_path_info *pi)
6938 {
6939 const struct prefix *p = bgp_dest_get_prefix(pi->net);
6940 route_map_result_t rmr = RMAP_DENYMATCH;
6941 struct bgp_path_info rmap_path = {};
6942 struct attr attr = {};
6943
6944 /* No route map entries created, just don't match. */
6945 if (aggregate->suppress_map == NULL)
6946 return false;
6947
6948 /* Call route map matching and return result. */
6949 attr.aspath = aspath_empty();
6950 rmap_path.peer = bgp->peer_self;
6951 rmap_path.attr = &attr;
6952
6953 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
6954 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
6955 bgp->peer_self->rmap_type = 0;
6956
6957 bgp_attr_flush(&attr);
6958 aspath_unintern(&attr.aspath);
6959
6960 return rmr == RMAP_PERMITMATCH;
6961 }
6962
6963 /** Test whether the aggregation has suppressed this path or not. */
6964 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
6965 struct bgp_path_info *pi)
6966 {
6967 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
6968 return false;
6969
6970 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
6971 }
6972
6973 /**
6974 * Suppress this path and keep the reference.
6975 *
6976 * \returns `true` if needs processing otherwise `false`.
6977 */
6978 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
6979 struct bgp_path_info *pi)
6980 {
6981 struct bgp_path_info_extra *pie;
6982
6983 /* Path is already suppressed by this aggregation. */
6984 if (aggr_suppress_exists(aggregate, pi))
6985 return false;
6986
6987 pie = bgp_path_info_extra_get(pi);
6988
6989 /* This is the first suppression, allocate memory and list it. */
6990 if (pie->aggr_suppressors == NULL)
6991 pie->aggr_suppressors = list_new();
6992
6993 listnode_add(pie->aggr_suppressors, aggregate);
6994
6995 /* Only mark for processing if suppressed. */
6996 if (listcount(pie->aggr_suppressors) == 1) {
6997 if (BGP_DEBUG(update, UPDATE_OUT))
6998 zlog_debug("aggregate-address suppressing: %pFX",
6999 bgp_dest_get_prefix(pi->net));
7000
7001 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7002 return true;
7003 }
7004
7005 return false;
7006 }
7007
7008 /**
7009 * Unsuppress this path and remove the reference.
7010 *
7011 * \returns `true` if needs processing otherwise `false`.
7012 */
7013 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7014 struct bgp_path_info *pi)
7015 {
7016 /* Path wasn't suppressed. */
7017 if (!aggr_suppress_exists(aggregate, pi))
7018 return false;
7019
7020 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7021
7022 /* Unsuppress and free extra memory if last item. */
7023 if (listcount(pi->extra->aggr_suppressors) == 0) {
7024 if (BGP_DEBUG(update, UPDATE_OUT))
7025 zlog_debug("aggregate-address unsuppressing: %pFX",
7026 bgp_dest_get_prefix(pi->net));
7027
7028 list_delete(&pi->extra->aggr_suppressors);
7029 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7030 return true;
7031 }
7032
7033 return false;
7034 }
7035
7036 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7037 struct aspath *aspath,
7038 struct community *comm,
7039 struct ecommunity *ecomm,
7040 struct lcommunity *lcomm)
7041 {
7042 static struct aspath *ae = NULL;
7043
7044 if (!ae)
7045 ae = aspath_empty();
7046
7047 if (!pi)
7048 return false;
7049
7050 if (origin != pi->attr->origin)
7051 return false;
7052
7053 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7054 return false;
7055
7056 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7057 return false;
7058
7059 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7060 return false;
7061
7062 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7063 return false;
7064
7065 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7066 return false;
7067
7068 return true;
7069 }
7070
7071 static void bgp_aggregate_install(
7072 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7073 uint8_t origin, struct aspath *aspath, struct community *community,
7074 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7075 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7076 {
7077 struct bgp_dest *dest;
7078 struct bgp_table *table;
7079 struct bgp_path_info *pi, *orig, *new;
7080 struct attr *attr;
7081
7082 table = bgp->rib[afi][safi];
7083
7084 dest = bgp_node_get(table, p);
7085
7086 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7087 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7088 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7089 break;
7090
7091 /*
7092 * If we have paths with different MEDs, then don't install
7093 * (or uninstall) the aggregate route.
7094 */
7095 if (aggregate->match_med && aggregate->med_mismatched)
7096 goto uninstall_aggregate_route;
7097
7098 if (aggregate->count > 0) {
7099 /*
7100 * If the aggregate information has not changed
7101 * no need to re-install it again.
7102 */
7103 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7104 ecommunity, lcommunity)) {
7105 bgp_dest_unlock_node(dest);
7106
7107 if (aspath)
7108 aspath_free(aspath);
7109 if (community)
7110 community_free(&community);
7111 if (ecommunity)
7112 ecommunity_free(&ecommunity);
7113 if (lcommunity)
7114 lcommunity_free(&lcommunity);
7115
7116 return;
7117 }
7118
7119 /*
7120 * Mark the old as unusable
7121 */
7122 if (pi)
7123 bgp_path_info_delete(dest, pi);
7124
7125 attr = bgp_attr_aggregate_intern(
7126 bgp, origin, aspath, community, ecommunity, lcommunity,
7127 aggregate, atomic_aggregate, p);
7128
7129 if (!attr) {
7130 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7131 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7132 zlog_debug("%s: %pFX null attribute", __func__,
7133 p);
7134 return;
7135 }
7136
7137 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7138 bgp->peer_self, attr, dest);
7139
7140 SET_FLAG(new->flags, BGP_PATH_VALID);
7141
7142 bgp_path_info_add(dest, new);
7143 bgp_process(bgp, dest, afi, safi);
7144 } else {
7145 uninstall_aggregate_route:
7146 for (pi = orig; pi; pi = pi->next)
7147 if (pi->peer == bgp->peer_self
7148 && pi->type == ZEBRA_ROUTE_BGP
7149 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7150 break;
7151
7152 /* Withdraw static BGP route from routing table. */
7153 if (pi) {
7154 bgp_path_info_delete(dest, pi);
7155 bgp_process(bgp, dest, afi, safi);
7156 }
7157 }
7158
7159 bgp_dest_unlock_node(dest);
7160 }
7161
7162 /**
7163 * Check if the current path has different MED than other known paths.
7164 *
7165 * \returns `true` if the MED matched the others else `false`.
7166 */
7167 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7168 struct bgp *bgp, struct bgp_path_info *pi)
7169 {
7170 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7171
7172 /* This is the first route being analyzed. */
7173 if (!aggregate->med_initialized) {
7174 aggregate->med_initialized = true;
7175 aggregate->med_mismatched = false;
7176 aggregate->med_matched_value = cur_med;
7177 } else {
7178 /* Check if routes with different MED showed up. */
7179 if (cur_med != aggregate->med_matched_value)
7180 aggregate->med_mismatched = true;
7181 }
7182
7183 return !aggregate->med_mismatched;
7184 }
7185
7186 /**
7187 * Initializes and tests all routes in the aggregate address path for MED
7188 * values.
7189 *
7190 * \returns `true` if all MEDs are the same otherwise `false`.
7191 */
7192 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7193 struct bgp *bgp, const struct prefix *p,
7194 afi_t afi, safi_t safi)
7195 {
7196 struct bgp_table *table = bgp->rib[afi][safi];
7197 const struct prefix *dest_p;
7198 struct bgp_dest *dest, *top;
7199 struct bgp_path_info *pi;
7200 bool med_matched = true;
7201
7202 aggregate->med_initialized = false;
7203
7204 top = bgp_node_get(table, p);
7205 for (dest = bgp_node_get(table, p); dest;
7206 dest = bgp_route_next_until(dest, top)) {
7207 dest_p = bgp_dest_get_prefix(dest);
7208 if (dest_p->prefixlen <= p->prefixlen)
7209 continue;
7210
7211 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7212 if (BGP_PATH_HOLDDOWN(pi))
7213 continue;
7214 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7215 continue;
7216 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7217 med_matched = false;
7218 break;
7219 }
7220 }
7221 if (!med_matched)
7222 break;
7223 }
7224 bgp_dest_unlock_node(top);
7225
7226 return med_matched;
7227 }
7228
7229 /**
7230 * Toggles the route suppression status for this aggregate address
7231 * configuration.
7232 */
7233 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7234 struct bgp *bgp, const struct prefix *p,
7235 afi_t afi, safi_t safi, bool suppress)
7236 {
7237 struct bgp_table *table = bgp->rib[afi][safi];
7238 const struct prefix *dest_p;
7239 struct bgp_dest *dest, *top;
7240 struct bgp_path_info *pi;
7241 bool toggle_suppression;
7242
7243 /* We've found a different MED we must revert any suppressed routes. */
7244 top = bgp_node_get(table, p);
7245 for (dest = bgp_node_get(table, p); dest;
7246 dest = bgp_route_next_until(dest, top)) {
7247 dest_p = bgp_dest_get_prefix(dest);
7248 if (dest_p->prefixlen <= p->prefixlen)
7249 continue;
7250
7251 toggle_suppression = false;
7252 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7253 if (BGP_PATH_HOLDDOWN(pi))
7254 continue;
7255 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7256 continue;
7257
7258 /* We are toggling suppression back. */
7259 if (suppress) {
7260 /* Suppress route if not suppressed already. */
7261 if (aggr_suppress_path(aggregate, pi))
7262 toggle_suppression = true;
7263 continue;
7264 }
7265
7266 /* Install route if there is no more suppression. */
7267 if (aggr_unsuppress_path(aggregate, pi))
7268 toggle_suppression = true;
7269 }
7270
7271 if (toggle_suppression)
7272 bgp_process(bgp, dest, afi, safi);
7273 }
7274 bgp_dest_unlock_node(top);
7275 }
7276
7277 /**
7278 * Aggregate address MED matching incremental test: this function is called
7279 * when the initial aggregation occurred and we are only testing a single
7280 * new path.
7281 *
7282 * In addition to testing and setting the MED validity it also installs back
7283 * suppressed routes (if summary is configured).
7284 *
7285 * Must not be called in `bgp_aggregate_route`.
7286 */
7287 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7288 struct bgp *bgp, const struct prefix *p,
7289 afi_t afi, safi_t safi,
7290 struct bgp_path_info *pi, bool is_adding)
7291 {
7292 /* MED matching disabled. */
7293 if (!aggregate->match_med)
7294 return;
7295
7296 /* Aggregation with different MED, nothing to do. */
7297 if (aggregate->med_mismatched)
7298 return;
7299
7300 /*
7301 * Test the current entry:
7302 *
7303 * is_adding == true: if the new entry doesn't match then we must
7304 * install all suppressed routes.
7305 *
7306 * is_adding == false: if the entry being removed was the last
7307 * unmatching entry then we can suppress all routes.
7308 */
7309 if (!is_adding) {
7310 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
7311 && aggregate->summary_only)
7312 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
7313 safi, true);
7314 } else
7315 bgp_aggregate_med_match(aggregate, bgp, pi);
7316
7317 /* No mismatches, just quit. */
7318 if (!aggregate->med_mismatched)
7319 return;
7320
7321 /* Route summarization is disabled. */
7322 if (!aggregate->summary_only)
7323 return;
7324
7325 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7326 }
7327
7328 /* Update an aggregate as routes are added/removed from the BGP table */
7329 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7330 safi_t safi, struct bgp_aggregate *aggregate)
7331 {
7332 struct bgp_table *table;
7333 struct bgp_dest *top;
7334 struct bgp_dest *dest;
7335 uint8_t origin;
7336 struct aspath *aspath = NULL;
7337 struct community *community = NULL;
7338 struct ecommunity *ecommunity = NULL;
7339 struct lcommunity *lcommunity = NULL;
7340 struct bgp_path_info *pi;
7341 unsigned long match = 0;
7342 uint8_t atomic_aggregate = 0;
7343
7344 /* If the bgp instance is being deleted or self peer is deleted
7345 * then do not create aggregate route
7346 */
7347 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7348 || (bgp->peer_self == NULL))
7349 return;
7350
7351 /* Initialize and test routes for MED difference. */
7352 if (aggregate->match_med)
7353 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7354
7355 /*
7356 * Reset aggregate count: we might've been called from route map
7357 * update so in that case we must retest all more specific routes.
7358 *
7359 * \see `bgp_route_map_process_update`.
7360 */
7361 aggregate->count = 0;
7362 aggregate->incomplete_origin_count = 0;
7363 aggregate->incomplete_origin_count = 0;
7364 aggregate->egp_origin_count = 0;
7365
7366 /* ORIGIN attribute: If at least one route among routes that are
7367 aggregated has ORIGIN with the value INCOMPLETE, then the
7368 aggregated route must have the ORIGIN attribute with the value
7369 INCOMPLETE. Otherwise, if at least one route among routes that
7370 are aggregated has ORIGIN with the value EGP, then the aggregated
7371 route must have the origin attribute with the value EGP. In all
7372 other case the value of the ORIGIN attribute of the aggregated
7373 route is INTERNAL. */
7374 origin = BGP_ORIGIN_IGP;
7375
7376 table = bgp->rib[afi][safi];
7377
7378 top = bgp_node_get(table, p);
7379 for (dest = bgp_node_get(table, p); dest;
7380 dest = bgp_route_next_until(dest, top)) {
7381 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7382
7383 if (dest_p->prefixlen <= p->prefixlen)
7384 continue;
7385
7386 /* If suppress fib is enabled and route not installed
7387 * in FIB, skip the route
7388 */
7389 if (!bgp_check_advertise(bgp, dest))
7390 continue;
7391
7392 match = 0;
7393
7394 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7395 if (BGP_PATH_HOLDDOWN(pi))
7396 continue;
7397
7398 if (pi->attr->flag
7399 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7400 atomic_aggregate = 1;
7401
7402 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7403 continue;
7404
7405 /*
7406 * summary-only aggregate route suppress
7407 * aggregated route announcements.
7408 *
7409 * MED matching:
7410 * Don't create summaries if MED didn't match
7411 * otherwise neither the specific routes and the
7412 * aggregation will be announced.
7413 */
7414 if (aggregate->summary_only
7415 && AGGREGATE_MED_VALID(aggregate)) {
7416 if (aggr_suppress_path(aggregate, pi))
7417 match++;
7418 }
7419
7420 /*
7421 * Suppress more specific routes that match the route
7422 * map results.
7423 *
7424 * MED matching:
7425 * Don't suppress routes if MED matching is enabled and
7426 * it mismatched otherwise we might end up with no
7427 * routes for this path.
7428 */
7429 if (aggregate->suppress_map_name
7430 && AGGREGATE_MED_VALID(aggregate)
7431 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7432 if (aggr_suppress_path(aggregate, pi))
7433 match++;
7434 }
7435
7436 aggregate->count++;
7437
7438 /*
7439 * If at least one route among routes that are
7440 * aggregated has ORIGIN with the value INCOMPLETE,
7441 * then the aggregated route MUST have the ORIGIN
7442 * attribute with the value INCOMPLETE. Otherwise, if
7443 * at least one route among routes that are aggregated
7444 * has ORIGIN with the value EGP, then the aggregated
7445 * route MUST have the ORIGIN attribute with the value
7446 * EGP.
7447 */
7448 switch (pi->attr->origin) {
7449 case BGP_ORIGIN_INCOMPLETE:
7450 aggregate->incomplete_origin_count++;
7451 break;
7452 case BGP_ORIGIN_EGP:
7453 aggregate->egp_origin_count++;
7454 break;
7455 default:
7456 /*Do nothing.
7457 */
7458 break;
7459 }
7460
7461 if (!aggregate->as_set)
7462 continue;
7463
7464 /*
7465 * as-set aggregate route generate origin, as path,
7466 * and community aggregation.
7467 */
7468 /* Compute aggregate route's as-path.
7469 */
7470 bgp_compute_aggregate_aspath_hash(aggregate,
7471 pi->attr->aspath);
7472
7473 /* Compute aggregate route's community.
7474 */
7475 if (bgp_attr_get_community(pi->attr))
7476 bgp_compute_aggregate_community_hash(
7477 aggregate,
7478 bgp_attr_get_community(pi->attr));
7479
7480 /* Compute aggregate route's extended community.
7481 */
7482 if (bgp_attr_get_ecommunity(pi->attr))
7483 bgp_compute_aggregate_ecommunity_hash(
7484 aggregate,
7485 bgp_attr_get_ecommunity(pi->attr));
7486
7487 /* Compute aggregate route's large community.
7488 */
7489 if (bgp_attr_get_lcommunity(pi->attr))
7490 bgp_compute_aggregate_lcommunity_hash(
7491 aggregate,
7492 bgp_attr_get_lcommunity(pi->attr));
7493 }
7494 if (match)
7495 bgp_process(bgp, dest, afi, safi);
7496 }
7497 if (aggregate->as_set) {
7498 bgp_compute_aggregate_aspath_val(aggregate);
7499 bgp_compute_aggregate_community_val(aggregate);
7500 bgp_compute_aggregate_ecommunity_val(aggregate);
7501 bgp_compute_aggregate_lcommunity_val(aggregate);
7502 }
7503
7504
7505 bgp_dest_unlock_node(top);
7506
7507
7508 if (aggregate->incomplete_origin_count > 0)
7509 origin = BGP_ORIGIN_INCOMPLETE;
7510 else if (aggregate->egp_origin_count > 0)
7511 origin = BGP_ORIGIN_EGP;
7512
7513 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7514 origin = aggregate->origin;
7515
7516 if (aggregate->as_set) {
7517 if (aggregate->aspath)
7518 /* Retrieve aggregate route's as-path.
7519 */
7520 aspath = aspath_dup(aggregate->aspath);
7521
7522 if (aggregate->community)
7523 /* Retrieve aggregate route's community.
7524 */
7525 community = community_dup(aggregate->community);
7526
7527 if (aggregate->ecommunity)
7528 /* Retrieve aggregate route's ecommunity.
7529 */
7530 ecommunity = ecommunity_dup(aggregate->ecommunity);
7531
7532 if (aggregate->lcommunity)
7533 /* Retrieve aggregate route's lcommunity.
7534 */
7535 lcommunity = lcommunity_dup(aggregate->lcommunity);
7536 }
7537
7538 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7539 ecommunity, lcommunity, atomic_aggregate,
7540 aggregate);
7541 }
7542
7543 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7544 safi_t safi, struct bgp_aggregate *aggregate)
7545 {
7546 struct bgp_table *table;
7547 struct bgp_dest *top;
7548 struct bgp_dest *dest;
7549 struct bgp_path_info *pi;
7550 unsigned long match;
7551
7552 table = bgp->rib[afi][safi];
7553
7554 /* If routes exists below this node, generate aggregate routes. */
7555 top = bgp_node_get(table, p);
7556 for (dest = bgp_node_get(table, p); dest;
7557 dest = bgp_route_next_until(dest, top)) {
7558 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7559
7560 if (dest_p->prefixlen <= p->prefixlen)
7561 continue;
7562 match = 0;
7563
7564 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7565 if (BGP_PATH_HOLDDOWN(pi))
7566 continue;
7567
7568 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7569 continue;
7570
7571 /*
7572 * This route is suppressed: attempt to unsuppress it.
7573 *
7574 * `aggr_unsuppress_path` will fail if this particular
7575 * aggregate route was not the suppressor.
7576 */
7577 if (pi->extra && pi->extra->aggr_suppressors &&
7578 listcount(pi->extra->aggr_suppressors)) {
7579 if (aggr_unsuppress_path(aggregate, pi))
7580 match++;
7581 }
7582
7583 aggregate->count--;
7584
7585 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7586 aggregate->incomplete_origin_count--;
7587 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7588 aggregate->egp_origin_count--;
7589
7590 if (aggregate->as_set) {
7591 /* Remove as-path from aggregate.
7592 */
7593 bgp_remove_aspath_from_aggregate_hash(
7594 aggregate,
7595 pi->attr->aspath);
7596
7597 if (bgp_attr_get_community(pi->attr))
7598 /* Remove community from aggregate.
7599 */
7600 bgp_remove_comm_from_aggregate_hash(
7601 aggregate,
7602 bgp_attr_get_community(
7603 pi->attr));
7604
7605 if (bgp_attr_get_ecommunity(pi->attr))
7606 /* Remove ecommunity from aggregate.
7607 */
7608 bgp_remove_ecomm_from_aggregate_hash(
7609 aggregate,
7610 bgp_attr_get_ecommunity(
7611 pi->attr));
7612
7613 if (bgp_attr_get_lcommunity(pi->attr))
7614 /* Remove lcommunity from aggregate.
7615 */
7616 bgp_remove_lcomm_from_aggregate_hash(
7617 aggregate,
7618 bgp_attr_get_lcommunity(
7619 pi->attr));
7620 }
7621 }
7622
7623 /* If this node was suppressed, process the change. */
7624 if (match)
7625 bgp_process(bgp, dest, afi, safi);
7626 }
7627 if (aggregate->as_set) {
7628 aspath_free(aggregate->aspath);
7629 aggregate->aspath = NULL;
7630 if (aggregate->community)
7631 community_free(&aggregate->community);
7632 if (aggregate->ecommunity)
7633 ecommunity_free(&aggregate->ecommunity);
7634 if (aggregate->lcommunity)
7635 lcommunity_free(&aggregate->lcommunity);
7636 }
7637
7638 bgp_dest_unlock_node(top);
7639 }
7640
7641 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7642 const struct prefix *aggr_p,
7643 struct bgp_path_info *pinew, afi_t afi,
7644 safi_t safi,
7645 struct bgp_aggregate *aggregate)
7646 {
7647 uint8_t origin;
7648 struct aspath *aspath = NULL;
7649 uint8_t atomic_aggregate = 0;
7650 struct community *community = NULL;
7651 struct ecommunity *ecommunity = NULL;
7652 struct lcommunity *lcommunity = NULL;
7653
7654 /* If the bgp instance is being deleted or self peer is deleted
7655 * then do not create aggregate route
7656 */
7657 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7658 || (bgp->peer_self == NULL))
7659 return;
7660
7661 /* ORIGIN attribute: If at least one route among routes that are
7662 * aggregated has ORIGIN with the value INCOMPLETE, then the
7663 * aggregated route must have the ORIGIN attribute with the value
7664 * INCOMPLETE. Otherwise, if at least one route among routes that
7665 * are aggregated has ORIGIN with the value EGP, then the aggregated
7666 * route must have the origin attribute with the value EGP. In all
7667 * other case the value of the ORIGIN attribute of the aggregated
7668 * route is INTERNAL.
7669 */
7670 origin = BGP_ORIGIN_IGP;
7671
7672 aggregate->count++;
7673
7674 /*
7675 * This must be called before `summary` check to avoid
7676 * "suppressing" twice.
7677 */
7678 if (aggregate->match_med)
7679 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7680 pinew, true);
7681
7682 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7683 aggr_suppress_path(aggregate, pinew);
7684
7685 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7686 && aggr_suppress_map_test(bgp, aggregate, pinew))
7687 aggr_suppress_path(aggregate, pinew);
7688
7689 switch (pinew->attr->origin) {
7690 case BGP_ORIGIN_INCOMPLETE:
7691 aggregate->incomplete_origin_count++;
7692 break;
7693 case BGP_ORIGIN_EGP:
7694 aggregate->egp_origin_count++;
7695 break;
7696 default:
7697 /* Do nothing.
7698 */
7699 break;
7700 }
7701
7702 if (aggregate->incomplete_origin_count > 0)
7703 origin = BGP_ORIGIN_INCOMPLETE;
7704 else if (aggregate->egp_origin_count > 0)
7705 origin = BGP_ORIGIN_EGP;
7706
7707 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7708 origin = aggregate->origin;
7709
7710 if (aggregate->as_set) {
7711 /* Compute aggregate route's as-path.
7712 */
7713 bgp_compute_aggregate_aspath(aggregate,
7714 pinew->attr->aspath);
7715
7716 /* Compute aggregate route's community.
7717 */
7718 if (bgp_attr_get_community(pinew->attr))
7719 bgp_compute_aggregate_community(
7720 aggregate, bgp_attr_get_community(pinew->attr));
7721
7722 /* Compute aggregate route's extended community.
7723 */
7724 if (bgp_attr_get_ecommunity(pinew->attr))
7725 bgp_compute_aggregate_ecommunity(
7726 aggregate,
7727 bgp_attr_get_ecommunity(pinew->attr));
7728
7729 /* Compute aggregate route's large community.
7730 */
7731 if (bgp_attr_get_lcommunity(pinew->attr))
7732 bgp_compute_aggregate_lcommunity(
7733 aggregate,
7734 bgp_attr_get_lcommunity(pinew->attr));
7735
7736 /* Retrieve aggregate route's as-path.
7737 */
7738 if (aggregate->aspath)
7739 aspath = aspath_dup(aggregate->aspath);
7740
7741 /* Retrieve aggregate route's community.
7742 */
7743 if (aggregate->community)
7744 community = community_dup(aggregate->community);
7745
7746 /* Retrieve aggregate route's ecommunity.
7747 */
7748 if (aggregate->ecommunity)
7749 ecommunity = ecommunity_dup(aggregate->ecommunity);
7750
7751 /* Retrieve aggregate route's lcommunity.
7752 */
7753 if (aggregate->lcommunity)
7754 lcommunity = lcommunity_dup(aggregate->lcommunity);
7755 }
7756
7757 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7758 aspath, community, ecommunity,
7759 lcommunity, atomic_aggregate, aggregate);
7760 }
7761
7762 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7763 safi_t safi,
7764 struct bgp_path_info *pi,
7765 struct bgp_aggregate *aggregate,
7766 const struct prefix *aggr_p)
7767 {
7768 uint8_t origin;
7769 struct aspath *aspath = NULL;
7770 uint8_t atomic_aggregate = 0;
7771 struct community *community = NULL;
7772 struct ecommunity *ecommunity = NULL;
7773 struct lcommunity *lcommunity = NULL;
7774 unsigned long match = 0;
7775
7776 /* If the bgp instance is being deleted or self peer is deleted
7777 * then do not create aggregate route
7778 */
7779 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7780 || (bgp->peer_self == NULL))
7781 return;
7782
7783 if (BGP_PATH_HOLDDOWN(pi))
7784 return;
7785
7786 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7787 return;
7788
7789 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7790 if (aggr_unsuppress_path(aggregate, pi))
7791 match++;
7792
7793 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7794 && aggr_suppress_map_test(bgp, aggregate, pi))
7795 if (aggr_unsuppress_path(aggregate, pi))
7796 match++;
7797
7798 /*
7799 * This must be called after `summary`, `suppress-map` check to avoid
7800 * "unsuppressing" twice.
7801 */
7802 if (aggregate->match_med)
7803 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
7804 true);
7805
7806 if (aggregate->count > 0)
7807 aggregate->count--;
7808
7809 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7810 aggregate->incomplete_origin_count--;
7811 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7812 aggregate->egp_origin_count--;
7813
7814 if (aggregate->as_set) {
7815 /* Remove as-path from aggregate.
7816 */
7817 bgp_remove_aspath_from_aggregate(aggregate,
7818 pi->attr->aspath);
7819
7820 if (bgp_attr_get_community(pi->attr))
7821 /* Remove community from aggregate.
7822 */
7823 bgp_remove_community_from_aggregate(
7824 aggregate, bgp_attr_get_community(pi->attr));
7825
7826 if (bgp_attr_get_ecommunity(pi->attr))
7827 /* Remove ecommunity from aggregate.
7828 */
7829 bgp_remove_ecommunity_from_aggregate(
7830 aggregate, bgp_attr_get_ecommunity(pi->attr));
7831
7832 if (bgp_attr_get_lcommunity(pi->attr))
7833 /* Remove lcommunity from aggregate.
7834 */
7835 bgp_remove_lcommunity_from_aggregate(
7836 aggregate, bgp_attr_get_lcommunity(pi->attr));
7837 }
7838
7839 /* If this node was suppressed, process the change. */
7840 if (match)
7841 bgp_process(bgp, pi->net, afi, safi);
7842
7843 origin = BGP_ORIGIN_IGP;
7844 if (aggregate->incomplete_origin_count > 0)
7845 origin = BGP_ORIGIN_INCOMPLETE;
7846 else if (aggregate->egp_origin_count > 0)
7847 origin = BGP_ORIGIN_EGP;
7848
7849 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7850 origin = aggregate->origin;
7851
7852 if (aggregate->as_set) {
7853 /* Retrieve aggregate route's as-path.
7854 */
7855 if (aggregate->aspath)
7856 aspath = aspath_dup(aggregate->aspath);
7857
7858 /* Retrieve aggregate route's community.
7859 */
7860 if (aggregate->community)
7861 community = community_dup(aggregate->community);
7862
7863 /* Retrieve aggregate route's ecommunity.
7864 */
7865 if (aggregate->ecommunity)
7866 ecommunity = ecommunity_dup(aggregate->ecommunity);
7867
7868 /* Retrieve aggregate route's lcommunity.
7869 */
7870 if (aggregate->lcommunity)
7871 lcommunity = lcommunity_dup(aggregate->lcommunity);
7872 }
7873
7874 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7875 aspath, community, ecommunity,
7876 lcommunity, atomic_aggregate, aggregate);
7877 }
7878
7879 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
7880 struct bgp_path_info *pi, afi_t afi, safi_t safi)
7881 {
7882 struct bgp_dest *child;
7883 struct bgp_dest *dest;
7884 struct bgp_aggregate *aggregate;
7885 struct bgp_table *table;
7886
7887 table = bgp->aggregate[afi][safi];
7888
7889 /* No aggregates configured. */
7890 if (bgp_table_top_nolock(table) == NULL)
7891 return;
7892
7893 if (p->prefixlen == 0)
7894 return;
7895
7896 if (BGP_PATH_HOLDDOWN(pi))
7897 return;
7898
7899 /* If suppress fib is enabled and route not installed
7900 * in FIB, do not update the aggregate route
7901 */
7902 if (!bgp_check_advertise(bgp, pi->net))
7903 return;
7904
7905 child = bgp_node_get(table, p);
7906
7907 /* Aggregate address configuration check. */
7908 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7909 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7910
7911 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7912 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7913 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
7914 aggregate);
7915 }
7916 }
7917 bgp_dest_unlock_node(child);
7918 }
7919
7920 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
7921 struct bgp_path_info *del, afi_t afi, safi_t safi)
7922 {
7923 struct bgp_dest *child;
7924 struct bgp_dest *dest;
7925 struct bgp_aggregate *aggregate;
7926 struct bgp_table *table;
7927
7928 table = bgp->aggregate[afi][safi];
7929
7930 /* No aggregates configured. */
7931 if (bgp_table_top_nolock(table) == NULL)
7932 return;
7933
7934 if (p->prefixlen == 0)
7935 return;
7936
7937 child = bgp_node_get(table, p);
7938
7939 /* Aggregate address configuration check. */
7940 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7941 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7942
7943 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7944 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7945 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
7946 aggregate, dest_p);
7947 }
7948 }
7949 bgp_dest_unlock_node(child);
7950 }
7951
7952 /* Aggregate route attribute. */
7953 #define AGGREGATE_SUMMARY_ONLY 1
7954 #define AGGREGATE_AS_SET 1
7955 #define AGGREGATE_AS_UNSET 0
7956
7957 static const char *bgp_origin2str(uint8_t origin)
7958 {
7959 switch (origin) {
7960 case BGP_ORIGIN_IGP:
7961 return "igp";
7962 case BGP_ORIGIN_EGP:
7963 return "egp";
7964 case BGP_ORIGIN_INCOMPLETE:
7965 return "incomplete";
7966 }
7967 return "n/a";
7968 }
7969
7970 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
7971 {
7972 switch (v_state) {
7973 case RPKI_NOT_BEING_USED:
7974 return "not used";
7975 case RPKI_VALID:
7976 return "valid";
7977 case RPKI_NOTFOUND:
7978 return "not found";
7979 case RPKI_INVALID:
7980 return "invalid";
7981 }
7982
7983 assert(!"We should never get here this is a dev escape");
7984 return "ERROR";
7985 }
7986
7987 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
7988 afi_t afi, safi_t safi)
7989 {
7990 VTY_DECLVAR_CONTEXT(bgp, bgp);
7991 int ret;
7992 struct prefix p;
7993 struct bgp_dest *dest;
7994 struct bgp_aggregate *aggregate;
7995
7996 /* Convert string to prefix structure. */
7997 ret = str2prefix(prefix_str, &p);
7998 if (!ret) {
7999 vty_out(vty, "Malformed prefix\n");
8000 return CMD_WARNING_CONFIG_FAILED;
8001 }
8002 apply_mask(&p);
8003
8004 /* Old configuration check. */
8005 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8006 if (!dest) {
8007 vty_out(vty,
8008 "%% There is no aggregate-address configuration.\n");
8009 return CMD_WARNING_CONFIG_FAILED;
8010 }
8011
8012 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8013 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8014 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8015 NULL, NULL, 0, aggregate);
8016
8017 /* Unlock aggregate address configuration. */
8018 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8019
8020 if (aggregate->community)
8021 community_free(&aggregate->community);
8022
8023 if (aggregate->community_hash) {
8024 /* Delete all communities in the hash.
8025 */
8026 hash_clean(aggregate->community_hash,
8027 bgp_aggr_community_remove);
8028 /* Free up the community_hash.
8029 */
8030 hash_free(aggregate->community_hash);
8031 }
8032
8033 if (aggregate->ecommunity)
8034 ecommunity_free(&aggregate->ecommunity);
8035
8036 if (aggregate->ecommunity_hash) {
8037 /* Delete all ecommunities in the hash.
8038 */
8039 hash_clean(aggregate->ecommunity_hash,
8040 bgp_aggr_ecommunity_remove);
8041 /* Free up the ecommunity_hash.
8042 */
8043 hash_free(aggregate->ecommunity_hash);
8044 }
8045
8046 if (aggregate->lcommunity)
8047 lcommunity_free(&aggregate->lcommunity);
8048
8049 if (aggregate->lcommunity_hash) {
8050 /* Delete all lcommunities in the hash.
8051 */
8052 hash_clean(aggregate->lcommunity_hash,
8053 bgp_aggr_lcommunity_remove);
8054 /* Free up the lcommunity_hash.
8055 */
8056 hash_free(aggregate->lcommunity_hash);
8057 }
8058
8059 if (aggregate->aspath)
8060 aspath_free(aggregate->aspath);
8061
8062 if (aggregate->aspath_hash) {
8063 /* Delete all as-paths in the hash.
8064 */
8065 hash_clean(aggregate->aspath_hash,
8066 bgp_aggr_aspath_remove);
8067 /* Free up the aspath_hash.
8068 */
8069 hash_free(aggregate->aspath_hash);
8070 }
8071
8072 bgp_aggregate_free(aggregate);
8073 bgp_dest_unlock_node(dest);
8074 bgp_dest_unlock_node(dest);
8075
8076 return CMD_SUCCESS;
8077 }
8078
8079 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8080 safi_t safi, const char *rmap,
8081 uint8_t summary_only, uint8_t as_set,
8082 uint8_t origin, bool match_med,
8083 const char *suppress_map)
8084 {
8085 VTY_DECLVAR_CONTEXT(bgp, bgp);
8086 int ret;
8087 struct prefix p;
8088 struct bgp_dest *dest;
8089 struct bgp_aggregate *aggregate;
8090 uint8_t as_set_new = as_set;
8091
8092 if (suppress_map && summary_only) {
8093 vty_out(vty,
8094 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8095 return CMD_WARNING_CONFIG_FAILED;
8096 }
8097
8098 /* Convert string to prefix structure. */
8099 ret = str2prefix(prefix_str, &p);
8100 if (!ret) {
8101 vty_out(vty, "Malformed prefix\n");
8102 return CMD_WARNING_CONFIG_FAILED;
8103 }
8104 apply_mask(&p);
8105
8106 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8107 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8108 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8109 prefix_str);
8110 return CMD_WARNING_CONFIG_FAILED;
8111 }
8112
8113 /* Old configuration check. */
8114 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8115 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8116
8117 if (aggregate) {
8118 vty_out(vty, "There is already same aggregate network.\n");
8119 /* try to remove the old entry */
8120 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8121 if (ret) {
8122 vty_out(vty, "Error deleting aggregate.\n");
8123 bgp_dest_unlock_node(dest);
8124 return CMD_WARNING_CONFIG_FAILED;
8125 }
8126 }
8127
8128 /* Make aggregate address structure. */
8129 aggregate = bgp_aggregate_new();
8130 aggregate->summary_only = summary_only;
8131 aggregate->match_med = match_med;
8132
8133 /* Network operators MUST NOT locally generate any new
8134 * announcements containing AS_SET or AS_CONFED_SET. If they have
8135 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8136 * SHOULD withdraw those routes and re-announce routes for the
8137 * aggregate or component prefixes (i.e., the more-specific routes
8138 * subsumed by the previously aggregated route) without AS_SET
8139 * or AS_CONFED_SET in the updates.
8140 */
8141 if (bgp->reject_as_sets) {
8142 if (as_set == AGGREGATE_AS_SET) {
8143 as_set_new = AGGREGATE_AS_UNSET;
8144 zlog_warn(
8145 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8146 __func__);
8147 vty_out(vty,
8148 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8149 }
8150 }
8151
8152 aggregate->as_set = as_set_new;
8153 aggregate->safi = safi;
8154 /* Override ORIGIN attribute if defined.
8155 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8156 * to IGP which is not what rfc4271 says.
8157 * This enables the same behavior, optionally.
8158 */
8159 aggregate->origin = origin;
8160
8161 if (rmap) {
8162 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8163 route_map_counter_decrement(aggregate->rmap.map);
8164 aggregate->rmap.name =
8165 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8166 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8167 route_map_counter_increment(aggregate->rmap.map);
8168 }
8169
8170 if (suppress_map) {
8171 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8172 route_map_counter_decrement(aggregate->suppress_map);
8173
8174 aggregate->suppress_map_name =
8175 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8176 aggregate->suppress_map =
8177 route_map_lookup_by_name(aggregate->suppress_map_name);
8178 route_map_counter_increment(aggregate->suppress_map);
8179 }
8180
8181 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8182
8183 /* Aggregate address insert into BGP routing table. */
8184 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8185
8186 return CMD_SUCCESS;
8187 }
8188
8189 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8190 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8191 "as-set$as_set_s"
8192 "|summary-only$summary_only"
8193 "|route-map RMAP_NAME$rmap_name"
8194 "|origin <egp|igp|incomplete>$origin_s"
8195 "|matching-MED-only$match_med"
8196 "|suppress-map RMAP_NAME$suppress_map"
8197 "}]",
8198 NO_STR
8199 "Configure BGP aggregate entries\n"
8200 "Aggregate prefix\n"
8201 "Aggregate address\n"
8202 "Aggregate mask\n"
8203 "Generate AS set path information\n"
8204 "Filter more specific routes from updates\n"
8205 "Apply route map to aggregate network\n"
8206 "Route map name\n"
8207 "BGP origin code\n"
8208 "Remote EGP\n"
8209 "Local IGP\n"
8210 "Unknown heritage\n"
8211 "Only aggregate routes with matching MED\n"
8212 "Suppress the selected more specific routes\n"
8213 "Route map with the route selectors\n")
8214 {
8215 const char *prefix_s = NULL;
8216 safi_t safi = bgp_node_safi(vty);
8217 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8218 int as_set = AGGREGATE_AS_UNSET;
8219 char prefix_buf[PREFIX2STR_BUFFER];
8220
8221 if (addr_str) {
8222 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8223 sizeof(prefix_buf))
8224 == 0) {
8225 vty_out(vty, "%% Inconsistent address and mask\n");
8226 return CMD_WARNING_CONFIG_FAILED;
8227 }
8228 prefix_s = prefix_buf;
8229 } else
8230 prefix_s = prefix_str;
8231
8232 if (origin_s) {
8233 if (strcmp(origin_s, "egp") == 0)
8234 origin = BGP_ORIGIN_EGP;
8235 else if (strcmp(origin_s, "igp") == 0)
8236 origin = BGP_ORIGIN_IGP;
8237 else if (strcmp(origin_s, "incomplete") == 0)
8238 origin = BGP_ORIGIN_INCOMPLETE;
8239 }
8240
8241 if (as_set_s)
8242 as_set = AGGREGATE_AS_SET;
8243
8244 /* Handle configuration removal, otherwise installation. */
8245 if (no)
8246 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8247
8248 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8249 summary_only != NULL, as_set, origin,
8250 match_med != NULL, suppress_map);
8251 }
8252
8253 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8254 "[no] aggregate-address X:X::X:X/M$prefix [{"
8255 "as-set$as_set_s"
8256 "|summary-only$summary_only"
8257 "|route-map RMAP_NAME$rmap_name"
8258 "|origin <egp|igp|incomplete>$origin_s"
8259 "|matching-MED-only$match_med"
8260 "|suppress-map RMAP_NAME$suppress_map"
8261 "}]",
8262 NO_STR
8263 "Configure BGP aggregate entries\n"
8264 "Aggregate prefix\n"
8265 "Generate AS set path information\n"
8266 "Filter more specific routes from updates\n"
8267 "Apply route map to aggregate network\n"
8268 "Route map name\n"
8269 "BGP origin code\n"
8270 "Remote EGP\n"
8271 "Local IGP\n"
8272 "Unknown heritage\n"
8273 "Only aggregate routes with matching MED\n"
8274 "Suppress the selected more specific routes\n"
8275 "Route map with the route selectors\n")
8276 {
8277 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8278 int as_set = AGGREGATE_AS_UNSET;
8279
8280 if (origin_s) {
8281 if (strcmp(origin_s, "egp") == 0)
8282 origin = BGP_ORIGIN_EGP;
8283 else if (strcmp(origin_s, "igp") == 0)
8284 origin = BGP_ORIGIN_IGP;
8285 else if (strcmp(origin_s, "incomplete") == 0)
8286 origin = BGP_ORIGIN_INCOMPLETE;
8287 }
8288
8289 if (as_set_s)
8290 as_set = AGGREGATE_AS_SET;
8291
8292 /* Handle configuration removal, otherwise installation. */
8293 if (no)
8294 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8295 SAFI_UNICAST);
8296
8297 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8298 rmap_name, summary_only != NULL, as_set,
8299 origin, match_med != NULL, suppress_map);
8300 }
8301
8302 /* Redistribute route treatment. */
8303 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8304 const union g_addr *nexthop, ifindex_t ifindex,
8305 enum nexthop_types_t nhtype, uint8_t distance,
8306 enum blackhole_type bhtype, uint32_t metric,
8307 uint8_t type, unsigned short instance,
8308 route_tag_t tag)
8309 {
8310 struct bgp_path_info *new;
8311 struct bgp_path_info *bpi;
8312 struct bgp_path_info rmap_path;
8313 struct bgp_dest *bn;
8314 struct attr attr;
8315 struct attr *new_attr;
8316 afi_t afi;
8317 route_map_result_t ret;
8318 struct bgp_redist *red;
8319
8320 /* Make default attribute. */
8321 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
8322 /*
8323 * This must not be NULL to satisfy Coverity SA
8324 */
8325 assert(attr.aspath);
8326
8327 switch (nhtype) {
8328 case NEXTHOP_TYPE_IFINDEX:
8329 break;
8330 case NEXTHOP_TYPE_IPV4:
8331 case NEXTHOP_TYPE_IPV4_IFINDEX:
8332 attr.nexthop = nexthop->ipv4;
8333 break;
8334 case NEXTHOP_TYPE_IPV6:
8335 case NEXTHOP_TYPE_IPV6_IFINDEX:
8336 attr.mp_nexthop_global = nexthop->ipv6;
8337 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8338 break;
8339 case NEXTHOP_TYPE_BLACKHOLE:
8340 switch (p->family) {
8341 case AF_INET:
8342 attr.nexthop.s_addr = INADDR_ANY;
8343 break;
8344 case AF_INET6:
8345 memset(&attr.mp_nexthop_global, 0,
8346 sizeof(attr.mp_nexthop_global));
8347 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8348 break;
8349 }
8350 attr.bh_type = bhtype;
8351 break;
8352 }
8353 attr.nh_type = nhtype;
8354 attr.nh_ifindex = ifindex;
8355
8356 attr.med = metric;
8357 attr.distance = distance;
8358 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8359 attr.tag = tag;
8360
8361 afi = family2afi(p->family);
8362
8363 red = bgp_redist_lookup(bgp, afi, type, instance);
8364 if (red) {
8365 struct attr attr_new;
8366
8367 /* Copy attribute for modification. */
8368 attr_new = attr;
8369
8370 if (red->redist_metric_flag)
8371 attr_new.med = red->redist_metric;
8372
8373 /* Apply route-map. */
8374 if (red->rmap.name) {
8375 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
8376 rmap_path.peer = bgp->peer_self;
8377 rmap_path.attr = &attr_new;
8378
8379 SET_FLAG(bgp->peer_self->rmap_type,
8380 PEER_RMAP_TYPE_REDISTRIBUTE);
8381
8382 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8383
8384 bgp->peer_self->rmap_type = 0;
8385
8386 if (ret == RMAP_DENYMATCH) {
8387 /* Free uninterned attribute. */
8388 bgp_attr_flush(&attr_new);
8389
8390 /* Unintern original. */
8391 aspath_unintern(&attr.aspath);
8392 bgp_redistribute_delete(bgp, p, type, instance);
8393 return;
8394 }
8395 }
8396
8397 if (bgp_in_graceful_shutdown(bgp))
8398 bgp_attr_add_gshut_community(&attr_new);
8399
8400 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8401 SAFI_UNICAST, p, NULL);
8402
8403 new_attr = bgp_attr_intern(&attr_new);
8404
8405 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8406 if (bpi->peer == bgp->peer_self
8407 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8408 break;
8409
8410 if (bpi) {
8411 /* Ensure the (source route) type is updated. */
8412 bpi->type = type;
8413 if (attrhash_cmp(bpi->attr, new_attr)
8414 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8415 bgp_attr_unintern(&new_attr);
8416 aspath_unintern(&attr.aspath);
8417 bgp_dest_unlock_node(bn);
8418 return;
8419 } else {
8420 /* The attribute is changed. */
8421 bgp_path_info_set_flag(bn, bpi,
8422 BGP_PATH_ATTR_CHANGED);
8423
8424 /* Rewrite BGP route information. */
8425 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8426 bgp_path_info_restore(bn, bpi);
8427 else
8428 bgp_aggregate_decrement(
8429 bgp, p, bpi, afi, SAFI_UNICAST);
8430 bgp_attr_unintern(&bpi->attr);
8431 bpi->attr = new_attr;
8432 bpi->uptime = bgp_clock();
8433
8434 /* Process change. */
8435 bgp_aggregate_increment(bgp, p, bpi, afi,
8436 SAFI_UNICAST);
8437 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8438 bgp_dest_unlock_node(bn);
8439 aspath_unintern(&attr.aspath);
8440
8441 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8442 || (bgp->inst_type
8443 == BGP_INSTANCE_TYPE_DEFAULT)) {
8444
8445 vpn_leak_from_vrf_update(
8446 bgp_get_default(), bgp, bpi);
8447 }
8448 return;
8449 }
8450 }
8451
8452 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8453 bgp->peer_self, new_attr, bn);
8454 SET_FLAG(new->flags, BGP_PATH_VALID);
8455
8456 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8457 bgp_path_info_add(bn, new);
8458 bgp_dest_unlock_node(bn);
8459 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8460 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8461
8462 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8463 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8464
8465 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8466 }
8467 }
8468
8469 /* Unintern original. */
8470 aspath_unintern(&attr.aspath);
8471 }
8472
8473 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8474 unsigned short instance)
8475 {
8476 afi_t afi;
8477 struct bgp_dest *dest;
8478 struct bgp_path_info *pi;
8479 struct bgp_redist *red;
8480
8481 afi = family2afi(p->family);
8482
8483 red = bgp_redist_lookup(bgp, afi, type, instance);
8484 if (red) {
8485 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8486 SAFI_UNICAST, p, NULL);
8487
8488 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8489 if (pi->peer == bgp->peer_self && pi->type == type)
8490 break;
8491
8492 if (pi) {
8493 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8494 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8495
8496 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8497 bgp, pi);
8498 }
8499 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8500 bgp_path_info_delete(dest, pi);
8501 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8502 }
8503 bgp_dest_unlock_node(dest);
8504 }
8505 }
8506
8507 /* Withdraw specified route type's route. */
8508 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8509 unsigned short instance)
8510 {
8511 struct bgp_dest *dest;
8512 struct bgp_path_info *pi;
8513 struct bgp_table *table;
8514
8515 table = bgp->rib[afi][SAFI_UNICAST];
8516
8517 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8518 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8519 if (pi->peer == bgp->peer_self && pi->type == type
8520 && pi->instance == instance)
8521 break;
8522
8523 if (pi) {
8524 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8525 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8526
8527 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8528 bgp, pi);
8529 }
8530 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8531 pi, afi, SAFI_UNICAST);
8532 bgp_path_info_delete(dest, pi);
8533 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8534 }
8535 }
8536 }
8537
8538 /* Static function to display route. */
8539 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8540 struct vty *vty, json_object *json, bool wide)
8541 {
8542 int len = 0;
8543 char buf[BUFSIZ];
8544
8545 if (p->family == AF_INET) {
8546 if (!json) {
8547 len = vty_out(vty, "%pFX", p);
8548 } else {
8549 json_object_string_add(json, "prefix",
8550 inet_ntop(p->family,
8551 &p->u.prefix, buf,
8552 BUFSIZ));
8553 json_object_int_add(json, "prefixLen", p->prefixlen);
8554 json_object_string_addf(json, "network", "%pFX", p);
8555 json_object_int_add(json, "version", dest->version);
8556 }
8557 } else if (p->family == AF_ETHERNET) {
8558 len = vty_out(vty, "%pFX", p);
8559 } else if (p->family == AF_EVPN) {
8560 if (!json)
8561 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8562 else
8563 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8564 } else if (p->family == AF_FLOWSPEC) {
8565 route_vty_out_flowspec(vty, p, NULL,
8566 json ?
8567 NLRI_STRING_FORMAT_JSON_SIMPLE :
8568 NLRI_STRING_FORMAT_MIN, json);
8569 } else {
8570 if (!json)
8571 len = vty_out(vty, "%pFX", p);
8572 else {
8573 json_object_string_add(json, "prefix",
8574 inet_ntop(p->family,
8575 &p->u.prefix, buf,
8576 BUFSIZ));
8577 json_object_int_add(json, "prefixLen", p->prefixlen);
8578 json_object_string_addf(json, "network", "%pFX", p);
8579 json_object_int_add(json, "version", dest->version);
8580 }
8581 }
8582
8583 if (!json) {
8584 len = wide ? (45 - len) : (17 - len);
8585 if (len < 1)
8586 vty_out(vty, "\n%*s", 20, " ");
8587 else
8588 vty_out(vty, "%*s", len, " ");
8589 }
8590 }
8591
8592 enum bgp_display_type {
8593 normal_list,
8594 };
8595
8596 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8597 {
8598 switch (reason) {
8599 case bgp_path_selection_none:
8600 return "Nothing to Select";
8601 case bgp_path_selection_first:
8602 return "First path received";
8603 case bgp_path_selection_evpn_sticky_mac:
8604 return "EVPN Sticky Mac";
8605 case bgp_path_selection_evpn_seq:
8606 return "EVPN sequence number";
8607 case bgp_path_selection_evpn_lower_ip:
8608 return "EVPN lower IP";
8609 case bgp_path_selection_evpn_local_path:
8610 return "EVPN local ES path";
8611 case bgp_path_selection_evpn_non_proxy:
8612 return "EVPN non proxy";
8613 case bgp_path_selection_weight:
8614 return "Weight";
8615 case bgp_path_selection_local_pref:
8616 return "Local Pref";
8617 case bgp_path_selection_local_route:
8618 return "Local Route";
8619 case bgp_path_selection_confed_as_path:
8620 return "Confederation based AS Path";
8621 case bgp_path_selection_as_path:
8622 return "AS Path";
8623 case bgp_path_selection_origin:
8624 return "Origin";
8625 case bgp_path_selection_med:
8626 return "MED";
8627 case bgp_path_selection_peer:
8628 return "Peer Type";
8629 case bgp_path_selection_confed:
8630 return "Confed Peer Type";
8631 case bgp_path_selection_igp_metric:
8632 return "IGP Metric";
8633 case bgp_path_selection_older:
8634 return "Older Path";
8635 case bgp_path_selection_router_id:
8636 return "Router ID";
8637 case bgp_path_selection_cluster_length:
8638 return "Cluster length";
8639 case bgp_path_selection_stale:
8640 return "Path Staleness";
8641 case bgp_path_selection_local_configured:
8642 return "Locally configured route";
8643 case bgp_path_selection_neighbor_ip:
8644 return "Neighbor IP";
8645 case bgp_path_selection_default:
8646 return "Nothing left to compare";
8647 }
8648 return "Invalid (internal error)";
8649 }
8650
8651 /* Print the short form route status for a bgp_path_info */
8652 static void route_vty_short_status_out(struct vty *vty,
8653 struct bgp_path_info *path,
8654 const struct prefix *p,
8655 json_object *json_path)
8656 {
8657 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8658
8659 if (json_path) {
8660
8661 /* Route status display. */
8662 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8663 json_object_boolean_true_add(json_path, "removed");
8664
8665 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8666 json_object_boolean_true_add(json_path, "stale");
8667
8668 if (path->extra && bgp_path_suppressed(path))
8669 json_object_boolean_true_add(json_path, "suppressed");
8670
8671 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8672 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8673 json_object_boolean_true_add(json_path, "valid");
8674
8675 /* Selected */
8676 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8677 json_object_boolean_true_add(json_path, "history");
8678
8679 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8680 json_object_boolean_true_add(json_path, "damped");
8681
8682 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8683 json_object_boolean_true_add(json_path, "bestpath");
8684 json_object_string_add(json_path, "selectionReason",
8685 bgp_path_selection_reason2str(
8686 path->net->reason));
8687 }
8688
8689 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8690 json_object_boolean_true_add(json_path, "multipath");
8691
8692 /* Internal route. */
8693 if ((path->peer->as)
8694 && (path->peer->as == path->peer->local_as))
8695 json_object_string_add(json_path, "pathFrom",
8696 "internal");
8697 else
8698 json_object_string_add(json_path, "pathFrom",
8699 "external");
8700
8701 return;
8702 }
8703
8704 /* RPKI validation state */
8705 rpki_state =
8706 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
8707
8708 if (rpki_state == RPKI_VALID)
8709 vty_out(vty, "V");
8710 else if (rpki_state == RPKI_INVALID)
8711 vty_out(vty, "I");
8712 else if (rpki_state == RPKI_NOTFOUND)
8713 vty_out(vty, "N");
8714
8715 /* Route status display. */
8716 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8717 vty_out(vty, "R");
8718 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8719 vty_out(vty, "S");
8720 else if (bgp_path_suppressed(path))
8721 vty_out(vty, "s");
8722 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8723 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8724 vty_out(vty, "*");
8725 else
8726 vty_out(vty, " ");
8727
8728 /* Selected */
8729 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8730 vty_out(vty, "h");
8731 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8732 vty_out(vty, "d");
8733 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8734 vty_out(vty, ">");
8735 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8736 vty_out(vty, "=");
8737 else
8738 vty_out(vty, " ");
8739
8740 /* Internal route. */
8741 if (path->peer && (path->peer->as)
8742 && (path->peer->as == path->peer->local_as))
8743 vty_out(vty, "i");
8744 else
8745 vty_out(vty, " ");
8746 }
8747
8748 static char *bgp_nexthop_hostname(struct peer *peer,
8749 struct bgp_nexthop_cache *bnc)
8750 {
8751 if (peer->hostname
8752 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8753 return peer->hostname;
8754 return NULL;
8755 }
8756
8757 /* called from terminal list command */
8758 void route_vty_out(struct vty *vty, const struct prefix *p,
8759 struct bgp_path_info *path, int display, safi_t safi,
8760 json_object *json_paths, bool wide)
8761 {
8762 int len;
8763 struct attr *attr = path->attr;
8764 json_object *json_path = NULL;
8765 json_object *json_nexthops = NULL;
8766 json_object *json_nexthop_global = NULL;
8767 json_object *json_nexthop_ll = NULL;
8768 json_object *json_ext_community = NULL;
8769 char vrf_id_str[VRF_NAMSIZ] = {0};
8770 bool nexthop_self =
8771 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8772 bool nexthop_othervrf = false;
8773 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8774 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8775 char *nexthop_hostname =
8776 bgp_nexthop_hostname(path->peer, path->nexthop);
8777 char esi_buf[ESI_STR_LEN];
8778
8779 if (json_paths)
8780 json_path = json_object_new_object();
8781
8782 /* short status lead text */
8783 route_vty_short_status_out(vty, path, p, json_path);
8784
8785 if (!json_paths) {
8786 /* print prefix and mask */
8787 if (!display)
8788 route_vty_out_route(path->net, p, vty, json_path, wide);
8789 else
8790 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8791 } else {
8792 route_vty_out_route(path->net, p, vty, json_path, wide);
8793 }
8794
8795 /*
8796 * If vrf id of nexthop is different from that of prefix,
8797 * set up printable string to append
8798 */
8799 if (path->extra && path->extra->bgp_orig) {
8800 const char *self = "";
8801
8802 if (nexthop_self)
8803 self = "<";
8804
8805 nexthop_othervrf = true;
8806 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8807
8808 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8809 snprintf(vrf_id_str, sizeof(vrf_id_str),
8810 "@%s%s", VRFID_NONE_STR, self);
8811 else
8812 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8813 path->extra->bgp_orig->vrf_id, self);
8814
8815 if (path->extra->bgp_orig->inst_type
8816 != BGP_INSTANCE_TYPE_DEFAULT)
8817
8818 nexthop_vrfname = path->extra->bgp_orig->name;
8819 } else {
8820 const char *self = "";
8821
8822 if (nexthop_self)
8823 self = "<";
8824
8825 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8826 }
8827
8828 /*
8829 * For ENCAP and EVPN routes, nexthop address family is not
8830 * neccessarily the same as the prefix address family.
8831 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
8832 * EVPN routes are also exchanged with a MP nexthop. Currently,
8833 * this
8834 * is only IPv4, the value will be present in either
8835 * attr->nexthop or
8836 * attr->mp_nexthop_global_in
8837 */
8838 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
8839 char buf[BUFSIZ];
8840 char nexthop[128];
8841 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8842
8843 switch (af) {
8844 case AF_INET:
8845 snprintf(nexthop, sizeof(nexthop), "%s",
8846 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
8847 BUFSIZ));
8848 break;
8849 case AF_INET6:
8850 snprintf(nexthop, sizeof(nexthop), "%s",
8851 inet_ntop(af, &attr->mp_nexthop_global, buf,
8852 BUFSIZ));
8853 break;
8854 default:
8855 snprintf(nexthop, sizeof(nexthop), "?");
8856 break;
8857 }
8858
8859 if (json_paths) {
8860 json_nexthop_global = json_object_new_object();
8861
8862 json_object_string_add(json_nexthop_global, "ip",
8863 nexthop);
8864
8865 if (path->peer->hostname)
8866 json_object_string_add(json_nexthop_global,
8867 "hostname",
8868 path->peer->hostname);
8869
8870 json_object_string_add(json_nexthop_global, "afi",
8871 (af == AF_INET) ? "ipv4"
8872 : "ipv6");
8873 json_object_boolean_true_add(json_nexthop_global,
8874 "used");
8875 } else {
8876 if (nexthop_hostname)
8877 len = vty_out(vty, "%s(%s)%s", nexthop,
8878 nexthop_hostname, vrf_id_str);
8879 else
8880 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
8881
8882 len = wide ? (41 - len) : (16 - len);
8883 if (len < 1)
8884 vty_out(vty, "\n%*s", 36, " ");
8885 else
8886 vty_out(vty, "%*s", len, " ");
8887 }
8888 } else if (safi == SAFI_EVPN) {
8889 if (json_paths) {
8890 json_nexthop_global = json_object_new_object();
8891
8892 json_object_string_addf(json_nexthop_global, "ip",
8893 "%pI4", &attr->nexthop);
8894
8895 if (path->peer->hostname)
8896 json_object_string_add(json_nexthop_global,
8897 "hostname",
8898 path->peer->hostname);
8899
8900 json_object_string_add(json_nexthop_global, "afi",
8901 "ipv4");
8902 json_object_boolean_true_add(json_nexthop_global,
8903 "used");
8904 } else {
8905 if (nexthop_hostname)
8906 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8907 nexthop_hostname, vrf_id_str);
8908 else
8909 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8910 vrf_id_str);
8911
8912 len = wide ? (41 - len) : (16 - len);
8913 if (len < 1)
8914 vty_out(vty, "\n%*s", 36, " ");
8915 else
8916 vty_out(vty, "%*s", len, " ");
8917 }
8918 } else if (safi == SAFI_FLOWSPEC) {
8919 if (attr->nexthop.s_addr != INADDR_ANY) {
8920 if (json_paths) {
8921 json_nexthop_global = json_object_new_object();
8922
8923 json_object_string_add(json_nexthop_global,
8924 "afi", "ipv4");
8925 json_object_string_addf(json_nexthop_global,
8926 "ip", "%pI4",
8927 &attr->nexthop);
8928
8929 if (path->peer->hostname)
8930 json_object_string_add(
8931 json_nexthop_global, "hostname",
8932 path->peer->hostname);
8933
8934 json_object_boolean_true_add(
8935 json_nexthop_global,
8936 "used");
8937 } else {
8938 if (nexthop_hostname)
8939 len = vty_out(vty, "%pI4(%s)%s",
8940 &attr->nexthop,
8941 nexthop_hostname,
8942 vrf_id_str);
8943 else
8944 len = vty_out(vty, "%pI4%s",
8945 &attr->nexthop,
8946 vrf_id_str);
8947
8948 len = wide ? (41 - len) : (16 - len);
8949 if (len < 1)
8950 vty_out(vty, "\n%*s", 36, " ");
8951 else
8952 vty_out(vty, "%*s", len, " ");
8953 }
8954 }
8955 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8956 if (json_paths) {
8957 json_nexthop_global = json_object_new_object();
8958
8959 json_object_string_addf(json_nexthop_global, "ip",
8960 "%pI4", &attr->nexthop);
8961
8962 if (path->peer->hostname)
8963 json_object_string_add(json_nexthop_global,
8964 "hostname",
8965 path->peer->hostname);
8966
8967 json_object_string_add(json_nexthop_global, "afi",
8968 "ipv4");
8969 json_object_boolean_true_add(json_nexthop_global,
8970 "used");
8971 } else {
8972 if (nexthop_hostname)
8973 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8974 nexthop_hostname, vrf_id_str);
8975 else
8976 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8977 vrf_id_str);
8978
8979 len = wide ? (41 - len) : (16 - len);
8980 if (len < 1)
8981 vty_out(vty, "\n%*s", 36, " ");
8982 else
8983 vty_out(vty, "%*s", len, " ");
8984 }
8985 }
8986
8987 /* IPv6 Next Hop */
8988 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8989 if (json_paths) {
8990 json_nexthop_global = json_object_new_object();
8991 json_object_string_addf(json_nexthop_global, "ip",
8992 "%pI6",
8993 &attr->mp_nexthop_global);
8994
8995 if (path->peer->hostname)
8996 json_object_string_add(json_nexthop_global,
8997 "hostname",
8998 path->peer->hostname);
8999
9000 json_object_string_add(json_nexthop_global, "afi",
9001 "ipv6");
9002 json_object_string_add(json_nexthop_global, "scope",
9003 "global");
9004
9005 /* We display both LL & GL if both have been
9006 * received */
9007 if ((attr->mp_nexthop_len
9008 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9009 || (path->peer->conf_if)) {
9010 json_nexthop_ll = json_object_new_object();
9011 json_object_string_addf(
9012 json_nexthop_ll, "ip", "%pI6",
9013 &attr->mp_nexthop_local);
9014
9015 if (path->peer->hostname)
9016 json_object_string_add(
9017 json_nexthop_ll, "hostname",
9018 path->peer->hostname);
9019
9020 json_object_string_add(json_nexthop_ll, "afi",
9021 "ipv6");
9022 json_object_string_add(json_nexthop_ll, "scope",
9023 "link-local");
9024
9025 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9026 &attr->mp_nexthop_local)
9027 != 0)
9028 && !attr->mp_nexthop_prefer_global)
9029 json_object_boolean_true_add(
9030 json_nexthop_ll, "used");
9031 else
9032 json_object_boolean_true_add(
9033 json_nexthop_global, "used");
9034 } else
9035 json_object_boolean_true_add(
9036 json_nexthop_global, "used");
9037 } else {
9038 /* Display LL if LL/Global both in table unless
9039 * prefer-global is set */
9040 if (((attr->mp_nexthop_len
9041 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9042 && !attr->mp_nexthop_prefer_global)
9043 || (path->peer->conf_if)) {
9044 if (path->peer->conf_if) {
9045 len = vty_out(vty, "%s",
9046 path->peer->conf_if);
9047 /* len of IPv6 addr + max len of def
9048 * ifname */
9049 len = wide ? (41 - len) : (16 - len);
9050
9051 if (len < 1)
9052 vty_out(vty, "\n%*s", 36, " ");
9053 else
9054 vty_out(vty, "%*s", len, " ");
9055 } else {
9056 if (nexthop_hostname)
9057 len = vty_out(
9058 vty, "%pI6(%s)%s",
9059 &attr->mp_nexthop_local,
9060 nexthop_hostname,
9061 vrf_id_str);
9062 else
9063 len = vty_out(
9064 vty, "%pI6%s",
9065 &attr->mp_nexthop_local,
9066 vrf_id_str);
9067
9068 len = wide ? (41 - len) : (16 - len);
9069
9070 if (len < 1)
9071 vty_out(vty, "\n%*s", 36, " ");
9072 else
9073 vty_out(vty, "%*s", len, " ");
9074 }
9075 } else {
9076 if (nexthop_hostname)
9077 len = vty_out(vty, "%pI6(%s)%s",
9078 &attr->mp_nexthop_global,
9079 nexthop_hostname,
9080 vrf_id_str);
9081 else
9082 len = vty_out(vty, "%pI6%s",
9083 &attr->mp_nexthop_global,
9084 vrf_id_str);
9085
9086 len = wide ? (41 - len) : (16 - len);
9087
9088 if (len < 1)
9089 vty_out(vty, "\n%*s", 36, " ");
9090 else
9091 vty_out(vty, "%*s", len, " ");
9092 }
9093 }
9094 }
9095
9096 /* MED/Metric */
9097 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9098 if (json_paths)
9099 json_object_int_add(json_path, "metric", attr->med);
9100 else if (wide)
9101 vty_out(vty, "%7u", attr->med);
9102 else
9103 vty_out(vty, "%10u", attr->med);
9104 else if (!json_paths) {
9105 if (wide)
9106 vty_out(vty, "%*s", 7, " ");
9107 else
9108 vty_out(vty, "%*s", 10, " ");
9109 }
9110
9111 /* Local Pref */
9112 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9113 if (json_paths)
9114 json_object_int_add(json_path, "locPrf",
9115 attr->local_pref);
9116 else
9117 vty_out(vty, "%7u", attr->local_pref);
9118 else if (!json_paths)
9119 vty_out(vty, " ");
9120
9121 if (json_paths)
9122 json_object_int_add(json_path, "weight", attr->weight);
9123 else
9124 vty_out(vty, "%7u ", attr->weight);
9125
9126 if (json_paths) {
9127 char buf[BUFSIZ];
9128 json_object_string_add(
9129 json_path, "peerId",
9130 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
9131 }
9132
9133 /* Print aspath */
9134 if (attr->aspath) {
9135 if (json_paths)
9136 json_object_string_add(json_path, "path",
9137 attr->aspath->str);
9138 else
9139 aspath_print_vty(vty, "%s", attr->aspath, " ");
9140 }
9141
9142 /* Print origin */
9143 if (json_paths)
9144 json_object_string_add(json_path, "origin",
9145 bgp_origin_long_str[attr->origin]);
9146 else
9147 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9148
9149 if (json_paths) {
9150 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9151 json_object_string_add(json_path, "esi",
9152 esi_to_str(&attr->esi,
9153 esi_buf, sizeof(esi_buf)));
9154 }
9155 if (safi == SAFI_EVPN &&
9156 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9157 json_ext_community = json_object_new_object();
9158 json_object_string_add(
9159 json_ext_community, "string",
9160 bgp_attr_get_ecommunity(attr)->str);
9161 json_object_object_add(json_path,
9162 "extendedCommunity",
9163 json_ext_community);
9164 }
9165
9166 if (nexthop_self)
9167 json_object_boolean_true_add(json_path,
9168 "announceNexthopSelf");
9169 if (nexthop_othervrf) {
9170 json_object_string_add(json_path, "nhVrfName",
9171 nexthop_vrfname);
9172
9173 json_object_int_add(json_path, "nhVrfId",
9174 ((nexthop_vrfid == VRF_UNKNOWN)
9175 ? -1
9176 : (int)nexthop_vrfid));
9177 }
9178 }
9179
9180 if (json_paths) {
9181 if (json_nexthop_global || json_nexthop_ll) {
9182 json_nexthops = json_object_new_array();
9183
9184 if (json_nexthop_global)
9185 json_object_array_add(json_nexthops,
9186 json_nexthop_global);
9187
9188 if (json_nexthop_ll)
9189 json_object_array_add(json_nexthops,
9190 json_nexthop_ll);
9191
9192 json_object_object_add(json_path, "nexthops",
9193 json_nexthops);
9194 }
9195
9196 json_object_array_add(json_paths, json_path);
9197 } else {
9198 vty_out(vty, "\n");
9199
9200 if (safi == SAFI_EVPN) {
9201 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9202 /* XXX - add these params to the json out */
9203 vty_out(vty, "%*s", 20, " ");
9204 vty_out(vty, "ESI:%s",
9205 esi_to_str(&attr->esi, esi_buf,
9206 sizeof(esi_buf)));
9207
9208 vty_out(vty, "\n");
9209 }
9210 if (attr->flag &
9211 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9212 vty_out(vty, "%*s", 20, " ");
9213 vty_out(vty, "%s\n",
9214 bgp_attr_get_ecommunity(attr)->str);
9215 }
9216 }
9217
9218 #ifdef ENABLE_BGP_VNC
9219 /* prints an additional line, indented, with VNC info, if
9220 * present */
9221 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9222 rfapi_vty_out_vncinfo(vty, p, path, safi);
9223 #endif
9224 }
9225 }
9226
9227 /* called from terminal list command */
9228 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9229 const struct prefix *p, struct attr *attr, safi_t safi,
9230 bool use_json, json_object *json_ar, bool wide)
9231 {
9232 json_object *json_status = NULL;
9233 json_object *json_net = NULL;
9234 int len;
9235 char buff[BUFSIZ];
9236
9237 /* Route status display. */
9238 if (use_json) {
9239 json_status = json_object_new_object();
9240 json_net = json_object_new_object();
9241 } else {
9242 vty_out(vty, "*");
9243 vty_out(vty, ">");
9244 vty_out(vty, " ");
9245 }
9246
9247 /* print prefix and mask */
9248 if (use_json) {
9249 if (safi == SAFI_EVPN)
9250 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9251 else if (p->family == AF_INET || p->family == AF_INET6) {
9252 json_object_string_add(
9253 json_net, "addrPrefix",
9254 inet_ntop(p->family, &p->u.prefix, buff,
9255 BUFSIZ));
9256 json_object_int_add(json_net, "prefixLen",
9257 p->prefixlen);
9258 json_object_string_addf(json_net, "network", "%pFX", p);
9259 }
9260 } else
9261 route_vty_out_route(dest, p, vty, NULL, wide);
9262
9263 /* Print attribute */
9264 if (attr) {
9265 if (use_json) {
9266 if (p->family == AF_INET
9267 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9268 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9269 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9270 json_object_string_addf(
9271 json_net, "nextHop", "%pI4",
9272 &attr->mp_nexthop_global_in);
9273 else
9274 json_object_string_addf(
9275 json_net, "nextHop", "%pI4",
9276 &attr->nexthop);
9277 } else if (p->family == AF_INET6
9278 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9279 json_object_string_addf(
9280 json_net, "nextHopGlobal", "%pI6",
9281 &attr->mp_nexthop_global);
9282 } else if (p->family == AF_EVPN
9283 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9284 json_object_string_addf(
9285 json_net, "nextHop", "%pI4",
9286 &attr->mp_nexthop_global_in);
9287 }
9288
9289 if (attr->flag
9290 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9291 json_object_int_add(json_net, "metric",
9292 attr->med);
9293
9294 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9295 json_object_int_add(json_net, "locPrf",
9296 attr->local_pref);
9297
9298 json_object_int_add(json_net, "weight", attr->weight);
9299
9300 /* Print aspath */
9301 if (attr->aspath)
9302 json_object_string_add(json_net, "path",
9303 attr->aspath->str);
9304
9305 /* Print origin */
9306 json_object_string_add(json_net, "bgpOriginCode",
9307 bgp_origin_str[attr->origin]);
9308 } else {
9309 if (p->family == AF_INET
9310 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9311 || safi == SAFI_EVPN
9312 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9313 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9314 || safi == SAFI_EVPN)
9315 vty_out(vty, "%-16pI4",
9316 &attr->mp_nexthop_global_in);
9317 else if (wide)
9318 vty_out(vty, "%-41pI4", &attr->nexthop);
9319 else
9320 vty_out(vty, "%-16pI4", &attr->nexthop);
9321 } else if (p->family == AF_INET6
9322 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9323 char buf[BUFSIZ];
9324
9325 len = vty_out(
9326 vty, "%s",
9327 inet_ntop(AF_INET6,
9328 &attr->mp_nexthop_global, buf,
9329 BUFSIZ));
9330 len = wide ? (41 - len) : (16 - len);
9331 if (len < 1)
9332 vty_out(vty, "\n%*s", 36, " ");
9333 else
9334 vty_out(vty, "%*s", len, " ");
9335 }
9336 if (attr->flag
9337 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9338 if (wide)
9339 vty_out(vty, "%7u", attr->med);
9340 else
9341 vty_out(vty, "%10u", attr->med);
9342 else if (wide)
9343 vty_out(vty, " ");
9344 else
9345 vty_out(vty, " ");
9346
9347 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9348 vty_out(vty, "%7u", attr->local_pref);
9349 else
9350 vty_out(vty, " ");
9351
9352 vty_out(vty, "%7u ", attr->weight);
9353
9354 /* Print aspath */
9355 if (attr->aspath)
9356 aspath_print_vty(vty, "%s", attr->aspath, " ");
9357
9358 /* Print origin */
9359 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9360 }
9361 }
9362 if (use_json) {
9363 json_object_boolean_true_add(json_status, "*");
9364 json_object_boolean_true_add(json_status, ">");
9365 json_object_object_add(json_net, "appliedStatusSymbols",
9366 json_status);
9367
9368 prefix2str(p, buff, PREFIX_STRLEN);
9369 json_object_object_add(json_ar, buff, json_net);
9370 } else
9371 vty_out(vty, "\n");
9372 }
9373
9374 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9375 struct bgp_path_info *path, int display, safi_t safi,
9376 json_object *json)
9377 {
9378 json_object *json_out = NULL;
9379 struct attr *attr;
9380 mpls_label_t label = MPLS_INVALID_LABEL;
9381
9382 if (!path->extra)
9383 return;
9384
9385 if (json)
9386 json_out = json_object_new_object();
9387
9388 /* short status lead text */
9389 route_vty_short_status_out(vty, path, p, json_out);
9390
9391 /* print prefix and mask */
9392 if (json == NULL) {
9393 if (!display)
9394 route_vty_out_route(path->net, p, vty, NULL, false);
9395 else
9396 vty_out(vty, "%*s", 17, " ");
9397 }
9398
9399 /* Print attribute */
9400 attr = path->attr;
9401 if (((p->family == AF_INET)
9402 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9403 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9404 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9405 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9406 || safi == SAFI_EVPN) {
9407 if (json)
9408 json_object_string_addf(
9409 json_out, "mpNexthopGlobalIn", "%pI4",
9410 &attr->mp_nexthop_global_in);
9411 else
9412 vty_out(vty, "%-16pI4",
9413 &attr->mp_nexthop_global_in);
9414 } else {
9415 if (json)
9416 json_object_string_addf(json_out, "nexthop",
9417 "%pI4", &attr->nexthop);
9418 else
9419 vty_out(vty, "%-16pI4", &attr->nexthop);
9420 }
9421 } else if (((p->family == AF_INET6)
9422 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9423 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9424 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9425 char buf_a[512];
9426
9427 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9428 if (json)
9429 json_object_string_addf(
9430 json_out, "mpNexthopGlobalIn", "%pI6",
9431 &attr->mp_nexthop_global);
9432 else
9433 vty_out(vty, "%s",
9434 inet_ntop(AF_INET6,
9435 &attr->mp_nexthop_global,
9436 buf_a, sizeof(buf_a)));
9437 } else if (attr->mp_nexthop_len
9438 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9439 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9440 &attr->mp_nexthop_global,
9441 &attr->mp_nexthop_local);
9442 if (json)
9443 json_object_string_add(json_out,
9444 "mpNexthopGlobalLocal",
9445 buf_a);
9446 else
9447 vty_out(vty, "%s", buf_a);
9448 }
9449 }
9450
9451 label = decode_label(&path->extra->label[0]);
9452
9453 if (bgp_is_valid_label(&label)) {
9454 if (json) {
9455 json_object_int_add(json_out, "notag", label);
9456 json_object_array_add(json, json_out);
9457 } else {
9458 vty_out(vty, "notag/%d", label);
9459 vty_out(vty, "\n");
9460 }
9461 } else if (!json)
9462 vty_out(vty, "\n");
9463 }
9464
9465 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9466 struct bgp_path_info *path, int display,
9467 json_object *json_paths)
9468 {
9469 struct attr *attr;
9470 json_object *json_path = NULL;
9471 json_object *json_nexthop = NULL;
9472 json_object *json_overlay = NULL;
9473
9474 if (!path->extra)
9475 return;
9476
9477 if (json_paths) {
9478 json_path = json_object_new_object();
9479 json_overlay = json_object_new_object();
9480 json_nexthop = json_object_new_object();
9481 }
9482
9483 /* short status lead text */
9484 route_vty_short_status_out(vty, path, p, json_path);
9485
9486 /* print prefix and mask */
9487 if (!display)
9488 route_vty_out_route(path->net, p, vty, json_path, false);
9489 else
9490 vty_out(vty, "%*s", 17, " ");
9491
9492 /* Print attribute */
9493 attr = path->attr;
9494 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9495
9496 switch (af) {
9497 case AF_INET:
9498 if (!json_path) {
9499 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9500 } else {
9501 json_object_string_addf(json_nexthop, "ip", "%pI4",
9502 &attr->mp_nexthop_global_in);
9503
9504 json_object_string_add(json_nexthop, "afi", "ipv4");
9505
9506 json_object_object_add(json_path, "nexthop",
9507 json_nexthop);
9508 }
9509 break;
9510 case AF_INET6:
9511 if (!json_path) {
9512 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9513 &attr->mp_nexthop_local);
9514 } else {
9515 json_object_string_addf(json_nexthop, "ipv6Global",
9516 "%pI6",
9517 &attr->mp_nexthop_global);
9518
9519 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9520 "%pI6",
9521 &attr->mp_nexthop_local);
9522
9523 json_object_string_add(json_nexthop, "afi", "ipv6");
9524
9525 json_object_object_add(json_path, "nexthop",
9526 json_nexthop);
9527 }
9528 break;
9529 default:
9530 if (!json_path) {
9531 vty_out(vty, "?");
9532 } else {
9533 json_object_string_add(json_nexthop, "Error",
9534 "Unsupported address-family");
9535 json_object_string_add(json_nexthop, "error",
9536 "Unsupported address-family");
9537 }
9538 }
9539
9540 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9541
9542 if (!json_path)
9543 vty_out(vty, "/%pIA", &eo->gw_ip);
9544 else
9545 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9546
9547 if (bgp_attr_get_ecommunity(attr)) {
9548 char *mac = NULL;
9549 struct ecommunity_val *routermac = ecommunity_lookup(
9550 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9551 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9552
9553 if (routermac)
9554 mac = ecom_mac2str((char *)routermac->val);
9555 if (mac) {
9556 if (!json_path) {
9557 vty_out(vty, "/%s", mac);
9558 } else {
9559 json_object_string_add(json_overlay, "rmac",
9560 mac);
9561 }
9562 XFREE(MTYPE_TMP, mac);
9563 }
9564 }
9565
9566 if (!json_path) {
9567 vty_out(vty, "\n");
9568 } else {
9569 json_object_object_add(json_path, "overlay", json_overlay);
9570
9571 json_object_array_add(json_paths, json_path);
9572 }
9573 }
9574
9575 /* dampening route */
9576 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9577 struct bgp_path_info *path, int display,
9578 afi_t afi, safi_t safi, bool use_json,
9579 json_object *json_paths)
9580 {
9581 struct attr *attr = path->attr;
9582 int len;
9583 char timebuf[BGP_UPTIME_LEN];
9584 json_object *json_path = NULL;
9585
9586 if (use_json)
9587 json_path = json_object_new_object();
9588
9589 /* short status lead text */
9590 route_vty_short_status_out(vty, path, p, json_path);
9591
9592 /* print prefix and mask */
9593 if (!use_json) {
9594 if (!display)
9595 route_vty_out_route(path->net, p, vty, NULL, false);
9596 else
9597 vty_out(vty, "%*s", 17, " ");
9598
9599 len = vty_out(vty, "%s", path->peer->host);
9600 len = 17 - len;
9601
9602 if (len < 1)
9603 vty_out(vty, "\n%*s", 34, " ");
9604 else
9605 vty_out(vty, "%*s", len, " ");
9606
9607 vty_out(vty, "%s ",
9608 bgp_damp_reuse_time_vty(vty, path, timebuf,
9609 BGP_UPTIME_LEN, afi, safi,
9610 use_json, NULL));
9611
9612 if (attr->aspath)
9613 aspath_print_vty(vty, "%s", attr->aspath, " ");
9614
9615 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9616
9617 vty_out(vty, "\n");
9618 } else {
9619 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9620 safi, use_json, json_path);
9621
9622 if (attr->aspath)
9623 json_object_string_add(json_path, "asPath",
9624 attr->aspath->str);
9625
9626 json_object_string_add(json_path, "origin",
9627 bgp_origin_str[attr->origin]);
9628 json_object_string_add(json_path, "peerHost", path->peer->host);
9629
9630 json_object_array_add(json_paths, json_path);
9631 }
9632 }
9633
9634 /* flap route */
9635 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9636 struct bgp_path_info *path, int display,
9637 afi_t afi, safi_t safi, bool use_json,
9638 json_object *json_paths)
9639 {
9640 struct attr *attr = path->attr;
9641 struct bgp_damp_info *bdi;
9642 char timebuf[BGP_UPTIME_LEN];
9643 int len;
9644 json_object *json_path = NULL;
9645
9646 if (!path->extra)
9647 return;
9648
9649 if (use_json)
9650 json_path = json_object_new_object();
9651
9652 bdi = path->extra->damp_info;
9653
9654 /* short status lead text */
9655 route_vty_short_status_out(vty, path, p, json_path);
9656
9657 if (!use_json) {
9658 if (!display)
9659 route_vty_out_route(path->net, p, vty, NULL, false);
9660 else
9661 vty_out(vty, "%*s", 17, " ");
9662
9663 len = vty_out(vty, "%s", path->peer->host);
9664 len = 16 - len;
9665 if (len < 1)
9666 vty_out(vty, "\n%*s", 33, " ");
9667 else
9668 vty_out(vty, "%*s", len, " ");
9669
9670 len = vty_out(vty, "%d", bdi->flap);
9671 len = 5 - len;
9672 if (len < 1)
9673 vty_out(vty, " ");
9674 else
9675 vty_out(vty, "%*s", len, " ");
9676
9677 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9678 BGP_UPTIME_LEN, 0, NULL));
9679
9680 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9681 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9682 vty_out(vty, "%s ",
9683 bgp_damp_reuse_time_vty(vty, path, timebuf,
9684 BGP_UPTIME_LEN, afi,
9685 safi, use_json, NULL));
9686 else
9687 vty_out(vty, "%*s ", 8, " ");
9688
9689 if (attr->aspath)
9690 aspath_print_vty(vty, "%s", attr->aspath, " ");
9691
9692 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9693
9694 vty_out(vty, "\n");
9695 } else {
9696 json_object_string_add(json_path, "peerHost", path->peer->host);
9697 json_object_int_add(json_path, "bdiFlap", bdi->flap);
9698
9699 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9700 json_path);
9701
9702 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9703 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9704 bgp_damp_reuse_time_vty(vty, path, timebuf,
9705 BGP_UPTIME_LEN, afi, safi,
9706 use_json, json_path);
9707
9708 if (attr->aspath)
9709 json_object_string_add(json_path, "asPath",
9710 attr->aspath->str);
9711
9712 json_object_string_add(json_path, "origin",
9713 bgp_origin_str[attr->origin]);
9714
9715 json_object_array_add(json_paths, json_path);
9716 }
9717 }
9718
9719 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9720 int *first, const char *header,
9721 json_object *json_adv_to)
9722 {
9723 char buf1[INET6_ADDRSTRLEN];
9724 json_object *json_peer = NULL;
9725
9726 if (json_adv_to) {
9727 /* 'advertised-to' is a dictionary of peers we have advertised
9728 * this
9729 * prefix too. The key is the peer's IP or swpX, the value is
9730 * the
9731 * hostname if we know it and "" if not.
9732 */
9733 json_peer = json_object_new_object();
9734
9735 if (peer->hostname)
9736 json_object_string_add(json_peer, "hostname",
9737 peer->hostname);
9738
9739 if (peer->conf_if)
9740 json_object_object_add(json_adv_to, peer->conf_if,
9741 json_peer);
9742 else
9743 json_object_object_add(
9744 json_adv_to,
9745 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
9746 json_peer);
9747 } else {
9748 if (*first) {
9749 vty_out(vty, "%s", header);
9750 *first = 0;
9751 }
9752
9753 if (peer->hostname
9754 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9755 if (peer->conf_if)
9756 vty_out(vty, " %s(%s)", peer->hostname,
9757 peer->conf_if);
9758 else
9759 vty_out(vty, " %s(%s)", peer->hostname,
9760 sockunion2str(&peer->su, buf1,
9761 SU_ADDRSTRLEN));
9762 } else {
9763 if (peer->conf_if)
9764 vty_out(vty, " %s", peer->conf_if);
9765 else
9766 vty_out(vty, " %s",
9767 sockunion2str(&peer->su, buf1,
9768 SU_ADDRSTRLEN));
9769 }
9770 }
9771 }
9772
9773 static void route_vty_out_tx_ids(struct vty *vty,
9774 struct bgp_addpath_info_data *d)
9775 {
9776 int i;
9777
9778 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9779 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9780 d->addpath_tx_id[i],
9781 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9782 }
9783 }
9784
9785 static void route_vty_out_detail_es_info(struct vty *vty,
9786 struct bgp_path_info *pi,
9787 struct attr *attr,
9788 json_object *json_path)
9789 {
9790 char esi_buf[ESI_STR_LEN];
9791 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9792 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9793 ATTR_ES_PEER_ROUTER);
9794 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9795 ATTR_ES_PEER_ACTIVE);
9796 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9797 ATTR_ES_PEER_PROXY);
9798 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9799 if (json_path) {
9800 json_object *json_es_info = NULL;
9801
9802 json_object_string_add(
9803 json_path, "esi",
9804 esi_buf);
9805 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9806 json_es_info = json_object_new_object();
9807 if (es_local)
9808 json_object_boolean_true_add(
9809 json_es_info, "localEs");
9810 if (peer_active)
9811 json_object_boolean_true_add(
9812 json_es_info, "peerActive");
9813 if (peer_proxy)
9814 json_object_boolean_true_add(
9815 json_es_info, "peerProxy");
9816 if (peer_router)
9817 json_object_boolean_true_add(
9818 json_es_info, "peerRouter");
9819 if (attr->mm_sync_seqnum)
9820 json_object_int_add(
9821 json_es_info, "peerSeq",
9822 attr->mm_sync_seqnum);
9823 json_object_object_add(
9824 json_path, "es_info",
9825 json_es_info);
9826 }
9827 } else {
9828 if (bgp_evpn_attr_is_sync(attr))
9829 vty_out(vty,
9830 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9831 esi_buf,
9832 es_local ? "local-es":"",
9833 peer_proxy ? "proxy " : "",
9834 peer_active ? "active ":"",
9835 peer_router ? "router ":"",
9836 attr->mm_sync_seqnum);
9837 else
9838 vty_out(vty, " ESI %s %s\n",
9839 esi_buf,
9840 es_local ? "local-es":"");
9841 }
9842 }
9843
9844 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
9845 struct bgp_path_info *path, afi_t afi, safi_t safi,
9846 enum rpki_states rpki_curr_state,
9847 json_object *json_paths)
9848 {
9849 char buf[INET6_ADDRSTRLEN];
9850 char buf1[BUFSIZ];
9851 struct attr *attr = path->attr;
9852 int sockunion_vty_out(struct vty *, union sockunion *);
9853 time_t tbuf;
9854 json_object *json_bestpath = NULL;
9855 json_object *json_cluster_list = NULL;
9856 json_object *json_cluster_list_list = NULL;
9857 json_object *json_ext_community = NULL;
9858 json_object *json_last_update = NULL;
9859 json_object *json_pmsi = NULL;
9860 json_object *json_nexthop_global = NULL;
9861 json_object *json_nexthop_ll = NULL;
9862 json_object *json_nexthops = NULL;
9863 json_object *json_path = NULL;
9864 json_object *json_peer = NULL;
9865 json_object *json_string = NULL;
9866 json_object *json_adv_to = NULL;
9867 int first = 0;
9868 struct listnode *node, *nnode;
9869 struct peer *peer;
9870 bool addpath_capable;
9871 int has_adj;
9872 unsigned int first_as;
9873 bool nexthop_self =
9874 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9875 int i;
9876 char *nexthop_hostname =
9877 bgp_nexthop_hostname(path->peer, path->nexthop);
9878
9879 if (json_paths) {
9880 json_path = json_object_new_object();
9881 json_peer = json_object_new_object();
9882 json_nexthop_global = json_object_new_object();
9883 }
9884
9885 if (safi == SAFI_EVPN) {
9886 if (!json_paths)
9887 vty_out(vty, " Route %pRN", bn);
9888 }
9889
9890 if (path->extra) {
9891 char tag_buf[30];
9892
9893 tag_buf[0] = '\0';
9894 if (path->extra && path->extra->num_labels) {
9895 bgp_evpn_label2str(path->extra->label,
9896 path->extra->num_labels, tag_buf,
9897 sizeof(tag_buf));
9898 }
9899 if (safi == SAFI_EVPN) {
9900 if (!json_paths) {
9901 if (tag_buf[0] != '\0')
9902 vty_out(vty, " VNI %s", tag_buf);
9903 } else {
9904 if (tag_buf[0]) {
9905 json_object_string_add(json_path, "VNI",
9906 tag_buf);
9907 json_object_string_add(json_path, "vni",
9908 tag_buf);
9909 }
9910 }
9911 }
9912
9913 if (path->extra && path->extra->parent && !json_paths) {
9914 struct bgp_path_info *parent_ri;
9915 struct bgp_dest *dest, *pdest;
9916
9917 parent_ri = (struct bgp_path_info *)path->extra->parent;
9918 dest = parent_ri->net;
9919 if (dest && dest->pdest) {
9920 pdest = dest->pdest;
9921 prefix_rd2str(
9922 (struct prefix_rd *)bgp_dest_get_prefix(
9923 pdest),
9924 buf1, sizeof(buf1));
9925 if (is_pi_family_evpn(parent_ri)) {
9926 vty_out(vty,
9927 " Imported from %s:%pFX, VNI %s",
9928 buf1,
9929 (struct prefix_evpn *)
9930 bgp_dest_get_prefix(
9931 dest),
9932 tag_buf);
9933 if (attr->es_flags & ATTR_ES_L3_NHG)
9934 vty_out(vty, ", L3NHG %s",
9935 (attr->es_flags
9936 & ATTR_ES_L3_NHG_ACTIVE)
9937 ? "active"
9938 : "inactive");
9939 vty_out(vty, "\n");
9940
9941 } else
9942 vty_out(vty,
9943 " Imported from %s:%pFX\n",
9944 buf1,
9945 (struct prefix_evpn *)
9946 bgp_dest_get_prefix(
9947 dest));
9948 }
9949 }
9950 }
9951
9952 if (safi == SAFI_EVPN
9953 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
9954 char gwip_buf[INET6_ADDRSTRLEN];
9955
9956 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
9957 sizeof(gwip_buf));
9958
9959 if (json_paths)
9960 json_object_string_add(json_path, "gatewayIP",
9961 gwip_buf);
9962 else
9963 vty_out(vty, " Gateway IP %s", gwip_buf);
9964 }
9965
9966 if (safi == SAFI_EVPN)
9967 vty_out(vty, "\n");
9968
9969 /* Line1 display AS-path, Aggregator */
9970 if (attr->aspath) {
9971 if (json_paths) {
9972 if (!attr->aspath->json)
9973 aspath_str_update(attr->aspath, true);
9974 json_object_lock(attr->aspath->json);
9975 json_object_object_add(json_path, "aspath",
9976 attr->aspath->json);
9977 } else {
9978 if (attr->aspath->segments)
9979 aspath_print_vty(vty, " %s", attr->aspath, "");
9980 else
9981 vty_out(vty, " Local");
9982 }
9983 }
9984
9985 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9986 if (json_paths)
9987 json_object_boolean_true_add(json_path, "removed");
9988 else
9989 vty_out(vty, ", (removed)");
9990 }
9991
9992 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9993 if (json_paths)
9994 json_object_boolean_true_add(json_path, "stale");
9995 else
9996 vty_out(vty, ", (stale)");
9997 }
9998
9999 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10000 if (json_paths) {
10001 json_object_int_add(json_path, "aggregatorAs",
10002 attr->aggregator_as);
10003 json_object_string_addf(json_path, "aggregatorId",
10004 "%pI4", &attr->aggregator_addr);
10005 } else {
10006 vty_out(vty, ", (aggregated by %u %pI4)",
10007 attr->aggregator_as, &attr->aggregator_addr);
10008 }
10009 }
10010
10011 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10012 PEER_FLAG_REFLECTOR_CLIENT)) {
10013 if (json_paths)
10014 json_object_boolean_true_add(json_path,
10015 "rxedFromRrClient");
10016 else
10017 vty_out(vty, ", (Received from a RR-client)");
10018 }
10019
10020 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10021 PEER_FLAG_RSERVER_CLIENT)) {
10022 if (json_paths)
10023 json_object_boolean_true_add(json_path,
10024 "rxedFromRsClient");
10025 else
10026 vty_out(vty, ", (Received from a RS-client)");
10027 }
10028
10029 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10030 if (json_paths)
10031 json_object_boolean_true_add(json_path,
10032 "dampeningHistoryEntry");
10033 else
10034 vty_out(vty, ", (history entry)");
10035 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10036 if (json_paths)
10037 json_object_boolean_true_add(json_path,
10038 "dampeningSuppressed");
10039 else
10040 vty_out(vty, ", (suppressed due to dampening)");
10041 }
10042
10043 if (!json_paths)
10044 vty_out(vty, "\n");
10045
10046 /* Line2 display Next-hop, Neighbor, Router-id */
10047 /* Display the nexthop */
10048 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10049
10050 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
10051 || bn_p->family == AF_EVPN)
10052 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
10053 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
10054 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10055 || safi == SAFI_EVPN) {
10056 if (json_paths) {
10057 json_object_string_addf(
10058 json_nexthop_global, "ip", "%pI4",
10059 &attr->mp_nexthop_global_in);
10060
10061 if (path->peer->hostname)
10062 json_object_string_add(
10063 json_nexthop_global, "hostname",
10064 path->peer->hostname);
10065 } else {
10066 if (nexthop_hostname)
10067 vty_out(vty, " %pI4(%s)",
10068 &attr->mp_nexthop_global_in,
10069 nexthop_hostname);
10070 else
10071 vty_out(vty, " %pI4",
10072 &attr->mp_nexthop_global_in);
10073 }
10074 } else {
10075 if (json_paths) {
10076 json_object_string_addf(json_nexthop_global,
10077 "ip", "%pI4",
10078 &attr->nexthop);
10079
10080 if (path->peer->hostname)
10081 json_object_string_add(
10082 json_nexthop_global, "hostname",
10083 path->peer->hostname);
10084 } else {
10085 if (nexthop_hostname)
10086 vty_out(vty, " %pI4(%s)",
10087 &attr->nexthop,
10088 nexthop_hostname);
10089 else
10090 vty_out(vty, " %pI4",
10091 &attr->nexthop);
10092 }
10093 }
10094
10095 if (json_paths)
10096 json_object_string_add(json_nexthop_global, "afi",
10097 "ipv4");
10098 } else {
10099 if (json_paths) {
10100 json_object_string_addf(json_nexthop_global, "ip",
10101 "%pI6",
10102 &attr->mp_nexthop_global);
10103
10104 if (path->peer->hostname)
10105 json_object_string_add(json_nexthop_global,
10106 "hostname",
10107 path->peer->hostname);
10108
10109 json_object_string_add(json_nexthop_global, "afi",
10110 "ipv6");
10111 json_object_string_add(json_nexthop_global, "scope",
10112 "global");
10113 } else {
10114 if (nexthop_hostname)
10115 vty_out(vty, " %pI6(%s)",
10116 &attr->mp_nexthop_global,
10117 nexthop_hostname);
10118 else
10119 vty_out(vty, " %pI6",
10120 &attr->mp_nexthop_global);
10121 }
10122 }
10123
10124 /* Display the IGP cost or 'inaccessible' */
10125 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10126 if (json_paths)
10127 json_object_boolean_false_add(json_nexthop_global,
10128 "accessible");
10129 else
10130 vty_out(vty, " (inaccessible)");
10131 } else {
10132 if (path->extra && path->extra->igpmetric) {
10133 if (json_paths)
10134 json_object_int_add(json_nexthop_global,
10135 "metric",
10136 path->extra->igpmetric);
10137 else
10138 vty_out(vty, " (metric %u)",
10139 path->extra->igpmetric);
10140 }
10141
10142 /* IGP cost is 0, display this only for json */
10143 else {
10144 if (json_paths)
10145 json_object_int_add(json_nexthop_global,
10146 "metric", 0);
10147 }
10148
10149 if (json_paths)
10150 json_object_boolean_true_add(json_nexthop_global,
10151 "accessible");
10152 }
10153
10154 /* Display peer "from" output */
10155 /* This path was originated locally */
10156 if (path->peer == bgp->peer_self) {
10157
10158 if (safi == SAFI_EVPN
10159 || (bn_p->family == AF_INET
10160 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
10161 if (json_paths)
10162 json_object_string_add(json_peer, "peerId",
10163 "0.0.0.0");
10164 else
10165 vty_out(vty, " from 0.0.0.0 ");
10166 } else {
10167 if (json_paths)
10168 json_object_string_add(json_peer, "peerId",
10169 "::");
10170 else
10171 vty_out(vty, " from :: ");
10172 }
10173
10174 if (json_paths)
10175 json_object_string_addf(json_peer, "routerId", "%pI4",
10176 &bgp->router_id);
10177 else
10178 vty_out(vty, "(%pI4)", &bgp->router_id);
10179 }
10180
10181 /* We RXed this path from one of our peers */
10182 else {
10183
10184 if (json_paths) {
10185 json_object_string_add(json_peer, "peerId",
10186 sockunion2str(&path->peer->su,
10187 buf,
10188 SU_ADDRSTRLEN));
10189 json_object_string_addf(json_peer, "routerId", "%pI4",
10190 &path->peer->remote_id);
10191
10192 if (path->peer->hostname)
10193 json_object_string_add(json_peer, "hostname",
10194 path->peer->hostname);
10195
10196 if (path->peer->domainname)
10197 json_object_string_add(json_peer, "domainname",
10198 path->peer->domainname);
10199
10200 if (path->peer->conf_if)
10201 json_object_string_add(json_peer, "interface",
10202 path->peer->conf_if);
10203 } else {
10204 if (path->peer->conf_if) {
10205 if (path->peer->hostname
10206 && CHECK_FLAG(path->peer->bgp->flags,
10207 BGP_FLAG_SHOW_HOSTNAME))
10208 vty_out(vty, " from %s(%s)",
10209 path->peer->hostname,
10210 path->peer->conf_if);
10211 else
10212 vty_out(vty, " from %s",
10213 path->peer->conf_if);
10214 } else {
10215 if (path->peer->hostname
10216 && CHECK_FLAG(path->peer->bgp->flags,
10217 BGP_FLAG_SHOW_HOSTNAME))
10218 vty_out(vty, " from %s(%s)",
10219 path->peer->hostname,
10220 path->peer->host);
10221 else
10222 vty_out(vty, " from %s",
10223 sockunion2str(&path->peer->su,
10224 buf,
10225 SU_ADDRSTRLEN));
10226 }
10227
10228 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10229 vty_out(vty, " (%pI4)", &attr->originator_id);
10230 else
10231 vty_out(vty, " (%s)",
10232 inet_ntop(AF_INET,
10233 &path->peer->remote_id, buf1,
10234 sizeof(buf1)));
10235 }
10236 }
10237
10238 /*
10239 * Note when vrfid of nexthop is different from that of prefix
10240 */
10241 if (path->extra && path->extra->bgp_orig) {
10242 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10243
10244 if (json_paths) {
10245 const char *vn;
10246
10247 if (path->extra->bgp_orig->inst_type
10248 == BGP_INSTANCE_TYPE_DEFAULT)
10249 vn = VRF_DEFAULT_NAME;
10250 else
10251 vn = path->extra->bgp_orig->name;
10252
10253 json_object_string_add(json_path, "nhVrfName", vn);
10254
10255 if (nexthop_vrfid == VRF_UNKNOWN) {
10256 json_object_int_add(json_path, "nhVrfId", -1);
10257 } else {
10258 json_object_int_add(json_path, "nhVrfId",
10259 (int)nexthop_vrfid);
10260 }
10261 } else {
10262 if (nexthop_vrfid == VRF_UNKNOWN)
10263 vty_out(vty, " vrf ?");
10264 else {
10265 struct vrf *vrf;
10266
10267 vrf = vrf_lookup_by_id(nexthop_vrfid);
10268 vty_out(vty, " vrf %s(%u)",
10269 VRF_LOGNAME(vrf), nexthop_vrfid);
10270 }
10271 }
10272 }
10273
10274 if (nexthop_self) {
10275 if (json_paths) {
10276 json_object_boolean_true_add(json_path,
10277 "announceNexthopSelf");
10278 } else {
10279 vty_out(vty, " announce-nh-self");
10280 }
10281 }
10282
10283 if (!json_paths)
10284 vty_out(vty, "\n");
10285
10286 /* display the link-local nexthop */
10287 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10288 if (json_paths) {
10289 json_nexthop_ll = json_object_new_object();
10290 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10291 &attr->mp_nexthop_local);
10292
10293 if (path->peer->hostname)
10294 json_object_string_add(json_nexthop_ll,
10295 "hostname",
10296 path->peer->hostname);
10297
10298 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10299 json_object_string_add(json_nexthop_ll, "scope",
10300 "link-local");
10301
10302 json_object_boolean_true_add(json_nexthop_ll,
10303 "accessible");
10304
10305 if (!attr->mp_nexthop_prefer_global)
10306 json_object_boolean_true_add(json_nexthop_ll,
10307 "used");
10308 else
10309 json_object_boolean_true_add(
10310 json_nexthop_global, "used");
10311 } else {
10312 vty_out(vty, " (%s) %s\n",
10313 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10314 buf, INET6_ADDRSTRLEN),
10315 attr->mp_nexthop_prefer_global
10316 ? "(prefer-global)"
10317 : "(used)");
10318 }
10319 }
10320 /* If we do not have a link-local nexthop then we must flag the
10321 global as "used" */
10322 else {
10323 if (json_paths)
10324 json_object_boolean_true_add(json_nexthop_global,
10325 "used");
10326 }
10327
10328 if (safi == SAFI_EVPN &&
10329 bgp_evpn_is_esi_valid(&attr->esi)) {
10330 route_vty_out_detail_es_info(vty, path, attr, json_path);
10331 }
10332
10333 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10334 * Int/Ext/Local, Atomic, best */
10335 if (json_paths)
10336 json_object_string_add(json_path, "origin",
10337 bgp_origin_long_str[attr->origin]);
10338 else
10339 vty_out(vty, " Origin %s",
10340 bgp_origin_long_str[attr->origin]);
10341
10342 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10343 if (json_paths)
10344 json_object_int_add(json_path, "metric", attr->med);
10345 else
10346 vty_out(vty, ", metric %u", attr->med);
10347 }
10348
10349 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10350 if (json_paths)
10351 json_object_int_add(json_path, "locPrf",
10352 attr->local_pref);
10353 else
10354 vty_out(vty, ", localpref %u", attr->local_pref);
10355 }
10356
10357 if (attr->weight != 0) {
10358 if (json_paths)
10359 json_object_int_add(json_path, "weight", attr->weight);
10360 else
10361 vty_out(vty, ", weight %u", attr->weight);
10362 }
10363
10364 if (attr->tag != 0) {
10365 if (json_paths)
10366 json_object_int_add(json_path, "tag", attr->tag);
10367 else
10368 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10369 }
10370
10371 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10372 if (json_paths)
10373 json_object_boolean_false_add(json_path, "valid");
10374 else
10375 vty_out(vty, ", invalid");
10376 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10377 if (json_paths)
10378 json_object_boolean_true_add(json_path, "valid");
10379 else
10380 vty_out(vty, ", valid");
10381 }
10382
10383 if (json_paths)
10384 json_object_int_add(json_path, "version", bn->version);
10385
10386 if (path->peer != bgp->peer_self) {
10387 if (path->peer->as == path->peer->local_as) {
10388 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10389 if (json_paths)
10390 json_object_string_add(
10391 json_peer, "type",
10392 "confed-internal");
10393 else
10394 vty_out(vty, ", confed-internal");
10395 } else {
10396 if (json_paths)
10397 json_object_string_add(
10398 json_peer, "type", "internal");
10399 else
10400 vty_out(vty, ", internal");
10401 }
10402 } else {
10403 if (bgp_confederation_peers_check(bgp,
10404 path->peer->as)) {
10405 if (json_paths)
10406 json_object_string_add(
10407 json_peer, "type",
10408 "confed-external");
10409 else
10410 vty_out(vty, ", confed-external");
10411 } else {
10412 if (json_paths)
10413 json_object_string_add(
10414 json_peer, "type", "external");
10415 else
10416 vty_out(vty, ", external");
10417 }
10418 }
10419 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10420 if (json_paths) {
10421 json_object_boolean_true_add(json_path, "aggregated");
10422 json_object_boolean_true_add(json_path, "local");
10423 } else {
10424 vty_out(vty, ", aggregated, local");
10425 }
10426 } else if (path->type != ZEBRA_ROUTE_BGP) {
10427 if (json_paths)
10428 json_object_boolean_true_add(json_path, "sourced");
10429 else
10430 vty_out(vty, ", sourced");
10431 } else {
10432 if (json_paths) {
10433 json_object_boolean_true_add(json_path, "sourced");
10434 json_object_boolean_true_add(json_path, "local");
10435 } else {
10436 vty_out(vty, ", sourced, local");
10437 }
10438 }
10439
10440 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10441 if (json_paths)
10442 json_object_boolean_true_add(json_path,
10443 "atomicAggregate");
10444 else
10445 vty_out(vty, ", atomic-aggregate");
10446 }
10447
10448 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10449 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10450 && bgp_path_info_mpath_count(path))) {
10451 if (json_paths)
10452 json_object_boolean_true_add(json_path, "multipath");
10453 else
10454 vty_out(vty, ", multipath");
10455 }
10456
10457 // Mark the bestpath(s)
10458 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10459 first_as = aspath_get_first_as(attr->aspath);
10460
10461 if (json_paths) {
10462 if (!json_bestpath)
10463 json_bestpath = json_object_new_object();
10464 json_object_int_add(json_bestpath, "bestpathFromAs",
10465 first_as);
10466 } else {
10467 if (first_as)
10468 vty_out(vty, ", bestpath-from-AS %u", first_as);
10469 else
10470 vty_out(vty, ", bestpath-from-AS Local");
10471 }
10472 }
10473
10474 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10475 if (json_paths) {
10476 if (!json_bestpath)
10477 json_bestpath = json_object_new_object();
10478 json_object_boolean_true_add(json_bestpath, "overall");
10479 json_object_string_add(
10480 json_bestpath, "selectionReason",
10481 bgp_path_selection_reason2str(bn->reason));
10482 } else {
10483 vty_out(vty, ", best");
10484 vty_out(vty, " (%s)",
10485 bgp_path_selection_reason2str(bn->reason));
10486 }
10487 }
10488
10489 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10490 if (json_paths)
10491 json_object_string_add(
10492 json_path, "rpkiValidationState",
10493 bgp_rpki_validation2str(rpki_curr_state));
10494 else
10495 vty_out(vty, ", rpki validation-state: %s",
10496 bgp_rpki_validation2str(rpki_curr_state));
10497 }
10498
10499 if (json_bestpath)
10500 json_object_object_add(json_path, "bestpath", json_bestpath);
10501
10502 if (!json_paths)
10503 vty_out(vty, "\n");
10504
10505 /* Line 4 display Community */
10506 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10507 if (json_paths) {
10508 if (!bgp_attr_get_community(attr)->json)
10509 community_str(bgp_attr_get_community(attr),
10510 true, true);
10511 json_object_lock(bgp_attr_get_community(attr)->json);
10512 json_object_object_add(
10513 json_path, "community",
10514 bgp_attr_get_community(attr)->json);
10515 } else {
10516 vty_out(vty, " Community: %s\n",
10517 bgp_attr_get_community(attr)->str);
10518 }
10519 }
10520
10521 /* Line 5 display Extended-community */
10522 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10523 if (json_paths) {
10524 json_ext_community = json_object_new_object();
10525 json_object_string_add(
10526 json_ext_community, "string",
10527 bgp_attr_get_ecommunity(attr)->str);
10528 json_object_object_add(json_path, "extendedCommunity",
10529 json_ext_community);
10530 } else {
10531 vty_out(vty, " Extended Community: %s\n",
10532 bgp_attr_get_ecommunity(attr)->str);
10533 }
10534 }
10535
10536 /* Line 6 display Large community */
10537 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10538 if (json_paths) {
10539 if (!bgp_attr_get_lcommunity(attr)->json)
10540 lcommunity_str(bgp_attr_get_lcommunity(attr),
10541 true, true);
10542 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10543 json_object_object_add(
10544 json_path, "largeCommunity",
10545 bgp_attr_get_lcommunity(attr)->json);
10546 } else {
10547 vty_out(vty, " Large Community: %s\n",
10548 bgp_attr_get_lcommunity(attr)->str);
10549 }
10550 }
10551
10552 /* Line 7 display Originator, Cluster-id */
10553 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10554 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10555 char buf[BUFSIZ] = {0};
10556
10557 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10558 if (json_paths)
10559 json_object_string_addf(json_path,
10560 "originatorId", "%pI4",
10561 &attr->originator_id);
10562 else
10563 vty_out(vty, " Originator: %pI4",
10564 &attr->originator_id);
10565 }
10566
10567 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10568 struct cluster_list *cluster =
10569 bgp_attr_get_cluster(attr);
10570 int i;
10571
10572 if (json_paths) {
10573 json_cluster_list = json_object_new_object();
10574 json_cluster_list_list =
10575 json_object_new_array();
10576
10577 for (i = 0; i < cluster->length / 4; i++) {
10578 json_string = json_object_new_string(
10579 inet_ntop(AF_INET,
10580 &cluster->list[i],
10581 buf, sizeof(buf)));
10582 json_object_array_add(
10583 json_cluster_list_list,
10584 json_string);
10585 }
10586
10587 /*
10588 * struct cluster_list does not have
10589 * "str" variable like aspath and community
10590 * do. Add this someday if someone asks
10591 * for it.
10592 * json_object_string_add(json_cluster_list,
10593 * "string", cluster->str);
10594 */
10595 json_object_object_add(json_cluster_list,
10596 "list",
10597 json_cluster_list_list);
10598 json_object_object_add(json_path, "clusterList",
10599 json_cluster_list);
10600 } else {
10601 vty_out(vty, ", Cluster list: ");
10602
10603 for (i = 0; i < cluster->length / 4; i++) {
10604 vty_out(vty, "%pI4 ",
10605 &cluster->list[i]);
10606 }
10607 }
10608 }
10609
10610 if (!json_paths)
10611 vty_out(vty, "\n");
10612 }
10613
10614 if (path->extra && path->extra->damp_info)
10615 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10616
10617 /* Remote Label */
10618 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10619 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10620 mpls_label_t label = label_pton(&path->extra->label[0]);
10621
10622 if (json_paths)
10623 json_object_int_add(json_path, "remoteLabel", label);
10624 else
10625 vty_out(vty, " Remote label: %d\n", label);
10626 }
10627
10628 /* Remote SID */
10629 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10630 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
10631 if (json_paths)
10632 json_object_string_add(json_path, "remoteSid", buf);
10633 else
10634 vty_out(vty, " Remote SID: %s\n", buf);
10635 }
10636
10637 /* Label Index */
10638 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10639 if (json_paths)
10640 json_object_int_add(json_path, "labelIndex",
10641 attr->label_index);
10642 else
10643 vty_out(vty, " Label Index: %d\n",
10644 attr->label_index);
10645 }
10646
10647 /* Line 8 display Addpath IDs */
10648 if (path->addpath_rx_id
10649 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10650 if (json_paths) {
10651 json_object_int_add(json_path, "addpathRxId",
10652 path->addpath_rx_id);
10653
10654 /* Keep backwards compatibility with the old API
10655 * by putting TX All's ID in the old field
10656 */
10657 json_object_int_add(
10658 json_path, "addpathTxId",
10659 path->tx_addpath
10660 .addpath_tx_id[BGP_ADDPATH_ALL]);
10661
10662 /* ... but create a specific field for each
10663 * strategy
10664 */
10665 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10666 json_object_int_add(
10667 json_path,
10668 bgp_addpath_names(i)->id_json_name,
10669 path->tx_addpath.addpath_tx_id[i]);
10670 }
10671 } else {
10672 vty_out(vty, " AddPath ID: RX %u, ",
10673 path->addpath_rx_id);
10674
10675 route_vty_out_tx_ids(vty, &path->tx_addpath);
10676 }
10677 }
10678
10679 /* If we used addpath to TX a non-bestpath we need to display
10680 * "Advertised to" on a path-by-path basis
10681 */
10682 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10683 first = 1;
10684
10685 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10686 addpath_capable =
10687 bgp_addpath_encode_tx(peer, afi, safi);
10688 has_adj = bgp_adj_out_lookup(
10689 peer, path->net,
10690 bgp_addpath_id_for_peer(peer, afi, safi,
10691 &path->tx_addpath));
10692
10693 if ((addpath_capable && has_adj)
10694 || (!addpath_capable && has_adj
10695 && CHECK_FLAG(path->flags,
10696 BGP_PATH_SELECTED))) {
10697 if (json_path && !json_adv_to)
10698 json_adv_to = json_object_new_object();
10699
10700 route_vty_out_advertised_to(
10701 vty, peer, &first,
10702 " Advertised to:", json_adv_to);
10703 }
10704 }
10705
10706 if (json_path) {
10707 if (json_adv_to) {
10708 json_object_object_add(
10709 json_path, "advertisedTo", json_adv_to);
10710 }
10711 } else {
10712 if (!first) {
10713 vty_out(vty, "\n");
10714 }
10715 }
10716 }
10717
10718 /* Line 9 display Uptime */
10719 tbuf = time(NULL) - (bgp_clock() - path->uptime);
10720 if (json_paths) {
10721 json_last_update = json_object_new_object();
10722 json_object_int_add(json_last_update, "epoch", tbuf);
10723 json_object_string_add(json_last_update, "string",
10724 ctime(&tbuf));
10725 json_object_object_add(json_path, "lastUpdate",
10726 json_last_update);
10727 } else
10728 vty_out(vty, " Last update: %s", ctime(&tbuf));
10729
10730 /* Line 10 display PMSI tunnel attribute, if present */
10731 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10732 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10733 bgp_attr_get_pmsi_tnl_type(attr),
10734 PMSI_TNLTYPE_STR_DEFAULT);
10735
10736 if (json_paths) {
10737 json_pmsi = json_object_new_object();
10738 json_object_string_add(json_pmsi, "tunnelType", str);
10739 json_object_int_add(json_pmsi, "label",
10740 label2vni(&attr->label));
10741 json_object_object_add(json_path, "pmsi", json_pmsi);
10742 } else
10743 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10744 str, label2vni(&attr->label));
10745 }
10746
10747 if (path->peer->t_gr_restart &&
10748 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10749 unsigned long gr_remaining =
10750 thread_timer_remain_second(path->peer->t_gr_restart);
10751
10752 if (json_paths) {
10753 json_object_int_add(json_path,
10754 "gracefulRestartSecondsRemaining",
10755 gr_remaining);
10756 } else
10757 vty_out(vty,
10758 " Time until Graceful Restart stale route deleted: %lu\n",
10759 gr_remaining);
10760 }
10761
10762 if (path->peer->t_llgr_stale[afi][safi] &&
10763 bgp_attr_get_community(attr) &&
10764 community_include(bgp_attr_get_community(attr),
10765 COMMUNITY_LLGR_STALE)) {
10766 unsigned long llgr_remaining = thread_timer_remain_second(
10767 path->peer->t_llgr_stale[afi][safi]);
10768
10769 if (json_paths) {
10770 json_object_int_add(json_path, "llgrSecondsRemaining",
10771 llgr_remaining);
10772 } else
10773 vty_out(vty,
10774 " Time until Long-lived stale route deleted: %lu\n",
10775 llgr_remaining);
10776 }
10777
10778 /* Output some debug about internal state of the dest flags */
10779 if (json_paths) {
10780 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10781 json_object_boolean_true_add(json_path, "processScheduled");
10782 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10783 json_object_boolean_true_add(json_path, "userCleared");
10784 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10785 json_object_boolean_true_add(json_path, "labelChanged");
10786 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10787 json_object_boolean_true_add(json_path, "registeredForLabel");
10788 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10789 json_object_boolean_true_add(json_path, "selectDefered");
10790 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10791 json_object_boolean_true_add(json_path, "fibInstalled");
10792 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10793 json_object_boolean_true_add(json_path, "fibPending");
10794
10795 if (json_nexthop_global || json_nexthop_ll) {
10796 json_nexthops = json_object_new_array();
10797
10798 if (json_nexthop_global)
10799 json_object_array_add(json_nexthops,
10800 json_nexthop_global);
10801
10802 if (json_nexthop_ll)
10803 json_object_array_add(json_nexthops,
10804 json_nexthop_ll);
10805
10806 json_object_object_add(json_path, "nexthops",
10807 json_nexthops);
10808 }
10809
10810 json_object_object_add(json_path, "peer", json_peer);
10811 json_object_array_add(json_paths, json_path);
10812 }
10813 }
10814
10815 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10816 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10817 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10818
10819 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10820 afi_t afi, safi_t safi, enum bgp_show_type type,
10821 bool use_json);
10822 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10823 const char *comstr, int exact, afi_t afi,
10824 safi_t safi, uint16_t show_flags);
10825
10826 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10827 struct bgp_table *table, enum bgp_show_type type,
10828 void *output_arg, const char *rd, int is_last,
10829 unsigned long *output_cum, unsigned long *total_cum,
10830 unsigned long *json_header_depth, uint16_t show_flags,
10831 enum rpki_states rpki_target_state)
10832 {
10833 struct bgp_path_info *pi;
10834 struct bgp_dest *dest;
10835 bool header = true;
10836 bool json_detail_header = false;
10837 int display;
10838 unsigned long output_count = 0;
10839 unsigned long total_count = 0;
10840 struct prefix *p;
10841 json_object *json_paths = NULL;
10842 int first = 1;
10843 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10844 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10845 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10846
10847 if (output_cum && *output_cum != 0)
10848 header = false;
10849
10850 if (use_json && !*json_header_depth) {
10851 if (all)
10852 *json_header_depth = 1;
10853 else {
10854 vty_out(vty, "{\n");
10855 *json_header_depth = 2;
10856 }
10857
10858 vty_out(vty,
10859 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10860 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10861 " \"localAS\": %u,\n \"routes\": { ",
10862 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10863 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
10864 ? VRF_DEFAULT_NAME
10865 : bgp->name,
10866 table->version, &bgp->router_id,
10867 bgp->default_local_pref, bgp->as);
10868 if (rd) {
10869 vty_out(vty, " \"routeDistinguishers\" : {");
10870 ++*json_header_depth;
10871 }
10872 }
10873
10874 if (use_json && rd) {
10875 vty_out(vty, " \"%s\" : { ", rd);
10876 }
10877
10878 /* Check for 'json detail', where we need header output once per dest */
10879 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
10880 type != bgp_show_type_dampend_paths &&
10881 type != bgp_show_type_damp_neighbor &&
10882 type != bgp_show_type_flap_statistics &&
10883 type != bgp_show_type_flap_neighbor)
10884 json_detail_header = true;
10885
10886 /* Start processing of routes. */
10887 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
10888 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10889 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
10890 bool json_detail = json_detail_header;
10891
10892 pi = bgp_dest_get_bgp_path_info(dest);
10893 if (pi == NULL)
10894 continue;
10895
10896 display = 0;
10897 if (use_json)
10898 json_paths = json_object_new_array();
10899 else
10900 json_paths = NULL;
10901
10902 for (; pi; pi = pi->next) {
10903 struct community *picomm = NULL;
10904
10905 picomm = bgp_attr_get_community(pi->attr);
10906
10907 total_count++;
10908
10909 if (type == bgp_show_type_prefix_version) {
10910 uint32_t version =
10911 strtoul(output_arg, NULL, 10);
10912 if (dest->version < version)
10913 continue;
10914 }
10915
10916 if (type == bgp_show_type_community_alias) {
10917 char *alias = output_arg;
10918 char **communities;
10919 int num;
10920 bool found = false;
10921
10922 if (picomm) {
10923 frrstr_split(picomm->str, " ",
10924 &communities, &num);
10925 for (int i = 0; i < num; i++) {
10926 const char *com2alias =
10927 bgp_community2alias(
10928 communities[i]);
10929 if (!found
10930 && strcmp(alias, com2alias)
10931 == 0)
10932 found = true;
10933 XFREE(MTYPE_TMP,
10934 communities[i]);
10935 }
10936 XFREE(MTYPE_TMP, communities);
10937 }
10938
10939 if (!found &&
10940 bgp_attr_get_lcommunity(pi->attr)) {
10941 frrstr_split(bgp_attr_get_lcommunity(
10942 pi->attr)
10943 ->str,
10944 " ", &communities, &num);
10945 for (int i = 0; i < num; i++) {
10946 const char *com2alias =
10947 bgp_community2alias(
10948 communities[i]);
10949 if (!found
10950 && strcmp(alias, com2alias)
10951 == 0)
10952 found = true;
10953 XFREE(MTYPE_TMP,
10954 communities[i]);
10955 }
10956 XFREE(MTYPE_TMP, communities);
10957 }
10958
10959 if (!found)
10960 continue;
10961 }
10962
10963 if (type == bgp_show_type_rpki) {
10964 if (dest_p->family == AF_INET
10965 || dest_p->family == AF_INET6)
10966 rpki_curr_state = hook_call(
10967 bgp_rpki_prefix_status,
10968 pi->peer, pi->attr, dest_p);
10969 if (rpki_target_state != RPKI_NOT_BEING_USED
10970 && rpki_curr_state != rpki_target_state)
10971 continue;
10972 }
10973
10974 if (type == bgp_show_type_flap_statistics
10975 || type == bgp_show_type_flap_neighbor
10976 || type == bgp_show_type_dampend_paths
10977 || type == bgp_show_type_damp_neighbor) {
10978 if (!(pi->extra && pi->extra->damp_info))
10979 continue;
10980 }
10981 if (type == bgp_show_type_regexp) {
10982 regex_t *regex = output_arg;
10983
10984 if (bgp_regexec(regex, pi->attr->aspath)
10985 == REG_NOMATCH)
10986 continue;
10987 }
10988 if (type == bgp_show_type_prefix_list) {
10989 struct prefix_list *plist = output_arg;
10990
10991 if (prefix_list_apply(plist, dest_p)
10992 != PREFIX_PERMIT)
10993 continue;
10994 }
10995 if (type == bgp_show_type_filter_list) {
10996 struct as_list *as_list = output_arg;
10997
10998 if (as_list_apply(as_list, pi->attr->aspath)
10999 != AS_FILTER_PERMIT)
11000 continue;
11001 }
11002 if (type == bgp_show_type_route_map) {
11003 struct route_map *rmap = output_arg;
11004 struct bgp_path_info path;
11005 struct attr dummy_attr;
11006 route_map_result_t ret;
11007
11008 dummy_attr = *pi->attr;
11009
11010 path.peer = pi->peer;
11011 path.attr = &dummy_attr;
11012
11013 ret = route_map_apply(rmap, dest_p, &path);
11014 bgp_attr_flush(&dummy_attr);
11015 if (ret == RMAP_DENYMATCH)
11016 continue;
11017 }
11018 if (type == bgp_show_type_neighbor
11019 || type == bgp_show_type_flap_neighbor
11020 || type == bgp_show_type_damp_neighbor) {
11021 union sockunion *su = output_arg;
11022
11023 if (pi->peer == NULL
11024 || pi->peer->su_remote == NULL
11025 || !sockunion_same(pi->peer->su_remote, su))
11026 continue;
11027 }
11028 if (type == bgp_show_type_cidr_only) {
11029 uint32_t destination;
11030
11031 destination = ntohl(dest_p->u.prefix4.s_addr);
11032 if (IN_CLASSC(destination)
11033 && dest_p->prefixlen == 24)
11034 continue;
11035 if (IN_CLASSB(destination)
11036 && dest_p->prefixlen == 16)
11037 continue;
11038 if (IN_CLASSA(destination)
11039 && dest_p->prefixlen == 8)
11040 continue;
11041 }
11042 if (type == bgp_show_type_prefix_longer) {
11043 p = output_arg;
11044 if (!prefix_match(p, dest_p))
11045 continue;
11046 }
11047 if (type == bgp_show_type_community_all) {
11048 if (!picomm)
11049 continue;
11050 }
11051 if (type == bgp_show_type_community) {
11052 struct community *com = output_arg;
11053
11054 if (!picomm || !community_match(picomm, com))
11055 continue;
11056 }
11057 if (type == bgp_show_type_community_exact) {
11058 struct community *com = output_arg;
11059
11060 if (!picomm || !community_cmp(picomm, com))
11061 continue;
11062 }
11063 if (type == bgp_show_type_community_list) {
11064 struct community_list *list = output_arg;
11065
11066 if (!community_list_match(picomm, list))
11067 continue;
11068 }
11069 if (type == bgp_show_type_community_list_exact) {
11070 struct community_list *list = output_arg;
11071
11072 if (!community_list_exact_match(picomm, list))
11073 continue;
11074 }
11075 if (type == bgp_show_type_lcommunity) {
11076 struct lcommunity *lcom = output_arg;
11077
11078 if (!bgp_attr_get_lcommunity(pi->attr) ||
11079 !lcommunity_match(
11080 bgp_attr_get_lcommunity(pi->attr),
11081 lcom))
11082 continue;
11083 }
11084
11085 if (type == bgp_show_type_lcommunity_exact) {
11086 struct lcommunity *lcom = output_arg;
11087
11088 if (!bgp_attr_get_lcommunity(pi->attr) ||
11089 !lcommunity_cmp(
11090 bgp_attr_get_lcommunity(pi->attr),
11091 lcom))
11092 continue;
11093 }
11094 if (type == bgp_show_type_lcommunity_list) {
11095 struct community_list *list = output_arg;
11096
11097 if (!lcommunity_list_match(
11098 bgp_attr_get_lcommunity(pi->attr),
11099 list))
11100 continue;
11101 }
11102 if (type
11103 == bgp_show_type_lcommunity_list_exact) {
11104 struct community_list *list = output_arg;
11105
11106 if (!lcommunity_list_exact_match(
11107 bgp_attr_get_lcommunity(pi->attr),
11108 list))
11109 continue;
11110 }
11111 if (type == bgp_show_type_lcommunity_all) {
11112 if (!bgp_attr_get_lcommunity(pi->attr))
11113 continue;
11114 }
11115 if (type == bgp_show_type_dampend_paths
11116 || type == bgp_show_type_damp_neighbor) {
11117 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11118 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11119 continue;
11120 }
11121
11122 if (!use_json && header) {
11123 vty_out(vty,
11124 "BGP table version is %" PRIu64
11125 ", local router ID is %pI4, vrf id ",
11126 table->version, &bgp->router_id);
11127 if (bgp->vrf_id == VRF_UNKNOWN)
11128 vty_out(vty, "%s", VRFID_NONE_STR);
11129 else
11130 vty_out(vty, "%u", bgp->vrf_id);
11131 vty_out(vty, "\n");
11132 vty_out(vty, "Default local pref %u, ",
11133 bgp->default_local_pref);
11134 vty_out(vty, "local AS %u\n", bgp->as);
11135 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11136 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11137 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11138 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11139 if (type == bgp_show_type_dampend_paths
11140 || type == bgp_show_type_damp_neighbor)
11141 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11142 else if (type == bgp_show_type_flap_statistics
11143 || type == bgp_show_type_flap_neighbor)
11144 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11145 else
11146 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11147 : BGP_SHOW_HEADER));
11148 header = false;
11149
11150 } else if (json_detail && json_paths != NULL) {
11151 const struct prefix_rd *prd;
11152 json_object *jtemp;
11153
11154 /* Use common detail header, for most types;
11155 * need a json 'object'.
11156 */
11157
11158 jtemp = json_object_new_object();
11159 prd = bgp_rd_from_dest(dest, safi);
11160
11161 route_vty_out_detail_header(
11162 vty, bgp, dest, prd, table->afi,
11163 safi, jtemp);
11164
11165 json_object_array_add(json_paths, jtemp);
11166
11167 json_detail = false;
11168 }
11169
11170 if (rd != NULL && !display && !output_count) {
11171 if (!use_json)
11172 vty_out(vty,
11173 "Route Distinguisher: %s\n",
11174 rd);
11175 }
11176 if (type == bgp_show_type_dampend_paths
11177 || type == bgp_show_type_damp_neighbor)
11178 damp_route_vty_out(vty, dest_p, pi, display,
11179 AFI_IP, safi, use_json,
11180 json_paths);
11181 else if (type == bgp_show_type_flap_statistics
11182 || type == bgp_show_type_flap_neighbor)
11183 flap_route_vty_out(vty, dest_p, pi, display,
11184 AFI_IP, safi, use_json,
11185 json_paths);
11186 else {
11187 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11188 route_vty_out_detail(
11189 vty, bgp, dest, pi,
11190 family2afi(dest_p->family),
11191 safi, RPKI_NOT_BEING_USED,
11192 json_paths);
11193 else
11194 route_vty_out(vty, dest_p, pi, display,
11195 safi, json_paths, wide);
11196 }
11197 display++;
11198 }
11199
11200 if (display) {
11201 output_count++;
11202 if (!use_json)
11203 continue;
11204
11205 /* encode prefix */
11206 if (dest_p->family == AF_FLOWSPEC) {
11207 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11208
11209
11210 bgp_fs_nlri_get_string(
11211 (unsigned char *)
11212 dest_p->u.prefix_flowspec.ptr,
11213 dest_p->u.prefix_flowspec.prefixlen,
11214 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11215 family2afi(dest_p->u
11216 .prefix_flowspec.family));
11217 if (first)
11218 vty_out(vty, "\"%s/%d\": ", retstr,
11219 dest_p->u.prefix_flowspec
11220 .prefixlen);
11221 else
11222 vty_out(vty, ",\"%s/%d\": ", retstr,
11223 dest_p->u.prefix_flowspec
11224 .prefixlen);
11225 } else {
11226 if (first)
11227 vty_out(vty, "\"%pFX\": ", dest_p);
11228 else
11229 vty_out(vty, ",\"%pFX\": ", dest_p);
11230 }
11231 vty_json(vty, json_paths);
11232 json_paths = NULL;
11233 first = 0;
11234 } else
11235 json_object_free(json_paths);
11236 }
11237
11238 if (output_cum) {
11239 output_count += *output_cum;
11240 *output_cum = output_count;
11241 }
11242 if (total_cum) {
11243 total_count += *total_cum;
11244 *total_cum = total_count;
11245 }
11246 if (use_json) {
11247 if (rd) {
11248 vty_out(vty, " }%s ", (is_last ? "" : ","));
11249 }
11250 if (is_last) {
11251 unsigned long i;
11252 for (i = 0; i < *json_header_depth; ++i)
11253 vty_out(vty, " } ");
11254 if (!all)
11255 vty_out(vty, "\n");
11256 }
11257 } else {
11258 if (is_last) {
11259 /* No route is displayed */
11260 if (output_count == 0) {
11261 if (type == bgp_show_type_normal)
11262 vty_out(vty,
11263 "No BGP prefixes displayed, %ld exist\n",
11264 total_count);
11265 } else
11266 vty_out(vty,
11267 "\nDisplayed %ld routes and %ld total paths\n",
11268 output_count, total_count);
11269 }
11270 }
11271
11272 return CMD_SUCCESS;
11273 }
11274
11275 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11276 struct bgp_table *table, struct prefix_rd *prd_match,
11277 enum bgp_show_type type, void *output_arg, bool use_json)
11278 {
11279 struct bgp_dest *dest, *next;
11280 unsigned long output_cum = 0;
11281 unsigned long total_cum = 0;
11282 unsigned long json_header_depth = 0;
11283 struct bgp_table *itable;
11284 bool show_msg;
11285 uint16_t show_flags = 0;
11286
11287 show_msg = (!use_json && type == bgp_show_type_normal);
11288
11289 if (use_json)
11290 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11291
11292 for (dest = bgp_table_top(table); dest; dest = next) {
11293 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11294
11295 next = bgp_route_next(dest);
11296 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11297 continue;
11298
11299 itable = bgp_dest_get_bgp_table_info(dest);
11300 if (itable != NULL) {
11301 struct prefix_rd prd;
11302 char rd[RD_ADDRSTRLEN];
11303
11304 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11305 prefix_rd2str(&prd, rd, sizeof(rd));
11306 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11307 rd, next == NULL, &output_cum,
11308 &total_cum, &json_header_depth,
11309 show_flags, RPKI_NOT_BEING_USED);
11310 if (next == NULL)
11311 show_msg = false;
11312 }
11313 }
11314 if (show_msg) {
11315 if (output_cum == 0)
11316 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11317 total_cum);
11318 else
11319 vty_out(vty,
11320 "\nDisplayed %ld routes and %ld total paths\n",
11321 output_cum, total_cum);
11322 }
11323 return CMD_SUCCESS;
11324 }
11325
11326 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11327 enum bgp_show_type type, void *output_arg,
11328 uint16_t show_flags, enum rpki_states rpki_target_state)
11329 {
11330 struct bgp_table *table;
11331 unsigned long json_header_depth = 0;
11332 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11333
11334 if (bgp == NULL) {
11335 bgp = bgp_get_default();
11336 }
11337
11338 if (bgp == NULL) {
11339 if (!use_json)
11340 vty_out(vty, "No BGP process is configured\n");
11341 else
11342 vty_out(vty, "{}\n");
11343 return CMD_WARNING;
11344 }
11345
11346 /* Labeled-unicast routes live in the unicast table. */
11347 if (safi == SAFI_LABELED_UNICAST)
11348 safi = SAFI_UNICAST;
11349
11350 table = bgp->rib[afi][safi];
11351 /* use MPLS and ENCAP specific shows until they are merged */
11352 if (safi == SAFI_MPLS_VPN) {
11353 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11354 output_arg, use_json);
11355 }
11356
11357 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11358 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11359 output_arg, use_json,
11360 1, NULL, NULL);
11361 }
11362
11363 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11364 NULL, NULL, &json_header_depth, show_flags,
11365 rpki_target_state);
11366 }
11367
11368 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11369 safi_t safi, uint16_t show_flags)
11370 {
11371 struct listnode *node, *nnode;
11372 struct bgp *bgp;
11373 int is_first = 1;
11374 bool route_output = false;
11375 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11376
11377 if (use_json)
11378 vty_out(vty, "{\n");
11379
11380 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11381 route_output = true;
11382 if (use_json) {
11383 if (!is_first)
11384 vty_out(vty, ",\n");
11385 else
11386 is_first = 0;
11387
11388 vty_out(vty, "\"%s\":",
11389 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11390 ? VRF_DEFAULT_NAME
11391 : bgp->name);
11392 } else {
11393 vty_out(vty, "\nInstance %s:\n",
11394 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11395 ? VRF_DEFAULT_NAME
11396 : bgp->name);
11397 }
11398 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11399 show_flags, RPKI_NOT_BEING_USED);
11400 }
11401
11402 if (use_json)
11403 vty_out(vty, "}\n");
11404 else if (!route_output)
11405 vty_out(vty, "%% BGP instance not found\n");
11406 }
11407
11408 /* Header of detailed BGP route information */
11409 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11410 struct bgp_dest *dest,
11411 const struct prefix_rd *prd,
11412 afi_t afi, safi_t safi, json_object *json)
11413 {
11414 struct bgp_path_info *pi;
11415 const struct prefix *p;
11416 struct peer *peer;
11417 struct listnode *node, *nnode;
11418 char buf1[RD_ADDRSTRLEN];
11419 int count = 0;
11420 int best = 0;
11421 int suppress = 0;
11422 int accept_own = 0;
11423 int route_filter_translated_v4 = 0;
11424 int route_filter_v4 = 0;
11425 int route_filter_translated_v6 = 0;
11426 int route_filter_v6 = 0;
11427 int llgr_stale = 0;
11428 int no_llgr = 0;
11429 int accept_own_nexthop = 0;
11430 int blackhole = 0;
11431 int no_export = 0;
11432 int no_advertise = 0;
11433 int local_as = 0;
11434 int no_peer = 0;
11435 int first = 1;
11436 int has_valid_label = 0;
11437 mpls_label_t label = 0;
11438 json_object *json_adv_to = NULL;
11439
11440 p = bgp_dest_get_prefix(dest);
11441 has_valid_label = bgp_is_valid_label(&dest->local_label);
11442
11443 if (has_valid_label)
11444 label = label_pton(&dest->local_label);
11445
11446 if (safi == SAFI_EVPN) {
11447
11448 if (!json) {
11449 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11450 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11451 : "",
11452 prd ? ":" : "", (struct prefix_evpn *)p);
11453 } else {
11454 json_object_string_add(json, "rd",
11455 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11456 "");
11457 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11458 }
11459 } else {
11460 if (!json) {
11461 vty_out(vty,
11462 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11463 "\n",
11464 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11465 ? prefix_rd2str(prd, buf1,
11466 sizeof(buf1))
11467 : ""),
11468 safi == SAFI_MPLS_VPN ? ":" : "", p,
11469 dest->version);
11470
11471 } else {
11472 json_object_string_addf(json, "prefix", "%pFX", p);
11473 json_object_int_add(json, "version", dest->version);
11474
11475 }
11476 }
11477
11478 if (has_valid_label) {
11479 if (json)
11480 json_object_int_add(json, "localLabel", label);
11481 else
11482 vty_out(vty, "Local label: %d\n", label);
11483 }
11484
11485 if (!json)
11486 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11487 vty_out(vty, "not allocated\n");
11488
11489 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11490 struct community *picomm = NULL;
11491
11492 picomm = bgp_attr_get_community(pi->attr);
11493
11494 count++;
11495 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11496 best = count;
11497 if (bgp_path_suppressed(pi))
11498 suppress = 1;
11499
11500 if (!picomm)
11501 continue;
11502
11503 no_advertise += community_include(
11504 picomm, COMMUNITY_NO_ADVERTISE);
11505 no_export +=
11506 community_include(picomm, COMMUNITY_NO_EXPORT);
11507 local_as +=
11508 community_include(picomm, COMMUNITY_LOCAL_AS);
11509 accept_own +=
11510 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11511 route_filter_translated_v4 += community_include(
11512 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11513 route_filter_translated_v6 += community_include(
11514 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11515 route_filter_v4 += community_include(
11516 picomm, COMMUNITY_ROUTE_FILTER_v4);
11517 route_filter_v6 += community_include(
11518 picomm, COMMUNITY_ROUTE_FILTER_v6);
11519 llgr_stale +=
11520 community_include(picomm, COMMUNITY_LLGR_STALE);
11521 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11522 accept_own_nexthop += community_include(
11523 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11524 blackhole +=
11525 community_include(picomm, COMMUNITY_BLACKHOLE);
11526 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11527 }
11528 }
11529
11530 if (!json) {
11531 vty_out(vty, "Paths: (%d available", count);
11532 if (best) {
11533 vty_out(vty, ", best #%d", best);
11534 if (safi == SAFI_UNICAST) {
11535 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11536 vty_out(vty, ", table %s",
11537 VRF_DEFAULT_NAME);
11538 else
11539 vty_out(vty, ", vrf %s",
11540 bgp->name);
11541 }
11542 } else
11543 vty_out(vty, ", no best path");
11544
11545 if (accept_own)
11546 vty_out(vty,
11547 ", accept own local route exported and imported in different VRF");
11548 else if (route_filter_translated_v4)
11549 vty_out(vty,
11550 ", mark translated RTs for VPNv4 route filtering");
11551 else if (route_filter_v4)
11552 vty_out(vty,
11553 ", attach RT as-is for VPNv4 route filtering");
11554 else if (route_filter_translated_v6)
11555 vty_out(vty,
11556 ", mark translated RTs for VPNv6 route filtering");
11557 else if (route_filter_v6)
11558 vty_out(vty,
11559 ", attach RT as-is for VPNv6 route filtering");
11560 else if (llgr_stale)
11561 vty_out(vty,
11562 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11563 else if (no_llgr)
11564 vty_out(vty,
11565 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11566 else if (accept_own_nexthop)
11567 vty_out(vty,
11568 ", accept local nexthop");
11569 else if (blackhole)
11570 vty_out(vty, ", inform peer to blackhole prefix");
11571 else if (no_export)
11572 vty_out(vty, ", not advertised to EBGP peer");
11573 else if (no_advertise)
11574 vty_out(vty, ", not advertised to any peer");
11575 else if (local_as)
11576 vty_out(vty, ", not advertised outside local AS");
11577 else if (no_peer)
11578 vty_out(vty,
11579 ", inform EBGP peer not to advertise to their EBGP peers");
11580
11581 if (suppress)
11582 vty_out(vty,
11583 ", Advertisements suppressed by an aggregate.");
11584 vty_out(vty, ")\n");
11585 }
11586
11587 /* If we are not using addpath then we can display Advertised to and
11588 * that will
11589 * show what peers we advertised the bestpath to. If we are using
11590 * addpath
11591 * though then we must display Advertised to on a path-by-path basis. */
11592 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11593 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11594 if (bgp_adj_out_lookup(peer, dest, 0)) {
11595 if (json && !json_adv_to)
11596 json_adv_to = json_object_new_object();
11597
11598 route_vty_out_advertised_to(
11599 vty, peer, &first,
11600 " Advertised to non peer-group peers:\n ",
11601 json_adv_to);
11602 }
11603 }
11604
11605 if (json) {
11606 if (json_adv_to) {
11607 json_object_object_add(json, "advertisedTo",
11608 json_adv_to);
11609 }
11610 } else {
11611 if (first)
11612 vty_out(vty, " Not advertised to any peer");
11613 vty_out(vty, "\n");
11614 }
11615 }
11616 }
11617
11618 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11619 struct bgp_dest *bgp_node, struct vty *vty,
11620 struct bgp *bgp, afi_t afi, safi_t safi,
11621 json_object *json, enum bgp_path_type pathtype,
11622 int *display, enum rpki_states rpki_target_state)
11623 {
11624 struct bgp_path_info *pi;
11625 int header = 1;
11626 char rdbuf[RD_ADDRSTRLEN];
11627 json_object *json_header = NULL;
11628 json_object *json_paths = NULL;
11629 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11630
11631 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11632 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11633
11634 if (p->family == AF_INET || p->family == AF_INET6)
11635 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11636 pi->peer, pi->attr, p);
11637
11638 if (rpki_target_state != RPKI_NOT_BEING_USED
11639 && rpki_curr_state != rpki_target_state)
11640 continue;
11641
11642 if (json && !json_paths) {
11643 /* Instantiate json_paths only if path is valid */
11644 json_paths = json_object_new_array();
11645 if (pfx_rd) {
11646 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11647 json_header = json_object_new_object();
11648 } else
11649 json_header = json;
11650 }
11651
11652 if (header) {
11653 route_vty_out_detail_header(
11654 vty, bgp, bgp_node, pfx_rd,
11655 AFI_IP, safi, json_header);
11656 header = 0;
11657 }
11658 (*display)++;
11659
11660 if (pathtype == BGP_PATH_SHOW_ALL
11661 || (pathtype == BGP_PATH_SHOW_BESTPATH
11662 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11663 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11664 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11665 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11666 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
11667 safi, rpki_curr_state, json_paths);
11668 }
11669
11670 if (json && json_paths) {
11671 json_object_object_add(json_header, "paths", json_paths);
11672
11673 if (pfx_rd)
11674 json_object_object_add(json, rdbuf, json_header);
11675 }
11676 }
11677
11678 /*
11679 * Return rd based on safi
11680 */
11681 static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
11682 safi_t safi)
11683 {
11684 switch (safi) {
11685 case SAFI_MPLS_VPN:
11686 case SAFI_ENCAP:
11687 case SAFI_EVPN:
11688 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
11689 default:
11690 return NULL;
11691
11692 }
11693 }
11694
11695 /* Display specified route of BGP table. */
11696 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11697 struct bgp_table *rib, const char *ip_str,
11698 afi_t afi, safi_t safi,
11699 enum rpki_states rpki_target_state,
11700 struct prefix_rd *prd, int prefix_check,
11701 enum bgp_path_type pathtype, bool use_json)
11702 {
11703 int ret;
11704 int display = 0;
11705 struct prefix match;
11706 struct bgp_dest *dest;
11707 struct bgp_dest *rm;
11708 struct bgp_table *table;
11709 json_object *json = NULL;
11710 json_object *json_paths = NULL;
11711
11712 /* Check IP address argument. */
11713 ret = str2prefix(ip_str, &match);
11714 if (!ret) {
11715 vty_out(vty, "address is malformed\n");
11716 return CMD_WARNING;
11717 }
11718
11719 match.family = afi2family(afi);
11720
11721 if (use_json)
11722 json = json_object_new_object();
11723
11724 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11725 for (dest = bgp_table_top(rib); dest;
11726 dest = bgp_route_next(dest)) {
11727 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11728
11729 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11730 continue;
11731 table = bgp_dest_get_bgp_table_info(dest);
11732 if (!table)
11733 continue;
11734
11735 rm = bgp_node_match(table, &match);
11736 if (rm == NULL)
11737 continue;
11738
11739 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11740 if (prefix_check
11741 && rm_p->prefixlen != match.prefixlen) {
11742 bgp_dest_unlock_node(rm);
11743 continue;
11744 }
11745
11746 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11747 bgp, afi, safi, json, pathtype,
11748 &display, rpki_target_state);
11749
11750 bgp_dest_unlock_node(rm);
11751 }
11752 } else if (safi == SAFI_EVPN) {
11753 struct bgp_dest *longest_pfx;
11754 bool is_exact_pfxlen_match = false;
11755
11756 for (dest = bgp_table_top(rib); dest;
11757 dest = bgp_route_next(dest)) {
11758 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11759
11760 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11761 continue;
11762 table = bgp_dest_get_bgp_table_info(dest);
11763 if (!table)
11764 continue;
11765
11766 longest_pfx = NULL;
11767 is_exact_pfxlen_match = false;
11768 /*
11769 * Search through all the prefixes for a match. The
11770 * pfx's are enumerated in ascending order of pfxlens.
11771 * So, the last pfx match is the longest match. Set
11772 * is_exact_pfxlen_match when we get exact pfxlen match
11773 */
11774 for (rm = bgp_table_top(table); rm;
11775 rm = bgp_route_next(rm)) {
11776 const struct prefix *rm_p =
11777 bgp_dest_get_prefix(rm);
11778 /*
11779 * Get prefixlen of the ip-prefix within type5
11780 * evpn route
11781 */
11782 if (evpn_type5_prefix_match(rm_p, &match)
11783 && rm->info) {
11784 longest_pfx = rm;
11785 int type5_pfxlen =
11786 bgp_evpn_get_type5_prefixlen(
11787 rm_p);
11788 if (type5_pfxlen == match.prefixlen) {
11789 is_exact_pfxlen_match = true;
11790 bgp_dest_unlock_node(rm);
11791 break;
11792 }
11793 }
11794 }
11795
11796 if (!longest_pfx)
11797 continue;
11798
11799 if (prefix_check && !is_exact_pfxlen_match)
11800 continue;
11801
11802 rm = longest_pfx;
11803 bgp_dest_lock_node(rm);
11804
11805 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11806 bgp, afi, safi, json, pathtype,
11807 &display, rpki_target_state);
11808
11809 bgp_dest_unlock_node(rm);
11810 }
11811 } else if (safi == SAFI_FLOWSPEC) {
11812 if (use_json)
11813 json_paths = json_object_new_array();
11814
11815 display = bgp_flowspec_display_match_per_ip(afi, rib,
11816 &match, prefix_check,
11817 vty,
11818 use_json,
11819 json_paths);
11820 if (use_json) {
11821 if (display)
11822 json_object_object_add(json, "paths",
11823 json_paths);
11824 else
11825 json_object_free(json_paths);
11826 }
11827 } else {
11828 dest = bgp_node_match(rib, &match);
11829 if (dest != NULL) {
11830 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11831 if (!prefix_check
11832 || dest_p->prefixlen == match.prefixlen) {
11833 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11834 safi, json, pathtype,
11835 &display, rpki_target_state);
11836 }
11837
11838 bgp_dest_unlock_node(dest);
11839 }
11840 }
11841
11842 if (use_json) {
11843 vty_json(vty, json);
11844 } else {
11845 if (!display) {
11846 vty_out(vty, "%% Network not in table\n");
11847 return CMD_WARNING;
11848 }
11849 }
11850
11851 return CMD_SUCCESS;
11852 }
11853
11854 /* Display specified route of Main RIB */
11855 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
11856 afi_t afi, safi_t safi, struct prefix_rd *prd,
11857 int prefix_check, enum bgp_path_type pathtype,
11858 enum rpki_states rpki_target_state, bool use_json)
11859 {
11860 if (!bgp) {
11861 bgp = bgp_get_default();
11862 if (!bgp) {
11863 if (!use_json)
11864 vty_out(vty, "No BGP process is configured\n");
11865 else
11866 vty_out(vty, "{}\n");
11867 return CMD_WARNING;
11868 }
11869 }
11870
11871 /* labeled-unicast routes live in the unicast table */
11872 if (safi == SAFI_LABELED_UNICAST)
11873 safi = SAFI_UNICAST;
11874
11875 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
11876 afi, safi, rpki_target_state, prd,
11877 prefix_check, pathtype, use_json);
11878 }
11879
11880 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
11881 struct cmd_token **argv, bool exact, afi_t afi,
11882 safi_t safi, bool uj)
11883 {
11884 struct lcommunity *lcom;
11885 struct buffer *b;
11886 int i;
11887 char *str;
11888 int first = 0;
11889 uint16_t show_flags = 0;
11890 int ret;
11891
11892 if (uj)
11893 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11894
11895 b = buffer_new(1024);
11896 for (i = 0; i < argc; i++) {
11897 if (first)
11898 buffer_putc(b, ' ');
11899 else {
11900 if (strmatch(argv[i]->text, "AA:BB:CC")) {
11901 first = 1;
11902 buffer_putstr(b, argv[i]->arg);
11903 }
11904 }
11905 }
11906 buffer_putc(b, '\0');
11907
11908 str = buffer_getstr(b);
11909 buffer_free(b);
11910
11911 lcom = lcommunity_str2com(str);
11912 XFREE(MTYPE_TMP, str);
11913 if (!lcom) {
11914 vty_out(vty, "%% Large-community malformed\n");
11915 return CMD_WARNING;
11916 }
11917
11918 ret = bgp_show(vty, bgp, afi, safi,
11919 (exact ? bgp_show_type_lcommunity_exact
11920 : bgp_show_type_lcommunity),
11921 lcom, show_flags, RPKI_NOT_BEING_USED);
11922
11923 lcommunity_free(&lcom);
11924 return ret;
11925 }
11926
11927 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
11928 const char *lcom, bool exact, afi_t afi,
11929 safi_t safi, bool uj)
11930 {
11931 struct community_list *list;
11932 uint16_t show_flags = 0;
11933
11934 if (uj)
11935 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11936
11937
11938 list = community_list_lookup(bgp_clist, lcom, 0,
11939 LARGE_COMMUNITY_LIST_MASTER);
11940 if (list == NULL) {
11941 vty_out(vty, "%% %s is not a valid large-community-list name\n",
11942 lcom);
11943 return CMD_WARNING;
11944 }
11945
11946 return bgp_show(vty, bgp, afi, safi,
11947 (exact ? bgp_show_type_lcommunity_list_exact
11948 : bgp_show_type_lcommunity_list),
11949 list, show_flags, RPKI_NOT_BEING_USED);
11950 }
11951
11952 DEFUN (show_ip_bgp_large_community_list,
11953 show_ip_bgp_large_community_list_cmd,
11954 "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]",
11955 SHOW_STR
11956 IP_STR
11957 BGP_STR
11958 BGP_INSTANCE_HELP_STR
11959 BGP_AFI_HELP_STR
11960 BGP_SAFI_WITH_LABEL_HELP_STR
11961 "Display routes matching the large-community-list\n"
11962 "large-community-list number\n"
11963 "large-community-list name\n"
11964 "Exact match of the large-communities\n"
11965 JSON_STR)
11966 {
11967 afi_t afi = AFI_IP6;
11968 safi_t safi = SAFI_UNICAST;
11969 int idx = 0;
11970 bool exact_match = 0;
11971 struct bgp *bgp = NULL;
11972 bool uj = use_json(argc, argv);
11973
11974 if (uj)
11975 argc--;
11976
11977 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11978 &bgp, uj);
11979 if (!idx)
11980 return CMD_WARNING;
11981
11982 argv_find(argv, argc, "large-community-list", &idx);
11983
11984 const char *clist_number_or_name = argv[++idx]->arg;
11985
11986 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11987 exact_match = 1;
11988
11989 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
11990 exact_match, afi, safi, uj);
11991 }
11992 DEFUN (show_ip_bgp_large_community,
11993 show_ip_bgp_large_community_cmd,
11994 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
11995 SHOW_STR
11996 IP_STR
11997 BGP_STR
11998 BGP_INSTANCE_HELP_STR
11999 BGP_AFI_HELP_STR
12000 BGP_SAFI_WITH_LABEL_HELP_STR
12001 "Display routes matching the large-communities\n"
12002 "List of large-community numbers\n"
12003 "Exact match of the large-communities\n"
12004 JSON_STR)
12005 {
12006 afi_t afi = AFI_IP6;
12007 safi_t safi = SAFI_UNICAST;
12008 int idx = 0;
12009 bool exact_match = 0;
12010 struct bgp *bgp = NULL;
12011 bool uj = use_json(argc, argv);
12012 uint16_t show_flags = 0;
12013
12014 if (uj) {
12015 argc--;
12016 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12017 }
12018
12019 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12020 &bgp, uj);
12021 if (!idx)
12022 return CMD_WARNING;
12023
12024 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12025 if (argv_find(argv, argc, "exact-match", &idx))
12026 exact_match = 1;
12027 return bgp_show_lcommunity(vty, bgp, argc, argv,
12028 exact_match, afi, safi, uj);
12029 } else
12030 return bgp_show(vty, bgp, afi, safi,
12031 bgp_show_type_lcommunity_all, NULL, show_flags,
12032 RPKI_NOT_BEING_USED);
12033 }
12034
12035 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12036 safi_t safi, struct json_object *json_array);
12037 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12038 safi_t safi, struct json_object *json);
12039
12040
12041 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12042 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12043 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12044 "Display number of prefixes for all afi/safi\n" JSON_STR)
12045 {
12046 bool uj = use_json(argc, argv);
12047 struct bgp *bgp = NULL;
12048 safi_t safi = SAFI_UNICAST;
12049 afi_t afi = AFI_IP6;
12050 int idx = 0;
12051 struct json_object *json_all = NULL;
12052 struct json_object *json_afi_safi = NULL;
12053
12054 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12055 &bgp, false);
12056 if (!idx)
12057 return CMD_WARNING;
12058
12059 if (uj)
12060 json_all = json_object_new_object();
12061
12062 FOREACH_AFI_SAFI (afi, safi) {
12063 /*
12064 * So limit output to those afi/safi pairs that
12065 * actually have something interesting in them
12066 */
12067 if (strmatch(get_afi_safi_str(afi, safi, true),
12068 "Unknown")) {
12069 continue;
12070 }
12071 if (uj) {
12072 json_afi_safi = json_object_new_array();
12073 json_object_object_add(
12074 json_all,
12075 get_afi_safi_str(afi, safi, true),
12076 json_afi_safi);
12077 } else {
12078 json_afi_safi = NULL;
12079 }
12080
12081 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12082 }
12083
12084 if (uj)
12085 vty_json(vty, json_all);
12086
12087 return CMD_SUCCESS;
12088 }
12089
12090 /* BGP route print out function without JSON */
12091 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12092 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12093 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12094 SHOW_STR
12095 IP_STR
12096 BGP_STR
12097 BGP_INSTANCE_HELP_STR
12098 L2VPN_HELP_STR
12099 EVPN_HELP_STR
12100 "BGP RIB advertisement statistics\n"
12101 JSON_STR)
12102 {
12103 afi_t afi = AFI_IP6;
12104 safi_t safi = SAFI_UNICAST;
12105 struct bgp *bgp = NULL;
12106 int idx = 0, ret;
12107 bool uj = use_json(argc, argv);
12108 struct json_object *json_afi_safi = NULL, *json = NULL;
12109
12110 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12111 &bgp, false);
12112 if (!idx)
12113 return CMD_WARNING;
12114
12115 if (uj)
12116 json_afi_safi = json_object_new_array();
12117 else
12118 json_afi_safi = NULL;
12119
12120 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12121
12122 if (uj) {
12123 json = json_object_new_object();
12124 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12125 json_afi_safi);
12126 vty_json(vty, json);
12127 }
12128 return ret;
12129 }
12130
12131 /* BGP route print out function without JSON */
12132 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12133 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12134 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12135 "]]\
12136 statistics [json]",
12137 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12138 BGP_SAFI_WITH_LABEL_HELP_STR
12139 "BGP RIB advertisement statistics\n" JSON_STR)
12140 {
12141 afi_t afi = AFI_IP6;
12142 safi_t safi = SAFI_UNICAST;
12143 struct bgp *bgp = NULL;
12144 int idx = 0, ret;
12145 bool uj = use_json(argc, argv);
12146 struct json_object *json_afi_safi = NULL, *json = NULL;
12147
12148 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12149 &bgp, false);
12150 if (!idx)
12151 return CMD_WARNING;
12152
12153 if (uj)
12154 json_afi_safi = json_object_new_array();
12155 else
12156 json_afi_safi = NULL;
12157
12158 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12159
12160 if (uj) {
12161 json = json_object_new_object();
12162 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12163 json_afi_safi);
12164 vty_json(vty, json);
12165 }
12166 return ret;
12167 }
12168
12169 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12170 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12171 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12172 "]] [all$all] dampening parameters [json]",
12173 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12174 BGP_SAFI_WITH_LABEL_HELP_STR
12175 "Display the entries for all address families\n"
12176 "Display detailed information about dampening\n"
12177 "Display detail of configured dampening parameters\n"
12178 JSON_STR)
12179 {
12180 afi_t afi = AFI_IP6;
12181 safi_t safi = SAFI_UNICAST;
12182 struct bgp *bgp = NULL;
12183 int idx = 0;
12184 uint16_t show_flags = 0;
12185 bool uj = use_json(argc, argv);
12186
12187 if (uj) {
12188 argc--;
12189 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12190 }
12191
12192 /* [<ipv4|ipv6> [all]] */
12193 if (all) {
12194 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12195 if (argv_find(argv, argc, "ipv4", &idx))
12196 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12197
12198 if (argv_find(argv, argc, "ipv6", &idx))
12199 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12200 }
12201
12202 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12203 &bgp, false);
12204 if (!idx)
12205 return CMD_WARNING;
12206
12207 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12208 }
12209
12210 /* BGP route print out function */
12211 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12212 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12213 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12214 "]]\
12215 [all$all]\
12216 [cidr-only\
12217 |dampening <flap-statistics|dampened-paths>\
12218 |community [AA:NN|local-AS|no-advertise|no-export\
12219 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12220 |accept-own|accept-own-nexthop|route-filter-v6\
12221 |route-filter-v4|route-filter-translated-v6\
12222 |route-filter-translated-v4] [exact-match]\
12223 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12224 |filter-list AS_PATH_FILTER_NAME\
12225 |prefix-list WORD\
12226 |route-map WORD\
12227 |rpki <invalid|valid|notfound>\
12228 |version (1-4294967295)\
12229 |alias ALIAS_NAME\
12230 |A.B.C.D/M longer-prefixes\
12231 |X:X::X:X/M longer-prefixes\
12232 ] [json$uj [detail$detail] | wide$wide]",
12233 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12234 BGP_SAFI_WITH_LABEL_HELP_STR
12235 "Display the entries for all address families\n"
12236 "Display only routes with non-natural netmasks\n"
12237 "Display detailed information about dampening\n"
12238 "Display flap statistics of routes\n"
12239 "Display paths suppressed due to dampening\n"
12240 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12241 "Do not send outside local AS (well-known community)\n"
12242 "Do not advertise to any peer (well-known community)\n"
12243 "Do not export to next AS (well-known community)\n"
12244 "Graceful shutdown (well-known community)\n"
12245 "Do not export to any peer (well-known community)\n"
12246 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12247 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12248 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12249 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12250 "Should accept VPN route with local nexthop (well-known community)\n"
12251 "RT VPNv6 route filtering (well-known community)\n"
12252 "RT VPNv4 route filtering (well-known community)\n"
12253 "RT translated VPNv6 route filtering (well-known community)\n"
12254 "RT translated VPNv4 route filtering (well-known community)\n"
12255 "Exact match of the communities\n"
12256 "Community-list number\n"
12257 "Community-list name\n"
12258 "Display routes matching the community-list\n"
12259 "Exact match of the communities\n"
12260 "Display routes conforming to the filter-list\n"
12261 "Regular expression access list name\n"
12262 "Display routes conforming to the prefix-list\n"
12263 "Prefix-list name\n"
12264 "Display routes matching the route-map\n"
12265 "A route-map to match on\n"
12266 "RPKI route types\n"
12267 "A valid path as determined by rpki\n"
12268 "A invalid path as determined by rpki\n"
12269 "A path that has no rpki data\n"
12270 "Display prefixes with matching version numbers\n"
12271 "Version number and above\n"
12272 "Display prefixes with matching BGP community alias\n"
12273 "BGP community alias\n"
12274 "IPv4 prefix\n"
12275 "Display route and more specific routes\n"
12276 "IPv6 prefix\n"
12277 "Display route and more specific routes\n"
12278 JSON_STR
12279 "Display detailed version of JSON output\n"
12280 "Increase table width for longer prefixes\n")
12281 {
12282 afi_t afi = AFI_IP6;
12283 safi_t safi = SAFI_UNICAST;
12284 enum bgp_show_type sh_type = bgp_show_type_normal;
12285 void *output_arg = NULL;
12286 struct bgp *bgp = NULL;
12287 int idx = 0;
12288 int exact_match = 0;
12289 char *community = NULL;
12290 bool first = true;
12291 uint16_t show_flags = 0;
12292 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12293 struct prefix p;
12294
12295 if (uj) {
12296 argc--;
12297 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12298 }
12299
12300 if (detail)
12301 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12302
12303 /* [<ipv4|ipv6> [all]] */
12304 if (all) {
12305 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12306
12307 if (argv_find(argv, argc, "ipv4", &idx))
12308 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12309
12310 if (argv_find(argv, argc, "ipv6", &idx))
12311 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12312 }
12313
12314 if (wide)
12315 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12316
12317 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12318 &bgp, uj);
12319 if (!idx)
12320 return CMD_WARNING;
12321
12322 if (argv_find(argv, argc, "cidr-only", &idx))
12323 sh_type = bgp_show_type_cidr_only;
12324
12325 if (argv_find(argv, argc, "dampening", &idx)) {
12326 if (argv_find(argv, argc, "dampened-paths", &idx))
12327 sh_type = bgp_show_type_dampend_paths;
12328 else if (argv_find(argv, argc, "flap-statistics", &idx))
12329 sh_type = bgp_show_type_flap_statistics;
12330 }
12331
12332 if (argv_find(argv, argc, "community", &idx)) {
12333 char *maybecomm = NULL;
12334
12335 if (idx + 1 < argc) {
12336 if (argv[idx + 1]->type == VARIABLE_TKN)
12337 maybecomm = argv[idx + 1]->arg;
12338 else
12339 maybecomm = argv[idx + 1]->text;
12340 }
12341
12342 if (maybecomm && !strmatch(maybecomm, "json")
12343 && !strmatch(maybecomm, "exact-match"))
12344 community = maybecomm;
12345
12346 if (argv_find(argv, argc, "exact-match", &idx))
12347 exact_match = 1;
12348
12349 if (!community)
12350 sh_type = bgp_show_type_community_all;
12351 }
12352
12353 if (argv_find(argv, argc, "community-list", &idx)) {
12354 const char *clist_number_or_name = argv[++idx]->arg;
12355 struct community_list *list;
12356
12357 if (argv_find(argv, argc, "exact-match", &idx))
12358 exact_match = 1;
12359
12360 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12361 COMMUNITY_LIST_MASTER);
12362 if (list == NULL) {
12363 vty_out(vty,
12364 "%% %s is not a valid community-list name\n",
12365 clist_number_or_name);
12366 return CMD_WARNING;
12367 }
12368
12369 if (exact_match)
12370 sh_type = bgp_show_type_community_list_exact;
12371 else
12372 sh_type = bgp_show_type_community_list;
12373 output_arg = list;
12374 }
12375
12376 if (argv_find(argv, argc, "filter-list", &idx)) {
12377 const char *filter = argv[++idx]->arg;
12378 struct as_list *as_list;
12379
12380 as_list = as_list_lookup(filter);
12381 if (as_list == NULL) {
12382 vty_out(vty,
12383 "%% %s is not a valid AS-path access-list name\n",
12384 filter);
12385 return CMD_WARNING;
12386 }
12387
12388 sh_type = bgp_show_type_filter_list;
12389 output_arg = as_list;
12390 }
12391
12392 if (argv_find(argv, argc, "prefix-list", &idx)) {
12393 const char *prefix_list_str = argv[++idx]->arg;
12394 struct prefix_list *plist;
12395
12396 plist = prefix_list_lookup(afi, prefix_list_str);
12397 if (plist == NULL) {
12398 vty_out(vty, "%% %s is not a valid prefix-list name\n",
12399 prefix_list_str);
12400 return CMD_WARNING;
12401 }
12402
12403 sh_type = bgp_show_type_prefix_list;
12404 output_arg = plist;
12405 }
12406
12407 if (argv_find(argv, argc, "route-map", &idx)) {
12408 const char *rmap_str = argv[++idx]->arg;
12409 struct route_map *rmap;
12410
12411 rmap = route_map_lookup_by_name(rmap_str);
12412 if (!rmap) {
12413 vty_out(vty, "%% %s is not a valid route-map name\n",
12414 rmap_str);
12415 return CMD_WARNING;
12416 }
12417
12418 sh_type = bgp_show_type_route_map;
12419 output_arg = rmap;
12420 }
12421
12422 if (argv_find(argv, argc, "rpki", &idx)) {
12423 sh_type = bgp_show_type_rpki;
12424 if (argv_find(argv, argc, "valid", &idx))
12425 rpki_target_state = RPKI_VALID;
12426 else if (argv_find(argv, argc, "invalid", &idx))
12427 rpki_target_state = RPKI_INVALID;
12428 }
12429
12430 /* Display prefixes with matching version numbers */
12431 if (argv_find(argv, argc, "version", &idx)) {
12432 sh_type = bgp_show_type_prefix_version;
12433 output_arg = argv[idx + 1]->arg;
12434 }
12435
12436 /* Display prefixes with matching BGP community alias */
12437 if (argv_find(argv, argc, "alias", &idx)) {
12438 sh_type = bgp_show_type_community_alias;
12439 output_arg = argv[idx + 1]->arg;
12440 }
12441
12442 /* prefix-longer */
12443 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12444 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12445 const char *prefix_str = argv[idx]->arg;
12446
12447 if (!str2prefix(prefix_str, &p)) {
12448 vty_out(vty, "%% Malformed Prefix\n");
12449 return CMD_WARNING;
12450 }
12451
12452 sh_type = bgp_show_type_prefix_longer;
12453 output_arg = &p;
12454 }
12455
12456 if (!all) {
12457 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12458 if (community)
12459 return bgp_show_community(vty, bgp, community,
12460 exact_match, afi, safi,
12461 show_flags);
12462 else
12463 return bgp_show(vty, bgp, afi, safi, sh_type,
12464 output_arg, show_flags,
12465 rpki_target_state);
12466 } else {
12467 struct listnode *node;
12468 struct bgp *abgp;
12469 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12470 * AFI_IP6 */
12471
12472 if (uj)
12473 vty_out(vty, "{\n");
12474
12475 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12476 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12477 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12478 ? AFI_IP
12479 : AFI_IP6;
12480 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12481 FOREACH_SAFI (safi) {
12482 if (!bgp_afi_safi_peer_exists(abgp, afi,
12483 safi))
12484 continue;
12485
12486 if (uj) {
12487 if (first)
12488 first = false;
12489 else
12490 vty_out(vty, ",\n");
12491 vty_out(vty, "\"%s\":{\n",
12492 get_afi_safi_str(afi,
12493 safi,
12494 true));
12495 } else
12496 vty_out(vty,
12497 "\nFor address family: %s\n",
12498 get_afi_safi_str(
12499 afi, safi,
12500 false));
12501
12502 if (community)
12503 bgp_show_community(
12504 vty, abgp, community,
12505 exact_match, afi, safi,
12506 show_flags);
12507 else
12508 bgp_show(vty, abgp, afi, safi,
12509 sh_type, output_arg,
12510 show_flags,
12511 rpki_target_state);
12512 if (uj)
12513 vty_out(vty, "}\n");
12514 }
12515 }
12516 } else {
12517 /* show <ip> bgp all: for each AFI and SAFI*/
12518 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12519 FOREACH_AFI_SAFI (afi, safi) {
12520 if (!bgp_afi_safi_peer_exists(abgp, afi,
12521 safi))
12522 continue;
12523
12524 if (uj) {
12525 if (first)
12526 first = false;
12527 else
12528 vty_out(vty, ",\n");
12529
12530 vty_out(vty, "\"%s\":{\n",
12531 get_afi_safi_str(afi,
12532 safi,
12533 true));
12534 } else
12535 vty_out(vty,
12536 "\nFor address family: %s\n",
12537 get_afi_safi_str(
12538 afi, safi,
12539 false));
12540
12541 if (community)
12542 bgp_show_community(
12543 vty, abgp, community,
12544 exact_match, afi, safi,
12545 show_flags);
12546 else
12547 bgp_show(vty, abgp, afi, safi,
12548 sh_type, output_arg,
12549 show_flags,
12550 rpki_target_state);
12551 if (uj)
12552 vty_out(vty, "}\n");
12553 }
12554 }
12555 }
12556 if (uj)
12557 vty_out(vty, "}\n");
12558 }
12559 return CMD_SUCCESS;
12560 }
12561
12562 DEFUN (show_ip_bgp_route,
12563 show_ip_bgp_route_cmd,
12564 "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]",
12565 SHOW_STR
12566 IP_STR
12567 BGP_STR
12568 BGP_INSTANCE_HELP_STR
12569 BGP_AFI_HELP_STR
12570 BGP_SAFI_WITH_LABEL_HELP_STR
12571 "Network in the BGP routing table to display\n"
12572 "IPv4 prefix\n"
12573 "Network in the BGP routing table to display\n"
12574 "IPv6 prefix\n"
12575 "Display only the bestpath\n"
12576 "Display only multipaths\n"
12577 "Display only paths that match the specified rpki state\n"
12578 "A valid path as determined by rpki\n"
12579 "A invalid path as determined by rpki\n"
12580 "A path that has no rpki data\n"
12581 JSON_STR)
12582 {
12583 int prefix_check = 0;
12584
12585 afi_t afi = AFI_IP6;
12586 safi_t safi = SAFI_UNICAST;
12587 char *prefix = NULL;
12588 struct bgp *bgp = NULL;
12589 enum bgp_path_type path_type;
12590 bool uj = use_json(argc, argv);
12591
12592 int idx = 0;
12593
12594 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12595 &bgp, uj);
12596 if (!idx)
12597 return CMD_WARNING;
12598
12599 if (!bgp) {
12600 vty_out(vty,
12601 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12602 return CMD_WARNING;
12603 }
12604
12605 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12606 if (argv_find(argv, argc, "A.B.C.D", &idx)
12607 || argv_find(argv, argc, "X:X::X:X", &idx))
12608 prefix_check = 0;
12609 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12610 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12611 prefix_check = 1;
12612
12613 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12614 && afi != AFI_IP6) {
12615 vty_out(vty,
12616 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12617 return CMD_WARNING;
12618 }
12619 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12620 && afi != AFI_IP) {
12621 vty_out(vty,
12622 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12623 return CMD_WARNING;
12624 }
12625
12626 prefix = argv[idx]->arg;
12627
12628 /* [<bestpath|multipath>] */
12629 if (argv_find(argv, argc, "bestpath", &idx))
12630 path_type = BGP_PATH_SHOW_BESTPATH;
12631 else if (argv_find(argv, argc, "multipath", &idx))
12632 path_type = BGP_PATH_SHOW_MULTIPATH;
12633 else
12634 path_type = BGP_PATH_SHOW_ALL;
12635
12636 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12637 path_type, RPKI_NOT_BEING_USED, uj);
12638 }
12639
12640 DEFUN (show_ip_bgp_regexp,
12641 show_ip_bgp_regexp_cmd,
12642 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12643 SHOW_STR
12644 IP_STR
12645 BGP_STR
12646 BGP_INSTANCE_HELP_STR
12647 BGP_AFI_HELP_STR
12648 BGP_SAFI_WITH_LABEL_HELP_STR
12649 "Display routes matching the AS path regular expression\n"
12650 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12651 JSON_STR)
12652 {
12653 afi_t afi = AFI_IP6;
12654 safi_t safi = SAFI_UNICAST;
12655 struct bgp *bgp = NULL;
12656 bool uj = use_json(argc, argv);
12657 char *regstr = NULL;
12658
12659 int idx = 0;
12660 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12661 &bgp, false);
12662 if (!idx)
12663 return CMD_WARNING;
12664
12665 // get index of regex
12666 if (argv_find(argv, argc, "REGEX", &idx))
12667 regstr = argv[idx]->arg;
12668
12669 assert(regstr);
12670 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12671 bgp_show_type_regexp, uj);
12672 }
12673
12674 DEFPY (show_ip_bgp_instance_all,
12675 show_ip_bgp_instance_all_cmd,
12676 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12677 SHOW_STR
12678 IP_STR
12679 BGP_STR
12680 BGP_INSTANCE_ALL_HELP_STR
12681 BGP_AFI_HELP_STR
12682 BGP_SAFI_WITH_LABEL_HELP_STR
12683 JSON_STR
12684 "Increase table width for longer prefixes\n")
12685 {
12686 afi_t afi = AFI_IP6;
12687 safi_t safi = SAFI_UNICAST;
12688 struct bgp *bgp = NULL;
12689 int idx = 0;
12690 uint16_t show_flags = 0;
12691
12692 if (uj) {
12693 argc--;
12694 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12695 }
12696
12697 if (wide)
12698 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12699
12700 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12701 &bgp, uj);
12702 if (!idx)
12703 return CMD_WARNING;
12704
12705 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12706 return CMD_SUCCESS;
12707 }
12708
12709 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12710 afi_t afi, safi_t safi, enum bgp_show_type type,
12711 bool use_json)
12712 {
12713 regex_t *regex;
12714 int rc;
12715 uint16_t show_flags = 0;
12716
12717 if (use_json)
12718 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12719
12720 if (!config_bgp_aspath_validate(regstr)) {
12721 vty_out(vty, "Invalid character in REGEX %s\n",
12722 regstr);
12723 return CMD_WARNING_CONFIG_FAILED;
12724 }
12725
12726 regex = bgp_regcomp(regstr);
12727 if (!regex) {
12728 vty_out(vty, "Can't compile regexp %s\n", regstr);
12729 return CMD_WARNING;
12730 }
12731
12732 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
12733 RPKI_NOT_BEING_USED);
12734 bgp_regex_free(regex);
12735 return rc;
12736 }
12737
12738 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12739 const char *comstr, int exact, afi_t afi,
12740 safi_t safi, uint16_t show_flags)
12741 {
12742 struct community *com;
12743 int ret = 0;
12744
12745 com = community_str2com(comstr);
12746 if (!com) {
12747 vty_out(vty, "%% Community malformed: %s\n", comstr);
12748 return CMD_WARNING;
12749 }
12750
12751 ret = bgp_show(vty, bgp, afi, safi,
12752 (exact ? bgp_show_type_community_exact
12753 : bgp_show_type_community),
12754 com, show_flags, RPKI_NOT_BEING_USED);
12755 community_free(&com);
12756
12757 return ret;
12758 }
12759
12760 enum bgp_stats {
12761 BGP_STATS_MAXBITLEN = 0,
12762 BGP_STATS_RIB,
12763 BGP_STATS_PREFIXES,
12764 BGP_STATS_TOTPLEN,
12765 BGP_STATS_UNAGGREGATEABLE,
12766 BGP_STATS_MAX_AGGREGATEABLE,
12767 BGP_STATS_AGGREGATES,
12768 BGP_STATS_SPACE,
12769 BGP_STATS_ASPATH_COUNT,
12770 BGP_STATS_ASPATH_MAXHOPS,
12771 BGP_STATS_ASPATH_TOTHOPS,
12772 BGP_STATS_ASPATH_MAXSIZE,
12773 BGP_STATS_ASPATH_TOTSIZE,
12774 BGP_STATS_ASN_HIGHEST,
12775 BGP_STATS_MAX,
12776 };
12777
12778 #define TABLE_STATS_IDX_VTY 0
12779 #define TABLE_STATS_IDX_JSON 1
12780
12781 static const char *table_stats_strs[][2] = {
12782 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12783 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12784 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12785 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12786 "unaggregateablePrefixes"},
12787 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12788 "maximumAggregateablePrefixes"},
12789 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12790 "bgpAggregateAdvertisements"},
12791 [BGP_STATS_SPACE] = {"Address space advertised",
12792 "addressSpaceAdvertised"},
12793 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12794 "advertisementsWithPaths"},
12795 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12796 "longestAsPath"},
12797 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12798 "largestAsPath"},
12799 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12800 "averageAsPathLengthHops"},
12801 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12802 "averageAsPathSizeBytes"},
12803 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12804 [BGP_STATS_MAX] = {NULL, NULL}
12805 };
12806
12807 struct bgp_table_stats {
12808 struct bgp_table *table;
12809 unsigned long long counts[BGP_STATS_MAX];
12810 double total_space;
12811 };
12812
12813 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12814 struct bgp_table_stats *ts, unsigned int space)
12815 {
12816 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12817 struct bgp_path_info *pi;
12818 const struct prefix *rn_p;
12819
12820 if (!bgp_dest_has_bgp_path_info_data(dest))
12821 return;
12822
12823 rn_p = bgp_dest_get_prefix(dest);
12824 ts->counts[BGP_STATS_PREFIXES]++;
12825 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12826
12827 /* check if the prefix is included by any other announcements */
12828 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12829 pdest = bgp_dest_parent_nolock(pdest);
12830
12831 if (pdest == NULL || pdest == top) {
12832 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12833 /* announced address space */
12834 if (space)
12835 ts->total_space += pow(2.0, space - rn_p->prefixlen);
12836 } else if (bgp_dest_has_bgp_path_info_data(pdest))
12837 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
12838
12839
12840 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
12841 ts->counts[BGP_STATS_RIB]++;
12842
12843 if (CHECK_FLAG(pi->attr->flag,
12844 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
12845 ts->counts[BGP_STATS_AGGREGATES]++;
12846
12847 /* as-path stats */
12848 if (pi->attr->aspath) {
12849 unsigned int hops = aspath_count_hops(pi->attr->aspath);
12850 unsigned int size = aspath_size(pi->attr->aspath);
12851 as_t highest = aspath_highest(pi->attr->aspath);
12852
12853 ts->counts[BGP_STATS_ASPATH_COUNT]++;
12854
12855 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
12856 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
12857
12858 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
12859 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
12860
12861 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
12862 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
12863 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
12864 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
12865 }
12866 }
12867 }
12868
12869 static void bgp_table_stats_walker(struct thread *t)
12870 {
12871 struct bgp_dest *dest, *ndest;
12872 struct bgp_dest *top;
12873 struct bgp_table_stats *ts = THREAD_ARG(t);
12874 unsigned int space = 0;
12875
12876 if (!(top = bgp_table_top(ts->table)))
12877 return;
12878
12879 switch (ts->table->afi) {
12880 case AFI_IP:
12881 space = IPV4_MAX_BITLEN;
12882 break;
12883 case AFI_IP6:
12884 space = IPV6_MAX_BITLEN;
12885 break;
12886 case AFI_L2VPN:
12887 space = EVPN_ROUTE_PREFIXLEN;
12888 break;
12889 default:
12890 return;
12891 }
12892
12893 ts->counts[BGP_STATS_MAXBITLEN] = space;
12894
12895 for (dest = top; dest; dest = bgp_route_next(dest)) {
12896 if (ts->table->safi == SAFI_MPLS_VPN
12897 || ts->table->safi == SAFI_ENCAP
12898 || ts->table->safi == SAFI_EVPN) {
12899 struct bgp_table *table;
12900
12901 table = bgp_dest_get_bgp_table_info(dest);
12902 if (!table)
12903 continue;
12904
12905 top = bgp_table_top(table);
12906 for (ndest = bgp_table_top(table); ndest;
12907 ndest = bgp_route_next(ndest))
12908 bgp_table_stats_rn(ndest, top, ts, space);
12909 } else {
12910 bgp_table_stats_rn(dest, top, ts, space);
12911 }
12912 }
12913 }
12914
12915 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
12916 struct json_object *json_array)
12917 {
12918 struct listnode *node, *nnode;
12919 struct bgp *bgp;
12920
12921 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
12922 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12923 }
12924
12925 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12926 safi_t safi, struct json_object *json_array)
12927 {
12928 struct bgp_table_stats ts;
12929 unsigned int i;
12930 int ret = CMD_SUCCESS;
12931 char temp_buf[20];
12932 struct json_object *json = NULL;
12933
12934 if (json_array)
12935 json = json_object_new_object();
12936
12937 if (!bgp->rib[afi][safi]) {
12938 char warning_msg[50];
12939
12940 snprintf(warning_msg, sizeof(warning_msg),
12941 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
12942 safi);
12943
12944 if (!json)
12945 vty_out(vty, "%s\n", warning_msg);
12946 else
12947 json_object_string_add(json, "warning", warning_msg);
12948
12949 ret = CMD_WARNING;
12950 goto end_table_stats;
12951 }
12952
12953 if (!json)
12954 vty_out(vty, "BGP %s RIB statistics (%s)\n",
12955 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
12956 else
12957 json_object_string_add(json, "instance", bgp->name_pretty);
12958
12959 /* labeled-unicast routes live in the unicast table */
12960 if (safi == SAFI_LABELED_UNICAST)
12961 safi = SAFI_UNICAST;
12962
12963 memset(&ts, 0, sizeof(ts));
12964 ts.table = bgp->rib[afi][safi];
12965 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
12966
12967 for (i = 0; i < BGP_STATS_MAX; i++) {
12968 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
12969 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
12970 continue;
12971
12972 switch (i) {
12973 case BGP_STATS_ASPATH_TOTHOPS:
12974 case BGP_STATS_ASPATH_TOTSIZE:
12975 if (!json) {
12976 snprintf(
12977 temp_buf, sizeof(temp_buf), "%12.2f",
12978 ts.counts[i]
12979 ? (float)ts.counts[i]
12980 / (float)ts.counts
12981 [BGP_STATS_ASPATH_COUNT]
12982 : 0);
12983 vty_out(vty, "%-30s: %s",
12984 table_stats_strs[i]
12985 [TABLE_STATS_IDX_VTY],
12986 temp_buf);
12987 } else {
12988 json_object_double_add(
12989 json,
12990 table_stats_strs[i]
12991 [TABLE_STATS_IDX_JSON],
12992 ts.counts[i]
12993 ? (double)ts.counts[i]
12994 / (double)ts.counts
12995 [BGP_STATS_ASPATH_COUNT]
12996 : 0);
12997 }
12998 break;
12999 case BGP_STATS_TOTPLEN:
13000 if (!json) {
13001 snprintf(
13002 temp_buf, sizeof(temp_buf), "%12.2f",
13003 ts.counts[i]
13004 ? (float)ts.counts[i]
13005 / (float)ts.counts
13006 [BGP_STATS_PREFIXES]
13007 : 0);
13008 vty_out(vty, "%-30s: %s",
13009 table_stats_strs[i]
13010 [TABLE_STATS_IDX_VTY],
13011 temp_buf);
13012 } else {
13013 json_object_double_add(
13014 json,
13015 table_stats_strs[i]
13016 [TABLE_STATS_IDX_JSON],
13017 ts.counts[i]
13018 ? (double)ts.counts[i]
13019 / (double)ts.counts
13020 [BGP_STATS_PREFIXES]
13021 : 0);
13022 }
13023 break;
13024 case BGP_STATS_SPACE:
13025 if (!json) {
13026 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13027 ts.total_space);
13028 vty_out(vty, "%-30s: %s\n",
13029 table_stats_strs[i]
13030 [TABLE_STATS_IDX_VTY],
13031 temp_buf);
13032 } else {
13033 json_object_double_add(
13034 json,
13035 table_stats_strs[i]
13036 [TABLE_STATS_IDX_JSON],
13037 (double)ts.total_space);
13038 }
13039 if (afi == AFI_IP6) {
13040 if (!json) {
13041 snprintf(temp_buf, sizeof(temp_buf),
13042 "%12g",
13043 ts.total_space
13044 * pow(2.0, -128 + 32));
13045 vty_out(vty, "%30s: %s\n",
13046 "/32 equivalent %s\n",
13047 temp_buf);
13048 } else {
13049 json_object_double_add(
13050 json, "/32equivalent",
13051 (double)(ts.total_space
13052 * pow(2.0,
13053 -128 + 32)));
13054 }
13055 if (!json) {
13056 snprintf(temp_buf, sizeof(temp_buf),
13057 "%12g",
13058 ts.total_space
13059 * pow(2.0, -128 + 48));
13060 vty_out(vty, "%30s: %s\n",
13061 "/48 equivalent %s\n",
13062 temp_buf);
13063 } else {
13064 json_object_double_add(
13065 json, "/48equivalent",
13066 (double)(ts.total_space
13067 * pow(2.0,
13068 -128 + 48)));
13069 }
13070 } else {
13071 if (!json) {
13072 snprintf(temp_buf, sizeof(temp_buf),
13073 "%12.2f",
13074 ts.total_space * 100.
13075 * pow(2.0, -32));
13076 vty_out(vty, "%30s: %s\n",
13077 "% announced ", temp_buf);
13078 } else {
13079 json_object_double_add(
13080 json, "%announced",
13081 (double)(ts.total_space * 100.
13082 * pow(2.0, -32)));
13083 }
13084 if (!json) {
13085 snprintf(temp_buf, sizeof(temp_buf),
13086 "%12.2f",
13087 ts.total_space
13088 * pow(2.0, -32 + 8));
13089 vty_out(vty, "%30s: %s\n",
13090 "/8 equivalent ", temp_buf);
13091 } else {
13092 json_object_double_add(
13093 json, "/8equivalent",
13094 (double)(ts.total_space
13095 * pow(2.0, -32 + 8)));
13096 }
13097 if (!json) {
13098 snprintf(temp_buf, sizeof(temp_buf),
13099 "%12.2f",
13100 ts.total_space
13101 * pow(2.0, -32 + 24));
13102 vty_out(vty, "%30s: %s\n",
13103 "/24 equivalent ", temp_buf);
13104 } else {
13105 json_object_double_add(
13106 json, "/24equivalent",
13107 (double)(ts.total_space
13108 * pow(2.0, -32 + 24)));
13109 }
13110 }
13111 break;
13112 default:
13113 if (!json) {
13114 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13115 ts.counts[i]);
13116 vty_out(vty, "%-30s: %s",
13117 table_stats_strs[i]
13118 [TABLE_STATS_IDX_VTY],
13119 temp_buf);
13120 } else {
13121 json_object_int_add(
13122 json,
13123 table_stats_strs[i]
13124 [TABLE_STATS_IDX_JSON],
13125 ts.counts[i]);
13126 }
13127 }
13128 if (!json)
13129 vty_out(vty, "\n");
13130 }
13131 end_table_stats:
13132 if (json)
13133 json_object_array_add(json_array, json);
13134 return ret;
13135 }
13136
13137 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13138 safi_t safi, struct json_object *json_array)
13139 {
13140 if (!bgp) {
13141 bgp_table_stats_all(vty, afi, safi, json_array);
13142 return CMD_SUCCESS;
13143 }
13144
13145 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13146 }
13147
13148 enum bgp_pcounts {
13149 PCOUNT_ADJ_IN = 0,
13150 PCOUNT_DAMPED,
13151 PCOUNT_REMOVED,
13152 PCOUNT_HISTORY,
13153 PCOUNT_STALE,
13154 PCOUNT_VALID,
13155 PCOUNT_ALL,
13156 PCOUNT_COUNTED,
13157 PCOUNT_BPATH_SELECTED,
13158 PCOUNT_PFCNT, /* the figure we display to users */
13159 PCOUNT_MAX,
13160 };
13161
13162 static const char *const pcount_strs[] = {
13163 [PCOUNT_ADJ_IN] = "Adj-in",
13164 [PCOUNT_DAMPED] = "Damped",
13165 [PCOUNT_REMOVED] = "Removed",
13166 [PCOUNT_HISTORY] = "History",
13167 [PCOUNT_STALE] = "Stale",
13168 [PCOUNT_VALID] = "Valid",
13169 [PCOUNT_ALL] = "All RIB",
13170 [PCOUNT_COUNTED] = "PfxCt counted",
13171 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13172 [PCOUNT_PFCNT] = "Useable",
13173 [PCOUNT_MAX] = NULL,
13174 };
13175
13176 struct peer_pcounts {
13177 unsigned int count[PCOUNT_MAX];
13178 const struct peer *peer;
13179 const struct bgp_table *table;
13180 safi_t safi;
13181 };
13182
13183 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13184 {
13185 const struct bgp_adj_in *ain;
13186 const struct bgp_path_info *pi;
13187 const struct peer *peer = pc->peer;
13188
13189 for (ain = rn->adj_in; ain; ain = ain->next)
13190 if (ain->peer == peer)
13191 pc->count[PCOUNT_ADJ_IN]++;
13192
13193 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13194
13195 if (pi->peer != peer)
13196 continue;
13197
13198 pc->count[PCOUNT_ALL]++;
13199
13200 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13201 pc->count[PCOUNT_DAMPED]++;
13202 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13203 pc->count[PCOUNT_HISTORY]++;
13204 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13205 pc->count[PCOUNT_REMOVED]++;
13206 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13207 pc->count[PCOUNT_STALE]++;
13208 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13209 pc->count[PCOUNT_VALID]++;
13210 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13211 pc->count[PCOUNT_PFCNT]++;
13212 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13213 pc->count[PCOUNT_BPATH_SELECTED]++;
13214
13215 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13216 pc->count[PCOUNT_COUNTED]++;
13217 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13218 flog_err(
13219 EC_LIB_DEVELOPMENT,
13220 "Attempting to count but flags say it is unusable");
13221 } else {
13222 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13223 flog_err(
13224 EC_LIB_DEVELOPMENT,
13225 "Not counted but flags say we should");
13226 }
13227 }
13228 }
13229
13230 static void bgp_peer_count_walker(struct thread *t)
13231 {
13232 struct bgp_dest *rn, *rm;
13233 const struct bgp_table *table;
13234 struct peer_pcounts *pc = THREAD_ARG(t);
13235
13236 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13237 || pc->safi == SAFI_EVPN) {
13238 /* Special handling for 2-level routing tables. */
13239 for (rn = bgp_table_top(pc->table); rn;
13240 rn = bgp_route_next(rn)) {
13241 table = bgp_dest_get_bgp_table_info(rn);
13242 if (table != NULL)
13243 for (rm = bgp_table_top(table); rm;
13244 rm = bgp_route_next(rm))
13245 bgp_peer_count_proc(rm, pc);
13246 }
13247 } else
13248 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13249 bgp_peer_count_proc(rn, pc);
13250 }
13251
13252 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13253 safi_t safi, bool use_json)
13254 {
13255 struct peer_pcounts pcounts = {.peer = peer};
13256 unsigned int i;
13257 json_object *json = NULL;
13258 json_object *json_loop = NULL;
13259
13260 if (use_json) {
13261 json = json_object_new_object();
13262 json_loop = json_object_new_object();
13263 }
13264
13265 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13266 || !peer->bgp->rib[afi][safi]) {
13267 if (use_json) {
13268 json_object_string_add(
13269 json, "warning",
13270 "No such neighbor or address family");
13271 vty_out(vty, "%s\n", json_object_to_json_string(json));
13272 json_object_free(json);
13273 json_object_free(json_loop);
13274 } else
13275 vty_out(vty, "%% No such neighbor or address family\n");
13276
13277 return CMD_WARNING;
13278 }
13279
13280 memset(&pcounts, 0, sizeof(pcounts));
13281 pcounts.peer = peer;
13282 pcounts.table = peer->bgp->rib[afi][safi];
13283 pcounts.safi = safi;
13284
13285 /* in-place call via thread subsystem so as to record execution time
13286 * stats for the thread-walk (i.e. ensure this can't be blamed on
13287 * on just vty_read()).
13288 */
13289 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13290
13291 if (use_json) {
13292 json_object_string_add(json, "prefixCountsFor", peer->host);
13293 json_object_string_add(json, "multiProtocol",
13294 get_afi_safi_str(afi, safi, true));
13295 json_object_int_add(json, "pfxCounter",
13296 peer->pcount[afi][safi]);
13297
13298 for (i = 0; i < PCOUNT_MAX; i++)
13299 json_object_int_add(json_loop, pcount_strs[i],
13300 pcounts.count[i]);
13301
13302 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13303
13304 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13305 json_object_string_add(json, "pfxctDriftFor",
13306 peer->host);
13307 json_object_string_add(
13308 json, "recommended",
13309 "Please report this bug, with the above command output");
13310 }
13311 vty_json(vty, json);
13312 } else {
13313
13314 if (peer->hostname
13315 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13316 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13317 peer->hostname, peer->host,
13318 get_afi_safi_str(afi, safi, false));
13319 } else {
13320 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13321 get_afi_safi_str(afi, safi, false));
13322 }
13323
13324 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13325 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13326
13327 for (i = 0; i < PCOUNT_MAX; i++)
13328 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13329 pcounts.count[i]);
13330
13331 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13332 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13333 vty_out(vty,
13334 "Please report this bug, with the above command output\n");
13335 }
13336 }
13337
13338 return CMD_SUCCESS;
13339 }
13340
13341 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13342 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13343 "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]",
13344 SHOW_STR
13345 IP_STR
13346 BGP_STR
13347 BGP_INSTANCE_HELP_STR
13348 BGP_AFI_HELP_STR
13349 BGP_SAFI_HELP_STR
13350 "Detailed information on TCP and BGP neighbor connections\n"
13351 "Neighbor to display information about\n"
13352 "Neighbor to display information about\n"
13353 "Neighbor on BGP configured interface\n"
13354 "Display detailed prefix count information\n"
13355 JSON_STR)
13356 {
13357 afi_t afi = AFI_IP6;
13358 safi_t safi = SAFI_UNICAST;
13359 struct peer *peer;
13360 int idx = 0;
13361 struct bgp *bgp = NULL;
13362 bool uj = use_json(argc, argv);
13363
13364 if (uj)
13365 argc--;
13366
13367 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13368 &bgp, uj);
13369 if (!idx)
13370 return CMD_WARNING;
13371
13372 argv_find(argv, argc, "neighbors", &idx);
13373 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13374 if (!peer)
13375 return CMD_WARNING;
13376
13377 return bgp_peer_counts(vty, peer, afi, safi, uj);
13378 }
13379
13380 #ifdef KEEP_OLD_VPN_COMMANDS
13381 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13382 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13383 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13384 SHOW_STR
13385 IP_STR
13386 BGP_STR
13387 BGP_VPNVX_HELP_STR
13388 "Display information about all VPNv4 NLRIs\n"
13389 "Detailed information on TCP and BGP neighbor connections\n"
13390 "Neighbor to display information about\n"
13391 "Neighbor to display information about\n"
13392 "Neighbor on BGP configured interface\n"
13393 "Display detailed prefix count information\n"
13394 JSON_STR)
13395 {
13396 int idx_peer = 6;
13397 struct peer *peer;
13398 bool uj = use_json(argc, argv);
13399
13400 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13401 if (!peer)
13402 return CMD_WARNING;
13403
13404 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13405 }
13406
13407 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13408 show_ip_bgp_vpn_all_route_prefix_cmd,
13409 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13410 SHOW_STR
13411 IP_STR
13412 BGP_STR
13413 BGP_VPNVX_HELP_STR
13414 "Display information about all VPNv4 NLRIs\n"
13415 "Network in the BGP routing table to display\n"
13416 "Network in the BGP routing table to display\n"
13417 JSON_STR)
13418 {
13419 int idx = 0;
13420 char *network = NULL;
13421 struct bgp *bgp = bgp_get_default();
13422 if (!bgp) {
13423 vty_out(vty, "Can't find default instance\n");
13424 return CMD_WARNING;
13425 }
13426
13427 if (argv_find(argv, argc, "A.B.C.D", &idx))
13428 network = argv[idx]->arg;
13429 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13430 network = argv[idx]->arg;
13431 else {
13432 vty_out(vty, "Unable to figure out Network\n");
13433 return CMD_WARNING;
13434 }
13435
13436 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13437 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13438 use_json(argc, argv));
13439 }
13440 #endif /* KEEP_OLD_VPN_COMMANDS */
13441
13442 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13443 show_bgp_l2vpn_evpn_route_prefix_cmd,
13444 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13445 SHOW_STR
13446 BGP_STR
13447 L2VPN_HELP_STR
13448 EVPN_HELP_STR
13449 "Network in the BGP routing table to display\n"
13450 "Network in the BGP routing table to display\n"
13451 "Network in the BGP routing table to display\n"
13452 "Network in the BGP routing table to display\n"
13453 JSON_STR)
13454 {
13455 int idx = 0;
13456 char *network = NULL;
13457 int prefix_check = 0;
13458
13459 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13460 argv_find(argv, argc, "X:X::X:X", &idx))
13461 network = argv[idx]->arg;
13462 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13463 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13464 network = argv[idx]->arg;
13465 prefix_check = 1;
13466 } else {
13467 vty_out(vty, "Unable to figure out Network\n");
13468 return CMD_WARNING;
13469 }
13470 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13471 prefix_check, BGP_PATH_SHOW_ALL,
13472 RPKI_NOT_BEING_USED, use_json(argc, argv));
13473 }
13474
13475 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
13476 struct bgp_table *table, int *header1,
13477 int *header2, json_object *json,
13478 json_object *json_scode,
13479 json_object *json_ocode, bool wide)
13480 {
13481 uint64_t version = table ? table->version : 0;
13482
13483 if (*header1) {
13484 if (json) {
13485 json_object_int_add(json, "bgpTableVersion", version);
13486 json_object_string_addf(json, "bgpLocalRouterId",
13487 "%pI4", &bgp->router_id);
13488 json_object_int_add(json, "defaultLocPrf",
13489 bgp->default_local_pref);
13490 json_object_int_add(json, "localAS", bgp->as);
13491 json_object_object_add(json, "bgpStatusCodes",
13492 json_scode);
13493 json_object_object_add(json, "bgpOriginCodes",
13494 json_ocode);
13495 } else {
13496 vty_out(vty,
13497 "BGP table version is %" PRIu64
13498 ", local router ID is %pI4, vrf id ",
13499 version, &bgp->router_id);
13500 if (bgp->vrf_id == VRF_UNKNOWN)
13501 vty_out(vty, "%s", VRFID_NONE_STR);
13502 else
13503 vty_out(vty, "%u", bgp->vrf_id);
13504 vty_out(vty, "\n");
13505 vty_out(vty, "Default local pref %u, ",
13506 bgp->default_local_pref);
13507 vty_out(vty, "local AS %u\n", bgp->as);
13508 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13509 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13510 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13511 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13512 }
13513 *header1 = 0;
13514 }
13515 if (*header2) {
13516 if (!json)
13517 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13518 : BGP_SHOW_HEADER));
13519 *header2 = 0;
13520 }
13521 }
13522
13523 static void
13524 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13525 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13526 const char *rmap_name, json_object *json, json_object *json_ar,
13527 json_object *json_scode, json_object *json_ocode,
13528 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13529 unsigned long *output_count, unsigned long *filtered_count)
13530 {
13531 struct bgp_adj_in *ain;
13532 struct bgp_adj_out *adj;
13533 struct bgp_dest *dest;
13534 struct bgp *bgp;
13535 struct attr attr;
13536 int ret;
13537 struct update_subgroup *subgrp;
13538 struct peer_af *paf;
13539 bool route_filtered;
13540 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13541 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13542 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13543 || (safi == SAFI_EVPN))
13544 ? true
13545 : false;
13546
13547 bgp = peer->bgp;
13548
13549 subgrp = peer_subgroup(peer, afi, safi);
13550
13551 if (type == bgp_show_adj_route_advertised && subgrp
13552 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13553 if (use_json) {
13554 json_object_int_add(json, "bgpTableVersion",
13555 table->version);
13556 json_object_string_addf(json, "bgpLocalRouterId",
13557 "%pI4", &bgp->router_id);
13558 json_object_int_add(json, "defaultLocPrf",
13559 bgp->default_local_pref);
13560 json_object_int_add(json, "localAS", bgp->as);
13561 json_object_object_add(json, "bgpStatusCodes",
13562 json_scode);
13563 json_object_object_add(json, "bgpOriginCodes",
13564 json_ocode);
13565 json_object_string_add(
13566 json, "bgpOriginatingDefaultNetwork",
13567 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13568 } else {
13569 vty_out(vty,
13570 "BGP table version is %" PRIu64
13571 ", local router ID is %pI4, vrf id ",
13572 table->version, &bgp->router_id);
13573 if (bgp->vrf_id == VRF_UNKNOWN)
13574 vty_out(vty, "%s", VRFID_NONE_STR);
13575 else
13576 vty_out(vty, "%u", bgp->vrf_id);
13577 vty_out(vty, "\n");
13578 vty_out(vty, "Default local pref %u, ",
13579 bgp->default_local_pref);
13580 vty_out(vty, "local AS %u\n", bgp->as);
13581 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13582 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13583 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13584 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13585
13586 vty_out(vty, "Originating default network %s\n\n",
13587 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13588 }
13589 *header1 = 0;
13590 }
13591
13592 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13593 if (type == bgp_show_adj_route_received
13594 || type == bgp_show_adj_route_filtered) {
13595 for (ain = dest->adj_in; ain; ain = ain->next) {
13596 if (ain->peer != peer)
13597 continue;
13598
13599 show_adj_route_header(vty, bgp, table, header1,
13600 header2, json, json_scode,
13601 json_ocode, wide);
13602
13603 if ((safi == SAFI_MPLS_VPN)
13604 || (safi == SAFI_ENCAP)
13605 || (safi == SAFI_EVPN)) {
13606 if (use_json)
13607 json_object_string_add(
13608 json_ar, "rd", rd_str);
13609 else if (show_rd && rd_str) {
13610 vty_out(vty,
13611 "Route Distinguisher: %s\n",
13612 rd_str);
13613 show_rd = false;
13614 }
13615 }
13616
13617 attr = *ain->attr;
13618 route_filtered = false;
13619
13620 /* Filter prefix using distribute list,
13621 * filter list or prefix list
13622 */
13623 const struct prefix *rn_p =
13624 bgp_dest_get_prefix(dest);
13625 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13626 safi))
13627 == FILTER_DENY)
13628 route_filtered = true;
13629
13630 /* Filter prefix using route-map */
13631 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13632 safi, rmap_name, NULL,
13633 0, NULL);
13634
13635 if (type == bgp_show_adj_route_filtered &&
13636 !route_filtered && ret != RMAP_DENY) {
13637 bgp_attr_flush(&attr);
13638 continue;
13639 }
13640
13641 if (type == bgp_show_adj_route_received
13642 && (route_filtered || ret == RMAP_DENY))
13643 (*filtered_count)++;
13644
13645 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
13646 use_json, json_ar, wide);
13647 bgp_attr_flush(&attr);
13648 (*output_count)++;
13649 }
13650 } else if (type == bgp_show_adj_route_advertised) {
13651 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13652 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13653 if (paf->peer != peer || !adj->attr)
13654 continue;
13655
13656 show_adj_route_header(vty, bgp, table,
13657 header1, header2,
13658 json, json_scode,
13659 json_ocode, wide);
13660
13661 const struct prefix *rn_p =
13662 bgp_dest_get_prefix(dest);
13663
13664 attr = *adj->attr;
13665 ret = bgp_output_modifier(
13666 peer, rn_p, &attr, afi, safi,
13667 rmap_name);
13668
13669 if (ret != RMAP_DENY) {
13670 if ((safi == SAFI_MPLS_VPN)
13671 || (safi == SAFI_ENCAP)
13672 || (safi == SAFI_EVPN)) {
13673 if (use_json)
13674 json_object_string_add(
13675 json_ar,
13676 "rd",
13677 rd_str);
13678 else if (show_rd
13679 && rd_str) {
13680 vty_out(vty,
13681 "Route Distinguisher: %s\n",
13682 rd_str);
13683 show_rd = false;
13684 }
13685 }
13686 route_vty_out_tmp(
13687 vty, dest, rn_p, &attr,
13688 safi, use_json, json_ar,
13689 wide);
13690 (*output_count)++;
13691 } else {
13692 (*filtered_count)++;
13693 }
13694
13695 bgp_attr_flush(&attr);
13696 }
13697 } else if (type == bgp_show_adj_route_bestpath) {
13698 struct bgp_path_info *pi;
13699
13700 show_adj_route_header(vty, bgp, table, header1, header2,
13701 json, json_scode, json_ocode,
13702 wide);
13703
13704 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13705 pi = pi->next) {
13706 if (pi->peer != peer)
13707 continue;
13708
13709 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13710 continue;
13711
13712 route_vty_out_tmp(vty, dest,
13713 bgp_dest_get_prefix(dest),
13714 pi->attr, safi, use_json,
13715 json_ar, wide);
13716 (*output_count)++;
13717 }
13718 }
13719 }
13720 }
13721
13722 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13723 safi_t safi, enum bgp_show_adj_route_type type,
13724 const char *rmap_name, uint16_t show_flags)
13725 {
13726 struct bgp *bgp;
13727 struct bgp_table *table;
13728 json_object *json = NULL;
13729 json_object *json_scode = NULL;
13730 json_object *json_ocode = NULL;
13731 json_object *json_ar = NULL;
13732 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13733
13734 /* Init BGP headers here so they're only displayed once
13735 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13736 */
13737 int header1 = 1;
13738 int header2 = 1;
13739
13740 /*
13741 * Initialize variables for each RD
13742 * All prefixes under an RD is aggregated within "json_routes"
13743 */
13744 char rd_str[BUFSIZ] = {0};
13745 json_object *json_routes = NULL;
13746
13747
13748 /* For 2-tier tables, prefix counts need to be
13749 * maintained across multiple runs of show_adj_route()
13750 */
13751 unsigned long output_count_per_rd;
13752 unsigned long filtered_count_per_rd;
13753 unsigned long output_count = 0;
13754 unsigned long filtered_count = 0;
13755
13756 if (use_json) {
13757 json = json_object_new_object();
13758 json_ar = json_object_new_object();
13759 json_scode = json_object_new_object();
13760 json_ocode = json_object_new_object();
13761
13762 json_object_string_add(json_scode, "suppressed", "s");
13763 json_object_string_add(json_scode, "damped", "d");
13764 json_object_string_add(json_scode, "history", "h");
13765 json_object_string_add(json_scode, "valid", "*");
13766 json_object_string_add(json_scode, "best", ">");
13767 json_object_string_add(json_scode, "multipath", "=");
13768 json_object_string_add(json_scode, "internal", "i");
13769 json_object_string_add(json_scode, "ribFailure", "r");
13770 json_object_string_add(json_scode, "stale", "S");
13771 json_object_string_add(json_scode, "removed", "R");
13772
13773 json_object_string_add(json_ocode, "igp", "i");
13774 json_object_string_add(json_ocode, "egp", "e");
13775 json_object_string_add(json_ocode, "incomplete", "?");
13776 }
13777
13778 if (!peer || !peer->afc[afi][safi]) {
13779 if (use_json) {
13780 json_object_string_add(
13781 json, "warning",
13782 "No such neighbor or address family");
13783 vty_out(vty, "%s\n", json_object_to_json_string(json));
13784 json_object_free(json);
13785 json_object_free(json_ar);
13786 json_object_free(json_scode);
13787 json_object_free(json_ocode);
13788 } else
13789 vty_out(vty, "%% No such neighbor or address family\n");
13790
13791 return CMD_WARNING;
13792 }
13793
13794 if ((type == bgp_show_adj_route_received
13795 || type == bgp_show_adj_route_filtered)
13796 && !CHECK_FLAG(peer->af_flags[afi][safi],
13797 PEER_FLAG_SOFT_RECONFIG)) {
13798 if (use_json) {
13799 json_object_string_add(
13800 json, "warning",
13801 "Inbound soft reconfiguration not enabled");
13802 vty_out(vty, "%s\n", json_object_to_json_string(json));
13803 json_object_free(json);
13804 json_object_free(json_ar);
13805 json_object_free(json_scode);
13806 json_object_free(json_ocode);
13807 } else
13808 vty_out(vty,
13809 "%% Inbound soft reconfiguration not enabled\n");
13810
13811 return CMD_WARNING;
13812 }
13813
13814 bgp = peer->bgp;
13815
13816 /* labeled-unicast routes live in the unicast table */
13817 if (safi == SAFI_LABELED_UNICAST)
13818 table = bgp->rib[afi][SAFI_UNICAST];
13819 else
13820 table = bgp->rib[afi][safi];
13821
13822 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13823 || (safi == SAFI_EVPN)) {
13824
13825 struct bgp_dest *dest;
13826
13827 for (dest = bgp_table_top(table); dest;
13828 dest = bgp_route_next(dest)) {
13829 table = bgp_dest_get_bgp_table_info(dest);
13830 if (!table)
13831 continue;
13832
13833 output_count_per_rd = 0;
13834 filtered_count_per_rd = 0;
13835
13836 if (use_json)
13837 json_routes = json_object_new_object();
13838
13839 const struct prefix_rd *prd;
13840 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13841 dest);
13842
13843 prefix_rd2str(prd, rd_str, sizeof(rd_str));
13844
13845 show_adj_route(vty, peer, table, afi, safi, type,
13846 rmap_name, json, json_routes, json_scode,
13847 json_ocode, show_flags, &header1,
13848 &header2, rd_str, &output_count_per_rd,
13849 &filtered_count_per_rd);
13850
13851 /* Don't include an empty RD in the output! */
13852 if (json_routes && (output_count_per_rd > 0))
13853 json_object_object_add(json_ar, rd_str,
13854 json_routes);
13855
13856 output_count += output_count_per_rd;
13857 filtered_count += filtered_count_per_rd;
13858 }
13859 } else
13860 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
13861 json, json_ar, json_scode, json_ocode,
13862 show_flags, &header1, &header2, rd_str,
13863 &output_count, &filtered_count);
13864
13865 if (use_json) {
13866 if (type == bgp_show_adj_route_advertised)
13867 json_object_object_add(json, "advertisedRoutes",
13868 json_ar);
13869 else
13870 json_object_object_add(json, "receivedRoutes", json_ar);
13871 json_object_int_add(json, "totalPrefixCounter", output_count);
13872 json_object_int_add(json, "filteredPrefixCounter",
13873 filtered_count);
13874
13875 /*
13876 * These fields only give up ownership to `json` when `header1`
13877 * is used (set to zero). See code in `show_adj_route` and
13878 * `show_adj_route_header`.
13879 */
13880 if (header1 == 1) {
13881 json_object_free(json_scode);
13882 json_object_free(json_ocode);
13883 }
13884
13885 vty_json(vty, json);
13886 } else if (output_count > 0) {
13887 if (filtered_count > 0)
13888 vty_out(vty,
13889 "\nTotal number of prefixes %ld (%ld filtered)\n",
13890 output_count, filtered_count);
13891 else
13892 vty_out(vty, "\nTotal number of prefixes %ld\n",
13893 output_count);
13894 }
13895
13896 return CMD_SUCCESS;
13897 }
13898
13899 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
13900 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
13901 "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 [json$uj | wide$wide]",
13902 SHOW_STR
13903 IP_STR
13904 BGP_STR
13905 BGP_INSTANCE_HELP_STR
13906 BGP_AFI_HELP_STR
13907 BGP_SAFI_WITH_LABEL_HELP_STR
13908 "Detailed information on TCP and BGP neighbor connections\n"
13909 "Neighbor to display information about\n"
13910 "Neighbor to display information about\n"
13911 "Neighbor on BGP configured interface\n"
13912 "Display the routes selected by best path\n"
13913 JSON_STR
13914 "Increase table width for longer prefixes\n")
13915 {
13916 afi_t afi = AFI_IP6;
13917 safi_t safi = SAFI_UNICAST;
13918 char *rmap_name = NULL;
13919 char *peerstr = NULL;
13920 struct bgp *bgp = NULL;
13921 struct peer *peer;
13922 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
13923 int idx = 0;
13924 uint16_t show_flags = 0;
13925
13926 if (uj)
13927 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13928
13929 if (wide)
13930 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13931
13932 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13933 &bgp, uj);
13934
13935 if (!idx)
13936 return CMD_WARNING;
13937
13938 argv_find(argv, argc, "neighbors", &idx);
13939 peerstr = argv[++idx]->arg;
13940
13941 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13942 if (!peer)
13943 return CMD_WARNING;
13944
13945 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13946 show_flags);
13947 }
13948
13949 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
13950 show_ip_bgp_instance_neighbor_advertised_route_cmd,
13951 "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 WORD] [json$uj | wide$wide]",
13952 SHOW_STR
13953 IP_STR
13954 BGP_STR
13955 BGP_INSTANCE_HELP_STR
13956 BGP_AFI_HELP_STR
13957 BGP_SAFI_WITH_LABEL_HELP_STR
13958 "Display the entries for all address families\n"
13959 "Detailed information on TCP and BGP neighbor connections\n"
13960 "Neighbor to display information about\n"
13961 "Neighbor to display information about\n"
13962 "Neighbor on BGP configured interface\n"
13963 "Display the routes advertised to a BGP neighbor\n"
13964 "Display the received routes from neighbor\n"
13965 "Display the filtered routes received from neighbor\n"
13966 "Route-map to modify the attributes\n"
13967 "Name of the route map\n"
13968 JSON_STR
13969 "Increase table width for longer prefixes\n")
13970 {
13971 afi_t afi = AFI_IP6;
13972 safi_t safi = SAFI_UNICAST;
13973 char *rmap_name = NULL;
13974 char *peerstr = NULL;
13975 struct bgp *bgp = NULL;
13976 struct peer *peer;
13977 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
13978 int idx = 0;
13979 bool first = true;
13980 uint16_t show_flags = 0;
13981 struct listnode *node;
13982 struct bgp *abgp;
13983
13984 if (uj) {
13985 argc--;
13986 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13987 }
13988
13989 if (all) {
13990 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
13991 if (argv_find(argv, argc, "ipv4", &idx))
13992 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
13993
13994 if (argv_find(argv, argc, "ipv6", &idx))
13995 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
13996 }
13997
13998 if (wide)
13999 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14000
14001 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14002 &bgp, uj);
14003 if (!idx)
14004 return CMD_WARNING;
14005
14006 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14007 argv_find(argv, argc, "neighbors", &idx);
14008 peerstr = argv[++idx]->arg;
14009
14010 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14011 if (!peer)
14012 return CMD_WARNING;
14013
14014 if (argv_find(argv, argc, "advertised-routes", &idx))
14015 type = bgp_show_adj_route_advertised;
14016 else if (argv_find(argv, argc, "received-routes", &idx))
14017 type = bgp_show_adj_route_received;
14018 else if (argv_find(argv, argc, "filtered-routes", &idx))
14019 type = bgp_show_adj_route_filtered;
14020
14021 if (argv_find(argv, argc, "route-map", &idx))
14022 rmap_name = argv[++idx]->arg;
14023
14024 if (!all)
14025 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14026 show_flags);
14027 if (uj)
14028 vty_out(vty, "{\n");
14029
14030 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14031 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14032 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14033 : AFI_IP6;
14034 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14035 FOREACH_SAFI (safi) {
14036 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14037 continue;
14038
14039 if (uj) {
14040 if (first)
14041 first = false;
14042 else
14043 vty_out(vty, ",\n");
14044 vty_out(vty, "\"%s\":",
14045 get_afi_safi_str(afi, safi,
14046 true));
14047 } else
14048 vty_out(vty,
14049 "\nFor address family: %s\n",
14050 get_afi_safi_str(afi, safi,
14051 false));
14052
14053 peer_adj_routes(vty, peer, afi, safi, type,
14054 rmap_name, show_flags);
14055 }
14056 }
14057 } else {
14058 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14059 FOREACH_AFI_SAFI (afi, safi) {
14060 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14061 continue;
14062
14063 if (uj) {
14064 if (first)
14065 first = false;
14066 else
14067 vty_out(vty, ",\n");
14068 vty_out(vty, "\"%s\":",
14069 get_afi_safi_str(afi, safi,
14070 true));
14071 } else
14072 vty_out(vty,
14073 "\nFor address family: %s\n",
14074 get_afi_safi_str(afi, safi,
14075 false));
14076
14077 peer_adj_routes(vty, peer, afi, safi, type,
14078 rmap_name, show_flags);
14079 }
14080 }
14081 }
14082 if (uj)
14083 vty_out(vty, "}\n");
14084
14085 return CMD_SUCCESS;
14086 }
14087
14088 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14089 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14090 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14091 SHOW_STR
14092 IP_STR
14093 BGP_STR
14094 BGP_INSTANCE_HELP_STR
14095 "Address Family\n"
14096 "Address Family\n"
14097 "Address Family modifier\n"
14098 "Detailed information on TCP and BGP neighbor connections\n"
14099 "Neighbor to display information about\n"
14100 "Neighbor to display information about\n"
14101 "Neighbor on BGP configured interface\n"
14102 "Display information received from a BGP neighbor\n"
14103 "Display the prefixlist filter\n"
14104 JSON_STR)
14105 {
14106 afi_t afi = AFI_IP6;
14107 safi_t safi = SAFI_UNICAST;
14108 char *peerstr = NULL;
14109 char name[BUFSIZ];
14110 struct peer *peer;
14111 int count;
14112 int idx = 0;
14113 struct bgp *bgp = NULL;
14114 bool uj = use_json(argc, argv);
14115
14116 if (uj)
14117 argc--;
14118
14119 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14120 &bgp, uj);
14121 if (!idx)
14122 return CMD_WARNING;
14123
14124 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14125 argv_find(argv, argc, "neighbors", &idx);
14126 peerstr = argv[++idx]->arg;
14127
14128 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14129 if (!peer)
14130 return CMD_WARNING;
14131
14132 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14133 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14134 if (count) {
14135 if (!uj)
14136 vty_out(vty, "Address Family: %s\n",
14137 get_afi_safi_str(afi, safi, false));
14138 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14139 } else {
14140 if (uj)
14141 vty_out(vty, "{}\n");
14142 else
14143 vty_out(vty, "No functional output\n");
14144 }
14145
14146 return CMD_SUCCESS;
14147 }
14148
14149 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14150 afi_t afi, safi_t safi,
14151 enum bgp_show_type type, bool use_json)
14152 {
14153 uint16_t show_flags = 0;
14154
14155 if (use_json)
14156 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14157
14158 if (!peer || !peer->afc[afi][safi]) {
14159 if (use_json) {
14160 json_object *json_no = NULL;
14161 json_no = json_object_new_object();
14162 json_object_string_add(
14163 json_no, "warning",
14164 "No such neighbor or address family");
14165 vty_out(vty, "%s\n",
14166 json_object_to_json_string(json_no));
14167 json_object_free(json_no);
14168 } else
14169 vty_out(vty, "%% No such neighbor or address family\n");
14170 return CMD_WARNING;
14171 }
14172
14173 /* labeled-unicast routes live in the unicast table */
14174 if (safi == SAFI_LABELED_UNICAST)
14175 safi = SAFI_UNICAST;
14176
14177 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14178 RPKI_NOT_BEING_USED);
14179 }
14180
14181 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14182 show_ip_bgp_flowspec_routes_detailed_cmd,
14183 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14184 SHOW_STR
14185 IP_STR
14186 BGP_STR
14187 BGP_INSTANCE_HELP_STR
14188 BGP_AFI_HELP_STR
14189 "SAFI Flowspec\n"
14190 "Detailed information on flowspec entries\n"
14191 JSON_STR)
14192 {
14193 afi_t afi = AFI_IP6;
14194 safi_t safi = SAFI_UNICAST;
14195 struct bgp *bgp = NULL;
14196 int idx = 0;
14197 bool uj = use_json(argc, argv);
14198 uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
14199
14200 if (uj) {
14201 argc--;
14202 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14203 }
14204
14205 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14206 &bgp, uj);
14207 if (!idx)
14208 return CMD_WARNING;
14209
14210 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14211 show_flags, RPKI_NOT_BEING_USED);
14212 }
14213
14214 DEFUN (show_ip_bgp_neighbor_routes,
14215 show_ip_bgp_neighbor_routes_cmd,
14216 "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]",
14217 SHOW_STR
14218 IP_STR
14219 BGP_STR
14220 BGP_INSTANCE_HELP_STR
14221 BGP_AFI_HELP_STR
14222 BGP_SAFI_WITH_LABEL_HELP_STR
14223 "Detailed information on TCP and BGP neighbor connections\n"
14224 "Neighbor to display information about\n"
14225 "Neighbor to display information about\n"
14226 "Neighbor on BGP configured interface\n"
14227 "Display flap statistics of the routes learned from neighbor\n"
14228 "Display the dampened routes received from neighbor\n"
14229 "Display routes learned from neighbor\n"
14230 JSON_STR)
14231 {
14232 char *peerstr = NULL;
14233 struct bgp *bgp = NULL;
14234 afi_t afi = AFI_IP6;
14235 safi_t safi = SAFI_UNICAST;
14236 struct peer *peer;
14237 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14238 int idx = 0;
14239 bool uj = use_json(argc, argv);
14240
14241 if (uj)
14242 argc--;
14243
14244 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14245 &bgp, uj);
14246 if (!idx)
14247 return CMD_WARNING;
14248
14249 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14250 argv_find(argv, argc, "neighbors", &idx);
14251 peerstr = argv[++idx]->arg;
14252
14253 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14254 if (!peer)
14255 return CMD_WARNING;
14256
14257 if (argv_find(argv, argc, "flap-statistics", &idx))
14258 sh_type = bgp_show_type_flap_neighbor;
14259 else if (argv_find(argv, argc, "dampened-routes", &idx))
14260 sh_type = bgp_show_type_damp_neighbor;
14261 else if (argv_find(argv, argc, "routes", &idx))
14262 sh_type = bgp_show_type_neighbor;
14263
14264 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14265 }
14266
14267 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14268
14269 struct bgp_distance {
14270 /* Distance value for the IP source prefix. */
14271 uint8_t distance;
14272
14273 /* Name of the access-list to be matched. */
14274 char *access_list;
14275 };
14276
14277 DEFUN (show_bgp_afi_vpn_rd_route,
14278 show_bgp_afi_vpn_rd_route_cmd,
14279 "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]",
14280 SHOW_STR
14281 BGP_STR
14282 BGP_AFI_HELP_STR
14283 "Address Family modifier\n"
14284 "Display information for a route distinguisher\n"
14285 "Route Distinguisher\n"
14286 "All Route Distinguishers\n"
14287 "Network in the BGP routing table to display\n"
14288 "Network in the BGP routing table to display\n"
14289 JSON_STR)
14290 {
14291 int ret;
14292 struct prefix_rd prd;
14293 afi_t afi = AFI_MAX;
14294 int idx = 0;
14295
14296 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14297 vty_out(vty, "%% Malformed Address Family\n");
14298 return CMD_WARNING;
14299 }
14300
14301 if (!strcmp(argv[5]->arg, "all"))
14302 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14303 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14304 RPKI_NOT_BEING_USED,
14305 use_json(argc, argv));
14306
14307 ret = str2prefix_rd(argv[5]->arg, &prd);
14308 if (!ret) {
14309 vty_out(vty, "%% Malformed Route Distinguisher\n");
14310 return CMD_WARNING;
14311 }
14312
14313 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14314 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14315 use_json(argc, argv));
14316 }
14317
14318 static struct bgp_distance *bgp_distance_new(void)
14319 {
14320 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14321 }
14322
14323 static void bgp_distance_free(struct bgp_distance *bdistance)
14324 {
14325 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14326 }
14327
14328 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14329 const char *ip_str, const char *access_list_str)
14330 {
14331 int ret;
14332 afi_t afi;
14333 safi_t safi;
14334 struct prefix p;
14335 uint8_t distance;
14336 struct bgp_dest *dest;
14337 struct bgp_distance *bdistance;
14338
14339 afi = bgp_node_afi(vty);
14340 safi = bgp_node_safi(vty);
14341
14342 ret = str2prefix(ip_str, &p);
14343 if (ret == 0) {
14344 vty_out(vty, "Malformed prefix\n");
14345 return CMD_WARNING_CONFIG_FAILED;
14346 }
14347
14348 distance = atoi(distance_str);
14349
14350 /* Get BGP distance node. */
14351 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14352 bdistance = bgp_dest_get_bgp_distance_info(dest);
14353 if (bdistance)
14354 bgp_dest_unlock_node(dest);
14355 else {
14356 bdistance = bgp_distance_new();
14357 bgp_dest_set_bgp_distance_info(dest, bdistance);
14358 }
14359
14360 /* Set distance value. */
14361 bdistance->distance = distance;
14362
14363 /* Reset access-list configuration. */
14364 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14365 if (access_list_str)
14366 bdistance->access_list =
14367 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14368
14369 return CMD_SUCCESS;
14370 }
14371
14372 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14373 const char *ip_str, const char *access_list_str)
14374 {
14375 int ret;
14376 afi_t afi;
14377 safi_t safi;
14378 struct prefix p;
14379 int distance;
14380 struct bgp_dest *dest;
14381 struct bgp_distance *bdistance;
14382
14383 afi = bgp_node_afi(vty);
14384 safi = bgp_node_safi(vty);
14385
14386 ret = str2prefix(ip_str, &p);
14387 if (ret == 0) {
14388 vty_out(vty, "Malformed prefix\n");
14389 return CMD_WARNING_CONFIG_FAILED;
14390 }
14391
14392 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14393 if (!dest) {
14394 vty_out(vty, "Can't find specified prefix\n");
14395 return CMD_WARNING_CONFIG_FAILED;
14396 }
14397
14398 bdistance = bgp_dest_get_bgp_distance_info(dest);
14399 distance = atoi(distance_str);
14400
14401 if (bdistance->distance != distance) {
14402 vty_out(vty, "Distance does not match configured\n");
14403 bgp_dest_unlock_node(dest);
14404 return CMD_WARNING_CONFIG_FAILED;
14405 }
14406
14407 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14408 bgp_distance_free(bdistance);
14409
14410 bgp_dest_set_bgp_path_info(dest, NULL);
14411 bgp_dest_unlock_node(dest);
14412 bgp_dest_unlock_node(dest);
14413
14414 return CMD_SUCCESS;
14415 }
14416
14417 /* Apply BGP information to distance method. */
14418 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14419 afi_t afi, safi_t safi, struct bgp *bgp)
14420 {
14421 struct bgp_dest *dest;
14422 struct prefix q = {0};
14423 struct peer *peer;
14424 struct bgp_distance *bdistance;
14425 struct access_list *alist;
14426 struct bgp_static *bgp_static;
14427
14428 if (!bgp)
14429 return 0;
14430
14431 peer = pinfo->peer;
14432
14433 if (pinfo->attr->distance)
14434 return pinfo->attr->distance;
14435
14436 /* Check source address.
14437 * Note: for aggregate route, peer can have unspec af type.
14438 */
14439 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14440 && !sockunion2hostprefix(&peer->su, &q))
14441 return 0;
14442
14443 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14444 if (dest) {
14445 bdistance = bgp_dest_get_bgp_distance_info(dest);
14446 bgp_dest_unlock_node(dest);
14447
14448 if (bdistance->access_list) {
14449 alist = access_list_lookup(afi, bdistance->access_list);
14450 if (alist
14451 && access_list_apply(alist, p) == FILTER_PERMIT)
14452 return bdistance->distance;
14453 } else
14454 return bdistance->distance;
14455 }
14456
14457 /* Backdoor check. */
14458 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14459 if (dest) {
14460 bgp_static = bgp_dest_get_bgp_static_info(dest);
14461 bgp_dest_unlock_node(dest);
14462
14463 if (bgp_static->backdoor) {
14464 if (bgp->distance_local[afi][safi])
14465 return bgp->distance_local[afi][safi];
14466 else
14467 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14468 }
14469 }
14470
14471 if (peer->sort == BGP_PEER_EBGP) {
14472 if (bgp->distance_ebgp[afi][safi])
14473 return bgp->distance_ebgp[afi][safi];
14474 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14475 } else if (peer->sort == BGP_PEER_IBGP) {
14476 if (bgp->distance_ibgp[afi][safi])
14477 return bgp->distance_ibgp[afi][safi];
14478 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14479 } else {
14480 if (bgp->distance_local[afi][safi])
14481 return bgp->distance_local[afi][safi];
14482 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14483 }
14484 }
14485
14486 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14487 * we should tell ZEBRA update the routes for a specific
14488 * AFI/SAFI to reflect changes in RIB.
14489 */
14490 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14491 afi_t update_afi,
14492 safi_t update_safi)
14493 {
14494 afi_t afi;
14495 safi_t safi;
14496
14497 FOREACH_AFI_SAFI (afi, safi) {
14498 if (!bgp_fibupd_safi(safi))
14499 continue;
14500
14501 if (afi != update_afi && safi != update_safi)
14502 continue;
14503
14504 if (BGP_DEBUG(zebra, ZEBRA))
14505 zlog_debug(
14506 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14507 __func__, afi, safi);
14508 bgp_zebra_announce_table(bgp, afi, safi);
14509 }
14510 }
14511
14512 DEFUN (bgp_distance,
14513 bgp_distance_cmd,
14514 "distance bgp (1-255) (1-255) (1-255)",
14515 "Define an administrative distance\n"
14516 "BGP distance\n"
14517 "Distance for routes external to the AS\n"
14518 "Distance for routes internal to the AS\n"
14519 "Distance for local routes\n")
14520 {
14521 VTY_DECLVAR_CONTEXT(bgp, bgp);
14522 int idx_number = 2;
14523 int idx_number_2 = 3;
14524 int idx_number_3 = 4;
14525 int distance_ebgp = atoi(argv[idx_number]->arg);
14526 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14527 int distance_local = atoi(argv[idx_number_3]->arg);
14528 afi_t afi;
14529 safi_t safi;
14530
14531 afi = bgp_node_afi(vty);
14532 safi = bgp_node_safi(vty);
14533
14534 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14535 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14536 || bgp->distance_local[afi][safi] != distance_local) {
14537 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14538 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14539 bgp->distance_local[afi][safi] = distance_local;
14540 bgp_announce_routes_distance_update(bgp, afi, safi);
14541 }
14542 return CMD_SUCCESS;
14543 }
14544
14545 DEFUN (no_bgp_distance,
14546 no_bgp_distance_cmd,
14547 "no distance bgp [(1-255) (1-255) (1-255)]",
14548 NO_STR
14549 "Define an administrative distance\n"
14550 "BGP distance\n"
14551 "Distance for routes external to the AS\n"
14552 "Distance for routes internal to the AS\n"
14553 "Distance for local routes\n")
14554 {
14555 VTY_DECLVAR_CONTEXT(bgp, bgp);
14556 afi_t afi;
14557 safi_t safi;
14558
14559 afi = bgp_node_afi(vty);
14560 safi = bgp_node_safi(vty);
14561
14562 if (bgp->distance_ebgp[afi][safi] != 0
14563 || bgp->distance_ibgp[afi][safi] != 0
14564 || bgp->distance_local[afi][safi] != 0) {
14565 bgp->distance_ebgp[afi][safi] = 0;
14566 bgp->distance_ibgp[afi][safi] = 0;
14567 bgp->distance_local[afi][safi] = 0;
14568 bgp_announce_routes_distance_update(bgp, afi, safi);
14569 }
14570 return CMD_SUCCESS;
14571 }
14572
14573
14574 DEFUN (bgp_distance_source,
14575 bgp_distance_source_cmd,
14576 "distance (1-255) A.B.C.D/M",
14577 "Define an administrative distance\n"
14578 "Administrative distance\n"
14579 "IP source prefix\n")
14580 {
14581 int idx_number = 1;
14582 int idx_ipv4_prefixlen = 2;
14583 bgp_distance_set(vty, argv[idx_number]->arg,
14584 argv[idx_ipv4_prefixlen]->arg, NULL);
14585 return CMD_SUCCESS;
14586 }
14587
14588 DEFUN (no_bgp_distance_source,
14589 no_bgp_distance_source_cmd,
14590 "no distance (1-255) A.B.C.D/M",
14591 NO_STR
14592 "Define an administrative distance\n"
14593 "Administrative distance\n"
14594 "IP source prefix\n")
14595 {
14596 int idx_number = 2;
14597 int idx_ipv4_prefixlen = 3;
14598 bgp_distance_unset(vty, argv[idx_number]->arg,
14599 argv[idx_ipv4_prefixlen]->arg, NULL);
14600 return CMD_SUCCESS;
14601 }
14602
14603 DEFUN (bgp_distance_source_access_list,
14604 bgp_distance_source_access_list_cmd,
14605 "distance (1-255) A.B.C.D/M WORD",
14606 "Define an administrative distance\n"
14607 "Administrative distance\n"
14608 "IP source prefix\n"
14609 "Access list name\n")
14610 {
14611 int idx_number = 1;
14612 int idx_ipv4_prefixlen = 2;
14613 int idx_word = 3;
14614 bgp_distance_set(vty, argv[idx_number]->arg,
14615 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14616 return CMD_SUCCESS;
14617 }
14618
14619 DEFUN (no_bgp_distance_source_access_list,
14620 no_bgp_distance_source_access_list_cmd,
14621 "no distance (1-255) A.B.C.D/M WORD",
14622 NO_STR
14623 "Define an administrative distance\n"
14624 "Administrative distance\n"
14625 "IP source prefix\n"
14626 "Access list name\n")
14627 {
14628 int idx_number = 2;
14629 int idx_ipv4_prefixlen = 3;
14630 int idx_word = 4;
14631 bgp_distance_unset(vty, argv[idx_number]->arg,
14632 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14633 return CMD_SUCCESS;
14634 }
14635
14636 DEFUN (ipv6_bgp_distance_source,
14637 ipv6_bgp_distance_source_cmd,
14638 "distance (1-255) X:X::X:X/M",
14639 "Define an administrative distance\n"
14640 "Administrative distance\n"
14641 "IP source prefix\n")
14642 {
14643 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
14644 return CMD_SUCCESS;
14645 }
14646
14647 DEFUN (no_ipv6_bgp_distance_source,
14648 no_ipv6_bgp_distance_source_cmd,
14649 "no distance (1-255) X:X::X:X/M",
14650 NO_STR
14651 "Define an administrative distance\n"
14652 "Administrative distance\n"
14653 "IP source prefix\n")
14654 {
14655 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
14656 return CMD_SUCCESS;
14657 }
14658
14659 DEFUN (ipv6_bgp_distance_source_access_list,
14660 ipv6_bgp_distance_source_access_list_cmd,
14661 "distance (1-255) X:X::X:X/M WORD",
14662 "Define an administrative distance\n"
14663 "Administrative distance\n"
14664 "IP source prefix\n"
14665 "Access list name\n")
14666 {
14667 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
14668 return CMD_SUCCESS;
14669 }
14670
14671 DEFUN (no_ipv6_bgp_distance_source_access_list,
14672 no_ipv6_bgp_distance_source_access_list_cmd,
14673 "no distance (1-255) X:X::X:X/M WORD",
14674 NO_STR
14675 "Define an administrative distance\n"
14676 "Administrative distance\n"
14677 "IP source prefix\n"
14678 "Access list name\n")
14679 {
14680 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
14681 return CMD_SUCCESS;
14682 }
14683
14684 DEFUN (bgp_damp_set,
14685 bgp_damp_set_cmd,
14686 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14687 "BGP Specific commands\n"
14688 "Enable route-flap dampening\n"
14689 "Half-life time for the penalty\n"
14690 "Value to start reusing a route\n"
14691 "Value to start suppressing a route\n"
14692 "Maximum duration to suppress a stable route\n")
14693 {
14694 VTY_DECLVAR_CONTEXT(bgp, bgp);
14695 int idx_half_life = 2;
14696 int idx_reuse = 3;
14697 int idx_suppress = 4;
14698 int idx_max_suppress = 5;
14699 int half = DEFAULT_HALF_LIFE * 60;
14700 int reuse = DEFAULT_REUSE;
14701 int suppress = DEFAULT_SUPPRESS;
14702 int max = 4 * half;
14703
14704 if (argc == 6) {
14705 half = atoi(argv[idx_half_life]->arg) * 60;
14706 reuse = atoi(argv[idx_reuse]->arg);
14707 suppress = atoi(argv[idx_suppress]->arg);
14708 max = atoi(argv[idx_max_suppress]->arg) * 60;
14709 } else if (argc == 3) {
14710 half = atoi(argv[idx_half_life]->arg) * 60;
14711 max = 4 * half;
14712 }
14713
14714 /*
14715 * These can't be 0 but our SA doesn't understand the
14716 * way our cli is constructed
14717 */
14718 assert(reuse);
14719 assert(half);
14720 if (suppress < reuse) {
14721 vty_out(vty,
14722 "Suppress value cannot be less than reuse value \n");
14723 return 0;
14724 }
14725
14726 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
14727 reuse, suppress, max);
14728 }
14729
14730 DEFUN (bgp_damp_unset,
14731 bgp_damp_unset_cmd,
14732 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14733 NO_STR
14734 "BGP Specific commands\n"
14735 "Enable route-flap dampening\n"
14736 "Half-life time for the penalty\n"
14737 "Value to start reusing a route\n"
14738 "Value to start suppressing a route\n"
14739 "Maximum duration to suppress a stable route\n")
14740 {
14741 VTY_DECLVAR_CONTEXT(bgp, bgp);
14742 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
14743 }
14744
14745 /* Display specified route of BGP table. */
14746 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14747 const char *ip_str, afi_t afi, safi_t safi,
14748 struct prefix_rd *prd, int prefix_check)
14749 {
14750 int ret;
14751 struct prefix match;
14752 struct bgp_dest *dest;
14753 struct bgp_dest *rm;
14754 struct bgp_path_info *pi;
14755 struct bgp_path_info *pi_temp;
14756 struct bgp *bgp;
14757 struct bgp_table *table;
14758
14759 /* BGP structure lookup. */
14760 if (view_name) {
14761 bgp = bgp_lookup_by_name(view_name);
14762 if (bgp == NULL) {
14763 vty_out(vty, "%% Can't find BGP instance %s\n",
14764 view_name);
14765 return CMD_WARNING;
14766 }
14767 } else {
14768 bgp = bgp_get_default();
14769 if (bgp == NULL) {
14770 vty_out(vty, "%% No BGP process is configured\n");
14771 return CMD_WARNING;
14772 }
14773 }
14774
14775 /* Check IP address argument. */
14776 ret = str2prefix(ip_str, &match);
14777 if (!ret) {
14778 vty_out(vty, "%% address is malformed\n");
14779 return CMD_WARNING;
14780 }
14781
14782 match.family = afi2family(afi);
14783
14784 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14785 || (safi == SAFI_EVPN)) {
14786 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14787 dest = bgp_route_next(dest)) {
14788 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14789
14790 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14791 continue;
14792 table = bgp_dest_get_bgp_table_info(dest);
14793 if (!table)
14794 continue;
14795 rm = bgp_node_match(table, &match);
14796 if (rm == NULL)
14797 continue;
14798
14799 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
14800
14801 if (!prefix_check
14802 || rm_p->prefixlen == match.prefixlen) {
14803 pi = bgp_dest_get_bgp_path_info(rm);
14804 while (pi) {
14805 if (pi->extra && pi->extra->damp_info) {
14806 pi_temp = pi->next;
14807 bgp_damp_info_free(
14808 pi->extra->damp_info,
14809 1, afi, safi);
14810 pi = pi_temp;
14811 } else
14812 pi = pi->next;
14813 }
14814 }
14815
14816 bgp_dest_unlock_node(rm);
14817 }
14818 } else {
14819 dest = bgp_node_match(bgp->rib[afi][safi], &match);
14820 if (dest != NULL) {
14821 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14822
14823 if (!prefix_check
14824 || dest_p->prefixlen == match.prefixlen) {
14825 pi = bgp_dest_get_bgp_path_info(dest);
14826 while (pi) {
14827 if (pi->extra && pi->extra->damp_info) {
14828 pi_temp = pi->next;
14829 bgp_damp_info_free(
14830 pi->extra->damp_info,
14831 1, afi, safi);
14832 pi = pi_temp;
14833 } else
14834 pi = pi->next;
14835 }
14836 }
14837
14838 bgp_dest_unlock_node(dest);
14839 }
14840 }
14841
14842 return CMD_SUCCESS;
14843 }
14844
14845 DEFUN (clear_ip_bgp_dampening,
14846 clear_ip_bgp_dampening_cmd,
14847 "clear ip bgp dampening",
14848 CLEAR_STR
14849 IP_STR
14850 BGP_STR
14851 "Clear route flap dampening information\n")
14852 {
14853 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
14854 return CMD_SUCCESS;
14855 }
14856
14857 DEFUN (clear_ip_bgp_dampening_prefix,
14858 clear_ip_bgp_dampening_prefix_cmd,
14859 "clear ip bgp dampening A.B.C.D/M",
14860 CLEAR_STR
14861 IP_STR
14862 BGP_STR
14863 "Clear route flap dampening information\n"
14864 "IPv4 prefix\n")
14865 {
14866 int idx_ipv4_prefixlen = 4;
14867 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
14868 AFI_IP, SAFI_UNICAST, NULL, 1);
14869 }
14870
14871 DEFUN (clear_ip_bgp_dampening_address,
14872 clear_ip_bgp_dampening_address_cmd,
14873 "clear ip bgp dampening A.B.C.D",
14874 CLEAR_STR
14875 IP_STR
14876 BGP_STR
14877 "Clear route flap dampening information\n"
14878 "Network to clear damping information\n")
14879 {
14880 int idx_ipv4 = 4;
14881 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
14882 SAFI_UNICAST, NULL, 0);
14883 }
14884
14885 DEFUN (clear_ip_bgp_dampening_address_mask,
14886 clear_ip_bgp_dampening_address_mask_cmd,
14887 "clear ip bgp dampening A.B.C.D A.B.C.D",
14888 CLEAR_STR
14889 IP_STR
14890 BGP_STR
14891 "Clear route flap dampening information\n"
14892 "Network to clear damping information\n"
14893 "Network mask\n")
14894 {
14895 int idx_ipv4 = 4;
14896 int idx_ipv4_2 = 5;
14897 int ret;
14898 char prefix_str[BUFSIZ];
14899
14900 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
14901 prefix_str, sizeof(prefix_str));
14902 if (!ret) {
14903 vty_out(vty, "%% Inconsistent address and mask\n");
14904 return CMD_WARNING;
14905 }
14906
14907 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
14908 NULL, 0);
14909 }
14910
14911 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
14912 {
14913 struct vty *vty = arg;
14914 struct peer *peer = bucket->data;
14915 char buf[SU_ADDRSTRLEN];
14916
14917 vty_out(vty, "\tPeer: %s %s\n", peer->host,
14918 sockunion2str(&peer->su, buf, sizeof(buf)));
14919 }
14920
14921 DEFUN (show_bgp_listeners,
14922 show_bgp_listeners_cmd,
14923 "show bgp listeners",
14924 SHOW_STR
14925 BGP_STR
14926 "Display Listen Sockets and who created them\n")
14927 {
14928 bgp_dump_listener_info(vty);
14929
14930 return CMD_SUCCESS;
14931 }
14932
14933 DEFUN (show_bgp_peerhash,
14934 show_bgp_peerhash_cmd,
14935 "show bgp peerhash",
14936 SHOW_STR
14937 BGP_STR
14938 "Display information about the BGP peerhash\n")
14939 {
14940 struct list *instances = bm->bgp;
14941 struct listnode *node;
14942 struct bgp *bgp;
14943
14944 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
14945 vty_out(vty, "BGP: %s\n", bgp->name);
14946 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
14947 vty);
14948 }
14949
14950 return CMD_SUCCESS;
14951 }
14952
14953 /* also used for encap safi */
14954 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
14955 afi_t afi, safi_t safi)
14956 {
14957 struct bgp_dest *pdest;
14958 struct bgp_dest *dest;
14959 struct bgp_table *table;
14960 const struct prefix *p;
14961 const struct prefix_rd *prd;
14962 struct bgp_static *bgp_static;
14963 mpls_label_t label;
14964 char rdbuf[RD_ADDRSTRLEN];
14965
14966 /* Network configuration. */
14967 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14968 pdest = bgp_route_next(pdest)) {
14969 table = bgp_dest_get_bgp_table_info(pdest);
14970 if (!table)
14971 continue;
14972
14973 for (dest = bgp_table_top(table); dest;
14974 dest = bgp_route_next(dest)) {
14975 bgp_static = bgp_dest_get_bgp_static_info(dest);
14976 if (bgp_static == NULL)
14977 continue;
14978
14979 p = bgp_dest_get_prefix(dest);
14980 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14981 pdest);
14982
14983 /* "network" configuration display. */
14984 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14985 label = decode_label(&bgp_static->label);
14986
14987 vty_out(vty, " network %pFX rd %s", p, rdbuf);
14988 if (safi == SAFI_MPLS_VPN)
14989 vty_out(vty, " label %u", label);
14990
14991 if (bgp_static->rmap.name)
14992 vty_out(vty, " route-map %s",
14993 bgp_static->rmap.name);
14994
14995 if (bgp_static->backdoor)
14996 vty_out(vty, " backdoor");
14997
14998 vty_out(vty, "\n");
14999 }
15000 }
15001 }
15002
15003 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15004 afi_t afi, safi_t safi)
15005 {
15006 struct bgp_dest *pdest;
15007 struct bgp_dest *dest;
15008 struct bgp_table *table;
15009 const struct prefix *p;
15010 const struct prefix_rd *prd;
15011 struct bgp_static *bgp_static;
15012 char buf[PREFIX_STRLEN * 2];
15013 char buf2[SU_ADDRSTRLEN];
15014 char rdbuf[RD_ADDRSTRLEN];
15015 char esi_buf[ESI_STR_LEN];
15016
15017 /* Network configuration. */
15018 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15019 pdest = bgp_route_next(pdest)) {
15020 table = bgp_dest_get_bgp_table_info(pdest);
15021 if (!table)
15022 continue;
15023
15024 for (dest = bgp_table_top(table); dest;
15025 dest = bgp_route_next(dest)) {
15026 bgp_static = bgp_dest_get_bgp_static_info(dest);
15027 if (bgp_static == NULL)
15028 continue;
15029
15030 char *macrouter = NULL;
15031
15032 if (bgp_static->router_mac)
15033 macrouter = prefix_mac2str(
15034 bgp_static->router_mac, NULL, 0);
15035 if (bgp_static->eth_s_id)
15036 esi_to_str(bgp_static->eth_s_id,
15037 esi_buf, sizeof(esi_buf));
15038 p = bgp_dest_get_prefix(dest);
15039 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15040
15041 /* "network" configuration display. */
15042 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
15043 if (p->u.prefix_evpn.route_type == 5) {
15044 char local_buf[PREFIX_STRLEN];
15045 uint8_t family = is_evpn_prefix_ipaddr_v4((
15046 struct prefix_evpn *)p)
15047 ? AF_INET
15048 : AF_INET6;
15049 inet_ntop(family,
15050 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15051 local_buf, PREFIX_STRLEN);
15052 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15053 p->u.prefix_evpn.prefix_addr
15054 .ip_prefix_length);
15055 } else {
15056 prefix2str(p, buf, sizeof(buf));
15057 }
15058
15059 if (bgp_static->gatewayIp.family == AF_INET
15060 || bgp_static->gatewayIp.family == AF_INET6)
15061 inet_ntop(bgp_static->gatewayIp.family,
15062 &bgp_static->gatewayIp.u.prefix, buf2,
15063 sizeof(buf2));
15064 vty_out(vty,
15065 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15066 buf, rdbuf,
15067 p->u.prefix_evpn.prefix_addr.eth_tag,
15068 decode_label(&bgp_static->label), esi_buf, buf2,
15069 macrouter);
15070
15071 XFREE(MTYPE_TMP, macrouter);
15072 }
15073 }
15074 }
15075
15076 /* Configuration of static route announcement and aggregate
15077 information. */
15078 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15079 safi_t safi)
15080 {
15081 struct bgp_dest *dest;
15082 const struct prefix *p;
15083 struct bgp_static *bgp_static;
15084 struct bgp_aggregate *bgp_aggregate;
15085
15086 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15087 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15088 return;
15089 }
15090
15091 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15092 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15093 return;
15094 }
15095
15096 /* Network configuration. */
15097 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15098 dest = bgp_route_next(dest)) {
15099 bgp_static = bgp_dest_get_bgp_static_info(dest);
15100 if (bgp_static == NULL)
15101 continue;
15102
15103 p = bgp_dest_get_prefix(dest);
15104
15105 vty_out(vty, " network %pFX", p);
15106
15107 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15108 vty_out(vty, " label-index %u",
15109 bgp_static->label_index);
15110
15111 if (bgp_static->rmap.name)
15112 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15113
15114 if (bgp_static->backdoor)
15115 vty_out(vty, " backdoor");
15116
15117 vty_out(vty, "\n");
15118 }
15119
15120 /* Aggregate-address configuration. */
15121 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15122 dest = bgp_route_next(dest)) {
15123 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15124 if (bgp_aggregate == NULL)
15125 continue;
15126
15127 p = bgp_dest_get_prefix(dest);
15128
15129 vty_out(vty, " aggregate-address %pFX", p);
15130
15131 if (bgp_aggregate->as_set)
15132 vty_out(vty, " as-set");
15133
15134 if (bgp_aggregate->summary_only)
15135 vty_out(vty, " summary-only");
15136
15137 if (bgp_aggregate->rmap.name)
15138 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15139
15140 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15141 vty_out(vty, " origin %s",
15142 bgp_origin2str(bgp_aggregate->origin));
15143
15144 if (bgp_aggregate->match_med)
15145 vty_out(vty, " matching-MED-only");
15146
15147 if (bgp_aggregate->suppress_map_name)
15148 vty_out(vty, " suppress-map %s",
15149 bgp_aggregate->suppress_map_name);
15150
15151 vty_out(vty, "\n");
15152 }
15153 }
15154
15155 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15156 safi_t safi)
15157 {
15158 struct bgp_dest *dest;
15159 struct bgp_distance *bdistance;
15160
15161 /* Distance configuration. */
15162 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15163 && bgp->distance_local[afi][safi]
15164 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15165 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15166 || bgp->distance_local[afi][safi]
15167 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15168 vty_out(vty, " distance bgp %d %d %d\n",
15169 bgp->distance_ebgp[afi][safi],
15170 bgp->distance_ibgp[afi][safi],
15171 bgp->distance_local[afi][safi]);
15172 }
15173
15174 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15175 dest = bgp_route_next(dest)) {
15176 bdistance = bgp_dest_get_bgp_distance_info(dest);
15177 if (bdistance != NULL)
15178 vty_out(vty, " distance %d %pBD %s\n",
15179 bdistance->distance, dest,
15180 bdistance->access_list ? bdistance->access_list
15181 : "");
15182 }
15183 }
15184
15185 /* Allocate routing table structure and install commands. */
15186 void bgp_route_init(void)
15187 {
15188 afi_t afi;
15189 safi_t safi;
15190
15191 /* Init BGP distance table. */
15192 FOREACH_AFI_SAFI (afi, safi)
15193 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15194
15195 /* IPv4 BGP commands. */
15196 install_element(BGP_NODE, &bgp_table_map_cmd);
15197 install_element(BGP_NODE, &bgp_network_cmd);
15198 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15199
15200 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15201
15202 /* IPv4 unicast configuration. */
15203 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15204 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15205 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15206
15207 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15208
15209 /* IPv4 multicast configuration. */
15210 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15211 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15212 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15213 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15214
15215 /* IPv4 labeled-unicast configuration. */
15216 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15217 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15218
15219 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15220 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15221 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15222 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15223 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15224 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15225 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15226 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15227
15228 install_element(VIEW_NODE,
15229 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15230 install_element(VIEW_NODE,
15231 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15232 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15233 install_element(VIEW_NODE,
15234 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15235 #ifdef KEEP_OLD_VPN_COMMANDS
15236 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15237 #endif /* KEEP_OLD_VPN_COMMANDS */
15238 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15239 install_element(VIEW_NODE,
15240 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15241
15242 /* BGP dampening clear commands */
15243 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15244 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15245
15246 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15247 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15248
15249 /* prefix count */
15250 install_element(ENABLE_NODE,
15251 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15252 #ifdef KEEP_OLD_VPN_COMMANDS
15253 install_element(ENABLE_NODE,
15254 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15255 #endif /* KEEP_OLD_VPN_COMMANDS */
15256
15257 /* New config IPv6 BGP commands. */
15258 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15259 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15260 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15261
15262 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15263
15264 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15265
15266 /* IPv6 labeled unicast address family. */
15267 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15268 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15269
15270 install_element(BGP_NODE, &bgp_distance_cmd);
15271 install_element(BGP_NODE, &no_bgp_distance_cmd);
15272 install_element(BGP_NODE, &bgp_distance_source_cmd);
15273 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15274 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15275 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15276 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15277 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15278 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15279 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15280 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15281 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15282 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15283 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15284 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15285 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15286 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15287 install_element(BGP_IPV4M_NODE,
15288 &no_bgp_distance_source_access_list_cmd);
15289 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15290 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15291 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15292 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15293 install_element(BGP_IPV6_NODE,
15294 &ipv6_bgp_distance_source_access_list_cmd);
15295 install_element(BGP_IPV6_NODE,
15296 &no_ipv6_bgp_distance_source_access_list_cmd);
15297 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15298 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15299 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15300 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15301 install_element(BGP_IPV6M_NODE,
15302 &ipv6_bgp_distance_source_access_list_cmd);
15303 install_element(BGP_IPV6M_NODE,
15304 &no_ipv6_bgp_distance_source_access_list_cmd);
15305
15306 /* BGP dampening */
15307 install_element(BGP_NODE, &bgp_damp_set_cmd);
15308 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15309 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15310 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15311 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15312 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15313 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15314 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15315 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15316 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15317 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15318 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15319 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15320 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15321
15322 /* Large Communities */
15323 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15324 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15325
15326 /* show bgp ipv4 flowspec detailed */
15327 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15328
15329 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15330 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15331 }
15332
15333 void bgp_route_finish(void)
15334 {
15335 afi_t afi;
15336 safi_t safi;
15337
15338 FOREACH_AFI_SAFI (afi, safi) {
15339 bgp_table_unlock(bgp_distance_table[afi][safi]);
15340 bgp_distance_table[afi][safi] = NULL;
15341 }
15342 }