]> git.proxmox.com Git - mirror_frr.git/blame_incremental - bgpd/bgp_route.c
topotests: add bgp vpnv4 over gre test
[mirror_frr.git] / bgpd / bgp_route.c
... / ...
CommitLineData
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
96DEFINE_HOOK(bgp_snmp_update_stats,
97 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
98 (rn, pi, added));
99
100DEFINE_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 */
106static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
107 safi_t safi);
108
109/* Extern from bgp_dump.c */
110extern const char *bgp_origin_str[];
111extern 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
116static 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
131DEFINE_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. */
137static 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
145struct 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
175struct 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 */
205static 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
217void 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 */
274struct 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. */
282static 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
298struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
299{
300 path->lock++;
301 return path;
302}
303
304struct 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 */
318static 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
394void 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* */
415void 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
430void 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 */
440void 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 */
448static 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
478static 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 */
487void 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
501void 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. */
517static 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
529void 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 */
543struct 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 */
560static 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 || mpath_cfg->same_clusterlen)) {
1085 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1086 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1087
1088 if (newm < existm) {
1089 if (debug && peer_sort_ret < 0)
1090 zlog_debug(
1091 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1092 pfx_buf, new_buf, exist_buf,
1093 newm, existm);
1094 igp_metric_ret = 1;
1095 }
1096
1097 if (newm > existm) {
1098 if (debug && peer_sort_ret < 0)
1099 zlog_debug(
1100 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1101 pfx_buf, new_buf, exist_buf,
1102 newm, existm);
1103 igp_metric_ret = 0;
1104 }
1105 }
1106 }
1107
1108 /* 10. confed-external vs. confed-internal */
1109 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1110 if (new_sort == BGP_PEER_CONFED
1111 && exist_sort == BGP_PEER_IBGP) {
1112 *reason = bgp_path_selection_confed;
1113 if (debug)
1114 zlog_debug(
1115 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1116 pfx_buf, new_buf, exist_buf);
1117 if (!CHECK_FLAG(bgp->flags,
1118 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1119 return 1;
1120 peer_sort_ret = 1;
1121 }
1122
1123 if (exist_sort == BGP_PEER_CONFED
1124 && new_sort == BGP_PEER_IBGP) {
1125 *reason = bgp_path_selection_confed;
1126 if (debug)
1127 zlog_debug(
1128 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1129 pfx_buf, new_buf, exist_buf);
1130 if (!CHECK_FLAG(bgp->flags,
1131 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1132 return 0;
1133 peer_sort_ret = 0;
1134 }
1135 }
1136
1137 /* 11. Maximum path check. */
1138 if (newm == existm) {
1139 /* If one path has a label but the other does not, do not treat
1140 * them as equals for multipath
1141 */
1142 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1143 != (exist->extra
1144 && bgp_is_valid_label(&exist->extra->label[0]))) {
1145 if (debug)
1146 zlog_debug(
1147 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1148 pfx_buf, new_buf, exist_buf);
1149 } else if (CHECK_FLAG(bgp->flags,
1150 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1151
1152 /*
1153 * For the two paths, all comparison steps till IGP
1154 * metric
1155 * have succeeded - including AS_PATH hop count. Since
1156 * 'bgp
1157 * bestpath as-path multipath-relax' knob is on, we
1158 * don't need
1159 * an exact match of AS_PATH. Thus, mark the paths are
1160 * equal.
1161 * That will trigger both these paths to get into the
1162 * multipath
1163 * array.
1164 */
1165 *paths_eq = 1;
1166
1167 if (debug)
1168 zlog_debug(
1169 "%s: %s and %s are equal via multipath-relax",
1170 pfx_buf, new_buf, exist_buf);
1171 } else if (new->peer->sort == BGP_PEER_IBGP) {
1172 if (aspath_cmp(new->attr->aspath,
1173 exist->attr->aspath)) {
1174 *paths_eq = 1;
1175
1176 if (debug)
1177 zlog_debug(
1178 "%s: %s and %s are equal via matching aspaths",
1179 pfx_buf, new_buf, exist_buf);
1180 }
1181 } else if (new->peer->as == exist->peer->as) {
1182 *paths_eq = 1;
1183
1184 if (debug)
1185 zlog_debug(
1186 "%s: %s and %s are equal via same remote-as",
1187 pfx_buf, new_buf, exist_buf);
1188 }
1189 } else {
1190 /*
1191 * TODO: If unequal cost ibgp multipath is enabled we can
1192 * mark the paths as equal here instead of returning
1193 */
1194
1195 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1196 * if either step 7 or 10 (peer type checks) yielded a winner,
1197 * that result was returned immediately. Returning from step 10
1198 * ignored the return value computed in steps 8 and 9 (IGP
1199 * metric checks). In order to preserve that behavior, if
1200 * peer_sort_ret is set, return that rather than igp_metric_ret.
1201 */
1202 ret = peer_sort_ret;
1203 if (peer_sort_ret < 0) {
1204 ret = igp_metric_ret;
1205 if (debug) {
1206 if (ret == 1)
1207 zlog_debug(
1208 "%s: %s wins over %s after IGP metric comparison",
1209 pfx_buf, new_buf, exist_buf);
1210 else
1211 zlog_debug(
1212 "%s: %s loses to %s after IGP metric comparison",
1213 pfx_buf, new_buf, exist_buf);
1214 }
1215 *reason = bgp_path_selection_igp_metric;
1216 }
1217 return ret;
1218 }
1219
1220 /*
1221 * At this point, the decision whether to set *paths_eq = 1 has been
1222 * completed. If we deferred returning because of bestpath peer-type
1223 * relax configuration, return now.
1224 */
1225 if (peer_sort_ret >= 0)
1226 return peer_sort_ret;
1227
1228 /* 12. If both paths are external, prefer the path that was received
1229 first (the oldest one). This step minimizes route-flap, since a
1230 newer path won't displace an older one, even if it was the
1231 preferred route based on the additional decision criteria below. */
1232 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1233 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1234 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1235 *reason = bgp_path_selection_older;
1236 if (debug)
1237 zlog_debug(
1238 "%s: %s wins over %s due to oldest external",
1239 pfx_buf, new_buf, exist_buf);
1240 return 1;
1241 }
1242
1243 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1244 *reason = bgp_path_selection_older;
1245 if (debug)
1246 zlog_debug(
1247 "%s: %s loses to %s due to oldest external",
1248 pfx_buf, new_buf, exist_buf);
1249 return 0;
1250 }
1251 }
1252
1253 /* 13. Router-ID comparison. */
1254 /* If one of the paths is "stale", the corresponding peer router-id will
1255 * be 0 and would always win over the other path. If originator id is
1256 * used for the comparison, it will decide which path is better.
1257 */
1258 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1259 new_id.s_addr = newattr->originator_id.s_addr;
1260 else
1261 new_id.s_addr = new->peer->remote_id.s_addr;
1262 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1263 exist_id.s_addr = existattr->originator_id.s_addr;
1264 else
1265 exist_id.s_addr = exist->peer->remote_id.s_addr;
1266
1267 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1268 *reason = bgp_path_selection_router_id;
1269 if (debug)
1270 zlog_debug(
1271 "%s: %s wins over %s due to Router-ID comparison",
1272 pfx_buf, new_buf, exist_buf);
1273 return 1;
1274 }
1275
1276 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1277 *reason = bgp_path_selection_router_id;
1278 if (debug)
1279 zlog_debug(
1280 "%s: %s loses to %s due to Router-ID comparison",
1281 pfx_buf, new_buf, exist_buf);
1282 return 0;
1283 }
1284
1285 /* 14. Cluster length comparison. */
1286 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1287 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1288
1289 if (new_cluster < exist_cluster) {
1290 *reason = bgp_path_selection_cluster_length;
1291 if (debug)
1292 zlog_debug(
1293 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1294 pfx_buf, new_buf, exist_buf, new_cluster,
1295 exist_cluster);
1296 return 1;
1297 }
1298
1299 if (new_cluster > exist_cluster) {
1300 *reason = bgp_path_selection_cluster_length;
1301 if (debug)
1302 zlog_debug(
1303 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1304 pfx_buf, new_buf, exist_buf, new_cluster,
1305 exist_cluster);
1306 return 0;
1307 }
1308
1309 /* 15. Neighbor address comparison. */
1310 /* Do this only if neither path is "stale" as stale paths do not have
1311 * valid peer information (as the connection may or may not be up).
1312 */
1313 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1314 *reason = bgp_path_selection_stale;
1315 if (debug)
1316 zlog_debug(
1317 "%s: %s wins over %s due to latter path being STALE",
1318 pfx_buf, new_buf, exist_buf);
1319 return 1;
1320 }
1321
1322 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1323 *reason = bgp_path_selection_stale;
1324 if (debug)
1325 zlog_debug(
1326 "%s: %s loses to %s due to former path being STALE",
1327 pfx_buf, new_buf, exist_buf);
1328 return 0;
1329 }
1330
1331 /* locally configured routes to advertise do not have su_remote */
1332 if (new->peer->su_remote == NULL) {
1333 *reason = bgp_path_selection_local_configured;
1334 return 0;
1335 }
1336 if (exist->peer->su_remote == NULL) {
1337 *reason = bgp_path_selection_local_configured;
1338 return 1;
1339 }
1340
1341 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1342
1343 if (ret == 1) {
1344 *reason = bgp_path_selection_neighbor_ip;
1345 if (debug)
1346 zlog_debug(
1347 "%s: %s loses to %s due to Neighor IP comparison",
1348 pfx_buf, new_buf, exist_buf);
1349 return 0;
1350 }
1351
1352 if (ret == -1) {
1353 *reason = bgp_path_selection_neighbor_ip;
1354 if (debug)
1355 zlog_debug(
1356 "%s: %s wins over %s due to Neighor IP comparison",
1357 pfx_buf, new_buf, exist_buf);
1358 return 1;
1359 }
1360
1361 *reason = bgp_path_selection_default;
1362 if (debug)
1363 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1364 pfx_buf, new_buf, exist_buf);
1365
1366 return 1;
1367}
1368
1369
1370int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1371 struct bgp_path_info *exist, int *paths_eq)
1372{
1373 enum bgp_path_selection_reason reason;
1374 char pfx_buf[PREFIX2STR_BUFFER];
1375
1376 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1377 AFI_L2VPN, SAFI_EVPN, &reason);
1378}
1379
1380/* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1381 * is preferred, or 0 if they are the same (usually will only occur if
1382 * multipath is enabled
1383 * This version is compatible with */
1384int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1385 struct bgp_path_info *exist, char *pfx_buf,
1386 afi_t afi, safi_t safi,
1387 enum bgp_path_selection_reason *reason)
1388{
1389 int paths_eq;
1390 int ret;
1391 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1392 afi, safi, reason);
1393
1394 if (paths_eq)
1395 ret = 0;
1396 else {
1397 if (ret == 1)
1398 ret = -1;
1399 else
1400 ret = 1;
1401 }
1402 return ret;
1403}
1404
1405static enum filter_type bgp_input_filter(struct peer *peer,
1406 const struct prefix *p,
1407 struct attr *attr, afi_t afi,
1408 safi_t safi)
1409{
1410 struct bgp_filter *filter;
1411 enum filter_type ret = FILTER_PERMIT;
1412
1413 filter = &peer->filter[afi][safi];
1414
1415#define FILTER_EXIST_WARN(F, f, filter) \
1416 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1417 zlog_debug("%s: Could not find configured input %s-list %s!", \
1418 peer->host, #f, F##_IN_NAME(filter));
1419
1420 if (DISTRIBUTE_IN_NAME(filter)) {
1421 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1422
1423 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1424 == FILTER_DENY) {
1425 ret = FILTER_DENY;
1426 goto done;
1427 }
1428 }
1429
1430 if (PREFIX_LIST_IN_NAME(filter)) {
1431 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1432
1433 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1434 == PREFIX_DENY) {
1435 ret = FILTER_DENY;
1436 goto done;
1437 }
1438 }
1439
1440 if (FILTER_LIST_IN_NAME(filter)) {
1441 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1442
1443 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1444 == AS_FILTER_DENY) {
1445 ret = FILTER_DENY;
1446 goto done;
1447 }
1448 }
1449
1450done:
1451 if (frrtrace_enabled(frr_bgp, input_filter)) {
1452 char pfxprint[PREFIX2STR_BUFFER];
1453
1454 prefix2str(p, pfxprint, sizeof(pfxprint));
1455 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1456 ret == FILTER_PERMIT ? "permit" : "deny");
1457 }
1458
1459 return ret;
1460#undef FILTER_EXIST_WARN
1461}
1462
1463static enum filter_type bgp_output_filter(struct peer *peer,
1464 const struct prefix *p,
1465 struct attr *attr, afi_t afi,
1466 safi_t safi)
1467{
1468 struct bgp_filter *filter;
1469 enum filter_type ret = FILTER_PERMIT;
1470
1471 filter = &peer->filter[afi][safi];
1472
1473#define FILTER_EXIST_WARN(F, f, filter) \
1474 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1475 zlog_debug("%s: Could not find configured output %s-list %s!", \
1476 peer->host, #f, F##_OUT_NAME(filter));
1477
1478 if (DISTRIBUTE_OUT_NAME(filter)) {
1479 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1480
1481 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1482 == FILTER_DENY) {
1483 ret = FILTER_DENY;
1484 goto done;
1485 }
1486 }
1487
1488 if (PREFIX_LIST_OUT_NAME(filter)) {
1489 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1490
1491 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1492 == PREFIX_DENY) {
1493 ret = FILTER_DENY;
1494 goto done;
1495 }
1496 }
1497
1498 if (FILTER_LIST_OUT_NAME(filter)) {
1499 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1500
1501 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1502 == AS_FILTER_DENY) {
1503 ret = FILTER_DENY;
1504 goto done;
1505 }
1506 }
1507
1508 if (frrtrace_enabled(frr_bgp, output_filter)) {
1509 char pfxprint[PREFIX2STR_BUFFER];
1510
1511 prefix2str(p, pfxprint, sizeof(pfxprint));
1512 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1513 ret == FILTER_PERMIT ? "permit" : "deny");
1514 }
1515
1516done:
1517 return ret;
1518#undef FILTER_EXIST_WARN
1519}
1520
1521/* If community attribute includes no_export then return 1. */
1522static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1523{
1524 if (bgp_attr_get_community(attr)) {
1525 /* NO_ADVERTISE check. */
1526 if (community_include(bgp_attr_get_community(attr),
1527 COMMUNITY_NO_ADVERTISE))
1528 return true;
1529
1530 /* NO_EXPORT check. */
1531 if (peer->sort == BGP_PEER_EBGP &&
1532 community_include(bgp_attr_get_community(attr),
1533 COMMUNITY_NO_EXPORT))
1534 return true;
1535
1536 /* NO_EXPORT_SUBCONFED check. */
1537 if (peer->sort == BGP_PEER_EBGP
1538 || peer->sort == BGP_PEER_CONFED)
1539 if (community_include(bgp_attr_get_community(attr),
1540 COMMUNITY_NO_EXPORT_SUBCONFED))
1541 return true;
1542 }
1543 return false;
1544}
1545
1546/* Route reflection loop check. */
1547static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1548{
1549 struct in_addr cluster_id;
1550 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1551
1552 if (cluster) {
1553 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1554 cluster_id = peer->bgp->cluster_id;
1555 else
1556 cluster_id = peer->bgp->router_id;
1557
1558 if (cluster_loop_check(cluster, cluster_id))
1559 return true;
1560 }
1561 return false;
1562}
1563
1564static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1565{
1566 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1567 if (peer->local_role == ROLE_PROVIDER ||
1568 peer->local_role == ROLE_RS_SERVER)
1569 return true;
1570 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1571 return true;
1572 return false;
1573 }
1574 if (peer->local_role == ROLE_CUSTOMER ||
1575 peer->local_role == ROLE_PEER ||
1576 peer->local_role == ROLE_RS_CLIENT) {
1577 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1578 attr->otc = peer->as;
1579 }
1580 return false;
1581}
1582
1583static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1584{
1585 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1586 if (peer->local_role == ROLE_CUSTOMER ||
1587 peer->local_role == ROLE_RS_CLIENT ||
1588 peer->local_role == ROLE_PEER)
1589 return true;
1590 return false;
1591 }
1592 if (peer->local_role == ROLE_PROVIDER ||
1593 peer->local_role == ROLE_PEER ||
1594 peer->local_role == ROLE_RS_SERVER) {
1595 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1596 attr->otc = peer->bgp->as;
1597 }
1598 return false;
1599}
1600
1601static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1602{
1603 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1604}
1605
1606static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1607 struct attr *attr, afi_t afi, safi_t safi,
1608 const char *rmap_name, mpls_label_t *label,
1609 uint32_t num_labels, struct bgp_dest *dest)
1610{
1611 struct bgp_filter *filter;
1612 struct bgp_path_info rmap_path = { 0 };
1613 struct bgp_path_info_extra extra = { 0 };
1614 route_map_result_t ret;
1615 struct route_map *rmap = NULL;
1616
1617 filter = &peer->filter[afi][safi];
1618
1619 /* Apply default weight value. */
1620 if (peer->weight[afi][safi])
1621 attr->weight = peer->weight[afi][safi];
1622
1623 if (rmap_name) {
1624 rmap = route_map_lookup_by_name(rmap_name);
1625
1626 if (rmap == NULL)
1627 return RMAP_DENY;
1628 } else {
1629 if (ROUTE_MAP_IN_NAME(filter)) {
1630 rmap = ROUTE_MAP_IN(filter);
1631
1632 if (rmap == NULL)
1633 return RMAP_DENY;
1634 }
1635 }
1636
1637 /* Route map apply. */
1638 if (rmap) {
1639 memset(&rmap_path, 0, sizeof(rmap_path));
1640 /* Duplicate current value to new structure for modification. */
1641 rmap_path.peer = peer;
1642 rmap_path.attr = attr;
1643 rmap_path.extra = &extra;
1644 rmap_path.net = dest;
1645
1646 extra.num_labels = num_labels;
1647 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1648 memcpy(extra.label, label,
1649 num_labels * sizeof(mpls_label_t));
1650
1651 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1652
1653 /* Apply BGP route map to the attribute. */
1654 ret = route_map_apply(rmap, p, &rmap_path);
1655
1656 peer->rmap_type = 0;
1657
1658 if (ret == RMAP_DENYMATCH)
1659 return RMAP_DENY;
1660 }
1661 return RMAP_PERMIT;
1662}
1663
1664static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1665 struct attr *attr, afi_t afi, safi_t safi,
1666 const char *rmap_name)
1667{
1668 struct bgp_path_info rmap_path;
1669 route_map_result_t ret;
1670 struct route_map *rmap = NULL;
1671 uint8_t rmap_type;
1672
1673 /*
1674 * So if we get to this point and have no rmap_name
1675 * we want to just show the output as it currently
1676 * exists.
1677 */
1678 if (!rmap_name)
1679 return RMAP_PERMIT;
1680
1681 /* Apply default weight value. */
1682 if (peer->weight[afi][safi])
1683 attr->weight = peer->weight[afi][safi];
1684
1685 rmap = route_map_lookup_by_name(rmap_name);
1686
1687 /*
1688 * If we have a route map name and we do not find
1689 * the routemap that means we have an implicit
1690 * deny.
1691 */
1692 if (rmap == NULL)
1693 return RMAP_DENY;
1694
1695 memset(&rmap_path, 0, sizeof(rmap_path));
1696 /* Route map apply. */
1697 /* Duplicate current value to new structure for modification. */
1698 rmap_path.peer = peer;
1699 rmap_path.attr = attr;
1700
1701 rmap_type = peer->rmap_type;
1702 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1703
1704 /* Apply BGP route map to the attribute. */
1705 ret = route_map_apply(rmap, p, &rmap_path);
1706
1707 peer->rmap_type = rmap_type;
1708
1709 if (ret == RMAP_DENYMATCH)
1710 /*
1711 * caller has multiple error paths with bgp_attr_flush()
1712 */
1713 return RMAP_DENY;
1714
1715 return RMAP_PERMIT;
1716}
1717
1718/* If this is an EBGP peer with remove-private-AS */
1719static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1720 struct peer *peer, struct attr *attr)
1721{
1722 if (peer->sort == BGP_PEER_EBGP
1723 && (peer_af_flag_check(peer, afi, safi,
1724 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1725 || peer_af_flag_check(peer, afi, safi,
1726 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1727 || peer_af_flag_check(peer, afi, safi,
1728 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1729 || peer_af_flag_check(peer, afi, safi,
1730 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1731 // Take action on the entire aspath
1732 if (peer_af_flag_check(peer, afi, safi,
1733 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1734 || peer_af_flag_check(peer, afi, safi,
1735 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1736 if (peer_af_flag_check(
1737 peer, afi, safi,
1738 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1739 attr->aspath = aspath_replace_private_asns(
1740 attr->aspath, bgp->as, peer->as);
1741
1742 /*
1743 * Even if the aspath consists of just private ASNs we
1744 * need to walk the AS-Path to maintain all instances
1745 * of the peer's ASN to break possible loops.
1746 */
1747 else
1748 attr->aspath = aspath_remove_private_asns(
1749 attr->aspath, peer->as);
1750 }
1751
1752 // 'all' was not specified so the entire aspath must be private
1753 // ASNs
1754 // for us to do anything
1755 else if (aspath_private_as_check(attr->aspath)) {
1756 if (peer_af_flag_check(
1757 peer, afi, safi,
1758 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1759 attr->aspath = aspath_replace_private_asns(
1760 attr->aspath, bgp->as, peer->as);
1761 else
1762 /*
1763 * Walk the aspath to retain any instances of
1764 * the peer_asn
1765 */
1766 attr->aspath = aspath_remove_private_asns(
1767 attr->aspath, peer->as);
1768 }
1769 }
1770}
1771
1772/* If this is an EBGP peer with as-override */
1773static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1774 struct peer *peer, struct attr *attr)
1775{
1776 if (peer->sort == BGP_PEER_EBGP &&
1777 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE))
1778 attr->aspath = aspath_replace_specific_asn(attr->aspath,
1779 peer->as, bgp->as);
1780}
1781
1782void bgp_attr_add_llgr_community(struct attr *attr)
1783{
1784 struct community *old;
1785 struct community *new;
1786 struct community *merge;
1787 struct community *llgr;
1788
1789 old = bgp_attr_get_community(attr);
1790 llgr = community_str2com("llgr-stale");
1791
1792 assert(llgr);
1793
1794 if (old) {
1795 merge = community_merge(community_dup(old), llgr);
1796
1797 if (old->refcnt == 0)
1798 community_free(&old);
1799
1800 new = community_uniq_sort(merge);
1801 community_free(&merge);
1802 } else {
1803 new = community_dup(llgr);
1804 }
1805
1806 community_free(&llgr);
1807
1808 bgp_attr_set_community(attr, new);
1809}
1810
1811void bgp_attr_add_gshut_community(struct attr *attr)
1812{
1813 struct community *old;
1814 struct community *new;
1815 struct community *merge;
1816 struct community *gshut;
1817
1818 old = bgp_attr_get_community(attr);
1819 gshut = community_str2com("graceful-shutdown");
1820
1821 assert(gshut);
1822
1823 if (old) {
1824 merge = community_merge(community_dup(old), gshut);
1825
1826 if (old->refcnt == 0)
1827 community_free(&old);
1828
1829 new = community_uniq_sort(merge);
1830 community_free(&merge);
1831 } else {
1832 new = community_dup(gshut);
1833 }
1834
1835 community_free(&gshut);
1836 bgp_attr_set_community(attr, new);
1837
1838 /* When we add the graceful-shutdown community we must also
1839 * lower the local-preference */
1840 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1841 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1842}
1843
1844
1845/* Notify BGP Conditional advertisement scanner process. */
1846void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1847{
1848 struct peer *peer = SUBGRP_PEER(subgrp);
1849 afi_t afi = SUBGRP_AFI(subgrp);
1850 safi_t safi = SUBGRP_SAFI(subgrp);
1851 struct bgp_filter *filter = &peer->filter[afi][safi];
1852
1853 if (!ADVERTISE_MAP_NAME(filter))
1854 return;
1855
1856 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1857 return;
1858
1859 peer->advmap_table_change = true;
1860}
1861
1862
1863void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1864{
1865 if (family == AF_INET) {
1866 attr->nexthop.s_addr = INADDR_ANY;
1867 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1868 }
1869 if (family == AF_INET6)
1870 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1871 if (family == AF_EVPN)
1872 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1873}
1874
1875bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1876 struct update_subgroup *subgrp,
1877 const struct prefix *p, struct attr *attr,
1878 struct attr *post_attr)
1879{
1880 struct bgp_filter *filter;
1881 struct peer *from;
1882 struct peer *peer;
1883 struct peer *onlypeer;
1884 struct bgp *bgp;
1885 struct attr *piattr;
1886 route_map_result_t ret;
1887 int transparent;
1888 int reflect;
1889 afi_t afi;
1890 safi_t safi;
1891 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1892 bool nh_reset = false;
1893 uint64_t cum_bw;
1894
1895 if (DISABLE_BGP_ANNOUNCE)
1896 return false;
1897
1898 afi = SUBGRP_AFI(subgrp);
1899 safi = SUBGRP_SAFI(subgrp);
1900 peer = SUBGRP_PEER(subgrp);
1901 onlypeer = NULL;
1902 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1903 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1904
1905 from = pi->peer;
1906 filter = &peer->filter[afi][safi];
1907 bgp = SUBGRP_INST(subgrp);
1908 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1909 : pi->attr;
1910
1911 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
1912 peer->pmax_out[afi][safi] != 0 &&
1913 subgrp->pscount >= peer->pmax_out[afi][safi]) {
1914 if (BGP_DEBUG(update, UPDATE_OUT) ||
1915 BGP_DEBUG(update, UPDATE_PREFIX)) {
1916 zlog_debug("%s reached maximum prefix to be send (%u)",
1917 peer->host, peer->pmax_out[afi][safi]);
1918 }
1919 return false;
1920 }
1921
1922#ifdef ENABLE_BGP_VNC
1923 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1924 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1925 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1926
1927 /*
1928 * direct and direct_ext type routes originate internally even
1929 * though they can have peer pointers that reference other
1930 * systems
1931 */
1932 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1933 __func__, p);
1934 samepeer_safe = 1;
1935 }
1936#endif
1937
1938 if (((afi == AFI_IP) || (afi == AFI_IP6))
1939 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1940 && (pi->type == ZEBRA_ROUTE_BGP)
1941 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1942
1943 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1944
1945 samepeer_safe = 1;
1946 }
1947
1948 /* With addpath we may be asked to TX all kinds of paths so make sure
1949 * pi is valid */
1950 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1951 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1952 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1953 return false;
1954 }
1955
1956 /* If this is not the bestpath then check to see if there is an enabled
1957 * addpath
1958 * feature that requires us to advertise it */
1959 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1960 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1961 return false;
1962 }
1963 }
1964
1965 /* Aggregate-address suppress check. */
1966 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1967 return false;
1968
1969 /*
1970 * If we are doing VRF 2 VRF leaking via the import
1971 * statement, we want to prevent the route going
1972 * off box as that the RT and RD created are localy
1973 * significant and globaly useless.
1974 */
1975 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1976 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1977 return false;
1978
1979 /* If it's labeled safi, make sure the route has a valid label. */
1980 if (safi == SAFI_LABELED_UNICAST) {
1981 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1982 if (!bgp_is_valid_label(&label)) {
1983 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1984 zlog_debug("u%" PRIu64 ":s%" PRIu64
1985 " %pFX is filtered - no label (%p)",
1986 subgrp->update_group->id, subgrp->id,
1987 p, &label);
1988 return false;
1989 }
1990 }
1991
1992 /* Do not send back route to sender. */
1993 if (onlypeer && from == onlypeer) {
1994 return false;
1995 }
1996
1997 /* Do not send the default route in the BGP table if the neighbor is
1998 * configured for default-originate */
1999 if (CHECK_FLAG(peer->af_flags[afi][safi],
2000 PEER_FLAG_DEFAULT_ORIGINATE)) {
2001 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2002 return false;
2003 else if (p->family == AF_INET6 && p->prefixlen == 0)
2004 return false;
2005 }
2006
2007 /* Transparency check. */
2008 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2009 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2010 transparent = 1;
2011 else
2012 transparent = 0;
2013
2014 /* If community is not disabled check the no-export and local. */
2015 if (!transparent && bgp_community_filter(peer, piattr)) {
2016 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2017 zlog_debug("%s: community filter check fail for %pFX",
2018 __func__, p);
2019 return false;
2020 }
2021
2022 /* If the attribute has originator-id and it is same as remote
2023 peer's id. */
2024 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2025 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2026 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2027 zlog_debug(
2028 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2029 onlypeer, p);
2030 return false;
2031 }
2032
2033 /* ORF prefix-list filter check */
2034 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2035 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2036 || CHECK_FLAG(peer->af_cap[afi][safi],
2037 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2038 if (peer->orf_plist[afi][safi]) {
2039 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2040 == PREFIX_DENY) {
2041 if (bgp_debug_update(NULL, p,
2042 subgrp->update_group, 0))
2043 zlog_debug(
2044 "%pBP [Update:SEND] %pFX is filtered via ORF",
2045 peer, p);
2046 return false;
2047 }
2048 }
2049
2050 /* Output filter check. */
2051 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2052 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2053 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2054 p);
2055 return false;
2056 }
2057
2058 /* AS path loop check. */
2059 if (onlypeer && onlypeer->as_path_loop_detection
2060 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2061 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2062 zlog_debug(
2063 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2064 onlypeer, onlypeer->as);
2065 return false;
2066 }
2067
2068 /* If we're a CONFED we need to loop check the CONFED ID too */
2069 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2070 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
2071 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2072 zlog_debug(
2073 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2074 peer, bgp->confed_id);
2075 return false;
2076 }
2077 }
2078
2079 /* Route-Reflect check. */
2080 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2081 reflect = 1;
2082 else
2083 reflect = 0;
2084
2085 /* IBGP reflection check. */
2086 if (reflect && !samepeer_safe) {
2087 /* A route from a Client peer. */
2088 if (CHECK_FLAG(from->af_flags[afi][safi],
2089 PEER_FLAG_REFLECTOR_CLIENT)) {
2090 /* Reflect to all the Non-Client peers and also to the
2091 Client peers other than the originator. Originator
2092 check
2093 is already done. So there is noting to do. */
2094 /* no bgp client-to-client reflection check. */
2095 if (CHECK_FLAG(bgp->flags,
2096 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2097 if (CHECK_FLAG(peer->af_flags[afi][safi],
2098 PEER_FLAG_REFLECTOR_CLIENT))
2099 return false;
2100 } else {
2101 /* A route from a Non-client peer. Reflect to all other
2102 clients. */
2103 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2104 PEER_FLAG_REFLECTOR_CLIENT))
2105 return false;
2106 }
2107 }
2108
2109 /* For modify attribute, copy it to temporary structure.
2110 * post_attr comes from BGP conditional advertisements, where
2111 * attributes are already processed by advertise-map route-map,
2112 * and this needs to be saved instead of overwriting from the
2113 * path attributes.
2114 */
2115 if (post_attr)
2116 *attr = *post_attr;
2117 else
2118 *attr = *piattr;
2119
2120 /* If local-preference is not set. */
2121 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2122 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2123 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2124 attr->local_pref = bgp->default_local_pref;
2125 }
2126
2127 /* If originator-id is not set and the route is to be reflected,
2128 set the originator id */
2129 if (reflect
2130 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2131 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2132 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2133 }
2134
2135 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2136 */
2137 if (peer->sort == BGP_PEER_EBGP
2138 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2139 if (from != bgp->peer_self && !transparent
2140 && !CHECK_FLAG(peer->af_flags[afi][safi],
2141 PEER_FLAG_MED_UNCHANGED))
2142 attr->flag &=
2143 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2144 }
2145
2146 /* Since the nexthop attribute can vary per peer, it is not explicitly
2147 * set
2148 * in announce check, only certain flags and length (or number of
2149 * nexthops
2150 * -- for IPv6/MP_REACH) are set here in order to guide the update
2151 * formation
2152 * code in setting the nexthop(s) on a per peer basis in
2153 * reformat_peer().
2154 * Typically, the source nexthop in the attribute is preserved but in
2155 * the
2156 * scenarios where we know it will always be overwritten, we reset the
2157 * nexthop to "0" in an attempt to achieve better Update packing. An
2158 * example of this is when a prefix from each of 2 IBGP peers needs to
2159 * be
2160 * announced to an EBGP peer (and they have the same attributes barring
2161 * their nexthop).
2162 */
2163 if (reflect)
2164 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2165
2166#define NEXTHOP_IS_V6 \
2167 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2168 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2169 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2170 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2171
2172 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2173 * if
2174 * the peer (group) is configured to receive link-local nexthop
2175 * unchanged
2176 * and it is available in the prefix OR we're not reflecting the route,
2177 * link-local nexthop address is valid and
2178 * the peer (group) to whom we're going to announce is on a shared
2179 * network
2180 * and this is either a self-originated route or the peer is EBGP.
2181 * By checking if nexthop LL address is valid we are sure that
2182 * we do not announce LL address as `::`.
2183 */
2184 if (NEXTHOP_IS_V6) {
2185 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2186 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2187 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2188 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2189 || (!reflect && !transparent
2190 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2191 && peer->shared_network
2192 && (from == bgp->peer_self
2193 || peer->sort == BGP_PEER_EBGP))) {
2194 attr->mp_nexthop_len =
2195 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2196 }
2197
2198 /* Clear off link-local nexthop in source, whenever it is not
2199 * needed to
2200 * ensure more prefixes share the same attribute for
2201 * announcement.
2202 */
2203 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2204 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2205 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2206 }
2207
2208 if (bgp_check_role_applicability(afi, safi) &&
2209 bgp_otc_egress(peer, attr))
2210 return false;
2211
2212 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2213 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2214
2215 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2216 filter->advmap.aname &&
2217 route_map_lookup_by_name(filter->advmap.aname)) {
2218 struct bgp_path_info rmap_path = {0};
2219 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2220 struct attr dummy_attr = *attr;
2221
2222 /* Fill temp path_info */
2223 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2224 pi, peer, &dummy_attr);
2225
2226 struct route_map *amap =
2227 route_map_lookup_by_name(filter->advmap.aname);
2228
2229 ret = route_map_apply(amap, p, &rmap_path);
2230
2231 bgp_attr_flush(&dummy_attr);
2232
2233 /*
2234 * The conditional advertisement mode is Withdraw and this
2235 * prefix is a conditional prefix. Don't advertise it
2236 */
2237 if (ret == RMAP_PERMITMATCH)
2238 return false;
2239 }
2240
2241 /* Route map & unsuppress-map apply. */
2242 if (!post_attr &&
2243 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2244 struct bgp_path_info rmap_path = {0};
2245 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2246 struct attr dummy_attr = {0};
2247
2248 /* Fill temp path_info */
2249 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2250 pi, peer, attr);
2251
2252 /* don't confuse inbound and outbound setting */
2253 RESET_FLAG(attr->rmap_change_flags);
2254
2255 /*
2256 * The route reflector is not allowed to modify the attributes
2257 * of the reflected IBGP routes unless explicitly allowed.
2258 */
2259 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2260 && !CHECK_FLAG(bgp->flags,
2261 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2262 dummy_attr = *attr;
2263 rmap_path.attr = &dummy_attr;
2264 }
2265
2266 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2267
2268 if (bgp_path_suppressed(pi))
2269 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2270 &rmap_path);
2271 else
2272 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2273 &rmap_path);
2274
2275 bgp_attr_flush(&dummy_attr);
2276 peer->rmap_type = 0;
2277
2278 if (ret == RMAP_DENYMATCH) {
2279 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2280 zlog_debug(
2281 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2282 peer, p, ROUTE_MAP_OUT_NAME(filter));
2283 bgp_attr_flush(rmap_path.attr);
2284 return false;
2285 }
2286 }
2287
2288 /* RFC 8212 to prevent route leaks.
2289 * This specification intends to improve this situation by requiring the
2290 * explicit configuration of both BGP Import and Export Policies for any
2291 * External BGP (EBGP) session such as customers, peers, or
2292 * confederation boundaries for all enabled address families. Through
2293 * codification of the aforementioned requirement, operators will
2294 * benefit from consistent behavior across different BGP
2295 * implementations.
2296 */
2297 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2298 if (!bgp_outbound_policy_exists(peer, filter)) {
2299 if (monotime_since(&bgp->ebgprequirespolicywarning,
2300 NULL) > FIFTEENMINUTE2USEC ||
2301 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2302 zlog_warn(
2303 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2304 monotime(&bgp->ebgprequirespolicywarning);
2305 }
2306 return false;
2307 }
2308
2309 /* draft-ietf-idr-deprecate-as-set-confed-set
2310 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2311 * Eventually, This document (if approved) updates RFC 4271
2312 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2313 * and obsoletes RFC 6472.
2314 */
2315 if (peer->bgp->reject_as_sets)
2316 if (aspath_check_as_sets(attr->aspath))
2317 return false;
2318
2319 /* If neighbor sso is configured, then check if the route has
2320 * SoO extended community and validate against the configured
2321 * one. If they match, do not announce, to prevent routing
2322 * loops.
2323 */
2324 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2325 peer->soo[afi][safi]) {
2326 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2327 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2328
2329 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2330 ECOMMUNITY_SITE_ORIGIN) ||
2331 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2332 ECOMMUNITY_SITE_ORIGIN)) &&
2333 ecommunity_include(ecomm, ecomm_soo)) {
2334 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2335 zlog_debug(
2336 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2337 peer, p, ecommunity_str(ecomm_soo));
2338 return false;
2339 }
2340 }
2341
2342 /* Codification of AS 0 Processing */
2343 if (aspath_check_as_zero(attr->aspath))
2344 return false;
2345
2346 if (bgp_in_graceful_shutdown(bgp)) {
2347 if (peer->sort == BGP_PEER_IBGP
2348 || peer->sort == BGP_PEER_CONFED) {
2349 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2350 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2351 } else {
2352 bgp_attr_add_gshut_community(attr);
2353 }
2354 }
2355
2356 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2357 * Capability" to a neighbor MUST perform the following upon receiving
2358 * a route from that neighbor with the "LLGR_STALE" community, or upon
2359 * attaching the "LLGR_STALE" community itself per Section 4.2:
2360 *
2361 * The route SHOULD NOT be advertised to any neighbor from which the
2362 * Long-lived Graceful Restart Capability has not been received.
2363 */
2364 if (bgp_attr_get_community(attr) &&
2365 community_include(bgp_attr_get_community(attr),
2366 COMMUNITY_LLGR_STALE) &&
2367 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2368 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2369 return false;
2370
2371 /* After route-map has been applied, we check to see if the nexthop to
2372 * be carried in the attribute (that is used for the announcement) can
2373 * be cleared off or not. We do this in all cases where we would be
2374 * setting the nexthop to "ourselves". For IPv6, we only need to
2375 * consider
2376 * the global nexthop here; the link-local nexthop would have been
2377 * cleared
2378 * already, and if not, it is required by the update formation code.
2379 * Also see earlier comments in this function.
2380 */
2381 /*
2382 * If route-map has performed some operation on the nexthop or the peer
2383 * configuration says to pass it unchanged, we cannot reset the nexthop
2384 * here, so only attempt to do it if these aren't true. Note that the
2385 * route-map handler itself might have cleared the nexthop, if for
2386 * example,
2387 * it is configured as 'peer-address'.
2388 */
2389 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2390 piattr->rmap_change_flags)
2391 && !transparent
2392 && !CHECK_FLAG(peer->af_flags[afi][safi],
2393 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2394 /* We can reset the nexthop, if setting (or forcing) it to
2395 * 'self' */
2396 if (CHECK_FLAG(peer->af_flags[afi][safi],
2397 PEER_FLAG_NEXTHOP_SELF)
2398 || CHECK_FLAG(peer->af_flags[afi][safi],
2399 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2400 if (!reflect
2401 || CHECK_FLAG(peer->af_flags[afi][safi],
2402 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2403 subgroup_announce_reset_nhop(
2404 (peer_cap_enhe(peer, afi, safi)
2405 ? AF_INET6
2406 : p->family),
2407 attr);
2408 nh_reset = true;
2409 }
2410 } else if (peer->sort == BGP_PEER_EBGP) {
2411 /* Can also reset the nexthop if announcing to EBGP, but
2412 * only if
2413 * no peer in the subgroup is on a shared subnet.
2414 * Note: 3rd party nexthop currently implemented for
2415 * IPv4 only.
2416 */
2417 if ((p->family == AF_INET) &&
2418 (!bgp_subgrp_multiaccess_check_v4(
2419 piattr->nexthop,
2420 subgrp, from))) {
2421 subgroup_announce_reset_nhop(
2422 (peer_cap_enhe(peer, afi, safi)
2423 ? AF_INET6
2424 : p->family),
2425 attr);
2426 nh_reset = true;
2427 }
2428
2429 if ((p->family == AF_INET6) &&
2430 (!bgp_subgrp_multiaccess_check_v6(
2431 piattr->mp_nexthop_global,
2432 subgrp, from))) {
2433 subgroup_announce_reset_nhop(
2434 (peer_cap_enhe(peer, afi, safi)
2435 ? AF_INET6
2436 : p->family),
2437 attr);
2438 nh_reset = true;
2439 }
2440
2441
2442
2443 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2444 /*
2445 * This flag is used for leaked vpn-vrf routes
2446 */
2447 int family = p->family;
2448
2449 if (peer_cap_enhe(peer, afi, safi))
2450 family = AF_INET6;
2451
2452 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2453 zlog_debug(
2454 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2455 __func__, family2str(family));
2456 subgroup_announce_reset_nhop(family, attr);
2457 nh_reset = true;
2458 }
2459 }
2460
2461 /* If IPv6/MP and nexthop does not have any override and happens
2462 * to
2463 * be a link-local address, reset it so that we don't pass along
2464 * the
2465 * source's link-local IPv6 address to recipients who may not be
2466 * on
2467 * the same interface.
2468 */
2469 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2470 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2471 subgroup_announce_reset_nhop(AF_INET6, attr);
2472 nh_reset = true;
2473 }
2474 }
2475
2476 /*
2477 * When the next hop is set to ourselves, if all multipaths have
2478 * link-bandwidth announce the cumulative bandwidth as that makes
2479 * the most sense. However, don't modify if the link-bandwidth has
2480 * been explicitly set by user policy.
2481 */
2482 if (nh_reset &&
2483 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2484 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2485 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2486 bgp_attr_set_ecommunity(
2487 attr,
2488 ecommunity_replace_linkbw(
2489 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2490 CHECK_FLAG(
2491 peer->flags,
2492 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2493
2494 return true;
2495}
2496
2497static void bgp_route_select_timer_expire(struct thread *thread)
2498{
2499 struct afi_safi_info *info;
2500 afi_t afi;
2501 safi_t safi;
2502 struct bgp *bgp;
2503
2504 info = THREAD_ARG(thread);
2505 afi = info->afi;
2506 safi = info->safi;
2507 bgp = info->bgp;
2508
2509 if (BGP_DEBUG(update, UPDATE_OUT))
2510 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2511 safi);
2512
2513 bgp->gr_info[afi][safi].t_route_select = NULL;
2514
2515 XFREE(MTYPE_TMP, info);
2516
2517 /* Best path selection */
2518 bgp_best_path_select_defer(bgp, afi, safi);
2519}
2520
2521void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2522 struct bgp_maxpaths_cfg *mpath_cfg,
2523 struct bgp_path_info_pair *result, afi_t afi,
2524 safi_t safi)
2525{
2526 struct bgp_path_info *new_select;
2527 struct bgp_path_info *old_select;
2528 struct bgp_path_info *pi;
2529 struct bgp_path_info *pi1;
2530 struct bgp_path_info *pi2;
2531 struct bgp_path_info *nextpi = NULL;
2532 int paths_eq, do_mpath, debug;
2533 struct list mp_list;
2534 char pfx_buf[PREFIX2STR_BUFFER];
2535 char path_buf[PATH_ADDPATH_STR_BUFFER];
2536
2537 bgp_mp_list_init(&mp_list);
2538 do_mpath =
2539 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2540
2541 debug = bgp_debug_bestpath(dest);
2542
2543 if (debug)
2544 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2545
2546 dest->reason = bgp_path_selection_none;
2547 /* bgp deterministic-med */
2548 new_select = NULL;
2549 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2550
2551 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2552 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2553 pi1 = pi1->next)
2554 bgp_path_info_unset_flag(dest, pi1,
2555 BGP_PATH_DMED_SELECTED);
2556
2557 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2558 pi1 = pi1->next) {
2559 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2560 continue;
2561 if (BGP_PATH_HOLDDOWN(pi1))
2562 continue;
2563 if (pi1->peer != bgp->peer_self)
2564 if (!peer_established(pi1->peer))
2565 continue;
2566
2567 new_select = pi1;
2568 if (pi1->next) {
2569 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2570 if (CHECK_FLAG(pi2->flags,
2571 BGP_PATH_DMED_CHECK))
2572 continue;
2573 if (BGP_PATH_HOLDDOWN(pi2))
2574 continue;
2575 if (pi2->peer != bgp->peer_self
2576 && !CHECK_FLAG(
2577 pi2->peer->sflags,
2578 PEER_STATUS_NSF_WAIT))
2579 if (pi2->peer->status
2580 != Established)
2581 continue;
2582
2583 if (!aspath_cmp_left(pi1->attr->aspath,
2584 pi2->attr->aspath)
2585 && !aspath_cmp_left_confed(
2586 pi1->attr->aspath,
2587 pi2->attr->aspath))
2588 continue;
2589
2590 if (bgp_path_info_cmp(
2591 bgp, pi2, new_select,
2592 &paths_eq, mpath_cfg, debug,
2593 pfx_buf, afi, safi,
2594 &dest->reason)) {
2595 bgp_path_info_unset_flag(
2596 dest, new_select,
2597 BGP_PATH_DMED_SELECTED);
2598 new_select = pi2;
2599 }
2600
2601 bgp_path_info_set_flag(
2602 dest, pi2, BGP_PATH_DMED_CHECK);
2603 }
2604 }
2605 bgp_path_info_set_flag(dest, new_select,
2606 BGP_PATH_DMED_CHECK);
2607 bgp_path_info_set_flag(dest, new_select,
2608 BGP_PATH_DMED_SELECTED);
2609
2610 if (debug) {
2611 bgp_path_info_path_with_addpath_rx_str(
2612 new_select, path_buf, sizeof(path_buf));
2613 zlog_debug(
2614 "%pBD(%s): %s is the bestpath from AS %u",
2615 dest, bgp->name_pretty, path_buf,
2616 aspath_get_first_as(
2617 new_select->attr->aspath));
2618 }
2619 }
2620 }
2621
2622 /* Check old selected route and new selected route. */
2623 old_select = NULL;
2624 new_select = NULL;
2625 for (pi = bgp_dest_get_bgp_path_info(dest);
2626 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2627 enum bgp_path_selection_reason reason;
2628
2629 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2630 old_select = pi;
2631
2632 if (BGP_PATH_HOLDDOWN(pi)) {
2633 /* reap REMOVED routes, if needs be
2634 * selected route must stay for a while longer though
2635 */
2636 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2637 && (pi != old_select))
2638 bgp_path_info_reap(dest, pi);
2639
2640 if (debug)
2641 zlog_debug("%s: pi %p in holddown", __func__,
2642 pi);
2643
2644 continue;
2645 }
2646
2647 if (pi->peer && pi->peer != bgp->peer_self
2648 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2649 if (!peer_established(pi->peer)) {
2650
2651 if (debug)
2652 zlog_debug(
2653 "%s: pi %p non self peer %s not estab state",
2654 __func__, pi, pi->peer->host);
2655
2656 continue;
2657 }
2658
2659 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2660 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2661 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2662 if (debug)
2663 zlog_debug("%s: pi %p dmed", __func__, pi);
2664 continue;
2665 }
2666
2667 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2668
2669 reason = dest->reason;
2670 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2671 debug, pfx_buf, afi, safi,
2672 &dest->reason)) {
2673 if (new_select == NULL &&
2674 reason != bgp_path_selection_none)
2675 dest->reason = reason;
2676 new_select = pi;
2677 }
2678 }
2679
2680 /* Now that we know which path is the bestpath see if any of the other
2681 * paths
2682 * qualify as multipaths
2683 */
2684 if (debug) {
2685 if (new_select)
2686 bgp_path_info_path_with_addpath_rx_str(
2687 new_select, path_buf, sizeof(path_buf));
2688 else
2689 snprintf(path_buf, sizeof(path_buf), "NONE");
2690 zlog_debug(
2691 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2692 dest, bgp->name_pretty, path_buf,
2693 old_select ? old_select->peer->host : "NONE");
2694 }
2695
2696 if (do_mpath && new_select) {
2697 for (pi = bgp_dest_get_bgp_path_info(dest);
2698 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2699
2700 if (debug)
2701 bgp_path_info_path_with_addpath_rx_str(
2702 pi, path_buf, sizeof(path_buf));
2703
2704 if (pi == new_select) {
2705 if (debug)
2706 zlog_debug(
2707 "%pBD(%s): %s is the bestpath, add to the multipath list",
2708 dest, bgp->name_pretty,
2709 path_buf);
2710 bgp_mp_list_add(&mp_list, pi);
2711 continue;
2712 }
2713
2714 if (BGP_PATH_HOLDDOWN(pi))
2715 continue;
2716
2717 if (pi->peer && pi->peer != bgp->peer_self
2718 && !CHECK_FLAG(pi->peer->sflags,
2719 PEER_STATUS_NSF_WAIT))
2720 if (!peer_established(pi->peer))
2721 continue;
2722
2723 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2724 if (debug)
2725 zlog_debug(
2726 "%pBD: %s has the same nexthop as the bestpath, skip it",
2727 dest, path_buf);
2728 continue;
2729 }
2730
2731 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2732 mpath_cfg, debug, pfx_buf, afi, safi,
2733 &dest->reason);
2734
2735 if (paths_eq) {
2736 if (debug)
2737 zlog_debug(
2738 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2739 dest, path_buf);
2740 bgp_mp_list_add(&mp_list, pi);
2741 }
2742 }
2743 }
2744
2745 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2746 mpath_cfg);
2747 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2748 bgp_mp_list_clear(&mp_list);
2749
2750 bgp_addpath_update_ids(bgp, dest, afi, safi);
2751
2752 result->old = old_select;
2753 result->new = new_select;
2754
2755 return;
2756}
2757
2758/*
2759 * A new route/change in bestpath of an existing route. Evaluate the path
2760 * for advertisement to the subgroup.
2761 */
2762void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2763 struct bgp_path_info *selected,
2764 struct bgp_dest *dest,
2765 uint32_t addpath_tx_id)
2766{
2767 const struct prefix *p;
2768 struct peer *onlypeer;
2769 struct attr attr;
2770 afi_t afi;
2771 safi_t safi;
2772 struct bgp *bgp;
2773 bool advertise;
2774
2775 p = bgp_dest_get_prefix(dest);
2776 afi = SUBGRP_AFI(subgrp);
2777 safi = SUBGRP_SAFI(subgrp);
2778 bgp = SUBGRP_INST(subgrp);
2779 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2780 : NULL);
2781
2782 if (BGP_DEBUG(update, UPDATE_OUT))
2783 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2784
2785 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2786 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2787 PEER_STATUS_ORF_WAIT_REFRESH))
2788 return;
2789
2790 memset(&attr, 0, sizeof(attr));
2791 /* It's initialized in bgp_announce_check() */
2792
2793 /* Announcement to the subgroup. If the route is filtered withdraw it.
2794 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2795 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2796 * route
2797 */
2798 advertise = bgp_check_advertise(bgp, dest);
2799
2800 if (selected) {
2801 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2802 NULL)) {
2803 /* Route is selected, if the route is already installed
2804 * in FIB, then it is advertised
2805 */
2806 if (advertise) {
2807 if (!bgp_check_withdrawal(bgp, dest))
2808 bgp_adj_out_set_subgroup(
2809 dest, subgrp, &attr, selected);
2810 else
2811 bgp_adj_out_unset_subgroup(
2812 dest, subgrp, 1, addpath_tx_id);
2813 }
2814 } else
2815 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2816 addpath_tx_id);
2817 }
2818
2819 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2820 else {
2821 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2822 }
2823}
2824
2825/*
2826 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2827 * This is called at the end of route processing.
2828 */
2829void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2830{
2831 struct bgp_path_info *pi;
2832
2833 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2834 if (BGP_PATH_HOLDDOWN(pi))
2835 continue;
2836 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2837 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2838 }
2839}
2840
2841/*
2842 * Has the route changed from the RIB's perspective? This is invoked only
2843 * if the route selection returns the same best route as earlier - to
2844 * determine if we need to update zebra or not.
2845 */
2846bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2847{
2848 struct bgp_path_info *mpinfo;
2849
2850 /* If this is multipath, check all selected paths for any nexthop
2851 * change or attribute change. Some attribute changes (e.g., community)
2852 * aren't of relevance to the RIB, but we'll update zebra to ensure
2853 * we handle the case of BGP nexthop change. This is the behavior
2854 * when the best path has an attribute change anyway.
2855 */
2856 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2857 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2858 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2859 return true;
2860
2861 /*
2862 * If this is multipath, check all selected paths for any nexthop change
2863 */
2864 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2865 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2866 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2867 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2868 return true;
2869 }
2870
2871 /* Nothing has changed from the RIB's perspective. */
2872 return false;
2873}
2874
2875struct bgp_process_queue {
2876 struct bgp *bgp;
2877 STAILQ_HEAD(, bgp_dest) pqueue;
2878#define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2879 unsigned int flags;
2880 unsigned int queued;
2881};
2882
2883static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2884 safi_t safi, struct bgp_dest *dest,
2885 struct bgp_path_info *new_select,
2886 struct bgp_path_info *old_select)
2887{
2888 const struct prefix *p = bgp_dest_get_prefix(dest);
2889
2890 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2891 return;
2892
2893 if (advertise_type5_routes(bgp, afi) && new_select
2894 && is_route_injectable_into_evpn(new_select)) {
2895
2896 /* apply the route-map */
2897 if (bgp->adv_cmd_rmap[afi][safi].map) {
2898 route_map_result_t ret;
2899 struct bgp_path_info rmap_path;
2900 struct bgp_path_info_extra rmap_path_extra;
2901 struct attr dummy_attr;
2902
2903 dummy_attr = *new_select->attr;
2904
2905 /* Fill temp path_info */
2906 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2907 new_select, new_select->peer,
2908 &dummy_attr);
2909
2910 RESET_FLAG(dummy_attr.rmap_change_flags);
2911
2912 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2913 p, &rmap_path);
2914
2915 if (ret == RMAP_DENYMATCH) {
2916 bgp_attr_flush(&dummy_attr);
2917 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2918 safi);
2919 } else
2920 bgp_evpn_advertise_type5_route(
2921 bgp, p, &dummy_attr, afi, safi);
2922 } else {
2923 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2924 afi, safi);
2925 }
2926 } else if (advertise_type5_routes(bgp, afi) && old_select
2927 && is_route_injectable_into_evpn(old_select))
2928 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2929}
2930
2931/*
2932 * Utility to determine whether a particular path_info should use
2933 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
2934 * in a path where we basically _know_ this is a BGP-LU route.
2935 */
2936static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
2937{
2938 /* Certain types get imp null; so do paths where the nexthop is
2939 * not labeled.
2940 */
2941 if (new_select->sub_type == BGP_ROUTE_STATIC
2942 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2943 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
2944 return true;
2945 else if (new_select->extra == NULL ||
2946 !bgp_is_valid_label(&new_select->extra->label[0]))
2947 /* TODO -- should be configurable? */
2948 return true;
2949 else
2950 return false;
2951}
2952
2953/*
2954 * old_select = The old best path
2955 * new_select = the new best path
2956 *
2957 * if (!old_select && new_select)
2958 * We are sending new information on.
2959 *
2960 * if (old_select && new_select) {
2961 * if (new_select != old_select)
2962 * We have a new best path send a change
2963 * else
2964 * We've received a update with new attributes that needs
2965 * to be passed on.
2966 * }
2967 *
2968 * if (old_select && !new_select)
2969 * We have no eligible route that we can announce or the rn
2970 * is being removed.
2971 */
2972static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2973 afi_t afi, safi_t safi)
2974{
2975 struct bgp_path_info *new_select;
2976 struct bgp_path_info *old_select;
2977 struct bgp_path_info_pair old_and_new;
2978 int debug = 0;
2979
2980 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2981 if (dest)
2982 debug = bgp_debug_bestpath(dest);
2983 if (debug)
2984 zlog_debug(
2985 "%s: bgp delete in progress, ignoring event, p=%pBD",
2986 __func__, dest);
2987 return;
2988 }
2989 /* Is it end of initial update? (after startup) */
2990 if (!dest) {
2991 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
2992 sizeof(bgp->update_delay_zebra_resume_time));
2993
2994 bgp->main_zebra_update_hold = 0;
2995 FOREACH_AFI_SAFI (afi, safi) {
2996 if (bgp_fibupd_safi(safi))
2997 bgp_zebra_announce_table(bgp, afi, safi);
2998 }
2999 bgp->main_peers_update_hold = 0;
3000
3001 bgp_start_routeadv(bgp);
3002 return;
3003 }
3004
3005 const struct prefix *p = bgp_dest_get_prefix(dest);
3006
3007 debug = bgp_debug_bestpath(dest);
3008 if (debug)
3009 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3010 dest, bgp->name_pretty, afi2str(afi),
3011 safi2str(safi));
3012
3013 /* The best path calculation for the route is deferred if
3014 * BGP_NODE_SELECT_DEFER is set
3015 */
3016 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3017 if (BGP_DEBUG(update, UPDATE_OUT))
3018 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3019 return;
3020 }
3021
3022 /* Best path selection. */
3023 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3024 afi, safi);
3025 old_select = old_and_new.old;
3026 new_select = old_and_new.new;
3027
3028 /* Do we need to allocate or free labels?
3029 * Right now, since we only deal with per-prefix labels, it is not
3030 * necessary to do this upon changes to best path. Exceptions:
3031 * - label index has changed -> recalculate resulting label
3032 * - path_info sub_type changed -> switch to/from implicit-null
3033 * - no valid label (due to removed static label binding) -> get new one
3034 */
3035 if (bgp->allocate_mpls_labels[afi][safi]) {
3036 if (new_select) {
3037 if (!old_select
3038 || bgp_label_index_differs(new_select, old_select)
3039 || new_select->sub_type != old_select->sub_type
3040 || !bgp_is_valid_label(&dest->local_label)) {
3041 /* Enforced penultimate hop popping:
3042 * implicit-null for local routes, aggregate
3043 * and redistributed routes
3044 */
3045 if (bgp_lu_need_imp_null(new_select)) {
3046 if (CHECK_FLAG(
3047 dest->flags,
3048 BGP_NODE_REGISTERED_FOR_LABEL)
3049 || CHECK_FLAG(
3050 dest->flags,
3051 BGP_NODE_LABEL_REQUESTED))
3052 bgp_unregister_for_label(dest);
3053 dest->local_label = mpls_lse_encode(
3054 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3055 1);
3056 bgp_set_valid_label(&dest->local_label);
3057 } else
3058 bgp_register_for_label(dest,
3059 new_select);
3060 }
3061 } else if (CHECK_FLAG(dest->flags,
3062 BGP_NODE_REGISTERED_FOR_LABEL)
3063 || CHECK_FLAG(dest->flags,
3064 BGP_NODE_LABEL_REQUESTED)) {
3065 bgp_unregister_for_label(dest);
3066 }
3067 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3068 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3069 bgp_unregister_for_label(dest);
3070 }
3071
3072 if (debug)
3073 zlog_debug(
3074 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3075 __func__, dest, bgp->name_pretty, afi2str(afi),
3076 safi2str(safi), old_select, new_select);
3077
3078 /* If best route remains the same and this is not due to user-initiated
3079 * clear, see exactly what needs to be done.
3080 */
3081 if (old_select && old_select == new_select
3082 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3083 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3084 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3085 if (bgp_zebra_has_route_changed(old_select)) {
3086#ifdef ENABLE_BGP_VNC
3087 vnc_import_bgp_add_route(bgp, p, old_select);
3088 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3089#endif
3090 if (bgp_fibupd_safi(safi)
3091 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3092
3093 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3094 && new_select->sub_type == BGP_ROUTE_NORMAL)
3095 SET_FLAG(dest->flags,
3096 BGP_NODE_FIB_INSTALL_PENDING);
3097
3098 if (new_select->type == ZEBRA_ROUTE_BGP
3099 && (new_select->sub_type == BGP_ROUTE_NORMAL
3100 || new_select->sub_type
3101 == BGP_ROUTE_IMPORTED))
3102
3103 bgp_zebra_announce(dest, p, old_select,
3104 bgp, afi, safi);
3105 }
3106 }
3107
3108 /* If there is a change of interest to peers, reannounce the
3109 * route. */
3110 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3111 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3112 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3113 group_announce_route(bgp, afi, safi, dest, new_select);
3114
3115 /* unicast routes must also be annouced to
3116 * labeled-unicast update-groups */
3117 if (safi == SAFI_UNICAST)
3118 group_announce_route(bgp, afi,
3119 SAFI_LABELED_UNICAST, dest,
3120 new_select);
3121
3122 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3123 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3124 }
3125
3126 /* advertise/withdraw type-5 routes */
3127 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3128 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3129 bgp_process_evpn_route_injection(
3130 bgp, afi, safi, dest, old_select, old_select);
3131
3132 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3133 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3134 bgp_zebra_clear_route_change_flags(dest);
3135 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3136 return;
3137 }
3138
3139 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3140 */
3141 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3142
3143 /* bestpath has changed; bump version */
3144 if (old_select || new_select) {
3145 bgp_bump_version(dest);
3146
3147 if (!bgp->t_rmap_def_originate_eval) {
3148 bgp_lock(bgp);
3149 thread_add_timer(
3150 bm->master,
3151 update_group_refresh_default_originate_route_map,
3152 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3153 &bgp->t_rmap_def_originate_eval);
3154 }
3155 }
3156
3157 if (old_select)
3158 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3159 if (new_select) {
3160 if (debug)
3161 zlog_debug("%s: setting SELECTED flag", __func__);
3162 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3163 bgp_path_info_unset_flag(dest, new_select,
3164 BGP_PATH_ATTR_CHANGED);
3165 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3166 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3167 }
3168
3169#ifdef ENABLE_BGP_VNC
3170 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3171 if (old_select != new_select) {
3172 if (old_select) {
3173 vnc_import_bgp_exterior_del_route(bgp, p,
3174 old_select);
3175 vnc_import_bgp_del_route(bgp, p, old_select);
3176 }
3177 if (new_select) {
3178 vnc_import_bgp_exterior_add_route(bgp, p,
3179 new_select);
3180 vnc_import_bgp_add_route(bgp, p, new_select);
3181 }
3182 }
3183 }
3184#endif
3185
3186 group_announce_route(bgp, afi, safi, dest, new_select);
3187
3188 /* unicast routes must also be annouced to labeled-unicast update-groups
3189 */
3190 if (safi == SAFI_UNICAST)
3191 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3192 new_select);
3193
3194 /* FIB update. */
3195 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3196 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3197
3198 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3199 && (new_select->sub_type == BGP_ROUTE_NORMAL
3200 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3201 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3202
3203 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3204 SET_FLAG(dest->flags,
3205 BGP_NODE_FIB_INSTALL_PENDING);
3206
3207 /* if this is an evpn imported type-5 prefix,
3208 * we need to withdraw the route first to clear
3209 * the nh neigh and the RMAC entry.
3210 */
3211 if (old_select &&
3212 is_route_parent_evpn(old_select))
3213 bgp_zebra_withdraw(p, old_select, bgp, safi);
3214
3215 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3216 } else {
3217 /* Withdraw the route from the kernel. */
3218 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3219 && (old_select->sub_type == BGP_ROUTE_NORMAL
3220 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3221 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3222
3223 bgp_zebra_withdraw(p, old_select, bgp, safi);
3224 }
3225 }
3226
3227 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3228 old_select);
3229
3230 /* Clear any route change flags. */
3231 bgp_zebra_clear_route_change_flags(dest);
3232
3233 /* Reap old select bgp_path_info, if it has been removed */
3234 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3235 bgp_path_info_reap(dest, old_select);
3236
3237 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3238 return;
3239}
3240
3241/* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3242void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3243{
3244 struct bgp_dest *dest;
3245 int cnt = 0;
3246 struct afi_safi_info *thread_info;
3247
3248 if (bgp->gr_info[afi][safi].t_route_select) {
3249 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3250
3251 thread_info = THREAD_ARG(t);
3252 XFREE(MTYPE_TMP, thread_info);
3253 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3254 }
3255
3256 if (BGP_DEBUG(update, UPDATE_OUT)) {
3257 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3258 get_afi_safi_str(afi, safi, false),
3259 bgp->gr_info[afi][safi].gr_deferred);
3260 }
3261
3262 /* Process the route list */
3263 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3264 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3265 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3266 dest = bgp_route_next(dest)) {
3267 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3268 continue;
3269
3270 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3271 bgp->gr_info[afi][safi].gr_deferred--;
3272 bgp_process_main_one(bgp, dest, afi, safi);
3273 cnt++;
3274 }
3275 /* If iteration stopped before the entire table was traversed then the
3276 * node needs to be unlocked.
3277 */
3278 if (dest) {
3279 bgp_dest_unlock_node(dest);
3280 dest = NULL;
3281 }
3282
3283 /* Send EOR message when all routes are processed */
3284 if (!bgp->gr_info[afi][safi].gr_deferred) {
3285 bgp_send_delayed_eor(bgp);
3286 /* Send route processing complete message to RIB */
3287 bgp_zebra_update(afi, safi, bgp->vrf_id,
3288 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3289 return;
3290 }
3291
3292 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3293
3294 thread_info->afi = afi;
3295 thread_info->safi = safi;
3296 thread_info->bgp = bgp;
3297
3298 /* If there are more routes to be processed, start the
3299 * selection timer
3300 */
3301 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3302 BGP_ROUTE_SELECT_DELAY,
3303 &bgp->gr_info[afi][safi].t_route_select);
3304}
3305
3306static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3307{
3308 struct bgp_process_queue *pqnode = data;
3309 struct bgp *bgp = pqnode->bgp;
3310 struct bgp_table *table;
3311 struct bgp_dest *dest;
3312
3313 /* eoiu marker */
3314 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3315 bgp_process_main_one(bgp, NULL, 0, 0);
3316 /* should always have dedicated wq call */
3317 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3318 return WQ_SUCCESS;
3319 }
3320
3321 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3322 dest = STAILQ_FIRST(&pqnode->pqueue);
3323 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3324 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3325 table = bgp_dest_table(dest);
3326 /* note, new DESTs may be added as part of processing */
3327 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3328
3329 bgp_dest_unlock_node(dest);
3330 bgp_table_unlock(table);
3331 }
3332
3333 return WQ_SUCCESS;
3334}
3335
3336static void bgp_processq_del(struct work_queue *wq, void *data)
3337{
3338 struct bgp_process_queue *pqnode = data;
3339
3340 bgp_unlock(pqnode->bgp);
3341
3342 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3343}
3344
3345void bgp_process_queue_init(struct bgp *bgp)
3346{
3347 if (!bgp->process_queue) {
3348 char name[BUFSIZ];
3349
3350 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3351 bgp->process_queue = work_queue_new(bm->master, name);
3352 }
3353
3354 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3355 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3356 bgp->process_queue->spec.max_retries = 0;
3357 bgp->process_queue->spec.hold = 50;
3358 /* Use a higher yield value of 50ms for main queue processing */
3359 bgp->process_queue->spec.yield = 50 * 1000L;
3360}
3361
3362static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3363{
3364 struct bgp_process_queue *pqnode;
3365
3366 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3367 sizeof(struct bgp_process_queue));
3368
3369 /* unlocked in bgp_processq_del */
3370 pqnode->bgp = bgp_lock(bgp);
3371 STAILQ_INIT(&pqnode->pqueue);
3372
3373 return pqnode;
3374}
3375
3376void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3377{
3378#define ARBITRARY_PROCESS_QLEN 10000
3379 struct work_queue *wq = bgp->process_queue;
3380 struct bgp_process_queue *pqnode;
3381 int pqnode_reuse = 0;
3382
3383 /* already scheduled for processing? */
3384 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3385 return;
3386
3387 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3388 * the workqueue
3389 */
3390 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3391 if (BGP_DEBUG(update, UPDATE_OUT))
3392 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3393 dest);
3394 return;
3395 }
3396
3397 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3398 if (BGP_DEBUG(update, UPDATE_OUT))
3399 zlog_debug(
3400 "Soft reconfigure table in progress for route %p",
3401 dest);
3402 return;
3403 }
3404
3405 if (wq == NULL)
3406 return;
3407
3408 /* Add route nodes to an existing work queue item until reaching the
3409 limit only if is from the same BGP view and it's not an EOIU marker
3410 */
3411 if (work_queue_item_count(wq)) {
3412 struct work_queue_item *item = work_queue_last_item(wq);
3413 pqnode = item->data;
3414
3415 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3416 || pqnode->bgp != bgp
3417 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3418 pqnode = bgp_processq_alloc(bgp);
3419 else
3420 pqnode_reuse = 1;
3421 } else
3422 pqnode = bgp_processq_alloc(bgp);
3423 /* all unlocked in bgp_process_wq */
3424 bgp_table_lock(bgp_dest_table(dest));
3425
3426 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3427 bgp_dest_lock_node(dest);
3428
3429 /* can't be enqueued twice */
3430 assert(STAILQ_NEXT(dest, pq) == NULL);
3431 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3432 pqnode->queued++;
3433
3434 if (!pqnode_reuse)
3435 work_queue_add(wq, pqnode);
3436
3437 return;
3438}
3439
3440void bgp_add_eoiu_mark(struct bgp *bgp)
3441{
3442 struct bgp_process_queue *pqnode;
3443
3444 if (bgp->process_queue == NULL)
3445 return;
3446
3447 pqnode = bgp_processq_alloc(bgp);
3448
3449 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3450 work_queue_add(bgp->process_queue, pqnode);
3451}
3452
3453static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3454{
3455 struct peer *peer;
3456
3457 peer = THREAD_ARG(thread);
3458 peer->t_pmax_restart = NULL;
3459
3460 if (bgp_debug_neighbor_events(peer))
3461 zlog_debug(
3462 "%s Maximum-prefix restart timer expired, restore peering",
3463 peer->host);
3464
3465 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3466 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3467}
3468
3469static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3470 safi_t safi)
3471{
3472 uint32_t count = 0;
3473 bool filtered = false;
3474 struct bgp_dest *dest;
3475 struct bgp_adj_in *ain;
3476 struct attr attr = {};
3477 struct bgp_table *table = peer->bgp->rib[afi][safi];
3478
3479 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3480 for (ain = dest->adj_in; ain; ain = ain->next) {
3481 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3482
3483 attr = *ain->attr;
3484
3485 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3486 == FILTER_DENY)
3487 filtered = true;
3488
3489 if (bgp_input_modifier(
3490 peer, rn_p, &attr, afi, safi,
3491 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3492 NULL, 0, NULL)
3493 == RMAP_DENY)
3494 filtered = true;
3495
3496 if (filtered)
3497 count++;
3498
3499 bgp_attr_flush(&attr);
3500 }
3501 }
3502
3503 return count;
3504}
3505
3506bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3507 int always)
3508{
3509 iana_afi_t pkt_afi;
3510 iana_safi_t pkt_safi;
3511 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3512 PEER_FLAG_MAX_PREFIX_FORCE))
3513 ? bgp_filtered_routes_count(peer, afi, safi)
3514 + peer->pcount[afi][safi]
3515 : peer->pcount[afi][safi];
3516
3517 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3518 return false;
3519
3520 if (pcount > peer->pmax[afi][safi]) {
3521 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3522 PEER_STATUS_PREFIX_LIMIT)
3523 && !always)
3524 return false;
3525
3526 zlog_info(
3527 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3528 get_afi_safi_str(afi, safi, false), peer, pcount,
3529 peer->pmax[afi][safi]);
3530 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3531
3532 if (CHECK_FLAG(peer->af_flags[afi][safi],
3533 PEER_FLAG_MAX_PREFIX_WARNING))
3534 return false;
3535
3536 /* Convert AFI, SAFI to values for packet. */
3537 pkt_afi = afi_int2iana(afi);
3538 pkt_safi = safi_int2iana(safi);
3539 {
3540 uint8_t ndata[7];
3541
3542 ndata[0] = (pkt_afi >> 8);
3543 ndata[1] = pkt_afi;
3544 ndata[2] = pkt_safi;
3545 ndata[3] = (peer->pmax[afi][safi] >> 24);
3546 ndata[4] = (peer->pmax[afi][safi] >> 16);
3547 ndata[5] = (peer->pmax[afi][safi] >> 8);
3548 ndata[6] = (peer->pmax[afi][safi]);
3549
3550 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3551 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3552 BGP_NOTIFY_CEASE_MAX_PREFIX,
3553 ndata, 7);
3554 }
3555
3556 /* Dynamic peers will just close their connection. */
3557 if (peer_dynamic_neighbor(peer))
3558 return true;
3559
3560 /* restart timer start */
3561 if (peer->pmax_restart[afi][safi]) {
3562 peer->v_pmax_restart =
3563 peer->pmax_restart[afi][safi] * 60;
3564
3565 if (bgp_debug_neighbor_events(peer))
3566 zlog_debug(
3567 "%pBP Maximum-prefix restart timer started for %d secs",
3568 peer, peer->v_pmax_restart);
3569
3570 BGP_TIMER_ON(peer->t_pmax_restart,
3571 bgp_maximum_prefix_restart_timer,
3572 peer->v_pmax_restart);
3573 }
3574
3575 return true;
3576 } else
3577 UNSET_FLAG(peer->af_sflags[afi][safi],
3578 PEER_STATUS_PREFIX_LIMIT);
3579
3580 if (pcount
3581 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3582 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3583 PEER_STATUS_PREFIX_THRESHOLD)
3584 && !always)
3585 return false;
3586
3587 zlog_info(
3588 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3589 get_afi_safi_str(afi, safi, false), peer, pcount,
3590 peer->pmax[afi][safi]);
3591 SET_FLAG(peer->af_sflags[afi][safi],
3592 PEER_STATUS_PREFIX_THRESHOLD);
3593 } else
3594 UNSET_FLAG(peer->af_sflags[afi][safi],
3595 PEER_STATUS_PREFIX_THRESHOLD);
3596 return false;
3597}
3598
3599/* Unconditionally remove the route from the RIB, without taking
3600 * damping into consideration (eg, because the session went down)
3601 */
3602void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3603 struct peer *peer, afi_t afi, safi_t safi)
3604{
3605
3606 struct bgp *bgp = NULL;
3607 bool delete_route = false;
3608
3609 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3610 safi);
3611
3612 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3613 bgp_path_info_delete(dest, pi); /* keep historical info */
3614
3615 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3616 * flag
3617 */
3618 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3619 delete_route = true;
3620 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3621 delete_route = true;
3622 if (delete_route) {
3623 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3624 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3625 bgp = pi->peer->bgp;
3626 bgp->gr_info[afi][safi].gr_deferred--;
3627 }
3628 }
3629 }
3630
3631 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3632 bgp_process(peer->bgp, dest, afi, safi);
3633}
3634
3635static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3636 struct peer *peer, afi_t afi, safi_t safi,
3637 struct prefix_rd *prd)
3638{
3639 const struct prefix *p = bgp_dest_get_prefix(dest);
3640
3641 /* apply dampening, if result is suppressed, we'll be retaining
3642 * the bgp_path_info in the RIB for historical reference.
3643 */
3644 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3645 && peer->sort == BGP_PEER_EBGP)
3646 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3647 == BGP_DAMP_SUPPRESSED) {
3648 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3649 safi);
3650 return;
3651 }
3652
3653#ifdef ENABLE_BGP_VNC
3654 if (safi == SAFI_MPLS_VPN) {
3655 struct bgp_dest *pdest = NULL;
3656 struct bgp_table *table = NULL;
3657
3658 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3659 (struct prefix *)prd);
3660 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3661 table = bgp_dest_get_bgp_table_info(pdest);
3662
3663 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3664 peer->bgp, prd, table, p, pi);
3665 }
3666 bgp_dest_unlock_node(pdest);
3667 }
3668 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3669 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3670
3671 vnc_import_bgp_del_route(peer->bgp, p, pi);
3672 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3673 }
3674 }
3675#endif
3676
3677 /* If this is an EVPN route, process for un-import. */
3678 if (safi == SAFI_EVPN)
3679 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3680
3681 bgp_rib_remove(dest, pi, peer, afi, safi);
3682}
3683
3684struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3685 struct peer *peer, struct attr *attr,
3686 struct bgp_dest *dest)
3687{
3688 struct bgp_path_info *new;
3689
3690 /* Make new BGP info. */
3691 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3692 new->type = type;
3693 new->instance = instance;
3694 new->sub_type = sub_type;
3695 new->peer = peer;
3696 new->attr = attr;
3697 new->uptime = monotime(NULL);
3698 new->net = dest;
3699 return new;
3700}
3701
3702/* Check if received nexthop is valid or not. */
3703bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3704 uint8_t type, uint8_t stype, struct attr *attr,
3705 struct bgp_dest *dest)
3706{
3707 bool ret = false;
3708 bool is_bgp_static_route =
3709 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3710 : false;
3711
3712 /*
3713 * Only validated for unicast and multicast currently.
3714 * Also valid for EVPN where the nexthop is an IP address.
3715 * If we are a bgp static route being checked then there is
3716 * no need to check to see if the nexthop is martian as
3717 * that it should be ok.
3718 */
3719 if (is_bgp_static_route ||
3720 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3721 return false;
3722
3723 /* If NEXT_HOP is present, validate it. */
3724 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3725 if (attr->nexthop.s_addr == INADDR_ANY ||
3726 !ipv4_unicast_valid(&attr->nexthop) ||
3727 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3728 return true;
3729 }
3730
3731 /* If MP_NEXTHOP is present, validate it. */
3732 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3733 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3734 * it is not an IPv6 link-local address.
3735 *
3736 * If we receive an UPDATE with nexthop length set to 32 bytes
3737 * we shouldn't discard an UPDATE if it's set to (::).
3738 * The link-local (2st) is validated along the code path later.
3739 */
3740 if (attr->mp_nexthop_len) {
3741 switch (attr->mp_nexthop_len) {
3742 case BGP_ATTR_NHLEN_IPV4:
3743 case BGP_ATTR_NHLEN_VPNV4:
3744 ret = (attr->mp_nexthop_global_in.s_addr ==
3745 INADDR_ANY ||
3746 !ipv4_unicast_valid(
3747 &attr->mp_nexthop_global_in) ||
3748 bgp_nexthop_self(bgp, afi, type, stype, attr,
3749 dest));
3750 break;
3751
3752 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3753 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3754 ret = (IN6_IS_ADDR_UNSPECIFIED(
3755 &attr->mp_nexthop_global)
3756 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3757 || IN6_IS_ADDR_MULTICAST(
3758 &attr->mp_nexthop_global)
3759 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3760 dest));
3761 break;
3762 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3763 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3764 || IN6_IS_ADDR_MULTICAST(
3765 &attr->mp_nexthop_global)
3766 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3767 dest));
3768 break;
3769
3770 default:
3771 ret = true;
3772 break;
3773 }
3774 }
3775
3776 return ret;
3777}
3778
3779static void bgp_attr_add_no_export_community(struct attr *attr)
3780{
3781 struct community *old;
3782 struct community *new;
3783 struct community *merge;
3784 struct community *no_export;
3785
3786 old = bgp_attr_get_community(attr);
3787 no_export = community_str2com("no-export");
3788
3789 assert(no_export);
3790
3791 if (old) {
3792 merge = community_merge(community_dup(old), no_export);
3793
3794 if (!old->refcnt)
3795 community_free(&old);
3796
3797 new = community_uniq_sort(merge);
3798 community_free(&merge);
3799 } else {
3800 new = community_dup(no_export);
3801 }
3802
3803 community_free(&no_export);
3804
3805 bgp_attr_set_community(attr, new);
3806}
3807
3808int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3809 struct attr *attr, afi_t afi, safi_t safi, int type,
3810 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3811 uint32_t num_labels, int soft_reconfig,
3812 struct bgp_route_evpn *evpn)
3813{
3814 int ret;
3815 int aspath_loop_count = 0;
3816 struct bgp_dest *dest;
3817 struct bgp *bgp;
3818 struct attr new_attr;
3819 struct attr *attr_new;
3820 struct bgp_path_info *pi;
3821 struct bgp_path_info *new;
3822 struct bgp_path_info_extra *extra;
3823 const char *reason;
3824 char pfx_buf[BGP_PRD_PATH_STRLEN];
3825 int connected = 0;
3826 int do_loop_check = 1;
3827 int has_valid_label = 0;
3828 afi_t nh_afi;
3829 uint8_t pi_type = 0;
3830 uint8_t pi_sub_type = 0;
3831 bool force_evpn_import = false;
3832 safi_t orig_safi = safi;
3833 bool leak_success = true;
3834
3835 if (frrtrace_enabled(frr_bgp, process_update)) {
3836 char pfxprint[PREFIX2STR_BUFFER];
3837
3838 prefix2str(p, pfxprint, sizeof(pfxprint));
3839 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3840 afi, safi, attr);
3841 }
3842
3843#ifdef ENABLE_BGP_VNC
3844 int vnc_implicit_withdraw = 0;
3845#endif
3846 int same_attr = 0;
3847
3848 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
3849 if (orig_safi == SAFI_LABELED_UNICAST)
3850 safi = SAFI_UNICAST;
3851
3852 memset(&new_attr, 0, sizeof(new_attr));
3853 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3854 new_attr.label = MPLS_INVALID_LABEL;
3855
3856 bgp = peer->bgp;
3857 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3858 /* TODO: Check to see if we can get rid of "is_valid_label" */
3859 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3860 has_valid_label = (num_labels > 0) ? 1 : 0;
3861 else
3862 has_valid_label = bgp_is_valid_label(label);
3863
3864 if (has_valid_label)
3865 assert(label != NULL);
3866
3867 /* Update overlay index of the attribute */
3868 if (afi == AFI_L2VPN && evpn)
3869 memcpy(&attr->evpn_overlay, evpn,
3870 sizeof(struct bgp_route_evpn));
3871
3872 /* When peer's soft reconfiguration enabled. Record input packet in
3873 Adj-RIBs-In. */
3874 if (!soft_reconfig
3875 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3876 && peer != bgp->peer_self)
3877 bgp_adj_in_set(dest, peer, attr, addpath_id);
3878
3879 /* Check previously received route. */
3880 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3881 if (pi->peer == peer && pi->type == type
3882 && pi->sub_type == sub_type
3883 && pi->addpath_rx_id == addpath_id)
3884 break;
3885
3886 /* AS path local-as loop check. */
3887 if (peer->change_local_as) {
3888 if (peer->allowas_in[afi][safi])
3889 aspath_loop_count = peer->allowas_in[afi][safi];
3890 else if (!CHECK_FLAG(peer->flags,
3891 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3892 aspath_loop_count = 1;
3893
3894 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3895 > aspath_loop_count) {
3896 peer->stat_pfx_aspath_loop++;
3897 reason = "as-path contains our own AS;";
3898 goto filtered;
3899 }
3900 }
3901
3902 /* If the peer is configured for "allowas-in origin" and the last ASN in
3903 * the
3904 * as-path is our ASN then we do not need to call aspath_loop_check
3905 */
3906 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3907 if (aspath_get_last_as(attr->aspath) == bgp->as)
3908 do_loop_check = 0;
3909
3910 /* AS path loop check. */
3911 if (do_loop_check) {
3912 if (aspath_loop_check(attr->aspath, bgp->as)
3913 > peer->allowas_in[afi][safi]
3914 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3915 && aspath_loop_check(attr->aspath, bgp->confed_id)
3916 > peer->allowas_in[afi][safi])) {
3917 peer->stat_pfx_aspath_loop++;
3918 reason = "as-path contains our own AS;";
3919 goto filtered;
3920 }
3921 }
3922
3923 /* Route reflector originator ID check. */
3924 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3925 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3926 peer->stat_pfx_originator_loop++;
3927 reason = "originator is us;";
3928 goto filtered;
3929 }
3930
3931 /* Route reflector cluster ID check. */
3932 if (bgp_cluster_filter(peer, attr)) {
3933 peer->stat_pfx_cluster_loop++;
3934 reason = "reflected from the same cluster;";
3935 goto filtered;
3936 }
3937
3938 /* Apply incoming filter. */
3939 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
3940 peer->stat_pfx_filter++;
3941 reason = "filter;";
3942 goto filtered;
3943 }
3944
3945 /* RFC 8212 to prevent route leaks.
3946 * This specification intends to improve this situation by requiring the
3947 * explicit configuration of both BGP Import and Export Policies for any
3948 * External BGP (EBGP) session such as customers, peers, or
3949 * confederation boundaries for all enabled address families. Through
3950 * codification of the aforementioned requirement, operators will
3951 * benefit from consistent behavior across different BGP
3952 * implementations.
3953 */
3954 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3955 if (!bgp_inbound_policy_exists(peer,
3956 &peer->filter[afi][safi])) {
3957 reason = "inbound policy missing";
3958 if (monotime_since(&bgp->ebgprequirespolicywarning,
3959 NULL) > FIFTEENMINUTE2USEC ||
3960 bgp->ebgprequirespolicywarning.tv_sec == 0) {
3961 zlog_warn(
3962 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
3963 monotime(&bgp->ebgprequirespolicywarning);
3964 }
3965 goto filtered;
3966 }
3967
3968 /* draft-ietf-idr-deprecate-as-set-confed-set
3969 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3970 * Eventually, This document (if approved) updates RFC 4271
3971 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3972 * and obsoletes RFC 6472.
3973 */
3974 if (peer->bgp->reject_as_sets)
3975 if (aspath_check_as_sets(attr->aspath)) {
3976 reason =
3977 "as-path contains AS_SET or AS_CONFED_SET type;";
3978 goto filtered;
3979 }
3980
3981 new_attr = *attr;
3982
3983 /* Apply incoming route-map.
3984 * NB: new_attr may now contain newly allocated values from route-map
3985 * "set"
3986 * commands, so we need bgp_attr_flush in the error paths, until we
3987 * intern
3988 * the attr (which takes over the memory references) */
3989 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
3990 num_labels, dest)
3991 == RMAP_DENY) {
3992 peer->stat_pfx_filter++;
3993 reason = "route-map;";
3994 bgp_attr_flush(&new_attr);
3995 goto filtered;
3996 }
3997
3998 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3999 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4000 /* remove from RIB previous entry */
4001 bgp_zebra_withdraw(p, pi, bgp, safi);
4002 }
4003
4004 if (peer->sort == BGP_PEER_EBGP) {
4005
4006 /* rfc7999:
4007 * A BGP speaker receiving an announcement tagged with the
4008 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4009 * NO_EXPORT community as defined in RFC1997, or a
4010 * similar community, to prevent propagation of the
4011 * prefix outside the local AS. The community to prevent
4012 * propagation SHOULD be chosen according to the operator's
4013 * routing policy.
4014 */
4015 if (bgp_attr_get_community(&new_attr) &&
4016 community_include(bgp_attr_get_community(&new_attr),
4017 COMMUNITY_BLACKHOLE))
4018 bgp_attr_add_no_export_community(&new_attr);
4019
4020 /* If we receive the graceful-shutdown community from an eBGP
4021 * peer we must lower local-preference */
4022 if (bgp_attr_get_community(&new_attr) &&
4023 community_include(bgp_attr_get_community(&new_attr),
4024 COMMUNITY_GSHUT)) {
4025 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4026 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4027
4028 /* If graceful-shutdown is configured then add the GSHUT
4029 * community to all paths received from eBGP peers */
4030 } else if (bgp_in_graceful_shutdown(peer->bgp))
4031 bgp_attr_add_gshut_community(&new_attr);
4032 }
4033
4034 if (pi) {
4035 pi_type = pi->type;
4036 pi_sub_type = pi->sub_type;
4037 }
4038
4039 /* next hop check. */
4040 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
4041 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
4042 &new_attr, dest)) {
4043 peer->stat_pfx_nh_invalid++;
4044 reason = "martian or self next-hop;";
4045 bgp_attr_flush(&new_attr);
4046 goto filtered;
4047 }
4048
4049 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4050 peer->stat_pfx_nh_invalid++;
4051 reason = "self mac;";
4052 bgp_attr_flush(&new_attr);
4053 goto filtered;
4054 }
4055
4056 if (bgp_check_role_applicability(afi, safi) &&
4057 bgp_otc_filter(peer, &new_attr)) {
4058 reason = "failing otc validation";
4059 bgp_attr_flush(&new_attr);
4060 goto filtered;
4061 }
4062 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4063 * condition :
4064 * Suppress fib is enabled
4065 * BGP_OPT_NO_FIB is not enabled
4066 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4067 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4068 */
4069 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4070 && (sub_type == BGP_ROUTE_NORMAL)
4071 && (!bgp_option_check(BGP_OPT_NO_FIB))
4072 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4073 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4074
4075 /* If maximum prefix count is configured and current prefix
4076 * count exeed it.
4077 */
4078 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4079 bgp_attr_flush(&new_attr);
4080 return -1;
4081 }
4082
4083 /* If neighbor soo is configured, tag all incoming routes with
4084 * this SoO tag and then filter out advertisements in
4085 * subgroup_announce_check() if it matches the configured SoO
4086 * on the other peer.
4087 */
4088 if (peer->soo[afi][safi]) {
4089 struct ecommunity *old_ecomm =
4090 bgp_attr_get_ecommunity(&new_attr);
4091 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4092 struct ecommunity *new_ecomm;
4093
4094 if (old_ecomm) {
4095 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4096 ecomm_soo);
4097
4098 if (!old_ecomm->refcnt)
4099 ecommunity_free(&old_ecomm);
4100 } else {
4101 new_ecomm = ecommunity_dup(ecomm_soo);
4102 }
4103
4104 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4105 }
4106
4107 attr_new = bgp_attr_intern(&new_attr);
4108
4109 /* If the update is implicit withdraw. */
4110 if (pi) {
4111 pi->uptime = monotime(NULL);
4112 same_attr = attrhash_cmp(pi->attr, attr_new);
4113
4114 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4115
4116 /* Same attribute comes in. */
4117 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4118 && same_attr
4119 && (!has_valid_label
4120 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4121 num_labels * sizeof(mpls_label_t))
4122 == 0)) {
4123 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4124 BGP_CONFIG_DAMPENING)
4125 && peer->sort == BGP_PEER_EBGP
4126 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4127 if (bgp_debug_update(peer, p, NULL, 1)) {
4128 bgp_debug_rdpfxpath2str(
4129 afi, safi, prd, p, label,
4130 num_labels, addpath_id ? 1 : 0,
4131 addpath_id, evpn, pfx_buf,
4132 sizeof(pfx_buf));
4133 zlog_debug("%pBP rcvd %s", peer,
4134 pfx_buf);
4135 }
4136
4137 if (bgp_damp_update(pi, dest, afi, safi)
4138 != BGP_DAMP_SUPPRESSED) {
4139 bgp_aggregate_increment(bgp, p, pi, afi,
4140 safi);
4141 bgp_process(bgp, dest, afi, safi);
4142 }
4143 } else /* Duplicate - odd */
4144 {
4145 if (bgp_debug_update(peer, p, NULL, 1)) {
4146 if (!peer->rcvd_attr_printed) {
4147 zlog_debug(
4148 "%pBP rcvd UPDATE w/ attr: %s",
4149 peer,
4150 peer->rcvd_attr_str);
4151 peer->rcvd_attr_printed = 1;
4152 }
4153
4154 bgp_debug_rdpfxpath2str(
4155 afi, safi, prd, p, label,
4156 num_labels, addpath_id ? 1 : 0,
4157 addpath_id, evpn, pfx_buf,
4158 sizeof(pfx_buf));
4159 zlog_debug(
4160 "%pBP rcvd %s...duplicate ignored",
4161 peer, pfx_buf);
4162 }
4163
4164 /* graceful restart STALE flag unset. */
4165 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4166 bgp_path_info_unset_flag(
4167 dest, pi, BGP_PATH_STALE);
4168 bgp_dest_set_defer_flag(dest, false);
4169 bgp_process(bgp, dest, afi, safi);
4170 }
4171 }
4172
4173 bgp_dest_unlock_node(dest);
4174 bgp_attr_unintern(&attr_new);
4175
4176 return 0;
4177 }
4178
4179 /* Withdraw/Announce before we fully processed the withdraw */
4180 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4181 if (bgp_debug_update(peer, p, NULL, 1)) {
4182 bgp_debug_rdpfxpath2str(
4183 afi, safi, prd, p, label, num_labels,
4184 addpath_id ? 1 : 0, addpath_id, evpn,
4185 pfx_buf, sizeof(pfx_buf));
4186 zlog_debug(
4187 "%pBP rcvd %s, flapped quicker than processing",
4188 peer, pfx_buf);
4189 }
4190
4191 bgp_path_info_restore(dest, pi);
4192
4193 /*
4194 * If the BGP_PATH_REMOVED flag is set, then EVPN
4195 * routes would have been unimported already when a
4196 * prior BGP withdraw processing happened. Such routes
4197 * need to be imported again, so flag accordingly.
4198 */
4199 force_evpn_import = true;
4200 }
4201
4202 /* Received Logging. */
4203 if (bgp_debug_update(peer, p, NULL, 1)) {
4204 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4205 num_labels, addpath_id ? 1 : 0,
4206 addpath_id, evpn, pfx_buf,
4207 sizeof(pfx_buf));
4208 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4209 }
4210
4211 /* graceful restart STALE flag unset. */
4212 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4213 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4214 bgp_dest_set_defer_flag(dest, false);
4215 }
4216
4217 /* The attribute is changed. */
4218 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4219
4220 /* implicit withdraw, decrement aggregate and pcount here.
4221 * only if update is accepted, they'll increment below.
4222 */
4223 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4224
4225 /* Update bgp route dampening information. */
4226 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4227 && peer->sort == BGP_PEER_EBGP) {
4228 /* This is implicit withdraw so we should update
4229 dampening
4230 information. */
4231 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4232 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4233 }
4234#ifdef ENABLE_BGP_VNC
4235 if (safi == SAFI_MPLS_VPN) {
4236 struct bgp_dest *pdest = NULL;
4237 struct bgp_table *table = NULL;
4238
4239 pdest = bgp_node_get(bgp->rib[afi][safi],
4240 (struct prefix *)prd);
4241 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4242 table = bgp_dest_get_bgp_table_info(pdest);
4243
4244 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4245 bgp, prd, table, p, pi);
4246 }
4247 bgp_dest_unlock_node(pdest);
4248 }
4249 if ((afi == AFI_IP || afi == AFI_IP6)
4250 && (safi == SAFI_UNICAST)) {
4251 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4252 /*
4253 * Implicit withdraw case.
4254 */
4255 ++vnc_implicit_withdraw;
4256 vnc_import_bgp_del_route(bgp, p, pi);
4257 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4258 }
4259 }
4260#endif
4261
4262 /* Special handling for EVPN update of an existing route. If the
4263 * extended community attribute has changed, we need to
4264 * un-import
4265 * the route using its existing extended community. It will be
4266 * subsequently processed for import with the new extended
4267 * community.
4268 */
4269 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4270 && !same_attr) {
4271 if ((pi->attr->flag
4272 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4273 && (attr_new->flag
4274 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4275 int cmp;
4276
4277 cmp = ecommunity_cmp(
4278 bgp_attr_get_ecommunity(pi->attr),
4279 bgp_attr_get_ecommunity(attr_new));
4280 if (!cmp) {
4281 if (bgp_debug_update(peer, p, NULL, 1))
4282 zlog_debug(
4283 "Change in EXT-COMM, existing %s new %s",
4284 ecommunity_str(
4285 bgp_attr_get_ecommunity(
4286 pi->attr)),
4287 ecommunity_str(
4288 bgp_attr_get_ecommunity(
4289 attr_new)));
4290 if (safi == SAFI_EVPN)
4291 bgp_evpn_unimport_route(
4292 bgp, afi, safi, p, pi);
4293 else /* SAFI_MPLS_VPN */
4294 vpn_leak_to_vrf_withdraw(bgp,
4295 pi);
4296 }
4297 }
4298 }
4299
4300 /* Update to new attribute. */
4301 bgp_attr_unintern(&pi->attr);
4302 pi->attr = attr_new;
4303
4304 /* Update MPLS label */
4305 if (has_valid_label) {
4306 extra = bgp_path_info_extra_get(pi);
4307 if (extra->label != label) {
4308 memcpy(&extra->label, label,
4309 num_labels * sizeof(mpls_label_t));
4310 extra->num_labels = num_labels;
4311 }
4312 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4313 bgp_set_valid_label(&extra->label[0]);
4314 }
4315
4316 /* Update SRv6 SID */
4317 if (attr->srv6_l3vpn) {
4318 extra = bgp_path_info_extra_get(pi);
4319 if (sid_diff(&extra->sid[0].sid,
4320 &attr->srv6_l3vpn->sid)) {
4321 sid_copy(&extra->sid[0].sid,
4322 &attr->srv6_l3vpn->sid);
4323 extra->num_sids = 1;
4324
4325 extra->sid[0].loc_block_len = 0;
4326 extra->sid[0].loc_node_len = 0;
4327 extra->sid[0].func_len = 0;
4328 extra->sid[0].arg_len = 0;
4329 extra->sid[0].transposition_len = 0;
4330 extra->sid[0].transposition_offset = 0;
4331
4332 if (attr->srv6_l3vpn->loc_block_len != 0) {
4333 extra->sid[0].loc_block_len =
4334 attr->srv6_l3vpn->loc_block_len;
4335 extra->sid[0].loc_node_len =
4336 attr->srv6_l3vpn->loc_node_len;
4337 extra->sid[0].func_len =
4338 attr->srv6_l3vpn->func_len;
4339 extra->sid[0].arg_len =
4340 attr->srv6_l3vpn->arg_len;
4341 extra->sid[0].transposition_len =
4342 attr->srv6_l3vpn
4343 ->transposition_len;
4344 extra->sid[0].transposition_offset =
4345 attr->srv6_l3vpn
4346 ->transposition_offset;
4347 }
4348 }
4349 } else if (attr->srv6_vpn) {
4350 extra = bgp_path_info_extra_get(pi);
4351 if (sid_diff(&extra->sid[0].sid,
4352 &attr->srv6_vpn->sid)) {
4353 sid_copy(&extra->sid[0].sid,
4354 &attr->srv6_vpn->sid);
4355 extra->num_sids = 1;
4356 }
4357 }
4358
4359#ifdef ENABLE_BGP_VNC
4360 if ((afi == AFI_IP || afi == AFI_IP6)
4361 && (safi == SAFI_UNICAST)) {
4362 if (vnc_implicit_withdraw) {
4363 /*
4364 * Add back the route with its new attributes
4365 * (e.g., nexthop).
4366 * The route is still selected, until the route
4367 * selection
4368 * queued by bgp_process actually runs. We have
4369 * to make this
4370 * update to the VNC side immediately to avoid
4371 * racing against
4372 * configuration changes (e.g., route-map
4373 * changes) which
4374 * trigger re-importation of the entire RIB.
4375 */
4376 vnc_import_bgp_add_route(bgp, p, pi);
4377 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4378 }
4379 }
4380#endif
4381
4382 /* Update bgp route dampening information. */
4383 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4384 && peer->sort == BGP_PEER_EBGP) {
4385 /* Now we do normal update dampening. */
4386 ret = bgp_damp_update(pi, dest, afi, safi);
4387 if (ret == BGP_DAMP_SUPPRESSED) {
4388 bgp_dest_unlock_node(dest);
4389 return 0;
4390 }
4391 }
4392
4393 /* Nexthop reachability check - for unicast and
4394 * labeled-unicast.. */
4395 if (((afi == AFI_IP || afi == AFI_IP6)
4396 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4397 || (safi == SAFI_EVPN &&
4398 bgp_evpn_is_prefix_nht_supported(p))) {
4399 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4400 && peer->ttl == BGP_DEFAULT_TTL
4401 && !CHECK_FLAG(peer->flags,
4402 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4403 && !CHECK_FLAG(bgp->flags,
4404 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4405 connected = 1;
4406 else
4407 connected = 0;
4408
4409 struct bgp *bgp_nexthop = bgp;
4410
4411 if (pi->extra && pi->extra->bgp_orig)
4412 bgp_nexthop = pi->extra->bgp_orig;
4413
4414 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4415
4416 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4417 safi, pi, NULL, connected,
4418 p)
4419 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4420 bgp_path_info_set_flag(dest, pi,
4421 BGP_PATH_VALID);
4422 else {
4423 if (BGP_DEBUG(nht, NHT)) {
4424 zlog_debug("%s(%pI4): NH unresolved",
4425 __func__,
4426 (in_addr_t *)&attr_new->nexthop);
4427 }
4428 bgp_path_info_unset_flag(dest, pi,
4429 BGP_PATH_VALID);
4430 }
4431 } else
4432 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4433
4434#ifdef ENABLE_BGP_VNC
4435 if (safi == SAFI_MPLS_VPN) {
4436 struct bgp_dest *pdest = NULL;
4437 struct bgp_table *table = NULL;
4438
4439 pdest = bgp_node_get(bgp->rib[afi][safi],
4440 (struct prefix *)prd);
4441 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4442 table = bgp_dest_get_bgp_table_info(pdest);
4443
4444 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4445 bgp, prd, table, p, pi);
4446 }
4447 bgp_dest_unlock_node(pdest);
4448 }
4449#endif
4450
4451 /* If this is an EVPN route and some attribute has changed,
4452 * or we are explicitly told to perform a route import, process
4453 * route for import. If the extended community has changed, we
4454 * would
4455 * have done the un-import earlier and the import would result
4456 * in the
4457 * route getting injected into appropriate L2 VNIs. If it is
4458 * just
4459 * some other attribute change, the import will result in
4460 * updating
4461 * the attributes for the route in the VNI(s).
4462 */
4463 if (safi == SAFI_EVPN &&
4464 (!same_attr || force_evpn_import) &&
4465 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4466 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4467
4468 /* Process change. */
4469 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4470
4471 bgp_process(bgp, dest, afi, safi);
4472 bgp_dest_unlock_node(dest);
4473
4474 if (SAFI_UNICAST == safi
4475 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4476 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4477
4478 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4479 }
4480 if ((SAFI_MPLS_VPN == safi)
4481 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4482
4483 leak_success = vpn_leak_to_vrf_update(bgp, pi);
4484 }
4485
4486#ifdef ENABLE_BGP_VNC
4487 if (SAFI_MPLS_VPN == safi) {
4488 mpls_label_t label_decoded = decode_label(label);
4489
4490 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4491 type, sub_type, &label_decoded);
4492 }
4493 if (SAFI_ENCAP == safi) {
4494 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4495 type, sub_type, NULL);
4496 }
4497#endif
4498 if ((safi == SAFI_MPLS_VPN) &&
4499 !CHECK_FLAG(bgp->af_flags[afi][safi],
4500 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4501 !leak_success) {
4502 bgp_unlink_nexthop(pi);
4503 bgp_path_info_delete(dest, pi);
4504 }
4505 return 0;
4506 } // End of implicit withdraw
4507
4508 /* Received Logging. */
4509 if (bgp_debug_update(peer, p, NULL, 1)) {
4510 if (!peer->rcvd_attr_printed) {
4511 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4512 peer->rcvd_attr_str);
4513 peer->rcvd_attr_printed = 1;
4514 }
4515
4516 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4517 addpath_id ? 1 : 0, addpath_id, evpn,
4518 pfx_buf, sizeof(pfx_buf));
4519 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4520 }
4521
4522 /* Make new BGP info. */
4523 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4524
4525 /* Update MPLS label */
4526 if (has_valid_label) {
4527 extra = bgp_path_info_extra_get(new);
4528 if (extra->label != label) {
4529 memcpy(&extra->label, label,
4530 num_labels * sizeof(mpls_label_t));
4531 extra->num_labels = num_labels;
4532 }
4533 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4534 bgp_set_valid_label(&extra->label[0]);
4535 }
4536
4537 /* Update SRv6 SID */
4538 if (safi == SAFI_MPLS_VPN) {
4539 extra = bgp_path_info_extra_get(new);
4540 if (attr->srv6_l3vpn) {
4541 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4542 extra->num_sids = 1;
4543
4544 extra->sid[0].loc_block_len =
4545 attr->srv6_l3vpn->loc_block_len;
4546 extra->sid[0].loc_node_len =
4547 attr->srv6_l3vpn->loc_node_len;
4548 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4549 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4550 extra->sid[0].transposition_len =
4551 attr->srv6_l3vpn->transposition_len;
4552 extra->sid[0].transposition_offset =
4553 attr->srv6_l3vpn->transposition_offset;
4554 } else if (attr->srv6_vpn) {
4555 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4556 extra->num_sids = 1;
4557 }
4558 }
4559
4560 /* Nexthop reachability check. */
4561 if (((afi == AFI_IP || afi == AFI_IP6)
4562 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4563 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4564 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4565 && peer->ttl == BGP_DEFAULT_TTL
4566 && !CHECK_FLAG(peer->flags,
4567 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4568 && !CHECK_FLAG(bgp->flags,
4569 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4570 connected = 1;
4571 else
4572 connected = 0;
4573
4574 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4575
4576 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4577 connected, p)
4578 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4579 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4580 else {
4581 if (BGP_DEBUG(nht, NHT)) {
4582 char buf1[INET6_ADDRSTRLEN];
4583 inet_ntop(AF_INET,
4584 (const void *)&attr_new->nexthop,
4585 buf1, INET6_ADDRSTRLEN);
4586 zlog_debug("%s(%s): NH unresolved", __func__,
4587 buf1);
4588 }
4589 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4590 }
4591 } else
4592 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4593
4594 /* Addpath ID */
4595 new->addpath_rx_id = addpath_id;
4596
4597 /* Increment prefix */
4598 bgp_aggregate_increment(bgp, p, new, afi, safi);
4599
4600 /* Register new BGP information. */
4601 bgp_path_info_add(dest, new);
4602
4603 /* route_node_get lock */
4604 bgp_dest_unlock_node(dest);
4605
4606#ifdef ENABLE_BGP_VNC
4607 if (safi == SAFI_MPLS_VPN) {
4608 struct bgp_dest *pdest = NULL;
4609 struct bgp_table *table = NULL;
4610
4611 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4612 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4613 table = bgp_dest_get_bgp_table_info(pdest);
4614
4615 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4616 bgp, prd, table, p, new);
4617 }
4618 bgp_dest_unlock_node(pdest);
4619 }
4620#endif
4621
4622 /* If this is an EVPN route, process for import. */
4623 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4624 bgp_evpn_import_route(bgp, afi, safi, p, new);
4625
4626 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4627
4628 /* Process change. */
4629 bgp_process(bgp, dest, afi, safi);
4630
4631 if (SAFI_UNICAST == safi
4632 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4633 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4634 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4635 }
4636 if ((SAFI_MPLS_VPN == safi)
4637 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4638 leak_success = vpn_leak_to_vrf_update(bgp, new);
4639 }
4640#ifdef ENABLE_BGP_VNC
4641 if (SAFI_MPLS_VPN == safi) {
4642 mpls_label_t label_decoded = decode_label(label);
4643
4644 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4645 sub_type, &label_decoded);
4646 }
4647 if (SAFI_ENCAP == safi) {
4648 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4649 sub_type, NULL);
4650 }
4651#endif
4652 if ((safi == SAFI_MPLS_VPN) &&
4653 !CHECK_FLAG(bgp->af_flags[afi][safi],
4654 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4655 !leak_success) {
4656 bgp_unlink_nexthop(new);
4657 bgp_path_info_delete(dest, new);
4658 }
4659
4660 return 0;
4661
4662/* This BGP update is filtered. Log the reason then update BGP
4663 entry. */
4664filtered:
4665 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4666
4667 if (bgp_debug_update(peer, p, NULL, 1)) {
4668 if (!peer->rcvd_attr_printed) {
4669 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4670 peer->rcvd_attr_str);
4671 peer->rcvd_attr_printed = 1;
4672 }
4673
4674 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4675 addpath_id ? 1 : 0, addpath_id, evpn,
4676 pfx_buf, sizeof(pfx_buf));
4677 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4678 peer, pfx_buf, reason);
4679 }
4680
4681 if (pi) {
4682 /* If this is an EVPN route, un-import it as it is now filtered.
4683 */
4684 if (safi == SAFI_EVPN)
4685 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4686
4687 if (SAFI_UNICAST == safi
4688 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4689 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4690
4691 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4692 }
4693 if ((SAFI_MPLS_VPN == safi)
4694 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4695
4696 vpn_leak_to_vrf_withdraw(bgp, pi);
4697 }
4698
4699 bgp_rib_remove(dest, pi, peer, afi, safi);
4700 }
4701
4702 bgp_dest_unlock_node(dest);
4703
4704#ifdef ENABLE_BGP_VNC
4705 /*
4706 * Filtered update is treated as an implicit withdrawal (see
4707 * bgp_rib_remove()
4708 * a few lines above)
4709 */
4710 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4711 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4712 0);
4713 }
4714#endif
4715
4716 return 0;
4717}
4718
4719int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4720 struct attr *attr, afi_t afi, safi_t safi, int type,
4721 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4722 uint32_t num_labels, struct bgp_route_evpn *evpn)
4723{
4724 struct bgp *bgp;
4725 char pfx_buf[BGP_PRD_PATH_STRLEN];
4726 struct bgp_dest *dest;
4727 struct bgp_path_info *pi;
4728
4729#ifdef ENABLE_BGP_VNC
4730 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4731 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4732 0);
4733 }
4734#endif
4735
4736 bgp = peer->bgp;
4737
4738 /* Lookup node. */
4739 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4740
4741 /* If peer is soft reconfiguration enabled. Record input packet for
4742 * further calculation.
4743 *
4744 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4745 * routes that are filtered. This tanks out Quagga RS pretty badly due
4746 * to
4747 * the iteration over all RS clients.
4748 * Since we need to remove the entry from adj_in anyway, do that first
4749 * and
4750 * if there was no entry, we don't need to do anything more.
4751 */
4752 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4753 && peer != bgp->peer_self)
4754 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4755 peer->stat_pfx_dup_withdraw++;
4756
4757 if (bgp_debug_update(peer, p, NULL, 1)) {
4758 bgp_debug_rdpfxpath2str(
4759 afi, safi, prd, p, label, num_labels,
4760 addpath_id ? 1 : 0, addpath_id, NULL,
4761 pfx_buf, sizeof(pfx_buf));
4762 zlog_debug(
4763 "%s withdrawing route %s not in adj-in",
4764 peer->host, pfx_buf);
4765 }
4766 bgp_dest_unlock_node(dest);
4767 return 0;
4768 }
4769
4770 /* Lookup withdrawn route. */
4771 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4772 if (pi->peer == peer && pi->type == type
4773 && pi->sub_type == sub_type
4774 && pi->addpath_rx_id == addpath_id)
4775 break;
4776
4777 /* Logging. */
4778 if (bgp_debug_update(peer, p, NULL, 1)) {
4779 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4780 addpath_id ? 1 : 0, addpath_id, NULL,
4781 pfx_buf, sizeof(pfx_buf));
4782 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4783 pfx_buf);
4784 }
4785
4786 /* Withdraw specified route from routing table. */
4787 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4788 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4789 if (SAFI_UNICAST == safi
4790 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4791 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4792 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4793 }
4794 if ((SAFI_MPLS_VPN == safi)
4795 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4796
4797 vpn_leak_to_vrf_withdraw(bgp, pi);
4798 }
4799 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4800 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4801 addpath_id ? 1 : 0, addpath_id, NULL,
4802 pfx_buf, sizeof(pfx_buf));
4803 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4804 }
4805
4806 /* Unlock bgp_node_get() lock. */
4807 bgp_dest_unlock_node(dest);
4808
4809 return 0;
4810}
4811
4812void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4813 int withdraw)
4814{
4815 struct update_subgroup *subgrp;
4816 subgrp = peer_subgroup(peer, afi, safi);
4817 subgroup_default_originate(subgrp, withdraw);
4818}
4819
4820
4821/*
4822 * bgp_stop_announce_route_timer
4823 */
4824void bgp_stop_announce_route_timer(struct peer_af *paf)
4825{
4826 if (!paf->t_announce_route)
4827 return;
4828
4829 THREAD_OFF(paf->t_announce_route);
4830}
4831
4832/*
4833 * bgp_announce_route_timer_expired
4834 *
4835 * Callback that is invoked when the route announcement timer for a
4836 * peer_af expires.
4837 */
4838static void bgp_announce_route_timer_expired(struct thread *t)
4839{
4840 struct peer_af *paf;
4841 struct peer *peer;
4842
4843 paf = THREAD_ARG(t);
4844 peer = paf->peer;
4845
4846 if (!peer_established(peer))
4847 return;
4848
4849 if (!peer->afc_nego[paf->afi][paf->safi])
4850 return;
4851
4852 peer_af_announce_route(paf, 1);
4853
4854 /* Notify BGP conditional advertisement scanner percess */
4855 peer->advmap_config_change[paf->afi][paf->safi] = true;
4856}
4857
4858/*
4859 * bgp_announce_route
4860 *
4861 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4862 *
4863 * if force is true we will force an update even if the update
4864 * limiting code is attempted to kick in.
4865 */
4866void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
4867{
4868 struct peer_af *paf;
4869 struct update_subgroup *subgrp;
4870
4871 paf = peer_af_find(peer, afi, safi);
4872 if (!paf)
4873 return;
4874 subgrp = PAF_SUBGRP(paf);
4875
4876 /*
4877 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4878 * or a refresh has already been triggered.
4879 */
4880 if (!subgrp || paf->t_announce_route)
4881 return;
4882
4883 if (force)
4884 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
4885
4886 /*
4887 * Start a timer to stagger/delay the announce. This serves
4888 * two purposes - announcement can potentially be combined for
4889 * multiple peers and the announcement doesn't happen in the
4890 * vty context.
4891 */
4892 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4893 (subgrp->peer_count == 1)
4894 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4895 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4896 &paf->t_announce_route);
4897}
4898
4899/*
4900 * Announce routes from all AF tables to a peer.
4901 *
4902 * This should ONLY be called when there is a need to refresh the
4903 * routes to the peer based on a policy change for this peer alone
4904 * or a route refresh request received from the peer.
4905 * The operation will result in splitting the peer from its existing
4906 * subgroups and putting it in new subgroups.
4907 */
4908void bgp_announce_route_all(struct peer *peer)
4909{
4910 afi_t afi;
4911 safi_t safi;
4912
4913 FOREACH_AFI_SAFI (afi, safi)
4914 bgp_announce_route(peer, afi, safi, false);
4915}
4916
4917/* Flag or unflag bgp_dest to determine whether it should be treated by
4918 * bgp_soft_reconfig_table_task.
4919 * Flag if flag is true. Unflag if flag is false.
4920 */
4921static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
4922{
4923 struct bgp_dest *dest;
4924 struct bgp_adj_in *ain;
4925
4926 if (!table)
4927 return;
4928
4929 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4930 for (ain = dest->adj_in; ain; ain = ain->next) {
4931 if (ain->peer != NULL)
4932 break;
4933 }
4934 if (flag && ain != NULL && ain->peer != NULL)
4935 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4936 else
4937 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4938 }
4939}
4940
4941static int bgp_soft_reconfig_table_update(struct peer *peer,
4942 struct bgp_dest *dest,
4943 struct bgp_adj_in *ain, afi_t afi,
4944 safi_t safi, struct prefix_rd *prd)
4945{
4946 struct bgp_path_info *pi;
4947 uint32_t num_labels = 0;
4948 mpls_label_t *label_pnt = NULL;
4949 struct bgp_route_evpn evpn;
4950
4951 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4952 if (pi->peer == peer)
4953 break;
4954
4955 if (pi && pi->extra)
4956 num_labels = pi->extra->num_labels;
4957 if (num_labels)
4958 label_pnt = &pi->extra->label[0];
4959 if (pi)
4960 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
4961 sizeof(evpn));
4962 else
4963 memset(&evpn, 0, sizeof(evpn));
4964
4965 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
4966 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
4967 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
4968 &evpn);
4969}
4970
4971static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4972 struct bgp_table *table,
4973 struct prefix_rd *prd)
4974{
4975 int ret;
4976 struct bgp_dest *dest;
4977 struct bgp_adj_in *ain;
4978
4979 if (!table)
4980 table = peer->bgp->rib[afi][safi];
4981
4982 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4983 for (ain = dest->adj_in; ain; ain = ain->next) {
4984 if (ain->peer != peer)
4985 continue;
4986
4987 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
4988 afi, safi, prd);
4989
4990 if (ret < 0) {
4991 bgp_dest_unlock_node(dest);
4992 return;
4993 }
4994 }
4995}
4996
4997/* Do soft reconfig table per bgp table.
4998 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
4999 * when BGP_NODE_SOFT_RECONFIG is set,
5000 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5001 * Schedule a new thread to continue the job.
5002 * Without splitting the full job into several part,
5003 * vtysh waits for the job to finish before responding to a BGP command
5004 */
5005static void bgp_soft_reconfig_table_task(struct thread *thread)
5006{
5007 uint32_t iter, max_iter;
5008 int ret;
5009 struct bgp_dest *dest;
5010 struct bgp_adj_in *ain;
5011 struct peer *peer;
5012 struct bgp_table *table;
5013 struct prefix_rd *prd;
5014 struct listnode *node, *nnode;
5015
5016 table = THREAD_ARG(thread);
5017 prd = NULL;
5018
5019 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5020 if (table->soft_reconfig_init) {
5021 /* first call of the function with a new srta structure.
5022 * Don't do any treatment this time on nodes
5023 * in order vtysh to respond quickly
5024 */
5025 max_iter = 0;
5026 }
5027
5028 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5029 dest = bgp_route_next(dest)) {
5030 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5031 continue;
5032
5033 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5034
5035 for (ain = dest->adj_in; ain; ain = ain->next) {
5036 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5037 nnode, peer)) {
5038 if (ain->peer != peer)
5039 continue;
5040
5041 ret = bgp_soft_reconfig_table_update(
5042 peer, dest, ain, table->afi,
5043 table->safi, prd);
5044 iter++;
5045
5046 if (ret < 0) {
5047 bgp_dest_unlock_node(dest);
5048 listnode_delete(
5049 table->soft_reconfig_peers,
5050 peer);
5051 bgp_announce_route(peer, table->afi,
5052 table->safi, false);
5053 if (list_isempty(
5054 table->soft_reconfig_peers)) {
5055 list_delete(
5056 &table->soft_reconfig_peers);
5057 bgp_soft_reconfig_table_flag(
5058 table, false);
5059 return;
5060 }
5061 }
5062 }
5063 }
5064 }
5065
5066 /* we're either starting the initial iteration,
5067 * or we're going to continue an ongoing iteration
5068 */
5069 if (dest || table->soft_reconfig_init) {
5070 table->soft_reconfig_init = false;
5071 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5072 table, 0, &table->soft_reconfig_thread);
5073 return;
5074 }
5075 /* we're done, clean up the background iteration context info and
5076 schedule route annoucement
5077 */
5078 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5079 listnode_delete(table->soft_reconfig_peers, peer);
5080 bgp_announce_route(peer, table->afi, table->safi, false);
5081 }
5082
5083 list_delete(&table->soft_reconfig_peers);
5084}
5085
5086
5087/* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5088 * and peer.
5089 * - bgp cannot be NULL
5090 * - if table and peer are NULL, cancel all threads within the bgp instance
5091 * - if table is NULL and peer is not,
5092 * remove peer in all threads within the bgp instance
5093 * - if peer is NULL, cancel all threads matching table within the bgp instance
5094 */
5095void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5096 const struct bgp_table *table,
5097 const struct peer *peer)
5098{
5099 struct peer *npeer;
5100 struct listnode *node, *nnode;
5101 int afi, safi;
5102 struct bgp_table *ntable;
5103
5104 if (!bgp)
5105 return;
5106
5107 FOREACH_AFI_SAFI (afi, safi) {
5108 ntable = bgp->rib[afi][safi];
5109 if (!ntable)
5110 continue;
5111 if (table && table != ntable)
5112 continue;
5113
5114 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5115 npeer)) {
5116 if (peer && peer != npeer)
5117 continue;
5118 listnode_delete(ntable->soft_reconfig_peers, npeer);
5119 }
5120
5121 if (!ntable->soft_reconfig_peers
5122 || !list_isempty(ntable->soft_reconfig_peers))
5123 continue;
5124
5125 list_delete(&ntable->soft_reconfig_peers);
5126 bgp_soft_reconfig_table_flag(ntable, false);
5127 THREAD_OFF(ntable->soft_reconfig_thread);
5128 }
5129}
5130
5131void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5132{
5133 struct bgp_dest *dest;
5134 struct bgp_table *table;
5135 struct listnode *node, *nnode;
5136 struct peer *npeer;
5137 struct peer_af *paf;
5138
5139 if (!peer_established(peer))
5140 return;
5141
5142 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5143 && (safi != SAFI_EVPN)) {
5144 table = peer->bgp->rib[afi][safi];
5145 if (!table)
5146 return;
5147
5148 table->soft_reconfig_init = true;
5149
5150 if (!table->soft_reconfig_peers)
5151 table->soft_reconfig_peers = list_new();
5152 npeer = NULL;
5153 /* add peer to the table soft_reconfig_peers if not already
5154 * there
5155 */
5156 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5157 npeer)) {
5158 if (peer == npeer)
5159 break;
5160 }
5161 if (peer != npeer)
5162 listnode_add(table->soft_reconfig_peers, peer);
5163
5164 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5165 * on table would start back at the beginning.
5166 */
5167 bgp_soft_reconfig_table_flag(table, true);
5168
5169 if (!table->soft_reconfig_thread)
5170 thread_add_event(bm->master,
5171 bgp_soft_reconfig_table_task, table, 0,
5172 &table->soft_reconfig_thread);
5173 /* Cancel bgp_announce_route_timer_expired threads.
5174 * bgp_announce_route_timer_expired threads have been scheduled
5175 * to announce routes as soon as the soft_reconfigure process
5176 * finishes.
5177 * In this case, soft_reconfigure is also scheduled by using
5178 * a thread but is planned after the
5179 * bgp_announce_route_timer_expired threads. It means that,
5180 * without cancelling the threads, the route announcement task
5181 * would run before the soft reconfiguration one. That would
5182 * useless and would block vtysh during several seconds. Route
5183 * announcements are rescheduled as soon as the soft_reconfigure
5184 * process finishes.
5185 */
5186 paf = peer_af_find(peer, afi, safi);
5187 if (paf)
5188 bgp_stop_announce_route_timer(paf);
5189 } else
5190 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5191 dest = bgp_route_next(dest)) {
5192 table = bgp_dest_get_bgp_table_info(dest);
5193
5194 if (table == NULL)
5195 continue;
5196
5197 const struct prefix *p = bgp_dest_get_prefix(dest);
5198 struct prefix_rd prd;
5199
5200 prd.family = AF_UNSPEC;
5201 prd.prefixlen = 64;
5202 memcpy(&prd.val, p->u.val, 8);
5203
5204 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5205 }
5206}
5207
5208
5209struct bgp_clear_node_queue {
5210 struct bgp_dest *dest;
5211};
5212
5213static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5214{
5215 struct bgp_clear_node_queue *cnq = data;
5216 struct bgp_dest *dest = cnq->dest;
5217 struct peer *peer = wq->spec.data;
5218 struct bgp_path_info *pi;
5219 struct bgp *bgp;
5220 afi_t afi = bgp_dest_table(dest)->afi;
5221 safi_t safi = bgp_dest_table(dest)->safi;
5222
5223 assert(dest && peer);
5224 bgp = peer->bgp;
5225
5226 /* It is possible that we have multiple paths for a prefix from a peer
5227 * if that peer is using AddPath.
5228 */
5229 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5230 if (pi->peer != peer)
5231 continue;
5232
5233 /* graceful restart STALE flag set. */
5234 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5235 && peer->nsf[afi][safi])
5236 || CHECK_FLAG(peer->af_sflags[afi][safi],
5237 PEER_STATUS_ENHANCED_REFRESH))
5238 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5239 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5240 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5241 else {
5242 /* If this is an EVPN route, process for
5243 * un-import. */
5244 if (safi == SAFI_EVPN)
5245 bgp_evpn_unimport_route(
5246 bgp, afi, safi,
5247 bgp_dest_get_prefix(dest), pi);
5248 /* Handle withdraw for VRF route-leaking and L3VPN */
5249 if (SAFI_UNICAST == safi
5250 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5251 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5252 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5253 bgp, pi);
5254 }
5255 if (SAFI_MPLS_VPN == safi &&
5256 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5257 vpn_leak_to_vrf_withdraw(bgp, pi);
5258 }
5259
5260 bgp_rib_remove(dest, pi, peer, afi, safi);
5261 }
5262 }
5263 return WQ_SUCCESS;
5264}
5265
5266static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5267{
5268 struct bgp_clear_node_queue *cnq = data;
5269 struct bgp_dest *dest = cnq->dest;
5270 struct bgp_table *table = bgp_dest_table(dest);
5271
5272 bgp_dest_unlock_node(dest);
5273 bgp_table_unlock(table);
5274 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5275}
5276
5277static void bgp_clear_node_complete(struct work_queue *wq)
5278{
5279 struct peer *peer = wq->spec.data;
5280
5281 /* Tickle FSM to start moving again */
5282 BGP_EVENT_ADD(peer, Clearing_Completed);
5283
5284 peer_unlock(peer); /* bgp_clear_route */
5285}
5286
5287static void bgp_clear_node_queue_init(struct peer *peer)
5288{
5289 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5290
5291 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5292#undef CLEAR_QUEUE_NAME_LEN
5293
5294 peer->clear_node_queue = work_queue_new(bm->master, wname);
5295 peer->clear_node_queue->spec.hold = 10;
5296 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5297 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5298 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5299 peer->clear_node_queue->spec.max_retries = 0;
5300
5301 /* we only 'lock' this peer reference when the queue is actually active
5302 */
5303 peer->clear_node_queue->spec.data = peer;
5304}
5305
5306static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5307 struct bgp_table *table)
5308{
5309 struct bgp_dest *dest;
5310 int force = peer->bgp->process_queue ? 0 : 1;
5311
5312 if (!table)
5313 table = peer->bgp->rib[afi][safi];
5314
5315 /* If still no table => afi/safi isn't configured at all or smth. */
5316 if (!table)
5317 return;
5318
5319 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5320 struct bgp_path_info *pi, *next;
5321 struct bgp_adj_in *ain;
5322 struct bgp_adj_in *ain_next;
5323
5324 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5325 * queued for every clearing peer, regardless of whether it is
5326 * relevant to the peer at hand.
5327 *
5328 * Overview: There are 3 different indices which need to be
5329 * scrubbed, potentially, when a peer is removed:
5330 *
5331 * 1 peer's routes visible via the RIB (ie accepted routes)
5332 * 2 peer's routes visible by the (optional) peer's adj-in index
5333 * 3 other routes visible by the peer's adj-out index
5334 *
5335 * 3 there is no hurry in scrubbing, once the struct peer is
5336 * removed from bgp->peer, we could just GC such deleted peer's
5337 * adj-outs at our leisure.
5338 *
5339 * 1 and 2 must be 'scrubbed' in some way, at least made
5340 * invisible via RIB index before peer session is allowed to be
5341 * brought back up. So one needs to know when such a 'search' is
5342 * complete.
5343 *
5344 * Ideally:
5345 *
5346 * - there'd be a single global queue or a single RIB walker
5347 * - rather than tracking which route_nodes still need to be
5348 * examined on a peer basis, we'd track which peers still
5349 * aren't cleared
5350 *
5351 * Given that our per-peer prefix-counts now should be reliable,
5352 * this may actually be achievable. It doesn't seem to be a huge
5353 * problem at this time,
5354 *
5355 * It is possible that we have multiple paths for a prefix from
5356 * a peer
5357 * if that peer is using AddPath.
5358 */
5359 ain = dest->adj_in;
5360 while (ain) {
5361 ain_next = ain->next;
5362
5363 if (ain->peer == peer)
5364 bgp_adj_in_remove(dest, ain);
5365
5366 ain = ain_next;
5367 }
5368
5369 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5370 next = pi->next;
5371 if (pi->peer != peer)
5372 continue;
5373
5374 if (force)
5375 bgp_path_info_reap(dest, pi);
5376 else {
5377 struct bgp_clear_node_queue *cnq;
5378
5379 /* both unlocked in bgp_clear_node_queue_del */
5380 bgp_table_lock(bgp_dest_table(dest));
5381 bgp_dest_lock_node(dest);
5382 cnq = XCALLOC(
5383 MTYPE_BGP_CLEAR_NODE_QUEUE,
5384 sizeof(struct bgp_clear_node_queue));
5385 cnq->dest = dest;
5386 work_queue_add(peer->clear_node_queue, cnq);
5387 break;
5388 }
5389 }
5390 }
5391 return;
5392}
5393
5394void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5395{
5396 struct bgp_dest *dest;
5397 struct bgp_table *table;
5398
5399 if (peer->clear_node_queue == NULL)
5400 bgp_clear_node_queue_init(peer);
5401
5402 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5403 * Idle until it receives a Clearing_Completed event. This protects
5404 * against peers which flap faster than we can we clear, which could
5405 * lead to:
5406 *
5407 * a) race with routes from the new session being installed before
5408 * clear_route_node visits the node (to delete the route of that
5409 * peer)
5410 * b) resource exhaustion, clear_route_node likely leads to an entry
5411 * on the process_main queue. Fast-flapping could cause that queue
5412 * to grow and grow.
5413 */
5414
5415 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5416 * the unlock will happen upon work-queue completion; other wise, the
5417 * unlock happens at the end of this function.
5418 */
5419 if (!peer->clear_node_queue->thread)
5420 peer_lock(peer);
5421
5422 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5423 bgp_clear_route_table(peer, afi, safi, NULL);
5424 else
5425 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5426 dest = bgp_route_next(dest)) {
5427 table = bgp_dest_get_bgp_table_info(dest);
5428 if (!table)
5429 continue;
5430
5431 bgp_clear_route_table(peer, afi, safi, table);
5432 }
5433
5434 /* unlock if no nodes got added to the clear-node-queue. */
5435 if (!peer->clear_node_queue->thread)
5436 peer_unlock(peer);
5437}
5438
5439void bgp_clear_route_all(struct peer *peer)
5440{
5441 afi_t afi;
5442 safi_t safi;
5443
5444 FOREACH_AFI_SAFI (afi, safi)
5445 bgp_clear_route(peer, afi, safi);
5446
5447#ifdef ENABLE_BGP_VNC
5448 rfapiProcessPeerDown(peer);
5449#endif
5450}
5451
5452void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5453{
5454 struct bgp_table *table;
5455 struct bgp_dest *dest;
5456 struct bgp_adj_in *ain;
5457 struct bgp_adj_in *ain_next;
5458
5459 table = peer->bgp->rib[afi][safi];
5460
5461 /* It is possible that we have multiple paths for a prefix from a peer
5462 * if that peer is using AddPath.
5463 */
5464 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5465 ain = dest->adj_in;
5466
5467 while (ain) {
5468 ain_next = ain->next;
5469
5470 if (ain->peer == peer)
5471 bgp_adj_in_remove(dest, ain);
5472
5473 ain = ain_next;
5474 }
5475 }
5476}
5477
5478/* If any of the routes from the peer have been marked with the NO_LLGR
5479 * community, either as sent by the peer, or as the result of a configured
5480 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5481 * operation of [RFC4271].
5482 */
5483void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5484{
5485 struct bgp_dest *dest;
5486 struct bgp_path_info *pi;
5487 struct bgp_table *table;
5488
5489 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5490 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5491 dest = bgp_route_next(dest)) {
5492 struct bgp_dest *rm;
5493
5494 /* look for neighbor in tables */
5495 table = bgp_dest_get_bgp_table_info(dest);
5496 if (!table)
5497 continue;
5498
5499 for (rm = bgp_table_top(table); rm;
5500 rm = bgp_route_next(rm))
5501 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5502 pi = pi->next) {
5503 if (pi->peer != peer)
5504 continue;
5505 if (CHECK_FLAG(
5506 peer->af_sflags[afi][safi],
5507 PEER_STATUS_LLGR_WAIT) &&
5508 bgp_attr_get_community(pi->attr) &&
5509 !community_include(
5510 bgp_attr_get_community(
5511 pi->attr),
5512 COMMUNITY_NO_LLGR))
5513 continue;
5514 if (!CHECK_FLAG(pi->flags,
5515 BGP_PATH_STALE))
5516 continue;
5517
5518 /*
5519 * If this is VRF leaked route
5520 * process for withdraw.
5521 */
5522 if (pi->sub_type ==
5523 BGP_ROUTE_IMPORTED &&
5524 peer->bgp->inst_type ==
5525 BGP_INSTANCE_TYPE_DEFAULT)
5526 vpn_leak_to_vrf_withdraw(
5527 peer->bgp, pi);
5528
5529 bgp_rib_remove(rm, pi, peer, afi, safi);
5530 break;
5531 }
5532 }
5533 } else {
5534 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5535 dest = bgp_route_next(dest))
5536 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5537 pi = pi->next) {
5538 if (pi->peer != peer)
5539 continue;
5540 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5541 PEER_STATUS_LLGR_WAIT) &&
5542 bgp_attr_get_community(pi->attr) &&
5543 !community_include(
5544 bgp_attr_get_community(pi->attr),
5545 COMMUNITY_NO_LLGR))
5546 continue;
5547 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5548 continue;
5549 if (safi == SAFI_UNICAST &&
5550 (peer->bgp->inst_type ==
5551 BGP_INSTANCE_TYPE_VRF ||
5552 peer->bgp->inst_type ==
5553 BGP_INSTANCE_TYPE_DEFAULT))
5554 vpn_leak_from_vrf_withdraw(
5555 bgp_get_default(), peer->bgp,
5556 pi);
5557
5558 bgp_rib_remove(dest, pi, peer, afi, safi);
5559 break;
5560 }
5561 }
5562}
5563
5564void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5565{
5566 struct bgp_dest *dest, *ndest;
5567 struct bgp_path_info *pi;
5568 struct bgp_table *table;
5569
5570 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5571 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5572 dest = bgp_route_next(dest)) {
5573 table = bgp_dest_get_bgp_table_info(dest);
5574 if (!table)
5575 continue;
5576
5577 for (ndest = bgp_table_top(table); ndest;
5578 ndest = bgp_route_next(ndest)) {
5579 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5580 pi = pi->next) {
5581 if (pi->peer != peer)
5582 continue;
5583
5584 if ((CHECK_FLAG(
5585 peer->af_sflags[afi][safi],
5586 PEER_STATUS_ENHANCED_REFRESH))
5587 && !CHECK_FLAG(pi->flags,
5588 BGP_PATH_STALE)
5589 && !CHECK_FLAG(
5590 pi->flags,
5591 BGP_PATH_UNUSEABLE)) {
5592 if (bgp_debug_neighbor_events(
5593 peer))
5594 zlog_debug(
5595 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5596 peer->host,
5597 afi2str(afi),
5598 safi2str(safi),
5599 bgp_dest_get_prefix(
5600 ndest));
5601
5602 bgp_path_info_set_flag(
5603 ndest, pi,
5604 BGP_PATH_STALE);
5605 }
5606 }
5607 }
5608 }
5609 } else {
5610 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5611 dest = bgp_route_next(dest)) {
5612 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5613 pi = pi->next) {
5614 if (pi->peer != peer)
5615 continue;
5616
5617 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5618 PEER_STATUS_ENHANCED_REFRESH))
5619 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5620 && !CHECK_FLAG(pi->flags,
5621 BGP_PATH_UNUSEABLE)) {
5622 if (bgp_debug_neighbor_events(peer))
5623 zlog_debug(
5624 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5625 peer->host,
5626 afi2str(afi),
5627 safi2str(safi),
5628 bgp_dest_get_prefix(
5629 dest));
5630
5631 bgp_path_info_set_flag(dest, pi,
5632 BGP_PATH_STALE);
5633 }
5634 }
5635 }
5636 }
5637}
5638
5639bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5640{
5641 if (peer->sort == BGP_PEER_IBGP)
5642 return true;
5643
5644 if (peer->sort == BGP_PEER_EBGP
5645 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5646 || FILTER_LIST_OUT_NAME(filter)
5647 || DISTRIBUTE_OUT_NAME(filter)))
5648 return true;
5649 return false;
5650}
5651
5652bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5653{
5654 if (peer->sort == BGP_PEER_IBGP)
5655 return true;
5656
5657 if (peer->sort == BGP_PEER_EBGP
5658 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5659 || FILTER_LIST_IN_NAME(filter)
5660 || DISTRIBUTE_IN_NAME(filter)))
5661 return true;
5662 return false;
5663}
5664
5665static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5666 safi_t safi)
5667{
5668 struct bgp_dest *dest;
5669 struct bgp_path_info *pi;
5670 struct bgp_path_info *next;
5671
5672 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5673 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5674 const struct prefix *p = bgp_dest_get_prefix(dest);
5675
5676 next = pi->next;
5677
5678 /* Unimport EVPN routes from VRFs */
5679 if (safi == SAFI_EVPN)
5680 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5681 SAFI_EVPN, p, pi);
5682
5683 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5684 && pi->type == ZEBRA_ROUTE_BGP
5685 && (pi->sub_type == BGP_ROUTE_NORMAL
5686 || pi->sub_type == BGP_ROUTE_AGGREGATE
5687 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5688
5689 if (bgp_fibupd_safi(safi))
5690 bgp_zebra_withdraw(p, pi, bgp, safi);
5691 }
5692
5693 bgp_path_info_reap(dest, pi);
5694 }
5695}
5696
5697/* Delete all kernel routes. */
5698void bgp_cleanup_routes(struct bgp *bgp)
5699{
5700 afi_t afi;
5701 struct bgp_dest *dest;
5702 struct bgp_table *table;
5703
5704 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5705 if (afi == AFI_L2VPN)
5706 continue;
5707 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5708 SAFI_UNICAST);
5709 /*
5710 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5711 */
5712 if (afi != AFI_L2VPN) {
5713 safi_t safi;
5714 safi = SAFI_MPLS_VPN;
5715 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5716 dest = bgp_route_next(dest)) {
5717 table = bgp_dest_get_bgp_table_info(dest);
5718 if (table != NULL) {
5719 bgp_cleanup_table(bgp, table, safi);
5720 bgp_table_finish(&table);
5721 bgp_dest_set_bgp_table_info(dest, NULL);
5722 bgp_dest_unlock_node(dest);
5723 }
5724 }
5725 safi = SAFI_ENCAP;
5726 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5727 dest = bgp_route_next(dest)) {
5728 table = bgp_dest_get_bgp_table_info(dest);
5729 if (table != NULL) {
5730 bgp_cleanup_table(bgp, table, safi);
5731 bgp_table_finish(&table);
5732 bgp_dest_set_bgp_table_info(dest, NULL);
5733 bgp_dest_unlock_node(dest);
5734 }
5735 }
5736 }
5737 }
5738 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5739 dest = bgp_route_next(dest)) {
5740 table = bgp_dest_get_bgp_table_info(dest);
5741 if (table != NULL) {
5742 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5743 bgp_table_finish(&table);
5744 bgp_dest_set_bgp_table_info(dest, NULL);
5745 bgp_dest_unlock_node(dest);
5746 }
5747 }
5748}
5749
5750void bgp_reset(void)
5751{
5752 vty_reset();
5753 bgp_zclient_reset();
5754 access_list_reset();
5755 prefix_list_reset();
5756}
5757
5758bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5759{
5760 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5761 && CHECK_FLAG(peer->af_cap[afi][safi],
5762 PEER_CAP_ADDPATH_AF_TX_RCV));
5763}
5764
5765/* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5766 value. */
5767int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5768 struct bgp_nlri *packet)
5769{
5770 uint8_t *pnt;
5771 uint8_t *lim;
5772 struct prefix p;
5773 int psize;
5774 int ret;
5775 afi_t afi;
5776 safi_t safi;
5777 bool addpath_capable;
5778 uint32_t addpath_id;
5779
5780 pnt = packet->nlri;
5781 lim = pnt + packet->length;
5782 afi = packet->afi;
5783 safi = packet->safi;
5784 addpath_id = 0;
5785 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5786
5787 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5788 syntactic validity. If the field is syntactically incorrect,
5789 then the Error Subcode is set to Invalid Network Field. */
5790 for (; pnt < lim; pnt += psize) {
5791 /* Clear prefix structure. */
5792 memset(&p, 0, sizeof(p));
5793
5794 if (addpath_capable) {
5795
5796 /* When packet overflow occurs return immediately. */
5797 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5798 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5799
5800 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5801 addpath_id = ntohl(addpath_id);
5802 pnt += BGP_ADDPATH_ID_LEN;
5803 }
5804
5805 /* Fetch prefix length. */
5806 p.prefixlen = *pnt++;
5807 /* afi/safi validity already verified by caller,
5808 * bgp_update_receive */
5809 p.family = afi2family(afi);
5810
5811 /* Prefix length check. */
5812 if (p.prefixlen > prefix_blen(&p) * 8) {
5813 flog_err(
5814 EC_BGP_UPDATE_RCV,
5815 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5816 peer->host, p.prefixlen, packet->afi);
5817 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5818 }
5819
5820 /* Packet size overflow check. */
5821 psize = PSIZE(p.prefixlen);
5822
5823 /* When packet overflow occur return immediately. */
5824 if (pnt + psize > lim) {
5825 flog_err(
5826 EC_BGP_UPDATE_RCV,
5827 "%s [Error] Update packet error (prefix length %d overflows packet)",
5828 peer->host, p.prefixlen);
5829 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5830 }
5831
5832 /* Defensive coding, double-check the psize fits in a struct
5833 * prefix for the v4 and v6 afi's and unicast/multicast */
5834 if (psize > (ssize_t)sizeof(p.u.val)) {
5835 flog_err(
5836 EC_BGP_UPDATE_RCV,
5837 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5838 peer->host, p.prefixlen, sizeof(p.u.val));
5839 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5840 }
5841
5842 /* Fetch prefix from NLRI packet. */
5843 memcpy(p.u.val, pnt, psize);
5844
5845 /* Check address. */
5846 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5847 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5848 /* From RFC4271 Section 6.3:
5849 *
5850 * If a prefix in the NLRI field is semantically
5851 * incorrect
5852 * (e.g., an unexpected multicast IP address),
5853 * an error SHOULD
5854 * be logged locally, and the prefix SHOULD be
5855 * ignored.
5856 */
5857 flog_err(
5858 EC_BGP_UPDATE_RCV,
5859 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5860 peer->host, &p.u.prefix4);
5861 continue;
5862 }
5863 }
5864
5865 /* Check address. */
5866 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5867 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5868 flog_err(
5869 EC_BGP_UPDATE_RCV,
5870 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
5871 peer->host, &p.u.prefix6);
5872
5873 continue;
5874 }
5875 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5876 flog_err(
5877 EC_BGP_UPDATE_RCV,
5878 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
5879 peer->host, &p.u.prefix6);
5880
5881 continue;
5882 }
5883 }
5884
5885 /* Normal process. */
5886 if (attr)
5887 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5888 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5889 NULL, NULL, 0, 0, NULL);
5890 else
5891 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5892 safi, ZEBRA_ROUTE_BGP,
5893 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5894 NULL);
5895
5896 /* Do not send BGP notification twice when maximum-prefix count
5897 * overflow. */
5898 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5899 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5900
5901 /* Address family configuration mismatch. */
5902 if (ret < 0)
5903 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5904 }
5905
5906 /* Packet length consistency check. */
5907 if (pnt != lim) {
5908 flog_err(
5909 EC_BGP_UPDATE_RCV,
5910 "%s [Error] Update packet error (prefix length mismatch with total length)",
5911 peer->host);
5912 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5913 }
5914
5915 return BGP_NLRI_PARSE_OK;
5916}
5917
5918static struct bgp_static *bgp_static_new(void)
5919{
5920 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5921}
5922
5923static void bgp_static_free(struct bgp_static *bgp_static)
5924{
5925 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5926 route_map_counter_decrement(bgp_static->rmap.map);
5927
5928 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5929 XFREE(MTYPE_BGP_STATIC, bgp_static);
5930}
5931
5932void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5933 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5934{
5935 struct bgp_dest *dest;
5936 struct bgp_path_info *pi;
5937 struct bgp_path_info *new;
5938 struct bgp_path_info rmap_path;
5939 struct attr attr;
5940 struct attr *attr_new;
5941 route_map_result_t ret;
5942#ifdef ENABLE_BGP_VNC
5943 int vnc_implicit_withdraw = 0;
5944#endif
5945
5946 assert(bgp_static);
5947
5948 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5949
5950 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
5951
5952 attr.nexthop = bgp_static->igpnexthop;
5953 attr.med = bgp_static->igpmetric;
5954 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5955
5956 if (afi == AFI_IP)
5957 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
5958
5959 if (bgp_static->atomic)
5960 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5961
5962 /* Store label index, if required. */
5963 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5964 attr.label_index = bgp_static->label_index;
5965 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5966 }
5967
5968 /* Apply route-map. */
5969 if (bgp_static->rmap.name) {
5970 struct attr attr_tmp = attr;
5971
5972 memset(&rmap_path, 0, sizeof(rmap_path));
5973 rmap_path.peer = bgp->peer_self;
5974 rmap_path.attr = &attr_tmp;
5975
5976 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5977
5978 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5979
5980 bgp->peer_self->rmap_type = 0;
5981
5982 if (ret == RMAP_DENYMATCH) {
5983 /* Free uninterned attribute. */
5984 bgp_attr_flush(&attr_tmp);
5985
5986 /* Unintern original. */
5987 aspath_unintern(&attr.aspath);
5988 bgp_static_withdraw(bgp, p, afi, safi);
5989 return;
5990 }
5991
5992 if (bgp_in_graceful_shutdown(bgp))
5993 bgp_attr_add_gshut_community(&attr_tmp);
5994
5995 attr_new = bgp_attr_intern(&attr_tmp);
5996 } else {
5997
5998 if (bgp_in_graceful_shutdown(bgp))
5999 bgp_attr_add_gshut_community(&attr);
6000
6001 attr_new = bgp_attr_intern(&attr);
6002 }
6003
6004 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6005 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6006 && pi->sub_type == BGP_ROUTE_STATIC)
6007 break;
6008
6009 if (pi) {
6010 if (attrhash_cmp(pi->attr, attr_new)
6011 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6012 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6013 bgp_dest_unlock_node(dest);
6014 bgp_attr_unintern(&attr_new);
6015 aspath_unintern(&attr.aspath);
6016 return;
6017 } else {
6018 /* The attribute is changed. */
6019 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6020
6021 /* Rewrite BGP route information. */
6022 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6023 bgp_path_info_restore(dest, pi);
6024 else
6025 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6026#ifdef ENABLE_BGP_VNC
6027 if ((afi == AFI_IP || afi == AFI_IP6)
6028 && (safi == SAFI_UNICAST)) {
6029 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6030 /*
6031 * Implicit withdraw case.
6032 * We have to do this before pi is
6033 * changed
6034 */
6035 ++vnc_implicit_withdraw;
6036 vnc_import_bgp_del_route(bgp, p, pi);
6037 vnc_import_bgp_exterior_del_route(
6038 bgp, p, pi);
6039 }
6040 }
6041#endif
6042 bgp_attr_unintern(&pi->attr);
6043 pi->attr = attr_new;
6044 pi->uptime = monotime(NULL);
6045#ifdef ENABLE_BGP_VNC
6046 if ((afi == AFI_IP || afi == AFI_IP6)
6047 && (safi == SAFI_UNICAST)) {
6048 if (vnc_implicit_withdraw) {
6049 vnc_import_bgp_add_route(bgp, p, pi);
6050 vnc_import_bgp_exterior_add_route(
6051 bgp, p, pi);
6052 }
6053 }
6054#endif
6055
6056 /* Nexthop reachability check. */
6057 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6058 && (safi == SAFI_UNICAST
6059 || safi == SAFI_LABELED_UNICAST)) {
6060
6061 struct bgp *bgp_nexthop = bgp;
6062
6063 if (pi->extra && pi->extra->bgp_orig)
6064 bgp_nexthop = pi->extra->bgp_orig;
6065
6066 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6067 afi, safi, pi, NULL,
6068 0, p))
6069 bgp_path_info_set_flag(dest, pi,
6070 BGP_PATH_VALID);
6071 else {
6072 if (BGP_DEBUG(nht, NHT)) {
6073 char buf1[INET6_ADDRSTRLEN];
6074 inet_ntop(p->family,
6075 &p->u.prefix, buf1,
6076 INET6_ADDRSTRLEN);
6077 zlog_debug(
6078 "%s(%s): Route not in table, not advertising",
6079 __func__, buf1);
6080 }
6081 bgp_path_info_unset_flag(
6082 dest, pi, BGP_PATH_VALID);
6083 }
6084 } else {
6085 /* Delete the NHT structure if any, if we're
6086 * toggling between
6087 * enabling/disabling import check. We
6088 * deregister the route
6089 * from NHT to avoid overloading NHT and the
6090 * process interaction
6091 */
6092 bgp_unlink_nexthop(pi);
6093 bgp_path_info_set_flag(dest, pi,
6094 BGP_PATH_VALID);
6095 }
6096 /* Process change. */
6097 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6098 bgp_process(bgp, dest, afi, safi);
6099
6100 if (SAFI_UNICAST == safi
6101 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6102 || bgp->inst_type
6103 == BGP_INSTANCE_TYPE_DEFAULT)) {
6104 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6105 pi);
6106 }
6107
6108 bgp_dest_unlock_node(dest);
6109 aspath_unintern(&attr.aspath);
6110 return;
6111 }
6112 }
6113
6114 /* Make new BGP info. */
6115 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6116 attr_new, dest);
6117 /* Nexthop reachability check. */
6118 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6119 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6120 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6121 p))
6122 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6123 else {
6124 if (BGP_DEBUG(nht, NHT)) {
6125 char buf1[INET6_ADDRSTRLEN];
6126 inet_ntop(p->family, &p->u.prefix, buf1,
6127 INET6_ADDRSTRLEN);
6128 zlog_debug(
6129 "%s(%s): Route not in table, not advertising",
6130 __func__, buf1);
6131 }
6132 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6133 }
6134 } else {
6135 /* Delete the NHT structure if any, if we're toggling between
6136 * enabling/disabling import check. We deregister the route
6137 * from NHT to avoid overloading NHT and the process interaction
6138 */
6139 bgp_unlink_nexthop(new);
6140
6141 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6142 }
6143
6144 /* Aggregate address increment. */
6145 bgp_aggregate_increment(bgp, p, new, afi, safi);
6146
6147 /* Register new BGP information. */
6148 bgp_path_info_add(dest, new);
6149
6150 /* route_node_get lock */
6151 bgp_dest_unlock_node(dest);
6152
6153 /* Process change. */
6154 bgp_process(bgp, dest, afi, safi);
6155
6156 if (SAFI_UNICAST == safi
6157 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6158 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6159 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6160 }
6161
6162 /* Unintern original. */
6163 aspath_unintern(&attr.aspath);
6164}
6165
6166void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6167 safi_t safi)
6168{
6169 struct bgp_dest *dest;
6170 struct bgp_path_info *pi;
6171
6172 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6173
6174 /* Check selected route and self inserted route. */
6175 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6176 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6177 && pi->sub_type == BGP_ROUTE_STATIC)
6178 break;
6179
6180 /* Withdraw static BGP route from routing table. */
6181 if (pi) {
6182 if (SAFI_UNICAST == safi
6183 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6184 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6185 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6186 }
6187 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6188 bgp_unlink_nexthop(pi);
6189 bgp_path_info_delete(dest, pi);
6190 bgp_process(bgp, dest, afi, safi);
6191 }
6192
6193 /* Unlock bgp_node_lookup. */
6194 bgp_dest_unlock_node(dest);
6195}
6196
6197/*
6198 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6199 */
6200static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6201 afi_t afi, safi_t safi,
6202 struct prefix_rd *prd)
6203{
6204 struct bgp_dest *dest;
6205 struct bgp_path_info *pi;
6206
6207 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6208
6209 /* Check selected route and self inserted route. */
6210 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6211 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6212 && pi->sub_type == BGP_ROUTE_STATIC)
6213 break;
6214
6215 /* Withdraw static BGP route from routing table. */
6216 if (pi) {
6217#ifdef ENABLE_BGP_VNC
6218 rfapiProcessWithdraw(
6219 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6220 1); /* Kill, since it is an administrative change */
6221#endif
6222 if (SAFI_MPLS_VPN == safi
6223 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6224 vpn_leak_to_vrf_withdraw(bgp, pi);
6225 }
6226 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6227 bgp_path_info_delete(dest, pi);
6228 bgp_process(bgp, dest, afi, safi);
6229 }
6230
6231 /* Unlock bgp_node_lookup. */
6232 bgp_dest_unlock_node(dest);
6233}
6234
6235static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6236 struct bgp_static *bgp_static, afi_t afi,
6237 safi_t safi)
6238{
6239 struct bgp_dest *dest;
6240 struct bgp_path_info *new;
6241 struct attr *attr_new;
6242 struct attr attr = {0};
6243 struct bgp_path_info *pi;
6244#ifdef ENABLE_BGP_VNC
6245 mpls_label_t label = 0;
6246#endif
6247 uint32_t num_labels = 0;
6248
6249 assert(bgp_static);
6250
6251 if (bgp_static->label != MPLS_INVALID_LABEL)
6252 num_labels = 1;
6253 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6254 &bgp_static->prd);
6255
6256 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6257
6258 attr.nexthop = bgp_static->igpnexthop;
6259 attr.med = bgp_static->igpmetric;
6260 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6261
6262 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6263 || (safi == SAFI_ENCAP)) {
6264 if (afi == AFI_IP) {
6265 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6266 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6267 }
6268 }
6269 if (afi == AFI_L2VPN) {
6270 if (bgp_static->gatewayIp.family == AF_INET) {
6271 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6272 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6273 &bgp_static->gatewayIp.u.prefix4,
6274 IPV4_MAX_BYTELEN);
6275 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6276 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6277 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6278 &bgp_static->gatewayIp.u.prefix6,
6279 IPV6_MAX_BYTELEN);
6280 }
6281 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6282 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6283 struct bgp_encap_type_vxlan bet;
6284 memset(&bet, 0, sizeof(bet));
6285 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6286 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6287 }
6288 if (bgp_static->router_mac) {
6289 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6290 }
6291 }
6292 /* Apply route-map. */
6293 if (bgp_static->rmap.name) {
6294 struct attr attr_tmp = attr;
6295 struct bgp_path_info rmap_path;
6296 route_map_result_t ret;
6297
6298 rmap_path.peer = bgp->peer_self;
6299 rmap_path.attr = &attr_tmp;
6300
6301 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6302
6303 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6304
6305 bgp->peer_self->rmap_type = 0;
6306
6307 if (ret == RMAP_DENYMATCH) {
6308 /* Free uninterned attribute. */
6309 bgp_attr_flush(&attr_tmp);
6310
6311 /* Unintern original. */
6312 aspath_unintern(&attr.aspath);
6313 bgp_static_withdraw_safi(bgp, p, afi, safi,
6314 &bgp_static->prd);
6315 return;
6316 }
6317
6318 attr_new = bgp_attr_intern(&attr_tmp);
6319 } else {
6320 attr_new = bgp_attr_intern(&attr);
6321 }
6322
6323 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6324 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6325 && pi->sub_type == BGP_ROUTE_STATIC)
6326 break;
6327
6328 if (pi) {
6329 if (attrhash_cmp(pi->attr, attr_new)
6330 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6331 bgp_dest_unlock_node(dest);
6332 bgp_attr_unintern(&attr_new);
6333 aspath_unintern(&attr.aspath);
6334 return;
6335 } else {
6336 /* The attribute is changed. */
6337 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6338
6339 /* Rewrite BGP route information. */
6340 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6341 bgp_path_info_restore(dest, pi);
6342 else
6343 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6344 bgp_attr_unintern(&pi->attr);
6345 pi->attr = attr_new;
6346 pi->uptime = monotime(NULL);
6347#ifdef ENABLE_BGP_VNC
6348 if (pi->extra)
6349 label = decode_label(&pi->extra->label[0]);
6350#endif
6351
6352 /* Process change. */
6353 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6354 bgp_process(bgp, dest, afi, safi);
6355
6356 if (SAFI_MPLS_VPN == safi
6357 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6358 vpn_leak_to_vrf_update(bgp, pi);
6359 }
6360#ifdef ENABLE_BGP_VNC
6361 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6362 pi->attr, afi, safi, pi->type,
6363 pi->sub_type, &label);
6364#endif
6365 bgp_dest_unlock_node(dest);
6366 aspath_unintern(&attr.aspath);
6367 return;
6368 }
6369 }
6370
6371
6372 /* Make new BGP info. */
6373 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6374 attr_new, dest);
6375 SET_FLAG(new->flags, BGP_PATH_VALID);
6376 bgp_path_info_extra_get(new);
6377 if (num_labels) {
6378 new->extra->label[0] = bgp_static->label;
6379 new->extra->num_labels = num_labels;
6380 }
6381#ifdef ENABLE_BGP_VNC
6382 label = decode_label(&bgp_static->label);
6383#endif
6384
6385 /* Aggregate address increment. */
6386 bgp_aggregate_increment(bgp, p, new, afi, safi);
6387
6388 /* Register new BGP information. */
6389 bgp_path_info_add(dest, new);
6390 /* route_node_get lock */
6391 bgp_dest_unlock_node(dest);
6392
6393 /* Process change. */
6394 bgp_process(bgp, dest, afi, safi);
6395
6396 if (SAFI_MPLS_VPN == safi
6397 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6398 vpn_leak_to_vrf_update(bgp, new);
6399 }
6400#ifdef ENABLE_BGP_VNC
6401 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6402 safi, new->type, new->sub_type, &label);
6403#endif
6404
6405 /* Unintern original. */
6406 aspath_unintern(&attr.aspath);
6407}
6408
6409/* Configure static BGP network. When user don't run zebra, static
6410 route should be installed as valid. */
6411static int bgp_static_set(struct vty *vty, const char *negate,
6412 const char *ip_str, afi_t afi, safi_t safi,
6413 const char *rmap, int backdoor, uint32_t label_index)
6414{
6415 VTY_DECLVAR_CONTEXT(bgp, bgp);
6416 int ret;
6417 struct prefix p;
6418 struct bgp_static *bgp_static;
6419 struct bgp_dest *dest;
6420 uint8_t need_update = 0;
6421
6422 /* Convert IP prefix string to struct prefix. */
6423 ret = str2prefix(ip_str, &p);
6424 if (!ret) {
6425 vty_out(vty, "%% Malformed prefix\n");
6426 return CMD_WARNING_CONFIG_FAILED;
6427 }
6428 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6429 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6430 return CMD_WARNING_CONFIG_FAILED;
6431 }
6432
6433 apply_mask(&p);
6434
6435 if (negate) {
6436
6437 /* Set BGP static route configuration. */
6438 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6439
6440 if (!dest) {
6441 vty_out(vty, "%% Can't find static route specified\n");
6442 return CMD_WARNING_CONFIG_FAILED;
6443 }
6444
6445 bgp_static = bgp_dest_get_bgp_static_info(dest);
6446
6447 if ((label_index != BGP_INVALID_LABEL_INDEX)
6448 && (label_index != bgp_static->label_index)) {
6449 vty_out(vty,
6450 "%% label-index doesn't match static route\n");
6451 bgp_dest_unlock_node(dest);
6452 return CMD_WARNING_CONFIG_FAILED;
6453 }
6454
6455 if ((rmap && bgp_static->rmap.name)
6456 && strcmp(rmap, bgp_static->rmap.name)) {
6457 vty_out(vty,
6458 "%% route-map name doesn't match static route\n");
6459 bgp_dest_unlock_node(dest);
6460 return CMD_WARNING_CONFIG_FAILED;
6461 }
6462
6463 /* Update BGP RIB. */
6464 if (!bgp_static->backdoor)
6465 bgp_static_withdraw(bgp, &p, afi, safi);
6466
6467 /* Clear configuration. */
6468 bgp_static_free(bgp_static);
6469 bgp_dest_set_bgp_static_info(dest, NULL);
6470 bgp_dest_unlock_node(dest);
6471 bgp_dest_unlock_node(dest);
6472 } else {
6473
6474 /* Set BGP static route configuration. */
6475 dest = bgp_node_get(bgp->route[afi][safi], &p);
6476 bgp_static = bgp_dest_get_bgp_static_info(dest);
6477 if (bgp_static) {
6478 /* Configuration change. */
6479 /* Label index cannot be changed. */
6480 if (bgp_static->label_index != label_index) {
6481 vty_out(vty, "%% cannot change label-index\n");
6482 return CMD_WARNING_CONFIG_FAILED;
6483 }
6484
6485 /* Check previous routes are installed into BGP. */
6486 if (bgp_static->valid
6487 && bgp_static->backdoor != backdoor)
6488 need_update = 1;
6489
6490 bgp_static->backdoor = backdoor;
6491
6492 if (rmap) {
6493 XFREE(MTYPE_ROUTE_MAP_NAME,
6494 bgp_static->rmap.name);
6495 route_map_counter_decrement(
6496 bgp_static->rmap.map);
6497 bgp_static->rmap.name =
6498 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6499 bgp_static->rmap.map =
6500 route_map_lookup_by_name(rmap);
6501 route_map_counter_increment(
6502 bgp_static->rmap.map);
6503 } else {
6504 XFREE(MTYPE_ROUTE_MAP_NAME,
6505 bgp_static->rmap.name);
6506 route_map_counter_decrement(
6507 bgp_static->rmap.map);
6508 bgp_static->rmap.map = NULL;
6509 bgp_static->valid = 0;
6510 }
6511 bgp_dest_unlock_node(dest);
6512 } else {
6513 /* New configuration. */
6514 bgp_static = bgp_static_new();
6515 bgp_static->backdoor = backdoor;
6516 bgp_static->valid = 0;
6517 bgp_static->igpmetric = 0;
6518 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6519 bgp_static->label_index = label_index;
6520
6521 if (rmap) {
6522 XFREE(MTYPE_ROUTE_MAP_NAME,
6523 bgp_static->rmap.name);
6524 route_map_counter_decrement(
6525 bgp_static->rmap.map);
6526 bgp_static->rmap.name =
6527 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6528 bgp_static->rmap.map =
6529 route_map_lookup_by_name(rmap);
6530 route_map_counter_increment(
6531 bgp_static->rmap.map);
6532 }
6533 bgp_dest_set_bgp_static_info(dest, bgp_static);
6534 }
6535
6536 bgp_static->valid = 1;
6537 if (need_update)
6538 bgp_static_withdraw(bgp, &p, afi, safi);
6539
6540 if (!bgp_static->backdoor)
6541 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6542 }
6543
6544 return CMD_SUCCESS;
6545}
6546
6547void bgp_static_add(struct bgp *bgp)
6548{
6549 afi_t afi;
6550 safi_t safi;
6551 struct bgp_dest *dest;
6552 struct bgp_dest *rm;
6553 struct bgp_table *table;
6554 struct bgp_static *bgp_static;
6555
6556 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6557 FOREACH_AFI_SAFI (afi, safi)
6558 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6559 dest = bgp_route_next(dest)) {
6560 if (!bgp_dest_has_bgp_path_info_data(dest))
6561 continue;
6562
6563 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6564 || (safi == SAFI_EVPN)) {
6565 table = bgp_dest_get_bgp_table_info(dest);
6566
6567 for (rm = bgp_table_top(table); rm;
6568 rm = bgp_route_next(rm)) {
6569 bgp_static =
6570 bgp_dest_get_bgp_static_info(
6571 rm);
6572 bgp_static_update_safi(
6573 bgp, bgp_dest_get_prefix(rm),
6574 bgp_static, afi, safi);
6575 }
6576 } else {
6577 bgp_static_update(
6578 bgp, bgp_dest_get_prefix(dest),
6579 bgp_dest_get_bgp_static_info(dest), afi,
6580 safi);
6581 }
6582 }
6583 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6584}
6585
6586/* Called from bgp_delete(). Delete all static routes from the BGP
6587 instance. */
6588void bgp_static_delete(struct bgp *bgp)
6589{
6590 afi_t afi;
6591 safi_t safi;
6592 struct bgp_dest *dest;
6593 struct bgp_dest *rm;
6594 struct bgp_table *table;
6595 struct bgp_static *bgp_static;
6596
6597 FOREACH_AFI_SAFI (afi, safi)
6598 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6599 dest = bgp_route_next(dest)) {
6600 if (!bgp_dest_has_bgp_path_info_data(dest))
6601 continue;
6602
6603 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6604 || (safi == SAFI_EVPN)) {
6605 table = bgp_dest_get_bgp_table_info(dest);
6606
6607 for (rm = bgp_table_top(table); rm;
6608 rm = bgp_route_next(rm)) {
6609 bgp_static =
6610 bgp_dest_get_bgp_static_info(
6611 rm);
6612 if (!bgp_static)
6613 continue;
6614
6615 bgp_static_withdraw_safi(
6616 bgp, bgp_dest_get_prefix(rm),
6617 AFI_IP, safi,
6618 (struct prefix_rd *)
6619 bgp_dest_get_prefix(
6620 dest));
6621 bgp_static_free(bgp_static);
6622 bgp_dest_set_bgp_static_info(rm,
6623 NULL);
6624 bgp_dest_unlock_node(rm);
6625 }
6626 } else {
6627 bgp_static = bgp_dest_get_bgp_static_info(dest);
6628 bgp_static_withdraw(bgp,
6629 bgp_dest_get_prefix(dest),
6630 afi, safi);
6631 bgp_static_free(bgp_static);
6632 bgp_dest_set_bgp_static_info(dest, NULL);
6633 bgp_dest_unlock_node(dest);
6634 }
6635 }
6636}
6637
6638void bgp_static_redo_import_check(struct bgp *bgp)
6639{
6640 afi_t afi;
6641 safi_t safi;
6642 struct bgp_dest *dest;
6643 struct bgp_dest *rm;
6644 struct bgp_table *table;
6645 struct bgp_static *bgp_static;
6646
6647 /* Use this flag to force reprocessing of the route */
6648 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6649 FOREACH_AFI_SAFI (afi, safi) {
6650 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6651 dest = bgp_route_next(dest)) {
6652 if (!bgp_dest_has_bgp_path_info_data(dest))
6653 continue;
6654
6655 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6656 || (safi == SAFI_EVPN)) {
6657 table = bgp_dest_get_bgp_table_info(dest);
6658
6659 for (rm = bgp_table_top(table); rm;
6660 rm = bgp_route_next(rm)) {
6661 bgp_static =
6662 bgp_dest_get_bgp_static_info(
6663 rm);
6664 bgp_static_update_safi(
6665 bgp, bgp_dest_get_prefix(rm),
6666 bgp_static, afi, safi);
6667 }
6668 } else {
6669 bgp_static = bgp_dest_get_bgp_static_info(dest);
6670 bgp_static_update(bgp,
6671 bgp_dest_get_prefix(dest),
6672 bgp_static, afi, safi);
6673 }
6674 }
6675 }
6676 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6677}
6678
6679static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6680 safi_t safi)
6681{
6682 struct bgp_table *table;
6683 struct bgp_dest *dest;
6684 struct bgp_path_info *pi;
6685
6686 /* Do not install the aggregate route if BGP is in the
6687 * process of termination.
6688 */
6689 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6690 || (bgp->peer_self == NULL))
6691 return;
6692
6693 table = bgp->rib[afi][safi];
6694 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6695 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6696 if (pi->peer == bgp->peer_self
6697 && ((pi->type == ZEBRA_ROUTE_BGP
6698 && pi->sub_type == BGP_ROUTE_STATIC)
6699 || (pi->type != ZEBRA_ROUTE_BGP
6700 && pi->sub_type
6701 == BGP_ROUTE_REDISTRIBUTE))) {
6702 bgp_aggregate_decrement(
6703 bgp, bgp_dest_get_prefix(dest), pi, afi,
6704 safi);
6705 bgp_unlink_nexthop(pi);
6706 bgp_path_info_delete(dest, pi);
6707 bgp_process(bgp, dest, afi, safi);
6708 }
6709 }
6710 }
6711}
6712
6713/*
6714 * Purge all networks and redistributed routes from routing table.
6715 * Invoked upon the instance going down.
6716 */
6717void bgp_purge_static_redist_routes(struct bgp *bgp)
6718{
6719 afi_t afi;
6720 safi_t safi;
6721
6722 FOREACH_AFI_SAFI (afi, safi)
6723 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6724}
6725
6726/*
6727 * gpz 110624
6728 * Currently this is used to set static routes for VPN and ENCAP.
6729 * I think it can probably be factored with bgp_static_set.
6730 */
6731int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6732 const char *ip_str, const char *rd_str,
6733 const char *label_str, const char *rmap_str,
6734 int evpn_type, const char *esi, const char *gwip,
6735 const char *ethtag, const char *routermac)
6736{
6737 VTY_DECLVAR_CONTEXT(bgp, bgp);
6738 int ret;
6739 struct prefix p;
6740 struct prefix_rd prd;
6741 struct bgp_dest *pdest;
6742 struct bgp_dest *dest;
6743 struct bgp_table *table;
6744 struct bgp_static *bgp_static;
6745 mpls_label_t label = MPLS_INVALID_LABEL;
6746 struct prefix gw_ip;
6747
6748 /* validate ip prefix */
6749 ret = str2prefix(ip_str, &p);
6750 if (!ret) {
6751 vty_out(vty, "%% Malformed prefix\n");
6752 return CMD_WARNING_CONFIG_FAILED;
6753 }
6754 apply_mask(&p);
6755 if ((afi == AFI_L2VPN)
6756 && (bgp_build_evpn_prefix(evpn_type,
6757 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6758 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6759 return CMD_WARNING_CONFIG_FAILED;
6760 }
6761
6762 ret = str2prefix_rd(rd_str, &prd);
6763 if (!ret) {
6764 vty_out(vty, "%% Malformed rd\n");
6765 return CMD_WARNING_CONFIG_FAILED;
6766 }
6767
6768 if (label_str) {
6769 unsigned long label_val;
6770 label_val = strtoul(label_str, NULL, 10);
6771 encode_label(label_val, &label);
6772 }
6773
6774 if (safi == SAFI_EVPN) {
6775 if (esi && str2esi(esi, NULL) == 0) {
6776 vty_out(vty, "%% Malformed ESI\n");
6777 return CMD_WARNING_CONFIG_FAILED;
6778 }
6779 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6780 vty_out(vty, "%% Malformed Router MAC\n");
6781 return CMD_WARNING_CONFIG_FAILED;
6782 }
6783 if (gwip) {
6784 memset(&gw_ip, 0, sizeof(gw_ip));
6785 ret = str2prefix(gwip, &gw_ip);
6786 if (!ret) {
6787 vty_out(vty, "%% Malformed GatewayIp\n");
6788 return CMD_WARNING_CONFIG_FAILED;
6789 }
6790 if ((gw_ip.family == AF_INET
6791 && is_evpn_prefix_ipaddr_v6(
6792 (struct prefix_evpn *)&p))
6793 || (gw_ip.family == AF_INET6
6794 && is_evpn_prefix_ipaddr_v4(
6795 (struct prefix_evpn *)&p))) {
6796 vty_out(vty,
6797 "%% GatewayIp family differs with IP prefix\n");
6798 return CMD_WARNING_CONFIG_FAILED;
6799 }
6800 }
6801 }
6802 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6803 if (!bgp_dest_has_bgp_path_info_data(pdest))
6804 bgp_dest_set_bgp_table_info(pdest,
6805 bgp_table_init(bgp, afi, safi));
6806 table = bgp_dest_get_bgp_table_info(pdest);
6807
6808 dest = bgp_node_get(table, &p);
6809
6810 if (bgp_dest_has_bgp_path_info_data(dest)) {
6811 vty_out(vty, "%% Same network configuration exists\n");
6812 bgp_dest_unlock_node(dest);
6813 } else {
6814 /* New configuration. */
6815 bgp_static = bgp_static_new();
6816 bgp_static->backdoor = 0;
6817 bgp_static->valid = 0;
6818 bgp_static->igpmetric = 0;
6819 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6820 bgp_static->label = label;
6821 bgp_static->prd = prd;
6822
6823 if (rmap_str) {
6824 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6825 route_map_counter_decrement(bgp_static->rmap.map);
6826 bgp_static->rmap.name =
6827 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6828 bgp_static->rmap.map =
6829 route_map_lookup_by_name(rmap_str);
6830 route_map_counter_increment(bgp_static->rmap.map);
6831 }
6832
6833 if (safi == SAFI_EVPN) {
6834 if (esi) {
6835 bgp_static->eth_s_id =
6836 XCALLOC(MTYPE_ATTR,
6837 sizeof(esi_t));
6838 str2esi(esi, bgp_static->eth_s_id);
6839 }
6840 if (routermac) {
6841 bgp_static->router_mac =
6842 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6843 (void)prefix_str2mac(routermac,
6844 bgp_static->router_mac);
6845 }
6846 if (gwip)
6847 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6848 }
6849 bgp_dest_set_bgp_static_info(dest, bgp_static);
6850
6851 bgp_static->valid = 1;
6852 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6853 }
6854
6855 return CMD_SUCCESS;
6856}
6857
6858/* Configure static BGP network. */
6859int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6860 const char *ip_str, const char *rd_str,
6861 const char *label_str, int evpn_type, const char *esi,
6862 const char *gwip, const char *ethtag)
6863{
6864 VTY_DECLVAR_CONTEXT(bgp, bgp);
6865 int ret;
6866 struct prefix p;
6867 struct prefix_rd prd;
6868 struct bgp_dest *pdest;
6869 struct bgp_dest *dest;
6870 struct bgp_table *table;
6871 struct bgp_static *bgp_static;
6872 mpls_label_t label = MPLS_INVALID_LABEL;
6873
6874 /* Convert IP prefix string to struct prefix. */
6875 ret = str2prefix(ip_str, &p);
6876 if (!ret) {
6877 vty_out(vty, "%% Malformed prefix\n");
6878 return CMD_WARNING_CONFIG_FAILED;
6879 }
6880 apply_mask(&p);
6881 if ((afi == AFI_L2VPN)
6882 && (bgp_build_evpn_prefix(evpn_type,
6883 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6884 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6885 return CMD_WARNING_CONFIG_FAILED;
6886 }
6887 ret = str2prefix_rd(rd_str, &prd);
6888 if (!ret) {
6889 vty_out(vty, "%% Malformed rd\n");
6890 return CMD_WARNING_CONFIG_FAILED;
6891 }
6892
6893 if (label_str) {
6894 unsigned long label_val;
6895 label_val = strtoul(label_str, NULL, 10);
6896 encode_label(label_val, &label);
6897 }
6898
6899 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6900 if (!bgp_dest_has_bgp_path_info_data(pdest))
6901 bgp_dest_set_bgp_table_info(pdest,
6902 bgp_table_init(bgp, afi, safi));
6903 else
6904 bgp_dest_unlock_node(pdest);
6905 table = bgp_dest_get_bgp_table_info(pdest);
6906
6907 dest = bgp_node_lookup(table, &p);
6908
6909 if (dest) {
6910 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6911
6912 bgp_static = bgp_dest_get_bgp_static_info(dest);
6913 bgp_static_free(bgp_static);
6914 bgp_dest_set_bgp_static_info(dest, NULL);
6915 bgp_dest_unlock_node(dest);
6916 bgp_dest_unlock_node(dest);
6917 } else
6918 vty_out(vty, "%% Can't find the route\n");
6919
6920 return CMD_SUCCESS;
6921}
6922
6923static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6924 const char *rmap_name)
6925{
6926 VTY_DECLVAR_CONTEXT(bgp, bgp);
6927 struct bgp_rmap *rmap;
6928
6929 rmap = &bgp->table_map[afi][safi];
6930 if (rmap_name) {
6931 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6932 route_map_counter_decrement(rmap->map);
6933 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6934 rmap->map = route_map_lookup_by_name(rmap_name);
6935 route_map_counter_increment(rmap->map);
6936 } else {
6937 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6938 route_map_counter_decrement(rmap->map);
6939 rmap->map = NULL;
6940 }
6941
6942 if (bgp_fibupd_safi(safi))
6943 bgp_zebra_announce_table(bgp, afi, safi);
6944
6945 return CMD_SUCCESS;
6946}
6947
6948static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6949 const char *rmap_name)
6950{
6951 VTY_DECLVAR_CONTEXT(bgp, bgp);
6952 struct bgp_rmap *rmap;
6953
6954 rmap = &bgp->table_map[afi][safi];
6955 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6956 route_map_counter_decrement(rmap->map);
6957 rmap->map = NULL;
6958
6959 if (bgp_fibupd_safi(safi))
6960 bgp_zebra_announce_table(bgp, afi, safi);
6961
6962 return CMD_SUCCESS;
6963}
6964
6965void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6966 safi_t safi)
6967{
6968 if (bgp->table_map[afi][safi].name) {
6969 vty_out(vty, " table-map %s\n",
6970 bgp->table_map[afi][safi].name);
6971 }
6972}
6973
6974DEFUN (bgp_table_map,
6975 bgp_table_map_cmd,
6976 "table-map WORD",
6977 "BGP table to RIB route download filter\n"
6978 "Name of the route map\n")
6979{
6980 int idx_word = 1;
6981 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6982 argv[idx_word]->arg);
6983}
6984DEFUN (no_bgp_table_map,
6985 no_bgp_table_map_cmd,
6986 "no table-map WORD",
6987 NO_STR
6988 "BGP table to RIB route download filter\n"
6989 "Name of the route map\n")
6990{
6991 int idx_word = 2;
6992 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6993 argv[idx_word]->arg);
6994}
6995
6996DEFPY(bgp_network,
6997 bgp_network_cmd,
6998 "[no] network \
6999 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7000 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7001 backdoor$backdoor}]",
7002 NO_STR
7003 "Specify a network to announce via BGP\n"
7004 "IPv4 prefix\n"
7005 "Network number\n"
7006 "Network mask\n"
7007 "Network mask\n"
7008 "Route-map to modify the attributes\n"
7009 "Name of the route map\n"
7010 "Label index to associate with the prefix\n"
7011 "Label index value\n"
7012 "Specify a BGP backdoor route\n")
7013{
7014 char addr_prefix_str[BUFSIZ];
7015
7016 if (address_str) {
7017 int ret;
7018
7019 ret = netmask_str2prefix_str(address_str, netmask_str,
7020 addr_prefix_str,
7021 sizeof(addr_prefix_str));
7022 if (!ret) {
7023 vty_out(vty, "%% Inconsistent address and mask\n");
7024 return CMD_WARNING_CONFIG_FAILED;
7025 }
7026 }
7027
7028 return bgp_static_set(
7029 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7030 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7031 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7032}
7033
7034DEFPY(ipv6_bgp_network,
7035 ipv6_bgp_network_cmd,
7036 "[no] network X:X::X:X/M$prefix \
7037 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7038 NO_STR
7039 "Specify a network to announce via BGP\n"
7040 "IPv6 prefix\n"
7041 "Route-map to modify the attributes\n"
7042 "Name of the route map\n"
7043 "Label index to associate with the prefix\n"
7044 "Label index value\n")
7045{
7046 return bgp_static_set(
7047 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7048 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7049}
7050
7051static struct bgp_aggregate *bgp_aggregate_new(void)
7052{
7053 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7054}
7055
7056static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7057{
7058 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7059 route_map_counter_decrement(aggregate->suppress_map);
7060 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7061 route_map_counter_decrement(aggregate->rmap.map);
7062 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7063}
7064
7065/**
7066 * Helper function to avoid repeated code: prepare variables for a
7067 * `route_map_apply` call.
7068 *
7069 * \returns `true` on route map match, otherwise `false`.
7070 */
7071static bool aggr_suppress_map_test(struct bgp *bgp,
7072 struct bgp_aggregate *aggregate,
7073 struct bgp_path_info *pi)
7074{
7075 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7076 route_map_result_t rmr = RMAP_DENYMATCH;
7077 struct bgp_path_info rmap_path = {};
7078 struct attr attr = {};
7079
7080 /* No route map entries created, just don't match. */
7081 if (aggregate->suppress_map == NULL)
7082 return false;
7083
7084 /* Call route map matching and return result. */
7085 attr.aspath = aspath_empty();
7086 rmap_path.peer = bgp->peer_self;
7087 rmap_path.attr = &attr;
7088
7089 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7090 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7091 bgp->peer_self->rmap_type = 0;
7092
7093 bgp_attr_flush(&attr);
7094 aspath_unintern(&attr.aspath);
7095
7096 return rmr == RMAP_PERMITMATCH;
7097}
7098
7099/** Test whether the aggregation has suppressed this path or not. */
7100static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7101 struct bgp_path_info *pi)
7102{
7103 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7104 return false;
7105
7106 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7107}
7108
7109/**
7110 * Suppress this path and keep the reference.
7111 *
7112 * \returns `true` if needs processing otherwise `false`.
7113 */
7114static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7115 struct bgp_path_info *pi)
7116{
7117 struct bgp_path_info_extra *pie;
7118
7119 /* Path is already suppressed by this aggregation. */
7120 if (aggr_suppress_exists(aggregate, pi))
7121 return false;
7122
7123 pie = bgp_path_info_extra_get(pi);
7124
7125 /* This is the first suppression, allocate memory and list it. */
7126 if (pie->aggr_suppressors == NULL)
7127 pie->aggr_suppressors = list_new();
7128
7129 listnode_add(pie->aggr_suppressors, aggregate);
7130
7131 /* Only mark for processing if suppressed. */
7132 if (listcount(pie->aggr_suppressors) == 1) {
7133 if (BGP_DEBUG(update, UPDATE_OUT))
7134 zlog_debug("aggregate-address suppressing: %pFX",
7135 bgp_dest_get_prefix(pi->net));
7136
7137 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7138 return true;
7139 }
7140
7141 return false;
7142}
7143
7144/**
7145 * Unsuppress this path and remove the reference.
7146 *
7147 * \returns `true` if needs processing otherwise `false`.
7148 */
7149static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7150 struct bgp_path_info *pi)
7151{
7152 /* Path wasn't suppressed. */
7153 if (!aggr_suppress_exists(aggregate, pi))
7154 return false;
7155
7156 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7157
7158 /* Unsuppress and free extra memory if last item. */
7159 if (listcount(pi->extra->aggr_suppressors) == 0) {
7160 if (BGP_DEBUG(update, UPDATE_OUT))
7161 zlog_debug("aggregate-address unsuppressing: %pFX",
7162 bgp_dest_get_prefix(pi->net));
7163
7164 list_delete(&pi->extra->aggr_suppressors);
7165 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7166 return true;
7167 }
7168
7169 return false;
7170}
7171
7172static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7173 struct aspath *aspath,
7174 struct community *comm,
7175 struct ecommunity *ecomm,
7176 struct lcommunity *lcomm)
7177{
7178 static struct aspath *ae = NULL;
7179
7180 if (!ae)
7181 ae = aspath_empty();
7182
7183 if (!pi)
7184 return false;
7185
7186 if (origin != pi->attr->origin)
7187 return false;
7188
7189 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7190 return false;
7191
7192 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7193 return false;
7194
7195 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7196 return false;
7197
7198 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7199 return false;
7200
7201 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7202 return false;
7203
7204 return true;
7205}
7206
7207static void bgp_aggregate_install(
7208 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7209 uint8_t origin, struct aspath *aspath, struct community *community,
7210 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7211 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7212{
7213 struct bgp_dest *dest;
7214 struct bgp_table *table;
7215 struct bgp_path_info *pi, *orig, *new;
7216 struct attr *attr;
7217
7218 table = bgp->rib[afi][safi];
7219
7220 dest = bgp_node_get(table, p);
7221
7222 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7223 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7224 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7225 break;
7226
7227 /*
7228 * If we have paths with different MEDs, then don't install
7229 * (or uninstall) the aggregate route.
7230 */
7231 if (aggregate->match_med && aggregate->med_mismatched)
7232 goto uninstall_aggregate_route;
7233
7234 if (aggregate->count > 0) {
7235 /*
7236 * If the aggregate information has not changed
7237 * no need to re-install it again.
7238 */
7239 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7240 ecommunity, lcommunity)) {
7241 bgp_dest_unlock_node(dest);
7242
7243 if (aspath)
7244 aspath_free(aspath);
7245 if (community)
7246 community_free(&community);
7247 if (ecommunity)
7248 ecommunity_free(&ecommunity);
7249 if (lcommunity)
7250 lcommunity_free(&lcommunity);
7251
7252 return;
7253 }
7254
7255 /*
7256 * Mark the old as unusable
7257 */
7258 if (pi)
7259 bgp_path_info_delete(dest, pi);
7260
7261 attr = bgp_attr_aggregate_intern(
7262 bgp, origin, aspath, community, ecommunity, lcommunity,
7263 aggregate, atomic_aggregate, p);
7264
7265 if (!attr) {
7266 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7267 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7268 zlog_debug("%s: %pFX null attribute", __func__,
7269 p);
7270 return;
7271 }
7272
7273 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7274 bgp->peer_self, attr, dest);
7275
7276 SET_FLAG(new->flags, BGP_PATH_VALID);
7277
7278 bgp_path_info_add(dest, new);
7279 bgp_process(bgp, dest, afi, safi);
7280 } else {
7281 uninstall_aggregate_route:
7282 for (pi = orig; pi; pi = pi->next)
7283 if (pi->peer == bgp->peer_self
7284 && pi->type == ZEBRA_ROUTE_BGP
7285 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7286 break;
7287
7288 /* Withdraw static BGP route from routing table. */
7289 if (pi) {
7290 bgp_path_info_delete(dest, pi);
7291 bgp_process(bgp, dest, afi, safi);
7292 }
7293 }
7294
7295 bgp_dest_unlock_node(dest);
7296}
7297
7298/**
7299 * Check if the current path has different MED than other known paths.
7300 *
7301 * \returns `true` if the MED matched the others else `false`.
7302 */
7303static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7304 struct bgp *bgp, struct bgp_path_info *pi)
7305{
7306 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7307
7308 /* This is the first route being analyzed. */
7309 if (!aggregate->med_initialized) {
7310 aggregate->med_initialized = true;
7311 aggregate->med_mismatched = false;
7312 aggregate->med_matched_value = cur_med;
7313 } else {
7314 /* Check if routes with different MED showed up. */
7315 if (cur_med != aggregate->med_matched_value)
7316 aggregate->med_mismatched = true;
7317 }
7318
7319 return !aggregate->med_mismatched;
7320}
7321
7322/**
7323 * Initializes and tests all routes in the aggregate address path for MED
7324 * values.
7325 *
7326 * \returns `true` if all MEDs are the same otherwise `false`.
7327 */
7328static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7329 struct bgp *bgp, const struct prefix *p,
7330 afi_t afi, safi_t safi)
7331{
7332 struct bgp_table *table = bgp->rib[afi][safi];
7333 const struct prefix *dest_p;
7334 struct bgp_dest *dest, *top;
7335 struct bgp_path_info *pi;
7336 bool med_matched = true;
7337
7338 aggregate->med_initialized = false;
7339
7340 top = bgp_node_get(table, p);
7341 for (dest = bgp_node_get(table, p); dest;
7342 dest = bgp_route_next_until(dest, top)) {
7343 dest_p = bgp_dest_get_prefix(dest);
7344 if (dest_p->prefixlen <= p->prefixlen)
7345 continue;
7346
7347 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7348 if (BGP_PATH_HOLDDOWN(pi))
7349 continue;
7350 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7351 continue;
7352 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7353 med_matched = false;
7354 break;
7355 }
7356 }
7357 if (!med_matched)
7358 break;
7359 }
7360 bgp_dest_unlock_node(top);
7361
7362 return med_matched;
7363}
7364
7365/**
7366 * Toggles the route suppression status for this aggregate address
7367 * configuration.
7368 */
7369void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7370 struct bgp *bgp, const struct prefix *p,
7371 afi_t afi, safi_t safi, bool suppress)
7372{
7373 struct bgp_table *table = bgp->rib[afi][safi];
7374 const struct prefix *dest_p;
7375 struct bgp_dest *dest, *top;
7376 struct bgp_path_info *pi;
7377 bool toggle_suppression;
7378
7379 /* We've found a different MED we must revert any suppressed routes. */
7380 top = bgp_node_get(table, p);
7381 for (dest = bgp_node_get(table, p); dest;
7382 dest = bgp_route_next_until(dest, top)) {
7383 dest_p = bgp_dest_get_prefix(dest);
7384 if (dest_p->prefixlen <= p->prefixlen)
7385 continue;
7386
7387 toggle_suppression = false;
7388 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7389 if (BGP_PATH_HOLDDOWN(pi))
7390 continue;
7391 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7392 continue;
7393
7394 /* We are toggling suppression back. */
7395 if (suppress) {
7396 /* Suppress route if not suppressed already. */
7397 if (aggr_suppress_path(aggregate, pi))
7398 toggle_suppression = true;
7399 continue;
7400 }
7401
7402 /* Install route if there is no more suppression. */
7403 if (aggr_unsuppress_path(aggregate, pi))
7404 toggle_suppression = true;
7405 }
7406
7407 if (toggle_suppression)
7408 bgp_process(bgp, dest, afi, safi);
7409 }
7410 bgp_dest_unlock_node(top);
7411}
7412
7413/**
7414 * Aggregate address MED matching incremental test: this function is called
7415 * when the initial aggregation occurred and we are only testing a single
7416 * new path.
7417 *
7418 * In addition to testing and setting the MED validity it also installs back
7419 * suppressed routes (if summary is configured).
7420 *
7421 * Must not be called in `bgp_aggregate_route`.
7422 */
7423static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7424 struct bgp *bgp, const struct prefix *p,
7425 afi_t afi, safi_t safi,
7426 struct bgp_path_info *pi, bool is_adding)
7427{
7428 /* MED matching disabled. */
7429 if (!aggregate->match_med)
7430 return;
7431
7432 /* Aggregation with different MED, nothing to do. */
7433 if (aggregate->med_mismatched)
7434 return;
7435
7436 /*
7437 * Test the current entry:
7438 *
7439 * is_adding == true: if the new entry doesn't match then we must
7440 * install all suppressed routes.
7441 *
7442 * is_adding == false: if the entry being removed was the last
7443 * unmatching entry then we can suppress all routes.
7444 */
7445 if (!is_adding) {
7446 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
7447 && aggregate->summary_only)
7448 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
7449 safi, true);
7450 } else
7451 bgp_aggregate_med_match(aggregate, bgp, pi);
7452
7453 /* No mismatches, just quit. */
7454 if (!aggregate->med_mismatched)
7455 return;
7456
7457 /* Route summarization is disabled. */
7458 if (!aggregate->summary_only)
7459 return;
7460
7461 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7462}
7463
7464/* Update an aggregate as routes are added/removed from the BGP table */
7465void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7466 safi_t safi, struct bgp_aggregate *aggregate)
7467{
7468 struct bgp_table *table;
7469 struct bgp_dest *top;
7470 struct bgp_dest *dest;
7471 uint8_t origin;
7472 struct aspath *aspath = NULL;
7473 struct community *community = NULL;
7474 struct ecommunity *ecommunity = NULL;
7475 struct lcommunity *lcommunity = NULL;
7476 struct bgp_path_info *pi;
7477 unsigned long match = 0;
7478 uint8_t atomic_aggregate = 0;
7479
7480 /* If the bgp instance is being deleted or self peer is deleted
7481 * then do not create aggregate route
7482 */
7483 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7484 || (bgp->peer_self == NULL))
7485 return;
7486
7487 /* Initialize and test routes for MED difference. */
7488 if (aggregate->match_med)
7489 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7490
7491 /*
7492 * Reset aggregate count: we might've been called from route map
7493 * update so in that case we must retest all more specific routes.
7494 *
7495 * \see `bgp_route_map_process_update`.
7496 */
7497 aggregate->count = 0;
7498 aggregate->incomplete_origin_count = 0;
7499 aggregate->incomplete_origin_count = 0;
7500 aggregate->egp_origin_count = 0;
7501
7502 /* ORIGIN attribute: If at least one route among routes that are
7503 aggregated has ORIGIN with the value INCOMPLETE, then the
7504 aggregated route must have the ORIGIN attribute with the value
7505 INCOMPLETE. Otherwise, if at least one route among routes that
7506 are aggregated has ORIGIN with the value EGP, then the aggregated
7507 route must have the origin attribute with the value EGP. In all
7508 other case the value of the ORIGIN attribute of the aggregated
7509 route is INTERNAL. */
7510 origin = BGP_ORIGIN_IGP;
7511
7512 table = bgp->rib[afi][safi];
7513
7514 top = bgp_node_get(table, p);
7515 for (dest = bgp_node_get(table, p); dest;
7516 dest = bgp_route_next_until(dest, top)) {
7517 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7518
7519 if (dest_p->prefixlen <= p->prefixlen)
7520 continue;
7521
7522 /* If suppress fib is enabled and route not installed
7523 * in FIB, skip the route
7524 */
7525 if (!bgp_check_advertise(bgp, dest))
7526 continue;
7527
7528 match = 0;
7529
7530 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7531 if (BGP_PATH_HOLDDOWN(pi))
7532 continue;
7533
7534 if (pi->attr->flag
7535 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7536 atomic_aggregate = 1;
7537
7538 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7539 continue;
7540
7541 /*
7542 * summary-only aggregate route suppress
7543 * aggregated route announcements.
7544 *
7545 * MED matching:
7546 * Don't create summaries if MED didn't match
7547 * otherwise neither the specific routes and the
7548 * aggregation will be announced.
7549 */
7550 if (aggregate->summary_only
7551 && AGGREGATE_MED_VALID(aggregate)) {
7552 if (aggr_suppress_path(aggregate, pi))
7553 match++;
7554 }
7555
7556 /*
7557 * Suppress more specific routes that match the route
7558 * map results.
7559 *
7560 * MED matching:
7561 * Don't suppress routes if MED matching is enabled and
7562 * it mismatched otherwise we might end up with no
7563 * routes for this path.
7564 */
7565 if (aggregate->suppress_map_name
7566 && AGGREGATE_MED_VALID(aggregate)
7567 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7568 if (aggr_suppress_path(aggregate, pi))
7569 match++;
7570 }
7571
7572 aggregate->count++;
7573
7574 /*
7575 * If at least one route among routes that are
7576 * aggregated has ORIGIN with the value INCOMPLETE,
7577 * then the aggregated route MUST have the ORIGIN
7578 * attribute with the value INCOMPLETE. Otherwise, if
7579 * at least one route among routes that are aggregated
7580 * has ORIGIN with the value EGP, then the aggregated
7581 * route MUST have the ORIGIN attribute with the value
7582 * EGP.
7583 */
7584 switch (pi->attr->origin) {
7585 case BGP_ORIGIN_INCOMPLETE:
7586 aggregate->incomplete_origin_count++;
7587 break;
7588 case BGP_ORIGIN_EGP:
7589 aggregate->egp_origin_count++;
7590 break;
7591 default:
7592 /*Do nothing.
7593 */
7594 break;
7595 }
7596
7597 if (!aggregate->as_set)
7598 continue;
7599
7600 /*
7601 * as-set aggregate route generate origin, as path,
7602 * and community aggregation.
7603 */
7604 /* Compute aggregate route's as-path.
7605 */
7606 bgp_compute_aggregate_aspath_hash(aggregate,
7607 pi->attr->aspath);
7608
7609 /* Compute aggregate route's community.
7610 */
7611 if (bgp_attr_get_community(pi->attr))
7612 bgp_compute_aggregate_community_hash(
7613 aggregate,
7614 bgp_attr_get_community(pi->attr));
7615
7616 /* Compute aggregate route's extended community.
7617 */
7618 if (bgp_attr_get_ecommunity(pi->attr))
7619 bgp_compute_aggregate_ecommunity_hash(
7620 aggregate,
7621 bgp_attr_get_ecommunity(pi->attr));
7622
7623 /* Compute aggregate route's large community.
7624 */
7625 if (bgp_attr_get_lcommunity(pi->attr))
7626 bgp_compute_aggregate_lcommunity_hash(
7627 aggregate,
7628 bgp_attr_get_lcommunity(pi->attr));
7629 }
7630 if (match)
7631 bgp_process(bgp, dest, afi, safi);
7632 }
7633 if (aggregate->as_set) {
7634 bgp_compute_aggregate_aspath_val(aggregate);
7635 bgp_compute_aggregate_community_val(aggregate);
7636 bgp_compute_aggregate_ecommunity_val(aggregate);
7637 bgp_compute_aggregate_lcommunity_val(aggregate);
7638 }
7639
7640
7641 bgp_dest_unlock_node(top);
7642
7643
7644 if (aggregate->incomplete_origin_count > 0)
7645 origin = BGP_ORIGIN_INCOMPLETE;
7646 else if (aggregate->egp_origin_count > 0)
7647 origin = BGP_ORIGIN_EGP;
7648
7649 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7650 origin = aggregate->origin;
7651
7652 if (aggregate->as_set) {
7653 if (aggregate->aspath)
7654 /* Retrieve aggregate route's as-path.
7655 */
7656 aspath = aspath_dup(aggregate->aspath);
7657
7658 if (aggregate->community)
7659 /* Retrieve aggregate route's community.
7660 */
7661 community = community_dup(aggregate->community);
7662
7663 if (aggregate->ecommunity)
7664 /* Retrieve aggregate route's ecommunity.
7665 */
7666 ecommunity = ecommunity_dup(aggregate->ecommunity);
7667
7668 if (aggregate->lcommunity)
7669 /* Retrieve aggregate route's lcommunity.
7670 */
7671 lcommunity = lcommunity_dup(aggregate->lcommunity);
7672 }
7673
7674 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7675 ecommunity, lcommunity, atomic_aggregate,
7676 aggregate);
7677}
7678
7679void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7680 safi_t safi, struct bgp_aggregate *aggregate)
7681{
7682 struct bgp_table *table;
7683 struct bgp_dest *top;
7684 struct bgp_dest *dest;
7685 struct bgp_path_info *pi;
7686 unsigned long match;
7687
7688 table = bgp->rib[afi][safi];
7689
7690 /* If routes exists below this node, generate aggregate routes. */
7691 top = bgp_node_get(table, p);
7692 for (dest = bgp_node_get(table, p); dest;
7693 dest = bgp_route_next_until(dest, top)) {
7694 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7695
7696 if (dest_p->prefixlen <= p->prefixlen)
7697 continue;
7698 match = 0;
7699
7700 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7701 if (BGP_PATH_HOLDDOWN(pi))
7702 continue;
7703
7704 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7705 continue;
7706
7707 /*
7708 * This route is suppressed: attempt to unsuppress it.
7709 *
7710 * `aggr_unsuppress_path` will fail if this particular
7711 * aggregate route was not the suppressor.
7712 */
7713 if (pi->extra && pi->extra->aggr_suppressors &&
7714 listcount(pi->extra->aggr_suppressors)) {
7715 if (aggr_unsuppress_path(aggregate, pi))
7716 match++;
7717 }
7718
7719 aggregate->count--;
7720
7721 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7722 aggregate->incomplete_origin_count--;
7723 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7724 aggregate->egp_origin_count--;
7725
7726 if (aggregate->as_set) {
7727 /* Remove as-path from aggregate.
7728 */
7729 bgp_remove_aspath_from_aggregate_hash(
7730 aggregate,
7731 pi->attr->aspath);
7732
7733 if (bgp_attr_get_community(pi->attr))
7734 /* Remove community from aggregate.
7735 */
7736 bgp_remove_comm_from_aggregate_hash(
7737 aggregate,
7738 bgp_attr_get_community(
7739 pi->attr));
7740
7741 if (bgp_attr_get_ecommunity(pi->attr))
7742 /* Remove ecommunity from aggregate.
7743 */
7744 bgp_remove_ecomm_from_aggregate_hash(
7745 aggregate,
7746 bgp_attr_get_ecommunity(
7747 pi->attr));
7748
7749 if (bgp_attr_get_lcommunity(pi->attr))
7750 /* Remove lcommunity from aggregate.
7751 */
7752 bgp_remove_lcomm_from_aggregate_hash(
7753 aggregate,
7754 bgp_attr_get_lcommunity(
7755 pi->attr));
7756 }
7757 }
7758
7759 /* If this node was suppressed, process the change. */
7760 if (match)
7761 bgp_process(bgp, dest, afi, safi);
7762 }
7763 if (aggregate->as_set) {
7764 aspath_free(aggregate->aspath);
7765 aggregate->aspath = NULL;
7766 if (aggregate->community)
7767 community_free(&aggregate->community);
7768 if (aggregate->ecommunity)
7769 ecommunity_free(&aggregate->ecommunity);
7770 if (aggregate->lcommunity)
7771 lcommunity_free(&aggregate->lcommunity);
7772 }
7773
7774 bgp_dest_unlock_node(top);
7775}
7776
7777static void bgp_add_route_to_aggregate(struct bgp *bgp,
7778 const struct prefix *aggr_p,
7779 struct bgp_path_info *pinew, afi_t afi,
7780 safi_t safi,
7781 struct bgp_aggregate *aggregate)
7782{
7783 uint8_t origin;
7784 struct aspath *aspath = NULL;
7785 uint8_t atomic_aggregate = 0;
7786 struct community *community = NULL;
7787 struct ecommunity *ecommunity = NULL;
7788 struct lcommunity *lcommunity = NULL;
7789
7790 /* If the bgp instance is being deleted or self peer is deleted
7791 * then do not create aggregate route
7792 */
7793 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7794 || (bgp->peer_self == NULL))
7795 return;
7796
7797 /* ORIGIN attribute: If at least one route among routes that are
7798 * aggregated has ORIGIN with the value INCOMPLETE, then the
7799 * aggregated route must have the ORIGIN attribute with the value
7800 * INCOMPLETE. Otherwise, if at least one route among routes that
7801 * are aggregated has ORIGIN with the value EGP, then the aggregated
7802 * route must have the origin attribute with the value EGP. In all
7803 * other case the value of the ORIGIN attribute of the aggregated
7804 * route is INTERNAL.
7805 */
7806 origin = BGP_ORIGIN_IGP;
7807
7808 aggregate->count++;
7809
7810 /*
7811 * This must be called before `summary` check to avoid
7812 * "suppressing" twice.
7813 */
7814 if (aggregate->match_med)
7815 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7816 pinew, true);
7817
7818 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7819 aggr_suppress_path(aggregate, pinew);
7820
7821 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7822 && aggr_suppress_map_test(bgp, aggregate, pinew))
7823 aggr_suppress_path(aggregate, pinew);
7824
7825 switch (pinew->attr->origin) {
7826 case BGP_ORIGIN_INCOMPLETE:
7827 aggregate->incomplete_origin_count++;
7828 break;
7829 case BGP_ORIGIN_EGP:
7830 aggregate->egp_origin_count++;
7831 break;
7832 default:
7833 /* Do nothing.
7834 */
7835 break;
7836 }
7837
7838 if (aggregate->incomplete_origin_count > 0)
7839 origin = BGP_ORIGIN_INCOMPLETE;
7840 else if (aggregate->egp_origin_count > 0)
7841 origin = BGP_ORIGIN_EGP;
7842
7843 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7844 origin = aggregate->origin;
7845
7846 if (aggregate->as_set) {
7847 /* Compute aggregate route's as-path.
7848 */
7849 bgp_compute_aggregate_aspath(aggregate,
7850 pinew->attr->aspath);
7851
7852 /* Compute aggregate route's community.
7853 */
7854 if (bgp_attr_get_community(pinew->attr))
7855 bgp_compute_aggregate_community(
7856 aggregate, bgp_attr_get_community(pinew->attr));
7857
7858 /* Compute aggregate route's extended community.
7859 */
7860 if (bgp_attr_get_ecommunity(pinew->attr))
7861 bgp_compute_aggregate_ecommunity(
7862 aggregate,
7863 bgp_attr_get_ecommunity(pinew->attr));
7864
7865 /* Compute aggregate route's large community.
7866 */
7867 if (bgp_attr_get_lcommunity(pinew->attr))
7868 bgp_compute_aggregate_lcommunity(
7869 aggregate,
7870 bgp_attr_get_lcommunity(pinew->attr));
7871
7872 /* Retrieve aggregate route's as-path.
7873 */
7874 if (aggregate->aspath)
7875 aspath = aspath_dup(aggregate->aspath);
7876
7877 /* Retrieve aggregate route's community.
7878 */
7879 if (aggregate->community)
7880 community = community_dup(aggregate->community);
7881
7882 /* Retrieve aggregate route's ecommunity.
7883 */
7884 if (aggregate->ecommunity)
7885 ecommunity = ecommunity_dup(aggregate->ecommunity);
7886
7887 /* Retrieve aggregate route's lcommunity.
7888 */
7889 if (aggregate->lcommunity)
7890 lcommunity = lcommunity_dup(aggregate->lcommunity);
7891 }
7892
7893 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7894 aspath, community, ecommunity,
7895 lcommunity, atomic_aggregate, aggregate);
7896}
7897
7898static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7899 safi_t safi,
7900 struct bgp_path_info *pi,
7901 struct bgp_aggregate *aggregate,
7902 const struct prefix *aggr_p)
7903{
7904 uint8_t origin;
7905 struct aspath *aspath = NULL;
7906 uint8_t atomic_aggregate = 0;
7907 struct community *community = NULL;
7908 struct ecommunity *ecommunity = NULL;
7909 struct lcommunity *lcommunity = NULL;
7910 unsigned long match = 0;
7911
7912 /* If the bgp instance is being deleted or self peer is deleted
7913 * then do not create aggregate route
7914 */
7915 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7916 || (bgp->peer_self == NULL))
7917 return;
7918
7919 if (BGP_PATH_HOLDDOWN(pi))
7920 return;
7921
7922 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7923 return;
7924
7925 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7926 if (aggr_unsuppress_path(aggregate, pi))
7927 match++;
7928
7929 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7930 && aggr_suppress_map_test(bgp, aggregate, pi))
7931 if (aggr_unsuppress_path(aggregate, pi))
7932 match++;
7933
7934 /*
7935 * This must be called after `summary`, `suppress-map` check to avoid
7936 * "unsuppressing" twice.
7937 */
7938 if (aggregate->match_med)
7939 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
7940 true);
7941
7942 if (aggregate->count > 0)
7943 aggregate->count--;
7944
7945 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7946 aggregate->incomplete_origin_count--;
7947 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7948 aggregate->egp_origin_count--;
7949
7950 if (aggregate->as_set) {
7951 /* Remove as-path from aggregate.
7952 */
7953 bgp_remove_aspath_from_aggregate(aggregate,
7954 pi->attr->aspath);
7955
7956 if (bgp_attr_get_community(pi->attr))
7957 /* Remove community from aggregate.
7958 */
7959 bgp_remove_community_from_aggregate(
7960 aggregate, bgp_attr_get_community(pi->attr));
7961
7962 if (bgp_attr_get_ecommunity(pi->attr))
7963 /* Remove ecommunity from aggregate.
7964 */
7965 bgp_remove_ecommunity_from_aggregate(
7966 aggregate, bgp_attr_get_ecommunity(pi->attr));
7967
7968 if (bgp_attr_get_lcommunity(pi->attr))
7969 /* Remove lcommunity from aggregate.
7970 */
7971 bgp_remove_lcommunity_from_aggregate(
7972 aggregate, bgp_attr_get_lcommunity(pi->attr));
7973 }
7974
7975 /* If this node was suppressed, process the change. */
7976 if (match)
7977 bgp_process(bgp, pi->net, afi, safi);
7978
7979 origin = BGP_ORIGIN_IGP;
7980 if (aggregate->incomplete_origin_count > 0)
7981 origin = BGP_ORIGIN_INCOMPLETE;
7982 else if (aggregate->egp_origin_count > 0)
7983 origin = BGP_ORIGIN_EGP;
7984
7985 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7986 origin = aggregate->origin;
7987
7988 if (aggregate->as_set) {
7989 /* Retrieve aggregate route's as-path.
7990 */
7991 if (aggregate->aspath)
7992 aspath = aspath_dup(aggregate->aspath);
7993
7994 /* Retrieve aggregate route's community.
7995 */
7996 if (aggregate->community)
7997 community = community_dup(aggregate->community);
7998
7999 /* Retrieve aggregate route's ecommunity.
8000 */
8001 if (aggregate->ecommunity)
8002 ecommunity = ecommunity_dup(aggregate->ecommunity);
8003
8004 /* Retrieve aggregate route's lcommunity.
8005 */
8006 if (aggregate->lcommunity)
8007 lcommunity = lcommunity_dup(aggregate->lcommunity);
8008 }
8009
8010 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8011 aspath, community, ecommunity,
8012 lcommunity, atomic_aggregate, aggregate);
8013}
8014
8015void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8016 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8017{
8018 struct bgp_dest *child;
8019 struct bgp_dest *dest;
8020 struct bgp_aggregate *aggregate;
8021 struct bgp_table *table;
8022
8023 table = bgp->aggregate[afi][safi];
8024
8025 /* No aggregates configured. */
8026 if (bgp_table_top_nolock(table) == NULL)
8027 return;
8028
8029 if (p->prefixlen == 0)
8030 return;
8031
8032 if (BGP_PATH_HOLDDOWN(pi))
8033 return;
8034
8035 /* If suppress fib is enabled and route not installed
8036 * in FIB, do not update the aggregate route
8037 */
8038 if (!bgp_check_advertise(bgp, pi->net))
8039 return;
8040
8041 child = bgp_node_get(table, p);
8042
8043 /* Aggregate address configuration check. */
8044 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8045 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8046
8047 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8048 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8049 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8050 aggregate);
8051 }
8052 }
8053 bgp_dest_unlock_node(child);
8054}
8055
8056void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8057 struct bgp_path_info *del, afi_t afi, safi_t safi)
8058{
8059 struct bgp_dest *child;
8060 struct bgp_dest *dest;
8061 struct bgp_aggregate *aggregate;
8062 struct bgp_table *table;
8063
8064 table = bgp->aggregate[afi][safi];
8065
8066 /* No aggregates configured. */
8067 if (bgp_table_top_nolock(table) == NULL)
8068 return;
8069
8070 if (p->prefixlen == 0)
8071 return;
8072
8073 child = bgp_node_get(table, p);
8074
8075 /* Aggregate address configuration check. */
8076 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8077 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8078
8079 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8080 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8081 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8082 aggregate, dest_p);
8083 }
8084 }
8085 bgp_dest_unlock_node(child);
8086}
8087
8088/* Aggregate route attribute. */
8089#define AGGREGATE_SUMMARY_ONLY 1
8090#define AGGREGATE_AS_SET 1
8091#define AGGREGATE_AS_UNSET 0
8092
8093static const char *bgp_origin2str(uint8_t origin)
8094{
8095 switch (origin) {
8096 case BGP_ORIGIN_IGP:
8097 return "igp";
8098 case BGP_ORIGIN_EGP:
8099 return "egp";
8100 case BGP_ORIGIN_INCOMPLETE:
8101 return "incomplete";
8102 }
8103 return "n/a";
8104}
8105
8106static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8107{
8108 switch (v_state) {
8109 case RPKI_NOT_BEING_USED:
8110 return "not used";
8111 case RPKI_VALID:
8112 return "valid";
8113 case RPKI_NOTFOUND:
8114 return "not found";
8115 case RPKI_INVALID:
8116 return "invalid";
8117 }
8118
8119 assert(!"We should never get here this is a dev escape");
8120 return "ERROR";
8121}
8122
8123static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8124 afi_t afi, safi_t safi)
8125{
8126 VTY_DECLVAR_CONTEXT(bgp, bgp);
8127 int ret;
8128 struct prefix p;
8129 struct bgp_dest *dest;
8130 struct bgp_aggregate *aggregate;
8131
8132 /* Convert string to prefix structure. */
8133 ret = str2prefix(prefix_str, &p);
8134 if (!ret) {
8135 vty_out(vty, "Malformed prefix\n");
8136 return CMD_WARNING_CONFIG_FAILED;
8137 }
8138 apply_mask(&p);
8139
8140 /* Old configuration check. */
8141 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8142 if (!dest) {
8143 vty_out(vty,
8144 "%% There is no aggregate-address configuration.\n");
8145 return CMD_WARNING_CONFIG_FAILED;
8146 }
8147
8148 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8149 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8150 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8151 NULL, NULL, 0, aggregate);
8152
8153 /* Unlock aggregate address configuration. */
8154 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8155
8156 if (aggregate->community)
8157 community_free(&aggregate->community);
8158
8159 if (aggregate->community_hash) {
8160 /* Delete all communities in the hash.
8161 */
8162 hash_clean(aggregate->community_hash,
8163 bgp_aggr_community_remove);
8164 /* Free up the community_hash.
8165 */
8166 hash_free(aggregate->community_hash);
8167 }
8168
8169 if (aggregate->ecommunity)
8170 ecommunity_free(&aggregate->ecommunity);
8171
8172 if (aggregate->ecommunity_hash) {
8173 /* Delete all ecommunities in the hash.
8174 */
8175 hash_clean(aggregate->ecommunity_hash,
8176 bgp_aggr_ecommunity_remove);
8177 /* Free up the ecommunity_hash.
8178 */
8179 hash_free(aggregate->ecommunity_hash);
8180 }
8181
8182 if (aggregate->lcommunity)
8183 lcommunity_free(&aggregate->lcommunity);
8184
8185 if (aggregate->lcommunity_hash) {
8186 /* Delete all lcommunities in the hash.
8187 */
8188 hash_clean(aggregate->lcommunity_hash,
8189 bgp_aggr_lcommunity_remove);
8190 /* Free up the lcommunity_hash.
8191 */
8192 hash_free(aggregate->lcommunity_hash);
8193 }
8194
8195 if (aggregate->aspath)
8196 aspath_free(aggregate->aspath);
8197
8198 if (aggregate->aspath_hash) {
8199 /* Delete all as-paths in the hash.
8200 */
8201 hash_clean(aggregate->aspath_hash,
8202 bgp_aggr_aspath_remove);
8203 /* Free up the aspath_hash.
8204 */
8205 hash_free(aggregate->aspath_hash);
8206 }
8207
8208 bgp_aggregate_free(aggregate);
8209 bgp_dest_unlock_node(dest);
8210 bgp_dest_unlock_node(dest);
8211
8212 return CMD_SUCCESS;
8213}
8214
8215static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8216 safi_t safi, const char *rmap,
8217 uint8_t summary_only, uint8_t as_set,
8218 uint8_t origin, bool match_med,
8219 const char *suppress_map)
8220{
8221 VTY_DECLVAR_CONTEXT(bgp, bgp);
8222 int ret;
8223 struct prefix p;
8224 struct bgp_dest *dest;
8225 struct bgp_aggregate *aggregate;
8226 uint8_t as_set_new = as_set;
8227
8228 if (suppress_map && summary_only) {
8229 vty_out(vty,
8230 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8231 return CMD_WARNING_CONFIG_FAILED;
8232 }
8233
8234 /* Convert string to prefix structure. */
8235 ret = str2prefix(prefix_str, &p);
8236 if (!ret) {
8237 vty_out(vty, "Malformed prefix\n");
8238 return CMD_WARNING_CONFIG_FAILED;
8239 }
8240 apply_mask(&p);
8241
8242 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8243 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8244 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8245 prefix_str);
8246 return CMD_WARNING_CONFIG_FAILED;
8247 }
8248
8249 /* Old configuration check. */
8250 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8251 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8252
8253 if (aggregate) {
8254 vty_out(vty, "There is already same aggregate network.\n");
8255 /* try to remove the old entry */
8256 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8257 if (ret) {
8258 vty_out(vty, "Error deleting aggregate.\n");
8259 bgp_dest_unlock_node(dest);
8260 return CMD_WARNING_CONFIG_FAILED;
8261 }
8262 }
8263
8264 /* Make aggregate address structure. */
8265 aggregate = bgp_aggregate_new();
8266 aggregate->summary_only = summary_only;
8267 aggregate->match_med = match_med;
8268
8269 /* Network operators MUST NOT locally generate any new
8270 * announcements containing AS_SET or AS_CONFED_SET. If they have
8271 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8272 * SHOULD withdraw those routes and re-announce routes for the
8273 * aggregate or component prefixes (i.e., the more-specific routes
8274 * subsumed by the previously aggregated route) without AS_SET
8275 * or AS_CONFED_SET in the updates.
8276 */
8277 if (bgp->reject_as_sets) {
8278 if (as_set == AGGREGATE_AS_SET) {
8279 as_set_new = AGGREGATE_AS_UNSET;
8280 zlog_warn(
8281 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8282 __func__);
8283 vty_out(vty,
8284 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8285 }
8286 }
8287
8288 aggregate->as_set = as_set_new;
8289 aggregate->safi = safi;
8290 /* Override ORIGIN attribute if defined.
8291 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8292 * to IGP which is not what rfc4271 says.
8293 * This enables the same behavior, optionally.
8294 */
8295 aggregate->origin = origin;
8296
8297 if (rmap) {
8298 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8299 route_map_counter_decrement(aggregate->rmap.map);
8300 aggregate->rmap.name =
8301 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8302 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8303 route_map_counter_increment(aggregate->rmap.map);
8304 }
8305
8306 if (suppress_map) {
8307 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8308 route_map_counter_decrement(aggregate->suppress_map);
8309
8310 aggregate->suppress_map_name =
8311 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8312 aggregate->suppress_map =
8313 route_map_lookup_by_name(aggregate->suppress_map_name);
8314 route_map_counter_increment(aggregate->suppress_map);
8315 }
8316
8317 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8318
8319 /* Aggregate address insert into BGP routing table. */
8320 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8321
8322 return CMD_SUCCESS;
8323}
8324
8325DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8326 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8327 "as-set$as_set_s"
8328 "|summary-only$summary_only"
8329 "|route-map RMAP_NAME$rmap_name"
8330 "|origin <egp|igp|incomplete>$origin_s"
8331 "|matching-MED-only$match_med"
8332 "|suppress-map RMAP_NAME$suppress_map"
8333 "}]",
8334 NO_STR
8335 "Configure BGP aggregate entries\n"
8336 "Aggregate prefix\n"
8337 "Aggregate address\n"
8338 "Aggregate mask\n"
8339 "Generate AS set path information\n"
8340 "Filter more specific routes from updates\n"
8341 "Apply route map to aggregate network\n"
8342 "Route map name\n"
8343 "BGP origin code\n"
8344 "Remote EGP\n"
8345 "Local IGP\n"
8346 "Unknown heritage\n"
8347 "Only aggregate routes with matching MED\n"
8348 "Suppress the selected more specific routes\n"
8349 "Route map with the route selectors\n")
8350{
8351 const char *prefix_s = NULL;
8352 safi_t safi = bgp_node_safi(vty);
8353 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8354 int as_set = AGGREGATE_AS_UNSET;
8355 char prefix_buf[PREFIX2STR_BUFFER];
8356
8357 if (addr_str) {
8358 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8359 sizeof(prefix_buf))
8360 == 0) {
8361 vty_out(vty, "%% Inconsistent address and mask\n");
8362 return CMD_WARNING_CONFIG_FAILED;
8363 }
8364 prefix_s = prefix_buf;
8365 } else
8366 prefix_s = prefix_str;
8367
8368 if (origin_s) {
8369 if (strcmp(origin_s, "egp") == 0)
8370 origin = BGP_ORIGIN_EGP;
8371 else if (strcmp(origin_s, "igp") == 0)
8372 origin = BGP_ORIGIN_IGP;
8373 else if (strcmp(origin_s, "incomplete") == 0)
8374 origin = BGP_ORIGIN_INCOMPLETE;
8375 }
8376
8377 if (as_set_s)
8378 as_set = AGGREGATE_AS_SET;
8379
8380 /* Handle configuration removal, otherwise installation. */
8381 if (no)
8382 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8383
8384 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8385 summary_only != NULL, as_set, origin,
8386 match_med != NULL, suppress_map);
8387}
8388
8389DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8390 "[no] aggregate-address X:X::X:X/M$prefix [{"
8391 "as-set$as_set_s"
8392 "|summary-only$summary_only"
8393 "|route-map RMAP_NAME$rmap_name"
8394 "|origin <egp|igp|incomplete>$origin_s"
8395 "|matching-MED-only$match_med"
8396 "|suppress-map RMAP_NAME$suppress_map"
8397 "}]",
8398 NO_STR
8399 "Configure BGP aggregate entries\n"
8400 "Aggregate prefix\n"
8401 "Generate AS set path information\n"
8402 "Filter more specific routes from updates\n"
8403 "Apply route map to aggregate network\n"
8404 "Route map name\n"
8405 "BGP origin code\n"
8406 "Remote EGP\n"
8407 "Local IGP\n"
8408 "Unknown heritage\n"
8409 "Only aggregate routes with matching MED\n"
8410 "Suppress the selected more specific routes\n"
8411 "Route map with the route selectors\n")
8412{
8413 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8414 int as_set = AGGREGATE_AS_UNSET;
8415
8416 if (origin_s) {
8417 if (strcmp(origin_s, "egp") == 0)
8418 origin = BGP_ORIGIN_EGP;
8419 else if (strcmp(origin_s, "igp") == 0)
8420 origin = BGP_ORIGIN_IGP;
8421 else if (strcmp(origin_s, "incomplete") == 0)
8422 origin = BGP_ORIGIN_INCOMPLETE;
8423 }
8424
8425 if (as_set_s)
8426 as_set = AGGREGATE_AS_SET;
8427
8428 /* Handle configuration removal, otherwise installation. */
8429 if (no)
8430 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8431 SAFI_UNICAST);
8432
8433 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8434 rmap_name, summary_only != NULL, as_set,
8435 origin, match_med != NULL, suppress_map);
8436}
8437
8438/* Redistribute route treatment. */
8439void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8440 const union g_addr *nexthop, ifindex_t ifindex,
8441 enum nexthop_types_t nhtype, uint8_t distance,
8442 enum blackhole_type bhtype, uint32_t metric,
8443 uint8_t type, unsigned short instance,
8444 route_tag_t tag)
8445{
8446 struct bgp_path_info *new;
8447 struct bgp_path_info *bpi;
8448 struct bgp_path_info rmap_path;
8449 struct bgp_dest *bn;
8450 struct attr attr;
8451 struct attr *new_attr;
8452 afi_t afi;
8453 route_map_result_t ret;
8454 struct bgp_redist *red;
8455
8456 /* Make default attribute. */
8457 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8458 /*
8459 * This must not be NULL to satisfy Coverity SA
8460 */
8461 assert(attr.aspath);
8462
8463 switch (nhtype) {
8464 case NEXTHOP_TYPE_IFINDEX:
8465 break;
8466 case NEXTHOP_TYPE_IPV4:
8467 case NEXTHOP_TYPE_IPV4_IFINDEX:
8468 attr.nexthop = nexthop->ipv4;
8469 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8470 break;
8471 case NEXTHOP_TYPE_IPV6:
8472 case NEXTHOP_TYPE_IPV6_IFINDEX:
8473 attr.mp_nexthop_global = nexthop->ipv6;
8474 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8475 break;
8476 case NEXTHOP_TYPE_BLACKHOLE:
8477 switch (p->family) {
8478 case AF_INET:
8479 attr.nexthop.s_addr = INADDR_ANY;
8480 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8481 break;
8482 case AF_INET6:
8483 memset(&attr.mp_nexthop_global, 0,
8484 sizeof(attr.mp_nexthop_global));
8485 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8486 break;
8487 }
8488 attr.bh_type = bhtype;
8489 break;
8490 }
8491 attr.nh_type = nhtype;
8492 attr.nh_ifindex = ifindex;
8493
8494 attr.med = metric;
8495 attr.distance = distance;
8496 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8497 attr.tag = tag;
8498
8499 afi = family2afi(p->family);
8500
8501 red = bgp_redist_lookup(bgp, afi, type, instance);
8502 if (red) {
8503 struct attr attr_new;
8504
8505 /* Copy attribute for modification. */
8506 attr_new = attr;
8507
8508 if (red->redist_metric_flag)
8509 attr_new.med = red->redist_metric;
8510
8511 /* Apply route-map. */
8512 if (red->rmap.name) {
8513 memset(&rmap_path, 0, sizeof(rmap_path));
8514 rmap_path.peer = bgp->peer_self;
8515 rmap_path.attr = &attr_new;
8516
8517 SET_FLAG(bgp->peer_self->rmap_type,
8518 PEER_RMAP_TYPE_REDISTRIBUTE);
8519
8520 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8521
8522 bgp->peer_self->rmap_type = 0;
8523
8524 if (ret == RMAP_DENYMATCH) {
8525 /* Free uninterned attribute. */
8526 bgp_attr_flush(&attr_new);
8527
8528 /* Unintern original. */
8529 aspath_unintern(&attr.aspath);
8530 bgp_redistribute_delete(bgp, p, type, instance);
8531 return;
8532 }
8533 }
8534
8535 if (bgp_in_graceful_shutdown(bgp))
8536 bgp_attr_add_gshut_community(&attr_new);
8537
8538 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8539 SAFI_UNICAST, p, NULL);
8540
8541 new_attr = bgp_attr_intern(&attr_new);
8542
8543 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8544 if (bpi->peer == bgp->peer_self
8545 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8546 break;
8547
8548 if (bpi) {
8549 /* Ensure the (source route) type is updated. */
8550 bpi->type = type;
8551 if (attrhash_cmp(bpi->attr, new_attr)
8552 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8553 bgp_attr_unintern(&new_attr);
8554 aspath_unintern(&attr.aspath);
8555 bgp_dest_unlock_node(bn);
8556 return;
8557 } else {
8558 /* The attribute is changed. */
8559 bgp_path_info_set_flag(bn, bpi,
8560 BGP_PATH_ATTR_CHANGED);
8561
8562 /* Rewrite BGP route information. */
8563 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8564 bgp_path_info_restore(bn, bpi);
8565 else
8566 bgp_aggregate_decrement(
8567 bgp, p, bpi, afi, SAFI_UNICAST);
8568 bgp_attr_unintern(&bpi->attr);
8569 bpi->attr = new_attr;
8570 bpi->uptime = monotime(NULL);
8571
8572 /* Process change. */
8573 bgp_aggregate_increment(bgp, p, bpi, afi,
8574 SAFI_UNICAST);
8575 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8576 bgp_dest_unlock_node(bn);
8577 aspath_unintern(&attr.aspath);
8578
8579 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8580 || (bgp->inst_type
8581 == BGP_INSTANCE_TYPE_DEFAULT)) {
8582
8583 vpn_leak_from_vrf_update(
8584 bgp_get_default(), bgp, bpi);
8585 }
8586 return;
8587 }
8588 }
8589
8590 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8591 bgp->peer_self, new_attr, bn);
8592 SET_FLAG(new->flags, BGP_PATH_VALID);
8593
8594 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8595 bgp_path_info_add(bn, new);
8596 bgp_dest_unlock_node(bn);
8597 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8598 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8599
8600 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8601 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8602
8603 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8604 }
8605 }
8606
8607 /* Unintern original. */
8608 aspath_unintern(&attr.aspath);
8609}
8610
8611void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8612 unsigned short instance)
8613{
8614 afi_t afi;
8615 struct bgp_dest *dest;
8616 struct bgp_path_info *pi;
8617 struct bgp_redist *red;
8618
8619 afi = family2afi(p->family);
8620
8621 red = bgp_redist_lookup(bgp, afi, type, instance);
8622 if (red) {
8623 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8624 SAFI_UNICAST, p, NULL);
8625
8626 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8627 if (pi->peer == bgp->peer_self && pi->type == type)
8628 break;
8629
8630 if (pi) {
8631 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8632 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8633
8634 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8635 bgp, pi);
8636 }
8637 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8638 bgp_path_info_delete(dest, pi);
8639 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8640 }
8641 bgp_dest_unlock_node(dest);
8642 }
8643}
8644
8645/* Withdraw specified route type's route. */
8646void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8647 unsigned short instance)
8648{
8649 struct bgp_dest *dest;
8650 struct bgp_path_info *pi;
8651 struct bgp_table *table;
8652
8653 table = bgp->rib[afi][SAFI_UNICAST];
8654
8655 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8656 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8657 if (pi->peer == bgp->peer_self && pi->type == type
8658 && pi->instance == instance)
8659 break;
8660
8661 if (pi) {
8662 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8663 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8664
8665 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8666 bgp, pi);
8667 }
8668 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8669 pi, afi, SAFI_UNICAST);
8670 bgp_path_info_delete(dest, pi);
8671 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8672 }
8673 }
8674}
8675
8676/* Static function to display route. */
8677static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8678 struct vty *vty, json_object *json, bool wide)
8679{
8680 int len = 0;
8681 char buf[BUFSIZ];
8682
8683 if (p->family == AF_INET) {
8684 if (!json) {
8685 len = vty_out(vty, "%pFX", p);
8686 } else {
8687 json_object_string_add(json, "prefix",
8688 inet_ntop(p->family,
8689 &p->u.prefix, buf,
8690 BUFSIZ));
8691 json_object_int_add(json, "prefixLen", p->prefixlen);
8692 json_object_string_addf(json, "network", "%pFX", p);
8693 json_object_int_add(json, "version", dest->version);
8694 }
8695 } else if (p->family == AF_ETHERNET) {
8696 len = vty_out(vty, "%pFX", p);
8697 } else if (p->family == AF_EVPN) {
8698 if (!json)
8699 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8700 else
8701 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8702 } else if (p->family == AF_FLOWSPEC) {
8703 route_vty_out_flowspec(vty, p, NULL,
8704 json ?
8705 NLRI_STRING_FORMAT_JSON_SIMPLE :
8706 NLRI_STRING_FORMAT_MIN, json);
8707 } else {
8708 if (!json)
8709 len = vty_out(vty, "%pFX", p);
8710 else {
8711 json_object_string_add(json, "prefix",
8712 inet_ntop(p->family,
8713 &p->u.prefix, buf,
8714 BUFSIZ));
8715 json_object_int_add(json, "prefixLen", p->prefixlen);
8716 json_object_string_addf(json, "network", "%pFX", p);
8717 json_object_int_add(json, "version", dest->version);
8718 }
8719 }
8720
8721 if (!json) {
8722 len = wide ? (45 - len) : (17 - len);
8723 if (len < 1)
8724 vty_out(vty, "\n%*s", 20, " ");
8725 else
8726 vty_out(vty, "%*s", len, " ");
8727 }
8728}
8729
8730enum bgp_display_type {
8731 normal_list,
8732};
8733
8734const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8735{
8736 switch (reason) {
8737 case bgp_path_selection_none:
8738 return "Nothing to Select";
8739 case bgp_path_selection_first:
8740 return "First path received";
8741 case bgp_path_selection_evpn_sticky_mac:
8742 return "EVPN Sticky Mac";
8743 case bgp_path_selection_evpn_seq:
8744 return "EVPN sequence number";
8745 case bgp_path_selection_evpn_lower_ip:
8746 return "EVPN lower IP";
8747 case bgp_path_selection_evpn_local_path:
8748 return "EVPN local ES path";
8749 case bgp_path_selection_evpn_non_proxy:
8750 return "EVPN non proxy";
8751 case bgp_path_selection_weight:
8752 return "Weight";
8753 case bgp_path_selection_local_pref:
8754 return "Local Pref";
8755 case bgp_path_selection_local_route:
8756 return "Local Route";
8757 case bgp_path_selection_confed_as_path:
8758 return "Confederation based AS Path";
8759 case bgp_path_selection_as_path:
8760 return "AS Path";
8761 case bgp_path_selection_origin:
8762 return "Origin";
8763 case bgp_path_selection_med:
8764 return "MED";
8765 case bgp_path_selection_peer:
8766 return "Peer Type";
8767 case bgp_path_selection_confed:
8768 return "Confed Peer Type";
8769 case bgp_path_selection_igp_metric:
8770 return "IGP Metric";
8771 case bgp_path_selection_older:
8772 return "Older Path";
8773 case bgp_path_selection_router_id:
8774 return "Router ID";
8775 case bgp_path_selection_cluster_length:
8776 return "Cluster length";
8777 case bgp_path_selection_stale:
8778 return "Path Staleness";
8779 case bgp_path_selection_local_configured:
8780 return "Locally configured route";
8781 case bgp_path_selection_neighbor_ip:
8782 return "Neighbor IP";
8783 case bgp_path_selection_default:
8784 return "Nothing left to compare";
8785 }
8786 return "Invalid (internal error)";
8787}
8788
8789/* Print the short form route status for a bgp_path_info */
8790static void route_vty_short_status_out(struct vty *vty,
8791 struct bgp_path_info *path,
8792 const struct prefix *p,
8793 json_object *json_path)
8794{
8795 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8796
8797 if (json_path) {
8798
8799 /* Route status display. */
8800 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8801 json_object_boolean_true_add(json_path, "removed");
8802
8803 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8804 json_object_boolean_true_add(json_path, "stale");
8805
8806 if (path->extra && bgp_path_suppressed(path))
8807 json_object_boolean_true_add(json_path, "suppressed");
8808
8809 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8810 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8811 json_object_boolean_true_add(json_path, "valid");
8812
8813 /* Selected */
8814 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8815 json_object_boolean_true_add(json_path, "history");
8816
8817 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8818 json_object_boolean_true_add(json_path, "damped");
8819
8820 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8821 json_object_boolean_true_add(json_path, "bestpath");
8822 json_object_string_add(json_path, "selectionReason",
8823 bgp_path_selection_reason2str(
8824 path->net->reason));
8825 }
8826
8827 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8828 json_object_boolean_true_add(json_path, "multipath");
8829
8830 /* Internal route. */
8831 if ((path->peer->as)
8832 && (path->peer->as == path->peer->local_as))
8833 json_object_string_add(json_path, "pathFrom",
8834 "internal");
8835 else
8836 json_object_string_add(json_path, "pathFrom",
8837 "external");
8838
8839 return;
8840 }
8841
8842 /* RPKI validation state */
8843 rpki_state =
8844 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
8845
8846 if (rpki_state == RPKI_VALID)
8847 vty_out(vty, "V");
8848 else if (rpki_state == RPKI_INVALID)
8849 vty_out(vty, "I");
8850 else if (rpki_state == RPKI_NOTFOUND)
8851 vty_out(vty, "N");
8852
8853 /* Route status display. */
8854 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8855 vty_out(vty, "R");
8856 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8857 vty_out(vty, "S");
8858 else if (bgp_path_suppressed(path))
8859 vty_out(vty, "s");
8860 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8861 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8862 vty_out(vty, "*");
8863 else
8864 vty_out(vty, " ");
8865
8866 /* Selected */
8867 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8868 vty_out(vty, "h");
8869 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8870 vty_out(vty, "d");
8871 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8872 vty_out(vty, ">");
8873 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8874 vty_out(vty, "=");
8875 else
8876 vty_out(vty, " ");
8877
8878 /* Internal route. */
8879 if (path->peer && (path->peer->as)
8880 && (path->peer->as == path->peer->local_as))
8881 vty_out(vty, "i");
8882 else
8883 vty_out(vty, " ");
8884}
8885
8886static char *bgp_nexthop_hostname(struct peer *peer,
8887 struct bgp_nexthop_cache *bnc)
8888{
8889 if (peer->hostname
8890 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8891 return peer->hostname;
8892 return NULL;
8893}
8894
8895/* called from terminal list command */
8896void route_vty_out(struct vty *vty, const struct prefix *p,
8897 struct bgp_path_info *path, int display, safi_t safi,
8898 json_object *json_paths, bool wide)
8899{
8900 int len;
8901 struct attr *attr = path->attr;
8902 json_object *json_path = NULL;
8903 json_object *json_nexthops = NULL;
8904 json_object *json_nexthop_global = NULL;
8905 json_object *json_nexthop_ll = NULL;
8906 json_object *json_ext_community = NULL;
8907 char vrf_id_str[VRF_NAMSIZ] = {0};
8908 bool nexthop_self =
8909 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8910 bool nexthop_othervrf = false;
8911 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8912 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8913 char *nexthop_hostname =
8914 bgp_nexthop_hostname(path->peer, path->nexthop);
8915 char esi_buf[ESI_STR_LEN];
8916
8917 if (json_paths)
8918 json_path = json_object_new_object();
8919
8920 /* short status lead text */
8921 route_vty_short_status_out(vty, path, p, json_path);
8922
8923 if (!json_paths) {
8924 /* print prefix and mask */
8925 if (!display)
8926 route_vty_out_route(path->net, p, vty, json_path, wide);
8927 else
8928 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8929 } else {
8930 route_vty_out_route(path->net, p, vty, json_path, wide);
8931 }
8932
8933 /*
8934 * If vrf id of nexthop is different from that of prefix,
8935 * set up printable string to append
8936 */
8937 if (path->extra && path->extra->bgp_orig) {
8938 const char *self = "";
8939
8940 if (nexthop_self)
8941 self = "<";
8942
8943 nexthop_othervrf = true;
8944 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8945
8946 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8947 snprintf(vrf_id_str, sizeof(vrf_id_str),
8948 "@%s%s", VRFID_NONE_STR, self);
8949 else
8950 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8951 path->extra->bgp_orig->vrf_id, self);
8952
8953 if (path->extra->bgp_orig->inst_type
8954 != BGP_INSTANCE_TYPE_DEFAULT)
8955
8956 nexthop_vrfname = path->extra->bgp_orig->name;
8957 } else {
8958 const char *self = "";
8959
8960 if (nexthop_self)
8961 self = "<";
8962
8963 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8964 }
8965
8966 /*
8967 * For ENCAP and EVPN routes, nexthop address family is not
8968 * neccessarily the same as the prefix address family.
8969 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
8970 * EVPN routes are also exchanged with a MP nexthop. Currently,
8971 * this
8972 * is only IPv4, the value will be present in either
8973 * attr->nexthop or
8974 * attr->mp_nexthop_global_in
8975 */
8976 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
8977 char buf[BUFSIZ];
8978 char nexthop[128];
8979 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8980
8981 switch (af) {
8982 case AF_INET:
8983 snprintf(nexthop, sizeof(nexthop), "%s",
8984 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
8985 BUFSIZ));
8986 break;
8987 case AF_INET6:
8988 snprintf(nexthop, sizeof(nexthop), "%s",
8989 inet_ntop(af, &attr->mp_nexthop_global, buf,
8990 BUFSIZ));
8991 break;
8992 default:
8993 snprintf(nexthop, sizeof(nexthop), "?");
8994 break;
8995 }
8996
8997 if (json_paths) {
8998 json_nexthop_global = json_object_new_object();
8999
9000 json_object_string_add(json_nexthop_global, "ip",
9001 nexthop);
9002
9003 if (path->peer->hostname)
9004 json_object_string_add(json_nexthop_global,
9005 "hostname",
9006 path->peer->hostname);
9007
9008 json_object_string_add(json_nexthop_global, "afi",
9009 (af == AF_INET) ? "ipv4"
9010 : "ipv6");
9011 json_object_boolean_true_add(json_nexthop_global,
9012 "used");
9013 } else {
9014 if (nexthop_hostname)
9015 len = vty_out(vty, "%s(%s)%s", nexthop,
9016 nexthop_hostname, vrf_id_str);
9017 else
9018 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9019
9020 len = wide ? (41 - len) : (16 - len);
9021 if (len < 1)
9022 vty_out(vty, "\n%*s", 36, " ");
9023 else
9024 vty_out(vty, "%*s", len, " ");
9025 }
9026 } else if (safi == SAFI_EVPN) {
9027 if (json_paths) {
9028 json_nexthop_global = json_object_new_object();
9029
9030 json_object_string_addf(json_nexthop_global, "ip",
9031 "%pI4",
9032 &attr->mp_nexthop_global_in);
9033
9034 if (path->peer->hostname)
9035 json_object_string_add(json_nexthop_global,
9036 "hostname",
9037 path->peer->hostname);
9038
9039 json_object_string_add(json_nexthop_global, "afi",
9040 "ipv4");
9041 json_object_boolean_true_add(json_nexthop_global,
9042 "used");
9043 } else {
9044 if (nexthop_hostname)
9045 len = vty_out(vty, "%pI4(%s)%s",
9046 &attr->mp_nexthop_global_in,
9047 nexthop_hostname, vrf_id_str);
9048 else
9049 len = vty_out(vty, "%pI4%s",
9050 &attr->mp_nexthop_global_in,
9051 vrf_id_str);
9052
9053 len = wide ? (41 - len) : (16 - len);
9054 if (len < 1)
9055 vty_out(vty, "\n%*s", 36, " ");
9056 else
9057 vty_out(vty, "%*s", len, " ");
9058 }
9059 } else if (safi == SAFI_FLOWSPEC) {
9060 if (attr->nexthop.s_addr != INADDR_ANY) {
9061 if (json_paths) {
9062 json_nexthop_global = json_object_new_object();
9063
9064 json_object_string_add(json_nexthop_global,
9065 "afi", "ipv4");
9066 json_object_string_addf(json_nexthop_global,
9067 "ip", "%pI4",
9068 &attr->nexthop);
9069
9070 if (path->peer->hostname)
9071 json_object_string_add(
9072 json_nexthop_global, "hostname",
9073 path->peer->hostname);
9074
9075 json_object_boolean_true_add(
9076 json_nexthop_global,
9077 "used");
9078 } else {
9079 if (nexthop_hostname)
9080 len = vty_out(vty, "%pI4(%s)%s",
9081 &attr->nexthop,
9082 nexthop_hostname,
9083 vrf_id_str);
9084 else
9085 len = vty_out(vty, "%pI4%s",
9086 &attr->nexthop,
9087 vrf_id_str);
9088
9089 len = wide ? (41 - len) : (16 - len);
9090 if (len < 1)
9091 vty_out(vty, "\n%*s", 36, " ");
9092 else
9093 vty_out(vty, "%*s", len, " ");
9094 }
9095 }
9096 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9097 if (json_paths) {
9098 json_nexthop_global = json_object_new_object();
9099
9100 json_object_string_addf(json_nexthop_global, "ip",
9101 "%pI4", &attr->nexthop);
9102
9103 if (path->peer->hostname)
9104 json_object_string_add(json_nexthop_global,
9105 "hostname",
9106 path->peer->hostname);
9107
9108 json_object_string_add(json_nexthop_global, "afi",
9109 "ipv4");
9110 json_object_boolean_true_add(json_nexthop_global,
9111 "used");
9112 } else {
9113 if (nexthop_hostname)
9114 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9115 nexthop_hostname, vrf_id_str);
9116 else
9117 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9118 vrf_id_str);
9119
9120 len = wide ? (41 - len) : (16 - len);
9121 if (len < 1)
9122 vty_out(vty, "\n%*s", 36, " ");
9123 else
9124 vty_out(vty, "%*s", len, " ");
9125 }
9126 }
9127
9128 /* IPv6 Next Hop */
9129 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9130 if (json_paths) {
9131 json_nexthop_global = json_object_new_object();
9132 json_object_string_addf(json_nexthop_global, "ip",
9133 "%pI6",
9134 &attr->mp_nexthop_global);
9135
9136 if (path->peer->hostname)
9137 json_object_string_add(json_nexthop_global,
9138 "hostname",
9139 path->peer->hostname);
9140
9141 json_object_string_add(json_nexthop_global, "afi",
9142 "ipv6");
9143 json_object_string_add(json_nexthop_global, "scope",
9144 "global");
9145
9146 /* We display both LL & GL if both have been
9147 * received */
9148 if ((attr->mp_nexthop_len
9149 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9150 || (path->peer->conf_if)) {
9151 json_nexthop_ll = json_object_new_object();
9152 json_object_string_addf(
9153 json_nexthop_ll, "ip", "%pI6",
9154 &attr->mp_nexthop_local);
9155
9156 if (path->peer->hostname)
9157 json_object_string_add(
9158 json_nexthop_ll, "hostname",
9159 path->peer->hostname);
9160
9161 json_object_string_add(json_nexthop_ll, "afi",
9162 "ipv6");
9163 json_object_string_add(json_nexthop_ll, "scope",
9164 "link-local");
9165
9166 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9167 &attr->mp_nexthop_local)
9168 != 0)
9169 && !attr->mp_nexthop_prefer_global)
9170 json_object_boolean_true_add(
9171 json_nexthop_ll, "used");
9172 else
9173 json_object_boolean_true_add(
9174 json_nexthop_global, "used");
9175 } else
9176 json_object_boolean_true_add(
9177 json_nexthop_global, "used");
9178 } else {
9179 /* Display LL if LL/Global both in table unless
9180 * prefer-global is set */
9181 if (((attr->mp_nexthop_len
9182 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9183 && !attr->mp_nexthop_prefer_global)
9184 || (path->peer->conf_if)) {
9185 if (path->peer->conf_if) {
9186 len = vty_out(vty, "%s",
9187 path->peer->conf_if);
9188 /* len of IPv6 addr + max len of def
9189 * ifname */
9190 len = wide ? (41 - len) : (16 - len);
9191
9192 if (len < 1)
9193 vty_out(vty, "\n%*s", 36, " ");
9194 else
9195 vty_out(vty, "%*s", len, " ");
9196 } else {
9197 if (nexthop_hostname)
9198 len = vty_out(
9199 vty, "%pI6(%s)%s",
9200 &attr->mp_nexthop_local,
9201 nexthop_hostname,
9202 vrf_id_str);
9203 else
9204 len = vty_out(
9205 vty, "%pI6%s",
9206 &attr->mp_nexthop_local,
9207 vrf_id_str);
9208
9209 len = wide ? (41 - len) : (16 - len);
9210
9211 if (len < 1)
9212 vty_out(vty, "\n%*s", 36, " ");
9213 else
9214 vty_out(vty, "%*s", len, " ");
9215 }
9216 } else {
9217 if (nexthop_hostname)
9218 len = vty_out(vty, "%pI6(%s)%s",
9219 &attr->mp_nexthop_global,
9220 nexthop_hostname,
9221 vrf_id_str);
9222 else
9223 len = vty_out(vty, "%pI6%s",
9224 &attr->mp_nexthop_global,
9225 vrf_id_str);
9226
9227 len = wide ? (41 - len) : (16 - len);
9228
9229 if (len < 1)
9230 vty_out(vty, "\n%*s", 36, " ");
9231 else
9232 vty_out(vty, "%*s", len, " ");
9233 }
9234 }
9235 }
9236
9237 /* MED/Metric */
9238 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9239 if (json_paths)
9240 json_object_int_add(json_path, "metric", attr->med);
9241 else if (wide)
9242 vty_out(vty, "%7u", attr->med);
9243 else
9244 vty_out(vty, "%10u", attr->med);
9245 else if (!json_paths) {
9246 if (wide)
9247 vty_out(vty, "%*s", 7, " ");
9248 else
9249 vty_out(vty, "%*s", 10, " ");
9250 }
9251
9252 /* Local Pref */
9253 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9254 if (json_paths)
9255 json_object_int_add(json_path, "locPrf",
9256 attr->local_pref);
9257 else
9258 vty_out(vty, "%7u", attr->local_pref);
9259 else if (!json_paths)
9260 vty_out(vty, " ");
9261
9262 if (json_paths)
9263 json_object_int_add(json_path, "weight", attr->weight);
9264 else
9265 vty_out(vty, "%7u ", attr->weight);
9266
9267 if (json_paths)
9268 json_object_string_addf(json_path, "peerId", "%pSU",
9269 &path->peer->su);
9270
9271 /* Print aspath */
9272 if (attr->aspath) {
9273 if (json_paths)
9274 json_object_string_add(json_path, "path",
9275 attr->aspath->str);
9276 else
9277 aspath_print_vty(vty, "%s", attr->aspath, " ");
9278 }
9279
9280 /* Print origin */
9281 if (json_paths)
9282 json_object_string_add(json_path, "origin",
9283 bgp_origin_long_str[attr->origin]);
9284 else
9285 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9286
9287 if (json_paths) {
9288 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9289 json_object_string_add(json_path, "esi",
9290 esi_to_str(&attr->esi,
9291 esi_buf, sizeof(esi_buf)));
9292 }
9293 if (safi == SAFI_EVPN &&
9294 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9295 json_ext_community = json_object_new_object();
9296 json_object_string_add(
9297 json_ext_community, "string",
9298 bgp_attr_get_ecommunity(attr)->str);
9299 json_object_object_add(json_path,
9300 "extendedCommunity",
9301 json_ext_community);
9302 }
9303
9304 if (nexthop_self)
9305 json_object_boolean_true_add(json_path,
9306 "announceNexthopSelf");
9307 if (nexthop_othervrf) {
9308 json_object_string_add(json_path, "nhVrfName",
9309 nexthop_vrfname);
9310
9311 json_object_int_add(json_path, "nhVrfId",
9312 ((nexthop_vrfid == VRF_UNKNOWN)
9313 ? -1
9314 : (int)nexthop_vrfid));
9315 }
9316 }
9317
9318 if (json_paths) {
9319 if (json_nexthop_global || json_nexthop_ll) {
9320 json_nexthops = json_object_new_array();
9321
9322 if (json_nexthop_global)
9323 json_object_array_add(json_nexthops,
9324 json_nexthop_global);
9325
9326 if (json_nexthop_ll)
9327 json_object_array_add(json_nexthops,
9328 json_nexthop_ll);
9329
9330 json_object_object_add(json_path, "nexthops",
9331 json_nexthops);
9332 }
9333
9334 json_object_array_add(json_paths, json_path);
9335 } else {
9336 vty_out(vty, "\n");
9337
9338 if (safi == SAFI_EVPN) {
9339 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9340 /* XXX - add these params to the json out */
9341 vty_out(vty, "%*s", 20, " ");
9342 vty_out(vty, "ESI:%s",
9343 esi_to_str(&attr->esi, esi_buf,
9344 sizeof(esi_buf)));
9345
9346 vty_out(vty, "\n");
9347 }
9348 if (attr->flag &
9349 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9350 vty_out(vty, "%*s", 20, " ");
9351 vty_out(vty, "%s\n",
9352 bgp_attr_get_ecommunity(attr)->str);
9353 }
9354 }
9355
9356#ifdef ENABLE_BGP_VNC
9357 /* prints an additional line, indented, with VNC info, if
9358 * present */
9359 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9360 rfapi_vty_out_vncinfo(vty, p, path, safi);
9361#endif
9362 }
9363}
9364
9365/* called from terminal list command */
9366void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9367 const struct prefix *p, struct attr *attr, safi_t safi,
9368 bool use_json, json_object *json_ar, bool wide)
9369{
9370 json_object *json_status = NULL;
9371 json_object *json_net = NULL;
9372 int len;
9373 char buff[BUFSIZ];
9374
9375 /* Route status display. */
9376 if (use_json) {
9377 json_status = json_object_new_object();
9378 json_net = json_object_new_object();
9379 } else {
9380 vty_out(vty, "*");
9381 vty_out(vty, ">");
9382 vty_out(vty, " ");
9383 }
9384
9385 /* print prefix and mask */
9386 if (use_json) {
9387 if (safi == SAFI_EVPN)
9388 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9389 else if (p->family == AF_INET || p->family == AF_INET6) {
9390 json_object_string_add(
9391 json_net, "addrPrefix",
9392 inet_ntop(p->family, &p->u.prefix, buff,
9393 BUFSIZ));
9394 json_object_int_add(json_net, "prefixLen",
9395 p->prefixlen);
9396 json_object_string_addf(json_net, "network", "%pFX", p);
9397 }
9398 } else
9399 route_vty_out_route(dest, p, vty, NULL, wide);
9400
9401 /* Print attribute */
9402 if (attr) {
9403 if (use_json) {
9404 if (p->family == AF_INET &&
9405 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9406 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9407 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9408 json_object_string_addf(
9409 json_net, "nextHop", "%pI4",
9410 &attr->mp_nexthop_global_in);
9411 else
9412 json_object_string_addf(
9413 json_net, "nextHop", "%pI4",
9414 &attr->nexthop);
9415 } else if (p->family == AF_INET6 ||
9416 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9417 json_object_string_addf(
9418 json_net, "nextHopGlobal", "%pI6",
9419 &attr->mp_nexthop_global);
9420 } else if (p->family == AF_EVPN &&
9421 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9422 json_object_string_addf(
9423 json_net, "nextHop", "%pI4",
9424 &attr->mp_nexthop_global_in);
9425 }
9426
9427 if (attr->flag
9428 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9429 json_object_int_add(json_net, "metric",
9430 attr->med);
9431
9432 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9433 json_object_int_add(json_net, "locPrf",
9434 attr->local_pref);
9435
9436 json_object_int_add(json_net, "weight", attr->weight);
9437
9438 /* Print aspath */
9439 if (attr->aspath)
9440 json_object_string_add(json_net, "path",
9441 attr->aspath->str);
9442
9443 /* Print origin */
9444 json_object_string_add(json_net, "bgpOriginCode",
9445 bgp_origin_str[attr->origin]);
9446 } else {
9447 if (p->family == AF_INET &&
9448 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9449 safi == SAFI_EVPN ||
9450 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9451 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9452 || safi == SAFI_EVPN)
9453 vty_out(vty, "%-16pI4",
9454 &attr->mp_nexthop_global_in);
9455 else if (wide)
9456 vty_out(vty, "%-41pI4", &attr->nexthop);
9457 else
9458 vty_out(vty, "%-16pI4", &attr->nexthop);
9459 } else if (p->family == AF_INET6 ||
9460 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9461 char buf[BUFSIZ];
9462
9463 len = vty_out(
9464 vty, "%s",
9465 inet_ntop(AF_INET6,
9466 &attr->mp_nexthop_global, buf,
9467 BUFSIZ));
9468 len = wide ? (41 - len) : (16 - len);
9469 if (len < 1)
9470 vty_out(vty, "\n%*s", 36, " ");
9471 else
9472 vty_out(vty, "%*s", len, " ");
9473 }
9474 if (attr->flag
9475 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9476 if (wide)
9477 vty_out(vty, "%7u", attr->med);
9478 else
9479 vty_out(vty, "%10u", attr->med);
9480 else if (wide)
9481 vty_out(vty, " ");
9482 else
9483 vty_out(vty, " ");
9484
9485 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9486 vty_out(vty, "%7u", attr->local_pref);
9487 else
9488 vty_out(vty, " ");
9489
9490 vty_out(vty, "%7u ", attr->weight);
9491
9492 /* Print aspath */
9493 if (attr->aspath)
9494 aspath_print_vty(vty, "%s", attr->aspath, " ");
9495
9496 /* Print origin */
9497 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9498 }
9499 }
9500 if (use_json) {
9501 json_object_boolean_true_add(json_status, "*");
9502 json_object_boolean_true_add(json_status, ">");
9503 json_object_object_add(json_net, "appliedStatusSymbols",
9504 json_status);
9505 json_object_object_addf(json_ar, json_net, "%pFX", p);
9506 } else
9507 vty_out(vty, "\n");
9508}
9509
9510void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9511 struct bgp_path_info *path, int display, safi_t safi,
9512 json_object *json)
9513{
9514 json_object *json_out = NULL;
9515 struct attr *attr;
9516 mpls_label_t label = MPLS_INVALID_LABEL;
9517
9518 if (!path->extra)
9519 return;
9520
9521 if (json)
9522 json_out = json_object_new_object();
9523
9524 /* short status lead text */
9525 route_vty_short_status_out(vty, path, p, json_out);
9526
9527 /* print prefix and mask */
9528 if (json == NULL) {
9529 if (!display)
9530 route_vty_out_route(path->net, p, vty, NULL, false);
9531 else
9532 vty_out(vty, "%*s", 17, " ");
9533 }
9534
9535 /* Print attribute */
9536 attr = path->attr;
9537 if (((p->family == AF_INET) &&
9538 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9539 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9540 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9541 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9542 || safi == SAFI_EVPN) {
9543 if (json)
9544 json_object_string_addf(
9545 json_out, "mpNexthopGlobalIn", "%pI4",
9546 &attr->mp_nexthop_global_in);
9547 else
9548 vty_out(vty, "%-16pI4",
9549 &attr->mp_nexthop_global_in);
9550 } else {
9551 if (json)
9552 json_object_string_addf(json_out, "nexthop",
9553 "%pI4", &attr->nexthop);
9554 else
9555 vty_out(vty, "%-16pI4", &attr->nexthop);
9556 }
9557 } else if (((p->family == AF_INET6) &&
9558 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9559 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9560 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9561 char buf_a[512];
9562
9563 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9564 if (json)
9565 json_object_string_addf(
9566 json_out, "mpNexthopGlobalIn", "%pI6",
9567 &attr->mp_nexthop_global);
9568 else
9569 vty_out(vty, "%s",
9570 inet_ntop(AF_INET6,
9571 &attr->mp_nexthop_global,
9572 buf_a, sizeof(buf_a)));
9573 } else if (attr->mp_nexthop_len
9574 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9575 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9576 &attr->mp_nexthop_global,
9577 &attr->mp_nexthop_local);
9578 if (json)
9579 json_object_string_add(json_out,
9580 "mpNexthopGlobalLocal",
9581 buf_a);
9582 else
9583 vty_out(vty, "%s", buf_a);
9584 }
9585 }
9586
9587 label = decode_label(&path->extra->label[0]);
9588
9589 if (bgp_is_valid_label(&label)) {
9590 if (json) {
9591 json_object_int_add(json_out, "notag", label);
9592 json_object_array_add(json, json_out);
9593 } else {
9594 vty_out(vty, "notag/%d", label);
9595 vty_out(vty, "\n");
9596 }
9597 } else if (!json)
9598 vty_out(vty, "\n");
9599}
9600
9601void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9602 struct bgp_path_info *path, int display,
9603 json_object *json_paths)
9604{
9605 struct attr *attr;
9606 json_object *json_path = NULL;
9607 json_object *json_nexthop = NULL;
9608 json_object *json_overlay = NULL;
9609
9610 if (!path->extra)
9611 return;
9612
9613 if (json_paths) {
9614 json_path = json_object_new_object();
9615 json_overlay = json_object_new_object();
9616 json_nexthop = json_object_new_object();
9617 }
9618
9619 /* short status lead text */
9620 route_vty_short_status_out(vty, path, p, json_path);
9621
9622 /* print prefix and mask */
9623 if (!display)
9624 route_vty_out_route(path->net, p, vty, json_path, false);
9625 else
9626 vty_out(vty, "%*s", 17, " ");
9627
9628 /* Print attribute */
9629 attr = path->attr;
9630 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9631
9632 switch (af) {
9633 case AF_INET:
9634 if (!json_path) {
9635 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9636 } else {
9637 json_object_string_addf(json_nexthop, "ip", "%pI4",
9638 &attr->mp_nexthop_global_in);
9639
9640 json_object_string_add(json_nexthop, "afi", "ipv4");
9641
9642 json_object_object_add(json_path, "nexthop",
9643 json_nexthop);
9644 }
9645 break;
9646 case AF_INET6:
9647 if (!json_path) {
9648 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9649 &attr->mp_nexthop_local);
9650 } else {
9651 json_object_string_addf(json_nexthop, "ipv6Global",
9652 "%pI6",
9653 &attr->mp_nexthop_global);
9654
9655 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9656 "%pI6",
9657 &attr->mp_nexthop_local);
9658
9659 json_object_string_add(json_nexthop, "afi", "ipv6");
9660
9661 json_object_object_add(json_path, "nexthop",
9662 json_nexthop);
9663 }
9664 break;
9665 default:
9666 if (!json_path) {
9667 vty_out(vty, "?");
9668 } else {
9669 json_object_string_add(json_nexthop, "Error",
9670 "Unsupported address-family");
9671 json_object_string_add(json_nexthop, "error",
9672 "Unsupported address-family");
9673 }
9674 }
9675
9676 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9677
9678 if (!json_path)
9679 vty_out(vty, "/%pIA", &eo->gw_ip);
9680 else
9681 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9682
9683 if (bgp_attr_get_ecommunity(attr)) {
9684 char *mac = NULL;
9685 struct ecommunity_val *routermac = ecommunity_lookup(
9686 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9687 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9688
9689 if (routermac)
9690 mac = ecom_mac2str((char *)routermac->val);
9691 if (mac) {
9692 if (!json_path) {
9693 vty_out(vty, "/%s", mac);
9694 } else {
9695 json_object_string_add(json_overlay, "rmac",
9696 mac);
9697 }
9698 XFREE(MTYPE_TMP, mac);
9699 }
9700 }
9701
9702 if (!json_path) {
9703 vty_out(vty, "\n");
9704 } else {
9705 json_object_object_add(json_path, "overlay", json_overlay);
9706
9707 json_object_array_add(json_paths, json_path);
9708 }
9709}
9710
9711/* dampening route */
9712static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9713 struct bgp_path_info *path, int display,
9714 afi_t afi, safi_t safi, bool use_json,
9715 json_object *json_paths)
9716{
9717 struct attr *attr = path->attr;
9718 int len;
9719 char timebuf[BGP_UPTIME_LEN];
9720 json_object *json_path = NULL;
9721
9722 if (use_json)
9723 json_path = json_object_new_object();
9724
9725 /* short status lead text */
9726 route_vty_short_status_out(vty, path, p, json_path);
9727
9728 /* print prefix and mask */
9729 if (!use_json) {
9730 if (!display)
9731 route_vty_out_route(path->net, p, vty, NULL, false);
9732 else
9733 vty_out(vty, "%*s", 17, " ");
9734
9735 len = vty_out(vty, "%s", path->peer->host);
9736 len = 17 - len;
9737
9738 if (len < 1)
9739 vty_out(vty, "\n%*s", 34, " ");
9740 else
9741 vty_out(vty, "%*s", len, " ");
9742
9743 vty_out(vty, "%s ",
9744 bgp_damp_reuse_time_vty(vty, path, timebuf,
9745 BGP_UPTIME_LEN, afi, safi,
9746 use_json, NULL));
9747
9748 if (attr->aspath)
9749 aspath_print_vty(vty, "%s", attr->aspath, " ");
9750
9751 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9752
9753 vty_out(vty, "\n");
9754 } else {
9755 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9756 safi, use_json, json_path);
9757
9758 if (attr->aspath)
9759 json_object_string_add(json_path, "asPath",
9760 attr->aspath->str);
9761
9762 json_object_string_add(json_path, "origin",
9763 bgp_origin_str[attr->origin]);
9764 json_object_string_add(json_path, "peerHost", path->peer->host);
9765
9766 json_object_array_add(json_paths, json_path);
9767 }
9768}
9769
9770/* flap route */
9771static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9772 struct bgp_path_info *path, int display,
9773 afi_t afi, safi_t safi, bool use_json,
9774 json_object *json_paths)
9775{
9776 struct attr *attr = path->attr;
9777 struct bgp_damp_info *bdi;
9778 char timebuf[BGP_UPTIME_LEN];
9779 int len;
9780 json_object *json_path = NULL;
9781
9782 if (!path->extra)
9783 return;
9784
9785 if (use_json)
9786 json_path = json_object_new_object();
9787
9788 bdi = path->extra->damp_info;
9789
9790 /* short status lead text */
9791 route_vty_short_status_out(vty, path, p, json_path);
9792
9793 if (!use_json) {
9794 if (!display)
9795 route_vty_out_route(path->net, p, vty, NULL, false);
9796 else
9797 vty_out(vty, "%*s", 17, " ");
9798
9799 len = vty_out(vty, "%s", path->peer->host);
9800 len = 16 - len;
9801 if (len < 1)
9802 vty_out(vty, "\n%*s", 33, " ");
9803 else
9804 vty_out(vty, "%*s", len, " ");
9805
9806 len = vty_out(vty, "%d", bdi->flap);
9807 len = 5 - len;
9808 if (len < 1)
9809 vty_out(vty, " ");
9810 else
9811 vty_out(vty, "%*s", len, " ");
9812
9813 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9814 BGP_UPTIME_LEN, 0, NULL));
9815
9816 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9817 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9818 vty_out(vty, "%s ",
9819 bgp_damp_reuse_time_vty(vty, path, timebuf,
9820 BGP_UPTIME_LEN, afi,
9821 safi, use_json, NULL));
9822 else
9823 vty_out(vty, "%*s ", 8, " ");
9824
9825 if (attr->aspath)
9826 aspath_print_vty(vty, "%s", attr->aspath, " ");
9827
9828 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9829
9830 vty_out(vty, "\n");
9831 } else {
9832 json_object_string_add(json_path, "peerHost", path->peer->host);
9833 json_object_int_add(json_path, "bdiFlap", bdi->flap);
9834
9835 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9836 json_path);
9837
9838 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9839 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9840 bgp_damp_reuse_time_vty(vty, path, timebuf,
9841 BGP_UPTIME_LEN, afi, safi,
9842 use_json, json_path);
9843
9844 if (attr->aspath)
9845 json_object_string_add(json_path, "asPath",
9846 attr->aspath->str);
9847
9848 json_object_string_add(json_path, "origin",
9849 bgp_origin_str[attr->origin]);
9850
9851 json_object_array_add(json_paths, json_path);
9852 }
9853}
9854
9855static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9856 int *first, const char *header,
9857 json_object *json_adv_to)
9858{
9859 json_object *json_peer = NULL;
9860
9861 if (json_adv_to) {
9862 /* 'advertised-to' is a dictionary of peers we have advertised
9863 * this
9864 * prefix too. The key is the peer's IP or swpX, the value is
9865 * the
9866 * hostname if we know it and "" if not.
9867 */
9868 json_peer = json_object_new_object();
9869
9870 if (peer->hostname)
9871 json_object_string_add(json_peer, "hostname",
9872 peer->hostname);
9873
9874 if (peer->conf_if)
9875 json_object_object_add(json_adv_to, peer->conf_if,
9876 json_peer);
9877 else
9878 json_object_object_addf(json_adv_to, json_peer, "%pSU",
9879 &peer->su);
9880 } else {
9881 if (*first) {
9882 vty_out(vty, "%s", header);
9883 *first = 0;
9884 }
9885
9886 if (peer->hostname
9887 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9888 if (peer->conf_if)
9889 vty_out(vty, " %s(%s)", peer->hostname,
9890 peer->conf_if);
9891 else
9892 vty_out(vty, " %s(%pSU)", peer->hostname,
9893 &peer->su);
9894 } else {
9895 if (peer->conf_if)
9896 vty_out(vty, " %s", peer->conf_if);
9897 else
9898 vty_out(vty, " %pSU", &peer->su);
9899 }
9900 }
9901}
9902
9903static void route_vty_out_tx_ids(struct vty *vty,
9904 struct bgp_addpath_info_data *d)
9905{
9906 int i;
9907
9908 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9909 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9910 d->addpath_tx_id[i],
9911 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9912 }
9913}
9914
9915static void route_vty_out_detail_es_info(struct vty *vty,
9916 struct bgp_path_info *pi,
9917 struct attr *attr,
9918 json_object *json_path)
9919{
9920 char esi_buf[ESI_STR_LEN];
9921 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9922 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9923 ATTR_ES_PEER_ROUTER);
9924 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9925 ATTR_ES_PEER_ACTIVE);
9926 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9927 ATTR_ES_PEER_PROXY);
9928 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9929 if (json_path) {
9930 json_object *json_es_info = NULL;
9931
9932 json_object_string_add(
9933 json_path, "esi",
9934 esi_buf);
9935 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9936 json_es_info = json_object_new_object();
9937 if (es_local)
9938 json_object_boolean_true_add(
9939 json_es_info, "localEs");
9940 if (peer_active)
9941 json_object_boolean_true_add(
9942 json_es_info, "peerActive");
9943 if (peer_proxy)
9944 json_object_boolean_true_add(
9945 json_es_info, "peerProxy");
9946 if (peer_router)
9947 json_object_boolean_true_add(
9948 json_es_info, "peerRouter");
9949 if (attr->mm_sync_seqnum)
9950 json_object_int_add(
9951 json_es_info, "peerSeq",
9952 attr->mm_sync_seqnum);
9953 json_object_object_add(
9954 json_path, "es_info",
9955 json_es_info);
9956 }
9957 } else {
9958 if (bgp_evpn_attr_is_sync(attr))
9959 vty_out(vty,
9960 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9961 esi_buf,
9962 es_local ? "local-es":"",
9963 peer_proxy ? "proxy " : "",
9964 peer_active ? "active ":"",
9965 peer_router ? "router ":"",
9966 attr->mm_sync_seqnum);
9967 else
9968 vty_out(vty, " ESI %s %s\n",
9969 esi_buf,
9970 es_local ? "local-es":"");
9971 }
9972}
9973
9974void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
9975 struct bgp_path_info *path, afi_t afi, safi_t safi,
9976 enum rpki_states rpki_curr_state,
9977 json_object *json_paths)
9978{
9979 char buf[INET6_ADDRSTRLEN];
9980 char buf1[BUFSIZ];
9981 struct attr *attr = path->attr;
9982 time_t tbuf;
9983 json_object *json_bestpath = NULL;
9984 json_object *json_cluster_list = NULL;
9985 json_object *json_cluster_list_list = NULL;
9986 json_object *json_ext_community = NULL;
9987 json_object *json_last_update = NULL;
9988 json_object *json_pmsi = NULL;
9989 json_object *json_nexthop_global = NULL;
9990 json_object *json_nexthop_ll = NULL;
9991 json_object *json_nexthops = NULL;
9992 json_object *json_path = NULL;
9993 json_object *json_peer = NULL;
9994 json_object *json_string = NULL;
9995 json_object *json_adv_to = NULL;
9996 int first = 0;
9997 struct listnode *node, *nnode;
9998 struct peer *peer;
9999 bool addpath_capable;
10000 int has_adj;
10001 unsigned int first_as;
10002 bool nexthop_self =
10003 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10004 int i;
10005 char *nexthop_hostname =
10006 bgp_nexthop_hostname(path->peer, path->nexthop);
10007 uint32_t ttl = 0;
10008 uint32_t bos = 0;
10009 uint32_t exp = 0;
10010 mpls_label_t label = MPLS_INVALID_LABEL;
10011
10012 if (json_paths) {
10013 json_path = json_object_new_object();
10014 json_peer = json_object_new_object();
10015 json_nexthop_global = json_object_new_object();
10016 }
10017
10018 if (safi == SAFI_EVPN) {
10019 if (!json_paths)
10020 vty_out(vty, " Route %pRN", bn);
10021 }
10022
10023 if (path->extra) {
10024 char tag_buf[30];
10025
10026 tag_buf[0] = '\0';
10027 if (path->extra && path->extra->num_labels) {
10028 bgp_evpn_label2str(path->extra->label,
10029 path->extra->num_labels, tag_buf,
10030 sizeof(tag_buf));
10031 }
10032 if (safi == SAFI_EVPN) {
10033 if (!json_paths) {
10034 if (tag_buf[0] != '\0')
10035 vty_out(vty, " VNI %s", tag_buf);
10036 } else {
10037 if (tag_buf[0]) {
10038 json_object_string_add(json_path, "VNI",
10039 tag_buf);
10040 json_object_string_add(json_path, "vni",
10041 tag_buf);
10042 }
10043 }
10044 }
10045
10046 if (path->extra && path->extra->parent && !json_paths) {
10047 struct bgp_path_info *parent_ri;
10048 struct bgp_dest *dest, *pdest;
10049
10050 parent_ri = (struct bgp_path_info *)path->extra->parent;
10051 dest = parent_ri->net;
10052 if (dest && dest->pdest) {
10053 pdest = dest->pdest;
10054 prefix_rd2str(
10055 (struct prefix_rd *)bgp_dest_get_prefix(
10056 pdest),
10057 buf1, sizeof(buf1));
10058 if (is_pi_family_evpn(parent_ri)) {
10059 vty_out(vty,
10060 " Imported from %s:%pFX, VNI %s",
10061 buf1,
10062 (struct prefix_evpn *)
10063 bgp_dest_get_prefix(
10064 dest),
10065 tag_buf);
10066 if (attr->es_flags & ATTR_ES_L3_NHG)
10067 vty_out(vty, ", L3NHG %s",
10068 (attr->es_flags
10069 & ATTR_ES_L3_NHG_ACTIVE)
10070 ? "active"
10071 : "inactive");
10072 vty_out(vty, "\n");
10073
10074 } else
10075 vty_out(vty,
10076 " Imported from %s:%pFX\n",
10077 buf1,
10078 (struct prefix_evpn *)
10079 bgp_dest_get_prefix(
10080 dest));
10081 }
10082 }
10083 }
10084
10085 if (safi == SAFI_EVPN
10086 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10087 char gwip_buf[INET6_ADDRSTRLEN];
10088
10089 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10090 sizeof(gwip_buf));
10091
10092 if (json_paths)
10093 json_object_string_add(json_path, "gatewayIP",
10094 gwip_buf);
10095 else
10096 vty_out(vty, " Gateway IP %s", gwip_buf);
10097 }
10098
10099 if (safi == SAFI_EVPN && !json_path)
10100 vty_out(vty, "\n");
10101
10102 /* Line1 display AS-path, Aggregator */
10103 if (attr->aspath) {
10104 if (json_paths) {
10105 if (!attr->aspath->json)
10106 aspath_str_update(attr->aspath, true);
10107 json_object_lock(attr->aspath->json);
10108 json_object_object_add(json_path, "aspath",
10109 attr->aspath->json);
10110 } else {
10111 if (attr->aspath->segments)
10112 aspath_print_vty(vty, " %s", attr->aspath, "");
10113 else
10114 vty_out(vty, " Local");
10115 }
10116 }
10117
10118 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10119 if (json_paths)
10120 json_object_boolean_true_add(json_path, "removed");
10121 else
10122 vty_out(vty, ", (removed)");
10123 }
10124
10125 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10126 if (json_paths)
10127 json_object_boolean_true_add(json_path, "stale");
10128 else
10129 vty_out(vty, ", (stale)");
10130 }
10131
10132 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10133 if (json_paths) {
10134 json_object_int_add(json_path, "aggregatorAs",
10135 attr->aggregator_as);
10136 json_object_string_addf(json_path, "aggregatorId",
10137 "%pI4", &attr->aggregator_addr);
10138 } else {
10139 vty_out(vty, ", (aggregated by %u %pI4)",
10140 attr->aggregator_as, &attr->aggregator_addr);
10141 }
10142 }
10143
10144 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10145 PEER_FLAG_REFLECTOR_CLIENT)) {
10146 if (json_paths)
10147 json_object_boolean_true_add(json_path,
10148 "rxedFromRrClient");
10149 else
10150 vty_out(vty, ", (Received from a RR-client)");
10151 }
10152
10153 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10154 PEER_FLAG_RSERVER_CLIENT)) {
10155 if (json_paths)
10156 json_object_boolean_true_add(json_path,
10157 "rxedFromRsClient");
10158 else
10159 vty_out(vty, ", (Received from a RS-client)");
10160 }
10161
10162 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10163 if (json_paths)
10164 json_object_boolean_true_add(json_path,
10165 "dampeningHistoryEntry");
10166 else
10167 vty_out(vty, ", (history entry)");
10168 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10169 if (json_paths)
10170 json_object_boolean_true_add(json_path,
10171 "dampeningSuppressed");
10172 else
10173 vty_out(vty, ", (suppressed due to dampening)");
10174 }
10175
10176 if (!json_paths)
10177 vty_out(vty, "\n");
10178
10179 /* Line2 display Next-hop, Neighbor, Router-id */
10180 /* Display the nexthop */
10181 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10182
10183 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET ||
10184 bn_p->family == AF_EVPN) &&
10185 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10186 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10187 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10188 || safi == SAFI_EVPN) {
10189 if (json_paths) {
10190 json_object_string_addf(
10191 json_nexthop_global, "ip", "%pI4",
10192 &attr->mp_nexthop_global_in);
10193
10194 if (path->peer->hostname)
10195 json_object_string_add(
10196 json_nexthop_global, "hostname",
10197 path->peer->hostname);
10198 } else {
10199 if (nexthop_hostname)
10200 vty_out(vty, " %pI4(%s)",
10201 &attr->mp_nexthop_global_in,
10202 nexthop_hostname);
10203 else
10204 vty_out(vty, " %pI4",
10205 &attr->mp_nexthop_global_in);
10206 }
10207 } else {
10208 if (json_paths) {
10209 json_object_string_addf(json_nexthop_global,
10210 "ip", "%pI4",
10211 &attr->nexthop);
10212
10213 if (path->peer->hostname)
10214 json_object_string_add(
10215 json_nexthop_global, "hostname",
10216 path->peer->hostname);
10217 } else {
10218 if (nexthop_hostname)
10219 vty_out(vty, " %pI4(%s)",
10220 &attr->nexthop,
10221 nexthop_hostname);
10222 else
10223 vty_out(vty, " %pI4",
10224 &attr->nexthop);
10225 }
10226 }
10227
10228 if (json_paths)
10229 json_object_string_add(json_nexthop_global, "afi",
10230 "ipv4");
10231 } else {
10232 if (json_paths) {
10233 json_object_string_addf(json_nexthop_global, "ip",
10234 "%pI6",
10235 &attr->mp_nexthop_global);
10236
10237 if (path->peer->hostname)
10238 json_object_string_add(json_nexthop_global,
10239 "hostname",
10240 path->peer->hostname);
10241
10242 json_object_string_add(json_nexthop_global, "afi",
10243 "ipv6");
10244 json_object_string_add(json_nexthop_global, "scope",
10245 "global");
10246 } else {
10247 if (nexthop_hostname)
10248 vty_out(vty, " %pI6(%s)",
10249 &attr->mp_nexthop_global,
10250 nexthop_hostname);
10251 else
10252 vty_out(vty, " %pI6",
10253 &attr->mp_nexthop_global);
10254 }
10255 }
10256
10257 /* Display the IGP cost or 'inaccessible' */
10258 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10259 if (json_paths)
10260 json_object_boolean_false_add(json_nexthop_global,
10261 "accessible");
10262 else
10263 vty_out(vty, " (inaccessible)");
10264 } else {
10265 if (path->extra && path->extra->igpmetric) {
10266 if (json_paths)
10267 json_object_int_add(json_nexthop_global,
10268 "metric",
10269 path->extra->igpmetric);
10270 else
10271 vty_out(vty, " (metric %u)",
10272 path->extra->igpmetric);
10273 }
10274
10275 /* IGP cost is 0, display this only for json */
10276 else {
10277 if (json_paths)
10278 json_object_int_add(json_nexthop_global,
10279 "metric", 0);
10280 }
10281
10282 if (json_paths)
10283 json_object_boolean_true_add(json_nexthop_global,
10284 "accessible");
10285 }
10286
10287 /* Display peer "from" output */
10288 /* This path was originated locally */
10289 if (path->peer == bgp->peer_self) {
10290
10291 if (safi == SAFI_EVPN || (bn_p->family == AF_INET &&
10292 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10293 if (json_paths)
10294 json_object_string_add(json_peer, "peerId",
10295 "0.0.0.0");
10296 else
10297 vty_out(vty, " from 0.0.0.0 ");
10298 } else {
10299 if (json_paths)
10300 json_object_string_add(json_peer, "peerId",
10301 "::");
10302 else
10303 vty_out(vty, " from :: ");
10304 }
10305
10306 if (json_paths)
10307 json_object_string_addf(json_peer, "routerId", "%pI4",
10308 &bgp->router_id);
10309 else
10310 vty_out(vty, "(%pI4)", &bgp->router_id);
10311 }
10312
10313 /* We RXed this path from one of our peers */
10314 else {
10315
10316 if (json_paths) {
10317 json_object_string_addf(json_peer, "peerId", "%pSU",
10318 &path->peer->su);
10319 json_object_string_addf(json_peer, "routerId", "%pI4",
10320 &path->peer->remote_id);
10321
10322 if (path->peer->hostname)
10323 json_object_string_add(json_peer, "hostname",
10324 path->peer->hostname);
10325
10326 if (path->peer->domainname)
10327 json_object_string_add(json_peer, "domainname",
10328 path->peer->domainname);
10329
10330 if (path->peer->conf_if)
10331 json_object_string_add(json_peer, "interface",
10332 path->peer->conf_if);
10333 } else {
10334 if (path->peer->conf_if) {
10335 if (path->peer->hostname
10336 && CHECK_FLAG(path->peer->bgp->flags,
10337 BGP_FLAG_SHOW_HOSTNAME))
10338 vty_out(vty, " from %s(%s)",
10339 path->peer->hostname,
10340 path->peer->conf_if);
10341 else
10342 vty_out(vty, " from %s",
10343 path->peer->conf_if);
10344 } else {
10345 if (path->peer->hostname
10346 && CHECK_FLAG(path->peer->bgp->flags,
10347 BGP_FLAG_SHOW_HOSTNAME))
10348 vty_out(vty, " from %s(%s)",
10349 path->peer->hostname,
10350 path->peer->host);
10351 else
10352 vty_out(vty, " from %pSU",
10353 &path->peer->su);
10354 }
10355
10356 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10357 vty_out(vty, " (%pI4)", &attr->originator_id);
10358 else
10359 vty_out(vty, " (%s)",
10360 inet_ntop(AF_INET,
10361 &path->peer->remote_id, buf1,
10362 sizeof(buf1)));
10363 }
10364 }
10365
10366 /*
10367 * Note when vrfid of nexthop is different from that of prefix
10368 */
10369 if (path->extra && path->extra->bgp_orig) {
10370 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10371
10372 if (json_paths) {
10373 const char *vn;
10374
10375 if (path->extra->bgp_orig->inst_type
10376 == BGP_INSTANCE_TYPE_DEFAULT)
10377 vn = VRF_DEFAULT_NAME;
10378 else
10379 vn = path->extra->bgp_orig->name;
10380
10381 json_object_string_add(json_path, "nhVrfName", vn);
10382
10383 if (nexthop_vrfid == VRF_UNKNOWN) {
10384 json_object_int_add(json_path, "nhVrfId", -1);
10385 } else {
10386 json_object_int_add(json_path, "nhVrfId",
10387 (int)nexthop_vrfid);
10388 }
10389 } else {
10390 if (nexthop_vrfid == VRF_UNKNOWN)
10391 vty_out(vty, " vrf ?");
10392 else {
10393 struct vrf *vrf;
10394
10395 vrf = vrf_lookup_by_id(nexthop_vrfid);
10396 vty_out(vty, " vrf %s(%u)",
10397 VRF_LOGNAME(vrf), nexthop_vrfid);
10398 }
10399 }
10400 }
10401
10402 if (nexthop_self) {
10403 if (json_paths) {
10404 json_object_boolean_true_add(json_path,
10405 "announceNexthopSelf");
10406 } else {
10407 vty_out(vty, " announce-nh-self");
10408 }
10409 }
10410
10411 if (!json_paths)
10412 vty_out(vty, "\n");
10413
10414 /* display the link-local nexthop */
10415 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10416 if (json_paths) {
10417 json_nexthop_ll = json_object_new_object();
10418 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10419 &attr->mp_nexthop_local);
10420
10421 if (path->peer->hostname)
10422 json_object_string_add(json_nexthop_ll,
10423 "hostname",
10424 path->peer->hostname);
10425
10426 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10427 json_object_string_add(json_nexthop_ll, "scope",
10428 "link-local");
10429
10430 json_object_boolean_true_add(json_nexthop_ll,
10431 "accessible");
10432
10433 if (!attr->mp_nexthop_prefer_global)
10434 json_object_boolean_true_add(json_nexthop_ll,
10435 "used");
10436 else
10437 json_object_boolean_true_add(
10438 json_nexthop_global, "used");
10439 } else {
10440 vty_out(vty, " (%s) %s\n",
10441 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10442 buf, INET6_ADDRSTRLEN),
10443 attr->mp_nexthop_prefer_global
10444 ? "(prefer-global)"
10445 : "(used)");
10446 }
10447 }
10448 /* If we do not have a link-local nexthop then we must flag the
10449 global as "used" */
10450 else {
10451 if (json_paths)
10452 json_object_boolean_true_add(json_nexthop_global,
10453 "used");
10454 }
10455
10456 if (safi == SAFI_EVPN &&
10457 bgp_evpn_is_esi_valid(&attr->esi)) {
10458 route_vty_out_detail_es_info(vty, path, attr, json_path);
10459 }
10460
10461 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10462 * Int/Ext/Local, Atomic, best */
10463 if (json_paths)
10464 json_object_string_add(json_path, "origin",
10465 bgp_origin_long_str[attr->origin]);
10466 else
10467 vty_out(vty, " Origin %s",
10468 bgp_origin_long_str[attr->origin]);
10469
10470 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10471 if (json_paths)
10472 json_object_int_add(json_path, "metric", attr->med);
10473 else
10474 vty_out(vty, ", metric %u", attr->med);
10475 }
10476
10477 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10478 if (json_paths)
10479 json_object_int_add(json_path, "locPrf",
10480 attr->local_pref);
10481 else
10482 vty_out(vty, ", localpref %u", attr->local_pref);
10483 }
10484
10485 if (attr->weight != 0) {
10486 if (json_paths)
10487 json_object_int_add(json_path, "weight", attr->weight);
10488 else
10489 vty_out(vty, ", weight %u", attr->weight);
10490 }
10491
10492 if (attr->tag != 0) {
10493 if (json_paths)
10494 json_object_int_add(json_path, "tag", attr->tag);
10495 else
10496 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10497 }
10498
10499 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10500 if (json_paths)
10501 json_object_boolean_false_add(json_path, "valid");
10502 else
10503 vty_out(vty, ", invalid");
10504 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10505 if (json_paths)
10506 json_object_boolean_true_add(json_path, "valid");
10507 else
10508 vty_out(vty, ", valid");
10509 }
10510
10511 if (json_paths)
10512 json_object_int_add(json_path, "version", bn->version);
10513
10514 if (path->peer != bgp->peer_self) {
10515 if (path->peer->as == path->peer->local_as) {
10516 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10517 if (json_paths)
10518 json_object_string_add(
10519 json_peer, "type",
10520 "confed-internal");
10521 else
10522 vty_out(vty, ", confed-internal");
10523 } else {
10524 if (json_paths)
10525 json_object_string_add(
10526 json_peer, "type", "internal");
10527 else
10528 vty_out(vty, ", internal");
10529 }
10530 } else {
10531 if (bgp_confederation_peers_check(bgp,
10532 path->peer->as)) {
10533 if (json_paths)
10534 json_object_string_add(
10535 json_peer, "type",
10536 "confed-external");
10537 else
10538 vty_out(vty, ", confed-external");
10539 } else {
10540 if (json_paths)
10541 json_object_string_add(
10542 json_peer, "type", "external");
10543 else
10544 vty_out(vty, ", external");
10545 }
10546 }
10547 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10548 if (json_paths) {
10549 json_object_boolean_true_add(json_path, "aggregated");
10550 json_object_boolean_true_add(json_path, "local");
10551 } else {
10552 vty_out(vty, ", aggregated, local");
10553 }
10554 } else if (path->type != ZEBRA_ROUTE_BGP) {
10555 if (json_paths)
10556 json_object_boolean_true_add(json_path, "sourced");
10557 else
10558 vty_out(vty, ", sourced");
10559 } else {
10560 if (json_paths) {
10561 json_object_boolean_true_add(json_path, "sourced");
10562 json_object_boolean_true_add(json_path, "local");
10563 } else {
10564 vty_out(vty, ", sourced, local");
10565 }
10566 }
10567
10568 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10569 if (json_paths)
10570 json_object_boolean_true_add(json_path,
10571 "atomicAggregate");
10572 else
10573 vty_out(vty, ", atomic-aggregate");
10574 }
10575
10576 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10577 if (json_paths)
10578 json_object_int_add(json_path, "otc", attr->otc);
10579 else
10580 vty_out(vty, ", otc %u", attr->otc);
10581 }
10582
10583 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10584 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10585 && bgp_path_info_mpath_count(path))) {
10586 if (json_paths)
10587 json_object_boolean_true_add(json_path, "multipath");
10588 else
10589 vty_out(vty, ", multipath");
10590 }
10591
10592 // Mark the bestpath(s)
10593 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10594 first_as = aspath_get_first_as(attr->aspath);
10595
10596 if (json_paths) {
10597 if (!json_bestpath)
10598 json_bestpath = json_object_new_object();
10599 json_object_int_add(json_bestpath, "bestpathFromAs",
10600 first_as);
10601 } else {
10602 if (first_as)
10603 vty_out(vty, ", bestpath-from-AS %u", first_as);
10604 else
10605 vty_out(vty, ", bestpath-from-AS Local");
10606 }
10607 }
10608
10609 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10610 if (json_paths) {
10611 if (!json_bestpath)
10612 json_bestpath = json_object_new_object();
10613 json_object_boolean_true_add(json_bestpath, "overall");
10614 json_object_string_add(
10615 json_bestpath, "selectionReason",
10616 bgp_path_selection_reason2str(bn->reason));
10617 } else {
10618 vty_out(vty, ", best");
10619 vty_out(vty, " (%s)",
10620 bgp_path_selection_reason2str(bn->reason));
10621 }
10622 }
10623
10624 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10625 if (json_paths)
10626 json_object_string_add(
10627 json_path, "rpkiValidationState",
10628 bgp_rpki_validation2str(rpki_curr_state));
10629 else
10630 vty_out(vty, ", rpki validation-state: %s",
10631 bgp_rpki_validation2str(rpki_curr_state));
10632 }
10633
10634 if (json_bestpath)
10635 json_object_object_add(json_path, "bestpath", json_bestpath);
10636
10637 if (!json_paths)
10638 vty_out(vty, "\n");
10639
10640 /* Line 4 display Community */
10641 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10642 if (json_paths) {
10643 if (!bgp_attr_get_community(attr)->json)
10644 community_str(bgp_attr_get_community(attr),
10645 true, true);
10646 json_object_lock(bgp_attr_get_community(attr)->json);
10647 json_object_object_add(
10648 json_path, "community",
10649 bgp_attr_get_community(attr)->json);
10650 } else {
10651 vty_out(vty, " Community: %s\n",
10652 bgp_attr_get_community(attr)->str);
10653 }
10654 }
10655
10656 /* Line 5 display Extended-community */
10657 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10658 if (json_paths) {
10659 json_ext_community = json_object_new_object();
10660 json_object_string_add(
10661 json_ext_community, "string",
10662 bgp_attr_get_ecommunity(attr)->str);
10663 json_object_object_add(json_path, "extendedCommunity",
10664 json_ext_community);
10665 } else {
10666 vty_out(vty, " Extended Community: %s\n",
10667 bgp_attr_get_ecommunity(attr)->str);
10668 }
10669 }
10670
10671 /* Line 6 display Large community */
10672 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10673 if (json_paths) {
10674 if (!bgp_attr_get_lcommunity(attr)->json)
10675 lcommunity_str(bgp_attr_get_lcommunity(attr),
10676 true, true);
10677 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10678 json_object_object_add(
10679 json_path, "largeCommunity",
10680 bgp_attr_get_lcommunity(attr)->json);
10681 } else {
10682 vty_out(vty, " Large Community: %s\n",
10683 bgp_attr_get_lcommunity(attr)->str);
10684 }
10685 }
10686
10687 /* Line 7 display Originator, Cluster-id */
10688 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10689 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10690 char buf[BUFSIZ] = {0};
10691
10692 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10693 if (json_paths)
10694 json_object_string_addf(json_path,
10695 "originatorId", "%pI4",
10696 &attr->originator_id);
10697 else
10698 vty_out(vty, " Originator: %pI4",
10699 &attr->originator_id);
10700 }
10701
10702 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10703 struct cluster_list *cluster =
10704 bgp_attr_get_cluster(attr);
10705 int i;
10706
10707 if (json_paths) {
10708 json_cluster_list = json_object_new_object();
10709 json_cluster_list_list =
10710 json_object_new_array();
10711
10712 for (i = 0; i < cluster->length / 4; i++) {
10713 json_string = json_object_new_string(
10714 inet_ntop(AF_INET,
10715 &cluster->list[i],
10716 buf, sizeof(buf)));
10717 json_object_array_add(
10718 json_cluster_list_list,
10719 json_string);
10720 }
10721
10722 /*
10723 * struct cluster_list does not have
10724 * "str" variable like aspath and community
10725 * do. Add this someday if someone asks
10726 * for it.
10727 * json_object_string_add(json_cluster_list,
10728 * "string", cluster->str);
10729 */
10730 json_object_object_add(json_cluster_list,
10731 "list",
10732 json_cluster_list_list);
10733 json_object_object_add(json_path, "clusterList",
10734 json_cluster_list);
10735 } else {
10736 vty_out(vty, ", Cluster list: ");
10737
10738 for (i = 0; i < cluster->length / 4; i++) {
10739 vty_out(vty, "%pI4 ",
10740 &cluster->list[i]);
10741 }
10742 }
10743 }
10744
10745 if (!json_paths)
10746 vty_out(vty, "\n");
10747 }
10748
10749 if (path->extra && path->extra->damp_info)
10750 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10751
10752 /* Remote Label */
10753 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10754 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10755 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10756 &bos);
10757
10758 if (json_paths)
10759 json_object_int_add(json_path, "remoteLabel", label);
10760 else
10761 vty_out(vty, " Remote label: %d\n", label);
10762 }
10763
10764 /* Remote SID */
10765 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10766 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
10767 if (json_paths)
10768 json_object_string_add(json_path, "remoteSid", buf);
10769 else
10770 vty_out(vty, " Remote SID: %s\n", buf);
10771 }
10772
10773 /* Label Index */
10774 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10775 if (json_paths)
10776 json_object_int_add(json_path, "labelIndex",
10777 attr->label_index);
10778 else
10779 vty_out(vty, " Label Index: %d\n",
10780 attr->label_index);
10781 }
10782
10783 /* Line 8 display Addpath IDs */
10784 if (path->addpath_rx_id
10785 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10786 if (json_paths) {
10787 json_object_int_add(json_path, "addpathRxId",
10788 path->addpath_rx_id);
10789
10790 /* Keep backwards compatibility with the old API
10791 * by putting TX All's ID in the old field
10792 */
10793 json_object_int_add(
10794 json_path, "addpathTxId",
10795 path->tx_addpath
10796 .addpath_tx_id[BGP_ADDPATH_ALL]);
10797
10798 /* ... but create a specific field for each
10799 * strategy
10800 */
10801 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10802 json_object_int_add(
10803 json_path,
10804 bgp_addpath_names(i)->id_json_name,
10805 path->tx_addpath.addpath_tx_id[i]);
10806 }
10807 } else {
10808 vty_out(vty, " AddPath ID: RX %u, ",
10809 path->addpath_rx_id);
10810
10811 route_vty_out_tx_ids(vty, &path->tx_addpath);
10812 }
10813 }
10814
10815 /* If we used addpath to TX a non-bestpath we need to display
10816 * "Advertised to" on a path-by-path basis
10817 */
10818 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10819 first = 1;
10820
10821 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10822 addpath_capable =
10823 bgp_addpath_encode_tx(peer, afi, safi);
10824 has_adj = bgp_adj_out_lookup(
10825 peer, path->net,
10826 bgp_addpath_id_for_peer(peer, afi, safi,
10827 &path->tx_addpath));
10828
10829 if ((addpath_capable && has_adj)
10830 || (!addpath_capable && has_adj
10831 && CHECK_FLAG(path->flags,
10832 BGP_PATH_SELECTED))) {
10833 if (json_path && !json_adv_to)
10834 json_adv_to = json_object_new_object();
10835
10836 route_vty_out_advertised_to(
10837 vty, peer, &first,
10838 " Advertised to:", json_adv_to);
10839 }
10840 }
10841
10842 if (json_path) {
10843 if (json_adv_to) {
10844 json_object_object_add(
10845 json_path, "advertisedTo", json_adv_to);
10846 }
10847 } else {
10848 if (!first) {
10849 vty_out(vty, "\n");
10850 }
10851 }
10852 }
10853
10854 /* Line 9 display Uptime */
10855 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
10856 if (json_paths) {
10857 json_last_update = json_object_new_object();
10858 json_object_int_add(json_last_update, "epoch", tbuf);
10859 json_object_string_add(json_last_update, "string",
10860 ctime(&tbuf));
10861 json_object_object_add(json_path, "lastUpdate",
10862 json_last_update);
10863 } else
10864 vty_out(vty, " Last update: %s", ctime(&tbuf));
10865
10866 /* Line 10 display PMSI tunnel attribute, if present */
10867 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10868 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10869 bgp_attr_get_pmsi_tnl_type(attr),
10870 PMSI_TNLTYPE_STR_DEFAULT);
10871
10872 if (json_paths) {
10873 json_pmsi = json_object_new_object();
10874 json_object_string_add(json_pmsi, "tunnelType", str);
10875 json_object_int_add(json_pmsi, "label",
10876 label2vni(&attr->label));
10877 json_object_object_add(json_path, "pmsi", json_pmsi);
10878 } else
10879 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10880 str, label2vni(&attr->label));
10881 }
10882
10883 if (path->peer->t_gr_restart &&
10884 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10885 unsigned long gr_remaining =
10886 thread_timer_remain_second(path->peer->t_gr_restart);
10887
10888 if (json_paths) {
10889 json_object_int_add(json_path,
10890 "gracefulRestartSecondsRemaining",
10891 gr_remaining);
10892 } else
10893 vty_out(vty,
10894 " Time until Graceful Restart stale route deleted: %lu\n",
10895 gr_remaining);
10896 }
10897
10898 if (path->peer->t_llgr_stale[afi][safi] &&
10899 bgp_attr_get_community(attr) &&
10900 community_include(bgp_attr_get_community(attr),
10901 COMMUNITY_LLGR_STALE)) {
10902 unsigned long llgr_remaining = thread_timer_remain_second(
10903 path->peer->t_llgr_stale[afi][safi]);
10904
10905 if (json_paths) {
10906 json_object_int_add(json_path, "llgrSecondsRemaining",
10907 llgr_remaining);
10908 } else
10909 vty_out(vty,
10910 " Time until Long-lived stale route deleted: %lu\n",
10911 llgr_remaining);
10912 }
10913
10914 /* Output some debug about internal state of the dest flags */
10915 if (json_paths) {
10916 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10917 json_object_boolean_true_add(json_path, "processScheduled");
10918 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10919 json_object_boolean_true_add(json_path, "userCleared");
10920 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10921 json_object_boolean_true_add(json_path, "labelChanged");
10922 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10923 json_object_boolean_true_add(json_path, "registeredForLabel");
10924 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10925 json_object_boolean_true_add(json_path, "selectDefered");
10926 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10927 json_object_boolean_true_add(json_path, "fibInstalled");
10928 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10929 json_object_boolean_true_add(json_path, "fibPending");
10930
10931 if (json_nexthop_global || json_nexthop_ll) {
10932 json_nexthops = json_object_new_array();
10933
10934 if (json_nexthop_global)
10935 json_object_array_add(json_nexthops,
10936 json_nexthop_global);
10937
10938 if (json_nexthop_ll)
10939 json_object_array_add(json_nexthops,
10940 json_nexthop_ll);
10941
10942 json_object_object_add(json_path, "nexthops",
10943 json_nexthops);
10944 }
10945
10946 json_object_object_add(json_path, "peer", json_peer);
10947 json_object_array_add(json_paths, json_path);
10948 }
10949}
10950
10951#define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10952#define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10953#define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10954
10955static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10956 afi_t afi, safi_t safi, enum bgp_show_type type,
10957 bool use_json);
10958static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10959 const char *comstr, int exact, afi_t afi,
10960 safi_t safi, uint16_t show_flags);
10961
10962static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10963 struct bgp_table *table, enum bgp_show_type type,
10964 void *output_arg, const char *rd, int is_last,
10965 unsigned long *output_cum, unsigned long *total_cum,
10966 unsigned long *json_header_depth, uint16_t show_flags,
10967 enum rpki_states rpki_target_state)
10968{
10969 struct bgp_path_info *pi;
10970 struct bgp_dest *dest;
10971 bool header = true;
10972 bool json_detail_header = false;
10973 int display;
10974 unsigned long output_count = 0;
10975 unsigned long total_count = 0;
10976 struct prefix *p;
10977 json_object *json_paths = NULL;
10978 int first = 1;
10979 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10980 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10981 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10982
10983 if (output_cum && *output_cum != 0)
10984 header = false;
10985
10986 if (use_json && !*json_header_depth) {
10987 if (all)
10988 *json_header_depth = 1;
10989 else {
10990 vty_out(vty, "{\n");
10991 *json_header_depth = 2;
10992 }
10993
10994 vty_out(vty,
10995 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10996 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10997 " \"localAS\": %u,\n \"routes\": { ",
10998 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10999 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11000 ? VRF_DEFAULT_NAME
11001 : bgp->name,
11002 table->version, &bgp->router_id,
11003 bgp->default_local_pref, bgp->as);
11004 if (rd) {
11005 vty_out(vty, " \"routeDistinguishers\" : {");
11006 ++*json_header_depth;
11007 }
11008 }
11009
11010 if (use_json && rd) {
11011 vty_out(vty, " \"%s\" : { ", rd);
11012 }
11013
11014 /* Check for 'json detail', where we need header output once per dest */
11015 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
11016 type != bgp_show_type_dampend_paths &&
11017 type != bgp_show_type_damp_neighbor &&
11018 type != bgp_show_type_flap_statistics &&
11019 type != bgp_show_type_flap_neighbor)
11020 json_detail_header = true;
11021
11022 /* Start processing of routes. */
11023 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11024 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11025 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11026 bool json_detail = json_detail_header;
11027
11028 pi = bgp_dest_get_bgp_path_info(dest);
11029 if (pi == NULL)
11030 continue;
11031
11032 display = 0;
11033 if (use_json)
11034 json_paths = json_object_new_array();
11035 else
11036 json_paths = NULL;
11037
11038 for (; pi; pi = pi->next) {
11039 struct community *picomm = NULL;
11040
11041 picomm = bgp_attr_get_community(pi->attr);
11042
11043 total_count++;
11044
11045 if (type == bgp_show_type_prefix_version) {
11046 uint32_t version =
11047 strtoul(output_arg, NULL, 10);
11048 if (dest->version < version)
11049 continue;
11050 }
11051
11052 if (type == bgp_show_type_community_alias) {
11053 char *alias = output_arg;
11054 char **communities;
11055 int num;
11056 bool found = false;
11057
11058 if (picomm) {
11059 frrstr_split(picomm->str, " ",
11060 &communities, &num);
11061 for (int i = 0; i < num; i++) {
11062 const char *com2alias =
11063 bgp_community2alias(
11064 communities[i]);
11065 if (!found
11066 && strcmp(alias, com2alias)
11067 == 0)
11068 found = true;
11069 XFREE(MTYPE_TMP,
11070 communities[i]);
11071 }
11072 XFREE(MTYPE_TMP, communities);
11073 }
11074
11075 if (!found &&
11076 bgp_attr_get_lcommunity(pi->attr)) {
11077 frrstr_split(bgp_attr_get_lcommunity(
11078 pi->attr)
11079 ->str,
11080 " ", &communities, &num);
11081 for (int i = 0; i < num; i++) {
11082 const char *com2alias =
11083 bgp_community2alias(
11084 communities[i]);
11085 if (!found
11086 && strcmp(alias, com2alias)
11087 == 0)
11088 found = true;
11089 XFREE(MTYPE_TMP,
11090 communities[i]);
11091 }
11092 XFREE(MTYPE_TMP, communities);
11093 }
11094
11095 if (!found)
11096 continue;
11097 }
11098
11099 if (type == bgp_show_type_rpki) {
11100 if (dest_p->family == AF_INET
11101 || dest_p->family == AF_INET6)
11102 rpki_curr_state = hook_call(
11103 bgp_rpki_prefix_status,
11104 pi->peer, pi->attr, dest_p);
11105 if (rpki_target_state != RPKI_NOT_BEING_USED
11106 && rpki_curr_state != rpki_target_state)
11107 continue;
11108 }
11109
11110 if (type == bgp_show_type_flap_statistics
11111 || type == bgp_show_type_flap_neighbor
11112 || type == bgp_show_type_dampend_paths
11113 || type == bgp_show_type_damp_neighbor) {
11114 if (!(pi->extra && pi->extra->damp_info))
11115 continue;
11116 }
11117 if (type == bgp_show_type_regexp) {
11118 regex_t *regex = output_arg;
11119
11120 if (bgp_regexec(regex, pi->attr->aspath)
11121 == REG_NOMATCH)
11122 continue;
11123 }
11124 if (type == bgp_show_type_prefix_list) {
11125 struct prefix_list *plist = output_arg;
11126
11127 if (prefix_list_apply(plist, dest_p)
11128 != PREFIX_PERMIT)
11129 continue;
11130 }
11131 if (type == bgp_show_type_access_list) {
11132 struct access_list *alist = output_arg;
11133
11134 if (access_list_apply(alist, dest_p) !=
11135 FILTER_PERMIT)
11136 continue;
11137 }
11138 if (type == bgp_show_type_filter_list) {
11139 struct as_list *as_list = output_arg;
11140
11141 if (as_list_apply(as_list, pi->attr->aspath)
11142 != AS_FILTER_PERMIT)
11143 continue;
11144 }
11145 if (type == bgp_show_type_route_map) {
11146 struct route_map *rmap = output_arg;
11147 struct bgp_path_info path;
11148 struct attr dummy_attr;
11149 route_map_result_t ret;
11150
11151 dummy_attr = *pi->attr;
11152
11153 path.peer = pi->peer;
11154 path.attr = &dummy_attr;
11155
11156 ret = route_map_apply(rmap, dest_p, &path);
11157 bgp_attr_flush(&dummy_attr);
11158 if (ret == RMAP_DENYMATCH)
11159 continue;
11160 }
11161 if (type == bgp_show_type_neighbor
11162 || type == bgp_show_type_flap_neighbor
11163 || type == bgp_show_type_damp_neighbor) {
11164 union sockunion *su = output_arg;
11165
11166 if (pi->peer == NULL
11167 || pi->peer->su_remote == NULL
11168 || !sockunion_same(pi->peer->su_remote, su))
11169 continue;
11170 }
11171 if (type == bgp_show_type_cidr_only) {
11172 uint32_t destination;
11173
11174 destination = ntohl(dest_p->u.prefix4.s_addr);
11175 if (IN_CLASSC(destination)
11176 && dest_p->prefixlen == 24)
11177 continue;
11178 if (IN_CLASSB(destination)
11179 && dest_p->prefixlen == 16)
11180 continue;
11181 if (IN_CLASSA(destination)
11182 && dest_p->prefixlen == 8)
11183 continue;
11184 }
11185 if (type == bgp_show_type_prefix_longer) {
11186 p = output_arg;
11187 if (!prefix_match(p, dest_p))
11188 continue;
11189 }
11190 if (type == bgp_show_type_community_all) {
11191 if (!picomm)
11192 continue;
11193 }
11194 if (type == bgp_show_type_community) {
11195 struct community *com = output_arg;
11196
11197 if (!picomm || !community_match(picomm, com))
11198 continue;
11199 }
11200 if (type == bgp_show_type_community_exact) {
11201 struct community *com = output_arg;
11202
11203 if (!picomm || !community_cmp(picomm, com))
11204 continue;
11205 }
11206 if (type == bgp_show_type_community_list) {
11207 struct community_list *list = output_arg;
11208
11209 if (!community_list_match(picomm, list))
11210 continue;
11211 }
11212 if (type == bgp_show_type_community_list_exact) {
11213 struct community_list *list = output_arg;
11214
11215 if (!community_list_exact_match(picomm, list))
11216 continue;
11217 }
11218 if (type == bgp_show_type_lcommunity) {
11219 struct lcommunity *lcom = output_arg;
11220
11221 if (!bgp_attr_get_lcommunity(pi->attr) ||
11222 !lcommunity_match(
11223 bgp_attr_get_lcommunity(pi->attr),
11224 lcom))
11225 continue;
11226 }
11227
11228 if (type == bgp_show_type_lcommunity_exact) {
11229 struct lcommunity *lcom = output_arg;
11230
11231 if (!bgp_attr_get_lcommunity(pi->attr) ||
11232 !lcommunity_cmp(
11233 bgp_attr_get_lcommunity(pi->attr),
11234 lcom))
11235 continue;
11236 }
11237 if (type == bgp_show_type_lcommunity_list) {
11238 struct community_list *list = output_arg;
11239
11240 if (!lcommunity_list_match(
11241 bgp_attr_get_lcommunity(pi->attr),
11242 list))
11243 continue;
11244 }
11245 if (type
11246 == bgp_show_type_lcommunity_list_exact) {
11247 struct community_list *list = output_arg;
11248
11249 if (!lcommunity_list_exact_match(
11250 bgp_attr_get_lcommunity(pi->attr),
11251 list))
11252 continue;
11253 }
11254 if (type == bgp_show_type_lcommunity_all) {
11255 if (!bgp_attr_get_lcommunity(pi->attr))
11256 continue;
11257 }
11258 if (type == bgp_show_type_dampend_paths
11259 || type == bgp_show_type_damp_neighbor) {
11260 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11261 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11262 continue;
11263 }
11264
11265 if (!use_json && header) {
11266 vty_out(vty,
11267 "BGP table version is %" PRIu64
11268 ", local router ID is %pI4, vrf id ",
11269 table->version, &bgp->router_id);
11270 if (bgp->vrf_id == VRF_UNKNOWN)
11271 vty_out(vty, "%s", VRFID_NONE_STR);
11272 else
11273 vty_out(vty, "%u", bgp->vrf_id);
11274 vty_out(vty, "\n");
11275 vty_out(vty, "Default local pref %u, ",
11276 bgp->default_local_pref);
11277 vty_out(vty, "local AS %u\n", bgp->as);
11278 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11279 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11280 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11281 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11282 if (type == bgp_show_type_dampend_paths
11283 || type == bgp_show_type_damp_neighbor)
11284 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11285 else if (type == bgp_show_type_flap_statistics
11286 || type == bgp_show_type_flap_neighbor)
11287 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11288 else
11289 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11290 : BGP_SHOW_HEADER));
11291 header = false;
11292
11293 } else if (json_detail && json_paths != NULL) {
11294 const struct prefix_rd *prd;
11295 json_object *jtemp;
11296
11297 /* Use common detail header, for most types;
11298 * need a json 'object'.
11299 */
11300
11301 jtemp = json_object_new_object();
11302 prd = bgp_rd_from_dest(dest, safi);
11303
11304 route_vty_out_detail_header(
11305 vty, bgp, dest, prd, table->afi,
11306 safi, jtemp);
11307
11308 json_object_array_add(json_paths, jtemp);
11309
11310 json_detail = false;
11311 }
11312
11313 if (rd != NULL && !display && !output_count) {
11314 if (!use_json)
11315 vty_out(vty,
11316 "Route Distinguisher: %s\n",
11317 rd);
11318 }
11319 if (type == bgp_show_type_dampend_paths
11320 || type == bgp_show_type_damp_neighbor)
11321 damp_route_vty_out(vty, dest_p, pi, display,
11322 AFI_IP, safi, use_json,
11323 json_paths);
11324 else if (type == bgp_show_type_flap_statistics
11325 || type == bgp_show_type_flap_neighbor)
11326 flap_route_vty_out(vty, dest_p, pi, display,
11327 AFI_IP, safi, use_json,
11328 json_paths);
11329 else {
11330 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11331 route_vty_out_detail(
11332 vty, bgp, dest, pi,
11333 family2afi(dest_p->family),
11334 safi, RPKI_NOT_BEING_USED,
11335 json_paths);
11336 else
11337 route_vty_out(vty, dest_p, pi, display,
11338 safi, json_paths, wide);
11339 }
11340 display++;
11341 }
11342
11343 if (display) {
11344 output_count++;
11345 if (!use_json)
11346 continue;
11347
11348 /* encode prefix */
11349 if (dest_p->family == AF_FLOWSPEC) {
11350 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11351
11352
11353 bgp_fs_nlri_get_string(
11354 (unsigned char *)
11355 dest_p->u.prefix_flowspec.ptr,
11356 dest_p->u.prefix_flowspec.prefixlen,
11357 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11358 family2afi(dest_p->u
11359 .prefix_flowspec.family));
11360 if (first)
11361 vty_out(vty, "\"%s/%d\": ", retstr,
11362 dest_p->u.prefix_flowspec
11363 .prefixlen);
11364 else
11365 vty_out(vty, ",\"%s/%d\": ", retstr,
11366 dest_p->u.prefix_flowspec
11367 .prefixlen);
11368 } else {
11369 if (first)
11370 vty_out(vty, "\"%pFX\": ", dest_p);
11371 else
11372 vty_out(vty, ",\"%pFX\": ", dest_p);
11373 }
11374 vty_json(vty, json_paths);
11375 json_paths = NULL;
11376 first = 0;
11377 } else
11378 json_object_free(json_paths);
11379 }
11380
11381 if (output_cum) {
11382 output_count += *output_cum;
11383 *output_cum = output_count;
11384 }
11385 if (total_cum) {
11386 total_count += *total_cum;
11387 *total_cum = total_count;
11388 }
11389 if (use_json) {
11390 if (rd) {
11391 vty_out(vty, " }%s ", (is_last ? "" : ","));
11392 }
11393 if (is_last) {
11394 unsigned long i;
11395 for (i = 0; i < *json_header_depth; ++i)
11396 vty_out(vty, " } ");
11397 if (!all)
11398 vty_out(vty, "\n");
11399 }
11400 } else {
11401 if (is_last) {
11402 /* No route is displayed */
11403 if (output_count == 0) {
11404 if (type == bgp_show_type_normal)
11405 vty_out(vty,
11406 "No BGP prefixes displayed, %ld exist\n",
11407 total_count);
11408 } else
11409 vty_out(vty,
11410 "\nDisplayed %ld routes and %ld total paths\n",
11411 output_count, total_count);
11412 }
11413 }
11414
11415 return CMD_SUCCESS;
11416}
11417
11418int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11419 struct bgp_table *table, struct prefix_rd *prd_match,
11420 enum bgp_show_type type, void *output_arg, bool use_json)
11421{
11422 struct bgp_dest *dest, *next;
11423 unsigned long output_cum = 0;
11424 unsigned long total_cum = 0;
11425 unsigned long json_header_depth = 0;
11426 struct bgp_table *itable;
11427 bool show_msg;
11428 uint16_t show_flags = 0;
11429
11430 show_msg = (!use_json && type == bgp_show_type_normal);
11431
11432 if (use_json)
11433 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11434
11435 for (dest = bgp_table_top(table); dest; dest = next) {
11436 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11437
11438 next = bgp_route_next(dest);
11439 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11440 continue;
11441
11442 itable = bgp_dest_get_bgp_table_info(dest);
11443 if (itable != NULL) {
11444 struct prefix_rd prd;
11445 char rd[RD_ADDRSTRLEN];
11446
11447 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11448 prefix_rd2str(&prd, rd, sizeof(rd));
11449 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11450 rd, next == NULL, &output_cum,
11451 &total_cum, &json_header_depth,
11452 show_flags, RPKI_NOT_BEING_USED);
11453 if (next == NULL)
11454 show_msg = false;
11455 }
11456 }
11457 if (show_msg) {
11458 if (output_cum == 0)
11459 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11460 total_cum);
11461 else
11462 vty_out(vty,
11463 "\nDisplayed %ld routes and %ld total paths\n",
11464 output_cum, total_cum);
11465 }
11466 return CMD_SUCCESS;
11467}
11468
11469static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11470 enum bgp_show_type type, void *output_arg,
11471 uint16_t show_flags, enum rpki_states rpki_target_state)
11472{
11473 struct bgp_table *table;
11474 unsigned long json_header_depth = 0;
11475 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11476
11477 if (bgp == NULL) {
11478 bgp = bgp_get_default();
11479 }
11480
11481 if (bgp == NULL) {
11482 if (!use_json)
11483 vty_out(vty, "No BGP process is configured\n");
11484 else
11485 vty_out(vty, "{}\n");
11486 return CMD_WARNING;
11487 }
11488
11489 /* Labeled-unicast routes live in the unicast table. */
11490 if (safi == SAFI_LABELED_UNICAST)
11491 safi = SAFI_UNICAST;
11492
11493 table = bgp->rib[afi][safi];
11494 /* use MPLS and ENCAP specific shows until they are merged */
11495 if (safi == SAFI_MPLS_VPN) {
11496 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11497 output_arg, use_json);
11498 }
11499
11500 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11501 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11502 output_arg, use_json,
11503 1, NULL, NULL);
11504 }
11505
11506 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11507 NULL, NULL, &json_header_depth, show_flags,
11508 rpki_target_state);
11509}
11510
11511static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11512 safi_t safi, uint16_t show_flags)
11513{
11514 struct listnode *node, *nnode;
11515 struct bgp *bgp;
11516 int is_first = 1;
11517 bool route_output = false;
11518 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11519
11520 if (use_json)
11521 vty_out(vty, "{\n");
11522
11523 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11524 route_output = true;
11525 if (use_json) {
11526 if (!is_first)
11527 vty_out(vty, ",\n");
11528 else
11529 is_first = 0;
11530
11531 vty_out(vty, "\"%s\":",
11532 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11533 ? VRF_DEFAULT_NAME
11534 : bgp->name);
11535 } else {
11536 vty_out(vty, "\nInstance %s:\n",
11537 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11538 ? VRF_DEFAULT_NAME
11539 : bgp->name);
11540 }
11541 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11542 show_flags, RPKI_NOT_BEING_USED);
11543 }
11544
11545 if (use_json)
11546 vty_out(vty, "}\n");
11547 else if (!route_output)
11548 vty_out(vty, "%% BGP instance not found\n");
11549}
11550
11551/* Header of detailed BGP route information */
11552void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11553 struct bgp_dest *dest,
11554 const struct prefix_rd *prd,
11555 afi_t afi, safi_t safi, json_object *json)
11556{
11557 struct bgp_path_info *pi;
11558 const struct prefix *p;
11559 struct peer *peer;
11560 struct listnode *node, *nnode;
11561 char buf1[RD_ADDRSTRLEN];
11562 int count = 0;
11563 int best = 0;
11564 int suppress = 0;
11565 int accept_own = 0;
11566 int route_filter_translated_v4 = 0;
11567 int route_filter_v4 = 0;
11568 int route_filter_translated_v6 = 0;
11569 int route_filter_v6 = 0;
11570 int llgr_stale = 0;
11571 int no_llgr = 0;
11572 int accept_own_nexthop = 0;
11573 int blackhole = 0;
11574 int no_export = 0;
11575 int no_advertise = 0;
11576 int local_as = 0;
11577 int no_peer = 0;
11578 int first = 1;
11579 int has_valid_label = 0;
11580 mpls_label_t label = 0;
11581 json_object *json_adv_to = NULL;
11582 uint32_t ttl = 0;
11583 uint32_t bos = 0;
11584 uint32_t exp = 0;
11585
11586 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11587
11588 p = bgp_dest_get_prefix(dest);
11589 has_valid_label = bgp_is_valid_label(&label);
11590
11591 if (safi == SAFI_EVPN) {
11592 if (!json) {
11593 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11594 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11595 : "",
11596 prd ? ":" : "", (struct prefix_evpn *)p);
11597 } else {
11598 json_object_string_add(json, "rd",
11599 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11600 "");
11601 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11602 }
11603 } else {
11604 if (!json) {
11605 vty_out(vty,
11606 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11607 "\n",
11608 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11609 ? prefix_rd2str(prd, buf1,
11610 sizeof(buf1))
11611 : ""),
11612 safi == SAFI_MPLS_VPN ? ":" : "", p,
11613 dest->version);
11614
11615 } else {
11616 json_object_string_addf(json, "prefix", "%pFX", p);
11617 json_object_int_add(json, "version", dest->version);
11618
11619 }
11620 }
11621
11622 if (has_valid_label) {
11623 if (json)
11624 json_object_int_add(json, "localLabel", label);
11625 else
11626 vty_out(vty, "Local label: %d\n", label);
11627 }
11628
11629 if (!json)
11630 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11631 vty_out(vty, "not allocated\n");
11632
11633 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11634 struct community *picomm = NULL;
11635
11636 picomm = bgp_attr_get_community(pi->attr);
11637
11638 count++;
11639 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11640 best = count;
11641 if (bgp_path_suppressed(pi))
11642 suppress = 1;
11643
11644 if (!picomm)
11645 continue;
11646
11647 no_advertise += community_include(
11648 picomm, COMMUNITY_NO_ADVERTISE);
11649 no_export +=
11650 community_include(picomm, COMMUNITY_NO_EXPORT);
11651 local_as +=
11652 community_include(picomm, COMMUNITY_LOCAL_AS);
11653 accept_own +=
11654 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11655 route_filter_translated_v4 += community_include(
11656 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11657 route_filter_translated_v6 += community_include(
11658 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11659 route_filter_v4 += community_include(
11660 picomm, COMMUNITY_ROUTE_FILTER_v4);
11661 route_filter_v6 += community_include(
11662 picomm, COMMUNITY_ROUTE_FILTER_v6);
11663 llgr_stale +=
11664 community_include(picomm, COMMUNITY_LLGR_STALE);
11665 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11666 accept_own_nexthop += community_include(
11667 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11668 blackhole +=
11669 community_include(picomm, COMMUNITY_BLACKHOLE);
11670 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11671 }
11672 }
11673
11674 if (!json) {
11675 vty_out(vty, "Paths: (%d available", count);
11676 if (best) {
11677 vty_out(vty, ", best #%d", best);
11678 if (safi == SAFI_UNICAST) {
11679 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11680 vty_out(vty, ", table %s",
11681 VRF_DEFAULT_NAME);
11682 else
11683 vty_out(vty, ", vrf %s",
11684 bgp->name);
11685 }
11686 } else
11687 vty_out(vty, ", no best path");
11688
11689 if (accept_own)
11690 vty_out(vty,
11691 ", accept own local route exported and imported in different VRF");
11692 else if (route_filter_translated_v4)
11693 vty_out(vty,
11694 ", mark translated RTs for VPNv4 route filtering");
11695 else if (route_filter_v4)
11696 vty_out(vty,
11697 ", attach RT as-is for VPNv4 route filtering");
11698 else if (route_filter_translated_v6)
11699 vty_out(vty,
11700 ", mark translated RTs for VPNv6 route filtering");
11701 else if (route_filter_v6)
11702 vty_out(vty,
11703 ", attach RT as-is for VPNv6 route filtering");
11704 else if (llgr_stale)
11705 vty_out(vty,
11706 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11707 else if (no_llgr)
11708 vty_out(vty,
11709 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11710 else if (accept_own_nexthop)
11711 vty_out(vty,
11712 ", accept local nexthop");
11713 else if (blackhole)
11714 vty_out(vty, ", inform peer to blackhole prefix");
11715 else if (no_export)
11716 vty_out(vty, ", not advertised to EBGP peer");
11717 else if (no_advertise)
11718 vty_out(vty, ", not advertised to any peer");
11719 else if (local_as)
11720 vty_out(vty, ", not advertised outside local AS");
11721 else if (no_peer)
11722 vty_out(vty,
11723 ", inform EBGP peer not to advertise to their EBGP peers");
11724
11725 if (suppress)
11726 vty_out(vty,
11727 ", Advertisements suppressed by an aggregate.");
11728 vty_out(vty, ")\n");
11729 }
11730
11731 /* If we are not using addpath then we can display Advertised to and
11732 * that will
11733 * show what peers we advertised the bestpath to. If we are using
11734 * addpath
11735 * though then we must display Advertised to on a path-by-path basis. */
11736 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11737 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11738 if (bgp_adj_out_lookup(peer, dest, 0)) {
11739 if (json && !json_adv_to)
11740 json_adv_to = json_object_new_object();
11741
11742 route_vty_out_advertised_to(
11743 vty, peer, &first,
11744 " Advertised to non peer-group peers:\n ",
11745 json_adv_to);
11746 }
11747 }
11748
11749 if (json) {
11750 if (json_adv_to) {
11751 json_object_object_add(json, "advertisedTo",
11752 json_adv_to);
11753 }
11754 } else {
11755 if (first)
11756 vty_out(vty, " Not advertised to any peer");
11757 vty_out(vty, "\n");
11758 }
11759 }
11760}
11761
11762static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11763 struct bgp_dest *bgp_node, struct vty *vty,
11764 struct bgp *bgp, afi_t afi, safi_t safi,
11765 json_object *json, enum bgp_path_type pathtype,
11766 int *display, enum rpki_states rpki_target_state)
11767{
11768 struct bgp_path_info *pi;
11769 int header = 1;
11770 char rdbuf[RD_ADDRSTRLEN];
11771 json_object *json_header = NULL;
11772 json_object *json_paths = NULL;
11773 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11774
11775 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11776 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11777
11778 if (p->family == AF_INET || p->family == AF_INET6)
11779 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11780 pi->peer, pi->attr, p);
11781
11782 if (rpki_target_state != RPKI_NOT_BEING_USED
11783 && rpki_curr_state != rpki_target_state)
11784 continue;
11785
11786 if (json && !json_paths) {
11787 /* Instantiate json_paths only if path is valid */
11788 json_paths = json_object_new_array();
11789 if (pfx_rd) {
11790 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11791 json_header = json_object_new_object();
11792 } else
11793 json_header = json;
11794 }
11795
11796 if (header) {
11797 route_vty_out_detail_header(
11798 vty, bgp, bgp_node, pfx_rd,
11799 AFI_IP, safi, json_header);
11800 header = 0;
11801 }
11802 (*display)++;
11803
11804 if (pathtype == BGP_PATH_SHOW_ALL
11805 || (pathtype == BGP_PATH_SHOW_BESTPATH
11806 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11807 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11808 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11809 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11810 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
11811 safi, rpki_curr_state, json_paths);
11812 }
11813
11814 if (json && json_paths) {
11815 json_object_object_add(json_header, "paths", json_paths);
11816
11817 if (pfx_rd)
11818 json_object_object_add(json, rdbuf, json_header);
11819 }
11820}
11821
11822/*
11823 * Return rd based on safi
11824 */
11825static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
11826 safi_t safi)
11827{
11828 switch (safi) {
11829 case SAFI_MPLS_VPN:
11830 case SAFI_ENCAP:
11831 case SAFI_EVPN:
11832 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
11833 default:
11834 return NULL;
11835
11836 }
11837}
11838
11839/* Display specified route of BGP table. */
11840static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11841 struct bgp_table *rib, const char *ip_str,
11842 afi_t afi, safi_t safi,
11843 enum rpki_states rpki_target_state,
11844 struct prefix_rd *prd, int prefix_check,
11845 enum bgp_path_type pathtype, bool use_json)
11846{
11847 int ret;
11848 int display = 0;
11849 struct prefix match;
11850 struct bgp_dest *dest;
11851 struct bgp_dest *rm;
11852 struct bgp_table *table;
11853 json_object *json = NULL;
11854 json_object *json_paths = NULL;
11855
11856 /* Check IP address argument. */
11857 ret = str2prefix(ip_str, &match);
11858 if (!ret) {
11859 vty_out(vty, "address is malformed\n");
11860 return CMD_WARNING;
11861 }
11862
11863 match.family = afi2family(afi);
11864
11865 if (use_json)
11866 json = json_object_new_object();
11867
11868 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11869 for (dest = bgp_table_top(rib); dest;
11870 dest = bgp_route_next(dest)) {
11871 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11872
11873 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11874 continue;
11875 table = bgp_dest_get_bgp_table_info(dest);
11876 if (!table)
11877 continue;
11878
11879 rm = bgp_node_match(table, &match);
11880 if (rm == NULL)
11881 continue;
11882
11883 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11884 if (prefix_check
11885 && rm_p->prefixlen != match.prefixlen) {
11886 bgp_dest_unlock_node(rm);
11887 continue;
11888 }
11889
11890 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11891 bgp, afi, safi, json, pathtype,
11892 &display, rpki_target_state);
11893
11894 bgp_dest_unlock_node(rm);
11895 }
11896 } else if (safi == SAFI_EVPN) {
11897 struct bgp_dest *longest_pfx;
11898 bool is_exact_pfxlen_match = false;
11899
11900 for (dest = bgp_table_top(rib); dest;
11901 dest = bgp_route_next(dest)) {
11902 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11903
11904 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11905 continue;
11906 table = bgp_dest_get_bgp_table_info(dest);
11907 if (!table)
11908 continue;
11909
11910 longest_pfx = NULL;
11911 is_exact_pfxlen_match = false;
11912 /*
11913 * Search through all the prefixes for a match. The
11914 * pfx's are enumerated in ascending order of pfxlens.
11915 * So, the last pfx match is the longest match. Set
11916 * is_exact_pfxlen_match when we get exact pfxlen match
11917 */
11918 for (rm = bgp_table_top(table); rm;
11919 rm = bgp_route_next(rm)) {
11920 const struct prefix *rm_p =
11921 bgp_dest_get_prefix(rm);
11922 /*
11923 * Get prefixlen of the ip-prefix within type5
11924 * evpn route
11925 */
11926 if (evpn_type5_prefix_match(rm_p, &match)
11927 && rm->info) {
11928 longest_pfx = rm;
11929 int type5_pfxlen =
11930 bgp_evpn_get_type5_prefixlen(
11931 rm_p);
11932 if (type5_pfxlen == match.prefixlen) {
11933 is_exact_pfxlen_match = true;
11934 bgp_dest_unlock_node(rm);
11935 break;
11936 }
11937 }
11938 }
11939
11940 if (!longest_pfx)
11941 continue;
11942
11943 if (prefix_check && !is_exact_pfxlen_match)
11944 continue;
11945
11946 rm = longest_pfx;
11947 bgp_dest_lock_node(rm);
11948
11949 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11950 bgp, afi, safi, json, pathtype,
11951 &display, rpki_target_state);
11952
11953 bgp_dest_unlock_node(rm);
11954 }
11955 } else if (safi == SAFI_FLOWSPEC) {
11956 if (use_json)
11957 json_paths = json_object_new_array();
11958
11959 display = bgp_flowspec_display_match_per_ip(afi, rib,
11960 &match, prefix_check,
11961 vty,
11962 use_json,
11963 json_paths);
11964 if (use_json) {
11965 if (display)
11966 json_object_object_add(json, "paths",
11967 json_paths);
11968 else
11969 json_object_free(json_paths);
11970 }
11971 } else {
11972 dest = bgp_node_match(rib, &match);
11973 if (dest != NULL) {
11974 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11975 if (!prefix_check
11976 || dest_p->prefixlen == match.prefixlen) {
11977 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11978 safi, json, pathtype,
11979 &display, rpki_target_state);
11980 }
11981
11982 bgp_dest_unlock_node(dest);
11983 }
11984 }
11985
11986 if (use_json) {
11987 vty_json(vty, json);
11988 } else {
11989 if (!display) {
11990 vty_out(vty, "%% Network not in table\n");
11991 return CMD_WARNING;
11992 }
11993 }
11994
11995 return CMD_SUCCESS;
11996}
11997
11998/* Display specified route of Main RIB */
11999static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12000 afi_t afi, safi_t safi, struct prefix_rd *prd,
12001 int prefix_check, enum bgp_path_type pathtype,
12002 enum rpki_states rpki_target_state, bool use_json)
12003{
12004 if (!bgp) {
12005 bgp = bgp_get_default();
12006 if (!bgp) {
12007 if (!use_json)
12008 vty_out(vty, "No BGP process is configured\n");
12009 else
12010 vty_out(vty, "{}\n");
12011 return CMD_WARNING;
12012 }
12013 }
12014
12015 /* labeled-unicast routes live in the unicast table */
12016 if (safi == SAFI_LABELED_UNICAST)
12017 safi = SAFI_UNICAST;
12018
12019 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12020 afi, safi, rpki_target_state, prd,
12021 prefix_check, pathtype, use_json);
12022}
12023
12024static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12025 struct cmd_token **argv, bool exact, afi_t afi,
12026 safi_t safi, bool uj)
12027{
12028 struct lcommunity *lcom;
12029 struct buffer *b;
12030 int i;
12031 char *str;
12032 int first = 0;
12033 uint16_t show_flags = 0;
12034 int ret;
12035
12036 if (uj)
12037 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12038
12039 b = buffer_new(1024);
12040 for (i = 0; i < argc; i++) {
12041 if (first)
12042 buffer_putc(b, ' ');
12043 else {
12044 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12045 first = 1;
12046 buffer_putstr(b, argv[i]->arg);
12047 }
12048 }
12049 }
12050 buffer_putc(b, '\0');
12051
12052 str = buffer_getstr(b);
12053 buffer_free(b);
12054
12055 lcom = lcommunity_str2com(str);
12056 XFREE(MTYPE_TMP, str);
12057 if (!lcom) {
12058 vty_out(vty, "%% Large-community malformed\n");
12059 return CMD_WARNING;
12060 }
12061
12062 ret = bgp_show(vty, bgp, afi, safi,
12063 (exact ? bgp_show_type_lcommunity_exact
12064 : bgp_show_type_lcommunity),
12065 lcom, show_flags, RPKI_NOT_BEING_USED);
12066
12067 lcommunity_free(&lcom);
12068 return ret;
12069}
12070
12071static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12072 const char *lcom, bool exact, afi_t afi,
12073 safi_t safi, bool uj)
12074{
12075 struct community_list *list;
12076 uint16_t show_flags = 0;
12077
12078 if (uj)
12079 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12080
12081
12082 list = community_list_lookup(bgp_clist, lcom, 0,
12083 LARGE_COMMUNITY_LIST_MASTER);
12084 if (list == NULL) {
12085 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12086 lcom);
12087 return CMD_WARNING;
12088 }
12089
12090 return bgp_show(vty, bgp, afi, safi,
12091 (exact ? bgp_show_type_lcommunity_list_exact
12092 : bgp_show_type_lcommunity_list),
12093 list, show_flags, RPKI_NOT_BEING_USED);
12094}
12095
12096DEFUN (show_ip_bgp_large_community_list,
12097 show_ip_bgp_large_community_list_cmd,
12098 "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]",
12099 SHOW_STR
12100 IP_STR
12101 BGP_STR
12102 BGP_INSTANCE_HELP_STR
12103 BGP_AFI_HELP_STR
12104 BGP_SAFI_WITH_LABEL_HELP_STR
12105 "Display routes matching the large-community-list\n"
12106 "large-community-list number\n"
12107 "large-community-list name\n"
12108 "Exact match of the large-communities\n"
12109 JSON_STR)
12110{
12111 afi_t afi = AFI_IP6;
12112 safi_t safi = SAFI_UNICAST;
12113 int idx = 0;
12114 bool exact_match = 0;
12115 struct bgp *bgp = NULL;
12116 bool uj = use_json(argc, argv);
12117
12118 if (uj)
12119 argc--;
12120
12121 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12122 &bgp, uj);
12123 if (!idx)
12124 return CMD_WARNING;
12125
12126 argv_find(argv, argc, "large-community-list", &idx);
12127
12128 const char *clist_number_or_name = argv[++idx]->arg;
12129
12130 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12131 exact_match = 1;
12132
12133 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12134 exact_match, afi, safi, uj);
12135}
12136DEFUN (show_ip_bgp_large_community,
12137 show_ip_bgp_large_community_cmd,
12138 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12139 SHOW_STR
12140 IP_STR
12141 BGP_STR
12142 BGP_INSTANCE_HELP_STR
12143 BGP_AFI_HELP_STR
12144 BGP_SAFI_WITH_LABEL_HELP_STR
12145 "Display routes matching the large-communities\n"
12146 "List of large-community numbers\n"
12147 "Exact match of the large-communities\n"
12148 JSON_STR)
12149{
12150 afi_t afi = AFI_IP6;
12151 safi_t safi = SAFI_UNICAST;
12152 int idx = 0;
12153 bool exact_match = 0;
12154 struct bgp *bgp = NULL;
12155 bool uj = use_json(argc, argv);
12156 uint16_t show_flags = 0;
12157
12158 if (uj) {
12159 argc--;
12160 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12161 }
12162
12163 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12164 &bgp, uj);
12165 if (!idx)
12166 return CMD_WARNING;
12167
12168 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12169 if (argv_find(argv, argc, "exact-match", &idx))
12170 exact_match = 1;
12171 return bgp_show_lcommunity(vty, bgp, argc, argv,
12172 exact_match, afi, safi, uj);
12173 } else
12174 return bgp_show(vty, bgp, afi, safi,
12175 bgp_show_type_lcommunity_all, NULL, show_flags,
12176 RPKI_NOT_BEING_USED);
12177}
12178
12179static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12180 safi_t safi, struct json_object *json_array);
12181static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12182 safi_t safi, struct json_object *json);
12183
12184
12185DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12186 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12187 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12188 "Display number of prefixes for all afi/safi\n" JSON_STR)
12189{
12190 bool uj = use_json(argc, argv);
12191 struct bgp *bgp = NULL;
12192 safi_t safi = SAFI_UNICAST;
12193 afi_t afi = AFI_IP6;
12194 int idx = 0;
12195 struct json_object *json_all = NULL;
12196 struct json_object *json_afi_safi = NULL;
12197
12198 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12199 &bgp, false);
12200 if (!idx)
12201 return CMD_WARNING;
12202
12203 if (uj)
12204 json_all = json_object_new_object();
12205
12206 FOREACH_AFI_SAFI (afi, safi) {
12207 /*
12208 * So limit output to those afi/safi pairs that
12209 * actually have something interesting in them
12210 */
12211 if (strmatch(get_afi_safi_str(afi, safi, true),
12212 "Unknown")) {
12213 continue;
12214 }
12215 if (uj) {
12216 json_afi_safi = json_object_new_array();
12217 json_object_object_add(
12218 json_all,
12219 get_afi_safi_str(afi, safi, true),
12220 json_afi_safi);
12221 } else {
12222 json_afi_safi = NULL;
12223 }
12224
12225 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12226 }
12227
12228 if (uj)
12229 vty_json(vty, json_all);
12230
12231 return CMD_SUCCESS;
12232}
12233
12234/* BGP route print out function without JSON */
12235DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12236 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12237 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12238 SHOW_STR
12239 IP_STR
12240 BGP_STR
12241 BGP_INSTANCE_HELP_STR
12242 L2VPN_HELP_STR
12243 EVPN_HELP_STR
12244 "BGP RIB advertisement statistics\n"
12245 JSON_STR)
12246{
12247 afi_t afi = AFI_IP6;
12248 safi_t safi = SAFI_UNICAST;
12249 struct bgp *bgp = NULL;
12250 int idx = 0, ret;
12251 bool uj = use_json(argc, argv);
12252 struct json_object *json_afi_safi = NULL, *json = NULL;
12253
12254 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12255 &bgp, false);
12256 if (!idx)
12257 return CMD_WARNING;
12258
12259 if (uj)
12260 json_afi_safi = json_object_new_array();
12261 else
12262 json_afi_safi = NULL;
12263
12264 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12265
12266 if (uj) {
12267 json = json_object_new_object();
12268 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12269 json_afi_safi);
12270 vty_json(vty, json);
12271 }
12272 return ret;
12273}
12274
12275/* BGP route print out function without JSON */
12276DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12277 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12278 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12279 "]]\
12280 statistics [json]",
12281 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12282 BGP_SAFI_WITH_LABEL_HELP_STR
12283 "BGP RIB advertisement statistics\n" JSON_STR)
12284{
12285 afi_t afi = AFI_IP6;
12286 safi_t safi = SAFI_UNICAST;
12287 struct bgp *bgp = NULL;
12288 int idx = 0, ret;
12289 bool uj = use_json(argc, argv);
12290 struct json_object *json_afi_safi = NULL, *json = NULL;
12291
12292 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12293 &bgp, false);
12294 if (!idx)
12295 return CMD_WARNING;
12296
12297 if (uj)
12298 json_afi_safi = json_object_new_array();
12299 else
12300 json_afi_safi = NULL;
12301
12302 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12303
12304 if (uj) {
12305 json = json_object_new_object();
12306 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12307 json_afi_safi);
12308 vty_json(vty, json);
12309 }
12310 return ret;
12311}
12312
12313DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12314 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12315 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12316 "]] [all$all] dampening parameters [json]",
12317 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12318 BGP_SAFI_WITH_LABEL_HELP_STR
12319 "Display the entries for all address families\n"
12320 "Display detailed information about dampening\n"
12321 "Display detail of configured dampening parameters\n"
12322 JSON_STR)
12323{
12324 afi_t afi = AFI_IP6;
12325 safi_t safi = SAFI_UNICAST;
12326 struct bgp *bgp = NULL;
12327 int idx = 0;
12328 uint16_t show_flags = 0;
12329 bool uj = use_json(argc, argv);
12330
12331 if (uj) {
12332 argc--;
12333 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12334 }
12335
12336 /* [<ipv4|ipv6> [all]] */
12337 if (all) {
12338 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12339 if (argv_find(argv, argc, "ipv4", &idx))
12340 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12341
12342 if (argv_find(argv, argc, "ipv6", &idx))
12343 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12344 }
12345
12346 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12347 &bgp, false);
12348 if (!idx)
12349 return CMD_WARNING;
12350
12351 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12352}
12353
12354/* BGP route print out function */
12355DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12356 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12357 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12358 "]]\
12359 [all$all]\
12360 [cidr-only\
12361 |dampening <flap-statistics|dampened-paths>\
12362 |community [AA:NN|local-AS|no-advertise|no-export\
12363 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12364 |accept-own|accept-own-nexthop|route-filter-v6\
12365 |route-filter-v4|route-filter-translated-v6\
12366 |route-filter-translated-v4] [exact-match]\
12367 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12368 |filter-list AS_PATH_FILTER_NAME\
12369 |prefix-list WORD\
12370 |access-list ACCESSLIST_NAME\
12371 |route-map RMAP_NAME\
12372 |rpki <invalid|valid|notfound>\
12373 |version (1-4294967295)\
12374 |alias ALIAS_NAME\
12375 |A.B.C.D/M longer-prefixes\
12376 |X:X::X:X/M longer-prefixes\
12377 ] [json$uj [detail$detail] | wide$wide]",
12378 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12379 BGP_SAFI_WITH_LABEL_HELP_STR
12380 "Display the entries for all address families\n"
12381 "Display only routes with non-natural netmasks\n"
12382 "Display detailed information about dampening\n"
12383 "Display flap statistics of routes\n"
12384 "Display paths suppressed due to dampening\n"
12385 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12386 "Do not send outside local AS (well-known community)\n"
12387 "Do not advertise to any peer (well-known community)\n"
12388 "Do not export to next AS (well-known community)\n"
12389 "Graceful shutdown (well-known community)\n"
12390 "Do not export to any peer (well-known community)\n"
12391 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12392 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12393 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12394 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12395 "Should accept VPN route with local nexthop (well-known community)\n"
12396 "RT VPNv6 route filtering (well-known community)\n"
12397 "RT VPNv4 route filtering (well-known community)\n"
12398 "RT translated VPNv6 route filtering (well-known community)\n"
12399 "RT translated VPNv4 route filtering (well-known community)\n"
12400 "Exact match of the communities\n"
12401 "Community-list number\n"
12402 "Community-list name\n"
12403 "Display routes matching the community-list\n"
12404 "Exact match of the communities\n"
12405 "Display routes conforming to the filter-list\n"
12406 "Regular expression access list name\n"
12407 "Display routes conforming to the prefix-list\n"
12408 "Prefix-list name\n"
12409 "Display routes conforming to the access-list\n"
12410 "Access-list name\n"
12411 "Display routes matching the route-map\n"
12412 "A route-map to match on\n"
12413 "RPKI route types\n"
12414 "A valid path as determined by rpki\n"
12415 "A invalid path as determined by rpki\n"
12416 "A path that has no rpki data\n"
12417 "Display prefixes with matching version numbers\n"
12418 "Version number and above\n"
12419 "Display prefixes with matching BGP community alias\n"
12420 "BGP community alias\n"
12421 "IPv4 prefix\n"
12422 "Display route and more specific routes\n"
12423 "IPv6 prefix\n"
12424 "Display route and more specific routes\n"
12425 JSON_STR
12426 "Display detailed version of JSON output\n"
12427 "Increase table width for longer prefixes\n")
12428{
12429 afi_t afi = AFI_IP6;
12430 safi_t safi = SAFI_UNICAST;
12431 enum bgp_show_type sh_type = bgp_show_type_normal;
12432 void *output_arg = NULL;
12433 struct bgp *bgp = NULL;
12434 int idx = 0;
12435 int exact_match = 0;
12436 char *community = NULL;
12437 bool first = true;
12438 uint16_t show_flags = 0;
12439 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12440 struct prefix p;
12441
12442 if (uj) {
12443 argc--;
12444 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12445 }
12446
12447 if (detail)
12448 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12449
12450 /* [<ipv4|ipv6> [all]] */
12451 if (all) {
12452 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12453
12454 if (argv_find(argv, argc, "ipv4", &idx))
12455 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12456
12457 if (argv_find(argv, argc, "ipv6", &idx))
12458 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12459 }
12460
12461 if (wide)
12462 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12463
12464 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12465 &bgp, uj);
12466 if (!idx)
12467 return CMD_WARNING;
12468
12469 if (argv_find(argv, argc, "cidr-only", &idx))
12470 sh_type = bgp_show_type_cidr_only;
12471
12472 if (argv_find(argv, argc, "dampening", &idx)) {
12473 if (argv_find(argv, argc, "dampened-paths", &idx))
12474 sh_type = bgp_show_type_dampend_paths;
12475 else if (argv_find(argv, argc, "flap-statistics", &idx))
12476 sh_type = bgp_show_type_flap_statistics;
12477 }
12478
12479 if (argv_find(argv, argc, "community", &idx)) {
12480 char *maybecomm = NULL;
12481
12482 if (idx + 1 < argc) {
12483 if (argv[idx + 1]->type == VARIABLE_TKN)
12484 maybecomm = argv[idx + 1]->arg;
12485 else
12486 maybecomm = argv[idx + 1]->text;
12487 }
12488
12489 if (maybecomm && !strmatch(maybecomm, "json")
12490 && !strmatch(maybecomm, "exact-match"))
12491 community = maybecomm;
12492
12493 if (argv_find(argv, argc, "exact-match", &idx))
12494 exact_match = 1;
12495
12496 if (!community)
12497 sh_type = bgp_show_type_community_all;
12498 }
12499
12500 if (argv_find(argv, argc, "community-list", &idx)) {
12501 const char *clist_number_or_name = argv[++idx]->arg;
12502 struct community_list *list;
12503
12504 if (argv_find(argv, argc, "exact-match", &idx))
12505 exact_match = 1;
12506
12507 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12508 COMMUNITY_LIST_MASTER);
12509 if (list == NULL) {
12510 vty_out(vty, "%% %s community-list not found\n",
12511 clist_number_or_name);
12512 return CMD_WARNING;
12513 }
12514
12515 if (exact_match)
12516 sh_type = bgp_show_type_community_list_exact;
12517 else
12518 sh_type = bgp_show_type_community_list;
12519 output_arg = list;
12520 }
12521
12522 if (argv_find(argv, argc, "filter-list", &idx)) {
12523 const char *filter = argv[++idx]->arg;
12524 struct as_list *as_list;
12525
12526 as_list = as_list_lookup(filter);
12527 if (as_list == NULL) {
12528 vty_out(vty, "%% %s AS-path access-list not found\n",
12529 filter);
12530 return CMD_WARNING;
12531 }
12532
12533 sh_type = bgp_show_type_filter_list;
12534 output_arg = as_list;
12535 }
12536
12537 if (argv_find(argv, argc, "prefix-list", &idx)) {
12538 const char *prefix_list_str = argv[++idx]->arg;
12539 struct prefix_list *plist;
12540
12541 plist = prefix_list_lookup(afi, prefix_list_str);
12542 if (plist == NULL) {
12543 vty_out(vty, "%% %s prefix-list not found\n",
12544 prefix_list_str);
12545 return CMD_WARNING;
12546 }
12547
12548 sh_type = bgp_show_type_prefix_list;
12549 output_arg = plist;
12550 }
12551
12552 if (argv_find(argv, argc, "access-list", &idx)) {
12553 const char *access_list_str = argv[++idx]->arg;
12554 struct access_list *alist;
12555
12556 alist = access_list_lookup(afi, access_list_str);
12557 if (!alist) {
12558 vty_out(vty, "%% %s access-list not found\n",
12559 access_list_str);
12560 return CMD_WARNING;
12561 }
12562
12563 sh_type = bgp_show_type_access_list;
12564 output_arg = alist;
12565 }
12566
12567 if (argv_find(argv, argc, "route-map", &idx)) {
12568 const char *rmap_str = argv[++idx]->arg;
12569 struct route_map *rmap;
12570
12571 rmap = route_map_lookup_by_name(rmap_str);
12572 if (!rmap) {
12573 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12574 return CMD_WARNING;
12575 }
12576
12577 sh_type = bgp_show_type_route_map;
12578 output_arg = rmap;
12579 }
12580
12581 if (argv_find(argv, argc, "rpki", &idx)) {
12582 sh_type = bgp_show_type_rpki;
12583 if (argv_find(argv, argc, "valid", &idx))
12584 rpki_target_state = RPKI_VALID;
12585 else if (argv_find(argv, argc, "invalid", &idx))
12586 rpki_target_state = RPKI_INVALID;
12587 }
12588
12589 /* Display prefixes with matching version numbers */
12590 if (argv_find(argv, argc, "version", &idx)) {
12591 sh_type = bgp_show_type_prefix_version;
12592 output_arg = argv[idx + 1]->arg;
12593 }
12594
12595 /* Display prefixes with matching BGP community alias */
12596 if (argv_find(argv, argc, "alias", &idx)) {
12597 sh_type = bgp_show_type_community_alias;
12598 output_arg = argv[idx + 1]->arg;
12599 }
12600
12601 /* prefix-longer */
12602 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12603 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12604 const char *prefix_str = argv[idx]->arg;
12605
12606 if (!str2prefix(prefix_str, &p)) {
12607 vty_out(vty, "%% Malformed Prefix\n");
12608 return CMD_WARNING;
12609 }
12610
12611 sh_type = bgp_show_type_prefix_longer;
12612 output_arg = &p;
12613 }
12614
12615 if (!all) {
12616 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12617 if (community)
12618 return bgp_show_community(vty, bgp, community,
12619 exact_match, afi, safi,
12620 show_flags);
12621 else
12622 return bgp_show(vty, bgp, afi, safi, sh_type,
12623 output_arg, show_flags,
12624 rpki_target_state);
12625 } else {
12626 struct listnode *node;
12627 struct bgp *abgp;
12628 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12629 * AFI_IP6 */
12630
12631 if (uj)
12632 vty_out(vty, "{\n");
12633
12634 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12635 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12636 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12637 ? AFI_IP
12638 : AFI_IP6;
12639 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12640 FOREACH_SAFI (safi) {
12641 if (!bgp_afi_safi_peer_exists(abgp, afi,
12642 safi))
12643 continue;
12644
12645 if (uj) {
12646 if (first)
12647 first = false;
12648 else
12649 vty_out(vty, ",\n");
12650 vty_out(vty, "\"%s\":{\n",
12651 get_afi_safi_str(afi,
12652 safi,
12653 true));
12654 } else
12655 vty_out(vty,
12656 "\nFor address family: %s\n",
12657 get_afi_safi_str(
12658 afi, safi,
12659 false));
12660
12661 if (community)
12662 bgp_show_community(
12663 vty, abgp, community,
12664 exact_match, afi, safi,
12665 show_flags);
12666 else
12667 bgp_show(vty, abgp, afi, safi,
12668 sh_type, output_arg,
12669 show_flags,
12670 rpki_target_state);
12671 if (uj)
12672 vty_out(vty, "}\n");
12673 }
12674 }
12675 } else {
12676 /* show <ip> bgp all: for each AFI and SAFI*/
12677 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12678 FOREACH_AFI_SAFI (afi, safi) {
12679 if (!bgp_afi_safi_peer_exists(abgp, afi,
12680 safi))
12681 continue;
12682
12683 if (uj) {
12684 if (first)
12685 first = false;
12686 else
12687 vty_out(vty, ",\n");
12688
12689 vty_out(vty, "\"%s\":{\n",
12690 get_afi_safi_str(afi,
12691 safi,
12692 true));
12693 } else
12694 vty_out(vty,
12695 "\nFor address family: %s\n",
12696 get_afi_safi_str(
12697 afi, safi,
12698 false));
12699
12700 if (community)
12701 bgp_show_community(
12702 vty, abgp, community,
12703 exact_match, afi, safi,
12704 show_flags);
12705 else
12706 bgp_show(vty, abgp, afi, safi,
12707 sh_type, output_arg,
12708 show_flags,
12709 rpki_target_state);
12710 if (uj)
12711 vty_out(vty, "}\n");
12712 }
12713 }
12714 }
12715 if (uj)
12716 vty_out(vty, "}\n");
12717 }
12718 return CMD_SUCCESS;
12719}
12720
12721DEFUN (show_ip_bgp_route,
12722 show_ip_bgp_route_cmd,
12723 "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]",
12724 SHOW_STR
12725 IP_STR
12726 BGP_STR
12727 BGP_INSTANCE_HELP_STR
12728 BGP_AFI_HELP_STR
12729 BGP_SAFI_WITH_LABEL_HELP_STR
12730 "Network in the BGP routing table to display\n"
12731 "IPv4 prefix\n"
12732 "Network in the BGP routing table to display\n"
12733 "IPv6 prefix\n"
12734 "Display only the bestpath\n"
12735 "Display only multipaths\n"
12736 "Display only paths that match the specified rpki state\n"
12737 "A valid path as determined by rpki\n"
12738 "A invalid path as determined by rpki\n"
12739 "A path that has no rpki data\n"
12740 JSON_STR)
12741{
12742 int prefix_check = 0;
12743
12744 afi_t afi = AFI_IP6;
12745 safi_t safi = SAFI_UNICAST;
12746 char *prefix = NULL;
12747 struct bgp *bgp = NULL;
12748 enum bgp_path_type path_type;
12749 bool uj = use_json(argc, argv);
12750
12751 int idx = 0;
12752
12753 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12754 &bgp, uj);
12755 if (!idx)
12756 return CMD_WARNING;
12757
12758 if (!bgp) {
12759 vty_out(vty,
12760 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12761 return CMD_WARNING;
12762 }
12763
12764 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12765 if (argv_find(argv, argc, "A.B.C.D", &idx)
12766 || argv_find(argv, argc, "X:X::X:X", &idx))
12767 prefix_check = 0;
12768 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12769 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12770 prefix_check = 1;
12771
12772 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12773 && afi != AFI_IP6) {
12774 vty_out(vty,
12775 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12776 return CMD_WARNING;
12777 }
12778 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12779 && afi != AFI_IP) {
12780 vty_out(vty,
12781 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12782 return CMD_WARNING;
12783 }
12784
12785 prefix = argv[idx]->arg;
12786
12787 /* [<bestpath|multipath>] */
12788 if (argv_find(argv, argc, "bestpath", &idx))
12789 path_type = BGP_PATH_SHOW_BESTPATH;
12790 else if (argv_find(argv, argc, "multipath", &idx))
12791 path_type = BGP_PATH_SHOW_MULTIPATH;
12792 else
12793 path_type = BGP_PATH_SHOW_ALL;
12794
12795 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12796 path_type, RPKI_NOT_BEING_USED, uj);
12797}
12798
12799DEFUN (show_ip_bgp_regexp,
12800 show_ip_bgp_regexp_cmd,
12801 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12802 SHOW_STR
12803 IP_STR
12804 BGP_STR
12805 BGP_INSTANCE_HELP_STR
12806 BGP_AFI_HELP_STR
12807 BGP_SAFI_WITH_LABEL_HELP_STR
12808 "Display routes matching the AS path regular expression\n"
12809 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12810 JSON_STR)
12811{
12812 afi_t afi = AFI_IP6;
12813 safi_t safi = SAFI_UNICAST;
12814 struct bgp *bgp = NULL;
12815 bool uj = use_json(argc, argv);
12816 char *regstr = NULL;
12817
12818 int idx = 0;
12819 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12820 &bgp, false);
12821 if (!idx)
12822 return CMD_WARNING;
12823
12824 // get index of regex
12825 if (argv_find(argv, argc, "REGEX", &idx))
12826 regstr = argv[idx]->arg;
12827
12828 assert(regstr);
12829 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12830 bgp_show_type_regexp, uj);
12831}
12832
12833DEFPY (show_ip_bgp_instance_all,
12834 show_ip_bgp_instance_all_cmd,
12835 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12836 SHOW_STR
12837 IP_STR
12838 BGP_STR
12839 BGP_INSTANCE_ALL_HELP_STR
12840 BGP_AFI_HELP_STR
12841 BGP_SAFI_WITH_LABEL_HELP_STR
12842 JSON_STR
12843 "Increase table width for longer prefixes\n")
12844{
12845 afi_t afi = AFI_IP6;
12846 safi_t safi = SAFI_UNICAST;
12847 struct bgp *bgp = NULL;
12848 int idx = 0;
12849 uint16_t show_flags = 0;
12850
12851 if (uj) {
12852 argc--;
12853 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12854 }
12855
12856 if (wide)
12857 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12858
12859 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12860 &bgp, uj);
12861 if (!idx)
12862 return CMD_WARNING;
12863
12864 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12865 return CMD_SUCCESS;
12866}
12867
12868static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12869 afi_t afi, safi_t safi, enum bgp_show_type type,
12870 bool use_json)
12871{
12872 regex_t *regex;
12873 int rc;
12874 uint16_t show_flags = 0;
12875
12876 if (use_json)
12877 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12878
12879 if (!config_bgp_aspath_validate(regstr)) {
12880 vty_out(vty, "Invalid character in REGEX %s\n",
12881 regstr);
12882 return CMD_WARNING_CONFIG_FAILED;
12883 }
12884
12885 regex = bgp_regcomp(regstr);
12886 if (!regex) {
12887 vty_out(vty, "Can't compile regexp %s\n", regstr);
12888 return CMD_WARNING;
12889 }
12890
12891 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
12892 RPKI_NOT_BEING_USED);
12893 bgp_regex_free(regex);
12894 return rc;
12895}
12896
12897static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12898 const char *comstr, int exact, afi_t afi,
12899 safi_t safi, uint16_t show_flags)
12900{
12901 struct community *com;
12902 int ret = 0;
12903
12904 com = community_str2com(comstr);
12905 if (!com) {
12906 vty_out(vty, "%% Community malformed: %s\n", comstr);
12907 return CMD_WARNING;
12908 }
12909
12910 ret = bgp_show(vty, bgp, afi, safi,
12911 (exact ? bgp_show_type_community_exact
12912 : bgp_show_type_community),
12913 com, show_flags, RPKI_NOT_BEING_USED);
12914 community_free(&com);
12915
12916 return ret;
12917}
12918
12919enum bgp_stats {
12920 BGP_STATS_MAXBITLEN = 0,
12921 BGP_STATS_RIB,
12922 BGP_STATS_PREFIXES,
12923 BGP_STATS_TOTPLEN,
12924 BGP_STATS_UNAGGREGATEABLE,
12925 BGP_STATS_MAX_AGGREGATEABLE,
12926 BGP_STATS_AGGREGATES,
12927 BGP_STATS_SPACE,
12928 BGP_STATS_ASPATH_COUNT,
12929 BGP_STATS_ASPATH_MAXHOPS,
12930 BGP_STATS_ASPATH_TOTHOPS,
12931 BGP_STATS_ASPATH_MAXSIZE,
12932 BGP_STATS_ASPATH_TOTSIZE,
12933 BGP_STATS_ASN_HIGHEST,
12934 BGP_STATS_MAX,
12935};
12936
12937#define TABLE_STATS_IDX_VTY 0
12938#define TABLE_STATS_IDX_JSON 1
12939
12940static const char *table_stats_strs[][2] = {
12941 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12942 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12943 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12944 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12945 "unaggregateablePrefixes"},
12946 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12947 "maximumAggregateablePrefixes"},
12948 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12949 "bgpAggregateAdvertisements"},
12950 [BGP_STATS_SPACE] = {"Address space advertised",
12951 "addressSpaceAdvertised"},
12952 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12953 "advertisementsWithPaths"},
12954 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12955 "longestAsPath"},
12956 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12957 "largestAsPath"},
12958 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12959 "averageAsPathLengthHops"},
12960 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12961 "averageAsPathSizeBytes"},
12962 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12963 [BGP_STATS_MAX] = {NULL, NULL}
12964};
12965
12966struct bgp_table_stats {
12967 struct bgp_table *table;
12968 unsigned long long counts[BGP_STATS_MAX];
12969
12970 unsigned long long
12971 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
12972 1];
12973
12974 double total_space;
12975};
12976
12977static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12978 struct bgp_table_stats *ts, unsigned int space)
12979{
12980 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12981 struct bgp_path_info *pi;
12982 const struct prefix *rn_p;
12983
12984 if (!bgp_dest_has_bgp_path_info_data(dest))
12985 return;
12986
12987 rn_p = bgp_dest_get_prefix(dest);
12988 ts->counts[BGP_STATS_PREFIXES]++;
12989 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12990
12991 ts->prefix_len_count[rn_p->prefixlen]++;
12992 /* check if the prefix is included by any other announcements */
12993 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12994 pdest = bgp_dest_parent_nolock(pdest);
12995
12996 if (pdest == NULL || pdest == top) {
12997 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12998 /* announced address space */
12999 if (space)
13000 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13001 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13002 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13003
13004
13005 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13006 ts->counts[BGP_STATS_RIB]++;
13007
13008 if (CHECK_FLAG(pi->attr->flag,
13009 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13010 ts->counts[BGP_STATS_AGGREGATES]++;
13011
13012 /* as-path stats */
13013 if (pi->attr->aspath) {
13014 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13015 unsigned int size = aspath_size(pi->attr->aspath);
13016 as_t highest = aspath_highest(pi->attr->aspath);
13017
13018 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13019
13020 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13021 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13022
13023 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13024 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13025
13026 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13027 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13028 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13029 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13030 }
13031 }
13032}
13033
13034static void bgp_table_stats_walker(struct thread *t)
13035{
13036 struct bgp_dest *dest, *ndest;
13037 struct bgp_dest *top;
13038 struct bgp_table_stats *ts = THREAD_ARG(t);
13039 unsigned int space = 0;
13040
13041 if (!(top = bgp_table_top(ts->table)))
13042 return;
13043
13044 switch (ts->table->afi) {
13045 case AFI_IP:
13046 space = IPV4_MAX_BITLEN;
13047 break;
13048 case AFI_IP6:
13049 space = IPV6_MAX_BITLEN;
13050 break;
13051 case AFI_L2VPN:
13052 space = EVPN_ROUTE_PREFIXLEN;
13053 break;
13054 default:
13055 return;
13056 }
13057
13058 ts->counts[BGP_STATS_MAXBITLEN] = space;
13059
13060 for (dest = top; dest; dest = bgp_route_next(dest)) {
13061 if (ts->table->safi == SAFI_MPLS_VPN
13062 || ts->table->safi == SAFI_ENCAP
13063 || ts->table->safi == SAFI_EVPN) {
13064 struct bgp_table *table;
13065
13066 table = bgp_dest_get_bgp_table_info(dest);
13067 if (!table)
13068 continue;
13069
13070 top = bgp_table_top(table);
13071 for (ndest = bgp_table_top(table); ndest;
13072 ndest = bgp_route_next(ndest))
13073 bgp_table_stats_rn(ndest, top, ts, space);
13074 } else {
13075 bgp_table_stats_rn(dest, top, ts, space);
13076 }
13077 }
13078}
13079
13080static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13081 struct json_object *json_array)
13082{
13083 struct listnode *node, *nnode;
13084 struct bgp *bgp;
13085
13086 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13087 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13088}
13089
13090static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13091 safi_t safi, struct json_object *json_array)
13092{
13093 struct bgp_table_stats ts;
13094 unsigned int i;
13095 int ret = CMD_SUCCESS;
13096 char temp_buf[20];
13097 struct json_object *json = NULL;
13098 uint32_t bitlen = 0;
13099 struct json_object *json_bitlen;
13100
13101 if (json_array)
13102 json = json_object_new_object();
13103
13104 if (!bgp->rib[afi][safi]) {
13105 char warning_msg[50];
13106
13107 snprintf(warning_msg, sizeof(warning_msg),
13108 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13109 safi);
13110
13111 if (!json)
13112 vty_out(vty, "%s\n", warning_msg);
13113 else
13114 json_object_string_add(json, "warning", warning_msg);
13115
13116 ret = CMD_WARNING;
13117 goto end_table_stats;
13118 }
13119
13120 if (!json)
13121 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13122 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13123 else
13124 json_object_string_add(json, "instance", bgp->name_pretty);
13125
13126 /* labeled-unicast routes live in the unicast table */
13127 if (safi == SAFI_LABELED_UNICAST)
13128 safi = SAFI_UNICAST;
13129
13130 memset(&ts, 0, sizeof(ts));
13131 ts.table = bgp->rib[afi][safi];
13132 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13133
13134 for (i = 0; i < BGP_STATS_MAX; i++) {
13135 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13136 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13137 continue;
13138
13139 switch (i) {
13140 case BGP_STATS_ASPATH_TOTHOPS:
13141 case BGP_STATS_ASPATH_TOTSIZE:
13142 if (!json) {
13143 snprintf(
13144 temp_buf, sizeof(temp_buf), "%12.2f",
13145 ts.counts[i]
13146 ? (float)ts.counts[i]
13147 / (float)ts.counts
13148 [BGP_STATS_ASPATH_COUNT]
13149 : 0);
13150 vty_out(vty, "%-30s: %s",
13151 table_stats_strs[i]
13152 [TABLE_STATS_IDX_VTY],
13153 temp_buf);
13154 } else {
13155 json_object_double_add(
13156 json,
13157 table_stats_strs[i]
13158 [TABLE_STATS_IDX_JSON],
13159 ts.counts[i]
13160 ? (double)ts.counts[i]
13161 / (double)ts.counts
13162 [BGP_STATS_ASPATH_COUNT]
13163 : 0);
13164 }
13165 break;
13166 case BGP_STATS_TOTPLEN:
13167 if (!json) {
13168 snprintf(
13169 temp_buf, sizeof(temp_buf), "%12.2f",
13170 ts.counts[i]
13171 ? (float)ts.counts[i]
13172 / (float)ts.counts
13173 [BGP_STATS_PREFIXES]
13174 : 0);
13175 vty_out(vty, "%-30s: %s",
13176 table_stats_strs[i]
13177 [TABLE_STATS_IDX_VTY],
13178 temp_buf);
13179 } else {
13180 json_object_double_add(
13181 json,
13182 table_stats_strs[i]
13183 [TABLE_STATS_IDX_JSON],
13184 ts.counts[i]
13185 ? (double)ts.counts[i]
13186 / (double)ts.counts
13187 [BGP_STATS_PREFIXES]
13188 : 0);
13189 }
13190 break;
13191 case BGP_STATS_SPACE:
13192 if (!json) {
13193 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13194 ts.total_space);
13195 vty_out(vty, "%-30s: %s\n",
13196 table_stats_strs[i]
13197 [TABLE_STATS_IDX_VTY],
13198 temp_buf);
13199 } else {
13200 json_object_double_add(
13201 json,
13202 table_stats_strs[i]
13203 [TABLE_STATS_IDX_JSON],
13204 (double)ts.total_space);
13205 }
13206 if (afi == AFI_IP6) {
13207 if (!json) {
13208 snprintf(temp_buf, sizeof(temp_buf),
13209 "%12g",
13210 ts.total_space
13211 * pow(2.0, -128 + 32));
13212 vty_out(vty, "%30s: %s\n",
13213 "/32 equivalent %s\n",
13214 temp_buf);
13215 } else {
13216 json_object_double_add(
13217 json, "/32equivalent",
13218 (double)(ts.total_space
13219 * pow(2.0,
13220 -128 + 32)));
13221 }
13222 if (!json) {
13223 snprintf(temp_buf, sizeof(temp_buf),
13224 "%12g",
13225 ts.total_space
13226 * pow(2.0, -128 + 48));
13227 vty_out(vty, "%30s: %s\n",
13228 "/48 equivalent %s\n",
13229 temp_buf);
13230 } else {
13231 json_object_double_add(
13232 json, "/48equivalent",
13233 (double)(ts.total_space
13234 * pow(2.0,
13235 -128 + 48)));
13236 }
13237 } else {
13238 if (!json) {
13239 snprintf(temp_buf, sizeof(temp_buf),
13240 "%12.2f",
13241 ts.total_space * 100.
13242 * pow(2.0, -32));
13243 vty_out(vty, "%30s: %s\n",
13244 "% announced ", temp_buf);
13245 } else {
13246 json_object_double_add(
13247 json, "%announced",
13248 (double)(ts.total_space * 100.
13249 * pow(2.0, -32)));
13250 }
13251 if (!json) {
13252 snprintf(temp_buf, sizeof(temp_buf),
13253 "%12.2f",
13254 ts.total_space
13255 * pow(2.0, -32 + 8));
13256 vty_out(vty, "%30s: %s\n",
13257 "/8 equivalent ", temp_buf);
13258 } else {
13259 json_object_double_add(
13260 json, "/8equivalent",
13261 (double)(ts.total_space
13262 * pow(2.0, -32 + 8)));
13263 }
13264 if (!json) {
13265 snprintf(temp_buf, sizeof(temp_buf),
13266 "%12.2f",
13267 ts.total_space
13268 * pow(2.0, -32 + 24));
13269 vty_out(vty, "%30s: %s\n",
13270 "/24 equivalent ", temp_buf);
13271 } else {
13272 json_object_double_add(
13273 json, "/24equivalent",
13274 (double)(ts.total_space
13275 * pow(2.0, -32 + 24)));
13276 }
13277 }
13278 break;
13279 default:
13280 if (!json) {
13281 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13282 ts.counts[i]);
13283 vty_out(vty, "%-30s: %s",
13284 table_stats_strs[i]
13285 [TABLE_STATS_IDX_VTY],
13286 temp_buf);
13287 } else {
13288 json_object_int_add(
13289 json,
13290 table_stats_strs[i]
13291 [TABLE_STATS_IDX_JSON],
13292 ts.counts[i]);
13293 }
13294 }
13295 if (!json)
13296 vty_out(vty, "\n");
13297 }
13298
13299 switch (afi) {
13300 case AFI_IP:
13301 bitlen = IPV4_MAX_BITLEN;
13302 break;
13303 case AFI_IP6:
13304 bitlen = IPV6_MAX_BITLEN;
13305 break;
13306 case AFI_L2VPN:
13307 bitlen = EVPN_ROUTE_PREFIXLEN;
13308 break;
13309 default:
13310 break;
13311 }
13312
13313 if (json) {
13314 json_bitlen = json_object_new_array();
13315
13316 for (i = 0; i <= bitlen; i++) {
13317 struct json_object *ind_bit = json_object_new_object();
13318
13319 if (!ts.prefix_len_count[i])
13320 continue;
13321
13322 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13323 json_object_int_add(ind_bit, temp_buf,
13324 ts.prefix_len_count[i]);
13325 json_object_array_add(json_bitlen, ind_bit);
13326 }
13327 json_object_object_add(json, "prefixLength", json_bitlen);
13328 }
13329
13330end_table_stats:
13331 if (json)
13332 json_object_array_add(json_array, json);
13333 return ret;
13334}
13335
13336static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13337 safi_t safi, struct json_object *json_array)
13338{
13339 if (!bgp) {
13340 bgp_table_stats_all(vty, afi, safi, json_array);
13341 return CMD_SUCCESS;
13342 }
13343
13344 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13345}
13346
13347enum bgp_pcounts {
13348 PCOUNT_ADJ_IN = 0,
13349 PCOUNT_DAMPED,
13350 PCOUNT_REMOVED,
13351 PCOUNT_HISTORY,
13352 PCOUNT_STALE,
13353 PCOUNT_VALID,
13354 PCOUNT_ALL,
13355 PCOUNT_COUNTED,
13356 PCOUNT_BPATH_SELECTED,
13357 PCOUNT_PFCNT, /* the figure we display to users */
13358 PCOUNT_MAX,
13359};
13360
13361static const char *const pcount_strs[] = {
13362 [PCOUNT_ADJ_IN] = "Adj-in",
13363 [PCOUNT_DAMPED] = "Damped",
13364 [PCOUNT_REMOVED] = "Removed",
13365 [PCOUNT_HISTORY] = "History",
13366 [PCOUNT_STALE] = "Stale",
13367 [PCOUNT_VALID] = "Valid",
13368 [PCOUNT_ALL] = "All RIB",
13369 [PCOUNT_COUNTED] = "PfxCt counted",
13370 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13371 [PCOUNT_PFCNT] = "Useable",
13372 [PCOUNT_MAX] = NULL,
13373};
13374
13375struct peer_pcounts {
13376 unsigned int count[PCOUNT_MAX];
13377 const struct peer *peer;
13378 const struct bgp_table *table;
13379 safi_t safi;
13380};
13381
13382static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13383{
13384 const struct bgp_adj_in *ain;
13385 const struct bgp_path_info *pi;
13386 const struct peer *peer = pc->peer;
13387
13388 for (ain = rn->adj_in; ain; ain = ain->next)
13389 if (ain->peer == peer)
13390 pc->count[PCOUNT_ADJ_IN]++;
13391
13392 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13393
13394 if (pi->peer != peer)
13395 continue;
13396
13397 pc->count[PCOUNT_ALL]++;
13398
13399 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13400 pc->count[PCOUNT_DAMPED]++;
13401 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13402 pc->count[PCOUNT_HISTORY]++;
13403 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13404 pc->count[PCOUNT_REMOVED]++;
13405 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13406 pc->count[PCOUNT_STALE]++;
13407 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13408 pc->count[PCOUNT_VALID]++;
13409 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13410 pc->count[PCOUNT_PFCNT]++;
13411 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13412 pc->count[PCOUNT_BPATH_SELECTED]++;
13413
13414 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13415 pc->count[PCOUNT_COUNTED]++;
13416 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13417 flog_err(
13418 EC_LIB_DEVELOPMENT,
13419 "Attempting to count but flags say it is unusable");
13420 } else {
13421 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13422 flog_err(
13423 EC_LIB_DEVELOPMENT,
13424 "Not counted but flags say we should");
13425 }
13426 }
13427}
13428
13429static void bgp_peer_count_walker(struct thread *t)
13430{
13431 struct bgp_dest *rn, *rm;
13432 const struct bgp_table *table;
13433 struct peer_pcounts *pc = THREAD_ARG(t);
13434
13435 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13436 || pc->safi == SAFI_EVPN) {
13437 /* Special handling for 2-level routing tables. */
13438 for (rn = bgp_table_top(pc->table); rn;
13439 rn = bgp_route_next(rn)) {
13440 table = bgp_dest_get_bgp_table_info(rn);
13441 if (table != NULL)
13442 for (rm = bgp_table_top(table); rm;
13443 rm = bgp_route_next(rm))
13444 bgp_peer_count_proc(rm, pc);
13445 }
13446 } else
13447 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13448 bgp_peer_count_proc(rn, pc);
13449}
13450
13451static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13452 safi_t safi, bool use_json)
13453{
13454 struct peer_pcounts pcounts = {.peer = peer};
13455 unsigned int i;
13456 json_object *json = NULL;
13457 json_object *json_loop = NULL;
13458
13459 if (use_json) {
13460 json = json_object_new_object();
13461 json_loop = json_object_new_object();
13462 }
13463
13464 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13465 || !peer->bgp->rib[afi][safi]) {
13466 if (use_json) {
13467 json_object_string_add(
13468 json, "warning",
13469 "No such neighbor or address family");
13470 vty_out(vty, "%s\n", json_object_to_json_string(json));
13471 json_object_free(json);
13472 json_object_free(json_loop);
13473 } else
13474 vty_out(vty, "%% No such neighbor or address family\n");
13475
13476 return CMD_WARNING;
13477 }
13478
13479 memset(&pcounts, 0, sizeof(pcounts));
13480 pcounts.peer = peer;
13481 pcounts.table = peer->bgp->rib[afi][safi];
13482 pcounts.safi = safi;
13483
13484 /* in-place call via thread subsystem so as to record execution time
13485 * stats for the thread-walk (i.e. ensure this can't be blamed on
13486 * on just vty_read()).
13487 */
13488 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13489
13490 if (use_json) {
13491 json_object_string_add(json, "prefixCountsFor", peer->host);
13492 json_object_string_add(json, "multiProtocol",
13493 get_afi_safi_str(afi, safi, true));
13494 json_object_int_add(json, "pfxCounter",
13495 peer->pcount[afi][safi]);
13496
13497 for (i = 0; i < PCOUNT_MAX; i++)
13498 json_object_int_add(json_loop, pcount_strs[i],
13499 pcounts.count[i]);
13500
13501 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13502
13503 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13504 json_object_string_add(json, "pfxctDriftFor",
13505 peer->host);
13506 json_object_string_add(
13507 json, "recommended",
13508 "Please report this bug, with the above command output");
13509 }
13510 vty_json(vty, json);
13511 } else {
13512
13513 if (peer->hostname
13514 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13515 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13516 peer->hostname, peer->host,
13517 get_afi_safi_str(afi, safi, false));
13518 } else {
13519 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13520 get_afi_safi_str(afi, safi, false));
13521 }
13522
13523 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13524 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13525
13526 for (i = 0; i < PCOUNT_MAX; i++)
13527 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13528 pcounts.count[i]);
13529
13530 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13531 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13532 vty_out(vty,
13533 "Please report this bug, with the above command output\n");
13534 }
13535 }
13536
13537 return CMD_SUCCESS;
13538}
13539
13540DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13541 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13542 "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]",
13543 SHOW_STR
13544 IP_STR
13545 BGP_STR
13546 BGP_INSTANCE_HELP_STR
13547 BGP_AFI_HELP_STR
13548 BGP_SAFI_HELP_STR
13549 "Detailed information on TCP and BGP neighbor connections\n"
13550 "Neighbor to display information about\n"
13551 "Neighbor to display information about\n"
13552 "Neighbor on BGP configured interface\n"
13553 "Display detailed prefix count information\n"
13554 JSON_STR)
13555{
13556 afi_t afi = AFI_IP6;
13557 safi_t safi = SAFI_UNICAST;
13558 struct peer *peer;
13559 int idx = 0;
13560 struct bgp *bgp = NULL;
13561 bool uj = use_json(argc, argv);
13562
13563 if (uj)
13564 argc--;
13565
13566 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13567 &bgp, uj);
13568 if (!idx)
13569 return CMD_WARNING;
13570
13571 argv_find(argv, argc, "neighbors", &idx);
13572 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13573 if (!peer)
13574 return CMD_WARNING;
13575
13576 return bgp_peer_counts(vty, peer, afi, safi, uj);
13577}
13578
13579#ifdef KEEP_OLD_VPN_COMMANDS
13580DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13581 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13582 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13583 SHOW_STR
13584 IP_STR
13585 BGP_STR
13586 BGP_VPNVX_HELP_STR
13587 "Display information about all VPNv4 NLRIs\n"
13588 "Detailed information on TCP and BGP neighbor connections\n"
13589 "Neighbor to display information about\n"
13590 "Neighbor to display information about\n"
13591 "Neighbor on BGP configured interface\n"
13592 "Display detailed prefix count information\n"
13593 JSON_STR)
13594{
13595 int idx_peer = 6;
13596 struct peer *peer;
13597 bool uj = use_json(argc, argv);
13598
13599 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13600 if (!peer)
13601 return CMD_WARNING;
13602
13603 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13604}
13605
13606DEFUN (show_ip_bgp_vpn_all_route_prefix,
13607 show_ip_bgp_vpn_all_route_prefix_cmd,
13608 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13609 SHOW_STR
13610 IP_STR
13611 BGP_STR
13612 BGP_VPNVX_HELP_STR
13613 "Display information about all VPNv4 NLRIs\n"
13614 "Network in the BGP routing table to display\n"
13615 "Network in the BGP routing table to display\n"
13616 JSON_STR)
13617{
13618 int idx = 0;
13619 char *network = NULL;
13620 struct bgp *bgp = bgp_get_default();
13621 if (!bgp) {
13622 vty_out(vty, "Can't find default instance\n");
13623 return CMD_WARNING;
13624 }
13625
13626 if (argv_find(argv, argc, "A.B.C.D", &idx))
13627 network = argv[idx]->arg;
13628 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13629 network = argv[idx]->arg;
13630 else {
13631 vty_out(vty, "Unable to figure out Network\n");
13632 return CMD_WARNING;
13633 }
13634
13635 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13636 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13637 use_json(argc, argv));
13638}
13639#endif /* KEEP_OLD_VPN_COMMANDS */
13640
13641DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13642 show_bgp_l2vpn_evpn_route_prefix_cmd,
13643 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13644 SHOW_STR
13645 BGP_STR
13646 L2VPN_HELP_STR
13647 EVPN_HELP_STR
13648 "Network in the BGP routing table to display\n"
13649 "Network in the BGP routing table to display\n"
13650 "Network in the BGP routing table to display\n"
13651 "Network in the BGP routing table to display\n"
13652 JSON_STR)
13653{
13654 int idx = 0;
13655 char *network = NULL;
13656 int prefix_check = 0;
13657
13658 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13659 argv_find(argv, argc, "X:X::X:X", &idx))
13660 network = argv[idx]->arg;
13661 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13662 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13663 network = argv[idx]->arg;
13664 prefix_check = 1;
13665 } else {
13666 vty_out(vty, "Unable to figure out Network\n");
13667 return CMD_WARNING;
13668 }
13669 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13670 prefix_check, BGP_PATH_SHOW_ALL,
13671 RPKI_NOT_BEING_USED, use_json(argc, argv));
13672}
13673
13674static void show_adj_route_header(struct vty *vty, struct peer *peer,
13675 struct bgp_table *table, int *header1,
13676 int *header2, json_object *json,
13677 json_object *json_scode,
13678 json_object *json_ocode, bool wide)
13679{
13680 uint64_t version = table ? table->version : 0;
13681
13682 if (*header1) {
13683 if (json) {
13684 json_object_int_add(json, "bgpTableVersion", version);
13685 json_object_string_addf(json, "bgpLocalRouterId",
13686 "%pI4", &peer->bgp->router_id);
13687 json_object_int_add(json, "defaultLocPrf",
13688 peer->bgp->default_local_pref);
13689 json_object_int_add(json, "localAS",
13690 peer->change_local_as
13691 ? peer->change_local_as
13692 : peer->local_as);
13693 json_object_object_add(json, "bgpStatusCodes",
13694 json_scode);
13695 json_object_object_add(json, "bgpOriginCodes",
13696 json_ocode);
13697 } else {
13698 vty_out(vty,
13699 "BGP table version is %" PRIu64
13700 ", local router ID is %pI4, vrf id ",
13701 version, &peer->bgp->router_id);
13702 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13703 vty_out(vty, "%s", VRFID_NONE_STR);
13704 else
13705 vty_out(vty, "%u", peer->bgp->vrf_id);
13706 vty_out(vty, "\n");
13707 vty_out(vty, "Default local pref %u, ",
13708 peer->bgp->default_local_pref);
13709 vty_out(vty, "local AS %u\n",
13710 peer->change_local_as ? peer->change_local_as
13711 : peer->local_as);
13712 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13713 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13714 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13715 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13716 }
13717 *header1 = 0;
13718 }
13719 if (*header2) {
13720 if (!json)
13721 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13722 : BGP_SHOW_HEADER));
13723 *header2 = 0;
13724 }
13725}
13726
13727static void
13728show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13729 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13730 const char *rmap_name, json_object *json, json_object *json_ar,
13731 json_object *json_scode, json_object *json_ocode,
13732 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13733 unsigned long *output_count, unsigned long *filtered_count)
13734{
13735 struct bgp_adj_in *ain;
13736 struct bgp_adj_out *adj;
13737 struct bgp_dest *dest;
13738 struct bgp *bgp;
13739 struct attr attr;
13740 int ret;
13741 struct update_subgroup *subgrp;
13742 struct peer_af *paf;
13743 bool route_filtered;
13744 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13745 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13746 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13747 || (safi == SAFI_EVPN))
13748 ? true
13749 : false;
13750
13751 bgp = peer->bgp;
13752
13753 subgrp = peer_subgroup(peer, afi, safi);
13754
13755 if (type == bgp_show_adj_route_advertised && subgrp
13756 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13757 if (use_json) {
13758 json_object_int_add(json, "bgpTableVersion",
13759 table->version);
13760 json_object_string_addf(json, "bgpLocalRouterId",
13761 "%pI4", &bgp->router_id);
13762 json_object_int_add(json, "defaultLocPrf",
13763 bgp->default_local_pref);
13764 json_object_int_add(json, "localAS",
13765 peer->change_local_as
13766 ? peer->change_local_as
13767 : peer->local_as);
13768 json_object_object_add(json, "bgpStatusCodes",
13769 json_scode);
13770 json_object_object_add(json, "bgpOriginCodes",
13771 json_ocode);
13772 json_object_string_add(
13773 json, "bgpOriginatingDefaultNetwork",
13774 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13775 } else {
13776 vty_out(vty,
13777 "BGP table version is %" PRIu64
13778 ", local router ID is %pI4, vrf id ",
13779 table->version, &bgp->router_id);
13780 if (bgp->vrf_id == VRF_UNKNOWN)
13781 vty_out(vty, "%s", VRFID_NONE_STR);
13782 else
13783 vty_out(vty, "%u", bgp->vrf_id);
13784 vty_out(vty, "\n");
13785 vty_out(vty, "Default local pref %u, ",
13786 bgp->default_local_pref);
13787 vty_out(vty, "local AS %u\n",
13788 peer->change_local_as ? peer->change_local_as
13789 : peer->local_as);
13790 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13791 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13792 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13793 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13794
13795 vty_out(vty, "Originating default network %s\n\n",
13796 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13797 }
13798 *header1 = 0;
13799 }
13800
13801 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13802 if (type == bgp_show_adj_route_received
13803 || type == bgp_show_adj_route_filtered) {
13804 for (ain = dest->adj_in; ain; ain = ain->next) {
13805 if (ain->peer != peer)
13806 continue;
13807
13808 show_adj_route_header(vty, peer, table, header1,
13809 header2, json, json_scode,
13810 json_ocode, wide);
13811
13812 if ((safi == SAFI_MPLS_VPN)
13813 || (safi == SAFI_ENCAP)
13814 || (safi == SAFI_EVPN)) {
13815 if (use_json)
13816 json_object_string_add(
13817 json_ar, "rd", rd_str);
13818 else if (show_rd && rd_str) {
13819 vty_out(vty,
13820 "Route Distinguisher: %s\n",
13821 rd_str);
13822 show_rd = false;
13823 }
13824 }
13825
13826 attr = *ain->attr;
13827 route_filtered = false;
13828
13829 /* Filter prefix using distribute list,
13830 * filter list or prefix list
13831 */
13832 const struct prefix *rn_p =
13833 bgp_dest_get_prefix(dest);
13834 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13835 safi))
13836 == FILTER_DENY)
13837 route_filtered = true;
13838
13839 /* Filter prefix using route-map */
13840 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13841 safi, rmap_name, NULL,
13842 0, NULL);
13843
13844 if (type == bgp_show_adj_route_filtered &&
13845 !route_filtered && ret != RMAP_DENY) {
13846 bgp_attr_flush(&attr);
13847 continue;
13848 }
13849
13850 if (type == bgp_show_adj_route_received
13851 && (route_filtered || ret == RMAP_DENY))
13852 (*filtered_count)++;
13853
13854 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
13855 use_json, json_ar, wide);
13856 bgp_attr_flush(&attr);
13857 (*output_count)++;
13858 }
13859 } else if (type == bgp_show_adj_route_advertised) {
13860 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13861 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13862 if (paf->peer != peer || !adj->attr)
13863 continue;
13864
13865 show_adj_route_header(vty, peer, table,
13866 header1, header2,
13867 json, json_scode,
13868 json_ocode, wide);
13869
13870 const struct prefix *rn_p =
13871 bgp_dest_get_prefix(dest);
13872
13873 attr = *adj->attr;
13874 ret = bgp_output_modifier(
13875 peer, rn_p, &attr, afi, safi,
13876 rmap_name);
13877
13878 if (ret != RMAP_DENY) {
13879 if ((safi == SAFI_MPLS_VPN)
13880 || (safi == SAFI_ENCAP)
13881 || (safi == SAFI_EVPN)) {
13882 if (use_json)
13883 json_object_string_add(
13884 json_ar,
13885 "rd",
13886 rd_str);
13887 else if (show_rd
13888 && rd_str) {
13889 vty_out(vty,
13890 "Route Distinguisher: %s\n",
13891 rd_str);
13892 show_rd = false;
13893 }
13894 }
13895 route_vty_out_tmp(
13896 vty, dest, rn_p, &attr,
13897 safi, use_json, json_ar,
13898 wide);
13899 (*output_count)++;
13900 } else {
13901 (*filtered_count)++;
13902 }
13903
13904 bgp_attr_flush(&attr);
13905 }
13906 } else if (type == bgp_show_adj_route_bestpath) {
13907 struct bgp_path_info *pi;
13908
13909 show_adj_route_header(vty, peer, table, header1,
13910 header2, json, json_scode,
13911 json_ocode, wide);
13912
13913 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13914 pi = pi->next) {
13915 if (pi->peer != peer)
13916 continue;
13917
13918 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13919 continue;
13920
13921 route_vty_out_tmp(vty, dest,
13922 bgp_dest_get_prefix(dest),
13923 pi->attr, safi, use_json,
13924 json_ar, wide);
13925 (*output_count)++;
13926 }
13927 }
13928 }
13929}
13930
13931static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13932 safi_t safi, enum bgp_show_adj_route_type type,
13933 const char *rmap_name, uint16_t show_flags)
13934{
13935 struct bgp *bgp;
13936 struct bgp_table *table;
13937 json_object *json = NULL;
13938 json_object *json_scode = NULL;
13939 json_object *json_ocode = NULL;
13940 json_object *json_ar = NULL;
13941 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13942
13943 /* Init BGP headers here so they're only displayed once
13944 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13945 */
13946 int header1 = 1;
13947 int header2 = 1;
13948
13949 /*
13950 * Initialize variables for each RD
13951 * All prefixes under an RD is aggregated within "json_routes"
13952 */
13953 char rd_str[BUFSIZ] = {0};
13954 json_object *json_routes = NULL;
13955
13956
13957 /* For 2-tier tables, prefix counts need to be
13958 * maintained across multiple runs of show_adj_route()
13959 */
13960 unsigned long output_count_per_rd;
13961 unsigned long filtered_count_per_rd;
13962 unsigned long output_count = 0;
13963 unsigned long filtered_count = 0;
13964
13965 if (use_json) {
13966 json = json_object_new_object();
13967 json_ar = json_object_new_object();
13968 json_scode = json_object_new_object();
13969 json_ocode = json_object_new_object();
13970
13971 json_object_string_add(json_scode, "suppressed", "s");
13972 json_object_string_add(json_scode, "damped", "d");
13973 json_object_string_add(json_scode, "history", "h");
13974 json_object_string_add(json_scode, "valid", "*");
13975 json_object_string_add(json_scode, "best", ">");
13976 json_object_string_add(json_scode, "multipath", "=");
13977 json_object_string_add(json_scode, "internal", "i");
13978 json_object_string_add(json_scode, "ribFailure", "r");
13979 json_object_string_add(json_scode, "stale", "S");
13980 json_object_string_add(json_scode, "removed", "R");
13981
13982 json_object_string_add(json_ocode, "igp", "i");
13983 json_object_string_add(json_ocode, "egp", "e");
13984 json_object_string_add(json_ocode, "incomplete", "?");
13985 }
13986
13987 if (!peer || !peer->afc[afi][safi]) {
13988 if (use_json) {
13989 json_object_string_add(
13990 json, "warning",
13991 "No such neighbor or address family");
13992 vty_out(vty, "%s\n", json_object_to_json_string(json));
13993 json_object_free(json);
13994 json_object_free(json_ar);
13995 json_object_free(json_scode);
13996 json_object_free(json_ocode);
13997 } else
13998 vty_out(vty, "%% No such neighbor or address family\n");
13999
14000 return CMD_WARNING;
14001 }
14002
14003 if ((type == bgp_show_adj_route_received
14004 || type == bgp_show_adj_route_filtered)
14005 && !CHECK_FLAG(peer->af_flags[afi][safi],
14006 PEER_FLAG_SOFT_RECONFIG)) {
14007 if (use_json) {
14008 json_object_string_add(
14009 json, "warning",
14010 "Inbound soft reconfiguration not enabled");
14011 vty_out(vty, "%s\n", json_object_to_json_string(json));
14012 json_object_free(json);
14013 json_object_free(json_ar);
14014 json_object_free(json_scode);
14015 json_object_free(json_ocode);
14016 } else
14017 vty_out(vty,
14018 "%% Inbound soft reconfiguration not enabled\n");
14019
14020 return CMD_WARNING;
14021 }
14022
14023 bgp = peer->bgp;
14024
14025 /* labeled-unicast routes live in the unicast table */
14026 if (safi == SAFI_LABELED_UNICAST)
14027 table = bgp->rib[afi][SAFI_UNICAST];
14028 else
14029 table = bgp->rib[afi][safi];
14030
14031 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14032 || (safi == SAFI_EVPN)) {
14033
14034 struct bgp_dest *dest;
14035
14036 for (dest = bgp_table_top(table); dest;
14037 dest = bgp_route_next(dest)) {
14038 table = bgp_dest_get_bgp_table_info(dest);
14039 if (!table)
14040 continue;
14041
14042 output_count_per_rd = 0;
14043 filtered_count_per_rd = 0;
14044
14045 if (use_json)
14046 json_routes = json_object_new_object();
14047
14048 const struct prefix_rd *prd;
14049 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14050 dest);
14051
14052 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14053
14054 show_adj_route(vty, peer, table, afi, safi, type,
14055 rmap_name, json, json_routes, json_scode,
14056 json_ocode, show_flags, &header1,
14057 &header2, rd_str, &output_count_per_rd,
14058 &filtered_count_per_rd);
14059
14060 /* Don't include an empty RD in the output! */
14061 if (json_routes && (output_count_per_rd > 0))
14062 json_object_object_add(json_ar, rd_str,
14063 json_routes);
14064
14065 output_count += output_count_per_rd;
14066 filtered_count += filtered_count_per_rd;
14067 }
14068 } else
14069 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14070 json, json_ar, json_scode, json_ocode,
14071 show_flags, &header1, &header2, rd_str,
14072 &output_count, &filtered_count);
14073
14074 if (use_json) {
14075 if (type == bgp_show_adj_route_advertised)
14076 json_object_object_add(json, "advertisedRoutes",
14077 json_ar);
14078 else
14079 json_object_object_add(json, "receivedRoutes", json_ar);
14080 json_object_int_add(json, "totalPrefixCounter", output_count);
14081 json_object_int_add(json, "filteredPrefixCounter",
14082 filtered_count);
14083
14084 /*
14085 * These fields only give up ownership to `json` when `header1`
14086 * is used (set to zero). See code in `show_adj_route` and
14087 * `show_adj_route_header`.
14088 */
14089 if (header1 == 1) {
14090 json_object_free(json_scode);
14091 json_object_free(json_ocode);
14092 }
14093
14094 vty_json(vty, json);
14095 } else if (output_count > 0) {
14096 if (filtered_count > 0)
14097 vty_out(vty,
14098 "\nTotal number of prefixes %ld (%ld filtered)\n",
14099 output_count, filtered_count);
14100 else
14101 vty_out(vty, "\nTotal number of prefixes %ld\n",
14102 output_count);
14103 }
14104
14105 return CMD_SUCCESS;
14106}
14107
14108DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14109 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14110 "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]",
14111 SHOW_STR
14112 IP_STR
14113 BGP_STR
14114 BGP_INSTANCE_HELP_STR
14115 BGP_AFI_HELP_STR
14116 BGP_SAFI_WITH_LABEL_HELP_STR
14117 "Detailed information on TCP and BGP neighbor connections\n"
14118 "Neighbor to display information about\n"
14119 "Neighbor to display information about\n"
14120 "Neighbor on BGP configured interface\n"
14121 "Display the routes selected by best path\n"
14122 JSON_STR
14123 "Increase table width for longer prefixes\n")
14124{
14125 afi_t afi = AFI_IP6;
14126 safi_t safi = SAFI_UNICAST;
14127 char *rmap_name = NULL;
14128 char *peerstr = NULL;
14129 struct bgp *bgp = NULL;
14130 struct peer *peer;
14131 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14132 int idx = 0;
14133 uint16_t show_flags = 0;
14134
14135 if (uj)
14136 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14137
14138 if (wide)
14139 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14140
14141 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14142 &bgp, uj);
14143
14144 if (!idx)
14145 return CMD_WARNING;
14146
14147 argv_find(argv, argc, "neighbors", &idx);
14148 peerstr = argv[++idx]->arg;
14149
14150 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14151 if (!peer)
14152 return CMD_WARNING;
14153
14154 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14155 show_flags);
14156}
14157
14158DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
14159 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14160 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [all$all] neighbors <A.B.C.D|X:X::X:X|WORD> <advertised-routes|received-routes|filtered-routes> [route-map RMAP_NAME$route_map] [json$uj | wide$wide]",
14161 SHOW_STR
14162 IP_STR
14163 BGP_STR
14164 BGP_INSTANCE_HELP_STR
14165 BGP_AFI_HELP_STR
14166 BGP_SAFI_WITH_LABEL_HELP_STR
14167 "Display the entries for all address families\n"
14168 "Detailed information on TCP and BGP neighbor connections\n"
14169 "Neighbor to display information about\n"
14170 "Neighbor to display information about\n"
14171 "Neighbor on BGP configured interface\n"
14172 "Display the routes advertised to a BGP neighbor\n"
14173 "Display the received routes from neighbor\n"
14174 "Display the filtered routes received from neighbor\n"
14175 "Route-map to modify the attributes\n"
14176 "Name of the route map\n"
14177 JSON_STR
14178 "Increase table width for longer prefixes\n")
14179{
14180 afi_t afi = AFI_IP6;
14181 safi_t safi = SAFI_UNICAST;
14182 char *peerstr = NULL;
14183 struct bgp *bgp = NULL;
14184 struct peer *peer;
14185 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14186 int idx = 0;
14187 bool first = true;
14188 uint16_t show_flags = 0;
14189 struct listnode *node;
14190 struct bgp *abgp;
14191
14192 if (uj) {
14193 argc--;
14194 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14195 }
14196
14197 if (all) {
14198 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14199 if (argv_find(argv, argc, "ipv4", &idx))
14200 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14201
14202 if (argv_find(argv, argc, "ipv6", &idx))
14203 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14204 }
14205
14206 if (wide)
14207 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14208
14209 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14210 &bgp, uj);
14211 if (!idx)
14212 return CMD_WARNING;
14213
14214 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14215 argv_find(argv, argc, "neighbors", &idx);
14216 peerstr = argv[++idx]->arg;
14217
14218 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14219 if (!peer)
14220 return CMD_WARNING;
14221
14222 if (argv_find(argv, argc, "advertised-routes", &idx))
14223 type = bgp_show_adj_route_advertised;
14224 else if (argv_find(argv, argc, "received-routes", &idx))
14225 type = bgp_show_adj_route_received;
14226 else if (argv_find(argv, argc, "filtered-routes", &idx))
14227 type = bgp_show_adj_route_filtered;
14228
14229 if (!all)
14230 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14231 show_flags);
14232 if (uj)
14233 vty_out(vty, "{\n");
14234
14235 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14236 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14237 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14238 : AFI_IP6;
14239 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14240 FOREACH_SAFI (safi) {
14241 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14242 continue;
14243
14244 if (uj) {
14245 if (first)
14246 first = false;
14247 else
14248 vty_out(vty, ",\n");
14249 vty_out(vty, "\"%s\":",
14250 get_afi_safi_str(afi, safi,
14251 true));
14252 } else
14253 vty_out(vty,
14254 "\nFor address family: %s\n",
14255 get_afi_safi_str(afi, safi,
14256 false));
14257
14258 peer_adj_routes(vty, peer, afi, safi, type,
14259 route_map, show_flags);
14260 }
14261 }
14262 } else {
14263 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14264 FOREACH_AFI_SAFI (afi, safi) {
14265 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14266 continue;
14267
14268 if (uj) {
14269 if (first)
14270 first = false;
14271 else
14272 vty_out(vty, ",\n");
14273 vty_out(vty, "\"%s\":",
14274 get_afi_safi_str(afi, safi,
14275 true));
14276 } else
14277 vty_out(vty,
14278 "\nFor address family: %s\n",
14279 get_afi_safi_str(afi, safi,
14280 false));
14281
14282 peer_adj_routes(vty, peer, afi, safi, type,
14283 route_map, show_flags);
14284 }
14285 }
14286 }
14287 if (uj)
14288 vty_out(vty, "}\n");
14289
14290 return CMD_SUCCESS;
14291}
14292
14293DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14294 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14295 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14296 SHOW_STR
14297 IP_STR
14298 BGP_STR
14299 BGP_INSTANCE_HELP_STR
14300 BGP_AF_STR
14301 BGP_AF_STR
14302 BGP_AF_MODIFIER_STR
14303 "Detailed information on TCP and BGP neighbor connections\n"
14304 "Neighbor to display information about\n"
14305 "Neighbor to display information about\n"
14306 "Neighbor on BGP configured interface\n"
14307 "Display information received from a BGP neighbor\n"
14308 "Display the prefixlist filter\n"
14309 JSON_STR)
14310{
14311 afi_t afi = AFI_IP6;
14312 safi_t safi = SAFI_UNICAST;
14313 char *peerstr = NULL;
14314 char name[BUFSIZ];
14315 struct peer *peer;
14316 int count;
14317 int idx = 0;
14318 struct bgp *bgp = NULL;
14319 bool uj = use_json(argc, argv);
14320
14321 if (uj)
14322 argc--;
14323
14324 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14325 &bgp, uj);
14326 if (!idx)
14327 return CMD_WARNING;
14328
14329 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14330 argv_find(argv, argc, "neighbors", &idx);
14331 peerstr = argv[++idx]->arg;
14332
14333 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14334 if (!peer)
14335 return CMD_WARNING;
14336
14337 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14338 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14339 if (count) {
14340 if (!uj)
14341 vty_out(vty, "Address Family: %s\n",
14342 get_afi_safi_str(afi, safi, false));
14343 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14344 } else {
14345 if (uj)
14346 vty_out(vty, "{}\n");
14347 else
14348 vty_out(vty, "No functional output\n");
14349 }
14350
14351 return CMD_SUCCESS;
14352}
14353
14354static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14355 afi_t afi, safi_t safi,
14356 enum bgp_show_type type, bool use_json)
14357{
14358 uint16_t show_flags = 0;
14359
14360 if (use_json)
14361 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14362
14363 if (!peer || !peer->afc[afi][safi]) {
14364 if (use_json) {
14365 json_object *json_no = NULL;
14366 json_no = json_object_new_object();
14367 json_object_string_add(
14368 json_no, "warning",
14369 "No such neighbor or address family");
14370 vty_out(vty, "%s\n",
14371 json_object_to_json_string(json_no));
14372 json_object_free(json_no);
14373 } else
14374 vty_out(vty, "%% No such neighbor or address family\n");
14375 return CMD_WARNING;
14376 }
14377
14378 /* labeled-unicast routes live in the unicast table */
14379 if (safi == SAFI_LABELED_UNICAST)
14380 safi = SAFI_UNICAST;
14381
14382 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14383 RPKI_NOT_BEING_USED);
14384}
14385
14386DEFUN (show_ip_bgp_flowspec_routes_detailed,
14387 show_ip_bgp_flowspec_routes_detailed_cmd,
14388 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14389 SHOW_STR
14390 IP_STR
14391 BGP_STR
14392 BGP_INSTANCE_HELP_STR
14393 BGP_AFI_HELP_STR
14394 "SAFI Flowspec\n"
14395 "Detailed information on flowspec entries\n"
14396 JSON_STR)
14397{
14398 afi_t afi = AFI_IP6;
14399 safi_t safi = SAFI_UNICAST;
14400 struct bgp *bgp = NULL;
14401 int idx = 0;
14402 bool uj = use_json(argc, argv);
14403 uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
14404
14405 if (uj) {
14406 argc--;
14407 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14408 }
14409
14410 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14411 &bgp, uj);
14412 if (!idx)
14413 return CMD_WARNING;
14414
14415 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14416 show_flags, RPKI_NOT_BEING_USED);
14417}
14418
14419DEFUN (show_ip_bgp_neighbor_routes,
14420 show_ip_bgp_neighbor_routes_cmd,
14421 "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]",
14422 SHOW_STR
14423 IP_STR
14424 BGP_STR
14425 BGP_INSTANCE_HELP_STR
14426 BGP_AFI_HELP_STR
14427 BGP_SAFI_WITH_LABEL_HELP_STR
14428 "Detailed information on TCP and BGP neighbor connections\n"
14429 "Neighbor to display information about\n"
14430 "Neighbor to display information about\n"
14431 "Neighbor on BGP configured interface\n"
14432 "Display flap statistics of the routes learned from neighbor\n"
14433 "Display the dampened routes received from neighbor\n"
14434 "Display routes learned from neighbor\n"
14435 JSON_STR)
14436{
14437 char *peerstr = NULL;
14438 struct bgp *bgp = NULL;
14439 afi_t afi = AFI_IP6;
14440 safi_t safi = SAFI_UNICAST;
14441 struct peer *peer;
14442 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14443 int idx = 0;
14444 bool uj = use_json(argc, argv);
14445
14446 if (uj)
14447 argc--;
14448
14449 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14450 &bgp, uj);
14451 if (!idx)
14452 return CMD_WARNING;
14453
14454 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14455 argv_find(argv, argc, "neighbors", &idx);
14456 peerstr = argv[++idx]->arg;
14457
14458 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14459 if (!peer)
14460 return CMD_WARNING;
14461
14462 if (argv_find(argv, argc, "flap-statistics", &idx))
14463 sh_type = bgp_show_type_flap_neighbor;
14464 else if (argv_find(argv, argc, "dampened-routes", &idx))
14465 sh_type = bgp_show_type_damp_neighbor;
14466 else if (argv_find(argv, argc, "routes", &idx))
14467 sh_type = bgp_show_type_neighbor;
14468
14469 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14470}
14471
14472struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14473
14474struct bgp_distance {
14475 /* Distance value for the IP source prefix. */
14476 uint8_t distance;
14477
14478 /* Name of the access-list to be matched. */
14479 char *access_list;
14480};
14481
14482DEFUN (show_bgp_afi_vpn_rd_route,
14483 show_bgp_afi_vpn_rd_route_cmd,
14484 "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]",
14485 SHOW_STR
14486 BGP_STR
14487 BGP_AFI_HELP_STR
14488 BGP_AF_MODIFIER_STR
14489 "Display information for a route distinguisher\n"
14490 "Route Distinguisher\n"
14491 "All Route Distinguishers\n"
14492 "Network in the BGP routing table to display\n"
14493 "Network in the BGP routing table to display\n"
14494 JSON_STR)
14495{
14496 int ret;
14497 struct prefix_rd prd;
14498 afi_t afi = AFI_MAX;
14499 int idx = 0;
14500
14501 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14502 vty_out(vty, "%% Malformed Address Family\n");
14503 return CMD_WARNING;
14504 }
14505
14506 if (!strcmp(argv[5]->arg, "all"))
14507 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14508 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14509 RPKI_NOT_BEING_USED,
14510 use_json(argc, argv));
14511
14512 ret = str2prefix_rd(argv[5]->arg, &prd);
14513 if (!ret) {
14514 vty_out(vty, "%% Malformed Route Distinguisher\n");
14515 return CMD_WARNING;
14516 }
14517
14518 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14519 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14520 use_json(argc, argv));
14521}
14522
14523static struct bgp_distance *bgp_distance_new(void)
14524{
14525 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14526}
14527
14528static void bgp_distance_free(struct bgp_distance *bdistance)
14529{
14530 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14531}
14532
14533static int bgp_distance_set(struct vty *vty, const char *distance_str,
14534 const char *ip_str, const char *access_list_str)
14535{
14536 int ret;
14537 afi_t afi;
14538 safi_t safi;
14539 struct prefix p;
14540 uint8_t distance;
14541 struct bgp_dest *dest;
14542 struct bgp_distance *bdistance;
14543
14544 afi = bgp_node_afi(vty);
14545 safi = bgp_node_safi(vty);
14546
14547 ret = str2prefix(ip_str, &p);
14548 if (ret == 0) {
14549 vty_out(vty, "Malformed prefix\n");
14550 return CMD_WARNING_CONFIG_FAILED;
14551 }
14552
14553 distance = atoi(distance_str);
14554
14555 /* Get BGP distance node. */
14556 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14557 bdistance = bgp_dest_get_bgp_distance_info(dest);
14558 if (bdistance)
14559 bgp_dest_unlock_node(dest);
14560 else {
14561 bdistance = bgp_distance_new();
14562 bgp_dest_set_bgp_distance_info(dest, bdistance);
14563 }
14564
14565 /* Set distance value. */
14566 bdistance->distance = distance;
14567
14568 /* Reset access-list configuration. */
14569 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14570 if (access_list_str)
14571 bdistance->access_list =
14572 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14573
14574 return CMD_SUCCESS;
14575}
14576
14577static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14578 const char *ip_str, const char *access_list_str)
14579{
14580 int ret;
14581 afi_t afi;
14582 safi_t safi;
14583 struct prefix p;
14584 int distance;
14585 struct bgp_dest *dest;
14586 struct bgp_distance *bdistance;
14587
14588 afi = bgp_node_afi(vty);
14589 safi = bgp_node_safi(vty);
14590
14591 ret = str2prefix(ip_str, &p);
14592 if (ret == 0) {
14593 vty_out(vty, "Malformed prefix\n");
14594 return CMD_WARNING_CONFIG_FAILED;
14595 }
14596
14597 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14598 if (!dest) {
14599 vty_out(vty, "Can't find specified prefix\n");
14600 return CMD_WARNING_CONFIG_FAILED;
14601 }
14602
14603 bdistance = bgp_dest_get_bgp_distance_info(dest);
14604 distance = atoi(distance_str);
14605
14606 if (bdistance->distance != distance) {
14607 vty_out(vty, "Distance does not match configured\n");
14608 bgp_dest_unlock_node(dest);
14609 return CMD_WARNING_CONFIG_FAILED;
14610 }
14611
14612 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14613 bgp_distance_free(bdistance);
14614
14615 bgp_dest_set_bgp_path_info(dest, NULL);
14616 bgp_dest_unlock_node(dest);
14617 bgp_dest_unlock_node(dest);
14618
14619 return CMD_SUCCESS;
14620}
14621
14622/* Apply BGP information to distance method. */
14623uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14624 afi_t afi, safi_t safi, struct bgp *bgp)
14625{
14626 struct bgp_dest *dest;
14627 struct prefix q = {0};
14628 struct peer *peer;
14629 struct bgp_distance *bdistance;
14630 struct access_list *alist;
14631 struct bgp_static *bgp_static;
14632
14633 if (!bgp)
14634 return 0;
14635
14636 peer = pinfo->peer;
14637
14638 if (pinfo->attr->distance)
14639 return pinfo->attr->distance;
14640
14641 /* Check source address.
14642 * Note: for aggregate route, peer can have unspec af type.
14643 */
14644 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14645 && !sockunion2hostprefix(&peer->su, &q))
14646 return 0;
14647
14648 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14649 if (dest) {
14650 bdistance = bgp_dest_get_bgp_distance_info(dest);
14651 bgp_dest_unlock_node(dest);
14652
14653 if (bdistance->access_list) {
14654 alist = access_list_lookup(afi, bdistance->access_list);
14655 if (alist
14656 && access_list_apply(alist, p) == FILTER_PERMIT)
14657 return bdistance->distance;
14658 } else
14659 return bdistance->distance;
14660 }
14661
14662 /* Backdoor check. */
14663 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14664 if (dest) {
14665 bgp_static = bgp_dest_get_bgp_static_info(dest);
14666 bgp_dest_unlock_node(dest);
14667
14668 if (bgp_static->backdoor) {
14669 if (bgp->distance_local[afi][safi])
14670 return bgp->distance_local[afi][safi];
14671 else
14672 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14673 }
14674 }
14675
14676 if (peer->sort == BGP_PEER_EBGP) {
14677 if (bgp->distance_ebgp[afi][safi])
14678 return bgp->distance_ebgp[afi][safi];
14679 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14680 } else if (peer->sort == BGP_PEER_IBGP) {
14681 if (bgp->distance_ibgp[afi][safi])
14682 return bgp->distance_ibgp[afi][safi];
14683 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14684 } else {
14685 if (bgp->distance_local[afi][safi])
14686 return bgp->distance_local[afi][safi];
14687 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14688 }
14689}
14690
14691/* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14692 * we should tell ZEBRA update the routes for a specific
14693 * AFI/SAFI to reflect changes in RIB.
14694 */
14695static void bgp_announce_routes_distance_update(struct bgp *bgp,
14696 afi_t update_afi,
14697 safi_t update_safi)
14698{
14699 afi_t afi;
14700 safi_t safi;
14701
14702 FOREACH_AFI_SAFI (afi, safi) {
14703 if (!bgp_fibupd_safi(safi))
14704 continue;
14705
14706 if (afi != update_afi && safi != update_safi)
14707 continue;
14708
14709 if (BGP_DEBUG(zebra, ZEBRA))
14710 zlog_debug(
14711 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14712 __func__, afi, safi);
14713 bgp_zebra_announce_table(bgp, afi, safi);
14714 }
14715}
14716
14717DEFUN (bgp_distance,
14718 bgp_distance_cmd,
14719 "distance bgp (1-255) (1-255) (1-255)",
14720 "Define an administrative distance\n"
14721 "BGP distance\n"
14722 "Distance for routes external to the AS\n"
14723 "Distance for routes internal to the AS\n"
14724 "Distance for local routes\n")
14725{
14726 VTY_DECLVAR_CONTEXT(bgp, bgp);
14727 int idx_number = 2;
14728 int idx_number_2 = 3;
14729 int idx_number_3 = 4;
14730 int distance_ebgp = atoi(argv[idx_number]->arg);
14731 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14732 int distance_local = atoi(argv[idx_number_3]->arg);
14733 afi_t afi;
14734 safi_t safi;
14735
14736 afi = bgp_node_afi(vty);
14737 safi = bgp_node_safi(vty);
14738
14739 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14740 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14741 || bgp->distance_local[afi][safi] != distance_local) {
14742 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14743 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14744 bgp->distance_local[afi][safi] = distance_local;
14745 bgp_announce_routes_distance_update(bgp, afi, safi);
14746 }
14747 return CMD_SUCCESS;
14748}
14749
14750DEFUN (no_bgp_distance,
14751 no_bgp_distance_cmd,
14752 "no distance bgp [(1-255) (1-255) (1-255)]",
14753 NO_STR
14754 "Define an administrative distance\n"
14755 "BGP distance\n"
14756 "Distance for routes external to the AS\n"
14757 "Distance for routes internal to the AS\n"
14758 "Distance for local routes\n")
14759{
14760 VTY_DECLVAR_CONTEXT(bgp, bgp);
14761 afi_t afi;
14762 safi_t safi;
14763
14764 afi = bgp_node_afi(vty);
14765 safi = bgp_node_safi(vty);
14766
14767 if (bgp->distance_ebgp[afi][safi] != 0
14768 || bgp->distance_ibgp[afi][safi] != 0
14769 || bgp->distance_local[afi][safi] != 0) {
14770 bgp->distance_ebgp[afi][safi] = 0;
14771 bgp->distance_ibgp[afi][safi] = 0;
14772 bgp->distance_local[afi][safi] = 0;
14773 bgp_announce_routes_distance_update(bgp, afi, safi);
14774 }
14775 return CMD_SUCCESS;
14776}
14777
14778
14779DEFUN (bgp_distance_source,
14780 bgp_distance_source_cmd,
14781 "distance (1-255) A.B.C.D/M",
14782 "Define an administrative distance\n"
14783 "Administrative distance\n"
14784 "IP source prefix\n")
14785{
14786 int idx_number = 1;
14787 int idx_ipv4_prefixlen = 2;
14788 bgp_distance_set(vty, argv[idx_number]->arg,
14789 argv[idx_ipv4_prefixlen]->arg, NULL);
14790 return CMD_SUCCESS;
14791}
14792
14793DEFUN (no_bgp_distance_source,
14794 no_bgp_distance_source_cmd,
14795 "no distance (1-255) A.B.C.D/M",
14796 NO_STR
14797 "Define an administrative distance\n"
14798 "Administrative distance\n"
14799 "IP source prefix\n")
14800{
14801 int idx_number = 2;
14802 int idx_ipv4_prefixlen = 3;
14803 bgp_distance_unset(vty, argv[idx_number]->arg,
14804 argv[idx_ipv4_prefixlen]->arg, NULL);
14805 return CMD_SUCCESS;
14806}
14807
14808DEFUN (bgp_distance_source_access_list,
14809 bgp_distance_source_access_list_cmd,
14810 "distance (1-255) A.B.C.D/M WORD",
14811 "Define an administrative distance\n"
14812 "Administrative distance\n"
14813 "IP source prefix\n"
14814 "Access list name\n")
14815{
14816 int idx_number = 1;
14817 int idx_ipv4_prefixlen = 2;
14818 int idx_word = 3;
14819 bgp_distance_set(vty, argv[idx_number]->arg,
14820 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14821 return CMD_SUCCESS;
14822}
14823
14824DEFUN (no_bgp_distance_source_access_list,
14825 no_bgp_distance_source_access_list_cmd,
14826 "no distance (1-255) A.B.C.D/M WORD",
14827 NO_STR
14828 "Define an administrative distance\n"
14829 "Administrative distance\n"
14830 "IP source prefix\n"
14831 "Access list name\n")
14832{
14833 int idx_number = 2;
14834 int idx_ipv4_prefixlen = 3;
14835 int idx_word = 4;
14836 bgp_distance_unset(vty, argv[idx_number]->arg,
14837 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14838 return CMD_SUCCESS;
14839}
14840
14841DEFUN (ipv6_bgp_distance_source,
14842 ipv6_bgp_distance_source_cmd,
14843 "distance (1-255) X:X::X:X/M",
14844 "Define an administrative distance\n"
14845 "Administrative distance\n"
14846 "IP source prefix\n")
14847{
14848 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
14849 return CMD_SUCCESS;
14850}
14851
14852DEFUN (no_ipv6_bgp_distance_source,
14853 no_ipv6_bgp_distance_source_cmd,
14854 "no distance (1-255) X:X::X:X/M",
14855 NO_STR
14856 "Define an administrative distance\n"
14857 "Administrative distance\n"
14858 "IP source prefix\n")
14859{
14860 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
14861 return CMD_SUCCESS;
14862}
14863
14864DEFUN (ipv6_bgp_distance_source_access_list,
14865 ipv6_bgp_distance_source_access_list_cmd,
14866 "distance (1-255) X:X::X:X/M WORD",
14867 "Define an administrative distance\n"
14868 "Administrative distance\n"
14869 "IP source prefix\n"
14870 "Access list name\n")
14871{
14872 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
14873 return CMD_SUCCESS;
14874}
14875
14876DEFUN (no_ipv6_bgp_distance_source_access_list,
14877 no_ipv6_bgp_distance_source_access_list_cmd,
14878 "no distance (1-255) X:X::X:X/M WORD",
14879 NO_STR
14880 "Define an administrative distance\n"
14881 "Administrative distance\n"
14882 "IP source prefix\n"
14883 "Access list name\n")
14884{
14885 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
14886 return CMD_SUCCESS;
14887}
14888
14889DEFUN (bgp_damp_set,
14890 bgp_damp_set_cmd,
14891 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14892 "BGP Specific commands\n"
14893 "Enable route-flap dampening\n"
14894 "Half-life time for the penalty\n"
14895 "Value to start reusing a route\n"
14896 "Value to start suppressing a route\n"
14897 "Maximum duration to suppress a stable route\n")
14898{
14899 VTY_DECLVAR_CONTEXT(bgp, bgp);
14900 int idx_half_life = 2;
14901 int idx_reuse = 3;
14902 int idx_suppress = 4;
14903 int idx_max_suppress = 5;
14904 int half = DEFAULT_HALF_LIFE * 60;
14905 int reuse = DEFAULT_REUSE;
14906 int suppress = DEFAULT_SUPPRESS;
14907 int max = 4 * half;
14908
14909 if (argc == 6) {
14910 half = atoi(argv[idx_half_life]->arg) * 60;
14911 reuse = atoi(argv[idx_reuse]->arg);
14912 suppress = atoi(argv[idx_suppress]->arg);
14913 max = atoi(argv[idx_max_suppress]->arg) * 60;
14914 } else if (argc == 3) {
14915 half = atoi(argv[idx_half_life]->arg) * 60;
14916 max = 4 * half;
14917 }
14918
14919 /*
14920 * These can't be 0 but our SA doesn't understand the
14921 * way our cli is constructed
14922 */
14923 assert(reuse);
14924 assert(half);
14925 if (suppress < reuse) {
14926 vty_out(vty,
14927 "Suppress value cannot be less than reuse value \n");
14928 return 0;
14929 }
14930
14931 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
14932 reuse, suppress, max);
14933}
14934
14935DEFUN (bgp_damp_unset,
14936 bgp_damp_unset_cmd,
14937 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14938 NO_STR
14939 "BGP Specific commands\n"
14940 "Enable route-flap dampening\n"
14941 "Half-life time for the penalty\n"
14942 "Value to start reusing a route\n"
14943 "Value to start suppressing a route\n"
14944 "Maximum duration to suppress a stable route\n")
14945{
14946 VTY_DECLVAR_CONTEXT(bgp, bgp);
14947 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
14948}
14949
14950/* Display specified route of BGP table. */
14951static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14952 const char *ip_str, afi_t afi, safi_t safi,
14953 struct prefix_rd *prd, int prefix_check)
14954{
14955 int ret;
14956 struct prefix match;
14957 struct bgp_dest *dest;
14958 struct bgp_dest *rm;
14959 struct bgp_path_info *pi;
14960 struct bgp_path_info *pi_temp;
14961 struct bgp *bgp;
14962 struct bgp_table *table;
14963
14964 /* BGP structure lookup. */
14965 if (view_name) {
14966 bgp = bgp_lookup_by_name(view_name);
14967 if (bgp == NULL) {
14968 vty_out(vty, "%% Can't find BGP instance %s\n",
14969 view_name);
14970 return CMD_WARNING;
14971 }
14972 } else {
14973 bgp = bgp_get_default();
14974 if (bgp == NULL) {
14975 vty_out(vty, "%% No BGP process is configured\n");
14976 return CMD_WARNING;
14977 }
14978 }
14979
14980 /* Check IP address argument. */
14981 ret = str2prefix(ip_str, &match);
14982 if (!ret) {
14983 vty_out(vty, "%% address is malformed\n");
14984 return CMD_WARNING;
14985 }
14986
14987 match.family = afi2family(afi);
14988
14989 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14990 || (safi == SAFI_EVPN)) {
14991 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14992 dest = bgp_route_next(dest)) {
14993 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14994
14995 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14996 continue;
14997 table = bgp_dest_get_bgp_table_info(dest);
14998 if (!table)
14999 continue;
15000 rm = bgp_node_match(table, &match);
15001 if (rm == NULL)
15002 continue;
15003
15004 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15005
15006 if (!prefix_check
15007 || rm_p->prefixlen == match.prefixlen) {
15008 pi = bgp_dest_get_bgp_path_info(rm);
15009 while (pi) {
15010 if (pi->extra && pi->extra->damp_info) {
15011 pi_temp = pi->next;
15012 bgp_damp_info_free(
15013 pi->extra->damp_info,
15014 1, afi, safi);
15015 pi = pi_temp;
15016 } else
15017 pi = pi->next;
15018 }
15019 }
15020
15021 bgp_dest_unlock_node(rm);
15022 }
15023 } else {
15024 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15025 if (dest != NULL) {
15026 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15027
15028 if (!prefix_check
15029 || dest_p->prefixlen == match.prefixlen) {
15030 pi = bgp_dest_get_bgp_path_info(dest);
15031 while (pi) {
15032 if (pi->extra && pi->extra->damp_info) {
15033 pi_temp = pi->next;
15034 bgp_damp_info_free(
15035 pi->extra->damp_info,
15036 1, afi, safi);
15037 pi = pi_temp;
15038 } else
15039 pi = pi->next;
15040 }
15041 }
15042
15043 bgp_dest_unlock_node(dest);
15044 }
15045 }
15046
15047 return CMD_SUCCESS;
15048}
15049
15050DEFUN (clear_ip_bgp_dampening,
15051 clear_ip_bgp_dampening_cmd,
15052 "clear ip bgp dampening",
15053 CLEAR_STR
15054 IP_STR
15055 BGP_STR
15056 "Clear route flap dampening information\n")
15057{
15058 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15059 return CMD_SUCCESS;
15060}
15061
15062DEFUN (clear_ip_bgp_dampening_prefix,
15063 clear_ip_bgp_dampening_prefix_cmd,
15064 "clear ip bgp dampening A.B.C.D/M",
15065 CLEAR_STR
15066 IP_STR
15067 BGP_STR
15068 "Clear route flap dampening information\n"
15069 "IPv4 prefix\n")
15070{
15071 int idx_ipv4_prefixlen = 4;
15072 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15073 AFI_IP, SAFI_UNICAST, NULL, 1);
15074}
15075
15076DEFUN (clear_ip_bgp_dampening_address,
15077 clear_ip_bgp_dampening_address_cmd,
15078 "clear ip bgp dampening A.B.C.D",
15079 CLEAR_STR
15080 IP_STR
15081 BGP_STR
15082 "Clear route flap dampening information\n"
15083 "Network to clear damping information\n")
15084{
15085 int idx_ipv4 = 4;
15086 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15087 SAFI_UNICAST, NULL, 0);
15088}
15089
15090DEFUN (clear_ip_bgp_dampening_address_mask,
15091 clear_ip_bgp_dampening_address_mask_cmd,
15092 "clear ip bgp dampening A.B.C.D A.B.C.D",
15093 CLEAR_STR
15094 IP_STR
15095 BGP_STR
15096 "Clear route flap dampening information\n"
15097 "Network to clear damping information\n"
15098 "Network mask\n")
15099{
15100 int idx_ipv4 = 4;
15101 int idx_ipv4_2 = 5;
15102 int ret;
15103 char prefix_str[BUFSIZ];
15104
15105 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15106 prefix_str, sizeof(prefix_str));
15107 if (!ret) {
15108 vty_out(vty, "%% Inconsistent address and mask\n");
15109 return CMD_WARNING;
15110 }
15111
15112 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15113 NULL, 0);
15114}
15115
15116static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15117{
15118 struct vty *vty = arg;
15119 struct peer *peer = bucket->data;
15120
15121 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15122}
15123
15124DEFUN (show_bgp_listeners,
15125 show_bgp_listeners_cmd,
15126 "show bgp listeners",
15127 SHOW_STR
15128 BGP_STR
15129 "Display Listen Sockets and who created them\n")
15130{
15131 bgp_dump_listener_info(vty);
15132
15133 return CMD_SUCCESS;
15134}
15135
15136DEFUN (show_bgp_peerhash,
15137 show_bgp_peerhash_cmd,
15138 "show bgp peerhash",
15139 SHOW_STR
15140 BGP_STR
15141 "Display information about the BGP peerhash\n")
15142{
15143 struct list *instances = bm->bgp;
15144 struct listnode *node;
15145 struct bgp *bgp;
15146
15147 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15148 vty_out(vty, "BGP: %s\n", bgp->name);
15149 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15150 vty);
15151 }
15152
15153 return CMD_SUCCESS;
15154}
15155
15156/* also used for encap safi */
15157static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15158 afi_t afi, safi_t safi)
15159{
15160 struct bgp_dest *pdest;
15161 struct bgp_dest *dest;
15162 struct bgp_table *table;
15163 const struct prefix *p;
15164 const struct prefix_rd *prd;
15165 struct bgp_static *bgp_static;
15166 mpls_label_t label;
15167 char rdbuf[RD_ADDRSTRLEN];
15168
15169 /* Network configuration. */
15170 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15171 pdest = bgp_route_next(pdest)) {
15172 table = bgp_dest_get_bgp_table_info(pdest);
15173 if (!table)
15174 continue;
15175
15176 for (dest = bgp_table_top(table); dest;
15177 dest = bgp_route_next(dest)) {
15178 bgp_static = bgp_dest_get_bgp_static_info(dest);
15179 if (bgp_static == NULL)
15180 continue;
15181
15182 p = bgp_dest_get_prefix(dest);
15183 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15184 pdest);
15185
15186 /* "network" configuration display. */
15187 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
15188 label = decode_label(&bgp_static->label);
15189
15190 vty_out(vty, " network %pFX rd %s", p, rdbuf);
15191 if (safi == SAFI_MPLS_VPN)
15192 vty_out(vty, " label %u", label);
15193
15194 if (bgp_static->rmap.name)
15195 vty_out(vty, " route-map %s",
15196 bgp_static->rmap.name);
15197
15198 if (bgp_static->backdoor)
15199 vty_out(vty, " backdoor");
15200
15201 vty_out(vty, "\n");
15202 }
15203 }
15204}
15205
15206static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15207 afi_t afi, safi_t safi)
15208{
15209 struct bgp_dest *pdest;
15210 struct bgp_dest *dest;
15211 struct bgp_table *table;
15212 const struct prefix *p;
15213 const struct prefix_rd *prd;
15214 struct bgp_static *bgp_static;
15215 char buf[PREFIX_STRLEN * 2];
15216 char buf2[SU_ADDRSTRLEN];
15217 char rdbuf[RD_ADDRSTRLEN];
15218 char esi_buf[ESI_STR_LEN];
15219
15220 /* Network configuration. */
15221 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15222 pdest = bgp_route_next(pdest)) {
15223 table = bgp_dest_get_bgp_table_info(pdest);
15224 if (!table)
15225 continue;
15226
15227 for (dest = bgp_table_top(table); dest;
15228 dest = bgp_route_next(dest)) {
15229 bgp_static = bgp_dest_get_bgp_static_info(dest);
15230 if (bgp_static == NULL)
15231 continue;
15232
15233 char *macrouter = NULL;
15234
15235 if (bgp_static->router_mac)
15236 macrouter = prefix_mac2str(
15237 bgp_static->router_mac, NULL, 0);
15238 if (bgp_static->eth_s_id)
15239 esi_to_str(bgp_static->eth_s_id,
15240 esi_buf, sizeof(esi_buf));
15241 p = bgp_dest_get_prefix(dest);
15242 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15243
15244 /* "network" configuration display. */
15245 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
15246 if (p->u.prefix_evpn.route_type == 5) {
15247 char local_buf[PREFIX_STRLEN];
15248 uint8_t family = is_evpn_prefix_ipaddr_v4((
15249 struct prefix_evpn *)p)
15250 ? AF_INET
15251 : AF_INET6;
15252 inet_ntop(family,
15253 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15254 local_buf, PREFIX_STRLEN);
15255 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15256 p->u.prefix_evpn.prefix_addr
15257 .ip_prefix_length);
15258 } else {
15259 prefix2str(p, buf, sizeof(buf));
15260 }
15261
15262 if (bgp_static->gatewayIp.family == AF_INET
15263 || bgp_static->gatewayIp.family == AF_INET6)
15264 inet_ntop(bgp_static->gatewayIp.family,
15265 &bgp_static->gatewayIp.u.prefix, buf2,
15266 sizeof(buf2));
15267 vty_out(vty,
15268 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15269 buf, rdbuf,
15270 p->u.prefix_evpn.prefix_addr.eth_tag,
15271 decode_label(&bgp_static->label), esi_buf, buf2,
15272 macrouter);
15273
15274 XFREE(MTYPE_TMP, macrouter);
15275 }
15276 }
15277}
15278
15279/* Configuration of static route announcement and aggregate
15280 information. */
15281void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15282 safi_t safi)
15283{
15284 struct bgp_dest *dest;
15285 const struct prefix *p;
15286 struct bgp_static *bgp_static;
15287 struct bgp_aggregate *bgp_aggregate;
15288
15289 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15290 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15291 return;
15292 }
15293
15294 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15295 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15296 return;
15297 }
15298
15299 /* Network configuration. */
15300 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15301 dest = bgp_route_next(dest)) {
15302 bgp_static = bgp_dest_get_bgp_static_info(dest);
15303 if (bgp_static == NULL)
15304 continue;
15305
15306 p = bgp_dest_get_prefix(dest);
15307
15308 vty_out(vty, " network %pFX", p);
15309
15310 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15311 vty_out(vty, " label-index %u",
15312 bgp_static->label_index);
15313
15314 if (bgp_static->rmap.name)
15315 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15316
15317 if (bgp_static->backdoor)
15318 vty_out(vty, " backdoor");
15319
15320 vty_out(vty, "\n");
15321 }
15322
15323 /* Aggregate-address configuration. */
15324 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15325 dest = bgp_route_next(dest)) {
15326 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15327 if (bgp_aggregate == NULL)
15328 continue;
15329
15330 p = bgp_dest_get_prefix(dest);
15331
15332 vty_out(vty, " aggregate-address %pFX", p);
15333
15334 if (bgp_aggregate->as_set)
15335 vty_out(vty, " as-set");
15336
15337 if (bgp_aggregate->summary_only)
15338 vty_out(vty, " summary-only");
15339
15340 if (bgp_aggregate->rmap.name)
15341 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15342
15343 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15344 vty_out(vty, " origin %s",
15345 bgp_origin2str(bgp_aggregate->origin));
15346
15347 if (bgp_aggregate->match_med)
15348 vty_out(vty, " matching-MED-only");
15349
15350 if (bgp_aggregate->suppress_map_name)
15351 vty_out(vty, " suppress-map %s",
15352 bgp_aggregate->suppress_map_name);
15353
15354 vty_out(vty, "\n");
15355 }
15356}
15357
15358void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15359 safi_t safi)
15360{
15361 struct bgp_dest *dest;
15362 struct bgp_distance *bdistance;
15363
15364 /* Distance configuration. */
15365 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15366 && bgp->distance_local[afi][safi]
15367 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15368 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15369 || bgp->distance_local[afi][safi]
15370 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15371 vty_out(vty, " distance bgp %d %d %d\n",
15372 bgp->distance_ebgp[afi][safi],
15373 bgp->distance_ibgp[afi][safi],
15374 bgp->distance_local[afi][safi]);
15375 }
15376
15377 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15378 dest = bgp_route_next(dest)) {
15379 bdistance = bgp_dest_get_bgp_distance_info(dest);
15380 if (bdistance != NULL)
15381 vty_out(vty, " distance %d %pBD %s\n",
15382 bdistance->distance, dest,
15383 bdistance->access_list ? bdistance->access_list
15384 : "");
15385 }
15386}
15387
15388/* Allocate routing table structure and install commands. */
15389void bgp_route_init(void)
15390{
15391 afi_t afi;
15392 safi_t safi;
15393
15394 /* Init BGP distance table. */
15395 FOREACH_AFI_SAFI (afi, safi)
15396 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15397
15398 /* IPv4 BGP commands. */
15399 install_element(BGP_NODE, &bgp_table_map_cmd);
15400 install_element(BGP_NODE, &bgp_network_cmd);
15401 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15402
15403 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15404
15405 /* IPv4 unicast configuration. */
15406 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15407 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15408 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15409
15410 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15411
15412 /* IPv4 multicast configuration. */
15413 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15414 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15415 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15416 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15417
15418 /* IPv4 labeled-unicast configuration. */
15419 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15420 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15421
15422 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15423 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15424 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15425 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15426 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15427 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15428 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15429 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15430
15431 install_element(VIEW_NODE,
15432 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15433 install_element(VIEW_NODE,
15434 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15435 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15436 install_element(VIEW_NODE,
15437 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15438#ifdef KEEP_OLD_VPN_COMMANDS
15439 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15440#endif /* KEEP_OLD_VPN_COMMANDS */
15441 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15442 install_element(VIEW_NODE,
15443 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15444
15445 /* BGP dampening clear commands */
15446 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15447 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15448
15449 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15450 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15451
15452 /* prefix count */
15453 install_element(ENABLE_NODE,
15454 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15455#ifdef KEEP_OLD_VPN_COMMANDS
15456 install_element(ENABLE_NODE,
15457 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15458#endif /* KEEP_OLD_VPN_COMMANDS */
15459
15460 /* New config IPv6 BGP commands. */
15461 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15462 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15463 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15464
15465 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15466
15467 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15468
15469 /* IPv6 labeled unicast address family. */
15470 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15471 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15472
15473 install_element(BGP_NODE, &bgp_distance_cmd);
15474 install_element(BGP_NODE, &no_bgp_distance_cmd);
15475 install_element(BGP_NODE, &bgp_distance_source_cmd);
15476 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15477 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15478 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15479 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15480 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15481 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15482 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15483 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15484 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15485 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15486 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15487 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15488 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15489 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15490 install_element(BGP_IPV4M_NODE,
15491 &no_bgp_distance_source_access_list_cmd);
15492 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15493 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15494 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15495 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15496 install_element(BGP_IPV6_NODE,
15497 &ipv6_bgp_distance_source_access_list_cmd);
15498 install_element(BGP_IPV6_NODE,
15499 &no_ipv6_bgp_distance_source_access_list_cmd);
15500 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15501 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15502 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15503 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15504 install_element(BGP_IPV6M_NODE,
15505 &ipv6_bgp_distance_source_access_list_cmd);
15506 install_element(BGP_IPV6M_NODE,
15507 &no_ipv6_bgp_distance_source_access_list_cmd);
15508
15509 /* BGP dampening */
15510 install_element(BGP_NODE, &bgp_damp_set_cmd);
15511 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15512 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15513 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15514 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15515 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15516 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15517 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15518 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15519 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15520 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15521 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15522 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15523 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15524
15525 /* Large Communities */
15526 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15527 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15528
15529 /* show bgp ipv4 flowspec detailed */
15530 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15531
15532 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15533 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15534}
15535
15536void bgp_route_finish(void)
15537{
15538 afi_t afi;
15539 safi_t safi;
15540
15541 FOREACH_AFI_SAFI (afi, safi) {
15542 bgp_table_unlock(bgp_distance_table[afi][safi]);
15543 bgp_distance_table[afi][safi] = NULL;
15544 }
15545}