]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #13074 from donaldsharp/hash_clean_and_free
[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 "thread.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, ROUTE_MAP_OUT_NAME(filter));
2390 bgp_attr_flush(rmap_path.attr);
2391 return false;
2392 }
2393 }
2394
2395 /* RFC 8212 to prevent route leaks.
2396 * This specification intends to improve this situation by requiring the
2397 * explicit configuration of both BGP Import and Export Policies for any
2398 * External BGP (EBGP) session such as customers, peers, or
2399 * confederation boundaries for all enabled address families. Through
2400 * codification of the aforementioned requirement, operators will
2401 * benefit from consistent behavior across different BGP
2402 * implementations.
2403 */
2404 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2405 if (!bgp_outbound_policy_exists(peer, filter)) {
2406 if (monotime_since(&bgp->ebgprequirespolicywarning,
2407 NULL) > FIFTEENMINUTE2USEC ||
2408 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2409 zlog_warn(
2410 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2411 monotime(&bgp->ebgprequirespolicywarning);
2412 }
2413 return false;
2414 }
2415
2416 /* draft-ietf-idr-deprecate-as-set-confed-set
2417 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2418 * Eventually, This document (if approved) updates RFC 4271
2419 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2420 * and obsoletes RFC 6472.
2421 */
2422 if (peer->bgp->reject_as_sets)
2423 if (aspath_check_as_sets(attr->aspath))
2424 return false;
2425
2426 /* If neighbor soo is configured, then check if the route has
2427 * SoO extended community and validate against the configured
2428 * one. If they match, do not announce, to prevent routing
2429 * loops.
2430 */
2431 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2432 peer->soo[afi][safi]) {
2433 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2434 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2435
2436 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2437 ECOMMUNITY_SITE_ORIGIN) ||
2438 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2439 ECOMMUNITY_SITE_ORIGIN) ||
2440 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2441 ECOMMUNITY_SITE_ORIGIN)) &&
2442 ecommunity_include(ecomm, ecomm_soo)) {
2443 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2444 zlog_debug(
2445 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2446 peer, p, ecommunity_str(ecomm_soo));
2447 return false;
2448 }
2449 }
2450
2451 /* Codification of AS 0 Processing */
2452 if (aspath_check_as_zero(attr->aspath))
2453 return false;
2454
2455 if (bgp_in_graceful_shutdown(bgp)) {
2456 if (peer->sort == BGP_PEER_IBGP
2457 || peer->sort == BGP_PEER_CONFED) {
2458 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2459 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2460 } else {
2461 bgp_attr_add_gshut_community(attr);
2462 }
2463 }
2464
2465 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2466 * Capability" to a neighbor MUST perform the following upon receiving
2467 * a route from that neighbor with the "LLGR_STALE" community, or upon
2468 * attaching the "LLGR_STALE" community itself per Section 4.2:
2469 *
2470 * The route SHOULD NOT be advertised to any neighbor from which the
2471 * Long-lived Graceful Restart Capability has not been received.
2472 */
2473 if (bgp_attr_get_community(attr) &&
2474 community_include(bgp_attr_get_community(attr),
2475 COMMUNITY_LLGR_STALE) &&
2476 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2477 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2478 return false;
2479
2480 /* After route-map has been applied, we check to see if the nexthop to
2481 * be carried in the attribute (that is used for the announcement) can
2482 * be cleared off or not. We do this in all cases where we would be
2483 * setting the nexthop to "ourselves". For IPv6, we only need to
2484 * consider
2485 * the global nexthop here; the link-local nexthop would have been
2486 * cleared
2487 * already, and if not, it is required by the update formation code.
2488 * Also see earlier comments in this function.
2489 */
2490 /*
2491 * If route-map has performed some operation on the nexthop or the peer
2492 * configuration says to pass it unchanged, we cannot reset the nexthop
2493 * here, so only attempt to do it if these aren't true. Note that the
2494 * route-map handler itself might have cleared the nexthop, if for
2495 * example,
2496 * it is configured as 'peer-address'.
2497 */
2498 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2499 piattr->rmap_change_flags)
2500 && !transparent
2501 && !CHECK_FLAG(peer->af_flags[afi][safi],
2502 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2503 /* We can reset the nexthop, if setting (or forcing) it to
2504 * 'self' */
2505 if (CHECK_FLAG(peer->af_flags[afi][safi],
2506 PEER_FLAG_NEXTHOP_SELF)
2507 || CHECK_FLAG(peer->af_flags[afi][safi],
2508 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2509 if (!reflect
2510 || CHECK_FLAG(peer->af_flags[afi][safi],
2511 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2512 subgroup_announce_reset_nhop(
2513 (peer_cap_enhe(peer, afi, safi)
2514 ? AF_INET6
2515 : p->family),
2516 attr);
2517 nh_reset = true;
2518 }
2519 } else if (peer->sort == BGP_PEER_EBGP) {
2520 /* Can also reset the nexthop if announcing to EBGP, but
2521 * only if
2522 * no peer in the subgroup is on a shared subnet.
2523 * Note: 3rd party nexthop currently implemented for
2524 * IPv4 only.
2525 */
2526 if ((p->family == AF_INET) &&
2527 (!bgp_subgrp_multiaccess_check_v4(
2528 piattr->nexthop,
2529 subgrp, from))) {
2530 subgroup_announce_reset_nhop(
2531 (peer_cap_enhe(peer, afi, safi)
2532 ? AF_INET6
2533 : p->family),
2534 attr);
2535 nh_reset = true;
2536 }
2537
2538 if ((p->family == AF_INET6) &&
2539 (!bgp_subgrp_multiaccess_check_v6(
2540 piattr->mp_nexthop_global,
2541 subgrp, from))) {
2542 subgroup_announce_reset_nhop(
2543 (peer_cap_enhe(peer, afi, safi)
2544 ? AF_INET6
2545 : p->family),
2546 attr);
2547 nh_reset = true;
2548 }
2549
2550
2551
2552 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2553 /*
2554 * This flag is used for leaked vpn-vrf routes
2555 */
2556 int family = p->family;
2557
2558 if (peer_cap_enhe(peer, afi, safi))
2559 family = AF_INET6;
2560
2561 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2562 zlog_debug(
2563 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2564 __func__, p, family2str(family));
2565 subgroup_announce_reset_nhop(family, attr);
2566 nh_reset = true;
2567 }
2568 }
2569
2570 /* If IPv6/MP and nexthop does not have any override and happens
2571 * to
2572 * be a link-local address, reset it so that we don't pass along
2573 * the
2574 * source's link-local IPv6 address to recipients who may not be
2575 * on
2576 * the same interface.
2577 */
2578 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2579 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2580 subgroup_announce_reset_nhop(AF_INET6, attr);
2581 nh_reset = true;
2582 }
2583 }
2584
2585 /* If this is an iBGP, send Origin Validation State (OVS)
2586 * extended community (rfc8097).
2587 */
2588 if (peer->sort == BGP_PEER_IBGP) {
2589 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2590
2591 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2592
2593 if (rpki_state != RPKI_NOT_BEING_USED)
2594 bgp_attr_set_ecommunity(
2595 attr, ecommunity_add_origin_validation_state(
2596 rpki_state,
2597 bgp_attr_get_ecommunity(attr)));
2598 }
2599
2600 /*
2601 * When the next hop is set to ourselves, if all multipaths have
2602 * link-bandwidth announce the cumulative bandwidth as that makes
2603 * the most sense. However, don't modify if the link-bandwidth has
2604 * been explicitly set by user policy.
2605 */
2606 if (nh_reset &&
2607 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2608 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2609 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2610 bgp_attr_set_ecommunity(
2611 attr,
2612 ecommunity_replace_linkbw(
2613 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2614 CHECK_FLAG(
2615 peer->flags,
2616 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2617
2618 return true;
2619 }
2620
2621 static void bgp_route_select_timer_expire(struct thread *thread)
2622 {
2623 struct afi_safi_info *info;
2624 afi_t afi;
2625 safi_t safi;
2626 struct bgp *bgp;
2627
2628 info = THREAD_ARG(thread);
2629 afi = info->afi;
2630 safi = info->safi;
2631 bgp = info->bgp;
2632
2633 bgp->gr_info[afi][safi].t_route_select = NULL;
2634 XFREE(MTYPE_TMP, info);
2635
2636 /* Best path selection */
2637 bgp_best_path_select_defer(bgp, afi, safi);
2638 }
2639
2640 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2641 struct bgp_maxpaths_cfg *mpath_cfg,
2642 struct bgp_path_info_pair *result, afi_t afi,
2643 safi_t safi)
2644 {
2645 struct bgp_path_info *new_select;
2646 struct bgp_path_info *old_select;
2647 struct bgp_path_info *pi;
2648 struct bgp_path_info *pi1;
2649 struct bgp_path_info *pi2;
2650 struct bgp_path_info *nextpi = NULL;
2651 int paths_eq, do_mpath, debug;
2652 struct list mp_list;
2653 char pfx_buf[PREFIX2STR_BUFFER];
2654 char path_buf[PATH_ADDPATH_STR_BUFFER];
2655
2656 bgp_mp_list_init(&mp_list);
2657 do_mpath =
2658 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2659
2660 debug = bgp_debug_bestpath(dest);
2661
2662 if (debug)
2663 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2664
2665 dest->reason = bgp_path_selection_none;
2666 /* bgp deterministic-med */
2667 new_select = NULL;
2668 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2669
2670 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2671 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2672 pi1 = pi1->next)
2673 bgp_path_info_unset_flag(dest, pi1,
2674 BGP_PATH_DMED_SELECTED);
2675
2676 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2677 pi1 = pi1->next) {
2678 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2679 continue;
2680 if (BGP_PATH_HOLDDOWN(pi1))
2681 continue;
2682 if (pi1->peer != bgp->peer_self &&
2683 !CHECK_FLAG(pi1->peer->sflags,
2684 PEER_STATUS_NSF_WAIT)) {
2685 if (!peer_established(pi1->peer))
2686 continue;
2687 }
2688
2689 new_select = pi1;
2690 if (pi1->next) {
2691 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2692 if (CHECK_FLAG(pi2->flags,
2693 BGP_PATH_DMED_CHECK))
2694 continue;
2695 if (BGP_PATH_HOLDDOWN(pi2))
2696 continue;
2697 if (pi2->peer != bgp->peer_self
2698 && !CHECK_FLAG(
2699 pi2->peer->sflags,
2700 PEER_STATUS_NSF_WAIT))
2701 if (pi2->peer->status
2702 != Established)
2703 continue;
2704
2705 if (!aspath_cmp_left(pi1->attr->aspath,
2706 pi2->attr->aspath)
2707 && !aspath_cmp_left_confed(
2708 pi1->attr->aspath,
2709 pi2->attr->aspath))
2710 continue;
2711
2712 if (bgp_path_info_cmp(
2713 bgp, pi2, new_select,
2714 &paths_eq, mpath_cfg, debug,
2715 pfx_buf, afi, safi,
2716 &dest->reason)) {
2717 bgp_path_info_unset_flag(
2718 dest, new_select,
2719 BGP_PATH_DMED_SELECTED);
2720 new_select = pi2;
2721 }
2722
2723 bgp_path_info_set_flag(
2724 dest, pi2, BGP_PATH_DMED_CHECK);
2725 }
2726 }
2727 bgp_path_info_set_flag(dest, new_select,
2728 BGP_PATH_DMED_CHECK);
2729 bgp_path_info_set_flag(dest, new_select,
2730 BGP_PATH_DMED_SELECTED);
2731
2732 if (debug) {
2733 bgp_path_info_path_with_addpath_rx_str(
2734 new_select, path_buf, sizeof(path_buf));
2735 zlog_debug(
2736 "%pBD(%s): %s is the bestpath from AS %u",
2737 dest, bgp->name_pretty, path_buf,
2738 aspath_get_first_as(
2739 new_select->attr->aspath));
2740 }
2741 }
2742 }
2743
2744 /* Check old selected route and new selected route. */
2745 old_select = NULL;
2746 new_select = NULL;
2747 for (pi = bgp_dest_get_bgp_path_info(dest);
2748 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2749 enum bgp_path_selection_reason reason;
2750
2751 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2752 old_select = pi;
2753
2754 if (BGP_PATH_HOLDDOWN(pi)) {
2755 /* reap REMOVED routes, if needs be
2756 * selected route must stay for a while longer though
2757 */
2758 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2759 && (pi != old_select))
2760 bgp_path_info_reap(dest, pi);
2761
2762 if (debug)
2763 zlog_debug(
2764 "%s: %pBD(%s) pi from %s in holddown",
2765 __func__, dest, bgp->name_pretty,
2766 pi->peer->host);
2767
2768 continue;
2769 }
2770
2771 if (pi->peer && pi->peer != bgp->peer_self
2772 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2773 if (!peer_established(pi->peer)) {
2774
2775 if (debug)
2776 zlog_debug(
2777 "%s: %pBD(%s) non self peer %s not estab state",
2778 __func__, dest,
2779 bgp->name_pretty,
2780 pi->peer->host);
2781
2782 continue;
2783 }
2784
2785 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2786 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2787 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2788 if (debug)
2789 zlog_debug("%s: %pBD(%s) pi %s dmed", __func__,
2790 dest, bgp->name_pretty,
2791 pi->peer->host);
2792 continue;
2793 }
2794
2795 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2796
2797 reason = dest->reason;
2798 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2799 debug, pfx_buf, afi, safi,
2800 &dest->reason)) {
2801 if (new_select == NULL &&
2802 reason != bgp_path_selection_none)
2803 dest->reason = reason;
2804 new_select = pi;
2805 }
2806 }
2807
2808 /* Now that we know which path is the bestpath see if any of the other
2809 * paths
2810 * qualify as multipaths
2811 */
2812 if (debug) {
2813 if (new_select)
2814 bgp_path_info_path_with_addpath_rx_str(
2815 new_select, path_buf, sizeof(path_buf));
2816 else
2817 snprintf(path_buf, sizeof(path_buf), "NONE");
2818 zlog_debug(
2819 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2820 dest, bgp->name_pretty, path_buf,
2821 old_select ? old_select->peer->host : "NONE");
2822 }
2823
2824 if (do_mpath && new_select) {
2825 for (pi = bgp_dest_get_bgp_path_info(dest);
2826 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2827
2828 if (debug)
2829 bgp_path_info_path_with_addpath_rx_str(
2830 pi, path_buf, sizeof(path_buf));
2831
2832 if (pi == new_select) {
2833 if (debug)
2834 zlog_debug(
2835 "%pBD(%s): %s is the bestpath, add to the multipath list",
2836 dest, bgp->name_pretty,
2837 path_buf);
2838 bgp_mp_list_add(&mp_list, pi);
2839 continue;
2840 }
2841
2842 if (BGP_PATH_HOLDDOWN(pi))
2843 continue;
2844
2845 if (pi->peer && pi->peer != bgp->peer_self
2846 && !CHECK_FLAG(pi->peer->sflags,
2847 PEER_STATUS_NSF_WAIT))
2848 if (!peer_established(pi->peer))
2849 continue;
2850
2851 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2852 if (debug)
2853 zlog_debug(
2854 "%pBD(%s): %s has the same nexthop as the bestpath, skip it",
2855 dest, bgp->name_pretty,
2856 path_buf);
2857 continue;
2858 }
2859
2860 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2861 mpath_cfg, debug, pfx_buf, afi, safi,
2862 &dest->reason);
2863
2864 if (paths_eq) {
2865 if (debug)
2866 zlog_debug(
2867 "%pBD(%s): %s is equivalent to the bestpath, add to the multipath list",
2868 dest, bgp->name_pretty,
2869 path_buf);
2870 bgp_mp_list_add(&mp_list, pi);
2871 }
2872 }
2873 }
2874
2875 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2876 mpath_cfg);
2877 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2878 bgp_mp_list_clear(&mp_list);
2879
2880 bgp_addpath_update_ids(bgp, dest, afi, safi);
2881
2882 result->old = old_select;
2883 result->new = new_select;
2884
2885 return;
2886 }
2887
2888 /*
2889 * A new route/change in bestpath of an existing route. Evaluate the path
2890 * for advertisement to the subgroup.
2891 */
2892 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2893 struct bgp_path_info *selected,
2894 struct bgp_dest *dest,
2895 uint32_t addpath_tx_id)
2896 {
2897 const struct prefix *p;
2898 struct peer *onlypeer;
2899 struct attr attr;
2900 afi_t afi;
2901 safi_t safi;
2902 struct bgp *bgp;
2903 bool advertise;
2904
2905 p = bgp_dest_get_prefix(dest);
2906 afi = SUBGRP_AFI(subgrp);
2907 safi = SUBGRP_SAFI(subgrp);
2908 bgp = SUBGRP_INST(subgrp);
2909 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2910 : NULL);
2911
2912 if (BGP_DEBUG(update, UPDATE_OUT))
2913 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2914
2915 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2916 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2917 PEER_STATUS_ORF_WAIT_REFRESH))
2918 return;
2919
2920 memset(&attr, 0, sizeof(attr));
2921 /* It's initialized in bgp_announce_check() */
2922
2923 /* Announcement to the subgroup. If the route is filtered withdraw it.
2924 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2925 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2926 * route
2927 */
2928 advertise = bgp_check_advertise(bgp, dest);
2929
2930 if (selected) {
2931 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2932 NULL)) {
2933 /* Route is selected, if the route is already installed
2934 * in FIB, then it is advertised
2935 */
2936 if (advertise) {
2937 if (!bgp_check_withdrawal(bgp, dest)) {
2938 struct attr *adv_attr =
2939 bgp_attr_intern(&attr);
2940
2941 bgp_adj_out_set_subgroup(dest, subgrp,
2942 adv_attr,
2943 selected);
2944 } else
2945 bgp_adj_out_unset_subgroup(
2946 dest, subgrp, 1, addpath_tx_id);
2947 }
2948 } else
2949 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2950 addpath_tx_id);
2951 }
2952
2953 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2954 else {
2955 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2956 }
2957 }
2958
2959 /*
2960 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2961 * This is called at the end of route processing.
2962 */
2963 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2964 {
2965 struct bgp_path_info *pi;
2966
2967 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2968 if (BGP_PATH_HOLDDOWN(pi))
2969 continue;
2970 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2971 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2972 }
2973 }
2974
2975 /*
2976 * Has the route changed from the RIB's perspective? This is invoked only
2977 * if the route selection returns the same best route as earlier - to
2978 * determine if we need to update zebra or not.
2979 */
2980 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2981 {
2982 struct bgp_path_info *mpinfo;
2983
2984 /* If this is multipath, check all selected paths for any nexthop
2985 * change or attribute change. Some attribute changes (e.g., community)
2986 * aren't of relevance to the RIB, but we'll update zebra to ensure
2987 * we handle the case of BGP nexthop change. This is the behavior
2988 * when the best path has an attribute change anyway.
2989 */
2990 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2991 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2992 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2993 return true;
2994
2995 /*
2996 * If this is multipath, check all selected paths for any nexthop change
2997 */
2998 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2999 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3000 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3001 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3002 return true;
3003 }
3004
3005 /* Nothing has changed from the RIB's perspective. */
3006 return false;
3007 }
3008
3009 struct bgp_process_queue {
3010 struct bgp *bgp;
3011 STAILQ_HEAD(, bgp_dest) pqueue;
3012 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3013 unsigned int flags;
3014 unsigned int queued;
3015 };
3016
3017 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3018 safi_t safi, struct bgp_dest *dest,
3019 struct bgp_path_info *new_select,
3020 struct bgp_path_info *old_select)
3021 {
3022 const struct prefix *p = bgp_dest_get_prefix(dest);
3023
3024 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3025 return;
3026
3027 if (advertise_type5_routes(bgp, afi) && new_select
3028 && is_route_injectable_into_evpn(new_select)) {
3029
3030 /* apply the route-map */
3031 if (bgp->adv_cmd_rmap[afi][safi].map) {
3032 route_map_result_t ret;
3033 struct bgp_path_info rmap_path;
3034 struct bgp_path_info_extra rmap_path_extra;
3035 struct attr dummy_attr;
3036
3037 dummy_attr = *new_select->attr;
3038
3039 /* Fill temp path_info */
3040 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3041 new_select, new_select->peer,
3042 &dummy_attr);
3043
3044 RESET_FLAG(dummy_attr.rmap_change_flags);
3045
3046 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3047 p, &rmap_path);
3048
3049 if (ret == RMAP_DENYMATCH) {
3050 bgp_attr_flush(&dummy_attr);
3051 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3052 safi);
3053 } else
3054 bgp_evpn_advertise_type5_route(
3055 bgp, p, &dummy_attr, afi, safi);
3056 } else {
3057 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3058 afi, safi);
3059 }
3060 } else if (advertise_type5_routes(bgp, afi) && old_select
3061 && is_route_injectable_into_evpn(old_select))
3062 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3063 }
3064
3065 /*
3066 * Utility to determine whether a particular path_info should use
3067 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3068 * in a path where we basically _know_ this is a BGP-LU route.
3069 */
3070 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3071 {
3072 /* Certain types get imp null; so do paths where the nexthop is
3073 * not labeled.
3074 */
3075 if (new_select->sub_type == BGP_ROUTE_STATIC
3076 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3077 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3078 return true;
3079 else if (new_select->extra == NULL ||
3080 !bgp_is_valid_label(&new_select->extra->label[0]))
3081 /* TODO -- should be configurable? */
3082 return true;
3083 else
3084 return false;
3085 }
3086
3087 /*
3088 * old_select = The old best path
3089 * new_select = the new best path
3090 *
3091 * if (!old_select && new_select)
3092 * We are sending new information on.
3093 *
3094 * if (old_select && new_select) {
3095 * if (new_select != old_select)
3096 * We have a new best path send a change
3097 * else
3098 * We've received a update with new attributes that needs
3099 * to be passed on.
3100 * }
3101 *
3102 * if (old_select && !new_select)
3103 * We have no eligible route that we can announce or the rn
3104 * is being removed.
3105 */
3106 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3107 afi_t afi, safi_t safi)
3108 {
3109 struct bgp_path_info *new_select;
3110 struct bgp_path_info *old_select;
3111 struct bgp_path_info_pair old_and_new;
3112 int debug = 0;
3113
3114 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3115 if (dest)
3116 debug = bgp_debug_bestpath(dest);
3117 if (debug)
3118 zlog_debug(
3119 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3120 __func__, dest, bgp->name_pretty);
3121 return;
3122 }
3123 /* Is it end of initial update? (after startup) */
3124 if (!dest) {
3125 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3126 sizeof(bgp->update_delay_zebra_resume_time));
3127
3128 bgp->main_zebra_update_hold = 0;
3129 FOREACH_AFI_SAFI (afi, safi) {
3130 if (bgp_fibupd_safi(safi))
3131 bgp_zebra_announce_table(bgp, afi, safi);
3132 }
3133 bgp->main_peers_update_hold = 0;
3134
3135 bgp_start_routeadv(bgp);
3136 return;
3137 }
3138
3139 const struct prefix *p = bgp_dest_get_prefix(dest);
3140
3141 debug = bgp_debug_bestpath(dest);
3142 if (debug)
3143 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3144 dest, bgp->name_pretty, afi2str(afi),
3145 safi2str(safi));
3146
3147 /* The best path calculation for the route is deferred if
3148 * BGP_NODE_SELECT_DEFER is set
3149 */
3150 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3151 if (BGP_DEBUG(update, UPDATE_OUT))
3152 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3153 dest, bgp->name_pretty);
3154 return;
3155 }
3156
3157 /* Best path selection. */
3158 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3159 afi, safi);
3160 old_select = old_and_new.old;
3161 new_select = old_and_new.new;
3162
3163 /* Do we need to allocate or free labels?
3164 * Right now, since we only deal with per-prefix labels, it is not
3165 * necessary to do this upon changes to best path. Exceptions:
3166 * - label index has changed -> recalculate resulting label
3167 * - path_info sub_type changed -> switch to/from implicit-null
3168 * - no valid label (due to removed static label binding) -> get new one
3169 */
3170 if (bgp->allocate_mpls_labels[afi][safi]) {
3171 if (new_select) {
3172 if (!old_select
3173 || bgp_label_index_differs(new_select, old_select)
3174 || new_select->sub_type != old_select->sub_type
3175 || !bgp_is_valid_label(&dest->local_label)) {
3176 /* Enforced penultimate hop popping:
3177 * implicit-null for local routes, aggregate
3178 * and redistributed routes
3179 */
3180 if (bgp_lu_need_imp_null(new_select)) {
3181 if (CHECK_FLAG(
3182 dest->flags,
3183 BGP_NODE_REGISTERED_FOR_LABEL)
3184 || CHECK_FLAG(
3185 dest->flags,
3186 BGP_NODE_LABEL_REQUESTED))
3187 bgp_unregister_for_label(dest);
3188 dest->local_label = mpls_lse_encode(
3189 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3190 1);
3191 bgp_set_valid_label(&dest->local_label);
3192 } else
3193 bgp_register_for_label(dest,
3194 new_select);
3195 }
3196 } else if (CHECK_FLAG(dest->flags,
3197 BGP_NODE_REGISTERED_FOR_LABEL)
3198 || CHECK_FLAG(dest->flags,
3199 BGP_NODE_LABEL_REQUESTED)) {
3200 bgp_unregister_for_label(dest);
3201 }
3202 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3203 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3204 bgp_unregister_for_label(dest);
3205 }
3206
3207 if (debug)
3208 zlog_debug(
3209 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3210 __func__, dest, bgp->name_pretty, afi2str(afi),
3211 safi2str(safi), old_select, new_select);
3212
3213 /* If best route remains the same and this is not due to user-initiated
3214 * clear, see exactly what needs to be done.
3215 */
3216 if (old_select && old_select == new_select
3217 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3218 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3219 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3220 if (bgp_zebra_has_route_changed(old_select)) {
3221 #ifdef ENABLE_BGP_VNC
3222 vnc_import_bgp_add_route(bgp, p, old_select);
3223 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3224 #endif
3225 if (bgp_fibupd_safi(safi)
3226 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3227
3228 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3229 && new_select->sub_type == BGP_ROUTE_NORMAL)
3230 SET_FLAG(dest->flags,
3231 BGP_NODE_FIB_INSTALL_PENDING);
3232
3233 if (new_select->type == ZEBRA_ROUTE_BGP
3234 && (new_select->sub_type == BGP_ROUTE_NORMAL
3235 || new_select->sub_type
3236 == BGP_ROUTE_IMPORTED))
3237
3238 bgp_zebra_announce(dest, p, old_select,
3239 bgp, afi, safi);
3240 }
3241 }
3242
3243 /* If there is a change of interest to peers, reannounce the
3244 * route. */
3245 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3246 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3247 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3248 group_announce_route(bgp, afi, safi, dest, new_select);
3249
3250 /* unicast routes must also be annouced to
3251 * labeled-unicast update-groups */
3252 if (safi == SAFI_UNICAST)
3253 group_announce_route(bgp, afi,
3254 SAFI_LABELED_UNICAST, dest,
3255 new_select);
3256
3257 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3258 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3259 }
3260
3261 /* advertise/withdraw type-5 routes */
3262 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3263 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3264 bgp_process_evpn_route_injection(
3265 bgp, afi, safi, dest, old_select, old_select);
3266
3267 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3268 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3269 bgp_zebra_clear_route_change_flags(dest);
3270 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3271 return;
3272 }
3273
3274 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3275 */
3276 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3277
3278 /* bestpath has changed; bump version */
3279 if (old_select || new_select) {
3280 bgp_bump_version(dest);
3281
3282 if (!bgp->t_rmap_def_originate_eval) {
3283 bgp_lock(bgp);
3284 thread_add_timer(
3285 bm->master,
3286 update_group_refresh_default_originate_route_map,
3287 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3288 &bgp->t_rmap_def_originate_eval);
3289 }
3290 }
3291
3292 if (old_select)
3293 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3294 if (new_select) {
3295 if (debug)
3296 zlog_debug("%s: setting SELECTED flag", __func__);
3297 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3298 bgp_path_info_unset_flag(dest, new_select,
3299 BGP_PATH_ATTR_CHANGED);
3300 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3301 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3302 }
3303
3304 #ifdef ENABLE_BGP_VNC
3305 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3306 if (old_select != new_select) {
3307 if (old_select) {
3308 vnc_import_bgp_exterior_del_route(bgp, p,
3309 old_select);
3310 vnc_import_bgp_del_route(bgp, p, old_select);
3311 }
3312 if (new_select) {
3313 vnc_import_bgp_exterior_add_route(bgp, p,
3314 new_select);
3315 vnc_import_bgp_add_route(bgp, p, new_select);
3316 }
3317 }
3318 }
3319 #endif
3320
3321 group_announce_route(bgp, afi, safi, dest, new_select);
3322
3323 /* unicast routes must also be annouced to labeled-unicast update-groups
3324 */
3325 if (safi == SAFI_UNICAST)
3326 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3327 new_select);
3328
3329 /* FIB update. */
3330 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3331 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3332
3333 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3334 && (new_select->sub_type == BGP_ROUTE_NORMAL
3335 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3336 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3337
3338 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3339 SET_FLAG(dest->flags,
3340 BGP_NODE_FIB_INSTALL_PENDING);
3341
3342 /* if this is an evpn imported type-5 prefix,
3343 * we need to withdraw the route first to clear
3344 * the nh neigh and the RMAC entry.
3345 */
3346 if (old_select &&
3347 is_route_parent_evpn(old_select))
3348 bgp_zebra_withdraw(p, old_select, bgp, safi);
3349
3350 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3351 } else {
3352 /* Withdraw the route from the kernel. */
3353 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3354 && (old_select->sub_type == BGP_ROUTE_NORMAL
3355 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3356 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3357
3358 bgp_zebra_withdraw(p, old_select, bgp, safi);
3359 }
3360 }
3361
3362 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3363 old_select);
3364
3365 /* Clear any route change flags. */
3366 bgp_zebra_clear_route_change_flags(dest);
3367
3368 /* Reap old select bgp_path_info, if it has been removed */
3369 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3370 bgp_path_info_reap(dest, old_select);
3371
3372 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3373 return;
3374 }
3375
3376 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3377 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3378 {
3379 struct bgp_dest *dest;
3380 int cnt = 0;
3381 struct afi_safi_info *thread_info;
3382
3383 if (bgp->gr_info[afi][safi].t_route_select) {
3384 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3385
3386 thread_info = THREAD_ARG(t);
3387 XFREE(MTYPE_TMP, thread_info);
3388 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3389 }
3390
3391 if (BGP_DEBUG(update, UPDATE_OUT)) {
3392 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3393 get_afi_safi_str(afi, safi, false),
3394 bgp->gr_info[afi][safi].gr_deferred);
3395 }
3396
3397 /* Process the route list */
3398 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3399 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3400 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3401 dest = bgp_route_next(dest)) {
3402 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3403 continue;
3404
3405 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3406 bgp->gr_info[afi][safi].gr_deferred--;
3407 bgp_process_main_one(bgp, dest, afi, safi);
3408 cnt++;
3409 }
3410 /* If iteration stopped before the entire table was traversed then the
3411 * node needs to be unlocked.
3412 */
3413 if (dest) {
3414 bgp_dest_unlock_node(dest);
3415 dest = NULL;
3416 }
3417
3418 /* Send EOR message when all routes are processed */
3419 if (!bgp->gr_info[afi][safi].gr_deferred) {
3420 bgp_send_delayed_eor(bgp);
3421 /* Send route processing complete message to RIB */
3422 bgp_zebra_update(bgp, afi, safi,
3423 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3424 return;
3425 }
3426
3427 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3428
3429 thread_info->afi = afi;
3430 thread_info->safi = safi;
3431 thread_info->bgp = bgp;
3432
3433 /* If there are more routes to be processed, start the
3434 * selection timer
3435 */
3436 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3437 BGP_ROUTE_SELECT_DELAY,
3438 &bgp->gr_info[afi][safi].t_route_select);
3439 }
3440
3441 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3442 {
3443 struct bgp_process_queue *pqnode = data;
3444 struct bgp *bgp = pqnode->bgp;
3445 struct bgp_table *table;
3446 struct bgp_dest *dest;
3447
3448 /* eoiu marker */
3449 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3450 bgp_process_main_one(bgp, NULL, 0, 0);
3451 /* should always have dedicated wq call */
3452 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3453 return WQ_SUCCESS;
3454 }
3455
3456 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3457 dest = STAILQ_FIRST(&pqnode->pqueue);
3458 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3459 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3460 table = bgp_dest_table(dest);
3461 /* note, new DESTs may be added as part of processing */
3462 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3463
3464 bgp_dest_unlock_node(dest);
3465 bgp_table_unlock(table);
3466 }
3467
3468 return WQ_SUCCESS;
3469 }
3470
3471 static void bgp_processq_del(struct work_queue *wq, void *data)
3472 {
3473 struct bgp_process_queue *pqnode = data;
3474
3475 bgp_unlock(pqnode->bgp);
3476
3477 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3478 }
3479
3480 void bgp_process_queue_init(struct bgp *bgp)
3481 {
3482 if (!bgp->process_queue) {
3483 char name[BUFSIZ];
3484
3485 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3486 bgp->process_queue = work_queue_new(bm->master, name);
3487 }
3488
3489 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3490 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3491 bgp->process_queue->spec.max_retries = 0;
3492 bgp->process_queue->spec.hold = 50;
3493 /* Use a higher yield value of 50ms for main queue processing */
3494 bgp->process_queue->spec.yield = 50 * 1000L;
3495 }
3496
3497 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3498 {
3499 struct bgp_process_queue *pqnode;
3500
3501 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3502 sizeof(struct bgp_process_queue));
3503
3504 /* unlocked in bgp_processq_del */
3505 pqnode->bgp = bgp_lock(bgp);
3506 STAILQ_INIT(&pqnode->pqueue);
3507
3508 return pqnode;
3509 }
3510
3511 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3512 {
3513 #define ARBITRARY_PROCESS_QLEN 10000
3514 struct work_queue *wq = bgp->process_queue;
3515 struct bgp_process_queue *pqnode;
3516 int pqnode_reuse = 0;
3517
3518 /* already scheduled for processing? */
3519 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3520 return;
3521
3522 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3523 * the workqueue
3524 */
3525 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3526 if (BGP_DEBUG(update, UPDATE_OUT))
3527 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3528 dest);
3529 return;
3530 }
3531
3532 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3533 if (BGP_DEBUG(update, UPDATE_OUT))
3534 zlog_debug(
3535 "Soft reconfigure table in progress for route %p",
3536 dest);
3537 return;
3538 }
3539
3540 if (wq == NULL)
3541 return;
3542
3543 /* Add route nodes to an existing work queue item until reaching the
3544 limit only if is from the same BGP view and it's not an EOIU marker
3545 */
3546 if (work_queue_item_count(wq)) {
3547 struct work_queue_item *item = work_queue_last_item(wq);
3548 pqnode = item->data;
3549
3550 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3551 || pqnode->bgp != bgp
3552 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3553 pqnode = bgp_processq_alloc(bgp);
3554 else
3555 pqnode_reuse = 1;
3556 } else
3557 pqnode = bgp_processq_alloc(bgp);
3558 /* all unlocked in bgp_process_wq */
3559 bgp_table_lock(bgp_dest_table(dest));
3560
3561 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3562 bgp_dest_lock_node(dest);
3563
3564 /* can't be enqueued twice */
3565 assert(STAILQ_NEXT(dest, pq) == NULL);
3566 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3567 pqnode->queued++;
3568
3569 if (!pqnode_reuse)
3570 work_queue_add(wq, pqnode);
3571
3572 return;
3573 }
3574
3575 void bgp_add_eoiu_mark(struct bgp *bgp)
3576 {
3577 struct bgp_process_queue *pqnode;
3578
3579 if (bgp->process_queue == NULL)
3580 return;
3581
3582 pqnode = bgp_processq_alloc(bgp);
3583
3584 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3585 work_queue_add(bgp->process_queue, pqnode);
3586 }
3587
3588 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3589 {
3590 struct peer *peer;
3591
3592 peer = THREAD_ARG(thread);
3593 peer->t_pmax_restart = NULL;
3594
3595 if (bgp_debug_neighbor_events(peer))
3596 zlog_debug(
3597 "%s Maximum-prefix restart timer expired, restore peering",
3598 peer->host);
3599
3600 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3601 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3602 }
3603
3604 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3605 safi_t safi)
3606 {
3607 uint32_t count = 0;
3608 bool filtered = false;
3609 struct bgp_dest *dest;
3610 struct bgp_adj_in *ain;
3611 struct attr attr = {};
3612 struct bgp_table *table = peer->bgp->rib[afi][safi];
3613
3614 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3615 for (ain = dest->adj_in; ain; ain = ain->next) {
3616 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3617
3618 attr = *ain->attr;
3619
3620 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3621 == FILTER_DENY)
3622 filtered = true;
3623
3624 if (bgp_input_modifier(
3625 peer, rn_p, &attr, afi, safi,
3626 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3627 NULL, 0, NULL)
3628 == RMAP_DENY)
3629 filtered = true;
3630
3631 if (filtered)
3632 count++;
3633
3634 bgp_attr_flush(&attr);
3635 }
3636 }
3637
3638 return count;
3639 }
3640
3641 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3642 int always)
3643 {
3644 iana_afi_t pkt_afi;
3645 iana_safi_t pkt_safi;
3646 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3647 PEER_FLAG_MAX_PREFIX_FORCE))
3648 ? bgp_filtered_routes_count(peer, afi, safi)
3649 + peer->pcount[afi][safi]
3650 : peer->pcount[afi][safi];
3651
3652 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3653 return false;
3654
3655 if (pcount > peer->pmax[afi][safi]) {
3656 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3657 PEER_STATUS_PREFIX_LIMIT)
3658 && !always)
3659 return false;
3660
3661 zlog_info(
3662 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3663 get_afi_safi_str(afi, safi, false), peer, pcount,
3664 peer->pmax[afi][safi]);
3665 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3666
3667 if (CHECK_FLAG(peer->af_flags[afi][safi],
3668 PEER_FLAG_MAX_PREFIX_WARNING))
3669 return false;
3670
3671 /* Convert AFI, SAFI to values for packet. */
3672 pkt_afi = afi_int2iana(afi);
3673 pkt_safi = safi_int2iana(safi);
3674 {
3675 uint8_t ndata[7];
3676
3677 ndata[0] = (pkt_afi >> 8);
3678 ndata[1] = pkt_afi;
3679 ndata[2] = pkt_safi;
3680 ndata[3] = (peer->pmax[afi][safi] >> 24);
3681 ndata[4] = (peer->pmax[afi][safi] >> 16);
3682 ndata[5] = (peer->pmax[afi][safi] >> 8);
3683 ndata[6] = (peer->pmax[afi][safi]);
3684
3685 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3686 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3687 BGP_NOTIFY_CEASE_MAX_PREFIX,
3688 ndata, 7);
3689 }
3690
3691 /* Dynamic peers will just close their connection. */
3692 if (peer_dynamic_neighbor(peer))
3693 return true;
3694
3695 /* restart timer start */
3696 if (peer->pmax_restart[afi][safi]) {
3697 peer->v_pmax_restart =
3698 peer->pmax_restart[afi][safi] * 60;
3699
3700 if (bgp_debug_neighbor_events(peer))
3701 zlog_debug(
3702 "%pBP Maximum-prefix restart timer started for %d secs",
3703 peer, peer->v_pmax_restart);
3704
3705 BGP_TIMER_ON(peer->t_pmax_restart,
3706 bgp_maximum_prefix_restart_timer,
3707 peer->v_pmax_restart);
3708 }
3709
3710 return true;
3711 } else
3712 UNSET_FLAG(peer->af_sflags[afi][safi],
3713 PEER_STATUS_PREFIX_LIMIT);
3714
3715 if (pcount
3716 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3717 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3718 PEER_STATUS_PREFIX_THRESHOLD)
3719 && !always)
3720 return false;
3721
3722 zlog_info(
3723 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3724 get_afi_safi_str(afi, safi, false), peer, pcount,
3725 peer->pmax[afi][safi]);
3726 SET_FLAG(peer->af_sflags[afi][safi],
3727 PEER_STATUS_PREFIX_THRESHOLD);
3728 } else
3729 UNSET_FLAG(peer->af_sflags[afi][safi],
3730 PEER_STATUS_PREFIX_THRESHOLD);
3731 return false;
3732 }
3733
3734 /* Unconditionally remove the route from the RIB, without taking
3735 * damping into consideration (eg, because the session went down)
3736 */
3737 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3738 struct peer *peer, afi_t afi, safi_t safi)
3739 {
3740
3741 struct bgp *bgp = NULL;
3742 bool delete_route = false;
3743
3744 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3745 safi);
3746
3747 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3748 bgp_path_info_delete(dest, pi); /* keep historical info */
3749
3750 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3751 * flag
3752 */
3753 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3754 delete_route = true;
3755 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3756 delete_route = true;
3757 if (delete_route) {
3758 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3759 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3760 bgp = pi->peer->bgp;
3761 bgp->gr_info[afi][safi].gr_deferred--;
3762 }
3763 }
3764 }
3765
3766 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3767 bgp_process(peer->bgp, dest, afi, safi);
3768 }
3769
3770 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3771 struct peer *peer, afi_t afi, safi_t safi,
3772 struct prefix_rd *prd)
3773 {
3774 const struct prefix *p = bgp_dest_get_prefix(dest);
3775
3776 /* apply dampening, if result is suppressed, we'll be retaining
3777 * the bgp_path_info in the RIB for historical reference.
3778 */
3779 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3780 && peer->sort == BGP_PEER_EBGP)
3781 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3782 == BGP_DAMP_SUPPRESSED) {
3783 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3784 safi);
3785 return;
3786 }
3787
3788 #ifdef ENABLE_BGP_VNC
3789 if (safi == SAFI_MPLS_VPN) {
3790 struct bgp_dest *pdest = NULL;
3791 struct bgp_table *table = NULL;
3792
3793 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3794 (struct prefix *)prd);
3795 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3796 table = bgp_dest_get_bgp_table_info(pdest);
3797
3798 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3799 peer->bgp, prd, table, p, pi);
3800 }
3801 bgp_dest_unlock_node(pdest);
3802 }
3803 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3804 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3805
3806 vnc_import_bgp_del_route(peer->bgp, p, pi);
3807 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3808 }
3809 }
3810 #endif
3811
3812 /* If this is an EVPN route, process for un-import. */
3813 if (safi == SAFI_EVPN)
3814 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3815
3816 bgp_rib_remove(dest, pi, peer, afi, safi);
3817 }
3818
3819 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3820 struct peer *peer, struct attr *attr,
3821 struct bgp_dest *dest)
3822 {
3823 struct bgp_path_info *new;
3824
3825 /* Make new BGP info. */
3826 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3827 new->type = type;
3828 new->instance = instance;
3829 new->sub_type = sub_type;
3830 new->peer = peer;
3831 new->attr = attr;
3832 new->uptime = monotime(NULL);
3833 new->net = dest;
3834 return new;
3835 }
3836
3837 /* Check if received nexthop is valid or not. */
3838 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3839 uint8_t type, uint8_t stype, struct attr *attr,
3840 struct bgp_dest *dest)
3841 {
3842 bool ret = false;
3843 bool is_bgp_static_route =
3844 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3845 : false;
3846
3847 /*
3848 * Only validated for unicast and multicast currently.
3849 * Also valid for EVPN where the nexthop is an IP address.
3850 * If we are a bgp static route being checked then there is
3851 * no need to check to see if the nexthop is martian as
3852 * that it should be ok.
3853 */
3854 if (is_bgp_static_route ||
3855 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3856 return false;
3857
3858 /* If NEXT_HOP is present, validate it. */
3859 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3860 if (attr->nexthop.s_addr == INADDR_ANY ||
3861 !ipv4_unicast_valid(&attr->nexthop) ||
3862 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3863 return true;
3864 }
3865
3866 /* If MP_NEXTHOP is present, validate it. */
3867 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3868 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3869 * it is not an IPv6 link-local address.
3870 *
3871 * If we receive an UPDATE with nexthop length set to 32 bytes
3872 * we shouldn't discard an UPDATE if it's set to (::).
3873 * The link-local (2st) is validated along the code path later.
3874 */
3875 if (attr->mp_nexthop_len) {
3876 switch (attr->mp_nexthop_len) {
3877 case BGP_ATTR_NHLEN_IPV4:
3878 case BGP_ATTR_NHLEN_VPNV4:
3879 ret = (attr->mp_nexthop_global_in.s_addr ==
3880 INADDR_ANY ||
3881 !ipv4_unicast_valid(
3882 &attr->mp_nexthop_global_in) ||
3883 bgp_nexthop_self(bgp, afi, type, stype, attr,
3884 dest));
3885 break;
3886
3887 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3888 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3889 ret = (IN6_IS_ADDR_UNSPECIFIED(
3890 &attr->mp_nexthop_global)
3891 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3892 || IN6_IS_ADDR_MULTICAST(
3893 &attr->mp_nexthop_global)
3894 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3895 dest));
3896 break;
3897 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3898 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3899 || IN6_IS_ADDR_MULTICAST(
3900 &attr->mp_nexthop_global)
3901 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3902 dest));
3903 break;
3904
3905 default:
3906 ret = true;
3907 break;
3908 }
3909 }
3910
3911 return ret;
3912 }
3913
3914 static void bgp_attr_add_no_export_community(struct attr *attr)
3915 {
3916 struct community *old;
3917 struct community *new;
3918 struct community *merge;
3919 struct community *no_export;
3920
3921 old = bgp_attr_get_community(attr);
3922 no_export = community_str2com("no-export");
3923
3924 assert(no_export);
3925
3926 if (old) {
3927 merge = community_merge(community_dup(old), no_export);
3928
3929 if (!old->refcnt)
3930 community_free(&old);
3931
3932 new = community_uniq_sort(merge);
3933 community_free(&merge);
3934 } else {
3935 new = community_dup(no_export);
3936 }
3937
3938 community_free(&no_export);
3939
3940 bgp_attr_set_community(attr, new);
3941 }
3942
3943 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3944 struct attr *attr, const struct prefix *prefix,
3945 int *sub_type)
3946 {
3947 struct listnode *node, *nnode;
3948 struct bgp *bgp;
3949 bool accept_own_found = false;
3950
3951 if (safi != SAFI_MPLS_VPN)
3952 return false;
3953
3954 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3955 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3956 return false;
3957
3958 /* The route in question carries the ACCEPT_OWN community */
3959 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3960 struct community *comm = bgp_attr_get_community(attr);
3961
3962 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3963 accept_own_found = true;
3964 }
3965
3966 /* The route in question is targeted to one or more destination VRFs
3967 * on the router (as determined by inspecting the Route Target(s)).
3968 */
3969 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3970 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3971 continue;
3972
3973 if (accept_own_found &&
3974 ecommunity_include(
3975 bgp->vpn_policy[afi]
3976 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3977 bgp_attr_get_ecommunity(attr))) {
3978 if (bgp_debug_update(peer, prefix, NULL, 1))
3979 zlog_debug(
3980 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3981 peer, prefix);
3982
3983 /* Treat this route as imported, because it's leaked
3984 * already from another VRF, and we got an updated
3985 * version from route-reflector with ACCEPT_OWN
3986 * community.
3987 */
3988 *sub_type = BGP_ROUTE_IMPORTED;
3989
3990 return true;
3991 }
3992 }
3993
3994 return false;
3995 }
3996
3997 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3998 struct attr *attr, afi_t afi, safi_t safi, int type,
3999 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4000 uint32_t num_labels, int soft_reconfig,
4001 struct bgp_route_evpn *evpn)
4002 {
4003 int ret;
4004 int aspath_loop_count = 0;
4005 struct bgp_dest *dest;
4006 struct bgp *bgp;
4007 struct attr new_attr;
4008 struct attr *attr_new;
4009 struct bgp_path_info *pi;
4010 struct bgp_path_info *new = NULL;
4011 struct bgp_path_info_extra *extra;
4012 const char *reason;
4013 char pfx_buf[BGP_PRD_PATH_STRLEN];
4014 int connected = 0;
4015 int do_loop_check = 1;
4016 int has_valid_label = 0;
4017 afi_t nh_afi;
4018 bool force_evpn_import = false;
4019 safi_t orig_safi = safi;
4020 bool leak_success = true;
4021 int allowas_in = 0;
4022
4023 if (frrtrace_enabled(frr_bgp, process_update)) {
4024 char pfxprint[PREFIX2STR_BUFFER];
4025
4026 prefix2str(p, pfxprint, sizeof(pfxprint));
4027 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4028 afi, safi, attr);
4029 }
4030
4031 #ifdef ENABLE_BGP_VNC
4032 int vnc_implicit_withdraw = 0;
4033 #endif
4034 int same_attr = 0;
4035 const struct prefix *bgp_nht_param_prefix;
4036
4037 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4038 if (orig_safi == SAFI_LABELED_UNICAST)
4039 safi = SAFI_UNICAST;
4040
4041 memset(&new_attr, 0, sizeof(new_attr));
4042 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4043 new_attr.label = MPLS_INVALID_LABEL;
4044
4045 bgp = peer->bgp;
4046 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4047 /* TODO: Check to see if we can get rid of "is_valid_label" */
4048 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4049 has_valid_label = (num_labels > 0) ? 1 : 0;
4050 else
4051 has_valid_label = bgp_is_valid_label(label);
4052
4053 if (has_valid_label)
4054 assert(label != NULL);
4055
4056 /* Update overlay index of the attribute */
4057 if (afi == AFI_L2VPN && evpn)
4058 memcpy(&attr->evpn_overlay, evpn,
4059 sizeof(struct bgp_route_evpn));
4060
4061 /* When peer's soft reconfiguration enabled. Record input packet in
4062 Adj-RIBs-In. */
4063 if (!soft_reconfig
4064 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4065 && peer != bgp->peer_self)
4066 bgp_adj_in_set(dest, peer, attr, addpath_id);
4067
4068 /* Update permitted loop count */
4069 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4070 allowas_in = peer->allowas_in[afi][safi];
4071
4072 /* Check previously received route. */
4073 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4074 if (pi->peer == peer && pi->type == type
4075 && pi->sub_type == sub_type
4076 && pi->addpath_rx_id == addpath_id)
4077 break;
4078
4079 /* AS path local-as loop check. */
4080 if (peer->change_local_as) {
4081 if (allowas_in)
4082 aspath_loop_count = allowas_in;
4083 else if (!CHECK_FLAG(peer->flags,
4084 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4085 aspath_loop_count = 1;
4086
4087 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4088 > aspath_loop_count) {
4089 peer->stat_pfx_aspath_loop++;
4090 reason = "as-path contains our own AS;";
4091 goto filtered;
4092 }
4093 }
4094
4095 /* If the peer is configured for "allowas-in origin" and the last ASN in
4096 * the
4097 * as-path is our ASN then we do not need to call aspath_loop_check
4098 */
4099 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4100 if (aspath_get_last_as(attr->aspath) == bgp->as)
4101 do_loop_check = 0;
4102
4103 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4104 bgp_nht_param_prefix = NULL;
4105 else
4106 bgp_nht_param_prefix = p;
4107
4108 /* AS path loop check. */
4109 if (do_loop_check) {
4110 if (aspath_loop_check(attr->aspath, bgp->as) >
4111 peer->allowas_in[afi][safi]) {
4112 peer->stat_pfx_aspath_loop++;
4113 reason = "as-path contains our own AS;";
4114 goto filtered;
4115 }
4116 }
4117
4118 /* If we're a CONFED we need to loop check the CONFED ID too */
4119 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4120 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4121 peer->allowas_in[afi][safi]) {
4122 peer->stat_pfx_aspath_loop++;
4123 reason = "as-path contains our own confed AS;";
4124 goto filtered;
4125 }
4126
4127 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4128 * enabled, then take care of that too.
4129 */
4130 bool accept_own = false;
4131
4132 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4133 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4134 accept_own =
4135 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4136 if (!accept_own) {
4137 peer->stat_pfx_originator_loop++;
4138 reason = "originator is us;";
4139 goto filtered;
4140 }
4141 }
4142
4143 /* Route reflector cluster ID check. */
4144 if (bgp_cluster_filter(peer, attr)) {
4145 peer->stat_pfx_cluster_loop++;
4146 reason = "reflected from the same cluster;";
4147 goto filtered;
4148 }
4149
4150 /* Apply incoming filter. */
4151 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4152 peer->stat_pfx_filter++;
4153 reason = "filter;";
4154 goto filtered;
4155 }
4156
4157 /* RFC 8212 to prevent route leaks.
4158 * This specification intends to improve this situation by requiring the
4159 * explicit configuration of both BGP Import and Export Policies for any
4160 * External BGP (EBGP) session such as customers, peers, or
4161 * confederation boundaries for all enabled address families. Through
4162 * codification of the aforementioned requirement, operators will
4163 * benefit from consistent behavior across different BGP
4164 * implementations.
4165 */
4166 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4167 if (!bgp_inbound_policy_exists(peer,
4168 &peer->filter[afi][safi])) {
4169 reason = "inbound policy missing";
4170 if (monotime_since(&bgp->ebgprequirespolicywarning,
4171 NULL) > FIFTEENMINUTE2USEC ||
4172 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4173 zlog_warn(
4174 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4175 monotime(&bgp->ebgprequirespolicywarning);
4176 }
4177 goto filtered;
4178 }
4179
4180 /* draft-ietf-idr-deprecate-as-set-confed-set
4181 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4182 * Eventually, This document (if approved) updates RFC 4271
4183 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4184 * and obsoletes RFC 6472.
4185 */
4186 if (peer->bgp->reject_as_sets)
4187 if (aspath_check_as_sets(attr->aspath)) {
4188 reason =
4189 "as-path contains AS_SET or AS_CONFED_SET type;";
4190 goto filtered;
4191 }
4192
4193 new_attr = *attr;
4194
4195 /* Apply incoming route-map.
4196 * NB: new_attr may now contain newly allocated values from route-map
4197 * "set"
4198 * commands, so we need bgp_attr_flush in the error paths, until we
4199 * intern
4200 * the attr (which takes over the memory references) */
4201 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4202 num_labels, dest)
4203 == RMAP_DENY) {
4204 peer->stat_pfx_filter++;
4205 reason = "route-map;";
4206 bgp_attr_flush(&new_attr);
4207 goto filtered;
4208 }
4209
4210 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4211 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4212 /* remove from RIB previous entry */
4213 bgp_zebra_withdraw(p, pi, bgp, safi);
4214 }
4215
4216 if (peer->sort == BGP_PEER_EBGP) {
4217
4218 /* rfc7999:
4219 * A BGP speaker receiving an announcement tagged with the
4220 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4221 * NO_EXPORT community as defined in RFC1997, or a
4222 * similar community, to prevent propagation of the
4223 * prefix outside the local AS. The community to prevent
4224 * propagation SHOULD be chosen according to the operator's
4225 * routing policy.
4226 */
4227 if (bgp_attr_get_community(&new_attr) &&
4228 community_include(bgp_attr_get_community(&new_attr),
4229 COMMUNITY_BLACKHOLE))
4230 bgp_attr_add_no_export_community(&new_attr);
4231
4232 /* If we receive the graceful-shutdown community from an eBGP
4233 * peer we must lower local-preference */
4234 if (bgp_attr_get_community(&new_attr) &&
4235 community_include(bgp_attr_get_community(&new_attr),
4236 COMMUNITY_GSHUT)) {
4237 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4238 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4239
4240 /* If graceful-shutdown is configured globally or
4241 * per neighbor, then add the GSHUT community to
4242 * all paths received from eBGP peers. */
4243 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4244 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4245 bgp_attr_add_gshut_community(&new_attr);
4246 }
4247
4248 /* next hop check. */
4249 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4250 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4251 &new_attr, dest)) {
4252 peer->stat_pfx_nh_invalid++;
4253 reason = "martian or self next-hop;";
4254 bgp_attr_flush(&new_attr);
4255 goto filtered;
4256 }
4257
4258 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4259 peer->stat_pfx_nh_invalid++;
4260 reason = "self mac;";
4261 bgp_attr_flush(&new_attr);
4262 goto filtered;
4263 }
4264
4265 if (bgp_check_role_applicability(afi, safi) &&
4266 bgp_otc_filter(peer, &new_attr)) {
4267 reason = "failing otc validation";
4268 bgp_attr_flush(&new_attr);
4269 goto filtered;
4270 }
4271 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4272 * condition :
4273 * Suppress fib is enabled
4274 * BGP_OPT_NO_FIB is not enabled
4275 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4276 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4277 */
4278 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4279 && (sub_type == BGP_ROUTE_NORMAL)
4280 && (!bgp_option_check(BGP_OPT_NO_FIB))
4281 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4282 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
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 THREAD_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 thread *t)
5059 {
5060 struct peer_af *paf;
5061 struct peer *peer;
5062
5063 paf = THREAD_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 thread_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 thread *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 = THREAD_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 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5267 table, 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 THREAD_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 thread_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 if (aggregate->community)
8360 community_free(&aggregate->community);
8361
8362 hash_clean_and_free(&aggregate->community_hash,
8363 bgp_aggr_community_remove);
8364
8365 if (aggregate->ecommunity)
8366 ecommunity_free(&aggregate->ecommunity);
8367
8368 hash_clean_and_free(&aggregate->ecommunity_hash,
8369 bgp_aggr_ecommunity_remove);
8370
8371 if (aggregate->lcommunity)
8372 lcommunity_free(&aggregate->lcommunity);
8373
8374 hash_clean_and_free(&aggregate->lcommunity_hash,
8375 bgp_aggr_lcommunity_remove);
8376
8377 if (aggregate->aspath)
8378 aspath_free(aggregate->aspath);
8379
8380 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8381
8382 bgp_aggregate_free(aggregate);
8383 bgp_dest_unlock_node(dest);
8384 bgp_dest_unlock_node(dest);
8385
8386 return CMD_SUCCESS;
8387 }
8388
8389 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8390 safi_t safi, const char *rmap,
8391 uint8_t summary_only, uint8_t as_set,
8392 uint8_t origin, bool match_med,
8393 const char *suppress_map)
8394 {
8395 VTY_DECLVAR_CONTEXT(bgp, bgp);
8396 int ret;
8397 struct prefix p;
8398 struct bgp_dest *dest;
8399 struct bgp_aggregate *aggregate;
8400 uint8_t as_set_new = as_set;
8401
8402 if (suppress_map && summary_only) {
8403 vty_out(vty,
8404 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8405 return CMD_WARNING_CONFIG_FAILED;
8406 }
8407
8408 /* Convert string to prefix structure. */
8409 ret = str2prefix(prefix_str, &p);
8410 if (!ret) {
8411 vty_out(vty, "Malformed prefix\n");
8412 return CMD_WARNING_CONFIG_FAILED;
8413 }
8414 apply_mask(&p);
8415
8416 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8417 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8418 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8419 prefix_str);
8420 return CMD_WARNING_CONFIG_FAILED;
8421 }
8422
8423 /* Old configuration check. */
8424 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8425 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8426
8427 if (aggregate) {
8428 vty_out(vty, "There is already same aggregate network.\n");
8429 /* try to remove the old entry */
8430 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8431 if (ret) {
8432 vty_out(vty, "Error deleting aggregate.\n");
8433 bgp_dest_unlock_node(dest);
8434 return CMD_WARNING_CONFIG_FAILED;
8435 }
8436 }
8437
8438 /* Make aggregate address structure. */
8439 aggregate = bgp_aggregate_new();
8440 aggregate->summary_only = summary_only;
8441 aggregate->match_med = match_med;
8442
8443 /* Network operators MUST NOT locally generate any new
8444 * announcements containing AS_SET or AS_CONFED_SET. If they have
8445 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8446 * SHOULD withdraw those routes and re-announce routes for the
8447 * aggregate or component prefixes (i.e., the more-specific routes
8448 * subsumed by the previously aggregated route) without AS_SET
8449 * or AS_CONFED_SET in the updates.
8450 */
8451 if (bgp->reject_as_sets) {
8452 if (as_set == AGGREGATE_AS_SET) {
8453 as_set_new = AGGREGATE_AS_UNSET;
8454 zlog_warn(
8455 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8456 __func__);
8457 vty_out(vty,
8458 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8459 }
8460 }
8461
8462 aggregate->as_set = as_set_new;
8463 aggregate->safi = safi;
8464 /* Override ORIGIN attribute if defined.
8465 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8466 * to IGP which is not what rfc4271 says.
8467 * This enables the same behavior, optionally.
8468 */
8469 aggregate->origin = origin;
8470
8471 if (rmap) {
8472 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8473 route_map_counter_decrement(aggregate->rmap.map);
8474 aggregate->rmap.name =
8475 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8476 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8477 route_map_counter_increment(aggregate->rmap.map);
8478 }
8479
8480 if (suppress_map) {
8481 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8482 route_map_counter_decrement(aggregate->suppress_map);
8483
8484 aggregate->suppress_map_name =
8485 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8486 aggregate->suppress_map =
8487 route_map_lookup_by_name(aggregate->suppress_map_name);
8488 route_map_counter_increment(aggregate->suppress_map);
8489 }
8490
8491 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8492
8493 /* Aggregate address insert into BGP routing table. */
8494 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8495 bgp_aggregate_free(aggregate);
8496 bgp_dest_unlock_node(dest);
8497 }
8498
8499 return CMD_SUCCESS;
8500 }
8501
8502 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8503 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8504 "as-set$as_set_s"
8505 "|summary-only$summary_only"
8506 "|route-map RMAP_NAME$rmap_name"
8507 "|origin <egp|igp|incomplete>$origin_s"
8508 "|matching-MED-only$match_med"
8509 "|suppress-map RMAP_NAME$suppress_map"
8510 "}]",
8511 NO_STR
8512 "Configure BGP aggregate entries\n"
8513 "Aggregate prefix\n"
8514 "Aggregate address\n"
8515 "Aggregate mask\n"
8516 "Generate AS set path information\n"
8517 "Filter more specific routes from updates\n"
8518 "Apply route map to aggregate network\n"
8519 "Route map name\n"
8520 "BGP origin code\n"
8521 "Remote EGP\n"
8522 "Local IGP\n"
8523 "Unknown heritage\n"
8524 "Only aggregate routes with matching MED\n"
8525 "Suppress the selected more specific routes\n"
8526 "Route map with the route selectors\n")
8527 {
8528 const char *prefix_s = NULL;
8529 safi_t safi = bgp_node_safi(vty);
8530 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8531 int as_set = AGGREGATE_AS_UNSET;
8532 char prefix_buf[PREFIX2STR_BUFFER];
8533
8534 if (addr_str) {
8535 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8536 sizeof(prefix_buf))
8537 == 0) {
8538 vty_out(vty, "%% Inconsistent address and mask\n");
8539 return CMD_WARNING_CONFIG_FAILED;
8540 }
8541 prefix_s = prefix_buf;
8542 } else
8543 prefix_s = prefix_str;
8544
8545 if (origin_s) {
8546 if (strcmp(origin_s, "egp") == 0)
8547 origin = BGP_ORIGIN_EGP;
8548 else if (strcmp(origin_s, "igp") == 0)
8549 origin = BGP_ORIGIN_IGP;
8550 else if (strcmp(origin_s, "incomplete") == 0)
8551 origin = BGP_ORIGIN_INCOMPLETE;
8552 }
8553
8554 if (as_set_s)
8555 as_set = AGGREGATE_AS_SET;
8556
8557 /* Handle configuration removal, otherwise installation. */
8558 if (no)
8559 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8560
8561 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8562 summary_only != NULL, as_set, origin,
8563 match_med != NULL, suppress_map);
8564 }
8565
8566 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8567 "[no] aggregate-address X:X::X:X/M$prefix [{"
8568 "as-set$as_set_s"
8569 "|summary-only$summary_only"
8570 "|route-map RMAP_NAME$rmap_name"
8571 "|origin <egp|igp|incomplete>$origin_s"
8572 "|matching-MED-only$match_med"
8573 "|suppress-map RMAP_NAME$suppress_map"
8574 "}]",
8575 NO_STR
8576 "Configure BGP aggregate entries\n"
8577 "Aggregate prefix\n"
8578 "Generate AS set path information\n"
8579 "Filter more specific routes from updates\n"
8580 "Apply route map to aggregate network\n"
8581 "Route map name\n"
8582 "BGP origin code\n"
8583 "Remote EGP\n"
8584 "Local IGP\n"
8585 "Unknown heritage\n"
8586 "Only aggregate routes with matching MED\n"
8587 "Suppress the selected more specific routes\n"
8588 "Route map with the route selectors\n")
8589 {
8590 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8591 int as_set = AGGREGATE_AS_UNSET;
8592
8593 if (origin_s) {
8594 if (strcmp(origin_s, "egp") == 0)
8595 origin = BGP_ORIGIN_EGP;
8596 else if (strcmp(origin_s, "igp") == 0)
8597 origin = BGP_ORIGIN_IGP;
8598 else if (strcmp(origin_s, "incomplete") == 0)
8599 origin = BGP_ORIGIN_INCOMPLETE;
8600 }
8601
8602 if (as_set_s)
8603 as_set = AGGREGATE_AS_SET;
8604
8605 /* Handle configuration removal, otherwise installation. */
8606 if (no)
8607 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8608 SAFI_UNICAST);
8609
8610 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8611 rmap_name, summary_only != NULL, as_set,
8612 origin, match_med != NULL, suppress_map);
8613 }
8614
8615 /* Redistribute route treatment. */
8616 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8617 const union g_addr *nexthop, ifindex_t ifindex,
8618 enum nexthop_types_t nhtype, uint8_t distance,
8619 enum blackhole_type bhtype, uint32_t metric,
8620 uint8_t type, unsigned short instance,
8621 route_tag_t tag)
8622 {
8623 struct bgp_path_info *new;
8624 struct bgp_path_info *bpi;
8625 struct bgp_path_info rmap_path;
8626 struct bgp_dest *bn;
8627 struct attr attr;
8628 struct attr *new_attr;
8629 afi_t afi;
8630 route_map_result_t ret;
8631 struct bgp_redist *red;
8632
8633 /* Make default attribute. */
8634 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8635 /*
8636 * This must not be NULL to satisfy Coverity SA
8637 */
8638 assert(attr.aspath);
8639
8640 switch (nhtype) {
8641 case NEXTHOP_TYPE_IFINDEX:
8642 switch (p->family) {
8643 case AF_INET:
8644 attr.nexthop.s_addr = INADDR_ANY;
8645 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8646 break;
8647 case AF_INET6:
8648 memset(&attr.mp_nexthop_global, 0,
8649 sizeof(attr.mp_nexthop_global));
8650 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8651 break;
8652 }
8653 break;
8654 case NEXTHOP_TYPE_IPV4:
8655 case NEXTHOP_TYPE_IPV4_IFINDEX:
8656 attr.nexthop = nexthop->ipv4;
8657 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8658 break;
8659 case NEXTHOP_TYPE_IPV6:
8660 case NEXTHOP_TYPE_IPV6_IFINDEX:
8661 attr.mp_nexthop_global = nexthop->ipv6;
8662 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8663 break;
8664 case NEXTHOP_TYPE_BLACKHOLE:
8665 switch (p->family) {
8666 case AF_INET:
8667 attr.nexthop.s_addr = INADDR_ANY;
8668 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8669 break;
8670 case AF_INET6:
8671 memset(&attr.mp_nexthop_global, 0,
8672 sizeof(attr.mp_nexthop_global));
8673 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8674 break;
8675 }
8676 attr.bh_type = bhtype;
8677 break;
8678 }
8679 attr.nh_type = nhtype;
8680 attr.nh_ifindex = ifindex;
8681
8682 attr.med = metric;
8683 attr.distance = distance;
8684 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8685 attr.tag = tag;
8686
8687 if (metric)
8688 bgp_attr_set_aigp_metric(&attr, metric);
8689
8690 afi = family2afi(p->family);
8691
8692 red = bgp_redist_lookup(bgp, afi, type, instance);
8693 if (red) {
8694 struct attr attr_new;
8695
8696 /* Copy attribute for modification. */
8697 attr_new = attr;
8698
8699 if (red->redist_metric_flag) {
8700 attr_new.med = red->redist_metric;
8701 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8702 }
8703
8704 /* Apply route-map. */
8705 if (red->rmap.name) {
8706 memset(&rmap_path, 0, sizeof(rmap_path));
8707 rmap_path.peer = bgp->peer_self;
8708 rmap_path.attr = &attr_new;
8709
8710 SET_FLAG(bgp->peer_self->rmap_type,
8711 PEER_RMAP_TYPE_REDISTRIBUTE);
8712
8713 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8714
8715 bgp->peer_self->rmap_type = 0;
8716
8717 if (ret == RMAP_DENYMATCH) {
8718 /* Free uninterned attribute. */
8719 bgp_attr_flush(&attr_new);
8720
8721 /* Unintern original. */
8722 aspath_unintern(&attr.aspath);
8723 bgp_redistribute_delete(bgp, p, type, instance);
8724 return;
8725 }
8726 }
8727
8728 if (bgp_in_graceful_shutdown(bgp))
8729 bgp_attr_add_gshut_community(&attr_new);
8730
8731 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8732 SAFI_UNICAST, p, NULL);
8733
8734 new_attr = bgp_attr_intern(&attr_new);
8735
8736 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8737 if (bpi->peer == bgp->peer_self
8738 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8739 break;
8740
8741 if (bpi) {
8742 /* Ensure the (source route) type is updated. */
8743 bpi->type = type;
8744 if (attrhash_cmp(bpi->attr, new_attr)
8745 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8746 bgp_attr_unintern(&new_attr);
8747 aspath_unintern(&attr.aspath);
8748 bgp_dest_unlock_node(bn);
8749 return;
8750 } else {
8751 /* The attribute is changed. */
8752 bgp_path_info_set_flag(bn, bpi,
8753 BGP_PATH_ATTR_CHANGED);
8754
8755 /* Rewrite BGP route information. */
8756 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8757 bgp_path_info_restore(bn, bpi);
8758 else
8759 bgp_aggregate_decrement(
8760 bgp, p, bpi, afi, SAFI_UNICAST);
8761 bgp_attr_unintern(&bpi->attr);
8762 bpi->attr = new_attr;
8763 bpi->uptime = monotime(NULL);
8764
8765 /* Process change. */
8766 bgp_aggregate_increment(bgp, p, bpi, afi,
8767 SAFI_UNICAST);
8768 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8769 bgp_dest_unlock_node(bn);
8770 aspath_unintern(&attr.aspath);
8771
8772 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8773 || (bgp->inst_type
8774 == BGP_INSTANCE_TYPE_DEFAULT)) {
8775
8776 vpn_leak_from_vrf_update(
8777 bgp_get_default(), bgp, bpi);
8778 }
8779 return;
8780 }
8781 }
8782
8783 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8784 bgp->peer_self, new_attr, bn);
8785 SET_FLAG(new->flags, BGP_PATH_VALID);
8786
8787 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8788 bgp_path_info_add(bn, new);
8789 bgp_dest_unlock_node(bn);
8790 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8791 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8792
8793 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8794 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8795
8796 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8797 }
8798 }
8799
8800 /* Unintern original. */
8801 aspath_unintern(&attr.aspath);
8802 }
8803
8804 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8805 unsigned short instance)
8806 {
8807 afi_t afi;
8808 struct bgp_dest *dest;
8809 struct bgp_path_info *pi;
8810 struct bgp_redist *red;
8811
8812 afi = family2afi(p->family);
8813
8814 red = bgp_redist_lookup(bgp, afi, type, instance);
8815 if (red) {
8816 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8817 SAFI_UNICAST, p, NULL);
8818
8819 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8820 if (pi->peer == bgp->peer_self && pi->type == type)
8821 break;
8822
8823 if (pi) {
8824 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8825 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8826
8827 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8828 bgp, pi);
8829 }
8830 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8831 bgp_path_info_delete(dest, pi);
8832 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8833 }
8834 bgp_dest_unlock_node(dest);
8835 }
8836 }
8837
8838 /* Withdraw specified route type's route. */
8839 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8840 unsigned short instance)
8841 {
8842 struct bgp_dest *dest;
8843 struct bgp_path_info *pi;
8844 struct bgp_table *table;
8845
8846 table = bgp->rib[afi][SAFI_UNICAST];
8847
8848 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8849 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8850 if (pi->peer == bgp->peer_self && pi->type == type
8851 && pi->instance == instance)
8852 break;
8853
8854 if (pi) {
8855 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8856 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8857
8858 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8859 bgp, pi);
8860 }
8861 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8862 pi, afi, SAFI_UNICAST);
8863 bgp_path_info_delete(dest, pi);
8864 if (!CHECK_FLAG(bgp->flags,
8865 BGP_FLAG_DELETE_IN_PROGRESS))
8866 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8867 else
8868 bgp_path_info_reap(dest, pi);
8869 }
8870 }
8871 }
8872
8873 /* Static function to display route. */
8874 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8875 struct vty *vty, json_object *json, bool wide)
8876 {
8877 int len = 0;
8878 char buf[INET6_ADDRSTRLEN];
8879
8880 if (p->family == AF_INET) {
8881 if (!json) {
8882 len = vty_out(vty, "%pFX", p);
8883 } else {
8884 json_object_string_add(json, "prefix",
8885 inet_ntop(p->family,
8886 &p->u.prefix, buf,
8887 sizeof(buf)));
8888 json_object_int_add(json, "prefixLen", p->prefixlen);
8889 json_object_string_addf(json, "network", "%pFX", p);
8890 json_object_int_add(json, "version", dest->version);
8891 }
8892 } else if (p->family == AF_ETHERNET) {
8893 len = vty_out(vty, "%pFX", p);
8894 } else if (p->family == AF_EVPN) {
8895 if (!json)
8896 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8897 else
8898 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8899 } else if (p->family == AF_FLOWSPEC) {
8900 route_vty_out_flowspec(vty, p, NULL,
8901 json ?
8902 NLRI_STRING_FORMAT_JSON_SIMPLE :
8903 NLRI_STRING_FORMAT_MIN, json);
8904 } else {
8905 if (!json)
8906 len = vty_out(vty, "%pFX", p);
8907 else {
8908 json_object_string_add(json, "prefix",
8909 inet_ntop(p->family,
8910 &p->u.prefix, buf,
8911 sizeof(buf)));
8912 json_object_int_add(json, "prefixLen", p->prefixlen);
8913 json_object_string_addf(json, "network", "%pFX", p);
8914 json_object_int_add(json, "version", dest->version);
8915 }
8916 }
8917
8918 if (!json) {
8919 len = wide ? (45 - len) : (17 - len);
8920 if (len < 1)
8921 vty_out(vty, "\n%*s", 20, " ");
8922 else
8923 vty_out(vty, "%*s", len, " ");
8924 }
8925 }
8926
8927 enum bgp_display_type {
8928 normal_list,
8929 };
8930
8931 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8932 {
8933 switch (reason) {
8934 case bgp_path_selection_none:
8935 return "Nothing to Select";
8936 case bgp_path_selection_first:
8937 return "First path received";
8938 case bgp_path_selection_evpn_sticky_mac:
8939 return "EVPN Sticky Mac";
8940 case bgp_path_selection_evpn_seq:
8941 return "EVPN sequence number";
8942 case bgp_path_selection_evpn_lower_ip:
8943 return "EVPN lower IP";
8944 case bgp_path_selection_evpn_local_path:
8945 return "EVPN local ES path";
8946 case bgp_path_selection_evpn_non_proxy:
8947 return "EVPN non proxy";
8948 case bgp_path_selection_weight:
8949 return "Weight";
8950 case bgp_path_selection_local_pref:
8951 return "Local Pref";
8952 case bgp_path_selection_accept_own:
8953 return "Accept Own";
8954 case bgp_path_selection_local_route:
8955 return "Local Route";
8956 case bgp_path_selection_aigp:
8957 return "AIGP";
8958 case bgp_path_selection_confed_as_path:
8959 return "Confederation based AS Path";
8960 case bgp_path_selection_as_path:
8961 return "AS Path";
8962 case bgp_path_selection_origin:
8963 return "Origin";
8964 case bgp_path_selection_med:
8965 return "MED";
8966 case bgp_path_selection_peer:
8967 return "Peer Type";
8968 case bgp_path_selection_confed:
8969 return "Confed Peer Type";
8970 case bgp_path_selection_igp_metric:
8971 return "IGP Metric";
8972 case bgp_path_selection_older:
8973 return "Older Path";
8974 case bgp_path_selection_router_id:
8975 return "Router ID";
8976 case bgp_path_selection_cluster_length:
8977 return "Cluster length";
8978 case bgp_path_selection_stale:
8979 return "Path Staleness";
8980 case bgp_path_selection_local_configured:
8981 return "Locally configured route";
8982 case bgp_path_selection_neighbor_ip:
8983 return "Neighbor IP";
8984 case bgp_path_selection_default:
8985 return "Nothing left to compare";
8986 }
8987 return "Invalid (internal error)";
8988 }
8989
8990 /* Print the short form route status for a bgp_path_info */
8991 static void route_vty_short_status_out(struct vty *vty,
8992 struct bgp_path_info *path,
8993 const struct prefix *p,
8994 json_object *json_path)
8995 {
8996 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8997
8998 if (json_path) {
8999
9000 /* Route status display. */
9001 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9002 json_object_boolean_true_add(json_path, "removed");
9003
9004 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9005 json_object_boolean_true_add(json_path, "stale");
9006
9007 if (path->extra && bgp_path_suppressed(path))
9008 json_object_boolean_true_add(json_path, "suppressed");
9009
9010 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9011 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9012 json_object_boolean_true_add(json_path, "valid");
9013
9014 /* Selected */
9015 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9016 json_object_boolean_true_add(json_path, "history");
9017
9018 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9019 json_object_boolean_true_add(json_path, "damped");
9020
9021 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9022 json_object_boolean_true_add(json_path, "bestpath");
9023 json_object_string_add(json_path, "selectionReason",
9024 bgp_path_selection_reason2str(
9025 path->net->reason));
9026 }
9027
9028 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9029 json_object_boolean_true_add(json_path, "multipath");
9030
9031 /* Internal route. */
9032 if ((path->peer->as)
9033 && (path->peer->as == path->peer->local_as))
9034 json_object_string_add(json_path, "pathFrom",
9035 "internal");
9036 else
9037 json_object_string_add(json_path, "pathFrom",
9038 "external");
9039
9040 return;
9041 }
9042
9043 /* RPKI validation state */
9044 rpki_state =
9045 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9046
9047 if (rpki_state == RPKI_VALID)
9048 vty_out(vty, "V");
9049 else if (rpki_state == RPKI_INVALID)
9050 vty_out(vty, "I");
9051 else if (rpki_state == RPKI_NOTFOUND)
9052 vty_out(vty, "N");
9053 else
9054 vty_out(vty, " ");
9055
9056 /* Route status display. */
9057 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9058 vty_out(vty, "R");
9059 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9060 vty_out(vty, "S");
9061 else if (bgp_path_suppressed(path))
9062 vty_out(vty, "s");
9063 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9064 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9065 vty_out(vty, "*");
9066 else
9067 vty_out(vty, " ");
9068
9069 /* Selected */
9070 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9071 vty_out(vty, "h");
9072 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9073 vty_out(vty, "d");
9074 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9075 vty_out(vty, ">");
9076 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9077 vty_out(vty, "=");
9078 else
9079 vty_out(vty, " ");
9080
9081 /* Internal route. */
9082 if (path->peer && (path->peer->as)
9083 && (path->peer->as == path->peer->local_as))
9084 vty_out(vty, "i");
9085 else
9086 vty_out(vty, " ");
9087 }
9088
9089 static char *bgp_nexthop_hostname(struct peer *peer,
9090 struct bgp_nexthop_cache *bnc)
9091 {
9092 if (peer->hostname
9093 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9094 return peer->hostname;
9095 return NULL;
9096 }
9097
9098 /* called from terminal list command */
9099 void route_vty_out(struct vty *vty, const struct prefix *p,
9100 struct bgp_path_info *path, int display, safi_t safi,
9101 json_object *json_paths, bool wide)
9102 {
9103 int len;
9104 struct attr *attr = path->attr;
9105 json_object *json_path = NULL;
9106 json_object *json_nexthops = NULL;
9107 json_object *json_nexthop_global = NULL;
9108 json_object *json_nexthop_ll = NULL;
9109 json_object *json_ext_community = NULL;
9110 char vrf_id_str[VRF_NAMSIZ] = {0};
9111 bool nexthop_self =
9112 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9113 bool nexthop_othervrf = false;
9114 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9115 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9116 char *nexthop_hostname =
9117 bgp_nexthop_hostname(path->peer, path->nexthop);
9118 char esi_buf[ESI_STR_LEN];
9119
9120 if (json_paths)
9121 json_path = json_object_new_object();
9122
9123 /* short status lead text */
9124 route_vty_short_status_out(vty, path, p, json_path);
9125
9126 if (!json_paths) {
9127 /* print prefix and mask */
9128 if (!display)
9129 route_vty_out_route(path->net, p, vty, json_path, wide);
9130 else
9131 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9132 } else {
9133 route_vty_out_route(path->net, p, vty, json_path, wide);
9134 }
9135
9136 /*
9137 * If vrf id of nexthop is different from that of prefix,
9138 * set up printable string to append
9139 */
9140 if (path->extra && path->extra->bgp_orig) {
9141 const char *self = "";
9142
9143 if (nexthop_self)
9144 self = "<";
9145
9146 nexthop_othervrf = true;
9147 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9148
9149 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9150 snprintf(vrf_id_str, sizeof(vrf_id_str),
9151 "@%s%s", VRFID_NONE_STR, self);
9152 else
9153 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9154 path->extra->bgp_orig->vrf_id, self);
9155
9156 if (path->extra->bgp_orig->inst_type
9157 != BGP_INSTANCE_TYPE_DEFAULT)
9158
9159 nexthop_vrfname = path->extra->bgp_orig->name;
9160 } else {
9161 const char *self = "";
9162
9163 if (nexthop_self)
9164 self = "<";
9165
9166 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9167 }
9168
9169 /*
9170 * For ENCAP and EVPN routes, nexthop address family is not
9171 * neccessarily the same as the prefix address family.
9172 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9173 * EVPN routes are also exchanged with a MP nexthop. Currently,
9174 * this
9175 * is only IPv4, the value will be present in either
9176 * attr->nexthop or
9177 * attr->mp_nexthop_global_in
9178 */
9179 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9180 char nexthop[128];
9181 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9182
9183 switch (af) {
9184 case AF_INET:
9185 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9186 &attr->mp_nexthop_global_in);
9187 break;
9188 case AF_INET6:
9189 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9190 &attr->mp_nexthop_global);
9191 break;
9192 default:
9193 snprintf(nexthop, sizeof(nexthop), "?");
9194 break;
9195 }
9196
9197 if (json_paths) {
9198 json_nexthop_global = json_object_new_object();
9199
9200 json_object_string_add(json_nexthop_global, "ip",
9201 nexthop);
9202
9203 if (path->peer->hostname)
9204 json_object_string_add(json_nexthop_global,
9205 "hostname",
9206 path->peer->hostname);
9207
9208 json_object_string_add(json_nexthop_global, "afi",
9209 (af == AF_INET) ? "ipv4"
9210 : "ipv6");
9211 json_object_boolean_true_add(json_nexthop_global,
9212 "used");
9213 } else {
9214 if (nexthop_hostname)
9215 len = vty_out(vty, "%s(%s)%s", nexthop,
9216 nexthop_hostname, vrf_id_str);
9217 else
9218 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9219
9220 len = wide ? (41 - len) : (16 - len);
9221 if (len < 1)
9222 vty_out(vty, "\n%*s", 36, " ");
9223 else
9224 vty_out(vty, "%*s", len, " ");
9225 }
9226 } else if (safi == SAFI_EVPN) {
9227 if (json_paths) {
9228 json_nexthop_global = json_object_new_object();
9229
9230 json_object_string_addf(json_nexthop_global, "ip",
9231 "%pI4",
9232 &attr->mp_nexthop_global_in);
9233
9234 if (path->peer->hostname)
9235 json_object_string_add(json_nexthop_global,
9236 "hostname",
9237 path->peer->hostname);
9238
9239 json_object_string_add(json_nexthop_global, "afi",
9240 "ipv4");
9241 json_object_boolean_true_add(json_nexthop_global,
9242 "used");
9243 } else {
9244 if (nexthop_hostname)
9245 len = vty_out(vty, "%pI4(%s)%s",
9246 &attr->mp_nexthop_global_in,
9247 nexthop_hostname, vrf_id_str);
9248 else
9249 len = vty_out(vty, "%pI4%s",
9250 &attr->mp_nexthop_global_in,
9251 vrf_id_str);
9252
9253 len = wide ? (41 - len) : (16 - len);
9254 if (len < 1)
9255 vty_out(vty, "\n%*s", 36, " ");
9256 else
9257 vty_out(vty, "%*s", len, " ");
9258 }
9259 } else if (safi == SAFI_FLOWSPEC) {
9260 if (attr->nexthop.s_addr != INADDR_ANY) {
9261 if (json_paths) {
9262 json_nexthop_global = json_object_new_object();
9263
9264 json_object_string_add(json_nexthop_global,
9265 "afi", "ipv4");
9266 json_object_string_addf(json_nexthop_global,
9267 "ip", "%pI4",
9268 &attr->nexthop);
9269
9270 if (path->peer->hostname)
9271 json_object_string_add(
9272 json_nexthop_global, "hostname",
9273 path->peer->hostname);
9274
9275 json_object_boolean_true_add(
9276 json_nexthop_global,
9277 "used");
9278 } else {
9279 if (nexthop_hostname)
9280 len = vty_out(vty, "%pI4(%s)%s",
9281 &attr->nexthop,
9282 nexthop_hostname,
9283 vrf_id_str);
9284 else
9285 len = vty_out(vty, "%pI4%s",
9286 &attr->nexthop,
9287 vrf_id_str);
9288
9289 len = wide ? (41 - len) : (16 - len);
9290 if (len < 1)
9291 vty_out(vty, "\n%*s", 36, " ");
9292 else
9293 vty_out(vty, "%*s", len, " ");
9294 }
9295 }
9296 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9297 if (json_paths) {
9298 json_nexthop_global = json_object_new_object();
9299
9300 json_object_string_addf(json_nexthop_global, "ip",
9301 "%pI4", &attr->nexthop);
9302
9303 if (path->peer->hostname)
9304 json_object_string_add(json_nexthop_global,
9305 "hostname",
9306 path->peer->hostname);
9307
9308 json_object_string_add(json_nexthop_global, "afi",
9309 "ipv4");
9310 json_object_boolean_true_add(json_nexthop_global,
9311 "used");
9312 } else {
9313 if (nexthop_hostname)
9314 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9315 nexthop_hostname, vrf_id_str);
9316 else
9317 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9318 vrf_id_str);
9319
9320 len = wide ? (41 - len) : (16 - len);
9321 if (len < 1)
9322 vty_out(vty, "\n%*s", 36, " ");
9323 else
9324 vty_out(vty, "%*s", len, " ");
9325 }
9326 }
9327
9328 /* IPv6 Next Hop */
9329 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9330 if (json_paths) {
9331 json_nexthop_global = json_object_new_object();
9332 json_object_string_addf(json_nexthop_global, "ip",
9333 "%pI6",
9334 &attr->mp_nexthop_global);
9335
9336 if (path->peer->hostname)
9337 json_object_string_add(json_nexthop_global,
9338 "hostname",
9339 path->peer->hostname);
9340
9341 json_object_string_add(json_nexthop_global, "afi",
9342 "ipv6");
9343 json_object_string_add(json_nexthop_global, "scope",
9344 "global");
9345
9346 /* We display both LL & GL if both have been
9347 * received */
9348 if ((attr->mp_nexthop_len
9349 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9350 || (path->peer->conf_if)) {
9351 json_nexthop_ll = json_object_new_object();
9352 json_object_string_addf(
9353 json_nexthop_ll, "ip", "%pI6",
9354 &attr->mp_nexthop_local);
9355
9356 if (path->peer->hostname)
9357 json_object_string_add(
9358 json_nexthop_ll, "hostname",
9359 path->peer->hostname);
9360
9361 json_object_string_add(json_nexthop_ll, "afi",
9362 "ipv6");
9363 json_object_string_add(json_nexthop_ll, "scope",
9364 "link-local");
9365
9366 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9367 &attr->mp_nexthop_local)
9368 != 0)
9369 && !attr->mp_nexthop_prefer_global)
9370 json_object_boolean_true_add(
9371 json_nexthop_ll, "used");
9372 else
9373 json_object_boolean_true_add(
9374 json_nexthop_global, "used");
9375 } else
9376 json_object_boolean_true_add(
9377 json_nexthop_global, "used");
9378 } else {
9379 /* Display LL if LL/Global both in table unless
9380 * prefer-global is set */
9381 if (((attr->mp_nexthop_len
9382 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9383 && !attr->mp_nexthop_prefer_global)
9384 || (path->peer->conf_if)) {
9385 if (path->peer->conf_if) {
9386 len = vty_out(vty, "%s",
9387 path->peer->conf_if);
9388 /* len of IPv6 addr + max len of def
9389 * ifname */
9390 len = wide ? (41 - len) : (16 - len);
9391
9392 if (len < 1)
9393 vty_out(vty, "\n%*s", 36, " ");
9394 else
9395 vty_out(vty, "%*s", len, " ");
9396 } else {
9397 if (nexthop_hostname)
9398 len = vty_out(
9399 vty, "%pI6(%s)%s",
9400 &attr->mp_nexthop_local,
9401 nexthop_hostname,
9402 vrf_id_str);
9403 else
9404 len = vty_out(
9405 vty, "%pI6%s",
9406 &attr->mp_nexthop_local,
9407 vrf_id_str);
9408
9409 len = wide ? (41 - len) : (16 - len);
9410
9411 if (len < 1)
9412 vty_out(vty, "\n%*s", 36, " ");
9413 else
9414 vty_out(vty, "%*s", len, " ");
9415 }
9416 } else {
9417 if (nexthop_hostname)
9418 len = vty_out(vty, "%pI6(%s)%s",
9419 &attr->mp_nexthop_global,
9420 nexthop_hostname,
9421 vrf_id_str);
9422 else
9423 len = vty_out(vty, "%pI6%s",
9424 &attr->mp_nexthop_global,
9425 vrf_id_str);
9426
9427 len = wide ? (41 - len) : (16 - len);
9428
9429 if (len < 1)
9430 vty_out(vty, "\n%*s", 36, " ");
9431 else
9432 vty_out(vty, "%*s", len, " ");
9433 }
9434 }
9435 }
9436
9437 /* MED/Metric */
9438 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9439 if (json_paths)
9440 json_object_int_add(json_path, "metric", attr->med);
9441 else if (wide)
9442 vty_out(vty, "%7u", attr->med);
9443 else
9444 vty_out(vty, "%10u", attr->med);
9445 else if (!json_paths) {
9446 if (wide)
9447 vty_out(vty, "%*s", 7, " ");
9448 else
9449 vty_out(vty, "%*s", 10, " ");
9450 }
9451
9452 /* Local Pref */
9453 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9454 if (json_paths)
9455 json_object_int_add(json_path, "locPrf",
9456 attr->local_pref);
9457 else
9458 vty_out(vty, "%7u", attr->local_pref);
9459 else if (!json_paths)
9460 vty_out(vty, " ");
9461
9462 if (json_paths)
9463 json_object_int_add(json_path, "weight", attr->weight);
9464 else
9465 vty_out(vty, "%7u ", attr->weight);
9466
9467 if (json_paths)
9468 json_object_string_addf(json_path, "peerId", "%pSU",
9469 &path->peer->su);
9470
9471 /* Print aspath */
9472 if (attr->aspath) {
9473 if (json_paths)
9474 json_object_string_add(json_path, "path",
9475 attr->aspath->str);
9476 else
9477 aspath_print_vty(vty, attr->aspath);
9478 }
9479
9480 /* Print origin */
9481 if (json_paths)
9482 json_object_string_add(json_path, "origin",
9483 bgp_origin_long_str[attr->origin]);
9484 else
9485 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9486
9487 if (json_paths) {
9488 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9489 json_object_string_add(json_path, "esi",
9490 esi_to_str(&attr->esi,
9491 esi_buf, sizeof(esi_buf)));
9492 }
9493 if (safi == SAFI_EVPN &&
9494 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9495 json_ext_community = json_object_new_object();
9496 json_object_string_add(
9497 json_ext_community, "string",
9498 bgp_attr_get_ecommunity(attr)->str);
9499 json_object_object_add(json_path,
9500 "extendedCommunity",
9501 json_ext_community);
9502 }
9503
9504 if (nexthop_self)
9505 json_object_boolean_true_add(json_path,
9506 "announceNexthopSelf");
9507 if (nexthop_othervrf) {
9508 json_object_string_add(json_path, "nhVrfName",
9509 nexthop_vrfname);
9510
9511 json_object_int_add(json_path, "nhVrfId",
9512 ((nexthop_vrfid == VRF_UNKNOWN)
9513 ? -1
9514 : (int)nexthop_vrfid));
9515 }
9516 }
9517
9518 if (json_paths) {
9519 if (json_nexthop_global || json_nexthop_ll) {
9520 json_nexthops = json_object_new_array();
9521
9522 if (json_nexthop_global)
9523 json_object_array_add(json_nexthops,
9524 json_nexthop_global);
9525
9526 if (json_nexthop_ll)
9527 json_object_array_add(json_nexthops,
9528 json_nexthop_ll);
9529
9530 json_object_object_add(json_path, "nexthops",
9531 json_nexthops);
9532 }
9533
9534 json_object_array_add(json_paths, json_path);
9535 } else {
9536 vty_out(vty, "\n");
9537
9538 if (safi == SAFI_EVPN) {
9539 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9540 /* XXX - add these params to the json out */
9541 vty_out(vty, "%*s", 20, " ");
9542 vty_out(vty, "ESI:%s",
9543 esi_to_str(&attr->esi, esi_buf,
9544 sizeof(esi_buf)));
9545
9546 vty_out(vty, "\n");
9547 }
9548 if (attr->flag &
9549 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9550 vty_out(vty, "%*s", 20, " ");
9551 vty_out(vty, "%s\n",
9552 bgp_attr_get_ecommunity(attr)->str);
9553 }
9554 }
9555
9556 #ifdef ENABLE_BGP_VNC
9557 /* prints an additional line, indented, with VNC info, if
9558 * present */
9559 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9560 rfapi_vty_out_vncinfo(vty, p, path, safi);
9561 #endif
9562 }
9563 }
9564
9565 /* called from terminal list command */
9566 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9567 const struct prefix *p, struct attr *attr, safi_t safi,
9568 bool use_json, json_object *json_ar, bool wide)
9569 {
9570 json_object *json_status = NULL;
9571 json_object *json_net = NULL;
9572 int len;
9573 char buff[BUFSIZ];
9574
9575 /* Route status display. */
9576 if (use_json) {
9577 json_status = json_object_new_object();
9578 json_net = json_object_new_object();
9579 } else {
9580 vty_out(vty, " *");
9581 vty_out(vty, ">");
9582 vty_out(vty, " ");
9583 }
9584
9585 /* print prefix and mask */
9586 if (use_json) {
9587 if (safi == SAFI_EVPN)
9588 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9589 else if (p->family == AF_INET || p->family == AF_INET6) {
9590 json_object_string_add(
9591 json_net, "addrPrefix",
9592 inet_ntop(p->family, &p->u.prefix, buff,
9593 BUFSIZ));
9594 json_object_int_add(json_net, "prefixLen",
9595 p->prefixlen);
9596 json_object_string_addf(json_net, "network", "%pFX", p);
9597 }
9598 } else
9599 route_vty_out_route(dest, p, vty, NULL, wide);
9600
9601 /* Print attribute */
9602 if (attr) {
9603 if (use_json) {
9604 if (p->family == AF_INET &&
9605 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9606 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9607 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9608 json_object_string_addf(
9609 json_net, "nextHop", "%pI4",
9610 &attr->mp_nexthop_global_in);
9611 else
9612 json_object_string_addf(
9613 json_net, "nextHop", "%pI4",
9614 &attr->nexthop);
9615 } else if (p->family == AF_INET6 ||
9616 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9617 json_object_string_addf(
9618 json_net, "nextHopGlobal", "%pI6",
9619 &attr->mp_nexthop_global);
9620 } else if (p->family == AF_EVPN &&
9621 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9622 json_object_string_addf(
9623 json_net, "nextHop", "%pI4",
9624 &attr->mp_nexthop_global_in);
9625 }
9626
9627 if (attr->flag
9628 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9629 json_object_int_add(json_net, "metric",
9630 attr->med);
9631
9632 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9633 json_object_int_add(json_net, "locPrf",
9634 attr->local_pref);
9635
9636 json_object_int_add(json_net, "weight", attr->weight);
9637
9638 /* Print aspath */
9639 if (attr->aspath)
9640 json_object_string_add(json_net, "path",
9641 attr->aspath->str);
9642
9643 /* Print origin */
9644 #if CONFDATE > 20231208
9645 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9646 #endif
9647 json_object_string_add(json_net, "bgpOriginCode",
9648 bgp_origin_str[attr->origin]);
9649 json_object_string_add(
9650 json_net, "origin",
9651 bgp_origin_long_str[attr->origin]);
9652 } else {
9653 if (p->family == AF_INET &&
9654 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9655 safi == SAFI_EVPN ||
9656 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9657 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9658 || safi == SAFI_EVPN)
9659 vty_out(vty, "%-16pI4",
9660 &attr->mp_nexthop_global_in);
9661 else if (wide)
9662 vty_out(vty, "%-41pI4", &attr->nexthop);
9663 else
9664 vty_out(vty, "%-16pI4", &attr->nexthop);
9665 } else if (p->family == AF_INET6 ||
9666 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9667 len = vty_out(vty, "%pI6",
9668 &attr->mp_nexthop_global);
9669 len = wide ? (41 - len) : (16 - len);
9670 if (len < 1)
9671 vty_out(vty, "\n%*s", 36, " ");
9672 else
9673 vty_out(vty, "%*s", len, " ");
9674 }
9675 if (attr->flag
9676 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9677 if (wide)
9678 vty_out(vty, "%7u", attr->med);
9679 else
9680 vty_out(vty, "%10u", attr->med);
9681 else if (wide)
9682 vty_out(vty, " ");
9683 else
9684 vty_out(vty, " ");
9685
9686 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9687 vty_out(vty, "%7u", attr->local_pref);
9688 else
9689 vty_out(vty, " ");
9690
9691 vty_out(vty, "%7u ", attr->weight);
9692
9693 /* Print aspath */
9694 if (attr->aspath)
9695 aspath_print_vty(vty, attr->aspath);
9696
9697 /* Print origin */
9698 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9699 }
9700 }
9701 if (use_json) {
9702 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9703
9704 #if CONFDATE > 20231208
9705 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9706 #endif
9707 json_object_boolean_true_add(json_status, "*");
9708 json_object_boolean_true_add(json_status, ">");
9709 json_object_boolean_true_add(json_net, "valid");
9710 json_object_boolean_true_add(json_net, "best");
9711
9712 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9713 json_object_boolean_true_add(json_status, "=");
9714 json_object_boolean_true_add(json_net, "multipath");
9715 }
9716 json_object_object_add(json_net, "appliedStatusSymbols",
9717 json_status);
9718 json_object_object_addf(json_ar, json_net, "%pFX", p);
9719 } else
9720 vty_out(vty, "\n");
9721 }
9722
9723 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9724 struct bgp_path_info *path, int display, safi_t safi,
9725 json_object *json)
9726 {
9727 json_object *json_out = NULL;
9728 struct attr *attr;
9729 mpls_label_t label = MPLS_INVALID_LABEL;
9730
9731 if (!path->extra)
9732 return;
9733
9734 if (json)
9735 json_out = json_object_new_object();
9736
9737 /* short status lead text */
9738 route_vty_short_status_out(vty, path, p, json_out);
9739
9740 /* print prefix and mask */
9741 if (json == NULL) {
9742 if (!display)
9743 route_vty_out_route(path->net, p, vty, NULL, false);
9744 else
9745 vty_out(vty, "%*s", 17, " ");
9746 }
9747
9748 /* Print attribute */
9749 attr = path->attr;
9750 if (((p->family == AF_INET) &&
9751 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9752 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9753 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9754 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9755 || safi == SAFI_EVPN) {
9756 if (json)
9757 json_object_string_addf(
9758 json_out, "mpNexthopGlobalIn", "%pI4",
9759 &attr->mp_nexthop_global_in);
9760 else
9761 vty_out(vty, "%-16pI4",
9762 &attr->mp_nexthop_global_in);
9763 } else {
9764 if (json)
9765 json_object_string_addf(json_out, "nexthop",
9766 "%pI4", &attr->nexthop);
9767 else
9768 vty_out(vty, "%-16pI4", &attr->nexthop);
9769 }
9770 } else if (((p->family == AF_INET6) &&
9771 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9772 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9773 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9774 char buf_a[512];
9775
9776 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9777 if (json)
9778 json_object_string_addf(
9779 json_out, "mpNexthopGlobalIn", "%pI6",
9780 &attr->mp_nexthop_global);
9781 else
9782 vty_out(vty, "%s",
9783 inet_ntop(AF_INET6,
9784 &attr->mp_nexthop_global,
9785 buf_a, sizeof(buf_a)));
9786 } else if (attr->mp_nexthop_len
9787 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9788 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9789 &attr->mp_nexthop_global,
9790 &attr->mp_nexthop_local);
9791 if (json)
9792 json_object_string_add(json_out,
9793 "mpNexthopGlobalLocal",
9794 buf_a);
9795 else
9796 vty_out(vty, "%s", buf_a);
9797 }
9798 }
9799
9800 label = decode_label(&path->extra->label[0]);
9801
9802 if (bgp_is_valid_label(&label)) {
9803 if (json) {
9804 json_object_int_add(json_out, "notag", label);
9805 json_object_array_add(json, json_out);
9806 } else {
9807 vty_out(vty, "notag/%d", label);
9808 vty_out(vty, "\n");
9809 }
9810 } else if (!json)
9811 vty_out(vty, "\n");
9812 }
9813
9814 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9815 struct bgp_path_info *path, int display,
9816 json_object *json_paths)
9817 {
9818 struct attr *attr;
9819 json_object *json_path = NULL;
9820 json_object *json_nexthop = NULL;
9821 json_object *json_overlay = NULL;
9822
9823 if (!path->extra)
9824 return;
9825
9826 if (json_paths) {
9827 json_path = json_object_new_object();
9828 json_overlay = json_object_new_object();
9829 json_nexthop = json_object_new_object();
9830 }
9831
9832 /* short status lead text */
9833 route_vty_short_status_out(vty, path, p, json_path);
9834
9835 /* print prefix and mask */
9836 if (!display)
9837 route_vty_out_route(path->net, p, vty, json_path, false);
9838 else
9839 vty_out(vty, "%*s", 17, " ");
9840
9841 /* Print attribute */
9842 attr = path->attr;
9843 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9844
9845 switch (af) {
9846 case AF_INET:
9847 if (!json_path) {
9848 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9849 } else {
9850 json_object_string_addf(json_nexthop, "ip", "%pI4",
9851 &attr->mp_nexthop_global_in);
9852
9853 json_object_string_add(json_nexthop, "afi", "ipv4");
9854
9855 json_object_object_add(json_path, "nexthop",
9856 json_nexthop);
9857 }
9858 break;
9859 case AF_INET6:
9860 if (!json_path) {
9861 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9862 &attr->mp_nexthop_local);
9863 } else {
9864 json_object_string_addf(json_nexthop, "ipv6Global",
9865 "%pI6",
9866 &attr->mp_nexthop_global);
9867
9868 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9869 "%pI6",
9870 &attr->mp_nexthop_local);
9871
9872 json_object_string_add(json_nexthop, "afi", "ipv6");
9873
9874 json_object_object_add(json_path, "nexthop",
9875 json_nexthop);
9876 }
9877 break;
9878 default:
9879 if (!json_path) {
9880 vty_out(vty, "?");
9881 } else {
9882 json_object_string_add(json_nexthop, "error",
9883 "Unsupported address-family");
9884 }
9885 }
9886
9887 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9888
9889 if (!json_path)
9890 vty_out(vty, "/%pIA", &eo->gw_ip);
9891 else
9892 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9893
9894 if (bgp_attr_get_ecommunity(attr)) {
9895 char *mac = NULL;
9896 struct ecommunity_val *routermac = ecommunity_lookup(
9897 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9898 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9899
9900 if (routermac)
9901 mac = ecom_mac2str((char *)routermac->val);
9902 if (mac) {
9903 if (!json_path) {
9904 vty_out(vty, "/%s", mac);
9905 } else {
9906 json_object_string_add(json_overlay, "rmac",
9907 mac);
9908 }
9909 XFREE(MTYPE_TMP, mac);
9910 }
9911 }
9912
9913 if (!json_path) {
9914 vty_out(vty, "\n");
9915 } else {
9916 json_object_object_add(json_path, "overlay", json_overlay);
9917
9918 json_object_array_add(json_paths, json_path);
9919 }
9920 }
9921
9922 /* dampening route */
9923 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9924 struct bgp_path_info *path, int display,
9925 afi_t afi, safi_t safi, bool use_json,
9926 json_object *json_paths)
9927 {
9928 struct attr *attr = path->attr;
9929 int len;
9930 char timebuf[BGP_UPTIME_LEN];
9931 json_object *json_path = NULL;
9932
9933 if (use_json)
9934 json_path = json_object_new_object();
9935
9936 /* short status lead text */
9937 route_vty_short_status_out(vty, path, p, json_path);
9938
9939 /* print prefix and mask */
9940 if (!use_json) {
9941 if (!display)
9942 route_vty_out_route(path->net, p, vty, NULL, false);
9943 else
9944 vty_out(vty, "%*s", 17, " ");
9945
9946 len = vty_out(vty, "%s", path->peer->host);
9947 len = 17 - len;
9948
9949 if (len < 1)
9950 vty_out(vty, "\n%*s", 34, " ");
9951 else
9952 vty_out(vty, "%*s", len, " ");
9953
9954 vty_out(vty, "%s ",
9955 bgp_damp_reuse_time_vty(vty, path, timebuf,
9956 BGP_UPTIME_LEN, afi, safi,
9957 use_json, NULL));
9958
9959 if (attr->aspath)
9960 aspath_print_vty(vty, attr->aspath);
9961
9962 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9963
9964 vty_out(vty, "\n");
9965 } else {
9966 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9967 safi, use_json, json_path);
9968
9969 if (attr->aspath)
9970 json_object_string_add(json_path, "asPath",
9971 attr->aspath->str);
9972
9973 json_object_string_add(json_path, "origin",
9974 bgp_origin_str[attr->origin]);
9975 json_object_string_add(json_path, "peerHost", path->peer->host);
9976
9977 json_object_array_add(json_paths, json_path);
9978 }
9979 }
9980
9981 /* flap route */
9982 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9983 struct bgp_path_info *path, int display,
9984 afi_t afi, safi_t safi, bool use_json,
9985 json_object *json_paths)
9986 {
9987 struct attr *attr = path->attr;
9988 struct bgp_damp_info *bdi;
9989 char timebuf[BGP_UPTIME_LEN];
9990 int len;
9991 json_object *json_path = NULL;
9992
9993 if (!path->extra)
9994 return;
9995
9996 if (use_json)
9997 json_path = json_object_new_object();
9998
9999 bdi = path->extra->damp_info;
10000
10001 /* short status lead text */
10002 route_vty_short_status_out(vty, path, p, json_path);
10003
10004 if (!use_json) {
10005 if (!display)
10006 route_vty_out_route(path->net, p, vty, NULL, false);
10007 else
10008 vty_out(vty, "%*s", 17, " ");
10009
10010 len = vty_out(vty, "%s", path->peer->host);
10011 len = 16 - len;
10012 if (len < 1)
10013 vty_out(vty, "\n%*s", 33, " ");
10014 else
10015 vty_out(vty, "%*s", len, " ");
10016
10017 len = vty_out(vty, "%d", bdi->flap);
10018 len = 5 - len;
10019 if (len < 1)
10020 vty_out(vty, " ");
10021 else
10022 vty_out(vty, "%*s", len, " ");
10023
10024 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10025 BGP_UPTIME_LEN, 0, NULL));
10026
10027 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10028 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10029 vty_out(vty, "%s ",
10030 bgp_damp_reuse_time_vty(vty, path, timebuf,
10031 BGP_UPTIME_LEN, afi,
10032 safi, use_json, NULL));
10033 else
10034 vty_out(vty, "%*s ", 8, " ");
10035
10036 if (attr->aspath)
10037 aspath_print_vty(vty, attr->aspath);
10038
10039 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10040
10041 vty_out(vty, "\n");
10042 } else {
10043 json_object_string_add(json_path, "peerHost", path->peer->host);
10044 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10045
10046 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10047 json_path);
10048
10049 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10050 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10051 bgp_damp_reuse_time_vty(vty, path, timebuf,
10052 BGP_UPTIME_LEN, afi, safi,
10053 use_json, json_path);
10054
10055 if (attr->aspath)
10056 json_object_string_add(json_path, "asPath",
10057 attr->aspath->str);
10058
10059 json_object_string_add(json_path, "origin",
10060 bgp_origin_str[attr->origin]);
10061
10062 json_object_array_add(json_paths, json_path);
10063 }
10064 }
10065
10066 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10067 int *first, const char *header,
10068 json_object *json_adv_to)
10069 {
10070 json_object *json_peer = NULL;
10071
10072 if (json_adv_to) {
10073 /* 'advertised-to' is a dictionary of peers we have advertised
10074 * this
10075 * prefix too. The key is the peer's IP or swpX, the value is
10076 * the
10077 * hostname if we know it and "" if not.
10078 */
10079 json_peer = json_object_new_object();
10080
10081 if (peer->hostname)
10082 json_object_string_add(json_peer, "hostname",
10083 peer->hostname);
10084
10085 if (peer->conf_if)
10086 json_object_object_add(json_adv_to, peer->conf_if,
10087 json_peer);
10088 else
10089 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10090 &peer->su);
10091 } else {
10092 if (*first) {
10093 vty_out(vty, "%s", header);
10094 *first = 0;
10095 }
10096
10097 if (peer->hostname
10098 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10099 if (peer->conf_if)
10100 vty_out(vty, " %s(%s)", peer->hostname,
10101 peer->conf_if);
10102 else
10103 vty_out(vty, " %s(%pSU)", peer->hostname,
10104 &peer->su);
10105 } else {
10106 if (peer->conf_if)
10107 vty_out(vty, " %s", peer->conf_if);
10108 else
10109 vty_out(vty, " %pSU", &peer->su);
10110 }
10111 }
10112 }
10113
10114 static void route_vty_out_tx_ids(struct vty *vty,
10115 struct bgp_addpath_info_data *d)
10116 {
10117 int i;
10118
10119 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10120 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10121 d->addpath_tx_id[i],
10122 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10123 }
10124 }
10125
10126 static void route_vty_out_detail_es_info(struct vty *vty,
10127 struct bgp_path_info *pi,
10128 struct attr *attr,
10129 json_object *json_path)
10130 {
10131 char esi_buf[ESI_STR_LEN];
10132 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10133 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10134 ATTR_ES_PEER_ROUTER);
10135 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10136 ATTR_ES_PEER_ACTIVE);
10137 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10138 ATTR_ES_PEER_PROXY);
10139 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10140 if (json_path) {
10141 json_object *json_es_info = NULL;
10142
10143 json_object_string_add(
10144 json_path, "esi",
10145 esi_buf);
10146 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10147 json_es_info = json_object_new_object();
10148 if (es_local)
10149 json_object_boolean_true_add(
10150 json_es_info, "localEs");
10151 if (peer_active)
10152 json_object_boolean_true_add(
10153 json_es_info, "peerActive");
10154 if (peer_proxy)
10155 json_object_boolean_true_add(
10156 json_es_info, "peerProxy");
10157 if (peer_router)
10158 json_object_boolean_true_add(
10159 json_es_info, "peerRouter");
10160 if (attr->mm_sync_seqnum)
10161 json_object_int_add(
10162 json_es_info, "peerSeq",
10163 attr->mm_sync_seqnum);
10164 json_object_object_add(
10165 json_path, "es_info",
10166 json_es_info);
10167 }
10168 } else {
10169 if (bgp_evpn_attr_is_sync(attr))
10170 vty_out(vty,
10171 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10172 esi_buf,
10173 es_local ? "local-es":"",
10174 peer_proxy ? "proxy " : "",
10175 peer_active ? "active ":"",
10176 peer_router ? "router ":"",
10177 attr->mm_sync_seqnum);
10178 else
10179 vty_out(vty, " ESI %s %s\n",
10180 esi_buf,
10181 es_local ? "local-es":"");
10182 }
10183 }
10184
10185 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10186 const struct prefix *p, struct bgp_path_info *path,
10187 afi_t afi, safi_t safi,
10188 enum rpki_states rpki_curr_state,
10189 json_object *json_paths)
10190 {
10191 char buf[INET6_ADDRSTRLEN];
10192 char tag_buf[30];
10193 struct attr *attr = path->attr;
10194 time_t tbuf;
10195 json_object *json_bestpath = NULL;
10196 json_object *json_cluster_list = NULL;
10197 json_object *json_cluster_list_list = NULL;
10198 json_object *json_ext_community = NULL;
10199 json_object *json_last_update = NULL;
10200 json_object *json_pmsi = NULL;
10201 json_object *json_nexthop_global = NULL;
10202 json_object *json_nexthop_ll = NULL;
10203 json_object *json_nexthops = NULL;
10204 json_object *json_path = NULL;
10205 json_object *json_peer = NULL;
10206 json_object *json_string = NULL;
10207 json_object *json_adv_to = NULL;
10208 int first = 0;
10209 struct listnode *node, *nnode;
10210 struct peer *peer;
10211 bool addpath_capable;
10212 int has_adj;
10213 unsigned int first_as;
10214 bool nexthop_self =
10215 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10216 int i;
10217 char *nexthop_hostname =
10218 bgp_nexthop_hostname(path->peer, path->nexthop);
10219 uint32_t ttl = 0;
10220 uint32_t bos = 0;
10221 uint32_t exp = 0;
10222 mpls_label_t label = MPLS_INVALID_LABEL;
10223 tag_buf[0] = '\0';
10224 struct bgp_path_info *bpi_ultimate =
10225 bgp_get_imported_bpi_ultimate(path);
10226
10227 if (json_paths) {
10228 json_path = json_object_new_object();
10229 json_peer = json_object_new_object();
10230 json_nexthop_global = json_object_new_object();
10231 }
10232
10233 if (safi == SAFI_EVPN) {
10234 if (!json_paths)
10235 vty_out(vty, " Route %pFX", p);
10236 }
10237
10238 if (path->extra) {
10239 if (path->extra && path->extra->num_labels) {
10240 bgp_evpn_label2str(path->extra->label,
10241 path->extra->num_labels, tag_buf,
10242 sizeof(tag_buf));
10243 }
10244 if (safi == SAFI_EVPN) {
10245 if (!json_paths) {
10246 if (tag_buf[0] != '\0')
10247 vty_out(vty, " VNI %s", tag_buf);
10248 } else {
10249 if (tag_buf[0])
10250 json_object_string_add(json_path, "vni",
10251 tag_buf);
10252 }
10253 }
10254 }
10255
10256 if (safi == SAFI_EVPN
10257 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10258 char gwip_buf[INET6_ADDRSTRLEN];
10259
10260 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10261 sizeof(gwip_buf));
10262
10263 if (json_paths)
10264 json_object_string_add(json_path, "gatewayIP",
10265 gwip_buf);
10266 else
10267 vty_out(vty, " Gateway IP %s", gwip_buf);
10268 }
10269
10270 if (safi == SAFI_EVPN && !json_path)
10271 vty_out(vty, "\n");
10272
10273
10274 if (path->extra && path->extra->parent && !json_paths) {
10275 struct bgp_path_info *parent_ri;
10276 struct bgp_dest *dest, *pdest;
10277
10278 parent_ri = (struct bgp_path_info *)path->extra->parent;
10279 dest = parent_ri->net;
10280 if (dest && dest->pdest) {
10281 pdest = dest->pdest;
10282 if (is_pi_family_evpn(parent_ri)) {
10283 vty_out(vty, " Imported from ");
10284 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10285 (struct prefix_rd *)bgp_dest_get_prefix(
10286 pdest));
10287 vty_out(vty, ":%pFX, VNI %s",
10288 (struct prefix_evpn *)
10289 bgp_dest_get_prefix(dest),
10290 tag_buf);
10291 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10292 vty_out(vty, ", L3NHG %s",
10293 CHECK_FLAG(
10294 attr->es_flags,
10295 ATTR_ES_L3_NHG_ACTIVE)
10296 ? "active"
10297 : "inactive");
10298 vty_out(vty, "\n");
10299
10300 } else {
10301 vty_out(vty, " Imported from ");
10302 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10303 (struct prefix_rd *)bgp_dest_get_prefix(
10304 pdest));
10305 vty_out(vty, ":%pFX\n",
10306 (struct prefix_evpn *)
10307 bgp_dest_get_prefix(dest));
10308 }
10309 }
10310 }
10311
10312 /* Line1 display AS-path, Aggregator */
10313 if (attr->aspath) {
10314 if (json_paths) {
10315 if (!attr->aspath->json)
10316 aspath_str_update(attr->aspath, true);
10317 json_object_lock(attr->aspath->json);
10318 json_object_object_add(json_path, "aspath",
10319 attr->aspath->json);
10320 } else {
10321 if (attr->aspath->segments)
10322 vty_out(vty, " %s", attr->aspath->str);
10323 else
10324 vty_out(vty, " Local");
10325 }
10326 }
10327
10328 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10329 if (json_paths)
10330 json_object_boolean_true_add(json_path, "removed");
10331 else
10332 vty_out(vty, ", (removed)");
10333 }
10334
10335 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10336 if (json_paths)
10337 json_object_boolean_true_add(json_path, "stale");
10338 else
10339 vty_out(vty, ", (stale)");
10340 }
10341
10342 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10343 if (json_paths) {
10344 json_object_int_add(json_path, "aggregatorAs",
10345 attr->aggregator_as);
10346 json_object_string_addf(json_path, "aggregatorId",
10347 "%pI4", &attr->aggregator_addr);
10348 } else {
10349 vty_out(vty, ", (aggregated by %u %pI4)",
10350 attr->aggregator_as, &attr->aggregator_addr);
10351 }
10352 }
10353
10354 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10355 PEER_FLAG_REFLECTOR_CLIENT)) {
10356 if (json_paths)
10357 json_object_boolean_true_add(json_path,
10358 "rxedFromRrClient");
10359 else
10360 vty_out(vty, ", (Received from a RR-client)");
10361 }
10362
10363 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10364 PEER_FLAG_RSERVER_CLIENT)) {
10365 if (json_paths)
10366 json_object_boolean_true_add(json_path,
10367 "rxedFromRsClient");
10368 else
10369 vty_out(vty, ", (Received from a RS-client)");
10370 }
10371
10372 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10373 if (json_paths)
10374 json_object_boolean_true_add(json_path,
10375 "dampeningHistoryEntry");
10376 else
10377 vty_out(vty, ", (history entry)");
10378 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10379 if (json_paths)
10380 json_object_boolean_true_add(json_path,
10381 "dampeningSuppressed");
10382 else
10383 vty_out(vty, ", (suppressed due to dampening)");
10384 }
10385
10386 if (!json_paths)
10387 vty_out(vty, "\n");
10388
10389 /* Line2 display Next-hop, Neighbor, Router-id */
10390 /* Display the nexthop */
10391
10392 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10393 p->family == AF_EVPN) &&
10394 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10395 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10396 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10397 || safi == SAFI_EVPN) {
10398 if (json_paths) {
10399 json_object_string_addf(
10400 json_nexthop_global, "ip", "%pI4",
10401 &attr->mp_nexthop_global_in);
10402
10403 if (path->peer->hostname)
10404 json_object_string_add(
10405 json_nexthop_global, "hostname",
10406 path->peer->hostname);
10407 } else {
10408 if (nexthop_hostname)
10409 vty_out(vty, " %pI4(%s)",
10410 &attr->mp_nexthop_global_in,
10411 nexthop_hostname);
10412 else
10413 vty_out(vty, " %pI4",
10414 &attr->mp_nexthop_global_in);
10415 }
10416 } else {
10417 if (json_paths) {
10418 json_object_string_addf(json_nexthop_global,
10419 "ip", "%pI4",
10420 &attr->nexthop);
10421
10422 if (path->peer->hostname)
10423 json_object_string_add(
10424 json_nexthop_global, "hostname",
10425 path->peer->hostname);
10426 } else {
10427 if (nexthop_hostname)
10428 vty_out(vty, " %pI4(%s)",
10429 &attr->nexthop,
10430 nexthop_hostname);
10431 else
10432 vty_out(vty, " %pI4",
10433 &attr->nexthop);
10434 }
10435 }
10436
10437 if (json_paths)
10438 json_object_string_add(json_nexthop_global, "afi",
10439 "ipv4");
10440 } else {
10441 if (json_paths) {
10442 json_object_string_addf(json_nexthop_global, "ip",
10443 "%pI6",
10444 &attr->mp_nexthop_global);
10445
10446 if (path->peer->hostname)
10447 json_object_string_add(json_nexthop_global,
10448 "hostname",
10449 path->peer->hostname);
10450
10451 json_object_string_add(json_nexthop_global, "afi",
10452 "ipv6");
10453 json_object_string_add(json_nexthop_global, "scope",
10454 "global");
10455 } else {
10456 if (nexthop_hostname)
10457 vty_out(vty, " %pI6(%s)",
10458 &attr->mp_nexthop_global,
10459 nexthop_hostname);
10460 else
10461 vty_out(vty, " %pI6",
10462 &attr->mp_nexthop_global);
10463 }
10464 }
10465
10466 /* Display the IGP cost or 'inaccessible' */
10467 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10468 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10469
10470 if (json_paths) {
10471 json_object_boolean_false_add(json_nexthop_global,
10472 "accessible");
10473 json_object_boolean_add(json_nexthop_global,
10474 "importCheckEnabled", import);
10475 } else {
10476 vty_out(vty, " (inaccessible%s)",
10477 import ? ", import-check enabled" : "");
10478 }
10479 } else {
10480 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10481 if (json_paths)
10482 json_object_int_add(
10483 json_nexthop_global, "metric",
10484 bpi_ultimate->extra->igpmetric);
10485 else
10486 vty_out(vty, " (metric %u)",
10487 bpi_ultimate->extra->igpmetric);
10488 }
10489
10490 /* IGP cost is 0, display this only for json */
10491 else {
10492 if (json_paths)
10493 json_object_int_add(json_nexthop_global,
10494 "metric", 0);
10495 }
10496
10497 if (json_paths)
10498 json_object_boolean_true_add(json_nexthop_global,
10499 "accessible");
10500 }
10501
10502 /* Display peer "from" output */
10503 /* This path was originated locally */
10504 if (path->peer == bgp->peer_self) {
10505
10506 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10507 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10508 if (json_paths)
10509 json_object_string_add(json_peer, "peerId",
10510 "0.0.0.0");
10511 else
10512 vty_out(vty, " from 0.0.0.0 ");
10513 } else {
10514 if (json_paths)
10515 json_object_string_add(json_peer, "peerId",
10516 "::");
10517 else
10518 vty_out(vty, " from :: ");
10519 }
10520
10521 if (json_paths)
10522 json_object_string_addf(json_peer, "routerId", "%pI4",
10523 &bgp->router_id);
10524 else
10525 vty_out(vty, "(%pI4)", &bgp->router_id);
10526 }
10527
10528 /* We RXed this path from one of our peers */
10529 else {
10530
10531 if (json_paths) {
10532 json_object_string_addf(json_peer, "peerId", "%pSU",
10533 &path->peer->su);
10534 json_object_string_addf(json_peer, "routerId", "%pI4",
10535 &path->peer->remote_id);
10536
10537 if (path->peer->hostname)
10538 json_object_string_add(json_peer, "hostname",
10539 path->peer->hostname);
10540
10541 if (path->peer->domainname)
10542 json_object_string_add(json_peer, "domainname",
10543 path->peer->domainname);
10544
10545 if (path->peer->conf_if)
10546 json_object_string_add(json_peer, "interface",
10547 path->peer->conf_if);
10548 } else {
10549 if (path->peer->conf_if) {
10550 if (path->peer->hostname
10551 && CHECK_FLAG(path->peer->bgp->flags,
10552 BGP_FLAG_SHOW_HOSTNAME))
10553 vty_out(vty, " from %s(%s)",
10554 path->peer->hostname,
10555 path->peer->conf_if);
10556 else
10557 vty_out(vty, " from %s",
10558 path->peer->conf_if);
10559 } else {
10560 if (path->peer->hostname
10561 && CHECK_FLAG(path->peer->bgp->flags,
10562 BGP_FLAG_SHOW_HOSTNAME))
10563 vty_out(vty, " from %s(%s)",
10564 path->peer->hostname,
10565 path->peer->host);
10566 else
10567 vty_out(vty, " from %pSU",
10568 &path->peer->su);
10569 }
10570
10571 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10572 vty_out(vty, " (%pI4)", &attr->originator_id);
10573 else
10574 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10575 }
10576 }
10577
10578 /*
10579 * Note when vrfid of nexthop is different from that of prefix
10580 */
10581 if (path->extra && path->extra->bgp_orig) {
10582 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10583
10584 if (json_paths) {
10585 const char *vn;
10586
10587 if (path->extra->bgp_orig->inst_type
10588 == BGP_INSTANCE_TYPE_DEFAULT)
10589 vn = VRF_DEFAULT_NAME;
10590 else
10591 vn = path->extra->bgp_orig->name;
10592
10593 json_object_string_add(json_path, "nhVrfName", vn);
10594
10595 if (nexthop_vrfid == VRF_UNKNOWN) {
10596 json_object_int_add(json_path, "nhVrfId", -1);
10597 } else {
10598 json_object_int_add(json_path, "nhVrfId",
10599 (int)nexthop_vrfid);
10600 }
10601 } else {
10602 if (nexthop_vrfid == VRF_UNKNOWN)
10603 vty_out(vty, " vrf ?");
10604 else {
10605 struct vrf *vrf;
10606
10607 vrf = vrf_lookup_by_id(nexthop_vrfid);
10608 vty_out(vty, " vrf %s(%u)",
10609 VRF_LOGNAME(vrf), nexthop_vrfid);
10610 }
10611 }
10612 }
10613
10614 if (nexthop_self) {
10615 if (json_paths) {
10616 json_object_boolean_true_add(json_path,
10617 "announceNexthopSelf");
10618 } else {
10619 vty_out(vty, " announce-nh-self");
10620 }
10621 }
10622
10623 if (!json_paths)
10624 vty_out(vty, "\n");
10625
10626 /* display the link-local nexthop */
10627 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10628 if (json_paths) {
10629 json_nexthop_ll = json_object_new_object();
10630 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10631 &attr->mp_nexthop_local);
10632
10633 if (path->peer->hostname)
10634 json_object_string_add(json_nexthop_ll,
10635 "hostname",
10636 path->peer->hostname);
10637
10638 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10639 json_object_string_add(json_nexthop_ll, "scope",
10640 "link-local");
10641
10642 json_object_boolean_true_add(json_nexthop_ll,
10643 "accessible");
10644
10645 if (!attr->mp_nexthop_prefer_global)
10646 json_object_boolean_true_add(json_nexthop_ll,
10647 "used");
10648 else
10649 json_object_boolean_true_add(
10650 json_nexthop_global, "used");
10651 } else {
10652 vty_out(vty, " (%s) %s\n",
10653 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10654 buf, INET6_ADDRSTRLEN),
10655 attr->mp_nexthop_prefer_global
10656 ? "(prefer-global)"
10657 : "(used)");
10658 }
10659 }
10660 /* If we do not have a link-local nexthop then we must flag the
10661 global as "used" */
10662 else {
10663 if (json_paths)
10664 json_object_boolean_true_add(json_nexthop_global,
10665 "used");
10666 }
10667
10668 if (safi == SAFI_EVPN &&
10669 bgp_evpn_is_esi_valid(&attr->esi)) {
10670 route_vty_out_detail_es_info(vty, path, attr, json_path);
10671 }
10672
10673 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10674 * Int/Ext/Local, Atomic, best */
10675 if (json_paths)
10676 json_object_string_add(json_path, "origin",
10677 bgp_origin_long_str[attr->origin]);
10678 else
10679 vty_out(vty, " Origin %s",
10680 bgp_origin_long_str[attr->origin]);
10681
10682 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10683 if (json_paths)
10684 json_object_int_add(json_path, "metric", attr->med);
10685 else
10686 vty_out(vty, ", metric %u", attr->med);
10687 }
10688
10689 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10690 if (json_paths)
10691 json_object_int_add(json_path, "locPrf",
10692 attr->local_pref);
10693 else
10694 vty_out(vty, ", localpref %u", attr->local_pref);
10695 }
10696
10697 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10698 if (json_paths)
10699 json_object_int_add(json_path, "aigpMetric",
10700 bgp_attr_get_aigp_metric(attr));
10701 else
10702 vty_out(vty, ", aigp-metric %" PRIu64,
10703 bgp_attr_get_aigp_metric(attr));
10704 }
10705
10706 if (attr->weight != 0) {
10707 if (json_paths)
10708 json_object_int_add(json_path, "weight", attr->weight);
10709 else
10710 vty_out(vty, ", weight %u", attr->weight);
10711 }
10712
10713 if (attr->tag != 0) {
10714 if (json_paths)
10715 json_object_int_add(json_path, "tag", attr->tag);
10716 else
10717 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10718 }
10719
10720 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10721 if (json_paths)
10722 json_object_boolean_false_add(json_path, "valid");
10723 else
10724 vty_out(vty, ", invalid");
10725 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10726 if (json_paths)
10727 json_object_boolean_true_add(json_path, "valid");
10728 else
10729 vty_out(vty, ", valid");
10730 }
10731
10732 if (json_paths)
10733 json_object_int_add(json_path, "version", bn->version);
10734
10735 if (path->peer != bgp->peer_self) {
10736 if (path->peer->as == path->peer->local_as) {
10737 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10738 if (json_paths)
10739 json_object_string_add(
10740 json_peer, "type",
10741 "confed-internal");
10742 else
10743 vty_out(vty, ", confed-internal");
10744 } else {
10745 if (json_paths)
10746 json_object_string_add(
10747 json_peer, "type", "internal");
10748 else
10749 vty_out(vty, ", internal");
10750 }
10751 } else {
10752 if (bgp_confederation_peers_check(bgp,
10753 path->peer->as)) {
10754 if (json_paths)
10755 json_object_string_add(
10756 json_peer, "type",
10757 "confed-external");
10758 else
10759 vty_out(vty, ", confed-external");
10760 } else {
10761 if (json_paths)
10762 json_object_string_add(
10763 json_peer, "type", "external");
10764 else
10765 vty_out(vty, ", external");
10766 }
10767 }
10768 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10769 if (json_paths) {
10770 json_object_boolean_true_add(json_path, "aggregated");
10771 json_object_boolean_true_add(json_path, "local");
10772 } else {
10773 vty_out(vty, ", aggregated, local");
10774 }
10775 } else if (path->type != ZEBRA_ROUTE_BGP) {
10776 if (json_paths)
10777 json_object_boolean_true_add(json_path, "sourced");
10778 else
10779 vty_out(vty, ", sourced");
10780 } else {
10781 if (json_paths) {
10782 json_object_boolean_true_add(json_path, "sourced");
10783 json_object_boolean_true_add(json_path, "local");
10784 } else {
10785 vty_out(vty, ", sourced, local");
10786 }
10787 }
10788
10789 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10790 if (json_paths)
10791 json_object_boolean_true_add(json_path,
10792 "atomicAggregate");
10793 else
10794 vty_out(vty, ", atomic-aggregate");
10795 }
10796
10797 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10798 if (json_paths)
10799 json_object_int_add(json_path, "otc", attr->otc);
10800 else
10801 vty_out(vty, ", otc %u", attr->otc);
10802 }
10803
10804 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10805 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10806 && bgp_path_info_mpath_count(path))) {
10807 if (json_paths)
10808 json_object_boolean_true_add(json_path, "multipath");
10809 else
10810 vty_out(vty, ", multipath");
10811 }
10812
10813 // Mark the bestpath(s)
10814 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10815 first_as = aspath_get_first_as(attr->aspath);
10816
10817 if (json_paths) {
10818 if (!json_bestpath)
10819 json_bestpath = json_object_new_object();
10820 json_object_int_add(json_bestpath, "bestpathFromAs",
10821 first_as);
10822 } else {
10823 if (first_as)
10824 vty_out(vty, ", bestpath-from-AS %u", first_as);
10825 else
10826 vty_out(vty, ", bestpath-from-AS Local");
10827 }
10828 }
10829
10830 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10831 if (json_paths) {
10832 if (!json_bestpath)
10833 json_bestpath = json_object_new_object();
10834 json_object_boolean_true_add(json_bestpath, "overall");
10835 json_object_string_add(
10836 json_bestpath, "selectionReason",
10837 bgp_path_selection_reason2str(bn->reason));
10838 } else {
10839 vty_out(vty, ", best");
10840 vty_out(vty, " (%s)",
10841 bgp_path_selection_reason2str(bn->reason));
10842 }
10843 }
10844
10845 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10846 if (json_paths)
10847 json_object_string_add(
10848 json_path, "rpkiValidationState",
10849 bgp_rpki_validation2str(rpki_curr_state));
10850 else
10851 vty_out(vty, ", rpki validation-state: %s",
10852 bgp_rpki_validation2str(rpki_curr_state));
10853 }
10854
10855 if (json_bestpath)
10856 json_object_object_add(json_path, "bestpath", json_bestpath);
10857
10858 if (!json_paths)
10859 vty_out(vty, "\n");
10860
10861 /* Line 4 display Community */
10862 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10863 if (json_paths) {
10864 if (!bgp_attr_get_community(attr)->json)
10865 community_str(bgp_attr_get_community(attr),
10866 true, true);
10867 json_object_lock(bgp_attr_get_community(attr)->json);
10868 json_object_object_add(
10869 json_path, "community",
10870 bgp_attr_get_community(attr)->json);
10871 } else {
10872 vty_out(vty, " Community: %s\n",
10873 bgp_attr_get_community(attr)->str);
10874 }
10875 }
10876
10877 /* Line 5 display Extended-community */
10878 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10879 if (json_paths) {
10880 json_ext_community = json_object_new_object();
10881 json_object_string_add(
10882 json_ext_community, "string",
10883 bgp_attr_get_ecommunity(attr)->str);
10884 json_object_object_add(json_path, "extendedCommunity",
10885 json_ext_community);
10886 } else {
10887 vty_out(vty, " Extended Community: %s\n",
10888 bgp_attr_get_ecommunity(attr)->str);
10889 }
10890 }
10891
10892 /* Line 6 display Large community */
10893 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10894 if (json_paths) {
10895 if (!bgp_attr_get_lcommunity(attr)->json)
10896 lcommunity_str(bgp_attr_get_lcommunity(attr),
10897 true, true);
10898 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10899 json_object_object_add(
10900 json_path, "largeCommunity",
10901 bgp_attr_get_lcommunity(attr)->json);
10902 } else {
10903 vty_out(vty, " Large Community: %s\n",
10904 bgp_attr_get_lcommunity(attr)->str);
10905 }
10906 }
10907
10908 /* Line 7 display Originator, Cluster-id */
10909 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10910 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10911 char buf[BUFSIZ] = {0};
10912
10913 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10914 if (json_paths)
10915 json_object_string_addf(json_path,
10916 "originatorId", "%pI4",
10917 &attr->originator_id);
10918 else
10919 vty_out(vty, " Originator: %pI4",
10920 &attr->originator_id);
10921 }
10922
10923 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10924 struct cluster_list *cluster =
10925 bgp_attr_get_cluster(attr);
10926 int i;
10927
10928 if (json_paths) {
10929 json_cluster_list = json_object_new_object();
10930 json_cluster_list_list =
10931 json_object_new_array();
10932
10933 for (i = 0; i < cluster->length / 4; i++) {
10934 json_string = json_object_new_string(
10935 inet_ntop(AF_INET,
10936 &cluster->list[i],
10937 buf, sizeof(buf)));
10938 json_object_array_add(
10939 json_cluster_list_list,
10940 json_string);
10941 }
10942
10943 /*
10944 * struct cluster_list does not have
10945 * "str" variable like aspath and community
10946 * do. Add this someday if someone asks
10947 * for it.
10948 * json_object_string_add(json_cluster_list,
10949 * "string", cluster->str);
10950 */
10951 json_object_object_add(json_cluster_list,
10952 "list",
10953 json_cluster_list_list);
10954 json_object_object_add(json_path, "clusterList",
10955 json_cluster_list);
10956 } else {
10957 vty_out(vty, ", Cluster list: ");
10958
10959 for (i = 0; i < cluster->length / 4; i++) {
10960 vty_out(vty, "%pI4 ",
10961 &cluster->list[i]);
10962 }
10963 }
10964 }
10965
10966 if (!json_paths)
10967 vty_out(vty, "\n");
10968 }
10969
10970 if (path->extra && path->extra->damp_info)
10971 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10972
10973 /* Remote Label */
10974 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10975 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10976 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10977 &bos);
10978
10979 if (json_paths)
10980 json_object_int_add(json_path, "remoteLabel", label);
10981 else
10982 vty_out(vty, " Remote label: %d\n", label);
10983 }
10984
10985 /* Remote SID */
10986 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10987 if (json_paths)
10988 json_object_string_addf(json_path, "remoteSid", "%pI6",
10989 &path->extra->sid[0].sid);
10990 else
10991 vty_out(vty, " Remote SID: %pI6\n",
10992 &path->extra->sid[0].sid);
10993 }
10994
10995 /* Label Index */
10996 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10997 if (json_paths)
10998 json_object_int_add(json_path, "labelIndex",
10999 attr->label_index);
11000 else
11001 vty_out(vty, " Label Index: %d\n",
11002 attr->label_index);
11003 }
11004
11005 /* Line 8 display Addpath IDs */
11006 if (path->addpath_rx_id
11007 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11008 if (json_paths) {
11009 json_object_int_add(json_path, "addpathRxId",
11010 path->addpath_rx_id);
11011
11012 /* Keep backwards compatibility with the old API
11013 * by putting TX All's ID in the old field
11014 */
11015 json_object_int_add(
11016 json_path, "addpathTxId",
11017 path->tx_addpath
11018 .addpath_tx_id[BGP_ADDPATH_ALL]);
11019
11020 /* ... but create a specific field for each
11021 * strategy
11022 */
11023 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11024 json_object_int_add(
11025 json_path,
11026 bgp_addpath_names(i)->id_json_name,
11027 path->tx_addpath.addpath_tx_id[i]);
11028 }
11029 } else {
11030 vty_out(vty, " AddPath ID: RX %u, ",
11031 path->addpath_rx_id);
11032
11033 route_vty_out_tx_ids(vty, &path->tx_addpath);
11034 }
11035 }
11036
11037 /* If we used addpath to TX a non-bestpath we need to display
11038 * "Advertised to" on a path-by-path basis
11039 */
11040 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11041 first = 1;
11042
11043 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11044 addpath_capable =
11045 bgp_addpath_encode_tx(peer, afi, safi);
11046 has_adj = bgp_adj_out_lookup(
11047 peer, path->net,
11048 bgp_addpath_id_for_peer(peer, afi, safi,
11049 &path->tx_addpath));
11050
11051 if ((addpath_capable && has_adj)
11052 || (!addpath_capable && has_adj
11053 && CHECK_FLAG(path->flags,
11054 BGP_PATH_SELECTED))) {
11055 if (json_path && !json_adv_to)
11056 json_adv_to = json_object_new_object();
11057
11058 route_vty_out_advertised_to(
11059 vty, peer, &first,
11060 " Advertised to:", json_adv_to);
11061 }
11062 }
11063
11064 if (json_path) {
11065 if (json_adv_to) {
11066 json_object_object_add(
11067 json_path, "advertisedTo", json_adv_to);
11068 }
11069 } else {
11070 if (!first) {
11071 vty_out(vty, "\n");
11072 }
11073 }
11074 }
11075
11076 /* Line 9 display Uptime */
11077 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11078 if (json_paths) {
11079 json_last_update = json_object_new_object();
11080 json_object_int_add(json_last_update, "epoch", tbuf);
11081 json_object_string_add(json_last_update, "string",
11082 ctime(&tbuf));
11083 json_object_object_add(json_path, "lastUpdate",
11084 json_last_update);
11085 } else
11086 vty_out(vty, " Last update: %s", ctime(&tbuf));
11087
11088 /* Line 10 display PMSI tunnel attribute, if present */
11089 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11090 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11091 bgp_attr_get_pmsi_tnl_type(attr),
11092 PMSI_TNLTYPE_STR_DEFAULT);
11093
11094 if (json_paths) {
11095 json_pmsi = json_object_new_object();
11096 json_object_string_add(json_pmsi, "tunnelType", str);
11097 json_object_int_add(json_pmsi, "label",
11098 label2vni(&attr->label));
11099 json_object_object_add(json_path, "pmsi", json_pmsi);
11100 } else
11101 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11102 str, label2vni(&attr->label));
11103 }
11104
11105 if (path->peer->t_gr_restart &&
11106 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11107 unsigned long gr_remaining =
11108 thread_timer_remain_second(path->peer->t_gr_restart);
11109
11110 if (json_paths) {
11111 json_object_int_add(json_path,
11112 "gracefulRestartSecondsRemaining",
11113 gr_remaining);
11114 } else
11115 vty_out(vty,
11116 " Time until Graceful Restart stale route deleted: %lu\n",
11117 gr_remaining);
11118 }
11119
11120 if (path->peer->t_llgr_stale[afi][safi] &&
11121 bgp_attr_get_community(attr) &&
11122 community_include(bgp_attr_get_community(attr),
11123 COMMUNITY_LLGR_STALE)) {
11124 unsigned long llgr_remaining = thread_timer_remain_second(
11125 path->peer->t_llgr_stale[afi][safi]);
11126
11127 if (json_paths) {
11128 json_object_int_add(json_path, "llgrSecondsRemaining",
11129 llgr_remaining);
11130 } else
11131 vty_out(vty,
11132 " Time until Long-lived stale route deleted: %lu\n",
11133 llgr_remaining);
11134 }
11135
11136 /* Output some debug about internal state of the dest flags */
11137 if (json_paths) {
11138 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11139 json_object_boolean_true_add(json_path, "processScheduled");
11140 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11141 json_object_boolean_true_add(json_path, "userCleared");
11142 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11143 json_object_boolean_true_add(json_path, "labelChanged");
11144 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11145 json_object_boolean_true_add(json_path, "registeredForLabel");
11146 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11147 json_object_boolean_true_add(json_path, "selectDefered");
11148 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11149 json_object_boolean_true_add(json_path, "fibInstalled");
11150 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11151 json_object_boolean_true_add(json_path, "fibPending");
11152
11153 if (json_nexthop_global || json_nexthop_ll) {
11154 json_nexthops = json_object_new_array();
11155
11156 if (json_nexthop_global)
11157 json_object_array_add(json_nexthops,
11158 json_nexthop_global);
11159
11160 if (json_nexthop_ll)
11161 json_object_array_add(json_nexthops,
11162 json_nexthop_ll);
11163
11164 json_object_object_add(json_path, "nexthops",
11165 json_nexthops);
11166 }
11167
11168 json_object_object_add(json_path, "peer", json_peer);
11169 json_object_array_add(json_paths, json_path);
11170 }
11171 }
11172
11173 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11174 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11175 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11176
11177 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11178 afi_t afi, safi_t safi, enum bgp_show_type type,
11179 bool use_json);
11180 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11181 const char *comstr, int exact, afi_t afi,
11182 safi_t safi, uint16_t show_flags);
11183
11184 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11185 struct bgp_table *table, enum bgp_show_type type,
11186 void *output_arg, const char *rd, int is_last,
11187 unsigned long *output_cum, unsigned long *total_cum,
11188 unsigned long *json_header_depth, uint16_t show_flags,
11189 enum rpki_states rpki_target_state)
11190 {
11191 struct bgp_path_info *pi;
11192 struct bgp_dest *dest;
11193 bool header = true;
11194 bool json_detail_header = false;
11195 int display;
11196 unsigned long output_count = 0;
11197 unsigned long total_count = 0;
11198 struct prefix *p;
11199 json_object *json_paths = NULL;
11200 int first = 1;
11201 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11202 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11203 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11204 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11205 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11206
11207 if (output_cum && *output_cum != 0)
11208 header = false;
11209
11210 if (use_json && !*json_header_depth) {
11211 if (all)
11212 *json_header_depth = 1;
11213 else {
11214 vty_out(vty, "{\n");
11215 *json_header_depth = 2;
11216 }
11217 vty_out(vty,
11218 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11219 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11220 " \"localAS\": ",
11221 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11222 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11223 ? VRF_DEFAULT_NAME
11224 : bgp->name,
11225 table->version, &bgp->router_id,
11226 bgp->default_local_pref);
11227 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11228 ((bgp->asnotation == ASNOTATION_DOT) &&
11229 (bgp->as < UINT16_MAX)))
11230 vty_out(vty, "%u", bgp->as);
11231 else {
11232 vty_out(vty, "\"");
11233 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11234 vty_out(vty, "\"");
11235 }
11236 vty_out(vty, ",\n \"routes\": { ");
11237 if (rd) {
11238 vty_out(vty, " \"routeDistinguishers\" : {");
11239 ++*json_header_depth;
11240 }
11241 }
11242
11243 if (use_json && rd) {
11244 vty_out(vty, " \"%s\" : { ", rd);
11245 }
11246
11247 /* Check for 'json detail', where we need header output once per dest */
11248 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11249 type != bgp_show_type_damp_neighbor &&
11250 type != bgp_show_type_flap_statistics &&
11251 type != bgp_show_type_flap_neighbor)
11252 json_detail_header = true;
11253
11254 /* Start processing of routes. */
11255 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11256 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11257 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11258 bool json_detail_header_used = false;
11259
11260 pi = bgp_dest_get_bgp_path_info(dest);
11261 if (pi == NULL)
11262 continue;
11263
11264 display = 0;
11265 if (use_json)
11266 json_paths = json_object_new_array();
11267 else
11268 json_paths = NULL;
11269
11270 for (; pi; pi = pi->next) {
11271 struct community *picomm = NULL;
11272
11273 picomm = bgp_attr_get_community(pi->attr);
11274
11275 total_count++;
11276
11277 if (type == bgp_show_type_prefix_version) {
11278 uint32_t version =
11279 strtoul(output_arg, NULL, 10);
11280 if (dest->version < version)
11281 continue;
11282 }
11283
11284 if (type == bgp_show_type_community_alias) {
11285 char *alias = output_arg;
11286 char **communities;
11287 int num;
11288 bool found = false;
11289
11290 if (picomm) {
11291 frrstr_split(picomm->str, " ",
11292 &communities, &num);
11293 for (int i = 0; i < num; i++) {
11294 const char *com2alias =
11295 bgp_community2alias(
11296 communities[i]);
11297 if (!found
11298 && strcmp(alias, com2alias)
11299 == 0)
11300 found = true;
11301 XFREE(MTYPE_TMP,
11302 communities[i]);
11303 }
11304 XFREE(MTYPE_TMP, communities);
11305 }
11306
11307 if (!found &&
11308 bgp_attr_get_lcommunity(pi->attr)) {
11309 frrstr_split(bgp_attr_get_lcommunity(
11310 pi->attr)
11311 ->str,
11312 " ", &communities, &num);
11313 for (int i = 0; i < num; i++) {
11314 const char *com2alias =
11315 bgp_community2alias(
11316 communities[i]);
11317 if (!found
11318 && strcmp(alias, com2alias)
11319 == 0)
11320 found = true;
11321 XFREE(MTYPE_TMP,
11322 communities[i]);
11323 }
11324 XFREE(MTYPE_TMP, communities);
11325 }
11326
11327 if (!found)
11328 continue;
11329 }
11330
11331 if (type == bgp_show_type_rpki) {
11332 if (dest_p->family == AF_INET
11333 || dest_p->family == AF_INET6)
11334 rpki_curr_state = hook_call(
11335 bgp_rpki_prefix_status,
11336 pi->peer, pi->attr, dest_p);
11337 if (rpki_target_state != RPKI_NOT_BEING_USED
11338 && rpki_curr_state != rpki_target_state)
11339 continue;
11340 }
11341
11342 if (type == bgp_show_type_flap_statistics
11343 || type == bgp_show_type_flap_neighbor
11344 || type == bgp_show_type_dampend_paths
11345 || type == bgp_show_type_damp_neighbor) {
11346 if (!(pi->extra && pi->extra->damp_info))
11347 continue;
11348 }
11349 if (type == bgp_show_type_regexp) {
11350 regex_t *regex = output_arg;
11351
11352 if (bgp_regexec(regex, pi->attr->aspath)
11353 == REG_NOMATCH)
11354 continue;
11355 }
11356 if (type == bgp_show_type_prefix_list) {
11357 struct prefix_list *plist = output_arg;
11358
11359 if (prefix_list_apply(plist, dest_p)
11360 != PREFIX_PERMIT)
11361 continue;
11362 }
11363 if (type == bgp_show_type_access_list) {
11364 struct access_list *alist = output_arg;
11365
11366 if (access_list_apply(alist, dest_p) !=
11367 FILTER_PERMIT)
11368 continue;
11369 }
11370 if (type == bgp_show_type_filter_list) {
11371 struct as_list *as_list = output_arg;
11372
11373 if (as_list_apply(as_list, pi->attr->aspath)
11374 != AS_FILTER_PERMIT)
11375 continue;
11376 }
11377 if (type == bgp_show_type_route_map) {
11378 struct route_map *rmap = output_arg;
11379 struct bgp_path_info path;
11380 struct bgp_path_info_extra extra;
11381 struct attr dummy_attr = {};
11382 route_map_result_t ret;
11383
11384 dummy_attr = *pi->attr;
11385
11386 prep_for_rmap_apply(&path, &extra, dest, pi,
11387 pi->peer, &dummy_attr);
11388
11389 ret = route_map_apply(rmap, dest_p, &path);
11390 bgp_attr_flush(&dummy_attr);
11391 if (ret == RMAP_DENYMATCH)
11392 continue;
11393 }
11394 if (type == bgp_show_type_neighbor
11395 || type == bgp_show_type_flap_neighbor
11396 || type == bgp_show_type_damp_neighbor) {
11397 union sockunion *su = output_arg;
11398
11399 if (pi->peer == NULL
11400 || pi->peer->su_remote == NULL
11401 || !sockunion_same(pi->peer->su_remote, su))
11402 continue;
11403 }
11404 if (type == bgp_show_type_cidr_only) {
11405 uint32_t destination;
11406
11407 destination = ntohl(dest_p->u.prefix4.s_addr);
11408 if (IN_CLASSC(destination)
11409 && dest_p->prefixlen == 24)
11410 continue;
11411 if (IN_CLASSB(destination)
11412 && dest_p->prefixlen == 16)
11413 continue;
11414 if (IN_CLASSA(destination)
11415 && dest_p->prefixlen == 8)
11416 continue;
11417 }
11418 if (type == bgp_show_type_prefix_longer) {
11419 p = output_arg;
11420 if (!prefix_match(p, dest_p))
11421 continue;
11422 }
11423 if (type == bgp_show_type_community_all) {
11424 if (!picomm)
11425 continue;
11426 }
11427 if (type == bgp_show_type_community) {
11428 struct community *com = output_arg;
11429
11430 if (!picomm || !community_match(picomm, com))
11431 continue;
11432 }
11433 if (type == bgp_show_type_community_exact) {
11434 struct community *com = output_arg;
11435
11436 if (!picomm || !community_cmp(picomm, com))
11437 continue;
11438 }
11439 if (type == bgp_show_type_community_list) {
11440 struct community_list *list = output_arg;
11441
11442 if (!community_list_match(picomm, list))
11443 continue;
11444 }
11445 if (type == bgp_show_type_community_list_exact) {
11446 struct community_list *list = output_arg;
11447
11448 if (!community_list_exact_match(picomm, list))
11449 continue;
11450 }
11451 if (type == bgp_show_type_lcommunity) {
11452 struct lcommunity *lcom = output_arg;
11453
11454 if (!bgp_attr_get_lcommunity(pi->attr) ||
11455 !lcommunity_match(
11456 bgp_attr_get_lcommunity(pi->attr),
11457 lcom))
11458 continue;
11459 }
11460
11461 if (type == bgp_show_type_lcommunity_exact) {
11462 struct lcommunity *lcom = output_arg;
11463
11464 if (!bgp_attr_get_lcommunity(pi->attr) ||
11465 !lcommunity_cmp(
11466 bgp_attr_get_lcommunity(pi->attr),
11467 lcom))
11468 continue;
11469 }
11470 if (type == bgp_show_type_lcommunity_list) {
11471 struct community_list *list = output_arg;
11472
11473 if (!lcommunity_list_match(
11474 bgp_attr_get_lcommunity(pi->attr),
11475 list))
11476 continue;
11477 }
11478 if (type
11479 == bgp_show_type_lcommunity_list_exact) {
11480 struct community_list *list = output_arg;
11481
11482 if (!lcommunity_list_exact_match(
11483 bgp_attr_get_lcommunity(pi->attr),
11484 list))
11485 continue;
11486 }
11487 if (type == bgp_show_type_lcommunity_all) {
11488 if (!bgp_attr_get_lcommunity(pi->attr))
11489 continue;
11490 }
11491 if (type == bgp_show_type_dampend_paths
11492 || type == bgp_show_type_damp_neighbor) {
11493 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11494 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11495 continue;
11496 }
11497 if (type == bgp_show_type_self_originated) {
11498 if (pi->peer != bgp->peer_self)
11499 continue;
11500 }
11501
11502 if (!use_json && header) {
11503 vty_out(vty,
11504 "BGP table version is %" PRIu64
11505 ", local router ID is %pI4, vrf id ",
11506 table->version, &bgp->router_id);
11507 if (bgp->vrf_id == VRF_UNKNOWN)
11508 vty_out(vty, "%s", VRFID_NONE_STR);
11509 else
11510 vty_out(vty, "%u", bgp->vrf_id);
11511 vty_out(vty, "\n");
11512 vty_out(vty, "Default local pref %u, ",
11513 bgp->default_local_pref);
11514 vty_out(vty, "local AS ");
11515 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11516 &bgp->as);
11517 vty_out(vty, "\n");
11518 if (!detail_routes) {
11519 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11520 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11521 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11522 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11523 }
11524 if (type == bgp_show_type_dampend_paths
11525 || type == bgp_show_type_damp_neighbor)
11526 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11527 else if (type == bgp_show_type_flap_statistics
11528 || type == bgp_show_type_flap_neighbor)
11529 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11530 else if (!detail_routes)
11531 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11532 : BGP_SHOW_HEADER));
11533 header = false;
11534
11535 }
11536 if (rd != NULL && !display && !output_count) {
11537 if (!use_json)
11538 vty_out(vty,
11539 "Route Distinguisher: %s\n",
11540 rd);
11541 }
11542 if (type == bgp_show_type_dampend_paths
11543 || type == bgp_show_type_damp_neighbor)
11544 damp_route_vty_out(vty, dest_p, pi, display,
11545 AFI_IP, safi, use_json,
11546 json_paths);
11547 else if (type == bgp_show_type_flap_statistics
11548 || type == bgp_show_type_flap_neighbor)
11549 flap_route_vty_out(vty, dest_p, pi, display,
11550 AFI_IP, safi, use_json,
11551 json_paths);
11552 else {
11553 if (detail_routes || detail_json) {
11554 const struct prefix_rd *prd = NULL;
11555
11556 if (dest->pdest)
11557 prd = bgp_rd_from_dest(
11558 dest->pdest, safi);
11559
11560 if (!use_json)
11561 route_vty_out_detail_header(
11562 vty, bgp, dest,
11563 bgp_dest_get_prefix(
11564 dest),
11565 prd, table->afi, safi,
11566 NULL, false);
11567
11568 route_vty_out_detail(
11569 vty, bgp, dest, dest_p, pi,
11570 family2afi(dest_p->family),
11571 safi, RPKI_NOT_BEING_USED,
11572 json_paths);
11573 } else {
11574 route_vty_out(vty, dest_p, pi, display,
11575 safi, json_paths, wide);
11576 }
11577 }
11578 display++;
11579 }
11580
11581 if (display) {
11582 output_count++;
11583 if (!use_json)
11584 continue;
11585
11586 /* encode prefix */
11587 if (dest_p->family == AF_FLOWSPEC) {
11588 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11589
11590
11591 bgp_fs_nlri_get_string(
11592 (unsigned char *)
11593 dest_p->u.prefix_flowspec.ptr,
11594 dest_p->u.prefix_flowspec.prefixlen,
11595 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11596 family2afi(dest_p->u
11597 .prefix_flowspec.family));
11598 if (first)
11599 vty_out(vty, "\"%s/%d\": ", retstr,
11600 dest_p->u.prefix_flowspec
11601 .prefixlen);
11602 else
11603 vty_out(vty, ",\"%s/%d\": ", retstr,
11604 dest_p->u.prefix_flowspec
11605 .prefixlen);
11606 } else {
11607 if (first)
11608 vty_out(vty, "\"%pFX\": ", dest_p);
11609 else
11610 vty_out(vty, ",\"%pFX\": ", dest_p);
11611 }
11612
11613 if (json_detail_header && json_paths != NULL) {
11614 const struct prefix_rd *prd;
11615
11616 vty_out(vty, "{\n");
11617
11618 prd = bgp_rd_from_dest(dest, safi);
11619
11620 route_vty_out_detail_header(
11621 vty, bgp, dest,
11622 bgp_dest_get_prefix(dest), prd,
11623 table->afi, safi, json_paths, true);
11624
11625 vty_out(vty, "\"paths\": ");
11626 json_detail_header_used = true;
11627 }
11628
11629 /*
11630 * We are using no_pretty here because under
11631 * extremely high settings( say lots and lots of
11632 * routes with lots and lots of ways to reach
11633 * that route via different paths ) this can
11634 * save several minutes of output when FRR
11635 * is run on older cpu's or more underperforming
11636 * routers out there
11637 */
11638 vty_json_no_pretty(vty, json_paths);
11639
11640 if (json_detail_header_used)
11641 vty_out(vty, "} ");
11642
11643 json_paths = NULL;
11644 first = 0;
11645 } else
11646 json_object_free(json_paths);
11647 }
11648
11649 if (output_cum) {
11650 output_count += *output_cum;
11651 *output_cum = output_count;
11652 }
11653 if (total_cum) {
11654 total_count += *total_cum;
11655 *total_cum = total_count;
11656 }
11657 if (use_json) {
11658 if (rd) {
11659 vty_out(vty, " }%s ", (is_last ? "" : ","));
11660 }
11661 if (is_last) {
11662 unsigned long i;
11663 for (i = 0; i < *json_header_depth; ++i)
11664 vty_out(vty, " } ");
11665 if (!all)
11666 vty_out(vty, "\n");
11667 }
11668 } else {
11669 if (is_last) {
11670 /* No route is displayed */
11671 if (output_count == 0) {
11672 if (type == bgp_show_type_normal)
11673 vty_out(vty,
11674 "No BGP prefixes displayed, %ld exist\n",
11675 total_count);
11676 } else
11677 vty_out(vty,
11678 "\nDisplayed %ld routes and %ld total paths\n",
11679 output_count, total_count);
11680 }
11681 }
11682
11683 return CMD_SUCCESS;
11684 }
11685
11686 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11687 struct bgp_table *table, struct prefix_rd *prd_match,
11688 enum bgp_show_type type, void *output_arg,
11689 uint16_t show_flags)
11690 {
11691 struct bgp_dest *dest, *next;
11692 unsigned long output_cum = 0;
11693 unsigned long total_cum = 0;
11694 unsigned long json_header_depth = 0;
11695 struct bgp_table *itable;
11696 bool show_msg;
11697 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11698
11699 show_msg = (!use_json && type == bgp_show_type_normal);
11700
11701 for (dest = bgp_table_top(table); dest; dest = next) {
11702 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11703
11704 next = bgp_route_next(dest);
11705 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11706 continue;
11707
11708 itable = bgp_dest_get_bgp_table_info(dest);
11709 if (itable != NULL) {
11710 struct prefix_rd prd;
11711 char rd[RD_ADDRSTRLEN];
11712
11713 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11714 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11715 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11716 rd, next == NULL, &output_cum,
11717 &total_cum, &json_header_depth,
11718 show_flags, RPKI_NOT_BEING_USED);
11719 if (next == NULL)
11720 show_msg = false;
11721 }
11722 }
11723 if (show_msg) {
11724 if (output_cum == 0)
11725 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11726 total_cum);
11727 else
11728 vty_out(vty,
11729 "\nDisplayed %ld routes and %ld total paths\n",
11730 output_cum, total_cum);
11731 } else {
11732 if (use_json && output_cum == 0)
11733 vty_out(vty, "{}\n");
11734 }
11735 return CMD_SUCCESS;
11736 }
11737
11738 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11739 enum bgp_show_type type, void *output_arg,
11740 uint16_t show_flags, enum rpki_states rpki_target_state)
11741 {
11742 struct bgp_table *table;
11743 unsigned long json_header_depth = 0;
11744 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11745
11746 if (bgp == NULL) {
11747 bgp = bgp_get_default();
11748 }
11749
11750 if (bgp == NULL) {
11751 if (!use_json)
11752 vty_out(vty, "No BGP process is configured\n");
11753 else
11754 vty_out(vty, "{}\n");
11755 return CMD_WARNING;
11756 }
11757
11758 /* Labeled-unicast routes live in the unicast table. */
11759 if (safi == SAFI_LABELED_UNICAST)
11760 safi = SAFI_UNICAST;
11761
11762 table = bgp->rib[afi][safi];
11763 /* use MPLS and ENCAP specific shows until they are merged */
11764 if (safi == SAFI_MPLS_VPN) {
11765 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11766 output_arg, show_flags);
11767 }
11768
11769 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11770 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11771 output_arg, use_json,
11772 1, NULL, NULL);
11773 }
11774
11775 if (safi == SAFI_EVPN)
11776 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11777
11778 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11779 NULL, NULL, &json_header_depth, show_flags,
11780 rpki_target_state);
11781 }
11782
11783 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11784 safi_t safi, uint16_t show_flags)
11785 {
11786 struct listnode *node, *nnode;
11787 struct bgp *bgp;
11788 int is_first = 1;
11789 bool route_output = false;
11790 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11791
11792 if (use_json)
11793 vty_out(vty, "{\n");
11794
11795 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11796 route_output = true;
11797 if (use_json) {
11798 if (!is_first)
11799 vty_out(vty, ",\n");
11800 else
11801 is_first = 0;
11802
11803 vty_out(vty, "\"%s\":",
11804 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11805 ? VRF_DEFAULT_NAME
11806 : bgp->name);
11807 } else {
11808 vty_out(vty, "\nInstance %s:\n",
11809 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11810 ? VRF_DEFAULT_NAME
11811 : bgp->name);
11812 }
11813 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11814 show_flags, RPKI_NOT_BEING_USED);
11815 }
11816
11817 if (use_json)
11818 vty_out(vty, "}\n");
11819 else if (!route_output)
11820 vty_out(vty, "%% BGP instance not found\n");
11821 }
11822
11823 /* Header of detailed BGP route information */
11824 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11825 struct bgp_dest *dest, const struct prefix *p,
11826 const struct prefix_rd *prd, afi_t afi,
11827 safi_t safi, json_object *json,
11828 bool incremental_print)
11829 {
11830 struct bgp_path_info *pi;
11831 struct peer *peer;
11832 struct listnode *node, *nnode;
11833 char buf1[RD_ADDRSTRLEN];
11834 int count = 0;
11835 int best = 0;
11836 int suppress = 0;
11837 int accept_own = 0;
11838 int route_filter_translated_v4 = 0;
11839 int route_filter_v4 = 0;
11840 int route_filter_translated_v6 = 0;
11841 int route_filter_v6 = 0;
11842 int llgr_stale = 0;
11843 int no_llgr = 0;
11844 int accept_own_nexthop = 0;
11845 int blackhole = 0;
11846 int no_export = 0;
11847 int no_advertise = 0;
11848 int local_as = 0;
11849 int no_peer = 0;
11850 int first = 1;
11851 int has_valid_label = 0;
11852 mpls_label_t label = 0;
11853 json_object *json_adv_to = NULL;
11854 uint32_t ttl = 0;
11855 uint32_t bos = 0;
11856 uint32_t exp = 0;
11857
11858 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11859
11860 has_valid_label = bgp_is_valid_label(&label);
11861
11862 if (safi == SAFI_EVPN) {
11863 if (!json) {
11864 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11865 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11866 bgp->asnotation)
11867 : "",
11868 prd ? ":" : "", (struct prefix_evpn *)p);
11869 } else {
11870 json_object_string_add(
11871 json, "rd",
11872 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11873 bgp->asnotation)
11874 : "");
11875 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11876 }
11877 } else {
11878 if (!json) {
11879 vty_out(vty,
11880 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11881 "\n",
11882 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11883 ? prefix_rd2str(prd, buf1,
11884 sizeof(buf1),
11885 bgp->asnotation)
11886 : ""),
11887 safi == SAFI_MPLS_VPN ? ":" : "", p,
11888 dest->version);
11889
11890 } else {
11891 if (incremental_print) {
11892 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11893 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11894 dest->version);
11895 } else {
11896 json_object_string_addf(json, "prefix", "%pFX",
11897 p);
11898 json_object_int_add(json, "version",
11899 dest->version);
11900 }
11901 }
11902 }
11903
11904 if (has_valid_label) {
11905 if (json) {
11906 if (incremental_print)
11907 vty_out(vty, "\"localLabel\": \"%u\",\n",
11908 label);
11909 else
11910 json_object_int_add(json, "localLabel", label);
11911 } else
11912 vty_out(vty, "Local label: %d\n", label);
11913 }
11914
11915 if (!json)
11916 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11917 vty_out(vty, "not allocated\n");
11918
11919 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11920 struct community *picomm = NULL;
11921
11922 picomm = bgp_attr_get_community(pi->attr);
11923
11924 count++;
11925 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11926 best = count;
11927 if (bgp_path_suppressed(pi))
11928 suppress = 1;
11929
11930 if (!picomm)
11931 continue;
11932
11933 no_advertise += community_include(
11934 picomm, COMMUNITY_NO_ADVERTISE);
11935 no_export +=
11936 community_include(picomm, COMMUNITY_NO_EXPORT);
11937 local_as +=
11938 community_include(picomm, COMMUNITY_LOCAL_AS);
11939 accept_own +=
11940 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11941 route_filter_translated_v4 += community_include(
11942 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11943 route_filter_translated_v6 += community_include(
11944 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11945 route_filter_v4 += community_include(
11946 picomm, COMMUNITY_ROUTE_FILTER_v4);
11947 route_filter_v6 += community_include(
11948 picomm, COMMUNITY_ROUTE_FILTER_v6);
11949 llgr_stale +=
11950 community_include(picomm, COMMUNITY_LLGR_STALE);
11951 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11952 accept_own_nexthop += community_include(
11953 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11954 blackhole +=
11955 community_include(picomm, COMMUNITY_BLACKHOLE);
11956 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11957 }
11958 }
11959
11960 if (!json) {
11961 vty_out(vty, "Paths: (%d available", count);
11962 if (best) {
11963 vty_out(vty, ", best #%d", best);
11964 if (safi == SAFI_UNICAST) {
11965 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11966 vty_out(vty, ", table %s",
11967 VRF_DEFAULT_NAME);
11968 else
11969 vty_out(vty, ", vrf %s",
11970 bgp->name);
11971 }
11972 } else
11973 vty_out(vty, ", no best path");
11974
11975 if (accept_own)
11976 vty_out(vty,
11977 ", accept own local route exported and imported in different VRF");
11978 else if (route_filter_translated_v4)
11979 vty_out(vty,
11980 ", mark translated RTs for VPNv4 route filtering");
11981 else if (route_filter_v4)
11982 vty_out(vty,
11983 ", attach RT as-is for VPNv4 route filtering");
11984 else if (route_filter_translated_v6)
11985 vty_out(vty,
11986 ", mark translated RTs for VPNv6 route filtering");
11987 else if (route_filter_v6)
11988 vty_out(vty,
11989 ", attach RT as-is for VPNv6 route filtering");
11990 else if (llgr_stale)
11991 vty_out(vty,
11992 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11993 else if (no_llgr)
11994 vty_out(vty,
11995 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11996 else if (accept_own_nexthop)
11997 vty_out(vty,
11998 ", accept local nexthop");
11999 else if (blackhole)
12000 vty_out(vty, ", inform peer to blackhole prefix");
12001 else if (no_export)
12002 vty_out(vty, ", not advertised to EBGP peer");
12003 else if (no_advertise)
12004 vty_out(vty, ", not advertised to any peer");
12005 else if (local_as)
12006 vty_out(vty, ", not advertised outside local AS");
12007 else if (no_peer)
12008 vty_out(vty,
12009 ", inform EBGP peer not to advertise to their EBGP peers");
12010
12011 if (suppress)
12012 vty_out(vty,
12013 ", Advertisements suppressed by an aggregate.");
12014 vty_out(vty, ")\n");
12015 }
12016
12017 /* If we are not using addpath then we can display Advertised to and
12018 * that will
12019 * show what peers we advertised the bestpath to. If we are using
12020 * addpath
12021 * though then we must display Advertised to on a path-by-path basis. */
12022 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12023 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12024 if (bgp_adj_out_lookup(peer, dest, 0)) {
12025 if (json && !json_adv_to)
12026 json_adv_to = json_object_new_object();
12027
12028 route_vty_out_advertised_to(
12029 vty, peer, &first,
12030 " Advertised to non peer-group peers:\n ",
12031 json_adv_to);
12032 }
12033 }
12034
12035 if (json && json_adv_to) {
12036 if (incremental_print) {
12037 vty_out(vty, "\"advertisedTo\": ");
12038 vty_json(vty, json_adv_to);
12039 vty_out(vty, ",");
12040 } else
12041 json_object_object_add(json, "advertisedTo",
12042 json_adv_to);
12043 } else {
12044 if (!json && first)
12045 vty_out(vty, " Not advertised to any peer");
12046 vty_out(vty, "\n");
12047 }
12048 }
12049 }
12050
12051 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12052 struct bgp_dest *bgp_node, struct vty *vty,
12053 struct bgp *bgp, afi_t afi, safi_t safi,
12054 json_object *json, enum bgp_path_type pathtype,
12055 int *display, enum rpki_states rpki_target_state)
12056 {
12057 struct bgp_path_info *pi;
12058 int header = 1;
12059 json_object *json_header = NULL;
12060 json_object *json_paths = NULL;
12061 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12062
12063 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12064 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12065
12066 if (p->family == AF_INET || p->family == AF_INET6)
12067 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12068 pi->peer, pi->attr, p);
12069
12070 if (rpki_target_state != RPKI_NOT_BEING_USED
12071 && rpki_curr_state != rpki_target_state)
12072 continue;
12073
12074 if (json && !json_paths) {
12075 /* Instantiate json_paths only if path is valid */
12076 json_paths = json_object_new_array();
12077 if (pfx_rd)
12078 json_header = json_object_new_object();
12079 else
12080 json_header = json;
12081 }
12082
12083 if (header) {
12084 route_vty_out_detail_header(
12085 vty, bgp, bgp_node,
12086 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12087 safi, json_header, false);
12088 header = 0;
12089 }
12090 (*display)++;
12091
12092 if (pathtype == BGP_PATH_SHOW_ALL
12093 || (pathtype == BGP_PATH_SHOW_BESTPATH
12094 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12095 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12096 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12097 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12098 route_vty_out_detail(vty, bgp, bgp_node,
12099 bgp_dest_get_prefix(bgp_node), pi,
12100 AFI_IP, safi, rpki_curr_state,
12101 json_paths);
12102 }
12103
12104 if (json && json_paths) {
12105 json_object_object_add(json_header, "paths", json_paths);
12106
12107 if (pfx_rd)
12108 json_object_object_addf(
12109 json, json_header,
12110 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12111 }
12112 }
12113
12114 /*
12115 * Return rd based on safi
12116 */
12117 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12118 safi_t safi)
12119 {
12120 switch (safi) {
12121 case SAFI_MPLS_VPN:
12122 case SAFI_ENCAP:
12123 case SAFI_EVPN:
12124 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12125 case SAFI_UNSPEC:
12126 case SAFI_UNICAST:
12127 case SAFI_MULTICAST:
12128 case SAFI_LABELED_UNICAST:
12129 case SAFI_FLOWSPEC:
12130 case SAFI_MAX:
12131 return NULL;
12132 }
12133
12134 assert(!"Reached end of function when we were not expecting it");
12135 }
12136
12137 /* Display specified route of BGP table. */
12138 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12139 struct bgp_table *rib, const char *ip_str,
12140 afi_t afi, safi_t safi,
12141 enum rpki_states rpki_target_state,
12142 struct prefix_rd *prd, int prefix_check,
12143 enum bgp_path_type pathtype, bool use_json)
12144 {
12145 int ret;
12146 int display = 0;
12147 struct prefix match;
12148 struct bgp_dest *dest;
12149 struct bgp_dest *rm;
12150 struct bgp_table *table;
12151 json_object *json = NULL;
12152 json_object *json_paths = NULL;
12153
12154 /* Check IP address argument. */
12155 ret = str2prefix(ip_str, &match);
12156 if (!ret) {
12157 vty_out(vty, "address is malformed\n");
12158 return CMD_WARNING;
12159 }
12160
12161 match.family = afi2family(afi);
12162
12163 if (use_json)
12164 json = json_object_new_object();
12165
12166 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12167 for (dest = bgp_table_top(rib); dest;
12168 dest = bgp_route_next(dest)) {
12169 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12170
12171 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12172 continue;
12173 table = bgp_dest_get_bgp_table_info(dest);
12174 if (!table)
12175 continue;
12176
12177 rm = bgp_node_match(table, &match);
12178 if (rm == NULL)
12179 continue;
12180
12181 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12182 if (prefix_check
12183 && rm_p->prefixlen != match.prefixlen) {
12184 bgp_dest_unlock_node(rm);
12185 continue;
12186 }
12187
12188 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12189 bgp, afi, safi, json, pathtype,
12190 &display, rpki_target_state);
12191
12192 bgp_dest_unlock_node(rm);
12193 }
12194 } else if (safi == SAFI_EVPN) {
12195 struct bgp_dest *longest_pfx;
12196 bool is_exact_pfxlen_match = false;
12197
12198 for (dest = bgp_table_top(rib); dest;
12199 dest = bgp_route_next(dest)) {
12200 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12201
12202 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12203 continue;
12204 table = bgp_dest_get_bgp_table_info(dest);
12205 if (!table)
12206 continue;
12207
12208 longest_pfx = NULL;
12209 is_exact_pfxlen_match = false;
12210 /*
12211 * Search through all the prefixes for a match. The
12212 * pfx's are enumerated in ascending order of pfxlens.
12213 * So, the last pfx match is the longest match. Set
12214 * is_exact_pfxlen_match when we get exact pfxlen match
12215 */
12216 for (rm = bgp_table_top(table); rm;
12217 rm = bgp_route_next(rm)) {
12218 const struct prefix *rm_p =
12219 bgp_dest_get_prefix(rm);
12220 /*
12221 * Get prefixlen of the ip-prefix within type5
12222 * evpn route
12223 */
12224 if (evpn_type5_prefix_match(rm_p, &match)
12225 && rm->info) {
12226 longest_pfx = rm;
12227 int type5_pfxlen =
12228 bgp_evpn_get_type5_prefixlen(
12229 rm_p);
12230 if (type5_pfxlen == match.prefixlen) {
12231 is_exact_pfxlen_match = true;
12232 bgp_dest_unlock_node(rm);
12233 break;
12234 }
12235 }
12236 }
12237
12238 if (!longest_pfx)
12239 continue;
12240
12241 if (prefix_check && !is_exact_pfxlen_match)
12242 continue;
12243
12244 rm = longest_pfx;
12245 bgp_dest_lock_node(rm);
12246
12247 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12248 bgp, afi, safi, json, pathtype,
12249 &display, rpki_target_state);
12250
12251 bgp_dest_unlock_node(rm);
12252 }
12253 } else if (safi == SAFI_FLOWSPEC) {
12254 if (use_json)
12255 json_paths = json_object_new_array();
12256
12257 display = bgp_flowspec_display_match_per_ip(afi, rib,
12258 &match, prefix_check,
12259 vty,
12260 use_json,
12261 json_paths);
12262 if (use_json) {
12263 if (display)
12264 json_object_object_add(json, "paths",
12265 json_paths);
12266 else
12267 json_object_free(json_paths);
12268 }
12269 } else {
12270 dest = bgp_node_match(rib, &match);
12271 if (dest != NULL) {
12272 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12273 if (!prefix_check
12274 || dest_p->prefixlen == match.prefixlen) {
12275 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12276 safi, json, pathtype,
12277 &display, rpki_target_state);
12278 }
12279
12280 bgp_dest_unlock_node(dest);
12281 }
12282 }
12283
12284 if (use_json) {
12285 vty_json(vty, json);
12286 } else {
12287 if (!display) {
12288 vty_out(vty, "%% Network not in table\n");
12289 return CMD_WARNING;
12290 }
12291 }
12292
12293 return CMD_SUCCESS;
12294 }
12295
12296 /* Display specified route of Main RIB */
12297 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12298 afi_t afi, safi_t safi, struct prefix_rd *prd,
12299 int prefix_check, enum bgp_path_type pathtype,
12300 enum rpki_states rpki_target_state, bool use_json)
12301 {
12302 if (!bgp) {
12303 bgp = bgp_get_default();
12304 if (!bgp) {
12305 if (!use_json)
12306 vty_out(vty, "No BGP process is configured\n");
12307 else
12308 vty_out(vty, "{}\n");
12309 return CMD_WARNING;
12310 }
12311 }
12312
12313 /* labeled-unicast routes live in the unicast table */
12314 if (safi == SAFI_LABELED_UNICAST)
12315 safi = SAFI_UNICAST;
12316
12317 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12318 afi, safi, rpki_target_state, prd,
12319 prefix_check, pathtype, use_json);
12320 }
12321
12322 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12323 struct cmd_token **argv, bool exact, afi_t afi,
12324 safi_t safi, bool uj)
12325 {
12326 struct lcommunity *lcom;
12327 struct buffer *b;
12328 int i;
12329 char *str;
12330 int first = 0;
12331 uint16_t show_flags = 0;
12332 int ret;
12333
12334 if (uj)
12335 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12336
12337 b = buffer_new(1024);
12338 for (i = 0; i < argc; i++) {
12339 if (first)
12340 buffer_putc(b, ' ');
12341 else {
12342 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12343 first = 1;
12344 buffer_putstr(b, argv[i]->arg);
12345 }
12346 }
12347 }
12348 buffer_putc(b, '\0');
12349
12350 str = buffer_getstr(b);
12351 buffer_free(b);
12352
12353 lcom = lcommunity_str2com(str);
12354 XFREE(MTYPE_TMP, str);
12355 if (!lcom) {
12356 vty_out(vty, "%% Large-community malformed\n");
12357 return CMD_WARNING;
12358 }
12359
12360 ret = bgp_show(vty, bgp, afi, safi,
12361 (exact ? bgp_show_type_lcommunity_exact
12362 : bgp_show_type_lcommunity),
12363 lcom, show_flags, RPKI_NOT_BEING_USED);
12364
12365 lcommunity_free(&lcom);
12366 return ret;
12367 }
12368
12369 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12370 const char *lcom, bool exact, afi_t afi,
12371 safi_t safi, bool uj)
12372 {
12373 struct community_list *list;
12374 uint16_t show_flags = 0;
12375
12376 if (uj)
12377 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12378
12379
12380 list = community_list_lookup(bgp_clist, lcom, 0,
12381 LARGE_COMMUNITY_LIST_MASTER);
12382 if (list == NULL) {
12383 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12384 lcom);
12385 return CMD_WARNING;
12386 }
12387
12388 return bgp_show(vty, bgp, afi, safi,
12389 (exact ? bgp_show_type_lcommunity_list_exact
12390 : bgp_show_type_lcommunity_list),
12391 list, show_flags, RPKI_NOT_BEING_USED);
12392 }
12393
12394 DEFUN (show_ip_bgp_large_community_list,
12395 show_ip_bgp_large_community_list_cmd,
12396 "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]",
12397 SHOW_STR
12398 IP_STR
12399 BGP_STR
12400 BGP_INSTANCE_HELP_STR
12401 BGP_AFI_HELP_STR
12402 BGP_SAFI_WITH_LABEL_HELP_STR
12403 "Display routes matching the large-community-list\n"
12404 "large-community-list number\n"
12405 "large-community-list name\n"
12406 "Exact match of the large-communities\n"
12407 JSON_STR)
12408 {
12409 afi_t afi = AFI_IP6;
12410 safi_t safi = SAFI_UNICAST;
12411 int idx = 0;
12412 bool exact_match = 0;
12413 struct bgp *bgp = NULL;
12414 bool uj = use_json(argc, argv);
12415
12416 if (uj)
12417 argc--;
12418
12419 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12420 &bgp, uj);
12421 if (!idx)
12422 return CMD_WARNING;
12423
12424 argv_find(argv, argc, "large-community-list", &idx);
12425
12426 const char *clist_number_or_name = argv[++idx]->arg;
12427
12428 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12429 exact_match = 1;
12430
12431 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12432 exact_match, afi, safi, uj);
12433 }
12434 DEFUN (show_ip_bgp_large_community,
12435 show_ip_bgp_large_community_cmd,
12436 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12437 SHOW_STR
12438 IP_STR
12439 BGP_STR
12440 BGP_INSTANCE_HELP_STR
12441 BGP_AFI_HELP_STR
12442 BGP_SAFI_WITH_LABEL_HELP_STR
12443 "Display routes matching the large-communities\n"
12444 "List of large-community numbers\n"
12445 "Exact match of the large-communities\n"
12446 JSON_STR)
12447 {
12448 afi_t afi = AFI_IP6;
12449 safi_t safi = SAFI_UNICAST;
12450 int idx = 0;
12451 bool exact_match = 0;
12452 struct bgp *bgp = NULL;
12453 bool uj = use_json(argc, argv);
12454 uint16_t show_flags = 0;
12455
12456 if (uj) {
12457 argc--;
12458 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12459 }
12460
12461 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12462 &bgp, uj);
12463 if (!idx)
12464 return CMD_WARNING;
12465
12466 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12467 if (argv_find(argv, argc, "exact-match", &idx)) {
12468 argc--;
12469 exact_match = 1;
12470 }
12471 return bgp_show_lcommunity(vty, bgp, argc, argv,
12472 exact_match, afi, safi, uj);
12473 } else
12474 return bgp_show(vty, bgp, afi, safi,
12475 bgp_show_type_lcommunity_all, NULL, show_flags,
12476 RPKI_NOT_BEING_USED);
12477 }
12478
12479 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12480 safi_t safi, struct json_object *json_array);
12481 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12482 safi_t safi, struct json_object *json);
12483
12484
12485 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12486 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12487 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12488 "Display number of prefixes for all afi/safi\n" JSON_STR)
12489 {
12490 bool uj = use_json(argc, argv);
12491 struct bgp *bgp = NULL;
12492 safi_t safi = SAFI_UNICAST;
12493 afi_t afi = AFI_IP6;
12494 int idx = 0;
12495 struct json_object *json_all = NULL;
12496 struct json_object *json_afi_safi = NULL;
12497
12498 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12499 &bgp, false);
12500 if (!idx)
12501 return CMD_WARNING;
12502
12503 if (uj)
12504 json_all = json_object_new_object();
12505
12506 FOREACH_AFI_SAFI (afi, safi) {
12507 /*
12508 * So limit output to those afi/safi pairs that
12509 * actually have something interesting in them
12510 */
12511 if (strmatch(get_afi_safi_str(afi, safi, true),
12512 "Unknown")) {
12513 continue;
12514 }
12515 if (uj) {
12516 json_afi_safi = json_object_new_array();
12517 json_object_object_add(
12518 json_all,
12519 get_afi_safi_str(afi, safi, true),
12520 json_afi_safi);
12521 } else {
12522 json_afi_safi = NULL;
12523 }
12524
12525 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12526 }
12527
12528 if (uj)
12529 vty_json(vty, json_all);
12530
12531 return CMD_SUCCESS;
12532 }
12533
12534 /* BGP route print out function without JSON */
12535 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12536 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12537 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12538 SHOW_STR
12539 IP_STR
12540 BGP_STR
12541 BGP_INSTANCE_HELP_STR
12542 L2VPN_HELP_STR
12543 EVPN_HELP_STR
12544 "BGP RIB advertisement statistics\n"
12545 JSON_STR)
12546 {
12547 afi_t afi = AFI_IP6;
12548 safi_t safi = SAFI_UNICAST;
12549 struct bgp *bgp = NULL;
12550 int idx = 0, ret;
12551 bool uj = use_json(argc, argv);
12552 struct json_object *json_afi_safi = NULL, *json = NULL;
12553
12554 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12555 &bgp, false);
12556 if (!idx)
12557 return CMD_WARNING;
12558
12559 if (uj)
12560 json_afi_safi = json_object_new_array();
12561 else
12562 json_afi_safi = NULL;
12563
12564 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12565
12566 if (uj) {
12567 json = json_object_new_object();
12568 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12569 json_afi_safi);
12570 vty_json(vty, json);
12571 }
12572 return ret;
12573 }
12574
12575 /* BGP route print out function without JSON */
12576 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12577 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12578 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12579 "]]\
12580 statistics [json]",
12581 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12582 BGP_SAFI_WITH_LABEL_HELP_STR
12583 "BGP RIB advertisement statistics\n" JSON_STR)
12584 {
12585 afi_t afi = AFI_IP6;
12586 safi_t safi = SAFI_UNICAST;
12587 struct bgp *bgp = NULL;
12588 int idx = 0, ret;
12589 bool uj = use_json(argc, argv);
12590 struct json_object *json_afi_safi = NULL, *json = NULL;
12591
12592 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12593 &bgp, false);
12594 if (!idx)
12595 return CMD_WARNING;
12596
12597 if (uj)
12598 json_afi_safi = json_object_new_array();
12599 else
12600 json_afi_safi = NULL;
12601
12602 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12603
12604 if (uj) {
12605 json = json_object_new_object();
12606 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12607 json_afi_safi);
12608 vty_json(vty, json);
12609 }
12610 return ret;
12611 }
12612
12613 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12614 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12615 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12616 "]] [all$all] dampening parameters [json]",
12617 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12618 BGP_SAFI_WITH_LABEL_HELP_STR
12619 "Display the entries for all address families\n"
12620 "Display detailed information about dampening\n"
12621 "Display detail of configured dampening parameters\n"
12622 JSON_STR)
12623 {
12624 afi_t afi = AFI_IP6;
12625 safi_t safi = SAFI_UNICAST;
12626 struct bgp *bgp = NULL;
12627 int idx = 0;
12628 uint16_t show_flags = 0;
12629 bool uj = use_json(argc, argv);
12630
12631 if (uj) {
12632 argc--;
12633 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12634 }
12635
12636 /* [<ipv4|ipv6> [all]] */
12637 if (all) {
12638 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12639 if (argv_find(argv, argc, "ipv4", &idx))
12640 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12641
12642 if (argv_find(argv, argc, "ipv6", &idx))
12643 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12644 }
12645
12646 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12647 &bgp, false);
12648 if (!idx)
12649 return CMD_WARNING;
12650
12651 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12652 }
12653
12654 /* BGP route print out function */
12655 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12656 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12657 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12658 "]]\
12659 [all$all]\
12660 [cidr-only\
12661 |dampening <flap-statistics|dampened-paths>\
12662 |community [AA:NN|local-AS|no-advertise|no-export\
12663 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12664 |accept-own|accept-own-nexthop|route-filter-v6\
12665 |route-filter-v4|route-filter-translated-v6\
12666 |route-filter-translated-v4] [exact-match]\
12667 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12668 |filter-list AS_PATH_FILTER_NAME\
12669 |prefix-list WORD\
12670 |access-list ACCESSLIST_NAME\
12671 |route-map RMAP_NAME\
12672 |rpki <invalid|valid|notfound>\
12673 |version (1-4294967295)\
12674 |alias ALIAS_NAME\
12675 |A.B.C.D/M longer-prefixes\
12676 |X:X::X:X/M longer-prefixes\
12677 |"BGP_SELF_ORIG_CMD_STR"\
12678 |detail-routes$detail_routes\
12679 ] [json$uj [detail$detail_json] | wide$wide]",
12680 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12681 BGP_SAFI_WITH_LABEL_HELP_STR
12682 "Display the entries for all address families\n"
12683 "Display only routes with non-natural netmasks\n"
12684 "Display detailed information about dampening\n"
12685 "Display flap statistics of routes\n"
12686 "Display paths suppressed due to dampening\n"
12687 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12688 "Do not send outside local AS (well-known community)\n"
12689 "Do not advertise to any peer (well-known community)\n"
12690 "Do not export to next AS (well-known community)\n"
12691 "Graceful shutdown (well-known community)\n"
12692 "Do not export to any peer (well-known community)\n"
12693 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12694 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12695 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12696 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12697 "Should accept VPN route with local nexthop (well-known community)\n"
12698 "RT VPNv6 route filtering (well-known community)\n"
12699 "RT VPNv4 route filtering (well-known community)\n"
12700 "RT translated VPNv6 route filtering (well-known community)\n"
12701 "RT translated VPNv4 route filtering (well-known community)\n"
12702 "Exact match of the communities\n"
12703 "Community-list number\n"
12704 "Community-list name\n"
12705 "Display routes matching the community-list\n"
12706 "Exact match of the communities\n"
12707 "Display routes conforming to the filter-list\n"
12708 "Regular expression access list name\n"
12709 "Display routes conforming to the prefix-list\n"
12710 "Prefix-list name\n"
12711 "Display routes conforming to the access-list\n"
12712 "Access-list name\n"
12713 "Display routes matching the route-map\n"
12714 "A route-map to match on\n"
12715 "RPKI route types\n"
12716 "A valid path as determined by rpki\n"
12717 "A invalid path as determined by rpki\n"
12718 "A path that has no rpki data\n"
12719 "Display prefixes with matching version numbers\n"
12720 "Version number and above\n"
12721 "Display prefixes with matching BGP community alias\n"
12722 "BGP community alias\n"
12723 "IPv4 prefix\n"
12724 "Display route and more specific routes\n"
12725 "IPv6 prefix\n"
12726 "Display route and more specific routes\n"
12727 BGP_SELF_ORIG_HELP_STR
12728 "Display detailed version of all routes\n"
12729 JSON_STR
12730 "Display detailed version of JSON output\n"
12731 "Increase table width for longer prefixes\n")
12732 {
12733 afi_t afi = AFI_IP6;
12734 safi_t safi = SAFI_UNICAST;
12735 enum bgp_show_type sh_type = bgp_show_type_normal;
12736 void *output_arg = NULL;
12737 struct bgp *bgp = NULL;
12738 int idx = 0;
12739 int exact_match = 0;
12740 char *community = NULL;
12741 bool first = true;
12742 uint16_t show_flags = 0;
12743 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12744 struct prefix p;
12745
12746 if (uj) {
12747 argc--;
12748 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12749 }
12750
12751 if (detail_json)
12752 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12753
12754 if (detail_routes)
12755 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12756
12757 /* [<ipv4|ipv6> [all]] */
12758 if (all) {
12759 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12760
12761 if (argv_find(argv, argc, "ipv4", &idx))
12762 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12763
12764 if (argv_find(argv, argc, "ipv6", &idx))
12765 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12766 }
12767
12768 if (wide)
12769 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12770
12771 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12772 &bgp, uj);
12773 if (!idx)
12774 return CMD_WARNING;
12775
12776 if (argv_find(argv, argc, "cidr-only", &idx))
12777 sh_type = bgp_show_type_cidr_only;
12778
12779 if (argv_find(argv, argc, "dampening", &idx)) {
12780 if (argv_find(argv, argc, "dampened-paths", &idx))
12781 sh_type = bgp_show_type_dampend_paths;
12782 else if (argv_find(argv, argc, "flap-statistics", &idx))
12783 sh_type = bgp_show_type_flap_statistics;
12784 }
12785
12786 if (argv_find(argv, argc, "community", &idx)) {
12787 char *maybecomm = NULL;
12788
12789 if (idx + 1 < argc) {
12790 if (argv[idx + 1]->type == VARIABLE_TKN)
12791 maybecomm = argv[idx + 1]->arg;
12792 else
12793 maybecomm = argv[idx + 1]->text;
12794 }
12795
12796 if (maybecomm && !strmatch(maybecomm, "json")
12797 && !strmatch(maybecomm, "exact-match"))
12798 community = maybecomm;
12799
12800 if (argv_find(argv, argc, "exact-match", &idx))
12801 exact_match = 1;
12802
12803 if (!community)
12804 sh_type = bgp_show_type_community_all;
12805 }
12806
12807 if (argv_find(argv, argc, "community-list", &idx)) {
12808 const char *clist_number_or_name = argv[++idx]->arg;
12809 struct community_list *list;
12810
12811 if (argv_find(argv, argc, "exact-match", &idx))
12812 exact_match = 1;
12813
12814 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12815 COMMUNITY_LIST_MASTER);
12816 if (list == NULL) {
12817 vty_out(vty, "%% %s community-list not found\n",
12818 clist_number_or_name);
12819 return CMD_WARNING;
12820 }
12821
12822 if (exact_match)
12823 sh_type = bgp_show_type_community_list_exact;
12824 else
12825 sh_type = bgp_show_type_community_list;
12826 output_arg = list;
12827 }
12828
12829 if (argv_find(argv, argc, "filter-list", &idx)) {
12830 const char *filter = argv[++idx]->arg;
12831 struct as_list *as_list;
12832
12833 as_list = as_list_lookup(filter);
12834 if (as_list == NULL) {
12835 vty_out(vty, "%% %s AS-path access-list not found\n",
12836 filter);
12837 return CMD_WARNING;
12838 }
12839
12840 sh_type = bgp_show_type_filter_list;
12841 output_arg = as_list;
12842 }
12843
12844 if (argv_find(argv, argc, "prefix-list", &idx)) {
12845 const char *prefix_list_str = argv[++idx]->arg;
12846 struct prefix_list *plist;
12847
12848 plist = prefix_list_lookup(afi, prefix_list_str);
12849 if (plist == NULL) {
12850 vty_out(vty, "%% %s prefix-list not found\n",
12851 prefix_list_str);
12852 return CMD_WARNING;
12853 }
12854
12855 sh_type = bgp_show_type_prefix_list;
12856 output_arg = plist;
12857 }
12858
12859 if (argv_find(argv, argc, "access-list", &idx)) {
12860 const char *access_list_str = argv[++idx]->arg;
12861 struct access_list *alist;
12862
12863 alist = access_list_lookup(afi, access_list_str);
12864 if (!alist) {
12865 vty_out(vty, "%% %s access-list not found\n",
12866 access_list_str);
12867 return CMD_WARNING;
12868 }
12869
12870 sh_type = bgp_show_type_access_list;
12871 output_arg = alist;
12872 }
12873
12874 if (argv_find(argv, argc, "route-map", &idx)) {
12875 const char *rmap_str = argv[++idx]->arg;
12876 struct route_map *rmap;
12877
12878 rmap = route_map_lookup_by_name(rmap_str);
12879 if (!rmap) {
12880 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12881 return CMD_WARNING;
12882 }
12883
12884 sh_type = bgp_show_type_route_map;
12885 output_arg = rmap;
12886 }
12887
12888 if (argv_find(argv, argc, "rpki", &idx)) {
12889 sh_type = bgp_show_type_rpki;
12890 if (argv_find(argv, argc, "valid", &idx))
12891 rpki_target_state = RPKI_VALID;
12892 else if (argv_find(argv, argc, "invalid", &idx))
12893 rpki_target_state = RPKI_INVALID;
12894 }
12895
12896 /* Display prefixes with matching version numbers */
12897 if (argv_find(argv, argc, "version", &idx)) {
12898 sh_type = bgp_show_type_prefix_version;
12899 output_arg = argv[idx + 1]->arg;
12900 }
12901
12902 /* Display prefixes with matching BGP community alias */
12903 if (argv_find(argv, argc, "alias", &idx)) {
12904 sh_type = bgp_show_type_community_alias;
12905 output_arg = argv[idx + 1]->arg;
12906 }
12907
12908 /* prefix-longer */
12909 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12910 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12911 const char *prefix_str = argv[idx]->arg;
12912
12913 if (!str2prefix(prefix_str, &p)) {
12914 vty_out(vty, "%% Malformed Prefix\n");
12915 return CMD_WARNING;
12916 }
12917
12918 sh_type = bgp_show_type_prefix_longer;
12919 output_arg = &p;
12920 }
12921
12922 /* self originated only */
12923 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12924 sh_type = bgp_show_type_self_originated;
12925
12926 if (!all) {
12927 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12928 if (community)
12929 return bgp_show_community(vty, bgp, community,
12930 exact_match, afi, safi,
12931 show_flags);
12932 else
12933 return bgp_show(vty, bgp, afi, safi, sh_type,
12934 output_arg, show_flags,
12935 rpki_target_state);
12936 } else {
12937 struct listnode *node;
12938 struct bgp *abgp;
12939 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12940 * AFI_IP6 */
12941
12942 if (uj)
12943 vty_out(vty, "{\n");
12944
12945 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12946 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12947 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12948 ? AFI_IP
12949 : AFI_IP6;
12950 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12951 FOREACH_SAFI (safi) {
12952 if (!bgp_afi_safi_peer_exists(abgp, afi,
12953 safi))
12954 continue;
12955
12956 if (uj) {
12957 if (first)
12958 first = false;
12959 else
12960 vty_out(vty, ",\n");
12961 vty_out(vty, "\"%s\":{\n",
12962 get_afi_safi_str(afi,
12963 safi,
12964 true));
12965 } else
12966 vty_out(vty,
12967 "\nFor address family: %s\n",
12968 get_afi_safi_str(
12969 afi, safi,
12970 false));
12971
12972 if (community)
12973 bgp_show_community(
12974 vty, abgp, community,
12975 exact_match, afi, safi,
12976 show_flags);
12977 else
12978 bgp_show(vty, abgp, afi, safi,
12979 sh_type, output_arg,
12980 show_flags,
12981 rpki_target_state);
12982 if (uj)
12983 vty_out(vty, "}\n");
12984 }
12985 }
12986 } else {
12987 /* show <ip> bgp all: for each AFI and SAFI*/
12988 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12989 FOREACH_AFI_SAFI (afi, safi) {
12990 if (!bgp_afi_safi_peer_exists(abgp, afi,
12991 safi))
12992 continue;
12993
12994 if (uj) {
12995 if (first)
12996 first = false;
12997 else
12998 vty_out(vty, ",\n");
12999
13000 vty_out(vty, "\"%s\":{\n",
13001 get_afi_safi_str(afi,
13002 safi,
13003 true));
13004 } else
13005 vty_out(vty,
13006 "\nFor address family: %s\n",
13007 get_afi_safi_str(
13008 afi, safi,
13009 false));
13010
13011 if (community)
13012 bgp_show_community(
13013 vty, abgp, community,
13014 exact_match, afi, safi,
13015 show_flags);
13016 else
13017 bgp_show(vty, abgp, afi, safi,
13018 sh_type, output_arg,
13019 show_flags,
13020 rpki_target_state);
13021 if (uj)
13022 vty_out(vty, "}\n");
13023 }
13024 }
13025 }
13026 if (uj)
13027 vty_out(vty, "}\n");
13028 }
13029 return CMD_SUCCESS;
13030 }
13031
13032 DEFUN (show_ip_bgp_route,
13033 show_ip_bgp_route_cmd,
13034 "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]",
13035 SHOW_STR
13036 IP_STR
13037 BGP_STR
13038 BGP_INSTANCE_HELP_STR
13039 BGP_AFI_HELP_STR
13040 BGP_SAFI_WITH_LABEL_HELP_STR
13041 "Network in the BGP routing table to display\n"
13042 "IPv4 prefix\n"
13043 "Network in the BGP routing table to display\n"
13044 "IPv6 prefix\n"
13045 "Display only the bestpath\n"
13046 "Display only multipaths\n"
13047 "Display only paths that match the specified rpki state\n"
13048 "A valid path as determined by rpki\n"
13049 "A invalid path as determined by rpki\n"
13050 "A path that has no rpki data\n"
13051 JSON_STR)
13052 {
13053 int prefix_check = 0;
13054
13055 afi_t afi = AFI_IP6;
13056 safi_t safi = SAFI_UNICAST;
13057 char *prefix = NULL;
13058 struct bgp *bgp = NULL;
13059 enum bgp_path_type path_type;
13060 bool uj = use_json(argc, argv);
13061
13062 int idx = 0;
13063
13064 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13065 &bgp, uj);
13066 if (!idx)
13067 return CMD_WARNING;
13068
13069 if (!bgp) {
13070 vty_out(vty,
13071 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13072 return CMD_WARNING;
13073 }
13074
13075 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13076 if (argv_find(argv, argc, "A.B.C.D", &idx)
13077 || argv_find(argv, argc, "X:X::X:X", &idx))
13078 prefix_check = 0;
13079 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13080 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13081 prefix_check = 1;
13082
13083 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13084 && afi != AFI_IP6) {
13085 vty_out(vty,
13086 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13087 return CMD_WARNING;
13088 }
13089 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13090 && afi != AFI_IP) {
13091 vty_out(vty,
13092 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13093 return CMD_WARNING;
13094 }
13095
13096 prefix = argv[idx]->arg;
13097
13098 /* [<bestpath|multipath>] */
13099 if (argv_find(argv, argc, "bestpath", &idx))
13100 path_type = BGP_PATH_SHOW_BESTPATH;
13101 else if (argv_find(argv, argc, "multipath", &idx))
13102 path_type = BGP_PATH_SHOW_MULTIPATH;
13103 else
13104 path_type = BGP_PATH_SHOW_ALL;
13105
13106 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13107 path_type, RPKI_NOT_BEING_USED, uj);
13108 }
13109
13110 DEFUN (show_ip_bgp_regexp,
13111 show_ip_bgp_regexp_cmd,
13112 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13113 SHOW_STR
13114 IP_STR
13115 BGP_STR
13116 BGP_INSTANCE_HELP_STR
13117 BGP_AFI_HELP_STR
13118 BGP_SAFI_WITH_LABEL_HELP_STR
13119 "Display routes matching the AS path regular expression\n"
13120 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13121 JSON_STR)
13122 {
13123 afi_t afi = AFI_IP6;
13124 safi_t safi = SAFI_UNICAST;
13125 struct bgp *bgp = NULL;
13126 bool uj = use_json(argc, argv);
13127 char *regstr = NULL;
13128
13129 int idx = 0;
13130 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13131 &bgp, false);
13132 if (!idx)
13133 return CMD_WARNING;
13134
13135 // get index of regex
13136 if (argv_find(argv, argc, "REGEX", &idx))
13137 regstr = argv[idx]->arg;
13138
13139 assert(regstr);
13140 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13141 bgp_show_type_regexp, uj);
13142 }
13143
13144 DEFPY (show_ip_bgp_instance_all,
13145 show_ip_bgp_instance_all_cmd,
13146 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13147 SHOW_STR
13148 IP_STR
13149 BGP_STR
13150 BGP_INSTANCE_ALL_HELP_STR
13151 BGP_AFI_HELP_STR
13152 BGP_SAFI_WITH_LABEL_HELP_STR
13153 JSON_STR
13154 "Increase table width for longer prefixes\n")
13155 {
13156 afi_t afi = AFI_IP6;
13157 safi_t safi = SAFI_UNICAST;
13158 struct bgp *bgp = NULL;
13159 int idx = 0;
13160 uint16_t show_flags = 0;
13161
13162 if (uj) {
13163 argc--;
13164 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13165 }
13166
13167 if (wide)
13168 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13169
13170 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13171 &bgp, uj);
13172 if (!idx)
13173 return CMD_WARNING;
13174
13175 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13176 return CMD_SUCCESS;
13177 }
13178
13179 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13180 afi_t afi, safi_t safi, enum bgp_show_type type,
13181 bool use_json)
13182 {
13183 regex_t *regex;
13184 int rc;
13185 uint16_t show_flags = 0;
13186
13187 if (use_json)
13188 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13189
13190 if (!config_bgp_aspath_validate(regstr)) {
13191 vty_out(vty, "Invalid character in REGEX %s\n",
13192 regstr);
13193 return CMD_WARNING_CONFIG_FAILED;
13194 }
13195
13196 regex = bgp_regcomp(regstr);
13197 if (!regex) {
13198 vty_out(vty, "Can't compile regexp %s\n", regstr);
13199 return CMD_WARNING;
13200 }
13201
13202 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13203 RPKI_NOT_BEING_USED);
13204 bgp_regex_free(regex);
13205 return rc;
13206 }
13207
13208 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13209 const char *comstr, int exact, afi_t afi,
13210 safi_t safi, uint16_t show_flags)
13211 {
13212 struct community *com;
13213 int ret = 0;
13214
13215 com = community_str2com(comstr);
13216 if (!com) {
13217 vty_out(vty, "%% Community malformed: %s\n", comstr);
13218 return CMD_WARNING;
13219 }
13220
13221 ret = bgp_show(vty, bgp, afi, safi,
13222 (exact ? bgp_show_type_community_exact
13223 : bgp_show_type_community),
13224 com, show_flags, RPKI_NOT_BEING_USED);
13225 community_free(&com);
13226
13227 return ret;
13228 }
13229
13230 enum bgp_stats {
13231 BGP_STATS_MAXBITLEN = 0,
13232 BGP_STATS_RIB,
13233 BGP_STATS_PREFIXES,
13234 BGP_STATS_TOTPLEN,
13235 BGP_STATS_UNAGGREGATEABLE,
13236 BGP_STATS_MAX_AGGREGATEABLE,
13237 BGP_STATS_AGGREGATES,
13238 BGP_STATS_SPACE,
13239 BGP_STATS_ASPATH_COUNT,
13240 BGP_STATS_ASPATH_MAXHOPS,
13241 BGP_STATS_ASPATH_TOTHOPS,
13242 BGP_STATS_ASPATH_MAXSIZE,
13243 BGP_STATS_ASPATH_TOTSIZE,
13244 BGP_STATS_ASN_HIGHEST,
13245 BGP_STATS_MAX,
13246 };
13247
13248 #define TABLE_STATS_IDX_VTY 0
13249 #define TABLE_STATS_IDX_JSON 1
13250
13251 static const char *table_stats_strs[][2] = {
13252 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13253 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13254 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13255 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13256 "unaggregateablePrefixes"},
13257 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13258 "maximumAggregateablePrefixes"},
13259 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13260 "bgpAggregateAdvertisements"},
13261 [BGP_STATS_SPACE] = {"Address space advertised",
13262 "addressSpaceAdvertised"},
13263 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13264 "advertisementsWithPaths"},
13265 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13266 "longestAsPath"},
13267 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13268 "largestAsPath"},
13269 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13270 "averageAsPathLengthHops"},
13271 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13272 "averageAsPathSizeBytes"},
13273 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13274 [BGP_STATS_MAX] = {NULL, NULL}
13275 };
13276
13277 struct bgp_table_stats {
13278 struct bgp_table *table;
13279 unsigned long long counts[BGP_STATS_MAX];
13280
13281 unsigned long long
13282 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13283 1];
13284
13285 double total_space;
13286 };
13287
13288 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13289 struct bgp_table_stats *ts, unsigned int space)
13290 {
13291 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13292 struct bgp_path_info *pi;
13293 const struct prefix *rn_p;
13294
13295 if (!bgp_dest_has_bgp_path_info_data(dest))
13296 return;
13297
13298 rn_p = bgp_dest_get_prefix(dest);
13299 ts->counts[BGP_STATS_PREFIXES]++;
13300 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13301
13302 ts->prefix_len_count[rn_p->prefixlen]++;
13303 /* check if the prefix is included by any other announcements */
13304 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13305 pdest = bgp_dest_parent_nolock(pdest);
13306
13307 if (pdest == NULL || pdest == top) {
13308 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13309 /* announced address space */
13310 if (space)
13311 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13312 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13313 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13314
13315
13316 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13317 ts->counts[BGP_STATS_RIB]++;
13318
13319 if (CHECK_FLAG(pi->attr->flag,
13320 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13321 ts->counts[BGP_STATS_AGGREGATES]++;
13322
13323 /* as-path stats */
13324 if (pi->attr->aspath) {
13325 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13326 unsigned int size = aspath_size(pi->attr->aspath);
13327 as_t highest = aspath_highest(pi->attr->aspath);
13328
13329 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13330
13331 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13332 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13333
13334 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13335 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13336
13337 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13338 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13339 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13340 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13341 }
13342 }
13343 }
13344
13345 static void bgp_table_stats_walker(struct thread *t)
13346 {
13347 struct bgp_dest *dest, *ndest;
13348 struct bgp_dest *top;
13349 struct bgp_table_stats *ts = THREAD_ARG(t);
13350 unsigned int space = 0;
13351
13352 if (!(top = bgp_table_top(ts->table)))
13353 return;
13354
13355 switch (ts->table->afi) {
13356 case AFI_IP:
13357 space = IPV4_MAX_BITLEN;
13358 break;
13359 case AFI_IP6:
13360 space = IPV6_MAX_BITLEN;
13361 break;
13362 case AFI_L2VPN:
13363 space = EVPN_ROUTE_PREFIXLEN;
13364 break;
13365 case AFI_UNSPEC:
13366 case AFI_MAX:
13367 return;
13368 }
13369
13370 ts->counts[BGP_STATS_MAXBITLEN] = space;
13371
13372 for (dest = top; dest; dest = bgp_route_next(dest)) {
13373 if (ts->table->safi == SAFI_MPLS_VPN
13374 || ts->table->safi == SAFI_ENCAP
13375 || ts->table->safi == SAFI_EVPN) {
13376 struct bgp_table *table;
13377
13378 table = bgp_dest_get_bgp_table_info(dest);
13379 if (!table)
13380 continue;
13381
13382 top = bgp_table_top(table);
13383 for (ndest = bgp_table_top(table); ndest;
13384 ndest = bgp_route_next(ndest))
13385 bgp_table_stats_rn(ndest, top, ts, space);
13386 } else {
13387 bgp_table_stats_rn(dest, top, ts, space);
13388 }
13389 }
13390 }
13391
13392 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13393 struct json_object *json_array)
13394 {
13395 struct listnode *node, *nnode;
13396 struct bgp *bgp;
13397
13398 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13399 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13400 }
13401
13402 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13403 safi_t safi, struct json_object *json_array)
13404 {
13405 struct bgp_table_stats ts;
13406 unsigned int i;
13407 int ret = CMD_SUCCESS;
13408 char temp_buf[20];
13409 struct json_object *json = NULL;
13410 uint32_t bitlen = 0;
13411 struct json_object *json_bitlen;
13412
13413 if (json_array)
13414 json = json_object_new_object();
13415
13416 if (!bgp->rib[afi][safi]) {
13417 char warning_msg[50];
13418
13419 snprintf(warning_msg, sizeof(warning_msg),
13420 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13421 safi);
13422
13423 if (!json)
13424 vty_out(vty, "%s\n", warning_msg);
13425 else
13426 json_object_string_add(json, "warning", warning_msg);
13427
13428 ret = CMD_WARNING;
13429 goto end_table_stats;
13430 }
13431
13432 if (!json)
13433 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13434 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13435 else
13436 json_object_string_add(json, "instance", bgp->name_pretty);
13437
13438 /* labeled-unicast routes live in the unicast table */
13439 if (safi == SAFI_LABELED_UNICAST)
13440 safi = SAFI_UNICAST;
13441
13442 memset(&ts, 0, sizeof(ts));
13443 ts.table = bgp->rib[afi][safi];
13444 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13445
13446 for (i = 0; i < BGP_STATS_MAX; i++) {
13447 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13448 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13449 continue;
13450
13451 switch (i) {
13452 case BGP_STATS_ASPATH_TOTHOPS:
13453 case BGP_STATS_ASPATH_TOTSIZE:
13454 if (!json) {
13455 snprintf(
13456 temp_buf, sizeof(temp_buf), "%12.2f",
13457 ts.counts[i]
13458 ? (float)ts.counts[i]
13459 / (float)ts.counts
13460 [BGP_STATS_ASPATH_COUNT]
13461 : 0);
13462 vty_out(vty, "%-30s: %s",
13463 table_stats_strs[i]
13464 [TABLE_STATS_IDX_VTY],
13465 temp_buf);
13466 } else {
13467 json_object_double_add(
13468 json,
13469 table_stats_strs[i]
13470 [TABLE_STATS_IDX_JSON],
13471 ts.counts[i]
13472 ? (double)ts.counts[i]
13473 / (double)ts.counts
13474 [BGP_STATS_ASPATH_COUNT]
13475 : 0);
13476 }
13477 break;
13478 case BGP_STATS_TOTPLEN:
13479 if (!json) {
13480 snprintf(
13481 temp_buf, sizeof(temp_buf), "%12.2f",
13482 ts.counts[i]
13483 ? (float)ts.counts[i]
13484 / (float)ts.counts
13485 [BGP_STATS_PREFIXES]
13486 : 0);
13487 vty_out(vty, "%-30s: %s",
13488 table_stats_strs[i]
13489 [TABLE_STATS_IDX_VTY],
13490 temp_buf);
13491 } else {
13492 json_object_double_add(
13493 json,
13494 table_stats_strs[i]
13495 [TABLE_STATS_IDX_JSON],
13496 ts.counts[i]
13497 ? (double)ts.counts[i]
13498 / (double)ts.counts
13499 [BGP_STATS_PREFIXES]
13500 : 0);
13501 }
13502 break;
13503 case BGP_STATS_SPACE:
13504 if (!json) {
13505 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13506 ts.total_space);
13507 vty_out(vty, "%-30s: %s\n",
13508 table_stats_strs[i]
13509 [TABLE_STATS_IDX_VTY],
13510 temp_buf);
13511 } else {
13512 json_object_double_add(
13513 json,
13514 table_stats_strs[i]
13515 [TABLE_STATS_IDX_JSON],
13516 (double)ts.total_space);
13517 }
13518 if (afi == AFI_IP6) {
13519 if (!json) {
13520 snprintf(temp_buf, sizeof(temp_buf),
13521 "%12g",
13522 ts.total_space
13523 * pow(2.0, -128 + 32));
13524 vty_out(vty, "%30s: %s\n",
13525 "/32 equivalent %s\n",
13526 temp_buf);
13527 } else {
13528 json_object_double_add(
13529 json, "/32equivalent",
13530 (double)(ts.total_space
13531 * pow(2.0,
13532 -128 + 32)));
13533 }
13534 if (!json) {
13535 snprintf(temp_buf, sizeof(temp_buf),
13536 "%12g",
13537 ts.total_space
13538 * pow(2.0, -128 + 48));
13539 vty_out(vty, "%30s: %s\n",
13540 "/48 equivalent %s\n",
13541 temp_buf);
13542 } else {
13543 json_object_double_add(
13544 json, "/48equivalent",
13545 (double)(ts.total_space
13546 * pow(2.0,
13547 -128 + 48)));
13548 }
13549 } else {
13550 if (!json) {
13551 snprintf(temp_buf, sizeof(temp_buf),
13552 "%12.2f",
13553 ts.total_space * 100.
13554 * pow(2.0, -32));
13555 vty_out(vty, "%30s: %s\n",
13556 "% announced ", temp_buf);
13557 } else {
13558 json_object_double_add(
13559 json, "%announced",
13560 (double)(ts.total_space * 100.
13561 * pow(2.0, -32)));
13562 }
13563 if (!json) {
13564 snprintf(temp_buf, sizeof(temp_buf),
13565 "%12.2f",
13566 ts.total_space
13567 * pow(2.0, -32 + 8));
13568 vty_out(vty, "%30s: %s\n",
13569 "/8 equivalent ", temp_buf);
13570 } else {
13571 json_object_double_add(
13572 json, "/8equivalent",
13573 (double)(ts.total_space
13574 * pow(2.0, -32 + 8)));
13575 }
13576 if (!json) {
13577 snprintf(temp_buf, sizeof(temp_buf),
13578 "%12.2f",
13579 ts.total_space
13580 * pow(2.0, -32 + 24));
13581 vty_out(vty, "%30s: %s\n",
13582 "/24 equivalent ", temp_buf);
13583 } else {
13584 json_object_double_add(
13585 json, "/24equivalent",
13586 (double)(ts.total_space
13587 * pow(2.0, -32 + 24)));
13588 }
13589 }
13590 break;
13591 default:
13592 if (!json) {
13593 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13594 ts.counts[i]);
13595 vty_out(vty, "%-30s: %s",
13596 table_stats_strs[i]
13597 [TABLE_STATS_IDX_VTY],
13598 temp_buf);
13599 } else {
13600 json_object_int_add(
13601 json,
13602 table_stats_strs[i]
13603 [TABLE_STATS_IDX_JSON],
13604 ts.counts[i]);
13605 }
13606 }
13607 if (!json)
13608 vty_out(vty, "\n");
13609 }
13610
13611 switch (afi) {
13612 case AFI_IP:
13613 bitlen = IPV4_MAX_BITLEN;
13614 break;
13615 case AFI_IP6:
13616 bitlen = IPV6_MAX_BITLEN;
13617 break;
13618 case AFI_L2VPN:
13619 bitlen = EVPN_ROUTE_PREFIXLEN;
13620 break;
13621 case AFI_UNSPEC:
13622 case AFI_MAX:
13623 break;
13624 }
13625
13626 if (json) {
13627 json_bitlen = json_object_new_array();
13628
13629 for (i = 0; i <= bitlen; i++) {
13630 struct json_object *ind_bit = json_object_new_object();
13631
13632 if (!ts.prefix_len_count[i])
13633 continue;
13634
13635 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13636 json_object_int_add(ind_bit, temp_buf,
13637 ts.prefix_len_count[i]);
13638 json_object_array_add(json_bitlen, ind_bit);
13639 }
13640 json_object_object_add(json, "prefixLength", json_bitlen);
13641 }
13642
13643 end_table_stats:
13644 if (json)
13645 json_object_array_add(json_array, json);
13646 return ret;
13647 }
13648
13649 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13650 safi_t safi, struct json_object *json_array)
13651 {
13652 if (!bgp) {
13653 bgp_table_stats_all(vty, afi, safi, json_array);
13654 return CMD_SUCCESS;
13655 }
13656
13657 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13658 }
13659
13660 enum bgp_pcounts {
13661 PCOUNT_ADJ_IN = 0,
13662 PCOUNT_DAMPED,
13663 PCOUNT_REMOVED,
13664 PCOUNT_HISTORY,
13665 PCOUNT_STALE,
13666 PCOUNT_VALID,
13667 PCOUNT_ALL,
13668 PCOUNT_COUNTED,
13669 PCOUNT_BPATH_SELECTED,
13670 PCOUNT_PFCNT, /* the figure we display to users */
13671 PCOUNT_MAX,
13672 };
13673
13674 static const char *const pcount_strs[] = {
13675 [PCOUNT_ADJ_IN] = "Adj-in",
13676 [PCOUNT_DAMPED] = "Damped",
13677 [PCOUNT_REMOVED] = "Removed",
13678 [PCOUNT_HISTORY] = "History",
13679 [PCOUNT_STALE] = "Stale",
13680 [PCOUNT_VALID] = "Valid",
13681 [PCOUNT_ALL] = "All RIB",
13682 [PCOUNT_COUNTED] = "PfxCt counted",
13683 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13684 [PCOUNT_PFCNT] = "Useable",
13685 [PCOUNT_MAX] = NULL,
13686 };
13687
13688 struct peer_pcounts {
13689 unsigned int count[PCOUNT_MAX];
13690 const struct peer *peer;
13691 const struct bgp_table *table;
13692 safi_t safi;
13693 };
13694
13695 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13696 {
13697 const struct bgp_adj_in *ain;
13698 const struct bgp_path_info *pi;
13699 const struct peer *peer = pc->peer;
13700
13701 for (ain = rn->adj_in; ain; ain = ain->next)
13702 if (ain->peer == peer)
13703 pc->count[PCOUNT_ADJ_IN]++;
13704
13705 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13706
13707 if (pi->peer != peer)
13708 continue;
13709
13710 pc->count[PCOUNT_ALL]++;
13711
13712 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13713 pc->count[PCOUNT_DAMPED]++;
13714 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13715 pc->count[PCOUNT_HISTORY]++;
13716 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13717 pc->count[PCOUNT_REMOVED]++;
13718 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13719 pc->count[PCOUNT_STALE]++;
13720 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13721 pc->count[PCOUNT_VALID]++;
13722 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13723 pc->count[PCOUNT_PFCNT]++;
13724 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13725 pc->count[PCOUNT_BPATH_SELECTED]++;
13726
13727 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13728 pc->count[PCOUNT_COUNTED]++;
13729 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13730 flog_err(
13731 EC_LIB_DEVELOPMENT,
13732 "Attempting to count but flags say it is unusable");
13733 } else {
13734 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13735 flog_err(
13736 EC_LIB_DEVELOPMENT,
13737 "Not counted but flags say we should");
13738 }
13739 }
13740 }
13741
13742 static void bgp_peer_count_walker(struct thread *t)
13743 {
13744 struct bgp_dest *rn, *rm;
13745 const struct bgp_table *table;
13746 struct peer_pcounts *pc = THREAD_ARG(t);
13747
13748 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13749 || pc->safi == SAFI_EVPN) {
13750 /* Special handling for 2-level routing tables. */
13751 for (rn = bgp_table_top(pc->table); rn;
13752 rn = bgp_route_next(rn)) {
13753 table = bgp_dest_get_bgp_table_info(rn);
13754 if (table != NULL)
13755 for (rm = bgp_table_top(table); rm;
13756 rm = bgp_route_next(rm))
13757 bgp_peer_count_proc(rm, pc);
13758 }
13759 } else
13760 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13761 bgp_peer_count_proc(rn, pc);
13762 }
13763
13764 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13765 safi_t safi, bool use_json)
13766 {
13767 struct peer_pcounts pcounts = {.peer = peer};
13768 unsigned int i;
13769 json_object *json = NULL;
13770 json_object *json_loop = NULL;
13771
13772 if (use_json) {
13773 json = json_object_new_object();
13774 json_loop = json_object_new_object();
13775 }
13776
13777 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13778 || !peer->bgp->rib[afi][safi]) {
13779 if (use_json) {
13780 json_object_string_add(
13781 json, "warning",
13782 "No such neighbor or address family");
13783 vty_out(vty, "%s\n", json_object_to_json_string(json));
13784 json_object_free(json);
13785 json_object_free(json_loop);
13786 } else
13787 vty_out(vty, "%% No such neighbor or address family\n");
13788
13789 return CMD_WARNING;
13790 }
13791
13792 memset(&pcounts, 0, sizeof(pcounts));
13793 pcounts.peer = peer;
13794 pcounts.table = peer->bgp->rib[afi][safi];
13795 pcounts.safi = safi;
13796
13797 /* in-place call via thread subsystem so as to record execution time
13798 * stats for the thread-walk (i.e. ensure this can't be blamed on
13799 * on just vty_read()).
13800 */
13801 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13802
13803 if (use_json) {
13804 json_object_string_add(json, "prefixCountsFor", peer->host);
13805 json_object_string_add(json, "multiProtocol",
13806 get_afi_safi_str(afi, safi, true));
13807 json_object_int_add(json, "pfxCounter",
13808 peer->pcount[afi][safi]);
13809
13810 for (i = 0; i < PCOUNT_MAX; i++)
13811 json_object_int_add(json_loop, pcount_strs[i],
13812 pcounts.count[i]);
13813
13814 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13815
13816 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13817 json_object_string_add(json, "pfxctDriftFor",
13818 peer->host);
13819 json_object_string_add(
13820 json, "recommended",
13821 "Please report this bug, with the above command output");
13822 }
13823 vty_json(vty, json);
13824 } else {
13825
13826 if (peer->hostname
13827 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13828 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13829 peer->hostname, peer->host,
13830 get_afi_safi_str(afi, safi, false));
13831 } else {
13832 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13833 get_afi_safi_str(afi, safi, false));
13834 }
13835
13836 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13837 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13838
13839 for (i = 0; i < PCOUNT_MAX; i++)
13840 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13841 pcounts.count[i]);
13842
13843 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13844 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13845 vty_out(vty,
13846 "Please report this bug, with the above command output\n");
13847 }
13848 }
13849
13850 return CMD_SUCCESS;
13851 }
13852
13853 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13854 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13855 "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]",
13856 SHOW_STR
13857 IP_STR
13858 BGP_STR
13859 BGP_INSTANCE_HELP_STR
13860 BGP_AFI_HELP_STR
13861 BGP_SAFI_HELP_STR
13862 "Detailed information on TCP and BGP neighbor connections\n"
13863 "Neighbor to display information about\n"
13864 "Neighbor to display information about\n"
13865 "Neighbor on BGP configured interface\n"
13866 "Display detailed prefix count information\n"
13867 JSON_STR)
13868 {
13869 afi_t afi = AFI_IP6;
13870 safi_t safi = SAFI_UNICAST;
13871 struct peer *peer;
13872 int idx = 0;
13873 struct bgp *bgp = NULL;
13874 bool uj = use_json(argc, argv);
13875
13876 if (uj)
13877 argc--;
13878
13879 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13880 &bgp, uj);
13881 if (!idx)
13882 return CMD_WARNING;
13883
13884 argv_find(argv, argc, "neighbors", &idx);
13885 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13886 if (!peer)
13887 return CMD_WARNING;
13888
13889 return bgp_peer_counts(vty, peer, afi, safi, uj);
13890 }
13891
13892 #ifdef KEEP_OLD_VPN_COMMANDS
13893 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13894 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13895 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13896 SHOW_STR
13897 IP_STR
13898 BGP_STR
13899 BGP_VPNVX_HELP_STR
13900 "Display information about all VPNv4 NLRIs\n"
13901 "Detailed information on TCP and BGP neighbor connections\n"
13902 "Neighbor to display information about\n"
13903 "Neighbor to display information about\n"
13904 "Neighbor on BGP configured interface\n"
13905 "Display detailed prefix count information\n"
13906 JSON_STR)
13907 {
13908 int idx_peer = 6;
13909 struct peer *peer;
13910 bool uj = use_json(argc, argv);
13911
13912 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13913 if (!peer)
13914 return CMD_WARNING;
13915
13916 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13917 }
13918
13919 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13920 show_ip_bgp_vpn_all_route_prefix_cmd,
13921 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13922 SHOW_STR
13923 IP_STR
13924 BGP_STR
13925 BGP_VPNVX_HELP_STR
13926 "Display information about all VPNv4 NLRIs\n"
13927 "Network in the BGP routing table to display\n"
13928 "Network in the BGP routing table to display\n"
13929 JSON_STR)
13930 {
13931 int idx = 0;
13932 char *network = NULL;
13933 struct bgp *bgp = bgp_get_default();
13934 if (!bgp) {
13935 vty_out(vty, "Can't find default instance\n");
13936 return CMD_WARNING;
13937 }
13938
13939 if (argv_find(argv, argc, "A.B.C.D", &idx))
13940 network = argv[idx]->arg;
13941 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13942 network = argv[idx]->arg;
13943 else {
13944 vty_out(vty, "Unable to figure out Network\n");
13945 return CMD_WARNING;
13946 }
13947
13948 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13949 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13950 use_json(argc, argv));
13951 }
13952 #endif /* KEEP_OLD_VPN_COMMANDS */
13953
13954 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13955 show_bgp_l2vpn_evpn_route_prefix_cmd,
13956 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13957 SHOW_STR
13958 BGP_STR
13959 L2VPN_HELP_STR
13960 EVPN_HELP_STR
13961 "Network in the BGP routing table to display\n"
13962 "Network in the BGP routing table to display\n"
13963 "Network in the BGP routing table to display\n"
13964 "Network in the BGP routing table to display\n"
13965 JSON_STR)
13966 {
13967 int idx = 0;
13968 char *network = NULL;
13969 int prefix_check = 0;
13970
13971 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13972 argv_find(argv, argc, "X:X::X:X", &idx))
13973 network = argv[idx]->arg;
13974 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13975 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13976 network = argv[idx]->arg;
13977 prefix_check = 1;
13978 } else {
13979 vty_out(vty, "Unable to figure out Network\n");
13980 return CMD_WARNING;
13981 }
13982 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13983 prefix_check, BGP_PATH_SHOW_ALL,
13984 RPKI_NOT_BEING_USED, use_json(argc, argv));
13985 }
13986
13987 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13988 struct bgp_table *table, int *header1,
13989 int *header2, json_object *json,
13990 json_object *json_scode,
13991 json_object *json_ocode, bool wide,
13992 bool detail)
13993 {
13994 uint64_t version = table ? table->version : 0;
13995
13996 if (*header1) {
13997 if (json) {
13998 json_object_int_add(json, "bgpTableVersion", version);
13999 json_object_string_addf(json, "bgpLocalRouterId",
14000 "%pI4", &peer->bgp->router_id);
14001 json_object_int_add(json, "defaultLocPrf",
14002 peer->bgp->default_local_pref);
14003 json_object_int_add(json, "localAS",
14004 peer->change_local_as
14005 ? peer->change_local_as
14006 : peer->local_as);
14007 json_object_object_add(json, "bgpStatusCodes",
14008 json_scode);
14009 json_object_object_add(json, "bgpOriginCodes",
14010 json_ocode);
14011 } else {
14012 vty_out(vty,
14013 "BGP table version is %" PRIu64
14014 ", local router ID is %pI4, vrf id ",
14015 version, &peer->bgp->router_id);
14016 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14017 vty_out(vty, "%s", VRFID_NONE_STR);
14018 else
14019 vty_out(vty, "%u", peer->bgp->vrf_id);
14020 vty_out(vty, "\n");
14021 vty_out(vty, "Default local pref %u, ",
14022 peer->bgp->default_local_pref);
14023 vty_out(vty, "local AS %u\n",
14024 peer->change_local_as ? peer->change_local_as
14025 : peer->local_as);
14026 if (!detail) {
14027 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14028 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14029 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14030 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14031 }
14032 }
14033 *header1 = 0;
14034 }
14035 if (*header2) {
14036 if (!json && !detail)
14037 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14038 : BGP_SHOW_HEADER));
14039 *header2 = 0;
14040 }
14041 }
14042
14043 static void
14044 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14045 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14046 const char *rmap_name, json_object *json, json_object *json_ar,
14047 json_object *json_scode, json_object *json_ocode,
14048 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14049 const struct prefix *match, unsigned long *output_count,
14050 unsigned long *filtered_count)
14051 {
14052 struct bgp_adj_in *ain = NULL;
14053 struct bgp_adj_out *adj = NULL;
14054 struct bgp_dest *dest;
14055 struct bgp *bgp;
14056 struct attr attr;
14057 int ret;
14058 struct update_subgroup *subgrp;
14059 struct peer_af *paf = NULL;
14060 bool route_filtered;
14061 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14062 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14063 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14064 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14065 || (safi == SAFI_EVPN))
14066 ? true
14067 : false;
14068 int display = 0;
14069 json_object *json_net = NULL;
14070
14071 bgp = peer->bgp;
14072
14073 /* If the user supplied a prefix, look for a matching route instead
14074 * of walking the whole table.
14075 */
14076 if (match) {
14077 dest = bgp_node_match(table, match);
14078 if (!dest) {
14079 if (!use_json)
14080 vty_out(vty, "Network not in table\n");
14081 return;
14082 }
14083
14084 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14085
14086 if (rn_p->prefixlen != match->prefixlen) {
14087 if (!use_json)
14088 vty_out(vty, "Network not in table\n");
14089 bgp_dest_unlock_node(dest);
14090 return;
14091 }
14092
14093 if (type == bgp_show_adj_route_received ||
14094 type == bgp_show_adj_route_filtered) {
14095 for (ain = dest->adj_in; ain; ain = ain->next) {
14096 if (ain->peer == peer) {
14097 attr = *ain->attr;
14098 break;
14099 }
14100 }
14101 /* bail out if if adj_out is empty, or
14102 * if the prefix isn't in this peer's
14103 * adj_in
14104 */
14105 if (!ain || ain->peer != peer) {
14106 if (!use_json)
14107 vty_out(vty, "Network not in table\n");
14108 bgp_dest_unlock_node(dest);
14109 return;
14110 }
14111 } else if (type == bgp_show_adj_route_advertised) {
14112 bool peer_found = false;
14113
14114 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14115 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14116 if (paf->peer == peer && adj->attr) {
14117 attr = *adj->attr;
14118 peer_found = true;
14119 break;
14120 }
14121 }
14122 if (peer_found)
14123 break;
14124 }
14125 /* bail out if if adj_out is empty, or
14126 * if the prefix isn't in this peer's
14127 * adj_out
14128 */
14129 if (!paf || !peer_found) {
14130 if (!use_json)
14131 vty_out(vty, "Network not in table\n");
14132 bgp_dest_unlock_node(dest);
14133 return;
14134 }
14135 }
14136
14137 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14138 rmap_name);
14139
14140 if (ret != RMAP_DENY) {
14141 show_adj_route_header(vty, peer, table, header1,
14142 header2, json, json_scode,
14143 json_ocode, wide, detail);
14144
14145 if (use_json)
14146 json_net = json_object_new_object();
14147
14148 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14149 afi, safi, json_net,
14150 BGP_PATH_SHOW_ALL, &display,
14151 RPKI_NOT_BEING_USED);
14152 if (use_json)
14153 json_object_object_addf(json_ar, json_net,
14154 "%pFX", rn_p);
14155 (*output_count)++;
14156 } else
14157 (*filtered_count)++;
14158
14159 bgp_attr_flush(&attr);
14160 bgp_dest_unlock_node(dest);
14161 return;
14162 }
14163
14164
14165 subgrp = peer_subgroup(peer, afi, safi);
14166
14167 if (type == bgp_show_adj_route_advertised && subgrp
14168 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14169 if (use_json) {
14170 json_object_int_add(json, "bgpTableVersion",
14171 table->version);
14172 json_object_string_addf(json, "bgpLocalRouterId",
14173 "%pI4", &bgp->router_id);
14174 json_object_int_add(json, "defaultLocPrf",
14175 bgp->default_local_pref);
14176 json_object_int_add(json, "localAS",
14177 peer->change_local_as
14178 ? peer->change_local_as
14179 : peer->local_as);
14180 json_object_object_add(json, "bgpStatusCodes",
14181 json_scode);
14182 json_object_object_add(json, "bgpOriginCodes",
14183 json_ocode);
14184 json_object_string_add(
14185 json, "bgpOriginatingDefaultNetwork",
14186 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14187 } else {
14188 vty_out(vty,
14189 "BGP table version is %" PRIu64
14190 ", local router ID is %pI4, vrf id ",
14191 table->version, &bgp->router_id);
14192 if (bgp->vrf_id == VRF_UNKNOWN)
14193 vty_out(vty, "%s", VRFID_NONE_STR);
14194 else
14195 vty_out(vty, "%u", bgp->vrf_id);
14196 vty_out(vty, "\n");
14197 vty_out(vty, "Default local pref %u, ",
14198 bgp->default_local_pref);
14199 vty_out(vty, "local AS %u\n",
14200 peer->change_local_as ? peer->change_local_as
14201 : peer->local_as);
14202 if (!detail) {
14203 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14204 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14205 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14206 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14207 }
14208
14209 vty_out(vty, "Originating default network %s\n\n",
14210 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14211 }
14212 (*output_count)++;
14213 *header1 = 0;
14214 }
14215
14216 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14217 if (type == bgp_show_adj_route_received
14218 || type == bgp_show_adj_route_filtered) {
14219 for (ain = dest->adj_in; ain; ain = ain->next) {
14220 if (ain->peer != peer)
14221 continue;
14222
14223 show_adj_route_header(vty, peer, table, header1,
14224 header2, json, json_scode,
14225 json_ocode, wide, detail);
14226
14227 if ((safi == SAFI_MPLS_VPN)
14228 || (safi == SAFI_ENCAP)
14229 || (safi == SAFI_EVPN)) {
14230 if (use_json)
14231 json_object_string_add(
14232 json_ar, "rd", rd_str);
14233 else if (show_rd && rd_str) {
14234 vty_out(vty,
14235 "Route Distinguisher: %s\n",
14236 rd_str);
14237 show_rd = false;
14238 }
14239 }
14240
14241 attr = *ain->attr;
14242 route_filtered = false;
14243
14244 /* Filter prefix using distribute list,
14245 * filter list or prefix list
14246 */
14247 const struct prefix *rn_p =
14248 bgp_dest_get_prefix(dest);
14249 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14250 safi))
14251 == FILTER_DENY)
14252 route_filtered = true;
14253
14254 /* Filter prefix using route-map */
14255 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14256 safi, rmap_name, NULL,
14257 0, NULL);
14258
14259 if (type == bgp_show_adj_route_filtered &&
14260 !route_filtered && ret != RMAP_DENY) {
14261 bgp_attr_flush(&attr);
14262 continue;
14263 }
14264
14265 if (type == bgp_show_adj_route_received
14266 && (route_filtered || ret == RMAP_DENY))
14267 (*filtered_count)++;
14268
14269 if (detail) {
14270 if (use_json)
14271 json_net =
14272 json_object_new_object();
14273 bgp_show_path_info(
14274 NULL /* prefix_rd */, dest, vty,
14275 bgp, afi, safi, json_net,
14276 BGP_PATH_SHOW_ALL, &display,
14277 RPKI_NOT_BEING_USED);
14278 if (use_json)
14279 json_object_object_addf(
14280 json_ar, json_net,
14281 "%pFX", rn_p);
14282 } else
14283 route_vty_out_tmp(vty, dest, rn_p,
14284 &attr, safi, use_json,
14285 json_ar, wide);
14286 bgp_attr_flush(&attr);
14287 (*output_count)++;
14288 }
14289 } else if (type == bgp_show_adj_route_advertised) {
14290 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14291 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14292 if (paf->peer != peer || !adj->attr)
14293 continue;
14294
14295 show_adj_route_header(
14296 vty, peer, table, header1,
14297 header2, json, json_scode,
14298 json_ocode, wide, detail);
14299
14300 const struct prefix *rn_p =
14301 bgp_dest_get_prefix(dest);
14302
14303 attr = *adj->attr;
14304 ret = bgp_output_modifier(
14305 peer, rn_p, &attr, afi, safi,
14306 rmap_name);
14307
14308 if (ret != RMAP_DENY) {
14309 if ((safi == SAFI_MPLS_VPN)
14310 || (safi == SAFI_ENCAP)
14311 || (safi == SAFI_EVPN)) {
14312 if (use_json)
14313 json_object_string_add(
14314 json_ar,
14315 "rd",
14316 rd_str);
14317 else if (show_rd
14318 && rd_str) {
14319 vty_out(vty,
14320 "Route Distinguisher: %s\n",
14321 rd_str);
14322 show_rd = false;
14323 }
14324 }
14325 if (detail) {
14326 if (use_json)
14327 json_net =
14328 json_object_new_object();
14329 bgp_show_path_info(
14330 NULL /* prefix_rd
14331 */
14332 ,
14333 dest, vty, bgp,
14334 afi, safi,
14335 json_net,
14336 BGP_PATH_SHOW_ALL,
14337 &display,
14338 RPKI_NOT_BEING_USED);
14339 if (use_json)
14340 json_object_object_addf(
14341 json_ar,
14342 json_net,
14343 "%pFX",
14344 rn_p);
14345 } else
14346 route_vty_out_tmp(
14347 vty, dest, rn_p,
14348 &attr, safi,
14349 use_json,
14350 json_ar, wide);
14351 (*output_count)++;
14352 } else {
14353 (*filtered_count)++;
14354 }
14355
14356 bgp_attr_flush(&attr);
14357 }
14358 } else if (type == bgp_show_adj_route_bestpath) {
14359 struct bgp_path_info *pi;
14360
14361 show_adj_route_header(vty, peer, table, header1,
14362 header2, json, json_scode,
14363 json_ocode, wide, detail);
14364
14365 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14366
14367 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14368 pi = pi->next) {
14369 if (pi->peer != peer)
14370 continue;
14371
14372 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14373 continue;
14374
14375 if (detail) {
14376 if (use_json)
14377 json_net =
14378 json_object_new_object();
14379 bgp_show_path_info(
14380 NULL /* prefix_rd */, dest, vty,
14381 bgp, afi, safi, json_net,
14382 BGP_PATH_SHOW_BESTPATH,
14383 &display, RPKI_NOT_BEING_USED);
14384 if (use_json)
14385 json_object_object_addf(
14386 json_ar, json_net,
14387 "%pFX", rn_p);
14388 } else
14389 route_vty_out_tmp(
14390 vty, dest, rn_p, pi->attr, safi,
14391 use_json, json_ar, wide);
14392 (*output_count)++;
14393 }
14394 }
14395 }
14396 }
14397
14398 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14399 safi_t safi, enum bgp_show_adj_route_type type,
14400 const char *rmap_name, const struct prefix *match,
14401 uint16_t show_flags)
14402 {
14403 struct bgp *bgp;
14404 struct bgp_table *table;
14405 json_object *json = NULL;
14406 json_object *json_scode = NULL;
14407 json_object *json_ocode = NULL;
14408 json_object *json_ar = NULL;
14409 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14410
14411 /* Init BGP headers here so they're only displayed once
14412 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14413 */
14414 int header1 = 1;
14415 int header2 = 1;
14416
14417 /*
14418 * Initialize variables for each RD
14419 * All prefixes under an RD is aggregated within "json_routes"
14420 */
14421 char rd_str[BUFSIZ] = {0};
14422 json_object *json_routes = NULL;
14423
14424
14425 /* For 2-tier tables, prefix counts need to be
14426 * maintained across multiple runs of show_adj_route()
14427 */
14428 unsigned long output_count_per_rd;
14429 unsigned long filtered_count_per_rd;
14430 unsigned long output_count = 0;
14431 unsigned long filtered_count = 0;
14432
14433 if (use_json) {
14434 json = json_object_new_object();
14435 json_ar = json_object_new_object();
14436 json_scode = json_object_new_object();
14437 json_ocode = json_object_new_object();
14438 #if CONFDATE > 20231208
14439 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14440 #endif
14441 json_object_string_add(json_scode, "suppressed", "s");
14442 json_object_string_add(json_scode, "damped", "d");
14443 json_object_string_add(json_scode, "history", "h");
14444 json_object_string_add(json_scode, "valid", "*");
14445 json_object_string_add(json_scode, "best", ">");
14446 json_object_string_add(json_scode, "multipath", "=");
14447 json_object_string_add(json_scode, "internal", "i");
14448 json_object_string_add(json_scode, "ribFailure", "r");
14449 json_object_string_add(json_scode, "stale", "S");
14450 json_object_string_add(json_scode, "removed", "R");
14451
14452 #if CONFDATE > 20231208
14453 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14454 #endif
14455 json_object_string_add(json_ocode, "igp", "i");
14456 json_object_string_add(json_ocode, "egp", "e");
14457 json_object_string_add(json_ocode, "incomplete", "?");
14458 }
14459
14460 if (!peer || !peer->afc[afi][safi]) {
14461 if (use_json) {
14462 json_object_string_add(
14463 json, "warning",
14464 "No such neighbor or address family");
14465 vty_out(vty, "%s\n", json_object_to_json_string(json));
14466 json_object_free(json);
14467 json_object_free(json_ar);
14468 json_object_free(json_scode);
14469 json_object_free(json_ocode);
14470 } else
14471 vty_out(vty, "%% No such neighbor or address family\n");
14472
14473 return CMD_WARNING;
14474 }
14475
14476 if ((type == bgp_show_adj_route_received
14477 || type == bgp_show_adj_route_filtered)
14478 && !CHECK_FLAG(peer->af_flags[afi][safi],
14479 PEER_FLAG_SOFT_RECONFIG)) {
14480 if (use_json) {
14481 json_object_string_add(
14482 json, "warning",
14483 "Inbound soft reconfiguration not enabled");
14484 vty_out(vty, "%s\n", json_object_to_json_string(json));
14485 json_object_free(json);
14486 json_object_free(json_ar);
14487 json_object_free(json_scode);
14488 json_object_free(json_ocode);
14489 } else
14490 vty_out(vty,
14491 "%% Inbound soft reconfiguration not enabled\n");
14492
14493 return CMD_WARNING;
14494 }
14495
14496 bgp = peer->bgp;
14497
14498 /* labeled-unicast routes live in the unicast table */
14499 if (safi == SAFI_LABELED_UNICAST)
14500 table = bgp->rib[afi][SAFI_UNICAST];
14501 else
14502 table = bgp->rib[afi][safi];
14503
14504 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14505 || (safi == SAFI_EVPN)) {
14506
14507 struct bgp_dest *dest;
14508
14509 for (dest = bgp_table_top(table); dest;
14510 dest = bgp_route_next(dest)) {
14511 table = bgp_dest_get_bgp_table_info(dest);
14512 if (!table)
14513 continue;
14514
14515 output_count_per_rd = 0;
14516 filtered_count_per_rd = 0;
14517
14518 if (use_json)
14519 json_routes = json_object_new_object();
14520
14521 const struct prefix_rd *prd;
14522 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14523 dest);
14524
14525 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14526 bgp->asnotation);
14527
14528 show_adj_route(
14529 vty, peer, table, afi, safi, type, rmap_name,
14530 json, json_routes, json_scode, json_ocode,
14531 show_flags, &header1, &header2, rd_str, match,
14532 &output_count_per_rd, &filtered_count_per_rd);
14533
14534 /* Don't include an empty RD in the output! */
14535 if (json_routes && (output_count_per_rd > 0))
14536 json_object_object_add(json_ar, rd_str,
14537 json_routes);
14538
14539 output_count += output_count_per_rd;
14540 filtered_count += filtered_count_per_rd;
14541 }
14542 } else
14543 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14544 json, json_ar, json_scode, json_ocode,
14545 show_flags, &header1, &header2, rd_str, match,
14546 &output_count, &filtered_count);
14547
14548 if (use_json) {
14549 if (type == bgp_show_adj_route_advertised)
14550 json_object_object_add(json, "advertisedRoutes",
14551 json_ar);
14552 else
14553 json_object_object_add(json, "receivedRoutes", json_ar);
14554 json_object_int_add(json, "totalPrefixCounter", output_count);
14555 json_object_int_add(json, "filteredPrefixCounter",
14556 filtered_count);
14557
14558 /*
14559 * These fields only give up ownership to `json` when `header1`
14560 * is used (set to zero). See code in `show_adj_route` and
14561 * `show_adj_route_header`.
14562 */
14563 if (header1 == 1) {
14564 json_object_free(json_scode);
14565 json_object_free(json_ocode);
14566 }
14567
14568 vty_json(vty, json);
14569 } else if (output_count > 0) {
14570 if (!match && filtered_count > 0)
14571 vty_out(vty,
14572 "\nTotal number of prefixes %ld (%ld filtered)\n",
14573 output_count, filtered_count);
14574 else
14575 vty_out(vty, "\nTotal number of prefixes %ld\n",
14576 output_count);
14577 }
14578
14579 return CMD_SUCCESS;
14580 }
14581
14582 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14583 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14584 "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]",
14585 SHOW_STR
14586 IP_STR
14587 BGP_STR
14588 BGP_INSTANCE_HELP_STR
14589 BGP_AFI_HELP_STR
14590 BGP_SAFI_WITH_LABEL_HELP_STR
14591 "Detailed information on TCP and BGP neighbor connections\n"
14592 "Neighbor to display information about\n"
14593 "Neighbor to display information about\n"
14594 "Neighbor on BGP configured interface\n"
14595 "Display the routes selected by best path\n"
14596 "Display detailed version of routes\n"
14597 JSON_STR
14598 "Increase table width for longer prefixes\n")
14599 {
14600 afi_t afi = AFI_IP6;
14601 safi_t safi = SAFI_UNICAST;
14602 char *rmap_name = NULL;
14603 char *peerstr = NULL;
14604 struct bgp *bgp = NULL;
14605 struct peer *peer;
14606 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14607 int idx = 0;
14608 uint16_t show_flags = 0;
14609
14610 if (detail)
14611 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14612
14613 if (uj)
14614 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14615
14616 if (wide)
14617 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14618
14619 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14620 &bgp, uj);
14621
14622 if (!idx)
14623 return CMD_WARNING;
14624
14625 argv_find(argv, argc, "neighbors", &idx);
14626 peerstr = argv[++idx]->arg;
14627
14628 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14629 if (!peer)
14630 return CMD_WARNING;
14631
14632 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14633 show_flags);
14634 }
14635
14636 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14637 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14638 "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]",
14639 SHOW_STR
14640 IP_STR
14641 BGP_STR
14642 BGP_INSTANCE_HELP_STR
14643 BGP_AFI_HELP_STR
14644 BGP_SAFI_WITH_LABEL_HELP_STR
14645 "Display the entries for all address families\n"
14646 "Detailed information on TCP and BGP neighbor connections\n"
14647 "Neighbor to display information about\n"
14648 "Neighbor to display information about\n"
14649 "Neighbor on BGP configured interface\n"
14650 "Display the routes advertised to a BGP neighbor\n"
14651 "Display the received routes from neighbor\n"
14652 "Display the filtered routes received from neighbor\n"
14653 "Route-map to modify the attributes\n"
14654 "Name of the route map\n"
14655 "IPv4 prefix\n"
14656 "IPv6 prefix\n"
14657 "Display detailed version of routes\n"
14658 JSON_STR
14659 "Increase table width for longer prefixes\n")
14660 {
14661 afi_t afi = AFI_IP6;
14662 safi_t safi = SAFI_UNICAST;
14663 char *peerstr = NULL;
14664 struct bgp *bgp = NULL;
14665 struct peer *peer;
14666 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14667 int idx = 0;
14668 bool first = true;
14669 uint16_t show_flags = 0;
14670 struct listnode *node;
14671 struct bgp *abgp;
14672
14673 if (detail || prefix_str)
14674 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14675
14676 if (uj) {
14677 argc--;
14678 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14679 }
14680
14681 if (all) {
14682 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14683 if (argv_find(argv, argc, "ipv4", &idx))
14684 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14685
14686 if (argv_find(argv, argc, "ipv6", &idx))
14687 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14688 }
14689
14690 if (wide)
14691 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14692
14693 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14694 &bgp, uj);
14695 if (!idx)
14696 return CMD_WARNING;
14697
14698 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14699 argv_find(argv, argc, "neighbors", &idx);
14700 peerstr = argv[++idx]->arg;
14701
14702 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14703 if (!peer)
14704 return CMD_WARNING;
14705
14706 if (argv_find(argv, argc, "advertised-routes", &idx))
14707 type = bgp_show_adj_route_advertised;
14708 else if (argv_find(argv, argc, "received-routes", &idx))
14709 type = bgp_show_adj_route_received;
14710 else if (argv_find(argv, argc, "filtered-routes", &idx))
14711 type = bgp_show_adj_route_filtered;
14712
14713 if (!all)
14714 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14715 prefix_str ? prefix : NULL, show_flags);
14716 if (uj)
14717 vty_out(vty, "{\n");
14718
14719 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14720 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14721 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14722 : AFI_IP6;
14723 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14724 FOREACH_SAFI (safi) {
14725 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14726 continue;
14727
14728 if (uj) {
14729 if (first)
14730 first = false;
14731 else
14732 vty_out(vty, ",\n");
14733 vty_out(vty, "\"%s\":",
14734 get_afi_safi_str(afi, safi,
14735 true));
14736 } else
14737 vty_out(vty,
14738 "\nFor address family: %s\n",
14739 get_afi_safi_str(afi, safi,
14740 false));
14741
14742 peer_adj_routes(vty, peer, afi, safi, type,
14743 route_map, prefix, show_flags);
14744 }
14745 }
14746 } else {
14747 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14748 FOREACH_AFI_SAFI (afi, safi) {
14749 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14750 continue;
14751
14752 if (uj) {
14753 if (first)
14754 first = false;
14755 else
14756 vty_out(vty, ",\n");
14757 vty_out(vty, "\"%s\":",
14758 get_afi_safi_str(afi, safi,
14759 true));
14760 } else
14761 vty_out(vty,
14762 "\nFor address family: %s\n",
14763 get_afi_safi_str(afi, safi,
14764 false));
14765
14766 peer_adj_routes(vty, peer, afi, safi, type,
14767 route_map, prefix, show_flags);
14768 }
14769 }
14770 }
14771 if (uj)
14772 vty_out(vty, "}\n");
14773
14774 return CMD_SUCCESS;
14775 }
14776
14777 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14778 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14779 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14780 SHOW_STR
14781 IP_STR
14782 BGP_STR
14783 BGP_INSTANCE_HELP_STR
14784 BGP_AF_STR
14785 BGP_AF_STR
14786 BGP_AF_MODIFIER_STR
14787 "Detailed information on TCP and BGP neighbor connections\n"
14788 "Neighbor to display information about\n"
14789 "Neighbor to display information about\n"
14790 "Neighbor on BGP configured interface\n"
14791 "Display information received from a BGP neighbor\n"
14792 "Display the prefixlist filter\n"
14793 JSON_STR)
14794 {
14795 afi_t afi = AFI_IP6;
14796 safi_t safi = SAFI_UNICAST;
14797 char *peerstr = NULL;
14798 char name[BUFSIZ];
14799 struct peer *peer;
14800 int count;
14801 int idx = 0;
14802 struct bgp *bgp = NULL;
14803 bool uj = use_json(argc, argv);
14804
14805 if (uj)
14806 argc--;
14807
14808 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14809 &bgp, uj);
14810 if (!idx)
14811 return CMD_WARNING;
14812
14813 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14814 argv_find(argv, argc, "neighbors", &idx);
14815 peerstr = argv[++idx]->arg;
14816
14817 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14818 if (!peer)
14819 return CMD_WARNING;
14820
14821 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14822 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14823 if (count) {
14824 if (!uj)
14825 vty_out(vty, "Address Family: %s\n",
14826 get_afi_safi_str(afi, safi, false));
14827 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14828 } else {
14829 if (uj)
14830 vty_out(vty, "{}\n");
14831 else
14832 vty_out(vty, "No functional output\n");
14833 }
14834
14835 return CMD_SUCCESS;
14836 }
14837
14838 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14839 afi_t afi, safi_t safi,
14840 enum bgp_show_type type, bool use_json)
14841 {
14842 uint16_t show_flags = 0;
14843
14844 if (use_json)
14845 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14846
14847 if (!peer || !peer->afc[afi][safi]) {
14848 if (use_json) {
14849 json_object *json_no = NULL;
14850 json_no = json_object_new_object();
14851 json_object_string_add(
14852 json_no, "warning",
14853 "No such neighbor or address family");
14854 vty_out(vty, "%s\n",
14855 json_object_to_json_string(json_no));
14856 json_object_free(json_no);
14857 } else
14858 vty_out(vty, "%% No such neighbor or address family\n");
14859 return CMD_WARNING;
14860 }
14861
14862 /* labeled-unicast routes live in the unicast table */
14863 if (safi == SAFI_LABELED_UNICAST)
14864 safi = SAFI_UNICAST;
14865
14866 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14867 RPKI_NOT_BEING_USED);
14868 }
14869
14870 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14871 show_ip_bgp_flowspec_routes_detailed_cmd,
14872 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14873 SHOW_STR
14874 IP_STR
14875 BGP_STR
14876 BGP_INSTANCE_HELP_STR
14877 BGP_AFI_HELP_STR
14878 "SAFI Flowspec\n"
14879 "Detailed information on flowspec entries\n"
14880 JSON_STR)
14881 {
14882 afi_t afi = AFI_IP6;
14883 safi_t safi = SAFI_UNICAST;
14884 struct bgp *bgp = NULL;
14885 int idx = 0;
14886 bool uj = use_json(argc, argv);
14887 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14888
14889 if (uj) {
14890 argc--;
14891 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14892 }
14893
14894 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14895 &bgp, uj);
14896 if (!idx)
14897 return CMD_WARNING;
14898
14899 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14900 show_flags, RPKI_NOT_BEING_USED);
14901 }
14902
14903 DEFUN (show_ip_bgp_neighbor_routes,
14904 show_ip_bgp_neighbor_routes_cmd,
14905 "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]",
14906 SHOW_STR
14907 IP_STR
14908 BGP_STR
14909 BGP_INSTANCE_HELP_STR
14910 BGP_AFI_HELP_STR
14911 BGP_SAFI_WITH_LABEL_HELP_STR
14912 "Detailed information on TCP and BGP neighbor connections\n"
14913 "Neighbor to display information about\n"
14914 "Neighbor to display information about\n"
14915 "Neighbor on BGP configured interface\n"
14916 "Display flap statistics of the routes learned from neighbor\n"
14917 "Display the dampened routes received from neighbor\n"
14918 "Display routes learned from neighbor\n"
14919 JSON_STR)
14920 {
14921 char *peerstr = NULL;
14922 struct bgp *bgp = NULL;
14923 afi_t afi = AFI_IP6;
14924 safi_t safi = SAFI_UNICAST;
14925 struct peer *peer;
14926 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14927 int idx = 0;
14928 bool uj = use_json(argc, argv);
14929
14930 if (uj)
14931 argc--;
14932
14933 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14934 &bgp, uj);
14935 if (!idx)
14936 return CMD_WARNING;
14937
14938 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14939 argv_find(argv, argc, "neighbors", &idx);
14940 peerstr = argv[++idx]->arg;
14941
14942 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14943 if (!peer)
14944 return CMD_WARNING;
14945
14946 if (argv_find(argv, argc, "flap-statistics", &idx))
14947 sh_type = bgp_show_type_flap_neighbor;
14948 else if (argv_find(argv, argc, "dampened-routes", &idx))
14949 sh_type = bgp_show_type_damp_neighbor;
14950 else if (argv_find(argv, argc, "routes", &idx))
14951 sh_type = bgp_show_type_neighbor;
14952
14953 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14954 }
14955
14956 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14957
14958 struct bgp_distance {
14959 /* Distance value for the IP source prefix. */
14960 uint8_t distance;
14961
14962 /* Name of the access-list to be matched. */
14963 char *access_list;
14964 };
14965
14966 DEFUN (show_bgp_afi_vpn_rd_route,
14967 show_bgp_afi_vpn_rd_route_cmd,
14968 "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]",
14969 SHOW_STR
14970 BGP_STR
14971 BGP_AFI_HELP_STR
14972 BGP_AF_MODIFIER_STR
14973 "Display information for a route distinguisher\n"
14974 "Route Distinguisher\n"
14975 "All Route Distinguishers\n"
14976 "Network in the BGP routing table to display\n"
14977 "Network in the BGP routing table to display\n"
14978 JSON_STR)
14979 {
14980 int ret;
14981 struct prefix_rd prd;
14982 afi_t afi = AFI_MAX;
14983 int idx = 0;
14984
14985 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14986 vty_out(vty, "%% Malformed Address Family\n");
14987 return CMD_WARNING;
14988 }
14989
14990 if (!strcmp(argv[5]->arg, "all"))
14991 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14992 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14993 RPKI_NOT_BEING_USED,
14994 use_json(argc, argv));
14995
14996 ret = str2prefix_rd(argv[5]->arg, &prd);
14997 if (!ret) {
14998 vty_out(vty, "%% Malformed Route Distinguisher\n");
14999 return CMD_WARNING;
15000 }
15001
15002 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
15003 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
15004 use_json(argc, argv));
15005 }
15006
15007 static struct bgp_distance *bgp_distance_new(void)
15008 {
15009 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
15010 }
15011
15012 static void bgp_distance_free(struct bgp_distance *bdistance)
15013 {
15014 XFREE(MTYPE_BGP_DISTANCE, bdistance);
15015 }
15016
15017 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15018 const char *ip_str, const char *access_list_str)
15019 {
15020 int ret;
15021 afi_t afi;
15022 safi_t safi;
15023 struct prefix p;
15024 uint8_t distance;
15025 struct bgp_dest *dest;
15026 struct bgp_distance *bdistance;
15027
15028 afi = bgp_node_afi(vty);
15029 safi = bgp_node_safi(vty);
15030
15031 ret = str2prefix(ip_str, &p);
15032 if (ret == 0) {
15033 vty_out(vty, "Malformed prefix\n");
15034 return CMD_WARNING_CONFIG_FAILED;
15035 }
15036
15037 distance = atoi(distance_str);
15038
15039 /* Get BGP distance node. */
15040 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15041 bdistance = bgp_dest_get_bgp_distance_info(dest);
15042 if (bdistance)
15043 bgp_dest_unlock_node(dest);
15044 else {
15045 bdistance = bgp_distance_new();
15046 bgp_dest_set_bgp_distance_info(dest, bdistance);
15047 }
15048
15049 /* Set distance value. */
15050 bdistance->distance = distance;
15051
15052 /* Reset access-list configuration. */
15053 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15054 if (access_list_str)
15055 bdistance->access_list =
15056 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15057
15058 return CMD_SUCCESS;
15059 }
15060
15061 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15062 const char *ip_str, const char *access_list_str)
15063 {
15064 int ret;
15065 afi_t afi;
15066 safi_t safi;
15067 struct prefix p;
15068 int distance;
15069 struct bgp_dest *dest;
15070 struct bgp_distance *bdistance;
15071
15072 afi = bgp_node_afi(vty);
15073 safi = bgp_node_safi(vty);
15074
15075 ret = str2prefix(ip_str, &p);
15076 if (ret == 0) {
15077 vty_out(vty, "Malformed prefix\n");
15078 return CMD_WARNING_CONFIG_FAILED;
15079 }
15080
15081 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15082 if (!dest) {
15083 vty_out(vty, "Can't find specified prefix\n");
15084 return CMD_WARNING_CONFIG_FAILED;
15085 }
15086
15087 bdistance = bgp_dest_get_bgp_distance_info(dest);
15088 distance = atoi(distance_str);
15089
15090 if (bdistance->distance != distance) {
15091 vty_out(vty, "Distance does not match configured\n");
15092 bgp_dest_unlock_node(dest);
15093 return CMD_WARNING_CONFIG_FAILED;
15094 }
15095
15096 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15097 bgp_distance_free(bdistance);
15098
15099 bgp_dest_set_bgp_path_info(dest, NULL);
15100 bgp_dest_unlock_node(dest);
15101 bgp_dest_unlock_node(dest);
15102
15103 return CMD_SUCCESS;
15104 }
15105
15106 /* Apply BGP information to distance method. */
15107 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15108 afi_t afi, safi_t safi, struct bgp *bgp)
15109 {
15110 struct bgp_dest *dest;
15111 struct prefix q = {0};
15112 struct peer *peer;
15113 struct bgp_distance *bdistance;
15114 struct access_list *alist;
15115 struct bgp_static *bgp_static;
15116 struct bgp_path_info *bpi_ultimate;
15117
15118 if (!bgp)
15119 return 0;
15120
15121 peer = pinfo->peer;
15122
15123 if (pinfo->attr->distance)
15124 return pinfo->attr->distance;
15125
15126 /* get peer origin to calculate appropriate distance */
15127 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15128 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15129 peer = bpi_ultimate->peer;
15130 }
15131
15132 /* Check source address.
15133 * Note: for aggregate route, peer can have unspec af type.
15134 */
15135 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15136 && !sockunion2hostprefix(&peer->su, &q))
15137 return 0;
15138
15139 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15140 if (dest) {
15141 bdistance = bgp_dest_get_bgp_distance_info(dest);
15142 bgp_dest_unlock_node(dest);
15143
15144 if (bdistance->access_list) {
15145 alist = access_list_lookup(afi, bdistance->access_list);
15146 if (alist
15147 && access_list_apply(alist, p) == FILTER_PERMIT)
15148 return bdistance->distance;
15149 } else
15150 return bdistance->distance;
15151 }
15152
15153 /* Backdoor check. */
15154 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15155 if (dest) {
15156 bgp_static = bgp_dest_get_bgp_static_info(dest);
15157 bgp_dest_unlock_node(dest);
15158
15159 if (bgp_static->backdoor) {
15160 if (bgp->distance_local[afi][safi])
15161 return bgp->distance_local[afi][safi];
15162 else
15163 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15164 }
15165 }
15166
15167 if (peer->sort == BGP_PEER_EBGP) {
15168 if (bgp->distance_ebgp[afi][safi])
15169 return bgp->distance_ebgp[afi][safi];
15170 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15171 } else if (peer->sort == BGP_PEER_IBGP) {
15172 if (bgp->distance_ibgp[afi][safi])
15173 return bgp->distance_ibgp[afi][safi];
15174 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15175 } else {
15176 if (bgp->distance_local[afi][safi])
15177 return bgp->distance_local[afi][safi];
15178 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15179 }
15180 }
15181
15182 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15183 * we should tell ZEBRA update the routes for a specific
15184 * AFI/SAFI to reflect changes in RIB.
15185 */
15186 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15187 afi_t update_afi,
15188 safi_t update_safi)
15189 {
15190 afi_t afi;
15191 safi_t safi;
15192
15193 FOREACH_AFI_SAFI (afi, safi) {
15194 if (!bgp_fibupd_safi(safi))
15195 continue;
15196
15197 if (afi != update_afi && safi != update_safi)
15198 continue;
15199
15200 if (BGP_DEBUG(zebra, ZEBRA))
15201 zlog_debug(
15202 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15203 __func__, afi, safi);
15204 bgp_zebra_announce_table(bgp, afi, safi);
15205 }
15206 }
15207
15208 DEFUN (bgp_distance,
15209 bgp_distance_cmd,
15210 "distance bgp (1-255) (1-255) (1-255)",
15211 "Define an administrative distance\n"
15212 "BGP distance\n"
15213 "Distance for routes external to the AS\n"
15214 "Distance for routes internal to the AS\n"
15215 "Distance for local routes\n")
15216 {
15217 VTY_DECLVAR_CONTEXT(bgp, bgp);
15218 int idx_number = 2;
15219 int idx_number_2 = 3;
15220 int idx_number_3 = 4;
15221 int distance_ebgp = atoi(argv[idx_number]->arg);
15222 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15223 int distance_local = atoi(argv[idx_number_3]->arg);
15224 afi_t afi;
15225 safi_t safi;
15226
15227 afi = bgp_node_afi(vty);
15228 safi = bgp_node_safi(vty);
15229
15230 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15231 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15232 || bgp->distance_local[afi][safi] != distance_local) {
15233 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15234 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15235 bgp->distance_local[afi][safi] = distance_local;
15236 bgp_announce_routes_distance_update(bgp, afi, safi);
15237 }
15238 return CMD_SUCCESS;
15239 }
15240
15241 DEFUN (no_bgp_distance,
15242 no_bgp_distance_cmd,
15243 "no distance bgp [(1-255) (1-255) (1-255)]",
15244 NO_STR
15245 "Define an administrative distance\n"
15246 "BGP distance\n"
15247 "Distance for routes external to the AS\n"
15248 "Distance for routes internal to the AS\n"
15249 "Distance for local routes\n")
15250 {
15251 VTY_DECLVAR_CONTEXT(bgp, bgp);
15252 afi_t afi;
15253 safi_t safi;
15254
15255 afi = bgp_node_afi(vty);
15256 safi = bgp_node_safi(vty);
15257
15258 if (bgp->distance_ebgp[afi][safi] != 0
15259 || bgp->distance_ibgp[afi][safi] != 0
15260 || bgp->distance_local[afi][safi] != 0) {
15261 bgp->distance_ebgp[afi][safi] = 0;
15262 bgp->distance_ibgp[afi][safi] = 0;
15263 bgp->distance_local[afi][safi] = 0;
15264 bgp_announce_routes_distance_update(bgp, afi, safi);
15265 }
15266 return CMD_SUCCESS;
15267 }
15268
15269
15270 DEFUN (bgp_distance_source,
15271 bgp_distance_source_cmd,
15272 "distance (1-255) A.B.C.D/M",
15273 "Define an administrative distance\n"
15274 "Administrative distance\n"
15275 "IP source prefix\n")
15276 {
15277 int idx_number = 1;
15278 int idx_ipv4_prefixlen = 2;
15279 bgp_distance_set(vty, argv[idx_number]->arg,
15280 argv[idx_ipv4_prefixlen]->arg, NULL);
15281 return CMD_SUCCESS;
15282 }
15283
15284 DEFUN (no_bgp_distance_source,
15285 no_bgp_distance_source_cmd,
15286 "no distance (1-255) A.B.C.D/M",
15287 NO_STR
15288 "Define an administrative distance\n"
15289 "Administrative distance\n"
15290 "IP source prefix\n")
15291 {
15292 int idx_number = 2;
15293 int idx_ipv4_prefixlen = 3;
15294 bgp_distance_unset(vty, argv[idx_number]->arg,
15295 argv[idx_ipv4_prefixlen]->arg, NULL);
15296 return CMD_SUCCESS;
15297 }
15298
15299 DEFUN (bgp_distance_source_access_list,
15300 bgp_distance_source_access_list_cmd,
15301 "distance (1-255) A.B.C.D/M WORD",
15302 "Define an administrative distance\n"
15303 "Administrative distance\n"
15304 "IP source prefix\n"
15305 "Access list name\n")
15306 {
15307 int idx_number = 1;
15308 int idx_ipv4_prefixlen = 2;
15309 int idx_word = 3;
15310 bgp_distance_set(vty, argv[idx_number]->arg,
15311 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15312 return CMD_SUCCESS;
15313 }
15314
15315 DEFUN (no_bgp_distance_source_access_list,
15316 no_bgp_distance_source_access_list_cmd,
15317 "no distance (1-255) A.B.C.D/M WORD",
15318 NO_STR
15319 "Define an administrative distance\n"
15320 "Administrative distance\n"
15321 "IP source prefix\n"
15322 "Access list name\n")
15323 {
15324 int idx_number = 2;
15325 int idx_ipv4_prefixlen = 3;
15326 int idx_word = 4;
15327 bgp_distance_unset(vty, argv[idx_number]->arg,
15328 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15329 return CMD_SUCCESS;
15330 }
15331
15332 DEFUN (ipv6_bgp_distance_source,
15333 ipv6_bgp_distance_source_cmd,
15334 "distance (1-255) X:X::X:X/M",
15335 "Define an administrative distance\n"
15336 "Administrative distance\n"
15337 "IP source prefix\n")
15338 {
15339 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15340 return CMD_SUCCESS;
15341 }
15342
15343 DEFUN (no_ipv6_bgp_distance_source,
15344 no_ipv6_bgp_distance_source_cmd,
15345 "no distance (1-255) X:X::X:X/M",
15346 NO_STR
15347 "Define an administrative distance\n"
15348 "Administrative distance\n"
15349 "IP source prefix\n")
15350 {
15351 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15352 return CMD_SUCCESS;
15353 }
15354
15355 DEFUN (ipv6_bgp_distance_source_access_list,
15356 ipv6_bgp_distance_source_access_list_cmd,
15357 "distance (1-255) X:X::X:X/M WORD",
15358 "Define an administrative distance\n"
15359 "Administrative distance\n"
15360 "IP source prefix\n"
15361 "Access list name\n")
15362 {
15363 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15364 return CMD_SUCCESS;
15365 }
15366
15367 DEFUN (no_ipv6_bgp_distance_source_access_list,
15368 no_ipv6_bgp_distance_source_access_list_cmd,
15369 "no distance (1-255) X:X::X:X/M WORD",
15370 NO_STR
15371 "Define an administrative distance\n"
15372 "Administrative distance\n"
15373 "IP source prefix\n"
15374 "Access list name\n")
15375 {
15376 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15377 return CMD_SUCCESS;
15378 }
15379
15380 DEFUN (bgp_damp_set,
15381 bgp_damp_set_cmd,
15382 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15383 "BGP Specific commands\n"
15384 "Enable route-flap dampening\n"
15385 "Half-life time for the penalty\n"
15386 "Value to start reusing a route\n"
15387 "Value to start suppressing a route\n"
15388 "Maximum duration to suppress a stable route\n")
15389 {
15390 VTY_DECLVAR_CONTEXT(bgp, bgp);
15391 int idx_half_life = 2;
15392 int idx_reuse = 3;
15393 int idx_suppress = 4;
15394 int idx_max_suppress = 5;
15395 int half = DEFAULT_HALF_LIFE * 60;
15396 int reuse = DEFAULT_REUSE;
15397 int suppress = DEFAULT_SUPPRESS;
15398 int max = 4 * half;
15399
15400 if (argc == 6) {
15401 half = atoi(argv[idx_half_life]->arg) * 60;
15402 reuse = atoi(argv[idx_reuse]->arg);
15403 suppress = atoi(argv[idx_suppress]->arg);
15404 max = atoi(argv[idx_max_suppress]->arg) * 60;
15405 } else if (argc == 3) {
15406 half = atoi(argv[idx_half_life]->arg) * 60;
15407 max = 4 * half;
15408 }
15409
15410 /*
15411 * These can't be 0 but our SA doesn't understand the
15412 * way our cli is constructed
15413 */
15414 assert(reuse);
15415 assert(half);
15416 if (suppress < reuse) {
15417 vty_out(vty,
15418 "Suppress value cannot be less than reuse value \n");
15419 return 0;
15420 }
15421
15422 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15423 reuse, suppress, max);
15424 }
15425
15426 DEFUN (bgp_damp_unset,
15427 bgp_damp_unset_cmd,
15428 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15429 NO_STR
15430 "BGP Specific commands\n"
15431 "Enable route-flap dampening\n"
15432 "Half-life time for the penalty\n"
15433 "Value to start reusing a route\n"
15434 "Value to start suppressing a route\n"
15435 "Maximum duration to suppress a stable route\n")
15436 {
15437 VTY_DECLVAR_CONTEXT(bgp, bgp);
15438 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15439 }
15440
15441 /* Display specified route of BGP table. */
15442 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15443 const char *ip_str, afi_t afi, safi_t safi,
15444 struct prefix_rd *prd, int prefix_check)
15445 {
15446 int ret;
15447 struct prefix match;
15448 struct bgp_dest *dest;
15449 struct bgp_dest *rm;
15450 struct bgp_path_info *pi;
15451 struct bgp_path_info *pi_temp;
15452 struct bgp *bgp;
15453 struct bgp_table *table;
15454
15455 /* BGP structure lookup. */
15456 if (view_name) {
15457 bgp = bgp_lookup_by_name(view_name);
15458 if (bgp == NULL) {
15459 vty_out(vty, "%% Can't find BGP instance %s\n",
15460 view_name);
15461 return CMD_WARNING;
15462 }
15463 } else {
15464 bgp = bgp_get_default();
15465 if (bgp == NULL) {
15466 vty_out(vty, "%% No BGP process is configured\n");
15467 return CMD_WARNING;
15468 }
15469 }
15470
15471 /* Check IP address argument. */
15472 ret = str2prefix(ip_str, &match);
15473 if (!ret) {
15474 vty_out(vty, "%% address is malformed\n");
15475 return CMD_WARNING;
15476 }
15477
15478 match.family = afi2family(afi);
15479
15480 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15481 || (safi == SAFI_EVPN)) {
15482 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15483 dest = bgp_route_next(dest)) {
15484 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15485
15486 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15487 continue;
15488 table = bgp_dest_get_bgp_table_info(dest);
15489 if (!table)
15490 continue;
15491 rm = bgp_node_match(table, &match);
15492 if (rm == NULL)
15493 continue;
15494
15495 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15496
15497 if (!prefix_check
15498 || rm_p->prefixlen == match.prefixlen) {
15499 pi = bgp_dest_get_bgp_path_info(rm);
15500 while (pi) {
15501 if (pi->extra && pi->extra->damp_info) {
15502 pi_temp = pi->next;
15503 bgp_damp_info_free(
15504 pi->extra->damp_info,
15505 1, afi, safi);
15506 pi = pi_temp;
15507 } else
15508 pi = pi->next;
15509 }
15510 }
15511
15512 bgp_dest_unlock_node(rm);
15513 }
15514 } else {
15515 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15516 if (dest != NULL) {
15517 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15518
15519 if (!prefix_check
15520 || dest_p->prefixlen == match.prefixlen) {
15521 pi = bgp_dest_get_bgp_path_info(dest);
15522 while (pi) {
15523 if (pi->extra && pi->extra->damp_info) {
15524 pi_temp = pi->next;
15525 bgp_damp_info_free(
15526 pi->extra->damp_info,
15527 1, afi, safi);
15528 pi = pi_temp;
15529 } else
15530 pi = pi->next;
15531 }
15532 }
15533
15534 bgp_dest_unlock_node(dest);
15535 }
15536 }
15537
15538 return CMD_SUCCESS;
15539 }
15540
15541 DEFUN (clear_ip_bgp_dampening,
15542 clear_ip_bgp_dampening_cmd,
15543 "clear ip bgp dampening",
15544 CLEAR_STR
15545 IP_STR
15546 BGP_STR
15547 "Clear route flap dampening information\n")
15548 {
15549 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15550 return CMD_SUCCESS;
15551 }
15552
15553 DEFUN (clear_ip_bgp_dampening_prefix,
15554 clear_ip_bgp_dampening_prefix_cmd,
15555 "clear ip bgp dampening A.B.C.D/M",
15556 CLEAR_STR
15557 IP_STR
15558 BGP_STR
15559 "Clear route flap dampening information\n"
15560 "IPv4 prefix\n")
15561 {
15562 int idx_ipv4_prefixlen = 4;
15563 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15564 AFI_IP, SAFI_UNICAST, NULL, 1);
15565 }
15566
15567 DEFUN (clear_ip_bgp_dampening_address,
15568 clear_ip_bgp_dampening_address_cmd,
15569 "clear ip bgp dampening A.B.C.D",
15570 CLEAR_STR
15571 IP_STR
15572 BGP_STR
15573 "Clear route flap dampening information\n"
15574 "Network to clear damping information\n")
15575 {
15576 int idx_ipv4 = 4;
15577 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15578 SAFI_UNICAST, NULL, 0);
15579 }
15580
15581 DEFUN (clear_ip_bgp_dampening_address_mask,
15582 clear_ip_bgp_dampening_address_mask_cmd,
15583 "clear ip bgp dampening A.B.C.D A.B.C.D",
15584 CLEAR_STR
15585 IP_STR
15586 BGP_STR
15587 "Clear route flap dampening information\n"
15588 "Network to clear damping information\n"
15589 "Network mask\n")
15590 {
15591 int idx_ipv4 = 4;
15592 int idx_ipv4_2 = 5;
15593 int ret;
15594 char prefix_str[BUFSIZ];
15595
15596 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15597 prefix_str, sizeof(prefix_str));
15598 if (!ret) {
15599 vty_out(vty, "%% Inconsistent address and mask\n");
15600 return CMD_WARNING;
15601 }
15602
15603 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15604 NULL, 0);
15605 }
15606
15607 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15608 {
15609 struct vty *vty = arg;
15610 struct peer *peer = bucket->data;
15611
15612 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15613 }
15614
15615 DEFUN (show_bgp_listeners,
15616 show_bgp_listeners_cmd,
15617 "show bgp listeners",
15618 SHOW_STR
15619 BGP_STR
15620 "Display Listen Sockets and who created them\n")
15621 {
15622 bgp_dump_listener_info(vty);
15623
15624 return CMD_SUCCESS;
15625 }
15626
15627 DEFUN (show_bgp_peerhash,
15628 show_bgp_peerhash_cmd,
15629 "show bgp peerhash",
15630 SHOW_STR
15631 BGP_STR
15632 "Display information about the BGP peerhash\n")
15633 {
15634 struct list *instances = bm->bgp;
15635 struct listnode *node;
15636 struct bgp *bgp;
15637
15638 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15639 vty_out(vty, "BGP: %s\n", bgp->name);
15640 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15641 vty);
15642 }
15643
15644 return CMD_SUCCESS;
15645 }
15646
15647 /* also used for encap safi */
15648 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15649 afi_t afi, safi_t safi)
15650 {
15651 struct bgp_dest *pdest;
15652 struct bgp_dest *dest;
15653 struct bgp_table *table;
15654 const struct prefix *p;
15655 struct bgp_static *bgp_static;
15656 mpls_label_t label;
15657
15658 /* Network configuration. */
15659 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15660 pdest = bgp_route_next(pdest)) {
15661 table = bgp_dest_get_bgp_table_info(pdest);
15662 if (!table)
15663 continue;
15664
15665 for (dest = bgp_table_top(table); dest;
15666 dest = bgp_route_next(dest)) {
15667 bgp_static = bgp_dest_get_bgp_static_info(dest);
15668 if (bgp_static == NULL)
15669 continue;
15670
15671 p = bgp_dest_get_prefix(dest);
15672
15673 /* "network" configuration display. */
15674 label = decode_label(&bgp_static->label);
15675
15676 vty_out(vty, " network %pFX rd %s", p,
15677 bgp_static->prd_pretty);
15678 if (safi == SAFI_MPLS_VPN)
15679 vty_out(vty, " label %u", label);
15680
15681 if (bgp_static->rmap.name)
15682 vty_out(vty, " route-map %s",
15683 bgp_static->rmap.name);
15684
15685 if (bgp_static->backdoor)
15686 vty_out(vty, " backdoor");
15687
15688 vty_out(vty, "\n");
15689 }
15690 }
15691 }
15692
15693 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15694 afi_t afi, safi_t safi)
15695 {
15696 struct bgp_dest *pdest;
15697 struct bgp_dest *dest;
15698 struct bgp_table *table;
15699 const struct prefix *p;
15700 struct bgp_static *bgp_static;
15701 char buf[PREFIX_STRLEN * 2];
15702 char buf2[SU_ADDRSTRLEN];
15703 char esi_buf[ESI_STR_LEN];
15704
15705 /* Network configuration. */
15706 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15707 pdest = bgp_route_next(pdest)) {
15708 table = bgp_dest_get_bgp_table_info(pdest);
15709 if (!table)
15710 continue;
15711
15712 for (dest = bgp_table_top(table); dest;
15713 dest = bgp_route_next(dest)) {
15714 bgp_static = bgp_dest_get_bgp_static_info(dest);
15715 if (bgp_static == NULL)
15716 continue;
15717
15718 char *macrouter = NULL;
15719
15720 if (bgp_static->router_mac)
15721 macrouter = prefix_mac2str(
15722 bgp_static->router_mac, NULL, 0);
15723 if (bgp_static->eth_s_id)
15724 esi_to_str(bgp_static->eth_s_id,
15725 esi_buf, sizeof(esi_buf));
15726 p = bgp_dest_get_prefix(dest);
15727
15728 /* "network" configuration display. */
15729 if (p->u.prefix_evpn.route_type == 5) {
15730 char local_buf[PREFIX_STRLEN];
15731
15732 uint8_t family = is_evpn_prefix_ipaddr_v4((
15733 struct prefix_evpn *)p)
15734 ? AF_INET
15735 : AF_INET6;
15736 inet_ntop(family,
15737 &p->u.prefix_evpn.prefix_addr.ip.ip
15738 .addr,
15739 local_buf, sizeof(local_buf));
15740 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15741 p->u.prefix_evpn.prefix_addr
15742 .ip_prefix_length);
15743 } else {
15744 prefix2str(p, buf, sizeof(buf));
15745 }
15746
15747 if (bgp_static->gatewayIp.family == AF_INET
15748 || bgp_static->gatewayIp.family == AF_INET6)
15749 inet_ntop(bgp_static->gatewayIp.family,
15750 &bgp_static->gatewayIp.u.prefix, buf2,
15751 sizeof(buf2));
15752 vty_out(vty,
15753 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15754 buf, bgp_static->prd_pretty,
15755 p->u.prefix_evpn.prefix_addr.eth_tag,
15756 decode_label(&bgp_static->label), esi_buf, buf2,
15757 macrouter);
15758
15759 XFREE(MTYPE_TMP, macrouter);
15760 }
15761 }
15762 }
15763
15764 /* Configuration of static route announcement and aggregate
15765 information. */
15766 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15767 safi_t safi)
15768 {
15769 struct bgp_dest *dest;
15770 const struct prefix *p;
15771 struct bgp_static *bgp_static;
15772 struct bgp_aggregate *bgp_aggregate;
15773
15774 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15775 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15776 return;
15777 }
15778
15779 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15780 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15781 return;
15782 }
15783
15784 /* Network configuration. */
15785 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15786 dest = bgp_route_next(dest)) {
15787 bgp_static = bgp_dest_get_bgp_static_info(dest);
15788 if (bgp_static == NULL)
15789 continue;
15790
15791 p = bgp_dest_get_prefix(dest);
15792
15793 vty_out(vty, " network %pFX", p);
15794
15795 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15796 vty_out(vty, " label-index %u",
15797 bgp_static->label_index);
15798
15799 if (bgp_static->rmap.name)
15800 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15801
15802 if (bgp_static->backdoor)
15803 vty_out(vty, " backdoor");
15804
15805 vty_out(vty, "\n");
15806 }
15807
15808 /* Aggregate-address configuration. */
15809 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15810 dest = bgp_route_next(dest)) {
15811 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15812 if (bgp_aggregate == NULL)
15813 continue;
15814
15815 p = bgp_dest_get_prefix(dest);
15816
15817 vty_out(vty, " aggregate-address %pFX", p);
15818
15819 if (bgp_aggregate->as_set)
15820 vty_out(vty, " as-set");
15821
15822 if (bgp_aggregate->summary_only)
15823 vty_out(vty, " summary-only");
15824
15825 if (bgp_aggregate->rmap.name)
15826 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15827
15828 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15829 vty_out(vty, " origin %s",
15830 bgp_origin2str(bgp_aggregate->origin));
15831
15832 if (bgp_aggregate->match_med)
15833 vty_out(vty, " matching-MED-only");
15834
15835 if (bgp_aggregate->suppress_map_name)
15836 vty_out(vty, " suppress-map %s",
15837 bgp_aggregate->suppress_map_name);
15838
15839 vty_out(vty, "\n");
15840 }
15841 }
15842
15843 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15844 safi_t safi)
15845 {
15846 struct bgp_dest *dest;
15847 struct bgp_distance *bdistance;
15848
15849 /* Distance configuration. */
15850 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15851 && bgp->distance_local[afi][safi]
15852 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15853 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15854 || bgp->distance_local[afi][safi]
15855 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15856 vty_out(vty, " distance bgp %d %d %d\n",
15857 bgp->distance_ebgp[afi][safi],
15858 bgp->distance_ibgp[afi][safi],
15859 bgp->distance_local[afi][safi]);
15860 }
15861
15862 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15863 dest = bgp_route_next(dest)) {
15864 bdistance = bgp_dest_get_bgp_distance_info(dest);
15865 if (bdistance != NULL)
15866 vty_out(vty, " distance %d %pBD %s\n",
15867 bdistance->distance, dest,
15868 bdistance->access_list ? bdistance->access_list
15869 : "");
15870 }
15871 }
15872
15873 /* Allocate routing table structure and install commands. */
15874 void bgp_route_init(void)
15875 {
15876 afi_t afi;
15877 safi_t safi;
15878
15879 /* Init BGP distance table. */
15880 FOREACH_AFI_SAFI (afi, safi)
15881 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15882
15883 /* IPv4 BGP commands. */
15884 install_element(BGP_NODE, &bgp_table_map_cmd);
15885 install_element(BGP_NODE, &bgp_network_cmd);
15886 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15887
15888 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15889
15890 /* IPv4 unicast configuration. */
15891 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15892 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15893 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15894
15895 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15896
15897 /* IPv4 multicast configuration. */
15898 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15899 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15900 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15901 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15902
15903 /* IPv4 labeled-unicast configuration. */
15904 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15905 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15906
15907 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15908 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15909 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15910 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15911 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15912 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15913 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15914 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15915
15916 install_element(VIEW_NODE,
15917 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15918 install_element(VIEW_NODE,
15919 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15920 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15921 install_element(VIEW_NODE,
15922 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15923 #ifdef KEEP_OLD_VPN_COMMANDS
15924 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15925 #endif /* KEEP_OLD_VPN_COMMANDS */
15926 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15927 install_element(VIEW_NODE,
15928 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15929
15930 /* BGP dampening clear commands */
15931 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15932 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15933
15934 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15935 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15936
15937 /* prefix count */
15938 install_element(ENABLE_NODE,
15939 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15940 #ifdef KEEP_OLD_VPN_COMMANDS
15941 install_element(ENABLE_NODE,
15942 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15943 #endif /* KEEP_OLD_VPN_COMMANDS */
15944
15945 /* New config IPv6 BGP commands. */
15946 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15947 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15948 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15949
15950 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15951
15952 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15953
15954 /* IPv6 labeled unicast address family. */
15955 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15956 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15957
15958 install_element(BGP_NODE, &bgp_distance_cmd);
15959 install_element(BGP_NODE, &no_bgp_distance_cmd);
15960 install_element(BGP_NODE, &bgp_distance_source_cmd);
15961 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15962 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15963 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15964 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15965 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15966 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15967 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15968 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15969 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15970 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15971 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15972 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15973 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15974 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15975 install_element(BGP_IPV4M_NODE,
15976 &no_bgp_distance_source_access_list_cmd);
15977 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15978 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15979 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15980 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15981 install_element(BGP_IPV6_NODE,
15982 &ipv6_bgp_distance_source_access_list_cmd);
15983 install_element(BGP_IPV6_NODE,
15984 &no_ipv6_bgp_distance_source_access_list_cmd);
15985 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15986 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15987 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15988 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15989 install_element(BGP_IPV6M_NODE,
15990 &ipv6_bgp_distance_source_access_list_cmd);
15991 install_element(BGP_IPV6M_NODE,
15992 &no_ipv6_bgp_distance_source_access_list_cmd);
15993
15994 /* BGP dampening */
15995 install_element(BGP_NODE, &bgp_damp_set_cmd);
15996 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15997 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15998 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15999 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
16000 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
16001 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
16002 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
16003 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
16004 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
16005 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
16006 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
16007 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
16008 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
16009
16010 /* Large Communities */
16011 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
16012 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
16013
16014 /* show bgp ipv4 flowspec detailed */
16015 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
16016
16017 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16018 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16019 }
16020
16021 void bgp_route_finish(void)
16022 {
16023 afi_t afi;
16024 safi_t safi;
16025
16026 FOREACH_AFI_SAFI (afi, safi) {
16027 bgp_table_unlock(bgp_distance_table[afi][safi]);
16028 bgp_distance_table[afi][safi] = NULL;
16029 }
16030 }