]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
topotest: add test for confederation
[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 #include "bgpd/bgp_route_clippy.c"
94
95 DEFINE_HOOK(bgp_snmp_update_stats,
96 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
97 (rn, pi, added));
98
99 DEFINE_HOOK(bgp_rpki_prefix_status,
100 (struct peer *peer, struct attr *attr,
101 const struct prefix *prefix),
102 (peer, attr, prefix));
103
104 /* Extern from bgp_dump.c */
105 extern const char *bgp_origin_str[];
106 extern const char *bgp_origin_long_str[];
107
108 /* PMSI strings. */
109 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
110 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
111 static const struct message bgp_pmsi_tnltype_str[] = {
112 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
113 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
114 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
115 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
116 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
117 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
118 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
119 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
120 {0}
121 };
122
123 #define VRFID_NONE_STR "-"
124 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
125
126 DEFINE_HOOK(bgp_process,
127 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
128 struct peer *peer, bool withdraw),
129 (bgp, afi, safi, bn, peer, withdraw));
130
131 /** Test if path is suppressed. */
132 static bool bgp_path_suppressed(struct bgp_path_info *pi)
133 {
134 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
135 return false;
136
137 return listcount(pi->extra->aggr_suppressors) > 0;
138 }
139
140 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
141 safi_t safi, const struct prefix *p,
142 struct prefix_rd *prd)
143 {
144 struct bgp_dest *dest;
145 struct bgp_dest *pdest = NULL;
146
147 assert(table);
148
149 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
150 || (safi == SAFI_EVPN)) {
151 pdest = bgp_node_get(table, (struct prefix *)prd);
152
153 if (!bgp_dest_has_bgp_path_info_data(pdest))
154 bgp_dest_set_bgp_table_info(
155 pdest, bgp_table_init(table->bgp, afi, safi));
156 else
157 bgp_dest_unlock_node(pdest);
158 table = bgp_dest_get_bgp_table_info(pdest);
159 }
160
161 dest = bgp_node_get(table, p);
162
163 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
164 || (safi == SAFI_EVPN))
165 dest->pdest = pdest;
166
167 return dest;
168 }
169
170 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
171 safi_t safi, const struct prefix *p,
172 struct prefix_rd *prd)
173 {
174 struct bgp_dest *dest;
175 struct bgp_dest *pdest = NULL;
176
177 if (!table)
178 return NULL;
179
180 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
181 || (safi == SAFI_EVPN)) {
182 pdest = bgp_node_lookup(table, (struct prefix *)prd);
183 if (!pdest)
184 return NULL;
185
186 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
187 bgp_dest_unlock_node(pdest);
188 return NULL;
189 }
190
191 table = bgp_dest_get_bgp_table_info(pdest);
192 }
193
194 dest = bgp_node_lookup(table, p);
195
196 return dest;
197 }
198
199 /* Allocate bgp_path_info_extra */
200 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
201 {
202 struct bgp_path_info_extra *new;
203 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
204 sizeof(struct bgp_path_info_extra));
205 new->label[0] = MPLS_INVALID_LABEL;
206 new->num_labels = 0;
207 new->bgp_fs_pbr = NULL;
208 new->bgp_fs_iprule = NULL;
209 return new;
210 }
211
212 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
213 {
214 struct bgp_path_info_extra *e;
215
216 if (!extra || !*extra)
217 return;
218
219 e = *extra;
220 if (e->damp_info)
221 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
222 e->damp_info->safi);
223
224 e->damp_info = NULL;
225 if (e->parent) {
226 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
227
228 if (bpi->net) {
229 /* FIXME: since multiple e may have the same e->parent
230 * and e->parent->net is holding a refcount for each
231 * of them, we need to do some fudging here.
232 *
233 * WARNING: if bpi->net->lock drops to 0, bpi may be
234 * freed as well (because bpi->net was holding the
235 * last reference to bpi) => write after free!
236 */
237 unsigned refcount;
238
239 bpi = bgp_path_info_lock(bpi);
240 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
241 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
242 if (!refcount)
243 bpi->net = NULL;
244 bgp_path_info_unlock(bpi);
245 }
246 bgp_path_info_unlock(e->parent);
247 e->parent = NULL;
248 }
249
250 if (e->bgp_orig)
251 bgp_unlock(e->bgp_orig);
252
253 if (e->peer_orig)
254 peer_unlock(e->peer_orig);
255
256 if (e->aggr_suppressors)
257 list_delete(&e->aggr_suppressors);
258
259 if (e->mh_info)
260 bgp_evpn_path_mh_info_free(e->mh_info);
261
262 if ((*extra)->bgp_fs_iprule)
263 list_delete(&((*extra)->bgp_fs_iprule));
264 if ((*extra)->bgp_fs_pbr)
265 list_delete(&((*extra)->bgp_fs_pbr));
266 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
267 }
268
269 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
270 * allocated if required.
271 */
272 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
273 {
274 if (!pi->extra)
275 pi->extra = bgp_path_info_extra_new();
276 return pi->extra;
277 }
278
279 /* Free bgp route information. */
280 static void bgp_path_info_free(struct bgp_path_info *path)
281 {
282 bgp_attr_unintern(&path->attr);
283
284 bgp_unlink_nexthop(path);
285 bgp_path_info_extra_free(&path->extra);
286 bgp_path_info_mpath_free(&path->mpath);
287 if (path->net)
288 bgp_addpath_free_info_data(&path->tx_addpath,
289 &path->net->tx_addpath);
290
291 peer_unlock(path->peer); /* bgp_path_info peer reference */
292
293 XFREE(MTYPE_BGP_ROUTE, path);
294 }
295
296 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
297 {
298 path->lock++;
299 return path;
300 }
301
302 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
303 {
304 assert(path && path->lock > 0);
305 path->lock--;
306
307 if (path->lock == 0) {
308 bgp_path_info_free(path);
309 return NULL;
310 }
311
312 return path;
313 }
314
315 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
316 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
317 {
318 struct peer *peer;
319 struct bgp_path_info *old_pi, *nextpi;
320 bool set_flag = false;
321 struct bgp *bgp = NULL;
322 struct bgp_table *table = NULL;
323 afi_t afi = 0;
324 safi_t safi = 0;
325
326 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
327 * then the route selection is deferred
328 */
329 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
330 return 0;
331
332 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
333 if (BGP_DEBUG(update, UPDATE_OUT))
334 zlog_debug(
335 "Route %pBD is in workqueue and being processed, not deferred.",
336 dest);
337
338 return 0;
339 }
340
341 table = bgp_dest_table(dest);
342 if (table) {
343 bgp = table->bgp;
344 afi = table->afi;
345 safi = table->safi;
346 }
347
348 for (old_pi = bgp_dest_get_bgp_path_info(dest);
349 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
350 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
351 continue;
352
353 /* Route selection is deferred if there is a stale path which
354 * which indicates peer is in restart mode
355 */
356 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
357 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
358 set_flag = true;
359 } else {
360 /* If the peer is graceful restart capable and peer is
361 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
362 */
363 peer = old_pi->peer;
364 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
365 && BGP_PEER_RESTARTING_MODE(peer)
366 && (old_pi
367 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
368 set_flag = true;
369 }
370 }
371 if (set_flag)
372 break;
373 }
374
375 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
376 * is active
377 */
378 if (set_flag && table) {
379 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
380 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
381 bgp->gr_info[afi][safi].gr_deferred++;
382 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
383 if (BGP_DEBUG(update, UPDATE_OUT))
384 zlog_debug("DEFER route %pBD, dest %p", dest,
385 dest);
386 return 0;
387 }
388 }
389 return -1;
390 }
391
392 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
393 {
394 struct bgp_path_info *top;
395
396 top = bgp_dest_get_bgp_path_info(dest);
397
398 pi->next = top;
399 pi->prev = NULL;
400 if (top)
401 top->prev = pi;
402 bgp_dest_set_bgp_path_info(dest, pi);
403
404 bgp_path_info_lock(pi);
405 bgp_dest_lock_node(dest);
406 peer_lock(pi->peer); /* bgp_path_info peer reference */
407 bgp_dest_set_defer_flag(dest, false);
408 hook_call(bgp_snmp_update_stats, dest, pi, true);
409 }
410
411 /* Do the actual removal of info from RIB, for use by bgp_process
412 completion callback *only* */
413 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
414 {
415 if (pi->next)
416 pi->next->prev = pi->prev;
417 if (pi->prev)
418 pi->prev->next = pi->next;
419 else
420 bgp_dest_set_bgp_path_info(dest, pi->next);
421
422 bgp_path_info_mpath_dequeue(pi);
423 bgp_path_info_unlock(pi);
424 hook_call(bgp_snmp_update_stats, dest, pi, false);
425 bgp_dest_unlock_node(dest);
426 }
427
428 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
429 {
430 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
431 /* set of previous already took care of pcount */
432 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
433 }
434
435 /* undo the effects of a previous call to bgp_path_info_delete; typically
436 called when a route is deleted and then quickly re-added before the
437 deletion has been processed */
438 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
439 {
440 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
441 /* unset of previous already took care of pcount */
442 SET_FLAG(pi->flags, BGP_PATH_VALID);
443 }
444
445 /* Adjust pcount as required */
446 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
447 {
448 struct bgp_table *table;
449
450 assert(dest && bgp_dest_table(dest));
451 assert(pi && pi->peer && pi->peer->bgp);
452
453 table = bgp_dest_table(dest);
454
455 if (pi->peer == pi->peer->bgp->peer_self)
456 return;
457
458 if (!BGP_PATH_COUNTABLE(pi)
459 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
460
461 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
462
463 /* slight hack, but more robust against errors. */
464 if (pi->peer->pcount[table->afi][table->safi])
465 pi->peer->pcount[table->afi][table->safi]--;
466 else
467 flog_err(EC_LIB_DEVELOPMENT,
468 "Asked to decrement 0 prefix count for peer");
469 } else if (BGP_PATH_COUNTABLE(pi)
470 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
471 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
472 pi->peer->pcount[table->afi][table->safi]++;
473 }
474 }
475
476 static int bgp_label_index_differs(struct bgp_path_info *pi1,
477 struct bgp_path_info *pi2)
478 {
479 return (!(pi1->attr->label_index == pi2->attr->label_index));
480 }
481
482 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
483 * This is here primarily to keep prefix-count in check.
484 */
485 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
486 uint32_t flag)
487 {
488 SET_FLAG(pi->flags, flag);
489
490 /* early bath if we know it's not a flag that changes countability state
491 */
492 if (!CHECK_FLAG(flag,
493 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
494 return;
495
496 bgp_pcount_adjust(dest, pi);
497 }
498
499 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
500 uint32_t flag)
501 {
502 UNSET_FLAG(pi->flags, flag);
503
504 /* early bath if we know it's not a flag that changes countability state
505 */
506 if (!CHECK_FLAG(flag,
507 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
508 return;
509
510 bgp_pcount_adjust(dest, pi);
511 }
512
513 /* Get MED value. If MED value is missing and "bgp bestpath
514 missing-as-worst" is specified, treat it as the worst value. */
515 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
516 {
517 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
518 return attr->med;
519 else {
520 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
521 return BGP_MED_MAX;
522 else
523 return 0;
524 }
525 }
526
527 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
528 size_t buf_len)
529 {
530 if (pi->addpath_rx_id)
531 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
532 pi->peer->host, pi->addpath_rx_id);
533 else
534 snprintf(buf, buf_len, "path %s", pi->peer->host);
535 }
536
537
538 /*
539 * Get the ultimate path info.
540 */
541 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
542 {
543 struct bgp_path_info *bpi_ultimate;
544
545 if (info->sub_type != BGP_ROUTE_IMPORTED)
546 return info;
547
548 for (bpi_ultimate = info;
549 bpi_ultimate->extra && bpi_ultimate->extra->parent;
550 bpi_ultimate = bpi_ultimate->extra->parent)
551 ;
552
553 return bpi_ultimate;
554 }
555
556 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
557 */
558 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
559 struct bgp_path_info *exist, int *paths_eq,
560 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
561 char *pfx_buf, afi_t afi, safi_t safi,
562 enum bgp_path_selection_reason *reason)
563 {
564 const struct prefix *new_p;
565 struct prefix exist_p;
566 struct attr *newattr, *existattr;
567 enum bgp_peer_sort new_sort;
568 enum bgp_peer_sort exist_sort;
569 uint32_t new_pref;
570 uint32_t exist_pref;
571 uint32_t new_med;
572 uint32_t exist_med;
573 uint32_t new_weight;
574 uint32_t exist_weight;
575 uint32_t newm, existm;
576 struct in_addr new_id;
577 struct in_addr exist_id;
578 int new_cluster;
579 int exist_cluster;
580 int internal_as_route;
581 int confed_as_route;
582 int ret = 0;
583 int igp_metric_ret = 0;
584 int peer_sort_ret = -1;
585 char new_buf[PATH_ADDPATH_STR_BUFFER];
586 char exist_buf[PATH_ADDPATH_STR_BUFFER];
587 uint32_t new_mm_seq;
588 uint32_t exist_mm_seq;
589 int nh_cmp;
590 esi_t *exist_esi;
591 esi_t *new_esi;
592 bool same_esi;
593 bool old_proxy;
594 bool new_proxy;
595 bool new_origin, exist_origin;
596 struct bgp_path_info *bpi_ultimate;
597
598 struct bgp_orr_group *orr_group = NULL;
599 struct listnode *node;
600 struct bgp_orr_igp_metric *igp_metric = NULL;
601 struct list *orr_group_igp_metric_info = NULL;
602
603 *paths_eq = 0;
604
605 /* 0. Null check. */
606 if (new == NULL) {
607 *reason = bgp_path_selection_none;
608 if (debug)
609 zlog_debug("%s: new is NULL", pfx_buf);
610 return 0;
611 }
612
613 if (debug) {
614 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
615 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
616 sizeof(new_buf));
617 }
618
619 if (exist == NULL) {
620 *reason = bgp_path_selection_first;
621 if (debug)
622 zlog_debug("%s(%s): %s is the initial bestpath",
623 pfx_buf, bgp->name_pretty, new_buf);
624 return 1;
625 }
626
627 if (debug) {
628 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
629 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
630 sizeof(exist_buf));
631 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
632 pfx_buf, bgp->name_pretty, new_buf, new->flags,
633 exist_buf, exist->flags);
634 }
635
636 newattr = new->attr;
637 existattr = exist->attr;
638
639 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
640 * Capability" to a neighbor MUST perform the following upon receiving
641 * a route from that neighbor with the "LLGR_STALE" community, or upon
642 * attaching the "LLGR_STALE" community itself per Section 4.2:
643 *
644 * Treat the route as the least-preferred in route selection (see
645 * below). See the Risks of Depreferencing Routes section (Section 5.2)
646 * for a discussion of potential risks inherent in doing this.
647 */
648 if (bgp_attr_get_community(newattr) &&
649 community_include(bgp_attr_get_community(newattr),
650 COMMUNITY_LLGR_STALE)) {
651 if (debug)
652 zlog_debug(
653 "%s: %s wins over %s due to LLGR_STALE community",
654 pfx_buf, new_buf, exist_buf);
655 return 0;
656 }
657
658 if (bgp_attr_get_community(existattr) &&
659 community_include(bgp_attr_get_community(existattr),
660 COMMUNITY_LLGR_STALE)) {
661 if (debug)
662 zlog_debug(
663 "%s: %s loses to %s due to LLGR_STALE community",
664 pfx_buf, new_buf, exist_buf);
665 return 1;
666 }
667
668 new_p = bgp_dest_get_prefix(new->net);
669
670 /* For EVPN routes, we cannot just go by local vs remote, we have to
671 * look at the MAC mobility sequence number, if present.
672 */
673 if ((safi == SAFI_EVPN)
674 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
675 /* This is an error condition described in RFC 7432 Section
676 * 15.2. The RFC
677 * states that in this scenario "the PE MUST alert the operator"
678 * but it
679 * does not state what other action to take. In order to provide
680 * some
681 * consistency in this scenario we are going to prefer the path
682 * with the
683 * sticky flag.
684 */
685 if (newattr->sticky != existattr->sticky) {
686 if (!debug) {
687 prefix2str(new_p, pfx_buf,
688 sizeof(*pfx_buf)
689 * PREFIX2STR_BUFFER);
690 bgp_path_info_path_with_addpath_rx_str(
691 new, new_buf, sizeof(new_buf));
692 bgp_path_info_path_with_addpath_rx_str(
693 exist, exist_buf, sizeof(exist_buf));
694 }
695
696 if (newattr->sticky && !existattr->sticky) {
697 *reason = bgp_path_selection_evpn_sticky_mac;
698 if (debug)
699 zlog_debug(
700 "%s: %s wins over %s due to sticky MAC flag",
701 pfx_buf, new_buf, exist_buf);
702 return 1;
703 }
704
705 if (!newattr->sticky && existattr->sticky) {
706 *reason = bgp_path_selection_evpn_sticky_mac;
707 if (debug)
708 zlog_debug(
709 "%s: %s loses to %s due to sticky MAC flag",
710 pfx_buf, new_buf, exist_buf);
711 return 0;
712 }
713 }
714
715 new_esi = bgp_evpn_attr_get_esi(newattr);
716 exist_esi = bgp_evpn_attr_get_esi(existattr);
717 if (bgp_evpn_is_esi_valid(new_esi) &&
718 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
719 same_esi = true;
720 } else {
721 same_esi = false;
722 }
723
724 /* If both paths have the same non-zero ES and
725 * one path is local it wins.
726 * PS: Note the local path wins even if the remote
727 * has the higher MM seq. The local path's
728 * MM seq will be fixed up to match the highest
729 * rem seq, subsequently.
730 */
731 if (same_esi) {
732 char esi_buf[ESI_STR_LEN];
733
734 if (bgp_evpn_is_path_local(bgp, new)) {
735 *reason = bgp_path_selection_evpn_local_path;
736 if (debug)
737 zlog_debug(
738 "%s: %s wins over %s as ES %s is same and local",
739 pfx_buf, new_buf, exist_buf,
740 esi_to_str(new_esi, esi_buf,
741 sizeof(esi_buf)));
742 return 1;
743 }
744 if (bgp_evpn_is_path_local(bgp, exist)) {
745 *reason = bgp_path_selection_evpn_local_path;
746 if (debug)
747 zlog_debug(
748 "%s: %s loses to %s as ES %s is same and local",
749 pfx_buf, new_buf, exist_buf,
750 esi_to_str(new_esi, esi_buf,
751 sizeof(esi_buf)));
752 return 0;
753 }
754 }
755
756 new_mm_seq = mac_mobility_seqnum(newattr);
757 exist_mm_seq = mac_mobility_seqnum(existattr);
758
759 if (new_mm_seq > exist_mm_seq) {
760 *reason = bgp_path_selection_evpn_seq;
761 if (debug)
762 zlog_debug(
763 "%s: %s wins over %s due to MM seq %u > %u",
764 pfx_buf, new_buf, exist_buf, new_mm_seq,
765 exist_mm_seq);
766 return 1;
767 }
768
769 if (new_mm_seq < exist_mm_seq) {
770 *reason = bgp_path_selection_evpn_seq;
771 if (debug)
772 zlog_debug(
773 "%s: %s loses to %s due to MM seq %u < %u",
774 pfx_buf, new_buf, exist_buf, new_mm_seq,
775 exist_mm_seq);
776 return 0;
777 }
778
779 /* if the sequence numbers and ESI are the same and one path
780 * is non-proxy it wins (over proxy)
781 */
782 new_proxy = bgp_evpn_attr_is_proxy(newattr);
783 old_proxy = bgp_evpn_attr_is_proxy(existattr);
784 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
785 old_proxy != new_proxy) {
786 if (!new_proxy) {
787 *reason = bgp_path_selection_evpn_non_proxy;
788 if (debug)
789 zlog_debug(
790 "%s: %s wins over %s, same seq/es and non-proxy",
791 pfx_buf, new_buf, exist_buf);
792 return 1;
793 }
794
795 *reason = bgp_path_selection_evpn_non_proxy;
796 if (debug)
797 zlog_debug(
798 "%s: %s loses to %s, same seq/es and non-proxy",
799 pfx_buf, new_buf, exist_buf);
800 return 0;
801 }
802
803 /*
804 * if sequence numbers are the same path with the lowest IP
805 * wins
806 */
807 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
808 if (nh_cmp < 0) {
809 *reason = bgp_path_selection_evpn_lower_ip;
810 if (debug)
811 zlog_debug(
812 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
813 pfx_buf, new_buf, exist_buf, new_mm_seq,
814 &new->attr->nexthop);
815 return 1;
816 }
817 if (nh_cmp > 0) {
818 *reason = bgp_path_selection_evpn_lower_ip;
819 if (debug)
820 zlog_debug(
821 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
822 pfx_buf, new_buf, exist_buf, new_mm_seq,
823 &new->attr->nexthop);
824 return 0;
825 }
826 }
827
828 /* 1. Weight check. */
829 new_weight = newattr->weight;
830 exist_weight = existattr->weight;
831
832 if (new_weight > exist_weight) {
833 *reason = bgp_path_selection_weight;
834 if (debug)
835 zlog_debug("%s: %s wins over %s due to weight %d > %d",
836 pfx_buf, new_buf, exist_buf, new_weight,
837 exist_weight);
838 return 1;
839 }
840
841 if (new_weight < exist_weight) {
842 *reason = bgp_path_selection_weight;
843 if (debug)
844 zlog_debug("%s: %s loses to %s due to weight %d < %d",
845 pfx_buf, new_buf, exist_buf, new_weight,
846 exist_weight);
847 return 0;
848 }
849
850 /* 2. Local preference check. */
851 new_pref = exist_pref = bgp->default_local_pref;
852
853 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
854 new_pref = newattr->local_pref;
855 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
856 exist_pref = existattr->local_pref;
857
858 if (new_pref > exist_pref) {
859 *reason = bgp_path_selection_local_pref;
860 if (debug)
861 zlog_debug(
862 "%s: %s wins over %s due to localpref %d > %d",
863 pfx_buf, new_buf, exist_buf, new_pref,
864 exist_pref);
865 return 1;
866 }
867
868 if (new_pref < exist_pref) {
869 *reason = bgp_path_selection_local_pref;
870 if (debug)
871 zlog_debug(
872 "%s: %s loses to %s due to localpref %d < %d",
873 pfx_buf, new_buf, exist_buf, new_pref,
874 exist_pref);
875 return 0;
876 }
877
878 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
879 * extensions defined in this document, the following step is inserted
880 * after the LOCAL_PREF comparison step in the BGP decision process:
881 * When comparing a pair of routes for a BGP destination, the
882 * route with the ACCEPT_OWN community attached is preferred over
883 * the route that does not have the community.
884 * This extra step MUST only be invoked during the best path selection
885 * process of VPN-IP routes.
886 */
887 if (safi == SAFI_MPLS_VPN &&
888 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
889 CHECK_FLAG(exist->peer->af_flags[afi][safi],
890 PEER_FLAG_ACCEPT_OWN))) {
891 bool new_accept_own = false;
892 bool exist_accept_own = false;
893 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
894
895 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
896 new_accept_own = community_include(
897 bgp_attr_get_community(newattr), accept_own);
898 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
899 exist_accept_own = community_include(
900 bgp_attr_get_community(existattr), accept_own);
901
902 if (new_accept_own && !exist_accept_own) {
903 *reason = bgp_path_selection_accept_own;
904 if (debug)
905 zlog_debug(
906 "%s: %s wins over %s due to accept-own",
907 pfx_buf, new_buf, exist_buf);
908 return 1;
909 }
910
911 if (!new_accept_own && exist_accept_own) {
912 *reason = bgp_path_selection_accept_own;
913 if (debug)
914 zlog_debug(
915 "%s: %s loses to %s due to accept-own",
916 pfx_buf, new_buf, exist_buf);
917 return 0;
918 }
919 }
920
921 /* Tie-breaker - AIGP (Metric TLV) attribute */
922 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
923 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
924 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
925 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
926 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
927
928 if (new_aigp < exist_aigp) {
929 *reason = bgp_path_selection_aigp;
930 if (debug)
931 zlog_debug(
932 "%s: %s wins over %s due to AIGP %" PRIu64
933 " < %" PRIu64,
934 pfx_buf, new_buf, exist_buf, new_aigp,
935 exist_aigp);
936 return 1;
937 }
938
939 if (new_aigp > exist_aigp) {
940 *reason = bgp_path_selection_aigp;
941 if (debug)
942 zlog_debug(
943 "%s: %s loses to %s due to AIGP %" PRIu64
944 " > %" PRIu64,
945 pfx_buf, new_buf, exist_buf, new_aigp,
946 exist_aigp);
947 return 0;
948 }
949 }
950
951 /* 3. Local route check. We prefer:
952 * - BGP_ROUTE_STATIC
953 * - BGP_ROUTE_AGGREGATE
954 * - BGP_ROUTE_REDISTRIBUTE
955 */
956 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
957 new->sub_type == BGP_ROUTE_IMPORTED);
958 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
959 exist->sub_type == BGP_ROUTE_IMPORTED);
960
961 if (new_origin && !exist_origin) {
962 *reason = bgp_path_selection_local_route;
963 if (debug)
964 zlog_debug(
965 "%s: %s wins over %s due to preferred BGP_ROUTE type",
966 pfx_buf, new_buf, exist_buf);
967 return 1;
968 }
969
970 if (!new_origin && exist_origin) {
971 *reason = bgp_path_selection_local_route;
972 if (debug)
973 zlog_debug(
974 "%s: %s loses to %s due to preferred BGP_ROUTE type",
975 pfx_buf, new_buf, exist_buf);
976 return 0;
977 }
978
979 /* Here if these are imported routes then get ultimate pi for
980 * path compare.
981 */
982 new = bgp_get_imported_bpi_ultimate(new);
983 exist = bgp_get_imported_bpi_ultimate(exist);
984 newattr = new->attr;
985 existattr = exist->attr;
986
987 /* 4. AS path length check. */
988 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
989 int exist_hops = aspath_count_hops(existattr->aspath);
990 int exist_confeds = aspath_count_confeds(existattr->aspath);
991
992 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
993 int aspath_hops;
994
995 aspath_hops = aspath_count_hops(newattr->aspath);
996 aspath_hops += aspath_count_confeds(newattr->aspath);
997
998 if (aspath_hops < (exist_hops + exist_confeds)) {
999 *reason = bgp_path_selection_confed_as_path;
1000 if (debug)
1001 zlog_debug(
1002 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
1003 pfx_buf, new_buf, exist_buf,
1004 aspath_hops,
1005 (exist_hops + exist_confeds));
1006 return 1;
1007 }
1008
1009 if (aspath_hops > (exist_hops + exist_confeds)) {
1010 *reason = bgp_path_selection_confed_as_path;
1011 if (debug)
1012 zlog_debug(
1013 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1014 pfx_buf, new_buf, exist_buf,
1015 aspath_hops,
1016 (exist_hops + exist_confeds));
1017 return 0;
1018 }
1019 } else {
1020 int newhops = aspath_count_hops(newattr->aspath);
1021
1022 if (newhops < exist_hops) {
1023 *reason = bgp_path_selection_as_path;
1024 if (debug)
1025 zlog_debug(
1026 "%s: %s wins over %s due to aspath hopcount %d < %d",
1027 pfx_buf, new_buf, exist_buf,
1028 newhops, exist_hops);
1029 return 1;
1030 }
1031
1032 if (newhops > exist_hops) {
1033 *reason = bgp_path_selection_as_path;
1034 if (debug)
1035 zlog_debug(
1036 "%s: %s loses to %s due to aspath hopcount %d > %d",
1037 pfx_buf, new_buf, exist_buf,
1038 newhops, exist_hops);
1039 return 0;
1040 }
1041 }
1042 }
1043
1044 /* 5. Origin check. */
1045 if (newattr->origin < existattr->origin) {
1046 *reason = bgp_path_selection_origin;
1047 if (debug)
1048 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1049 pfx_buf, new_buf, exist_buf,
1050 bgp_origin_long_str[newattr->origin],
1051 bgp_origin_long_str[existattr->origin]);
1052 return 1;
1053 }
1054
1055 if (newattr->origin > existattr->origin) {
1056 *reason = bgp_path_selection_origin;
1057 if (debug)
1058 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1059 pfx_buf, new_buf, exist_buf,
1060 bgp_origin_long_str[newattr->origin],
1061 bgp_origin_long_str[existattr->origin]);
1062 return 0;
1063 }
1064
1065 /* 6. MED check. */
1066 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1067 && aspath_count_hops(existattr->aspath) == 0);
1068 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1069 && aspath_count_confeds(existattr->aspath) > 0
1070 && aspath_count_hops(newattr->aspath) == 0
1071 && aspath_count_hops(existattr->aspath) == 0);
1072
1073 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1074 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1075 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1076 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1077 || internal_as_route) {
1078 new_med = bgp_med_value(new->attr, bgp);
1079 exist_med = bgp_med_value(exist->attr, bgp);
1080
1081 if (new_med < exist_med) {
1082 *reason = bgp_path_selection_med;
1083 if (debug)
1084 zlog_debug(
1085 "%s: %s wins over %s due to MED %d < %d",
1086 pfx_buf, new_buf, exist_buf, new_med,
1087 exist_med);
1088 return 1;
1089 }
1090
1091 if (new_med > exist_med) {
1092 *reason = bgp_path_selection_med;
1093 if (debug)
1094 zlog_debug(
1095 "%s: %s loses to %s due to MED %d > %d",
1096 pfx_buf, new_buf, exist_buf, new_med,
1097 exist_med);
1098 return 0;
1099 }
1100 }
1101
1102 /* 7. Peer type check. */
1103 new_sort = new->peer->sort;
1104 exist_sort = exist->peer->sort;
1105
1106 if (new_sort == BGP_PEER_EBGP
1107 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1108 *reason = bgp_path_selection_peer;
1109 if (debug)
1110 zlog_debug(
1111 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1112 pfx_buf, new_buf, exist_buf);
1113 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1114 return 1;
1115 peer_sort_ret = 1;
1116 }
1117
1118 if (exist_sort == BGP_PEER_EBGP
1119 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1120 *reason = bgp_path_selection_peer;
1121 if (debug)
1122 zlog_debug(
1123 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1124 pfx_buf, new_buf, exist_buf);
1125 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1126 return 0;
1127 peer_sort_ret = 0;
1128 }
1129
1130 /* 8. IGP metric check. */
1131 newm = existm = 0;
1132
1133 if (new->extra)
1134 newm = new->extra->igpmetric;
1135 if (exist->extra)
1136 existm = exist->extra->igpmetric;
1137
1138 if (new->peer->orr_group_name[afi][safi]) {
1139 ret = str2prefix(new->peer->host, &exist_p);
1140 orr_group = bgp_orr_group_lookup_by_name(
1141 bgp, afi, safi, new->peer->orr_group_name[afi][safi]);
1142 if (orr_group) {
1143 orr_group_igp_metric_info = orr_group->igp_metric_info;
1144 if (orr_group_igp_metric_info) {
1145 for (ALL_LIST_ELEMENTS_RO(
1146 orr_group_igp_metric_info, node,
1147 igp_metric)) {
1148 if (ret &&
1149 prefix_cmp(&exist_p,
1150 &igp_metric->prefix) ==
1151 0) {
1152 newm = igp_metric->igp_metric;
1153 break;
1154 }
1155 }
1156 }
1157 }
1158 }
1159 if (exist->peer->orr_group_name[afi][safi]) {
1160 ret = str2prefix(exist->peer->host, &exist_p);
1161 orr_group = bgp_orr_group_lookup_by_name(
1162 bgp, afi, safi, exist->peer->orr_group_name[afi][safi]);
1163 if (orr_group) {
1164 orr_group_igp_metric_info = orr_group->igp_metric_info;
1165 if (orr_group_igp_metric_info) {
1166 for (ALL_LIST_ELEMENTS_RO(
1167 orr_group_igp_metric_info, node,
1168 igp_metric)) {
1169 if (ret &&
1170 prefix_cmp(&exist_p,
1171 &igp_metric->prefix) ==
1172 0) {
1173 existm = igp_metric->igp_metric;
1174 break;
1175 }
1176 }
1177 }
1178 }
1179 }
1180
1181 if (newm < existm) {
1182 if (debug && peer_sort_ret < 0)
1183 zlog_debug(
1184 "%s: %s wins over %s due to IGP metric %u < %u",
1185 pfx_buf, new_buf, exist_buf, 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 IGP metric %u > %u",
1193 pfx_buf, new_buf, exist_buf, newm, existm);
1194 igp_metric_ret = 0;
1195 }
1196
1197 /* 9. Same IGP metric. Compare the cluster list length as
1198 representative of IGP hops metric. Rewrite the metric value
1199 pair (newm, existm) with the cluster list length. Prefer the
1200 path with smaller cluster list length. */
1201 if (newm == existm) {
1202 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP &&
1203 peer_sort_lookup(exist->peer) == BGP_PEER_IBGP &&
1204 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1205 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1206 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1207
1208 if (newm < existm) {
1209 if (debug && peer_sort_ret < 0)
1210 zlog_debug(
1211 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1212 pfx_buf, new_buf, exist_buf,
1213 newm, existm);
1214 igp_metric_ret = 1;
1215 }
1216
1217 if (newm > existm) {
1218 if (debug && peer_sort_ret < 0)
1219 zlog_debug(
1220 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1221 pfx_buf, new_buf, exist_buf,
1222 newm, existm);
1223 igp_metric_ret = 0;
1224 }
1225 }
1226 }
1227
1228 /* 10. confed-external vs. confed-internal */
1229 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1230 if (new_sort == BGP_PEER_CONFED
1231 && exist_sort == BGP_PEER_IBGP) {
1232 *reason = bgp_path_selection_confed;
1233 if (debug)
1234 zlog_debug(
1235 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1236 pfx_buf, new_buf, exist_buf);
1237 if (!CHECK_FLAG(bgp->flags,
1238 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1239 return 1;
1240 peer_sort_ret = 1;
1241 }
1242
1243 if (exist_sort == BGP_PEER_CONFED
1244 && new_sort == BGP_PEER_IBGP) {
1245 *reason = bgp_path_selection_confed;
1246 if (debug)
1247 zlog_debug(
1248 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1249 pfx_buf, new_buf, exist_buf);
1250 if (!CHECK_FLAG(bgp->flags,
1251 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1252 return 0;
1253 peer_sort_ret = 0;
1254 }
1255 }
1256
1257 /* 11. Maximum path check. */
1258 if (newm == existm) {
1259 /* If one path has a label but the other does not, do not treat
1260 * them as equals for multipath
1261 */
1262 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1263 != (exist->extra
1264 && bgp_is_valid_label(&exist->extra->label[0]))) {
1265 if (debug)
1266 zlog_debug(
1267 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1268 pfx_buf, new_buf, exist_buf);
1269 } else if (CHECK_FLAG(bgp->flags,
1270 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1271
1272 /*
1273 * For the two paths, all comparison steps till IGP
1274 * metric
1275 * have succeeded - including AS_PATH hop count. Since
1276 * 'bgp
1277 * bestpath as-path multipath-relax' knob is on, we
1278 * don't need
1279 * an exact match of AS_PATH. Thus, mark the paths are
1280 * equal.
1281 * That will trigger both these paths to get into the
1282 * multipath
1283 * array.
1284 */
1285 *paths_eq = 1;
1286
1287 if (debug)
1288 zlog_debug(
1289 "%s: %s and %s are equal via multipath-relax",
1290 pfx_buf, new_buf, exist_buf);
1291 } else if (new->peer->sort == BGP_PEER_IBGP) {
1292 if (aspath_cmp(new->attr->aspath,
1293 exist->attr->aspath)) {
1294 *paths_eq = 1;
1295
1296 if (debug)
1297 zlog_debug(
1298 "%s: %s and %s are equal via matching aspaths",
1299 pfx_buf, new_buf, exist_buf);
1300 }
1301 } else if (new->peer->as == exist->peer->as) {
1302 *paths_eq = 1;
1303
1304 if (debug)
1305 zlog_debug(
1306 "%s: %s and %s are equal via same remote-as",
1307 pfx_buf, new_buf, exist_buf);
1308 }
1309 } else {
1310 /*
1311 * TODO: If unequal cost ibgp multipath is enabled we can
1312 * mark the paths as equal here instead of returning
1313 */
1314
1315 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1316 * if either step 7 or 10 (peer type checks) yielded a winner,
1317 * that result was returned immediately. Returning from step 10
1318 * ignored the return value computed in steps 8 and 9 (IGP
1319 * metric checks). In order to preserve that behavior, if
1320 * peer_sort_ret is set, return that rather than igp_metric_ret.
1321 */
1322 ret = peer_sort_ret;
1323 if (peer_sort_ret < 0) {
1324 ret = igp_metric_ret;
1325 if (debug) {
1326 if (ret == 1)
1327 zlog_debug(
1328 "%s: %s wins over %s after IGP metric comparison",
1329 pfx_buf, new_buf, exist_buf);
1330 else
1331 zlog_debug(
1332 "%s: %s loses to %s after IGP metric comparison",
1333 pfx_buf, new_buf, exist_buf);
1334 }
1335 *reason = bgp_path_selection_igp_metric;
1336 }
1337 return ret;
1338 }
1339
1340 /*
1341 * At this point, the decision whether to set *paths_eq = 1 has been
1342 * completed. If we deferred returning because of bestpath peer-type
1343 * relax configuration, return now.
1344 */
1345 if (peer_sort_ret >= 0)
1346 return peer_sort_ret;
1347
1348 /* 12. If both paths are external, prefer the path that was received
1349 first (the oldest one). This step minimizes route-flap, since a
1350 newer path won't displace an older one, even if it was the
1351 preferred route based on the additional decision criteria below. */
1352 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1353 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1354 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1355 *reason = bgp_path_selection_older;
1356 if (debug)
1357 zlog_debug(
1358 "%s: %s wins over %s due to oldest external",
1359 pfx_buf, new_buf, exist_buf);
1360 return 1;
1361 }
1362
1363 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1364 *reason = bgp_path_selection_older;
1365 if (debug)
1366 zlog_debug(
1367 "%s: %s loses to %s due to oldest external",
1368 pfx_buf, new_buf, exist_buf);
1369 return 0;
1370 }
1371 }
1372
1373 /* 13. Router-ID comparison. */
1374 /* If one of the paths is "stale", the corresponding peer router-id will
1375 * be 0 and would always win over the other path. If originator id is
1376 * used for the comparison, it will decide which path is better.
1377 */
1378 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1379 new_id.s_addr = newattr->originator_id.s_addr;
1380 else
1381 new_id.s_addr = new->peer->remote_id.s_addr;
1382 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1383 exist_id.s_addr = existattr->originator_id.s_addr;
1384 else
1385 exist_id.s_addr = exist->peer->remote_id.s_addr;
1386
1387 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1388 *reason = bgp_path_selection_router_id;
1389 if (debug)
1390 zlog_debug(
1391 "%s: %s wins over %s due to Router-ID comparison",
1392 pfx_buf, new_buf, exist_buf);
1393 return 1;
1394 }
1395
1396 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1397 *reason = bgp_path_selection_router_id;
1398 if (debug)
1399 zlog_debug(
1400 "%s: %s loses to %s due to Router-ID comparison",
1401 pfx_buf, new_buf, exist_buf);
1402 return 0;
1403 }
1404
1405 /* 14. Cluster length comparison. */
1406 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1407 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1408
1409 if (new_cluster < exist_cluster) {
1410 *reason = bgp_path_selection_cluster_length;
1411 if (debug)
1412 zlog_debug(
1413 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1414 pfx_buf, new_buf, exist_buf, new_cluster,
1415 exist_cluster);
1416 return 1;
1417 }
1418
1419 if (new_cluster > exist_cluster) {
1420 *reason = bgp_path_selection_cluster_length;
1421 if (debug)
1422 zlog_debug(
1423 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1424 pfx_buf, new_buf, exist_buf, new_cluster,
1425 exist_cluster);
1426 return 0;
1427 }
1428
1429 /* 15. Neighbor address comparison. */
1430 /* Do this only if neither path is "stale" as stale paths do not have
1431 * valid peer information (as the connection may or may not be up).
1432 */
1433 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1434 *reason = bgp_path_selection_stale;
1435 if (debug)
1436 zlog_debug(
1437 "%s: %s wins over %s due to latter path being STALE",
1438 pfx_buf, new_buf, exist_buf);
1439 return 1;
1440 }
1441
1442 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1443 *reason = bgp_path_selection_stale;
1444 if (debug)
1445 zlog_debug(
1446 "%s: %s loses to %s due to former path being STALE",
1447 pfx_buf, new_buf, exist_buf);
1448 return 0;
1449 }
1450
1451 /* locally configured routes to advertise do not have su_remote */
1452 if (new->peer->su_remote == NULL) {
1453 *reason = bgp_path_selection_local_configured;
1454 return 0;
1455 }
1456 if (exist->peer->su_remote == NULL) {
1457 *reason = bgp_path_selection_local_configured;
1458 return 1;
1459 }
1460
1461 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1462
1463 if (ret == 1) {
1464 *reason = bgp_path_selection_neighbor_ip;
1465 if (debug)
1466 zlog_debug(
1467 "%s: %s loses to %s due to Neighor IP comparison",
1468 pfx_buf, new_buf, exist_buf);
1469 return 0;
1470 }
1471
1472 if (ret == -1) {
1473 *reason = bgp_path_selection_neighbor_ip;
1474 if (debug)
1475 zlog_debug(
1476 "%s: %s wins over %s due to Neighor IP comparison",
1477 pfx_buf, new_buf, exist_buf);
1478 return 1;
1479 }
1480
1481 *reason = bgp_path_selection_default;
1482 if (debug)
1483 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1484 pfx_buf, new_buf, exist_buf);
1485
1486 return 1;
1487 }
1488
1489
1490 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1491 struct bgp_path_info *exist, int *paths_eq)
1492 {
1493 enum bgp_path_selection_reason reason;
1494 char pfx_buf[PREFIX2STR_BUFFER];
1495
1496 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1497 AFI_L2VPN, SAFI_EVPN, &reason);
1498 }
1499
1500 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1501 * is preferred, or 0 if they are the same (usually will only occur if
1502 * multipath is enabled
1503 * This version is compatible with */
1504 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1505 struct bgp_path_info *exist, char *pfx_buf,
1506 afi_t afi, safi_t safi,
1507 enum bgp_path_selection_reason *reason)
1508 {
1509 int paths_eq;
1510 int ret;
1511 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1512 afi, safi, reason);
1513
1514 if (paths_eq)
1515 ret = 0;
1516 else {
1517 if (ret == 1)
1518 ret = -1;
1519 else
1520 ret = 1;
1521 }
1522 return ret;
1523 }
1524
1525 static enum filter_type bgp_input_filter(struct peer *peer,
1526 const struct prefix *p,
1527 struct attr *attr, afi_t afi,
1528 safi_t safi)
1529 {
1530 struct bgp_filter *filter;
1531 enum filter_type ret = FILTER_PERMIT;
1532
1533 filter = &peer->filter[afi][safi];
1534
1535 #define FILTER_EXIST_WARN(F, f, filter) \
1536 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1537 zlog_debug("%s: Could not find configured input %s-list %s!", \
1538 peer->host, #f, F##_IN_NAME(filter));
1539
1540 if (DISTRIBUTE_IN_NAME(filter)) {
1541 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1542
1543 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1544 == FILTER_DENY) {
1545 ret = FILTER_DENY;
1546 goto done;
1547 }
1548 }
1549
1550 if (PREFIX_LIST_IN_NAME(filter)) {
1551 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1552
1553 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1554 == PREFIX_DENY) {
1555 ret = FILTER_DENY;
1556 goto done;
1557 }
1558 }
1559
1560 if (FILTER_LIST_IN_NAME(filter)) {
1561 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1562
1563 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1564 == AS_FILTER_DENY) {
1565 ret = FILTER_DENY;
1566 goto done;
1567 }
1568 }
1569
1570 done:
1571 if (frrtrace_enabled(frr_bgp, input_filter)) {
1572 char pfxprint[PREFIX2STR_BUFFER];
1573
1574 prefix2str(p, pfxprint, sizeof(pfxprint));
1575 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1576 ret == FILTER_PERMIT ? "permit" : "deny");
1577 }
1578
1579 return ret;
1580 #undef FILTER_EXIST_WARN
1581 }
1582
1583 static enum filter_type bgp_output_filter(struct peer *peer,
1584 const struct prefix *p,
1585 struct attr *attr, afi_t afi,
1586 safi_t safi)
1587 {
1588 struct bgp_filter *filter;
1589 enum filter_type ret = FILTER_PERMIT;
1590
1591 filter = &peer->filter[afi][safi];
1592
1593 #define FILTER_EXIST_WARN(F, f, filter) \
1594 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1595 zlog_debug("%s: Could not find configured output %s-list %s!", \
1596 peer->host, #f, F##_OUT_NAME(filter));
1597
1598 if (DISTRIBUTE_OUT_NAME(filter)) {
1599 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1600
1601 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1602 == FILTER_DENY) {
1603 ret = FILTER_DENY;
1604 goto done;
1605 }
1606 }
1607
1608 if (PREFIX_LIST_OUT_NAME(filter)) {
1609 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1610
1611 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1612 == PREFIX_DENY) {
1613 ret = FILTER_DENY;
1614 goto done;
1615 }
1616 }
1617
1618 if (FILTER_LIST_OUT_NAME(filter)) {
1619 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1620
1621 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1622 == AS_FILTER_DENY) {
1623 ret = FILTER_DENY;
1624 goto done;
1625 }
1626 }
1627
1628 if (frrtrace_enabled(frr_bgp, output_filter)) {
1629 char pfxprint[PREFIX2STR_BUFFER];
1630
1631 prefix2str(p, pfxprint, sizeof(pfxprint));
1632 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1633 ret == FILTER_PERMIT ? "permit" : "deny");
1634 }
1635
1636 done:
1637 return ret;
1638 #undef FILTER_EXIST_WARN
1639 }
1640
1641 /* If community attribute includes no_export then return 1. */
1642 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1643 {
1644 if (bgp_attr_get_community(attr)) {
1645 /* NO_ADVERTISE check. */
1646 if (community_include(bgp_attr_get_community(attr),
1647 COMMUNITY_NO_ADVERTISE))
1648 return true;
1649
1650 /* NO_EXPORT check. */
1651 if (peer->sort == BGP_PEER_EBGP &&
1652 community_include(bgp_attr_get_community(attr),
1653 COMMUNITY_NO_EXPORT))
1654 return true;
1655
1656 /* NO_EXPORT_SUBCONFED check. */
1657 if (peer->sort == BGP_PEER_EBGP
1658 || peer->sort == BGP_PEER_CONFED)
1659 if (community_include(bgp_attr_get_community(attr),
1660 COMMUNITY_NO_EXPORT_SUBCONFED))
1661 return true;
1662 }
1663 return false;
1664 }
1665
1666 /* Route reflection loop check. */
1667 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1668 {
1669 struct in_addr cluster_id;
1670 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1671
1672 if (cluster) {
1673 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1674 cluster_id = peer->bgp->cluster_id;
1675 else
1676 cluster_id = peer->bgp->router_id;
1677
1678 if (cluster_loop_check(cluster, cluster_id))
1679 return true;
1680 }
1681 return false;
1682 }
1683
1684 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1685 {
1686 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1687 if (peer->local_role == ROLE_PROVIDER ||
1688 peer->local_role == ROLE_RS_SERVER)
1689 return true;
1690 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1691 return true;
1692 return false;
1693 }
1694 if (peer->local_role == ROLE_CUSTOMER ||
1695 peer->local_role == ROLE_PEER ||
1696 peer->local_role == ROLE_RS_CLIENT) {
1697 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1698 attr->otc = peer->as;
1699 }
1700 return false;
1701 }
1702
1703 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1704 {
1705 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1706 if (peer->local_role == ROLE_CUSTOMER ||
1707 peer->local_role == ROLE_RS_CLIENT ||
1708 peer->local_role == ROLE_PEER)
1709 return true;
1710 return false;
1711 }
1712 if (peer->local_role == ROLE_PROVIDER ||
1713 peer->local_role == ROLE_PEER ||
1714 peer->local_role == ROLE_RS_SERVER) {
1715 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1716 attr->otc = peer->bgp->as;
1717 }
1718 return false;
1719 }
1720
1721 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1722 {
1723 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1724 }
1725
1726 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1727 struct attr *attr, afi_t afi, safi_t safi,
1728 const char *rmap_name, mpls_label_t *label,
1729 uint32_t num_labels, struct bgp_dest *dest)
1730 {
1731 struct bgp_filter *filter;
1732 struct bgp_path_info rmap_path = { 0 };
1733 struct bgp_path_info_extra extra = { 0 };
1734 route_map_result_t ret;
1735 struct route_map *rmap = NULL;
1736
1737 filter = &peer->filter[afi][safi];
1738
1739 /* Apply default weight value. */
1740 if (peer->weight[afi][safi])
1741 attr->weight = peer->weight[afi][safi];
1742
1743 if (rmap_name) {
1744 rmap = route_map_lookup_by_name(rmap_name);
1745
1746 if (rmap == NULL)
1747 return RMAP_DENY;
1748 } else {
1749 if (ROUTE_MAP_IN_NAME(filter)) {
1750 rmap = ROUTE_MAP_IN(filter);
1751
1752 if (rmap == NULL)
1753 return RMAP_DENY;
1754 }
1755 }
1756
1757 /* Route map apply. */
1758 if (rmap) {
1759 memset(&rmap_path, 0, sizeof(rmap_path));
1760 /* Duplicate current value to new structure for modification. */
1761 rmap_path.peer = peer;
1762 rmap_path.attr = attr;
1763 rmap_path.extra = &extra;
1764 rmap_path.net = dest;
1765
1766 extra.num_labels = num_labels;
1767 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1768 memcpy(extra.label, label,
1769 num_labels * sizeof(mpls_label_t));
1770
1771 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1772
1773 /* Apply BGP route map to the attribute. */
1774 ret = route_map_apply(rmap, p, &rmap_path);
1775
1776 peer->rmap_type = 0;
1777
1778 if (ret == RMAP_DENYMATCH)
1779 return RMAP_DENY;
1780 }
1781 return RMAP_PERMIT;
1782 }
1783
1784 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1785 struct attr *attr, afi_t afi, safi_t safi,
1786 const char *rmap_name)
1787 {
1788 struct bgp_path_info rmap_path;
1789 route_map_result_t ret;
1790 struct route_map *rmap = NULL;
1791 uint8_t rmap_type;
1792
1793 /*
1794 * So if we get to this point and have no rmap_name
1795 * we want to just show the output as it currently
1796 * exists.
1797 */
1798 if (!rmap_name)
1799 return RMAP_PERMIT;
1800
1801 /* Apply default weight value. */
1802 if (peer->weight[afi][safi])
1803 attr->weight = peer->weight[afi][safi];
1804
1805 rmap = route_map_lookup_by_name(rmap_name);
1806
1807 /*
1808 * If we have a route map name and we do not find
1809 * the routemap that means we have an implicit
1810 * deny.
1811 */
1812 if (rmap == NULL)
1813 return RMAP_DENY;
1814
1815 memset(&rmap_path, 0, sizeof(rmap_path));
1816 /* Route map apply. */
1817 /* Duplicate current value to new structure for modification. */
1818 rmap_path.peer = peer;
1819 rmap_path.attr = attr;
1820
1821 rmap_type = peer->rmap_type;
1822 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1823
1824 /* Apply BGP route map to the attribute. */
1825 ret = route_map_apply(rmap, p, &rmap_path);
1826
1827 peer->rmap_type = rmap_type;
1828
1829 if (ret == RMAP_DENYMATCH)
1830 /*
1831 * caller has multiple error paths with bgp_attr_flush()
1832 */
1833 return RMAP_DENY;
1834
1835 return RMAP_PERMIT;
1836 }
1837
1838 /* If this is an EBGP peer with remove-private-AS */
1839 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1840 struct peer *peer, struct attr *attr)
1841 {
1842 if (peer->sort == BGP_PEER_EBGP
1843 && (peer_af_flag_check(peer, afi, safi,
1844 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1845 || peer_af_flag_check(peer, afi, safi,
1846 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1847 || peer_af_flag_check(peer, afi, safi,
1848 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1849 || peer_af_flag_check(peer, afi, safi,
1850 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1851 // Take action on the entire aspath
1852 if (peer_af_flag_check(peer, afi, safi,
1853 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1854 || peer_af_flag_check(peer, afi, safi,
1855 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1856 if (peer_af_flag_check(
1857 peer, afi, safi,
1858 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1859 attr->aspath = aspath_replace_private_asns(
1860 attr->aspath, bgp->as, peer->as);
1861
1862 /*
1863 * Even if the aspath consists of just private ASNs we
1864 * need to walk the AS-Path to maintain all instances
1865 * of the peer's ASN to break possible loops.
1866 */
1867 else
1868 attr->aspath = aspath_remove_private_asns(
1869 attr->aspath, peer->as);
1870 }
1871
1872 // 'all' was not specified so the entire aspath must be private
1873 // ASNs
1874 // for us to do anything
1875 else if (aspath_private_as_check(attr->aspath)) {
1876 if (peer_af_flag_check(
1877 peer, afi, safi,
1878 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1879 attr->aspath = aspath_replace_private_asns(
1880 attr->aspath, bgp->as, peer->as);
1881 else
1882 /*
1883 * Walk the aspath to retain any instances of
1884 * the peer_asn
1885 */
1886 attr->aspath = aspath_remove_private_asns(
1887 attr->aspath, peer->as);
1888 }
1889 }
1890 }
1891
1892 /* If this is an EBGP peer with as-override */
1893 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1894 struct peer *peer, struct attr *attr)
1895 {
1896 struct aspath *aspath;
1897
1898 if (peer->sort == BGP_PEER_EBGP &&
1899 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1900 if (attr->aspath->refcnt)
1901 aspath = aspath_dup(attr->aspath);
1902 else
1903 aspath = attr->aspath;
1904
1905 attr->aspath = aspath_intern(
1906 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1907
1908 aspath_free(aspath);
1909 }
1910 }
1911
1912 void bgp_attr_add_llgr_community(struct attr *attr)
1913 {
1914 struct community *old;
1915 struct community *new;
1916 struct community *merge;
1917 struct community *llgr;
1918
1919 old = bgp_attr_get_community(attr);
1920 llgr = community_str2com("llgr-stale");
1921
1922 assert(llgr);
1923
1924 if (old) {
1925 merge = community_merge(community_dup(old), llgr);
1926
1927 if (old->refcnt == 0)
1928 community_free(&old);
1929
1930 new = community_uniq_sort(merge);
1931 community_free(&merge);
1932 } else {
1933 new = community_dup(llgr);
1934 }
1935
1936 community_free(&llgr);
1937
1938 bgp_attr_set_community(attr, new);
1939 }
1940
1941 void bgp_attr_add_gshut_community(struct attr *attr)
1942 {
1943 struct community *old;
1944 struct community *new;
1945 struct community *merge;
1946 struct community *gshut;
1947
1948 old = bgp_attr_get_community(attr);
1949 gshut = community_str2com("graceful-shutdown");
1950
1951 assert(gshut);
1952
1953 if (old) {
1954 merge = community_merge(community_dup(old), gshut);
1955
1956 if (old->refcnt == 0)
1957 community_free(&old);
1958
1959 new = community_uniq_sort(merge);
1960 community_free(&merge);
1961 } else {
1962 new = community_dup(gshut);
1963 }
1964
1965 community_free(&gshut);
1966 bgp_attr_set_community(attr, new);
1967
1968 /* When we add the graceful-shutdown community we must also
1969 * lower the local-preference */
1970 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1971 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1972 }
1973
1974
1975 /* Notify BGP Conditional advertisement scanner process. */
1976 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1977 {
1978 struct peer *peer = SUBGRP_PEER(subgrp);
1979 afi_t afi = SUBGRP_AFI(subgrp);
1980 safi_t safi = SUBGRP_SAFI(subgrp);
1981 struct bgp_filter *filter = &peer->filter[afi][safi];
1982
1983 if (!ADVERTISE_MAP_NAME(filter))
1984 return;
1985
1986 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1987 return;
1988
1989 peer->advmap_table_change = true;
1990 }
1991
1992
1993 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1994 {
1995 if (family == AF_INET) {
1996 attr->nexthop.s_addr = INADDR_ANY;
1997 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1998 }
1999 if (family == AF_INET6)
2000 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
2001 if (family == AF_EVPN)
2002 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
2003 }
2004
2005 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
2006 struct update_subgroup *subgrp,
2007 const struct prefix *p, struct attr *attr,
2008 struct attr *post_attr)
2009 {
2010 struct bgp_filter *filter;
2011 struct peer *from;
2012 struct peer *peer;
2013 struct peer *onlypeer;
2014 struct bgp *bgp;
2015 struct attr *piattr;
2016 route_map_result_t ret;
2017 int transparent;
2018 int reflect;
2019 afi_t afi;
2020 safi_t safi;
2021 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
2022 bool nh_reset = false;
2023 uint64_t cum_bw;
2024
2025 if (DISABLE_BGP_ANNOUNCE)
2026 return false;
2027
2028 afi = SUBGRP_AFI(subgrp);
2029 safi = SUBGRP_SAFI(subgrp);
2030 peer = SUBGRP_PEER(subgrp);
2031 onlypeer = NULL;
2032 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2033 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2034
2035 from = pi->peer;
2036 filter = &peer->filter[afi][safi];
2037 bgp = SUBGRP_INST(subgrp);
2038 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2039 : pi->attr;
2040
2041 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2042 peer->pmax_out[afi][safi] != 0 &&
2043 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2044 if (BGP_DEBUG(update, UPDATE_OUT) ||
2045 BGP_DEBUG(update, UPDATE_PREFIX)) {
2046 zlog_debug("%s reached maximum prefix to be send (%u)",
2047 peer->host, peer->pmax_out[afi][safi]);
2048 }
2049 return false;
2050 }
2051
2052 #ifdef ENABLE_BGP_VNC
2053 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2054 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2055 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2056
2057 /*
2058 * direct and direct_ext type routes originate internally even
2059 * though they can have peer pointers that reference other
2060 * systems
2061 */
2062 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2063 __func__, p);
2064 samepeer_safe = 1;
2065 }
2066 #endif
2067
2068 if (((afi == AFI_IP) || (afi == AFI_IP6))
2069 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2070 && (pi->type == ZEBRA_ROUTE_BGP)
2071 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2072
2073 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2074
2075 samepeer_safe = 1;
2076 }
2077
2078 /* With addpath we may be asked to TX all kinds of paths so make sure
2079 * pi is valid */
2080 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2081 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2082 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2083 return false;
2084 }
2085
2086 /* If this is not the bestpath then check to see if there is an enabled
2087 * addpath
2088 * feature that requires us to advertise it */
2089 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
2090 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
2091 return false;
2092 }
2093 }
2094
2095 /* Aggregate-address suppress check. */
2096 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2097 return false;
2098
2099 /*
2100 * If we are doing VRF 2 VRF leaking via the import
2101 * statement, we want to prevent the route going
2102 * off box as that the RT and RD created are localy
2103 * significant and globaly useless.
2104 */
2105 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2106 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2107 return false;
2108
2109 /* If it's labeled safi, make sure the route has a valid label. */
2110 if (safi == SAFI_LABELED_UNICAST) {
2111 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2112 if (!bgp_is_valid_label(&label)) {
2113 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2114 zlog_debug("u%" PRIu64 ":s%" PRIu64
2115 " %pFX is filtered - no label (%p)",
2116 subgrp->update_group->id, subgrp->id,
2117 p, &label);
2118 return false;
2119 }
2120 }
2121
2122 /* Do not send back route to sender. */
2123 if (onlypeer && from == onlypeer) {
2124 return false;
2125 }
2126
2127 /* Do not send the default route in the BGP table if the neighbor is
2128 * configured for default-originate */
2129 if (CHECK_FLAG(peer->af_flags[afi][safi],
2130 PEER_FLAG_DEFAULT_ORIGINATE)) {
2131 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2132 return false;
2133 else if (p->family == AF_INET6 && p->prefixlen == 0)
2134 return false;
2135 }
2136
2137 /* Transparency check. */
2138 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2139 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2140 transparent = 1;
2141 else
2142 transparent = 0;
2143
2144 /* If community is not disabled check the no-export and local. */
2145 if (!transparent && bgp_community_filter(peer, piattr)) {
2146 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2147 zlog_debug("%s: community filter check fail for %pFX",
2148 __func__, p);
2149 return false;
2150 }
2151
2152 /* If the attribute has originator-id and it is same as remote
2153 peer's id. */
2154 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2155 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2156 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2157 zlog_debug(
2158 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2159 onlypeer, p);
2160 return false;
2161 }
2162
2163 /* ORF prefix-list filter check */
2164 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2165 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2166 || CHECK_FLAG(peer->af_cap[afi][safi],
2167 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2168 if (peer->orf_plist[afi][safi]) {
2169 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2170 == PREFIX_DENY) {
2171 if (bgp_debug_update(NULL, p,
2172 subgrp->update_group, 0))
2173 zlog_debug(
2174 "%pBP [Update:SEND] %pFX is filtered via ORF",
2175 peer, p);
2176 return false;
2177 }
2178 }
2179
2180 /* Output filter check. */
2181 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2182 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2183 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2184 p);
2185 return false;
2186 }
2187
2188 /* AS path loop check. */
2189 if (onlypeer && onlypeer->as_path_loop_detection
2190 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2191 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2192 zlog_debug(
2193 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2194 onlypeer, onlypeer->as);
2195 return false;
2196 }
2197
2198 /* If we're a CONFED we need to loop check the CONFED ID too */
2199 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2200 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2201 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2202 zlog_debug(
2203 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2204 peer, bgp->confed_id);
2205 return false;
2206 }
2207 }
2208
2209 /* Route-Reflect check. */
2210 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2211 reflect = 1;
2212 else
2213 reflect = 0;
2214
2215 /* IBGP reflection check. */
2216 if (reflect && !samepeer_safe) {
2217 /* A route from a Client peer. */
2218 if (CHECK_FLAG(from->af_flags[afi][safi],
2219 PEER_FLAG_REFLECTOR_CLIENT)) {
2220 /* Reflect to all the Non-Client peers and also to the
2221 Client peers other than the originator. Originator
2222 check
2223 is already done. So there is noting to do. */
2224 /* no bgp client-to-client reflection check. */
2225 if (CHECK_FLAG(bgp->flags,
2226 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2227 if (CHECK_FLAG(peer->af_flags[afi][safi],
2228 PEER_FLAG_REFLECTOR_CLIENT))
2229 return false;
2230 } else {
2231 /* A route from a Non-client peer. Reflect to all other
2232 clients. */
2233 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2234 PEER_FLAG_REFLECTOR_CLIENT))
2235 return false;
2236 }
2237 }
2238
2239 /* For modify attribute, copy it to temporary structure.
2240 * post_attr comes from BGP conditional advertisements, where
2241 * attributes are already processed by advertise-map route-map,
2242 * and this needs to be saved instead of overwriting from the
2243 * path attributes.
2244 */
2245 if (post_attr)
2246 *attr = *post_attr;
2247 else
2248 *attr = *piattr;
2249
2250 /* If local-preference is not set. */
2251 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2252 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2253 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2254 attr->local_pref = bgp->default_local_pref;
2255 }
2256
2257 /* If originator-id is not set and the route is to be reflected,
2258 set the originator id */
2259 if (reflect
2260 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2261 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2262 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2263 }
2264
2265 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2266 */
2267 if (peer->sort == BGP_PEER_EBGP
2268 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2269 if (from != bgp->peer_self && !transparent
2270 && !CHECK_FLAG(peer->af_flags[afi][safi],
2271 PEER_FLAG_MED_UNCHANGED))
2272 attr->flag &=
2273 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2274 }
2275
2276 /* Since the nexthop attribute can vary per peer, it is not explicitly
2277 * set
2278 * in announce check, only certain flags and length (or number of
2279 * nexthops
2280 * -- for IPv6/MP_REACH) are set here in order to guide the update
2281 * formation
2282 * code in setting the nexthop(s) on a per peer basis in
2283 * reformat_peer().
2284 * Typically, the source nexthop in the attribute is preserved but in
2285 * the
2286 * scenarios where we know it will always be overwritten, we reset the
2287 * nexthop to "0" in an attempt to achieve better Update packing. An
2288 * example of this is when a prefix from each of 2 IBGP peers needs to
2289 * be
2290 * announced to an EBGP peer (and they have the same attributes barring
2291 * their nexthop).
2292 */
2293 if (reflect)
2294 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2295
2296 #define NEXTHOP_IS_V6 \
2297 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2298 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2299 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2300 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2301
2302 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2303 * if
2304 * the peer (group) is configured to receive link-local nexthop
2305 * unchanged
2306 * and it is available in the prefix OR we're not reflecting the route,
2307 * link-local nexthop address is valid and
2308 * the peer (group) to whom we're going to announce is on a shared
2309 * network
2310 * and this is either a self-originated route or the peer is EBGP.
2311 * By checking if nexthop LL address is valid we are sure that
2312 * we do not announce LL address as `::`.
2313 */
2314 if (NEXTHOP_IS_V6) {
2315 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2316 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2317 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2318 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2319 || (!reflect && !transparent
2320 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2321 && peer->shared_network
2322 && (from == bgp->peer_self
2323 || peer->sort == BGP_PEER_EBGP))) {
2324 attr->mp_nexthop_len =
2325 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2326 }
2327
2328 /* Clear off link-local nexthop in source, whenever it is not
2329 * needed to
2330 * ensure more prefixes share the same attribute for
2331 * announcement.
2332 */
2333 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2334 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2335 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2336 }
2337
2338 if (bgp_check_role_applicability(afi, safi) &&
2339 bgp_otc_egress(peer, attr))
2340 return false;
2341
2342 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2343 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2344
2345 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2346 filter->advmap.aname &&
2347 route_map_lookup_by_name(filter->advmap.aname)) {
2348 struct bgp_path_info rmap_path = {0};
2349 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2350 struct attr dummy_attr = *attr;
2351
2352 /* Fill temp path_info */
2353 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2354 pi, peer, &dummy_attr);
2355
2356 struct route_map *amap =
2357 route_map_lookup_by_name(filter->advmap.aname);
2358
2359 ret = route_map_apply(amap, p, &rmap_path);
2360
2361 bgp_attr_flush(&dummy_attr);
2362
2363 /*
2364 * The conditional advertisement mode is Withdraw and this
2365 * prefix is a conditional prefix. Don't advertise it
2366 */
2367 if (ret == RMAP_PERMITMATCH)
2368 return false;
2369 }
2370
2371 /* Route map & unsuppress-map apply. */
2372 if (!post_attr &&
2373 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2374 struct bgp_path_info rmap_path = {0};
2375 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2376 struct attr dummy_attr = {0};
2377
2378 /* Fill temp path_info */
2379 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2380 pi, peer, attr);
2381
2382 /* don't confuse inbound and outbound setting */
2383 RESET_FLAG(attr->rmap_change_flags);
2384
2385 /*
2386 * The route reflector is not allowed to modify the attributes
2387 * of the reflected IBGP routes unless explicitly allowed.
2388 */
2389 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2390 && !CHECK_FLAG(bgp->flags,
2391 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2392 dummy_attr = *attr;
2393 rmap_path.attr = &dummy_attr;
2394 }
2395
2396 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2397
2398 if (bgp_path_suppressed(pi))
2399 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2400 &rmap_path);
2401 else
2402 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2403 &rmap_path);
2404
2405 bgp_attr_flush(&dummy_attr);
2406 peer->rmap_type = 0;
2407
2408 if (ret == RMAP_DENYMATCH) {
2409 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2410 zlog_debug(
2411 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2412 peer, p, ROUTE_MAP_OUT_NAME(filter));
2413 bgp_attr_flush(rmap_path.attr);
2414 return false;
2415 }
2416 }
2417
2418 /* RFC 8212 to prevent route leaks.
2419 * This specification intends to improve this situation by requiring the
2420 * explicit configuration of both BGP Import and Export Policies for any
2421 * External BGP (EBGP) session such as customers, peers, or
2422 * confederation boundaries for all enabled address families. Through
2423 * codification of the aforementioned requirement, operators will
2424 * benefit from consistent behavior across different BGP
2425 * implementations.
2426 */
2427 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2428 if (!bgp_outbound_policy_exists(peer, filter)) {
2429 if (monotime_since(&bgp->ebgprequirespolicywarning,
2430 NULL) > FIFTEENMINUTE2USEC ||
2431 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2432 zlog_warn(
2433 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2434 monotime(&bgp->ebgprequirespolicywarning);
2435 }
2436 return false;
2437 }
2438
2439 /* draft-ietf-idr-deprecate-as-set-confed-set
2440 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2441 * Eventually, This document (if approved) updates RFC 4271
2442 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2443 * and obsoletes RFC 6472.
2444 */
2445 if (peer->bgp->reject_as_sets)
2446 if (aspath_check_as_sets(attr->aspath))
2447 return false;
2448
2449 /* If neighbor soo is configured, then check if the route has
2450 * SoO extended community and validate against the configured
2451 * one. If they match, do not announce, to prevent routing
2452 * loops.
2453 */
2454 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2455 peer->soo[afi][safi]) {
2456 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2457 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2458
2459 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2460 ECOMMUNITY_SITE_ORIGIN) ||
2461 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2462 ECOMMUNITY_SITE_ORIGIN) ||
2463 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2464 ECOMMUNITY_SITE_ORIGIN)) &&
2465 ecommunity_include(ecomm, ecomm_soo)) {
2466 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2467 zlog_debug(
2468 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2469 peer, p, ecommunity_str(ecomm_soo));
2470 return false;
2471 }
2472 }
2473
2474 /* Codification of AS 0 Processing */
2475 if (aspath_check_as_zero(attr->aspath))
2476 return false;
2477
2478 if (bgp_in_graceful_shutdown(bgp)) {
2479 if (peer->sort == BGP_PEER_IBGP
2480 || peer->sort == BGP_PEER_CONFED) {
2481 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2482 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2483 } else {
2484 bgp_attr_add_gshut_community(attr);
2485 }
2486 }
2487
2488 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2489 * Capability" to a neighbor MUST perform the following upon receiving
2490 * a route from that neighbor with the "LLGR_STALE" community, or upon
2491 * attaching the "LLGR_STALE" community itself per Section 4.2:
2492 *
2493 * The route SHOULD NOT be advertised to any neighbor from which the
2494 * Long-lived Graceful Restart Capability has not been received.
2495 */
2496 if (bgp_attr_get_community(attr) &&
2497 community_include(bgp_attr_get_community(attr),
2498 COMMUNITY_LLGR_STALE) &&
2499 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2500 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2501 return false;
2502
2503 /* After route-map has been applied, we check to see if the nexthop to
2504 * be carried in the attribute (that is used for the announcement) can
2505 * be cleared off or not. We do this in all cases where we would be
2506 * setting the nexthop to "ourselves". For IPv6, we only need to
2507 * consider
2508 * the global nexthop here; the link-local nexthop would have been
2509 * cleared
2510 * already, and if not, it is required by the update formation code.
2511 * Also see earlier comments in this function.
2512 */
2513 /*
2514 * If route-map has performed some operation on the nexthop or the peer
2515 * configuration says to pass it unchanged, we cannot reset the nexthop
2516 * here, so only attempt to do it if these aren't true. Note that the
2517 * route-map handler itself might have cleared the nexthop, if for
2518 * example,
2519 * it is configured as 'peer-address'.
2520 */
2521 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2522 piattr->rmap_change_flags)
2523 && !transparent
2524 && !CHECK_FLAG(peer->af_flags[afi][safi],
2525 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2526 /* We can reset the nexthop, if setting (or forcing) it to
2527 * 'self' */
2528 if (CHECK_FLAG(peer->af_flags[afi][safi],
2529 PEER_FLAG_NEXTHOP_SELF)
2530 || CHECK_FLAG(peer->af_flags[afi][safi],
2531 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2532 if (!reflect
2533 || CHECK_FLAG(peer->af_flags[afi][safi],
2534 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
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 } else if (peer->sort == BGP_PEER_EBGP) {
2543 /* Can also reset the nexthop if announcing to EBGP, but
2544 * only if
2545 * no peer in the subgroup is on a shared subnet.
2546 * Note: 3rd party nexthop currently implemented for
2547 * IPv4 only.
2548 */
2549 if ((p->family == AF_INET) &&
2550 (!bgp_subgrp_multiaccess_check_v4(
2551 piattr->nexthop,
2552 subgrp, from))) {
2553 subgroup_announce_reset_nhop(
2554 (peer_cap_enhe(peer, afi, safi)
2555 ? AF_INET6
2556 : p->family),
2557 attr);
2558 nh_reset = true;
2559 }
2560
2561 if ((p->family == AF_INET6) &&
2562 (!bgp_subgrp_multiaccess_check_v6(
2563 piattr->mp_nexthop_global,
2564 subgrp, from))) {
2565 subgroup_announce_reset_nhop(
2566 (peer_cap_enhe(peer, afi, safi)
2567 ? AF_INET6
2568 : p->family),
2569 attr);
2570 nh_reset = true;
2571 }
2572
2573
2574
2575 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2576 /*
2577 * This flag is used for leaked vpn-vrf routes
2578 */
2579 int family = p->family;
2580
2581 if (peer_cap_enhe(peer, afi, safi))
2582 family = AF_INET6;
2583
2584 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2585 zlog_debug(
2586 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2587 __func__, family2str(family));
2588 subgroup_announce_reset_nhop(family, attr);
2589 nh_reset = true;
2590 }
2591 }
2592
2593 /* If IPv6/MP and nexthop does not have any override and happens
2594 * to
2595 * be a link-local address, reset it so that we don't pass along
2596 * the
2597 * source's link-local IPv6 address to recipients who may not be
2598 * on
2599 * the same interface.
2600 */
2601 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2602 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2603 subgroup_announce_reset_nhop(AF_INET6, attr);
2604 nh_reset = true;
2605 }
2606 }
2607
2608 /* If this is an iBGP, send Origin Validation State (OVS)
2609 * extended community (rfc8097).
2610 */
2611 if (peer->sort == BGP_PEER_IBGP) {
2612 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2613
2614 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2615
2616 if (rpki_state != RPKI_NOT_BEING_USED)
2617 bgp_attr_set_ecommunity(
2618 attr, ecommunity_add_origin_validation_state(
2619 rpki_state,
2620 bgp_attr_get_ecommunity(attr)));
2621 }
2622
2623 /*
2624 * When the next hop is set to ourselves, if all multipaths have
2625 * link-bandwidth announce the cumulative bandwidth as that makes
2626 * the most sense. However, don't modify if the link-bandwidth has
2627 * been explicitly set by user policy.
2628 */
2629 if (nh_reset &&
2630 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2631 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2632 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2633 bgp_attr_set_ecommunity(
2634 attr,
2635 ecommunity_replace_linkbw(
2636 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2637 CHECK_FLAG(
2638 peer->flags,
2639 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2640
2641 return true;
2642 }
2643
2644 static void bgp_route_select_timer_expire(struct thread *thread)
2645 {
2646 struct afi_safi_info *info;
2647 afi_t afi;
2648 safi_t safi;
2649 struct bgp *bgp;
2650
2651 info = THREAD_ARG(thread);
2652 afi = info->afi;
2653 safi = info->safi;
2654 bgp = info->bgp;
2655
2656 if (BGP_DEBUG(update, UPDATE_OUT))
2657 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2658 safi);
2659
2660 bgp->gr_info[afi][safi].t_route_select = NULL;
2661
2662 XFREE(MTYPE_TMP, info);
2663
2664 /* Best path selection */
2665 bgp_best_path_select_defer(bgp, afi, safi);
2666 }
2667
2668 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2669 struct bgp_maxpaths_cfg *mpath_cfg,
2670 struct bgp_path_info_pair *result, afi_t afi,
2671 safi_t safi)
2672 {
2673 struct bgp_path_info *new_select;
2674 struct bgp_path_info *old_select;
2675 struct bgp_path_info *pi;
2676 struct bgp_path_info *pi1;
2677 struct bgp_path_info *pi2;
2678 struct bgp_path_info *nextpi = NULL;
2679 int paths_eq, do_mpath, debug;
2680 struct list mp_list;
2681 char pfx_buf[PREFIX2STR_BUFFER];
2682 char path_buf[PATH_ADDPATH_STR_BUFFER];
2683
2684 bgp_mp_list_init(&mp_list);
2685 do_mpath =
2686 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2687
2688 debug = bgp_debug_bestpath(dest);
2689
2690 if (debug)
2691 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2692
2693 dest->reason = bgp_path_selection_none;
2694 /* bgp deterministic-med */
2695 new_select = NULL;
2696 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2697
2698 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2699 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2700 pi1 = pi1->next)
2701 bgp_path_info_unset_flag(dest, pi1,
2702 BGP_PATH_DMED_SELECTED);
2703
2704 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2705 pi1 = pi1->next) {
2706 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2707 continue;
2708 if (BGP_PATH_HOLDDOWN(pi1))
2709 continue;
2710 if (pi1->peer != bgp->peer_self)
2711 if (!peer_established(pi1->peer))
2712 continue;
2713
2714 new_select = pi1;
2715 if (pi1->next) {
2716 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2717 if (CHECK_FLAG(pi2->flags,
2718 BGP_PATH_DMED_CHECK))
2719 continue;
2720 if (BGP_PATH_HOLDDOWN(pi2))
2721 continue;
2722 if (pi2->peer != bgp->peer_self
2723 && !CHECK_FLAG(
2724 pi2->peer->sflags,
2725 PEER_STATUS_NSF_WAIT))
2726 if (pi2->peer->status
2727 != Established)
2728 continue;
2729
2730 if (!aspath_cmp_left(pi1->attr->aspath,
2731 pi2->attr->aspath)
2732 && !aspath_cmp_left_confed(
2733 pi1->attr->aspath,
2734 pi2->attr->aspath))
2735 continue;
2736
2737 if (bgp_path_info_cmp(
2738 bgp, pi2, new_select,
2739 &paths_eq, mpath_cfg, debug,
2740 pfx_buf, afi, safi,
2741 &dest->reason)) {
2742 bgp_path_info_unset_flag(
2743 dest, new_select,
2744 BGP_PATH_DMED_SELECTED);
2745 new_select = pi2;
2746 }
2747
2748 bgp_path_info_set_flag(
2749 dest, pi2, BGP_PATH_DMED_CHECK);
2750 }
2751 }
2752 bgp_path_info_set_flag(dest, new_select,
2753 BGP_PATH_DMED_CHECK);
2754 bgp_path_info_set_flag(dest, new_select,
2755 BGP_PATH_DMED_SELECTED);
2756
2757 if (debug) {
2758 bgp_path_info_path_with_addpath_rx_str(
2759 new_select, path_buf, sizeof(path_buf));
2760 zlog_debug(
2761 "%pBD(%s): %s is the bestpath from AS %u",
2762 dest, bgp->name_pretty, path_buf,
2763 aspath_get_first_as(
2764 new_select->attr->aspath));
2765 }
2766 }
2767 }
2768
2769 /* Check old selected route and new selected route. */
2770 old_select = NULL;
2771 new_select = NULL;
2772 for (pi = bgp_dest_get_bgp_path_info(dest);
2773 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2774 enum bgp_path_selection_reason reason;
2775
2776 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2777 old_select = pi;
2778
2779 if (BGP_PATH_HOLDDOWN(pi)) {
2780 /* reap REMOVED routes, if needs be
2781 * selected route must stay for a while longer though
2782 */
2783 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2784 && (pi != old_select))
2785 bgp_path_info_reap(dest, pi);
2786
2787 if (debug)
2788 zlog_debug("%s: pi %p in holddown", __func__,
2789 pi);
2790
2791 continue;
2792 }
2793
2794 if (pi->peer && pi->peer != bgp->peer_self
2795 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2796 if (!peer_established(pi->peer)) {
2797
2798 if (debug)
2799 zlog_debug(
2800 "%s: pi %p non self peer %s not estab state",
2801 __func__, pi, pi->peer->host);
2802
2803 continue;
2804 }
2805
2806 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2807 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2808 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2809 if (debug)
2810 zlog_debug("%s: pi %p dmed", __func__, pi);
2811 continue;
2812 }
2813
2814 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2815
2816 reason = dest->reason;
2817 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2818 debug, pfx_buf, afi, safi,
2819 &dest->reason)) {
2820 if (new_select == NULL &&
2821 reason != bgp_path_selection_none)
2822 dest->reason = reason;
2823 new_select = pi;
2824 }
2825 }
2826
2827 /* Now that we know which path is the bestpath see if any of the other
2828 * paths
2829 * qualify as multipaths
2830 */
2831 if (debug) {
2832 if (new_select)
2833 bgp_path_info_path_with_addpath_rx_str(
2834 new_select, path_buf, sizeof(path_buf));
2835 else
2836 snprintf(path_buf, sizeof(path_buf), "NONE");
2837 zlog_debug(
2838 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2839 dest, bgp->name_pretty, path_buf,
2840 old_select ? old_select->peer->host : "NONE");
2841 }
2842
2843 if (do_mpath && new_select) {
2844 for (pi = bgp_dest_get_bgp_path_info(dest);
2845 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2846
2847 if (debug)
2848 bgp_path_info_path_with_addpath_rx_str(
2849 pi, path_buf, sizeof(path_buf));
2850
2851 if (pi == new_select) {
2852 if (debug)
2853 zlog_debug(
2854 "%pBD(%s): %s is the bestpath, add to the multipath list",
2855 dest, bgp->name_pretty,
2856 path_buf);
2857 bgp_mp_list_add(&mp_list, pi);
2858 continue;
2859 }
2860
2861 if (BGP_PATH_HOLDDOWN(pi))
2862 continue;
2863
2864 if (pi->peer && pi->peer != bgp->peer_self
2865 && !CHECK_FLAG(pi->peer->sflags,
2866 PEER_STATUS_NSF_WAIT))
2867 if (!peer_established(pi->peer))
2868 continue;
2869
2870 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2871 if (debug)
2872 zlog_debug(
2873 "%pBD: %s has the same nexthop as the bestpath, skip it",
2874 dest, path_buf);
2875 continue;
2876 }
2877
2878 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2879 mpath_cfg, debug, pfx_buf, afi, safi,
2880 &dest->reason);
2881
2882 if (paths_eq) {
2883 if (debug)
2884 zlog_debug(
2885 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2886 dest, path_buf);
2887 bgp_mp_list_add(&mp_list, pi);
2888 }
2889 }
2890 }
2891
2892 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2893 mpath_cfg);
2894 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2895 bgp_mp_list_clear(&mp_list);
2896
2897 bgp_addpath_update_ids(bgp, dest, afi, safi);
2898
2899 result->old = old_select;
2900 result->new = new_select;
2901
2902 return;
2903 }
2904
2905 /*
2906 * A new route/change in bestpath of an existing route. Evaluate the path
2907 * for advertisement to the subgroup.
2908 */
2909 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2910 struct bgp_path_info *selected,
2911 struct bgp_dest *dest,
2912 uint32_t addpath_tx_id)
2913 {
2914 const struct prefix *p;
2915 struct peer *onlypeer;
2916 struct attr attr;
2917 afi_t afi;
2918 safi_t safi;
2919 struct bgp *bgp;
2920 bool advertise;
2921
2922 p = bgp_dest_get_prefix(dest);
2923 afi = SUBGRP_AFI(subgrp);
2924 safi = SUBGRP_SAFI(subgrp);
2925 bgp = SUBGRP_INST(subgrp);
2926 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2927 : NULL);
2928
2929 if (BGP_DEBUG(update, UPDATE_OUT))
2930 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2931
2932 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2933 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2934 PEER_STATUS_ORF_WAIT_REFRESH))
2935 return;
2936
2937 memset(&attr, 0, sizeof(attr));
2938 /* It's initialized in bgp_announce_check() */
2939
2940 /* Announcement to the subgroup. If the route is filtered withdraw it.
2941 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2942 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2943 * route
2944 */
2945 advertise = bgp_check_advertise(bgp, dest);
2946
2947 if (selected) {
2948 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2949 NULL)) {
2950 /* Route is selected, if the route is already installed
2951 * in FIB, then it is advertised
2952 */
2953 if (advertise) {
2954 if (!bgp_check_withdrawal(bgp, dest))
2955 bgp_adj_out_set_subgroup(
2956 dest, subgrp, &attr, selected);
2957 else
2958 bgp_adj_out_unset_subgroup(
2959 dest, subgrp, 1, addpath_tx_id);
2960 }
2961 } else
2962 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2963 addpath_tx_id);
2964 }
2965
2966 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2967 else {
2968 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2969 }
2970 }
2971
2972 /*
2973 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2974 * This is called at the end of route processing.
2975 */
2976 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2977 {
2978 struct bgp_path_info *pi;
2979
2980 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2981 if (BGP_PATH_HOLDDOWN(pi))
2982 continue;
2983 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2984 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2985 }
2986 }
2987
2988 /*
2989 * Has the route changed from the RIB's perspective? This is invoked only
2990 * if the route selection returns the same best route as earlier - to
2991 * determine if we need to update zebra or not.
2992 */
2993 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2994 {
2995 struct bgp_path_info *mpinfo;
2996
2997 /* If this is multipath, check all selected paths for any nexthop
2998 * change or attribute change. Some attribute changes (e.g., community)
2999 * aren't of relevance to the RIB, but we'll update zebra to ensure
3000 * we handle the case of BGP nexthop change. This is the behavior
3001 * when the best path has an attribute change anyway.
3002 */
3003 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
3004 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
3005 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
3006 return true;
3007
3008 /*
3009 * If this is multipath, check all selected paths for any nexthop change
3010 */
3011 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
3012 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3013 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3014 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3015 return true;
3016 }
3017
3018 /* Nothing has changed from the RIB's perspective. */
3019 return false;
3020 }
3021
3022 struct bgp_process_queue {
3023 struct bgp *bgp;
3024 STAILQ_HEAD(, bgp_dest) pqueue;
3025 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3026 unsigned int flags;
3027 unsigned int queued;
3028 };
3029
3030 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3031 safi_t safi, struct bgp_dest *dest,
3032 struct bgp_path_info *new_select,
3033 struct bgp_path_info *old_select)
3034 {
3035 const struct prefix *p = bgp_dest_get_prefix(dest);
3036
3037 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3038 return;
3039
3040 if (advertise_type5_routes(bgp, afi) && new_select
3041 && is_route_injectable_into_evpn(new_select)) {
3042
3043 /* apply the route-map */
3044 if (bgp->adv_cmd_rmap[afi][safi].map) {
3045 route_map_result_t ret;
3046 struct bgp_path_info rmap_path;
3047 struct bgp_path_info_extra rmap_path_extra;
3048 struct attr dummy_attr;
3049
3050 dummy_attr = *new_select->attr;
3051
3052 /* Fill temp path_info */
3053 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3054 new_select, new_select->peer,
3055 &dummy_attr);
3056
3057 RESET_FLAG(dummy_attr.rmap_change_flags);
3058
3059 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3060 p, &rmap_path);
3061
3062 if (ret == RMAP_DENYMATCH) {
3063 bgp_attr_flush(&dummy_attr);
3064 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3065 safi);
3066 } else
3067 bgp_evpn_advertise_type5_route(
3068 bgp, p, &dummy_attr, afi, safi);
3069 } else {
3070 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3071 afi, safi);
3072 }
3073 } else if (advertise_type5_routes(bgp, afi) && old_select
3074 && is_route_injectable_into_evpn(old_select))
3075 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3076 }
3077
3078 /*
3079 * Utility to determine whether a particular path_info should use
3080 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3081 * in a path where we basically _know_ this is a BGP-LU route.
3082 */
3083 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3084 {
3085 /* Certain types get imp null; so do paths where the nexthop is
3086 * not labeled.
3087 */
3088 if (new_select->sub_type == BGP_ROUTE_STATIC
3089 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3090 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3091 return true;
3092 else if (new_select->extra == NULL ||
3093 !bgp_is_valid_label(&new_select->extra->label[0]))
3094 /* TODO -- should be configurable? */
3095 return true;
3096 else
3097 return false;
3098 }
3099
3100 /*
3101 * old_select = The old best path
3102 * new_select = the new best path
3103 *
3104 * if (!old_select && new_select)
3105 * We are sending new information on.
3106 *
3107 * if (old_select && new_select) {
3108 * if (new_select != old_select)
3109 * We have a new best path send a change
3110 * else
3111 * We've received a update with new attributes that needs
3112 * to be passed on.
3113 * }
3114 *
3115 * if (old_select && !new_select)
3116 * We have no eligible route that we can announce or the rn
3117 * is being removed.
3118 */
3119 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3120 afi_t afi, safi_t safi)
3121 {
3122 struct bgp_path_info *new_select;
3123 struct bgp_path_info *old_select;
3124 struct bgp_path_info_pair old_and_new;
3125 int debug = 0;
3126
3127 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3128 if (dest)
3129 debug = bgp_debug_bestpath(dest);
3130 if (debug)
3131 zlog_debug(
3132 "%s: bgp delete in progress, ignoring event, p=%pBD",
3133 __func__, dest);
3134 return;
3135 }
3136 /* Is it end of initial update? (after startup) */
3137 if (!dest) {
3138 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3139 sizeof(bgp->update_delay_zebra_resume_time));
3140
3141 bgp->main_zebra_update_hold = 0;
3142 FOREACH_AFI_SAFI (afi, safi) {
3143 if (bgp_fibupd_safi(safi))
3144 bgp_zebra_announce_table(bgp, afi, safi);
3145 }
3146 bgp->main_peers_update_hold = 0;
3147
3148 bgp_start_routeadv(bgp);
3149 return;
3150 }
3151
3152 const struct prefix *p = bgp_dest_get_prefix(dest);
3153
3154 debug = bgp_debug_bestpath(dest);
3155 if (debug)
3156 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3157 dest, bgp->name_pretty, afi2str(afi),
3158 safi2str(safi));
3159
3160 /* The best path calculation for the route is deferred if
3161 * BGP_NODE_SELECT_DEFER is set
3162 */
3163 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3164 if (BGP_DEBUG(update, UPDATE_OUT))
3165 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3166 return;
3167 }
3168
3169 /* Best path selection. */
3170 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3171 afi, safi);
3172 old_select = old_and_new.old;
3173 new_select = old_and_new.new;
3174
3175 /* Do we need to allocate or free labels?
3176 * Right now, since we only deal with per-prefix labels, it is not
3177 * necessary to do this upon changes to best path. Exceptions:
3178 * - label index has changed -> recalculate resulting label
3179 * - path_info sub_type changed -> switch to/from implicit-null
3180 * - no valid label (due to removed static label binding) -> get new one
3181 */
3182 if (bgp->allocate_mpls_labels[afi][safi]) {
3183 if (new_select) {
3184 if (!old_select
3185 || bgp_label_index_differs(new_select, old_select)
3186 || new_select->sub_type != old_select->sub_type
3187 || !bgp_is_valid_label(&dest->local_label)) {
3188 /* Enforced penultimate hop popping:
3189 * implicit-null for local routes, aggregate
3190 * and redistributed routes
3191 */
3192 if (bgp_lu_need_imp_null(new_select)) {
3193 if (CHECK_FLAG(
3194 dest->flags,
3195 BGP_NODE_REGISTERED_FOR_LABEL)
3196 || CHECK_FLAG(
3197 dest->flags,
3198 BGP_NODE_LABEL_REQUESTED))
3199 bgp_unregister_for_label(dest);
3200 dest->local_label = mpls_lse_encode(
3201 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3202 1);
3203 bgp_set_valid_label(&dest->local_label);
3204 } else
3205 bgp_register_for_label(dest,
3206 new_select);
3207 }
3208 } else if (CHECK_FLAG(dest->flags,
3209 BGP_NODE_REGISTERED_FOR_LABEL)
3210 || CHECK_FLAG(dest->flags,
3211 BGP_NODE_LABEL_REQUESTED)) {
3212 bgp_unregister_for_label(dest);
3213 }
3214 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3215 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3216 bgp_unregister_for_label(dest);
3217 }
3218
3219 if (debug)
3220 zlog_debug(
3221 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3222 __func__, dest, bgp->name_pretty, afi2str(afi),
3223 safi2str(safi), old_select, new_select);
3224
3225 /* If best route remains the same and this is not due to user-initiated
3226 * clear, see exactly what needs to be done.
3227 */
3228 if (old_select && old_select == new_select
3229 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3230 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3231 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3232 if (bgp_zebra_has_route_changed(old_select)) {
3233 #ifdef ENABLE_BGP_VNC
3234 vnc_import_bgp_add_route(bgp, p, old_select);
3235 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3236 #endif
3237 if (bgp_fibupd_safi(safi)
3238 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3239
3240 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3241 && new_select->sub_type == BGP_ROUTE_NORMAL)
3242 SET_FLAG(dest->flags,
3243 BGP_NODE_FIB_INSTALL_PENDING);
3244
3245 if (new_select->type == ZEBRA_ROUTE_BGP
3246 && (new_select->sub_type == BGP_ROUTE_NORMAL
3247 || new_select->sub_type
3248 == BGP_ROUTE_IMPORTED))
3249
3250 bgp_zebra_announce(dest, p, old_select,
3251 bgp, afi, safi);
3252 }
3253 }
3254
3255 /* If there is a change of interest to peers, reannounce the
3256 * route. */
3257 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3258 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3259 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3260 group_announce_route(bgp, afi, safi, dest, new_select);
3261
3262 /* unicast routes must also be annouced to
3263 * labeled-unicast update-groups */
3264 if (safi == SAFI_UNICAST)
3265 group_announce_route(bgp, afi,
3266 SAFI_LABELED_UNICAST, dest,
3267 new_select);
3268
3269 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3270 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3271 }
3272
3273 /* advertise/withdraw type-5 routes */
3274 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3275 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3276 bgp_process_evpn_route_injection(
3277 bgp, afi, safi, dest, old_select, old_select);
3278
3279 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3280 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3281 bgp_zebra_clear_route_change_flags(dest);
3282 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3283 return;
3284 }
3285
3286 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3287 */
3288 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3289
3290 /* bestpath has changed; bump version */
3291 if (old_select || new_select) {
3292 bgp_bump_version(dest);
3293
3294 if (!bgp->t_rmap_def_originate_eval) {
3295 bgp_lock(bgp);
3296 thread_add_timer(
3297 bm->master,
3298 update_group_refresh_default_originate_route_map,
3299 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3300 &bgp->t_rmap_def_originate_eval);
3301 }
3302 }
3303
3304 if (old_select)
3305 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3306 if (new_select) {
3307 if (debug)
3308 zlog_debug("%s: setting SELECTED flag", __func__);
3309 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3310 bgp_path_info_unset_flag(dest, new_select,
3311 BGP_PATH_ATTR_CHANGED);
3312 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3313 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3314 }
3315
3316 #ifdef ENABLE_BGP_VNC
3317 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3318 if (old_select != new_select) {
3319 if (old_select) {
3320 vnc_import_bgp_exterior_del_route(bgp, p,
3321 old_select);
3322 vnc_import_bgp_del_route(bgp, p, old_select);
3323 }
3324 if (new_select) {
3325 vnc_import_bgp_exterior_add_route(bgp, p,
3326 new_select);
3327 vnc_import_bgp_add_route(bgp, p, new_select);
3328 }
3329 }
3330 }
3331 #endif
3332
3333 group_announce_route(bgp, afi, safi, dest, new_select);
3334
3335 /* unicast routes must also be annouced to labeled-unicast update-groups
3336 */
3337 if (safi == SAFI_UNICAST)
3338 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3339 new_select);
3340
3341 /* FIB update. */
3342 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3343 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3344
3345 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3346 && (new_select->sub_type == BGP_ROUTE_NORMAL
3347 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3348 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3349
3350 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3351 SET_FLAG(dest->flags,
3352 BGP_NODE_FIB_INSTALL_PENDING);
3353
3354 /* if this is an evpn imported type-5 prefix,
3355 * we need to withdraw the route first to clear
3356 * the nh neigh and the RMAC entry.
3357 */
3358 if (old_select &&
3359 is_route_parent_evpn(old_select))
3360 bgp_zebra_withdraw(p, old_select, bgp, safi);
3361
3362 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3363 } else {
3364 /* Withdraw the route from the kernel. */
3365 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3366 && (old_select->sub_type == BGP_ROUTE_NORMAL
3367 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3368 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3369
3370 bgp_zebra_withdraw(p, old_select, bgp, safi);
3371 }
3372 }
3373
3374 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3375 old_select);
3376
3377 /* Clear any route change flags. */
3378 bgp_zebra_clear_route_change_flags(dest);
3379
3380 /* Reap old select bgp_path_info, if it has been removed */
3381 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3382 bgp_path_info_reap(dest, old_select);
3383
3384 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3385 return;
3386 }
3387
3388 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3389 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3390 {
3391 struct bgp_dest *dest;
3392 int cnt = 0;
3393 struct afi_safi_info *thread_info;
3394
3395 if (bgp->gr_info[afi][safi].t_route_select) {
3396 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3397
3398 thread_info = THREAD_ARG(t);
3399 XFREE(MTYPE_TMP, thread_info);
3400 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3401 }
3402
3403 if (BGP_DEBUG(update, UPDATE_OUT)) {
3404 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3405 get_afi_safi_str(afi, safi, false),
3406 bgp->gr_info[afi][safi].gr_deferred);
3407 }
3408
3409 /* Process the route list */
3410 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3411 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3412 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3413 dest = bgp_route_next(dest)) {
3414 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3415 continue;
3416
3417 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3418 bgp->gr_info[afi][safi].gr_deferred--;
3419 bgp_process_main_one(bgp, dest, afi, safi);
3420 cnt++;
3421 }
3422 /* If iteration stopped before the entire table was traversed then the
3423 * node needs to be unlocked.
3424 */
3425 if (dest) {
3426 bgp_dest_unlock_node(dest);
3427 dest = NULL;
3428 }
3429
3430 /* Send EOR message when all routes are processed */
3431 if (!bgp->gr_info[afi][safi].gr_deferred) {
3432 bgp_send_delayed_eor(bgp);
3433 /* Send route processing complete message to RIB */
3434 bgp_zebra_update(afi, safi, bgp->vrf_id,
3435 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3436 return;
3437 }
3438
3439 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3440
3441 thread_info->afi = afi;
3442 thread_info->safi = safi;
3443 thread_info->bgp = bgp;
3444
3445 /* If there are more routes to be processed, start the
3446 * selection timer
3447 */
3448 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3449 BGP_ROUTE_SELECT_DELAY,
3450 &bgp->gr_info[afi][safi].t_route_select);
3451 }
3452
3453 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3454 {
3455 struct bgp_process_queue *pqnode = data;
3456 struct bgp *bgp = pqnode->bgp;
3457 struct bgp_table *table;
3458 struct bgp_dest *dest;
3459
3460 /* eoiu marker */
3461 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3462 bgp_process_main_one(bgp, NULL, 0, 0);
3463 /* should always have dedicated wq call */
3464 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3465 return WQ_SUCCESS;
3466 }
3467
3468 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3469 dest = STAILQ_FIRST(&pqnode->pqueue);
3470 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3471 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3472 table = bgp_dest_table(dest);
3473 /* note, new DESTs may be added as part of processing */
3474 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3475
3476 bgp_dest_unlock_node(dest);
3477 bgp_table_unlock(table);
3478 }
3479
3480 return WQ_SUCCESS;
3481 }
3482
3483 static void bgp_processq_del(struct work_queue *wq, void *data)
3484 {
3485 struct bgp_process_queue *pqnode = data;
3486
3487 bgp_unlock(pqnode->bgp);
3488
3489 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3490 }
3491
3492 void bgp_process_queue_init(struct bgp *bgp)
3493 {
3494 if (!bgp->process_queue) {
3495 char name[BUFSIZ];
3496
3497 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3498 bgp->process_queue = work_queue_new(bm->master, name);
3499 }
3500
3501 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3502 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3503 bgp->process_queue->spec.max_retries = 0;
3504 bgp->process_queue->spec.hold = 50;
3505 /* Use a higher yield value of 50ms for main queue processing */
3506 bgp->process_queue->spec.yield = 50 * 1000L;
3507 }
3508
3509 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3510 {
3511 struct bgp_process_queue *pqnode;
3512
3513 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3514 sizeof(struct bgp_process_queue));
3515
3516 /* unlocked in bgp_processq_del */
3517 pqnode->bgp = bgp_lock(bgp);
3518 STAILQ_INIT(&pqnode->pqueue);
3519
3520 return pqnode;
3521 }
3522
3523 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3524 {
3525 #define ARBITRARY_PROCESS_QLEN 10000
3526 struct work_queue *wq = bgp->process_queue;
3527 struct bgp_process_queue *pqnode;
3528 int pqnode_reuse = 0;
3529
3530 /* already scheduled for processing? */
3531 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3532 return;
3533
3534 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3535 * the workqueue
3536 */
3537 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3538 if (BGP_DEBUG(update, UPDATE_OUT))
3539 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3540 dest);
3541 return;
3542 }
3543
3544 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3545 if (BGP_DEBUG(update, UPDATE_OUT))
3546 zlog_debug(
3547 "Soft reconfigure table in progress for route %p",
3548 dest);
3549 return;
3550 }
3551
3552 if (wq == NULL)
3553 return;
3554
3555 /* Add route nodes to an existing work queue item until reaching the
3556 limit only if is from the same BGP view and it's not an EOIU marker
3557 */
3558 if (work_queue_item_count(wq)) {
3559 struct work_queue_item *item = work_queue_last_item(wq);
3560 pqnode = item->data;
3561
3562 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3563 || pqnode->bgp != bgp
3564 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3565 pqnode = bgp_processq_alloc(bgp);
3566 else
3567 pqnode_reuse = 1;
3568 } else
3569 pqnode = bgp_processq_alloc(bgp);
3570 /* all unlocked in bgp_process_wq */
3571 bgp_table_lock(bgp_dest_table(dest));
3572
3573 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3574 bgp_dest_lock_node(dest);
3575
3576 /* can't be enqueued twice */
3577 assert(STAILQ_NEXT(dest, pq) == NULL);
3578 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3579 pqnode->queued++;
3580
3581 if (!pqnode_reuse)
3582 work_queue_add(wq, pqnode);
3583
3584 return;
3585 }
3586
3587 void bgp_add_eoiu_mark(struct bgp *bgp)
3588 {
3589 struct bgp_process_queue *pqnode;
3590
3591 if (bgp->process_queue == NULL)
3592 return;
3593
3594 pqnode = bgp_processq_alloc(bgp);
3595
3596 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3597 work_queue_add(bgp->process_queue, pqnode);
3598 }
3599
3600 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3601 {
3602 struct peer *peer;
3603
3604 peer = THREAD_ARG(thread);
3605 peer->t_pmax_restart = NULL;
3606
3607 if (bgp_debug_neighbor_events(peer))
3608 zlog_debug(
3609 "%s Maximum-prefix restart timer expired, restore peering",
3610 peer->host);
3611
3612 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3613 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3614 }
3615
3616 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3617 safi_t safi)
3618 {
3619 uint32_t count = 0;
3620 bool filtered = false;
3621 struct bgp_dest *dest;
3622 struct bgp_adj_in *ain;
3623 struct attr attr = {};
3624 struct bgp_table *table = peer->bgp->rib[afi][safi];
3625
3626 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3627 for (ain = dest->adj_in; ain; ain = ain->next) {
3628 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3629
3630 attr = *ain->attr;
3631
3632 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3633 == FILTER_DENY)
3634 filtered = true;
3635
3636 if (bgp_input_modifier(
3637 peer, rn_p, &attr, afi, safi,
3638 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3639 NULL, 0, NULL)
3640 == RMAP_DENY)
3641 filtered = true;
3642
3643 if (filtered)
3644 count++;
3645
3646 bgp_attr_flush(&attr);
3647 }
3648 }
3649
3650 return count;
3651 }
3652
3653 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3654 int always)
3655 {
3656 iana_afi_t pkt_afi;
3657 iana_safi_t pkt_safi;
3658 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3659 PEER_FLAG_MAX_PREFIX_FORCE))
3660 ? bgp_filtered_routes_count(peer, afi, safi)
3661 + peer->pcount[afi][safi]
3662 : peer->pcount[afi][safi];
3663
3664 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3665 return false;
3666
3667 if (pcount > peer->pmax[afi][safi]) {
3668 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3669 PEER_STATUS_PREFIX_LIMIT)
3670 && !always)
3671 return false;
3672
3673 zlog_info(
3674 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3675 get_afi_safi_str(afi, safi, false), peer, pcount,
3676 peer->pmax[afi][safi]);
3677 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3678
3679 if (CHECK_FLAG(peer->af_flags[afi][safi],
3680 PEER_FLAG_MAX_PREFIX_WARNING))
3681 return false;
3682
3683 /* Convert AFI, SAFI to values for packet. */
3684 pkt_afi = afi_int2iana(afi);
3685 pkt_safi = safi_int2iana(safi);
3686 {
3687 uint8_t ndata[7];
3688
3689 ndata[0] = (pkt_afi >> 8);
3690 ndata[1] = pkt_afi;
3691 ndata[2] = pkt_safi;
3692 ndata[3] = (peer->pmax[afi][safi] >> 24);
3693 ndata[4] = (peer->pmax[afi][safi] >> 16);
3694 ndata[5] = (peer->pmax[afi][safi] >> 8);
3695 ndata[6] = (peer->pmax[afi][safi]);
3696
3697 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3698 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3699 BGP_NOTIFY_CEASE_MAX_PREFIX,
3700 ndata, 7);
3701 }
3702
3703 /* Dynamic peers will just close their connection. */
3704 if (peer_dynamic_neighbor(peer))
3705 return true;
3706
3707 /* restart timer start */
3708 if (peer->pmax_restart[afi][safi]) {
3709 peer->v_pmax_restart =
3710 peer->pmax_restart[afi][safi] * 60;
3711
3712 if (bgp_debug_neighbor_events(peer))
3713 zlog_debug(
3714 "%pBP Maximum-prefix restart timer started for %d secs",
3715 peer, peer->v_pmax_restart);
3716
3717 BGP_TIMER_ON(peer->t_pmax_restart,
3718 bgp_maximum_prefix_restart_timer,
3719 peer->v_pmax_restart);
3720 }
3721
3722 return true;
3723 } else
3724 UNSET_FLAG(peer->af_sflags[afi][safi],
3725 PEER_STATUS_PREFIX_LIMIT);
3726
3727 if (pcount
3728 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3729 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3730 PEER_STATUS_PREFIX_THRESHOLD)
3731 && !always)
3732 return false;
3733
3734 zlog_info(
3735 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3736 get_afi_safi_str(afi, safi, false), peer, pcount,
3737 peer->pmax[afi][safi]);
3738 SET_FLAG(peer->af_sflags[afi][safi],
3739 PEER_STATUS_PREFIX_THRESHOLD);
3740 } else
3741 UNSET_FLAG(peer->af_sflags[afi][safi],
3742 PEER_STATUS_PREFIX_THRESHOLD);
3743 return false;
3744 }
3745
3746 /* Unconditionally remove the route from the RIB, without taking
3747 * damping into consideration (eg, because the session went down)
3748 */
3749 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3750 struct peer *peer, afi_t afi, safi_t safi)
3751 {
3752
3753 struct bgp *bgp = NULL;
3754 bool delete_route = false;
3755
3756 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3757 safi);
3758
3759 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3760 bgp_path_info_delete(dest, pi); /* keep historical info */
3761
3762 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3763 * flag
3764 */
3765 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3766 delete_route = true;
3767 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3768 delete_route = true;
3769 if (delete_route) {
3770 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3771 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3772 bgp = pi->peer->bgp;
3773 bgp->gr_info[afi][safi].gr_deferred--;
3774 }
3775 }
3776 }
3777
3778 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3779 bgp_process(peer->bgp, dest, afi, safi);
3780 }
3781
3782 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3783 struct peer *peer, afi_t afi, safi_t safi,
3784 struct prefix_rd *prd)
3785 {
3786 const struct prefix *p = bgp_dest_get_prefix(dest);
3787
3788 /* apply dampening, if result is suppressed, we'll be retaining
3789 * the bgp_path_info in the RIB for historical reference.
3790 */
3791 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3792 && peer->sort == BGP_PEER_EBGP)
3793 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3794 == BGP_DAMP_SUPPRESSED) {
3795 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3796 safi);
3797 return;
3798 }
3799
3800 #ifdef ENABLE_BGP_VNC
3801 if (safi == SAFI_MPLS_VPN) {
3802 struct bgp_dest *pdest = NULL;
3803 struct bgp_table *table = NULL;
3804
3805 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3806 (struct prefix *)prd);
3807 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3808 table = bgp_dest_get_bgp_table_info(pdest);
3809
3810 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3811 peer->bgp, prd, table, p, pi);
3812 }
3813 bgp_dest_unlock_node(pdest);
3814 }
3815 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3816 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3817
3818 vnc_import_bgp_del_route(peer->bgp, p, pi);
3819 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3820 }
3821 }
3822 #endif
3823
3824 /* If this is an EVPN route, process for un-import. */
3825 if (safi == SAFI_EVPN)
3826 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3827
3828 bgp_rib_remove(dest, pi, peer, afi, safi);
3829 }
3830
3831 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3832 struct peer *peer, struct attr *attr,
3833 struct bgp_dest *dest)
3834 {
3835 struct bgp_path_info *new;
3836
3837 /* Make new BGP info. */
3838 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3839 new->type = type;
3840 new->instance = instance;
3841 new->sub_type = sub_type;
3842 new->peer = peer;
3843 new->attr = attr;
3844 new->uptime = monotime(NULL);
3845 new->net = dest;
3846 return new;
3847 }
3848
3849 /* Check if received nexthop is valid or not. */
3850 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3851 uint8_t type, uint8_t stype, struct attr *attr,
3852 struct bgp_dest *dest)
3853 {
3854 bool ret = false;
3855 bool is_bgp_static_route =
3856 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3857 : false;
3858
3859 /*
3860 * Only validated for unicast and multicast currently.
3861 * Also valid for EVPN where the nexthop is an IP address.
3862 * If we are a bgp static route being checked then there is
3863 * no need to check to see if the nexthop is martian as
3864 * that it should be ok.
3865 */
3866 if (is_bgp_static_route ||
3867 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3868 return false;
3869
3870 /* If NEXT_HOP is present, validate it. */
3871 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3872 if (attr->nexthop.s_addr == INADDR_ANY ||
3873 !ipv4_unicast_valid(&attr->nexthop) ||
3874 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3875 return true;
3876 }
3877
3878 /* If MP_NEXTHOP is present, validate it. */
3879 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3880 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3881 * it is not an IPv6 link-local address.
3882 *
3883 * If we receive an UPDATE with nexthop length set to 32 bytes
3884 * we shouldn't discard an UPDATE if it's set to (::).
3885 * The link-local (2st) is validated along the code path later.
3886 */
3887 if (attr->mp_nexthop_len) {
3888 switch (attr->mp_nexthop_len) {
3889 case BGP_ATTR_NHLEN_IPV4:
3890 case BGP_ATTR_NHLEN_VPNV4:
3891 ret = (attr->mp_nexthop_global_in.s_addr ==
3892 INADDR_ANY ||
3893 !ipv4_unicast_valid(
3894 &attr->mp_nexthop_global_in) ||
3895 bgp_nexthop_self(bgp, afi, type, stype, attr,
3896 dest));
3897 break;
3898
3899 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3900 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3901 ret = (IN6_IS_ADDR_UNSPECIFIED(
3902 &attr->mp_nexthop_global)
3903 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3904 || IN6_IS_ADDR_MULTICAST(
3905 &attr->mp_nexthop_global)
3906 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3907 dest));
3908 break;
3909 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3910 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3911 || IN6_IS_ADDR_MULTICAST(
3912 &attr->mp_nexthop_global)
3913 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3914 dest));
3915 break;
3916
3917 default:
3918 ret = true;
3919 break;
3920 }
3921 }
3922
3923 return ret;
3924 }
3925
3926 static void bgp_attr_add_no_export_community(struct attr *attr)
3927 {
3928 struct community *old;
3929 struct community *new;
3930 struct community *merge;
3931 struct community *no_export;
3932
3933 old = bgp_attr_get_community(attr);
3934 no_export = community_str2com("no-export");
3935
3936 assert(no_export);
3937
3938 if (old) {
3939 merge = community_merge(community_dup(old), no_export);
3940
3941 if (!old->refcnt)
3942 community_free(&old);
3943
3944 new = community_uniq_sort(merge);
3945 community_free(&merge);
3946 } else {
3947 new = community_dup(no_export);
3948 }
3949
3950 community_free(&no_export);
3951
3952 bgp_attr_set_community(attr, new);
3953 }
3954
3955 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3956 struct attr *attr, const struct prefix *prefix,
3957 int *sub_type)
3958 {
3959 struct listnode *node, *nnode;
3960 struct bgp *bgp;
3961 bool accept_own_found = false;
3962
3963 if (safi != SAFI_MPLS_VPN)
3964 return false;
3965
3966 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3967 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3968 return false;
3969
3970 /* The route in question carries the ACCEPT_OWN community */
3971 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3972 struct community *comm = bgp_attr_get_community(attr);
3973
3974 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3975 accept_own_found = true;
3976 }
3977
3978 /* The route in question is targeted to one or more destination VRFs
3979 * on the router (as determined by inspecting the Route Target(s)).
3980 */
3981 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3982 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3983 continue;
3984
3985 if (accept_own_found &&
3986 ecommunity_include(
3987 bgp->vpn_policy[afi]
3988 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3989 bgp_attr_get_ecommunity(attr))) {
3990 if (bgp_debug_update(peer, prefix, NULL, 1))
3991 zlog_debug(
3992 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3993 peer, prefix);
3994
3995 /* Treat this route as imported, because it's leaked
3996 * already from another VRF, and we got an updated
3997 * version from route-reflector with ACCEPT_OWN
3998 * community.
3999 */
4000 *sub_type = BGP_ROUTE_IMPORTED;
4001
4002 return true;
4003 }
4004 }
4005
4006 return false;
4007 }
4008
4009 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4010 struct attr *attr, afi_t afi, safi_t safi, int type,
4011 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4012 uint32_t num_labels, int soft_reconfig,
4013 struct bgp_route_evpn *evpn)
4014 {
4015 int ret;
4016 int aspath_loop_count = 0;
4017 struct bgp_dest *dest;
4018 struct bgp *bgp;
4019 struct attr new_attr;
4020 struct attr *attr_new;
4021 struct bgp_path_info *pi;
4022 struct bgp_path_info *new;
4023 struct bgp_path_info_extra *extra;
4024 const char *reason;
4025 char pfx_buf[BGP_PRD_PATH_STRLEN];
4026 int connected = 0;
4027 int do_loop_check = 1;
4028 int has_valid_label = 0;
4029 afi_t nh_afi;
4030 bool force_evpn_import = false;
4031 safi_t orig_safi = safi;
4032 bool leak_success = true;
4033 int allowas_in = 0;
4034
4035 if (frrtrace_enabled(frr_bgp, process_update)) {
4036 char pfxprint[PREFIX2STR_BUFFER];
4037
4038 prefix2str(p, pfxprint, sizeof(pfxprint));
4039 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4040 afi, safi, attr);
4041 }
4042
4043 #ifdef ENABLE_BGP_VNC
4044 int vnc_implicit_withdraw = 0;
4045 #endif
4046 int same_attr = 0;
4047
4048 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4049 if (orig_safi == SAFI_LABELED_UNICAST)
4050 safi = SAFI_UNICAST;
4051
4052 memset(&new_attr, 0, sizeof(new_attr));
4053 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4054 new_attr.label = MPLS_INVALID_LABEL;
4055
4056 bgp = peer->bgp;
4057 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4058 /* TODO: Check to see if we can get rid of "is_valid_label" */
4059 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4060 has_valid_label = (num_labels > 0) ? 1 : 0;
4061 else
4062 has_valid_label = bgp_is_valid_label(label);
4063
4064 if (has_valid_label)
4065 assert(label != NULL);
4066
4067 /* Update overlay index of the attribute */
4068 if (afi == AFI_L2VPN && evpn)
4069 memcpy(&attr->evpn_overlay, evpn,
4070 sizeof(struct bgp_route_evpn));
4071
4072 /* When peer's soft reconfiguration enabled. Record input packet in
4073 Adj-RIBs-In. */
4074 if (!soft_reconfig
4075 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4076 && peer != bgp->peer_self)
4077 bgp_adj_in_set(dest, peer, attr, addpath_id);
4078
4079 /* Update permitted loop count */
4080 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4081 allowas_in = peer->allowas_in[afi][safi];
4082
4083 /* Check previously received route. */
4084 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4085 if (pi->peer == peer && pi->type == type
4086 && pi->sub_type == sub_type
4087 && pi->addpath_rx_id == addpath_id)
4088 break;
4089
4090 /* AS path local-as loop check. */
4091 if (peer->change_local_as) {
4092 if (allowas_in)
4093 aspath_loop_count = allowas_in;
4094 else if (!CHECK_FLAG(peer->flags,
4095 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4096 aspath_loop_count = 1;
4097
4098 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4099 > aspath_loop_count) {
4100 peer->stat_pfx_aspath_loop++;
4101 reason = "as-path contains our own AS;";
4102 goto filtered;
4103 }
4104 }
4105
4106 /* If the peer is configured for "allowas-in origin" and the last ASN in
4107 * the
4108 * as-path is our ASN then we do not need to call aspath_loop_check
4109 */
4110 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4111 if (aspath_get_last_as(attr->aspath) == bgp->as)
4112 do_loop_check = 0;
4113
4114 /* AS path loop check. */
4115 if (do_loop_check) {
4116 if (aspath_loop_check(attr->aspath, bgp->as) >
4117 peer->allowas_in[afi][safi]) {
4118 peer->stat_pfx_aspath_loop++;
4119 reason = "as-path contains our own AS;";
4120 goto filtered;
4121 }
4122 }
4123
4124 /* If we're a CONFED we need to loop check the CONFED ID too */
4125 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4126 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4127 peer->allowas_in[afi][safi]) {
4128 peer->stat_pfx_aspath_loop++;
4129 reason = "as-path contains our own confed AS;";
4130 goto filtered;
4131 }
4132
4133 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4134 * enabled, then take care of that too.
4135 */
4136 bool accept_own = false;
4137
4138 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4139 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4140 accept_own =
4141 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4142 if (!accept_own) {
4143 peer->stat_pfx_originator_loop++;
4144 reason = "originator is us;";
4145 goto filtered;
4146 }
4147 }
4148
4149 /* Route reflector cluster ID check. */
4150 if (bgp_cluster_filter(peer, attr)) {
4151 peer->stat_pfx_cluster_loop++;
4152 reason = "reflected from the same cluster;";
4153 goto filtered;
4154 }
4155
4156 /* Apply incoming filter. */
4157 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4158 peer->stat_pfx_filter++;
4159 reason = "filter;";
4160 goto filtered;
4161 }
4162
4163 /* RFC 8212 to prevent route leaks.
4164 * This specification intends to improve this situation by requiring the
4165 * explicit configuration of both BGP Import and Export Policies for any
4166 * External BGP (EBGP) session such as customers, peers, or
4167 * confederation boundaries for all enabled address families. Through
4168 * codification of the aforementioned requirement, operators will
4169 * benefit from consistent behavior across different BGP
4170 * implementations.
4171 */
4172 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4173 if (!bgp_inbound_policy_exists(peer,
4174 &peer->filter[afi][safi])) {
4175 reason = "inbound policy missing";
4176 if (monotime_since(&bgp->ebgprequirespolicywarning,
4177 NULL) > FIFTEENMINUTE2USEC ||
4178 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4179 zlog_warn(
4180 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4181 monotime(&bgp->ebgprequirespolicywarning);
4182 }
4183 goto filtered;
4184 }
4185
4186 /* draft-ietf-idr-deprecate-as-set-confed-set
4187 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4188 * Eventually, This document (if approved) updates RFC 4271
4189 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4190 * and obsoletes RFC 6472.
4191 */
4192 if (peer->bgp->reject_as_sets)
4193 if (aspath_check_as_sets(attr->aspath)) {
4194 reason =
4195 "as-path contains AS_SET or AS_CONFED_SET type;";
4196 goto filtered;
4197 }
4198
4199 new_attr = *attr;
4200
4201 /* Apply incoming route-map.
4202 * NB: new_attr may now contain newly allocated values from route-map
4203 * "set"
4204 * commands, so we need bgp_attr_flush in the error paths, until we
4205 * intern
4206 * the attr (which takes over the memory references) */
4207 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4208 num_labels, dest)
4209 == RMAP_DENY) {
4210 peer->stat_pfx_filter++;
4211 reason = "route-map;";
4212 bgp_attr_flush(&new_attr);
4213 goto filtered;
4214 }
4215
4216 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4217 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4218 /* remove from RIB previous entry */
4219 bgp_zebra_withdraw(p, pi, bgp, safi);
4220 }
4221
4222 if (peer->sort == BGP_PEER_EBGP) {
4223
4224 /* rfc7999:
4225 * A BGP speaker receiving an announcement tagged with the
4226 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4227 * NO_EXPORT community as defined in RFC1997, or a
4228 * similar community, to prevent propagation of the
4229 * prefix outside the local AS. The community to prevent
4230 * propagation SHOULD be chosen according to the operator's
4231 * routing policy.
4232 */
4233 if (bgp_attr_get_community(&new_attr) &&
4234 community_include(bgp_attr_get_community(&new_attr),
4235 COMMUNITY_BLACKHOLE))
4236 bgp_attr_add_no_export_community(&new_attr);
4237
4238 /* If we receive the graceful-shutdown community from an eBGP
4239 * peer we must lower local-preference */
4240 if (bgp_attr_get_community(&new_attr) &&
4241 community_include(bgp_attr_get_community(&new_attr),
4242 COMMUNITY_GSHUT)) {
4243 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4244 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4245
4246 /* If graceful-shutdown is configured then add the GSHUT
4247 * community to all paths received from eBGP peers */
4248 } else if (bgp_in_graceful_shutdown(peer->bgp))
4249 bgp_attr_add_gshut_community(&new_attr);
4250 }
4251
4252 /* next hop check. */
4253 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4254 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4255 &new_attr, dest)) {
4256 peer->stat_pfx_nh_invalid++;
4257 reason = "martian or self next-hop;";
4258 bgp_attr_flush(&new_attr);
4259 goto filtered;
4260 }
4261
4262 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4263 peer->stat_pfx_nh_invalid++;
4264 reason = "self mac;";
4265 bgp_attr_flush(&new_attr);
4266 goto filtered;
4267 }
4268
4269 if (bgp_check_role_applicability(afi, safi) &&
4270 bgp_otc_filter(peer, &new_attr)) {
4271 reason = "failing otc validation";
4272 bgp_attr_flush(&new_attr);
4273 goto filtered;
4274 }
4275 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4276 * condition :
4277 * Suppress fib is enabled
4278 * BGP_OPT_NO_FIB is not enabled
4279 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4280 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4281 */
4282 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4283 && (sub_type == BGP_ROUTE_NORMAL)
4284 && (!bgp_option_check(BGP_OPT_NO_FIB))
4285 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4286 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4287
4288 /* If maximum prefix count is configured and current prefix
4289 * count exeed it.
4290 */
4291 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4292 bgp_attr_flush(&new_attr);
4293 return -1;
4294 }
4295
4296 /* If neighbor soo is configured, tag all incoming routes with
4297 * this SoO tag and then filter out advertisements in
4298 * subgroup_announce_check() if it matches the configured SoO
4299 * on the other peer.
4300 */
4301 if (peer->soo[afi][safi]) {
4302 struct ecommunity *old_ecomm =
4303 bgp_attr_get_ecommunity(&new_attr);
4304 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4305 struct ecommunity *new_ecomm;
4306
4307 if (old_ecomm) {
4308 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4309 ecomm_soo);
4310
4311 if (!old_ecomm->refcnt)
4312 ecommunity_free(&old_ecomm);
4313 } else {
4314 new_ecomm = ecommunity_dup(ecomm_soo);
4315 }
4316
4317 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4318 }
4319
4320 attr_new = bgp_attr_intern(&new_attr);
4321
4322 /* If the update is implicit withdraw. */
4323 if (pi) {
4324 pi->uptime = monotime(NULL);
4325 same_attr = attrhash_cmp(pi->attr, attr_new);
4326
4327 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4328
4329 /* Same attribute comes in. */
4330 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4331 && same_attr
4332 && (!has_valid_label
4333 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4334 num_labels * sizeof(mpls_label_t))
4335 == 0)) {
4336 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4337 BGP_CONFIG_DAMPENING)
4338 && peer->sort == BGP_PEER_EBGP
4339 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4340 if (bgp_debug_update(peer, p, NULL, 1)) {
4341 bgp_debug_rdpfxpath2str(
4342 afi, safi, prd, p, label,
4343 num_labels, addpath_id ? 1 : 0,
4344 addpath_id, evpn, pfx_buf,
4345 sizeof(pfx_buf));
4346 zlog_debug("%pBP rcvd %s", peer,
4347 pfx_buf);
4348 }
4349
4350 if (bgp_damp_update(pi, dest, afi, safi)
4351 != BGP_DAMP_SUPPRESSED) {
4352 bgp_aggregate_increment(bgp, p, pi, afi,
4353 safi);
4354 bgp_process(bgp, dest, afi, safi);
4355 }
4356 } else /* Duplicate - odd */
4357 {
4358 if (bgp_debug_update(peer, p, NULL, 1)) {
4359 if (!peer->rcvd_attr_printed) {
4360 zlog_debug(
4361 "%pBP rcvd UPDATE w/ attr: %s",
4362 peer,
4363 peer->rcvd_attr_str);
4364 peer->rcvd_attr_printed = 1;
4365 }
4366
4367 bgp_debug_rdpfxpath2str(
4368 afi, safi, prd, p, label,
4369 num_labels, addpath_id ? 1 : 0,
4370 addpath_id, evpn, pfx_buf,
4371 sizeof(pfx_buf));
4372 zlog_debug(
4373 "%pBP rcvd %s...duplicate ignored",
4374 peer, pfx_buf);
4375 }
4376
4377 /* graceful restart STALE flag unset. */
4378 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4379 bgp_path_info_unset_flag(
4380 dest, pi, BGP_PATH_STALE);
4381 bgp_dest_set_defer_flag(dest, false);
4382 bgp_process(bgp, dest, afi, safi);
4383 }
4384 }
4385
4386 bgp_dest_unlock_node(dest);
4387 bgp_attr_unintern(&attr_new);
4388
4389 return 0;
4390 }
4391
4392 /* Withdraw/Announce before we fully processed the withdraw */
4393 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4394 if (bgp_debug_update(peer, p, NULL, 1)) {
4395 bgp_debug_rdpfxpath2str(
4396 afi, safi, prd, p, label, num_labels,
4397 addpath_id ? 1 : 0, addpath_id, evpn,
4398 pfx_buf, sizeof(pfx_buf));
4399 zlog_debug(
4400 "%pBP rcvd %s, flapped quicker than processing",
4401 peer, pfx_buf);
4402 }
4403
4404 bgp_path_info_restore(dest, pi);
4405
4406 /*
4407 * If the BGP_PATH_REMOVED flag is set, then EVPN
4408 * routes would have been unimported already when a
4409 * prior BGP withdraw processing happened. Such routes
4410 * need to be imported again, so flag accordingly.
4411 */
4412 force_evpn_import = true;
4413 }
4414
4415 /* Received Logging. */
4416 if (bgp_debug_update(peer, p, NULL, 1)) {
4417 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4418 num_labels, addpath_id ? 1 : 0,
4419 addpath_id, evpn, pfx_buf,
4420 sizeof(pfx_buf));
4421 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4422 }
4423
4424 /* graceful restart STALE flag unset. */
4425 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4426 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4427 bgp_dest_set_defer_flag(dest, false);
4428 }
4429
4430 /* The attribute is changed. */
4431 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4432
4433 /* implicit withdraw, decrement aggregate and pcount here.
4434 * only if update is accepted, they'll increment below.
4435 */
4436 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4437
4438 /* Update bgp route dampening information. */
4439 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4440 && peer->sort == BGP_PEER_EBGP) {
4441 /* This is implicit withdraw so we should update
4442 dampening
4443 information. */
4444 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4445 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4446 }
4447 #ifdef ENABLE_BGP_VNC
4448 if (safi == SAFI_MPLS_VPN) {
4449 struct bgp_dest *pdest = NULL;
4450 struct bgp_table *table = NULL;
4451
4452 pdest = bgp_node_get(bgp->rib[afi][safi],
4453 (struct prefix *)prd);
4454 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4455 table = bgp_dest_get_bgp_table_info(pdest);
4456
4457 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4458 bgp, prd, table, p, pi);
4459 }
4460 bgp_dest_unlock_node(pdest);
4461 }
4462 if ((afi == AFI_IP || afi == AFI_IP6)
4463 && (safi == SAFI_UNICAST)) {
4464 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4465 /*
4466 * Implicit withdraw case.
4467 */
4468 ++vnc_implicit_withdraw;
4469 vnc_import_bgp_del_route(bgp, p, pi);
4470 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4471 }
4472 }
4473 #endif
4474
4475 /* Special handling for EVPN update of an existing route. If the
4476 * extended community attribute has changed, we need to
4477 * un-import
4478 * the route using its existing extended community. It will be
4479 * subsequently processed for import with the new extended
4480 * community.
4481 */
4482 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4483 && !same_attr) {
4484 if ((pi->attr->flag
4485 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4486 && (attr_new->flag
4487 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4488 int cmp;
4489
4490 cmp = ecommunity_cmp(
4491 bgp_attr_get_ecommunity(pi->attr),
4492 bgp_attr_get_ecommunity(attr_new));
4493 if (!cmp) {
4494 if (bgp_debug_update(peer, p, NULL, 1))
4495 zlog_debug(
4496 "Change in EXT-COMM, existing %s new %s",
4497 ecommunity_str(
4498 bgp_attr_get_ecommunity(
4499 pi->attr)),
4500 ecommunity_str(
4501 bgp_attr_get_ecommunity(
4502 attr_new)));
4503 if (safi == SAFI_EVPN)
4504 bgp_evpn_unimport_route(
4505 bgp, afi, safi, p, pi);
4506 else /* SAFI_MPLS_VPN */
4507 vpn_leak_to_vrf_withdraw(bgp,
4508 pi);
4509 }
4510 }
4511 }
4512
4513 /* Update to new attribute. */
4514 bgp_attr_unintern(&pi->attr);
4515 pi->attr = attr_new;
4516
4517 /* Update MPLS label */
4518 if (has_valid_label) {
4519 extra = bgp_path_info_extra_get(pi);
4520 if (extra->label != label) {
4521 memcpy(&extra->label, label,
4522 num_labels * sizeof(mpls_label_t));
4523 extra->num_labels = num_labels;
4524 }
4525 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4526 bgp_set_valid_label(&extra->label[0]);
4527 }
4528
4529 /* Update SRv6 SID */
4530 if (attr->srv6_l3vpn) {
4531 extra = bgp_path_info_extra_get(pi);
4532 if (sid_diff(&extra->sid[0].sid,
4533 &attr->srv6_l3vpn->sid)) {
4534 sid_copy(&extra->sid[0].sid,
4535 &attr->srv6_l3vpn->sid);
4536 extra->num_sids = 1;
4537
4538 extra->sid[0].loc_block_len = 0;
4539 extra->sid[0].loc_node_len = 0;
4540 extra->sid[0].func_len = 0;
4541 extra->sid[0].arg_len = 0;
4542 extra->sid[0].transposition_len = 0;
4543 extra->sid[0].transposition_offset = 0;
4544
4545 if (attr->srv6_l3vpn->loc_block_len != 0) {
4546 extra->sid[0].loc_block_len =
4547 attr->srv6_l3vpn->loc_block_len;
4548 extra->sid[0].loc_node_len =
4549 attr->srv6_l3vpn->loc_node_len;
4550 extra->sid[0].func_len =
4551 attr->srv6_l3vpn->func_len;
4552 extra->sid[0].arg_len =
4553 attr->srv6_l3vpn->arg_len;
4554 extra->sid[0].transposition_len =
4555 attr->srv6_l3vpn
4556 ->transposition_len;
4557 extra->sid[0].transposition_offset =
4558 attr->srv6_l3vpn
4559 ->transposition_offset;
4560 }
4561 }
4562 } else if (attr->srv6_vpn) {
4563 extra = bgp_path_info_extra_get(pi);
4564 if (sid_diff(&extra->sid[0].sid,
4565 &attr->srv6_vpn->sid)) {
4566 sid_copy(&extra->sid[0].sid,
4567 &attr->srv6_vpn->sid);
4568 extra->num_sids = 1;
4569 }
4570 }
4571
4572 #ifdef ENABLE_BGP_VNC
4573 if ((afi == AFI_IP || afi == AFI_IP6)
4574 && (safi == SAFI_UNICAST)) {
4575 if (vnc_implicit_withdraw) {
4576 /*
4577 * Add back the route with its new attributes
4578 * (e.g., nexthop).
4579 * The route is still selected, until the route
4580 * selection
4581 * queued by bgp_process actually runs. We have
4582 * to make this
4583 * update to the VNC side immediately to avoid
4584 * racing against
4585 * configuration changes (e.g., route-map
4586 * changes) which
4587 * trigger re-importation of the entire RIB.
4588 */
4589 vnc_import_bgp_add_route(bgp, p, pi);
4590 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4591 }
4592 }
4593 #endif
4594
4595 /* Update bgp route dampening information. */
4596 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4597 && peer->sort == BGP_PEER_EBGP) {
4598 /* Now we do normal update dampening. */
4599 ret = bgp_damp_update(pi, dest, afi, safi);
4600 if (ret == BGP_DAMP_SUPPRESSED) {
4601 bgp_dest_unlock_node(dest);
4602 return 0;
4603 }
4604 }
4605
4606 /* Nexthop reachability check - for unicast and
4607 * labeled-unicast.. */
4608 if (((afi == AFI_IP || afi == AFI_IP6)
4609 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4610 || (safi == SAFI_EVPN &&
4611 bgp_evpn_is_prefix_nht_supported(p))) {
4612 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4613 && peer->ttl == BGP_DEFAULT_TTL
4614 && !CHECK_FLAG(peer->flags,
4615 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4616 && !CHECK_FLAG(bgp->flags,
4617 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4618 connected = 1;
4619 else
4620 connected = 0;
4621
4622 struct bgp *bgp_nexthop = bgp;
4623
4624 if (pi->extra && pi->extra->bgp_orig)
4625 bgp_nexthop = pi->extra->bgp_orig;
4626
4627 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4628
4629 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4630 safi, pi, NULL, connected,
4631 p)
4632 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4633 bgp_path_info_set_flag(dest, pi,
4634 BGP_PATH_VALID);
4635 else {
4636 if (BGP_DEBUG(nht, NHT)) {
4637 zlog_debug("%s(%pI4): NH unresolved",
4638 __func__,
4639 (in_addr_t *)&attr_new->nexthop);
4640 }
4641 bgp_path_info_unset_flag(dest, pi,
4642 BGP_PATH_VALID);
4643 }
4644 } else {
4645 if (accept_own)
4646 bgp_path_info_set_flag(dest, pi,
4647 BGP_PATH_ACCEPT_OWN);
4648
4649 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4650 }
4651
4652 #ifdef ENABLE_BGP_VNC
4653 if (safi == SAFI_MPLS_VPN) {
4654 struct bgp_dest *pdest = NULL;
4655 struct bgp_table *table = NULL;
4656
4657 pdest = bgp_node_get(bgp->rib[afi][safi],
4658 (struct prefix *)prd);
4659 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4660 table = bgp_dest_get_bgp_table_info(pdest);
4661
4662 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4663 bgp, prd, table, p, pi);
4664 }
4665 bgp_dest_unlock_node(pdest);
4666 }
4667 #endif
4668
4669 /* If this is an EVPN route and some attribute has changed,
4670 * or we are explicitly told to perform a route import, process
4671 * route for import. If the extended community has changed, we
4672 * would
4673 * have done the un-import earlier and the import would result
4674 * in the
4675 * route getting injected into appropriate L2 VNIs. If it is
4676 * just
4677 * some other attribute change, the import will result in
4678 * updating
4679 * the attributes for the route in the VNI(s).
4680 */
4681 if (safi == SAFI_EVPN &&
4682 (!same_attr || force_evpn_import) &&
4683 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4684 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4685
4686 /* Process change. */
4687 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4688
4689 bgp_process(bgp, dest, afi, safi);
4690 bgp_dest_unlock_node(dest);
4691
4692 if (SAFI_UNICAST == safi
4693 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4694 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4695
4696 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4697 }
4698 if ((SAFI_MPLS_VPN == safi)
4699 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4700 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4701 }
4702
4703 #ifdef ENABLE_BGP_VNC
4704 if (SAFI_MPLS_VPN == safi) {
4705 mpls_label_t label_decoded = decode_label(label);
4706
4707 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4708 type, sub_type, &label_decoded);
4709 }
4710 if (SAFI_ENCAP == safi) {
4711 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4712 type, sub_type, NULL);
4713 }
4714 #endif
4715 if ((safi == SAFI_MPLS_VPN) &&
4716 !CHECK_FLAG(bgp->af_flags[afi][safi],
4717 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4718 !leak_success) {
4719 bgp_unlink_nexthop(pi);
4720 bgp_path_info_delete(dest, pi);
4721 }
4722 return 0;
4723 } // End of implicit withdraw
4724
4725 /* Received Logging. */
4726 if (bgp_debug_update(peer, p, NULL, 1)) {
4727 if (!peer->rcvd_attr_printed) {
4728 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4729 peer->rcvd_attr_str);
4730 peer->rcvd_attr_printed = 1;
4731 }
4732
4733 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4734 addpath_id ? 1 : 0, addpath_id, evpn,
4735 pfx_buf, sizeof(pfx_buf));
4736 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4737 }
4738
4739 /* Make new BGP info. */
4740 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4741
4742 /* Update MPLS label */
4743 if (has_valid_label) {
4744 extra = bgp_path_info_extra_get(new);
4745 if (extra->label != label) {
4746 memcpy(&extra->label, label,
4747 num_labels * sizeof(mpls_label_t));
4748 extra->num_labels = num_labels;
4749 }
4750 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4751 bgp_set_valid_label(&extra->label[0]);
4752 }
4753
4754 /* Update SRv6 SID */
4755 if (safi == SAFI_MPLS_VPN) {
4756 extra = bgp_path_info_extra_get(new);
4757 if (attr->srv6_l3vpn) {
4758 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4759 extra->num_sids = 1;
4760
4761 extra->sid[0].loc_block_len =
4762 attr->srv6_l3vpn->loc_block_len;
4763 extra->sid[0].loc_node_len =
4764 attr->srv6_l3vpn->loc_node_len;
4765 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4766 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4767 extra->sid[0].transposition_len =
4768 attr->srv6_l3vpn->transposition_len;
4769 extra->sid[0].transposition_offset =
4770 attr->srv6_l3vpn->transposition_offset;
4771 } else if (attr->srv6_vpn) {
4772 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4773 extra->num_sids = 1;
4774 }
4775 }
4776
4777 /* Nexthop reachability check. */
4778 if (((afi == AFI_IP || afi == AFI_IP6)
4779 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4780 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4781 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4782 && peer->ttl == BGP_DEFAULT_TTL
4783 && !CHECK_FLAG(peer->flags,
4784 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4785 && !CHECK_FLAG(bgp->flags,
4786 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4787 connected = 1;
4788 else
4789 connected = 0;
4790
4791 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4792
4793 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4794 connected, p)
4795 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4796 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4797 else {
4798 if (BGP_DEBUG(nht, NHT)) {
4799 char buf1[INET6_ADDRSTRLEN];
4800 inet_ntop(AF_INET,
4801 (const void *)&attr_new->nexthop,
4802 buf1, INET6_ADDRSTRLEN);
4803 zlog_debug("%s(%s): NH unresolved", __func__,
4804 buf1);
4805 }
4806 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4807 }
4808 } else {
4809 if (accept_own)
4810 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4811
4812 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4813 }
4814
4815 /* Addpath ID */
4816 new->addpath_rx_id = addpath_id;
4817
4818 /* Increment prefix */
4819 bgp_aggregate_increment(bgp, p, new, afi, safi);
4820
4821 /* Register new BGP information. */
4822 bgp_path_info_add(dest, new);
4823
4824 /* route_node_get lock */
4825 bgp_dest_unlock_node(dest);
4826
4827 #ifdef ENABLE_BGP_VNC
4828 if (safi == SAFI_MPLS_VPN) {
4829 struct bgp_dest *pdest = NULL;
4830 struct bgp_table *table = NULL;
4831
4832 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4833 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4834 table = bgp_dest_get_bgp_table_info(pdest);
4835
4836 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4837 bgp, prd, table, p, new);
4838 }
4839 bgp_dest_unlock_node(pdest);
4840 }
4841 #endif
4842
4843 /* If this is an EVPN route, process for import. */
4844 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4845 bgp_evpn_import_route(bgp, afi, safi, p, new);
4846
4847 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4848
4849 /* Process change. */
4850 bgp_process(bgp, dest, afi, safi);
4851
4852 if (SAFI_UNICAST == safi
4853 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4854 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4855 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4856 }
4857 if ((SAFI_MPLS_VPN == safi)
4858 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4859 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4860 }
4861 #ifdef ENABLE_BGP_VNC
4862 if (SAFI_MPLS_VPN == safi) {
4863 mpls_label_t label_decoded = decode_label(label);
4864
4865 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4866 sub_type, &label_decoded);
4867 }
4868 if (SAFI_ENCAP == safi) {
4869 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4870 sub_type, NULL);
4871 }
4872 #endif
4873 if ((safi == SAFI_MPLS_VPN) &&
4874 !CHECK_FLAG(bgp->af_flags[afi][safi],
4875 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4876 !leak_success) {
4877 bgp_unlink_nexthop(new);
4878 bgp_path_info_delete(dest, new);
4879 }
4880
4881 return 0;
4882
4883 /* This BGP update is filtered. Log the reason then update BGP
4884 entry. */
4885 filtered:
4886 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4887
4888 if (bgp_debug_update(peer, p, NULL, 1)) {
4889 if (!peer->rcvd_attr_printed) {
4890 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4891 peer->rcvd_attr_str);
4892 peer->rcvd_attr_printed = 1;
4893 }
4894
4895 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4896 addpath_id ? 1 : 0, addpath_id, evpn,
4897 pfx_buf, sizeof(pfx_buf));
4898 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4899 peer, pfx_buf, reason);
4900 }
4901
4902 if (pi) {
4903 /* If this is an EVPN route, un-import it as it is now filtered.
4904 */
4905 if (safi == SAFI_EVPN)
4906 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4907
4908 if (SAFI_UNICAST == safi
4909 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4910 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4911
4912 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4913 }
4914 if ((SAFI_MPLS_VPN == safi)
4915 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4916
4917 vpn_leak_to_vrf_withdraw(bgp, pi);
4918 }
4919
4920 bgp_rib_remove(dest, pi, peer, afi, safi);
4921 }
4922
4923 bgp_dest_unlock_node(dest);
4924
4925 #ifdef ENABLE_BGP_VNC
4926 /*
4927 * Filtered update is treated as an implicit withdrawal (see
4928 * bgp_rib_remove()
4929 * a few lines above)
4930 */
4931 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4932 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4933 0);
4934 }
4935 #endif
4936
4937 return 0;
4938 }
4939
4940 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4941 struct attr *attr, afi_t afi, safi_t safi, int type,
4942 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4943 uint32_t num_labels, struct bgp_route_evpn *evpn)
4944 {
4945 struct bgp *bgp;
4946 char pfx_buf[BGP_PRD_PATH_STRLEN];
4947 struct bgp_dest *dest;
4948 struct bgp_path_info *pi;
4949
4950 #ifdef ENABLE_BGP_VNC
4951 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4952 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4953 0);
4954 }
4955 #endif
4956
4957 bgp = peer->bgp;
4958
4959 /* Lookup node. */
4960 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4961
4962 /* If peer is soft reconfiguration enabled. Record input packet for
4963 * further calculation.
4964 *
4965 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4966 * routes that are filtered. This tanks out Quagga RS pretty badly due
4967 * to
4968 * the iteration over all RS clients.
4969 * Since we need to remove the entry from adj_in anyway, do that first
4970 * and
4971 * if there was no entry, we don't need to do anything more.
4972 */
4973 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4974 && peer != bgp->peer_self)
4975 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4976 peer->stat_pfx_dup_withdraw++;
4977
4978 if (bgp_debug_update(peer, p, NULL, 1)) {
4979 bgp_debug_rdpfxpath2str(
4980 afi, safi, prd, p, label, num_labels,
4981 addpath_id ? 1 : 0, addpath_id, NULL,
4982 pfx_buf, sizeof(pfx_buf));
4983 zlog_debug(
4984 "%s withdrawing route %s not in adj-in",
4985 peer->host, pfx_buf);
4986 }
4987 bgp_dest_unlock_node(dest);
4988 return 0;
4989 }
4990
4991 /* Lookup withdrawn route. */
4992 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4993 if (pi->peer == peer && pi->type == type
4994 && pi->sub_type == sub_type
4995 && pi->addpath_rx_id == addpath_id)
4996 break;
4997
4998 /* Logging. */
4999 if (bgp_debug_update(peer, p, NULL, 1)) {
5000 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5001 addpath_id ? 1 : 0, addpath_id, NULL,
5002 pfx_buf, sizeof(pfx_buf));
5003 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
5004 pfx_buf);
5005 }
5006
5007 /* Withdraw specified route from routing table. */
5008 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
5009 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
5010 if (SAFI_UNICAST == safi
5011 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5012 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5013 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5014 }
5015 if ((SAFI_MPLS_VPN == safi)
5016 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5017
5018 vpn_leak_to_vrf_withdraw(bgp, pi);
5019 }
5020 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5021 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5022 addpath_id ? 1 : 0, addpath_id, NULL,
5023 pfx_buf, sizeof(pfx_buf));
5024 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5025 }
5026
5027 /* Unlock bgp_node_get() lock. */
5028 bgp_dest_unlock_node(dest);
5029
5030 return 0;
5031 }
5032
5033 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5034 int withdraw)
5035 {
5036 struct update_subgroup *subgrp;
5037 subgrp = peer_subgroup(peer, afi, safi);
5038 subgroup_default_originate(subgrp, withdraw);
5039 }
5040
5041
5042 /*
5043 * bgp_stop_announce_route_timer
5044 */
5045 void bgp_stop_announce_route_timer(struct peer_af *paf)
5046 {
5047 if (!paf->t_announce_route)
5048 return;
5049
5050 THREAD_OFF(paf->t_announce_route);
5051 }
5052
5053 /*
5054 * bgp_announce_route_timer_expired
5055 *
5056 * Callback that is invoked when the route announcement timer for a
5057 * peer_af expires.
5058 */
5059 static void bgp_announce_route_timer_expired(struct thread *t)
5060 {
5061 struct peer_af *paf;
5062 struct peer *peer;
5063
5064 paf = THREAD_ARG(t);
5065 peer = paf->peer;
5066
5067 if (!peer_established(peer))
5068 return;
5069
5070 if (!peer->afc_nego[paf->afi][paf->safi])
5071 return;
5072
5073 peer_af_announce_route(paf, 1);
5074
5075 /* Notify BGP conditional advertisement scanner percess */
5076 peer->advmap_config_change[paf->afi][paf->safi] = true;
5077 }
5078
5079 /*
5080 * bgp_announce_route
5081 *
5082 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5083 *
5084 * if force is true we will force an update even if the update
5085 * limiting code is attempted to kick in.
5086 */
5087 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5088 {
5089 struct peer_af *paf;
5090 struct update_subgroup *subgrp;
5091
5092 paf = peer_af_find(peer, afi, safi);
5093 if (!paf)
5094 return;
5095 subgrp = PAF_SUBGRP(paf);
5096
5097 /*
5098 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5099 * or a refresh has already been triggered.
5100 */
5101 if (!subgrp || paf->t_announce_route)
5102 return;
5103
5104 if (force)
5105 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5106
5107 /*
5108 * Start a timer to stagger/delay the announce. This serves
5109 * two purposes - announcement can potentially be combined for
5110 * multiple peers and the announcement doesn't happen in the
5111 * vty context.
5112 */
5113 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5114 (subgrp->peer_count == 1)
5115 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5116 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5117 &paf->t_announce_route);
5118 }
5119
5120 /*
5121 * Announce routes from all AF tables to a peer.
5122 *
5123 * This should ONLY be called when there is a need to refresh the
5124 * routes to the peer based on a policy change for this peer alone
5125 * or a route refresh request received from the peer.
5126 * The operation will result in splitting the peer from its existing
5127 * subgroups and putting it in new subgroups.
5128 */
5129 void bgp_announce_route_all(struct peer *peer)
5130 {
5131 afi_t afi;
5132 safi_t safi;
5133
5134 FOREACH_AFI_SAFI (afi, safi)
5135 bgp_announce_route(peer, afi, safi, false);
5136 }
5137
5138 /* Flag or unflag bgp_dest to determine whether it should be treated by
5139 * bgp_soft_reconfig_table_task.
5140 * Flag if flag is true. Unflag if flag is false.
5141 */
5142 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5143 {
5144 struct bgp_dest *dest;
5145 struct bgp_adj_in *ain;
5146
5147 if (!table)
5148 return;
5149
5150 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5151 for (ain = dest->adj_in; ain; ain = ain->next) {
5152 if (ain->peer != NULL)
5153 break;
5154 }
5155 if (flag && ain != NULL && ain->peer != NULL)
5156 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5157 else
5158 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5159 }
5160 }
5161
5162 static int bgp_soft_reconfig_table_update(struct peer *peer,
5163 struct bgp_dest *dest,
5164 struct bgp_adj_in *ain, afi_t afi,
5165 safi_t safi, struct prefix_rd *prd)
5166 {
5167 struct bgp_path_info *pi;
5168 uint32_t num_labels = 0;
5169 mpls_label_t *label_pnt = NULL;
5170 struct bgp_route_evpn evpn;
5171
5172 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5173 if (pi->peer == peer)
5174 break;
5175
5176 if (pi && pi->extra)
5177 num_labels = pi->extra->num_labels;
5178 if (num_labels)
5179 label_pnt = &pi->extra->label[0];
5180 if (pi)
5181 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5182 sizeof(evpn));
5183 else
5184 memset(&evpn, 0, sizeof(evpn));
5185
5186 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5187 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
5188 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
5189 &evpn);
5190 }
5191
5192 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5193 struct bgp_table *table,
5194 struct prefix_rd *prd)
5195 {
5196 int ret;
5197 struct bgp_dest *dest;
5198 struct bgp_adj_in *ain;
5199
5200 if (!table)
5201 table = peer->bgp->rib[afi][safi];
5202
5203 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5204 for (ain = dest->adj_in; ain; ain = ain->next) {
5205 if (ain->peer != peer)
5206 continue;
5207
5208 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
5209 afi, safi, prd);
5210
5211 if (ret < 0) {
5212 bgp_dest_unlock_node(dest);
5213 return;
5214 }
5215 }
5216 }
5217
5218 /* Do soft reconfig table per bgp table.
5219 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5220 * when BGP_NODE_SOFT_RECONFIG is set,
5221 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5222 * Schedule a new thread to continue the job.
5223 * Without splitting the full job into several part,
5224 * vtysh waits for the job to finish before responding to a BGP command
5225 */
5226 static void bgp_soft_reconfig_table_task(struct thread *thread)
5227 {
5228 uint32_t iter, max_iter;
5229 int ret;
5230 struct bgp_dest *dest;
5231 struct bgp_adj_in *ain;
5232 struct peer *peer;
5233 struct bgp_table *table;
5234 struct prefix_rd *prd;
5235 struct listnode *node, *nnode;
5236
5237 table = THREAD_ARG(thread);
5238 prd = NULL;
5239
5240 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5241 if (table->soft_reconfig_init) {
5242 /* first call of the function with a new srta structure.
5243 * Don't do any treatment this time on nodes
5244 * in order vtysh to respond quickly
5245 */
5246 max_iter = 0;
5247 }
5248
5249 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5250 dest = bgp_route_next(dest)) {
5251 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5252 continue;
5253
5254 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5255
5256 for (ain = dest->adj_in; ain; ain = ain->next) {
5257 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5258 nnode, peer)) {
5259 if (ain->peer != peer)
5260 continue;
5261
5262 ret = bgp_soft_reconfig_table_update(
5263 peer, dest, ain, table->afi,
5264 table->safi, prd);
5265 iter++;
5266
5267 if (ret < 0) {
5268 bgp_dest_unlock_node(dest);
5269 listnode_delete(
5270 table->soft_reconfig_peers,
5271 peer);
5272 bgp_announce_route(peer, table->afi,
5273 table->safi, false);
5274 if (list_isempty(
5275 table->soft_reconfig_peers)) {
5276 list_delete(
5277 &table->soft_reconfig_peers);
5278 bgp_soft_reconfig_table_flag(
5279 table, false);
5280 return;
5281 }
5282 }
5283 }
5284 }
5285 }
5286
5287 /* we're either starting the initial iteration,
5288 * or we're going to continue an ongoing iteration
5289 */
5290 if (dest || table->soft_reconfig_init) {
5291 table->soft_reconfig_init = false;
5292 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5293 table, 0, &table->soft_reconfig_thread);
5294 return;
5295 }
5296 /* we're done, clean up the background iteration context info and
5297 schedule route annoucement
5298 */
5299 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5300 listnode_delete(table->soft_reconfig_peers, peer);
5301 bgp_announce_route(peer, table->afi, table->safi, false);
5302 }
5303
5304 list_delete(&table->soft_reconfig_peers);
5305 }
5306
5307
5308 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5309 * and peer.
5310 * - bgp cannot be NULL
5311 * - if table and peer are NULL, cancel all threads within the bgp instance
5312 * - if table is NULL and peer is not,
5313 * remove peer in all threads within the bgp instance
5314 * - if peer is NULL, cancel all threads matching table within the bgp instance
5315 */
5316 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5317 const struct bgp_table *table,
5318 const struct peer *peer)
5319 {
5320 struct peer *npeer;
5321 struct listnode *node, *nnode;
5322 int afi, safi;
5323 struct bgp_table *ntable;
5324
5325 if (!bgp)
5326 return;
5327
5328 FOREACH_AFI_SAFI (afi, safi) {
5329 ntable = bgp->rib[afi][safi];
5330 if (!ntable)
5331 continue;
5332 if (table && table != ntable)
5333 continue;
5334
5335 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5336 npeer)) {
5337 if (peer && peer != npeer)
5338 continue;
5339 listnode_delete(ntable->soft_reconfig_peers, npeer);
5340 }
5341
5342 if (!ntable->soft_reconfig_peers
5343 || !list_isempty(ntable->soft_reconfig_peers))
5344 continue;
5345
5346 list_delete(&ntable->soft_reconfig_peers);
5347 bgp_soft_reconfig_table_flag(ntable, false);
5348 THREAD_OFF(ntable->soft_reconfig_thread);
5349 }
5350 }
5351
5352 /*
5353 * Returns false if the peer is not configured for soft reconfig in
5354 */
5355 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5356 {
5357 struct bgp_dest *dest;
5358 struct bgp_table *table;
5359 struct listnode *node, *nnode;
5360 struct peer *npeer;
5361 struct peer_af *paf;
5362
5363 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5364 return false;
5365
5366 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5367 && (safi != SAFI_EVPN)) {
5368 table = peer->bgp->rib[afi][safi];
5369 if (!table)
5370 return true;
5371
5372 table->soft_reconfig_init = true;
5373
5374 if (!table->soft_reconfig_peers)
5375 table->soft_reconfig_peers = list_new();
5376 npeer = NULL;
5377 /* add peer to the table soft_reconfig_peers if not already
5378 * there
5379 */
5380 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5381 npeer)) {
5382 if (peer == npeer)
5383 break;
5384 }
5385 if (peer != npeer)
5386 listnode_add(table->soft_reconfig_peers, peer);
5387
5388 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5389 * on table would start back at the beginning.
5390 */
5391 bgp_soft_reconfig_table_flag(table, true);
5392
5393 if (!table->soft_reconfig_thread)
5394 thread_add_event(bm->master,
5395 bgp_soft_reconfig_table_task, table, 0,
5396 &table->soft_reconfig_thread);
5397 /* Cancel bgp_announce_route_timer_expired threads.
5398 * bgp_announce_route_timer_expired threads have been scheduled
5399 * to announce routes as soon as the soft_reconfigure process
5400 * finishes.
5401 * In this case, soft_reconfigure is also scheduled by using
5402 * a thread but is planned after the
5403 * bgp_announce_route_timer_expired threads. It means that,
5404 * without cancelling the threads, the route announcement task
5405 * would run before the soft reconfiguration one. That would
5406 * useless and would block vtysh during several seconds. Route
5407 * announcements are rescheduled as soon as the soft_reconfigure
5408 * process finishes.
5409 */
5410 paf = peer_af_find(peer, afi, safi);
5411 if (paf)
5412 bgp_stop_announce_route_timer(paf);
5413 } else
5414 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5415 dest = bgp_route_next(dest)) {
5416 table = bgp_dest_get_bgp_table_info(dest);
5417
5418 if (table == NULL)
5419 continue;
5420
5421 const struct prefix *p = bgp_dest_get_prefix(dest);
5422 struct prefix_rd prd;
5423
5424 prd.family = AF_UNSPEC;
5425 prd.prefixlen = 64;
5426 memcpy(&prd.val, p->u.val, 8);
5427
5428 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5429 }
5430
5431 return true;
5432 }
5433
5434
5435 struct bgp_clear_node_queue {
5436 struct bgp_dest *dest;
5437 };
5438
5439 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5440 {
5441 struct bgp_clear_node_queue *cnq = data;
5442 struct bgp_dest *dest = cnq->dest;
5443 struct peer *peer = wq->spec.data;
5444 struct bgp_path_info *pi;
5445 struct bgp *bgp;
5446 afi_t afi = bgp_dest_table(dest)->afi;
5447 safi_t safi = bgp_dest_table(dest)->safi;
5448
5449 assert(dest && peer);
5450 bgp = peer->bgp;
5451
5452 /* It is possible that we have multiple paths for a prefix from a peer
5453 * if that peer is using AddPath.
5454 */
5455 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5456 if (pi->peer != peer)
5457 continue;
5458
5459 /* graceful restart STALE flag set. */
5460 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5461 && peer->nsf[afi][safi])
5462 || CHECK_FLAG(peer->af_sflags[afi][safi],
5463 PEER_STATUS_ENHANCED_REFRESH))
5464 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5465 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5466 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5467 else {
5468 /* If this is an EVPN route, process for
5469 * un-import. */
5470 if (safi == SAFI_EVPN)
5471 bgp_evpn_unimport_route(
5472 bgp, afi, safi,
5473 bgp_dest_get_prefix(dest), pi);
5474 /* Handle withdraw for VRF route-leaking and L3VPN */
5475 if (SAFI_UNICAST == safi
5476 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5477 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5478 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5479 bgp, pi);
5480 }
5481 if (SAFI_MPLS_VPN == safi &&
5482 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5483 vpn_leak_to_vrf_withdraw(bgp, pi);
5484 }
5485
5486 bgp_rib_remove(dest, pi, peer, afi, safi);
5487 }
5488 }
5489 return WQ_SUCCESS;
5490 }
5491
5492 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5493 {
5494 struct bgp_clear_node_queue *cnq = data;
5495 struct bgp_dest *dest = cnq->dest;
5496 struct bgp_table *table = bgp_dest_table(dest);
5497
5498 bgp_dest_unlock_node(dest);
5499 bgp_table_unlock(table);
5500 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5501 }
5502
5503 static void bgp_clear_node_complete(struct work_queue *wq)
5504 {
5505 struct peer *peer = wq->spec.data;
5506
5507 /* Tickle FSM to start moving again */
5508 BGP_EVENT_ADD(peer, Clearing_Completed);
5509
5510 peer_unlock(peer); /* bgp_clear_route */
5511 }
5512
5513 static void bgp_clear_node_queue_init(struct peer *peer)
5514 {
5515 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5516
5517 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5518 #undef CLEAR_QUEUE_NAME_LEN
5519
5520 peer->clear_node_queue = work_queue_new(bm->master, wname);
5521 peer->clear_node_queue->spec.hold = 10;
5522 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5523 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5524 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5525 peer->clear_node_queue->spec.max_retries = 0;
5526
5527 /* we only 'lock' this peer reference when the queue is actually active
5528 */
5529 peer->clear_node_queue->spec.data = peer;
5530 }
5531
5532 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5533 struct bgp_table *table)
5534 {
5535 struct bgp_dest *dest;
5536 int force = peer->bgp->process_queue ? 0 : 1;
5537
5538 if (!table)
5539 table = peer->bgp->rib[afi][safi];
5540
5541 /* If still no table => afi/safi isn't configured at all or smth. */
5542 if (!table)
5543 return;
5544
5545 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5546 struct bgp_path_info *pi, *next;
5547 struct bgp_adj_in *ain;
5548 struct bgp_adj_in *ain_next;
5549
5550 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5551 * queued for every clearing peer, regardless of whether it is
5552 * relevant to the peer at hand.
5553 *
5554 * Overview: There are 3 different indices which need to be
5555 * scrubbed, potentially, when a peer is removed:
5556 *
5557 * 1 peer's routes visible via the RIB (ie accepted routes)
5558 * 2 peer's routes visible by the (optional) peer's adj-in index
5559 * 3 other routes visible by the peer's adj-out index
5560 *
5561 * 3 there is no hurry in scrubbing, once the struct peer is
5562 * removed from bgp->peer, we could just GC such deleted peer's
5563 * adj-outs at our leisure.
5564 *
5565 * 1 and 2 must be 'scrubbed' in some way, at least made
5566 * invisible via RIB index before peer session is allowed to be
5567 * brought back up. So one needs to know when such a 'search' is
5568 * complete.
5569 *
5570 * Ideally:
5571 *
5572 * - there'd be a single global queue or a single RIB walker
5573 * - rather than tracking which route_nodes still need to be
5574 * examined on a peer basis, we'd track which peers still
5575 * aren't cleared
5576 *
5577 * Given that our per-peer prefix-counts now should be reliable,
5578 * this may actually be achievable. It doesn't seem to be a huge
5579 * problem at this time,
5580 *
5581 * It is possible that we have multiple paths for a prefix from
5582 * a peer
5583 * if that peer is using AddPath.
5584 */
5585 ain = dest->adj_in;
5586 while (ain) {
5587 ain_next = ain->next;
5588
5589 if (ain->peer == peer)
5590 bgp_adj_in_remove(dest, ain);
5591
5592 ain = ain_next;
5593 }
5594
5595 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5596 next = pi->next;
5597 if (pi->peer != peer)
5598 continue;
5599
5600 if (force)
5601 bgp_path_info_reap(dest, pi);
5602 else {
5603 struct bgp_clear_node_queue *cnq;
5604
5605 /* both unlocked in bgp_clear_node_queue_del */
5606 bgp_table_lock(bgp_dest_table(dest));
5607 bgp_dest_lock_node(dest);
5608 cnq = XCALLOC(
5609 MTYPE_BGP_CLEAR_NODE_QUEUE,
5610 sizeof(struct bgp_clear_node_queue));
5611 cnq->dest = dest;
5612 work_queue_add(peer->clear_node_queue, cnq);
5613 break;
5614 }
5615 }
5616 }
5617 return;
5618 }
5619
5620 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5621 {
5622 struct bgp_dest *dest;
5623 struct bgp_table *table;
5624
5625 if (peer->clear_node_queue == NULL)
5626 bgp_clear_node_queue_init(peer);
5627
5628 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5629 * Idle until it receives a Clearing_Completed event. This protects
5630 * against peers which flap faster than we can we clear, which could
5631 * lead to:
5632 *
5633 * a) race with routes from the new session being installed before
5634 * clear_route_node visits the node (to delete the route of that
5635 * peer)
5636 * b) resource exhaustion, clear_route_node likely leads to an entry
5637 * on the process_main queue. Fast-flapping could cause that queue
5638 * to grow and grow.
5639 */
5640
5641 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5642 * the unlock will happen upon work-queue completion; other wise, the
5643 * unlock happens at the end of this function.
5644 */
5645 if (!peer->clear_node_queue->thread)
5646 peer_lock(peer);
5647
5648 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5649 bgp_clear_route_table(peer, afi, safi, NULL);
5650 else
5651 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5652 dest = bgp_route_next(dest)) {
5653 table = bgp_dest_get_bgp_table_info(dest);
5654 if (!table)
5655 continue;
5656
5657 bgp_clear_route_table(peer, afi, safi, table);
5658 }
5659
5660 /* unlock if no nodes got added to the clear-node-queue. */
5661 if (!peer->clear_node_queue->thread)
5662 peer_unlock(peer);
5663 }
5664
5665 void bgp_clear_route_all(struct peer *peer)
5666 {
5667 afi_t afi;
5668 safi_t safi;
5669
5670 FOREACH_AFI_SAFI (afi, safi)
5671 bgp_clear_route(peer, afi, safi);
5672
5673 #ifdef ENABLE_BGP_VNC
5674 rfapiProcessPeerDown(peer);
5675 #endif
5676 }
5677
5678 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5679 {
5680 struct bgp_table *table;
5681 struct bgp_dest *dest;
5682 struct bgp_adj_in *ain;
5683 struct bgp_adj_in *ain_next;
5684
5685 table = peer->bgp->rib[afi][safi];
5686
5687 /* It is possible that we have multiple paths for a prefix from a peer
5688 * if that peer is using AddPath.
5689 */
5690 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5691 ain = dest->adj_in;
5692
5693 while (ain) {
5694 ain_next = ain->next;
5695
5696 if (ain->peer == peer)
5697 bgp_adj_in_remove(dest, ain);
5698
5699 ain = ain_next;
5700 }
5701 }
5702 }
5703
5704 /* If any of the routes from the peer have been marked with the NO_LLGR
5705 * community, either as sent by the peer, or as the result of a configured
5706 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5707 * operation of [RFC4271].
5708 */
5709 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5710 {
5711 struct bgp_dest *dest;
5712 struct bgp_path_info *pi;
5713 struct bgp_table *table;
5714
5715 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5716 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5717 dest = bgp_route_next(dest)) {
5718 struct bgp_dest *rm;
5719
5720 /* look for neighbor in tables */
5721 table = bgp_dest_get_bgp_table_info(dest);
5722 if (!table)
5723 continue;
5724
5725 for (rm = bgp_table_top(table); rm;
5726 rm = bgp_route_next(rm))
5727 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5728 pi = pi->next) {
5729 if (pi->peer != peer)
5730 continue;
5731 if (CHECK_FLAG(
5732 peer->af_sflags[afi][safi],
5733 PEER_STATUS_LLGR_WAIT) &&
5734 bgp_attr_get_community(pi->attr) &&
5735 !community_include(
5736 bgp_attr_get_community(
5737 pi->attr),
5738 COMMUNITY_NO_LLGR))
5739 continue;
5740 if (!CHECK_FLAG(pi->flags,
5741 BGP_PATH_STALE))
5742 continue;
5743
5744 /*
5745 * If this is VRF leaked route
5746 * process for withdraw.
5747 */
5748 if (pi->sub_type ==
5749 BGP_ROUTE_IMPORTED &&
5750 peer->bgp->inst_type ==
5751 BGP_INSTANCE_TYPE_DEFAULT)
5752 vpn_leak_to_vrf_withdraw(
5753 peer->bgp, pi);
5754
5755 bgp_rib_remove(rm, pi, peer, afi, safi);
5756 break;
5757 }
5758 }
5759 } else {
5760 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5761 dest = bgp_route_next(dest))
5762 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5763 pi = pi->next) {
5764 if (pi->peer != peer)
5765 continue;
5766 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5767 PEER_STATUS_LLGR_WAIT) &&
5768 bgp_attr_get_community(pi->attr) &&
5769 !community_include(
5770 bgp_attr_get_community(pi->attr),
5771 COMMUNITY_NO_LLGR))
5772 continue;
5773 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5774 continue;
5775 if (safi == SAFI_UNICAST &&
5776 (peer->bgp->inst_type ==
5777 BGP_INSTANCE_TYPE_VRF ||
5778 peer->bgp->inst_type ==
5779 BGP_INSTANCE_TYPE_DEFAULT))
5780 vpn_leak_from_vrf_withdraw(
5781 bgp_get_default(), peer->bgp,
5782 pi);
5783
5784 bgp_rib_remove(dest, pi, peer, afi, safi);
5785 break;
5786 }
5787 }
5788 }
5789
5790 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5791 {
5792 struct bgp_dest *dest, *ndest;
5793 struct bgp_path_info *pi;
5794 struct bgp_table *table;
5795
5796 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5797 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5798 dest = bgp_route_next(dest)) {
5799 table = bgp_dest_get_bgp_table_info(dest);
5800 if (!table)
5801 continue;
5802
5803 for (ndest = bgp_table_top(table); ndest;
5804 ndest = bgp_route_next(ndest)) {
5805 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5806 pi = pi->next) {
5807 if (pi->peer != peer)
5808 continue;
5809
5810 if ((CHECK_FLAG(
5811 peer->af_sflags[afi][safi],
5812 PEER_STATUS_ENHANCED_REFRESH))
5813 && !CHECK_FLAG(pi->flags,
5814 BGP_PATH_STALE)
5815 && !CHECK_FLAG(
5816 pi->flags,
5817 BGP_PATH_UNUSEABLE)) {
5818 if (bgp_debug_neighbor_events(
5819 peer))
5820 zlog_debug(
5821 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5822 peer,
5823 afi2str(afi),
5824 safi2str(safi),
5825 bgp_dest_get_prefix(
5826 ndest));
5827
5828 bgp_path_info_set_flag(
5829 ndest, pi,
5830 BGP_PATH_STALE);
5831 }
5832 }
5833 }
5834 }
5835 } else {
5836 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5837 dest = bgp_route_next(dest)) {
5838 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5839 pi = pi->next) {
5840 if (pi->peer != peer)
5841 continue;
5842
5843 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5844 PEER_STATUS_ENHANCED_REFRESH))
5845 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5846 && !CHECK_FLAG(pi->flags,
5847 BGP_PATH_UNUSEABLE)) {
5848 if (bgp_debug_neighbor_events(peer))
5849 zlog_debug(
5850 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5851 peer, afi2str(afi),
5852 safi2str(safi),
5853 bgp_dest_get_prefix(
5854 dest));
5855
5856 bgp_path_info_set_flag(dest, pi,
5857 BGP_PATH_STALE);
5858 }
5859 }
5860 }
5861 }
5862 }
5863
5864 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5865 {
5866 if (peer->sort == BGP_PEER_IBGP)
5867 return true;
5868
5869 if (peer->sort == BGP_PEER_EBGP
5870 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5871 || FILTER_LIST_OUT_NAME(filter)
5872 || DISTRIBUTE_OUT_NAME(filter)))
5873 return true;
5874 return false;
5875 }
5876
5877 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5878 {
5879 if (peer->sort == BGP_PEER_IBGP)
5880 return true;
5881
5882 if (peer->sort == BGP_PEER_EBGP
5883 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5884 || FILTER_LIST_IN_NAME(filter)
5885 || DISTRIBUTE_IN_NAME(filter)))
5886 return true;
5887 return false;
5888 }
5889
5890 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5891 safi_t safi)
5892 {
5893 struct bgp_dest *dest;
5894 struct bgp_path_info *pi;
5895 struct bgp_path_info *next;
5896
5897 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5898 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5899 const struct prefix *p = bgp_dest_get_prefix(dest);
5900
5901 next = pi->next;
5902
5903 /* Unimport EVPN routes from VRFs */
5904 if (safi == SAFI_EVPN)
5905 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5906 SAFI_EVPN, p, pi);
5907
5908 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5909 && pi->type == ZEBRA_ROUTE_BGP
5910 && (pi->sub_type == BGP_ROUTE_NORMAL
5911 || pi->sub_type == BGP_ROUTE_AGGREGATE
5912 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5913
5914 if (bgp_fibupd_safi(safi))
5915 bgp_zebra_withdraw(p, pi, bgp, safi);
5916 }
5917
5918 bgp_path_info_reap(dest, pi);
5919 }
5920 }
5921
5922 /* Delete all kernel routes. */
5923 void bgp_cleanup_routes(struct bgp *bgp)
5924 {
5925 afi_t afi;
5926 struct bgp_dest *dest;
5927 struct bgp_table *table;
5928
5929 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5930 if (afi == AFI_L2VPN)
5931 continue;
5932 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5933 SAFI_UNICAST);
5934 /*
5935 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5936 */
5937 if (afi != AFI_L2VPN) {
5938 safi_t safi;
5939 safi = SAFI_MPLS_VPN;
5940 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5941 dest = bgp_route_next(dest)) {
5942 table = bgp_dest_get_bgp_table_info(dest);
5943 if (table != NULL) {
5944 bgp_cleanup_table(bgp, table, safi);
5945 bgp_table_finish(&table);
5946 bgp_dest_set_bgp_table_info(dest, NULL);
5947 bgp_dest_unlock_node(dest);
5948 }
5949 }
5950 safi = SAFI_ENCAP;
5951 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5952 dest = bgp_route_next(dest)) {
5953 table = bgp_dest_get_bgp_table_info(dest);
5954 if (table != NULL) {
5955 bgp_cleanup_table(bgp, table, safi);
5956 bgp_table_finish(&table);
5957 bgp_dest_set_bgp_table_info(dest, NULL);
5958 bgp_dest_unlock_node(dest);
5959 }
5960 }
5961 }
5962 }
5963 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5964 dest = bgp_route_next(dest)) {
5965 table = bgp_dest_get_bgp_table_info(dest);
5966 if (table != NULL) {
5967 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5968 bgp_table_finish(&table);
5969 bgp_dest_set_bgp_table_info(dest, NULL);
5970 bgp_dest_unlock_node(dest);
5971 }
5972 }
5973 }
5974
5975 void bgp_reset(void)
5976 {
5977 vty_reset();
5978 bgp_zclient_reset();
5979 access_list_reset();
5980 prefix_list_reset();
5981 }
5982
5983 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5984 {
5985 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5986 && CHECK_FLAG(peer->af_cap[afi][safi],
5987 PEER_CAP_ADDPATH_AF_TX_RCV));
5988 }
5989
5990 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5991 value. */
5992 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5993 struct bgp_nlri *packet)
5994 {
5995 uint8_t *pnt;
5996 uint8_t *lim;
5997 struct prefix p;
5998 int psize;
5999 int ret;
6000 afi_t afi;
6001 safi_t safi;
6002 bool addpath_capable;
6003 uint32_t addpath_id;
6004
6005 pnt = packet->nlri;
6006 lim = pnt + packet->length;
6007 afi = packet->afi;
6008 safi = packet->safi;
6009 addpath_id = 0;
6010 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
6011
6012 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
6013 syntactic validity. If the field is syntactically incorrect,
6014 then the Error Subcode is set to Invalid Network Field. */
6015 for (; pnt < lim; pnt += psize) {
6016 /* Clear prefix structure. */
6017 memset(&p, 0, sizeof(p));
6018
6019 if (addpath_capable) {
6020
6021 /* When packet overflow occurs return immediately. */
6022 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
6023 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6024
6025 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
6026 addpath_id = ntohl(addpath_id);
6027 pnt += BGP_ADDPATH_ID_LEN;
6028 }
6029
6030 /* Fetch prefix length. */
6031 p.prefixlen = *pnt++;
6032 /* afi/safi validity already verified by caller,
6033 * bgp_update_receive */
6034 p.family = afi2family(afi);
6035
6036 /* Prefix length check. */
6037 if (p.prefixlen > prefix_blen(&p) * 8) {
6038 flog_err(
6039 EC_BGP_UPDATE_RCV,
6040 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6041 peer->host, p.prefixlen, packet->afi);
6042 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6043 }
6044
6045 /* Packet size overflow check. */
6046 psize = PSIZE(p.prefixlen);
6047
6048 /* When packet overflow occur return immediately. */
6049 if (pnt + psize > lim) {
6050 flog_err(
6051 EC_BGP_UPDATE_RCV,
6052 "%s [Error] Update packet error (prefix length %d overflows packet)",
6053 peer->host, p.prefixlen);
6054 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6055 }
6056
6057 /* Defensive coding, double-check the psize fits in a struct
6058 * prefix for the v4 and v6 afi's and unicast/multicast */
6059 if (psize > (ssize_t)sizeof(p.u.val)) {
6060 flog_err(
6061 EC_BGP_UPDATE_RCV,
6062 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6063 peer->host, p.prefixlen, sizeof(p.u.val));
6064 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6065 }
6066
6067 /* Fetch prefix from NLRI packet. */
6068 memcpy(p.u.val, pnt, psize);
6069
6070 /* Check address. */
6071 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6072 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6073 /* From RFC4271 Section 6.3:
6074 *
6075 * If a prefix in the NLRI field is semantically
6076 * incorrect
6077 * (e.g., an unexpected multicast IP address),
6078 * an error SHOULD
6079 * be logged locally, and the prefix SHOULD be
6080 * ignored.
6081 */
6082 flog_err(
6083 EC_BGP_UPDATE_RCV,
6084 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6085 peer->host, &p.u.prefix4);
6086 continue;
6087 }
6088 }
6089
6090 /* Check address. */
6091 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6092 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6093 flog_err(
6094 EC_BGP_UPDATE_RCV,
6095 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6096 peer->host, &p.u.prefix6);
6097
6098 continue;
6099 }
6100 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6101 flog_err(
6102 EC_BGP_UPDATE_RCV,
6103 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6104 peer->host, &p.u.prefix6);
6105
6106 continue;
6107 }
6108 }
6109
6110 /* Normal process. */
6111 if (attr)
6112 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
6113 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
6114 NULL, NULL, 0, 0, NULL);
6115 else
6116 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
6117 safi, ZEBRA_ROUTE_BGP,
6118 BGP_ROUTE_NORMAL, NULL, NULL, 0,
6119 NULL);
6120
6121 /* Do not send BGP notification twice when maximum-prefix count
6122 * overflow. */
6123 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6124 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6125
6126 /* Address family configuration mismatch. */
6127 if (ret < 0)
6128 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
6129 }
6130
6131 /* Packet length consistency check. */
6132 if (pnt != lim) {
6133 flog_err(
6134 EC_BGP_UPDATE_RCV,
6135 "%s [Error] Update packet error (prefix length mismatch with total length)",
6136 peer->host);
6137 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6138 }
6139
6140 return BGP_NLRI_PARSE_OK;
6141 }
6142
6143 static struct bgp_static *bgp_static_new(void)
6144 {
6145 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6146 }
6147
6148 static void bgp_static_free(struct bgp_static *bgp_static)
6149 {
6150 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6151 route_map_counter_decrement(bgp_static->rmap.map);
6152
6153 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6154 XFREE(MTYPE_BGP_STATIC, bgp_static);
6155 }
6156
6157 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6158 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6159 {
6160 struct bgp_dest *dest;
6161 struct bgp_path_info *pi;
6162 struct bgp_path_info *new;
6163 struct bgp_path_info rmap_path;
6164 struct attr attr;
6165 struct attr *attr_new;
6166 route_map_result_t ret;
6167 #ifdef ENABLE_BGP_VNC
6168 int vnc_implicit_withdraw = 0;
6169 #endif
6170
6171 assert(bgp_static);
6172
6173 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6174
6175 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6176
6177 attr.nexthop = bgp_static->igpnexthop;
6178 attr.med = bgp_static->igpmetric;
6179 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6180
6181 if (afi == AFI_IP)
6182 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6183
6184 if (bgp_static->igpmetric)
6185 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6186
6187 if (bgp_static->atomic)
6188 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6189
6190 /* Store label index, if required. */
6191 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6192 attr.label_index = bgp_static->label_index;
6193 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6194 }
6195
6196 /* Apply route-map. */
6197 if (bgp_static->rmap.name) {
6198 struct attr attr_tmp = attr;
6199
6200 memset(&rmap_path, 0, sizeof(rmap_path));
6201 rmap_path.peer = bgp->peer_self;
6202 rmap_path.attr = &attr_tmp;
6203
6204 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6205
6206 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6207
6208 bgp->peer_self->rmap_type = 0;
6209
6210 if (ret == RMAP_DENYMATCH) {
6211 /* Free uninterned attribute. */
6212 bgp_attr_flush(&attr_tmp);
6213
6214 /* Unintern original. */
6215 aspath_unintern(&attr.aspath);
6216 bgp_static_withdraw(bgp, p, afi, safi);
6217 bgp_dest_unlock_node(dest);
6218 return;
6219 }
6220
6221 if (bgp_in_graceful_shutdown(bgp))
6222 bgp_attr_add_gshut_community(&attr_tmp);
6223
6224 attr_new = bgp_attr_intern(&attr_tmp);
6225 } else {
6226
6227 if (bgp_in_graceful_shutdown(bgp))
6228 bgp_attr_add_gshut_community(&attr);
6229
6230 attr_new = bgp_attr_intern(&attr);
6231 }
6232
6233 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6234 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6235 && pi->sub_type == BGP_ROUTE_STATIC)
6236 break;
6237
6238 if (pi) {
6239 if (attrhash_cmp(pi->attr, attr_new)
6240 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6241 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6242 bgp_dest_unlock_node(dest);
6243 bgp_attr_unintern(&attr_new);
6244 aspath_unintern(&attr.aspath);
6245 return;
6246 } else {
6247 /* The attribute is changed. */
6248 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6249
6250 /* Rewrite BGP route information. */
6251 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6252 bgp_path_info_restore(dest, pi);
6253 else
6254 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6255 #ifdef ENABLE_BGP_VNC
6256 if ((afi == AFI_IP || afi == AFI_IP6)
6257 && (safi == SAFI_UNICAST)) {
6258 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6259 /*
6260 * Implicit withdraw case.
6261 * We have to do this before pi is
6262 * changed
6263 */
6264 ++vnc_implicit_withdraw;
6265 vnc_import_bgp_del_route(bgp, p, pi);
6266 vnc_import_bgp_exterior_del_route(
6267 bgp, p, pi);
6268 }
6269 }
6270 #endif
6271 bgp_attr_unintern(&pi->attr);
6272 pi->attr = attr_new;
6273 pi->uptime = monotime(NULL);
6274 #ifdef ENABLE_BGP_VNC
6275 if ((afi == AFI_IP || afi == AFI_IP6)
6276 && (safi == SAFI_UNICAST)) {
6277 if (vnc_implicit_withdraw) {
6278 vnc_import_bgp_add_route(bgp, p, pi);
6279 vnc_import_bgp_exterior_add_route(
6280 bgp, p, pi);
6281 }
6282 }
6283 #endif
6284
6285 /* Nexthop reachability check. */
6286 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6287 && (safi == SAFI_UNICAST
6288 || safi == SAFI_LABELED_UNICAST)) {
6289
6290 struct bgp *bgp_nexthop = bgp;
6291
6292 if (pi->extra && pi->extra->bgp_orig)
6293 bgp_nexthop = pi->extra->bgp_orig;
6294
6295 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6296 afi, safi, pi, NULL,
6297 0, p))
6298 bgp_path_info_set_flag(dest, pi,
6299 BGP_PATH_VALID);
6300 else {
6301 if (BGP_DEBUG(nht, NHT)) {
6302 char buf1[INET6_ADDRSTRLEN];
6303 inet_ntop(p->family,
6304 &p->u.prefix, buf1,
6305 INET6_ADDRSTRLEN);
6306 zlog_debug(
6307 "%s(%s): Route not in table, not advertising",
6308 __func__, buf1);
6309 }
6310 bgp_path_info_unset_flag(
6311 dest, pi, BGP_PATH_VALID);
6312 }
6313 } else {
6314 /* Delete the NHT structure if any, if we're
6315 * toggling between
6316 * enabling/disabling import check. We
6317 * deregister the route
6318 * from NHT to avoid overloading NHT and the
6319 * process interaction
6320 */
6321 bgp_unlink_nexthop(pi);
6322 bgp_path_info_set_flag(dest, pi,
6323 BGP_PATH_VALID);
6324 }
6325 /* Process change. */
6326 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6327 bgp_process(bgp, dest, afi, safi);
6328
6329 if (SAFI_UNICAST == safi
6330 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6331 || bgp->inst_type
6332 == BGP_INSTANCE_TYPE_DEFAULT)) {
6333 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6334 pi);
6335 }
6336
6337 bgp_dest_unlock_node(dest);
6338 aspath_unintern(&attr.aspath);
6339 return;
6340 }
6341 }
6342
6343 /* Make new BGP info. */
6344 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6345 attr_new, dest);
6346 /* Nexthop reachability check. */
6347 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6348 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6349 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6350 p))
6351 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6352 else {
6353 if (BGP_DEBUG(nht, NHT)) {
6354 char buf1[INET6_ADDRSTRLEN];
6355 inet_ntop(p->family, &p->u.prefix, buf1,
6356 INET6_ADDRSTRLEN);
6357 zlog_debug(
6358 "%s(%s): Route not in table, not advertising",
6359 __func__, buf1);
6360 }
6361 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6362 }
6363 } else {
6364 /* Delete the NHT structure if any, if we're toggling between
6365 * enabling/disabling import check. We deregister the route
6366 * from NHT to avoid overloading NHT and the process interaction
6367 */
6368 bgp_unlink_nexthop(new);
6369
6370 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6371 }
6372
6373 /* Aggregate address increment. */
6374 bgp_aggregate_increment(bgp, p, new, afi, safi);
6375
6376 /* Register new BGP information. */
6377 bgp_path_info_add(dest, new);
6378
6379 /* route_node_get lock */
6380 bgp_dest_unlock_node(dest);
6381
6382 /* Process change. */
6383 bgp_process(bgp, dest, afi, safi);
6384
6385 if (SAFI_UNICAST == safi
6386 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6387 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6388 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6389 }
6390
6391 /* Unintern original. */
6392 aspath_unintern(&attr.aspath);
6393 }
6394
6395 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6396 safi_t safi)
6397 {
6398 struct bgp_dest *dest;
6399 struct bgp_path_info *pi;
6400
6401 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6402
6403 /* Check selected route and self inserted route. */
6404 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6405 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6406 && pi->sub_type == BGP_ROUTE_STATIC)
6407 break;
6408
6409 /* Withdraw static BGP route from routing table. */
6410 if (pi) {
6411 if (SAFI_UNICAST == safi
6412 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6413 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6414 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6415 }
6416 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6417 bgp_unlink_nexthop(pi);
6418 bgp_path_info_delete(dest, pi);
6419 bgp_process(bgp, dest, afi, safi);
6420 }
6421
6422 /* Unlock bgp_node_lookup. */
6423 bgp_dest_unlock_node(dest);
6424 }
6425
6426 /*
6427 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6428 */
6429 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6430 afi_t afi, safi_t safi,
6431 struct prefix_rd *prd)
6432 {
6433 struct bgp_dest *dest;
6434 struct bgp_path_info *pi;
6435
6436 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6437
6438 /* Check selected route and self inserted route. */
6439 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6440 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6441 && pi->sub_type == BGP_ROUTE_STATIC)
6442 break;
6443
6444 /* Withdraw static BGP route from routing table. */
6445 if (pi) {
6446 #ifdef ENABLE_BGP_VNC
6447 rfapiProcessWithdraw(
6448 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6449 1); /* Kill, since it is an administrative change */
6450 #endif
6451 if (SAFI_MPLS_VPN == safi
6452 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6453 vpn_leak_to_vrf_withdraw(bgp, pi);
6454 }
6455 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6456 bgp_path_info_delete(dest, pi);
6457 bgp_process(bgp, dest, afi, safi);
6458 }
6459
6460 /* Unlock bgp_node_lookup. */
6461 bgp_dest_unlock_node(dest);
6462 }
6463
6464 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6465 struct bgp_static *bgp_static, afi_t afi,
6466 safi_t safi)
6467 {
6468 struct bgp_dest *dest;
6469 struct bgp_path_info *new;
6470 struct attr *attr_new;
6471 struct attr attr = {0};
6472 struct bgp_path_info *pi;
6473 #ifdef ENABLE_BGP_VNC
6474 mpls_label_t label = 0;
6475 #endif
6476 uint32_t num_labels = 0;
6477
6478 assert(bgp_static);
6479
6480 if (bgp_static->label != MPLS_INVALID_LABEL)
6481 num_labels = 1;
6482 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6483 &bgp_static->prd);
6484
6485 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6486
6487 attr.nexthop = bgp_static->igpnexthop;
6488 attr.med = bgp_static->igpmetric;
6489 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6490
6491 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6492 || (safi == SAFI_ENCAP)) {
6493 if (afi == AFI_IP) {
6494 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6495 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6496 }
6497 }
6498 if (afi == AFI_L2VPN) {
6499 if (bgp_static->gatewayIp.family == AF_INET) {
6500 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6501 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6502 &bgp_static->gatewayIp.u.prefix4,
6503 IPV4_MAX_BYTELEN);
6504 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6505 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6506 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6507 &bgp_static->gatewayIp.u.prefix6,
6508 IPV6_MAX_BYTELEN);
6509 }
6510 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6511 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6512 struct bgp_encap_type_vxlan bet;
6513 memset(&bet, 0, sizeof(bet));
6514 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6515 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6516 }
6517 if (bgp_static->router_mac) {
6518 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6519 }
6520 }
6521 /* Apply route-map. */
6522 if (bgp_static->rmap.name) {
6523 struct attr attr_tmp = attr;
6524 struct bgp_path_info rmap_path;
6525 route_map_result_t ret;
6526
6527 rmap_path.peer = bgp->peer_self;
6528 rmap_path.attr = &attr_tmp;
6529
6530 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6531
6532 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6533
6534 bgp->peer_self->rmap_type = 0;
6535
6536 if (ret == RMAP_DENYMATCH) {
6537 /* Free uninterned attribute. */
6538 bgp_attr_flush(&attr_tmp);
6539
6540 /* Unintern original. */
6541 aspath_unintern(&attr.aspath);
6542 bgp_static_withdraw_safi(bgp, p, afi, safi,
6543 &bgp_static->prd);
6544 bgp_dest_unlock_node(dest);
6545 return;
6546 }
6547
6548 attr_new = bgp_attr_intern(&attr_tmp);
6549 } else {
6550 attr_new = bgp_attr_intern(&attr);
6551 }
6552
6553 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6554 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6555 && pi->sub_type == BGP_ROUTE_STATIC)
6556 break;
6557
6558 if (pi) {
6559 if (attrhash_cmp(pi->attr, attr_new)
6560 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6561 bgp_dest_unlock_node(dest);
6562 bgp_attr_unintern(&attr_new);
6563 aspath_unintern(&attr.aspath);
6564 return;
6565 } else {
6566 /* The attribute is changed. */
6567 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6568
6569 /* Rewrite BGP route information. */
6570 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6571 bgp_path_info_restore(dest, pi);
6572 else
6573 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6574 bgp_attr_unintern(&pi->attr);
6575 pi->attr = attr_new;
6576 pi->uptime = monotime(NULL);
6577 #ifdef ENABLE_BGP_VNC
6578 if (pi->extra)
6579 label = decode_label(&pi->extra->label[0]);
6580 #endif
6581
6582 /* Process change. */
6583 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6584 bgp_process(bgp, dest, afi, safi);
6585
6586 if (SAFI_MPLS_VPN == safi
6587 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6588 vpn_leak_to_vrf_update(bgp, pi,
6589 &bgp_static->prd);
6590 }
6591 #ifdef ENABLE_BGP_VNC
6592 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6593 pi->attr, afi, safi, pi->type,
6594 pi->sub_type, &label);
6595 #endif
6596 bgp_dest_unlock_node(dest);
6597 aspath_unintern(&attr.aspath);
6598 return;
6599 }
6600 }
6601
6602
6603 /* Make new BGP info. */
6604 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6605 attr_new, dest);
6606 SET_FLAG(new->flags, BGP_PATH_VALID);
6607 bgp_path_info_extra_get(new);
6608 if (num_labels) {
6609 new->extra->label[0] = bgp_static->label;
6610 new->extra->num_labels = num_labels;
6611 }
6612 #ifdef ENABLE_BGP_VNC
6613 label = decode_label(&bgp_static->label);
6614 #endif
6615
6616 /* Aggregate address increment. */
6617 bgp_aggregate_increment(bgp, p, new, afi, safi);
6618
6619 /* Register new BGP information. */
6620 bgp_path_info_add(dest, new);
6621 /* route_node_get lock */
6622 bgp_dest_unlock_node(dest);
6623
6624 /* Process change. */
6625 bgp_process(bgp, dest, afi, safi);
6626
6627 if (SAFI_MPLS_VPN == safi
6628 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6629 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6630 }
6631 #ifdef ENABLE_BGP_VNC
6632 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6633 safi, new->type, new->sub_type, &label);
6634 #endif
6635
6636 /* Unintern original. */
6637 aspath_unintern(&attr.aspath);
6638 }
6639
6640 /* Configure static BGP network. When user don't run zebra, static
6641 route should be installed as valid. */
6642 static int bgp_static_set(struct vty *vty, const char *negate,
6643 const char *ip_str, afi_t afi, safi_t safi,
6644 const char *rmap, int backdoor, uint32_t label_index)
6645 {
6646 VTY_DECLVAR_CONTEXT(bgp, bgp);
6647 int ret;
6648 struct prefix p;
6649 struct bgp_static *bgp_static;
6650 struct bgp_dest *dest;
6651 uint8_t need_update = 0;
6652
6653 /* Convert IP prefix string to struct prefix. */
6654 ret = str2prefix(ip_str, &p);
6655 if (!ret) {
6656 vty_out(vty, "%% Malformed prefix\n");
6657 return CMD_WARNING_CONFIG_FAILED;
6658 }
6659 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6660 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6661 return CMD_WARNING_CONFIG_FAILED;
6662 }
6663
6664 apply_mask(&p);
6665
6666 if (negate) {
6667
6668 /* Set BGP static route configuration. */
6669 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6670
6671 if (!dest) {
6672 vty_out(vty, "%% Can't find static route specified\n");
6673 return CMD_WARNING_CONFIG_FAILED;
6674 }
6675
6676 bgp_static = bgp_dest_get_bgp_static_info(dest);
6677
6678 if ((label_index != BGP_INVALID_LABEL_INDEX)
6679 && (label_index != bgp_static->label_index)) {
6680 vty_out(vty,
6681 "%% label-index doesn't match static route\n");
6682 bgp_dest_unlock_node(dest);
6683 return CMD_WARNING_CONFIG_FAILED;
6684 }
6685
6686 if ((rmap && bgp_static->rmap.name)
6687 && strcmp(rmap, bgp_static->rmap.name)) {
6688 vty_out(vty,
6689 "%% route-map name doesn't match static route\n");
6690 bgp_dest_unlock_node(dest);
6691 return CMD_WARNING_CONFIG_FAILED;
6692 }
6693
6694 /* Update BGP RIB. */
6695 if (!bgp_static->backdoor)
6696 bgp_static_withdraw(bgp, &p, afi, safi);
6697
6698 /* Clear configuration. */
6699 bgp_static_free(bgp_static);
6700 bgp_dest_set_bgp_static_info(dest, NULL);
6701 bgp_dest_unlock_node(dest);
6702 bgp_dest_unlock_node(dest);
6703 } else {
6704
6705 /* Set BGP static route configuration. */
6706 dest = bgp_node_get(bgp->route[afi][safi], &p);
6707 bgp_static = bgp_dest_get_bgp_static_info(dest);
6708 if (bgp_static) {
6709 /* Configuration change. */
6710 /* Label index cannot be changed. */
6711 if (bgp_static->label_index != label_index) {
6712 vty_out(vty, "%% cannot change label-index\n");
6713 bgp_dest_unlock_node(dest);
6714 return CMD_WARNING_CONFIG_FAILED;
6715 }
6716
6717 /* Check previous routes are installed into BGP. */
6718 if (bgp_static->valid
6719 && bgp_static->backdoor != backdoor)
6720 need_update = 1;
6721
6722 bgp_static->backdoor = backdoor;
6723
6724 if (rmap) {
6725 XFREE(MTYPE_ROUTE_MAP_NAME,
6726 bgp_static->rmap.name);
6727 route_map_counter_decrement(
6728 bgp_static->rmap.map);
6729 bgp_static->rmap.name =
6730 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6731 bgp_static->rmap.map =
6732 route_map_lookup_by_name(rmap);
6733 route_map_counter_increment(
6734 bgp_static->rmap.map);
6735 } else {
6736 XFREE(MTYPE_ROUTE_MAP_NAME,
6737 bgp_static->rmap.name);
6738 route_map_counter_decrement(
6739 bgp_static->rmap.map);
6740 bgp_static->rmap.map = NULL;
6741 bgp_static->valid = 0;
6742 }
6743 bgp_dest_unlock_node(dest);
6744 } else {
6745 /* New configuration. */
6746 bgp_static = bgp_static_new();
6747 bgp_static->backdoor = backdoor;
6748 bgp_static->valid = 0;
6749 bgp_static->igpmetric = 0;
6750 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6751 bgp_static->label_index = label_index;
6752
6753 if (rmap) {
6754 XFREE(MTYPE_ROUTE_MAP_NAME,
6755 bgp_static->rmap.name);
6756 route_map_counter_decrement(
6757 bgp_static->rmap.map);
6758 bgp_static->rmap.name =
6759 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6760 bgp_static->rmap.map =
6761 route_map_lookup_by_name(rmap);
6762 route_map_counter_increment(
6763 bgp_static->rmap.map);
6764 }
6765 bgp_dest_set_bgp_static_info(dest, bgp_static);
6766 }
6767
6768 bgp_static->valid = 1;
6769 if (need_update)
6770 bgp_static_withdraw(bgp, &p, afi, safi);
6771
6772 if (!bgp_static->backdoor)
6773 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6774 }
6775
6776 return CMD_SUCCESS;
6777 }
6778
6779 void bgp_static_add(struct bgp *bgp)
6780 {
6781 afi_t afi;
6782 safi_t safi;
6783 struct bgp_dest *dest;
6784 struct bgp_dest *rm;
6785 struct bgp_table *table;
6786 struct bgp_static *bgp_static;
6787
6788 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6789 FOREACH_AFI_SAFI (afi, safi)
6790 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6791 dest = bgp_route_next(dest)) {
6792 if (!bgp_dest_has_bgp_path_info_data(dest))
6793 continue;
6794
6795 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6796 || (safi == SAFI_EVPN)) {
6797 table = bgp_dest_get_bgp_table_info(dest);
6798
6799 for (rm = bgp_table_top(table); rm;
6800 rm = bgp_route_next(rm)) {
6801 bgp_static =
6802 bgp_dest_get_bgp_static_info(
6803 rm);
6804 bgp_static_update_safi(
6805 bgp, bgp_dest_get_prefix(rm),
6806 bgp_static, afi, safi);
6807 }
6808 } else {
6809 bgp_static_update(
6810 bgp, bgp_dest_get_prefix(dest),
6811 bgp_dest_get_bgp_static_info(dest), afi,
6812 safi);
6813 }
6814 }
6815 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6816 }
6817
6818 /* Called from bgp_delete(). Delete all static routes from the BGP
6819 instance. */
6820 void bgp_static_delete(struct bgp *bgp)
6821 {
6822 afi_t afi;
6823 safi_t safi;
6824 struct bgp_dest *dest;
6825 struct bgp_dest *rm;
6826 struct bgp_table *table;
6827 struct bgp_static *bgp_static;
6828
6829 FOREACH_AFI_SAFI (afi, safi)
6830 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6831 dest = bgp_route_next(dest)) {
6832 if (!bgp_dest_has_bgp_path_info_data(dest))
6833 continue;
6834
6835 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6836 || (safi == SAFI_EVPN)) {
6837 table = bgp_dest_get_bgp_table_info(dest);
6838
6839 for (rm = bgp_table_top(table); rm;
6840 rm = bgp_route_next(rm)) {
6841 bgp_static =
6842 bgp_dest_get_bgp_static_info(
6843 rm);
6844 if (!bgp_static)
6845 continue;
6846
6847 bgp_static_withdraw_safi(
6848 bgp, bgp_dest_get_prefix(rm),
6849 AFI_IP, safi,
6850 (struct prefix_rd *)
6851 bgp_dest_get_prefix(
6852 dest));
6853 bgp_static_free(bgp_static);
6854 bgp_dest_set_bgp_static_info(rm,
6855 NULL);
6856 bgp_dest_unlock_node(rm);
6857 }
6858 } else {
6859 bgp_static = bgp_dest_get_bgp_static_info(dest);
6860 bgp_static_withdraw(bgp,
6861 bgp_dest_get_prefix(dest),
6862 afi, safi);
6863 bgp_static_free(bgp_static);
6864 bgp_dest_set_bgp_static_info(dest, NULL);
6865 bgp_dest_unlock_node(dest);
6866 }
6867 }
6868 }
6869
6870 void bgp_static_redo_import_check(struct bgp *bgp)
6871 {
6872 afi_t afi;
6873 safi_t safi;
6874 struct bgp_dest *dest;
6875 struct bgp_dest *rm;
6876 struct bgp_table *table;
6877 struct bgp_static *bgp_static;
6878
6879 /* Use this flag to force reprocessing of the route */
6880 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6881 FOREACH_AFI_SAFI (afi, safi) {
6882 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6883 dest = bgp_route_next(dest)) {
6884 if (!bgp_dest_has_bgp_path_info_data(dest))
6885 continue;
6886
6887 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6888 || (safi == SAFI_EVPN)) {
6889 table = bgp_dest_get_bgp_table_info(dest);
6890
6891 for (rm = bgp_table_top(table); rm;
6892 rm = bgp_route_next(rm)) {
6893 bgp_static =
6894 bgp_dest_get_bgp_static_info(
6895 rm);
6896 bgp_static_update_safi(
6897 bgp, bgp_dest_get_prefix(rm),
6898 bgp_static, afi, safi);
6899 }
6900 } else {
6901 bgp_static = bgp_dest_get_bgp_static_info(dest);
6902 bgp_static_update(bgp,
6903 bgp_dest_get_prefix(dest),
6904 bgp_static, afi, safi);
6905 }
6906 }
6907 }
6908 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6909 }
6910
6911 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6912 safi_t safi)
6913 {
6914 struct bgp_table *table;
6915 struct bgp_dest *dest;
6916 struct bgp_path_info *pi;
6917
6918 /* Do not install the aggregate route if BGP is in the
6919 * process of termination.
6920 */
6921 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6922 || (bgp->peer_self == NULL))
6923 return;
6924
6925 table = bgp->rib[afi][safi];
6926 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6927 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6928 if (pi->peer == bgp->peer_self
6929 && ((pi->type == ZEBRA_ROUTE_BGP
6930 && pi->sub_type == BGP_ROUTE_STATIC)
6931 || (pi->type != ZEBRA_ROUTE_BGP
6932 && pi->sub_type
6933 == BGP_ROUTE_REDISTRIBUTE))) {
6934 bgp_aggregate_decrement(
6935 bgp, bgp_dest_get_prefix(dest), pi, afi,
6936 safi);
6937 bgp_unlink_nexthop(pi);
6938 bgp_path_info_delete(dest, pi);
6939 bgp_process(bgp, dest, afi, safi);
6940 }
6941 }
6942 }
6943 }
6944
6945 /*
6946 * Purge all networks and redistributed routes from routing table.
6947 * Invoked upon the instance going down.
6948 */
6949 void bgp_purge_static_redist_routes(struct bgp *bgp)
6950 {
6951 afi_t afi;
6952 safi_t safi;
6953
6954 FOREACH_AFI_SAFI (afi, safi)
6955 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6956 }
6957
6958 /*
6959 * gpz 110624
6960 * Currently this is used to set static routes for VPN and ENCAP.
6961 * I think it can probably be factored with bgp_static_set.
6962 */
6963 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6964 const char *ip_str, const char *rd_str,
6965 const char *label_str, const char *rmap_str,
6966 int evpn_type, const char *esi, const char *gwip,
6967 const char *ethtag, const char *routermac)
6968 {
6969 VTY_DECLVAR_CONTEXT(bgp, bgp);
6970 int ret;
6971 struct prefix p;
6972 struct prefix_rd prd;
6973 struct bgp_dest *pdest;
6974 struct bgp_dest *dest;
6975 struct bgp_table *table;
6976 struct bgp_static *bgp_static;
6977 mpls_label_t label = MPLS_INVALID_LABEL;
6978 struct prefix gw_ip;
6979
6980 /* validate ip prefix */
6981 ret = str2prefix(ip_str, &p);
6982 if (!ret) {
6983 vty_out(vty, "%% Malformed prefix\n");
6984 return CMD_WARNING_CONFIG_FAILED;
6985 }
6986 apply_mask(&p);
6987 if ((afi == AFI_L2VPN)
6988 && (bgp_build_evpn_prefix(evpn_type,
6989 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6990 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6991 return CMD_WARNING_CONFIG_FAILED;
6992 }
6993
6994 ret = str2prefix_rd(rd_str, &prd);
6995 if (!ret) {
6996 vty_out(vty, "%% Malformed rd\n");
6997 return CMD_WARNING_CONFIG_FAILED;
6998 }
6999
7000 if (label_str) {
7001 unsigned long label_val;
7002 label_val = strtoul(label_str, NULL, 10);
7003 encode_label(label_val, &label);
7004 }
7005
7006 if (safi == SAFI_EVPN) {
7007 if (esi && str2esi(esi, NULL) == 0) {
7008 vty_out(vty, "%% Malformed ESI\n");
7009 return CMD_WARNING_CONFIG_FAILED;
7010 }
7011 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
7012 vty_out(vty, "%% Malformed Router MAC\n");
7013 return CMD_WARNING_CONFIG_FAILED;
7014 }
7015 if (gwip) {
7016 memset(&gw_ip, 0, sizeof(gw_ip));
7017 ret = str2prefix(gwip, &gw_ip);
7018 if (!ret) {
7019 vty_out(vty, "%% Malformed GatewayIp\n");
7020 return CMD_WARNING_CONFIG_FAILED;
7021 }
7022 if ((gw_ip.family == AF_INET
7023 && is_evpn_prefix_ipaddr_v6(
7024 (struct prefix_evpn *)&p))
7025 || (gw_ip.family == AF_INET6
7026 && is_evpn_prefix_ipaddr_v4(
7027 (struct prefix_evpn *)&p))) {
7028 vty_out(vty,
7029 "%% GatewayIp family differs with IP prefix\n");
7030 return CMD_WARNING_CONFIG_FAILED;
7031 }
7032 }
7033 }
7034 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7035 if (!bgp_dest_has_bgp_path_info_data(pdest))
7036 bgp_dest_set_bgp_table_info(pdest,
7037 bgp_table_init(bgp, afi, safi));
7038 table = bgp_dest_get_bgp_table_info(pdest);
7039
7040 dest = bgp_node_get(table, &p);
7041
7042 if (bgp_dest_has_bgp_path_info_data(dest)) {
7043 vty_out(vty, "%% Same network configuration exists\n");
7044 bgp_dest_unlock_node(dest);
7045 } else {
7046 /* New configuration. */
7047 bgp_static = bgp_static_new();
7048 bgp_static->backdoor = 0;
7049 bgp_static->valid = 0;
7050 bgp_static->igpmetric = 0;
7051 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7052 bgp_static->label = label;
7053 bgp_static->prd = prd;
7054
7055 if (rmap_str) {
7056 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7057 route_map_counter_decrement(bgp_static->rmap.map);
7058 bgp_static->rmap.name =
7059 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7060 bgp_static->rmap.map =
7061 route_map_lookup_by_name(rmap_str);
7062 route_map_counter_increment(bgp_static->rmap.map);
7063 }
7064
7065 if (safi == SAFI_EVPN) {
7066 if (esi) {
7067 bgp_static->eth_s_id =
7068 XCALLOC(MTYPE_ATTR,
7069 sizeof(esi_t));
7070 str2esi(esi, bgp_static->eth_s_id);
7071 }
7072 if (routermac) {
7073 bgp_static->router_mac =
7074 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7075 (void)prefix_str2mac(routermac,
7076 bgp_static->router_mac);
7077 }
7078 if (gwip)
7079 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7080 }
7081 bgp_dest_set_bgp_static_info(dest, bgp_static);
7082
7083 bgp_static->valid = 1;
7084 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7085 }
7086
7087 return CMD_SUCCESS;
7088 }
7089
7090 /* Configure static BGP network. */
7091 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7092 const char *ip_str, const char *rd_str,
7093 const char *label_str, int evpn_type, const char *esi,
7094 const char *gwip, const char *ethtag)
7095 {
7096 VTY_DECLVAR_CONTEXT(bgp, bgp);
7097 int ret;
7098 struct prefix p;
7099 struct prefix_rd prd;
7100 struct bgp_dest *pdest;
7101 struct bgp_dest *dest;
7102 struct bgp_table *table;
7103 struct bgp_static *bgp_static;
7104 mpls_label_t label = MPLS_INVALID_LABEL;
7105
7106 /* Convert IP prefix string to struct prefix. */
7107 ret = str2prefix(ip_str, &p);
7108 if (!ret) {
7109 vty_out(vty, "%% Malformed prefix\n");
7110 return CMD_WARNING_CONFIG_FAILED;
7111 }
7112 apply_mask(&p);
7113 if ((afi == AFI_L2VPN)
7114 && (bgp_build_evpn_prefix(evpn_type,
7115 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7116 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7117 return CMD_WARNING_CONFIG_FAILED;
7118 }
7119 ret = str2prefix_rd(rd_str, &prd);
7120 if (!ret) {
7121 vty_out(vty, "%% Malformed rd\n");
7122 return CMD_WARNING_CONFIG_FAILED;
7123 }
7124
7125 if (label_str) {
7126 unsigned long label_val;
7127 label_val = strtoul(label_str, NULL, 10);
7128 encode_label(label_val, &label);
7129 }
7130
7131 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7132 if (!bgp_dest_has_bgp_path_info_data(pdest))
7133 bgp_dest_set_bgp_table_info(pdest,
7134 bgp_table_init(bgp, afi, safi));
7135 else
7136 bgp_dest_unlock_node(pdest);
7137 table = bgp_dest_get_bgp_table_info(pdest);
7138
7139 dest = bgp_node_lookup(table, &p);
7140
7141 if (dest) {
7142 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7143
7144 bgp_static = bgp_dest_get_bgp_static_info(dest);
7145 bgp_static_free(bgp_static);
7146 bgp_dest_set_bgp_static_info(dest, NULL);
7147 bgp_dest_unlock_node(dest);
7148 bgp_dest_unlock_node(dest);
7149 } else
7150 vty_out(vty, "%% Can't find the route\n");
7151
7152 return CMD_SUCCESS;
7153 }
7154
7155 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7156 const char *rmap_name)
7157 {
7158 VTY_DECLVAR_CONTEXT(bgp, bgp);
7159 struct bgp_rmap *rmap;
7160
7161 rmap = &bgp->table_map[afi][safi];
7162 if (rmap_name) {
7163 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7164 route_map_counter_decrement(rmap->map);
7165 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7166 rmap->map = route_map_lookup_by_name(rmap_name);
7167 route_map_counter_increment(rmap->map);
7168 } else {
7169 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7170 route_map_counter_decrement(rmap->map);
7171 rmap->map = NULL;
7172 }
7173
7174 if (bgp_fibupd_safi(safi))
7175 bgp_zebra_announce_table(bgp, afi, safi);
7176
7177 return CMD_SUCCESS;
7178 }
7179
7180 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7181 const char *rmap_name)
7182 {
7183 VTY_DECLVAR_CONTEXT(bgp, bgp);
7184 struct bgp_rmap *rmap;
7185
7186 rmap = &bgp->table_map[afi][safi];
7187 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7188 route_map_counter_decrement(rmap->map);
7189 rmap->map = NULL;
7190
7191 if (bgp_fibupd_safi(safi))
7192 bgp_zebra_announce_table(bgp, afi, safi);
7193
7194 return CMD_SUCCESS;
7195 }
7196
7197 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7198 safi_t safi)
7199 {
7200 if (bgp->table_map[afi][safi].name) {
7201 vty_out(vty, " table-map %s\n",
7202 bgp->table_map[afi][safi].name);
7203 }
7204 }
7205
7206 DEFUN (bgp_table_map,
7207 bgp_table_map_cmd,
7208 "table-map WORD",
7209 "BGP table to RIB route download filter\n"
7210 "Name of the route map\n")
7211 {
7212 int idx_word = 1;
7213 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7214 argv[idx_word]->arg);
7215 }
7216 DEFUN (no_bgp_table_map,
7217 no_bgp_table_map_cmd,
7218 "no table-map WORD",
7219 NO_STR
7220 "BGP table to RIB route download filter\n"
7221 "Name of the route map\n")
7222 {
7223 int idx_word = 2;
7224 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7225 argv[idx_word]->arg);
7226 }
7227
7228 DEFPY(bgp_network,
7229 bgp_network_cmd,
7230 "[no] network \
7231 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7232 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7233 backdoor$backdoor}]",
7234 NO_STR
7235 "Specify a network to announce via BGP\n"
7236 "IPv4 prefix\n"
7237 "Network number\n"
7238 "Network mask\n"
7239 "Network mask\n"
7240 "Route-map to modify the attributes\n"
7241 "Name of the route map\n"
7242 "Label index to associate with the prefix\n"
7243 "Label index value\n"
7244 "Specify a BGP backdoor route\n")
7245 {
7246 char addr_prefix_str[BUFSIZ];
7247
7248 if (address_str) {
7249 int ret;
7250
7251 ret = netmask_str2prefix_str(address_str, netmask_str,
7252 addr_prefix_str,
7253 sizeof(addr_prefix_str));
7254 if (!ret) {
7255 vty_out(vty, "%% Inconsistent address and mask\n");
7256 return CMD_WARNING_CONFIG_FAILED;
7257 }
7258 }
7259
7260 return bgp_static_set(
7261 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7262 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7263 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7264 }
7265
7266 DEFPY(ipv6_bgp_network,
7267 ipv6_bgp_network_cmd,
7268 "[no] network X:X::X:X/M$prefix \
7269 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7270 NO_STR
7271 "Specify a network to announce via BGP\n"
7272 "IPv6 prefix\n"
7273 "Route-map to modify the attributes\n"
7274 "Name of the route map\n"
7275 "Label index to associate with the prefix\n"
7276 "Label index value\n")
7277 {
7278 return bgp_static_set(
7279 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7280 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7281 }
7282
7283 static struct bgp_aggregate *bgp_aggregate_new(void)
7284 {
7285 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7286 }
7287
7288 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7289 {
7290 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7291 route_map_counter_decrement(aggregate->suppress_map);
7292 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7293 route_map_counter_decrement(aggregate->rmap.map);
7294 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7295 }
7296
7297 /**
7298 * Helper function to avoid repeated code: prepare variables for a
7299 * `route_map_apply` call.
7300 *
7301 * \returns `true` on route map match, otherwise `false`.
7302 */
7303 static bool aggr_suppress_map_test(struct bgp *bgp,
7304 struct bgp_aggregate *aggregate,
7305 struct bgp_path_info *pi)
7306 {
7307 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7308 route_map_result_t rmr = RMAP_DENYMATCH;
7309 struct bgp_path_info rmap_path = {};
7310 struct attr attr = {};
7311
7312 /* No route map entries created, just don't match. */
7313 if (aggregate->suppress_map == NULL)
7314 return false;
7315
7316 /* Call route map matching and return result. */
7317 attr.aspath = aspath_empty();
7318 rmap_path.peer = bgp->peer_self;
7319 rmap_path.attr = &attr;
7320
7321 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7322 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7323 bgp->peer_self->rmap_type = 0;
7324
7325 bgp_attr_flush(&attr);
7326 aspath_unintern(&attr.aspath);
7327
7328 return rmr == RMAP_PERMITMATCH;
7329 }
7330
7331 /** Test whether the aggregation has suppressed this path or not. */
7332 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7333 struct bgp_path_info *pi)
7334 {
7335 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7336 return false;
7337
7338 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7339 }
7340
7341 /**
7342 * Suppress this path and keep the reference.
7343 *
7344 * \returns `true` if needs processing otherwise `false`.
7345 */
7346 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7347 struct bgp_path_info *pi)
7348 {
7349 struct bgp_path_info_extra *pie;
7350
7351 /* Path is already suppressed by this aggregation. */
7352 if (aggr_suppress_exists(aggregate, pi))
7353 return false;
7354
7355 pie = bgp_path_info_extra_get(pi);
7356
7357 /* This is the first suppression, allocate memory and list it. */
7358 if (pie->aggr_suppressors == NULL)
7359 pie->aggr_suppressors = list_new();
7360
7361 listnode_add(pie->aggr_suppressors, aggregate);
7362
7363 /* Only mark for processing if suppressed. */
7364 if (listcount(pie->aggr_suppressors) == 1) {
7365 if (BGP_DEBUG(update, UPDATE_OUT))
7366 zlog_debug("aggregate-address suppressing: %pFX",
7367 bgp_dest_get_prefix(pi->net));
7368
7369 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7370 return true;
7371 }
7372
7373 return false;
7374 }
7375
7376 /**
7377 * Unsuppress this path and remove the reference.
7378 *
7379 * \returns `true` if needs processing otherwise `false`.
7380 */
7381 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7382 struct bgp_path_info *pi)
7383 {
7384 /* Path wasn't suppressed. */
7385 if (!aggr_suppress_exists(aggregate, pi))
7386 return false;
7387
7388 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7389
7390 /* Unsuppress and free extra memory if last item. */
7391 if (listcount(pi->extra->aggr_suppressors) == 0) {
7392 if (BGP_DEBUG(update, UPDATE_OUT))
7393 zlog_debug("aggregate-address unsuppressing: %pFX",
7394 bgp_dest_get_prefix(pi->net));
7395
7396 list_delete(&pi->extra->aggr_suppressors);
7397 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7398 return true;
7399 }
7400
7401 return false;
7402 }
7403
7404 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7405 struct aspath *aspath,
7406 struct community *comm,
7407 struct ecommunity *ecomm,
7408 struct lcommunity *lcomm)
7409 {
7410 static struct aspath *ae = NULL;
7411
7412 if (!ae)
7413 ae = aspath_empty();
7414
7415 if (!pi)
7416 return false;
7417
7418 if (origin != pi->attr->origin)
7419 return false;
7420
7421 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7422 return false;
7423
7424 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7425 return false;
7426
7427 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7428 return false;
7429
7430 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7431 return false;
7432
7433 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7434 return false;
7435
7436 return true;
7437 }
7438
7439 static void bgp_aggregate_install(
7440 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7441 uint8_t origin, struct aspath *aspath, struct community *community,
7442 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7443 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7444 {
7445 struct bgp_dest *dest;
7446 struct bgp_table *table;
7447 struct bgp_path_info *pi, *orig, *new;
7448 struct attr *attr;
7449
7450 table = bgp->rib[afi][safi];
7451
7452 dest = bgp_node_get(table, p);
7453
7454 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7455 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7456 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7457 break;
7458
7459 /*
7460 * If we have paths with different MEDs, then don't install
7461 * (or uninstall) the aggregate route.
7462 */
7463 if (aggregate->match_med && aggregate->med_mismatched)
7464 goto uninstall_aggregate_route;
7465
7466 if (aggregate->count > 0) {
7467 /*
7468 * If the aggregate information has not changed
7469 * no need to re-install it again.
7470 */
7471 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7472 ecommunity, lcommunity)) {
7473 bgp_dest_unlock_node(dest);
7474
7475 if (aspath)
7476 aspath_free(aspath);
7477 if (community)
7478 community_free(&community);
7479 if (ecommunity)
7480 ecommunity_free(&ecommunity);
7481 if (lcommunity)
7482 lcommunity_free(&lcommunity);
7483
7484 return;
7485 }
7486
7487 /*
7488 * Mark the old as unusable
7489 */
7490 if (pi)
7491 bgp_path_info_delete(dest, pi);
7492
7493 attr = bgp_attr_aggregate_intern(
7494 bgp, origin, aspath, community, ecommunity, lcommunity,
7495 aggregate, atomic_aggregate, p);
7496
7497 if (!attr) {
7498 bgp_dest_unlock_node(dest);
7499 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7500 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7501 zlog_debug("%s: %pFX null attribute", __func__,
7502 p);
7503 return;
7504 }
7505
7506 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7507 bgp->peer_self, attr, dest);
7508
7509 SET_FLAG(new->flags, BGP_PATH_VALID);
7510
7511 bgp_path_info_add(dest, new);
7512 bgp_process(bgp, dest, afi, safi);
7513 } else {
7514 uninstall_aggregate_route:
7515 for (pi = orig; pi; pi = pi->next)
7516 if (pi->peer == bgp->peer_self
7517 && pi->type == ZEBRA_ROUTE_BGP
7518 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7519 break;
7520
7521 /* Withdraw static BGP route from routing table. */
7522 if (pi) {
7523 bgp_path_info_delete(dest, pi);
7524 bgp_process(bgp, dest, afi, safi);
7525 }
7526 }
7527
7528 bgp_dest_unlock_node(dest);
7529 }
7530
7531 /**
7532 * Check if the current path has different MED than other known paths.
7533 *
7534 * \returns `true` if the MED matched the others else `false`.
7535 */
7536 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7537 struct bgp *bgp, struct bgp_path_info *pi)
7538 {
7539 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7540
7541 /* This is the first route being analyzed. */
7542 if (!aggregate->med_initialized) {
7543 aggregate->med_initialized = true;
7544 aggregate->med_mismatched = false;
7545 aggregate->med_matched_value = cur_med;
7546 } else {
7547 /* Check if routes with different MED showed up. */
7548 if (cur_med != aggregate->med_matched_value)
7549 aggregate->med_mismatched = true;
7550 }
7551
7552 return !aggregate->med_mismatched;
7553 }
7554
7555 /**
7556 * Initializes and tests all routes in the aggregate address path for MED
7557 * values.
7558 *
7559 * \returns `true` if all MEDs are the same otherwise `false`.
7560 */
7561 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7562 struct bgp *bgp, const struct prefix *p,
7563 afi_t afi, safi_t safi)
7564 {
7565 struct bgp_table *table = bgp->rib[afi][safi];
7566 const struct prefix *dest_p;
7567 struct bgp_dest *dest, *top;
7568 struct bgp_path_info *pi;
7569 bool med_matched = true;
7570
7571 aggregate->med_initialized = false;
7572
7573 top = bgp_node_get(table, p);
7574 for (dest = bgp_node_get(table, p); dest;
7575 dest = bgp_route_next_until(dest, top)) {
7576 dest_p = bgp_dest_get_prefix(dest);
7577 if (dest_p->prefixlen <= p->prefixlen)
7578 continue;
7579
7580 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7581 if (BGP_PATH_HOLDDOWN(pi))
7582 continue;
7583 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7584 continue;
7585 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7586 med_matched = false;
7587 break;
7588 }
7589 }
7590 if (!med_matched)
7591 break;
7592 }
7593 bgp_dest_unlock_node(top);
7594
7595 return med_matched;
7596 }
7597
7598 /**
7599 * Toggles the route suppression status for this aggregate address
7600 * configuration.
7601 */
7602 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7603 struct bgp *bgp, const struct prefix *p,
7604 afi_t afi, safi_t safi, bool suppress)
7605 {
7606 struct bgp_table *table = bgp->rib[afi][safi];
7607 const struct prefix *dest_p;
7608 struct bgp_dest *dest, *top;
7609 struct bgp_path_info *pi;
7610 bool toggle_suppression;
7611
7612 /* We've found a different MED we must revert any suppressed routes. */
7613 top = bgp_node_get(table, p);
7614 for (dest = bgp_node_get(table, p); dest;
7615 dest = bgp_route_next_until(dest, top)) {
7616 dest_p = bgp_dest_get_prefix(dest);
7617 if (dest_p->prefixlen <= p->prefixlen)
7618 continue;
7619
7620 toggle_suppression = false;
7621 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7622 if (BGP_PATH_HOLDDOWN(pi))
7623 continue;
7624 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7625 continue;
7626
7627 /* We are toggling suppression back. */
7628 if (suppress) {
7629 /* Suppress route if not suppressed already. */
7630 if (aggr_suppress_path(aggregate, pi))
7631 toggle_suppression = true;
7632 continue;
7633 }
7634
7635 /* Install route if there is no more suppression. */
7636 if (aggr_unsuppress_path(aggregate, pi))
7637 toggle_suppression = true;
7638 }
7639
7640 if (toggle_suppression)
7641 bgp_process(bgp, dest, afi, safi);
7642 }
7643 bgp_dest_unlock_node(top);
7644 }
7645
7646 /**
7647 * Aggregate address MED matching incremental test: this function is called
7648 * when the initial aggregation occurred and we are only testing a single
7649 * new path.
7650 *
7651 * In addition to testing and setting the MED validity it also installs back
7652 * suppressed routes (if summary is configured).
7653 *
7654 * Must not be called in `bgp_aggregate_route`.
7655 */
7656 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7657 struct bgp *bgp, const struct prefix *p,
7658 afi_t afi, safi_t safi,
7659 struct bgp_path_info *pi)
7660 {
7661 /* MED matching disabled. */
7662 if (!aggregate->match_med)
7663 return;
7664
7665 /* Aggregation with different MED, recheck if we have got equal MEDs
7666 * now.
7667 */
7668 if (aggregate->med_mismatched &&
7669 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7670 aggregate->summary_only)
7671 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7672 true);
7673 else
7674 bgp_aggregate_med_match(aggregate, bgp, pi);
7675
7676 /* No mismatches, just quit. */
7677 if (!aggregate->med_mismatched)
7678 return;
7679
7680 /* Route summarization is disabled. */
7681 if (!aggregate->summary_only)
7682 return;
7683
7684 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7685 }
7686
7687 /* Update an aggregate as routes are added/removed from the BGP table */
7688 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7689 safi_t safi, struct bgp_aggregate *aggregate)
7690 {
7691 struct bgp_table *table;
7692 struct bgp_dest *top;
7693 struct bgp_dest *dest;
7694 uint8_t origin;
7695 struct aspath *aspath = NULL;
7696 struct community *community = NULL;
7697 struct ecommunity *ecommunity = NULL;
7698 struct lcommunity *lcommunity = NULL;
7699 struct bgp_path_info *pi;
7700 unsigned long match = 0;
7701 uint8_t atomic_aggregate = 0;
7702
7703 /* If the bgp instance is being deleted or self peer is deleted
7704 * then do not create aggregate route
7705 */
7706 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7707 || (bgp->peer_self == NULL))
7708 return;
7709
7710 /* Initialize and test routes for MED difference. */
7711 if (aggregate->match_med)
7712 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7713
7714 /*
7715 * Reset aggregate count: we might've been called from route map
7716 * update so in that case we must retest all more specific routes.
7717 *
7718 * \see `bgp_route_map_process_update`.
7719 */
7720 aggregate->count = 0;
7721 aggregate->incomplete_origin_count = 0;
7722 aggregate->incomplete_origin_count = 0;
7723 aggregate->egp_origin_count = 0;
7724
7725 /* ORIGIN attribute: If at least one route among routes that are
7726 aggregated has ORIGIN with the value INCOMPLETE, then the
7727 aggregated route must have the ORIGIN attribute with the value
7728 INCOMPLETE. Otherwise, if at least one route among routes that
7729 are aggregated has ORIGIN with the value EGP, then the aggregated
7730 route must have the origin attribute with the value EGP. In all
7731 other case the value of the ORIGIN attribute of the aggregated
7732 route is INTERNAL. */
7733 origin = BGP_ORIGIN_IGP;
7734
7735 table = bgp->rib[afi][safi];
7736
7737 top = bgp_node_get(table, p);
7738 for (dest = bgp_node_get(table, p); dest;
7739 dest = bgp_route_next_until(dest, top)) {
7740 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7741
7742 if (dest_p->prefixlen <= p->prefixlen)
7743 continue;
7744
7745 /* If suppress fib is enabled and route not installed
7746 * in FIB, skip the route
7747 */
7748 if (!bgp_check_advertise(bgp, dest))
7749 continue;
7750
7751 match = 0;
7752
7753 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7754 if (BGP_PATH_HOLDDOWN(pi))
7755 continue;
7756
7757 if (pi->attr->flag
7758 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7759 atomic_aggregate = 1;
7760
7761 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7762 continue;
7763
7764 /*
7765 * summary-only aggregate route suppress
7766 * aggregated route announcements.
7767 *
7768 * MED matching:
7769 * Don't create summaries if MED didn't match
7770 * otherwise neither the specific routes and the
7771 * aggregation will be announced.
7772 */
7773 if (aggregate->summary_only
7774 && AGGREGATE_MED_VALID(aggregate)) {
7775 if (aggr_suppress_path(aggregate, pi))
7776 match++;
7777 }
7778
7779 /*
7780 * Suppress more specific routes that match the route
7781 * map results.
7782 *
7783 * MED matching:
7784 * Don't suppress routes if MED matching is enabled and
7785 * it mismatched otherwise we might end up with no
7786 * routes for this path.
7787 */
7788 if (aggregate->suppress_map_name
7789 && AGGREGATE_MED_VALID(aggregate)
7790 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7791 if (aggr_suppress_path(aggregate, pi))
7792 match++;
7793 }
7794
7795 aggregate->count++;
7796
7797 /*
7798 * If at least one route among routes that are
7799 * aggregated has ORIGIN with the value INCOMPLETE,
7800 * then the aggregated route MUST have the ORIGIN
7801 * attribute with the value INCOMPLETE. Otherwise, if
7802 * at least one route among routes that are aggregated
7803 * has ORIGIN with the value EGP, then the aggregated
7804 * route MUST have the ORIGIN attribute with the value
7805 * EGP.
7806 */
7807 switch (pi->attr->origin) {
7808 case BGP_ORIGIN_INCOMPLETE:
7809 aggregate->incomplete_origin_count++;
7810 break;
7811 case BGP_ORIGIN_EGP:
7812 aggregate->egp_origin_count++;
7813 break;
7814 default:
7815 /*Do nothing.
7816 */
7817 break;
7818 }
7819
7820 if (!aggregate->as_set)
7821 continue;
7822
7823 /*
7824 * as-set aggregate route generate origin, as path,
7825 * and community aggregation.
7826 */
7827 /* Compute aggregate route's as-path.
7828 */
7829 bgp_compute_aggregate_aspath_hash(aggregate,
7830 pi->attr->aspath);
7831
7832 /* Compute aggregate route's community.
7833 */
7834 if (bgp_attr_get_community(pi->attr))
7835 bgp_compute_aggregate_community_hash(
7836 aggregate,
7837 bgp_attr_get_community(pi->attr));
7838
7839 /* Compute aggregate route's extended community.
7840 */
7841 if (bgp_attr_get_ecommunity(pi->attr))
7842 bgp_compute_aggregate_ecommunity_hash(
7843 aggregate,
7844 bgp_attr_get_ecommunity(pi->attr));
7845
7846 /* Compute aggregate route's large community.
7847 */
7848 if (bgp_attr_get_lcommunity(pi->attr))
7849 bgp_compute_aggregate_lcommunity_hash(
7850 aggregate,
7851 bgp_attr_get_lcommunity(pi->attr));
7852 }
7853 if (match)
7854 bgp_process(bgp, dest, afi, safi);
7855 }
7856 if (aggregate->as_set) {
7857 bgp_compute_aggregate_aspath_val(aggregate);
7858 bgp_compute_aggregate_community_val(aggregate);
7859 bgp_compute_aggregate_ecommunity_val(aggregate);
7860 bgp_compute_aggregate_lcommunity_val(aggregate);
7861 }
7862
7863
7864 bgp_dest_unlock_node(top);
7865
7866
7867 if (aggregate->incomplete_origin_count > 0)
7868 origin = BGP_ORIGIN_INCOMPLETE;
7869 else if (aggregate->egp_origin_count > 0)
7870 origin = BGP_ORIGIN_EGP;
7871
7872 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7873 origin = aggregate->origin;
7874
7875 if (aggregate->as_set) {
7876 if (aggregate->aspath)
7877 /* Retrieve aggregate route's as-path.
7878 */
7879 aspath = aspath_dup(aggregate->aspath);
7880
7881 if (aggregate->community)
7882 /* Retrieve aggregate route's community.
7883 */
7884 community = community_dup(aggregate->community);
7885
7886 if (aggregate->ecommunity)
7887 /* Retrieve aggregate route's ecommunity.
7888 */
7889 ecommunity = ecommunity_dup(aggregate->ecommunity);
7890
7891 if (aggregate->lcommunity)
7892 /* Retrieve aggregate route's lcommunity.
7893 */
7894 lcommunity = lcommunity_dup(aggregate->lcommunity);
7895 }
7896
7897 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7898 ecommunity, lcommunity, atomic_aggregate,
7899 aggregate);
7900 }
7901
7902 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7903 safi_t safi, struct bgp_aggregate *aggregate)
7904 {
7905 struct bgp_table *table;
7906 struct bgp_dest *top;
7907 struct bgp_dest *dest;
7908 struct bgp_path_info *pi;
7909 unsigned long match;
7910
7911 table = bgp->rib[afi][safi];
7912
7913 /* If routes exists below this node, generate aggregate routes. */
7914 top = bgp_node_get(table, p);
7915 for (dest = bgp_node_get(table, p); dest;
7916 dest = bgp_route_next_until(dest, top)) {
7917 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7918
7919 if (dest_p->prefixlen <= p->prefixlen)
7920 continue;
7921 match = 0;
7922
7923 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7924 if (BGP_PATH_HOLDDOWN(pi))
7925 continue;
7926
7927 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7928 continue;
7929
7930 /*
7931 * This route is suppressed: attempt to unsuppress it.
7932 *
7933 * `aggr_unsuppress_path` will fail if this particular
7934 * aggregate route was not the suppressor.
7935 */
7936 if (pi->extra && pi->extra->aggr_suppressors &&
7937 listcount(pi->extra->aggr_suppressors)) {
7938 if (aggr_unsuppress_path(aggregate, pi))
7939 match++;
7940 }
7941
7942 aggregate->count--;
7943
7944 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7945 aggregate->incomplete_origin_count--;
7946 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7947 aggregate->egp_origin_count--;
7948
7949 if (aggregate->as_set) {
7950 /* Remove as-path from aggregate.
7951 */
7952 bgp_remove_aspath_from_aggregate_hash(
7953 aggregate,
7954 pi->attr->aspath);
7955
7956 if (bgp_attr_get_community(pi->attr))
7957 /* Remove community from aggregate.
7958 */
7959 bgp_remove_comm_from_aggregate_hash(
7960 aggregate,
7961 bgp_attr_get_community(
7962 pi->attr));
7963
7964 if (bgp_attr_get_ecommunity(pi->attr))
7965 /* Remove ecommunity from aggregate.
7966 */
7967 bgp_remove_ecomm_from_aggregate_hash(
7968 aggregate,
7969 bgp_attr_get_ecommunity(
7970 pi->attr));
7971
7972 if (bgp_attr_get_lcommunity(pi->attr))
7973 /* Remove lcommunity from aggregate.
7974 */
7975 bgp_remove_lcomm_from_aggregate_hash(
7976 aggregate,
7977 bgp_attr_get_lcommunity(
7978 pi->attr));
7979 }
7980 }
7981
7982 /* If this node was suppressed, process the change. */
7983 if (match)
7984 bgp_process(bgp, dest, afi, safi);
7985 }
7986 if (aggregate->as_set) {
7987 aspath_free(aggregate->aspath);
7988 aggregate->aspath = NULL;
7989 if (aggregate->community)
7990 community_free(&aggregate->community);
7991 if (aggregate->ecommunity)
7992 ecommunity_free(&aggregate->ecommunity);
7993 if (aggregate->lcommunity)
7994 lcommunity_free(&aggregate->lcommunity);
7995 }
7996
7997 bgp_dest_unlock_node(top);
7998 }
7999
8000 static void bgp_add_route_to_aggregate(struct bgp *bgp,
8001 const struct prefix *aggr_p,
8002 struct bgp_path_info *pinew, afi_t afi,
8003 safi_t safi,
8004 struct bgp_aggregate *aggregate)
8005 {
8006 uint8_t origin;
8007 struct aspath *aspath = NULL;
8008 uint8_t atomic_aggregate = 0;
8009 struct community *community = NULL;
8010 struct ecommunity *ecommunity = NULL;
8011 struct lcommunity *lcommunity = NULL;
8012
8013 /* If the bgp instance is being deleted or self peer is deleted
8014 * then do not create aggregate route
8015 */
8016 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8017 || (bgp->peer_self == NULL))
8018 return;
8019
8020 /* ORIGIN attribute: If at least one route among routes that are
8021 * aggregated has ORIGIN with the value INCOMPLETE, then the
8022 * aggregated route must have the ORIGIN attribute with the value
8023 * INCOMPLETE. Otherwise, if at least one route among routes that
8024 * are aggregated has ORIGIN with the value EGP, then the aggregated
8025 * route must have the origin attribute with the value EGP. In all
8026 * other case the value of the ORIGIN attribute of the aggregated
8027 * route is INTERNAL.
8028 */
8029 origin = BGP_ORIGIN_IGP;
8030
8031 aggregate->count++;
8032
8033 /*
8034 * This must be called before `summary` check to avoid
8035 * "suppressing" twice.
8036 */
8037 if (aggregate->match_med)
8038 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8039 pinew);
8040
8041 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8042 aggr_suppress_path(aggregate, pinew);
8043
8044 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8045 && aggr_suppress_map_test(bgp, aggregate, pinew))
8046 aggr_suppress_path(aggregate, pinew);
8047
8048 switch (pinew->attr->origin) {
8049 case BGP_ORIGIN_INCOMPLETE:
8050 aggregate->incomplete_origin_count++;
8051 break;
8052 case BGP_ORIGIN_EGP:
8053 aggregate->egp_origin_count++;
8054 break;
8055 default:
8056 /* Do nothing.
8057 */
8058 break;
8059 }
8060
8061 if (aggregate->incomplete_origin_count > 0)
8062 origin = BGP_ORIGIN_INCOMPLETE;
8063 else if (aggregate->egp_origin_count > 0)
8064 origin = BGP_ORIGIN_EGP;
8065
8066 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8067 origin = aggregate->origin;
8068
8069 if (aggregate->as_set) {
8070 /* Compute aggregate route's as-path.
8071 */
8072 bgp_compute_aggregate_aspath(aggregate,
8073 pinew->attr->aspath);
8074
8075 /* Compute aggregate route's community.
8076 */
8077 if (bgp_attr_get_community(pinew->attr))
8078 bgp_compute_aggregate_community(
8079 aggregate, bgp_attr_get_community(pinew->attr));
8080
8081 /* Compute aggregate route's extended community.
8082 */
8083 if (bgp_attr_get_ecommunity(pinew->attr))
8084 bgp_compute_aggregate_ecommunity(
8085 aggregate,
8086 bgp_attr_get_ecommunity(pinew->attr));
8087
8088 /* Compute aggregate route's large community.
8089 */
8090 if (bgp_attr_get_lcommunity(pinew->attr))
8091 bgp_compute_aggregate_lcommunity(
8092 aggregate,
8093 bgp_attr_get_lcommunity(pinew->attr));
8094
8095 /* Retrieve aggregate route's as-path.
8096 */
8097 if (aggregate->aspath)
8098 aspath = aspath_dup(aggregate->aspath);
8099
8100 /* Retrieve aggregate route's community.
8101 */
8102 if (aggregate->community)
8103 community = community_dup(aggregate->community);
8104
8105 /* Retrieve aggregate route's ecommunity.
8106 */
8107 if (aggregate->ecommunity)
8108 ecommunity = ecommunity_dup(aggregate->ecommunity);
8109
8110 /* Retrieve aggregate route's lcommunity.
8111 */
8112 if (aggregate->lcommunity)
8113 lcommunity = lcommunity_dup(aggregate->lcommunity);
8114 }
8115
8116 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8117 aspath, community, ecommunity,
8118 lcommunity, atomic_aggregate, aggregate);
8119 }
8120
8121 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8122 safi_t safi,
8123 struct bgp_path_info *pi,
8124 struct bgp_aggregate *aggregate,
8125 const struct prefix *aggr_p)
8126 {
8127 uint8_t origin;
8128 struct aspath *aspath = NULL;
8129 uint8_t atomic_aggregate = 0;
8130 struct community *community = NULL;
8131 struct ecommunity *ecommunity = NULL;
8132 struct lcommunity *lcommunity = NULL;
8133 unsigned long match = 0;
8134
8135 /* If the bgp instance is being deleted or self peer is deleted
8136 * then do not create aggregate route
8137 */
8138 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8139 || (bgp->peer_self == NULL))
8140 return;
8141
8142 if (BGP_PATH_HOLDDOWN(pi))
8143 return;
8144
8145 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8146 return;
8147
8148 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8149 if (aggr_unsuppress_path(aggregate, pi))
8150 match++;
8151
8152 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8153 && aggr_suppress_map_test(bgp, aggregate, pi))
8154 if (aggr_unsuppress_path(aggregate, pi))
8155 match++;
8156
8157 /*
8158 * This must be called after `summary`, `suppress-map` check to avoid
8159 * "unsuppressing" twice.
8160 */
8161 if (aggregate->match_med)
8162 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8163
8164 if (aggregate->count > 0)
8165 aggregate->count--;
8166
8167 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8168 aggregate->incomplete_origin_count--;
8169 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8170 aggregate->egp_origin_count--;
8171
8172 if (aggregate->as_set) {
8173 /* Remove as-path from aggregate.
8174 */
8175 bgp_remove_aspath_from_aggregate(aggregate,
8176 pi->attr->aspath);
8177
8178 if (bgp_attr_get_community(pi->attr))
8179 /* Remove community from aggregate.
8180 */
8181 bgp_remove_community_from_aggregate(
8182 aggregate, bgp_attr_get_community(pi->attr));
8183
8184 if (bgp_attr_get_ecommunity(pi->attr))
8185 /* Remove ecommunity from aggregate.
8186 */
8187 bgp_remove_ecommunity_from_aggregate(
8188 aggregate, bgp_attr_get_ecommunity(pi->attr));
8189
8190 if (bgp_attr_get_lcommunity(pi->attr))
8191 /* Remove lcommunity from aggregate.
8192 */
8193 bgp_remove_lcommunity_from_aggregate(
8194 aggregate, bgp_attr_get_lcommunity(pi->attr));
8195 }
8196
8197 /* If this node was suppressed, process the change. */
8198 if (match)
8199 bgp_process(bgp, pi->net, afi, safi);
8200
8201 origin = BGP_ORIGIN_IGP;
8202 if (aggregate->incomplete_origin_count > 0)
8203 origin = BGP_ORIGIN_INCOMPLETE;
8204 else if (aggregate->egp_origin_count > 0)
8205 origin = BGP_ORIGIN_EGP;
8206
8207 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8208 origin = aggregate->origin;
8209
8210 if (aggregate->as_set) {
8211 /* Retrieve aggregate route's as-path.
8212 */
8213 if (aggregate->aspath)
8214 aspath = aspath_dup(aggregate->aspath);
8215
8216 /* Retrieve aggregate route's community.
8217 */
8218 if (aggregate->community)
8219 community = community_dup(aggregate->community);
8220
8221 /* Retrieve aggregate route's ecommunity.
8222 */
8223 if (aggregate->ecommunity)
8224 ecommunity = ecommunity_dup(aggregate->ecommunity);
8225
8226 /* Retrieve aggregate route's lcommunity.
8227 */
8228 if (aggregate->lcommunity)
8229 lcommunity = lcommunity_dup(aggregate->lcommunity);
8230 }
8231
8232 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8233 aspath, community, ecommunity,
8234 lcommunity, atomic_aggregate, aggregate);
8235 }
8236
8237 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8238 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8239 {
8240 struct bgp_dest *child;
8241 struct bgp_dest *dest;
8242 struct bgp_aggregate *aggregate;
8243 struct bgp_table *table;
8244
8245 table = bgp->aggregate[afi][safi];
8246
8247 /* No aggregates configured. */
8248 if (bgp_table_top_nolock(table) == NULL)
8249 return;
8250
8251 if (p->prefixlen == 0)
8252 return;
8253
8254 if (BGP_PATH_HOLDDOWN(pi))
8255 return;
8256
8257 /* If suppress fib is enabled and route not installed
8258 * in FIB, do not update the aggregate route
8259 */
8260 if (!bgp_check_advertise(bgp, pi->net))
8261 return;
8262
8263 child = bgp_node_get(table, p);
8264
8265 /* Aggregate address configuration check. */
8266 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8267 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8268
8269 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8270 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8271 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8272 aggregate);
8273 }
8274 }
8275 bgp_dest_unlock_node(child);
8276 }
8277
8278 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8279 struct bgp_path_info *del, afi_t afi, safi_t safi)
8280 {
8281 struct bgp_dest *child;
8282 struct bgp_dest *dest;
8283 struct bgp_aggregate *aggregate;
8284 struct bgp_table *table;
8285
8286 table = bgp->aggregate[afi][safi];
8287
8288 /* No aggregates configured. */
8289 if (bgp_table_top_nolock(table) == NULL)
8290 return;
8291
8292 if (p->prefixlen == 0)
8293 return;
8294
8295 child = bgp_node_get(table, p);
8296
8297 /* Aggregate address configuration check. */
8298 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8299 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8300
8301 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8302 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8303 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8304 aggregate, dest_p);
8305 }
8306 }
8307 bgp_dest_unlock_node(child);
8308 }
8309
8310 /* Aggregate route attribute. */
8311 #define AGGREGATE_SUMMARY_ONLY 1
8312 #define AGGREGATE_AS_SET 1
8313 #define AGGREGATE_AS_UNSET 0
8314
8315 static const char *bgp_origin2str(uint8_t origin)
8316 {
8317 switch (origin) {
8318 case BGP_ORIGIN_IGP:
8319 return "igp";
8320 case BGP_ORIGIN_EGP:
8321 return "egp";
8322 case BGP_ORIGIN_INCOMPLETE:
8323 return "incomplete";
8324 }
8325 return "n/a";
8326 }
8327
8328 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8329 {
8330 switch (v_state) {
8331 case RPKI_NOT_BEING_USED:
8332 return "not used";
8333 case RPKI_VALID:
8334 return "valid";
8335 case RPKI_NOTFOUND:
8336 return "not found";
8337 case RPKI_INVALID:
8338 return "invalid";
8339 }
8340
8341 assert(!"We should never get here this is a dev escape");
8342 return "ERROR";
8343 }
8344
8345 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8346 afi_t afi, safi_t safi)
8347 {
8348 VTY_DECLVAR_CONTEXT(bgp, bgp);
8349 int ret;
8350 struct prefix p;
8351 struct bgp_dest *dest;
8352 struct bgp_aggregate *aggregate;
8353
8354 /* Convert string to prefix structure. */
8355 ret = str2prefix(prefix_str, &p);
8356 if (!ret) {
8357 vty_out(vty, "Malformed prefix\n");
8358 return CMD_WARNING_CONFIG_FAILED;
8359 }
8360 apply_mask(&p);
8361
8362 /* Old configuration check. */
8363 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8364 if (!dest) {
8365 vty_out(vty,
8366 "%% There is no aggregate-address configuration.\n");
8367 return CMD_WARNING_CONFIG_FAILED;
8368 }
8369
8370 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8371 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8372 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8373 NULL, NULL, 0, aggregate);
8374
8375 /* Unlock aggregate address configuration. */
8376 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8377
8378 if (aggregate->community)
8379 community_free(&aggregate->community);
8380
8381 if (aggregate->community_hash) {
8382 /* Delete all communities in the hash.
8383 */
8384 hash_clean(aggregate->community_hash,
8385 bgp_aggr_community_remove);
8386 /* Free up the community_hash.
8387 */
8388 hash_free(aggregate->community_hash);
8389 }
8390
8391 if (aggregate->ecommunity)
8392 ecommunity_free(&aggregate->ecommunity);
8393
8394 if (aggregate->ecommunity_hash) {
8395 /* Delete all ecommunities in the hash.
8396 */
8397 hash_clean(aggregate->ecommunity_hash,
8398 bgp_aggr_ecommunity_remove);
8399 /* Free up the ecommunity_hash.
8400 */
8401 hash_free(aggregate->ecommunity_hash);
8402 }
8403
8404 if (aggregate->lcommunity)
8405 lcommunity_free(&aggregate->lcommunity);
8406
8407 if (aggregate->lcommunity_hash) {
8408 /* Delete all lcommunities in the hash.
8409 */
8410 hash_clean(aggregate->lcommunity_hash,
8411 bgp_aggr_lcommunity_remove);
8412 /* Free up the lcommunity_hash.
8413 */
8414 hash_free(aggregate->lcommunity_hash);
8415 }
8416
8417 if (aggregate->aspath)
8418 aspath_free(aggregate->aspath);
8419
8420 if (aggregate->aspath_hash) {
8421 /* Delete all as-paths in the hash.
8422 */
8423 hash_clean(aggregate->aspath_hash,
8424 bgp_aggr_aspath_remove);
8425 /* Free up the aspath_hash.
8426 */
8427 hash_free(aggregate->aspath_hash);
8428 }
8429
8430 bgp_aggregate_free(aggregate);
8431 bgp_dest_unlock_node(dest);
8432 bgp_dest_unlock_node(dest);
8433
8434 return CMD_SUCCESS;
8435 }
8436
8437 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8438 safi_t safi, const char *rmap,
8439 uint8_t summary_only, uint8_t as_set,
8440 uint8_t origin, bool match_med,
8441 const char *suppress_map)
8442 {
8443 VTY_DECLVAR_CONTEXT(bgp, bgp);
8444 int ret;
8445 struct prefix p;
8446 struct bgp_dest *dest;
8447 struct bgp_aggregate *aggregate;
8448 uint8_t as_set_new = as_set;
8449
8450 if (suppress_map && summary_only) {
8451 vty_out(vty,
8452 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8453 return CMD_WARNING_CONFIG_FAILED;
8454 }
8455
8456 /* Convert string to prefix structure. */
8457 ret = str2prefix(prefix_str, &p);
8458 if (!ret) {
8459 vty_out(vty, "Malformed prefix\n");
8460 return CMD_WARNING_CONFIG_FAILED;
8461 }
8462 apply_mask(&p);
8463
8464 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8465 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8466 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8467 prefix_str);
8468 return CMD_WARNING_CONFIG_FAILED;
8469 }
8470
8471 /* Old configuration check. */
8472 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8473 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8474
8475 if (aggregate) {
8476 vty_out(vty, "There is already same aggregate network.\n");
8477 /* try to remove the old entry */
8478 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8479 if (ret) {
8480 vty_out(vty, "Error deleting aggregate.\n");
8481 bgp_dest_unlock_node(dest);
8482 return CMD_WARNING_CONFIG_FAILED;
8483 }
8484 }
8485
8486 /* Make aggregate address structure. */
8487 aggregate = bgp_aggregate_new();
8488 aggregate->summary_only = summary_only;
8489 aggregate->match_med = match_med;
8490
8491 /* Network operators MUST NOT locally generate any new
8492 * announcements containing AS_SET or AS_CONFED_SET. If they have
8493 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8494 * SHOULD withdraw those routes and re-announce routes for the
8495 * aggregate or component prefixes (i.e., the more-specific routes
8496 * subsumed by the previously aggregated route) without AS_SET
8497 * or AS_CONFED_SET in the updates.
8498 */
8499 if (bgp->reject_as_sets) {
8500 if (as_set == AGGREGATE_AS_SET) {
8501 as_set_new = AGGREGATE_AS_UNSET;
8502 zlog_warn(
8503 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8504 __func__);
8505 vty_out(vty,
8506 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8507 }
8508 }
8509
8510 aggregate->as_set = as_set_new;
8511 aggregate->safi = safi;
8512 /* Override ORIGIN attribute if defined.
8513 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8514 * to IGP which is not what rfc4271 says.
8515 * This enables the same behavior, optionally.
8516 */
8517 aggregate->origin = origin;
8518
8519 if (rmap) {
8520 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8521 route_map_counter_decrement(aggregate->rmap.map);
8522 aggregate->rmap.name =
8523 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8524 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8525 route_map_counter_increment(aggregate->rmap.map);
8526 }
8527
8528 if (suppress_map) {
8529 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8530 route_map_counter_decrement(aggregate->suppress_map);
8531
8532 aggregate->suppress_map_name =
8533 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8534 aggregate->suppress_map =
8535 route_map_lookup_by_name(aggregate->suppress_map_name);
8536 route_map_counter_increment(aggregate->suppress_map);
8537 }
8538
8539 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8540
8541 /* Aggregate address insert into BGP routing table. */
8542 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8543
8544 return CMD_SUCCESS;
8545 }
8546
8547 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8548 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8549 "as-set$as_set_s"
8550 "|summary-only$summary_only"
8551 "|route-map RMAP_NAME$rmap_name"
8552 "|origin <egp|igp|incomplete>$origin_s"
8553 "|matching-MED-only$match_med"
8554 "|suppress-map RMAP_NAME$suppress_map"
8555 "}]",
8556 NO_STR
8557 "Configure BGP aggregate entries\n"
8558 "Aggregate prefix\n"
8559 "Aggregate address\n"
8560 "Aggregate mask\n"
8561 "Generate AS set path information\n"
8562 "Filter more specific routes from updates\n"
8563 "Apply route map to aggregate network\n"
8564 "Route map name\n"
8565 "BGP origin code\n"
8566 "Remote EGP\n"
8567 "Local IGP\n"
8568 "Unknown heritage\n"
8569 "Only aggregate routes with matching MED\n"
8570 "Suppress the selected more specific routes\n"
8571 "Route map with the route selectors\n")
8572 {
8573 const char *prefix_s = NULL;
8574 safi_t safi = bgp_node_safi(vty);
8575 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8576 int as_set = AGGREGATE_AS_UNSET;
8577 char prefix_buf[PREFIX2STR_BUFFER];
8578
8579 if (addr_str) {
8580 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8581 sizeof(prefix_buf))
8582 == 0) {
8583 vty_out(vty, "%% Inconsistent address and mask\n");
8584 return CMD_WARNING_CONFIG_FAILED;
8585 }
8586 prefix_s = prefix_buf;
8587 } else
8588 prefix_s = prefix_str;
8589
8590 if (origin_s) {
8591 if (strcmp(origin_s, "egp") == 0)
8592 origin = BGP_ORIGIN_EGP;
8593 else if (strcmp(origin_s, "igp") == 0)
8594 origin = BGP_ORIGIN_IGP;
8595 else if (strcmp(origin_s, "incomplete") == 0)
8596 origin = BGP_ORIGIN_INCOMPLETE;
8597 }
8598
8599 if (as_set_s)
8600 as_set = AGGREGATE_AS_SET;
8601
8602 /* Handle configuration removal, otherwise installation. */
8603 if (no)
8604 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8605
8606 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8607 summary_only != NULL, as_set, origin,
8608 match_med != NULL, suppress_map);
8609 }
8610
8611 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8612 "[no] aggregate-address X:X::X:X/M$prefix [{"
8613 "as-set$as_set_s"
8614 "|summary-only$summary_only"
8615 "|route-map RMAP_NAME$rmap_name"
8616 "|origin <egp|igp|incomplete>$origin_s"
8617 "|matching-MED-only$match_med"
8618 "|suppress-map RMAP_NAME$suppress_map"
8619 "}]",
8620 NO_STR
8621 "Configure BGP aggregate entries\n"
8622 "Aggregate prefix\n"
8623 "Generate AS set path information\n"
8624 "Filter more specific routes from updates\n"
8625 "Apply route map to aggregate network\n"
8626 "Route map name\n"
8627 "BGP origin code\n"
8628 "Remote EGP\n"
8629 "Local IGP\n"
8630 "Unknown heritage\n"
8631 "Only aggregate routes with matching MED\n"
8632 "Suppress the selected more specific routes\n"
8633 "Route map with the route selectors\n")
8634 {
8635 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8636 int as_set = AGGREGATE_AS_UNSET;
8637
8638 if (origin_s) {
8639 if (strcmp(origin_s, "egp") == 0)
8640 origin = BGP_ORIGIN_EGP;
8641 else if (strcmp(origin_s, "igp") == 0)
8642 origin = BGP_ORIGIN_IGP;
8643 else if (strcmp(origin_s, "incomplete") == 0)
8644 origin = BGP_ORIGIN_INCOMPLETE;
8645 }
8646
8647 if (as_set_s)
8648 as_set = AGGREGATE_AS_SET;
8649
8650 /* Handle configuration removal, otherwise installation. */
8651 if (no)
8652 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8653 SAFI_UNICAST);
8654
8655 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8656 rmap_name, summary_only != NULL, as_set,
8657 origin, match_med != NULL, suppress_map);
8658 }
8659
8660 /* Redistribute route treatment. */
8661 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8662 const union g_addr *nexthop, ifindex_t ifindex,
8663 enum nexthop_types_t nhtype, uint8_t distance,
8664 enum blackhole_type bhtype, uint32_t metric,
8665 uint8_t type, unsigned short instance,
8666 route_tag_t tag)
8667 {
8668 struct bgp_path_info *new;
8669 struct bgp_path_info *bpi;
8670 struct bgp_path_info rmap_path;
8671 struct bgp_dest *bn;
8672 struct attr attr;
8673 struct attr *new_attr;
8674 afi_t afi;
8675 route_map_result_t ret;
8676 struct bgp_redist *red;
8677
8678 /* Make default attribute. */
8679 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8680 /*
8681 * This must not be NULL to satisfy Coverity SA
8682 */
8683 assert(attr.aspath);
8684
8685 switch (nhtype) {
8686 case NEXTHOP_TYPE_IFINDEX:
8687 switch (p->family) {
8688 case AF_INET:
8689 attr.nexthop.s_addr = INADDR_ANY;
8690 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8691 break;
8692 case AF_INET6:
8693 memset(&attr.mp_nexthop_global, 0,
8694 sizeof(attr.mp_nexthop_global));
8695 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8696 break;
8697 }
8698 break;
8699 case NEXTHOP_TYPE_IPV4:
8700 case NEXTHOP_TYPE_IPV4_IFINDEX:
8701 attr.nexthop = nexthop->ipv4;
8702 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8703 break;
8704 case NEXTHOP_TYPE_IPV6:
8705 case NEXTHOP_TYPE_IPV6_IFINDEX:
8706 attr.mp_nexthop_global = nexthop->ipv6;
8707 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8708 break;
8709 case NEXTHOP_TYPE_BLACKHOLE:
8710 switch (p->family) {
8711 case AF_INET:
8712 attr.nexthop.s_addr = INADDR_ANY;
8713 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8714 break;
8715 case AF_INET6:
8716 memset(&attr.mp_nexthop_global, 0,
8717 sizeof(attr.mp_nexthop_global));
8718 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8719 break;
8720 }
8721 attr.bh_type = bhtype;
8722 break;
8723 }
8724 attr.nh_type = nhtype;
8725 attr.nh_ifindex = ifindex;
8726
8727 attr.med = metric;
8728 attr.distance = distance;
8729 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8730 attr.tag = tag;
8731
8732 if (metric)
8733 bgp_attr_set_aigp_metric(&attr, metric);
8734
8735 afi = family2afi(p->family);
8736
8737 red = bgp_redist_lookup(bgp, afi, type, instance);
8738 if (red) {
8739 struct attr attr_new;
8740
8741 /* Copy attribute for modification. */
8742 attr_new = attr;
8743
8744 if (red->redist_metric_flag) {
8745 attr_new.med = red->redist_metric;
8746 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8747 }
8748
8749 /* Apply route-map. */
8750 if (red->rmap.name) {
8751 memset(&rmap_path, 0, sizeof(rmap_path));
8752 rmap_path.peer = bgp->peer_self;
8753 rmap_path.attr = &attr_new;
8754
8755 SET_FLAG(bgp->peer_self->rmap_type,
8756 PEER_RMAP_TYPE_REDISTRIBUTE);
8757
8758 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8759
8760 bgp->peer_self->rmap_type = 0;
8761
8762 if (ret == RMAP_DENYMATCH) {
8763 /* Free uninterned attribute. */
8764 bgp_attr_flush(&attr_new);
8765
8766 /* Unintern original. */
8767 aspath_unintern(&attr.aspath);
8768 bgp_redistribute_delete(bgp, p, type, instance);
8769 return;
8770 }
8771 }
8772
8773 if (bgp_in_graceful_shutdown(bgp))
8774 bgp_attr_add_gshut_community(&attr_new);
8775
8776 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8777 SAFI_UNICAST, p, NULL);
8778
8779 new_attr = bgp_attr_intern(&attr_new);
8780
8781 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8782 if (bpi->peer == bgp->peer_self
8783 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8784 break;
8785
8786 if (bpi) {
8787 /* Ensure the (source route) type is updated. */
8788 bpi->type = type;
8789 if (attrhash_cmp(bpi->attr, new_attr)
8790 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8791 bgp_attr_unintern(&new_attr);
8792 aspath_unintern(&attr.aspath);
8793 bgp_dest_unlock_node(bn);
8794 return;
8795 } else {
8796 /* The attribute is changed. */
8797 bgp_path_info_set_flag(bn, bpi,
8798 BGP_PATH_ATTR_CHANGED);
8799
8800 /* Rewrite BGP route information. */
8801 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8802 bgp_path_info_restore(bn, bpi);
8803 else
8804 bgp_aggregate_decrement(
8805 bgp, p, bpi, afi, SAFI_UNICAST);
8806 bgp_attr_unintern(&bpi->attr);
8807 bpi->attr = new_attr;
8808 bpi->uptime = monotime(NULL);
8809
8810 /* Process change. */
8811 bgp_aggregate_increment(bgp, p, bpi, afi,
8812 SAFI_UNICAST);
8813 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8814 bgp_dest_unlock_node(bn);
8815 aspath_unintern(&attr.aspath);
8816
8817 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8818 || (bgp->inst_type
8819 == BGP_INSTANCE_TYPE_DEFAULT)) {
8820
8821 vpn_leak_from_vrf_update(
8822 bgp_get_default(), bgp, bpi);
8823 }
8824 return;
8825 }
8826 }
8827
8828 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8829 bgp->peer_self, new_attr, bn);
8830 SET_FLAG(new->flags, BGP_PATH_VALID);
8831
8832 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8833 bgp_path_info_add(bn, new);
8834 bgp_dest_unlock_node(bn);
8835 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8836 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8837
8838 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8839 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8840
8841 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8842 }
8843 }
8844
8845 /* Unintern original. */
8846 aspath_unintern(&attr.aspath);
8847 }
8848
8849 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8850 unsigned short instance)
8851 {
8852 afi_t afi;
8853 struct bgp_dest *dest;
8854 struct bgp_path_info *pi;
8855 struct bgp_redist *red;
8856
8857 afi = family2afi(p->family);
8858
8859 red = bgp_redist_lookup(bgp, afi, type, instance);
8860 if (red) {
8861 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8862 SAFI_UNICAST, p, NULL);
8863
8864 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8865 if (pi->peer == bgp->peer_self && pi->type == type)
8866 break;
8867
8868 if (pi) {
8869 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8870 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8871
8872 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8873 bgp, pi);
8874 }
8875 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8876 bgp_path_info_delete(dest, pi);
8877 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8878 }
8879 bgp_dest_unlock_node(dest);
8880 }
8881 }
8882
8883 /* Withdraw specified route type's route. */
8884 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8885 unsigned short instance)
8886 {
8887 struct bgp_dest *dest;
8888 struct bgp_path_info *pi;
8889 struct bgp_table *table;
8890
8891 table = bgp->rib[afi][SAFI_UNICAST];
8892
8893 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8894 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8895 if (pi->peer == bgp->peer_self && pi->type == type
8896 && pi->instance == instance)
8897 break;
8898
8899 if (pi) {
8900 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8901 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8902
8903 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8904 bgp, pi);
8905 }
8906 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8907 pi, afi, SAFI_UNICAST);
8908 bgp_path_info_delete(dest, pi);
8909 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8910 }
8911 }
8912 }
8913
8914 /* Static function to display route. */
8915 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8916 struct vty *vty, json_object *json, bool wide)
8917 {
8918 int len = 0;
8919 char buf[BUFSIZ];
8920
8921 if (p->family == AF_INET) {
8922 if (!json) {
8923 len = vty_out(vty, "%pFX", p);
8924 } else {
8925 json_object_string_add(json, "prefix",
8926 inet_ntop(p->family,
8927 &p->u.prefix, buf,
8928 BUFSIZ));
8929 json_object_int_add(json, "prefixLen", p->prefixlen);
8930 json_object_string_addf(json, "network", "%pFX", p);
8931 json_object_int_add(json, "version", dest->version);
8932 }
8933 } else if (p->family == AF_ETHERNET) {
8934 len = vty_out(vty, "%pFX", p);
8935 } else if (p->family == AF_EVPN) {
8936 if (!json)
8937 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8938 else
8939 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8940 } else if (p->family == AF_FLOWSPEC) {
8941 route_vty_out_flowspec(vty, p, NULL,
8942 json ?
8943 NLRI_STRING_FORMAT_JSON_SIMPLE :
8944 NLRI_STRING_FORMAT_MIN, json);
8945 } else {
8946 if (!json)
8947 len = vty_out(vty, "%pFX", p);
8948 else {
8949 json_object_string_add(json, "prefix",
8950 inet_ntop(p->family,
8951 &p->u.prefix, buf,
8952 BUFSIZ));
8953 json_object_int_add(json, "prefixLen", p->prefixlen);
8954 json_object_string_addf(json, "network", "%pFX", p);
8955 json_object_int_add(json, "version", dest->version);
8956 }
8957 }
8958
8959 if (!json) {
8960 len = wide ? (45 - len) : (17 - len);
8961 if (len < 1)
8962 vty_out(vty, "\n%*s", 20, " ");
8963 else
8964 vty_out(vty, "%*s", len, " ");
8965 }
8966 }
8967
8968 enum bgp_display_type {
8969 normal_list,
8970 };
8971
8972 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8973 {
8974 switch (reason) {
8975 case bgp_path_selection_none:
8976 return "Nothing to Select";
8977 case bgp_path_selection_first:
8978 return "First path received";
8979 case bgp_path_selection_evpn_sticky_mac:
8980 return "EVPN Sticky Mac";
8981 case bgp_path_selection_evpn_seq:
8982 return "EVPN sequence number";
8983 case bgp_path_selection_evpn_lower_ip:
8984 return "EVPN lower IP";
8985 case bgp_path_selection_evpn_local_path:
8986 return "EVPN local ES path";
8987 case bgp_path_selection_evpn_non_proxy:
8988 return "EVPN non proxy";
8989 case bgp_path_selection_weight:
8990 return "Weight";
8991 case bgp_path_selection_local_pref:
8992 return "Local Pref";
8993 case bgp_path_selection_accept_own:
8994 return "Accept Own";
8995 case bgp_path_selection_local_route:
8996 return "Local Route";
8997 case bgp_path_selection_aigp:
8998 return "AIGP";
8999 case bgp_path_selection_confed_as_path:
9000 return "Confederation based AS Path";
9001 case bgp_path_selection_as_path:
9002 return "AS Path";
9003 case bgp_path_selection_origin:
9004 return "Origin";
9005 case bgp_path_selection_med:
9006 return "MED";
9007 case bgp_path_selection_peer:
9008 return "Peer Type";
9009 case bgp_path_selection_confed:
9010 return "Confed Peer Type";
9011 case bgp_path_selection_igp_metric:
9012 return "IGP Metric";
9013 case bgp_path_selection_older:
9014 return "Older Path";
9015 case bgp_path_selection_router_id:
9016 return "Router ID";
9017 case bgp_path_selection_cluster_length:
9018 return "Cluster length";
9019 case bgp_path_selection_stale:
9020 return "Path Staleness";
9021 case bgp_path_selection_local_configured:
9022 return "Locally configured route";
9023 case bgp_path_selection_neighbor_ip:
9024 return "Neighbor IP";
9025 case bgp_path_selection_default:
9026 return "Nothing left to compare";
9027 }
9028 return "Invalid (internal error)";
9029 }
9030
9031 /* Print the short form route status for a bgp_path_info */
9032 static void route_vty_short_status_out(struct vty *vty,
9033 struct bgp_path_info *path,
9034 const struct prefix *p,
9035 json_object *json_path)
9036 {
9037 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9038
9039 if (json_path) {
9040
9041 /* Route status display. */
9042 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9043 json_object_boolean_true_add(json_path, "removed");
9044
9045 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9046 json_object_boolean_true_add(json_path, "stale");
9047
9048 if (path->extra && bgp_path_suppressed(path))
9049 json_object_boolean_true_add(json_path, "suppressed");
9050
9051 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9052 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9053 json_object_boolean_true_add(json_path, "valid");
9054
9055 /* Selected */
9056 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9057 json_object_boolean_true_add(json_path, "history");
9058
9059 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9060 json_object_boolean_true_add(json_path, "damped");
9061
9062 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9063 json_object_boolean_true_add(json_path, "bestpath");
9064 json_object_string_add(json_path, "selectionReason",
9065 bgp_path_selection_reason2str(
9066 path->net->reason));
9067 }
9068
9069 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9070 json_object_boolean_true_add(json_path, "multipath");
9071
9072 /* Internal route. */
9073 if ((path->peer->as)
9074 && (path->peer->as == path->peer->local_as))
9075 json_object_string_add(json_path, "pathFrom",
9076 "internal");
9077 else
9078 json_object_string_add(json_path, "pathFrom",
9079 "external");
9080
9081 return;
9082 }
9083
9084 /* RPKI validation state */
9085 rpki_state =
9086 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9087
9088 if (rpki_state == RPKI_VALID)
9089 vty_out(vty, "V");
9090 else if (rpki_state == RPKI_INVALID)
9091 vty_out(vty, "I");
9092 else if (rpki_state == RPKI_NOTFOUND)
9093 vty_out(vty, "N");
9094 else
9095 vty_out(vty, " ");
9096
9097 /* Route status display. */
9098 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9099 vty_out(vty, "R");
9100 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9101 vty_out(vty, "S");
9102 else if (bgp_path_suppressed(path))
9103 vty_out(vty, "s");
9104 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9105 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9106 vty_out(vty, "*");
9107 else
9108 vty_out(vty, " ");
9109
9110 /* Selected */
9111 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9112 vty_out(vty, "h");
9113 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9114 vty_out(vty, "d");
9115 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9116 vty_out(vty, ">");
9117 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9118 vty_out(vty, "=");
9119 else
9120 vty_out(vty, " ");
9121
9122 /* Internal route. */
9123 if (path->peer && (path->peer->as)
9124 && (path->peer->as == path->peer->local_as))
9125 vty_out(vty, "i");
9126 else
9127 vty_out(vty, " ");
9128 }
9129
9130 static char *bgp_nexthop_hostname(struct peer *peer,
9131 struct bgp_nexthop_cache *bnc)
9132 {
9133 if (peer->hostname
9134 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9135 return peer->hostname;
9136 return NULL;
9137 }
9138
9139 /* called from terminal list command */
9140 void route_vty_out(struct vty *vty, const struct prefix *p,
9141 struct bgp_path_info *path, int display, safi_t safi,
9142 json_object *json_paths, bool wide)
9143 {
9144 int len;
9145 struct attr *attr = path->attr;
9146 json_object *json_path = NULL;
9147 json_object *json_nexthops = NULL;
9148 json_object *json_nexthop_global = NULL;
9149 json_object *json_nexthop_ll = NULL;
9150 json_object *json_ext_community = NULL;
9151 char vrf_id_str[VRF_NAMSIZ] = {0};
9152 bool nexthop_self =
9153 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9154 bool nexthop_othervrf = false;
9155 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9156 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9157 char *nexthop_hostname =
9158 bgp_nexthop_hostname(path->peer, path->nexthop);
9159 char esi_buf[ESI_STR_LEN];
9160
9161 if (json_paths)
9162 json_path = json_object_new_object();
9163
9164 /* short status lead text */
9165 route_vty_short_status_out(vty, path, p, json_path);
9166
9167 if (!json_paths) {
9168 /* print prefix and mask */
9169 if (!display)
9170 route_vty_out_route(path->net, p, vty, json_path, wide);
9171 else
9172 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9173 } else {
9174 route_vty_out_route(path->net, p, vty, json_path, wide);
9175 }
9176
9177 /*
9178 * If vrf id of nexthop is different from that of prefix,
9179 * set up printable string to append
9180 */
9181 if (path->extra && path->extra->bgp_orig) {
9182 const char *self = "";
9183
9184 if (nexthop_self)
9185 self = "<";
9186
9187 nexthop_othervrf = true;
9188 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9189
9190 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9191 snprintf(vrf_id_str, sizeof(vrf_id_str),
9192 "@%s%s", VRFID_NONE_STR, self);
9193 else
9194 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9195 path->extra->bgp_orig->vrf_id, self);
9196
9197 if (path->extra->bgp_orig->inst_type
9198 != BGP_INSTANCE_TYPE_DEFAULT)
9199
9200 nexthop_vrfname = path->extra->bgp_orig->name;
9201 } else {
9202 const char *self = "";
9203
9204 if (nexthop_self)
9205 self = "<";
9206
9207 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9208 }
9209
9210 /*
9211 * For ENCAP and EVPN routes, nexthop address family is not
9212 * neccessarily the same as the prefix address family.
9213 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9214 * EVPN routes are also exchanged with a MP nexthop. Currently,
9215 * this
9216 * is only IPv4, the value will be present in either
9217 * attr->nexthop or
9218 * attr->mp_nexthop_global_in
9219 */
9220 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9221 char buf[BUFSIZ];
9222 char nexthop[128];
9223 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9224
9225 switch (af) {
9226 case AF_INET:
9227 snprintf(nexthop, sizeof(nexthop), "%s",
9228 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
9229 BUFSIZ));
9230 break;
9231 case AF_INET6:
9232 snprintf(nexthop, sizeof(nexthop), "%s",
9233 inet_ntop(af, &attr->mp_nexthop_global, buf,
9234 BUFSIZ));
9235 break;
9236 default:
9237 snprintf(nexthop, sizeof(nexthop), "?");
9238 break;
9239 }
9240
9241 if (json_paths) {
9242 json_nexthop_global = json_object_new_object();
9243
9244 json_object_string_add(json_nexthop_global, "ip",
9245 nexthop);
9246
9247 if (path->peer->hostname)
9248 json_object_string_add(json_nexthop_global,
9249 "hostname",
9250 path->peer->hostname);
9251
9252 json_object_string_add(json_nexthop_global, "afi",
9253 (af == AF_INET) ? "ipv4"
9254 : "ipv6");
9255 json_object_boolean_true_add(json_nexthop_global,
9256 "used");
9257 } else {
9258 if (nexthop_hostname)
9259 len = vty_out(vty, "%s(%s)%s", nexthop,
9260 nexthop_hostname, vrf_id_str);
9261 else
9262 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9263
9264 len = wide ? (41 - len) : (16 - len);
9265 if (len < 1)
9266 vty_out(vty, "\n%*s", 36, " ");
9267 else
9268 vty_out(vty, "%*s", len, " ");
9269 }
9270 } else if (safi == SAFI_EVPN) {
9271 if (json_paths) {
9272 json_nexthop_global = json_object_new_object();
9273
9274 json_object_string_addf(json_nexthop_global, "ip",
9275 "%pI4",
9276 &attr->mp_nexthop_global_in);
9277
9278 if (path->peer->hostname)
9279 json_object_string_add(json_nexthop_global,
9280 "hostname",
9281 path->peer->hostname);
9282
9283 json_object_string_add(json_nexthop_global, "afi",
9284 "ipv4");
9285 json_object_boolean_true_add(json_nexthop_global,
9286 "used");
9287 } else {
9288 if (nexthop_hostname)
9289 len = vty_out(vty, "%pI4(%s)%s",
9290 &attr->mp_nexthop_global_in,
9291 nexthop_hostname, vrf_id_str);
9292 else
9293 len = vty_out(vty, "%pI4%s",
9294 &attr->mp_nexthop_global_in,
9295 vrf_id_str);
9296
9297 len = wide ? (41 - len) : (16 - len);
9298 if (len < 1)
9299 vty_out(vty, "\n%*s", 36, " ");
9300 else
9301 vty_out(vty, "%*s", len, " ");
9302 }
9303 } else if (safi == SAFI_FLOWSPEC) {
9304 if (attr->nexthop.s_addr != INADDR_ANY) {
9305 if (json_paths) {
9306 json_nexthop_global = json_object_new_object();
9307
9308 json_object_string_add(json_nexthop_global,
9309 "afi", "ipv4");
9310 json_object_string_addf(json_nexthop_global,
9311 "ip", "%pI4",
9312 &attr->nexthop);
9313
9314 if (path->peer->hostname)
9315 json_object_string_add(
9316 json_nexthop_global, "hostname",
9317 path->peer->hostname);
9318
9319 json_object_boolean_true_add(
9320 json_nexthop_global,
9321 "used");
9322 } else {
9323 if (nexthop_hostname)
9324 len = vty_out(vty, "%pI4(%s)%s",
9325 &attr->nexthop,
9326 nexthop_hostname,
9327 vrf_id_str);
9328 else
9329 len = vty_out(vty, "%pI4%s",
9330 &attr->nexthop,
9331 vrf_id_str);
9332
9333 len = wide ? (41 - len) : (16 - len);
9334 if (len < 1)
9335 vty_out(vty, "\n%*s", 36, " ");
9336 else
9337 vty_out(vty, "%*s", len, " ");
9338 }
9339 }
9340 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9341 if (json_paths) {
9342 json_nexthop_global = json_object_new_object();
9343
9344 json_object_string_addf(json_nexthop_global, "ip",
9345 "%pI4", &attr->nexthop);
9346
9347 if (path->peer->hostname)
9348 json_object_string_add(json_nexthop_global,
9349 "hostname",
9350 path->peer->hostname);
9351
9352 json_object_string_add(json_nexthop_global, "afi",
9353 "ipv4");
9354 json_object_boolean_true_add(json_nexthop_global,
9355 "used");
9356 } else {
9357 if (nexthop_hostname)
9358 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9359 nexthop_hostname, vrf_id_str);
9360 else
9361 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9362 vrf_id_str);
9363
9364 len = wide ? (41 - len) : (16 - len);
9365 if (len < 1)
9366 vty_out(vty, "\n%*s", 36, " ");
9367 else
9368 vty_out(vty, "%*s", len, " ");
9369 }
9370 }
9371
9372 /* IPv6 Next Hop */
9373 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9374 if (json_paths) {
9375 json_nexthop_global = json_object_new_object();
9376 json_object_string_addf(json_nexthop_global, "ip",
9377 "%pI6",
9378 &attr->mp_nexthop_global);
9379
9380 if (path->peer->hostname)
9381 json_object_string_add(json_nexthop_global,
9382 "hostname",
9383 path->peer->hostname);
9384
9385 json_object_string_add(json_nexthop_global, "afi",
9386 "ipv6");
9387 json_object_string_add(json_nexthop_global, "scope",
9388 "global");
9389
9390 /* We display both LL & GL if both have been
9391 * received */
9392 if ((attr->mp_nexthop_len
9393 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9394 || (path->peer->conf_if)) {
9395 json_nexthop_ll = json_object_new_object();
9396 json_object_string_addf(
9397 json_nexthop_ll, "ip", "%pI6",
9398 &attr->mp_nexthop_local);
9399
9400 if (path->peer->hostname)
9401 json_object_string_add(
9402 json_nexthop_ll, "hostname",
9403 path->peer->hostname);
9404
9405 json_object_string_add(json_nexthop_ll, "afi",
9406 "ipv6");
9407 json_object_string_add(json_nexthop_ll, "scope",
9408 "link-local");
9409
9410 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9411 &attr->mp_nexthop_local)
9412 != 0)
9413 && !attr->mp_nexthop_prefer_global)
9414 json_object_boolean_true_add(
9415 json_nexthop_ll, "used");
9416 else
9417 json_object_boolean_true_add(
9418 json_nexthop_global, "used");
9419 } else
9420 json_object_boolean_true_add(
9421 json_nexthop_global, "used");
9422 } else {
9423 /* Display LL if LL/Global both in table unless
9424 * prefer-global is set */
9425 if (((attr->mp_nexthop_len
9426 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9427 && !attr->mp_nexthop_prefer_global)
9428 || (path->peer->conf_if)) {
9429 if (path->peer->conf_if) {
9430 len = vty_out(vty, "%s",
9431 path->peer->conf_if);
9432 /* len of IPv6 addr + max len of def
9433 * ifname */
9434 len = wide ? (41 - len) : (16 - len);
9435
9436 if (len < 1)
9437 vty_out(vty, "\n%*s", 36, " ");
9438 else
9439 vty_out(vty, "%*s", len, " ");
9440 } else {
9441 if (nexthop_hostname)
9442 len = vty_out(
9443 vty, "%pI6(%s)%s",
9444 &attr->mp_nexthop_local,
9445 nexthop_hostname,
9446 vrf_id_str);
9447 else
9448 len = vty_out(
9449 vty, "%pI6%s",
9450 &attr->mp_nexthop_local,
9451 vrf_id_str);
9452
9453 len = wide ? (41 - len) : (16 - len);
9454
9455 if (len < 1)
9456 vty_out(vty, "\n%*s", 36, " ");
9457 else
9458 vty_out(vty, "%*s", len, " ");
9459 }
9460 } else {
9461 if (nexthop_hostname)
9462 len = vty_out(vty, "%pI6(%s)%s",
9463 &attr->mp_nexthop_global,
9464 nexthop_hostname,
9465 vrf_id_str);
9466 else
9467 len = vty_out(vty, "%pI6%s",
9468 &attr->mp_nexthop_global,
9469 vrf_id_str);
9470
9471 len = wide ? (41 - len) : (16 - len);
9472
9473 if (len < 1)
9474 vty_out(vty, "\n%*s", 36, " ");
9475 else
9476 vty_out(vty, "%*s", len, " ");
9477 }
9478 }
9479 }
9480
9481 /* MED/Metric */
9482 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9483 if (json_paths)
9484 json_object_int_add(json_path, "metric", attr->med);
9485 else if (wide)
9486 vty_out(vty, "%7u", attr->med);
9487 else
9488 vty_out(vty, "%10u", attr->med);
9489 else if (!json_paths) {
9490 if (wide)
9491 vty_out(vty, "%*s", 7, " ");
9492 else
9493 vty_out(vty, "%*s", 10, " ");
9494 }
9495
9496 /* Local Pref */
9497 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9498 if (json_paths)
9499 json_object_int_add(json_path, "locPrf",
9500 attr->local_pref);
9501 else
9502 vty_out(vty, "%7u", attr->local_pref);
9503 else if (!json_paths)
9504 vty_out(vty, " ");
9505
9506 if (json_paths)
9507 json_object_int_add(json_path, "weight", attr->weight);
9508 else
9509 vty_out(vty, "%7u ", attr->weight);
9510
9511 if (json_paths)
9512 json_object_string_addf(json_path, "peerId", "%pSU",
9513 &path->peer->su);
9514
9515 /* Print aspath */
9516 if (attr->aspath) {
9517 if (json_paths)
9518 json_object_string_add(json_path, "path",
9519 attr->aspath->str);
9520 else
9521 aspath_print_vty(vty, "%s", attr->aspath, " ");
9522 }
9523
9524 /* Print origin */
9525 if (json_paths)
9526 json_object_string_add(json_path, "origin",
9527 bgp_origin_long_str[attr->origin]);
9528 else
9529 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9530
9531 if (json_paths) {
9532 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9533 json_object_string_add(json_path, "esi",
9534 esi_to_str(&attr->esi,
9535 esi_buf, sizeof(esi_buf)));
9536 }
9537 if (safi == SAFI_EVPN &&
9538 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9539 json_ext_community = json_object_new_object();
9540 json_object_string_add(
9541 json_ext_community, "string",
9542 bgp_attr_get_ecommunity(attr)->str);
9543 json_object_object_add(json_path,
9544 "extendedCommunity",
9545 json_ext_community);
9546 }
9547
9548 if (nexthop_self)
9549 json_object_boolean_true_add(json_path,
9550 "announceNexthopSelf");
9551 if (nexthop_othervrf) {
9552 json_object_string_add(json_path, "nhVrfName",
9553 nexthop_vrfname);
9554
9555 json_object_int_add(json_path, "nhVrfId",
9556 ((nexthop_vrfid == VRF_UNKNOWN)
9557 ? -1
9558 : (int)nexthop_vrfid));
9559 }
9560 }
9561
9562 if (json_paths) {
9563 if (json_nexthop_global || json_nexthop_ll) {
9564 json_nexthops = json_object_new_array();
9565
9566 if (json_nexthop_global)
9567 json_object_array_add(json_nexthops,
9568 json_nexthop_global);
9569
9570 if (json_nexthop_ll)
9571 json_object_array_add(json_nexthops,
9572 json_nexthop_ll);
9573
9574 json_object_object_add(json_path, "nexthops",
9575 json_nexthops);
9576 }
9577
9578 json_object_array_add(json_paths, json_path);
9579 } else {
9580 vty_out(vty, "\n");
9581
9582 if (safi == SAFI_EVPN) {
9583 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9584 /* XXX - add these params to the json out */
9585 vty_out(vty, "%*s", 20, " ");
9586 vty_out(vty, "ESI:%s",
9587 esi_to_str(&attr->esi, esi_buf,
9588 sizeof(esi_buf)));
9589
9590 vty_out(vty, "\n");
9591 }
9592 if (attr->flag &
9593 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9594 vty_out(vty, "%*s", 20, " ");
9595 vty_out(vty, "%s\n",
9596 bgp_attr_get_ecommunity(attr)->str);
9597 }
9598 }
9599
9600 #ifdef ENABLE_BGP_VNC
9601 /* prints an additional line, indented, with VNC info, if
9602 * present */
9603 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9604 rfapi_vty_out_vncinfo(vty, p, path, safi);
9605 #endif
9606 }
9607 }
9608
9609 /* called from terminal list command */
9610 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9611 const struct prefix *p, struct attr *attr, safi_t safi,
9612 bool use_json, json_object *json_ar, bool wide)
9613 {
9614 json_object *json_status = NULL;
9615 json_object *json_net = NULL;
9616 int len;
9617 char buff[BUFSIZ];
9618
9619 /* Route status display. */
9620 if (use_json) {
9621 json_status = json_object_new_object();
9622 json_net = json_object_new_object();
9623 } else {
9624 vty_out(vty, "*");
9625 vty_out(vty, ">");
9626 vty_out(vty, " ");
9627 }
9628
9629 /* print prefix and mask */
9630 if (use_json) {
9631 if (safi == SAFI_EVPN)
9632 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9633 else if (p->family == AF_INET || p->family == AF_INET6) {
9634 json_object_string_add(
9635 json_net, "addrPrefix",
9636 inet_ntop(p->family, &p->u.prefix, buff,
9637 BUFSIZ));
9638 json_object_int_add(json_net, "prefixLen",
9639 p->prefixlen);
9640 json_object_string_addf(json_net, "network", "%pFX", p);
9641 }
9642 } else
9643 route_vty_out_route(dest, p, vty, NULL, wide);
9644
9645 /* Print attribute */
9646 if (attr) {
9647 if (use_json) {
9648 if (p->family == AF_INET &&
9649 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9650 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9651 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9652 json_object_string_addf(
9653 json_net, "nextHop", "%pI4",
9654 &attr->mp_nexthop_global_in);
9655 else
9656 json_object_string_addf(
9657 json_net, "nextHop", "%pI4",
9658 &attr->nexthop);
9659 } else if (p->family == AF_INET6 ||
9660 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9661 json_object_string_addf(
9662 json_net, "nextHopGlobal", "%pI6",
9663 &attr->mp_nexthop_global);
9664 } else if (p->family == AF_EVPN &&
9665 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9666 json_object_string_addf(
9667 json_net, "nextHop", "%pI4",
9668 &attr->mp_nexthop_global_in);
9669 }
9670
9671 if (attr->flag
9672 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9673 json_object_int_add(json_net, "metric",
9674 attr->med);
9675
9676 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9677 json_object_int_add(json_net, "locPrf",
9678 attr->local_pref);
9679
9680 json_object_int_add(json_net, "weight", attr->weight);
9681
9682 /* Print aspath */
9683 if (attr->aspath)
9684 json_object_string_add(json_net, "path",
9685 attr->aspath->str);
9686
9687 /* Print origin */
9688 json_object_string_add(json_net, "bgpOriginCode",
9689 bgp_origin_str[attr->origin]);
9690 } else {
9691 if (p->family == AF_INET &&
9692 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9693 safi == SAFI_EVPN ||
9694 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9695 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9696 || safi == SAFI_EVPN)
9697 vty_out(vty, "%-16pI4",
9698 &attr->mp_nexthop_global_in);
9699 else if (wide)
9700 vty_out(vty, "%-41pI4", &attr->nexthop);
9701 else
9702 vty_out(vty, "%-16pI4", &attr->nexthop);
9703 } else if (p->family == AF_INET6 ||
9704 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9705 char buf[BUFSIZ];
9706
9707 len = vty_out(
9708 vty, "%s",
9709 inet_ntop(AF_INET6,
9710 &attr->mp_nexthop_global, buf,
9711 BUFSIZ));
9712 len = wide ? (41 - len) : (16 - len);
9713 if (len < 1)
9714 vty_out(vty, "\n%*s", 36, " ");
9715 else
9716 vty_out(vty, "%*s", len, " ");
9717 }
9718 if (attr->flag
9719 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9720 if (wide)
9721 vty_out(vty, "%7u", attr->med);
9722 else
9723 vty_out(vty, "%10u", attr->med);
9724 else if (wide)
9725 vty_out(vty, " ");
9726 else
9727 vty_out(vty, " ");
9728
9729 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9730 vty_out(vty, "%7u", attr->local_pref);
9731 else
9732 vty_out(vty, " ");
9733
9734 vty_out(vty, "%7u ", attr->weight);
9735
9736 /* Print aspath */
9737 if (attr->aspath)
9738 aspath_print_vty(vty, "%s", attr->aspath, " ");
9739
9740 /* Print origin */
9741 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9742 }
9743 }
9744 if (use_json) {
9745 json_object_boolean_true_add(json_status, "*");
9746 json_object_boolean_true_add(json_status, ">");
9747 json_object_object_add(json_net, "appliedStatusSymbols",
9748 json_status);
9749 json_object_object_addf(json_ar, json_net, "%pFX", p);
9750 } else
9751 vty_out(vty, "\n");
9752 }
9753
9754 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9755 struct bgp_path_info *path, int display, safi_t safi,
9756 json_object *json)
9757 {
9758 json_object *json_out = NULL;
9759 struct attr *attr;
9760 mpls_label_t label = MPLS_INVALID_LABEL;
9761
9762 if (!path->extra)
9763 return;
9764
9765 if (json)
9766 json_out = json_object_new_object();
9767
9768 /* short status lead text */
9769 route_vty_short_status_out(vty, path, p, json_out);
9770
9771 /* print prefix and mask */
9772 if (json == NULL) {
9773 if (!display)
9774 route_vty_out_route(path->net, p, vty, NULL, false);
9775 else
9776 vty_out(vty, "%*s", 17, " ");
9777 }
9778
9779 /* Print attribute */
9780 attr = path->attr;
9781 if (((p->family == AF_INET) &&
9782 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9783 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9784 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9785 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9786 || safi == SAFI_EVPN) {
9787 if (json)
9788 json_object_string_addf(
9789 json_out, "mpNexthopGlobalIn", "%pI4",
9790 &attr->mp_nexthop_global_in);
9791 else
9792 vty_out(vty, "%-16pI4",
9793 &attr->mp_nexthop_global_in);
9794 } else {
9795 if (json)
9796 json_object_string_addf(json_out, "nexthop",
9797 "%pI4", &attr->nexthop);
9798 else
9799 vty_out(vty, "%-16pI4", &attr->nexthop);
9800 }
9801 } else if (((p->family == AF_INET6) &&
9802 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9803 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9804 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9805 char buf_a[512];
9806
9807 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9808 if (json)
9809 json_object_string_addf(
9810 json_out, "mpNexthopGlobalIn", "%pI6",
9811 &attr->mp_nexthop_global);
9812 else
9813 vty_out(vty, "%s",
9814 inet_ntop(AF_INET6,
9815 &attr->mp_nexthop_global,
9816 buf_a, sizeof(buf_a)));
9817 } else if (attr->mp_nexthop_len
9818 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9819 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9820 &attr->mp_nexthop_global,
9821 &attr->mp_nexthop_local);
9822 if (json)
9823 json_object_string_add(json_out,
9824 "mpNexthopGlobalLocal",
9825 buf_a);
9826 else
9827 vty_out(vty, "%s", buf_a);
9828 }
9829 }
9830
9831 label = decode_label(&path->extra->label[0]);
9832
9833 if (bgp_is_valid_label(&label)) {
9834 if (json) {
9835 json_object_int_add(json_out, "notag", label);
9836 json_object_array_add(json, json_out);
9837 } else {
9838 vty_out(vty, "notag/%d", label);
9839 vty_out(vty, "\n");
9840 }
9841 } else if (!json)
9842 vty_out(vty, "\n");
9843 }
9844
9845 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9846 struct bgp_path_info *path, int display,
9847 json_object *json_paths)
9848 {
9849 struct attr *attr;
9850 json_object *json_path = NULL;
9851 json_object *json_nexthop = NULL;
9852 json_object *json_overlay = NULL;
9853
9854 if (!path->extra)
9855 return;
9856
9857 if (json_paths) {
9858 json_path = json_object_new_object();
9859 json_overlay = json_object_new_object();
9860 json_nexthop = json_object_new_object();
9861 }
9862
9863 /* short status lead text */
9864 route_vty_short_status_out(vty, path, p, json_path);
9865
9866 /* print prefix and mask */
9867 if (!display)
9868 route_vty_out_route(path->net, p, vty, json_path, false);
9869 else
9870 vty_out(vty, "%*s", 17, " ");
9871
9872 /* Print attribute */
9873 attr = path->attr;
9874 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9875
9876 switch (af) {
9877 case AF_INET:
9878 if (!json_path) {
9879 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9880 } else {
9881 json_object_string_addf(json_nexthop, "ip", "%pI4",
9882 &attr->mp_nexthop_global_in);
9883
9884 json_object_string_add(json_nexthop, "afi", "ipv4");
9885
9886 json_object_object_add(json_path, "nexthop",
9887 json_nexthop);
9888 }
9889 break;
9890 case AF_INET6:
9891 if (!json_path) {
9892 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9893 &attr->mp_nexthop_local);
9894 } else {
9895 json_object_string_addf(json_nexthop, "ipv6Global",
9896 "%pI6",
9897 &attr->mp_nexthop_global);
9898
9899 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9900 "%pI6",
9901 &attr->mp_nexthop_local);
9902
9903 json_object_string_add(json_nexthop, "afi", "ipv6");
9904
9905 json_object_object_add(json_path, "nexthop",
9906 json_nexthop);
9907 }
9908 break;
9909 default:
9910 if (!json_path) {
9911 vty_out(vty, "?");
9912 } else {
9913 json_object_string_add(json_nexthop, "Error",
9914 "Unsupported address-family");
9915 json_object_string_add(json_nexthop, "error",
9916 "Unsupported address-family");
9917 }
9918 }
9919
9920 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9921
9922 if (!json_path)
9923 vty_out(vty, "/%pIA", &eo->gw_ip);
9924 else
9925 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9926
9927 if (bgp_attr_get_ecommunity(attr)) {
9928 char *mac = NULL;
9929 struct ecommunity_val *routermac = ecommunity_lookup(
9930 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9931 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9932
9933 if (routermac)
9934 mac = ecom_mac2str((char *)routermac->val);
9935 if (mac) {
9936 if (!json_path) {
9937 vty_out(vty, "/%s", mac);
9938 } else {
9939 json_object_string_add(json_overlay, "rmac",
9940 mac);
9941 }
9942 XFREE(MTYPE_TMP, mac);
9943 }
9944 }
9945
9946 if (!json_path) {
9947 vty_out(vty, "\n");
9948 } else {
9949 json_object_object_add(json_path, "overlay", json_overlay);
9950
9951 json_object_array_add(json_paths, json_path);
9952 }
9953 }
9954
9955 /* dampening route */
9956 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9957 struct bgp_path_info *path, int display,
9958 afi_t afi, safi_t safi, bool use_json,
9959 json_object *json_paths)
9960 {
9961 struct attr *attr = path->attr;
9962 int len;
9963 char timebuf[BGP_UPTIME_LEN];
9964 json_object *json_path = NULL;
9965
9966 if (use_json)
9967 json_path = json_object_new_object();
9968
9969 /* short status lead text */
9970 route_vty_short_status_out(vty, path, p, json_path);
9971
9972 /* print prefix and mask */
9973 if (!use_json) {
9974 if (!display)
9975 route_vty_out_route(path->net, p, vty, NULL, false);
9976 else
9977 vty_out(vty, "%*s", 17, " ");
9978
9979 len = vty_out(vty, "%s", path->peer->host);
9980 len = 17 - len;
9981
9982 if (len < 1)
9983 vty_out(vty, "\n%*s", 34, " ");
9984 else
9985 vty_out(vty, "%*s", len, " ");
9986
9987 vty_out(vty, "%s ",
9988 bgp_damp_reuse_time_vty(vty, path, timebuf,
9989 BGP_UPTIME_LEN, afi, safi,
9990 use_json, NULL));
9991
9992 if (attr->aspath)
9993 aspath_print_vty(vty, "%s", attr->aspath, " ");
9994
9995 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9996
9997 vty_out(vty, "\n");
9998 } else {
9999 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
10000 safi, use_json, json_path);
10001
10002 if (attr->aspath)
10003 json_object_string_add(json_path, "asPath",
10004 attr->aspath->str);
10005
10006 json_object_string_add(json_path, "origin",
10007 bgp_origin_str[attr->origin]);
10008 json_object_string_add(json_path, "peerHost", path->peer->host);
10009
10010 json_object_array_add(json_paths, json_path);
10011 }
10012 }
10013
10014 /* flap route */
10015 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
10016 struct bgp_path_info *path, int display,
10017 afi_t afi, safi_t safi, bool use_json,
10018 json_object *json_paths)
10019 {
10020 struct attr *attr = path->attr;
10021 struct bgp_damp_info *bdi;
10022 char timebuf[BGP_UPTIME_LEN];
10023 int len;
10024 json_object *json_path = NULL;
10025
10026 if (!path->extra)
10027 return;
10028
10029 if (use_json)
10030 json_path = json_object_new_object();
10031
10032 bdi = path->extra->damp_info;
10033
10034 /* short status lead text */
10035 route_vty_short_status_out(vty, path, p, json_path);
10036
10037 if (!use_json) {
10038 if (!display)
10039 route_vty_out_route(path->net, p, vty, NULL, false);
10040 else
10041 vty_out(vty, "%*s", 17, " ");
10042
10043 len = vty_out(vty, "%s", path->peer->host);
10044 len = 16 - len;
10045 if (len < 1)
10046 vty_out(vty, "\n%*s", 33, " ");
10047 else
10048 vty_out(vty, "%*s", len, " ");
10049
10050 len = vty_out(vty, "%d", bdi->flap);
10051 len = 5 - len;
10052 if (len < 1)
10053 vty_out(vty, " ");
10054 else
10055 vty_out(vty, "%*s", len, " ");
10056
10057 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10058 BGP_UPTIME_LEN, 0, NULL));
10059
10060 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10061 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10062 vty_out(vty, "%s ",
10063 bgp_damp_reuse_time_vty(vty, path, timebuf,
10064 BGP_UPTIME_LEN, afi,
10065 safi, use_json, NULL));
10066 else
10067 vty_out(vty, "%*s ", 8, " ");
10068
10069 if (attr->aspath)
10070 aspath_print_vty(vty, "%s", attr->aspath, " ");
10071
10072 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10073
10074 vty_out(vty, "\n");
10075 } else {
10076 json_object_string_add(json_path, "peerHost", path->peer->host);
10077 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10078
10079 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10080 json_path);
10081
10082 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10083 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10084 bgp_damp_reuse_time_vty(vty, path, timebuf,
10085 BGP_UPTIME_LEN, afi, safi,
10086 use_json, json_path);
10087
10088 if (attr->aspath)
10089 json_object_string_add(json_path, "asPath",
10090 attr->aspath->str);
10091
10092 json_object_string_add(json_path, "origin",
10093 bgp_origin_str[attr->origin]);
10094
10095 json_object_array_add(json_paths, json_path);
10096 }
10097 }
10098
10099 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10100 int *first, const char *header,
10101 json_object *json_adv_to)
10102 {
10103 json_object *json_peer = NULL;
10104
10105 if (json_adv_to) {
10106 /* 'advertised-to' is a dictionary of peers we have advertised
10107 * this
10108 * prefix too. The key is the peer's IP or swpX, the value is
10109 * the
10110 * hostname if we know it and "" if not.
10111 */
10112 json_peer = json_object_new_object();
10113
10114 if (peer->hostname)
10115 json_object_string_add(json_peer, "hostname",
10116 peer->hostname);
10117
10118 if (peer->conf_if)
10119 json_object_object_add(json_adv_to, peer->conf_if,
10120 json_peer);
10121 else
10122 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10123 &peer->su);
10124 } else {
10125 if (*first) {
10126 vty_out(vty, "%s", header);
10127 *first = 0;
10128 }
10129
10130 if (peer->hostname
10131 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10132 if (peer->conf_if)
10133 vty_out(vty, " %s(%s)", peer->hostname,
10134 peer->conf_if);
10135 else
10136 vty_out(vty, " %s(%pSU)", peer->hostname,
10137 &peer->su);
10138 } else {
10139 if (peer->conf_if)
10140 vty_out(vty, " %s", peer->conf_if);
10141 else
10142 vty_out(vty, " %pSU", &peer->su);
10143 }
10144 }
10145 }
10146
10147 static void route_vty_out_tx_ids(struct vty *vty,
10148 struct bgp_addpath_info_data *d)
10149 {
10150 int i;
10151
10152 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10153 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10154 d->addpath_tx_id[i],
10155 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10156 }
10157 }
10158
10159 static void route_vty_out_detail_es_info(struct vty *vty,
10160 struct bgp_path_info *pi,
10161 struct attr *attr,
10162 json_object *json_path)
10163 {
10164 char esi_buf[ESI_STR_LEN];
10165 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10166 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10167 ATTR_ES_PEER_ROUTER);
10168 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10169 ATTR_ES_PEER_ACTIVE);
10170 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10171 ATTR_ES_PEER_PROXY);
10172 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10173 if (json_path) {
10174 json_object *json_es_info = NULL;
10175
10176 json_object_string_add(
10177 json_path, "esi",
10178 esi_buf);
10179 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10180 json_es_info = json_object_new_object();
10181 if (es_local)
10182 json_object_boolean_true_add(
10183 json_es_info, "localEs");
10184 if (peer_active)
10185 json_object_boolean_true_add(
10186 json_es_info, "peerActive");
10187 if (peer_proxy)
10188 json_object_boolean_true_add(
10189 json_es_info, "peerProxy");
10190 if (peer_router)
10191 json_object_boolean_true_add(
10192 json_es_info, "peerRouter");
10193 if (attr->mm_sync_seqnum)
10194 json_object_int_add(
10195 json_es_info, "peerSeq",
10196 attr->mm_sync_seqnum);
10197 json_object_object_add(
10198 json_path, "es_info",
10199 json_es_info);
10200 }
10201 } else {
10202 if (bgp_evpn_attr_is_sync(attr))
10203 vty_out(vty,
10204 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10205 esi_buf,
10206 es_local ? "local-es":"",
10207 peer_proxy ? "proxy " : "",
10208 peer_active ? "active ":"",
10209 peer_router ? "router ":"",
10210 attr->mm_sync_seqnum);
10211 else
10212 vty_out(vty, " ESI %s %s\n",
10213 esi_buf,
10214 es_local ? "local-es":"");
10215 }
10216 }
10217
10218 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10219 struct bgp_path_info *path, afi_t afi, safi_t safi,
10220 enum rpki_states rpki_curr_state,
10221 json_object *json_paths)
10222 {
10223 char buf[INET6_ADDRSTRLEN];
10224 char buf1[BUFSIZ];
10225 struct attr *attr = path->attr;
10226 time_t tbuf;
10227 json_object *json_bestpath = NULL;
10228 json_object *json_cluster_list = NULL;
10229 json_object *json_cluster_list_list = NULL;
10230 json_object *json_ext_community = NULL;
10231 json_object *json_last_update = NULL;
10232 json_object *json_pmsi = NULL;
10233 json_object *json_nexthop_global = NULL;
10234 json_object *json_nexthop_ll = NULL;
10235 json_object *json_nexthops = NULL;
10236 json_object *json_path = NULL;
10237 json_object *json_peer = NULL;
10238 json_object *json_string = NULL;
10239 json_object *json_adv_to = NULL;
10240 int first = 0;
10241 struct listnode *node, *nnode;
10242 struct peer *peer;
10243 bool addpath_capable;
10244 int has_adj;
10245 unsigned int first_as;
10246 bool nexthop_self =
10247 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10248 int i;
10249 char *nexthop_hostname =
10250 bgp_nexthop_hostname(path->peer, path->nexthop);
10251 uint32_t ttl = 0;
10252 uint32_t bos = 0;
10253 uint32_t exp = 0;
10254 mpls_label_t label = MPLS_INVALID_LABEL;
10255
10256 if (json_paths) {
10257 json_path = json_object_new_object();
10258 json_peer = json_object_new_object();
10259 json_nexthop_global = json_object_new_object();
10260 }
10261
10262 if (safi == SAFI_EVPN) {
10263 if (!json_paths)
10264 vty_out(vty, " Route %pRN", bn);
10265 }
10266
10267 if (path->extra) {
10268 char tag_buf[30];
10269
10270 tag_buf[0] = '\0';
10271 if (path->extra && path->extra->num_labels) {
10272 bgp_evpn_label2str(path->extra->label,
10273 path->extra->num_labels, tag_buf,
10274 sizeof(tag_buf));
10275 }
10276 if (safi == SAFI_EVPN) {
10277 if (!json_paths) {
10278 if (tag_buf[0] != '\0')
10279 vty_out(vty, " VNI %s", tag_buf);
10280 } else {
10281 if (tag_buf[0]) {
10282 json_object_string_add(json_path, "VNI",
10283 tag_buf);
10284 json_object_string_add(json_path, "vni",
10285 tag_buf);
10286 }
10287 }
10288 }
10289
10290 if (path->extra && path->extra->parent && !json_paths) {
10291 struct bgp_path_info *parent_ri;
10292 struct bgp_dest *dest, *pdest;
10293
10294 parent_ri = (struct bgp_path_info *)path->extra->parent;
10295 dest = parent_ri->net;
10296 if (dest && dest->pdest) {
10297 pdest = dest->pdest;
10298 if (is_pi_family_evpn(parent_ri)) {
10299 vty_out(vty,
10300 " Imported from %pRD:%pFX, VNI %s",
10301 (struct prefix_rd *)
10302 bgp_dest_get_prefix(
10303 pdest),
10304 (struct prefix_evpn *)
10305 bgp_dest_get_prefix(
10306 dest),
10307 tag_buf);
10308 if (attr->es_flags & ATTR_ES_L3_NHG)
10309 vty_out(vty, ", L3NHG %s",
10310 (attr->es_flags
10311 & ATTR_ES_L3_NHG_ACTIVE)
10312 ? "active"
10313 : "inactive");
10314 vty_out(vty, "\n");
10315
10316 } else
10317 vty_out(vty,
10318 " Imported from %pRD:%pFX\n",
10319 (struct prefix_rd *)
10320 bgp_dest_get_prefix(
10321 pdest),
10322 (struct prefix_evpn *)
10323 bgp_dest_get_prefix(
10324 dest));
10325 }
10326 }
10327 }
10328
10329 if (safi == SAFI_EVPN
10330 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10331 char gwip_buf[INET6_ADDRSTRLEN];
10332
10333 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10334 sizeof(gwip_buf));
10335
10336 if (json_paths)
10337 json_object_string_add(json_path, "gatewayIP",
10338 gwip_buf);
10339 else
10340 vty_out(vty, " Gateway IP %s", gwip_buf);
10341 }
10342
10343 if (safi == SAFI_EVPN && !json_path)
10344 vty_out(vty, "\n");
10345
10346 /* Line1 display AS-path, Aggregator */
10347 if (attr->aspath) {
10348 if (json_paths) {
10349 if (!attr->aspath->json)
10350 aspath_str_update(attr->aspath, true);
10351 json_object_lock(attr->aspath->json);
10352 json_object_object_add(json_path, "aspath",
10353 attr->aspath->json);
10354 } else {
10355 if (attr->aspath->segments)
10356 aspath_print_vty(vty, " %s", attr->aspath, "");
10357 else
10358 vty_out(vty, " Local");
10359 }
10360 }
10361
10362 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10363 if (json_paths)
10364 json_object_boolean_true_add(json_path, "removed");
10365 else
10366 vty_out(vty, ", (removed)");
10367 }
10368
10369 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10370 if (json_paths)
10371 json_object_boolean_true_add(json_path, "stale");
10372 else
10373 vty_out(vty, ", (stale)");
10374 }
10375
10376 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10377 if (json_paths) {
10378 json_object_int_add(json_path, "aggregatorAs",
10379 attr->aggregator_as);
10380 json_object_string_addf(json_path, "aggregatorId",
10381 "%pI4", &attr->aggregator_addr);
10382 } else {
10383 vty_out(vty, ", (aggregated by %u %pI4)",
10384 attr->aggregator_as, &attr->aggregator_addr);
10385 }
10386 }
10387
10388 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10389 PEER_FLAG_REFLECTOR_CLIENT)) {
10390 if (json_paths)
10391 json_object_boolean_true_add(json_path,
10392 "rxedFromRrClient");
10393 else
10394 vty_out(vty, ", (Received from a RR-client)");
10395 }
10396
10397 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10398 PEER_FLAG_RSERVER_CLIENT)) {
10399 if (json_paths)
10400 json_object_boolean_true_add(json_path,
10401 "rxedFromRsClient");
10402 else
10403 vty_out(vty, ", (Received from a RS-client)");
10404 }
10405
10406 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10407 if (json_paths)
10408 json_object_boolean_true_add(json_path,
10409 "dampeningHistoryEntry");
10410 else
10411 vty_out(vty, ", (history entry)");
10412 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10413 if (json_paths)
10414 json_object_boolean_true_add(json_path,
10415 "dampeningSuppressed");
10416 else
10417 vty_out(vty, ", (suppressed due to dampening)");
10418 }
10419
10420 if (!json_paths)
10421 vty_out(vty, "\n");
10422
10423 /* Line2 display Next-hop, Neighbor, Router-id */
10424 /* Display the nexthop */
10425 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10426
10427 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET ||
10428 bn_p->family == AF_EVPN) &&
10429 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10430 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10431 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10432 || safi == SAFI_EVPN) {
10433 if (json_paths) {
10434 json_object_string_addf(
10435 json_nexthop_global, "ip", "%pI4",
10436 &attr->mp_nexthop_global_in);
10437
10438 if (path->peer->hostname)
10439 json_object_string_add(
10440 json_nexthop_global, "hostname",
10441 path->peer->hostname);
10442 } else {
10443 if (nexthop_hostname)
10444 vty_out(vty, " %pI4(%s)",
10445 &attr->mp_nexthop_global_in,
10446 nexthop_hostname);
10447 else
10448 vty_out(vty, " %pI4",
10449 &attr->mp_nexthop_global_in);
10450 }
10451 } else {
10452 if (json_paths) {
10453 json_object_string_addf(json_nexthop_global,
10454 "ip", "%pI4",
10455 &attr->nexthop);
10456
10457 if (path->peer->hostname)
10458 json_object_string_add(
10459 json_nexthop_global, "hostname",
10460 path->peer->hostname);
10461 } else {
10462 if (nexthop_hostname)
10463 vty_out(vty, " %pI4(%s)",
10464 &attr->nexthop,
10465 nexthop_hostname);
10466 else
10467 vty_out(vty, " %pI4",
10468 &attr->nexthop);
10469 }
10470 }
10471
10472 if (json_paths)
10473 json_object_string_add(json_nexthop_global, "afi",
10474 "ipv4");
10475 } else {
10476 if (json_paths) {
10477 json_object_string_addf(json_nexthop_global, "ip",
10478 "%pI6",
10479 &attr->mp_nexthop_global);
10480
10481 if (path->peer->hostname)
10482 json_object_string_add(json_nexthop_global,
10483 "hostname",
10484 path->peer->hostname);
10485
10486 json_object_string_add(json_nexthop_global, "afi",
10487 "ipv6");
10488 json_object_string_add(json_nexthop_global, "scope",
10489 "global");
10490 } else {
10491 if (nexthop_hostname)
10492 vty_out(vty, " %pI6(%s)",
10493 &attr->mp_nexthop_global,
10494 nexthop_hostname);
10495 else
10496 vty_out(vty, " %pI6",
10497 &attr->mp_nexthop_global);
10498 }
10499 }
10500
10501 /* Display the IGP cost or 'inaccessible' */
10502 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10503 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10504
10505 if (json_paths) {
10506 json_object_boolean_false_add(json_nexthop_global,
10507 "accessible");
10508 json_object_boolean_add(json_nexthop_global,
10509 "importCheckEnabled", import);
10510 } else {
10511 vty_out(vty, " (inaccessible%s)",
10512 import ? ", import-check enabled" : "");
10513 }
10514 } else {
10515 if (path->extra && path->extra->igpmetric) {
10516 if (json_paths)
10517 json_object_int_add(json_nexthop_global,
10518 "metric",
10519 path->extra->igpmetric);
10520 else
10521 vty_out(vty, " (metric %u)",
10522 path->extra->igpmetric);
10523 }
10524
10525 /* IGP cost is 0, display this only for json */
10526 else {
10527 if (json_paths)
10528 json_object_int_add(json_nexthop_global,
10529 "metric", 0);
10530 }
10531
10532 if (json_paths)
10533 json_object_boolean_true_add(json_nexthop_global,
10534 "accessible");
10535 }
10536
10537 /* Display peer "from" output */
10538 /* This path was originated locally */
10539 if (path->peer == bgp->peer_self) {
10540
10541 if (safi == SAFI_EVPN || (bn_p->family == AF_INET &&
10542 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10543 if (json_paths)
10544 json_object_string_add(json_peer, "peerId",
10545 "0.0.0.0");
10546 else
10547 vty_out(vty, " from 0.0.0.0 ");
10548 } else {
10549 if (json_paths)
10550 json_object_string_add(json_peer, "peerId",
10551 "::");
10552 else
10553 vty_out(vty, " from :: ");
10554 }
10555
10556 if (json_paths)
10557 json_object_string_addf(json_peer, "routerId", "%pI4",
10558 &bgp->router_id);
10559 else
10560 vty_out(vty, "(%pI4)", &bgp->router_id);
10561 }
10562
10563 /* We RXed this path from one of our peers */
10564 else {
10565
10566 if (json_paths) {
10567 json_object_string_addf(json_peer, "peerId", "%pSU",
10568 &path->peer->su);
10569 json_object_string_addf(json_peer, "routerId", "%pI4",
10570 &path->peer->remote_id);
10571
10572 if (path->peer->hostname)
10573 json_object_string_add(json_peer, "hostname",
10574 path->peer->hostname);
10575
10576 if (path->peer->domainname)
10577 json_object_string_add(json_peer, "domainname",
10578 path->peer->domainname);
10579
10580 if (path->peer->conf_if)
10581 json_object_string_add(json_peer, "interface",
10582 path->peer->conf_if);
10583 } else {
10584 if (path->peer->conf_if) {
10585 if (path->peer->hostname
10586 && CHECK_FLAG(path->peer->bgp->flags,
10587 BGP_FLAG_SHOW_HOSTNAME))
10588 vty_out(vty, " from %s(%s)",
10589 path->peer->hostname,
10590 path->peer->conf_if);
10591 else
10592 vty_out(vty, " from %s",
10593 path->peer->conf_if);
10594 } else {
10595 if (path->peer->hostname
10596 && CHECK_FLAG(path->peer->bgp->flags,
10597 BGP_FLAG_SHOW_HOSTNAME))
10598 vty_out(vty, " from %s(%s)",
10599 path->peer->hostname,
10600 path->peer->host);
10601 else
10602 vty_out(vty, " from %pSU",
10603 &path->peer->su);
10604 }
10605
10606 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10607 vty_out(vty, " (%pI4)", &attr->originator_id);
10608 else
10609 vty_out(vty, " (%s)",
10610 inet_ntop(AF_INET,
10611 &path->peer->remote_id, buf1,
10612 sizeof(buf1)));
10613 }
10614 }
10615
10616 /*
10617 * Note when vrfid of nexthop is different from that of prefix
10618 */
10619 if (path->extra && path->extra->bgp_orig) {
10620 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10621
10622 if (json_paths) {
10623 const char *vn;
10624
10625 if (path->extra->bgp_orig->inst_type
10626 == BGP_INSTANCE_TYPE_DEFAULT)
10627 vn = VRF_DEFAULT_NAME;
10628 else
10629 vn = path->extra->bgp_orig->name;
10630
10631 json_object_string_add(json_path, "nhVrfName", vn);
10632
10633 if (nexthop_vrfid == VRF_UNKNOWN) {
10634 json_object_int_add(json_path, "nhVrfId", -1);
10635 } else {
10636 json_object_int_add(json_path, "nhVrfId",
10637 (int)nexthop_vrfid);
10638 }
10639 } else {
10640 if (nexthop_vrfid == VRF_UNKNOWN)
10641 vty_out(vty, " vrf ?");
10642 else {
10643 struct vrf *vrf;
10644
10645 vrf = vrf_lookup_by_id(nexthop_vrfid);
10646 vty_out(vty, " vrf %s(%u)",
10647 VRF_LOGNAME(vrf), nexthop_vrfid);
10648 }
10649 }
10650 }
10651
10652 if (nexthop_self) {
10653 if (json_paths) {
10654 json_object_boolean_true_add(json_path,
10655 "announceNexthopSelf");
10656 } else {
10657 vty_out(vty, " announce-nh-self");
10658 }
10659 }
10660
10661 if (!json_paths)
10662 vty_out(vty, "\n");
10663
10664 /* display the link-local nexthop */
10665 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10666 if (json_paths) {
10667 json_nexthop_ll = json_object_new_object();
10668 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10669 &attr->mp_nexthop_local);
10670
10671 if (path->peer->hostname)
10672 json_object_string_add(json_nexthop_ll,
10673 "hostname",
10674 path->peer->hostname);
10675
10676 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10677 json_object_string_add(json_nexthop_ll, "scope",
10678 "link-local");
10679
10680 json_object_boolean_true_add(json_nexthop_ll,
10681 "accessible");
10682
10683 if (!attr->mp_nexthop_prefer_global)
10684 json_object_boolean_true_add(json_nexthop_ll,
10685 "used");
10686 else
10687 json_object_boolean_true_add(
10688 json_nexthop_global, "used");
10689 } else {
10690 vty_out(vty, " (%s) %s\n",
10691 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10692 buf, INET6_ADDRSTRLEN),
10693 attr->mp_nexthop_prefer_global
10694 ? "(prefer-global)"
10695 : "(used)");
10696 }
10697 }
10698 /* If we do not have a link-local nexthop then we must flag the
10699 global as "used" */
10700 else {
10701 if (json_paths)
10702 json_object_boolean_true_add(json_nexthop_global,
10703 "used");
10704 }
10705
10706 if (safi == SAFI_EVPN &&
10707 bgp_evpn_is_esi_valid(&attr->esi)) {
10708 route_vty_out_detail_es_info(vty, path, attr, json_path);
10709 }
10710
10711 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10712 * Int/Ext/Local, Atomic, best */
10713 if (json_paths)
10714 json_object_string_add(json_path, "origin",
10715 bgp_origin_long_str[attr->origin]);
10716 else
10717 vty_out(vty, " Origin %s",
10718 bgp_origin_long_str[attr->origin]);
10719
10720 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10721 if (json_paths)
10722 json_object_int_add(json_path, "metric", attr->med);
10723 else
10724 vty_out(vty, ", metric %u", attr->med);
10725 }
10726
10727 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10728 if (json_paths)
10729 json_object_int_add(json_path, "locPrf",
10730 attr->local_pref);
10731 else
10732 vty_out(vty, ", localpref %u", attr->local_pref);
10733 }
10734
10735 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10736 if (json_paths)
10737 json_object_int_add(json_path, "aigpMetric",
10738 bgp_attr_get_aigp_metric(attr));
10739 else
10740 vty_out(vty, ", aigp-metric %" PRIu64,
10741 bgp_attr_get_aigp_metric(attr));
10742 }
10743
10744 if (attr->weight != 0) {
10745 if (json_paths)
10746 json_object_int_add(json_path, "weight", attr->weight);
10747 else
10748 vty_out(vty, ", weight %u", attr->weight);
10749 }
10750
10751 if (attr->tag != 0) {
10752 if (json_paths)
10753 json_object_int_add(json_path, "tag", attr->tag);
10754 else
10755 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10756 }
10757
10758 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10759 if (json_paths)
10760 json_object_boolean_false_add(json_path, "valid");
10761 else
10762 vty_out(vty, ", invalid");
10763 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10764 if (json_paths)
10765 json_object_boolean_true_add(json_path, "valid");
10766 else
10767 vty_out(vty, ", valid");
10768 }
10769
10770 if (json_paths)
10771 json_object_int_add(json_path, "version", bn->version);
10772
10773 if (path->peer != bgp->peer_self) {
10774 if (path->peer->as == path->peer->local_as) {
10775 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10776 if (json_paths)
10777 json_object_string_add(
10778 json_peer, "type",
10779 "confed-internal");
10780 else
10781 vty_out(vty, ", confed-internal");
10782 } else {
10783 if (json_paths)
10784 json_object_string_add(
10785 json_peer, "type", "internal");
10786 else
10787 vty_out(vty, ", internal");
10788 }
10789 } else {
10790 if (bgp_confederation_peers_check(bgp,
10791 path->peer->as)) {
10792 if (json_paths)
10793 json_object_string_add(
10794 json_peer, "type",
10795 "confed-external");
10796 else
10797 vty_out(vty, ", confed-external");
10798 } else {
10799 if (json_paths)
10800 json_object_string_add(
10801 json_peer, "type", "external");
10802 else
10803 vty_out(vty, ", external");
10804 }
10805 }
10806 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10807 if (json_paths) {
10808 json_object_boolean_true_add(json_path, "aggregated");
10809 json_object_boolean_true_add(json_path, "local");
10810 } else {
10811 vty_out(vty, ", aggregated, local");
10812 }
10813 } else if (path->type != ZEBRA_ROUTE_BGP) {
10814 if (json_paths)
10815 json_object_boolean_true_add(json_path, "sourced");
10816 else
10817 vty_out(vty, ", sourced");
10818 } else {
10819 if (json_paths) {
10820 json_object_boolean_true_add(json_path, "sourced");
10821 json_object_boolean_true_add(json_path, "local");
10822 } else {
10823 vty_out(vty, ", sourced, local");
10824 }
10825 }
10826
10827 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10828 if (json_paths)
10829 json_object_boolean_true_add(json_path,
10830 "atomicAggregate");
10831 else
10832 vty_out(vty, ", atomic-aggregate");
10833 }
10834
10835 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10836 if (json_paths)
10837 json_object_int_add(json_path, "otc", attr->otc);
10838 else
10839 vty_out(vty, ", otc %u", attr->otc);
10840 }
10841
10842 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10843 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10844 && bgp_path_info_mpath_count(path))) {
10845 if (json_paths)
10846 json_object_boolean_true_add(json_path, "multipath");
10847 else
10848 vty_out(vty, ", multipath");
10849 }
10850
10851 // Mark the bestpath(s)
10852 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10853 first_as = aspath_get_first_as(attr->aspath);
10854
10855 if (json_paths) {
10856 if (!json_bestpath)
10857 json_bestpath = json_object_new_object();
10858 json_object_int_add(json_bestpath, "bestpathFromAs",
10859 first_as);
10860 } else {
10861 if (first_as)
10862 vty_out(vty, ", bestpath-from-AS %u", first_as);
10863 else
10864 vty_out(vty, ", bestpath-from-AS Local");
10865 }
10866 }
10867
10868 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10869 if (json_paths) {
10870 if (!json_bestpath)
10871 json_bestpath = json_object_new_object();
10872 json_object_boolean_true_add(json_bestpath, "overall");
10873 json_object_string_add(
10874 json_bestpath, "selectionReason",
10875 bgp_path_selection_reason2str(bn->reason));
10876 } else {
10877 vty_out(vty, ", best");
10878 vty_out(vty, " (%s)",
10879 bgp_path_selection_reason2str(bn->reason));
10880 }
10881 }
10882
10883 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10884 if (json_paths)
10885 json_object_string_add(
10886 json_path, "rpkiValidationState",
10887 bgp_rpki_validation2str(rpki_curr_state));
10888 else
10889 vty_out(vty, ", rpki validation-state: %s",
10890 bgp_rpki_validation2str(rpki_curr_state));
10891 }
10892
10893 if (json_bestpath)
10894 json_object_object_add(json_path, "bestpath", json_bestpath);
10895
10896 if (!json_paths)
10897 vty_out(vty, "\n");
10898
10899 /* Line 4 display Community */
10900 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10901 if (json_paths) {
10902 if (!bgp_attr_get_community(attr)->json)
10903 community_str(bgp_attr_get_community(attr),
10904 true, true);
10905 json_object_lock(bgp_attr_get_community(attr)->json);
10906 json_object_object_add(
10907 json_path, "community",
10908 bgp_attr_get_community(attr)->json);
10909 } else {
10910 vty_out(vty, " Community: %s\n",
10911 bgp_attr_get_community(attr)->str);
10912 }
10913 }
10914
10915 /* Line 5 display Extended-community */
10916 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10917 if (json_paths) {
10918 json_ext_community = json_object_new_object();
10919 json_object_string_add(
10920 json_ext_community, "string",
10921 bgp_attr_get_ecommunity(attr)->str);
10922 json_object_object_add(json_path, "extendedCommunity",
10923 json_ext_community);
10924 } else {
10925 vty_out(vty, " Extended Community: %s\n",
10926 bgp_attr_get_ecommunity(attr)->str);
10927 }
10928 }
10929
10930 /* Line 6 display Large community */
10931 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10932 if (json_paths) {
10933 if (!bgp_attr_get_lcommunity(attr)->json)
10934 lcommunity_str(bgp_attr_get_lcommunity(attr),
10935 true, true);
10936 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10937 json_object_object_add(
10938 json_path, "largeCommunity",
10939 bgp_attr_get_lcommunity(attr)->json);
10940 } else {
10941 vty_out(vty, " Large Community: %s\n",
10942 bgp_attr_get_lcommunity(attr)->str);
10943 }
10944 }
10945
10946 /* Line 7 display Originator, Cluster-id */
10947 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10948 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10949 char buf[BUFSIZ] = {0};
10950
10951 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10952 if (json_paths)
10953 json_object_string_addf(json_path,
10954 "originatorId", "%pI4",
10955 &attr->originator_id);
10956 else
10957 vty_out(vty, " Originator: %pI4",
10958 &attr->originator_id);
10959 }
10960
10961 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10962 struct cluster_list *cluster =
10963 bgp_attr_get_cluster(attr);
10964 int i;
10965
10966 if (json_paths) {
10967 json_cluster_list = json_object_new_object();
10968 json_cluster_list_list =
10969 json_object_new_array();
10970
10971 for (i = 0; i < cluster->length / 4; i++) {
10972 json_string = json_object_new_string(
10973 inet_ntop(AF_INET,
10974 &cluster->list[i],
10975 buf, sizeof(buf)));
10976 json_object_array_add(
10977 json_cluster_list_list,
10978 json_string);
10979 }
10980
10981 /*
10982 * struct cluster_list does not have
10983 * "str" variable like aspath and community
10984 * do. Add this someday if someone asks
10985 * for it.
10986 * json_object_string_add(json_cluster_list,
10987 * "string", cluster->str);
10988 */
10989 json_object_object_add(json_cluster_list,
10990 "list",
10991 json_cluster_list_list);
10992 json_object_object_add(json_path, "clusterList",
10993 json_cluster_list);
10994 } else {
10995 vty_out(vty, ", Cluster list: ");
10996
10997 for (i = 0; i < cluster->length / 4; i++) {
10998 vty_out(vty, "%pI4 ",
10999 &cluster->list[i]);
11000 }
11001 }
11002 }
11003
11004 if (!json_paths)
11005 vty_out(vty, "\n");
11006 }
11007
11008 if (path->extra && path->extra->damp_info)
11009 bgp_damp_info_vty(vty, path, afi, safi, json_path);
11010
11011 /* Remote Label */
11012 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
11013 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
11014 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
11015 &bos);
11016
11017 if (json_paths)
11018 json_object_int_add(json_path, "remoteLabel", label);
11019 else
11020 vty_out(vty, " Remote label: %d\n", label);
11021 }
11022
11023 /* Remote SID */
11024 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
11025 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
11026 if (json_paths)
11027 json_object_string_add(json_path, "remoteSid", buf);
11028 else
11029 vty_out(vty, " Remote SID: %s\n", buf);
11030 }
11031
11032 /* Label Index */
11033 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11034 if (json_paths)
11035 json_object_int_add(json_path, "labelIndex",
11036 attr->label_index);
11037 else
11038 vty_out(vty, " Label Index: %d\n",
11039 attr->label_index);
11040 }
11041
11042 /* Line 8 display Addpath IDs */
11043 if (path->addpath_rx_id
11044 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11045 if (json_paths) {
11046 json_object_int_add(json_path, "addpathRxId",
11047 path->addpath_rx_id);
11048
11049 /* Keep backwards compatibility with the old API
11050 * by putting TX All's ID in the old field
11051 */
11052 json_object_int_add(
11053 json_path, "addpathTxId",
11054 path->tx_addpath
11055 .addpath_tx_id[BGP_ADDPATH_ALL]);
11056
11057 /* ... but create a specific field for each
11058 * strategy
11059 */
11060 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11061 json_object_int_add(
11062 json_path,
11063 bgp_addpath_names(i)->id_json_name,
11064 path->tx_addpath.addpath_tx_id[i]);
11065 }
11066 } else {
11067 vty_out(vty, " AddPath ID: RX %u, ",
11068 path->addpath_rx_id);
11069
11070 route_vty_out_tx_ids(vty, &path->tx_addpath);
11071 }
11072 }
11073
11074 /* If we used addpath to TX a non-bestpath we need to display
11075 * "Advertised to" on a path-by-path basis
11076 */
11077 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11078 first = 1;
11079
11080 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11081 addpath_capable =
11082 bgp_addpath_encode_tx(peer, afi, safi);
11083 has_adj = bgp_adj_out_lookup(
11084 peer, path->net,
11085 bgp_addpath_id_for_peer(peer, afi, safi,
11086 &path->tx_addpath));
11087
11088 if ((addpath_capable && has_adj)
11089 || (!addpath_capable && has_adj
11090 && CHECK_FLAG(path->flags,
11091 BGP_PATH_SELECTED))) {
11092 if (json_path && !json_adv_to)
11093 json_adv_to = json_object_new_object();
11094
11095 route_vty_out_advertised_to(
11096 vty, peer, &first,
11097 " Advertised to:", json_adv_to);
11098 }
11099 }
11100
11101 if (json_path) {
11102 if (json_adv_to) {
11103 json_object_object_add(
11104 json_path, "advertisedTo", json_adv_to);
11105 }
11106 } else {
11107 if (!first) {
11108 vty_out(vty, "\n");
11109 }
11110 }
11111 }
11112
11113 /* Line 9 display Uptime */
11114 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11115 if (json_paths) {
11116 json_last_update = json_object_new_object();
11117 json_object_int_add(json_last_update, "epoch", tbuf);
11118 json_object_string_add(json_last_update, "string",
11119 ctime(&tbuf));
11120 json_object_object_add(json_path, "lastUpdate",
11121 json_last_update);
11122 } else
11123 vty_out(vty, " Last update: %s", ctime(&tbuf));
11124
11125 /* Line 10 display PMSI tunnel attribute, if present */
11126 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11127 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11128 bgp_attr_get_pmsi_tnl_type(attr),
11129 PMSI_TNLTYPE_STR_DEFAULT);
11130
11131 if (json_paths) {
11132 json_pmsi = json_object_new_object();
11133 json_object_string_add(json_pmsi, "tunnelType", str);
11134 json_object_int_add(json_pmsi, "label",
11135 label2vni(&attr->label));
11136 json_object_object_add(json_path, "pmsi", json_pmsi);
11137 } else
11138 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11139 str, label2vni(&attr->label));
11140 }
11141
11142 if (path->peer->t_gr_restart &&
11143 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11144 unsigned long gr_remaining =
11145 thread_timer_remain_second(path->peer->t_gr_restart);
11146
11147 if (json_paths) {
11148 json_object_int_add(json_path,
11149 "gracefulRestartSecondsRemaining",
11150 gr_remaining);
11151 } else
11152 vty_out(vty,
11153 " Time until Graceful Restart stale route deleted: %lu\n",
11154 gr_remaining);
11155 }
11156
11157 if (path->peer->t_llgr_stale[afi][safi] &&
11158 bgp_attr_get_community(attr) &&
11159 community_include(bgp_attr_get_community(attr),
11160 COMMUNITY_LLGR_STALE)) {
11161 unsigned long llgr_remaining = thread_timer_remain_second(
11162 path->peer->t_llgr_stale[afi][safi]);
11163
11164 if (json_paths) {
11165 json_object_int_add(json_path, "llgrSecondsRemaining",
11166 llgr_remaining);
11167 } else
11168 vty_out(vty,
11169 " Time until Long-lived stale route deleted: %lu\n",
11170 llgr_remaining);
11171 }
11172
11173 /* Output some debug about internal state of the dest flags */
11174 if (json_paths) {
11175 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11176 json_object_boolean_true_add(json_path, "processScheduled");
11177 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11178 json_object_boolean_true_add(json_path, "userCleared");
11179 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11180 json_object_boolean_true_add(json_path, "labelChanged");
11181 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11182 json_object_boolean_true_add(json_path, "registeredForLabel");
11183 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11184 json_object_boolean_true_add(json_path, "selectDefered");
11185 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11186 json_object_boolean_true_add(json_path, "fibInstalled");
11187 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11188 json_object_boolean_true_add(json_path, "fibPending");
11189
11190 if (json_nexthop_global || json_nexthop_ll) {
11191 json_nexthops = json_object_new_array();
11192
11193 if (json_nexthop_global)
11194 json_object_array_add(json_nexthops,
11195 json_nexthop_global);
11196
11197 if (json_nexthop_ll)
11198 json_object_array_add(json_nexthops,
11199 json_nexthop_ll);
11200
11201 json_object_object_add(json_path, "nexthops",
11202 json_nexthops);
11203 }
11204
11205 json_object_object_add(json_path, "peer", json_peer);
11206 json_object_array_add(json_paths, json_path);
11207 }
11208 }
11209
11210 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11211 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11212 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11213
11214 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11215 afi_t afi, safi_t safi, enum bgp_show_type type,
11216 bool use_json);
11217 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11218 const char *comstr, int exact, afi_t afi,
11219 safi_t safi, uint16_t show_flags);
11220
11221 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11222 struct bgp_table *table, enum bgp_show_type type,
11223 void *output_arg, const char *rd, int is_last,
11224 unsigned long *output_cum, unsigned long *total_cum,
11225 unsigned long *json_header_depth, uint16_t show_flags,
11226 enum rpki_states rpki_target_state)
11227 {
11228 struct bgp_path_info *pi;
11229 struct bgp_dest *dest;
11230 bool header = true;
11231 bool json_detail_header = false;
11232 int display;
11233 unsigned long output_count = 0;
11234 unsigned long total_count = 0;
11235 struct prefix *p;
11236 json_object *json_paths = NULL;
11237 int first = 1;
11238 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11239 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11240 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11241
11242 if (output_cum && *output_cum != 0)
11243 header = false;
11244
11245 if (use_json && !*json_header_depth) {
11246 if (all)
11247 *json_header_depth = 1;
11248 else {
11249 vty_out(vty, "{\n");
11250 *json_header_depth = 2;
11251 }
11252
11253 vty_out(vty,
11254 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11255 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11256 " \"localAS\": %u,\n \"routes\": { ",
11257 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11258 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11259 ? VRF_DEFAULT_NAME
11260 : bgp->name,
11261 table->version, &bgp->router_id,
11262 bgp->default_local_pref, bgp->as);
11263 if (rd) {
11264 vty_out(vty, " \"routeDistinguishers\" : {");
11265 ++*json_header_depth;
11266 }
11267 }
11268
11269 if (use_json && rd) {
11270 vty_out(vty, " \"%s\" : { ", rd);
11271 }
11272
11273 /* Check for 'json detail', where we need header output once per dest */
11274 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
11275 type != bgp_show_type_dampend_paths &&
11276 type != bgp_show_type_damp_neighbor &&
11277 type != bgp_show_type_flap_statistics &&
11278 type != bgp_show_type_flap_neighbor)
11279 json_detail_header = true;
11280
11281 /* Start processing of routes. */
11282 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11283 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11284 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11285 bool json_detail = json_detail_header;
11286
11287 pi = bgp_dest_get_bgp_path_info(dest);
11288 if (pi == NULL)
11289 continue;
11290
11291 display = 0;
11292 if (use_json)
11293 json_paths = json_object_new_array();
11294 else
11295 json_paths = NULL;
11296
11297 for (; pi; pi = pi->next) {
11298 struct community *picomm = NULL;
11299
11300 picomm = bgp_attr_get_community(pi->attr);
11301
11302 total_count++;
11303
11304 if (type == bgp_show_type_prefix_version) {
11305 uint32_t version =
11306 strtoul(output_arg, NULL, 10);
11307 if (dest->version < version)
11308 continue;
11309 }
11310
11311 if (type == bgp_show_type_community_alias) {
11312 char *alias = output_arg;
11313 char **communities;
11314 int num;
11315 bool found = false;
11316
11317 if (picomm) {
11318 frrstr_split(picomm->str, " ",
11319 &communities, &num);
11320 for (int i = 0; i < num; i++) {
11321 const char *com2alias =
11322 bgp_community2alias(
11323 communities[i]);
11324 if (!found
11325 && strcmp(alias, com2alias)
11326 == 0)
11327 found = true;
11328 XFREE(MTYPE_TMP,
11329 communities[i]);
11330 }
11331 XFREE(MTYPE_TMP, communities);
11332 }
11333
11334 if (!found &&
11335 bgp_attr_get_lcommunity(pi->attr)) {
11336 frrstr_split(bgp_attr_get_lcommunity(
11337 pi->attr)
11338 ->str,
11339 " ", &communities, &num);
11340 for (int i = 0; i < num; i++) {
11341 const char *com2alias =
11342 bgp_community2alias(
11343 communities[i]);
11344 if (!found
11345 && strcmp(alias, com2alias)
11346 == 0)
11347 found = true;
11348 XFREE(MTYPE_TMP,
11349 communities[i]);
11350 }
11351 XFREE(MTYPE_TMP, communities);
11352 }
11353
11354 if (!found)
11355 continue;
11356 }
11357
11358 if (type == bgp_show_type_rpki) {
11359 if (dest_p->family == AF_INET
11360 || dest_p->family == AF_INET6)
11361 rpki_curr_state = hook_call(
11362 bgp_rpki_prefix_status,
11363 pi->peer, pi->attr, dest_p);
11364 if (rpki_target_state != RPKI_NOT_BEING_USED
11365 && rpki_curr_state != rpki_target_state)
11366 continue;
11367 }
11368
11369 if (type == bgp_show_type_flap_statistics
11370 || type == bgp_show_type_flap_neighbor
11371 || type == bgp_show_type_dampend_paths
11372 || type == bgp_show_type_damp_neighbor) {
11373 if (!(pi->extra && pi->extra->damp_info))
11374 continue;
11375 }
11376 if (type == bgp_show_type_regexp) {
11377 regex_t *regex = output_arg;
11378
11379 if (bgp_regexec(regex, pi->attr->aspath)
11380 == REG_NOMATCH)
11381 continue;
11382 }
11383 if (type == bgp_show_type_prefix_list) {
11384 struct prefix_list *plist = output_arg;
11385
11386 if (prefix_list_apply(plist, dest_p)
11387 != PREFIX_PERMIT)
11388 continue;
11389 }
11390 if (type == bgp_show_type_access_list) {
11391 struct access_list *alist = output_arg;
11392
11393 if (access_list_apply(alist, dest_p) !=
11394 FILTER_PERMIT)
11395 continue;
11396 }
11397 if (type == bgp_show_type_filter_list) {
11398 struct as_list *as_list = output_arg;
11399
11400 if (as_list_apply(as_list, pi->attr->aspath)
11401 != AS_FILTER_PERMIT)
11402 continue;
11403 }
11404 if (type == bgp_show_type_route_map) {
11405 struct route_map *rmap = output_arg;
11406 struct bgp_path_info path;
11407 struct bgp_path_info_extra extra;
11408 struct attr dummy_attr = {};
11409 route_map_result_t ret;
11410
11411 dummy_attr = *pi->attr;
11412
11413 prep_for_rmap_apply(&path, &extra, dest, pi,
11414 pi->peer, &dummy_attr);
11415
11416 ret = route_map_apply(rmap, dest_p, &path);
11417 bgp_attr_flush(&dummy_attr);
11418 if (ret == RMAP_DENYMATCH)
11419 continue;
11420 }
11421 if (type == bgp_show_type_neighbor
11422 || type == bgp_show_type_flap_neighbor
11423 || type == bgp_show_type_damp_neighbor) {
11424 union sockunion *su = output_arg;
11425
11426 if (pi->peer == NULL
11427 || pi->peer->su_remote == NULL
11428 || !sockunion_same(pi->peer->su_remote, su))
11429 continue;
11430 }
11431 if (type == bgp_show_type_cidr_only) {
11432 uint32_t destination;
11433
11434 destination = ntohl(dest_p->u.prefix4.s_addr);
11435 if (IN_CLASSC(destination)
11436 && dest_p->prefixlen == 24)
11437 continue;
11438 if (IN_CLASSB(destination)
11439 && dest_p->prefixlen == 16)
11440 continue;
11441 if (IN_CLASSA(destination)
11442 && dest_p->prefixlen == 8)
11443 continue;
11444 }
11445 if (type == bgp_show_type_prefix_longer) {
11446 p = output_arg;
11447 if (!prefix_match(p, dest_p))
11448 continue;
11449 }
11450 if (type == bgp_show_type_community_all) {
11451 if (!picomm)
11452 continue;
11453 }
11454 if (type == bgp_show_type_community) {
11455 struct community *com = output_arg;
11456
11457 if (!picomm || !community_match(picomm, com))
11458 continue;
11459 }
11460 if (type == bgp_show_type_community_exact) {
11461 struct community *com = output_arg;
11462
11463 if (!picomm || !community_cmp(picomm, com))
11464 continue;
11465 }
11466 if (type == bgp_show_type_community_list) {
11467 struct community_list *list = output_arg;
11468
11469 if (!community_list_match(picomm, list))
11470 continue;
11471 }
11472 if (type == bgp_show_type_community_list_exact) {
11473 struct community_list *list = output_arg;
11474
11475 if (!community_list_exact_match(picomm, list))
11476 continue;
11477 }
11478 if (type == bgp_show_type_lcommunity) {
11479 struct lcommunity *lcom = output_arg;
11480
11481 if (!bgp_attr_get_lcommunity(pi->attr) ||
11482 !lcommunity_match(
11483 bgp_attr_get_lcommunity(pi->attr),
11484 lcom))
11485 continue;
11486 }
11487
11488 if (type == bgp_show_type_lcommunity_exact) {
11489 struct lcommunity *lcom = output_arg;
11490
11491 if (!bgp_attr_get_lcommunity(pi->attr) ||
11492 !lcommunity_cmp(
11493 bgp_attr_get_lcommunity(pi->attr),
11494 lcom))
11495 continue;
11496 }
11497 if (type == bgp_show_type_lcommunity_list) {
11498 struct community_list *list = output_arg;
11499
11500 if (!lcommunity_list_match(
11501 bgp_attr_get_lcommunity(pi->attr),
11502 list))
11503 continue;
11504 }
11505 if (type
11506 == bgp_show_type_lcommunity_list_exact) {
11507 struct community_list *list = output_arg;
11508
11509 if (!lcommunity_list_exact_match(
11510 bgp_attr_get_lcommunity(pi->attr),
11511 list))
11512 continue;
11513 }
11514 if (type == bgp_show_type_lcommunity_all) {
11515 if (!bgp_attr_get_lcommunity(pi->attr))
11516 continue;
11517 }
11518 if (type == bgp_show_type_dampend_paths
11519 || type == bgp_show_type_damp_neighbor) {
11520 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11521 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11522 continue;
11523 }
11524
11525 if (!use_json && header) {
11526 vty_out(vty,
11527 "BGP table version is %" PRIu64
11528 ", local router ID is %pI4, vrf id ",
11529 table->version, &bgp->router_id);
11530 if (bgp->vrf_id == VRF_UNKNOWN)
11531 vty_out(vty, "%s", VRFID_NONE_STR);
11532 else
11533 vty_out(vty, "%u", bgp->vrf_id);
11534 vty_out(vty, "\n");
11535 vty_out(vty, "Default local pref %u, ",
11536 bgp->default_local_pref);
11537 vty_out(vty, "local AS %u\n", bgp->as);
11538 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11539 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11540 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11541 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11542 if (type == bgp_show_type_dampend_paths
11543 || type == bgp_show_type_damp_neighbor)
11544 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11545 else if (type == bgp_show_type_flap_statistics
11546 || type == bgp_show_type_flap_neighbor)
11547 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11548 else
11549 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11550 : BGP_SHOW_HEADER));
11551 header = false;
11552
11553 } else if (json_detail && json_paths != NULL) {
11554 const struct prefix_rd *prd;
11555 json_object *jtemp;
11556
11557 /* Use common detail header, for most types;
11558 * need a json 'object'.
11559 */
11560
11561 jtemp = json_object_new_object();
11562 prd = bgp_rd_from_dest(dest, safi);
11563
11564 route_vty_out_detail_header(
11565 vty, bgp, dest, prd, table->afi,
11566 safi, jtemp);
11567
11568 json_object_array_add(json_paths, jtemp);
11569
11570 json_detail = false;
11571 }
11572
11573 if (rd != NULL && !display && !output_count) {
11574 if (!use_json)
11575 vty_out(vty,
11576 "Route Distinguisher: %s\n",
11577 rd);
11578 }
11579 if (type == bgp_show_type_dampend_paths
11580 || type == bgp_show_type_damp_neighbor)
11581 damp_route_vty_out(vty, dest_p, pi, display,
11582 AFI_IP, safi, use_json,
11583 json_paths);
11584 else if (type == bgp_show_type_flap_statistics
11585 || type == bgp_show_type_flap_neighbor)
11586 flap_route_vty_out(vty, dest_p, pi, display,
11587 AFI_IP, safi, use_json,
11588 json_paths);
11589 else {
11590 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11591 route_vty_out_detail(
11592 vty, bgp, dest, pi,
11593 family2afi(dest_p->family),
11594 safi, RPKI_NOT_BEING_USED,
11595 json_paths);
11596 else
11597 route_vty_out(vty, dest_p, pi, display,
11598 safi, json_paths, wide);
11599 }
11600 display++;
11601 }
11602
11603 if (display) {
11604 output_count++;
11605 if (!use_json)
11606 continue;
11607
11608 /* encode prefix */
11609 if (dest_p->family == AF_FLOWSPEC) {
11610 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11611
11612
11613 bgp_fs_nlri_get_string(
11614 (unsigned char *)
11615 dest_p->u.prefix_flowspec.ptr,
11616 dest_p->u.prefix_flowspec.prefixlen,
11617 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11618 family2afi(dest_p->u
11619 .prefix_flowspec.family));
11620 if (first)
11621 vty_out(vty, "\"%s/%d\": ", retstr,
11622 dest_p->u.prefix_flowspec
11623 .prefixlen);
11624 else
11625 vty_out(vty, ",\"%s/%d\": ", retstr,
11626 dest_p->u.prefix_flowspec
11627 .prefixlen);
11628 } else {
11629 if (first)
11630 vty_out(vty, "\"%pFX\": ", dest_p);
11631 else
11632 vty_out(vty, ",\"%pFX\": ", dest_p);
11633 }
11634 vty_json(vty, json_paths);
11635 json_paths = NULL;
11636 first = 0;
11637 } else
11638 json_object_free(json_paths);
11639 }
11640
11641 if (output_cum) {
11642 output_count += *output_cum;
11643 *output_cum = output_count;
11644 }
11645 if (total_cum) {
11646 total_count += *total_cum;
11647 *total_cum = total_count;
11648 }
11649 if (use_json) {
11650 if (rd) {
11651 vty_out(vty, " }%s ", (is_last ? "" : ","));
11652 }
11653 if (is_last) {
11654 unsigned long i;
11655 for (i = 0; i < *json_header_depth; ++i)
11656 vty_out(vty, " } ");
11657 if (!all)
11658 vty_out(vty, "\n");
11659 }
11660 } else {
11661 if (is_last) {
11662 /* No route is displayed */
11663 if (output_count == 0) {
11664 if (type == bgp_show_type_normal)
11665 vty_out(vty,
11666 "No BGP prefixes displayed, %ld exist\n",
11667 total_count);
11668 } else
11669 vty_out(vty,
11670 "\nDisplayed %ld routes and %ld total paths\n",
11671 output_count, total_count);
11672 }
11673 }
11674
11675 return CMD_SUCCESS;
11676 }
11677
11678 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11679 struct bgp_table *table, struct prefix_rd *prd_match,
11680 enum bgp_show_type type, void *output_arg, bool use_json)
11681 {
11682 struct bgp_dest *dest, *next;
11683 unsigned long output_cum = 0;
11684 unsigned long total_cum = 0;
11685 unsigned long json_header_depth = 0;
11686 struct bgp_table *itable;
11687 bool show_msg;
11688 uint16_t show_flags = 0;
11689
11690 show_msg = (!use_json && type == bgp_show_type_normal);
11691
11692 if (use_json)
11693 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11694
11695 for (dest = bgp_table_top(table); dest; dest = next) {
11696 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11697
11698 next = bgp_route_next(dest);
11699 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11700 continue;
11701
11702 itable = bgp_dest_get_bgp_table_info(dest);
11703 if (itable != NULL) {
11704 struct prefix_rd prd;
11705 char rd[RD_ADDRSTRLEN];
11706
11707 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11708 prefix_rd2str(&prd, rd, sizeof(rd));
11709 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11710 rd, next == NULL, &output_cum,
11711 &total_cum, &json_header_depth,
11712 show_flags, RPKI_NOT_BEING_USED);
11713 if (next == NULL)
11714 show_msg = false;
11715 }
11716 }
11717 if (show_msg) {
11718 if (output_cum == 0)
11719 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11720 total_cum);
11721 else
11722 vty_out(vty,
11723 "\nDisplayed %ld routes and %ld total paths\n",
11724 output_cum, total_cum);
11725 }
11726 return CMD_SUCCESS;
11727 }
11728
11729 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11730 enum bgp_show_type type, void *output_arg,
11731 uint16_t show_flags, enum rpki_states rpki_target_state)
11732 {
11733 struct bgp_table *table;
11734 unsigned long json_header_depth = 0;
11735 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11736
11737 if (bgp == NULL) {
11738 bgp = bgp_get_default();
11739 }
11740
11741 if (bgp == NULL) {
11742 if (!use_json)
11743 vty_out(vty, "No BGP process is configured\n");
11744 else
11745 vty_out(vty, "{}\n");
11746 return CMD_WARNING;
11747 }
11748
11749 /* Labeled-unicast routes live in the unicast table. */
11750 if (safi == SAFI_LABELED_UNICAST)
11751 safi = SAFI_UNICAST;
11752
11753 table = bgp->rib[afi][safi];
11754 /* use MPLS and ENCAP specific shows until they are merged */
11755 if (safi == SAFI_MPLS_VPN) {
11756 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11757 output_arg, use_json);
11758 }
11759
11760 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11761 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11762 output_arg, use_json,
11763 1, NULL, NULL);
11764 }
11765
11766 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11767 NULL, NULL, &json_header_depth, show_flags,
11768 rpki_target_state);
11769 }
11770
11771 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11772 safi_t safi, uint16_t show_flags)
11773 {
11774 struct listnode *node, *nnode;
11775 struct bgp *bgp;
11776 int is_first = 1;
11777 bool route_output = false;
11778 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11779
11780 if (use_json)
11781 vty_out(vty, "{\n");
11782
11783 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11784 route_output = true;
11785 if (use_json) {
11786 if (!is_first)
11787 vty_out(vty, ",\n");
11788 else
11789 is_first = 0;
11790
11791 vty_out(vty, "\"%s\":",
11792 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11793 ? VRF_DEFAULT_NAME
11794 : bgp->name);
11795 } else {
11796 vty_out(vty, "\nInstance %s:\n",
11797 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11798 ? VRF_DEFAULT_NAME
11799 : bgp->name);
11800 }
11801 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11802 show_flags, RPKI_NOT_BEING_USED);
11803 }
11804
11805 if (use_json)
11806 vty_out(vty, "}\n");
11807 else if (!route_output)
11808 vty_out(vty, "%% BGP instance not found\n");
11809 }
11810
11811 /* Header of detailed BGP route information */
11812 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11813 struct bgp_dest *dest,
11814 const struct prefix_rd *prd,
11815 afi_t afi, safi_t safi, json_object *json)
11816 {
11817 struct bgp_path_info *pi;
11818 const struct prefix *p;
11819 struct peer *peer;
11820 struct listnode *node, *nnode;
11821 char buf1[RD_ADDRSTRLEN];
11822 int count = 0;
11823 int best = 0;
11824 int suppress = 0;
11825 int accept_own = 0;
11826 int route_filter_translated_v4 = 0;
11827 int route_filter_v4 = 0;
11828 int route_filter_translated_v6 = 0;
11829 int route_filter_v6 = 0;
11830 int llgr_stale = 0;
11831 int no_llgr = 0;
11832 int accept_own_nexthop = 0;
11833 int blackhole = 0;
11834 int no_export = 0;
11835 int no_advertise = 0;
11836 int local_as = 0;
11837 int no_peer = 0;
11838 int first = 1;
11839 int has_valid_label = 0;
11840 mpls_label_t label = 0;
11841 json_object *json_adv_to = NULL;
11842 uint32_t ttl = 0;
11843 uint32_t bos = 0;
11844 uint32_t exp = 0;
11845
11846 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11847
11848 p = bgp_dest_get_prefix(dest);
11849 has_valid_label = bgp_is_valid_label(&label);
11850
11851 if (safi == SAFI_EVPN) {
11852 if (!json) {
11853 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11854 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11855 : "",
11856 prd ? ":" : "", (struct prefix_evpn *)p);
11857 } else {
11858 json_object_string_add(json, "rd",
11859 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11860 "");
11861 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11862 }
11863 } else {
11864 if (!json) {
11865 vty_out(vty,
11866 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11867 "\n",
11868 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11869 ? prefix_rd2str(prd, buf1,
11870 sizeof(buf1))
11871 : ""),
11872 safi == SAFI_MPLS_VPN ? ":" : "", p,
11873 dest->version);
11874
11875 } else {
11876 json_object_string_addf(json, "prefix", "%pFX", p);
11877 json_object_int_add(json, "version", dest->version);
11878
11879 }
11880 }
11881
11882 if (has_valid_label) {
11883 if (json)
11884 json_object_int_add(json, "localLabel", label);
11885 else
11886 vty_out(vty, "Local label: %d\n", label);
11887 }
11888
11889 if (!json)
11890 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11891 vty_out(vty, "not allocated\n");
11892
11893 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11894 struct community *picomm = NULL;
11895
11896 picomm = bgp_attr_get_community(pi->attr);
11897
11898 count++;
11899 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11900 best = count;
11901 if (bgp_path_suppressed(pi))
11902 suppress = 1;
11903
11904 if (!picomm)
11905 continue;
11906
11907 no_advertise += community_include(
11908 picomm, COMMUNITY_NO_ADVERTISE);
11909 no_export +=
11910 community_include(picomm, COMMUNITY_NO_EXPORT);
11911 local_as +=
11912 community_include(picomm, COMMUNITY_LOCAL_AS);
11913 accept_own +=
11914 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11915 route_filter_translated_v4 += community_include(
11916 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11917 route_filter_translated_v6 += community_include(
11918 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11919 route_filter_v4 += community_include(
11920 picomm, COMMUNITY_ROUTE_FILTER_v4);
11921 route_filter_v6 += community_include(
11922 picomm, COMMUNITY_ROUTE_FILTER_v6);
11923 llgr_stale +=
11924 community_include(picomm, COMMUNITY_LLGR_STALE);
11925 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11926 accept_own_nexthop += community_include(
11927 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11928 blackhole +=
11929 community_include(picomm, COMMUNITY_BLACKHOLE);
11930 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11931 }
11932 }
11933
11934 if (!json) {
11935 vty_out(vty, "Paths: (%d available", count);
11936 if (best) {
11937 vty_out(vty, ", best #%d", best);
11938 if (safi == SAFI_UNICAST) {
11939 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11940 vty_out(vty, ", table %s",
11941 VRF_DEFAULT_NAME);
11942 else
11943 vty_out(vty, ", vrf %s",
11944 bgp->name);
11945 }
11946 } else
11947 vty_out(vty, ", no best path");
11948
11949 if (accept_own)
11950 vty_out(vty,
11951 ", accept own local route exported and imported in different VRF");
11952 else if (route_filter_translated_v4)
11953 vty_out(vty,
11954 ", mark translated RTs for VPNv4 route filtering");
11955 else if (route_filter_v4)
11956 vty_out(vty,
11957 ", attach RT as-is for VPNv4 route filtering");
11958 else if (route_filter_translated_v6)
11959 vty_out(vty,
11960 ", mark translated RTs for VPNv6 route filtering");
11961 else if (route_filter_v6)
11962 vty_out(vty,
11963 ", attach RT as-is for VPNv6 route filtering");
11964 else if (llgr_stale)
11965 vty_out(vty,
11966 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11967 else if (no_llgr)
11968 vty_out(vty,
11969 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11970 else if (accept_own_nexthop)
11971 vty_out(vty,
11972 ", accept local nexthop");
11973 else if (blackhole)
11974 vty_out(vty, ", inform peer to blackhole prefix");
11975 else if (no_export)
11976 vty_out(vty, ", not advertised to EBGP peer");
11977 else if (no_advertise)
11978 vty_out(vty, ", not advertised to any peer");
11979 else if (local_as)
11980 vty_out(vty, ", not advertised outside local AS");
11981 else if (no_peer)
11982 vty_out(vty,
11983 ", inform EBGP peer not to advertise to their EBGP peers");
11984
11985 if (suppress)
11986 vty_out(vty,
11987 ", Advertisements suppressed by an aggregate.");
11988 vty_out(vty, ")\n");
11989 }
11990
11991 /* If we are not using addpath then we can display Advertised to and
11992 * that will
11993 * show what peers we advertised the bestpath to. If we are using
11994 * addpath
11995 * though then we must display Advertised to on a path-by-path basis. */
11996 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11997 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11998 if (bgp_adj_out_lookup(peer, dest, 0)) {
11999 if (json && !json_adv_to)
12000 json_adv_to = json_object_new_object();
12001
12002 route_vty_out_advertised_to(
12003 vty, peer, &first,
12004 " Advertised to non peer-group peers:\n ",
12005 json_adv_to);
12006 }
12007 }
12008
12009 if (json) {
12010 if (json_adv_to) {
12011 json_object_object_add(json, "advertisedTo",
12012 json_adv_to);
12013 }
12014 } else {
12015 if (first)
12016 vty_out(vty, " Not advertised to any peer");
12017 vty_out(vty, "\n");
12018 }
12019 }
12020 }
12021
12022 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12023 struct bgp_dest *bgp_node, struct vty *vty,
12024 struct bgp *bgp, afi_t afi, safi_t safi,
12025 json_object *json, enum bgp_path_type pathtype,
12026 int *display, enum rpki_states rpki_target_state)
12027 {
12028 struct bgp_path_info *pi;
12029 int header = 1;
12030 json_object *json_header = NULL;
12031 json_object *json_paths = NULL;
12032 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12033
12034 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12035 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12036
12037 if (p->family == AF_INET || p->family == AF_INET6)
12038 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12039 pi->peer, pi->attr, p);
12040
12041 if (rpki_target_state != RPKI_NOT_BEING_USED
12042 && rpki_curr_state != rpki_target_state)
12043 continue;
12044
12045 if (json && !json_paths) {
12046 /* Instantiate json_paths only if path is valid */
12047 json_paths = json_object_new_array();
12048 if (pfx_rd)
12049 json_header = json_object_new_object();
12050 else
12051 json_header = json;
12052 }
12053
12054 if (header) {
12055 route_vty_out_detail_header(
12056 vty, bgp, bgp_node, pfx_rd,
12057 AFI_IP, safi, json_header);
12058 header = 0;
12059 }
12060 (*display)++;
12061
12062 if (pathtype == BGP_PATH_SHOW_ALL
12063 || (pathtype == BGP_PATH_SHOW_BESTPATH
12064 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12065 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12066 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12067 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12068 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
12069 safi, rpki_curr_state, json_paths);
12070 }
12071
12072 if (json && json_paths) {
12073 json_object_object_add(json_header, "paths", json_paths);
12074
12075 if (pfx_rd)
12076 json_object_object_addf(json, json_header, "%pRD",
12077 pfx_rd);
12078 }
12079 }
12080
12081 /*
12082 * Return rd based on safi
12083 */
12084 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12085 safi_t safi)
12086 {
12087 switch (safi) {
12088 case SAFI_MPLS_VPN:
12089 case SAFI_ENCAP:
12090 case SAFI_EVPN:
12091 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12092 default:
12093 return NULL;
12094 }
12095 }
12096
12097 /* Display specified route of BGP table. */
12098 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12099 struct bgp_table *rib, const char *ip_str,
12100 afi_t afi, safi_t safi,
12101 enum rpki_states rpki_target_state,
12102 struct prefix_rd *prd, int prefix_check,
12103 enum bgp_path_type pathtype, bool use_json)
12104 {
12105 int ret;
12106 int display = 0;
12107 struct prefix match;
12108 struct bgp_dest *dest;
12109 struct bgp_dest *rm;
12110 struct bgp_table *table;
12111 json_object *json = NULL;
12112 json_object *json_paths = NULL;
12113
12114 /* Check IP address argument. */
12115 ret = str2prefix(ip_str, &match);
12116 if (!ret) {
12117 vty_out(vty, "address is malformed\n");
12118 return CMD_WARNING;
12119 }
12120
12121 match.family = afi2family(afi);
12122
12123 if (use_json)
12124 json = json_object_new_object();
12125
12126 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12127 for (dest = bgp_table_top(rib); dest;
12128 dest = bgp_route_next(dest)) {
12129 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12130
12131 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12132 continue;
12133 table = bgp_dest_get_bgp_table_info(dest);
12134 if (!table)
12135 continue;
12136
12137 rm = bgp_node_match(table, &match);
12138 if (rm == NULL)
12139 continue;
12140
12141 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12142 if (prefix_check
12143 && rm_p->prefixlen != match.prefixlen) {
12144 bgp_dest_unlock_node(rm);
12145 continue;
12146 }
12147
12148 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12149 bgp, afi, safi, json, pathtype,
12150 &display, rpki_target_state);
12151
12152 bgp_dest_unlock_node(rm);
12153 }
12154 } else if (safi == SAFI_EVPN) {
12155 struct bgp_dest *longest_pfx;
12156 bool is_exact_pfxlen_match = false;
12157
12158 for (dest = bgp_table_top(rib); dest;
12159 dest = bgp_route_next(dest)) {
12160 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12161
12162 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12163 continue;
12164 table = bgp_dest_get_bgp_table_info(dest);
12165 if (!table)
12166 continue;
12167
12168 longest_pfx = NULL;
12169 is_exact_pfxlen_match = false;
12170 /*
12171 * Search through all the prefixes for a match. The
12172 * pfx's are enumerated in ascending order of pfxlens.
12173 * So, the last pfx match is the longest match. Set
12174 * is_exact_pfxlen_match when we get exact pfxlen match
12175 */
12176 for (rm = bgp_table_top(table); rm;
12177 rm = bgp_route_next(rm)) {
12178 const struct prefix *rm_p =
12179 bgp_dest_get_prefix(rm);
12180 /*
12181 * Get prefixlen of the ip-prefix within type5
12182 * evpn route
12183 */
12184 if (evpn_type5_prefix_match(rm_p, &match)
12185 && rm->info) {
12186 longest_pfx = rm;
12187 int type5_pfxlen =
12188 bgp_evpn_get_type5_prefixlen(
12189 rm_p);
12190 if (type5_pfxlen == match.prefixlen) {
12191 is_exact_pfxlen_match = true;
12192 bgp_dest_unlock_node(rm);
12193 break;
12194 }
12195 }
12196 }
12197
12198 if (!longest_pfx)
12199 continue;
12200
12201 if (prefix_check && !is_exact_pfxlen_match)
12202 continue;
12203
12204 rm = longest_pfx;
12205 bgp_dest_lock_node(rm);
12206
12207 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12208 bgp, afi, safi, json, pathtype,
12209 &display, rpki_target_state);
12210
12211 bgp_dest_unlock_node(rm);
12212 }
12213 } else if (safi == SAFI_FLOWSPEC) {
12214 if (use_json)
12215 json_paths = json_object_new_array();
12216
12217 display = bgp_flowspec_display_match_per_ip(afi, rib,
12218 &match, prefix_check,
12219 vty,
12220 use_json,
12221 json_paths);
12222 if (use_json) {
12223 if (display)
12224 json_object_object_add(json, "paths",
12225 json_paths);
12226 else
12227 json_object_free(json_paths);
12228 }
12229 } else {
12230 dest = bgp_node_match(rib, &match);
12231 if (dest != NULL) {
12232 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12233 if (!prefix_check
12234 || dest_p->prefixlen == match.prefixlen) {
12235 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12236 safi, json, pathtype,
12237 &display, rpki_target_state);
12238 }
12239
12240 bgp_dest_unlock_node(dest);
12241 }
12242 }
12243
12244 if (use_json) {
12245 vty_json(vty, json);
12246 } else {
12247 if (!display) {
12248 vty_out(vty, "%% Network not in table\n");
12249 return CMD_WARNING;
12250 }
12251 }
12252
12253 return CMD_SUCCESS;
12254 }
12255
12256 /* Display specified route of Main RIB */
12257 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12258 afi_t afi, safi_t safi, struct prefix_rd *prd,
12259 int prefix_check, enum bgp_path_type pathtype,
12260 enum rpki_states rpki_target_state, bool use_json)
12261 {
12262 if (!bgp) {
12263 bgp = bgp_get_default();
12264 if (!bgp) {
12265 if (!use_json)
12266 vty_out(vty, "No BGP process is configured\n");
12267 else
12268 vty_out(vty, "{}\n");
12269 return CMD_WARNING;
12270 }
12271 }
12272
12273 /* labeled-unicast routes live in the unicast table */
12274 if (safi == SAFI_LABELED_UNICAST)
12275 safi = SAFI_UNICAST;
12276
12277 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12278 afi, safi, rpki_target_state, prd,
12279 prefix_check, pathtype, use_json);
12280 }
12281
12282 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12283 struct cmd_token **argv, bool exact, afi_t afi,
12284 safi_t safi, bool uj)
12285 {
12286 struct lcommunity *lcom;
12287 struct buffer *b;
12288 int i;
12289 char *str;
12290 int first = 0;
12291 uint16_t show_flags = 0;
12292 int ret;
12293
12294 if (uj)
12295 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12296
12297 b = buffer_new(1024);
12298 for (i = 0; i < argc; i++) {
12299 if (first)
12300 buffer_putc(b, ' ');
12301 else {
12302 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12303 first = 1;
12304 buffer_putstr(b, argv[i]->arg);
12305 }
12306 }
12307 }
12308 buffer_putc(b, '\0');
12309
12310 str = buffer_getstr(b);
12311 buffer_free(b);
12312
12313 lcom = lcommunity_str2com(str);
12314 XFREE(MTYPE_TMP, str);
12315 if (!lcom) {
12316 vty_out(vty, "%% Large-community malformed\n");
12317 return CMD_WARNING;
12318 }
12319
12320 ret = bgp_show(vty, bgp, afi, safi,
12321 (exact ? bgp_show_type_lcommunity_exact
12322 : bgp_show_type_lcommunity),
12323 lcom, show_flags, RPKI_NOT_BEING_USED);
12324
12325 lcommunity_free(&lcom);
12326 return ret;
12327 }
12328
12329 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12330 const char *lcom, bool exact, afi_t afi,
12331 safi_t safi, bool uj)
12332 {
12333 struct community_list *list;
12334 uint16_t show_flags = 0;
12335
12336 if (uj)
12337 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12338
12339
12340 list = community_list_lookup(bgp_clist, lcom, 0,
12341 LARGE_COMMUNITY_LIST_MASTER);
12342 if (list == NULL) {
12343 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12344 lcom);
12345 return CMD_WARNING;
12346 }
12347
12348 return bgp_show(vty, bgp, afi, safi,
12349 (exact ? bgp_show_type_lcommunity_list_exact
12350 : bgp_show_type_lcommunity_list),
12351 list, show_flags, RPKI_NOT_BEING_USED);
12352 }
12353
12354 DEFUN (show_ip_bgp_large_community_list,
12355 show_ip_bgp_large_community_list_cmd,
12356 "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]",
12357 SHOW_STR
12358 IP_STR
12359 BGP_STR
12360 BGP_INSTANCE_HELP_STR
12361 BGP_AFI_HELP_STR
12362 BGP_SAFI_WITH_LABEL_HELP_STR
12363 "Display routes matching the large-community-list\n"
12364 "large-community-list number\n"
12365 "large-community-list name\n"
12366 "Exact match of the large-communities\n"
12367 JSON_STR)
12368 {
12369 afi_t afi = AFI_IP6;
12370 safi_t safi = SAFI_UNICAST;
12371 int idx = 0;
12372 bool exact_match = 0;
12373 struct bgp *bgp = NULL;
12374 bool uj = use_json(argc, argv);
12375
12376 if (uj)
12377 argc--;
12378
12379 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12380 &bgp, uj);
12381 if (!idx)
12382 return CMD_WARNING;
12383
12384 argv_find(argv, argc, "large-community-list", &idx);
12385
12386 const char *clist_number_or_name = argv[++idx]->arg;
12387
12388 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12389 exact_match = 1;
12390
12391 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12392 exact_match, afi, safi, uj);
12393 }
12394 DEFUN (show_ip_bgp_large_community,
12395 show_ip_bgp_large_community_cmd,
12396 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12397 SHOW_STR
12398 IP_STR
12399 BGP_STR
12400 BGP_INSTANCE_HELP_STR
12401 BGP_AFI_HELP_STR
12402 BGP_SAFI_WITH_LABEL_HELP_STR
12403 "Display routes matching the large-communities\n"
12404 "List of large-community numbers\n"
12405 "Exact match of the large-communities\n"
12406 JSON_STR)
12407 {
12408 afi_t afi = AFI_IP6;
12409 safi_t safi = SAFI_UNICAST;
12410 int idx = 0;
12411 bool exact_match = 0;
12412 struct bgp *bgp = NULL;
12413 bool uj = use_json(argc, argv);
12414 uint16_t show_flags = 0;
12415
12416 if (uj) {
12417 argc--;
12418 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12419 }
12420
12421 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12422 &bgp, uj);
12423 if (!idx)
12424 return CMD_WARNING;
12425
12426 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12427 if (argv_find(argv, argc, "exact-match", &idx)) {
12428 argc--;
12429 exact_match = 1;
12430 }
12431 return bgp_show_lcommunity(vty, bgp, argc, argv,
12432 exact_match, afi, safi, uj);
12433 } else
12434 return bgp_show(vty, bgp, afi, safi,
12435 bgp_show_type_lcommunity_all, NULL, show_flags,
12436 RPKI_NOT_BEING_USED);
12437 }
12438
12439 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12440 safi_t safi, struct json_object *json_array);
12441 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12442 safi_t safi, struct json_object *json);
12443
12444
12445 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12446 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12447 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12448 "Display number of prefixes for all afi/safi\n" JSON_STR)
12449 {
12450 bool uj = use_json(argc, argv);
12451 struct bgp *bgp = NULL;
12452 safi_t safi = SAFI_UNICAST;
12453 afi_t afi = AFI_IP6;
12454 int idx = 0;
12455 struct json_object *json_all = NULL;
12456 struct json_object *json_afi_safi = NULL;
12457
12458 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12459 &bgp, false);
12460 if (!idx)
12461 return CMD_WARNING;
12462
12463 if (uj)
12464 json_all = json_object_new_object();
12465
12466 FOREACH_AFI_SAFI (afi, safi) {
12467 /*
12468 * So limit output to those afi/safi pairs that
12469 * actually have something interesting in them
12470 */
12471 if (strmatch(get_afi_safi_str(afi, safi, true),
12472 "Unknown")) {
12473 continue;
12474 }
12475 if (uj) {
12476 json_afi_safi = json_object_new_array();
12477 json_object_object_add(
12478 json_all,
12479 get_afi_safi_str(afi, safi, true),
12480 json_afi_safi);
12481 } else {
12482 json_afi_safi = NULL;
12483 }
12484
12485 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12486 }
12487
12488 if (uj)
12489 vty_json(vty, json_all);
12490
12491 return CMD_SUCCESS;
12492 }
12493
12494 /* BGP route print out function without JSON */
12495 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12496 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12497 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12498 SHOW_STR
12499 IP_STR
12500 BGP_STR
12501 BGP_INSTANCE_HELP_STR
12502 L2VPN_HELP_STR
12503 EVPN_HELP_STR
12504 "BGP RIB advertisement statistics\n"
12505 JSON_STR)
12506 {
12507 afi_t afi = AFI_IP6;
12508 safi_t safi = SAFI_UNICAST;
12509 struct bgp *bgp = NULL;
12510 int idx = 0, ret;
12511 bool uj = use_json(argc, argv);
12512 struct json_object *json_afi_safi = NULL, *json = NULL;
12513
12514 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12515 &bgp, false);
12516 if (!idx)
12517 return CMD_WARNING;
12518
12519 if (uj)
12520 json_afi_safi = json_object_new_array();
12521 else
12522 json_afi_safi = NULL;
12523
12524 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12525
12526 if (uj) {
12527 json = json_object_new_object();
12528 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12529 json_afi_safi);
12530 vty_json(vty, json);
12531 }
12532 return ret;
12533 }
12534
12535 /* BGP route print out function without JSON */
12536 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12537 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12538 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12539 "]]\
12540 statistics [json]",
12541 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12542 BGP_SAFI_WITH_LABEL_HELP_STR
12543 "BGP RIB advertisement statistics\n" JSON_STR)
12544 {
12545 afi_t afi = AFI_IP6;
12546 safi_t safi = SAFI_UNICAST;
12547 struct bgp *bgp = NULL;
12548 int idx = 0, ret;
12549 bool uj = use_json(argc, argv);
12550 struct json_object *json_afi_safi = NULL, *json = NULL;
12551
12552 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12553 &bgp, false);
12554 if (!idx)
12555 return CMD_WARNING;
12556
12557 if (uj)
12558 json_afi_safi = json_object_new_array();
12559 else
12560 json_afi_safi = NULL;
12561
12562 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12563
12564 if (uj) {
12565 json = json_object_new_object();
12566 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12567 json_afi_safi);
12568 vty_json(vty, json);
12569 }
12570 return ret;
12571 }
12572
12573 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12574 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12575 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12576 "]] [all$all] dampening parameters [json]",
12577 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12578 BGP_SAFI_WITH_LABEL_HELP_STR
12579 "Display the entries for all address families\n"
12580 "Display detailed information about dampening\n"
12581 "Display detail of configured dampening parameters\n"
12582 JSON_STR)
12583 {
12584 afi_t afi = AFI_IP6;
12585 safi_t safi = SAFI_UNICAST;
12586 struct bgp *bgp = NULL;
12587 int idx = 0;
12588 uint16_t show_flags = 0;
12589 bool uj = use_json(argc, argv);
12590
12591 if (uj) {
12592 argc--;
12593 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12594 }
12595
12596 /* [<ipv4|ipv6> [all]] */
12597 if (all) {
12598 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12599 if (argv_find(argv, argc, "ipv4", &idx))
12600 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12601
12602 if (argv_find(argv, argc, "ipv6", &idx))
12603 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12604 }
12605
12606 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12607 &bgp, false);
12608 if (!idx)
12609 return CMD_WARNING;
12610
12611 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12612 }
12613
12614 /* BGP route print out function */
12615 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12616 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12617 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12618 "]]\
12619 [all$all]\
12620 [cidr-only\
12621 |dampening <flap-statistics|dampened-paths>\
12622 |community [AA:NN|local-AS|no-advertise|no-export\
12623 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12624 |accept-own|accept-own-nexthop|route-filter-v6\
12625 |route-filter-v4|route-filter-translated-v6\
12626 |route-filter-translated-v4] [exact-match]\
12627 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12628 |filter-list AS_PATH_FILTER_NAME\
12629 |prefix-list WORD\
12630 |access-list ACCESSLIST_NAME\
12631 |route-map RMAP_NAME\
12632 |rpki <invalid|valid|notfound>\
12633 |version (1-4294967295)\
12634 |alias ALIAS_NAME\
12635 |A.B.C.D/M longer-prefixes\
12636 |X:X::X:X/M longer-prefixes\
12637 |optimal-route-reflection [WORD$orr_group_name]\
12638 ] [json$uj [detail$detail] | wide$wide]",
12639 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12640 BGP_SAFI_WITH_LABEL_HELP_STR
12641 "Display the entries for all address families\n"
12642 "Display only routes with non-natural netmasks\n"
12643 "Display detailed information about dampening\n"
12644 "Display flap statistics of routes\n"
12645 "Display paths suppressed due to dampening\n"
12646 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12647 "Do not send outside local AS (well-known community)\n"
12648 "Do not advertise to any peer (well-known community)\n"
12649 "Do not export to next AS (well-known community)\n"
12650 "Graceful shutdown (well-known community)\n"
12651 "Do not export to any peer (well-known community)\n"
12652 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12653 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12654 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12655 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12656 "Should accept VPN route with local nexthop (well-known community)\n"
12657 "RT VPNv6 route filtering (well-known community)\n"
12658 "RT VPNv4 route filtering (well-known community)\n"
12659 "RT translated VPNv6 route filtering (well-known community)\n"
12660 "RT translated VPNv4 route filtering (well-known community)\n"
12661 "Exact match of the communities\n"
12662 "Community-list number\n"
12663 "Community-list name\n"
12664 "Display routes matching the community-list\n"
12665 "Exact match of the communities\n"
12666 "Display routes conforming to the filter-list\n"
12667 "Regular expression access list name\n"
12668 "Display routes conforming to the prefix-list\n"
12669 "Prefix-list name\n"
12670 "Display routes conforming to the access-list\n"
12671 "Access-list name\n"
12672 "Display routes matching the route-map\n"
12673 "A route-map to match on\n"
12674 "RPKI route types\n"
12675 "A valid path as determined by rpki\n"
12676 "A invalid path as determined by rpki\n"
12677 "A path that has no rpki data\n"
12678 "Display prefixes with matching version numbers\n"
12679 "Version number and above\n"
12680 "Display prefixes with matching BGP community alias\n"
12681 "BGP community alias\n"
12682 "IPv4 prefix\n"
12683 "Display route and more specific routes\n"
12684 "IPv6 prefix\n"
12685 "Display route and more specific routes\n"
12686 "Display Optimal Route Reflection RR Clients\n"
12687 "ORR Group name\n"
12688 JSON_STR
12689 "Display detailed version of JSON output\n"
12690 "Increase table width for longer prefixes\n")
12691 {
12692 afi_t afi = AFI_IP6;
12693 safi_t safi = SAFI_UNICAST;
12694 enum bgp_show_type sh_type = bgp_show_type_normal;
12695 void *output_arg = NULL;
12696 struct bgp *bgp = NULL;
12697 int idx = 0;
12698 int exact_match = 0;
12699 char *community = NULL;
12700 bool first = true;
12701 uint16_t show_flags = 0;
12702 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12703 struct prefix p;
12704 bool orr_group = false;
12705
12706 if (uj) {
12707 argc--;
12708 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12709 }
12710
12711 if (detail)
12712 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12713
12714 /* [<ipv4|ipv6> [all]] */
12715 if (all) {
12716 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12717
12718 if (argv_find(argv, argc, "ipv4", &idx))
12719 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12720
12721 if (argv_find(argv, argc, "ipv6", &idx))
12722 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12723 }
12724
12725 if (wide)
12726 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12727
12728 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12729 &bgp, uj);
12730 if (!idx)
12731 return CMD_WARNING;
12732
12733 if (argv_find(argv, argc, "cidr-only", &idx))
12734 sh_type = bgp_show_type_cidr_only;
12735
12736 if (argv_find(argv, argc, "dampening", &idx)) {
12737 if (argv_find(argv, argc, "dampened-paths", &idx))
12738 sh_type = bgp_show_type_dampend_paths;
12739 else if (argv_find(argv, argc, "flap-statistics", &idx))
12740 sh_type = bgp_show_type_flap_statistics;
12741 }
12742
12743 if (argv_find(argv, argc, "community", &idx)) {
12744 char *maybecomm = NULL;
12745
12746 if (idx + 1 < argc) {
12747 if (argv[idx + 1]->type == VARIABLE_TKN)
12748 maybecomm = argv[idx + 1]->arg;
12749 else
12750 maybecomm = argv[idx + 1]->text;
12751 }
12752
12753 if (maybecomm && !strmatch(maybecomm, "json")
12754 && !strmatch(maybecomm, "exact-match"))
12755 community = maybecomm;
12756
12757 if (argv_find(argv, argc, "exact-match", &idx))
12758 exact_match = 1;
12759
12760 if (!community)
12761 sh_type = bgp_show_type_community_all;
12762 }
12763
12764 if (argv_find(argv, argc, "community-list", &idx)) {
12765 const char *clist_number_or_name = argv[++idx]->arg;
12766 struct community_list *list;
12767
12768 if (argv_find(argv, argc, "exact-match", &idx))
12769 exact_match = 1;
12770
12771 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12772 COMMUNITY_LIST_MASTER);
12773 if (list == NULL) {
12774 vty_out(vty, "%% %s community-list not found\n",
12775 clist_number_or_name);
12776 return CMD_WARNING;
12777 }
12778
12779 if (exact_match)
12780 sh_type = bgp_show_type_community_list_exact;
12781 else
12782 sh_type = bgp_show_type_community_list;
12783 output_arg = list;
12784 }
12785
12786 if (argv_find(argv, argc, "filter-list", &idx)) {
12787 const char *filter = argv[++idx]->arg;
12788 struct as_list *as_list;
12789
12790 as_list = as_list_lookup(filter);
12791 if (as_list == NULL) {
12792 vty_out(vty, "%% %s AS-path access-list not found\n",
12793 filter);
12794 return CMD_WARNING;
12795 }
12796
12797 sh_type = bgp_show_type_filter_list;
12798 output_arg = as_list;
12799 }
12800
12801 if (argv_find(argv, argc, "prefix-list", &idx)) {
12802 const char *prefix_list_str = argv[++idx]->arg;
12803 struct prefix_list *plist;
12804
12805 plist = prefix_list_lookup(afi, prefix_list_str);
12806 if (plist == NULL) {
12807 vty_out(vty, "%% %s prefix-list not found\n",
12808 prefix_list_str);
12809 return CMD_WARNING;
12810 }
12811
12812 sh_type = bgp_show_type_prefix_list;
12813 output_arg = plist;
12814 }
12815
12816 if (argv_find(argv, argc, "access-list", &idx)) {
12817 const char *access_list_str = argv[++idx]->arg;
12818 struct access_list *alist;
12819
12820 alist = access_list_lookup(afi, access_list_str);
12821 if (!alist) {
12822 vty_out(vty, "%% %s access-list not found\n",
12823 access_list_str);
12824 return CMD_WARNING;
12825 }
12826
12827 sh_type = bgp_show_type_access_list;
12828 output_arg = alist;
12829 }
12830
12831 if (argv_find(argv, argc, "route-map", &idx)) {
12832 const char *rmap_str = argv[++idx]->arg;
12833 struct route_map *rmap;
12834
12835 rmap = route_map_lookup_by_name(rmap_str);
12836 if (!rmap) {
12837 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12838 return CMD_WARNING;
12839 }
12840
12841 sh_type = bgp_show_type_route_map;
12842 output_arg = rmap;
12843 }
12844
12845 if (argv_find(argv, argc, "rpki", &idx)) {
12846 sh_type = bgp_show_type_rpki;
12847 if (argv_find(argv, argc, "valid", &idx))
12848 rpki_target_state = RPKI_VALID;
12849 else if (argv_find(argv, argc, "invalid", &idx))
12850 rpki_target_state = RPKI_INVALID;
12851 }
12852
12853 /* Display prefixes with matching version numbers */
12854 if (argv_find(argv, argc, "version", &idx)) {
12855 sh_type = bgp_show_type_prefix_version;
12856 output_arg = argv[idx + 1]->arg;
12857 }
12858
12859 /* Display prefixes with matching BGP community alias */
12860 if (argv_find(argv, argc, "alias", &idx)) {
12861 sh_type = bgp_show_type_community_alias;
12862 output_arg = argv[idx + 1]->arg;
12863 }
12864
12865 /* prefix-longer */
12866 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12867 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12868 const char *prefix_str = argv[idx]->arg;
12869
12870 if (!str2prefix(prefix_str, &p)) {
12871 vty_out(vty, "%% Malformed Prefix\n");
12872 return CMD_WARNING;
12873 }
12874
12875 sh_type = bgp_show_type_prefix_longer;
12876 output_arg = &p;
12877 }
12878
12879 if (argv_find(argv, argc, "optimal-route-reflection", &idx))
12880 orr_group = true;
12881
12882 if (!all) {
12883 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12884 if (community)
12885 return bgp_show_community(vty, bgp, community,
12886 exact_match, afi, safi,
12887 show_flags);
12888 else if (orr_group)
12889 return bgp_show_orr(vty, bgp, afi, safi, orr_group_name,
12890 show_flags);
12891 else
12892 return bgp_show(vty, bgp, afi, safi, sh_type,
12893 output_arg, show_flags,
12894 rpki_target_state);
12895 } else {
12896 struct listnode *node;
12897 struct bgp *abgp;
12898 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12899 * AFI_IP6 */
12900
12901 if (uj)
12902 vty_out(vty, "{\n");
12903
12904 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12905 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12906 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12907 ? AFI_IP
12908 : AFI_IP6;
12909 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12910 FOREACH_SAFI (safi) {
12911 if (!bgp_afi_safi_peer_exists(abgp, afi,
12912 safi))
12913 continue;
12914
12915 if (uj) {
12916 if (first)
12917 first = false;
12918 else
12919 vty_out(vty, ",\n");
12920 vty_out(vty, "\"%s\":{\n",
12921 get_afi_safi_str(afi,
12922 safi,
12923 true));
12924 } else
12925 vty_out(vty,
12926 "\nFor address family: %s\n",
12927 get_afi_safi_str(
12928 afi, safi,
12929 false));
12930
12931 if (community)
12932 bgp_show_community(
12933 vty, abgp, community,
12934 exact_match, afi, safi,
12935 show_flags);
12936 else if (orr_group)
12937 bgp_show_orr(vty, bgp, afi,
12938 safi,
12939 orr_group_name,
12940 show_flags);
12941 else
12942 bgp_show(vty, abgp, afi, safi,
12943 sh_type, output_arg,
12944 show_flags,
12945 rpki_target_state);
12946 if (uj)
12947 vty_out(vty, "}\n");
12948 }
12949 }
12950 } else {
12951 /* show <ip> bgp all: for each AFI and SAFI*/
12952 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12953 FOREACH_AFI_SAFI (afi, safi) {
12954 if (!bgp_afi_safi_peer_exists(abgp, afi,
12955 safi))
12956 continue;
12957
12958 if (uj) {
12959 if (first)
12960 first = false;
12961 else
12962 vty_out(vty, ",\n");
12963
12964 vty_out(vty, "\"%s\":{\n",
12965 get_afi_safi_str(afi,
12966 safi,
12967 true));
12968 } else
12969 vty_out(vty,
12970 "\nFor address family: %s\n",
12971 get_afi_safi_str(
12972 afi, safi,
12973 false));
12974
12975 if (community)
12976 bgp_show_community(
12977 vty, abgp, community,
12978 exact_match, afi, safi,
12979 show_flags);
12980 else if (orr_group)
12981 bgp_show_orr(vty, bgp, afi,
12982 safi,
12983 orr_group_name,
12984 show_flags);
12985 else
12986 bgp_show(vty, abgp, afi, safi,
12987 sh_type, output_arg,
12988 show_flags,
12989 rpki_target_state);
12990 if (uj)
12991 vty_out(vty, "}\n");
12992 }
12993 }
12994 }
12995 if (uj)
12996 vty_out(vty, "}\n");
12997 }
12998 return CMD_SUCCESS;
12999 }
13000
13001 DEFUN (show_ip_bgp_route,
13002 show_ip_bgp_route_cmd,
13003 "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]",
13004 SHOW_STR
13005 IP_STR
13006 BGP_STR
13007 BGP_INSTANCE_HELP_STR
13008 BGP_AFI_HELP_STR
13009 BGP_SAFI_WITH_LABEL_HELP_STR
13010 "Network in the BGP routing table to display\n"
13011 "IPv4 prefix\n"
13012 "Network in the BGP routing table to display\n"
13013 "IPv6 prefix\n"
13014 "Display only the bestpath\n"
13015 "Display only multipaths\n"
13016 "Display only paths that match the specified rpki state\n"
13017 "A valid path as determined by rpki\n"
13018 "A invalid path as determined by rpki\n"
13019 "A path that has no rpki data\n"
13020 JSON_STR)
13021 {
13022 int prefix_check = 0;
13023
13024 afi_t afi = AFI_IP6;
13025 safi_t safi = SAFI_UNICAST;
13026 char *prefix = NULL;
13027 struct bgp *bgp = NULL;
13028 enum bgp_path_type path_type;
13029 bool uj = use_json(argc, argv);
13030
13031 int idx = 0;
13032
13033 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13034 &bgp, uj);
13035 if (!idx)
13036 return CMD_WARNING;
13037
13038 if (!bgp) {
13039 vty_out(vty,
13040 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13041 return CMD_WARNING;
13042 }
13043
13044 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13045 if (argv_find(argv, argc, "A.B.C.D", &idx)
13046 || argv_find(argv, argc, "X:X::X:X", &idx))
13047 prefix_check = 0;
13048 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13049 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13050 prefix_check = 1;
13051
13052 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13053 && afi != AFI_IP6) {
13054 vty_out(vty,
13055 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13056 return CMD_WARNING;
13057 }
13058 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13059 && afi != AFI_IP) {
13060 vty_out(vty,
13061 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13062 return CMD_WARNING;
13063 }
13064
13065 prefix = argv[idx]->arg;
13066
13067 /* [<bestpath|multipath>] */
13068 if (argv_find(argv, argc, "bestpath", &idx))
13069 path_type = BGP_PATH_SHOW_BESTPATH;
13070 else if (argv_find(argv, argc, "multipath", &idx))
13071 path_type = BGP_PATH_SHOW_MULTIPATH;
13072 else
13073 path_type = BGP_PATH_SHOW_ALL;
13074
13075 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13076 path_type, RPKI_NOT_BEING_USED, uj);
13077 }
13078
13079 DEFUN (show_ip_bgp_regexp,
13080 show_ip_bgp_regexp_cmd,
13081 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13082 SHOW_STR
13083 IP_STR
13084 BGP_STR
13085 BGP_INSTANCE_HELP_STR
13086 BGP_AFI_HELP_STR
13087 BGP_SAFI_WITH_LABEL_HELP_STR
13088 "Display routes matching the AS path regular expression\n"
13089 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13090 JSON_STR)
13091 {
13092 afi_t afi = AFI_IP6;
13093 safi_t safi = SAFI_UNICAST;
13094 struct bgp *bgp = NULL;
13095 bool uj = use_json(argc, argv);
13096 char *regstr = NULL;
13097
13098 int idx = 0;
13099 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13100 &bgp, false);
13101 if (!idx)
13102 return CMD_WARNING;
13103
13104 // get index of regex
13105 if (argv_find(argv, argc, "REGEX", &idx))
13106 regstr = argv[idx]->arg;
13107
13108 assert(regstr);
13109 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13110 bgp_show_type_regexp, uj);
13111 }
13112
13113 DEFPY (show_ip_bgp_instance_all,
13114 show_ip_bgp_instance_all_cmd,
13115 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13116 SHOW_STR
13117 IP_STR
13118 BGP_STR
13119 BGP_INSTANCE_ALL_HELP_STR
13120 BGP_AFI_HELP_STR
13121 BGP_SAFI_WITH_LABEL_HELP_STR
13122 JSON_STR
13123 "Increase table width for longer prefixes\n")
13124 {
13125 afi_t afi = AFI_IP6;
13126 safi_t safi = SAFI_UNICAST;
13127 struct bgp *bgp = NULL;
13128 int idx = 0;
13129 uint16_t show_flags = 0;
13130
13131 if (uj) {
13132 argc--;
13133 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13134 }
13135
13136 if (wide)
13137 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13138
13139 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13140 &bgp, uj);
13141 if (!idx)
13142 return CMD_WARNING;
13143
13144 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13145 return CMD_SUCCESS;
13146 }
13147
13148 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13149 afi_t afi, safi_t safi, enum bgp_show_type type,
13150 bool use_json)
13151 {
13152 regex_t *regex;
13153 int rc;
13154 uint16_t show_flags = 0;
13155
13156 if (use_json)
13157 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13158
13159 if (!config_bgp_aspath_validate(regstr)) {
13160 vty_out(vty, "Invalid character in REGEX %s\n",
13161 regstr);
13162 return CMD_WARNING_CONFIG_FAILED;
13163 }
13164
13165 regex = bgp_regcomp(regstr);
13166 if (!regex) {
13167 vty_out(vty, "Can't compile regexp %s\n", regstr);
13168 return CMD_WARNING;
13169 }
13170
13171 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13172 RPKI_NOT_BEING_USED);
13173 bgp_regex_free(regex);
13174 return rc;
13175 }
13176
13177 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13178 const char *comstr, int exact, afi_t afi,
13179 safi_t safi, uint16_t show_flags)
13180 {
13181 struct community *com;
13182 int ret = 0;
13183
13184 com = community_str2com(comstr);
13185 if (!com) {
13186 vty_out(vty, "%% Community malformed: %s\n", comstr);
13187 return CMD_WARNING;
13188 }
13189
13190 ret = bgp_show(vty, bgp, afi, safi,
13191 (exact ? bgp_show_type_community_exact
13192 : bgp_show_type_community),
13193 com, show_flags, RPKI_NOT_BEING_USED);
13194 community_free(&com);
13195
13196 return ret;
13197 }
13198
13199 enum bgp_stats {
13200 BGP_STATS_MAXBITLEN = 0,
13201 BGP_STATS_RIB,
13202 BGP_STATS_PREFIXES,
13203 BGP_STATS_TOTPLEN,
13204 BGP_STATS_UNAGGREGATEABLE,
13205 BGP_STATS_MAX_AGGREGATEABLE,
13206 BGP_STATS_AGGREGATES,
13207 BGP_STATS_SPACE,
13208 BGP_STATS_ASPATH_COUNT,
13209 BGP_STATS_ASPATH_MAXHOPS,
13210 BGP_STATS_ASPATH_TOTHOPS,
13211 BGP_STATS_ASPATH_MAXSIZE,
13212 BGP_STATS_ASPATH_TOTSIZE,
13213 BGP_STATS_ASN_HIGHEST,
13214 BGP_STATS_MAX,
13215 };
13216
13217 #define TABLE_STATS_IDX_VTY 0
13218 #define TABLE_STATS_IDX_JSON 1
13219
13220 static const char *table_stats_strs[][2] = {
13221 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13222 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13223 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13224 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13225 "unaggregateablePrefixes"},
13226 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13227 "maximumAggregateablePrefixes"},
13228 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13229 "bgpAggregateAdvertisements"},
13230 [BGP_STATS_SPACE] = {"Address space advertised",
13231 "addressSpaceAdvertised"},
13232 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13233 "advertisementsWithPaths"},
13234 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13235 "longestAsPath"},
13236 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13237 "largestAsPath"},
13238 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13239 "averageAsPathLengthHops"},
13240 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13241 "averageAsPathSizeBytes"},
13242 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13243 [BGP_STATS_MAX] = {NULL, NULL}
13244 };
13245
13246 struct bgp_table_stats {
13247 struct bgp_table *table;
13248 unsigned long long counts[BGP_STATS_MAX];
13249
13250 unsigned long long
13251 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13252 1];
13253
13254 double total_space;
13255 };
13256
13257 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13258 struct bgp_table_stats *ts, unsigned int space)
13259 {
13260 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13261 struct bgp_path_info *pi;
13262 const struct prefix *rn_p;
13263
13264 if (!bgp_dest_has_bgp_path_info_data(dest))
13265 return;
13266
13267 rn_p = bgp_dest_get_prefix(dest);
13268 ts->counts[BGP_STATS_PREFIXES]++;
13269 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13270
13271 ts->prefix_len_count[rn_p->prefixlen]++;
13272 /* check if the prefix is included by any other announcements */
13273 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13274 pdest = bgp_dest_parent_nolock(pdest);
13275
13276 if (pdest == NULL || pdest == top) {
13277 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13278 /* announced address space */
13279 if (space)
13280 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13281 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13282 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13283
13284
13285 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13286 ts->counts[BGP_STATS_RIB]++;
13287
13288 if (CHECK_FLAG(pi->attr->flag,
13289 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13290 ts->counts[BGP_STATS_AGGREGATES]++;
13291
13292 /* as-path stats */
13293 if (pi->attr->aspath) {
13294 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13295 unsigned int size = aspath_size(pi->attr->aspath);
13296 as_t highest = aspath_highest(pi->attr->aspath);
13297
13298 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13299
13300 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13301 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13302
13303 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13304 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13305
13306 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13307 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13308 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13309 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13310 }
13311 }
13312 }
13313
13314 static void bgp_table_stats_walker(struct thread *t)
13315 {
13316 struct bgp_dest *dest, *ndest;
13317 struct bgp_dest *top;
13318 struct bgp_table_stats *ts = THREAD_ARG(t);
13319 unsigned int space = 0;
13320
13321 if (!(top = bgp_table_top(ts->table)))
13322 return;
13323
13324 switch (ts->table->afi) {
13325 case AFI_IP:
13326 space = IPV4_MAX_BITLEN;
13327 break;
13328 case AFI_IP6:
13329 space = IPV6_MAX_BITLEN;
13330 break;
13331 case AFI_L2VPN:
13332 space = EVPN_ROUTE_PREFIXLEN;
13333 break;
13334 default:
13335 return;
13336 }
13337
13338 ts->counts[BGP_STATS_MAXBITLEN] = space;
13339
13340 for (dest = top; dest; dest = bgp_route_next(dest)) {
13341 if (ts->table->safi == SAFI_MPLS_VPN
13342 || ts->table->safi == SAFI_ENCAP
13343 || ts->table->safi == SAFI_EVPN) {
13344 struct bgp_table *table;
13345
13346 table = bgp_dest_get_bgp_table_info(dest);
13347 if (!table)
13348 continue;
13349
13350 top = bgp_table_top(table);
13351 for (ndest = bgp_table_top(table); ndest;
13352 ndest = bgp_route_next(ndest))
13353 bgp_table_stats_rn(ndest, top, ts, space);
13354 } else {
13355 bgp_table_stats_rn(dest, top, ts, space);
13356 }
13357 }
13358 }
13359
13360 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13361 struct json_object *json_array)
13362 {
13363 struct listnode *node, *nnode;
13364 struct bgp *bgp;
13365
13366 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13367 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13368 }
13369
13370 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13371 safi_t safi, struct json_object *json_array)
13372 {
13373 struct bgp_table_stats ts;
13374 unsigned int i;
13375 int ret = CMD_SUCCESS;
13376 char temp_buf[20];
13377 struct json_object *json = NULL;
13378 uint32_t bitlen = 0;
13379 struct json_object *json_bitlen;
13380
13381 if (json_array)
13382 json = json_object_new_object();
13383
13384 if (!bgp->rib[afi][safi]) {
13385 char warning_msg[50];
13386
13387 snprintf(warning_msg, sizeof(warning_msg),
13388 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13389 safi);
13390
13391 if (!json)
13392 vty_out(vty, "%s\n", warning_msg);
13393 else
13394 json_object_string_add(json, "warning", warning_msg);
13395
13396 ret = CMD_WARNING;
13397 goto end_table_stats;
13398 }
13399
13400 if (!json)
13401 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13402 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13403 else
13404 json_object_string_add(json, "instance", bgp->name_pretty);
13405
13406 /* labeled-unicast routes live in the unicast table */
13407 if (safi == SAFI_LABELED_UNICAST)
13408 safi = SAFI_UNICAST;
13409
13410 memset(&ts, 0, sizeof(ts));
13411 ts.table = bgp->rib[afi][safi];
13412 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13413
13414 for (i = 0; i < BGP_STATS_MAX; i++) {
13415 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13416 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13417 continue;
13418
13419 switch (i) {
13420 case BGP_STATS_ASPATH_TOTHOPS:
13421 case BGP_STATS_ASPATH_TOTSIZE:
13422 if (!json) {
13423 snprintf(
13424 temp_buf, sizeof(temp_buf), "%12.2f",
13425 ts.counts[i]
13426 ? (float)ts.counts[i]
13427 / (float)ts.counts
13428 [BGP_STATS_ASPATH_COUNT]
13429 : 0);
13430 vty_out(vty, "%-30s: %s",
13431 table_stats_strs[i]
13432 [TABLE_STATS_IDX_VTY],
13433 temp_buf);
13434 } else {
13435 json_object_double_add(
13436 json,
13437 table_stats_strs[i]
13438 [TABLE_STATS_IDX_JSON],
13439 ts.counts[i]
13440 ? (double)ts.counts[i]
13441 / (double)ts.counts
13442 [BGP_STATS_ASPATH_COUNT]
13443 : 0);
13444 }
13445 break;
13446 case BGP_STATS_TOTPLEN:
13447 if (!json) {
13448 snprintf(
13449 temp_buf, sizeof(temp_buf), "%12.2f",
13450 ts.counts[i]
13451 ? (float)ts.counts[i]
13452 / (float)ts.counts
13453 [BGP_STATS_PREFIXES]
13454 : 0);
13455 vty_out(vty, "%-30s: %s",
13456 table_stats_strs[i]
13457 [TABLE_STATS_IDX_VTY],
13458 temp_buf);
13459 } else {
13460 json_object_double_add(
13461 json,
13462 table_stats_strs[i]
13463 [TABLE_STATS_IDX_JSON],
13464 ts.counts[i]
13465 ? (double)ts.counts[i]
13466 / (double)ts.counts
13467 [BGP_STATS_PREFIXES]
13468 : 0);
13469 }
13470 break;
13471 case BGP_STATS_SPACE:
13472 if (!json) {
13473 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13474 ts.total_space);
13475 vty_out(vty, "%-30s: %s\n",
13476 table_stats_strs[i]
13477 [TABLE_STATS_IDX_VTY],
13478 temp_buf);
13479 } else {
13480 json_object_double_add(
13481 json,
13482 table_stats_strs[i]
13483 [TABLE_STATS_IDX_JSON],
13484 (double)ts.total_space);
13485 }
13486 if (afi == AFI_IP6) {
13487 if (!json) {
13488 snprintf(temp_buf, sizeof(temp_buf),
13489 "%12g",
13490 ts.total_space
13491 * pow(2.0, -128 + 32));
13492 vty_out(vty, "%30s: %s\n",
13493 "/32 equivalent %s\n",
13494 temp_buf);
13495 } else {
13496 json_object_double_add(
13497 json, "/32equivalent",
13498 (double)(ts.total_space
13499 * pow(2.0,
13500 -128 + 32)));
13501 }
13502 if (!json) {
13503 snprintf(temp_buf, sizeof(temp_buf),
13504 "%12g",
13505 ts.total_space
13506 * pow(2.0, -128 + 48));
13507 vty_out(vty, "%30s: %s\n",
13508 "/48 equivalent %s\n",
13509 temp_buf);
13510 } else {
13511 json_object_double_add(
13512 json, "/48equivalent",
13513 (double)(ts.total_space
13514 * pow(2.0,
13515 -128 + 48)));
13516 }
13517 } else {
13518 if (!json) {
13519 snprintf(temp_buf, sizeof(temp_buf),
13520 "%12.2f",
13521 ts.total_space * 100.
13522 * pow(2.0, -32));
13523 vty_out(vty, "%30s: %s\n",
13524 "% announced ", temp_buf);
13525 } else {
13526 json_object_double_add(
13527 json, "%announced",
13528 (double)(ts.total_space * 100.
13529 * pow(2.0, -32)));
13530 }
13531 if (!json) {
13532 snprintf(temp_buf, sizeof(temp_buf),
13533 "%12.2f",
13534 ts.total_space
13535 * pow(2.0, -32 + 8));
13536 vty_out(vty, "%30s: %s\n",
13537 "/8 equivalent ", temp_buf);
13538 } else {
13539 json_object_double_add(
13540 json, "/8equivalent",
13541 (double)(ts.total_space
13542 * pow(2.0, -32 + 8)));
13543 }
13544 if (!json) {
13545 snprintf(temp_buf, sizeof(temp_buf),
13546 "%12.2f",
13547 ts.total_space
13548 * pow(2.0, -32 + 24));
13549 vty_out(vty, "%30s: %s\n",
13550 "/24 equivalent ", temp_buf);
13551 } else {
13552 json_object_double_add(
13553 json, "/24equivalent",
13554 (double)(ts.total_space
13555 * pow(2.0, -32 + 24)));
13556 }
13557 }
13558 break;
13559 default:
13560 if (!json) {
13561 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13562 ts.counts[i]);
13563 vty_out(vty, "%-30s: %s",
13564 table_stats_strs[i]
13565 [TABLE_STATS_IDX_VTY],
13566 temp_buf);
13567 } else {
13568 json_object_int_add(
13569 json,
13570 table_stats_strs[i]
13571 [TABLE_STATS_IDX_JSON],
13572 ts.counts[i]);
13573 }
13574 }
13575 if (!json)
13576 vty_out(vty, "\n");
13577 }
13578
13579 switch (afi) {
13580 case AFI_IP:
13581 bitlen = IPV4_MAX_BITLEN;
13582 break;
13583 case AFI_IP6:
13584 bitlen = IPV6_MAX_BITLEN;
13585 break;
13586 case AFI_L2VPN:
13587 bitlen = EVPN_ROUTE_PREFIXLEN;
13588 break;
13589 default:
13590 break;
13591 }
13592
13593 if (json) {
13594 json_bitlen = json_object_new_array();
13595
13596 for (i = 0; i <= bitlen; i++) {
13597 struct json_object *ind_bit = json_object_new_object();
13598
13599 if (!ts.prefix_len_count[i])
13600 continue;
13601
13602 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13603 json_object_int_add(ind_bit, temp_buf,
13604 ts.prefix_len_count[i]);
13605 json_object_array_add(json_bitlen, ind_bit);
13606 }
13607 json_object_object_add(json, "prefixLength", json_bitlen);
13608 }
13609
13610 end_table_stats:
13611 if (json)
13612 json_object_array_add(json_array, json);
13613 return ret;
13614 }
13615
13616 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13617 safi_t safi, struct json_object *json_array)
13618 {
13619 if (!bgp) {
13620 bgp_table_stats_all(vty, afi, safi, json_array);
13621 return CMD_SUCCESS;
13622 }
13623
13624 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13625 }
13626
13627 enum bgp_pcounts {
13628 PCOUNT_ADJ_IN = 0,
13629 PCOUNT_DAMPED,
13630 PCOUNT_REMOVED,
13631 PCOUNT_HISTORY,
13632 PCOUNT_STALE,
13633 PCOUNT_VALID,
13634 PCOUNT_ALL,
13635 PCOUNT_COUNTED,
13636 PCOUNT_BPATH_SELECTED,
13637 PCOUNT_PFCNT, /* the figure we display to users */
13638 PCOUNT_MAX,
13639 };
13640
13641 static const char *const pcount_strs[] = {
13642 [PCOUNT_ADJ_IN] = "Adj-in",
13643 [PCOUNT_DAMPED] = "Damped",
13644 [PCOUNT_REMOVED] = "Removed",
13645 [PCOUNT_HISTORY] = "History",
13646 [PCOUNT_STALE] = "Stale",
13647 [PCOUNT_VALID] = "Valid",
13648 [PCOUNT_ALL] = "All RIB",
13649 [PCOUNT_COUNTED] = "PfxCt counted",
13650 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13651 [PCOUNT_PFCNT] = "Useable",
13652 [PCOUNT_MAX] = NULL,
13653 };
13654
13655 struct peer_pcounts {
13656 unsigned int count[PCOUNT_MAX];
13657 const struct peer *peer;
13658 const struct bgp_table *table;
13659 safi_t safi;
13660 };
13661
13662 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13663 {
13664 const struct bgp_adj_in *ain;
13665 const struct bgp_path_info *pi;
13666 const struct peer *peer = pc->peer;
13667
13668 for (ain = rn->adj_in; ain; ain = ain->next)
13669 if (ain->peer == peer)
13670 pc->count[PCOUNT_ADJ_IN]++;
13671
13672 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13673
13674 if (pi->peer != peer)
13675 continue;
13676
13677 pc->count[PCOUNT_ALL]++;
13678
13679 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13680 pc->count[PCOUNT_DAMPED]++;
13681 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13682 pc->count[PCOUNT_HISTORY]++;
13683 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13684 pc->count[PCOUNT_REMOVED]++;
13685 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13686 pc->count[PCOUNT_STALE]++;
13687 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13688 pc->count[PCOUNT_VALID]++;
13689 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13690 pc->count[PCOUNT_PFCNT]++;
13691 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13692 pc->count[PCOUNT_BPATH_SELECTED]++;
13693
13694 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13695 pc->count[PCOUNT_COUNTED]++;
13696 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13697 flog_err(
13698 EC_LIB_DEVELOPMENT,
13699 "Attempting to count but flags say it is unusable");
13700 } else {
13701 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13702 flog_err(
13703 EC_LIB_DEVELOPMENT,
13704 "Not counted but flags say we should");
13705 }
13706 }
13707 }
13708
13709 static void bgp_peer_count_walker(struct thread *t)
13710 {
13711 struct bgp_dest *rn, *rm;
13712 const struct bgp_table *table;
13713 struct peer_pcounts *pc = THREAD_ARG(t);
13714
13715 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13716 || pc->safi == SAFI_EVPN) {
13717 /* Special handling for 2-level routing tables. */
13718 for (rn = bgp_table_top(pc->table); rn;
13719 rn = bgp_route_next(rn)) {
13720 table = bgp_dest_get_bgp_table_info(rn);
13721 if (table != NULL)
13722 for (rm = bgp_table_top(table); rm;
13723 rm = bgp_route_next(rm))
13724 bgp_peer_count_proc(rm, pc);
13725 }
13726 } else
13727 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13728 bgp_peer_count_proc(rn, pc);
13729 }
13730
13731 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13732 safi_t safi, bool use_json)
13733 {
13734 struct peer_pcounts pcounts = {.peer = peer};
13735 unsigned int i;
13736 json_object *json = NULL;
13737 json_object *json_loop = NULL;
13738
13739 if (use_json) {
13740 json = json_object_new_object();
13741 json_loop = json_object_new_object();
13742 }
13743
13744 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13745 || !peer->bgp->rib[afi][safi]) {
13746 if (use_json) {
13747 json_object_string_add(
13748 json, "warning",
13749 "No such neighbor or address family");
13750 vty_out(vty, "%s\n", json_object_to_json_string(json));
13751 json_object_free(json);
13752 json_object_free(json_loop);
13753 } else
13754 vty_out(vty, "%% No such neighbor or address family\n");
13755
13756 return CMD_WARNING;
13757 }
13758
13759 memset(&pcounts, 0, sizeof(pcounts));
13760 pcounts.peer = peer;
13761 pcounts.table = peer->bgp->rib[afi][safi];
13762 pcounts.safi = safi;
13763
13764 /* in-place call via thread subsystem so as to record execution time
13765 * stats for the thread-walk (i.e. ensure this can't be blamed on
13766 * on just vty_read()).
13767 */
13768 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13769
13770 if (use_json) {
13771 json_object_string_add(json, "prefixCountsFor", peer->host);
13772 json_object_string_add(json, "multiProtocol",
13773 get_afi_safi_str(afi, safi, true));
13774 json_object_int_add(json, "pfxCounter",
13775 peer->pcount[afi][safi]);
13776
13777 for (i = 0; i < PCOUNT_MAX; i++)
13778 json_object_int_add(json_loop, pcount_strs[i],
13779 pcounts.count[i]);
13780
13781 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13782
13783 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13784 json_object_string_add(json, "pfxctDriftFor",
13785 peer->host);
13786 json_object_string_add(
13787 json, "recommended",
13788 "Please report this bug, with the above command output");
13789 }
13790 vty_json(vty, json);
13791 } else {
13792
13793 if (peer->hostname
13794 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13795 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13796 peer->hostname, peer->host,
13797 get_afi_safi_str(afi, safi, false));
13798 } else {
13799 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13800 get_afi_safi_str(afi, safi, false));
13801 }
13802
13803 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13804 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13805
13806 for (i = 0; i < PCOUNT_MAX; i++)
13807 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13808 pcounts.count[i]);
13809
13810 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13811 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13812 vty_out(vty,
13813 "Please report this bug, with the above command output\n");
13814 }
13815 }
13816
13817 return CMD_SUCCESS;
13818 }
13819
13820 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13821 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13822 "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]",
13823 SHOW_STR
13824 IP_STR
13825 BGP_STR
13826 BGP_INSTANCE_HELP_STR
13827 BGP_AFI_HELP_STR
13828 BGP_SAFI_HELP_STR
13829 "Detailed information on TCP and BGP neighbor connections\n"
13830 "Neighbor to display information about\n"
13831 "Neighbor to display information about\n"
13832 "Neighbor on BGP configured interface\n"
13833 "Display detailed prefix count information\n"
13834 JSON_STR)
13835 {
13836 afi_t afi = AFI_IP6;
13837 safi_t safi = SAFI_UNICAST;
13838 struct peer *peer;
13839 int idx = 0;
13840 struct bgp *bgp = NULL;
13841 bool uj = use_json(argc, argv);
13842
13843 if (uj)
13844 argc--;
13845
13846 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13847 &bgp, uj);
13848 if (!idx)
13849 return CMD_WARNING;
13850
13851 argv_find(argv, argc, "neighbors", &idx);
13852 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13853 if (!peer)
13854 return CMD_WARNING;
13855
13856 return bgp_peer_counts(vty, peer, afi, safi, uj);
13857 }
13858
13859 #ifdef KEEP_OLD_VPN_COMMANDS
13860 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13861 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13862 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13863 SHOW_STR
13864 IP_STR
13865 BGP_STR
13866 BGP_VPNVX_HELP_STR
13867 "Display information about all VPNv4 NLRIs\n"
13868 "Detailed information on TCP and BGP neighbor connections\n"
13869 "Neighbor to display information about\n"
13870 "Neighbor to display information about\n"
13871 "Neighbor on BGP configured interface\n"
13872 "Display detailed prefix count information\n"
13873 JSON_STR)
13874 {
13875 int idx_peer = 6;
13876 struct peer *peer;
13877 bool uj = use_json(argc, argv);
13878
13879 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13880 if (!peer)
13881 return CMD_WARNING;
13882
13883 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13884 }
13885
13886 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13887 show_ip_bgp_vpn_all_route_prefix_cmd,
13888 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13889 SHOW_STR
13890 IP_STR
13891 BGP_STR
13892 BGP_VPNVX_HELP_STR
13893 "Display information about all VPNv4 NLRIs\n"
13894 "Network in the BGP routing table to display\n"
13895 "Network in the BGP routing table to display\n"
13896 JSON_STR)
13897 {
13898 int idx = 0;
13899 char *network = NULL;
13900 struct bgp *bgp = bgp_get_default();
13901 if (!bgp) {
13902 vty_out(vty, "Can't find default instance\n");
13903 return CMD_WARNING;
13904 }
13905
13906 if (argv_find(argv, argc, "A.B.C.D", &idx))
13907 network = argv[idx]->arg;
13908 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13909 network = argv[idx]->arg;
13910 else {
13911 vty_out(vty, "Unable to figure out Network\n");
13912 return CMD_WARNING;
13913 }
13914
13915 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13916 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13917 use_json(argc, argv));
13918 }
13919 #endif /* KEEP_OLD_VPN_COMMANDS */
13920
13921 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13922 show_bgp_l2vpn_evpn_route_prefix_cmd,
13923 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13924 SHOW_STR
13925 BGP_STR
13926 L2VPN_HELP_STR
13927 EVPN_HELP_STR
13928 "Network in the BGP routing table to display\n"
13929 "Network in the BGP routing table to display\n"
13930 "Network in the BGP routing table to display\n"
13931 "Network in the BGP routing table to display\n"
13932 JSON_STR)
13933 {
13934 int idx = 0;
13935 char *network = NULL;
13936 int prefix_check = 0;
13937
13938 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13939 argv_find(argv, argc, "X:X::X:X", &idx))
13940 network = argv[idx]->arg;
13941 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13942 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13943 network = argv[idx]->arg;
13944 prefix_check = 1;
13945 } else {
13946 vty_out(vty, "Unable to figure out Network\n");
13947 return CMD_WARNING;
13948 }
13949 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13950 prefix_check, BGP_PATH_SHOW_ALL,
13951 RPKI_NOT_BEING_USED, use_json(argc, argv));
13952 }
13953
13954 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13955 struct bgp_table *table, int *header1,
13956 int *header2, json_object *json,
13957 json_object *json_scode,
13958 json_object *json_ocode, bool wide)
13959 {
13960 uint64_t version = table ? table->version : 0;
13961
13962 if (*header1) {
13963 if (json) {
13964 json_object_int_add(json, "bgpTableVersion", version);
13965 json_object_string_addf(json, "bgpLocalRouterId",
13966 "%pI4", &peer->bgp->router_id);
13967 json_object_int_add(json, "defaultLocPrf",
13968 peer->bgp->default_local_pref);
13969 json_object_int_add(json, "localAS",
13970 peer->change_local_as
13971 ? peer->change_local_as
13972 : peer->local_as);
13973 json_object_object_add(json, "bgpStatusCodes",
13974 json_scode);
13975 json_object_object_add(json, "bgpOriginCodes",
13976 json_ocode);
13977 } else {
13978 vty_out(vty,
13979 "BGP table version is %" PRIu64
13980 ", local router ID is %pI4, vrf id ",
13981 version, &peer->bgp->router_id);
13982 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13983 vty_out(vty, "%s", VRFID_NONE_STR);
13984 else
13985 vty_out(vty, "%u", peer->bgp->vrf_id);
13986 vty_out(vty, "\n");
13987 vty_out(vty, "Default local pref %u, ",
13988 peer->bgp->default_local_pref);
13989 vty_out(vty, "local AS %u\n",
13990 peer->change_local_as ? peer->change_local_as
13991 : peer->local_as);
13992 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13993 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13994 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13995 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13996 }
13997 *header1 = 0;
13998 }
13999 if (*header2) {
14000 if (!json)
14001 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14002 : BGP_SHOW_HEADER));
14003 *header2 = 0;
14004 }
14005 }
14006
14007 static void
14008 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14009 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14010 const char *rmap_name, json_object *json, json_object *json_ar,
14011 json_object *json_scode, json_object *json_ocode,
14012 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14013 unsigned long *output_count, unsigned long *filtered_count)
14014 {
14015 struct bgp_adj_in *ain;
14016 struct bgp_adj_out *adj;
14017 struct bgp_dest *dest;
14018 struct bgp *bgp;
14019 struct attr attr;
14020 int ret;
14021 struct update_subgroup *subgrp;
14022 struct peer_af *paf;
14023 bool route_filtered;
14024 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14025 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14026 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14027 || (safi == SAFI_EVPN))
14028 ? true
14029 : false;
14030
14031 bgp = peer->bgp;
14032
14033 subgrp = peer_subgroup(peer, afi, safi);
14034
14035 if (type == bgp_show_adj_route_advertised && subgrp
14036 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14037 if (use_json) {
14038 json_object_int_add(json, "bgpTableVersion",
14039 table->version);
14040 json_object_string_addf(json, "bgpLocalRouterId",
14041 "%pI4", &bgp->router_id);
14042 json_object_int_add(json, "defaultLocPrf",
14043 bgp->default_local_pref);
14044 json_object_int_add(json, "localAS",
14045 peer->change_local_as
14046 ? peer->change_local_as
14047 : peer->local_as);
14048 json_object_object_add(json, "bgpStatusCodes",
14049 json_scode);
14050 json_object_object_add(json, "bgpOriginCodes",
14051 json_ocode);
14052 json_object_string_add(
14053 json, "bgpOriginatingDefaultNetwork",
14054 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14055 } else {
14056 vty_out(vty,
14057 "BGP table version is %" PRIu64
14058 ", local router ID is %pI4, vrf id ",
14059 table->version, &bgp->router_id);
14060 if (bgp->vrf_id == VRF_UNKNOWN)
14061 vty_out(vty, "%s", VRFID_NONE_STR);
14062 else
14063 vty_out(vty, "%u", bgp->vrf_id);
14064 vty_out(vty, "\n");
14065 vty_out(vty, "Default local pref %u, ",
14066 bgp->default_local_pref);
14067 vty_out(vty, "local AS %u\n",
14068 peer->change_local_as ? peer->change_local_as
14069 : peer->local_as);
14070 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14071 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14072 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14073 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14074
14075 vty_out(vty, "Originating default network %s\n\n",
14076 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14077 }
14078 *header1 = 0;
14079 }
14080
14081 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14082 if (type == bgp_show_adj_route_received
14083 || type == bgp_show_adj_route_filtered) {
14084 for (ain = dest->adj_in; ain; ain = ain->next) {
14085 if (ain->peer != peer)
14086 continue;
14087
14088 show_adj_route_header(vty, peer, table, header1,
14089 header2, json, json_scode,
14090 json_ocode, wide);
14091
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, "rd", rd_str);
14098 else if (show_rd && rd_str) {
14099 vty_out(vty,
14100 "Route Distinguisher: %s\n",
14101 rd_str);
14102 show_rd = false;
14103 }
14104 }
14105
14106 attr = *ain->attr;
14107 route_filtered = false;
14108
14109 /* Filter prefix using distribute list,
14110 * filter list or prefix list
14111 */
14112 const struct prefix *rn_p =
14113 bgp_dest_get_prefix(dest);
14114 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14115 safi))
14116 == FILTER_DENY)
14117 route_filtered = true;
14118
14119 /* Filter prefix using route-map */
14120 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14121 safi, rmap_name, NULL,
14122 0, NULL);
14123
14124 if (type == bgp_show_adj_route_filtered &&
14125 !route_filtered && ret != RMAP_DENY) {
14126 bgp_attr_flush(&attr);
14127 continue;
14128 }
14129
14130 if (type == bgp_show_adj_route_received
14131 && (route_filtered || ret == RMAP_DENY))
14132 (*filtered_count)++;
14133
14134 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
14135 use_json, json_ar, wide);
14136 bgp_attr_flush(&attr);
14137 (*output_count)++;
14138 }
14139 } else if (type == bgp_show_adj_route_advertised) {
14140 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14141 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14142 if (paf->peer != peer || !adj->attr)
14143 continue;
14144
14145 show_adj_route_header(vty, peer, table,
14146 header1, header2,
14147 json, json_scode,
14148 json_ocode, wide);
14149
14150 const struct prefix *rn_p =
14151 bgp_dest_get_prefix(dest);
14152
14153 attr = *adj->attr;
14154 ret = bgp_output_modifier(
14155 peer, rn_p, &attr, afi, safi,
14156 rmap_name);
14157
14158 if (ret != RMAP_DENY) {
14159 if ((safi == SAFI_MPLS_VPN)
14160 || (safi == SAFI_ENCAP)
14161 || (safi == SAFI_EVPN)) {
14162 if (use_json)
14163 json_object_string_add(
14164 json_ar,
14165 "rd",
14166 rd_str);
14167 else if (show_rd
14168 && rd_str) {
14169 vty_out(vty,
14170 "Route Distinguisher: %s\n",
14171 rd_str);
14172 show_rd = false;
14173 }
14174 }
14175 route_vty_out_tmp(
14176 vty, dest, rn_p, &attr,
14177 safi, use_json, json_ar,
14178 wide);
14179 (*output_count)++;
14180 } else {
14181 (*filtered_count)++;
14182 }
14183
14184 bgp_attr_flush(&attr);
14185 }
14186 } else if (type == bgp_show_adj_route_bestpath) {
14187 struct bgp_path_info *pi;
14188
14189 show_adj_route_header(vty, peer, table, header1,
14190 header2, json, json_scode,
14191 json_ocode, wide);
14192
14193 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14194 pi = pi->next) {
14195 if (pi->peer != peer)
14196 continue;
14197
14198 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14199 continue;
14200
14201 route_vty_out_tmp(vty, dest,
14202 bgp_dest_get_prefix(dest),
14203 pi->attr, safi, use_json,
14204 json_ar, wide);
14205 (*output_count)++;
14206 }
14207 }
14208 }
14209 }
14210
14211 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14212 safi_t safi, enum bgp_show_adj_route_type type,
14213 const char *rmap_name, uint16_t show_flags)
14214 {
14215 struct bgp *bgp;
14216 struct bgp_table *table;
14217 json_object *json = NULL;
14218 json_object *json_scode = NULL;
14219 json_object *json_ocode = NULL;
14220 json_object *json_ar = NULL;
14221 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14222
14223 /* Init BGP headers here so they're only displayed once
14224 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14225 */
14226 int header1 = 1;
14227 int header2 = 1;
14228
14229 /*
14230 * Initialize variables for each RD
14231 * All prefixes under an RD is aggregated within "json_routes"
14232 */
14233 char rd_str[BUFSIZ] = {0};
14234 json_object *json_routes = NULL;
14235
14236
14237 /* For 2-tier tables, prefix counts need to be
14238 * maintained across multiple runs of show_adj_route()
14239 */
14240 unsigned long output_count_per_rd;
14241 unsigned long filtered_count_per_rd;
14242 unsigned long output_count = 0;
14243 unsigned long filtered_count = 0;
14244
14245 if (use_json) {
14246 json = json_object_new_object();
14247 json_ar = json_object_new_object();
14248 json_scode = json_object_new_object();
14249 json_ocode = json_object_new_object();
14250
14251 json_object_string_add(json_scode, "suppressed", "s");
14252 json_object_string_add(json_scode, "damped", "d");
14253 json_object_string_add(json_scode, "history", "h");
14254 json_object_string_add(json_scode, "valid", "*");
14255 json_object_string_add(json_scode, "best", ">");
14256 json_object_string_add(json_scode, "multipath", "=");
14257 json_object_string_add(json_scode, "internal", "i");
14258 json_object_string_add(json_scode, "ribFailure", "r");
14259 json_object_string_add(json_scode, "stale", "S");
14260 json_object_string_add(json_scode, "removed", "R");
14261
14262 json_object_string_add(json_ocode, "igp", "i");
14263 json_object_string_add(json_ocode, "egp", "e");
14264 json_object_string_add(json_ocode, "incomplete", "?");
14265 }
14266
14267 if (!peer || !peer->afc[afi][safi]) {
14268 if (use_json) {
14269 json_object_string_add(
14270 json, "warning",
14271 "No such neighbor or address family");
14272 vty_out(vty, "%s\n", json_object_to_json_string(json));
14273 json_object_free(json);
14274 json_object_free(json_ar);
14275 json_object_free(json_scode);
14276 json_object_free(json_ocode);
14277 } else
14278 vty_out(vty, "%% No such neighbor or address family\n");
14279
14280 return CMD_WARNING;
14281 }
14282
14283 if ((type == bgp_show_adj_route_received
14284 || type == bgp_show_adj_route_filtered)
14285 && !CHECK_FLAG(peer->af_flags[afi][safi],
14286 PEER_FLAG_SOFT_RECONFIG)) {
14287 if (use_json) {
14288 json_object_string_add(
14289 json, "warning",
14290 "Inbound soft reconfiguration not enabled");
14291 vty_out(vty, "%s\n", json_object_to_json_string(json));
14292 json_object_free(json);
14293 json_object_free(json_ar);
14294 json_object_free(json_scode);
14295 json_object_free(json_ocode);
14296 } else
14297 vty_out(vty,
14298 "%% Inbound soft reconfiguration not enabled\n");
14299
14300 return CMD_WARNING;
14301 }
14302
14303 bgp = peer->bgp;
14304
14305 /* labeled-unicast routes live in the unicast table */
14306 if (safi == SAFI_LABELED_UNICAST)
14307 table = bgp->rib[afi][SAFI_UNICAST];
14308 else
14309 table = bgp->rib[afi][safi];
14310
14311 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14312 || (safi == SAFI_EVPN)) {
14313
14314 struct bgp_dest *dest;
14315
14316 for (dest = bgp_table_top(table); dest;
14317 dest = bgp_route_next(dest)) {
14318 table = bgp_dest_get_bgp_table_info(dest);
14319 if (!table)
14320 continue;
14321
14322 output_count_per_rd = 0;
14323 filtered_count_per_rd = 0;
14324
14325 if (use_json)
14326 json_routes = json_object_new_object();
14327
14328 const struct prefix_rd *prd;
14329 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14330 dest);
14331
14332 prefix_rd2str(prd, rd_str, sizeof(rd_str));
14333
14334 show_adj_route(vty, peer, table, afi, safi, type,
14335 rmap_name, json, json_routes, json_scode,
14336 json_ocode, show_flags, &header1,
14337 &header2, rd_str, &output_count_per_rd,
14338 &filtered_count_per_rd);
14339
14340 /* Don't include an empty RD in the output! */
14341 if (json_routes && (output_count_per_rd > 0))
14342 json_object_object_add(json_ar, rd_str,
14343 json_routes);
14344
14345 output_count += output_count_per_rd;
14346 filtered_count += filtered_count_per_rd;
14347 }
14348 } else
14349 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14350 json, json_ar, json_scode, json_ocode,
14351 show_flags, &header1, &header2, rd_str,
14352 &output_count, &filtered_count);
14353
14354 if (use_json) {
14355 if (type == bgp_show_adj_route_advertised)
14356 json_object_object_add(json, "advertisedRoutes",
14357 json_ar);
14358 else
14359 json_object_object_add(json, "receivedRoutes", json_ar);
14360 json_object_int_add(json, "totalPrefixCounter", output_count);
14361 json_object_int_add(json, "filteredPrefixCounter",
14362 filtered_count);
14363
14364 /*
14365 * These fields only give up ownership to `json` when `header1`
14366 * is used (set to zero). See code in `show_adj_route` and
14367 * `show_adj_route_header`.
14368 */
14369 if (header1 == 1) {
14370 json_object_free(json_scode);
14371 json_object_free(json_ocode);
14372 }
14373
14374 vty_json(vty, json);
14375 } else if (output_count > 0) {
14376 if (filtered_count > 0)
14377 vty_out(vty,
14378 "\nTotal number of prefixes %ld (%ld filtered)\n",
14379 output_count, filtered_count);
14380 else
14381 vty_out(vty, "\nTotal number of prefixes %ld\n",
14382 output_count);
14383 }
14384
14385 return CMD_SUCCESS;
14386 }
14387
14388 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14389 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14390 "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]",
14391 SHOW_STR
14392 IP_STR
14393 BGP_STR
14394 BGP_INSTANCE_HELP_STR
14395 BGP_AFI_HELP_STR
14396 BGP_SAFI_WITH_LABEL_HELP_STR
14397 "Detailed information on TCP and BGP neighbor connections\n"
14398 "Neighbor to display information about\n"
14399 "Neighbor to display information about\n"
14400 "Neighbor on BGP configured interface\n"
14401 "Display the routes selected by best path\n"
14402 JSON_STR
14403 "Increase table width for longer prefixes\n")
14404 {
14405 afi_t afi = AFI_IP6;
14406 safi_t safi = SAFI_UNICAST;
14407 char *rmap_name = NULL;
14408 char *peerstr = NULL;
14409 struct bgp *bgp = NULL;
14410 struct peer *peer;
14411 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14412 int idx = 0;
14413 uint16_t show_flags = 0;
14414
14415 if (uj)
14416 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14417
14418 if (wide)
14419 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14420
14421 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14422 &bgp, uj);
14423
14424 if (!idx)
14425 return CMD_WARNING;
14426
14427 argv_find(argv, argc, "neighbors", &idx);
14428 peerstr = argv[++idx]->arg;
14429
14430 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14431 if (!peer)
14432 return CMD_WARNING;
14433
14434 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14435 show_flags);
14436 }
14437
14438 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
14439 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14440 "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]",
14441 SHOW_STR
14442 IP_STR
14443 BGP_STR
14444 BGP_INSTANCE_HELP_STR
14445 BGP_AFI_HELP_STR
14446 BGP_SAFI_WITH_LABEL_HELP_STR
14447 "Display the entries for all address families\n"
14448 "Detailed information on TCP and BGP neighbor connections\n"
14449 "Neighbor to display information about\n"
14450 "Neighbor to display information about\n"
14451 "Neighbor on BGP configured interface\n"
14452 "Display the routes advertised to a BGP neighbor\n"
14453 "Display the received routes from neighbor\n"
14454 "Display the filtered routes received from neighbor\n"
14455 "Route-map to modify the attributes\n"
14456 "Name of the route map\n"
14457 JSON_STR
14458 "Increase table width for longer prefixes\n")
14459 {
14460 afi_t afi = AFI_IP6;
14461 safi_t safi = SAFI_UNICAST;
14462 char *peerstr = NULL;
14463 struct bgp *bgp = NULL;
14464 struct peer *peer;
14465 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14466 int idx = 0;
14467 bool first = true;
14468 uint16_t show_flags = 0;
14469 struct listnode *node;
14470 struct bgp *abgp;
14471
14472 if (uj) {
14473 argc--;
14474 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14475 }
14476
14477 if (all) {
14478 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14479 if (argv_find(argv, argc, "ipv4", &idx))
14480 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14481
14482 if (argv_find(argv, argc, "ipv6", &idx))
14483 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14484 }
14485
14486 if (wide)
14487 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14488
14489 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14490 &bgp, uj);
14491 if (!idx)
14492 return CMD_WARNING;
14493
14494 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14495 argv_find(argv, argc, "neighbors", &idx);
14496 peerstr = argv[++idx]->arg;
14497
14498 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14499 if (!peer)
14500 return CMD_WARNING;
14501
14502 if (argv_find(argv, argc, "advertised-routes", &idx))
14503 type = bgp_show_adj_route_advertised;
14504 else if (argv_find(argv, argc, "received-routes", &idx))
14505 type = bgp_show_adj_route_received;
14506 else if (argv_find(argv, argc, "filtered-routes", &idx))
14507 type = bgp_show_adj_route_filtered;
14508
14509 if (!all)
14510 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14511 show_flags);
14512 if (uj)
14513 vty_out(vty, "{\n");
14514
14515 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14516 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14517 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14518 : AFI_IP6;
14519 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14520 FOREACH_SAFI (safi) {
14521 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14522 continue;
14523
14524 if (uj) {
14525 if (first)
14526 first = false;
14527 else
14528 vty_out(vty, ",\n");
14529 vty_out(vty, "\"%s\":",
14530 get_afi_safi_str(afi, safi,
14531 true));
14532 } else
14533 vty_out(vty,
14534 "\nFor address family: %s\n",
14535 get_afi_safi_str(afi, safi,
14536 false));
14537
14538 peer_adj_routes(vty, peer, afi, safi, type,
14539 route_map, show_flags);
14540 }
14541 }
14542 } else {
14543 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14544 FOREACH_AFI_SAFI (afi, safi) {
14545 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14546 continue;
14547
14548 if (uj) {
14549 if (first)
14550 first = false;
14551 else
14552 vty_out(vty, ",\n");
14553 vty_out(vty, "\"%s\":",
14554 get_afi_safi_str(afi, safi,
14555 true));
14556 } else
14557 vty_out(vty,
14558 "\nFor address family: %s\n",
14559 get_afi_safi_str(afi, safi,
14560 false));
14561
14562 peer_adj_routes(vty, peer, afi, safi, type,
14563 route_map, show_flags);
14564 }
14565 }
14566 }
14567 if (uj)
14568 vty_out(vty, "}\n");
14569
14570 return CMD_SUCCESS;
14571 }
14572
14573 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14574 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14575 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14576 SHOW_STR
14577 IP_STR
14578 BGP_STR
14579 BGP_INSTANCE_HELP_STR
14580 BGP_AF_STR
14581 BGP_AF_STR
14582 BGP_AF_MODIFIER_STR
14583 "Detailed information on TCP and BGP neighbor connections\n"
14584 "Neighbor to display information about\n"
14585 "Neighbor to display information about\n"
14586 "Neighbor on BGP configured interface\n"
14587 "Display information received from a BGP neighbor\n"
14588 "Display the prefixlist filter\n"
14589 JSON_STR)
14590 {
14591 afi_t afi = AFI_IP6;
14592 safi_t safi = SAFI_UNICAST;
14593 char *peerstr = NULL;
14594 char name[BUFSIZ];
14595 struct peer *peer;
14596 int count;
14597 int idx = 0;
14598 struct bgp *bgp = NULL;
14599 bool uj = use_json(argc, argv);
14600
14601 if (uj)
14602 argc--;
14603
14604 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14605 &bgp, uj);
14606 if (!idx)
14607 return CMD_WARNING;
14608
14609 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14610 argv_find(argv, argc, "neighbors", &idx);
14611 peerstr = argv[++idx]->arg;
14612
14613 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14614 if (!peer)
14615 return CMD_WARNING;
14616
14617 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14618 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14619 if (count) {
14620 if (!uj)
14621 vty_out(vty, "Address Family: %s\n",
14622 get_afi_safi_str(afi, safi, false));
14623 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14624 } else {
14625 if (uj)
14626 vty_out(vty, "{}\n");
14627 else
14628 vty_out(vty, "No functional output\n");
14629 }
14630
14631 return CMD_SUCCESS;
14632 }
14633
14634 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14635 afi_t afi, safi_t safi,
14636 enum bgp_show_type type, bool use_json)
14637 {
14638 uint16_t show_flags = 0;
14639
14640 if (use_json)
14641 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14642
14643 if (!peer || !peer->afc[afi][safi]) {
14644 if (use_json) {
14645 json_object *json_no = NULL;
14646 json_no = json_object_new_object();
14647 json_object_string_add(
14648 json_no, "warning",
14649 "No such neighbor or address family");
14650 vty_out(vty, "%s\n",
14651 json_object_to_json_string(json_no));
14652 json_object_free(json_no);
14653 } else
14654 vty_out(vty, "%% No such neighbor or address family\n");
14655 return CMD_WARNING;
14656 }
14657
14658 /* labeled-unicast routes live in the unicast table */
14659 if (safi == SAFI_LABELED_UNICAST)
14660 safi = SAFI_UNICAST;
14661
14662 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14663 RPKI_NOT_BEING_USED);
14664 }
14665
14666 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14667 show_ip_bgp_flowspec_routes_detailed_cmd,
14668 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14669 SHOW_STR
14670 IP_STR
14671 BGP_STR
14672 BGP_INSTANCE_HELP_STR
14673 BGP_AFI_HELP_STR
14674 "SAFI Flowspec\n"
14675 "Detailed information on flowspec entries\n"
14676 JSON_STR)
14677 {
14678 afi_t afi = AFI_IP6;
14679 safi_t safi = SAFI_UNICAST;
14680 struct bgp *bgp = NULL;
14681 int idx = 0;
14682 bool uj = use_json(argc, argv);
14683 uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
14684
14685 if (uj) {
14686 argc--;
14687 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14688 }
14689
14690 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14691 &bgp, uj);
14692 if (!idx)
14693 return CMD_WARNING;
14694
14695 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14696 show_flags, RPKI_NOT_BEING_USED);
14697 }
14698
14699 DEFUN (show_ip_bgp_neighbor_routes,
14700 show_ip_bgp_neighbor_routes_cmd,
14701 "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]",
14702 SHOW_STR
14703 IP_STR
14704 BGP_STR
14705 BGP_INSTANCE_HELP_STR
14706 BGP_AFI_HELP_STR
14707 BGP_SAFI_WITH_LABEL_HELP_STR
14708 "Detailed information on TCP and BGP neighbor connections\n"
14709 "Neighbor to display information about\n"
14710 "Neighbor to display information about\n"
14711 "Neighbor on BGP configured interface\n"
14712 "Display flap statistics of the routes learned from neighbor\n"
14713 "Display the dampened routes received from neighbor\n"
14714 "Display routes learned from neighbor\n"
14715 JSON_STR)
14716 {
14717 char *peerstr = NULL;
14718 struct bgp *bgp = NULL;
14719 afi_t afi = AFI_IP6;
14720 safi_t safi = SAFI_UNICAST;
14721 struct peer *peer;
14722 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14723 int idx = 0;
14724 bool uj = use_json(argc, argv);
14725
14726 if (uj)
14727 argc--;
14728
14729 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14730 &bgp, uj);
14731 if (!idx)
14732 return CMD_WARNING;
14733
14734 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14735 argv_find(argv, argc, "neighbors", &idx);
14736 peerstr = argv[++idx]->arg;
14737
14738 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14739 if (!peer)
14740 return CMD_WARNING;
14741
14742 if (argv_find(argv, argc, "flap-statistics", &idx))
14743 sh_type = bgp_show_type_flap_neighbor;
14744 else if (argv_find(argv, argc, "dampened-routes", &idx))
14745 sh_type = bgp_show_type_damp_neighbor;
14746 else if (argv_find(argv, argc, "routes", &idx))
14747 sh_type = bgp_show_type_neighbor;
14748
14749 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14750 }
14751
14752 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14753
14754 struct bgp_distance {
14755 /* Distance value for the IP source prefix. */
14756 uint8_t distance;
14757
14758 /* Name of the access-list to be matched. */
14759 char *access_list;
14760 };
14761
14762 DEFUN (show_bgp_afi_vpn_rd_route,
14763 show_bgp_afi_vpn_rd_route_cmd,
14764 "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]",
14765 SHOW_STR
14766 BGP_STR
14767 BGP_AFI_HELP_STR
14768 BGP_AF_MODIFIER_STR
14769 "Display information for a route distinguisher\n"
14770 "Route Distinguisher\n"
14771 "All Route Distinguishers\n"
14772 "Network in the BGP routing table to display\n"
14773 "Network in the BGP routing table to display\n"
14774 JSON_STR)
14775 {
14776 int ret;
14777 struct prefix_rd prd;
14778 afi_t afi = AFI_MAX;
14779 int idx = 0;
14780
14781 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14782 vty_out(vty, "%% Malformed Address Family\n");
14783 return CMD_WARNING;
14784 }
14785
14786 if (!strcmp(argv[5]->arg, "all"))
14787 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14788 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14789 RPKI_NOT_BEING_USED,
14790 use_json(argc, argv));
14791
14792 ret = str2prefix_rd(argv[5]->arg, &prd);
14793 if (!ret) {
14794 vty_out(vty, "%% Malformed Route Distinguisher\n");
14795 return CMD_WARNING;
14796 }
14797
14798 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14799 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14800 use_json(argc, argv));
14801 }
14802
14803 static struct bgp_distance *bgp_distance_new(void)
14804 {
14805 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14806 }
14807
14808 static void bgp_distance_free(struct bgp_distance *bdistance)
14809 {
14810 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14811 }
14812
14813 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14814 const char *ip_str, const char *access_list_str)
14815 {
14816 int ret;
14817 afi_t afi;
14818 safi_t safi;
14819 struct prefix p;
14820 uint8_t distance;
14821 struct bgp_dest *dest;
14822 struct bgp_distance *bdistance;
14823
14824 afi = bgp_node_afi(vty);
14825 safi = bgp_node_safi(vty);
14826
14827 ret = str2prefix(ip_str, &p);
14828 if (ret == 0) {
14829 vty_out(vty, "Malformed prefix\n");
14830 return CMD_WARNING_CONFIG_FAILED;
14831 }
14832
14833 distance = atoi(distance_str);
14834
14835 /* Get BGP distance node. */
14836 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14837 bdistance = bgp_dest_get_bgp_distance_info(dest);
14838 if (bdistance)
14839 bgp_dest_unlock_node(dest);
14840 else {
14841 bdistance = bgp_distance_new();
14842 bgp_dest_set_bgp_distance_info(dest, bdistance);
14843 }
14844
14845 /* Set distance value. */
14846 bdistance->distance = distance;
14847
14848 /* Reset access-list configuration. */
14849 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14850 if (access_list_str)
14851 bdistance->access_list =
14852 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14853
14854 return CMD_SUCCESS;
14855 }
14856
14857 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14858 const char *ip_str, const char *access_list_str)
14859 {
14860 int ret;
14861 afi_t afi;
14862 safi_t safi;
14863 struct prefix p;
14864 int distance;
14865 struct bgp_dest *dest;
14866 struct bgp_distance *bdistance;
14867
14868 afi = bgp_node_afi(vty);
14869 safi = bgp_node_safi(vty);
14870
14871 ret = str2prefix(ip_str, &p);
14872 if (ret == 0) {
14873 vty_out(vty, "Malformed prefix\n");
14874 return CMD_WARNING_CONFIG_FAILED;
14875 }
14876
14877 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14878 if (!dest) {
14879 vty_out(vty, "Can't find specified prefix\n");
14880 return CMD_WARNING_CONFIG_FAILED;
14881 }
14882
14883 bdistance = bgp_dest_get_bgp_distance_info(dest);
14884 distance = atoi(distance_str);
14885
14886 if (bdistance->distance != distance) {
14887 vty_out(vty, "Distance does not match configured\n");
14888 bgp_dest_unlock_node(dest);
14889 return CMD_WARNING_CONFIG_FAILED;
14890 }
14891
14892 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14893 bgp_distance_free(bdistance);
14894
14895 bgp_dest_set_bgp_path_info(dest, NULL);
14896 bgp_dest_unlock_node(dest);
14897 bgp_dest_unlock_node(dest);
14898
14899 return CMD_SUCCESS;
14900 }
14901
14902 /* Apply BGP information to distance method. */
14903 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14904 afi_t afi, safi_t safi, struct bgp *bgp)
14905 {
14906 struct bgp_dest *dest;
14907 struct prefix q = {0};
14908 struct peer *peer;
14909 struct bgp_distance *bdistance;
14910 struct access_list *alist;
14911 struct bgp_static *bgp_static;
14912
14913 if (!bgp)
14914 return 0;
14915
14916 peer = pinfo->peer;
14917
14918 if (pinfo->attr->distance)
14919 return pinfo->attr->distance;
14920
14921 /* Check source address.
14922 * Note: for aggregate route, peer can have unspec af type.
14923 */
14924 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14925 && !sockunion2hostprefix(&peer->su, &q))
14926 return 0;
14927
14928 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14929 if (dest) {
14930 bdistance = bgp_dest_get_bgp_distance_info(dest);
14931 bgp_dest_unlock_node(dest);
14932
14933 if (bdistance->access_list) {
14934 alist = access_list_lookup(afi, bdistance->access_list);
14935 if (alist
14936 && access_list_apply(alist, p) == FILTER_PERMIT)
14937 return bdistance->distance;
14938 } else
14939 return bdistance->distance;
14940 }
14941
14942 /* Backdoor check. */
14943 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14944 if (dest) {
14945 bgp_static = bgp_dest_get_bgp_static_info(dest);
14946 bgp_dest_unlock_node(dest);
14947
14948 if (bgp_static->backdoor) {
14949 if (bgp->distance_local[afi][safi])
14950 return bgp->distance_local[afi][safi];
14951 else
14952 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14953 }
14954 }
14955
14956 if (peer->sort == BGP_PEER_EBGP) {
14957 if (bgp->distance_ebgp[afi][safi])
14958 return bgp->distance_ebgp[afi][safi];
14959 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14960 } else if (peer->sort == BGP_PEER_IBGP) {
14961 if (bgp->distance_ibgp[afi][safi])
14962 return bgp->distance_ibgp[afi][safi];
14963 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14964 } else {
14965 if (bgp->distance_local[afi][safi])
14966 return bgp->distance_local[afi][safi];
14967 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14968 }
14969 }
14970
14971 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14972 * we should tell ZEBRA update the routes for a specific
14973 * AFI/SAFI to reflect changes in RIB.
14974 */
14975 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14976 afi_t update_afi,
14977 safi_t update_safi)
14978 {
14979 afi_t afi;
14980 safi_t safi;
14981
14982 FOREACH_AFI_SAFI (afi, safi) {
14983 if (!bgp_fibupd_safi(safi))
14984 continue;
14985
14986 if (afi != update_afi && safi != update_safi)
14987 continue;
14988
14989 if (BGP_DEBUG(zebra, ZEBRA))
14990 zlog_debug(
14991 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14992 __func__, afi, safi);
14993 bgp_zebra_announce_table(bgp, afi, safi);
14994 }
14995 }
14996
14997 DEFUN (bgp_distance,
14998 bgp_distance_cmd,
14999 "distance bgp (1-255) (1-255) (1-255)",
15000 "Define an administrative distance\n"
15001 "BGP distance\n"
15002 "Distance for routes external to the AS\n"
15003 "Distance for routes internal to the AS\n"
15004 "Distance for local routes\n")
15005 {
15006 VTY_DECLVAR_CONTEXT(bgp, bgp);
15007 int idx_number = 2;
15008 int idx_number_2 = 3;
15009 int idx_number_3 = 4;
15010 int distance_ebgp = atoi(argv[idx_number]->arg);
15011 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15012 int distance_local = atoi(argv[idx_number_3]->arg);
15013 afi_t afi;
15014 safi_t safi;
15015
15016 afi = bgp_node_afi(vty);
15017 safi = bgp_node_safi(vty);
15018
15019 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15020 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15021 || bgp->distance_local[afi][safi] != distance_local) {
15022 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15023 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15024 bgp->distance_local[afi][safi] = distance_local;
15025 bgp_announce_routes_distance_update(bgp, afi, safi);
15026 }
15027 return CMD_SUCCESS;
15028 }
15029
15030 DEFUN (no_bgp_distance,
15031 no_bgp_distance_cmd,
15032 "no distance bgp [(1-255) (1-255) (1-255)]",
15033 NO_STR
15034 "Define an administrative distance\n"
15035 "BGP distance\n"
15036 "Distance for routes external to the AS\n"
15037 "Distance for routes internal to the AS\n"
15038 "Distance for local routes\n")
15039 {
15040 VTY_DECLVAR_CONTEXT(bgp, bgp);
15041 afi_t afi;
15042 safi_t safi;
15043
15044 afi = bgp_node_afi(vty);
15045 safi = bgp_node_safi(vty);
15046
15047 if (bgp->distance_ebgp[afi][safi] != 0
15048 || bgp->distance_ibgp[afi][safi] != 0
15049 || bgp->distance_local[afi][safi] != 0) {
15050 bgp->distance_ebgp[afi][safi] = 0;
15051 bgp->distance_ibgp[afi][safi] = 0;
15052 bgp->distance_local[afi][safi] = 0;
15053 bgp_announce_routes_distance_update(bgp, afi, safi);
15054 }
15055 return CMD_SUCCESS;
15056 }
15057
15058
15059 DEFUN (bgp_distance_source,
15060 bgp_distance_source_cmd,
15061 "distance (1-255) A.B.C.D/M",
15062 "Define an administrative distance\n"
15063 "Administrative distance\n"
15064 "IP source prefix\n")
15065 {
15066 int idx_number = 1;
15067 int idx_ipv4_prefixlen = 2;
15068 bgp_distance_set(vty, argv[idx_number]->arg,
15069 argv[idx_ipv4_prefixlen]->arg, NULL);
15070 return CMD_SUCCESS;
15071 }
15072
15073 DEFUN (no_bgp_distance_source,
15074 no_bgp_distance_source_cmd,
15075 "no distance (1-255) A.B.C.D/M",
15076 NO_STR
15077 "Define an administrative distance\n"
15078 "Administrative distance\n"
15079 "IP source prefix\n")
15080 {
15081 int idx_number = 2;
15082 int idx_ipv4_prefixlen = 3;
15083 bgp_distance_unset(vty, argv[idx_number]->arg,
15084 argv[idx_ipv4_prefixlen]->arg, NULL);
15085 return CMD_SUCCESS;
15086 }
15087
15088 DEFUN (bgp_distance_source_access_list,
15089 bgp_distance_source_access_list_cmd,
15090 "distance (1-255) A.B.C.D/M WORD",
15091 "Define an administrative distance\n"
15092 "Administrative distance\n"
15093 "IP source prefix\n"
15094 "Access list name\n")
15095 {
15096 int idx_number = 1;
15097 int idx_ipv4_prefixlen = 2;
15098 int idx_word = 3;
15099 bgp_distance_set(vty, argv[idx_number]->arg,
15100 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15101 return CMD_SUCCESS;
15102 }
15103
15104 DEFUN (no_bgp_distance_source_access_list,
15105 no_bgp_distance_source_access_list_cmd,
15106 "no distance (1-255) A.B.C.D/M WORD",
15107 NO_STR
15108 "Define an administrative distance\n"
15109 "Administrative distance\n"
15110 "IP source prefix\n"
15111 "Access list name\n")
15112 {
15113 int idx_number = 2;
15114 int idx_ipv4_prefixlen = 3;
15115 int idx_word = 4;
15116 bgp_distance_unset(vty, argv[idx_number]->arg,
15117 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15118 return CMD_SUCCESS;
15119 }
15120
15121 DEFUN (ipv6_bgp_distance_source,
15122 ipv6_bgp_distance_source_cmd,
15123 "distance (1-255) X:X::X:X/M",
15124 "Define an administrative distance\n"
15125 "Administrative distance\n"
15126 "IP source prefix\n")
15127 {
15128 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15129 return CMD_SUCCESS;
15130 }
15131
15132 DEFUN (no_ipv6_bgp_distance_source,
15133 no_ipv6_bgp_distance_source_cmd,
15134 "no distance (1-255) X:X::X:X/M",
15135 NO_STR
15136 "Define an administrative distance\n"
15137 "Administrative distance\n"
15138 "IP source prefix\n")
15139 {
15140 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15141 return CMD_SUCCESS;
15142 }
15143
15144 DEFUN (ipv6_bgp_distance_source_access_list,
15145 ipv6_bgp_distance_source_access_list_cmd,
15146 "distance (1-255) X:X::X:X/M WORD",
15147 "Define an administrative distance\n"
15148 "Administrative distance\n"
15149 "IP source prefix\n"
15150 "Access list name\n")
15151 {
15152 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15153 return CMD_SUCCESS;
15154 }
15155
15156 DEFUN (no_ipv6_bgp_distance_source_access_list,
15157 no_ipv6_bgp_distance_source_access_list_cmd,
15158 "no distance (1-255) X:X::X:X/M WORD",
15159 NO_STR
15160 "Define an administrative distance\n"
15161 "Administrative distance\n"
15162 "IP source prefix\n"
15163 "Access list name\n")
15164 {
15165 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15166 return CMD_SUCCESS;
15167 }
15168
15169 DEFUN (bgp_damp_set,
15170 bgp_damp_set_cmd,
15171 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15172 "BGP Specific commands\n"
15173 "Enable route-flap dampening\n"
15174 "Half-life time for the penalty\n"
15175 "Value to start reusing a route\n"
15176 "Value to start suppressing a route\n"
15177 "Maximum duration to suppress a stable route\n")
15178 {
15179 VTY_DECLVAR_CONTEXT(bgp, bgp);
15180 int idx_half_life = 2;
15181 int idx_reuse = 3;
15182 int idx_suppress = 4;
15183 int idx_max_suppress = 5;
15184 int half = DEFAULT_HALF_LIFE * 60;
15185 int reuse = DEFAULT_REUSE;
15186 int suppress = DEFAULT_SUPPRESS;
15187 int max = 4 * half;
15188
15189 if (argc == 6) {
15190 half = atoi(argv[idx_half_life]->arg) * 60;
15191 reuse = atoi(argv[idx_reuse]->arg);
15192 suppress = atoi(argv[idx_suppress]->arg);
15193 max = atoi(argv[idx_max_suppress]->arg) * 60;
15194 } else if (argc == 3) {
15195 half = atoi(argv[idx_half_life]->arg) * 60;
15196 max = 4 * half;
15197 }
15198
15199 /*
15200 * These can't be 0 but our SA doesn't understand the
15201 * way our cli is constructed
15202 */
15203 assert(reuse);
15204 assert(half);
15205 if (suppress < reuse) {
15206 vty_out(vty,
15207 "Suppress value cannot be less than reuse value \n");
15208 return 0;
15209 }
15210
15211 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15212 reuse, suppress, max);
15213 }
15214
15215 DEFUN (bgp_damp_unset,
15216 bgp_damp_unset_cmd,
15217 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15218 NO_STR
15219 "BGP Specific commands\n"
15220 "Enable route-flap dampening\n"
15221 "Half-life time for the penalty\n"
15222 "Value to start reusing a route\n"
15223 "Value to start suppressing a route\n"
15224 "Maximum duration to suppress a stable route\n")
15225 {
15226 VTY_DECLVAR_CONTEXT(bgp, bgp);
15227 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15228 }
15229
15230 /* Display specified route of BGP table. */
15231 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15232 const char *ip_str, afi_t afi, safi_t safi,
15233 struct prefix_rd *prd, int prefix_check)
15234 {
15235 int ret;
15236 struct prefix match;
15237 struct bgp_dest *dest;
15238 struct bgp_dest *rm;
15239 struct bgp_path_info *pi;
15240 struct bgp_path_info *pi_temp;
15241 struct bgp *bgp;
15242 struct bgp_table *table;
15243
15244 /* BGP structure lookup. */
15245 if (view_name) {
15246 bgp = bgp_lookup_by_name(view_name);
15247 if (bgp == NULL) {
15248 vty_out(vty, "%% Can't find BGP instance %s\n",
15249 view_name);
15250 return CMD_WARNING;
15251 }
15252 } else {
15253 bgp = bgp_get_default();
15254 if (bgp == NULL) {
15255 vty_out(vty, "%% No BGP process is configured\n");
15256 return CMD_WARNING;
15257 }
15258 }
15259
15260 /* Check IP address argument. */
15261 ret = str2prefix(ip_str, &match);
15262 if (!ret) {
15263 vty_out(vty, "%% address is malformed\n");
15264 return CMD_WARNING;
15265 }
15266
15267 match.family = afi2family(afi);
15268
15269 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15270 || (safi == SAFI_EVPN)) {
15271 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15272 dest = bgp_route_next(dest)) {
15273 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15274
15275 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15276 continue;
15277 table = bgp_dest_get_bgp_table_info(dest);
15278 if (!table)
15279 continue;
15280 rm = bgp_node_match(table, &match);
15281 if (rm == NULL)
15282 continue;
15283
15284 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15285
15286 if (!prefix_check
15287 || rm_p->prefixlen == match.prefixlen) {
15288 pi = bgp_dest_get_bgp_path_info(rm);
15289 while (pi) {
15290 if (pi->extra && pi->extra->damp_info) {
15291 pi_temp = pi->next;
15292 bgp_damp_info_free(
15293 pi->extra->damp_info,
15294 1, afi, safi);
15295 pi = pi_temp;
15296 } else
15297 pi = pi->next;
15298 }
15299 }
15300
15301 bgp_dest_unlock_node(rm);
15302 }
15303 } else {
15304 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15305 if (dest != NULL) {
15306 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15307
15308 if (!prefix_check
15309 || dest_p->prefixlen == match.prefixlen) {
15310 pi = bgp_dest_get_bgp_path_info(dest);
15311 while (pi) {
15312 if (pi->extra && pi->extra->damp_info) {
15313 pi_temp = pi->next;
15314 bgp_damp_info_free(
15315 pi->extra->damp_info,
15316 1, afi, safi);
15317 pi = pi_temp;
15318 } else
15319 pi = pi->next;
15320 }
15321 }
15322
15323 bgp_dest_unlock_node(dest);
15324 }
15325 }
15326
15327 return CMD_SUCCESS;
15328 }
15329
15330 DEFUN (clear_ip_bgp_dampening,
15331 clear_ip_bgp_dampening_cmd,
15332 "clear ip bgp dampening",
15333 CLEAR_STR
15334 IP_STR
15335 BGP_STR
15336 "Clear route flap dampening information\n")
15337 {
15338 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15339 return CMD_SUCCESS;
15340 }
15341
15342 DEFUN (clear_ip_bgp_dampening_prefix,
15343 clear_ip_bgp_dampening_prefix_cmd,
15344 "clear ip bgp dampening A.B.C.D/M",
15345 CLEAR_STR
15346 IP_STR
15347 BGP_STR
15348 "Clear route flap dampening information\n"
15349 "IPv4 prefix\n")
15350 {
15351 int idx_ipv4_prefixlen = 4;
15352 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15353 AFI_IP, SAFI_UNICAST, NULL, 1);
15354 }
15355
15356 DEFUN (clear_ip_bgp_dampening_address,
15357 clear_ip_bgp_dampening_address_cmd,
15358 "clear ip bgp dampening A.B.C.D",
15359 CLEAR_STR
15360 IP_STR
15361 BGP_STR
15362 "Clear route flap dampening information\n"
15363 "Network to clear damping information\n")
15364 {
15365 int idx_ipv4 = 4;
15366 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15367 SAFI_UNICAST, NULL, 0);
15368 }
15369
15370 DEFUN (clear_ip_bgp_dampening_address_mask,
15371 clear_ip_bgp_dampening_address_mask_cmd,
15372 "clear ip bgp dampening A.B.C.D A.B.C.D",
15373 CLEAR_STR
15374 IP_STR
15375 BGP_STR
15376 "Clear route flap dampening information\n"
15377 "Network to clear damping information\n"
15378 "Network mask\n")
15379 {
15380 int idx_ipv4 = 4;
15381 int idx_ipv4_2 = 5;
15382 int ret;
15383 char prefix_str[BUFSIZ];
15384
15385 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15386 prefix_str, sizeof(prefix_str));
15387 if (!ret) {
15388 vty_out(vty, "%% Inconsistent address and mask\n");
15389 return CMD_WARNING;
15390 }
15391
15392 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15393 NULL, 0);
15394 }
15395
15396 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15397 {
15398 struct vty *vty = arg;
15399 struct peer *peer = bucket->data;
15400
15401 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15402 }
15403
15404 DEFUN (show_bgp_listeners,
15405 show_bgp_listeners_cmd,
15406 "show bgp listeners",
15407 SHOW_STR
15408 BGP_STR
15409 "Display Listen Sockets and who created them\n")
15410 {
15411 bgp_dump_listener_info(vty);
15412
15413 return CMD_SUCCESS;
15414 }
15415
15416 DEFUN (show_bgp_peerhash,
15417 show_bgp_peerhash_cmd,
15418 "show bgp peerhash",
15419 SHOW_STR
15420 BGP_STR
15421 "Display information about the BGP peerhash\n")
15422 {
15423 struct list *instances = bm->bgp;
15424 struct listnode *node;
15425 struct bgp *bgp;
15426
15427 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15428 vty_out(vty, "BGP: %s\n", bgp->name);
15429 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15430 vty);
15431 }
15432
15433 return CMD_SUCCESS;
15434 }
15435
15436 /* also used for encap safi */
15437 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15438 afi_t afi, safi_t safi)
15439 {
15440 struct bgp_dest *pdest;
15441 struct bgp_dest *dest;
15442 struct bgp_table *table;
15443 const struct prefix *p;
15444 const struct prefix_rd *prd;
15445 struct bgp_static *bgp_static;
15446 mpls_label_t label;
15447
15448 /* Network configuration. */
15449 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15450 pdest = bgp_route_next(pdest)) {
15451 table = bgp_dest_get_bgp_table_info(pdest);
15452 if (!table)
15453 continue;
15454
15455 for (dest = bgp_table_top(table); dest;
15456 dest = bgp_route_next(dest)) {
15457 bgp_static = bgp_dest_get_bgp_static_info(dest);
15458 if (bgp_static == NULL)
15459 continue;
15460
15461 p = bgp_dest_get_prefix(dest);
15462 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
15463 pdest);
15464
15465 /* "network" configuration display. */
15466 label = decode_label(&bgp_static->label);
15467
15468 vty_out(vty, " network %pFX rd %pRD", p, prd);
15469 if (safi == SAFI_MPLS_VPN)
15470 vty_out(vty, " label %u", label);
15471
15472 if (bgp_static->rmap.name)
15473 vty_out(vty, " route-map %s",
15474 bgp_static->rmap.name);
15475
15476 if (bgp_static->backdoor)
15477 vty_out(vty, " backdoor");
15478
15479 vty_out(vty, "\n");
15480 }
15481 }
15482 }
15483
15484 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15485 afi_t afi, safi_t safi)
15486 {
15487 struct bgp_dest *pdest;
15488 struct bgp_dest *dest;
15489 struct bgp_table *table;
15490 const struct prefix *p;
15491 const struct prefix_rd *prd;
15492 struct bgp_static *bgp_static;
15493 char buf[PREFIX_STRLEN * 2];
15494 char buf2[SU_ADDRSTRLEN];
15495 char esi_buf[ESI_STR_LEN];
15496
15497 /* Network configuration. */
15498 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15499 pdest = bgp_route_next(pdest)) {
15500 table = bgp_dest_get_bgp_table_info(pdest);
15501 if (!table)
15502 continue;
15503
15504 for (dest = bgp_table_top(table); dest;
15505 dest = bgp_route_next(dest)) {
15506 bgp_static = bgp_dest_get_bgp_static_info(dest);
15507 if (bgp_static == NULL)
15508 continue;
15509
15510 char *macrouter = NULL;
15511
15512 if (bgp_static->router_mac)
15513 macrouter = prefix_mac2str(
15514 bgp_static->router_mac, NULL, 0);
15515 if (bgp_static->eth_s_id)
15516 esi_to_str(bgp_static->eth_s_id,
15517 esi_buf, sizeof(esi_buf));
15518 p = bgp_dest_get_prefix(dest);
15519 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15520
15521 /* "network" configuration display. */
15522 if (p->u.prefix_evpn.route_type == 5) {
15523 char local_buf[PREFIX_STRLEN];
15524 uint8_t family = is_evpn_prefix_ipaddr_v4((
15525 struct prefix_evpn *)p)
15526 ? AF_INET
15527 : AF_INET6;
15528 inet_ntop(family,
15529 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15530 local_buf, PREFIX_STRLEN);
15531 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15532 p->u.prefix_evpn.prefix_addr
15533 .ip_prefix_length);
15534 } else {
15535 prefix2str(p, buf, sizeof(buf));
15536 }
15537
15538 if (bgp_static->gatewayIp.family == AF_INET
15539 || bgp_static->gatewayIp.family == AF_INET6)
15540 inet_ntop(bgp_static->gatewayIp.family,
15541 &bgp_static->gatewayIp.u.prefix, buf2,
15542 sizeof(buf2));
15543 vty_out(vty,
15544 " network %s rd %pRD ethtag %u label %u esi %s gwip %s routermac %s\n",
15545 buf, prd, p->u.prefix_evpn.prefix_addr.eth_tag,
15546 decode_label(&bgp_static->label), esi_buf, buf2,
15547 macrouter);
15548
15549 XFREE(MTYPE_TMP, macrouter);
15550 }
15551 }
15552 }
15553
15554 /* Configuration of static route announcement and aggregate
15555 information. */
15556 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15557 safi_t safi)
15558 {
15559 struct bgp_dest *dest;
15560 const struct prefix *p;
15561 struct bgp_static *bgp_static;
15562 struct bgp_aggregate *bgp_aggregate;
15563
15564 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15565 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15566 return;
15567 }
15568
15569 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15570 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15571 return;
15572 }
15573
15574 /* Network configuration. */
15575 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15576 dest = bgp_route_next(dest)) {
15577 bgp_static = bgp_dest_get_bgp_static_info(dest);
15578 if (bgp_static == NULL)
15579 continue;
15580
15581 p = bgp_dest_get_prefix(dest);
15582
15583 vty_out(vty, " network %pFX", p);
15584
15585 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15586 vty_out(vty, " label-index %u",
15587 bgp_static->label_index);
15588
15589 if (bgp_static->rmap.name)
15590 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15591
15592 if (bgp_static->backdoor)
15593 vty_out(vty, " backdoor");
15594
15595 vty_out(vty, "\n");
15596 }
15597
15598 /* Aggregate-address configuration. */
15599 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15600 dest = bgp_route_next(dest)) {
15601 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15602 if (bgp_aggregate == NULL)
15603 continue;
15604
15605 p = bgp_dest_get_prefix(dest);
15606
15607 vty_out(vty, " aggregate-address %pFX", p);
15608
15609 if (bgp_aggregate->as_set)
15610 vty_out(vty, " as-set");
15611
15612 if (bgp_aggregate->summary_only)
15613 vty_out(vty, " summary-only");
15614
15615 if (bgp_aggregate->rmap.name)
15616 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15617
15618 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15619 vty_out(vty, " origin %s",
15620 bgp_origin2str(bgp_aggregate->origin));
15621
15622 if (bgp_aggregate->match_med)
15623 vty_out(vty, " matching-MED-only");
15624
15625 if (bgp_aggregate->suppress_map_name)
15626 vty_out(vty, " suppress-map %s",
15627 bgp_aggregate->suppress_map_name);
15628
15629 vty_out(vty, "\n");
15630 }
15631 }
15632
15633 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15634 safi_t safi)
15635 {
15636 struct bgp_dest *dest;
15637 struct bgp_distance *bdistance;
15638
15639 /* Distance configuration. */
15640 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15641 && bgp->distance_local[afi][safi]
15642 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15643 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15644 || bgp->distance_local[afi][safi]
15645 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15646 vty_out(vty, " distance bgp %d %d %d\n",
15647 bgp->distance_ebgp[afi][safi],
15648 bgp->distance_ibgp[afi][safi],
15649 bgp->distance_local[afi][safi]);
15650 }
15651
15652 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15653 dest = bgp_route_next(dest)) {
15654 bdistance = bgp_dest_get_bgp_distance_info(dest);
15655 if (bdistance != NULL)
15656 vty_out(vty, " distance %d %pBD %s\n",
15657 bdistance->distance, dest,
15658 bdistance->access_list ? bdistance->access_list
15659 : "");
15660 }
15661 }
15662
15663 /* Allocate routing table structure and install commands. */
15664 void bgp_route_init(void)
15665 {
15666 afi_t afi;
15667 safi_t safi;
15668
15669 /* Init BGP distance table. */
15670 FOREACH_AFI_SAFI (afi, safi)
15671 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15672
15673 /* IPv4 BGP commands. */
15674 install_element(BGP_NODE, &bgp_table_map_cmd);
15675 install_element(BGP_NODE, &bgp_network_cmd);
15676 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15677
15678 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15679
15680 /* IPv4 unicast configuration. */
15681 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15682 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15683 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15684
15685 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15686
15687 /* IPv4 multicast configuration. */
15688 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15689 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15690 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15691 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15692
15693 /* IPv4 labeled-unicast configuration. */
15694 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15695 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15696
15697 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15698 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15699 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15700 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15701 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15702 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15703 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15704 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15705
15706 install_element(VIEW_NODE,
15707 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15708 install_element(VIEW_NODE,
15709 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15710 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15711 install_element(VIEW_NODE,
15712 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15713 #ifdef KEEP_OLD_VPN_COMMANDS
15714 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15715 #endif /* KEEP_OLD_VPN_COMMANDS */
15716 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15717 install_element(VIEW_NODE,
15718 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15719
15720 /* BGP dampening clear commands */
15721 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15722 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15723
15724 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15725 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15726
15727 /* prefix count */
15728 install_element(ENABLE_NODE,
15729 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15730 #ifdef KEEP_OLD_VPN_COMMANDS
15731 install_element(ENABLE_NODE,
15732 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15733 #endif /* KEEP_OLD_VPN_COMMANDS */
15734
15735 /* New config IPv6 BGP commands. */
15736 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15737 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15738 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15739
15740 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15741
15742 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15743
15744 /* IPv6 labeled unicast address family. */
15745 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15746 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15747
15748 install_element(BGP_NODE, &bgp_distance_cmd);
15749 install_element(BGP_NODE, &no_bgp_distance_cmd);
15750 install_element(BGP_NODE, &bgp_distance_source_cmd);
15751 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15752 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15753 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15754 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15755 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15756 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15757 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15758 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15759 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15760 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15761 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15762 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15763 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15764 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15765 install_element(BGP_IPV4M_NODE,
15766 &no_bgp_distance_source_access_list_cmd);
15767 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15768 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15769 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15770 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15771 install_element(BGP_IPV6_NODE,
15772 &ipv6_bgp_distance_source_access_list_cmd);
15773 install_element(BGP_IPV6_NODE,
15774 &no_ipv6_bgp_distance_source_access_list_cmd);
15775 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15776 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15777 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15778 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15779 install_element(BGP_IPV6M_NODE,
15780 &ipv6_bgp_distance_source_access_list_cmd);
15781 install_element(BGP_IPV6M_NODE,
15782 &no_ipv6_bgp_distance_source_access_list_cmd);
15783
15784 /* BGP dampening */
15785 install_element(BGP_NODE, &bgp_damp_set_cmd);
15786 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15787 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15788 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15789 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15790 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15791 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15792 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15793 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15794 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15795 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15796 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15797 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15798 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15799
15800 /* Large Communities */
15801 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15802 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15803
15804 /* show bgp ipv4 flowspec detailed */
15805 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15806
15807 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15808 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15809 }
15810
15811 void bgp_route_finish(void)
15812 {
15813 afi_t afi;
15814 safi_t safi;
15815
15816 FOREACH_AFI_SAFI (afi, safi) {
15817 bgp_table_unlock(bgp_distance_table[afi][safi]);
15818 bgp_distance_table[afi][safi] = NULL;
15819 }
15820 }