]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #13303 from pguibert6WIND/srv6_seg6local_defaultvrf
[mirror_frr.git] / bgpd / bgp_route.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP routing information
3 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
4 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 */
6
7 #include <zebra.h>
8 #include <math.h>
9
10 #include "printfrr.h"
11 #include "frrstr.h"
12 #include "prefix.h"
13 #include "linklist.h"
14 #include "memory.h"
15 #include "command.h"
16 #include "stream.h"
17 #include "filter.h"
18 #include "log.h"
19 #include "routemap.h"
20 #include "buffer.h"
21 #include "sockunion.h"
22 #include "plist.h"
23 #include "frrevent.h"
24 #include "workqueue.h"
25 #include "queue.h"
26 #include "memory.h"
27 #include "srv6.h"
28 #include "lib/json.h"
29 #include "lib_errors.h"
30 #include "zclient.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_regex.h"
39 #include "bgpd/bgp_community.h"
40 #include "bgpd/bgp_community_alias.h"
41 #include "bgpd/bgp_ecommunity.h"
42 #include "bgpd/bgp_lcommunity.h"
43 #include "bgpd/bgp_clist.h"
44 #include "bgpd/bgp_packet.h"
45 #include "bgpd/bgp_filter.h"
46 #include "bgpd/bgp_fsm.h"
47 #include "bgpd/bgp_mplsvpn.h"
48 #include "bgpd/bgp_nexthop.h"
49 #include "bgpd/bgp_damp.h"
50 #include "bgpd/bgp_advertise.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_vty.h"
53 #include "bgpd/bgp_mpath.h"
54 #include "bgpd/bgp_nht.h"
55 #include "bgpd/bgp_updgrp.h"
56 #include "bgpd/bgp_label.h"
57 #include "bgpd/bgp_addpath.h"
58 #include "bgpd/bgp_mac.h"
59 #include "bgpd/bgp_network.h"
60 #include "bgpd/bgp_trace.h"
61 #include "bgpd/bgp_rpki.h"
62
63 #ifdef ENABLE_BGP_VNC
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #include "bgpd/rfapi/vnc_import_bgp.h"
66 #include "bgpd/rfapi/vnc_export_bgp.h"
67 #endif
68 #include "bgpd/bgp_encap_types.h"
69 #include "bgpd/bgp_encap_tlv.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_evpn_mh.h"
72 #include "bgpd/bgp_evpn_vty.h"
73 #include "bgpd/bgp_flowspec.h"
74 #include "bgpd/bgp_flowspec_util.h"
75 #include "bgpd/bgp_pbr.h"
76
77 #include "bgpd/bgp_route_clippy.c"
78
79 DEFINE_HOOK(bgp_snmp_update_stats,
80 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
81 (rn, pi, added));
82
83 DEFINE_HOOK(bgp_rpki_prefix_status,
84 (struct peer *peer, struct attr *attr,
85 const struct prefix *prefix),
86 (peer, attr, prefix));
87
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str[];
90 extern const char *bgp_origin_long_str[];
91
92 /* PMSI strings. */
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str[] = {
96 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
104 {0}
105 };
106
107 #define VRFID_NONE_STR "-"
108 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
109
110 DEFINE_HOOK(bgp_process,
111 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
112 struct peer *peer, bool withdraw),
113 (bgp, afi, safi, bn, peer, withdraw));
114
115 /** Test if path is suppressed. */
116 static bool bgp_path_suppressed(struct bgp_path_info *pi)
117 {
118 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
119 return false;
120
121 return listcount(pi->extra->aggr_suppressors) > 0;
122 }
123
124 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
125 safi_t safi, const struct prefix *p,
126 struct prefix_rd *prd)
127 {
128 struct bgp_dest *dest;
129 struct bgp_dest *pdest = NULL;
130
131 assert(table);
132
133 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
134 || (safi == SAFI_EVPN)) {
135 pdest = bgp_node_get(table, (struct prefix *)prd);
136
137 if (!bgp_dest_has_bgp_path_info_data(pdest))
138 bgp_dest_set_bgp_table_info(
139 pdest, bgp_table_init(table->bgp, afi, safi));
140 else
141 bgp_dest_unlock_node(pdest);
142 table = bgp_dest_get_bgp_table_info(pdest);
143 }
144
145 dest = bgp_node_get(table, p);
146
147 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
148 || (safi == SAFI_EVPN))
149 dest->pdest = pdest;
150
151 return dest;
152 }
153
154 struct bgp_dest *bgp_safi_node_lookup(struct bgp_table *table, safi_t safi,
155 const struct prefix *p,
156 struct prefix_rd *prd)
157 {
158 struct bgp_dest *dest;
159 struct bgp_dest *pdest = NULL;
160
161 if (!table)
162 return NULL;
163
164 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
165 || (safi == SAFI_EVPN)) {
166 pdest = bgp_node_lookup(table, (struct prefix *)prd);
167 if (!pdest)
168 return NULL;
169
170 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
171 bgp_dest_unlock_node(pdest);
172 return NULL;
173 }
174
175 table = bgp_dest_get_bgp_table_info(pdest);
176 }
177
178 dest = bgp_node_lookup(table, p);
179
180 return dest;
181 }
182
183 /* Allocate bgp_path_info_extra */
184 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
185 {
186 struct bgp_path_info_extra *new;
187 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
188 sizeof(struct bgp_path_info_extra));
189 new->label[0] = MPLS_INVALID_LABEL;
190 new->num_labels = 0;
191 new->bgp_fs_pbr = NULL;
192 new->bgp_fs_iprule = NULL;
193 return new;
194 }
195
196 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
197 {
198 struct bgp_path_info_extra *e;
199
200 if (!extra || !*extra)
201 return;
202
203 e = *extra;
204 if (e->damp_info)
205 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
206 e->damp_info->safi);
207
208 e->damp_info = NULL;
209 if (e->parent) {
210 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
211
212 if (bpi->net) {
213 /* FIXME: since multiple e may have the same e->parent
214 * and e->parent->net is holding a refcount for each
215 * of them, we need to do some fudging here.
216 *
217 * WARNING: if bpi->net->lock drops to 0, bpi may be
218 * freed as well (because bpi->net was holding the
219 * last reference to bpi) => write after free!
220 */
221 unsigned refcount;
222
223 bpi = bgp_path_info_lock(bpi);
224 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
225 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
226 if (!refcount)
227 bpi->net = NULL;
228 bgp_path_info_unlock(bpi);
229 }
230 bgp_path_info_unlock(e->parent);
231 e->parent = NULL;
232 }
233
234 if (e->bgp_orig)
235 bgp_unlock(e->bgp_orig);
236
237 if (e->peer_orig)
238 peer_unlock(e->peer_orig);
239
240 if (e->aggr_suppressors)
241 list_delete(&e->aggr_suppressors);
242
243 if (e->mh_info)
244 bgp_evpn_path_mh_info_free(e->mh_info);
245
246 if ((*extra)->bgp_fs_iprule)
247 list_delete(&((*extra)->bgp_fs_iprule));
248 if ((*extra)->bgp_fs_pbr)
249 list_delete(&((*extra)->bgp_fs_pbr));
250 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
251 }
252
253 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
254 * allocated if required.
255 */
256 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
257 {
258 if (!pi->extra)
259 pi->extra = bgp_path_info_extra_new();
260 return pi->extra;
261 }
262
263 /* Free bgp route information. */
264 void bgp_path_info_free_with_caller(const char *name,
265 struct bgp_path_info *path)
266 {
267 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
268 bgp_attr_unintern(&path->attr);
269
270 bgp_unlink_nexthop(path);
271 bgp_path_info_extra_free(&path->extra);
272 bgp_path_info_mpath_free(&path->mpath);
273 if (path->net)
274 bgp_addpath_free_info_data(&path->tx_addpath,
275 &path->net->tx_addpath);
276
277 peer_unlock(path->peer); /* bgp_path_info peer reference */
278
279 XFREE(MTYPE_BGP_ROUTE, path);
280 }
281
282 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
283 {
284 path->lock++;
285 return path;
286 }
287
288 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
289 {
290 assert(path && path->lock > 0);
291 path->lock--;
292
293 if (path->lock == 0) {
294 bgp_path_info_free(path);
295 return NULL;
296 }
297
298 return path;
299 }
300
301 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
302 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
303 {
304 struct peer *peer;
305 struct bgp_path_info *old_pi, *nextpi;
306 bool set_flag = false;
307 struct bgp *bgp = NULL;
308 struct bgp_table *table = NULL;
309 afi_t afi = 0;
310 safi_t safi = 0;
311
312 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
313 * then the route selection is deferred
314 */
315 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
316 return 0;
317
318 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
319 if (BGP_DEBUG(update, UPDATE_OUT)) {
320 table = bgp_dest_table(dest);
321 if (table)
322 bgp = table->bgp;
323
324 zlog_debug(
325 "Route %pBD(%s) is in workqueue and being processed, not deferred.",
326 dest, bgp ? bgp->name_pretty : "(Unknown)");
327 }
328
329 return 0;
330 }
331
332 table = bgp_dest_table(dest);
333 if (table) {
334 bgp = table->bgp;
335 afi = table->afi;
336 safi = table->safi;
337 }
338
339 for (old_pi = bgp_dest_get_bgp_path_info(dest);
340 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
341 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
342 continue;
343
344 /* Route selection is deferred if there is a stale path which
345 * which indicates peer is in restart mode
346 */
347 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
348 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
349 set_flag = true;
350 } else {
351 /* If the peer is graceful restart capable and peer is
352 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
353 */
354 peer = old_pi->peer;
355 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
356 && BGP_PEER_RESTARTING_MODE(peer)
357 && (old_pi
358 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
359 set_flag = true;
360 }
361 }
362 if (set_flag)
363 break;
364 }
365
366 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
367 * is active
368 */
369 if (set_flag && table) {
370 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
371 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
372 bgp->gr_info[afi][safi].gr_deferred++;
373 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
374 if (BGP_DEBUG(update, UPDATE_OUT))
375 zlog_debug("DEFER route %pBD(%s), dest %p",
376 dest, bgp->name_pretty, dest);
377 return 0;
378 }
379 }
380 return -1;
381 }
382
383 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
384 struct bgp_path_info *pi)
385 {
386 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
387 struct bgp_path_info *top;
388
389 top = bgp_dest_get_bgp_path_info(dest);
390
391 pi->next = top;
392 pi->prev = NULL;
393 if (top)
394 top->prev = pi;
395 bgp_dest_set_bgp_path_info(dest, pi);
396
397 bgp_path_info_lock(pi);
398 bgp_dest_lock_node(dest);
399 peer_lock(pi->peer); /* bgp_path_info peer reference */
400 bgp_dest_set_defer_flag(dest, false);
401 hook_call(bgp_snmp_update_stats, dest, pi, true);
402 }
403
404 /* Do the actual removal of info from RIB, for use by bgp_process
405 completion callback *only* */
406 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
407 {
408 if (pi->next)
409 pi->next->prev = pi->prev;
410 if (pi->prev)
411 pi->prev->next = pi->next;
412 else
413 bgp_dest_set_bgp_path_info(dest, pi->next);
414
415 bgp_path_info_mpath_dequeue(pi);
416 bgp_path_info_unlock(pi);
417 hook_call(bgp_snmp_update_stats, dest, pi, false);
418 bgp_dest_unlock_node(dest);
419 }
420
421 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
422 {
423 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
424 /* set of previous already took care of pcount */
425 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
426 }
427
428 /* undo the effects of a previous call to bgp_path_info_delete; typically
429 called when a route is deleted and then quickly re-added before the
430 deletion has been processed */
431 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
432 {
433 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
434 /* unset of previous already took care of pcount */
435 SET_FLAG(pi->flags, BGP_PATH_VALID);
436 }
437
438 /* Adjust pcount as required */
439 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
440 {
441 struct bgp_table *table;
442
443 assert(dest && bgp_dest_table(dest));
444 assert(pi && pi->peer && pi->peer->bgp);
445
446 table = bgp_dest_table(dest);
447
448 if (pi->peer == pi->peer->bgp->peer_self)
449 return;
450
451 if (!BGP_PATH_COUNTABLE(pi)
452 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
453
454 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
455
456 /* slight hack, but more robust against errors. */
457 if (pi->peer->pcount[table->afi][table->safi])
458 pi->peer->pcount[table->afi][table->safi]--;
459 else
460 flog_err(EC_LIB_DEVELOPMENT,
461 "Asked to decrement 0 prefix count for peer");
462 } else if (BGP_PATH_COUNTABLE(pi)
463 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
464 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
465 pi->peer->pcount[table->afi][table->safi]++;
466 }
467 }
468
469 static int bgp_label_index_differs(struct bgp_path_info *pi1,
470 struct bgp_path_info *pi2)
471 {
472 return (!(pi1->attr->label_index == pi2->attr->label_index));
473 }
474
475 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
476 * This is here primarily to keep prefix-count in check.
477 */
478 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
479 uint32_t flag)
480 {
481 SET_FLAG(pi->flags, flag);
482
483 /* early bath if we know it's not a flag that changes countability state
484 */
485 if (!CHECK_FLAG(flag,
486 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
487 return;
488
489 bgp_pcount_adjust(dest, pi);
490 }
491
492 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
493 uint32_t flag)
494 {
495 UNSET_FLAG(pi->flags, flag);
496
497 /* early bath if we know it's not a flag that changes countability state
498 */
499 if (!CHECK_FLAG(flag,
500 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
501 return;
502
503 bgp_pcount_adjust(dest, pi);
504 }
505
506 /* Get MED value. If MED value is missing and "bgp bestpath
507 missing-as-worst" is specified, treat it as the worst value. */
508 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
509 {
510 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
511 return attr->med;
512 else {
513 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
514 return BGP_MED_MAX;
515 else
516 return 0;
517 }
518 }
519
520 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
521 size_t buf_len)
522 {
523 struct peer *peer;
524
525 if (pi->sub_type == BGP_ROUTE_IMPORTED &&
526 bgp_get_imported_bpi_ultimate(pi))
527 peer = bgp_get_imported_bpi_ultimate(pi)->peer;
528 else
529 peer = pi->peer;
530
531 if (pi->addpath_rx_id)
532 snprintf(buf, buf_len, "path %s (addpath rxid %d)", peer->host,
533 pi->addpath_rx_id);
534 else
535 snprintf(buf, buf_len, "path %s", peer->host);
536 }
537
538
539 /*
540 * Get the ultimate path info.
541 */
542 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
543 {
544 struct bgp_path_info *bpi_ultimate;
545
546 if (info->sub_type != BGP_ROUTE_IMPORTED)
547 return info;
548
549 for (bpi_ultimate = info;
550 bpi_ultimate->extra && bpi_ultimate->extra->parent;
551 bpi_ultimate = bpi_ultimate->extra->parent)
552 ;
553
554 return bpi_ultimate;
555 }
556
557 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
558 */
559 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
560 struct bgp_path_info *exist, int *paths_eq,
561 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
562 char *pfx_buf, afi_t afi, safi_t safi,
563 enum bgp_path_selection_reason *reason)
564 {
565 const struct prefix *new_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 struct peer *peer_new, *peer_exist;
598
599 *paths_eq = 0;
600
601 /* 0. Null check. */
602 if (new == NULL) {
603 *reason = bgp_path_selection_none;
604 if (debug)
605 zlog_debug("%s: new is NULL", pfx_buf);
606 return 0;
607 }
608
609 if (debug) {
610 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
611 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
612 sizeof(new_buf));
613 }
614
615 if (exist == NULL) {
616 *reason = bgp_path_selection_first;
617 if (debug)
618 zlog_debug("%s(%s): %s is the initial bestpath",
619 pfx_buf, bgp->name_pretty, new_buf);
620 return 1;
621 }
622
623 if (debug) {
624 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
625 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
626 sizeof(exist_buf));
627 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
628 pfx_buf, bgp->name_pretty, new_buf, new->flags,
629 exist_buf, exist->flags);
630 }
631
632 newattr = new->attr;
633 existattr = exist->attr;
634
635 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
636 * Capability" to a neighbor MUST perform the following upon receiving
637 * a route from that neighbor with the "LLGR_STALE" community, or upon
638 * attaching the "LLGR_STALE" community itself per Section 4.2:
639 *
640 * Treat the route as the least-preferred in route selection (see
641 * below). See the Risks of Depreferencing Routes section (Section 5.2)
642 * for a discussion of potential risks inherent in doing this.
643 */
644 if (bgp_attr_get_community(newattr) &&
645 community_include(bgp_attr_get_community(newattr),
646 COMMUNITY_LLGR_STALE)) {
647 if (debug)
648 zlog_debug(
649 "%s: %s wins over %s due to LLGR_STALE community",
650 pfx_buf, new_buf, exist_buf);
651 return 0;
652 }
653
654 if (bgp_attr_get_community(existattr) &&
655 community_include(bgp_attr_get_community(existattr),
656 COMMUNITY_LLGR_STALE)) {
657 if (debug)
658 zlog_debug(
659 "%s: %s loses to %s due to LLGR_STALE community",
660 pfx_buf, new_buf, exist_buf);
661 return 1;
662 }
663
664 new_p = bgp_dest_get_prefix(new->net);
665
666 /* For EVPN routes, we cannot just go by local vs remote, we have to
667 * look at the MAC mobility sequence number, if present.
668 */
669 if ((safi == SAFI_EVPN)
670 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
671 /* This is an error condition described in RFC 7432 Section
672 * 15.2. The RFC
673 * states that in this scenario "the PE MUST alert the operator"
674 * but it
675 * does not state what other action to take. In order to provide
676 * some
677 * consistency in this scenario we are going to prefer the path
678 * with the
679 * sticky flag.
680 */
681 if (newattr->sticky != existattr->sticky) {
682 if (!debug) {
683 prefix2str(new_p, pfx_buf,
684 sizeof(*pfx_buf)
685 * PREFIX2STR_BUFFER);
686 bgp_path_info_path_with_addpath_rx_str(
687 new, new_buf, sizeof(new_buf));
688 bgp_path_info_path_with_addpath_rx_str(
689 exist, exist_buf, sizeof(exist_buf));
690 }
691
692 if (newattr->sticky && !existattr->sticky) {
693 *reason = bgp_path_selection_evpn_sticky_mac;
694 if (debug)
695 zlog_debug(
696 "%s: %s wins over %s due to sticky MAC flag",
697 pfx_buf, new_buf, exist_buf);
698 return 1;
699 }
700
701 if (!newattr->sticky && existattr->sticky) {
702 *reason = bgp_path_selection_evpn_sticky_mac;
703 if (debug)
704 zlog_debug(
705 "%s: %s loses to %s due to sticky MAC flag",
706 pfx_buf, new_buf, exist_buf);
707 return 0;
708 }
709 }
710
711 new_esi = bgp_evpn_attr_get_esi(newattr);
712 exist_esi = bgp_evpn_attr_get_esi(existattr);
713 if (bgp_evpn_is_esi_valid(new_esi) &&
714 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
715 same_esi = true;
716 } else {
717 same_esi = false;
718 }
719
720 /* If both paths have the same non-zero ES and
721 * one path is local it wins.
722 * PS: Note the local path wins even if the remote
723 * has the higher MM seq. The local path's
724 * MM seq will be fixed up to match the highest
725 * rem seq, subsequently.
726 */
727 if (same_esi) {
728 char esi_buf[ESI_STR_LEN];
729
730 if (bgp_evpn_is_path_local(bgp, new)) {
731 *reason = bgp_path_selection_evpn_local_path;
732 if (debug)
733 zlog_debug(
734 "%s: %s wins over %s as ES %s is same and local",
735 pfx_buf, new_buf, exist_buf,
736 esi_to_str(new_esi, esi_buf,
737 sizeof(esi_buf)));
738 return 1;
739 }
740 if (bgp_evpn_is_path_local(bgp, exist)) {
741 *reason = bgp_path_selection_evpn_local_path;
742 if (debug)
743 zlog_debug(
744 "%s: %s loses to %s as ES %s is same and local",
745 pfx_buf, new_buf, exist_buf,
746 esi_to_str(new_esi, esi_buf,
747 sizeof(esi_buf)));
748 return 0;
749 }
750 }
751
752 new_mm_seq = mac_mobility_seqnum(newattr);
753 exist_mm_seq = mac_mobility_seqnum(existattr);
754
755 if (new_mm_seq > exist_mm_seq) {
756 *reason = bgp_path_selection_evpn_seq;
757 if (debug)
758 zlog_debug(
759 "%s: %s wins over %s due to MM seq %u > %u",
760 pfx_buf, new_buf, exist_buf, new_mm_seq,
761 exist_mm_seq);
762 return 1;
763 }
764
765 if (new_mm_seq < exist_mm_seq) {
766 *reason = bgp_path_selection_evpn_seq;
767 if (debug)
768 zlog_debug(
769 "%s: %s loses to %s due to MM seq %u < %u",
770 pfx_buf, new_buf, exist_buf, new_mm_seq,
771 exist_mm_seq);
772 return 0;
773 }
774
775 /* if the sequence numbers and ESI are the same and one path
776 * is non-proxy it wins (over proxy)
777 */
778 new_proxy = bgp_evpn_attr_is_proxy(newattr);
779 old_proxy = bgp_evpn_attr_is_proxy(existattr);
780 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
781 old_proxy != new_proxy) {
782 if (!new_proxy) {
783 *reason = bgp_path_selection_evpn_non_proxy;
784 if (debug)
785 zlog_debug(
786 "%s: %s wins over %s, same seq/es and non-proxy",
787 pfx_buf, new_buf, exist_buf);
788 return 1;
789 }
790
791 *reason = bgp_path_selection_evpn_non_proxy;
792 if (debug)
793 zlog_debug(
794 "%s: %s loses to %s, same seq/es and non-proxy",
795 pfx_buf, new_buf, exist_buf);
796 return 0;
797 }
798
799 /*
800 * if sequence numbers are the same path with the lowest IP
801 * wins
802 */
803 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
804 if (nh_cmp < 0) {
805 *reason = bgp_path_selection_evpn_lower_ip;
806 if (debug)
807 zlog_debug(
808 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
809 pfx_buf, new_buf, exist_buf, new_mm_seq,
810 &new->attr->nexthop);
811 return 1;
812 }
813 if (nh_cmp > 0) {
814 *reason = bgp_path_selection_evpn_lower_ip;
815 if (debug)
816 zlog_debug(
817 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
818 pfx_buf, new_buf, exist_buf, new_mm_seq,
819 &new->attr->nexthop);
820 return 0;
821 }
822 }
823
824 /* 1. Weight check. */
825 new_weight = newattr->weight;
826 exist_weight = existattr->weight;
827
828 if (new_weight > exist_weight) {
829 *reason = bgp_path_selection_weight;
830 if (debug)
831 zlog_debug("%s: %s wins over %s due to weight %d > %d",
832 pfx_buf, new_buf, exist_buf, new_weight,
833 exist_weight);
834 return 1;
835 }
836
837 if (new_weight < exist_weight) {
838 *reason = bgp_path_selection_weight;
839 if (debug)
840 zlog_debug("%s: %s loses to %s due to weight %d < %d",
841 pfx_buf, new_buf, exist_buf, new_weight,
842 exist_weight);
843 return 0;
844 }
845
846 /* 2. Local preference check. */
847 new_pref = exist_pref = bgp->default_local_pref;
848
849 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
850 new_pref = newattr->local_pref;
851 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
852 exist_pref = existattr->local_pref;
853
854 if (new_pref > exist_pref) {
855 *reason = bgp_path_selection_local_pref;
856 if (debug)
857 zlog_debug(
858 "%s: %s wins over %s due to localpref %d > %d",
859 pfx_buf, new_buf, exist_buf, new_pref,
860 exist_pref);
861 return 1;
862 }
863
864 if (new_pref < exist_pref) {
865 *reason = bgp_path_selection_local_pref;
866 if (debug)
867 zlog_debug(
868 "%s: %s loses to %s due to localpref %d < %d",
869 pfx_buf, new_buf, exist_buf, new_pref,
870 exist_pref);
871 return 0;
872 }
873
874 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
875 * extensions defined in this document, the following step is inserted
876 * after the LOCAL_PREF comparison step in the BGP decision process:
877 * When comparing a pair of routes for a BGP destination, the
878 * route with the ACCEPT_OWN community attached is preferred over
879 * the route that does not have the community.
880 * This extra step MUST only be invoked during the best path selection
881 * process of VPN-IP routes.
882 */
883 if (safi == SAFI_MPLS_VPN &&
884 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
885 CHECK_FLAG(exist->peer->af_flags[afi][safi],
886 PEER_FLAG_ACCEPT_OWN))) {
887 bool new_accept_own = false;
888 bool exist_accept_own = false;
889 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
890
891 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
892 new_accept_own = community_include(
893 bgp_attr_get_community(newattr), accept_own);
894 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
895 exist_accept_own = community_include(
896 bgp_attr_get_community(existattr), accept_own);
897
898 if (new_accept_own && !exist_accept_own) {
899 *reason = bgp_path_selection_accept_own;
900 if (debug)
901 zlog_debug(
902 "%s: %s wins over %s due to accept-own",
903 pfx_buf, new_buf, exist_buf);
904 return 1;
905 }
906
907 if (!new_accept_own && exist_accept_own) {
908 *reason = bgp_path_selection_accept_own;
909 if (debug)
910 zlog_debug(
911 "%s: %s loses to %s due to accept-own",
912 pfx_buf, new_buf, exist_buf);
913 return 0;
914 }
915 }
916
917 /* Tie-breaker - AIGP (Metric TLV) attribute */
918 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
919 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
920 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
921 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
922 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
923
924 if (new_aigp < exist_aigp) {
925 *reason = bgp_path_selection_aigp;
926 if (debug)
927 zlog_debug(
928 "%s: %s wins over %s due to AIGP %" PRIu64
929 " < %" PRIu64,
930 pfx_buf, new_buf, exist_buf, new_aigp,
931 exist_aigp);
932 return 1;
933 }
934
935 if (new_aigp > exist_aigp) {
936 *reason = bgp_path_selection_aigp;
937 if (debug)
938 zlog_debug(
939 "%s: %s loses to %s due to AIGP %" PRIu64
940 " > %" PRIu64,
941 pfx_buf, new_buf, exist_buf, new_aigp,
942 exist_aigp);
943 return 0;
944 }
945 }
946
947 /* 3. Local route check. We prefer:
948 * - BGP_ROUTE_STATIC
949 * - BGP_ROUTE_AGGREGATE
950 * - BGP_ROUTE_REDISTRIBUTE
951 */
952 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
953 new->sub_type == BGP_ROUTE_IMPORTED);
954 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
955 exist->sub_type == BGP_ROUTE_IMPORTED);
956
957 if (new_origin && !exist_origin) {
958 *reason = bgp_path_selection_local_route;
959 if (debug)
960 zlog_debug(
961 "%s: %s wins over %s due to preferred BGP_ROUTE type",
962 pfx_buf, new_buf, exist_buf);
963 return 1;
964 }
965
966 if (!new_origin && exist_origin) {
967 *reason = bgp_path_selection_local_route;
968 if (debug)
969 zlog_debug(
970 "%s: %s loses to %s due to preferred BGP_ROUTE type",
971 pfx_buf, new_buf, exist_buf);
972 return 0;
973 }
974
975 /* Here if these are imported routes then get ultimate pi for
976 * path compare.
977 */
978 new = bgp_get_imported_bpi_ultimate(new);
979 exist = bgp_get_imported_bpi_ultimate(exist);
980 newattr = new->attr;
981 existattr = exist->attr;
982
983 /* 4. AS path length check. */
984 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
985 int exist_hops = aspath_count_hops(existattr->aspath);
986 int exist_confeds = aspath_count_confeds(existattr->aspath);
987
988 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
989 int aspath_hops;
990
991 aspath_hops = aspath_count_hops(newattr->aspath);
992 aspath_hops += aspath_count_confeds(newattr->aspath);
993
994 if (aspath_hops < (exist_hops + exist_confeds)) {
995 *reason = bgp_path_selection_confed_as_path;
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
999 pfx_buf, new_buf, exist_buf,
1000 aspath_hops,
1001 (exist_hops + exist_confeds));
1002 return 1;
1003 }
1004
1005 if (aspath_hops > (exist_hops + exist_confeds)) {
1006 *reason = bgp_path_selection_confed_as_path;
1007 if (debug)
1008 zlog_debug(
1009 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1010 pfx_buf, new_buf, exist_buf,
1011 aspath_hops,
1012 (exist_hops + exist_confeds));
1013 return 0;
1014 }
1015 } else {
1016 int newhops = aspath_count_hops(newattr->aspath);
1017
1018 if (newhops < exist_hops) {
1019 *reason = bgp_path_selection_as_path;
1020 if (debug)
1021 zlog_debug(
1022 "%s: %s wins over %s due to aspath hopcount %d < %d",
1023 pfx_buf, new_buf, exist_buf,
1024 newhops, exist_hops);
1025 return 1;
1026 }
1027
1028 if (newhops > exist_hops) {
1029 *reason = bgp_path_selection_as_path;
1030 if (debug)
1031 zlog_debug(
1032 "%s: %s loses to %s due to aspath hopcount %d > %d",
1033 pfx_buf, new_buf, exist_buf,
1034 newhops, exist_hops);
1035 return 0;
1036 }
1037 }
1038 }
1039
1040 /* 5. Origin check. */
1041 if (newattr->origin < existattr->origin) {
1042 *reason = bgp_path_selection_origin;
1043 if (debug)
1044 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1045 pfx_buf, new_buf, exist_buf,
1046 bgp_origin_long_str[newattr->origin],
1047 bgp_origin_long_str[existattr->origin]);
1048 return 1;
1049 }
1050
1051 if (newattr->origin > existattr->origin) {
1052 *reason = bgp_path_selection_origin;
1053 if (debug)
1054 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1055 pfx_buf, new_buf, exist_buf,
1056 bgp_origin_long_str[newattr->origin],
1057 bgp_origin_long_str[existattr->origin]);
1058 return 0;
1059 }
1060
1061 /* 6. MED check. */
1062 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1063 && aspath_count_hops(existattr->aspath) == 0);
1064 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1065 && aspath_count_confeds(existattr->aspath) > 0
1066 && aspath_count_hops(newattr->aspath) == 0
1067 && aspath_count_hops(existattr->aspath) == 0);
1068
1069 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1070 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1071 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1072 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1073 || internal_as_route) {
1074 new_med = bgp_med_value(new->attr, bgp);
1075 exist_med = bgp_med_value(exist->attr, bgp);
1076
1077 if (new_med < exist_med) {
1078 *reason = bgp_path_selection_med;
1079 if (debug)
1080 zlog_debug(
1081 "%s: %s wins over %s due to MED %d < %d",
1082 pfx_buf, new_buf, exist_buf, new_med,
1083 exist_med);
1084 return 1;
1085 }
1086
1087 if (new_med > exist_med) {
1088 *reason = bgp_path_selection_med;
1089 if (debug)
1090 zlog_debug(
1091 "%s: %s loses to %s due to MED %d > %d",
1092 pfx_buf, new_buf, exist_buf, new_med,
1093 exist_med);
1094 return 0;
1095 }
1096 }
1097
1098 if (exist->sub_type == BGP_ROUTE_IMPORTED) {
1099 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
1100 peer_exist = bpi_ultimate->peer;
1101 } else
1102 peer_exist = exist->peer;
1103
1104 if (new->sub_type == BGP_ROUTE_IMPORTED) {
1105 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
1106 peer_new = bpi_ultimate->peer;
1107 } else
1108 peer_new = new->peer;
1109
1110 /* 7. Peer type check. */
1111 new_sort = peer_new->sort;
1112 exist_sort = peer_exist->sort;
1113
1114 if (new_sort == BGP_PEER_EBGP
1115 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1116 *reason = bgp_path_selection_peer;
1117 if (debug)
1118 zlog_debug(
1119 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1120 pfx_buf, new_buf, exist_buf);
1121 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_EBGP
1127 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1128 *reason = bgp_path_selection_peer;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1134 return 0;
1135 peer_sort_ret = 0;
1136 }
1137
1138 /* 8. IGP metric check. */
1139 newm = existm = 0;
1140
1141 if (new->extra)
1142 newm = new->extra->igpmetric;
1143 if (exist->extra)
1144 existm = exist->extra->igpmetric;
1145
1146 if (newm < existm) {
1147 if (debug && peer_sort_ret < 0)
1148 zlog_debug(
1149 "%s: %s wins over %s due to IGP metric %u < %u",
1150 pfx_buf, new_buf, exist_buf, newm, existm);
1151 igp_metric_ret = 1;
1152 }
1153
1154 if (newm > existm) {
1155 if (debug && peer_sort_ret < 0)
1156 zlog_debug(
1157 "%s: %s loses to %s due to IGP metric %u > %u",
1158 pfx_buf, new_buf, exist_buf, newm, existm);
1159 igp_metric_ret = 0;
1160 }
1161
1162 /* 9. Same IGP metric. Compare the cluster list length as
1163 representative of IGP hops metric. Rewrite the metric value
1164 pair (newm, existm) with the cluster list length. Prefer the
1165 path with smaller cluster list length. */
1166 if (newm == existm) {
1167 if (peer_sort_lookup(peer_new) == BGP_PEER_IBGP &&
1168 peer_sort_lookup(peer_exist) == BGP_PEER_IBGP &&
1169 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1170 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1171 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1172
1173 if (newm < existm) {
1174 if (debug && peer_sort_ret < 0)
1175 zlog_debug(
1176 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1177 pfx_buf, new_buf, exist_buf,
1178 newm, existm);
1179 igp_metric_ret = 1;
1180 }
1181
1182 if (newm > existm) {
1183 if (debug && peer_sort_ret < 0)
1184 zlog_debug(
1185 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1186 pfx_buf, new_buf, exist_buf,
1187 newm, existm);
1188 igp_metric_ret = 0;
1189 }
1190 }
1191 }
1192
1193 /* 10. confed-external vs. confed-internal */
1194 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1195 if (new_sort == BGP_PEER_CONFED
1196 && exist_sort == BGP_PEER_IBGP) {
1197 *reason = bgp_path_selection_confed;
1198 if (debug)
1199 zlog_debug(
1200 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1201 pfx_buf, new_buf, exist_buf);
1202 if (!CHECK_FLAG(bgp->flags,
1203 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1204 return 1;
1205 peer_sort_ret = 1;
1206 }
1207
1208 if (exist_sort == BGP_PEER_CONFED
1209 && new_sort == BGP_PEER_IBGP) {
1210 *reason = bgp_path_selection_confed;
1211 if (debug)
1212 zlog_debug(
1213 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1214 pfx_buf, new_buf, exist_buf);
1215 if (!CHECK_FLAG(bgp->flags,
1216 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1217 return 0;
1218 peer_sort_ret = 0;
1219 }
1220 }
1221
1222 /* 11. Maximum path check. */
1223 if (newm == existm) {
1224 /* If one path has a label but the other does not, do not treat
1225 * them as equals for multipath
1226 */
1227 int newl, existl;
1228
1229 newl = existl = 0;
1230
1231 if (new->extra)
1232 newl = new->extra->num_labels;
1233 if (exist->extra)
1234 existl = exist->extra->num_labels;
1235 if (((new->extra &&bgp_is_valid_label(&new->extra->label[0])) !=
1236 (exist->extra &&
1237 bgp_is_valid_label(&exist->extra->label[0]))) ||
1238 (newl != existl)) {
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1242 pfx_buf, new_buf, exist_buf);
1243 } else if (CHECK_FLAG(bgp->flags,
1244 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1245
1246 /*
1247 * For the two paths, all comparison steps till IGP
1248 * metric
1249 * have succeeded - including AS_PATH hop count. Since
1250 * 'bgp
1251 * bestpath as-path multipath-relax' knob is on, we
1252 * don't need
1253 * an exact match of AS_PATH. Thus, mark the paths are
1254 * equal.
1255 * That will trigger both these paths to get into the
1256 * multipath
1257 * array.
1258 */
1259 *paths_eq = 1;
1260
1261 if (debug)
1262 zlog_debug(
1263 "%s: %s and %s are equal via multipath-relax",
1264 pfx_buf, new_buf, exist_buf);
1265 } else if (peer_new->sort == BGP_PEER_IBGP) {
1266 if (aspath_cmp(new->attr->aspath,
1267 exist->attr->aspath)) {
1268 *paths_eq = 1;
1269
1270 if (debug)
1271 zlog_debug(
1272 "%s: %s and %s are equal via matching aspaths",
1273 pfx_buf, new_buf, exist_buf);
1274 }
1275 } else if (peer_new->as == peer_exist->as) {
1276 *paths_eq = 1;
1277
1278 if (debug)
1279 zlog_debug(
1280 "%s: %s and %s are equal via same remote-as",
1281 pfx_buf, new_buf, exist_buf);
1282 }
1283 } else {
1284 /*
1285 * TODO: If unequal cost ibgp multipath is enabled we can
1286 * mark the paths as equal here instead of returning
1287 */
1288
1289 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1290 * if either step 7 or 10 (peer type checks) yielded a winner,
1291 * that result was returned immediately. Returning from step 10
1292 * ignored the return value computed in steps 8 and 9 (IGP
1293 * metric checks). In order to preserve that behavior, if
1294 * peer_sort_ret is set, return that rather than igp_metric_ret.
1295 */
1296 ret = peer_sort_ret;
1297 if (peer_sort_ret < 0) {
1298 ret = igp_metric_ret;
1299 if (debug) {
1300 if (ret == 1)
1301 zlog_debug(
1302 "%s: %s wins over %s after IGP metric comparison",
1303 pfx_buf, new_buf, exist_buf);
1304 else
1305 zlog_debug(
1306 "%s: %s loses to %s after IGP metric comparison",
1307 pfx_buf, new_buf, exist_buf);
1308 }
1309 *reason = bgp_path_selection_igp_metric;
1310 }
1311 return ret;
1312 }
1313
1314 /*
1315 * At this point, the decision whether to set *paths_eq = 1 has been
1316 * completed. If we deferred returning because of bestpath peer-type
1317 * relax configuration, return now.
1318 */
1319 if (peer_sort_ret >= 0)
1320 return peer_sort_ret;
1321
1322 /* 12. If both paths are external, prefer the path that was received
1323 first (the oldest one). This step minimizes route-flap, since a
1324 newer path won't displace an older one, even if it was the
1325 preferred route based on the additional decision criteria below. */
1326 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1327 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1328 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1329 *reason = bgp_path_selection_older;
1330 if (debug)
1331 zlog_debug(
1332 "%s: %s wins over %s due to oldest external",
1333 pfx_buf, new_buf, exist_buf);
1334 return 1;
1335 }
1336
1337 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1338 *reason = bgp_path_selection_older;
1339 if (debug)
1340 zlog_debug(
1341 "%s: %s loses to %s due to oldest external",
1342 pfx_buf, new_buf, exist_buf);
1343 return 0;
1344 }
1345 }
1346
1347 /* 13. Router-ID comparison. */
1348 /* If one of the paths is "stale", the corresponding peer router-id will
1349 * be 0 and would always win over the other path. If originator id is
1350 * used for the comparison, it will decide which path is better.
1351 */
1352 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1353 new_id.s_addr = newattr->originator_id.s_addr;
1354 else
1355 new_id.s_addr = peer_new->remote_id.s_addr;
1356 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1357 exist_id.s_addr = existattr->originator_id.s_addr;
1358 else
1359 exist_id.s_addr = peer_exist->remote_id.s_addr;
1360
1361 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1362 *reason = bgp_path_selection_router_id;
1363 if (debug)
1364 zlog_debug(
1365 "%s: %s wins over %s due to Router-ID comparison",
1366 pfx_buf, new_buf, exist_buf);
1367 return 1;
1368 }
1369
1370 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1371 *reason = bgp_path_selection_router_id;
1372 if (debug)
1373 zlog_debug(
1374 "%s: %s loses to %s due to Router-ID comparison",
1375 pfx_buf, new_buf, exist_buf);
1376 return 0;
1377 }
1378
1379 /* 14. Cluster length comparison. */
1380 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1381 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1382
1383 if (new_cluster < exist_cluster) {
1384 *reason = bgp_path_selection_cluster_length;
1385 if (debug)
1386 zlog_debug(
1387 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1388 pfx_buf, new_buf, exist_buf, new_cluster,
1389 exist_cluster);
1390 return 1;
1391 }
1392
1393 if (new_cluster > exist_cluster) {
1394 *reason = bgp_path_selection_cluster_length;
1395 if (debug)
1396 zlog_debug(
1397 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1398 pfx_buf, new_buf, exist_buf, new_cluster,
1399 exist_cluster);
1400 return 0;
1401 }
1402
1403 /* 15. Neighbor address comparison. */
1404 /* Do this only if neither path is "stale" as stale paths do not have
1405 * valid peer information (as the connection may or may not be up).
1406 */
1407 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1408 *reason = bgp_path_selection_stale;
1409 if (debug)
1410 zlog_debug(
1411 "%s: %s wins over %s due to latter path being STALE",
1412 pfx_buf, new_buf, exist_buf);
1413 return 1;
1414 }
1415
1416 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1417 *reason = bgp_path_selection_stale;
1418 if (debug)
1419 zlog_debug(
1420 "%s: %s loses to %s due to former path being STALE",
1421 pfx_buf, new_buf, exist_buf);
1422 return 0;
1423 }
1424
1425 /* locally configured routes to advertise do not have su_remote */
1426 if (peer_new->su_remote == NULL) {
1427 *reason = bgp_path_selection_local_configured;
1428 return 0;
1429 }
1430
1431 if (peer_exist->su_remote == NULL) {
1432 *reason = bgp_path_selection_local_configured;
1433 return 1;
1434 }
1435
1436 ret = sockunion_cmp(peer_new->su_remote, peer_exist->su_remote);
1437
1438 if (ret == 1) {
1439 *reason = bgp_path_selection_neighbor_ip;
1440 if (debug)
1441 zlog_debug(
1442 "%s: %s loses to %s due to Neighor IP comparison",
1443 pfx_buf, new_buf, exist_buf);
1444 return 0;
1445 }
1446
1447 if (ret == -1) {
1448 *reason = bgp_path_selection_neighbor_ip;
1449 if (debug)
1450 zlog_debug(
1451 "%s: %s wins over %s due to Neighor IP comparison",
1452 pfx_buf, new_buf, exist_buf);
1453 return 1;
1454 }
1455
1456 *reason = bgp_path_selection_default;
1457 if (debug)
1458 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1459 pfx_buf, new_buf, exist_buf);
1460
1461 return 1;
1462 }
1463
1464
1465 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1466 struct bgp_path_info *exist, int *paths_eq)
1467 {
1468 enum bgp_path_selection_reason reason;
1469 char pfx_buf[PREFIX2STR_BUFFER];
1470
1471 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1472 AFI_L2VPN, SAFI_EVPN, &reason);
1473 }
1474
1475 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1476 * is preferred, or 0 if they are the same (usually will only occur if
1477 * multipath is enabled
1478 * This version is compatible with */
1479 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1480 struct bgp_path_info *exist, char *pfx_buf,
1481 afi_t afi, safi_t safi,
1482 enum bgp_path_selection_reason *reason)
1483 {
1484 int paths_eq;
1485 int ret;
1486 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1487 afi, safi, reason);
1488
1489 if (paths_eq)
1490 ret = 0;
1491 else {
1492 if (ret == 1)
1493 ret = -1;
1494 else
1495 ret = 1;
1496 }
1497 return ret;
1498 }
1499
1500 static enum filter_type bgp_input_filter(struct peer *peer,
1501 const struct prefix *p,
1502 struct attr *attr, afi_t afi,
1503 safi_t safi)
1504 {
1505 struct bgp_filter *filter;
1506 enum filter_type ret = FILTER_PERMIT;
1507
1508 filter = &peer->filter[afi][safi];
1509
1510 #define FILTER_EXIST_WARN(F, f, filter) \
1511 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1512 zlog_debug("%s: Could not find configured input %s-list %s!", \
1513 peer->host, #f, F##_IN_NAME(filter));
1514
1515 if (DISTRIBUTE_IN_NAME(filter)) {
1516 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1517
1518 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1519 == FILTER_DENY) {
1520 ret = FILTER_DENY;
1521 goto done;
1522 }
1523 }
1524
1525 if (PREFIX_LIST_IN_NAME(filter)) {
1526 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1527
1528 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1529 == PREFIX_DENY) {
1530 ret = FILTER_DENY;
1531 goto done;
1532 }
1533 }
1534
1535 if (FILTER_LIST_IN_NAME(filter)) {
1536 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1537
1538 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1539 == AS_FILTER_DENY) {
1540 ret = FILTER_DENY;
1541 goto done;
1542 }
1543 }
1544
1545 done:
1546 if (frrtrace_enabled(frr_bgp, input_filter)) {
1547 char pfxprint[PREFIX2STR_BUFFER];
1548
1549 prefix2str(p, pfxprint, sizeof(pfxprint));
1550 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1551 ret == FILTER_PERMIT ? "permit" : "deny");
1552 }
1553
1554 return ret;
1555 #undef FILTER_EXIST_WARN
1556 }
1557
1558 static enum filter_type bgp_output_filter(struct peer *peer,
1559 const struct prefix *p,
1560 struct attr *attr, afi_t afi,
1561 safi_t safi)
1562 {
1563 struct bgp_filter *filter;
1564 enum filter_type ret = FILTER_PERMIT;
1565
1566 filter = &peer->filter[afi][safi];
1567
1568 #define FILTER_EXIST_WARN(F, f, filter) \
1569 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1570 zlog_debug("%s: Could not find configured output %s-list %s!", \
1571 peer->host, #f, F##_OUT_NAME(filter));
1572
1573 if (DISTRIBUTE_OUT_NAME(filter)) {
1574 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1575
1576 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1577 == FILTER_DENY) {
1578 ret = FILTER_DENY;
1579 goto done;
1580 }
1581 }
1582
1583 if (PREFIX_LIST_OUT_NAME(filter)) {
1584 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1585
1586 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1587 == PREFIX_DENY) {
1588 ret = FILTER_DENY;
1589 goto done;
1590 }
1591 }
1592
1593 if (FILTER_LIST_OUT_NAME(filter)) {
1594 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1595
1596 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1597 == AS_FILTER_DENY) {
1598 ret = FILTER_DENY;
1599 goto done;
1600 }
1601 }
1602
1603 if (frrtrace_enabled(frr_bgp, output_filter)) {
1604 char pfxprint[PREFIX2STR_BUFFER];
1605
1606 prefix2str(p, pfxprint, sizeof(pfxprint));
1607 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1608 ret == FILTER_PERMIT ? "permit" : "deny");
1609 }
1610
1611 done:
1612 return ret;
1613 #undef FILTER_EXIST_WARN
1614 }
1615
1616 /* If community attribute includes no_export then return 1. */
1617 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1618 {
1619 if (bgp_attr_get_community(attr)) {
1620 /* NO_ADVERTISE check. */
1621 if (community_include(bgp_attr_get_community(attr),
1622 COMMUNITY_NO_ADVERTISE))
1623 return true;
1624
1625 /* NO_EXPORT check. */
1626 if (peer->sort == BGP_PEER_EBGP &&
1627 community_include(bgp_attr_get_community(attr),
1628 COMMUNITY_NO_EXPORT))
1629 return true;
1630
1631 /* NO_EXPORT_SUBCONFED check. */
1632 if (peer->sort == BGP_PEER_EBGP
1633 || peer->sort == BGP_PEER_CONFED)
1634 if (community_include(bgp_attr_get_community(attr),
1635 COMMUNITY_NO_EXPORT_SUBCONFED))
1636 return true;
1637 }
1638 return false;
1639 }
1640
1641 /* Route reflection loop check. */
1642 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1643 {
1644 struct in_addr cluster_id;
1645 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1646
1647 if (cluster) {
1648 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1649 cluster_id = peer->bgp->cluster_id;
1650 else
1651 cluster_id = peer->bgp->router_id;
1652
1653 if (cluster_loop_check(cluster, cluster_id))
1654 return true;
1655 }
1656 return false;
1657 }
1658
1659 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1660 {
1661 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1662 if (peer->local_role == ROLE_PROVIDER ||
1663 peer->local_role == ROLE_RS_SERVER)
1664 return true;
1665 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1666 return true;
1667 return false;
1668 }
1669 if (peer->local_role == ROLE_CUSTOMER ||
1670 peer->local_role == ROLE_PEER ||
1671 peer->local_role == ROLE_RS_CLIENT) {
1672 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1673 attr->otc = peer->as;
1674 }
1675 return false;
1676 }
1677
1678 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1679 {
1680 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1681 if (peer->local_role == ROLE_CUSTOMER ||
1682 peer->local_role == ROLE_RS_CLIENT ||
1683 peer->local_role == ROLE_PEER)
1684 return true;
1685 return false;
1686 }
1687 if (peer->local_role == ROLE_PROVIDER ||
1688 peer->local_role == ROLE_PEER ||
1689 peer->local_role == ROLE_RS_SERVER) {
1690 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1691 attr->otc = peer->bgp->as;
1692 }
1693 return false;
1694 }
1695
1696 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1697 {
1698 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1699 }
1700
1701 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1702 struct attr *attr, afi_t afi, safi_t safi,
1703 const char *rmap_name, mpls_label_t *label,
1704 uint32_t num_labels, struct bgp_dest *dest)
1705 {
1706 struct bgp_filter *filter;
1707 struct bgp_path_info rmap_path = { 0 };
1708 struct bgp_path_info_extra extra = { 0 };
1709 route_map_result_t ret;
1710 struct route_map *rmap = NULL;
1711
1712 filter = &peer->filter[afi][safi];
1713
1714 /* Apply default weight value. */
1715 if (peer->weight[afi][safi])
1716 attr->weight = peer->weight[afi][safi];
1717
1718 if (rmap_name) {
1719 rmap = route_map_lookup_by_name(rmap_name);
1720
1721 if (rmap == NULL)
1722 return RMAP_DENY;
1723 } else {
1724 if (ROUTE_MAP_IN_NAME(filter)) {
1725 rmap = ROUTE_MAP_IN(filter);
1726
1727 if (rmap == NULL)
1728 return RMAP_DENY;
1729 }
1730 }
1731
1732 /* Route map apply. */
1733 if (rmap) {
1734 memset(&rmap_path, 0, sizeof(rmap_path));
1735 /* Duplicate current value to new structure for modification. */
1736 rmap_path.peer = peer;
1737 rmap_path.attr = attr;
1738 rmap_path.extra = &extra;
1739 rmap_path.net = dest;
1740
1741 extra.num_labels = num_labels;
1742 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1743 memcpy(extra.label, label,
1744 num_labels * sizeof(mpls_label_t));
1745
1746 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1747
1748 /* Apply BGP route map to the attribute. */
1749 ret = route_map_apply(rmap, p, &rmap_path);
1750
1751 peer->rmap_type = 0;
1752
1753 if (ret == RMAP_DENYMATCH)
1754 return RMAP_DENY;
1755 }
1756 return RMAP_PERMIT;
1757 }
1758
1759 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1760 struct attr *attr, afi_t afi, safi_t safi,
1761 const char *rmap_name)
1762 {
1763 struct bgp_path_info rmap_path;
1764 route_map_result_t ret;
1765 struct route_map *rmap = NULL;
1766 uint8_t rmap_type;
1767
1768 /*
1769 * So if we get to this point and have no rmap_name
1770 * we want to just show the output as it currently
1771 * exists.
1772 */
1773 if (!rmap_name)
1774 return RMAP_PERMIT;
1775
1776 /* Apply default weight value. */
1777 if (peer->weight[afi][safi])
1778 attr->weight = peer->weight[afi][safi];
1779
1780 rmap = route_map_lookup_by_name(rmap_name);
1781
1782 /*
1783 * If we have a route map name and we do not find
1784 * the routemap that means we have an implicit
1785 * deny.
1786 */
1787 if (rmap == NULL)
1788 return RMAP_DENY;
1789
1790 memset(&rmap_path, 0, sizeof(rmap_path));
1791 /* Route map apply. */
1792 /* Duplicate current value to new structure for modification. */
1793 rmap_path.peer = peer;
1794 rmap_path.attr = attr;
1795
1796 rmap_type = peer->rmap_type;
1797 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1798
1799 /* Apply BGP route map to the attribute. */
1800 ret = route_map_apply(rmap, p, &rmap_path);
1801
1802 peer->rmap_type = rmap_type;
1803
1804 if (ret == RMAP_DENYMATCH)
1805 /*
1806 * caller has multiple error paths with bgp_attr_flush()
1807 */
1808 return RMAP_DENY;
1809
1810 return RMAP_PERMIT;
1811 }
1812
1813 /* If this is an EBGP peer with remove-private-AS */
1814 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1815 struct peer *peer, struct attr *attr)
1816 {
1817 if (peer->sort == BGP_PEER_EBGP
1818 && (peer_af_flag_check(peer, afi, safi,
1819 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1820 || peer_af_flag_check(peer, afi, safi,
1821 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1822 || peer_af_flag_check(peer, afi, safi,
1823 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1824 || peer_af_flag_check(peer, afi, safi,
1825 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1826 // Take action on the entire aspath
1827 if (peer_af_flag_check(peer, afi, safi,
1828 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1829 || peer_af_flag_check(peer, afi, safi,
1830 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1831 if (peer_af_flag_check(
1832 peer, afi, safi,
1833 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1834 attr->aspath = aspath_replace_private_asns(
1835 attr->aspath, bgp->as, peer->as);
1836
1837 /*
1838 * Even if the aspath consists of just private ASNs we
1839 * need to walk the AS-Path to maintain all instances
1840 * of the peer's ASN to break possible loops.
1841 */
1842 else
1843 attr->aspath = aspath_remove_private_asns(
1844 attr->aspath, peer->as);
1845 }
1846
1847 // 'all' was not specified so the entire aspath must be private
1848 // ASNs
1849 // for us to do anything
1850 else if (aspath_private_as_check(attr->aspath)) {
1851 if (peer_af_flag_check(
1852 peer, afi, safi,
1853 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1854 attr->aspath = aspath_replace_private_asns(
1855 attr->aspath, bgp->as, peer->as);
1856 else
1857 /*
1858 * Walk the aspath to retain any instances of
1859 * the peer_asn
1860 */
1861 attr->aspath = aspath_remove_private_asns(
1862 attr->aspath, peer->as);
1863 }
1864 }
1865 }
1866
1867 /* If this is an EBGP peer with as-override */
1868 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1869 struct peer *peer, struct attr *attr)
1870 {
1871 struct aspath *aspath;
1872
1873 if (peer->sort == BGP_PEER_EBGP &&
1874 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1875 if (attr->aspath->refcnt)
1876 aspath = aspath_dup(attr->aspath);
1877 else
1878 aspath = attr->aspath;
1879
1880 attr->aspath = aspath_intern(
1881 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1882
1883 aspath_free(aspath);
1884 }
1885 }
1886
1887 void bgp_attr_add_llgr_community(struct attr *attr)
1888 {
1889 struct community *old;
1890 struct community *new;
1891 struct community *merge;
1892 struct community *llgr;
1893
1894 old = bgp_attr_get_community(attr);
1895 llgr = community_str2com("llgr-stale");
1896
1897 assert(llgr);
1898
1899 if (old) {
1900 merge = community_merge(community_dup(old), llgr);
1901
1902 if (old->refcnt == 0)
1903 community_free(&old);
1904
1905 new = community_uniq_sort(merge);
1906 community_free(&merge);
1907 } else {
1908 new = community_dup(llgr);
1909 }
1910
1911 community_free(&llgr);
1912
1913 bgp_attr_set_community(attr, new);
1914 }
1915
1916 void bgp_attr_add_gshut_community(struct attr *attr)
1917 {
1918 struct community *old;
1919 struct community *new;
1920 struct community *merge;
1921 struct community *gshut;
1922
1923 old = bgp_attr_get_community(attr);
1924 gshut = community_str2com("graceful-shutdown");
1925
1926 assert(gshut);
1927
1928 if (old) {
1929 merge = community_merge(community_dup(old), gshut);
1930
1931 if (old->refcnt == 0)
1932 community_free(&old);
1933
1934 new = community_uniq_sort(merge);
1935 community_free(&merge);
1936 } else {
1937 new = community_dup(gshut);
1938 }
1939
1940 community_free(&gshut);
1941 bgp_attr_set_community(attr, new);
1942
1943 /* When we add the graceful-shutdown community we must also
1944 * lower the local-preference */
1945 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1946 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1947 }
1948
1949
1950 /* Notify BGP Conditional advertisement scanner process. */
1951 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1952 {
1953 struct peer *peer = SUBGRP_PEER(subgrp);
1954 afi_t afi = SUBGRP_AFI(subgrp);
1955 safi_t safi = SUBGRP_SAFI(subgrp);
1956 struct bgp_filter *filter = &peer->filter[afi][safi];
1957
1958 if (!ADVERTISE_MAP_NAME(filter))
1959 return;
1960
1961 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1962 return;
1963
1964 peer->advmap_table_change = true;
1965 }
1966
1967
1968 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1969 {
1970 if (family == AF_INET) {
1971 attr->nexthop.s_addr = INADDR_ANY;
1972 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1973 }
1974 if (family == AF_INET6)
1975 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1976 if (family == AF_EVPN)
1977 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1978 }
1979
1980 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1981 struct update_subgroup *subgrp,
1982 const struct prefix *p, struct attr *attr,
1983 struct attr *post_attr)
1984 {
1985 struct bgp_filter *filter;
1986 struct peer *from;
1987 struct peer *peer;
1988 struct peer *onlypeer;
1989 struct bgp *bgp;
1990 struct attr *piattr;
1991 route_map_result_t ret;
1992 int transparent;
1993 int reflect;
1994 afi_t afi;
1995 safi_t safi;
1996 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1997 bool nh_reset = false;
1998 uint64_t cum_bw;
1999
2000 if (DISABLE_BGP_ANNOUNCE)
2001 return false;
2002
2003 afi = SUBGRP_AFI(subgrp);
2004 safi = SUBGRP_SAFI(subgrp);
2005 peer = SUBGRP_PEER(subgrp);
2006 onlypeer = NULL;
2007 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2008 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2009
2010 from = pi->peer;
2011 filter = &peer->filter[afi][safi];
2012 bgp = SUBGRP_INST(subgrp);
2013 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2014 : pi->attr;
2015
2016 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2017 peer->pmax_out[afi][safi] != 0 &&
2018 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2019 if (BGP_DEBUG(update, UPDATE_OUT) ||
2020 BGP_DEBUG(update, UPDATE_PREFIX)) {
2021 zlog_debug("%s reached maximum prefix to be send (%u)",
2022 peer->host, peer->pmax_out[afi][safi]);
2023 }
2024 return false;
2025 }
2026
2027 #ifdef ENABLE_BGP_VNC
2028 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2029 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2030 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2031
2032 /*
2033 * direct and direct_ext type routes originate internally even
2034 * though they can have peer pointers that reference other
2035 * systems
2036 */
2037 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2038 __func__, p);
2039 samepeer_safe = 1;
2040 }
2041 #endif
2042
2043 if (((afi == AFI_IP) || (afi == AFI_IP6))
2044 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2045 && (pi->type == ZEBRA_ROUTE_BGP)
2046 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2047
2048 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2049
2050 samepeer_safe = 1;
2051 }
2052
2053 /* With addpath we may be asked to TX all kinds of paths so make sure
2054 * pi is valid */
2055 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2056 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2057 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2058 return false;
2059 }
2060
2061 /* If this is not the bestpath then check to see if there is an enabled
2062 * addpath
2063 * feature that requires us to advertise it */
2064 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2065 if (!bgp_addpath_capable(pi, peer, afi, safi))
2066 return false;
2067
2068 /* Aggregate-address suppress check. */
2069 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2070 return false;
2071
2072 /*
2073 * If we are doing VRF 2 VRF leaking via the import
2074 * statement, we want to prevent the route going
2075 * off box as that the RT and RD created are localy
2076 * significant and globaly useless.
2077 */
2078 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2079 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2080 return false;
2081
2082 /* If it's labeled safi, make sure the route has a valid label. */
2083 if (safi == SAFI_LABELED_UNICAST) {
2084 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2085 if (!bgp_is_valid_label(&label)) {
2086 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2087 zlog_debug("u%" PRIu64 ":s%" PRIu64
2088 " %pFX is filtered - no label (%p)",
2089 subgrp->update_group->id, subgrp->id,
2090 p, &label);
2091 return false;
2092 }
2093 }
2094
2095 /* Do not send back route to sender. */
2096 if (onlypeer && from == onlypeer) {
2097 return false;
2098 }
2099
2100 /* Do not send the default route in the BGP table if the neighbor is
2101 * configured for default-originate */
2102 if (CHECK_FLAG(peer->af_flags[afi][safi],
2103 PEER_FLAG_DEFAULT_ORIGINATE)) {
2104 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2105 return false;
2106 else if (p->family == AF_INET6 && p->prefixlen == 0)
2107 return false;
2108 }
2109
2110 /* Transparency check. */
2111 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2112 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2113 transparent = 1;
2114 else
2115 transparent = 0;
2116
2117 /* If community is not disabled check the no-export and local. */
2118 if (!transparent && bgp_community_filter(peer, piattr)) {
2119 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2120 zlog_debug("%s: community filter check fail for %pFX",
2121 __func__, p);
2122 return false;
2123 }
2124
2125 /* If the attribute has originator-id and it is same as remote
2126 peer's id. */
2127 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2128 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2129 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2130 zlog_debug(
2131 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2132 onlypeer, p);
2133 return false;
2134 }
2135
2136 /* ORF prefix-list filter check */
2137 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2138 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2139 || CHECK_FLAG(peer->af_cap[afi][safi],
2140 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2141 if (peer->orf_plist[afi][safi]) {
2142 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2143 == PREFIX_DENY) {
2144 if (bgp_debug_update(NULL, p,
2145 subgrp->update_group, 0))
2146 zlog_debug(
2147 "%pBP [Update:SEND] %pFX is filtered via ORF",
2148 peer, p);
2149 return false;
2150 }
2151 }
2152
2153 /* Output filter check. */
2154 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2155 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2156 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2157 p);
2158 return false;
2159 }
2160
2161 /* AS path loop check. */
2162 if (peer->as_path_loop_detection &&
2163 aspath_loop_check(piattr->aspath, peer->as)) {
2164 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2165 zlog_debug(
2166 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2167 peer, peer->as);
2168 return false;
2169 }
2170
2171 /* If we're a CONFED we need to loop check the CONFED ID too */
2172 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2173 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2174 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2175 zlog_debug(
2176 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2177 peer, bgp->confed_id);
2178 return false;
2179 }
2180 }
2181
2182 /* Route-Reflect check. */
2183 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2184 reflect = 1;
2185 else
2186 reflect = 0;
2187
2188 /* IBGP reflection check. */
2189 if (reflect && !samepeer_safe) {
2190 /* A route from a Client peer. */
2191 if (CHECK_FLAG(from->af_flags[afi][safi],
2192 PEER_FLAG_REFLECTOR_CLIENT)) {
2193 /* Reflect to all the Non-Client peers and also to the
2194 Client peers other than the originator. Originator
2195 check
2196 is already done. So there is noting to do. */
2197 /* no bgp client-to-client reflection check. */
2198 if (CHECK_FLAG(bgp->flags,
2199 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2200 if (CHECK_FLAG(peer->af_flags[afi][safi],
2201 PEER_FLAG_REFLECTOR_CLIENT))
2202 return false;
2203 } else {
2204 /* A route from a Non-client peer. Reflect to all other
2205 clients. */
2206 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2207 PEER_FLAG_REFLECTOR_CLIENT))
2208 return false;
2209 }
2210 }
2211
2212 /* For modify attribute, copy it to temporary structure.
2213 * post_attr comes from BGP conditional advertisements, where
2214 * attributes are already processed by advertise-map route-map,
2215 * and this needs to be saved instead of overwriting from the
2216 * path attributes.
2217 */
2218 if (post_attr)
2219 *attr = *post_attr;
2220 else
2221 *attr = *piattr;
2222
2223 /* If local-preference is not set. */
2224 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2225 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2226 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2227 attr->local_pref = bgp->default_local_pref;
2228 }
2229
2230 /* If originator-id is not set and the route is to be reflected,
2231 set the originator id */
2232 if (reflect
2233 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2234 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2235 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2236 }
2237
2238 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2239 */
2240 if (peer->sort == BGP_PEER_EBGP
2241 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2242 if (from != bgp->peer_self && !transparent
2243 && !CHECK_FLAG(peer->af_flags[afi][safi],
2244 PEER_FLAG_MED_UNCHANGED))
2245 attr->flag &=
2246 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2247 }
2248
2249 /* Since the nexthop attribute can vary per peer, it is not explicitly
2250 * set
2251 * in announce check, only certain flags and length (or number of
2252 * nexthops
2253 * -- for IPv6/MP_REACH) are set here in order to guide the update
2254 * formation
2255 * code in setting the nexthop(s) on a per peer basis in
2256 * reformat_peer().
2257 * Typically, the source nexthop in the attribute is preserved but in
2258 * the
2259 * scenarios where we know it will always be overwritten, we reset the
2260 * nexthop to "0" in an attempt to achieve better Update packing. An
2261 * example of this is when a prefix from each of 2 IBGP peers needs to
2262 * be
2263 * announced to an EBGP peer (and they have the same attributes barring
2264 * their nexthop).
2265 */
2266 if (reflect)
2267 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2268
2269 #define NEXTHOP_IS_V6 \
2270 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2271 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2272 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2273 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2274
2275 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2276 * if
2277 * the peer (group) is configured to receive link-local nexthop
2278 * unchanged
2279 * and it is available in the prefix OR we're not reflecting the route,
2280 * link-local nexthop address is valid and
2281 * the peer (group) to whom we're going to announce is on a shared
2282 * network
2283 * and this is either a self-originated route or the peer is EBGP.
2284 * By checking if nexthop LL address is valid we are sure that
2285 * we do not announce LL address as `::`.
2286 */
2287 if (NEXTHOP_IS_V6) {
2288 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2289 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2290 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2291 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2292 || (!reflect && !transparent
2293 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2294 && peer->shared_network
2295 && (from == bgp->peer_self
2296 || peer->sort == BGP_PEER_EBGP))) {
2297 if (safi == SAFI_MPLS_VPN)
2298 attr->mp_nexthop_len =
2299 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2300 else
2301 attr->mp_nexthop_len =
2302 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2303 }
2304
2305 /* Clear off link-local nexthop in source, whenever it is not
2306 * needed to
2307 * ensure more prefixes share the same attribute for
2308 * announcement.
2309 */
2310 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2311 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2312 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2313 }
2314
2315 if (bgp_check_role_applicability(afi, safi) &&
2316 bgp_otc_egress(peer, attr))
2317 return false;
2318
2319 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2320 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2321
2322 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2323 filter->advmap.aname &&
2324 route_map_lookup_by_name(filter->advmap.aname)) {
2325 struct bgp_path_info rmap_path = {0};
2326 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2327 struct attr dummy_attr = *attr;
2328
2329 /* Fill temp path_info */
2330 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2331 pi, peer, &dummy_attr);
2332
2333 struct route_map *amap =
2334 route_map_lookup_by_name(filter->advmap.aname);
2335
2336 ret = route_map_apply(amap, p, &rmap_path);
2337
2338 bgp_attr_flush(&dummy_attr);
2339
2340 /*
2341 * The conditional advertisement mode is Withdraw and this
2342 * prefix is a conditional prefix. Don't advertise it
2343 */
2344 if (ret == RMAP_PERMITMATCH)
2345 return false;
2346 }
2347
2348 /* Route map & unsuppress-map apply. */
2349 if (!post_attr &&
2350 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2351 struct bgp_path_info rmap_path = {0};
2352 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2353 struct attr dummy_attr = {0};
2354
2355 /* Fill temp path_info */
2356 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2357 pi, peer, attr);
2358
2359 /* don't confuse inbound and outbound setting */
2360 RESET_FLAG(attr->rmap_change_flags);
2361
2362 /*
2363 * The route reflector is not allowed to modify the attributes
2364 * of the reflected IBGP routes unless explicitly allowed.
2365 */
2366 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2367 && !CHECK_FLAG(bgp->flags,
2368 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2369 dummy_attr = *attr;
2370 rmap_path.attr = &dummy_attr;
2371 }
2372
2373 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2374
2375 if (bgp_path_suppressed(pi))
2376 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2377 &rmap_path);
2378 else
2379 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2380 &rmap_path);
2381
2382 bgp_attr_flush(&dummy_attr);
2383 peer->rmap_type = 0;
2384
2385 if (ret == RMAP_DENYMATCH) {
2386 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2387 zlog_debug(
2388 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2389 peer, p,
2390 bgp_path_suppressed(pi)
2391 ? UNSUPPRESS_MAP_NAME(filter)
2392 : ROUTE_MAP_OUT_NAME(filter));
2393 bgp_attr_flush(rmap_path.attr);
2394 return false;
2395 }
2396 }
2397
2398 /* RFC 8212 to prevent route leaks.
2399 * This specification intends to improve this situation by requiring the
2400 * explicit configuration of both BGP Import and Export Policies for any
2401 * External BGP (EBGP) session such as customers, peers, or
2402 * confederation boundaries for all enabled address families. Through
2403 * codification of the aforementioned requirement, operators will
2404 * benefit from consistent behavior across different BGP
2405 * implementations.
2406 */
2407 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2408 if (!bgp_outbound_policy_exists(peer, filter)) {
2409 if (monotime_since(&bgp->ebgprequirespolicywarning,
2410 NULL) > FIFTEENMINUTE2USEC ||
2411 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2412 zlog_warn(
2413 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2414 monotime(&bgp->ebgprequirespolicywarning);
2415 }
2416 return false;
2417 }
2418
2419 /* draft-ietf-idr-deprecate-as-set-confed-set
2420 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2421 * Eventually, This document (if approved) updates RFC 4271
2422 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2423 * and obsoletes RFC 6472.
2424 */
2425 if (peer->bgp->reject_as_sets)
2426 if (aspath_check_as_sets(attr->aspath))
2427 return false;
2428
2429 /* If neighbor soo is configured, then check if the route has
2430 * SoO extended community and validate against the configured
2431 * one. If they match, do not announce, to prevent routing
2432 * loops.
2433 */
2434 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2435 peer->soo[afi][safi]) {
2436 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2437 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2438
2439 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2440 ECOMMUNITY_SITE_ORIGIN) ||
2441 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2442 ECOMMUNITY_SITE_ORIGIN) ||
2443 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2444 ECOMMUNITY_SITE_ORIGIN)) &&
2445 ecommunity_include(ecomm, ecomm_soo)) {
2446 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2447 zlog_debug(
2448 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2449 peer, p, ecommunity_str(ecomm_soo));
2450 return false;
2451 }
2452 }
2453
2454 /* Codification of AS 0 Processing */
2455 if (aspath_check_as_zero(attr->aspath))
2456 return false;
2457
2458 if (bgp_in_graceful_shutdown(bgp)) {
2459 if (peer->sort == BGP_PEER_IBGP
2460 || peer->sort == BGP_PEER_CONFED) {
2461 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2462 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2463 } else {
2464 bgp_attr_add_gshut_community(attr);
2465 }
2466 }
2467
2468 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2469 * Capability" to a neighbor MUST perform the following upon receiving
2470 * a route from that neighbor with the "LLGR_STALE" community, or upon
2471 * attaching the "LLGR_STALE" community itself per Section 4.2:
2472 *
2473 * The route SHOULD NOT be advertised to any neighbor from which the
2474 * Long-lived Graceful Restart Capability has not been received.
2475 */
2476 if (bgp_attr_get_community(attr) &&
2477 community_include(bgp_attr_get_community(attr),
2478 COMMUNITY_LLGR_STALE) &&
2479 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2480 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2481 return false;
2482
2483 /* After route-map has been applied, we check to see if the nexthop to
2484 * be carried in the attribute (that is used for the announcement) can
2485 * be cleared off or not. We do this in all cases where we would be
2486 * setting the nexthop to "ourselves". For IPv6, we only need to
2487 * consider
2488 * the global nexthop here; the link-local nexthop would have been
2489 * cleared
2490 * already, and if not, it is required by the update formation code.
2491 * Also see earlier comments in this function.
2492 */
2493 /*
2494 * If route-map has performed some operation on the nexthop or the peer
2495 * configuration says to pass it unchanged, we cannot reset the nexthop
2496 * here, so only attempt to do it if these aren't true. Note that the
2497 * route-map handler itself might have cleared the nexthop, if for
2498 * example,
2499 * it is configured as 'peer-address'.
2500 */
2501 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2502 piattr->rmap_change_flags)
2503 && !transparent
2504 && !CHECK_FLAG(peer->af_flags[afi][safi],
2505 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2506 /* We can reset the nexthop, if setting (or forcing) it to
2507 * 'self' */
2508 if (CHECK_FLAG(peer->af_flags[afi][safi],
2509 PEER_FLAG_NEXTHOP_SELF)
2510 || CHECK_FLAG(peer->af_flags[afi][safi],
2511 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2512 if (!reflect
2513 || CHECK_FLAG(peer->af_flags[afi][safi],
2514 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2515 subgroup_announce_reset_nhop(
2516 (peer_cap_enhe(peer, afi, safi)
2517 ? AF_INET6
2518 : p->family),
2519 attr);
2520 nh_reset = true;
2521 }
2522 } else if (peer->sort == BGP_PEER_EBGP) {
2523 /* Can also reset the nexthop if announcing to EBGP, but
2524 * only if
2525 * no peer in the subgroup is on a shared subnet.
2526 * Note: 3rd party nexthop currently implemented for
2527 * IPv4 only.
2528 */
2529 if ((p->family == AF_INET) &&
2530 (!bgp_subgrp_multiaccess_check_v4(
2531 piattr->nexthop,
2532 subgrp, from))) {
2533 subgroup_announce_reset_nhop(
2534 (peer_cap_enhe(peer, afi, safi)
2535 ? AF_INET6
2536 : p->family),
2537 attr);
2538 nh_reset = true;
2539 }
2540
2541 if ((p->family == AF_INET6) &&
2542 (!bgp_subgrp_multiaccess_check_v6(
2543 piattr->mp_nexthop_global,
2544 subgrp, from))) {
2545 subgroup_announce_reset_nhop(
2546 (peer_cap_enhe(peer, afi, safi)
2547 ? AF_INET6
2548 : p->family),
2549 attr);
2550 nh_reset = true;
2551 }
2552
2553
2554
2555 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2556 /*
2557 * This flag is used for leaked vpn-vrf routes
2558 */
2559 int family = p->family;
2560
2561 if (peer_cap_enhe(peer, afi, safi))
2562 family = AF_INET6;
2563
2564 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2565 zlog_debug(
2566 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2567 __func__, p, family2str(family));
2568 subgroup_announce_reset_nhop(family, attr);
2569 nh_reset = true;
2570 }
2571 }
2572
2573 /* If IPv6/MP and nexthop does not have any override and happens
2574 * to
2575 * be a link-local address, reset it so that we don't pass along
2576 * the
2577 * source's link-local IPv6 address to recipients who may not be
2578 * on
2579 * the same interface.
2580 */
2581 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2582 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2583 subgroup_announce_reset_nhop(AF_INET6, attr);
2584 nh_reset = true;
2585 }
2586 }
2587
2588 /* If this is an iBGP, send Origin Validation State (OVS)
2589 * extended community (rfc8097).
2590 */
2591 if (peer->sort == BGP_PEER_IBGP) {
2592 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2593
2594 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2595
2596 if (rpki_state != RPKI_NOT_BEING_USED)
2597 bgp_attr_set_ecommunity(
2598 attr, ecommunity_add_origin_validation_state(
2599 rpki_state,
2600 bgp_attr_get_ecommunity(attr)));
2601 }
2602
2603 /*
2604 * When the next hop is set to ourselves, if all multipaths have
2605 * link-bandwidth announce the cumulative bandwidth as that makes
2606 * the most sense. However, don't modify if the link-bandwidth has
2607 * been explicitly set by user policy.
2608 */
2609 if (nh_reset &&
2610 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2611 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2612 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2613 bgp_attr_set_ecommunity(
2614 attr,
2615 ecommunity_replace_linkbw(
2616 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2617 CHECK_FLAG(
2618 peer->flags,
2619 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2620
2621 return true;
2622 }
2623
2624 static void bgp_route_select_timer_expire(struct event *thread)
2625 {
2626 struct afi_safi_info *info;
2627 afi_t afi;
2628 safi_t safi;
2629 struct bgp *bgp;
2630
2631 info = EVENT_ARG(thread);
2632 afi = info->afi;
2633 safi = info->safi;
2634 bgp = info->bgp;
2635
2636 bgp->gr_info[afi][safi].t_route_select = NULL;
2637 XFREE(MTYPE_TMP, info);
2638
2639 /* Best path selection */
2640 bgp_best_path_select_defer(bgp, afi, safi);
2641 }
2642
2643 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2644 struct bgp_maxpaths_cfg *mpath_cfg,
2645 struct bgp_path_info_pair *result, afi_t afi,
2646 safi_t safi)
2647 {
2648 struct bgp_path_info *new_select;
2649 struct bgp_path_info *old_select;
2650 struct bgp_path_info *pi;
2651 struct bgp_path_info *pi1;
2652 struct bgp_path_info *pi2;
2653 struct bgp_path_info *nextpi = NULL;
2654 int paths_eq, do_mpath, debug;
2655 struct list mp_list;
2656 char pfx_buf[PREFIX2STR_BUFFER];
2657 char path_buf[PATH_ADDPATH_STR_BUFFER];
2658
2659 bgp_mp_list_init(&mp_list);
2660 do_mpath =
2661 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2662
2663 debug = bgp_debug_bestpath(dest);
2664
2665 if (debug)
2666 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2667
2668 dest->reason = bgp_path_selection_none;
2669 /* bgp deterministic-med */
2670 new_select = NULL;
2671 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2672
2673 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2674 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2675 pi1 = pi1->next)
2676 bgp_path_info_unset_flag(dest, pi1,
2677 BGP_PATH_DMED_SELECTED);
2678
2679 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2680 pi1 = pi1->next) {
2681 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2682 continue;
2683 if (BGP_PATH_HOLDDOWN(pi1))
2684 continue;
2685 if (pi1->peer != bgp->peer_self &&
2686 !CHECK_FLAG(pi1->peer->sflags,
2687 PEER_STATUS_NSF_WAIT)) {
2688 if (!peer_established(pi1->peer))
2689 continue;
2690 }
2691
2692 new_select = pi1;
2693 if (pi1->next) {
2694 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2695 if (CHECK_FLAG(pi2->flags,
2696 BGP_PATH_DMED_CHECK))
2697 continue;
2698 if (BGP_PATH_HOLDDOWN(pi2))
2699 continue;
2700 if (pi2->peer != bgp->peer_self
2701 && !CHECK_FLAG(
2702 pi2->peer->sflags,
2703 PEER_STATUS_NSF_WAIT))
2704 if (pi2->peer->status
2705 != Established)
2706 continue;
2707
2708 if (!aspath_cmp_left(pi1->attr->aspath,
2709 pi2->attr->aspath)
2710 && !aspath_cmp_left_confed(
2711 pi1->attr->aspath,
2712 pi2->attr->aspath))
2713 continue;
2714
2715 if (bgp_path_info_cmp(
2716 bgp, pi2, new_select,
2717 &paths_eq, mpath_cfg, debug,
2718 pfx_buf, afi, safi,
2719 &dest->reason)) {
2720 bgp_path_info_unset_flag(
2721 dest, new_select,
2722 BGP_PATH_DMED_SELECTED);
2723 new_select = pi2;
2724 }
2725
2726 bgp_path_info_set_flag(
2727 dest, pi2, BGP_PATH_DMED_CHECK);
2728 }
2729 }
2730 bgp_path_info_set_flag(dest, new_select,
2731 BGP_PATH_DMED_CHECK);
2732 bgp_path_info_set_flag(dest, new_select,
2733 BGP_PATH_DMED_SELECTED);
2734
2735 if (debug) {
2736 bgp_path_info_path_with_addpath_rx_str(
2737 new_select, path_buf, sizeof(path_buf));
2738 zlog_debug(
2739 "%pBD(%s): %s is the bestpath from AS %u",
2740 dest, bgp->name_pretty, path_buf,
2741 aspath_get_first_as(
2742 new_select->attr->aspath));
2743 }
2744 }
2745 }
2746
2747 /* Check old selected route and new selected route. */
2748 old_select = NULL;
2749 new_select = NULL;
2750 for (pi = bgp_dest_get_bgp_path_info(dest);
2751 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2752 enum bgp_path_selection_reason reason;
2753
2754 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2755 old_select = pi;
2756
2757 if (BGP_PATH_HOLDDOWN(pi)) {
2758 /* reap REMOVED routes, if needs be
2759 * selected route must stay for a while longer though
2760 */
2761 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2762 && (pi != old_select))
2763 bgp_path_info_reap(dest, pi);
2764
2765 if (debug)
2766 zlog_debug(
2767 "%s: %pBD(%s) pi from %s in holddown",
2768 __func__, dest, bgp->name_pretty,
2769 pi->peer->host);
2770
2771 continue;
2772 }
2773
2774 if (pi->peer && pi->peer != bgp->peer_self
2775 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2776 if (!peer_established(pi->peer)) {
2777
2778 if (debug)
2779 zlog_debug(
2780 "%s: %pBD(%s) non self peer %s not estab state",
2781 __func__, dest,
2782 bgp->name_pretty,
2783 pi->peer->host);
2784
2785 continue;
2786 }
2787
2788 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2789 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2790 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2791 if (debug)
2792 zlog_debug("%s: %pBD(%s) pi %s dmed", __func__,
2793 dest, bgp->name_pretty,
2794 pi->peer->host);
2795 continue;
2796 }
2797
2798 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2799
2800 reason = dest->reason;
2801 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2802 debug, pfx_buf, afi, safi,
2803 &dest->reason)) {
2804 if (new_select == NULL &&
2805 reason != bgp_path_selection_none)
2806 dest->reason = reason;
2807 new_select = pi;
2808 }
2809 }
2810
2811 /* Now that we know which path is the bestpath see if any of the other
2812 * paths
2813 * qualify as multipaths
2814 */
2815 if (debug) {
2816 if (new_select)
2817 bgp_path_info_path_with_addpath_rx_str(
2818 new_select, path_buf, sizeof(path_buf));
2819 else
2820 snprintf(path_buf, sizeof(path_buf), "NONE");
2821 zlog_debug(
2822 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2823 dest, bgp->name_pretty, path_buf,
2824 old_select ? old_select->peer->host : "NONE");
2825 }
2826
2827 if (do_mpath && new_select) {
2828 for (pi = bgp_dest_get_bgp_path_info(dest);
2829 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2830
2831 if (debug)
2832 bgp_path_info_path_with_addpath_rx_str(
2833 pi, path_buf, sizeof(path_buf));
2834
2835 if (pi == new_select) {
2836 if (debug)
2837 zlog_debug(
2838 "%pBD(%s): %s is the bestpath, add to the multipath list",
2839 dest, bgp->name_pretty,
2840 path_buf);
2841 bgp_mp_list_add(&mp_list, pi);
2842 continue;
2843 }
2844
2845 if (BGP_PATH_HOLDDOWN(pi))
2846 continue;
2847
2848 if (pi->peer && pi->peer != bgp->peer_self
2849 && !CHECK_FLAG(pi->peer->sflags,
2850 PEER_STATUS_NSF_WAIT))
2851 if (!peer_established(pi->peer))
2852 continue;
2853
2854 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2855 if (debug)
2856 zlog_debug(
2857 "%pBD(%s): %s has the same nexthop as the bestpath, skip it",
2858 dest, bgp->name_pretty,
2859 path_buf);
2860 continue;
2861 }
2862
2863 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2864 mpath_cfg, debug, pfx_buf, afi, safi,
2865 &dest->reason);
2866
2867 if (paths_eq) {
2868 if (debug)
2869 zlog_debug(
2870 "%pBD(%s): %s is equivalent to the bestpath, add to the multipath list",
2871 dest, bgp->name_pretty,
2872 path_buf);
2873 bgp_mp_list_add(&mp_list, pi);
2874 }
2875 }
2876 }
2877
2878 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2879 mpath_cfg);
2880 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2881 bgp_mp_list_clear(&mp_list);
2882
2883 bgp_addpath_update_ids(bgp, dest, afi, safi);
2884
2885 result->old = old_select;
2886 result->new = new_select;
2887
2888 return;
2889 }
2890
2891 /*
2892 * A new route/change in bestpath of an existing route. Evaluate the path
2893 * for advertisement to the subgroup.
2894 */
2895 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2896 struct bgp_path_info *selected,
2897 struct bgp_dest *dest,
2898 uint32_t addpath_tx_id)
2899 {
2900 const struct prefix *p;
2901 struct peer *onlypeer;
2902 struct attr attr;
2903 afi_t afi;
2904 safi_t safi;
2905 struct bgp *bgp;
2906 bool advertise;
2907
2908 p = bgp_dest_get_prefix(dest);
2909 afi = SUBGRP_AFI(subgrp);
2910 safi = SUBGRP_SAFI(subgrp);
2911 bgp = SUBGRP_INST(subgrp);
2912 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2913 : NULL);
2914
2915 if (BGP_DEBUG(update, UPDATE_OUT))
2916 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2917
2918 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2919 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2920 PEER_STATUS_ORF_WAIT_REFRESH))
2921 return;
2922
2923 memset(&attr, 0, sizeof(attr));
2924 /* It's initialized in bgp_announce_check() */
2925
2926 /* Announcement to the subgroup. If the route is filtered withdraw it.
2927 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2928 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2929 * route
2930 */
2931 advertise = bgp_check_advertise(bgp, dest);
2932
2933 if (selected) {
2934 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2935 NULL)) {
2936 /* Route is selected, if the route is already installed
2937 * in FIB, then it is advertised
2938 */
2939 if (advertise) {
2940 if (!bgp_check_withdrawal(bgp, dest)) {
2941 struct attr *adv_attr =
2942 bgp_attr_intern(&attr);
2943
2944 bgp_adj_out_set_subgroup(dest, subgrp,
2945 adv_attr,
2946 selected);
2947 } else
2948 bgp_adj_out_unset_subgroup(
2949 dest, subgrp, 1, addpath_tx_id);
2950 }
2951 } else
2952 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2953 addpath_tx_id);
2954 }
2955
2956 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2957 else {
2958 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2959 }
2960 }
2961
2962 /*
2963 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2964 * This is called at the end of route processing.
2965 */
2966 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2967 {
2968 struct bgp_path_info *pi;
2969
2970 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2971 if (BGP_PATH_HOLDDOWN(pi))
2972 continue;
2973 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2974 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2975 }
2976 }
2977
2978 /*
2979 * Has the route changed from the RIB's perspective? This is invoked only
2980 * if the route selection returns the same best route as earlier - to
2981 * determine if we need to update zebra or not.
2982 */
2983 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2984 {
2985 struct bgp_path_info *mpinfo;
2986
2987 /* If this is multipath, check all selected paths for any nexthop
2988 * change or attribute change. Some attribute changes (e.g., community)
2989 * aren't of relevance to the RIB, but we'll update zebra to ensure
2990 * we handle the case of BGP nexthop change. This is the behavior
2991 * when the best path has an attribute change anyway.
2992 */
2993 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2994 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2995 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2996 return true;
2997
2998 /*
2999 * If this is multipath, check all selected paths for any nexthop change
3000 */
3001 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
3002 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3003 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3004 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3005 return true;
3006 }
3007
3008 /* Nothing has changed from the RIB's perspective. */
3009 return false;
3010 }
3011
3012 struct bgp_process_queue {
3013 struct bgp *bgp;
3014 STAILQ_HEAD(, bgp_dest) pqueue;
3015 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3016 unsigned int flags;
3017 unsigned int queued;
3018 };
3019
3020 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3021 safi_t safi, struct bgp_dest *dest,
3022 struct bgp_path_info *new_select,
3023 struct bgp_path_info *old_select)
3024 {
3025 const struct prefix *p = bgp_dest_get_prefix(dest);
3026
3027 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3028 return;
3029
3030 if (advertise_type5_routes(bgp, afi) && new_select
3031 && is_route_injectable_into_evpn(new_select)) {
3032
3033 /* apply the route-map */
3034 if (bgp->adv_cmd_rmap[afi][safi].map) {
3035 route_map_result_t ret;
3036 struct bgp_path_info rmap_path;
3037 struct bgp_path_info_extra rmap_path_extra;
3038 struct attr dummy_attr;
3039
3040 dummy_attr = *new_select->attr;
3041
3042 /* Fill temp path_info */
3043 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3044 new_select, new_select->peer,
3045 &dummy_attr);
3046
3047 RESET_FLAG(dummy_attr.rmap_change_flags);
3048
3049 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3050 p, &rmap_path);
3051
3052 if (ret == RMAP_DENYMATCH) {
3053 bgp_attr_flush(&dummy_attr);
3054 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3055 safi);
3056 } else
3057 bgp_evpn_advertise_type5_route(
3058 bgp, p, &dummy_attr, afi, safi);
3059 } else {
3060 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3061 afi, safi);
3062 }
3063 } else if (advertise_type5_routes(bgp, afi) && old_select
3064 && is_route_injectable_into_evpn(old_select))
3065 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3066 }
3067
3068 /*
3069 * Utility to determine whether a particular path_info should use
3070 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3071 * in a path where we basically _know_ this is a BGP-LU route.
3072 */
3073 static bool bgp_lu_need_null_label(struct bgp *bgp,
3074 const struct bgp_path_info *new_select,
3075 afi_t afi, mpls_label_t *label)
3076 {
3077 /* Certain types get imp null; so do paths where the nexthop is
3078 * not labeled.
3079 */
3080 if (new_select->sub_type == BGP_ROUTE_STATIC
3081 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3082 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3083 goto need_null_label;
3084 else if (new_select->extra &&
3085 bgp_is_valid_label(&new_select->extra->label[0]))
3086 return false;
3087 need_null_label:
3088 if (label == NULL)
3089 return true;
3090 if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL))
3091 /* Disable PHP : explicit-null */
3092 *label = afi == AFI_IP ? MPLS_LABEL_IPV4_EXPLICIT_NULL
3093 : MPLS_LABEL_IPV6_EXPLICIT_NULL;
3094 else
3095 /* Enforced PHP popping: implicit-null */
3096 *label = MPLS_LABEL_IMPLICIT_NULL;
3097
3098 return true;
3099 }
3100
3101 /*
3102 * old_select = The old best path
3103 * new_select = the new best path
3104 *
3105 * if (!old_select && new_select)
3106 * We are sending new information on.
3107 *
3108 * if (old_select && new_select) {
3109 * if (new_select != old_select)
3110 * We have a new best path send a change
3111 * else
3112 * We've received a update with new attributes that needs
3113 * to be passed on.
3114 * }
3115 *
3116 * if (old_select && !new_select)
3117 * We have no eligible route that we can announce or the rn
3118 * is being removed.
3119 */
3120 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3121 afi_t afi, safi_t safi)
3122 {
3123 struct bgp_path_info *new_select;
3124 struct bgp_path_info *old_select;
3125 struct bgp_path_info_pair old_and_new;
3126 int debug = 0;
3127 mpls_label_t mpls_label_null;
3128
3129 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3130 if (dest)
3131 debug = bgp_debug_bestpath(dest);
3132 if (debug)
3133 zlog_debug(
3134 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3135 __func__, dest, bgp->name_pretty);
3136 return;
3137 }
3138 /* Is it end of initial update? (after startup) */
3139 if (!dest) {
3140 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3141 sizeof(bgp->update_delay_zebra_resume_time));
3142
3143 bgp->main_zebra_update_hold = 0;
3144 FOREACH_AFI_SAFI (afi, safi) {
3145 if (bgp_fibupd_safi(safi))
3146 bgp_zebra_announce_table(bgp, afi, safi);
3147 }
3148 bgp->main_peers_update_hold = 0;
3149
3150 bgp_start_routeadv(bgp);
3151 return;
3152 }
3153
3154 const struct prefix *p = bgp_dest_get_prefix(dest);
3155
3156 debug = bgp_debug_bestpath(dest);
3157 if (debug)
3158 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3159 dest, bgp->name_pretty, afi2str(afi),
3160 safi2str(safi));
3161
3162 /* The best path calculation for the route is deferred if
3163 * BGP_NODE_SELECT_DEFER is set
3164 */
3165 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3166 if (BGP_DEBUG(update, UPDATE_OUT))
3167 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3168 dest, bgp->name_pretty);
3169 return;
3170 }
3171
3172 /* Best path selection. */
3173 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3174 afi, safi);
3175 old_select = old_and_new.old;
3176 new_select = old_and_new.new;
3177
3178 /* Do we need to allocate or free labels?
3179 * Right now, since we only deal with per-prefix labels, it is not
3180 * necessary to do this upon changes to best path. Exceptions:
3181 * - label index has changed -> recalculate resulting label
3182 * - path_info sub_type changed -> switch to/from null label value
3183 * - no valid label (due to removed static label binding) -> get new one
3184 */
3185 if (bgp->allocate_mpls_labels[afi][safi]) {
3186 if (new_select) {
3187 if (!old_select
3188 || bgp_label_index_differs(new_select, old_select)
3189 || new_select->sub_type != old_select->sub_type
3190 || !bgp_is_valid_label(&dest->local_label)) {
3191 /* control label imposition for local routes,
3192 * aggregate and redistributed routes
3193 */
3194 mpls_label_null = MPLS_LABEL_IMPLICIT_NULL;
3195 if (bgp_lu_need_null_label(bgp, new_select, afi,
3196 &mpls_label_null)) {
3197 if (CHECK_FLAG(
3198 dest->flags,
3199 BGP_NODE_REGISTERED_FOR_LABEL)
3200 || CHECK_FLAG(
3201 dest->flags,
3202 BGP_NODE_LABEL_REQUESTED))
3203 bgp_unregister_for_label(dest);
3204 dest->local_label = mpls_lse_encode(
3205 mpls_label_null, 0, 0, 1);
3206 bgp_set_valid_label(&dest->local_label);
3207 } else
3208 bgp_register_for_label(dest,
3209 new_select);
3210 }
3211 } else if (CHECK_FLAG(dest->flags,
3212 BGP_NODE_REGISTERED_FOR_LABEL)
3213 || CHECK_FLAG(dest->flags,
3214 BGP_NODE_LABEL_REQUESTED)) {
3215 bgp_unregister_for_label(dest);
3216 }
3217 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3218 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3219 bgp_unregister_for_label(dest);
3220 }
3221
3222 if (debug)
3223 zlog_debug(
3224 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3225 __func__, dest, bgp->name_pretty, afi2str(afi),
3226 safi2str(safi), old_select, new_select);
3227
3228 /* If best route remains the same and this is not due to user-initiated
3229 * clear, see exactly what needs to be done.
3230 */
3231 if (old_select && old_select == new_select
3232 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3233 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3234 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3235 if (bgp_zebra_has_route_changed(old_select)) {
3236 #ifdef ENABLE_BGP_VNC
3237 vnc_import_bgp_add_route(bgp, p, old_select);
3238 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3239 #endif
3240 if (bgp_fibupd_safi(safi)
3241 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3242
3243 if (new_select->type == ZEBRA_ROUTE_BGP
3244 && (new_select->sub_type == BGP_ROUTE_NORMAL
3245 || new_select->sub_type
3246 == BGP_ROUTE_IMPORTED))
3247
3248 bgp_zebra_announce(dest, p, old_select,
3249 bgp, afi, safi);
3250 }
3251 }
3252
3253 /* If there is a change of interest to peers, reannounce the
3254 * route. */
3255 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3256 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3257 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3258 group_announce_route(bgp, afi, safi, dest, new_select);
3259
3260 /* unicast routes must also be annouced to
3261 * labeled-unicast update-groups */
3262 if (safi == SAFI_UNICAST)
3263 group_announce_route(bgp, afi,
3264 SAFI_LABELED_UNICAST, dest,
3265 new_select);
3266
3267 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3268 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3269 }
3270
3271 /* advertise/withdraw type-5 routes */
3272 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3273 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3274 bgp_process_evpn_route_injection(
3275 bgp, afi, safi, dest, old_select, old_select);
3276
3277 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3278 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3279 bgp_zebra_clear_route_change_flags(dest);
3280 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3281 return;
3282 }
3283
3284 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3285 */
3286 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3287
3288 /* bestpath has changed; bump version */
3289 if (old_select || new_select) {
3290 bgp_bump_version(dest);
3291
3292 if (!bgp->t_rmap_def_originate_eval) {
3293 bgp_lock(bgp);
3294 event_add_timer(
3295 bm->master,
3296 update_group_refresh_default_originate_route_map,
3297 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3298 &bgp->t_rmap_def_originate_eval);
3299 }
3300 }
3301
3302 if (old_select)
3303 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3304 if (new_select) {
3305 if (debug)
3306 zlog_debug("%s: setting SELECTED flag", __func__);
3307 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3308 bgp_path_info_unset_flag(dest, new_select,
3309 BGP_PATH_ATTR_CHANGED);
3310 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3311 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3312 }
3313
3314 #ifdef ENABLE_BGP_VNC
3315 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3316 if (old_select != new_select) {
3317 if (old_select) {
3318 vnc_import_bgp_exterior_del_route(bgp, p,
3319 old_select);
3320 vnc_import_bgp_del_route(bgp, p, old_select);
3321 }
3322 if (new_select) {
3323 vnc_import_bgp_exterior_add_route(bgp, p,
3324 new_select);
3325 vnc_import_bgp_add_route(bgp, p, new_select);
3326 }
3327 }
3328 }
3329 #endif
3330
3331 group_announce_route(bgp, afi, safi, dest, new_select);
3332
3333 /* unicast routes must also be annouced to labeled-unicast update-groups
3334 */
3335 if (safi == SAFI_UNICAST)
3336 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3337 new_select);
3338
3339 /* FIB update. */
3340 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3341 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3342
3343 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3344 && (new_select->sub_type == BGP_ROUTE_NORMAL
3345 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3346 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3347
3348 /* if this is an evpn imported type-5 prefix,
3349 * we need to withdraw the route first to clear
3350 * the nh neigh and the RMAC entry.
3351 */
3352 if (old_select &&
3353 is_route_parent_evpn(old_select))
3354 bgp_zebra_withdraw(p, old_select, bgp, safi);
3355
3356 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3357 } else {
3358 /* Withdraw the route from the kernel. */
3359 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3360 && (old_select->sub_type == BGP_ROUTE_NORMAL
3361 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3362 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3363
3364 bgp_zebra_withdraw(p, old_select, bgp, safi);
3365 }
3366 }
3367
3368 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3369 old_select);
3370
3371 /* Clear any route change flags. */
3372 bgp_zebra_clear_route_change_flags(dest);
3373
3374 /* Reap old select bgp_path_info, if it has been removed */
3375 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3376 bgp_path_info_reap(dest, old_select);
3377
3378 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3379 return;
3380 }
3381
3382 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3383 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3384 {
3385 struct bgp_dest *dest;
3386 int cnt = 0;
3387 struct afi_safi_info *thread_info;
3388
3389 if (bgp->gr_info[afi][safi].t_route_select) {
3390 struct event *t = bgp->gr_info[afi][safi].t_route_select;
3391
3392 thread_info = EVENT_ARG(t);
3393 XFREE(MTYPE_TMP, thread_info);
3394 EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
3395 }
3396
3397 if (BGP_DEBUG(update, UPDATE_OUT)) {
3398 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3399 get_afi_safi_str(afi, safi, false),
3400 bgp->gr_info[afi][safi].gr_deferred);
3401 }
3402
3403 /* Process the route list */
3404 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3405 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3406 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3407 dest = bgp_route_next(dest)) {
3408 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3409 continue;
3410
3411 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3412 bgp->gr_info[afi][safi].gr_deferred--;
3413 bgp_process_main_one(bgp, dest, afi, safi);
3414 cnt++;
3415 }
3416 /* If iteration stopped before the entire table was traversed then the
3417 * node needs to be unlocked.
3418 */
3419 if (dest) {
3420 bgp_dest_unlock_node(dest);
3421 dest = NULL;
3422 }
3423
3424 /* Send EOR message when all routes are processed */
3425 if (!bgp->gr_info[afi][safi].gr_deferred) {
3426 bgp_send_delayed_eor(bgp);
3427 /* Send route processing complete message to RIB */
3428 bgp_zebra_update(bgp, afi, safi,
3429 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3430 return;
3431 }
3432
3433 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3434
3435 thread_info->afi = afi;
3436 thread_info->safi = safi;
3437 thread_info->bgp = bgp;
3438
3439 /* If there are more routes to be processed, start the
3440 * selection timer
3441 */
3442 event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3443 BGP_ROUTE_SELECT_DELAY,
3444 &bgp->gr_info[afi][safi].t_route_select);
3445 }
3446
3447 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3448 {
3449 struct bgp_process_queue *pqnode = data;
3450 struct bgp *bgp = pqnode->bgp;
3451 struct bgp_table *table;
3452 struct bgp_dest *dest;
3453
3454 /* eoiu marker */
3455 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3456 bgp_process_main_one(bgp, NULL, 0, 0);
3457 /* should always have dedicated wq call */
3458 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3459 return WQ_SUCCESS;
3460 }
3461
3462 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3463 dest = STAILQ_FIRST(&pqnode->pqueue);
3464 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3465 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3466 table = bgp_dest_table(dest);
3467 /* note, new DESTs may be added as part of processing */
3468 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3469
3470 bgp_dest_unlock_node(dest);
3471 bgp_table_unlock(table);
3472 }
3473
3474 return WQ_SUCCESS;
3475 }
3476
3477 static void bgp_processq_del(struct work_queue *wq, void *data)
3478 {
3479 struct bgp_process_queue *pqnode = data;
3480
3481 bgp_unlock(pqnode->bgp);
3482
3483 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3484 }
3485
3486 void bgp_process_queue_init(struct bgp *bgp)
3487 {
3488 if (!bgp->process_queue) {
3489 char name[BUFSIZ];
3490
3491 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3492 bgp->process_queue = work_queue_new(bm->master, name);
3493 }
3494
3495 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3496 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3497 bgp->process_queue->spec.max_retries = 0;
3498 bgp->process_queue->spec.hold = 50;
3499 /* Use a higher yield value of 50ms for main queue processing */
3500 bgp->process_queue->spec.yield = 50 * 1000L;
3501 }
3502
3503 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3504 {
3505 struct bgp_process_queue *pqnode;
3506
3507 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3508 sizeof(struct bgp_process_queue));
3509
3510 /* unlocked in bgp_processq_del */
3511 pqnode->bgp = bgp_lock(bgp);
3512 STAILQ_INIT(&pqnode->pqueue);
3513
3514 return pqnode;
3515 }
3516
3517 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3518 {
3519 #define ARBITRARY_PROCESS_QLEN 10000
3520 struct work_queue *wq = bgp->process_queue;
3521 struct bgp_process_queue *pqnode;
3522 int pqnode_reuse = 0;
3523
3524 /* already scheduled for processing? */
3525 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3526 return;
3527
3528 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3529 * the workqueue
3530 */
3531 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3532 if (BGP_DEBUG(update, UPDATE_OUT))
3533 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3534 dest);
3535 return;
3536 }
3537
3538 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3539 if (BGP_DEBUG(update, UPDATE_OUT))
3540 zlog_debug(
3541 "Soft reconfigure table in progress for route %p",
3542 dest);
3543 return;
3544 }
3545
3546 if (wq == NULL)
3547 return;
3548
3549 /* Add route nodes to an existing work queue item until reaching the
3550 limit only if is from the same BGP view and it's not an EOIU marker
3551 */
3552 if (work_queue_item_count(wq)) {
3553 struct work_queue_item *item = work_queue_last_item(wq);
3554 pqnode = item->data;
3555
3556 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3557 || pqnode->bgp != bgp
3558 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3559 pqnode = bgp_processq_alloc(bgp);
3560 else
3561 pqnode_reuse = 1;
3562 } else
3563 pqnode = bgp_processq_alloc(bgp);
3564 /* all unlocked in bgp_process_wq */
3565 bgp_table_lock(bgp_dest_table(dest));
3566
3567 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3568 bgp_dest_lock_node(dest);
3569
3570 /* can't be enqueued twice */
3571 assert(STAILQ_NEXT(dest, pq) == NULL);
3572 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3573 pqnode->queued++;
3574
3575 if (!pqnode_reuse)
3576 work_queue_add(wq, pqnode);
3577
3578 return;
3579 }
3580
3581 void bgp_add_eoiu_mark(struct bgp *bgp)
3582 {
3583 struct bgp_process_queue *pqnode;
3584
3585 if (bgp->process_queue == NULL)
3586 return;
3587
3588 pqnode = bgp_processq_alloc(bgp);
3589
3590 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3591 work_queue_add(bgp->process_queue, pqnode);
3592 }
3593
3594 static void bgp_maximum_prefix_restart_timer(struct event *thread)
3595 {
3596 struct peer *peer;
3597
3598 peer = EVENT_ARG(thread);
3599 peer->t_pmax_restart = NULL;
3600
3601 if (bgp_debug_neighbor_events(peer))
3602 zlog_debug(
3603 "%s Maximum-prefix restart timer expired, restore peering",
3604 peer->host);
3605
3606 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3607 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3608 }
3609
3610 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3611 safi_t safi)
3612 {
3613 uint32_t count = 0;
3614 bool filtered = false;
3615 struct bgp_dest *dest;
3616 struct bgp_adj_in *ain;
3617 struct attr attr = {};
3618 struct bgp_table *table = peer->bgp->rib[afi][safi];
3619
3620 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3621 for (ain = dest->adj_in; ain; ain = ain->next) {
3622 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3623
3624 attr = *ain->attr;
3625
3626 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3627 == FILTER_DENY)
3628 filtered = true;
3629
3630 if (bgp_input_modifier(
3631 peer, rn_p, &attr, afi, safi,
3632 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3633 NULL, 0, NULL)
3634 == RMAP_DENY)
3635 filtered = true;
3636
3637 if (filtered)
3638 count++;
3639
3640 bgp_attr_flush(&attr);
3641 }
3642 }
3643
3644 return count;
3645 }
3646
3647 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3648 int always)
3649 {
3650 iana_afi_t pkt_afi;
3651 iana_safi_t pkt_safi;
3652 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3653 PEER_FLAG_MAX_PREFIX_FORCE))
3654 ? bgp_filtered_routes_count(peer, afi, safi)
3655 + peer->pcount[afi][safi]
3656 : peer->pcount[afi][safi];
3657
3658 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3659 return false;
3660
3661 if (pcount > peer->pmax[afi][safi]) {
3662 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3663 PEER_STATUS_PREFIX_LIMIT)
3664 && !always)
3665 return false;
3666
3667 zlog_info(
3668 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3669 get_afi_safi_str(afi, safi, false), peer, pcount,
3670 peer->pmax[afi][safi]);
3671 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3672
3673 if (CHECK_FLAG(peer->af_flags[afi][safi],
3674 PEER_FLAG_MAX_PREFIX_WARNING))
3675 return false;
3676
3677 /* Convert AFI, SAFI to values for packet. */
3678 pkt_afi = afi_int2iana(afi);
3679 pkt_safi = safi_int2iana(safi);
3680 {
3681 uint8_t ndata[7];
3682
3683 ndata[0] = (pkt_afi >> 8);
3684 ndata[1] = pkt_afi;
3685 ndata[2] = pkt_safi;
3686 ndata[3] = (peer->pmax[afi][safi] >> 24);
3687 ndata[4] = (peer->pmax[afi][safi] >> 16);
3688 ndata[5] = (peer->pmax[afi][safi] >> 8);
3689 ndata[6] = (peer->pmax[afi][safi]);
3690
3691 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3692 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3693 BGP_NOTIFY_CEASE_MAX_PREFIX,
3694 ndata, 7);
3695 }
3696
3697 /* Dynamic peers will just close their connection. */
3698 if (peer_dynamic_neighbor(peer))
3699 return true;
3700
3701 /* restart timer start */
3702 if (peer->pmax_restart[afi][safi]) {
3703 peer->v_pmax_restart =
3704 peer->pmax_restart[afi][safi] * 60;
3705
3706 if (bgp_debug_neighbor_events(peer))
3707 zlog_debug(
3708 "%pBP Maximum-prefix restart timer started for %d secs",
3709 peer, peer->v_pmax_restart);
3710
3711 BGP_TIMER_ON(peer->t_pmax_restart,
3712 bgp_maximum_prefix_restart_timer,
3713 peer->v_pmax_restart);
3714 }
3715
3716 return true;
3717 } else
3718 UNSET_FLAG(peer->af_sflags[afi][safi],
3719 PEER_STATUS_PREFIX_LIMIT);
3720
3721 if (pcount
3722 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3723 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3724 PEER_STATUS_PREFIX_THRESHOLD)
3725 && !always)
3726 return false;
3727
3728 zlog_info(
3729 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3730 get_afi_safi_str(afi, safi, false), peer, pcount,
3731 peer->pmax[afi][safi]);
3732 SET_FLAG(peer->af_sflags[afi][safi],
3733 PEER_STATUS_PREFIX_THRESHOLD);
3734 } else
3735 UNSET_FLAG(peer->af_sflags[afi][safi],
3736 PEER_STATUS_PREFIX_THRESHOLD);
3737 return false;
3738 }
3739
3740 /* Unconditionally remove the route from the RIB, without taking
3741 * damping into consideration (eg, because the session went down)
3742 */
3743 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3744 struct peer *peer, afi_t afi, safi_t safi)
3745 {
3746
3747 struct bgp *bgp = NULL;
3748 bool delete_route = false;
3749
3750 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3751 safi);
3752
3753 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3754 bgp_path_info_delete(dest, pi); /* keep historical info */
3755
3756 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3757 * flag
3758 */
3759 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3760 delete_route = true;
3761 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3762 delete_route = true;
3763 if (delete_route) {
3764 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3765 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3766 bgp = pi->peer->bgp;
3767 bgp->gr_info[afi][safi].gr_deferred--;
3768 }
3769 }
3770 }
3771
3772 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3773 bgp_process(peer->bgp, dest, afi, safi);
3774 }
3775
3776 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3777 struct peer *peer, afi_t afi, safi_t safi,
3778 struct prefix_rd *prd)
3779 {
3780 const struct prefix *p = bgp_dest_get_prefix(dest);
3781
3782 /* apply dampening, if result is suppressed, we'll be retaining
3783 * the bgp_path_info in the RIB for historical reference.
3784 */
3785 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3786 && peer->sort == BGP_PEER_EBGP)
3787 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3788 == BGP_DAMP_SUPPRESSED) {
3789 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3790 safi);
3791 return;
3792 }
3793
3794 #ifdef ENABLE_BGP_VNC
3795 if (safi == SAFI_MPLS_VPN) {
3796 struct bgp_dest *pdest = NULL;
3797 struct bgp_table *table = NULL;
3798
3799 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3800 (struct prefix *)prd);
3801 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3802 table = bgp_dest_get_bgp_table_info(pdest);
3803
3804 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3805 peer->bgp, prd, table, p, pi);
3806 }
3807 bgp_dest_unlock_node(pdest);
3808 }
3809 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3810 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3811
3812 vnc_import_bgp_del_route(peer->bgp, p, pi);
3813 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3814 }
3815 }
3816 #endif
3817
3818 /* If this is an EVPN route, process for un-import. */
3819 if (safi == SAFI_EVPN)
3820 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3821
3822 bgp_rib_remove(dest, pi, peer, afi, safi);
3823 }
3824
3825 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3826 struct peer *peer, struct attr *attr,
3827 struct bgp_dest *dest)
3828 {
3829 struct bgp_path_info *new;
3830
3831 /* Make new BGP info. */
3832 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3833 new->type = type;
3834 new->instance = instance;
3835 new->sub_type = sub_type;
3836 new->peer = peer;
3837 new->attr = attr;
3838 new->uptime = monotime(NULL);
3839 new->net = dest;
3840 return new;
3841 }
3842
3843 /* Check if received nexthop is valid or not. */
3844 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3845 uint8_t type, uint8_t stype, struct attr *attr,
3846 struct bgp_dest *dest)
3847 {
3848 bool ret = false;
3849 bool is_bgp_static_route =
3850 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3851 : false;
3852
3853 /* If `bgp allow-martian-nexthop` is turned on, return next-hop
3854 * as good.
3855 */
3856 if (bgp->allow_martian)
3857 return 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 void 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 = NULL;
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 const struct prefix *bgp_nht_param_prefix;
4048
4049 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4050 if (orig_safi == SAFI_LABELED_UNICAST)
4051 safi = SAFI_UNICAST;
4052
4053 memset(&new_attr, 0, sizeof(new_attr));
4054 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4055 new_attr.label = MPLS_INVALID_LABEL;
4056
4057 bgp = peer->bgp;
4058 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4059 /* TODO: Check to see if we can get rid of "is_valid_label" */
4060 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4061 has_valid_label = (num_labels > 0) ? 1 : 0;
4062 else
4063 has_valid_label = bgp_is_valid_label(label);
4064
4065 if (has_valid_label)
4066 assert(label != NULL);
4067
4068 /* Update overlay index of the attribute */
4069 if (afi == AFI_L2VPN && evpn)
4070 memcpy(&attr->evpn_overlay, evpn,
4071 sizeof(struct bgp_route_evpn));
4072
4073 /* When peer's soft reconfiguration enabled. Record input packet in
4074 Adj-RIBs-In. */
4075 if (!soft_reconfig
4076 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4077 && peer != bgp->peer_self)
4078 bgp_adj_in_set(dest, peer, attr, addpath_id);
4079
4080 /* Update permitted loop count */
4081 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4082 allowas_in = peer->allowas_in[afi][safi];
4083
4084 /* Check previously received route. */
4085 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4086 if (pi->peer == peer && pi->type == type
4087 && pi->sub_type == sub_type
4088 && pi->addpath_rx_id == addpath_id)
4089 break;
4090
4091 /* AS path local-as loop check. */
4092 if (peer->change_local_as) {
4093 if (allowas_in)
4094 aspath_loop_count = allowas_in;
4095 else if (!CHECK_FLAG(peer->flags,
4096 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4097 aspath_loop_count = 1;
4098
4099 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4100 > aspath_loop_count) {
4101 peer->stat_pfx_aspath_loop++;
4102 reason = "as-path contains our own AS;";
4103 goto filtered;
4104 }
4105 }
4106
4107 /* If the peer is configured for "allowas-in origin" and the last ASN in
4108 * the
4109 * as-path is our ASN then we do not need to call aspath_loop_check
4110 */
4111 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4112 if (aspath_get_last_as(attr->aspath) == bgp->as)
4113 do_loop_check = 0;
4114
4115 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4116 bgp_nht_param_prefix = NULL;
4117 else
4118 bgp_nht_param_prefix = p;
4119
4120 /* AS path loop check. */
4121 if (do_loop_check) {
4122 if (aspath_loop_check(attr->aspath, bgp->as) >
4123 peer->allowas_in[afi][safi]) {
4124 peer->stat_pfx_aspath_loop++;
4125 reason = "as-path contains our own AS;";
4126 goto filtered;
4127 }
4128 }
4129
4130 /* If we're a CONFED we need to loop check the CONFED ID too */
4131 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4132 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4133 peer->allowas_in[afi][safi]) {
4134 peer->stat_pfx_aspath_loop++;
4135 reason = "as-path contains our own confed AS;";
4136 goto filtered;
4137 }
4138
4139 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4140 * enabled, then take care of that too.
4141 */
4142 bool accept_own = false;
4143
4144 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4145 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4146 accept_own =
4147 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4148 if (!accept_own) {
4149 peer->stat_pfx_originator_loop++;
4150 reason = "originator is us;";
4151 goto filtered;
4152 }
4153 }
4154
4155 /* Route reflector cluster ID check. */
4156 if (bgp_cluster_filter(peer, attr)) {
4157 peer->stat_pfx_cluster_loop++;
4158 reason = "reflected from the same cluster;";
4159 goto filtered;
4160 }
4161
4162 /* Apply incoming filter. */
4163 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4164 peer->stat_pfx_filter++;
4165 reason = "filter;";
4166 goto filtered;
4167 }
4168
4169 /* RFC 8212 to prevent route leaks.
4170 * This specification intends to improve this situation by requiring the
4171 * explicit configuration of both BGP Import and Export Policies for any
4172 * External BGP (EBGP) session such as customers, peers, or
4173 * confederation boundaries for all enabled address families. Through
4174 * codification of the aforementioned requirement, operators will
4175 * benefit from consistent behavior across different BGP
4176 * implementations.
4177 */
4178 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4179 if (!bgp_inbound_policy_exists(peer,
4180 &peer->filter[afi][safi])) {
4181 reason = "inbound policy missing";
4182 if (monotime_since(&bgp->ebgprequirespolicywarning,
4183 NULL) > FIFTEENMINUTE2USEC ||
4184 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4185 zlog_warn(
4186 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4187 monotime(&bgp->ebgprequirespolicywarning);
4188 }
4189 goto filtered;
4190 }
4191
4192 /* draft-ietf-idr-deprecate-as-set-confed-set
4193 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4194 * Eventually, This document (if approved) updates RFC 4271
4195 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4196 * and obsoletes RFC 6472.
4197 */
4198 if (peer->bgp->reject_as_sets)
4199 if (aspath_check_as_sets(attr->aspath)) {
4200 reason =
4201 "as-path contains AS_SET or AS_CONFED_SET type;";
4202 goto filtered;
4203 }
4204
4205 new_attr = *attr;
4206
4207 /* Apply incoming route-map.
4208 * NB: new_attr may now contain newly allocated values from route-map
4209 * "set"
4210 * commands, so we need bgp_attr_flush in the error paths, until we
4211 * intern
4212 * the attr (which takes over the memory references) */
4213 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4214 num_labels, dest)
4215 == RMAP_DENY) {
4216 peer->stat_pfx_filter++;
4217 reason = "route-map;";
4218 bgp_attr_flush(&new_attr);
4219 goto filtered;
4220 }
4221
4222 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4223 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4224 /* remove from RIB previous entry */
4225 bgp_zebra_withdraw(p, pi, bgp, safi);
4226 }
4227
4228 if (peer->sort == BGP_PEER_EBGP) {
4229
4230 /* rfc7999:
4231 * A BGP speaker receiving an announcement tagged with the
4232 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4233 * NO_EXPORT community as defined in RFC1997, or a
4234 * similar community, to prevent propagation of the
4235 * prefix outside the local AS. The community to prevent
4236 * propagation SHOULD be chosen according to the operator's
4237 * routing policy.
4238 */
4239 if (bgp_attr_get_community(&new_attr) &&
4240 community_include(bgp_attr_get_community(&new_attr),
4241 COMMUNITY_BLACKHOLE))
4242 bgp_attr_add_no_export_community(&new_attr);
4243
4244 /* If we receive the graceful-shutdown community from an eBGP
4245 * peer we must lower local-preference */
4246 if (bgp_attr_get_community(&new_attr) &&
4247 community_include(bgp_attr_get_community(&new_attr),
4248 COMMUNITY_GSHUT)) {
4249 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4250 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4251
4252 /* If graceful-shutdown is configured globally or
4253 * per neighbor, then add the GSHUT community to
4254 * all paths received from eBGP peers. */
4255 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4256 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4257 bgp_attr_add_gshut_community(&new_attr);
4258 }
4259
4260 /* next hop check. */
4261 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4262 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4263 &new_attr, dest)) {
4264 peer->stat_pfx_nh_invalid++;
4265 reason = "martian or self next-hop;";
4266 bgp_attr_flush(&new_attr);
4267 goto filtered;
4268 }
4269
4270 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4271 peer->stat_pfx_nh_invalid++;
4272 reason = "self mac;";
4273 bgp_attr_flush(&new_attr);
4274 goto filtered;
4275 }
4276
4277 if (bgp_check_role_applicability(afi, safi) &&
4278 bgp_otc_filter(peer, &new_attr)) {
4279 reason = "failing otc validation";
4280 bgp_attr_flush(&new_attr);
4281 goto filtered;
4282 }
4283
4284 /* If neighbor soo is configured, tag all incoming routes with
4285 * this SoO tag and then filter out advertisements in
4286 * subgroup_announce_check() if it matches the configured SoO
4287 * on the other peer.
4288 */
4289 if (peer->soo[afi][safi]) {
4290 struct ecommunity *old_ecomm =
4291 bgp_attr_get_ecommunity(&new_attr);
4292 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4293 struct ecommunity *new_ecomm;
4294
4295 if (old_ecomm) {
4296 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4297 ecomm_soo);
4298
4299 if (!old_ecomm->refcnt)
4300 ecommunity_free(&old_ecomm);
4301 } else {
4302 new_ecomm = ecommunity_dup(ecomm_soo);
4303 }
4304
4305 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4306 }
4307
4308 attr_new = bgp_attr_intern(&new_attr);
4309
4310 /* If the update is implicit withdraw. */
4311 if (pi) {
4312 pi->uptime = monotime(NULL);
4313 same_attr = attrhash_cmp(pi->attr, attr_new);
4314
4315 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4316
4317 /* Same attribute comes in. */
4318 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4319 && same_attr
4320 && (!has_valid_label
4321 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4322 num_labels * sizeof(mpls_label_t))
4323 == 0)) {
4324 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4325 BGP_CONFIG_DAMPENING)
4326 && peer->sort == BGP_PEER_EBGP
4327 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4328 if (bgp_debug_update(peer, p, NULL, 1)) {
4329 bgp_debug_rdpfxpath2str(
4330 afi, safi, prd, p, label,
4331 num_labels, addpath_id ? 1 : 0,
4332 addpath_id, evpn, pfx_buf,
4333 sizeof(pfx_buf));
4334 zlog_debug("%pBP rcvd %s", peer,
4335 pfx_buf);
4336 }
4337
4338 if (bgp_damp_update(pi, dest, afi, safi)
4339 != BGP_DAMP_SUPPRESSED) {
4340 bgp_aggregate_increment(bgp, p, pi, afi,
4341 safi);
4342 bgp_process(bgp, dest, afi, safi);
4343 }
4344 } else /* Duplicate - odd */
4345 {
4346 if (bgp_debug_update(peer, p, NULL, 1)) {
4347 if (!peer->rcvd_attr_printed) {
4348 zlog_debug(
4349 "%pBP rcvd UPDATE w/ attr: %s",
4350 peer,
4351 peer->rcvd_attr_str);
4352 peer->rcvd_attr_printed = 1;
4353 }
4354
4355 bgp_debug_rdpfxpath2str(
4356 afi, safi, prd, p, label,
4357 num_labels, addpath_id ? 1 : 0,
4358 addpath_id, evpn, pfx_buf,
4359 sizeof(pfx_buf));
4360 zlog_debug(
4361 "%pBP rcvd %s...duplicate ignored",
4362 peer, pfx_buf);
4363 }
4364
4365 /* graceful restart STALE flag unset. */
4366 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4367 bgp_path_info_unset_flag(
4368 dest, pi, BGP_PATH_STALE);
4369 bgp_dest_set_defer_flag(dest, false);
4370 bgp_process(bgp, dest, afi, safi);
4371 }
4372 }
4373
4374 bgp_dest_unlock_node(dest);
4375 bgp_attr_unintern(&attr_new);
4376
4377 return;
4378 }
4379
4380 /* Withdraw/Announce before we fully processed the withdraw */
4381 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4382 if (bgp_debug_update(peer, p, NULL, 1)) {
4383 bgp_debug_rdpfxpath2str(
4384 afi, safi, prd, p, label, num_labels,
4385 addpath_id ? 1 : 0, addpath_id, evpn,
4386 pfx_buf, sizeof(pfx_buf));
4387 zlog_debug(
4388 "%pBP rcvd %s, flapped quicker than processing",
4389 peer, pfx_buf);
4390 }
4391
4392 bgp_path_info_restore(dest, pi);
4393
4394 /*
4395 * If the BGP_PATH_REMOVED flag is set, then EVPN
4396 * routes would have been unimported already when a
4397 * prior BGP withdraw processing happened. Such routes
4398 * need to be imported again, so flag accordingly.
4399 */
4400 force_evpn_import = true;
4401 } else {
4402 /* implicit withdraw, decrement aggregate and pcount
4403 * here. only if update is accepted, they'll increment
4404 * below.
4405 */
4406 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4407 }
4408
4409 /* Received Logging. */
4410 if (bgp_debug_update(peer, p, NULL, 1)) {
4411 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4412 num_labels, addpath_id ? 1 : 0,
4413 addpath_id, evpn, pfx_buf,
4414 sizeof(pfx_buf));
4415 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4416 }
4417
4418 /* graceful restart STALE flag unset. */
4419 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4420 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4421 bgp_dest_set_defer_flag(dest, false);
4422 }
4423
4424 /* The attribute is changed. */
4425 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4426
4427 /* Update bgp route dampening information. */
4428 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4429 && peer->sort == BGP_PEER_EBGP) {
4430 /* This is implicit withdraw so we should update
4431 dampening
4432 information. */
4433 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4434 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4435 }
4436 #ifdef ENABLE_BGP_VNC
4437 if (safi == SAFI_MPLS_VPN) {
4438 struct bgp_dest *pdest = NULL;
4439 struct bgp_table *table = NULL;
4440
4441 pdest = bgp_node_get(bgp->rib[afi][safi],
4442 (struct prefix *)prd);
4443 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4444 table = bgp_dest_get_bgp_table_info(pdest);
4445
4446 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4447 bgp, prd, table, p, pi);
4448 }
4449 bgp_dest_unlock_node(pdest);
4450 }
4451 if ((afi == AFI_IP || afi == AFI_IP6)
4452 && (safi == SAFI_UNICAST)) {
4453 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4454 /*
4455 * Implicit withdraw case.
4456 */
4457 ++vnc_implicit_withdraw;
4458 vnc_import_bgp_del_route(bgp, p, pi);
4459 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4460 }
4461 }
4462 #endif
4463
4464 /* Special handling for EVPN update of an existing route. If the
4465 * extended community attribute has changed, we need to
4466 * un-import
4467 * the route using its existing extended community. It will be
4468 * subsequently processed for import with the new extended
4469 * community.
4470 */
4471 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4472 && !same_attr) {
4473 if ((pi->attr->flag
4474 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4475 && (attr_new->flag
4476 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4477 int cmp;
4478
4479 cmp = ecommunity_cmp(
4480 bgp_attr_get_ecommunity(pi->attr),
4481 bgp_attr_get_ecommunity(attr_new));
4482 if (!cmp) {
4483 if (bgp_debug_update(peer, p, NULL, 1))
4484 zlog_debug(
4485 "Change in EXT-COMM, existing %s new %s",
4486 ecommunity_str(
4487 bgp_attr_get_ecommunity(
4488 pi->attr)),
4489 ecommunity_str(
4490 bgp_attr_get_ecommunity(
4491 attr_new)));
4492 if (safi == SAFI_EVPN)
4493 bgp_evpn_unimport_route(
4494 bgp, afi, safi, p, pi);
4495 else /* SAFI_MPLS_VPN */
4496 vpn_leak_to_vrf_withdraw(pi);
4497 }
4498 }
4499 }
4500
4501 /* Update to new attribute. */
4502 bgp_attr_unintern(&pi->attr);
4503 pi->attr = attr_new;
4504
4505 /* Update MPLS label */
4506 if (has_valid_label) {
4507 extra = bgp_path_info_extra_get(pi);
4508 if (extra->label != label) {
4509 memcpy(&extra->label, label,
4510 num_labels * sizeof(mpls_label_t));
4511 extra->num_labels = num_labels;
4512 }
4513 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4514 bgp_set_valid_label(&extra->label[0]);
4515 }
4516
4517 /* Update SRv6 SID */
4518 if (attr->srv6_l3vpn) {
4519 extra = bgp_path_info_extra_get(pi);
4520 if (sid_diff(&extra->sid[0].sid,
4521 &attr->srv6_l3vpn->sid)) {
4522 sid_copy(&extra->sid[0].sid,
4523 &attr->srv6_l3vpn->sid);
4524 extra->num_sids = 1;
4525
4526 extra->sid[0].loc_block_len = 0;
4527 extra->sid[0].loc_node_len = 0;
4528 extra->sid[0].func_len = 0;
4529 extra->sid[0].arg_len = 0;
4530 extra->sid[0].transposition_len = 0;
4531 extra->sid[0].transposition_offset = 0;
4532
4533 if (attr->srv6_l3vpn->loc_block_len != 0) {
4534 extra->sid[0].loc_block_len =
4535 attr->srv6_l3vpn->loc_block_len;
4536 extra->sid[0].loc_node_len =
4537 attr->srv6_l3vpn->loc_node_len;
4538 extra->sid[0].func_len =
4539 attr->srv6_l3vpn->func_len;
4540 extra->sid[0].arg_len =
4541 attr->srv6_l3vpn->arg_len;
4542 extra->sid[0].transposition_len =
4543 attr->srv6_l3vpn
4544 ->transposition_len;
4545 extra->sid[0].transposition_offset =
4546 attr->srv6_l3vpn
4547 ->transposition_offset;
4548 }
4549 }
4550 } else if (attr->srv6_vpn) {
4551 extra = bgp_path_info_extra_get(pi);
4552 if (sid_diff(&extra->sid[0].sid,
4553 &attr->srv6_vpn->sid)) {
4554 sid_copy(&extra->sid[0].sid,
4555 &attr->srv6_vpn->sid);
4556 extra->num_sids = 1;
4557 }
4558 }
4559
4560 #ifdef ENABLE_BGP_VNC
4561 if ((afi == AFI_IP || afi == AFI_IP6)
4562 && (safi == SAFI_UNICAST)) {
4563 if (vnc_implicit_withdraw) {
4564 /*
4565 * Add back the route with its new attributes
4566 * (e.g., nexthop).
4567 * The route is still selected, until the route
4568 * selection
4569 * queued by bgp_process actually runs. We have
4570 * to make this
4571 * update to the VNC side immediately to avoid
4572 * racing against
4573 * configuration changes (e.g., route-map
4574 * changes) which
4575 * trigger re-importation of the entire RIB.
4576 */
4577 vnc_import_bgp_add_route(bgp, p, pi);
4578 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4579 }
4580 }
4581 #endif
4582
4583 /* Update bgp route dampening information. */
4584 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4585 && peer->sort == BGP_PEER_EBGP) {
4586 /* Now we do normal update dampening. */
4587 ret = bgp_damp_update(pi, dest, afi, safi);
4588 if (ret == BGP_DAMP_SUPPRESSED) {
4589 bgp_dest_unlock_node(dest);
4590 return;
4591 }
4592 }
4593
4594 /* Nexthop reachability check - for unicast and
4595 * labeled-unicast.. */
4596 if (((afi == AFI_IP || afi == AFI_IP6)
4597 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4598 || (safi == SAFI_EVPN &&
4599 bgp_evpn_is_prefix_nht_supported(p))) {
4600 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4601 && peer->ttl == BGP_DEFAULT_TTL
4602 && !CHECK_FLAG(peer->flags,
4603 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4604 && !CHECK_FLAG(bgp->flags,
4605 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4606 connected = 1;
4607 else
4608 connected = 0;
4609
4610 struct bgp *bgp_nexthop = bgp;
4611
4612 if (pi->extra && pi->extra->bgp_orig)
4613 bgp_nexthop = pi->extra->bgp_orig;
4614
4615 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4616
4617 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4618 safi, pi, NULL, connected,
4619 bgp_nht_param_prefix) ||
4620 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4621 bgp_path_info_set_flag(dest, pi,
4622 BGP_PATH_VALID);
4623 else {
4624 if (BGP_DEBUG(nht, NHT)) {
4625 zlog_debug("%s(%pI4): NH unresolved",
4626 __func__,
4627 (in_addr_t *)&attr_new->nexthop);
4628 }
4629 bgp_path_info_unset_flag(dest, pi,
4630 BGP_PATH_VALID);
4631 }
4632 } else {
4633 if (accept_own)
4634 bgp_path_info_set_flag(dest, pi,
4635 BGP_PATH_ACCEPT_OWN);
4636
4637 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4638 }
4639
4640 #ifdef ENABLE_BGP_VNC
4641 if (safi == SAFI_MPLS_VPN) {
4642 struct bgp_dest *pdest = NULL;
4643 struct bgp_table *table = NULL;
4644
4645 pdest = bgp_node_get(bgp->rib[afi][safi],
4646 (struct prefix *)prd);
4647 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4648 table = bgp_dest_get_bgp_table_info(pdest);
4649
4650 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4651 bgp, prd, table, p, pi);
4652 }
4653 bgp_dest_unlock_node(pdest);
4654 }
4655 #endif
4656
4657 /* If this is an EVPN route and some attribute has changed,
4658 * or we are explicitly told to perform a route import, process
4659 * route for import. If the extended community has changed, we
4660 * would
4661 * have done the un-import earlier and the import would result
4662 * in the
4663 * route getting injected into appropriate L2 VNIs. If it is
4664 * just
4665 * some other attribute change, the import will result in
4666 * updating
4667 * the attributes for the route in the VNI(s).
4668 */
4669 if (safi == SAFI_EVPN &&
4670 (!same_attr || force_evpn_import) &&
4671 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4672 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4673
4674 /* Process change. */
4675 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4676
4677 bgp_process(bgp, dest, afi, safi);
4678 bgp_dest_unlock_node(dest);
4679
4680 if (SAFI_UNICAST == safi
4681 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4682 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4683
4684 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4685 }
4686 if ((SAFI_MPLS_VPN == safi)
4687 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4688 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4689 }
4690
4691 #ifdef ENABLE_BGP_VNC
4692 if (SAFI_MPLS_VPN == safi) {
4693 mpls_label_t label_decoded = decode_label(label);
4694
4695 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4696 type, sub_type, &label_decoded);
4697 }
4698 if (SAFI_ENCAP == safi) {
4699 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4700 type, sub_type, NULL);
4701 }
4702 #endif
4703 if ((safi == SAFI_MPLS_VPN) &&
4704 !CHECK_FLAG(bgp->af_flags[afi][safi],
4705 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4706 !leak_success) {
4707 bgp_unlink_nexthop(pi);
4708 bgp_path_info_delete(dest, pi);
4709 }
4710 return;
4711 } // End of implicit withdraw
4712
4713 /* Received Logging. */
4714 if (bgp_debug_update(peer, p, NULL, 1)) {
4715 if (!peer->rcvd_attr_printed) {
4716 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4717 peer->rcvd_attr_str);
4718 peer->rcvd_attr_printed = 1;
4719 }
4720
4721 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4722 addpath_id ? 1 : 0, addpath_id, evpn,
4723 pfx_buf, sizeof(pfx_buf));
4724 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4725 }
4726
4727 /* Make new BGP info. */
4728 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4729
4730 /* Update MPLS label */
4731 if (has_valid_label) {
4732 extra = bgp_path_info_extra_get(new);
4733 if (extra->label != label) {
4734 memcpy(&extra->label, label,
4735 num_labels * sizeof(mpls_label_t));
4736 extra->num_labels = num_labels;
4737 }
4738 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4739 bgp_set_valid_label(&extra->label[0]);
4740 }
4741
4742 /* Update SRv6 SID */
4743 if (safi == SAFI_MPLS_VPN) {
4744 extra = bgp_path_info_extra_get(new);
4745 if (attr->srv6_l3vpn) {
4746 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4747 extra->num_sids = 1;
4748
4749 extra->sid[0].loc_block_len =
4750 attr->srv6_l3vpn->loc_block_len;
4751 extra->sid[0].loc_node_len =
4752 attr->srv6_l3vpn->loc_node_len;
4753 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4754 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4755 extra->sid[0].transposition_len =
4756 attr->srv6_l3vpn->transposition_len;
4757 extra->sid[0].transposition_offset =
4758 attr->srv6_l3vpn->transposition_offset;
4759 } else if (attr->srv6_vpn) {
4760 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4761 extra->num_sids = 1;
4762 }
4763 }
4764
4765 /* Nexthop reachability check. */
4766 if (((afi == AFI_IP || afi == AFI_IP6)
4767 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4768 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4769 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4770 && peer->ttl == BGP_DEFAULT_TTL
4771 && !CHECK_FLAG(peer->flags,
4772 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4773 && !CHECK_FLAG(bgp->flags,
4774 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4775 connected = 1;
4776 else
4777 connected = 0;
4778
4779 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4780
4781 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4782 connected, bgp_nht_param_prefix) ||
4783 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4784 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4785 else {
4786 if (BGP_DEBUG(nht, NHT))
4787 zlog_debug("%s(%pI4): NH unresolved", __func__,
4788 &attr_new->nexthop);
4789 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4790 }
4791 } else {
4792 if (accept_own)
4793 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4794
4795 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4796 }
4797
4798 /* If maximum prefix count is configured and current prefix
4799 * count exeed it.
4800 */
4801 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4802 reason = "maximum-prefix overflow";
4803 bgp_attr_flush(&new_attr);
4804 goto filtered;
4805 }
4806
4807 /* Addpath ID */
4808 new->addpath_rx_id = addpath_id;
4809
4810 /* Increment prefix */
4811 bgp_aggregate_increment(bgp, p, new, afi, safi);
4812
4813 /* Register new BGP information. */
4814 bgp_path_info_add(dest, new);
4815
4816 /* route_node_get lock */
4817 bgp_dest_unlock_node(dest);
4818
4819 #ifdef ENABLE_BGP_VNC
4820 if (safi == SAFI_MPLS_VPN) {
4821 struct bgp_dest *pdest = NULL;
4822 struct bgp_table *table = NULL;
4823
4824 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4825 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4826 table = bgp_dest_get_bgp_table_info(pdest);
4827
4828 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4829 bgp, prd, table, p, new);
4830 }
4831 bgp_dest_unlock_node(pdest);
4832 }
4833 #endif
4834
4835 /* If this is an EVPN route, process for import. */
4836 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4837 bgp_evpn_import_route(bgp, afi, safi, p, new);
4838
4839 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4840
4841 /* Process change. */
4842 bgp_process(bgp, dest, afi, safi);
4843
4844 if (SAFI_UNICAST == safi
4845 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4846 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4847 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4848 }
4849 if ((SAFI_MPLS_VPN == safi)
4850 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4851 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4852 }
4853 #ifdef ENABLE_BGP_VNC
4854 if (SAFI_MPLS_VPN == safi) {
4855 mpls_label_t label_decoded = decode_label(label);
4856
4857 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4858 sub_type, &label_decoded);
4859 }
4860 if (SAFI_ENCAP == safi) {
4861 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4862 sub_type, NULL);
4863 }
4864 #endif
4865 if ((safi == SAFI_MPLS_VPN) &&
4866 !CHECK_FLAG(bgp->af_flags[afi][safi],
4867 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4868 !leak_success) {
4869 bgp_unlink_nexthop(new);
4870 bgp_path_info_delete(dest, new);
4871 }
4872
4873 return;
4874
4875 /* This BGP update is filtered. Log the reason then update BGP
4876 entry. */
4877 filtered:
4878 if (new) {
4879 bgp_unlink_nexthop(new);
4880 bgp_path_info_delete(dest, new);
4881 bgp_path_info_extra_free(&new->extra);
4882 XFREE(MTYPE_BGP_ROUTE, new);
4883 }
4884
4885 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4886
4887 if (bgp_debug_update(peer, p, NULL, 1)) {
4888 if (!peer->rcvd_attr_printed) {
4889 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4890 peer->rcvd_attr_str);
4891 peer->rcvd_attr_printed = 1;
4892 }
4893
4894 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4895 addpath_id ? 1 : 0, addpath_id, evpn,
4896 pfx_buf, sizeof(pfx_buf));
4897 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4898 peer, pfx_buf, reason);
4899 }
4900
4901 if (pi) {
4902 /* If this is an EVPN route, un-import it as it is now filtered.
4903 */
4904 if (safi == SAFI_EVPN)
4905 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4906
4907 if (SAFI_UNICAST == safi
4908 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4909 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4910
4911 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4912 }
4913 if ((SAFI_MPLS_VPN == safi)
4914 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4915
4916 vpn_leak_to_vrf_withdraw(pi);
4917 }
4918
4919 bgp_rib_remove(dest, pi, peer, afi, safi);
4920 }
4921
4922 bgp_dest_unlock_node(dest);
4923
4924 #ifdef ENABLE_BGP_VNC
4925 /*
4926 * Filtered update is treated as an implicit withdrawal (see
4927 * bgp_rib_remove()
4928 * a few lines above)
4929 */
4930 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4931 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4932 0);
4933 }
4934 #endif
4935
4936 return;
4937 }
4938
4939 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4940 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4941 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4942 uint32_t num_labels, struct bgp_route_evpn *evpn)
4943 {
4944 struct bgp *bgp;
4945 char pfx_buf[BGP_PRD_PATH_STRLEN];
4946 struct bgp_dest *dest;
4947 struct bgp_path_info *pi;
4948
4949 #ifdef ENABLE_BGP_VNC
4950 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4951 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4952 0);
4953 }
4954 #endif
4955
4956 bgp = peer->bgp;
4957
4958 /* Lookup node. */
4959 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4960
4961 /* If peer is soft reconfiguration enabled. Record input packet for
4962 * further calculation.
4963 *
4964 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4965 * routes that are filtered. This tanks out Quagga RS pretty badly due
4966 * to
4967 * the iteration over all RS clients.
4968 * Since we need to remove the entry from adj_in anyway, do that first
4969 * and
4970 * if there was no entry, we don't need to do anything more.
4971 */
4972 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4973 && peer != bgp->peer_self)
4974 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4975 peer->stat_pfx_dup_withdraw++;
4976
4977 if (bgp_debug_update(peer, p, NULL, 1)) {
4978 bgp_debug_rdpfxpath2str(
4979 afi, safi, prd, p, label, num_labels,
4980 addpath_id ? 1 : 0, addpath_id, NULL,
4981 pfx_buf, sizeof(pfx_buf));
4982 zlog_debug(
4983 "%s withdrawing route %s not in adj-in",
4984 peer->host, pfx_buf);
4985 }
4986 bgp_dest_unlock_node(dest);
4987 return;
4988 }
4989
4990 /* Lookup withdrawn route. */
4991 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4992 if (pi->peer == peer && pi->type == type
4993 && pi->sub_type == sub_type
4994 && pi->addpath_rx_id == addpath_id)
4995 break;
4996
4997 /* Logging. */
4998 if (bgp_debug_update(peer, p, NULL, 1)) {
4999 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5000 addpath_id ? 1 : 0, addpath_id, NULL,
5001 pfx_buf, sizeof(pfx_buf));
5002 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
5003 pfx_buf);
5004 }
5005
5006 /* Withdraw specified route from routing table. */
5007 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
5008 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
5009 if (SAFI_UNICAST == safi
5010 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5011 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5012 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5013 }
5014 if ((SAFI_MPLS_VPN == safi)
5015 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5016
5017 vpn_leak_to_vrf_withdraw(pi);
5018 }
5019 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5020 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5021 addpath_id ? 1 : 0, addpath_id, NULL,
5022 pfx_buf, sizeof(pfx_buf));
5023 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5024 }
5025
5026 /* Unlock bgp_node_get() lock. */
5027 bgp_dest_unlock_node(dest);
5028
5029 return;
5030 }
5031
5032 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5033 int withdraw)
5034 {
5035 struct update_subgroup *subgrp;
5036 subgrp = peer_subgroup(peer, afi, safi);
5037 subgroup_default_originate(subgrp, withdraw);
5038 }
5039
5040
5041 /*
5042 * bgp_stop_announce_route_timer
5043 */
5044 void bgp_stop_announce_route_timer(struct peer_af *paf)
5045 {
5046 if (!paf->t_announce_route)
5047 return;
5048
5049 EVENT_OFF(paf->t_announce_route);
5050 }
5051
5052 /*
5053 * bgp_announce_route_timer_expired
5054 *
5055 * Callback that is invoked when the route announcement timer for a
5056 * peer_af expires.
5057 */
5058 static void bgp_announce_route_timer_expired(struct event *t)
5059 {
5060 struct peer_af *paf;
5061 struct peer *peer;
5062
5063 paf = EVENT_ARG(t);
5064 peer = paf->peer;
5065
5066 if (!peer_established(peer))
5067 return;
5068
5069 if (!peer->afc_nego[paf->afi][paf->safi])
5070 return;
5071
5072 peer_af_announce_route(paf, 1);
5073
5074 /* Notify BGP conditional advertisement scanner percess */
5075 peer->advmap_config_change[paf->afi][paf->safi] = true;
5076 }
5077
5078 /*
5079 * bgp_announce_route
5080 *
5081 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5082 *
5083 * if force is true we will force an update even if the update
5084 * limiting code is attempted to kick in.
5085 */
5086 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5087 {
5088 struct peer_af *paf;
5089 struct update_subgroup *subgrp;
5090
5091 paf = peer_af_find(peer, afi, safi);
5092 if (!paf)
5093 return;
5094 subgrp = PAF_SUBGRP(paf);
5095
5096 /*
5097 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5098 * or a refresh has already been triggered.
5099 */
5100 if (!subgrp || paf->t_announce_route)
5101 return;
5102
5103 if (force)
5104 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5105
5106 /*
5107 * Start a timer to stagger/delay the announce. This serves
5108 * two purposes - announcement can potentially be combined for
5109 * multiple peers and the announcement doesn't happen in the
5110 * vty context.
5111 */
5112 event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5113 (subgrp->peer_count == 1)
5114 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5115 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5116 &paf->t_announce_route);
5117 }
5118
5119 /*
5120 * Announce routes from all AF tables to a peer.
5121 *
5122 * This should ONLY be called when there is a need to refresh the
5123 * routes to the peer based on a policy change for this peer alone
5124 * or a route refresh request received from the peer.
5125 * The operation will result in splitting the peer from its existing
5126 * subgroups and putting it in new subgroups.
5127 */
5128 void bgp_announce_route_all(struct peer *peer)
5129 {
5130 afi_t afi;
5131 safi_t safi;
5132
5133 FOREACH_AFI_SAFI (afi, safi)
5134 bgp_announce_route(peer, afi, safi, false);
5135 }
5136
5137 /* Flag or unflag bgp_dest to determine whether it should be treated by
5138 * bgp_soft_reconfig_table_task.
5139 * Flag if flag is true. Unflag if flag is false.
5140 */
5141 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5142 {
5143 struct bgp_dest *dest;
5144 struct bgp_adj_in *ain;
5145
5146 if (!table)
5147 return;
5148
5149 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5150 for (ain = dest->adj_in; ain; ain = ain->next) {
5151 if (ain->peer != NULL)
5152 break;
5153 }
5154 if (flag && ain != NULL && ain->peer != NULL)
5155 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5156 else
5157 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5158 }
5159 }
5160
5161 static void bgp_soft_reconfig_table_update(struct peer *peer,
5162 struct bgp_dest *dest,
5163 struct bgp_adj_in *ain, afi_t afi,
5164 safi_t safi, struct prefix_rd *prd)
5165 {
5166 struct bgp_path_info *pi;
5167 uint32_t num_labels = 0;
5168 mpls_label_t *label_pnt = NULL;
5169 struct bgp_route_evpn evpn;
5170
5171 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5172 if (pi->peer == peer)
5173 break;
5174
5175 if (pi && pi->extra)
5176 num_labels = pi->extra->num_labels;
5177 if (num_labels)
5178 label_pnt = &pi->extra->label[0];
5179 if (pi)
5180 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5181 sizeof(evpn));
5182 else
5183 memset(&evpn, 0, sizeof(evpn));
5184
5185 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5186 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5187 label_pnt, num_labels, 1, &evpn);
5188 }
5189
5190 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5191 struct bgp_table *table,
5192 struct prefix_rd *prd)
5193 {
5194 struct bgp_dest *dest;
5195 struct bgp_adj_in *ain;
5196
5197 if (!table)
5198 table = peer->bgp->rib[afi][safi];
5199
5200 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5201 for (ain = dest->adj_in; ain; ain = ain->next) {
5202 if (ain->peer != peer)
5203 continue;
5204
5205 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5206 safi, prd);
5207 }
5208 }
5209
5210 /* Do soft reconfig table per bgp table.
5211 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5212 * when BGP_NODE_SOFT_RECONFIG is set,
5213 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5214 * Schedule a new thread to continue the job.
5215 * Without splitting the full job into several part,
5216 * vtysh waits for the job to finish before responding to a BGP command
5217 */
5218 static void bgp_soft_reconfig_table_task(struct event *thread)
5219 {
5220 uint32_t iter, max_iter;
5221 struct bgp_dest *dest;
5222 struct bgp_adj_in *ain;
5223 struct peer *peer;
5224 struct bgp_table *table;
5225 struct prefix_rd *prd;
5226 struct listnode *node, *nnode;
5227
5228 table = EVENT_ARG(thread);
5229 prd = NULL;
5230
5231 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5232 if (table->soft_reconfig_init) {
5233 /* first call of the function with a new srta structure.
5234 * Don't do any treatment this time on nodes
5235 * in order vtysh to respond quickly
5236 */
5237 max_iter = 0;
5238 }
5239
5240 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5241 dest = bgp_route_next(dest)) {
5242 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5243 continue;
5244
5245 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5246
5247 for (ain = dest->adj_in; ain; ain = ain->next) {
5248 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5249 nnode, peer)) {
5250 if (ain->peer != peer)
5251 continue;
5252
5253 bgp_soft_reconfig_table_update(
5254 peer, dest, ain, table->afi,
5255 table->safi, prd);
5256 iter++;
5257 }
5258 }
5259 }
5260
5261 /* we're either starting the initial iteration,
5262 * or we're going to continue an ongoing iteration
5263 */
5264 if (dest || table->soft_reconfig_init) {
5265 table->soft_reconfig_init = false;
5266 event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
5267 0, &table->soft_reconfig_thread);
5268 return;
5269 }
5270 /* we're done, clean up the background iteration context info and
5271 schedule route annoucement
5272 */
5273 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5274 listnode_delete(table->soft_reconfig_peers, peer);
5275 bgp_announce_route(peer, table->afi, table->safi, false);
5276 }
5277
5278 list_delete(&table->soft_reconfig_peers);
5279 }
5280
5281
5282 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5283 * and peer.
5284 * - bgp cannot be NULL
5285 * - if table and peer are NULL, cancel all threads within the bgp instance
5286 * - if table is NULL and peer is not,
5287 * remove peer in all threads within the bgp instance
5288 * - if peer is NULL, cancel all threads matching table within the bgp instance
5289 */
5290 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5291 const struct bgp_table *table,
5292 const struct peer *peer)
5293 {
5294 struct peer *npeer;
5295 struct listnode *node, *nnode;
5296 int afi, safi;
5297 struct bgp_table *ntable;
5298
5299 if (!bgp)
5300 return;
5301
5302 FOREACH_AFI_SAFI (afi, safi) {
5303 ntable = bgp->rib[afi][safi];
5304 if (!ntable)
5305 continue;
5306 if (table && table != ntable)
5307 continue;
5308
5309 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5310 npeer)) {
5311 if (peer && peer != npeer)
5312 continue;
5313 listnode_delete(ntable->soft_reconfig_peers, npeer);
5314 }
5315
5316 if (!ntable->soft_reconfig_peers
5317 || !list_isempty(ntable->soft_reconfig_peers))
5318 continue;
5319
5320 list_delete(&ntable->soft_reconfig_peers);
5321 bgp_soft_reconfig_table_flag(ntable, false);
5322 EVENT_OFF(ntable->soft_reconfig_thread);
5323 }
5324 }
5325
5326 /*
5327 * Returns false if the peer is not configured for soft reconfig in
5328 */
5329 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5330 {
5331 struct bgp_dest *dest;
5332 struct bgp_table *table;
5333 struct listnode *node, *nnode;
5334 struct peer *npeer;
5335 struct peer_af *paf;
5336
5337 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5338 return false;
5339
5340 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5341 && (safi != SAFI_EVPN)) {
5342 table = peer->bgp->rib[afi][safi];
5343 if (!table)
5344 return true;
5345
5346 table->soft_reconfig_init = true;
5347
5348 if (!table->soft_reconfig_peers)
5349 table->soft_reconfig_peers = list_new();
5350 npeer = NULL;
5351 /* add peer to the table soft_reconfig_peers if not already
5352 * there
5353 */
5354 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5355 npeer)) {
5356 if (peer == npeer)
5357 break;
5358 }
5359 if (peer != npeer)
5360 listnode_add(table->soft_reconfig_peers, peer);
5361
5362 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5363 * on table would start back at the beginning.
5364 */
5365 bgp_soft_reconfig_table_flag(table, true);
5366
5367 if (!table->soft_reconfig_thread)
5368 event_add_event(bm->master,
5369 bgp_soft_reconfig_table_task, table, 0,
5370 &table->soft_reconfig_thread);
5371 /* Cancel bgp_announce_route_timer_expired threads.
5372 * bgp_announce_route_timer_expired threads have been scheduled
5373 * to announce routes as soon as the soft_reconfigure process
5374 * finishes.
5375 * In this case, soft_reconfigure is also scheduled by using
5376 * a thread but is planned after the
5377 * bgp_announce_route_timer_expired threads. It means that,
5378 * without cancelling the threads, the route announcement task
5379 * would run before the soft reconfiguration one. That would
5380 * useless and would block vtysh during several seconds. Route
5381 * announcements are rescheduled as soon as the soft_reconfigure
5382 * process finishes.
5383 */
5384 paf = peer_af_find(peer, afi, safi);
5385 if (paf)
5386 bgp_stop_announce_route_timer(paf);
5387 } else
5388 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5389 dest = bgp_route_next(dest)) {
5390 table = bgp_dest_get_bgp_table_info(dest);
5391
5392 if (table == NULL)
5393 continue;
5394
5395 const struct prefix *p = bgp_dest_get_prefix(dest);
5396 struct prefix_rd prd;
5397
5398 prd.family = AF_UNSPEC;
5399 prd.prefixlen = 64;
5400 memcpy(&prd.val, p->u.val, 8);
5401
5402 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5403 }
5404
5405 return true;
5406 }
5407
5408
5409 struct bgp_clear_node_queue {
5410 struct bgp_dest *dest;
5411 };
5412
5413 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5414 {
5415 struct bgp_clear_node_queue *cnq = data;
5416 struct bgp_dest *dest = cnq->dest;
5417 struct peer *peer = wq->spec.data;
5418 struct bgp_path_info *pi;
5419 struct bgp *bgp;
5420 afi_t afi = bgp_dest_table(dest)->afi;
5421 safi_t safi = bgp_dest_table(dest)->safi;
5422
5423 assert(dest && peer);
5424 bgp = peer->bgp;
5425
5426 /* It is possible that we have multiple paths for a prefix from a peer
5427 * if that peer is using AddPath.
5428 */
5429 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5430 if (pi->peer != peer)
5431 continue;
5432
5433 /* graceful restart STALE flag set. */
5434 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5435 && peer->nsf[afi][safi])
5436 || CHECK_FLAG(peer->af_sflags[afi][safi],
5437 PEER_STATUS_ENHANCED_REFRESH))
5438 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5439 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5440 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5441 else {
5442 /* If this is an EVPN route, process for
5443 * un-import. */
5444 if (safi == SAFI_EVPN)
5445 bgp_evpn_unimport_route(
5446 bgp, afi, safi,
5447 bgp_dest_get_prefix(dest), pi);
5448 /* Handle withdraw for VRF route-leaking and L3VPN */
5449 if (SAFI_UNICAST == safi
5450 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5451 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5452 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5453 bgp, pi);
5454 }
5455 if (SAFI_MPLS_VPN == safi &&
5456 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5457 vpn_leak_to_vrf_withdraw(pi);
5458 }
5459
5460 bgp_rib_remove(dest, pi, peer, afi, safi);
5461 }
5462 }
5463 return WQ_SUCCESS;
5464 }
5465
5466 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5467 {
5468 struct bgp_clear_node_queue *cnq = data;
5469 struct bgp_dest *dest = cnq->dest;
5470 struct bgp_table *table = bgp_dest_table(dest);
5471
5472 bgp_dest_unlock_node(dest);
5473 bgp_table_unlock(table);
5474 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5475 }
5476
5477 static void bgp_clear_node_complete(struct work_queue *wq)
5478 {
5479 struct peer *peer = wq->spec.data;
5480
5481 /* Tickle FSM to start moving again */
5482 BGP_EVENT_ADD(peer, Clearing_Completed);
5483
5484 peer_unlock(peer); /* bgp_clear_route */
5485 }
5486
5487 static void bgp_clear_node_queue_init(struct peer *peer)
5488 {
5489 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5490
5491 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5492 #undef CLEAR_QUEUE_NAME_LEN
5493
5494 peer->clear_node_queue = work_queue_new(bm->master, wname);
5495 peer->clear_node_queue->spec.hold = 10;
5496 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5497 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5498 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5499 peer->clear_node_queue->spec.max_retries = 0;
5500
5501 /* we only 'lock' this peer reference when the queue is actually active
5502 */
5503 peer->clear_node_queue->spec.data = peer;
5504 }
5505
5506 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5507 struct bgp_table *table)
5508 {
5509 struct bgp_dest *dest;
5510 int force = peer->bgp->process_queue ? 0 : 1;
5511
5512 if (!table)
5513 table = peer->bgp->rib[afi][safi];
5514
5515 /* If still no table => afi/safi isn't configured at all or smth. */
5516 if (!table)
5517 return;
5518
5519 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5520 struct bgp_path_info *pi, *next;
5521 struct bgp_adj_in *ain;
5522 struct bgp_adj_in *ain_next;
5523
5524 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5525 * queued for every clearing peer, regardless of whether it is
5526 * relevant to the peer at hand.
5527 *
5528 * Overview: There are 3 different indices which need to be
5529 * scrubbed, potentially, when a peer is removed:
5530 *
5531 * 1 peer's routes visible via the RIB (ie accepted routes)
5532 * 2 peer's routes visible by the (optional) peer's adj-in index
5533 * 3 other routes visible by the peer's adj-out index
5534 *
5535 * 3 there is no hurry in scrubbing, once the struct peer is
5536 * removed from bgp->peer, we could just GC such deleted peer's
5537 * adj-outs at our leisure.
5538 *
5539 * 1 and 2 must be 'scrubbed' in some way, at least made
5540 * invisible via RIB index before peer session is allowed to be
5541 * brought back up. So one needs to know when such a 'search' is
5542 * complete.
5543 *
5544 * Ideally:
5545 *
5546 * - there'd be a single global queue or a single RIB walker
5547 * - rather than tracking which route_nodes still need to be
5548 * examined on a peer basis, we'd track which peers still
5549 * aren't cleared
5550 *
5551 * Given that our per-peer prefix-counts now should be reliable,
5552 * this may actually be achievable. It doesn't seem to be a huge
5553 * problem at this time,
5554 *
5555 * It is possible that we have multiple paths for a prefix from
5556 * a peer
5557 * if that peer is using AddPath.
5558 */
5559 ain = dest->adj_in;
5560 while (ain) {
5561 ain_next = ain->next;
5562
5563 if (ain->peer == peer)
5564 bgp_adj_in_remove(dest, ain);
5565
5566 ain = ain_next;
5567 }
5568
5569 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5570 next = pi->next;
5571 if (pi->peer != peer)
5572 continue;
5573
5574 if (force)
5575 bgp_path_info_reap(dest, pi);
5576 else {
5577 struct bgp_clear_node_queue *cnq;
5578
5579 /* both unlocked in bgp_clear_node_queue_del */
5580 bgp_table_lock(bgp_dest_table(dest));
5581 bgp_dest_lock_node(dest);
5582 cnq = XCALLOC(
5583 MTYPE_BGP_CLEAR_NODE_QUEUE,
5584 sizeof(struct bgp_clear_node_queue));
5585 cnq->dest = dest;
5586 work_queue_add(peer->clear_node_queue, cnq);
5587 break;
5588 }
5589 }
5590 }
5591 return;
5592 }
5593
5594 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5595 {
5596 struct bgp_dest *dest;
5597 struct bgp_table *table;
5598
5599 if (peer->clear_node_queue == NULL)
5600 bgp_clear_node_queue_init(peer);
5601
5602 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5603 * Idle until it receives a Clearing_Completed event. This protects
5604 * against peers which flap faster than we can we clear, which could
5605 * lead to:
5606 *
5607 * a) race with routes from the new session being installed before
5608 * clear_route_node visits the node (to delete the route of that
5609 * peer)
5610 * b) resource exhaustion, clear_route_node likely leads to an entry
5611 * on the process_main queue. Fast-flapping could cause that queue
5612 * to grow and grow.
5613 */
5614
5615 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5616 * the unlock will happen upon work-queue completion; other wise, the
5617 * unlock happens at the end of this function.
5618 */
5619 if (!peer->clear_node_queue->thread)
5620 peer_lock(peer);
5621
5622 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5623 bgp_clear_route_table(peer, afi, safi, NULL);
5624 else
5625 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5626 dest = bgp_route_next(dest)) {
5627 table = bgp_dest_get_bgp_table_info(dest);
5628 if (!table)
5629 continue;
5630
5631 bgp_clear_route_table(peer, afi, safi, table);
5632 }
5633
5634 /* unlock if no nodes got added to the clear-node-queue. */
5635 if (!peer->clear_node_queue->thread)
5636 peer_unlock(peer);
5637 }
5638
5639 void bgp_clear_route_all(struct peer *peer)
5640 {
5641 afi_t afi;
5642 safi_t safi;
5643
5644 FOREACH_AFI_SAFI (afi, safi)
5645 bgp_clear_route(peer, afi, safi);
5646
5647 #ifdef ENABLE_BGP_VNC
5648 rfapiProcessPeerDown(peer);
5649 #endif
5650 }
5651
5652 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5653 {
5654 struct bgp_table *table;
5655 struct bgp_dest *dest;
5656 struct bgp_adj_in *ain;
5657 struct bgp_adj_in *ain_next;
5658
5659 table = peer->bgp->rib[afi][safi];
5660
5661 /* It is possible that we have multiple paths for a prefix from a peer
5662 * if that peer is using AddPath.
5663 */
5664 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5665 ain = dest->adj_in;
5666
5667 while (ain) {
5668 ain_next = ain->next;
5669
5670 if (ain->peer == peer)
5671 bgp_adj_in_remove(dest, ain);
5672
5673 ain = ain_next;
5674 }
5675 }
5676 }
5677
5678 /* If any of the routes from the peer have been marked with the NO_LLGR
5679 * community, either as sent by the peer, or as the result of a configured
5680 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5681 * operation of [RFC4271].
5682 */
5683 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5684 {
5685 struct bgp_dest *dest;
5686 struct bgp_path_info *pi;
5687 struct bgp_table *table;
5688
5689 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5690 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5691 dest = bgp_route_next(dest)) {
5692 struct bgp_dest *rm;
5693
5694 /* look for neighbor in tables */
5695 table = bgp_dest_get_bgp_table_info(dest);
5696 if (!table)
5697 continue;
5698
5699 for (rm = bgp_table_top(table); rm;
5700 rm = bgp_route_next(rm))
5701 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5702 pi = pi->next) {
5703 if (pi->peer != peer)
5704 continue;
5705 if (CHECK_FLAG(
5706 peer->af_sflags[afi][safi],
5707 PEER_STATUS_LLGR_WAIT) &&
5708 bgp_attr_get_community(pi->attr) &&
5709 !community_include(
5710 bgp_attr_get_community(
5711 pi->attr),
5712 COMMUNITY_NO_LLGR))
5713 continue;
5714 if (!CHECK_FLAG(pi->flags,
5715 BGP_PATH_STALE))
5716 continue;
5717
5718 /*
5719 * If this is VRF leaked route
5720 * process for withdraw.
5721 */
5722 if (pi->sub_type ==
5723 BGP_ROUTE_IMPORTED &&
5724 peer->bgp->inst_type ==
5725 BGP_INSTANCE_TYPE_DEFAULT)
5726 vpn_leak_to_vrf_withdraw(pi);
5727
5728 bgp_rib_remove(rm, pi, peer, afi, safi);
5729 break;
5730 }
5731 }
5732 } else {
5733 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5734 dest = bgp_route_next(dest))
5735 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5736 pi = pi->next) {
5737 if (pi->peer != peer)
5738 continue;
5739 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5740 PEER_STATUS_LLGR_WAIT) &&
5741 bgp_attr_get_community(pi->attr) &&
5742 !community_include(
5743 bgp_attr_get_community(pi->attr),
5744 COMMUNITY_NO_LLGR))
5745 continue;
5746 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5747 continue;
5748 if (safi == SAFI_UNICAST &&
5749 (peer->bgp->inst_type ==
5750 BGP_INSTANCE_TYPE_VRF ||
5751 peer->bgp->inst_type ==
5752 BGP_INSTANCE_TYPE_DEFAULT))
5753 vpn_leak_from_vrf_withdraw(
5754 bgp_get_default(), peer->bgp,
5755 pi);
5756
5757 bgp_rib_remove(dest, pi, peer, afi, safi);
5758 break;
5759 }
5760 }
5761 }
5762
5763 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5764 {
5765 struct bgp_dest *dest, *ndest;
5766 struct bgp_path_info *pi;
5767 struct bgp_table *table;
5768
5769 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5770 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5771 dest = bgp_route_next(dest)) {
5772 table = bgp_dest_get_bgp_table_info(dest);
5773 if (!table)
5774 continue;
5775
5776 for (ndest = bgp_table_top(table); ndest;
5777 ndest = bgp_route_next(ndest)) {
5778 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5779 pi = pi->next) {
5780 if (pi->peer != peer)
5781 continue;
5782
5783 if ((CHECK_FLAG(
5784 peer->af_sflags[afi][safi],
5785 PEER_STATUS_ENHANCED_REFRESH))
5786 && !CHECK_FLAG(pi->flags,
5787 BGP_PATH_STALE)
5788 && !CHECK_FLAG(
5789 pi->flags,
5790 BGP_PATH_UNUSEABLE)) {
5791 if (bgp_debug_neighbor_events(
5792 peer))
5793 zlog_debug(
5794 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5795 peer,
5796 afi2str(afi),
5797 safi2str(safi),
5798 bgp_dest_get_prefix(
5799 ndest));
5800
5801 bgp_path_info_set_flag(
5802 ndest, pi,
5803 BGP_PATH_STALE);
5804 }
5805 }
5806 }
5807 }
5808 } else {
5809 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5810 dest = bgp_route_next(dest)) {
5811 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5812 pi = pi->next) {
5813 if (pi->peer != peer)
5814 continue;
5815
5816 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5817 PEER_STATUS_ENHANCED_REFRESH))
5818 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5819 && !CHECK_FLAG(pi->flags,
5820 BGP_PATH_UNUSEABLE)) {
5821 if (bgp_debug_neighbor_events(peer))
5822 zlog_debug(
5823 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5824 peer, afi2str(afi),
5825 safi2str(safi),
5826 bgp_dest_get_prefix(
5827 dest));
5828
5829 bgp_path_info_set_flag(dest, pi,
5830 BGP_PATH_STALE);
5831 }
5832 }
5833 }
5834 }
5835 }
5836
5837 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5838 {
5839 if (peer->sort == BGP_PEER_IBGP)
5840 return true;
5841
5842 if (peer->sort == BGP_PEER_EBGP
5843 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5844 || FILTER_LIST_OUT_NAME(filter)
5845 || DISTRIBUTE_OUT_NAME(filter)))
5846 return true;
5847 return false;
5848 }
5849
5850 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5851 {
5852 if (peer->sort == BGP_PEER_IBGP)
5853 return true;
5854
5855 if (peer->sort == BGP_PEER_EBGP
5856 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5857 || FILTER_LIST_IN_NAME(filter)
5858 || DISTRIBUTE_IN_NAME(filter)))
5859 return true;
5860 return false;
5861 }
5862
5863 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5864 safi_t safi)
5865 {
5866 struct bgp_dest *dest;
5867 struct bgp_path_info *pi;
5868 struct bgp_path_info *next;
5869
5870 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5871 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5872 const struct prefix *p = bgp_dest_get_prefix(dest);
5873
5874 next = pi->next;
5875
5876 /* Unimport EVPN routes from VRFs */
5877 if (safi == SAFI_EVPN)
5878 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5879 SAFI_EVPN, p, pi);
5880
5881 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5882 && pi->type == ZEBRA_ROUTE_BGP
5883 && (pi->sub_type == BGP_ROUTE_NORMAL
5884 || pi->sub_type == BGP_ROUTE_AGGREGATE
5885 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5886
5887 if (bgp_fibupd_safi(safi))
5888 bgp_zebra_withdraw(p, pi, bgp, safi);
5889 }
5890
5891 bgp_path_info_reap(dest, pi);
5892 }
5893 }
5894
5895 /* Delete all kernel routes. */
5896 void bgp_cleanup_routes(struct bgp *bgp)
5897 {
5898 afi_t afi;
5899 struct bgp_dest *dest;
5900 struct bgp_table *table;
5901
5902 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5903 if (afi == AFI_L2VPN)
5904 continue;
5905 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5906 SAFI_UNICAST);
5907 /*
5908 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5909 */
5910 if (afi != AFI_L2VPN) {
5911 safi_t safi;
5912 safi = SAFI_MPLS_VPN;
5913 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5914 dest = bgp_route_next(dest)) {
5915 table = bgp_dest_get_bgp_table_info(dest);
5916 if (table != NULL) {
5917 bgp_cleanup_table(bgp, table, safi);
5918 bgp_table_finish(&table);
5919 bgp_dest_set_bgp_table_info(dest, NULL);
5920 bgp_dest_unlock_node(dest);
5921 }
5922 }
5923 safi = SAFI_ENCAP;
5924 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5925 dest = bgp_route_next(dest)) {
5926 table = bgp_dest_get_bgp_table_info(dest);
5927 if (table != NULL) {
5928 bgp_cleanup_table(bgp, table, safi);
5929 bgp_table_finish(&table);
5930 bgp_dest_set_bgp_table_info(dest, NULL);
5931 bgp_dest_unlock_node(dest);
5932 }
5933 }
5934 }
5935 }
5936 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5937 dest = bgp_route_next(dest)) {
5938 table = bgp_dest_get_bgp_table_info(dest);
5939 if (table != NULL) {
5940 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5941 bgp_table_finish(&table);
5942 bgp_dest_set_bgp_table_info(dest, NULL);
5943 bgp_dest_unlock_node(dest);
5944 }
5945 }
5946 }
5947
5948 void bgp_reset(void)
5949 {
5950 vty_reset();
5951 bgp_zclient_reset();
5952 access_list_reset();
5953 prefix_list_reset();
5954 }
5955
5956 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5957 {
5958 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5959 && CHECK_FLAG(peer->af_cap[afi][safi],
5960 PEER_CAP_ADDPATH_AF_TX_RCV));
5961 }
5962
5963 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5964 value. */
5965 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5966 struct bgp_nlri *packet)
5967 {
5968 uint8_t *pnt;
5969 uint8_t *lim;
5970 struct prefix p;
5971 int psize;
5972 afi_t afi;
5973 safi_t safi;
5974 bool addpath_capable;
5975 uint32_t addpath_id;
5976
5977 pnt = packet->nlri;
5978 lim = pnt + packet->length;
5979 afi = packet->afi;
5980 safi = packet->safi;
5981 addpath_id = 0;
5982 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5983
5984 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5985 syntactic validity. If the field is syntactically incorrect,
5986 then the Error Subcode is set to Invalid Network Field. */
5987 for (; pnt < lim; pnt += psize) {
5988 /* Clear prefix structure. */
5989 memset(&p, 0, sizeof(p));
5990
5991 if (addpath_capable) {
5992
5993 /* When packet overflow occurs return immediately. */
5994 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5995 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5996
5997 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5998 addpath_id = ntohl(addpath_id);
5999 pnt += BGP_ADDPATH_ID_LEN;
6000 }
6001
6002 /* Fetch prefix length. */
6003 p.prefixlen = *pnt++;
6004 /* afi/safi validity already verified by caller,
6005 * bgp_update_receive */
6006 p.family = afi2family(afi);
6007
6008 /* Prefix length check. */
6009 if (p.prefixlen > prefix_blen(&p) * 8) {
6010 flog_err(
6011 EC_BGP_UPDATE_RCV,
6012 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6013 peer->host, p.prefixlen, packet->afi);
6014 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6015 }
6016
6017 /* Packet size overflow check. */
6018 psize = PSIZE(p.prefixlen);
6019
6020 /* When packet overflow occur return immediately. */
6021 if (pnt + psize > lim) {
6022 flog_err(
6023 EC_BGP_UPDATE_RCV,
6024 "%s [Error] Update packet error (prefix length %d overflows packet)",
6025 peer->host, p.prefixlen);
6026 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6027 }
6028
6029 /* Defensive coding, double-check the psize fits in a struct
6030 * prefix for the v4 and v6 afi's and unicast/multicast */
6031 if (psize > (ssize_t)sizeof(p.u.val)) {
6032 flog_err(
6033 EC_BGP_UPDATE_RCV,
6034 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6035 peer->host, p.prefixlen, sizeof(p.u.val));
6036 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6037 }
6038
6039 /* Fetch prefix from NLRI packet. */
6040 memcpy(p.u.val, pnt, psize);
6041
6042 /* Check address. */
6043 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6044 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6045 /* From RFC4271 Section 6.3:
6046 *
6047 * If a prefix in the NLRI field is semantically
6048 * incorrect
6049 * (e.g., an unexpected multicast IP address),
6050 * an error SHOULD
6051 * be logged locally, and the prefix SHOULD be
6052 * ignored.
6053 */
6054 flog_err(
6055 EC_BGP_UPDATE_RCV,
6056 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6057 peer->host, &p.u.prefix4);
6058 continue;
6059 }
6060 }
6061
6062 /* Check address. */
6063 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6064 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6065 flog_err(
6066 EC_BGP_UPDATE_RCV,
6067 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6068 peer->host, &p.u.prefix6);
6069
6070 continue;
6071 }
6072 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6073 flog_err(
6074 EC_BGP_UPDATE_RCV,
6075 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6076 peer->host, &p.u.prefix6);
6077
6078 continue;
6079 }
6080 }
6081
6082 /* Normal process. */
6083 if (attr)
6084 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6085 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6086 NULL, 0, 0, NULL);
6087 else
6088 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6089 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6090 NULL, 0, NULL);
6091
6092 /* Do not send BGP notification twice when maximum-prefix count
6093 * overflow. */
6094 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6095 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6096 }
6097
6098 /* Packet length consistency check. */
6099 if (pnt != lim) {
6100 flog_err(
6101 EC_BGP_UPDATE_RCV,
6102 "%s [Error] Update packet error (prefix length mismatch with total length)",
6103 peer->host);
6104 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6105 }
6106
6107 return BGP_NLRI_PARSE_OK;
6108 }
6109
6110 static struct bgp_static *bgp_static_new(void)
6111 {
6112 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6113 }
6114
6115 static void bgp_static_free(struct bgp_static *bgp_static)
6116 {
6117 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6118 route_map_counter_decrement(bgp_static->rmap.map);
6119
6120 if (bgp_static->prd_pretty)
6121 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6122 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6123 XFREE(MTYPE_BGP_STATIC, bgp_static);
6124 }
6125
6126 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6127 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6128 {
6129 struct bgp_dest *dest;
6130 struct bgp_path_info *pi;
6131 struct bgp_path_info *new;
6132 struct bgp_path_info rmap_path;
6133 struct attr attr;
6134 struct attr *attr_new;
6135 route_map_result_t ret;
6136 #ifdef ENABLE_BGP_VNC
6137 int vnc_implicit_withdraw = 0;
6138 #endif
6139
6140 assert(bgp_static);
6141
6142 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6143
6144 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6145
6146 attr.nexthop = bgp_static->igpnexthop;
6147 attr.med = bgp_static->igpmetric;
6148 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6149
6150 if (afi == AFI_IP)
6151 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6152
6153 if (bgp_static->igpmetric)
6154 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6155
6156 if (bgp_static->atomic)
6157 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6158
6159 /* Store label index, if required. */
6160 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6161 attr.label_index = bgp_static->label_index;
6162 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6163 }
6164
6165 /* Apply route-map. */
6166 if (bgp_static->rmap.name) {
6167 struct attr attr_tmp = attr;
6168
6169 memset(&rmap_path, 0, sizeof(rmap_path));
6170 rmap_path.peer = bgp->peer_self;
6171 rmap_path.attr = &attr_tmp;
6172
6173 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6174
6175 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6176
6177 bgp->peer_self->rmap_type = 0;
6178
6179 if (ret == RMAP_DENYMATCH) {
6180 /* Free uninterned attribute. */
6181 bgp_attr_flush(&attr_tmp);
6182
6183 /* Unintern original. */
6184 aspath_unintern(&attr.aspath);
6185 bgp_static_withdraw(bgp, p, afi, safi);
6186 bgp_dest_unlock_node(dest);
6187 return;
6188 }
6189
6190 if (bgp_in_graceful_shutdown(bgp))
6191 bgp_attr_add_gshut_community(&attr_tmp);
6192
6193 attr_new = bgp_attr_intern(&attr_tmp);
6194 } else {
6195
6196 if (bgp_in_graceful_shutdown(bgp))
6197 bgp_attr_add_gshut_community(&attr);
6198
6199 attr_new = bgp_attr_intern(&attr);
6200 }
6201
6202 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6203 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6204 && pi->sub_type == BGP_ROUTE_STATIC)
6205 break;
6206
6207 if (pi) {
6208 if (attrhash_cmp(pi->attr, attr_new)
6209 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6210 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6211 bgp_dest_unlock_node(dest);
6212 bgp_attr_unintern(&attr_new);
6213 aspath_unintern(&attr.aspath);
6214 return;
6215 } else {
6216 /* The attribute is changed. */
6217 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6218
6219 /* Rewrite BGP route information. */
6220 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6221 bgp_path_info_restore(dest, pi);
6222 else
6223 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6224 #ifdef ENABLE_BGP_VNC
6225 if ((afi == AFI_IP || afi == AFI_IP6)
6226 && (safi == SAFI_UNICAST)) {
6227 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6228 /*
6229 * Implicit withdraw case.
6230 * We have to do this before pi is
6231 * changed
6232 */
6233 ++vnc_implicit_withdraw;
6234 vnc_import_bgp_del_route(bgp, p, pi);
6235 vnc_import_bgp_exterior_del_route(
6236 bgp, p, pi);
6237 }
6238 }
6239 #endif
6240 bgp_attr_unintern(&pi->attr);
6241 pi->attr = attr_new;
6242 pi->uptime = monotime(NULL);
6243 #ifdef ENABLE_BGP_VNC
6244 if ((afi == AFI_IP || afi == AFI_IP6)
6245 && (safi == SAFI_UNICAST)) {
6246 if (vnc_implicit_withdraw) {
6247 vnc_import_bgp_add_route(bgp, p, pi);
6248 vnc_import_bgp_exterior_add_route(
6249 bgp, p, pi);
6250 }
6251 }
6252 #endif
6253
6254 /* Nexthop reachability check. */
6255 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6256 && (safi == SAFI_UNICAST
6257 || safi == SAFI_LABELED_UNICAST)) {
6258
6259 struct bgp *bgp_nexthop = bgp;
6260
6261 if (pi->extra && pi->extra->bgp_orig)
6262 bgp_nexthop = pi->extra->bgp_orig;
6263
6264 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6265 afi, safi, pi, NULL,
6266 0, p))
6267 bgp_path_info_set_flag(dest, pi,
6268 BGP_PATH_VALID);
6269 else {
6270 if (BGP_DEBUG(nht, NHT)) {
6271 char buf1[INET6_ADDRSTRLEN];
6272 inet_ntop(p->family,
6273 &p->u.prefix, buf1,
6274 sizeof(buf1));
6275 zlog_debug(
6276 "%s(%s): Route not in table, not advertising",
6277 __func__, buf1);
6278 }
6279 bgp_path_info_unset_flag(
6280 dest, pi, BGP_PATH_VALID);
6281 }
6282 } else {
6283 /* Delete the NHT structure if any, if we're
6284 * toggling between
6285 * enabling/disabling import check. We
6286 * deregister the route
6287 * from NHT to avoid overloading NHT and the
6288 * process interaction
6289 */
6290 bgp_unlink_nexthop(pi);
6291 bgp_path_info_set_flag(dest, pi,
6292 BGP_PATH_VALID);
6293 }
6294 /* Process change. */
6295 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6296 bgp_process(bgp, dest, afi, safi);
6297
6298 if (SAFI_UNICAST == safi
6299 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6300 || bgp->inst_type
6301 == BGP_INSTANCE_TYPE_DEFAULT)) {
6302 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6303 pi);
6304 }
6305
6306 bgp_dest_unlock_node(dest);
6307 aspath_unintern(&attr.aspath);
6308 return;
6309 }
6310 }
6311
6312 /* Make new BGP info. */
6313 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6314 attr_new, dest);
6315 /* Nexthop reachability check. */
6316 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6317 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6318 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6319 p))
6320 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6321 else {
6322 if (BGP_DEBUG(nht, NHT)) {
6323 char buf1[INET6_ADDRSTRLEN];
6324
6325 inet_ntop(p->family, &p->u.prefix, buf1,
6326 sizeof(buf1));
6327 zlog_debug(
6328 "%s(%s): Route not in table, not advertising",
6329 __func__, buf1);
6330 }
6331 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6332 }
6333 } else {
6334 /* Delete the NHT structure if any, if we're toggling between
6335 * enabling/disabling import check. We deregister the route
6336 * from NHT to avoid overloading NHT and the process interaction
6337 */
6338 bgp_unlink_nexthop(new);
6339
6340 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6341 }
6342
6343 /* Aggregate address increment. */
6344 bgp_aggregate_increment(bgp, p, new, afi, safi);
6345
6346 /* Register new BGP information. */
6347 bgp_path_info_add(dest, new);
6348
6349 /* route_node_get lock */
6350 bgp_dest_unlock_node(dest);
6351
6352 /* Process change. */
6353 bgp_process(bgp, dest, afi, safi);
6354
6355 if (SAFI_UNICAST == safi
6356 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6357 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6358 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6359 }
6360
6361 /* Unintern original. */
6362 aspath_unintern(&attr.aspath);
6363 }
6364
6365 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6366 safi_t safi)
6367 {
6368 struct bgp_dest *dest;
6369 struct bgp_path_info *pi;
6370
6371 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6372
6373 /* Check selected route and self inserted route. */
6374 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6375 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6376 && pi->sub_type == BGP_ROUTE_STATIC)
6377 break;
6378
6379 /* Withdraw static BGP route from routing table. */
6380 if (pi) {
6381 if (SAFI_UNICAST == safi
6382 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6383 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6384 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6385 }
6386 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6387 bgp_unlink_nexthop(pi);
6388 bgp_path_info_delete(dest, pi);
6389 bgp_process(bgp, dest, afi, safi);
6390 }
6391
6392 /* Unlock bgp_node_lookup. */
6393 bgp_dest_unlock_node(dest);
6394 }
6395
6396 /*
6397 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6398 */
6399 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6400 afi_t afi, safi_t safi,
6401 struct prefix_rd *prd)
6402 {
6403 struct bgp_dest *dest;
6404 struct bgp_path_info *pi;
6405
6406 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6407
6408 /* Check selected route and self inserted route. */
6409 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6410 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6411 && pi->sub_type == BGP_ROUTE_STATIC)
6412 break;
6413
6414 /* Withdraw static BGP route from routing table. */
6415 if (pi) {
6416 #ifdef ENABLE_BGP_VNC
6417 rfapiProcessWithdraw(
6418 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6419 1); /* Kill, since it is an administrative change */
6420 #endif
6421 if (SAFI_MPLS_VPN == safi
6422 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6423 vpn_leak_to_vrf_withdraw(pi);
6424 }
6425 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6426 bgp_path_info_delete(dest, pi);
6427 bgp_process(bgp, dest, afi, safi);
6428 }
6429
6430 /* Unlock bgp_node_lookup. */
6431 bgp_dest_unlock_node(dest);
6432 }
6433
6434 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6435 struct bgp_static *bgp_static, afi_t afi,
6436 safi_t safi)
6437 {
6438 struct bgp_dest *dest;
6439 struct bgp_path_info *new;
6440 struct attr *attr_new;
6441 struct attr attr = {0};
6442 struct bgp_path_info *pi;
6443 #ifdef ENABLE_BGP_VNC
6444 mpls_label_t label = 0;
6445 #endif
6446 uint32_t num_labels = 0;
6447
6448 assert(bgp_static);
6449
6450 if (bgp_static->label != MPLS_INVALID_LABEL)
6451 num_labels = 1;
6452 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6453 &bgp_static->prd);
6454
6455 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6456
6457 attr.nexthop = bgp_static->igpnexthop;
6458 attr.med = bgp_static->igpmetric;
6459 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6460
6461 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6462 || (safi == SAFI_ENCAP)) {
6463 if (afi == AFI_IP) {
6464 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6465 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6466 }
6467 }
6468 if (afi == AFI_L2VPN) {
6469 if (bgp_static->gatewayIp.family == AF_INET) {
6470 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6471 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6472 &bgp_static->gatewayIp.u.prefix4,
6473 IPV4_MAX_BYTELEN);
6474 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6475 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6476 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6477 &bgp_static->gatewayIp.u.prefix6,
6478 IPV6_MAX_BYTELEN);
6479 }
6480 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6481 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6482 struct bgp_encap_type_vxlan bet;
6483 memset(&bet, 0, sizeof(bet));
6484 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6485 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6486 }
6487 if (bgp_static->router_mac) {
6488 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6489 }
6490 }
6491 /* Apply route-map. */
6492 if (bgp_static->rmap.name) {
6493 struct attr attr_tmp = attr;
6494 struct bgp_path_info rmap_path;
6495 route_map_result_t ret;
6496
6497 rmap_path.peer = bgp->peer_self;
6498 rmap_path.attr = &attr_tmp;
6499
6500 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6501
6502 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6503
6504 bgp->peer_self->rmap_type = 0;
6505
6506 if (ret == RMAP_DENYMATCH) {
6507 /* Free uninterned attribute. */
6508 bgp_attr_flush(&attr_tmp);
6509
6510 /* Unintern original. */
6511 aspath_unintern(&attr.aspath);
6512 bgp_static_withdraw_safi(bgp, p, afi, safi,
6513 &bgp_static->prd);
6514 bgp_dest_unlock_node(dest);
6515 return;
6516 }
6517
6518 attr_new = bgp_attr_intern(&attr_tmp);
6519 } else {
6520 attr_new = bgp_attr_intern(&attr);
6521 }
6522
6523 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6524 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6525 && pi->sub_type == BGP_ROUTE_STATIC)
6526 break;
6527
6528 if (pi) {
6529 if (attrhash_cmp(pi->attr, attr_new)
6530 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6531 bgp_dest_unlock_node(dest);
6532 bgp_attr_unintern(&attr_new);
6533 aspath_unintern(&attr.aspath);
6534 return;
6535 } else {
6536 /* The attribute is changed. */
6537 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6538
6539 /* Rewrite BGP route information. */
6540 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6541 bgp_path_info_restore(dest, pi);
6542 else
6543 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6544 bgp_attr_unintern(&pi->attr);
6545 pi->attr = attr_new;
6546 pi->uptime = monotime(NULL);
6547 #ifdef ENABLE_BGP_VNC
6548 if (pi->extra)
6549 label = decode_label(&pi->extra->label[0]);
6550 #endif
6551
6552 /* Process change. */
6553 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6554 bgp_process(bgp, dest, afi, safi);
6555
6556 if (SAFI_MPLS_VPN == safi
6557 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6558 vpn_leak_to_vrf_update(bgp, pi,
6559 &bgp_static->prd);
6560 }
6561 #ifdef ENABLE_BGP_VNC
6562 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6563 pi->attr, afi, safi, pi->type,
6564 pi->sub_type, &label);
6565 #endif
6566 bgp_dest_unlock_node(dest);
6567 aspath_unintern(&attr.aspath);
6568 return;
6569 }
6570 }
6571
6572
6573 /* Make new BGP info. */
6574 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6575 attr_new, dest);
6576 SET_FLAG(new->flags, BGP_PATH_VALID);
6577 bgp_path_info_extra_get(new);
6578 if (num_labels) {
6579 new->extra->label[0] = bgp_static->label;
6580 new->extra->num_labels = num_labels;
6581 }
6582 #ifdef ENABLE_BGP_VNC
6583 label = decode_label(&bgp_static->label);
6584 #endif
6585
6586 /* Aggregate address increment. */
6587 bgp_aggregate_increment(bgp, p, new, afi, safi);
6588
6589 /* Register new BGP information. */
6590 bgp_path_info_add(dest, new);
6591 /* route_node_get lock */
6592 bgp_dest_unlock_node(dest);
6593
6594 /* Process change. */
6595 bgp_process(bgp, dest, afi, safi);
6596
6597 if (SAFI_MPLS_VPN == safi
6598 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6599 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6600 }
6601 #ifdef ENABLE_BGP_VNC
6602 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6603 safi, new->type, new->sub_type, &label);
6604 #endif
6605
6606 /* Unintern original. */
6607 aspath_unintern(&attr.aspath);
6608 }
6609
6610 /* Configure static BGP network. When user don't run zebra, static
6611 route should be installed as valid. */
6612 static int bgp_static_set(struct vty *vty, const char *negate,
6613 const char *ip_str, afi_t afi, safi_t safi,
6614 const char *rmap, int backdoor, uint32_t label_index)
6615 {
6616 VTY_DECLVAR_CONTEXT(bgp, bgp);
6617 int ret;
6618 struct prefix p;
6619 struct bgp_static *bgp_static;
6620 struct bgp_dest *dest;
6621 uint8_t need_update = 0;
6622
6623 /* Convert IP prefix string to struct prefix. */
6624 ret = str2prefix(ip_str, &p);
6625 if (!ret) {
6626 vty_out(vty, "%% Malformed prefix\n");
6627 return CMD_WARNING_CONFIG_FAILED;
6628 }
6629 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6630 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6631 return CMD_WARNING_CONFIG_FAILED;
6632 }
6633
6634 apply_mask(&p);
6635
6636 if (negate) {
6637
6638 /* Set BGP static route configuration. */
6639 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6640
6641 if (!dest) {
6642 vty_out(vty, "%% Can't find static route specified\n");
6643 return CMD_WARNING_CONFIG_FAILED;
6644 }
6645
6646 bgp_static = bgp_dest_get_bgp_static_info(dest);
6647
6648 if ((label_index != BGP_INVALID_LABEL_INDEX)
6649 && (label_index != bgp_static->label_index)) {
6650 vty_out(vty,
6651 "%% label-index doesn't match static route\n");
6652 bgp_dest_unlock_node(dest);
6653 return CMD_WARNING_CONFIG_FAILED;
6654 }
6655
6656 if ((rmap && bgp_static->rmap.name)
6657 && strcmp(rmap, bgp_static->rmap.name)) {
6658 vty_out(vty,
6659 "%% route-map name doesn't match static route\n");
6660 bgp_dest_unlock_node(dest);
6661 return CMD_WARNING_CONFIG_FAILED;
6662 }
6663
6664 /* Update BGP RIB. */
6665 if (!bgp_static->backdoor)
6666 bgp_static_withdraw(bgp, &p, afi, safi);
6667
6668 /* Clear configuration. */
6669 bgp_static_free(bgp_static);
6670 bgp_dest_set_bgp_static_info(dest, NULL);
6671 bgp_dest_unlock_node(dest);
6672 bgp_dest_unlock_node(dest);
6673 } else {
6674
6675 /* Set BGP static route configuration. */
6676 dest = bgp_node_get(bgp->route[afi][safi], &p);
6677 bgp_static = bgp_dest_get_bgp_static_info(dest);
6678 if (bgp_static) {
6679 /* Configuration change. */
6680 /* Label index cannot be changed. */
6681 if (bgp_static->label_index != label_index) {
6682 vty_out(vty, "%% cannot change label-index\n");
6683 bgp_dest_unlock_node(dest);
6684 return CMD_WARNING_CONFIG_FAILED;
6685 }
6686
6687 /* Check previous routes are installed into BGP. */
6688 if (bgp_static->valid
6689 && bgp_static->backdoor != backdoor)
6690 need_update = 1;
6691
6692 bgp_static->backdoor = backdoor;
6693
6694 if (rmap) {
6695 XFREE(MTYPE_ROUTE_MAP_NAME,
6696 bgp_static->rmap.name);
6697 route_map_counter_decrement(
6698 bgp_static->rmap.map);
6699 bgp_static->rmap.name =
6700 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6701 bgp_static->rmap.map =
6702 route_map_lookup_by_name(rmap);
6703 route_map_counter_increment(
6704 bgp_static->rmap.map);
6705 } else {
6706 XFREE(MTYPE_ROUTE_MAP_NAME,
6707 bgp_static->rmap.name);
6708 route_map_counter_decrement(
6709 bgp_static->rmap.map);
6710 bgp_static->rmap.map = NULL;
6711 bgp_static->valid = 0;
6712 }
6713 bgp_dest_unlock_node(dest);
6714 } else {
6715 /* New configuration. */
6716 bgp_static = bgp_static_new();
6717 bgp_static->backdoor = backdoor;
6718 bgp_static->valid = 0;
6719 bgp_static->igpmetric = 0;
6720 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6721 bgp_static->label_index = label_index;
6722
6723 if (rmap) {
6724 XFREE(MTYPE_ROUTE_MAP_NAME,
6725 bgp_static->rmap.name);
6726 route_map_counter_decrement(
6727 bgp_static->rmap.map);
6728 bgp_static->rmap.name =
6729 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6730 bgp_static->rmap.map =
6731 route_map_lookup_by_name(rmap);
6732 route_map_counter_increment(
6733 bgp_static->rmap.map);
6734 }
6735 bgp_dest_set_bgp_static_info(dest, bgp_static);
6736 }
6737
6738 bgp_static->valid = 1;
6739 if (need_update)
6740 bgp_static_withdraw(bgp, &p, afi, safi);
6741
6742 if (!bgp_static->backdoor)
6743 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6744 }
6745
6746 return CMD_SUCCESS;
6747 }
6748
6749 void bgp_static_add(struct bgp *bgp)
6750 {
6751 afi_t afi;
6752 safi_t safi;
6753 struct bgp_dest *dest;
6754 struct bgp_dest *rm;
6755 struct bgp_table *table;
6756 struct bgp_static *bgp_static;
6757
6758 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6759 FOREACH_AFI_SAFI (afi, safi)
6760 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6761 dest = bgp_route_next(dest)) {
6762 if (!bgp_dest_has_bgp_path_info_data(dest))
6763 continue;
6764
6765 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6766 || (safi == SAFI_EVPN)) {
6767 table = bgp_dest_get_bgp_table_info(dest);
6768
6769 for (rm = bgp_table_top(table); rm;
6770 rm = bgp_route_next(rm)) {
6771 bgp_static =
6772 bgp_dest_get_bgp_static_info(
6773 rm);
6774 bgp_static_update_safi(
6775 bgp, bgp_dest_get_prefix(rm),
6776 bgp_static, afi, safi);
6777 }
6778 } else {
6779 bgp_static_update(
6780 bgp, bgp_dest_get_prefix(dest),
6781 bgp_dest_get_bgp_static_info(dest), afi,
6782 safi);
6783 }
6784 }
6785 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6786 }
6787
6788 /* Called from bgp_delete(). Delete all static routes from the BGP
6789 instance. */
6790 void bgp_static_delete(struct bgp *bgp)
6791 {
6792 afi_t afi;
6793 safi_t safi;
6794 struct bgp_dest *dest;
6795 struct bgp_dest *rm;
6796 struct bgp_table *table;
6797 struct bgp_static *bgp_static;
6798
6799 FOREACH_AFI_SAFI (afi, safi)
6800 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6801 dest = bgp_route_next(dest)) {
6802 if (!bgp_dest_has_bgp_path_info_data(dest))
6803 continue;
6804
6805 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6806 || (safi == SAFI_EVPN)) {
6807 table = bgp_dest_get_bgp_table_info(dest);
6808
6809 for (rm = bgp_table_top(table); rm;
6810 rm = bgp_route_next(rm)) {
6811 bgp_static =
6812 bgp_dest_get_bgp_static_info(
6813 rm);
6814 if (!bgp_static)
6815 continue;
6816
6817 bgp_static_withdraw_safi(
6818 bgp, bgp_dest_get_prefix(rm),
6819 AFI_IP, safi,
6820 (struct prefix_rd *)
6821 bgp_dest_get_prefix(
6822 dest));
6823 bgp_static_free(bgp_static);
6824 bgp_dest_set_bgp_static_info(rm,
6825 NULL);
6826 bgp_dest_unlock_node(rm);
6827 }
6828 } else {
6829 bgp_static = bgp_dest_get_bgp_static_info(dest);
6830 bgp_static_withdraw(bgp,
6831 bgp_dest_get_prefix(dest),
6832 afi, safi);
6833 bgp_static_free(bgp_static);
6834 bgp_dest_set_bgp_static_info(dest, NULL);
6835 bgp_dest_unlock_node(dest);
6836 }
6837 }
6838 }
6839
6840 void bgp_static_redo_import_check(struct bgp *bgp)
6841 {
6842 afi_t afi;
6843 safi_t safi;
6844 struct bgp_dest *dest;
6845 struct bgp_dest *rm;
6846 struct bgp_table *table;
6847 struct bgp_static *bgp_static;
6848
6849 /* Use this flag to force reprocessing of the route */
6850 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6851 FOREACH_AFI_SAFI (afi, safi) {
6852 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6853 dest = bgp_route_next(dest)) {
6854 if (!bgp_dest_has_bgp_path_info_data(dest))
6855 continue;
6856
6857 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6858 || (safi == SAFI_EVPN)) {
6859 table = bgp_dest_get_bgp_table_info(dest);
6860
6861 for (rm = bgp_table_top(table); rm;
6862 rm = bgp_route_next(rm)) {
6863 bgp_static =
6864 bgp_dest_get_bgp_static_info(
6865 rm);
6866 bgp_static_update_safi(
6867 bgp, bgp_dest_get_prefix(rm),
6868 bgp_static, afi, safi);
6869 }
6870 } else {
6871 bgp_static = bgp_dest_get_bgp_static_info(dest);
6872 bgp_static_update(bgp,
6873 bgp_dest_get_prefix(dest),
6874 bgp_static, afi, safi);
6875 }
6876 }
6877 }
6878 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6879 }
6880
6881 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6882 safi_t safi)
6883 {
6884 struct bgp_table *table;
6885 struct bgp_dest *dest;
6886 struct bgp_path_info *pi;
6887
6888 /* Do not install the aggregate route if BGP is in the
6889 * process of termination.
6890 */
6891 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6892 || (bgp->peer_self == NULL))
6893 return;
6894
6895 table = bgp->rib[afi][safi];
6896 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6897 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6898 if (pi->peer == bgp->peer_self
6899 && ((pi->type == ZEBRA_ROUTE_BGP
6900 && pi->sub_type == BGP_ROUTE_STATIC)
6901 || (pi->type != ZEBRA_ROUTE_BGP
6902 && pi->sub_type
6903 == BGP_ROUTE_REDISTRIBUTE))) {
6904 bgp_aggregate_decrement(
6905 bgp, bgp_dest_get_prefix(dest), pi, afi,
6906 safi);
6907 bgp_unlink_nexthop(pi);
6908 bgp_path_info_delete(dest, pi);
6909 bgp_process(bgp, dest, afi, safi);
6910 }
6911 }
6912 }
6913 }
6914
6915 /*
6916 * Purge all networks and redistributed routes from routing table.
6917 * Invoked upon the instance going down.
6918 */
6919 void bgp_purge_static_redist_routes(struct bgp *bgp)
6920 {
6921 afi_t afi;
6922 safi_t safi;
6923
6924 FOREACH_AFI_SAFI (afi, safi)
6925 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6926 }
6927
6928 /*
6929 * gpz 110624
6930 * Currently this is used to set static routes for VPN and ENCAP.
6931 * I think it can probably be factored with bgp_static_set.
6932 */
6933 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6934 const char *ip_str, const char *rd_str,
6935 const char *label_str, const char *rmap_str,
6936 int evpn_type, const char *esi, const char *gwip,
6937 const char *ethtag, const char *routermac)
6938 {
6939 VTY_DECLVAR_CONTEXT(bgp, bgp);
6940 int ret;
6941 struct prefix p;
6942 struct prefix_rd prd;
6943 struct bgp_dest *pdest;
6944 struct bgp_dest *dest;
6945 struct bgp_table *table;
6946 struct bgp_static *bgp_static;
6947 mpls_label_t label = MPLS_INVALID_LABEL;
6948 struct prefix gw_ip;
6949
6950 /* validate ip prefix */
6951 ret = str2prefix(ip_str, &p);
6952 if (!ret) {
6953 vty_out(vty, "%% Malformed prefix\n");
6954 return CMD_WARNING_CONFIG_FAILED;
6955 }
6956 apply_mask(&p);
6957 if ((afi == AFI_L2VPN)
6958 && (bgp_build_evpn_prefix(evpn_type,
6959 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6960 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6961 return CMD_WARNING_CONFIG_FAILED;
6962 }
6963
6964 ret = str2prefix_rd(rd_str, &prd);
6965 if (!ret) {
6966 vty_out(vty, "%% Malformed rd\n");
6967 return CMD_WARNING_CONFIG_FAILED;
6968 }
6969
6970 if (label_str) {
6971 unsigned long label_val;
6972 label_val = strtoul(label_str, NULL, 10);
6973 encode_label(label_val, &label);
6974 }
6975
6976 if (safi == SAFI_EVPN) {
6977 if (esi && str2esi(esi, NULL) == 0) {
6978 vty_out(vty, "%% Malformed ESI\n");
6979 return CMD_WARNING_CONFIG_FAILED;
6980 }
6981 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6982 vty_out(vty, "%% Malformed Router MAC\n");
6983 return CMD_WARNING_CONFIG_FAILED;
6984 }
6985 if (gwip) {
6986 memset(&gw_ip, 0, sizeof(gw_ip));
6987 ret = str2prefix(gwip, &gw_ip);
6988 if (!ret) {
6989 vty_out(vty, "%% Malformed GatewayIp\n");
6990 return CMD_WARNING_CONFIG_FAILED;
6991 }
6992 if ((gw_ip.family == AF_INET
6993 && is_evpn_prefix_ipaddr_v6(
6994 (struct prefix_evpn *)&p))
6995 || (gw_ip.family == AF_INET6
6996 && is_evpn_prefix_ipaddr_v4(
6997 (struct prefix_evpn *)&p))) {
6998 vty_out(vty,
6999 "%% GatewayIp family differs with IP prefix\n");
7000 return CMD_WARNING_CONFIG_FAILED;
7001 }
7002 }
7003 }
7004 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7005 if (!bgp_dest_has_bgp_path_info_data(pdest))
7006 bgp_dest_set_bgp_table_info(pdest,
7007 bgp_table_init(bgp, afi, safi));
7008 table = bgp_dest_get_bgp_table_info(pdest);
7009
7010 dest = bgp_node_get(table, &p);
7011
7012 if (bgp_dest_has_bgp_path_info_data(dest)) {
7013 vty_out(vty, "%% Same network configuration exists\n");
7014 bgp_dest_unlock_node(dest);
7015 } else {
7016 /* New configuration. */
7017 bgp_static = bgp_static_new();
7018 bgp_static->backdoor = 0;
7019 bgp_static->valid = 0;
7020 bgp_static->igpmetric = 0;
7021 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7022 bgp_static->label = label;
7023 bgp_static->prd = prd;
7024
7025 if (rd_str)
7026 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
7027 if (rmap_str) {
7028 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7029 route_map_counter_decrement(bgp_static->rmap.map);
7030 bgp_static->rmap.name =
7031 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7032 bgp_static->rmap.map =
7033 route_map_lookup_by_name(rmap_str);
7034 route_map_counter_increment(bgp_static->rmap.map);
7035 }
7036
7037 if (safi == SAFI_EVPN) {
7038 if (esi) {
7039 bgp_static->eth_s_id =
7040 XCALLOC(MTYPE_ATTR,
7041 sizeof(esi_t));
7042 str2esi(esi, bgp_static->eth_s_id);
7043 }
7044 if (routermac) {
7045 bgp_static->router_mac =
7046 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7047 (void)prefix_str2mac(routermac,
7048 bgp_static->router_mac);
7049 }
7050 if (gwip)
7051 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7052 }
7053 bgp_dest_set_bgp_static_info(dest, bgp_static);
7054
7055 bgp_static->valid = 1;
7056 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7057 }
7058
7059 return CMD_SUCCESS;
7060 }
7061
7062 /* Configure static BGP network. */
7063 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7064 const char *ip_str, const char *rd_str,
7065 const char *label_str, int evpn_type, const char *esi,
7066 const char *gwip, const char *ethtag)
7067 {
7068 VTY_DECLVAR_CONTEXT(bgp, bgp);
7069 int ret;
7070 struct prefix p;
7071 struct prefix_rd prd;
7072 struct bgp_dest *pdest;
7073 struct bgp_dest *dest;
7074 struct bgp_table *table;
7075 struct bgp_static *bgp_static;
7076 mpls_label_t label = MPLS_INVALID_LABEL;
7077
7078 /* Convert IP prefix string to struct prefix. */
7079 ret = str2prefix(ip_str, &p);
7080 if (!ret) {
7081 vty_out(vty, "%% Malformed prefix\n");
7082 return CMD_WARNING_CONFIG_FAILED;
7083 }
7084 apply_mask(&p);
7085 if ((afi == AFI_L2VPN)
7086 && (bgp_build_evpn_prefix(evpn_type,
7087 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7088 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7089 return CMD_WARNING_CONFIG_FAILED;
7090 }
7091 ret = str2prefix_rd(rd_str, &prd);
7092 if (!ret) {
7093 vty_out(vty, "%% Malformed rd\n");
7094 return CMD_WARNING_CONFIG_FAILED;
7095 }
7096
7097 if (label_str) {
7098 unsigned long label_val;
7099 label_val = strtoul(label_str, NULL, 10);
7100 encode_label(label_val, &label);
7101 }
7102
7103 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7104 if (!bgp_dest_has_bgp_path_info_data(pdest))
7105 bgp_dest_set_bgp_table_info(pdest,
7106 bgp_table_init(bgp, afi, safi));
7107 else
7108 bgp_dest_unlock_node(pdest);
7109 table = bgp_dest_get_bgp_table_info(pdest);
7110
7111 dest = bgp_node_lookup(table, &p);
7112
7113 if (dest) {
7114 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7115
7116 bgp_static = bgp_dest_get_bgp_static_info(dest);
7117 bgp_static_free(bgp_static);
7118 bgp_dest_set_bgp_static_info(dest, NULL);
7119 bgp_dest_unlock_node(dest);
7120 bgp_dest_unlock_node(dest);
7121 } else
7122 vty_out(vty, "%% Can't find the route\n");
7123
7124 return CMD_SUCCESS;
7125 }
7126
7127 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7128 const char *rmap_name)
7129 {
7130 VTY_DECLVAR_CONTEXT(bgp, bgp);
7131 struct bgp_rmap *rmap;
7132
7133 rmap = &bgp->table_map[afi][safi];
7134 if (rmap_name) {
7135 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7136 route_map_counter_decrement(rmap->map);
7137 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7138 rmap->map = route_map_lookup_by_name(rmap_name);
7139 route_map_counter_increment(rmap->map);
7140 } else {
7141 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7142 route_map_counter_decrement(rmap->map);
7143 rmap->map = NULL;
7144 }
7145
7146 if (bgp_fibupd_safi(safi))
7147 bgp_zebra_announce_table(bgp, afi, safi);
7148
7149 return CMD_SUCCESS;
7150 }
7151
7152 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7153 const char *rmap_name)
7154 {
7155 VTY_DECLVAR_CONTEXT(bgp, bgp);
7156 struct bgp_rmap *rmap;
7157
7158 rmap = &bgp->table_map[afi][safi];
7159 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7160 route_map_counter_decrement(rmap->map);
7161 rmap->map = NULL;
7162
7163 if (bgp_fibupd_safi(safi))
7164 bgp_zebra_announce_table(bgp, afi, safi);
7165
7166 return CMD_SUCCESS;
7167 }
7168
7169 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7170 safi_t safi)
7171 {
7172 if (bgp->table_map[afi][safi].name) {
7173 vty_out(vty, " table-map %s\n",
7174 bgp->table_map[afi][safi].name);
7175 }
7176 }
7177
7178 DEFUN (bgp_table_map,
7179 bgp_table_map_cmd,
7180 "table-map WORD",
7181 "BGP table to RIB route download filter\n"
7182 "Name of the route map\n")
7183 {
7184 int idx_word = 1;
7185 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7186 argv[idx_word]->arg);
7187 }
7188 DEFUN (no_bgp_table_map,
7189 no_bgp_table_map_cmd,
7190 "no table-map WORD",
7191 NO_STR
7192 "BGP table to RIB route download filter\n"
7193 "Name of the route map\n")
7194 {
7195 int idx_word = 2;
7196 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7197 argv[idx_word]->arg);
7198 }
7199
7200 DEFPY(bgp_network,
7201 bgp_network_cmd,
7202 "[no] network \
7203 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7204 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7205 backdoor$backdoor}]",
7206 NO_STR
7207 "Specify a network to announce via BGP\n"
7208 "IPv4 prefix\n"
7209 "Network number\n"
7210 "Network mask\n"
7211 "Network mask\n"
7212 "Route-map to modify the attributes\n"
7213 "Name of the route map\n"
7214 "Label index to associate with the prefix\n"
7215 "Label index value\n"
7216 "Specify a BGP backdoor route\n")
7217 {
7218 char addr_prefix_str[BUFSIZ];
7219
7220 if (address_str) {
7221 int ret;
7222
7223 ret = netmask_str2prefix_str(address_str, netmask_str,
7224 addr_prefix_str,
7225 sizeof(addr_prefix_str));
7226 if (!ret) {
7227 vty_out(vty, "%% Inconsistent address and mask\n");
7228 return CMD_WARNING_CONFIG_FAILED;
7229 }
7230 }
7231
7232 return bgp_static_set(
7233 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7234 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7235 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7236 }
7237
7238 DEFPY(ipv6_bgp_network,
7239 ipv6_bgp_network_cmd,
7240 "[no] network X:X::X:X/M$prefix \
7241 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7242 NO_STR
7243 "Specify a network to announce via BGP\n"
7244 "IPv6 prefix\n"
7245 "Route-map to modify the attributes\n"
7246 "Name of the route map\n"
7247 "Label index to associate with the prefix\n"
7248 "Label index value\n")
7249 {
7250 return bgp_static_set(
7251 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7252 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7253 }
7254
7255 static struct bgp_aggregate *bgp_aggregate_new(void)
7256 {
7257 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7258 }
7259
7260 void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7261 {
7262 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7263 route_map_counter_decrement(aggregate->suppress_map);
7264 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7265 route_map_counter_decrement(aggregate->rmap.map);
7266 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7267 }
7268
7269 /**
7270 * Helper function to avoid repeated code: prepare variables for a
7271 * `route_map_apply` call.
7272 *
7273 * \returns `true` on route map match, otherwise `false`.
7274 */
7275 static bool aggr_suppress_map_test(struct bgp *bgp,
7276 struct bgp_aggregate *aggregate,
7277 struct bgp_path_info *pi)
7278 {
7279 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7280 route_map_result_t rmr = RMAP_DENYMATCH;
7281 struct bgp_path_info rmap_path = {};
7282 struct attr attr = {};
7283
7284 /* No route map entries created, just don't match. */
7285 if (aggregate->suppress_map == NULL)
7286 return false;
7287
7288 /* Call route map matching and return result. */
7289 attr.aspath = aspath_empty(bgp->asnotation);
7290 rmap_path.peer = bgp->peer_self;
7291 rmap_path.attr = &attr;
7292
7293 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7294 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7295 bgp->peer_self->rmap_type = 0;
7296
7297 bgp_attr_flush(&attr);
7298 aspath_unintern(&attr.aspath);
7299
7300 return rmr == RMAP_PERMITMATCH;
7301 }
7302
7303 /** Test whether the aggregation has suppressed this path or not. */
7304 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7305 struct bgp_path_info *pi)
7306 {
7307 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7308 return false;
7309
7310 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7311 }
7312
7313 /**
7314 * Suppress this path and keep the reference.
7315 *
7316 * \returns `true` if needs processing otherwise `false`.
7317 */
7318 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7319 struct bgp_path_info *pi)
7320 {
7321 struct bgp_path_info_extra *pie;
7322
7323 /* Path is already suppressed by this aggregation. */
7324 if (aggr_suppress_exists(aggregate, pi))
7325 return false;
7326
7327 pie = bgp_path_info_extra_get(pi);
7328
7329 /* This is the first suppression, allocate memory and list it. */
7330 if (pie->aggr_suppressors == NULL)
7331 pie->aggr_suppressors = list_new();
7332
7333 listnode_add(pie->aggr_suppressors, aggregate);
7334
7335 /* Only mark for processing if suppressed. */
7336 if (listcount(pie->aggr_suppressors) == 1) {
7337 if (BGP_DEBUG(update, UPDATE_OUT))
7338 zlog_debug("aggregate-address suppressing: %pFX",
7339 bgp_dest_get_prefix(pi->net));
7340
7341 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7342 return true;
7343 }
7344
7345 return false;
7346 }
7347
7348 /**
7349 * Unsuppress this path and remove the reference.
7350 *
7351 * \returns `true` if needs processing otherwise `false`.
7352 */
7353 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7354 struct bgp_path_info *pi)
7355 {
7356 /* Path wasn't suppressed. */
7357 if (!aggr_suppress_exists(aggregate, pi))
7358 return false;
7359
7360 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7361
7362 /* Unsuppress and free extra memory if last item. */
7363 if (listcount(pi->extra->aggr_suppressors) == 0) {
7364 if (BGP_DEBUG(update, UPDATE_OUT))
7365 zlog_debug("aggregate-address unsuppressing: %pFX",
7366 bgp_dest_get_prefix(pi->net));
7367
7368 list_delete(&pi->extra->aggr_suppressors);
7369 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7370 return true;
7371 }
7372
7373 return false;
7374 }
7375
7376 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7377 struct aspath *aspath,
7378 struct community *comm,
7379 struct ecommunity *ecomm,
7380 struct lcommunity *lcomm)
7381 {
7382 static struct aspath *ae = NULL;
7383 enum asnotation_mode asnotation;
7384
7385 asnotation = bgp_get_asnotation(NULL);
7386
7387 if (!ae)
7388 ae = aspath_empty(asnotation);
7389
7390 if (!pi)
7391 return false;
7392
7393 if (origin != pi->attr->origin)
7394 return false;
7395
7396 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7397 return false;
7398
7399 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7400 return false;
7401
7402 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7403 return false;
7404
7405 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7406 return false;
7407
7408 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7409 return false;
7410
7411 return true;
7412 }
7413
7414 static void bgp_aggregate_install(
7415 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7416 uint8_t origin, struct aspath *aspath, struct community *community,
7417 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7418 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7419 {
7420 struct bgp_dest *dest;
7421 struct bgp_table *table;
7422 struct bgp_path_info *pi, *orig, *new;
7423 struct attr *attr;
7424
7425 table = bgp->rib[afi][safi];
7426
7427 dest = bgp_node_get(table, p);
7428
7429 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7430 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7431 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7432 break;
7433
7434 /*
7435 * If we have paths with different MEDs, then don't install
7436 * (or uninstall) the aggregate route.
7437 */
7438 if (aggregate->match_med && aggregate->med_mismatched)
7439 goto uninstall_aggregate_route;
7440
7441 if (aggregate->count > 0) {
7442 /*
7443 * If the aggregate information has not changed
7444 * no need to re-install it again.
7445 */
7446 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7447 ecommunity, lcommunity)) {
7448 bgp_dest_unlock_node(dest);
7449
7450 if (aspath)
7451 aspath_free(aspath);
7452 if (community)
7453 community_free(&community);
7454 if (ecommunity)
7455 ecommunity_free(&ecommunity);
7456 if (lcommunity)
7457 lcommunity_free(&lcommunity);
7458
7459 return;
7460 }
7461
7462 /*
7463 * Mark the old as unusable
7464 */
7465 if (pi)
7466 bgp_path_info_delete(dest, pi);
7467
7468 attr = bgp_attr_aggregate_intern(
7469 bgp, origin, aspath, community, ecommunity, lcommunity,
7470 aggregate, atomic_aggregate, p);
7471
7472 if (!attr) {
7473 aspath_free(aspath);
7474 community_free(&community);
7475 ecommunity_free(&ecommunity);
7476 lcommunity_free(&lcommunity);
7477 bgp_dest_unlock_node(dest);
7478 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7479 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7480 zlog_debug("%s: %pFX null attribute", __func__,
7481 p);
7482 return;
7483 }
7484
7485 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7486 bgp->peer_self, attr, dest);
7487
7488 SET_FLAG(new->flags, BGP_PATH_VALID);
7489
7490 bgp_path_info_add(dest, new);
7491 bgp_process(bgp, dest, afi, safi);
7492 } else {
7493 uninstall_aggregate_route:
7494 for (pi = orig; pi; pi = pi->next)
7495 if (pi->peer == bgp->peer_self
7496 && pi->type == ZEBRA_ROUTE_BGP
7497 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7498 break;
7499
7500 /* Withdraw static BGP route from routing table. */
7501 if (pi) {
7502 bgp_path_info_delete(dest, pi);
7503 bgp_process(bgp, dest, afi, safi);
7504 }
7505 }
7506
7507 bgp_dest_unlock_node(dest);
7508 }
7509
7510 /**
7511 * Check if the current path has different MED than other known paths.
7512 *
7513 * \returns `true` if the MED matched the others else `false`.
7514 */
7515 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7516 struct bgp *bgp, struct bgp_path_info *pi)
7517 {
7518 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7519
7520 /* This is the first route being analyzed. */
7521 if (!aggregate->med_initialized) {
7522 aggregate->med_initialized = true;
7523 aggregate->med_mismatched = false;
7524 aggregate->med_matched_value = cur_med;
7525 } else {
7526 /* Check if routes with different MED showed up. */
7527 if (cur_med != aggregate->med_matched_value)
7528 aggregate->med_mismatched = true;
7529 }
7530
7531 return !aggregate->med_mismatched;
7532 }
7533
7534 /**
7535 * Initializes and tests all routes in the aggregate address path for MED
7536 * values.
7537 *
7538 * \returns `true` if all MEDs are the same otherwise `false`.
7539 */
7540 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7541 struct bgp *bgp, const struct prefix *p,
7542 afi_t afi, safi_t safi)
7543 {
7544 struct bgp_table *table = bgp->rib[afi][safi];
7545 const struct prefix *dest_p;
7546 struct bgp_dest *dest, *top;
7547 struct bgp_path_info *pi;
7548 bool med_matched = true;
7549
7550 aggregate->med_initialized = false;
7551
7552 top = bgp_node_get(table, p);
7553 for (dest = bgp_node_get(table, p); dest;
7554 dest = bgp_route_next_until(dest, top)) {
7555 dest_p = bgp_dest_get_prefix(dest);
7556 if (dest_p->prefixlen <= p->prefixlen)
7557 continue;
7558
7559 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7560 if (BGP_PATH_HOLDDOWN(pi))
7561 continue;
7562 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7563 continue;
7564 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7565 med_matched = false;
7566 break;
7567 }
7568 }
7569 if (!med_matched)
7570 break;
7571 }
7572 bgp_dest_unlock_node(top);
7573
7574 return med_matched;
7575 }
7576
7577 /**
7578 * Toggles the route suppression status for this aggregate address
7579 * configuration.
7580 */
7581 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7582 struct bgp *bgp, const struct prefix *p,
7583 afi_t afi, safi_t safi, bool suppress)
7584 {
7585 struct bgp_table *table = bgp->rib[afi][safi];
7586 const struct prefix *dest_p;
7587 struct bgp_dest *dest, *top;
7588 struct bgp_path_info *pi;
7589 bool toggle_suppression;
7590
7591 /* We've found a different MED we must revert any suppressed routes. */
7592 top = bgp_node_get(table, p);
7593 for (dest = bgp_node_get(table, p); dest;
7594 dest = bgp_route_next_until(dest, top)) {
7595 dest_p = bgp_dest_get_prefix(dest);
7596 if (dest_p->prefixlen <= p->prefixlen)
7597 continue;
7598
7599 toggle_suppression = false;
7600 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7601 if (BGP_PATH_HOLDDOWN(pi))
7602 continue;
7603 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7604 continue;
7605
7606 /* We are toggling suppression back. */
7607 if (suppress) {
7608 /* Suppress route if not suppressed already. */
7609 if (aggr_suppress_path(aggregate, pi))
7610 toggle_suppression = true;
7611 continue;
7612 }
7613
7614 /* Install route if there is no more suppression. */
7615 if (aggr_unsuppress_path(aggregate, pi))
7616 toggle_suppression = true;
7617 }
7618
7619 if (toggle_suppression)
7620 bgp_process(bgp, dest, afi, safi);
7621 }
7622 bgp_dest_unlock_node(top);
7623 }
7624
7625 /**
7626 * Aggregate address MED matching incremental test: this function is called
7627 * when the initial aggregation occurred and we are only testing a single
7628 * new path.
7629 *
7630 * In addition to testing and setting the MED validity it also installs back
7631 * suppressed routes (if summary is configured).
7632 *
7633 * Must not be called in `bgp_aggregate_route`.
7634 */
7635 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7636 struct bgp *bgp, const struct prefix *p,
7637 afi_t afi, safi_t safi,
7638 struct bgp_path_info *pi)
7639 {
7640 /* MED matching disabled. */
7641 if (!aggregate->match_med)
7642 return;
7643
7644 /* Aggregation with different MED, recheck if we have got equal MEDs
7645 * now.
7646 */
7647 if (aggregate->med_mismatched &&
7648 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7649 aggregate->summary_only)
7650 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7651 true);
7652 else
7653 bgp_aggregate_med_match(aggregate, bgp, pi);
7654
7655 /* No mismatches, just quit. */
7656 if (!aggregate->med_mismatched)
7657 return;
7658
7659 /* Route summarization is disabled. */
7660 if (!aggregate->summary_only)
7661 return;
7662
7663 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7664 }
7665
7666 /* Update an aggregate as routes are added/removed from the BGP table */
7667 bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7668 safi_t safi, struct bgp_aggregate *aggregate)
7669 {
7670 struct bgp_table *table;
7671 struct bgp_dest *top;
7672 struct bgp_dest *dest;
7673 uint8_t origin;
7674 struct aspath *aspath = NULL;
7675 struct community *community = NULL;
7676 struct ecommunity *ecommunity = NULL;
7677 struct lcommunity *lcommunity = NULL;
7678 struct bgp_path_info *pi;
7679 unsigned long match = 0;
7680 uint8_t atomic_aggregate = 0;
7681
7682 /* If the bgp instance is being deleted or self peer is deleted
7683 * then do not create aggregate route
7684 */
7685 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
7686 bgp->peer_self == NULL)
7687 return false;
7688
7689 /* Initialize and test routes for MED difference. */
7690 if (aggregate->match_med)
7691 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7692
7693 /*
7694 * Reset aggregate count: we might've been called from route map
7695 * update so in that case we must retest all more specific routes.
7696 *
7697 * \see `bgp_route_map_process_update`.
7698 */
7699 aggregate->count = 0;
7700 aggregate->incomplete_origin_count = 0;
7701 aggregate->incomplete_origin_count = 0;
7702 aggregate->egp_origin_count = 0;
7703
7704 /* ORIGIN attribute: If at least one route among routes that are
7705 aggregated has ORIGIN with the value INCOMPLETE, then the
7706 aggregated route must have the ORIGIN attribute with the value
7707 INCOMPLETE. Otherwise, if at least one route among routes that
7708 are aggregated has ORIGIN with the value EGP, then the aggregated
7709 route must have the origin attribute with the value EGP. In all
7710 other case the value of the ORIGIN attribute of the aggregated
7711 route is INTERNAL. */
7712 origin = BGP_ORIGIN_IGP;
7713
7714 table = bgp->rib[afi][safi];
7715
7716 top = bgp_node_get(table, p);
7717 for (dest = bgp_node_get(table, p); dest;
7718 dest = bgp_route_next_until(dest, top)) {
7719 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7720
7721 if (dest_p->prefixlen <= p->prefixlen)
7722 continue;
7723
7724 /* If suppress fib is enabled and route not installed
7725 * in FIB, skip the route
7726 */
7727 if (!bgp_check_advertise(bgp, dest))
7728 continue;
7729
7730 match = 0;
7731
7732 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7733 if (BGP_PATH_HOLDDOWN(pi))
7734 continue;
7735
7736 if (pi->attr->flag
7737 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7738 atomic_aggregate = 1;
7739
7740 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7741 continue;
7742
7743 /*
7744 * summary-only aggregate route suppress
7745 * aggregated route announcements.
7746 *
7747 * MED matching:
7748 * Don't create summaries if MED didn't match
7749 * otherwise neither the specific routes and the
7750 * aggregation will be announced.
7751 */
7752 if (aggregate->summary_only
7753 && AGGREGATE_MED_VALID(aggregate)) {
7754 if (aggr_suppress_path(aggregate, pi))
7755 match++;
7756 }
7757
7758 /*
7759 * Suppress more specific routes that match the route
7760 * map results.
7761 *
7762 * MED matching:
7763 * Don't suppress routes if MED matching is enabled and
7764 * it mismatched otherwise we might end up with no
7765 * routes for this path.
7766 */
7767 if (aggregate->suppress_map_name
7768 && AGGREGATE_MED_VALID(aggregate)
7769 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7770 if (aggr_suppress_path(aggregate, pi))
7771 match++;
7772 }
7773
7774 aggregate->count++;
7775
7776 /*
7777 * If at least one route among routes that are
7778 * aggregated has ORIGIN with the value INCOMPLETE,
7779 * then the aggregated route MUST have the ORIGIN
7780 * attribute with the value INCOMPLETE. Otherwise, if
7781 * at least one route among routes that are aggregated
7782 * has ORIGIN with the value EGP, then the aggregated
7783 * route MUST have the ORIGIN attribute with the value
7784 * EGP.
7785 */
7786 switch (pi->attr->origin) {
7787 case BGP_ORIGIN_INCOMPLETE:
7788 aggregate->incomplete_origin_count++;
7789 break;
7790 case BGP_ORIGIN_EGP:
7791 aggregate->egp_origin_count++;
7792 break;
7793 default:
7794 /*Do nothing.
7795 */
7796 break;
7797 }
7798
7799 if (!aggregate->as_set)
7800 continue;
7801
7802 /*
7803 * as-set aggregate route generate origin, as path,
7804 * and community aggregation.
7805 */
7806 /* Compute aggregate route's as-path.
7807 */
7808 bgp_compute_aggregate_aspath_hash(aggregate,
7809 pi->attr->aspath);
7810
7811 /* Compute aggregate route's community.
7812 */
7813 if (bgp_attr_get_community(pi->attr))
7814 bgp_compute_aggregate_community_hash(
7815 aggregate,
7816 bgp_attr_get_community(pi->attr));
7817
7818 /* Compute aggregate route's extended community.
7819 */
7820 if (bgp_attr_get_ecommunity(pi->attr))
7821 bgp_compute_aggregate_ecommunity_hash(
7822 aggregate,
7823 bgp_attr_get_ecommunity(pi->attr));
7824
7825 /* Compute aggregate route's large community.
7826 */
7827 if (bgp_attr_get_lcommunity(pi->attr))
7828 bgp_compute_aggregate_lcommunity_hash(
7829 aggregate,
7830 bgp_attr_get_lcommunity(pi->attr));
7831 }
7832 if (match)
7833 bgp_process(bgp, dest, afi, safi);
7834 }
7835 if (aggregate->as_set) {
7836 bgp_compute_aggregate_aspath_val(aggregate);
7837 bgp_compute_aggregate_community_val(aggregate);
7838 bgp_compute_aggregate_ecommunity_val(aggregate);
7839 bgp_compute_aggregate_lcommunity_val(aggregate);
7840 }
7841
7842
7843 bgp_dest_unlock_node(top);
7844
7845
7846 if (aggregate->incomplete_origin_count > 0)
7847 origin = BGP_ORIGIN_INCOMPLETE;
7848 else if (aggregate->egp_origin_count > 0)
7849 origin = BGP_ORIGIN_EGP;
7850
7851 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7852 origin = aggregate->origin;
7853
7854 if (aggregate->as_set) {
7855 if (aggregate->aspath)
7856 /* Retrieve aggregate route's as-path.
7857 */
7858 aspath = aspath_dup(aggregate->aspath);
7859
7860 if (aggregate->community)
7861 /* Retrieve aggregate route's community.
7862 */
7863 community = community_dup(aggregate->community);
7864
7865 if (aggregate->ecommunity)
7866 /* Retrieve aggregate route's ecommunity.
7867 */
7868 ecommunity = ecommunity_dup(aggregate->ecommunity);
7869
7870 if (aggregate->lcommunity)
7871 /* Retrieve aggregate route's lcommunity.
7872 */
7873 lcommunity = lcommunity_dup(aggregate->lcommunity);
7874 }
7875
7876 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7877 ecommunity, lcommunity, atomic_aggregate,
7878 aggregate);
7879
7880 return true;
7881 }
7882
7883 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7884 safi_t safi, struct bgp_aggregate *aggregate)
7885 {
7886 struct bgp_table *table;
7887 struct bgp_dest *top;
7888 struct bgp_dest *dest;
7889 struct bgp_path_info *pi;
7890 unsigned long match;
7891
7892 table = bgp->rib[afi][safi];
7893
7894 /* If routes exists below this node, generate aggregate routes. */
7895 top = bgp_node_get(table, p);
7896 for (dest = bgp_node_get(table, p); dest;
7897 dest = bgp_route_next_until(dest, top)) {
7898 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7899
7900 if (dest_p->prefixlen <= p->prefixlen)
7901 continue;
7902 match = 0;
7903
7904 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7905 if (BGP_PATH_HOLDDOWN(pi))
7906 continue;
7907
7908 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7909 continue;
7910
7911 /*
7912 * This route is suppressed: attempt to unsuppress it.
7913 *
7914 * `aggr_unsuppress_path` will fail if this particular
7915 * aggregate route was not the suppressor.
7916 */
7917 if (pi->extra && pi->extra->aggr_suppressors &&
7918 listcount(pi->extra->aggr_suppressors)) {
7919 if (aggr_unsuppress_path(aggregate, pi))
7920 match++;
7921 }
7922
7923 aggregate->count--;
7924
7925 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7926 aggregate->incomplete_origin_count--;
7927 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7928 aggregate->egp_origin_count--;
7929
7930 if (aggregate->as_set) {
7931 /* Remove as-path from aggregate.
7932 */
7933 bgp_remove_aspath_from_aggregate_hash(
7934 aggregate,
7935 pi->attr->aspath);
7936
7937 if (bgp_attr_get_community(pi->attr))
7938 /* Remove community from aggregate.
7939 */
7940 bgp_remove_comm_from_aggregate_hash(
7941 aggregate,
7942 bgp_attr_get_community(
7943 pi->attr));
7944
7945 if (bgp_attr_get_ecommunity(pi->attr))
7946 /* Remove ecommunity from aggregate.
7947 */
7948 bgp_remove_ecomm_from_aggregate_hash(
7949 aggregate,
7950 bgp_attr_get_ecommunity(
7951 pi->attr));
7952
7953 if (bgp_attr_get_lcommunity(pi->attr))
7954 /* Remove lcommunity from aggregate.
7955 */
7956 bgp_remove_lcomm_from_aggregate_hash(
7957 aggregate,
7958 bgp_attr_get_lcommunity(
7959 pi->attr));
7960 }
7961 }
7962
7963 /* If this node was suppressed, process the change. */
7964 if (match)
7965 bgp_process(bgp, dest, afi, safi);
7966 }
7967 if (aggregate->as_set) {
7968 aspath_free(aggregate->aspath);
7969 aggregate->aspath = NULL;
7970 if (aggregate->community)
7971 community_free(&aggregate->community);
7972 if (aggregate->ecommunity)
7973 ecommunity_free(&aggregate->ecommunity);
7974 if (aggregate->lcommunity)
7975 lcommunity_free(&aggregate->lcommunity);
7976 }
7977
7978 bgp_dest_unlock_node(top);
7979 }
7980
7981 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7982 const struct prefix *aggr_p,
7983 struct bgp_path_info *pinew, afi_t afi,
7984 safi_t safi,
7985 struct bgp_aggregate *aggregate)
7986 {
7987 uint8_t origin;
7988 struct aspath *aspath = NULL;
7989 uint8_t atomic_aggregate = 0;
7990 struct community *community = NULL;
7991 struct ecommunity *ecommunity = NULL;
7992 struct lcommunity *lcommunity = NULL;
7993
7994 /* If the bgp instance is being deleted or self peer is deleted
7995 * then do not create aggregate route
7996 */
7997 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7998 || (bgp->peer_self == NULL))
7999 return;
8000
8001 /* ORIGIN attribute: If at least one route among routes that are
8002 * aggregated has ORIGIN with the value INCOMPLETE, then the
8003 * aggregated route must have the ORIGIN attribute with the value
8004 * INCOMPLETE. Otherwise, if at least one route among routes that
8005 * are aggregated has ORIGIN with the value EGP, then the aggregated
8006 * route must have the origin attribute with the value EGP. In all
8007 * other case the value of the ORIGIN attribute of the aggregated
8008 * route is INTERNAL.
8009 */
8010 origin = BGP_ORIGIN_IGP;
8011
8012 aggregate->count++;
8013
8014 /*
8015 * This must be called before `summary` check to avoid
8016 * "suppressing" twice.
8017 */
8018 if (aggregate->match_med)
8019 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8020 pinew);
8021
8022 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8023 aggr_suppress_path(aggregate, pinew);
8024
8025 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8026 && aggr_suppress_map_test(bgp, aggregate, pinew))
8027 aggr_suppress_path(aggregate, pinew);
8028
8029 switch (pinew->attr->origin) {
8030 case BGP_ORIGIN_INCOMPLETE:
8031 aggregate->incomplete_origin_count++;
8032 break;
8033 case BGP_ORIGIN_EGP:
8034 aggregate->egp_origin_count++;
8035 break;
8036 default:
8037 /* Do nothing.
8038 */
8039 break;
8040 }
8041
8042 if (aggregate->incomplete_origin_count > 0)
8043 origin = BGP_ORIGIN_INCOMPLETE;
8044 else if (aggregate->egp_origin_count > 0)
8045 origin = BGP_ORIGIN_EGP;
8046
8047 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8048 origin = aggregate->origin;
8049
8050 if (aggregate->as_set) {
8051 /* Compute aggregate route's as-path.
8052 */
8053 bgp_compute_aggregate_aspath(aggregate,
8054 pinew->attr->aspath);
8055
8056 /* Compute aggregate route's community.
8057 */
8058 if (bgp_attr_get_community(pinew->attr))
8059 bgp_compute_aggregate_community(
8060 aggregate, bgp_attr_get_community(pinew->attr));
8061
8062 /* Compute aggregate route's extended community.
8063 */
8064 if (bgp_attr_get_ecommunity(pinew->attr))
8065 bgp_compute_aggregate_ecommunity(
8066 aggregate,
8067 bgp_attr_get_ecommunity(pinew->attr));
8068
8069 /* Compute aggregate route's large community.
8070 */
8071 if (bgp_attr_get_lcommunity(pinew->attr))
8072 bgp_compute_aggregate_lcommunity(
8073 aggregate,
8074 bgp_attr_get_lcommunity(pinew->attr));
8075
8076 /* Retrieve aggregate route's as-path.
8077 */
8078 if (aggregate->aspath)
8079 aspath = aspath_dup(aggregate->aspath);
8080
8081 /* Retrieve aggregate route's community.
8082 */
8083 if (aggregate->community)
8084 community = community_dup(aggregate->community);
8085
8086 /* Retrieve aggregate route's ecommunity.
8087 */
8088 if (aggregate->ecommunity)
8089 ecommunity = ecommunity_dup(aggregate->ecommunity);
8090
8091 /* Retrieve aggregate route's lcommunity.
8092 */
8093 if (aggregate->lcommunity)
8094 lcommunity = lcommunity_dup(aggregate->lcommunity);
8095 }
8096
8097 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8098 aspath, community, ecommunity,
8099 lcommunity, atomic_aggregate, aggregate);
8100 }
8101
8102 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8103 safi_t safi,
8104 struct bgp_path_info *pi,
8105 struct bgp_aggregate *aggregate,
8106 const struct prefix *aggr_p)
8107 {
8108 uint8_t origin;
8109 struct aspath *aspath = NULL;
8110 uint8_t atomic_aggregate = 0;
8111 struct community *community = NULL;
8112 struct ecommunity *ecommunity = NULL;
8113 struct lcommunity *lcommunity = NULL;
8114 unsigned long match = 0;
8115
8116 /* If the bgp instance is being deleted or self peer is deleted
8117 * then do not create aggregate route
8118 */
8119 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8120 || (bgp->peer_self == NULL))
8121 return;
8122
8123 if (BGP_PATH_HOLDDOWN(pi))
8124 return;
8125
8126 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8127 return;
8128
8129 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8130 if (aggr_unsuppress_path(aggregate, pi))
8131 match++;
8132
8133 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8134 && aggr_suppress_map_test(bgp, aggregate, pi))
8135 if (aggr_unsuppress_path(aggregate, pi))
8136 match++;
8137
8138 /*
8139 * This must be called after `summary`, `suppress-map` check to avoid
8140 * "unsuppressing" twice.
8141 */
8142 if (aggregate->match_med)
8143 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8144
8145 if (aggregate->count > 0)
8146 aggregate->count--;
8147
8148 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8149 aggregate->incomplete_origin_count--;
8150 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8151 aggregate->egp_origin_count--;
8152
8153 if (aggregate->as_set) {
8154 /* Remove as-path from aggregate.
8155 */
8156 bgp_remove_aspath_from_aggregate(aggregate,
8157 pi->attr->aspath);
8158
8159 if (bgp_attr_get_community(pi->attr))
8160 /* Remove community from aggregate.
8161 */
8162 bgp_remove_community_from_aggregate(
8163 aggregate, bgp_attr_get_community(pi->attr));
8164
8165 if (bgp_attr_get_ecommunity(pi->attr))
8166 /* Remove ecommunity from aggregate.
8167 */
8168 bgp_remove_ecommunity_from_aggregate(
8169 aggregate, bgp_attr_get_ecommunity(pi->attr));
8170
8171 if (bgp_attr_get_lcommunity(pi->attr))
8172 /* Remove lcommunity from aggregate.
8173 */
8174 bgp_remove_lcommunity_from_aggregate(
8175 aggregate, bgp_attr_get_lcommunity(pi->attr));
8176 }
8177
8178 /* If this node was suppressed, process the change. */
8179 if (match)
8180 bgp_process(bgp, pi->net, afi, safi);
8181
8182 origin = BGP_ORIGIN_IGP;
8183 if (aggregate->incomplete_origin_count > 0)
8184 origin = BGP_ORIGIN_INCOMPLETE;
8185 else if (aggregate->egp_origin_count > 0)
8186 origin = BGP_ORIGIN_EGP;
8187
8188 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8189 origin = aggregate->origin;
8190
8191 if (aggregate->as_set) {
8192 /* Retrieve aggregate route's as-path.
8193 */
8194 if (aggregate->aspath)
8195 aspath = aspath_dup(aggregate->aspath);
8196
8197 /* Retrieve aggregate route's community.
8198 */
8199 if (aggregate->community)
8200 community = community_dup(aggregate->community);
8201
8202 /* Retrieve aggregate route's ecommunity.
8203 */
8204 if (aggregate->ecommunity)
8205 ecommunity = ecommunity_dup(aggregate->ecommunity);
8206
8207 /* Retrieve aggregate route's lcommunity.
8208 */
8209 if (aggregate->lcommunity)
8210 lcommunity = lcommunity_dup(aggregate->lcommunity);
8211 }
8212
8213 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8214 aspath, community, ecommunity,
8215 lcommunity, atomic_aggregate, aggregate);
8216 }
8217
8218 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8219 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8220 {
8221 struct bgp_dest *child;
8222 struct bgp_dest *dest;
8223 struct bgp_aggregate *aggregate;
8224 struct bgp_table *table;
8225
8226 table = bgp->aggregate[afi][safi];
8227
8228 /* No aggregates configured. */
8229 if (bgp_table_top_nolock(table) == NULL)
8230 return;
8231
8232 if (p->prefixlen == 0)
8233 return;
8234
8235 if (BGP_PATH_HOLDDOWN(pi))
8236 return;
8237
8238 /* If suppress fib is enabled and route not installed
8239 * in FIB, do not update the aggregate route
8240 */
8241 if (!bgp_check_advertise(bgp, pi->net))
8242 return;
8243
8244 child = bgp_node_get(table, p);
8245
8246 /* Aggregate address configuration check. */
8247 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8248 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8249
8250 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8251 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8252 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8253 aggregate);
8254 }
8255 }
8256 bgp_dest_unlock_node(child);
8257 }
8258
8259 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8260 struct bgp_path_info *del, afi_t afi, safi_t safi)
8261 {
8262 struct bgp_dest *child;
8263 struct bgp_dest *dest;
8264 struct bgp_aggregate *aggregate;
8265 struct bgp_table *table;
8266
8267 table = bgp->aggregate[afi][safi];
8268
8269 /* No aggregates configured. */
8270 if (bgp_table_top_nolock(table) == NULL)
8271 return;
8272
8273 if (p->prefixlen == 0)
8274 return;
8275
8276 child = bgp_node_get(table, p);
8277
8278 /* Aggregate address configuration check. */
8279 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8280 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8281
8282 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8283 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8284 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8285 aggregate, dest_p);
8286 }
8287 }
8288 bgp_dest_unlock_node(child);
8289 }
8290
8291 /* Aggregate route attribute. */
8292 #define AGGREGATE_SUMMARY_ONLY 1
8293 #define AGGREGATE_AS_SET 1
8294 #define AGGREGATE_AS_UNSET 0
8295
8296 static const char *bgp_origin2str(uint8_t origin)
8297 {
8298 switch (origin) {
8299 case BGP_ORIGIN_IGP:
8300 return "igp";
8301 case BGP_ORIGIN_EGP:
8302 return "egp";
8303 case BGP_ORIGIN_INCOMPLETE:
8304 return "incomplete";
8305 }
8306 return "n/a";
8307 }
8308
8309 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8310 {
8311 switch (v_state) {
8312 case RPKI_NOT_BEING_USED:
8313 return "not used";
8314 case RPKI_VALID:
8315 return "valid";
8316 case RPKI_NOTFOUND:
8317 return "not found";
8318 case RPKI_INVALID:
8319 return "invalid";
8320 }
8321
8322 assert(!"We should never get here this is a dev escape");
8323 return "ERROR";
8324 }
8325
8326 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8327 afi_t afi, safi_t safi)
8328 {
8329 VTY_DECLVAR_CONTEXT(bgp, bgp);
8330 int ret;
8331 struct prefix p;
8332 struct bgp_dest *dest;
8333 struct bgp_aggregate *aggregate;
8334
8335 /* Convert string to prefix structure. */
8336 ret = str2prefix(prefix_str, &p);
8337 if (!ret) {
8338 vty_out(vty, "Malformed prefix\n");
8339 return CMD_WARNING_CONFIG_FAILED;
8340 }
8341 apply_mask(&p);
8342
8343 /* Old configuration check. */
8344 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8345 if (!dest) {
8346 vty_out(vty,
8347 "%% There is no aggregate-address configuration.\n");
8348 return CMD_WARNING_CONFIG_FAILED;
8349 }
8350
8351 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8352 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8353 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8354 NULL, NULL, 0, aggregate);
8355
8356 /* Unlock aggregate address configuration. */
8357 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8358
8359 bgp_free_aggregate_info(aggregate);
8360 bgp_dest_unlock_node(dest);
8361 bgp_dest_unlock_node(dest);
8362
8363 return CMD_SUCCESS;
8364 }
8365
8366 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8367 safi_t safi, const char *rmap,
8368 uint8_t summary_only, uint8_t as_set,
8369 uint8_t origin, bool match_med,
8370 const char *suppress_map)
8371 {
8372 VTY_DECLVAR_CONTEXT(bgp, bgp);
8373 int ret;
8374 struct prefix p;
8375 struct bgp_dest *dest;
8376 struct bgp_aggregate *aggregate;
8377 uint8_t as_set_new = as_set;
8378
8379 if (suppress_map && summary_only) {
8380 vty_out(vty,
8381 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8382 return CMD_WARNING_CONFIG_FAILED;
8383 }
8384
8385 /* Convert string to prefix structure. */
8386 ret = str2prefix(prefix_str, &p);
8387 if (!ret) {
8388 vty_out(vty, "Malformed prefix\n");
8389 return CMD_WARNING_CONFIG_FAILED;
8390 }
8391 apply_mask(&p);
8392
8393 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8394 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8395 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8396 prefix_str);
8397 return CMD_WARNING_CONFIG_FAILED;
8398 }
8399
8400 /* Old configuration check. */
8401 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8402 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8403
8404 if (aggregate) {
8405 vty_out(vty, "There is already same aggregate network.\n");
8406 /* try to remove the old entry */
8407 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8408 if (ret) {
8409 vty_out(vty, "Error deleting aggregate.\n");
8410 bgp_dest_unlock_node(dest);
8411 return CMD_WARNING_CONFIG_FAILED;
8412 }
8413 }
8414
8415 /* Make aggregate address structure. */
8416 aggregate = bgp_aggregate_new();
8417 aggregate->summary_only = summary_only;
8418 aggregate->match_med = match_med;
8419
8420 /* Network operators MUST NOT locally generate any new
8421 * announcements containing AS_SET or AS_CONFED_SET. If they have
8422 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8423 * SHOULD withdraw those routes and re-announce routes for the
8424 * aggregate or component prefixes (i.e., the more-specific routes
8425 * subsumed by the previously aggregated route) without AS_SET
8426 * or AS_CONFED_SET in the updates.
8427 */
8428 if (bgp->reject_as_sets) {
8429 if (as_set == AGGREGATE_AS_SET) {
8430 as_set_new = AGGREGATE_AS_UNSET;
8431 zlog_warn(
8432 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8433 __func__);
8434 vty_out(vty,
8435 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8436 }
8437 }
8438
8439 aggregate->as_set = as_set_new;
8440 aggregate->safi = safi;
8441 /* Override ORIGIN attribute if defined.
8442 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8443 * to IGP which is not what rfc4271 says.
8444 * This enables the same behavior, optionally.
8445 */
8446 aggregate->origin = origin;
8447
8448 if (rmap) {
8449 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8450 route_map_counter_decrement(aggregate->rmap.map);
8451 aggregate->rmap.name =
8452 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8453 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8454 route_map_counter_increment(aggregate->rmap.map);
8455 }
8456
8457 if (suppress_map) {
8458 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8459 route_map_counter_decrement(aggregate->suppress_map);
8460
8461 aggregate->suppress_map_name =
8462 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8463 aggregate->suppress_map =
8464 route_map_lookup_by_name(aggregate->suppress_map_name);
8465 route_map_counter_increment(aggregate->suppress_map);
8466 }
8467
8468 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8469
8470 /* Aggregate address insert into BGP routing table. */
8471 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8472 bgp_aggregate_free(aggregate);
8473 bgp_dest_unlock_node(dest);
8474 }
8475
8476 return CMD_SUCCESS;
8477 }
8478
8479 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8480 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8481 "as-set$as_set_s"
8482 "|summary-only$summary_only"
8483 "|route-map RMAP_NAME$rmap_name"
8484 "|origin <egp|igp|incomplete>$origin_s"
8485 "|matching-MED-only$match_med"
8486 "|suppress-map RMAP_NAME$suppress_map"
8487 "}]",
8488 NO_STR
8489 "Configure BGP aggregate entries\n"
8490 "Aggregate prefix\n"
8491 "Aggregate address\n"
8492 "Aggregate mask\n"
8493 "Generate AS set path information\n"
8494 "Filter more specific routes from updates\n"
8495 "Apply route map to aggregate network\n"
8496 "Route map name\n"
8497 "BGP origin code\n"
8498 "Remote EGP\n"
8499 "Local IGP\n"
8500 "Unknown heritage\n"
8501 "Only aggregate routes with matching MED\n"
8502 "Suppress the selected more specific routes\n"
8503 "Route map with the route selectors\n")
8504 {
8505 const char *prefix_s = NULL;
8506 safi_t safi = bgp_node_safi(vty);
8507 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8508 int as_set = AGGREGATE_AS_UNSET;
8509 char prefix_buf[PREFIX2STR_BUFFER];
8510
8511 if (addr_str) {
8512 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8513 sizeof(prefix_buf))
8514 == 0) {
8515 vty_out(vty, "%% Inconsistent address and mask\n");
8516 return CMD_WARNING_CONFIG_FAILED;
8517 }
8518 prefix_s = prefix_buf;
8519 } else
8520 prefix_s = prefix_str;
8521
8522 if (origin_s) {
8523 if (strcmp(origin_s, "egp") == 0)
8524 origin = BGP_ORIGIN_EGP;
8525 else if (strcmp(origin_s, "igp") == 0)
8526 origin = BGP_ORIGIN_IGP;
8527 else if (strcmp(origin_s, "incomplete") == 0)
8528 origin = BGP_ORIGIN_INCOMPLETE;
8529 }
8530
8531 if (as_set_s)
8532 as_set = AGGREGATE_AS_SET;
8533
8534 /* Handle configuration removal, otherwise installation. */
8535 if (no)
8536 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8537
8538 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8539 summary_only != NULL, as_set, origin,
8540 match_med != NULL, suppress_map);
8541 }
8542
8543 void bgp_free_aggregate_info(struct bgp_aggregate *aggregate)
8544 {
8545 if (aggregate->community)
8546 community_free(&aggregate->community);
8547
8548 hash_clean_and_free(&aggregate->community_hash,
8549 bgp_aggr_community_remove);
8550
8551 if (aggregate->ecommunity)
8552 ecommunity_free(&aggregate->ecommunity);
8553
8554 hash_clean_and_free(&aggregate->ecommunity_hash,
8555 bgp_aggr_ecommunity_remove);
8556
8557 if (aggregate->lcommunity)
8558 lcommunity_free(&aggregate->lcommunity);
8559
8560 hash_clean_and_free(&aggregate->lcommunity_hash,
8561 bgp_aggr_lcommunity_remove);
8562
8563 if (aggregate->aspath)
8564 aspath_free(aggregate->aspath);
8565
8566 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8567
8568 bgp_aggregate_free(aggregate);
8569 }
8570
8571 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8572 "[no] aggregate-address X:X::X:X/M$prefix [{"
8573 "as-set$as_set_s"
8574 "|summary-only$summary_only"
8575 "|route-map RMAP_NAME$rmap_name"
8576 "|origin <egp|igp|incomplete>$origin_s"
8577 "|matching-MED-only$match_med"
8578 "|suppress-map RMAP_NAME$suppress_map"
8579 "}]",
8580 NO_STR
8581 "Configure BGP aggregate entries\n"
8582 "Aggregate prefix\n"
8583 "Generate AS set path information\n"
8584 "Filter more specific routes from updates\n"
8585 "Apply route map to aggregate network\n"
8586 "Route map name\n"
8587 "BGP origin code\n"
8588 "Remote EGP\n"
8589 "Local IGP\n"
8590 "Unknown heritage\n"
8591 "Only aggregate routes with matching MED\n"
8592 "Suppress the selected more specific routes\n"
8593 "Route map with the route selectors\n")
8594 {
8595 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8596 int as_set = AGGREGATE_AS_UNSET;
8597
8598 if (origin_s) {
8599 if (strcmp(origin_s, "egp") == 0)
8600 origin = BGP_ORIGIN_EGP;
8601 else if (strcmp(origin_s, "igp") == 0)
8602 origin = BGP_ORIGIN_IGP;
8603 else if (strcmp(origin_s, "incomplete") == 0)
8604 origin = BGP_ORIGIN_INCOMPLETE;
8605 }
8606
8607 if (as_set_s)
8608 as_set = AGGREGATE_AS_SET;
8609
8610 /* Handle configuration removal, otherwise installation. */
8611 if (no)
8612 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8613 SAFI_UNICAST);
8614
8615 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8616 rmap_name, summary_only != NULL, as_set,
8617 origin, match_med != NULL, suppress_map);
8618 }
8619
8620 /* Redistribute route treatment. */
8621 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8622 const union g_addr *nexthop, ifindex_t ifindex,
8623 enum nexthop_types_t nhtype, uint8_t distance,
8624 enum blackhole_type bhtype, uint32_t metric,
8625 uint8_t type, unsigned short instance,
8626 route_tag_t tag)
8627 {
8628 struct bgp_path_info *new;
8629 struct bgp_path_info *bpi;
8630 struct bgp_path_info rmap_path;
8631 struct bgp_dest *bn;
8632 struct attr attr;
8633 struct attr *new_attr;
8634 afi_t afi;
8635 route_map_result_t ret;
8636 struct bgp_redist *red;
8637
8638 /* Make default attribute. */
8639 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8640 /*
8641 * This must not be NULL to satisfy Coverity SA
8642 */
8643 assert(attr.aspath);
8644
8645 switch (nhtype) {
8646 case NEXTHOP_TYPE_IFINDEX:
8647 switch (p->family) {
8648 case AF_INET:
8649 attr.nexthop.s_addr = INADDR_ANY;
8650 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8651 break;
8652 case AF_INET6:
8653 memset(&attr.mp_nexthop_global, 0,
8654 sizeof(attr.mp_nexthop_global));
8655 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8656 break;
8657 }
8658 break;
8659 case NEXTHOP_TYPE_IPV4:
8660 case NEXTHOP_TYPE_IPV4_IFINDEX:
8661 attr.nexthop = nexthop->ipv4;
8662 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8663 break;
8664 case NEXTHOP_TYPE_IPV6:
8665 case NEXTHOP_TYPE_IPV6_IFINDEX:
8666 attr.mp_nexthop_global = nexthop->ipv6;
8667 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8668 break;
8669 case NEXTHOP_TYPE_BLACKHOLE:
8670 switch (p->family) {
8671 case AF_INET:
8672 attr.nexthop.s_addr = INADDR_ANY;
8673 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8674 break;
8675 case AF_INET6:
8676 memset(&attr.mp_nexthop_global, 0,
8677 sizeof(attr.mp_nexthop_global));
8678 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8679 break;
8680 }
8681 attr.bh_type = bhtype;
8682 break;
8683 }
8684 attr.nh_type = nhtype;
8685 attr.nh_ifindex = ifindex;
8686
8687 attr.med = metric;
8688 attr.distance = distance;
8689 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8690 attr.tag = tag;
8691
8692 if (metric)
8693 bgp_attr_set_aigp_metric(&attr, metric);
8694
8695 afi = family2afi(p->family);
8696
8697 red = bgp_redist_lookup(bgp, afi, type, instance);
8698 if (red) {
8699 struct attr attr_new;
8700
8701 /* Copy attribute for modification. */
8702 attr_new = attr;
8703
8704 if (red->redist_metric_flag) {
8705 attr_new.med = red->redist_metric;
8706 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8707 }
8708
8709 /* Apply route-map. */
8710 if (red->rmap.name) {
8711 memset(&rmap_path, 0, sizeof(rmap_path));
8712 rmap_path.peer = bgp->peer_self;
8713 rmap_path.attr = &attr_new;
8714
8715 SET_FLAG(bgp->peer_self->rmap_type,
8716 PEER_RMAP_TYPE_REDISTRIBUTE);
8717
8718 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8719
8720 bgp->peer_self->rmap_type = 0;
8721
8722 if (ret == RMAP_DENYMATCH) {
8723 /* Free uninterned attribute. */
8724 bgp_attr_flush(&attr_new);
8725
8726 /* Unintern original. */
8727 aspath_unintern(&attr.aspath);
8728 bgp_redistribute_delete(bgp, p, type, instance);
8729 return;
8730 }
8731 }
8732
8733 if (bgp_in_graceful_shutdown(bgp))
8734 bgp_attr_add_gshut_community(&attr_new);
8735
8736 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8737 SAFI_UNICAST, p, NULL);
8738
8739 new_attr = bgp_attr_intern(&attr_new);
8740
8741 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8742 if (bpi->peer == bgp->peer_self
8743 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8744 break;
8745
8746 if (bpi) {
8747 /* Ensure the (source route) type is updated. */
8748 bpi->type = type;
8749 if (attrhash_cmp(bpi->attr, new_attr)
8750 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8751 bgp_attr_unintern(&new_attr);
8752 aspath_unintern(&attr.aspath);
8753 bgp_dest_unlock_node(bn);
8754 return;
8755 } else {
8756 /* The attribute is changed. */
8757 bgp_path_info_set_flag(bn, bpi,
8758 BGP_PATH_ATTR_CHANGED);
8759
8760 /* Rewrite BGP route information. */
8761 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8762 bgp_path_info_restore(bn, bpi);
8763 else
8764 bgp_aggregate_decrement(
8765 bgp, p, bpi, afi, SAFI_UNICAST);
8766 bgp_attr_unintern(&bpi->attr);
8767 bpi->attr = new_attr;
8768 bpi->uptime = monotime(NULL);
8769
8770 /* Process change. */
8771 bgp_aggregate_increment(bgp, p, bpi, afi,
8772 SAFI_UNICAST);
8773 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8774 bgp_dest_unlock_node(bn);
8775 aspath_unintern(&attr.aspath);
8776
8777 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8778 || (bgp->inst_type
8779 == BGP_INSTANCE_TYPE_DEFAULT)) {
8780
8781 vpn_leak_from_vrf_update(
8782 bgp_get_default(), bgp, bpi);
8783 }
8784 return;
8785 }
8786 }
8787
8788 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8789 bgp->peer_self, new_attr, bn);
8790 SET_FLAG(new->flags, BGP_PATH_VALID);
8791
8792 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8793 bgp_path_info_add(bn, new);
8794 bgp_dest_unlock_node(bn);
8795 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8796 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8797
8798 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8799 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8800
8801 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8802 }
8803 }
8804
8805 /* Unintern original. */
8806 aspath_unintern(&attr.aspath);
8807 }
8808
8809 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8810 unsigned short instance)
8811 {
8812 afi_t afi;
8813 struct bgp_dest *dest;
8814 struct bgp_path_info *pi;
8815 struct bgp_redist *red;
8816
8817 afi = family2afi(p->family);
8818
8819 red = bgp_redist_lookup(bgp, afi, type, instance);
8820 if (red) {
8821 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8822 SAFI_UNICAST, p, NULL);
8823
8824 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8825 if (pi->peer == bgp->peer_self && pi->type == type)
8826 break;
8827
8828 if (pi) {
8829 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8830 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8831
8832 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8833 bgp, pi);
8834 }
8835 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8836 bgp_path_info_delete(dest, pi);
8837 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8838 }
8839 bgp_dest_unlock_node(dest);
8840 }
8841 }
8842
8843 /* Withdraw specified route type's route. */
8844 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8845 unsigned short instance)
8846 {
8847 struct bgp_dest *dest;
8848 struct bgp_path_info *pi;
8849 struct bgp_table *table;
8850
8851 table = bgp->rib[afi][SAFI_UNICAST];
8852
8853 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8854 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8855 if (pi->peer == bgp->peer_self && pi->type == type
8856 && pi->instance == instance)
8857 break;
8858
8859 if (pi) {
8860 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8861 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8862
8863 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8864 bgp, pi);
8865 }
8866 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8867 pi, afi, SAFI_UNICAST);
8868 bgp_path_info_delete(dest, pi);
8869 if (!CHECK_FLAG(bgp->flags,
8870 BGP_FLAG_DELETE_IN_PROGRESS))
8871 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8872 else
8873 bgp_path_info_reap(dest, pi);
8874 }
8875 }
8876 }
8877
8878 /* Static function to display route. */
8879 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8880 struct vty *vty, json_object *json, bool wide)
8881 {
8882 int len = 0;
8883 char buf[INET6_ADDRSTRLEN];
8884
8885 if (p->family == AF_INET) {
8886 if (!json) {
8887 len = vty_out(vty, "%pFX", p);
8888 } else {
8889 json_object_string_add(json, "prefix",
8890 inet_ntop(p->family,
8891 &p->u.prefix, buf,
8892 sizeof(buf)));
8893 json_object_int_add(json, "prefixLen", p->prefixlen);
8894 json_object_string_addf(json, "network", "%pFX", p);
8895 json_object_int_add(json, "version", dest->version);
8896 }
8897 } else if (p->family == AF_ETHERNET) {
8898 len = vty_out(vty, "%pFX", p);
8899 } else if (p->family == AF_EVPN) {
8900 if (!json)
8901 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8902 else
8903 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8904 } else if (p->family == AF_FLOWSPEC) {
8905 route_vty_out_flowspec(vty, p, NULL,
8906 json ?
8907 NLRI_STRING_FORMAT_JSON_SIMPLE :
8908 NLRI_STRING_FORMAT_MIN, json);
8909 } else {
8910 if (!json)
8911 len = vty_out(vty, "%pFX", p);
8912 else {
8913 json_object_string_add(json, "prefix",
8914 inet_ntop(p->family,
8915 &p->u.prefix, buf,
8916 sizeof(buf)));
8917 json_object_int_add(json, "prefixLen", p->prefixlen);
8918 json_object_string_addf(json, "network", "%pFX", p);
8919 json_object_int_add(json, "version", dest->version);
8920 }
8921 }
8922
8923 if (!json) {
8924 len = wide ? (45 - len) : (17 - len);
8925 if (len < 1)
8926 vty_out(vty, "\n%*s", 20, " ");
8927 else
8928 vty_out(vty, "%*s", len, " ");
8929 }
8930 }
8931
8932 enum bgp_display_type {
8933 normal_list,
8934 };
8935
8936 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8937 {
8938 switch (reason) {
8939 case bgp_path_selection_none:
8940 return "Nothing to Select";
8941 case bgp_path_selection_first:
8942 return "First path received";
8943 case bgp_path_selection_evpn_sticky_mac:
8944 return "EVPN Sticky Mac";
8945 case bgp_path_selection_evpn_seq:
8946 return "EVPN sequence number";
8947 case bgp_path_selection_evpn_lower_ip:
8948 return "EVPN lower IP";
8949 case bgp_path_selection_evpn_local_path:
8950 return "EVPN local ES path";
8951 case bgp_path_selection_evpn_non_proxy:
8952 return "EVPN non proxy";
8953 case bgp_path_selection_weight:
8954 return "Weight";
8955 case bgp_path_selection_local_pref:
8956 return "Local Pref";
8957 case bgp_path_selection_accept_own:
8958 return "Accept Own";
8959 case bgp_path_selection_local_route:
8960 return "Local Route";
8961 case bgp_path_selection_aigp:
8962 return "AIGP";
8963 case bgp_path_selection_confed_as_path:
8964 return "Confederation based AS Path";
8965 case bgp_path_selection_as_path:
8966 return "AS Path";
8967 case bgp_path_selection_origin:
8968 return "Origin";
8969 case bgp_path_selection_med:
8970 return "MED";
8971 case bgp_path_selection_peer:
8972 return "Peer Type";
8973 case bgp_path_selection_confed:
8974 return "Confed Peer Type";
8975 case bgp_path_selection_igp_metric:
8976 return "IGP Metric";
8977 case bgp_path_selection_older:
8978 return "Older Path";
8979 case bgp_path_selection_router_id:
8980 return "Router ID";
8981 case bgp_path_selection_cluster_length:
8982 return "Cluster length";
8983 case bgp_path_selection_stale:
8984 return "Path Staleness";
8985 case bgp_path_selection_local_configured:
8986 return "Locally configured route";
8987 case bgp_path_selection_neighbor_ip:
8988 return "Neighbor IP";
8989 case bgp_path_selection_default:
8990 return "Nothing left to compare";
8991 }
8992 return "Invalid (internal error)";
8993 }
8994
8995 /* Print the short form route status for a bgp_path_info */
8996 static void route_vty_short_status_out(struct vty *vty,
8997 struct bgp_path_info *path,
8998 const struct prefix *p,
8999 json_object *json_path)
9000 {
9001 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9002
9003 if (json_path) {
9004
9005 /* Route status display. */
9006 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9007 json_object_boolean_true_add(json_path, "removed");
9008
9009 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9010 json_object_boolean_true_add(json_path, "stale");
9011
9012 if (path->extra && bgp_path_suppressed(path))
9013 json_object_boolean_true_add(json_path, "suppressed");
9014
9015 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9016 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9017 json_object_boolean_true_add(json_path, "valid");
9018
9019 /* Selected */
9020 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9021 json_object_boolean_true_add(json_path, "history");
9022
9023 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9024 json_object_boolean_true_add(json_path, "damped");
9025
9026 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9027 json_object_boolean_true_add(json_path, "bestpath");
9028 json_object_string_add(json_path, "selectionReason",
9029 bgp_path_selection_reason2str(
9030 path->net->reason));
9031 }
9032
9033 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9034 json_object_boolean_true_add(json_path, "multipath");
9035
9036 /* Internal route. */
9037 if ((path->peer->as)
9038 && (path->peer->as == path->peer->local_as))
9039 json_object_string_add(json_path, "pathFrom",
9040 "internal");
9041 else
9042 json_object_string_add(json_path, "pathFrom",
9043 "external");
9044
9045 return;
9046 }
9047
9048 /* RPKI validation state */
9049 rpki_state =
9050 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9051
9052 if (rpki_state == RPKI_VALID)
9053 vty_out(vty, "V");
9054 else if (rpki_state == RPKI_INVALID)
9055 vty_out(vty, "I");
9056 else if (rpki_state == RPKI_NOTFOUND)
9057 vty_out(vty, "N");
9058 else
9059 vty_out(vty, " ");
9060
9061 /* Route status display. */
9062 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9063 vty_out(vty, "R");
9064 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9065 vty_out(vty, "S");
9066 else if (bgp_path_suppressed(path))
9067 vty_out(vty, "s");
9068 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9069 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9070 vty_out(vty, "*");
9071 else
9072 vty_out(vty, " ");
9073
9074 /* Selected */
9075 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9076 vty_out(vty, "h");
9077 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9078 vty_out(vty, "d");
9079 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9080 vty_out(vty, ">");
9081 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9082 vty_out(vty, "=");
9083 else
9084 vty_out(vty, " ");
9085
9086 /* Internal route. */
9087 if (path->peer && (path->peer->as)
9088 && (path->peer->as == path->peer->local_as))
9089 vty_out(vty, "i");
9090 else
9091 vty_out(vty, " ");
9092 }
9093
9094 static char *bgp_nexthop_hostname(struct peer *peer,
9095 struct bgp_nexthop_cache *bnc)
9096 {
9097 if (peer->hostname
9098 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9099 return peer->hostname;
9100 return NULL;
9101 }
9102
9103 /* called from terminal list command */
9104 void route_vty_out(struct vty *vty, const struct prefix *p,
9105 struct bgp_path_info *path, int display, safi_t safi,
9106 json_object *json_paths, bool wide)
9107 {
9108 int len;
9109 struct attr *attr = path->attr;
9110 json_object *json_path = NULL;
9111 json_object *json_nexthops = NULL;
9112 json_object *json_nexthop_global = NULL;
9113 json_object *json_nexthop_ll = NULL;
9114 json_object *json_ext_community = NULL;
9115 char vrf_id_str[VRF_NAMSIZ] = {0};
9116 bool nexthop_self =
9117 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9118 bool nexthop_othervrf = false;
9119 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9120 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9121 char *nexthop_hostname =
9122 bgp_nexthop_hostname(path->peer, path->nexthop);
9123 char esi_buf[ESI_STR_LEN];
9124
9125 if (json_paths)
9126 json_path = json_object_new_object();
9127
9128 /* short status lead text */
9129 route_vty_short_status_out(vty, path, p, json_path);
9130
9131 if (!json_paths) {
9132 /* print prefix and mask */
9133 if (!display)
9134 route_vty_out_route(path->net, p, vty, json_path, wide);
9135 else
9136 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9137 } else {
9138 route_vty_out_route(path->net, p, vty, json_path, wide);
9139 }
9140
9141 /*
9142 * If vrf id of nexthop is different from that of prefix,
9143 * set up printable string to append
9144 */
9145 if (path->extra && path->extra->bgp_orig) {
9146 const char *self = "";
9147
9148 if (nexthop_self)
9149 self = "<";
9150
9151 nexthop_othervrf = true;
9152 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9153
9154 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9155 snprintf(vrf_id_str, sizeof(vrf_id_str),
9156 "@%s%s", VRFID_NONE_STR, self);
9157 else
9158 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9159 path->extra->bgp_orig->vrf_id, self);
9160
9161 if (path->extra->bgp_orig->inst_type
9162 != BGP_INSTANCE_TYPE_DEFAULT)
9163
9164 nexthop_vrfname = path->extra->bgp_orig->name;
9165 } else {
9166 const char *self = "";
9167
9168 if (nexthop_self)
9169 self = "<";
9170
9171 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9172 }
9173
9174 /*
9175 * For ENCAP and EVPN routes, nexthop address family is not
9176 * neccessarily the same as the prefix address family.
9177 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9178 * EVPN routes are also exchanged with a MP nexthop. Currently,
9179 * this
9180 * is only IPv4, the value will be present in either
9181 * attr->nexthop or
9182 * attr->mp_nexthop_global_in
9183 */
9184 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9185 char nexthop[128];
9186 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9187
9188 switch (af) {
9189 case AF_INET:
9190 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9191 &attr->mp_nexthop_global_in);
9192 break;
9193 case AF_INET6:
9194 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9195 &attr->mp_nexthop_global);
9196 break;
9197 default:
9198 snprintf(nexthop, sizeof(nexthop), "?");
9199 break;
9200 }
9201
9202 if (json_paths) {
9203 json_nexthop_global = json_object_new_object();
9204
9205 json_object_string_add(json_nexthop_global, "ip",
9206 nexthop);
9207
9208 if (path->peer->hostname)
9209 json_object_string_add(json_nexthop_global,
9210 "hostname",
9211 path->peer->hostname);
9212
9213 json_object_string_add(json_nexthop_global, "afi",
9214 (af == AF_INET) ? "ipv4"
9215 : "ipv6");
9216 json_object_boolean_true_add(json_nexthop_global,
9217 "used");
9218 } else {
9219 if (nexthop_hostname)
9220 len = vty_out(vty, "%s(%s)%s", nexthop,
9221 nexthop_hostname, vrf_id_str);
9222 else
9223 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9224
9225 len = wide ? (41 - len) : (16 - len);
9226 if (len < 1)
9227 vty_out(vty, "\n%*s", 36, " ");
9228 else
9229 vty_out(vty, "%*s", len, " ");
9230 }
9231 } else if (safi == SAFI_EVPN) {
9232 if (json_paths) {
9233 json_nexthop_global = json_object_new_object();
9234
9235 json_object_string_addf(json_nexthop_global, "ip",
9236 "%pI4",
9237 &attr->mp_nexthop_global_in);
9238
9239 if (path->peer->hostname)
9240 json_object_string_add(json_nexthop_global,
9241 "hostname",
9242 path->peer->hostname);
9243
9244 json_object_string_add(json_nexthop_global, "afi",
9245 "ipv4");
9246 json_object_boolean_true_add(json_nexthop_global,
9247 "used");
9248 } else {
9249 if (nexthop_hostname)
9250 len = vty_out(vty, "%pI4(%s)%s",
9251 &attr->mp_nexthop_global_in,
9252 nexthop_hostname, vrf_id_str);
9253 else
9254 len = vty_out(vty, "%pI4%s",
9255 &attr->mp_nexthop_global_in,
9256 vrf_id_str);
9257
9258 len = wide ? (41 - len) : (16 - len);
9259 if (len < 1)
9260 vty_out(vty, "\n%*s", 36, " ");
9261 else
9262 vty_out(vty, "%*s", len, " ");
9263 }
9264 } else if (safi == SAFI_FLOWSPEC) {
9265 if (attr->nexthop.s_addr != INADDR_ANY) {
9266 if (json_paths) {
9267 json_nexthop_global = json_object_new_object();
9268
9269 json_object_string_add(json_nexthop_global,
9270 "afi", "ipv4");
9271 json_object_string_addf(json_nexthop_global,
9272 "ip", "%pI4",
9273 &attr->nexthop);
9274
9275 if (path->peer->hostname)
9276 json_object_string_add(
9277 json_nexthop_global, "hostname",
9278 path->peer->hostname);
9279
9280 json_object_boolean_true_add(
9281 json_nexthop_global,
9282 "used");
9283 } else {
9284 if (nexthop_hostname)
9285 len = vty_out(vty, "%pI4(%s)%s",
9286 &attr->nexthop,
9287 nexthop_hostname,
9288 vrf_id_str);
9289 else
9290 len = vty_out(vty, "%pI4%s",
9291 &attr->nexthop,
9292 vrf_id_str);
9293
9294 len = wide ? (41 - len) : (16 - len);
9295 if (len < 1)
9296 vty_out(vty, "\n%*s", 36, " ");
9297 else
9298 vty_out(vty, "%*s", len, " ");
9299 }
9300 }
9301 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9302 if (json_paths) {
9303 json_nexthop_global = json_object_new_object();
9304
9305 json_object_string_addf(json_nexthop_global, "ip",
9306 "%pI4", &attr->nexthop);
9307
9308 if (path->peer->hostname)
9309 json_object_string_add(json_nexthop_global,
9310 "hostname",
9311 path->peer->hostname);
9312
9313 json_object_string_add(json_nexthop_global, "afi",
9314 "ipv4");
9315 json_object_boolean_true_add(json_nexthop_global,
9316 "used");
9317 } else {
9318 if (nexthop_hostname)
9319 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9320 nexthop_hostname, vrf_id_str);
9321 else
9322 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9323 vrf_id_str);
9324
9325 len = wide ? (41 - len) : (16 - len);
9326 if (len < 1)
9327 vty_out(vty, "\n%*s", 36, " ");
9328 else
9329 vty_out(vty, "%*s", len, " ");
9330 }
9331 }
9332
9333 /* IPv6 Next Hop */
9334 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9335 if (json_paths) {
9336 json_nexthop_global = json_object_new_object();
9337 json_object_string_addf(json_nexthop_global, "ip",
9338 "%pI6",
9339 &attr->mp_nexthop_global);
9340
9341 if (path->peer->hostname)
9342 json_object_string_add(json_nexthop_global,
9343 "hostname",
9344 path->peer->hostname);
9345
9346 json_object_string_add(json_nexthop_global, "afi",
9347 "ipv6");
9348 json_object_string_add(json_nexthop_global, "scope",
9349 "global");
9350
9351 /* We display both LL & GL if both have been
9352 * received */
9353 if ((attr->mp_nexthop_len
9354 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9355 || (path->peer->conf_if)) {
9356 json_nexthop_ll = json_object_new_object();
9357 json_object_string_addf(
9358 json_nexthop_ll, "ip", "%pI6",
9359 &attr->mp_nexthop_local);
9360
9361 if (path->peer->hostname)
9362 json_object_string_add(
9363 json_nexthop_ll, "hostname",
9364 path->peer->hostname);
9365
9366 json_object_string_add(json_nexthop_ll, "afi",
9367 "ipv6");
9368 json_object_string_add(json_nexthop_ll, "scope",
9369 "link-local");
9370
9371 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9372 &attr->mp_nexthop_local)
9373 != 0)
9374 && !attr->mp_nexthop_prefer_global)
9375 json_object_boolean_true_add(
9376 json_nexthop_ll, "used");
9377 else
9378 json_object_boolean_true_add(
9379 json_nexthop_global, "used");
9380 } else
9381 json_object_boolean_true_add(
9382 json_nexthop_global, "used");
9383 } else {
9384 /* Display LL if LL/Global both in table unless
9385 * prefer-global is set */
9386 if (((attr->mp_nexthop_len
9387 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9388 && !attr->mp_nexthop_prefer_global)
9389 || (path->peer->conf_if)) {
9390 if (path->peer->conf_if) {
9391 len = vty_out(vty, "%s",
9392 path->peer->conf_if);
9393 /* len of IPv6 addr + max len of def
9394 * ifname */
9395 len = wide ? (41 - len) : (16 - len);
9396
9397 if (len < 1)
9398 vty_out(vty, "\n%*s", 36, " ");
9399 else
9400 vty_out(vty, "%*s", len, " ");
9401 } else {
9402 if (nexthop_hostname)
9403 len = vty_out(
9404 vty, "%pI6(%s)%s",
9405 &attr->mp_nexthop_local,
9406 nexthop_hostname,
9407 vrf_id_str);
9408 else
9409 len = vty_out(
9410 vty, "%pI6%s",
9411 &attr->mp_nexthop_local,
9412 vrf_id_str);
9413
9414 len = wide ? (41 - len) : (16 - len);
9415
9416 if (len < 1)
9417 vty_out(vty, "\n%*s", 36, " ");
9418 else
9419 vty_out(vty, "%*s", len, " ");
9420 }
9421 } else {
9422 if (nexthop_hostname)
9423 len = vty_out(vty, "%pI6(%s)%s",
9424 &attr->mp_nexthop_global,
9425 nexthop_hostname,
9426 vrf_id_str);
9427 else
9428 len = vty_out(vty, "%pI6%s",
9429 &attr->mp_nexthop_global,
9430 vrf_id_str);
9431
9432 len = wide ? (41 - len) : (16 - len);
9433
9434 if (len < 1)
9435 vty_out(vty, "\n%*s", 36, " ");
9436 else
9437 vty_out(vty, "%*s", len, " ");
9438 }
9439 }
9440 }
9441
9442 /* MED/Metric */
9443 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9444 if (json_paths)
9445 json_object_int_add(json_path, "metric", attr->med);
9446 else if (wide)
9447 vty_out(vty, "%7u", attr->med);
9448 else
9449 vty_out(vty, "%10u", attr->med);
9450 else if (!json_paths) {
9451 if (wide)
9452 vty_out(vty, "%*s", 7, " ");
9453 else
9454 vty_out(vty, "%*s", 10, " ");
9455 }
9456
9457 /* Local Pref */
9458 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9459 if (json_paths)
9460 json_object_int_add(json_path, "locPrf",
9461 attr->local_pref);
9462 else
9463 vty_out(vty, "%7u", attr->local_pref);
9464 else if (!json_paths)
9465 vty_out(vty, " ");
9466
9467 if (json_paths)
9468 json_object_int_add(json_path, "weight", attr->weight);
9469 else
9470 vty_out(vty, "%7u ", attr->weight);
9471
9472 if (json_paths)
9473 json_object_string_addf(json_path, "peerId", "%pSU",
9474 &path->peer->su);
9475
9476 /* Print aspath */
9477 if (attr->aspath) {
9478 if (json_paths)
9479 json_object_string_add(json_path, "path",
9480 attr->aspath->str);
9481 else
9482 aspath_print_vty(vty, attr->aspath);
9483 }
9484
9485 /* Print origin */
9486 if (json_paths)
9487 json_object_string_add(json_path, "origin",
9488 bgp_origin_long_str[attr->origin]);
9489 else
9490 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9491
9492 if (json_paths) {
9493 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9494 json_object_string_add(json_path, "esi",
9495 esi_to_str(&attr->esi,
9496 esi_buf, sizeof(esi_buf)));
9497 }
9498 if (safi == SAFI_EVPN &&
9499 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9500 json_ext_community = json_object_new_object();
9501 json_object_string_add(
9502 json_ext_community, "string",
9503 bgp_attr_get_ecommunity(attr)->str);
9504 json_object_object_add(json_path,
9505 "extendedCommunity",
9506 json_ext_community);
9507 }
9508
9509 if (nexthop_self)
9510 json_object_boolean_true_add(json_path,
9511 "announceNexthopSelf");
9512 if (nexthop_othervrf) {
9513 json_object_string_add(json_path, "nhVrfName",
9514 nexthop_vrfname);
9515
9516 json_object_int_add(json_path, "nhVrfId",
9517 ((nexthop_vrfid == VRF_UNKNOWN)
9518 ? -1
9519 : (int)nexthop_vrfid));
9520 }
9521 }
9522
9523 if (json_paths) {
9524 if (json_nexthop_global || json_nexthop_ll) {
9525 json_nexthops = json_object_new_array();
9526
9527 if (json_nexthop_global)
9528 json_object_array_add(json_nexthops,
9529 json_nexthop_global);
9530
9531 if (json_nexthop_ll)
9532 json_object_array_add(json_nexthops,
9533 json_nexthop_ll);
9534
9535 json_object_object_add(json_path, "nexthops",
9536 json_nexthops);
9537 }
9538
9539 json_object_array_add(json_paths, json_path);
9540 } else {
9541 vty_out(vty, "\n");
9542
9543 if (safi == SAFI_EVPN) {
9544 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9545 /* XXX - add these params to the json out */
9546 vty_out(vty, "%*s", 20, " ");
9547 vty_out(vty, "ESI:%s",
9548 esi_to_str(&attr->esi, esi_buf,
9549 sizeof(esi_buf)));
9550
9551 vty_out(vty, "\n");
9552 }
9553 if (attr->flag &
9554 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9555 vty_out(vty, "%*s", 20, " ");
9556 vty_out(vty, "%s\n",
9557 bgp_attr_get_ecommunity(attr)->str);
9558 }
9559 }
9560
9561 #ifdef ENABLE_BGP_VNC
9562 /* prints an additional line, indented, with VNC info, if
9563 * present */
9564 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9565 rfapi_vty_out_vncinfo(vty, p, path, safi);
9566 #endif
9567 }
9568 }
9569
9570 /* called from terminal list command */
9571 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9572 const struct prefix *p, struct attr *attr, safi_t safi,
9573 bool use_json, json_object *json_ar, bool wide)
9574 {
9575 json_object *json_status = NULL;
9576 json_object *json_net = NULL;
9577 int len;
9578 char buff[BUFSIZ];
9579
9580 /* Route status display. */
9581 if (use_json) {
9582 json_status = json_object_new_object();
9583 json_net = json_object_new_object();
9584 } else {
9585 vty_out(vty, " *");
9586 vty_out(vty, ">");
9587 vty_out(vty, " ");
9588 }
9589
9590 /* print prefix and mask */
9591 if (use_json) {
9592 if (safi == SAFI_EVPN)
9593 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9594 else if (p->family == AF_INET || p->family == AF_INET6) {
9595 json_object_string_add(
9596 json_net, "addrPrefix",
9597 inet_ntop(p->family, &p->u.prefix, buff,
9598 BUFSIZ));
9599 json_object_int_add(json_net, "prefixLen",
9600 p->prefixlen);
9601 json_object_string_addf(json_net, "network", "%pFX", p);
9602 }
9603 } else
9604 route_vty_out_route(dest, p, vty, NULL, wide);
9605
9606 /* Print attribute */
9607 if (attr) {
9608 if (use_json) {
9609 if (p->family == AF_INET &&
9610 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9611 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9612 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9613 json_object_string_addf(
9614 json_net, "nextHop", "%pI4",
9615 &attr->mp_nexthop_global_in);
9616 else
9617 json_object_string_addf(
9618 json_net, "nextHop", "%pI4",
9619 &attr->nexthop);
9620 } else if (p->family == AF_INET6 ||
9621 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9622 json_object_string_addf(
9623 json_net, "nextHopGlobal", "%pI6",
9624 &attr->mp_nexthop_global);
9625 } else if (p->family == AF_EVPN &&
9626 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9627 json_object_string_addf(
9628 json_net, "nextHop", "%pI4",
9629 &attr->mp_nexthop_global_in);
9630 }
9631
9632 if (attr->flag
9633 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9634 json_object_int_add(json_net, "metric",
9635 attr->med);
9636
9637 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9638 json_object_int_add(json_net, "locPrf",
9639 attr->local_pref);
9640
9641 json_object_int_add(json_net, "weight", attr->weight);
9642
9643 /* Print aspath */
9644 if (attr->aspath)
9645 json_object_string_add(json_net, "path",
9646 attr->aspath->str);
9647
9648 /* Print origin */
9649 #if CONFDATE > 20231208
9650 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9651 #endif
9652 json_object_string_add(json_net, "bgpOriginCode",
9653 bgp_origin_str[attr->origin]);
9654 json_object_string_add(
9655 json_net, "origin",
9656 bgp_origin_long_str[attr->origin]);
9657 } else {
9658 if (p->family == AF_INET &&
9659 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9660 safi == SAFI_EVPN ||
9661 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9662 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9663 || safi == SAFI_EVPN)
9664 vty_out(vty, "%-16pI4",
9665 &attr->mp_nexthop_global_in);
9666 else if (wide)
9667 vty_out(vty, "%-41pI4", &attr->nexthop);
9668 else
9669 vty_out(vty, "%-16pI4", &attr->nexthop);
9670 } else if (p->family == AF_INET6 ||
9671 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9672 len = vty_out(vty, "%pI6",
9673 &attr->mp_nexthop_global);
9674 len = wide ? (41 - len) : (16 - len);
9675 if (len < 1)
9676 vty_out(vty, "\n%*s", 36, " ");
9677 else
9678 vty_out(vty, "%*s", len, " ");
9679 }
9680 if (attr->flag
9681 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9682 if (wide)
9683 vty_out(vty, "%7u", attr->med);
9684 else
9685 vty_out(vty, "%10u", attr->med);
9686 else if (wide)
9687 vty_out(vty, " ");
9688 else
9689 vty_out(vty, " ");
9690
9691 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9692 vty_out(vty, "%7u", attr->local_pref);
9693 else
9694 vty_out(vty, " ");
9695
9696 vty_out(vty, "%7u ", attr->weight);
9697
9698 /* Print aspath */
9699 if (attr->aspath)
9700 aspath_print_vty(vty, attr->aspath);
9701
9702 /* Print origin */
9703 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9704 }
9705 }
9706 if (use_json) {
9707 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9708
9709 #if CONFDATE > 20231208
9710 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9711 #endif
9712 json_object_boolean_true_add(json_status, "*");
9713 json_object_boolean_true_add(json_status, ">");
9714 json_object_boolean_true_add(json_net, "valid");
9715 json_object_boolean_true_add(json_net, "best");
9716
9717 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9718 json_object_boolean_true_add(json_status, "=");
9719 json_object_boolean_true_add(json_net, "multipath");
9720 }
9721 json_object_object_add(json_net, "appliedStatusSymbols",
9722 json_status);
9723 json_object_object_addf(json_ar, json_net, "%pFX", p);
9724 } else
9725 vty_out(vty, "\n");
9726 }
9727
9728 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9729 struct bgp_path_info *path, int display, safi_t safi,
9730 json_object *json)
9731 {
9732 json_object *json_out = NULL;
9733 struct attr *attr;
9734 mpls_label_t label = MPLS_INVALID_LABEL;
9735
9736 if (!path->extra)
9737 return;
9738
9739 if (json)
9740 json_out = json_object_new_object();
9741
9742 /* short status lead text */
9743 route_vty_short_status_out(vty, path, p, json_out);
9744
9745 /* print prefix and mask */
9746 if (json == NULL) {
9747 if (!display)
9748 route_vty_out_route(path->net, p, vty, NULL, false);
9749 else
9750 vty_out(vty, "%*s", 17, " ");
9751 }
9752
9753 /* Print attribute */
9754 attr = path->attr;
9755 if (((p->family == AF_INET) &&
9756 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9757 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9758 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9759 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9760 || safi == SAFI_EVPN) {
9761 if (json)
9762 json_object_string_addf(
9763 json_out, "mpNexthopGlobalIn", "%pI4",
9764 &attr->mp_nexthop_global_in);
9765 else
9766 vty_out(vty, "%-16pI4",
9767 &attr->mp_nexthop_global_in);
9768 } else {
9769 if (json)
9770 json_object_string_addf(json_out, "nexthop",
9771 "%pI4", &attr->nexthop);
9772 else
9773 vty_out(vty, "%-16pI4", &attr->nexthop);
9774 }
9775 } else if (((p->family == AF_INET6) &&
9776 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9777 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9778 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9779 char buf_a[512];
9780
9781 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9782 if (json)
9783 json_object_string_addf(
9784 json_out, "mpNexthopGlobalIn", "%pI6",
9785 &attr->mp_nexthop_global);
9786 else
9787 vty_out(vty, "%s",
9788 inet_ntop(AF_INET6,
9789 &attr->mp_nexthop_global,
9790 buf_a, sizeof(buf_a)));
9791 } else if (attr->mp_nexthop_len
9792 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9793 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9794 &attr->mp_nexthop_global,
9795 &attr->mp_nexthop_local);
9796 if (json)
9797 json_object_string_add(json_out,
9798 "mpNexthopGlobalLocal",
9799 buf_a);
9800 else
9801 vty_out(vty, "%s", buf_a);
9802 }
9803 }
9804
9805 label = decode_label(&path->extra->label[0]);
9806
9807 if (bgp_is_valid_label(&label)) {
9808 if (json) {
9809 json_object_int_add(json_out, "notag", label);
9810 json_object_array_add(json, json_out);
9811 } else {
9812 vty_out(vty, "notag/%d", label);
9813 vty_out(vty, "\n");
9814 }
9815 } else if (!json)
9816 vty_out(vty, "\n");
9817 }
9818
9819 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9820 struct bgp_path_info *path, int display,
9821 json_object *json_paths)
9822 {
9823 struct attr *attr;
9824 json_object *json_path = NULL;
9825 json_object *json_nexthop = NULL;
9826 json_object *json_overlay = NULL;
9827
9828 if (!path->extra)
9829 return;
9830
9831 if (json_paths) {
9832 json_path = json_object_new_object();
9833 json_overlay = json_object_new_object();
9834 json_nexthop = json_object_new_object();
9835 }
9836
9837 /* short status lead text */
9838 route_vty_short_status_out(vty, path, p, json_path);
9839
9840 /* print prefix and mask */
9841 if (!display)
9842 route_vty_out_route(path->net, p, vty, json_path, false);
9843 else
9844 vty_out(vty, "%*s", 17, " ");
9845
9846 /* Print attribute */
9847 attr = path->attr;
9848 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9849
9850 switch (af) {
9851 case AF_INET:
9852 if (!json_path) {
9853 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9854 } else {
9855 json_object_string_addf(json_nexthop, "ip", "%pI4",
9856 &attr->mp_nexthop_global_in);
9857
9858 json_object_string_add(json_nexthop, "afi", "ipv4");
9859
9860 json_object_object_add(json_path, "nexthop",
9861 json_nexthop);
9862 }
9863 break;
9864 case AF_INET6:
9865 if (!json_path) {
9866 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9867 &attr->mp_nexthop_local);
9868 } else {
9869 json_object_string_addf(json_nexthop, "ipv6Global",
9870 "%pI6",
9871 &attr->mp_nexthop_global);
9872
9873 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9874 "%pI6",
9875 &attr->mp_nexthop_local);
9876
9877 json_object_string_add(json_nexthop, "afi", "ipv6");
9878
9879 json_object_object_add(json_path, "nexthop",
9880 json_nexthop);
9881 }
9882 break;
9883 default:
9884 if (!json_path) {
9885 vty_out(vty, "?");
9886 } else {
9887 json_object_string_add(json_nexthop, "error",
9888 "Unsupported address-family");
9889 }
9890 }
9891
9892 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9893
9894 if (!json_path)
9895 vty_out(vty, "/%pIA", &eo->gw_ip);
9896 else
9897 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9898
9899 if (bgp_attr_get_ecommunity(attr)) {
9900 char *mac = NULL;
9901 struct ecommunity_val *routermac = ecommunity_lookup(
9902 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9903 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9904
9905 if (routermac)
9906 mac = ecom_mac2str((char *)routermac->val);
9907 if (mac) {
9908 if (!json_path) {
9909 vty_out(vty, "/%s", mac);
9910 } else {
9911 json_object_string_add(json_overlay, "rmac",
9912 mac);
9913 }
9914 XFREE(MTYPE_TMP, mac);
9915 }
9916 }
9917
9918 if (!json_path) {
9919 vty_out(vty, "\n");
9920 } else {
9921 json_object_object_add(json_path, "overlay", json_overlay);
9922
9923 json_object_array_add(json_paths, json_path);
9924 }
9925 }
9926
9927 /* dampening route */
9928 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9929 struct bgp_path_info *path, int display,
9930 afi_t afi, safi_t safi, bool use_json,
9931 json_object *json_paths)
9932 {
9933 struct attr *attr = path->attr;
9934 int len;
9935 char timebuf[BGP_UPTIME_LEN];
9936 json_object *json_path = NULL;
9937
9938 if (use_json)
9939 json_path = json_object_new_object();
9940
9941 /* short status lead text */
9942 route_vty_short_status_out(vty, path, p, json_path);
9943
9944 /* print prefix and mask */
9945 if (!use_json) {
9946 if (!display)
9947 route_vty_out_route(path->net, p, vty, NULL, false);
9948 else
9949 vty_out(vty, "%*s", 17, " ");
9950
9951 len = vty_out(vty, "%s", path->peer->host);
9952 len = 17 - len;
9953
9954 if (len < 1)
9955 vty_out(vty, "\n%*s", 34, " ");
9956 else
9957 vty_out(vty, "%*s", len, " ");
9958
9959 vty_out(vty, "%s ",
9960 bgp_damp_reuse_time_vty(vty, path, timebuf,
9961 BGP_UPTIME_LEN, afi, safi,
9962 use_json, NULL));
9963
9964 if (attr->aspath)
9965 aspath_print_vty(vty, attr->aspath);
9966
9967 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9968
9969 vty_out(vty, "\n");
9970 } else {
9971 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9972 safi, use_json, json_path);
9973
9974 if (attr->aspath)
9975 json_object_string_add(json_path, "asPath",
9976 attr->aspath->str);
9977
9978 json_object_string_add(json_path, "origin",
9979 bgp_origin_str[attr->origin]);
9980 json_object_string_add(json_path, "peerHost", path->peer->host);
9981
9982 json_object_array_add(json_paths, json_path);
9983 }
9984 }
9985
9986 /* flap route */
9987 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9988 struct bgp_path_info *path, int display,
9989 afi_t afi, safi_t safi, bool use_json,
9990 json_object *json_paths)
9991 {
9992 struct attr *attr = path->attr;
9993 struct bgp_damp_info *bdi;
9994 char timebuf[BGP_UPTIME_LEN];
9995 int len;
9996 json_object *json_path = NULL;
9997
9998 if (!path->extra)
9999 return;
10000
10001 if (use_json)
10002 json_path = json_object_new_object();
10003
10004 bdi = path->extra->damp_info;
10005
10006 /* short status lead text */
10007 route_vty_short_status_out(vty, path, p, json_path);
10008
10009 if (!use_json) {
10010 if (!display)
10011 route_vty_out_route(path->net, p, vty, NULL, false);
10012 else
10013 vty_out(vty, "%*s", 17, " ");
10014
10015 len = vty_out(vty, "%s", path->peer->host);
10016 len = 16 - len;
10017 if (len < 1)
10018 vty_out(vty, "\n%*s", 33, " ");
10019 else
10020 vty_out(vty, "%*s", len, " ");
10021
10022 len = vty_out(vty, "%d", bdi->flap);
10023 len = 5 - len;
10024 if (len < 1)
10025 vty_out(vty, " ");
10026 else
10027 vty_out(vty, "%*s", len, " ");
10028
10029 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10030 BGP_UPTIME_LEN, 0, NULL));
10031
10032 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10033 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10034 vty_out(vty, "%s ",
10035 bgp_damp_reuse_time_vty(vty, path, timebuf,
10036 BGP_UPTIME_LEN, afi,
10037 safi, use_json, NULL));
10038 else
10039 vty_out(vty, "%*s ", 8, " ");
10040
10041 if (attr->aspath)
10042 aspath_print_vty(vty, attr->aspath);
10043
10044 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10045
10046 vty_out(vty, "\n");
10047 } else {
10048 json_object_string_add(json_path, "peerHost", path->peer->host);
10049 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10050
10051 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10052 json_path);
10053
10054 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10055 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10056 bgp_damp_reuse_time_vty(vty, path, timebuf,
10057 BGP_UPTIME_LEN, afi, safi,
10058 use_json, json_path);
10059
10060 if (attr->aspath)
10061 json_object_string_add(json_path, "asPath",
10062 attr->aspath->str);
10063
10064 json_object_string_add(json_path, "origin",
10065 bgp_origin_str[attr->origin]);
10066
10067 json_object_array_add(json_paths, json_path);
10068 }
10069 }
10070
10071 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10072 int *first, const char *header,
10073 json_object *json_adv_to)
10074 {
10075 json_object *json_peer = NULL;
10076
10077 if (json_adv_to) {
10078 /* 'advertised-to' is a dictionary of peers we have advertised
10079 * this
10080 * prefix too. The key is the peer's IP or swpX, the value is
10081 * the
10082 * hostname if we know it and "" if not.
10083 */
10084 json_peer = json_object_new_object();
10085
10086 if (peer->hostname)
10087 json_object_string_add(json_peer, "hostname",
10088 peer->hostname);
10089
10090 if (peer->conf_if)
10091 json_object_object_add(json_adv_to, peer->conf_if,
10092 json_peer);
10093 else
10094 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10095 &peer->su);
10096 } else {
10097 if (*first) {
10098 vty_out(vty, "%s", header);
10099 *first = 0;
10100 }
10101
10102 if (peer->hostname
10103 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10104 if (peer->conf_if)
10105 vty_out(vty, " %s(%s)", peer->hostname,
10106 peer->conf_if);
10107 else
10108 vty_out(vty, " %s(%pSU)", peer->hostname,
10109 &peer->su);
10110 } else {
10111 if (peer->conf_if)
10112 vty_out(vty, " %s", peer->conf_if);
10113 else
10114 vty_out(vty, " %pSU", &peer->su);
10115 }
10116 }
10117 }
10118
10119 static void route_vty_out_tx_ids(struct vty *vty,
10120 struct bgp_addpath_info_data *d)
10121 {
10122 int i;
10123
10124 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10125 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10126 d->addpath_tx_id[i],
10127 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10128 }
10129 }
10130
10131 static void route_vty_out_detail_es_info(struct vty *vty,
10132 struct bgp_path_info *pi,
10133 struct attr *attr,
10134 json_object *json_path)
10135 {
10136 char esi_buf[ESI_STR_LEN];
10137 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10138 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10139 ATTR_ES_PEER_ROUTER);
10140 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10141 ATTR_ES_PEER_ACTIVE);
10142 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10143 ATTR_ES_PEER_PROXY);
10144 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10145 if (json_path) {
10146 json_object *json_es_info = NULL;
10147
10148 json_object_string_add(
10149 json_path, "esi",
10150 esi_buf);
10151 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10152 json_es_info = json_object_new_object();
10153 if (es_local)
10154 json_object_boolean_true_add(
10155 json_es_info, "localEs");
10156 if (peer_active)
10157 json_object_boolean_true_add(
10158 json_es_info, "peerActive");
10159 if (peer_proxy)
10160 json_object_boolean_true_add(
10161 json_es_info, "peerProxy");
10162 if (peer_router)
10163 json_object_boolean_true_add(
10164 json_es_info, "peerRouter");
10165 if (attr->mm_sync_seqnum)
10166 json_object_int_add(
10167 json_es_info, "peerSeq",
10168 attr->mm_sync_seqnum);
10169 json_object_object_add(
10170 json_path, "es_info",
10171 json_es_info);
10172 }
10173 } else {
10174 if (bgp_evpn_attr_is_sync(attr))
10175 vty_out(vty,
10176 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10177 esi_buf,
10178 es_local ? "local-es":"",
10179 peer_proxy ? "proxy " : "",
10180 peer_active ? "active ":"",
10181 peer_router ? "router ":"",
10182 attr->mm_sync_seqnum);
10183 else
10184 vty_out(vty, " ESI %s %s\n",
10185 esi_buf,
10186 es_local ? "local-es":"");
10187 }
10188 }
10189
10190 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10191 const struct prefix *p, struct bgp_path_info *path,
10192 afi_t afi, safi_t safi,
10193 enum rpki_states rpki_curr_state,
10194 json_object *json_paths)
10195 {
10196 char buf[INET6_ADDRSTRLEN];
10197 char tag_buf[30];
10198 struct attr *attr = path->attr;
10199 time_t tbuf;
10200 json_object *json_bestpath = NULL;
10201 json_object *json_cluster_list = NULL;
10202 json_object *json_cluster_list_list = NULL;
10203 json_object *json_ext_community = NULL;
10204 json_object *json_last_update = NULL;
10205 json_object *json_pmsi = NULL;
10206 json_object *json_nexthop_global = NULL;
10207 json_object *json_nexthop_ll = NULL;
10208 json_object *json_nexthops = NULL;
10209 json_object *json_path = NULL;
10210 json_object *json_peer = NULL;
10211 json_object *json_string = NULL;
10212 json_object *json_adv_to = NULL;
10213 int first = 0;
10214 struct listnode *node, *nnode;
10215 struct peer *peer;
10216 bool addpath_capable;
10217 int has_adj;
10218 unsigned int first_as;
10219 bool nexthop_self =
10220 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10221 int i;
10222 char *nexthop_hostname =
10223 bgp_nexthop_hostname(path->peer, path->nexthop);
10224 uint32_t ttl = 0;
10225 uint32_t bos = 0;
10226 uint32_t exp = 0;
10227 mpls_label_t label = MPLS_INVALID_LABEL;
10228 tag_buf[0] = '\0';
10229 struct bgp_path_info *bpi_ultimate =
10230 bgp_get_imported_bpi_ultimate(path);
10231
10232 if (json_paths) {
10233 json_path = json_object_new_object();
10234 json_peer = json_object_new_object();
10235 json_nexthop_global = json_object_new_object();
10236 }
10237
10238 if (safi == SAFI_EVPN) {
10239 if (!json_paths)
10240 vty_out(vty, " Route %pFX", p);
10241 }
10242
10243 if (path->extra) {
10244 if (path->extra && path->extra->num_labels) {
10245 bgp_evpn_label2str(path->extra->label,
10246 path->extra->num_labels, tag_buf,
10247 sizeof(tag_buf));
10248 }
10249 if (safi == SAFI_EVPN) {
10250 if (!json_paths) {
10251 if (tag_buf[0] != '\0')
10252 vty_out(vty, " VNI %s", tag_buf);
10253 } else {
10254 if (tag_buf[0])
10255 json_object_string_add(json_path, "vni",
10256 tag_buf);
10257 }
10258 }
10259 }
10260
10261 if (safi == SAFI_EVPN
10262 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10263 char gwip_buf[INET6_ADDRSTRLEN];
10264
10265 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10266 sizeof(gwip_buf));
10267
10268 if (json_paths)
10269 json_object_string_add(json_path, "gatewayIP",
10270 gwip_buf);
10271 else
10272 vty_out(vty, " Gateway IP %s", gwip_buf);
10273 }
10274
10275 if (safi == SAFI_EVPN && !json_path)
10276 vty_out(vty, "\n");
10277
10278
10279 if (path->extra && path->extra->parent && !json_paths) {
10280 struct bgp_path_info *parent_ri;
10281 struct bgp_dest *dest, *pdest;
10282
10283 parent_ri = (struct bgp_path_info *)path->extra->parent;
10284 dest = parent_ri->net;
10285 if (dest && dest->pdest) {
10286 pdest = dest->pdest;
10287 if (is_pi_family_evpn(parent_ri)) {
10288 vty_out(vty, " Imported from ");
10289 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10290 (struct prefix_rd *)bgp_dest_get_prefix(
10291 pdest));
10292 vty_out(vty, ":%pFX, VNI %s",
10293 (struct prefix_evpn *)
10294 bgp_dest_get_prefix(dest),
10295 tag_buf);
10296 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10297 vty_out(vty, ", L3NHG %s",
10298 CHECK_FLAG(
10299 attr->es_flags,
10300 ATTR_ES_L3_NHG_ACTIVE)
10301 ? "active"
10302 : "inactive");
10303 vty_out(vty, "\n");
10304
10305 } else {
10306 vty_out(vty, " Imported from ");
10307 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10308 (struct prefix_rd *)bgp_dest_get_prefix(
10309 pdest));
10310 vty_out(vty, ":%pFX\n",
10311 (struct prefix_evpn *)
10312 bgp_dest_get_prefix(dest));
10313 }
10314 }
10315 }
10316
10317 /* Line1 display AS-path, Aggregator */
10318 if (attr->aspath) {
10319 if (json_paths) {
10320 if (!attr->aspath->json)
10321 aspath_str_update(attr->aspath, true);
10322 json_object_lock(attr->aspath->json);
10323 json_object_object_add(json_path, "aspath",
10324 attr->aspath->json);
10325 } else {
10326 if (attr->aspath->segments)
10327 vty_out(vty, " %s", attr->aspath->str);
10328 else
10329 vty_out(vty, " Local");
10330 }
10331 }
10332
10333 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10334 if (json_paths)
10335 json_object_boolean_true_add(json_path, "removed");
10336 else
10337 vty_out(vty, ", (removed)");
10338 }
10339
10340 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10341 if (json_paths)
10342 json_object_boolean_true_add(json_path, "stale");
10343 else
10344 vty_out(vty, ", (stale)");
10345 }
10346
10347 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10348 if (json_paths) {
10349 json_object_int_add(json_path, "aggregatorAs",
10350 attr->aggregator_as);
10351 json_object_string_addf(json_path, "aggregatorId",
10352 "%pI4", &attr->aggregator_addr);
10353 } else {
10354 vty_out(vty, ", (aggregated by %u %pI4)",
10355 attr->aggregator_as, &attr->aggregator_addr);
10356 }
10357 }
10358
10359 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10360 PEER_FLAG_REFLECTOR_CLIENT)) {
10361 if (json_paths)
10362 json_object_boolean_true_add(json_path,
10363 "rxedFromRrClient");
10364 else
10365 vty_out(vty, ", (Received from a RR-client)");
10366 }
10367
10368 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10369 PEER_FLAG_RSERVER_CLIENT)) {
10370 if (json_paths)
10371 json_object_boolean_true_add(json_path,
10372 "rxedFromRsClient");
10373 else
10374 vty_out(vty, ", (Received from a RS-client)");
10375 }
10376
10377 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10378 if (json_paths)
10379 json_object_boolean_true_add(json_path,
10380 "dampeningHistoryEntry");
10381 else
10382 vty_out(vty, ", (history entry)");
10383 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10384 if (json_paths)
10385 json_object_boolean_true_add(json_path,
10386 "dampeningSuppressed");
10387 else
10388 vty_out(vty, ", (suppressed due to dampening)");
10389 }
10390
10391 if (!json_paths)
10392 vty_out(vty, "\n");
10393
10394 /* Line2 display Next-hop, Neighbor, Router-id */
10395 /* Display the nexthop */
10396
10397 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10398 p->family == AF_EVPN) &&
10399 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10400 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10401 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10402 || safi == SAFI_EVPN) {
10403 if (json_paths) {
10404 json_object_string_addf(
10405 json_nexthop_global, "ip", "%pI4",
10406 &attr->mp_nexthop_global_in);
10407
10408 if (path->peer->hostname)
10409 json_object_string_add(
10410 json_nexthop_global, "hostname",
10411 path->peer->hostname);
10412 } else {
10413 if (nexthop_hostname)
10414 vty_out(vty, " %pI4(%s)",
10415 &attr->mp_nexthop_global_in,
10416 nexthop_hostname);
10417 else
10418 vty_out(vty, " %pI4",
10419 &attr->mp_nexthop_global_in);
10420 }
10421 } else {
10422 if (json_paths) {
10423 json_object_string_addf(json_nexthop_global,
10424 "ip", "%pI4",
10425 &attr->nexthop);
10426
10427 if (path->peer->hostname)
10428 json_object_string_add(
10429 json_nexthop_global, "hostname",
10430 path->peer->hostname);
10431 } else {
10432 if (nexthop_hostname)
10433 vty_out(vty, " %pI4(%s)",
10434 &attr->nexthop,
10435 nexthop_hostname);
10436 else
10437 vty_out(vty, " %pI4",
10438 &attr->nexthop);
10439 }
10440 }
10441
10442 if (json_paths)
10443 json_object_string_add(json_nexthop_global, "afi",
10444 "ipv4");
10445 } else {
10446 if (json_paths) {
10447 json_object_string_addf(json_nexthop_global, "ip",
10448 "%pI6",
10449 &attr->mp_nexthop_global);
10450
10451 if (path->peer->hostname)
10452 json_object_string_add(json_nexthop_global,
10453 "hostname",
10454 path->peer->hostname);
10455
10456 json_object_string_add(json_nexthop_global, "afi",
10457 "ipv6");
10458 json_object_string_add(json_nexthop_global, "scope",
10459 "global");
10460 } else {
10461 if (nexthop_hostname)
10462 vty_out(vty, " %pI6(%s)",
10463 &attr->mp_nexthop_global,
10464 nexthop_hostname);
10465 else
10466 vty_out(vty, " %pI6",
10467 &attr->mp_nexthop_global);
10468 }
10469 }
10470
10471 /* Display the IGP cost or 'inaccessible' */
10472 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10473 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10474
10475 if (json_paths) {
10476 json_object_boolean_false_add(json_nexthop_global,
10477 "accessible");
10478 json_object_boolean_add(json_nexthop_global,
10479 "importCheckEnabled", import);
10480 } else {
10481 vty_out(vty, " (inaccessible%s)",
10482 import ? ", import-check enabled" : "");
10483 }
10484 } else {
10485 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10486 if (json_paths)
10487 json_object_int_add(
10488 json_nexthop_global, "metric",
10489 bpi_ultimate->extra->igpmetric);
10490 else
10491 vty_out(vty, " (metric %u)",
10492 bpi_ultimate->extra->igpmetric);
10493 }
10494
10495 /* IGP cost is 0, display this only for json */
10496 else {
10497 if (json_paths)
10498 json_object_int_add(json_nexthop_global,
10499 "metric", 0);
10500 }
10501
10502 if (json_paths)
10503 json_object_boolean_true_add(json_nexthop_global,
10504 "accessible");
10505 }
10506
10507 /* Display peer "from" output */
10508 /* This path was originated locally */
10509 if (path->peer == bgp->peer_self) {
10510
10511 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10512 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10513 if (json_paths)
10514 json_object_string_add(json_peer, "peerId",
10515 "0.0.0.0");
10516 else
10517 vty_out(vty, " from 0.0.0.0 ");
10518 } else {
10519 if (json_paths)
10520 json_object_string_add(json_peer, "peerId",
10521 "::");
10522 else
10523 vty_out(vty, " from :: ");
10524 }
10525
10526 if (json_paths)
10527 json_object_string_addf(json_peer, "routerId", "%pI4",
10528 &bgp->router_id);
10529 else
10530 vty_out(vty, "(%pI4)", &bgp->router_id);
10531 }
10532
10533 /* We RXed this path from one of our peers */
10534 else {
10535
10536 if (json_paths) {
10537 json_object_string_addf(json_peer, "peerId", "%pSU",
10538 &path->peer->su);
10539 json_object_string_addf(json_peer, "routerId", "%pI4",
10540 &path->peer->remote_id);
10541
10542 if (path->peer->hostname)
10543 json_object_string_add(json_peer, "hostname",
10544 path->peer->hostname);
10545
10546 if (path->peer->domainname)
10547 json_object_string_add(json_peer, "domainname",
10548 path->peer->domainname);
10549
10550 if (path->peer->conf_if)
10551 json_object_string_add(json_peer, "interface",
10552 path->peer->conf_if);
10553 } else {
10554 if (path->peer->conf_if) {
10555 if (path->peer->hostname
10556 && CHECK_FLAG(path->peer->bgp->flags,
10557 BGP_FLAG_SHOW_HOSTNAME))
10558 vty_out(vty, " from %s(%s)",
10559 path->peer->hostname,
10560 path->peer->conf_if);
10561 else
10562 vty_out(vty, " from %s",
10563 path->peer->conf_if);
10564 } else {
10565 if (path->peer->hostname
10566 && CHECK_FLAG(path->peer->bgp->flags,
10567 BGP_FLAG_SHOW_HOSTNAME))
10568 vty_out(vty, " from %s(%s)",
10569 path->peer->hostname,
10570 path->peer->host);
10571 else
10572 vty_out(vty, " from %pSU",
10573 &path->peer->su);
10574 }
10575
10576 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10577 vty_out(vty, " (%pI4)", &attr->originator_id);
10578 else
10579 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10580 }
10581 }
10582
10583 /*
10584 * Note when vrfid of nexthop is different from that of prefix
10585 */
10586 if (path->extra && path->extra->bgp_orig) {
10587 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10588
10589 if (json_paths) {
10590 const char *vn;
10591
10592 if (path->extra->bgp_orig->inst_type
10593 == BGP_INSTANCE_TYPE_DEFAULT)
10594 vn = VRF_DEFAULT_NAME;
10595 else
10596 vn = path->extra->bgp_orig->name;
10597
10598 json_object_string_add(json_path, "nhVrfName", vn);
10599
10600 if (nexthop_vrfid == VRF_UNKNOWN) {
10601 json_object_int_add(json_path, "nhVrfId", -1);
10602 } else {
10603 json_object_int_add(json_path, "nhVrfId",
10604 (int)nexthop_vrfid);
10605 }
10606 } else {
10607 if (nexthop_vrfid == VRF_UNKNOWN)
10608 vty_out(vty, " vrf ?");
10609 else {
10610 struct vrf *vrf;
10611
10612 vrf = vrf_lookup_by_id(nexthop_vrfid);
10613 vty_out(vty, " vrf %s(%u)",
10614 VRF_LOGNAME(vrf), nexthop_vrfid);
10615 }
10616 }
10617 }
10618
10619 if (nexthop_self) {
10620 if (json_paths) {
10621 json_object_boolean_true_add(json_path,
10622 "announceNexthopSelf");
10623 } else {
10624 vty_out(vty, " announce-nh-self");
10625 }
10626 }
10627
10628 if (!json_paths)
10629 vty_out(vty, "\n");
10630
10631 /* display the link-local nexthop */
10632 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10633 if (json_paths) {
10634 json_nexthop_ll = json_object_new_object();
10635 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10636 &attr->mp_nexthop_local);
10637
10638 if (path->peer->hostname)
10639 json_object_string_add(json_nexthop_ll,
10640 "hostname",
10641 path->peer->hostname);
10642
10643 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10644 json_object_string_add(json_nexthop_ll, "scope",
10645 "link-local");
10646
10647 json_object_boolean_true_add(json_nexthop_ll,
10648 "accessible");
10649
10650 if (!attr->mp_nexthop_prefer_global)
10651 json_object_boolean_true_add(json_nexthop_ll,
10652 "used");
10653 else
10654 json_object_boolean_true_add(
10655 json_nexthop_global, "used");
10656 } else {
10657 vty_out(vty, " (%s) %s\n",
10658 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10659 buf, INET6_ADDRSTRLEN),
10660 attr->mp_nexthop_prefer_global
10661 ? "(prefer-global)"
10662 : "(used)");
10663 }
10664 }
10665 /* If we do not have a link-local nexthop then we must flag the
10666 global as "used" */
10667 else {
10668 if (json_paths)
10669 json_object_boolean_true_add(json_nexthop_global,
10670 "used");
10671 }
10672
10673 if (safi == SAFI_EVPN &&
10674 bgp_evpn_is_esi_valid(&attr->esi)) {
10675 route_vty_out_detail_es_info(vty, path, attr, json_path);
10676 }
10677
10678 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10679 * Int/Ext/Local, Atomic, best */
10680 if (json_paths)
10681 json_object_string_add(json_path, "origin",
10682 bgp_origin_long_str[attr->origin]);
10683 else
10684 vty_out(vty, " Origin %s",
10685 bgp_origin_long_str[attr->origin]);
10686
10687 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10688 if (json_paths)
10689 json_object_int_add(json_path, "metric", attr->med);
10690 else
10691 vty_out(vty, ", metric %u", attr->med);
10692 }
10693
10694 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10695 if (json_paths)
10696 json_object_int_add(json_path, "locPrf",
10697 attr->local_pref);
10698 else
10699 vty_out(vty, ", localpref %u", attr->local_pref);
10700 }
10701
10702 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10703 if (json_paths)
10704 json_object_int_add(json_path, "aigpMetric",
10705 bgp_attr_get_aigp_metric(attr));
10706 else
10707 vty_out(vty, ", aigp-metric %" PRIu64,
10708 bgp_attr_get_aigp_metric(attr));
10709 }
10710
10711 if (attr->weight != 0) {
10712 if (json_paths)
10713 json_object_int_add(json_path, "weight", attr->weight);
10714 else
10715 vty_out(vty, ", weight %u", attr->weight);
10716 }
10717
10718 if (attr->tag != 0) {
10719 if (json_paths)
10720 json_object_int_add(json_path, "tag", attr->tag);
10721 else
10722 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10723 }
10724
10725 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10726 if (json_paths)
10727 json_object_boolean_false_add(json_path, "valid");
10728 else
10729 vty_out(vty, ", invalid");
10730 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10731 if (json_paths)
10732 json_object_boolean_true_add(json_path, "valid");
10733 else
10734 vty_out(vty, ", valid");
10735 }
10736
10737 if (json_paths)
10738 json_object_int_add(json_path, "version", bn->version);
10739
10740 if (path->peer != bgp->peer_self) {
10741 if (path->peer->as == path->peer->local_as) {
10742 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10743 if (json_paths)
10744 json_object_string_add(
10745 json_peer, "type",
10746 "confed-internal");
10747 else
10748 vty_out(vty, ", confed-internal");
10749 } else {
10750 if (json_paths)
10751 json_object_string_add(
10752 json_peer, "type", "internal");
10753 else
10754 vty_out(vty, ", internal");
10755 }
10756 } else {
10757 if (bgp_confederation_peers_check(bgp,
10758 path->peer->as)) {
10759 if (json_paths)
10760 json_object_string_add(
10761 json_peer, "type",
10762 "confed-external");
10763 else
10764 vty_out(vty, ", confed-external");
10765 } else {
10766 if (json_paths)
10767 json_object_string_add(
10768 json_peer, "type", "external");
10769 else
10770 vty_out(vty, ", external");
10771 }
10772 }
10773 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10774 if (json_paths) {
10775 json_object_boolean_true_add(json_path, "aggregated");
10776 json_object_boolean_true_add(json_path, "local");
10777 } else {
10778 vty_out(vty, ", aggregated, local");
10779 }
10780 } else if (path->type != ZEBRA_ROUTE_BGP) {
10781 if (json_paths)
10782 json_object_boolean_true_add(json_path, "sourced");
10783 else
10784 vty_out(vty, ", sourced");
10785 } else {
10786 if (json_paths) {
10787 json_object_boolean_true_add(json_path, "sourced");
10788 json_object_boolean_true_add(json_path, "local");
10789 } else {
10790 vty_out(vty, ", sourced, local");
10791 }
10792 }
10793
10794 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10795 if (json_paths)
10796 json_object_boolean_true_add(json_path,
10797 "atomicAggregate");
10798 else
10799 vty_out(vty, ", atomic-aggregate");
10800 }
10801
10802 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10803 if (json_paths)
10804 json_object_int_add(json_path, "otc", attr->otc);
10805 else
10806 vty_out(vty, ", otc %u", attr->otc);
10807 }
10808
10809 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10810 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10811 && bgp_path_info_mpath_count(path))) {
10812 if (json_paths)
10813 json_object_boolean_true_add(json_path, "multipath");
10814 else
10815 vty_out(vty, ", multipath");
10816 }
10817
10818 // Mark the bestpath(s)
10819 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10820 first_as = aspath_get_first_as(attr->aspath);
10821
10822 if (json_paths) {
10823 if (!json_bestpath)
10824 json_bestpath = json_object_new_object();
10825 json_object_int_add(json_bestpath, "bestpathFromAs",
10826 first_as);
10827 } else {
10828 if (first_as)
10829 vty_out(vty, ", bestpath-from-AS %u", first_as);
10830 else
10831 vty_out(vty, ", bestpath-from-AS Local");
10832 }
10833 }
10834
10835 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10836 if (json_paths) {
10837 if (!json_bestpath)
10838 json_bestpath = json_object_new_object();
10839 json_object_boolean_true_add(json_bestpath, "overall");
10840 json_object_string_add(
10841 json_bestpath, "selectionReason",
10842 bgp_path_selection_reason2str(bn->reason));
10843 } else {
10844 vty_out(vty, ", best");
10845 vty_out(vty, " (%s)",
10846 bgp_path_selection_reason2str(bn->reason));
10847 }
10848 }
10849
10850 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10851 if (json_paths)
10852 json_object_string_add(
10853 json_path, "rpkiValidationState",
10854 bgp_rpki_validation2str(rpki_curr_state));
10855 else
10856 vty_out(vty, ", rpki validation-state: %s",
10857 bgp_rpki_validation2str(rpki_curr_state));
10858 }
10859
10860 if (json_bestpath)
10861 json_object_object_add(json_path, "bestpath", json_bestpath);
10862
10863 if (!json_paths)
10864 vty_out(vty, "\n");
10865
10866 /* Line 4 display Community */
10867 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10868 if (json_paths) {
10869 if (!bgp_attr_get_community(attr)->json)
10870 community_str(bgp_attr_get_community(attr),
10871 true, true);
10872 json_object_lock(bgp_attr_get_community(attr)->json);
10873 json_object_object_add(
10874 json_path, "community",
10875 bgp_attr_get_community(attr)->json);
10876 } else {
10877 vty_out(vty, " Community: %s\n",
10878 bgp_attr_get_community(attr)->str);
10879 }
10880 }
10881
10882 /* Line 5 display Extended-community */
10883 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10884 if (json_paths) {
10885 json_ext_community = json_object_new_object();
10886 json_object_string_add(
10887 json_ext_community, "string",
10888 bgp_attr_get_ecommunity(attr)->str);
10889 json_object_object_add(json_path, "extendedCommunity",
10890 json_ext_community);
10891 } else {
10892 vty_out(vty, " Extended Community: %s\n",
10893 bgp_attr_get_ecommunity(attr)->str);
10894 }
10895 }
10896
10897 /* Line 6 display Large community */
10898 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10899 if (json_paths) {
10900 if (!bgp_attr_get_lcommunity(attr)->json)
10901 lcommunity_str(bgp_attr_get_lcommunity(attr),
10902 true, true);
10903 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10904 json_object_object_add(
10905 json_path, "largeCommunity",
10906 bgp_attr_get_lcommunity(attr)->json);
10907 } else {
10908 vty_out(vty, " Large Community: %s\n",
10909 bgp_attr_get_lcommunity(attr)->str);
10910 }
10911 }
10912
10913 /* Line 7 display Originator, Cluster-id */
10914 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10915 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10916 char buf[BUFSIZ] = {0};
10917
10918 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10919 if (json_paths)
10920 json_object_string_addf(json_path,
10921 "originatorId", "%pI4",
10922 &attr->originator_id);
10923 else
10924 vty_out(vty, " Originator: %pI4",
10925 &attr->originator_id);
10926 }
10927
10928 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10929 struct cluster_list *cluster =
10930 bgp_attr_get_cluster(attr);
10931 int i;
10932
10933 if (json_paths) {
10934 json_cluster_list = json_object_new_object();
10935 json_cluster_list_list =
10936 json_object_new_array();
10937
10938 for (i = 0; i < cluster->length / 4; i++) {
10939 json_string = json_object_new_string(
10940 inet_ntop(AF_INET,
10941 &cluster->list[i],
10942 buf, sizeof(buf)));
10943 json_object_array_add(
10944 json_cluster_list_list,
10945 json_string);
10946 }
10947
10948 /*
10949 * struct cluster_list does not have
10950 * "str" variable like aspath and community
10951 * do. Add this someday if someone asks
10952 * for it.
10953 * json_object_string_add(json_cluster_list,
10954 * "string", cluster->str);
10955 */
10956 json_object_object_add(json_cluster_list,
10957 "list",
10958 json_cluster_list_list);
10959 json_object_object_add(json_path, "clusterList",
10960 json_cluster_list);
10961 } else {
10962 vty_out(vty, ", Cluster list: ");
10963
10964 for (i = 0; i < cluster->length / 4; i++) {
10965 vty_out(vty, "%pI4 ",
10966 &cluster->list[i]);
10967 }
10968 }
10969 }
10970
10971 if (!json_paths)
10972 vty_out(vty, "\n");
10973 }
10974
10975 if (path->extra && path->extra->damp_info)
10976 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10977
10978 /* Remote Label */
10979 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10980 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10981 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10982 &bos);
10983
10984 if (json_paths)
10985 json_object_int_add(json_path, "remoteLabel", label);
10986 else
10987 vty_out(vty, " Remote label: %d\n", label);
10988 }
10989
10990 /* Remote SID */
10991 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10992 if (json_paths)
10993 json_object_string_addf(json_path, "remoteSid", "%pI6",
10994 &path->extra->sid[0].sid);
10995 else
10996 vty_out(vty, " Remote SID: %pI6\n",
10997 &path->extra->sid[0].sid);
10998 }
10999
11000 /* Label Index */
11001 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11002 if (json_paths)
11003 json_object_int_add(json_path, "labelIndex",
11004 attr->label_index);
11005 else
11006 vty_out(vty, " Label Index: %d\n",
11007 attr->label_index);
11008 }
11009
11010 /* Line 8 display Addpath IDs */
11011 if (path->addpath_rx_id
11012 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11013 if (json_paths) {
11014 json_object_int_add(json_path, "addpathRxId",
11015 path->addpath_rx_id);
11016
11017 /* Keep backwards compatibility with the old API
11018 * by putting TX All's ID in the old field
11019 */
11020 json_object_int_add(
11021 json_path, "addpathTxId",
11022 path->tx_addpath
11023 .addpath_tx_id[BGP_ADDPATH_ALL]);
11024
11025 /* ... but create a specific field for each
11026 * strategy
11027 */
11028 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11029 json_object_int_add(
11030 json_path,
11031 bgp_addpath_names(i)->id_json_name,
11032 path->tx_addpath.addpath_tx_id[i]);
11033 }
11034 } else {
11035 vty_out(vty, " AddPath ID: RX %u, ",
11036 path->addpath_rx_id);
11037
11038 route_vty_out_tx_ids(vty, &path->tx_addpath);
11039 }
11040 }
11041
11042 /* If we used addpath to TX a non-bestpath we need to display
11043 * "Advertised to" on a path-by-path basis
11044 */
11045 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11046 first = 1;
11047
11048 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11049 addpath_capable =
11050 bgp_addpath_encode_tx(peer, afi, safi);
11051 has_adj = bgp_adj_out_lookup(
11052 peer, path->net,
11053 bgp_addpath_id_for_peer(peer, afi, safi,
11054 &path->tx_addpath));
11055
11056 if ((addpath_capable && has_adj)
11057 || (!addpath_capable && has_adj
11058 && CHECK_FLAG(path->flags,
11059 BGP_PATH_SELECTED))) {
11060 if (json_path && !json_adv_to)
11061 json_adv_to = json_object_new_object();
11062
11063 route_vty_out_advertised_to(
11064 vty, peer, &first,
11065 " Advertised to:", json_adv_to);
11066 }
11067 }
11068
11069 if (json_path) {
11070 if (json_adv_to) {
11071 json_object_object_add(
11072 json_path, "advertisedTo", json_adv_to);
11073 }
11074 } else {
11075 if (!first) {
11076 vty_out(vty, "\n");
11077 }
11078 }
11079 }
11080
11081 /* Line 9 display Uptime */
11082 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11083 if (json_paths) {
11084 json_last_update = json_object_new_object();
11085 json_object_int_add(json_last_update, "epoch", tbuf);
11086 json_object_string_add(json_last_update, "string",
11087 ctime(&tbuf));
11088 json_object_object_add(json_path, "lastUpdate",
11089 json_last_update);
11090 } else
11091 vty_out(vty, " Last update: %s", ctime(&tbuf));
11092
11093 /* Line 10 display PMSI tunnel attribute, if present */
11094 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11095 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11096 bgp_attr_get_pmsi_tnl_type(attr),
11097 PMSI_TNLTYPE_STR_DEFAULT);
11098
11099 if (json_paths) {
11100 json_pmsi = json_object_new_object();
11101 json_object_string_add(json_pmsi, "tunnelType", str);
11102 json_object_int_add(json_pmsi, "label",
11103 label2vni(&attr->label));
11104 json_object_object_add(json_path, "pmsi", json_pmsi);
11105 } else
11106 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11107 str, label2vni(&attr->label));
11108 }
11109
11110 if (path->peer->t_gr_restart &&
11111 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11112 unsigned long gr_remaining =
11113 event_timer_remain_second(path->peer->t_gr_restart);
11114
11115 if (json_paths) {
11116 json_object_int_add(json_path,
11117 "gracefulRestartSecondsRemaining",
11118 gr_remaining);
11119 } else
11120 vty_out(vty,
11121 " Time until Graceful Restart stale route deleted: %lu\n",
11122 gr_remaining);
11123 }
11124
11125 if (path->peer->t_llgr_stale[afi][safi] &&
11126 bgp_attr_get_community(attr) &&
11127 community_include(bgp_attr_get_community(attr),
11128 COMMUNITY_LLGR_STALE)) {
11129 unsigned long llgr_remaining = event_timer_remain_second(
11130 path->peer->t_llgr_stale[afi][safi]);
11131
11132 if (json_paths) {
11133 json_object_int_add(json_path, "llgrSecondsRemaining",
11134 llgr_remaining);
11135 } else
11136 vty_out(vty,
11137 " Time until Long-lived stale route deleted: %lu\n",
11138 llgr_remaining);
11139 }
11140
11141 /* Output some debug about internal state of the dest flags */
11142 if (json_paths) {
11143 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11144 json_object_boolean_true_add(json_path, "processScheduled");
11145 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11146 json_object_boolean_true_add(json_path, "userCleared");
11147 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11148 json_object_boolean_true_add(json_path, "labelChanged");
11149 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11150 json_object_boolean_true_add(json_path, "registeredForLabel");
11151 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11152 json_object_boolean_true_add(json_path, "selectDefered");
11153 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11154 json_object_boolean_true_add(json_path, "fibInstalled");
11155 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11156 json_object_boolean_true_add(json_path, "fibPending");
11157
11158 if (json_nexthop_global || json_nexthop_ll) {
11159 json_nexthops = json_object_new_array();
11160
11161 if (json_nexthop_global)
11162 json_object_array_add(json_nexthops,
11163 json_nexthop_global);
11164
11165 if (json_nexthop_ll)
11166 json_object_array_add(json_nexthops,
11167 json_nexthop_ll);
11168
11169 json_object_object_add(json_path, "nexthops",
11170 json_nexthops);
11171 }
11172
11173 json_object_object_add(json_path, "peer", json_peer);
11174 json_object_array_add(json_paths, json_path);
11175 }
11176 }
11177
11178 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11179 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11180 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11181
11182 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11183 afi_t afi, safi_t safi, enum bgp_show_type type,
11184 bool use_json);
11185 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11186 const char *comstr, int exact, afi_t afi,
11187 safi_t safi, uint16_t show_flags);
11188
11189 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11190 struct bgp_table *table, enum bgp_show_type type,
11191 void *output_arg, const char *rd, int is_last,
11192 unsigned long *output_cum, unsigned long *total_cum,
11193 unsigned long *json_header_depth, uint16_t show_flags,
11194 enum rpki_states rpki_target_state)
11195 {
11196 struct bgp_path_info *pi;
11197 struct bgp_dest *dest;
11198 bool header = true;
11199 bool json_detail_header = false;
11200 int display;
11201 unsigned long output_count = 0;
11202 unsigned long total_count = 0;
11203 struct prefix *p;
11204 json_object *json_paths = NULL;
11205 int first = 1;
11206 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11207 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11208 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11209 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11210 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11211
11212 if (output_cum && *output_cum != 0)
11213 header = false;
11214
11215 if (use_json && !*json_header_depth) {
11216 if (all)
11217 *json_header_depth = 1;
11218 else {
11219 vty_out(vty, "{\n");
11220 *json_header_depth = 2;
11221 }
11222 vty_out(vty,
11223 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11224 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11225 " \"localAS\": ",
11226 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11227 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11228 ? VRF_DEFAULT_NAME
11229 : bgp->name,
11230 table->version, &bgp->router_id,
11231 bgp->default_local_pref);
11232 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11233 ((bgp->asnotation == ASNOTATION_DOT) &&
11234 (bgp->as < UINT16_MAX)))
11235 vty_out(vty, "%u", bgp->as);
11236 else {
11237 vty_out(vty, "\"");
11238 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11239 vty_out(vty, "\"");
11240 }
11241 vty_out(vty, ",\n \"routes\": { ");
11242 if (rd) {
11243 vty_out(vty, " \"routeDistinguishers\" : {");
11244 ++*json_header_depth;
11245 }
11246 }
11247
11248 if (use_json && rd) {
11249 vty_out(vty, " \"%s\" : { ", rd);
11250 }
11251
11252 /* Check for 'json detail', where we need header output once per dest */
11253 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11254 type != bgp_show_type_damp_neighbor &&
11255 type != bgp_show_type_flap_statistics &&
11256 type != bgp_show_type_flap_neighbor)
11257 json_detail_header = true;
11258
11259 /* Start processing of routes. */
11260 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11261 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11262 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11263 bool json_detail_header_used = false;
11264
11265 pi = bgp_dest_get_bgp_path_info(dest);
11266 if (pi == NULL)
11267 continue;
11268
11269 display = 0;
11270 if (use_json)
11271 json_paths = json_object_new_array();
11272 else
11273 json_paths = NULL;
11274
11275 for (; pi; pi = pi->next) {
11276 struct community *picomm = NULL;
11277
11278 picomm = bgp_attr_get_community(pi->attr);
11279
11280 total_count++;
11281
11282 if (type == bgp_show_type_prefix_version) {
11283 uint32_t version =
11284 strtoul(output_arg, NULL, 10);
11285 if (dest->version < version)
11286 continue;
11287 }
11288
11289 if (type == bgp_show_type_community_alias) {
11290 char *alias = output_arg;
11291 char **communities;
11292 int num;
11293 bool found = false;
11294
11295 if (picomm) {
11296 frrstr_split(picomm->str, " ",
11297 &communities, &num);
11298 for (int i = 0; i < num; i++) {
11299 const char *com2alias =
11300 bgp_community2alias(
11301 communities[i]);
11302 if (!found
11303 && strcmp(alias, com2alias)
11304 == 0)
11305 found = true;
11306 XFREE(MTYPE_TMP,
11307 communities[i]);
11308 }
11309 XFREE(MTYPE_TMP, communities);
11310 }
11311
11312 if (!found &&
11313 bgp_attr_get_lcommunity(pi->attr)) {
11314 frrstr_split(bgp_attr_get_lcommunity(
11315 pi->attr)
11316 ->str,
11317 " ", &communities, &num);
11318 for (int i = 0; i < num; i++) {
11319 const char *com2alias =
11320 bgp_community2alias(
11321 communities[i]);
11322 if (!found
11323 && strcmp(alias, com2alias)
11324 == 0)
11325 found = true;
11326 XFREE(MTYPE_TMP,
11327 communities[i]);
11328 }
11329 XFREE(MTYPE_TMP, communities);
11330 }
11331
11332 if (!found)
11333 continue;
11334 }
11335
11336 if (type == bgp_show_type_rpki) {
11337 if (dest_p->family == AF_INET
11338 || dest_p->family == AF_INET6)
11339 rpki_curr_state = hook_call(
11340 bgp_rpki_prefix_status,
11341 pi->peer, pi->attr, dest_p);
11342 if (rpki_target_state != RPKI_NOT_BEING_USED
11343 && rpki_curr_state != rpki_target_state)
11344 continue;
11345 }
11346
11347 if (type == bgp_show_type_flap_statistics
11348 || type == bgp_show_type_flap_neighbor
11349 || type == bgp_show_type_dampend_paths
11350 || type == bgp_show_type_damp_neighbor) {
11351 if (!(pi->extra && pi->extra->damp_info))
11352 continue;
11353 }
11354 if (type == bgp_show_type_regexp) {
11355 regex_t *regex = output_arg;
11356
11357 if (bgp_regexec(regex, pi->attr->aspath)
11358 == REG_NOMATCH)
11359 continue;
11360 }
11361 if (type == bgp_show_type_prefix_list) {
11362 struct prefix_list *plist = output_arg;
11363
11364 if (prefix_list_apply(plist, dest_p)
11365 != PREFIX_PERMIT)
11366 continue;
11367 }
11368 if (type == bgp_show_type_access_list) {
11369 struct access_list *alist = output_arg;
11370
11371 if (access_list_apply(alist, dest_p) !=
11372 FILTER_PERMIT)
11373 continue;
11374 }
11375 if (type == bgp_show_type_filter_list) {
11376 struct as_list *as_list = output_arg;
11377
11378 if (as_list_apply(as_list, pi->attr->aspath)
11379 != AS_FILTER_PERMIT)
11380 continue;
11381 }
11382 if (type == bgp_show_type_route_map) {
11383 struct route_map *rmap = output_arg;
11384 struct bgp_path_info path;
11385 struct bgp_path_info_extra extra;
11386 struct attr dummy_attr = {};
11387 route_map_result_t ret;
11388
11389 dummy_attr = *pi->attr;
11390
11391 prep_for_rmap_apply(&path, &extra, dest, pi,
11392 pi->peer, &dummy_attr);
11393
11394 ret = route_map_apply(rmap, dest_p, &path);
11395 bgp_attr_flush(&dummy_attr);
11396 if (ret == RMAP_DENYMATCH)
11397 continue;
11398 }
11399 if (type == bgp_show_type_neighbor
11400 || type == bgp_show_type_flap_neighbor
11401 || type == bgp_show_type_damp_neighbor) {
11402 union sockunion *su = output_arg;
11403
11404 if (pi->peer == NULL
11405 || pi->peer->su_remote == NULL
11406 || !sockunion_same(pi->peer->su_remote, su))
11407 continue;
11408 }
11409 if (type == bgp_show_type_cidr_only) {
11410 uint32_t destination;
11411
11412 destination = ntohl(dest_p->u.prefix4.s_addr);
11413 if (IN_CLASSC(destination)
11414 && dest_p->prefixlen == 24)
11415 continue;
11416 if (IN_CLASSB(destination)
11417 && dest_p->prefixlen == 16)
11418 continue;
11419 if (IN_CLASSA(destination)
11420 && dest_p->prefixlen == 8)
11421 continue;
11422 }
11423 if (type == bgp_show_type_prefix_longer) {
11424 p = output_arg;
11425 if (!prefix_match(p, dest_p))
11426 continue;
11427 }
11428 if (type == bgp_show_type_community_all) {
11429 if (!picomm)
11430 continue;
11431 }
11432 if (type == bgp_show_type_community) {
11433 struct community *com = output_arg;
11434
11435 if (!picomm || !community_match(picomm, com))
11436 continue;
11437 }
11438 if (type == bgp_show_type_community_exact) {
11439 struct community *com = output_arg;
11440
11441 if (!picomm || !community_cmp(picomm, com))
11442 continue;
11443 }
11444 if (type == bgp_show_type_community_list) {
11445 struct community_list *list = output_arg;
11446
11447 if (!community_list_match(picomm, list))
11448 continue;
11449 }
11450 if (type == bgp_show_type_community_list_exact) {
11451 struct community_list *list = output_arg;
11452
11453 if (!community_list_exact_match(picomm, list))
11454 continue;
11455 }
11456 if (type == bgp_show_type_lcommunity) {
11457 struct lcommunity *lcom = output_arg;
11458
11459 if (!bgp_attr_get_lcommunity(pi->attr) ||
11460 !lcommunity_match(
11461 bgp_attr_get_lcommunity(pi->attr),
11462 lcom))
11463 continue;
11464 }
11465
11466 if (type == bgp_show_type_lcommunity_exact) {
11467 struct lcommunity *lcom = output_arg;
11468
11469 if (!bgp_attr_get_lcommunity(pi->attr) ||
11470 !lcommunity_cmp(
11471 bgp_attr_get_lcommunity(pi->attr),
11472 lcom))
11473 continue;
11474 }
11475 if (type == bgp_show_type_lcommunity_list) {
11476 struct community_list *list = output_arg;
11477
11478 if (!lcommunity_list_match(
11479 bgp_attr_get_lcommunity(pi->attr),
11480 list))
11481 continue;
11482 }
11483 if (type
11484 == bgp_show_type_lcommunity_list_exact) {
11485 struct community_list *list = output_arg;
11486
11487 if (!lcommunity_list_exact_match(
11488 bgp_attr_get_lcommunity(pi->attr),
11489 list))
11490 continue;
11491 }
11492 if (type == bgp_show_type_lcommunity_all) {
11493 if (!bgp_attr_get_lcommunity(pi->attr))
11494 continue;
11495 }
11496 if (type == bgp_show_type_dampend_paths
11497 || type == bgp_show_type_damp_neighbor) {
11498 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11499 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11500 continue;
11501 }
11502 if (type == bgp_show_type_self_originated) {
11503 if (pi->peer != bgp->peer_self)
11504 continue;
11505 }
11506
11507 if (!use_json && header) {
11508 vty_out(vty,
11509 "BGP table version is %" PRIu64
11510 ", local router ID is %pI4, vrf id ",
11511 table->version, &bgp->router_id);
11512 if (bgp->vrf_id == VRF_UNKNOWN)
11513 vty_out(vty, "%s", VRFID_NONE_STR);
11514 else
11515 vty_out(vty, "%u", bgp->vrf_id);
11516 vty_out(vty, "\n");
11517 vty_out(vty, "Default local pref %u, ",
11518 bgp->default_local_pref);
11519 vty_out(vty, "local AS ");
11520 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11521 &bgp->as);
11522 vty_out(vty, "\n");
11523 if (!detail_routes) {
11524 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11525 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11526 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11527 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11528 }
11529 if (type == bgp_show_type_dampend_paths
11530 || type == bgp_show_type_damp_neighbor)
11531 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11532 else if (type == bgp_show_type_flap_statistics
11533 || type == bgp_show_type_flap_neighbor)
11534 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11535 else if (!detail_routes)
11536 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11537 : BGP_SHOW_HEADER));
11538 header = false;
11539
11540 }
11541 if (rd != NULL && !display && !output_count) {
11542 if (!use_json)
11543 vty_out(vty,
11544 "Route Distinguisher: %s\n",
11545 rd);
11546 }
11547 if (type == bgp_show_type_dampend_paths
11548 || type == bgp_show_type_damp_neighbor)
11549 damp_route_vty_out(vty, dest_p, pi, display,
11550 AFI_IP, safi, use_json,
11551 json_paths);
11552 else if (type == bgp_show_type_flap_statistics
11553 || type == bgp_show_type_flap_neighbor)
11554 flap_route_vty_out(vty, dest_p, pi, display,
11555 AFI_IP, safi, use_json,
11556 json_paths);
11557 else {
11558 if (detail_routes || detail_json) {
11559 const struct prefix_rd *prd = NULL;
11560
11561 if (dest->pdest)
11562 prd = bgp_rd_from_dest(
11563 dest->pdest, safi);
11564
11565 if (!use_json)
11566 route_vty_out_detail_header(
11567 vty, bgp, dest,
11568 bgp_dest_get_prefix(
11569 dest),
11570 prd, table->afi, safi,
11571 NULL, false);
11572
11573 route_vty_out_detail(
11574 vty, bgp, dest, dest_p, pi,
11575 family2afi(dest_p->family),
11576 safi, RPKI_NOT_BEING_USED,
11577 json_paths);
11578 } else {
11579 route_vty_out(vty, dest_p, pi, display,
11580 safi, json_paths, wide);
11581 }
11582 }
11583 display++;
11584 }
11585
11586 if (display) {
11587 output_count++;
11588 if (!use_json)
11589 continue;
11590
11591 /* encode prefix */
11592 if (dest_p->family == AF_FLOWSPEC) {
11593 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11594
11595
11596 bgp_fs_nlri_get_string(
11597 (unsigned char *)
11598 dest_p->u.prefix_flowspec.ptr,
11599 dest_p->u.prefix_flowspec.prefixlen,
11600 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11601 family2afi(dest_p->u
11602 .prefix_flowspec.family));
11603 if (first)
11604 vty_out(vty, "\"%s/%d\": ", retstr,
11605 dest_p->u.prefix_flowspec
11606 .prefixlen);
11607 else
11608 vty_out(vty, ",\"%s/%d\": ", retstr,
11609 dest_p->u.prefix_flowspec
11610 .prefixlen);
11611 } else {
11612 if (first)
11613 vty_out(vty, "\"%pFX\": ", dest_p);
11614 else
11615 vty_out(vty, ",\"%pFX\": ", dest_p);
11616 }
11617
11618 /* This is used for 'json detail' vty keywords.
11619 *
11620 * In plain 'json' the per-prefix header is encoded
11621 * as a standalone dictionary in the first json_paths
11622 * array element:
11623 * "<prefix>": [{header}, {path-1}, {path-N}]
11624 * (which is confusing and borderline broken)
11625 *
11626 * For 'json detail' this changes the value
11627 * of each prefix-key to be a dictionary where each
11628 * header item has its own key, and json_paths is
11629 * tucked under the "paths" key:
11630 * "<prefix>": {
11631 * "<header-key-1>": <header-val-1>,
11632 * "<header-key-N>": <header-val-N>,
11633 * "paths": [{path-1}, {path-N}]
11634 * }
11635 */
11636 if (json_detail_header && json_paths != NULL) {
11637 const struct prefix_rd *prd;
11638
11639 /* Start per-prefix dictionary */
11640 vty_out(vty, "{\n");
11641
11642 prd = bgp_rd_from_dest(dest, safi);
11643
11644 route_vty_out_detail_header(
11645 vty, bgp, dest,
11646 bgp_dest_get_prefix(dest), prd,
11647 table->afi, safi, json_paths, true);
11648
11649 vty_out(vty, "\"paths\": ");
11650 json_detail_header_used = true;
11651 }
11652
11653 /*
11654 * We are using no_pretty here because under
11655 * extremely high settings( say lots and lots of
11656 * routes with lots and lots of ways to reach
11657 * that route via different paths ) this can
11658 * save several minutes of output when FRR
11659 * is run on older cpu's or more underperforming
11660 * routers out there
11661 */
11662 vty_json_no_pretty(vty, json_paths);
11663
11664 /* End per-prefix dictionary */
11665 if (json_detail_header_used)
11666 vty_out(vty, "} ");
11667
11668 json_paths = NULL;
11669 first = 0;
11670 } else
11671 json_object_free(json_paths);
11672 }
11673
11674 if (output_cum) {
11675 output_count += *output_cum;
11676 *output_cum = output_count;
11677 }
11678 if (total_cum) {
11679 total_count += *total_cum;
11680 *total_cum = total_count;
11681 }
11682 if (use_json) {
11683 if (rd) {
11684 vty_out(vty, " }%s ", (is_last ? "" : ","));
11685 }
11686 if (is_last) {
11687 unsigned long i;
11688 for (i = 0; i < *json_header_depth; ++i)
11689 vty_out(vty, " } ");
11690 if (!all)
11691 vty_out(vty, "\n");
11692 }
11693 } else {
11694 if (is_last) {
11695 /* No route is displayed */
11696 if (output_count == 0) {
11697 if (type == bgp_show_type_normal)
11698 vty_out(vty,
11699 "No BGP prefixes displayed, %ld exist\n",
11700 total_count);
11701 } else
11702 vty_out(vty,
11703 "\nDisplayed %ld routes and %ld total paths\n",
11704 output_count, total_count);
11705 }
11706 }
11707
11708 return CMD_SUCCESS;
11709 }
11710
11711 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11712 struct bgp_table *table, struct prefix_rd *prd_match,
11713 enum bgp_show_type type, void *output_arg,
11714 uint16_t show_flags)
11715 {
11716 struct bgp_dest *dest, *next;
11717 unsigned long output_cum = 0;
11718 unsigned long total_cum = 0;
11719 unsigned long json_header_depth = 0;
11720 struct bgp_table *itable;
11721 bool show_msg;
11722 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11723
11724 show_msg = (!use_json && type == bgp_show_type_normal);
11725
11726 for (dest = bgp_table_top(table); dest; dest = next) {
11727 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11728
11729 next = bgp_route_next(dest);
11730 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11731 continue;
11732
11733 itable = bgp_dest_get_bgp_table_info(dest);
11734 if (itable != NULL) {
11735 struct prefix_rd prd;
11736 char rd[RD_ADDRSTRLEN];
11737
11738 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11739 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11740 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11741 rd, next == NULL, &output_cum,
11742 &total_cum, &json_header_depth,
11743 show_flags, RPKI_NOT_BEING_USED);
11744 if (next == NULL)
11745 show_msg = false;
11746 }
11747 }
11748 if (show_msg) {
11749 if (output_cum == 0)
11750 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11751 total_cum);
11752 else
11753 vty_out(vty,
11754 "\nDisplayed %ld routes and %ld total paths\n",
11755 output_cum, total_cum);
11756 } else {
11757 if (use_json && output_cum == 0)
11758 vty_out(vty, "{}\n");
11759 }
11760 return CMD_SUCCESS;
11761 }
11762
11763 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11764 enum bgp_show_type type, void *output_arg,
11765 uint16_t show_flags, enum rpki_states rpki_target_state)
11766 {
11767 struct bgp_table *table;
11768 unsigned long json_header_depth = 0;
11769 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11770
11771 if (bgp == NULL) {
11772 bgp = bgp_get_default();
11773 }
11774
11775 if (bgp == NULL) {
11776 if (!use_json)
11777 vty_out(vty, "No BGP process is configured\n");
11778 else
11779 vty_out(vty, "{}\n");
11780 return CMD_WARNING;
11781 }
11782
11783 /* Labeled-unicast routes live in the unicast table. */
11784 if (safi == SAFI_LABELED_UNICAST)
11785 safi = SAFI_UNICAST;
11786
11787 table = bgp->rib[afi][safi];
11788 /* use MPLS and ENCAP specific shows until they are merged */
11789 if (safi == SAFI_MPLS_VPN) {
11790 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11791 output_arg, show_flags);
11792 }
11793
11794 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11795 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11796 output_arg, use_json,
11797 1, NULL, NULL);
11798 }
11799
11800 if (safi == SAFI_EVPN)
11801 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11802
11803 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11804 NULL, NULL, &json_header_depth, show_flags,
11805 rpki_target_state);
11806 }
11807
11808 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11809 safi_t safi, uint16_t show_flags)
11810 {
11811 struct listnode *node, *nnode;
11812 struct bgp *bgp;
11813 int is_first = 1;
11814 bool route_output = false;
11815 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11816
11817 if (use_json)
11818 vty_out(vty, "{\n");
11819
11820 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11821 route_output = true;
11822 if (use_json) {
11823 if (!is_first)
11824 vty_out(vty, ",\n");
11825 else
11826 is_first = 0;
11827
11828 vty_out(vty, "\"%s\":",
11829 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11830 ? VRF_DEFAULT_NAME
11831 : bgp->name);
11832 } else {
11833 vty_out(vty, "\nInstance %s:\n",
11834 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11835 ? VRF_DEFAULT_NAME
11836 : bgp->name);
11837 }
11838 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11839 show_flags, RPKI_NOT_BEING_USED);
11840 }
11841
11842 if (use_json)
11843 vty_out(vty, "}\n");
11844 else if (!route_output)
11845 vty_out(vty, "%% BGP instance not found\n");
11846 }
11847
11848 /* Header of detailed BGP route information */
11849 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11850 struct bgp_dest *dest, const struct prefix *p,
11851 const struct prefix_rd *prd, afi_t afi,
11852 safi_t safi, json_object *json,
11853 bool incremental_print)
11854 {
11855 struct bgp_path_info *pi;
11856 struct peer *peer;
11857 struct listnode *node, *nnode;
11858 char buf1[RD_ADDRSTRLEN];
11859 int count = 0;
11860 int best = 0;
11861 int suppress = 0;
11862 int accept_own = 0;
11863 int route_filter_translated_v4 = 0;
11864 int route_filter_v4 = 0;
11865 int route_filter_translated_v6 = 0;
11866 int route_filter_v6 = 0;
11867 int llgr_stale = 0;
11868 int no_llgr = 0;
11869 int accept_own_nexthop = 0;
11870 int blackhole = 0;
11871 int no_export = 0;
11872 int no_advertise = 0;
11873 int local_as = 0;
11874 int no_peer = 0;
11875 int first = 1;
11876 int has_valid_label = 0;
11877 mpls_label_t label = 0;
11878 json_object *json_adv_to = NULL;
11879 uint32_t ttl = 0;
11880 uint32_t bos = 0;
11881 uint32_t exp = 0;
11882
11883 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11884
11885 has_valid_label = bgp_is_valid_label(&label);
11886
11887 if (safi == SAFI_EVPN) {
11888 if (!json) {
11889 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11890 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11891 bgp->asnotation)
11892 : "",
11893 prd ? ":" : "", (struct prefix_evpn *)p);
11894 } else {
11895 json_object_string_add(
11896 json, "rd",
11897 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11898 bgp->asnotation)
11899 : "");
11900 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11901 }
11902 } else {
11903 if (!json) {
11904 vty_out(vty,
11905 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11906 "\n",
11907 (((safi == SAFI_MPLS_VPN ||
11908 safi == SAFI_ENCAP) &&
11909 prd)
11910 ? prefix_rd2str(prd, buf1,
11911 sizeof(buf1),
11912 bgp->asnotation)
11913 : ""),
11914 safi == SAFI_MPLS_VPN && prd ? ":" : "", p,
11915 dest->version);
11916
11917 } else {
11918 if (incremental_print) {
11919 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11920 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11921 dest->version);
11922 } else {
11923 json_object_string_addf(json, "prefix", "%pFX",
11924 p);
11925 json_object_int_add(json, "version",
11926 dest->version);
11927 }
11928 }
11929 }
11930
11931 if (has_valid_label) {
11932 if (json) {
11933 if (incremental_print)
11934 vty_out(vty, "\"localLabel\": \"%u\",\n",
11935 label);
11936 else
11937 json_object_int_add(json, "localLabel", label);
11938 } else
11939 vty_out(vty, "Local label: %d\n", label);
11940 }
11941
11942 if (!json)
11943 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11944 vty_out(vty, "not allocated\n");
11945
11946 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11947 struct community *picomm = NULL;
11948
11949 picomm = bgp_attr_get_community(pi->attr);
11950
11951 count++;
11952 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11953 best = count;
11954 if (bgp_path_suppressed(pi))
11955 suppress = 1;
11956
11957 if (!picomm)
11958 continue;
11959
11960 no_advertise += community_include(
11961 picomm, COMMUNITY_NO_ADVERTISE);
11962 no_export +=
11963 community_include(picomm, COMMUNITY_NO_EXPORT);
11964 local_as +=
11965 community_include(picomm, COMMUNITY_LOCAL_AS);
11966 accept_own +=
11967 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11968 route_filter_translated_v4 += community_include(
11969 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11970 route_filter_translated_v6 += community_include(
11971 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11972 route_filter_v4 += community_include(
11973 picomm, COMMUNITY_ROUTE_FILTER_v4);
11974 route_filter_v6 += community_include(
11975 picomm, COMMUNITY_ROUTE_FILTER_v6);
11976 llgr_stale +=
11977 community_include(picomm, COMMUNITY_LLGR_STALE);
11978 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11979 accept_own_nexthop += community_include(
11980 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11981 blackhole +=
11982 community_include(picomm, COMMUNITY_BLACKHOLE);
11983 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11984 }
11985 }
11986
11987 if (!json) {
11988 vty_out(vty, "Paths: (%d available", count);
11989 if (best) {
11990 vty_out(vty, ", best #%d", best);
11991 if (safi == SAFI_UNICAST) {
11992 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11993 vty_out(vty, ", table %s",
11994 VRF_DEFAULT_NAME);
11995 else
11996 vty_out(vty, ", vrf %s",
11997 bgp->name);
11998 }
11999 } else
12000 vty_out(vty, ", no best path");
12001
12002 if (accept_own)
12003 vty_out(vty,
12004 ", accept own local route exported and imported in different VRF");
12005 else if (route_filter_translated_v4)
12006 vty_out(vty,
12007 ", mark translated RTs for VPNv4 route filtering");
12008 else if (route_filter_v4)
12009 vty_out(vty,
12010 ", attach RT as-is for VPNv4 route filtering");
12011 else if (route_filter_translated_v6)
12012 vty_out(vty,
12013 ", mark translated RTs for VPNv6 route filtering");
12014 else if (route_filter_v6)
12015 vty_out(vty,
12016 ", attach RT as-is for VPNv6 route filtering");
12017 else if (llgr_stale)
12018 vty_out(vty,
12019 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
12020 else if (no_llgr)
12021 vty_out(vty,
12022 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
12023 else if (accept_own_nexthop)
12024 vty_out(vty,
12025 ", accept local nexthop");
12026 else if (blackhole)
12027 vty_out(vty, ", inform peer to blackhole prefix");
12028 else if (no_export)
12029 vty_out(vty, ", not advertised to EBGP peer");
12030 else if (no_advertise)
12031 vty_out(vty, ", not advertised to any peer");
12032 else if (local_as)
12033 vty_out(vty, ", not advertised outside local AS");
12034 else if (no_peer)
12035 vty_out(vty,
12036 ", inform EBGP peer not to advertise to their EBGP peers");
12037
12038 if (suppress)
12039 vty_out(vty,
12040 ", Advertisements suppressed by an aggregate.");
12041 vty_out(vty, ")\n");
12042 }
12043
12044 /* If we are not using addpath then we can display Advertised to and
12045 * that will
12046 * show what peers we advertised the bestpath to. If we are using
12047 * addpath
12048 * though then we must display Advertised to on a path-by-path basis. */
12049 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12050 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12051 if (bgp_adj_out_lookup(peer, dest, 0)) {
12052 if (json && !json_adv_to)
12053 json_adv_to = json_object_new_object();
12054
12055 route_vty_out_advertised_to(
12056 vty, peer, &first,
12057 " Advertised to non peer-group peers:\n ",
12058 json_adv_to);
12059 }
12060 }
12061
12062 if (json && json_adv_to) {
12063 if (incremental_print) {
12064 vty_out(vty, "\"advertisedTo\": ");
12065 vty_json(vty, json_adv_to);
12066 vty_out(vty, ",");
12067 } else
12068 json_object_object_add(json, "advertisedTo",
12069 json_adv_to);
12070 } else {
12071 if (!json && first)
12072 vty_out(vty, " Not advertised to any peer");
12073 vty_out(vty, "\n");
12074 }
12075 }
12076 }
12077
12078 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12079 struct bgp_dest *bgp_node, struct vty *vty,
12080 struct bgp *bgp, afi_t afi, safi_t safi,
12081 json_object *json, enum bgp_path_type pathtype,
12082 int *display, enum rpki_states rpki_target_state)
12083 {
12084 struct bgp_path_info *pi;
12085 int header = 1;
12086 json_object *json_header = NULL;
12087 json_object *json_paths = NULL;
12088 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12089
12090 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12091 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12092
12093 if (p->family == AF_INET || p->family == AF_INET6)
12094 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12095 pi->peer, pi->attr, p);
12096
12097 if (rpki_target_state != RPKI_NOT_BEING_USED
12098 && rpki_curr_state != rpki_target_state)
12099 continue;
12100
12101 if (json && !json_paths) {
12102 /* Instantiate json_paths only if path is valid */
12103 json_paths = json_object_new_array();
12104 if (pfx_rd)
12105 json_header = json_object_new_object();
12106 else
12107 json_header = json;
12108 }
12109
12110 if (header) {
12111 route_vty_out_detail_header(
12112 vty, bgp, bgp_node,
12113 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12114 safi, json_header, false);
12115 header = 0;
12116 }
12117 (*display)++;
12118
12119 if (pathtype == BGP_PATH_SHOW_ALL
12120 || (pathtype == BGP_PATH_SHOW_BESTPATH
12121 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12122 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12123 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12124 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12125 route_vty_out_detail(vty, bgp, bgp_node,
12126 bgp_dest_get_prefix(bgp_node), pi,
12127 AFI_IP, safi, rpki_curr_state,
12128 json_paths);
12129 }
12130
12131 if (json && json_paths) {
12132 json_object_object_add(json_header, "paths", json_paths);
12133
12134 if (pfx_rd)
12135 json_object_object_addf(
12136 json, json_header,
12137 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12138 }
12139 }
12140
12141 /*
12142 * Return rd based on safi
12143 */
12144 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12145 safi_t safi)
12146 {
12147 switch (safi) {
12148 case SAFI_MPLS_VPN:
12149 case SAFI_ENCAP:
12150 case SAFI_EVPN:
12151 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12152 case SAFI_UNSPEC:
12153 case SAFI_UNICAST:
12154 case SAFI_MULTICAST:
12155 case SAFI_LABELED_UNICAST:
12156 case SAFI_FLOWSPEC:
12157 case SAFI_MAX:
12158 return NULL;
12159 }
12160
12161 assert(!"Reached end of function when we were not expecting it");
12162 }
12163
12164 /* Display specified route of BGP table. */
12165 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12166 struct bgp_table *rib, const char *ip_str,
12167 afi_t afi, safi_t safi,
12168 enum rpki_states rpki_target_state,
12169 struct prefix_rd *prd, int prefix_check,
12170 enum bgp_path_type pathtype, bool use_json)
12171 {
12172 int ret;
12173 int display = 0;
12174 struct prefix match;
12175 struct bgp_dest *dest;
12176 struct bgp_dest *rm;
12177 struct bgp_table *table;
12178 json_object *json = NULL;
12179 json_object *json_paths = NULL;
12180
12181 /* Check IP address argument. */
12182 ret = str2prefix(ip_str, &match);
12183 if (!ret) {
12184 vty_out(vty, "address is malformed\n");
12185 return CMD_WARNING;
12186 }
12187
12188 match.family = afi2family(afi);
12189
12190 if (use_json)
12191 json = json_object_new_object();
12192
12193 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12194 for (dest = bgp_table_top(rib); dest;
12195 dest = bgp_route_next(dest)) {
12196 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12197
12198 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12199 continue;
12200 table = bgp_dest_get_bgp_table_info(dest);
12201 if (!table)
12202 continue;
12203
12204 rm = bgp_node_match(table, &match);
12205 if (rm == NULL)
12206 continue;
12207
12208 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12209 if (prefix_check
12210 && rm_p->prefixlen != match.prefixlen) {
12211 bgp_dest_unlock_node(rm);
12212 continue;
12213 }
12214
12215 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12216 bgp, afi, safi, json, pathtype,
12217 &display, rpki_target_state);
12218
12219 bgp_dest_unlock_node(rm);
12220 }
12221 } else if (safi == SAFI_EVPN) {
12222 struct bgp_dest *longest_pfx;
12223 bool is_exact_pfxlen_match = false;
12224
12225 for (dest = bgp_table_top(rib); dest;
12226 dest = bgp_route_next(dest)) {
12227 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12228
12229 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12230 continue;
12231 table = bgp_dest_get_bgp_table_info(dest);
12232 if (!table)
12233 continue;
12234
12235 longest_pfx = NULL;
12236 is_exact_pfxlen_match = false;
12237 /*
12238 * Search through all the prefixes for a match. The
12239 * pfx's are enumerated in ascending order of pfxlens.
12240 * So, the last pfx match is the longest match. Set
12241 * is_exact_pfxlen_match when we get exact pfxlen match
12242 */
12243 for (rm = bgp_table_top(table); rm;
12244 rm = bgp_route_next(rm)) {
12245 const struct prefix *rm_p =
12246 bgp_dest_get_prefix(rm);
12247 /*
12248 * Get prefixlen of the ip-prefix within type5
12249 * evpn route
12250 */
12251 if (evpn_type5_prefix_match(rm_p, &match)
12252 && rm->info) {
12253 longest_pfx = rm;
12254 int type5_pfxlen =
12255 bgp_evpn_get_type5_prefixlen(
12256 rm_p);
12257 if (type5_pfxlen == match.prefixlen) {
12258 is_exact_pfxlen_match = true;
12259 bgp_dest_unlock_node(rm);
12260 break;
12261 }
12262 }
12263 }
12264
12265 if (!longest_pfx)
12266 continue;
12267
12268 if (prefix_check && !is_exact_pfxlen_match)
12269 continue;
12270
12271 rm = longest_pfx;
12272 bgp_dest_lock_node(rm);
12273
12274 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12275 bgp, afi, safi, json, pathtype,
12276 &display, rpki_target_state);
12277
12278 bgp_dest_unlock_node(rm);
12279 }
12280 } else if (safi == SAFI_FLOWSPEC) {
12281 if (use_json)
12282 json_paths = json_object_new_array();
12283
12284 display = bgp_flowspec_display_match_per_ip(afi, rib,
12285 &match, prefix_check,
12286 vty,
12287 use_json,
12288 json_paths);
12289 if (use_json) {
12290 if (display)
12291 json_object_object_add(json, "paths",
12292 json_paths);
12293 else
12294 json_object_free(json_paths);
12295 }
12296 } else {
12297 dest = bgp_node_match(rib, &match);
12298 if (dest != NULL) {
12299 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12300 if (!prefix_check
12301 || dest_p->prefixlen == match.prefixlen) {
12302 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12303 safi, json, pathtype,
12304 &display, rpki_target_state);
12305 }
12306
12307 bgp_dest_unlock_node(dest);
12308 }
12309 }
12310
12311 if (use_json) {
12312 vty_json(vty, json);
12313 } else {
12314 if (!display) {
12315 vty_out(vty, "%% Network not in table\n");
12316 return CMD_WARNING;
12317 }
12318 }
12319
12320 return CMD_SUCCESS;
12321 }
12322
12323 /* Display specified route of Main RIB */
12324 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12325 afi_t afi, safi_t safi, struct prefix_rd *prd,
12326 int prefix_check, enum bgp_path_type pathtype,
12327 enum rpki_states rpki_target_state, bool use_json)
12328 {
12329 if (!bgp) {
12330 bgp = bgp_get_default();
12331 if (!bgp) {
12332 if (!use_json)
12333 vty_out(vty, "No BGP process is configured\n");
12334 else
12335 vty_out(vty, "{}\n");
12336 return CMD_WARNING;
12337 }
12338 }
12339
12340 /* labeled-unicast routes live in the unicast table */
12341 if (safi == SAFI_LABELED_UNICAST)
12342 safi = SAFI_UNICAST;
12343
12344 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12345 afi, safi, rpki_target_state, prd,
12346 prefix_check, pathtype, use_json);
12347 }
12348
12349 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12350 struct cmd_token **argv, bool exact, afi_t afi,
12351 safi_t safi, bool uj)
12352 {
12353 struct lcommunity *lcom;
12354 struct buffer *b;
12355 int i;
12356 char *str;
12357 int first = 0;
12358 uint16_t show_flags = 0;
12359 int ret;
12360
12361 if (uj)
12362 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12363
12364 b = buffer_new(1024);
12365 for (i = 0; i < argc; i++) {
12366 if (first)
12367 buffer_putc(b, ' ');
12368 else {
12369 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12370 first = 1;
12371 buffer_putstr(b, argv[i]->arg);
12372 }
12373 }
12374 }
12375 buffer_putc(b, '\0');
12376
12377 str = buffer_getstr(b);
12378 buffer_free(b);
12379
12380 lcom = lcommunity_str2com(str);
12381 XFREE(MTYPE_TMP, str);
12382 if (!lcom) {
12383 vty_out(vty, "%% Large-community malformed\n");
12384 return CMD_WARNING;
12385 }
12386
12387 ret = bgp_show(vty, bgp, afi, safi,
12388 (exact ? bgp_show_type_lcommunity_exact
12389 : bgp_show_type_lcommunity),
12390 lcom, show_flags, RPKI_NOT_BEING_USED);
12391
12392 lcommunity_free(&lcom);
12393 return ret;
12394 }
12395
12396 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12397 const char *lcom, bool exact, afi_t afi,
12398 safi_t safi, bool uj)
12399 {
12400 struct community_list *list;
12401 uint16_t show_flags = 0;
12402
12403 if (uj)
12404 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12405
12406
12407 list = community_list_lookup(bgp_clist, lcom, 0,
12408 LARGE_COMMUNITY_LIST_MASTER);
12409 if (list == NULL) {
12410 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12411 lcom);
12412 return CMD_WARNING;
12413 }
12414
12415 return bgp_show(vty, bgp, afi, safi,
12416 (exact ? bgp_show_type_lcommunity_list_exact
12417 : bgp_show_type_lcommunity_list),
12418 list, show_flags, RPKI_NOT_BEING_USED);
12419 }
12420
12421 DEFUN (show_ip_bgp_large_community_list,
12422 show_ip_bgp_large_community_list_cmd,
12423 "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]",
12424 SHOW_STR
12425 IP_STR
12426 BGP_STR
12427 BGP_INSTANCE_HELP_STR
12428 BGP_AFI_HELP_STR
12429 BGP_SAFI_WITH_LABEL_HELP_STR
12430 "Display routes matching the large-community-list\n"
12431 "large-community-list number\n"
12432 "large-community-list name\n"
12433 "Exact match of the large-communities\n"
12434 JSON_STR)
12435 {
12436 afi_t afi = AFI_IP6;
12437 safi_t safi = SAFI_UNICAST;
12438 int idx = 0;
12439 bool exact_match = 0;
12440 struct bgp *bgp = NULL;
12441 bool uj = use_json(argc, argv);
12442
12443 if (uj)
12444 argc--;
12445
12446 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12447 &bgp, uj);
12448 if (!idx)
12449 return CMD_WARNING;
12450
12451 argv_find(argv, argc, "large-community-list", &idx);
12452
12453 const char *clist_number_or_name = argv[++idx]->arg;
12454
12455 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12456 exact_match = 1;
12457
12458 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12459 exact_match, afi, safi, uj);
12460 }
12461 DEFUN (show_ip_bgp_large_community,
12462 show_ip_bgp_large_community_cmd,
12463 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12464 SHOW_STR
12465 IP_STR
12466 BGP_STR
12467 BGP_INSTANCE_HELP_STR
12468 BGP_AFI_HELP_STR
12469 BGP_SAFI_WITH_LABEL_HELP_STR
12470 "Display routes matching the large-communities\n"
12471 "List of large-community numbers\n"
12472 "Exact match of the large-communities\n"
12473 JSON_STR)
12474 {
12475 afi_t afi = AFI_IP6;
12476 safi_t safi = SAFI_UNICAST;
12477 int idx = 0;
12478 bool exact_match = 0;
12479 struct bgp *bgp = NULL;
12480 bool uj = use_json(argc, argv);
12481 uint16_t show_flags = 0;
12482
12483 if (uj) {
12484 argc--;
12485 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12486 }
12487
12488 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12489 &bgp, uj);
12490 if (!idx)
12491 return CMD_WARNING;
12492
12493 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12494 if (argv_find(argv, argc, "exact-match", &idx)) {
12495 argc--;
12496 exact_match = 1;
12497 }
12498 return bgp_show_lcommunity(vty, bgp, argc, argv,
12499 exact_match, afi, safi, uj);
12500 } else
12501 return bgp_show(vty, bgp, afi, safi,
12502 bgp_show_type_lcommunity_all, NULL, show_flags,
12503 RPKI_NOT_BEING_USED);
12504 }
12505
12506 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12507 safi_t safi, struct json_object *json_array);
12508 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12509 safi_t safi, struct json_object *json);
12510
12511
12512 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12513 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12514 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12515 "Display number of prefixes for all afi/safi\n" JSON_STR)
12516 {
12517 bool uj = use_json(argc, argv);
12518 struct bgp *bgp = NULL;
12519 safi_t safi = SAFI_UNICAST;
12520 afi_t afi = AFI_IP6;
12521 int idx = 0;
12522 struct json_object *json_all = NULL;
12523 struct json_object *json_afi_safi = NULL;
12524
12525 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12526 &bgp, false);
12527 if (!idx)
12528 return CMD_WARNING;
12529
12530 if (uj)
12531 json_all = json_object_new_object();
12532
12533 FOREACH_AFI_SAFI (afi, safi) {
12534 /*
12535 * So limit output to those afi/safi pairs that
12536 * actually have something interesting in them
12537 */
12538 if (strmatch(get_afi_safi_str(afi, safi, true),
12539 "Unknown")) {
12540 continue;
12541 }
12542 if (uj) {
12543 json_afi_safi = json_object_new_array();
12544 json_object_object_add(
12545 json_all,
12546 get_afi_safi_str(afi, safi, true),
12547 json_afi_safi);
12548 } else {
12549 json_afi_safi = NULL;
12550 }
12551
12552 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12553 }
12554
12555 if (uj)
12556 vty_json(vty, json_all);
12557
12558 return CMD_SUCCESS;
12559 }
12560
12561 /* BGP route print out function without JSON */
12562 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12563 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12564 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12565 SHOW_STR
12566 IP_STR
12567 BGP_STR
12568 BGP_INSTANCE_HELP_STR
12569 L2VPN_HELP_STR
12570 EVPN_HELP_STR
12571 "BGP RIB advertisement statistics\n"
12572 JSON_STR)
12573 {
12574 afi_t afi = AFI_IP6;
12575 safi_t safi = SAFI_UNICAST;
12576 struct bgp *bgp = NULL;
12577 int idx = 0, ret;
12578 bool uj = use_json(argc, argv);
12579 struct json_object *json_afi_safi = NULL, *json = NULL;
12580
12581 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12582 &bgp, false);
12583 if (!idx)
12584 return CMD_WARNING;
12585
12586 if (uj)
12587 json_afi_safi = json_object_new_array();
12588 else
12589 json_afi_safi = NULL;
12590
12591 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12592
12593 if (uj) {
12594 json = json_object_new_object();
12595 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12596 json_afi_safi);
12597 vty_json(vty, json);
12598 }
12599 return ret;
12600 }
12601
12602 /* BGP route print out function without JSON */
12603 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12604 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12605 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12606 "]]\
12607 statistics [json]",
12608 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12609 BGP_SAFI_WITH_LABEL_HELP_STR
12610 "BGP RIB advertisement statistics\n" JSON_STR)
12611 {
12612 afi_t afi = AFI_IP6;
12613 safi_t safi = SAFI_UNICAST;
12614 struct bgp *bgp = NULL;
12615 int idx = 0, ret;
12616 bool uj = use_json(argc, argv);
12617 struct json_object *json_afi_safi = NULL, *json = NULL;
12618
12619 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12620 &bgp, false);
12621 if (!idx)
12622 return CMD_WARNING;
12623
12624 if (uj)
12625 json_afi_safi = json_object_new_array();
12626 else
12627 json_afi_safi = NULL;
12628
12629 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12630
12631 if (uj) {
12632 json = json_object_new_object();
12633 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12634 json_afi_safi);
12635 vty_json(vty, json);
12636 }
12637 return ret;
12638 }
12639
12640 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12641 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12642 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12643 "]] [all$all] dampening parameters [json]",
12644 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12645 BGP_SAFI_WITH_LABEL_HELP_STR
12646 "Display the entries for all address families\n"
12647 "Display detailed information about dampening\n"
12648 "Display detail of configured dampening parameters\n"
12649 JSON_STR)
12650 {
12651 afi_t afi = AFI_IP6;
12652 safi_t safi = SAFI_UNICAST;
12653 struct bgp *bgp = NULL;
12654 int idx = 0;
12655 uint16_t show_flags = 0;
12656 bool uj = use_json(argc, argv);
12657
12658 if (uj) {
12659 argc--;
12660 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12661 }
12662
12663 /* [<ipv4|ipv6> [all]] */
12664 if (all) {
12665 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12666 if (argv_find(argv, argc, "ipv4", &idx))
12667 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12668
12669 if (argv_find(argv, argc, "ipv6", &idx))
12670 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12671 }
12672
12673 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12674 &bgp, false);
12675 if (!idx)
12676 return CMD_WARNING;
12677
12678 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12679 }
12680
12681 /* BGP route print out function */
12682 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12683 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12684 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12685 "]]\
12686 [all$all]\
12687 [cidr-only\
12688 |dampening <flap-statistics|dampened-paths>\
12689 |community [AA:NN|local-AS|no-advertise|no-export\
12690 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12691 |accept-own|accept-own-nexthop|route-filter-v6\
12692 |route-filter-v4|route-filter-translated-v6\
12693 |route-filter-translated-v4] [exact-match]\
12694 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12695 |filter-list AS_PATH_FILTER_NAME\
12696 |prefix-list WORD\
12697 |access-list ACCESSLIST_NAME\
12698 |route-map RMAP_NAME\
12699 |rpki <invalid|valid|notfound>\
12700 |version (1-4294967295)\
12701 |alias ALIAS_NAME\
12702 |A.B.C.D/M longer-prefixes\
12703 |X:X::X:X/M longer-prefixes\
12704 |"BGP_SELF_ORIG_CMD_STR"\
12705 |detail-routes$detail_routes\
12706 ] [json$uj [detail$detail_json] | wide$wide]",
12707 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12708 BGP_SAFI_WITH_LABEL_HELP_STR
12709 "Display the entries for all address families\n"
12710 "Display only routes with non-natural netmasks\n"
12711 "Display detailed information about dampening\n"
12712 "Display flap statistics of routes\n"
12713 "Display paths suppressed due to dampening\n"
12714 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12715 "Do not send outside local AS (well-known community)\n"
12716 "Do not advertise to any peer (well-known community)\n"
12717 "Do not export to next AS (well-known community)\n"
12718 "Graceful shutdown (well-known community)\n"
12719 "Do not export to any peer (well-known community)\n"
12720 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12721 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12722 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12723 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12724 "Should accept VPN route with local nexthop (well-known community)\n"
12725 "RT VPNv6 route filtering (well-known community)\n"
12726 "RT VPNv4 route filtering (well-known community)\n"
12727 "RT translated VPNv6 route filtering (well-known community)\n"
12728 "RT translated VPNv4 route filtering (well-known community)\n"
12729 "Exact match of the communities\n"
12730 "Community-list number\n"
12731 "Community-list name\n"
12732 "Display routes matching the community-list\n"
12733 "Exact match of the communities\n"
12734 "Display routes conforming to the filter-list\n"
12735 "Regular expression access list name\n"
12736 "Display routes conforming to the prefix-list\n"
12737 "Prefix-list name\n"
12738 "Display routes conforming to the access-list\n"
12739 "Access-list name\n"
12740 "Display routes matching the route-map\n"
12741 "A route-map to match on\n"
12742 "RPKI route types\n"
12743 "A valid path as determined by rpki\n"
12744 "A invalid path as determined by rpki\n"
12745 "A path that has no rpki data\n"
12746 "Display prefixes with matching version numbers\n"
12747 "Version number and above\n"
12748 "Display prefixes with matching BGP community alias\n"
12749 "BGP community alias\n"
12750 "IPv4 prefix\n"
12751 "Display route and more specific routes\n"
12752 "IPv6 prefix\n"
12753 "Display route and more specific routes\n"
12754 BGP_SELF_ORIG_HELP_STR
12755 "Display detailed version of all routes\n"
12756 JSON_STR
12757 "Display detailed version of JSON output\n"
12758 "Increase table width for longer prefixes\n")
12759 {
12760 afi_t afi = AFI_IP6;
12761 safi_t safi = SAFI_UNICAST;
12762 enum bgp_show_type sh_type = bgp_show_type_normal;
12763 void *output_arg = NULL;
12764 struct bgp *bgp = NULL;
12765 int idx = 0;
12766 int exact_match = 0;
12767 char *community = NULL;
12768 bool first = true;
12769 uint16_t show_flags = 0;
12770 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12771 struct prefix p;
12772
12773 if (uj) {
12774 argc--;
12775 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12776 }
12777
12778 if (detail_json)
12779 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12780
12781 if (detail_routes)
12782 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12783
12784 /* [<ipv4|ipv6> [all]] */
12785 if (all) {
12786 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12787
12788 if (argv_find(argv, argc, "ipv4", &idx))
12789 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12790
12791 if (argv_find(argv, argc, "ipv6", &idx))
12792 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12793 }
12794
12795 if (wide)
12796 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12797
12798 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12799 &bgp, uj);
12800 if (!idx)
12801 return CMD_WARNING;
12802
12803 if (argv_find(argv, argc, "cidr-only", &idx))
12804 sh_type = bgp_show_type_cidr_only;
12805
12806 if (argv_find(argv, argc, "dampening", &idx)) {
12807 if (argv_find(argv, argc, "dampened-paths", &idx))
12808 sh_type = bgp_show_type_dampend_paths;
12809 else if (argv_find(argv, argc, "flap-statistics", &idx))
12810 sh_type = bgp_show_type_flap_statistics;
12811 }
12812
12813 if (argv_find(argv, argc, "community", &idx)) {
12814 char *maybecomm = NULL;
12815
12816 if (idx + 1 < argc) {
12817 if (argv[idx + 1]->type == VARIABLE_TKN)
12818 maybecomm = argv[idx + 1]->arg;
12819 else
12820 maybecomm = argv[idx + 1]->text;
12821 }
12822
12823 if (maybecomm && !strmatch(maybecomm, "json")
12824 && !strmatch(maybecomm, "exact-match"))
12825 community = maybecomm;
12826
12827 if (argv_find(argv, argc, "exact-match", &idx))
12828 exact_match = 1;
12829
12830 if (!community)
12831 sh_type = bgp_show_type_community_all;
12832 }
12833
12834 if (argv_find(argv, argc, "community-list", &idx)) {
12835 const char *clist_number_or_name = argv[++idx]->arg;
12836 struct community_list *list;
12837
12838 if (argv_find(argv, argc, "exact-match", &idx))
12839 exact_match = 1;
12840
12841 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12842 COMMUNITY_LIST_MASTER);
12843 if (list == NULL) {
12844 vty_out(vty, "%% %s community-list not found\n",
12845 clist_number_or_name);
12846 return CMD_WARNING;
12847 }
12848
12849 if (exact_match)
12850 sh_type = bgp_show_type_community_list_exact;
12851 else
12852 sh_type = bgp_show_type_community_list;
12853 output_arg = list;
12854 }
12855
12856 if (argv_find(argv, argc, "filter-list", &idx)) {
12857 const char *filter = argv[++idx]->arg;
12858 struct as_list *as_list;
12859
12860 as_list = as_list_lookup(filter);
12861 if (as_list == NULL) {
12862 vty_out(vty, "%% %s AS-path access-list not found\n",
12863 filter);
12864 return CMD_WARNING;
12865 }
12866
12867 sh_type = bgp_show_type_filter_list;
12868 output_arg = as_list;
12869 }
12870
12871 if (argv_find(argv, argc, "prefix-list", &idx)) {
12872 const char *prefix_list_str = argv[++idx]->arg;
12873 struct prefix_list *plist;
12874
12875 plist = prefix_list_lookup(afi, prefix_list_str);
12876 if (plist == NULL) {
12877 vty_out(vty, "%% %s prefix-list not found\n",
12878 prefix_list_str);
12879 return CMD_WARNING;
12880 }
12881
12882 sh_type = bgp_show_type_prefix_list;
12883 output_arg = plist;
12884 }
12885
12886 if (argv_find(argv, argc, "access-list", &idx)) {
12887 const char *access_list_str = argv[++idx]->arg;
12888 struct access_list *alist;
12889
12890 alist = access_list_lookup(afi, access_list_str);
12891 if (!alist) {
12892 vty_out(vty, "%% %s access-list not found\n",
12893 access_list_str);
12894 return CMD_WARNING;
12895 }
12896
12897 sh_type = bgp_show_type_access_list;
12898 output_arg = alist;
12899 }
12900
12901 if (argv_find(argv, argc, "route-map", &idx)) {
12902 const char *rmap_str = argv[++idx]->arg;
12903 struct route_map *rmap;
12904
12905 rmap = route_map_lookup_by_name(rmap_str);
12906 if (!rmap) {
12907 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12908 return CMD_WARNING;
12909 }
12910
12911 sh_type = bgp_show_type_route_map;
12912 output_arg = rmap;
12913 }
12914
12915 if (argv_find(argv, argc, "rpki", &idx)) {
12916 sh_type = bgp_show_type_rpki;
12917 if (argv_find(argv, argc, "valid", &idx))
12918 rpki_target_state = RPKI_VALID;
12919 else if (argv_find(argv, argc, "invalid", &idx))
12920 rpki_target_state = RPKI_INVALID;
12921 }
12922
12923 /* Display prefixes with matching version numbers */
12924 if (argv_find(argv, argc, "version", &idx)) {
12925 sh_type = bgp_show_type_prefix_version;
12926 output_arg = argv[idx + 1]->arg;
12927 }
12928
12929 /* Display prefixes with matching BGP community alias */
12930 if (argv_find(argv, argc, "alias", &idx)) {
12931 sh_type = bgp_show_type_community_alias;
12932 output_arg = argv[idx + 1]->arg;
12933 }
12934
12935 /* prefix-longer */
12936 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12937 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12938 const char *prefix_str = argv[idx]->arg;
12939
12940 if (!str2prefix(prefix_str, &p)) {
12941 vty_out(vty, "%% Malformed Prefix\n");
12942 return CMD_WARNING;
12943 }
12944
12945 sh_type = bgp_show_type_prefix_longer;
12946 output_arg = &p;
12947 }
12948
12949 /* self originated only */
12950 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12951 sh_type = bgp_show_type_self_originated;
12952
12953 if (!all) {
12954 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12955 if (community)
12956 return bgp_show_community(vty, bgp, community,
12957 exact_match, afi, safi,
12958 show_flags);
12959 else
12960 return bgp_show(vty, bgp, afi, safi, sh_type,
12961 output_arg, show_flags,
12962 rpki_target_state);
12963 } else {
12964 struct listnode *node;
12965 struct bgp *abgp;
12966 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12967 * AFI_IP6 */
12968
12969 if (uj)
12970 vty_out(vty, "{\n");
12971
12972 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12973 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12974 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12975 ? AFI_IP
12976 : AFI_IP6;
12977 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12978 FOREACH_SAFI (safi) {
12979 if (!bgp_afi_safi_peer_exists(abgp, afi,
12980 safi))
12981 continue;
12982
12983 if (uj) {
12984 if (first)
12985 first = false;
12986 else
12987 vty_out(vty, ",\n");
12988 vty_out(vty, "\"%s\":{\n",
12989 get_afi_safi_str(afi,
12990 safi,
12991 true));
12992 } else
12993 vty_out(vty,
12994 "\nFor address family: %s\n",
12995 get_afi_safi_str(
12996 afi, safi,
12997 false));
12998
12999 if (community)
13000 bgp_show_community(
13001 vty, abgp, community,
13002 exact_match, afi, safi,
13003 show_flags);
13004 else
13005 bgp_show(vty, abgp, afi, safi,
13006 sh_type, output_arg,
13007 show_flags,
13008 rpki_target_state);
13009 if (uj)
13010 vty_out(vty, "}\n");
13011 }
13012 }
13013 } else {
13014 /* show <ip> bgp all: for each AFI and SAFI*/
13015 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13016 FOREACH_AFI_SAFI (afi, safi) {
13017 if (!bgp_afi_safi_peer_exists(abgp, afi,
13018 safi))
13019 continue;
13020
13021 if (uj) {
13022 if (first)
13023 first = false;
13024 else
13025 vty_out(vty, ",\n");
13026
13027 vty_out(vty, "\"%s\":{\n",
13028 get_afi_safi_str(afi,
13029 safi,
13030 true));
13031 } else
13032 vty_out(vty,
13033 "\nFor address family: %s\n",
13034 get_afi_safi_str(
13035 afi, safi,
13036 false));
13037
13038 if (community)
13039 bgp_show_community(
13040 vty, abgp, community,
13041 exact_match, afi, safi,
13042 show_flags);
13043 else
13044 bgp_show(vty, abgp, afi, safi,
13045 sh_type, output_arg,
13046 show_flags,
13047 rpki_target_state);
13048 if (uj)
13049 vty_out(vty, "}\n");
13050 }
13051 }
13052 }
13053 if (uj)
13054 vty_out(vty, "}\n");
13055 }
13056 return CMD_SUCCESS;
13057 }
13058
13059 DEFUN (show_ip_bgp_route,
13060 show_ip_bgp_route_cmd,
13061 "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]",
13062 SHOW_STR
13063 IP_STR
13064 BGP_STR
13065 BGP_INSTANCE_HELP_STR
13066 BGP_AFI_HELP_STR
13067 BGP_SAFI_WITH_LABEL_HELP_STR
13068 "Network in the BGP routing table to display\n"
13069 "IPv4 prefix\n"
13070 "Network in the BGP routing table to display\n"
13071 "IPv6 prefix\n"
13072 "Display only the bestpath\n"
13073 "Display only multipaths\n"
13074 "Display only paths that match the specified rpki state\n"
13075 "A valid path as determined by rpki\n"
13076 "A invalid path as determined by rpki\n"
13077 "A path that has no rpki data\n"
13078 JSON_STR)
13079 {
13080 int prefix_check = 0;
13081
13082 afi_t afi = AFI_IP6;
13083 safi_t safi = SAFI_UNICAST;
13084 char *prefix = NULL;
13085 struct bgp *bgp = NULL;
13086 enum bgp_path_type path_type;
13087 bool uj = use_json(argc, argv);
13088
13089 int idx = 0;
13090
13091 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13092 &bgp, uj);
13093 if (!idx)
13094 return CMD_WARNING;
13095
13096 if (!bgp) {
13097 vty_out(vty,
13098 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13099 return CMD_WARNING;
13100 }
13101
13102 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13103 if (argv_find(argv, argc, "A.B.C.D", &idx)
13104 || argv_find(argv, argc, "X:X::X:X", &idx))
13105 prefix_check = 0;
13106 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13107 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13108 prefix_check = 1;
13109
13110 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13111 && afi != AFI_IP6) {
13112 vty_out(vty,
13113 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13114 return CMD_WARNING;
13115 }
13116 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13117 && afi != AFI_IP) {
13118 vty_out(vty,
13119 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13120 return CMD_WARNING;
13121 }
13122
13123 prefix = argv[idx]->arg;
13124
13125 /* [<bestpath|multipath>] */
13126 if (argv_find(argv, argc, "bestpath", &idx))
13127 path_type = BGP_PATH_SHOW_BESTPATH;
13128 else if (argv_find(argv, argc, "multipath", &idx))
13129 path_type = BGP_PATH_SHOW_MULTIPATH;
13130 else
13131 path_type = BGP_PATH_SHOW_ALL;
13132
13133 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13134 path_type, RPKI_NOT_BEING_USED, uj);
13135 }
13136
13137 DEFUN (show_ip_bgp_regexp,
13138 show_ip_bgp_regexp_cmd,
13139 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13140 SHOW_STR
13141 IP_STR
13142 BGP_STR
13143 BGP_INSTANCE_HELP_STR
13144 BGP_AFI_HELP_STR
13145 BGP_SAFI_WITH_LABEL_HELP_STR
13146 "Display routes matching the AS path regular expression\n"
13147 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13148 JSON_STR)
13149 {
13150 afi_t afi = AFI_IP6;
13151 safi_t safi = SAFI_UNICAST;
13152 struct bgp *bgp = NULL;
13153 bool uj = use_json(argc, argv);
13154 char *regstr = NULL;
13155
13156 int idx = 0;
13157 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13158 &bgp, false);
13159 if (!idx)
13160 return CMD_WARNING;
13161
13162 // get index of regex
13163 if (argv_find(argv, argc, "REGEX", &idx))
13164 regstr = argv[idx]->arg;
13165
13166 assert(regstr);
13167 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13168 bgp_show_type_regexp, uj);
13169 }
13170
13171 DEFPY (show_ip_bgp_instance_all,
13172 show_ip_bgp_instance_all_cmd,
13173 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13174 SHOW_STR
13175 IP_STR
13176 BGP_STR
13177 BGP_INSTANCE_ALL_HELP_STR
13178 BGP_AFI_HELP_STR
13179 BGP_SAFI_WITH_LABEL_HELP_STR
13180 JSON_STR
13181 "Increase table width for longer prefixes\n")
13182 {
13183 afi_t afi = AFI_IP6;
13184 safi_t safi = SAFI_UNICAST;
13185 struct bgp *bgp = NULL;
13186 int idx = 0;
13187 uint16_t show_flags = 0;
13188
13189 if (uj) {
13190 argc--;
13191 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13192 }
13193
13194 if (wide)
13195 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13196
13197 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13198 &bgp, uj);
13199 if (!idx)
13200 return CMD_WARNING;
13201
13202 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13203 return CMD_SUCCESS;
13204 }
13205
13206 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13207 afi_t afi, safi_t safi, enum bgp_show_type type,
13208 bool use_json)
13209 {
13210 regex_t *regex;
13211 int rc;
13212 uint16_t show_flags = 0;
13213
13214 if (use_json)
13215 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13216
13217 if (!config_bgp_aspath_validate(regstr)) {
13218 vty_out(vty, "Invalid character in REGEX %s\n",
13219 regstr);
13220 return CMD_WARNING_CONFIG_FAILED;
13221 }
13222
13223 regex = bgp_regcomp(regstr);
13224 if (!regex) {
13225 vty_out(vty, "Can't compile regexp %s\n", regstr);
13226 return CMD_WARNING;
13227 }
13228
13229 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13230 RPKI_NOT_BEING_USED);
13231 bgp_regex_free(regex);
13232 return rc;
13233 }
13234
13235 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13236 const char *comstr, int exact, afi_t afi,
13237 safi_t safi, uint16_t show_flags)
13238 {
13239 struct community *com;
13240 int ret = 0;
13241
13242 com = community_str2com(comstr);
13243 if (!com) {
13244 vty_out(vty, "%% Community malformed: %s\n", comstr);
13245 return CMD_WARNING;
13246 }
13247
13248 ret = bgp_show(vty, bgp, afi, safi,
13249 (exact ? bgp_show_type_community_exact
13250 : bgp_show_type_community),
13251 com, show_flags, RPKI_NOT_BEING_USED);
13252 community_free(&com);
13253
13254 return ret;
13255 }
13256
13257 enum bgp_stats {
13258 BGP_STATS_MAXBITLEN = 0,
13259 BGP_STATS_RIB,
13260 BGP_STATS_PREFIXES,
13261 BGP_STATS_TOTPLEN,
13262 BGP_STATS_UNAGGREGATEABLE,
13263 BGP_STATS_MAX_AGGREGATEABLE,
13264 BGP_STATS_AGGREGATES,
13265 BGP_STATS_SPACE,
13266 BGP_STATS_ASPATH_COUNT,
13267 BGP_STATS_ASPATH_MAXHOPS,
13268 BGP_STATS_ASPATH_TOTHOPS,
13269 BGP_STATS_ASPATH_MAXSIZE,
13270 BGP_STATS_ASPATH_TOTSIZE,
13271 BGP_STATS_ASN_HIGHEST,
13272 BGP_STATS_MAX,
13273 };
13274
13275 #define TABLE_STATS_IDX_VTY 0
13276 #define TABLE_STATS_IDX_JSON 1
13277
13278 static const char *table_stats_strs[][2] = {
13279 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13280 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13281 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13282 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13283 "unaggregateablePrefixes"},
13284 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13285 "maximumAggregateablePrefixes"},
13286 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13287 "bgpAggregateAdvertisements"},
13288 [BGP_STATS_SPACE] = {"Address space advertised",
13289 "addressSpaceAdvertised"},
13290 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13291 "advertisementsWithPaths"},
13292 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13293 "longestAsPath"},
13294 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13295 "largestAsPath"},
13296 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13297 "averageAsPathLengthHops"},
13298 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13299 "averageAsPathSizeBytes"},
13300 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13301 [BGP_STATS_MAX] = {NULL, NULL}
13302 };
13303
13304 struct bgp_table_stats {
13305 struct bgp_table *table;
13306 unsigned long long counts[BGP_STATS_MAX];
13307
13308 unsigned long long
13309 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13310 1];
13311
13312 double total_space;
13313 };
13314
13315 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13316 struct bgp_table_stats *ts, unsigned int space)
13317 {
13318 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13319 struct bgp_path_info *pi;
13320 const struct prefix *rn_p;
13321
13322 if (!bgp_dest_has_bgp_path_info_data(dest))
13323 return;
13324
13325 rn_p = bgp_dest_get_prefix(dest);
13326 ts->counts[BGP_STATS_PREFIXES]++;
13327 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13328
13329 ts->prefix_len_count[rn_p->prefixlen]++;
13330 /* check if the prefix is included by any other announcements */
13331 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13332 pdest = bgp_dest_parent_nolock(pdest);
13333
13334 if (pdest == NULL || pdest == top) {
13335 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13336 /* announced address space */
13337 if (space)
13338 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13339 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13340 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13341
13342
13343 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13344 ts->counts[BGP_STATS_RIB]++;
13345
13346 if (CHECK_FLAG(pi->attr->flag,
13347 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13348 ts->counts[BGP_STATS_AGGREGATES]++;
13349
13350 /* as-path stats */
13351 if (pi->attr->aspath) {
13352 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13353 unsigned int size = aspath_size(pi->attr->aspath);
13354 as_t highest = aspath_highest(pi->attr->aspath);
13355
13356 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13357
13358 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13359 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13360
13361 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13362 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13363
13364 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13365 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13366 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13367 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13368 }
13369 }
13370 }
13371
13372 static void bgp_table_stats_walker(struct event *t)
13373 {
13374 struct bgp_dest *dest, *ndest;
13375 struct bgp_dest *top;
13376 struct bgp_table_stats *ts = EVENT_ARG(t);
13377 unsigned int space = 0;
13378
13379 if (!(top = bgp_table_top(ts->table)))
13380 return;
13381
13382 switch (ts->table->afi) {
13383 case AFI_IP:
13384 space = IPV4_MAX_BITLEN;
13385 break;
13386 case AFI_IP6:
13387 space = IPV6_MAX_BITLEN;
13388 break;
13389 case AFI_L2VPN:
13390 space = EVPN_ROUTE_PREFIXLEN;
13391 break;
13392 case AFI_UNSPEC:
13393 case AFI_MAX:
13394 return;
13395 }
13396
13397 ts->counts[BGP_STATS_MAXBITLEN] = space;
13398
13399 for (dest = top; dest; dest = bgp_route_next(dest)) {
13400 if (ts->table->safi == SAFI_MPLS_VPN
13401 || ts->table->safi == SAFI_ENCAP
13402 || ts->table->safi == SAFI_EVPN) {
13403 struct bgp_table *table;
13404
13405 table = bgp_dest_get_bgp_table_info(dest);
13406 if (!table)
13407 continue;
13408
13409 top = bgp_table_top(table);
13410 for (ndest = bgp_table_top(table); ndest;
13411 ndest = bgp_route_next(ndest))
13412 bgp_table_stats_rn(ndest, top, ts, space);
13413 } else {
13414 bgp_table_stats_rn(dest, top, ts, space);
13415 }
13416 }
13417 }
13418
13419 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13420 struct json_object *json_array)
13421 {
13422 struct listnode *node, *nnode;
13423 struct bgp *bgp;
13424
13425 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13426 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13427 }
13428
13429 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13430 safi_t safi, struct json_object *json_array)
13431 {
13432 struct bgp_table_stats ts;
13433 unsigned int i;
13434 int ret = CMD_SUCCESS;
13435 char temp_buf[20];
13436 struct json_object *json = NULL;
13437 uint32_t bitlen = 0;
13438 struct json_object *json_bitlen;
13439
13440 if (json_array)
13441 json = json_object_new_object();
13442
13443 if (!bgp->rib[afi][safi]) {
13444 char warning_msg[50];
13445
13446 snprintf(warning_msg, sizeof(warning_msg),
13447 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13448 safi);
13449
13450 if (!json)
13451 vty_out(vty, "%s\n", warning_msg);
13452 else
13453 json_object_string_add(json, "warning", warning_msg);
13454
13455 ret = CMD_WARNING;
13456 goto end_table_stats;
13457 }
13458
13459 if (!json)
13460 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13461 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13462 else
13463 json_object_string_add(json, "instance", bgp->name_pretty);
13464
13465 /* labeled-unicast routes live in the unicast table */
13466 if (safi == SAFI_LABELED_UNICAST)
13467 safi = SAFI_UNICAST;
13468
13469 memset(&ts, 0, sizeof(ts));
13470 ts.table = bgp->rib[afi][safi];
13471 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13472
13473 for (i = 0; i < BGP_STATS_MAX; i++) {
13474 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13475 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13476 continue;
13477
13478 switch (i) {
13479 case BGP_STATS_ASPATH_TOTHOPS:
13480 case BGP_STATS_ASPATH_TOTSIZE:
13481 if (!json) {
13482 snprintf(
13483 temp_buf, sizeof(temp_buf), "%12.2f",
13484 ts.counts[i]
13485 ? (float)ts.counts[i]
13486 / (float)ts.counts
13487 [BGP_STATS_ASPATH_COUNT]
13488 : 0);
13489 vty_out(vty, "%-30s: %s",
13490 table_stats_strs[i]
13491 [TABLE_STATS_IDX_VTY],
13492 temp_buf);
13493 } else {
13494 json_object_double_add(
13495 json,
13496 table_stats_strs[i]
13497 [TABLE_STATS_IDX_JSON],
13498 ts.counts[i]
13499 ? (double)ts.counts[i]
13500 / (double)ts.counts
13501 [BGP_STATS_ASPATH_COUNT]
13502 : 0);
13503 }
13504 break;
13505 case BGP_STATS_TOTPLEN:
13506 if (!json) {
13507 snprintf(
13508 temp_buf, sizeof(temp_buf), "%12.2f",
13509 ts.counts[i]
13510 ? (float)ts.counts[i]
13511 / (float)ts.counts
13512 [BGP_STATS_PREFIXES]
13513 : 0);
13514 vty_out(vty, "%-30s: %s",
13515 table_stats_strs[i]
13516 [TABLE_STATS_IDX_VTY],
13517 temp_buf);
13518 } else {
13519 json_object_double_add(
13520 json,
13521 table_stats_strs[i]
13522 [TABLE_STATS_IDX_JSON],
13523 ts.counts[i]
13524 ? (double)ts.counts[i]
13525 / (double)ts.counts
13526 [BGP_STATS_PREFIXES]
13527 : 0);
13528 }
13529 break;
13530 case BGP_STATS_SPACE:
13531 if (!json) {
13532 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13533 ts.total_space);
13534 vty_out(vty, "%-30s: %s\n",
13535 table_stats_strs[i]
13536 [TABLE_STATS_IDX_VTY],
13537 temp_buf);
13538 } else {
13539 json_object_double_add(
13540 json,
13541 table_stats_strs[i]
13542 [TABLE_STATS_IDX_JSON],
13543 (double)ts.total_space);
13544 }
13545 if (afi == AFI_IP6) {
13546 if (!json) {
13547 snprintf(temp_buf, sizeof(temp_buf),
13548 "%12g",
13549 ts.total_space
13550 * pow(2.0, -128 + 32));
13551 vty_out(vty, "%30s: %s\n",
13552 "/32 equivalent %s\n",
13553 temp_buf);
13554 } else {
13555 json_object_double_add(
13556 json, "/32equivalent",
13557 (double)(ts.total_space
13558 * pow(2.0,
13559 -128 + 32)));
13560 }
13561 if (!json) {
13562 snprintf(temp_buf, sizeof(temp_buf),
13563 "%12g",
13564 ts.total_space
13565 * pow(2.0, -128 + 48));
13566 vty_out(vty, "%30s: %s\n",
13567 "/48 equivalent %s\n",
13568 temp_buf);
13569 } else {
13570 json_object_double_add(
13571 json, "/48equivalent",
13572 (double)(ts.total_space
13573 * pow(2.0,
13574 -128 + 48)));
13575 }
13576 } else {
13577 if (!json) {
13578 snprintf(temp_buf, sizeof(temp_buf),
13579 "%12.2f",
13580 ts.total_space * 100.
13581 * pow(2.0, -32));
13582 vty_out(vty, "%30s: %s\n",
13583 "% announced ", temp_buf);
13584 } else {
13585 json_object_double_add(
13586 json, "%announced",
13587 (double)(ts.total_space * 100.
13588 * pow(2.0, -32)));
13589 }
13590 if (!json) {
13591 snprintf(temp_buf, sizeof(temp_buf),
13592 "%12.2f",
13593 ts.total_space
13594 * pow(2.0, -32 + 8));
13595 vty_out(vty, "%30s: %s\n",
13596 "/8 equivalent ", temp_buf);
13597 } else {
13598 json_object_double_add(
13599 json, "/8equivalent",
13600 (double)(ts.total_space
13601 * pow(2.0, -32 + 8)));
13602 }
13603 if (!json) {
13604 snprintf(temp_buf, sizeof(temp_buf),
13605 "%12.2f",
13606 ts.total_space
13607 * pow(2.0, -32 + 24));
13608 vty_out(vty, "%30s: %s\n",
13609 "/24 equivalent ", temp_buf);
13610 } else {
13611 json_object_double_add(
13612 json, "/24equivalent",
13613 (double)(ts.total_space
13614 * pow(2.0, -32 + 24)));
13615 }
13616 }
13617 break;
13618 default:
13619 if (!json) {
13620 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13621 ts.counts[i]);
13622 vty_out(vty, "%-30s: %s",
13623 table_stats_strs[i]
13624 [TABLE_STATS_IDX_VTY],
13625 temp_buf);
13626 } else {
13627 json_object_int_add(
13628 json,
13629 table_stats_strs[i]
13630 [TABLE_STATS_IDX_JSON],
13631 ts.counts[i]);
13632 }
13633 }
13634 if (!json)
13635 vty_out(vty, "\n");
13636 }
13637
13638 switch (afi) {
13639 case AFI_IP:
13640 bitlen = IPV4_MAX_BITLEN;
13641 break;
13642 case AFI_IP6:
13643 bitlen = IPV6_MAX_BITLEN;
13644 break;
13645 case AFI_L2VPN:
13646 bitlen = EVPN_ROUTE_PREFIXLEN;
13647 break;
13648 case AFI_UNSPEC:
13649 case AFI_MAX:
13650 break;
13651 }
13652
13653 if (json) {
13654 json_bitlen = json_object_new_array();
13655
13656 for (i = 0; i <= bitlen; i++) {
13657 struct json_object *ind_bit = json_object_new_object();
13658
13659 if (!ts.prefix_len_count[i])
13660 continue;
13661
13662 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13663 json_object_int_add(ind_bit, temp_buf,
13664 ts.prefix_len_count[i]);
13665 json_object_array_add(json_bitlen, ind_bit);
13666 }
13667 json_object_object_add(json, "prefixLength", json_bitlen);
13668 }
13669
13670 end_table_stats:
13671 if (json)
13672 json_object_array_add(json_array, json);
13673 return ret;
13674 }
13675
13676 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13677 safi_t safi, struct json_object *json_array)
13678 {
13679 if (!bgp) {
13680 bgp_table_stats_all(vty, afi, safi, json_array);
13681 return CMD_SUCCESS;
13682 }
13683
13684 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13685 }
13686
13687 enum bgp_pcounts {
13688 PCOUNT_ADJ_IN = 0,
13689 PCOUNT_DAMPED,
13690 PCOUNT_REMOVED,
13691 PCOUNT_HISTORY,
13692 PCOUNT_STALE,
13693 PCOUNT_VALID,
13694 PCOUNT_ALL,
13695 PCOUNT_COUNTED,
13696 PCOUNT_BPATH_SELECTED,
13697 PCOUNT_PFCNT, /* the figure we display to users */
13698 PCOUNT_MAX,
13699 };
13700
13701 static const char *const pcount_strs[] = {
13702 [PCOUNT_ADJ_IN] = "Adj-in",
13703 [PCOUNT_DAMPED] = "Damped",
13704 [PCOUNT_REMOVED] = "Removed",
13705 [PCOUNT_HISTORY] = "History",
13706 [PCOUNT_STALE] = "Stale",
13707 [PCOUNT_VALID] = "Valid",
13708 [PCOUNT_ALL] = "All RIB",
13709 [PCOUNT_COUNTED] = "PfxCt counted",
13710 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13711 [PCOUNT_PFCNT] = "Useable",
13712 [PCOUNT_MAX] = NULL,
13713 };
13714
13715 struct peer_pcounts {
13716 unsigned int count[PCOUNT_MAX];
13717 const struct peer *peer;
13718 const struct bgp_table *table;
13719 safi_t safi;
13720 };
13721
13722 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13723 {
13724 const struct bgp_adj_in *ain;
13725 const struct bgp_path_info *pi;
13726 const struct peer *peer = pc->peer;
13727
13728 for (ain = rn->adj_in; ain; ain = ain->next)
13729 if (ain->peer == peer)
13730 pc->count[PCOUNT_ADJ_IN]++;
13731
13732 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13733
13734 if (pi->peer != peer)
13735 continue;
13736
13737 pc->count[PCOUNT_ALL]++;
13738
13739 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13740 pc->count[PCOUNT_DAMPED]++;
13741 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13742 pc->count[PCOUNT_HISTORY]++;
13743 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13744 pc->count[PCOUNT_REMOVED]++;
13745 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13746 pc->count[PCOUNT_STALE]++;
13747 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13748 pc->count[PCOUNT_VALID]++;
13749 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13750 pc->count[PCOUNT_PFCNT]++;
13751 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13752 pc->count[PCOUNT_BPATH_SELECTED]++;
13753
13754 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13755 pc->count[PCOUNT_COUNTED]++;
13756 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13757 flog_err(
13758 EC_LIB_DEVELOPMENT,
13759 "Attempting to count but flags say it is unusable");
13760 } else {
13761 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13762 flog_err(
13763 EC_LIB_DEVELOPMENT,
13764 "Not counted but flags say we should");
13765 }
13766 }
13767 }
13768
13769 static void bgp_peer_count_walker(struct event *t)
13770 {
13771 struct bgp_dest *rn, *rm;
13772 const struct bgp_table *table;
13773 struct peer_pcounts *pc = EVENT_ARG(t);
13774
13775 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13776 || pc->safi == SAFI_EVPN) {
13777 /* Special handling for 2-level routing tables. */
13778 for (rn = bgp_table_top(pc->table); rn;
13779 rn = bgp_route_next(rn)) {
13780 table = bgp_dest_get_bgp_table_info(rn);
13781 if (table != NULL)
13782 for (rm = bgp_table_top(table); rm;
13783 rm = bgp_route_next(rm))
13784 bgp_peer_count_proc(rm, pc);
13785 }
13786 } else
13787 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13788 bgp_peer_count_proc(rn, pc);
13789 }
13790
13791 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13792 safi_t safi, bool use_json)
13793 {
13794 struct peer_pcounts pcounts = {.peer = peer};
13795 unsigned int i;
13796 json_object *json = NULL;
13797 json_object *json_loop = NULL;
13798
13799 if (use_json) {
13800 json = json_object_new_object();
13801 json_loop = json_object_new_object();
13802 }
13803
13804 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13805 || !peer->bgp->rib[afi][safi]) {
13806 if (use_json) {
13807 json_object_string_add(
13808 json, "warning",
13809 "No such neighbor or address family");
13810 vty_out(vty, "%s\n", json_object_to_json_string(json));
13811 json_object_free(json);
13812 json_object_free(json_loop);
13813 } else
13814 vty_out(vty, "%% No such neighbor or address family\n");
13815
13816 return CMD_WARNING;
13817 }
13818
13819 memset(&pcounts, 0, sizeof(pcounts));
13820 pcounts.peer = peer;
13821 pcounts.table = peer->bgp->rib[afi][safi];
13822 pcounts.safi = safi;
13823
13824 /* in-place call via thread subsystem so as to record execution time
13825 * stats for the thread-walk (i.e. ensure this can't be blamed on
13826 * on just vty_read()).
13827 */
13828 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13829
13830 if (use_json) {
13831 json_object_string_add(json, "prefixCountsFor", peer->host);
13832 json_object_string_add(json, "multiProtocol",
13833 get_afi_safi_str(afi, safi, true));
13834 json_object_int_add(json, "pfxCounter",
13835 peer->pcount[afi][safi]);
13836
13837 for (i = 0; i < PCOUNT_MAX; i++)
13838 json_object_int_add(json_loop, pcount_strs[i],
13839 pcounts.count[i]);
13840
13841 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13842
13843 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13844 json_object_string_add(json, "pfxctDriftFor",
13845 peer->host);
13846 json_object_string_add(
13847 json, "recommended",
13848 "Please report this bug, with the above command output");
13849 }
13850 vty_json(vty, json);
13851 } else {
13852
13853 if (peer->hostname
13854 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13855 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13856 peer->hostname, peer->host,
13857 get_afi_safi_str(afi, safi, false));
13858 } else {
13859 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13860 get_afi_safi_str(afi, safi, false));
13861 }
13862
13863 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13864 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13865
13866 for (i = 0; i < PCOUNT_MAX; i++)
13867 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13868 pcounts.count[i]);
13869
13870 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13871 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13872 vty_out(vty,
13873 "Please report this bug, with the above command output\n");
13874 }
13875 }
13876
13877 return CMD_SUCCESS;
13878 }
13879
13880 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13881 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13882 "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]",
13883 SHOW_STR
13884 IP_STR
13885 BGP_STR
13886 BGP_INSTANCE_HELP_STR
13887 BGP_AFI_HELP_STR
13888 BGP_SAFI_HELP_STR
13889 "Detailed information on TCP and BGP neighbor connections\n"
13890 "Neighbor to display information about\n"
13891 "Neighbor to display information about\n"
13892 "Neighbor on BGP configured interface\n"
13893 "Display detailed prefix count information\n"
13894 JSON_STR)
13895 {
13896 afi_t afi = AFI_IP6;
13897 safi_t safi = SAFI_UNICAST;
13898 struct peer *peer;
13899 int idx = 0;
13900 struct bgp *bgp = NULL;
13901 bool uj = use_json(argc, argv);
13902
13903 if (uj)
13904 argc--;
13905
13906 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13907 &bgp, uj);
13908 if (!idx)
13909 return CMD_WARNING;
13910
13911 argv_find(argv, argc, "neighbors", &idx);
13912 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13913 if (!peer)
13914 return CMD_WARNING;
13915
13916 return bgp_peer_counts(vty, peer, afi, safi, uj);
13917 }
13918
13919 #ifdef KEEP_OLD_VPN_COMMANDS
13920 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13921 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13922 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13923 SHOW_STR
13924 IP_STR
13925 BGP_STR
13926 BGP_VPNVX_HELP_STR
13927 "Display information about all VPNv4 NLRIs\n"
13928 "Detailed information on TCP and BGP neighbor connections\n"
13929 "Neighbor to display information about\n"
13930 "Neighbor to display information about\n"
13931 "Neighbor on BGP configured interface\n"
13932 "Display detailed prefix count information\n"
13933 JSON_STR)
13934 {
13935 int idx_peer = 6;
13936 struct peer *peer;
13937 bool uj = use_json(argc, argv);
13938
13939 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13940 if (!peer)
13941 return CMD_WARNING;
13942
13943 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13944 }
13945
13946 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13947 show_ip_bgp_vpn_all_route_prefix_cmd,
13948 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13949 SHOW_STR
13950 IP_STR
13951 BGP_STR
13952 BGP_VPNVX_HELP_STR
13953 "Display information about all VPNv4 NLRIs\n"
13954 "Network in the BGP routing table to display\n"
13955 "Network in the BGP routing table to display\n"
13956 JSON_STR)
13957 {
13958 int idx = 0;
13959 char *network = NULL;
13960 struct bgp *bgp = bgp_get_default();
13961 if (!bgp) {
13962 vty_out(vty, "Can't find default instance\n");
13963 return CMD_WARNING;
13964 }
13965
13966 if (argv_find(argv, argc, "A.B.C.D", &idx))
13967 network = argv[idx]->arg;
13968 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13969 network = argv[idx]->arg;
13970 else {
13971 vty_out(vty, "Unable to figure out Network\n");
13972 return CMD_WARNING;
13973 }
13974
13975 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13976 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13977 use_json(argc, argv));
13978 }
13979 #endif /* KEEP_OLD_VPN_COMMANDS */
13980
13981 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13982 show_bgp_l2vpn_evpn_route_prefix_cmd,
13983 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13984 SHOW_STR
13985 BGP_STR
13986 L2VPN_HELP_STR
13987 EVPN_HELP_STR
13988 "Network in the BGP routing table to display\n"
13989 "Network in the BGP routing table to display\n"
13990 "Network in the BGP routing table to display\n"
13991 "Network in the BGP routing table to display\n"
13992 JSON_STR)
13993 {
13994 int idx = 0;
13995 char *network = NULL;
13996 int prefix_check = 0;
13997
13998 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13999 argv_find(argv, argc, "X:X::X:X", &idx))
14000 network = argv[idx]->arg;
14001 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
14002 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
14003 network = argv[idx]->arg;
14004 prefix_check = 1;
14005 } else {
14006 vty_out(vty, "Unable to figure out Network\n");
14007 return CMD_WARNING;
14008 }
14009 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
14010 prefix_check, BGP_PATH_SHOW_ALL,
14011 RPKI_NOT_BEING_USED, use_json(argc, argv));
14012 }
14013
14014 static void show_adj_route_header(struct vty *vty, struct peer *peer,
14015 struct bgp_table *table, int *header1,
14016 int *header2, json_object *json,
14017 json_object *json_scode,
14018 json_object *json_ocode, bool wide,
14019 bool detail)
14020 {
14021 uint64_t version = table ? table->version : 0;
14022
14023 if (*header1) {
14024 if (json) {
14025 json_object_int_add(json, "bgpTableVersion", version);
14026 json_object_string_addf(json, "bgpLocalRouterId",
14027 "%pI4", &peer->bgp->router_id);
14028 json_object_int_add(json, "defaultLocPrf",
14029 peer->bgp->default_local_pref);
14030 json_object_int_add(json, "localAS",
14031 peer->change_local_as
14032 ? peer->change_local_as
14033 : peer->local_as);
14034 json_object_object_add(json, "bgpStatusCodes",
14035 json_scode);
14036 json_object_object_add(json, "bgpOriginCodes",
14037 json_ocode);
14038 } else {
14039 vty_out(vty,
14040 "BGP table version is %" PRIu64
14041 ", local router ID is %pI4, vrf id ",
14042 version, &peer->bgp->router_id);
14043 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14044 vty_out(vty, "%s", VRFID_NONE_STR);
14045 else
14046 vty_out(vty, "%u", peer->bgp->vrf_id);
14047 vty_out(vty, "\n");
14048 vty_out(vty, "Default local pref %u, ",
14049 peer->bgp->default_local_pref);
14050 vty_out(vty, "local AS %u\n",
14051 peer->change_local_as ? peer->change_local_as
14052 : peer->local_as);
14053 if (!detail) {
14054 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14055 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14056 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14057 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14058 }
14059 }
14060 *header1 = 0;
14061 }
14062 if (*header2) {
14063 if (!json && !detail)
14064 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14065 : BGP_SHOW_HEADER));
14066 *header2 = 0;
14067 }
14068 }
14069
14070 static void
14071 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14072 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14073 const char *rmap_name, json_object *json, json_object *json_ar,
14074 json_object *json_scode, json_object *json_ocode,
14075 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14076 const struct prefix *match, unsigned long *output_count,
14077 unsigned long *filtered_count)
14078 {
14079 struct bgp_adj_in *ain = NULL;
14080 struct bgp_adj_out *adj = NULL;
14081 struct bgp_dest *dest;
14082 struct bgp *bgp;
14083 struct attr attr;
14084 int ret;
14085 struct update_subgroup *subgrp;
14086 struct peer_af *paf = NULL;
14087 bool route_filtered;
14088 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14089 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14090 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14091 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14092 || (safi == SAFI_EVPN))
14093 ? true
14094 : false;
14095 int display = 0;
14096 json_object *json_net = NULL;
14097
14098 bgp = peer->bgp;
14099
14100 /* If the user supplied a prefix, look for a matching route instead
14101 * of walking the whole table.
14102 */
14103 if (match) {
14104 dest = bgp_node_match(table, match);
14105 if (!dest) {
14106 if (!use_json)
14107 vty_out(vty, "Network not in table\n");
14108 return;
14109 }
14110
14111 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14112
14113 if (rn_p->prefixlen != match->prefixlen) {
14114 if (!use_json)
14115 vty_out(vty, "Network not in table\n");
14116 bgp_dest_unlock_node(dest);
14117 return;
14118 }
14119
14120 if (type == bgp_show_adj_route_received ||
14121 type == bgp_show_adj_route_filtered) {
14122 for (ain = dest->adj_in; ain; ain = ain->next) {
14123 if (ain->peer == peer) {
14124 attr = *ain->attr;
14125 break;
14126 }
14127 }
14128 /* bail out if if adj_out is empty, or
14129 * if the prefix isn't in this peer's
14130 * adj_in
14131 */
14132 if (!ain || ain->peer != peer) {
14133 if (!use_json)
14134 vty_out(vty, "Network not in table\n");
14135 bgp_dest_unlock_node(dest);
14136 return;
14137 }
14138 } else if (type == bgp_show_adj_route_advertised) {
14139 bool peer_found = false;
14140
14141 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14142 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14143 if (paf->peer == peer && adj->attr) {
14144 attr = *adj->attr;
14145 peer_found = true;
14146 break;
14147 }
14148 }
14149 if (peer_found)
14150 break;
14151 }
14152 /* bail out if if adj_out is empty, or
14153 * if the prefix isn't in this peer's
14154 * adj_out
14155 */
14156 if (!paf || !peer_found) {
14157 if (!use_json)
14158 vty_out(vty, "Network not in table\n");
14159 bgp_dest_unlock_node(dest);
14160 return;
14161 }
14162 }
14163
14164 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14165 rmap_name);
14166
14167 if (ret != RMAP_DENY) {
14168 show_adj_route_header(vty, peer, table, header1,
14169 header2, json, json_scode,
14170 json_ocode, wide, detail);
14171
14172 if (use_json)
14173 json_net = json_object_new_object();
14174
14175 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14176 afi, safi, json_net,
14177 BGP_PATH_SHOW_ALL, &display,
14178 RPKI_NOT_BEING_USED);
14179 if (use_json)
14180 json_object_object_addf(json_ar, json_net,
14181 "%pFX", rn_p);
14182 (*output_count)++;
14183 } else
14184 (*filtered_count)++;
14185
14186 bgp_attr_flush(&attr);
14187 bgp_dest_unlock_node(dest);
14188 return;
14189 }
14190
14191
14192 subgrp = peer_subgroup(peer, afi, safi);
14193
14194 if (type == bgp_show_adj_route_advertised && subgrp
14195 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14196 if (use_json) {
14197 json_object_int_add(json, "bgpTableVersion",
14198 table->version);
14199 json_object_string_addf(json, "bgpLocalRouterId",
14200 "%pI4", &bgp->router_id);
14201 json_object_int_add(json, "defaultLocPrf",
14202 bgp->default_local_pref);
14203 json_object_int_add(json, "localAS",
14204 peer->change_local_as
14205 ? peer->change_local_as
14206 : peer->local_as);
14207 json_object_object_add(json, "bgpStatusCodes",
14208 json_scode);
14209 json_object_object_add(json, "bgpOriginCodes",
14210 json_ocode);
14211 json_object_string_add(
14212 json, "bgpOriginatingDefaultNetwork",
14213 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14214 } else {
14215 vty_out(vty,
14216 "BGP table version is %" PRIu64
14217 ", local router ID is %pI4, vrf id ",
14218 table->version, &bgp->router_id);
14219 if (bgp->vrf_id == VRF_UNKNOWN)
14220 vty_out(vty, "%s", VRFID_NONE_STR);
14221 else
14222 vty_out(vty, "%u", bgp->vrf_id);
14223 vty_out(vty, "\n");
14224 vty_out(vty, "Default local pref %u, ",
14225 bgp->default_local_pref);
14226 vty_out(vty, "local AS %u\n",
14227 peer->change_local_as ? peer->change_local_as
14228 : peer->local_as);
14229 if (!detail) {
14230 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14231 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14232 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14233 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14234 }
14235
14236 vty_out(vty, "Originating default network %s\n\n",
14237 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14238 }
14239 (*output_count)++;
14240 *header1 = 0;
14241 }
14242
14243 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14244 if (type == bgp_show_adj_route_received
14245 || type == bgp_show_adj_route_filtered) {
14246 for (ain = dest->adj_in; ain; ain = ain->next) {
14247 if (ain->peer != peer)
14248 continue;
14249
14250 show_adj_route_header(vty, peer, table, header1,
14251 header2, json, json_scode,
14252 json_ocode, wide, detail);
14253
14254 if ((safi == SAFI_MPLS_VPN)
14255 || (safi == SAFI_ENCAP)
14256 || (safi == SAFI_EVPN)) {
14257 if (use_json)
14258 json_object_string_add(
14259 json_ar, "rd", rd_str);
14260 else if (show_rd && rd_str) {
14261 vty_out(vty,
14262 "Route Distinguisher: %s\n",
14263 rd_str);
14264 show_rd = false;
14265 }
14266 }
14267
14268 attr = *ain->attr;
14269 route_filtered = false;
14270
14271 /* Filter prefix using distribute list,
14272 * filter list or prefix list
14273 */
14274 const struct prefix *rn_p =
14275 bgp_dest_get_prefix(dest);
14276 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14277 safi))
14278 == FILTER_DENY)
14279 route_filtered = true;
14280
14281 /* Filter prefix using route-map */
14282 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14283 safi, rmap_name, NULL,
14284 0, NULL);
14285
14286 if (type == bgp_show_adj_route_filtered &&
14287 !route_filtered && ret != RMAP_DENY) {
14288 bgp_attr_flush(&attr);
14289 continue;
14290 }
14291
14292 if (type == bgp_show_adj_route_received
14293 && (route_filtered || ret == RMAP_DENY))
14294 (*filtered_count)++;
14295
14296 if (detail) {
14297 if (use_json)
14298 json_net =
14299 json_object_new_object();
14300 bgp_show_path_info(
14301 NULL /* prefix_rd */, dest, vty,
14302 bgp, afi, safi, json_net,
14303 BGP_PATH_SHOW_ALL, &display,
14304 RPKI_NOT_BEING_USED);
14305 if (use_json)
14306 json_object_object_addf(
14307 json_ar, json_net,
14308 "%pFX", rn_p);
14309 } else
14310 route_vty_out_tmp(vty, dest, rn_p,
14311 &attr, safi, use_json,
14312 json_ar, wide);
14313 bgp_attr_flush(&attr);
14314 (*output_count)++;
14315 }
14316 } else if (type == bgp_show_adj_route_advertised) {
14317 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14318 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14319 if (paf->peer != peer || !adj->attr)
14320 continue;
14321
14322 show_adj_route_header(
14323 vty, peer, table, header1,
14324 header2, json, json_scode,
14325 json_ocode, wide, detail);
14326
14327 const struct prefix *rn_p =
14328 bgp_dest_get_prefix(dest);
14329
14330 attr = *adj->attr;
14331 ret = bgp_output_modifier(
14332 peer, rn_p, &attr, afi, safi,
14333 rmap_name);
14334
14335 if (ret != RMAP_DENY) {
14336 if ((safi == SAFI_MPLS_VPN)
14337 || (safi == SAFI_ENCAP)
14338 || (safi == SAFI_EVPN)) {
14339 if (use_json)
14340 json_object_string_add(
14341 json_ar,
14342 "rd",
14343 rd_str);
14344 else if (show_rd
14345 && rd_str) {
14346 vty_out(vty,
14347 "Route Distinguisher: %s\n",
14348 rd_str);
14349 show_rd = false;
14350 }
14351 }
14352 if (detail) {
14353 if (use_json)
14354 json_net =
14355 json_object_new_object();
14356 bgp_show_path_info(
14357 NULL /* prefix_rd
14358 */
14359 ,
14360 dest, vty, bgp,
14361 afi, safi,
14362 json_net,
14363 BGP_PATH_SHOW_ALL,
14364 &display,
14365 RPKI_NOT_BEING_USED);
14366 if (use_json)
14367 json_object_object_addf(
14368 json_ar,
14369 json_net,
14370 "%pFX",
14371 rn_p);
14372 } else
14373 route_vty_out_tmp(
14374 vty, dest, rn_p,
14375 &attr, safi,
14376 use_json,
14377 json_ar, wide);
14378 (*output_count)++;
14379 } else {
14380 (*filtered_count)++;
14381 }
14382
14383 bgp_attr_flush(&attr);
14384 }
14385 } else if (type == bgp_show_adj_route_bestpath) {
14386 struct bgp_path_info *pi;
14387
14388 show_adj_route_header(vty, peer, table, header1,
14389 header2, json, json_scode,
14390 json_ocode, wide, detail);
14391
14392 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14393
14394 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14395 pi = pi->next) {
14396 if (pi->peer != peer)
14397 continue;
14398
14399 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14400 continue;
14401
14402 if (detail) {
14403 if (use_json)
14404 json_net =
14405 json_object_new_object();
14406 bgp_show_path_info(
14407 NULL /* prefix_rd */, dest, vty,
14408 bgp, afi, safi, json_net,
14409 BGP_PATH_SHOW_BESTPATH,
14410 &display, RPKI_NOT_BEING_USED);
14411 if (use_json)
14412 json_object_object_addf(
14413 json_ar, json_net,
14414 "%pFX", rn_p);
14415 } else
14416 route_vty_out_tmp(
14417 vty, dest, rn_p, pi->attr, safi,
14418 use_json, json_ar, wide);
14419 (*output_count)++;
14420 }
14421 }
14422 }
14423 }
14424
14425 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14426 safi_t safi, enum bgp_show_adj_route_type type,
14427 const char *rmap_name, const struct prefix *match,
14428 uint16_t show_flags)
14429 {
14430 struct bgp *bgp;
14431 struct bgp_table *table;
14432 json_object *json = NULL;
14433 json_object *json_scode = NULL;
14434 json_object *json_ocode = NULL;
14435 json_object *json_ar = NULL;
14436 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14437
14438 /* Init BGP headers here so they're only displayed once
14439 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14440 */
14441 int header1 = 1;
14442 int header2 = 1;
14443
14444 /*
14445 * Initialize variables for each RD
14446 * All prefixes under an RD is aggregated within "json_routes"
14447 */
14448 char rd_str[BUFSIZ] = {0};
14449 json_object *json_routes = NULL;
14450
14451
14452 /* For 2-tier tables, prefix counts need to be
14453 * maintained across multiple runs of show_adj_route()
14454 */
14455 unsigned long output_count_per_rd;
14456 unsigned long filtered_count_per_rd;
14457 unsigned long output_count = 0;
14458 unsigned long filtered_count = 0;
14459
14460 if (use_json) {
14461 json = json_object_new_object();
14462 json_ar = json_object_new_object();
14463 json_scode = json_object_new_object();
14464 json_ocode = json_object_new_object();
14465 #if CONFDATE > 20231208
14466 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14467 #endif
14468 json_object_string_add(json_scode, "suppressed", "s");
14469 json_object_string_add(json_scode, "damped", "d");
14470 json_object_string_add(json_scode, "history", "h");
14471 json_object_string_add(json_scode, "valid", "*");
14472 json_object_string_add(json_scode, "best", ">");
14473 json_object_string_add(json_scode, "multipath", "=");
14474 json_object_string_add(json_scode, "internal", "i");
14475 json_object_string_add(json_scode, "ribFailure", "r");
14476 json_object_string_add(json_scode, "stale", "S");
14477 json_object_string_add(json_scode, "removed", "R");
14478
14479 #if CONFDATE > 20231208
14480 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14481 #endif
14482 json_object_string_add(json_ocode, "igp", "i");
14483 json_object_string_add(json_ocode, "egp", "e");
14484 json_object_string_add(json_ocode, "incomplete", "?");
14485 }
14486
14487 if (!peer || !peer->afc[afi][safi]) {
14488 if (use_json) {
14489 json_object_string_add(
14490 json, "warning",
14491 "No such neighbor or address family");
14492 vty_out(vty, "%s\n", json_object_to_json_string(json));
14493 json_object_free(json);
14494 json_object_free(json_ar);
14495 json_object_free(json_scode);
14496 json_object_free(json_ocode);
14497 } else
14498 vty_out(vty, "%% No such neighbor or address family\n");
14499
14500 return CMD_WARNING;
14501 }
14502
14503 if ((type == bgp_show_adj_route_received
14504 || type == bgp_show_adj_route_filtered)
14505 && !CHECK_FLAG(peer->af_flags[afi][safi],
14506 PEER_FLAG_SOFT_RECONFIG)) {
14507 if (use_json) {
14508 json_object_string_add(
14509 json, "warning",
14510 "Inbound soft reconfiguration not enabled");
14511 vty_out(vty, "%s\n", json_object_to_json_string(json));
14512 json_object_free(json);
14513 json_object_free(json_ar);
14514 json_object_free(json_scode);
14515 json_object_free(json_ocode);
14516 } else
14517 vty_out(vty,
14518 "%% Inbound soft reconfiguration not enabled\n");
14519
14520 return CMD_WARNING;
14521 }
14522
14523 bgp = peer->bgp;
14524
14525 /* labeled-unicast routes live in the unicast table */
14526 if (safi == SAFI_LABELED_UNICAST)
14527 table = bgp->rib[afi][SAFI_UNICAST];
14528 else
14529 table = bgp->rib[afi][safi];
14530
14531 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14532 || (safi == SAFI_EVPN)) {
14533
14534 struct bgp_dest *dest;
14535
14536 for (dest = bgp_table_top(table); dest;
14537 dest = bgp_route_next(dest)) {
14538 table = bgp_dest_get_bgp_table_info(dest);
14539 if (!table)
14540 continue;
14541
14542 output_count_per_rd = 0;
14543 filtered_count_per_rd = 0;
14544
14545 if (use_json)
14546 json_routes = json_object_new_object();
14547
14548 const struct prefix_rd *prd;
14549 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14550 dest);
14551
14552 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14553 bgp->asnotation);
14554
14555 show_adj_route(
14556 vty, peer, table, afi, safi, type, rmap_name,
14557 json, json_routes, json_scode, json_ocode,
14558 show_flags, &header1, &header2, rd_str, match,
14559 &output_count_per_rd, &filtered_count_per_rd);
14560
14561 /* Don't include an empty RD in the output! */
14562 if (json_routes && (output_count_per_rd > 0))
14563 json_object_object_add(json_ar, rd_str,
14564 json_routes);
14565
14566 output_count += output_count_per_rd;
14567 filtered_count += filtered_count_per_rd;
14568 }
14569 } else
14570 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14571 json, json_ar, json_scode, json_ocode,
14572 show_flags, &header1, &header2, rd_str, match,
14573 &output_count, &filtered_count);
14574
14575 if (use_json) {
14576 if (type == bgp_show_adj_route_advertised)
14577 json_object_object_add(json, "advertisedRoutes",
14578 json_ar);
14579 else
14580 json_object_object_add(json, "receivedRoutes", json_ar);
14581 json_object_int_add(json, "totalPrefixCounter", output_count);
14582 json_object_int_add(json, "filteredPrefixCounter",
14583 filtered_count);
14584
14585 /*
14586 * These fields only give up ownership to `json` when `header1`
14587 * is used (set to zero). See code in `show_adj_route` and
14588 * `show_adj_route_header`.
14589 */
14590 if (header1 == 1) {
14591 json_object_free(json_scode);
14592 json_object_free(json_ocode);
14593 }
14594
14595 vty_json(vty, json);
14596 } else if (output_count > 0) {
14597 if (!match && filtered_count > 0)
14598 vty_out(vty,
14599 "\nTotal number of prefixes %ld (%ld filtered)\n",
14600 output_count, filtered_count);
14601 else
14602 vty_out(vty, "\nTotal number of prefixes %ld\n",
14603 output_count);
14604 }
14605
14606 return CMD_SUCCESS;
14607 }
14608
14609 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14610 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14611 "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 [detail$detail] [json$uj | wide$wide]",
14612 SHOW_STR
14613 IP_STR
14614 BGP_STR
14615 BGP_INSTANCE_HELP_STR
14616 BGP_AFI_HELP_STR
14617 BGP_SAFI_WITH_LABEL_HELP_STR
14618 "Detailed information on TCP and BGP neighbor connections\n"
14619 "Neighbor to display information about\n"
14620 "Neighbor to display information about\n"
14621 "Neighbor on BGP configured interface\n"
14622 "Display the routes selected by best path\n"
14623 "Display detailed version of routes\n"
14624 JSON_STR
14625 "Increase table width for longer prefixes\n")
14626 {
14627 afi_t afi = AFI_IP6;
14628 safi_t safi = SAFI_UNICAST;
14629 char *rmap_name = NULL;
14630 char *peerstr = NULL;
14631 struct bgp *bgp = NULL;
14632 struct peer *peer;
14633 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14634 int idx = 0;
14635 uint16_t show_flags = 0;
14636
14637 if (detail)
14638 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14639
14640 if (uj)
14641 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14642
14643 if (wide)
14644 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14645
14646 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14647 &bgp, uj);
14648
14649 if (!idx)
14650 return CMD_WARNING;
14651
14652 argv_find(argv, argc, "neighbors", &idx);
14653 peerstr = argv[++idx]->arg;
14654
14655 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14656 if (!peer)
14657 return CMD_WARNING;
14658
14659 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14660 show_flags);
14661 }
14662
14663 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14664 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14665 "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] [<A.B.C.D/M|X:X::X:X/M>$prefix | detail$detail] [json$uj | wide$wide]",
14666 SHOW_STR
14667 IP_STR
14668 BGP_STR
14669 BGP_INSTANCE_HELP_STR
14670 BGP_AFI_HELP_STR
14671 BGP_SAFI_WITH_LABEL_HELP_STR
14672 "Display the entries for all address families\n"
14673 "Detailed information on TCP and BGP neighbor connections\n"
14674 "Neighbor to display information about\n"
14675 "Neighbor to display information about\n"
14676 "Neighbor on BGP configured interface\n"
14677 "Display the routes advertised to a BGP neighbor\n"
14678 "Display the received routes from neighbor\n"
14679 "Display the filtered routes received from neighbor\n"
14680 "Route-map to modify the attributes\n"
14681 "Name of the route map\n"
14682 "IPv4 prefix\n"
14683 "IPv6 prefix\n"
14684 "Display detailed version of routes\n"
14685 JSON_STR
14686 "Increase table width for longer prefixes\n")
14687 {
14688 afi_t afi = AFI_IP6;
14689 safi_t safi = SAFI_UNICAST;
14690 char *peerstr = NULL;
14691 struct bgp *bgp = NULL;
14692 struct peer *peer;
14693 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14694 int idx = 0;
14695 bool first = true;
14696 uint16_t show_flags = 0;
14697 struct listnode *node;
14698 struct bgp *abgp;
14699
14700 if (detail || prefix_str)
14701 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14702
14703 if (uj) {
14704 argc--;
14705 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14706 }
14707
14708 if (all) {
14709 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14710 if (argv_find(argv, argc, "ipv4", &idx))
14711 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14712
14713 if (argv_find(argv, argc, "ipv6", &idx))
14714 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14715 }
14716
14717 if (wide)
14718 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14719
14720 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14721 &bgp, uj);
14722 if (!idx)
14723 return CMD_WARNING;
14724
14725 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14726 argv_find(argv, argc, "neighbors", &idx);
14727 peerstr = argv[++idx]->arg;
14728
14729 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14730 if (!peer)
14731 return CMD_WARNING;
14732
14733 if (argv_find(argv, argc, "advertised-routes", &idx))
14734 type = bgp_show_adj_route_advertised;
14735 else if (argv_find(argv, argc, "received-routes", &idx))
14736 type = bgp_show_adj_route_received;
14737 else if (argv_find(argv, argc, "filtered-routes", &idx))
14738 type = bgp_show_adj_route_filtered;
14739
14740 if (!all)
14741 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14742 prefix_str ? prefix : NULL, show_flags);
14743 if (uj)
14744 vty_out(vty, "{\n");
14745
14746 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14747 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14748 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14749 : AFI_IP6;
14750 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14751 FOREACH_SAFI (safi) {
14752 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14753 continue;
14754
14755 if (uj) {
14756 if (first)
14757 first = false;
14758 else
14759 vty_out(vty, ",\n");
14760 vty_out(vty, "\"%s\":",
14761 get_afi_safi_str(afi, safi,
14762 true));
14763 } else
14764 vty_out(vty,
14765 "\nFor address family: %s\n",
14766 get_afi_safi_str(afi, safi,
14767 false));
14768
14769 peer_adj_routes(vty, peer, afi, safi, type,
14770 route_map, prefix, show_flags);
14771 }
14772 }
14773 } else {
14774 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14775 FOREACH_AFI_SAFI (afi, safi) {
14776 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14777 continue;
14778
14779 if (uj) {
14780 if (first)
14781 first = false;
14782 else
14783 vty_out(vty, ",\n");
14784 vty_out(vty, "\"%s\":",
14785 get_afi_safi_str(afi, safi,
14786 true));
14787 } else
14788 vty_out(vty,
14789 "\nFor address family: %s\n",
14790 get_afi_safi_str(afi, safi,
14791 false));
14792
14793 peer_adj_routes(vty, peer, afi, safi, type,
14794 route_map, prefix, show_flags);
14795 }
14796 }
14797 }
14798 if (uj)
14799 vty_out(vty, "}\n");
14800
14801 return CMD_SUCCESS;
14802 }
14803
14804 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14805 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14806 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14807 SHOW_STR
14808 IP_STR
14809 BGP_STR
14810 BGP_INSTANCE_HELP_STR
14811 BGP_AF_STR
14812 BGP_AF_STR
14813 BGP_AF_MODIFIER_STR
14814 "Detailed information on TCP and BGP neighbor connections\n"
14815 "Neighbor to display information about\n"
14816 "Neighbor to display information about\n"
14817 "Neighbor on BGP configured interface\n"
14818 "Display information received from a BGP neighbor\n"
14819 "Display the prefixlist filter\n"
14820 JSON_STR)
14821 {
14822 afi_t afi = AFI_IP6;
14823 safi_t safi = SAFI_UNICAST;
14824 char *peerstr = NULL;
14825 char name[BUFSIZ];
14826 struct peer *peer;
14827 int count;
14828 int idx = 0;
14829 struct bgp *bgp = NULL;
14830 bool uj = use_json(argc, argv);
14831
14832 if (uj)
14833 argc--;
14834
14835 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14836 &bgp, uj);
14837 if (!idx)
14838 return CMD_WARNING;
14839
14840 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14841 argv_find(argv, argc, "neighbors", &idx);
14842 peerstr = argv[++idx]->arg;
14843
14844 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14845 if (!peer)
14846 return CMD_WARNING;
14847
14848 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14849 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14850 if (count) {
14851 if (!uj)
14852 vty_out(vty, "Address Family: %s\n",
14853 get_afi_safi_str(afi, safi, false));
14854 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14855 } else {
14856 if (uj)
14857 vty_out(vty, "{}\n");
14858 else
14859 vty_out(vty, "No functional output\n");
14860 }
14861
14862 return CMD_SUCCESS;
14863 }
14864
14865 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14866 afi_t afi, safi_t safi,
14867 enum bgp_show_type type, bool use_json)
14868 {
14869 uint16_t show_flags = 0;
14870
14871 if (use_json)
14872 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14873
14874 if (!peer || !peer->afc[afi][safi]) {
14875 if (use_json) {
14876 json_object *json_no = NULL;
14877 json_no = json_object_new_object();
14878 json_object_string_add(
14879 json_no, "warning",
14880 "No such neighbor or address family");
14881 vty_out(vty, "%s\n",
14882 json_object_to_json_string(json_no));
14883 json_object_free(json_no);
14884 } else
14885 vty_out(vty, "%% No such neighbor or address family\n");
14886 return CMD_WARNING;
14887 }
14888
14889 /* labeled-unicast routes live in the unicast table */
14890 if (safi == SAFI_LABELED_UNICAST)
14891 safi = SAFI_UNICAST;
14892
14893 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14894 RPKI_NOT_BEING_USED);
14895 }
14896
14897 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14898 show_ip_bgp_flowspec_routes_detailed_cmd,
14899 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14900 SHOW_STR
14901 IP_STR
14902 BGP_STR
14903 BGP_INSTANCE_HELP_STR
14904 BGP_AFI_HELP_STR
14905 "SAFI Flowspec\n"
14906 "Detailed information on flowspec entries\n"
14907 JSON_STR)
14908 {
14909 afi_t afi = AFI_IP6;
14910 safi_t safi = SAFI_UNICAST;
14911 struct bgp *bgp = NULL;
14912 int idx = 0;
14913 bool uj = use_json(argc, argv);
14914 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14915
14916 if (uj) {
14917 argc--;
14918 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14919 }
14920
14921 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14922 &bgp, uj);
14923 if (!idx)
14924 return CMD_WARNING;
14925
14926 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14927 show_flags, RPKI_NOT_BEING_USED);
14928 }
14929
14930 DEFUN (show_ip_bgp_neighbor_routes,
14931 show_ip_bgp_neighbor_routes_cmd,
14932 "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]",
14933 SHOW_STR
14934 IP_STR
14935 BGP_STR
14936 BGP_INSTANCE_HELP_STR
14937 BGP_AFI_HELP_STR
14938 BGP_SAFI_WITH_LABEL_HELP_STR
14939 "Detailed information on TCP and BGP neighbor connections\n"
14940 "Neighbor to display information about\n"
14941 "Neighbor to display information about\n"
14942 "Neighbor on BGP configured interface\n"
14943 "Display flap statistics of the routes learned from neighbor\n"
14944 "Display the dampened routes received from neighbor\n"
14945 "Display routes learned from neighbor\n"
14946 JSON_STR)
14947 {
14948 char *peerstr = NULL;
14949 struct bgp *bgp = NULL;
14950 afi_t afi = AFI_IP6;
14951 safi_t safi = SAFI_UNICAST;
14952 struct peer *peer;
14953 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14954 int idx = 0;
14955 bool uj = use_json(argc, argv);
14956
14957 if (uj)
14958 argc--;
14959
14960 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14961 &bgp, uj);
14962 if (!idx)
14963 return CMD_WARNING;
14964
14965 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14966 argv_find(argv, argc, "neighbors", &idx);
14967 peerstr = argv[++idx]->arg;
14968
14969 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14970 if (!peer)
14971 return CMD_WARNING;
14972
14973 if (argv_find(argv, argc, "flap-statistics", &idx))
14974 sh_type = bgp_show_type_flap_neighbor;
14975 else if (argv_find(argv, argc, "dampened-routes", &idx))
14976 sh_type = bgp_show_type_damp_neighbor;
14977 else if (argv_find(argv, argc, "routes", &idx))
14978 sh_type = bgp_show_type_neighbor;
14979
14980 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14981 }
14982
14983 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14984
14985 struct bgp_distance {
14986 /* Distance value for the IP source prefix. */
14987 uint8_t distance;
14988
14989 /* Name of the access-list to be matched. */
14990 char *access_list;
14991 };
14992
14993 DEFUN (show_bgp_afi_vpn_rd_route,
14994 show_bgp_afi_vpn_rd_route_cmd,
14995 "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]",
14996 SHOW_STR
14997 BGP_STR
14998 BGP_AFI_HELP_STR
14999 BGP_AF_MODIFIER_STR
15000 "Display information for a route distinguisher\n"
15001 "Route Distinguisher\n"
15002 "All Route Distinguishers\n"
15003 "Network in the BGP routing table to display\n"
15004 "Network in the BGP routing table to display\n"
15005 JSON_STR)
15006 {
15007 int ret;
15008 struct prefix_rd prd;
15009 afi_t afi = AFI_MAX;
15010 int idx = 0;
15011
15012 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
15013 vty_out(vty, "%% Malformed Address Family\n");
15014 return CMD_WARNING;
15015 }
15016
15017 if (!strcmp(argv[5]->arg, "all"))
15018 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
15019 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
15020 RPKI_NOT_BEING_USED,
15021 use_json(argc, argv));
15022
15023 ret = str2prefix_rd(argv[5]->arg, &prd);
15024 if (!ret) {
15025 vty_out(vty, "%% Malformed Route Distinguisher\n");
15026 return CMD_WARNING;
15027 }
15028
15029 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
15030 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
15031 use_json(argc, argv));
15032 }
15033
15034 static struct bgp_distance *bgp_distance_new(void)
15035 {
15036 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
15037 }
15038
15039 static void bgp_distance_free(struct bgp_distance *bdistance)
15040 {
15041 XFREE(MTYPE_BGP_DISTANCE, bdistance);
15042 }
15043
15044 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15045 const char *ip_str, const char *access_list_str)
15046 {
15047 int ret;
15048 afi_t afi;
15049 safi_t safi;
15050 struct prefix p;
15051 uint8_t distance;
15052 struct bgp_dest *dest;
15053 struct bgp_distance *bdistance;
15054
15055 afi = bgp_node_afi(vty);
15056 safi = bgp_node_safi(vty);
15057
15058 ret = str2prefix(ip_str, &p);
15059 if (ret == 0) {
15060 vty_out(vty, "Malformed prefix\n");
15061 return CMD_WARNING_CONFIG_FAILED;
15062 }
15063
15064 distance = atoi(distance_str);
15065
15066 /* Get BGP distance node. */
15067 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15068 bdistance = bgp_dest_get_bgp_distance_info(dest);
15069 if (bdistance)
15070 bgp_dest_unlock_node(dest);
15071 else {
15072 bdistance = bgp_distance_new();
15073 bgp_dest_set_bgp_distance_info(dest, bdistance);
15074 }
15075
15076 /* Set distance value. */
15077 bdistance->distance = distance;
15078
15079 /* Reset access-list configuration. */
15080 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15081 if (access_list_str)
15082 bdistance->access_list =
15083 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15084
15085 return CMD_SUCCESS;
15086 }
15087
15088 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15089 const char *ip_str, const char *access_list_str)
15090 {
15091 int ret;
15092 afi_t afi;
15093 safi_t safi;
15094 struct prefix p;
15095 int distance;
15096 struct bgp_dest *dest;
15097 struct bgp_distance *bdistance;
15098
15099 afi = bgp_node_afi(vty);
15100 safi = bgp_node_safi(vty);
15101
15102 ret = str2prefix(ip_str, &p);
15103 if (ret == 0) {
15104 vty_out(vty, "Malformed prefix\n");
15105 return CMD_WARNING_CONFIG_FAILED;
15106 }
15107
15108 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15109 if (!dest) {
15110 vty_out(vty, "Can't find specified prefix\n");
15111 return CMD_WARNING_CONFIG_FAILED;
15112 }
15113
15114 bdistance = bgp_dest_get_bgp_distance_info(dest);
15115 distance = atoi(distance_str);
15116
15117 if (bdistance->distance != distance) {
15118 vty_out(vty, "Distance does not match configured\n");
15119 bgp_dest_unlock_node(dest);
15120 return CMD_WARNING_CONFIG_FAILED;
15121 }
15122
15123 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15124 bgp_distance_free(bdistance);
15125
15126 bgp_dest_set_bgp_path_info(dest, NULL);
15127 bgp_dest_unlock_node(dest);
15128 bgp_dest_unlock_node(dest);
15129
15130 return CMD_SUCCESS;
15131 }
15132
15133 /* Apply BGP information to distance method. */
15134 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15135 afi_t afi, safi_t safi, struct bgp *bgp)
15136 {
15137 struct bgp_dest *dest;
15138 struct prefix q = {0};
15139 struct peer *peer;
15140 struct bgp_distance *bdistance;
15141 struct access_list *alist;
15142 struct bgp_static *bgp_static;
15143 struct bgp_path_info *bpi_ultimate;
15144
15145 if (!bgp)
15146 return 0;
15147
15148 peer = pinfo->peer;
15149
15150 if (pinfo->attr->distance)
15151 return pinfo->attr->distance;
15152
15153 /* get peer origin to calculate appropriate distance */
15154 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15155 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15156 peer = bpi_ultimate->peer;
15157 }
15158
15159 /* Check source address.
15160 * Note: for aggregate route, peer can have unspec af type.
15161 */
15162 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15163 && !sockunion2hostprefix(&peer->su, &q))
15164 return 0;
15165
15166 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15167 if (dest) {
15168 bdistance = bgp_dest_get_bgp_distance_info(dest);
15169 bgp_dest_unlock_node(dest);
15170
15171 if (bdistance->access_list) {
15172 alist = access_list_lookup(afi, bdistance->access_list);
15173 if (alist
15174 && access_list_apply(alist, p) == FILTER_PERMIT)
15175 return bdistance->distance;
15176 } else
15177 return bdistance->distance;
15178 }
15179
15180 /* Backdoor check. */
15181 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15182 if (dest) {
15183 bgp_static = bgp_dest_get_bgp_static_info(dest);
15184 bgp_dest_unlock_node(dest);
15185
15186 if (bgp_static->backdoor) {
15187 if (bgp->distance_local[afi][safi])
15188 return bgp->distance_local[afi][safi];
15189 else
15190 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15191 }
15192 }
15193
15194 if (peer->sort == BGP_PEER_EBGP) {
15195 if (bgp->distance_ebgp[afi][safi])
15196 return bgp->distance_ebgp[afi][safi];
15197 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15198 } else if (peer->sort == BGP_PEER_IBGP) {
15199 if (bgp->distance_ibgp[afi][safi])
15200 return bgp->distance_ibgp[afi][safi];
15201 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15202 } else {
15203 if (bgp->distance_local[afi][safi])
15204 return bgp->distance_local[afi][safi];
15205 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15206 }
15207 }
15208
15209 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15210 * we should tell ZEBRA update the routes for a specific
15211 * AFI/SAFI to reflect changes in RIB.
15212 */
15213 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15214 afi_t update_afi,
15215 safi_t update_safi)
15216 {
15217 afi_t afi;
15218 safi_t safi;
15219
15220 FOREACH_AFI_SAFI (afi, safi) {
15221 if (!bgp_fibupd_safi(safi))
15222 continue;
15223
15224 if (afi != update_afi && safi != update_safi)
15225 continue;
15226
15227 if (BGP_DEBUG(zebra, ZEBRA))
15228 zlog_debug(
15229 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15230 __func__, afi, safi);
15231 bgp_zebra_announce_table(bgp, afi, safi);
15232 }
15233 }
15234
15235 DEFUN (bgp_distance,
15236 bgp_distance_cmd,
15237 "distance bgp (1-255) (1-255) (1-255)",
15238 "Define an administrative distance\n"
15239 "BGP distance\n"
15240 "Distance for routes external to the AS\n"
15241 "Distance for routes internal to the AS\n"
15242 "Distance for local routes\n")
15243 {
15244 VTY_DECLVAR_CONTEXT(bgp, bgp);
15245 int idx_number = 2;
15246 int idx_number_2 = 3;
15247 int idx_number_3 = 4;
15248 int distance_ebgp = atoi(argv[idx_number]->arg);
15249 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15250 int distance_local = atoi(argv[idx_number_3]->arg);
15251 afi_t afi;
15252 safi_t safi;
15253
15254 afi = bgp_node_afi(vty);
15255 safi = bgp_node_safi(vty);
15256
15257 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15258 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15259 || bgp->distance_local[afi][safi] != distance_local) {
15260 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15261 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15262 bgp->distance_local[afi][safi] = distance_local;
15263 bgp_announce_routes_distance_update(bgp, afi, safi);
15264 }
15265 return CMD_SUCCESS;
15266 }
15267
15268 DEFUN (no_bgp_distance,
15269 no_bgp_distance_cmd,
15270 "no distance bgp [(1-255) (1-255) (1-255)]",
15271 NO_STR
15272 "Define an administrative distance\n"
15273 "BGP distance\n"
15274 "Distance for routes external to the AS\n"
15275 "Distance for routes internal to the AS\n"
15276 "Distance for local routes\n")
15277 {
15278 VTY_DECLVAR_CONTEXT(bgp, bgp);
15279 afi_t afi;
15280 safi_t safi;
15281
15282 afi = bgp_node_afi(vty);
15283 safi = bgp_node_safi(vty);
15284
15285 if (bgp->distance_ebgp[afi][safi] != 0
15286 || bgp->distance_ibgp[afi][safi] != 0
15287 || bgp->distance_local[afi][safi] != 0) {
15288 bgp->distance_ebgp[afi][safi] = 0;
15289 bgp->distance_ibgp[afi][safi] = 0;
15290 bgp->distance_local[afi][safi] = 0;
15291 bgp_announce_routes_distance_update(bgp, afi, safi);
15292 }
15293 return CMD_SUCCESS;
15294 }
15295
15296
15297 DEFUN (bgp_distance_source,
15298 bgp_distance_source_cmd,
15299 "distance (1-255) A.B.C.D/M",
15300 "Define an administrative distance\n"
15301 "Administrative distance\n"
15302 "IP source prefix\n")
15303 {
15304 int idx_number = 1;
15305 int idx_ipv4_prefixlen = 2;
15306 bgp_distance_set(vty, argv[idx_number]->arg,
15307 argv[idx_ipv4_prefixlen]->arg, NULL);
15308 return CMD_SUCCESS;
15309 }
15310
15311 DEFUN (no_bgp_distance_source,
15312 no_bgp_distance_source_cmd,
15313 "no distance (1-255) A.B.C.D/M",
15314 NO_STR
15315 "Define an administrative distance\n"
15316 "Administrative distance\n"
15317 "IP source prefix\n")
15318 {
15319 int idx_number = 2;
15320 int idx_ipv4_prefixlen = 3;
15321 bgp_distance_unset(vty, argv[idx_number]->arg,
15322 argv[idx_ipv4_prefixlen]->arg, NULL);
15323 return CMD_SUCCESS;
15324 }
15325
15326 DEFUN (bgp_distance_source_access_list,
15327 bgp_distance_source_access_list_cmd,
15328 "distance (1-255) A.B.C.D/M WORD",
15329 "Define an administrative distance\n"
15330 "Administrative distance\n"
15331 "IP source prefix\n"
15332 "Access list name\n")
15333 {
15334 int idx_number = 1;
15335 int idx_ipv4_prefixlen = 2;
15336 int idx_word = 3;
15337 bgp_distance_set(vty, argv[idx_number]->arg,
15338 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15339 return CMD_SUCCESS;
15340 }
15341
15342 DEFUN (no_bgp_distance_source_access_list,
15343 no_bgp_distance_source_access_list_cmd,
15344 "no distance (1-255) A.B.C.D/M WORD",
15345 NO_STR
15346 "Define an administrative distance\n"
15347 "Administrative distance\n"
15348 "IP source prefix\n"
15349 "Access list name\n")
15350 {
15351 int idx_number = 2;
15352 int idx_ipv4_prefixlen = 3;
15353 int idx_word = 4;
15354 bgp_distance_unset(vty, argv[idx_number]->arg,
15355 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15356 return CMD_SUCCESS;
15357 }
15358
15359 DEFUN (ipv6_bgp_distance_source,
15360 ipv6_bgp_distance_source_cmd,
15361 "distance (1-255) X:X::X:X/M",
15362 "Define an administrative distance\n"
15363 "Administrative distance\n"
15364 "IP source prefix\n")
15365 {
15366 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15367 return CMD_SUCCESS;
15368 }
15369
15370 DEFUN (no_ipv6_bgp_distance_source,
15371 no_ipv6_bgp_distance_source_cmd,
15372 "no distance (1-255) X:X::X:X/M",
15373 NO_STR
15374 "Define an administrative distance\n"
15375 "Administrative distance\n"
15376 "IP source prefix\n")
15377 {
15378 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15379 return CMD_SUCCESS;
15380 }
15381
15382 DEFUN (ipv6_bgp_distance_source_access_list,
15383 ipv6_bgp_distance_source_access_list_cmd,
15384 "distance (1-255) X:X::X:X/M WORD",
15385 "Define an administrative distance\n"
15386 "Administrative distance\n"
15387 "IP source prefix\n"
15388 "Access list name\n")
15389 {
15390 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15391 return CMD_SUCCESS;
15392 }
15393
15394 DEFUN (no_ipv6_bgp_distance_source_access_list,
15395 no_ipv6_bgp_distance_source_access_list_cmd,
15396 "no distance (1-255) X:X::X:X/M WORD",
15397 NO_STR
15398 "Define an administrative distance\n"
15399 "Administrative distance\n"
15400 "IP source prefix\n"
15401 "Access list name\n")
15402 {
15403 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15404 return CMD_SUCCESS;
15405 }
15406
15407 DEFUN (bgp_damp_set,
15408 bgp_damp_set_cmd,
15409 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15410 "BGP Specific commands\n"
15411 "Enable route-flap dampening\n"
15412 "Half-life time for the penalty\n"
15413 "Value to start reusing a route\n"
15414 "Value to start suppressing a route\n"
15415 "Maximum duration to suppress a stable route\n")
15416 {
15417 VTY_DECLVAR_CONTEXT(bgp, bgp);
15418 int idx_half_life = 2;
15419 int idx_reuse = 3;
15420 int idx_suppress = 4;
15421 int idx_max_suppress = 5;
15422 int half = DEFAULT_HALF_LIFE * 60;
15423 int reuse = DEFAULT_REUSE;
15424 int suppress = DEFAULT_SUPPRESS;
15425 int max = 4 * half;
15426
15427 if (argc == 6) {
15428 half = atoi(argv[idx_half_life]->arg) * 60;
15429 reuse = atoi(argv[idx_reuse]->arg);
15430 suppress = atoi(argv[idx_suppress]->arg);
15431 max = atoi(argv[idx_max_suppress]->arg) * 60;
15432 } else if (argc == 3) {
15433 half = atoi(argv[idx_half_life]->arg) * 60;
15434 max = 4 * half;
15435 }
15436
15437 /*
15438 * These can't be 0 but our SA doesn't understand the
15439 * way our cli is constructed
15440 */
15441 assert(reuse);
15442 assert(half);
15443 if (suppress < reuse) {
15444 vty_out(vty,
15445 "Suppress value cannot be less than reuse value \n");
15446 return 0;
15447 }
15448
15449 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15450 reuse, suppress, max);
15451 }
15452
15453 DEFUN (bgp_damp_unset,
15454 bgp_damp_unset_cmd,
15455 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15456 NO_STR
15457 "BGP Specific commands\n"
15458 "Enable route-flap dampening\n"
15459 "Half-life time for the penalty\n"
15460 "Value to start reusing a route\n"
15461 "Value to start suppressing a route\n"
15462 "Maximum duration to suppress a stable route\n")
15463 {
15464 VTY_DECLVAR_CONTEXT(bgp, bgp);
15465 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15466 }
15467
15468 /* Display specified route of BGP table. */
15469 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15470 const char *ip_str, afi_t afi, safi_t safi,
15471 struct prefix_rd *prd, int prefix_check)
15472 {
15473 int ret;
15474 struct prefix match;
15475 struct bgp_dest *dest;
15476 struct bgp_dest *rm;
15477 struct bgp_path_info *pi;
15478 struct bgp_path_info *pi_temp;
15479 struct bgp *bgp;
15480 struct bgp_table *table;
15481
15482 /* BGP structure lookup. */
15483 if (view_name) {
15484 bgp = bgp_lookup_by_name(view_name);
15485 if (bgp == NULL) {
15486 vty_out(vty, "%% Can't find BGP instance %s\n",
15487 view_name);
15488 return CMD_WARNING;
15489 }
15490 } else {
15491 bgp = bgp_get_default();
15492 if (bgp == NULL) {
15493 vty_out(vty, "%% No BGP process is configured\n");
15494 return CMD_WARNING;
15495 }
15496 }
15497
15498 /* Check IP address argument. */
15499 ret = str2prefix(ip_str, &match);
15500 if (!ret) {
15501 vty_out(vty, "%% address is malformed\n");
15502 return CMD_WARNING;
15503 }
15504
15505 match.family = afi2family(afi);
15506
15507 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15508 || (safi == SAFI_EVPN)) {
15509 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15510 dest = bgp_route_next(dest)) {
15511 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15512
15513 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15514 continue;
15515 table = bgp_dest_get_bgp_table_info(dest);
15516 if (!table)
15517 continue;
15518 rm = bgp_node_match(table, &match);
15519 if (rm == NULL)
15520 continue;
15521
15522 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15523
15524 if (!prefix_check
15525 || rm_p->prefixlen == match.prefixlen) {
15526 pi = bgp_dest_get_bgp_path_info(rm);
15527 while (pi) {
15528 if (pi->extra && pi->extra->damp_info) {
15529 pi_temp = pi->next;
15530 bgp_damp_info_free(
15531 pi->extra->damp_info,
15532 1, afi, safi);
15533 pi = pi_temp;
15534 } else
15535 pi = pi->next;
15536 }
15537 }
15538
15539 bgp_dest_unlock_node(rm);
15540 }
15541 } else {
15542 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15543 if (dest != NULL) {
15544 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15545
15546 if (!prefix_check
15547 || dest_p->prefixlen == match.prefixlen) {
15548 pi = bgp_dest_get_bgp_path_info(dest);
15549 while (pi) {
15550 if (pi->extra && pi->extra->damp_info) {
15551 pi_temp = pi->next;
15552 bgp_damp_info_free(
15553 pi->extra->damp_info,
15554 1, afi, safi);
15555 pi = pi_temp;
15556 } else
15557 pi = pi->next;
15558 }
15559 }
15560
15561 bgp_dest_unlock_node(dest);
15562 }
15563 }
15564
15565 return CMD_SUCCESS;
15566 }
15567
15568 DEFUN (clear_ip_bgp_dampening,
15569 clear_ip_bgp_dampening_cmd,
15570 "clear ip bgp dampening",
15571 CLEAR_STR
15572 IP_STR
15573 BGP_STR
15574 "Clear route flap dampening information\n")
15575 {
15576 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15577 return CMD_SUCCESS;
15578 }
15579
15580 DEFUN (clear_ip_bgp_dampening_prefix,
15581 clear_ip_bgp_dampening_prefix_cmd,
15582 "clear ip bgp dampening A.B.C.D/M",
15583 CLEAR_STR
15584 IP_STR
15585 BGP_STR
15586 "Clear route flap dampening information\n"
15587 "IPv4 prefix\n")
15588 {
15589 int idx_ipv4_prefixlen = 4;
15590 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15591 AFI_IP, SAFI_UNICAST, NULL, 1);
15592 }
15593
15594 DEFUN (clear_ip_bgp_dampening_address,
15595 clear_ip_bgp_dampening_address_cmd,
15596 "clear ip bgp dampening A.B.C.D",
15597 CLEAR_STR
15598 IP_STR
15599 BGP_STR
15600 "Clear route flap dampening information\n"
15601 "Network to clear damping information\n")
15602 {
15603 int idx_ipv4 = 4;
15604 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15605 SAFI_UNICAST, NULL, 0);
15606 }
15607
15608 DEFUN (clear_ip_bgp_dampening_address_mask,
15609 clear_ip_bgp_dampening_address_mask_cmd,
15610 "clear ip bgp dampening A.B.C.D A.B.C.D",
15611 CLEAR_STR
15612 IP_STR
15613 BGP_STR
15614 "Clear route flap dampening information\n"
15615 "Network to clear damping information\n"
15616 "Network mask\n")
15617 {
15618 int idx_ipv4 = 4;
15619 int idx_ipv4_2 = 5;
15620 int ret;
15621 char prefix_str[BUFSIZ];
15622
15623 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15624 prefix_str, sizeof(prefix_str));
15625 if (!ret) {
15626 vty_out(vty, "%% Inconsistent address and mask\n");
15627 return CMD_WARNING;
15628 }
15629
15630 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15631 NULL, 0);
15632 }
15633
15634 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15635 {
15636 struct vty *vty = arg;
15637 struct peer *peer = bucket->data;
15638
15639 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15640 }
15641
15642 DEFUN (show_bgp_listeners,
15643 show_bgp_listeners_cmd,
15644 "show bgp listeners",
15645 SHOW_STR
15646 BGP_STR
15647 "Display Listen Sockets and who created them\n")
15648 {
15649 bgp_dump_listener_info(vty);
15650
15651 return CMD_SUCCESS;
15652 }
15653
15654 DEFUN (show_bgp_peerhash,
15655 show_bgp_peerhash_cmd,
15656 "show bgp peerhash",
15657 SHOW_STR
15658 BGP_STR
15659 "Display information about the BGP peerhash\n")
15660 {
15661 struct list *instances = bm->bgp;
15662 struct listnode *node;
15663 struct bgp *bgp;
15664
15665 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15666 vty_out(vty, "BGP: %s\n", bgp->name);
15667 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15668 vty);
15669 }
15670
15671 return CMD_SUCCESS;
15672 }
15673
15674 /* also used for encap safi */
15675 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15676 afi_t afi, safi_t safi)
15677 {
15678 struct bgp_dest *pdest;
15679 struct bgp_dest *dest;
15680 struct bgp_table *table;
15681 const struct prefix *p;
15682 struct bgp_static *bgp_static;
15683 mpls_label_t label;
15684
15685 /* Network configuration. */
15686 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15687 pdest = bgp_route_next(pdest)) {
15688 table = bgp_dest_get_bgp_table_info(pdest);
15689 if (!table)
15690 continue;
15691
15692 for (dest = bgp_table_top(table); dest;
15693 dest = bgp_route_next(dest)) {
15694 bgp_static = bgp_dest_get_bgp_static_info(dest);
15695 if (bgp_static == NULL)
15696 continue;
15697
15698 p = bgp_dest_get_prefix(dest);
15699
15700 /* "network" configuration display. */
15701 label = decode_label(&bgp_static->label);
15702
15703 vty_out(vty, " network %pFX rd %s", p,
15704 bgp_static->prd_pretty);
15705 if (safi == SAFI_MPLS_VPN)
15706 vty_out(vty, " label %u", label);
15707
15708 if (bgp_static->rmap.name)
15709 vty_out(vty, " route-map %s",
15710 bgp_static->rmap.name);
15711
15712 if (bgp_static->backdoor)
15713 vty_out(vty, " backdoor");
15714
15715 vty_out(vty, "\n");
15716 }
15717 }
15718 }
15719
15720 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15721 afi_t afi, safi_t safi)
15722 {
15723 struct bgp_dest *pdest;
15724 struct bgp_dest *dest;
15725 struct bgp_table *table;
15726 const struct prefix *p;
15727 struct bgp_static *bgp_static;
15728 char buf[PREFIX_STRLEN * 2];
15729 char buf2[SU_ADDRSTRLEN];
15730 char esi_buf[ESI_STR_LEN];
15731
15732 /* Network configuration. */
15733 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15734 pdest = bgp_route_next(pdest)) {
15735 table = bgp_dest_get_bgp_table_info(pdest);
15736 if (!table)
15737 continue;
15738
15739 for (dest = bgp_table_top(table); dest;
15740 dest = bgp_route_next(dest)) {
15741 bgp_static = bgp_dest_get_bgp_static_info(dest);
15742 if (bgp_static == NULL)
15743 continue;
15744
15745 char *macrouter = NULL;
15746
15747 if (bgp_static->router_mac)
15748 macrouter = prefix_mac2str(
15749 bgp_static->router_mac, NULL, 0);
15750 if (bgp_static->eth_s_id)
15751 esi_to_str(bgp_static->eth_s_id,
15752 esi_buf, sizeof(esi_buf));
15753 p = bgp_dest_get_prefix(dest);
15754
15755 /* "network" configuration display. */
15756 if (p->u.prefix_evpn.route_type == 5) {
15757 char local_buf[PREFIX_STRLEN];
15758
15759 uint8_t family = is_evpn_prefix_ipaddr_v4((
15760 struct prefix_evpn *)p)
15761 ? AF_INET
15762 : AF_INET6;
15763 inet_ntop(family,
15764 &p->u.prefix_evpn.prefix_addr.ip.ip
15765 .addr,
15766 local_buf, sizeof(local_buf));
15767 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15768 p->u.prefix_evpn.prefix_addr
15769 .ip_prefix_length);
15770 } else {
15771 prefix2str(p, buf, sizeof(buf));
15772 }
15773
15774 if (bgp_static->gatewayIp.family == AF_INET
15775 || bgp_static->gatewayIp.family == AF_INET6)
15776 inet_ntop(bgp_static->gatewayIp.family,
15777 &bgp_static->gatewayIp.u.prefix, buf2,
15778 sizeof(buf2));
15779 vty_out(vty,
15780 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15781 buf, bgp_static->prd_pretty,
15782 p->u.prefix_evpn.prefix_addr.eth_tag,
15783 decode_label(&bgp_static->label), esi_buf, buf2,
15784 macrouter);
15785
15786 XFREE(MTYPE_TMP, macrouter);
15787 }
15788 }
15789 }
15790
15791 /* Configuration of static route announcement and aggregate
15792 information. */
15793 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15794 safi_t safi)
15795 {
15796 struct bgp_dest *dest;
15797 const struct prefix *p;
15798 struct bgp_static *bgp_static;
15799 struct bgp_aggregate *bgp_aggregate;
15800
15801 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15802 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15803 return;
15804 }
15805
15806 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15807 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15808 return;
15809 }
15810
15811 /* Network configuration. */
15812 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15813 dest = bgp_route_next(dest)) {
15814 bgp_static = bgp_dest_get_bgp_static_info(dest);
15815 if (bgp_static == NULL)
15816 continue;
15817
15818 p = bgp_dest_get_prefix(dest);
15819
15820 vty_out(vty, " network %pFX", p);
15821
15822 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15823 vty_out(vty, " label-index %u",
15824 bgp_static->label_index);
15825
15826 if (bgp_static->rmap.name)
15827 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15828
15829 if (bgp_static->backdoor)
15830 vty_out(vty, " backdoor");
15831
15832 vty_out(vty, "\n");
15833 }
15834
15835 /* Aggregate-address configuration. */
15836 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15837 dest = bgp_route_next(dest)) {
15838 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15839 if (bgp_aggregate == NULL)
15840 continue;
15841
15842 p = bgp_dest_get_prefix(dest);
15843
15844 vty_out(vty, " aggregate-address %pFX", p);
15845
15846 if (bgp_aggregate->as_set)
15847 vty_out(vty, " as-set");
15848
15849 if (bgp_aggregate->summary_only)
15850 vty_out(vty, " summary-only");
15851
15852 if (bgp_aggregate->rmap.name)
15853 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15854
15855 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15856 vty_out(vty, " origin %s",
15857 bgp_origin2str(bgp_aggregate->origin));
15858
15859 if (bgp_aggregate->match_med)
15860 vty_out(vty, " matching-MED-only");
15861
15862 if (bgp_aggregate->suppress_map_name)
15863 vty_out(vty, " suppress-map %s",
15864 bgp_aggregate->suppress_map_name);
15865
15866 vty_out(vty, "\n");
15867 }
15868 }
15869
15870 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15871 safi_t safi)
15872 {
15873 struct bgp_dest *dest;
15874 struct bgp_distance *bdistance;
15875
15876 /* Distance configuration. */
15877 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15878 && bgp->distance_local[afi][safi]
15879 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15880 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15881 || bgp->distance_local[afi][safi]
15882 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15883 vty_out(vty, " distance bgp %d %d %d\n",
15884 bgp->distance_ebgp[afi][safi],
15885 bgp->distance_ibgp[afi][safi],
15886 bgp->distance_local[afi][safi]);
15887 }
15888
15889 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15890 dest = bgp_route_next(dest)) {
15891 bdistance = bgp_dest_get_bgp_distance_info(dest);
15892 if (bdistance != NULL)
15893 vty_out(vty, " distance %d %pBD %s\n",
15894 bdistance->distance, dest,
15895 bdistance->access_list ? bdistance->access_list
15896 : "");
15897 }
15898 }
15899
15900 /* Allocate routing table structure and install commands. */
15901 void bgp_route_init(void)
15902 {
15903 afi_t afi;
15904 safi_t safi;
15905
15906 /* Init BGP distance table. */
15907 FOREACH_AFI_SAFI (afi, safi)
15908 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15909
15910 /* IPv4 BGP commands. */
15911 install_element(BGP_NODE, &bgp_table_map_cmd);
15912 install_element(BGP_NODE, &bgp_network_cmd);
15913 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15914
15915 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15916
15917 /* IPv4 unicast configuration. */
15918 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15919 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15920 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15921
15922 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15923
15924 /* IPv4 multicast configuration. */
15925 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15926 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15927 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15928 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15929
15930 /* IPv4 labeled-unicast configuration. */
15931 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15932 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15933
15934 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15935 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15936 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15937 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15938 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15939 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15940 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15941 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15942
15943 install_element(VIEW_NODE,
15944 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15945 install_element(VIEW_NODE,
15946 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15947 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15948 install_element(VIEW_NODE,
15949 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15950 #ifdef KEEP_OLD_VPN_COMMANDS
15951 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15952 #endif /* KEEP_OLD_VPN_COMMANDS */
15953 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15954 install_element(VIEW_NODE,
15955 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15956
15957 /* BGP dampening clear commands */
15958 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15959 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15960
15961 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15962 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15963
15964 /* prefix count */
15965 install_element(ENABLE_NODE,
15966 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15967 #ifdef KEEP_OLD_VPN_COMMANDS
15968 install_element(ENABLE_NODE,
15969 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15970 #endif /* KEEP_OLD_VPN_COMMANDS */
15971
15972 /* New config IPv6 BGP commands. */
15973 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15974 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15975 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15976
15977 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15978
15979 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15980
15981 /* IPv6 labeled unicast address family. */
15982 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15983 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15984
15985 install_element(BGP_NODE, &bgp_distance_cmd);
15986 install_element(BGP_NODE, &no_bgp_distance_cmd);
15987 install_element(BGP_NODE, &bgp_distance_source_cmd);
15988 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15989 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15990 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15991 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15992 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15993 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15994 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15995 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15996 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15997 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15998 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15999 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
16000 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
16001 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
16002 install_element(BGP_IPV4M_NODE,
16003 &no_bgp_distance_source_access_list_cmd);
16004 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
16005 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
16006 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
16007 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
16008 install_element(BGP_IPV6_NODE,
16009 &ipv6_bgp_distance_source_access_list_cmd);
16010 install_element(BGP_IPV6_NODE,
16011 &no_ipv6_bgp_distance_source_access_list_cmd);
16012 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
16013 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
16014 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
16015 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
16016 install_element(BGP_IPV6M_NODE,
16017 &ipv6_bgp_distance_source_access_list_cmd);
16018 install_element(BGP_IPV6M_NODE,
16019 &no_ipv6_bgp_distance_source_access_list_cmd);
16020
16021 /* BGP dampening */
16022 install_element(BGP_NODE, &bgp_damp_set_cmd);
16023 install_element(BGP_NODE, &bgp_damp_unset_cmd);
16024 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
16025 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
16026 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
16027 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
16028 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
16029 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
16030 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
16031 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
16032 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
16033 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
16034 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
16035 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
16036
16037 /* Large Communities */
16038 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
16039 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
16040
16041 /* show bgp ipv4 flowspec detailed */
16042 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
16043
16044 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16045 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16046 }
16047
16048 void bgp_route_finish(void)
16049 {
16050 afi_t afi;
16051 safi_t safi;
16052
16053 FOREACH_AFI_SAFI (afi, safi) {
16054 bgp_table_unlock(bgp_distance_table[afi][safi]);
16055 bgp_distance_table[afi][safi] = NULL;
16056 }
16057 }