]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Don't forget bgp_dest_unlock_node before return
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23 #include <math.h>
24
25 #include "printfrr.h"
26 #include "frrstr.h"
27 #include "prefix.h"
28 #include "linklist.h"
29 #include "memory.h"
30 #include "command.h"
31 #include "stream.h"
32 #include "filter.h"
33 #include "log.h"
34 #include "routemap.h"
35 #include "buffer.h"
36 #include "sockunion.h"
37 #include "plist.h"
38 #include "thread.h"
39 #include "workqueue.h"
40 #include "queue.h"
41 #include "memory.h"
42 #include "srv6.h"
43 #include "lib/json.h"
44 #include "lib_errors.h"
45 #include "zclient.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_route.h"
49 #include "bgpd/bgp_attr.h"
50 #include "bgpd/bgp_debug.h"
51 #include "bgpd/bgp_errors.h"
52 #include "bgpd/bgp_aspath.h"
53 #include "bgpd/bgp_regex.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_community_alias.h"
56 #include "bgpd/bgp_ecommunity.h"
57 #include "bgpd/bgp_lcommunity.h"
58 #include "bgpd/bgp_clist.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_filter.h"
61 #include "bgpd/bgp_fsm.h"
62 #include "bgpd/bgp_mplsvpn.h"
63 #include "bgpd/bgp_nexthop.h"
64 #include "bgpd/bgp_damp.h"
65 #include "bgpd/bgp_advertise.h"
66 #include "bgpd/bgp_zebra.h"
67 #include "bgpd/bgp_vty.h"
68 #include "bgpd/bgp_mpath.h"
69 #include "bgpd/bgp_nht.h"
70 #include "bgpd/bgp_updgrp.h"
71 #include "bgpd/bgp_label.h"
72 #include "bgpd/bgp_addpath.h"
73 #include "bgpd/bgp_mac.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_trace.h"
76 #include "bgpd/bgp_rpki.h"
77
78 #ifdef ENABLE_BGP_VNC
79 #include "bgpd/rfapi/rfapi_backend.h"
80 #include "bgpd/rfapi/vnc_import_bgp.h"
81 #include "bgpd/rfapi/vnc_export_bgp.h"
82 #endif
83 #include "bgpd/bgp_encap_types.h"
84 #include "bgpd/bgp_encap_tlv.h"
85 #include "bgpd/bgp_evpn.h"
86 #include "bgpd/bgp_evpn_mh.h"
87 #include "bgpd/bgp_evpn_vty.h"
88 #include "bgpd/bgp_flowspec.h"
89 #include "bgpd/bgp_flowspec_util.h"
90 #include "bgpd/bgp_pbr.h"
91
92 #ifndef VTYSH_EXTRACT_PL
93 #include "bgpd/bgp_route_clippy.c"
94 #endif
95
96 DEFINE_HOOK(bgp_snmp_update_stats,
97 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
98 (rn, pi, added));
99
100 DEFINE_HOOK(bgp_rpki_prefix_status,
101 (struct peer *peer, struct attr *attr,
102 const struct prefix *prefix),
103 (peer, attr, prefix));
104
105 /* Render dest to prefix_rd based on safi */
106 static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
107 safi_t safi);
108
109 /* Extern from bgp_dump.c */
110 extern const char *bgp_origin_str[];
111 extern const char *bgp_origin_long_str[];
112
113 /* PMSI strings. */
114 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
115 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
116 static const struct message bgp_pmsi_tnltype_str[] = {
117 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
118 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
119 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
120 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
121 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
122 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
123 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
124 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
125 {0}
126 };
127
128 #define VRFID_NONE_STR "-"
129 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
130
131 DEFINE_HOOK(bgp_process,
132 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
133 struct peer *peer, bool withdraw),
134 (bgp, afi, safi, bn, peer, withdraw));
135
136 /** Test if path is suppressed. */
137 static bool bgp_path_suppressed(struct bgp_path_info *pi)
138 {
139 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
140 return false;
141
142 return listcount(pi->extra->aggr_suppressors) > 0;
143 }
144
145 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
146 safi_t safi, const struct prefix *p,
147 struct prefix_rd *prd)
148 {
149 struct bgp_dest *dest;
150 struct bgp_dest *pdest = NULL;
151
152 assert(table);
153
154 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
155 || (safi == SAFI_EVPN)) {
156 pdest = bgp_node_get(table, (struct prefix *)prd);
157
158 if (!bgp_dest_has_bgp_path_info_data(pdest))
159 bgp_dest_set_bgp_table_info(
160 pdest, bgp_table_init(table->bgp, afi, safi));
161 else
162 bgp_dest_unlock_node(pdest);
163 table = bgp_dest_get_bgp_table_info(pdest);
164 }
165
166 dest = bgp_node_get(table, p);
167
168 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
169 || (safi == SAFI_EVPN))
170 dest->pdest = pdest;
171
172 return dest;
173 }
174
175 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
176 safi_t safi, const struct prefix *p,
177 struct prefix_rd *prd)
178 {
179 struct bgp_dest *dest;
180 struct bgp_dest *pdest = NULL;
181
182 if (!table)
183 return NULL;
184
185 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
186 || (safi == SAFI_EVPN)) {
187 pdest = bgp_node_lookup(table, (struct prefix *)prd);
188 if (!pdest)
189 return NULL;
190
191 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
192 bgp_dest_unlock_node(pdest);
193 return NULL;
194 }
195
196 table = bgp_dest_get_bgp_table_info(pdest);
197 }
198
199 dest = bgp_node_lookup(table, p);
200
201 return dest;
202 }
203
204 /* Allocate bgp_path_info_extra */
205 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
206 {
207 struct bgp_path_info_extra *new;
208 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
209 sizeof(struct bgp_path_info_extra));
210 new->label[0] = MPLS_INVALID_LABEL;
211 new->num_labels = 0;
212 new->bgp_fs_pbr = NULL;
213 new->bgp_fs_iprule = NULL;
214 return new;
215 }
216
217 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
218 {
219 struct bgp_path_info_extra *e;
220
221 if (!extra || !*extra)
222 return;
223
224 e = *extra;
225 if (e->damp_info)
226 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
227 e->damp_info->safi);
228
229 e->damp_info = NULL;
230 if (e->parent) {
231 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
232
233 if (bpi->net) {
234 /* FIXME: since multiple e may have the same e->parent
235 * and e->parent->net is holding a refcount for each
236 * of them, we need to do some fudging here.
237 *
238 * WARNING: if bpi->net->lock drops to 0, bpi may be
239 * freed as well (because bpi->net was holding the
240 * last reference to bpi) => write after free!
241 */
242 unsigned refcount;
243
244 bpi = bgp_path_info_lock(bpi);
245 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
246 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
247 if (!refcount)
248 bpi->net = NULL;
249 bgp_path_info_unlock(bpi);
250 }
251 bgp_path_info_unlock(e->parent);
252 e->parent = NULL;
253 }
254
255 if (e->bgp_orig)
256 bgp_unlock(e->bgp_orig);
257
258 if (e->peer_orig)
259 peer_unlock(e->peer_orig);
260
261 if (e->aggr_suppressors)
262 list_delete(&e->aggr_suppressors);
263
264 if (e->mh_info)
265 bgp_evpn_path_mh_info_free(e->mh_info);
266
267 if ((*extra)->bgp_fs_iprule)
268 list_delete(&((*extra)->bgp_fs_iprule));
269 if ((*extra)->bgp_fs_pbr)
270 list_delete(&((*extra)->bgp_fs_pbr));
271 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
272 }
273
274 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
275 * allocated if required.
276 */
277 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
278 {
279 if (!pi->extra)
280 pi->extra = bgp_path_info_extra_new();
281 return pi->extra;
282 }
283
284 /* Free bgp route information. */
285 static void bgp_path_info_free(struct bgp_path_info *path)
286 {
287 bgp_attr_unintern(&path->attr);
288
289 bgp_unlink_nexthop(path);
290 bgp_path_info_extra_free(&path->extra);
291 bgp_path_info_mpath_free(&path->mpath);
292 if (path->net)
293 bgp_addpath_free_info_data(&path->tx_addpath,
294 &path->net->tx_addpath);
295
296 peer_unlock(path->peer); /* bgp_path_info peer reference */
297
298 XFREE(MTYPE_BGP_ROUTE, path);
299 }
300
301 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
302 {
303 path->lock++;
304 return path;
305 }
306
307 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
308 {
309 assert(path && path->lock > 0);
310 path->lock--;
311
312 if (path->lock == 0) {
313 bgp_path_info_free(path);
314 return NULL;
315 }
316
317 return path;
318 }
319
320 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
321 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
322 {
323 struct peer *peer;
324 struct bgp_path_info *old_pi, *nextpi;
325 bool set_flag = false;
326 struct bgp *bgp = NULL;
327 struct bgp_table *table = NULL;
328 afi_t afi = 0;
329 safi_t safi = 0;
330
331 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
332 * then the route selection is deferred
333 */
334 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
335 return 0;
336
337 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
338 if (BGP_DEBUG(update, UPDATE_OUT))
339 zlog_debug(
340 "Route %pBD is in workqueue and being processed, not deferred.",
341 dest);
342
343 return 0;
344 }
345
346 table = bgp_dest_table(dest);
347 if (table) {
348 bgp = table->bgp;
349 afi = table->afi;
350 safi = table->safi;
351 }
352
353 for (old_pi = bgp_dest_get_bgp_path_info(dest);
354 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
355 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
356 continue;
357
358 /* Route selection is deferred if there is a stale path which
359 * which indicates peer is in restart mode
360 */
361 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
362 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
363 set_flag = true;
364 } else {
365 /* If the peer is graceful restart capable and peer is
366 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
367 */
368 peer = old_pi->peer;
369 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
370 && BGP_PEER_RESTARTING_MODE(peer)
371 && (old_pi
372 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
373 set_flag = true;
374 }
375 }
376 if (set_flag)
377 break;
378 }
379
380 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
381 * is active
382 */
383 if (set_flag && table) {
384 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
385 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
386 bgp->gr_info[afi][safi].gr_deferred++;
387 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
388 if (BGP_DEBUG(update, UPDATE_OUT))
389 zlog_debug("DEFER route %pBD, dest %p", dest,
390 dest);
391 return 0;
392 }
393 }
394 return -1;
395 }
396
397 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
398 {
399 struct bgp_path_info *top;
400
401 top = bgp_dest_get_bgp_path_info(dest);
402
403 pi->next = top;
404 pi->prev = NULL;
405 if (top)
406 top->prev = pi;
407 bgp_dest_set_bgp_path_info(dest, pi);
408
409 bgp_path_info_lock(pi);
410 bgp_dest_lock_node(dest);
411 peer_lock(pi->peer); /* bgp_path_info peer reference */
412 bgp_dest_set_defer_flag(dest, false);
413 hook_call(bgp_snmp_update_stats, dest, pi, true);
414 }
415
416 /* Do the actual removal of info from RIB, for use by bgp_process
417 completion callback *only* */
418 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
419 {
420 if (pi->next)
421 pi->next->prev = pi->prev;
422 if (pi->prev)
423 pi->prev->next = pi->next;
424 else
425 bgp_dest_set_bgp_path_info(dest, pi->next);
426
427 bgp_path_info_mpath_dequeue(pi);
428 bgp_path_info_unlock(pi);
429 hook_call(bgp_snmp_update_stats, dest, pi, false);
430 bgp_dest_unlock_node(dest);
431 }
432
433 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
434 {
435 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
436 /* set of previous already took care of pcount */
437 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
438 }
439
440 /* undo the effects of a previous call to bgp_path_info_delete; typically
441 called when a route is deleted and then quickly re-added before the
442 deletion has been processed */
443 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
444 {
445 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
446 /* unset of previous already took care of pcount */
447 SET_FLAG(pi->flags, BGP_PATH_VALID);
448 }
449
450 /* Adjust pcount as required */
451 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
452 {
453 struct bgp_table *table;
454
455 assert(dest && bgp_dest_table(dest));
456 assert(pi && pi->peer && pi->peer->bgp);
457
458 table = bgp_dest_table(dest);
459
460 if (pi->peer == pi->peer->bgp->peer_self)
461 return;
462
463 if (!BGP_PATH_COUNTABLE(pi)
464 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
465
466 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
467
468 /* slight hack, but more robust against errors. */
469 if (pi->peer->pcount[table->afi][table->safi])
470 pi->peer->pcount[table->afi][table->safi]--;
471 else
472 flog_err(EC_LIB_DEVELOPMENT,
473 "Asked to decrement 0 prefix count for peer");
474 } else if (BGP_PATH_COUNTABLE(pi)
475 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
476 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
477 pi->peer->pcount[table->afi][table->safi]++;
478 }
479 }
480
481 static int bgp_label_index_differs(struct bgp_path_info *pi1,
482 struct bgp_path_info *pi2)
483 {
484 return (!(pi1->attr->label_index == pi2->attr->label_index));
485 }
486
487 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
488 * This is here primarily to keep prefix-count in check.
489 */
490 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
491 uint32_t flag)
492 {
493 SET_FLAG(pi->flags, flag);
494
495 /* early bath if we know it's not a flag that changes countability state
496 */
497 if (!CHECK_FLAG(flag,
498 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
499 return;
500
501 bgp_pcount_adjust(dest, pi);
502 }
503
504 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
505 uint32_t flag)
506 {
507 UNSET_FLAG(pi->flags, flag);
508
509 /* early bath if we know it's not a flag that changes countability state
510 */
511 if (!CHECK_FLAG(flag,
512 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
513 return;
514
515 bgp_pcount_adjust(dest, pi);
516 }
517
518 /* Get MED value. If MED value is missing and "bgp bestpath
519 missing-as-worst" is specified, treat it as the worst value. */
520 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
521 {
522 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
523 return attr->med;
524 else {
525 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
526 return BGP_MED_MAX;
527 else
528 return 0;
529 }
530 }
531
532 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
533 size_t buf_len)
534 {
535 if (pi->addpath_rx_id)
536 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
537 pi->peer->host, pi->addpath_rx_id);
538 else
539 snprintf(buf, buf_len, "path %s", pi->peer->host);
540 }
541
542
543 /*
544 * Get the ultimate path info.
545 */
546 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
547 {
548 struct bgp_path_info *bpi_ultimate;
549
550 if (info->sub_type != BGP_ROUTE_IMPORTED)
551 return info;
552
553 for (bpi_ultimate = info;
554 bpi_ultimate->extra && bpi_ultimate->extra->parent;
555 bpi_ultimate = bpi_ultimate->extra->parent)
556 ;
557
558 return bpi_ultimate;
559 }
560
561 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
562 */
563 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
564 struct bgp_path_info *exist, int *paths_eq,
565 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
566 char *pfx_buf, afi_t afi, safi_t safi,
567 enum bgp_path_selection_reason *reason)
568 {
569 const struct prefix *new_p;
570 struct attr *newattr, *existattr;
571 enum bgp_peer_sort new_sort;
572 enum bgp_peer_sort exist_sort;
573 uint32_t new_pref;
574 uint32_t exist_pref;
575 uint32_t new_med;
576 uint32_t exist_med;
577 uint32_t new_weight;
578 uint32_t exist_weight;
579 uint32_t newm, existm;
580 struct in_addr new_id;
581 struct in_addr exist_id;
582 int new_cluster;
583 int exist_cluster;
584 int internal_as_route;
585 int confed_as_route;
586 int ret = 0;
587 int igp_metric_ret = 0;
588 int peer_sort_ret = -1;
589 char new_buf[PATH_ADDPATH_STR_BUFFER];
590 char exist_buf[PATH_ADDPATH_STR_BUFFER];
591 uint32_t new_mm_seq;
592 uint32_t exist_mm_seq;
593 int nh_cmp;
594 esi_t *exist_esi;
595 esi_t *new_esi;
596 bool same_esi;
597 bool old_proxy;
598 bool new_proxy;
599 bool new_origin, exist_origin;
600 struct bgp_path_info *bpi_ultimate;
601
602 *paths_eq = 0;
603
604 /* 0. Null check. */
605 if (new == NULL) {
606 *reason = bgp_path_selection_none;
607 if (debug)
608 zlog_debug("%s: new is NULL", pfx_buf);
609 return 0;
610 }
611
612 if (debug) {
613 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
614 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
615 sizeof(new_buf));
616 }
617
618 if (exist == NULL) {
619 *reason = bgp_path_selection_first;
620 if (debug)
621 zlog_debug("%s(%s): %s is the initial bestpath",
622 pfx_buf, bgp->name_pretty, new_buf);
623 return 1;
624 }
625
626 if (debug) {
627 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
628 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
629 sizeof(exist_buf));
630 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
631 pfx_buf, bgp->name_pretty, new_buf, new->flags,
632 exist_buf, exist->flags);
633 }
634
635 newattr = new->attr;
636 existattr = exist->attr;
637
638 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
639 * Capability" to a neighbor MUST perform the following upon receiving
640 * a route from that neighbor with the "LLGR_STALE" community, or upon
641 * attaching the "LLGR_STALE" community itself per Section 4.2:
642 *
643 * Treat the route as the least-preferred in route selection (see
644 * below). See the Risks of Depreferencing Routes section (Section 5.2)
645 * for a discussion of potential risks inherent in doing this.
646 */
647 if (bgp_attr_get_community(newattr) &&
648 community_include(bgp_attr_get_community(newattr),
649 COMMUNITY_LLGR_STALE)) {
650 if (debug)
651 zlog_debug(
652 "%s: %s wins over %s due to LLGR_STALE community",
653 pfx_buf, new_buf, exist_buf);
654 return 0;
655 }
656
657 if (bgp_attr_get_community(existattr) &&
658 community_include(bgp_attr_get_community(existattr),
659 COMMUNITY_LLGR_STALE)) {
660 if (debug)
661 zlog_debug(
662 "%s: %s loses to %s due to LLGR_STALE community",
663 pfx_buf, new_buf, exist_buf);
664 return 1;
665 }
666
667 new_p = bgp_dest_get_prefix(new->net);
668
669 /* For EVPN routes, we cannot just go by local vs remote, we have to
670 * look at the MAC mobility sequence number, if present.
671 */
672 if ((safi == SAFI_EVPN)
673 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
674 /* This is an error condition described in RFC 7432 Section
675 * 15.2. The RFC
676 * states that in this scenario "the PE MUST alert the operator"
677 * but it
678 * does not state what other action to take. In order to provide
679 * some
680 * consistency in this scenario we are going to prefer the path
681 * with the
682 * sticky flag.
683 */
684 if (newattr->sticky != existattr->sticky) {
685 if (!debug) {
686 prefix2str(new_p, pfx_buf,
687 sizeof(*pfx_buf)
688 * PREFIX2STR_BUFFER);
689 bgp_path_info_path_with_addpath_rx_str(
690 new, new_buf, sizeof(new_buf));
691 bgp_path_info_path_with_addpath_rx_str(
692 exist, exist_buf, sizeof(exist_buf));
693 }
694
695 if (newattr->sticky && !existattr->sticky) {
696 *reason = bgp_path_selection_evpn_sticky_mac;
697 if (debug)
698 zlog_debug(
699 "%s: %s wins over %s due to sticky MAC flag",
700 pfx_buf, new_buf, exist_buf);
701 return 1;
702 }
703
704 if (!newattr->sticky && existattr->sticky) {
705 *reason = bgp_path_selection_evpn_sticky_mac;
706 if (debug)
707 zlog_debug(
708 "%s: %s loses to %s due to sticky MAC flag",
709 pfx_buf, new_buf, exist_buf);
710 return 0;
711 }
712 }
713
714 new_esi = bgp_evpn_attr_get_esi(newattr);
715 exist_esi = bgp_evpn_attr_get_esi(existattr);
716 if (bgp_evpn_is_esi_valid(new_esi) &&
717 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
718 same_esi = true;
719 } else {
720 same_esi = false;
721 }
722
723 /* If both paths have the same non-zero ES and
724 * one path is local it wins.
725 * PS: Note the local path wins even if the remote
726 * has the higher MM seq. The local path's
727 * MM seq will be fixed up to match the highest
728 * rem seq, subsequently.
729 */
730 if (same_esi) {
731 char esi_buf[ESI_STR_LEN];
732
733 if (bgp_evpn_is_path_local(bgp, new)) {
734 *reason = bgp_path_selection_evpn_local_path;
735 if (debug)
736 zlog_debug(
737 "%s: %s wins over %s as ES %s is same and local",
738 pfx_buf, new_buf, exist_buf,
739 esi_to_str(new_esi, esi_buf,
740 sizeof(esi_buf)));
741 return 1;
742 }
743 if (bgp_evpn_is_path_local(bgp, exist)) {
744 *reason = bgp_path_selection_evpn_local_path;
745 if (debug)
746 zlog_debug(
747 "%s: %s loses to %s as ES %s is same and local",
748 pfx_buf, new_buf, exist_buf,
749 esi_to_str(new_esi, esi_buf,
750 sizeof(esi_buf)));
751 return 0;
752 }
753 }
754
755 new_mm_seq = mac_mobility_seqnum(newattr);
756 exist_mm_seq = mac_mobility_seqnum(existattr);
757
758 if (new_mm_seq > exist_mm_seq) {
759 *reason = bgp_path_selection_evpn_seq;
760 if (debug)
761 zlog_debug(
762 "%s: %s wins over %s due to MM seq %u > %u",
763 pfx_buf, new_buf, exist_buf, new_mm_seq,
764 exist_mm_seq);
765 return 1;
766 }
767
768 if (new_mm_seq < exist_mm_seq) {
769 *reason = bgp_path_selection_evpn_seq;
770 if (debug)
771 zlog_debug(
772 "%s: %s loses to %s due to MM seq %u < %u",
773 pfx_buf, new_buf, exist_buf, new_mm_seq,
774 exist_mm_seq);
775 return 0;
776 }
777
778 /* if the sequence numbers and ESI are the same and one path
779 * is non-proxy it wins (over proxy)
780 */
781 new_proxy = bgp_evpn_attr_is_proxy(newattr);
782 old_proxy = bgp_evpn_attr_is_proxy(existattr);
783 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
784 old_proxy != new_proxy) {
785 if (!new_proxy) {
786 *reason = bgp_path_selection_evpn_non_proxy;
787 if (debug)
788 zlog_debug(
789 "%s: %s wins over %s, same seq/es and non-proxy",
790 pfx_buf, new_buf, exist_buf);
791 return 1;
792 }
793
794 *reason = bgp_path_selection_evpn_non_proxy;
795 if (debug)
796 zlog_debug(
797 "%s: %s loses to %s, same seq/es and non-proxy",
798 pfx_buf, new_buf, exist_buf);
799 return 0;
800 }
801
802 /*
803 * if sequence numbers are the same path with the lowest IP
804 * wins
805 */
806 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
807 if (nh_cmp < 0) {
808 *reason = bgp_path_selection_evpn_lower_ip;
809 if (debug)
810 zlog_debug(
811 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
812 pfx_buf, new_buf, exist_buf, new_mm_seq,
813 &new->attr->nexthop);
814 return 1;
815 }
816 if (nh_cmp > 0) {
817 *reason = bgp_path_selection_evpn_lower_ip;
818 if (debug)
819 zlog_debug(
820 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
821 pfx_buf, new_buf, exist_buf, new_mm_seq,
822 &new->attr->nexthop);
823 return 0;
824 }
825 }
826
827 /* 1. Weight check. */
828 new_weight = newattr->weight;
829 exist_weight = existattr->weight;
830
831 if (new_weight > exist_weight) {
832 *reason = bgp_path_selection_weight;
833 if (debug)
834 zlog_debug("%s: %s wins over %s due to weight %d > %d",
835 pfx_buf, new_buf, exist_buf, new_weight,
836 exist_weight);
837 return 1;
838 }
839
840 if (new_weight < exist_weight) {
841 *reason = bgp_path_selection_weight;
842 if (debug)
843 zlog_debug("%s: %s loses to %s due to weight %d < %d",
844 pfx_buf, new_buf, exist_buf, new_weight,
845 exist_weight);
846 return 0;
847 }
848
849 /* 2. Local preference check. */
850 new_pref = exist_pref = bgp->default_local_pref;
851
852 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
853 new_pref = newattr->local_pref;
854 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
855 exist_pref = existattr->local_pref;
856
857 if (new_pref > exist_pref) {
858 *reason = bgp_path_selection_local_pref;
859 if (debug)
860 zlog_debug(
861 "%s: %s wins over %s due to localpref %d > %d",
862 pfx_buf, new_buf, exist_buf, new_pref,
863 exist_pref);
864 return 1;
865 }
866
867 if (new_pref < exist_pref) {
868 *reason = bgp_path_selection_local_pref;
869 if (debug)
870 zlog_debug(
871 "%s: %s loses to %s due to localpref %d < %d",
872 pfx_buf, new_buf, exist_buf, new_pref,
873 exist_pref);
874 return 0;
875 }
876
877 /* 3. Local route check. We prefer:
878 * - BGP_ROUTE_STATIC
879 * - BGP_ROUTE_AGGREGATE
880 * - BGP_ROUTE_REDISTRIBUTE
881 */
882 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
883 new->sub_type == BGP_ROUTE_IMPORTED);
884 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
885 exist->sub_type == BGP_ROUTE_IMPORTED);
886
887 if (new_origin && !exist_origin) {
888 *reason = bgp_path_selection_local_route;
889 if (debug)
890 zlog_debug(
891 "%s: %s wins over %s due to preferred BGP_ROUTE type",
892 pfx_buf, new_buf, exist_buf);
893 return 1;
894 }
895
896 if (!new_origin && exist_origin) {
897 *reason = bgp_path_selection_local_route;
898 if (debug)
899 zlog_debug(
900 "%s: %s loses to %s due to preferred BGP_ROUTE type",
901 pfx_buf, new_buf, exist_buf);
902 return 0;
903 }
904
905 /* Here if these are imported routes then get ultimate pi for
906 * path compare.
907 */
908 new = bgp_get_imported_bpi_ultimate(new);
909 exist = bgp_get_imported_bpi_ultimate(exist);
910 newattr = new->attr;
911 existattr = exist->attr;
912
913 /* 4. AS path length check. */
914 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
915 int exist_hops = aspath_count_hops(existattr->aspath);
916 int exist_confeds = aspath_count_confeds(existattr->aspath);
917
918 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
919 int aspath_hops;
920
921 aspath_hops = aspath_count_hops(newattr->aspath);
922 aspath_hops += aspath_count_confeds(newattr->aspath);
923
924 if (aspath_hops < (exist_hops + exist_confeds)) {
925 *reason = bgp_path_selection_confed_as_path;
926 if (debug)
927 zlog_debug(
928 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
929 pfx_buf, new_buf, exist_buf,
930 aspath_hops,
931 (exist_hops + exist_confeds));
932 return 1;
933 }
934
935 if (aspath_hops > (exist_hops + exist_confeds)) {
936 *reason = bgp_path_selection_confed_as_path;
937 if (debug)
938 zlog_debug(
939 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
940 pfx_buf, new_buf, exist_buf,
941 aspath_hops,
942 (exist_hops + exist_confeds));
943 return 0;
944 }
945 } else {
946 int newhops = aspath_count_hops(newattr->aspath);
947
948 if (newhops < exist_hops) {
949 *reason = bgp_path_selection_as_path;
950 if (debug)
951 zlog_debug(
952 "%s: %s wins over %s due to aspath hopcount %d < %d",
953 pfx_buf, new_buf, exist_buf,
954 newhops, exist_hops);
955 return 1;
956 }
957
958 if (newhops > exist_hops) {
959 *reason = bgp_path_selection_as_path;
960 if (debug)
961 zlog_debug(
962 "%s: %s loses to %s due to aspath hopcount %d > %d",
963 pfx_buf, new_buf, exist_buf,
964 newhops, exist_hops);
965 return 0;
966 }
967 }
968 }
969
970 /* 5. Origin check. */
971 if (newattr->origin < existattr->origin) {
972 *reason = bgp_path_selection_origin;
973 if (debug)
974 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
975 pfx_buf, new_buf, exist_buf,
976 bgp_origin_long_str[newattr->origin],
977 bgp_origin_long_str[existattr->origin]);
978 return 1;
979 }
980
981 if (newattr->origin > existattr->origin) {
982 *reason = bgp_path_selection_origin;
983 if (debug)
984 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
985 pfx_buf, new_buf, exist_buf,
986 bgp_origin_long_str[newattr->origin],
987 bgp_origin_long_str[existattr->origin]);
988 return 0;
989 }
990
991 /* 6. MED check. */
992 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
993 && aspath_count_hops(existattr->aspath) == 0);
994 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
995 && aspath_count_confeds(existattr->aspath) > 0
996 && aspath_count_hops(newattr->aspath) == 0
997 && aspath_count_hops(existattr->aspath) == 0);
998
999 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1000 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1001 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1002 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1003 || internal_as_route) {
1004 new_med = bgp_med_value(new->attr, bgp);
1005 exist_med = bgp_med_value(exist->attr, bgp);
1006
1007 if (new_med < exist_med) {
1008 *reason = bgp_path_selection_med;
1009 if (debug)
1010 zlog_debug(
1011 "%s: %s wins over %s due to MED %d < %d",
1012 pfx_buf, new_buf, exist_buf, new_med,
1013 exist_med);
1014 return 1;
1015 }
1016
1017 if (new_med > exist_med) {
1018 *reason = bgp_path_selection_med;
1019 if (debug)
1020 zlog_debug(
1021 "%s: %s loses to %s due to MED %d > %d",
1022 pfx_buf, new_buf, exist_buf, new_med,
1023 exist_med);
1024 return 0;
1025 }
1026 }
1027
1028 /* 7. Peer type check. */
1029 new_sort = new->peer->sort;
1030 exist_sort = exist->peer->sort;
1031
1032 if (new_sort == BGP_PEER_EBGP
1033 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1034 *reason = bgp_path_selection_peer;
1035 if (debug)
1036 zlog_debug(
1037 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1038 pfx_buf, new_buf, exist_buf);
1039 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1040 return 1;
1041 peer_sort_ret = 1;
1042 }
1043
1044 if (exist_sort == BGP_PEER_EBGP
1045 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1046 *reason = bgp_path_selection_peer;
1047 if (debug)
1048 zlog_debug(
1049 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1050 pfx_buf, new_buf, exist_buf);
1051 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1052 return 0;
1053 peer_sort_ret = 0;
1054 }
1055
1056 /* 8. IGP metric check. */
1057 newm = existm = 0;
1058
1059 if (new->extra)
1060 newm = new->extra->igpmetric;
1061 if (exist->extra)
1062 existm = exist->extra->igpmetric;
1063
1064 if (newm < existm) {
1065 if (debug && peer_sort_ret < 0)
1066 zlog_debug(
1067 "%s: %s wins over %s due to IGP metric %u < %u",
1068 pfx_buf, new_buf, exist_buf, newm, existm);
1069 igp_metric_ret = 1;
1070 }
1071
1072 if (newm > existm) {
1073 if (debug && peer_sort_ret < 0)
1074 zlog_debug(
1075 "%s: %s loses to %s due to IGP metric %u > %u",
1076 pfx_buf, new_buf, exist_buf, newm, existm);
1077 igp_metric_ret = 0;
1078 }
1079
1080 /* 9. Same IGP metric. Compare the cluster list length as
1081 representative of IGP hops metric. Rewrite the metric value
1082 pair (newm, existm) with the cluster list length. Prefer the
1083 path with smaller cluster list length. */
1084 if (newm == existm) {
1085 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP &&
1086 peer_sort_lookup(exist->peer) == BGP_PEER_IBGP &&
1087 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1088 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1089 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1090
1091 if (newm < existm) {
1092 if (debug && peer_sort_ret < 0)
1093 zlog_debug(
1094 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1095 pfx_buf, new_buf, exist_buf,
1096 newm, existm);
1097 igp_metric_ret = 1;
1098 }
1099
1100 if (newm > existm) {
1101 if (debug && peer_sort_ret < 0)
1102 zlog_debug(
1103 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1104 pfx_buf, new_buf, exist_buf,
1105 newm, existm);
1106 igp_metric_ret = 0;
1107 }
1108 }
1109 }
1110
1111 /* 10. confed-external vs. confed-internal */
1112 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1113 if (new_sort == BGP_PEER_CONFED
1114 && exist_sort == BGP_PEER_IBGP) {
1115 *reason = bgp_path_selection_confed;
1116 if (debug)
1117 zlog_debug(
1118 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1119 pfx_buf, new_buf, exist_buf);
1120 if (!CHECK_FLAG(bgp->flags,
1121 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_CONFED
1127 && new_sort == BGP_PEER_IBGP) {
1128 *reason = bgp_path_selection_confed;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags,
1134 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1135 return 0;
1136 peer_sort_ret = 0;
1137 }
1138 }
1139
1140 /* 11. Maximum path check. */
1141 if (newm == existm) {
1142 /* If one path has a label but the other does not, do not treat
1143 * them as equals for multipath
1144 */
1145 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1146 != (exist->extra
1147 && bgp_is_valid_label(&exist->extra->label[0]))) {
1148 if (debug)
1149 zlog_debug(
1150 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1151 pfx_buf, new_buf, exist_buf);
1152 } else if (CHECK_FLAG(bgp->flags,
1153 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1154
1155 /*
1156 * For the two paths, all comparison steps till IGP
1157 * metric
1158 * have succeeded - including AS_PATH hop count. Since
1159 * 'bgp
1160 * bestpath as-path multipath-relax' knob is on, we
1161 * don't need
1162 * an exact match of AS_PATH. Thus, mark the paths are
1163 * equal.
1164 * That will trigger both these paths to get into the
1165 * multipath
1166 * array.
1167 */
1168 *paths_eq = 1;
1169
1170 if (debug)
1171 zlog_debug(
1172 "%s: %s and %s are equal via multipath-relax",
1173 pfx_buf, new_buf, exist_buf);
1174 } else if (new->peer->sort == BGP_PEER_IBGP) {
1175 if (aspath_cmp(new->attr->aspath,
1176 exist->attr->aspath)) {
1177 *paths_eq = 1;
1178
1179 if (debug)
1180 zlog_debug(
1181 "%s: %s and %s are equal via matching aspaths",
1182 pfx_buf, new_buf, exist_buf);
1183 }
1184 } else if (new->peer->as == exist->peer->as) {
1185 *paths_eq = 1;
1186
1187 if (debug)
1188 zlog_debug(
1189 "%s: %s and %s are equal via same remote-as",
1190 pfx_buf, new_buf, exist_buf);
1191 }
1192 } else {
1193 /*
1194 * TODO: If unequal cost ibgp multipath is enabled we can
1195 * mark the paths as equal here instead of returning
1196 */
1197
1198 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1199 * if either step 7 or 10 (peer type checks) yielded a winner,
1200 * that result was returned immediately. Returning from step 10
1201 * ignored the return value computed in steps 8 and 9 (IGP
1202 * metric checks). In order to preserve that behavior, if
1203 * peer_sort_ret is set, return that rather than igp_metric_ret.
1204 */
1205 ret = peer_sort_ret;
1206 if (peer_sort_ret < 0) {
1207 ret = igp_metric_ret;
1208 if (debug) {
1209 if (ret == 1)
1210 zlog_debug(
1211 "%s: %s wins over %s after IGP metric comparison",
1212 pfx_buf, new_buf, exist_buf);
1213 else
1214 zlog_debug(
1215 "%s: %s loses to %s after IGP metric comparison",
1216 pfx_buf, new_buf, exist_buf);
1217 }
1218 *reason = bgp_path_selection_igp_metric;
1219 }
1220 return ret;
1221 }
1222
1223 /*
1224 * At this point, the decision whether to set *paths_eq = 1 has been
1225 * completed. If we deferred returning because of bestpath peer-type
1226 * relax configuration, return now.
1227 */
1228 if (peer_sort_ret >= 0)
1229 return peer_sort_ret;
1230
1231 /* 12. If both paths are external, prefer the path that was received
1232 first (the oldest one). This step minimizes route-flap, since a
1233 newer path won't displace an older one, even if it was the
1234 preferred route based on the additional decision criteria below. */
1235 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1236 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1237 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1238 *reason = bgp_path_selection_older;
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s wins over %s due to oldest external",
1242 pfx_buf, new_buf, exist_buf);
1243 return 1;
1244 }
1245
1246 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1247 *reason = bgp_path_selection_older;
1248 if (debug)
1249 zlog_debug(
1250 "%s: %s loses to %s due to oldest external",
1251 pfx_buf, new_buf, exist_buf);
1252 return 0;
1253 }
1254 }
1255
1256 /* 13. Router-ID comparison. */
1257 /* If one of the paths is "stale", the corresponding peer router-id will
1258 * be 0 and would always win over the other path. If originator id is
1259 * used for the comparison, it will decide which path is better.
1260 */
1261 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1262 new_id.s_addr = newattr->originator_id.s_addr;
1263 else
1264 new_id.s_addr = new->peer->remote_id.s_addr;
1265 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1266 exist_id.s_addr = existattr->originator_id.s_addr;
1267 else
1268 exist_id.s_addr = exist->peer->remote_id.s_addr;
1269
1270 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1271 *reason = bgp_path_selection_router_id;
1272 if (debug)
1273 zlog_debug(
1274 "%s: %s wins over %s due to Router-ID comparison",
1275 pfx_buf, new_buf, exist_buf);
1276 return 1;
1277 }
1278
1279 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1280 *reason = bgp_path_selection_router_id;
1281 if (debug)
1282 zlog_debug(
1283 "%s: %s loses to %s due to Router-ID comparison",
1284 pfx_buf, new_buf, exist_buf);
1285 return 0;
1286 }
1287
1288 /* 14. Cluster length comparison. */
1289 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1290 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1291
1292 if (new_cluster < exist_cluster) {
1293 *reason = bgp_path_selection_cluster_length;
1294 if (debug)
1295 zlog_debug(
1296 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1297 pfx_buf, new_buf, exist_buf, new_cluster,
1298 exist_cluster);
1299 return 1;
1300 }
1301
1302 if (new_cluster > exist_cluster) {
1303 *reason = bgp_path_selection_cluster_length;
1304 if (debug)
1305 zlog_debug(
1306 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1307 pfx_buf, new_buf, exist_buf, new_cluster,
1308 exist_cluster);
1309 return 0;
1310 }
1311
1312 /* 15. Neighbor address comparison. */
1313 /* Do this only if neither path is "stale" as stale paths do not have
1314 * valid peer information (as the connection may or may not be up).
1315 */
1316 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1317 *reason = bgp_path_selection_stale;
1318 if (debug)
1319 zlog_debug(
1320 "%s: %s wins over %s due to latter path being STALE",
1321 pfx_buf, new_buf, exist_buf);
1322 return 1;
1323 }
1324
1325 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1326 *reason = bgp_path_selection_stale;
1327 if (debug)
1328 zlog_debug(
1329 "%s: %s loses to %s due to former path being STALE",
1330 pfx_buf, new_buf, exist_buf);
1331 return 0;
1332 }
1333
1334 /* locally configured routes to advertise do not have su_remote */
1335 if (new->peer->su_remote == NULL) {
1336 *reason = bgp_path_selection_local_configured;
1337 return 0;
1338 }
1339 if (exist->peer->su_remote == NULL) {
1340 *reason = bgp_path_selection_local_configured;
1341 return 1;
1342 }
1343
1344 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1345
1346 if (ret == 1) {
1347 *reason = bgp_path_selection_neighbor_ip;
1348 if (debug)
1349 zlog_debug(
1350 "%s: %s loses to %s due to Neighor IP comparison",
1351 pfx_buf, new_buf, exist_buf);
1352 return 0;
1353 }
1354
1355 if (ret == -1) {
1356 *reason = bgp_path_selection_neighbor_ip;
1357 if (debug)
1358 zlog_debug(
1359 "%s: %s wins over %s due to Neighor IP comparison",
1360 pfx_buf, new_buf, exist_buf);
1361 return 1;
1362 }
1363
1364 *reason = bgp_path_selection_default;
1365 if (debug)
1366 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1367 pfx_buf, new_buf, exist_buf);
1368
1369 return 1;
1370 }
1371
1372
1373 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1374 struct bgp_path_info *exist, int *paths_eq)
1375 {
1376 enum bgp_path_selection_reason reason;
1377 char pfx_buf[PREFIX2STR_BUFFER];
1378
1379 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1380 AFI_L2VPN, SAFI_EVPN, &reason);
1381 }
1382
1383 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1384 * is preferred, or 0 if they are the same (usually will only occur if
1385 * multipath is enabled
1386 * This version is compatible with */
1387 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1388 struct bgp_path_info *exist, char *pfx_buf,
1389 afi_t afi, safi_t safi,
1390 enum bgp_path_selection_reason *reason)
1391 {
1392 int paths_eq;
1393 int ret;
1394 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1395 afi, safi, reason);
1396
1397 if (paths_eq)
1398 ret = 0;
1399 else {
1400 if (ret == 1)
1401 ret = -1;
1402 else
1403 ret = 1;
1404 }
1405 return ret;
1406 }
1407
1408 static enum filter_type bgp_input_filter(struct peer *peer,
1409 const struct prefix *p,
1410 struct attr *attr, afi_t afi,
1411 safi_t safi)
1412 {
1413 struct bgp_filter *filter;
1414 enum filter_type ret = FILTER_PERMIT;
1415
1416 filter = &peer->filter[afi][safi];
1417
1418 #define FILTER_EXIST_WARN(F, f, filter) \
1419 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1420 zlog_debug("%s: Could not find configured input %s-list %s!", \
1421 peer->host, #f, F##_IN_NAME(filter));
1422
1423 if (DISTRIBUTE_IN_NAME(filter)) {
1424 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1425
1426 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1427 == FILTER_DENY) {
1428 ret = FILTER_DENY;
1429 goto done;
1430 }
1431 }
1432
1433 if (PREFIX_LIST_IN_NAME(filter)) {
1434 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1435
1436 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1437 == PREFIX_DENY) {
1438 ret = FILTER_DENY;
1439 goto done;
1440 }
1441 }
1442
1443 if (FILTER_LIST_IN_NAME(filter)) {
1444 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1445
1446 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1447 == AS_FILTER_DENY) {
1448 ret = FILTER_DENY;
1449 goto done;
1450 }
1451 }
1452
1453 done:
1454 if (frrtrace_enabled(frr_bgp, input_filter)) {
1455 char pfxprint[PREFIX2STR_BUFFER];
1456
1457 prefix2str(p, pfxprint, sizeof(pfxprint));
1458 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1459 ret == FILTER_PERMIT ? "permit" : "deny");
1460 }
1461
1462 return ret;
1463 #undef FILTER_EXIST_WARN
1464 }
1465
1466 static enum filter_type bgp_output_filter(struct peer *peer,
1467 const struct prefix *p,
1468 struct attr *attr, afi_t afi,
1469 safi_t safi)
1470 {
1471 struct bgp_filter *filter;
1472 enum filter_type ret = FILTER_PERMIT;
1473
1474 filter = &peer->filter[afi][safi];
1475
1476 #define FILTER_EXIST_WARN(F, f, filter) \
1477 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1478 zlog_debug("%s: Could not find configured output %s-list %s!", \
1479 peer->host, #f, F##_OUT_NAME(filter));
1480
1481 if (DISTRIBUTE_OUT_NAME(filter)) {
1482 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1483
1484 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1485 == FILTER_DENY) {
1486 ret = FILTER_DENY;
1487 goto done;
1488 }
1489 }
1490
1491 if (PREFIX_LIST_OUT_NAME(filter)) {
1492 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1493
1494 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1495 == PREFIX_DENY) {
1496 ret = FILTER_DENY;
1497 goto done;
1498 }
1499 }
1500
1501 if (FILTER_LIST_OUT_NAME(filter)) {
1502 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1503
1504 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1505 == AS_FILTER_DENY) {
1506 ret = FILTER_DENY;
1507 goto done;
1508 }
1509 }
1510
1511 if (frrtrace_enabled(frr_bgp, output_filter)) {
1512 char pfxprint[PREFIX2STR_BUFFER];
1513
1514 prefix2str(p, pfxprint, sizeof(pfxprint));
1515 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1516 ret == FILTER_PERMIT ? "permit" : "deny");
1517 }
1518
1519 done:
1520 return ret;
1521 #undef FILTER_EXIST_WARN
1522 }
1523
1524 /* If community attribute includes no_export then return 1. */
1525 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1526 {
1527 if (bgp_attr_get_community(attr)) {
1528 /* NO_ADVERTISE check. */
1529 if (community_include(bgp_attr_get_community(attr),
1530 COMMUNITY_NO_ADVERTISE))
1531 return true;
1532
1533 /* NO_EXPORT check. */
1534 if (peer->sort == BGP_PEER_EBGP &&
1535 community_include(bgp_attr_get_community(attr),
1536 COMMUNITY_NO_EXPORT))
1537 return true;
1538
1539 /* NO_EXPORT_SUBCONFED check. */
1540 if (peer->sort == BGP_PEER_EBGP
1541 || peer->sort == BGP_PEER_CONFED)
1542 if (community_include(bgp_attr_get_community(attr),
1543 COMMUNITY_NO_EXPORT_SUBCONFED))
1544 return true;
1545 }
1546 return false;
1547 }
1548
1549 /* Route reflection loop check. */
1550 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1551 {
1552 struct in_addr cluster_id;
1553 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1554
1555 if (cluster) {
1556 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1557 cluster_id = peer->bgp->cluster_id;
1558 else
1559 cluster_id = peer->bgp->router_id;
1560
1561 if (cluster_loop_check(cluster, cluster_id))
1562 return true;
1563 }
1564 return false;
1565 }
1566
1567 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1568 {
1569 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1570 if (peer->local_role == ROLE_PROVIDER ||
1571 peer->local_role == ROLE_RS_SERVER)
1572 return true;
1573 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1574 return true;
1575 return false;
1576 }
1577 if (peer->local_role == ROLE_CUSTOMER ||
1578 peer->local_role == ROLE_PEER ||
1579 peer->local_role == ROLE_RS_CLIENT) {
1580 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1581 attr->otc = peer->as;
1582 }
1583 return false;
1584 }
1585
1586 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1587 {
1588 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1589 if (peer->local_role == ROLE_CUSTOMER ||
1590 peer->local_role == ROLE_RS_CLIENT ||
1591 peer->local_role == ROLE_PEER)
1592 return true;
1593 return false;
1594 }
1595 if (peer->local_role == ROLE_PROVIDER ||
1596 peer->local_role == ROLE_PEER ||
1597 peer->local_role == ROLE_RS_SERVER) {
1598 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1599 attr->otc = peer->bgp->as;
1600 }
1601 return false;
1602 }
1603
1604 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1605 {
1606 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1607 }
1608
1609 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1610 struct attr *attr, afi_t afi, safi_t safi,
1611 const char *rmap_name, mpls_label_t *label,
1612 uint32_t num_labels, struct bgp_dest *dest)
1613 {
1614 struct bgp_filter *filter;
1615 struct bgp_path_info rmap_path = { 0 };
1616 struct bgp_path_info_extra extra = { 0 };
1617 route_map_result_t ret;
1618 struct route_map *rmap = NULL;
1619
1620 filter = &peer->filter[afi][safi];
1621
1622 /* Apply default weight value. */
1623 if (peer->weight[afi][safi])
1624 attr->weight = peer->weight[afi][safi];
1625
1626 if (rmap_name) {
1627 rmap = route_map_lookup_by_name(rmap_name);
1628
1629 if (rmap == NULL)
1630 return RMAP_DENY;
1631 } else {
1632 if (ROUTE_MAP_IN_NAME(filter)) {
1633 rmap = ROUTE_MAP_IN(filter);
1634
1635 if (rmap == NULL)
1636 return RMAP_DENY;
1637 }
1638 }
1639
1640 /* Route map apply. */
1641 if (rmap) {
1642 memset(&rmap_path, 0, sizeof(rmap_path));
1643 /* Duplicate current value to new structure for modification. */
1644 rmap_path.peer = peer;
1645 rmap_path.attr = attr;
1646 rmap_path.extra = &extra;
1647 rmap_path.net = dest;
1648
1649 extra.num_labels = num_labels;
1650 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1651 memcpy(extra.label, label,
1652 num_labels * sizeof(mpls_label_t));
1653
1654 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1655
1656 /* Apply BGP route map to the attribute. */
1657 ret = route_map_apply(rmap, p, &rmap_path);
1658
1659 peer->rmap_type = 0;
1660
1661 if (ret == RMAP_DENYMATCH)
1662 return RMAP_DENY;
1663 }
1664 return RMAP_PERMIT;
1665 }
1666
1667 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1668 struct attr *attr, afi_t afi, safi_t safi,
1669 const char *rmap_name)
1670 {
1671 struct bgp_path_info rmap_path;
1672 route_map_result_t ret;
1673 struct route_map *rmap = NULL;
1674 uint8_t rmap_type;
1675
1676 /*
1677 * So if we get to this point and have no rmap_name
1678 * we want to just show the output as it currently
1679 * exists.
1680 */
1681 if (!rmap_name)
1682 return RMAP_PERMIT;
1683
1684 /* Apply default weight value. */
1685 if (peer->weight[afi][safi])
1686 attr->weight = peer->weight[afi][safi];
1687
1688 rmap = route_map_lookup_by_name(rmap_name);
1689
1690 /*
1691 * If we have a route map name and we do not find
1692 * the routemap that means we have an implicit
1693 * deny.
1694 */
1695 if (rmap == NULL)
1696 return RMAP_DENY;
1697
1698 memset(&rmap_path, 0, sizeof(rmap_path));
1699 /* Route map apply. */
1700 /* Duplicate current value to new structure for modification. */
1701 rmap_path.peer = peer;
1702 rmap_path.attr = attr;
1703
1704 rmap_type = peer->rmap_type;
1705 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1706
1707 /* Apply BGP route map to the attribute. */
1708 ret = route_map_apply(rmap, p, &rmap_path);
1709
1710 peer->rmap_type = rmap_type;
1711
1712 if (ret == RMAP_DENYMATCH)
1713 /*
1714 * caller has multiple error paths with bgp_attr_flush()
1715 */
1716 return RMAP_DENY;
1717
1718 return RMAP_PERMIT;
1719 }
1720
1721 /* If this is an EBGP peer with remove-private-AS */
1722 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1723 struct peer *peer, struct attr *attr)
1724 {
1725 if (peer->sort == BGP_PEER_EBGP
1726 && (peer_af_flag_check(peer, afi, safi,
1727 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1728 || peer_af_flag_check(peer, afi, safi,
1729 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1730 || peer_af_flag_check(peer, afi, safi,
1731 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1732 || peer_af_flag_check(peer, afi, safi,
1733 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1734 // Take action on the entire aspath
1735 if (peer_af_flag_check(peer, afi, safi,
1736 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1737 || peer_af_flag_check(peer, afi, safi,
1738 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1739 if (peer_af_flag_check(
1740 peer, afi, safi,
1741 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1742 attr->aspath = aspath_replace_private_asns(
1743 attr->aspath, bgp->as, peer->as);
1744
1745 /*
1746 * Even if the aspath consists of just private ASNs we
1747 * need to walk the AS-Path to maintain all instances
1748 * of the peer's ASN to break possible loops.
1749 */
1750 else
1751 attr->aspath = aspath_remove_private_asns(
1752 attr->aspath, peer->as);
1753 }
1754
1755 // 'all' was not specified so the entire aspath must be private
1756 // ASNs
1757 // for us to do anything
1758 else if (aspath_private_as_check(attr->aspath)) {
1759 if (peer_af_flag_check(
1760 peer, afi, safi,
1761 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1762 attr->aspath = aspath_replace_private_asns(
1763 attr->aspath, bgp->as, peer->as);
1764 else
1765 /*
1766 * Walk the aspath to retain any instances of
1767 * the peer_asn
1768 */
1769 attr->aspath = aspath_remove_private_asns(
1770 attr->aspath, peer->as);
1771 }
1772 }
1773 }
1774
1775 /* If this is an EBGP peer with as-override */
1776 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1777 struct peer *peer, struct attr *attr)
1778 {
1779 struct aspath *aspath;
1780
1781 if (peer->sort == BGP_PEER_EBGP &&
1782 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1783 if (attr->aspath->refcnt)
1784 aspath = aspath_dup(attr->aspath);
1785 else
1786 aspath = attr->aspath;
1787
1788 attr->aspath = aspath_intern(
1789 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1790
1791 aspath_free(aspath);
1792 }
1793 }
1794
1795 void bgp_attr_add_llgr_community(struct attr *attr)
1796 {
1797 struct community *old;
1798 struct community *new;
1799 struct community *merge;
1800 struct community *llgr;
1801
1802 old = bgp_attr_get_community(attr);
1803 llgr = community_str2com("llgr-stale");
1804
1805 assert(llgr);
1806
1807 if (old) {
1808 merge = community_merge(community_dup(old), llgr);
1809
1810 if (old->refcnt == 0)
1811 community_free(&old);
1812
1813 new = community_uniq_sort(merge);
1814 community_free(&merge);
1815 } else {
1816 new = community_dup(llgr);
1817 }
1818
1819 community_free(&llgr);
1820
1821 bgp_attr_set_community(attr, new);
1822 }
1823
1824 void bgp_attr_add_gshut_community(struct attr *attr)
1825 {
1826 struct community *old;
1827 struct community *new;
1828 struct community *merge;
1829 struct community *gshut;
1830
1831 old = bgp_attr_get_community(attr);
1832 gshut = community_str2com("graceful-shutdown");
1833
1834 assert(gshut);
1835
1836 if (old) {
1837 merge = community_merge(community_dup(old), gshut);
1838
1839 if (old->refcnt == 0)
1840 community_free(&old);
1841
1842 new = community_uniq_sort(merge);
1843 community_free(&merge);
1844 } else {
1845 new = community_dup(gshut);
1846 }
1847
1848 community_free(&gshut);
1849 bgp_attr_set_community(attr, new);
1850
1851 /* When we add the graceful-shutdown community we must also
1852 * lower the local-preference */
1853 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1854 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1855 }
1856
1857
1858 /* Notify BGP Conditional advertisement scanner process. */
1859 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1860 {
1861 struct peer *peer = SUBGRP_PEER(subgrp);
1862 afi_t afi = SUBGRP_AFI(subgrp);
1863 safi_t safi = SUBGRP_SAFI(subgrp);
1864 struct bgp_filter *filter = &peer->filter[afi][safi];
1865
1866 if (!ADVERTISE_MAP_NAME(filter))
1867 return;
1868
1869 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1870 return;
1871
1872 peer->advmap_table_change = true;
1873 }
1874
1875
1876 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1877 {
1878 if (family == AF_INET) {
1879 attr->nexthop.s_addr = INADDR_ANY;
1880 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1881 }
1882 if (family == AF_INET6)
1883 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1884 if (family == AF_EVPN)
1885 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1886 }
1887
1888 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1889 struct update_subgroup *subgrp,
1890 const struct prefix *p, struct attr *attr,
1891 struct attr *post_attr)
1892 {
1893 struct bgp_filter *filter;
1894 struct peer *from;
1895 struct peer *peer;
1896 struct peer *onlypeer;
1897 struct bgp *bgp;
1898 struct attr *piattr;
1899 route_map_result_t ret;
1900 int transparent;
1901 int reflect;
1902 afi_t afi;
1903 safi_t safi;
1904 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1905 bool nh_reset = false;
1906 uint64_t cum_bw;
1907
1908 if (DISABLE_BGP_ANNOUNCE)
1909 return false;
1910
1911 afi = SUBGRP_AFI(subgrp);
1912 safi = SUBGRP_SAFI(subgrp);
1913 peer = SUBGRP_PEER(subgrp);
1914 onlypeer = NULL;
1915 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1916 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1917
1918 from = pi->peer;
1919 filter = &peer->filter[afi][safi];
1920 bgp = SUBGRP_INST(subgrp);
1921 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1922 : pi->attr;
1923
1924 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
1925 peer->pmax_out[afi][safi] != 0 &&
1926 subgrp->pscount >= peer->pmax_out[afi][safi]) {
1927 if (BGP_DEBUG(update, UPDATE_OUT) ||
1928 BGP_DEBUG(update, UPDATE_PREFIX)) {
1929 zlog_debug("%s reached maximum prefix to be send (%u)",
1930 peer->host, peer->pmax_out[afi][safi]);
1931 }
1932 return false;
1933 }
1934
1935 #ifdef ENABLE_BGP_VNC
1936 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1937 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1938 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1939
1940 /*
1941 * direct and direct_ext type routes originate internally even
1942 * though they can have peer pointers that reference other
1943 * systems
1944 */
1945 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1946 __func__, p);
1947 samepeer_safe = 1;
1948 }
1949 #endif
1950
1951 if (((afi == AFI_IP) || (afi == AFI_IP6))
1952 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1953 && (pi->type == ZEBRA_ROUTE_BGP)
1954 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1955
1956 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1957
1958 samepeer_safe = 1;
1959 }
1960
1961 /* With addpath we may be asked to TX all kinds of paths so make sure
1962 * pi is valid */
1963 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1964 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1965 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1966 return false;
1967 }
1968
1969 /* If this is not the bestpath then check to see if there is an enabled
1970 * addpath
1971 * feature that requires us to advertise it */
1972 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1973 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1974 return false;
1975 }
1976 }
1977
1978 /* Aggregate-address suppress check. */
1979 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1980 return false;
1981
1982 /*
1983 * If we are doing VRF 2 VRF leaking via the import
1984 * statement, we want to prevent the route going
1985 * off box as that the RT and RD created are localy
1986 * significant and globaly useless.
1987 */
1988 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1989 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1990 return false;
1991
1992 /* If it's labeled safi, make sure the route has a valid label. */
1993 if (safi == SAFI_LABELED_UNICAST) {
1994 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1995 if (!bgp_is_valid_label(&label)) {
1996 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1997 zlog_debug("u%" PRIu64 ":s%" PRIu64
1998 " %pFX is filtered - no label (%p)",
1999 subgrp->update_group->id, subgrp->id,
2000 p, &label);
2001 return false;
2002 }
2003 }
2004
2005 /* Do not send back route to sender. */
2006 if (onlypeer && from == onlypeer) {
2007 return false;
2008 }
2009
2010 /* Do not send the default route in the BGP table if the neighbor is
2011 * configured for default-originate */
2012 if (CHECK_FLAG(peer->af_flags[afi][safi],
2013 PEER_FLAG_DEFAULT_ORIGINATE)) {
2014 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2015 return false;
2016 else if (p->family == AF_INET6 && p->prefixlen == 0)
2017 return false;
2018 }
2019
2020 /* Transparency check. */
2021 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2022 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2023 transparent = 1;
2024 else
2025 transparent = 0;
2026
2027 /* If community is not disabled check the no-export and local. */
2028 if (!transparent && bgp_community_filter(peer, piattr)) {
2029 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2030 zlog_debug("%s: community filter check fail for %pFX",
2031 __func__, p);
2032 return false;
2033 }
2034
2035 /* If the attribute has originator-id and it is same as remote
2036 peer's id. */
2037 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2038 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2039 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2040 zlog_debug(
2041 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2042 onlypeer, p);
2043 return false;
2044 }
2045
2046 /* ORF prefix-list filter check */
2047 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2048 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2049 || CHECK_FLAG(peer->af_cap[afi][safi],
2050 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2051 if (peer->orf_plist[afi][safi]) {
2052 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2053 == PREFIX_DENY) {
2054 if (bgp_debug_update(NULL, p,
2055 subgrp->update_group, 0))
2056 zlog_debug(
2057 "%pBP [Update:SEND] %pFX is filtered via ORF",
2058 peer, p);
2059 return false;
2060 }
2061 }
2062
2063 /* Output filter check. */
2064 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2065 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2066 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2067 p);
2068 return false;
2069 }
2070
2071 /* AS path loop check. */
2072 if (onlypeer && onlypeer->as_path_loop_detection
2073 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2074 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2075 zlog_debug(
2076 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2077 onlypeer, onlypeer->as);
2078 return false;
2079 }
2080
2081 /* If we're a CONFED we need to loop check the CONFED ID too */
2082 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2083 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
2084 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2085 zlog_debug(
2086 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2087 peer, bgp->confed_id);
2088 return false;
2089 }
2090 }
2091
2092 /* Route-Reflect check. */
2093 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2094 reflect = 1;
2095 else
2096 reflect = 0;
2097
2098 /* IBGP reflection check. */
2099 if (reflect && !samepeer_safe) {
2100 /* A route from a Client peer. */
2101 if (CHECK_FLAG(from->af_flags[afi][safi],
2102 PEER_FLAG_REFLECTOR_CLIENT)) {
2103 /* Reflect to all the Non-Client peers and also to the
2104 Client peers other than the originator. Originator
2105 check
2106 is already done. So there is noting to do. */
2107 /* no bgp client-to-client reflection check. */
2108 if (CHECK_FLAG(bgp->flags,
2109 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2110 if (CHECK_FLAG(peer->af_flags[afi][safi],
2111 PEER_FLAG_REFLECTOR_CLIENT))
2112 return false;
2113 } else {
2114 /* A route from a Non-client peer. Reflect to all other
2115 clients. */
2116 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2117 PEER_FLAG_REFLECTOR_CLIENT))
2118 return false;
2119 }
2120 }
2121
2122 /* For modify attribute, copy it to temporary structure.
2123 * post_attr comes from BGP conditional advertisements, where
2124 * attributes are already processed by advertise-map route-map,
2125 * and this needs to be saved instead of overwriting from the
2126 * path attributes.
2127 */
2128 if (post_attr)
2129 *attr = *post_attr;
2130 else
2131 *attr = *piattr;
2132
2133 /* If local-preference is not set. */
2134 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2135 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2136 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2137 attr->local_pref = bgp->default_local_pref;
2138 }
2139
2140 /* If originator-id is not set and the route is to be reflected,
2141 set the originator id */
2142 if (reflect
2143 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2144 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2145 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2146 }
2147
2148 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2149 */
2150 if (peer->sort == BGP_PEER_EBGP
2151 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2152 if (from != bgp->peer_self && !transparent
2153 && !CHECK_FLAG(peer->af_flags[afi][safi],
2154 PEER_FLAG_MED_UNCHANGED))
2155 attr->flag &=
2156 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2157 }
2158
2159 /* Since the nexthop attribute can vary per peer, it is not explicitly
2160 * set
2161 * in announce check, only certain flags and length (or number of
2162 * nexthops
2163 * -- for IPv6/MP_REACH) are set here in order to guide the update
2164 * formation
2165 * code in setting the nexthop(s) on a per peer basis in
2166 * reformat_peer().
2167 * Typically, the source nexthop in the attribute is preserved but in
2168 * the
2169 * scenarios where we know it will always be overwritten, we reset the
2170 * nexthop to "0" in an attempt to achieve better Update packing. An
2171 * example of this is when a prefix from each of 2 IBGP peers needs to
2172 * be
2173 * announced to an EBGP peer (and they have the same attributes barring
2174 * their nexthop).
2175 */
2176 if (reflect)
2177 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2178
2179 #define NEXTHOP_IS_V6 \
2180 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2181 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2182 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2183 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2184
2185 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2186 * if
2187 * the peer (group) is configured to receive link-local nexthop
2188 * unchanged
2189 * and it is available in the prefix OR we're not reflecting the route,
2190 * link-local nexthop address is valid and
2191 * the peer (group) to whom we're going to announce is on a shared
2192 * network
2193 * and this is either a self-originated route or the peer is EBGP.
2194 * By checking if nexthop LL address is valid we are sure that
2195 * we do not announce LL address as `::`.
2196 */
2197 if (NEXTHOP_IS_V6) {
2198 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2199 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2200 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2201 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2202 || (!reflect && !transparent
2203 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2204 && peer->shared_network
2205 && (from == bgp->peer_self
2206 || peer->sort == BGP_PEER_EBGP))) {
2207 attr->mp_nexthop_len =
2208 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2209 }
2210
2211 /* Clear off link-local nexthop in source, whenever it is not
2212 * needed to
2213 * ensure more prefixes share the same attribute for
2214 * announcement.
2215 */
2216 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2217 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2218 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2219 }
2220
2221 if (bgp_check_role_applicability(afi, safi) &&
2222 bgp_otc_egress(peer, attr))
2223 return false;
2224
2225 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2226 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2227
2228 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2229 filter->advmap.aname &&
2230 route_map_lookup_by_name(filter->advmap.aname)) {
2231 struct bgp_path_info rmap_path = {0};
2232 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2233 struct attr dummy_attr = *attr;
2234
2235 /* Fill temp path_info */
2236 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2237 pi, peer, &dummy_attr);
2238
2239 struct route_map *amap =
2240 route_map_lookup_by_name(filter->advmap.aname);
2241
2242 ret = route_map_apply(amap, p, &rmap_path);
2243
2244 bgp_attr_flush(&dummy_attr);
2245
2246 /*
2247 * The conditional advertisement mode is Withdraw and this
2248 * prefix is a conditional prefix. Don't advertise it
2249 */
2250 if (ret == RMAP_PERMITMATCH)
2251 return false;
2252 }
2253
2254 /* Route map & unsuppress-map apply. */
2255 if (!post_attr &&
2256 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2257 struct bgp_path_info rmap_path = {0};
2258 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2259 struct attr dummy_attr = {0};
2260
2261 /* Fill temp path_info */
2262 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2263 pi, peer, attr);
2264
2265 /* don't confuse inbound and outbound setting */
2266 RESET_FLAG(attr->rmap_change_flags);
2267
2268 /*
2269 * The route reflector is not allowed to modify the attributes
2270 * of the reflected IBGP routes unless explicitly allowed.
2271 */
2272 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2273 && !CHECK_FLAG(bgp->flags,
2274 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2275 dummy_attr = *attr;
2276 rmap_path.attr = &dummy_attr;
2277 }
2278
2279 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2280
2281 if (bgp_path_suppressed(pi))
2282 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2283 &rmap_path);
2284 else
2285 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2286 &rmap_path);
2287
2288 bgp_attr_flush(&dummy_attr);
2289 peer->rmap_type = 0;
2290
2291 if (ret == RMAP_DENYMATCH) {
2292 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2293 zlog_debug(
2294 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2295 peer, p, ROUTE_MAP_OUT_NAME(filter));
2296 bgp_attr_flush(rmap_path.attr);
2297 return false;
2298 }
2299 }
2300
2301 /* RFC 8212 to prevent route leaks.
2302 * This specification intends to improve this situation by requiring the
2303 * explicit configuration of both BGP Import and Export Policies for any
2304 * External BGP (EBGP) session such as customers, peers, or
2305 * confederation boundaries for all enabled address families. Through
2306 * codification of the aforementioned requirement, operators will
2307 * benefit from consistent behavior across different BGP
2308 * implementations.
2309 */
2310 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2311 if (!bgp_outbound_policy_exists(peer, filter)) {
2312 if (monotime_since(&bgp->ebgprequirespolicywarning,
2313 NULL) > FIFTEENMINUTE2USEC ||
2314 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2315 zlog_warn(
2316 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2317 monotime(&bgp->ebgprequirespolicywarning);
2318 }
2319 return false;
2320 }
2321
2322 /* draft-ietf-idr-deprecate-as-set-confed-set
2323 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2324 * Eventually, This document (if approved) updates RFC 4271
2325 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2326 * and obsoletes RFC 6472.
2327 */
2328 if (peer->bgp->reject_as_sets)
2329 if (aspath_check_as_sets(attr->aspath))
2330 return false;
2331
2332 /* If neighbor sso is configured, then check if the route has
2333 * SoO extended community and validate against the configured
2334 * one. If they match, do not announce, to prevent routing
2335 * loops.
2336 */
2337 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2338 peer->soo[afi][safi]) {
2339 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2340 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2341
2342 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2343 ECOMMUNITY_SITE_ORIGIN) ||
2344 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2345 ECOMMUNITY_SITE_ORIGIN)) &&
2346 ecommunity_include(ecomm, ecomm_soo)) {
2347 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2348 zlog_debug(
2349 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2350 peer, p, ecommunity_str(ecomm_soo));
2351 return false;
2352 }
2353 }
2354
2355 /* Codification of AS 0 Processing */
2356 if (aspath_check_as_zero(attr->aspath))
2357 return false;
2358
2359 if (bgp_in_graceful_shutdown(bgp)) {
2360 if (peer->sort == BGP_PEER_IBGP
2361 || peer->sort == BGP_PEER_CONFED) {
2362 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2363 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2364 } else {
2365 bgp_attr_add_gshut_community(attr);
2366 }
2367 }
2368
2369 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2370 * Capability" to a neighbor MUST perform the following upon receiving
2371 * a route from that neighbor with the "LLGR_STALE" community, or upon
2372 * attaching the "LLGR_STALE" community itself per Section 4.2:
2373 *
2374 * The route SHOULD NOT be advertised to any neighbor from which the
2375 * Long-lived Graceful Restart Capability has not been received.
2376 */
2377 if (bgp_attr_get_community(attr) &&
2378 community_include(bgp_attr_get_community(attr),
2379 COMMUNITY_LLGR_STALE) &&
2380 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2381 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2382 return false;
2383
2384 /* After route-map has been applied, we check to see if the nexthop to
2385 * be carried in the attribute (that is used for the announcement) can
2386 * be cleared off or not. We do this in all cases where we would be
2387 * setting the nexthop to "ourselves". For IPv6, we only need to
2388 * consider
2389 * the global nexthop here; the link-local nexthop would have been
2390 * cleared
2391 * already, and if not, it is required by the update formation code.
2392 * Also see earlier comments in this function.
2393 */
2394 /*
2395 * If route-map has performed some operation on the nexthop or the peer
2396 * configuration says to pass it unchanged, we cannot reset the nexthop
2397 * here, so only attempt to do it if these aren't true. Note that the
2398 * route-map handler itself might have cleared the nexthop, if for
2399 * example,
2400 * it is configured as 'peer-address'.
2401 */
2402 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2403 piattr->rmap_change_flags)
2404 && !transparent
2405 && !CHECK_FLAG(peer->af_flags[afi][safi],
2406 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2407 /* We can reset the nexthop, if setting (or forcing) it to
2408 * 'self' */
2409 if (CHECK_FLAG(peer->af_flags[afi][safi],
2410 PEER_FLAG_NEXTHOP_SELF)
2411 || CHECK_FLAG(peer->af_flags[afi][safi],
2412 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2413 if (!reflect
2414 || CHECK_FLAG(peer->af_flags[afi][safi],
2415 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2416 subgroup_announce_reset_nhop(
2417 (peer_cap_enhe(peer, afi, safi)
2418 ? AF_INET6
2419 : p->family),
2420 attr);
2421 nh_reset = true;
2422 }
2423 } else if (peer->sort == BGP_PEER_EBGP) {
2424 /* Can also reset the nexthop if announcing to EBGP, but
2425 * only if
2426 * no peer in the subgroup is on a shared subnet.
2427 * Note: 3rd party nexthop currently implemented for
2428 * IPv4 only.
2429 */
2430 if ((p->family == AF_INET) &&
2431 (!bgp_subgrp_multiaccess_check_v4(
2432 piattr->nexthop,
2433 subgrp, from))) {
2434 subgroup_announce_reset_nhop(
2435 (peer_cap_enhe(peer, afi, safi)
2436 ? AF_INET6
2437 : p->family),
2438 attr);
2439 nh_reset = true;
2440 }
2441
2442 if ((p->family == AF_INET6) &&
2443 (!bgp_subgrp_multiaccess_check_v6(
2444 piattr->mp_nexthop_global,
2445 subgrp, from))) {
2446 subgroup_announce_reset_nhop(
2447 (peer_cap_enhe(peer, afi, safi)
2448 ? AF_INET6
2449 : p->family),
2450 attr);
2451 nh_reset = true;
2452 }
2453
2454
2455
2456 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2457 /*
2458 * This flag is used for leaked vpn-vrf routes
2459 */
2460 int family = p->family;
2461
2462 if (peer_cap_enhe(peer, afi, safi))
2463 family = AF_INET6;
2464
2465 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2466 zlog_debug(
2467 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2468 __func__, family2str(family));
2469 subgroup_announce_reset_nhop(family, attr);
2470 nh_reset = true;
2471 }
2472 }
2473
2474 /* If IPv6/MP and nexthop does not have any override and happens
2475 * to
2476 * be a link-local address, reset it so that we don't pass along
2477 * the
2478 * source's link-local IPv6 address to recipients who may not be
2479 * on
2480 * the same interface.
2481 */
2482 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2483 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2484 subgroup_announce_reset_nhop(AF_INET6, attr);
2485 nh_reset = true;
2486 }
2487 }
2488
2489 /* If this is an iBGP, send Origin Validation State (OVS)
2490 * extended community (rfc8097).
2491 */
2492 if (peer->sort == BGP_PEER_IBGP) {
2493 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2494
2495 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2496
2497 if (rpki_state != RPKI_NOT_BEING_USED)
2498 bgp_attr_set_ecommunity(
2499 attr, ecommunity_add_origin_validation_state(
2500 rpki_state,
2501 bgp_attr_get_ecommunity(attr)));
2502 }
2503
2504 /*
2505 * When the next hop is set to ourselves, if all multipaths have
2506 * link-bandwidth announce the cumulative bandwidth as that makes
2507 * the most sense. However, don't modify if the link-bandwidth has
2508 * been explicitly set by user policy.
2509 */
2510 if (nh_reset &&
2511 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2512 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2513 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2514 bgp_attr_set_ecommunity(
2515 attr,
2516 ecommunity_replace_linkbw(
2517 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2518 CHECK_FLAG(
2519 peer->flags,
2520 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2521
2522 return true;
2523 }
2524
2525 static void bgp_route_select_timer_expire(struct thread *thread)
2526 {
2527 struct afi_safi_info *info;
2528 afi_t afi;
2529 safi_t safi;
2530 struct bgp *bgp;
2531
2532 info = THREAD_ARG(thread);
2533 afi = info->afi;
2534 safi = info->safi;
2535 bgp = info->bgp;
2536
2537 if (BGP_DEBUG(update, UPDATE_OUT))
2538 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2539 safi);
2540
2541 bgp->gr_info[afi][safi].t_route_select = NULL;
2542
2543 XFREE(MTYPE_TMP, info);
2544
2545 /* Best path selection */
2546 bgp_best_path_select_defer(bgp, afi, safi);
2547 }
2548
2549 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2550 struct bgp_maxpaths_cfg *mpath_cfg,
2551 struct bgp_path_info_pair *result, afi_t afi,
2552 safi_t safi)
2553 {
2554 struct bgp_path_info *new_select;
2555 struct bgp_path_info *old_select;
2556 struct bgp_path_info *pi;
2557 struct bgp_path_info *pi1;
2558 struct bgp_path_info *pi2;
2559 struct bgp_path_info *nextpi = NULL;
2560 int paths_eq, do_mpath, debug;
2561 struct list mp_list;
2562 char pfx_buf[PREFIX2STR_BUFFER];
2563 char path_buf[PATH_ADDPATH_STR_BUFFER];
2564
2565 bgp_mp_list_init(&mp_list);
2566 do_mpath =
2567 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2568
2569 debug = bgp_debug_bestpath(dest);
2570
2571 if (debug)
2572 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2573
2574 dest->reason = bgp_path_selection_none;
2575 /* bgp deterministic-med */
2576 new_select = NULL;
2577 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2578
2579 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2580 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2581 pi1 = pi1->next)
2582 bgp_path_info_unset_flag(dest, pi1,
2583 BGP_PATH_DMED_SELECTED);
2584
2585 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2586 pi1 = pi1->next) {
2587 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2588 continue;
2589 if (BGP_PATH_HOLDDOWN(pi1))
2590 continue;
2591 if (pi1->peer != bgp->peer_self)
2592 if (!peer_established(pi1->peer))
2593 continue;
2594
2595 new_select = pi1;
2596 if (pi1->next) {
2597 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2598 if (CHECK_FLAG(pi2->flags,
2599 BGP_PATH_DMED_CHECK))
2600 continue;
2601 if (BGP_PATH_HOLDDOWN(pi2))
2602 continue;
2603 if (pi2->peer != bgp->peer_self
2604 && !CHECK_FLAG(
2605 pi2->peer->sflags,
2606 PEER_STATUS_NSF_WAIT))
2607 if (pi2->peer->status
2608 != Established)
2609 continue;
2610
2611 if (!aspath_cmp_left(pi1->attr->aspath,
2612 pi2->attr->aspath)
2613 && !aspath_cmp_left_confed(
2614 pi1->attr->aspath,
2615 pi2->attr->aspath))
2616 continue;
2617
2618 if (bgp_path_info_cmp(
2619 bgp, pi2, new_select,
2620 &paths_eq, mpath_cfg, debug,
2621 pfx_buf, afi, safi,
2622 &dest->reason)) {
2623 bgp_path_info_unset_flag(
2624 dest, new_select,
2625 BGP_PATH_DMED_SELECTED);
2626 new_select = pi2;
2627 }
2628
2629 bgp_path_info_set_flag(
2630 dest, pi2, BGP_PATH_DMED_CHECK);
2631 }
2632 }
2633 bgp_path_info_set_flag(dest, new_select,
2634 BGP_PATH_DMED_CHECK);
2635 bgp_path_info_set_flag(dest, new_select,
2636 BGP_PATH_DMED_SELECTED);
2637
2638 if (debug) {
2639 bgp_path_info_path_with_addpath_rx_str(
2640 new_select, path_buf, sizeof(path_buf));
2641 zlog_debug(
2642 "%pBD(%s): %s is the bestpath from AS %u",
2643 dest, bgp->name_pretty, path_buf,
2644 aspath_get_first_as(
2645 new_select->attr->aspath));
2646 }
2647 }
2648 }
2649
2650 /* Check old selected route and new selected route. */
2651 old_select = NULL;
2652 new_select = NULL;
2653 for (pi = bgp_dest_get_bgp_path_info(dest);
2654 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2655 enum bgp_path_selection_reason reason;
2656
2657 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2658 old_select = pi;
2659
2660 if (BGP_PATH_HOLDDOWN(pi)) {
2661 /* reap REMOVED routes, if needs be
2662 * selected route must stay for a while longer though
2663 */
2664 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2665 && (pi != old_select))
2666 bgp_path_info_reap(dest, pi);
2667
2668 if (debug)
2669 zlog_debug("%s: pi %p in holddown", __func__,
2670 pi);
2671
2672 continue;
2673 }
2674
2675 if (pi->peer && pi->peer != bgp->peer_self
2676 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2677 if (!peer_established(pi->peer)) {
2678
2679 if (debug)
2680 zlog_debug(
2681 "%s: pi %p non self peer %s not estab state",
2682 __func__, pi, pi->peer->host);
2683
2684 continue;
2685 }
2686
2687 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2688 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2689 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2690 if (debug)
2691 zlog_debug("%s: pi %p dmed", __func__, pi);
2692 continue;
2693 }
2694
2695 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2696
2697 reason = dest->reason;
2698 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2699 debug, pfx_buf, afi, safi,
2700 &dest->reason)) {
2701 if (new_select == NULL &&
2702 reason != bgp_path_selection_none)
2703 dest->reason = reason;
2704 new_select = pi;
2705 }
2706 }
2707
2708 /* Now that we know which path is the bestpath see if any of the other
2709 * paths
2710 * qualify as multipaths
2711 */
2712 if (debug) {
2713 if (new_select)
2714 bgp_path_info_path_with_addpath_rx_str(
2715 new_select, path_buf, sizeof(path_buf));
2716 else
2717 snprintf(path_buf, sizeof(path_buf), "NONE");
2718 zlog_debug(
2719 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2720 dest, bgp->name_pretty, path_buf,
2721 old_select ? old_select->peer->host : "NONE");
2722 }
2723
2724 if (do_mpath && new_select) {
2725 for (pi = bgp_dest_get_bgp_path_info(dest);
2726 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2727
2728 if (debug)
2729 bgp_path_info_path_with_addpath_rx_str(
2730 pi, path_buf, sizeof(path_buf));
2731
2732 if (pi == new_select) {
2733 if (debug)
2734 zlog_debug(
2735 "%pBD(%s): %s is the bestpath, add to the multipath list",
2736 dest, bgp->name_pretty,
2737 path_buf);
2738 bgp_mp_list_add(&mp_list, pi);
2739 continue;
2740 }
2741
2742 if (BGP_PATH_HOLDDOWN(pi))
2743 continue;
2744
2745 if (pi->peer && pi->peer != bgp->peer_self
2746 && !CHECK_FLAG(pi->peer->sflags,
2747 PEER_STATUS_NSF_WAIT))
2748 if (!peer_established(pi->peer))
2749 continue;
2750
2751 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2752 if (debug)
2753 zlog_debug(
2754 "%pBD: %s has the same nexthop as the bestpath, skip it",
2755 dest, path_buf);
2756 continue;
2757 }
2758
2759 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2760 mpath_cfg, debug, pfx_buf, afi, safi,
2761 &dest->reason);
2762
2763 if (paths_eq) {
2764 if (debug)
2765 zlog_debug(
2766 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2767 dest, path_buf);
2768 bgp_mp_list_add(&mp_list, pi);
2769 }
2770 }
2771 }
2772
2773 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2774 mpath_cfg);
2775 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2776 bgp_mp_list_clear(&mp_list);
2777
2778 bgp_addpath_update_ids(bgp, dest, afi, safi);
2779
2780 result->old = old_select;
2781 result->new = new_select;
2782
2783 return;
2784 }
2785
2786 /*
2787 * A new route/change in bestpath of an existing route. Evaluate the path
2788 * for advertisement to the subgroup.
2789 */
2790 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2791 struct bgp_path_info *selected,
2792 struct bgp_dest *dest,
2793 uint32_t addpath_tx_id)
2794 {
2795 const struct prefix *p;
2796 struct peer *onlypeer;
2797 struct attr attr;
2798 afi_t afi;
2799 safi_t safi;
2800 struct bgp *bgp;
2801 bool advertise;
2802
2803 p = bgp_dest_get_prefix(dest);
2804 afi = SUBGRP_AFI(subgrp);
2805 safi = SUBGRP_SAFI(subgrp);
2806 bgp = SUBGRP_INST(subgrp);
2807 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2808 : NULL);
2809
2810 if (BGP_DEBUG(update, UPDATE_OUT))
2811 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2812
2813 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2814 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2815 PEER_STATUS_ORF_WAIT_REFRESH))
2816 return;
2817
2818 memset(&attr, 0, sizeof(attr));
2819 /* It's initialized in bgp_announce_check() */
2820
2821 /* Announcement to the subgroup. If the route is filtered withdraw it.
2822 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2823 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2824 * route
2825 */
2826 advertise = bgp_check_advertise(bgp, dest);
2827
2828 if (selected) {
2829 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2830 NULL)) {
2831 /* Route is selected, if the route is already installed
2832 * in FIB, then it is advertised
2833 */
2834 if (advertise) {
2835 if (!bgp_check_withdrawal(bgp, dest))
2836 bgp_adj_out_set_subgroup(
2837 dest, subgrp, &attr, selected);
2838 else
2839 bgp_adj_out_unset_subgroup(
2840 dest, subgrp, 1, addpath_tx_id);
2841 }
2842 } else
2843 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2844 addpath_tx_id);
2845 }
2846
2847 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2848 else {
2849 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2850 }
2851 }
2852
2853 /*
2854 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2855 * This is called at the end of route processing.
2856 */
2857 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2858 {
2859 struct bgp_path_info *pi;
2860
2861 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2862 if (BGP_PATH_HOLDDOWN(pi))
2863 continue;
2864 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2865 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2866 }
2867 }
2868
2869 /*
2870 * Has the route changed from the RIB's perspective? This is invoked only
2871 * if the route selection returns the same best route as earlier - to
2872 * determine if we need to update zebra or not.
2873 */
2874 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2875 {
2876 struct bgp_path_info *mpinfo;
2877
2878 /* If this is multipath, check all selected paths for any nexthop
2879 * change or attribute change. Some attribute changes (e.g., community)
2880 * aren't of relevance to the RIB, but we'll update zebra to ensure
2881 * we handle the case of BGP nexthop change. This is the behavior
2882 * when the best path has an attribute change anyway.
2883 */
2884 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2885 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2886 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2887 return true;
2888
2889 /*
2890 * If this is multipath, check all selected paths for any nexthop change
2891 */
2892 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2893 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2894 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2895 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2896 return true;
2897 }
2898
2899 /* Nothing has changed from the RIB's perspective. */
2900 return false;
2901 }
2902
2903 struct bgp_process_queue {
2904 struct bgp *bgp;
2905 STAILQ_HEAD(, bgp_dest) pqueue;
2906 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2907 unsigned int flags;
2908 unsigned int queued;
2909 };
2910
2911 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2912 safi_t safi, struct bgp_dest *dest,
2913 struct bgp_path_info *new_select,
2914 struct bgp_path_info *old_select)
2915 {
2916 const struct prefix *p = bgp_dest_get_prefix(dest);
2917
2918 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2919 return;
2920
2921 if (advertise_type5_routes(bgp, afi) && new_select
2922 && is_route_injectable_into_evpn(new_select)) {
2923
2924 /* apply the route-map */
2925 if (bgp->adv_cmd_rmap[afi][safi].map) {
2926 route_map_result_t ret;
2927 struct bgp_path_info rmap_path;
2928 struct bgp_path_info_extra rmap_path_extra;
2929 struct attr dummy_attr;
2930
2931 dummy_attr = *new_select->attr;
2932
2933 /* Fill temp path_info */
2934 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2935 new_select, new_select->peer,
2936 &dummy_attr);
2937
2938 RESET_FLAG(dummy_attr.rmap_change_flags);
2939
2940 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2941 p, &rmap_path);
2942
2943 if (ret == RMAP_DENYMATCH) {
2944 bgp_attr_flush(&dummy_attr);
2945 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2946 safi);
2947 } else
2948 bgp_evpn_advertise_type5_route(
2949 bgp, p, &dummy_attr, afi, safi);
2950 } else {
2951 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2952 afi, safi);
2953 }
2954 } else if (advertise_type5_routes(bgp, afi) && old_select
2955 && is_route_injectable_into_evpn(old_select))
2956 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2957 }
2958
2959 /*
2960 * Utility to determine whether a particular path_info should use
2961 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
2962 * in a path where we basically _know_ this is a BGP-LU route.
2963 */
2964 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
2965 {
2966 /* Certain types get imp null; so do paths where the nexthop is
2967 * not labeled.
2968 */
2969 if (new_select->sub_type == BGP_ROUTE_STATIC
2970 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2971 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
2972 return true;
2973 else if (new_select->extra == NULL ||
2974 !bgp_is_valid_label(&new_select->extra->label[0]))
2975 /* TODO -- should be configurable? */
2976 return true;
2977 else
2978 return false;
2979 }
2980
2981 /*
2982 * old_select = The old best path
2983 * new_select = the new best path
2984 *
2985 * if (!old_select && new_select)
2986 * We are sending new information on.
2987 *
2988 * if (old_select && new_select) {
2989 * if (new_select != old_select)
2990 * We have a new best path send a change
2991 * else
2992 * We've received a update with new attributes that needs
2993 * to be passed on.
2994 * }
2995 *
2996 * if (old_select && !new_select)
2997 * We have no eligible route that we can announce or the rn
2998 * is being removed.
2999 */
3000 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3001 afi_t afi, safi_t safi)
3002 {
3003 struct bgp_path_info *new_select;
3004 struct bgp_path_info *old_select;
3005 struct bgp_path_info_pair old_and_new;
3006 int debug = 0;
3007
3008 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3009 if (dest)
3010 debug = bgp_debug_bestpath(dest);
3011 if (debug)
3012 zlog_debug(
3013 "%s: bgp delete in progress, ignoring event, p=%pBD",
3014 __func__, dest);
3015 return;
3016 }
3017 /* Is it end of initial update? (after startup) */
3018 if (!dest) {
3019 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3020 sizeof(bgp->update_delay_zebra_resume_time));
3021
3022 bgp->main_zebra_update_hold = 0;
3023 FOREACH_AFI_SAFI (afi, safi) {
3024 if (bgp_fibupd_safi(safi))
3025 bgp_zebra_announce_table(bgp, afi, safi);
3026 }
3027 bgp->main_peers_update_hold = 0;
3028
3029 bgp_start_routeadv(bgp);
3030 return;
3031 }
3032
3033 const struct prefix *p = bgp_dest_get_prefix(dest);
3034
3035 debug = bgp_debug_bestpath(dest);
3036 if (debug)
3037 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3038 dest, bgp->name_pretty, afi2str(afi),
3039 safi2str(safi));
3040
3041 /* The best path calculation for the route is deferred if
3042 * BGP_NODE_SELECT_DEFER is set
3043 */
3044 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3045 if (BGP_DEBUG(update, UPDATE_OUT))
3046 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3047 return;
3048 }
3049
3050 /* Best path selection. */
3051 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3052 afi, safi);
3053 old_select = old_and_new.old;
3054 new_select = old_and_new.new;
3055
3056 /* Do we need to allocate or free labels?
3057 * Right now, since we only deal with per-prefix labels, it is not
3058 * necessary to do this upon changes to best path. Exceptions:
3059 * - label index has changed -> recalculate resulting label
3060 * - path_info sub_type changed -> switch to/from implicit-null
3061 * - no valid label (due to removed static label binding) -> get new one
3062 */
3063 if (bgp->allocate_mpls_labels[afi][safi]) {
3064 if (new_select) {
3065 if (!old_select
3066 || bgp_label_index_differs(new_select, old_select)
3067 || new_select->sub_type != old_select->sub_type
3068 || !bgp_is_valid_label(&dest->local_label)) {
3069 /* Enforced penultimate hop popping:
3070 * implicit-null for local routes, aggregate
3071 * and redistributed routes
3072 */
3073 if (bgp_lu_need_imp_null(new_select)) {
3074 if (CHECK_FLAG(
3075 dest->flags,
3076 BGP_NODE_REGISTERED_FOR_LABEL)
3077 || CHECK_FLAG(
3078 dest->flags,
3079 BGP_NODE_LABEL_REQUESTED))
3080 bgp_unregister_for_label(dest);
3081 dest->local_label = mpls_lse_encode(
3082 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3083 1);
3084 bgp_set_valid_label(&dest->local_label);
3085 } else
3086 bgp_register_for_label(dest,
3087 new_select);
3088 }
3089 } else if (CHECK_FLAG(dest->flags,
3090 BGP_NODE_REGISTERED_FOR_LABEL)
3091 || CHECK_FLAG(dest->flags,
3092 BGP_NODE_LABEL_REQUESTED)) {
3093 bgp_unregister_for_label(dest);
3094 }
3095 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3096 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3097 bgp_unregister_for_label(dest);
3098 }
3099
3100 if (debug)
3101 zlog_debug(
3102 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3103 __func__, dest, bgp->name_pretty, afi2str(afi),
3104 safi2str(safi), old_select, new_select);
3105
3106 /* If best route remains the same and this is not due to user-initiated
3107 * clear, see exactly what needs to be done.
3108 */
3109 if (old_select && old_select == new_select
3110 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3111 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3112 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3113 if (bgp_zebra_has_route_changed(old_select)) {
3114 #ifdef ENABLE_BGP_VNC
3115 vnc_import_bgp_add_route(bgp, p, old_select);
3116 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3117 #endif
3118 if (bgp_fibupd_safi(safi)
3119 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3120
3121 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3122 && new_select->sub_type == BGP_ROUTE_NORMAL)
3123 SET_FLAG(dest->flags,
3124 BGP_NODE_FIB_INSTALL_PENDING);
3125
3126 if (new_select->type == ZEBRA_ROUTE_BGP
3127 && (new_select->sub_type == BGP_ROUTE_NORMAL
3128 || new_select->sub_type
3129 == BGP_ROUTE_IMPORTED))
3130
3131 bgp_zebra_announce(dest, p, old_select,
3132 bgp, afi, safi);
3133 }
3134 }
3135
3136 /* If there is a change of interest to peers, reannounce the
3137 * route. */
3138 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3139 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3140 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3141 group_announce_route(bgp, afi, safi, dest, new_select);
3142
3143 /* unicast routes must also be annouced to
3144 * labeled-unicast update-groups */
3145 if (safi == SAFI_UNICAST)
3146 group_announce_route(bgp, afi,
3147 SAFI_LABELED_UNICAST, dest,
3148 new_select);
3149
3150 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3151 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3152 }
3153
3154 /* advertise/withdraw type-5 routes */
3155 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3156 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3157 bgp_process_evpn_route_injection(
3158 bgp, afi, safi, dest, old_select, old_select);
3159
3160 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3161 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3162 bgp_zebra_clear_route_change_flags(dest);
3163 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3164 return;
3165 }
3166
3167 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3168 */
3169 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3170
3171 /* bestpath has changed; bump version */
3172 if (old_select || new_select) {
3173 bgp_bump_version(dest);
3174
3175 if (!bgp->t_rmap_def_originate_eval) {
3176 bgp_lock(bgp);
3177 thread_add_timer(
3178 bm->master,
3179 update_group_refresh_default_originate_route_map,
3180 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3181 &bgp->t_rmap_def_originate_eval);
3182 }
3183 }
3184
3185 if (old_select)
3186 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3187 if (new_select) {
3188 if (debug)
3189 zlog_debug("%s: setting SELECTED flag", __func__);
3190 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3191 bgp_path_info_unset_flag(dest, new_select,
3192 BGP_PATH_ATTR_CHANGED);
3193 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3194 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3195 }
3196
3197 #ifdef ENABLE_BGP_VNC
3198 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3199 if (old_select != new_select) {
3200 if (old_select) {
3201 vnc_import_bgp_exterior_del_route(bgp, p,
3202 old_select);
3203 vnc_import_bgp_del_route(bgp, p, old_select);
3204 }
3205 if (new_select) {
3206 vnc_import_bgp_exterior_add_route(bgp, p,
3207 new_select);
3208 vnc_import_bgp_add_route(bgp, p, new_select);
3209 }
3210 }
3211 }
3212 #endif
3213
3214 group_announce_route(bgp, afi, safi, dest, new_select);
3215
3216 /* unicast routes must also be annouced to labeled-unicast update-groups
3217 */
3218 if (safi == SAFI_UNICAST)
3219 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3220 new_select);
3221
3222 /* FIB update. */
3223 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3224 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3225
3226 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3227 && (new_select->sub_type == BGP_ROUTE_NORMAL
3228 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3229 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3230
3231 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3232 SET_FLAG(dest->flags,
3233 BGP_NODE_FIB_INSTALL_PENDING);
3234
3235 /* if this is an evpn imported type-5 prefix,
3236 * we need to withdraw the route first to clear
3237 * the nh neigh and the RMAC entry.
3238 */
3239 if (old_select &&
3240 is_route_parent_evpn(old_select))
3241 bgp_zebra_withdraw(p, old_select, bgp, safi);
3242
3243 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3244 } else {
3245 /* Withdraw the route from the kernel. */
3246 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3247 && (old_select->sub_type == BGP_ROUTE_NORMAL
3248 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3249 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3250
3251 bgp_zebra_withdraw(p, old_select, bgp, safi);
3252 }
3253 }
3254
3255 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3256 old_select);
3257
3258 /* Clear any route change flags. */
3259 bgp_zebra_clear_route_change_flags(dest);
3260
3261 /* Reap old select bgp_path_info, if it has been removed */
3262 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3263 bgp_path_info_reap(dest, old_select);
3264
3265 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3266 return;
3267 }
3268
3269 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3270 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3271 {
3272 struct bgp_dest *dest;
3273 int cnt = 0;
3274 struct afi_safi_info *thread_info;
3275
3276 if (bgp->gr_info[afi][safi].t_route_select) {
3277 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3278
3279 thread_info = THREAD_ARG(t);
3280 XFREE(MTYPE_TMP, thread_info);
3281 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3282 }
3283
3284 if (BGP_DEBUG(update, UPDATE_OUT)) {
3285 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3286 get_afi_safi_str(afi, safi, false),
3287 bgp->gr_info[afi][safi].gr_deferred);
3288 }
3289
3290 /* Process the route list */
3291 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3292 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3293 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3294 dest = bgp_route_next(dest)) {
3295 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3296 continue;
3297
3298 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3299 bgp->gr_info[afi][safi].gr_deferred--;
3300 bgp_process_main_one(bgp, dest, afi, safi);
3301 cnt++;
3302 }
3303 /* If iteration stopped before the entire table was traversed then the
3304 * node needs to be unlocked.
3305 */
3306 if (dest) {
3307 bgp_dest_unlock_node(dest);
3308 dest = NULL;
3309 }
3310
3311 /* Send EOR message when all routes are processed */
3312 if (!bgp->gr_info[afi][safi].gr_deferred) {
3313 bgp_send_delayed_eor(bgp);
3314 /* Send route processing complete message to RIB */
3315 bgp_zebra_update(afi, safi, bgp->vrf_id,
3316 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3317 return;
3318 }
3319
3320 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3321
3322 thread_info->afi = afi;
3323 thread_info->safi = safi;
3324 thread_info->bgp = bgp;
3325
3326 /* If there are more routes to be processed, start the
3327 * selection timer
3328 */
3329 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3330 BGP_ROUTE_SELECT_DELAY,
3331 &bgp->gr_info[afi][safi].t_route_select);
3332 }
3333
3334 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3335 {
3336 struct bgp_process_queue *pqnode = data;
3337 struct bgp *bgp = pqnode->bgp;
3338 struct bgp_table *table;
3339 struct bgp_dest *dest;
3340
3341 /* eoiu marker */
3342 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3343 bgp_process_main_one(bgp, NULL, 0, 0);
3344 /* should always have dedicated wq call */
3345 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3346 return WQ_SUCCESS;
3347 }
3348
3349 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3350 dest = STAILQ_FIRST(&pqnode->pqueue);
3351 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3352 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3353 table = bgp_dest_table(dest);
3354 /* note, new DESTs may be added as part of processing */
3355 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3356
3357 bgp_dest_unlock_node(dest);
3358 bgp_table_unlock(table);
3359 }
3360
3361 return WQ_SUCCESS;
3362 }
3363
3364 static void bgp_processq_del(struct work_queue *wq, void *data)
3365 {
3366 struct bgp_process_queue *pqnode = data;
3367
3368 bgp_unlock(pqnode->bgp);
3369
3370 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3371 }
3372
3373 void bgp_process_queue_init(struct bgp *bgp)
3374 {
3375 if (!bgp->process_queue) {
3376 char name[BUFSIZ];
3377
3378 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3379 bgp->process_queue = work_queue_new(bm->master, name);
3380 }
3381
3382 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3383 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3384 bgp->process_queue->spec.max_retries = 0;
3385 bgp->process_queue->spec.hold = 50;
3386 /* Use a higher yield value of 50ms for main queue processing */
3387 bgp->process_queue->spec.yield = 50 * 1000L;
3388 }
3389
3390 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3391 {
3392 struct bgp_process_queue *pqnode;
3393
3394 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3395 sizeof(struct bgp_process_queue));
3396
3397 /* unlocked in bgp_processq_del */
3398 pqnode->bgp = bgp_lock(bgp);
3399 STAILQ_INIT(&pqnode->pqueue);
3400
3401 return pqnode;
3402 }
3403
3404 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3405 {
3406 #define ARBITRARY_PROCESS_QLEN 10000
3407 struct work_queue *wq = bgp->process_queue;
3408 struct bgp_process_queue *pqnode;
3409 int pqnode_reuse = 0;
3410
3411 /* already scheduled for processing? */
3412 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3413 return;
3414
3415 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3416 * the workqueue
3417 */
3418 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3419 if (BGP_DEBUG(update, UPDATE_OUT))
3420 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3421 dest);
3422 return;
3423 }
3424
3425 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3426 if (BGP_DEBUG(update, UPDATE_OUT))
3427 zlog_debug(
3428 "Soft reconfigure table in progress for route %p",
3429 dest);
3430 return;
3431 }
3432
3433 if (wq == NULL)
3434 return;
3435
3436 /* Add route nodes to an existing work queue item until reaching the
3437 limit only if is from the same BGP view and it's not an EOIU marker
3438 */
3439 if (work_queue_item_count(wq)) {
3440 struct work_queue_item *item = work_queue_last_item(wq);
3441 pqnode = item->data;
3442
3443 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3444 || pqnode->bgp != bgp
3445 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3446 pqnode = bgp_processq_alloc(bgp);
3447 else
3448 pqnode_reuse = 1;
3449 } else
3450 pqnode = bgp_processq_alloc(bgp);
3451 /* all unlocked in bgp_process_wq */
3452 bgp_table_lock(bgp_dest_table(dest));
3453
3454 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3455 bgp_dest_lock_node(dest);
3456
3457 /* can't be enqueued twice */
3458 assert(STAILQ_NEXT(dest, pq) == NULL);
3459 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3460 pqnode->queued++;
3461
3462 if (!pqnode_reuse)
3463 work_queue_add(wq, pqnode);
3464
3465 return;
3466 }
3467
3468 void bgp_add_eoiu_mark(struct bgp *bgp)
3469 {
3470 struct bgp_process_queue *pqnode;
3471
3472 if (bgp->process_queue == NULL)
3473 return;
3474
3475 pqnode = bgp_processq_alloc(bgp);
3476
3477 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3478 work_queue_add(bgp->process_queue, pqnode);
3479 }
3480
3481 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3482 {
3483 struct peer *peer;
3484
3485 peer = THREAD_ARG(thread);
3486 peer->t_pmax_restart = NULL;
3487
3488 if (bgp_debug_neighbor_events(peer))
3489 zlog_debug(
3490 "%s Maximum-prefix restart timer expired, restore peering",
3491 peer->host);
3492
3493 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3494 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3495 }
3496
3497 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3498 safi_t safi)
3499 {
3500 uint32_t count = 0;
3501 bool filtered = false;
3502 struct bgp_dest *dest;
3503 struct bgp_adj_in *ain;
3504 struct attr attr = {};
3505 struct bgp_table *table = peer->bgp->rib[afi][safi];
3506
3507 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3508 for (ain = dest->adj_in; ain; ain = ain->next) {
3509 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3510
3511 attr = *ain->attr;
3512
3513 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3514 == FILTER_DENY)
3515 filtered = true;
3516
3517 if (bgp_input_modifier(
3518 peer, rn_p, &attr, afi, safi,
3519 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3520 NULL, 0, NULL)
3521 == RMAP_DENY)
3522 filtered = true;
3523
3524 if (filtered)
3525 count++;
3526
3527 bgp_attr_flush(&attr);
3528 }
3529 }
3530
3531 return count;
3532 }
3533
3534 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3535 int always)
3536 {
3537 iana_afi_t pkt_afi;
3538 iana_safi_t pkt_safi;
3539 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3540 PEER_FLAG_MAX_PREFIX_FORCE))
3541 ? bgp_filtered_routes_count(peer, afi, safi)
3542 + peer->pcount[afi][safi]
3543 : peer->pcount[afi][safi];
3544
3545 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3546 return false;
3547
3548 if (pcount > peer->pmax[afi][safi]) {
3549 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3550 PEER_STATUS_PREFIX_LIMIT)
3551 && !always)
3552 return false;
3553
3554 zlog_info(
3555 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3556 get_afi_safi_str(afi, safi, false), peer, pcount,
3557 peer->pmax[afi][safi]);
3558 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3559
3560 if (CHECK_FLAG(peer->af_flags[afi][safi],
3561 PEER_FLAG_MAX_PREFIX_WARNING))
3562 return false;
3563
3564 /* Convert AFI, SAFI to values for packet. */
3565 pkt_afi = afi_int2iana(afi);
3566 pkt_safi = safi_int2iana(safi);
3567 {
3568 uint8_t ndata[7];
3569
3570 ndata[0] = (pkt_afi >> 8);
3571 ndata[1] = pkt_afi;
3572 ndata[2] = pkt_safi;
3573 ndata[3] = (peer->pmax[afi][safi] >> 24);
3574 ndata[4] = (peer->pmax[afi][safi] >> 16);
3575 ndata[5] = (peer->pmax[afi][safi] >> 8);
3576 ndata[6] = (peer->pmax[afi][safi]);
3577
3578 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3579 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3580 BGP_NOTIFY_CEASE_MAX_PREFIX,
3581 ndata, 7);
3582 }
3583
3584 /* Dynamic peers will just close their connection. */
3585 if (peer_dynamic_neighbor(peer))
3586 return true;
3587
3588 /* restart timer start */
3589 if (peer->pmax_restart[afi][safi]) {
3590 peer->v_pmax_restart =
3591 peer->pmax_restart[afi][safi] * 60;
3592
3593 if (bgp_debug_neighbor_events(peer))
3594 zlog_debug(
3595 "%pBP Maximum-prefix restart timer started for %d secs",
3596 peer, peer->v_pmax_restart);
3597
3598 BGP_TIMER_ON(peer->t_pmax_restart,
3599 bgp_maximum_prefix_restart_timer,
3600 peer->v_pmax_restart);
3601 }
3602
3603 return true;
3604 } else
3605 UNSET_FLAG(peer->af_sflags[afi][safi],
3606 PEER_STATUS_PREFIX_LIMIT);
3607
3608 if (pcount
3609 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3610 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3611 PEER_STATUS_PREFIX_THRESHOLD)
3612 && !always)
3613 return false;
3614
3615 zlog_info(
3616 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3617 get_afi_safi_str(afi, safi, false), peer, pcount,
3618 peer->pmax[afi][safi]);
3619 SET_FLAG(peer->af_sflags[afi][safi],
3620 PEER_STATUS_PREFIX_THRESHOLD);
3621 } else
3622 UNSET_FLAG(peer->af_sflags[afi][safi],
3623 PEER_STATUS_PREFIX_THRESHOLD);
3624 return false;
3625 }
3626
3627 /* Unconditionally remove the route from the RIB, without taking
3628 * damping into consideration (eg, because the session went down)
3629 */
3630 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3631 struct peer *peer, afi_t afi, safi_t safi)
3632 {
3633
3634 struct bgp *bgp = NULL;
3635 bool delete_route = false;
3636
3637 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3638 safi);
3639
3640 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3641 bgp_path_info_delete(dest, pi); /* keep historical info */
3642
3643 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3644 * flag
3645 */
3646 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3647 delete_route = true;
3648 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3649 delete_route = true;
3650 if (delete_route) {
3651 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3652 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3653 bgp = pi->peer->bgp;
3654 bgp->gr_info[afi][safi].gr_deferred--;
3655 }
3656 }
3657 }
3658
3659 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3660 bgp_process(peer->bgp, dest, afi, safi);
3661 }
3662
3663 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3664 struct peer *peer, afi_t afi, safi_t safi,
3665 struct prefix_rd *prd)
3666 {
3667 const struct prefix *p = bgp_dest_get_prefix(dest);
3668
3669 /* apply dampening, if result is suppressed, we'll be retaining
3670 * the bgp_path_info in the RIB for historical reference.
3671 */
3672 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3673 && peer->sort == BGP_PEER_EBGP)
3674 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3675 == BGP_DAMP_SUPPRESSED) {
3676 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3677 safi);
3678 return;
3679 }
3680
3681 #ifdef ENABLE_BGP_VNC
3682 if (safi == SAFI_MPLS_VPN) {
3683 struct bgp_dest *pdest = NULL;
3684 struct bgp_table *table = NULL;
3685
3686 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3687 (struct prefix *)prd);
3688 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3689 table = bgp_dest_get_bgp_table_info(pdest);
3690
3691 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3692 peer->bgp, prd, table, p, pi);
3693 }
3694 bgp_dest_unlock_node(pdest);
3695 }
3696 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3697 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3698
3699 vnc_import_bgp_del_route(peer->bgp, p, pi);
3700 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3701 }
3702 }
3703 #endif
3704
3705 /* If this is an EVPN route, process for un-import. */
3706 if (safi == SAFI_EVPN)
3707 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3708
3709 bgp_rib_remove(dest, pi, peer, afi, safi);
3710 }
3711
3712 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3713 struct peer *peer, struct attr *attr,
3714 struct bgp_dest *dest)
3715 {
3716 struct bgp_path_info *new;
3717
3718 /* Make new BGP info. */
3719 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3720 new->type = type;
3721 new->instance = instance;
3722 new->sub_type = sub_type;
3723 new->peer = peer;
3724 new->attr = attr;
3725 new->uptime = monotime(NULL);
3726 new->net = dest;
3727 return new;
3728 }
3729
3730 /* Check if received nexthop is valid or not. */
3731 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3732 uint8_t type, uint8_t stype, struct attr *attr,
3733 struct bgp_dest *dest)
3734 {
3735 bool ret = false;
3736 bool is_bgp_static_route =
3737 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3738 : false;
3739
3740 /*
3741 * Only validated for unicast and multicast currently.
3742 * Also valid for EVPN where the nexthop is an IP address.
3743 * If we are a bgp static route being checked then there is
3744 * no need to check to see if the nexthop is martian as
3745 * that it should be ok.
3746 */
3747 if (is_bgp_static_route ||
3748 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3749 return false;
3750
3751 /* If NEXT_HOP is present, validate it. */
3752 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3753 if (attr->nexthop.s_addr == INADDR_ANY ||
3754 !ipv4_unicast_valid(&attr->nexthop) ||
3755 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3756 return true;
3757 }
3758
3759 /* If MP_NEXTHOP is present, validate it. */
3760 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3761 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3762 * it is not an IPv6 link-local address.
3763 *
3764 * If we receive an UPDATE with nexthop length set to 32 bytes
3765 * we shouldn't discard an UPDATE if it's set to (::).
3766 * The link-local (2st) is validated along the code path later.
3767 */
3768 if (attr->mp_nexthop_len) {
3769 switch (attr->mp_nexthop_len) {
3770 case BGP_ATTR_NHLEN_IPV4:
3771 case BGP_ATTR_NHLEN_VPNV4:
3772 ret = (attr->mp_nexthop_global_in.s_addr ==
3773 INADDR_ANY ||
3774 !ipv4_unicast_valid(
3775 &attr->mp_nexthop_global_in) ||
3776 bgp_nexthop_self(bgp, afi, type, stype, attr,
3777 dest));
3778 break;
3779
3780 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3781 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3782 ret = (IN6_IS_ADDR_UNSPECIFIED(
3783 &attr->mp_nexthop_global)
3784 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3785 || IN6_IS_ADDR_MULTICAST(
3786 &attr->mp_nexthop_global)
3787 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3788 dest));
3789 break;
3790 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3791 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3792 || IN6_IS_ADDR_MULTICAST(
3793 &attr->mp_nexthop_global)
3794 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3795 dest));
3796 break;
3797
3798 default:
3799 ret = true;
3800 break;
3801 }
3802 }
3803
3804 return ret;
3805 }
3806
3807 static void bgp_attr_add_no_export_community(struct attr *attr)
3808 {
3809 struct community *old;
3810 struct community *new;
3811 struct community *merge;
3812 struct community *no_export;
3813
3814 old = bgp_attr_get_community(attr);
3815 no_export = community_str2com("no-export");
3816
3817 assert(no_export);
3818
3819 if (old) {
3820 merge = community_merge(community_dup(old), no_export);
3821
3822 if (!old->refcnt)
3823 community_free(&old);
3824
3825 new = community_uniq_sort(merge);
3826 community_free(&merge);
3827 } else {
3828 new = community_dup(no_export);
3829 }
3830
3831 community_free(&no_export);
3832
3833 bgp_attr_set_community(attr, new);
3834 }
3835
3836 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3837 struct attr *attr, afi_t afi, safi_t safi, int type,
3838 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3839 uint32_t num_labels, int soft_reconfig,
3840 struct bgp_route_evpn *evpn)
3841 {
3842 int ret;
3843 int aspath_loop_count = 0;
3844 struct bgp_dest *dest;
3845 struct bgp *bgp;
3846 struct attr new_attr;
3847 struct attr *attr_new;
3848 struct bgp_path_info *pi;
3849 struct bgp_path_info *new;
3850 struct bgp_path_info_extra *extra;
3851 const char *reason;
3852 char pfx_buf[BGP_PRD_PATH_STRLEN];
3853 int connected = 0;
3854 int do_loop_check = 1;
3855 int has_valid_label = 0;
3856 afi_t nh_afi;
3857 uint8_t pi_type = 0;
3858 uint8_t pi_sub_type = 0;
3859 bool force_evpn_import = false;
3860 safi_t orig_safi = safi;
3861 bool leak_success = true;
3862
3863 if (frrtrace_enabled(frr_bgp, process_update)) {
3864 char pfxprint[PREFIX2STR_BUFFER];
3865
3866 prefix2str(p, pfxprint, sizeof(pfxprint));
3867 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3868 afi, safi, attr);
3869 }
3870
3871 #ifdef ENABLE_BGP_VNC
3872 int vnc_implicit_withdraw = 0;
3873 #endif
3874 int same_attr = 0;
3875
3876 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
3877 if (orig_safi == SAFI_LABELED_UNICAST)
3878 safi = SAFI_UNICAST;
3879
3880 memset(&new_attr, 0, sizeof(new_attr));
3881 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3882 new_attr.label = MPLS_INVALID_LABEL;
3883
3884 bgp = peer->bgp;
3885 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3886 /* TODO: Check to see if we can get rid of "is_valid_label" */
3887 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3888 has_valid_label = (num_labels > 0) ? 1 : 0;
3889 else
3890 has_valid_label = bgp_is_valid_label(label);
3891
3892 if (has_valid_label)
3893 assert(label != NULL);
3894
3895 /* Update overlay index of the attribute */
3896 if (afi == AFI_L2VPN && evpn)
3897 memcpy(&attr->evpn_overlay, evpn,
3898 sizeof(struct bgp_route_evpn));
3899
3900 /* When peer's soft reconfiguration enabled. Record input packet in
3901 Adj-RIBs-In. */
3902 if (!soft_reconfig
3903 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3904 && peer != bgp->peer_self)
3905 bgp_adj_in_set(dest, peer, attr, addpath_id);
3906
3907 /* Check previously received route. */
3908 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3909 if (pi->peer == peer && pi->type == type
3910 && pi->sub_type == sub_type
3911 && pi->addpath_rx_id == addpath_id)
3912 break;
3913
3914 /* AS path local-as loop check. */
3915 if (peer->change_local_as) {
3916 if (peer->allowas_in[afi][safi])
3917 aspath_loop_count = peer->allowas_in[afi][safi];
3918 else if (!CHECK_FLAG(peer->flags,
3919 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3920 aspath_loop_count = 1;
3921
3922 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3923 > aspath_loop_count) {
3924 peer->stat_pfx_aspath_loop++;
3925 reason = "as-path contains our own AS;";
3926 goto filtered;
3927 }
3928 }
3929
3930 /* If the peer is configured for "allowas-in origin" and the last ASN in
3931 * the
3932 * as-path is our ASN then we do not need to call aspath_loop_check
3933 */
3934 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3935 if (aspath_get_last_as(attr->aspath) == bgp->as)
3936 do_loop_check = 0;
3937
3938 /* AS path loop check. */
3939 if (do_loop_check) {
3940 if (aspath_loop_check(attr->aspath, bgp->as)
3941 > peer->allowas_in[afi][safi]
3942 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3943 && aspath_loop_check(attr->aspath, bgp->confed_id)
3944 > peer->allowas_in[afi][safi])) {
3945 peer->stat_pfx_aspath_loop++;
3946 reason = "as-path contains our own AS;";
3947 goto filtered;
3948 }
3949 }
3950
3951 /* Route reflector originator ID check. */
3952 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3953 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3954 peer->stat_pfx_originator_loop++;
3955 reason = "originator is us;";
3956 goto filtered;
3957 }
3958
3959 /* Route reflector cluster ID check. */
3960 if (bgp_cluster_filter(peer, attr)) {
3961 peer->stat_pfx_cluster_loop++;
3962 reason = "reflected from the same cluster;";
3963 goto filtered;
3964 }
3965
3966 /* Apply incoming filter. */
3967 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
3968 peer->stat_pfx_filter++;
3969 reason = "filter;";
3970 goto filtered;
3971 }
3972
3973 /* RFC 8212 to prevent route leaks.
3974 * This specification intends to improve this situation by requiring the
3975 * explicit configuration of both BGP Import and Export Policies for any
3976 * External BGP (EBGP) session such as customers, peers, or
3977 * confederation boundaries for all enabled address families. Through
3978 * codification of the aforementioned requirement, operators will
3979 * benefit from consistent behavior across different BGP
3980 * implementations.
3981 */
3982 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3983 if (!bgp_inbound_policy_exists(peer,
3984 &peer->filter[afi][safi])) {
3985 reason = "inbound policy missing";
3986 if (monotime_since(&bgp->ebgprequirespolicywarning,
3987 NULL) > FIFTEENMINUTE2USEC ||
3988 bgp->ebgprequirespolicywarning.tv_sec == 0) {
3989 zlog_warn(
3990 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
3991 monotime(&bgp->ebgprequirespolicywarning);
3992 }
3993 goto filtered;
3994 }
3995
3996 /* draft-ietf-idr-deprecate-as-set-confed-set
3997 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3998 * Eventually, This document (if approved) updates RFC 4271
3999 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4000 * and obsoletes RFC 6472.
4001 */
4002 if (peer->bgp->reject_as_sets)
4003 if (aspath_check_as_sets(attr->aspath)) {
4004 reason =
4005 "as-path contains AS_SET or AS_CONFED_SET type;";
4006 goto filtered;
4007 }
4008
4009 new_attr = *attr;
4010
4011 /* Apply incoming route-map.
4012 * NB: new_attr may now contain newly allocated values from route-map
4013 * "set"
4014 * commands, so we need bgp_attr_flush in the error paths, until we
4015 * intern
4016 * the attr (which takes over the memory references) */
4017 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4018 num_labels, dest)
4019 == RMAP_DENY) {
4020 peer->stat_pfx_filter++;
4021 reason = "route-map;";
4022 bgp_attr_flush(&new_attr);
4023 goto filtered;
4024 }
4025
4026 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4027 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4028 /* remove from RIB previous entry */
4029 bgp_zebra_withdraw(p, pi, bgp, safi);
4030 }
4031
4032 if (peer->sort == BGP_PEER_EBGP) {
4033
4034 /* rfc7999:
4035 * A BGP speaker receiving an announcement tagged with the
4036 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4037 * NO_EXPORT community as defined in RFC1997, or a
4038 * similar community, to prevent propagation of the
4039 * prefix outside the local AS. The community to prevent
4040 * propagation SHOULD be chosen according to the operator's
4041 * routing policy.
4042 */
4043 if (bgp_attr_get_community(&new_attr) &&
4044 community_include(bgp_attr_get_community(&new_attr),
4045 COMMUNITY_BLACKHOLE))
4046 bgp_attr_add_no_export_community(&new_attr);
4047
4048 /* If we receive the graceful-shutdown community from an eBGP
4049 * peer we must lower local-preference */
4050 if (bgp_attr_get_community(&new_attr) &&
4051 community_include(bgp_attr_get_community(&new_attr),
4052 COMMUNITY_GSHUT)) {
4053 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4054 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4055
4056 /* If graceful-shutdown is configured then add the GSHUT
4057 * community to all paths received from eBGP peers */
4058 } else if (bgp_in_graceful_shutdown(peer->bgp))
4059 bgp_attr_add_gshut_community(&new_attr);
4060 }
4061
4062 if (pi) {
4063 pi_type = pi->type;
4064 pi_sub_type = pi->sub_type;
4065 }
4066
4067 /* next hop check. */
4068 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
4069 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
4070 &new_attr, dest)) {
4071 peer->stat_pfx_nh_invalid++;
4072 reason = "martian or self next-hop;";
4073 bgp_attr_flush(&new_attr);
4074 goto filtered;
4075 }
4076
4077 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4078 peer->stat_pfx_nh_invalid++;
4079 reason = "self mac;";
4080 bgp_attr_flush(&new_attr);
4081 goto filtered;
4082 }
4083
4084 if (bgp_check_role_applicability(afi, safi) &&
4085 bgp_otc_filter(peer, &new_attr)) {
4086 reason = "failing otc validation";
4087 bgp_attr_flush(&new_attr);
4088 goto filtered;
4089 }
4090 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4091 * condition :
4092 * Suppress fib is enabled
4093 * BGP_OPT_NO_FIB is not enabled
4094 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4095 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4096 */
4097 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4098 && (sub_type == BGP_ROUTE_NORMAL)
4099 && (!bgp_option_check(BGP_OPT_NO_FIB))
4100 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4101 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4102
4103 /* If maximum prefix count is configured and current prefix
4104 * count exeed it.
4105 */
4106 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4107 bgp_attr_flush(&new_attr);
4108 return -1;
4109 }
4110
4111 /* If neighbor soo is configured, tag all incoming routes with
4112 * this SoO tag and then filter out advertisements in
4113 * subgroup_announce_check() if it matches the configured SoO
4114 * on the other peer.
4115 */
4116 if (peer->soo[afi][safi]) {
4117 struct ecommunity *old_ecomm =
4118 bgp_attr_get_ecommunity(&new_attr);
4119 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4120 struct ecommunity *new_ecomm;
4121
4122 if (old_ecomm) {
4123 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4124 ecomm_soo);
4125
4126 if (!old_ecomm->refcnt)
4127 ecommunity_free(&old_ecomm);
4128 } else {
4129 new_ecomm = ecommunity_dup(ecomm_soo);
4130 }
4131
4132 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4133 }
4134
4135 attr_new = bgp_attr_intern(&new_attr);
4136
4137 /* If the update is implicit withdraw. */
4138 if (pi) {
4139 pi->uptime = monotime(NULL);
4140 same_attr = attrhash_cmp(pi->attr, attr_new);
4141
4142 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4143
4144 /* Same attribute comes in. */
4145 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4146 && same_attr
4147 && (!has_valid_label
4148 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4149 num_labels * sizeof(mpls_label_t))
4150 == 0)) {
4151 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4152 BGP_CONFIG_DAMPENING)
4153 && peer->sort == BGP_PEER_EBGP
4154 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4155 if (bgp_debug_update(peer, p, NULL, 1)) {
4156 bgp_debug_rdpfxpath2str(
4157 afi, safi, prd, p, label,
4158 num_labels, addpath_id ? 1 : 0,
4159 addpath_id, evpn, pfx_buf,
4160 sizeof(pfx_buf));
4161 zlog_debug("%pBP rcvd %s", peer,
4162 pfx_buf);
4163 }
4164
4165 if (bgp_damp_update(pi, dest, afi, safi)
4166 != BGP_DAMP_SUPPRESSED) {
4167 bgp_aggregate_increment(bgp, p, pi, afi,
4168 safi);
4169 bgp_process(bgp, dest, afi, safi);
4170 }
4171 } else /* Duplicate - odd */
4172 {
4173 if (bgp_debug_update(peer, p, NULL, 1)) {
4174 if (!peer->rcvd_attr_printed) {
4175 zlog_debug(
4176 "%pBP rcvd UPDATE w/ attr: %s",
4177 peer,
4178 peer->rcvd_attr_str);
4179 peer->rcvd_attr_printed = 1;
4180 }
4181
4182 bgp_debug_rdpfxpath2str(
4183 afi, safi, prd, p, label,
4184 num_labels, addpath_id ? 1 : 0,
4185 addpath_id, evpn, pfx_buf,
4186 sizeof(pfx_buf));
4187 zlog_debug(
4188 "%pBP rcvd %s...duplicate ignored",
4189 peer, pfx_buf);
4190 }
4191
4192 /* graceful restart STALE flag unset. */
4193 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4194 bgp_path_info_unset_flag(
4195 dest, pi, BGP_PATH_STALE);
4196 bgp_dest_set_defer_flag(dest, false);
4197 bgp_process(bgp, dest, afi, safi);
4198 }
4199 }
4200
4201 bgp_dest_unlock_node(dest);
4202 bgp_attr_unintern(&attr_new);
4203
4204 return 0;
4205 }
4206
4207 /* Withdraw/Announce before we fully processed the withdraw */
4208 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4209 if (bgp_debug_update(peer, p, NULL, 1)) {
4210 bgp_debug_rdpfxpath2str(
4211 afi, safi, prd, p, label, num_labels,
4212 addpath_id ? 1 : 0, addpath_id, evpn,
4213 pfx_buf, sizeof(pfx_buf));
4214 zlog_debug(
4215 "%pBP rcvd %s, flapped quicker than processing",
4216 peer, pfx_buf);
4217 }
4218
4219 bgp_path_info_restore(dest, pi);
4220
4221 /*
4222 * If the BGP_PATH_REMOVED flag is set, then EVPN
4223 * routes would have been unimported already when a
4224 * prior BGP withdraw processing happened. Such routes
4225 * need to be imported again, so flag accordingly.
4226 */
4227 force_evpn_import = true;
4228 }
4229
4230 /* Received Logging. */
4231 if (bgp_debug_update(peer, p, NULL, 1)) {
4232 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4233 num_labels, addpath_id ? 1 : 0,
4234 addpath_id, evpn, pfx_buf,
4235 sizeof(pfx_buf));
4236 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4237 }
4238
4239 /* graceful restart STALE flag unset. */
4240 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4241 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4242 bgp_dest_set_defer_flag(dest, false);
4243 }
4244
4245 /* The attribute is changed. */
4246 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4247
4248 /* implicit withdraw, decrement aggregate and pcount here.
4249 * only if update is accepted, they'll increment below.
4250 */
4251 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4252
4253 /* Update bgp route dampening information. */
4254 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4255 && peer->sort == BGP_PEER_EBGP) {
4256 /* This is implicit withdraw so we should update
4257 dampening
4258 information. */
4259 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4260 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4261 }
4262 #ifdef ENABLE_BGP_VNC
4263 if (safi == SAFI_MPLS_VPN) {
4264 struct bgp_dest *pdest = NULL;
4265 struct bgp_table *table = NULL;
4266
4267 pdest = bgp_node_get(bgp->rib[afi][safi],
4268 (struct prefix *)prd);
4269 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4270 table = bgp_dest_get_bgp_table_info(pdest);
4271
4272 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4273 bgp, prd, table, p, pi);
4274 }
4275 bgp_dest_unlock_node(pdest);
4276 }
4277 if ((afi == AFI_IP || afi == AFI_IP6)
4278 && (safi == SAFI_UNICAST)) {
4279 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4280 /*
4281 * Implicit withdraw case.
4282 */
4283 ++vnc_implicit_withdraw;
4284 vnc_import_bgp_del_route(bgp, p, pi);
4285 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4286 }
4287 }
4288 #endif
4289
4290 /* Special handling for EVPN update of an existing route. If the
4291 * extended community attribute has changed, we need to
4292 * un-import
4293 * the route using its existing extended community. It will be
4294 * subsequently processed for import with the new extended
4295 * community.
4296 */
4297 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4298 && !same_attr) {
4299 if ((pi->attr->flag
4300 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4301 && (attr_new->flag
4302 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4303 int cmp;
4304
4305 cmp = ecommunity_cmp(
4306 bgp_attr_get_ecommunity(pi->attr),
4307 bgp_attr_get_ecommunity(attr_new));
4308 if (!cmp) {
4309 if (bgp_debug_update(peer, p, NULL, 1))
4310 zlog_debug(
4311 "Change in EXT-COMM, existing %s new %s",
4312 ecommunity_str(
4313 bgp_attr_get_ecommunity(
4314 pi->attr)),
4315 ecommunity_str(
4316 bgp_attr_get_ecommunity(
4317 attr_new)));
4318 if (safi == SAFI_EVPN)
4319 bgp_evpn_unimport_route(
4320 bgp, afi, safi, p, pi);
4321 else /* SAFI_MPLS_VPN */
4322 vpn_leak_to_vrf_withdraw(bgp,
4323 pi);
4324 }
4325 }
4326 }
4327
4328 /* Update to new attribute. */
4329 bgp_attr_unintern(&pi->attr);
4330 pi->attr = attr_new;
4331
4332 /* Update MPLS label */
4333 if (has_valid_label) {
4334 extra = bgp_path_info_extra_get(pi);
4335 if (extra->label != label) {
4336 memcpy(&extra->label, label,
4337 num_labels * sizeof(mpls_label_t));
4338 extra->num_labels = num_labels;
4339 }
4340 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4341 bgp_set_valid_label(&extra->label[0]);
4342 }
4343
4344 /* Update SRv6 SID */
4345 if (attr->srv6_l3vpn) {
4346 extra = bgp_path_info_extra_get(pi);
4347 if (sid_diff(&extra->sid[0].sid,
4348 &attr->srv6_l3vpn->sid)) {
4349 sid_copy(&extra->sid[0].sid,
4350 &attr->srv6_l3vpn->sid);
4351 extra->num_sids = 1;
4352
4353 extra->sid[0].loc_block_len = 0;
4354 extra->sid[0].loc_node_len = 0;
4355 extra->sid[0].func_len = 0;
4356 extra->sid[0].arg_len = 0;
4357 extra->sid[0].transposition_len = 0;
4358 extra->sid[0].transposition_offset = 0;
4359
4360 if (attr->srv6_l3vpn->loc_block_len != 0) {
4361 extra->sid[0].loc_block_len =
4362 attr->srv6_l3vpn->loc_block_len;
4363 extra->sid[0].loc_node_len =
4364 attr->srv6_l3vpn->loc_node_len;
4365 extra->sid[0].func_len =
4366 attr->srv6_l3vpn->func_len;
4367 extra->sid[0].arg_len =
4368 attr->srv6_l3vpn->arg_len;
4369 extra->sid[0].transposition_len =
4370 attr->srv6_l3vpn
4371 ->transposition_len;
4372 extra->sid[0].transposition_offset =
4373 attr->srv6_l3vpn
4374 ->transposition_offset;
4375 }
4376 }
4377 } else if (attr->srv6_vpn) {
4378 extra = bgp_path_info_extra_get(pi);
4379 if (sid_diff(&extra->sid[0].sid,
4380 &attr->srv6_vpn->sid)) {
4381 sid_copy(&extra->sid[0].sid,
4382 &attr->srv6_vpn->sid);
4383 extra->num_sids = 1;
4384 }
4385 }
4386
4387 #ifdef ENABLE_BGP_VNC
4388 if ((afi == AFI_IP || afi == AFI_IP6)
4389 && (safi == SAFI_UNICAST)) {
4390 if (vnc_implicit_withdraw) {
4391 /*
4392 * Add back the route with its new attributes
4393 * (e.g., nexthop).
4394 * The route is still selected, until the route
4395 * selection
4396 * queued by bgp_process actually runs. We have
4397 * to make this
4398 * update to the VNC side immediately to avoid
4399 * racing against
4400 * configuration changes (e.g., route-map
4401 * changes) which
4402 * trigger re-importation of the entire RIB.
4403 */
4404 vnc_import_bgp_add_route(bgp, p, pi);
4405 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4406 }
4407 }
4408 #endif
4409
4410 /* Update bgp route dampening information. */
4411 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4412 && peer->sort == BGP_PEER_EBGP) {
4413 /* Now we do normal update dampening. */
4414 ret = bgp_damp_update(pi, dest, afi, safi);
4415 if (ret == BGP_DAMP_SUPPRESSED) {
4416 bgp_dest_unlock_node(dest);
4417 return 0;
4418 }
4419 }
4420
4421 /* Nexthop reachability check - for unicast and
4422 * labeled-unicast.. */
4423 if (((afi == AFI_IP || afi == AFI_IP6)
4424 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4425 || (safi == SAFI_EVPN &&
4426 bgp_evpn_is_prefix_nht_supported(p))) {
4427 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4428 && peer->ttl == BGP_DEFAULT_TTL
4429 && !CHECK_FLAG(peer->flags,
4430 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4431 && !CHECK_FLAG(bgp->flags,
4432 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4433 connected = 1;
4434 else
4435 connected = 0;
4436
4437 struct bgp *bgp_nexthop = bgp;
4438
4439 if (pi->extra && pi->extra->bgp_orig)
4440 bgp_nexthop = pi->extra->bgp_orig;
4441
4442 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4443
4444 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4445 safi, pi, NULL, connected,
4446 p)
4447 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4448 bgp_path_info_set_flag(dest, pi,
4449 BGP_PATH_VALID);
4450 else {
4451 if (BGP_DEBUG(nht, NHT)) {
4452 zlog_debug("%s(%pI4): NH unresolved",
4453 __func__,
4454 (in_addr_t *)&attr_new->nexthop);
4455 }
4456 bgp_path_info_unset_flag(dest, pi,
4457 BGP_PATH_VALID);
4458 }
4459 } else
4460 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4461
4462 #ifdef ENABLE_BGP_VNC
4463 if (safi == SAFI_MPLS_VPN) {
4464 struct bgp_dest *pdest = NULL;
4465 struct bgp_table *table = NULL;
4466
4467 pdest = bgp_node_get(bgp->rib[afi][safi],
4468 (struct prefix *)prd);
4469 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4470 table = bgp_dest_get_bgp_table_info(pdest);
4471
4472 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4473 bgp, prd, table, p, pi);
4474 }
4475 bgp_dest_unlock_node(pdest);
4476 }
4477 #endif
4478
4479 /* If this is an EVPN route and some attribute has changed,
4480 * or we are explicitly told to perform a route import, process
4481 * route for import. If the extended community has changed, we
4482 * would
4483 * have done the un-import earlier and the import would result
4484 * in the
4485 * route getting injected into appropriate L2 VNIs. If it is
4486 * just
4487 * some other attribute change, the import will result in
4488 * updating
4489 * the attributes for the route in the VNI(s).
4490 */
4491 if (safi == SAFI_EVPN &&
4492 (!same_attr || force_evpn_import) &&
4493 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4494 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4495
4496 /* Process change. */
4497 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4498
4499 bgp_process(bgp, dest, afi, safi);
4500 bgp_dest_unlock_node(dest);
4501
4502 if (SAFI_UNICAST == safi
4503 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4504 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4505
4506 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4507 }
4508 if ((SAFI_MPLS_VPN == safi)
4509 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4510
4511 leak_success = vpn_leak_to_vrf_update(bgp, pi);
4512 }
4513
4514 #ifdef ENABLE_BGP_VNC
4515 if (SAFI_MPLS_VPN == safi) {
4516 mpls_label_t label_decoded = decode_label(label);
4517
4518 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4519 type, sub_type, &label_decoded);
4520 }
4521 if (SAFI_ENCAP == safi) {
4522 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4523 type, sub_type, NULL);
4524 }
4525 #endif
4526 if ((safi == SAFI_MPLS_VPN) &&
4527 !CHECK_FLAG(bgp->af_flags[afi][safi],
4528 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4529 !leak_success) {
4530 bgp_unlink_nexthop(pi);
4531 bgp_path_info_delete(dest, pi);
4532 }
4533 return 0;
4534 } // End of implicit withdraw
4535
4536 /* Received Logging. */
4537 if (bgp_debug_update(peer, p, NULL, 1)) {
4538 if (!peer->rcvd_attr_printed) {
4539 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4540 peer->rcvd_attr_str);
4541 peer->rcvd_attr_printed = 1;
4542 }
4543
4544 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4545 addpath_id ? 1 : 0, addpath_id, evpn,
4546 pfx_buf, sizeof(pfx_buf));
4547 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4548 }
4549
4550 /* Make new BGP info. */
4551 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4552
4553 /* Update MPLS label */
4554 if (has_valid_label) {
4555 extra = bgp_path_info_extra_get(new);
4556 if (extra->label != label) {
4557 memcpy(&extra->label, label,
4558 num_labels * sizeof(mpls_label_t));
4559 extra->num_labels = num_labels;
4560 }
4561 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4562 bgp_set_valid_label(&extra->label[0]);
4563 }
4564
4565 /* Update SRv6 SID */
4566 if (safi == SAFI_MPLS_VPN) {
4567 extra = bgp_path_info_extra_get(new);
4568 if (attr->srv6_l3vpn) {
4569 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4570 extra->num_sids = 1;
4571
4572 extra->sid[0].loc_block_len =
4573 attr->srv6_l3vpn->loc_block_len;
4574 extra->sid[0].loc_node_len =
4575 attr->srv6_l3vpn->loc_node_len;
4576 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4577 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4578 extra->sid[0].transposition_len =
4579 attr->srv6_l3vpn->transposition_len;
4580 extra->sid[0].transposition_offset =
4581 attr->srv6_l3vpn->transposition_offset;
4582 } else if (attr->srv6_vpn) {
4583 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4584 extra->num_sids = 1;
4585 }
4586 }
4587
4588 /* Nexthop reachability check. */
4589 if (((afi == AFI_IP || afi == AFI_IP6)
4590 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4591 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4592 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4593 && peer->ttl == BGP_DEFAULT_TTL
4594 && !CHECK_FLAG(peer->flags,
4595 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4596 && !CHECK_FLAG(bgp->flags,
4597 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4598 connected = 1;
4599 else
4600 connected = 0;
4601
4602 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4603
4604 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4605 connected, p)
4606 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4607 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4608 else {
4609 if (BGP_DEBUG(nht, NHT)) {
4610 char buf1[INET6_ADDRSTRLEN];
4611 inet_ntop(AF_INET,
4612 (const void *)&attr_new->nexthop,
4613 buf1, INET6_ADDRSTRLEN);
4614 zlog_debug("%s(%s): NH unresolved", __func__,
4615 buf1);
4616 }
4617 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4618 }
4619 } else
4620 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4621
4622 /* Addpath ID */
4623 new->addpath_rx_id = addpath_id;
4624
4625 /* Increment prefix */
4626 bgp_aggregate_increment(bgp, p, new, afi, safi);
4627
4628 /* Register new BGP information. */
4629 bgp_path_info_add(dest, new);
4630
4631 /* route_node_get lock */
4632 bgp_dest_unlock_node(dest);
4633
4634 #ifdef ENABLE_BGP_VNC
4635 if (safi == SAFI_MPLS_VPN) {
4636 struct bgp_dest *pdest = NULL;
4637 struct bgp_table *table = NULL;
4638
4639 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4640 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4641 table = bgp_dest_get_bgp_table_info(pdest);
4642
4643 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4644 bgp, prd, table, p, new);
4645 }
4646 bgp_dest_unlock_node(pdest);
4647 }
4648 #endif
4649
4650 /* If this is an EVPN route, process for import. */
4651 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4652 bgp_evpn_import_route(bgp, afi, safi, p, new);
4653
4654 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4655
4656 /* Process change. */
4657 bgp_process(bgp, dest, afi, safi);
4658
4659 if (SAFI_UNICAST == safi
4660 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4661 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4662 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4663 }
4664 if ((SAFI_MPLS_VPN == safi)
4665 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4666 leak_success = vpn_leak_to_vrf_update(bgp, new);
4667 }
4668 #ifdef ENABLE_BGP_VNC
4669 if (SAFI_MPLS_VPN == safi) {
4670 mpls_label_t label_decoded = decode_label(label);
4671
4672 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4673 sub_type, &label_decoded);
4674 }
4675 if (SAFI_ENCAP == safi) {
4676 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4677 sub_type, NULL);
4678 }
4679 #endif
4680 if ((safi == SAFI_MPLS_VPN) &&
4681 !CHECK_FLAG(bgp->af_flags[afi][safi],
4682 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4683 !leak_success) {
4684 bgp_unlink_nexthop(new);
4685 bgp_path_info_delete(dest, new);
4686 }
4687
4688 return 0;
4689
4690 /* This BGP update is filtered. Log the reason then update BGP
4691 entry. */
4692 filtered:
4693 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4694
4695 if (bgp_debug_update(peer, p, NULL, 1)) {
4696 if (!peer->rcvd_attr_printed) {
4697 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4698 peer->rcvd_attr_str);
4699 peer->rcvd_attr_printed = 1;
4700 }
4701
4702 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4703 addpath_id ? 1 : 0, addpath_id, evpn,
4704 pfx_buf, sizeof(pfx_buf));
4705 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4706 peer, pfx_buf, reason);
4707 }
4708
4709 if (pi) {
4710 /* If this is an EVPN route, un-import it as it is now filtered.
4711 */
4712 if (safi == SAFI_EVPN)
4713 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4714
4715 if (SAFI_UNICAST == safi
4716 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4717 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4718
4719 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4720 }
4721 if ((SAFI_MPLS_VPN == safi)
4722 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4723
4724 vpn_leak_to_vrf_withdraw(bgp, pi);
4725 }
4726
4727 bgp_rib_remove(dest, pi, peer, afi, safi);
4728 }
4729
4730 bgp_dest_unlock_node(dest);
4731
4732 #ifdef ENABLE_BGP_VNC
4733 /*
4734 * Filtered update is treated as an implicit withdrawal (see
4735 * bgp_rib_remove()
4736 * a few lines above)
4737 */
4738 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4739 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4740 0);
4741 }
4742 #endif
4743
4744 return 0;
4745 }
4746
4747 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4748 struct attr *attr, afi_t afi, safi_t safi, int type,
4749 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4750 uint32_t num_labels, struct bgp_route_evpn *evpn)
4751 {
4752 struct bgp *bgp;
4753 char pfx_buf[BGP_PRD_PATH_STRLEN];
4754 struct bgp_dest *dest;
4755 struct bgp_path_info *pi;
4756
4757 #ifdef ENABLE_BGP_VNC
4758 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4759 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4760 0);
4761 }
4762 #endif
4763
4764 bgp = peer->bgp;
4765
4766 /* Lookup node. */
4767 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4768
4769 /* If peer is soft reconfiguration enabled. Record input packet for
4770 * further calculation.
4771 *
4772 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4773 * routes that are filtered. This tanks out Quagga RS pretty badly due
4774 * to
4775 * the iteration over all RS clients.
4776 * Since we need to remove the entry from adj_in anyway, do that first
4777 * and
4778 * if there was no entry, we don't need to do anything more.
4779 */
4780 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4781 && peer != bgp->peer_self)
4782 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4783 peer->stat_pfx_dup_withdraw++;
4784
4785 if (bgp_debug_update(peer, p, NULL, 1)) {
4786 bgp_debug_rdpfxpath2str(
4787 afi, safi, prd, p, label, num_labels,
4788 addpath_id ? 1 : 0, addpath_id, NULL,
4789 pfx_buf, sizeof(pfx_buf));
4790 zlog_debug(
4791 "%s withdrawing route %s not in adj-in",
4792 peer->host, pfx_buf);
4793 }
4794 bgp_dest_unlock_node(dest);
4795 return 0;
4796 }
4797
4798 /* Lookup withdrawn route. */
4799 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4800 if (pi->peer == peer && pi->type == type
4801 && pi->sub_type == sub_type
4802 && pi->addpath_rx_id == addpath_id)
4803 break;
4804
4805 /* Logging. */
4806 if (bgp_debug_update(peer, p, NULL, 1)) {
4807 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4808 addpath_id ? 1 : 0, addpath_id, NULL,
4809 pfx_buf, sizeof(pfx_buf));
4810 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4811 pfx_buf);
4812 }
4813
4814 /* Withdraw specified route from routing table. */
4815 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4816 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4817 if (SAFI_UNICAST == safi
4818 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4819 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4820 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4821 }
4822 if ((SAFI_MPLS_VPN == safi)
4823 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4824
4825 vpn_leak_to_vrf_withdraw(bgp, pi);
4826 }
4827 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4828 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4829 addpath_id ? 1 : 0, addpath_id, NULL,
4830 pfx_buf, sizeof(pfx_buf));
4831 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4832 }
4833
4834 /* Unlock bgp_node_get() lock. */
4835 bgp_dest_unlock_node(dest);
4836
4837 return 0;
4838 }
4839
4840 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4841 int withdraw)
4842 {
4843 struct update_subgroup *subgrp;
4844 subgrp = peer_subgroup(peer, afi, safi);
4845 subgroup_default_originate(subgrp, withdraw);
4846 }
4847
4848
4849 /*
4850 * bgp_stop_announce_route_timer
4851 */
4852 void bgp_stop_announce_route_timer(struct peer_af *paf)
4853 {
4854 if (!paf->t_announce_route)
4855 return;
4856
4857 THREAD_OFF(paf->t_announce_route);
4858 }
4859
4860 /*
4861 * bgp_announce_route_timer_expired
4862 *
4863 * Callback that is invoked when the route announcement timer for a
4864 * peer_af expires.
4865 */
4866 static void bgp_announce_route_timer_expired(struct thread *t)
4867 {
4868 struct peer_af *paf;
4869 struct peer *peer;
4870
4871 paf = THREAD_ARG(t);
4872 peer = paf->peer;
4873
4874 if (!peer_established(peer))
4875 return;
4876
4877 if (!peer->afc_nego[paf->afi][paf->safi])
4878 return;
4879
4880 peer_af_announce_route(paf, 1);
4881
4882 /* Notify BGP conditional advertisement scanner percess */
4883 peer->advmap_config_change[paf->afi][paf->safi] = true;
4884 }
4885
4886 /*
4887 * bgp_announce_route
4888 *
4889 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4890 *
4891 * if force is true we will force an update even if the update
4892 * limiting code is attempted to kick in.
4893 */
4894 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
4895 {
4896 struct peer_af *paf;
4897 struct update_subgroup *subgrp;
4898
4899 paf = peer_af_find(peer, afi, safi);
4900 if (!paf)
4901 return;
4902 subgrp = PAF_SUBGRP(paf);
4903
4904 /*
4905 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4906 * or a refresh has already been triggered.
4907 */
4908 if (!subgrp || paf->t_announce_route)
4909 return;
4910
4911 if (force)
4912 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
4913
4914 /*
4915 * Start a timer to stagger/delay the announce. This serves
4916 * two purposes - announcement can potentially be combined for
4917 * multiple peers and the announcement doesn't happen in the
4918 * vty context.
4919 */
4920 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4921 (subgrp->peer_count == 1)
4922 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4923 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4924 &paf->t_announce_route);
4925 }
4926
4927 /*
4928 * Announce routes from all AF tables to a peer.
4929 *
4930 * This should ONLY be called when there is a need to refresh the
4931 * routes to the peer based on a policy change for this peer alone
4932 * or a route refresh request received from the peer.
4933 * The operation will result in splitting the peer from its existing
4934 * subgroups and putting it in new subgroups.
4935 */
4936 void bgp_announce_route_all(struct peer *peer)
4937 {
4938 afi_t afi;
4939 safi_t safi;
4940
4941 FOREACH_AFI_SAFI (afi, safi)
4942 bgp_announce_route(peer, afi, safi, false);
4943 }
4944
4945 /* Flag or unflag bgp_dest to determine whether it should be treated by
4946 * bgp_soft_reconfig_table_task.
4947 * Flag if flag is true. Unflag if flag is false.
4948 */
4949 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
4950 {
4951 struct bgp_dest *dest;
4952 struct bgp_adj_in *ain;
4953
4954 if (!table)
4955 return;
4956
4957 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4958 for (ain = dest->adj_in; ain; ain = ain->next) {
4959 if (ain->peer != NULL)
4960 break;
4961 }
4962 if (flag && ain != NULL && ain->peer != NULL)
4963 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4964 else
4965 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4966 }
4967 }
4968
4969 static int bgp_soft_reconfig_table_update(struct peer *peer,
4970 struct bgp_dest *dest,
4971 struct bgp_adj_in *ain, afi_t afi,
4972 safi_t safi, struct prefix_rd *prd)
4973 {
4974 struct bgp_path_info *pi;
4975 uint32_t num_labels = 0;
4976 mpls_label_t *label_pnt = NULL;
4977 struct bgp_route_evpn evpn;
4978
4979 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4980 if (pi->peer == peer)
4981 break;
4982
4983 if (pi && pi->extra)
4984 num_labels = pi->extra->num_labels;
4985 if (num_labels)
4986 label_pnt = &pi->extra->label[0];
4987 if (pi)
4988 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
4989 sizeof(evpn));
4990 else
4991 memset(&evpn, 0, sizeof(evpn));
4992
4993 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
4994 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
4995 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
4996 &evpn);
4997 }
4998
4999 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5000 struct bgp_table *table,
5001 struct prefix_rd *prd)
5002 {
5003 int ret;
5004 struct bgp_dest *dest;
5005 struct bgp_adj_in *ain;
5006
5007 if (!table)
5008 table = peer->bgp->rib[afi][safi];
5009
5010 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5011 for (ain = dest->adj_in; ain; ain = ain->next) {
5012 if (ain->peer != peer)
5013 continue;
5014
5015 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
5016 afi, safi, prd);
5017
5018 if (ret < 0) {
5019 bgp_dest_unlock_node(dest);
5020 return;
5021 }
5022 }
5023 }
5024
5025 /* Do soft reconfig table per bgp table.
5026 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5027 * when BGP_NODE_SOFT_RECONFIG is set,
5028 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5029 * Schedule a new thread to continue the job.
5030 * Without splitting the full job into several part,
5031 * vtysh waits for the job to finish before responding to a BGP command
5032 */
5033 static void bgp_soft_reconfig_table_task(struct thread *thread)
5034 {
5035 uint32_t iter, max_iter;
5036 int ret;
5037 struct bgp_dest *dest;
5038 struct bgp_adj_in *ain;
5039 struct peer *peer;
5040 struct bgp_table *table;
5041 struct prefix_rd *prd;
5042 struct listnode *node, *nnode;
5043
5044 table = THREAD_ARG(thread);
5045 prd = NULL;
5046
5047 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5048 if (table->soft_reconfig_init) {
5049 /* first call of the function with a new srta structure.
5050 * Don't do any treatment this time on nodes
5051 * in order vtysh to respond quickly
5052 */
5053 max_iter = 0;
5054 }
5055
5056 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5057 dest = bgp_route_next(dest)) {
5058 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5059 continue;
5060
5061 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5062
5063 for (ain = dest->adj_in; ain; ain = ain->next) {
5064 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5065 nnode, peer)) {
5066 if (ain->peer != peer)
5067 continue;
5068
5069 ret = bgp_soft_reconfig_table_update(
5070 peer, dest, ain, table->afi,
5071 table->safi, prd);
5072 iter++;
5073
5074 if (ret < 0) {
5075 bgp_dest_unlock_node(dest);
5076 listnode_delete(
5077 table->soft_reconfig_peers,
5078 peer);
5079 bgp_announce_route(peer, table->afi,
5080 table->safi, false);
5081 if (list_isempty(
5082 table->soft_reconfig_peers)) {
5083 list_delete(
5084 &table->soft_reconfig_peers);
5085 bgp_soft_reconfig_table_flag(
5086 table, false);
5087 return;
5088 }
5089 }
5090 }
5091 }
5092 }
5093
5094 /* we're either starting the initial iteration,
5095 * or we're going to continue an ongoing iteration
5096 */
5097 if (dest || table->soft_reconfig_init) {
5098 table->soft_reconfig_init = false;
5099 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5100 table, 0, &table->soft_reconfig_thread);
5101 return;
5102 }
5103 /* we're done, clean up the background iteration context info and
5104 schedule route annoucement
5105 */
5106 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5107 listnode_delete(table->soft_reconfig_peers, peer);
5108 bgp_announce_route(peer, table->afi, table->safi, false);
5109 }
5110
5111 list_delete(&table->soft_reconfig_peers);
5112 }
5113
5114
5115 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5116 * and peer.
5117 * - bgp cannot be NULL
5118 * - if table and peer are NULL, cancel all threads within the bgp instance
5119 * - if table is NULL and peer is not,
5120 * remove peer in all threads within the bgp instance
5121 * - if peer is NULL, cancel all threads matching table within the bgp instance
5122 */
5123 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5124 const struct bgp_table *table,
5125 const struct peer *peer)
5126 {
5127 struct peer *npeer;
5128 struct listnode *node, *nnode;
5129 int afi, safi;
5130 struct bgp_table *ntable;
5131
5132 if (!bgp)
5133 return;
5134
5135 FOREACH_AFI_SAFI (afi, safi) {
5136 ntable = bgp->rib[afi][safi];
5137 if (!ntable)
5138 continue;
5139 if (table && table != ntable)
5140 continue;
5141
5142 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5143 npeer)) {
5144 if (peer && peer != npeer)
5145 continue;
5146 listnode_delete(ntable->soft_reconfig_peers, npeer);
5147 }
5148
5149 if (!ntable->soft_reconfig_peers
5150 || !list_isempty(ntable->soft_reconfig_peers))
5151 continue;
5152
5153 list_delete(&ntable->soft_reconfig_peers);
5154 bgp_soft_reconfig_table_flag(ntable, false);
5155 THREAD_OFF(ntable->soft_reconfig_thread);
5156 }
5157 }
5158
5159 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5160 {
5161 struct bgp_dest *dest;
5162 struct bgp_table *table;
5163 struct listnode *node, *nnode;
5164 struct peer *npeer;
5165 struct peer_af *paf;
5166
5167 if (!peer_established(peer))
5168 return;
5169
5170 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5171 && (safi != SAFI_EVPN)) {
5172 table = peer->bgp->rib[afi][safi];
5173 if (!table)
5174 return;
5175
5176 table->soft_reconfig_init = true;
5177
5178 if (!table->soft_reconfig_peers)
5179 table->soft_reconfig_peers = list_new();
5180 npeer = NULL;
5181 /* add peer to the table soft_reconfig_peers if not already
5182 * there
5183 */
5184 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5185 npeer)) {
5186 if (peer == npeer)
5187 break;
5188 }
5189 if (peer != npeer)
5190 listnode_add(table->soft_reconfig_peers, peer);
5191
5192 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5193 * on table would start back at the beginning.
5194 */
5195 bgp_soft_reconfig_table_flag(table, true);
5196
5197 if (!table->soft_reconfig_thread)
5198 thread_add_event(bm->master,
5199 bgp_soft_reconfig_table_task, table, 0,
5200 &table->soft_reconfig_thread);
5201 /* Cancel bgp_announce_route_timer_expired threads.
5202 * bgp_announce_route_timer_expired threads have been scheduled
5203 * to announce routes as soon as the soft_reconfigure process
5204 * finishes.
5205 * In this case, soft_reconfigure is also scheduled by using
5206 * a thread but is planned after the
5207 * bgp_announce_route_timer_expired threads. It means that,
5208 * without cancelling the threads, the route announcement task
5209 * would run before the soft reconfiguration one. That would
5210 * useless and would block vtysh during several seconds. Route
5211 * announcements are rescheduled as soon as the soft_reconfigure
5212 * process finishes.
5213 */
5214 paf = peer_af_find(peer, afi, safi);
5215 if (paf)
5216 bgp_stop_announce_route_timer(paf);
5217 } else
5218 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5219 dest = bgp_route_next(dest)) {
5220 table = bgp_dest_get_bgp_table_info(dest);
5221
5222 if (table == NULL)
5223 continue;
5224
5225 const struct prefix *p = bgp_dest_get_prefix(dest);
5226 struct prefix_rd prd;
5227
5228 prd.family = AF_UNSPEC;
5229 prd.prefixlen = 64;
5230 memcpy(&prd.val, p->u.val, 8);
5231
5232 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5233 }
5234 }
5235
5236
5237 struct bgp_clear_node_queue {
5238 struct bgp_dest *dest;
5239 };
5240
5241 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5242 {
5243 struct bgp_clear_node_queue *cnq = data;
5244 struct bgp_dest *dest = cnq->dest;
5245 struct peer *peer = wq->spec.data;
5246 struct bgp_path_info *pi;
5247 struct bgp *bgp;
5248 afi_t afi = bgp_dest_table(dest)->afi;
5249 safi_t safi = bgp_dest_table(dest)->safi;
5250
5251 assert(dest && peer);
5252 bgp = peer->bgp;
5253
5254 /* It is possible that we have multiple paths for a prefix from a peer
5255 * if that peer is using AddPath.
5256 */
5257 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5258 if (pi->peer != peer)
5259 continue;
5260
5261 /* graceful restart STALE flag set. */
5262 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5263 && peer->nsf[afi][safi])
5264 || CHECK_FLAG(peer->af_sflags[afi][safi],
5265 PEER_STATUS_ENHANCED_REFRESH))
5266 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5267 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5268 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5269 else {
5270 /* If this is an EVPN route, process for
5271 * un-import. */
5272 if (safi == SAFI_EVPN)
5273 bgp_evpn_unimport_route(
5274 bgp, afi, safi,
5275 bgp_dest_get_prefix(dest), pi);
5276 /* Handle withdraw for VRF route-leaking and L3VPN */
5277 if (SAFI_UNICAST == safi
5278 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5279 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5280 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5281 bgp, pi);
5282 }
5283 if (SAFI_MPLS_VPN == safi &&
5284 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5285 vpn_leak_to_vrf_withdraw(bgp, pi);
5286 }
5287
5288 bgp_rib_remove(dest, pi, peer, afi, safi);
5289 }
5290 }
5291 return WQ_SUCCESS;
5292 }
5293
5294 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5295 {
5296 struct bgp_clear_node_queue *cnq = data;
5297 struct bgp_dest *dest = cnq->dest;
5298 struct bgp_table *table = bgp_dest_table(dest);
5299
5300 bgp_dest_unlock_node(dest);
5301 bgp_table_unlock(table);
5302 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5303 }
5304
5305 static void bgp_clear_node_complete(struct work_queue *wq)
5306 {
5307 struct peer *peer = wq->spec.data;
5308
5309 /* Tickle FSM to start moving again */
5310 BGP_EVENT_ADD(peer, Clearing_Completed);
5311
5312 peer_unlock(peer); /* bgp_clear_route */
5313 }
5314
5315 static void bgp_clear_node_queue_init(struct peer *peer)
5316 {
5317 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5318
5319 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5320 #undef CLEAR_QUEUE_NAME_LEN
5321
5322 peer->clear_node_queue = work_queue_new(bm->master, wname);
5323 peer->clear_node_queue->spec.hold = 10;
5324 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5325 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5326 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5327 peer->clear_node_queue->spec.max_retries = 0;
5328
5329 /* we only 'lock' this peer reference when the queue is actually active
5330 */
5331 peer->clear_node_queue->spec.data = peer;
5332 }
5333
5334 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5335 struct bgp_table *table)
5336 {
5337 struct bgp_dest *dest;
5338 int force = peer->bgp->process_queue ? 0 : 1;
5339
5340 if (!table)
5341 table = peer->bgp->rib[afi][safi];
5342
5343 /* If still no table => afi/safi isn't configured at all or smth. */
5344 if (!table)
5345 return;
5346
5347 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5348 struct bgp_path_info *pi, *next;
5349 struct bgp_adj_in *ain;
5350 struct bgp_adj_in *ain_next;
5351
5352 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5353 * queued for every clearing peer, regardless of whether it is
5354 * relevant to the peer at hand.
5355 *
5356 * Overview: There are 3 different indices which need to be
5357 * scrubbed, potentially, when a peer is removed:
5358 *
5359 * 1 peer's routes visible via the RIB (ie accepted routes)
5360 * 2 peer's routes visible by the (optional) peer's adj-in index
5361 * 3 other routes visible by the peer's adj-out index
5362 *
5363 * 3 there is no hurry in scrubbing, once the struct peer is
5364 * removed from bgp->peer, we could just GC such deleted peer's
5365 * adj-outs at our leisure.
5366 *
5367 * 1 and 2 must be 'scrubbed' in some way, at least made
5368 * invisible via RIB index before peer session is allowed to be
5369 * brought back up. So one needs to know when such a 'search' is
5370 * complete.
5371 *
5372 * Ideally:
5373 *
5374 * - there'd be a single global queue or a single RIB walker
5375 * - rather than tracking which route_nodes still need to be
5376 * examined on a peer basis, we'd track which peers still
5377 * aren't cleared
5378 *
5379 * Given that our per-peer prefix-counts now should be reliable,
5380 * this may actually be achievable. It doesn't seem to be a huge
5381 * problem at this time,
5382 *
5383 * It is possible that we have multiple paths for a prefix from
5384 * a peer
5385 * if that peer is using AddPath.
5386 */
5387 ain = dest->adj_in;
5388 while (ain) {
5389 ain_next = ain->next;
5390
5391 if (ain->peer == peer)
5392 bgp_adj_in_remove(dest, ain);
5393
5394 ain = ain_next;
5395 }
5396
5397 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5398 next = pi->next;
5399 if (pi->peer != peer)
5400 continue;
5401
5402 if (force)
5403 bgp_path_info_reap(dest, pi);
5404 else {
5405 struct bgp_clear_node_queue *cnq;
5406
5407 /* both unlocked in bgp_clear_node_queue_del */
5408 bgp_table_lock(bgp_dest_table(dest));
5409 bgp_dest_lock_node(dest);
5410 cnq = XCALLOC(
5411 MTYPE_BGP_CLEAR_NODE_QUEUE,
5412 sizeof(struct bgp_clear_node_queue));
5413 cnq->dest = dest;
5414 work_queue_add(peer->clear_node_queue, cnq);
5415 break;
5416 }
5417 }
5418 }
5419 return;
5420 }
5421
5422 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5423 {
5424 struct bgp_dest *dest;
5425 struct bgp_table *table;
5426
5427 if (peer->clear_node_queue == NULL)
5428 bgp_clear_node_queue_init(peer);
5429
5430 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5431 * Idle until it receives a Clearing_Completed event. This protects
5432 * against peers which flap faster than we can we clear, which could
5433 * lead to:
5434 *
5435 * a) race with routes from the new session being installed before
5436 * clear_route_node visits the node (to delete the route of that
5437 * peer)
5438 * b) resource exhaustion, clear_route_node likely leads to an entry
5439 * on the process_main queue. Fast-flapping could cause that queue
5440 * to grow and grow.
5441 */
5442
5443 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5444 * the unlock will happen upon work-queue completion; other wise, the
5445 * unlock happens at the end of this function.
5446 */
5447 if (!peer->clear_node_queue->thread)
5448 peer_lock(peer);
5449
5450 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5451 bgp_clear_route_table(peer, afi, safi, NULL);
5452 else
5453 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5454 dest = bgp_route_next(dest)) {
5455 table = bgp_dest_get_bgp_table_info(dest);
5456 if (!table)
5457 continue;
5458
5459 bgp_clear_route_table(peer, afi, safi, table);
5460 }
5461
5462 /* unlock if no nodes got added to the clear-node-queue. */
5463 if (!peer->clear_node_queue->thread)
5464 peer_unlock(peer);
5465 }
5466
5467 void bgp_clear_route_all(struct peer *peer)
5468 {
5469 afi_t afi;
5470 safi_t safi;
5471
5472 FOREACH_AFI_SAFI (afi, safi)
5473 bgp_clear_route(peer, afi, safi);
5474
5475 #ifdef ENABLE_BGP_VNC
5476 rfapiProcessPeerDown(peer);
5477 #endif
5478 }
5479
5480 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5481 {
5482 struct bgp_table *table;
5483 struct bgp_dest *dest;
5484 struct bgp_adj_in *ain;
5485 struct bgp_adj_in *ain_next;
5486
5487 table = peer->bgp->rib[afi][safi];
5488
5489 /* It is possible that we have multiple paths for a prefix from a peer
5490 * if that peer is using AddPath.
5491 */
5492 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5493 ain = dest->adj_in;
5494
5495 while (ain) {
5496 ain_next = ain->next;
5497
5498 if (ain->peer == peer)
5499 bgp_adj_in_remove(dest, ain);
5500
5501 ain = ain_next;
5502 }
5503 }
5504 }
5505
5506 /* If any of the routes from the peer have been marked with the NO_LLGR
5507 * community, either as sent by the peer, or as the result of a configured
5508 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5509 * operation of [RFC4271].
5510 */
5511 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5512 {
5513 struct bgp_dest *dest;
5514 struct bgp_path_info *pi;
5515 struct bgp_table *table;
5516
5517 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5518 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5519 dest = bgp_route_next(dest)) {
5520 struct bgp_dest *rm;
5521
5522 /* look for neighbor in tables */
5523 table = bgp_dest_get_bgp_table_info(dest);
5524 if (!table)
5525 continue;
5526
5527 for (rm = bgp_table_top(table); rm;
5528 rm = bgp_route_next(rm))
5529 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5530 pi = pi->next) {
5531 if (pi->peer != peer)
5532 continue;
5533 if (CHECK_FLAG(
5534 peer->af_sflags[afi][safi],
5535 PEER_STATUS_LLGR_WAIT) &&
5536 bgp_attr_get_community(pi->attr) &&
5537 !community_include(
5538 bgp_attr_get_community(
5539 pi->attr),
5540 COMMUNITY_NO_LLGR))
5541 continue;
5542 if (!CHECK_FLAG(pi->flags,
5543 BGP_PATH_STALE))
5544 continue;
5545
5546 /*
5547 * If this is VRF leaked route
5548 * process for withdraw.
5549 */
5550 if (pi->sub_type ==
5551 BGP_ROUTE_IMPORTED &&
5552 peer->bgp->inst_type ==
5553 BGP_INSTANCE_TYPE_DEFAULT)
5554 vpn_leak_to_vrf_withdraw(
5555 peer->bgp, pi);
5556
5557 bgp_rib_remove(rm, pi, peer, afi, safi);
5558 break;
5559 }
5560 }
5561 } else {
5562 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5563 dest = bgp_route_next(dest))
5564 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5565 pi = pi->next) {
5566 if (pi->peer != peer)
5567 continue;
5568 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5569 PEER_STATUS_LLGR_WAIT) &&
5570 bgp_attr_get_community(pi->attr) &&
5571 !community_include(
5572 bgp_attr_get_community(pi->attr),
5573 COMMUNITY_NO_LLGR))
5574 continue;
5575 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5576 continue;
5577 if (safi == SAFI_UNICAST &&
5578 (peer->bgp->inst_type ==
5579 BGP_INSTANCE_TYPE_VRF ||
5580 peer->bgp->inst_type ==
5581 BGP_INSTANCE_TYPE_DEFAULT))
5582 vpn_leak_from_vrf_withdraw(
5583 bgp_get_default(), peer->bgp,
5584 pi);
5585
5586 bgp_rib_remove(dest, pi, peer, afi, safi);
5587 break;
5588 }
5589 }
5590 }
5591
5592 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5593 {
5594 struct bgp_dest *dest, *ndest;
5595 struct bgp_path_info *pi;
5596 struct bgp_table *table;
5597
5598 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5599 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5600 dest = bgp_route_next(dest)) {
5601 table = bgp_dest_get_bgp_table_info(dest);
5602 if (!table)
5603 continue;
5604
5605 for (ndest = bgp_table_top(table); ndest;
5606 ndest = bgp_route_next(ndest)) {
5607 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5608 pi = pi->next) {
5609 if (pi->peer != peer)
5610 continue;
5611
5612 if ((CHECK_FLAG(
5613 peer->af_sflags[afi][safi],
5614 PEER_STATUS_ENHANCED_REFRESH))
5615 && !CHECK_FLAG(pi->flags,
5616 BGP_PATH_STALE)
5617 && !CHECK_FLAG(
5618 pi->flags,
5619 BGP_PATH_UNUSEABLE)) {
5620 if (bgp_debug_neighbor_events(
5621 peer))
5622 zlog_debug(
5623 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5624 peer->host,
5625 afi2str(afi),
5626 safi2str(safi),
5627 bgp_dest_get_prefix(
5628 ndest));
5629
5630 bgp_path_info_set_flag(
5631 ndest, pi,
5632 BGP_PATH_STALE);
5633 }
5634 }
5635 }
5636 }
5637 } else {
5638 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5639 dest = bgp_route_next(dest)) {
5640 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5641 pi = pi->next) {
5642 if (pi->peer != peer)
5643 continue;
5644
5645 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5646 PEER_STATUS_ENHANCED_REFRESH))
5647 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5648 && !CHECK_FLAG(pi->flags,
5649 BGP_PATH_UNUSEABLE)) {
5650 if (bgp_debug_neighbor_events(peer))
5651 zlog_debug(
5652 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5653 peer->host,
5654 afi2str(afi),
5655 safi2str(safi),
5656 bgp_dest_get_prefix(
5657 dest));
5658
5659 bgp_path_info_set_flag(dest, pi,
5660 BGP_PATH_STALE);
5661 }
5662 }
5663 }
5664 }
5665 }
5666
5667 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5668 {
5669 if (peer->sort == BGP_PEER_IBGP)
5670 return true;
5671
5672 if (peer->sort == BGP_PEER_EBGP
5673 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5674 || FILTER_LIST_OUT_NAME(filter)
5675 || DISTRIBUTE_OUT_NAME(filter)))
5676 return true;
5677 return false;
5678 }
5679
5680 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5681 {
5682 if (peer->sort == BGP_PEER_IBGP)
5683 return true;
5684
5685 if (peer->sort == BGP_PEER_EBGP
5686 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5687 || FILTER_LIST_IN_NAME(filter)
5688 || DISTRIBUTE_IN_NAME(filter)))
5689 return true;
5690 return false;
5691 }
5692
5693 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5694 safi_t safi)
5695 {
5696 struct bgp_dest *dest;
5697 struct bgp_path_info *pi;
5698 struct bgp_path_info *next;
5699
5700 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5701 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5702 const struct prefix *p = bgp_dest_get_prefix(dest);
5703
5704 next = pi->next;
5705
5706 /* Unimport EVPN routes from VRFs */
5707 if (safi == SAFI_EVPN)
5708 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5709 SAFI_EVPN, p, pi);
5710
5711 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5712 && pi->type == ZEBRA_ROUTE_BGP
5713 && (pi->sub_type == BGP_ROUTE_NORMAL
5714 || pi->sub_type == BGP_ROUTE_AGGREGATE
5715 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5716
5717 if (bgp_fibupd_safi(safi))
5718 bgp_zebra_withdraw(p, pi, bgp, safi);
5719 }
5720
5721 bgp_path_info_reap(dest, pi);
5722 }
5723 }
5724
5725 /* Delete all kernel routes. */
5726 void bgp_cleanup_routes(struct bgp *bgp)
5727 {
5728 afi_t afi;
5729 struct bgp_dest *dest;
5730 struct bgp_table *table;
5731
5732 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5733 if (afi == AFI_L2VPN)
5734 continue;
5735 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5736 SAFI_UNICAST);
5737 /*
5738 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5739 */
5740 if (afi != AFI_L2VPN) {
5741 safi_t safi;
5742 safi = SAFI_MPLS_VPN;
5743 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5744 dest = bgp_route_next(dest)) {
5745 table = bgp_dest_get_bgp_table_info(dest);
5746 if (table != NULL) {
5747 bgp_cleanup_table(bgp, table, safi);
5748 bgp_table_finish(&table);
5749 bgp_dest_set_bgp_table_info(dest, NULL);
5750 bgp_dest_unlock_node(dest);
5751 }
5752 }
5753 safi = SAFI_ENCAP;
5754 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5755 dest = bgp_route_next(dest)) {
5756 table = bgp_dest_get_bgp_table_info(dest);
5757 if (table != NULL) {
5758 bgp_cleanup_table(bgp, table, safi);
5759 bgp_table_finish(&table);
5760 bgp_dest_set_bgp_table_info(dest, NULL);
5761 bgp_dest_unlock_node(dest);
5762 }
5763 }
5764 }
5765 }
5766 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5767 dest = bgp_route_next(dest)) {
5768 table = bgp_dest_get_bgp_table_info(dest);
5769 if (table != NULL) {
5770 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5771 bgp_table_finish(&table);
5772 bgp_dest_set_bgp_table_info(dest, NULL);
5773 bgp_dest_unlock_node(dest);
5774 }
5775 }
5776 }
5777
5778 void bgp_reset(void)
5779 {
5780 vty_reset();
5781 bgp_zclient_reset();
5782 access_list_reset();
5783 prefix_list_reset();
5784 }
5785
5786 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5787 {
5788 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5789 && CHECK_FLAG(peer->af_cap[afi][safi],
5790 PEER_CAP_ADDPATH_AF_TX_RCV));
5791 }
5792
5793 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5794 value. */
5795 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5796 struct bgp_nlri *packet)
5797 {
5798 uint8_t *pnt;
5799 uint8_t *lim;
5800 struct prefix p;
5801 int psize;
5802 int ret;
5803 afi_t afi;
5804 safi_t safi;
5805 bool addpath_capable;
5806 uint32_t addpath_id;
5807
5808 pnt = packet->nlri;
5809 lim = pnt + packet->length;
5810 afi = packet->afi;
5811 safi = packet->safi;
5812 addpath_id = 0;
5813 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5814
5815 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5816 syntactic validity. If the field is syntactically incorrect,
5817 then the Error Subcode is set to Invalid Network Field. */
5818 for (; pnt < lim; pnt += psize) {
5819 /* Clear prefix structure. */
5820 memset(&p, 0, sizeof(p));
5821
5822 if (addpath_capable) {
5823
5824 /* When packet overflow occurs return immediately. */
5825 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5826 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5827
5828 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5829 addpath_id = ntohl(addpath_id);
5830 pnt += BGP_ADDPATH_ID_LEN;
5831 }
5832
5833 /* Fetch prefix length. */
5834 p.prefixlen = *pnt++;
5835 /* afi/safi validity already verified by caller,
5836 * bgp_update_receive */
5837 p.family = afi2family(afi);
5838
5839 /* Prefix length check. */
5840 if (p.prefixlen > prefix_blen(&p) * 8) {
5841 flog_err(
5842 EC_BGP_UPDATE_RCV,
5843 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5844 peer->host, p.prefixlen, packet->afi);
5845 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5846 }
5847
5848 /* Packet size overflow check. */
5849 psize = PSIZE(p.prefixlen);
5850
5851 /* When packet overflow occur return immediately. */
5852 if (pnt + psize > lim) {
5853 flog_err(
5854 EC_BGP_UPDATE_RCV,
5855 "%s [Error] Update packet error (prefix length %d overflows packet)",
5856 peer->host, p.prefixlen);
5857 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5858 }
5859
5860 /* Defensive coding, double-check the psize fits in a struct
5861 * prefix for the v4 and v6 afi's and unicast/multicast */
5862 if (psize > (ssize_t)sizeof(p.u.val)) {
5863 flog_err(
5864 EC_BGP_UPDATE_RCV,
5865 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5866 peer->host, p.prefixlen, sizeof(p.u.val));
5867 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5868 }
5869
5870 /* Fetch prefix from NLRI packet. */
5871 memcpy(p.u.val, pnt, psize);
5872
5873 /* Check address. */
5874 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5875 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5876 /* From RFC4271 Section 6.3:
5877 *
5878 * If a prefix in the NLRI field is semantically
5879 * incorrect
5880 * (e.g., an unexpected multicast IP address),
5881 * an error SHOULD
5882 * be logged locally, and the prefix SHOULD be
5883 * ignored.
5884 */
5885 flog_err(
5886 EC_BGP_UPDATE_RCV,
5887 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5888 peer->host, &p.u.prefix4);
5889 continue;
5890 }
5891 }
5892
5893 /* Check address. */
5894 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5895 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5896 flog_err(
5897 EC_BGP_UPDATE_RCV,
5898 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
5899 peer->host, &p.u.prefix6);
5900
5901 continue;
5902 }
5903 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5904 flog_err(
5905 EC_BGP_UPDATE_RCV,
5906 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
5907 peer->host, &p.u.prefix6);
5908
5909 continue;
5910 }
5911 }
5912
5913 /* Normal process. */
5914 if (attr)
5915 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5916 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5917 NULL, NULL, 0, 0, NULL);
5918 else
5919 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5920 safi, ZEBRA_ROUTE_BGP,
5921 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5922 NULL);
5923
5924 /* Do not send BGP notification twice when maximum-prefix count
5925 * overflow. */
5926 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5927 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5928
5929 /* Address family configuration mismatch. */
5930 if (ret < 0)
5931 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5932 }
5933
5934 /* Packet length consistency check. */
5935 if (pnt != lim) {
5936 flog_err(
5937 EC_BGP_UPDATE_RCV,
5938 "%s [Error] Update packet error (prefix length mismatch with total length)",
5939 peer->host);
5940 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5941 }
5942
5943 return BGP_NLRI_PARSE_OK;
5944 }
5945
5946 static struct bgp_static *bgp_static_new(void)
5947 {
5948 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5949 }
5950
5951 static void bgp_static_free(struct bgp_static *bgp_static)
5952 {
5953 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5954 route_map_counter_decrement(bgp_static->rmap.map);
5955
5956 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5957 XFREE(MTYPE_BGP_STATIC, bgp_static);
5958 }
5959
5960 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5961 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5962 {
5963 struct bgp_dest *dest;
5964 struct bgp_path_info *pi;
5965 struct bgp_path_info *new;
5966 struct bgp_path_info rmap_path;
5967 struct attr attr;
5968 struct attr *attr_new;
5969 route_map_result_t ret;
5970 #ifdef ENABLE_BGP_VNC
5971 int vnc_implicit_withdraw = 0;
5972 #endif
5973
5974 assert(bgp_static);
5975
5976 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5977
5978 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
5979
5980 attr.nexthop = bgp_static->igpnexthop;
5981 attr.med = bgp_static->igpmetric;
5982 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5983
5984 if (afi == AFI_IP)
5985 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
5986
5987 if (bgp_static->atomic)
5988 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5989
5990 /* Store label index, if required. */
5991 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5992 attr.label_index = bgp_static->label_index;
5993 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5994 }
5995
5996 /* Apply route-map. */
5997 if (bgp_static->rmap.name) {
5998 struct attr attr_tmp = attr;
5999
6000 memset(&rmap_path, 0, sizeof(rmap_path));
6001 rmap_path.peer = bgp->peer_self;
6002 rmap_path.attr = &attr_tmp;
6003
6004 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6005
6006 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6007
6008 bgp->peer_self->rmap_type = 0;
6009
6010 if (ret == RMAP_DENYMATCH) {
6011 /* Free uninterned attribute. */
6012 bgp_attr_flush(&attr_tmp);
6013
6014 /* Unintern original. */
6015 aspath_unintern(&attr.aspath);
6016 bgp_static_withdraw(bgp, p, afi, safi);
6017 bgp_dest_unlock_node(dest);
6018 return;
6019 }
6020
6021 if (bgp_in_graceful_shutdown(bgp))
6022 bgp_attr_add_gshut_community(&attr_tmp);
6023
6024 attr_new = bgp_attr_intern(&attr_tmp);
6025 } else {
6026
6027 if (bgp_in_graceful_shutdown(bgp))
6028 bgp_attr_add_gshut_community(&attr);
6029
6030 attr_new = bgp_attr_intern(&attr);
6031 }
6032
6033 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6034 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6035 && pi->sub_type == BGP_ROUTE_STATIC)
6036 break;
6037
6038 if (pi) {
6039 if (attrhash_cmp(pi->attr, attr_new)
6040 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6041 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6042 bgp_dest_unlock_node(dest);
6043 bgp_attr_unintern(&attr_new);
6044 aspath_unintern(&attr.aspath);
6045 return;
6046 } else {
6047 /* The attribute is changed. */
6048 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6049
6050 /* Rewrite BGP route information. */
6051 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6052 bgp_path_info_restore(dest, pi);
6053 else
6054 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6055 #ifdef ENABLE_BGP_VNC
6056 if ((afi == AFI_IP || afi == AFI_IP6)
6057 && (safi == SAFI_UNICAST)) {
6058 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6059 /*
6060 * Implicit withdraw case.
6061 * We have to do this before pi is
6062 * changed
6063 */
6064 ++vnc_implicit_withdraw;
6065 vnc_import_bgp_del_route(bgp, p, pi);
6066 vnc_import_bgp_exterior_del_route(
6067 bgp, p, pi);
6068 }
6069 }
6070 #endif
6071 bgp_attr_unintern(&pi->attr);
6072 pi->attr = attr_new;
6073 pi->uptime = monotime(NULL);
6074 #ifdef ENABLE_BGP_VNC
6075 if ((afi == AFI_IP || afi == AFI_IP6)
6076 && (safi == SAFI_UNICAST)) {
6077 if (vnc_implicit_withdraw) {
6078 vnc_import_bgp_add_route(bgp, p, pi);
6079 vnc_import_bgp_exterior_add_route(
6080 bgp, p, pi);
6081 }
6082 }
6083 #endif
6084
6085 /* Nexthop reachability check. */
6086 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6087 && (safi == SAFI_UNICAST
6088 || safi == SAFI_LABELED_UNICAST)) {
6089
6090 struct bgp *bgp_nexthop = bgp;
6091
6092 if (pi->extra && pi->extra->bgp_orig)
6093 bgp_nexthop = pi->extra->bgp_orig;
6094
6095 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6096 afi, safi, pi, NULL,
6097 0, p))
6098 bgp_path_info_set_flag(dest, pi,
6099 BGP_PATH_VALID);
6100 else {
6101 if (BGP_DEBUG(nht, NHT)) {
6102 char buf1[INET6_ADDRSTRLEN];
6103 inet_ntop(p->family,
6104 &p->u.prefix, buf1,
6105 INET6_ADDRSTRLEN);
6106 zlog_debug(
6107 "%s(%s): Route not in table, not advertising",
6108 __func__, buf1);
6109 }
6110 bgp_path_info_unset_flag(
6111 dest, pi, BGP_PATH_VALID);
6112 }
6113 } else {
6114 /* Delete the NHT structure if any, if we're
6115 * toggling between
6116 * enabling/disabling import check. We
6117 * deregister the route
6118 * from NHT to avoid overloading NHT and the
6119 * process interaction
6120 */
6121 bgp_unlink_nexthop(pi);
6122 bgp_path_info_set_flag(dest, pi,
6123 BGP_PATH_VALID);
6124 }
6125 /* Process change. */
6126 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6127 bgp_process(bgp, dest, afi, safi);
6128
6129 if (SAFI_UNICAST == safi
6130 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6131 || bgp->inst_type
6132 == BGP_INSTANCE_TYPE_DEFAULT)) {
6133 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6134 pi);
6135 }
6136
6137 bgp_dest_unlock_node(dest);
6138 aspath_unintern(&attr.aspath);
6139 return;
6140 }
6141 }
6142
6143 /* Make new BGP info. */
6144 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6145 attr_new, dest);
6146 /* Nexthop reachability check. */
6147 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6148 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6149 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6150 p))
6151 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6152 else {
6153 if (BGP_DEBUG(nht, NHT)) {
6154 char buf1[INET6_ADDRSTRLEN];
6155 inet_ntop(p->family, &p->u.prefix, buf1,
6156 INET6_ADDRSTRLEN);
6157 zlog_debug(
6158 "%s(%s): Route not in table, not advertising",
6159 __func__, buf1);
6160 }
6161 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6162 }
6163 } else {
6164 /* Delete the NHT structure if any, if we're toggling between
6165 * enabling/disabling import check. We deregister the route
6166 * from NHT to avoid overloading NHT and the process interaction
6167 */
6168 bgp_unlink_nexthop(new);
6169
6170 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6171 }
6172
6173 /* Aggregate address increment. */
6174 bgp_aggregate_increment(bgp, p, new, afi, safi);
6175
6176 /* Register new BGP information. */
6177 bgp_path_info_add(dest, new);
6178
6179 /* route_node_get lock */
6180 bgp_dest_unlock_node(dest);
6181
6182 /* Process change. */
6183 bgp_process(bgp, dest, afi, safi);
6184
6185 if (SAFI_UNICAST == safi
6186 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6187 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6188 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6189 }
6190
6191 /* Unintern original. */
6192 aspath_unintern(&attr.aspath);
6193 }
6194
6195 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6196 safi_t safi)
6197 {
6198 struct bgp_dest *dest;
6199 struct bgp_path_info *pi;
6200
6201 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6202
6203 /* Check selected route and self inserted route. */
6204 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6205 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6206 && pi->sub_type == BGP_ROUTE_STATIC)
6207 break;
6208
6209 /* Withdraw static BGP route from routing table. */
6210 if (pi) {
6211 if (SAFI_UNICAST == safi
6212 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6213 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6214 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6215 }
6216 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6217 bgp_unlink_nexthop(pi);
6218 bgp_path_info_delete(dest, pi);
6219 bgp_process(bgp, dest, afi, safi);
6220 }
6221
6222 /* Unlock bgp_node_lookup. */
6223 bgp_dest_unlock_node(dest);
6224 }
6225
6226 /*
6227 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6228 */
6229 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6230 afi_t afi, safi_t safi,
6231 struct prefix_rd *prd)
6232 {
6233 struct bgp_dest *dest;
6234 struct bgp_path_info *pi;
6235
6236 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6237
6238 /* Check selected route and self inserted route. */
6239 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6240 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6241 && pi->sub_type == BGP_ROUTE_STATIC)
6242 break;
6243
6244 /* Withdraw static BGP route from routing table. */
6245 if (pi) {
6246 #ifdef ENABLE_BGP_VNC
6247 rfapiProcessWithdraw(
6248 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6249 1); /* Kill, since it is an administrative change */
6250 #endif
6251 if (SAFI_MPLS_VPN == safi
6252 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6253 vpn_leak_to_vrf_withdraw(bgp, pi);
6254 }
6255 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6256 bgp_path_info_delete(dest, pi);
6257 bgp_process(bgp, dest, afi, safi);
6258 }
6259
6260 /* Unlock bgp_node_lookup. */
6261 bgp_dest_unlock_node(dest);
6262 }
6263
6264 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6265 struct bgp_static *bgp_static, afi_t afi,
6266 safi_t safi)
6267 {
6268 struct bgp_dest *dest;
6269 struct bgp_path_info *new;
6270 struct attr *attr_new;
6271 struct attr attr = {0};
6272 struct bgp_path_info *pi;
6273 #ifdef ENABLE_BGP_VNC
6274 mpls_label_t label = 0;
6275 #endif
6276 uint32_t num_labels = 0;
6277
6278 assert(bgp_static);
6279
6280 if (bgp_static->label != MPLS_INVALID_LABEL)
6281 num_labels = 1;
6282 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6283 &bgp_static->prd);
6284
6285 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6286
6287 attr.nexthop = bgp_static->igpnexthop;
6288 attr.med = bgp_static->igpmetric;
6289 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6290
6291 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6292 || (safi == SAFI_ENCAP)) {
6293 if (afi == AFI_IP) {
6294 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6295 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6296 }
6297 }
6298 if (afi == AFI_L2VPN) {
6299 if (bgp_static->gatewayIp.family == AF_INET) {
6300 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6301 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6302 &bgp_static->gatewayIp.u.prefix4,
6303 IPV4_MAX_BYTELEN);
6304 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6305 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6306 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6307 &bgp_static->gatewayIp.u.prefix6,
6308 IPV6_MAX_BYTELEN);
6309 }
6310 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6311 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6312 struct bgp_encap_type_vxlan bet;
6313 memset(&bet, 0, sizeof(bet));
6314 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6315 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6316 }
6317 if (bgp_static->router_mac) {
6318 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6319 }
6320 }
6321 /* Apply route-map. */
6322 if (bgp_static->rmap.name) {
6323 struct attr attr_tmp = attr;
6324 struct bgp_path_info rmap_path;
6325 route_map_result_t ret;
6326
6327 rmap_path.peer = bgp->peer_self;
6328 rmap_path.attr = &attr_tmp;
6329
6330 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6331
6332 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6333
6334 bgp->peer_self->rmap_type = 0;
6335
6336 if (ret == RMAP_DENYMATCH) {
6337 /* Free uninterned attribute. */
6338 bgp_attr_flush(&attr_tmp);
6339
6340 /* Unintern original. */
6341 aspath_unintern(&attr.aspath);
6342 bgp_static_withdraw_safi(bgp, p, afi, safi,
6343 &bgp_static->prd);
6344 bgp_dest_unlock_node(dest);
6345 return;
6346 }
6347
6348 attr_new = bgp_attr_intern(&attr_tmp);
6349 } else {
6350 attr_new = bgp_attr_intern(&attr);
6351 }
6352
6353 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6354 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6355 && pi->sub_type == BGP_ROUTE_STATIC)
6356 break;
6357
6358 if (pi) {
6359 if (attrhash_cmp(pi->attr, attr_new)
6360 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6361 bgp_dest_unlock_node(dest);
6362 bgp_attr_unintern(&attr_new);
6363 aspath_unintern(&attr.aspath);
6364 return;
6365 } else {
6366 /* The attribute is changed. */
6367 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6368
6369 /* Rewrite BGP route information. */
6370 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6371 bgp_path_info_restore(dest, pi);
6372 else
6373 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6374 bgp_attr_unintern(&pi->attr);
6375 pi->attr = attr_new;
6376 pi->uptime = monotime(NULL);
6377 #ifdef ENABLE_BGP_VNC
6378 if (pi->extra)
6379 label = decode_label(&pi->extra->label[0]);
6380 #endif
6381
6382 /* Process change. */
6383 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6384 bgp_process(bgp, dest, afi, safi);
6385
6386 if (SAFI_MPLS_VPN == safi
6387 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6388 vpn_leak_to_vrf_update(bgp, pi);
6389 }
6390 #ifdef ENABLE_BGP_VNC
6391 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6392 pi->attr, afi, safi, pi->type,
6393 pi->sub_type, &label);
6394 #endif
6395 bgp_dest_unlock_node(dest);
6396 aspath_unintern(&attr.aspath);
6397 return;
6398 }
6399 }
6400
6401
6402 /* Make new BGP info. */
6403 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6404 attr_new, dest);
6405 SET_FLAG(new->flags, BGP_PATH_VALID);
6406 bgp_path_info_extra_get(new);
6407 if (num_labels) {
6408 new->extra->label[0] = bgp_static->label;
6409 new->extra->num_labels = num_labels;
6410 }
6411 #ifdef ENABLE_BGP_VNC
6412 label = decode_label(&bgp_static->label);
6413 #endif
6414
6415 /* Aggregate address increment. */
6416 bgp_aggregate_increment(bgp, p, new, afi, safi);
6417
6418 /* Register new BGP information. */
6419 bgp_path_info_add(dest, new);
6420 /* route_node_get lock */
6421 bgp_dest_unlock_node(dest);
6422
6423 /* Process change. */
6424 bgp_process(bgp, dest, afi, safi);
6425
6426 if (SAFI_MPLS_VPN == safi
6427 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6428 vpn_leak_to_vrf_update(bgp, new);
6429 }
6430 #ifdef ENABLE_BGP_VNC
6431 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6432 safi, new->type, new->sub_type, &label);
6433 #endif
6434
6435 /* Unintern original. */
6436 aspath_unintern(&attr.aspath);
6437 }
6438
6439 /* Configure static BGP network. When user don't run zebra, static
6440 route should be installed as valid. */
6441 static int bgp_static_set(struct vty *vty, const char *negate,
6442 const char *ip_str, afi_t afi, safi_t safi,
6443 const char *rmap, int backdoor, uint32_t label_index)
6444 {
6445 VTY_DECLVAR_CONTEXT(bgp, bgp);
6446 int ret;
6447 struct prefix p;
6448 struct bgp_static *bgp_static;
6449 struct bgp_dest *dest;
6450 uint8_t need_update = 0;
6451
6452 /* Convert IP prefix string to struct prefix. */
6453 ret = str2prefix(ip_str, &p);
6454 if (!ret) {
6455 vty_out(vty, "%% Malformed prefix\n");
6456 return CMD_WARNING_CONFIG_FAILED;
6457 }
6458 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6459 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6460 return CMD_WARNING_CONFIG_FAILED;
6461 }
6462
6463 apply_mask(&p);
6464
6465 if (negate) {
6466
6467 /* Set BGP static route configuration. */
6468 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6469
6470 if (!dest) {
6471 vty_out(vty, "%% Can't find static route specified\n");
6472 return CMD_WARNING_CONFIG_FAILED;
6473 }
6474
6475 bgp_static = bgp_dest_get_bgp_static_info(dest);
6476
6477 if ((label_index != BGP_INVALID_LABEL_INDEX)
6478 && (label_index != bgp_static->label_index)) {
6479 vty_out(vty,
6480 "%% label-index doesn't match static route\n");
6481 bgp_dest_unlock_node(dest);
6482 return CMD_WARNING_CONFIG_FAILED;
6483 }
6484
6485 if ((rmap && bgp_static->rmap.name)
6486 && strcmp(rmap, bgp_static->rmap.name)) {
6487 vty_out(vty,
6488 "%% route-map name doesn't match static route\n");
6489 bgp_dest_unlock_node(dest);
6490 return CMD_WARNING_CONFIG_FAILED;
6491 }
6492
6493 /* Update BGP RIB. */
6494 if (!bgp_static->backdoor)
6495 bgp_static_withdraw(bgp, &p, afi, safi);
6496
6497 /* Clear configuration. */
6498 bgp_static_free(bgp_static);
6499 bgp_dest_set_bgp_static_info(dest, NULL);
6500 bgp_dest_unlock_node(dest);
6501 bgp_dest_unlock_node(dest);
6502 } else {
6503
6504 /* Set BGP static route configuration. */
6505 dest = bgp_node_get(bgp->route[afi][safi], &p);
6506 bgp_static = bgp_dest_get_bgp_static_info(dest);
6507 if (bgp_static) {
6508 /* Configuration change. */
6509 /* Label index cannot be changed. */
6510 if (bgp_static->label_index != label_index) {
6511 vty_out(vty, "%% cannot change label-index\n");
6512 bgp_dest_unlock_node(dest);
6513 return CMD_WARNING_CONFIG_FAILED;
6514 }
6515
6516 /* Check previous routes are installed into BGP. */
6517 if (bgp_static->valid
6518 && bgp_static->backdoor != backdoor)
6519 need_update = 1;
6520
6521 bgp_static->backdoor = backdoor;
6522
6523 if (rmap) {
6524 XFREE(MTYPE_ROUTE_MAP_NAME,
6525 bgp_static->rmap.name);
6526 route_map_counter_decrement(
6527 bgp_static->rmap.map);
6528 bgp_static->rmap.name =
6529 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6530 bgp_static->rmap.map =
6531 route_map_lookup_by_name(rmap);
6532 route_map_counter_increment(
6533 bgp_static->rmap.map);
6534 } else {
6535 XFREE(MTYPE_ROUTE_MAP_NAME,
6536 bgp_static->rmap.name);
6537 route_map_counter_decrement(
6538 bgp_static->rmap.map);
6539 bgp_static->rmap.map = NULL;
6540 bgp_static->valid = 0;
6541 }
6542 bgp_dest_unlock_node(dest);
6543 } else {
6544 /* New configuration. */
6545 bgp_static = bgp_static_new();
6546 bgp_static->backdoor = backdoor;
6547 bgp_static->valid = 0;
6548 bgp_static->igpmetric = 0;
6549 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6550 bgp_static->label_index = label_index;
6551
6552 if (rmap) {
6553 XFREE(MTYPE_ROUTE_MAP_NAME,
6554 bgp_static->rmap.name);
6555 route_map_counter_decrement(
6556 bgp_static->rmap.map);
6557 bgp_static->rmap.name =
6558 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6559 bgp_static->rmap.map =
6560 route_map_lookup_by_name(rmap);
6561 route_map_counter_increment(
6562 bgp_static->rmap.map);
6563 }
6564 bgp_dest_set_bgp_static_info(dest, bgp_static);
6565 }
6566
6567 bgp_static->valid = 1;
6568 if (need_update)
6569 bgp_static_withdraw(bgp, &p, afi, safi);
6570
6571 if (!bgp_static->backdoor)
6572 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6573 }
6574
6575 return CMD_SUCCESS;
6576 }
6577
6578 void bgp_static_add(struct bgp *bgp)
6579 {
6580 afi_t afi;
6581 safi_t safi;
6582 struct bgp_dest *dest;
6583 struct bgp_dest *rm;
6584 struct bgp_table *table;
6585 struct bgp_static *bgp_static;
6586
6587 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6588 FOREACH_AFI_SAFI (afi, safi)
6589 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6590 dest = bgp_route_next(dest)) {
6591 if (!bgp_dest_has_bgp_path_info_data(dest))
6592 continue;
6593
6594 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6595 || (safi == SAFI_EVPN)) {
6596 table = bgp_dest_get_bgp_table_info(dest);
6597
6598 for (rm = bgp_table_top(table); rm;
6599 rm = bgp_route_next(rm)) {
6600 bgp_static =
6601 bgp_dest_get_bgp_static_info(
6602 rm);
6603 bgp_static_update_safi(
6604 bgp, bgp_dest_get_prefix(rm),
6605 bgp_static, afi, safi);
6606 }
6607 } else {
6608 bgp_static_update(
6609 bgp, bgp_dest_get_prefix(dest),
6610 bgp_dest_get_bgp_static_info(dest), afi,
6611 safi);
6612 }
6613 }
6614 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6615 }
6616
6617 /* Called from bgp_delete(). Delete all static routes from the BGP
6618 instance. */
6619 void bgp_static_delete(struct bgp *bgp)
6620 {
6621 afi_t afi;
6622 safi_t safi;
6623 struct bgp_dest *dest;
6624 struct bgp_dest *rm;
6625 struct bgp_table *table;
6626 struct bgp_static *bgp_static;
6627
6628 FOREACH_AFI_SAFI (afi, safi)
6629 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6630 dest = bgp_route_next(dest)) {
6631 if (!bgp_dest_has_bgp_path_info_data(dest))
6632 continue;
6633
6634 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6635 || (safi == SAFI_EVPN)) {
6636 table = bgp_dest_get_bgp_table_info(dest);
6637
6638 for (rm = bgp_table_top(table); rm;
6639 rm = bgp_route_next(rm)) {
6640 bgp_static =
6641 bgp_dest_get_bgp_static_info(
6642 rm);
6643 if (!bgp_static)
6644 continue;
6645
6646 bgp_static_withdraw_safi(
6647 bgp, bgp_dest_get_prefix(rm),
6648 AFI_IP, safi,
6649 (struct prefix_rd *)
6650 bgp_dest_get_prefix(
6651 dest));
6652 bgp_static_free(bgp_static);
6653 bgp_dest_set_bgp_static_info(rm,
6654 NULL);
6655 bgp_dest_unlock_node(rm);
6656 }
6657 } else {
6658 bgp_static = bgp_dest_get_bgp_static_info(dest);
6659 bgp_static_withdraw(bgp,
6660 bgp_dest_get_prefix(dest),
6661 afi, safi);
6662 bgp_static_free(bgp_static);
6663 bgp_dest_set_bgp_static_info(dest, NULL);
6664 bgp_dest_unlock_node(dest);
6665 }
6666 }
6667 }
6668
6669 void bgp_static_redo_import_check(struct bgp *bgp)
6670 {
6671 afi_t afi;
6672 safi_t safi;
6673 struct bgp_dest *dest;
6674 struct bgp_dest *rm;
6675 struct bgp_table *table;
6676 struct bgp_static *bgp_static;
6677
6678 /* Use this flag to force reprocessing of the route */
6679 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6680 FOREACH_AFI_SAFI (afi, safi) {
6681 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6682 dest = bgp_route_next(dest)) {
6683 if (!bgp_dest_has_bgp_path_info_data(dest))
6684 continue;
6685
6686 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6687 || (safi == SAFI_EVPN)) {
6688 table = bgp_dest_get_bgp_table_info(dest);
6689
6690 for (rm = bgp_table_top(table); rm;
6691 rm = bgp_route_next(rm)) {
6692 bgp_static =
6693 bgp_dest_get_bgp_static_info(
6694 rm);
6695 bgp_static_update_safi(
6696 bgp, bgp_dest_get_prefix(rm),
6697 bgp_static, afi, safi);
6698 }
6699 } else {
6700 bgp_static = bgp_dest_get_bgp_static_info(dest);
6701 bgp_static_update(bgp,
6702 bgp_dest_get_prefix(dest),
6703 bgp_static, afi, safi);
6704 }
6705 }
6706 }
6707 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6708 }
6709
6710 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6711 safi_t safi)
6712 {
6713 struct bgp_table *table;
6714 struct bgp_dest *dest;
6715 struct bgp_path_info *pi;
6716
6717 /* Do not install the aggregate route if BGP is in the
6718 * process of termination.
6719 */
6720 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6721 || (bgp->peer_self == NULL))
6722 return;
6723
6724 table = bgp->rib[afi][safi];
6725 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6726 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6727 if (pi->peer == bgp->peer_self
6728 && ((pi->type == ZEBRA_ROUTE_BGP
6729 && pi->sub_type == BGP_ROUTE_STATIC)
6730 || (pi->type != ZEBRA_ROUTE_BGP
6731 && pi->sub_type
6732 == BGP_ROUTE_REDISTRIBUTE))) {
6733 bgp_aggregate_decrement(
6734 bgp, bgp_dest_get_prefix(dest), pi, afi,
6735 safi);
6736 bgp_unlink_nexthop(pi);
6737 bgp_path_info_delete(dest, pi);
6738 bgp_process(bgp, dest, afi, safi);
6739 }
6740 }
6741 }
6742 }
6743
6744 /*
6745 * Purge all networks and redistributed routes from routing table.
6746 * Invoked upon the instance going down.
6747 */
6748 void bgp_purge_static_redist_routes(struct bgp *bgp)
6749 {
6750 afi_t afi;
6751 safi_t safi;
6752
6753 FOREACH_AFI_SAFI (afi, safi)
6754 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6755 }
6756
6757 /*
6758 * gpz 110624
6759 * Currently this is used to set static routes for VPN and ENCAP.
6760 * I think it can probably be factored with bgp_static_set.
6761 */
6762 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6763 const char *ip_str, const char *rd_str,
6764 const char *label_str, const char *rmap_str,
6765 int evpn_type, const char *esi, const char *gwip,
6766 const char *ethtag, const char *routermac)
6767 {
6768 VTY_DECLVAR_CONTEXT(bgp, bgp);
6769 int ret;
6770 struct prefix p;
6771 struct prefix_rd prd;
6772 struct bgp_dest *pdest;
6773 struct bgp_dest *dest;
6774 struct bgp_table *table;
6775 struct bgp_static *bgp_static;
6776 mpls_label_t label = MPLS_INVALID_LABEL;
6777 struct prefix gw_ip;
6778
6779 /* validate ip prefix */
6780 ret = str2prefix(ip_str, &p);
6781 if (!ret) {
6782 vty_out(vty, "%% Malformed prefix\n");
6783 return CMD_WARNING_CONFIG_FAILED;
6784 }
6785 apply_mask(&p);
6786 if ((afi == AFI_L2VPN)
6787 && (bgp_build_evpn_prefix(evpn_type,
6788 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6789 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6790 return CMD_WARNING_CONFIG_FAILED;
6791 }
6792
6793 ret = str2prefix_rd(rd_str, &prd);
6794 if (!ret) {
6795 vty_out(vty, "%% Malformed rd\n");
6796 return CMD_WARNING_CONFIG_FAILED;
6797 }
6798
6799 if (label_str) {
6800 unsigned long label_val;
6801 label_val = strtoul(label_str, NULL, 10);
6802 encode_label(label_val, &label);
6803 }
6804
6805 if (safi == SAFI_EVPN) {
6806 if (esi && str2esi(esi, NULL) == 0) {
6807 vty_out(vty, "%% Malformed ESI\n");
6808 return CMD_WARNING_CONFIG_FAILED;
6809 }
6810 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6811 vty_out(vty, "%% Malformed Router MAC\n");
6812 return CMD_WARNING_CONFIG_FAILED;
6813 }
6814 if (gwip) {
6815 memset(&gw_ip, 0, sizeof(gw_ip));
6816 ret = str2prefix(gwip, &gw_ip);
6817 if (!ret) {
6818 vty_out(vty, "%% Malformed GatewayIp\n");
6819 return CMD_WARNING_CONFIG_FAILED;
6820 }
6821 if ((gw_ip.family == AF_INET
6822 && is_evpn_prefix_ipaddr_v6(
6823 (struct prefix_evpn *)&p))
6824 || (gw_ip.family == AF_INET6
6825 && is_evpn_prefix_ipaddr_v4(
6826 (struct prefix_evpn *)&p))) {
6827 vty_out(vty,
6828 "%% GatewayIp family differs with IP prefix\n");
6829 return CMD_WARNING_CONFIG_FAILED;
6830 }
6831 }
6832 }
6833 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6834 if (!bgp_dest_has_bgp_path_info_data(pdest))
6835 bgp_dest_set_bgp_table_info(pdest,
6836 bgp_table_init(bgp, afi, safi));
6837 table = bgp_dest_get_bgp_table_info(pdest);
6838
6839 dest = bgp_node_get(table, &p);
6840
6841 if (bgp_dest_has_bgp_path_info_data(dest)) {
6842 vty_out(vty, "%% Same network configuration exists\n");
6843 bgp_dest_unlock_node(dest);
6844 } else {
6845 /* New configuration. */
6846 bgp_static = bgp_static_new();
6847 bgp_static->backdoor = 0;
6848 bgp_static->valid = 0;
6849 bgp_static->igpmetric = 0;
6850 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6851 bgp_static->label = label;
6852 bgp_static->prd = prd;
6853
6854 if (rmap_str) {
6855 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6856 route_map_counter_decrement(bgp_static->rmap.map);
6857 bgp_static->rmap.name =
6858 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6859 bgp_static->rmap.map =
6860 route_map_lookup_by_name(rmap_str);
6861 route_map_counter_increment(bgp_static->rmap.map);
6862 }
6863
6864 if (safi == SAFI_EVPN) {
6865 if (esi) {
6866 bgp_static->eth_s_id =
6867 XCALLOC(MTYPE_ATTR,
6868 sizeof(esi_t));
6869 str2esi(esi, bgp_static->eth_s_id);
6870 }
6871 if (routermac) {
6872 bgp_static->router_mac =
6873 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6874 (void)prefix_str2mac(routermac,
6875 bgp_static->router_mac);
6876 }
6877 if (gwip)
6878 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6879 }
6880 bgp_dest_set_bgp_static_info(dest, bgp_static);
6881
6882 bgp_static->valid = 1;
6883 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6884 }
6885
6886 return CMD_SUCCESS;
6887 }
6888
6889 /* Configure static BGP network. */
6890 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6891 const char *ip_str, const char *rd_str,
6892 const char *label_str, int evpn_type, const char *esi,
6893 const char *gwip, const char *ethtag)
6894 {
6895 VTY_DECLVAR_CONTEXT(bgp, bgp);
6896 int ret;
6897 struct prefix p;
6898 struct prefix_rd prd;
6899 struct bgp_dest *pdest;
6900 struct bgp_dest *dest;
6901 struct bgp_table *table;
6902 struct bgp_static *bgp_static;
6903 mpls_label_t label = MPLS_INVALID_LABEL;
6904
6905 /* Convert IP prefix string to struct prefix. */
6906 ret = str2prefix(ip_str, &p);
6907 if (!ret) {
6908 vty_out(vty, "%% Malformed prefix\n");
6909 return CMD_WARNING_CONFIG_FAILED;
6910 }
6911 apply_mask(&p);
6912 if ((afi == AFI_L2VPN)
6913 && (bgp_build_evpn_prefix(evpn_type,
6914 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6915 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6916 return CMD_WARNING_CONFIG_FAILED;
6917 }
6918 ret = str2prefix_rd(rd_str, &prd);
6919 if (!ret) {
6920 vty_out(vty, "%% Malformed rd\n");
6921 return CMD_WARNING_CONFIG_FAILED;
6922 }
6923
6924 if (label_str) {
6925 unsigned long label_val;
6926 label_val = strtoul(label_str, NULL, 10);
6927 encode_label(label_val, &label);
6928 }
6929
6930 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6931 if (!bgp_dest_has_bgp_path_info_data(pdest))
6932 bgp_dest_set_bgp_table_info(pdest,
6933 bgp_table_init(bgp, afi, safi));
6934 else
6935 bgp_dest_unlock_node(pdest);
6936 table = bgp_dest_get_bgp_table_info(pdest);
6937
6938 dest = bgp_node_lookup(table, &p);
6939
6940 if (dest) {
6941 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6942
6943 bgp_static = bgp_dest_get_bgp_static_info(dest);
6944 bgp_static_free(bgp_static);
6945 bgp_dest_set_bgp_static_info(dest, NULL);
6946 bgp_dest_unlock_node(dest);
6947 bgp_dest_unlock_node(dest);
6948 } else
6949 vty_out(vty, "%% Can't find the route\n");
6950
6951 return CMD_SUCCESS;
6952 }
6953
6954 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6955 const char *rmap_name)
6956 {
6957 VTY_DECLVAR_CONTEXT(bgp, bgp);
6958 struct bgp_rmap *rmap;
6959
6960 rmap = &bgp->table_map[afi][safi];
6961 if (rmap_name) {
6962 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6963 route_map_counter_decrement(rmap->map);
6964 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6965 rmap->map = route_map_lookup_by_name(rmap_name);
6966 route_map_counter_increment(rmap->map);
6967 } else {
6968 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6969 route_map_counter_decrement(rmap->map);
6970 rmap->map = NULL;
6971 }
6972
6973 if (bgp_fibupd_safi(safi))
6974 bgp_zebra_announce_table(bgp, afi, safi);
6975
6976 return CMD_SUCCESS;
6977 }
6978
6979 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6980 const char *rmap_name)
6981 {
6982 VTY_DECLVAR_CONTEXT(bgp, bgp);
6983 struct bgp_rmap *rmap;
6984
6985 rmap = &bgp->table_map[afi][safi];
6986 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6987 route_map_counter_decrement(rmap->map);
6988 rmap->map = NULL;
6989
6990 if (bgp_fibupd_safi(safi))
6991 bgp_zebra_announce_table(bgp, afi, safi);
6992
6993 return CMD_SUCCESS;
6994 }
6995
6996 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6997 safi_t safi)
6998 {
6999 if (bgp->table_map[afi][safi].name) {
7000 vty_out(vty, " table-map %s\n",
7001 bgp->table_map[afi][safi].name);
7002 }
7003 }
7004
7005 DEFUN (bgp_table_map,
7006 bgp_table_map_cmd,
7007 "table-map WORD",
7008 "BGP table to RIB route download filter\n"
7009 "Name of the route map\n")
7010 {
7011 int idx_word = 1;
7012 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7013 argv[idx_word]->arg);
7014 }
7015 DEFUN (no_bgp_table_map,
7016 no_bgp_table_map_cmd,
7017 "no table-map WORD",
7018 NO_STR
7019 "BGP table to RIB route download filter\n"
7020 "Name of the route map\n")
7021 {
7022 int idx_word = 2;
7023 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7024 argv[idx_word]->arg);
7025 }
7026
7027 DEFPY(bgp_network,
7028 bgp_network_cmd,
7029 "[no] network \
7030 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7031 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7032 backdoor$backdoor}]",
7033 NO_STR
7034 "Specify a network to announce via BGP\n"
7035 "IPv4 prefix\n"
7036 "Network number\n"
7037 "Network mask\n"
7038 "Network mask\n"
7039 "Route-map to modify the attributes\n"
7040 "Name of the route map\n"
7041 "Label index to associate with the prefix\n"
7042 "Label index value\n"
7043 "Specify a BGP backdoor route\n")
7044 {
7045 char addr_prefix_str[BUFSIZ];
7046
7047 if (address_str) {
7048 int ret;
7049
7050 ret = netmask_str2prefix_str(address_str, netmask_str,
7051 addr_prefix_str,
7052 sizeof(addr_prefix_str));
7053 if (!ret) {
7054 vty_out(vty, "%% Inconsistent address and mask\n");
7055 return CMD_WARNING_CONFIG_FAILED;
7056 }
7057 }
7058
7059 return bgp_static_set(
7060 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7061 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7062 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7063 }
7064
7065 DEFPY(ipv6_bgp_network,
7066 ipv6_bgp_network_cmd,
7067 "[no] network X:X::X:X/M$prefix \
7068 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7069 NO_STR
7070 "Specify a network to announce via BGP\n"
7071 "IPv6 prefix\n"
7072 "Route-map to modify the attributes\n"
7073 "Name of the route map\n"
7074 "Label index to associate with the prefix\n"
7075 "Label index value\n")
7076 {
7077 return bgp_static_set(
7078 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7079 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7080 }
7081
7082 static struct bgp_aggregate *bgp_aggregate_new(void)
7083 {
7084 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7085 }
7086
7087 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7088 {
7089 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7090 route_map_counter_decrement(aggregate->suppress_map);
7091 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7092 route_map_counter_decrement(aggregate->rmap.map);
7093 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7094 }
7095
7096 /**
7097 * Helper function to avoid repeated code: prepare variables for a
7098 * `route_map_apply` call.
7099 *
7100 * \returns `true` on route map match, otherwise `false`.
7101 */
7102 static bool aggr_suppress_map_test(struct bgp *bgp,
7103 struct bgp_aggregate *aggregate,
7104 struct bgp_path_info *pi)
7105 {
7106 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7107 route_map_result_t rmr = RMAP_DENYMATCH;
7108 struct bgp_path_info rmap_path = {};
7109 struct attr attr = {};
7110
7111 /* No route map entries created, just don't match. */
7112 if (aggregate->suppress_map == NULL)
7113 return false;
7114
7115 /* Call route map matching and return result. */
7116 attr.aspath = aspath_empty();
7117 rmap_path.peer = bgp->peer_self;
7118 rmap_path.attr = &attr;
7119
7120 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7121 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7122 bgp->peer_self->rmap_type = 0;
7123
7124 bgp_attr_flush(&attr);
7125 aspath_unintern(&attr.aspath);
7126
7127 return rmr == RMAP_PERMITMATCH;
7128 }
7129
7130 /** Test whether the aggregation has suppressed this path or not. */
7131 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7132 struct bgp_path_info *pi)
7133 {
7134 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7135 return false;
7136
7137 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7138 }
7139
7140 /**
7141 * Suppress this path and keep the reference.
7142 *
7143 * \returns `true` if needs processing otherwise `false`.
7144 */
7145 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7146 struct bgp_path_info *pi)
7147 {
7148 struct bgp_path_info_extra *pie;
7149
7150 /* Path is already suppressed by this aggregation. */
7151 if (aggr_suppress_exists(aggregate, pi))
7152 return false;
7153
7154 pie = bgp_path_info_extra_get(pi);
7155
7156 /* This is the first suppression, allocate memory and list it. */
7157 if (pie->aggr_suppressors == NULL)
7158 pie->aggr_suppressors = list_new();
7159
7160 listnode_add(pie->aggr_suppressors, aggregate);
7161
7162 /* Only mark for processing if suppressed. */
7163 if (listcount(pie->aggr_suppressors) == 1) {
7164 if (BGP_DEBUG(update, UPDATE_OUT))
7165 zlog_debug("aggregate-address suppressing: %pFX",
7166 bgp_dest_get_prefix(pi->net));
7167
7168 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7169 return true;
7170 }
7171
7172 return false;
7173 }
7174
7175 /**
7176 * Unsuppress this path and remove the reference.
7177 *
7178 * \returns `true` if needs processing otherwise `false`.
7179 */
7180 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7181 struct bgp_path_info *pi)
7182 {
7183 /* Path wasn't suppressed. */
7184 if (!aggr_suppress_exists(aggregate, pi))
7185 return false;
7186
7187 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7188
7189 /* Unsuppress and free extra memory if last item. */
7190 if (listcount(pi->extra->aggr_suppressors) == 0) {
7191 if (BGP_DEBUG(update, UPDATE_OUT))
7192 zlog_debug("aggregate-address unsuppressing: %pFX",
7193 bgp_dest_get_prefix(pi->net));
7194
7195 list_delete(&pi->extra->aggr_suppressors);
7196 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7197 return true;
7198 }
7199
7200 return false;
7201 }
7202
7203 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7204 struct aspath *aspath,
7205 struct community *comm,
7206 struct ecommunity *ecomm,
7207 struct lcommunity *lcomm)
7208 {
7209 static struct aspath *ae = NULL;
7210
7211 if (!ae)
7212 ae = aspath_empty();
7213
7214 if (!pi)
7215 return false;
7216
7217 if (origin != pi->attr->origin)
7218 return false;
7219
7220 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7221 return false;
7222
7223 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7224 return false;
7225
7226 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7227 return false;
7228
7229 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7230 return false;
7231
7232 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7233 return false;
7234
7235 return true;
7236 }
7237
7238 static void bgp_aggregate_install(
7239 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7240 uint8_t origin, struct aspath *aspath, struct community *community,
7241 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7242 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7243 {
7244 struct bgp_dest *dest;
7245 struct bgp_table *table;
7246 struct bgp_path_info *pi, *orig, *new;
7247 struct attr *attr;
7248
7249 table = bgp->rib[afi][safi];
7250
7251 dest = bgp_node_get(table, p);
7252
7253 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7254 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7255 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7256 break;
7257
7258 /*
7259 * If we have paths with different MEDs, then don't install
7260 * (or uninstall) the aggregate route.
7261 */
7262 if (aggregate->match_med && aggregate->med_mismatched)
7263 goto uninstall_aggregate_route;
7264
7265 if (aggregate->count > 0) {
7266 /*
7267 * If the aggregate information has not changed
7268 * no need to re-install it again.
7269 */
7270 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7271 ecommunity, lcommunity)) {
7272 bgp_dest_unlock_node(dest);
7273
7274 if (aspath)
7275 aspath_free(aspath);
7276 if (community)
7277 community_free(&community);
7278 if (ecommunity)
7279 ecommunity_free(&ecommunity);
7280 if (lcommunity)
7281 lcommunity_free(&lcommunity);
7282
7283 return;
7284 }
7285
7286 /*
7287 * Mark the old as unusable
7288 */
7289 if (pi)
7290 bgp_path_info_delete(dest, pi);
7291
7292 attr = bgp_attr_aggregate_intern(
7293 bgp, origin, aspath, community, ecommunity, lcommunity,
7294 aggregate, atomic_aggregate, p);
7295
7296 if (!attr) {
7297 bgp_dest_unlock_node(dest);
7298 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7299 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7300 zlog_debug("%s: %pFX null attribute", __func__,
7301 p);
7302 return;
7303 }
7304
7305 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7306 bgp->peer_self, attr, dest);
7307
7308 SET_FLAG(new->flags, BGP_PATH_VALID);
7309
7310 bgp_path_info_add(dest, new);
7311 bgp_process(bgp, dest, afi, safi);
7312 } else {
7313 uninstall_aggregate_route:
7314 for (pi = orig; pi; pi = pi->next)
7315 if (pi->peer == bgp->peer_self
7316 && pi->type == ZEBRA_ROUTE_BGP
7317 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7318 break;
7319
7320 /* Withdraw static BGP route from routing table. */
7321 if (pi) {
7322 bgp_path_info_delete(dest, pi);
7323 bgp_process(bgp, dest, afi, safi);
7324 }
7325 }
7326
7327 bgp_dest_unlock_node(dest);
7328 }
7329
7330 /**
7331 * Check if the current path has different MED than other known paths.
7332 *
7333 * \returns `true` if the MED matched the others else `false`.
7334 */
7335 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7336 struct bgp *bgp, struct bgp_path_info *pi)
7337 {
7338 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7339
7340 /* This is the first route being analyzed. */
7341 if (!aggregate->med_initialized) {
7342 aggregate->med_initialized = true;
7343 aggregate->med_mismatched = false;
7344 aggregate->med_matched_value = cur_med;
7345 } else {
7346 /* Check if routes with different MED showed up. */
7347 if (cur_med != aggregate->med_matched_value)
7348 aggregate->med_mismatched = true;
7349 }
7350
7351 return !aggregate->med_mismatched;
7352 }
7353
7354 /**
7355 * Initializes and tests all routes in the aggregate address path for MED
7356 * values.
7357 *
7358 * \returns `true` if all MEDs are the same otherwise `false`.
7359 */
7360 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7361 struct bgp *bgp, const struct prefix *p,
7362 afi_t afi, safi_t safi)
7363 {
7364 struct bgp_table *table = bgp->rib[afi][safi];
7365 const struct prefix *dest_p;
7366 struct bgp_dest *dest, *top;
7367 struct bgp_path_info *pi;
7368 bool med_matched = true;
7369
7370 aggregate->med_initialized = false;
7371
7372 top = bgp_node_get(table, p);
7373 for (dest = bgp_node_get(table, p); dest;
7374 dest = bgp_route_next_until(dest, top)) {
7375 dest_p = bgp_dest_get_prefix(dest);
7376 if (dest_p->prefixlen <= p->prefixlen)
7377 continue;
7378
7379 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7380 if (BGP_PATH_HOLDDOWN(pi))
7381 continue;
7382 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7383 continue;
7384 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7385 med_matched = false;
7386 break;
7387 }
7388 }
7389 if (!med_matched)
7390 break;
7391 }
7392 bgp_dest_unlock_node(top);
7393
7394 return med_matched;
7395 }
7396
7397 /**
7398 * Toggles the route suppression status for this aggregate address
7399 * configuration.
7400 */
7401 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7402 struct bgp *bgp, const struct prefix *p,
7403 afi_t afi, safi_t safi, bool suppress)
7404 {
7405 struct bgp_table *table = bgp->rib[afi][safi];
7406 const struct prefix *dest_p;
7407 struct bgp_dest *dest, *top;
7408 struct bgp_path_info *pi;
7409 bool toggle_suppression;
7410
7411 /* We've found a different MED we must revert any suppressed routes. */
7412 top = bgp_node_get(table, p);
7413 for (dest = bgp_node_get(table, p); dest;
7414 dest = bgp_route_next_until(dest, top)) {
7415 dest_p = bgp_dest_get_prefix(dest);
7416 if (dest_p->prefixlen <= p->prefixlen)
7417 continue;
7418
7419 toggle_suppression = false;
7420 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7421 if (BGP_PATH_HOLDDOWN(pi))
7422 continue;
7423 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7424 continue;
7425
7426 /* We are toggling suppression back. */
7427 if (suppress) {
7428 /* Suppress route if not suppressed already. */
7429 if (aggr_suppress_path(aggregate, pi))
7430 toggle_suppression = true;
7431 continue;
7432 }
7433
7434 /* Install route if there is no more suppression. */
7435 if (aggr_unsuppress_path(aggregate, pi))
7436 toggle_suppression = true;
7437 }
7438
7439 if (toggle_suppression)
7440 bgp_process(bgp, dest, afi, safi);
7441 }
7442 bgp_dest_unlock_node(top);
7443 }
7444
7445 /**
7446 * Aggregate address MED matching incremental test: this function is called
7447 * when the initial aggregation occurred and we are only testing a single
7448 * new path.
7449 *
7450 * In addition to testing and setting the MED validity it also installs back
7451 * suppressed routes (if summary is configured).
7452 *
7453 * Must not be called in `bgp_aggregate_route`.
7454 */
7455 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7456 struct bgp *bgp, const struct prefix *p,
7457 afi_t afi, safi_t safi,
7458 struct bgp_path_info *pi)
7459 {
7460 /* MED matching disabled. */
7461 if (!aggregate->match_med)
7462 return;
7463
7464 /* Aggregation with different MED, recheck if we have got equal MEDs
7465 * now.
7466 */
7467 if (aggregate->med_mismatched &&
7468 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7469 aggregate->summary_only)
7470 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7471 true);
7472 else
7473 bgp_aggregate_med_match(aggregate, bgp, pi);
7474
7475 /* No mismatches, just quit. */
7476 if (!aggregate->med_mismatched)
7477 return;
7478
7479 /* Route summarization is disabled. */
7480 if (!aggregate->summary_only)
7481 return;
7482
7483 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7484 }
7485
7486 /* Update an aggregate as routes are added/removed from the BGP table */
7487 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7488 safi_t safi, struct bgp_aggregate *aggregate)
7489 {
7490 struct bgp_table *table;
7491 struct bgp_dest *top;
7492 struct bgp_dest *dest;
7493 uint8_t origin;
7494 struct aspath *aspath = NULL;
7495 struct community *community = NULL;
7496 struct ecommunity *ecommunity = NULL;
7497 struct lcommunity *lcommunity = NULL;
7498 struct bgp_path_info *pi;
7499 unsigned long match = 0;
7500 uint8_t atomic_aggregate = 0;
7501
7502 /* If the bgp instance is being deleted or self peer is deleted
7503 * then do not create aggregate route
7504 */
7505 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7506 || (bgp->peer_self == NULL))
7507 return;
7508
7509 /* Initialize and test routes for MED difference. */
7510 if (aggregate->match_med)
7511 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7512
7513 /*
7514 * Reset aggregate count: we might've been called from route map
7515 * update so in that case we must retest all more specific routes.
7516 *
7517 * \see `bgp_route_map_process_update`.
7518 */
7519 aggregate->count = 0;
7520 aggregate->incomplete_origin_count = 0;
7521 aggregate->incomplete_origin_count = 0;
7522 aggregate->egp_origin_count = 0;
7523
7524 /* ORIGIN attribute: If at least one route among routes that are
7525 aggregated has ORIGIN with the value INCOMPLETE, then the
7526 aggregated route must have the ORIGIN attribute with the value
7527 INCOMPLETE. Otherwise, if at least one route among routes that
7528 are aggregated has ORIGIN with the value EGP, then the aggregated
7529 route must have the origin attribute with the value EGP. In all
7530 other case the value of the ORIGIN attribute of the aggregated
7531 route is INTERNAL. */
7532 origin = BGP_ORIGIN_IGP;
7533
7534 table = bgp->rib[afi][safi];
7535
7536 top = bgp_node_get(table, p);
7537 for (dest = bgp_node_get(table, p); dest;
7538 dest = bgp_route_next_until(dest, top)) {
7539 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7540
7541 if (dest_p->prefixlen <= p->prefixlen)
7542 continue;
7543
7544 /* If suppress fib is enabled and route not installed
7545 * in FIB, skip the route
7546 */
7547 if (!bgp_check_advertise(bgp, dest))
7548 continue;
7549
7550 match = 0;
7551
7552 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7553 if (BGP_PATH_HOLDDOWN(pi))
7554 continue;
7555
7556 if (pi->attr->flag
7557 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7558 atomic_aggregate = 1;
7559
7560 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7561 continue;
7562
7563 /*
7564 * summary-only aggregate route suppress
7565 * aggregated route announcements.
7566 *
7567 * MED matching:
7568 * Don't create summaries if MED didn't match
7569 * otherwise neither the specific routes and the
7570 * aggregation will be announced.
7571 */
7572 if (aggregate->summary_only
7573 && AGGREGATE_MED_VALID(aggregate)) {
7574 if (aggr_suppress_path(aggregate, pi))
7575 match++;
7576 }
7577
7578 /*
7579 * Suppress more specific routes that match the route
7580 * map results.
7581 *
7582 * MED matching:
7583 * Don't suppress routes if MED matching is enabled and
7584 * it mismatched otherwise we might end up with no
7585 * routes for this path.
7586 */
7587 if (aggregate->suppress_map_name
7588 && AGGREGATE_MED_VALID(aggregate)
7589 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7590 if (aggr_suppress_path(aggregate, pi))
7591 match++;
7592 }
7593
7594 aggregate->count++;
7595
7596 /*
7597 * If at least one route among routes that are
7598 * aggregated has ORIGIN with the value INCOMPLETE,
7599 * then the aggregated route MUST have the ORIGIN
7600 * attribute with the value INCOMPLETE. Otherwise, if
7601 * at least one route among routes that are aggregated
7602 * has ORIGIN with the value EGP, then the aggregated
7603 * route MUST have the ORIGIN attribute with the value
7604 * EGP.
7605 */
7606 switch (pi->attr->origin) {
7607 case BGP_ORIGIN_INCOMPLETE:
7608 aggregate->incomplete_origin_count++;
7609 break;
7610 case BGP_ORIGIN_EGP:
7611 aggregate->egp_origin_count++;
7612 break;
7613 default:
7614 /*Do nothing.
7615 */
7616 break;
7617 }
7618
7619 if (!aggregate->as_set)
7620 continue;
7621
7622 /*
7623 * as-set aggregate route generate origin, as path,
7624 * and community aggregation.
7625 */
7626 /* Compute aggregate route's as-path.
7627 */
7628 bgp_compute_aggregate_aspath_hash(aggregate,
7629 pi->attr->aspath);
7630
7631 /* Compute aggregate route's community.
7632 */
7633 if (bgp_attr_get_community(pi->attr))
7634 bgp_compute_aggregate_community_hash(
7635 aggregate,
7636 bgp_attr_get_community(pi->attr));
7637
7638 /* Compute aggregate route's extended community.
7639 */
7640 if (bgp_attr_get_ecommunity(pi->attr))
7641 bgp_compute_aggregate_ecommunity_hash(
7642 aggregate,
7643 bgp_attr_get_ecommunity(pi->attr));
7644
7645 /* Compute aggregate route's large community.
7646 */
7647 if (bgp_attr_get_lcommunity(pi->attr))
7648 bgp_compute_aggregate_lcommunity_hash(
7649 aggregate,
7650 bgp_attr_get_lcommunity(pi->attr));
7651 }
7652 if (match)
7653 bgp_process(bgp, dest, afi, safi);
7654 }
7655 if (aggregate->as_set) {
7656 bgp_compute_aggregate_aspath_val(aggregate);
7657 bgp_compute_aggregate_community_val(aggregate);
7658 bgp_compute_aggregate_ecommunity_val(aggregate);
7659 bgp_compute_aggregate_lcommunity_val(aggregate);
7660 }
7661
7662
7663 bgp_dest_unlock_node(top);
7664
7665
7666 if (aggregate->incomplete_origin_count > 0)
7667 origin = BGP_ORIGIN_INCOMPLETE;
7668 else if (aggregate->egp_origin_count > 0)
7669 origin = BGP_ORIGIN_EGP;
7670
7671 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7672 origin = aggregate->origin;
7673
7674 if (aggregate->as_set) {
7675 if (aggregate->aspath)
7676 /* Retrieve aggregate route's as-path.
7677 */
7678 aspath = aspath_dup(aggregate->aspath);
7679
7680 if (aggregate->community)
7681 /* Retrieve aggregate route's community.
7682 */
7683 community = community_dup(aggregate->community);
7684
7685 if (aggregate->ecommunity)
7686 /* Retrieve aggregate route's ecommunity.
7687 */
7688 ecommunity = ecommunity_dup(aggregate->ecommunity);
7689
7690 if (aggregate->lcommunity)
7691 /* Retrieve aggregate route's lcommunity.
7692 */
7693 lcommunity = lcommunity_dup(aggregate->lcommunity);
7694 }
7695
7696 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7697 ecommunity, lcommunity, atomic_aggregate,
7698 aggregate);
7699 }
7700
7701 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7702 safi_t safi, struct bgp_aggregate *aggregate)
7703 {
7704 struct bgp_table *table;
7705 struct bgp_dest *top;
7706 struct bgp_dest *dest;
7707 struct bgp_path_info *pi;
7708 unsigned long match;
7709
7710 table = bgp->rib[afi][safi];
7711
7712 /* If routes exists below this node, generate aggregate routes. */
7713 top = bgp_node_get(table, p);
7714 for (dest = bgp_node_get(table, p); dest;
7715 dest = bgp_route_next_until(dest, top)) {
7716 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7717
7718 if (dest_p->prefixlen <= p->prefixlen)
7719 continue;
7720 match = 0;
7721
7722 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7723 if (BGP_PATH_HOLDDOWN(pi))
7724 continue;
7725
7726 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7727 continue;
7728
7729 /*
7730 * This route is suppressed: attempt to unsuppress it.
7731 *
7732 * `aggr_unsuppress_path` will fail if this particular
7733 * aggregate route was not the suppressor.
7734 */
7735 if (pi->extra && pi->extra->aggr_suppressors &&
7736 listcount(pi->extra->aggr_suppressors)) {
7737 if (aggr_unsuppress_path(aggregate, pi))
7738 match++;
7739 }
7740
7741 aggregate->count--;
7742
7743 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7744 aggregate->incomplete_origin_count--;
7745 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7746 aggregate->egp_origin_count--;
7747
7748 if (aggregate->as_set) {
7749 /* Remove as-path from aggregate.
7750 */
7751 bgp_remove_aspath_from_aggregate_hash(
7752 aggregate,
7753 pi->attr->aspath);
7754
7755 if (bgp_attr_get_community(pi->attr))
7756 /* Remove community from aggregate.
7757 */
7758 bgp_remove_comm_from_aggregate_hash(
7759 aggregate,
7760 bgp_attr_get_community(
7761 pi->attr));
7762
7763 if (bgp_attr_get_ecommunity(pi->attr))
7764 /* Remove ecommunity from aggregate.
7765 */
7766 bgp_remove_ecomm_from_aggregate_hash(
7767 aggregate,
7768 bgp_attr_get_ecommunity(
7769 pi->attr));
7770
7771 if (bgp_attr_get_lcommunity(pi->attr))
7772 /* Remove lcommunity from aggregate.
7773 */
7774 bgp_remove_lcomm_from_aggregate_hash(
7775 aggregate,
7776 bgp_attr_get_lcommunity(
7777 pi->attr));
7778 }
7779 }
7780
7781 /* If this node was suppressed, process the change. */
7782 if (match)
7783 bgp_process(bgp, dest, afi, safi);
7784 }
7785 if (aggregate->as_set) {
7786 aspath_free(aggregate->aspath);
7787 aggregate->aspath = NULL;
7788 if (aggregate->community)
7789 community_free(&aggregate->community);
7790 if (aggregate->ecommunity)
7791 ecommunity_free(&aggregate->ecommunity);
7792 if (aggregate->lcommunity)
7793 lcommunity_free(&aggregate->lcommunity);
7794 }
7795
7796 bgp_dest_unlock_node(top);
7797 }
7798
7799 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7800 const struct prefix *aggr_p,
7801 struct bgp_path_info *pinew, afi_t afi,
7802 safi_t safi,
7803 struct bgp_aggregate *aggregate)
7804 {
7805 uint8_t origin;
7806 struct aspath *aspath = NULL;
7807 uint8_t atomic_aggregate = 0;
7808 struct community *community = NULL;
7809 struct ecommunity *ecommunity = NULL;
7810 struct lcommunity *lcommunity = NULL;
7811
7812 /* If the bgp instance is being deleted or self peer is deleted
7813 * then do not create aggregate route
7814 */
7815 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7816 || (bgp->peer_self == NULL))
7817 return;
7818
7819 /* ORIGIN attribute: If at least one route among routes that are
7820 * aggregated has ORIGIN with the value INCOMPLETE, then the
7821 * aggregated route must have the ORIGIN attribute with the value
7822 * INCOMPLETE. Otherwise, if at least one route among routes that
7823 * are aggregated has ORIGIN with the value EGP, then the aggregated
7824 * route must have the origin attribute with the value EGP. In all
7825 * other case the value of the ORIGIN attribute of the aggregated
7826 * route is INTERNAL.
7827 */
7828 origin = BGP_ORIGIN_IGP;
7829
7830 aggregate->count++;
7831
7832 /*
7833 * This must be called before `summary` check to avoid
7834 * "suppressing" twice.
7835 */
7836 if (aggregate->match_med)
7837 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7838 pinew);
7839
7840 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7841 aggr_suppress_path(aggregate, pinew);
7842
7843 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7844 && aggr_suppress_map_test(bgp, aggregate, pinew))
7845 aggr_suppress_path(aggregate, pinew);
7846
7847 switch (pinew->attr->origin) {
7848 case BGP_ORIGIN_INCOMPLETE:
7849 aggregate->incomplete_origin_count++;
7850 break;
7851 case BGP_ORIGIN_EGP:
7852 aggregate->egp_origin_count++;
7853 break;
7854 default:
7855 /* Do nothing.
7856 */
7857 break;
7858 }
7859
7860 if (aggregate->incomplete_origin_count > 0)
7861 origin = BGP_ORIGIN_INCOMPLETE;
7862 else if (aggregate->egp_origin_count > 0)
7863 origin = BGP_ORIGIN_EGP;
7864
7865 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7866 origin = aggregate->origin;
7867
7868 if (aggregate->as_set) {
7869 /* Compute aggregate route's as-path.
7870 */
7871 bgp_compute_aggregate_aspath(aggregate,
7872 pinew->attr->aspath);
7873
7874 /* Compute aggregate route's community.
7875 */
7876 if (bgp_attr_get_community(pinew->attr))
7877 bgp_compute_aggregate_community(
7878 aggregate, bgp_attr_get_community(pinew->attr));
7879
7880 /* Compute aggregate route's extended community.
7881 */
7882 if (bgp_attr_get_ecommunity(pinew->attr))
7883 bgp_compute_aggregate_ecommunity(
7884 aggregate,
7885 bgp_attr_get_ecommunity(pinew->attr));
7886
7887 /* Compute aggregate route's large community.
7888 */
7889 if (bgp_attr_get_lcommunity(pinew->attr))
7890 bgp_compute_aggregate_lcommunity(
7891 aggregate,
7892 bgp_attr_get_lcommunity(pinew->attr));
7893
7894 /* Retrieve aggregate route's as-path.
7895 */
7896 if (aggregate->aspath)
7897 aspath = aspath_dup(aggregate->aspath);
7898
7899 /* Retrieve aggregate route's community.
7900 */
7901 if (aggregate->community)
7902 community = community_dup(aggregate->community);
7903
7904 /* Retrieve aggregate route's ecommunity.
7905 */
7906 if (aggregate->ecommunity)
7907 ecommunity = ecommunity_dup(aggregate->ecommunity);
7908
7909 /* Retrieve aggregate route's lcommunity.
7910 */
7911 if (aggregate->lcommunity)
7912 lcommunity = lcommunity_dup(aggregate->lcommunity);
7913 }
7914
7915 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7916 aspath, community, ecommunity,
7917 lcommunity, atomic_aggregate, aggregate);
7918 }
7919
7920 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7921 safi_t safi,
7922 struct bgp_path_info *pi,
7923 struct bgp_aggregate *aggregate,
7924 const struct prefix *aggr_p)
7925 {
7926 uint8_t origin;
7927 struct aspath *aspath = NULL;
7928 uint8_t atomic_aggregate = 0;
7929 struct community *community = NULL;
7930 struct ecommunity *ecommunity = NULL;
7931 struct lcommunity *lcommunity = NULL;
7932 unsigned long match = 0;
7933
7934 /* If the bgp instance is being deleted or self peer is deleted
7935 * then do not create aggregate route
7936 */
7937 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7938 || (bgp->peer_self == NULL))
7939 return;
7940
7941 if (BGP_PATH_HOLDDOWN(pi))
7942 return;
7943
7944 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7945 return;
7946
7947 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7948 if (aggr_unsuppress_path(aggregate, pi))
7949 match++;
7950
7951 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7952 && aggr_suppress_map_test(bgp, aggregate, pi))
7953 if (aggr_unsuppress_path(aggregate, pi))
7954 match++;
7955
7956 /*
7957 * This must be called after `summary`, `suppress-map` check to avoid
7958 * "unsuppressing" twice.
7959 */
7960 if (aggregate->match_med)
7961 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
7962
7963 if (aggregate->count > 0)
7964 aggregate->count--;
7965
7966 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7967 aggregate->incomplete_origin_count--;
7968 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7969 aggregate->egp_origin_count--;
7970
7971 if (aggregate->as_set) {
7972 /* Remove as-path from aggregate.
7973 */
7974 bgp_remove_aspath_from_aggregate(aggregate,
7975 pi->attr->aspath);
7976
7977 if (bgp_attr_get_community(pi->attr))
7978 /* Remove community from aggregate.
7979 */
7980 bgp_remove_community_from_aggregate(
7981 aggregate, bgp_attr_get_community(pi->attr));
7982
7983 if (bgp_attr_get_ecommunity(pi->attr))
7984 /* Remove ecommunity from aggregate.
7985 */
7986 bgp_remove_ecommunity_from_aggregate(
7987 aggregate, bgp_attr_get_ecommunity(pi->attr));
7988
7989 if (bgp_attr_get_lcommunity(pi->attr))
7990 /* Remove lcommunity from aggregate.
7991 */
7992 bgp_remove_lcommunity_from_aggregate(
7993 aggregate, bgp_attr_get_lcommunity(pi->attr));
7994 }
7995
7996 /* If this node was suppressed, process the change. */
7997 if (match)
7998 bgp_process(bgp, pi->net, afi, safi);
7999
8000 origin = BGP_ORIGIN_IGP;
8001 if (aggregate->incomplete_origin_count > 0)
8002 origin = BGP_ORIGIN_INCOMPLETE;
8003 else if (aggregate->egp_origin_count > 0)
8004 origin = BGP_ORIGIN_EGP;
8005
8006 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8007 origin = aggregate->origin;
8008
8009 if (aggregate->as_set) {
8010 /* Retrieve aggregate route's as-path.
8011 */
8012 if (aggregate->aspath)
8013 aspath = aspath_dup(aggregate->aspath);
8014
8015 /* Retrieve aggregate route's community.
8016 */
8017 if (aggregate->community)
8018 community = community_dup(aggregate->community);
8019
8020 /* Retrieve aggregate route's ecommunity.
8021 */
8022 if (aggregate->ecommunity)
8023 ecommunity = ecommunity_dup(aggregate->ecommunity);
8024
8025 /* Retrieve aggregate route's lcommunity.
8026 */
8027 if (aggregate->lcommunity)
8028 lcommunity = lcommunity_dup(aggregate->lcommunity);
8029 }
8030
8031 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8032 aspath, community, ecommunity,
8033 lcommunity, atomic_aggregate, aggregate);
8034 }
8035
8036 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8037 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8038 {
8039 struct bgp_dest *child;
8040 struct bgp_dest *dest;
8041 struct bgp_aggregate *aggregate;
8042 struct bgp_table *table;
8043
8044 table = bgp->aggregate[afi][safi];
8045
8046 /* No aggregates configured. */
8047 if (bgp_table_top_nolock(table) == NULL)
8048 return;
8049
8050 if (p->prefixlen == 0)
8051 return;
8052
8053 if (BGP_PATH_HOLDDOWN(pi))
8054 return;
8055
8056 /* If suppress fib is enabled and route not installed
8057 * in FIB, do not update the aggregate route
8058 */
8059 if (!bgp_check_advertise(bgp, pi->net))
8060 return;
8061
8062 child = bgp_node_get(table, p);
8063
8064 /* Aggregate address configuration check. */
8065 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8066 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8067
8068 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8069 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8070 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8071 aggregate);
8072 }
8073 }
8074 bgp_dest_unlock_node(child);
8075 }
8076
8077 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8078 struct bgp_path_info *del, afi_t afi, safi_t safi)
8079 {
8080 struct bgp_dest *child;
8081 struct bgp_dest *dest;
8082 struct bgp_aggregate *aggregate;
8083 struct bgp_table *table;
8084
8085 table = bgp->aggregate[afi][safi];
8086
8087 /* No aggregates configured. */
8088 if (bgp_table_top_nolock(table) == NULL)
8089 return;
8090
8091 if (p->prefixlen == 0)
8092 return;
8093
8094 child = bgp_node_get(table, p);
8095
8096 /* Aggregate address configuration check. */
8097 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8098 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8099
8100 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8101 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8102 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8103 aggregate, dest_p);
8104 }
8105 }
8106 bgp_dest_unlock_node(child);
8107 }
8108
8109 /* Aggregate route attribute. */
8110 #define AGGREGATE_SUMMARY_ONLY 1
8111 #define AGGREGATE_AS_SET 1
8112 #define AGGREGATE_AS_UNSET 0
8113
8114 static const char *bgp_origin2str(uint8_t origin)
8115 {
8116 switch (origin) {
8117 case BGP_ORIGIN_IGP:
8118 return "igp";
8119 case BGP_ORIGIN_EGP:
8120 return "egp";
8121 case BGP_ORIGIN_INCOMPLETE:
8122 return "incomplete";
8123 }
8124 return "n/a";
8125 }
8126
8127 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8128 {
8129 switch (v_state) {
8130 case RPKI_NOT_BEING_USED:
8131 return "not used";
8132 case RPKI_VALID:
8133 return "valid";
8134 case RPKI_NOTFOUND:
8135 return "not found";
8136 case RPKI_INVALID:
8137 return "invalid";
8138 }
8139
8140 assert(!"We should never get here this is a dev escape");
8141 return "ERROR";
8142 }
8143
8144 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8145 afi_t afi, safi_t safi)
8146 {
8147 VTY_DECLVAR_CONTEXT(bgp, bgp);
8148 int ret;
8149 struct prefix p;
8150 struct bgp_dest *dest;
8151 struct bgp_aggregate *aggregate;
8152
8153 /* Convert string to prefix structure. */
8154 ret = str2prefix(prefix_str, &p);
8155 if (!ret) {
8156 vty_out(vty, "Malformed prefix\n");
8157 return CMD_WARNING_CONFIG_FAILED;
8158 }
8159 apply_mask(&p);
8160
8161 /* Old configuration check. */
8162 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8163 if (!dest) {
8164 vty_out(vty,
8165 "%% There is no aggregate-address configuration.\n");
8166 return CMD_WARNING_CONFIG_FAILED;
8167 }
8168
8169 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8170 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8171 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8172 NULL, NULL, 0, aggregate);
8173
8174 /* Unlock aggregate address configuration. */
8175 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8176
8177 if (aggregate->community)
8178 community_free(&aggregate->community);
8179
8180 if (aggregate->community_hash) {
8181 /* Delete all communities in the hash.
8182 */
8183 hash_clean(aggregate->community_hash,
8184 bgp_aggr_community_remove);
8185 /* Free up the community_hash.
8186 */
8187 hash_free(aggregate->community_hash);
8188 }
8189
8190 if (aggregate->ecommunity)
8191 ecommunity_free(&aggregate->ecommunity);
8192
8193 if (aggregate->ecommunity_hash) {
8194 /* Delete all ecommunities in the hash.
8195 */
8196 hash_clean(aggregate->ecommunity_hash,
8197 bgp_aggr_ecommunity_remove);
8198 /* Free up the ecommunity_hash.
8199 */
8200 hash_free(aggregate->ecommunity_hash);
8201 }
8202
8203 if (aggregate->lcommunity)
8204 lcommunity_free(&aggregate->lcommunity);
8205
8206 if (aggregate->lcommunity_hash) {
8207 /* Delete all lcommunities in the hash.
8208 */
8209 hash_clean(aggregate->lcommunity_hash,
8210 bgp_aggr_lcommunity_remove);
8211 /* Free up the lcommunity_hash.
8212 */
8213 hash_free(aggregate->lcommunity_hash);
8214 }
8215
8216 if (aggregate->aspath)
8217 aspath_free(aggregate->aspath);
8218
8219 if (aggregate->aspath_hash) {
8220 /* Delete all as-paths in the hash.
8221 */
8222 hash_clean(aggregate->aspath_hash,
8223 bgp_aggr_aspath_remove);
8224 /* Free up the aspath_hash.
8225 */
8226 hash_free(aggregate->aspath_hash);
8227 }
8228
8229 bgp_aggregate_free(aggregate);
8230 bgp_dest_unlock_node(dest);
8231 bgp_dest_unlock_node(dest);
8232
8233 return CMD_SUCCESS;
8234 }
8235
8236 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8237 safi_t safi, const char *rmap,
8238 uint8_t summary_only, uint8_t as_set,
8239 uint8_t origin, bool match_med,
8240 const char *suppress_map)
8241 {
8242 VTY_DECLVAR_CONTEXT(bgp, bgp);
8243 int ret;
8244 struct prefix p;
8245 struct bgp_dest *dest;
8246 struct bgp_aggregate *aggregate;
8247 uint8_t as_set_new = as_set;
8248
8249 if (suppress_map && summary_only) {
8250 vty_out(vty,
8251 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8252 return CMD_WARNING_CONFIG_FAILED;
8253 }
8254
8255 /* Convert string to prefix structure. */
8256 ret = str2prefix(prefix_str, &p);
8257 if (!ret) {
8258 vty_out(vty, "Malformed prefix\n");
8259 return CMD_WARNING_CONFIG_FAILED;
8260 }
8261 apply_mask(&p);
8262
8263 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8264 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8265 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8266 prefix_str);
8267 return CMD_WARNING_CONFIG_FAILED;
8268 }
8269
8270 /* Old configuration check. */
8271 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8272 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8273
8274 if (aggregate) {
8275 vty_out(vty, "There is already same aggregate network.\n");
8276 /* try to remove the old entry */
8277 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8278 if (ret) {
8279 vty_out(vty, "Error deleting aggregate.\n");
8280 bgp_dest_unlock_node(dest);
8281 return CMD_WARNING_CONFIG_FAILED;
8282 }
8283 }
8284
8285 /* Make aggregate address structure. */
8286 aggregate = bgp_aggregate_new();
8287 aggregate->summary_only = summary_only;
8288 aggregate->match_med = match_med;
8289
8290 /* Network operators MUST NOT locally generate any new
8291 * announcements containing AS_SET or AS_CONFED_SET. If they have
8292 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8293 * SHOULD withdraw those routes and re-announce routes for the
8294 * aggregate or component prefixes (i.e., the more-specific routes
8295 * subsumed by the previously aggregated route) without AS_SET
8296 * or AS_CONFED_SET in the updates.
8297 */
8298 if (bgp->reject_as_sets) {
8299 if (as_set == AGGREGATE_AS_SET) {
8300 as_set_new = AGGREGATE_AS_UNSET;
8301 zlog_warn(
8302 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8303 __func__);
8304 vty_out(vty,
8305 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8306 }
8307 }
8308
8309 aggregate->as_set = as_set_new;
8310 aggregate->safi = safi;
8311 /* Override ORIGIN attribute if defined.
8312 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8313 * to IGP which is not what rfc4271 says.
8314 * This enables the same behavior, optionally.
8315 */
8316 aggregate->origin = origin;
8317
8318 if (rmap) {
8319 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8320 route_map_counter_decrement(aggregate->rmap.map);
8321 aggregate->rmap.name =
8322 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8323 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8324 route_map_counter_increment(aggregate->rmap.map);
8325 }
8326
8327 if (suppress_map) {
8328 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8329 route_map_counter_decrement(aggregate->suppress_map);
8330
8331 aggregate->suppress_map_name =
8332 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8333 aggregate->suppress_map =
8334 route_map_lookup_by_name(aggregate->suppress_map_name);
8335 route_map_counter_increment(aggregate->suppress_map);
8336 }
8337
8338 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8339
8340 /* Aggregate address insert into BGP routing table. */
8341 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8342
8343 return CMD_SUCCESS;
8344 }
8345
8346 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8347 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8348 "as-set$as_set_s"
8349 "|summary-only$summary_only"
8350 "|route-map RMAP_NAME$rmap_name"
8351 "|origin <egp|igp|incomplete>$origin_s"
8352 "|matching-MED-only$match_med"
8353 "|suppress-map RMAP_NAME$suppress_map"
8354 "}]",
8355 NO_STR
8356 "Configure BGP aggregate entries\n"
8357 "Aggregate prefix\n"
8358 "Aggregate address\n"
8359 "Aggregate mask\n"
8360 "Generate AS set path information\n"
8361 "Filter more specific routes from updates\n"
8362 "Apply route map to aggregate network\n"
8363 "Route map name\n"
8364 "BGP origin code\n"
8365 "Remote EGP\n"
8366 "Local IGP\n"
8367 "Unknown heritage\n"
8368 "Only aggregate routes with matching MED\n"
8369 "Suppress the selected more specific routes\n"
8370 "Route map with the route selectors\n")
8371 {
8372 const char *prefix_s = NULL;
8373 safi_t safi = bgp_node_safi(vty);
8374 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8375 int as_set = AGGREGATE_AS_UNSET;
8376 char prefix_buf[PREFIX2STR_BUFFER];
8377
8378 if (addr_str) {
8379 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8380 sizeof(prefix_buf))
8381 == 0) {
8382 vty_out(vty, "%% Inconsistent address and mask\n");
8383 return CMD_WARNING_CONFIG_FAILED;
8384 }
8385 prefix_s = prefix_buf;
8386 } else
8387 prefix_s = prefix_str;
8388
8389 if (origin_s) {
8390 if (strcmp(origin_s, "egp") == 0)
8391 origin = BGP_ORIGIN_EGP;
8392 else if (strcmp(origin_s, "igp") == 0)
8393 origin = BGP_ORIGIN_IGP;
8394 else if (strcmp(origin_s, "incomplete") == 0)
8395 origin = BGP_ORIGIN_INCOMPLETE;
8396 }
8397
8398 if (as_set_s)
8399 as_set = AGGREGATE_AS_SET;
8400
8401 /* Handle configuration removal, otherwise installation. */
8402 if (no)
8403 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8404
8405 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8406 summary_only != NULL, as_set, origin,
8407 match_med != NULL, suppress_map);
8408 }
8409
8410 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8411 "[no] aggregate-address X:X::X:X/M$prefix [{"
8412 "as-set$as_set_s"
8413 "|summary-only$summary_only"
8414 "|route-map RMAP_NAME$rmap_name"
8415 "|origin <egp|igp|incomplete>$origin_s"
8416 "|matching-MED-only$match_med"
8417 "|suppress-map RMAP_NAME$suppress_map"
8418 "}]",
8419 NO_STR
8420 "Configure BGP aggregate entries\n"
8421 "Aggregate prefix\n"
8422 "Generate AS set path information\n"
8423 "Filter more specific routes from updates\n"
8424 "Apply route map to aggregate network\n"
8425 "Route map name\n"
8426 "BGP origin code\n"
8427 "Remote EGP\n"
8428 "Local IGP\n"
8429 "Unknown heritage\n"
8430 "Only aggregate routes with matching MED\n"
8431 "Suppress the selected more specific routes\n"
8432 "Route map with the route selectors\n")
8433 {
8434 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8435 int as_set = AGGREGATE_AS_UNSET;
8436
8437 if (origin_s) {
8438 if (strcmp(origin_s, "egp") == 0)
8439 origin = BGP_ORIGIN_EGP;
8440 else if (strcmp(origin_s, "igp") == 0)
8441 origin = BGP_ORIGIN_IGP;
8442 else if (strcmp(origin_s, "incomplete") == 0)
8443 origin = BGP_ORIGIN_INCOMPLETE;
8444 }
8445
8446 if (as_set_s)
8447 as_set = AGGREGATE_AS_SET;
8448
8449 /* Handle configuration removal, otherwise installation. */
8450 if (no)
8451 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8452 SAFI_UNICAST);
8453
8454 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8455 rmap_name, summary_only != NULL, as_set,
8456 origin, match_med != NULL, suppress_map);
8457 }
8458
8459 /* Redistribute route treatment. */
8460 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8461 const union g_addr *nexthop, ifindex_t ifindex,
8462 enum nexthop_types_t nhtype, uint8_t distance,
8463 enum blackhole_type bhtype, uint32_t metric,
8464 uint8_t type, unsigned short instance,
8465 route_tag_t tag)
8466 {
8467 struct bgp_path_info *new;
8468 struct bgp_path_info *bpi;
8469 struct bgp_path_info rmap_path;
8470 struct bgp_dest *bn;
8471 struct attr attr;
8472 struct attr *new_attr;
8473 afi_t afi;
8474 route_map_result_t ret;
8475 struct bgp_redist *red;
8476
8477 /* Make default attribute. */
8478 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8479 /*
8480 * This must not be NULL to satisfy Coverity SA
8481 */
8482 assert(attr.aspath);
8483
8484 switch (nhtype) {
8485 case NEXTHOP_TYPE_IFINDEX:
8486 switch (p->family) {
8487 case AF_INET:
8488 attr.nexthop.s_addr = INADDR_ANY;
8489 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8490 break;
8491 case AF_INET6:
8492 memset(&attr.mp_nexthop_global, 0,
8493 sizeof(attr.mp_nexthop_global));
8494 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8495 break;
8496 }
8497 break;
8498 case NEXTHOP_TYPE_IPV4:
8499 case NEXTHOP_TYPE_IPV4_IFINDEX:
8500 attr.nexthop = nexthop->ipv4;
8501 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8502 break;
8503 case NEXTHOP_TYPE_IPV6:
8504 case NEXTHOP_TYPE_IPV6_IFINDEX:
8505 attr.mp_nexthop_global = nexthop->ipv6;
8506 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8507 break;
8508 case NEXTHOP_TYPE_BLACKHOLE:
8509 switch (p->family) {
8510 case AF_INET:
8511 attr.nexthop.s_addr = INADDR_ANY;
8512 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8513 break;
8514 case AF_INET6:
8515 memset(&attr.mp_nexthop_global, 0,
8516 sizeof(attr.mp_nexthop_global));
8517 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8518 break;
8519 }
8520 attr.bh_type = bhtype;
8521 break;
8522 }
8523 attr.nh_type = nhtype;
8524 attr.nh_ifindex = ifindex;
8525
8526 attr.med = metric;
8527 attr.distance = distance;
8528 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8529 attr.tag = tag;
8530
8531 afi = family2afi(p->family);
8532
8533 red = bgp_redist_lookup(bgp, afi, type, instance);
8534 if (red) {
8535 struct attr attr_new;
8536
8537 /* Copy attribute for modification. */
8538 attr_new = attr;
8539
8540 if (red->redist_metric_flag)
8541 attr_new.med = red->redist_metric;
8542
8543 /* Apply route-map. */
8544 if (red->rmap.name) {
8545 memset(&rmap_path, 0, sizeof(rmap_path));
8546 rmap_path.peer = bgp->peer_self;
8547 rmap_path.attr = &attr_new;
8548
8549 SET_FLAG(bgp->peer_self->rmap_type,
8550 PEER_RMAP_TYPE_REDISTRIBUTE);
8551
8552 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8553
8554 bgp->peer_self->rmap_type = 0;
8555
8556 if (ret == RMAP_DENYMATCH) {
8557 /* Free uninterned attribute. */
8558 bgp_attr_flush(&attr_new);
8559
8560 /* Unintern original. */
8561 aspath_unintern(&attr.aspath);
8562 bgp_redistribute_delete(bgp, p, type, instance);
8563 return;
8564 }
8565 }
8566
8567 if (bgp_in_graceful_shutdown(bgp))
8568 bgp_attr_add_gshut_community(&attr_new);
8569
8570 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8571 SAFI_UNICAST, p, NULL);
8572
8573 new_attr = bgp_attr_intern(&attr_new);
8574
8575 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8576 if (bpi->peer == bgp->peer_self
8577 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8578 break;
8579
8580 if (bpi) {
8581 /* Ensure the (source route) type is updated. */
8582 bpi->type = type;
8583 if (attrhash_cmp(bpi->attr, new_attr)
8584 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8585 bgp_attr_unintern(&new_attr);
8586 aspath_unintern(&attr.aspath);
8587 bgp_dest_unlock_node(bn);
8588 return;
8589 } else {
8590 /* The attribute is changed. */
8591 bgp_path_info_set_flag(bn, bpi,
8592 BGP_PATH_ATTR_CHANGED);
8593
8594 /* Rewrite BGP route information. */
8595 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8596 bgp_path_info_restore(bn, bpi);
8597 else
8598 bgp_aggregate_decrement(
8599 bgp, p, bpi, afi, SAFI_UNICAST);
8600 bgp_attr_unintern(&bpi->attr);
8601 bpi->attr = new_attr;
8602 bpi->uptime = monotime(NULL);
8603
8604 /* Process change. */
8605 bgp_aggregate_increment(bgp, p, bpi, afi,
8606 SAFI_UNICAST);
8607 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8608 bgp_dest_unlock_node(bn);
8609 aspath_unintern(&attr.aspath);
8610
8611 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8612 || (bgp->inst_type
8613 == BGP_INSTANCE_TYPE_DEFAULT)) {
8614
8615 vpn_leak_from_vrf_update(
8616 bgp_get_default(), bgp, bpi);
8617 }
8618 return;
8619 }
8620 }
8621
8622 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8623 bgp->peer_self, new_attr, bn);
8624 SET_FLAG(new->flags, BGP_PATH_VALID);
8625
8626 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8627 bgp_path_info_add(bn, new);
8628 bgp_dest_unlock_node(bn);
8629 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8630 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8631
8632 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8633 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8634
8635 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8636 }
8637 }
8638
8639 /* Unintern original. */
8640 aspath_unintern(&attr.aspath);
8641 }
8642
8643 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8644 unsigned short instance)
8645 {
8646 afi_t afi;
8647 struct bgp_dest *dest;
8648 struct bgp_path_info *pi;
8649 struct bgp_redist *red;
8650
8651 afi = family2afi(p->family);
8652
8653 red = bgp_redist_lookup(bgp, afi, type, instance);
8654 if (red) {
8655 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8656 SAFI_UNICAST, p, NULL);
8657
8658 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8659 if (pi->peer == bgp->peer_self && pi->type == type)
8660 break;
8661
8662 if (pi) {
8663 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8664 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8665
8666 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8667 bgp, pi);
8668 }
8669 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8670 bgp_path_info_delete(dest, pi);
8671 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8672 }
8673 bgp_dest_unlock_node(dest);
8674 }
8675 }
8676
8677 /* Withdraw specified route type's route. */
8678 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8679 unsigned short instance)
8680 {
8681 struct bgp_dest *dest;
8682 struct bgp_path_info *pi;
8683 struct bgp_table *table;
8684
8685 table = bgp->rib[afi][SAFI_UNICAST];
8686
8687 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8688 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8689 if (pi->peer == bgp->peer_self && pi->type == type
8690 && pi->instance == instance)
8691 break;
8692
8693 if (pi) {
8694 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8695 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8696
8697 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8698 bgp, pi);
8699 }
8700 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8701 pi, afi, SAFI_UNICAST);
8702 bgp_path_info_delete(dest, pi);
8703 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8704 }
8705 }
8706 }
8707
8708 /* Static function to display route. */
8709 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8710 struct vty *vty, json_object *json, bool wide)
8711 {
8712 int len = 0;
8713 char buf[BUFSIZ];
8714
8715 if (p->family == AF_INET) {
8716 if (!json) {
8717 len = vty_out(vty, "%pFX", p);
8718 } else {
8719 json_object_string_add(json, "prefix",
8720 inet_ntop(p->family,
8721 &p->u.prefix, buf,
8722 BUFSIZ));
8723 json_object_int_add(json, "prefixLen", p->prefixlen);
8724 json_object_string_addf(json, "network", "%pFX", p);
8725 json_object_int_add(json, "version", dest->version);
8726 }
8727 } else if (p->family == AF_ETHERNET) {
8728 len = vty_out(vty, "%pFX", p);
8729 } else if (p->family == AF_EVPN) {
8730 if (!json)
8731 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8732 else
8733 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8734 } else if (p->family == AF_FLOWSPEC) {
8735 route_vty_out_flowspec(vty, p, NULL,
8736 json ?
8737 NLRI_STRING_FORMAT_JSON_SIMPLE :
8738 NLRI_STRING_FORMAT_MIN, json);
8739 } else {
8740 if (!json)
8741 len = vty_out(vty, "%pFX", p);
8742 else {
8743 json_object_string_add(json, "prefix",
8744 inet_ntop(p->family,
8745 &p->u.prefix, buf,
8746 BUFSIZ));
8747 json_object_int_add(json, "prefixLen", p->prefixlen);
8748 json_object_string_addf(json, "network", "%pFX", p);
8749 json_object_int_add(json, "version", dest->version);
8750 }
8751 }
8752
8753 if (!json) {
8754 len = wide ? (45 - len) : (17 - len);
8755 if (len < 1)
8756 vty_out(vty, "\n%*s", 20, " ");
8757 else
8758 vty_out(vty, "%*s", len, " ");
8759 }
8760 }
8761
8762 enum bgp_display_type {
8763 normal_list,
8764 };
8765
8766 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8767 {
8768 switch (reason) {
8769 case bgp_path_selection_none:
8770 return "Nothing to Select";
8771 case bgp_path_selection_first:
8772 return "First path received";
8773 case bgp_path_selection_evpn_sticky_mac:
8774 return "EVPN Sticky Mac";
8775 case bgp_path_selection_evpn_seq:
8776 return "EVPN sequence number";
8777 case bgp_path_selection_evpn_lower_ip:
8778 return "EVPN lower IP";
8779 case bgp_path_selection_evpn_local_path:
8780 return "EVPN local ES path";
8781 case bgp_path_selection_evpn_non_proxy:
8782 return "EVPN non proxy";
8783 case bgp_path_selection_weight:
8784 return "Weight";
8785 case bgp_path_selection_local_pref:
8786 return "Local Pref";
8787 case bgp_path_selection_local_route:
8788 return "Local Route";
8789 case bgp_path_selection_confed_as_path:
8790 return "Confederation based AS Path";
8791 case bgp_path_selection_as_path:
8792 return "AS Path";
8793 case bgp_path_selection_origin:
8794 return "Origin";
8795 case bgp_path_selection_med:
8796 return "MED";
8797 case bgp_path_selection_peer:
8798 return "Peer Type";
8799 case bgp_path_selection_confed:
8800 return "Confed Peer Type";
8801 case bgp_path_selection_igp_metric:
8802 return "IGP Metric";
8803 case bgp_path_selection_older:
8804 return "Older Path";
8805 case bgp_path_selection_router_id:
8806 return "Router ID";
8807 case bgp_path_selection_cluster_length:
8808 return "Cluster length";
8809 case bgp_path_selection_stale:
8810 return "Path Staleness";
8811 case bgp_path_selection_local_configured:
8812 return "Locally configured route";
8813 case bgp_path_selection_neighbor_ip:
8814 return "Neighbor IP";
8815 case bgp_path_selection_default:
8816 return "Nothing left to compare";
8817 }
8818 return "Invalid (internal error)";
8819 }
8820
8821 /* Print the short form route status for a bgp_path_info */
8822 static void route_vty_short_status_out(struct vty *vty,
8823 struct bgp_path_info *path,
8824 const struct prefix *p,
8825 json_object *json_path)
8826 {
8827 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8828
8829 if (json_path) {
8830
8831 /* Route status display. */
8832 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8833 json_object_boolean_true_add(json_path, "removed");
8834
8835 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8836 json_object_boolean_true_add(json_path, "stale");
8837
8838 if (path->extra && bgp_path_suppressed(path))
8839 json_object_boolean_true_add(json_path, "suppressed");
8840
8841 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8842 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8843 json_object_boolean_true_add(json_path, "valid");
8844
8845 /* Selected */
8846 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8847 json_object_boolean_true_add(json_path, "history");
8848
8849 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8850 json_object_boolean_true_add(json_path, "damped");
8851
8852 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8853 json_object_boolean_true_add(json_path, "bestpath");
8854 json_object_string_add(json_path, "selectionReason",
8855 bgp_path_selection_reason2str(
8856 path->net->reason));
8857 }
8858
8859 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8860 json_object_boolean_true_add(json_path, "multipath");
8861
8862 /* Internal route. */
8863 if ((path->peer->as)
8864 && (path->peer->as == path->peer->local_as))
8865 json_object_string_add(json_path, "pathFrom",
8866 "internal");
8867 else
8868 json_object_string_add(json_path, "pathFrom",
8869 "external");
8870
8871 return;
8872 }
8873
8874 /* RPKI validation state */
8875 rpki_state =
8876 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
8877
8878 if (rpki_state == RPKI_VALID)
8879 vty_out(vty, "V");
8880 else if (rpki_state == RPKI_INVALID)
8881 vty_out(vty, "I");
8882 else if (rpki_state == RPKI_NOTFOUND)
8883 vty_out(vty, "N");
8884
8885 /* Route status display. */
8886 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8887 vty_out(vty, "R");
8888 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8889 vty_out(vty, "S");
8890 else if (bgp_path_suppressed(path))
8891 vty_out(vty, "s");
8892 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8893 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8894 vty_out(vty, "*");
8895 else
8896 vty_out(vty, " ");
8897
8898 /* Selected */
8899 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8900 vty_out(vty, "h");
8901 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8902 vty_out(vty, "d");
8903 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8904 vty_out(vty, ">");
8905 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8906 vty_out(vty, "=");
8907 else
8908 vty_out(vty, " ");
8909
8910 /* Internal route. */
8911 if (path->peer && (path->peer->as)
8912 && (path->peer->as == path->peer->local_as))
8913 vty_out(vty, "i");
8914 else
8915 vty_out(vty, " ");
8916 }
8917
8918 static char *bgp_nexthop_hostname(struct peer *peer,
8919 struct bgp_nexthop_cache *bnc)
8920 {
8921 if (peer->hostname
8922 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8923 return peer->hostname;
8924 return NULL;
8925 }
8926
8927 /* called from terminal list command */
8928 void route_vty_out(struct vty *vty, const struct prefix *p,
8929 struct bgp_path_info *path, int display, safi_t safi,
8930 json_object *json_paths, bool wide)
8931 {
8932 int len;
8933 struct attr *attr = path->attr;
8934 json_object *json_path = NULL;
8935 json_object *json_nexthops = NULL;
8936 json_object *json_nexthop_global = NULL;
8937 json_object *json_nexthop_ll = NULL;
8938 json_object *json_ext_community = NULL;
8939 char vrf_id_str[VRF_NAMSIZ] = {0};
8940 bool nexthop_self =
8941 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8942 bool nexthop_othervrf = false;
8943 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8944 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8945 char *nexthop_hostname =
8946 bgp_nexthop_hostname(path->peer, path->nexthop);
8947 char esi_buf[ESI_STR_LEN];
8948
8949 if (json_paths)
8950 json_path = json_object_new_object();
8951
8952 /* short status lead text */
8953 route_vty_short_status_out(vty, path, p, json_path);
8954
8955 if (!json_paths) {
8956 /* print prefix and mask */
8957 if (!display)
8958 route_vty_out_route(path->net, p, vty, json_path, wide);
8959 else
8960 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8961 } else {
8962 route_vty_out_route(path->net, p, vty, json_path, wide);
8963 }
8964
8965 /*
8966 * If vrf id of nexthop is different from that of prefix,
8967 * set up printable string to append
8968 */
8969 if (path->extra && path->extra->bgp_orig) {
8970 const char *self = "";
8971
8972 if (nexthop_self)
8973 self = "<";
8974
8975 nexthop_othervrf = true;
8976 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8977
8978 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8979 snprintf(vrf_id_str, sizeof(vrf_id_str),
8980 "@%s%s", VRFID_NONE_STR, self);
8981 else
8982 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8983 path->extra->bgp_orig->vrf_id, self);
8984
8985 if (path->extra->bgp_orig->inst_type
8986 != BGP_INSTANCE_TYPE_DEFAULT)
8987
8988 nexthop_vrfname = path->extra->bgp_orig->name;
8989 } else {
8990 const char *self = "";
8991
8992 if (nexthop_self)
8993 self = "<";
8994
8995 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8996 }
8997
8998 /*
8999 * For ENCAP and EVPN routes, nexthop address family is not
9000 * neccessarily the same as the prefix address family.
9001 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9002 * EVPN routes are also exchanged with a MP nexthop. Currently,
9003 * this
9004 * is only IPv4, the value will be present in either
9005 * attr->nexthop or
9006 * attr->mp_nexthop_global_in
9007 */
9008 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9009 char buf[BUFSIZ];
9010 char nexthop[128];
9011 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9012
9013 switch (af) {
9014 case AF_INET:
9015 snprintf(nexthop, sizeof(nexthop), "%s",
9016 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
9017 BUFSIZ));
9018 break;
9019 case AF_INET6:
9020 snprintf(nexthop, sizeof(nexthop), "%s",
9021 inet_ntop(af, &attr->mp_nexthop_global, buf,
9022 BUFSIZ));
9023 break;
9024 default:
9025 snprintf(nexthop, sizeof(nexthop), "?");
9026 break;
9027 }
9028
9029 if (json_paths) {
9030 json_nexthop_global = json_object_new_object();
9031
9032 json_object_string_add(json_nexthop_global, "ip",
9033 nexthop);
9034
9035 if (path->peer->hostname)
9036 json_object_string_add(json_nexthop_global,
9037 "hostname",
9038 path->peer->hostname);
9039
9040 json_object_string_add(json_nexthop_global, "afi",
9041 (af == AF_INET) ? "ipv4"
9042 : "ipv6");
9043 json_object_boolean_true_add(json_nexthop_global,
9044 "used");
9045 } else {
9046 if (nexthop_hostname)
9047 len = vty_out(vty, "%s(%s)%s", nexthop,
9048 nexthop_hostname, vrf_id_str);
9049 else
9050 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9051
9052 len = wide ? (41 - len) : (16 - len);
9053 if (len < 1)
9054 vty_out(vty, "\n%*s", 36, " ");
9055 else
9056 vty_out(vty, "%*s", len, " ");
9057 }
9058 } else if (safi == SAFI_EVPN) {
9059 if (json_paths) {
9060 json_nexthop_global = json_object_new_object();
9061
9062 json_object_string_addf(json_nexthop_global, "ip",
9063 "%pI4",
9064 &attr->mp_nexthop_global_in);
9065
9066 if (path->peer->hostname)
9067 json_object_string_add(json_nexthop_global,
9068 "hostname",
9069 path->peer->hostname);
9070
9071 json_object_string_add(json_nexthop_global, "afi",
9072 "ipv4");
9073 json_object_boolean_true_add(json_nexthop_global,
9074 "used");
9075 } else {
9076 if (nexthop_hostname)
9077 len = vty_out(vty, "%pI4(%s)%s",
9078 &attr->mp_nexthop_global_in,
9079 nexthop_hostname, vrf_id_str);
9080 else
9081 len = vty_out(vty, "%pI4%s",
9082 &attr->mp_nexthop_global_in,
9083 vrf_id_str);
9084
9085 len = wide ? (41 - len) : (16 - len);
9086 if (len < 1)
9087 vty_out(vty, "\n%*s", 36, " ");
9088 else
9089 vty_out(vty, "%*s", len, " ");
9090 }
9091 } else if (safi == SAFI_FLOWSPEC) {
9092 if (attr->nexthop.s_addr != INADDR_ANY) {
9093 if (json_paths) {
9094 json_nexthop_global = json_object_new_object();
9095
9096 json_object_string_add(json_nexthop_global,
9097 "afi", "ipv4");
9098 json_object_string_addf(json_nexthop_global,
9099 "ip", "%pI4",
9100 &attr->nexthop);
9101
9102 if (path->peer->hostname)
9103 json_object_string_add(
9104 json_nexthop_global, "hostname",
9105 path->peer->hostname);
9106
9107 json_object_boolean_true_add(
9108 json_nexthop_global,
9109 "used");
9110 } else {
9111 if (nexthop_hostname)
9112 len = vty_out(vty, "%pI4(%s)%s",
9113 &attr->nexthop,
9114 nexthop_hostname,
9115 vrf_id_str);
9116 else
9117 len = vty_out(vty, "%pI4%s",
9118 &attr->nexthop,
9119 vrf_id_str);
9120
9121 len = wide ? (41 - len) : (16 - len);
9122 if (len < 1)
9123 vty_out(vty, "\n%*s", 36, " ");
9124 else
9125 vty_out(vty, "%*s", len, " ");
9126 }
9127 }
9128 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9129 if (json_paths) {
9130 json_nexthop_global = json_object_new_object();
9131
9132 json_object_string_addf(json_nexthop_global, "ip",
9133 "%pI4", &attr->nexthop);
9134
9135 if (path->peer->hostname)
9136 json_object_string_add(json_nexthop_global,
9137 "hostname",
9138 path->peer->hostname);
9139
9140 json_object_string_add(json_nexthop_global, "afi",
9141 "ipv4");
9142 json_object_boolean_true_add(json_nexthop_global,
9143 "used");
9144 } else {
9145 if (nexthop_hostname)
9146 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9147 nexthop_hostname, vrf_id_str);
9148 else
9149 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9150 vrf_id_str);
9151
9152 len = wide ? (41 - len) : (16 - len);
9153 if (len < 1)
9154 vty_out(vty, "\n%*s", 36, " ");
9155 else
9156 vty_out(vty, "%*s", len, " ");
9157 }
9158 }
9159
9160 /* IPv6 Next Hop */
9161 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9162 if (json_paths) {
9163 json_nexthop_global = json_object_new_object();
9164 json_object_string_addf(json_nexthop_global, "ip",
9165 "%pI6",
9166 &attr->mp_nexthop_global);
9167
9168 if (path->peer->hostname)
9169 json_object_string_add(json_nexthop_global,
9170 "hostname",
9171 path->peer->hostname);
9172
9173 json_object_string_add(json_nexthop_global, "afi",
9174 "ipv6");
9175 json_object_string_add(json_nexthop_global, "scope",
9176 "global");
9177
9178 /* We display both LL & GL if both have been
9179 * received */
9180 if ((attr->mp_nexthop_len
9181 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9182 || (path->peer->conf_if)) {
9183 json_nexthop_ll = json_object_new_object();
9184 json_object_string_addf(
9185 json_nexthop_ll, "ip", "%pI6",
9186 &attr->mp_nexthop_local);
9187
9188 if (path->peer->hostname)
9189 json_object_string_add(
9190 json_nexthop_ll, "hostname",
9191 path->peer->hostname);
9192
9193 json_object_string_add(json_nexthop_ll, "afi",
9194 "ipv6");
9195 json_object_string_add(json_nexthop_ll, "scope",
9196 "link-local");
9197
9198 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9199 &attr->mp_nexthop_local)
9200 != 0)
9201 && !attr->mp_nexthop_prefer_global)
9202 json_object_boolean_true_add(
9203 json_nexthop_ll, "used");
9204 else
9205 json_object_boolean_true_add(
9206 json_nexthop_global, "used");
9207 } else
9208 json_object_boolean_true_add(
9209 json_nexthop_global, "used");
9210 } else {
9211 /* Display LL if LL/Global both in table unless
9212 * prefer-global is set */
9213 if (((attr->mp_nexthop_len
9214 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9215 && !attr->mp_nexthop_prefer_global)
9216 || (path->peer->conf_if)) {
9217 if (path->peer->conf_if) {
9218 len = vty_out(vty, "%s",
9219 path->peer->conf_if);
9220 /* len of IPv6 addr + max len of def
9221 * ifname */
9222 len = wide ? (41 - len) : (16 - len);
9223
9224 if (len < 1)
9225 vty_out(vty, "\n%*s", 36, " ");
9226 else
9227 vty_out(vty, "%*s", len, " ");
9228 } else {
9229 if (nexthop_hostname)
9230 len = vty_out(
9231 vty, "%pI6(%s)%s",
9232 &attr->mp_nexthop_local,
9233 nexthop_hostname,
9234 vrf_id_str);
9235 else
9236 len = vty_out(
9237 vty, "%pI6%s",
9238 &attr->mp_nexthop_local,
9239 vrf_id_str);
9240
9241 len = wide ? (41 - len) : (16 - len);
9242
9243 if (len < 1)
9244 vty_out(vty, "\n%*s", 36, " ");
9245 else
9246 vty_out(vty, "%*s", len, " ");
9247 }
9248 } else {
9249 if (nexthop_hostname)
9250 len = vty_out(vty, "%pI6(%s)%s",
9251 &attr->mp_nexthop_global,
9252 nexthop_hostname,
9253 vrf_id_str);
9254 else
9255 len = vty_out(vty, "%pI6%s",
9256 &attr->mp_nexthop_global,
9257 vrf_id_str);
9258
9259 len = wide ? (41 - len) : (16 - len);
9260
9261 if (len < 1)
9262 vty_out(vty, "\n%*s", 36, " ");
9263 else
9264 vty_out(vty, "%*s", len, " ");
9265 }
9266 }
9267 }
9268
9269 /* MED/Metric */
9270 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9271 if (json_paths)
9272 json_object_int_add(json_path, "metric", attr->med);
9273 else if (wide)
9274 vty_out(vty, "%7u", attr->med);
9275 else
9276 vty_out(vty, "%10u", attr->med);
9277 else if (!json_paths) {
9278 if (wide)
9279 vty_out(vty, "%*s", 7, " ");
9280 else
9281 vty_out(vty, "%*s", 10, " ");
9282 }
9283
9284 /* Local Pref */
9285 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9286 if (json_paths)
9287 json_object_int_add(json_path, "locPrf",
9288 attr->local_pref);
9289 else
9290 vty_out(vty, "%7u", attr->local_pref);
9291 else if (!json_paths)
9292 vty_out(vty, " ");
9293
9294 if (json_paths)
9295 json_object_int_add(json_path, "weight", attr->weight);
9296 else
9297 vty_out(vty, "%7u ", attr->weight);
9298
9299 if (json_paths)
9300 json_object_string_addf(json_path, "peerId", "%pSU",
9301 &path->peer->su);
9302
9303 /* Print aspath */
9304 if (attr->aspath) {
9305 if (json_paths)
9306 json_object_string_add(json_path, "path",
9307 attr->aspath->str);
9308 else
9309 aspath_print_vty(vty, "%s", attr->aspath, " ");
9310 }
9311
9312 /* Print origin */
9313 if (json_paths)
9314 json_object_string_add(json_path, "origin",
9315 bgp_origin_long_str[attr->origin]);
9316 else
9317 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9318
9319 if (json_paths) {
9320 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9321 json_object_string_add(json_path, "esi",
9322 esi_to_str(&attr->esi,
9323 esi_buf, sizeof(esi_buf)));
9324 }
9325 if (safi == SAFI_EVPN &&
9326 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9327 json_ext_community = json_object_new_object();
9328 json_object_string_add(
9329 json_ext_community, "string",
9330 bgp_attr_get_ecommunity(attr)->str);
9331 json_object_object_add(json_path,
9332 "extendedCommunity",
9333 json_ext_community);
9334 }
9335
9336 if (nexthop_self)
9337 json_object_boolean_true_add(json_path,
9338 "announceNexthopSelf");
9339 if (nexthop_othervrf) {
9340 json_object_string_add(json_path, "nhVrfName",
9341 nexthop_vrfname);
9342
9343 json_object_int_add(json_path, "nhVrfId",
9344 ((nexthop_vrfid == VRF_UNKNOWN)
9345 ? -1
9346 : (int)nexthop_vrfid));
9347 }
9348 }
9349
9350 if (json_paths) {
9351 if (json_nexthop_global || json_nexthop_ll) {
9352 json_nexthops = json_object_new_array();
9353
9354 if (json_nexthop_global)
9355 json_object_array_add(json_nexthops,
9356 json_nexthop_global);
9357
9358 if (json_nexthop_ll)
9359 json_object_array_add(json_nexthops,
9360 json_nexthop_ll);
9361
9362 json_object_object_add(json_path, "nexthops",
9363 json_nexthops);
9364 }
9365
9366 json_object_array_add(json_paths, json_path);
9367 } else {
9368 vty_out(vty, "\n");
9369
9370 if (safi == SAFI_EVPN) {
9371 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9372 /* XXX - add these params to the json out */
9373 vty_out(vty, "%*s", 20, " ");
9374 vty_out(vty, "ESI:%s",
9375 esi_to_str(&attr->esi, esi_buf,
9376 sizeof(esi_buf)));
9377
9378 vty_out(vty, "\n");
9379 }
9380 if (attr->flag &
9381 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9382 vty_out(vty, "%*s", 20, " ");
9383 vty_out(vty, "%s\n",
9384 bgp_attr_get_ecommunity(attr)->str);
9385 }
9386 }
9387
9388 #ifdef ENABLE_BGP_VNC
9389 /* prints an additional line, indented, with VNC info, if
9390 * present */
9391 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9392 rfapi_vty_out_vncinfo(vty, p, path, safi);
9393 #endif
9394 }
9395 }
9396
9397 /* called from terminal list command */
9398 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9399 const struct prefix *p, struct attr *attr, safi_t safi,
9400 bool use_json, json_object *json_ar, bool wide)
9401 {
9402 json_object *json_status = NULL;
9403 json_object *json_net = NULL;
9404 int len;
9405 char buff[BUFSIZ];
9406
9407 /* Route status display. */
9408 if (use_json) {
9409 json_status = json_object_new_object();
9410 json_net = json_object_new_object();
9411 } else {
9412 vty_out(vty, "*");
9413 vty_out(vty, ">");
9414 vty_out(vty, " ");
9415 }
9416
9417 /* print prefix and mask */
9418 if (use_json) {
9419 if (safi == SAFI_EVPN)
9420 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9421 else if (p->family == AF_INET || p->family == AF_INET6) {
9422 json_object_string_add(
9423 json_net, "addrPrefix",
9424 inet_ntop(p->family, &p->u.prefix, buff,
9425 BUFSIZ));
9426 json_object_int_add(json_net, "prefixLen",
9427 p->prefixlen);
9428 json_object_string_addf(json_net, "network", "%pFX", p);
9429 }
9430 } else
9431 route_vty_out_route(dest, p, vty, NULL, wide);
9432
9433 /* Print attribute */
9434 if (attr) {
9435 if (use_json) {
9436 if (p->family == AF_INET &&
9437 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9438 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9439 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9440 json_object_string_addf(
9441 json_net, "nextHop", "%pI4",
9442 &attr->mp_nexthop_global_in);
9443 else
9444 json_object_string_addf(
9445 json_net, "nextHop", "%pI4",
9446 &attr->nexthop);
9447 } else if (p->family == AF_INET6 ||
9448 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9449 json_object_string_addf(
9450 json_net, "nextHopGlobal", "%pI6",
9451 &attr->mp_nexthop_global);
9452 } else if (p->family == AF_EVPN &&
9453 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9454 json_object_string_addf(
9455 json_net, "nextHop", "%pI4",
9456 &attr->mp_nexthop_global_in);
9457 }
9458
9459 if (attr->flag
9460 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9461 json_object_int_add(json_net, "metric",
9462 attr->med);
9463
9464 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9465 json_object_int_add(json_net, "locPrf",
9466 attr->local_pref);
9467
9468 json_object_int_add(json_net, "weight", attr->weight);
9469
9470 /* Print aspath */
9471 if (attr->aspath)
9472 json_object_string_add(json_net, "path",
9473 attr->aspath->str);
9474
9475 /* Print origin */
9476 json_object_string_add(json_net, "bgpOriginCode",
9477 bgp_origin_str[attr->origin]);
9478 } else {
9479 if (p->family == AF_INET &&
9480 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9481 safi == SAFI_EVPN ||
9482 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9483 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9484 || safi == SAFI_EVPN)
9485 vty_out(vty, "%-16pI4",
9486 &attr->mp_nexthop_global_in);
9487 else if (wide)
9488 vty_out(vty, "%-41pI4", &attr->nexthop);
9489 else
9490 vty_out(vty, "%-16pI4", &attr->nexthop);
9491 } else if (p->family == AF_INET6 ||
9492 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9493 char buf[BUFSIZ];
9494
9495 len = vty_out(
9496 vty, "%s",
9497 inet_ntop(AF_INET6,
9498 &attr->mp_nexthop_global, buf,
9499 BUFSIZ));
9500 len = wide ? (41 - len) : (16 - len);
9501 if (len < 1)
9502 vty_out(vty, "\n%*s", 36, " ");
9503 else
9504 vty_out(vty, "%*s", len, " ");
9505 }
9506 if (attr->flag
9507 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9508 if (wide)
9509 vty_out(vty, "%7u", attr->med);
9510 else
9511 vty_out(vty, "%10u", attr->med);
9512 else if (wide)
9513 vty_out(vty, " ");
9514 else
9515 vty_out(vty, " ");
9516
9517 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9518 vty_out(vty, "%7u", attr->local_pref);
9519 else
9520 vty_out(vty, " ");
9521
9522 vty_out(vty, "%7u ", attr->weight);
9523
9524 /* Print aspath */
9525 if (attr->aspath)
9526 aspath_print_vty(vty, "%s", attr->aspath, " ");
9527
9528 /* Print origin */
9529 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9530 }
9531 }
9532 if (use_json) {
9533 json_object_boolean_true_add(json_status, "*");
9534 json_object_boolean_true_add(json_status, ">");
9535 json_object_object_add(json_net, "appliedStatusSymbols",
9536 json_status);
9537 json_object_object_addf(json_ar, json_net, "%pFX", p);
9538 } else
9539 vty_out(vty, "\n");
9540 }
9541
9542 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9543 struct bgp_path_info *path, int display, safi_t safi,
9544 json_object *json)
9545 {
9546 json_object *json_out = NULL;
9547 struct attr *attr;
9548 mpls_label_t label = MPLS_INVALID_LABEL;
9549
9550 if (!path->extra)
9551 return;
9552
9553 if (json)
9554 json_out = json_object_new_object();
9555
9556 /* short status lead text */
9557 route_vty_short_status_out(vty, path, p, json_out);
9558
9559 /* print prefix and mask */
9560 if (json == NULL) {
9561 if (!display)
9562 route_vty_out_route(path->net, p, vty, NULL, false);
9563 else
9564 vty_out(vty, "%*s", 17, " ");
9565 }
9566
9567 /* Print attribute */
9568 attr = path->attr;
9569 if (((p->family == AF_INET) &&
9570 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9571 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9572 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9573 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9574 || safi == SAFI_EVPN) {
9575 if (json)
9576 json_object_string_addf(
9577 json_out, "mpNexthopGlobalIn", "%pI4",
9578 &attr->mp_nexthop_global_in);
9579 else
9580 vty_out(vty, "%-16pI4",
9581 &attr->mp_nexthop_global_in);
9582 } else {
9583 if (json)
9584 json_object_string_addf(json_out, "nexthop",
9585 "%pI4", &attr->nexthop);
9586 else
9587 vty_out(vty, "%-16pI4", &attr->nexthop);
9588 }
9589 } else if (((p->family == AF_INET6) &&
9590 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9591 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9592 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9593 char buf_a[512];
9594
9595 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9596 if (json)
9597 json_object_string_addf(
9598 json_out, "mpNexthopGlobalIn", "%pI6",
9599 &attr->mp_nexthop_global);
9600 else
9601 vty_out(vty, "%s",
9602 inet_ntop(AF_INET6,
9603 &attr->mp_nexthop_global,
9604 buf_a, sizeof(buf_a)));
9605 } else if (attr->mp_nexthop_len
9606 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9607 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9608 &attr->mp_nexthop_global,
9609 &attr->mp_nexthop_local);
9610 if (json)
9611 json_object_string_add(json_out,
9612 "mpNexthopGlobalLocal",
9613 buf_a);
9614 else
9615 vty_out(vty, "%s", buf_a);
9616 }
9617 }
9618
9619 label = decode_label(&path->extra->label[0]);
9620
9621 if (bgp_is_valid_label(&label)) {
9622 if (json) {
9623 json_object_int_add(json_out, "notag", label);
9624 json_object_array_add(json, json_out);
9625 } else {
9626 vty_out(vty, "notag/%d", label);
9627 vty_out(vty, "\n");
9628 }
9629 } else if (!json)
9630 vty_out(vty, "\n");
9631 }
9632
9633 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9634 struct bgp_path_info *path, int display,
9635 json_object *json_paths)
9636 {
9637 struct attr *attr;
9638 json_object *json_path = NULL;
9639 json_object *json_nexthop = NULL;
9640 json_object *json_overlay = NULL;
9641
9642 if (!path->extra)
9643 return;
9644
9645 if (json_paths) {
9646 json_path = json_object_new_object();
9647 json_overlay = json_object_new_object();
9648 json_nexthop = json_object_new_object();
9649 }
9650
9651 /* short status lead text */
9652 route_vty_short_status_out(vty, path, p, json_path);
9653
9654 /* print prefix and mask */
9655 if (!display)
9656 route_vty_out_route(path->net, p, vty, json_path, false);
9657 else
9658 vty_out(vty, "%*s", 17, " ");
9659
9660 /* Print attribute */
9661 attr = path->attr;
9662 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9663
9664 switch (af) {
9665 case AF_INET:
9666 if (!json_path) {
9667 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9668 } else {
9669 json_object_string_addf(json_nexthop, "ip", "%pI4",
9670 &attr->mp_nexthop_global_in);
9671
9672 json_object_string_add(json_nexthop, "afi", "ipv4");
9673
9674 json_object_object_add(json_path, "nexthop",
9675 json_nexthop);
9676 }
9677 break;
9678 case AF_INET6:
9679 if (!json_path) {
9680 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9681 &attr->mp_nexthop_local);
9682 } else {
9683 json_object_string_addf(json_nexthop, "ipv6Global",
9684 "%pI6",
9685 &attr->mp_nexthop_global);
9686
9687 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9688 "%pI6",
9689 &attr->mp_nexthop_local);
9690
9691 json_object_string_add(json_nexthop, "afi", "ipv6");
9692
9693 json_object_object_add(json_path, "nexthop",
9694 json_nexthop);
9695 }
9696 break;
9697 default:
9698 if (!json_path) {
9699 vty_out(vty, "?");
9700 } else {
9701 json_object_string_add(json_nexthop, "Error",
9702 "Unsupported address-family");
9703 json_object_string_add(json_nexthop, "error",
9704 "Unsupported address-family");
9705 }
9706 }
9707
9708 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9709
9710 if (!json_path)
9711 vty_out(vty, "/%pIA", &eo->gw_ip);
9712 else
9713 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9714
9715 if (bgp_attr_get_ecommunity(attr)) {
9716 char *mac = NULL;
9717 struct ecommunity_val *routermac = ecommunity_lookup(
9718 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9719 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9720
9721 if (routermac)
9722 mac = ecom_mac2str((char *)routermac->val);
9723 if (mac) {
9724 if (!json_path) {
9725 vty_out(vty, "/%s", mac);
9726 } else {
9727 json_object_string_add(json_overlay, "rmac",
9728 mac);
9729 }
9730 XFREE(MTYPE_TMP, mac);
9731 }
9732 }
9733
9734 if (!json_path) {
9735 vty_out(vty, "\n");
9736 } else {
9737 json_object_object_add(json_path, "overlay", json_overlay);
9738
9739 json_object_array_add(json_paths, json_path);
9740 }
9741 }
9742
9743 /* dampening route */
9744 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9745 struct bgp_path_info *path, int display,
9746 afi_t afi, safi_t safi, bool use_json,
9747 json_object *json_paths)
9748 {
9749 struct attr *attr = path->attr;
9750 int len;
9751 char timebuf[BGP_UPTIME_LEN];
9752 json_object *json_path = NULL;
9753
9754 if (use_json)
9755 json_path = json_object_new_object();
9756
9757 /* short status lead text */
9758 route_vty_short_status_out(vty, path, p, json_path);
9759
9760 /* print prefix and mask */
9761 if (!use_json) {
9762 if (!display)
9763 route_vty_out_route(path->net, p, vty, NULL, false);
9764 else
9765 vty_out(vty, "%*s", 17, " ");
9766
9767 len = vty_out(vty, "%s", path->peer->host);
9768 len = 17 - len;
9769
9770 if (len < 1)
9771 vty_out(vty, "\n%*s", 34, " ");
9772 else
9773 vty_out(vty, "%*s", len, " ");
9774
9775 vty_out(vty, "%s ",
9776 bgp_damp_reuse_time_vty(vty, path, timebuf,
9777 BGP_UPTIME_LEN, afi, safi,
9778 use_json, NULL));
9779
9780 if (attr->aspath)
9781 aspath_print_vty(vty, "%s", attr->aspath, " ");
9782
9783 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9784
9785 vty_out(vty, "\n");
9786 } else {
9787 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9788 safi, use_json, json_path);
9789
9790 if (attr->aspath)
9791 json_object_string_add(json_path, "asPath",
9792 attr->aspath->str);
9793
9794 json_object_string_add(json_path, "origin",
9795 bgp_origin_str[attr->origin]);
9796 json_object_string_add(json_path, "peerHost", path->peer->host);
9797
9798 json_object_array_add(json_paths, json_path);
9799 }
9800 }
9801
9802 /* flap route */
9803 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9804 struct bgp_path_info *path, int display,
9805 afi_t afi, safi_t safi, bool use_json,
9806 json_object *json_paths)
9807 {
9808 struct attr *attr = path->attr;
9809 struct bgp_damp_info *bdi;
9810 char timebuf[BGP_UPTIME_LEN];
9811 int len;
9812 json_object *json_path = NULL;
9813
9814 if (!path->extra)
9815 return;
9816
9817 if (use_json)
9818 json_path = json_object_new_object();
9819
9820 bdi = path->extra->damp_info;
9821
9822 /* short status lead text */
9823 route_vty_short_status_out(vty, path, p, json_path);
9824
9825 if (!use_json) {
9826 if (!display)
9827 route_vty_out_route(path->net, p, vty, NULL, false);
9828 else
9829 vty_out(vty, "%*s", 17, " ");
9830
9831 len = vty_out(vty, "%s", path->peer->host);
9832 len = 16 - len;
9833 if (len < 1)
9834 vty_out(vty, "\n%*s", 33, " ");
9835 else
9836 vty_out(vty, "%*s", len, " ");
9837
9838 len = vty_out(vty, "%d", bdi->flap);
9839 len = 5 - len;
9840 if (len < 1)
9841 vty_out(vty, " ");
9842 else
9843 vty_out(vty, "%*s", len, " ");
9844
9845 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9846 BGP_UPTIME_LEN, 0, NULL));
9847
9848 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9849 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9850 vty_out(vty, "%s ",
9851 bgp_damp_reuse_time_vty(vty, path, timebuf,
9852 BGP_UPTIME_LEN, afi,
9853 safi, use_json, NULL));
9854 else
9855 vty_out(vty, "%*s ", 8, " ");
9856
9857 if (attr->aspath)
9858 aspath_print_vty(vty, "%s", attr->aspath, " ");
9859
9860 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9861
9862 vty_out(vty, "\n");
9863 } else {
9864 json_object_string_add(json_path, "peerHost", path->peer->host);
9865 json_object_int_add(json_path, "bdiFlap", bdi->flap);
9866
9867 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9868 json_path);
9869
9870 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9871 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9872 bgp_damp_reuse_time_vty(vty, path, timebuf,
9873 BGP_UPTIME_LEN, afi, safi,
9874 use_json, json_path);
9875
9876 if (attr->aspath)
9877 json_object_string_add(json_path, "asPath",
9878 attr->aspath->str);
9879
9880 json_object_string_add(json_path, "origin",
9881 bgp_origin_str[attr->origin]);
9882
9883 json_object_array_add(json_paths, json_path);
9884 }
9885 }
9886
9887 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9888 int *first, const char *header,
9889 json_object *json_adv_to)
9890 {
9891 json_object *json_peer = NULL;
9892
9893 if (json_adv_to) {
9894 /* 'advertised-to' is a dictionary of peers we have advertised
9895 * this
9896 * prefix too. The key is the peer's IP or swpX, the value is
9897 * the
9898 * hostname if we know it and "" if not.
9899 */
9900 json_peer = json_object_new_object();
9901
9902 if (peer->hostname)
9903 json_object_string_add(json_peer, "hostname",
9904 peer->hostname);
9905
9906 if (peer->conf_if)
9907 json_object_object_add(json_adv_to, peer->conf_if,
9908 json_peer);
9909 else
9910 json_object_object_addf(json_adv_to, json_peer, "%pSU",
9911 &peer->su);
9912 } else {
9913 if (*first) {
9914 vty_out(vty, "%s", header);
9915 *first = 0;
9916 }
9917
9918 if (peer->hostname
9919 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9920 if (peer->conf_if)
9921 vty_out(vty, " %s(%s)", peer->hostname,
9922 peer->conf_if);
9923 else
9924 vty_out(vty, " %s(%pSU)", peer->hostname,
9925 &peer->su);
9926 } else {
9927 if (peer->conf_if)
9928 vty_out(vty, " %s", peer->conf_if);
9929 else
9930 vty_out(vty, " %pSU", &peer->su);
9931 }
9932 }
9933 }
9934
9935 static void route_vty_out_tx_ids(struct vty *vty,
9936 struct bgp_addpath_info_data *d)
9937 {
9938 int i;
9939
9940 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9941 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9942 d->addpath_tx_id[i],
9943 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9944 }
9945 }
9946
9947 static void route_vty_out_detail_es_info(struct vty *vty,
9948 struct bgp_path_info *pi,
9949 struct attr *attr,
9950 json_object *json_path)
9951 {
9952 char esi_buf[ESI_STR_LEN];
9953 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9954 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9955 ATTR_ES_PEER_ROUTER);
9956 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9957 ATTR_ES_PEER_ACTIVE);
9958 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9959 ATTR_ES_PEER_PROXY);
9960 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9961 if (json_path) {
9962 json_object *json_es_info = NULL;
9963
9964 json_object_string_add(
9965 json_path, "esi",
9966 esi_buf);
9967 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9968 json_es_info = json_object_new_object();
9969 if (es_local)
9970 json_object_boolean_true_add(
9971 json_es_info, "localEs");
9972 if (peer_active)
9973 json_object_boolean_true_add(
9974 json_es_info, "peerActive");
9975 if (peer_proxy)
9976 json_object_boolean_true_add(
9977 json_es_info, "peerProxy");
9978 if (peer_router)
9979 json_object_boolean_true_add(
9980 json_es_info, "peerRouter");
9981 if (attr->mm_sync_seqnum)
9982 json_object_int_add(
9983 json_es_info, "peerSeq",
9984 attr->mm_sync_seqnum);
9985 json_object_object_add(
9986 json_path, "es_info",
9987 json_es_info);
9988 }
9989 } else {
9990 if (bgp_evpn_attr_is_sync(attr))
9991 vty_out(vty,
9992 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9993 esi_buf,
9994 es_local ? "local-es":"",
9995 peer_proxy ? "proxy " : "",
9996 peer_active ? "active ":"",
9997 peer_router ? "router ":"",
9998 attr->mm_sync_seqnum);
9999 else
10000 vty_out(vty, " ESI %s %s\n",
10001 esi_buf,
10002 es_local ? "local-es":"");
10003 }
10004 }
10005
10006 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10007 struct bgp_path_info *path, afi_t afi, safi_t safi,
10008 enum rpki_states rpki_curr_state,
10009 json_object *json_paths)
10010 {
10011 char buf[INET6_ADDRSTRLEN];
10012 char buf1[BUFSIZ];
10013 struct attr *attr = path->attr;
10014 time_t tbuf;
10015 json_object *json_bestpath = NULL;
10016 json_object *json_cluster_list = NULL;
10017 json_object *json_cluster_list_list = NULL;
10018 json_object *json_ext_community = NULL;
10019 json_object *json_last_update = NULL;
10020 json_object *json_pmsi = NULL;
10021 json_object *json_nexthop_global = NULL;
10022 json_object *json_nexthop_ll = NULL;
10023 json_object *json_nexthops = NULL;
10024 json_object *json_path = NULL;
10025 json_object *json_peer = NULL;
10026 json_object *json_string = NULL;
10027 json_object *json_adv_to = NULL;
10028 int first = 0;
10029 struct listnode *node, *nnode;
10030 struct peer *peer;
10031 bool addpath_capable;
10032 int has_adj;
10033 unsigned int first_as;
10034 bool nexthop_self =
10035 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10036 int i;
10037 char *nexthop_hostname =
10038 bgp_nexthop_hostname(path->peer, path->nexthop);
10039 uint32_t ttl = 0;
10040 uint32_t bos = 0;
10041 uint32_t exp = 0;
10042 mpls_label_t label = MPLS_INVALID_LABEL;
10043
10044 if (json_paths) {
10045 json_path = json_object_new_object();
10046 json_peer = json_object_new_object();
10047 json_nexthop_global = json_object_new_object();
10048 }
10049
10050 if (safi == SAFI_EVPN) {
10051 if (!json_paths)
10052 vty_out(vty, " Route %pRN", bn);
10053 }
10054
10055 if (path->extra) {
10056 char tag_buf[30];
10057
10058 tag_buf[0] = '\0';
10059 if (path->extra && path->extra->num_labels) {
10060 bgp_evpn_label2str(path->extra->label,
10061 path->extra->num_labels, tag_buf,
10062 sizeof(tag_buf));
10063 }
10064 if (safi == SAFI_EVPN) {
10065 if (!json_paths) {
10066 if (tag_buf[0] != '\0')
10067 vty_out(vty, " VNI %s", tag_buf);
10068 } else {
10069 if (tag_buf[0]) {
10070 json_object_string_add(json_path, "VNI",
10071 tag_buf);
10072 json_object_string_add(json_path, "vni",
10073 tag_buf);
10074 }
10075 }
10076 }
10077
10078 if (path->extra && path->extra->parent && !json_paths) {
10079 struct bgp_path_info *parent_ri;
10080 struct bgp_dest *dest, *pdest;
10081
10082 parent_ri = (struct bgp_path_info *)path->extra->parent;
10083 dest = parent_ri->net;
10084 if (dest && dest->pdest) {
10085 pdest = dest->pdest;
10086 prefix_rd2str(
10087 (struct prefix_rd *)bgp_dest_get_prefix(
10088 pdest),
10089 buf1, sizeof(buf1));
10090 if (is_pi_family_evpn(parent_ri)) {
10091 vty_out(vty,
10092 " Imported from %s:%pFX, VNI %s",
10093 buf1,
10094 (struct prefix_evpn *)
10095 bgp_dest_get_prefix(
10096 dest),
10097 tag_buf);
10098 if (attr->es_flags & ATTR_ES_L3_NHG)
10099 vty_out(vty, ", L3NHG %s",
10100 (attr->es_flags
10101 & ATTR_ES_L3_NHG_ACTIVE)
10102 ? "active"
10103 : "inactive");
10104 vty_out(vty, "\n");
10105
10106 } else
10107 vty_out(vty,
10108 " Imported from %s:%pFX\n",
10109 buf1,
10110 (struct prefix_evpn *)
10111 bgp_dest_get_prefix(
10112 dest));
10113 }
10114 }
10115 }
10116
10117 if (safi == SAFI_EVPN
10118 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10119 char gwip_buf[INET6_ADDRSTRLEN];
10120
10121 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10122 sizeof(gwip_buf));
10123
10124 if (json_paths)
10125 json_object_string_add(json_path, "gatewayIP",
10126 gwip_buf);
10127 else
10128 vty_out(vty, " Gateway IP %s", gwip_buf);
10129 }
10130
10131 if (safi == SAFI_EVPN && !json_path)
10132 vty_out(vty, "\n");
10133
10134 /* Line1 display AS-path, Aggregator */
10135 if (attr->aspath) {
10136 if (json_paths) {
10137 if (!attr->aspath->json)
10138 aspath_str_update(attr->aspath, true);
10139 json_object_lock(attr->aspath->json);
10140 json_object_object_add(json_path, "aspath",
10141 attr->aspath->json);
10142 } else {
10143 if (attr->aspath->segments)
10144 aspath_print_vty(vty, " %s", attr->aspath, "");
10145 else
10146 vty_out(vty, " Local");
10147 }
10148 }
10149
10150 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10151 if (json_paths)
10152 json_object_boolean_true_add(json_path, "removed");
10153 else
10154 vty_out(vty, ", (removed)");
10155 }
10156
10157 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10158 if (json_paths)
10159 json_object_boolean_true_add(json_path, "stale");
10160 else
10161 vty_out(vty, ", (stale)");
10162 }
10163
10164 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10165 if (json_paths) {
10166 json_object_int_add(json_path, "aggregatorAs",
10167 attr->aggregator_as);
10168 json_object_string_addf(json_path, "aggregatorId",
10169 "%pI4", &attr->aggregator_addr);
10170 } else {
10171 vty_out(vty, ", (aggregated by %u %pI4)",
10172 attr->aggregator_as, &attr->aggregator_addr);
10173 }
10174 }
10175
10176 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10177 PEER_FLAG_REFLECTOR_CLIENT)) {
10178 if (json_paths)
10179 json_object_boolean_true_add(json_path,
10180 "rxedFromRrClient");
10181 else
10182 vty_out(vty, ", (Received from a RR-client)");
10183 }
10184
10185 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10186 PEER_FLAG_RSERVER_CLIENT)) {
10187 if (json_paths)
10188 json_object_boolean_true_add(json_path,
10189 "rxedFromRsClient");
10190 else
10191 vty_out(vty, ", (Received from a RS-client)");
10192 }
10193
10194 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10195 if (json_paths)
10196 json_object_boolean_true_add(json_path,
10197 "dampeningHistoryEntry");
10198 else
10199 vty_out(vty, ", (history entry)");
10200 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10201 if (json_paths)
10202 json_object_boolean_true_add(json_path,
10203 "dampeningSuppressed");
10204 else
10205 vty_out(vty, ", (suppressed due to dampening)");
10206 }
10207
10208 if (!json_paths)
10209 vty_out(vty, "\n");
10210
10211 /* Line2 display Next-hop, Neighbor, Router-id */
10212 /* Display the nexthop */
10213 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10214
10215 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET ||
10216 bn_p->family == AF_EVPN) &&
10217 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10218 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10219 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10220 || safi == SAFI_EVPN) {
10221 if (json_paths) {
10222 json_object_string_addf(
10223 json_nexthop_global, "ip", "%pI4",
10224 &attr->mp_nexthop_global_in);
10225
10226 if (path->peer->hostname)
10227 json_object_string_add(
10228 json_nexthop_global, "hostname",
10229 path->peer->hostname);
10230 } else {
10231 if (nexthop_hostname)
10232 vty_out(vty, " %pI4(%s)",
10233 &attr->mp_nexthop_global_in,
10234 nexthop_hostname);
10235 else
10236 vty_out(vty, " %pI4",
10237 &attr->mp_nexthop_global_in);
10238 }
10239 } else {
10240 if (json_paths) {
10241 json_object_string_addf(json_nexthop_global,
10242 "ip", "%pI4",
10243 &attr->nexthop);
10244
10245 if (path->peer->hostname)
10246 json_object_string_add(
10247 json_nexthop_global, "hostname",
10248 path->peer->hostname);
10249 } else {
10250 if (nexthop_hostname)
10251 vty_out(vty, " %pI4(%s)",
10252 &attr->nexthop,
10253 nexthop_hostname);
10254 else
10255 vty_out(vty, " %pI4",
10256 &attr->nexthop);
10257 }
10258 }
10259
10260 if (json_paths)
10261 json_object_string_add(json_nexthop_global, "afi",
10262 "ipv4");
10263 } else {
10264 if (json_paths) {
10265 json_object_string_addf(json_nexthop_global, "ip",
10266 "%pI6",
10267 &attr->mp_nexthop_global);
10268
10269 if (path->peer->hostname)
10270 json_object_string_add(json_nexthop_global,
10271 "hostname",
10272 path->peer->hostname);
10273
10274 json_object_string_add(json_nexthop_global, "afi",
10275 "ipv6");
10276 json_object_string_add(json_nexthop_global, "scope",
10277 "global");
10278 } else {
10279 if (nexthop_hostname)
10280 vty_out(vty, " %pI6(%s)",
10281 &attr->mp_nexthop_global,
10282 nexthop_hostname);
10283 else
10284 vty_out(vty, " %pI6",
10285 &attr->mp_nexthop_global);
10286 }
10287 }
10288
10289 /* Display the IGP cost or 'inaccessible' */
10290 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10291 if (json_paths)
10292 json_object_boolean_false_add(json_nexthop_global,
10293 "accessible");
10294 else
10295 vty_out(vty, " (inaccessible)");
10296 } else {
10297 if (path->extra && path->extra->igpmetric) {
10298 if (json_paths)
10299 json_object_int_add(json_nexthop_global,
10300 "metric",
10301 path->extra->igpmetric);
10302 else
10303 vty_out(vty, " (metric %u)",
10304 path->extra->igpmetric);
10305 }
10306
10307 /* IGP cost is 0, display this only for json */
10308 else {
10309 if (json_paths)
10310 json_object_int_add(json_nexthop_global,
10311 "metric", 0);
10312 }
10313
10314 if (json_paths)
10315 json_object_boolean_true_add(json_nexthop_global,
10316 "accessible");
10317 }
10318
10319 /* Display peer "from" output */
10320 /* This path was originated locally */
10321 if (path->peer == bgp->peer_self) {
10322
10323 if (safi == SAFI_EVPN || (bn_p->family == AF_INET &&
10324 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10325 if (json_paths)
10326 json_object_string_add(json_peer, "peerId",
10327 "0.0.0.0");
10328 else
10329 vty_out(vty, " from 0.0.0.0 ");
10330 } else {
10331 if (json_paths)
10332 json_object_string_add(json_peer, "peerId",
10333 "::");
10334 else
10335 vty_out(vty, " from :: ");
10336 }
10337
10338 if (json_paths)
10339 json_object_string_addf(json_peer, "routerId", "%pI4",
10340 &bgp->router_id);
10341 else
10342 vty_out(vty, "(%pI4)", &bgp->router_id);
10343 }
10344
10345 /* We RXed this path from one of our peers */
10346 else {
10347
10348 if (json_paths) {
10349 json_object_string_addf(json_peer, "peerId", "%pSU",
10350 &path->peer->su);
10351 json_object_string_addf(json_peer, "routerId", "%pI4",
10352 &path->peer->remote_id);
10353
10354 if (path->peer->hostname)
10355 json_object_string_add(json_peer, "hostname",
10356 path->peer->hostname);
10357
10358 if (path->peer->domainname)
10359 json_object_string_add(json_peer, "domainname",
10360 path->peer->domainname);
10361
10362 if (path->peer->conf_if)
10363 json_object_string_add(json_peer, "interface",
10364 path->peer->conf_if);
10365 } else {
10366 if (path->peer->conf_if) {
10367 if (path->peer->hostname
10368 && CHECK_FLAG(path->peer->bgp->flags,
10369 BGP_FLAG_SHOW_HOSTNAME))
10370 vty_out(vty, " from %s(%s)",
10371 path->peer->hostname,
10372 path->peer->conf_if);
10373 else
10374 vty_out(vty, " from %s",
10375 path->peer->conf_if);
10376 } else {
10377 if (path->peer->hostname
10378 && CHECK_FLAG(path->peer->bgp->flags,
10379 BGP_FLAG_SHOW_HOSTNAME))
10380 vty_out(vty, " from %s(%s)",
10381 path->peer->hostname,
10382 path->peer->host);
10383 else
10384 vty_out(vty, " from %pSU",
10385 &path->peer->su);
10386 }
10387
10388 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10389 vty_out(vty, " (%pI4)", &attr->originator_id);
10390 else
10391 vty_out(vty, " (%s)",
10392 inet_ntop(AF_INET,
10393 &path->peer->remote_id, buf1,
10394 sizeof(buf1)));
10395 }
10396 }
10397
10398 /*
10399 * Note when vrfid of nexthop is different from that of prefix
10400 */
10401 if (path->extra && path->extra->bgp_orig) {
10402 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10403
10404 if (json_paths) {
10405 const char *vn;
10406
10407 if (path->extra->bgp_orig->inst_type
10408 == BGP_INSTANCE_TYPE_DEFAULT)
10409 vn = VRF_DEFAULT_NAME;
10410 else
10411 vn = path->extra->bgp_orig->name;
10412
10413 json_object_string_add(json_path, "nhVrfName", vn);
10414
10415 if (nexthop_vrfid == VRF_UNKNOWN) {
10416 json_object_int_add(json_path, "nhVrfId", -1);
10417 } else {
10418 json_object_int_add(json_path, "nhVrfId",
10419 (int)nexthop_vrfid);
10420 }
10421 } else {
10422 if (nexthop_vrfid == VRF_UNKNOWN)
10423 vty_out(vty, " vrf ?");
10424 else {
10425 struct vrf *vrf;
10426
10427 vrf = vrf_lookup_by_id(nexthop_vrfid);
10428 vty_out(vty, " vrf %s(%u)",
10429 VRF_LOGNAME(vrf), nexthop_vrfid);
10430 }
10431 }
10432 }
10433
10434 if (nexthop_self) {
10435 if (json_paths) {
10436 json_object_boolean_true_add(json_path,
10437 "announceNexthopSelf");
10438 } else {
10439 vty_out(vty, " announce-nh-self");
10440 }
10441 }
10442
10443 if (!json_paths)
10444 vty_out(vty, "\n");
10445
10446 /* display the link-local nexthop */
10447 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10448 if (json_paths) {
10449 json_nexthop_ll = json_object_new_object();
10450 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10451 &attr->mp_nexthop_local);
10452
10453 if (path->peer->hostname)
10454 json_object_string_add(json_nexthop_ll,
10455 "hostname",
10456 path->peer->hostname);
10457
10458 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10459 json_object_string_add(json_nexthop_ll, "scope",
10460 "link-local");
10461
10462 json_object_boolean_true_add(json_nexthop_ll,
10463 "accessible");
10464
10465 if (!attr->mp_nexthop_prefer_global)
10466 json_object_boolean_true_add(json_nexthop_ll,
10467 "used");
10468 else
10469 json_object_boolean_true_add(
10470 json_nexthop_global, "used");
10471 } else {
10472 vty_out(vty, " (%s) %s\n",
10473 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10474 buf, INET6_ADDRSTRLEN),
10475 attr->mp_nexthop_prefer_global
10476 ? "(prefer-global)"
10477 : "(used)");
10478 }
10479 }
10480 /* If we do not have a link-local nexthop then we must flag the
10481 global as "used" */
10482 else {
10483 if (json_paths)
10484 json_object_boolean_true_add(json_nexthop_global,
10485 "used");
10486 }
10487
10488 if (safi == SAFI_EVPN &&
10489 bgp_evpn_is_esi_valid(&attr->esi)) {
10490 route_vty_out_detail_es_info(vty, path, attr, json_path);
10491 }
10492
10493 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10494 * Int/Ext/Local, Atomic, best */
10495 if (json_paths)
10496 json_object_string_add(json_path, "origin",
10497 bgp_origin_long_str[attr->origin]);
10498 else
10499 vty_out(vty, " Origin %s",
10500 bgp_origin_long_str[attr->origin]);
10501
10502 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10503 if (json_paths)
10504 json_object_int_add(json_path, "metric", attr->med);
10505 else
10506 vty_out(vty, ", metric %u", attr->med);
10507 }
10508
10509 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10510 if (json_paths)
10511 json_object_int_add(json_path, "locPrf",
10512 attr->local_pref);
10513 else
10514 vty_out(vty, ", localpref %u", attr->local_pref);
10515 }
10516
10517 if (attr->weight != 0) {
10518 if (json_paths)
10519 json_object_int_add(json_path, "weight", attr->weight);
10520 else
10521 vty_out(vty, ", weight %u", attr->weight);
10522 }
10523
10524 if (attr->tag != 0) {
10525 if (json_paths)
10526 json_object_int_add(json_path, "tag", attr->tag);
10527 else
10528 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10529 }
10530
10531 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10532 if (json_paths)
10533 json_object_boolean_false_add(json_path, "valid");
10534 else
10535 vty_out(vty, ", invalid");
10536 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10537 if (json_paths)
10538 json_object_boolean_true_add(json_path, "valid");
10539 else
10540 vty_out(vty, ", valid");
10541 }
10542
10543 if (json_paths)
10544 json_object_int_add(json_path, "version", bn->version);
10545
10546 if (path->peer != bgp->peer_self) {
10547 if (path->peer->as == path->peer->local_as) {
10548 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10549 if (json_paths)
10550 json_object_string_add(
10551 json_peer, "type",
10552 "confed-internal");
10553 else
10554 vty_out(vty, ", confed-internal");
10555 } else {
10556 if (json_paths)
10557 json_object_string_add(
10558 json_peer, "type", "internal");
10559 else
10560 vty_out(vty, ", internal");
10561 }
10562 } else {
10563 if (bgp_confederation_peers_check(bgp,
10564 path->peer->as)) {
10565 if (json_paths)
10566 json_object_string_add(
10567 json_peer, "type",
10568 "confed-external");
10569 else
10570 vty_out(vty, ", confed-external");
10571 } else {
10572 if (json_paths)
10573 json_object_string_add(
10574 json_peer, "type", "external");
10575 else
10576 vty_out(vty, ", external");
10577 }
10578 }
10579 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10580 if (json_paths) {
10581 json_object_boolean_true_add(json_path, "aggregated");
10582 json_object_boolean_true_add(json_path, "local");
10583 } else {
10584 vty_out(vty, ", aggregated, local");
10585 }
10586 } else if (path->type != ZEBRA_ROUTE_BGP) {
10587 if (json_paths)
10588 json_object_boolean_true_add(json_path, "sourced");
10589 else
10590 vty_out(vty, ", sourced");
10591 } else {
10592 if (json_paths) {
10593 json_object_boolean_true_add(json_path, "sourced");
10594 json_object_boolean_true_add(json_path, "local");
10595 } else {
10596 vty_out(vty, ", sourced, local");
10597 }
10598 }
10599
10600 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10601 if (json_paths)
10602 json_object_boolean_true_add(json_path,
10603 "atomicAggregate");
10604 else
10605 vty_out(vty, ", atomic-aggregate");
10606 }
10607
10608 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10609 if (json_paths)
10610 json_object_int_add(json_path, "otc", attr->otc);
10611 else
10612 vty_out(vty, ", otc %u", attr->otc);
10613 }
10614
10615 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10616 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10617 && bgp_path_info_mpath_count(path))) {
10618 if (json_paths)
10619 json_object_boolean_true_add(json_path, "multipath");
10620 else
10621 vty_out(vty, ", multipath");
10622 }
10623
10624 // Mark the bestpath(s)
10625 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10626 first_as = aspath_get_first_as(attr->aspath);
10627
10628 if (json_paths) {
10629 if (!json_bestpath)
10630 json_bestpath = json_object_new_object();
10631 json_object_int_add(json_bestpath, "bestpathFromAs",
10632 first_as);
10633 } else {
10634 if (first_as)
10635 vty_out(vty, ", bestpath-from-AS %u", first_as);
10636 else
10637 vty_out(vty, ", bestpath-from-AS Local");
10638 }
10639 }
10640
10641 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10642 if (json_paths) {
10643 if (!json_bestpath)
10644 json_bestpath = json_object_new_object();
10645 json_object_boolean_true_add(json_bestpath, "overall");
10646 json_object_string_add(
10647 json_bestpath, "selectionReason",
10648 bgp_path_selection_reason2str(bn->reason));
10649 } else {
10650 vty_out(vty, ", best");
10651 vty_out(vty, " (%s)",
10652 bgp_path_selection_reason2str(bn->reason));
10653 }
10654 }
10655
10656 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10657 if (json_paths)
10658 json_object_string_add(
10659 json_path, "rpkiValidationState",
10660 bgp_rpki_validation2str(rpki_curr_state));
10661 else
10662 vty_out(vty, ", rpki validation-state: %s",
10663 bgp_rpki_validation2str(rpki_curr_state));
10664 }
10665
10666 if (json_bestpath)
10667 json_object_object_add(json_path, "bestpath", json_bestpath);
10668
10669 if (!json_paths)
10670 vty_out(vty, "\n");
10671
10672 /* Line 4 display Community */
10673 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10674 if (json_paths) {
10675 if (!bgp_attr_get_community(attr)->json)
10676 community_str(bgp_attr_get_community(attr),
10677 true, true);
10678 json_object_lock(bgp_attr_get_community(attr)->json);
10679 json_object_object_add(
10680 json_path, "community",
10681 bgp_attr_get_community(attr)->json);
10682 } else {
10683 vty_out(vty, " Community: %s\n",
10684 bgp_attr_get_community(attr)->str);
10685 }
10686 }
10687
10688 /* Line 5 display Extended-community */
10689 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10690 if (json_paths) {
10691 json_ext_community = json_object_new_object();
10692 json_object_string_add(
10693 json_ext_community, "string",
10694 bgp_attr_get_ecommunity(attr)->str);
10695 json_object_object_add(json_path, "extendedCommunity",
10696 json_ext_community);
10697 } else {
10698 vty_out(vty, " Extended Community: %s\n",
10699 bgp_attr_get_ecommunity(attr)->str);
10700 }
10701 }
10702
10703 /* Line 6 display Large community */
10704 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10705 if (json_paths) {
10706 if (!bgp_attr_get_lcommunity(attr)->json)
10707 lcommunity_str(bgp_attr_get_lcommunity(attr),
10708 true, true);
10709 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10710 json_object_object_add(
10711 json_path, "largeCommunity",
10712 bgp_attr_get_lcommunity(attr)->json);
10713 } else {
10714 vty_out(vty, " Large Community: %s\n",
10715 bgp_attr_get_lcommunity(attr)->str);
10716 }
10717 }
10718
10719 /* Line 7 display Originator, Cluster-id */
10720 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10721 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10722 char buf[BUFSIZ] = {0};
10723
10724 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10725 if (json_paths)
10726 json_object_string_addf(json_path,
10727 "originatorId", "%pI4",
10728 &attr->originator_id);
10729 else
10730 vty_out(vty, " Originator: %pI4",
10731 &attr->originator_id);
10732 }
10733
10734 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10735 struct cluster_list *cluster =
10736 bgp_attr_get_cluster(attr);
10737 int i;
10738
10739 if (json_paths) {
10740 json_cluster_list = json_object_new_object();
10741 json_cluster_list_list =
10742 json_object_new_array();
10743
10744 for (i = 0; i < cluster->length / 4; i++) {
10745 json_string = json_object_new_string(
10746 inet_ntop(AF_INET,
10747 &cluster->list[i],
10748 buf, sizeof(buf)));
10749 json_object_array_add(
10750 json_cluster_list_list,
10751 json_string);
10752 }
10753
10754 /*
10755 * struct cluster_list does not have
10756 * "str" variable like aspath and community
10757 * do. Add this someday if someone asks
10758 * for it.
10759 * json_object_string_add(json_cluster_list,
10760 * "string", cluster->str);
10761 */
10762 json_object_object_add(json_cluster_list,
10763 "list",
10764 json_cluster_list_list);
10765 json_object_object_add(json_path, "clusterList",
10766 json_cluster_list);
10767 } else {
10768 vty_out(vty, ", Cluster list: ");
10769
10770 for (i = 0; i < cluster->length / 4; i++) {
10771 vty_out(vty, "%pI4 ",
10772 &cluster->list[i]);
10773 }
10774 }
10775 }
10776
10777 if (!json_paths)
10778 vty_out(vty, "\n");
10779 }
10780
10781 if (path->extra && path->extra->damp_info)
10782 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10783
10784 /* Remote Label */
10785 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10786 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10787 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10788 &bos);
10789
10790 if (json_paths)
10791 json_object_int_add(json_path, "remoteLabel", label);
10792 else
10793 vty_out(vty, " Remote label: %d\n", label);
10794 }
10795
10796 /* Remote SID */
10797 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10798 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
10799 if (json_paths)
10800 json_object_string_add(json_path, "remoteSid", buf);
10801 else
10802 vty_out(vty, " Remote SID: %s\n", buf);
10803 }
10804
10805 /* Label Index */
10806 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10807 if (json_paths)
10808 json_object_int_add(json_path, "labelIndex",
10809 attr->label_index);
10810 else
10811 vty_out(vty, " Label Index: %d\n",
10812 attr->label_index);
10813 }
10814
10815 /* Line 8 display Addpath IDs */
10816 if (path->addpath_rx_id
10817 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10818 if (json_paths) {
10819 json_object_int_add(json_path, "addpathRxId",
10820 path->addpath_rx_id);
10821
10822 /* Keep backwards compatibility with the old API
10823 * by putting TX All's ID in the old field
10824 */
10825 json_object_int_add(
10826 json_path, "addpathTxId",
10827 path->tx_addpath
10828 .addpath_tx_id[BGP_ADDPATH_ALL]);
10829
10830 /* ... but create a specific field for each
10831 * strategy
10832 */
10833 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10834 json_object_int_add(
10835 json_path,
10836 bgp_addpath_names(i)->id_json_name,
10837 path->tx_addpath.addpath_tx_id[i]);
10838 }
10839 } else {
10840 vty_out(vty, " AddPath ID: RX %u, ",
10841 path->addpath_rx_id);
10842
10843 route_vty_out_tx_ids(vty, &path->tx_addpath);
10844 }
10845 }
10846
10847 /* If we used addpath to TX a non-bestpath we need to display
10848 * "Advertised to" on a path-by-path basis
10849 */
10850 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10851 first = 1;
10852
10853 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10854 addpath_capable =
10855 bgp_addpath_encode_tx(peer, afi, safi);
10856 has_adj = bgp_adj_out_lookup(
10857 peer, path->net,
10858 bgp_addpath_id_for_peer(peer, afi, safi,
10859 &path->tx_addpath));
10860
10861 if ((addpath_capable && has_adj)
10862 || (!addpath_capable && has_adj
10863 && CHECK_FLAG(path->flags,
10864 BGP_PATH_SELECTED))) {
10865 if (json_path && !json_adv_to)
10866 json_adv_to = json_object_new_object();
10867
10868 route_vty_out_advertised_to(
10869 vty, peer, &first,
10870 " Advertised to:", json_adv_to);
10871 }
10872 }
10873
10874 if (json_path) {
10875 if (json_adv_to) {
10876 json_object_object_add(
10877 json_path, "advertisedTo", json_adv_to);
10878 }
10879 } else {
10880 if (!first) {
10881 vty_out(vty, "\n");
10882 }
10883 }
10884 }
10885
10886 /* Line 9 display Uptime */
10887 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
10888 if (json_paths) {
10889 json_last_update = json_object_new_object();
10890 json_object_int_add(json_last_update, "epoch", tbuf);
10891 json_object_string_add(json_last_update, "string",
10892 ctime(&tbuf));
10893 json_object_object_add(json_path, "lastUpdate",
10894 json_last_update);
10895 } else
10896 vty_out(vty, " Last update: %s", ctime(&tbuf));
10897
10898 /* Line 10 display PMSI tunnel attribute, if present */
10899 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10900 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10901 bgp_attr_get_pmsi_tnl_type(attr),
10902 PMSI_TNLTYPE_STR_DEFAULT);
10903
10904 if (json_paths) {
10905 json_pmsi = json_object_new_object();
10906 json_object_string_add(json_pmsi, "tunnelType", str);
10907 json_object_int_add(json_pmsi, "label",
10908 label2vni(&attr->label));
10909 json_object_object_add(json_path, "pmsi", json_pmsi);
10910 } else
10911 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10912 str, label2vni(&attr->label));
10913 }
10914
10915 if (path->peer->t_gr_restart &&
10916 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10917 unsigned long gr_remaining =
10918 thread_timer_remain_second(path->peer->t_gr_restart);
10919
10920 if (json_paths) {
10921 json_object_int_add(json_path,
10922 "gracefulRestartSecondsRemaining",
10923 gr_remaining);
10924 } else
10925 vty_out(vty,
10926 " Time until Graceful Restart stale route deleted: %lu\n",
10927 gr_remaining);
10928 }
10929
10930 if (path->peer->t_llgr_stale[afi][safi] &&
10931 bgp_attr_get_community(attr) &&
10932 community_include(bgp_attr_get_community(attr),
10933 COMMUNITY_LLGR_STALE)) {
10934 unsigned long llgr_remaining = thread_timer_remain_second(
10935 path->peer->t_llgr_stale[afi][safi]);
10936
10937 if (json_paths) {
10938 json_object_int_add(json_path, "llgrSecondsRemaining",
10939 llgr_remaining);
10940 } else
10941 vty_out(vty,
10942 " Time until Long-lived stale route deleted: %lu\n",
10943 llgr_remaining);
10944 }
10945
10946 /* Output some debug about internal state of the dest flags */
10947 if (json_paths) {
10948 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10949 json_object_boolean_true_add(json_path, "processScheduled");
10950 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10951 json_object_boolean_true_add(json_path, "userCleared");
10952 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10953 json_object_boolean_true_add(json_path, "labelChanged");
10954 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10955 json_object_boolean_true_add(json_path, "registeredForLabel");
10956 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10957 json_object_boolean_true_add(json_path, "selectDefered");
10958 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10959 json_object_boolean_true_add(json_path, "fibInstalled");
10960 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10961 json_object_boolean_true_add(json_path, "fibPending");
10962
10963 if (json_nexthop_global || json_nexthop_ll) {
10964 json_nexthops = json_object_new_array();
10965
10966 if (json_nexthop_global)
10967 json_object_array_add(json_nexthops,
10968 json_nexthop_global);
10969
10970 if (json_nexthop_ll)
10971 json_object_array_add(json_nexthops,
10972 json_nexthop_ll);
10973
10974 json_object_object_add(json_path, "nexthops",
10975 json_nexthops);
10976 }
10977
10978 json_object_object_add(json_path, "peer", json_peer);
10979 json_object_array_add(json_paths, json_path);
10980 }
10981 }
10982
10983 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10984 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10985 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10986
10987 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10988 afi_t afi, safi_t safi, enum bgp_show_type type,
10989 bool use_json);
10990 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10991 const char *comstr, int exact, afi_t afi,
10992 safi_t safi, uint16_t show_flags);
10993
10994 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10995 struct bgp_table *table, enum bgp_show_type type,
10996 void *output_arg, const char *rd, int is_last,
10997 unsigned long *output_cum, unsigned long *total_cum,
10998 unsigned long *json_header_depth, uint16_t show_flags,
10999 enum rpki_states rpki_target_state)
11000 {
11001 struct bgp_path_info *pi;
11002 struct bgp_dest *dest;
11003 bool header = true;
11004 bool json_detail_header = false;
11005 int display;
11006 unsigned long output_count = 0;
11007 unsigned long total_count = 0;
11008 struct prefix *p;
11009 json_object *json_paths = NULL;
11010 int first = 1;
11011 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11012 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11013 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11014
11015 if (output_cum && *output_cum != 0)
11016 header = false;
11017
11018 if (use_json && !*json_header_depth) {
11019 if (all)
11020 *json_header_depth = 1;
11021 else {
11022 vty_out(vty, "{\n");
11023 *json_header_depth = 2;
11024 }
11025
11026 vty_out(vty,
11027 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11028 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11029 " \"localAS\": %u,\n \"routes\": { ",
11030 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11031 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11032 ? VRF_DEFAULT_NAME
11033 : bgp->name,
11034 table->version, &bgp->router_id,
11035 bgp->default_local_pref, bgp->as);
11036 if (rd) {
11037 vty_out(vty, " \"routeDistinguishers\" : {");
11038 ++*json_header_depth;
11039 }
11040 }
11041
11042 if (use_json && rd) {
11043 vty_out(vty, " \"%s\" : { ", rd);
11044 }
11045
11046 /* Check for 'json detail', where we need header output once per dest */
11047 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
11048 type != bgp_show_type_dampend_paths &&
11049 type != bgp_show_type_damp_neighbor &&
11050 type != bgp_show_type_flap_statistics &&
11051 type != bgp_show_type_flap_neighbor)
11052 json_detail_header = true;
11053
11054 /* Start processing of routes. */
11055 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11056 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11057 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11058 bool json_detail = json_detail_header;
11059
11060 pi = bgp_dest_get_bgp_path_info(dest);
11061 if (pi == NULL)
11062 continue;
11063
11064 display = 0;
11065 if (use_json)
11066 json_paths = json_object_new_array();
11067 else
11068 json_paths = NULL;
11069
11070 for (; pi; pi = pi->next) {
11071 struct community *picomm = NULL;
11072
11073 picomm = bgp_attr_get_community(pi->attr);
11074
11075 total_count++;
11076
11077 if (type == bgp_show_type_prefix_version) {
11078 uint32_t version =
11079 strtoul(output_arg, NULL, 10);
11080 if (dest->version < version)
11081 continue;
11082 }
11083
11084 if (type == bgp_show_type_community_alias) {
11085 char *alias = output_arg;
11086 char **communities;
11087 int num;
11088 bool found = false;
11089
11090 if (picomm) {
11091 frrstr_split(picomm->str, " ",
11092 &communities, &num);
11093 for (int i = 0; i < num; i++) {
11094 const char *com2alias =
11095 bgp_community2alias(
11096 communities[i]);
11097 if (!found
11098 && strcmp(alias, com2alias)
11099 == 0)
11100 found = true;
11101 XFREE(MTYPE_TMP,
11102 communities[i]);
11103 }
11104 XFREE(MTYPE_TMP, communities);
11105 }
11106
11107 if (!found &&
11108 bgp_attr_get_lcommunity(pi->attr)) {
11109 frrstr_split(bgp_attr_get_lcommunity(
11110 pi->attr)
11111 ->str,
11112 " ", &communities, &num);
11113 for (int i = 0; i < num; i++) {
11114 const char *com2alias =
11115 bgp_community2alias(
11116 communities[i]);
11117 if (!found
11118 && strcmp(alias, com2alias)
11119 == 0)
11120 found = true;
11121 XFREE(MTYPE_TMP,
11122 communities[i]);
11123 }
11124 XFREE(MTYPE_TMP, communities);
11125 }
11126
11127 if (!found)
11128 continue;
11129 }
11130
11131 if (type == bgp_show_type_rpki) {
11132 if (dest_p->family == AF_INET
11133 || dest_p->family == AF_INET6)
11134 rpki_curr_state = hook_call(
11135 bgp_rpki_prefix_status,
11136 pi->peer, pi->attr, dest_p);
11137 if (rpki_target_state != RPKI_NOT_BEING_USED
11138 && rpki_curr_state != rpki_target_state)
11139 continue;
11140 }
11141
11142 if (type == bgp_show_type_flap_statistics
11143 || type == bgp_show_type_flap_neighbor
11144 || type == bgp_show_type_dampend_paths
11145 || type == bgp_show_type_damp_neighbor) {
11146 if (!(pi->extra && pi->extra->damp_info))
11147 continue;
11148 }
11149 if (type == bgp_show_type_regexp) {
11150 regex_t *regex = output_arg;
11151
11152 if (bgp_regexec(regex, pi->attr->aspath)
11153 == REG_NOMATCH)
11154 continue;
11155 }
11156 if (type == bgp_show_type_prefix_list) {
11157 struct prefix_list *plist = output_arg;
11158
11159 if (prefix_list_apply(plist, dest_p)
11160 != PREFIX_PERMIT)
11161 continue;
11162 }
11163 if (type == bgp_show_type_access_list) {
11164 struct access_list *alist = output_arg;
11165
11166 if (access_list_apply(alist, dest_p) !=
11167 FILTER_PERMIT)
11168 continue;
11169 }
11170 if (type == bgp_show_type_filter_list) {
11171 struct as_list *as_list = output_arg;
11172
11173 if (as_list_apply(as_list, pi->attr->aspath)
11174 != AS_FILTER_PERMIT)
11175 continue;
11176 }
11177 if (type == bgp_show_type_route_map) {
11178 struct route_map *rmap = output_arg;
11179 struct bgp_path_info path;
11180 struct bgp_path_info_extra extra;
11181 struct attr dummy_attr = {};
11182 route_map_result_t ret;
11183
11184 dummy_attr = *pi->attr;
11185
11186 prep_for_rmap_apply(&path, &extra, dest, pi,
11187 pi->peer, &dummy_attr);
11188
11189 ret = route_map_apply(rmap, dest_p, &path);
11190 bgp_attr_flush(&dummy_attr);
11191 if (ret == RMAP_DENYMATCH)
11192 continue;
11193 }
11194 if (type == bgp_show_type_neighbor
11195 || type == bgp_show_type_flap_neighbor
11196 || type == bgp_show_type_damp_neighbor) {
11197 union sockunion *su = output_arg;
11198
11199 if (pi->peer == NULL
11200 || pi->peer->su_remote == NULL
11201 || !sockunion_same(pi->peer->su_remote, su))
11202 continue;
11203 }
11204 if (type == bgp_show_type_cidr_only) {
11205 uint32_t destination;
11206
11207 destination = ntohl(dest_p->u.prefix4.s_addr);
11208 if (IN_CLASSC(destination)
11209 && dest_p->prefixlen == 24)
11210 continue;
11211 if (IN_CLASSB(destination)
11212 && dest_p->prefixlen == 16)
11213 continue;
11214 if (IN_CLASSA(destination)
11215 && dest_p->prefixlen == 8)
11216 continue;
11217 }
11218 if (type == bgp_show_type_prefix_longer) {
11219 p = output_arg;
11220 if (!prefix_match(p, dest_p))
11221 continue;
11222 }
11223 if (type == bgp_show_type_community_all) {
11224 if (!picomm)
11225 continue;
11226 }
11227 if (type == bgp_show_type_community) {
11228 struct community *com = output_arg;
11229
11230 if (!picomm || !community_match(picomm, com))
11231 continue;
11232 }
11233 if (type == bgp_show_type_community_exact) {
11234 struct community *com = output_arg;
11235
11236 if (!picomm || !community_cmp(picomm, com))
11237 continue;
11238 }
11239 if (type == bgp_show_type_community_list) {
11240 struct community_list *list = output_arg;
11241
11242 if (!community_list_match(picomm, list))
11243 continue;
11244 }
11245 if (type == bgp_show_type_community_list_exact) {
11246 struct community_list *list = output_arg;
11247
11248 if (!community_list_exact_match(picomm, list))
11249 continue;
11250 }
11251 if (type == bgp_show_type_lcommunity) {
11252 struct lcommunity *lcom = output_arg;
11253
11254 if (!bgp_attr_get_lcommunity(pi->attr) ||
11255 !lcommunity_match(
11256 bgp_attr_get_lcommunity(pi->attr),
11257 lcom))
11258 continue;
11259 }
11260
11261 if (type == bgp_show_type_lcommunity_exact) {
11262 struct lcommunity *lcom = output_arg;
11263
11264 if (!bgp_attr_get_lcommunity(pi->attr) ||
11265 !lcommunity_cmp(
11266 bgp_attr_get_lcommunity(pi->attr),
11267 lcom))
11268 continue;
11269 }
11270 if (type == bgp_show_type_lcommunity_list) {
11271 struct community_list *list = output_arg;
11272
11273 if (!lcommunity_list_match(
11274 bgp_attr_get_lcommunity(pi->attr),
11275 list))
11276 continue;
11277 }
11278 if (type
11279 == bgp_show_type_lcommunity_list_exact) {
11280 struct community_list *list = output_arg;
11281
11282 if (!lcommunity_list_exact_match(
11283 bgp_attr_get_lcommunity(pi->attr),
11284 list))
11285 continue;
11286 }
11287 if (type == bgp_show_type_lcommunity_all) {
11288 if (!bgp_attr_get_lcommunity(pi->attr))
11289 continue;
11290 }
11291 if (type == bgp_show_type_dampend_paths
11292 || type == bgp_show_type_damp_neighbor) {
11293 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11294 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11295 continue;
11296 }
11297
11298 if (!use_json && header) {
11299 vty_out(vty,
11300 "BGP table version is %" PRIu64
11301 ", local router ID is %pI4, vrf id ",
11302 table->version, &bgp->router_id);
11303 if (bgp->vrf_id == VRF_UNKNOWN)
11304 vty_out(vty, "%s", VRFID_NONE_STR);
11305 else
11306 vty_out(vty, "%u", bgp->vrf_id);
11307 vty_out(vty, "\n");
11308 vty_out(vty, "Default local pref %u, ",
11309 bgp->default_local_pref);
11310 vty_out(vty, "local AS %u\n", bgp->as);
11311 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11312 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11313 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11314 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11315 if (type == bgp_show_type_dampend_paths
11316 || type == bgp_show_type_damp_neighbor)
11317 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11318 else if (type == bgp_show_type_flap_statistics
11319 || type == bgp_show_type_flap_neighbor)
11320 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11321 else
11322 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11323 : BGP_SHOW_HEADER));
11324 header = false;
11325
11326 } else if (json_detail && json_paths != NULL) {
11327 const struct prefix_rd *prd;
11328 json_object *jtemp;
11329
11330 /* Use common detail header, for most types;
11331 * need a json 'object'.
11332 */
11333
11334 jtemp = json_object_new_object();
11335 prd = bgp_rd_from_dest(dest, safi);
11336
11337 route_vty_out_detail_header(
11338 vty, bgp, dest, prd, table->afi,
11339 safi, jtemp);
11340
11341 json_object_array_add(json_paths, jtemp);
11342
11343 json_detail = false;
11344 }
11345
11346 if (rd != NULL && !display && !output_count) {
11347 if (!use_json)
11348 vty_out(vty,
11349 "Route Distinguisher: %s\n",
11350 rd);
11351 }
11352 if (type == bgp_show_type_dampend_paths
11353 || type == bgp_show_type_damp_neighbor)
11354 damp_route_vty_out(vty, dest_p, pi, display,
11355 AFI_IP, safi, use_json,
11356 json_paths);
11357 else if (type == bgp_show_type_flap_statistics
11358 || type == bgp_show_type_flap_neighbor)
11359 flap_route_vty_out(vty, dest_p, pi, display,
11360 AFI_IP, safi, use_json,
11361 json_paths);
11362 else {
11363 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11364 route_vty_out_detail(
11365 vty, bgp, dest, pi,
11366 family2afi(dest_p->family),
11367 safi, RPKI_NOT_BEING_USED,
11368 json_paths);
11369 else
11370 route_vty_out(vty, dest_p, pi, display,
11371 safi, json_paths, wide);
11372 }
11373 display++;
11374 }
11375
11376 if (display) {
11377 output_count++;
11378 if (!use_json)
11379 continue;
11380
11381 /* encode prefix */
11382 if (dest_p->family == AF_FLOWSPEC) {
11383 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11384
11385
11386 bgp_fs_nlri_get_string(
11387 (unsigned char *)
11388 dest_p->u.prefix_flowspec.ptr,
11389 dest_p->u.prefix_flowspec.prefixlen,
11390 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11391 family2afi(dest_p->u
11392 .prefix_flowspec.family));
11393 if (first)
11394 vty_out(vty, "\"%s/%d\": ", retstr,
11395 dest_p->u.prefix_flowspec
11396 .prefixlen);
11397 else
11398 vty_out(vty, ",\"%s/%d\": ", retstr,
11399 dest_p->u.prefix_flowspec
11400 .prefixlen);
11401 } else {
11402 if (first)
11403 vty_out(vty, "\"%pFX\": ", dest_p);
11404 else
11405 vty_out(vty, ",\"%pFX\": ", dest_p);
11406 }
11407 vty_json(vty, json_paths);
11408 json_paths = NULL;
11409 first = 0;
11410 } else
11411 json_object_free(json_paths);
11412 }
11413
11414 if (output_cum) {
11415 output_count += *output_cum;
11416 *output_cum = output_count;
11417 }
11418 if (total_cum) {
11419 total_count += *total_cum;
11420 *total_cum = total_count;
11421 }
11422 if (use_json) {
11423 if (rd) {
11424 vty_out(vty, " }%s ", (is_last ? "" : ","));
11425 }
11426 if (is_last) {
11427 unsigned long i;
11428 for (i = 0; i < *json_header_depth; ++i)
11429 vty_out(vty, " } ");
11430 if (!all)
11431 vty_out(vty, "\n");
11432 }
11433 } else {
11434 if (is_last) {
11435 /* No route is displayed */
11436 if (output_count == 0) {
11437 if (type == bgp_show_type_normal)
11438 vty_out(vty,
11439 "No BGP prefixes displayed, %ld exist\n",
11440 total_count);
11441 } else
11442 vty_out(vty,
11443 "\nDisplayed %ld routes and %ld total paths\n",
11444 output_count, total_count);
11445 }
11446 }
11447
11448 return CMD_SUCCESS;
11449 }
11450
11451 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11452 struct bgp_table *table, struct prefix_rd *prd_match,
11453 enum bgp_show_type type, void *output_arg, bool use_json)
11454 {
11455 struct bgp_dest *dest, *next;
11456 unsigned long output_cum = 0;
11457 unsigned long total_cum = 0;
11458 unsigned long json_header_depth = 0;
11459 struct bgp_table *itable;
11460 bool show_msg;
11461 uint16_t show_flags = 0;
11462
11463 show_msg = (!use_json && type == bgp_show_type_normal);
11464
11465 if (use_json)
11466 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11467
11468 for (dest = bgp_table_top(table); dest; dest = next) {
11469 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11470
11471 next = bgp_route_next(dest);
11472 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11473 continue;
11474
11475 itable = bgp_dest_get_bgp_table_info(dest);
11476 if (itable != NULL) {
11477 struct prefix_rd prd;
11478 char rd[RD_ADDRSTRLEN];
11479
11480 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11481 prefix_rd2str(&prd, rd, sizeof(rd));
11482 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11483 rd, next == NULL, &output_cum,
11484 &total_cum, &json_header_depth,
11485 show_flags, RPKI_NOT_BEING_USED);
11486 if (next == NULL)
11487 show_msg = false;
11488 }
11489 }
11490 if (show_msg) {
11491 if (output_cum == 0)
11492 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11493 total_cum);
11494 else
11495 vty_out(vty,
11496 "\nDisplayed %ld routes and %ld total paths\n",
11497 output_cum, total_cum);
11498 }
11499 return CMD_SUCCESS;
11500 }
11501
11502 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11503 enum bgp_show_type type, void *output_arg,
11504 uint16_t show_flags, enum rpki_states rpki_target_state)
11505 {
11506 struct bgp_table *table;
11507 unsigned long json_header_depth = 0;
11508 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11509
11510 if (bgp == NULL) {
11511 bgp = bgp_get_default();
11512 }
11513
11514 if (bgp == NULL) {
11515 if (!use_json)
11516 vty_out(vty, "No BGP process is configured\n");
11517 else
11518 vty_out(vty, "{}\n");
11519 return CMD_WARNING;
11520 }
11521
11522 /* Labeled-unicast routes live in the unicast table. */
11523 if (safi == SAFI_LABELED_UNICAST)
11524 safi = SAFI_UNICAST;
11525
11526 table = bgp->rib[afi][safi];
11527 /* use MPLS and ENCAP specific shows until they are merged */
11528 if (safi == SAFI_MPLS_VPN) {
11529 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11530 output_arg, use_json);
11531 }
11532
11533 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11534 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11535 output_arg, use_json,
11536 1, NULL, NULL);
11537 }
11538
11539 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11540 NULL, NULL, &json_header_depth, show_flags,
11541 rpki_target_state);
11542 }
11543
11544 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11545 safi_t safi, uint16_t show_flags)
11546 {
11547 struct listnode *node, *nnode;
11548 struct bgp *bgp;
11549 int is_first = 1;
11550 bool route_output = false;
11551 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11552
11553 if (use_json)
11554 vty_out(vty, "{\n");
11555
11556 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11557 route_output = true;
11558 if (use_json) {
11559 if (!is_first)
11560 vty_out(vty, ",\n");
11561 else
11562 is_first = 0;
11563
11564 vty_out(vty, "\"%s\":",
11565 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11566 ? VRF_DEFAULT_NAME
11567 : bgp->name);
11568 } else {
11569 vty_out(vty, "\nInstance %s:\n",
11570 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11571 ? VRF_DEFAULT_NAME
11572 : bgp->name);
11573 }
11574 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11575 show_flags, RPKI_NOT_BEING_USED);
11576 }
11577
11578 if (use_json)
11579 vty_out(vty, "}\n");
11580 else if (!route_output)
11581 vty_out(vty, "%% BGP instance not found\n");
11582 }
11583
11584 /* Header of detailed BGP route information */
11585 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11586 struct bgp_dest *dest,
11587 const struct prefix_rd *prd,
11588 afi_t afi, safi_t safi, json_object *json)
11589 {
11590 struct bgp_path_info *pi;
11591 const struct prefix *p;
11592 struct peer *peer;
11593 struct listnode *node, *nnode;
11594 char buf1[RD_ADDRSTRLEN];
11595 int count = 0;
11596 int best = 0;
11597 int suppress = 0;
11598 int accept_own = 0;
11599 int route_filter_translated_v4 = 0;
11600 int route_filter_v4 = 0;
11601 int route_filter_translated_v6 = 0;
11602 int route_filter_v6 = 0;
11603 int llgr_stale = 0;
11604 int no_llgr = 0;
11605 int accept_own_nexthop = 0;
11606 int blackhole = 0;
11607 int no_export = 0;
11608 int no_advertise = 0;
11609 int local_as = 0;
11610 int no_peer = 0;
11611 int first = 1;
11612 int has_valid_label = 0;
11613 mpls_label_t label = 0;
11614 json_object *json_adv_to = NULL;
11615 uint32_t ttl = 0;
11616 uint32_t bos = 0;
11617 uint32_t exp = 0;
11618
11619 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11620
11621 p = bgp_dest_get_prefix(dest);
11622 has_valid_label = bgp_is_valid_label(&label);
11623
11624 if (safi == SAFI_EVPN) {
11625 if (!json) {
11626 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11627 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11628 : "",
11629 prd ? ":" : "", (struct prefix_evpn *)p);
11630 } else {
11631 json_object_string_add(json, "rd",
11632 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11633 "");
11634 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11635 }
11636 } else {
11637 if (!json) {
11638 vty_out(vty,
11639 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11640 "\n",
11641 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11642 ? prefix_rd2str(prd, buf1,
11643 sizeof(buf1))
11644 : ""),
11645 safi == SAFI_MPLS_VPN ? ":" : "", p,
11646 dest->version);
11647
11648 } else {
11649 json_object_string_addf(json, "prefix", "%pFX", p);
11650 json_object_int_add(json, "version", dest->version);
11651
11652 }
11653 }
11654
11655 if (has_valid_label) {
11656 if (json)
11657 json_object_int_add(json, "localLabel", label);
11658 else
11659 vty_out(vty, "Local label: %d\n", label);
11660 }
11661
11662 if (!json)
11663 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11664 vty_out(vty, "not allocated\n");
11665
11666 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11667 struct community *picomm = NULL;
11668
11669 picomm = bgp_attr_get_community(pi->attr);
11670
11671 count++;
11672 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11673 best = count;
11674 if (bgp_path_suppressed(pi))
11675 suppress = 1;
11676
11677 if (!picomm)
11678 continue;
11679
11680 no_advertise += community_include(
11681 picomm, COMMUNITY_NO_ADVERTISE);
11682 no_export +=
11683 community_include(picomm, COMMUNITY_NO_EXPORT);
11684 local_as +=
11685 community_include(picomm, COMMUNITY_LOCAL_AS);
11686 accept_own +=
11687 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11688 route_filter_translated_v4 += community_include(
11689 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11690 route_filter_translated_v6 += community_include(
11691 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11692 route_filter_v4 += community_include(
11693 picomm, COMMUNITY_ROUTE_FILTER_v4);
11694 route_filter_v6 += community_include(
11695 picomm, COMMUNITY_ROUTE_FILTER_v6);
11696 llgr_stale +=
11697 community_include(picomm, COMMUNITY_LLGR_STALE);
11698 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11699 accept_own_nexthop += community_include(
11700 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11701 blackhole +=
11702 community_include(picomm, COMMUNITY_BLACKHOLE);
11703 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11704 }
11705 }
11706
11707 if (!json) {
11708 vty_out(vty, "Paths: (%d available", count);
11709 if (best) {
11710 vty_out(vty, ", best #%d", best);
11711 if (safi == SAFI_UNICAST) {
11712 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11713 vty_out(vty, ", table %s",
11714 VRF_DEFAULT_NAME);
11715 else
11716 vty_out(vty, ", vrf %s",
11717 bgp->name);
11718 }
11719 } else
11720 vty_out(vty, ", no best path");
11721
11722 if (accept_own)
11723 vty_out(vty,
11724 ", accept own local route exported and imported in different VRF");
11725 else if (route_filter_translated_v4)
11726 vty_out(vty,
11727 ", mark translated RTs for VPNv4 route filtering");
11728 else if (route_filter_v4)
11729 vty_out(vty,
11730 ", attach RT as-is for VPNv4 route filtering");
11731 else if (route_filter_translated_v6)
11732 vty_out(vty,
11733 ", mark translated RTs for VPNv6 route filtering");
11734 else if (route_filter_v6)
11735 vty_out(vty,
11736 ", attach RT as-is for VPNv6 route filtering");
11737 else if (llgr_stale)
11738 vty_out(vty,
11739 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11740 else if (no_llgr)
11741 vty_out(vty,
11742 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11743 else if (accept_own_nexthop)
11744 vty_out(vty,
11745 ", accept local nexthop");
11746 else if (blackhole)
11747 vty_out(vty, ", inform peer to blackhole prefix");
11748 else if (no_export)
11749 vty_out(vty, ", not advertised to EBGP peer");
11750 else if (no_advertise)
11751 vty_out(vty, ", not advertised to any peer");
11752 else if (local_as)
11753 vty_out(vty, ", not advertised outside local AS");
11754 else if (no_peer)
11755 vty_out(vty,
11756 ", inform EBGP peer not to advertise to their EBGP peers");
11757
11758 if (suppress)
11759 vty_out(vty,
11760 ", Advertisements suppressed by an aggregate.");
11761 vty_out(vty, ")\n");
11762 }
11763
11764 /* If we are not using addpath then we can display Advertised to and
11765 * that will
11766 * show what peers we advertised the bestpath to. If we are using
11767 * addpath
11768 * though then we must display Advertised to on a path-by-path basis. */
11769 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11770 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11771 if (bgp_adj_out_lookup(peer, dest, 0)) {
11772 if (json && !json_adv_to)
11773 json_adv_to = json_object_new_object();
11774
11775 route_vty_out_advertised_to(
11776 vty, peer, &first,
11777 " Advertised to non peer-group peers:\n ",
11778 json_adv_to);
11779 }
11780 }
11781
11782 if (json) {
11783 if (json_adv_to) {
11784 json_object_object_add(json, "advertisedTo",
11785 json_adv_to);
11786 }
11787 } else {
11788 if (first)
11789 vty_out(vty, " Not advertised to any peer");
11790 vty_out(vty, "\n");
11791 }
11792 }
11793 }
11794
11795 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11796 struct bgp_dest *bgp_node, struct vty *vty,
11797 struct bgp *bgp, afi_t afi, safi_t safi,
11798 json_object *json, enum bgp_path_type pathtype,
11799 int *display, enum rpki_states rpki_target_state)
11800 {
11801 struct bgp_path_info *pi;
11802 int header = 1;
11803 char rdbuf[RD_ADDRSTRLEN];
11804 json_object *json_header = NULL;
11805 json_object *json_paths = NULL;
11806 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11807
11808 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11809 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11810
11811 if (p->family == AF_INET || p->family == AF_INET6)
11812 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11813 pi->peer, pi->attr, p);
11814
11815 if (rpki_target_state != RPKI_NOT_BEING_USED
11816 && rpki_curr_state != rpki_target_state)
11817 continue;
11818
11819 if (json && !json_paths) {
11820 /* Instantiate json_paths only if path is valid */
11821 json_paths = json_object_new_array();
11822 if (pfx_rd) {
11823 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11824 json_header = json_object_new_object();
11825 } else
11826 json_header = json;
11827 }
11828
11829 if (header) {
11830 route_vty_out_detail_header(
11831 vty, bgp, bgp_node, pfx_rd,
11832 AFI_IP, safi, json_header);
11833 header = 0;
11834 }
11835 (*display)++;
11836
11837 if (pathtype == BGP_PATH_SHOW_ALL
11838 || (pathtype == BGP_PATH_SHOW_BESTPATH
11839 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11840 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11841 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11842 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11843 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
11844 safi, rpki_curr_state, json_paths);
11845 }
11846
11847 if (json && json_paths) {
11848 json_object_object_add(json_header, "paths", json_paths);
11849
11850 if (pfx_rd)
11851 json_object_object_add(json, rdbuf, json_header);
11852 }
11853 }
11854
11855 /*
11856 * Return rd based on safi
11857 */
11858 static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
11859 safi_t safi)
11860 {
11861 switch (safi) {
11862 case SAFI_MPLS_VPN:
11863 case SAFI_ENCAP:
11864 case SAFI_EVPN:
11865 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
11866 default:
11867 return NULL;
11868
11869 }
11870 }
11871
11872 /* Display specified route of BGP table. */
11873 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11874 struct bgp_table *rib, const char *ip_str,
11875 afi_t afi, safi_t safi,
11876 enum rpki_states rpki_target_state,
11877 struct prefix_rd *prd, int prefix_check,
11878 enum bgp_path_type pathtype, bool use_json)
11879 {
11880 int ret;
11881 int display = 0;
11882 struct prefix match;
11883 struct bgp_dest *dest;
11884 struct bgp_dest *rm;
11885 struct bgp_table *table;
11886 json_object *json = NULL;
11887 json_object *json_paths = NULL;
11888
11889 /* Check IP address argument. */
11890 ret = str2prefix(ip_str, &match);
11891 if (!ret) {
11892 vty_out(vty, "address is malformed\n");
11893 return CMD_WARNING;
11894 }
11895
11896 match.family = afi2family(afi);
11897
11898 if (use_json)
11899 json = json_object_new_object();
11900
11901 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11902 for (dest = bgp_table_top(rib); dest;
11903 dest = bgp_route_next(dest)) {
11904 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11905
11906 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11907 continue;
11908 table = bgp_dest_get_bgp_table_info(dest);
11909 if (!table)
11910 continue;
11911
11912 rm = bgp_node_match(table, &match);
11913 if (rm == NULL)
11914 continue;
11915
11916 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11917 if (prefix_check
11918 && rm_p->prefixlen != match.prefixlen) {
11919 bgp_dest_unlock_node(rm);
11920 continue;
11921 }
11922
11923 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11924 bgp, afi, safi, json, pathtype,
11925 &display, rpki_target_state);
11926
11927 bgp_dest_unlock_node(rm);
11928 }
11929 } else if (safi == SAFI_EVPN) {
11930 struct bgp_dest *longest_pfx;
11931 bool is_exact_pfxlen_match = false;
11932
11933 for (dest = bgp_table_top(rib); dest;
11934 dest = bgp_route_next(dest)) {
11935 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11936
11937 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11938 continue;
11939 table = bgp_dest_get_bgp_table_info(dest);
11940 if (!table)
11941 continue;
11942
11943 longest_pfx = NULL;
11944 is_exact_pfxlen_match = false;
11945 /*
11946 * Search through all the prefixes for a match. The
11947 * pfx's are enumerated in ascending order of pfxlens.
11948 * So, the last pfx match is the longest match. Set
11949 * is_exact_pfxlen_match when we get exact pfxlen match
11950 */
11951 for (rm = bgp_table_top(table); rm;
11952 rm = bgp_route_next(rm)) {
11953 const struct prefix *rm_p =
11954 bgp_dest_get_prefix(rm);
11955 /*
11956 * Get prefixlen of the ip-prefix within type5
11957 * evpn route
11958 */
11959 if (evpn_type5_prefix_match(rm_p, &match)
11960 && rm->info) {
11961 longest_pfx = rm;
11962 int type5_pfxlen =
11963 bgp_evpn_get_type5_prefixlen(
11964 rm_p);
11965 if (type5_pfxlen == match.prefixlen) {
11966 is_exact_pfxlen_match = true;
11967 bgp_dest_unlock_node(rm);
11968 break;
11969 }
11970 }
11971 }
11972
11973 if (!longest_pfx)
11974 continue;
11975
11976 if (prefix_check && !is_exact_pfxlen_match)
11977 continue;
11978
11979 rm = longest_pfx;
11980 bgp_dest_lock_node(rm);
11981
11982 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11983 bgp, afi, safi, json, pathtype,
11984 &display, rpki_target_state);
11985
11986 bgp_dest_unlock_node(rm);
11987 }
11988 } else if (safi == SAFI_FLOWSPEC) {
11989 if (use_json)
11990 json_paths = json_object_new_array();
11991
11992 display = bgp_flowspec_display_match_per_ip(afi, rib,
11993 &match, prefix_check,
11994 vty,
11995 use_json,
11996 json_paths);
11997 if (use_json) {
11998 if (display)
11999 json_object_object_add(json, "paths",
12000 json_paths);
12001 else
12002 json_object_free(json_paths);
12003 }
12004 } else {
12005 dest = bgp_node_match(rib, &match);
12006 if (dest != NULL) {
12007 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12008 if (!prefix_check
12009 || dest_p->prefixlen == match.prefixlen) {
12010 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12011 safi, json, pathtype,
12012 &display, rpki_target_state);
12013 }
12014
12015 bgp_dest_unlock_node(dest);
12016 }
12017 }
12018
12019 if (use_json) {
12020 vty_json(vty, json);
12021 } else {
12022 if (!display) {
12023 vty_out(vty, "%% Network not in table\n");
12024 return CMD_WARNING;
12025 }
12026 }
12027
12028 return CMD_SUCCESS;
12029 }
12030
12031 /* Display specified route of Main RIB */
12032 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12033 afi_t afi, safi_t safi, struct prefix_rd *prd,
12034 int prefix_check, enum bgp_path_type pathtype,
12035 enum rpki_states rpki_target_state, bool use_json)
12036 {
12037 if (!bgp) {
12038 bgp = bgp_get_default();
12039 if (!bgp) {
12040 if (!use_json)
12041 vty_out(vty, "No BGP process is configured\n");
12042 else
12043 vty_out(vty, "{}\n");
12044 return CMD_WARNING;
12045 }
12046 }
12047
12048 /* labeled-unicast routes live in the unicast table */
12049 if (safi == SAFI_LABELED_UNICAST)
12050 safi = SAFI_UNICAST;
12051
12052 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12053 afi, safi, rpki_target_state, prd,
12054 prefix_check, pathtype, use_json);
12055 }
12056
12057 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12058 struct cmd_token **argv, bool exact, afi_t afi,
12059 safi_t safi, bool uj)
12060 {
12061 struct lcommunity *lcom;
12062 struct buffer *b;
12063 int i;
12064 char *str;
12065 int first = 0;
12066 uint16_t show_flags = 0;
12067 int ret;
12068
12069 if (uj)
12070 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12071
12072 b = buffer_new(1024);
12073 for (i = 0; i < argc; i++) {
12074 if (first)
12075 buffer_putc(b, ' ');
12076 else {
12077 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12078 first = 1;
12079 buffer_putstr(b, argv[i]->arg);
12080 }
12081 }
12082 }
12083 buffer_putc(b, '\0');
12084
12085 str = buffer_getstr(b);
12086 buffer_free(b);
12087
12088 lcom = lcommunity_str2com(str);
12089 XFREE(MTYPE_TMP, str);
12090 if (!lcom) {
12091 vty_out(vty, "%% Large-community malformed\n");
12092 return CMD_WARNING;
12093 }
12094
12095 ret = bgp_show(vty, bgp, afi, safi,
12096 (exact ? bgp_show_type_lcommunity_exact
12097 : bgp_show_type_lcommunity),
12098 lcom, show_flags, RPKI_NOT_BEING_USED);
12099
12100 lcommunity_free(&lcom);
12101 return ret;
12102 }
12103
12104 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12105 const char *lcom, bool exact, afi_t afi,
12106 safi_t safi, bool uj)
12107 {
12108 struct community_list *list;
12109 uint16_t show_flags = 0;
12110
12111 if (uj)
12112 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12113
12114
12115 list = community_list_lookup(bgp_clist, lcom, 0,
12116 LARGE_COMMUNITY_LIST_MASTER);
12117 if (list == NULL) {
12118 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12119 lcom);
12120 return CMD_WARNING;
12121 }
12122
12123 return bgp_show(vty, bgp, afi, safi,
12124 (exact ? bgp_show_type_lcommunity_list_exact
12125 : bgp_show_type_lcommunity_list),
12126 list, show_flags, RPKI_NOT_BEING_USED);
12127 }
12128
12129 DEFUN (show_ip_bgp_large_community_list,
12130 show_ip_bgp_large_community_list_cmd,
12131 "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]",
12132 SHOW_STR
12133 IP_STR
12134 BGP_STR
12135 BGP_INSTANCE_HELP_STR
12136 BGP_AFI_HELP_STR
12137 BGP_SAFI_WITH_LABEL_HELP_STR
12138 "Display routes matching the large-community-list\n"
12139 "large-community-list number\n"
12140 "large-community-list name\n"
12141 "Exact match of the large-communities\n"
12142 JSON_STR)
12143 {
12144 afi_t afi = AFI_IP6;
12145 safi_t safi = SAFI_UNICAST;
12146 int idx = 0;
12147 bool exact_match = 0;
12148 struct bgp *bgp = NULL;
12149 bool uj = use_json(argc, argv);
12150
12151 if (uj)
12152 argc--;
12153
12154 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12155 &bgp, uj);
12156 if (!idx)
12157 return CMD_WARNING;
12158
12159 argv_find(argv, argc, "large-community-list", &idx);
12160
12161 const char *clist_number_or_name = argv[++idx]->arg;
12162
12163 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12164 exact_match = 1;
12165
12166 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12167 exact_match, afi, safi, uj);
12168 }
12169 DEFUN (show_ip_bgp_large_community,
12170 show_ip_bgp_large_community_cmd,
12171 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12172 SHOW_STR
12173 IP_STR
12174 BGP_STR
12175 BGP_INSTANCE_HELP_STR
12176 BGP_AFI_HELP_STR
12177 BGP_SAFI_WITH_LABEL_HELP_STR
12178 "Display routes matching the large-communities\n"
12179 "List of large-community numbers\n"
12180 "Exact match of the large-communities\n"
12181 JSON_STR)
12182 {
12183 afi_t afi = AFI_IP6;
12184 safi_t safi = SAFI_UNICAST;
12185 int idx = 0;
12186 bool exact_match = 0;
12187 struct bgp *bgp = NULL;
12188 bool uj = use_json(argc, argv);
12189 uint16_t show_flags = 0;
12190
12191 if (uj) {
12192 argc--;
12193 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12194 }
12195
12196 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12197 &bgp, uj);
12198 if (!idx)
12199 return CMD_WARNING;
12200
12201 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12202 if (argv_find(argv, argc, "exact-match", &idx))
12203 exact_match = 1;
12204 return bgp_show_lcommunity(vty, bgp, argc, argv,
12205 exact_match, afi, safi, uj);
12206 } else
12207 return bgp_show(vty, bgp, afi, safi,
12208 bgp_show_type_lcommunity_all, NULL, show_flags,
12209 RPKI_NOT_BEING_USED);
12210 }
12211
12212 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12213 safi_t safi, struct json_object *json_array);
12214 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12215 safi_t safi, struct json_object *json);
12216
12217
12218 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12219 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12220 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12221 "Display number of prefixes for all afi/safi\n" JSON_STR)
12222 {
12223 bool uj = use_json(argc, argv);
12224 struct bgp *bgp = NULL;
12225 safi_t safi = SAFI_UNICAST;
12226 afi_t afi = AFI_IP6;
12227 int idx = 0;
12228 struct json_object *json_all = NULL;
12229 struct json_object *json_afi_safi = NULL;
12230
12231 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12232 &bgp, false);
12233 if (!idx)
12234 return CMD_WARNING;
12235
12236 if (uj)
12237 json_all = json_object_new_object();
12238
12239 FOREACH_AFI_SAFI (afi, safi) {
12240 /*
12241 * So limit output to those afi/safi pairs that
12242 * actually have something interesting in them
12243 */
12244 if (strmatch(get_afi_safi_str(afi, safi, true),
12245 "Unknown")) {
12246 continue;
12247 }
12248 if (uj) {
12249 json_afi_safi = json_object_new_array();
12250 json_object_object_add(
12251 json_all,
12252 get_afi_safi_str(afi, safi, true),
12253 json_afi_safi);
12254 } else {
12255 json_afi_safi = NULL;
12256 }
12257
12258 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12259 }
12260
12261 if (uj)
12262 vty_json(vty, json_all);
12263
12264 return CMD_SUCCESS;
12265 }
12266
12267 /* BGP route print out function without JSON */
12268 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12269 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12270 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12271 SHOW_STR
12272 IP_STR
12273 BGP_STR
12274 BGP_INSTANCE_HELP_STR
12275 L2VPN_HELP_STR
12276 EVPN_HELP_STR
12277 "BGP RIB advertisement statistics\n"
12278 JSON_STR)
12279 {
12280 afi_t afi = AFI_IP6;
12281 safi_t safi = SAFI_UNICAST;
12282 struct bgp *bgp = NULL;
12283 int idx = 0, ret;
12284 bool uj = use_json(argc, argv);
12285 struct json_object *json_afi_safi = NULL, *json = NULL;
12286
12287 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12288 &bgp, false);
12289 if (!idx)
12290 return CMD_WARNING;
12291
12292 if (uj)
12293 json_afi_safi = json_object_new_array();
12294 else
12295 json_afi_safi = NULL;
12296
12297 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12298
12299 if (uj) {
12300 json = json_object_new_object();
12301 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12302 json_afi_safi);
12303 vty_json(vty, json);
12304 }
12305 return ret;
12306 }
12307
12308 /* BGP route print out function without JSON */
12309 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12310 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12311 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12312 "]]\
12313 statistics [json]",
12314 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12315 BGP_SAFI_WITH_LABEL_HELP_STR
12316 "BGP RIB advertisement statistics\n" JSON_STR)
12317 {
12318 afi_t afi = AFI_IP6;
12319 safi_t safi = SAFI_UNICAST;
12320 struct bgp *bgp = NULL;
12321 int idx = 0, ret;
12322 bool uj = use_json(argc, argv);
12323 struct json_object *json_afi_safi = NULL, *json = NULL;
12324
12325 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12326 &bgp, false);
12327 if (!idx)
12328 return CMD_WARNING;
12329
12330 if (uj)
12331 json_afi_safi = json_object_new_array();
12332 else
12333 json_afi_safi = NULL;
12334
12335 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12336
12337 if (uj) {
12338 json = json_object_new_object();
12339 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12340 json_afi_safi);
12341 vty_json(vty, json);
12342 }
12343 return ret;
12344 }
12345
12346 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12347 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12348 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12349 "]] [all$all] dampening parameters [json]",
12350 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12351 BGP_SAFI_WITH_LABEL_HELP_STR
12352 "Display the entries for all address families\n"
12353 "Display detailed information about dampening\n"
12354 "Display detail of configured dampening parameters\n"
12355 JSON_STR)
12356 {
12357 afi_t afi = AFI_IP6;
12358 safi_t safi = SAFI_UNICAST;
12359 struct bgp *bgp = NULL;
12360 int idx = 0;
12361 uint16_t show_flags = 0;
12362 bool uj = use_json(argc, argv);
12363
12364 if (uj) {
12365 argc--;
12366 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12367 }
12368
12369 /* [<ipv4|ipv6> [all]] */
12370 if (all) {
12371 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12372 if (argv_find(argv, argc, "ipv4", &idx))
12373 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12374
12375 if (argv_find(argv, argc, "ipv6", &idx))
12376 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12377 }
12378
12379 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12380 &bgp, false);
12381 if (!idx)
12382 return CMD_WARNING;
12383
12384 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12385 }
12386
12387 /* BGP route print out function */
12388 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12389 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12390 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12391 "]]\
12392 [all$all]\
12393 [cidr-only\
12394 |dampening <flap-statistics|dampened-paths>\
12395 |community [AA:NN|local-AS|no-advertise|no-export\
12396 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12397 |accept-own|accept-own-nexthop|route-filter-v6\
12398 |route-filter-v4|route-filter-translated-v6\
12399 |route-filter-translated-v4] [exact-match]\
12400 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12401 |filter-list AS_PATH_FILTER_NAME\
12402 |prefix-list WORD\
12403 |access-list ACCESSLIST_NAME\
12404 |route-map RMAP_NAME\
12405 |rpki <invalid|valid|notfound>\
12406 |version (1-4294967295)\
12407 |alias ALIAS_NAME\
12408 |A.B.C.D/M longer-prefixes\
12409 |X:X::X:X/M longer-prefixes\
12410 ] [json$uj [detail$detail] | wide$wide]",
12411 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12412 BGP_SAFI_WITH_LABEL_HELP_STR
12413 "Display the entries for all address families\n"
12414 "Display only routes with non-natural netmasks\n"
12415 "Display detailed information about dampening\n"
12416 "Display flap statistics of routes\n"
12417 "Display paths suppressed due to dampening\n"
12418 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12419 "Do not send outside local AS (well-known community)\n"
12420 "Do not advertise to any peer (well-known community)\n"
12421 "Do not export to next AS (well-known community)\n"
12422 "Graceful shutdown (well-known community)\n"
12423 "Do not export to any peer (well-known community)\n"
12424 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12425 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12426 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12427 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12428 "Should accept VPN route with local nexthop (well-known community)\n"
12429 "RT VPNv6 route filtering (well-known community)\n"
12430 "RT VPNv4 route filtering (well-known community)\n"
12431 "RT translated VPNv6 route filtering (well-known community)\n"
12432 "RT translated VPNv4 route filtering (well-known community)\n"
12433 "Exact match of the communities\n"
12434 "Community-list number\n"
12435 "Community-list name\n"
12436 "Display routes matching the community-list\n"
12437 "Exact match of the communities\n"
12438 "Display routes conforming to the filter-list\n"
12439 "Regular expression access list name\n"
12440 "Display routes conforming to the prefix-list\n"
12441 "Prefix-list name\n"
12442 "Display routes conforming to the access-list\n"
12443 "Access-list name\n"
12444 "Display routes matching the route-map\n"
12445 "A route-map to match on\n"
12446 "RPKI route types\n"
12447 "A valid path as determined by rpki\n"
12448 "A invalid path as determined by rpki\n"
12449 "A path that has no rpki data\n"
12450 "Display prefixes with matching version numbers\n"
12451 "Version number and above\n"
12452 "Display prefixes with matching BGP community alias\n"
12453 "BGP community alias\n"
12454 "IPv4 prefix\n"
12455 "Display route and more specific routes\n"
12456 "IPv6 prefix\n"
12457 "Display route and more specific routes\n"
12458 JSON_STR
12459 "Display detailed version of JSON output\n"
12460 "Increase table width for longer prefixes\n")
12461 {
12462 afi_t afi = AFI_IP6;
12463 safi_t safi = SAFI_UNICAST;
12464 enum bgp_show_type sh_type = bgp_show_type_normal;
12465 void *output_arg = NULL;
12466 struct bgp *bgp = NULL;
12467 int idx = 0;
12468 int exact_match = 0;
12469 char *community = NULL;
12470 bool first = true;
12471 uint16_t show_flags = 0;
12472 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12473 struct prefix p;
12474
12475 if (uj) {
12476 argc--;
12477 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12478 }
12479
12480 if (detail)
12481 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12482
12483 /* [<ipv4|ipv6> [all]] */
12484 if (all) {
12485 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12486
12487 if (argv_find(argv, argc, "ipv4", &idx))
12488 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12489
12490 if (argv_find(argv, argc, "ipv6", &idx))
12491 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12492 }
12493
12494 if (wide)
12495 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12496
12497 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12498 &bgp, uj);
12499 if (!idx)
12500 return CMD_WARNING;
12501
12502 if (argv_find(argv, argc, "cidr-only", &idx))
12503 sh_type = bgp_show_type_cidr_only;
12504
12505 if (argv_find(argv, argc, "dampening", &idx)) {
12506 if (argv_find(argv, argc, "dampened-paths", &idx))
12507 sh_type = bgp_show_type_dampend_paths;
12508 else if (argv_find(argv, argc, "flap-statistics", &idx))
12509 sh_type = bgp_show_type_flap_statistics;
12510 }
12511
12512 if (argv_find(argv, argc, "community", &idx)) {
12513 char *maybecomm = NULL;
12514
12515 if (idx + 1 < argc) {
12516 if (argv[idx + 1]->type == VARIABLE_TKN)
12517 maybecomm = argv[idx + 1]->arg;
12518 else
12519 maybecomm = argv[idx + 1]->text;
12520 }
12521
12522 if (maybecomm && !strmatch(maybecomm, "json")
12523 && !strmatch(maybecomm, "exact-match"))
12524 community = maybecomm;
12525
12526 if (argv_find(argv, argc, "exact-match", &idx))
12527 exact_match = 1;
12528
12529 if (!community)
12530 sh_type = bgp_show_type_community_all;
12531 }
12532
12533 if (argv_find(argv, argc, "community-list", &idx)) {
12534 const char *clist_number_or_name = argv[++idx]->arg;
12535 struct community_list *list;
12536
12537 if (argv_find(argv, argc, "exact-match", &idx))
12538 exact_match = 1;
12539
12540 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12541 COMMUNITY_LIST_MASTER);
12542 if (list == NULL) {
12543 vty_out(vty, "%% %s community-list not found\n",
12544 clist_number_or_name);
12545 return CMD_WARNING;
12546 }
12547
12548 if (exact_match)
12549 sh_type = bgp_show_type_community_list_exact;
12550 else
12551 sh_type = bgp_show_type_community_list;
12552 output_arg = list;
12553 }
12554
12555 if (argv_find(argv, argc, "filter-list", &idx)) {
12556 const char *filter = argv[++idx]->arg;
12557 struct as_list *as_list;
12558
12559 as_list = as_list_lookup(filter);
12560 if (as_list == NULL) {
12561 vty_out(vty, "%% %s AS-path access-list not found\n",
12562 filter);
12563 return CMD_WARNING;
12564 }
12565
12566 sh_type = bgp_show_type_filter_list;
12567 output_arg = as_list;
12568 }
12569
12570 if (argv_find(argv, argc, "prefix-list", &idx)) {
12571 const char *prefix_list_str = argv[++idx]->arg;
12572 struct prefix_list *plist;
12573
12574 plist = prefix_list_lookup(afi, prefix_list_str);
12575 if (plist == NULL) {
12576 vty_out(vty, "%% %s prefix-list not found\n",
12577 prefix_list_str);
12578 return CMD_WARNING;
12579 }
12580
12581 sh_type = bgp_show_type_prefix_list;
12582 output_arg = plist;
12583 }
12584
12585 if (argv_find(argv, argc, "access-list", &idx)) {
12586 const char *access_list_str = argv[++idx]->arg;
12587 struct access_list *alist;
12588
12589 alist = access_list_lookup(afi, access_list_str);
12590 if (!alist) {
12591 vty_out(vty, "%% %s access-list not found\n",
12592 access_list_str);
12593 return CMD_WARNING;
12594 }
12595
12596 sh_type = bgp_show_type_access_list;
12597 output_arg = alist;
12598 }
12599
12600 if (argv_find(argv, argc, "route-map", &idx)) {
12601 const char *rmap_str = argv[++idx]->arg;
12602 struct route_map *rmap;
12603
12604 rmap = route_map_lookup_by_name(rmap_str);
12605 if (!rmap) {
12606 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12607 return CMD_WARNING;
12608 }
12609
12610 sh_type = bgp_show_type_route_map;
12611 output_arg = rmap;
12612 }
12613
12614 if (argv_find(argv, argc, "rpki", &idx)) {
12615 sh_type = bgp_show_type_rpki;
12616 if (argv_find(argv, argc, "valid", &idx))
12617 rpki_target_state = RPKI_VALID;
12618 else if (argv_find(argv, argc, "invalid", &idx))
12619 rpki_target_state = RPKI_INVALID;
12620 }
12621
12622 /* Display prefixes with matching version numbers */
12623 if (argv_find(argv, argc, "version", &idx)) {
12624 sh_type = bgp_show_type_prefix_version;
12625 output_arg = argv[idx + 1]->arg;
12626 }
12627
12628 /* Display prefixes with matching BGP community alias */
12629 if (argv_find(argv, argc, "alias", &idx)) {
12630 sh_type = bgp_show_type_community_alias;
12631 output_arg = argv[idx + 1]->arg;
12632 }
12633
12634 /* prefix-longer */
12635 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12636 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12637 const char *prefix_str = argv[idx]->arg;
12638
12639 if (!str2prefix(prefix_str, &p)) {
12640 vty_out(vty, "%% Malformed Prefix\n");
12641 return CMD_WARNING;
12642 }
12643
12644 sh_type = bgp_show_type_prefix_longer;
12645 output_arg = &p;
12646 }
12647
12648 if (!all) {
12649 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12650 if (community)
12651 return bgp_show_community(vty, bgp, community,
12652 exact_match, afi, safi,
12653 show_flags);
12654 else
12655 return bgp_show(vty, bgp, afi, safi, sh_type,
12656 output_arg, show_flags,
12657 rpki_target_state);
12658 } else {
12659 struct listnode *node;
12660 struct bgp *abgp;
12661 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12662 * AFI_IP6 */
12663
12664 if (uj)
12665 vty_out(vty, "{\n");
12666
12667 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12668 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12669 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12670 ? AFI_IP
12671 : AFI_IP6;
12672 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12673 FOREACH_SAFI (safi) {
12674 if (!bgp_afi_safi_peer_exists(abgp, afi,
12675 safi))
12676 continue;
12677
12678 if (uj) {
12679 if (first)
12680 first = false;
12681 else
12682 vty_out(vty, ",\n");
12683 vty_out(vty, "\"%s\":{\n",
12684 get_afi_safi_str(afi,
12685 safi,
12686 true));
12687 } else
12688 vty_out(vty,
12689 "\nFor address family: %s\n",
12690 get_afi_safi_str(
12691 afi, safi,
12692 false));
12693
12694 if (community)
12695 bgp_show_community(
12696 vty, abgp, community,
12697 exact_match, afi, safi,
12698 show_flags);
12699 else
12700 bgp_show(vty, abgp, afi, safi,
12701 sh_type, output_arg,
12702 show_flags,
12703 rpki_target_state);
12704 if (uj)
12705 vty_out(vty, "}\n");
12706 }
12707 }
12708 } else {
12709 /* show <ip> bgp all: for each AFI and SAFI*/
12710 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12711 FOREACH_AFI_SAFI (afi, safi) {
12712 if (!bgp_afi_safi_peer_exists(abgp, afi,
12713 safi))
12714 continue;
12715
12716 if (uj) {
12717 if (first)
12718 first = false;
12719 else
12720 vty_out(vty, ",\n");
12721
12722 vty_out(vty, "\"%s\":{\n",
12723 get_afi_safi_str(afi,
12724 safi,
12725 true));
12726 } else
12727 vty_out(vty,
12728 "\nFor address family: %s\n",
12729 get_afi_safi_str(
12730 afi, safi,
12731 false));
12732
12733 if (community)
12734 bgp_show_community(
12735 vty, abgp, community,
12736 exact_match, afi, safi,
12737 show_flags);
12738 else
12739 bgp_show(vty, abgp, afi, safi,
12740 sh_type, output_arg,
12741 show_flags,
12742 rpki_target_state);
12743 if (uj)
12744 vty_out(vty, "}\n");
12745 }
12746 }
12747 }
12748 if (uj)
12749 vty_out(vty, "}\n");
12750 }
12751 return CMD_SUCCESS;
12752 }
12753
12754 DEFUN (show_ip_bgp_route,
12755 show_ip_bgp_route_cmd,
12756 "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]",
12757 SHOW_STR
12758 IP_STR
12759 BGP_STR
12760 BGP_INSTANCE_HELP_STR
12761 BGP_AFI_HELP_STR
12762 BGP_SAFI_WITH_LABEL_HELP_STR
12763 "Network in the BGP routing table to display\n"
12764 "IPv4 prefix\n"
12765 "Network in the BGP routing table to display\n"
12766 "IPv6 prefix\n"
12767 "Display only the bestpath\n"
12768 "Display only multipaths\n"
12769 "Display only paths that match the specified rpki state\n"
12770 "A valid path as determined by rpki\n"
12771 "A invalid path as determined by rpki\n"
12772 "A path that has no rpki data\n"
12773 JSON_STR)
12774 {
12775 int prefix_check = 0;
12776
12777 afi_t afi = AFI_IP6;
12778 safi_t safi = SAFI_UNICAST;
12779 char *prefix = NULL;
12780 struct bgp *bgp = NULL;
12781 enum bgp_path_type path_type;
12782 bool uj = use_json(argc, argv);
12783
12784 int idx = 0;
12785
12786 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12787 &bgp, uj);
12788 if (!idx)
12789 return CMD_WARNING;
12790
12791 if (!bgp) {
12792 vty_out(vty,
12793 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12794 return CMD_WARNING;
12795 }
12796
12797 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12798 if (argv_find(argv, argc, "A.B.C.D", &idx)
12799 || argv_find(argv, argc, "X:X::X:X", &idx))
12800 prefix_check = 0;
12801 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12802 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12803 prefix_check = 1;
12804
12805 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12806 && afi != AFI_IP6) {
12807 vty_out(vty,
12808 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12809 return CMD_WARNING;
12810 }
12811 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12812 && afi != AFI_IP) {
12813 vty_out(vty,
12814 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12815 return CMD_WARNING;
12816 }
12817
12818 prefix = argv[idx]->arg;
12819
12820 /* [<bestpath|multipath>] */
12821 if (argv_find(argv, argc, "bestpath", &idx))
12822 path_type = BGP_PATH_SHOW_BESTPATH;
12823 else if (argv_find(argv, argc, "multipath", &idx))
12824 path_type = BGP_PATH_SHOW_MULTIPATH;
12825 else
12826 path_type = BGP_PATH_SHOW_ALL;
12827
12828 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12829 path_type, RPKI_NOT_BEING_USED, uj);
12830 }
12831
12832 DEFUN (show_ip_bgp_regexp,
12833 show_ip_bgp_regexp_cmd,
12834 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12835 SHOW_STR
12836 IP_STR
12837 BGP_STR
12838 BGP_INSTANCE_HELP_STR
12839 BGP_AFI_HELP_STR
12840 BGP_SAFI_WITH_LABEL_HELP_STR
12841 "Display routes matching the AS path regular expression\n"
12842 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12843 JSON_STR)
12844 {
12845 afi_t afi = AFI_IP6;
12846 safi_t safi = SAFI_UNICAST;
12847 struct bgp *bgp = NULL;
12848 bool uj = use_json(argc, argv);
12849 char *regstr = NULL;
12850
12851 int idx = 0;
12852 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12853 &bgp, false);
12854 if (!idx)
12855 return CMD_WARNING;
12856
12857 // get index of regex
12858 if (argv_find(argv, argc, "REGEX", &idx))
12859 regstr = argv[idx]->arg;
12860
12861 assert(regstr);
12862 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12863 bgp_show_type_regexp, uj);
12864 }
12865
12866 DEFPY (show_ip_bgp_instance_all,
12867 show_ip_bgp_instance_all_cmd,
12868 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12869 SHOW_STR
12870 IP_STR
12871 BGP_STR
12872 BGP_INSTANCE_ALL_HELP_STR
12873 BGP_AFI_HELP_STR
12874 BGP_SAFI_WITH_LABEL_HELP_STR
12875 JSON_STR
12876 "Increase table width for longer prefixes\n")
12877 {
12878 afi_t afi = AFI_IP6;
12879 safi_t safi = SAFI_UNICAST;
12880 struct bgp *bgp = NULL;
12881 int idx = 0;
12882 uint16_t show_flags = 0;
12883
12884 if (uj) {
12885 argc--;
12886 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12887 }
12888
12889 if (wide)
12890 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12891
12892 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12893 &bgp, uj);
12894 if (!idx)
12895 return CMD_WARNING;
12896
12897 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12898 return CMD_SUCCESS;
12899 }
12900
12901 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12902 afi_t afi, safi_t safi, enum bgp_show_type type,
12903 bool use_json)
12904 {
12905 regex_t *regex;
12906 int rc;
12907 uint16_t show_flags = 0;
12908
12909 if (use_json)
12910 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12911
12912 if (!config_bgp_aspath_validate(regstr)) {
12913 vty_out(vty, "Invalid character in REGEX %s\n",
12914 regstr);
12915 return CMD_WARNING_CONFIG_FAILED;
12916 }
12917
12918 regex = bgp_regcomp(regstr);
12919 if (!regex) {
12920 vty_out(vty, "Can't compile regexp %s\n", regstr);
12921 return CMD_WARNING;
12922 }
12923
12924 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
12925 RPKI_NOT_BEING_USED);
12926 bgp_regex_free(regex);
12927 return rc;
12928 }
12929
12930 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12931 const char *comstr, int exact, afi_t afi,
12932 safi_t safi, uint16_t show_flags)
12933 {
12934 struct community *com;
12935 int ret = 0;
12936
12937 com = community_str2com(comstr);
12938 if (!com) {
12939 vty_out(vty, "%% Community malformed: %s\n", comstr);
12940 return CMD_WARNING;
12941 }
12942
12943 ret = bgp_show(vty, bgp, afi, safi,
12944 (exact ? bgp_show_type_community_exact
12945 : bgp_show_type_community),
12946 com, show_flags, RPKI_NOT_BEING_USED);
12947 community_free(&com);
12948
12949 return ret;
12950 }
12951
12952 enum bgp_stats {
12953 BGP_STATS_MAXBITLEN = 0,
12954 BGP_STATS_RIB,
12955 BGP_STATS_PREFIXES,
12956 BGP_STATS_TOTPLEN,
12957 BGP_STATS_UNAGGREGATEABLE,
12958 BGP_STATS_MAX_AGGREGATEABLE,
12959 BGP_STATS_AGGREGATES,
12960 BGP_STATS_SPACE,
12961 BGP_STATS_ASPATH_COUNT,
12962 BGP_STATS_ASPATH_MAXHOPS,
12963 BGP_STATS_ASPATH_TOTHOPS,
12964 BGP_STATS_ASPATH_MAXSIZE,
12965 BGP_STATS_ASPATH_TOTSIZE,
12966 BGP_STATS_ASN_HIGHEST,
12967 BGP_STATS_MAX,
12968 };
12969
12970 #define TABLE_STATS_IDX_VTY 0
12971 #define TABLE_STATS_IDX_JSON 1
12972
12973 static const char *table_stats_strs[][2] = {
12974 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12975 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12976 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12977 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12978 "unaggregateablePrefixes"},
12979 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12980 "maximumAggregateablePrefixes"},
12981 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12982 "bgpAggregateAdvertisements"},
12983 [BGP_STATS_SPACE] = {"Address space advertised",
12984 "addressSpaceAdvertised"},
12985 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12986 "advertisementsWithPaths"},
12987 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12988 "longestAsPath"},
12989 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12990 "largestAsPath"},
12991 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12992 "averageAsPathLengthHops"},
12993 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12994 "averageAsPathSizeBytes"},
12995 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12996 [BGP_STATS_MAX] = {NULL, NULL}
12997 };
12998
12999 struct bgp_table_stats {
13000 struct bgp_table *table;
13001 unsigned long long counts[BGP_STATS_MAX];
13002
13003 unsigned long long
13004 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13005 1];
13006
13007 double total_space;
13008 };
13009
13010 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13011 struct bgp_table_stats *ts, unsigned int space)
13012 {
13013 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13014 struct bgp_path_info *pi;
13015 const struct prefix *rn_p;
13016
13017 if (!bgp_dest_has_bgp_path_info_data(dest))
13018 return;
13019
13020 rn_p = bgp_dest_get_prefix(dest);
13021 ts->counts[BGP_STATS_PREFIXES]++;
13022 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13023
13024 ts->prefix_len_count[rn_p->prefixlen]++;
13025 /* check if the prefix is included by any other announcements */
13026 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13027 pdest = bgp_dest_parent_nolock(pdest);
13028
13029 if (pdest == NULL || pdest == top) {
13030 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13031 /* announced address space */
13032 if (space)
13033 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13034 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13035 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13036
13037
13038 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13039 ts->counts[BGP_STATS_RIB]++;
13040
13041 if (CHECK_FLAG(pi->attr->flag,
13042 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13043 ts->counts[BGP_STATS_AGGREGATES]++;
13044
13045 /* as-path stats */
13046 if (pi->attr->aspath) {
13047 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13048 unsigned int size = aspath_size(pi->attr->aspath);
13049 as_t highest = aspath_highest(pi->attr->aspath);
13050
13051 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13052
13053 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13054 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13055
13056 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13057 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13058
13059 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13060 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13061 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13062 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13063 }
13064 }
13065 }
13066
13067 static void bgp_table_stats_walker(struct thread *t)
13068 {
13069 struct bgp_dest *dest, *ndest;
13070 struct bgp_dest *top;
13071 struct bgp_table_stats *ts = THREAD_ARG(t);
13072 unsigned int space = 0;
13073
13074 if (!(top = bgp_table_top(ts->table)))
13075 return;
13076
13077 switch (ts->table->afi) {
13078 case AFI_IP:
13079 space = IPV4_MAX_BITLEN;
13080 break;
13081 case AFI_IP6:
13082 space = IPV6_MAX_BITLEN;
13083 break;
13084 case AFI_L2VPN:
13085 space = EVPN_ROUTE_PREFIXLEN;
13086 break;
13087 default:
13088 return;
13089 }
13090
13091 ts->counts[BGP_STATS_MAXBITLEN] = space;
13092
13093 for (dest = top; dest; dest = bgp_route_next(dest)) {
13094 if (ts->table->safi == SAFI_MPLS_VPN
13095 || ts->table->safi == SAFI_ENCAP
13096 || ts->table->safi == SAFI_EVPN) {
13097 struct bgp_table *table;
13098
13099 table = bgp_dest_get_bgp_table_info(dest);
13100 if (!table)
13101 continue;
13102
13103 top = bgp_table_top(table);
13104 for (ndest = bgp_table_top(table); ndest;
13105 ndest = bgp_route_next(ndest))
13106 bgp_table_stats_rn(ndest, top, ts, space);
13107 } else {
13108 bgp_table_stats_rn(dest, top, ts, space);
13109 }
13110 }
13111 }
13112
13113 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13114 struct json_object *json_array)
13115 {
13116 struct listnode *node, *nnode;
13117 struct bgp *bgp;
13118
13119 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13120 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13121 }
13122
13123 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13124 safi_t safi, struct json_object *json_array)
13125 {
13126 struct bgp_table_stats ts;
13127 unsigned int i;
13128 int ret = CMD_SUCCESS;
13129 char temp_buf[20];
13130 struct json_object *json = NULL;
13131 uint32_t bitlen = 0;
13132 struct json_object *json_bitlen;
13133
13134 if (json_array)
13135 json = json_object_new_object();
13136
13137 if (!bgp->rib[afi][safi]) {
13138 char warning_msg[50];
13139
13140 snprintf(warning_msg, sizeof(warning_msg),
13141 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13142 safi);
13143
13144 if (!json)
13145 vty_out(vty, "%s\n", warning_msg);
13146 else
13147 json_object_string_add(json, "warning", warning_msg);
13148
13149 ret = CMD_WARNING;
13150 goto end_table_stats;
13151 }
13152
13153 if (!json)
13154 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13155 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13156 else
13157 json_object_string_add(json, "instance", bgp->name_pretty);
13158
13159 /* labeled-unicast routes live in the unicast table */
13160 if (safi == SAFI_LABELED_UNICAST)
13161 safi = SAFI_UNICAST;
13162
13163 memset(&ts, 0, sizeof(ts));
13164 ts.table = bgp->rib[afi][safi];
13165 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13166
13167 for (i = 0; i < BGP_STATS_MAX; i++) {
13168 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13169 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13170 continue;
13171
13172 switch (i) {
13173 case BGP_STATS_ASPATH_TOTHOPS:
13174 case BGP_STATS_ASPATH_TOTSIZE:
13175 if (!json) {
13176 snprintf(
13177 temp_buf, sizeof(temp_buf), "%12.2f",
13178 ts.counts[i]
13179 ? (float)ts.counts[i]
13180 / (float)ts.counts
13181 [BGP_STATS_ASPATH_COUNT]
13182 : 0);
13183 vty_out(vty, "%-30s: %s",
13184 table_stats_strs[i]
13185 [TABLE_STATS_IDX_VTY],
13186 temp_buf);
13187 } else {
13188 json_object_double_add(
13189 json,
13190 table_stats_strs[i]
13191 [TABLE_STATS_IDX_JSON],
13192 ts.counts[i]
13193 ? (double)ts.counts[i]
13194 / (double)ts.counts
13195 [BGP_STATS_ASPATH_COUNT]
13196 : 0);
13197 }
13198 break;
13199 case BGP_STATS_TOTPLEN:
13200 if (!json) {
13201 snprintf(
13202 temp_buf, sizeof(temp_buf), "%12.2f",
13203 ts.counts[i]
13204 ? (float)ts.counts[i]
13205 / (float)ts.counts
13206 [BGP_STATS_PREFIXES]
13207 : 0);
13208 vty_out(vty, "%-30s: %s",
13209 table_stats_strs[i]
13210 [TABLE_STATS_IDX_VTY],
13211 temp_buf);
13212 } else {
13213 json_object_double_add(
13214 json,
13215 table_stats_strs[i]
13216 [TABLE_STATS_IDX_JSON],
13217 ts.counts[i]
13218 ? (double)ts.counts[i]
13219 / (double)ts.counts
13220 [BGP_STATS_PREFIXES]
13221 : 0);
13222 }
13223 break;
13224 case BGP_STATS_SPACE:
13225 if (!json) {
13226 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13227 ts.total_space);
13228 vty_out(vty, "%-30s: %s\n",
13229 table_stats_strs[i]
13230 [TABLE_STATS_IDX_VTY],
13231 temp_buf);
13232 } else {
13233 json_object_double_add(
13234 json,
13235 table_stats_strs[i]
13236 [TABLE_STATS_IDX_JSON],
13237 (double)ts.total_space);
13238 }
13239 if (afi == AFI_IP6) {
13240 if (!json) {
13241 snprintf(temp_buf, sizeof(temp_buf),
13242 "%12g",
13243 ts.total_space
13244 * pow(2.0, -128 + 32));
13245 vty_out(vty, "%30s: %s\n",
13246 "/32 equivalent %s\n",
13247 temp_buf);
13248 } else {
13249 json_object_double_add(
13250 json, "/32equivalent",
13251 (double)(ts.total_space
13252 * pow(2.0,
13253 -128 + 32)));
13254 }
13255 if (!json) {
13256 snprintf(temp_buf, sizeof(temp_buf),
13257 "%12g",
13258 ts.total_space
13259 * pow(2.0, -128 + 48));
13260 vty_out(vty, "%30s: %s\n",
13261 "/48 equivalent %s\n",
13262 temp_buf);
13263 } else {
13264 json_object_double_add(
13265 json, "/48equivalent",
13266 (double)(ts.total_space
13267 * pow(2.0,
13268 -128 + 48)));
13269 }
13270 } else {
13271 if (!json) {
13272 snprintf(temp_buf, sizeof(temp_buf),
13273 "%12.2f",
13274 ts.total_space * 100.
13275 * pow(2.0, -32));
13276 vty_out(vty, "%30s: %s\n",
13277 "% announced ", temp_buf);
13278 } else {
13279 json_object_double_add(
13280 json, "%announced",
13281 (double)(ts.total_space * 100.
13282 * pow(2.0, -32)));
13283 }
13284 if (!json) {
13285 snprintf(temp_buf, sizeof(temp_buf),
13286 "%12.2f",
13287 ts.total_space
13288 * pow(2.0, -32 + 8));
13289 vty_out(vty, "%30s: %s\n",
13290 "/8 equivalent ", temp_buf);
13291 } else {
13292 json_object_double_add(
13293 json, "/8equivalent",
13294 (double)(ts.total_space
13295 * pow(2.0, -32 + 8)));
13296 }
13297 if (!json) {
13298 snprintf(temp_buf, sizeof(temp_buf),
13299 "%12.2f",
13300 ts.total_space
13301 * pow(2.0, -32 + 24));
13302 vty_out(vty, "%30s: %s\n",
13303 "/24 equivalent ", temp_buf);
13304 } else {
13305 json_object_double_add(
13306 json, "/24equivalent",
13307 (double)(ts.total_space
13308 * pow(2.0, -32 + 24)));
13309 }
13310 }
13311 break;
13312 default:
13313 if (!json) {
13314 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13315 ts.counts[i]);
13316 vty_out(vty, "%-30s: %s",
13317 table_stats_strs[i]
13318 [TABLE_STATS_IDX_VTY],
13319 temp_buf);
13320 } else {
13321 json_object_int_add(
13322 json,
13323 table_stats_strs[i]
13324 [TABLE_STATS_IDX_JSON],
13325 ts.counts[i]);
13326 }
13327 }
13328 if (!json)
13329 vty_out(vty, "\n");
13330 }
13331
13332 switch (afi) {
13333 case AFI_IP:
13334 bitlen = IPV4_MAX_BITLEN;
13335 break;
13336 case AFI_IP6:
13337 bitlen = IPV6_MAX_BITLEN;
13338 break;
13339 case AFI_L2VPN:
13340 bitlen = EVPN_ROUTE_PREFIXLEN;
13341 break;
13342 default:
13343 break;
13344 }
13345
13346 if (json) {
13347 json_bitlen = json_object_new_array();
13348
13349 for (i = 0; i <= bitlen; i++) {
13350 struct json_object *ind_bit = json_object_new_object();
13351
13352 if (!ts.prefix_len_count[i])
13353 continue;
13354
13355 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13356 json_object_int_add(ind_bit, temp_buf,
13357 ts.prefix_len_count[i]);
13358 json_object_array_add(json_bitlen, ind_bit);
13359 }
13360 json_object_object_add(json, "prefixLength", json_bitlen);
13361 }
13362
13363 end_table_stats:
13364 if (json)
13365 json_object_array_add(json_array, json);
13366 return ret;
13367 }
13368
13369 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13370 safi_t safi, struct json_object *json_array)
13371 {
13372 if (!bgp) {
13373 bgp_table_stats_all(vty, afi, safi, json_array);
13374 return CMD_SUCCESS;
13375 }
13376
13377 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13378 }
13379
13380 enum bgp_pcounts {
13381 PCOUNT_ADJ_IN = 0,
13382 PCOUNT_DAMPED,
13383 PCOUNT_REMOVED,
13384 PCOUNT_HISTORY,
13385 PCOUNT_STALE,
13386 PCOUNT_VALID,
13387 PCOUNT_ALL,
13388 PCOUNT_COUNTED,
13389 PCOUNT_BPATH_SELECTED,
13390 PCOUNT_PFCNT, /* the figure we display to users */
13391 PCOUNT_MAX,
13392 };
13393
13394 static const char *const pcount_strs[] = {
13395 [PCOUNT_ADJ_IN] = "Adj-in",
13396 [PCOUNT_DAMPED] = "Damped",
13397 [PCOUNT_REMOVED] = "Removed",
13398 [PCOUNT_HISTORY] = "History",
13399 [PCOUNT_STALE] = "Stale",
13400 [PCOUNT_VALID] = "Valid",
13401 [PCOUNT_ALL] = "All RIB",
13402 [PCOUNT_COUNTED] = "PfxCt counted",
13403 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13404 [PCOUNT_PFCNT] = "Useable",
13405 [PCOUNT_MAX] = NULL,
13406 };
13407
13408 struct peer_pcounts {
13409 unsigned int count[PCOUNT_MAX];
13410 const struct peer *peer;
13411 const struct bgp_table *table;
13412 safi_t safi;
13413 };
13414
13415 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13416 {
13417 const struct bgp_adj_in *ain;
13418 const struct bgp_path_info *pi;
13419 const struct peer *peer = pc->peer;
13420
13421 for (ain = rn->adj_in; ain; ain = ain->next)
13422 if (ain->peer == peer)
13423 pc->count[PCOUNT_ADJ_IN]++;
13424
13425 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13426
13427 if (pi->peer != peer)
13428 continue;
13429
13430 pc->count[PCOUNT_ALL]++;
13431
13432 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13433 pc->count[PCOUNT_DAMPED]++;
13434 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13435 pc->count[PCOUNT_HISTORY]++;
13436 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13437 pc->count[PCOUNT_REMOVED]++;
13438 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13439 pc->count[PCOUNT_STALE]++;
13440 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13441 pc->count[PCOUNT_VALID]++;
13442 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13443 pc->count[PCOUNT_PFCNT]++;
13444 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13445 pc->count[PCOUNT_BPATH_SELECTED]++;
13446
13447 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13448 pc->count[PCOUNT_COUNTED]++;
13449 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13450 flog_err(
13451 EC_LIB_DEVELOPMENT,
13452 "Attempting to count but flags say it is unusable");
13453 } else {
13454 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13455 flog_err(
13456 EC_LIB_DEVELOPMENT,
13457 "Not counted but flags say we should");
13458 }
13459 }
13460 }
13461
13462 static void bgp_peer_count_walker(struct thread *t)
13463 {
13464 struct bgp_dest *rn, *rm;
13465 const struct bgp_table *table;
13466 struct peer_pcounts *pc = THREAD_ARG(t);
13467
13468 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13469 || pc->safi == SAFI_EVPN) {
13470 /* Special handling for 2-level routing tables. */
13471 for (rn = bgp_table_top(pc->table); rn;
13472 rn = bgp_route_next(rn)) {
13473 table = bgp_dest_get_bgp_table_info(rn);
13474 if (table != NULL)
13475 for (rm = bgp_table_top(table); rm;
13476 rm = bgp_route_next(rm))
13477 bgp_peer_count_proc(rm, pc);
13478 }
13479 } else
13480 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13481 bgp_peer_count_proc(rn, pc);
13482 }
13483
13484 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13485 safi_t safi, bool use_json)
13486 {
13487 struct peer_pcounts pcounts = {.peer = peer};
13488 unsigned int i;
13489 json_object *json = NULL;
13490 json_object *json_loop = NULL;
13491
13492 if (use_json) {
13493 json = json_object_new_object();
13494 json_loop = json_object_new_object();
13495 }
13496
13497 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13498 || !peer->bgp->rib[afi][safi]) {
13499 if (use_json) {
13500 json_object_string_add(
13501 json, "warning",
13502 "No such neighbor or address family");
13503 vty_out(vty, "%s\n", json_object_to_json_string(json));
13504 json_object_free(json);
13505 json_object_free(json_loop);
13506 } else
13507 vty_out(vty, "%% No such neighbor or address family\n");
13508
13509 return CMD_WARNING;
13510 }
13511
13512 memset(&pcounts, 0, sizeof(pcounts));
13513 pcounts.peer = peer;
13514 pcounts.table = peer->bgp->rib[afi][safi];
13515 pcounts.safi = safi;
13516
13517 /* in-place call via thread subsystem so as to record execution time
13518 * stats for the thread-walk (i.e. ensure this can't be blamed on
13519 * on just vty_read()).
13520 */
13521 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13522
13523 if (use_json) {
13524 json_object_string_add(json, "prefixCountsFor", peer->host);
13525 json_object_string_add(json, "multiProtocol",
13526 get_afi_safi_str(afi, safi, true));
13527 json_object_int_add(json, "pfxCounter",
13528 peer->pcount[afi][safi]);
13529
13530 for (i = 0; i < PCOUNT_MAX; i++)
13531 json_object_int_add(json_loop, pcount_strs[i],
13532 pcounts.count[i]);
13533
13534 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13535
13536 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13537 json_object_string_add(json, "pfxctDriftFor",
13538 peer->host);
13539 json_object_string_add(
13540 json, "recommended",
13541 "Please report this bug, with the above command output");
13542 }
13543 vty_json(vty, json);
13544 } else {
13545
13546 if (peer->hostname
13547 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13548 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13549 peer->hostname, peer->host,
13550 get_afi_safi_str(afi, safi, false));
13551 } else {
13552 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13553 get_afi_safi_str(afi, safi, false));
13554 }
13555
13556 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13557 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13558
13559 for (i = 0; i < PCOUNT_MAX; i++)
13560 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13561 pcounts.count[i]);
13562
13563 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13564 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13565 vty_out(vty,
13566 "Please report this bug, with the above command output\n");
13567 }
13568 }
13569
13570 return CMD_SUCCESS;
13571 }
13572
13573 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13574 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13575 "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]",
13576 SHOW_STR
13577 IP_STR
13578 BGP_STR
13579 BGP_INSTANCE_HELP_STR
13580 BGP_AFI_HELP_STR
13581 BGP_SAFI_HELP_STR
13582 "Detailed information on TCP and BGP neighbor connections\n"
13583 "Neighbor to display information about\n"
13584 "Neighbor to display information about\n"
13585 "Neighbor on BGP configured interface\n"
13586 "Display detailed prefix count information\n"
13587 JSON_STR)
13588 {
13589 afi_t afi = AFI_IP6;
13590 safi_t safi = SAFI_UNICAST;
13591 struct peer *peer;
13592 int idx = 0;
13593 struct bgp *bgp = NULL;
13594 bool uj = use_json(argc, argv);
13595
13596 if (uj)
13597 argc--;
13598
13599 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13600 &bgp, uj);
13601 if (!idx)
13602 return CMD_WARNING;
13603
13604 argv_find(argv, argc, "neighbors", &idx);
13605 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13606 if (!peer)
13607 return CMD_WARNING;
13608
13609 return bgp_peer_counts(vty, peer, afi, safi, uj);
13610 }
13611
13612 #ifdef KEEP_OLD_VPN_COMMANDS
13613 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13614 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13615 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13616 SHOW_STR
13617 IP_STR
13618 BGP_STR
13619 BGP_VPNVX_HELP_STR
13620 "Display information about all VPNv4 NLRIs\n"
13621 "Detailed information on TCP and BGP neighbor connections\n"
13622 "Neighbor to display information about\n"
13623 "Neighbor to display information about\n"
13624 "Neighbor on BGP configured interface\n"
13625 "Display detailed prefix count information\n"
13626 JSON_STR)
13627 {
13628 int idx_peer = 6;
13629 struct peer *peer;
13630 bool uj = use_json(argc, argv);
13631
13632 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13633 if (!peer)
13634 return CMD_WARNING;
13635
13636 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13637 }
13638
13639 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13640 show_ip_bgp_vpn_all_route_prefix_cmd,
13641 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13642 SHOW_STR
13643 IP_STR
13644 BGP_STR
13645 BGP_VPNVX_HELP_STR
13646 "Display information about all VPNv4 NLRIs\n"
13647 "Network in the BGP routing table to display\n"
13648 "Network in the BGP routing table to display\n"
13649 JSON_STR)
13650 {
13651 int idx = 0;
13652 char *network = NULL;
13653 struct bgp *bgp = bgp_get_default();
13654 if (!bgp) {
13655 vty_out(vty, "Can't find default instance\n");
13656 return CMD_WARNING;
13657 }
13658
13659 if (argv_find(argv, argc, "A.B.C.D", &idx))
13660 network = argv[idx]->arg;
13661 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13662 network = argv[idx]->arg;
13663 else {
13664 vty_out(vty, "Unable to figure out Network\n");
13665 return CMD_WARNING;
13666 }
13667
13668 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13669 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13670 use_json(argc, argv));
13671 }
13672 #endif /* KEEP_OLD_VPN_COMMANDS */
13673
13674 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13675 show_bgp_l2vpn_evpn_route_prefix_cmd,
13676 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13677 SHOW_STR
13678 BGP_STR
13679 L2VPN_HELP_STR
13680 EVPN_HELP_STR
13681 "Network in the BGP routing table to display\n"
13682 "Network in the BGP routing table to display\n"
13683 "Network in the BGP routing table to display\n"
13684 "Network in the BGP routing table to display\n"
13685 JSON_STR)
13686 {
13687 int idx = 0;
13688 char *network = NULL;
13689 int prefix_check = 0;
13690
13691 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13692 argv_find(argv, argc, "X:X::X:X", &idx))
13693 network = argv[idx]->arg;
13694 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13695 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13696 network = argv[idx]->arg;
13697 prefix_check = 1;
13698 } else {
13699 vty_out(vty, "Unable to figure out Network\n");
13700 return CMD_WARNING;
13701 }
13702 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13703 prefix_check, BGP_PATH_SHOW_ALL,
13704 RPKI_NOT_BEING_USED, use_json(argc, argv));
13705 }
13706
13707 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13708 struct bgp_table *table, int *header1,
13709 int *header2, json_object *json,
13710 json_object *json_scode,
13711 json_object *json_ocode, bool wide)
13712 {
13713 uint64_t version = table ? table->version : 0;
13714
13715 if (*header1) {
13716 if (json) {
13717 json_object_int_add(json, "bgpTableVersion", version);
13718 json_object_string_addf(json, "bgpLocalRouterId",
13719 "%pI4", &peer->bgp->router_id);
13720 json_object_int_add(json, "defaultLocPrf",
13721 peer->bgp->default_local_pref);
13722 json_object_int_add(json, "localAS",
13723 peer->change_local_as
13724 ? peer->change_local_as
13725 : peer->local_as);
13726 json_object_object_add(json, "bgpStatusCodes",
13727 json_scode);
13728 json_object_object_add(json, "bgpOriginCodes",
13729 json_ocode);
13730 } else {
13731 vty_out(vty,
13732 "BGP table version is %" PRIu64
13733 ", local router ID is %pI4, vrf id ",
13734 version, &peer->bgp->router_id);
13735 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13736 vty_out(vty, "%s", VRFID_NONE_STR);
13737 else
13738 vty_out(vty, "%u", peer->bgp->vrf_id);
13739 vty_out(vty, "\n");
13740 vty_out(vty, "Default local pref %u, ",
13741 peer->bgp->default_local_pref);
13742 vty_out(vty, "local AS %u\n",
13743 peer->change_local_as ? peer->change_local_as
13744 : peer->local_as);
13745 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13746 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13747 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13748 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13749 }
13750 *header1 = 0;
13751 }
13752 if (*header2) {
13753 if (!json)
13754 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13755 : BGP_SHOW_HEADER));
13756 *header2 = 0;
13757 }
13758 }
13759
13760 static void
13761 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13762 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13763 const char *rmap_name, json_object *json, json_object *json_ar,
13764 json_object *json_scode, json_object *json_ocode,
13765 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13766 unsigned long *output_count, unsigned long *filtered_count)
13767 {
13768 struct bgp_adj_in *ain;
13769 struct bgp_adj_out *adj;
13770 struct bgp_dest *dest;
13771 struct bgp *bgp;
13772 struct attr attr;
13773 int ret;
13774 struct update_subgroup *subgrp;
13775 struct peer_af *paf;
13776 bool route_filtered;
13777 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13778 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13779 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13780 || (safi == SAFI_EVPN))
13781 ? true
13782 : false;
13783
13784 bgp = peer->bgp;
13785
13786 subgrp = peer_subgroup(peer, afi, safi);
13787
13788 if (type == bgp_show_adj_route_advertised && subgrp
13789 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13790 if (use_json) {
13791 json_object_int_add(json, "bgpTableVersion",
13792 table->version);
13793 json_object_string_addf(json, "bgpLocalRouterId",
13794 "%pI4", &bgp->router_id);
13795 json_object_int_add(json, "defaultLocPrf",
13796 bgp->default_local_pref);
13797 json_object_int_add(json, "localAS",
13798 peer->change_local_as
13799 ? peer->change_local_as
13800 : peer->local_as);
13801 json_object_object_add(json, "bgpStatusCodes",
13802 json_scode);
13803 json_object_object_add(json, "bgpOriginCodes",
13804 json_ocode);
13805 json_object_string_add(
13806 json, "bgpOriginatingDefaultNetwork",
13807 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13808 } else {
13809 vty_out(vty,
13810 "BGP table version is %" PRIu64
13811 ", local router ID is %pI4, vrf id ",
13812 table->version, &bgp->router_id);
13813 if (bgp->vrf_id == VRF_UNKNOWN)
13814 vty_out(vty, "%s", VRFID_NONE_STR);
13815 else
13816 vty_out(vty, "%u", bgp->vrf_id);
13817 vty_out(vty, "\n");
13818 vty_out(vty, "Default local pref %u, ",
13819 bgp->default_local_pref);
13820 vty_out(vty, "local AS %u\n",
13821 peer->change_local_as ? peer->change_local_as
13822 : peer->local_as);
13823 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13824 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13825 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13826 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13827
13828 vty_out(vty, "Originating default network %s\n\n",
13829 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13830 }
13831 *header1 = 0;
13832 }
13833
13834 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13835 if (type == bgp_show_adj_route_received
13836 || type == bgp_show_adj_route_filtered) {
13837 for (ain = dest->adj_in; ain; ain = ain->next) {
13838 if (ain->peer != peer)
13839 continue;
13840
13841 show_adj_route_header(vty, peer, table, header1,
13842 header2, json, json_scode,
13843 json_ocode, wide);
13844
13845 if ((safi == SAFI_MPLS_VPN)
13846 || (safi == SAFI_ENCAP)
13847 || (safi == SAFI_EVPN)) {
13848 if (use_json)
13849 json_object_string_add(
13850 json_ar, "rd", rd_str);
13851 else if (show_rd && rd_str) {
13852 vty_out(vty,
13853 "Route Distinguisher: %s\n",
13854 rd_str);
13855 show_rd = false;
13856 }
13857 }
13858
13859 attr = *ain->attr;
13860 route_filtered = false;
13861
13862 /* Filter prefix using distribute list,
13863 * filter list or prefix list
13864 */
13865 const struct prefix *rn_p =
13866 bgp_dest_get_prefix(dest);
13867 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13868 safi))
13869 == FILTER_DENY)
13870 route_filtered = true;
13871
13872 /* Filter prefix using route-map */
13873 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13874 safi, rmap_name, NULL,
13875 0, NULL);
13876
13877 if (type == bgp_show_adj_route_filtered &&
13878 !route_filtered && ret != RMAP_DENY) {
13879 bgp_attr_flush(&attr);
13880 continue;
13881 }
13882
13883 if (type == bgp_show_adj_route_received
13884 && (route_filtered || ret == RMAP_DENY))
13885 (*filtered_count)++;
13886
13887 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
13888 use_json, json_ar, wide);
13889 bgp_attr_flush(&attr);
13890 (*output_count)++;
13891 }
13892 } else if (type == bgp_show_adj_route_advertised) {
13893 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13894 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13895 if (paf->peer != peer || !adj->attr)
13896 continue;
13897
13898 show_adj_route_header(vty, peer, table,
13899 header1, header2,
13900 json, json_scode,
13901 json_ocode, wide);
13902
13903 const struct prefix *rn_p =
13904 bgp_dest_get_prefix(dest);
13905
13906 attr = *adj->attr;
13907 ret = bgp_output_modifier(
13908 peer, rn_p, &attr, afi, safi,
13909 rmap_name);
13910
13911 if (ret != RMAP_DENY) {
13912 if ((safi == SAFI_MPLS_VPN)
13913 || (safi == SAFI_ENCAP)
13914 || (safi == SAFI_EVPN)) {
13915 if (use_json)
13916 json_object_string_add(
13917 json_ar,
13918 "rd",
13919 rd_str);
13920 else if (show_rd
13921 && rd_str) {
13922 vty_out(vty,
13923 "Route Distinguisher: %s\n",
13924 rd_str);
13925 show_rd = false;
13926 }
13927 }
13928 route_vty_out_tmp(
13929 vty, dest, rn_p, &attr,
13930 safi, use_json, json_ar,
13931 wide);
13932 (*output_count)++;
13933 } else {
13934 (*filtered_count)++;
13935 }
13936
13937 bgp_attr_flush(&attr);
13938 }
13939 } else if (type == bgp_show_adj_route_bestpath) {
13940 struct bgp_path_info *pi;
13941
13942 show_adj_route_header(vty, peer, table, header1,
13943 header2, json, json_scode,
13944 json_ocode, wide);
13945
13946 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13947 pi = pi->next) {
13948 if (pi->peer != peer)
13949 continue;
13950
13951 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13952 continue;
13953
13954 route_vty_out_tmp(vty, dest,
13955 bgp_dest_get_prefix(dest),
13956 pi->attr, safi, use_json,
13957 json_ar, wide);
13958 (*output_count)++;
13959 }
13960 }
13961 }
13962 }
13963
13964 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13965 safi_t safi, enum bgp_show_adj_route_type type,
13966 const char *rmap_name, uint16_t show_flags)
13967 {
13968 struct bgp *bgp;
13969 struct bgp_table *table;
13970 json_object *json = NULL;
13971 json_object *json_scode = NULL;
13972 json_object *json_ocode = NULL;
13973 json_object *json_ar = NULL;
13974 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13975
13976 /* Init BGP headers here so they're only displayed once
13977 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13978 */
13979 int header1 = 1;
13980 int header2 = 1;
13981
13982 /*
13983 * Initialize variables for each RD
13984 * All prefixes under an RD is aggregated within "json_routes"
13985 */
13986 char rd_str[BUFSIZ] = {0};
13987 json_object *json_routes = NULL;
13988
13989
13990 /* For 2-tier tables, prefix counts need to be
13991 * maintained across multiple runs of show_adj_route()
13992 */
13993 unsigned long output_count_per_rd;
13994 unsigned long filtered_count_per_rd;
13995 unsigned long output_count = 0;
13996 unsigned long filtered_count = 0;
13997
13998 if (use_json) {
13999 json = json_object_new_object();
14000 json_ar = json_object_new_object();
14001 json_scode = json_object_new_object();
14002 json_ocode = json_object_new_object();
14003
14004 json_object_string_add(json_scode, "suppressed", "s");
14005 json_object_string_add(json_scode, "damped", "d");
14006 json_object_string_add(json_scode, "history", "h");
14007 json_object_string_add(json_scode, "valid", "*");
14008 json_object_string_add(json_scode, "best", ">");
14009 json_object_string_add(json_scode, "multipath", "=");
14010 json_object_string_add(json_scode, "internal", "i");
14011 json_object_string_add(json_scode, "ribFailure", "r");
14012 json_object_string_add(json_scode, "stale", "S");
14013 json_object_string_add(json_scode, "removed", "R");
14014
14015 json_object_string_add(json_ocode, "igp", "i");
14016 json_object_string_add(json_ocode, "egp", "e");
14017 json_object_string_add(json_ocode, "incomplete", "?");
14018 }
14019
14020 if (!peer || !peer->afc[afi][safi]) {
14021 if (use_json) {
14022 json_object_string_add(
14023 json, "warning",
14024 "No such neighbor or address family");
14025 vty_out(vty, "%s\n", json_object_to_json_string(json));
14026 json_object_free(json);
14027 json_object_free(json_ar);
14028 json_object_free(json_scode);
14029 json_object_free(json_ocode);
14030 } else
14031 vty_out(vty, "%% No such neighbor or address family\n");
14032
14033 return CMD_WARNING;
14034 }
14035
14036 if ((type == bgp_show_adj_route_received
14037 || type == bgp_show_adj_route_filtered)
14038 && !CHECK_FLAG(peer->af_flags[afi][safi],
14039 PEER_FLAG_SOFT_RECONFIG)) {
14040 if (use_json) {
14041 json_object_string_add(
14042 json, "warning",
14043 "Inbound soft reconfiguration not enabled");
14044 vty_out(vty, "%s\n", json_object_to_json_string(json));
14045 json_object_free(json);
14046 json_object_free(json_ar);
14047 json_object_free(json_scode);
14048 json_object_free(json_ocode);
14049 } else
14050 vty_out(vty,
14051 "%% Inbound soft reconfiguration not enabled\n");
14052
14053 return CMD_WARNING;
14054 }
14055
14056 bgp = peer->bgp;
14057
14058 /* labeled-unicast routes live in the unicast table */
14059 if (safi == SAFI_LABELED_UNICAST)
14060 table = bgp->rib[afi][SAFI_UNICAST];
14061 else
14062 table = bgp->rib[afi][safi];
14063
14064 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14065 || (safi == SAFI_EVPN)) {
14066
14067 struct bgp_dest *dest;
14068
14069 for (dest = bgp_table_top(table); dest;
14070 dest = bgp_route_next(dest)) {
14071 table = bgp_dest_get_bgp_table_info(dest);
14072 if (!table)
14073 continue;
14074
14075 output_count_per_rd = 0;
14076 filtered_count_per_rd = 0;
14077
14078 if (use_json)
14079 json_routes = json_object_new_object();
14080
14081 const struct prefix_rd *prd;
14082 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14083 dest);
14084
14085 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14086
14087 show_adj_route(vty, peer, table, afi, safi, type,
14088 rmap_name, json, json_routes, json_scode,
14089 json_ocode, show_flags, &header1,
14090 &header2, rd_str, &output_count_per_rd,
14091 &filtered_count_per_rd);
14092
14093 /* Don't include an empty RD in the output! */
14094 if (json_routes && (output_count_per_rd > 0))
14095 json_object_object_add(json_ar, rd_str,
14096 json_routes);
14097
14098 output_count += output_count_per_rd;
14099 filtered_count += filtered_count_per_rd;
14100 }
14101 } else
14102 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14103 json, json_ar, json_scode, json_ocode,
14104 show_flags, &header1, &header2, rd_str,
14105 &output_count, &filtered_count);
14106
14107 if (use_json) {
14108 if (type == bgp_show_adj_route_advertised)
14109 json_object_object_add(json, "advertisedRoutes",
14110 json_ar);
14111 else
14112 json_object_object_add(json, "receivedRoutes", json_ar);
14113 json_object_int_add(json, "totalPrefixCounter", output_count);
14114 json_object_int_add(json, "filteredPrefixCounter",
14115 filtered_count);
14116
14117 /*
14118 * These fields only give up ownership to `json` when `header1`
14119 * is used (set to zero). See code in `show_adj_route` and
14120 * `show_adj_route_header`.
14121 */
14122 if (header1 == 1) {
14123 json_object_free(json_scode);
14124 json_object_free(json_ocode);
14125 }
14126
14127 vty_json(vty, json);
14128 } else if (output_count > 0) {
14129 if (filtered_count > 0)
14130 vty_out(vty,
14131 "\nTotal number of prefixes %ld (%ld filtered)\n",
14132 output_count, filtered_count);
14133 else
14134 vty_out(vty, "\nTotal number of prefixes %ld\n",
14135 output_count);
14136 }
14137
14138 return CMD_SUCCESS;
14139 }
14140
14141 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14142 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14143 "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]",
14144 SHOW_STR
14145 IP_STR
14146 BGP_STR
14147 BGP_INSTANCE_HELP_STR
14148 BGP_AFI_HELP_STR
14149 BGP_SAFI_WITH_LABEL_HELP_STR
14150 "Detailed information on TCP and BGP neighbor connections\n"
14151 "Neighbor to display information about\n"
14152 "Neighbor to display information about\n"
14153 "Neighbor on BGP configured interface\n"
14154 "Display the routes selected by best path\n"
14155 JSON_STR
14156 "Increase table width for longer prefixes\n")
14157 {
14158 afi_t afi = AFI_IP6;
14159 safi_t safi = SAFI_UNICAST;
14160 char *rmap_name = NULL;
14161 char *peerstr = NULL;
14162 struct bgp *bgp = NULL;
14163 struct peer *peer;
14164 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14165 int idx = 0;
14166 uint16_t show_flags = 0;
14167
14168 if (uj)
14169 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14170
14171 if (wide)
14172 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14173
14174 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14175 &bgp, uj);
14176
14177 if (!idx)
14178 return CMD_WARNING;
14179
14180 argv_find(argv, argc, "neighbors", &idx);
14181 peerstr = argv[++idx]->arg;
14182
14183 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14184 if (!peer)
14185 return CMD_WARNING;
14186
14187 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14188 show_flags);
14189 }
14190
14191 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
14192 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14193 "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]",
14194 SHOW_STR
14195 IP_STR
14196 BGP_STR
14197 BGP_INSTANCE_HELP_STR
14198 BGP_AFI_HELP_STR
14199 BGP_SAFI_WITH_LABEL_HELP_STR
14200 "Display the entries for all address families\n"
14201 "Detailed information on TCP and BGP neighbor connections\n"
14202 "Neighbor to display information about\n"
14203 "Neighbor to display information about\n"
14204 "Neighbor on BGP configured interface\n"
14205 "Display the routes advertised to a BGP neighbor\n"
14206 "Display the received routes from neighbor\n"
14207 "Display the filtered routes received from neighbor\n"
14208 "Route-map to modify the attributes\n"
14209 "Name of the route map\n"
14210 JSON_STR
14211 "Increase table width for longer prefixes\n")
14212 {
14213 afi_t afi = AFI_IP6;
14214 safi_t safi = SAFI_UNICAST;
14215 char *peerstr = NULL;
14216 struct bgp *bgp = NULL;
14217 struct peer *peer;
14218 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14219 int idx = 0;
14220 bool first = true;
14221 uint16_t show_flags = 0;
14222 struct listnode *node;
14223 struct bgp *abgp;
14224
14225 if (uj) {
14226 argc--;
14227 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14228 }
14229
14230 if (all) {
14231 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14232 if (argv_find(argv, argc, "ipv4", &idx))
14233 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14234
14235 if (argv_find(argv, argc, "ipv6", &idx))
14236 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14237 }
14238
14239 if (wide)
14240 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14241
14242 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14243 &bgp, uj);
14244 if (!idx)
14245 return CMD_WARNING;
14246
14247 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14248 argv_find(argv, argc, "neighbors", &idx);
14249 peerstr = argv[++idx]->arg;
14250
14251 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14252 if (!peer)
14253 return CMD_WARNING;
14254
14255 if (argv_find(argv, argc, "advertised-routes", &idx))
14256 type = bgp_show_adj_route_advertised;
14257 else if (argv_find(argv, argc, "received-routes", &idx))
14258 type = bgp_show_adj_route_received;
14259 else if (argv_find(argv, argc, "filtered-routes", &idx))
14260 type = bgp_show_adj_route_filtered;
14261
14262 if (!all)
14263 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14264 show_flags);
14265 if (uj)
14266 vty_out(vty, "{\n");
14267
14268 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14269 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14270 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14271 : AFI_IP6;
14272 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14273 FOREACH_SAFI (safi) {
14274 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14275 continue;
14276
14277 if (uj) {
14278 if (first)
14279 first = false;
14280 else
14281 vty_out(vty, ",\n");
14282 vty_out(vty, "\"%s\":",
14283 get_afi_safi_str(afi, safi,
14284 true));
14285 } else
14286 vty_out(vty,
14287 "\nFor address family: %s\n",
14288 get_afi_safi_str(afi, safi,
14289 false));
14290
14291 peer_adj_routes(vty, peer, afi, safi, type,
14292 route_map, show_flags);
14293 }
14294 }
14295 } else {
14296 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14297 FOREACH_AFI_SAFI (afi, safi) {
14298 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14299 continue;
14300
14301 if (uj) {
14302 if (first)
14303 first = false;
14304 else
14305 vty_out(vty, ",\n");
14306 vty_out(vty, "\"%s\":",
14307 get_afi_safi_str(afi, safi,
14308 true));
14309 } else
14310 vty_out(vty,
14311 "\nFor address family: %s\n",
14312 get_afi_safi_str(afi, safi,
14313 false));
14314
14315 peer_adj_routes(vty, peer, afi, safi, type,
14316 route_map, show_flags);
14317 }
14318 }
14319 }
14320 if (uj)
14321 vty_out(vty, "}\n");
14322
14323 return CMD_SUCCESS;
14324 }
14325
14326 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14327 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14328 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14329 SHOW_STR
14330 IP_STR
14331 BGP_STR
14332 BGP_INSTANCE_HELP_STR
14333 BGP_AF_STR
14334 BGP_AF_STR
14335 BGP_AF_MODIFIER_STR
14336 "Detailed information on TCP and BGP neighbor connections\n"
14337 "Neighbor to display information about\n"
14338 "Neighbor to display information about\n"
14339 "Neighbor on BGP configured interface\n"
14340 "Display information received from a BGP neighbor\n"
14341 "Display the prefixlist filter\n"
14342 JSON_STR)
14343 {
14344 afi_t afi = AFI_IP6;
14345 safi_t safi = SAFI_UNICAST;
14346 char *peerstr = NULL;
14347 char name[BUFSIZ];
14348 struct peer *peer;
14349 int count;
14350 int idx = 0;
14351 struct bgp *bgp = NULL;
14352 bool uj = use_json(argc, argv);
14353
14354 if (uj)
14355 argc--;
14356
14357 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14358 &bgp, uj);
14359 if (!idx)
14360 return CMD_WARNING;
14361
14362 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14363 argv_find(argv, argc, "neighbors", &idx);
14364 peerstr = argv[++idx]->arg;
14365
14366 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14367 if (!peer)
14368 return CMD_WARNING;
14369
14370 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14371 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14372 if (count) {
14373 if (!uj)
14374 vty_out(vty, "Address Family: %s\n",
14375 get_afi_safi_str(afi, safi, false));
14376 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14377 } else {
14378 if (uj)
14379 vty_out(vty, "{}\n");
14380 else
14381 vty_out(vty, "No functional output\n");
14382 }
14383
14384 return CMD_SUCCESS;
14385 }
14386
14387 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14388 afi_t afi, safi_t safi,
14389 enum bgp_show_type type, bool use_json)
14390 {
14391 uint16_t show_flags = 0;
14392
14393 if (use_json)
14394 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14395
14396 if (!peer || !peer->afc[afi][safi]) {
14397 if (use_json) {
14398 json_object *json_no = NULL;
14399 json_no = json_object_new_object();
14400 json_object_string_add(
14401 json_no, "warning",
14402 "No such neighbor or address family");
14403 vty_out(vty, "%s\n",
14404 json_object_to_json_string(json_no));
14405 json_object_free(json_no);
14406 } else
14407 vty_out(vty, "%% No such neighbor or address family\n");
14408 return CMD_WARNING;
14409 }
14410
14411 /* labeled-unicast routes live in the unicast table */
14412 if (safi == SAFI_LABELED_UNICAST)
14413 safi = SAFI_UNICAST;
14414
14415 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14416 RPKI_NOT_BEING_USED);
14417 }
14418
14419 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14420 show_ip_bgp_flowspec_routes_detailed_cmd,
14421 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14422 SHOW_STR
14423 IP_STR
14424 BGP_STR
14425 BGP_INSTANCE_HELP_STR
14426 BGP_AFI_HELP_STR
14427 "SAFI Flowspec\n"
14428 "Detailed information on flowspec entries\n"
14429 JSON_STR)
14430 {
14431 afi_t afi = AFI_IP6;
14432 safi_t safi = SAFI_UNICAST;
14433 struct bgp *bgp = NULL;
14434 int idx = 0;
14435 bool uj = use_json(argc, argv);
14436 uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
14437
14438 if (uj) {
14439 argc--;
14440 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14441 }
14442
14443 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14444 &bgp, uj);
14445 if (!idx)
14446 return CMD_WARNING;
14447
14448 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14449 show_flags, RPKI_NOT_BEING_USED);
14450 }
14451
14452 DEFUN (show_ip_bgp_neighbor_routes,
14453 show_ip_bgp_neighbor_routes_cmd,
14454 "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]",
14455 SHOW_STR
14456 IP_STR
14457 BGP_STR
14458 BGP_INSTANCE_HELP_STR
14459 BGP_AFI_HELP_STR
14460 BGP_SAFI_WITH_LABEL_HELP_STR
14461 "Detailed information on TCP and BGP neighbor connections\n"
14462 "Neighbor to display information about\n"
14463 "Neighbor to display information about\n"
14464 "Neighbor on BGP configured interface\n"
14465 "Display flap statistics of the routes learned from neighbor\n"
14466 "Display the dampened routes received from neighbor\n"
14467 "Display routes learned from neighbor\n"
14468 JSON_STR)
14469 {
14470 char *peerstr = NULL;
14471 struct bgp *bgp = NULL;
14472 afi_t afi = AFI_IP6;
14473 safi_t safi = SAFI_UNICAST;
14474 struct peer *peer;
14475 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14476 int idx = 0;
14477 bool uj = use_json(argc, argv);
14478
14479 if (uj)
14480 argc--;
14481
14482 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14483 &bgp, uj);
14484 if (!idx)
14485 return CMD_WARNING;
14486
14487 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14488 argv_find(argv, argc, "neighbors", &idx);
14489 peerstr = argv[++idx]->arg;
14490
14491 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14492 if (!peer)
14493 return CMD_WARNING;
14494
14495 if (argv_find(argv, argc, "flap-statistics", &idx))
14496 sh_type = bgp_show_type_flap_neighbor;
14497 else if (argv_find(argv, argc, "dampened-routes", &idx))
14498 sh_type = bgp_show_type_damp_neighbor;
14499 else if (argv_find(argv, argc, "routes", &idx))
14500 sh_type = bgp_show_type_neighbor;
14501
14502 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14503 }
14504
14505 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14506
14507 struct bgp_distance {
14508 /* Distance value for the IP source prefix. */
14509 uint8_t distance;
14510
14511 /* Name of the access-list to be matched. */
14512 char *access_list;
14513 };
14514
14515 DEFUN (show_bgp_afi_vpn_rd_route,
14516 show_bgp_afi_vpn_rd_route_cmd,
14517 "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]",
14518 SHOW_STR
14519 BGP_STR
14520 BGP_AFI_HELP_STR
14521 BGP_AF_MODIFIER_STR
14522 "Display information for a route distinguisher\n"
14523 "Route Distinguisher\n"
14524 "All Route Distinguishers\n"
14525 "Network in the BGP routing table to display\n"
14526 "Network in the BGP routing table to display\n"
14527 JSON_STR)
14528 {
14529 int ret;
14530 struct prefix_rd prd;
14531 afi_t afi = AFI_MAX;
14532 int idx = 0;
14533
14534 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14535 vty_out(vty, "%% Malformed Address Family\n");
14536 return CMD_WARNING;
14537 }
14538
14539 if (!strcmp(argv[5]->arg, "all"))
14540 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14541 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14542 RPKI_NOT_BEING_USED,
14543 use_json(argc, argv));
14544
14545 ret = str2prefix_rd(argv[5]->arg, &prd);
14546 if (!ret) {
14547 vty_out(vty, "%% Malformed Route Distinguisher\n");
14548 return CMD_WARNING;
14549 }
14550
14551 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14552 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14553 use_json(argc, argv));
14554 }
14555
14556 static struct bgp_distance *bgp_distance_new(void)
14557 {
14558 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14559 }
14560
14561 static void bgp_distance_free(struct bgp_distance *bdistance)
14562 {
14563 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14564 }
14565
14566 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14567 const char *ip_str, const char *access_list_str)
14568 {
14569 int ret;
14570 afi_t afi;
14571 safi_t safi;
14572 struct prefix p;
14573 uint8_t distance;
14574 struct bgp_dest *dest;
14575 struct bgp_distance *bdistance;
14576
14577 afi = bgp_node_afi(vty);
14578 safi = bgp_node_safi(vty);
14579
14580 ret = str2prefix(ip_str, &p);
14581 if (ret == 0) {
14582 vty_out(vty, "Malformed prefix\n");
14583 return CMD_WARNING_CONFIG_FAILED;
14584 }
14585
14586 distance = atoi(distance_str);
14587
14588 /* Get BGP distance node. */
14589 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14590 bdistance = bgp_dest_get_bgp_distance_info(dest);
14591 if (bdistance)
14592 bgp_dest_unlock_node(dest);
14593 else {
14594 bdistance = bgp_distance_new();
14595 bgp_dest_set_bgp_distance_info(dest, bdistance);
14596 }
14597
14598 /* Set distance value. */
14599 bdistance->distance = distance;
14600
14601 /* Reset access-list configuration. */
14602 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14603 if (access_list_str)
14604 bdistance->access_list =
14605 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14606
14607 return CMD_SUCCESS;
14608 }
14609
14610 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14611 const char *ip_str, const char *access_list_str)
14612 {
14613 int ret;
14614 afi_t afi;
14615 safi_t safi;
14616 struct prefix p;
14617 int distance;
14618 struct bgp_dest *dest;
14619 struct bgp_distance *bdistance;
14620
14621 afi = bgp_node_afi(vty);
14622 safi = bgp_node_safi(vty);
14623
14624 ret = str2prefix(ip_str, &p);
14625 if (ret == 0) {
14626 vty_out(vty, "Malformed prefix\n");
14627 return CMD_WARNING_CONFIG_FAILED;
14628 }
14629
14630 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14631 if (!dest) {
14632 vty_out(vty, "Can't find specified prefix\n");
14633 return CMD_WARNING_CONFIG_FAILED;
14634 }
14635
14636 bdistance = bgp_dest_get_bgp_distance_info(dest);
14637 distance = atoi(distance_str);
14638
14639 if (bdistance->distance != distance) {
14640 vty_out(vty, "Distance does not match configured\n");
14641 bgp_dest_unlock_node(dest);
14642 return CMD_WARNING_CONFIG_FAILED;
14643 }
14644
14645 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14646 bgp_distance_free(bdistance);
14647
14648 bgp_dest_set_bgp_path_info(dest, NULL);
14649 bgp_dest_unlock_node(dest);
14650 bgp_dest_unlock_node(dest);
14651
14652 return CMD_SUCCESS;
14653 }
14654
14655 /* Apply BGP information to distance method. */
14656 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14657 afi_t afi, safi_t safi, struct bgp *bgp)
14658 {
14659 struct bgp_dest *dest;
14660 struct prefix q = {0};
14661 struct peer *peer;
14662 struct bgp_distance *bdistance;
14663 struct access_list *alist;
14664 struct bgp_static *bgp_static;
14665
14666 if (!bgp)
14667 return 0;
14668
14669 peer = pinfo->peer;
14670
14671 if (pinfo->attr->distance)
14672 return pinfo->attr->distance;
14673
14674 /* Check source address.
14675 * Note: for aggregate route, peer can have unspec af type.
14676 */
14677 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14678 && !sockunion2hostprefix(&peer->su, &q))
14679 return 0;
14680
14681 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14682 if (dest) {
14683 bdistance = bgp_dest_get_bgp_distance_info(dest);
14684 bgp_dest_unlock_node(dest);
14685
14686 if (bdistance->access_list) {
14687 alist = access_list_lookup(afi, bdistance->access_list);
14688 if (alist
14689 && access_list_apply(alist, p) == FILTER_PERMIT)
14690 return bdistance->distance;
14691 } else
14692 return bdistance->distance;
14693 }
14694
14695 /* Backdoor check. */
14696 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14697 if (dest) {
14698 bgp_static = bgp_dest_get_bgp_static_info(dest);
14699 bgp_dest_unlock_node(dest);
14700
14701 if (bgp_static->backdoor) {
14702 if (bgp->distance_local[afi][safi])
14703 return bgp->distance_local[afi][safi];
14704 else
14705 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14706 }
14707 }
14708
14709 if (peer->sort == BGP_PEER_EBGP) {
14710 if (bgp->distance_ebgp[afi][safi])
14711 return bgp->distance_ebgp[afi][safi];
14712 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14713 } else if (peer->sort == BGP_PEER_IBGP) {
14714 if (bgp->distance_ibgp[afi][safi])
14715 return bgp->distance_ibgp[afi][safi];
14716 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14717 } else {
14718 if (bgp->distance_local[afi][safi])
14719 return bgp->distance_local[afi][safi];
14720 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14721 }
14722 }
14723
14724 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14725 * we should tell ZEBRA update the routes for a specific
14726 * AFI/SAFI to reflect changes in RIB.
14727 */
14728 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14729 afi_t update_afi,
14730 safi_t update_safi)
14731 {
14732 afi_t afi;
14733 safi_t safi;
14734
14735 FOREACH_AFI_SAFI (afi, safi) {
14736 if (!bgp_fibupd_safi(safi))
14737 continue;
14738
14739 if (afi != update_afi && safi != update_safi)
14740 continue;
14741
14742 if (BGP_DEBUG(zebra, ZEBRA))
14743 zlog_debug(
14744 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14745 __func__, afi, safi);
14746 bgp_zebra_announce_table(bgp, afi, safi);
14747 }
14748 }
14749
14750 DEFUN (bgp_distance,
14751 bgp_distance_cmd,
14752 "distance bgp (1-255) (1-255) (1-255)",
14753 "Define an administrative distance\n"
14754 "BGP distance\n"
14755 "Distance for routes external to the AS\n"
14756 "Distance for routes internal to the AS\n"
14757 "Distance for local routes\n")
14758 {
14759 VTY_DECLVAR_CONTEXT(bgp, bgp);
14760 int idx_number = 2;
14761 int idx_number_2 = 3;
14762 int idx_number_3 = 4;
14763 int distance_ebgp = atoi(argv[idx_number]->arg);
14764 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14765 int distance_local = atoi(argv[idx_number_3]->arg);
14766 afi_t afi;
14767 safi_t safi;
14768
14769 afi = bgp_node_afi(vty);
14770 safi = bgp_node_safi(vty);
14771
14772 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14773 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14774 || bgp->distance_local[afi][safi] != distance_local) {
14775 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14776 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14777 bgp->distance_local[afi][safi] = distance_local;
14778 bgp_announce_routes_distance_update(bgp, afi, safi);
14779 }
14780 return CMD_SUCCESS;
14781 }
14782
14783 DEFUN (no_bgp_distance,
14784 no_bgp_distance_cmd,
14785 "no distance bgp [(1-255) (1-255) (1-255)]",
14786 NO_STR
14787 "Define an administrative distance\n"
14788 "BGP distance\n"
14789 "Distance for routes external to the AS\n"
14790 "Distance for routes internal to the AS\n"
14791 "Distance for local routes\n")
14792 {
14793 VTY_DECLVAR_CONTEXT(bgp, bgp);
14794 afi_t afi;
14795 safi_t safi;
14796
14797 afi = bgp_node_afi(vty);
14798 safi = bgp_node_safi(vty);
14799
14800 if (bgp->distance_ebgp[afi][safi] != 0
14801 || bgp->distance_ibgp[afi][safi] != 0
14802 || bgp->distance_local[afi][safi] != 0) {
14803 bgp->distance_ebgp[afi][safi] = 0;
14804 bgp->distance_ibgp[afi][safi] = 0;
14805 bgp->distance_local[afi][safi] = 0;
14806 bgp_announce_routes_distance_update(bgp, afi, safi);
14807 }
14808 return CMD_SUCCESS;
14809 }
14810
14811
14812 DEFUN (bgp_distance_source,
14813 bgp_distance_source_cmd,
14814 "distance (1-255) A.B.C.D/M",
14815 "Define an administrative distance\n"
14816 "Administrative distance\n"
14817 "IP source prefix\n")
14818 {
14819 int idx_number = 1;
14820 int idx_ipv4_prefixlen = 2;
14821 bgp_distance_set(vty, argv[idx_number]->arg,
14822 argv[idx_ipv4_prefixlen]->arg, NULL);
14823 return CMD_SUCCESS;
14824 }
14825
14826 DEFUN (no_bgp_distance_source,
14827 no_bgp_distance_source_cmd,
14828 "no distance (1-255) A.B.C.D/M",
14829 NO_STR
14830 "Define an administrative distance\n"
14831 "Administrative distance\n"
14832 "IP source prefix\n")
14833 {
14834 int idx_number = 2;
14835 int idx_ipv4_prefixlen = 3;
14836 bgp_distance_unset(vty, argv[idx_number]->arg,
14837 argv[idx_ipv4_prefixlen]->arg, NULL);
14838 return CMD_SUCCESS;
14839 }
14840
14841 DEFUN (bgp_distance_source_access_list,
14842 bgp_distance_source_access_list_cmd,
14843 "distance (1-255) A.B.C.D/M WORD",
14844 "Define an administrative distance\n"
14845 "Administrative distance\n"
14846 "IP source prefix\n"
14847 "Access list name\n")
14848 {
14849 int idx_number = 1;
14850 int idx_ipv4_prefixlen = 2;
14851 int idx_word = 3;
14852 bgp_distance_set(vty, argv[idx_number]->arg,
14853 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14854 return CMD_SUCCESS;
14855 }
14856
14857 DEFUN (no_bgp_distance_source_access_list,
14858 no_bgp_distance_source_access_list_cmd,
14859 "no distance (1-255) A.B.C.D/M WORD",
14860 NO_STR
14861 "Define an administrative distance\n"
14862 "Administrative distance\n"
14863 "IP source prefix\n"
14864 "Access list name\n")
14865 {
14866 int idx_number = 2;
14867 int idx_ipv4_prefixlen = 3;
14868 int idx_word = 4;
14869 bgp_distance_unset(vty, argv[idx_number]->arg,
14870 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14871 return CMD_SUCCESS;
14872 }
14873
14874 DEFUN (ipv6_bgp_distance_source,
14875 ipv6_bgp_distance_source_cmd,
14876 "distance (1-255) X:X::X:X/M",
14877 "Define an administrative distance\n"
14878 "Administrative distance\n"
14879 "IP source prefix\n")
14880 {
14881 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
14882 return CMD_SUCCESS;
14883 }
14884
14885 DEFUN (no_ipv6_bgp_distance_source,
14886 no_ipv6_bgp_distance_source_cmd,
14887 "no distance (1-255) X:X::X:X/M",
14888 NO_STR
14889 "Define an administrative distance\n"
14890 "Administrative distance\n"
14891 "IP source prefix\n")
14892 {
14893 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
14894 return CMD_SUCCESS;
14895 }
14896
14897 DEFUN (ipv6_bgp_distance_source_access_list,
14898 ipv6_bgp_distance_source_access_list_cmd,
14899 "distance (1-255) X:X::X:X/M WORD",
14900 "Define an administrative distance\n"
14901 "Administrative distance\n"
14902 "IP source prefix\n"
14903 "Access list name\n")
14904 {
14905 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
14906 return CMD_SUCCESS;
14907 }
14908
14909 DEFUN (no_ipv6_bgp_distance_source_access_list,
14910 no_ipv6_bgp_distance_source_access_list_cmd,
14911 "no distance (1-255) X:X::X:X/M WORD",
14912 NO_STR
14913 "Define an administrative distance\n"
14914 "Administrative distance\n"
14915 "IP source prefix\n"
14916 "Access list name\n")
14917 {
14918 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
14919 return CMD_SUCCESS;
14920 }
14921
14922 DEFUN (bgp_damp_set,
14923 bgp_damp_set_cmd,
14924 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14925 "BGP Specific commands\n"
14926 "Enable route-flap dampening\n"
14927 "Half-life time for the penalty\n"
14928 "Value to start reusing a route\n"
14929 "Value to start suppressing a route\n"
14930 "Maximum duration to suppress a stable route\n")
14931 {
14932 VTY_DECLVAR_CONTEXT(bgp, bgp);
14933 int idx_half_life = 2;
14934 int idx_reuse = 3;
14935 int idx_suppress = 4;
14936 int idx_max_suppress = 5;
14937 int half = DEFAULT_HALF_LIFE * 60;
14938 int reuse = DEFAULT_REUSE;
14939 int suppress = DEFAULT_SUPPRESS;
14940 int max = 4 * half;
14941
14942 if (argc == 6) {
14943 half = atoi(argv[idx_half_life]->arg) * 60;
14944 reuse = atoi(argv[idx_reuse]->arg);
14945 suppress = atoi(argv[idx_suppress]->arg);
14946 max = atoi(argv[idx_max_suppress]->arg) * 60;
14947 } else if (argc == 3) {
14948 half = atoi(argv[idx_half_life]->arg) * 60;
14949 max = 4 * half;
14950 }
14951
14952 /*
14953 * These can't be 0 but our SA doesn't understand the
14954 * way our cli is constructed
14955 */
14956 assert(reuse);
14957 assert(half);
14958 if (suppress < reuse) {
14959 vty_out(vty,
14960 "Suppress value cannot be less than reuse value \n");
14961 return 0;
14962 }
14963
14964 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
14965 reuse, suppress, max);
14966 }
14967
14968 DEFUN (bgp_damp_unset,
14969 bgp_damp_unset_cmd,
14970 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14971 NO_STR
14972 "BGP Specific commands\n"
14973 "Enable route-flap dampening\n"
14974 "Half-life time for the penalty\n"
14975 "Value to start reusing a route\n"
14976 "Value to start suppressing a route\n"
14977 "Maximum duration to suppress a stable route\n")
14978 {
14979 VTY_DECLVAR_CONTEXT(bgp, bgp);
14980 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
14981 }
14982
14983 /* Display specified route of BGP table. */
14984 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14985 const char *ip_str, afi_t afi, safi_t safi,
14986 struct prefix_rd *prd, int prefix_check)
14987 {
14988 int ret;
14989 struct prefix match;
14990 struct bgp_dest *dest;
14991 struct bgp_dest *rm;
14992 struct bgp_path_info *pi;
14993 struct bgp_path_info *pi_temp;
14994 struct bgp *bgp;
14995 struct bgp_table *table;
14996
14997 /* BGP structure lookup. */
14998 if (view_name) {
14999 bgp = bgp_lookup_by_name(view_name);
15000 if (bgp == NULL) {
15001 vty_out(vty, "%% Can't find BGP instance %s\n",
15002 view_name);
15003 return CMD_WARNING;
15004 }
15005 } else {
15006 bgp = bgp_get_default();
15007 if (bgp == NULL) {
15008 vty_out(vty, "%% No BGP process is configured\n");
15009 return CMD_WARNING;
15010 }
15011 }
15012
15013 /* Check IP address argument. */
15014 ret = str2prefix(ip_str, &match);
15015 if (!ret) {
15016 vty_out(vty, "%% address is malformed\n");
15017 return CMD_WARNING;
15018 }
15019
15020 match.family = afi2family(afi);
15021
15022 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15023 || (safi == SAFI_EVPN)) {
15024 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15025 dest = bgp_route_next(dest)) {
15026 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15027
15028 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15029 continue;
15030 table = bgp_dest_get_bgp_table_info(dest);
15031 if (!table)
15032 continue;
15033 rm = bgp_node_match(table, &match);
15034 if (rm == NULL)
15035 continue;
15036
15037 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15038
15039 if (!prefix_check
15040 || rm_p->prefixlen == match.prefixlen) {
15041 pi = bgp_dest_get_bgp_path_info(rm);
15042 while (pi) {
15043 if (pi->extra && pi->extra->damp_info) {
15044 pi_temp = pi->next;
15045 bgp_damp_info_free(
15046 pi->extra->damp_info,
15047 1, afi, safi);
15048 pi = pi_temp;
15049 } else
15050 pi = pi->next;
15051 }
15052 }
15053
15054 bgp_dest_unlock_node(rm);
15055 }
15056 } else {
15057 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15058 if (dest != NULL) {
15059 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15060
15061 if (!prefix_check
15062 || dest_p->prefixlen == match.prefixlen) {
15063 pi = bgp_dest_get_bgp_path_info(dest);
15064 while (pi) {
15065 if (pi->extra && pi->extra->damp_info) {
15066 pi_temp = pi->next;
15067 bgp_damp_info_free(
15068 pi->extra->damp_info,
15069 1, afi, safi);
15070 pi = pi_temp;
15071 } else
15072 pi = pi->next;
15073 }
15074 }
15075
15076 bgp_dest_unlock_node(dest);
15077 }
15078 }
15079
15080 return CMD_SUCCESS;
15081 }
15082
15083 DEFUN (clear_ip_bgp_dampening,
15084 clear_ip_bgp_dampening_cmd,
15085 "clear ip bgp dampening",
15086 CLEAR_STR
15087 IP_STR
15088 BGP_STR
15089 "Clear route flap dampening information\n")
15090 {
15091 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15092 return CMD_SUCCESS;
15093 }
15094
15095 DEFUN (clear_ip_bgp_dampening_prefix,
15096 clear_ip_bgp_dampening_prefix_cmd,
15097 "clear ip bgp dampening A.B.C.D/M",
15098 CLEAR_STR
15099 IP_STR
15100 BGP_STR
15101 "Clear route flap dampening information\n"
15102 "IPv4 prefix\n")
15103 {
15104 int idx_ipv4_prefixlen = 4;
15105 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15106 AFI_IP, SAFI_UNICAST, NULL, 1);
15107 }
15108
15109 DEFUN (clear_ip_bgp_dampening_address,
15110 clear_ip_bgp_dampening_address_cmd,
15111 "clear ip bgp dampening A.B.C.D",
15112 CLEAR_STR
15113 IP_STR
15114 BGP_STR
15115 "Clear route flap dampening information\n"
15116 "Network to clear damping information\n")
15117 {
15118 int idx_ipv4 = 4;
15119 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15120 SAFI_UNICAST, NULL, 0);
15121 }
15122
15123 DEFUN (clear_ip_bgp_dampening_address_mask,
15124 clear_ip_bgp_dampening_address_mask_cmd,
15125 "clear ip bgp dampening A.B.C.D A.B.C.D",
15126 CLEAR_STR
15127 IP_STR
15128 BGP_STR
15129 "Clear route flap dampening information\n"
15130 "Network to clear damping information\n"
15131 "Network mask\n")
15132 {
15133 int idx_ipv4 = 4;
15134 int idx_ipv4_2 = 5;
15135 int ret;
15136 char prefix_str[BUFSIZ];
15137
15138 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15139 prefix_str, sizeof(prefix_str));
15140 if (!ret) {
15141 vty_out(vty, "%% Inconsistent address and mask\n");
15142 return CMD_WARNING;
15143 }
15144
15145 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15146 NULL, 0);
15147 }
15148
15149 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15150 {
15151 struct vty *vty = arg;
15152 struct peer *peer = bucket->data;
15153
15154 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15155 }
15156
15157 DEFUN (show_bgp_listeners,
15158 show_bgp_listeners_cmd,
15159 "show bgp listeners",
15160 SHOW_STR
15161 BGP_STR
15162 "Display Listen Sockets and who created them\n")
15163 {
15164 bgp_dump_listener_info(vty);
15165
15166 return CMD_SUCCESS;
15167 }
15168
15169 DEFUN (show_bgp_peerhash,
15170 show_bgp_peerhash_cmd,
15171 "show bgp peerhash",
15172 SHOW_STR
15173 BGP_STR
15174 "Display information about the BGP peerhash\n")
15175 {
15176 struct list *instances = bm->bgp;
15177 struct listnode *node;
15178 struct bgp *bgp;
15179
15180 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15181 vty_out(vty, "BGP: %s\n", bgp->name);
15182 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15183 vty);
15184 }
15185
15186 return CMD_SUCCESS;
15187 }
15188
15189 /* also used for encap safi */
15190 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15191 afi_t afi, safi_t safi)
15192 {
15193 struct bgp_dest *pdest;
15194 struct bgp_dest *dest;
15195 struct bgp_table *table;
15196 const struct prefix *p;
15197 const struct prefix_rd *prd;
15198 struct bgp_static *bgp_static;
15199 mpls_label_t label;
15200 char rdbuf[RD_ADDRSTRLEN];
15201
15202 /* Network configuration. */
15203 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15204 pdest = bgp_route_next(pdest)) {
15205 table = bgp_dest_get_bgp_table_info(pdest);
15206 if (!table)
15207 continue;
15208
15209 for (dest = bgp_table_top(table); dest;
15210 dest = bgp_route_next(dest)) {
15211 bgp_static = bgp_dest_get_bgp_static_info(dest);
15212 if (bgp_static == NULL)
15213 continue;
15214
15215 p = bgp_dest_get_prefix(dest);
15216 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15217 pdest);
15218
15219 /* "network" configuration display. */
15220 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
15221 label = decode_label(&bgp_static->label);
15222
15223 vty_out(vty, " network %pFX rd %s", p, rdbuf);
15224 if (safi == SAFI_MPLS_VPN)
15225 vty_out(vty, " label %u", label);
15226
15227 if (bgp_static->rmap.name)
15228 vty_out(vty, " route-map %s",
15229 bgp_static->rmap.name);
15230
15231 if (bgp_static->backdoor)
15232 vty_out(vty, " backdoor");
15233
15234 vty_out(vty, "\n");
15235 }
15236 }
15237 }
15238
15239 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15240 afi_t afi, safi_t safi)
15241 {
15242 struct bgp_dest *pdest;
15243 struct bgp_dest *dest;
15244 struct bgp_table *table;
15245 const struct prefix *p;
15246 const struct prefix_rd *prd;
15247 struct bgp_static *bgp_static;
15248 char buf[PREFIX_STRLEN * 2];
15249 char buf2[SU_ADDRSTRLEN];
15250 char rdbuf[RD_ADDRSTRLEN];
15251 char esi_buf[ESI_STR_LEN];
15252
15253 /* Network configuration. */
15254 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15255 pdest = bgp_route_next(pdest)) {
15256 table = bgp_dest_get_bgp_table_info(pdest);
15257 if (!table)
15258 continue;
15259
15260 for (dest = bgp_table_top(table); dest;
15261 dest = bgp_route_next(dest)) {
15262 bgp_static = bgp_dest_get_bgp_static_info(dest);
15263 if (bgp_static == NULL)
15264 continue;
15265
15266 char *macrouter = NULL;
15267
15268 if (bgp_static->router_mac)
15269 macrouter = prefix_mac2str(
15270 bgp_static->router_mac, NULL, 0);
15271 if (bgp_static->eth_s_id)
15272 esi_to_str(bgp_static->eth_s_id,
15273 esi_buf, sizeof(esi_buf));
15274 p = bgp_dest_get_prefix(dest);
15275 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15276
15277 /* "network" configuration display. */
15278 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
15279 if (p->u.prefix_evpn.route_type == 5) {
15280 char local_buf[PREFIX_STRLEN];
15281 uint8_t family = is_evpn_prefix_ipaddr_v4((
15282 struct prefix_evpn *)p)
15283 ? AF_INET
15284 : AF_INET6;
15285 inet_ntop(family,
15286 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15287 local_buf, PREFIX_STRLEN);
15288 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15289 p->u.prefix_evpn.prefix_addr
15290 .ip_prefix_length);
15291 } else {
15292 prefix2str(p, buf, sizeof(buf));
15293 }
15294
15295 if (bgp_static->gatewayIp.family == AF_INET
15296 || bgp_static->gatewayIp.family == AF_INET6)
15297 inet_ntop(bgp_static->gatewayIp.family,
15298 &bgp_static->gatewayIp.u.prefix, buf2,
15299 sizeof(buf2));
15300 vty_out(vty,
15301 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15302 buf, rdbuf,
15303 p->u.prefix_evpn.prefix_addr.eth_tag,
15304 decode_label(&bgp_static->label), esi_buf, buf2,
15305 macrouter);
15306
15307 XFREE(MTYPE_TMP, macrouter);
15308 }
15309 }
15310 }
15311
15312 /* Configuration of static route announcement and aggregate
15313 information. */
15314 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15315 safi_t safi)
15316 {
15317 struct bgp_dest *dest;
15318 const struct prefix *p;
15319 struct bgp_static *bgp_static;
15320 struct bgp_aggregate *bgp_aggregate;
15321
15322 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15323 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15324 return;
15325 }
15326
15327 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15328 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15329 return;
15330 }
15331
15332 /* Network configuration. */
15333 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15334 dest = bgp_route_next(dest)) {
15335 bgp_static = bgp_dest_get_bgp_static_info(dest);
15336 if (bgp_static == NULL)
15337 continue;
15338
15339 p = bgp_dest_get_prefix(dest);
15340
15341 vty_out(vty, " network %pFX", p);
15342
15343 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15344 vty_out(vty, " label-index %u",
15345 bgp_static->label_index);
15346
15347 if (bgp_static->rmap.name)
15348 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15349
15350 if (bgp_static->backdoor)
15351 vty_out(vty, " backdoor");
15352
15353 vty_out(vty, "\n");
15354 }
15355
15356 /* Aggregate-address configuration. */
15357 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15358 dest = bgp_route_next(dest)) {
15359 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15360 if (bgp_aggregate == NULL)
15361 continue;
15362
15363 p = bgp_dest_get_prefix(dest);
15364
15365 vty_out(vty, " aggregate-address %pFX", p);
15366
15367 if (bgp_aggregate->as_set)
15368 vty_out(vty, " as-set");
15369
15370 if (bgp_aggregate->summary_only)
15371 vty_out(vty, " summary-only");
15372
15373 if (bgp_aggregate->rmap.name)
15374 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15375
15376 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15377 vty_out(vty, " origin %s",
15378 bgp_origin2str(bgp_aggregate->origin));
15379
15380 if (bgp_aggregate->match_med)
15381 vty_out(vty, " matching-MED-only");
15382
15383 if (bgp_aggregate->suppress_map_name)
15384 vty_out(vty, " suppress-map %s",
15385 bgp_aggregate->suppress_map_name);
15386
15387 vty_out(vty, "\n");
15388 }
15389 }
15390
15391 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15392 safi_t safi)
15393 {
15394 struct bgp_dest *dest;
15395 struct bgp_distance *bdistance;
15396
15397 /* Distance configuration. */
15398 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15399 && bgp->distance_local[afi][safi]
15400 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15401 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15402 || bgp->distance_local[afi][safi]
15403 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15404 vty_out(vty, " distance bgp %d %d %d\n",
15405 bgp->distance_ebgp[afi][safi],
15406 bgp->distance_ibgp[afi][safi],
15407 bgp->distance_local[afi][safi]);
15408 }
15409
15410 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15411 dest = bgp_route_next(dest)) {
15412 bdistance = bgp_dest_get_bgp_distance_info(dest);
15413 if (bdistance != NULL)
15414 vty_out(vty, " distance %d %pBD %s\n",
15415 bdistance->distance, dest,
15416 bdistance->access_list ? bdistance->access_list
15417 : "");
15418 }
15419 }
15420
15421 /* Allocate routing table structure and install commands. */
15422 void bgp_route_init(void)
15423 {
15424 afi_t afi;
15425 safi_t safi;
15426
15427 /* Init BGP distance table. */
15428 FOREACH_AFI_SAFI (afi, safi)
15429 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15430
15431 /* IPv4 BGP commands. */
15432 install_element(BGP_NODE, &bgp_table_map_cmd);
15433 install_element(BGP_NODE, &bgp_network_cmd);
15434 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15435
15436 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15437
15438 /* IPv4 unicast configuration. */
15439 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15440 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15441 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15442
15443 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15444
15445 /* IPv4 multicast configuration. */
15446 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15447 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15448 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15449 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15450
15451 /* IPv4 labeled-unicast configuration. */
15452 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15453 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15454
15455 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15456 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15457 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15458 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15459 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15460 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15461 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15462 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15463
15464 install_element(VIEW_NODE,
15465 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15466 install_element(VIEW_NODE,
15467 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15468 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15469 install_element(VIEW_NODE,
15470 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15471 #ifdef KEEP_OLD_VPN_COMMANDS
15472 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15473 #endif /* KEEP_OLD_VPN_COMMANDS */
15474 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15475 install_element(VIEW_NODE,
15476 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15477
15478 /* BGP dampening clear commands */
15479 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15480 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15481
15482 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15483 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15484
15485 /* prefix count */
15486 install_element(ENABLE_NODE,
15487 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15488 #ifdef KEEP_OLD_VPN_COMMANDS
15489 install_element(ENABLE_NODE,
15490 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15491 #endif /* KEEP_OLD_VPN_COMMANDS */
15492
15493 /* New config IPv6 BGP commands. */
15494 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15495 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15496 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15497
15498 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15499
15500 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15501
15502 /* IPv6 labeled unicast address family. */
15503 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15504 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15505
15506 install_element(BGP_NODE, &bgp_distance_cmd);
15507 install_element(BGP_NODE, &no_bgp_distance_cmd);
15508 install_element(BGP_NODE, &bgp_distance_source_cmd);
15509 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15510 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15511 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15512 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15513 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15514 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15515 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15516 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15517 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15518 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15519 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15520 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15521 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15522 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15523 install_element(BGP_IPV4M_NODE,
15524 &no_bgp_distance_source_access_list_cmd);
15525 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15526 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15527 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15528 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15529 install_element(BGP_IPV6_NODE,
15530 &ipv6_bgp_distance_source_access_list_cmd);
15531 install_element(BGP_IPV6_NODE,
15532 &no_ipv6_bgp_distance_source_access_list_cmd);
15533 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15534 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15535 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15536 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15537 install_element(BGP_IPV6M_NODE,
15538 &ipv6_bgp_distance_source_access_list_cmd);
15539 install_element(BGP_IPV6M_NODE,
15540 &no_ipv6_bgp_distance_source_access_list_cmd);
15541
15542 /* BGP dampening */
15543 install_element(BGP_NODE, &bgp_damp_set_cmd);
15544 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15545 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15546 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15547 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15548 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15549 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15550 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15551 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15552 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15553 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15554 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15555 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15556 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15557
15558 /* Large Communities */
15559 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15560 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15561
15562 /* show bgp ipv4 flowspec detailed */
15563 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15564
15565 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15566 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15567 }
15568
15569 void bgp_route_finish(void)
15570 {
15571 afi_t afi;
15572 safi_t safi;
15573
15574 FOREACH_AFI_SAFI (afi, safi) {
15575 bgp_table_unlock(bgp_distance_table[afi][safi]);
15576 bgp_distance_table[afi][safi] = NULL;
15577 }
15578 }