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