]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #12094 from patrasar/pimv6_rp_linklocal
[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_orr.h"
76 #include "bgpd/bgp_trace.h"
77 #include "bgpd/bgp_rpki.h"
78
79 #ifdef ENABLE_BGP_VNC
80 #include "bgpd/rfapi/rfapi_backend.h"
81 #include "bgpd/rfapi/vnc_import_bgp.h"
82 #include "bgpd/rfapi/vnc_export_bgp.h"
83 #endif
84 #include "bgpd/bgp_encap_types.h"
85 #include "bgpd/bgp_encap_tlv.h"
86 #include "bgpd/bgp_evpn.h"
87 #include "bgpd/bgp_evpn_mh.h"
88 #include "bgpd/bgp_evpn_vty.h"
89 #include "bgpd/bgp_flowspec.h"
90 #include "bgpd/bgp_flowspec_util.h"
91 #include "bgpd/bgp_pbr.h"
92
93 #ifndef VTYSH_EXTRACT_PL
94 #include "bgpd/bgp_route_clippy.c"
95 #endif
96
97 DEFINE_HOOK(bgp_snmp_update_stats,
98 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
99 (rn, pi, added));
100
101 DEFINE_HOOK(bgp_rpki_prefix_status,
102 (struct peer *peer, struct attr *attr,
103 const struct prefix *prefix),
104 (peer, attr, prefix));
105
106 /* Extern from bgp_dump.c */
107 extern const char *bgp_origin_str[];
108 extern const char *bgp_origin_long_str[];
109
110 /* PMSI strings. */
111 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
112 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
113 static const struct message bgp_pmsi_tnltype_str[] = {
114 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
115 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
116 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
117 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
118 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
119 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
120 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
121 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
122 {0}
123 };
124
125 #define VRFID_NONE_STR "-"
126 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
127
128 DEFINE_HOOK(bgp_process,
129 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
130 struct peer *peer, bool withdraw),
131 (bgp, afi, safi, bn, peer, withdraw));
132
133 /** Test if path is suppressed. */
134 static bool bgp_path_suppressed(struct bgp_path_info *pi)
135 {
136 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
137 return false;
138
139 return listcount(pi->extra->aggr_suppressors) > 0;
140 }
141
142 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
143 safi_t safi, const struct prefix *p,
144 struct prefix_rd *prd)
145 {
146 struct bgp_dest *dest;
147 struct bgp_dest *pdest = NULL;
148
149 assert(table);
150
151 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
152 || (safi == SAFI_EVPN)) {
153 pdest = bgp_node_get(table, (struct prefix *)prd);
154
155 if (!bgp_dest_has_bgp_path_info_data(pdest))
156 bgp_dest_set_bgp_table_info(
157 pdest, bgp_table_init(table->bgp, afi, safi));
158 else
159 bgp_dest_unlock_node(pdest);
160 table = bgp_dest_get_bgp_table_info(pdest);
161 }
162
163 dest = bgp_node_get(table, p);
164
165 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
166 || (safi == SAFI_EVPN))
167 dest->pdest = pdest;
168
169 return dest;
170 }
171
172 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
173 safi_t safi, const struct prefix *p,
174 struct prefix_rd *prd)
175 {
176 struct bgp_dest *dest;
177 struct bgp_dest *pdest = NULL;
178
179 if (!table)
180 return NULL;
181
182 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
183 || (safi == SAFI_EVPN)) {
184 pdest = bgp_node_lookup(table, (struct prefix *)prd);
185 if (!pdest)
186 return NULL;
187
188 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
189 bgp_dest_unlock_node(pdest);
190 return NULL;
191 }
192
193 table = bgp_dest_get_bgp_table_info(pdest);
194 }
195
196 dest = bgp_node_lookup(table, p);
197
198 return dest;
199 }
200
201 /* Allocate bgp_path_info_extra */
202 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
203 {
204 struct bgp_path_info_extra *new;
205 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
206 sizeof(struct bgp_path_info_extra));
207 new->label[0] = MPLS_INVALID_LABEL;
208 new->num_labels = 0;
209 new->bgp_fs_pbr = NULL;
210 new->bgp_fs_iprule = NULL;
211 return new;
212 }
213
214 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
215 {
216 struct bgp_path_info_extra *e;
217
218 if (!extra || !*extra)
219 return;
220
221 e = *extra;
222 if (e->damp_info)
223 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
224 e->damp_info->safi);
225
226 e->damp_info = NULL;
227 if (e->parent) {
228 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
229
230 if (bpi->net) {
231 /* FIXME: since multiple e may have the same e->parent
232 * and e->parent->net is holding a refcount for each
233 * of them, we need to do some fudging here.
234 *
235 * WARNING: if bpi->net->lock drops to 0, bpi may be
236 * freed as well (because bpi->net was holding the
237 * last reference to bpi) => write after free!
238 */
239 unsigned refcount;
240
241 bpi = bgp_path_info_lock(bpi);
242 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
243 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
244 if (!refcount)
245 bpi->net = NULL;
246 bgp_path_info_unlock(bpi);
247 }
248 bgp_path_info_unlock(e->parent);
249 e->parent = NULL;
250 }
251
252 if (e->bgp_orig)
253 bgp_unlock(e->bgp_orig);
254
255 if (e->peer_orig)
256 peer_unlock(e->peer_orig);
257
258 if (e->aggr_suppressors)
259 list_delete(&e->aggr_suppressors);
260
261 if (e->mh_info)
262 bgp_evpn_path_mh_info_free(e->mh_info);
263
264 if ((*extra)->bgp_fs_iprule)
265 list_delete(&((*extra)->bgp_fs_iprule));
266 if ((*extra)->bgp_fs_pbr)
267 list_delete(&((*extra)->bgp_fs_pbr));
268 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
269 }
270
271 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
272 * allocated if required.
273 */
274 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
275 {
276 if (!pi->extra)
277 pi->extra = bgp_path_info_extra_new();
278 return pi->extra;
279 }
280
281 /* Free bgp route information. */
282 static void bgp_path_info_free(struct bgp_path_info *path)
283 {
284 bgp_attr_unintern(&path->attr);
285
286 bgp_unlink_nexthop(path);
287 bgp_path_info_extra_free(&path->extra);
288 bgp_path_info_mpath_free(&path->mpath);
289 if (path->net)
290 bgp_addpath_free_info_data(&path->tx_addpath,
291 &path->net->tx_addpath);
292
293 peer_unlock(path->peer); /* bgp_path_info peer reference */
294
295 XFREE(MTYPE_BGP_ROUTE, path);
296 }
297
298 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
299 {
300 path->lock++;
301 return path;
302 }
303
304 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
305 {
306 assert(path && path->lock > 0);
307 path->lock--;
308
309 if (path->lock == 0) {
310 bgp_path_info_free(path);
311 return NULL;
312 }
313
314 return path;
315 }
316
317 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
318 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
319 {
320 struct peer *peer;
321 struct bgp_path_info *old_pi, *nextpi;
322 bool set_flag = false;
323 struct bgp *bgp = NULL;
324 struct bgp_table *table = NULL;
325 afi_t afi = 0;
326 safi_t safi = 0;
327
328 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
329 * then the route selection is deferred
330 */
331 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
332 return 0;
333
334 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
335 if (BGP_DEBUG(update, UPDATE_OUT))
336 zlog_debug(
337 "Route %pBD is in workqueue and being processed, not deferred.",
338 dest);
339
340 return 0;
341 }
342
343 table = bgp_dest_table(dest);
344 if (table) {
345 bgp = table->bgp;
346 afi = table->afi;
347 safi = table->safi;
348 }
349
350 for (old_pi = bgp_dest_get_bgp_path_info(dest);
351 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
352 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
353 continue;
354
355 /* Route selection is deferred if there is a stale path which
356 * which indicates peer is in restart mode
357 */
358 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
359 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
360 set_flag = true;
361 } else {
362 /* If the peer is graceful restart capable and peer is
363 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
364 */
365 peer = old_pi->peer;
366 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
367 && BGP_PEER_RESTARTING_MODE(peer)
368 && (old_pi
369 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
370 set_flag = true;
371 }
372 }
373 if (set_flag)
374 break;
375 }
376
377 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
378 * is active
379 */
380 if (set_flag && table) {
381 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
382 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
383 bgp->gr_info[afi][safi].gr_deferred++;
384 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
385 if (BGP_DEBUG(update, UPDATE_OUT))
386 zlog_debug("DEFER route %pBD, dest %p", dest,
387 dest);
388 return 0;
389 }
390 }
391 return -1;
392 }
393
394 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
395 {
396 struct bgp_path_info *top;
397
398 top = bgp_dest_get_bgp_path_info(dest);
399
400 pi->next = top;
401 pi->prev = NULL;
402 if (top)
403 top->prev = pi;
404 bgp_dest_set_bgp_path_info(dest, pi);
405
406 bgp_path_info_lock(pi);
407 bgp_dest_lock_node(dest);
408 peer_lock(pi->peer); /* bgp_path_info peer reference */
409 bgp_dest_set_defer_flag(dest, false);
410 hook_call(bgp_snmp_update_stats, dest, pi, true);
411 }
412
413 /* Do the actual removal of info from RIB, for use by bgp_process
414 completion callback *only* */
415 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
416 {
417 if (pi->next)
418 pi->next->prev = pi->prev;
419 if (pi->prev)
420 pi->prev->next = pi->next;
421 else
422 bgp_dest_set_bgp_path_info(dest, pi->next);
423
424 bgp_path_info_mpath_dequeue(pi);
425 bgp_path_info_unlock(pi);
426 hook_call(bgp_snmp_update_stats, dest, pi, false);
427 bgp_dest_unlock_node(dest);
428 }
429
430 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
431 {
432 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
433 /* set of previous already took care of pcount */
434 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
435 }
436
437 /* undo the effects of a previous call to bgp_path_info_delete; typically
438 called when a route is deleted and then quickly re-added before the
439 deletion has been processed */
440 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
441 {
442 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
443 /* unset of previous already took care of pcount */
444 SET_FLAG(pi->flags, BGP_PATH_VALID);
445 }
446
447 /* Adjust pcount as required */
448 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
449 {
450 struct bgp_table *table;
451
452 assert(dest && bgp_dest_table(dest));
453 assert(pi && pi->peer && pi->peer->bgp);
454
455 table = bgp_dest_table(dest);
456
457 if (pi->peer == pi->peer->bgp->peer_self)
458 return;
459
460 if (!BGP_PATH_COUNTABLE(pi)
461 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
462
463 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
464
465 /* slight hack, but more robust against errors. */
466 if (pi->peer->pcount[table->afi][table->safi])
467 pi->peer->pcount[table->afi][table->safi]--;
468 else
469 flog_err(EC_LIB_DEVELOPMENT,
470 "Asked to decrement 0 prefix count for peer");
471 } else if (BGP_PATH_COUNTABLE(pi)
472 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
473 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
474 pi->peer->pcount[table->afi][table->safi]++;
475 }
476 }
477
478 static int bgp_label_index_differs(struct bgp_path_info *pi1,
479 struct bgp_path_info *pi2)
480 {
481 return (!(pi1->attr->label_index == pi2->attr->label_index));
482 }
483
484 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
485 * This is here primarily to keep prefix-count in check.
486 */
487 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
488 uint32_t flag)
489 {
490 SET_FLAG(pi->flags, flag);
491
492 /* early bath if we know it's not a flag that changes countability state
493 */
494 if (!CHECK_FLAG(flag,
495 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
496 return;
497
498 bgp_pcount_adjust(dest, pi);
499 }
500
501 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
502 uint32_t flag)
503 {
504 UNSET_FLAG(pi->flags, flag);
505
506 /* early bath if we know it's not a flag that changes countability state
507 */
508 if (!CHECK_FLAG(flag,
509 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
510 return;
511
512 bgp_pcount_adjust(dest, pi);
513 }
514
515 /* Get MED value. If MED value is missing and "bgp bestpath
516 missing-as-worst" is specified, treat it as the worst value. */
517 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
518 {
519 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
520 return attr->med;
521 else {
522 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
523 return BGP_MED_MAX;
524 else
525 return 0;
526 }
527 }
528
529 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
530 size_t buf_len)
531 {
532 if (pi->addpath_rx_id)
533 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
534 pi->peer->host, pi->addpath_rx_id);
535 else
536 snprintf(buf, buf_len, "path %s", pi->peer->host);
537 }
538
539
540 /*
541 * Get the ultimate path info.
542 */
543 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
544 {
545 struct bgp_path_info *bpi_ultimate;
546
547 if (info->sub_type != BGP_ROUTE_IMPORTED)
548 return info;
549
550 for (bpi_ultimate = info;
551 bpi_ultimate->extra && bpi_ultimate->extra->parent;
552 bpi_ultimate = bpi_ultimate->extra->parent)
553 ;
554
555 return bpi_ultimate;
556 }
557
558 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
559 */
560 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
561 struct bgp_path_info *exist, int *paths_eq,
562 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
563 char *pfx_buf, afi_t afi, safi_t safi,
564 enum bgp_path_selection_reason *reason)
565 {
566 const struct prefix *new_p;
567 struct prefix exist_p;
568 struct attr *newattr, *existattr;
569 enum bgp_peer_sort new_sort;
570 enum bgp_peer_sort exist_sort;
571 uint32_t new_pref;
572 uint32_t exist_pref;
573 uint32_t new_med;
574 uint32_t exist_med;
575 uint32_t new_weight;
576 uint32_t exist_weight;
577 uint32_t newm, existm;
578 struct in_addr new_id;
579 struct in_addr exist_id;
580 int new_cluster;
581 int exist_cluster;
582 int internal_as_route;
583 int confed_as_route;
584 int ret = 0;
585 int igp_metric_ret = 0;
586 int peer_sort_ret = -1;
587 char new_buf[PATH_ADDPATH_STR_BUFFER];
588 char exist_buf[PATH_ADDPATH_STR_BUFFER];
589 uint32_t new_mm_seq;
590 uint32_t exist_mm_seq;
591 int nh_cmp;
592 esi_t *exist_esi;
593 esi_t *new_esi;
594 bool same_esi;
595 bool old_proxy;
596 bool new_proxy;
597 bool new_origin, exist_origin;
598 struct bgp_path_info *bpi_ultimate;
599
600 struct bgp_orr_group *orr_group = NULL;
601 struct listnode *node;
602 struct bgp_orr_igp_metric *igp_metric = NULL;
603 struct list *orr_group_igp_metric_info = NULL;
604
605 *paths_eq = 0;
606
607 /* 0. Null check. */
608 if (new == NULL) {
609 *reason = bgp_path_selection_none;
610 if (debug)
611 zlog_debug("%s: new is NULL", pfx_buf);
612 return 0;
613 }
614
615 if (debug) {
616 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
617 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
618 sizeof(new_buf));
619 }
620
621 if (exist == NULL) {
622 *reason = bgp_path_selection_first;
623 if (debug)
624 zlog_debug("%s(%s): %s is the initial bestpath",
625 pfx_buf, bgp->name_pretty, new_buf);
626 return 1;
627 }
628
629 if (debug) {
630 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
631 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
632 sizeof(exist_buf));
633 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
634 pfx_buf, bgp->name_pretty, new_buf, new->flags,
635 exist_buf, exist->flags);
636 }
637
638 newattr = new->attr;
639 existattr = exist->attr;
640
641 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
642 * Capability" to a neighbor MUST perform the following upon receiving
643 * a route from that neighbor with the "LLGR_STALE" community, or upon
644 * attaching the "LLGR_STALE" community itself per Section 4.2:
645 *
646 * Treat the route as the least-preferred in route selection (see
647 * below). See the Risks of Depreferencing Routes section (Section 5.2)
648 * for a discussion of potential risks inherent in doing this.
649 */
650 if (bgp_attr_get_community(newattr) &&
651 community_include(bgp_attr_get_community(newattr),
652 COMMUNITY_LLGR_STALE)) {
653 if (debug)
654 zlog_debug(
655 "%s: %s wins over %s due to LLGR_STALE community",
656 pfx_buf, new_buf, exist_buf);
657 return 0;
658 }
659
660 if (bgp_attr_get_community(existattr) &&
661 community_include(bgp_attr_get_community(existattr),
662 COMMUNITY_LLGR_STALE)) {
663 if (debug)
664 zlog_debug(
665 "%s: %s loses to %s due to LLGR_STALE community",
666 pfx_buf, new_buf, exist_buf);
667 return 1;
668 }
669
670 new_p = bgp_dest_get_prefix(new->net);
671
672 /* For EVPN routes, we cannot just go by local vs remote, we have to
673 * look at the MAC mobility sequence number, if present.
674 */
675 if ((safi == SAFI_EVPN)
676 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
677 /* This is an error condition described in RFC 7432 Section
678 * 15.2. The RFC
679 * states that in this scenario "the PE MUST alert the operator"
680 * but it
681 * does not state what other action to take. In order to provide
682 * some
683 * consistency in this scenario we are going to prefer the path
684 * with the
685 * sticky flag.
686 */
687 if (newattr->sticky != existattr->sticky) {
688 if (!debug) {
689 prefix2str(new_p, pfx_buf,
690 sizeof(*pfx_buf)
691 * PREFIX2STR_BUFFER);
692 bgp_path_info_path_with_addpath_rx_str(
693 new, new_buf, sizeof(new_buf));
694 bgp_path_info_path_with_addpath_rx_str(
695 exist, exist_buf, sizeof(exist_buf));
696 }
697
698 if (newattr->sticky && !existattr->sticky) {
699 *reason = bgp_path_selection_evpn_sticky_mac;
700 if (debug)
701 zlog_debug(
702 "%s: %s wins over %s due to sticky MAC flag",
703 pfx_buf, new_buf, exist_buf);
704 return 1;
705 }
706
707 if (!newattr->sticky && existattr->sticky) {
708 *reason = bgp_path_selection_evpn_sticky_mac;
709 if (debug)
710 zlog_debug(
711 "%s: %s loses to %s due to sticky MAC flag",
712 pfx_buf, new_buf, exist_buf);
713 return 0;
714 }
715 }
716
717 new_esi = bgp_evpn_attr_get_esi(newattr);
718 exist_esi = bgp_evpn_attr_get_esi(existattr);
719 if (bgp_evpn_is_esi_valid(new_esi) &&
720 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
721 same_esi = true;
722 } else {
723 same_esi = false;
724 }
725
726 /* If both paths have the same non-zero ES and
727 * one path is local it wins.
728 * PS: Note the local path wins even if the remote
729 * has the higher MM seq. The local path's
730 * MM seq will be fixed up to match the highest
731 * rem seq, subsequently.
732 */
733 if (same_esi) {
734 char esi_buf[ESI_STR_LEN];
735
736 if (bgp_evpn_is_path_local(bgp, new)) {
737 *reason = bgp_path_selection_evpn_local_path;
738 if (debug)
739 zlog_debug(
740 "%s: %s wins over %s as ES %s is same and local",
741 pfx_buf, new_buf, exist_buf,
742 esi_to_str(new_esi, esi_buf,
743 sizeof(esi_buf)));
744 return 1;
745 }
746 if (bgp_evpn_is_path_local(bgp, exist)) {
747 *reason = bgp_path_selection_evpn_local_path;
748 if (debug)
749 zlog_debug(
750 "%s: %s loses to %s as ES %s is same and local",
751 pfx_buf, new_buf, exist_buf,
752 esi_to_str(new_esi, esi_buf,
753 sizeof(esi_buf)));
754 return 0;
755 }
756 }
757
758 new_mm_seq = mac_mobility_seqnum(newattr);
759 exist_mm_seq = mac_mobility_seqnum(existattr);
760
761 if (new_mm_seq > exist_mm_seq) {
762 *reason = bgp_path_selection_evpn_seq;
763 if (debug)
764 zlog_debug(
765 "%s: %s wins over %s due to MM seq %u > %u",
766 pfx_buf, new_buf, exist_buf, new_mm_seq,
767 exist_mm_seq);
768 return 1;
769 }
770
771 if (new_mm_seq < exist_mm_seq) {
772 *reason = bgp_path_selection_evpn_seq;
773 if (debug)
774 zlog_debug(
775 "%s: %s loses to %s due to MM seq %u < %u",
776 pfx_buf, new_buf, exist_buf, new_mm_seq,
777 exist_mm_seq);
778 return 0;
779 }
780
781 /* if the sequence numbers and ESI are the same and one path
782 * is non-proxy it wins (over proxy)
783 */
784 new_proxy = bgp_evpn_attr_is_proxy(newattr);
785 old_proxy = bgp_evpn_attr_is_proxy(existattr);
786 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
787 old_proxy != new_proxy) {
788 if (!new_proxy) {
789 *reason = bgp_path_selection_evpn_non_proxy;
790 if (debug)
791 zlog_debug(
792 "%s: %s wins over %s, same seq/es and non-proxy",
793 pfx_buf, new_buf, exist_buf);
794 return 1;
795 }
796
797 *reason = bgp_path_selection_evpn_non_proxy;
798 if (debug)
799 zlog_debug(
800 "%s: %s loses to %s, same seq/es and non-proxy",
801 pfx_buf, new_buf, exist_buf);
802 return 0;
803 }
804
805 /*
806 * if sequence numbers are the same path with the lowest IP
807 * wins
808 */
809 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
810 if (nh_cmp < 0) {
811 *reason = bgp_path_selection_evpn_lower_ip;
812 if (debug)
813 zlog_debug(
814 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
815 pfx_buf, new_buf, exist_buf, new_mm_seq,
816 &new->attr->nexthop);
817 return 1;
818 }
819 if (nh_cmp > 0) {
820 *reason = bgp_path_selection_evpn_lower_ip;
821 if (debug)
822 zlog_debug(
823 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
824 pfx_buf, new_buf, exist_buf, new_mm_seq,
825 &new->attr->nexthop);
826 return 0;
827 }
828 }
829
830 /* 1. Weight check. */
831 new_weight = newattr->weight;
832 exist_weight = existattr->weight;
833
834 if (new_weight > exist_weight) {
835 *reason = bgp_path_selection_weight;
836 if (debug)
837 zlog_debug("%s: %s wins over %s due to weight %d > %d",
838 pfx_buf, new_buf, exist_buf, new_weight,
839 exist_weight);
840 return 1;
841 }
842
843 if (new_weight < exist_weight) {
844 *reason = bgp_path_selection_weight;
845 if (debug)
846 zlog_debug("%s: %s loses to %s due to weight %d < %d",
847 pfx_buf, new_buf, exist_buf, new_weight,
848 exist_weight);
849 return 0;
850 }
851
852 /* 2. Local preference check. */
853 new_pref = exist_pref = bgp->default_local_pref;
854
855 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
856 new_pref = newattr->local_pref;
857 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
858 exist_pref = existattr->local_pref;
859
860 if (new_pref > exist_pref) {
861 *reason = bgp_path_selection_local_pref;
862 if (debug)
863 zlog_debug(
864 "%s: %s wins over %s due to localpref %d > %d",
865 pfx_buf, new_buf, exist_buf, new_pref,
866 exist_pref);
867 return 1;
868 }
869
870 if (new_pref < exist_pref) {
871 *reason = bgp_path_selection_local_pref;
872 if (debug)
873 zlog_debug(
874 "%s: %s loses to %s due to localpref %d < %d",
875 pfx_buf, new_buf, exist_buf, new_pref,
876 exist_pref);
877 return 0;
878 }
879
880 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
881 * extensions defined in this document, the following step is inserted
882 * after the LOCAL_PREF comparison step in the BGP decision process:
883 * When comparing a pair of routes for a BGP destination, the
884 * route with the ACCEPT_OWN community attached is preferred over
885 * the route that does not have the community.
886 * This extra step MUST only be invoked during the best path selection
887 * process of VPN-IP routes.
888 */
889 if (safi == SAFI_MPLS_VPN &&
890 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
891 CHECK_FLAG(exist->peer->af_flags[afi][safi],
892 PEER_FLAG_ACCEPT_OWN))) {
893 bool new_accept_own = false;
894 bool exist_accept_own = false;
895 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
896
897 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
898 new_accept_own = community_include(
899 bgp_attr_get_community(newattr), accept_own);
900 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
901 exist_accept_own = community_include(
902 bgp_attr_get_community(existattr), accept_own);
903
904 if (new_accept_own && !exist_accept_own) {
905 *reason = bgp_path_selection_accept_own;
906 if (debug)
907 zlog_debug(
908 "%s: %s wins over %s due to accept-own",
909 pfx_buf, new_buf, exist_buf);
910 return 1;
911 }
912
913 if (!new_accept_own && exist_accept_own) {
914 *reason = bgp_path_selection_accept_own;
915 if (debug)
916 zlog_debug(
917 "%s: %s loses to %s due to accept-own",
918 pfx_buf, new_buf, exist_buf);
919 return 0;
920 }
921 }
922
923 /* 3. Local route check. We prefer:
924 * - BGP_ROUTE_STATIC
925 * - BGP_ROUTE_AGGREGATE
926 * - BGP_ROUTE_REDISTRIBUTE
927 */
928 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
929 new->sub_type == BGP_ROUTE_IMPORTED);
930 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
931 exist->sub_type == BGP_ROUTE_IMPORTED);
932
933 if (new_origin && !exist_origin) {
934 *reason = bgp_path_selection_local_route;
935 if (debug)
936 zlog_debug(
937 "%s: %s wins over %s due to preferred BGP_ROUTE type",
938 pfx_buf, new_buf, exist_buf);
939 return 1;
940 }
941
942 if (!new_origin && exist_origin) {
943 *reason = bgp_path_selection_local_route;
944 if (debug)
945 zlog_debug(
946 "%s: %s loses to %s due to preferred BGP_ROUTE type",
947 pfx_buf, new_buf, exist_buf);
948 return 0;
949 }
950
951 /* Here if these are imported routes then get ultimate pi for
952 * path compare.
953 */
954 new = bgp_get_imported_bpi_ultimate(new);
955 exist = bgp_get_imported_bpi_ultimate(exist);
956 newattr = new->attr;
957 existattr = exist->attr;
958
959 /* 4. AS path length check. */
960 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
961 int exist_hops = aspath_count_hops(existattr->aspath);
962 int exist_confeds = aspath_count_confeds(existattr->aspath);
963
964 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
965 int aspath_hops;
966
967 aspath_hops = aspath_count_hops(newattr->aspath);
968 aspath_hops += aspath_count_confeds(newattr->aspath);
969
970 if (aspath_hops < (exist_hops + exist_confeds)) {
971 *reason = bgp_path_selection_confed_as_path;
972 if (debug)
973 zlog_debug(
974 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
975 pfx_buf, new_buf, exist_buf,
976 aspath_hops,
977 (exist_hops + exist_confeds));
978 return 1;
979 }
980
981 if (aspath_hops > (exist_hops + exist_confeds)) {
982 *reason = bgp_path_selection_confed_as_path;
983 if (debug)
984 zlog_debug(
985 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
986 pfx_buf, new_buf, exist_buf,
987 aspath_hops,
988 (exist_hops + exist_confeds));
989 return 0;
990 }
991 } else {
992 int newhops = aspath_count_hops(newattr->aspath);
993
994 if (newhops < exist_hops) {
995 *reason = bgp_path_selection_as_path;
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to aspath hopcount %d < %d",
999 pfx_buf, new_buf, exist_buf,
1000 newhops, exist_hops);
1001 return 1;
1002 }
1003
1004 if (newhops > exist_hops) {
1005 *reason = bgp_path_selection_as_path;
1006 if (debug)
1007 zlog_debug(
1008 "%s: %s loses to %s due to aspath hopcount %d > %d",
1009 pfx_buf, new_buf, exist_buf,
1010 newhops, exist_hops);
1011 return 0;
1012 }
1013 }
1014 }
1015
1016 /* 5. Origin check. */
1017 if (newattr->origin < existattr->origin) {
1018 *reason = bgp_path_selection_origin;
1019 if (debug)
1020 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1021 pfx_buf, new_buf, exist_buf,
1022 bgp_origin_long_str[newattr->origin],
1023 bgp_origin_long_str[existattr->origin]);
1024 return 1;
1025 }
1026
1027 if (newattr->origin > existattr->origin) {
1028 *reason = bgp_path_selection_origin;
1029 if (debug)
1030 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1031 pfx_buf, new_buf, exist_buf,
1032 bgp_origin_long_str[newattr->origin],
1033 bgp_origin_long_str[existattr->origin]);
1034 return 0;
1035 }
1036
1037 /* 6. MED check. */
1038 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1039 && aspath_count_hops(existattr->aspath) == 0);
1040 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1041 && aspath_count_confeds(existattr->aspath) > 0
1042 && aspath_count_hops(newattr->aspath) == 0
1043 && aspath_count_hops(existattr->aspath) == 0);
1044
1045 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1046 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1047 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1048 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1049 || internal_as_route) {
1050 new_med = bgp_med_value(new->attr, bgp);
1051 exist_med = bgp_med_value(exist->attr, bgp);
1052
1053 if (new_med < exist_med) {
1054 *reason = bgp_path_selection_med;
1055 if (debug)
1056 zlog_debug(
1057 "%s: %s wins over %s due to MED %d < %d",
1058 pfx_buf, new_buf, exist_buf, new_med,
1059 exist_med);
1060 return 1;
1061 }
1062
1063 if (new_med > exist_med) {
1064 *reason = bgp_path_selection_med;
1065 if (debug)
1066 zlog_debug(
1067 "%s: %s loses to %s due to MED %d > %d",
1068 pfx_buf, new_buf, exist_buf, new_med,
1069 exist_med);
1070 return 0;
1071 }
1072 }
1073
1074 /* 7. Peer type check. */
1075 new_sort = new->peer->sort;
1076 exist_sort = exist->peer->sort;
1077
1078 if (new_sort == BGP_PEER_EBGP
1079 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1080 *reason = bgp_path_selection_peer;
1081 if (debug)
1082 zlog_debug(
1083 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1084 pfx_buf, new_buf, exist_buf);
1085 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1086 return 1;
1087 peer_sort_ret = 1;
1088 }
1089
1090 if (exist_sort == BGP_PEER_EBGP
1091 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1092 *reason = bgp_path_selection_peer;
1093 if (debug)
1094 zlog_debug(
1095 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1096 pfx_buf, new_buf, exist_buf);
1097 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1098 return 0;
1099 peer_sort_ret = 0;
1100 }
1101
1102 /* 8. IGP metric check. */
1103 newm = existm = 0;
1104
1105 if (new->extra)
1106 newm = new->extra->igpmetric;
1107 if (exist->extra)
1108 existm = exist->extra->igpmetric;
1109
1110 if (new->peer->orr_group_name[afi][safi]) {
1111 ret = str2prefix(new->peer->host, &exist_p);
1112 orr_group = bgp_orr_group_lookup_by_name(
1113 bgp, afi, safi, new->peer->orr_group_name[afi][safi]);
1114 if (orr_group) {
1115 orr_group_igp_metric_info = orr_group->igp_metric_info;
1116 if (orr_group_igp_metric_info) {
1117 for (ALL_LIST_ELEMENTS_RO(
1118 orr_group_igp_metric_info, node,
1119 igp_metric)) {
1120 if (ret &&
1121 prefix_cmp(&exist_p,
1122 &igp_metric->prefix) ==
1123 0) {
1124 newm = igp_metric->igp_metric;
1125 break;
1126 }
1127 }
1128 }
1129 }
1130 }
1131 if (exist->peer->orr_group_name[afi][safi]) {
1132 ret = str2prefix(exist->peer->host, &exist_p);
1133 orr_group = bgp_orr_group_lookup_by_name(
1134 bgp, afi, safi, exist->peer->orr_group_name[afi][safi]);
1135 if (orr_group) {
1136 orr_group_igp_metric_info = orr_group->igp_metric_info;
1137 if (orr_group_igp_metric_info) {
1138 for (ALL_LIST_ELEMENTS_RO(
1139 orr_group_igp_metric_info, node,
1140 igp_metric)) {
1141 if (ret &&
1142 prefix_cmp(&exist_p,
1143 &igp_metric->prefix) ==
1144 0) {
1145 existm = igp_metric->igp_metric;
1146 break;
1147 }
1148 }
1149 }
1150 }
1151 }
1152
1153 if (newm < existm) {
1154 if (debug && peer_sort_ret < 0)
1155 zlog_debug(
1156 "%s: %s wins over %s due to IGP metric %u < %u",
1157 pfx_buf, new_buf, exist_buf, newm, existm);
1158 igp_metric_ret = 1;
1159 }
1160
1161 if (newm > existm) {
1162 if (debug && peer_sort_ret < 0)
1163 zlog_debug(
1164 "%s: %s loses to %s due to IGP metric %u > %u",
1165 pfx_buf, new_buf, exist_buf, newm, existm);
1166 igp_metric_ret = 0;
1167 }
1168
1169 /* 9. Same IGP metric. Compare the cluster list length as
1170 representative of IGP hops metric. Rewrite the metric value
1171 pair (newm, existm) with the cluster list length. Prefer the
1172 path with smaller cluster list length. */
1173 if (newm == existm) {
1174 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP &&
1175 peer_sort_lookup(exist->peer) == BGP_PEER_IBGP &&
1176 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1177 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1178 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1179
1180 if (newm < existm) {
1181 if (debug && peer_sort_ret < 0)
1182 zlog_debug(
1183 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1184 pfx_buf, new_buf, exist_buf,
1185 newm, existm);
1186 igp_metric_ret = 1;
1187 }
1188
1189 if (newm > existm) {
1190 if (debug && peer_sort_ret < 0)
1191 zlog_debug(
1192 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1193 pfx_buf, new_buf, exist_buf,
1194 newm, existm);
1195 igp_metric_ret = 0;
1196 }
1197 }
1198 }
1199
1200 /* 10. confed-external vs. confed-internal */
1201 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1202 if (new_sort == BGP_PEER_CONFED
1203 && exist_sort == BGP_PEER_IBGP) {
1204 *reason = bgp_path_selection_confed;
1205 if (debug)
1206 zlog_debug(
1207 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1208 pfx_buf, new_buf, exist_buf);
1209 if (!CHECK_FLAG(bgp->flags,
1210 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1211 return 1;
1212 peer_sort_ret = 1;
1213 }
1214
1215 if (exist_sort == BGP_PEER_CONFED
1216 && new_sort == BGP_PEER_IBGP) {
1217 *reason = bgp_path_selection_confed;
1218 if (debug)
1219 zlog_debug(
1220 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1221 pfx_buf, new_buf, exist_buf);
1222 if (!CHECK_FLAG(bgp->flags,
1223 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1224 return 0;
1225 peer_sort_ret = 0;
1226 }
1227 }
1228
1229 /* 11. Maximum path check. */
1230 if (newm == existm) {
1231 /* If one path has a label but the other does not, do not treat
1232 * them as equals for multipath
1233 */
1234 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1235 != (exist->extra
1236 && bgp_is_valid_label(&exist->extra->label[0]))) {
1237 if (debug)
1238 zlog_debug(
1239 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1240 pfx_buf, new_buf, exist_buf);
1241 } else if (CHECK_FLAG(bgp->flags,
1242 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1243
1244 /*
1245 * For the two paths, all comparison steps till IGP
1246 * metric
1247 * have succeeded - including AS_PATH hop count. Since
1248 * 'bgp
1249 * bestpath as-path multipath-relax' knob is on, we
1250 * don't need
1251 * an exact match of AS_PATH. Thus, mark the paths are
1252 * equal.
1253 * That will trigger both these paths to get into the
1254 * multipath
1255 * array.
1256 */
1257 *paths_eq = 1;
1258
1259 if (debug)
1260 zlog_debug(
1261 "%s: %s and %s are equal via multipath-relax",
1262 pfx_buf, new_buf, exist_buf);
1263 } else if (new->peer->sort == BGP_PEER_IBGP) {
1264 if (aspath_cmp(new->attr->aspath,
1265 exist->attr->aspath)) {
1266 *paths_eq = 1;
1267
1268 if (debug)
1269 zlog_debug(
1270 "%s: %s and %s are equal via matching aspaths",
1271 pfx_buf, new_buf, exist_buf);
1272 }
1273 } else if (new->peer->as == exist->peer->as) {
1274 *paths_eq = 1;
1275
1276 if (debug)
1277 zlog_debug(
1278 "%s: %s and %s are equal via same remote-as",
1279 pfx_buf, new_buf, exist_buf);
1280 }
1281 } else {
1282 /*
1283 * TODO: If unequal cost ibgp multipath is enabled we can
1284 * mark the paths as equal here instead of returning
1285 */
1286
1287 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1288 * if either step 7 or 10 (peer type checks) yielded a winner,
1289 * that result was returned immediately. Returning from step 10
1290 * ignored the return value computed in steps 8 and 9 (IGP
1291 * metric checks). In order to preserve that behavior, if
1292 * peer_sort_ret is set, return that rather than igp_metric_ret.
1293 */
1294 ret = peer_sort_ret;
1295 if (peer_sort_ret < 0) {
1296 ret = igp_metric_ret;
1297 if (debug) {
1298 if (ret == 1)
1299 zlog_debug(
1300 "%s: %s wins over %s after IGP metric comparison",
1301 pfx_buf, new_buf, exist_buf);
1302 else
1303 zlog_debug(
1304 "%s: %s loses to %s after IGP metric comparison",
1305 pfx_buf, new_buf, exist_buf);
1306 }
1307 *reason = bgp_path_selection_igp_metric;
1308 }
1309 return ret;
1310 }
1311
1312 /*
1313 * At this point, the decision whether to set *paths_eq = 1 has been
1314 * completed. If we deferred returning because of bestpath peer-type
1315 * relax configuration, return now.
1316 */
1317 if (peer_sort_ret >= 0)
1318 return peer_sort_ret;
1319
1320 /* 12. If both paths are external, prefer the path that was received
1321 first (the oldest one). This step minimizes route-flap, since a
1322 newer path won't displace an older one, even if it was the
1323 preferred route based on the additional decision criteria below. */
1324 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1325 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1326 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1327 *reason = bgp_path_selection_older;
1328 if (debug)
1329 zlog_debug(
1330 "%s: %s wins over %s due to oldest external",
1331 pfx_buf, new_buf, exist_buf);
1332 return 1;
1333 }
1334
1335 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1336 *reason = bgp_path_selection_older;
1337 if (debug)
1338 zlog_debug(
1339 "%s: %s loses to %s due to oldest external",
1340 pfx_buf, new_buf, exist_buf);
1341 return 0;
1342 }
1343 }
1344
1345 /* 13. Router-ID comparison. */
1346 /* If one of the paths is "stale", the corresponding peer router-id will
1347 * be 0 and would always win over the other path. If originator id is
1348 * used for the comparison, it will decide which path is better.
1349 */
1350 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1351 new_id.s_addr = newattr->originator_id.s_addr;
1352 else
1353 new_id.s_addr = new->peer->remote_id.s_addr;
1354 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1355 exist_id.s_addr = existattr->originator_id.s_addr;
1356 else
1357 exist_id.s_addr = exist->peer->remote_id.s_addr;
1358
1359 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1360 *reason = bgp_path_selection_router_id;
1361 if (debug)
1362 zlog_debug(
1363 "%s: %s wins over %s due to Router-ID comparison",
1364 pfx_buf, new_buf, exist_buf);
1365 return 1;
1366 }
1367
1368 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1369 *reason = bgp_path_selection_router_id;
1370 if (debug)
1371 zlog_debug(
1372 "%s: %s loses to %s due to Router-ID comparison",
1373 pfx_buf, new_buf, exist_buf);
1374 return 0;
1375 }
1376
1377 /* 14. Cluster length comparison. */
1378 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1379 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1380
1381 if (new_cluster < exist_cluster) {
1382 *reason = bgp_path_selection_cluster_length;
1383 if (debug)
1384 zlog_debug(
1385 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1386 pfx_buf, new_buf, exist_buf, new_cluster,
1387 exist_cluster);
1388 return 1;
1389 }
1390
1391 if (new_cluster > exist_cluster) {
1392 *reason = bgp_path_selection_cluster_length;
1393 if (debug)
1394 zlog_debug(
1395 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1396 pfx_buf, new_buf, exist_buf, new_cluster,
1397 exist_cluster);
1398 return 0;
1399 }
1400
1401 /* 15. Neighbor address comparison. */
1402 /* Do this only if neither path is "stale" as stale paths do not have
1403 * valid peer information (as the connection may or may not be up).
1404 */
1405 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1406 *reason = bgp_path_selection_stale;
1407 if (debug)
1408 zlog_debug(
1409 "%s: %s wins over %s due to latter path being STALE",
1410 pfx_buf, new_buf, exist_buf);
1411 return 1;
1412 }
1413
1414 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1415 *reason = bgp_path_selection_stale;
1416 if (debug)
1417 zlog_debug(
1418 "%s: %s loses to %s due to former path being STALE",
1419 pfx_buf, new_buf, exist_buf);
1420 return 0;
1421 }
1422
1423 /* locally configured routes to advertise do not have su_remote */
1424 if (new->peer->su_remote == NULL) {
1425 *reason = bgp_path_selection_local_configured;
1426 return 0;
1427 }
1428 if (exist->peer->su_remote == NULL) {
1429 *reason = bgp_path_selection_local_configured;
1430 return 1;
1431 }
1432
1433 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1434
1435 if (ret == 1) {
1436 *reason = bgp_path_selection_neighbor_ip;
1437 if (debug)
1438 zlog_debug(
1439 "%s: %s loses to %s due to Neighor IP comparison",
1440 pfx_buf, new_buf, exist_buf);
1441 return 0;
1442 }
1443
1444 if (ret == -1) {
1445 *reason = bgp_path_selection_neighbor_ip;
1446 if (debug)
1447 zlog_debug(
1448 "%s: %s wins over %s due to Neighor IP comparison",
1449 pfx_buf, new_buf, exist_buf);
1450 return 1;
1451 }
1452
1453 *reason = bgp_path_selection_default;
1454 if (debug)
1455 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1456 pfx_buf, new_buf, exist_buf);
1457
1458 return 1;
1459 }
1460
1461
1462 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1463 struct bgp_path_info *exist, int *paths_eq)
1464 {
1465 enum bgp_path_selection_reason reason;
1466 char pfx_buf[PREFIX2STR_BUFFER];
1467
1468 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1469 AFI_L2VPN, SAFI_EVPN, &reason);
1470 }
1471
1472 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1473 * is preferred, or 0 if they are the same (usually will only occur if
1474 * multipath is enabled
1475 * This version is compatible with */
1476 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1477 struct bgp_path_info *exist, char *pfx_buf,
1478 afi_t afi, safi_t safi,
1479 enum bgp_path_selection_reason *reason)
1480 {
1481 int paths_eq;
1482 int ret;
1483 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1484 afi, safi, reason);
1485
1486 if (paths_eq)
1487 ret = 0;
1488 else {
1489 if (ret == 1)
1490 ret = -1;
1491 else
1492 ret = 1;
1493 }
1494 return ret;
1495 }
1496
1497 static enum filter_type bgp_input_filter(struct peer *peer,
1498 const struct prefix *p,
1499 struct attr *attr, afi_t afi,
1500 safi_t safi)
1501 {
1502 struct bgp_filter *filter;
1503 enum filter_type ret = FILTER_PERMIT;
1504
1505 filter = &peer->filter[afi][safi];
1506
1507 #define FILTER_EXIST_WARN(F, f, filter) \
1508 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1509 zlog_debug("%s: Could not find configured input %s-list %s!", \
1510 peer->host, #f, F##_IN_NAME(filter));
1511
1512 if (DISTRIBUTE_IN_NAME(filter)) {
1513 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1514
1515 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1516 == FILTER_DENY) {
1517 ret = FILTER_DENY;
1518 goto done;
1519 }
1520 }
1521
1522 if (PREFIX_LIST_IN_NAME(filter)) {
1523 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1524
1525 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1526 == PREFIX_DENY) {
1527 ret = FILTER_DENY;
1528 goto done;
1529 }
1530 }
1531
1532 if (FILTER_LIST_IN_NAME(filter)) {
1533 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1534
1535 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1536 == AS_FILTER_DENY) {
1537 ret = FILTER_DENY;
1538 goto done;
1539 }
1540 }
1541
1542 done:
1543 if (frrtrace_enabled(frr_bgp, input_filter)) {
1544 char pfxprint[PREFIX2STR_BUFFER];
1545
1546 prefix2str(p, pfxprint, sizeof(pfxprint));
1547 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1548 ret == FILTER_PERMIT ? "permit" : "deny");
1549 }
1550
1551 return ret;
1552 #undef FILTER_EXIST_WARN
1553 }
1554
1555 static enum filter_type bgp_output_filter(struct peer *peer,
1556 const struct prefix *p,
1557 struct attr *attr, afi_t afi,
1558 safi_t safi)
1559 {
1560 struct bgp_filter *filter;
1561 enum filter_type ret = FILTER_PERMIT;
1562
1563 filter = &peer->filter[afi][safi];
1564
1565 #define FILTER_EXIST_WARN(F, f, filter) \
1566 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1567 zlog_debug("%s: Could not find configured output %s-list %s!", \
1568 peer->host, #f, F##_OUT_NAME(filter));
1569
1570 if (DISTRIBUTE_OUT_NAME(filter)) {
1571 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1572
1573 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1574 == FILTER_DENY) {
1575 ret = FILTER_DENY;
1576 goto done;
1577 }
1578 }
1579
1580 if (PREFIX_LIST_OUT_NAME(filter)) {
1581 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1582
1583 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1584 == PREFIX_DENY) {
1585 ret = FILTER_DENY;
1586 goto done;
1587 }
1588 }
1589
1590 if (FILTER_LIST_OUT_NAME(filter)) {
1591 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1592
1593 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1594 == AS_FILTER_DENY) {
1595 ret = FILTER_DENY;
1596 goto done;
1597 }
1598 }
1599
1600 if (frrtrace_enabled(frr_bgp, output_filter)) {
1601 char pfxprint[PREFIX2STR_BUFFER];
1602
1603 prefix2str(p, pfxprint, sizeof(pfxprint));
1604 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1605 ret == FILTER_PERMIT ? "permit" : "deny");
1606 }
1607
1608 done:
1609 return ret;
1610 #undef FILTER_EXIST_WARN
1611 }
1612
1613 /* If community attribute includes no_export then return 1. */
1614 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1615 {
1616 if (bgp_attr_get_community(attr)) {
1617 /* NO_ADVERTISE check. */
1618 if (community_include(bgp_attr_get_community(attr),
1619 COMMUNITY_NO_ADVERTISE))
1620 return true;
1621
1622 /* NO_EXPORT check. */
1623 if (peer->sort == BGP_PEER_EBGP &&
1624 community_include(bgp_attr_get_community(attr),
1625 COMMUNITY_NO_EXPORT))
1626 return true;
1627
1628 /* NO_EXPORT_SUBCONFED check. */
1629 if (peer->sort == BGP_PEER_EBGP
1630 || peer->sort == BGP_PEER_CONFED)
1631 if (community_include(bgp_attr_get_community(attr),
1632 COMMUNITY_NO_EXPORT_SUBCONFED))
1633 return true;
1634 }
1635 return false;
1636 }
1637
1638 /* Route reflection loop check. */
1639 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1640 {
1641 struct in_addr cluster_id;
1642 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1643
1644 if (cluster) {
1645 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1646 cluster_id = peer->bgp->cluster_id;
1647 else
1648 cluster_id = peer->bgp->router_id;
1649
1650 if (cluster_loop_check(cluster, cluster_id))
1651 return true;
1652 }
1653 return false;
1654 }
1655
1656 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1657 {
1658 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1659 if (peer->local_role == ROLE_PROVIDER ||
1660 peer->local_role == ROLE_RS_SERVER)
1661 return true;
1662 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1663 return true;
1664 return false;
1665 }
1666 if (peer->local_role == ROLE_CUSTOMER ||
1667 peer->local_role == ROLE_PEER ||
1668 peer->local_role == ROLE_RS_CLIENT) {
1669 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1670 attr->otc = peer->as;
1671 }
1672 return false;
1673 }
1674
1675 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1676 {
1677 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1678 if (peer->local_role == ROLE_CUSTOMER ||
1679 peer->local_role == ROLE_RS_CLIENT ||
1680 peer->local_role == ROLE_PEER)
1681 return true;
1682 return false;
1683 }
1684 if (peer->local_role == ROLE_PROVIDER ||
1685 peer->local_role == ROLE_PEER ||
1686 peer->local_role == ROLE_RS_SERVER) {
1687 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1688 attr->otc = peer->bgp->as;
1689 }
1690 return false;
1691 }
1692
1693 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1694 {
1695 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1696 }
1697
1698 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1699 struct attr *attr, afi_t afi, safi_t safi,
1700 const char *rmap_name, mpls_label_t *label,
1701 uint32_t num_labels, struct bgp_dest *dest)
1702 {
1703 struct bgp_filter *filter;
1704 struct bgp_path_info rmap_path = { 0 };
1705 struct bgp_path_info_extra extra = { 0 };
1706 route_map_result_t ret;
1707 struct route_map *rmap = NULL;
1708
1709 filter = &peer->filter[afi][safi];
1710
1711 /* Apply default weight value. */
1712 if (peer->weight[afi][safi])
1713 attr->weight = peer->weight[afi][safi];
1714
1715 if (rmap_name) {
1716 rmap = route_map_lookup_by_name(rmap_name);
1717
1718 if (rmap == NULL)
1719 return RMAP_DENY;
1720 } else {
1721 if (ROUTE_MAP_IN_NAME(filter)) {
1722 rmap = ROUTE_MAP_IN(filter);
1723
1724 if (rmap == NULL)
1725 return RMAP_DENY;
1726 }
1727 }
1728
1729 /* Route map apply. */
1730 if (rmap) {
1731 memset(&rmap_path, 0, sizeof(rmap_path));
1732 /* Duplicate current value to new structure for modification. */
1733 rmap_path.peer = peer;
1734 rmap_path.attr = attr;
1735 rmap_path.extra = &extra;
1736 rmap_path.net = dest;
1737
1738 extra.num_labels = num_labels;
1739 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1740 memcpy(extra.label, label,
1741 num_labels * sizeof(mpls_label_t));
1742
1743 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1744
1745 /* Apply BGP route map to the attribute. */
1746 ret = route_map_apply(rmap, p, &rmap_path);
1747
1748 peer->rmap_type = 0;
1749
1750 if (ret == RMAP_DENYMATCH)
1751 return RMAP_DENY;
1752 }
1753 return RMAP_PERMIT;
1754 }
1755
1756 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1757 struct attr *attr, afi_t afi, safi_t safi,
1758 const char *rmap_name)
1759 {
1760 struct bgp_path_info rmap_path;
1761 route_map_result_t ret;
1762 struct route_map *rmap = NULL;
1763 uint8_t rmap_type;
1764
1765 /*
1766 * So if we get to this point and have no rmap_name
1767 * we want to just show the output as it currently
1768 * exists.
1769 */
1770 if (!rmap_name)
1771 return RMAP_PERMIT;
1772
1773 /* Apply default weight value. */
1774 if (peer->weight[afi][safi])
1775 attr->weight = peer->weight[afi][safi];
1776
1777 rmap = route_map_lookup_by_name(rmap_name);
1778
1779 /*
1780 * If we have a route map name and we do not find
1781 * the routemap that means we have an implicit
1782 * deny.
1783 */
1784 if (rmap == NULL)
1785 return RMAP_DENY;
1786
1787 memset(&rmap_path, 0, sizeof(rmap_path));
1788 /* Route map apply. */
1789 /* Duplicate current value to new structure for modification. */
1790 rmap_path.peer = peer;
1791 rmap_path.attr = attr;
1792
1793 rmap_type = peer->rmap_type;
1794 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1795
1796 /* Apply BGP route map to the attribute. */
1797 ret = route_map_apply(rmap, p, &rmap_path);
1798
1799 peer->rmap_type = rmap_type;
1800
1801 if (ret == RMAP_DENYMATCH)
1802 /*
1803 * caller has multiple error paths with bgp_attr_flush()
1804 */
1805 return RMAP_DENY;
1806
1807 return RMAP_PERMIT;
1808 }
1809
1810 /* If this is an EBGP peer with remove-private-AS */
1811 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1812 struct peer *peer, struct attr *attr)
1813 {
1814 if (peer->sort == BGP_PEER_EBGP
1815 && (peer_af_flag_check(peer, afi, safi,
1816 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1817 || peer_af_flag_check(peer, afi, safi,
1818 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1819 || peer_af_flag_check(peer, afi, safi,
1820 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1821 || peer_af_flag_check(peer, afi, safi,
1822 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1823 // Take action on the entire aspath
1824 if (peer_af_flag_check(peer, afi, safi,
1825 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1826 || peer_af_flag_check(peer, afi, safi,
1827 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1828 if (peer_af_flag_check(
1829 peer, afi, safi,
1830 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1831 attr->aspath = aspath_replace_private_asns(
1832 attr->aspath, bgp->as, peer->as);
1833
1834 /*
1835 * Even if the aspath consists of just private ASNs we
1836 * need to walk the AS-Path to maintain all instances
1837 * of the peer's ASN to break possible loops.
1838 */
1839 else
1840 attr->aspath = aspath_remove_private_asns(
1841 attr->aspath, peer->as);
1842 }
1843
1844 // 'all' was not specified so the entire aspath must be private
1845 // ASNs
1846 // for us to do anything
1847 else if (aspath_private_as_check(attr->aspath)) {
1848 if (peer_af_flag_check(
1849 peer, afi, safi,
1850 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1851 attr->aspath = aspath_replace_private_asns(
1852 attr->aspath, bgp->as, peer->as);
1853 else
1854 /*
1855 * Walk the aspath to retain any instances of
1856 * the peer_asn
1857 */
1858 attr->aspath = aspath_remove_private_asns(
1859 attr->aspath, peer->as);
1860 }
1861 }
1862 }
1863
1864 /* If this is an EBGP peer with as-override */
1865 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1866 struct peer *peer, struct attr *attr)
1867 {
1868 struct aspath *aspath;
1869
1870 if (peer->sort == BGP_PEER_EBGP &&
1871 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1872 if (attr->aspath->refcnt)
1873 aspath = aspath_dup(attr->aspath);
1874 else
1875 aspath = attr->aspath;
1876
1877 attr->aspath = aspath_intern(
1878 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1879
1880 aspath_free(aspath);
1881 }
1882 }
1883
1884 void bgp_attr_add_llgr_community(struct attr *attr)
1885 {
1886 struct community *old;
1887 struct community *new;
1888 struct community *merge;
1889 struct community *llgr;
1890
1891 old = bgp_attr_get_community(attr);
1892 llgr = community_str2com("llgr-stale");
1893
1894 assert(llgr);
1895
1896 if (old) {
1897 merge = community_merge(community_dup(old), llgr);
1898
1899 if (old->refcnt == 0)
1900 community_free(&old);
1901
1902 new = community_uniq_sort(merge);
1903 community_free(&merge);
1904 } else {
1905 new = community_dup(llgr);
1906 }
1907
1908 community_free(&llgr);
1909
1910 bgp_attr_set_community(attr, new);
1911 }
1912
1913 void bgp_attr_add_gshut_community(struct attr *attr)
1914 {
1915 struct community *old;
1916 struct community *new;
1917 struct community *merge;
1918 struct community *gshut;
1919
1920 old = bgp_attr_get_community(attr);
1921 gshut = community_str2com("graceful-shutdown");
1922
1923 assert(gshut);
1924
1925 if (old) {
1926 merge = community_merge(community_dup(old), gshut);
1927
1928 if (old->refcnt == 0)
1929 community_free(&old);
1930
1931 new = community_uniq_sort(merge);
1932 community_free(&merge);
1933 } else {
1934 new = community_dup(gshut);
1935 }
1936
1937 community_free(&gshut);
1938 bgp_attr_set_community(attr, new);
1939
1940 /* When we add the graceful-shutdown community we must also
1941 * lower the local-preference */
1942 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1943 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1944 }
1945
1946
1947 /* Notify BGP Conditional advertisement scanner process. */
1948 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1949 {
1950 struct peer *peer = SUBGRP_PEER(subgrp);
1951 afi_t afi = SUBGRP_AFI(subgrp);
1952 safi_t safi = SUBGRP_SAFI(subgrp);
1953 struct bgp_filter *filter = &peer->filter[afi][safi];
1954
1955 if (!ADVERTISE_MAP_NAME(filter))
1956 return;
1957
1958 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1959 return;
1960
1961 peer->advmap_table_change = true;
1962 }
1963
1964
1965 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1966 {
1967 if (family == AF_INET) {
1968 attr->nexthop.s_addr = INADDR_ANY;
1969 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1970 }
1971 if (family == AF_INET6)
1972 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1973 if (family == AF_EVPN)
1974 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1975 }
1976
1977 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1978 struct update_subgroup *subgrp,
1979 const struct prefix *p, struct attr *attr,
1980 struct attr *post_attr)
1981 {
1982 struct bgp_filter *filter;
1983 struct peer *from;
1984 struct peer *peer;
1985 struct peer *onlypeer;
1986 struct bgp *bgp;
1987 struct attr *piattr;
1988 route_map_result_t ret;
1989 int transparent;
1990 int reflect;
1991 afi_t afi;
1992 safi_t safi;
1993 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1994 bool nh_reset = false;
1995 uint64_t cum_bw;
1996
1997 if (DISABLE_BGP_ANNOUNCE)
1998 return false;
1999
2000 afi = SUBGRP_AFI(subgrp);
2001 safi = SUBGRP_SAFI(subgrp);
2002 peer = SUBGRP_PEER(subgrp);
2003 onlypeer = NULL;
2004 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2005 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2006
2007 from = pi->peer;
2008 filter = &peer->filter[afi][safi];
2009 bgp = SUBGRP_INST(subgrp);
2010 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2011 : pi->attr;
2012
2013 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2014 peer->pmax_out[afi][safi] != 0 &&
2015 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2016 if (BGP_DEBUG(update, UPDATE_OUT) ||
2017 BGP_DEBUG(update, UPDATE_PREFIX)) {
2018 zlog_debug("%s reached maximum prefix to be send (%u)",
2019 peer->host, peer->pmax_out[afi][safi]);
2020 }
2021 return false;
2022 }
2023
2024 #ifdef ENABLE_BGP_VNC
2025 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2026 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2027 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2028
2029 /*
2030 * direct and direct_ext type routes originate internally even
2031 * though they can have peer pointers that reference other
2032 * systems
2033 */
2034 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2035 __func__, p);
2036 samepeer_safe = 1;
2037 }
2038 #endif
2039
2040 if (((afi == AFI_IP) || (afi == AFI_IP6))
2041 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2042 && (pi->type == ZEBRA_ROUTE_BGP)
2043 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2044
2045 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2046
2047 samepeer_safe = 1;
2048 }
2049
2050 /* With addpath we may be asked to TX all kinds of paths so make sure
2051 * pi is valid */
2052 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2053 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2054 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2055 return false;
2056 }
2057
2058 /* If this is not the bestpath then check to see if there is an enabled
2059 * addpath
2060 * feature that requires us to advertise it */
2061 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
2062 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
2063 return false;
2064 }
2065 }
2066
2067 /* Aggregate-address suppress check. */
2068 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2069 return false;
2070
2071 /*
2072 * If we are doing VRF 2 VRF leaking via the import
2073 * statement, we want to prevent the route going
2074 * off box as that the RT and RD created are localy
2075 * significant and globaly useless.
2076 */
2077 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2078 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2079 return false;
2080
2081 /* If it's labeled safi, make sure the route has a valid label. */
2082 if (safi == SAFI_LABELED_UNICAST) {
2083 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2084 if (!bgp_is_valid_label(&label)) {
2085 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2086 zlog_debug("u%" PRIu64 ":s%" PRIu64
2087 " %pFX is filtered - no label (%p)",
2088 subgrp->update_group->id, subgrp->id,
2089 p, &label);
2090 return false;
2091 }
2092 }
2093
2094 /* Do not send back route to sender. */
2095 if (onlypeer && from == onlypeer) {
2096 return false;
2097 }
2098
2099 /* Do not send the default route in the BGP table if the neighbor is
2100 * configured for default-originate */
2101 if (CHECK_FLAG(peer->af_flags[afi][safi],
2102 PEER_FLAG_DEFAULT_ORIGINATE)) {
2103 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2104 return false;
2105 else if (p->family == AF_INET6 && p->prefixlen == 0)
2106 return false;
2107 }
2108
2109 /* Transparency check. */
2110 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2111 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2112 transparent = 1;
2113 else
2114 transparent = 0;
2115
2116 /* If community is not disabled check the no-export and local. */
2117 if (!transparent && bgp_community_filter(peer, piattr)) {
2118 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2119 zlog_debug("%s: community filter check fail for %pFX",
2120 __func__, p);
2121 return false;
2122 }
2123
2124 /* If the attribute has originator-id and it is same as remote
2125 peer's id. */
2126 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2127 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2128 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2129 zlog_debug(
2130 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2131 onlypeer, p);
2132 return false;
2133 }
2134
2135 /* ORF prefix-list filter check */
2136 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2137 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2138 || CHECK_FLAG(peer->af_cap[afi][safi],
2139 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2140 if (peer->orf_plist[afi][safi]) {
2141 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2142 == PREFIX_DENY) {
2143 if (bgp_debug_update(NULL, p,
2144 subgrp->update_group, 0))
2145 zlog_debug(
2146 "%pBP [Update:SEND] %pFX is filtered via ORF",
2147 peer, p);
2148 return false;
2149 }
2150 }
2151
2152 /* Output filter check. */
2153 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2154 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2155 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2156 p);
2157 return false;
2158 }
2159
2160 /* AS path loop check. */
2161 if (onlypeer && onlypeer->as_path_loop_detection
2162 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2163 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2164 zlog_debug(
2165 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2166 onlypeer, onlypeer->as);
2167 return false;
2168 }
2169
2170 /* If we're a CONFED we need to loop check the CONFED ID too */
2171 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2172 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
2173 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2174 zlog_debug(
2175 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2176 peer, bgp->confed_id);
2177 return false;
2178 }
2179 }
2180
2181 /* Route-Reflect check. */
2182 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2183 reflect = 1;
2184 else
2185 reflect = 0;
2186
2187 /* IBGP reflection check. */
2188 if (reflect && !samepeer_safe) {
2189 /* A route from a Client peer. */
2190 if (CHECK_FLAG(from->af_flags[afi][safi],
2191 PEER_FLAG_REFLECTOR_CLIENT)) {
2192 /* Reflect to all the Non-Client peers and also to the
2193 Client peers other than the originator. Originator
2194 check
2195 is already done. So there is noting to do. */
2196 /* no bgp client-to-client reflection check. */
2197 if (CHECK_FLAG(bgp->flags,
2198 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2199 if (CHECK_FLAG(peer->af_flags[afi][safi],
2200 PEER_FLAG_REFLECTOR_CLIENT))
2201 return false;
2202 } else {
2203 /* A route from a Non-client peer. Reflect to all other
2204 clients. */
2205 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2206 PEER_FLAG_REFLECTOR_CLIENT))
2207 return false;
2208 }
2209 }
2210
2211 /* For modify attribute, copy it to temporary structure.
2212 * post_attr comes from BGP conditional advertisements, where
2213 * attributes are already processed by advertise-map route-map,
2214 * and this needs to be saved instead of overwriting from the
2215 * path attributes.
2216 */
2217 if (post_attr)
2218 *attr = *post_attr;
2219 else
2220 *attr = *piattr;
2221
2222 /* If local-preference is not set. */
2223 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2224 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2225 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2226 attr->local_pref = bgp->default_local_pref;
2227 }
2228
2229 /* If originator-id is not set and the route is to be reflected,
2230 set the originator id */
2231 if (reflect
2232 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2233 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2234 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2235 }
2236
2237 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2238 */
2239 if (peer->sort == BGP_PEER_EBGP
2240 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2241 if (from != bgp->peer_self && !transparent
2242 && !CHECK_FLAG(peer->af_flags[afi][safi],
2243 PEER_FLAG_MED_UNCHANGED))
2244 attr->flag &=
2245 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2246 }
2247
2248 /* Since the nexthop attribute can vary per peer, it is not explicitly
2249 * set
2250 * in announce check, only certain flags and length (or number of
2251 * nexthops
2252 * -- for IPv6/MP_REACH) are set here in order to guide the update
2253 * formation
2254 * code in setting the nexthop(s) on a per peer basis in
2255 * reformat_peer().
2256 * Typically, the source nexthop in the attribute is preserved but in
2257 * the
2258 * scenarios where we know it will always be overwritten, we reset the
2259 * nexthop to "0" in an attempt to achieve better Update packing. An
2260 * example of this is when a prefix from each of 2 IBGP peers needs to
2261 * be
2262 * announced to an EBGP peer (and they have the same attributes barring
2263 * their nexthop).
2264 */
2265 if (reflect)
2266 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2267
2268 #define NEXTHOP_IS_V6 \
2269 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2270 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2271 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2272 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2273
2274 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2275 * if
2276 * the peer (group) is configured to receive link-local nexthop
2277 * unchanged
2278 * and it is available in the prefix OR we're not reflecting the route,
2279 * link-local nexthop address is valid and
2280 * the peer (group) to whom we're going to announce is on a shared
2281 * network
2282 * and this is either a self-originated route or the peer is EBGP.
2283 * By checking if nexthop LL address is valid we are sure that
2284 * we do not announce LL address as `::`.
2285 */
2286 if (NEXTHOP_IS_V6) {
2287 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2288 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2289 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2290 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2291 || (!reflect && !transparent
2292 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2293 && peer->shared_network
2294 && (from == bgp->peer_self
2295 || peer->sort == BGP_PEER_EBGP))) {
2296 attr->mp_nexthop_len =
2297 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2298 }
2299
2300 /* Clear off link-local nexthop in source, whenever it is not
2301 * needed to
2302 * ensure more prefixes share the same attribute for
2303 * announcement.
2304 */
2305 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2306 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2307 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2308 }
2309
2310 if (bgp_check_role_applicability(afi, safi) &&
2311 bgp_otc_egress(peer, attr))
2312 return false;
2313
2314 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2315 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2316
2317 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2318 filter->advmap.aname &&
2319 route_map_lookup_by_name(filter->advmap.aname)) {
2320 struct bgp_path_info rmap_path = {0};
2321 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2322 struct attr dummy_attr = *attr;
2323
2324 /* Fill temp path_info */
2325 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2326 pi, peer, &dummy_attr);
2327
2328 struct route_map *amap =
2329 route_map_lookup_by_name(filter->advmap.aname);
2330
2331 ret = route_map_apply(amap, p, &rmap_path);
2332
2333 bgp_attr_flush(&dummy_attr);
2334
2335 /*
2336 * The conditional advertisement mode is Withdraw and this
2337 * prefix is a conditional prefix. Don't advertise it
2338 */
2339 if (ret == RMAP_PERMITMATCH)
2340 return false;
2341 }
2342
2343 /* Route map & unsuppress-map apply. */
2344 if (!post_attr &&
2345 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2346 struct bgp_path_info rmap_path = {0};
2347 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2348 struct attr dummy_attr = {0};
2349
2350 /* Fill temp path_info */
2351 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2352 pi, peer, attr);
2353
2354 /* don't confuse inbound and outbound setting */
2355 RESET_FLAG(attr->rmap_change_flags);
2356
2357 /*
2358 * The route reflector is not allowed to modify the attributes
2359 * of the reflected IBGP routes unless explicitly allowed.
2360 */
2361 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2362 && !CHECK_FLAG(bgp->flags,
2363 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2364 dummy_attr = *attr;
2365 rmap_path.attr = &dummy_attr;
2366 }
2367
2368 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2369
2370 if (bgp_path_suppressed(pi))
2371 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2372 &rmap_path);
2373 else
2374 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2375 &rmap_path);
2376
2377 bgp_attr_flush(&dummy_attr);
2378 peer->rmap_type = 0;
2379
2380 if (ret == RMAP_DENYMATCH) {
2381 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2382 zlog_debug(
2383 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2384 peer, p, ROUTE_MAP_OUT_NAME(filter));
2385 bgp_attr_flush(rmap_path.attr);
2386 return false;
2387 }
2388 }
2389
2390 /* RFC 8212 to prevent route leaks.
2391 * This specification intends to improve this situation by requiring the
2392 * explicit configuration of both BGP Import and Export Policies for any
2393 * External BGP (EBGP) session such as customers, peers, or
2394 * confederation boundaries for all enabled address families. Through
2395 * codification of the aforementioned requirement, operators will
2396 * benefit from consistent behavior across different BGP
2397 * implementations.
2398 */
2399 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2400 if (!bgp_outbound_policy_exists(peer, filter)) {
2401 if (monotime_since(&bgp->ebgprequirespolicywarning,
2402 NULL) > FIFTEENMINUTE2USEC ||
2403 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2404 zlog_warn(
2405 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2406 monotime(&bgp->ebgprequirespolicywarning);
2407 }
2408 return false;
2409 }
2410
2411 /* draft-ietf-idr-deprecate-as-set-confed-set
2412 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2413 * Eventually, This document (if approved) updates RFC 4271
2414 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2415 * and obsoletes RFC 6472.
2416 */
2417 if (peer->bgp->reject_as_sets)
2418 if (aspath_check_as_sets(attr->aspath))
2419 return false;
2420
2421 /* If neighbor sso is configured, then check if the route has
2422 * SoO extended community and validate against the configured
2423 * one. If they match, do not announce, to prevent routing
2424 * loops.
2425 */
2426 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2427 peer->soo[afi][safi]) {
2428 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2429 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2430
2431 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2432 ECOMMUNITY_SITE_ORIGIN) ||
2433 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2434 ECOMMUNITY_SITE_ORIGIN)) &&
2435 ecommunity_include(ecomm, ecomm_soo)) {
2436 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2437 zlog_debug(
2438 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2439 peer, p, ecommunity_str(ecomm_soo));
2440 return false;
2441 }
2442 }
2443
2444 /* Codification of AS 0 Processing */
2445 if (aspath_check_as_zero(attr->aspath))
2446 return false;
2447
2448 if (bgp_in_graceful_shutdown(bgp)) {
2449 if (peer->sort == BGP_PEER_IBGP
2450 || peer->sort == BGP_PEER_CONFED) {
2451 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2452 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2453 } else {
2454 bgp_attr_add_gshut_community(attr);
2455 }
2456 }
2457
2458 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2459 * Capability" to a neighbor MUST perform the following upon receiving
2460 * a route from that neighbor with the "LLGR_STALE" community, or upon
2461 * attaching the "LLGR_STALE" community itself per Section 4.2:
2462 *
2463 * The route SHOULD NOT be advertised to any neighbor from which the
2464 * Long-lived Graceful Restart Capability has not been received.
2465 */
2466 if (bgp_attr_get_community(attr) &&
2467 community_include(bgp_attr_get_community(attr),
2468 COMMUNITY_LLGR_STALE) &&
2469 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2470 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2471 return false;
2472
2473 /* After route-map has been applied, we check to see if the nexthop to
2474 * be carried in the attribute (that is used for the announcement) can
2475 * be cleared off or not. We do this in all cases where we would be
2476 * setting the nexthop to "ourselves". For IPv6, we only need to
2477 * consider
2478 * the global nexthop here; the link-local nexthop would have been
2479 * cleared
2480 * already, and if not, it is required by the update formation code.
2481 * Also see earlier comments in this function.
2482 */
2483 /*
2484 * If route-map has performed some operation on the nexthop or the peer
2485 * configuration says to pass it unchanged, we cannot reset the nexthop
2486 * here, so only attempt to do it if these aren't true. Note that the
2487 * route-map handler itself might have cleared the nexthop, if for
2488 * example,
2489 * it is configured as 'peer-address'.
2490 */
2491 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2492 piattr->rmap_change_flags)
2493 && !transparent
2494 && !CHECK_FLAG(peer->af_flags[afi][safi],
2495 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2496 /* We can reset the nexthop, if setting (or forcing) it to
2497 * 'self' */
2498 if (CHECK_FLAG(peer->af_flags[afi][safi],
2499 PEER_FLAG_NEXTHOP_SELF)
2500 || CHECK_FLAG(peer->af_flags[afi][safi],
2501 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2502 if (!reflect
2503 || CHECK_FLAG(peer->af_flags[afi][safi],
2504 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2505 subgroup_announce_reset_nhop(
2506 (peer_cap_enhe(peer, afi, safi)
2507 ? AF_INET6
2508 : p->family),
2509 attr);
2510 nh_reset = true;
2511 }
2512 } else if (peer->sort == BGP_PEER_EBGP) {
2513 /* Can also reset the nexthop if announcing to EBGP, but
2514 * only if
2515 * no peer in the subgroup is on a shared subnet.
2516 * Note: 3rd party nexthop currently implemented for
2517 * IPv4 only.
2518 */
2519 if ((p->family == AF_INET) &&
2520 (!bgp_subgrp_multiaccess_check_v4(
2521 piattr->nexthop,
2522 subgrp, from))) {
2523 subgroup_announce_reset_nhop(
2524 (peer_cap_enhe(peer, afi, safi)
2525 ? AF_INET6
2526 : p->family),
2527 attr);
2528 nh_reset = true;
2529 }
2530
2531 if ((p->family == AF_INET6) &&
2532 (!bgp_subgrp_multiaccess_check_v6(
2533 piattr->mp_nexthop_global,
2534 subgrp, from))) {
2535 subgroup_announce_reset_nhop(
2536 (peer_cap_enhe(peer, afi, safi)
2537 ? AF_INET6
2538 : p->family),
2539 attr);
2540 nh_reset = true;
2541 }
2542
2543
2544
2545 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2546 /*
2547 * This flag is used for leaked vpn-vrf routes
2548 */
2549 int family = p->family;
2550
2551 if (peer_cap_enhe(peer, afi, safi))
2552 family = AF_INET6;
2553
2554 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2555 zlog_debug(
2556 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2557 __func__, family2str(family));
2558 subgroup_announce_reset_nhop(family, attr);
2559 nh_reset = true;
2560 }
2561 }
2562
2563 /* If IPv6/MP and nexthop does not have any override and happens
2564 * to
2565 * be a link-local address, reset it so that we don't pass along
2566 * the
2567 * source's link-local IPv6 address to recipients who may not be
2568 * on
2569 * the same interface.
2570 */
2571 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2572 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2573 subgroup_announce_reset_nhop(AF_INET6, attr);
2574 nh_reset = true;
2575 }
2576 }
2577
2578 /* If this is an iBGP, send Origin Validation State (OVS)
2579 * extended community (rfc8097).
2580 */
2581 if (peer->sort == BGP_PEER_IBGP) {
2582 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2583
2584 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2585
2586 if (rpki_state != RPKI_NOT_BEING_USED)
2587 bgp_attr_set_ecommunity(
2588 attr, ecommunity_add_origin_validation_state(
2589 rpki_state,
2590 bgp_attr_get_ecommunity(attr)));
2591 }
2592
2593 /*
2594 * When the next hop is set to ourselves, if all multipaths have
2595 * link-bandwidth announce the cumulative bandwidth as that makes
2596 * the most sense. However, don't modify if the link-bandwidth has
2597 * been explicitly set by user policy.
2598 */
2599 if (nh_reset &&
2600 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2601 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2602 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2603 bgp_attr_set_ecommunity(
2604 attr,
2605 ecommunity_replace_linkbw(
2606 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2607 CHECK_FLAG(
2608 peer->flags,
2609 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2610
2611 return true;
2612 }
2613
2614 static void bgp_route_select_timer_expire(struct thread *thread)
2615 {
2616 struct afi_safi_info *info;
2617 afi_t afi;
2618 safi_t safi;
2619 struct bgp *bgp;
2620
2621 info = THREAD_ARG(thread);
2622 afi = info->afi;
2623 safi = info->safi;
2624 bgp = info->bgp;
2625
2626 if (BGP_DEBUG(update, UPDATE_OUT))
2627 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2628 safi);
2629
2630 bgp->gr_info[afi][safi].t_route_select = NULL;
2631
2632 XFREE(MTYPE_TMP, info);
2633
2634 /* Best path selection */
2635 bgp_best_path_select_defer(bgp, afi, safi);
2636 }
2637
2638 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2639 struct bgp_maxpaths_cfg *mpath_cfg,
2640 struct bgp_path_info_pair *result, afi_t afi,
2641 safi_t safi)
2642 {
2643 struct bgp_path_info *new_select;
2644 struct bgp_path_info *old_select;
2645 struct bgp_path_info *pi;
2646 struct bgp_path_info *pi1;
2647 struct bgp_path_info *pi2;
2648 struct bgp_path_info *nextpi = NULL;
2649 int paths_eq, do_mpath, debug;
2650 struct list mp_list;
2651 char pfx_buf[PREFIX2STR_BUFFER];
2652 char path_buf[PATH_ADDPATH_STR_BUFFER];
2653
2654 bgp_mp_list_init(&mp_list);
2655 do_mpath =
2656 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2657
2658 debug = bgp_debug_bestpath(dest);
2659
2660 if (debug)
2661 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2662
2663 dest->reason = bgp_path_selection_none;
2664 /* bgp deterministic-med */
2665 new_select = NULL;
2666 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2667
2668 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2669 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2670 pi1 = pi1->next)
2671 bgp_path_info_unset_flag(dest, pi1,
2672 BGP_PATH_DMED_SELECTED);
2673
2674 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2675 pi1 = pi1->next) {
2676 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2677 continue;
2678 if (BGP_PATH_HOLDDOWN(pi1))
2679 continue;
2680 if (pi1->peer != bgp->peer_self)
2681 if (!peer_established(pi1->peer))
2682 continue;
2683
2684 new_select = pi1;
2685 if (pi1->next) {
2686 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2687 if (CHECK_FLAG(pi2->flags,
2688 BGP_PATH_DMED_CHECK))
2689 continue;
2690 if (BGP_PATH_HOLDDOWN(pi2))
2691 continue;
2692 if (pi2->peer != bgp->peer_self
2693 && !CHECK_FLAG(
2694 pi2->peer->sflags,
2695 PEER_STATUS_NSF_WAIT))
2696 if (pi2->peer->status
2697 != Established)
2698 continue;
2699
2700 if (!aspath_cmp_left(pi1->attr->aspath,
2701 pi2->attr->aspath)
2702 && !aspath_cmp_left_confed(
2703 pi1->attr->aspath,
2704 pi2->attr->aspath))
2705 continue;
2706
2707 if (bgp_path_info_cmp(
2708 bgp, pi2, new_select,
2709 &paths_eq, mpath_cfg, debug,
2710 pfx_buf, afi, safi,
2711 &dest->reason)) {
2712 bgp_path_info_unset_flag(
2713 dest, new_select,
2714 BGP_PATH_DMED_SELECTED);
2715 new_select = pi2;
2716 }
2717
2718 bgp_path_info_set_flag(
2719 dest, pi2, BGP_PATH_DMED_CHECK);
2720 }
2721 }
2722 bgp_path_info_set_flag(dest, new_select,
2723 BGP_PATH_DMED_CHECK);
2724 bgp_path_info_set_flag(dest, new_select,
2725 BGP_PATH_DMED_SELECTED);
2726
2727 if (debug) {
2728 bgp_path_info_path_with_addpath_rx_str(
2729 new_select, path_buf, sizeof(path_buf));
2730 zlog_debug(
2731 "%pBD(%s): %s is the bestpath from AS %u",
2732 dest, bgp->name_pretty, path_buf,
2733 aspath_get_first_as(
2734 new_select->attr->aspath));
2735 }
2736 }
2737 }
2738
2739 /* Check old selected route and new selected route. */
2740 old_select = NULL;
2741 new_select = NULL;
2742 for (pi = bgp_dest_get_bgp_path_info(dest);
2743 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2744 enum bgp_path_selection_reason reason;
2745
2746 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2747 old_select = pi;
2748
2749 if (BGP_PATH_HOLDDOWN(pi)) {
2750 /* reap REMOVED routes, if needs be
2751 * selected route must stay for a while longer though
2752 */
2753 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2754 && (pi != old_select))
2755 bgp_path_info_reap(dest, pi);
2756
2757 if (debug)
2758 zlog_debug("%s: pi %p in holddown", __func__,
2759 pi);
2760
2761 continue;
2762 }
2763
2764 if (pi->peer && pi->peer != bgp->peer_self
2765 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2766 if (!peer_established(pi->peer)) {
2767
2768 if (debug)
2769 zlog_debug(
2770 "%s: pi %p non self peer %s not estab state",
2771 __func__, pi, pi->peer->host);
2772
2773 continue;
2774 }
2775
2776 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2777 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2778 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2779 if (debug)
2780 zlog_debug("%s: pi %p dmed", __func__, pi);
2781 continue;
2782 }
2783
2784 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2785
2786 reason = dest->reason;
2787 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2788 debug, pfx_buf, afi, safi,
2789 &dest->reason)) {
2790 if (new_select == NULL &&
2791 reason != bgp_path_selection_none)
2792 dest->reason = reason;
2793 new_select = pi;
2794 }
2795 }
2796
2797 /* Now that we know which path is the bestpath see if any of the other
2798 * paths
2799 * qualify as multipaths
2800 */
2801 if (debug) {
2802 if (new_select)
2803 bgp_path_info_path_with_addpath_rx_str(
2804 new_select, path_buf, sizeof(path_buf));
2805 else
2806 snprintf(path_buf, sizeof(path_buf), "NONE");
2807 zlog_debug(
2808 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2809 dest, bgp->name_pretty, path_buf,
2810 old_select ? old_select->peer->host : "NONE");
2811 }
2812
2813 if (do_mpath && new_select) {
2814 for (pi = bgp_dest_get_bgp_path_info(dest);
2815 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2816
2817 if (debug)
2818 bgp_path_info_path_with_addpath_rx_str(
2819 pi, path_buf, sizeof(path_buf));
2820
2821 if (pi == new_select) {
2822 if (debug)
2823 zlog_debug(
2824 "%pBD(%s): %s is the bestpath, add to the multipath list",
2825 dest, bgp->name_pretty,
2826 path_buf);
2827 bgp_mp_list_add(&mp_list, pi);
2828 continue;
2829 }
2830
2831 if (BGP_PATH_HOLDDOWN(pi))
2832 continue;
2833
2834 if (pi->peer && pi->peer != bgp->peer_self
2835 && !CHECK_FLAG(pi->peer->sflags,
2836 PEER_STATUS_NSF_WAIT))
2837 if (!peer_established(pi->peer))
2838 continue;
2839
2840 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2841 if (debug)
2842 zlog_debug(
2843 "%pBD: %s has the same nexthop as the bestpath, skip it",
2844 dest, path_buf);
2845 continue;
2846 }
2847
2848 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2849 mpath_cfg, debug, pfx_buf, afi, safi,
2850 &dest->reason);
2851
2852 if (paths_eq) {
2853 if (debug)
2854 zlog_debug(
2855 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2856 dest, path_buf);
2857 bgp_mp_list_add(&mp_list, pi);
2858 }
2859 }
2860 }
2861
2862 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2863 mpath_cfg);
2864 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2865 bgp_mp_list_clear(&mp_list);
2866
2867 bgp_addpath_update_ids(bgp, dest, afi, safi);
2868
2869 result->old = old_select;
2870 result->new = new_select;
2871
2872 return;
2873 }
2874
2875 /*
2876 * A new route/change in bestpath of an existing route. Evaluate the path
2877 * for advertisement to the subgroup.
2878 */
2879 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2880 struct bgp_path_info *selected,
2881 struct bgp_dest *dest,
2882 uint32_t addpath_tx_id)
2883 {
2884 const struct prefix *p;
2885 struct peer *onlypeer;
2886 struct attr attr;
2887 afi_t afi;
2888 safi_t safi;
2889 struct bgp *bgp;
2890 bool advertise;
2891
2892 p = bgp_dest_get_prefix(dest);
2893 afi = SUBGRP_AFI(subgrp);
2894 safi = SUBGRP_SAFI(subgrp);
2895 bgp = SUBGRP_INST(subgrp);
2896 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2897 : NULL);
2898
2899 if (BGP_DEBUG(update, UPDATE_OUT))
2900 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2901
2902 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2903 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2904 PEER_STATUS_ORF_WAIT_REFRESH))
2905 return;
2906
2907 memset(&attr, 0, sizeof(attr));
2908 /* It's initialized in bgp_announce_check() */
2909
2910 /* Announcement to the subgroup. If the route is filtered withdraw it.
2911 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2912 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2913 * route
2914 */
2915 advertise = bgp_check_advertise(bgp, dest);
2916
2917 if (selected) {
2918 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2919 NULL)) {
2920 /* Route is selected, if the route is already installed
2921 * in FIB, then it is advertised
2922 */
2923 if (advertise) {
2924 if (!bgp_check_withdrawal(bgp, dest))
2925 bgp_adj_out_set_subgroup(
2926 dest, subgrp, &attr, selected);
2927 else
2928 bgp_adj_out_unset_subgroup(
2929 dest, subgrp, 1, addpath_tx_id);
2930 }
2931 } else
2932 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2933 addpath_tx_id);
2934 }
2935
2936 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2937 else {
2938 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2939 }
2940 }
2941
2942 /*
2943 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2944 * This is called at the end of route processing.
2945 */
2946 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2947 {
2948 struct bgp_path_info *pi;
2949
2950 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2951 if (BGP_PATH_HOLDDOWN(pi))
2952 continue;
2953 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2954 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2955 }
2956 }
2957
2958 /*
2959 * Has the route changed from the RIB's perspective? This is invoked only
2960 * if the route selection returns the same best route as earlier - to
2961 * determine if we need to update zebra or not.
2962 */
2963 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2964 {
2965 struct bgp_path_info *mpinfo;
2966
2967 /* If this is multipath, check all selected paths for any nexthop
2968 * change or attribute change. Some attribute changes (e.g., community)
2969 * aren't of relevance to the RIB, but we'll update zebra to ensure
2970 * we handle the case of BGP nexthop change. This is the behavior
2971 * when the best path has an attribute change anyway.
2972 */
2973 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2974 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2975 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2976 return true;
2977
2978 /*
2979 * If this is multipath, check all selected paths for any nexthop change
2980 */
2981 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2982 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2983 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2984 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2985 return true;
2986 }
2987
2988 /* Nothing has changed from the RIB's perspective. */
2989 return false;
2990 }
2991
2992 struct bgp_process_queue {
2993 struct bgp *bgp;
2994 STAILQ_HEAD(, bgp_dest) pqueue;
2995 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2996 unsigned int flags;
2997 unsigned int queued;
2998 };
2999
3000 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3001 safi_t safi, struct bgp_dest *dest,
3002 struct bgp_path_info *new_select,
3003 struct bgp_path_info *old_select)
3004 {
3005 const struct prefix *p = bgp_dest_get_prefix(dest);
3006
3007 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3008 return;
3009
3010 if (advertise_type5_routes(bgp, afi) && new_select
3011 && is_route_injectable_into_evpn(new_select)) {
3012
3013 /* apply the route-map */
3014 if (bgp->adv_cmd_rmap[afi][safi].map) {
3015 route_map_result_t ret;
3016 struct bgp_path_info rmap_path;
3017 struct bgp_path_info_extra rmap_path_extra;
3018 struct attr dummy_attr;
3019
3020 dummy_attr = *new_select->attr;
3021
3022 /* Fill temp path_info */
3023 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3024 new_select, new_select->peer,
3025 &dummy_attr);
3026
3027 RESET_FLAG(dummy_attr.rmap_change_flags);
3028
3029 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3030 p, &rmap_path);
3031
3032 if (ret == RMAP_DENYMATCH) {
3033 bgp_attr_flush(&dummy_attr);
3034 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3035 safi);
3036 } else
3037 bgp_evpn_advertise_type5_route(
3038 bgp, p, &dummy_attr, afi, safi);
3039 } else {
3040 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3041 afi, safi);
3042 }
3043 } else if (advertise_type5_routes(bgp, afi) && old_select
3044 && is_route_injectable_into_evpn(old_select))
3045 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3046 }
3047
3048 /*
3049 * Utility to determine whether a particular path_info should use
3050 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3051 * in a path where we basically _know_ this is a BGP-LU route.
3052 */
3053 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3054 {
3055 /* Certain types get imp null; so do paths where the nexthop is
3056 * not labeled.
3057 */
3058 if (new_select->sub_type == BGP_ROUTE_STATIC
3059 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3060 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3061 return true;
3062 else if (new_select->extra == NULL ||
3063 !bgp_is_valid_label(&new_select->extra->label[0]))
3064 /* TODO -- should be configurable? */
3065 return true;
3066 else
3067 return false;
3068 }
3069
3070 /*
3071 * old_select = The old best path
3072 * new_select = the new best path
3073 *
3074 * if (!old_select && new_select)
3075 * We are sending new information on.
3076 *
3077 * if (old_select && new_select) {
3078 * if (new_select != old_select)
3079 * We have a new best path send a change
3080 * else
3081 * We've received a update with new attributes that needs
3082 * to be passed on.
3083 * }
3084 *
3085 * if (old_select && !new_select)
3086 * We have no eligible route that we can announce or the rn
3087 * is being removed.
3088 */
3089 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3090 afi_t afi, safi_t safi)
3091 {
3092 struct bgp_path_info *new_select;
3093 struct bgp_path_info *old_select;
3094 struct bgp_path_info_pair old_and_new;
3095 int debug = 0;
3096
3097 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3098 if (dest)
3099 debug = bgp_debug_bestpath(dest);
3100 if (debug)
3101 zlog_debug(
3102 "%s: bgp delete in progress, ignoring event, p=%pBD",
3103 __func__, dest);
3104 return;
3105 }
3106 /* Is it end of initial update? (after startup) */
3107 if (!dest) {
3108 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3109 sizeof(bgp->update_delay_zebra_resume_time));
3110
3111 bgp->main_zebra_update_hold = 0;
3112 FOREACH_AFI_SAFI (afi, safi) {
3113 if (bgp_fibupd_safi(safi))
3114 bgp_zebra_announce_table(bgp, afi, safi);
3115 }
3116 bgp->main_peers_update_hold = 0;
3117
3118 bgp_start_routeadv(bgp);
3119 return;
3120 }
3121
3122 const struct prefix *p = bgp_dest_get_prefix(dest);
3123
3124 debug = bgp_debug_bestpath(dest);
3125 if (debug)
3126 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3127 dest, bgp->name_pretty, afi2str(afi),
3128 safi2str(safi));
3129
3130 /* The best path calculation for the route is deferred if
3131 * BGP_NODE_SELECT_DEFER is set
3132 */
3133 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3134 if (BGP_DEBUG(update, UPDATE_OUT))
3135 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3136 return;
3137 }
3138
3139 /* Best path selection. */
3140 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3141 afi, safi);
3142 old_select = old_and_new.old;
3143 new_select = old_and_new.new;
3144
3145 /* Do we need to allocate or free labels?
3146 * Right now, since we only deal with per-prefix labels, it is not
3147 * necessary to do this upon changes to best path. Exceptions:
3148 * - label index has changed -> recalculate resulting label
3149 * - path_info sub_type changed -> switch to/from implicit-null
3150 * - no valid label (due to removed static label binding) -> get new one
3151 */
3152 if (bgp->allocate_mpls_labels[afi][safi]) {
3153 if (new_select) {
3154 if (!old_select
3155 || bgp_label_index_differs(new_select, old_select)
3156 || new_select->sub_type != old_select->sub_type
3157 || !bgp_is_valid_label(&dest->local_label)) {
3158 /* Enforced penultimate hop popping:
3159 * implicit-null for local routes, aggregate
3160 * and redistributed routes
3161 */
3162 if (bgp_lu_need_imp_null(new_select)) {
3163 if (CHECK_FLAG(
3164 dest->flags,
3165 BGP_NODE_REGISTERED_FOR_LABEL)
3166 || CHECK_FLAG(
3167 dest->flags,
3168 BGP_NODE_LABEL_REQUESTED))
3169 bgp_unregister_for_label(dest);
3170 dest->local_label = mpls_lse_encode(
3171 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3172 1);
3173 bgp_set_valid_label(&dest->local_label);
3174 } else
3175 bgp_register_for_label(dest,
3176 new_select);
3177 }
3178 } else if (CHECK_FLAG(dest->flags,
3179 BGP_NODE_REGISTERED_FOR_LABEL)
3180 || CHECK_FLAG(dest->flags,
3181 BGP_NODE_LABEL_REQUESTED)) {
3182 bgp_unregister_for_label(dest);
3183 }
3184 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3185 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3186 bgp_unregister_for_label(dest);
3187 }
3188
3189 if (debug)
3190 zlog_debug(
3191 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3192 __func__, dest, bgp->name_pretty, afi2str(afi),
3193 safi2str(safi), old_select, new_select);
3194
3195 /* If best route remains the same and this is not due to user-initiated
3196 * clear, see exactly what needs to be done.
3197 */
3198 if (old_select && old_select == new_select
3199 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3200 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3201 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3202 if (bgp_zebra_has_route_changed(old_select)) {
3203 #ifdef ENABLE_BGP_VNC
3204 vnc_import_bgp_add_route(bgp, p, old_select);
3205 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3206 #endif
3207 if (bgp_fibupd_safi(safi)
3208 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3209
3210 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3211 && new_select->sub_type == BGP_ROUTE_NORMAL)
3212 SET_FLAG(dest->flags,
3213 BGP_NODE_FIB_INSTALL_PENDING);
3214
3215 if (new_select->type == ZEBRA_ROUTE_BGP
3216 && (new_select->sub_type == BGP_ROUTE_NORMAL
3217 || new_select->sub_type
3218 == BGP_ROUTE_IMPORTED))
3219
3220 bgp_zebra_announce(dest, p, old_select,
3221 bgp, afi, safi);
3222 }
3223 }
3224
3225 /* If there is a change of interest to peers, reannounce the
3226 * route. */
3227 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3228 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3229 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3230 group_announce_route(bgp, afi, safi, dest, new_select);
3231
3232 /* unicast routes must also be annouced to
3233 * labeled-unicast update-groups */
3234 if (safi == SAFI_UNICAST)
3235 group_announce_route(bgp, afi,
3236 SAFI_LABELED_UNICAST, dest,
3237 new_select);
3238
3239 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3240 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3241 }
3242
3243 /* advertise/withdraw type-5 routes */
3244 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3245 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3246 bgp_process_evpn_route_injection(
3247 bgp, afi, safi, dest, old_select, old_select);
3248
3249 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3250 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3251 bgp_zebra_clear_route_change_flags(dest);
3252 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3253 return;
3254 }
3255
3256 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3257 */
3258 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3259
3260 /* bestpath has changed; bump version */
3261 if (old_select || new_select) {
3262 bgp_bump_version(dest);
3263
3264 if (!bgp->t_rmap_def_originate_eval) {
3265 bgp_lock(bgp);
3266 thread_add_timer(
3267 bm->master,
3268 update_group_refresh_default_originate_route_map,
3269 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3270 &bgp->t_rmap_def_originate_eval);
3271 }
3272 }
3273
3274 if (old_select)
3275 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3276 if (new_select) {
3277 if (debug)
3278 zlog_debug("%s: setting SELECTED flag", __func__);
3279 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3280 bgp_path_info_unset_flag(dest, new_select,
3281 BGP_PATH_ATTR_CHANGED);
3282 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3283 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3284 }
3285
3286 #ifdef ENABLE_BGP_VNC
3287 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3288 if (old_select != new_select) {
3289 if (old_select) {
3290 vnc_import_bgp_exterior_del_route(bgp, p,
3291 old_select);
3292 vnc_import_bgp_del_route(bgp, p, old_select);
3293 }
3294 if (new_select) {
3295 vnc_import_bgp_exterior_add_route(bgp, p,
3296 new_select);
3297 vnc_import_bgp_add_route(bgp, p, new_select);
3298 }
3299 }
3300 }
3301 #endif
3302
3303 group_announce_route(bgp, afi, safi, dest, new_select);
3304
3305 /* unicast routes must also be annouced to labeled-unicast update-groups
3306 */
3307 if (safi == SAFI_UNICAST)
3308 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3309 new_select);
3310
3311 /* FIB update. */
3312 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3313 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3314
3315 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3316 && (new_select->sub_type == BGP_ROUTE_NORMAL
3317 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3318 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3319
3320 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3321 SET_FLAG(dest->flags,
3322 BGP_NODE_FIB_INSTALL_PENDING);
3323
3324 /* if this is an evpn imported type-5 prefix,
3325 * we need to withdraw the route first to clear
3326 * the nh neigh and the RMAC entry.
3327 */
3328 if (old_select &&
3329 is_route_parent_evpn(old_select))
3330 bgp_zebra_withdraw(p, old_select, bgp, safi);
3331
3332 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3333 } else {
3334 /* Withdraw the route from the kernel. */
3335 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3336 && (old_select->sub_type == BGP_ROUTE_NORMAL
3337 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3338 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3339
3340 bgp_zebra_withdraw(p, old_select, bgp, safi);
3341 }
3342 }
3343
3344 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3345 old_select);
3346
3347 /* Clear any route change flags. */
3348 bgp_zebra_clear_route_change_flags(dest);
3349
3350 /* Reap old select bgp_path_info, if it has been removed */
3351 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3352 bgp_path_info_reap(dest, old_select);
3353
3354 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3355 return;
3356 }
3357
3358 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3359 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3360 {
3361 struct bgp_dest *dest;
3362 int cnt = 0;
3363 struct afi_safi_info *thread_info;
3364
3365 if (bgp->gr_info[afi][safi].t_route_select) {
3366 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3367
3368 thread_info = THREAD_ARG(t);
3369 XFREE(MTYPE_TMP, thread_info);
3370 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3371 }
3372
3373 if (BGP_DEBUG(update, UPDATE_OUT)) {
3374 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3375 get_afi_safi_str(afi, safi, false),
3376 bgp->gr_info[afi][safi].gr_deferred);
3377 }
3378
3379 /* Process the route list */
3380 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3381 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3382 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3383 dest = bgp_route_next(dest)) {
3384 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3385 continue;
3386
3387 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3388 bgp->gr_info[afi][safi].gr_deferred--;
3389 bgp_process_main_one(bgp, dest, afi, safi);
3390 cnt++;
3391 }
3392 /* If iteration stopped before the entire table was traversed then the
3393 * node needs to be unlocked.
3394 */
3395 if (dest) {
3396 bgp_dest_unlock_node(dest);
3397 dest = NULL;
3398 }
3399
3400 /* Send EOR message when all routes are processed */
3401 if (!bgp->gr_info[afi][safi].gr_deferred) {
3402 bgp_send_delayed_eor(bgp);
3403 /* Send route processing complete message to RIB */
3404 bgp_zebra_update(afi, safi, bgp->vrf_id,
3405 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3406 return;
3407 }
3408
3409 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3410
3411 thread_info->afi = afi;
3412 thread_info->safi = safi;
3413 thread_info->bgp = bgp;
3414
3415 /* If there are more routes to be processed, start the
3416 * selection timer
3417 */
3418 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3419 BGP_ROUTE_SELECT_DELAY,
3420 &bgp->gr_info[afi][safi].t_route_select);
3421 }
3422
3423 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3424 {
3425 struct bgp_process_queue *pqnode = data;
3426 struct bgp *bgp = pqnode->bgp;
3427 struct bgp_table *table;
3428 struct bgp_dest *dest;
3429
3430 /* eoiu marker */
3431 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3432 bgp_process_main_one(bgp, NULL, 0, 0);
3433 /* should always have dedicated wq call */
3434 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3435 return WQ_SUCCESS;
3436 }
3437
3438 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3439 dest = STAILQ_FIRST(&pqnode->pqueue);
3440 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3441 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3442 table = bgp_dest_table(dest);
3443 /* note, new DESTs may be added as part of processing */
3444 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3445
3446 bgp_dest_unlock_node(dest);
3447 bgp_table_unlock(table);
3448 }
3449
3450 return WQ_SUCCESS;
3451 }
3452
3453 static void bgp_processq_del(struct work_queue *wq, void *data)
3454 {
3455 struct bgp_process_queue *pqnode = data;
3456
3457 bgp_unlock(pqnode->bgp);
3458
3459 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3460 }
3461
3462 void bgp_process_queue_init(struct bgp *bgp)
3463 {
3464 if (!bgp->process_queue) {
3465 char name[BUFSIZ];
3466
3467 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3468 bgp->process_queue = work_queue_new(bm->master, name);
3469 }
3470
3471 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3472 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3473 bgp->process_queue->spec.max_retries = 0;
3474 bgp->process_queue->spec.hold = 50;
3475 /* Use a higher yield value of 50ms for main queue processing */
3476 bgp->process_queue->spec.yield = 50 * 1000L;
3477 }
3478
3479 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3480 {
3481 struct bgp_process_queue *pqnode;
3482
3483 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3484 sizeof(struct bgp_process_queue));
3485
3486 /* unlocked in bgp_processq_del */
3487 pqnode->bgp = bgp_lock(bgp);
3488 STAILQ_INIT(&pqnode->pqueue);
3489
3490 return pqnode;
3491 }
3492
3493 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3494 {
3495 #define ARBITRARY_PROCESS_QLEN 10000
3496 struct work_queue *wq = bgp->process_queue;
3497 struct bgp_process_queue *pqnode;
3498 int pqnode_reuse = 0;
3499
3500 /* already scheduled for processing? */
3501 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3502 return;
3503
3504 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3505 * the workqueue
3506 */
3507 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3508 if (BGP_DEBUG(update, UPDATE_OUT))
3509 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3510 dest);
3511 return;
3512 }
3513
3514 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3515 if (BGP_DEBUG(update, UPDATE_OUT))
3516 zlog_debug(
3517 "Soft reconfigure table in progress for route %p",
3518 dest);
3519 return;
3520 }
3521
3522 if (wq == NULL)
3523 return;
3524
3525 /* Add route nodes to an existing work queue item until reaching the
3526 limit only if is from the same BGP view and it's not an EOIU marker
3527 */
3528 if (work_queue_item_count(wq)) {
3529 struct work_queue_item *item = work_queue_last_item(wq);
3530 pqnode = item->data;
3531
3532 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3533 || pqnode->bgp != bgp
3534 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3535 pqnode = bgp_processq_alloc(bgp);
3536 else
3537 pqnode_reuse = 1;
3538 } else
3539 pqnode = bgp_processq_alloc(bgp);
3540 /* all unlocked in bgp_process_wq */
3541 bgp_table_lock(bgp_dest_table(dest));
3542
3543 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3544 bgp_dest_lock_node(dest);
3545
3546 /* can't be enqueued twice */
3547 assert(STAILQ_NEXT(dest, pq) == NULL);
3548 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3549 pqnode->queued++;
3550
3551 if (!pqnode_reuse)
3552 work_queue_add(wq, pqnode);
3553
3554 return;
3555 }
3556
3557 void bgp_add_eoiu_mark(struct bgp *bgp)
3558 {
3559 struct bgp_process_queue *pqnode;
3560
3561 if (bgp->process_queue == NULL)
3562 return;
3563
3564 pqnode = bgp_processq_alloc(bgp);
3565
3566 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3567 work_queue_add(bgp->process_queue, pqnode);
3568 }
3569
3570 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3571 {
3572 struct peer *peer;
3573
3574 peer = THREAD_ARG(thread);
3575 peer->t_pmax_restart = NULL;
3576
3577 if (bgp_debug_neighbor_events(peer))
3578 zlog_debug(
3579 "%s Maximum-prefix restart timer expired, restore peering",
3580 peer->host);
3581
3582 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3583 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3584 }
3585
3586 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3587 safi_t safi)
3588 {
3589 uint32_t count = 0;
3590 bool filtered = false;
3591 struct bgp_dest *dest;
3592 struct bgp_adj_in *ain;
3593 struct attr attr = {};
3594 struct bgp_table *table = peer->bgp->rib[afi][safi];
3595
3596 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3597 for (ain = dest->adj_in; ain; ain = ain->next) {
3598 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3599
3600 attr = *ain->attr;
3601
3602 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3603 == FILTER_DENY)
3604 filtered = true;
3605
3606 if (bgp_input_modifier(
3607 peer, rn_p, &attr, afi, safi,
3608 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3609 NULL, 0, NULL)
3610 == RMAP_DENY)
3611 filtered = true;
3612
3613 if (filtered)
3614 count++;
3615
3616 bgp_attr_flush(&attr);
3617 }
3618 }
3619
3620 return count;
3621 }
3622
3623 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3624 int always)
3625 {
3626 iana_afi_t pkt_afi;
3627 iana_safi_t pkt_safi;
3628 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3629 PEER_FLAG_MAX_PREFIX_FORCE))
3630 ? bgp_filtered_routes_count(peer, afi, safi)
3631 + peer->pcount[afi][safi]
3632 : peer->pcount[afi][safi];
3633
3634 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3635 return false;
3636
3637 if (pcount > peer->pmax[afi][safi]) {
3638 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3639 PEER_STATUS_PREFIX_LIMIT)
3640 && !always)
3641 return false;
3642
3643 zlog_info(
3644 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3645 get_afi_safi_str(afi, safi, false), peer, pcount,
3646 peer->pmax[afi][safi]);
3647 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3648
3649 if (CHECK_FLAG(peer->af_flags[afi][safi],
3650 PEER_FLAG_MAX_PREFIX_WARNING))
3651 return false;
3652
3653 /* Convert AFI, SAFI to values for packet. */
3654 pkt_afi = afi_int2iana(afi);
3655 pkt_safi = safi_int2iana(safi);
3656 {
3657 uint8_t ndata[7];
3658
3659 ndata[0] = (pkt_afi >> 8);
3660 ndata[1] = pkt_afi;
3661 ndata[2] = pkt_safi;
3662 ndata[3] = (peer->pmax[afi][safi] >> 24);
3663 ndata[4] = (peer->pmax[afi][safi] >> 16);
3664 ndata[5] = (peer->pmax[afi][safi] >> 8);
3665 ndata[6] = (peer->pmax[afi][safi]);
3666
3667 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3668 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3669 BGP_NOTIFY_CEASE_MAX_PREFIX,
3670 ndata, 7);
3671 }
3672
3673 /* Dynamic peers will just close their connection. */
3674 if (peer_dynamic_neighbor(peer))
3675 return true;
3676
3677 /* restart timer start */
3678 if (peer->pmax_restart[afi][safi]) {
3679 peer->v_pmax_restart =
3680 peer->pmax_restart[afi][safi] * 60;
3681
3682 if (bgp_debug_neighbor_events(peer))
3683 zlog_debug(
3684 "%pBP Maximum-prefix restart timer started for %d secs",
3685 peer, peer->v_pmax_restart);
3686
3687 BGP_TIMER_ON(peer->t_pmax_restart,
3688 bgp_maximum_prefix_restart_timer,
3689 peer->v_pmax_restart);
3690 }
3691
3692 return true;
3693 } else
3694 UNSET_FLAG(peer->af_sflags[afi][safi],
3695 PEER_STATUS_PREFIX_LIMIT);
3696
3697 if (pcount
3698 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3699 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3700 PEER_STATUS_PREFIX_THRESHOLD)
3701 && !always)
3702 return false;
3703
3704 zlog_info(
3705 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3706 get_afi_safi_str(afi, safi, false), peer, pcount,
3707 peer->pmax[afi][safi]);
3708 SET_FLAG(peer->af_sflags[afi][safi],
3709 PEER_STATUS_PREFIX_THRESHOLD);
3710 } else
3711 UNSET_FLAG(peer->af_sflags[afi][safi],
3712 PEER_STATUS_PREFIX_THRESHOLD);
3713 return false;
3714 }
3715
3716 /* Unconditionally remove the route from the RIB, without taking
3717 * damping into consideration (eg, because the session went down)
3718 */
3719 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3720 struct peer *peer, afi_t afi, safi_t safi)
3721 {
3722
3723 struct bgp *bgp = NULL;
3724 bool delete_route = false;
3725
3726 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3727 safi);
3728
3729 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3730 bgp_path_info_delete(dest, pi); /* keep historical info */
3731
3732 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3733 * flag
3734 */
3735 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3736 delete_route = true;
3737 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3738 delete_route = true;
3739 if (delete_route) {
3740 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3741 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3742 bgp = pi->peer->bgp;
3743 bgp->gr_info[afi][safi].gr_deferred--;
3744 }
3745 }
3746 }
3747
3748 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3749 bgp_process(peer->bgp, dest, afi, safi);
3750 }
3751
3752 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3753 struct peer *peer, afi_t afi, safi_t safi,
3754 struct prefix_rd *prd)
3755 {
3756 const struct prefix *p = bgp_dest_get_prefix(dest);
3757
3758 /* apply dampening, if result is suppressed, we'll be retaining
3759 * the bgp_path_info in the RIB for historical reference.
3760 */
3761 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3762 && peer->sort == BGP_PEER_EBGP)
3763 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3764 == BGP_DAMP_SUPPRESSED) {
3765 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3766 safi);
3767 return;
3768 }
3769
3770 #ifdef ENABLE_BGP_VNC
3771 if (safi == SAFI_MPLS_VPN) {
3772 struct bgp_dest *pdest = NULL;
3773 struct bgp_table *table = NULL;
3774
3775 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3776 (struct prefix *)prd);
3777 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3778 table = bgp_dest_get_bgp_table_info(pdest);
3779
3780 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3781 peer->bgp, prd, table, p, pi);
3782 }
3783 bgp_dest_unlock_node(pdest);
3784 }
3785 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3786 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3787
3788 vnc_import_bgp_del_route(peer->bgp, p, pi);
3789 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3790 }
3791 }
3792 #endif
3793
3794 /* If this is an EVPN route, process for un-import. */
3795 if (safi == SAFI_EVPN)
3796 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3797
3798 bgp_rib_remove(dest, pi, peer, afi, safi);
3799 }
3800
3801 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3802 struct peer *peer, struct attr *attr,
3803 struct bgp_dest *dest)
3804 {
3805 struct bgp_path_info *new;
3806
3807 /* Make new BGP info. */
3808 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3809 new->type = type;
3810 new->instance = instance;
3811 new->sub_type = sub_type;
3812 new->peer = peer;
3813 new->attr = attr;
3814 new->uptime = monotime(NULL);
3815 new->net = dest;
3816 return new;
3817 }
3818
3819 /* Check if received nexthop is valid or not. */
3820 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3821 uint8_t type, uint8_t stype, struct attr *attr,
3822 struct bgp_dest *dest)
3823 {
3824 bool ret = false;
3825 bool is_bgp_static_route =
3826 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3827 : false;
3828
3829 /*
3830 * Only validated for unicast and multicast currently.
3831 * Also valid for EVPN where the nexthop is an IP address.
3832 * If we are a bgp static route being checked then there is
3833 * no need to check to see if the nexthop is martian as
3834 * that it should be ok.
3835 */
3836 if (is_bgp_static_route ||
3837 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3838 return false;
3839
3840 /* If NEXT_HOP is present, validate it. */
3841 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3842 if (attr->nexthop.s_addr == INADDR_ANY ||
3843 !ipv4_unicast_valid(&attr->nexthop) ||
3844 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3845 return true;
3846 }
3847
3848 /* If MP_NEXTHOP is present, validate it. */
3849 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3850 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3851 * it is not an IPv6 link-local address.
3852 *
3853 * If we receive an UPDATE with nexthop length set to 32 bytes
3854 * we shouldn't discard an UPDATE if it's set to (::).
3855 * The link-local (2st) is validated along the code path later.
3856 */
3857 if (attr->mp_nexthop_len) {
3858 switch (attr->mp_nexthop_len) {
3859 case BGP_ATTR_NHLEN_IPV4:
3860 case BGP_ATTR_NHLEN_VPNV4:
3861 ret = (attr->mp_nexthop_global_in.s_addr ==
3862 INADDR_ANY ||
3863 !ipv4_unicast_valid(
3864 &attr->mp_nexthop_global_in) ||
3865 bgp_nexthop_self(bgp, afi, type, stype, attr,
3866 dest));
3867 break;
3868
3869 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3870 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3871 ret = (IN6_IS_ADDR_UNSPECIFIED(
3872 &attr->mp_nexthop_global)
3873 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3874 || IN6_IS_ADDR_MULTICAST(
3875 &attr->mp_nexthop_global)
3876 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3877 dest));
3878 break;
3879 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3880 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3881 || IN6_IS_ADDR_MULTICAST(
3882 &attr->mp_nexthop_global)
3883 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3884 dest));
3885 break;
3886
3887 default:
3888 ret = true;
3889 break;
3890 }
3891 }
3892
3893 return ret;
3894 }
3895
3896 static void bgp_attr_add_no_export_community(struct attr *attr)
3897 {
3898 struct community *old;
3899 struct community *new;
3900 struct community *merge;
3901 struct community *no_export;
3902
3903 old = bgp_attr_get_community(attr);
3904 no_export = community_str2com("no-export");
3905
3906 assert(no_export);
3907
3908 if (old) {
3909 merge = community_merge(community_dup(old), no_export);
3910
3911 if (!old->refcnt)
3912 community_free(&old);
3913
3914 new = community_uniq_sort(merge);
3915 community_free(&merge);
3916 } else {
3917 new = community_dup(no_export);
3918 }
3919
3920 community_free(&no_export);
3921
3922 bgp_attr_set_community(attr, new);
3923 }
3924
3925 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3926 struct attr *attr, const struct prefix *prefix,
3927 int *sub_type)
3928 {
3929 struct listnode *node, *nnode;
3930 struct bgp *bgp;
3931 bool accept_own_found = false;
3932
3933 if (safi != SAFI_MPLS_VPN)
3934 return false;
3935
3936 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3937 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3938 return false;
3939
3940 /* The route in question carries the ACCEPT_OWN community */
3941 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3942 struct community *comm = bgp_attr_get_community(attr);
3943
3944 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3945 accept_own_found = true;
3946 }
3947
3948 /* The route in question is targeted to one or more destination VRFs
3949 * on the router (as determined by inspecting the Route Target(s)).
3950 */
3951 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3952 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3953 continue;
3954
3955 if (accept_own_found &&
3956 ecommunity_include(
3957 bgp->vpn_policy[afi]
3958 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3959 bgp_attr_get_ecommunity(attr))) {
3960 if (bgp_debug_update(peer, prefix, NULL, 1))
3961 zlog_debug(
3962 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3963 peer, prefix);
3964
3965 /* Treat this route as imported, because it's leaked
3966 * already from another VRF, and we got an updated
3967 * version from route-reflector with ACCEPT_OWN
3968 * community.
3969 */
3970 *sub_type = BGP_ROUTE_IMPORTED;
3971
3972 return true;
3973 }
3974 }
3975
3976 return false;
3977 }
3978
3979 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3980 struct attr *attr, afi_t afi, safi_t safi, int type,
3981 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3982 uint32_t num_labels, int soft_reconfig,
3983 struct bgp_route_evpn *evpn)
3984 {
3985 int ret;
3986 int aspath_loop_count = 0;
3987 struct bgp_dest *dest;
3988 struct bgp *bgp;
3989 struct attr new_attr;
3990 struct attr *attr_new;
3991 struct bgp_path_info *pi;
3992 struct bgp_path_info *new;
3993 struct bgp_path_info_extra *extra;
3994 const char *reason;
3995 char pfx_buf[BGP_PRD_PATH_STRLEN];
3996 int connected = 0;
3997 int do_loop_check = 1;
3998 int has_valid_label = 0;
3999 afi_t nh_afi;
4000 bool force_evpn_import = false;
4001 safi_t orig_safi = safi;
4002 bool leak_success = true;
4003
4004 if (frrtrace_enabled(frr_bgp, process_update)) {
4005 char pfxprint[PREFIX2STR_BUFFER];
4006
4007 prefix2str(p, pfxprint, sizeof(pfxprint));
4008 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4009 afi, safi, attr);
4010 }
4011
4012 #ifdef ENABLE_BGP_VNC
4013 int vnc_implicit_withdraw = 0;
4014 #endif
4015 int same_attr = 0;
4016
4017 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4018 if (orig_safi == SAFI_LABELED_UNICAST)
4019 safi = SAFI_UNICAST;
4020
4021 memset(&new_attr, 0, sizeof(new_attr));
4022 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4023 new_attr.label = MPLS_INVALID_LABEL;
4024
4025 bgp = peer->bgp;
4026 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4027 /* TODO: Check to see if we can get rid of "is_valid_label" */
4028 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4029 has_valid_label = (num_labels > 0) ? 1 : 0;
4030 else
4031 has_valid_label = bgp_is_valid_label(label);
4032
4033 if (has_valid_label)
4034 assert(label != NULL);
4035
4036 /* Update overlay index of the attribute */
4037 if (afi == AFI_L2VPN && evpn)
4038 memcpy(&attr->evpn_overlay, evpn,
4039 sizeof(struct bgp_route_evpn));
4040
4041 /* When peer's soft reconfiguration enabled. Record input packet in
4042 Adj-RIBs-In. */
4043 if (!soft_reconfig
4044 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4045 && peer != bgp->peer_self)
4046 bgp_adj_in_set(dest, peer, attr, addpath_id);
4047
4048 /* Check previously received route. */
4049 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4050 if (pi->peer == peer && pi->type == type
4051 && pi->sub_type == sub_type
4052 && pi->addpath_rx_id == addpath_id)
4053 break;
4054
4055 /* AS path local-as loop check. */
4056 if (peer->change_local_as) {
4057 if (peer->allowas_in[afi][safi])
4058 aspath_loop_count = peer->allowas_in[afi][safi];
4059 else if (!CHECK_FLAG(peer->flags,
4060 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4061 aspath_loop_count = 1;
4062
4063 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4064 > aspath_loop_count) {
4065 peer->stat_pfx_aspath_loop++;
4066 reason = "as-path contains our own AS;";
4067 goto filtered;
4068 }
4069 }
4070
4071 /* If the peer is configured for "allowas-in origin" and the last ASN in
4072 * the
4073 * as-path is our ASN then we do not need to call aspath_loop_check
4074 */
4075 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4076 if (aspath_get_last_as(attr->aspath) == bgp->as)
4077 do_loop_check = 0;
4078
4079 /* AS path loop check. */
4080 if (do_loop_check) {
4081 if (aspath_loop_check(attr->aspath, bgp->as)
4082 > peer->allowas_in[afi][safi]
4083 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
4084 && aspath_loop_check(attr->aspath, bgp->confed_id)
4085 > peer->allowas_in[afi][safi])) {
4086 peer->stat_pfx_aspath_loop++;
4087 reason = "as-path contains our own AS;";
4088 goto filtered;
4089 }
4090 }
4091
4092 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4093 * enabled, then take care of that too.
4094 */
4095 bool accept_own = false;
4096
4097 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4098 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4099 accept_own =
4100 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4101 if (!accept_own) {
4102 peer->stat_pfx_originator_loop++;
4103 reason = "originator is us;";
4104 goto filtered;
4105 }
4106 }
4107
4108 /* Route reflector cluster ID check. */
4109 if (bgp_cluster_filter(peer, attr)) {
4110 peer->stat_pfx_cluster_loop++;
4111 reason = "reflected from the same cluster;";
4112 goto filtered;
4113 }
4114
4115 /* Apply incoming filter. */
4116 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4117 peer->stat_pfx_filter++;
4118 reason = "filter;";
4119 goto filtered;
4120 }
4121
4122 /* RFC 8212 to prevent route leaks.
4123 * This specification intends to improve this situation by requiring the
4124 * explicit configuration of both BGP Import and Export Policies for any
4125 * External BGP (EBGP) session such as customers, peers, or
4126 * confederation boundaries for all enabled address families. Through
4127 * codification of the aforementioned requirement, operators will
4128 * benefit from consistent behavior across different BGP
4129 * implementations.
4130 */
4131 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4132 if (!bgp_inbound_policy_exists(peer,
4133 &peer->filter[afi][safi])) {
4134 reason = "inbound policy missing";
4135 if (monotime_since(&bgp->ebgprequirespolicywarning,
4136 NULL) > FIFTEENMINUTE2USEC ||
4137 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4138 zlog_warn(
4139 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4140 monotime(&bgp->ebgprequirespolicywarning);
4141 }
4142 goto filtered;
4143 }
4144
4145 /* draft-ietf-idr-deprecate-as-set-confed-set
4146 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4147 * Eventually, This document (if approved) updates RFC 4271
4148 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4149 * and obsoletes RFC 6472.
4150 */
4151 if (peer->bgp->reject_as_sets)
4152 if (aspath_check_as_sets(attr->aspath)) {
4153 reason =
4154 "as-path contains AS_SET or AS_CONFED_SET type;";
4155 goto filtered;
4156 }
4157
4158 new_attr = *attr;
4159
4160 /* Apply incoming route-map.
4161 * NB: new_attr may now contain newly allocated values from route-map
4162 * "set"
4163 * commands, so we need bgp_attr_flush in the error paths, until we
4164 * intern
4165 * the attr (which takes over the memory references) */
4166 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4167 num_labels, dest)
4168 == RMAP_DENY) {
4169 peer->stat_pfx_filter++;
4170 reason = "route-map;";
4171 bgp_attr_flush(&new_attr);
4172 goto filtered;
4173 }
4174
4175 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4176 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4177 /* remove from RIB previous entry */
4178 bgp_zebra_withdraw(p, pi, bgp, safi);
4179 }
4180
4181 if (peer->sort == BGP_PEER_EBGP) {
4182
4183 /* rfc7999:
4184 * A BGP speaker receiving an announcement tagged with the
4185 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4186 * NO_EXPORT community as defined in RFC1997, or a
4187 * similar community, to prevent propagation of the
4188 * prefix outside the local AS. The community to prevent
4189 * propagation SHOULD be chosen according to the operator's
4190 * routing policy.
4191 */
4192 if (bgp_attr_get_community(&new_attr) &&
4193 community_include(bgp_attr_get_community(&new_attr),
4194 COMMUNITY_BLACKHOLE))
4195 bgp_attr_add_no_export_community(&new_attr);
4196
4197 /* If we receive the graceful-shutdown community from an eBGP
4198 * peer we must lower local-preference */
4199 if (bgp_attr_get_community(&new_attr) &&
4200 community_include(bgp_attr_get_community(&new_attr),
4201 COMMUNITY_GSHUT)) {
4202 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4203 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4204
4205 /* If graceful-shutdown is configured then add the GSHUT
4206 * community to all paths received from eBGP peers */
4207 } else if (bgp_in_graceful_shutdown(peer->bgp))
4208 bgp_attr_add_gshut_community(&new_attr);
4209 }
4210
4211 /* next hop check. */
4212 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4213 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4214 &new_attr, dest)) {
4215 peer->stat_pfx_nh_invalid++;
4216 reason = "martian or self next-hop;";
4217 bgp_attr_flush(&new_attr);
4218 goto filtered;
4219 }
4220
4221 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4222 peer->stat_pfx_nh_invalid++;
4223 reason = "self mac;";
4224 bgp_attr_flush(&new_attr);
4225 goto filtered;
4226 }
4227
4228 if (bgp_check_role_applicability(afi, safi) &&
4229 bgp_otc_filter(peer, &new_attr)) {
4230 reason = "failing otc validation";
4231 bgp_attr_flush(&new_attr);
4232 goto filtered;
4233 }
4234 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4235 * condition :
4236 * Suppress fib is enabled
4237 * BGP_OPT_NO_FIB is not enabled
4238 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4239 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4240 */
4241 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4242 && (sub_type == BGP_ROUTE_NORMAL)
4243 && (!bgp_option_check(BGP_OPT_NO_FIB))
4244 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4245 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4246
4247 /* If maximum prefix count is configured and current prefix
4248 * count exeed it.
4249 */
4250 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4251 bgp_attr_flush(&new_attr);
4252 return -1;
4253 }
4254
4255 /* If neighbor soo is configured, tag all incoming routes with
4256 * this SoO tag and then filter out advertisements in
4257 * subgroup_announce_check() if it matches the configured SoO
4258 * on the other peer.
4259 */
4260 if (peer->soo[afi][safi]) {
4261 struct ecommunity *old_ecomm =
4262 bgp_attr_get_ecommunity(&new_attr);
4263 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4264 struct ecommunity *new_ecomm;
4265
4266 if (old_ecomm) {
4267 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4268 ecomm_soo);
4269
4270 if (!old_ecomm->refcnt)
4271 ecommunity_free(&old_ecomm);
4272 } else {
4273 new_ecomm = ecommunity_dup(ecomm_soo);
4274 }
4275
4276 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4277 }
4278
4279 attr_new = bgp_attr_intern(&new_attr);
4280
4281 /* If the update is implicit withdraw. */
4282 if (pi) {
4283 pi->uptime = monotime(NULL);
4284 same_attr = attrhash_cmp(pi->attr, attr_new);
4285
4286 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4287
4288 /* Same attribute comes in. */
4289 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4290 && same_attr
4291 && (!has_valid_label
4292 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4293 num_labels * sizeof(mpls_label_t))
4294 == 0)) {
4295 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4296 BGP_CONFIG_DAMPENING)
4297 && peer->sort == BGP_PEER_EBGP
4298 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4299 if (bgp_debug_update(peer, p, NULL, 1)) {
4300 bgp_debug_rdpfxpath2str(
4301 afi, safi, prd, p, label,
4302 num_labels, addpath_id ? 1 : 0,
4303 addpath_id, evpn, pfx_buf,
4304 sizeof(pfx_buf));
4305 zlog_debug("%pBP rcvd %s", peer,
4306 pfx_buf);
4307 }
4308
4309 if (bgp_damp_update(pi, dest, afi, safi)
4310 != BGP_DAMP_SUPPRESSED) {
4311 bgp_aggregate_increment(bgp, p, pi, afi,
4312 safi);
4313 bgp_process(bgp, dest, afi, safi);
4314 }
4315 } else /* Duplicate - odd */
4316 {
4317 if (bgp_debug_update(peer, p, NULL, 1)) {
4318 if (!peer->rcvd_attr_printed) {
4319 zlog_debug(
4320 "%pBP rcvd UPDATE w/ attr: %s",
4321 peer,
4322 peer->rcvd_attr_str);
4323 peer->rcvd_attr_printed = 1;
4324 }
4325
4326 bgp_debug_rdpfxpath2str(
4327 afi, safi, prd, p, label,
4328 num_labels, addpath_id ? 1 : 0,
4329 addpath_id, evpn, pfx_buf,
4330 sizeof(pfx_buf));
4331 zlog_debug(
4332 "%pBP rcvd %s...duplicate ignored",
4333 peer, pfx_buf);
4334 }
4335
4336 /* graceful restart STALE flag unset. */
4337 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4338 bgp_path_info_unset_flag(
4339 dest, pi, BGP_PATH_STALE);
4340 bgp_dest_set_defer_flag(dest, false);
4341 bgp_process(bgp, dest, afi, safi);
4342 }
4343 }
4344
4345 bgp_dest_unlock_node(dest);
4346 bgp_attr_unintern(&attr_new);
4347
4348 return 0;
4349 }
4350
4351 /* Withdraw/Announce before we fully processed the withdraw */
4352 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4353 if (bgp_debug_update(peer, p, NULL, 1)) {
4354 bgp_debug_rdpfxpath2str(
4355 afi, safi, prd, p, label, num_labels,
4356 addpath_id ? 1 : 0, addpath_id, evpn,
4357 pfx_buf, sizeof(pfx_buf));
4358 zlog_debug(
4359 "%pBP rcvd %s, flapped quicker than processing",
4360 peer, pfx_buf);
4361 }
4362
4363 bgp_path_info_restore(dest, pi);
4364
4365 /*
4366 * If the BGP_PATH_REMOVED flag is set, then EVPN
4367 * routes would have been unimported already when a
4368 * prior BGP withdraw processing happened. Such routes
4369 * need to be imported again, so flag accordingly.
4370 */
4371 force_evpn_import = true;
4372 }
4373
4374 /* Received Logging. */
4375 if (bgp_debug_update(peer, p, NULL, 1)) {
4376 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4377 num_labels, addpath_id ? 1 : 0,
4378 addpath_id, evpn, pfx_buf,
4379 sizeof(pfx_buf));
4380 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4381 }
4382
4383 /* graceful restart STALE flag unset. */
4384 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4385 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4386 bgp_dest_set_defer_flag(dest, false);
4387 }
4388
4389 /* The attribute is changed. */
4390 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4391
4392 /* implicit withdraw, decrement aggregate and pcount here.
4393 * only if update is accepted, they'll increment below.
4394 */
4395 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4396
4397 /* Update bgp route dampening information. */
4398 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4399 && peer->sort == BGP_PEER_EBGP) {
4400 /* This is implicit withdraw so we should update
4401 dampening
4402 information. */
4403 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4404 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4405 }
4406 #ifdef ENABLE_BGP_VNC
4407 if (safi == SAFI_MPLS_VPN) {
4408 struct bgp_dest *pdest = NULL;
4409 struct bgp_table *table = NULL;
4410
4411 pdest = bgp_node_get(bgp->rib[afi][safi],
4412 (struct prefix *)prd);
4413 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4414 table = bgp_dest_get_bgp_table_info(pdest);
4415
4416 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4417 bgp, prd, table, p, pi);
4418 }
4419 bgp_dest_unlock_node(pdest);
4420 }
4421 if ((afi == AFI_IP || afi == AFI_IP6)
4422 && (safi == SAFI_UNICAST)) {
4423 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4424 /*
4425 * Implicit withdraw case.
4426 */
4427 ++vnc_implicit_withdraw;
4428 vnc_import_bgp_del_route(bgp, p, pi);
4429 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4430 }
4431 }
4432 #endif
4433
4434 /* Special handling for EVPN update of an existing route. If the
4435 * extended community attribute has changed, we need to
4436 * un-import
4437 * the route using its existing extended community. It will be
4438 * subsequently processed for import with the new extended
4439 * community.
4440 */
4441 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4442 && !same_attr) {
4443 if ((pi->attr->flag
4444 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4445 && (attr_new->flag
4446 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4447 int cmp;
4448
4449 cmp = ecommunity_cmp(
4450 bgp_attr_get_ecommunity(pi->attr),
4451 bgp_attr_get_ecommunity(attr_new));
4452 if (!cmp) {
4453 if (bgp_debug_update(peer, p, NULL, 1))
4454 zlog_debug(
4455 "Change in EXT-COMM, existing %s new %s",
4456 ecommunity_str(
4457 bgp_attr_get_ecommunity(
4458 pi->attr)),
4459 ecommunity_str(
4460 bgp_attr_get_ecommunity(
4461 attr_new)));
4462 if (safi == SAFI_EVPN)
4463 bgp_evpn_unimport_route(
4464 bgp, afi, safi, p, pi);
4465 else /* SAFI_MPLS_VPN */
4466 vpn_leak_to_vrf_withdraw(bgp,
4467 pi);
4468 }
4469 }
4470 }
4471
4472 /* Update to new attribute. */
4473 bgp_attr_unintern(&pi->attr);
4474 pi->attr = attr_new;
4475
4476 /* Update MPLS label */
4477 if (has_valid_label) {
4478 extra = bgp_path_info_extra_get(pi);
4479 if (extra->label != label) {
4480 memcpy(&extra->label, label,
4481 num_labels * sizeof(mpls_label_t));
4482 extra->num_labels = num_labels;
4483 }
4484 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4485 bgp_set_valid_label(&extra->label[0]);
4486 }
4487
4488 /* Update SRv6 SID */
4489 if (attr->srv6_l3vpn) {
4490 extra = bgp_path_info_extra_get(pi);
4491 if (sid_diff(&extra->sid[0].sid,
4492 &attr->srv6_l3vpn->sid)) {
4493 sid_copy(&extra->sid[0].sid,
4494 &attr->srv6_l3vpn->sid);
4495 extra->num_sids = 1;
4496
4497 extra->sid[0].loc_block_len = 0;
4498 extra->sid[0].loc_node_len = 0;
4499 extra->sid[0].func_len = 0;
4500 extra->sid[0].arg_len = 0;
4501 extra->sid[0].transposition_len = 0;
4502 extra->sid[0].transposition_offset = 0;
4503
4504 if (attr->srv6_l3vpn->loc_block_len != 0) {
4505 extra->sid[0].loc_block_len =
4506 attr->srv6_l3vpn->loc_block_len;
4507 extra->sid[0].loc_node_len =
4508 attr->srv6_l3vpn->loc_node_len;
4509 extra->sid[0].func_len =
4510 attr->srv6_l3vpn->func_len;
4511 extra->sid[0].arg_len =
4512 attr->srv6_l3vpn->arg_len;
4513 extra->sid[0].transposition_len =
4514 attr->srv6_l3vpn
4515 ->transposition_len;
4516 extra->sid[0].transposition_offset =
4517 attr->srv6_l3vpn
4518 ->transposition_offset;
4519 }
4520 }
4521 } else if (attr->srv6_vpn) {
4522 extra = bgp_path_info_extra_get(pi);
4523 if (sid_diff(&extra->sid[0].sid,
4524 &attr->srv6_vpn->sid)) {
4525 sid_copy(&extra->sid[0].sid,
4526 &attr->srv6_vpn->sid);
4527 extra->num_sids = 1;
4528 }
4529 }
4530
4531 #ifdef ENABLE_BGP_VNC
4532 if ((afi == AFI_IP || afi == AFI_IP6)
4533 && (safi == SAFI_UNICAST)) {
4534 if (vnc_implicit_withdraw) {
4535 /*
4536 * Add back the route with its new attributes
4537 * (e.g., nexthop).
4538 * The route is still selected, until the route
4539 * selection
4540 * queued by bgp_process actually runs. We have
4541 * to make this
4542 * update to the VNC side immediately to avoid
4543 * racing against
4544 * configuration changes (e.g., route-map
4545 * changes) which
4546 * trigger re-importation of the entire RIB.
4547 */
4548 vnc_import_bgp_add_route(bgp, p, pi);
4549 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4550 }
4551 }
4552 #endif
4553
4554 /* Update bgp route dampening information. */
4555 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4556 && peer->sort == BGP_PEER_EBGP) {
4557 /* Now we do normal update dampening. */
4558 ret = bgp_damp_update(pi, dest, afi, safi);
4559 if (ret == BGP_DAMP_SUPPRESSED) {
4560 bgp_dest_unlock_node(dest);
4561 return 0;
4562 }
4563 }
4564
4565 /* Nexthop reachability check - for unicast and
4566 * labeled-unicast.. */
4567 if (((afi == AFI_IP || afi == AFI_IP6)
4568 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4569 || (safi == SAFI_EVPN &&
4570 bgp_evpn_is_prefix_nht_supported(p))) {
4571 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4572 && peer->ttl == BGP_DEFAULT_TTL
4573 && !CHECK_FLAG(peer->flags,
4574 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4575 && !CHECK_FLAG(bgp->flags,
4576 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4577 connected = 1;
4578 else
4579 connected = 0;
4580
4581 struct bgp *bgp_nexthop = bgp;
4582
4583 if (pi->extra && pi->extra->bgp_orig)
4584 bgp_nexthop = pi->extra->bgp_orig;
4585
4586 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4587
4588 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4589 safi, pi, NULL, connected,
4590 p)
4591 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4592 bgp_path_info_set_flag(dest, pi,
4593 BGP_PATH_VALID);
4594 else {
4595 if (BGP_DEBUG(nht, NHT)) {
4596 zlog_debug("%s(%pI4): NH unresolved",
4597 __func__,
4598 (in_addr_t *)&attr_new->nexthop);
4599 }
4600 bgp_path_info_unset_flag(dest, pi,
4601 BGP_PATH_VALID);
4602 }
4603 } else {
4604 if (accept_own)
4605 bgp_path_info_set_flag(dest, pi,
4606 BGP_PATH_ACCEPT_OWN);
4607
4608 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4609 }
4610
4611 #ifdef ENABLE_BGP_VNC
4612 if (safi == SAFI_MPLS_VPN) {
4613 struct bgp_dest *pdest = NULL;
4614 struct bgp_table *table = NULL;
4615
4616 pdest = bgp_node_get(bgp->rib[afi][safi],
4617 (struct prefix *)prd);
4618 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4619 table = bgp_dest_get_bgp_table_info(pdest);
4620
4621 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4622 bgp, prd, table, p, pi);
4623 }
4624 bgp_dest_unlock_node(pdest);
4625 }
4626 #endif
4627
4628 /* If this is an EVPN route and some attribute has changed,
4629 * or we are explicitly told to perform a route import, process
4630 * route for import. If the extended community has changed, we
4631 * would
4632 * have done the un-import earlier and the import would result
4633 * in the
4634 * route getting injected into appropriate L2 VNIs. If it is
4635 * just
4636 * some other attribute change, the import will result in
4637 * updating
4638 * the attributes for the route in the VNI(s).
4639 */
4640 if (safi == SAFI_EVPN &&
4641 (!same_attr || force_evpn_import) &&
4642 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4643 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4644
4645 /* Process change. */
4646 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4647
4648 bgp_process(bgp, dest, afi, safi);
4649 bgp_dest_unlock_node(dest);
4650
4651 if (SAFI_UNICAST == safi
4652 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4653 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4654
4655 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4656 }
4657 if ((SAFI_MPLS_VPN == safi)
4658 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4659 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4660 }
4661
4662 #ifdef ENABLE_BGP_VNC
4663 if (SAFI_MPLS_VPN == safi) {
4664 mpls_label_t label_decoded = decode_label(label);
4665
4666 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4667 type, sub_type, &label_decoded);
4668 }
4669 if (SAFI_ENCAP == safi) {
4670 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4671 type, sub_type, NULL);
4672 }
4673 #endif
4674 if ((safi == SAFI_MPLS_VPN) &&
4675 !CHECK_FLAG(bgp->af_flags[afi][safi],
4676 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4677 !leak_success) {
4678 bgp_unlink_nexthop(pi);
4679 bgp_path_info_delete(dest, pi);
4680 }
4681 return 0;
4682 } // End of implicit withdraw
4683
4684 /* Received Logging. */
4685 if (bgp_debug_update(peer, p, NULL, 1)) {
4686 if (!peer->rcvd_attr_printed) {
4687 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4688 peer->rcvd_attr_str);
4689 peer->rcvd_attr_printed = 1;
4690 }
4691
4692 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4693 addpath_id ? 1 : 0, addpath_id, evpn,
4694 pfx_buf, sizeof(pfx_buf));
4695 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4696 }
4697
4698 /* Make new BGP info. */
4699 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4700
4701 /* Update MPLS label */
4702 if (has_valid_label) {
4703 extra = bgp_path_info_extra_get(new);
4704 if (extra->label != label) {
4705 memcpy(&extra->label, label,
4706 num_labels * sizeof(mpls_label_t));
4707 extra->num_labels = num_labels;
4708 }
4709 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4710 bgp_set_valid_label(&extra->label[0]);
4711 }
4712
4713 /* Update SRv6 SID */
4714 if (safi == SAFI_MPLS_VPN) {
4715 extra = bgp_path_info_extra_get(new);
4716 if (attr->srv6_l3vpn) {
4717 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4718 extra->num_sids = 1;
4719
4720 extra->sid[0].loc_block_len =
4721 attr->srv6_l3vpn->loc_block_len;
4722 extra->sid[0].loc_node_len =
4723 attr->srv6_l3vpn->loc_node_len;
4724 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4725 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4726 extra->sid[0].transposition_len =
4727 attr->srv6_l3vpn->transposition_len;
4728 extra->sid[0].transposition_offset =
4729 attr->srv6_l3vpn->transposition_offset;
4730 } else if (attr->srv6_vpn) {
4731 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4732 extra->num_sids = 1;
4733 }
4734 }
4735
4736 /* Nexthop reachability check. */
4737 if (((afi == AFI_IP || afi == AFI_IP6)
4738 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4739 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4740 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4741 && peer->ttl == BGP_DEFAULT_TTL
4742 && !CHECK_FLAG(peer->flags,
4743 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4744 && !CHECK_FLAG(bgp->flags,
4745 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4746 connected = 1;
4747 else
4748 connected = 0;
4749
4750 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4751
4752 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4753 connected, p)
4754 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4755 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4756 else {
4757 if (BGP_DEBUG(nht, NHT)) {
4758 char buf1[INET6_ADDRSTRLEN];
4759 inet_ntop(AF_INET,
4760 (const void *)&attr_new->nexthop,
4761 buf1, INET6_ADDRSTRLEN);
4762 zlog_debug("%s(%s): NH unresolved", __func__,
4763 buf1);
4764 }
4765 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4766 }
4767 } else {
4768 if (accept_own)
4769 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4770
4771 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4772 }
4773
4774 /* Addpath ID */
4775 new->addpath_rx_id = addpath_id;
4776
4777 /* Increment prefix */
4778 bgp_aggregate_increment(bgp, p, new, afi, safi);
4779
4780 /* Register new BGP information. */
4781 bgp_path_info_add(dest, new);
4782
4783 /* route_node_get lock */
4784 bgp_dest_unlock_node(dest);
4785
4786 #ifdef ENABLE_BGP_VNC
4787 if (safi == SAFI_MPLS_VPN) {
4788 struct bgp_dest *pdest = NULL;
4789 struct bgp_table *table = NULL;
4790
4791 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4792 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4793 table = bgp_dest_get_bgp_table_info(pdest);
4794
4795 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4796 bgp, prd, table, p, new);
4797 }
4798 bgp_dest_unlock_node(pdest);
4799 }
4800 #endif
4801
4802 /* If this is an EVPN route, process for import. */
4803 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4804 bgp_evpn_import_route(bgp, afi, safi, p, new);
4805
4806 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4807
4808 /* Process change. */
4809 bgp_process(bgp, dest, afi, safi);
4810
4811 if (SAFI_UNICAST == safi
4812 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4813 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4814 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4815 }
4816 if ((SAFI_MPLS_VPN == safi)
4817 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4818 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4819 }
4820 #ifdef ENABLE_BGP_VNC
4821 if (SAFI_MPLS_VPN == safi) {
4822 mpls_label_t label_decoded = decode_label(label);
4823
4824 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4825 sub_type, &label_decoded);
4826 }
4827 if (SAFI_ENCAP == safi) {
4828 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4829 sub_type, NULL);
4830 }
4831 #endif
4832 if ((safi == SAFI_MPLS_VPN) &&
4833 !CHECK_FLAG(bgp->af_flags[afi][safi],
4834 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4835 !leak_success) {
4836 bgp_unlink_nexthop(new);
4837 bgp_path_info_delete(dest, new);
4838 }
4839
4840 return 0;
4841
4842 /* This BGP update is filtered. Log the reason then update BGP
4843 entry. */
4844 filtered:
4845 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4846
4847 if (bgp_debug_update(peer, p, NULL, 1)) {
4848 if (!peer->rcvd_attr_printed) {
4849 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4850 peer->rcvd_attr_str);
4851 peer->rcvd_attr_printed = 1;
4852 }
4853
4854 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4855 addpath_id ? 1 : 0, addpath_id, evpn,
4856 pfx_buf, sizeof(pfx_buf));
4857 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4858 peer, pfx_buf, reason);
4859 }
4860
4861 if (pi) {
4862 /* If this is an EVPN route, un-import it as it is now filtered.
4863 */
4864 if (safi == SAFI_EVPN)
4865 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4866
4867 if (SAFI_UNICAST == safi
4868 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4869 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4870
4871 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4872 }
4873 if ((SAFI_MPLS_VPN == safi)
4874 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4875
4876 vpn_leak_to_vrf_withdraw(bgp, pi);
4877 }
4878
4879 bgp_rib_remove(dest, pi, peer, afi, safi);
4880 }
4881
4882 bgp_dest_unlock_node(dest);
4883
4884 #ifdef ENABLE_BGP_VNC
4885 /*
4886 * Filtered update is treated as an implicit withdrawal (see
4887 * bgp_rib_remove()
4888 * a few lines above)
4889 */
4890 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4891 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4892 0);
4893 }
4894 #endif
4895
4896 return 0;
4897 }
4898
4899 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4900 struct attr *attr, afi_t afi, safi_t safi, int type,
4901 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4902 uint32_t num_labels, struct bgp_route_evpn *evpn)
4903 {
4904 struct bgp *bgp;
4905 char pfx_buf[BGP_PRD_PATH_STRLEN];
4906 struct bgp_dest *dest;
4907 struct bgp_path_info *pi;
4908
4909 #ifdef ENABLE_BGP_VNC
4910 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4911 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4912 0);
4913 }
4914 #endif
4915
4916 bgp = peer->bgp;
4917
4918 /* Lookup node. */
4919 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4920
4921 /* If peer is soft reconfiguration enabled. Record input packet for
4922 * further calculation.
4923 *
4924 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4925 * routes that are filtered. This tanks out Quagga RS pretty badly due
4926 * to
4927 * the iteration over all RS clients.
4928 * Since we need to remove the entry from adj_in anyway, do that first
4929 * and
4930 * if there was no entry, we don't need to do anything more.
4931 */
4932 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4933 && peer != bgp->peer_self)
4934 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4935 peer->stat_pfx_dup_withdraw++;
4936
4937 if (bgp_debug_update(peer, p, NULL, 1)) {
4938 bgp_debug_rdpfxpath2str(
4939 afi, safi, prd, p, label, num_labels,
4940 addpath_id ? 1 : 0, addpath_id, NULL,
4941 pfx_buf, sizeof(pfx_buf));
4942 zlog_debug(
4943 "%s withdrawing route %s not in adj-in",
4944 peer->host, pfx_buf);
4945 }
4946 bgp_dest_unlock_node(dest);
4947 return 0;
4948 }
4949
4950 /* Lookup withdrawn route. */
4951 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4952 if (pi->peer == peer && pi->type == type
4953 && pi->sub_type == sub_type
4954 && pi->addpath_rx_id == addpath_id)
4955 break;
4956
4957 /* Logging. */
4958 if (bgp_debug_update(peer, p, NULL, 1)) {
4959 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4960 addpath_id ? 1 : 0, addpath_id, NULL,
4961 pfx_buf, sizeof(pfx_buf));
4962 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4963 pfx_buf);
4964 }
4965
4966 /* Withdraw specified route from routing table. */
4967 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4968 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4969 if (SAFI_UNICAST == safi
4970 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4971 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4972 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4973 }
4974 if ((SAFI_MPLS_VPN == safi)
4975 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4976
4977 vpn_leak_to_vrf_withdraw(bgp, pi);
4978 }
4979 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4980 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4981 addpath_id ? 1 : 0, addpath_id, NULL,
4982 pfx_buf, sizeof(pfx_buf));
4983 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4984 }
4985
4986 /* Unlock bgp_node_get() lock. */
4987 bgp_dest_unlock_node(dest);
4988
4989 return 0;
4990 }
4991
4992 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4993 int withdraw)
4994 {
4995 struct update_subgroup *subgrp;
4996 subgrp = peer_subgroup(peer, afi, safi);
4997 subgroup_default_originate(subgrp, withdraw);
4998 }
4999
5000
5001 /*
5002 * bgp_stop_announce_route_timer
5003 */
5004 void bgp_stop_announce_route_timer(struct peer_af *paf)
5005 {
5006 if (!paf->t_announce_route)
5007 return;
5008
5009 THREAD_OFF(paf->t_announce_route);
5010 }
5011
5012 /*
5013 * bgp_announce_route_timer_expired
5014 *
5015 * Callback that is invoked when the route announcement timer for a
5016 * peer_af expires.
5017 */
5018 static void bgp_announce_route_timer_expired(struct thread *t)
5019 {
5020 struct peer_af *paf;
5021 struct peer *peer;
5022
5023 paf = THREAD_ARG(t);
5024 peer = paf->peer;
5025
5026 if (!peer_established(peer))
5027 return;
5028
5029 if (!peer->afc_nego[paf->afi][paf->safi])
5030 return;
5031
5032 peer_af_announce_route(paf, 1);
5033
5034 /* Notify BGP conditional advertisement scanner percess */
5035 peer->advmap_config_change[paf->afi][paf->safi] = true;
5036 }
5037
5038 /*
5039 * bgp_announce_route
5040 *
5041 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5042 *
5043 * if force is true we will force an update even if the update
5044 * limiting code is attempted to kick in.
5045 */
5046 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5047 {
5048 struct peer_af *paf;
5049 struct update_subgroup *subgrp;
5050
5051 paf = peer_af_find(peer, afi, safi);
5052 if (!paf)
5053 return;
5054 subgrp = PAF_SUBGRP(paf);
5055
5056 /*
5057 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5058 * or a refresh has already been triggered.
5059 */
5060 if (!subgrp || paf->t_announce_route)
5061 return;
5062
5063 if (force)
5064 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5065
5066 /*
5067 * Start a timer to stagger/delay the announce. This serves
5068 * two purposes - announcement can potentially be combined for
5069 * multiple peers and the announcement doesn't happen in the
5070 * vty context.
5071 */
5072 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5073 (subgrp->peer_count == 1)
5074 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5075 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5076 &paf->t_announce_route);
5077 }
5078
5079 /*
5080 * Announce routes from all AF tables to a peer.
5081 *
5082 * This should ONLY be called when there is a need to refresh the
5083 * routes to the peer based on a policy change for this peer alone
5084 * or a route refresh request received from the peer.
5085 * The operation will result in splitting the peer from its existing
5086 * subgroups and putting it in new subgroups.
5087 */
5088 void bgp_announce_route_all(struct peer *peer)
5089 {
5090 afi_t afi;
5091 safi_t safi;
5092
5093 FOREACH_AFI_SAFI (afi, safi)
5094 bgp_announce_route(peer, afi, safi, false);
5095 }
5096
5097 /* Flag or unflag bgp_dest to determine whether it should be treated by
5098 * bgp_soft_reconfig_table_task.
5099 * Flag if flag is true. Unflag if flag is false.
5100 */
5101 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5102 {
5103 struct bgp_dest *dest;
5104 struct bgp_adj_in *ain;
5105
5106 if (!table)
5107 return;
5108
5109 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5110 for (ain = dest->adj_in; ain; ain = ain->next) {
5111 if (ain->peer != NULL)
5112 break;
5113 }
5114 if (flag && ain != NULL && ain->peer != NULL)
5115 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5116 else
5117 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5118 }
5119 }
5120
5121 static int bgp_soft_reconfig_table_update(struct peer *peer,
5122 struct bgp_dest *dest,
5123 struct bgp_adj_in *ain, afi_t afi,
5124 safi_t safi, struct prefix_rd *prd)
5125 {
5126 struct bgp_path_info *pi;
5127 uint32_t num_labels = 0;
5128 mpls_label_t *label_pnt = NULL;
5129 struct bgp_route_evpn evpn;
5130
5131 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5132 if (pi->peer == peer)
5133 break;
5134
5135 if (pi && pi->extra)
5136 num_labels = pi->extra->num_labels;
5137 if (num_labels)
5138 label_pnt = &pi->extra->label[0];
5139 if (pi)
5140 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5141 sizeof(evpn));
5142 else
5143 memset(&evpn, 0, sizeof(evpn));
5144
5145 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5146 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
5147 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
5148 &evpn);
5149 }
5150
5151 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5152 struct bgp_table *table,
5153 struct prefix_rd *prd)
5154 {
5155 int ret;
5156 struct bgp_dest *dest;
5157 struct bgp_adj_in *ain;
5158
5159 if (!table)
5160 table = peer->bgp->rib[afi][safi];
5161
5162 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5163 for (ain = dest->adj_in; ain; ain = ain->next) {
5164 if (ain->peer != peer)
5165 continue;
5166
5167 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
5168 afi, safi, prd);
5169
5170 if (ret < 0) {
5171 bgp_dest_unlock_node(dest);
5172 return;
5173 }
5174 }
5175 }
5176
5177 /* Do soft reconfig table per bgp table.
5178 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5179 * when BGP_NODE_SOFT_RECONFIG is set,
5180 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5181 * Schedule a new thread to continue the job.
5182 * Without splitting the full job into several part,
5183 * vtysh waits for the job to finish before responding to a BGP command
5184 */
5185 static void bgp_soft_reconfig_table_task(struct thread *thread)
5186 {
5187 uint32_t iter, max_iter;
5188 int ret;
5189 struct bgp_dest *dest;
5190 struct bgp_adj_in *ain;
5191 struct peer *peer;
5192 struct bgp_table *table;
5193 struct prefix_rd *prd;
5194 struct listnode *node, *nnode;
5195
5196 table = THREAD_ARG(thread);
5197 prd = NULL;
5198
5199 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5200 if (table->soft_reconfig_init) {
5201 /* first call of the function with a new srta structure.
5202 * Don't do any treatment this time on nodes
5203 * in order vtysh to respond quickly
5204 */
5205 max_iter = 0;
5206 }
5207
5208 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5209 dest = bgp_route_next(dest)) {
5210 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5211 continue;
5212
5213 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5214
5215 for (ain = dest->adj_in; ain; ain = ain->next) {
5216 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5217 nnode, peer)) {
5218 if (ain->peer != peer)
5219 continue;
5220
5221 ret = bgp_soft_reconfig_table_update(
5222 peer, dest, ain, table->afi,
5223 table->safi, prd);
5224 iter++;
5225
5226 if (ret < 0) {
5227 bgp_dest_unlock_node(dest);
5228 listnode_delete(
5229 table->soft_reconfig_peers,
5230 peer);
5231 bgp_announce_route(peer, table->afi,
5232 table->safi, false);
5233 if (list_isempty(
5234 table->soft_reconfig_peers)) {
5235 list_delete(
5236 &table->soft_reconfig_peers);
5237 bgp_soft_reconfig_table_flag(
5238 table, false);
5239 return;
5240 }
5241 }
5242 }
5243 }
5244 }
5245
5246 /* we're either starting the initial iteration,
5247 * or we're going to continue an ongoing iteration
5248 */
5249 if (dest || table->soft_reconfig_init) {
5250 table->soft_reconfig_init = false;
5251 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5252 table, 0, &table->soft_reconfig_thread);
5253 return;
5254 }
5255 /* we're done, clean up the background iteration context info and
5256 schedule route annoucement
5257 */
5258 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5259 listnode_delete(table->soft_reconfig_peers, peer);
5260 bgp_announce_route(peer, table->afi, table->safi, false);
5261 }
5262
5263 list_delete(&table->soft_reconfig_peers);
5264 }
5265
5266
5267 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5268 * and peer.
5269 * - bgp cannot be NULL
5270 * - if table and peer are NULL, cancel all threads within the bgp instance
5271 * - if table is NULL and peer is not,
5272 * remove peer in all threads within the bgp instance
5273 * - if peer is NULL, cancel all threads matching table within the bgp instance
5274 */
5275 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5276 const struct bgp_table *table,
5277 const struct peer *peer)
5278 {
5279 struct peer *npeer;
5280 struct listnode *node, *nnode;
5281 int afi, safi;
5282 struct bgp_table *ntable;
5283
5284 if (!bgp)
5285 return;
5286
5287 FOREACH_AFI_SAFI (afi, safi) {
5288 ntable = bgp->rib[afi][safi];
5289 if (!ntable)
5290 continue;
5291 if (table && table != ntable)
5292 continue;
5293
5294 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5295 npeer)) {
5296 if (peer && peer != npeer)
5297 continue;
5298 listnode_delete(ntable->soft_reconfig_peers, npeer);
5299 }
5300
5301 if (!ntable->soft_reconfig_peers
5302 || !list_isempty(ntable->soft_reconfig_peers))
5303 continue;
5304
5305 list_delete(&ntable->soft_reconfig_peers);
5306 bgp_soft_reconfig_table_flag(ntable, false);
5307 THREAD_OFF(ntable->soft_reconfig_thread);
5308 }
5309 }
5310
5311 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5312 {
5313 struct bgp_dest *dest;
5314 struct bgp_table *table;
5315 struct listnode *node, *nnode;
5316 struct peer *npeer;
5317 struct peer_af *paf;
5318
5319 if (!peer_established(peer))
5320 return;
5321
5322 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5323 && (safi != SAFI_EVPN)) {
5324 table = peer->bgp->rib[afi][safi];
5325 if (!table)
5326 return;
5327
5328 table->soft_reconfig_init = true;
5329
5330 if (!table->soft_reconfig_peers)
5331 table->soft_reconfig_peers = list_new();
5332 npeer = NULL;
5333 /* add peer to the table soft_reconfig_peers if not already
5334 * there
5335 */
5336 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5337 npeer)) {
5338 if (peer == npeer)
5339 break;
5340 }
5341 if (peer != npeer)
5342 listnode_add(table->soft_reconfig_peers, peer);
5343
5344 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5345 * on table would start back at the beginning.
5346 */
5347 bgp_soft_reconfig_table_flag(table, true);
5348
5349 if (!table->soft_reconfig_thread)
5350 thread_add_event(bm->master,
5351 bgp_soft_reconfig_table_task, table, 0,
5352 &table->soft_reconfig_thread);
5353 /* Cancel bgp_announce_route_timer_expired threads.
5354 * bgp_announce_route_timer_expired threads have been scheduled
5355 * to announce routes as soon as the soft_reconfigure process
5356 * finishes.
5357 * In this case, soft_reconfigure is also scheduled by using
5358 * a thread but is planned after the
5359 * bgp_announce_route_timer_expired threads. It means that,
5360 * without cancelling the threads, the route announcement task
5361 * would run before the soft reconfiguration one. That would
5362 * useless and would block vtysh during several seconds. Route
5363 * announcements are rescheduled as soon as the soft_reconfigure
5364 * process finishes.
5365 */
5366 paf = peer_af_find(peer, afi, safi);
5367 if (paf)
5368 bgp_stop_announce_route_timer(paf);
5369 } else
5370 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5371 dest = bgp_route_next(dest)) {
5372 table = bgp_dest_get_bgp_table_info(dest);
5373
5374 if (table == NULL)
5375 continue;
5376
5377 const struct prefix *p = bgp_dest_get_prefix(dest);
5378 struct prefix_rd prd;
5379
5380 prd.family = AF_UNSPEC;
5381 prd.prefixlen = 64;
5382 memcpy(&prd.val, p->u.val, 8);
5383
5384 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5385 }
5386 }
5387
5388
5389 struct bgp_clear_node_queue {
5390 struct bgp_dest *dest;
5391 };
5392
5393 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5394 {
5395 struct bgp_clear_node_queue *cnq = data;
5396 struct bgp_dest *dest = cnq->dest;
5397 struct peer *peer = wq->spec.data;
5398 struct bgp_path_info *pi;
5399 struct bgp *bgp;
5400 afi_t afi = bgp_dest_table(dest)->afi;
5401 safi_t safi = bgp_dest_table(dest)->safi;
5402
5403 assert(dest && peer);
5404 bgp = peer->bgp;
5405
5406 /* It is possible that we have multiple paths for a prefix from a peer
5407 * if that peer is using AddPath.
5408 */
5409 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5410 if (pi->peer != peer)
5411 continue;
5412
5413 /* graceful restart STALE flag set. */
5414 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5415 && peer->nsf[afi][safi])
5416 || CHECK_FLAG(peer->af_sflags[afi][safi],
5417 PEER_STATUS_ENHANCED_REFRESH))
5418 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5419 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5420 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5421 else {
5422 /* If this is an EVPN route, process for
5423 * un-import. */
5424 if (safi == SAFI_EVPN)
5425 bgp_evpn_unimport_route(
5426 bgp, afi, safi,
5427 bgp_dest_get_prefix(dest), pi);
5428 /* Handle withdraw for VRF route-leaking and L3VPN */
5429 if (SAFI_UNICAST == safi
5430 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5431 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5432 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5433 bgp, pi);
5434 }
5435 if (SAFI_MPLS_VPN == safi &&
5436 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5437 vpn_leak_to_vrf_withdraw(bgp, pi);
5438 }
5439
5440 bgp_rib_remove(dest, pi, peer, afi, safi);
5441 }
5442 }
5443 return WQ_SUCCESS;
5444 }
5445
5446 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5447 {
5448 struct bgp_clear_node_queue *cnq = data;
5449 struct bgp_dest *dest = cnq->dest;
5450 struct bgp_table *table = bgp_dest_table(dest);
5451
5452 bgp_dest_unlock_node(dest);
5453 bgp_table_unlock(table);
5454 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5455 }
5456
5457 static void bgp_clear_node_complete(struct work_queue *wq)
5458 {
5459 struct peer *peer = wq->spec.data;
5460
5461 /* Tickle FSM to start moving again */
5462 BGP_EVENT_ADD(peer, Clearing_Completed);
5463
5464 peer_unlock(peer); /* bgp_clear_route */
5465 }
5466
5467 static void bgp_clear_node_queue_init(struct peer *peer)
5468 {
5469 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5470
5471 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5472 #undef CLEAR_QUEUE_NAME_LEN
5473
5474 peer->clear_node_queue = work_queue_new(bm->master, wname);
5475 peer->clear_node_queue->spec.hold = 10;
5476 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5477 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5478 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5479 peer->clear_node_queue->spec.max_retries = 0;
5480
5481 /* we only 'lock' this peer reference when the queue is actually active
5482 */
5483 peer->clear_node_queue->spec.data = peer;
5484 }
5485
5486 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5487 struct bgp_table *table)
5488 {
5489 struct bgp_dest *dest;
5490 int force = peer->bgp->process_queue ? 0 : 1;
5491
5492 if (!table)
5493 table = peer->bgp->rib[afi][safi];
5494
5495 /* If still no table => afi/safi isn't configured at all or smth. */
5496 if (!table)
5497 return;
5498
5499 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5500 struct bgp_path_info *pi, *next;
5501 struct bgp_adj_in *ain;
5502 struct bgp_adj_in *ain_next;
5503
5504 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5505 * queued for every clearing peer, regardless of whether it is
5506 * relevant to the peer at hand.
5507 *
5508 * Overview: There are 3 different indices which need to be
5509 * scrubbed, potentially, when a peer is removed:
5510 *
5511 * 1 peer's routes visible via the RIB (ie accepted routes)
5512 * 2 peer's routes visible by the (optional) peer's adj-in index
5513 * 3 other routes visible by the peer's adj-out index
5514 *
5515 * 3 there is no hurry in scrubbing, once the struct peer is
5516 * removed from bgp->peer, we could just GC such deleted peer's
5517 * adj-outs at our leisure.
5518 *
5519 * 1 and 2 must be 'scrubbed' in some way, at least made
5520 * invisible via RIB index before peer session is allowed to be
5521 * brought back up. So one needs to know when such a 'search' is
5522 * complete.
5523 *
5524 * Ideally:
5525 *
5526 * - there'd be a single global queue or a single RIB walker
5527 * - rather than tracking which route_nodes still need to be
5528 * examined on a peer basis, we'd track which peers still
5529 * aren't cleared
5530 *
5531 * Given that our per-peer prefix-counts now should be reliable,
5532 * this may actually be achievable. It doesn't seem to be a huge
5533 * problem at this time,
5534 *
5535 * It is possible that we have multiple paths for a prefix from
5536 * a peer
5537 * if that peer is using AddPath.
5538 */
5539 ain = dest->adj_in;
5540 while (ain) {
5541 ain_next = ain->next;
5542
5543 if (ain->peer == peer)
5544 bgp_adj_in_remove(dest, ain);
5545
5546 ain = ain_next;
5547 }
5548
5549 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5550 next = pi->next;
5551 if (pi->peer != peer)
5552 continue;
5553
5554 if (force)
5555 bgp_path_info_reap(dest, pi);
5556 else {
5557 struct bgp_clear_node_queue *cnq;
5558
5559 /* both unlocked in bgp_clear_node_queue_del */
5560 bgp_table_lock(bgp_dest_table(dest));
5561 bgp_dest_lock_node(dest);
5562 cnq = XCALLOC(
5563 MTYPE_BGP_CLEAR_NODE_QUEUE,
5564 sizeof(struct bgp_clear_node_queue));
5565 cnq->dest = dest;
5566 work_queue_add(peer->clear_node_queue, cnq);
5567 break;
5568 }
5569 }
5570 }
5571 return;
5572 }
5573
5574 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5575 {
5576 struct bgp_dest *dest;
5577 struct bgp_table *table;
5578
5579 if (peer->clear_node_queue == NULL)
5580 bgp_clear_node_queue_init(peer);
5581
5582 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5583 * Idle until it receives a Clearing_Completed event. This protects
5584 * against peers which flap faster than we can we clear, which could
5585 * lead to:
5586 *
5587 * a) race with routes from the new session being installed before
5588 * clear_route_node visits the node (to delete the route of that
5589 * peer)
5590 * b) resource exhaustion, clear_route_node likely leads to an entry
5591 * on the process_main queue. Fast-flapping could cause that queue
5592 * to grow and grow.
5593 */
5594
5595 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5596 * the unlock will happen upon work-queue completion; other wise, the
5597 * unlock happens at the end of this function.
5598 */
5599 if (!peer->clear_node_queue->thread)
5600 peer_lock(peer);
5601
5602 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5603 bgp_clear_route_table(peer, afi, safi, NULL);
5604 else
5605 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5606 dest = bgp_route_next(dest)) {
5607 table = bgp_dest_get_bgp_table_info(dest);
5608 if (!table)
5609 continue;
5610
5611 bgp_clear_route_table(peer, afi, safi, table);
5612 }
5613
5614 /* unlock if no nodes got added to the clear-node-queue. */
5615 if (!peer->clear_node_queue->thread)
5616 peer_unlock(peer);
5617 }
5618
5619 void bgp_clear_route_all(struct peer *peer)
5620 {
5621 afi_t afi;
5622 safi_t safi;
5623
5624 FOREACH_AFI_SAFI (afi, safi)
5625 bgp_clear_route(peer, afi, safi);
5626
5627 #ifdef ENABLE_BGP_VNC
5628 rfapiProcessPeerDown(peer);
5629 #endif
5630 }
5631
5632 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5633 {
5634 struct bgp_table *table;
5635 struct bgp_dest *dest;
5636 struct bgp_adj_in *ain;
5637 struct bgp_adj_in *ain_next;
5638
5639 table = peer->bgp->rib[afi][safi];
5640
5641 /* It is possible that we have multiple paths for a prefix from a peer
5642 * if that peer is using AddPath.
5643 */
5644 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5645 ain = dest->adj_in;
5646
5647 while (ain) {
5648 ain_next = ain->next;
5649
5650 if (ain->peer == peer)
5651 bgp_adj_in_remove(dest, ain);
5652
5653 ain = ain_next;
5654 }
5655 }
5656 }
5657
5658 /* If any of the routes from the peer have been marked with the NO_LLGR
5659 * community, either as sent by the peer, or as the result of a configured
5660 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5661 * operation of [RFC4271].
5662 */
5663 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5664 {
5665 struct bgp_dest *dest;
5666 struct bgp_path_info *pi;
5667 struct bgp_table *table;
5668
5669 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5670 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5671 dest = bgp_route_next(dest)) {
5672 struct bgp_dest *rm;
5673
5674 /* look for neighbor in tables */
5675 table = bgp_dest_get_bgp_table_info(dest);
5676 if (!table)
5677 continue;
5678
5679 for (rm = bgp_table_top(table); rm;
5680 rm = bgp_route_next(rm))
5681 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5682 pi = pi->next) {
5683 if (pi->peer != peer)
5684 continue;
5685 if (CHECK_FLAG(
5686 peer->af_sflags[afi][safi],
5687 PEER_STATUS_LLGR_WAIT) &&
5688 bgp_attr_get_community(pi->attr) &&
5689 !community_include(
5690 bgp_attr_get_community(
5691 pi->attr),
5692 COMMUNITY_NO_LLGR))
5693 continue;
5694 if (!CHECK_FLAG(pi->flags,
5695 BGP_PATH_STALE))
5696 continue;
5697
5698 /*
5699 * If this is VRF leaked route
5700 * process for withdraw.
5701 */
5702 if (pi->sub_type ==
5703 BGP_ROUTE_IMPORTED &&
5704 peer->bgp->inst_type ==
5705 BGP_INSTANCE_TYPE_DEFAULT)
5706 vpn_leak_to_vrf_withdraw(
5707 peer->bgp, pi);
5708
5709 bgp_rib_remove(rm, pi, peer, afi, safi);
5710 break;
5711 }
5712 }
5713 } else {
5714 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5715 dest = bgp_route_next(dest))
5716 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5717 pi = pi->next) {
5718 if (pi->peer != peer)
5719 continue;
5720 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5721 PEER_STATUS_LLGR_WAIT) &&
5722 bgp_attr_get_community(pi->attr) &&
5723 !community_include(
5724 bgp_attr_get_community(pi->attr),
5725 COMMUNITY_NO_LLGR))
5726 continue;
5727 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5728 continue;
5729 if (safi == SAFI_UNICAST &&
5730 (peer->bgp->inst_type ==
5731 BGP_INSTANCE_TYPE_VRF ||
5732 peer->bgp->inst_type ==
5733 BGP_INSTANCE_TYPE_DEFAULT))
5734 vpn_leak_from_vrf_withdraw(
5735 bgp_get_default(), peer->bgp,
5736 pi);
5737
5738 bgp_rib_remove(dest, pi, peer, afi, safi);
5739 break;
5740 }
5741 }
5742 }
5743
5744 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5745 {
5746 struct bgp_dest *dest, *ndest;
5747 struct bgp_path_info *pi;
5748 struct bgp_table *table;
5749
5750 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5751 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5752 dest = bgp_route_next(dest)) {
5753 table = bgp_dest_get_bgp_table_info(dest);
5754 if (!table)
5755 continue;
5756
5757 for (ndest = bgp_table_top(table); ndest;
5758 ndest = bgp_route_next(ndest)) {
5759 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5760 pi = pi->next) {
5761 if (pi->peer != peer)
5762 continue;
5763
5764 if ((CHECK_FLAG(
5765 peer->af_sflags[afi][safi],
5766 PEER_STATUS_ENHANCED_REFRESH))
5767 && !CHECK_FLAG(pi->flags,
5768 BGP_PATH_STALE)
5769 && !CHECK_FLAG(
5770 pi->flags,
5771 BGP_PATH_UNUSEABLE)) {
5772 if (bgp_debug_neighbor_events(
5773 peer))
5774 zlog_debug(
5775 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5776 peer,
5777 afi2str(afi),
5778 safi2str(safi),
5779 bgp_dest_get_prefix(
5780 ndest));
5781
5782 bgp_path_info_set_flag(
5783 ndest, pi,
5784 BGP_PATH_STALE);
5785 }
5786 }
5787 }
5788 }
5789 } else {
5790 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5791 dest = bgp_route_next(dest)) {
5792 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5793 pi = pi->next) {
5794 if (pi->peer != peer)
5795 continue;
5796
5797 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5798 PEER_STATUS_ENHANCED_REFRESH))
5799 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5800 && !CHECK_FLAG(pi->flags,
5801 BGP_PATH_UNUSEABLE)) {
5802 if (bgp_debug_neighbor_events(peer))
5803 zlog_debug(
5804 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5805 peer, afi2str(afi),
5806 safi2str(safi),
5807 bgp_dest_get_prefix(
5808 dest));
5809
5810 bgp_path_info_set_flag(dest, pi,
5811 BGP_PATH_STALE);
5812 }
5813 }
5814 }
5815 }
5816 }
5817
5818 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5819 {
5820 if (peer->sort == BGP_PEER_IBGP)
5821 return true;
5822
5823 if (peer->sort == BGP_PEER_EBGP
5824 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5825 || FILTER_LIST_OUT_NAME(filter)
5826 || DISTRIBUTE_OUT_NAME(filter)))
5827 return true;
5828 return false;
5829 }
5830
5831 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5832 {
5833 if (peer->sort == BGP_PEER_IBGP)
5834 return true;
5835
5836 if (peer->sort == BGP_PEER_EBGP
5837 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5838 || FILTER_LIST_IN_NAME(filter)
5839 || DISTRIBUTE_IN_NAME(filter)))
5840 return true;
5841 return false;
5842 }
5843
5844 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5845 safi_t safi)
5846 {
5847 struct bgp_dest *dest;
5848 struct bgp_path_info *pi;
5849 struct bgp_path_info *next;
5850
5851 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5852 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5853 const struct prefix *p = bgp_dest_get_prefix(dest);
5854
5855 next = pi->next;
5856
5857 /* Unimport EVPN routes from VRFs */
5858 if (safi == SAFI_EVPN)
5859 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5860 SAFI_EVPN, p, pi);
5861
5862 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5863 && pi->type == ZEBRA_ROUTE_BGP
5864 && (pi->sub_type == BGP_ROUTE_NORMAL
5865 || pi->sub_type == BGP_ROUTE_AGGREGATE
5866 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5867
5868 if (bgp_fibupd_safi(safi))
5869 bgp_zebra_withdraw(p, pi, bgp, safi);
5870 }
5871
5872 bgp_path_info_reap(dest, pi);
5873 }
5874 }
5875
5876 /* Delete all kernel routes. */
5877 void bgp_cleanup_routes(struct bgp *bgp)
5878 {
5879 afi_t afi;
5880 struct bgp_dest *dest;
5881 struct bgp_table *table;
5882
5883 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5884 if (afi == AFI_L2VPN)
5885 continue;
5886 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5887 SAFI_UNICAST);
5888 /*
5889 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5890 */
5891 if (afi != AFI_L2VPN) {
5892 safi_t safi;
5893 safi = SAFI_MPLS_VPN;
5894 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5895 dest = bgp_route_next(dest)) {
5896 table = bgp_dest_get_bgp_table_info(dest);
5897 if (table != NULL) {
5898 bgp_cleanup_table(bgp, table, safi);
5899 bgp_table_finish(&table);
5900 bgp_dest_set_bgp_table_info(dest, NULL);
5901 bgp_dest_unlock_node(dest);
5902 }
5903 }
5904 safi = SAFI_ENCAP;
5905 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5906 dest = bgp_route_next(dest)) {
5907 table = bgp_dest_get_bgp_table_info(dest);
5908 if (table != NULL) {
5909 bgp_cleanup_table(bgp, table, safi);
5910 bgp_table_finish(&table);
5911 bgp_dest_set_bgp_table_info(dest, NULL);
5912 bgp_dest_unlock_node(dest);
5913 }
5914 }
5915 }
5916 }
5917 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5918 dest = bgp_route_next(dest)) {
5919 table = bgp_dest_get_bgp_table_info(dest);
5920 if (table != NULL) {
5921 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5922 bgp_table_finish(&table);
5923 bgp_dest_set_bgp_table_info(dest, NULL);
5924 bgp_dest_unlock_node(dest);
5925 }
5926 }
5927 }
5928
5929 void bgp_reset(void)
5930 {
5931 vty_reset();
5932 bgp_zclient_reset();
5933 access_list_reset();
5934 prefix_list_reset();
5935 }
5936
5937 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5938 {
5939 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5940 && CHECK_FLAG(peer->af_cap[afi][safi],
5941 PEER_CAP_ADDPATH_AF_TX_RCV));
5942 }
5943
5944 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5945 value. */
5946 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5947 struct bgp_nlri *packet)
5948 {
5949 uint8_t *pnt;
5950 uint8_t *lim;
5951 struct prefix p;
5952 int psize;
5953 int ret;
5954 afi_t afi;
5955 safi_t safi;
5956 bool addpath_capable;
5957 uint32_t addpath_id;
5958
5959 pnt = packet->nlri;
5960 lim = pnt + packet->length;
5961 afi = packet->afi;
5962 safi = packet->safi;
5963 addpath_id = 0;
5964 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5965
5966 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5967 syntactic validity. If the field is syntactically incorrect,
5968 then the Error Subcode is set to Invalid Network Field. */
5969 for (; pnt < lim; pnt += psize) {
5970 /* Clear prefix structure. */
5971 memset(&p, 0, sizeof(p));
5972
5973 if (addpath_capable) {
5974
5975 /* When packet overflow occurs return immediately. */
5976 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5977 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5978
5979 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5980 addpath_id = ntohl(addpath_id);
5981 pnt += BGP_ADDPATH_ID_LEN;
5982 }
5983
5984 /* Fetch prefix length. */
5985 p.prefixlen = *pnt++;
5986 /* afi/safi validity already verified by caller,
5987 * bgp_update_receive */
5988 p.family = afi2family(afi);
5989
5990 /* Prefix length check. */
5991 if (p.prefixlen > prefix_blen(&p) * 8) {
5992 flog_err(
5993 EC_BGP_UPDATE_RCV,
5994 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5995 peer->host, p.prefixlen, packet->afi);
5996 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5997 }
5998
5999 /* Packet size overflow check. */
6000 psize = PSIZE(p.prefixlen);
6001
6002 /* When packet overflow occur return immediately. */
6003 if (pnt + psize > lim) {
6004 flog_err(
6005 EC_BGP_UPDATE_RCV,
6006 "%s [Error] Update packet error (prefix length %d overflows packet)",
6007 peer->host, p.prefixlen);
6008 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6009 }
6010
6011 /* Defensive coding, double-check the psize fits in a struct
6012 * prefix for the v4 and v6 afi's and unicast/multicast */
6013 if (psize > (ssize_t)sizeof(p.u.val)) {
6014 flog_err(
6015 EC_BGP_UPDATE_RCV,
6016 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6017 peer->host, p.prefixlen, sizeof(p.u.val));
6018 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6019 }
6020
6021 /* Fetch prefix from NLRI packet. */
6022 memcpy(p.u.val, pnt, psize);
6023
6024 /* Check address. */
6025 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6026 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6027 /* From RFC4271 Section 6.3:
6028 *
6029 * If a prefix in the NLRI field is semantically
6030 * incorrect
6031 * (e.g., an unexpected multicast IP address),
6032 * an error SHOULD
6033 * be logged locally, and the prefix SHOULD be
6034 * ignored.
6035 */
6036 flog_err(
6037 EC_BGP_UPDATE_RCV,
6038 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6039 peer->host, &p.u.prefix4);
6040 continue;
6041 }
6042 }
6043
6044 /* Check address. */
6045 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6046 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6047 flog_err(
6048 EC_BGP_UPDATE_RCV,
6049 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6050 peer->host, &p.u.prefix6);
6051
6052 continue;
6053 }
6054 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6055 flog_err(
6056 EC_BGP_UPDATE_RCV,
6057 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6058 peer->host, &p.u.prefix6);
6059
6060 continue;
6061 }
6062 }
6063
6064 /* Normal process. */
6065 if (attr)
6066 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
6067 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
6068 NULL, NULL, 0, 0, NULL);
6069 else
6070 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
6071 safi, ZEBRA_ROUTE_BGP,
6072 BGP_ROUTE_NORMAL, NULL, NULL, 0,
6073 NULL);
6074
6075 /* Do not send BGP notification twice when maximum-prefix count
6076 * overflow. */
6077 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6078 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6079
6080 /* Address family configuration mismatch. */
6081 if (ret < 0)
6082 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
6083 }
6084
6085 /* Packet length consistency check. */
6086 if (pnt != lim) {
6087 flog_err(
6088 EC_BGP_UPDATE_RCV,
6089 "%s [Error] Update packet error (prefix length mismatch with total length)",
6090 peer->host);
6091 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6092 }
6093
6094 return BGP_NLRI_PARSE_OK;
6095 }
6096
6097 static struct bgp_static *bgp_static_new(void)
6098 {
6099 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6100 }
6101
6102 static void bgp_static_free(struct bgp_static *bgp_static)
6103 {
6104 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6105 route_map_counter_decrement(bgp_static->rmap.map);
6106
6107 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6108 XFREE(MTYPE_BGP_STATIC, bgp_static);
6109 }
6110
6111 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6112 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6113 {
6114 struct bgp_dest *dest;
6115 struct bgp_path_info *pi;
6116 struct bgp_path_info *new;
6117 struct bgp_path_info rmap_path;
6118 struct attr attr;
6119 struct attr *attr_new;
6120 route_map_result_t ret;
6121 #ifdef ENABLE_BGP_VNC
6122 int vnc_implicit_withdraw = 0;
6123 #endif
6124
6125 assert(bgp_static);
6126
6127 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6128
6129 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6130
6131 attr.nexthop = bgp_static->igpnexthop;
6132 attr.med = bgp_static->igpmetric;
6133 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6134
6135 if (afi == AFI_IP)
6136 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6137
6138 if (bgp_static->atomic)
6139 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6140
6141 /* Store label index, if required. */
6142 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6143 attr.label_index = bgp_static->label_index;
6144 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6145 }
6146
6147 /* Apply route-map. */
6148 if (bgp_static->rmap.name) {
6149 struct attr attr_tmp = attr;
6150
6151 memset(&rmap_path, 0, sizeof(rmap_path));
6152 rmap_path.peer = bgp->peer_self;
6153 rmap_path.attr = &attr_tmp;
6154
6155 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6156
6157 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6158
6159 bgp->peer_self->rmap_type = 0;
6160
6161 if (ret == RMAP_DENYMATCH) {
6162 /* Free uninterned attribute. */
6163 bgp_attr_flush(&attr_tmp);
6164
6165 /* Unintern original. */
6166 aspath_unintern(&attr.aspath);
6167 bgp_static_withdraw(bgp, p, afi, safi);
6168 bgp_dest_unlock_node(dest);
6169 return;
6170 }
6171
6172 if (bgp_in_graceful_shutdown(bgp))
6173 bgp_attr_add_gshut_community(&attr_tmp);
6174
6175 attr_new = bgp_attr_intern(&attr_tmp);
6176 } else {
6177
6178 if (bgp_in_graceful_shutdown(bgp))
6179 bgp_attr_add_gshut_community(&attr);
6180
6181 attr_new = bgp_attr_intern(&attr);
6182 }
6183
6184 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6185 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6186 && pi->sub_type == BGP_ROUTE_STATIC)
6187 break;
6188
6189 if (pi) {
6190 if (attrhash_cmp(pi->attr, attr_new)
6191 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6192 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6193 bgp_dest_unlock_node(dest);
6194 bgp_attr_unintern(&attr_new);
6195 aspath_unintern(&attr.aspath);
6196 return;
6197 } else {
6198 /* The attribute is changed. */
6199 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6200
6201 /* Rewrite BGP route information. */
6202 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6203 bgp_path_info_restore(dest, pi);
6204 else
6205 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6206 #ifdef ENABLE_BGP_VNC
6207 if ((afi == AFI_IP || afi == AFI_IP6)
6208 && (safi == SAFI_UNICAST)) {
6209 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6210 /*
6211 * Implicit withdraw case.
6212 * We have to do this before pi is
6213 * changed
6214 */
6215 ++vnc_implicit_withdraw;
6216 vnc_import_bgp_del_route(bgp, p, pi);
6217 vnc_import_bgp_exterior_del_route(
6218 bgp, p, pi);
6219 }
6220 }
6221 #endif
6222 bgp_attr_unintern(&pi->attr);
6223 pi->attr = attr_new;
6224 pi->uptime = monotime(NULL);
6225 #ifdef ENABLE_BGP_VNC
6226 if ((afi == AFI_IP || afi == AFI_IP6)
6227 && (safi == SAFI_UNICAST)) {
6228 if (vnc_implicit_withdraw) {
6229 vnc_import_bgp_add_route(bgp, p, pi);
6230 vnc_import_bgp_exterior_add_route(
6231 bgp, p, pi);
6232 }
6233 }
6234 #endif
6235
6236 /* Nexthop reachability check. */
6237 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6238 && (safi == SAFI_UNICAST
6239 || safi == SAFI_LABELED_UNICAST)) {
6240
6241 struct bgp *bgp_nexthop = bgp;
6242
6243 if (pi->extra && pi->extra->bgp_orig)
6244 bgp_nexthop = pi->extra->bgp_orig;
6245
6246 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6247 afi, safi, pi, NULL,
6248 0, p))
6249 bgp_path_info_set_flag(dest, pi,
6250 BGP_PATH_VALID);
6251 else {
6252 if (BGP_DEBUG(nht, NHT)) {
6253 char buf1[INET6_ADDRSTRLEN];
6254 inet_ntop(p->family,
6255 &p->u.prefix, buf1,
6256 INET6_ADDRSTRLEN);
6257 zlog_debug(
6258 "%s(%s): Route not in table, not advertising",
6259 __func__, buf1);
6260 }
6261 bgp_path_info_unset_flag(
6262 dest, pi, BGP_PATH_VALID);
6263 }
6264 } else {
6265 /* Delete the NHT structure if any, if we're
6266 * toggling between
6267 * enabling/disabling import check. We
6268 * deregister the route
6269 * from NHT to avoid overloading NHT and the
6270 * process interaction
6271 */
6272 bgp_unlink_nexthop(pi);
6273 bgp_path_info_set_flag(dest, pi,
6274 BGP_PATH_VALID);
6275 }
6276 /* Process change. */
6277 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6278 bgp_process(bgp, dest, afi, safi);
6279
6280 if (SAFI_UNICAST == safi
6281 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6282 || bgp->inst_type
6283 == BGP_INSTANCE_TYPE_DEFAULT)) {
6284 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6285 pi);
6286 }
6287
6288 bgp_dest_unlock_node(dest);
6289 aspath_unintern(&attr.aspath);
6290 return;
6291 }
6292 }
6293
6294 /* Make new BGP info. */
6295 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6296 attr_new, dest);
6297 /* Nexthop reachability check. */
6298 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6299 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6300 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6301 p))
6302 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6303 else {
6304 if (BGP_DEBUG(nht, NHT)) {
6305 char buf1[INET6_ADDRSTRLEN];
6306 inet_ntop(p->family, &p->u.prefix, buf1,
6307 INET6_ADDRSTRLEN);
6308 zlog_debug(
6309 "%s(%s): Route not in table, not advertising",
6310 __func__, buf1);
6311 }
6312 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6313 }
6314 } else {
6315 /* Delete the NHT structure if any, if we're toggling between
6316 * enabling/disabling import check. We deregister the route
6317 * from NHT to avoid overloading NHT and the process interaction
6318 */
6319 bgp_unlink_nexthop(new);
6320
6321 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6322 }
6323
6324 /* Aggregate address increment. */
6325 bgp_aggregate_increment(bgp, p, new, afi, safi);
6326
6327 /* Register new BGP information. */
6328 bgp_path_info_add(dest, new);
6329
6330 /* route_node_get lock */
6331 bgp_dest_unlock_node(dest);
6332
6333 /* Process change. */
6334 bgp_process(bgp, dest, afi, safi);
6335
6336 if (SAFI_UNICAST == safi
6337 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6338 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6339 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6340 }
6341
6342 /* Unintern original. */
6343 aspath_unintern(&attr.aspath);
6344 }
6345
6346 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6347 safi_t safi)
6348 {
6349 struct bgp_dest *dest;
6350 struct bgp_path_info *pi;
6351
6352 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6353
6354 /* Check selected route and self inserted route. */
6355 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6356 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6357 && pi->sub_type == BGP_ROUTE_STATIC)
6358 break;
6359
6360 /* Withdraw static BGP route from routing table. */
6361 if (pi) {
6362 if (SAFI_UNICAST == safi
6363 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6364 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6365 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6366 }
6367 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6368 bgp_unlink_nexthop(pi);
6369 bgp_path_info_delete(dest, pi);
6370 bgp_process(bgp, dest, afi, safi);
6371 }
6372
6373 /* Unlock bgp_node_lookup. */
6374 bgp_dest_unlock_node(dest);
6375 }
6376
6377 /*
6378 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6379 */
6380 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6381 afi_t afi, safi_t safi,
6382 struct prefix_rd *prd)
6383 {
6384 struct bgp_dest *dest;
6385 struct bgp_path_info *pi;
6386
6387 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6388
6389 /* Check selected route and self inserted route. */
6390 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6391 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6392 && pi->sub_type == BGP_ROUTE_STATIC)
6393 break;
6394
6395 /* Withdraw static BGP route from routing table. */
6396 if (pi) {
6397 #ifdef ENABLE_BGP_VNC
6398 rfapiProcessWithdraw(
6399 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6400 1); /* Kill, since it is an administrative change */
6401 #endif
6402 if (SAFI_MPLS_VPN == safi
6403 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6404 vpn_leak_to_vrf_withdraw(bgp, pi);
6405 }
6406 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6407 bgp_path_info_delete(dest, pi);
6408 bgp_process(bgp, dest, afi, safi);
6409 }
6410
6411 /* Unlock bgp_node_lookup. */
6412 bgp_dest_unlock_node(dest);
6413 }
6414
6415 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6416 struct bgp_static *bgp_static, afi_t afi,
6417 safi_t safi)
6418 {
6419 struct bgp_dest *dest;
6420 struct bgp_path_info *new;
6421 struct attr *attr_new;
6422 struct attr attr = {0};
6423 struct bgp_path_info *pi;
6424 #ifdef ENABLE_BGP_VNC
6425 mpls_label_t label = 0;
6426 #endif
6427 uint32_t num_labels = 0;
6428
6429 assert(bgp_static);
6430
6431 if (bgp_static->label != MPLS_INVALID_LABEL)
6432 num_labels = 1;
6433 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6434 &bgp_static->prd);
6435
6436 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6437
6438 attr.nexthop = bgp_static->igpnexthop;
6439 attr.med = bgp_static->igpmetric;
6440 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6441
6442 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6443 || (safi == SAFI_ENCAP)) {
6444 if (afi == AFI_IP) {
6445 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6446 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6447 }
6448 }
6449 if (afi == AFI_L2VPN) {
6450 if (bgp_static->gatewayIp.family == AF_INET) {
6451 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6452 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6453 &bgp_static->gatewayIp.u.prefix4,
6454 IPV4_MAX_BYTELEN);
6455 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6456 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6457 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6458 &bgp_static->gatewayIp.u.prefix6,
6459 IPV6_MAX_BYTELEN);
6460 }
6461 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6462 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6463 struct bgp_encap_type_vxlan bet;
6464 memset(&bet, 0, sizeof(bet));
6465 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6466 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6467 }
6468 if (bgp_static->router_mac) {
6469 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6470 }
6471 }
6472 /* Apply route-map. */
6473 if (bgp_static->rmap.name) {
6474 struct attr attr_tmp = attr;
6475 struct bgp_path_info rmap_path;
6476 route_map_result_t ret;
6477
6478 rmap_path.peer = bgp->peer_self;
6479 rmap_path.attr = &attr_tmp;
6480
6481 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6482
6483 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6484
6485 bgp->peer_self->rmap_type = 0;
6486
6487 if (ret == RMAP_DENYMATCH) {
6488 /* Free uninterned attribute. */
6489 bgp_attr_flush(&attr_tmp);
6490
6491 /* Unintern original. */
6492 aspath_unintern(&attr.aspath);
6493 bgp_static_withdraw_safi(bgp, p, afi, safi,
6494 &bgp_static->prd);
6495 bgp_dest_unlock_node(dest);
6496 return;
6497 }
6498
6499 attr_new = bgp_attr_intern(&attr_tmp);
6500 } else {
6501 attr_new = bgp_attr_intern(&attr);
6502 }
6503
6504 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6505 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6506 && pi->sub_type == BGP_ROUTE_STATIC)
6507 break;
6508
6509 if (pi) {
6510 if (attrhash_cmp(pi->attr, attr_new)
6511 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6512 bgp_dest_unlock_node(dest);
6513 bgp_attr_unintern(&attr_new);
6514 aspath_unintern(&attr.aspath);
6515 return;
6516 } else {
6517 /* The attribute is changed. */
6518 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6519
6520 /* Rewrite BGP route information. */
6521 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6522 bgp_path_info_restore(dest, pi);
6523 else
6524 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6525 bgp_attr_unintern(&pi->attr);
6526 pi->attr = attr_new;
6527 pi->uptime = monotime(NULL);
6528 #ifdef ENABLE_BGP_VNC
6529 if (pi->extra)
6530 label = decode_label(&pi->extra->label[0]);
6531 #endif
6532
6533 /* Process change. */
6534 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6535 bgp_process(bgp, dest, afi, safi);
6536
6537 if (SAFI_MPLS_VPN == safi
6538 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6539 vpn_leak_to_vrf_update(bgp, pi,
6540 &bgp_static->prd);
6541 }
6542 #ifdef ENABLE_BGP_VNC
6543 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6544 pi->attr, afi, safi, pi->type,
6545 pi->sub_type, &label);
6546 #endif
6547 bgp_dest_unlock_node(dest);
6548 aspath_unintern(&attr.aspath);
6549 return;
6550 }
6551 }
6552
6553
6554 /* Make new BGP info. */
6555 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6556 attr_new, dest);
6557 SET_FLAG(new->flags, BGP_PATH_VALID);
6558 bgp_path_info_extra_get(new);
6559 if (num_labels) {
6560 new->extra->label[0] = bgp_static->label;
6561 new->extra->num_labels = num_labels;
6562 }
6563 #ifdef ENABLE_BGP_VNC
6564 label = decode_label(&bgp_static->label);
6565 #endif
6566
6567 /* Aggregate address increment. */
6568 bgp_aggregate_increment(bgp, p, new, afi, safi);
6569
6570 /* Register new BGP information. */
6571 bgp_path_info_add(dest, new);
6572 /* route_node_get lock */
6573 bgp_dest_unlock_node(dest);
6574
6575 /* Process change. */
6576 bgp_process(bgp, dest, afi, safi);
6577
6578 if (SAFI_MPLS_VPN == safi
6579 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6580 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6581 }
6582 #ifdef ENABLE_BGP_VNC
6583 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6584 safi, new->type, new->sub_type, &label);
6585 #endif
6586
6587 /* Unintern original. */
6588 aspath_unintern(&attr.aspath);
6589 }
6590
6591 /* Configure static BGP network. When user don't run zebra, static
6592 route should be installed as valid. */
6593 static int bgp_static_set(struct vty *vty, const char *negate,
6594 const char *ip_str, afi_t afi, safi_t safi,
6595 const char *rmap, int backdoor, uint32_t label_index)
6596 {
6597 VTY_DECLVAR_CONTEXT(bgp, bgp);
6598 int ret;
6599 struct prefix p;
6600 struct bgp_static *bgp_static;
6601 struct bgp_dest *dest;
6602 uint8_t need_update = 0;
6603
6604 /* Convert IP prefix string to struct prefix. */
6605 ret = str2prefix(ip_str, &p);
6606 if (!ret) {
6607 vty_out(vty, "%% Malformed prefix\n");
6608 return CMD_WARNING_CONFIG_FAILED;
6609 }
6610 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6611 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6612 return CMD_WARNING_CONFIG_FAILED;
6613 }
6614
6615 apply_mask(&p);
6616
6617 if (negate) {
6618
6619 /* Set BGP static route configuration. */
6620 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6621
6622 if (!dest) {
6623 vty_out(vty, "%% Can't find static route specified\n");
6624 return CMD_WARNING_CONFIG_FAILED;
6625 }
6626
6627 bgp_static = bgp_dest_get_bgp_static_info(dest);
6628
6629 if ((label_index != BGP_INVALID_LABEL_INDEX)
6630 && (label_index != bgp_static->label_index)) {
6631 vty_out(vty,
6632 "%% label-index doesn't match static route\n");
6633 bgp_dest_unlock_node(dest);
6634 return CMD_WARNING_CONFIG_FAILED;
6635 }
6636
6637 if ((rmap && bgp_static->rmap.name)
6638 && strcmp(rmap, bgp_static->rmap.name)) {
6639 vty_out(vty,
6640 "%% route-map name doesn't match static route\n");
6641 bgp_dest_unlock_node(dest);
6642 return CMD_WARNING_CONFIG_FAILED;
6643 }
6644
6645 /* Update BGP RIB. */
6646 if (!bgp_static->backdoor)
6647 bgp_static_withdraw(bgp, &p, afi, safi);
6648
6649 /* Clear configuration. */
6650 bgp_static_free(bgp_static);
6651 bgp_dest_set_bgp_static_info(dest, NULL);
6652 bgp_dest_unlock_node(dest);
6653 bgp_dest_unlock_node(dest);
6654 } else {
6655
6656 /* Set BGP static route configuration. */
6657 dest = bgp_node_get(bgp->route[afi][safi], &p);
6658 bgp_static = bgp_dest_get_bgp_static_info(dest);
6659 if (bgp_static) {
6660 /* Configuration change. */
6661 /* Label index cannot be changed. */
6662 if (bgp_static->label_index != label_index) {
6663 vty_out(vty, "%% cannot change label-index\n");
6664 bgp_dest_unlock_node(dest);
6665 return CMD_WARNING_CONFIG_FAILED;
6666 }
6667
6668 /* Check previous routes are installed into BGP. */
6669 if (bgp_static->valid
6670 && bgp_static->backdoor != backdoor)
6671 need_update = 1;
6672
6673 bgp_static->backdoor = backdoor;
6674
6675 if (rmap) {
6676 XFREE(MTYPE_ROUTE_MAP_NAME,
6677 bgp_static->rmap.name);
6678 route_map_counter_decrement(
6679 bgp_static->rmap.map);
6680 bgp_static->rmap.name =
6681 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6682 bgp_static->rmap.map =
6683 route_map_lookup_by_name(rmap);
6684 route_map_counter_increment(
6685 bgp_static->rmap.map);
6686 } else {
6687 XFREE(MTYPE_ROUTE_MAP_NAME,
6688 bgp_static->rmap.name);
6689 route_map_counter_decrement(
6690 bgp_static->rmap.map);
6691 bgp_static->rmap.map = NULL;
6692 bgp_static->valid = 0;
6693 }
6694 bgp_dest_unlock_node(dest);
6695 } else {
6696 /* New configuration. */
6697 bgp_static = bgp_static_new();
6698 bgp_static->backdoor = backdoor;
6699 bgp_static->valid = 0;
6700 bgp_static->igpmetric = 0;
6701 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6702 bgp_static->label_index = label_index;
6703
6704 if (rmap) {
6705 XFREE(MTYPE_ROUTE_MAP_NAME,
6706 bgp_static->rmap.name);
6707 route_map_counter_decrement(
6708 bgp_static->rmap.map);
6709 bgp_static->rmap.name =
6710 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6711 bgp_static->rmap.map =
6712 route_map_lookup_by_name(rmap);
6713 route_map_counter_increment(
6714 bgp_static->rmap.map);
6715 }
6716 bgp_dest_set_bgp_static_info(dest, bgp_static);
6717 }
6718
6719 bgp_static->valid = 1;
6720 if (need_update)
6721 bgp_static_withdraw(bgp, &p, afi, safi);
6722
6723 if (!bgp_static->backdoor)
6724 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6725 }
6726
6727 return CMD_SUCCESS;
6728 }
6729
6730 void bgp_static_add(struct bgp *bgp)
6731 {
6732 afi_t afi;
6733 safi_t safi;
6734 struct bgp_dest *dest;
6735 struct bgp_dest *rm;
6736 struct bgp_table *table;
6737 struct bgp_static *bgp_static;
6738
6739 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6740 FOREACH_AFI_SAFI (afi, safi)
6741 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6742 dest = bgp_route_next(dest)) {
6743 if (!bgp_dest_has_bgp_path_info_data(dest))
6744 continue;
6745
6746 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6747 || (safi == SAFI_EVPN)) {
6748 table = bgp_dest_get_bgp_table_info(dest);
6749
6750 for (rm = bgp_table_top(table); rm;
6751 rm = bgp_route_next(rm)) {
6752 bgp_static =
6753 bgp_dest_get_bgp_static_info(
6754 rm);
6755 bgp_static_update_safi(
6756 bgp, bgp_dest_get_prefix(rm),
6757 bgp_static, afi, safi);
6758 }
6759 } else {
6760 bgp_static_update(
6761 bgp, bgp_dest_get_prefix(dest),
6762 bgp_dest_get_bgp_static_info(dest), afi,
6763 safi);
6764 }
6765 }
6766 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6767 }
6768
6769 /* Called from bgp_delete(). Delete all static routes from the BGP
6770 instance. */
6771 void bgp_static_delete(struct bgp *bgp)
6772 {
6773 afi_t afi;
6774 safi_t safi;
6775 struct bgp_dest *dest;
6776 struct bgp_dest *rm;
6777 struct bgp_table *table;
6778 struct bgp_static *bgp_static;
6779
6780 FOREACH_AFI_SAFI (afi, safi)
6781 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6782 dest = bgp_route_next(dest)) {
6783 if (!bgp_dest_has_bgp_path_info_data(dest))
6784 continue;
6785
6786 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6787 || (safi == SAFI_EVPN)) {
6788 table = bgp_dest_get_bgp_table_info(dest);
6789
6790 for (rm = bgp_table_top(table); rm;
6791 rm = bgp_route_next(rm)) {
6792 bgp_static =
6793 bgp_dest_get_bgp_static_info(
6794 rm);
6795 if (!bgp_static)
6796 continue;
6797
6798 bgp_static_withdraw_safi(
6799 bgp, bgp_dest_get_prefix(rm),
6800 AFI_IP, safi,
6801 (struct prefix_rd *)
6802 bgp_dest_get_prefix(
6803 dest));
6804 bgp_static_free(bgp_static);
6805 bgp_dest_set_bgp_static_info(rm,
6806 NULL);
6807 bgp_dest_unlock_node(rm);
6808 }
6809 } else {
6810 bgp_static = bgp_dest_get_bgp_static_info(dest);
6811 bgp_static_withdraw(bgp,
6812 bgp_dest_get_prefix(dest),
6813 afi, safi);
6814 bgp_static_free(bgp_static);
6815 bgp_dest_set_bgp_static_info(dest, NULL);
6816 bgp_dest_unlock_node(dest);
6817 }
6818 }
6819 }
6820
6821 void bgp_static_redo_import_check(struct bgp *bgp)
6822 {
6823 afi_t afi;
6824 safi_t safi;
6825 struct bgp_dest *dest;
6826 struct bgp_dest *rm;
6827 struct bgp_table *table;
6828 struct bgp_static *bgp_static;
6829
6830 /* Use this flag to force reprocessing of the route */
6831 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6832 FOREACH_AFI_SAFI (afi, safi) {
6833 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6834 dest = bgp_route_next(dest)) {
6835 if (!bgp_dest_has_bgp_path_info_data(dest))
6836 continue;
6837
6838 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6839 || (safi == SAFI_EVPN)) {
6840 table = bgp_dest_get_bgp_table_info(dest);
6841
6842 for (rm = bgp_table_top(table); rm;
6843 rm = bgp_route_next(rm)) {
6844 bgp_static =
6845 bgp_dest_get_bgp_static_info(
6846 rm);
6847 bgp_static_update_safi(
6848 bgp, bgp_dest_get_prefix(rm),
6849 bgp_static, afi, safi);
6850 }
6851 } else {
6852 bgp_static = bgp_dest_get_bgp_static_info(dest);
6853 bgp_static_update(bgp,
6854 bgp_dest_get_prefix(dest),
6855 bgp_static, afi, safi);
6856 }
6857 }
6858 }
6859 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6860 }
6861
6862 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6863 safi_t safi)
6864 {
6865 struct bgp_table *table;
6866 struct bgp_dest *dest;
6867 struct bgp_path_info *pi;
6868
6869 /* Do not install the aggregate route if BGP is in the
6870 * process of termination.
6871 */
6872 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6873 || (bgp->peer_self == NULL))
6874 return;
6875
6876 table = bgp->rib[afi][safi];
6877 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6878 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6879 if (pi->peer == bgp->peer_self
6880 && ((pi->type == ZEBRA_ROUTE_BGP
6881 && pi->sub_type == BGP_ROUTE_STATIC)
6882 || (pi->type != ZEBRA_ROUTE_BGP
6883 && pi->sub_type
6884 == BGP_ROUTE_REDISTRIBUTE))) {
6885 bgp_aggregate_decrement(
6886 bgp, bgp_dest_get_prefix(dest), pi, afi,
6887 safi);
6888 bgp_unlink_nexthop(pi);
6889 bgp_path_info_delete(dest, pi);
6890 bgp_process(bgp, dest, afi, safi);
6891 }
6892 }
6893 }
6894 }
6895
6896 /*
6897 * Purge all networks and redistributed routes from routing table.
6898 * Invoked upon the instance going down.
6899 */
6900 void bgp_purge_static_redist_routes(struct bgp *bgp)
6901 {
6902 afi_t afi;
6903 safi_t safi;
6904
6905 FOREACH_AFI_SAFI (afi, safi)
6906 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6907 }
6908
6909 /*
6910 * gpz 110624
6911 * Currently this is used to set static routes for VPN and ENCAP.
6912 * I think it can probably be factored with bgp_static_set.
6913 */
6914 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6915 const char *ip_str, const char *rd_str,
6916 const char *label_str, const char *rmap_str,
6917 int evpn_type, const char *esi, const char *gwip,
6918 const char *ethtag, const char *routermac)
6919 {
6920 VTY_DECLVAR_CONTEXT(bgp, bgp);
6921 int ret;
6922 struct prefix p;
6923 struct prefix_rd prd;
6924 struct bgp_dest *pdest;
6925 struct bgp_dest *dest;
6926 struct bgp_table *table;
6927 struct bgp_static *bgp_static;
6928 mpls_label_t label = MPLS_INVALID_LABEL;
6929 struct prefix gw_ip;
6930
6931 /* validate ip prefix */
6932 ret = str2prefix(ip_str, &p);
6933 if (!ret) {
6934 vty_out(vty, "%% Malformed prefix\n");
6935 return CMD_WARNING_CONFIG_FAILED;
6936 }
6937 apply_mask(&p);
6938 if ((afi == AFI_L2VPN)
6939 && (bgp_build_evpn_prefix(evpn_type,
6940 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6941 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6942 return CMD_WARNING_CONFIG_FAILED;
6943 }
6944
6945 ret = str2prefix_rd(rd_str, &prd);
6946 if (!ret) {
6947 vty_out(vty, "%% Malformed rd\n");
6948 return CMD_WARNING_CONFIG_FAILED;
6949 }
6950
6951 if (label_str) {
6952 unsigned long label_val;
6953 label_val = strtoul(label_str, NULL, 10);
6954 encode_label(label_val, &label);
6955 }
6956
6957 if (safi == SAFI_EVPN) {
6958 if (esi && str2esi(esi, NULL) == 0) {
6959 vty_out(vty, "%% Malformed ESI\n");
6960 return CMD_WARNING_CONFIG_FAILED;
6961 }
6962 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6963 vty_out(vty, "%% Malformed Router MAC\n");
6964 return CMD_WARNING_CONFIG_FAILED;
6965 }
6966 if (gwip) {
6967 memset(&gw_ip, 0, sizeof(gw_ip));
6968 ret = str2prefix(gwip, &gw_ip);
6969 if (!ret) {
6970 vty_out(vty, "%% Malformed GatewayIp\n");
6971 return CMD_WARNING_CONFIG_FAILED;
6972 }
6973 if ((gw_ip.family == AF_INET
6974 && is_evpn_prefix_ipaddr_v6(
6975 (struct prefix_evpn *)&p))
6976 || (gw_ip.family == AF_INET6
6977 && is_evpn_prefix_ipaddr_v4(
6978 (struct prefix_evpn *)&p))) {
6979 vty_out(vty,
6980 "%% GatewayIp family differs with IP prefix\n");
6981 return CMD_WARNING_CONFIG_FAILED;
6982 }
6983 }
6984 }
6985 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6986 if (!bgp_dest_has_bgp_path_info_data(pdest))
6987 bgp_dest_set_bgp_table_info(pdest,
6988 bgp_table_init(bgp, afi, safi));
6989 table = bgp_dest_get_bgp_table_info(pdest);
6990
6991 dest = bgp_node_get(table, &p);
6992
6993 if (bgp_dest_has_bgp_path_info_data(dest)) {
6994 vty_out(vty, "%% Same network configuration exists\n");
6995 bgp_dest_unlock_node(dest);
6996 } else {
6997 /* New configuration. */
6998 bgp_static = bgp_static_new();
6999 bgp_static->backdoor = 0;
7000 bgp_static->valid = 0;
7001 bgp_static->igpmetric = 0;
7002 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7003 bgp_static->label = label;
7004 bgp_static->prd = prd;
7005
7006 if (rmap_str) {
7007 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7008 route_map_counter_decrement(bgp_static->rmap.map);
7009 bgp_static->rmap.name =
7010 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7011 bgp_static->rmap.map =
7012 route_map_lookup_by_name(rmap_str);
7013 route_map_counter_increment(bgp_static->rmap.map);
7014 }
7015
7016 if (safi == SAFI_EVPN) {
7017 if (esi) {
7018 bgp_static->eth_s_id =
7019 XCALLOC(MTYPE_ATTR,
7020 sizeof(esi_t));
7021 str2esi(esi, bgp_static->eth_s_id);
7022 }
7023 if (routermac) {
7024 bgp_static->router_mac =
7025 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7026 (void)prefix_str2mac(routermac,
7027 bgp_static->router_mac);
7028 }
7029 if (gwip)
7030 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7031 }
7032 bgp_dest_set_bgp_static_info(dest, bgp_static);
7033
7034 bgp_static->valid = 1;
7035 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7036 }
7037
7038 return CMD_SUCCESS;
7039 }
7040
7041 /* Configure static BGP network. */
7042 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7043 const char *ip_str, const char *rd_str,
7044 const char *label_str, int evpn_type, const char *esi,
7045 const char *gwip, const char *ethtag)
7046 {
7047 VTY_DECLVAR_CONTEXT(bgp, bgp);
7048 int ret;
7049 struct prefix p;
7050 struct prefix_rd prd;
7051 struct bgp_dest *pdest;
7052 struct bgp_dest *dest;
7053 struct bgp_table *table;
7054 struct bgp_static *bgp_static;
7055 mpls_label_t label = MPLS_INVALID_LABEL;
7056
7057 /* Convert IP prefix string to struct prefix. */
7058 ret = str2prefix(ip_str, &p);
7059 if (!ret) {
7060 vty_out(vty, "%% Malformed prefix\n");
7061 return CMD_WARNING_CONFIG_FAILED;
7062 }
7063 apply_mask(&p);
7064 if ((afi == AFI_L2VPN)
7065 && (bgp_build_evpn_prefix(evpn_type,
7066 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7067 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7068 return CMD_WARNING_CONFIG_FAILED;
7069 }
7070 ret = str2prefix_rd(rd_str, &prd);
7071 if (!ret) {
7072 vty_out(vty, "%% Malformed rd\n");
7073 return CMD_WARNING_CONFIG_FAILED;
7074 }
7075
7076 if (label_str) {
7077 unsigned long label_val;
7078 label_val = strtoul(label_str, NULL, 10);
7079 encode_label(label_val, &label);
7080 }
7081
7082 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7083 if (!bgp_dest_has_bgp_path_info_data(pdest))
7084 bgp_dest_set_bgp_table_info(pdest,
7085 bgp_table_init(bgp, afi, safi));
7086 else
7087 bgp_dest_unlock_node(pdest);
7088 table = bgp_dest_get_bgp_table_info(pdest);
7089
7090 dest = bgp_node_lookup(table, &p);
7091
7092 if (dest) {
7093 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7094
7095 bgp_static = bgp_dest_get_bgp_static_info(dest);
7096 bgp_static_free(bgp_static);
7097 bgp_dest_set_bgp_static_info(dest, NULL);
7098 bgp_dest_unlock_node(dest);
7099 bgp_dest_unlock_node(dest);
7100 } else
7101 vty_out(vty, "%% Can't find the route\n");
7102
7103 return CMD_SUCCESS;
7104 }
7105
7106 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7107 const char *rmap_name)
7108 {
7109 VTY_DECLVAR_CONTEXT(bgp, bgp);
7110 struct bgp_rmap *rmap;
7111
7112 rmap = &bgp->table_map[afi][safi];
7113 if (rmap_name) {
7114 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7115 route_map_counter_decrement(rmap->map);
7116 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7117 rmap->map = route_map_lookup_by_name(rmap_name);
7118 route_map_counter_increment(rmap->map);
7119 } else {
7120 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7121 route_map_counter_decrement(rmap->map);
7122 rmap->map = NULL;
7123 }
7124
7125 if (bgp_fibupd_safi(safi))
7126 bgp_zebra_announce_table(bgp, afi, safi);
7127
7128 return CMD_SUCCESS;
7129 }
7130
7131 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7132 const char *rmap_name)
7133 {
7134 VTY_DECLVAR_CONTEXT(bgp, bgp);
7135 struct bgp_rmap *rmap;
7136
7137 rmap = &bgp->table_map[afi][safi];
7138 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7139 route_map_counter_decrement(rmap->map);
7140 rmap->map = NULL;
7141
7142 if (bgp_fibupd_safi(safi))
7143 bgp_zebra_announce_table(bgp, afi, safi);
7144
7145 return CMD_SUCCESS;
7146 }
7147
7148 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7149 safi_t safi)
7150 {
7151 if (bgp->table_map[afi][safi].name) {
7152 vty_out(vty, " table-map %s\n",
7153 bgp->table_map[afi][safi].name);
7154 }
7155 }
7156
7157 DEFUN (bgp_table_map,
7158 bgp_table_map_cmd,
7159 "table-map WORD",
7160 "BGP table to RIB route download filter\n"
7161 "Name of the route map\n")
7162 {
7163 int idx_word = 1;
7164 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7165 argv[idx_word]->arg);
7166 }
7167 DEFUN (no_bgp_table_map,
7168 no_bgp_table_map_cmd,
7169 "no table-map WORD",
7170 NO_STR
7171 "BGP table to RIB route download filter\n"
7172 "Name of the route map\n")
7173 {
7174 int idx_word = 2;
7175 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7176 argv[idx_word]->arg);
7177 }
7178
7179 DEFPY(bgp_network,
7180 bgp_network_cmd,
7181 "[no] network \
7182 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7183 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7184 backdoor$backdoor}]",
7185 NO_STR
7186 "Specify a network to announce via BGP\n"
7187 "IPv4 prefix\n"
7188 "Network number\n"
7189 "Network mask\n"
7190 "Network mask\n"
7191 "Route-map to modify the attributes\n"
7192 "Name of the route map\n"
7193 "Label index to associate with the prefix\n"
7194 "Label index value\n"
7195 "Specify a BGP backdoor route\n")
7196 {
7197 char addr_prefix_str[BUFSIZ];
7198
7199 if (address_str) {
7200 int ret;
7201
7202 ret = netmask_str2prefix_str(address_str, netmask_str,
7203 addr_prefix_str,
7204 sizeof(addr_prefix_str));
7205 if (!ret) {
7206 vty_out(vty, "%% Inconsistent address and mask\n");
7207 return CMD_WARNING_CONFIG_FAILED;
7208 }
7209 }
7210
7211 return bgp_static_set(
7212 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7213 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7214 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7215 }
7216
7217 DEFPY(ipv6_bgp_network,
7218 ipv6_bgp_network_cmd,
7219 "[no] network X:X::X:X/M$prefix \
7220 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7221 NO_STR
7222 "Specify a network to announce via BGP\n"
7223 "IPv6 prefix\n"
7224 "Route-map to modify the attributes\n"
7225 "Name of the route map\n"
7226 "Label index to associate with the prefix\n"
7227 "Label index value\n")
7228 {
7229 return bgp_static_set(
7230 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7231 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7232 }
7233
7234 static struct bgp_aggregate *bgp_aggregate_new(void)
7235 {
7236 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7237 }
7238
7239 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7240 {
7241 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7242 route_map_counter_decrement(aggregate->suppress_map);
7243 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7244 route_map_counter_decrement(aggregate->rmap.map);
7245 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7246 }
7247
7248 /**
7249 * Helper function to avoid repeated code: prepare variables for a
7250 * `route_map_apply` call.
7251 *
7252 * \returns `true` on route map match, otherwise `false`.
7253 */
7254 static bool aggr_suppress_map_test(struct bgp *bgp,
7255 struct bgp_aggregate *aggregate,
7256 struct bgp_path_info *pi)
7257 {
7258 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7259 route_map_result_t rmr = RMAP_DENYMATCH;
7260 struct bgp_path_info rmap_path = {};
7261 struct attr attr = {};
7262
7263 /* No route map entries created, just don't match. */
7264 if (aggregate->suppress_map == NULL)
7265 return false;
7266
7267 /* Call route map matching and return result. */
7268 attr.aspath = aspath_empty();
7269 rmap_path.peer = bgp->peer_self;
7270 rmap_path.attr = &attr;
7271
7272 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7273 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7274 bgp->peer_self->rmap_type = 0;
7275
7276 bgp_attr_flush(&attr);
7277 aspath_unintern(&attr.aspath);
7278
7279 return rmr == RMAP_PERMITMATCH;
7280 }
7281
7282 /** Test whether the aggregation has suppressed this path or not. */
7283 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7284 struct bgp_path_info *pi)
7285 {
7286 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7287 return false;
7288
7289 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7290 }
7291
7292 /**
7293 * Suppress this path and keep the reference.
7294 *
7295 * \returns `true` if needs processing otherwise `false`.
7296 */
7297 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7298 struct bgp_path_info *pi)
7299 {
7300 struct bgp_path_info_extra *pie;
7301
7302 /* Path is already suppressed by this aggregation. */
7303 if (aggr_suppress_exists(aggregate, pi))
7304 return false;
7305
7306 pie = bgp_path_info_extra_get(pi);
7307
7308 /* This is the first suppression, allocate memory and list it. */
7309 if (pie->aggr_suppressors == NULL)
7310 pie->aggr_suppressors = list_new();
7311
7312 listnode_add(pie->aggr_suppressors, aggregate);
7313
7314 /* Only mark for processing if suppressed. */
7315 if (listcount(pie->aggr_suppressors) == 1) {
7316 if (BGP_DEBUG(update, UPDATE_OUT))
7317 zlog_debug("aggregate-address suppressing: %pFX",
7318 bgp_dest_get_prefix(pi->net));
7319
7320 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7321 return true;
7322 }
7323
7324 return false;
7325 }
7326
7327 /**
7328 * Unsuppress this path and remove the reference.
7329 *
7330 * \returns `true` if needs processing otherwise `false`.
7331 */
7332 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7333 struct bgp_path_info *pi)
7334 {
7335 /* Path wasn't suppressed. */
7336 if (!aggr_suppress_exists(aggregate, pi))
7337 return false;
7338
7339 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7340
7341 /* Unsuppress and free extra memory if last item. */
7342 if (listcount(pi->extra->aggr_suppressors) == 0) {
7343 if (BGP_DEBUG(update, UPDATE_OUT))
7344 zlog_debug("aggregate-address unsuppressing: %pFX",
7345 bgp_dest_get_prefix(pi->net));
7346
7347 list_delete(&pi->extra->aggr_suppressors);
7348 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7349 return true;
7350 }
7351
7352 return false;
7353 }
7354
7355 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7356 struct aspath *aspath,
7357 struct community *comm,
7358 struct ecommunity *ecomm,
7359 struct lcommunity *lcomm)
7360 {
7361 static struct aspath *ae = NULL;
7362
7363 if (!ae)
7364 ae = aspath_empty();
7365
7366 if (!pi)
7367 return false;
7368
7369 if (origin != pi->attr->origin)
7370 return false;
7371
7372 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7373 return false;
7374
7375 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7376 return false;
7377
7378 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7379 return false;
7380
7381 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7382 return false;
7383
7384 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7385 return false;
7386
7387 return true;
7388 }
7389
7390 static void bgp_aggregate_install(
7391 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7392 uint8_t origin, struct aspath *aspath, struct community *community,
7393 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7394 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7395 {
7396 struct bgp_dest *dest;
7397 struct bgp_table *table;
7398 struct bgp_path_info *pi, *orig, *new;
7399 struct attr *attr;
7400
7401 table = bgp->rib[afi][safi];
7402
7403 dest = bgp_node_get(table, p);
7404
7405 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7406 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7407 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7408 break;
7409
7410 /*
7411 * If we have paths with different MEDs, then don't install
7412 * (or uninstall) the aggregate route.
7413 */
7414 if (aggregate->match_med && aggregate->med_mismatched)
7415 goto uninstall_aggregate_route;
7416
7417 if (aggregate->count > 0) {
7418 /*
7419 * If the aggregate information has not changed
7420 * no need to re-install it again.
7421 */
7422 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7423 ecommunity, lcommunity)) {
7424 bgp_dest_unlock_node(dest);
7425
7426 if (aspath)
7427 aspath_free(aspath);
7428 if (community)
7429 community_free(&community);
7430 if (ecommunity)
7431 ecommunity_free(&ecommunity);
7432 if (lcommunity)
7433 lcommunity_free(&lcommunity);
7434
7435 return;
7436 }
7437
7438 /*
7439 * Mark the old as unusable
7440 */
7441 if (pi)
7442 bgp_path_info_delete(dest, pi);
7443
7444 attr = bgp_attr_aggregate_intern(
7445 bgp, origin, aspath, community, ecommunity, lcommunity,
7446 aggregate, atomic_aggregate, p);
7447
7448 if (!attr) {
7449 bgp_dest_unlock_node(dest);
7450 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7451 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7452 zlog_debug("%s: %pFX null attribute", __func__,
7453 p);
7454 return;
7455 }
7456
7457 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7458 bgp->peer_self, attr, dest);
7459
7460 SET_FLAG(new->flags, BGP_PATH_VALID);
7461
7462 bgp_path_info_add(dest, new);
7463 bgp_process(bgp, dest, afi, safi);
7464 } else {
7465 uninstall_aggregate_route:
7466 for (pi = orig; pi; pi = pi->next)
7467 if (pi->peer == bgp->peer_self
7468 && pi->type == ZEBRA_ROUTE_BGP
7469 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7470 break;
7471
7472 /* Withdraw static BGP route from routing table. */
7473 if (pi) {
7474 bgp_path_info_delete(dest, pi);
7475 bgp_process(bgp, dest, afi, safi);
7476 }
7477 }
7478
7479 bgp_dest_unlock_node(dest);
7480 }
7481
7482 /**
7483 * Check if the current path has different MED than other known paths.
7484 *
7485 * \returns `true` if the MED matched the others else `false`.
7486 */
7487 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7488 struct bgp *bgp, struct bgp_path_info *pi)
7489 {
7490 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7491
7492 /* This is the first route being analyzed. */
7493 if (!aggregate->med_initialized) {
7494 aggregate->med_initialized = true;
7495 aggregate->med_mismatched = false;
7496 aggregate->med_matched_value = cur_med;
7497 } else {
7498 /* Check if routes with different MED showed up. */
7499 if (cur_med != aggregate->med_matched_value)
7500 aggregate->med_mismatched = true;
7501 }
7502
7503 return !aggregate->med_mismatched;
7504 }
7505
7506 /**
7507 * Initializes and tests all routes in the aggregate address path for MED
7508 * values.
7509 *
7510 * \returns `true` if all MEDs are the same otherwise `false`.
7511 */
7512 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7513 struct bgp *bgp, const struct prefix *p,
7514 afi_t afi, safi_t safi)
7515 {
7516 struct bgp_table *table = bgp->rib[afi][safi];
7517 const struct prefix *dest_p;
7518 struct bgp_dest *dest, *top;
7519 struct bgp_path_info *pi;
7520 bool med_matched = true;
7521
7522 aggregate->med_initialized = false;
7523
7524 top = bgp_node_get(table, p);
7525 for (dest = bgp_node_get(table, p); dest;
7526 dest = bgp_route_next_until(dest, top)) {
7527 dest_p = bgp_dest_get_prefix(dest);
7528 if (dest_p->prefixlen <= p->prefixlen)
7529 continue;
7530
7531 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7532 if (BGP_PATH_HOLDDOWN(pi))
7533 continue;
7534 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7535 continue;
7536 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7537 med_matched = false;
7538 break;
7539 }
7540 }
7541 if (!med_matched)
7542 break;
7543 }
7544 bgp_dest_unlock_node(top);
7545
7546 return med_matched;
7547 }
7548
7549 /**
7550 * Toggles the route suppression status for this aggregate address
7551 * configuration.
7552 */
7553 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7554 struct bgp *bgp, const struct prefix *p,
7555 afi_t afi, safi_t safi, bool suppress)
7556 {
7557 struct bgp_table *table = bgp->rib[afi][safi];
7558 const struct prefix *dest_p;
7559 struct bgp_dest *dest, *top;
7560 struct bgp_path_info *pi;
7561 bool toggle_suppression;
7562
7563 /* We've found a different MED we must revert any suppressed routes. */
7564 top = bgp_node_get(table, p);
7565 for (dest = bgp_node_get(table, p); dest;
7566 dest = bgp_route_next_until(dest, top)) {
7567 dest_p = bgp_dest_get_prefix(dest);
7568 if (dest_p->prefixlen <= p->prefixlen)
7569 continue;
7570
7571 toggle_suppression = false;
7572 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7573 if (BGP_PATH_HOLDDOWN(pi))
7574 continue;
7575 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7576 continue;
7577
7578 /* We are toggling suppression back. */
7579 if (suppress) {
7580 /* Suppress route if not suppressed already. */
7581 if (aggr_suppress_path(aggregate, pi))
7582 toggle_suppression = true;
7583 continue;
7584 }
7585
7586 /* Install route if there is no more suppression. */
7587 if (aggr_unsuppress_path(aggregate, pi))
7588 toggle_suppression = true;
7589 }
7590
7591 if (toggle_suppression)
7592 bgp_process(bgp, dest, afi, safi);
7593 }
7594 bgp_dest_unlock_node(top);
7595 }
7596
7597 /**
7598 * Aggregate address MED matching incremental test: this function is called
7599 * when the initial aggregation occurred and we are only testing a single
7600 * new path.
7601 *
7602 * In addition to testing and setting the MED validity it also installs back
7603 * suppressed routes (if summary is configured).
7604 *
7605 * Must not be called in `bgp_aggregate_route`.
7606 */
7607 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7608 struct bgp *bgp, const struct prefix *p,
7609 afi_t afi, safi_t safi,
7610 struct bgp_path_info *pi)
7611 {
7612 /* MED matching disabled. */
7613 if (!aggregate->match_med)
7614 return;
7615
7616 /* Aggregation with different MED, recheck if we have got equal MEDs
7617 * now.
7618 */
7619 if (aggregate->med_mismatched &&
7620 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7621 aggregate->summary_only)
7622 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7623 true);
7624 else
7625 bgp_aggregate_med_match(aggregate, bgp, pi);
7626
7627 /* No mismatches, just quit. */
7628 if (!aggregate->med_mismatched)
7629 return;
7630
7631 /* Route summarization is disabled. */
7632 if (!aggregate->summary_only)
7633 return;
7634
7635 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7636 }
7637
7638 /* Update an aggregate as routes are added/removed from the BGP table */
7639 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7640 safi_t safi, struct bgp_aggregate *aggregate)
7641 {
7642 struct bgp_table *table;
7643 struct bgp_dest *top;
7644 struct bgp_dest *dest;
7645 uint8_t origin;
7646 struct aspath *aspath = NULL;
7647 struct community *community = NULL;
7648 struct ecommunity *ecommunity = NULL;
7649 struct lcommunity *lcommunity = NULL;
7650 struct bgp_path_info *pi;
7651 unsigned long match = 0;
7652 uint8_t atomic_aggregate = 0;
7653
7654 /* If the bgp instance is being deleted or self peer is deleted
7655 * then do not create aggregate route
7656 */
7657 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7658 || (bgp->peer_self == NULL))
7659 return;
7660
7661 /* Initialize and test routes for MED difference. */
7662 if (aggregate->match_med)
7663 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7664
7665 /*
7666 * Reset aggregate count: we might've been called from route map
7667 * update so in that case we must retest all more specific routes.
7668 *
7669 * \see `bgp_route_map_process_update`.
7670 */
7671 aggregate->count = 0;
7672 aggregate->incomplete_origin_count = 0;
7673 aggregate->incomplete_origin_count = 0;
7674 aggregate->egp_origin_count = 0;
7675
7676 /* ORIGIN attribute: If at least one route among routes that are
7677 aggregated has ORIGIN with the value INCOMPLETE, then the
7678 aggregated route must have the ORIGIN attribute with the value
7679 INCOMPLETE. Otherwise, if at least one route among routes that
7680 are aggregated has ORIGIN with the value EGP, then the aggregated
7681 route must have the origin attribute with the value EGP. In all
7682 other case the value of the ORIGIN attribute of the aggregated
7683 route is INTERNAL. */
7684 origin = BGP_ORIGIN_IGP;
7685
7686 table = bgp->rib[afi][safi];
7687
7688 top = bgp_node_get(table, p);
7689 for (dest = bgp_node_get(table, p); dest;
7690 dest = bgp_route_next_until(dest, top)) {
7691 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7692
7693 if (dest_p->prefixlen <= p->prefixlen)
7694 continue;
7695
7696 /* If suppress fib is enabled and route not installed
7697 * in FIB, skip the route
7698 */
7699 if (!bgp_check_advertise(bgp, dest))
7700 continue;
7701
7702 match = 0;
7703
7704 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7705 if (BGP_PATH_HOLDDOWN(pi))
7706 continue;
7707
7708 if (pi->attr->flag
7709 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7710 atomic_aggregate = 1;
7711
7712 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7713 continue;
7714
7715 /*
7716 * summary-only aggregate route suppress
7717 * aggregated route announcements.
7718 *
7719 * MED matching:
7720 * Don't create summaries if MED didn't match
7721 * otherwise neither the specific routes and the
7722 * aggregation will be announced.
7723 */
7724 if (aggregate->summary_only
7725 && AGGREGATE_MED_VALID(aggregate)) {
7726 if (aggr_suppress_path(aggregate, pi))
7727 match++;
7728 }
7729
7730 /*
7731 * Suppress more specific routes that match the route
7732 * map results.
7733 *
7734 * MED matching:
7735 * Don't suppress routes if MED matching is enabled and
7736 * it mismatched otherwise we might end up with no
7737 * routes for this path.
7738 */
7739 if (aggregate->suppress_map_name
7740 && AGGREGATE_MED_VALID(aggregate)
7741 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7742 if (aggr_suppress_path(aggregate, pi))
7743 match++;
7744 }
7745
7746 aggregate->count++;
7747
7748 /*
7749 * If at least one route among routes that are
7750 * aggregated has ORIGIN with the value INCOMPLETE,
7751 * then the aggregated route MUST have the ORIGIN
7752 * attribute with the value INCOMPLETE. Otherwise, if
7753 * at least one route among routes that are aggregated
7754 * has ORIGIN with the value EGP, then the aggregated
7755 * route MUST have the ORIGIN attribute with the value
7756 * EGP.
7757 */
7758 switch (pi->attr->origin) {
7759 case BGP_ORIGIN_INCOMPLETE:
7760 aggregate->incomplete_origin_count++;
7761 break;
7762 case BGP_ORIGIN_EGP:
7763 aggregate->egp_origin_count++;
7764 break;
7765 default:
7766 /*Do nothing.
7767 */
7768 break;
7769 }
7770
7771 if (!aggregate->as_set)
7772 continue;
7773
7774 /*
7775 * as-set aggregate route generate origin, as path,
7776 * and community aggregation.
7777 */
7778 /* Compute aggregate route's as-path.
7779 */
7780 bgp_compute_aggregate_aspath_hash(aggregate,
7781 pi->attr->aspath);
7782
7783 /* Compute aggregate route's community.
7784 */
7785 if (bgp_attr_get_community(pi->attr))
7786 bgp_compute_aggregate_community_hash(
7787 aggregate,
7788 bgp_attr_get_community(pi->attr));
7789
7790 /* Compute aggregate route's extended community.
7791 */
7792 if (bgp_attr_get_ecommunity(pi->attr))
7793 bgp_compute_aggregate_ecommunity_hash(
7794 aggregate,
7795 bgp_attr_get_ecommunity(pi->attr));
7796
7797 /* Compute aggregate route's large community.
7798 */
7799 if (bgp_attr_get_lcommunity(pi->attr))
7800 bgp_compute_aggregate_lcommunity_hash(
7801 aggregate,
7802 bgp_attr_get_lcommunity(pi->attr));
7803 }
7804 if (match)
7805 bgp_process(bgp, dest, afi, safi);
7806 }
7807 if (aggregate->as_set) {
7808 bgp_compute_aggregate_aspath_val(aggregate);
7809 bgp_compute_aggregate_community_val(aggregate);
7810 bgp_compute_aggregate_ecommunity_val(aggregate);
7811 bgp_compute_aggregate_lcommunity_val(aggregate);
7812 }
7813
7814
7815 bgp_dest_unlock_node(top);
7816
7817
7818 if (aggregate->incomplete_origin_count > 0)
7819 origin = BGP_ORIGIN_INCOMPLETE;
7820 else if (aggregate->egp_origin_count > 0)
7821 origin = BGP_ORIGIN_EGP;
7822
7823 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7824 origin = aggregate->origin;
7825
7826 if (aggregate->as_set) {
7827 if (aggregate->aspath)
7828 /* Retrieve aggregate route's as-path.
7829 */
7830 aspath = aspath_dup(aggregate->aspath);
7831
7832 if (aggregate->community)
7833 /* Retrieve aggregate route's community.
7834 */
7835 community = community_dup(aggregate->community);
7836
7837 if (aggregate->ecommunity)
7838 /* Retrieve aggregate route's ecommunity.
7839 */
7840 ecommunity = ecommunity_dup(aggregate->ecommunity);
7841
7842 if (aggregate->lcommunity)
7843 /* Retrieve aggregate route's lcommunity.
7844 */
7845 lcommunity = lcommunity_dup(aggregate->lcommunity);
7846 }
7847
7848 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7849 ecommunity, lcommunity, atomic_aggregate,
7850 aggregate);
7851 }
7852
7853 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7854 safi_t safi, struct bgp_aggregate *aggregate)
7855 {
7856 struct bgp_table *table;
7857 struct bgp_dest *top;
7858 struct bgp_dest *dest;
7859 struct bgp_path_info *pi;
7860 unsigned long match;
7861
7862 table = bgp->rib[afi][safi];
7863
7864 /* If routes exists below this node, generate aggregate routes. */
7865 top = bgp_node_get(table, p);
7866 for (dest = bgp_node_get(table, p); dest;
7867 dest = bgp_route_next_until(dest, top)) {
7868 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7869
7870 if (dest_p->prefixlen <= p->prefixlen)
7871 continue;
7872 match = 0;
7873
7874 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7875 if (BGP_PATH_HOLDDOWN(pi))
7876 continue;
7877
7878 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7879 continue;
7880
7881 /*
7882 * This route is suppressed: attempt to unsuppress it.
7883 *
7884 * `aggr_unsuppress_path` will fail if this particular
7885 * aggregate route was not the suppressor.
7886 */
7887 if (pi->extra && pi->extra->aggr_suppressors &&
7888 listcount(pi->extra->aggr_suppressors)) {
7889 if (aggr_unsuppress_path(aggregate, pi))
7890 match++;
7891 }
7892
7893 aggregate->count--;
7894
7895 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7896 aggregate->incomplete_origin_count--;
7897 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7898 aggregate->egp_origin_count--;
7899
7900 if (aggregate->as_set) {
7901 /* Remove as-path from aggregate.
7902 */
7903 bgp_remove_aspath_from_aggregate_hash(
7904 aggregate,
7905 pi->attr->aspath);
7906
7907 if (bgp_attr_get_community(pi->attr))
7908 /* Remove community from aggregate.
7909 */
7910 bgp_remove_comm_from_aggregate_hash(
7911 aggregate,
7912 bgp_attr_get_community(
7913 pi->attr));
7914
7915 if (bgp_attr_get_ecommunity(pi->attr))
7916 /* Remove ecommunity from aggregate.
7917 */
7918 bgp_remove_ecomm_from_aggregate_hash(
7919 aggregate,
7920 bgp_attr_get_ecommunity(
7921 pi->attr));
7922
7923 if (bgp_attr_get_lcommunity(pi->attr))
7924 /* Remove lcommunity from aggregate.
7925 */
7926 bgp_remove_lcomm_from_aggregate_hash(
7927 aggregate,
7928 bgp_attr_get_lcommunity(
7929 pi->attr));
7930 }
7931 }
7932
7933 /* If this node was suppressed, process the change. */
7934 if (match)
7935 bgp_process(bgp, dest, afi, safi);
7936 }
7937 if (aggregate->as_set) {
7938 aspath_free(aggregate->aspath);
7939 aggregate->aspath = NULL;
7940 if (aggregate->community)
7941 community_free(&aggregate->community);
7942 if (aggregate->ecommunity)
7943 ecommunity_free(&aggregate->ecommunity);
7944 if (aggregate->lcommunity)
7945 lcommunity_free(&aggregate->lcommunity);
7946 }
7947
7948 bgp_dest_unlock_node(top);
7949 }
7950
7951 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7952 const struct prefix *aggr_p,
7953 struct bgp_path_info *pinew, afi_t afi,
7954 safi_t safi,
7955 struct bgp_aggregate *aggregate)
7956 {
7957 uint8_t origin;
7958 struct aspath *aspath = NULL;
7959 uint8_t atomic_aggregate = 0;
7960 struct community *community = NULL;
7961 struct ecommunity *ecommunity = NULL;
7962 struct lcommunity *lcommunity = NULL;
7963
7964 /* If the bgp instance is being deleted or self peer is deleted
7965 * then do not create aggregate route
7966 */
7967 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7968 || (bgp->peer_self == NULL))
7969 return;
7970
7971 /* ORIGIN attribute: If at least one route among routes that are
7972 * aggregated has ORIGIN with the value INCOMPLETE, then the
7973 * aggregated route must have the ORIGIN attribute with the value
7974 * INCOMPLETE. Otherwise, if at least one route among routes that
7975 * are aggregated has ORIGIN with the value EGP, then the aggregated
7976 * route must have the origin attribute with the value EGP. In all
7977 * other case the value of the ORIGIN attribute of the aggregated
7978 * route is INTERNAL.
7979 */
7980 origin = BGP_ORIGIN_IGP;
7981
7982 aggregate->count++;
7983
7984 /*
7985 * This must be called before `summary` check to avoid
7986 * "suppressing" twice.
7987 */
7988 if (aggregate->match_med)
7989 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7990 pinew);
7991
7992 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7993 aggr_suppress_path(aggregate, pinew);
7994
7995 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7996 && aggr_suppress_map_test(bgp, aggregate, pinew))
7997 aggr_suppress_path(aggregate, pinew);
7998
7999 switch (pinew->attr->origin) {
8000 case BGP_ORIGIN_INCOMPLETE:
8001 aggregate->incomplete_origin_count++;
8002 break;
8003 case BGP_ORIGIN_EGP:
8004 aggregate->egp_origin_count++;
8005 break;
8006 default:
8007 /* Do nothing.
8008 */
8009 break;
8010 }
8011
8012 if (aggregate->incomplete_origin_count > 0)
8013 origin = BGP_ORIGIN_INCOMPLETE;
8014 else if (aggregate->egp_origin_count > 0)
8015 origin = BGP_ORIGIN_EGP;
8016
8017 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8018 origin = aggregate->origin;
8019
8020 if (aggregate->as_set) {
8021 /* Compute aggregate route's as-path.
8022 */
8023 bgp_compute_aggregate_aspath(aggregate,
8024 pinew->attr->aspath);
8025
8026 /* Compute aggregate route's community.
8027 */
8028 if (bgp_attr_get_community(pinew->attr))
8029 bgp_compute_aggregate_community(
8030 aggregate, bgp_attr_get_community(pinew->attr));
8031
8032 /* Compute aggregate route's extended community.
8033 */
8034 if (bgp_attr_get_ecommunity(pinew->attr))
8035 bgp_compute_aggregate_ecommunity(
8036 aggregate,
8037 bgp_attr_get_ecommunity(pinew->attr));
8038
8039 /* Compute aggregate route's large community.
8040 */
8041 if (bgp_attr_get_lcommunity(pinew->attr))
8042 bgp_compute_aggregate_lcommunity(
8043 aggregate,
8044 bgp_attr_get_lcommunity(pinew->attr));
8045
8046 /* Retrieve aggregate route's as-path.
8047 */
8048 if (aggregate->aspath)
8049 aspath = aspath_dup(aggregate->aspath);
8050
8051 /* Retrieve aggregate route's community.
8052 */
8053 if (aggregate->community)
8054 community = community_dup(aggregate->community);
8055
8056 /* Retrieve aggregate route's ecommunity.
8057 */
8058 if (aggregate->ecommunity)
8059 ecommunity = ecommunity_dup(aggregate->ecommunity);
8060
8061 /* Retrieve aggregate route's lcommunity.
8062 */
8063 if (aggregate->lcommunity)
8064 lcommunity = lcommunity_dup(aggregate->lcommunity);
8065 }
8066
8067 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8068 aspath, community, ecommunity,
8069 lcommunity, atomic_aggregate, aggregate);
8070 }
8071
8072 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8073 safi_t safi,
8074 struct bgp_path_info *pi,
8075 struct bgp_aggregate *aggregate,
8076 const struct prefix *aggr_p)
8077 {
8078 uint8_t origin;
8079 struct aspath *aspath = NULL;
8080 uint8_t atomic_aggregate = 0;
8081 struct community *community = NULL;
8082 struct ecommunity *ecommunity = NULL;
8083 struct lcommunity *lcommunity = NULL;
8084 unsigned long match = 0;
8085
8086 /* If the bgp instance is being deleted or self peer is deleted
8087 * then do not create aggregate route
8088 */
8089 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8090 || (bgp->peer_self == NULL))
8091 return;
8092
8093 if (BGP_PATH_HOLDDOWN(pi))
8094 return;
8095
8096 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8097 return;
8098
8099 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8100 if (aggr_unsuppress_path(aggregate, pi))
8101 match++;
8102
8103 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8104 && aggr_suppress_map_test(bgp, aggregate, pi))
8105 if (aggr_unsuppress_path(aggregate, pi))
8106 match++;
8107
8108 /*
8109 * This must be called after `summary`, `suppress-map` check to avoid
8110 * "unsuppressing" twice.
8111 */
8112 if (aggregate->match_med)
8113 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8114
8115 if (aggregate->count > 0)
8116 aggregate->count--;
8117
8118 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8119 aggregate->incomplete_origin_count--;
8120 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8121 aggregate->egp_origin_count--;
8122
8123 if (aggregate->as_set) {
8124 /* Remove as-path from aggregate.
8125 */
8126 bgp_remove_aspath_from_aggregate(aggregate,
8127 pi->attr->aspath);
8128
8129 if (bgp_attr_get_community(pi->attr))
8130 /* Remove community from aggregate.
8131 */
8132 bgp_remove_community_from_aggregate(
8133 aggregate, bgp_attr_get_community(pi->attr));
8134
8135 if (bgp_attr_get_ecommunity(pi->attr))
8136 /* Remove ecommunity from aggregate.
8137 */
8138 bgp_remove_ecommunity_from_aggregate(
8139 aggregate, bgp_attr_get_ecommunity(pi->attr));
8140
8141 if (bgp_attr_get_lcommunity(pi->attr))
8142 /* Remove lcommunity from aggregate.
8143 */
8144 bgp_remove_lcommunity_from_aggregate(
8145 aggregate, bgp_attr_get_lcommunity(pi->attr));
8146 }
8147
8148 /* If this node was suppressed, process the change. */
8149 if (match)
8150 bgp_process(bgp, pi->net, afi, safi);
8151
8152 origin = BGP_ORIGIN_IGP;
8153 if (aggregate->incomplete_origin_count > 0)
8154 origin = BGP_ORIGIN_INCOMPLETE;
8155 else if (aggregate->egp_origin_count > 0)
8156 origin = BGP_ORIGIN_EGP;
8157
8158 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8159 origin = aggregate->origin;
8160
8161 if (aggregate->as_set) {
8162 /* Retrieve aggregate route's as-path.
8163 */
8164 if (aggregate->aspath)
8165 aspath = aspath_dup(aggregate->aspath);
8166
8167 /* Retrieve aggregate route's community.
8168 */
8169 if (aggregate->community)
8170 community = community_dup(aggregate->community);
8171
8172 /* Retrieve aggregate route's ecommunity.
8173 */
8174 if (aggregate->ecommunity)
8175 ecommunity = ecommunity_dup(aggregate->ecommunity);
8176
8177 /* Retrieve aggregate route's lcommunity.
8178 */
8179 if (aggregate->lcommunity)
8180 lcommunity = lcommunity_dup(aggregate->lcommunity);
8181 }
8182
8183 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8184 aspath, community, ecommunity,
8185 lcommunity, atomic_aggregate, aggregate);
8186 }
8187
8188 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8189 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8190 {
8191 struct bgp_dest *child;
8192 struct bgp_dest *dest;
8193 struct bgp_aggregate *aggregate;
8194 struct bgp_table *table;
8195
8196 table = bgp->aggregate[afi][safi];
8197
8198 /* No aggregates configured. */
8199 if (bgp_table_top_nolock(table) == NULL)
8200 return;
8201
8202 if (p->prefixlen == 0)
8203 return;
8204
8205 if (BGP_PATH_HOLDDOWN(pi))
8206 return;
8207
8208 /* If suppress fib is enabled and route not installed
8209 * in FIB, do not update the aggregate route
8210 */
8211 if (!bgp_check_advertise(bgp, pi->net))
8212 return;
8213
8214 child = bgp_node_get(table, p);
8215
8216 /* Aggregate address configuration check. */
8217 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8218 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8219
8220 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8221 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8222 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8223 aggregate);
8224 }
8225 }
8226 bgp_dest_unlock_node(child);
8227 }
8228
8229 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8230 struct bgp_path_info *del, afi_t afi, safi_t safi)
8231 {
8232 struct bgp_dest *child;
8233 struct bgp_dest *dest;
8234 struct bgp_aggregate *aggregate;
8235 struct bgp_table *table;
8236
8237 table = bgp->aggregate[afi][safi];
8238
8239 /* No aggregates configured. */
8240 if (bgp_table_top_nolock(table) == NULL)
8241 return;
8242
8243 if (p->prefixlen == 0)
8244 return;
8245
8246 child = bgp_node_get(table, p);
8247
8248 /* Aggregate address configuration check. */
8249 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8250 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8251
8252 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8253 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8254 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8255 aggregate, dest_p);
8256 }
8257 }
8258 bgp_dest_unlock_node(child);
8259 }
8260
8261 /* Aggregate route attribute. */
8262 #define AGGREGATE_SUMMARY_ONLY 1
8263 #define AGGREGATE_AS_SET 1
8264 #define AGGREGATE_AS_UNSET 0
8265
8266 static const char *bgp_origin2str(uint8_t origin)
8267 {
8268 switch (origin) {
8269 case BGP_ORIGIN_IGP:
8270 return "igp";
8271 case BGP_ORIGIN_EGP:
8272 return "egp";
8273 case BGP_ORIGIN_INCOMPLETE:
8274 return "incomplete";
8275 }
8276 return "n/a";
8277 }
8278
8279 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8280 {
8281 switch (v_state) {
8282 case RPKI_NOT_BEING_USED:
8283 return "not used";
8284 case RPKI_VALID:
8285 return "valid";
8286 case RPKI_NOTFOUND:
8287 return "not found";
8288 case RPKI_INVALID:
8289 return "invalid";
8290 }
8291
8292 assert(!"We should never get here this is a dev escape");
8293 return "ERROR";
8294 }
8295
8296 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8297 afi_t afi, safi_t safi)
8298 {
8299 VTY_DECLVAR_CONTEXT(bgp, bgp);
8300 int ret;
8301 struct prefix p;
8302 struct bgp_dest *dest;
8303 struct bgp_aggregate *aggregate;
8304
8305 /* Convert string to prefix structure. */
8306 ret = str2prefix(prefix_str, &p);
8307 if (!ret) {
8308 vty_out(vty, "Malformed prefix\n");
8309 return CMD_WARNING_CONFIG_FAILED;
8310 }
8311 apply_mask(&p);
8312
8313 /* Old configuration check. */
8314 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8315 if (!dest) {
8316 vty_out(vty,
8317 "%% There is no aggregate-address configuration.\n");
8318 return CMD_WARNING_CONFIG_FAILED;
8319 }
8320
8321 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8322 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8323 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8324 NULL, NULL, 0, aggregate);
8325
8326 /* Unlock aggregate address configuration. */
8327 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8328
8329 if (aggregate->community)
8330 community_free(&aggregate->community);
8331
8332 if (aggregate->community_hash) {
8333 /* Delete all communities in the hash.
8334 */
8335 hash_clean(aggregate->community_hash,
8336 bgp_aggr_community_remove);
8337 /* Free up the community_hash.
8338 */
8339 hash_free(aggregate->community_hash);
8340 }
8341
8342 if (aggregate->ecommunity)
8343 ecommunity_free(&aggregate->ecommunity);
8344
8345 if (aggregate->ecommunity_hash) {
8346 /* Delete all ecommunities in the hash.
8347 */
8348 hash_clean(aggregate->ecommunity_hash,
8349 bgp_aggr_ecommunity_remove);
8350 /* Free up the ecommunity_hash.
8351 */
8352 hash_free(aggregate->ecommunity_hash);
8353 }
8354
8355 if (aggregate->lcommunity)
8356 lcommunity_free(&aggregate->lcommunity);
8357
8358 if (aggregate->lcommunity_hash) {
8359 /* Delete all lcommunities in the hash.
8360 */
8361 hash_clean(aggregate->lcommunity_hash,
8362 bgp_aggr_lcommunity_remove);
8363 /* Free up the lcommunity_hash.
8364 */
8365 hash_free(aggregate->lcommunity_hash);
8366 }
8367
8368 if (aggregate->aspath)
8369 aspath_free(aggregate->aspath);
8370
8371 if (aggregate->aspath_hash) {
8372 /* Delete all as-paths in the hash.
8373 */
8374 hash_clean(aggregate->aspath_hash,
8375 bgp_aggr_aspath_remove);
8376 /* Free up the aspath_hash.
8377 */
8378 hash_free(aggregate->aspath_hash);
8379 }
8380
8381 bgp_aggregate_free(aggregate);
8382 bgp_dest_unlock_node(dest);
8383 bgp_dest_unlock_node(dest);
8384
8385 return CMD_SUCCESS;
8386 }
8387
8388 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8389 safi_t safi, const char *rmap,
8390 uint8_t summary_only, uint8_t as_set,
8391 uint8_t origin, bool match_med,
8392 const char *suppress_map)
8393 {
8394 VTY_DECLVAR_CONTEXT(bgp, bgp);
8395 int ret;
8396 struct prefix p;
8397 struct bgp_dest *dest;
8398 struct bgp_aggregate *aggregate;
8399 uint8_t as_set_new = as_set;
8400
8401 if (suppress_map && summary_only) {
8402 vty_out(vty,
8403 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8404 return CMD_WARNING_CONFIG_FAILED;
8405 }
8406
8407 /* Convert string to prefix structure. */
8408 ret = str2prefix(prefix_str, &p);
8409 if (!ret) {
8410 vty_out(vty, "Malformed prefix\n");
8411 return CMD_WARNING_CONFIG_FAILED;
8412 }
8413 apply_mask(&p);
8414
8415 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8416 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8417 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8418 prefix_str);
8419 return CMD_WARNING_CONFIG_FAILED;
8420 }
8421
8422 /* Old configuration check. */
8423 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8424 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8425
8426 if (aggregate) {
8427 vty_out(vty, "There is already same aggregate network.\n");
8428 /* try to remove the old entry */
8429 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8430 if (ret) {
8431 vty_out(vty, "Error deleting aggregate.\n");
8432 bgp_dest_unlock_node(dest);
8433 return CMD_WARNING_CONFIG_FAILED;
8434 }
8435 }
8436
8437 /* Make aggregate address structure. */
8438 aggregate = bgp_aggregate_new();
8439 aggregate->summary_only = summary_only;
8440 aggregate->match_med = match_med;
8441
8442 /* Network operators MUST NOT locally generate any new
8443 * announcements containing AS_SET or AS_CONFED_SET. If they have
8444 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8445 * SHOULD withdraw those routes and re-announce routes for the
8446 * aggregate or component prefixes (i.e., the more-specific routes
8447 * subsumed by the previously aggregated route) without AS_SET
8448 * or AS_CONFED_SET in the updates.
8449 */
8450 if (bgp->reject_as_sets) {
8451 if (as_set == AGGREGATE_AS_SET) {
8452 as_set_new = AGGREGATE_AS_UNSET;
8453 zlog_warn(
8454 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8455 __func__);
8456 vty_out(vty,
8457 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8458 }
8459 }
8460
8461 aggregate->as_set = as_set_new;
8462 aggregate->safi = safi;
8463 /* Override ORIGIN attribute if defined.
8464 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8465 * to IGP which is not what rfc4271 says.
8466 * This enables the same behavior, optionally.
8467 */
8468 aggregate->origin = origin;
8469
8470 if (rmap) {
8471 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8472 route_map_counter_decrement(aggregate->rmap.map);
8473 aggregate->rmap.name =
8474 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8475 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8476 route_map_counter_increment(aggregate->rmap.map);
8477 }
8478
8479 if (suppress_map) {
8480 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8481 route_map_counter_decrement(aggregate->suppress_map);
8482
8483 aggregate->suppress_map_name =
8484 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8485 aggregate->suppress_map =
8486 route_map_lookup_by_name(aggregate->suppress_map_name);
8487 route_map_counter_increment(aggregate->suppress_map);
8488 }
8489
8490 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8491
8492 /* Aggregate address insert into BGP routing table. */
8493 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8494
8495 return CMD_SUCCESS;
8496 }
8497
8498 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8499 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8500 "as-set$as_set_s"
8501 "|summary-only$summary_only"
8502 "|route-map RMAP_NAME$rmap_name"
8503 "|origin <egp|igp|incomplete>$origin_s"
8504 "|matching-MED-only$match_med"
8505 "|suppress-map RMAP_NAME$suppress_map"
8506 "}]",
8507 NO_STR
8508 "Configure BGP aggregate entries\n"
8509 "Aggregate prefix\n"
8510 "Aggregate address\n"
8511 "Aggregate mask\n"
8512 "Generate AS set path information\n"
8513 "Filter more specific routes from updates\n"
8514 "Apply route map to aggregate network\n"
8515 "Route map name\n"
8516 "BGP origin code\n"
8517 "Remote EGP\n"
8518 "Local IGP\n"
8519 "Unknown heritage\n"
8520 "Only aggregate routes with matching MED\n"
8521 "Suppress the selected more specific routes\n"
8522 "Route map with the route selectors\n")
8523 {
8524 const char *prefix_s = NULL;
8525 safi_t safi = bgp_node_safi(vty);
8526 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8527 int as_set = AGGREGATE_AS_UNSET;
8528 char prefix_buf[PREFIX2STR_BUFFER];
8529
8530 if (addr_str) {
8531 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8532 sizeof(prefix_buf))
8533 == 0) {
8534 vty_out(vty, "%% Inconsistent address and mask\n");
8535 return CMD_WARNING_CONFIG_FAILED;
8536 }
8537 prefix_s = prefix_buf;
8538 } else
8539 prefix_s = prefix_str;
8540
8541 if (origin_s) {
8542 if (strcmp(origin_s, "egp") == 0)
8543 origin = BGP_ORIGIN_EGP;
8544 else if (strcmp(origin_s, "igp") == 0)
8545 origin = BGP_ORIGIN_IGP;
8546 else if (strcmp(origin_s, "incomplete") == 0)
8547 origin = BGP_ORIGIN_INCOMPLETE;
8548 }
8549
8550 if (as_set_s)
8551 as_set = AGGREGATE_AS_SET;
8552
8553 /* Handle configuration removal, otherwise installation. */
8554 if (no)
8555 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8556
8557 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8558 summary_only != NULL, as_set, origin,
8559 match_med != NULL, suppress_map);
8560 }
8561
8562 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8563 "[no] aggregate-address X:X::X:X/M$prefix [{"
8564 "as-set$as_set_s"
8565 "|summary-only$summary_only"
8566 "|route-map RMAP_NAME$rmap_name"
8567 "|origin <egp|igp|incomplete>$origin_s"
8568 "|matching-MED-only$match_med"
8569 "|suppress-map RMAP_NAME$suppress_map"
8570 "}]",
8571 NO_STR
8572 "Configure BGP aggregate entries\n"
8573 "Aggregate prefix\n"
8574 "Generate AS set path information\n"
8575 "Filter more specific routes from updates\n"
8576 "Apply route map to aggregate network\n"
8577 "Route map name\n"
8578 "BGP origin code\n"
8579 "Remote EGP\n"
8580 "Local IGP\n"
8581 "Unknown heritage\n"
8582 "Only aggregate routes with matching MED\n"
8583 "Suppress the selected more specific routes\n"
8584 "Route map with the route selectors\n")
8585 {
8586 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8587 int as_set = AGGREGATE_AS_UNSET;
8588
8589 if (origin_s) {
8590 if (strcmp(origin_s, "egp") == 0)
8591 origin = BGP_ORIGIN_EGP;
8592 else if (strcmp(origin_s, "igp") == 0)
8593 origin = BGP_ORIGIN_IGP;
8594 else if (strcmp(origin_s, "incomplete") == 0)
8595 origin = BGP_ORIGIN_INCOMPLETE;
8596 }
8597
8598 if (as_set_s)
8599 as_set = AGGREGATE_AS_SET;
8600
8601 /* Handle configuration removal, otherwise installation. */
8602 if (no)
8603 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8604 SAFI_UNICAST);
8605
8606 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8607 rmap_name, summary_only != NULL, as_set,
8608 origin, match_med != NULL, suppress_map);
8609 }
8610
8611 /* Redistribute route treatment. */
8612 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8613 const union g_addr *nexthop, ifindex_t ifindex,
8614 enum nexthop_types_t nhtype, uint8_t distance,
8615 enum blackhole_type bhtype, uint32_t metric,
8616 uint8_t type, unsigned short instance,
8617 route_tag_t tag)
8618 {
8619 struct bgp_path_info *new;
8620 struct bgp_path_info *bpi;
8621 struct bgp_path_info rmap_path;
8622 struct bgp_dest *bn;
8623 struct attr attr;
8624 struct attr *new_attr;
8625 afi_t afi;
8626 route_map_result_t ret;
8627 struct bgp_redist *red;
8628
8629 /* Make default attribute. */
8630 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8631 /*
8632 * This must not be NULL to satisfy Coverity SA
8633 */
8634 assert(attr.aspath);
8635
8636 switch (nhtype) {
8637 case NEXTHOP_TYPE_IFINDEX:
8638 switch (p->family) {
8639 case AF_INET:
8640 attr.nexthop.s_addr = INADDR_ANY;
8641 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8642 break;
8643 case AF_INET6:
8644 memset(&attr.mp_nexthop_global, 0,
8645 sizeof(attr.mp_nexthop_global));
8646 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8647 break;
8648 }
8649 break;
8650 case NEXTHOP_TYPE_IPV4:
8651 case NEXTHOP_TYPE_IPV4_IFINDEX:
8652 attr.nexthop = nexthop->ipv4;
8653 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8654 break;
8655 case NEXTHOP_TYPE_IPV6:
8656 case NEXTHOP_TYPE_IPV6_IFINDEX:
8657 attr.mp_nexthop_global = nexthop->ipv6;
8658 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8659 break;
8660 case NEXTHOP_TYPE_BLACKHOLE:
8661 switch (p->family) {
8662 case AF_INET:
8663 attr.nexthop.s_addr = INADDR_ANY;
8664 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8665 break;
8666 case AF_INET6:
8667 memset(&attr.mp_nexthop_global, 0,
8668 sizeof(attr.mp_nexthop_global));
8669 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8670 break;
8671 }
8672 attr.bh_type = bhtype;
8673 break;
8674 }
8675 attr.nh_type = nhtype;
8676 attr.nh_ifindex = ifindex;
8677
8678 attr.med = metric;
8679 attr.distance = distance;
8680 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8681 attr.tag = tag;
8682
8683 afi = family2afi(p->family);
8684
8685 red = bgp_redist_lookup(bgp, afi, type, instance);
8686 if (red) {
8687 struct attr attr_new;
8688
8689 /* Copy attribute for modification. */
8690 attr_new = attr;
8691
8692 if (red->redist_metric_flag)
8693 attr_new.med = red->redist_metric;
8694
8695 /* Apply route-map. */
8696 if (red->rmap.name) {
8697 memset(&rmap_path, 0, sizeof(rmap_path));
8698 rmap_path.peer = bgp->peer_self;
8699 rmap_path.attr = &attr_new;
8700
8701 SET_FLAG(bgp->peer_self->rmap_type,
8702 PEER_RMAP_TYPE_REDISTRIBUTE);
8703
8704 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8705
8706 bgp->peer_self->rmap_type = 0;
8707
8708 if (ret == RMAP_DENYMATCH) {
8709 /* Free uninterned attribute. */
8710 bgp_attr_flush(&attr_new);
8711
8712 /* Unintern original. */
8713 aspath_unintern(&attr.aspath);
8714 bgp_redistribute_delete(bgp, p, type, instance);
8715 return;
8716 }
8717 }
8718
8719 if (bgp_in_graceful_shutdown(bgp))
8720 bgp_attr_add_gshut_community(&attr_new);
8721
8722 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8723 SAFI_UNICAST, p, NULL);
8724
8725 new_attr = bgp_attr_intern(&attr_new);
8726
8727 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8728 if (bpi->peer == bgp->peer_self
8729 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8730 break;
8731
8732 if (bpi) {
8733 /* Ensure the (source route) type is updated. */
8734 bpi->type = type;
8735 if (attrhash_cmp(bpi->attr, new_attr)
8736 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8737 bgp_attr_unintern(&new_attr);
8738 aspath_unintern(&attr.aspath);
8739 bgp_dest_unlock_node(bn);
8740 return;
8741 } else {
8742 /* The attribute is changed. */
8743 bgp_path_info_set_flag(bn, bpi,
8744 BGP_PATH_ATTR_CHANGED);
8745
8746 /* Rewrite BGP route information. */
8747 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8748 bgp_path_info_restore(bn, bpi);
8749 else
8750 bgp_aggregate_decrement(
8751 bgp, p, bpi, afi, SAFI_UNICAST);
8752 bgp_attr_unintern(&bpi->attr);
8753 bpi->attr = new_attr;
8754 bpi->uptime = monotime(NULL);
8755
8756 /* Process change. */
8757 bgp_aggregate_increment(bgp, p, bpi, afi,
8758 SAFI_UNICAST);
8759 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8760 bgp_dest_unlock_node(bn);
8761 aspath_unintern(&attr.aspath);
8762
8763 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8764 || (bgp->inst_type
8765 == BGP_INSTANCE_TYPE_DEFAULT)) {
8766
8767 vpn_leak_from_vrf_update(
8768 bgp_get_default(), bgp, bpi);
8769 }
8770 return;
8771 }
8772 }
8773
8774 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8775 bgp->peer_self, new_attr, bn);
8776 SET_FLAG(new->flags, BGP_PATH_VALID);
8777
8778 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8779 bgp_path_info_add(bn, new);
8780 bgp_dest_unlock_node(bn);
8781 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8782 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8783
8784 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8785 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8786
8787 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8788 }
8789 }
8790
8791 /* Unintern original. */
8792 aspath_unintern(&attr.aspath);
8793 }
8794
8795 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8796 unsigned short instance)
8797 {
8798 afi_t afi;
8799 struct bgp_dest *dest;
8800 struct bgp_path_info *pi;
8801 struct bgp_redist *red;
8802
8803 afi = family2afi(p->family);
8804
8805 red = bgp_redist_lookup(bgp, afi, type, instance);
8806 if (red) {
8807 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8808 SAFI_UNICAST, p, NULL);
8809
8810 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8811 if (pi->peer == bgp->peer_self && pi->type == type)
8812 break;
8813
8814 if (pi) {
8815 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8816 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8817
8818 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8819 bgp, pi);
8820 }
8821 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8822 bgp_path_info_delete(dest, pi);
8823 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8824 }
8825 bgp_dest_unlock_node(dest);
8826 }
8827 }
8828
8829 /* Withdraw specified route type's route. */
8830 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8831 unsigned short instance)
8832 {
8833 struct bgp_dest *dest;
8834 struct bgp_path_info *pi;
8835 struct bgp_table *table;
8836
8837 table = bgp->rib[afi][SAFI_UNICAST];
8838
8839 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8840 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8841 if (pi->peer == bgp->peer_self && pi->type == type
8842 && pi->instance == instance)
8843 break;
8844
8845 if (pi) {
8846 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8847 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8848
8849 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8850 bgp, pi);
8851 }
8852 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8853 pi, afi, SAFI_UNICAST);
8854 bgp_path_info_delete(dest, pi);
8855 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8856 }
8857 }
8858 }
8859
8860 /* Static function to display route. */
8861 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8862 struct vty *vty, json_object *json, bool wide)
8863 {
8864 int len = 0;
8865 char buf[BUFSIZ];
8866
8867 if (p->family == AF_INET) {
8868 if (!json) {
8869 len = vty_out(vty, "%pFX", p);
8870 } else {
8871 json_object_string_add(json, "prefix",
8872 inet_ntop(p->family,
8873 &p->u.prefix, buf,
8874 BUFSIZ));
8875 json_object_int_add(json, "prefixLen", p->prefixlen);
8876 json_object_string_addf(json, "network", "%pFX", p);
8877 json_object_int_add(json, "version", dest->version);
8878 }
8879 } else if (p->family == AF_ETHERNET) {
8880 len = vty_out(vty, "%pFX", p);
8881 } else if (p->family == AF_EVPN) {
8882 if (!json)
8883 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8884 else
8885 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8886 } else if (p->family == AF_FLOWSPEC) {
8887 route_vty_out_flowspec(vty, p, NULL,
8888 json ?
8889 NLRI_STRING_FORMAT_JSON_SIMPLE :
8890 NLRI_STRING_FORMAT_MIN, json);
8891 } else {
8892 if (!json)
8893 len = vty_out(vty, "%pFX", p);
8894 else {
8895 json_object_string_add(json, "prefix",
8896 inet_ntop(p->family,
8897 &p->u.prefix, buf,
8898 BUFSIZ));
8899 json_object_int_add(json, "prefixLen", p->prefixlen);
8900 json_object_string_addf(json, "network", "%pFX", p);
8901 json_object_int_add(json, "version", dest->version);
8902 }
8903 }
8904
8905 if (!json) {
8906 len = wide ? (45 - len) : (17 - len);
8907 if (len < 1)
8908 vty_out(vty, "\n%*s", 20, " ");
8909 else
8910 vty_out(vty, "%*s", len, " ");
8911 }
8912 }
8913
8914 enum bgp_display_type {
8915 normal_list,
8916 };
8917
8918 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8919 {
8920 switch (reason) {
8921 case bgp_path_selection_none:
8922 return "Nothing to Select";
8923 case bgp_path_selection_first:
8924 return "First path received";
8925 case bgp_path_selection_evpn_sticky_mac:
8926 return "EVPN Sticky Mac";
8927 case bgp_path_selection_evpn_seq:
8928 return "EVPN sequence number";
8929 case bgp_path_selection_evpn_lower_ip:
8930 return "EVPN lower IP";
8931 case bgp_path_selection_evpn_local_path:
8932 return "EVPN local ES path";
8933 case bgp_path_selection_evpn_non_proxy:
8934 return "EVPN non proxy";
8935 case bgp_path_selection_weight:
8936 return "Weight";
8937 case bgp_path_selection_local_pref:
8938 return "Local Pref";
8939 case bgp_path_selection_accept_own:
8940 return "Accept Own";
8941 case bgp_path_selection_local_route:
8942 return "Local Route";
8943 case bgp_path_selection_confed_as_path:
8944 return "Confederation based AS Path";
8945 case bgp_path_selection_as_path:
8946 return "AS Path";
8947 case bgp_path_selection_origin:
8948 return "Origin";
8949 case bgp_path_selection_med:
8950 return "MED";
8951 case bgp_path_selection_peer:
8952 return "Peer Type";
8953 case bgp_path_selection_confed:
8954 return "Confed Peer Type";
8955 case bgp_path_selection_igp_metric:
8956 return "IGP Metric";
8957 case bgp_path_selection_older:
8958 return "Older Path";
8959 case bgp_path_selection_router_id:
8960 return "Router ID";
8961 case bgp_path_selection_cluster_length:
8962 return "Cluster length";
8963 case bgp_path_selection_stale:
8964 return "Path Staleness";
8965 case bgp_path_selection_local_configured:
8966 return "Locally configured route";
8967 case bgp_path_selection_neighbor_ip:
8968 return "Neighbor IP";
8969 case bgp_path_selection_default:
8970 return "Nothing left to compare";
8971 }
8972 return "Invalid (internal error)";
8973 }
8974
8975 /* Print the short form route status for a bgp_path_info */
8976 static void route_vty_short_status_out(struct vty *vty,
8977 struct bgp_path_info *path,
8978 const struct prefix *p,
8979 json_object *json_path)
8980 {
8981 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8982
8983 if (json_path) {
8984
8985 /* Route status display. */
8986 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8987 json_object_boolean_true_add(json_path, "removed");
8988
8989 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8990 json_object_boolean_true_add(json_path, "stale");
8991
8992 if (path->extra && bgp_path_suppressed(path))
8993 json_object_boolean_true_add(json_path, "suppressed");
8994
8995 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8996 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8997 json_object_boolean_true_add(json_path, "valid");
8998
8999 /* Selected */
9000 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9001 json_object_boolean_true_add(json_path, "history");
9002
9003 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9004 json_object_boolean_true_add(json_path, "damped");
9005
9006 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9007 json_object_boolean_true_add(json_path, "bestpath");
9008 json_object_string_add(json_path, "selectionReason",
9009 bgp_path_selection_reason2str(
9010 path->net->reason));
9011 }
9012
9013 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9014 json_object_boolean_true_add(json_path, "multipath");
9015
9016 /* Internal route. */
9017 if ((path->peer->as)
9018 && (path->peer->as == path->peer->local_as))
9019 json_object_string_add(json_path, "pathFrom",
9020 "internal");
9021 else
9022 json_object_string_add(json_path, "pathFrom",
9023 "external");
9024
9025 return;
9026 }
9027
9028 /* RPKI validation state */
9029 rpki_state =
9030 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9031
9032 if (rpki_state == RPKI_VALID)
9033 vty_out(vty, "V");
9034 else if (rpki_state == RPKI_INVALID)
9035 vty_out(vty, "I");
9036 else if (rpki_state == RPKI_NOTFOUND)
9037 vty_out(vty, "N");
9038
9039 /* Route status display. */
9040 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9041 vty_out(vty, "R");
9042 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9043 vty_out(vty, "S");
9044 else if (bgp_path_suppressed(path))
9045 vty_out(vty, "s");
9046 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9047 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9048 vty_out(vty, "*");
9049 else
9050 vty_out(vty, " ");
9051
9052 /* Selected */
9053 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9054 vty_out(vty, "h");
9055 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9056 vty_out(vty, "d");
9057 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9058 vty_out(vty, ">");
9059 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9060 vty_out(vty, "=");
9061 else
9062 vty_out(vty, " ");
9063
9064 /* Internal route. */
9065 if (path->peer && (path->peer->as)
9066 && (path->peer->as == path->peer->local_as))
9067 vty_out(vty, "i");
9068 else
9069 vty_out(vty, " ");
9070 }
9071
9072 static char *bgp_nexthop_hostname(struct peer *peer,
9073 struct bgp_nexthop_cache *bnc)
9074 {
9075 if (peer->hostname
9076 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9077 return peer->hostname;
9078 return NULL;
9079 }
9080
9081 /* called from terminal list command */
9082 void route_vty_out(struct vty *vty, const struct prefix *p,
9083 struct bgp_path_info *path, int display, safi_t safi,
9084 json_object *json_paths, bool wide)
9085 {
9086 int len;
9087 struct attr *attr = path->attr;
9088 json_object *json_path = NULL;
9089 json_object *json_nexthops = NULL;
9090 json_object *json_nexthop_global = NULL;
9091 json_object *json_nexthop_ll = NULL;
9092 json_object *json_ext_community = NULL;
9093 char vrf_id_str[VRF_NAMSIZ] = {0};
9094 bool nexthop_self =
9095 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9096 bool nexthop_othervrf = false;
9097 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9098 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9099 char *nexthop_hostname =
9100 bgp_nexthop_hostname(path->peer, path->nexthop);
9101 char esi_buf[ESI_STR_LEN];
9102
9103 if (json_paths)
9104 json_path = json_object_new_object();
9105
9106 /* short status lead text */
9107 route_vty_short_status_out(vty, path, p, json_path);
9108
9109 if (!json_paths) {
9110 /* print prefix and mask */
9111 if (!display)
9112 route_vty_out_route(path->net, p, vty, json_path, wide);
9113 else
9114 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9115 } else {
9116 route_vty_out_route(path->net, p, vty, json_path, wide);
9117 }
9118
9119 /*
9120 * If vrf id of nexthop is different from that of prefix,
9121 * set up printable string to append
9122 */
9123 if (path->extra && path->extra->bgp_orig) {
9124 const char *self = "";
9125
9126 if (nexthop_self)
9127 self = "<";
9128
9129 nexthop_othervrf = true;
9130 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9131
9132 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9133 snprintf(vrf_id_str, sizeof(vrf_id_str),
9134 "@%s%s", VRFID_NONE_STR, self);
9135 else
9136 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9137 path->extra->bgp_orig->vrf_id, self);
9138
9139 if (path->extra->bgp_orig->inst_type
9140 != BGP_INSTANCE_TYPE_DEFAULT)
9141
9142 nexthop_vrfname = path->extra->bgp_orig->name;
9143 } else {
9144 const char *self = "";
9145
9146 if (nexthop_self)
9147 self = "<";
9148
9149 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9150 }
9151
9152 /*
9153 * For ENCAP and EVPN routes, nexthop address family is not
9154 * neccessarily the same as the prefix address family.
9155 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9156 * EVPN routes are also exchanged with a MP nexthop. Currently,
9157 * this
9158 * is only IPv4, the value will be present in either
9159 * attr->nexthop or
9160 * attr->mp_nexthop_global_in
9161 */
9162 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9163 char buf[BUFSIZ];
9164 char nexthop[128];
9165 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9166
9167 switch (af) {
9168 case AF_INET:
9169 snprintf(nexthop, sizeof(nexthop), "%s",
9170 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
9171 BUFSIZ));
9172 break;
9173 case AF_INET6:
9174 snprintf(nexthop, sizeof(nexthop), "%s",
9175 inet_ntop(af, &attr->mp_nexthop_global, buf,
9176 BUFSIZ));
9177 break;
9178 default:
9179 snprintf(nexthop, sizeof(nexthop), "?");
9180 break;
9181 }
9182
9183 if (json_paths) {
9184 json_nexthop_global = json_object_new_object();
9185
9186 json_object_string_add(json_nexthop_global, "ip",
9187 nexthop);
9188
9189 if (path->peer->hostname)
9190 json_object_string_add(json_nexthop_global,
9191 "hostname",
9192 path->peer->hostname);
9193
9194 json_object_string_add(json_nexthop_global, "afi",
9195 (af == AF_INET) ? "ipv4"
9196 : "ipv6");
9197 json_object_boolean_true_add(json_nexthop_global,
9198 "used");
9199 } else {
9200 if (nexthop_hostname)
9201 len = vty_out(vty, "%s(%s)%s", nexthop,
9202 nexthop_hostname, vrf_id_str);
9203 else
9204 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9205
9206 len = wide ? (41 - len) : (16 - len);
9207 if (len < 1)
9208 vty_out(vty, "\n%*s", 36, " ");
9209 else
9210 vty_out(vty, "%*s", len, " ");
9211 }
9212 } else if (safi == SAFI_EVPN) {
9213 if (json_paths) {
9214 json_nexthop_global = json_object_new_object();
9215
9216 json_object_string_addf(json_nexthop_global, "ip",
9217 "%pI4",
9218 &attr->mp_nexthop_global_in);
9219
9220 if (path->peer->hostname)
9221 json_object_string_add(json_nexthop_global,
9222 "hostname",
9223 path->peer->hostname);
9224
9225 json_object_string_add(json_nexthop_global, "afi",
9226 "ipv4");
9227 json_object_boolean_true_add(json_nexthop_global,
9228 "used");
9229 } else {
9230 if (nexthop_hostname)
9231 len = vty_out(vty, "%pI4(%s)%s",
9232 &attr->mp_nexthop_global_in,
9233 nexthop_hostname, vrf_id_str);
9234 else
9235 len = vty_out(vty, "%pI4%s",
9236 &attr->mp_nexthop_global_in,
9237 vrf_id_str);
9238
9239 len = wide ? (41 - len) : (16 - len);
9240 if (len < 1)
9241 vty_out(vty, "\n%*s", 36, " ");
9242 else
9243 vty_out(vty, "%*s", len, " ");
9244 }
9245 } else if (safi == SAFI_FLOWSPEC) {
9246 if (attr->nexthop.s_addr != INADDR_ANY) {
9247 if (json_paths) {
9248 json_nexthop_global = json_object_new_object();
9249
9250 json_object_string_add(json_nexthop_global,
9251 "afi", "ipv4");
9252 json_object_string_addf(json_nexthop_global,
9253 "ip", "%pI4",
9254 &attr->nexthop);
9255
9256 if (path->peer->hostname)
9257 json_object_string_add(
9258 json_nexthop_global, "hostname",
9259 path->peer->hostname);
9260
9261 json_object_boolean_true_add(
9262 json_nexthop_global,
9263 "used");
9264 } else {
9265 if (nexthop_hostname)
9266 len = vty_out(vty, "%pI4(%s)%s",
9267 &attr->nexthop,
9268 nexthop_hostname,
9269 vrf_id_str);
9270 else
9271 len = vty_out(vty, "%pI4%s",
9272 &attr->nexthop,
9273 vrf_id_str);
9274
9275 len = wide ? (41 - len) : (16 - len);
9276 if (len < 1)
9277 vty_out(vty, "\n%*s", 36, " ");
9278 else
9279 vty_out(vty, "%*s", len, " ");
9280 }
9281 }
9282 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9283 if (json_paths) {
9284 json_nexthop_global = json_object_new_object();
9285
9286 json_object_string_addf(json_nexthop_global, "ip",
9287 "%pI4", &attr->nexthop);
9288
9289 if (path->peer->hostname)
9290 json_object_string_add(json_nexthop_global,
9291 "hostname",
9292 path->peer->hostname);
9293
9294 json_object_string_add(json_nexthop_global, "afi",
9295 "ipv4");
9296 json_object_boolean_true_add(json_nexthop_global,
9297 "used");
9298 } else {
9299 if (nexthop_hostname)
9300 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9301 nexthop_hostname, vrf_id_str);
9302 else
9303 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9304 vrf_id_str);
9305
9306 len = wide ? (41 - len) : (16 - len);
9307 if (len < 1)
9308 vty_out(vty, "\n%*s", 36, " ");
9309 else
9310 vty_out(vty, "%*s", len, " ");
9311 }
9312 }
9313
9314 /* IPv6 Next Hop */
9315 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9316 if (json_paths) {
9317 json_nexthop_global = json_object_new_object();
9318 json_object_string_addf(json_nexthop_global, "ip",
9319 "%pI6",
9320 &attr->mp_nexthop_global);
9321
9322 if (path->peer->hostname)
9323 json_object_string_add(json_nexthop_global,
9324 "hostname",
9325 path->peer->hostname);
9326
9327 json_object_string_add(json_nexthop_global, "afi",
9328 "ipv6");
9329 json_object_string_add(json_nexthop_global, "scope",
9330 "global");
9331
9332 /* We display both LL & GL if both have been
9333 * received */
9334 if ((attr->mp_nexthop_len
9335 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9336 || (path->peer->conf_if)) {
9337 json_nexthop_ll = json_object_new_object();
9338 json_object_string_addf(
9339 json_nexthop_ll, "ip", "%pI6",
9340 &attr->mp_nexthop_local);
9341
9342 if (path->peer->hostname)
9343 json_object_string_add(
9344 json_nexthop_ll, "hostname",
9345 path->peer->hostname);
9346
9347 json_object_string_add(json_nexthop_ll, "afi",
9348 "ipv6");
9349 json_object_string_add(json_nexthop_ll, "scope",
9350 "link-local");
9351
9352 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9353 &attr->mp_nexthop_local)
9354 != 0)
9355 && !attr->mp_nexthop_prefer_global)
9356 json_object_boolean_true_add(
9357 json_nexthop_ll, "used");
9358 else
9359 json_object_boolean_true_add(
9360 json_nexthop_global, "used");
9361 } else
9362 json_object_boolean_true_add(
9363 json_nexthop_global, "used");
9364 } else {
9365 /* Display LL if LL/Global both in table unless
9366 * prefer-global is set */
9367 if (((attr->mp_nexthop_len
9368 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9369 && !attr->mp_nexthop_prefer_global)
9370 || (path->peer->conf_if)) {
9371 if (path->peer->conf_if) {
9372 len = vty_out(vty, "%s",
9373 path->peer->conf_if);
9374 /* len of IPv6 addr + max len of def
9375 * ifname */
9376 len = wide ? (41 - len) : (16 - len);
9377
9378 if (len < 1)
9379 vty_out(vty, "\n%*s", 36, " ");
9380 else
9381 vty_out(vty, "%*s", len, " ");
9382 } else {
9383 if (nexthop_hostname)
9384 len = vty_out(
9385 vty, "%pI6(%s)%s",
9386 &attr->mp_nexthop_local,
9387 nexthop_hostname,
9388 vrf_id_str);
9389 else
9390 len = vty_out(
9391 vty, "%pI6%s",
9392 &attr->mp_nexthop_local,
9393 vrf_id_str);
9394
9395 len = wide ? (41 - len) : (16 - len);
9396
9397 if (len < 1)
9398 vty_out(vty, "\n%*s", 36, " ");
9399 else
9400 vty_out(vty, "%*s", len, " ");
9401 }
9402 } else {
9403 if (nexthop_hostname)
9404 len = vty_out(vty, "%pI6(%s)%s",
9405 &attr->mp_nexthop_global,
9406 nexthop_hostname,
9407 vrf_id_str);
9408 else
9409 len = vty_out(vty, "%pI6%s",
9410 &attr->mp_nexthop_global,
9411 vrf_id_str);
9412
9413 len = wide ? (41 - len) : (16 - len);
9414
9415 if (len < 1)
9416 vty_out(vty, "\n%*s", 36, " ");
9417 else
9418 vty_out(vty, "%*s", len, " ");
9419 }
9420 }
9421 }
9422
9423 /* MED/Metric */
9424 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9425 if (json_paths)
9426 json_object_int_add(json_path, "metric", attr->med);
9427 else if (wide)
9428 vty_out(vty, "%7u", attr->med);
9429 else
9430 vty_out(vty, "%10u", attr->med);
9431 else if (!json_paths) {
9432 if (wide)
9433 vty_out(vty, "%*s", 7, " ");
9434 else
9435 vty_out(vty, "%*s", 10, " ");
9436 }
9437
9438 /* Local Pref */
9439 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9440 if (json_paths)
9441 json_object_int_add(json_path, "locPrf",
9442 attr->local_pref);
9443 else
9444 vty_out(vty, "%7u", attr->local_pref);
9445 else if (!json_paths)
9446 vty_out(vty, " ");
9447
9448 if (json_paths)
9449 json_object_int_add(json_path, "weight", attr->weight);
9450 else
9451 vty_out(vty, "%7u ", attr->weight);
9452
9453 if (json_paths)
9454 json_object_string_addf(json_path, "peerId", "%pSU",
9455 &path->peer->su);
9456
9457 /* Print aspath */
9458 if (attr->aspath) {
9459 if (json_paths)
9460 json_object_string_add(json_path, "path",
9461 attr->aspath->str);
9462 else
9463 aspath_print_vty(vty, "%s", attr->aspath, " ");
9464 }
9465
9466 /* Print origin */
9467 if (json_paths)
9468 json_object_string_add(json_path, "origin",
9469 bgp_origin_long_str[attr->origin]);
9470 else
9471 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9472
9473 if (json_paths) {
9474 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9475 json_object_string_add(json_path, "esi",
9476 esi_to_str(&attr->esi,
9477 esi_buf, sizeof(esi_buf)));
9478 }
9479 if (safi == SAFI_EVPN &&
9480 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9481 json_ext_community = json_object_new_object();
9482 json_object_string_add(
9483 json_ext_community, "string",
9484 bgp_attr_get_ecommunity(attr)->str);
9485 json_object_object_add(json_path,
9486 "extendedCommunity",
9487 json_ext_community);
9488 }
9489
9490 if (nexthop_self)
9491 json_object_boolean_true_add(json_path,
9492 "announceNexthopSelf");
9493 if (nexthop_othervrf) {
9494 json_object_string_add(json_path, "nhVrfName",
9495 nexthop_vrfname);
9496
9497 json_object_int_add(json_path, "nhVrfId",
9498 ((nexthop_vrfid == VRF_UNKNOWN)
9499 ? -1
9500 : (int)nexthop_vrfid));
9501 }
9502 }
9503
9504 if (json_paths) {
9505 if (json_nexthop_global || json_nexthop_ll) {
9506 json_nexthops = json_object_new_array();
9507
9508 if (json_nexthop_global)
9509 json_object_array_add(json_nexthops,
9510 json_nexthop_global);
9511
9512 if (json_nexthop_ll)
9513 json_object_array_add(json_nexthops,
9514 json_nexthop_ll);
9515
9516 json_object_object_add(json_path, "nexthops",
9517 json_nexthops);
9518 }
9519
9520 json_object_array_add(json_paths, json_path);
9521 } else {
9522 vty_out(vty, "\n");
9523
9524 if (safi == SAFI_EVPN) {
9525 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9526 /* XXX - add these params to the json out */
9527 vty_out(vty, "%*s", 20, " ");
9528 vty_out(vty, "ESI:%s",
9529 esi_to_str(&attr->esi, esi_buf,
9530 sizeof(esi_buf)));
9531
9532 vty_out(vty, "\n");
9533 }
9534 if (attr->flag &
9535 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9536 vty_out(vty, "%*s", 20, " ");
9537 vty_out(vty, "%s\n",
9538 bgp_attr_get_ecommunity(attr)->str);
9539 }
9540 }
9541
9542 #ifdef ENABLE_BGP_VNC
9543 /* prints an additional line, indented, with VNC info, if
9544 * present */
9545 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9546 rfapi_vty_out_vncinfo(vty, p, path, safi);
9547 #endif
9548 }
9549 }
9550
9551 /* called from terminal list command */
9552 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9553 const struct prefix *p, struct attr *attr, safi_t safi,
9554 bool use_json, json_object *json_ar, bool wide)
9555 {
9556 json_object *json_status = NULL;
9557 json_object *json_net = NULL;
9558 int len;
9559 char buff[BUFSIZ];
9560
9561 /* Route status display. */
9562 if (use_json) {
9563 json_status = json_object_new_object();
9564 json_net = json_object_new_object();
9565 } else {
9566 vty_out(vty, "*");
9567 vty_out(vty, ">");
9568 vty_out(vty, " ");
9569 }
9570
9571 /* print prefix and mask */
9572 if (use_json) {
9573 if (safi == SAFI_EVPN)
9574 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9575 else if (p->family == AF_INET || p->family == AF_INET6) {
9576 json_object_string_add(
9577 json_net, "addrPrefix",
9578 inet_ntop(p->family, &p->u.prefix, buff,
9579 BUFSIZ));
9580 json_object_int_add(json_net, "prefixLen",
9581 p->prefixlen);
9582 json_object_string_addf(json_net, "network", "%pFX", p);
9583 }
9584 } else
9585 route_vty_out_route(dest, p, vty, NULL, wide);
9586
9587 /* Print attribute */
9588 if (attr) {
9589 if (use_json) {
9590 if (p->family == AF_INET &&
9591 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9592 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9593 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9594 json_object_string_addf(
9595 json_net, "nextHop", "%pI4",
9596 &attr->mp_nexthop_global_in);
9597 else
9598 json_object_string_addf(
9599 json_net, "nextHop", "%pI4",
9600 &attr->nexthop);
9601 } else if (p->family == AF_INET6 ||
9602 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9603 json_object_string_addf(
9604 json_net, "nextHopGlobal", "%pI6",
9605 &attr->mp_nexthop_global);
9606 } else if (p->family == AF_EVPN &&
9607 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9608 json_object_string_addf(
9609 json_net, "nextHop", "%pI4",
9610 &attr->mp_nexthop_global_in);
9611 }
9612
9613 if (attr->flag
9614 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9615 json_object_int_add(json_net, "metric",
9616 attr->med);
9617
9618 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9619 json_object_int_add(json_net, "locPrf",
9620 attr->local_pref);
9621
9622 json_object_int_add(json_net, "weight", attr->weight);
9623
9624 /* Print aspath */
9625 if (attr->aspath)
9626 json_object_string_add(json_net, "path",
9627 attr->aspath->str);
9628
9629 /* Print origin */
9630 json_object_string_add(json_net, "bgpOriginCode",
9631 bgp_origin_str[attr->origin]);
9632 } else {
9633 if (p->family == AF_INET &&
9634 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9635 safi == SAFI_EVPN ||
9636 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9637 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9638 || safi == SAFI_EVPN)
9639 vty_out(vty, "%-16pI4",
9640 &attr->mp_nexthop_global_in);
9641 else if (wide)
9642 vty_out(vty, "%-41pI4", &attr->nexthop);
9643 else
9644 vty_out(vty, "%-16pI4", &attr->nexthop);
9645 } else if (p->family == AF_INET6 ||
9646 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9647 char buf[BUFSIZ];
9648
9649 len = vty_out(
9650 vty, "%s",
9651 inet_ntop(AF_INET6,
9652 &attr->mp_nexthop_global, buf,
9653 BUFSIZ));
9654 len = wide ? (41 - len) : (16 - len);
9655 if (len < 1)
9656 vty_out(vty, "\n%*s", 36, " ");
9657 else
9658 vty_out(vty, "%*s", len, " ");
9659 }
9660 if (attr->flag
9661 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9662 if (wide)
9663 vty_out(vty, "%7u", attr->med);
9664 else
9665 vty_out(vty, "%10u", attr->med);
9666 else if (wide)
9667 vty_out(vty, " ");
9668 else
9669 vty_out(vty, " ");
9670
9671 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9672 vty_out(vty, "%7u", attr->local_pref);
9673 else
9674 vty_out(vty, " ");
9675
9676 vty_out(vty, "%7u ", attr->weight);
9677
9678 /* Print aspath */
9679 if (attr->aspath)
9680 aspath_print_vty(vty, "%s", attr->aspath, " ");
9681
9682 /* Print origin */
9683 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9684 }
9685 }
9686 if (use_json) {
9687 json_object_boolean_true_add(json_status, "*");
9688 json_object_boolean_true_add(json_status, ">");
9689 json_object_object_add(json_net, "appliedStatusSymbols",
9690 json_status);
9691 json_object_object_addf(json_ar, json_net, "%pFX", p);
9692 } else
9693 vty_out(vty, "\n");
9694 }
9695
9696 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9697 struct bgp_path_info *path, int display, safi_t safi,
9698 json_object *json)
9699 {
9700 json_object *json_out = NULL;
9701 struct attr *attr;
9702 mpls_label_t label = MPLS_INVALID_LABEL;
9703
9704 if (!path->extra)
9705 return;
9706
9707 if (json)
9708 json_out = json_object_new_object();
9709
9710 /* short status lead text */
9711 route_vty_short_status_out(vty, path, p, json_out);
9712
9713 /* print prefix and mask */
9714 if (json == NULL) {
9715 if (!display)
9716 route_vty_out_route(path->net, p, vty, NULL, false);
9717 else
9718 vty_out(vty, "%*s", 17, " ");
9719 }
9720
9721 /* Print attribute */
9722 attr = path->attr;
9723 if (((p->family == AF_INET) &&
9724 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9725 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9726 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9727 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9728 || safi == SAFI_EVPN) {
9729 if (json)
9730 json_object_string_addf(
9731 json_out, "mpNexthopGlobalIn", "%pI4",
9732 &attr->mp_nexthop_global_in);
9733 else
9734 vty_out(vty, "%-16pI4",
9735 &attr->mp_nexthop_global_in);
9736 } else {
9737 if (json)
9738 json_object_string_addf(json_out, "nexthop",
9739 "%pI4", &attr->nexthop);
9740 else
9741 vty_out(vty, "%-16pI4", &attr->nexthop);
9742 }
9743 } else if (((p->family == AF_INET6) &&
9744 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9745 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9746 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9747 char buf_a[512];
9748
9749 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9750 if (json)
9751 json_object_string_addf(
9752 json_out, "mpNexthopGlobalIn", "%pI6",
9753 &attr->mp_nexthop_global);
9754 else
9755 vty_out(vty, "%s",
9756 inet_ntop(AF_INET6,
9757 &attr->mp_nexthop_global,
9758 buf_a, sizeof(buf_a)));
9759 } else if (attr->mp_nexthop_len
9760 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9761 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9762 &attr->mp_nexthop_global,
9763 &attr->mp_nexthop_local);
9764 if (json)
9765 json_object_string_add(json_out,
9766 "mpNexthopGlobalLocal",
9767 buf_a);
9768 else
9769 vty_out(vty, "%s", buf_a);
9770 }
9771 }
9772
9773 label = decode_label(&path->extra->label[0]);
9774
9775 if (bgp_is_valid_label(&label)) {
9776 if (json) {
9777 json_object_int_add(json_out, "notag", label);
9778 json_object_array_add(json, json_out);
9779 } else {
9780 vty_out(vty, "notag/%d", label);
9781 vty_out(vty, "\n");
9782 }
9783 } else if (!json)
9784 vty_out(vty, "\n");
9785 }
9786
9787 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9788 struct bgp_path_info *path, int display,
9789 json_object *json_paths)
9790 {
9791 struct attr *attr;
9792 json_object *json_path = NULL;
9793 json_object *json_nexthop = NULL;
9794 json_object *json_overlay = NULL;
9795
9796 if (!path->extra)
9797 return;
9798
9799 if (json_paths) {
9800 json_path = json_object_new_object();
9801 json_overlay = json_object_new_object();
9802 json_nexthop = json_object_new_object();
9803 }
9804
9805 /* short status lead text */
9806 route_vty_short_status_out(vty, path, p, json_path);
9807
9808 /* print prefix and mask */
9809 if (!display)
9810 route_vty_out_route(path->net, p, vty, json_path, false);
9811 else
9812 vty_out(vty, "%*s", 17, " ");
9813
9814 /* Print attribute */
9815 attr = path->attr;
9816 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9817
9818 switch (af) {
9819 case AF_INET:
9820 if (!json_path) {
9821 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9822 } else {
9823 json_object_string_addf(json_nexthop, "ip", "%pI4",
9824 &attr->mp_nexthop_global_in);
9825
9826 json_object_string_add(json_nexthop, "afi", "ipv4");
9827
9828 json_object_object_add(json_path, "nexthop",
9829 json_nexthop);
9830 }
9831 break;
9832 case AF_INET6:
9833 if (!json_path) {
9834 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9835 &attr->mp_nexthop_local);
9836 } else {
9837 json_object_string_addf(json_nexthop, "ipv6Global",
9838 "%pI6",
9839 &attr->mp_nexthop_global);
9840
9841 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9842 "%pI6",
9843 &attr->mp_nexthop_local);
9844
9845 json_object_string_add(json_nexthop, "afi", "ipv6");
9846
9847 json_object_object_add(json_path, "nexthop",
9848 json_nexthop);
9849 }
9850 break;
9851 default:
9852 if (!json_path) {
9853 vty_out(vty, "?");
9854 } else {
9855 json_object_string_add(json_nexthop, "Error",
9856 "Unsupported address-family");
9857 json_object_string_add(json_nexthop, "error",
9858 "Unsupported address-family");
9859 }
9860 }
9861
9862 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9863
9864 if (!json_path)
9865 vty_out(vty, "/%pIA", &eo->gw_ip);
9866 else
9867 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9868
9869 if (bgp_attr_get_ecommunity(attr)) {
9870 char *mac = NULL;
9871 struct ecommunity_val *routermac = ecommunity_lookup(
9872 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9873 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9874
9875 if (routermac)
9876 mac = ecom_mac2str((char *)routermac->val);
9877 if (mac) {
9878 if (!json_path) {
9879 vty_out(vty, "/%s", mac);
9880 } else {
9881 json_object_string_add(json_overlay, "rmac",
9882 mac);
9883 }
9884 XFREE(MTYPE_TMP, mac);
9885 }
9886 }
9887
9888 if (!json_path) {
9889 vty_out(vty, "\n");
9890 } else {
9891 json_object_object_add(json_path, "overlay", json_overlay);
9892
9893 json_object_array_add(json_paths, json_path);
9894 }
9895 }
9896
9897 /* dampening route */
9898 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9899 struct bgp_path_info *path, int display,
9900 afi_t afi, safi_t safi, bool use_json,
9901 json_object *json_paths)
9902 {
9903 struct attr *attr = path->attr;
9904 int len;
9905 char timebuf[BGP_UPTIME_LEN];
9906 json_object *json_path = NULL;
9907
9908 if (use_json)
9909 json_path = json_object_new_object();
9910
9911 /* short status lead text */
9912 route_vty_short_status_out(vty, path, p, json_path);
9913
9914 /* print prefix and mask */
9915 if (!use_json) {
9916 if (!display)
9917 route_vty_out_route(path->net, p, vty, NULL, false);
9918 else
9919 vty_out(vty, "%*s", 17, " ");
9920
9921 len = vty_out(vty, "%s", path->peer->host);
9922 len = 17 - len;
9923
9924 if (len < 1)
9925 vty_out(vty, "\n%*s", 34, " ");
9926 else
9927 vty_out(vty, "%*s", len, " ");
9928
9929 vty_out(vty, "%s ",
9930 bgp_damp_reuse_time_vty(vty, path, timebuf,
9931 BGP_UPTIME_LEN, afi, safi,
9932 use_json, NULL));
9933
9934 if (attr->aspath)
9935 aspath_print_vty(vty, "%s", attr->aspath, " ");
9936
9937 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9938
9939 vty_out(vty, "\n");
9940 } else {
9941 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9942 safi, use_json, json_path);
9943
9944 if (attr->aspath)
9945 json_object_string_add(json_path, "asPath",
9946 attr->aspath->str);
9947
9948 json_object_string_add(json_path, "origin",
9949 bgp_origin_str[attr->origin]);
9950 json_object_string_add(json_path, "peerHost", path->peer->host);
9951
9952 json_object_array_add(json_paths, json_path);
9953 }
9954 }
9955
9956 /* flap route */
9957 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9958 struct bgp_path_info *path, int display,
9959 afi_t afi, safi_t safi, bool use_json,
9960 json_object *json_paths)
9961 {
9962 struct attr *attr = path->attr;
9963 struct bgp_damp_info *bdi;
9964 char timebuf[BGP_UPTIME_LEN];
9965 int len;
9966 json_object *json_path = NULL;
9967
9968 if (!path->extra)
9969 return;
9970
9971 if (use_json)
9972 json_path = json_object_new_object();
9973
9974 bdi = path->extra->damp_info;
9975
9976 /* short status lead text */
9977 route_vty_short_status_out(vty, path, p, json_path);
9978
9979 if (!use_json) {
9980 if (!display)
9981 route_vty_out_route(path->net, p, vty, NULL, false);
9982 else
9983 vty_out(vty, "%*s", 17, " ");
9984
9985 len = vty_out(vty, "%s", path->peer->host);
9986 len = 16 - len;
9987 if (len < 1)
9988 vty_out(vty, "\n%*s", 33, " ");
9989 else
9990 vty_out(vty, "%*s", len, " ");
9991
9992 len = vty_out(vty, "%d", bdi->flap);
9993 len = 5 - len;
9994 if (len < 1)
9995 vty_out(vty, " ");
9996 else
9997 vty_out(vty, "%*s", len, " ");
9998
9999 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10000 BGP_UPTIME_LEN, 0, NULL));
10001
10002 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10003 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10004 vty_out(vty, "%s ",
10005 bgp_damp_reuse_time_vty(vty, path, timebuf,
10006 BGP_UPTIME_LEN, afi,
10007 safi, use_json, NULL));
10008 else
10009 vty_out(vty, "%*s ", 8, " ");
10010
10011 if (attr->aspath)
10012 aspath_print_vty(vty, "%s", attr->aspath, " ");
10013
10014 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10015
10016 vty_out(vty, "\n");
10017 } else {
10018 json_object_string_add(json_path, "peerHost", path->peer->host);
10019 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10020
10021 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10022 json_path);
10023
10024 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10025 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10026 bgp_damp_reuse_time_vty(vty, path, timebuf,
10027 BGP_UPTIME_LEN, afi, safi,
10028 use_json, json_path);
10029
10030 if (attr->aspath)
10031 json_object_string_add(json_path, "asPath",
10032 attr->aspath->str);
10033
10034 json_object_string_add(json_path, "origin",
10035 bgp_origin_str[attr->origin]);
10036
10037 json_object_array_add(json_paths, json_path);
10038 }
10039 }
10040
10041 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10042 int *first, const char *header,
10043 json_object *json_adv_to)
10044 {
10045 json_object *json_peer = NULL;
10046
10047 if (json_adv_to) {
10048 /* 'advertised-to' is a dictionary of peers we have advertised
10049 * this
10050 * prefix too. The key is the peer's IP or swpX, the value is
10051 * the
10052 * hostname if we know it and "" if not.
10053 */
10054 json_peer = json_object_new_object();
10055
10056 if (peer->hostname)
10057 json_object_string_add(json_peer, "hostname",
10058 peer->hostname);
10059
10060 if (peer->conf_if)
10061 json_object_object_add(json_adv_to, peer->conf_if,
10062 json_peer);
10063 else
10064 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10065 &peer->su);
10066 } else {
10067 if (*first) {
10068 vty_out(vty, "%s", header);
10069 *first = 0;
10070 }
10071
10072 if (peer->hostname
10073 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10074 if (peer->conf_if)
10075 vty_out(vty, " %s(%s)", peer->hostname,
10076 peer->conf_if);
10077 else
10078 vty_out(vty, " %s(%pSU)", peer->hostname,
10079 &peer->su);
10080 } else {
10081 if (peer->conf_if)
10082 vty_out(vty, " %s", peer->conf_if);
10083 else
10084 vty_out(vty, " %pSU", &peer->su);
10085 }
10086 }
10087 }
10088
10089 static void route_vty_out_tx_ids(struct vty *vty,
10090 struct bgp_addpath_info_data *d)
10091 {
10092 int i;
10093
10094 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10095 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10096 d->addpath_tx_id[i],
10097 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10098 }
10099 }
10100
10101 static void route_vty_out_detail_es_info(struct vty *vty,
10102 struct bgp_path_info *pi,
10103 struct attr *attr,
10104 json_object *json_path)
10105 {
10106 char esi_buf[ESI_STR_LEN];
10107 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10108 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10109 ATTR_ES_PEER_ROUTER);
10110 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10111 ATTR_ES_PEER_ACTIVE);
10112 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10113 ATTR_ES_PEER_PROXY);
10114 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10115 if (json_path) {
10116 json_object *json_es_info = NULL;
10117
10118 json_object_string_add(
10119 json_path, "esi",
10120 esi_buf);
10121 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10122 json_es_info = json_object_new_object();
10123 if (es_local)
10124 json_object_boolean_true_add(
10125 json_es_info, "localEs");
10126 if (peer_active)
10127 json_object_boolean_true_add(
10128 json_es_info, "peerActive");
10129 if (peer_proxy)
10130 json_object_boolean_true_add(
10131 json_es_info, "peerProxy");
10132 if (peer_router)
10133 json_object_boolean_true_add(
10134 json_es_info, "peerRouter");
10135 if (attr->mm_sync_seqnum)
10136 json_object_int_add(
10137 json_es_info, "peerSeq",
10138 attr->mm_sync_seqnum);
10139 json_object_object_add(
10140 json_path, "es_info",
10141 json_es_info);
10142 }
10143 } else {
10144 if (bgp_evpn_attr_is_sync(attr))
10145 vty_out(vty,
10146 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10147 esi_buf,
10148 es_local ? "local-es":"",
10149 peer_proxy ? "proxy " : "",
10150 peer_active ? "active ":"",
10151 peer_router ? "router ":"",
10152 attr->mm_sync_seqnum);
10153 else
10154 vty_out(vty, " ESI %s %s\n",
10155 esi_buf,
10156 es_local ? "local-es":"");
10157 }
10158 }
10159
10160 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10161 struct bgp_path_info *path, afi_t afi, safi_t safi,
10162 enum rpki_states rpki_curr_state,
10163 json_object *json_paths)
10164 {
10165 char buf[INET6_ADDRSTRLEN];
10166 char buf1[BUFSIZ];
10167 struct attr *attr = path->attr;
10168 time_t tbuf;
10169 json_object *json_bestpath = NULL;
10170 json_object *json_cluster_list = NULL;
10171 json_object *json_cluster_list_list = NULL;
10172 json_object *json_ext_community = NULL;
10173 json_object *json_last_update = NULL;
10174 json_object *json_pmsi = NULL;
10175 json_object *json_nexthop_global = NULL;
10176 json_object *json_nexthop_ll = NULL;
10177 json_object *json_nexthops = NULL;
10178 json_object *json_path = NULL;
10179 json_object *json_peer = NULL;
10180 json_object *json_string = NULL;
10181 json_object *json_adv_to = NULL;
10182 int first = 0;
10183 struct listnode *node, *nnode;
10184 struct peer *peer;
10185 bool addpath_capable;
10186 int has_adj;
10187 unsigned int first_as;
10188 bool nexthop_self =
10189 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10190 int i;
10191 char *nexthop_hostname =
10192 bgp_nexthop_hostname(path->peer, path->nexthop);
10193 uint32_t ttl = 0;
10194 uint32_t bos = 0;
10195 uint32_t exp = 0;
10196 mpls_label_t label = MPLS_INVALID_LABEL;
10197
10198 if (json_paths) {
10199 json_path = json_object_new_object();
10200 json_peer = json_object_new_object();
10201 json_nexthop_global = json_object_new_object();
10202 }
10203
10204 if (safi == SAFI_EVPN) {
10205 if (!json_paths)
10206 vty_out(vty, " Route %pRN", bn);
10207 }
10208
10209 if (path->extra) {
10210 char tag_buf[30];
10211
10212 tag_buf[0] = '\0';
10213 if (path->extra && path->extra->num_labels) {
10214 bgp_evpn_label2str(path->extra->label,
10215 path->extra->num_labels, tag_buf,
10216 sizeof(tag_buf));
10217 }
10218 if (safi == SAFI_EVPN) {
10219 if (!json_paths) {
10220 if (tag_buf[0] != '\0')
10221 vty_out(vty, " VNI %s", tag_buf);
10222 } else {
10223 if (tag_buf[0]) {
10224 json_object_string_add(json_path, "VNI",
10225 tag_buf);
10226 json_object_string_add(json_path, "vni",
10227 tag_buf);
10228 }
10229 }
10230 }
10231
10232 if (path->extra && path->extra->parent && !json_paths) {
10233 struct bgp_path_info *parent_ri;
10234 struct bgp_dest *dest, *pdest;
10235
10236 parent_ri = (struct bgp_path_info *)path->extra->parent;
10237 dest = parent_ri->net;
10238 if (dest && dest->pdest) {
10239 pdest = dest->pdest;
10240 if (is_pi_family_evpn(parent_ri)) {
10241 vty_out(vty,
10242 " Imported from %pRD:%pFX, VNI %s",
10243 (struct prefix_rd *)
10244 bgp_dest_get_prefix(
10245 pdest),
10246 (struct prefix_evpn *)
10247 bgp_dest_get_prefix(
10248 dest),
10249 tag_buf);
10250 if (attr->es_flags & ATTR_ES_L3_NHG)
10251 vty_out(vty, ", L3NHG %s",
10252 (attr->es_flags
10253 & ATTR_ES_L3_NHG_ACTIVE)
10254 ? "active"
10255 : "inactive");
10256 vty_out(vty, "\n");
10257
10258 } else
10259 vty_out(vty,
10260 " Imported from %pRD:%pFX\n",
10261 (struct prefix_rd *)
10262 bgp_dest_get_prefix(
10263 pdest),
10264 (struct prefix_evpn *)
10265 bgp_dest_get_prefix(
10266 dest));
10267 }
10268 }
10269 }
10270
10271 if (safi == SAFI_EVPN
10272 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10273 char gwip_buf[INET6_ADDRSTRLEN];
10274
10275 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10276 sizeof(gwip_buf));
10277
10278 if (json_paths)
10279 json_object_string_add(json_path, "gatewayIP",
10280 gwip_buf);
10281 else
10282 vty_out(vty, " Gateway IP %s", gwip_buf);
10283 }
10284
10285 if (safi == SAFI_EVPN && !json_path)
10286 vty_out(vty, "\n");
10287
10288 /* Line1 display AS-path, Aggregator */
10289 if (attr->aspath) {
10290 if (json_paths) {
10291 if (!attr->aspath->json)
10292 aspath_str_update(attr->aspath, true);
10293 json_object_lock(attr->aspath->json);
10294 json_object_object_add(json_path, "aspath",
10295 attr->aspath->json);
10296 } else {
10297 if (attr->aspath->segments)
10298 aspath_print_vty(vty, " %s", attr->aspath, "");
10299 else
10300 vty_out(vty, " Local");
10301 }
10302 }
10303
10304 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10305 if (json_paths)
10306 json_object_boolean_true_add(json_path, "removed");
10307 else
10308 vty_out(vty, ", (removed)");
10309 }
10310
10311 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10312 if (json_paths)
10313 json_object_boolean_true_add(json_path, "stale");
10314 else
10315 vty_out(vty, ", (stale)");
10316 }
10317
10318 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10319 if (json_paths) {
10320 json_object_int_add(json_path, "aggregatorAs",
10321 attr->aggregator_as);
10322 json_object_string_addf(json_path, "aggregatorId",
10323 "%pI4", &attr->aggregator_addr);
10324 } else {
10325 vty_out(vty, ", (aggregated by %u %pI4)",
10326 attr->aggregator_as, &attr->aggregator_addr);
10327 }
10328 }
10329
10330 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10331 PEER_FLAG_REFLECTOR_CLIENT)) {
10332 if (json_paths)
10333 json_object_boolean_true_add(json_path,
10334 "rxedFromRrClient");
10335 else
10336 vty_out(vty, ", (Received from a RR-client)");
10337 }
10338
10339 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10340 PEER_FLAG_RSERVER_CLIENT)) {
10341 if (json_paths)
10342 json_object_boolean_true_add(json_path,
10343 "rxedFromRsClient");
10344 else
10345 vty_out(vty, ", (Received from a RS-client)");
10346 }
10347
10348 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10349 if (json_paths)
10350 json_object_boolean_true_add(json_path,
10351 "dampeningHistoryEntry");
10352 else
10353 vty_out(vty, ", (history entry)");
10354 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10355 if (json_paths)
10356 json_object_boolean_true_add(json_path,
10357 "dampeningSuppressed");
10358 else
10359 vty_out(vty, ", (suppressed due to dampening)");
10360 }
10361
10362 if (!json_paths)
10363 vty_out(vty, "\n");
10364
10365 /* Line2 display Next-hop, Neighbor, Router-id */
10366 /* Display the nexthop */
10367 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10368
10369 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET ||
10370 bn_p->family == AF_EVPN) &&
10371 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10372 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10373 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10374 || safi == SAFI_EVPN) {
10375 if (json_paths) {
10376 json_object_string_addf(
10377 json_nexthop_global, "ip", "%pI4",
10378 &attr->mp_nexthop_global_in);
10379
10380 if (path->peer->hostname)
10381 json_object_string_add(
10382 json_nexthop_global, "hostname",
10383 path->peer->hostname);
10384 } else {
10385 if (nexthop_hostname)
10386 vty_out(vty, " %pI4(%s)",
10387 &attr->mp_nexthop_global_in,
10388 nexthop_hostname);
10389 else
10390 vty_out(vty, " %pI4",
10391 &attr->mp_nexthop_global_in);
10392 }
10393 } else {
10394 if (json_paths) {
10395 json_object_string_addf(json_nexthop_global,
10396 "ip", "%pI4",
10397 &attr->nexthop);
10398
10399 if (path->peer->hostname)
10400 json_object_string_add(
10401 json_nexthop_global, "hostname",
10402 path->peer->hostname);
10403 } else {
10404 if (nexthop_hostname)
10405 vty_out(vty, " %pI4(%s)",
10406 &attr->nexthop,
10407 nexthop_hostname);
10408 else
10409 vty_out(vty, " %pI4",
10410 &attr->nexthop);
10411 }
10412 }
10413
10414 if (json_paths)
10415 json_object_string_add(json_nexthop_global, "afi",
10416 "ipv4");
10417 } else {
10418 if (json_paths) {
10419 json_object_string_addf(json_nexthop_global, "ip",
10420 "%pI6",
10421 &attr->mp_nexthop_global);
10422
10423 if (path->peer->hostname)
10424 json_object_string_add(json_nexthop_global,
10425 "hostname",
10426 path->peer->hostname);
10427
10428 json_object_string_add(json_nexthop_global, "afi",
10429 "ipv6");
10430 json_object_string_add(json_nexthop_global, "scope",
10431 "global");
10432 } else {
10433 if (nexthop_hostname)
10434 vty_out(vty, " %pI6(%s)",
10435 &attr->mp_nexthop_global,
10436 nexthop_hostname);
10437 else
10438 vty_out(vty, " %pI6",
10439 &attr->mp_nexthop_global);
10440 }
10441 }
10442
10443 /* Display the IGP cost or 'inaccessible' */
10444 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10445 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10446
10447 if (json_paths) {
10448 json_object_boolean_false_add(json_nexthop_global,
10449 "accessible");
10450 json_object_boolean_add(json_nexthop_global,
10451 "importCheckEnabled", import);
10452 } else {
10453 vty_out(vty, " (inaccessible%s)",
10454 import ? ", import-check enabled" : "");
10455 }
10456 } else {
10457 if (path->extra && path->extra->igpmetric) {
10458 if (json_paths)
10459 json_object_int_add(json_nexthop_global,
10460 "metric",
10461 path->extra->igpmetric);
10462 else
10463 vty_out(vty, " (metric %u)",
10464 path->extra->igpmetric);
10465 }
10466
10467 /* IGP cost is 0, display this only for json */
10468 else {
10469 if (json_paths)
10470 json_object_int_add(json_nexthop_global,
10471 "metric", 0);
10472 }
10473
10474 if (json_paths)
10475 json_object_boolean_true_add(json_nexthop_global,
10476 "accessible");
10477 }
10478
10479 /* Display peer "from" output */
10480 /* This path was originated locally */
10481 if (path->peer == bgp->peer_self) {
10482
10483 if (safi == SAFI_EVPN || (bn_p->family == AF_INET &&
10484 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10485 if (json_paths)
10486 json_object_string_add(json_peer, "peerId",
10487 "0.0.0.0");
10488 else
10489 vty_out(vty, " from 0.0.0.0 ");
10490 } else {
10491 if (json_paths)
10492 json_object_string_add(json_peer, "peerId",
10493 "::");
10494 else
10495 vty_out(vty, " from :: ");
10496 }
10497
10498 if (json_paths)
10499 json_object_string_addf(json_peer, "routerId", "%pI4",
10500 &bgp->router_id);
10501 else
10502 vty_out(vty, "(%pI4)", &bgp->router_id);
10503 }
10504
10505 /* We RXed this path from one of our peers */
10506 else {
10507
10508 if (json_paths) {
10509 json_object_string_addf(json_peer, "peerId", "%pSU",
10510 &path->peer->su);
10511 json_object_string_addf(json_peer, "routerId", "%pI4",
10512 &path->peer->remote_id);
10513
10514 if (path->peer->hostname)
10515 json_object_string_add(json_peer, "hostname",
10516 path->peer->hostname);
10517
10518 if (path->peer->domainname)
10519 json_object_string_add(json_peer, "domainname",
10520 path->peer->domainname);
10521
10522 if (path->peer->conf_if)
10523 json_object_string_add(json_peer, "interface",
10524 path->peer->conf_if);
10525 } else {
10526 if (path->peer->conf_if) {
10527 if (path->peer->hostname
10528 && CHECK_FLAG(path->peer->bgp->flags,
10529 BGP_FLAG_SHOW_HOSTNAME))
10530 vty_out(vty, " from %s(%s)",
10531 path->peer->hostname,
10532 path->peer->conf_if);
10533 else
10534 vty_out(vty, " from %s",
10535 path->peer->conf_if);
10536 } else {
10537 if (path->peer->hostname
10538 && CHECK_FLAG(path->peer->bgp->flags,
10539 BGP_FLAG_SHOW_HOSTNAME))
10540 vty_out(vty, " from %s(%s)",
10541 path->peer->hostname,
10542 path->peer->host);
10543 else
10544 vty_out(vty, " from %pSU",
10545 &path->peer->su);
10546 }
10547
10548 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10549 vty_out(vty, " (%pI4)", &attr->originator_id);
10550 else
10551 vty_out(vty, " (%s)",
10552 inet_ntop(AF_INET,
10553 &path->peer->remote_id, buf1,
10554 sizeof(buf1)));
10555 }
10556 }
10557
10558 /*
10559 * Note when vrfid of nexthop is different from that of prefix
10560 */
10561 if (path->extra && path->extra->bgp_orig) {
10562 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10563
10564 if (json_paths) {
10565 const char *vn;
10566
10567 if (path->extra->bgp_orig->inst_type
10568 == BGP_INSTANCE_TYPE_DEFAULT)
10569 vn = VRF_DEFAULT_NAME;
10570 else
10571 vn = path->extra->bgp_orig->name;
10572
10573 json_object_string_add(json_path, "nhVrfName", vn);
10574
10575 if (nexthop_vrfid == VRF_UNKNOWN) {
10576 json_object_int_add(json_path, "nhVrfId", -1);
10577 } else {
10578 json_object_int_add(json_path, "nhVrfId",
10579 (int)nexthop_vrfid);
10580 }
10581 } else {
10582 if (nexthop_vrfid == VRF_UNKNOWN)
10583 vty_out(vty, " vrf ?");
10584 else {
10585 struct vrf *vrf;
10586
10587 vrf = vrf_lookup_by_id(nexthop_vrfid);
10588 vty_out(vty, " vrf %s(%u)",
10589 VRF_LOGNAME(vrf), nexthop_vrfid);
10590 }
10591 }
10592 }
10593
10594 if (nexthop_self) {
10595 if (json_paths) {
10596 json_object_boolean_true_add(json_path,
10597 "announceNexthopSelf");
10598 } else {
10599 vty_out(vty, " announce-nh-self");
10600 }
10601 }
10602
10603 if (!json_paths)
10604 vty_out(vty, "\n");
10605
10606 /* display the link-local nexthop */
10607 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10608 if (json_paths) {
10609 json_nexthop_ll = json_object_new_object();
10610 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10611 &attr->mp_nexthop_local);
10612
10613 if (path->peer->hostname)
10614 json_object_string_add(json_nexthop_ll,
10615 "hostname",
10616 path->peer->hostname);
10617
10618 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10619 json_object_string_add(json_nexthop_ll, "scope",
10620 "link-local");
10621
10622 json_object_boolean_true_add(json_nexthop_ll,
10623 "accessible");
10624
10625 if (!attr->mp_nexthop_prefer_global)
10626 json_object_boolean_true_add(json_nexthop_ll,
10627 "used");
10628 else
10629 json_object_boolean_true_add(
10630 json_nexthop_global, "used");
10631 } else {
10632 vty_out(vty, " (%s) %s\n",
10633 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10634 buf, INET6_ADDRSTRLEN),
10635 attr->mp_nexthop_prefer_global
10636 ? "(prefer-global)"
10637 : "(used)");
10638 }
10639 }
10640 /* If we do not have a link-local nexthop then we must flag the
10641 global as "used" */
10642 else {
10643 if (json_paths)
10644 json_object_boolean_true_add(json_nexthop_global,
10645 "used");
10646 }
10647
10648 if (safi == SAFI_EVPN &&
10649 bgp_evpn_is_esi_valid(&attr->esi)) {
10650 route_vty_out_detail_es_info(vty, path, attr, json_path);
10651 }
10652
10653 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10654 * Int/Ext/Local, Atomic, best */
10655 if (json_paths)
10656 json_object_string_add(json_path, "origin",
10657 bgp_origin_long_str[attr->origin]);
10658 else
10659 vty_out(vty, " Origin %s",
10660 bgp_origin_long_str[attr->origin]);
10661
10662 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10663 if (json_paths)
10664 json_object_int_add(json_path, "metric", attr->med);
10665 else
10666 vty_out(vty, ", metric %u", attr->med);
10667 }
10668
10669 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10670 if (json_paths)
10671 json_object_int_add(json_path, "locPrf",
10672 attr->local_pref);
10673 else
10674 vty_out(vty, ", localpref %u", attr->local_pref);
10675 }
10676
10677 if (attr->weight != 0) {
10678 if (json_paths)
10679 json_object_int_add(json_path, "weight", attr->weight);
10680 else
10681 vty_out(vty, ", weight %u", attr->weight);
10682 }
10683
10684 if (attr->tag != 0) {
10685 if (json_paths)
10686 json_object_int_add(json_path, "tag", attr->tag);
10687 else
10688 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10689 }
10690
10691 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10692 if (json_paths)
10693 json_object_boolean_false_add(json_path, "valid");
10694 else
10695 vty_out(vty, ", invalid");
10696 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10697 if (json_paths)
10698 json_object_boolean_true_add(json_path, "valid");
10699 else
10700 vty_out(vty, ", valid");
10701 }
10702
10703 if (json_paths)
10704 json_object_int_add(json_path, "version", bn->version);
10705
10706 if (path->peer != bgp->peer_self) {
10707 if (path->peer->as == path->peer->local_as) {
10708 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10709 if (json_paths)
10710 json_object_string_add(
10711 json_peer, "type",
10712 "confed-internal");
10713 else
10714 vty_out(vty, ", confed-internal");
10715 } else {
10716 if (json_paths)
10717 json_object_string_add(
10718 json_peer, "type", "internal");
10719 else
10720 vty_out(vty, ", internal");
10721 }
10722 } else {
10723 if (bgp_confederation_peers_check(bgp,
10724 path->peer->as)) {
10725 if (json_paths)
10726 json_object_string_add(
10727 json_peer, "type",
10728 "confed-external");
10729 else
10730 vty_out(vty, ", confed-external");
10731 } else {
10732 if (json_paths)
10733 json_object_string_add(
10734 json_peer, "type", "external");
10735 else
10736 vty_out(vty, ", external");
10737 }
10738 }
10739 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10740 if (json_paths) {
10741 json_object_boolean_true_add(json_path, "aggregated");
10742 json_object_boolean_true_add(json_path, "local");
10743 } else {
10744 vty_out(vty, ", aggregated, local");
10745 }
10746 } else if (path->type != ZEBRA_ROUTE_BGP) {
10747 if (json_paths)
10748 json_object_boolean_true_add(json_path, "sourced");
10749 else
10750 vty_out(vty, ", sourced");
10751 } else {
10752 if (json_paths) {
10753 json_object_boolean_true_add(json_path, "sourced");
10754 json_object_boolean_true_add(json_path, "local");
10755 } else {
10756 vty_out(vty, ", sourced, local");
10757 }
10758 }
10759
10760 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10761 if (json_paths)
10762 json_object_boolean_true_add(json_path,
10763 "atomicAggregate");
10764 else
10765 vty_out(vty, ", atomic-aggregate");
10766 }
10767
10768 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10769 if (json_paths)
10770 json_object_int_add(json_path, "otc", attr->otc);
10771 else
10772 vty_out(vty, ", otc %u", attr->otc);
10773 }
10774
10775 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10776 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10777 && bgp_path_info_mpath_count(path))) {
10778 if (json_paths)
10779 json_object_boolean_true_add(json_path, "multipath");
10780 else
10781 vty_out(vty, ", multipath");
10782 }
10783
10784 // Mark the bestpath(s)
10785 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10786 first_as = aspath_get_first_as(attr->aspath);
10787
10788 if (json_paths) {
10789 if (!json_bestpath)
10790 json_bestpath = json_object_new_object();
10791 json_object_int_add(json_bestpath, "bestpathFromAs",
10792 first_as);
10793 } else {
10794 if (first_as)
10795 vty_out(vty, ", bestpath-from-AS %u", first_as);
10796 else
10797 vty_out(vty, ", bestpath-from-AS Local");
10798 }
10799 }
10800
10801 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10802 if (json_paths) {
10803 if (!json_bestpath)
10804 json_bestpath = json_object_new_object();
10805 json_object_boolean_true_add(json_bestpath, "overall");
10806 json_object_string_add(
10807 json_bestpath, "selectionReason",
10808 bgp_path_selection_reason2str(bn->reason));
10809 } else {
10810 vty_out(vty, ", best");
10811 vty_out(vty, " (%s)",
10812 bgp_path_selection_reason2str(bn->reason));
10813 }
10814 }
10815
10816 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10817 if (json_paths)
10818 json_object_string_add(
10819 json_path, "rpkiValidationState",
10820 bgp_rpki_validation2str(rpki_curr_state));
10821 else
10822 vty_out(vty, ", rpki validation-state: %s",
10823 bgp_rpki_validation2str(rpki_curr_state));
10824 }
10825
10826 if (json_bestpath)
10827 json_object_object_add(json_path, "bestpath", json_bestpath);
10828
10829 if (!json_paths)
10830 vty_out(vty, "\n");
10831
10832 /* Line 4 display Community */
10833 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10834 if (json_paths) {
10835 if (!bgp_attr_get_community(attr)->json)
10836 community_str(bgp_attr_get_community(attr),
10837 true, true);
10838 json_object_lock(bgp_attr_get_community(attr)->json);
10839 json_object_object_add(
10840 json_path, "community",
10841 bgp_attr_get_community(attr)->json);
10842 } else {
10843 vty_out(vty, " Community: %s\n",
10844 bgp_attr_get_community(attr)->str);
10845 }
10846 }
10847
10848 /* Line 5 display Extended-community */
10849 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10850 if (json_paths) {
10851 json_ext_community = json_object_new_object();
10852 json_object_string_add(
10853 json_ext_community, "string",
10854 bgp_attr_get_ecommunity(attr)->str);
10855 json_object_object_add(json_path, "extendedCommunity",
10856 json_ext_community);
10857 } else {
10858 vty_out(vty, " Extended Community: %s\n",
10859 bgp_attr_get_ecommunity(attr)->str);
10860 }
10861 }
10862
10863 /* Line 6 display Large community */
10864 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10865 if (json_paths) {
10866 if (!bgp_attr_get_lcommunity(attr)->json)
10867 lcommunity_str(bgp_attr_get_lcommunity(attr),
10868 true, true);
10869 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10870 json_object_object_add(
10871 json_path, "largeCommunity",
10872 bgp_attr_get_lcommunity(attr)->json);
10873 } else {
10874 vty_out(vty, " Large Community: %s\n",
10875 bgp_attr_get_lcommunity(attr)->str);
10876 }
10877 }
10878
10879 /* Line 7 display Originator, Cluster-id */
10880 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10881 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10882 char buf[BUFSIZ] = {0};
10883
10884 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10885 if (json_paths)
10886 json_object_string_addf(json_path,
10887 "originatorId", "%pI4",
10888 &attr->originator_id);
10889 else
10890 vty_out(vty, " Originator: %pI4",
10891 &attr->originator_id);
10892 }
10893
10894 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10895 struct cluster_list *cluster =
10896 bgp_attr_get_cluster(attr);
10897 int i;
10898
10899 if (json_paths) {
10900 json_cluster_list = json_object_new_object();
10901 json_cluster_list_list =
10902 json_object_new_array();
10903
10904 for (i = 0; i < cluster->length / 4; i++) {
10905 json_string = json_object_new_string(
10906 inet_ntop(AF_INET,
10907 &cluster->list[i],
10908 buf, sizeof(buf)));
10909 json_object_array_add(
10910 json_cluster_list_list,
10911 json_string);
10912 }
10913
10914 /*
10915 * struct cluster_list does not have
10916 * "str" variable like aspath and community
10917 * do. Add this someday if someone asks
10918 * for it.
10919 * json_object_string_add(json_cluster_list,
10920 * "string", cluster->str);
10921 */
10922 json_object_object_add(json_cluster_list,
10923 "list",
10924 json_cluster_list_list);
10925 json_object_object_add(json_path, "clusterList",
10926 json_cluster_list);
10927 } else {
10928 vty_out(vty, ", Cluster list: ");
10929
10930 for (i = 0; i < cluster->length / 4; i++) {
10931 vty_out(vty, "%pI4 ",
10932 &cluster->list[i]);
10933 }
10934 }
10935 }
10936
10937 if (!json_paths)
10938 vty_out(vty, "\n");
10939 }
10940
10941 if (path->extra && path->extra->damp_info)
10942 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10943
10944 /* Remote Label */
10945 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10946 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10947 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10948 &bos);
10949
10950 if (json_paths)
10951 json_object_int_add(json_path, "remoteLabel", label);
10952 else
10953 vty_out(vty, " Remote label: %d\n", label);
10954 }
10955
10956 /* Remote SID */
10957 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10958 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
10959 if (json_paths)
10960 json_object_string_add(json_path, "remoteSid", buf);
10961 else
10962 vty_out(vty, " Remote SID: %s\n", buf);
10963 }
10964
10965 /* Label Index */
10966 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10967 if (json_paths)
10968 json_object_int_add(json_path, "labelIndex",
10969 attr->label_index);
10970 else
10971 vty_out(vty, " Label Index: %d\n",
10972 attr->label_index);
10973 }
10974
10975 /* Line 8 display Addpath IDs */
10976 if (path->addpath_rx_id
10977 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10978 if (json_paths) {
10979 json_object_int_add(json_path, "addpathRxId",
10980 path->addpath_rx_id);
10981
10982 /* Keep backwards compatibility with the old API
10983 * by putting TX All's ID in the old field
10984 */
10985 json_object_int_add(
10986 json_path, "addpathTxId",
10987 path->tx_addpath
10988 .addpath_tx_id[BGP_ADDPATH_ALL]);
10989
10990 /* ... but create a specific field for each
10991 * strategy
10992 */
10993 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10994 json_object_int_add(
10995 json_path,
10996 bgp_addpath_names(i)->id_json_name,
10997 path->tx_addpath.addpath_tx_id[i]);
10998 }
10999 } else {
11000 vty_out(vty, " AddPath ID: RX %u, ",
11001 path->addpath_rx_id);
11002
11003 route_vty_out_tx_ids(vty, &path->tx_addpath);
11004 }
11005 }
11006
11007 /* If we used addpath to TX a non-bestpath we need to display
11008 * "Advertised to" on a path-by-path basis
11009 */
11010 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11011 first = 1;
11012
11013 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11014 addpath_capable =
11015 bgp_addpath_encode_tx(peer, afi, safi);
11016 has_adj = bgp_adj_out_lookup(
11017 peer, path->net,
11018 bgp_addpath_id_for_peer(peer, afi, safi,
11019 &path->tx_addpath));
11020
11021 if ((addpath_capable && has_adj)
11022 || (!addpath_capable && has_adj
11023 && CHECK_FLAG(path->flags,
11024 BGP_PATH_SELECTED))) {
11025 if (json_path && !json_adv_to)
11026 json_adv_to = json_object_new_object();
11027
11028 route_vty_out_advertised_to(
11029 vty, peer, &first,
11030 " Advertised to:", json_adv_to);
11031 }
11032 }
11033
11034 if (json_path) {
11035 if (json_adv_to) {
11036 json_object_object_add(
11037 json_path, "advertisedTo", json_adv_to);
11038 }
11039 } else {
11040 if (!first) {
11041 vty_out(vty, "\n");
11042 }
11043 }
11044 }
11045
11046 /* Line 9 display Uptime */
11047 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11048 if (json_paths) {
11049 json_last_update = json_object_new_object();
11050 json_object_int_add(json_last_update, "epoch", tbuf);
11051 json_object_string_add(json_last_update, "string",
11052 ctime(&tbuf));
11053 json_object_object_add(json_path, "lastUpdate",
11054 json_last_update);
11055 } else
11056 vty_out(vty, " Last update: %s", ctime(&tbuf));
11057
11058 /* Line 10 display PMSI tunnel attribute, if present */
11059 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11060 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11061 bgp_attr_get_pmsi_tnl_type(attr),
11062 PMSI_TNLTYPE_STR_DEFAULT);
11063
11064 if (json_paths) {
11065 json_pmsi = json_object_new_object();
11066 json_object_string_add(json_pmsi, "tunnelType", str);
11067 json_object_int_add(json_pmsi, "label",
11068 label2vni(&attr->label));
11069 json_object_object_add(json_path, "pmsi", json_pmsi);
11070 } else
11071 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11072 str, label2vni(&attr->label));
11073 }
11074
11075 if (path->peer->t_gr_restart &&
11076 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11077 unsigned long gr_remaining =
11078 thread_timer_remain_second(path->peer->t_gr_restart);
11079
11080 if (json_paths) {
11081 json_object_int_add(json_path,
11082 "gracefulRestartSecondsRemaining",
11083 gr_remaining);
11084 } else
11085 vty_out(vty,
11086 " Time until Graceful Restart stale route deleted: %lu\n",
11087 gr_remaining);
11088 }
11089
11090 if (path->peer->t_llgr_stale[afi][safi] &&
11091 bgp_attr_get_community(attr) &&
11092 community_include(bgp_attr_get_community(attr),
11093 COMMUNITY_LLGR_STALE)) {
11094 unsigned long llgr_remaining = thread_timer_remain_second(
11095 path->peer->t_llgr_stale[afi][safi]);
11096
11097 if (json_paths) {
11098 json_object_int_add(json_path, "llgrSecondsRemaining",
11099 llgr_remaining);
11100 } else
11101 vty_out(vty,
11102 " Time until Long-lived stale route deleted: %lu\n",
11103 llgr_remaining);
11104 }
11105
11106 /* Output some debug about internal state of the dest flags */
11107 if (json_paths) {
11108 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11109 json_object_boolean_true_add(json_path, "processScheduled");
11110 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11111 json_object_boolean_true_add(json_path, "userCleared");
11112 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11113 json_object_boolean_true_add(json_path, "labelChanged");
11114 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11115 json_object_boolean_true_add(json_path, "registeredForLabel");
11116 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11117 json_object_boolean_true_add(json_path, "selectDefered");
11118 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11119 json_object_boolean_true_add(json_path, "fibInstalled");
11120 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11121 json_object_boolean_true_add(json_path, "fibPending");
11122
11123 if (json_nexthop_global || json_nexthop_ll) {
11124 json_nexthops = json_object_new_array();
11125
11126 if (json_nexthop_global)
11127 json_object_array_add(json_nexthops,
11128 json_nexthop_global);
11129
11130 if (json_nexthop_ll)
11131 json_object_array_add(json_nexthops,
11132 json_nexthop_ll);
11133
11134 json_object_object_add(json_path, "nexthops",
11135 json_nexthops);
11136 }
11137
11138 json_object_object_add(json_path, "peer", json_peer);
11139 json_object_array_add(json_paths, json_path);
11140 }
11141 }
11142
11143 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11144 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11145 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11146
11147 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11148 afi_t afi, safi_t safi, enum bgp_show_type type,
11149 bool use_json);
11150 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11151 const char *comstr, int exact, afi_t afi,
11152 safi_t safi, uint16_t show_flags);
11153
11154 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11155 struct bgp_table *table, enum bgp_show_type type,
11156 void *output_arg, const char *rd, int is_last,
11157 unsigned long *output_cum, unsigned long *total_cum,
11158 unsigned long *json_header_depth, uint16_t show_flags,
11159 enum rpki_states rpki_target_state)
11160 {
11161 struct bgp_path_info *pi;
11162 struct bgp_dest *dest;
11163 bool header = true;
11164 bool json_detail_header = false;
11165 int display;
11166 unsigned long output_count = 0;
11167 unsigned long total_count = 0;
11168 struct prefix *p;
11169 json_object *json_paths = NULL;
11170 int first = 1;
11171 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11172 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11173 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11174
11175 if (output_cum && *output_cum != 0)
11176 header = false;
11177
11178 if (use_json && !*json_header_depth) {
11179 if (all)
11180 *json_header_depth = 1;
11181 else {
11182 vty_out(vty, "{\n");
11183 *json_header_depth = 2;
11184 }
11185
11186 vty_out(vty,
11187 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11188 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11189 " \"localAS\": %u,\n \"routes\": { ",
11190 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11191 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11192 ? VRF_DEFAULT_NAME
11193 : bgp->name,
11194 table->version, &bgp->router_id,
11195 bgp->default_local_pref, bgp->as);
11196 if (rd) {
11197 vty_out(vty, " \"routeDistinguishers\" : {");
11198 ++*json_header_depth;
11199 }
11200 }
11201
11202 if (use_json && rd) {
11203 vty_out(vty, " \"%s\" : { ", rd);
11204 }
11205
11206 /* Check for 'json detail', where we need header output once per dest */
11207 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
11208 type != bgp_show_type_dampend_paths &&
11209 type != bgp_show_type_damp_neighbor &&
11210 type != bgp_show_type_flap_statistics &&
11211 type != bgp_show_type_flap_neighbor)
11212 json_detail_header = true;
11213
11214 /* Start processing of routes. */
11215 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11216 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11217 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11218 bool json_detail = json_detail_header;
11219
11220 pi = bgp_dest_get_bgp_path_info(dest);
11221 if (pi == NULL)
11222 continue;
11223
11224 display = 0;
11225 if (use_json)
11226 json_paths = json_object_new_array();
11227 else
11228 json_paths = NULL;
11229
11230 for (; pi; pi = pi->next) {
11231 struct community *picomm = NULL;
11232
11233 picomm = bgp_attr_get_community(pi->attr);
11234
11235 total_count++;
11236
11237 if (type == bgp_show_type_prefix_version) {
11238 uint32_t version =
11239 strtoul(output_arg, NULL, 10);
11240 if (dest->version < version)
11241 continue;
11242 }
11243
11244 if (type == bgp_show_type_community_alias) {
11245 char *alias = output_arg;
11246 char **communities;
11247 int num;
11248 bool found = false;
11249
11250 if (picomm) {
11251 frrstr_split(picomm->str, " ",
11252 &communities, &num);
11253 for (int i = 0; i < num; i++) {
11254 const char *com2alias =
11255 bgp_community2alias(
11256 communities[i]);
11257 if (!found
11258 && strcmp(alias, com2alias)
11259 == 0)
11260 found = true;
11261 XFREE(MTYPE_TMP,
11262 communities[i]);
11263 }
11264 XFREE(MTYPE_TMP, communities);
11265 }
11266
11267 if (!found &&
11268 bgp_attr_get_lcommunity(pi->attr)) {
11269 frrstr_split(bgp_attr_get_lcommunity(
11270 pi->attr)
11271 ->str,
11272 " ", &communities, &num);
11273 for (int i = 0; i < num; i++) {
11274 const char *com2alias =
11275 bgp_community2alias(
11276 communities[i]);
11277 if (!found
11278 && strcmp(alias, com2alias)
11279 == 0)
11280 found = true;
11281 XFREE(MTYPE_TMP,
11282 communities[i]);
11283 }
11284 XFREE(MTYPE_TMP, communities);
11285 }
11286
11287 if (!found)
11288 continue;
11289 }
11290
11291 if (type == bgp_show_type_rpki) {
11292 if (dest_p->family == AF_INET
11293 || dest_p->family == AF_INET6)
11294 rpki_curr_state = hook_call(
11295 bgp_rpki_prefix_status,
11296 pi->peer, pi->attr, dest_p);
11297 if (rpki_target_state != RPKI_NOT_BEING_USED
11298 && rpki_curr_state != rpki_target_state)
11299 continue;
11300 }
11301
11302 if (type == bgp_show_type_flap_statistics
11303 || type == bgp_show_type_flap_neighbor
11304 || type == bgp_show_type_dampend_paths
11305 || type == bgp_show_type_damp_neighbor) {
11306 if (!(pi->extra && pi->extra->damp_info))
11307 continue;
11308 }
11309 if (type == bgp_show_type_regexp) {
11310 regex_t *regex = output_arg;
11311
11312 if (bgp_regexec(regex, pi->attr->aspath)
11313 == REG_NOMATCH)
11314 continue;
11315 }
11316 if (type == bgp_show_type_prefix_list) {
11317 struct prefix_list *plist = output_arg;
11318
11319 if (prefix_list_apply(plist, dest_p)
11320 != PREFIX_PERMIT)
11321 continue;
11322 }
11323 if (type == bgp_show_type_access_list) {
11324 struct access_list *alist = output_arg;
11325
11326 if (access_list_apply(alist, dest_p) !=
11327 FILTER_PERMIT)
11328 continue;
11329 }
11330 if (type == bgp_show_type_filter_list) {
11331 struct as_list *as_list = output_arg;
11332
11333 if (as_list_apply(as_list, pi->attr->aspath)
11334 != AS_FILTER_PERMIT)
11335 continue;
11336 }
11337 if (type == bgp_show_type_route_map) {
11338 struct route_map *rmap = output_arg;
11339 struct bgp_path_info path;
11340 struct bgp_path_info_extra extra;
11341 struct attr dummy_attr = {};
11342 route_map_result_t ret;
11343
11344 dummy_attr = *pi->attr;
11345
11346 prep_for_rmap_apply(&path, &extra, dest, pi,
11347 pi->peer, &dummy_attr);
11348
11349 ret = route_map_apply(rmap, dest_p, &path);
11350 bgp_attr_flush(&dummy_attr);
11351 if (ret == RMAP_DENYMATCH)
11352 continue;
11353 }
11354 if (type == bgp_show_type_neighbor
11355 || type == bgp_show_type_flap_neighbor
11356 || type == bgp_show_type_damp_neighbor) {
11357 union sockunion *su = output_arg;
11358
11359 if (pi->peer == NULL
11360 || pi->peer->su_remote == NULL
11361 || !sockunion_same(pi->peer->su_remote, su))
11362 continue;
11363 }
11364 if (type == bgp_show_type_cidr_only) {
11365 uint32_t destination;
11366
11367 destination = ntohl(dest_p->u.prefix4.s_addr);
11368 if (IN_CLASSC(destination)
11369 && dest_p->prefixlen == 24)
11370 continue;
11371 if (IN_CLASSB(destination)
11372 && dest_p->prefixlen == 16)
11373 continue;
11374 if (IN_CLASSA(destination)
11375 && dest_p->prefixlen == 8)
11376 continue;
11377 }
11378 if (type == bgp_show_type_prefix_longer) {
11379 p = output_arg;
11380 if (!prefix_match(p, dest_p))
11381 continue;
11382 }
11383 if (type == bgp_show_type_community_all) {
11384 if (!picomm)
11385 continue;
11386 }
11387 if (type == bgp_show_type_community) {
11388 struct community *com = output_arg;
11389
11390 if (!picomm || !community_match(picomm, com))
11391 continue;
11392 }
11393 if (type == bgp_show_type_community_exact) {
11394 struct community *com = output_arg;
11395
11396 if (!picomm || !community_cmp(picomm, com))
11397 continue;
11398 }
11399 if (type == bgp_show_type_community_list) {
11400 struct community_list *list = output_arg;
11401
11402 if (!community_list_match(picomm, list))
11403 continue;
11404 }
11405 if (type == bgp_show_type_community_list_exact) {
11406 struct community_list *list = output_arg;
11407
11408 if (!community_list_exact_match(picomm, list))
11409 continue;
11410 }
11411 if (type == bgp_show_type_lcommunity) {
11412 struct lcommunity *lcom = output_arg;
11413
11414 if (!bgp_attr_get_lcommunity(pi->attr) ||
11415 !lcommunity_match(
11416 bgp_attr_get_lcommunity(pi->attr),
11417 lcom))
11418 continue;
11419 }
11420
11421 if (type == bgp_show_type_lcommunity_exact) {
11422 struct lcommunity *lcom = output_arg;
11423
11424 if (!bgp_attr_get_lcommunity(pi->attr) ||
11425 !lcommunity_cmp(
11426 bgp_attr_get_lcommunity(pi->attr),
11427 lcom))
11428 continue;
11429 }
11430 if (type == bgp_show_type_lcommunity_list) {
11431 struct community_list *list = output_arg;
11432
11433 if (!lcommunity_list_match(
11434 bgp_attr_get_lcommunity(pi->attr),
11435 list))
11436 continue;
11437 }
11438 if (type
11439 == bgp_show_type_lcommunity_list_exact) {
11440 struct community_list *list = output_arg;
11441
11442 if (!lcommunity_list_exact_match(
11443 bgp_attr_get_lcommunity(pi->attr),
11444 list))
11445 continue;
11446 }
11447 if (type == bgp_show_type_lcommunity_all) {
11448 if (!bgp_attr_get_lcommunity(pi->attr))
11449 continue;
11450 }
11451 if (type == bgp_show_type_dampend_paths
11452 || type == bgp_show_type_damp_neighbor) {
11453 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11454 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11455 continue;
11456 }
11457
11458 if (!use_json && header) {
11459 vty_out(vty,
11460 "BGP table version is %" PRIu64
11461 ", local router ID is %pI4, vrf id ",
11462 table->version, &bgp->router_id);
11463 if (bgp->vrf_id == VRF_UNKNOWN)
11464 vty_out(vty, "%s", VRFID_NONE_STR);
11465 else
11466 vty_out(vty, "%u", bgp->vrf_id);
11467 vty_out(vty, "\n");
11468 vty_out(vty, "Default local pref %u, ",
11469 bgp->default_local_pref);
11470 vty_out(vty, "local AS %u\n", bgp->as);
11471 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11472 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11473 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11474 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11475 if (type == bgp_show_type_dampend_paths
11476 || type == bgp_show_type_damp_neighbor)
11477 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11478 else if (type == bgp_show_type_flap_statistics
11479 || type == bgp_show_type_flap_neighbor)
11480 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11481 else
11482 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11483 : BGP_SHOW_HEADER));
11484 header = false;
11485
11486 } else if (json_detail && json_paths != NULL) {
11487 const struct prefix_rd *prd;
11488 json_object *jtemp;
11489
11490 /* Use common detail header, for most types;
11491 * need a json 'object'.
11492 */
11493
11494 jtemp = json_object_new_object();
11495 prd = bgp_rd_from_dest(dest, safi);
11496
11497 route_vty_out_detail_header(
11498 vty, bgp, dest, prd, table->afi,
11499 safi, jtemp);
11500
11501 json_object_array_add(json_paths, jtemp);
11502
11503 json_detail = false;
11504 }
11505
11506 if (rd != NULL && !display && !output_count) {
11507 if (!use_json)
11508 vty_out(vty,
11509 "Route Distinguisher: %s\n",
11510 rd);
11511 }
11512 if (type == bgp_show_type_dampend_paths
11513 || type == bgp_show_type_damp_neighbor)
11514 damp_route_vty_out(vty, dest_p, pi, display,
11515 AFI_IP, safi, use_json,
11516 json_paths);
11517 else if (type == bgp_show_type_flap_statistics
11518 || type == bgp_show_type_flap_neighbor)
11519 flap_route_vty_out(vty, dest_p, pi, display,
11520 AFI_IP, safi, use_json,
11521 json_paths);
11522 else {
11523 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11524 route_vty_out_detail(
11525 vty, bgp, dest, pi,
11526 family2afi(dest_p->family),
11527 safi, RPKI_NOT_BEING_USED,
11528 json_paths);
11529 else
11530 route_vty_out(vty, dest_p, pi, display,
11531 safi, json_paths, wide);
11532 }
11533 display++;
11534 }
11535
11536 if (display) {
11537 output_count++;
11538 if (!use_json)
11539 continue;
11540
11541 /* encode prefix */
11542 if (dest_p->family == AF_FLOWSPEC) {
11543 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11544
11545
11546 bgp_fs_nlri_get_string(
11547 (unsigned char *)
11548 dest_p->u.prefix_flowspec.ptr,
11549 dest_p->u.prefix_flowspec.prefixlen,
11550 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11551 family2afi(dest_p->u
11552 .prefix_flowspec.family));
11553 if (first)
11554 vty_out(vty, "\"%s/%d\": ", retstr,
11555 dest_p->u.prefix_flowspec
11556 .prefixlen);
11557 else
11558 vty_out(vty, ",\"%s/%d\": ", retstr,
11559 dest_p->u.prefix_flowspec
11560 .prefixlen);
11561 } else {
11562 if (first)
11563 vty_out(vty, "\"%pFX\": ", dest_p);
11564 else
11565 vty_out(vty, ",\"%pFX\": ", dest_p);
11566 }
11567 vty_json(vty, json_paths);
11568 json_paths = NULL;
11569 first = 0;
11570 } else
11571 json_object_free(json_paths);
11572 }
11573
11574 if (output_cum) {
11575 output_count += *output_cum;
11576 *output_cum = output_count;
11577 }
11578 if (total_cum) {
11579 total_count += *total_cum;
11580 *total_cum = total_count;
11581 }
11582 if (use_json) {
11583 if (rd) {
11584 vty_out(vty, " }%s ", (is_last ? "" : ","));
11585 }
11586 if (is_last) {
11587 unsigned long i;
11588 for (i = 0; i < *json_header_depth; ++i)
11589 vty_out(vty, " } ");
11590 if (!all)
11591 vty_out(vty, "\n");
11592 }
11593 } else {
11594 if (is_last) {
11595 /* No route is displayed */
11596 if (output_count == 0) {
11597 if (type == bgp_show_type_normal)
11598 vty_out(vty,
11599 "No BGP prefixes displayed, %ld exist\n",
11600 total_count);
11601 } else
11602 vty_out(vty,
11603 "\nDisplayed %ld routes and %ld total paths\n",
11604 output_count, total_count);
11605 }
11606 }
11607
11608 return CMD_SUCCESS;
11609 }
11610
11611 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11612 struct bgp_table *table, struct prefix_rd *prd_match,
11613 enum bgp_show_type type, void *output_arg, bool use_json)
11614 {
11615 struct bgp_dest *dest, *next;
11616 unsigned long output_cum = 0;
11617 unsigned long total_cum = 0;
11618 unsigned long json_header_depth = 0;
11619 struct bgp_table *itable;
11620 bool show_msg;
11621 uint16_t show_flags = 0;
11622
11623 show_msg = (!use_json && type == bgp_show_type_normal);
11624
11625 if (use_json)
11626 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11627
11628 for (dest = bgp_table_top(table); dest; dest = next) {
11629 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11630
11631 next = bgp_route_next(dest);
11632 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11633 continue;
11634
11635 itable = bgp_dest_get_bgp_table_info(dest);
11636 if (itable != NULL) {
11637 struct prefix_rd prd;
11638 char rd[RD_ADDRSTRLEN];
11639
11640 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11641 prefix_rd2str(&prd, rd, sizeof(rd));
11642 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11643 rd, next == NULL, &output_cum,
11644 &total_cum, &json_header_depth,
11645 show_flags, RPKI_NOT_BEING_USED);
11646 if (next == NULL)
11647 show_msg = false;
11648 }
11649 }
11650 if (show_msg) {
11651 if (output_cum == 0)
11652 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11653 total_cum);
11654 else
11655 vty_out(vty,
11656 "\nDisplayed %ld routes and %ld total paths\n",
11657 output_cum, total_cum);
11658 }
11659 return CMD_SUCCESS;
11660 }
11661
11662 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11663 enum bgp_show_type type, void *output_arg,
11664 uint16_t show_flags, enum rpki_states rpki_target_state)
11665 {
11666 struct bgp_table *table;
11667 unsigned long json_header_depth = 0;
11668 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11669
11670 if (bgp == NULL) {
11671 bgp = bgp_get_default();
11672 }
11673
11674 if (bgp == NULL) {
11675 if (!use_json)
11676 vty_out(vty, "No BGP process is configured\n");
11677 else
11678 vty_out(vty, "{}\n");
11679 return CMD_WARNING;
11680 }
11681
11682 /* Labeled-unicast routes live in the unicast table. */
11683 if (safi == SAFI_LABELED_UNICAST)
11684 safi = SAFI_UNICAST;
11685
11686 table = bgp->rib[afi][safi];
11687 /* use MPLS and ENCAP specific shows until they are merged */
11688 if (safi == SAFI_MPLS_VPN) {
11689 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11690 output_arg, use_json);
11691 }
11692
11693 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11694 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11695 output_arg, use_json,
11696 1, NULL, NULL);
11697 }
11698
11699 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11700 NULL, NULL, &json_header_depth, show_flags,
11701 rpki_target_state);
11702 }
11703
11704 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11705 safi_t safi, uint16_t show_flags)
11706 {
11707 struct listnode *node, *nnode;
11708 struct bgp *bgp;
11709 int is_first = 1;
11710 bool route_output = false;
11711 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11712
11713 if (use_json)
11714 vty_out(vty, "{\n");
11715
11716 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11717 route_output = true;
11718 if (use_json) {
11719 if (!is_first)
11720 vty_out(vty, ",\n");
11721 else
11722 is_first = 0;
11723
11724 vty_out(vty, "\"%s\":",
11725 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11726 ? VRF_DEFAULT_NAME
11727 : bgp->name);
11728 } else {
11729 vty_out(vty, "\nInstance %s:\n",
11730 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11731 ? VRF_DEFAULT_NAME
11732 : bgp->name);
11733 }
11734 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11735 show_flags, RPKI_NOT_BEING_USED);
11736 }
11737
11738 if (use_json)
11739 vty_out(vty, "}\n");
11740 else if (!route_output)
11741 vty_out(vty, "%% BGP instance not found\n");
11742 }
11743
11744 /* Header of detailed BGP route information */
11745 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11746 struct bgp_dest *dest,
11747 const struct prefix_rd *prd,
11748 afi_t afi, safi_t safi, json_object *json)
11749 {
11750 struct bgp_path_info *pi;
11751 const struct prefix *p;
11752 struct peer *peer;
11753 struct listnode *node, *nnode;
11754 char buf1[RD_ADDRSTRLEN];
11755 int count = 0;
11756 int best = 0;
11757 int suppress = 0;
11758 int accept_own = 0;
11759 int route_filter_translated_v4 = 0;
11760 int route_filter_v4 = 0;
11761 int route_filter_translated_v6 = 0;
11762 int route_filter_v6 = 0;
11763 int llgr_stale = 0;
11764 int no_llgr = 0;
11765 int accept_own_nexthop = 0;
11766 int blackhole = 0;
11767 int no_export = 0;
11768 int no_advertise = 0;
11769 int local_as = 0;
11770 int no_peer = 0;
11771 int first = 1;
11772 int has_valid_label = 0;
11773 mpls_label_t label = 0;
11774 json_object *json_adv_to = NULL;
11775 uint32_t ttl = 0;
11776 uint32_t bos = 0;
11777 uint32_t exp = 0;
11778
11779 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11780
11781 p = bgp_dest_get_prefix(dest);
11782 has_valid_label = bgp_is_valid_label(&label);
11783
11784 if (safi == SAFI_EVPN) {
11785 if (!json) {
11786 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11787 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11788 : "",
11789 prd ? ":" : "", (struct prefix_evpn *)p);
11790 } else {
11791 json_object_string_add(json, "rd",
11792 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11793 "");
11794 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11795 }
11796 } else {
11797 if (!json) {
11798 vty_out(vty,
11799 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11800 "\n",
11801 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11802 ? prefix_rd2str(prd, buf1,
11803 sizeof(buf1))
11804 : ""),
11805 safi == SAFI_MPLS_VPN ? ":" : "", p,
11806 dest->version);
11807
11808 } else {
11809 json_object_string_addf(json, "prefix", "%pFX", p);
11810 json_object_int_add(json, "version", dest->version);
11811
11812 }
11813 }
11814
11815 if (has_valid_label) {
11816 if (json)
11817 json_object_int_add(json, "localLabel", label);
11818 else
11819 vty_out(vty, "Local label: %d\n", label);
11820 }
11821
11822 if (!json)
11823 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11824 vty_out(vty, "not allocated\n");
11825
11826 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11827 struct community *picomm = NULL;
11828
11829 picomm = bgp_attr_get_community(pi->attr);
11830
11831 count++;
11832 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11833 best = count;
11834 if (bgp_path_suppressed(pi))
11835 suppress = 1;
11836
11837 if (!picomm)
11838 continue;
11839
11840 no_advertise += community_include(
11841 picomm, COMMUNITY_NO_ADVERTISE);
11842 no_export +=
11843 community_include(picomm, COMMUNITY_NO_EXPORT);
11844 local_as +=
11845 community_include(picomm, COMMUNITY_LOCAL_AS);
11846 accept_own +=
11847 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11848 route_filter_translated_v4 += community_include(
11849 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11850 route_filter_translated_v6 += community_include(
11851 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11852 route_filter_v4 += community_include(
11853 picomm, COMMUNITY_ROUTE_FILTER_v4);
11854 route_filter_v6 += community_include(
11855 picomm, COMMUNITY_ROUTE_FILTER_v6);
11856 llgr_stale +=
11857 community_include(picomm, COMMUNITY_LLGR_STALE);
11858 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11859 accept_own_nexthop += community_include(
11860 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11861 blackhole +=
11862 community_include(picomm, COMMUNITY_BLACKHOLE);
11863 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11864 }
11865 }
11866
11867 if (!json) {
11868 vty_out(vty, "Paths: (%d available", count);
11869 if (best) {
11870 vty_out(vty, ", best #%d", best);
11871 if (safi == SAFI_UNICAST) {
11872 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11873 vty_out(vty, ", table %s",
11874 VRF_DEFAULT_NAME);
11875 else
11876 vty_out(vty, ", vrf %s",
11877 bgp->name);
11878 }
11879 } else
11880 vty_out(vty, ", no best path");
11881
11882 if (accept_own)
11883 vty_out(vty,
11884 ", accept own local route exported and imported in different VRF");
11885 else if (route_filter_translated_v4)
11886 vty_out(vty,
11887 ", mark translated RTs for VPNv4 route filtering");
11888 else if (route_filter_v4)
11889 vty_out(vty,
11890 ", attach RT as-is for VPNv4 route filtering");
11891 else if (route_filter_translated_v6)
11892 vty_out(vty,
11893 ", mark translated RTs for VPNv6 route filtering");
11894 else if (route_filter_v6)
11895 vty_out(vty,
11896 ", attach RT as-is for VPNv6 route filtering");
11897 else if (llgr_stale)
11898 vty_out(vty,
11899 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11900 else if (no_llgr)
11901 vty_out(vty,
11902 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11903 else if (accept_own_nexthop)
11904 vty_out(vty,
11905 ", accept local nexthop");
11906 else if (blackhole)
11907 vty_out(vty, ", inform peer to blackhole prefix");
11908 else if (no_export)
11909 vty_out(vty, ", not advertised to EBGP peer");
11910 else if (no_advertise)
11911 vty_out(vty, ", not advertised to any peer");
11912 else if (local_as)
11913 vty_out(vty, ", not advertised outside local AS");
11914 else if (no_peer)
11915 vty_out(vty,
11916 ", inform EBGP peer not to advertise to their EBGP peers");
11917
11918 if (suppress)
11919 vty_out(vty,
11920 ", Advertisements suppressed by an aggregate.");
11921 vty_out(vty, ")\n");
11922 }
11923
11924 /* If we are not using addpath then we can display Advertised to and
11925 * that will
11926 * show what peers we advertised the bestpath to. If we are using
11927 * addpath
11928 * though then we must display Advertised to on a path-by-path basis. */
11929 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11930 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11931 if (bgp_adj_out_lookup(peer, dest, 0)) {
11932 if (json && !json_adv_to)
11933 json_adv_to = json_object_new_object();
11934
11935 route_vty_out_advertised_to(
11936 vty, peer, &first,
11937 " Advertised to non peer-group peers:\n ",
11938 json_adv_to);
11939 }
11940 }
11941
11942 if (json) {
11943 if (json_adv_to) {
11944 json_object_object_add(json, "advertisedTo",
11945 json_adv_to);
11946 }
11947 } else {
11948 if (first)
11949 vty_out(vty, " Not advertised to any peer");
11950 vty_out(vty, "\n");
11951 }
11952 }
11953 }
11954
11955 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11956 struct bgp_dest *bgp_node, struct vty *vty,
11957 struct bgp *bgp, afi_t afi, safi_t safi,
11958 json_object *json, enum bgp_path_type pathtype,
11959 int *display, enum rpki_states rpki_target_state)
11960 {
11961 struct bgp_path_info *pi;
11962 int header = 1;
11963 json_object *json_header = NULL;
11964 json_object *json_paths = NULL;
11965 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11966
11967 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11968 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11969
11970 if (p->family == AF_INET || p->family == AF_INET6)
11971 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11972 pi->peer, pi->attr, p);
11973
11974 if (rpki_target_state != RPKI_NOT_BEING_USED
11975 && rpki_curr_state != rpki_target_state)
11976 continue;
11977
11978 if (json && !json_paths) {
11979 /* Instantiate json_paths only if path is valid */
11980 json_paths = json_object_new_array();
11981 if (pfx_rd)
11982 json_header = json_object_new_object();
11983 else
11984 json_header = json;
11985 }
11986
11987 if (header) {
11988 route_vty_out_detail_header(
11989 vty, bgp, bgp_node, pfx_rd,
11990 AFI_IP, safi, json_header);
11991 header = 0;
11992 }
11993 (*display)++;
11994
11995 if (pathtype == BGP_PATH_SHOW_ALL
11996 || (pathtype == BGP_PATH_SHOW_BESTPATH
11997 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11998 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11999 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12000 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12001 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
12002 safi, rpki_curr_state, json_paths);
12003 }
12004
12005 if (json && json_paths) {
12006 json_object_object_add(json_header, "paths", json_paths);
12007
12008 if (pfx_rd)
12009 json_object_object_addf(json, json_header, "%pRD",
12010 pfx_rd);
12011 }
12012 }
12013
12014 /*
12015 * Return rd based on safi
12016 */
12017 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12018 safi_t safi)
12019 {
12020 switch (safi) {
12021 case SAFI_MPLS_VPN:
12022 case SAFI_ENCAP:
12023 case SAFI_EVPN:
12024 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12025 default:
12026 return NULL;
12027 }
12028 }
12029
12030 /* Display specified route of BGP table. */
12031 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12032 struct bgp_table *rib, const char *ip_str,
12033 afi_t afi, safi_t safi,
12034 enum rpki_states rpki_target_state,
12035 struct prefix_rd *prd, int prefix_check,
12036 enum bgp_path_type pathtype, bool use_json)
12037 {
12038 int ret;
12039 int display = 0;
12040 struct prefix match;
12041 struct bgp_dest *dest;
12042 struct bgp_dest *rm;
12043 struct bgp_table *table;
12044 json_object *json = NULL;
12045 json_object *json_paths = NULL;
12046
12047 /* Check IP address argument. */
12048 ret = str2prefix(ip_str, &match);
12049 if (!ret) {
12050 vty_out(vty, "address is malformed\n");
12051 return CMD_WARNING;
12052 }
12053
12054 match.family = afi2family(afi);
12055
12056 if (use_json)
12057 json = json_object_new_object();
12058
12059 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12060 for (dest = bgp_table_top(rib); dest;
12061 dest = bgp_route_next(dest)) {
12062 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12063
12064 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12065 continue;
12066 table = bgp_dest_get_bgp_table_info(dest);
12067 if (!table)
12068 continue;
12069
12070 rm = bgp_node_match(table, &match);
12071 if (rm == NULL)
12072 continue;
12073
12074 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12075 if (prefix_check
12076 && rm_p->prefixlen != match.prefixlen) {
12077 bgp_dest_unlock_node(rm);
12078 continue;
12079 }
12080
12081 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12082 bgp, afi, safi, json, pathtype,
12083 &display, rpki_target_state);
12084
12085 bgp_dest_unlock_node(rm);
12086 }
12087 } else if (safi == SAFI_EVPN) {
12088 struct bgp_dest *longest_pfx;
12089 bool is_exact_pfxlen_match = false;
12090
12091 for (dest = bgp_table_top(rib); dest;
12092 dest = bgp_route_next(dest)) {
12093 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12094
12095 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12096 continue;
12097 table = bgp_dest_get_bgp_table_info(dest);
12098 if (!table)
12099 continue;
12100
12101 longest_pfx = NULL;
12102 is_exact_pfxlen_match = false;
12103 /*
12104 * Search through all the prefixes for a match. The
12105 * pfx's are enumerated in ascending order of pfxlens.
12106 * So, the last pfx match is the longest match. Set
12107 * is_exact_pfxlen_match when we get exact pfxlen match
12108 */
12109 for (rm = bgp_table_top(table); rm;
12110 rm = bgp_route_next(rm)) {
12111 const struct prefix *rm_p =
12112 bgp_dest_get_prefix(rm);
12113 /*
12114 * Get prefixlen of the ip-prefix within type5
12115 * evpn route
12116 */
12117 if (evpn_type5_prefix_match(rm_p, &match)
12118 && rm->info) {
12119 longest_pfx = rm;
12120 int type5_pfxlen =
12121 bgp_evpn_get_type5_prefixlen(
12122 rm_p);
12123 if (type5_pfxlen == match.prefixlen) {
12124 is_exact_pfxlen_match = true;
12125 bgp_dest_unlock_node(rm);
12126 break;
12127 }
12128 }
12129 }
12130
12131 if (!longest_pfx)
12132 continue;
12133
12134 if (prefix_check && !is_exact_pfxlen_match)
12135 continue;
12136
12137 rm = longest_pfx;
12138 bgp_dest_lock_node(rm);
12139
12140 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12141 bgp, afi, safi, json, pathtype,
12142 &display, rpki_target_state);
12143
12144 bgp_dest_unlock_node(rm);
12145 }
12146 } else if (safi == SAFI_FLOWSPEC) {
12147 if (use_json)
12148 json_paths = json_object_new_array();
12149
12150 display = bgp_flowspec_display_match_per_ip(afi, rib,
12151 &match, prefix_check,
12152 vty,
12153 use_json,
12154 json_paths);
12155 if (use_json) {
12156 if (display)
12157 json_object_object_add(json, "paths",
12158 json_paths);
12159 else
12160 json_object_free(json_paths);
12161 }
12162 } else {
12163 dest = bgp_node_match(rib, &match);
12164 if (dest != NULL) {
12165 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12166 if (!prefix_check
12167 || dest_p->prefixlen == match.prefixlen) {
12168 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12169 safi, json, pathtype,
12170 &display, rpki_target_state);
12171 }
12172
12173 bgp_dest_unlock_node(dest);
12174 }
12175 }
12176
12177 if (use_json) {
12178 vty_json(vty, json);
12179 } else {
12180 if (!display) {
12181 vty_out(vty, "%% Network not in table\n");
12182 return CMD_WARNING;
12183 }
12184 }
12185
12186 return CMD_SUCCESS;
12187 }
12188
12189 /* Display specified route of Main RIB */
12190 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12191 afi_t afi, safi_t safi, struct prefix_rd *prd,
12192 int prefix_check, enum bgp_path_type pathtype,
12193 enum rpki_states rpki_target_state, bool use_json)
12194 {
12195 if (!bgp) {
12196 bgp = bgp_get_default();
12197 if (!bgp) {
12198 if (!use_json)
12199 vty_out(vty, "No BGP process is configured\n");
12200 else
12201 vty_out(vty, "{}\n");
12202 return CMD_WARNING;
12203 }
12204 }
12205
12206 /* labeled-unicast routes live in the unicast table */
12207 if (safi == SAFI_LABELED_UNICAST)
12208 safi = SAFI_UNICAST;
12209
12210 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12211 afi, safi, rpki_target_state, prd,
12212 prefix_check, pathtype, use_json);
12213 }
12214
12215 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12216 struct cmd_token **argv, bool exact, afi_t afi,
12217 safi_t safi, bool uj)
12218 {
12219 struct lcommunity *lcom;
12220 struct buffer *b;
12221 int i;
12222 char *str;
12223 int first = 0;
12224 uint16_t show_flags = 0;
12225 int ret;
12226
12227 if (uj)
12228 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12229
12230 b = buffer_new(1024);
12231 for (i = 0; i < argc; i++) {
12232 if (first)
12233 buffer_putc(b, ' ');
12234 else {
12235 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12236 first = 1;
12237 buffer_putstr(b, argv[i]->arg);
12238 }
12239 }
12240 }
12241 buffer_putc(b, '\0');
12242
12243 str = buffer_getstr(b);
12244 buffer_free(b);
12245
12246 lcom = lcommunity_str2com(str);
12247 XFREE(MTYPE_TMP, str);
12248 if (!lcom) {
12249 vty_out(vty, "%% Large-community malformed\n");
12250 return CMD_WARNING;
12251 }
12252
12253 ret = bgp_show(vty, bgp, afi, safi,
12254 (exact ? bgp_show_type_lcommunity_exact
12255 : bgp_show_type_lcommunity),
12256 lcom, show_flags, RPKI_NOT_BEING_USED);
12257
12258 lcommunity_free(&lcom);
12259 return ret;
12260 }
12261
12262 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12263 const char *lcom, bool exact, afi_t afi,
12264 safi_t safi, bool uj)
12265 {
12266 struct community_list *list;
12267 uint16_t show_flags = 0;
12268
12269 if (uj)
12270 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12271
12272
12273 list = community_list_lookup(bgp_clist, lcom, 0,
12274 LARGE_COMMUNITY_LIST_MASTER);
12275 if (list == NULL) {
12276 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12277 lcom);
12278 return CMD_WARNING;
12279 }
12280
12281 return bgp_show(vty, bgp, afi, safi,
12282 (exact ? bgp_show_type_lcommunity_list_exact
12283 : bgp_show_type_lcommunity_list),
12284 list, show_flags, RPKI_NOT_BEING_USED);
12285 }
12286
12287 DEFUN (show_ip_bgp_large_community_list,
12288 show_ip_bgp_large_community_list_cmd,
12289 "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]",
12290 SHOW_STR
12291 IP_STR
12292 BGP_STR
12293 BGP_INSTANCE_HELP_STR
12294 BGP_AFI_HELP_STR
12295 BGP_SAFI_WITH_LABEL_HELP_STR
12296 "Display routes matching the large-community-list\n"
12297 "large-community-list number\n"
12298 "large-community-list name\n"
12299 "Exact match of the large-communities\n"
12300 JSON_STR)
12301 {
12302 afi_t afi = AFI_IP6;
12303 safi_t safi = SAFI_UNICAST;
12304 int idx = 0;
12305 bool exact_match = 0;
12306 struct bgp *bgp = NULL;
12307 bool uj = use_json(argc, argv);
12308
12309 if (uj)
12310 argc--;
12311
12312 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12313 &bgp, uj);
12314 if (!idx)
12315 return CMD_WARNING;
12316
12317 argv_find(argv, argc, "large-community-list", &idx);
12318
12319 const char *clist_number_or_name = argv[++idx]->arg;
12320
12321 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12322 exact_match = 1;
12323
12324 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12325 exact_match, afi, safi, uj);
12326 }
12327 DEFUN (show_ip_bgp_large_community,
12328 show_ip_bgp_large_community_cmd,
12329 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12330 SHOW_STR
12331 IP_STR
12332 BGP_STR
12333 BGP_INSTANCE_HELP_STR
12334 BGP_AFI_HELP_STR
12335 BGP_SAFI_WITH_LABEL_HELP_STR
12336 "Display routes matching the large-communities\n"
12337 "List of large-community numbers\n"
12338 "Exact match of the large-communities\n"
12339 JSON_STR)
12340 {
12341 afi_t afi = AFI_IP6;
12342 safi_t safi = SAFI_UNICAST;
12343 int idx = 0;
12344 bool exact_match = 0;
12345 struct bgp *bgp = NULL;
12346 bool uj = use_json(argc, argv);
12347 uint16_t show_flags = 0;
12348
12349 if (uj) {
12350 argc--;
12351 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12352 }
12353
12354 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12355 &bgp, uj);
12356 if (!idx)
12357 return CMD_WARNING;
12358
12359 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12360 if (argv_find(argv, argc, "exact-match", &idx)) {
12361 argc--;
12362 exact_match = 1;
12363 }
12364 return bgp_show_lcommunity(vty, bgp, argc, argv,
12365 exact_match, afi, safi, uj);
12366 } else
12367 return bgp_show(vty, bgp, afi, safi,
12368 bgp_show_type_lcommunity_all, NULL, show_flags,
12369 RPKI_NOT_BEING_USED);
12370 }
12371
12372 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12373 safi_t safi, struct json_object *json_array);
12374 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12375 safi_t safi, struct json_object *json);
12376
12377
12378 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12379 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12380 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12381 "Display number of prefixes for all afi/safi\n" JSON_STR)
12382 {
12383 bool uj = use_json(argc, argv);
12384 struct bgp *bgp = NULL;
12385 safi_t safi = SAFI_UNICAST;
12386 afi_t afi = AFI_IP6;
12387 int idx = 0;
12388 struct json_object *json_all = NULL;
12389 struct json_object *json_afi_safi = NULL;
12390
12391 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12392 &bgp, false);
12393 if (!idx)
12394 return CMD_WARNING;
12395
12396 if (uj)
12397 json_all = json_object_new_object();
12398
12399 FOREACH_AFI_SAFI (afi, safi) {
12400 /*
12401 * So limit output to those afi/safi pairs that
12402 * actually have something interesting in them
12403 */
12404 if (strmatch(get_afi_safi_str(afi, safi, true),
12405 "Unknown")) {
12406 continue;
12407 }
12408 if (uj) {
12409 json_afi_safi = json_object_new_array();
12410 json_object_object_add(
12411 json_all,
12412 get_afi_safi_str(afi, safi, true),
12413 json_afi_safi);
12414 } else {
12415 json_afi_safi = NULL;
12416 }
12417
12418 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12419 }
12420
12421 if (uj)
12422 vty_json(vty, json_all);
12423
12424 return CMD_SUCCESS;
12425 }
12426
12427 /* BGP route print out function without JSON */
12428 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12429 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12430 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12431 SHOW_STR
12432 IP_STR
12433 BGP_STR
12434 BGP_INSTANCE_HELP_STR
12435 L2VPN_HELP_STR
12436 EVPN_HELP_STR
12437 "BGP RIB advertisement statistics\n"
12438 JSON_STR)
12439 {
12440 afi_t afi = AFI_IP6;
12441 safi_t safi = SAFI_UNICAST;
12442 struct bgp *bgp = NULL;
12443 int idx = 0, ret;
12444 bool uj = use_json(argc, argv);
12445 struct json_object *json_afi_safi = NULL, *json = NULL;
12446
12447 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12448 &bgp, false);
12449 if (!idx)
12450 return CMD_WARNING;
12451
12452 if (uj)
12453 json_afi_safi = json_object_new_array();
12454 else
12455 json_afi_safi = NULL;
12456
12457 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12458
12459 if (uj) {
12460 json = json_object_new_object();
12461 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12462 json_afi_safi);
12463 vty_json(vty, json);
12464 }
12465 return ret;
12466 }
12467
12468 /* BGP route print out function without JSON */
12469 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12470 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12471 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12472 "]]\
12473 statistics [json]",
12474 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12475 BGP_SAFI_WITH_LABEL_HELP_STR
12476 "BGP RIB advertisement statistics\n" JSON_STR)
12477 {
12478 afi_t afi = AFI_IP6;
12479 safi_t safi = SAFI_UNICAST;
12480 struct bgp *bgp = NULL;
12481 int idx = 0, ret;
12482 bool uj = use_json(argc, argv);
12483 struct json_object *json_afi_safi = NULL, *json = NULL;
12484
12485 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12486 &bgp, false);
12487 if (!idx)
12488 return CMD_WARNING;
12489
12490 if (uj)
12491 json_afi_safi = json_object_new_array();
12492 else
12493 json_afi_safi = NULL;
12494
12495 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12496
12497 if (uj) {
12498 json = json_object_new_object();
12499 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12500 json_afi_safi);
12501 vty_json(vty, json);
12502 }
12503 return ret;
12504 }
12505
12506 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12507 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12508 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12509 "]] [all$all] dampening parameters [json]",
12510 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12511 BGP_SAFI_WITH_LABEL_HELP_STR
12512 "Display the entries for all address families\n"
12513 "Display detailed information about dampening\n"
12514 "Display detail of configured dampening parameters\n"
12515 JSON_STR)
12516 {
12517 afi_t afi = AFI_IP6;
12518 safi_t safi = SAFI_UNICAST;
12519 struct bgp *bgp = NULL;
12520 int idx = 0;
12521 uint16_t show_flags = 0;
12522 bool uj = use_json(argc, argv);
12523
12524 if (uj) {
12525 argc--;
12526 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12527 }
12528
12529 /* [<ipv4|ipv6> [all]] */
12530 if (all) {
12531 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12532 if (argv_find(argv, argc, "ipv4", &idx))
12533 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12534
12535 if (argv_find(argv, argc, "ipv6", &idx))
12536 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12537 }
12538
12539 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12540 &bgp, false);
12541 if (!idx)
12542 return CMD_WARNING;
12543
12544 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12545 }
12546
12547 /* BGP route print out function */
12548 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12549 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12550 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12551 "]]\
12552 [all$all]\
12553 [cidr-only\
12554 |dampening <flap-statistics|dampened-paths>\
12555 |community [AA:NN|local-AS|no-advertise|no-export\
12556 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12557 |accept-own|accept-own-nexthop|route-filter-v6\
12558 |route-filter-v4|route-filter-translated-v6\
12559 |route-filter-translated-v4] [exact-match]\
12560 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12561 |filter-list AS_PATH_FILTER_NAME\
12562 |prefix-list WORD\
12563 |access-list ACCESSLIST_NAME\
12564 |route-map RMAP_NAME\
12565 |rpki <invalid|valid|notfound>\
12566 |version (1-4294967295)\
12567 |alias ALIAS_NAME\
12568 |A.B.C.D/M longer-prefixes\
12569 |X:X::X:X/M longer-prefixes\
12570 |optimal-route-reflection [WORD$orr_group_name]\
12571 ] [json$uj [detail$detail] | wide$wide]",
12572 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12573 BGP_SAFI_WITH_LABEL_HELP_STR
12574 "Display the entries for all address families\n"
12575 "Display only routes with non-natural netmasks\n"
12576 "Display detailed information about dampening\n"
12577 "Display flap statistics of routes\n"
12578 "Display paths suppressed due to dampening\n"
12579 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12580 "Do not send outside local AS (well-known community)\n"
12581 "Do not advertise to any peer (well-known community)\n"
12582 "Do not export to next AS (well-known community)\n"
12583 "Graceful shutdown (well-known community)\n"
12584 "Do not export to any peer (well-known community)\n"
12585 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12586 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12587 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12588 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12589 "Should accept VPN route with local nexthop (well-known community)\n"
12590 "RT VPNv6 route filtering (well-known community)\n"
12591 "RT VPNv4 route filtering (well-known community)\n"
12592 "RT translated VPNv6 route filtering (well-known community)\n"
12593 "RT translated VPNv4 route filtering (well-known community)\n"
12594 "Exact match of the communities\n"
12595 "Community-list number\n"
12596 "Community-list name\n"
12597 "Display routes matching the community-list\n"
12598 "Exact match of the communities\n"
12599 "Display routes conforming to the filter-list\n"
12600 "Regular expression access list name\n"
12601 "Display routes conforming to the prefix-list\n"
12602 "Prefix-list name\n"
12603 "Display routes conforming to the access-list\n"
12604 "Access-list name\n"
12605 "Display routes matching the route-map\n"
12606 "A route-map to match on\n"
12607 "RPKI route types\n"
12608 "A valid path as determined by rpki\n"
12609 "A invalid path as determined by rpki\n"
12610 "A path that has no rpki data\n"
12611 "Display prefixes with matching version numbers\n"
12612 "Version number and above\n"
12613 "Display prefixes with matching BGP community alias\n"
12614 "BGP community alias\n"
12615 "IPv4 prefix\n"
12616 "Display route and more specific routes\n"
12617 "IPv6 prefix\n"
12618 "Display route and more specific routes\n"
12619 "Display Optimal Route Reflection RR Clients\n"
12620 "ORR Group name\n"
12621 JSON_STR
12622 "Display detailed version of JSON output\n"
12623 "Increase table width for longer prefixes\n")
12624 {
12625 afi_t afi = AFI_IP6;
12626 safi_t safi = SAFI_UNICAST;
12627 enum bgp_show_type sh_type = bgp_show_type_normal;
12628 void *output_arg = NULL;
12629 struct bgp *bgp = NULL;
12630 int idx = 0;
12631 int exact_match = 0;
12632 char *community = NULL;
12633 bool first = true;
12634 uint16_t show_flags = 0;
12635 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12636 struct prefix p;
12637 bool orr_group = false;
12638
12639 if (uj) {
12640 argc--;
12641 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12642 }
12643
12644 if (detail)
12645 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12646
12647 /* [<ipv4|ipv6> [all]] */
12648 if (all) {
12649 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12650
12651 if (argv_find(argv, argc, "ipv4", &idx))
12652 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12653
12654 if (argv_find(argv, argc, "ipv6", &idx))
12655 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12656 }
12657
12658 if (wide)
12659 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12660
12661 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12662 &bgp, uj);
12663 if (!idx)
12664 return CMD_WARNING;
12665
12666 if (argv_find(argv, argc, "cidr-only", &idx))
12667 sh_type = bgp_show_type_cidr_only;
12668
12669 if (argv_find(argv, argc, "dampening", &idx)) {
12670 if (argv_find(argv, argc, "dampened-paths", &idx))
12671 sh_type = bgp_show_type_dampend_paths;
12672 else if (argv_find(argv, argc, "flap-statistics", &idx))
12673 sh_type = bgp_show_type_flap_statistics;
12674 }
12675
12676 if (argv_find(argv, argc, "community", &idx)) {
12677 char *maybecomm = NULL;
12678
12679 if (idx + 1 < argc) {
12680 if (argv[idx + 1]->type == VARIABLE_TKN)
12681 maybecomm = argv[idx + 1]->arg;
12682 else
12683 maybecomm = argv[idx + 1]->text;
12684 }
12685
12686 if (maybecomm && !strmatch(maybecomm, "json")
12687 && !strmatch(maybecomm, "exact-match"))
12688 community = maybecomm;
12689
12690 if (argv_find(argv, argc, "exact-match", &idx))
12691 exact_match = 1;
12692
12693 if (!community)
12694 sh_type = bgp_show_type_community_all;
12695 }
12696
12697 if (argv_find(argv, argc, "community-list", &idx)) {
12698 const char *clist_number_or_name = argv[++idx]->arg;
12699 struct community_list *list;
12700
12701 if (argv_find(argv, argc, "exact-match", &idx))
12702 exact_match = 1;
12703
12704 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12705 COMMUNITY_LIST_MASTER);
12706 if (list == NULL) {
12707 vty_out(vty, "%% %s community-list not found\n",
12708 clist_number_or_name);
12709 return CMD_WARNING;
12710 }
12711
12712 if (exact_match)
12713 sh_type = bgp_show_type_community_list_exact;
12714 else
12715 sh_type = bgp_show_type_community_list;
12716 output_arg = list;
12717 }
12718
12719 if (argv_find(argv, argc, "filter-list", &idx)) {
12720 const char *filter = argv[++idx]->arg;
12721 struct as_list *as_list;
12722
12723 as_list = as_list_lookup(filter);
12724 if (as_list == NULL) {
12725 vty_out(vty, "%% %s AS-path access-list not found\n",
12726 filter);
12727 return CMD_WARNING;
12728 }
12729
12730 sh_type = bgp_show_type_filter_list;
12731 output_arg = as_list;
12732 }
12733
12734 if (argv_find(argv, argc, "prefix-list", &idx)) {
12735 const char *prefix_list_str = argv[++idx]->arg;
12736 struct prefix_list *plist;
12737
12738 plist = prefix_list_lookup(afi, prefix_list_str);
12739 if (plist == NULL) {
12740 vty_out(vty, "%% %s prefix-list not found\n",
12741 prefix_list_str);
12742 return CMD_WARNING;
12743 }
12744
12745 sh_type = bgp_show_type_prefix_list;
12746 output_arg = plist;
12747 }
12748
12749 if (argv_find(argv, argc, "access-list", &idx)) {
12750 const char *access_list_str = argv[++idx]->arg;
12751 struct access_list *alist;
12752
12753 alist = access_list_lookup(afi, access_list_str);
12754 if (!alist) {
12755 vty_out(vty, "%% %s access-list not found\n",
12756 access_list_str);
12757 return CMD_WARNING;
12758 }
12759
12760 sh_type = bgp_show_type_access_list;
12761 output_arg = alist;
12762 }
12763
12764 if (argv_find(argv, argc, "route-map", &idx)) {
12765 const char *rmap_str = argv[++idx]->arg;
12766 struct route_map *rmap;
12767
12768 rmap = route_map_lookup_by_name(rmap_str);
12769 if (!rmap) {
12770 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12771 return CMD_WARNING;
12772 }
12773
12774 sh_type = bgp_show_type_route_map;
12775 output_arg = rmap;
12776 }
12777
12778 if (argv_find(argv, argc, "rpki", &idx)) {
12779 sh_type = bgp_show_type_rpki;
12780 if (argv_find(argv, argc, "valid", &idx))
12781 rpki_target_state = RPKI_VALID;
12782 else if (argv_find(argv, argc, "invalid", &idx))
12783 rpki_target_state = RPKI_INVALID;
12784 }
12785
12786 /* Display prefixes with matching version numbers */
12787 if (argv_find(argv, argc, "version", &idx)) {
12788 sh_type = bgp_show_type_prefix_version;
12789 output_arg = argv[idx + 1]->arg;
12790 }
12791
12792 /* Display prefixes with matching BGP community alias */
12793 if (argv_find(argv, argc, "alias", &idx)) {
12794 sh_type = bgp_show_type_community_alias;
12795 output_arg = argv[idx + 1]->arg;
12796 }
12797
12798 /* prefix-longer */
12799 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12800 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12801 const char *prefix_str = argv[idx]->arg;
12802
12803 if (!str2prefix(prefix_str, &p)) {
12804 vty_out(vty, "%% Malformed Prefix\n");
12805 return CMD_WARNING;
12806 }
12807
12808 sh_type = bgp_show_type_prefix_longer;
12809 output_arg = &p;
12810 }
12811
12812 if (argv_find(argv, argc, "optimal-route-reflection", &idx))
12813 orr_group = true;
12814
12815 if (!all) {
12816 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12817 if (community)
12818 return bgp_show_community(vty, bgp, community,
12819 exact_match, afi, safi,
12820 show_flags);
12821 else if (orr_group)
12822 return bgp_show_orr(vty, bgp, afi, safi, orr_group_name,
12823 show_flags);
12824 else
12825 return bgp_show(vty, bgp, afi, safi, sh_type,
12826 output_arg, show_flags,
12827 rpki_target_state);
12828 } else {
12829 struct listnode *node;
12830 struct bgp *abgp;
12831 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12832 * AFI_IP6 */
12833
12834 if (uj)
12835 vty_out(vty, "{\n");
12836
12837 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12838 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12839 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12840 ? AFI_IP
12841 : AFI_IP6;
12842 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12843 FOREACH_SAFI (safi) {
12844 if (!bgp_afi_safi_peer_exists(abgp, afi,
12845 safi))
12846 continue;
12847
12848 if (uj) {
12849 if (first)
12850 first = false;
12851 else
12852 vty_out(vty, ",\n");
12853 vty_out(vty, "\"%s\":{\n",
12854 get_afi_safi_str(afi,
12855 safi,
12856 true));
12857 } else
12858 vty_out(vty,
12859 "\nFor address family: %s\n",
12860 get_afi_safi_str(
12861 afi, safi,
12862 false));
12863
12864 if (community)
12865 bgp_show_community(
12866 vty, abgp, community,
12867 exact_match, afi, safi,
12868 show_flags);
12869 else if (orr_group)
12870 bgp_show_orr(vty, bgp, afi,
12871 safi,
12872 orr_group_name,
12873 show_flags);
12874 else
12875 bgp_show(vty, abgp, afi, safi,
12876 sh_type, output_arg,
12877 show_flags,
12878 rpki_target_state);
12879 if (uj)
12880 vty_out(vty, "}\n");
12881 }
12882 }
12883 } else {
12884 /* show <ip> bgp all: for each AFI and SAFI*/
12885 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12886 FOREACH_AFI_SAFI (afi, safi) {
12887 if (!bgp_afi_safi_peer_exists(abgp, afi,
12888 safi))
12889 continue;
12890
12891 if (uj) {
12892 if (first)
12893 first = false;
12894 else
12895 vty_out(vty, ",\n");
12896
12897 vty_out(vty, "\"%s\":{\n",
12898 get_afi_safi_str(afi,
12899 safi,
12900 true));
12901 } else
12902 vty_out(vty,
12903 "\nFor address family: %s\n",
12904 get_afi_safi_str(
12905 afi, safi,
12906 false));
12907
12908 if (community)
12909 bgp_show_community(
12910 vty, abgp, community,
12911 exact_match, afi, safi,
12912 show_flags);
12913 else if (orr_group)
12914 bgp_show_orr(vty, bgp, afi,
12915 safi,
12916 orr_group_name,
12917 show_flags);
12918 else
12919 bgp_show(vty, abgp, afi, safi,
12920 sh_type, output_arg,
12921 show_flags,
12922 rpki_target_state);
12923 if (uj)
12924 vty_out(vty, "}\n");
12925 }
12926 }
12927 }
12928 if (uj)
12929 vty_out(vty, "}\n");
12930 }
12931 return CMD_SUCCESS;
12932 }
12933
12934 DEFUN (show_ip_bgp_route,
12935 show_ip_bgp_route_cmd,
12936 "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]",
12937 SHOW_STR
12938 IP_STR
12939 BGP_STR
12940 BGP_INSTANCE_HELP_STR
12941 BGP_AFI_HELP_STR
12942 BGP_SAFI_WITH_LABEL_HELP_STR
12943 "Network in the BGP routing table to display\n"
12944 "IPv4 prefix\n"
12945 "Network in the BGP routing table to display\n"
12946 "IPv6 prefix\n"
12947 "Display only the bestpath\n"
12948 "Display only multipaths\n"
12949 "Display only paths that match the specified rpki state\n"
12950 "A valid path as determined by rpki\n"
12951 "A invalid path as determined by rpki\n"
12952 "A path that has no rpki data\n"
12953 JSON_STR)
12954 {
12955 int prefix_check = 0;
12956
12957 afi_t afi = AFI_IP6;
12958 safi_t safi = SAFI_UNICAST;
12959 char *prefix = NULL;
12960 struct bgp *bgp = NULL;
12961 enum bgp_path_type path_type;
12962 bool uj = use_json(argc, argv);
12963
12964 int idx = 0;
12965
12966 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12967 &bgp, uj);
12968 if (!idx)
12969 return CMD_WARNING;
12970
12971 if (!bgp) {
12972 vty_out(vty,
12973 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12974 return CMD_WARNING;
12975 }
12976
12977 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12978 if (argv_find(argv, argc, "A.B.C.D", &idx)
12979 || argv_find(argv, argc, "X:X::X:X", &idx))
12980 prefix_check = 0;
12981 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12982 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12983 prefix_check = 1;
12984
12985 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12986 && afi != AFI_IP6) {
12987 vty_out(vty,
12988 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12989 return CMD_WARNING;
12990 }
12991 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12992 && afi != AFI_IP) {
12993 vty_out(vty,
12994 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12995 return CMD_WARNING;
12996 }
12997
12998 prefix = argv[idx]->arg;
12999
13000 /* [<bestpath|multipath>] */
13001 if (argv_find(argv, argc, "bestpath", &idx))
13002 path_type = BGP_PATH_SHOW_BESTPATH;
13003 else if (argv_find(argv, argc, "multipath", &idx))
13004 path_type = BGP_PATH_SHOW_MULTIPATH;
13005 else
13006 path_type = BGP_PATH_SHOW_ALL;
13007
13008 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13009 path_type, RPKI_NOT_BEING_USED, uj);
13010 }
13011
13012 DEFUN (show_ip_bgp_regexp,
13013 show_ip_bgp_regexp_cmd,
13014 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13015 SHOW_STR
13016 IP_STR
13017 BGP_STR
13018 BGP_INSTANCE_HELP_STR
13019 BGP_AFI_HELP_STR
13020 BGP_SAFI_WITH_LABEL_HELP_STR
13021 "Display routes matching the AS path regular expression\n"
13022 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13023 JSON_STR)
13024 {
13025 afi_t afi = AFI_IP6;
13026 safi_t safi = SAFI_UNICAST;
13027 struct bgp *bgp = NULL;
13028 bool uj = use_json(argc, argv);
13029 char *regstr = NULL;
13030
13031 int idx = 0;
13032 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13033 &bgp, false);
13034 if (!idx)
13035 return CMD_WARNING;
13036
13037 // get index of regex
13038 if (argv_find(argv, argc, "REGEX", &idx))
13039 regstr = argv[idx]->arg;
13040
13041 assert(regstr);
13042 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13043 bgp_show_type_regexp, uj);
13044 }
13045
13046 DEFPY (show_ip_bgp_instance_all,
13047 show_ip_bgp_instance_all_cmd,
13048 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13049 SHOW_STR
13050 IP_STR
13051 BGP_STR
13052 BGP_INSTANCE_ALL_HELP_STR
13053 BGP_AFI_HELP_STR
13054 BGP_SAFI_WITH_LABEL_HELP_STR
13055 JSON_STR
13056 "Increase table width for longer prefixes\n")
13057 {
13058 afi_t afi = AFI_IP6;
13059 safi_t safi = SAFI_UNICAST;
13060 struct bgp *bgp = NULL;
13061 int idx = 0;
13062 uint16_t show_flags = 0;
13063
13064 if (uj) {
13065 argc--;
13066 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13067 }
13068
13069 if (wide)
13070 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13071
13072 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13073 &bgp, uj);
13074 if (!idx)
13075 return CMD_WARNING;
13076
13077 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13078 return CMD_SUCCESS;
13079 }
13080
13081 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13082 afi_t afi, safi_t safi, enum bgp_show_type type,
13083 bool use_json)
13084 {
13085 regex_t *regex;
13086 int rc;
13087 uint16_t show_flags = 0;
13088
13089 if (use_json)
13090 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13091
13092 if (!config_bgp_aspath_validate(regstr)) {
13093 vty_out(vty, "Invalid character in REGEX %s\n",
13094 regstr);
13095 return CMD_WARNING_CONFIG_FAILED;
13096 }
13097
13098 regex = bgp_regcomp(regstr);
13099 if (!regex) {
13100 vty_out(vty, "Can't compile regexp %s\n", regstr);
13101 return CMD_WARNING;
13102 }
13103
13104 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13105 RPKI_NOT_BEING_USED);
13106 bgp_regex_free(regex);
13107 return rc;
13108 }
13109
13110 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13111 const char *comstr, int exact, afi_t afi,
13112 safi_t safi, uint16_t show_flags)
13113 {
13114 struct community *com;
13115 int ret = 0;
13116
13117 com = community_str2com(comstr);
13118 if (!com) {
13119 vty_out(vty, "%% Community malformed: %s\n", comstr);
13120 return CMD_WARNING;
13121 }
13122
13123 ret = bgp_show(vty, bgp, afi, safi,
13124 (exact ? bgp_show_type_community_exact
13125 : bgp_show_type_community),
13126 com, show_flags, RPKI_NOT_BEING_USED);
13127 community_free(&com);
13128
13129 return ret;
13130 }
13131
13132 enum bgp_stats {
13133 BGP_STATS_MAXBITLEN = 0,
13134 BGP_STATS_RIB,
13135 BGP_STATS_PREFIXES,
13136 BGP_STATS_TOTPLEN,
13137 BGP_STATS_UNAGGREGATEABLE,
13138 BGP_STATS_MAX_AGGREGATEABLE,
13139 BGP_STATS_AGGREGATES,
13140 BGP_STATS_SPACE,
13141 BGP_STATS_ASPATH_COUNT,
13142 BGP_STATS_ASPATH_MAXHOPS,
13143 BGP_STATS_ASPATH_TOTHOPS,
13144 BGP_STATS_ASPATH_MAXSIZE,
13145 BGP_STATS_ASPATH_TOTSIZE,
13146 BGP_STATS_ASN_HIGHEST,
13147 BGP_STATS_MAX,
13148 };
13149
13150 #define TABLE_STATS_IDX_VTY 0
13151 #define TABLE_STATS_IDX_JSON 1
13152
13153 static const char *table_stats_strs[][2] = {
13154 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13155 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13156 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13157 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13158 "unaggregateablePrefixes"},
13159 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13160 "maximumAggregateablePrefixes"},
13161 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13162 "bgpAggregateAdvertisements"},
13163 [BGP_STATS_SPACE] = {"Address space advertised",
13164 "addressSpaceAdvertised"},
13165 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13166 "advertisementsWithPaths"},
13167 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13168 "longestAsPath"},
13169 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13170 "largestAsPath"},
13171 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13172 "averageAsPathLengthHops"},
13173 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13174 "averageAsPathSizeBytes"},
13175 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13176 [BGP_STATS_MAX] = {NULL, NULL}
13177 };
13178
13179 struct bgp_table_stats {
13180 struct bgp_table *table;
13181 unsigned long long counts[BGP_STATS_MAX];
13182
13183 unsigned long long
13184 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13185 1];
13186
13187 double total_space;
13188 };
13189
13190 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13191 struct bgp_table_stats *ts, unsigned int space)
13192 {
13193 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13194 struct bgp_path_info *pi;
13195 const struct prefix *rn_p;
13196
13197 if (!bgp_dest_has_bgp_path_info_data(dest))
13198 return;
13199
13200 rn_p = bgp_dest_get_prefix(dest);
13201 ts->counts[BGP_STATS_PREFIXES]++;
13202 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13203
13204 ts->prefix_len_count[rn_p->prefixlen]++;
13205 /* check if the prefix is included by any other announcements */
13206 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13207 pdest = bgp_dest_parent_nolock(pdest);
13208
13209 if (pdest == NULL || pdest == top) {
13210 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13211 /* announced address space */
13212 if (space)
13213 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13214 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13215 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13216
13217
13218 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13219 ts->counts[BGP_STATS_RIB]++;
13220
13221 if (CHECK_FLAG(pi->attr->flag,
13222 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13223 ts->counts[BGP_STATS_AGGREGATES]++;
13224
13225 /* as-path stats */
13226 if (pi->attr->aspath) {
13227 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13228 unsigned int size = aspath_size(pi->attr->aspath);
13229 as_t highest = aspath_highest(pi->attr->aspath);
13230
13231 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13232
13233 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13234 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13235
13236 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13237 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13238
13239 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13240 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13241 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13242 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13243 }
13244 }
13245 }
13246
13247 static void bgp_table_stats_walker(struct thread *t)
13248 {
13249 struct bgp_dest *dest, *ndest;
13250 struct bgp_dest *top;
13251 struct bgp_table_stats *ts = THREAD_ARG(t);
13252 unsigned int space = 0;
13253
13254 if (!(top = bgp_table_top(ts->table)))
13255 return;
13256
13257 switch (ts->table->afi) {
13258 case AFI_IP:
13259 space = IPV4_MAX_BITLEN;
13260 break;
13261 case AFI_IP6:
13262 space = IPV6_MAX_BITLEN;
13263 break;
13264 case AFI_L2VPN:
13265 space = EVPN_ROUTE_PREFIXLEN;
13266 break;
13267 default:
13268 return;
13269 }
13270
13271 ts->counts[BGP_STATS_MAXBITLEN] = space;
13272
13273 for (dest = top; dest; dest = bgp_route_next(dest)) {
13274 if (ts->table->safi == SAFI_MPLS_VPN
13275 || ts->table->safi == SAFI_ENCAP
13276 || ts->table->safi == SAFI_EVPN) {
13277 struct bgp_table *table;
13278
13279 table = bgp_dest_get_bgp_table_info(dest);
13280 if (!table)
13281 continue;
13282
13283 top = bgp_table_top(table);
13284 for (ndest = bgp_table_top(table); ndest;
13285 ndest = bgp_route_next(ndest))
13286 bgp_table_stats_rn(ndest, top, ts, space);
13287 } else {
13288 bgp_table_stats_rn(dest, top, ts, space);
13289 }
13290 }
13291 }
13292
13293 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13294 struct json_object *json_array)
13295 {
13296 struct listnode *node, *nnode;
13297 struct bgp *bgp;
13298
13299 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13300 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13301 }
13302
13303 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13304 safi_t safi, struct json_object *json_array)
13305 {
13306 struct bgp_table_stats ts;
13307 unsigned int i;
13308 int ret = CMD_SUCCESS;
13309 char temp_buf[20];
13310 struct json_object *json = NULL;
13311 uint32_t bitlen = 0;
13312 struct json_object *json_bitlen;
13313
13314 if (json_array)
13315 json = json_object_new_object();
13316
13317 if (!bgp->rib[afi][safi]) {
13318 char warning_msg[50];
13319
13320 snprintf(warning_msg, sizeof(warning_msg),
13321 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13322 safi);
13323
13324 if (!json)
13325 vty_out(vty, "%s\n", warning_msg);
13326 else
13327 json_object_string_add(json, "warning", warning_msg);
13328
13329 ret = CMD_WARNING;
13330 goto end_table_stats;
13331 }
13332
13333 if (!json)
13334 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13335 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13336 else
13337 json_object_string_add(json, "instance", bgp->name_pretty);
13338
13339 /* labeled-unicast routes live in the unicast table */
13340 if (safi == SAFI_LABELED_UNICAST)
13341 safi = SAFI_UNICAST;
13342
13343 memset(&ts, 0, sizeof(ts));
13344 ts.table = bgp->rib[afi][safi];
13345 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13346
13347 for (i = 0; i < BGP_STATS_MAX; i++) {
13348 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13349 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13350 continue;
13351
13352 switch (i) {
13353 case BGP_STATS_ASPATH_TOTHOPS:
13354 case BGP_STATS_ASPATH_TOTSIZE:
13355 if (!json) {
13356 snprintf(
13357 temp_buf, sizeof(temp_buf), "%12.2f",
13358 ts.counts[i]
13359 ? (float)ts.counts[i]
13360 / (float)ts.counts
13361 [BGP_STATS_ASPATH_COUNT]
13362 : 0);
13363 vty_out(vty, "%-30s: %s",
13364 table_stats_strs[i]
13365 [TABLE_STATS_IDX_VTY],
13366 temp_buf);
13367 } else {
13368 json_object_double_add(
13369 json,
13370 table_stats_strs[i]
13371 [TABLE_STATS_IDX_JSON],
13372 ts.counts[i]
13373 ? (double)ts.counts[i]
13374 / (double)ts.counts
13375 [BGP_STATS_ASPATH_COUNT]
13376 : 0);
13377 }
13378 break;
13379 case BGP_STATS_TOTPLEN:
13380 if (!json) {
13381 snprintf(
13382 temp_buf, sizeof(temp_buf), "%12.2f",
13383 ts.counts[i]
13384 ? (float)ts.counts[i]
13385 / (float)ts.counts
13386 [BGP_STATS_PREFIXES]
13387 : 0);
13388 vty_out(vty, "%-30s: %s",
13389 table_stats_strs[i]
13390 [TABLE_STATS_IDX_VTY],
13391 temp_buf);
13392 } else {
13393 json_object_double_add(
13394 json,
13395 table_stats_strs[i]
13396 [TABLE_STATS_IDX_JSON],
13397 ts.counts[i]
13398 ? (double)ts.counts[i]
13399 / (double)ts.counts
13400 [BGP_STATS_PREFIXES]
13401 : 0);
13402 }
13403 break;
13404 case BGP_STATS_SPACE:
13405 if (!json) {
13406 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13407 ts.total_space);
13408 vty_out(vty, "%-30s: %s\n",
13409 table_stats_strs[i]
13410 [TABLE_STATS_IDX_VTY],
13411 temp_buf);
13412 } else {
13413 json_object_double_add(
13414 json,
13415 table_stats_strs[i]
13416 [TABLE_STATS_IDX_JSON],
13417 (double)ts.total_space);
13418 }
13419 if (afi == AFI_IP6) {
13420 if (!json) {
13421 snprintf(temp_buf, sizeof(temp_buf),
13422 "%12g",
13423 ts.total_space
13424 * pow(2.0, -128 + 32));
13425 vty_out(vty, "%30s: %s\n",
13426 "/32 equivalent %s\n",
13427 temp_buf);
13428 } else {
13429 json_object_double_add(
13430 json, "/32equivalent",
13431 (double)(ts.total_space
13432 * pow(2.0,
13433 -128 + 32)));
13434 }
13435 if (!json) {
13436 snprintf(temp_buf, sizeof(temp_buf),
13437 "%12g",
13438 ts.total_space
13439 * pow(2.0, -128 + 48));
13440 vty_out(vty, "%30s: %s\n",
13441 "/48 equivalent %s\n",
13442 temp_buf);
13443 } else {
13444 json_object_double_add(
13445 json, "/48equivalent",
13446 (double)(ts.total_space
13447 * pow(2.0,
13448 -128 + 48)));
13449 }
13450 } else {
13451 if (!json) {
13452 snprintf(temp_buf, sizeof(temp_buf),
13453 "%12.2f",
13454 ts.total_space * 100.
13455 * pow(2.0, -32));
13456 vty_out(vty, "%30s: %s\n",
13457 "% announced ", temp_buf);
13458 } else {
13459 json_object_double_add(
13460 json, "%announced",
13461 (double)(ts.total_space * 100.
13462 * pow(2.0, -32)));
13463 }
13464 if (!json) {
13465 snprintf(temp_buf, sizeof(temp_buf),
13466 "%12.2f",
13467 ts.total_space
13468 * pow(2.0, -32 + 8));
13469 vty_out(vty, "%30s: %s\n",
13470 "/8 equivalent ", temp_buf);
13471 } else {
13472 json_object_double_add(
13473 json, "/8equivalent",
13474 (double)(ts.total_space
13475 * pow(2.0, -32 + 8)));
13476 }
13477 if (!json) {
13478 snprintf(temp_buf, sizeof(temp_buf),
13479 "%12.2f",
13480 ts.total_space
13481 * pow(2.0, -32 + 24));
13482 vty_out(vty, "%30s: %s\n",
13483 "/24 equivalent ", temp_buf);
13484 } else {
13485 json_object_double_add(
13486 json, "/24equivalent",
13487 (double)(ts.total_space
13488 * pow(2.0, -32 + 24)));
13489 }
13490 }
13491 break;
13492 default:
13493 if (!json) {
13494 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13495 ts.counts[i]);
13496 vty_out(vty, "%-30s: %s",
13497 table_stats_strs[i]
13498 [TABLE_STATS_IDX_VTY],
13499 temp_buf);
13500 } else {
13501 json_object_int_add(
13502 json,
13503 table_stats_strs[i]
13504 [TABLE_STATS_IDX_JSON],
13505 ts.counts[i]);
13506 }
13507 }
13508 if (!json)
13509 vty_out(vty, "\n");
13510 }
13511
13512 switch (afi) {
13513 case AFI_IP:
13514 bitlen = IPV4_MAX_BITLEN;
13515 break;
13516 case AFI_IP6:
13517 bitlen = IPV6_MAX_BITLEN;
13518 break;
13519 case AFI_L2VPN:
13520 bitlen = EVPN_ROUTE_PREFIXLEN;
13521 break;
13522 default:
13523 break;
13524 }
13525
13526 if (json) {
13527 json_bitlen = json_object_new_array();
13528
13529 for (i = 0; i <= bitlen; i++) {
13530 struct json_object *ind_bit = json_object_new_object();
13531
13532 if (!ts.prefix_len_count[i])
13533 continue;
13534
13535 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13536 json_object_int_add(ind_bit, temp_buf,
13537 ts.prefix_len_count[i]);
13538 json_object_array_add(json_bitlen, ind_bit);
13539 }
13540 json_object_object_add(json, "prefixLength", json_bitlen);
13541 }
13542
13543 end_table_stats:
13544 if (json)
13545 json_object_array_add(json_array, json);
13546 return ret;
13547 }
13548
13549 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13550 safi_t safi, struct json_object *json_array)
13551 {
13552 if (!bgp) {
13553 bgp_table_stats_all(vty, afi, safi, json_array);
13554 return CMD_SUCCESS;
13555 }
13556
13557 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13558 }
13559
13560 enum bgp_pcounts {
13561 PCOUNT_ADJ_IN = 0,
13562 PCOUNT_DAMPED,
13563 PCOUNT_REMOVED,
13564 PCOUNT_HISTORY,
13565 PCOUNT_STALE,
13566 PCOUNT_VALID,
13567 PCOUNT_ALL,
13568 PCOUNT_COUNTED,
13569 PCOUNT_BPATH_SELECTED,
13570 PCOUNT_PFCNT, /* the figure we display to users */
13571 PCOUNT_MAX,
13572 };
13573
13574 static const char *const pcount_strs[] = {
13575 [PCOUNT_ADJ_IN] = "Adj-in",
13576 [PCOUNT_DAMPED] = "Damped",
13577 [PCOUNT_REMOVED] = "Removed",
13578 [PCOUNT_HISTORY] = "History",
13579 [PCOUNT_STALE] = "Stale",
13580 [PCOUNT_VALID] = "Valid",
13581 [PCOUNT_ALL] = "All RIB",
13582 [PCOUNT_COUNTED] = "PfxCt counted",
13583 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13584 [PCOUNT_PFCNT] = "Useable",
13585 [PCOUNT_MAX] = NULL,
13586 };
13587
13588 struct peer_pcounts {
13589 unsigned int count[PCOUNT_MAX];
13590 const struct peer *peer;
13591 const struct bgp_table *table;
13592 safi_t safi;
13593 };
13594
13595 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13596 {
13597 const struct bgp_adj_in *ain;
13598 const struct bgp_path_info *pi;
13599 const struct peer *peer = pc->peer;
13600
13601 for (ain = rn->adj_in; ain; ain = ain->next)
13602 if (ain->peer == peer)
13603 pc->count[PCOUNT_ADJ_IN]++;
13604
13605 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13606
13607 if (pi->peer != peer)
13608 continue;
13609
13610 pc->count[PCOUNT_ALL]++;
13611
13612 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13613 pc->count[PCOUNT_DAMPED]++;
13614 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13615 pc->count[PCOUNT_HISTORY]++;
13616 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13617 pc->count[PCOUNT_REMOVED]++;
13618 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13619 pc->count[PCOUNT_STALE]++;
13620 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13621 pc->count[PCOUNT_VALID]++;
13622 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13623 pc->count[PCOUNT_PFCNT]++;
13624 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13625 pc->count[PCOUNT_BPATH_SELECTED]++;
13626
13627 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13628 pc->count[PCOUNT_COUNTED]++;
13629 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13630 flog_err(
13631 EC_LIB_DEVELOPMENT,
13632 "Attempting to count but flags say it is unusable");
13633 } else {
13634 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13635 flog_err(
13636 EC_LIB_DEVELOPMENT,
13637 "Not counted but flags say we should");
13638 }
13639 }
13640 }
13641
13642 static void bgp_peer_count_walker(struct thread *t)
13643 {
13644 struct bgp_dest *rn, *rm;
13645 const struct bgp_table *table;
13646 struct peer_pcounts *pc = THREAD_ARG(t);
13647
13648 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13649 || pc->safi == SAFI_EVPN) {
13650 /* Special handling for 2-level routing tables. */
13651 for (rn = bgp_table_top(pc->table); rn;
13652 rn = bgp_route_next(rn)) {
13653 table = bgp_dest_get_bgp_table_info(rn);
13654 if (table != NULL)
13655 for (rm = bgp_table_top(table); rm;
13656 rm = bgp_route_next(rm))
13657 bgp_peer_count_proc(rm, pc);
13658 }
13659 } else
13660 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13661 bgp_peer_count_proc(rn, pc);
13662 }
13663
13664 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13665 safi_t safi, bool use_json)
13666 {
13667 struct peer_pcounts pcounts = {.peer = peer};
13668 unsigned int i;
13669 json_object *json = NULL;
13670 json_object *json_loop = NULL;
13671
13672 if (use_json) {
13673 json = json_object_new_object();
13674 json_loop = json_object_new_object();
13675 }
13676
13677 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13678 || !peer->bgp->rib[afi][safi]) {
13679 if (use_json) {
13680 json_object_string_add(
13681 json, "warning",
13682 "No such neighbor or address family");
13683 vty_out(vty, "%s\n", json_object_to_json_string(json));
13684 json_object_free(json);
13685 json_object_free(json_loop);
13686 } else
13687 vty_out(vty, "%% No such neighbor or address family\n");
13688
13689 return CMD_WARNING;
13690 }
13691
13692 memset(&pcounts, 0, sizeof(pcounts));
13693 pcounts.peer = peer;
13694 pcounts.table = peer->bgp->rib[afi][safi];
13695 pcounts.safi = safi;
13696
13697 /* in-place call via thread subsystem so as to record execution time
13698 * stats for the thread-walk (i.e. ensure this can't be blamed on
13699 * on just vty_read()).
13700 */
13701 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13702
13703 if (use_json) {
13704 json_object_string_add(json, "prefixCountsFor", peer->host);
13705 json_object_string_add(json, "multiProtocol",
13706 get_afi_safi_str(afi, safi, true));
13707 json_object_int_add(json, "pfxCounter",
13708 peer->pcount[afi][safi]);
13709
13710 for (i = 0; i < PCOUNT_MAX; i++)
13711 json_object_int_add(json_loop, pcount_strs[i],
13712 pcounts.count[i]);
13713
13714 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13715
13716 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13717 json_object_string_add(json, "pfxctDriftFor",
13718 peer->host);
13719 json_object_string_add(
13720 json, "recommended",
13721 "Please report this bug, with the above command output");
13722 }
13723 vty_json(vty, json);
13724 } else {
13725
13726 if (peer->hostname
13727 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13728 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13729 peer->hostname, peer->host,
13730 get_afi_safi_str(afi, safi, false));
13731 } else {
13732 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13733 get_afi_safi_str(afi, safi, false));
13734 }
13735
13736 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13737 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13738
13739 for (i = 0; i < PCOUNT_MAX; i++)
13740 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13741 pcounts.count[i]);
13742
13743 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13744 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13745 vty_out(vty,
13746 "Please report this bug, with the above command output\n");
13747 }
13748 }
13749
13750 return CMD_SUCCESS;
13751 }
13752
13753 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13754 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13755 "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]",
13756 SHOW_STR
13757 IP_STR
13758 BGP_STR
13759 BGP_INSTANCE_HELP_STR
13760 BGP_AFI_HELP_STR
13761 BGP_SAFI_HELP_STR
13762 "Detailed information on TCP and BGP neighbor connections\n"
13763 "Neighbor to display information about\n"
13764 "Neighbor to display information about\n"
13765 "Neighbor on BGP configured interface\n"
13766 "Display detailed prefix count information\n"
13767 JSON_STR)
13768 {
13769 afi_t afi = AFI_IP6;
13770 safi_t safi = SAFI_UNICAST;
13771 struct peer *peer;
13772 int idx = 0;
13773 struct bgp *bgp = NULL;
13774 bool uj = use_json(argc, argv);
13775
13776 if (uj)
13777 argc--;
13778
13779 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13780 &bgp, uj);
13781 if (!idx)
13782 return CMD_WARNING;
13783
13784 argv_find(argv, argc, "neighbors", &idx);
13785 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13786 if (!peer)
13787 return CMD_WARNING;
13788
13789 return bgp_peer_counts(vty, peer, afi, safi, uj);
13790 }
13791
13792 #ifdef KEEP_OLD_VPN_COMMANDS
13793 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13794 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13795 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13796 SHOW_STR
13797 IP_STR
13798 BGP_STR
13799 BGP_VPNVX_HELP_STR
13800 "Display information about all VPNv4 NLRIs\n"
13801 "Detailed information on TCP and BGP neighbor connections\n"
13802 "Neighbor to display information about\n"
13803 "Neighbor to display information about\n"
13804 "Neighbor on BGP configured interface\n"
13805 "Display detailed prefix count information\n"
13806 JSON_STR)
13807 {
13808 int idx_peer = 6;
13809 struct peer *peer;
13810 bool uj = use_json(argc, argv);
13811
13812 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13813 if (!peer)
13814 return CMD_WARNING;
13815
13816 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13817 }
13818
13819 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13820 show_ip_bgp_vpn_all_route_prefix_cmd,
13821 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13822 SHOW_STR
13823 IP_STR
13824 BGP_STR
13825 BGP_VPNVX_HELP_STR
13826 "Display information about all VPNv4 NLRIs\n"
13827 "Network in the BGP routing table to display\n"
13828 "Network in the BGP routing table to display\n"
13829 JSON_STR)
13830 {
13831 int idx = 0;
13832 char *network = NULL;
13833 struct bgp *bgp = bgp_get_default();
13834 if (!bgp) {
13835 vty_out(vty, "Can't find default instance\n");
13836 return CMD_WARNING;
13837 }
13838
13839 if (argv_find(argv, argc, "A.B.C.D", &idx))
13840 network = argv[idx]->arg;
13841 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13842 network = argv[idx]->arg;
13843 else {
13844 vty_out(vty, "Unable to figure out Network\n");
13845 return CMD_WARNING;
13846 }
13847
13848 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13849 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13850 use_json(argc, argv));
13851 }
13852 #endif /* KEEP_OLD_VPN_COMMANDS */
13853
13854 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13855 show_bgp_l2vpn_evpn_route_prefix_cmd,
13856 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13857 SHOW_STR
13858 BGP_STR
13859 L2VPN_HELP_STR
13860 EVPN_HELP_STR
13861 "Network in the BGP routing table to display\n"
13862 "Network in the BGP routing table to display\n"
13863 "Network in the BGP routing table to display\n"
13864 "Network in the BGP routing table to display\n"
13865 JSON_STR)
13866 {
13867 int idx = 0;
13868 char *network = NULL;
13869 int prefix_check = 0;
13870
13871 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13872 argv_find(argv, argc, "X:X::X:X", &idx))
13873 network = argv[idx]->arg;
13874 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13875 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13876 network = argv[idx]->arg;
13877 prefix_check = 1;
13878 } else {
13879 vty_out(vty, "Unable to figure out Network\n");
13880 return CMD_WARNING;
13881 }
13882 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13883 prefix_check, BGP_PATH_SHOW_ALL,
13884 RPKI_NOT_BEING_USED, use_json(argc, argv));
13885 }
13886
13887 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13888 struct bgp_table *table, int *header1,
13889 int *header2, json_object *json,
13890 json_object *json_scode,
13891 json_object *json_ocode, bool wide)
13892 {
13893 uint64_t version = table ? table->version : 0;
13894
13895 if (*header1) {
13896 if (json) {
13897 json_object_int_add(json, "bgpTableVersion", version);
13898 json_object_string_addf(json, "bgpLocalRouterId",
13899 "%pI4", &peer->bgp->router_id);
13900 json_object_int_add(json, "defaultLocPrf",
13901 peer->bgp->default_local_pref);
13902 json_object_int_add(json, "localAS",
13903 peer->change_local_as
13904 ? peer->change_local_as
13905 : peer->local_as);
13906 json_object_object_add(json, "bgpStatusCodes",
13907 json_scode);
13908 json_object_object_add(json, "bgpOriginCodes",
13909 json_ocode);
13910 } else {
13911 vty_out(vty,
13912 "BGP table version is %" PRIu64
13913 ", local router ID is %pI4, vrf id ",
13914 version, &peer->bgp->router_id);
13915 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13916 vty_out(vty, "%s", VRFID_NONE_STR);
13917 else
13918 vty_out(vty, "%u", peer->bgp->vrf_id);
13919 vty_out(vty, "\n");
13920 vty_out(vty, "Default local pref %u, ",
13921 peer->bgp->default_local_pref);
13922 vty_out(vty, "local AS %u\n",
13923 peer->change_local_as ? peer->change_local_as
13924 : peer->local_as);
13925 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13926 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13927 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13928 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13929 }
13930 *header1 = 0;
13931 }
13932 if (*header2) {
13933 if (!json)
13934 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13935 : BGP_SHOW_HEADER));
13936 *header2 = 0;
13937 }
13938 }
13939
13940 static void
13941 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13942 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13943 const char *rmap_name, json_object *json, json_object *json_ar,
13944 json_object *json_scode, json_object *json_ocode,
13945 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13946 unsigned long *output_count, unsigned long *filtered_count)
13947 {
13948 struct bgp_adj_in *ain;
13949 struct bgp_adj_out *adj;
13950 struct bgp_dest *dest;
13951 struct bgp *bgp;
13952 struct attr attr;
13953 int ret;
13954 struct update_subgroup *subgrp;
13955 struct peer_af *paf;
13956 bool route_filtered;
13957 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13958 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13959 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13960 || (safi == SAFI_EVPN))
13961 ? true
13962 : false;
13963
13964 bgp = peer->bgp;
13965
13966 subgrp = peer_subgroup(peer, afi, safi);
13967
13968 if (type == bgp_show_adj_route_advertised && subgrp
13969 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13970 if (use_json) {
13971 json_object_int_add(json, "bgpTableVersion",
13972 table->version);
13973 json_object_string_addf(json, "bgpLocalRouterId",
13974 "%pI4", &bgp->router_id);
13975 json_object_int_add(json, "defaultLocPrf",
13976 bgp->default_local_pref);
13977 json_object_int_add(json, "localAS",
13978 peer->change_local_as
13979 ? peer->change_local_as
13980 : peer->local_as);
13981 json_object_object_add(json, "bgpStatusCodes",
13982 json_scode);
13983 json_object_object_add(json, "bgpOriginCodes",
13984 json_ocode);
13985 json_object_string_add(
13986 json, "bgpOriginatingDefaultNetwork",
13987 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13988 } else {
13989 vty_out(vty,
13990 "BGP table version is %" PRIu64
13991 ", local router ID is %pI4, vrf id ",
13992 table->version, &bgp->router_id);
13993 if (bgp->vrf_id == VRF_UNKNOWN)
13994 vty_out(vty, "%s", VRFID_NONE_STR);
13995 else
13996 vty_out(vty, "%u", bgp->vrf_id);
13997 vty_out(vty, "\n");
13998 vty_out(vty, "Default local pref %u, ",
13999 bgp->default_local_pref);
14000 vty_out(vty, "local AS %u\n",
14001 peer->change_local_as ? peer->change_local_as
14002 : peer->local_as);
14003 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14004 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14005 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14006 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14007
14008 vty_out(vty, "Originating default network %s\n\n",
14009 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14010 }
14011 *header1 = 0;
14012 }
14013
14014 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14015 if (type == bgp_show_adj_route_received
14016 || type == bgp_show_adj_route_filtered) {
14017 for (ain = dest->adj_in; ain; ain = ain->next) {
14018 if (ain->peer != peer)
14019 continue;
14020
14021 show_adj_route_header(vty, peer, table, header1,
14022 header2, json, json_scode,
14023 json_ocode, wide);
14024
14025 if ((safi == SAFI_MPLS_VPN)
14026 || (safi == SAFI_ENCAP)
14027 || (safi == SAFI_EVPN)) {
14028 if (use_json)
14029 json_object_string_add(
14030 json_ar, "rd", rd_str);
14031 else if (show_rd && rd_str) {
14032 vty_out(vty,
14033 "Route Distinguisher: %s\n",
14034 rd_str);
14035 show_rd = false;
14036 }
14037 }
14038
14039 attr = *ain->attr;
14040 route_filtered = false;
14041
14042 /* Filter prefix using distribute list,
14043 * filter list or prefix list
14044 */
14045 const struct prefix *rn_p =
14046 bgp_dest_get_prefix(dest);
14047 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14048 safi))
14049 == FILTER_DENY)
14050 route_filtered = true;
14051
14052 /* Filter prefix using route-map */
14053 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14054 safi, rmap_name, NULL,
14055 0, NULL);
14056
14057 if (type == bgp_show_adj_route_filtered &&
14058 !route_filtered && ret != RMAP_DENY) {
14059 bgp_attr_flush(&attr);
14060 continue;
14061 }
14062
14063 if (type == bgp_show_adj_route_received
14064 && (route_filtered || ret == RMAP_DENY))
14065 (*filtered_count)++;
14066
14067 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
14068 use_json, json_ar, wide);
14069 bgp_attr_flush(&attr);
14070 (*output_count)++;
14071 }
14072 } else if (type == bgp_show_adj_route_advertised) {
14073 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14074 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14075 if (paf->peer != peer || !adj->attr)
14076 continue;
14077
14078 show_adj_route_header(vty, peer, table,
14079 header1, header2,
14080 json, json_scode,
14081 json_ocode, wide);
14082
14083 const struct prefix *rn_p =
14084 bgp_dest_get_prefix(dest);
14085
14086 attr = *adj->attr;
14087 ret = bgp_output_modifier(
14088 peer, rn_p, &attr, afi, safi,
14089 rmap_name);
14090
14091 if (ret != RMAP_DENY) {
14092 if ((safi == SAFI_MPLS_VPN)
14093 || (safi == SAFI_ENCAP)
14094 || (safi == SAFI_EVPN)) {
14095 if (use_json)
14096 json_object_string_add(
14097 json_ar,
14098 "rd",
14099 rd_str);
14100 else if (show_rd
14101 && rd_str) {
14102 vty_out(vty,
14103 "Route Distinguisher: %s\n",
14104 rd_str);
14105 show_rd = false;
14106 }
14107 }
14108 route_vty_out_tmp(
14109 vty, dest, rn_p, &attr,
14110 safi, use_json, json_ar,
14111 wide);
14112 (*output_count)++;
14113 } else {
14114 (*filtered_count)++;
14115 }
14116
14117 bgp_attr_flush(&attr);
14118 }
14119 } else if (type == bgp_show_adj_route_bestpath) {
14120 struct bgp_path_info *pi;
14121
14122 show_adj_route_header(vty, peer, table, header1,
14123 header2, json, json_scode,
14124 json_ocode, wide);
14125
14126 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14127 pi = pi->next) {
14128 if (pi->peer != peer)
14129 continue;
14130
14131 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14132 continue;
14133
14134 route_vty_out_tmp(vty, dest,
14135 bgp_dest_get_prefix(dest),
14136 pi->attr, safi, use_json,
14137 json_ar, wide);
14138 (*output_count)++;
14139 }
14140 }
14141 }
14142 }
14143
14144 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14145 safi_t safi, enum bgp_show_adj_route_type type,
14146 const char *rmap_name, uint16_t show_flags)
14147 {
14148 struct bgp *bgp;
14149 struct bgp_table *table;
14150 json_object *json = NULL;
14151 json_object *json_scode = NULL;
14152 json_object *json_ocode = NULL;
14153 json_object *json_ar = NULL;
14154 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14155
14156 /* Init BGP headers here so they're only displayed once
14157 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14158 */
14159 int header1 = 1;
14160 int header2 = 1;
14161
14162 /*
14163 * Initialize variables for each RD
14164 * All prefixes under an RD is aggregated within "json_routes"
14165 */
14166 char rd_str[BUFSIZ] = {0};
14167 json_object *json_routes = NULL;
14168
14169
14170 /* For 2-tier tables, prefix counts need to be
14171 * maintained across multiple runs of show_adj_route()
14172 */
14173 unsigned long output_count_per_rd;
14174 unsigned long filtered_count_per_rd;
14175 unsigned long output_count = 0;
14176 unsigned long filtered_count = 0;
14177
14178 if (use_json) {
14179 json = json_object_new_object();
14180 json_ar = json_object_new_object();
14181 json_scode = json_object_new_object();
14182 json_ocode = json_object_new_object();
14183
14184 json_object_string_add(json_scode, "suppressed", "s");
14185 json_object_string_add(json_scode, "damped", "d");
14186 json_object_string_add(json_scode, "history", "h");
14187 json_object_string_add(json_scode, "valid", "*");
14188 json_object_string_add(json_scode, "best", ">");
14189 json_object_string_add(json_scode, "multipath", "=");
14190 json_object_string_add(json_scode, "internal", "i");
14191 json_object_string_add(json_scode, "ribFailure", "r");
14192 json_object_string_add(json_scode, "stale", "S");
14193 json_object_string_add(json_scode, "removed", "R");
14194
14195 json_object_string_add(json_ocode, "igp", "i");
14196 json_object_string_add(json_ocode, "egp", "e");
14197 json_object_string_add(json_ocode, "incomplete", "?");
14198 }
14199
14200 if (!peer || !peer->afc[afi][safi]) {
14201 if (use_json) {
14202 json_object_string_add(
14203 json, "warning",
14204 "No such neighbor or address family");
14205 vty_out(vty, "%s\n", json_object_to_json_string(json));
14206 json_object_free(json);
14207 json_object_free(json_ar);
14208 json_object_free(json_scode);
14209 json_object_free(json_ocode);
14210 } else
14211 vty_out(vty, "%% No such neighbor or address family\n");
14212
14213 return CMD_WARNING;
14214 }
14215
14216 if ((type == bgp_show_adj_route_received
14217 || type == bgp_show_adj_route_filtered)
14218 && !CHECK_FLAG(peer->af_flags[afi][safi],
14219 PEER_FLAG_SOFT_RECONFIG)) {
14220 if (use_json) {
14221 json_object_string_add(
14222 json, "warning",
14223 "Inbound soft reconfiguration not enabled");
14224 vty_out(vty, "%s\n", json_object_to_json_string(json));
14225 json_object_free(json);
14226 json_object_free(json_ar);
14227 json_object_free(json_scode);
14228 json_object_free(json_ocode);
14229 } else
14230 vty_out(vty,
14231 "%% Inbound soft reconfiguration not enabled\n");
14232
14233 return CMD_WARNING;
14234 }
14235
14236 bgp = peer->bgp;
14237
14238 /* labeled-unicast routes live in the unicast table */
14239 if (safi == SAFI_LABELED_UNICAST)
14240 table = bgp->rib[afi][SAFI_UNICAST];
14241 else
14242 table = bgp->rib[afi][safi];
14243
14244 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14245 || (safi == SAFI_EVPN)) {
14246
14247 struct bgp_dest *dest;
14248
14249 for (dest = bgp_table_top(table); dest;
14250 dest = bgp_route_next(dest)) {
14251 table = bgp_dest_get_bgp_table_info(dest);
14252 if (!table)
14253 continue;
14254
14255 output_count_per_rd = 0;
14256 filtered_count_per_rd = 0;
14257
14258 if (use_json)
14259 json_routes = json_object_new_object();
14260
14261 const struct prefix_rd *prd;
14262 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14263 dest);
14264
14265 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14266
14267 show_adj_route(vty, peer, table, afi, safi, type,
14268 rmap_name, json, json_routes, json_scode,
14269 json_ocode, show_flags, &header1,
14270 &header2, rd_str, &output_count_per_rd,
14271 &filtered_count_per_rd);
14272
14273 /* Don't include an empty RD in the output! */
14274 if (json_routes && (output_count_per_rd > 0))
14275 json_object_object_add(json_ar, rd_str,
14276 json_routes);
14277
14278 output_count += output_count_per_rd;
14279 filtered_count += filtered_count_per_rd;
14280 }
14281 } else
14282 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14283 json, json_ar, json_scode, json_ocode,
14284 show_flags, &header1, &header2, rd_str,
14285 &output_count, &filtered_count);
14286
14287 if (use_json) {
14288 if (type == bgp_show_adj_route_advertised)
14289 json_object_object_add(json, "advertisedRoutes",
14290 json_ar);
14291 else
14292 json_object_object_add(json, "receivedRoutes", json_ar);
14293 json_object_int_add(json, "totalPrefixCounter", output_count);
14294 json_object_int_add(json, "filteredPrefixCounter",
14295 filtered_count);
14296
14297 /*
14298 * These fields only give up ownership to `json` when `header1`
14299 * is used (set to zero). See code in `show_adj_route` and
14300 * `show_adj_route_header`.
14301 */
14302 if (header1 == 1) {
14303 json_object_free(json_scode);
14304 json_object_free(json_ocode);
14305 }
14306
14307 vty_json(vty, json);
14308 } else if (output_count > 0) {
14309 if (filtered_count > 0)
14310 vty_out(vty,
14311 "\nTotal number of prefixes %ld (%ld filtered)\n",
14312 output_count, filtered_count);
14313 else
14314 vty_out(vty, "\nTotal number of prefixes %ld\n",
14315 output_count);
14316 }
14317
14318 return CMD_SUCCESS;
14319 }
14320
14321 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14322 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14323 "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]",
14324 SHOW_STR
14325 IP_STR
14326 BGP_STR
14327 BGP_INSTANCE_HELP_STR
14328 BGP_AFI_HELP_STR
14329 BGP_SAFI_WITH_LABEL_HELP_STR
14330 "Detailed information on TCP and BGP neighbor connections\n"
14331 "Neighbor to display information about\n"
14332 "Neighbor to display information about\n"
14333 "Neighbor on BGP configured interface\n"
14334 "Display the routes selected by best path\n"
14335 JSON_STR
14336 "Increase table width for longer prefixes\n")
14337 {
14338 afi_t afi = AFI_IP6;
14339 safi_t safi = SAFI_UNICAST;
14340 char *rmap_name = NULL;
14341 char *peerstr = NULL;
14342 struct bgp *bgp = NULL;
14343 struct peer *peer;
14344 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14345 int idx = 0;
14346 uint16_t show_flags = 0;
14347
14348 if (uj)
14349 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14350
14351 if (wide)
14352 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14353
14354 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14355 &bgp, uj);
14356
14357 if (!idx)
14358 return CMD_WARNING;
14359
14360 argv_find(argv, argc, "neighbors", &idx);
14361 peerstr = argv[++idx]->arg;
14362
14363 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14364 if (!peer)
14365 return CMD_WARNING;
14366
14367 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14368 show_flags);
14369 }
14370
14371 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
14372 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14373 "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]",
14374 SHOW_STR
14375 IP_STR
14376 BGP_STR
14377 BGP_INSTANCE_HELP_STR
14378 BGP_AFI_HELP_STR
14379 BGP_SAFI_WITH_LABEL_HELP_STR
14380 "Display the entries for all address families\n"
14381 "Detailed information on TCP and BGP neighbor connections\n"
14382 "Neighbor to display information about\n"
14383 "Neighbor to display information about\n"
14384 "Neighbor on BGP configured interface\n"
14385 "Display the routes advertised to a BGP neighbor\n"
14386 "Display the received routes from neighbor\n"
14387 "Display the filtered routes received from neighbor\n"
14388 "Route-map to modify the attributes\n"
14389 "Name of the route map\n"
14390 JSON_STR
14391 "Increase table width for longer prefixes\n")
14392 {
14393 afi_t afi = AFI_IP6;
14394 safi_t safi = SAFI_UNICAST;
14395 char *peerstr = NULL;
14396 struct bgp *bgp = NULL;
14397 struct peer *peer;
14398 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14399 int idx = 0;
14400 bool first = true;
14401 uint16_t show_flags = 0;
14402 struct listnode *node;
14403 struct bgp *abgp;
14404
14405 if (uj) {
14406 argc--;
14407 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14408 }
14409
14410 if (all) {
14411 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14412 if (argv_find(argv, argc, "ipv4", &idx))
14413 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14414
14415 if (argv_find(argv, argc, "ipv6", &idx))
14416 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14417 }
14418
14419 if (wide)
14420 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14421
14422 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14423 &bgp, uj);
14424 if (!idx)
14425 return CMD_WARNING;
14426
14427 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14428 argv_find(argv, argc, "neighbors", &idx);
14429 peerstr = argv[++idx]->arg;
14430
14431 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14432 if (!peer)
14433 return CMD_WARNING;
14434
14435 if (argv_find(argv, argc, "advertised-routes", &idx))
14436 type = bgp_show_adj_route_advertised;
14437 else if (argv_find(argv, argc, "received-routes", &idx))
14438 type = bgp_show_adj_route_received;
14439 else if (argv_find(argv, argc, "filtered-routes", &idx))
14440 type = bgp_show_adj_route_filtered;
14441
14442 if (!all)
14443 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14444 show_flags);
14445 if (uj)
14446 vty_out(vty, "{\n");
14447
14448 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14449 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14450 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14451 : AFI_IP6;
14452 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14453 FOREACH_SAFI (safi) {
14454 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14455 continue;
14456
14457 if (uj) {
14458 if (first)
14459 first = false;
14460 else
14461 vty_out(vty, ",\n");
14462 vty_out(vty, "\"%s\":",
14463 get_afi_safi_str(afi, safi,
14464 true));
14465 } else
14466 vty_out(vty,
14467 "\nFor address family: %s\n",
14468 get_afi_safi_str(afi, safi,
14469 false));
14470
14471 peer_adj_routes(vty, peer, afi, safi, type,
14472 route_map, show_flags);
14473 }
14474 }
14475 } else {
14476 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14477 FOREACH_AFI_SAFI (afi, safi) {
14478 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14479 continue;
14480
14481 if (uj) {
14482 if (first)
14483 first = false;
14484 else
14485 vty_out(vty, ",\n");
14486 vty_out(vty, "\"%s\":",
14487 get_afi_safi_str(afi, safi,
14488 true));
14489 } else
14490 vty_out(vty,
14491 "\nFor address family: %s\n",
14492 get_afi_safi_str(afi, safi,
14493 false));
14494
14495 peer_adj_routes(vty, peer, afi, safi, type,
14496 route_map, show_flags);
14497 }
14498 }
14499 }
14500 if (uj)
14501 vty_out(vty, "}\n");
14502
14503 return CMD_SUCCESS;
14504 }
14505
14506 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14507 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14508 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14509 SHOW_STR
14510 IP_STR
14511 BGP_STR
14512 BGP_INSTANCE_HELP_STR
14513 BGP_AF_STR
14514 BGP_AF_STR
14515 BGP_AF_MODIFIER_STR
14516 "Detailed information on TCP and BGP neighbor connections\n"
14517 "Neighbor to display information about\n"
14518 "Neighbor to display information about\n"
14519 "Neighbor on BGP configured interface\n"
14520 "Display information received from a BGP neighbor\n"
14521 "Display the prefixlist filter\n"
14522 JSON_STR)
14523 {
14524 afi_t afi = AFI_IP6;
14525 safi_t safi = SAFI_UNICAST;
14526 char *peerstr = NULL;
14527 char name[BUFSIZ];
14528 struct peer *peer;
14529 int count;
14530 int idx = 0;
14531 struct bgp *bgp = NULL;
14532 bool uj = use_json(argc, argv);
14533
14534 if (uj)
14535 argc--;
14536
14537 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14538 &bgp, uj);
14539 if (!idx)
14540 return CMD_WARNING;
14541
14542 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14543 argv_find(argv, argc, "neighbors", &idx);
14544 peerstr = argv[++idx]->arg;
14545
14546 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14547 if (!peer)
14548 return CMD_WARNING;
14549
14550 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14551 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14552 if (count) {
14553 if (!uj)
14554 vty_out(vty, "Address Family: %s\n",
14555 get_afi_safi_str(afi, safi, false));
14556 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14557 } else {
14558 if (uj)
14559 vty_out(vty, "{}\n");
14560 else
14561 vty_out(vty, "No functional output\n");
14562 }
14563
14564 return CMD_SUCCESS;
14565 }
14566
14567 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14568 afi_t afi, safi_t safi,
14569 enum bgp_show_type type, bool use_json)
14570 {
14571 uint16_t show_flags = 0;
14572
14573 if (use_json)
14574 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14575
14576 if (!peer || !peer->afc[afi][safi]) {
14577 if (use_json) {
14578 json_object *json_no = NULL;
14579 json_no = json_object_new_object();
14580 json_object_string_add(
14581 json_no, "warning",
14582 "No such neighbor or address family");
14583 vty_out(vty, "%s\n",
14584 json_object_to_json_string(json_no));
14585 json_object_free(json_no);
14586 } else
14587 vty_out(vty, "%% No such neighbor or address family\n");
14588 return CMD_WARNING;
14589 }
14590
14591 /* labeled-unicast routes live in the unicast table */
14592 if (safi == SAFI_LABELED_UNICAST)
14593 safi = SAFI_UNICAST;
14594
14595 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14596 RPKI_NOT_BEING_USED);
14597 }
14598
14599 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14600 show_ip_bgp_flowspec_routes_detailed_cmd,
14601 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14602 SHOW_STR
14603 IP_STR
14604 BGP_STR
14605 BGP_INSTANCE_HELP_STR
14606 BGP_AFI_HELP_STR
14607 "SAFI Flowspec\n"
14608 "Detailed information on flowspec entries\n"
14609 JSON_STR)
14610 {
14611 afi_t afi = AFI_IP6;
14612 safi_t safi = SAFI_UNICAST;
14613 struct bgp *bgp = NULL;
14614 int idx = 0;
14615 bool uj = use_json(argc, argv);
14616 uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
14617
14618 if (uj) {
14619 argc--;
14620 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14621 }
14622
14623 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14624 &bgp, uj);
14625 if (!idx)
14626 return CMD_WARNING;
14627
14628 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14629 show_flags, RPKI_NOT_BEING_USED);
14630 }
14631
14632 DEFUN (show_ip_bgp_neighbor_routes,
14633 show_ip_bgp_neighbor_routes_cmd,
14634 "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]",
14635 SHOW_STR
14636 IP_STR
14637 BGP_STR
14638 BGP_INSTANCE_HELP_STR
14639 BGP_AFI_HELP_STR
14640 BGP_SAFI_WITH_LABEL_HELP_STR
14641 "Detailed information on TCP and BGP neighbor connections\n"
14642 "Neighbor to display information about\n"
14643 "Neighbor to display information about\n"
14644 "Neighbor on BGP configured interface\n"
14645 "Display flap statistics of the routes learned from neighbor\n"
14646 "Display the dampened routes received from neighbor\n"
14647 "Display routes learned from neighbor\n"
14648 JSON_STR)
14649 {
14650 char *peerstr = NULL;
14651 struct bgp *bgp = NULL;
14652 afi_t afi = AFI_IP6;
14653 safi_t safi = SAFI_UNICAST;
14654 struct peer *peer;
14655 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14656 int idx = 0;
14657 bool uj = use_json(argc, argv);
14658
14659 if (uj)
14660 argc--;
14661
14662 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14663 &bgp, uj);
14664 if (!idx)
14665 return CMD_WARNING;
14666
14667 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14668 argv_find(argv, argc, "neighbors", &idx);
14669 peerstr = argv[++idx]->arg;
14670
14671 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14672 if (!peer)
14673 return CMD_WARNING;
14674
14675 if (argv_find(argv, argc, "flap-statistics", &idx))
14676 sh_type = bgp_show_type_flap_neighbor;
14677 else if (argv_find(argv, argc, "dampened-routes", &idx))
14678 sh_type = bgp_show_type_damp_neighbor;
14679 else if (argv_find(argv, argc, "routes", &idx))
14680 sh_type = bgp_show_type_neighbor;
14681
14682 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14683 }
14684
14685 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14686
14687 struct bgp_distance {
14688 /* Distance value for the IP source prefix. */
14689 uint8_t distance;
14690
14691 /* Name of the access-list to be matched. */
14692 char *access_list;
14693 };
14694
14695 DEFUN (show_bgp_afi_vpn_rd_route,
14696 show_bgp_afi_vpn_rd_route_cmd,
14697 "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]",
14698 SHOW_STR
14699 BGP_STR
14700 BGP_AFI_HELP_STR
14701 BGP_AF_MODIFIER_STR
14702 "Display information for a route distinguisher\n"
14703 "Route Distinguisher\n"
14704 "All Route Distinguishers\n"
14705 "Network in the BGP routing table to display\n"
14706 "Network in the BGP routing table to display\n"
14707 JSON_STR)
14708 {
14709 int ret;
14710 struct prefix_rd prd;
14711 afi_t afi = AFI_MAX;
14712 int idx = 0;
14713
14714 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14715 vty_out(vty, "%% Malformed Address Family\n");
14716 return CMD_WARNING;
14717 }
14718
14719 if (!strcmp(argv[5]->arg, "all"))
14720 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14721 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14722 RPKI_NOT_BEING_USED,
14723 use_json(argc, argv));
14724
14725 ret = str2prefix_rd(argv[5]->arg, &prd);
14726 if (!ret) {
14727 vty_out(vty, "%% Malformed Route Distinguisher\n");
14728 return CMD_WARNING;
14729 }
14730
14731 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14732 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14733 use_json(argc, argv));
14734 }
14735
14736 static struct bgp_distance *bgp_distance_new(void)
14737 {
14738 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14739 }
14740
14741 static void bgp_distance_free(struct bgp_distance *bdistance)
14742 {
14743 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14744 }
14745
14746 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14747 const char *ip_str, const char *access_list_str)
14748 {
14749 int ret;
14750 afi_t afi;
14751 safi_t safi;
14752 struct prefix p;
14753 uint8_t distance;
14754 struct bgp_dest *dest;
14755 struct bgp_distance *bdistance;
14756
14757 afi = bgp_node_afi(vty);
14758 safi = bgp_node_safi(vty);
14759
14760 ret = str2prefix(ip_str, &p);
14761 if (ret == 0) {
14762 vty_out(vty, "Malformed prefix\n");
14763 return CMD_WARNING_CONFIG_FAILED;
14764 }
14765
14766 distance = atoi(distance_str);
14767
14768 /* Get BGP distance node. */
14769 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14770 bdistance = bgp_dest_get_bgp_distance_info(dest);
14771 if (bdistance)
14772 bgp_dest_unlock_node(dest);
14773 else {
14774 bdistance = bgp_distance_new();
14775 bgp_dest_set_bgp_distance_info(dest, bdistance);
14776 }
14777
14778 /* Set distance value. */
14779 bdistance->distance = distance;
14780
14781 /* Reset access-list configuration. */
14782 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14783 if (access_list_str)
14784 bdistance->access_list =
14785 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14786
14787 return CMD_SUCCESS;
14788 }
14789
14790 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14791 const char *ip_str, const char *access_list_str)
14792 {
14793 int ret;
14794 afi_t afi;
14795 safi_t safi;
14796 struct prefix p;
14797 int distance;
14798 struct bgp_dest *dest;
14799 struct bgp_distance *bdistance;
14800
14801 afi = bgp_node_afi(vty);
14802 safi = bgp_node_safi(vty);
14803
14804 ret = str2prefix(ip_str, &p);
14805 if (ret == 0) {
14806 vty_out(vty, "Malformed prefix\n");
14807 return CMD_WARNING_CONFIG_FAILED;
14808 }
14809
14810 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14811 if (!dest) {
14812 vty_out(vty, "Can't find specified prefix\n");
14813 return CMD_WARNING_CONFIG_FAILED;
14814 }
14815
14816 bdistance = bgp_dest_get_bgp_distance_info(dest);
14817 distance = atoi(distance_str);
14818
14819 if (bdistance->distance != distance) {
14820 vty_out(vty, "Distance does not match configured\n");
14821 bgp_dest_unlock_node(dest);
14822 return CMD_WARNING_CONFIG_FAILED;
14823 }
14824
14825 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14826 bgp_distance_free(bdistance);
14827
14828 bgp_dest_set_bgp_path_info(dest, NULL);
14829 bgp_dest_unlock_node(dest);
14830 bgp_dest_unlock_node(dest);
14831
14832 return CMD_SUCCESS;
14833 }
14834
14835 /* Apply BGP information to distance method. */
14836 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14837 afi_t afi, safi_t safi, struct bgp *bgp)
14838 {
14839 struct bgp_dest *dest;
14840 struct prefix q = {0};
14841 struct peer *peer;
14842 struct bgp_distance *bdistance;
14843 struct access_list *alist;
14844 struct bgp_static *bgp_static;
14845
14846 if (!bgp)
14847 return 0;
14848
14849 peer = pinfo->peer;
14850
14851 if (pinfo->attr->distance)
14852 return pinfo->attr->distance;
14853
14854 /* Check source address.
14855 * Note: for aggregate route, peer can have unspec af type.
14856 */
14857 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14858 && !sockunion2hostprefix(&peer->su, &q))
14859 return 0;
14860
14861 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14862 if (dest) {
14863 bdistance = bgp_dest_get_bgp_distance_info(dest);
14864 bgp_dest_unlock_node(dest);
14865
14866 if (bdistance->access_list) {
14867 alist = access_list_lookup(afi, bdistance->access_list);
14868 if (alist
14869 && access_list_apply(alist, p) == FILTER_PERMIT)
14870 return bdistance->distance;
14871 } else
14872 return bdistance->distance;
14873 }
14874
14875 /* Backdoor check. */
14876 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14877 if (dest) {
14878 bgp_static = bgp_dest_get_bgp_static_info(dest);
14879 bgp_dest_unlock_node(dest);
14880
14881 if (bgp_static->backdoor) {
14882 if (bgp->distance_local[afi][safi])
14883 return bgp->distance_local[afi][safi];
14884 else
14885 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14886 }
14887 }
14888
14889 if (peer->sort == BGP_PEER_EBGP) {
14890 if (bgp->distance_ebgp[afi][safi])
14891 return bgp->distance_ebgp[afi][safi];
14892 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14893 } else if (peer->sort == BGP_PEER_IBGP) {
14894 if (bgp->distance_ibgp[afi][safi])
14895 return bgp->distance_ibgp[afi][safi];
14896 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14897 } else {
14898 if (bgp->distance_local[afi][safi])
14899 return bgp->distance_local[afi][safi];
14900 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14901 }
14902 }
14903
14904 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14905 * we should tell ZEBRA update the routes for a specific
14906 * AFI/SAFI to reflect changes in RIB.
14907 */
14908 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14909 afi_t update_afi,
14910 safi_t update_safi)
14911 {
14912 afi_t afi;
14913 safi_t safi;
14914
14915 FOREACH_AFI_SAFI (afi, safi) {
14916 if (!bgp_fibupd_safi(safi))
14917 continue;
14918
14919 if (afi != update_afi && safi != update_safi)
14920 continue;
14921
14922 if (BGP_DEBUG(zebra, ZEBRA))
14923 zlog_debug(
14924 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14925 __func__, afi, safi);
14926 bgp_zebra_announce_table(bgp, afi, safi);
14927 }
14928 }
14929
14930 DEFUN (bgp_distance,
14931 bgp_distance_cmd,
14932 "distance bgp (1-255) (1-255) (1-255)",
14933 "Define an administrative distance\n"
14934 "BGP distance\n"
14935 "Distance for routes external to the AS\n"
14936 "Distance for routes internal to the AS\n"
14937 "Distance for local routes\n")
14938 {
14939 VTY_DECLVAR_CONTEXT(bgp, bgp);
14940 int idx_number = 2;
14941 int idx_number_2 = 3;
14942 int idx_number_3 = 4;
14943 int distance_ebgp = atoi(argv[idx_number]->arg);
14944 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14945 int distance_local = atoi(argv[idx_number_3]->arg);
14946 afi_t afi;
14947 safi_t safi;
14948
14949 afi = bgp_node_afi(vty);
14950 safi = bgp_node_safi(vty);
14951
14952 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14953 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14954 || bgp->distance_local[afi][safi] != distance_local) {
14955 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14956 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14957 bgp->distance_local[afi][safi] = distance_local;
14958 bgp_announce_routes_distance_update(bgp, afi, safi);
14959 }
14960 return CMD_SUCCESS;
14961 }
14962
14963 DEFUN (no_bgp_distance,
14964 no_bgp_distance_cmd,
14965 "no distance bgp [(1-255) (1-255) (1-255)]",
14966 NO_STR
14967 "Define an administrative distance\n"
14968 "BGP distance\n"
14969 "Distance for routes external to the AS\n"
14970 "Distance for routes internal to the AS\n"
14971 "Distance for local routes\n")
14972 {
14973 VTY_DECLVAR_CONTEXT(bgp, bgp);
14974 afi_t afi;
14975 safi_t safi;
14976
14977 afi = bgp_node_afi(vty);
14978 safi = bgp_node_safi(vty);
14979
14980 if (bgp->distance_ebgp[afi][safi] != 0
14981 || bgp->distance_ibgp[afi][safi] != 0
14982 || bgp->distance_local[afi][safi] != 0) {
14983 bgp->distance_ebgp[afi][safi] = 0;
14984 bgp->distance_ibgp[afi][safi] = 0;
14985 bgp->distance_local[afi][safi] = 0;
14986 bgp_announce_routes_distance_update(bgp, afi, safi);
14987 }
14988 return CMD_SUCCESS;
14989 }
14990
14991
14992 DEFUN (bgp_distance_source,
14993 bgp_distance_source_cmd,
14994 "distance (1-255) A.B.C.D/M",
14995 "Define an administrative distance\n"
14996 "Administrative distance\n"
14997 "IP source prefix\n")
14998 {
14999 int idx_number = 1;
15000 int idx_ipv4_prefixlen = 2;
15001 bgp_distance_set(vty, argv[idx_number]->arg,
15002 argv[idx_ipv4_prefixlen]->arg, NULL);
15003 return CMD_SUCCESS;
15004 }
15005
15006 DEFUN (no_bgp_distance_source,
15007 no_bgp_distance_source_cmd,
15008 "no distance (1-255) A.B.C.D/M",
15009 NO_STR
15010 "Define an administrative distance\n"
15011 "Administrative distance\n"
15012 "IP source prefix\n")
15013 {
15014 int idx_number = 2;
15015 int idx_ipv4_prefixlen = 3;
15016 bgp_distance_unset(vty, argv[idx_number]->arg,
15017 argv[idx_ipv4_prefixlen]->arg, NULL);
15018 return CMD_SUCCESS;
15019 }
15020
15021 DEFUN (bgp_distance_source_access_list,
15022 bgp_distance_source_access_list_cmd,
15023 "distance (1-255) A.B.C.D/M WORD",
15024 "Define an administrative distance\n"
15025 "Administrative distance\n"
15026 "IP source prefix\n"
15027 "Access list name\n")
15028 {
15029 int idx_number = 1;
15030 int idx_ipv4_prefixlen = 2;
15031 int idx_word = 3;
15032 bgp_distance_set(vty, argv[idx_number]->arg,
15033 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15034 return CMD_SUCCESS;
15035 }
15036
15037 DEFUN (no_bgp_distance_source_access_list,
15038 no_bgp_distance_source_access_list_cmd,
15039 "no distance (1-255) A.B.C.D/M WORD",
15040 NO_STR
15041 "Define an administrative distance\n"
15042 "Administrative distance\n"
15043 "IP source prefix\n"
15044 "Access list name\n")
15045 {
15046 int idx_number = 2;
15047 int idx_ipv4_prefixlen = 3;
15048 int idx_word = 4;
15049 bgp_distance_unset(vty, argv[idx_number]->arg,
15050 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15051 return CMD_SUCCESS;
15052 }
15053
15054 DEFUN (ipv6_bgp_distance_source,
15055 ipv6_bgp_distance_source_cmd,
15056 "distance (1-255) X:X::X:X/M",
15057 "Define an administrative distance\n"
15058 "Administrative distance\n"
15059 "IP source prefix\n")
15060 {
15061 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15062 return CMD_SUCCESS;
15063 }
15064
15065 DEFUN (no_ipv6_bgp_distance_source,
15066 no_ipv6_bgp_distance_source_cmd,
15067 "no distance (1-255) X:X::X:X/M",
15068 NO_STR
15069 "Define an administrative distance\n"
15070 "Administrative distance\n"
15071 "IP source prefix\n")
15072 {
15073 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15074 return CMD_SUCCESS;
15075 }
15076
15077 DEFUN (ipv6_bgp_distance_source_access_list,
15078 ipv6_bgp_distance_source_access_list_cmd,
15079 "distance (1-255) X:X::X:X/M WORD",
15080 "Define an administrative distance\n"
15081 "Administrative distance\n"
15082 "IP source prefix\n"
15083 "Access list name\n")
15084 {
15085 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15086 return CMD_SUCCESS;
15087 }
15088
15089 DEFUN (no_ipv6_bgp_distance_source_access_list,
15090 no_ipv6_bgp_distance_source_access_list_cmd,
15091 "no distance (1-255) X:X::X:X/M WORD",
15092 NO_STR
15093 "Define an administrative distance\n"
15094 "Administrative distance\n"
15095 "IP source prefix\n"
15096 "Access list name\n")
15097 {
15098 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15099 return CMD_SUCCESS;
15100 }
15101
15102 DEFUN (bgp_damp_set,
15103 bgp_damp_set_cmd,
15104 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15105 "BGP Specific commands\n"
15106 "Enable route-flap dampening\n"
15107 "Half-life time for the penalty\n"
15108 "Value to start reusing a route\n"
15109 "Value to start suppressing a route\n"
15110 "Maximum duration to suppress a stable route\n")
15111 {
15112 VTY_DECLVAR_CONTEXT(bgp, bgp);
15113 int idx_half_life = 2;
15114 int idx_reuse = 3;
15115 int idx_suppress = 4;
15116 int idx_max_suppress = 5;
15117 int half = DEFAULT_HALF_LIFE * 60;
15118 int reuse = DEFAULT_REUSE;
15119 int suppress = DEFAULT_SUPPRESS;
15120 int max = 4 * half;
15121
15122 if (argc == 6) {
15123 half = atoi(argv[idx_half_life]->arg) * 60;
15124 reuse = atoi(argv[idx_reuse]->arg);
15125 suppress = atoi(argv[idx_suppress]->arg);
15126 max = atoi(argv[idx_max_suppress]->arg) * 60;
15127 } else if (argc == 3) {
15128 half = atoi(argv[idx_half_life]->arg) * 60;
15129 max = 4 * half;
15130 }
15131
15132 /*
15133 * These can't be 0 but our SA doesn't understand the
15134 * way our cli is constructed
15135 */
15136 assert(reuse);
15137 assert(half);
15138 if (suppress < reuse) {
15139 vty_out(vty,
15140 "Suppress value cannot be less than reuse value \n");
15141 return 0;
15142 }
15143
15144 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15145 reuse, suppress, max);
15146 }
15147
15148 DEFUN (bgp_damp_unset,
15149 bgp_damp_unset_cmd,
15150 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15151 NO_STR
15152 "BGP Specific commands\n"
15153 "Enable route-flap dampening\n"
15154 "Half-life time for the penalty\n"
15155 "Value to start reusing a route\n"
15156 "Value to start suppressing a route\n"
15157 "Maximum duration to suppress a stable route\n")
15158 {
15159 VTY_DECLVAR_CONTEXT(bgp, bgp);
15160 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15161 }
15162
15163 /* Display specified route of BGP table. */
15164 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15165 const char *ip_str, afi_t afi, safi_t safi,
15166 struct prefix_rd *prd, int prefix_check)
15167 {
15168 int ret;
15169 struct prefix match;
15170 struct bgp_dest *dest;
15171 struct bgp_dest *rm;
15172 struct bgp_path_info *pi;
15173 struct bgp_path_info *pi_temp;
15174 struct bgp *bgp;
15175 struct bgp_table *table;
15176
15177 /* BGP structure lookup. */
15178 if (view_name) {
15179 bgp = bgp_lookup_by_name(view_name);
15180 if (bgp == NULL) {
15181 vty_out(vty, "%% Can't find BGP instance %s\n",
15182 view_name);
15183 return CMD_WARNING;
15184 }
15185 } else {
15186 bgp = bgp_get_default();
15187 if (bgp == NULL) {
15188 vty_out(vty, "%% No BGP process is configured\n");
15189 return CMD_WARNING;
15190 }
15191 }
15192
15193 /* Check IP address argument. */
15194 ret = str2prefix(ip_str, &match);
15195 if (!ret) {
15196 vty_out(vty, "%% address is malformed\n");
15197 return CMD_WARNING;
15198 }
15199
15200 match.family = afi2family(afi);
15201
15202 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15203 || (safi == SAFI_EVPN)) {
15204 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15205 dest = bgp_route_next(dest)) {
15206 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15207
15208 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15209 continue;
15210 table = bgp_dest_get_bgp_table_info(dest);
15211 if (!table)
15212 continue;
15213 rm = bgp_node_match(table, &match);
15214 if (rm == NULL)
15215 continue;
15216
15217 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15218
15219 if (!prefix_check
15220 || rm_p->prefixlen == match.prefixlen) {
15221 pi = bgp_dest_get_bgp_path_info(rm);
15222 while (pi) {
15223 if (pi->extra && pi->extra->damp_info) {
15224 pi_temp = pi->next;
15225 bgp_damp_info_free(
15226 pi->extra->damp_info,
15227 1, afi, safi);
15228 pi = pi_temp;
15229 } else
15230 pi = pi->next;
15231 }
15232 }
15233
15234 bgp_dest_unlock_node(rm);
15235 }
15236 } else {
15237 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15238 if (dest != NULL) {
15239 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15240
15241 if (!prefix_check
15242 || dest_p->prefixlen == match.prefixlen) {
15243 pi = bgp_dest_get_bgp_path_info(dest);
15244 while (pi) {
15245 if (pi->extra && pi->extra->damp_info) {
15246 pi_temp = pi->next;
15247 bgp_damp_info_free(
15248 pi->extra->damp_info,
15249 1, afi, safi);
15250 pi = pi_temp;
15251 } else
15252 pi = pi->next;
15253 }
15254 }
15255
15256 bgp_dest_unlock_node(dest);
15257 }
15258 }
15259
15260 return CMD_SUCCESS;
15261 }
15262
15263 DEFUN (clear_ip_bgp_dampening,
15264 clear_ip_bgp_dampening_cmd,
15265 "clear ip bgp dampening",
15266 CLEAR_STR
15267 IP_STR
15268 BGP_STR
15269 "Clear route flap dampening information\n")
15270 {
15271 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15272 return CMD_SUCCESS;
15273 }
15274
15275 DEFUN (clear_ip_bgp_dampening_prefix,
15276 clear_ip_bgp_dampening_prefix_cmd,
15277 "clear ip bgp dampening A.B.C.D/M",
15278 CLEAR_STR
15279 IP_STR
15280 BGP_STR
15281 "Clear route flap dampening information\n"
15282 "IPv4 prefix\n")
15283 {
15284 int idx_ipv4_prefixlen = 4;
15285 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15286 AFI_IP, SAFI_UNICAST, NULL, 1);
15287 }
15288
15289 DEFUN (clear_ip_bgp_dampening_address,
15290 clear_ip_bgp_dampening_address_cmd,
15291 "clear ip bgp dampening A.B.C.D",
15292 CLEAR_STR
15293 IP_STR
15294 BGP_STR
15295 "Clear route flap dampening information\n"
15296 "Network to clear damping information\n")
15297 {
15298 int idx_ipv4 = 4;
15299 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15300 SAFI_UNICAST, NULL, 0);
15301 }
15302
15303 DEFUN (clear_ip_bgp_dampening_address_mask,
15304 clear_ip_bgp_dampening_address_mask_cmd,
15305 "clear ip bgp dampening A.B.C.D A.B.C.D",
15306 CLEAR_STR
15307 IP_STR
15308 BGP_STR
15309 "Clear route flap dampening information\n"
15310 "Network to clear damping information\n"
15311 "Network mask\n")
15312 {
15313 int idx_ipv4 = 4;
15314 int idx_ipv4_2 = 5;
15315 int ret;
15316 char prefix_str[BUFSIZ];
15317
15318 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15319 prefix_str, sizeof(prefix_str));
15320 if (!ret) {
15321 vty_out(vty, "%% Inconsistent address and mask\n");
15322 return CMD_WARNING;
15323 }
15324
15325 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15326 NULL, 0);
15327 }
15328
15329 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15330 {
15331 struct vty *vty = arg;
15332 struct peer *peer = bucket->data;
15333
15334 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15335 }
15336
15337 DEFUN (show_bgp_listeners,
15338 show_bgp_listeners_cmd,
15339 "show bgp listeners",
15340 SHOW_STR
15341 BGP_STR
15342 "Display Listen Sockets and who created them\n")
15343 {
15344 bgp_dump_listener_info(vty);
15345
15346 return CMD_SUCCESS;
15347 }
15348
15349 DEFUN (show_bgp_peerhash,
15350 show_bgp_peerhash_cmd,
15351 "show bgp peerhash",
15352 SHOW_STR
15353 BGP_STR
15354 "Display information about the BGP peerhash\n")
15355 {
15356 struct list *instances = bm->bgp;
15357 struct listnode *node;
15358 struct bgp *bgp;
15359
15360 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15361 vty_out(vty, "BGP: %s\n", bgp->name);
15362 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15363 vty);
15364 }
15365
15366 return CMD_SUCCESS;
15367 }
15368
15369 /* also used for encap safi */
15370 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15371 afi_t afi, safi_t safi)
15372 {
15373 struct bgp_dest *pdest;
15374 struct bgp_dest *dest;
15375 struct bgp_table *table;
15376 const struct prefix *p;
15377 const struct prefix_rd *prd;
15378 struct bgp_static *bgp_static;
15379 mpls_label_t label;
15380
15381 /* Network configuration. */
15382 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15383 pdest = bgp_route_next(pdest)) {
15384 table = bgp_dest_get_bgp_table_info(pdest);
15385 if (!table)
15386 continue;
15387
15388 for (dest = bgp_table_top(table); dest;
15389 dest = bgp_route_next(dest)) {
15390 bgp_static = bgp_dest_get_bgp_static_info(dest);
15391 if (bgp_static == NULL)
15392 continue;
15393
15394 p = bgp_dest_get_prefix(dest);
15395 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15396 pdest);
15397
15398 /* "network" configuration display. */
15399 label = decode_label(&bgp_static->label);
15400
15401 vty_out(vty, " network %pFX rd %pRD", p, prd);
15402 if (safi == SAFI_MPLS_VPN)
15403 vty_out(vty, " label %u", label);
15404
15405 if (bgp_static->rmap.name)
15406 vty_out(vty, " route-map %s",
15407 bgp_static->rmap.name);
15408
15409 if (bgp_static->backdoor)
15410 vty_out(vty, " backdoor");
15411
15412 vty_out(vty, "\n");
15413 }
15414 }
15415 }
15416
15417 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15418 afi_t afi, safi_t safi)
15419 {
15420 struct bgp_dest *pdest;
15421 struct bgp_dest *dest;
15422 struct bgp_table *table;
15423 const struct prefix *p;
15424 const struct prefix_rd *prd;
15425 struct bgp_static *bgp_static;
15426 char buf[PREFIX_STRLEN * 2];
15427 char buf2[SU_ADDRSTRLEN];
15428 char esi_buf[ESI_STR_LEN];
15429
15430 /* Network configuration. */
15431 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15432 pdest = bgp_route_next(pdest)) {
15433 table = bgp_dest_get_bgp_table_info(pdest);
15434 if (!table)
15435 continue;
15436
15437 for (dest = bgp_table_top(table); dest;
15438 dest = bgp_route_next(dest)) {
15439 bgp_static = bgp_dest_get_bgp_static_info(dest);
15440 if (bgp_static == NULL)
15441 continue;
15442
15443 char *macrouter = NULL;
15444
15445 if (bgp_static->router_mac)
15446 macrouter = prefix_mac2str(
15447 bgp_static->router_mac, NULL, 0);
15448 if (bgp_static->eth_s_id)
15449 esi_to_str(bgp_static->eth_s_id,
15450 esi_buf, sizeof(esi_buf));
15451 p = bgp_dest_get_prefix(dest);
15452 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15453
15454 /* "network" configuration display. */
15455 if (p->u.prefix_evpn.route_type == 5) {
15456 char local_buf[PREFIX_STRLEN];
15457 uint8_t family = is_evpn_prefix_ipaddr_v4((
15458 struct prefix_evpn *)p)
15459 ? AF_INET
15460 : AF_INET6;
15461 inet_ntop(family,
15462 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15463 local_buf, PREFIX_STRLEN);
15464 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15465 p->u.prefix_evpn.prefix_addr
15466 .ip_prefix_length);
15467 } else {
15468 prefix2str(p, buf, sizeof(buf));
15469 }
15470
15471 if (bgp_static->gatewayIp.family == AF_INET
15472 || bgp_static->gatewayIp.family == AF_INET6)
15473 inet_ntop(bgp_static->gatewayIp.family,
15474 &bgp_static->gatewayIp.u.prefix, buf2,
15475 sizeof(buf2));
15476 vty_out(vty,
15477 " network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
15478 buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
15479 decode_label(&bgp_static->label), esi_buf, buf2,
15480 macrouter);
15481
15482 XFREE(MTYPE_TMP, macrouter);
15483 }
15484 }
15485 }
15486
15487 /* Configuration of static route announcement and aggregate
15488 information. */
15489 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15490 safi_t safi)
15491 {
15492 struct bgp_dest *dest;
15493 const struct prefix *p;
15494 struct bgp_static *bgp_static;
15495 struct bgp_aggregate *bgp_aggregate;
15496
15497 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15498 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15499 return;
15500 }
15501
15502 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15503 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15504 return;
15505 }
15506
15507 /* Network configuration. */
15508 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15509 dest = bgp_route_next(dest)) {
15510 bgp_static = bgp_dest_get_bgp_static_info(dest);
15511 if (bgp_static == NULL)
15512 continue;
15513
15514 p = bgp_dest_get_prefix(dest);
15515
15516 vty_out(vty, " network %pFX", p);
15517
15518 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15519 vty_out(vty, " label-index %u",
15520 bgp_static->label_index);
15521
15522 if (bgp_static->rmap.name)
15523 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15524
15525 if (bgp_static->backdoor)
15526 vty_out(vty, " backdoor");
15527
15528 vty_out(vty, "\n");
15529 }
15530
15531 /* Aggregate-address configuration. */
15532 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15533 dest = bgp_route_next(dest)) {
15534 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15535 if (bgp_aggregate == NULL)
15536 continue;
15537
15538 p = bgp_dest_get_prefix(dest);
15539
15540 vty_out(vty, " aggregate-address %pFX", p);
15541
15542 if (bgp_aggregate->as_set)
15543 vty_out(vty, " as-set");
15544
15545 if (bgp_aggregate->summary_only)
15546 vty_out(vty, " summary-only");
15547
15548 if (bgp_aggregate->rmap.name)
15549 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15550
15551 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15552 vty_out(vty, " origin %s",
15553 bgp_origin2str(bgp_aggregate->origin));
15554
15555 if (bgp_aggregate->match_med)
15556 vty_out(vty, " matching-MED-only");
15557
15558 if (bgp_aggregate->suppress_map_name)
15559 vty_out(vty, " suppress-map %s",
15560 bgp_aggregate->suppress_map_name);
15561
15562 vty_out(vty, "\n");
15563 }
15564 }
15565
15566 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15567 safi_t safi)
15568 {
15569 struct bgp_dest *dest;
15570 struct bgp_distance *bdistance;
15571
15572 /* Distance configuration. */
15573 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15574 && bgp->distance_local[afi][safi]
15575 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15576 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15577 || bgp->distance_local[afi][safi]
15578 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15579 vty_out(vty, " distance bgp %d %d %d\n",
15580 bgp->distance_ebgp[afi][safi],
15581 bgp->distance_ibgp[afi][safi],
15582 bgp->distance_local[afi][safi]);
15583 }
15584
15585 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15586 dest = bgp_route_next(dest)) {
15587 bdistance = bgp_dest_get_bgp_distance_info(dest);
15588 if (bdistance != NULL)
15589 vty_out(vty, " distance %d %pBD %s\n",
15590 bdistance->distance, dest,
15591 bdistance->access_list ? bdistance->access_list
15592 : "");
15593 }
15594 }
15595
15596 /* Allocate routing table structure and install commands. */
15597 void bgp_route_init(void)
15598 {
15599 afi_t afi;
15600 safi_t safi;
15601
15602 /* Init BGP distance table. */
15603 FOREACH_AFI_SAFI (afi, safi)
15604 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15605
15606 /* IPv4 BGP commands. */
15607 install_element(BGP_NODE, &bgp_table_map_cmd);
15608 install_element(BGP_NODE, &bgp_network_cmd);
15609 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15610
15611 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15612
15613 /* IPv4 unicast configuration. */
15614 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15615 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15616 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15617
15618 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15619
15620 /* IPv4 multicast configuration. */
15621 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15622 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15623 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15624 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15625
15626 /* IPv4 labeled-unicast configuration. */
15627 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15628 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15629
15630 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15631 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15632 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15633 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15634 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15635 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15636 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15637 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15638
15639 install_element(VIEW_NODE,
15640 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15641 install_element(VIEW_NODE,
15642 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15643 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15644 install_element(VIEW_NODE,
15645 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15646 #ifdef KEEP_OLD_VPN_COMMANDS
15647 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15648 #endif /* KEEP_OLD_VPN_COMMANDS */
15649 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15650 install_element(VIEW_NODE,
15651 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15652
15653 /* BGP dampening clear commands */
15654 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15655 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15656
15657 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15658 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15659
15660 /* prefix count */
15661 install_element(ENABLE_NODE,
15662 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15663 #ifdef KEEP_OLD_VPN_COMMANDS
15664 install_element(ENABLE_NODE,
15665 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15666 #endif /* KEEP_OLD_VPN_COMMANDS */
15667
15668 /* New config IPv6 BGP commands. */
15669 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15670 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15671 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15672
15673 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15674
15675 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15676
15677 /* IPv6 labeled unicast address family. */
15678 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15679 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15680
15681 install_element(BGP_NODE, &bgp_distance_cmd);
15682 install_element(BGP_NODE, &no_bgp_distance_cmd);
15683 install_element(BGP_NODE, &bgp_distance_source_cmd);
15684 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15685 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15686 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15687 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15688 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15689 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15690 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15691 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15692 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15693 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15694 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15695 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15696 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15697 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15698 install_element(BGP_IPV4M_NODE,
15699 &no_bgp_distance_source_access_list_cmd);
15700 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15701 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15702 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15703 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15704 install_element(BGP_IPV6_NODE,
15705 &ipv6_bgp_distance_source_access_list_cmd);
15706 install_element(BGP_IPV6_NODE,
15707 &no_ipv6_bgp_distance_source_access_list_cmd);
15708 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15709 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15710 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15711 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15712 install_element(BGP_IPV6M_NODE,
15713 &ipv6_bgp_distance_source_access_list_cmd);
15714 install_element(BGP_IPV6M_NODE,
15715 &no_ipv6_bgp_distance_source_access_list_cmd);
15716
15717 /* BGP dampening */
15718 install_element(BGP_NODE, &bgp_damp_set_cmd);
15719 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15720 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15721 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15722 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15723 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15724 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15725 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15726 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15727 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15728 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15729 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15730 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15731 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15732
15733 /* Large Communities */
15734 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15735 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15736
15737 /* show bgp ipv4 flowspec detailed */
15738 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15739
15740 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15741 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15742 }
15743
15744 void bgp_route_finish(void)
15745 {
15746 afi_t afi;
15747 safi_t safi;
15748
15749 FOREACH_AFI_SAFI (afi, safi) {
15750 bgp_table_unlock(bgp_distance_table[afi][safi]);
15751 bgp_distance_table[afi][safi] = NULL;
15752 }
15753 }