]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: fix bgp label value when static route used
[mirror_frr.git] / bgpd / bgp_route.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP routing information
3 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
4 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 */
6
7 #include <zebra.h>
8 #include <math.h>
9
10 #include "printfrr.h"
11 #include "frrstr.h"
12 #include "prefix.h"
13 #include "linklist.h"
14 #include "memory.h"
15 #include "command.h"
16 #include "stream.h"
17 #include "filter.h"
18 #include "log.h"
19 #include "routemap.h"
20 #include "buffer.h"
21 #include "sockunion.h"
22 #include "plist.h"
23 #include "frrevent.h"
24 #include "workqueue.h"
25 #include "queue.h"
26 #include "memory.h"
27 #include "srv6.h"
28 #include "lib/json.h"
29 #include "lib_errors.h"
30 #include "zclient.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_regex.h"
39 #include "bgpd/bgp_community.h"
40 #include "bgpd/bgp_community_alias.h"
41 #include "bgpd/bgp_ecommunity.h"
42 #include "bgpd/bgp_lcommunity.h"
43 #include "bgpd/bgp_clist.h"
44 #include "bgpd/bgp_packet.h"
45 #include "bgpd/bgp_filter.h"
46 #include "bgpd/bgp_fsm.h"
47 #include "bgpd/bgp_mplsvpn.h"
48 #include "bgpd/bgp_nexthop.h"
49 #include "bgpd/bgp_damp.h"
50 #include "bgpd/bgp_advertise.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_vty.h"
53 #include "bgpd/bgp_mpath.h"
54 #include "bgpd/bgp_nht.h"
55 #include "bgpd/bgp_updgrp.h"
56 #include "bgpd/bgp_label.h"
57 #include "bgpd/bgp_addpath.h"
58 #include "bgpd/bgp_mac.h"
59 #include "bgpd/bgp_network.h"
60 #include "bgpd/bgp_trace.h"
61 #include "bgpd/bgp_rpki.h"
62
63 #ifdef ENABLE_BGP_VNC
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #include "bgpd/rfapi/vnc_import_bgp.h"
66 #include "bgpd/rfapi/vnc_export_bgp.h"
67 #endif
68 #include "bgpd/bgp_encap_types.h"
69 #include "bgpd/bgp_encap_tlv.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_evpn_mh.h"
72 #include "bgpd/bgp_evpn_vty.h"
73 #include "bgpd/bgp_flowspec.h"
74 #include "bgpd/bgp_flowspec_util.h"
75 #include "bgpd/bgp_pbr.h"
76
77 #include "bgpd/bgp_route_clippy.c"
78
79 DEFINE_HOOK(bgp_snmp_update_stats,
80 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
81 (rn, pi, added));
82
83 DEFINE_HOOK(bgp_rpki_prefix_status,
84 (struct peer *peer, struct attr *attr,
85 const struct prefix *prefix),
86 (peer, attr, prefix));
87
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str[];
90 extern const char *bgp_origin_long_str[];
91
92 /* PMSI strings. */
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str[] = {
96 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
104 {0}
105 };
106
107 #define VRFID_NONE_STR "-"
108 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
109
110 DEFINE_HOOK(bgp_process,
111 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
112 struct peer *peer, bool withdraw),
113 (bgp, afi, safi, bn, peer, withdraw));
114
115 /** Test if path is suppressed. */
116 static bool bgp_path_suppressed(struct bgp_path_info *pi)
117 {
118 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
119 return false;
120
121 return listcount(pi->extra->aggr_suppressors) > 0;
122 }
123
124 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
125 safi_t safi, const struct prefix *p,
126 struct prefix_rd *prd)
127 {
128 struct bgp_dest *dest;
129 struct bgp_dest *pdest = NULL;
130
131 assert(table);
132
133 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
134 || (safi == SAFI_EVPN)) {
135 pdest = bgp_node_get(table, (struct prefix *)prd);
136
137 if (!bgp_dest_has_bgp_path_info_data(pdest))
138 bgp_dest_set_bgp_table_info(
139 pdest, bgp_table_init(table->bgp, afi, safi));
140 else
141 bgp_dest_unlock_node(pdest);
142 table = bgp_dest_get_bgp_table_info(pdest);
143 }
144
145 dest = bgp_node_get(table, p);
146
147 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
148 || (safi == SAFI_EVPN))
149 dest->pdest = pdest;
150
151 return dest;
152 }
153
154 struct bgp_dest *bgp_safi_node_lookup(struct bgp_table *table, safi_t safi,
155 const struct prefix *p,
156 struct prefix_rd *prd)
157 {
158 struct bgp_dest *dest;
159 struct bgp_dest *pdest = NULL;
160
161 if (!table)
162 return NULL;
163
164 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
165 || (safi == SAFI_EVPN)) {
166 pdest = bgp_node_lookup(table, (struct prefix *)prd);
167 if (!pdest)
168 return NULL;
169
170 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
171 bgp_dest_unlock_node(pdest);
172 return NULL;
173 }
174
175 table = bgp_dest_get_bgp_table_info(pdest);
176 }
177
178 dest = bgp_node_lookup(table, p);
179
180 return dest;
181 }
182
183 /* Allocate bgp_path_info_extra */
184 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
185 {
186 struct bgp_path_info_extra *new;
187 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
188 sizeof(struct bgp_path_info_extra));
189 new->label[0] = MPLS_INVALID_LABEL;
190 new->num_labels = 0;
191 new->bgp_fs_pbr = NULL;
192 new->bgp_fs_iprule = NULL;
193 return new;
194 }
195
196 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
197 {
198 struct bgp_path_info_extra *e;
199
200 if (!extra || !*extra)
201 return;
202
203 e = *extra;
204 if (e->damp_info)
205 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
206 e->damp_info->safi);
207
208 e->damp_info = NULL;
209 if (e->parent) {
210 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
211
212 if (bpi->net) {
213 /* FIXME: since multiple e may have the same e->parent
214 * and e->parent->net is holding a refcount for each
215 * of them, we need to do some fudging here.
216 *
217 * WARNING: if bpi->net->lock drops to 0, bpi may be
218 * freed as well (because bpi->net was holding the
219 * last reference to bpi) => write after free!
220 */
221 unsigned refcount;
222
223 bpi = bgp_path_info_lock(bpi);
224 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
225 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
226 if (!refcount)
227 bpi->net = NULL;
228 bgp_path_info_unlock(bpi);
229 }
230 bgp_path_info_unlock(e->parent);
231 e->parent = NULL;
232 }
233
234 if (e->bgp_orig)
235 bgp_unlock(e->bgp_orig);
236
237 if (e->peer_orig)
238 peer_unlock(e->peer_orig);
239
240 if (e->aggr_suppressors)
241 list_delete(&e->aggr_suppressors);
242
243 if (e->mh_info)
244 bgp_evpn_path_mh_info_free(e->mh_info);
245
246 if ((*extra)->bgp_fs_iprule)
247 list_delete(&((*extra)->bgp_fs_iprule));
248 if ((*extra)->bgp_fs_pbr)
249 list_delete(&((*extra)->bgp_fs_pbr));
250 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
251 }
252
253 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
254 * allocated if required.
255 */
256 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
257 {
258 if (!pi->extra)
259 pi->extra = bgp_path_info_extra_new();
260 return pi->extra;
261 }
262
263 /* Free bgp route information. */
264 void bgp_path_info_free_with_caller(const char *name,
265 struct bgp_path_info *path)
266 {
267 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
268 bgp_attr_unintern(&path->attr);
269
270 bgp_unlink_nexthop(path);
271 bgp_path_info_extra_free(&path->extra);
272 bgp_path_info_mpath_free(&path->mpath);
273 if (path->net)
274 bgp_addpath_free_info_data(&path->tx_addpath,
275 &path->net->tx_addpath);
276
277 peer_unlock(path->peer); /* bgp_path_info peer reference */
278
279 XFREE(MTYPE_BGP_ROUTE, path);
280 }
281
282 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
283 {
284 path->lock++;
285 return path;
286 }
287
288 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
289 {
290 assert(path && path->lock > 0);
291 path->lock--;
292
293 if (path->lock == 0) {
294 bgp_path_info_free(path);
295 return NULL;
296 }
297
298 return path;
299 }
300
301 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
302 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
303 {
304 struct peer *peer;
305 struct bgp_path_info *old_pi, *nextpi;
306 bool set_flag = false;
307 struct bgp *bgp = NULL;
308 struct bgp_table *table = NULL;
309 afi_t afi = 0;
310 safi_t safi = 0;
311
312 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
313 * then the route selection is deferred
314 */
315 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
316 return 0;
317
318 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
319 if (BGP_DEBUG(update, UPDATE_OUT)) {
320 table = bgp_dest_table(dest);
321 if (table)
322 bgp = table->bgp;
323
324 zlog_debug(
325 "Route %pBD(%s) is in workqueue and being processed, not deferred.",
326 dest, bgp ? bgp->name_pretty : "(Unknown)");
327 }
328
329 return 0;
330 }
331
332 table = bgp_dest_table(dest);
333 if (table) {
334 bgp = table->bgp;
335 afi = table->afi;
336 safi = table->safi;
337 }
338
339 for (old_pi = bgp_dest_get_bgp_path_info(dest);
340 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
341 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
342 continue;
343
344 /* Route selection is deferred if there is a stale path which
345 * which indicates peer is in restart mode
346 */
347 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
348 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
349 set_flag = true;
350 } else {
351 /* If the peer is graceful restart capable and peer is
352 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
353 */
354 peer = old_pi->peer;
355 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
356 && BGP_PEER_RESTARTING_MODE(peer)
357 && (old_pi
358 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
359 set_flag = true;
360 }
361 }
362 if (set_flag)
363 break;
364 }
365
366 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
367 * is active
368 */
369 if (set_flag && table) {
370 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
371 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
372 bgp->gr_info[afi][safi].gr_deferred++;
373 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
374 if (BGP_DEBUG(update, UPDATE_OUT))
375 zlog_debug("DEFER route %pBD(%s), dest %p",
376 dest, bgp->name_pretty, dest);
377 return 0;
378 }
379 }
380 return -1;
381 }
382
383 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
384 struct bgp_path_info *pi)
385 {
386 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
387 struct bgp_path_info *top;
388
389 top = bgp_dest_get_bgp_path_info(dest);
390
391 pi->next = top;
392 pi->prev = NULL;
393 if (top)
394 top->prev = pi;
395 bgp_dest_set_bgp_path_info(dest, pi);
396
397 bgp_path_info_lock(pi);
398 bgp_dest_lock_node(dest);
399 peer_lock(pi->peer); /* bgp_path_info peer reference */
400 bgp_dest_set_defer_flag(dest, false);
401 hook_call(bgp_snmp_update_stats, dest, pi, true);
402 }
403
404 /* Do the actual removal of info from RIB, for use by bgp_process
405 completion callback *only* */
406 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
407 {
408 if (pi->next)
409 pi->next->prev = pi->prev;
410 if (pi->prev)
411 pi->prev->next = pi->next;
412 else
413 bgp_dest_set_bgp_path_info(dest, pi->next);
414
415 bgp_path_info_mpath_dequeue(pi);
416 bgp_path_info_unlock(pi);
417 hook_call(bgp_snmp_update_stats, dest, pi, false);
418 bgp_dest_unlock_node(dest);
419 }
420
421 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
422 {
423 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
424 /* set of previous already took care of pcount */
425 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
426 }
427
428 /* undo the effects of a previous call to bgp_path_info_delete; typically
429 called when a route is deleted and then quickly re-added before the
430 deletion has been processed */
431 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
432 {
433 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
434 /* unset of previous already took care of pcount */
435 SET_FLAG(pi->flags, BGP_PATH_VALID);
436 }
437
438 /* Adjust pcount as required */
439 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
440 {
441 struct bgp_table *table;
442
443 assert(dest && bgp_dest_table(dest));
444 assert(pi && pi->peer && pi->peer->bgp);
445
446 table = bgp_dest_table(dest);
447
448 if (pi->peer == pi->peer->bgp->peer_self)
449 return;
450
451 if (!BGP_PATH_COUNTABLE(pi)
452 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
453
454 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
455
456 /* slight hack, but more robust against errors. */
457 if (pi->peer->pcount[table->afi][table->safi])
458 pi->peer->pcount[table->afi][table->safi]--;
459 else
460 flog_err(EC_LIB_DEVELOPMENT,
461 "Asked to decrement 0 prefix count for peer");
462 } else if (BGP_PATH_COUNTABLE(pi)
463 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
464 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
465 pi->peer->pcount[table->afi][table->safi]++;
466 }
467 }
468
469 static int bgp_label_index_differs(struct bgp_path_info *pi1,
470 struct bgp_path_info *pi2)
471 {
472 return (!(pi1->attr->label_index == pi2->attr->label_index));
473 }
474
475 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
476 * This is here primarily to keep prefix-count in check.
477 */
478 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
479 uint32_t flag)
480 {
481 SET_FLAG(pi->flags, flag);
482
483 /* early bath if we know it's not a flag that changes countability state
484 */
485 if (!CHECK_FLAG(flag,
486 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
487 return;
488
489 bgp_pcount_adjust(dest, pi);
490 }
491
492 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
493 uint32_t flag)
494 {
495 UNSET_FLAG(pi->flags, flag);
496
497 /* early bath if we know it's not a flag that changes countability state
498 */
499 if (!CHECK_FLAG(flag,
500 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
501 return;
502
503 bgp_pcount_adjust(dest, pi);
504 }
505
506 /* Get MED value. If MED value is missing and "bgp bestpath
507 missing-as-worst" is specified, treat it as the worst value. */
508 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
509 {
510 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
511 return attr->med;
512 else {
513 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
514 return BGP_MED_MAX;
515 else
516 return 0;
517 }
518 }
519
520 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
521 size_t buf_len)
522 {
523 struct peer *peer;
524
525 if (pi->sub_type == BGP_ROUTE_IMPORTED &&
526 bgp_get_imported_bpi_ultimate(pi))
527 peer = bgp_get_imported_bpi_ultimate(pi)->peer;
528 else
529 peer = pi->peer;
530
531 if (pi->addpath_rx_id)
532 snprintf(buf, buf_len, "path %s (addpath rxid %d)", peer->host,
533 pi->addpath_rx_id);
534 else
535 snprintf(buf, buf_len, "path %s", peer->host);
536 }
537
538
539 /*
540 * Get the ultimate path info.
541 */
542 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
543 {
544 struct bgp_path_info *bpi_ultimate;
545
546 if (info->sub_type != BGP_ROUTE_IMPORTED)
547 return info;
548
549 for (bpi_ultimate = info;
550 bpi_ultimate->extra && bpi_ultimate->extra->parent;
551 bpi_ultimate = bpi_ultimate->extra->parent)
552 ;
553
554 return bpi_ultimate;
555 }
556
557 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
558 */
559 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
560 struct bgp_path_info *exist, int *paths_eq,
561 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
562 char *pfx_buf, afi_t afi, safi_t safi,
563 enum bgp_path_selection_reason *reason)
564 {
565 const struct prefix *new_p;
566 struct attr *newattr, *existattr;
567 enum bgp_peer_sort new_sort;
568 enum bgp_peer_sort exist_sort;
569 uint32_t new_pref;
570 uint32_t exist_pref;
571 uint32_t new_med;
572 uint32_t exist_med;
573 uint32_t new_weight;
574 uint32_t exist_weight;
575 uint32_t newm, existm;
576 struct in_addr new_id;
577 struct in_addr exist_id;
578 int new_cluster;
579 int exist_cluster;
580 int internal_as_route;
581 int confed_as_route;
582 int ret = 0;
583 int igp_metric_ret = 0;
584 int peer_sort_ret = -1;
585 char new_buf[PATH_ADDPATH_STR_BUFFER];
586 char exist_buf[PATH_ADDPATH_STR_BUFFER];
587 uint32_t new_mm_seq;
588 uint32_t exist_mm_seq;
589 int nh_cmp;
590 esi_t *exist_esi;
591 esi_t *new_esi;
592 bool same_esi;
593 bool old_proxy;
594 bool new_proxy;
595 bool new_origin, exist_origin;
596 struct bgp_path_info *bpi_ultimate;
597 struct peer *peer_new, *peer_exist;
598
599 *paths_eq = 0;
600
601 /* 0. Null check. */
602 if (new == NULL) {
603 *reason = bgp_path_selection_none;
604 if (debug)
605 zlog_debug("%s: new is NULL", pfx_buf);
606 return 0;
607 }
608
609 if (debug) {
610 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
611 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
612 sizeof(new_buf));
613 }
614
615 if (exist == NULL) {
616 *reason = bgp_path_selection_first;
617 if (debug)
618 zlog_debug("%s(%s): %s is the initial bestpath",
619 pfx_buf, bgp->name_pretty, new_buf);
620 return 1;
621 }
622
623 if (debug) {
624 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
625 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
626 sizeof(exist_buf));
627 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
628 pfx_buf, bgp->name_pretty, new_buf, new->flags,
629 exist_buf, exist->flags);
630 }
631
632 newattr = new->attr;
633 existattr = exist->attr;
634
635 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
636 * Capability" to a neighbor MUST perform the following upon receiving
637 * a route from that neighbor with the "LLGR_STALE" community, or upon
638 * attaching the "LLGR_STALE" community itself per Section 4.2:
639 *
640 * Treat the route as the least-preferred in route selection (see
641 * below). See the Risks of Depreferencing Routes section (Section 5.2)
642 * for a discussion of potential risks inherent in doing this.
643 */
644 if (bgp_attr_get_community(newattr) &&
645 community_include(bgp_attr_get_community(newattr),
646 COMMUNITY_LLGR_STALE)) {
647 if (debug)
648 zlog_debug(
649 "%s: %s wins over %s due to LLGR_STALE community",
650 pfx_buf, new_buf, exist_buf);
651 return 0;
652 }
653
654 if (bgp_attr_get_community(existattr) &&
655 community_include(bgp_attr_get_community(existattr),
656 COMMUNITY_LLGR_STALE)) {
657 if (debug)
658 zlog_debug(
659 "%s: %s loses to %s due to LLGR_STALE community",
660 pfx_buf, new_buf, exist_buf);
661 return 1;
662 }
663
664 new_p = bgp_dest_get_prefix(new->net);
665
666 /* For EVPN routes, we cannot just go by local vs remote, we have to
667 * look at the MAC mobility sequence number, if present.
668 */
669 if ((safi == SAFI_EVPN)
670 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
671 /* This is an error condition described in RFC 7432 Section
672 * 15.2. The RFC
673 * states that in this scenario "the PE MUST alert the operator"
674 * but it
675 * does not state what other action to take. In order to provide
676 * some
677 * consistency in this scenario we are going to prefer the path
678 * with the
679 * sticky flag.
680 */
681 if (newattr->sticky != existattr->sticky) {
682 if (!debug) {
683 prefix2str(new_p, pfx_buf,
684 sizeof(*pfx_buf)
685 * PREFIX2STR_BUFFER);
686 bgp_path_info_path_with_addpath_rx_str(
687 new, new_buf, sizeof(new_buf));
688 bgp_path_info_path_with_addpath_rx_str(
689 exist, exist_buf, sizeof(exist_buf));
690 }
691
692 if (newattr->sticky && !existattr->sticky) {
693 *reason = bgp_path_selection_evpn_sticky_mac;
694 if (debug)
695 zlog_debug(
696 "%s: %s wins over %s due to sticky MAC flag",
697 pfx_buf, new_buf, exist_buf);
698 return 1;
699 }
700
701 if (!newattr->sticky && existattr->sticky) {
702 *reason = bgp_path_selection_evpn_sticky_mac;
703 if (debug)
704 zlog_debug(
705 "%s: %s loses to %s due to sticky MAC flag",
706 pfx_buf, new_buf, exist_buf);
707 return 0;
708 }
709 }
710
711 new_esi = bgp_evpn_attr_get_esi(newattr);
712 exist_esi = bgp_evpn_attr_get_esi(existattr);
713 if (bgp_evpn_is_esi_valid(new_esi) &&
714 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
715 same_esi = true;
716 } else {
717 same_esi = false;
718 }
719
720 /* If both paths have the same non-zero ES and
721 * one path is local it wins.
722 * PS: Note the local path wins even if the remote
723 * has the higher MM seq. The local path's
724 * MM seq will be fixed up to match the highest
725 * rem seq, subsequently.
726 */
727 if (same_esi) {
728 char esi_buf[ESI_STR_LEN];
729
730 if (bgp_evpn_is_path_local(bgp, new)) {
731 *reason = bgp_path_selection_evpn_local_path;
732 if (debug)
733 zlog_debug(
734 "%s: %s wins over %s as ES %s is same and local",
735 pfx_buf, new_buf, exist_buf,
736 esi_to_str(new_esi, esi_buf,
737 sizeof(esi_buf)));
738 return 1;
739 }
740 if (bgp_evpn_is_path_local(bgp, exist)) {
741 *reason = bgp_path_selection_evpn_local_path;
742 if (debug)
743 zlog_debug(
744 "%s: %s loses to %s as ES %s is same and local",
745 pfx_buf, new_buf, exist_buf,
746 esi_to_str(new_esi, esi_buf,
747 sizeof(esi_buf)));
748 return 0;
749 }
750 }
751
752 new_mm_seq = mac_mobility_seqnum(newattr);
753 exist_mm_seq = mac_mobility_seqnum(existattr);
754
755 if (new_mm_seq > exist_mm_seq) {
756 *reason = bgp_path_selection_evpn_seq;
757 if (debug)
758 zlog_debug(
759 "%s: %s wins over %s due to MM seq %u > %u",
760 pfx_buf, new_buf, exist_buf, new_mm_seq,
761 exist_mm_seq);
762 return 1;
763 }
764
765 if (new_mm_seq < exist_mm_seq) {
766 *reason = bgp_path_selection_evpn_seq;
767 if (debug)
768 zlog_debug(
769 "%s: %s loses to %s due to MM seq %u < %u",
770 pfx_buf, new_buf, exist_buf, new_mm_seq,
771 exist_mm_seq);
772 return 0;
773 }
774
775 /* if the sequence numbers and ESI are the same and one path
776 * is non-proxy it wins (over proxy)
777 */
778 new_proxy = bgp_evpn_attr_is_proxy(newattr);
779 old_proxy = bgp_evpn_attr_is_proxy(existattr);
780 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
781 old_proxy != new_proxy) {
782 if (!new_proxy) {
783 *reason = bgp_path_selection_evpn_non_proxy;
784 if (debug)
785 zlog_debug(
786 "%s: %s wins over %s, same seq/es and non-proxy",
787 pfx_buf, new_buf, exist_buf);
788 return 1;
789 }
790
791 *reason = bgp_path_selection_evpn_non_proxy;
792 if (debug)
793 zlog_debug(
794 "%s: %s loses to %s, same seq/es and non-proxy",
795 pfx_buf, new_buf, exist_buf);
796 return 0;
797 }
798
799 /*
800 * if sequence numbers are the same path with the lowest IP
801 * wins
802 */
803 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
804 if (nh_cmp < 0) {
805 *reason = bgp_path_selection_evpn_lower_ip;
806 if (debug)
807 zlog_debug(
808 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
809 pfx_buf, new_buf, exist_buf, new_mm_seq,
810 &new->attr->nexthop);
811 return 1;
812 }
813 if (nh_cmp > 0) {
814 *reason = bgp_path_selection_evpn_lower_ip;
815 if (debug)
816 zlog_debug(
817 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
818 pfx_buf, new_buf, exist_buf, new_mm_seq,
819 &new->attr->nexthop);
820 return 0;
821 }
822 }
823
824 /* 1. Weight check. */
825 new_weight = newattr->weight;
826 exist_weight = existattr->weight;
827
828 if (new_weight > exist_weight) {
829 *reason = bgp_path_selection_weight;
830 if (debug)
831 zlog_debug("%s: %s wins over %s due to weight %d > %d",
832 pfx_buf, new_buf, exist_buf, new_weight,
833 exist_weight);
834 return 1;
835 }
836
837 if (new_weight < exist_weight) {
838 *reason = bgp_path_selection_weight;
839 if (debug)
840 zlog_debug("%s: %s loses to %s due to weight %d < %d",
841 pfx_buf, new_buf, exist_buf, new_weight,
842 exist_weight);
843 return 0;
844 }
845
846 /* 2. Local preference check. */
847 new_pref = exist_pref = bgp->default_local_pref;
848
849 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
850 new_pref = newattr->local_pref;
851 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
852 exist_pref = existattr->local_pref;
853
854 if (new_pref > exist_pref) {
855 *reason = bgp_path_selection_local_pref;
856 if (debug)
857 zlog_debug(
858 "%s: %s wins over %s due to localpref %d > %d",
859 pfx_buf, new_buf, exist_buf, new_pref,
860 exist_pref);
861 return 1;
862 }
863
864 if (new_pref < exist_pref) {
865 *reason = bgp_path_selection_local_pref;
866 if (debug)
867 zlog_debug(
868 "%s: %s loses to %s due to localpref %d < %d",
869 pfx_buf, new_buf, exist_buf, new_pref,
870 exist_pref);
871 return 0;
872 }
873
874 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
875 * extensions defined in this document, the following step is inserted
876 * after the LOCAL_PREF comparison step in the BGP decision process:
877 * When comparing a pair of routes for a BGP destination, the
878 * route with the ACCEPT_OWN community attached is preferred over
879 * the route that does not have the community.
880 * This extra step MUST only be invoked during the best path selection
881 * process of VPN-IP routes.
882 */
883 if (safi == SAFI_MPLS_VPN &&
884 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
885 CHECK_FLAG(exist->peer->af_flags[afi][safi],
886 PEER_FLAG_ACCEPT_OWN))) {
887 bool new_accept_own = false;
888 bool exist_accept_own = false;
889 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
890
891 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
892 new_accept_own = community_include(
893 bgp_attr_get_community(newattr), accept_own);
894 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
895 exist_accept_own = community_include(
896 bgp_attr_get_community(existattr), accept_own);
897
898 if (new_accept_own && !exist_accept_own) {
899 *reason = bgp_path_selection_accept_own;
900 if (debug)
901 zlog_debug(
902 "%s: %s wins over %s due to accept-own",
903 pfx_buf, new_buf, exist_buf);
904 return 1;
905 }
906
907 if (!new_accept_own && exist_accept_own) {
908 *reason = bgp_path_selection_accept_own;
909 if (debug)
910 zlog_debug(
911 "%s: %s loses to %s due to accept-own",
912 pfx_buf, new_buf, exist_buf);
913 return 0;
914 }
915 }
916
917 /* Tie-breaker - AIGP (Metric TLV) attribute */
918 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
919 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
920 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
921 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
922 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
923
924 if (new_aigp < exist_aigp) {
925 *reason = bgp_path_selection_aigp;
926 if (debug)
927 zlog_debug(
928 "%s: %s wins over %s due to AIGP %" PRIu64
929 " < %" PRIu64,
930 pfx_buf, new_buf, exist_buf, new_aigp,
931 exist_aigp);
932 return 1;
933 }
934
935 if (new_aigp > exist_aigp) {
936 *reason = bgp_path_selection_aigp;
937 if (debug)
938 zlog_debug(
939 "%s: %s loses to %s due to AIGP %" PRIu64
940 " > %" PRIu64,
941 pfx_buf, new_buf, exist_buf, new_aigp,
942 exist_aigp);
943 return 0;
944 }
945 }
946
947 /* 3. Local route check. We prefer:
948 * - BGP_ROUTE_STATIC
949 * - BGP_ROUTE_AGGREGATE
950 * - BGP_ROUTE_REDISTRIBUTE
951 */
952 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
953 new->sub_type == BGP_ROUTE_IMPORTED);
954 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
955 exist->sub_type == BGP_ROUTE_IMPORTED);
956
957 if (new_origin && !exist_origin) {
958 *reason = bgp_path_selection_local_route;
959 if (debug)
960 zlog_debug(
961 "%s: %s wins over %s due to preferred BGP_ROUTE type",
962 pfx_buf, new_buf, exist_buf);
963 return 1;
964 }
965
966 if (!new_origin && exist_origin) {
967 *reason = bgp_path_selection_local_route;
968 if (debug)
969 zlog_debug(
970 "%s: %s loses to %s due to preferred BGP_ROUTE type",
971 pfx_buf, new_buf, exist_buf);
972 return 0;
973 }
974
975 /* Here if these are imported routes then get ultimate pi for
976 * path compare.
977 */
978 new = bgp_get_imported_bpi_ultimate(new);
979 exist = bgp_get_imported_bpi_ultimate(exist);
980 newattr = new->attr;
981 existattr = exist->attr;
982
983 /* 4. AS path length check. */
984 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
985 int exist_hops = aspath_count_hops(existattr->aspath);
986 int exist_confeds = aspath_count_confeds(existattr->aspath);
987
988 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
989 int aspath_hops;
990
991 aspath_hops = aspath_count_hops(newattr->aspath);
992 aspath_hops += aspath_count_confeds(newattr->aspath);
993
994 if (aspath_hops < (exist_hops + exist_confeds)) {
995 *reason = bgp_path_selection_confed_as_path;
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
999 pfx_buf, new_buf, exist_buf,
1000 aspath_hops,
1001 (exist_hops + exist_confeds));
1002 return 1;
1003 }
1004
1005 if (aspath_hops > (exist_hops + exist_confeds)) {
1006 *reason = bgp_path_selection_confed_as_path;
1007 if (debug)
1008 zlog_debug(
1009 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1010 pfx_buf, new_buf, exist_buf,
1011 aspath_hops,
1012 (exist_hops + exist_confeds));
1013 return 0;
1014 }
1015 } else {
1016 int newhops = aspath_count_hops(newattr->aspath);
1017
1018 if (newhops < exist_hops) {
1019 *reason = bgp_path_selection_as_path;
1020 if (debug)
1021 zlog_debug(
1022 "%s: %s wins over %s due to aspath hopcount %d < %d",
1023 pfx_buf, new_buf, exist_buf,
1024 newhops, exist_hops);
1025 return 1;
1026 }
1027
1028 if (newhops > exist_hops) {
1029 *reason = bgp_path_selection_as_path;
1030 if (debug)
1031 zlog_debug(
1032 "%s: %s loses to %s due to aspath hopcount %d > %d",
1033 pfx_buf, new_buf, exist_buf,
1034 newhops, exist_hops);
1035 return 0;
1036 }
1037 }
1038 }
1039
1040 /* 5. Origin check. */
1041 if (newattr->origin < existattr->origin) {
1042 *reason = bgp_path_selection_origin;
1043 if (debug)
1044 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1045 pfx_buf, new_buf, exist_buf,
1046 bgp_origin_long_str[newattr->origin],
1047 bgp_origin_long_str[existattr->origin]);
1048 return 1;
1049 }
1050
1051 if (newattr->origin > existattr->origin) {
1052 *reason = bgp_path_selection_origin;
1053 if (debug)
1054 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1055 pfx_buf, new_buf, exist_buf,
1056 bgp_origin_long_str[newattr->origin],
1057 bgp_origin_long_str[existattr->origin]);
1058 return 0;
1059 }
1060
1061 /* 6. MED check. */
1062 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1063 && aspath_count_hops(existattr->aspath) == 0);
1064 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1065 && aspath_count_confeds(existattr->aspath) > 0
1066 && aspath_count_hops(newattr->aspath) == 0
1067 && aspath_count_hops(existattr->aspath) == 0);
1068
1069 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1070 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1071 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1072 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1073 || internal_as_route) {
1074 new_med = bgp_med_value(new->attr, bgp);
1075 exist_med = bgp_med_value(exist->attr, bgp);
1076
1077 if (new_med < exist_med) {
1078 *reason = bgp_path_selection_med;
1079 if (debug)
1080 zlog_debug(
1081 "%s: %s wins over %s due to MED %d < %d",
1082 pfx_buf, new_buf, exist_buf, new_med,
1083 exist_med);
1084 return 1;
1085 }
1086
1087 if (new_med > exist_med) {
1088 *reason = bgp_path_selection_med;
1089 if (debug)
1090 zlog_debug(
1091 "%s: %s loses to %s due to MED %d > %d",
1092 pfx_buf, new_buf, exist_buf, new_med,
1093 exist_med);
1094 return 0;
1095 }
1096 }
1097
1098 if (exist->sub_type == BGP_ROUTE_IMPORTED) {
1099 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
1100 peer_exist = bpi_ultimate->peer;
1101 } else
1102 peer_exist = exist->peer;
1103
1104 if (new->sub_type == BGP_ROUTE_IMPORTED) {
1105 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
1106 peer_new = bpi_ultimate->peer;
1107 } else
1108 peer_new = new->peer;
1109
1110 /* 7. Peer type check. */
1111 new_sort = peer_new->sort;
1112 exist_sort = peer_exist->sort;
1113
1114 if (new_sort == BGP_PEER_EBGP
1115 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1116 *reason = bgp_path_selection_peer;
1117 if (debug)
1118 zlog_debug(
1119 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1120 pfx_buf, new_buf, exist_buf);
1121 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_EBGP
1127 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1128 *reason = bgp_path_selection_peer;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1134 return 0;
1135 peer_sort_ret = 0;
1136 }
1137
1138 /* 8. IGP metric check. */
1139 newm = existm = 0;
1140
1141 if (new->extra)
1142 newm = new->extra->igpmetric;
1143 if (exist->extra)
1144 existm = exist->extra->igpmetric;
1145
1146 if (newm < existm) {
1147 if (debug && peer_sort_ret < 0)
1148 zlog_debug(
1149 "%s: %s wins over %s due to IGP metric %u < %u",
1150 pfx_buf, new_buf, exist_buf, newm, existm);
1151 igp_metric_ret = 1;
1152 }
1153
1154 if (newm > existm) {
1155 if (debug && peer_sort_ret < 0)
1156 zlog_debug(
1157 "%s: %s loses to %s due to IGP metric %u > %u",
1158 pfx_buf, new_buf, exist_buf, newm, existm);
1159 igp_metric_ret = 0;
1160 }
1161
1162 /* 9. Same IGP metric. Compare the cluster list length as
1163 representative of IGP hops metric. Rewrite the metric value
1164 pair (newm, existm) with the cluster list length. Prefer the
1165 path with smaller cluster list length. */
1166 if (newm == existm) {
1167 if (peer_sort_lookup(peer_new) == BGP_PEER_IBGP &&
1168 peer_sort_lookup(peer_exist) == BGP_PEER_IBGP &&
1169 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1170 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1171 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1172
1173 if (newm < existm) {
1174 if (debug && peer_sort_ret < 0)
1175 zlog_debug(
1176 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1177 pfx_buf, new_buf, exist_buf,
1178 newm, existm);
1179 igp_metric_ret = 1;
1180 }
1181
1182 if (newm > existm) {
1183 if (debug && peer_sort_ret < 0)
1184 zlog_debug(
1185 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1186 pfx_buf, new_buf, exist_buf,
1187 newm, existm);
1188 igp_metric_ret = 0;
1189 }
1190 }
1191 }
1192
1193 /* 10. confed-external vs. confed-internal */
1194 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1195 if (new_sort == BGP_PEER_CONFED
1196 && exist_sort == BGP_PEER_IBGP) {
1197 *reason = bgp_path_selection_confed;
1198 if (debug)
1199 zlog_debug(
1200 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1201 pfx_buf, new_buf, exist_buf);
1202 if (!CHECK_FLAG(bgp->flags,
1203 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1204 return 1;
1205 peer_sort_ret = 1;
1206 }
1207
1208 if (exist_sort == BGP_PEER_CONFED
1209 && new_sort == BGP_PEER_IBGP) {
1210 *reason = bgp_path_selection_confed;
1211 if (debug)
1212 zlog_debug(
1213 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1214 pfx_buf, new_buf, exist_buf);
1215 if (!CHECK_FLAG(bgp->flags,
1216 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1217 return 0;
1218 peer_sort_ret = 0;
1219 }
1220 }
1221
1222 /* 11. Maximum path check. */
1223 if (newm == existm) {
1224 /* If one path has a label but the other does not, do not treat
1225 * them as equals for multipath
1226 */
1227 int newl, existl;
1228
1229 newl = existl = 0;
1230
1231 if (new->extra)
1232 newl = new->extra->num_labels;
1233 if (exist->extra)
1234 existl = exist->extra->num_labels;
1235 if (((new->extra &&bgp_is_valid_label(&new->extra->label[0])) !=
1236 (exist->extra &&
1237 bgp_is_valid_label(&exist->extra->label[0]))) ||
1238 (newl != existl)) {
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1242 pfx_buf, new_buf, exist_buf);
1243 } else if (CHECK_FLAG(bgp->flags,
1244 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1245
1246 /*
1247 * For the two paths, all comparison steps till IGP
1248 * metric
1249 * have succeeded - including AS_PATH hop count. Since
1250 * 'bgp
1251 * bestpath as-path multipath-relax' knob is on, we
1252 * don't need
1253 * an exact match of AS_PATH. Thus, mark the paths are
1254 * equal.
1255 * That will trigger both these paths to get into the
1256 * multipath
1257 * array.
1258 */
1259 *paths_eq = 1;
1260
1261 if (debug)
1262 zlog_debug(
1263 "%s: %s and %s are equal via multipath-relax",
1264 pfx_buf, new_buf, exist_buf);
1265 } else if (peer_new->sort == BGP_PEER_IBGP) {
1266 if (aspath_cmp(new->attr->aspath,
1267 exist->attr->aspath)) {
1268 *paths_eq = 1;
1269
1270 if (debug)
1271 zlog_debug(
1272 "%s: %s and %s are equal via matching aspaths",
1273 pfx_buf, new_buf, exist_buf);
1274 }
1275 } else if (peer_new->as == peer_exist->as) {
1276 *paths_eq = 1;
1277
1278 if (debug)
1279 zlog_debug(
1280 "%s: %s and %s are equal via same remote-as",
1281 pfx_buf, new_buf, exist_buf);
1282 }
1283 } else {
1284 /*
1285 * TODO: If unequal cost ibgp multipath is enabled we can
1286 * mark the paths as equal here instead of returning
1287 */
1288
1289 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1290 * if either step 7 or 10 (peer type checks) yielded a winner,
1291 * that result was returned immediately. Returning from step 10
1292 * ignored the return value computed in steps 8 and 9 (IGP
1293 * metric checks). In order to preserve that behavior, if
1294 * peer_sort_ret is set, return that rather than igp_metric_ret.
1295 */
1296 ret = peer_sort_ret;
1297 if (peer_sort_ret < 0) {
1298 ret = igp_metric_ret;
1299 if (debug) {
1300 if (ret == 1)
1301 zlog_debug(
1302 "%s: %s wins over %s after IGP metric comparison",
1303 pfx_buf, new_buf, exist_buf);
1304 else
1305 zlog_debug(
1306 "%s: %s loses to %s after IGP metric comparison",
1307 pfx_buf, new_buf, exist_buf);
1308 }
1309 *reason = bgp_path_selection_igp_metric;
1310 }
1311 return ret;
1312 }
1313
1314 /*
1315 * At this point, the decision whether to set *paths_eq = 1 has been
1316 * completed. If we deferred returning because of bestpath peer-type
1317 * relax configuration, return now.
1318 */
1319 if (peer_sort_ret >= 0)
1320 return peer_sort_ret;
1321
1322 /* 12. If both paths are external, prefer the path that was received
1323 first (the oldest one). This step minimizes route-flap, since a
1324 newer path won't displace an older one, even if it was the
1325 preferred route based on the additional decision criteria below. */
1326 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1327 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1328 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1329 *reason = bgp_path_selection_older;
1330 if (debug)
1331 zlog_debug(
1332 "%s: %s wins over %s due to oldest external",
1333 pfx_buf, new_buf, exist_buf);
1334 return 1;
1335 }
1336
1337 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1338 *reason = bgp_path_selection_older;
1339 if (debug)
1340 zlog_debug(
1341 "%s: %s loses to %s due to oldest external",
1342 pfx_buf, new_buf, exist_buf);
1343 return 0;
1344 }
1345 }
1346
1347 /* 13. Router-ID comparison. */
1348 /* If one of the paths is "stale", the corresponding peer router-id will
1349 * be 0 and would always win over the other path. If originator id is
1350 * used for the comparison, it will decide which path is better.
1351 */
1352 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1353 new_id.s_addr = newattr->originator_id.s_addr;
1354 else
1355 new_id.s_addr = peer_new->remote_id.s_addr;
1356 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1357 exist_id.s_addr = existattr->originator_id.s_addr;
1358 else
1359 exist_id.s_addr = peer_exist->remote_id.s_addr;
1360
1361 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1362 *reason = bgp_path_selection_router_id;
1363 if (debug)
1364 zlog_debug(
1365 "%s: %s wins over %s due to Router-ID comparison",
1366 pfx_buf, new_buf, exist_buf);
1367 return 1;
1368 }
1369
1370 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1371 *reason = bgp_path_selection_router_id;
1372 if (debug)
1373 zlog_debug(
1374 "%s: %s loses to %s due to Router-ID comparison",
1375 pfx_buf, new_buf, exist_buf);
1376 return 0;
1377 }
1378
1379 /* 14. Cluster length comparison. */
1380 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1381 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1382
1383 if (new_cluster < exist_cluster) {
1384 *reason = bgp_path_selection_cluster_length;
1385 if (debug)
1386 zlog_debug(
1387 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1388 pfx_buf, new_buf, exist_buf, new_cluster,
1389 exist_cluster);
1390 return 1;
1391 }
1392
1393 if (new_cluster > exist_cluster) {
1394 *reason = bgp_path_selection_cluster_length;
1395 if (debug)
1396 zlog_debug(
1397 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1398 pfx_buf, new_buf, exist_buf, new_cluster,
1399 exist_cluster);
1400 return 0;
1401 }
1402
1403 /* 15. Neighbor address comparison. */
1404 /* Do this only if neither path is "stale" as stale paths do not have
1405 * valid peer information (as the connection may or may not be up).
1406 */
1407 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1408 *reason = bgp_path_selection_stale;
1409 if (debug)
1410 zlog_debug(
1411 "%s: %s wins over %s due to latter path being STALE",
1412 pfx_buf, new_buf, exist_buf);
1413 return 1;
1414 }
1415
1416 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1417 *reason = bgp_path_selection_stale;
1418 if (debug)
1419 zlog_debug(
1420 "%s: %s loses to %s due to former path being STALE",
1421 pfx_buf, new_buf, exist_buf);
1422 return 0;
1423 }
1424
1425 /* locally configured routes to advertise do not have su_remote */
1426 if (peer_new->su_remote == NULL) {
1427 *reason = bgp_path_selection_local_configured;
1428 return 0;
1429 }
1430
1431 if (peer_exist->su_remote == NULL) {
1432 *reason = bgp_path_selection_local_configured;
1433 return 1;
1434 }
1435
1436 ret = sockunion_cmp(peer_new->su_remote, peer_exist->su_remote);
1437
1438 if (ret == 1) {
1439 *reason = bgp_path_selection_neighbor_ip;
1440 if (debug)
1441 zlog_debug(
1442 "%s: %s loses to %s due to Neighor IP comparison",
1443 pfx_buf, new_buf, exist_buf);
1444 return 0;
1445 }
1446
1447 if (ret == -1) {
1448 *reason = bgp_path_selection_neighbor_ip;
1449 if (debug)
1450 zlog_debug(
1451 "%s: %s wins over %s due to Neighor IP comparison",
1452 pfx_buf, new_buf, exist_buf);
1453 return 1;
1454 }
1455
1456 *reason = bgp_path_selection_default;
1457 if (debug)
1458 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1459 pfx_buf, new_buf, exist_buf);
1460
1461 return 1;
1462 }
1463
1464
1465 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1466 struct bgp_path_info *exist, int *paths_eq)
1467 {
1468 enum bgp_path_selection_reason reason;
1469 char pfx_buf[PREFIX2STR_BUFFER];
1470
1471 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1472 AFI_L2VPN, SAFI_EVPN, &reason);
1473 }
1474
1475 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1476 * is preferred, or 0 if they are the same (usually will only occur if
1477 * multipath is enabled
1478 * This version is compatible with */
1479 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1480 struct bgp_path_info *exist, char *pfx_buf,
1481 afi_t afi, safi_t safi,
1482 enum bgp_path_selection_reason *reason)
1483 {
1484 int paths_eq;
1485 int ret;
1486 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1487 afi, safi, reason);
1488
1489 if (paths_eq)
1490 ret = 0;
1491 else {
1492 if (ret == 1)
1493 ret = -1;
1494 else
1495 ret = 1;
1496 }
1497 return ret;
1498 }
1499
1500 static enum filter_type bgp_input_filter(struct peer *peer,
1501 const struct prefix *p,
1502 struct attr *attr, afi_t afi,
1503 safi_t safi)
1504 {
1505 struct bgp_filter *filter;
1506 enum filter_type ret = FILTER_PERMIT;
1507
1508 filter = &peer->filter[afi][safi];
1509
1510 #define FILTER_EXIST_WARN(F, f, filter) \
1511 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1512 zlog_debug("%s: Could not find configured input %s-list %s!", \
1513 peer->host, #f, F##_IN_NAME(filter));
1514
1515 if (DISTRIBUTE_IN_NAME(filter)) {
1516 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1517
1518 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1519 == FILTER_DENY) {
1520 ret = FILTER_DENY;
1521 goto done;
1522 }
1523 }
1524
1525 if (PREFIX_LIST_IN_NAME(filter)) {
1526 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1527
1528 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1529 == PREFIX_DENY) {
1530 ret = FILTER_DENY;
1531 goto done;
1532 }
1533 }
1534
1535 if (FILTER_LIST_IN_NAME(filter)) {
1536 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1537
1538 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1539 == AS_FILTER_DENY) {
1540 ret = FILTER_DENY;
1541 goto done;
1542 }
1543 }
1544
1545 done:
1546 if (frrtrace_enabled(frr_bgp, input_filter)) {
1547 char pfxprint[PREFIX2STR_BUFFER];
1548
1549 prefix2str(p, pfxprint, sizeof(pfxprint));
1550 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1551 ret == FILTER_PERMIT ? "permit" : "deny");
1552 }
1553
1554 return ret;
1555 #undef FILTER_EXIST_WARN
1556 }
1557
1558 static enum filter_type bgp_output_filter(struct peer *peer,
1559 const struct prefix *p,
1560 struct attr *attr, afi_t afi,
1561 safi_t safi)
1562 {
1563 struct bgp_filter *filter;
1564 enum filter_type ret = FILTER_PERMIT;
1565
1566 filter = &peer->filter[afi][safi];
1567
1568 #define FILTER_EXIST_WARN(F, f, filter) \
1569 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1570 zlog_debug("%s: Could not find configured output %s-list %s!", \
1571 peer->host, #f, F##_OUT_NAME(filter));
1572
1573 if (DISTRIBUTE_OUT_NAME(filter)) {
1574 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1575
1576 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1577 == FILTER_DENY) {
1578 ret = FILTER_DENY;
1579 goto done;
1580 }
1581 }
1582
1583 if (PREFIX_LIST_OUT_NAME(filter)) {
1584 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1585
1586 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1587 == PREFIX_DENY) {
1588 ret = FILTER_DENY;
1589 goto done;
1590 }
1591 }
1592
1593 if (FILTER_LIST_OUT_NAME(filter)) {
1594 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1595
1596 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1597 == AS_FILTER_DENY) {
1598 ret = FILTER_DENY;
1599 goto done;
1600 }
1601 }
1602
1603 if (frrtrace_enabled(frr_bgp, output_filter)) {
1604 char pfxprint[PREFIX2STR_BUFFER];
1605
1606 prefix2str(p, pfxprint, sizeof(pfxprint));
1607 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1608 ret == FILTER_PERMIT ? "permit" : "deny");
1609 }
1610
1611 done:
1612 return ret;
1613 #undef FILTER_EXIST_WARN
1614 }
1615
1616 /* If community attribute includes no_export then return 1. */
1617 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1618 {
1619 if (bgp_attr_get_community(attr)) {
1620 /* NO_ADVERTISE check. */
1621 if (community_include(bgp_attr_get_community(attr),
1622 COMMUNITY_NO_ADVERTISE))
1623 return true;
1624
1625 /* NO_EXPORT check. */
1626 if (peer->sort == BGP_PEER_EBGP &&
1627 community_include(bgp_attr_get_community(attr),
1628 COMMUNITY_NO_EXPORT))
1629 return true;
1630
1631 /* NO_EXPORT_SUBCONFED check. */
1632 if (peer->sort == BGP_PEER_EBGP
1633 || peer->sort == BGP_PEER_CONFED)
1634 if (community_include(bgp_attr_get_community(attr),
1635 COMMUNITY_NO_EXPORT_SUBCONFED))
1636 return true;
1637 }
1638 return false;
1639 }
1640
1641 /* Route reflection loop check. */
1642 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1643 {
1644 struct in_addr cluster_id;
1645 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1646
1647 if (cluster) {
1648 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1649 cluster_id = peer->bgp->cluster_id;
1650 else
1651 cluster_id = peer->bgp->router_id;
1652
1653 if (cluster_loop_check(cluster, cluster_id))
1654 return true;
1655 }
1656 return false;
1657 }
1658
1659 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1660 {
1661 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1662 if (peer->local_role == ROLE_PROVIDER ||
1663 peer->local_role == ROLE_RS_SERVER)
1664 return true;
1665 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1666 return true;
1667 return false;
1668 }
1669 if (peer->local_role == ROLE_CUSTOMER ||
1670 peer->local_role == ROLE_PEER ||
1671 peer->local_role == ROLE_RS_CLIENT) {
1672 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1673 attr->otc = peer->as;
1674 }
1675 return false;
1676 }
1677
1678 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1679 {
1680 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1681 if (peer->local_role == ROLE_CUSTOMER ||
1682 peer->local_role == ROLE_RS_CLIENT ||
1683 peer->local_role == ROLE_PEER)
1684 return true;
1685 return false;
1686 }
1687 if (peer->local_role == ROLE_PROVIDER ||
1688 peer->local_role == ROLE_PEER ||
1689 peer->local_role == ROLE_RS_SERVER) {
1690 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1691 attr->otc = peer->bgp->as;
1692 }
1693 return false;
1694 }
1695
1696 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1697 {
1698 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1699 }
1700
1701 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1702 struct attr *attr, afi_t afi, safi_t safi,
1703 const char *rmap_name, mpls_label_t *label,
1704 uint32_t num_labels, struct bgp_dest *dest)
1705 {
1706 struct bgp_filter *filter;
1707 struct bgp_path_info rmap_path = { 0 };
1708 struct bgp_path_info_extra extra = { 0 };
1709 route_map_result_t ret;
1710 struct route_map *rmap = NULL;
1711
1712 filter = &peer->filter[afi][safi];
1713
1714 /* Apply default weight value. */
1715 if (peer->weight[afi][safi])
1716 attr->weight = peer->weight[afi][safi];
1717
1718 if (rmap_name) {
1719 rmap = route_map_lookup_by_name(rmap_name);
1720
1721 if (rmap == NULL)
1722 return RMAP_DENY;
1723 } else {
1724 if (ROUTE_MAP_IN_NAME(filter)) {
1725 rmap = ROUTE_MAP_IN(filter);
1726
1727 if (rmap == NULL)
1728 return RMAP_DENY;
1729 }
1730 }
1731
1732 /* Route map apply. */
1733 if (rmap) {
1734 memset(&rmap_path, 0, sizeof(rmap_path));
1735 /* Duplicate current value to new structure for modification. */
1736 rmap_path.peer = peer;
1737 rmap_path.attr = attr;
1738 rmap_path.extra = &extra;
1739 rmap_path.net = dest;
1740
1741 extra.num_labels = num_labels;
1742 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1743 memcpy(extra.label, label,
1744 num_labels * sizeof(mpls_label_t));
1745
1746 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1747
1748 /* Apply BGP route map to the attribute. */
1749 ret = route_map_apply(rmap, p, &rmap_path);
1750
1751 peer->rmap_type = 0;
1752
1753 if (ret == RMAP_DENYMATCH)
1754 return RMAP_DENY;
1755 }
1756 return RMAP_PERMIT;
1757 }
1758
1759 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1760 struct attr *attr, afi_t afi, safi_t safi,
1761 const char *rmap_name)
1762 {
1763 struct bgp_path_info rmap_path;
1764 route_map_result_t ret;
1765 struct route_map *rmap = NULL;
1766 uint8_t rmap_type;
1767
1768 /*
1769 * So if we get to this point and have no rmap_name
1770 * we want to just show the output as it currently
1771 * exists.
1772 */
1773 if (!rmap_name)
1774 return RMAP_PERMIT;
1775
1776 /* Apply default weight value. */
1777 if (peer->weight[afi][safi])
1778 attr->weight = peer->weight[afi][safi];
1779
1780 rmap = route_map_lookup_by_name(rmap_name);
1781
1782 /*
1783 * If we have a route map name and we do not find
1784 * the routemap that means we have an implicit
1785 * deny.
1786 */
1787 if (rmap == NULL)
1788 return RMAP_DENY;
1789
1790 memset(&rmap_path, 0, sizeof(rmap_path));
1791 /* Route map apply. */
1792 /* Duplicate current value to new structure for modification. */
1793 rmap_path.peer = peer;
1794 rmap_path.attr = attr;
1795
1796 rmap_type = peer->rmap_type;
1797 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1798
1799 /* Apply BGP route map to the attribute. */
1800 ret = route_map_apply(rmap, p, &rmap_path);
1801
1802 peer->rmap_type = rmap_type;
1803
1804 if (ret == RMAP_DENYMATCH)
1805 /*
1806 * caller has multiple error paths with bgp_attr_flush()
1807 */
1808 return RMAP_DENY;
1809
1810 return RMAP_PERMIT;
1811 }
1812
1813 /* If this is an EBGP peer with remove-private-AS */
1814 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1815 struct peer *peer, struct attr *attr)
1816 {
1817 if (peer->sort == BGP_PEER_EBGP
1818 && (peer_af_flag_check(peer, afi, safi,
1819 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1820 || peer_af_flag_check(peer, afi, safi,
1821 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1822 || peer_af_flag_check(peer, afi, safi,
1823 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1824 || peer_af_flag_check(peer, afi, safi,
1825 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1826 // Take action on the entire aspath
1827 if (peer_af_flag_check(peer, afi, safi,
1828 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1829 || peer_af_flag_check(peer, afi, safi,
1830 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1831 if (peer_af_flag_check(
1832 peer, afi, safi,
1833 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1834 attr->aspath = aspath_replace_private_asns(
1835 attr->aspath, bgp->as, peer->as);
1836
1837 /*
1838 * Even if the aspath consists of just private ASNs we
1839 * need to walk the AS-Path to maintain all instances
1840 * of the peer's ASN to break possible loops.
1841 */
1842 else
1843 attr->aspath = aspath_remove_private_asns(
1844 attr->aspath, peer->as);
1845 }
1846
1847 // 'all' was not specified so the entire aspath must be private
1848 // ASNs
1849 // for us to do anything
1850 else if (aspath_private_as_check(attr->aspath)) {
1851 if (peer_af_flag_check(
1852 peer, afi, safi,
1853 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1854 attr->aspath = aspath_replace_private_asns(
1855 attr->aspath, bgp->as, peer->as);
1856 else
1857 /*
1858 * Walk the aspath to retain any instances of
1859 * the peer_asn
1860 */
1861 attr->aspath = aspath_remove_private_asns(
1862 attr->aspath, peer->as);
1863 }
1864 }
1865 }
1866
1867 /* If this is an EBGP peer with as-override */
1868 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1869 struct peer *peer, struct attr *attr)
1870 {
1871 struct aspath *aspath;
1872
1873 if (peer->sort == BGP_PEER_EBGP &&
1874 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1875 if (attr->aspath->refcnt)
1876 aspath = aspath_dup(attr->aspath);
1877 else
1878 aspath = attr->aspath;
1879
1880 attr->aspath = aspath_intern(
1881 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1882
1883 aspath_free(aspath);
1884 }
1885 }
1886
1887 void bgp_attr_add_llgr_community(struct attr *attr)
1888 {
1889 struct community *old;
1890 struct community *new;
1891 struct community *merge;
1892 struct community *llgr;
1893
1894 old = bgp_attr_get_community(attr);
1895 llgr = community_str2com("llgr-stale");
1896
1897 assert(llgr);
1898
1899 if (old) {
1900 merge = community_merge(community_dup(old), llgr);
1901
1902 if (old->refcnt == 0)
1903 community_free(&old);
1904
1905 new = community_uniq_sort(merge);
1906 community_free(&merge);
1907 } else {
1908 new = community_dup(llgr);
1909 }
1910
1911 community_free(&llgr);
1912
1913 bgp_attr_set_community(attr, new);
1914 }
1915
1916 void bgp_attr_add_gshut_community(struct attr *attr)
1917 {
1918 struct community *old;
1919 struct community *new;
1920 struct community *merge;
1921 struct community *gshut;
1922
1923 old = bgp_attr_get_community(attr);
1924 gshut = community_str2com("graceful-shutdown");
1925
1926 assert(gshut);
1927
1928 if (old) {
1929 merge = community_merge(community_dup(old), gshut);
1930
1931 if (old->refcnt == 0)
1932 community_free(&old);
1933
1934 new = community_uniq_sort(merge);
1935 community_free(&merge);
1936 } else {
1937 new = community_dup(gshut);
1938 }
1939
1940 community_free(&gshut);
1941 bgp_attr_set_community(attr, new);
1942
1943 /* When we add the graceful-shutdown community we must also
1944 * lower the local-preference */
1945 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1946 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1947 }
1948
1949
1950 /* Notify BGP Conditional advertisement scanner process. */
1951 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1952 {
1953 struct peer *peer = SUBGRP_PEER(subgrp);
1954 afi_t afi = SUBGRP_AFI(subgrp);
1955 safi_t safi = SUBGRP_SAFI(subgrp);
1956 struct bgp_filter *filter = &peer->filter[afi][safi];
1957
1958 if (!ADVERTISE_MAP_NAME(filter))
1959 return;
1960
1961 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1962 return;
1963
1964 peer->advmap_table_change = true;
1965 }
1966
1967
1968 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1969 {
1970 if (family == AF_INET) {
1971 attr->nexthop.s_addr = INADDR_ANY;
1972 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1973 }
1974 if (family == AF_INET6)
1975 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1976 if (family == AF_EVPN)
1977 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1978 }
1979
1980 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1981 struct update_subgroup *subgrp,
1982 const struct prefix *p, struct attr *attr,
1983 struct attr *post_attr)
1984 {
1985 struct bgp_filter *filter;
1986 struct peer *from;
1987 struct peer *peer;
1988 struct peer *onlypeer;
1989 struct bgp *bgp;
1990 struct attr *piattr;
1991 route_map_result_t ret;
1992 int transparent;
1993 int reflect;
1994 afi_t afi;
1995 safi_t safi;
1996 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1997 bool nh_reset = false;
1998 uint64_t cum_bw;
1999
2000 if (DISABLE_BGP_ANNOUNCE)
2001 return false;
2002
2003 afi = SUBGRP_AFI(subgrp);
2004 safi = SUBGRP_SAFI(subgrp);
2005 peer = SUBGRP_PEER(subgrp);
2006 onlypeer = NULL;
2007 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2008 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2009
2010 from = pi->peer;
2011 filter = &peer->filter[afi][safi];
2012 bgp = SUBGRP_INST(subgrp);
2013 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2014 : pi->attr;
2015
2016 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2017 peer->pmax_out[afi][safi] != 0 &&
2018 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2019 if (BGP_DEBUG(update, UPDATE_OUT) ||
2020 BGP_DEBUG(update, UPDATE_PREFIX)) {
2021 zlog_debug("%s reached maximum prefix to be send (%u)",
2022 peer->host, peer->pmax_out[afi][safi]);
2023 }
2024 return false;
2025 }
2026
2027 #ifdef ENABLE_BGP_VNC
2028 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2029 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2030 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2031
2032 /*
2033 * direct and direct_ext type routes originate internally even
2034 * though they can have peer pointers that reference other
2035 * systems
2036 */
2037 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2038 __func__, p);
2039 samepeer_safe = 1;
2040 }
2041 #endif
2042
2043 if (((afi == AFI_IP) || (afi == AFI_IP6))
2044 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2045 && (pi->type == ZEBRA_ROUTE_BGP)
2046 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2047
2048 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2049
2050 samepeer_safe = 1;
2051 }
2052
2053 /* With addpath we may be asked to TX all kinds of paths so make sure
2054 * pi is valid */
2055 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2056 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2057 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2058 return false;
2059 }
2060
2061 /* If this is not the bestpath then check to see if there is an enabled
2062 * addpath
2063 * feature that requires us to advertise it */
2064 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2065 if (!bgp_addpath_capable(pi, peer, afi, safi))
2066 return false;
2067
2068 /* Aggregate-address suppress check. */
2069 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2070 return false;
2071
2072 /*
2073 * If we are doing VRF 2 VRF leaking via the import
2074 * statement, we want to prevent the route going
2075 * off box as that the RT and RD created are localy
2076 * significant and globaly useless.
2077 */
2078 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2079 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2080 return false;
2081
2082 /* If it's labeled safi, make sure the route has a valid label. */
2083 if (safi == SAFI_LABELED_UNICAST) {
2084 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2085 if (!bgp_is_valid_label(&label)) {
2086 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2087 zlog_debug("u%" PRIu64 ":s%" PRIu64
2088 " %pFX is filtered - no label (%p)",
2089 subgrp->update_group->id, subgrp->id,
2090 p, &label);
2091 return false;
2092 }
2093 }
2094
2095 /* Do not send back route to sender. */
2096 if (onlypeer && from == onlypeer) {
2097 return false;
2098 }
2099
2100 /* Do not send the default route in the BGP table if the neighbor is
2101 * configured for default-originate */
2102 if (CHECK_FLAG(peer->af_flags[afi][safi],
2103 PEER_FLAG_DEFAULT_ORIGINATE)) {
2104 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2105 return false;
2106 else if (p->family == AF_INET6 && p->prefixlen == 0)
2107 return false;
2108 }
2109
2110 /* Transparency check. */
2111 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2112 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2113 transparent = 1;
2114 else
2115 transparent = 0;
2116
2117 /* If community is not disabled check the no-export and local. */
2118 if (!transparent && bgp_community_filter(peer, piattr)) {
2119 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2120 zlog_debug("%s: community filter check fail for %pFX",
2121 __func__, p);
2122 return false;
2123 }
2124
2125 /* If the attribute has originator-id and it is same as remote
2126 peer's id. */
2127 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2128 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2129 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2130 zlog_debug(
2131 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2132 onlypeer, p);
2133 return false;
2134 }
2135
2136 /* ORF prefix-list filter check */
2137 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2138 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2139 || CHECK_FLAG(peer->af_cap[afi][safi],
2140 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2141 if (peer->orf_plist[afi][safi]) {
2142 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2143 == PREFIX_DENY) {
2144 if (bgp_debug_update(NULL, p,
2145 subgrp->update_group, 0))
2146 zlog_debug(
2147 "%pBP [Update:SEND] %pFX is filtered via ORF",
2148 peer, p);
2149 return false;
2150 }
2151 }
2152
2153 /* Output filter check. */
2154 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2155 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2156 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2157 p);
2158 return false;
2159 }
2160
2161 /* AS path loop check. */
2162 if (peer->as_path_loop_detection &&
2163 aspath_loop_check(piattr->aspath, peer->as)) {
2164 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2165 zlog_debug(
2166 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2167 peer, peer->as);
2168 return false;
2169 }
2170
2171 /* If we're a CONFED we need to loop check the CONFED ID too */
2172 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2173 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2174 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2175 zlog_debug(
2176 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2177 peer, bgp->confed_id);
2178 return false;
2179 }
2180 }
2181
2182 /* Route-Reflect check. */
2183 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2184 reflect = 1;
2185 else
2186 reflect = 0;
2187
2188 /* IBGP reflection check. */
2189 if (reflect && !samepeer_safe) {
2190 /* A route from a Client peer. */
2191 if (CHECK_FLAG(from->af_flags[afi][safi],
2192 PEER_FLAG_REFLECTOR_CLIENT)) {
2193 /* Reflect to all the Non-Client peers and also to the
2194 Client peers other than the originator. Originator
2195 check
2196 is already done. So there is noting to do. */
2197 /* no bgp client-to-client reflection check. */
2198 if (CHECK_FLAG(bgp->flags,
2199 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2200 if (CHECK_FLAG(peer->af_flags[afi][safi],
2201 PEER_FLAG_REFLECTOR_CLIENT))
2202 return false;
2203 } else {
2204 /* A route from a Non-client peer. Reflect to all other
2205 clients. */
2206 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2207 PEER_FLAG_REFLECTOR_CLIENT))
2208 return false;
2209 }
2210 }
2211
2212 /* For modify attribute, copy it to temporary structure.
2213 * post_attr comes from BGP conditional advertisements, where
2214 * attributes are already processed by advertise-map route-map,
2215 * and this needs to be saved instead of overwriting from the
2216 * path attributes.
2217 */
2218 if (post_attr)
2219 *attr = *post_attr;
2220 else
2221 *attr = *piattr;
2222
2223 /* If local-preference is not set. */
2224 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2225 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2226 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2227 attr->local_pref = bgp->default_local_pref;
2228 }
2229
2230 /* If originator-id is not set and the route is to be reflected,
2231 set the originator id */
2232 if (reflect
2233 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2234 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2235 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2236 }
2237
2238 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2239 */
2240 if (peer->sort == BGP_PEER_EBGP
2241 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2242 if (from != bgp->peer_self && !transparent
2243 && !CHECK_FLAG(peer->af_flags[afi][safi],
2244 PEER_FLAG_MED_UNCHANGED))
2245 attr->flag &=
2246 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2247 }
2248
2249 /* Since the nexthop attribute can vary per peer, it is not explicitly
2250 * set
2251 * in announce check, only certain flags and length (or number of
2252 * nexthops
2253 * -- for IPv6/MP_REACH) are set here in order to guide the update
2254 * formation
2255 * code in setting the nexthop(s) on a per peer basis in
2256 * reformat_peer().
2257 * Typically, the source nexthop in the attribute is preserved but in
2258 * the
2259 * scenarios where we know it will always be overwritten, we reset the
2260 * nexthop to "0" in an attempt to achieve better Update packing. An
2261 * example of this is when a prefix from each of 2 IBGP peers needs to
2262 * be
2263 * announced to an EBGP peer (and they have the same attributes barring
2264 * their nexthop).
2265 */
2266 if (reflect)
2267 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2268
2269 #define NEXTHOP_IS_V6 \
2270 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2271 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2272 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2273 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2274
2275 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2276 * if
2277 * the peer (group) is configured to receive link-local nexthop
2278 * unchanged
2279 * and it is available in the prefix OR we're not reflecting the route,
2280 * link-local nexthop address is valid and
2281 * the peer (group) to whom we're going to announce is on a shared
2282 * network
2283 * and this is either a self-originated route or the peer is EBGP.
2284 * By checking if nexthop LL address is valid we are sure that
2285 * we do not announce LL address as `::`.
2286 */
2287 if (NEXTHOP_IS_V6) {
2288 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2289 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2290 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2291 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2292 || (!reflect && !transparent
2293 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2294 && peer->shared_network
2295 && (from == bgp->peer_self
2296 || peer->sort == BGP_PEER_EBGP))) {
2297 if (safi == SAFI_MPLS_VPN)
2298 attr->mp_nexthop_len =
2299 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2300 else
2301 attr->mp_nexthop_len =
2302 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2303 }
2304
2305 /* Clear off link-local nexthop in source, whenever it is not
2306 * needed to
2307 * ensure more prefixes share the same attribute for
2308 * announcement.
2309 */
2310 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2311 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2312 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2313 }
2314
2315 if (bgp_check_role_applicability(afi, safi) &&
2316 bgp_otc_egress(peer, attr))
2317 return false;
2318
2319 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2320 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2321
2322 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2323 filter->advmap.aname &&
2324 route_map_lookup_by_name(filter->advmap.aname)) {
2325 struct bgp_path_info rmap_path = {0};
2326 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2327 struct attr dummy_attr = *attr;
2328
2329 /* Fill temp path_info */
2330 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2331 pi, peer, &dummy_attr);
2332
2333 struct route_map *amap =
2334 route_map_lookup_by_name(filter->advmap.aname);
2335
2336 ret = route_map_apply(amap, p, &rmap_path);
2337
2338 bgp_attr_flush(&dummy_attr);
2339
2340 /*
2341 * The conditional advertisement mode is Withdraw and this
2342 * prefix is a conditional prefix. Don't advertise it
2343 */
2344 if (ret == RMAP_PERMITMATCH)
2345 return false;
2346 }
2347
2348 /* Route map & unsuppress-map apply. */
2349 if (!post_attr &&
2350 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2351 struct bgp_path_info rmap_path = {0};
2352 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2353 struct attr dummy_attr = {0};
2354
2355 /* Fill temp path_info */
2356 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2357 pi, peer, attr);
2358
2359 /* don't confuse inbound and outbound setting */
2360 RESET_FLAG(attr->rmap_change_flags);
2361
2362 /*
2363 * The route reflector is not allowed to modify the attributes
2364 * of the reflected IBGP routes unless explicitly allowed.
2365 */
2366 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2367 && !CHECK_FLAG(bgp->flags,
2368 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2369 dummy_attr = *attr;
2370 rmap_path.attr = &dummy_attr;
2371 }
2372
2373 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2374
2375 if (bgp_path_suppressed(pi))
2376 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2377 &rmap_path);
2378 else
2379 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2380 &rmap_path);
2381
2382 bgp_attr_flush(&dummy_attr);
2383 peer->rmap_type = 0;
2384
2385 if (ret == RMAP_DENYMATCH) {
2386 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2387 zlog_debug(
2388 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2389 peer, p,
2390 bgp_path_suppressed(pi)
2391 ? UNSUPPRESS_MAP_NAME(filter)
2392 : ROUTE_MAP_OUT_NAME(filter));
2393 bgp_attr_flush(rmap_path.attr);
2394 return false;
2395 }
2396 }
2397
2398 /* RFC 8212 to prevent route leaks.
2399 * This specification intends to improve this situation by requiring the
2400 * explicit configuration of both BGP Import and Export Policies for any
2401 * External BGP (EBGP) session such as customers, peers, or
2402 * confederation boundaries for all enabled address families. Through
2403 * codification of the aforementioned requirement, operators will
2404 * benefit from consistent behavior across different BGP
2405 * implementations.
2406 */
2407 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2408 if (!bgp_outbound_policy_exists(peer, filter)) {
2409 if (monotime_since(&bgp->ebgprequirespolicywarning,
2410 NULL) > FIFTEENMINUTE2USEC ||
2411 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2412 zlog_warn(
2413 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2414 monotime(&bgp->ebgprequirespolicywarning);
2415 }
2416 return false;
2417 }
2418
2419 /* draft-ietf-idr-deprecate-as-set-confed-set
2420 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2421 * Eventually, This document (if approved) updates RFC 4271
2422 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2423 * and obsoletes RFC 6472.
2424 */
2425 if (peer->bgp->reject_as_sets)
2426 if (aspath_check_as_sets(attr->aspath))
2427 return false;
2428
2429 /* If neighbor soo is configured, then check if the route has
2430 * SoO extended community and validate against the configured
2431 * one. If they match, do not announce, to prevent routing
2432 * loops.
2433 */
2434 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2435 peer->soo[afi][safi]) {
2436 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2437 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2438
2439 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2440 ECOMMUNITY_SITE_ORIGIN) ||
2441 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2442 ECOMMUNITY_SITE_ORIGIN) ||
2443 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2444 ECOMMUNITY_SITE_ORIGIN)) &&
2445 ecommunity_include(ecomm, ecomm_soo)) {
2446 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2447 zlog_debug(
2448 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2449 peer, p, ecommunity_str(ecomm_soo));
2450 return false;
2451 }
2452 }
2453
2454 /* Codification of AS 0 Processing */
2455 if (aspath_check_as_zero(attr->aspath))
2456 return false;
2457
2458 if (bgp_in_graceful_shutdown(bgp)) {
2459 if (peer->sort == BGP_PEER_IBGP
2460 || peer->sort == BGP_PEER_CONFED) {
2461 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2462 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2463 } else {
2464 bgp_attr_add_gshut_community(attr);
2465 }
2466 }
2467
2468 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2469 * Capability" to a neighbor MUST perform the following upon receiving
2470 * a route from that neighbor with the "LLGR_STALE" community, or upon
2471 * attaching the "LLGR_STALE" community itself per Section 4.2:
2472 *
2473 * The route SHOULD NOT be advertised to any neighbor from which the
2474 * Long-lived Graceful Restart Capability has not been received.
2475 */
2476 if (bgp_attr_get_community(attr) &&
2477 community_include(bgp_attr_get_community(attr),
2478 COMMUNITY_LLGR_STALE) &&
2479 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2480 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2481 return false;
2482
2483 /* After route-map has been applied, we check to see if the nexthop to
2484 * be carried in the attribute (that is used for the announcement) can
2485 * be cleared off or not. We do this in all cases where we would be
2486 * setting the nexthop to "ourselves". For IPv6, we only need to
2487 * consider
2488 * the global nexthop here; the link-local nexthop would have been
2489 * cleared
2490 * already, and if not, it is required by the update formation code.
2491 * Also see earlier comments in this function.
2492 */
2493 /*
2494 * If route-map has performed some operation on the nexthop or the peer
2495 * configuration says to pass it unchanged, we cannot reset the nexthop
2496 * here, so only attempt to do it if these aren't true. Note that the
2497 * route-map handler itself might have cleared the nexthop, if for
2498 * example,
2499 * it is configured as 'peer-address'.
2500 */
2501 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2502 piattr->rmap_change_flags)
2503 && !transparent
2504 && !CHECK_FLAG(peer->af_flags[afi][safi],
2505 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2506 /* We can reset the nexthop, if setting (or forcing) it to
2507 * 'self' */
2508 if (CHECK_FLAG(peer->af_flags[afi][safi],
2509 PEER_FLAG_NEXTHOP_SELF)
2510 || CHECK_FLAG(peer->af_flags[afi][safi],
2511 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2512 if (!reflect
2513 || CHECK_FLAG(peer->af_flags[afi][safi],
2514 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2515 subgroup_announce_reset_nhop(
2516 (peer_cap_enhe(peer, afi, safi)
2517 ? AF_INET6
2518 : p->family),
2519 attr);
2520 nh_reset = true;
2521 }
2522 } else if (peer->sort == BGP_PEER_EBGP) {
2523 /* Can also reset the nexthop if announcing to EBGP, but
2524 * only if
2525 * no peer in the subgroup is on a shared subnet.
2526 * Note: 3rd party nexthop currently implemented for
2527 * IPv4 only.
2528 */
2529 if ((p->family == AF_INET) &&
2530 (!bgp_subgrp_multiaccess_check_v4(
2531 piattr->nexthop,
2532 subgrp, from))) {
2533 subgroup_announce_reset_nhop(
2534 (peer_cap_enhe(peer, afi, safi)
2535 ? AF_INET6
2536 : p->family),
2537 attr);
2538 nh_reset = true;
2539 }
2540
2541 if ((p->family == AF_INET6) &&
2542 (!bgp_subgrp_multiaccess_check_v6(
2543 piattr->mp_nexthop_global,
2544 subgrp, from))) {
2545 subgroup_announce_reset_nhop(
2546 (peer_cap_enhe(peer, afi, safi)
2547 ? AF_INET6
2548 : p->family),
2549 attr);
2550 nh_reset = true;
2551 }
2552
2553
2554
2555 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2556 /*
2557 * This flag is used for leaked vpn-vrf routes
2558 */
2559 int family = p->family;
2560
2561 if (peer_cap_enhe(peer, afi, safi))
2562 family = AF_INET6;
2563
2564 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2565 zlog_debug(
2566 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2567 __func__, p, family2str(family));
2568 subgroup_announce_reset_nhop(family, attr);
2569 nh_reset = true;
2570 }
2571 }
2572
2573 /* If IPv6/MP and nexthop does not have any override and happens
2574 * to
2575 * be a link-local address, reset it so that we don't pass along
2576 * the
2577 * source's link-local IPv6 address to recipients who may not be
2578 * on
2579 * the same interface.
2580 */
2581 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2582 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2583 subgroup_announce_reset_nhop(AF_INET6, attr);
2584 nh_reset = true;
2585 }
2586 }
2587
2588 /* If this is an iBGP, send Origin Validation State (OVS)
2589 * extended community (rfc8097).
2590 */
2591 if (peer->sort == BGP_PEER_IBGP) {
2592 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2593
2594 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2595
2596 if (rpki_state != RPKI_NOT_BEING_USED)
2597 bgp_attr_set_ecommunity(
2598 attr, ecommunity_add_origin_validation_state(
2599 rpki_state,
2600 bgp_attr_get_ecommunity(attr)));
2601 }
2602
2603 /*
2604 * When the next hop is set to ourselves, if all multipaths have
2605 * link-bandwidth announce the cumulative bandwidth as that makes
2606 * the most sense. However, don't modify if the link-bandwidth has
2607 * been explicitly set by user policy.
2608 */
2609 if (nh_reset &&
2610 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2611 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2612 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2613 bgp_attr_set_ecommunity(
2614 attr,
2615 ecommunity_replace_linkbw(
2616 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2617 CHECK_FLAG(
2618 peer->flags,
2619 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2620
2621 return true;
2622 }
2623
2624 static void bgp_route_select_timer_expire(struct event *thread)
2625 {
2626 struct afi_safi_info *info;
2627 afi_t afi;
2628 safi_t safi;
2629 struct bgp *bgp;
2630
2631 info = EVENT_ARG(thread);
2632 afi = info->afi;
2633 safi = info->safi;
2634 bgp = info->bgp;
2635
2636 bgp->gr_info[afi][safi].t_route_select = NULL;
2637 XFREE(MTYPE_TMP, info);
2638
2639 /* Best path selection */
2640 bgp_best_path_select_defer(bgp, afi, safi);
2641 }
2642
2643 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2644 struct bgp_maxpaths_cfg *mpath_cfg,
2645 struct bgp_path_info_pair *result, afi_t afi,
2646 safi_t safi)
2647 {
2648 struct bgp_path_info *new_select;
2649 struct bgp_path_info *old_select;
2650 struct bgp_path_info *pi;
2651 struct bgp_path_info *pi1;
2652 struct bgp_path_info *pi2;
2653 struct bgp_path_info *nextpi = NULL;
2654 int paths_eq, do_mpath, debug;
2655 struct list mp_list;
2656 char pfx_buf[PREFIX2STR_BUFFER];
2657 char path_buf[PATH_ADDPATH_STR_BUFFER];
2658
2659 bgp_mp_list_init(&mp_list);
2660 do_mpath =
2661 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2662
2663 debug = bgp_debug_bestpath(dest);
2664
2665 if (debug)
2666 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2667
2668 dest->reason = bgp_path_selection_none;
2669 /* bgp deterministic-med */
2670 new_select = NULL;
2671 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2672
2673 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2674 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2675 pi1 = pi1->next)
2676 bgp_path_info_unset_flag(dest, pi1,
2677 BGP_PATH_DMED_SELECTED);
2678
2679 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2680 pi1 = pi1->next) {
2681 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2682 continue;
2683 if (BGP_PATH_HOLDDOWN(pi1))
2684 continue;
2685 if (pi1->peer != bgp->peer_self &&
2686 !CHECK_FLAG(pi1->peer->sflags,
2687 PEER_STATUS_NSF_WAIT)) {
2688 if (!peer_established(pi1->peer))
2689 continue;
2690 }
2691
2692 new_select = pi1;
2693 if (pi1->next) {
2694 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2695 if (CHECK_FLAG(pi2->flags,
2696 BGP_PATH_DMED_CHECK))
2697 continue;
2698 if (BGP_PATH_HOLDDOWN(pi2))
2699 continue;
2700 if (pi2->peer != bgp->peer_self
2701 && !CHECK_FLAG(
2702 pi2->peer->sflags,
2703 PEER_STATUS_NSF_WAIT))
2704 if (pi2->peer->status
2705 != Established)
2706 continue;
2707
2708 if (!aspath_cmp_left(pi1->attr->aspath,
2709 pi2->attr->aspath)
2710 && !aspath_cmp_left_confed(
2711 pi1->attr->aspath,
2712 pi2->attr->aspath))
2713 continue;
2714
2715 if (bgp_path_info_cmp(
2716 bgp, pi2, new_select,
2717 &paths_eq, mpath_cfg, debug,
2718 pfx_buf, afi, safi,
2719 &dest->reason)) {
2720 bgp_path_info_unset_flag(
2721 dest, new_select,
2722 BGP_PATH_DMED_SELECTED);
2723 new_select = pi2;
2724 }
2725
2726 bgp_path_info_set_flag(
2727 dest, pi2, BGP_PATH_DMED_CHECK);
2728 }
2729 }
2730 bgp_path_info_set_flag(dest, new_select,
2731 BGP_PATH_DMED_CHECK);
2732 bgp_path_info_set_flag(dest, new_select,
2733 BGP_PATH_DMED_SELECTED);
2734
2735 if (debug) {
2736 bgp_path_info_path_with_addpath_rx_str(
2737 new_select, path_buf, sizeof(path_buf));
2738 zlog_debug(
2739 "%pBD(%s): %s is the bestpath from AS %u",
2740 dest, bgp->name_pretty, path_buf,
2741 aspath_get_first_as(
2742 new_select->attr->aspath));
2743 }
2744 }
2745 }
2746
2747 /* Check old selected route and new selected route. */
2748 old_select = NULL;
2749 new_select = NULL;
2750 for (pi = bgp_dest_get_bgp_path_info(dest);
2751 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2752 enum bgp_path_selection_reason reason;
2753
2754 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2755 old_select = pi;
2756
2757 if (BGP_PATH_HOLDDOWN(pi)) {
2758 /* reap REMOVED routes, if needs be
2759 * selected route must stay for a while longer though
2760 */
2761 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2762 && (pi != old_select))
2763 bgp_path_info_reap(dest, pi);
2764
2765 if (debug)
2766 zlog_debug(
2767 "%s: %pBD(%s) pi from %s in holddown",
2768 __func__, dest, bgp->name_pretty,
2769 pi->peer->host);
2770
2771 continue;
2772 }
2773
2774 if (pi->peer && pi->peer != bgp->peer_self
2775 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2776 if (!peer_established(pi->peer)) {
2777
2778 if (debug)
2779 zlog_debug(
2780 "%s: %pBD(%s) non self peer %s not estab state",
2781 __func__, dest,
2782 bgp->name_pretty,
2783 pi->peer->host);
2784
2785 continue;
2786 }
2787
2788 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2789 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2790 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2791 if (debug)
2792 zlog_debug("%s: %pBD(%s) pi %s dmed", __func__,
2793 dest, bgp->name_pretty,
2794 pi->peer->host);
2795 continue;
2796 }
2797
2798 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2799
2800 reason = dest->reason;
2801 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2802 debug, pfx_buf, afi, safi,
2803 &dest->reason)) {
2804 if (new_select == NULL &&
2805 reason != bgp_path_selection_none)
2806 dest->reason = reason;
2807 new_select = pi;
2808 }
2809 }
2810
2811 /* Now that we know which path is the bestpath see if any of the other
2812 * paths
2813 * qualify as multipaths
2814 */
2815 if (debug) {
2816 if (new_select)
2817 bgp_path_info_path_with_addpath_rx_str(
2818 new_select, path_buf, sizeof(path_buf));
2819 else
2820 snprintf(path_buf, sizeof(path_buf), "NONE");
2821 zlog_debug(
2822 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2823 dest, bgp->name_pretty, path_buf,
2824 old_select ? old_select->peer->host : "NONE");
2825 }
2826
2827 if (do_mpath && new_select) {
2828 for (pi = bgp_dest_get_bgp_path_info(dest);
2829 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2830
2831 if (debug)
2832 bgp_path_info_path_with_addpath_rx_str(
2833 pi, path_buf, sizeof(path_buf));
2834
2835 if (pi == new_select) {
2836 if (debug)
2837 zlog_debug(
2838 "%pBD(%s): %s is the bestpath, add to the multipath list",
2839 dest, bgp->name_pretty,
2840 path_buf);
2841 bgp_mp_list_add(&mp_list, pi);
2842 continue;
2843 }
2844
2845 if (BGP_PATH_HOLDDOWN(pi))
2846 continue;
2847
2848 if (pi->peer && pi->peer != bgp->peer_self
2849 && !CHECK_FLAG(pi->peer->sflags,
2850 PEER_STATUS_NSF_WAIT))
2851 if (!peer_established(pi->peer))
2852 continue;
2853
2854 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2855 if (debug)
2856 zlog_debug(
2857 "%pBD(%s): %s has the same nexthop as the bestpath, skip it",
2858 dest, bgp->name_pretty,
2859 path_buf);
2860 continue;
2861 }
2862
2863 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2864 mpath_cfg, debug, pfx_buf, afi, safi,
2865 &dest->reason);
2866
2867 if (paths_eq) {
2868 if (debug)
2869 zlog_debug(
2870 "%pBD(%s): %s is equivalent to the bestpath, add to the multipath list",
2871 dest, bgp->name_pretty,
2872 path_buf);
2873 bgp_mp_list_add(&mp_list, pi);
2874 }
2875 }
2876 }
2877
2878 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2879 mpath_cfg);
2880 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2881 bgp_mp_list_clear(&mp_list);
2882
2883 bgp_addpath_update_ids(bgp, dest, afi, safi);
2884
2885 result->old = old_select;
2886 result->new = new_select;
2887
2888 return;
2889 }
2890
2891 /*
2892 * A new route/change in bestpath of an existing route. Evaluate the path
2893 * for advertisement to the subgroup.
2894 */
2895 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2896 struct bgp_path_info *selected,
2897 struct bgp_dest *dest,
2898 uint32_t addpath_tx_id)
2899 {
2900 const struct prefix *p;
2901 struct peer *onlypeer;
2902 struct attr attr;
2903 afi_t afi;
2904 safi_t safi;
2905 struct bgp *bgp;
2906 bool advertise;
2907
2908 p = bgp_dest_get_prefix(dest);
2909 afi = SUBGRP_AFI(subgrp);
2910 safi = SUBGRP_SAFI(subgrp);
2911 bgp = SUBGRP_INST(subgrp);
2912 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2913 : NULL);
2914
2915 if (BGP_DEBUG(update, UPDATE_OUT))
2916 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2917
2918 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2919 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2920 PEER_STATUS_ORF_WAIT_REFRESH))
2921 return;
2922
2923 memset(&attr, 0, sizeof(attr));
2924 /* It's initialized in bgp_announce_check() */
2925
2926 /* Announcement to the subgroup. If the route is filtered withdraw it.
2927 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2928 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2929 * route
2930 */
2931 advertise = bgp_check_advertise(bgp, dest);
2932
2933 if (selected) {
2934 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2935 NULL)) {
2936 /* Route is selected, if the route is already installed
2937 * in FIB, then it is advertised
2938 */
2939 if (advertise) {
2940 if (!bgp_check_withdrawal(bgp, dest)) {
2941 struct attr *adv_attr =
2942 bgp_attr_intern(&attr);
2943
2944 bgp_adj_out_set_subgroup(dest, subgrp,
2945 adv_attr,
2946 selected);
2947 } else
2948 bgp_adj_out_unset_subgroup(
2949 dest, subgrp, 1, addpath_tx_id);
2950 }
2951 } else
2952 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2953 addpath_tx_id);
2954 }
2955
2956 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2957 else {
2958 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2959 }
2960 }
2961
2962 /*
2963 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2964 * This is called at the end of route processing.
2965 */
2966 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2967 {
2968 struct bgp_path_info *pi;
2969
2970 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2971 if (BGP_PATH_HOLDDOWN(pi))
2972 continue;
2973 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2974 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2975 }
2976 }
2977
2978 /*
2979 * Has the route changed from the RIB's perspective? This is invoked only
2980 * if the route selection returns the same best route as earlier - to
2981 * determine if we need to update zebra or not.
2982 */
2983 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2984 {
2985 struct bgp_path_info *mpinfo;
2986
2987 /* If this is multipath, check all selected paths for any nexthop
2988 * change or attribute change. Some attribute changes (e.g., community)
2989 * aren't of relevance to the RIB, but we'll update zebra to ensure
2990 * we handle the case of BGP nexthop change. This is the behavior
2991 * when the best path has an attribute change anyway.
2992 */
2993 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2994 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2995 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2996 return true;
2997
2998 /*
2999 * If this is multipath, check all selected paths for any nexthop change
3000 */
3001 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
3002 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3003 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3004 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3005 return true;
3006 }
3007
3008 /* Nothing has changed from the RIB's perspective. */
3009 return false;
3010 }
3011
3012 struct bgp_process_queue {
3013 struct bgp *bgp;
3014 STAILQ_HEAD(, bgp_dest) pqueue;
3015 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3016 unsigned int flags;
3017 unsigned int queued;
3018 };
3019
3020 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3021 safi_t safi, struct bgp_dest *dest,
3022 struct bgp_path_info *new_select,
3023 struct bgp_path_info *old_select)
3024 {
3025 const struct prefix *p = bgp_dest_get_prefix(dest);
3026
3027 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3028 return;
3029
3030 if (advertise_type5_routes(bgp, afi) && new_select
3031 && is_route_injectable_into_evpn(new_select)) {
3032
3033 /* apply the route-map */
3034 if (bgp->adv_cmd_rmap[afi][safi].map) {
3035 route_map_result_t ret;
3036 struct bgp_path_info rmap_path;
3037 struct bgp_path_info_extra rmap_path_extra;
3038 struct attr dummy_attr;
3039
3040 dummy_attr = *new_select->attr;
3041
3042 /* Fill temp path_info */
3043 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3044 new_select, new_select->peer,
3045 &dummy_attr);
3046
3047 RESET_FLAG(dummy_attr.rmap_change_flags);
3048
3049 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3050 p, &rmap_path);
3051
3052 if (ret == RMAP_DENYMATCH) {
3053 bgp_attr_flush(&dummy_attr);
3054 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3055 safi);
3056 } else
3057 bgp_evpn_advertise_type5_route(
3058 bgp, p, &dummy_attr, afi, safi);
3059 } else {
3060 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3061 afi, safi);
3062 }
3063 } else if (advertise_type5_routes(bgp, afi) && old_select
3064 && is_route_injectable_into_evpn(old_select))
3065 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3066 }
3067
3068 /*
3069 * Utility to determine whether a particular path_info should use
3070 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3071 * in a path where we basically _know_ this is a BGP-LU route.
3072 */
3073 static bool bgp_lu_need_null_label(struct bgp *bgp,
3074 const struct bgp_path_info *new_select,
3075 afi_t afi, mpls_label_t *label)
3076 {
3077 /* Certain types get imp null; so do paths where the nexthop is
3078 * not labeled.
3079 */
3080 if (new_select->sub_type == BGP_ROUTE_STATIC
3081 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3082 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3083 goto need_null_label;
3084 else if (new_select->extra &&
3085 bgp_is_valid_label(&new_select->extra->label[0]))
3086 return false;
3087 need_null_label:
3088 if (label == NULL)
3089 return true;
3090 if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL))
3091 /* Disable PHP : explicit-null */
3092 *label = afi == AFI_IP ? MPLS_LABEL_IPV4_EXPLICIT_NULL
3093 : MPLS_LABEL_IPV6_EXPLICIT_NULL;
3094 else
3095 /* Enforced PHP popping: implicit-null */
3096 *label = MPLS_LABEL_IMPLICIT_NULL;
3097
3098 return true;
3099 }
3100
3101 /*
3102 * old_select = The old best path
3103 * new_select = the new best path
3104 *
3105 * if (!old_select && new_select)
3106 * We are sending new information on.
3107 *
3108 * if (old_select && new_select) {
3109 * if (new_select != old_select)
3110 * We have a new best path send a change
3111 * else
3112 * We've received a update with new attributes that needs
3113 * to be passed on.
3114 * }
3115 *
3116 * if (old_select && !new_select)
3117 * We have no eligible route that we can announce or the rn
3118 * is being removed.
3119 */
3120 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3121 afi_t afi, safi_t safi)
3122 {
3123 struct bgp_path_info *new_select;
3124 struct bgp_path_info *old_select;
3125 struct bgp_path_info_pair old_and_new;
3126 int debug = 0;
3127 mpls_label_t mpls_label_null;
3128
3129 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3130 if (dest)
3131 debug = bgp_debug_bestpath(dest);
3132 if (debug)
3133 zlog_debug(
3134 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3135 __func__, dest, bgp->name_pretty);
3136 return;
3137 }
3138 /* Is it end of initial update? (after startup) */
3139 if (!dest) {
3140 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3141 sizeof(bgp->update_delay_zebra_resume_time));
3142
3143 bgp->main_zebra_update_hold = 0;
3144 FOREACH_AFI_SAFI (afi, safi) {
3145 if (bgp_fibupd_safi(safi))
3146 bgp_zebra_announce_table(bgp, afi, safi);
3147 }
3148 bgp->main_peers_update_hold = 0;
3149
3150 bgp_start_routeadv(bgp);
3151 return;
3152 }
3153
3154 const struct prefix *p = bgp_dest_get_prefix(dest);
3155
3156 debug = bgp_debug_bestpath(dest);
3157 if (debug)
3158 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3159 dest, bgp->name_pretty, afi2str(afi),
3160 safi2str(safi));
3161
3162 /* The best path calculation for the route is deferred if
3163 * BGP_NODE_SELECT_DEFER is set
3164 */
3165 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3166 if (BGP_DEBUG(update, UPDATE_OUT))
3167 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3168 dest, bgp->name_pretty);
3169 return;
3170 }
3171
3172 /* Best path selection. */
3173 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3174 afi, safi);
3175 old_select = old_and_new.old;
3176 new_select = old_and_new.new;
3177
3178 /* Do we need to allocate or free labels?
3179 * Right now, since we only deal with per-prefix labels, it is not
3180 * necessary to do this upon changes to best path. Exceptions:
3181 * - label index has changed -> recalculate resulting label
3182 * - path_info sub_type changed -> switch to/from null label value
3183 * - no valid label (due to removed static label binding) -> get new one
3184 */
3185 if (bgp->allocate_mpls_labels[afi][safi]) {
3186 if (new_select) {
3187 if (!old_select
3188 || bgp_label_index_differs(new_select, old_select)
3189 || new_select->sub_type != old_select->sub_type
3190 || !bgp_is_valid_label(&dest->local_label)) {
3191 /* control label imposition for local routes,
3192 * aggregate and redistributed routes
3193 */
3194 mpls_label_null = MPLS_LABEL_IMPLICIT_NULL;
3195 if (bgp_lu_need_null_label(bgp, new_select, afi,
3196 &mpls_label_null)) {
3197 if (CHECK_FLAG(
3198 dest->flags,
3199 BGP_NODE_REGISTERED_FOR_LABEL)
3200 || CHECK_FLAG(
3201 dest->flags,
3202 BGP_NODE_LABEL_REQUESTED))
3203 bgp_unregister_for_label(dest);
3204 dest->local_label = mpls_lse_encode(
3205 mpls_label_null, 0, 0, 1);
3206 bgp_set_valid_label(&dest->local_label);
3207 } else
3208 bgp_register_for_label(dest,
3209 new_select);
3210 }
3211 } else if (CHECK_FLAG(dest->flags,
3212 BGP_NODE_REGISTERED_FOR_LABEL)
3213 || CHECK_FLAG(dest->flags,
3214 BGP_NODE_LABEL_REQUESTED)) {
3215 bgp_unregister_for_label(dest);
3216 }
3217 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3218 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3219 bgp_unregister_for_label(dest);
3220 }
3221
3222 if (debug)
3223 zlog_debug(
3224 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3225 __func__, dest, bgp->name_pretty, afi2str(afi),
3226 safi2str(safi), old_select, new_select);
3227
3228 /* If best route remains the same and this is not due to user-initiated
3229 * clear, see exactly what needs to be done.
3230 */
3231 if (old_select && old_select == new_select
3232 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3233 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3234 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3235 if (bgp_zebra_has_route_changed(old_select)) {
3236 #ifdef ENABLE_BGP_VNC
3237 vnc_import_bgp_add_route(bgp, p, old_select);
3238 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3239 #endif
3240 if (bgp_fibupd_safi(safi)
3241 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3242
3243 if (new_select->type == ZEBRA_ROUTE_BGP
3244 && (new_select->sub_type == BGP_ROUTE_NORMAL
3245 || new_select->sub_type
3246 == BGP_ROUTE_IMPORTED))
3247
3248 bgp_zebra_announce(dest, p, old_select,
3249 bgp, afi, safi);
3250 }
3251 }
3252
3253 /* If there is a change of interest to peers, reannounce the
3254 * route. */
3255 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3256 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3257 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3258 group_announce_route(bgp, afi, safi, dest, new_select);
3259
3260 /* unicast routes must also be annouced to
3261 * labeled-unicast update-groups */
3262 if (safi == SAFI_UNICAST)
3263 group_announce_route(bgp, afi,
3264 SAFI_LABELED_UNICAST, dest,
3265 new_select);
3266
3267 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3268 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3269 }
3270
3271 /* advertise/withdraw type-5 routes */
3272 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3273 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3274 bgp_process_evpn_route_injection(
3275 bgp, afi, safi, dest, old_select, old_select);
3276
3277 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3278 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3279 bgp_zebra_clear_route_change_flags(dest);
3280 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3281 return;
3282 }
3283
3284 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3285 */
3286 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3287
3288 /* bestpath has changed; bump version */
3289 if (old_select || new_select) {
3290 bgp_bump_version(dest);
3291
3292 if (!bgp->t_rmap_def_originate_eval) {
3293 bgp_lock(bgp);
3294 event_add_timer(
3295 bm->master,
3296 update_group_refresh_default_originate_route_map,
3297 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3298 &bgp->t_rmap_def_originate_eval);
3299 }
3300 }
3301
3302 if (old_select)
3303 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3304 if (new_select) {
3305 if (debug)
3306 zlog_debug("%s: setting SELECTED flag", __func__);
3307 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3308 bgp_path_info_unset_flag(dest, new_select,
3309 BGP_PATH_ATTR_CHANGED);
3310 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3311 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3312 }
3313
3314 #ifdef ENABLE_BGP_VNC
3315 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3316 if (old_select != new_select) {
3317 if (old_select) {
3318 vnc_import_bgp_exterior_del_route(bgp, p,
3319 old_select);
3320 vnc_import_bgp_del_route(bgp, p, old_select);
3321 }
3322 if (new_select) {
3323 vnc_import_bgp_exterior_add_route(bgp, p,
3324 new_select);
3325 vnc_import_bgp_add_route(bgp, p, new_select);
3326 }
3327 }
3328 }
3329 #endif
3330
3331 group_announce_route(bgp, afi, safi, dest, new_select);
3332
3333 /* unicast routes must also be annouced to labeled-unicast update-groups
3334 */
3335 if (safi == SAFI_UNICAST)
3336 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3337 new_select);
3338
3339 /* FIB update. */
3340 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3341 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3342
3343 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3344 && (new_select->sub_type == BGP_ROUTE_NORMAL
3345 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3346 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3347
3348 /* if this is an evpn imported type-5 prefix,
3349 * we need to withdraw the route first to clear
3350 * the nh neigh and the RMAC entry.
3351 */
3352 if (old_select &&
3353 is_route_parent_evpn(old_select))
3354 bgp_zebra_withdraw(p, old_select, bgp, safi);
3355
3356 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3357 } else {
3358 /* Withdraw the route from the kernel. */
3359 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3360 && (old_select->sub_type == BGP_ROUTE_NORMAL
3361 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3362 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3363
3364 bgp_zebra_withdraw(p, old_select, bgp, safi);
3365 }
3366 }
3367
3368 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3369 old_select);
3370
3371 /* Clear any route change flags. */
3372 bgp_zebra_clear_route_change_flags(dest);
3373
3374 /* Reap old select bgp_path_info, if it has been removed */
3375 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3376 bgp_path_info_reap(dest, old_select);
3377
3378 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3379 return;
3380 }
3381
3382 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3383 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3384 {
3385 struct bgp_dest *dest;
3386 int cnt = 0;
3387 struct afi_safi_info *thread_info;
3388
3389 if (bgp->gr_info[afi][safi].t_route_select) {
3390 struct event *t = bgp->gr_info[afi][safi].t_route_select;
3391
3392 thread_info = EVENT_ARG(t);
3393 XFREE(MTYPE_TMP, thread_info);
3394 EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
3395 }
3396
3397 if (BGP_DEBUG(update, UPDATE_OUT)) {
3398 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3399 get_afi_safi_str(afi, safi, false),
3400 bgp->gr_info[afi][safi].gr_deferred);
3401 }
3402
3403 /* Process the route list */
3404 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3405 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3406 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3407 dest = bgp_route_next(dest)) {
3408 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3409 continue;
3410
3411 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3412 bgp->gr_info[afi][safi].gr_deferred--;
3413 bgp_process_main_one(bgp, dest, afi, safi);
3414 cnt++;
3415 }
3416 /* If iteration stopped before the entire table was traversed then the
3417 * node needs to be unlocked.
3418 */
3419 if (dest) {
3420 bgp_dest_unlock_node(dest);
3421 dest = NULL;
3422 }
3423
3424 /* Send EOR message when all routes are processed */
3425 if (!bgp->gr_info[afi][safi].gr_deferred) {
3426 bgp_send_delayed_eor(bgp);
3427 /* Send route processing complete message to RIB */
3428 bgp_zebra_update(bgp, afi, safi,
3429 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3430 return;
3431 }
3432
3433 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3434
3435 thread_info->afi = afi;
3436 thread_info->safi = safi;
3437 thread_info->bgp = bgp;
3438
3439 /* If there are more routes to be processed, start the
3440 * selection timer
3441 */
3442 event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3443 BGP_ROUTE_SELECT_DELAY,
3444 &bgp->gr_info[afi][safi].t_route_select);
3445 }
3446
3447 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3448 {
3449 struct bgp_process_queue *pqnode = data;
3450 struct bgp *bgp = pqnode->bgp;
3451 struct bgp_table *table;
3452 struct bgp_dest *dest;
3453
3454 /* eoiu marker */
3455 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3456 bgp_process_main_one(bgp, NULL, 0, 0);
3457 /* should always have dedicated wq call */
3458 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3459 return WQ_SUCCESS;
3460 }
3461
3462 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3463 dest = STAILQ_FIRST(&pqnode->pqueue);
3464 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3465 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3466 table = bgp_dest_table(dest);
3467 /* note, new DESTs may be added as part of processing */
3468 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3469
3470 bgp_dest_unlock_node(dest);
3471 bgp_table_unlock(table);
3472 }
3473
3474 return WQ_SUCCESS;
3475 }
3476
3477 static void bgp_processq_del(struct work_queue *wq, void *data)
3478 {
3479 struct bgp_process_queue *pqnode = data;
3480
3481 bgp_unlock(pqnode->bgp);
3482
3483 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3484 }
3485
3486 void bgp_process_queue_init(struct bgp *bgp)
3487 {
3488 if (!bgp->process_queue) {
3489 char name[BUFSIZ];
3490
3491 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3492 bgp->process_queue = work_queue_new(bm->master, name);
3493 }
3494
3495 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3496 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3497 bgp->process_queue->spec.max_retries = 0;
3498 bgp->process_queue->spec.hold = 50;
3499 /* Use a higher yield value of 50ms for main queue processing */
3500 bgp->process_queue->spec.yield = 50 * 1000L;
3501 }
3502
3503 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3504 {
3505 struct bgp_process_queue *pqnode;
3506
3507 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3508 sizeof(struct bgp_process_queue));
3509
3510 /* unlocked in bgp_processq_del */
3511 pqnode->bgp = bgp_lock(bgp);
3512 STAILQ_INIT(&pqnode->pqueue);
3513
3514 return pqnode;
3515 }
3516
3517 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3518 {
3519 #define ARBITRARY_PROCESS_QLEN 10000
3520 struct work_queue *wq = bgp->process_queue;
3521 struct bgp_process_queue *pqnode;
3522 int pqnode_reuse = 0;
3523
3524 /* already scheduled for processing? */
3525 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3526 return;
3527
3528 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3529 * the workqueue
3530 */
3531 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3532 if (BGP_DEBUG(update, UPDATE_OUT))
3533 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3534 dest);
3535 return;
3536 }
3537
3538 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3539 if (BGP_DEBUG(update, UPDATE_OUT))
3540 zlog_debug(
3541 "Soft reconfigure table in progress for route %p",
3542 dest);
3543 return;
3544 }
3545
3546 if (wq == NULL)
3547 return;
3548
3549 /* Add route nodes to an existing work queue item until reaching the
3550 limit only if is from the same BGP view and it's not an EOIU marker
3551 */
3552 if (work_queue_item_count(wq)) {
3553 struct work_queue_item *item = work_queue_last_item(wq);
3554 pqnode = item->data;
3555
3556 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3557 || pqnode->bgp != bgp
3558 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3559 pqnode = bgp_processq_alloc(bgp);
3560 else
3561 pqnode_reuse = 1;
3562 } else
3563 pqnode = bgp_processq_alloc(bgp);
3564 /* all unlocked in bgp_process_wq */
3565 bgp_table_lock(bgp_dest_table(dest));
3566
3567 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3568 bgp_dest_lock_node(dest);
3569
3570 /* can't be enqueued twice */
3571 assert(STAILQ_NEXT(dest, pq) == NULL);
3572 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3573 pqnode->queued++;
3574
3575 if (!pqnode_reuse)
3576 work_queue_add(wq, pqnode);
3577
3578 return;
3579 }
3580
3581 void bgp_add_eoiu_mark(struct bgp *bgp)
3582 {
3583 struct bgp_process_queue *pqnode;
3584
3585 if (bgp->process_queue == NULL)
3586 return;
3587
3588 pqnode = bgp_processq_alloc(bgp);
3589
3590 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3591 work_queue_add(bgp->process_queue, pqnode);
3592 }
3593
3594 static void bgp_maximum_prefix_restart_timer(struct event *thread)
3595 {
3596 struct peer *peer;
3597
3598 peer = EVENT_ARG(thread);
3599 peer->t_pmax_restart = NULL;
3600
3601 if (bgp_debug_neighbor_events(peer))
3602 zlog_debug(
3603 "%s Maximum-prefix restart timer expired, restore peering",
3604 peer->host);
3605
3606 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3607 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3608 }
3609
3610 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3611 safi_t safi)
3612 {
3613 uint32_t count = 0;
3614 bool filtered = false;
3615 struct bgp_dest *dest;
3616 struct bgp_adj_in *ain;
3617 struct attr attr = {};
3618 struct bgp_table *table = peer->bgp->rib[afi][safi];
3619
3620 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3621 for (ain = dest->adj_in; ain; ain = ain->next) {
3622 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3623
3624 attr = *ain->attr;
3625
3626 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3627 == FILTER_DENY)
3628 filtered = true;
3629
3630 if (bgp_input_modifier(
3631 peer, rn_p, &attr, afi, safi,
3632 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3633 NULL, 0, NULL)
3634 == RMAP_DENY)
3635 filtered = true;
3636
3637 if (filtered)
3638 count++;
3639
3640 bgp_attr_flush(&attr);
3641 }
3642 }
3643
3644 return count;
3645 }
3646
3647 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3648 int always)
3649 {
3650 iana_afi_t pkt_afi;
3651 iana_safi_t pkt_safi;
3652 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3653 PEER_FLAG_MAX_PREFIX_FORCE))
3654 ? bgp_filtered_routes_count(peer, afi, safi)
3655 + peer->pcount[afi][safi]
3656 : peer->pcount[afi][safi];
3657
3658 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3659 return false;
3660
3661 if (pcount > peer->pmax[afi][safi]) {
3662 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3663 PEER_STATUS_PREFIX_LIMIT)
3664 && !always)
3665 return false;
3666
3667 zlog_info(
3668 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3669 get_afi_safi_str(afi, safi, false), peer, pcount,
3670 peer->pmax[afi][safi]);
3671 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3672
3673 if (CHECK_FLAG(peer->af_flags[afi][safi],
3674 PEER_FLAG_MAX_PREFIX_WARNING))
3675 return false;
3676
3677 /* Convert AFI, SAFI to values for packet. */
3678 pkt_afi = afi_int2iana(afi);
3679 pkt_safi = safi_int2iana(safi);
3680 {
3681 uint8_t ndata[7];
3682
3683 ndata[0] = (pkt_afi >> 8);
3684 ndata[1] = pkt_afi;
3685 ndata[2] = pkt_safi;
3686 ndata[3] = (peer->pmax[afi][safi] >> 24);
3687 ndata[4] = (peer->pmax[afi][safi] >> 16);
3688 ndata[5] = (peer->pmax[afi][safi] >> 8);
3689 ndata[6] = (peer->pmax[afi][safi]);
3690
3691 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3692 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3693 BGP_NOTIFY_CEASE_MAX_PREFIX,
3694 ndata, 7);
3695 }
3696
3697 /* Dynamic peers will just close their connection. */
3698 if (peer_dynamic_neighbor(peer))
3699 return true;
3700
3701 /* restart timer start */
3702 if (peer->pmax_restart[afi][safi]) {
3703 peer->v_pmax_restart =
3704 peer->pmax_restart[afi][safi] * 60;
3705
3706 if (bgp_debug_neighbor_events(peer))
3707 zlog_debug(
3708 "%pBP Maximum-prefix restart timer started for %d secs",
3709 peer, peer->v_pmax_restart);
3710
3711 BGP_TIMER_ON(peer->t_pmax_restart,
3712 bgp_maximum_prefix_restart_timer,
3713 peer->v_pmax_restart);
3714 }
3715
3716 return true;
3717 } else
3718 UNSET_FLAG(peer->af_sflags[afi][safi],
3719 PEER_STATUS_PREFIX_LIMIT);
3720
3721 if (pcount
3722 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3723 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3724 PEER_STATUS_PREFIX_THRESHOLD)
3725 && !always)
3726 return false;
3727
3728 zlog_info(
3729 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3730 get_afi_safi_str(afi, safi, false), peer, pcount,
3731 peer->pmax[afi][safi]);
3732 SET_FLAG(peer->af_sflags[afi][safi],
3733 PEER_STATUS_PREFIX_THRESHOLD);
3734 } else
3735 UNSET_FLAG(peer->af_sflags[afi][safi],
3736 PEER_STATUS_PREFIX_THRESHOLD);
3737 return false;
3738 }
3739
3740 /* Unconditionally remove the route from the RIB, without taking
3741 * damping into consideration (eg, because the session went down)
3742 */
3743 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3744 struct peer *peer, afi_t afi, safi_t safi)
3745 {
3746
3747 struct bgp *bgp = NULL;
3748 bool delete_route = false;
3749
3750 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3751 safi);
3752
3753 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3754 bgp_path_info_delete(dest, pi); /* keep historical info */
3755
3756 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3757 * flag
3758 */
3759 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3760 delete_route = true;
3761 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3762 delete_route = true;
3763 if (delete_route) {
3764 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3765 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3766 bgp = pi->peer->bgp;
3767 bgp->gr_info[afi][safi].gr_deferred--;
3768 }
3769 }
3770 }
3771
3772 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3773 bgp_process(peer->bgp, dest, afi, safi);
3774 }
3775
3776 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3777 struct peer *peer, afi_t afi, safi_t safi,
3778 struct prefix_rd *prd)
3779 {
3780 const struct prefix *p = bgp_dest_get_prefix(dest);
3781
3782 /* apply dampening, if result is suppressed, we'll be retaining
3783 * the bgp_path_info in the RIB for historical reference.
3784 */
3785 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3786 && peer->sort == BGP_PEER_EBGP)
3787 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3788 == BGP_DAMP_SUPPRESSED) {
3789 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3790 safi);
3791 return;
3792 }
3793
3794 #ifdef ENABLE_BGP_VNC
3795 if (safi == SAFI_MPLS_VPN) {
3796 struct bgp_dest *pdest = NULL;
3797 struct bgp_table *table = NULL;
3798
3799 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3800 (struct prefix *)prd);
3801 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3802 table = bgp_dest_get_bgp_table_info(pdest);
3803
3804 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3805 peer->bgp, prd, table, p, pi);
3806 }
3807 bgp_dest_unlock_node(pdest);
3808 }
3809 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3810 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3811
3812 vnc_import_bgp_del_route(peer->bgp, p, pi);
3813 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3814 }
3815 }
3816 #endif
3817
3818 /* If this is an EVPN route, process for un-import. */
3819 if (safi == SAFI_EVPN)
3820 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3821
3822 bgp_rib_remove(dest, pi, peer, afi, safi);
3823 }
3824
3825 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3826 struct peer *peer, struct attr *attr,
3827 struct bgp_dest *dest)
3828 {
3829 struct bgp_path_info *new;
3830
3831 /* Make new BGP info. */
3832 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3833 new->type = type;
3834 new->instance = instance;
3835 new->sub_type = sub_type;
3836 new->peer = peer;
3837 new->attr = attr;
3838 new->uptime = monotime(NULL);
3839 new->net = dest;
3840 return new;
3841 }
3842
3843 /* Check if received nexthop is valid or not. */
3844 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3845 uint8_t type, uint8_t stype, struct attr *attr,
3846 struct bgp_dest *dest)
3847 {
3848 bool ret = false;
3849 bool is_bgp_static_route =
3850 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3851 : false;
3852
3853 /* If `bgp allow-martian-nexthop` is turned on, return next-hop
3854 * as good.
3855 */
3856 if (bgp->allow_martian)
3857 return false;
3858
3859 /*
3860 * Only validated for unicast and multicast currently.
3861 * Also valid for EVPN where the nexthop is an IP address.
3862 * If we are a bgp static route being checked then there is
3863 * no need to check to see if the nexthop is martian as
3864 * that it should be ok.
3865 */
3866 if (is_bgp_static_route ||
3867 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3868 return false;
3869
3870 /* If NEXT_HOP is present, validate it. */
3871 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3872 if (attr->nexthop.s_addr == INADDR_ANY ||
3873 !ipv4_unicast_valid(&attr->nexthop) ||
3874 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3875 return true;
3876 }
3877
3878 /* If MP_NEXTHOP is present, validate it. */
3879 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3880 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3881 * it is not an IPv6 link-local address.
3882 *
3883 * If we receive an UPDATE with nexthop length set to 32 bytes
3884 * we shouldn't discard an UPDATE if it's set to (::).
3885 * The link-local (2st) is validated along the code path later.
3886 */
3887 if (attr->mp_nexthop_len) {
3888 switch (attr->mp_nexthop_len) {
3889 case BGP_ATTR_NHLEN_IPV4:
3890 case BGP_ATTR_NHLEN_VPNV4:
3891 ret = (attr->mp_nexthop_global_in.s_addr ==
3892 INADDR_ANY ||
3893 !ipv4_unicast_valid(
3894 &attr->mp_nexthop_global_in) ||
3895 bgp_nexthop_self(bgp, afi, type, stype, attr,
3896 dest));
3897 break;
3898
3899 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3900 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3901 ret = (IN6_IS_ADDR_UNSPECIFIED(
3902 &attr->mp_nexthop_global)
3903 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3904 || IN6_IS_ADDR_MULTICAST(
3905 &attr->mp_nexthop_global)
3906 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3907 dest));
3908 break;
3909 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3910 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3911 || IN6_IS_ADDR_MULTICAST(
3912 &attr->mp_nexthop_global)
3913 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3914 dest));
3915 break;
3916
3917 default:
3918 ret = true;
3919 break;
3920 }
3921 }
3922
3923 return ret;
3924 }
3925
3926 static void bgp_attr_add_no_export_community(struct attr *attr)
3927 {
3928 struct community *old;
3929 struct community *new;
3930 struct community *merge;
3931 struct community *no_export;
3932
3933 old = bgp_attr_get_community(attr);
3934 no_export = community_str2com("no-export");
3935
3936 assert(no_export);
3937
3938 if (old) {
3939 merge = community_merge(community_dup(old), no_export);
3940
3941 if (!old->refcnt)
3942 community_free(&old);
3943
3944 new = community_uniq_sort(merge);
3945 community_free(&merge);
3946 } else {
3947 new = community_dup(no_export);
3948 }
3949
3950 community_free(&no_export);
3951
3952 bgp_attr_set_community(attr, new);
3953 }
3954
3955 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3956 struct attr *attr, const struct prefix *prefix,
3957 int *sub_type)
3958 {
3959 struct listnode *node, *nnode;
3960 struct bgp *bgp;
3961 bool accept_own_found = false;
3962
3963 if (safi != SAFI_MPLS_VPN)
3964 return false;
3965
3966 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3967 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3968 return false;
3969
3970 /* The route in question carries the ACCEPT_OWN community */
3971 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3972 struct community *comm = bgp_attr_get_community(attr);
3973
3974 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3975 accept_own_found = true;
3976 }
3977
3978 /* The route in question is targeted to one or more destination VRFs
3979 * on the router (as determined by inspecting the Route Target(s)).
3980 */
3981 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3982 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3983 continue;
3984
3985 if (accept_own_found &&
3986 ecommunity_include(
3987 bgp->vpn_policy[afi]
3988 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3989 bgp_attr_get_ecommunity(attr))) {
3990 if (bgp_debug_update(peer, prefix, NULL, 1))
3991 zlog_debug(
3992 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3993 peer, prefix);
3994
3995 /* Treat this route as imported, because it's leaked
3996 * already from another VRF, and we got an updated
3997 * version from route-reflector with ACCEPT_OWN
3998 * community.
3999 */
4000 *sub_type = BGP_ROUTE_IMPORTED;
4001
4002 return true;
4003 }
4004 }
4005
4006 return false;
4007 }
4008
4009 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4010 struct attr *attr, afi_t afi, safi_t safi, int type,
4011 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4012 uint32_t num_labels, int soft_reconfig,
4013 struct bgp_route_evpn *evpn)
4014 {
4015 int ret;
4016 int aspath_loop_count = 0;
4017 struct bgp_dest *dest;
4018 struct bgp *bgp;
4019 struct attr new_attr;
4020 struct attr *attr_new;
4021 struct bgp_path_info *pi;
4022 struct bgp_path_info *new = NULL;
4023 struct bgp_path_info_extra *extra;
4024 const char *reason;
4025 char pfx_buf[BGP_PRD_PATH_STRLEN];
4026 int connected = 0;
4027 int do_loop_check = 1;
4028 int has_valid_label = 0;
4029 afi_t nh_afi;
4030 bool force_evpn_import = false;
4031 safi_t orig_safi = safi;
4032 bool leak_success = true;
4033 int allowas_in = 0;
4034
4035 if (frrtrace_enabled(frr_bgp, process_update)) {
4036 char pfxprint[PREFIX2STR_BUFFER];
4037
4038 prefix2str(p, pfxprint, sizeof(pfxprint));
4039 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4040 afi, safi, attr);
4041 }
4042
4043 #ifdef ENABLE_BGP_VNC
4044 int vnc_implicit_withdraw = 0;
4045 #endif
4046 int same_attr = 0;
4047 const struct prefix *bgp_nht_param_prefix;
4048
4049 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4050 if (orig_safi == SAFI_LABELED_UNICAST)
4051 safi = SAFI_UNICAST;
4052
4053 memset(&new_attr, 0, sizeof(new_attr));
4054 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4055 new_attr.label = MPLS_INVALID_LABEL;
4056
4057 bgp = peer->bgp;
4058 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4059 /* TODO: Check to see if we can get rid of "is_valid_label" */
4060 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4061 has_valid_label = (num_labels > 0) ? 1 : 0;
4062 else
4063 has_valid_label = bgp_is_valid_label(label);
4064
4065 if (has_valid_label)
4066 assert(label != NULL);
4067
4068 /* Update overlay index of the attribute */
4069 if (afi == AFI_L2VPN && evpn)
4070 memcpy(&attr->evpn_overlay, evpn,
4071 sizeof(struct bgp_route_evpn));
4072
4073 /* When peer's soft reconfiguration enabled. Record input packet in
4074 Adj-RIBs-In. */
4075 if (!soft_reconfig
4076 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4077 && peer != bgp->peer_self)
4078 bgp_adj_in_set(dest, peer, attr, addpath_id);
4079
4080 /* Update permitted loop count */
4081 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4082 allowas_in = peer->allowas_in[afi][safi];
4083
4084 /* Check previously received route. */
4085 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4086 if (pi->peer == peer && pi->type == type
4087 && pi->sub_type == sub_type
4088 && pi->addpath_rx_id == addpath_id)
4089 break;
4090
4091 /* AS path local-as loop check. */
4092 if (peer->change_local_as) {
4093 if (allowas_in)
4094 aspath_loop_count = allowas_in;
4095 else if (!CHECK_FLAG(peer->flags,
4096 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4097 aspath_loop_count = 1;
4098
4099 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4100 > aspath_loop_count) {
4101 peer->stat_pfx_aspath_loop++;
4102 reason = "as-path contains our own AS;";
4103 goto filtered;
4104 }
4105 }
4106
4107 /* If the peer is configured for "allowas-in origin" and the last ASN in
4108 * the
4109 * as-path is our ASN then we do not need to call aspath_loop_check
4110 */
4111 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4112 if (aspath_get_last_as(attr->aspath) == bgp->as)
4113 do_loop_check = 0;
4114
4115 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4116 bgp_nht_param_prefix = NULL;
4117 else
4118 bgp_nht_param_prefix = p;
4119
4120 /* AS path loop check. */
4121 if (do_loop_check) {
4122 if (aspath_loop_check(attr->aspath, bgp->as) >
4123 peer->allowas_in[afi][safi]) {
4124 peer->stat_pfx_aspath_loop++;
4125 reason = "as-path contains our own AS;";
4126 goto filtered;
4127 }
4128 }
4129
4130 /* If we're a CONFED we need to loop check the CONFED ID too */
4131 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4132 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4133 peer->allowas_in[afi][safi]) {
4134 peer->stat_pfx_aspath_loop++;
4135 reason = "as-path contains our own confed AS;";
4136 goto filtered;
4137 }
4138
4139 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4140 * enabled, then take care of that too.
4141 */
4142 bool accept_own = false;
4143
4144 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4145 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4146 accept_own =
4147 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4148 if (!accept_own) {
4149 peer->stat_pfx_originator_loop++;
4150 reason = "originator is us;";
4151 goto filtered;
4152 }
4153 }
4154
4155 /* Route reflector cluster ID check. */
4156 if (bgp_cluster_filter(peer, attr)) {
4157 peer->stat_pfx_cluster_loop++;
4158 reason = "reflected from the same cluster;";
4159 goto filtered;
4160 }
4161
4162 /* Apply incoming filter. */
4163 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4164 peer->stat_pfx_filter++;
4165 reason = "filter;";
4166 goto filtered;
4167 }
4168
4169 /* RFC 8212 to prevent route leaks.
4170 * This specification intends to improve this situation by requiring the
4171 * explicit configuration of both BGP Import and Export Policies for any
4172 * External BGP (EBGP) session such as customers, peers, or
4173 * confederation boundaries for all enabled address families. Through
4174 * codification of the aforementioned requirement, operators will
4175 * benefit from consistent behavior across different BGP
4176 * implementations.
4177 */
4178 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4179 if (!bgp_inbound_policy_exists(peer,
4180 &peer->filter[afi][safi])) {
4181 reason = "inbound policy missing";
4182 if (monotime_since(&bgp->ebgprequirespolicywarning,
4183 NULL) > FIFTEENMINUTE2USEC ||
4184 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4185 zlog_warn(
4186 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4187 monotime(&bgp->ebgprequirespolicywarning);
4188 }
4189 goto filtered;
4190 }
4191
4192 /* draft-ietf-idr-deprecate-as-set-confed-set
4193 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4194 * Eventually, This document (if approved) updates RFC 4271
4195 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4196 * and obsoletes RFC 6472.
4197 */
4198 if (peer->bgp->reject_as_sets)
4199 if (aspath_check_as_sets(attr->aspath)) {
4200 reason =
4201 "as-path contains AS_SET or AS_CONFED_SET type;";
4202 goto filtered;
4203 }
4204
4205 new_attr = *attr;
4206
4207 /* Apply incoming route-map.
4208 * NB: new_attr may now contain newly allocated values from route-map
4209 * "set"
4210 * commands, so we need bgp_attr_flush in the error paths, until we
4211 * intern
4212 * the attr (which takes over the memory references) */
4213 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4214 num_labels, dest)
4215 == RMAP_DENY) {
4216 peer->stat_pfx_filter++;
4217 reason = "route-map;";
4218 bgp_attr_flush(&new_attr);
4219 goto filtered;
4220 }
4221
4222 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4223 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4224 /* remove from RIB previous entry */
4225 bgp_zebra_withdraw(p, pi, bgp, safi);
4226 }
4227
4228 if (peer->sort == BGP_PEER_EBGP) {
4229
4230 /* rfc7999:
4231 * A BGP speaker receiving an announcement tagged with the
4232 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4233 * NO_EXPORT community as defined in RFC1997, or a
4234 * similar community, to prevent propagation of the
4235 * prefix outside the local AS. The community to prevent
4236 * propagation SHOULD be chosen according to the operator's
4237 * routing policy.
4238 */
4239 if (bgp_attr_get_community(&new_attr) &&
4240 community_include(bgp_attr_get_community(&new_attr),
4241 COMMUNITY_BLACKHOLE))
4242 bgp_attr_add_no_export_community(&new_attr);
4243
4244 /* If we receive the graceful-shutdown community from an eBGP
4245 * peer we must lower local-preference */
4246 if (bgp_attr_get_community(&new_attr) &&
4247 community_include(bgp_attr_get_community(&new_attr),
4248 COMMUNITY_GSHUT)) {
4249 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4250 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4251
4252 /* If graceful-shutdown is configured globally or
4253 * per neighbor, then add the GSHUT community to
4254 * all paths received from eBGP peers. */
4255 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4256 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4257 bgp_attr_add_gshut_community(&new_attr);
4258 }
4259
4260 /* next hop check. */
4261 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4262 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4263 &new_attr, dest)) {
4264 peer->stat_pfx_nh_invalid++;
4265 reason = "martian or self next-hop;";
4266 bgp_attr_flush(&new_attr);
4267 goto filtered;
4268 }
4269
4270 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4271 peer->stat_pfx_nh_invalid++;
4272 reason = "self mac;";
4273 bgp_attr_flush(&new_attr);
4274 goto filtered;
4275 }
4276
4277 if (bgp_check_role_applicability(afi, safi) &&
4278 bgp_otc_filter(peer, &new_attr)) {
4279 reason = "failing otc validation";
4280 bgp_attr_flush(&new_attr);
4281 goto filtered;
4282 }
4283
4284 /* If neighbor soo is configured, tag all incoming routes with
4285 * this SoO tag and then filter out advertisements in
4286 * subgroup_announce_check() if it matches the configured SoO
4287 * on the other peer.
4288 */
4289 if (peer->soo[afi][safi]) {
4290 struct ecommunity *old_ecomm =
4291 bgp_attr_get_ecommunity(&new_attr);
4292 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4293 struct ecommunity *new_ecomm;
4294
4295 if (old_ecomm) {
4296 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4297 ecomm_soo);
4298
4299 if (!old_ecomm->refcnt)
4300 ecommunity_free(&old_ecomm);
4301 } else {
4302 new_ecomm = ecommunity_dup(ecomm_soo);
4303 }
4304
4305 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4306 }
4307
4308 attr_new = bgp_attr_intern(&new_attr);
4309
4310 /* If the update is implicit withdraw. */
4311 if (pi) {
4312 pi->uptime = monotime(NULL);
4313 same_attr = attrhash_cmp(pi->attr, attr_new);
4314
4315 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4316
4317 /* Same attribute comes in. */
4318 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4319 && same_attr
4320 && (!has_valid_label
4321 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4322 num_labels * sizeof(mpls_label_t))
4323 == 0)) {
4324 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4325 BGP_CONFIG_DAMPENING)
4326 && peer->sort == BGP_PEER_EBGP
4327 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4328 if (bgp_debug_update(peer, p, NULL, 1)) {
4329 bgp_debug_rdpfxpath2str(
4330 afi, safi, prd, p, label,
4331 num_labels, addpath_id ? 1 : 0,
4332 addpath_id, evpn, pfx_buf,
4333 sizeof(pfx_buf));
4334 zlog_debug("%pBP rcvd %s", peer,
4335 pfx_buf);
4336 }
4337
4338 if (bgp_damp_update(pi, dest, afi, safi)
4339 != BGP_DAMP_SUPPRESSED) {
4340 bgp_aggregate_increment(bgp, p, pi, afi,
4341 safi);
4342 bgp_process(bgp, dest, afi, safi);
4343 }
4344 } else /* Duplicate - odd */
4345 {
4346 if (bgp_debug_update(peer, p, NULL, 1)) {
4347 if (!peer->rcvd_attr_printed) {
4348 zlog_debug(
4349 "%pBP rcvd UPDATE w/ attr: %s",
4350 peer,
4351 peer->rcvd_attr_str);
4352 peer->rcvd_attr_printed = 1;
4353 }
4354
4355 bgp_debug_rdpfxpath2str(
4356 afi, safi, prd, p, label,
4357 num_labels, addpath_id ? 1 : 0,
4358 addpath_id, evpn, pfx_buf,
4359 sizeof(pfx_buf));
4360 zlog_debug(
4361 "%pBP rcvd %s...duplicate ignored",
4362 peer, pfx_buf);
4363 }
4364
4365 /* graceful restart STALE flag unset. */
4366 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4367 bgp_path_info_unset_flag(
4368 dest, pi, BGP_PATH_STALE);
4369 bgp_dest_set_defer_flag(dest, false);
4370 bgp_process(bgp, dest, afi, safi);
4371 }
4372 }
4373
4374 bgp_dest_unlock_node(dest);
4375 bgp_attr_unintern(&attr_new);
4376
4377 return;
4378 }
4379
4380 /* Withdraw/Announce before we fully processed the withdraw */
4381 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4382 if (bgp_debug_update(peer, p, NULL, 1)) {
4383 bgp_debug_rdpfxpath2str(
4384 afi, safi, prd, p, label, num_labels,
4385 addpath_id ? 1 : 0, addpath_id, evpn,
4386 pfx_buf, sizeof(pfx_buf));
4387 zlog_debug(
4388 "%pBP rcvd %s, flapped quicker than processing",
4389 peer, pfx_buf);
4390 }
4391
4392 bgp_path_info_restore(dest, pi);
4393
4394 /*
4395 * If the BGP_PATH_REMOVED flag is set, then EVPN
4396 * routes would have been unimported already when a
4397 * prior BGP withdraw processing happened. Such routes
4398 * need to be imported again, so flag accordingly.
4399 */
4400 force_evpn_import = true;
4401 } else {
4402 /* implicit withdraw, decrement aggregate and pcount
4403 * here. only if update is accepted, they'll increment
4404 * below.
4405 */
4406 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4407 }
4408
4409 /* Received Logging. */
4410 if (bgp_debug_update(peer, p, NULL, 1)) {
4411 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4412 num_labels, addpath_id ? 1 : 0,
4413 addpath_id, evpn, pfx_buf,
4414 sizeof(pfx_buf));
4415 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4416 }
4417
4418 /* graceful restart STALE flag unset. */
4419 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4420 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4421 bgp_dest_set_defer_flag(dest, false);
4422 }
4423
4424 /* The attribute is changed. */
4425 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4426
4427 /* Update bgp route dampening information. */
4428 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4429 && peer->sort == BGP_PEER_EBGP) {
4430 /* This is implicit withdraw so we should update
4431 dampening
4432 information. */
4433 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4434 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4435 }
4436 #ifdef ENABLE_BGP_VNC
4437 if (safi == SAFI_MPLS_VPN) {
4438 struct bgp_dest *pdest = NULL;
4439 struct bgp_table *table = NULL;
4440
4441 pdest = bgp_node_get(bgp->rib[afi][safi],
4442 (struct prefix *)prd);
4443 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4444 table = bgp_dest_get_bgp_table_info(pdest);
4445
4446 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4447 bgp, prd, table, p, pi);
4448 }
4449 bgp_dest_unlock_node(pdest);
4450 }
4451 if ((afi == AFI_IP || afi == AFI_IP6)
4452 && (safi == SAFI_UNICAST)) {
4453 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4454 /*
4455 * Implicit withdraw case.
4456 */
4457 ++vnc_implicit_withdraw;
4458 vnc_import_bgp_del_route(bgp, p, pi);
4459 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4460 }
4461 }
4462 #endif
4463
4464 /* Special handling for EVPN update of an existing route. If the
4465 * extended community attribute has changed, we need to
4466 * un-import
4467 * the route using its existing extended community. It will be
4468 * subsequently processed for import with the new extended
4469 * community.
4470 */
4471 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4472 && !same_attr) {
4473 if ((pi->attr->flag
4474 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4475 && (attr_new->flag
4476 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4477 int cmp;
4478
4479 cmp = ecommunity_cmp(
4480 bgp_attr_get_ecommunity(pi->attr),
4481 bgp_attr_get_ecommunity(attr_new));
4482 if (!cmp) {
4483 if (bgp_debug_update(peer, p, NULL, 1))
4484 zlog_debug(
4485 "Change in EXT-COMM, existing %s new %s",
4486 ecommunity_str(
4487 bgp_attr_get_ecommunity(
4488 pi->attr)),
4489 ecommunity_str(
4490 bgp_attr_get_ecommunity(
4491 attr_new)));
4492 if (safi == SAFI_EVPN)
4493 bgp_evpn_unimport_route(
4494 bgp, afi, safi, p, pi);
4495 else /* SAFI_MPLS_VPN */
4496 vpn_leak_to_vrf_withdraw(pi);
4497 }
4498 }
4499 }
4500
4501 /* Update to new attribute. */
4502 bgp_attr_unintern(&pi->attr);
4503 pi->attr = attr_new;
4504
4505 /* Update MPLS label */
4506 if (has_valid_label) {
4507 extra = bgp_path_info_extra_get(pi);
4508 if (extra->label != label) {
4509 memcpy(&extra->label, label,
4510 num_labels * sizeof(mpls_label_t));
4511 extra->num_labels = num_labels;
4512 }
4513 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4514 bgp_set_valid_label(&extra->label[0]);
4515 }
4516
4517 /* Update SRv6 SID */
4518 if (attr->srv6_l3vpn) {
4519 extra = bgp_path_info_extra_get(pi);
4520 if (sid_diff(&extra->sid[0].sid,
4521 &attr->srv6_l3vpn->sid)) {
4522 sid_copy(&extra->sid[0].sid,
4523 &attr->srv6_l3vpn->sid);
4524 extra->num_sids = 1;
4525
4526 extra->sid[0].loc_block_len = 0;
4527 extra->sid[0].loc_node_len = 0;
4528 extra->sid[0].func_len = 0;
4529 extra->sid[0].arg_len = 0;
4530 extra->sid[0].transposition_len = 0;
4531 extra->sid[0].transposition_offset = 0;
4532
4533 if (attr->srv6_l3vpn->loc_block_len != 0) {
4534 extra->sid[0].loc_block_len =
4535 attr->srv6_l3vpn->loc_block_len;
4536 extra->sid[0].loc_node_len =
4537 attr->srv6_l3vpn->loc_node_len;
4538 extra->sid[0].func_len =
4539 attr->srv6_l3vpn->func_len;
4540 extra->sid[0].arg_len =
4541 attr->srv6_l3vpn->arg_len;
4542 extra->sid[0].transposition_len =
4543 attr->srv6_l3vpn
4544 ->transposition_len;
4545 extra->sid[0].transposition_offset =
4546 attr->srv6_l3vpn
4547 ->transposition_offset;
4548 }
4549 }
4550 } else if (attr->srv6_vpn) {
4551 extra = bgp_path_info_extra_get(pi);
4552 if (sid_diff(&extra->sid[0].sid,
4553 &attr->srv6_vpn->sid)) {
4554 sid_copy(&extra->sid[0].sid,
4555 &attr->srv6_vpn->sid);
4556 extra->num_sids = 1;
4557 }
4558 }
4559
4560 #ifdef ENABLE_BGP_VNC
4561 if ((afi == AFI_IP || afi == AFI_IP6)
4562 && (safi == SAFI_UNICAST)) {
4563 if (vnc_implicit_withdraw) {
4564 /*
4565 * Add back the route with its new attributes
4566 * (e.g., nexthop).
4567 * The route is still selected, until the route
4568 * selection
4569 * queued by bgp_process actually runs. We have
4570 * to make this
4571 * update to the VNC side immediately to avoid
4572 * racing against
4573 * configuration changes (e.g., route-map
4574 * changes) which
4575 * trigger re-importation of the entire RIB.
4576 */
4577 vnc_import_bgp_add_route(bgp, p, pi);
4578 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4579 }
4580 }
4581 #endif
4582
4583 /* Update bgp route dampening information. */
4584 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4585 && peer->sort == BGP_PEER_EBGP) {
4586 /* Now we do normal update dampening. */
4587 ret = bgp_damp_update(pi, dest, afi, safi);
4588 if (ret == BGP_DAMP_SUPPRESSED) {
4589 bgp_dest_unlock_node(dest);
4590 return;
4591 }
4592 }
4593
4594 /* Nexthop reachability check - for unicast and
4595 * labeled-unicast.. */
4596 if (((afi == AFI_IP || afi == AFI_IP6)
4597 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4598 || (safi == SAFI_EVPN &&
4599 bgp_evpn_is_prefix_nht_supported(p))) {
4600 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4601 && peer->ttl == BGP_DEFAULT_TTL
4602 && !CHECK_FLAG(peer->flags,
4603 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4604 && !CHECK_FLAG(bgp->flags,
4605 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4606 connected = 1;
4607 else
4608 connected = 0;
4609
4610 struct bgp *bgp_nexthop = bgp;
4611
4612 if (pi->extra && pi->extra->bgp_orig)
4613 bgp_nexthop = pi->extra->bgp_orig;
4614
4615 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4616
4617 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4618 safi, pi, NULL, connected,
4619 bgp_nht_param_prefix) ||
4620 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4621 bgp_path_info_set_flag(dest, pi,
4622 BGP_PATH_VALID);
4623 else {
4624 if (BGP_DEBUG(nht, NHT)) {
4625 zlog_debug("%s(%pI4): NH unresolved",
4626 __func__,
4627 (in_addr_t *)&attr_new->nexthop);
4628 }
4629 bgp_path_info_unset_flag(dest, pi,
4630 BGP_PATH_VALID);
4631 }
4632 } else {
4633 if (accept_own)
4634 bgp_path_info_set_flag(dest, pi,
4635 BGP_PATH_ACCEPT_OWN);
4636
4637 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4638 }
4639
4640 #ifdef ENABLE_BGP_VNC
4641 if (safi == SAFI_MPLS_VPN) {
4642 struct bgp_dest *pdest = NULL;
4643 struct bgp_table *table = NULL;
4644
4645 pdest = bgp_node_get(bgp->rib[afi][safi],
4646 (struct prefix *)prd);
4647 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4648 table = bgp_dest_get_bgp_table_info(pdest);
4649
4650 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4651 bgp, prd, table, p, pi);
4652 }
4653 bgp_dest_unlock_node(pdest);
4654 }
4655 #endif
4656
4657 /* If this is an EVPN route and some attribute has changed,
4658 * or we are explicitly told to perform a route import, process
4659 * route for import. If the extended community has changed, we
4660 * would
4661 * have done the un-import earlier and the import would result
4662 * in the
4663 * route getting injected into appropriate L2 VNIs. If it is
4664 * just
4665 * some other attribute change, the import will result in
4666 * updating
4667 * the attributes for the route in the VNI(s).
4668 */
4669 if (safi == SAFI_EVPN &&
4670 (!same_attr || force_evpn_import) &&
4671 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4672 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4673
4674 /* Process change. */
4675 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4676
4677 bgp_process(bgp, dest, afi, safi);
4678 bgp_dest_unlock_node(dest);
4679
4680 if (SAFI_UNICAST == safi
4681 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4682 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4683
4684 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4685 }
4686 if ((SAFI_MPLS_VPN == safi)
4687 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4688 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4689 }
4690
4691 #ifdef ENABLE_BGP_VNC
4692 if (SAFI_MPLS_VPN == safi) {
4693 mpls_label_t label_decoded = decode_label(label);
4694
4695 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4696 type, sub_type, &label_decoded);
4697 }
4698 if (SAFI_ENCAP == safi) {
4699 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4700 type, sub_type, NULL);
4701 }
4702 #endif
4703 if ((safi == SAFI_MPLS_VPN) &&
4704 !CHECK_FLAG(bgp->af_flags[afi][safi],
4705 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4706 !leak_success) {
4707 bgp_unlink_nexthop(pi);
4708 bgp_path_info_delete(dest, pi);
4709 }
4710 return;
4711 } // End of implicit withdraw
4712
4713 /* Received Logging. */
4714 if (bgp_debug_update(peer, p, NULL, 1)) {
4715 if (!peer->rcvd_attr_printed) {
4716 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4717 peer->rcvd_attr_str);
4718 peer->rcvd_attr_printed = 1;
4719 }
4720
4721 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4722 addpath_id ? 1 : 0, addpath_id, evpn,
4723 pfx_buf, sizeof(pfx_buf));
4724 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4725 }
4726
4727 /* Make new BGP info. */
4728 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4729
4730 /* Update MPLS label */
4731 if (has_valid_label) {
4732 extra = bgp_path_info_extra_get(new);
4733 if (extra->label != label) {
4734 memcpy(&extra->label, label,
4735 num_labels * sizeof(mpls_label_t));
4736 extra->num_labels = num_labels;
4737 }
4738 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4739 bgp_set_valid_label(&extra->label[0]);
4740 }
4741
4742 /* Update SRv6 SID */
4743 if (safi == SAFI_MPLS_VPN) {
4744 extra = bgp_path_info_extra_get(new);
4745 if (attr->srv6_l3vpn) {
4746 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4747 extra->num_sids = 1;
4748
4749 extra->sid[0].loc_block_len =
4750 attr->srv6_l3vpn->loc_block_len;
4751 extra->sid[0].loc_node_len =
4752 attr->srv6_l3vpn->loc_node_len;
4753 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4754 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4755 extra->sid[0].transposition_len =
4756 attr->srv6_l3vpn->transposition_len;
4757 extra->sid[0].transposition_offset =
4758 attr->srv6_l3vpn->transposition_offset;
4759 } else if (attr->srv6_vpn) {
4760 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4761 extra->num_sids = 1;
4762 }
4763 }
4764
4765 /* Nexthop reachability check. */
4766 if (((afi == AFI_IP || afi == AFI_IP6)
4767 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4768 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4769 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4770 && peer->ttl == BGP_DEFAULT_TTL
4771 && !CHECK_FLAG(peer->flags,
4772 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4773 && !CHECK_FLAG(bgp->flags,
4774 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4775 connected = 1;
4776 else
4777 connected = 0;
4778
4779 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4780
4781 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4782 connected, bgp_nht_param_prefix) ||
4783 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4784 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4785 else {
4786 if (BGP_DEBUG(nht, NHT))
4787 zlog_debug("%s(%pI4): NH unresolved", __func__,
4788 &attr_new->nexthop);
4789 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4790 }
4791 } else {
4792 if (accept_own)
4793 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4794
4795 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4796 }
4797
4798 /* If maximum prefix count is configured and current prefix
4799 * count exeed it.
4800 */
4801 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4802 reason = "maximum-prefix overflow";
4803 bgp_attr_flush(&new_attr);
4804 goto filtered;
4805 }
4806
4807 /* Addpath ID */
4808 new->addpath_rx_id = addpath_id;
4809
4810 /* Increment prefix */
4811 bgp_aggregate_increment(bgp, p, new, afi, safi);
4812
4813 /* Register new BGP information. */
4814 bgp_path_info_add(dest, new);
4815
4816 /* route_node_get lock */
4817 bgp_dest_unlock_node(dest);
4818
4819 #ifdef ENABLE_BGP_VNC
4820 if (safi == SAFI_MPLS_VPN) {
4821 struct bgp_dest *pdest = NULL;
4822 struct bgp_table *table = NULL;
4823
4824 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4825 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4826 table = bgp_dest_get_bgp_table_info(pdest);
4827
4828 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4829 bgp, prd, table, p, new);
4830 }
4831 bgp_dest_unlock_node(pdest);
4832 }
4833 #endif
4834
4835 /* If this is an EVPN route, process for import. */
4836 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4837 bgp_evpn_import_route(bgp, afi, safi, p, new);
4838
4839 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4840
4841 /* Process change. */
4842 bgp_process(bgp, dest, afi, safi);
4843
4844 if (SAFI_UNICAST == safi
4845 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4846 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4847 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4848 }
4849 if ((SAFI_MPLS_VPN == safi)
4850 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4851 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4852 }
4853 #ifdef ENABLE_BGP_VNC
4854 if (SAFI_MPLS_VPN == safi) {
4855 mpls_label_t label_decoded = decode_label(label);
4856
4857 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4858 sub_type, &label_decoded);
4859 }
4860 if (SAFI_ENCAP == safi) {
4861 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4862 sub_type, NULL);
4863 }
4864 #endif
4865 if ((safi == SAFI_MPLS_VPN) &&
4866 !CHECK_FLAG(bgp->af_flags[afi][safi],
4867 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4868 !leak_success) {
4869 bgp_unlink_nexthop(new);
4870 bgp_path_info_delete(dest, new);
4871 }
4872
4873 return;
4874
4875 /* This BGP update is filtered. Log the reason then update BGP
4876 entry. */
4877 filtered:
4878 if (new) {
4879 bgp_unlink_nexthop(new);
4880 bgp_path_info_delete(dest, new);
4881 bgp_path_info_extra_free(&new->extra);
4882 XFREE(MTYPE_BGP_ROUTE, new);
4883 }
4884
4885 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4886
4887 if (bgp_debug_update(peer, p, NULL, 1)) {
4888 if (!peer->rcvd_attr_printed) {
4889 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4890 peer->rcvd_attr_str);
4891 peer->rcvd_attr_printed = 1;
4892 }
4893
4894 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4895 addpath_id ? 1 : 0, addpath_id, evpn,
4896 pfx_buf, sizeof(pfx_buf));
4897 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4898 peer, pfx_buf, reason);
4899 }
4900
4901 if (pi) {
4902 /* If this is an EVPN route, un-import it as it is now filtered.
4903 */
4904 if (safi == SAFI_EVPN)
4905 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4906
4907 if (SAFI_UNICAST == safi
4908 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4909 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4910
4911 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4912 }
4913 if ((SAFI_MPLS_VPN == safi)
4914 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4915
4916 vpn_leak_to_vrf_withdraw(pi);
4917 }
4918
4919 bgp_rib_remove(dest, pi, peer, afi, safi);
4920 }
4921
4922 bgp_dest_unlock_node(dest);
4923
4924 #ifdef ENABLE_BGP_VNC
4925 /*
4926 * Filtered update is treated as an implicit withdrawal (see
4927 * bgp_rib_remove()
4928 * a few lines above)
4929 */
4930 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4931 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4932 0);
4933 }
4934 #endif
4935
4936 return;
4937 }
4938
4939 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4940 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4941 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4942 uint32_t num_labels, struct bgp_route_evpn *evpn)
4943 {
4944 struct bgp *bgp;
4945 char pfx_buf[BGP_PRD_PATH_STRLEN];
4946 struct bgp_dest *dest;
4947 struct bgp_path_info *pi;
4948
4949 #ifdef ENABLE_BGP_VNC
4950 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4951 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4952 0);
4953 }
4954 #endif
4955
4956 bgp = peer->bgp;
4957
4958 /* Lookup node. */
4959 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4960
4961 /* If peer is soft reconfiguration enabled. Record input packet for
4962 * further calculation.
4963 *
4964 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4965 * routes that are filtered. This tanks out Quagga RS pretty badly due
4966 * to
4967 * the iteration over all RS clients.
4968 * Since we need to remove the entry from adj_in anyway, do that first
4969 * and
4970 * if there was no entry, we don't need to do anything more.
4971 */
4972 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4973 && peer != bgp->peer_self)
4974 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4975 peer->stat_pfx_dup_withdraw++;
4976
4977 if (bgp_debug_update(peer, p, NULL, 1)) {
4978 bgp_debug_rdpfxpath2str(
4979 afi, safi, prd, p, label, num_labels,
4980 addpath_id ? 1 : 0, addpath_id, NULL,
4981 pfx_buf, sizeof(pfx_buf));
4982 zlog_debug(
4983 "%s withdrawing route %s not in adj-in",
4984 peer->host, pfx_buf);
4985 }
4986 bgp_dest_unlock_node(dest);
4987 return;
4988 }
4989
4990 /* Lookup withdrawn route. */
4991 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4992 if (pi->peer == peer && pi->type == type
4993 && pi->sub_type == sub_type
4994 && pi->addpath_rx_id == addpath_id)
4995 break;
4996
4997 /* Logging. */
4998 if (bgp_debug_update(peer, p, NULL, 1)) {
4999 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5000 addpath_id ? 1 : 0, addpath_id, NULL,
5001 pfx_buf, sizeof(pfx_buf));
5002 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
5003 pfx_buf);
5004 }
5005
5006 /* Withdraw specified route from routing table. */
5007 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
5008 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
5009 if (SAFI_UNICAST == safi
5010 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5011 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5012 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5013 }
5014 if ((SAFI_MPLS_VPN == safi)
5015 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5016
5017 vpn_leak_to_vrf_withdraw(pi);
5018 }
5019 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5020 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5021 addpath_id ? 1 : 0, addpath_id, NULL,
5022 pfx_buf, sizeof(pfx_buf));
5023 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5024 }
5025
5026 /* Unlock bgp_node_get() lock. */
5027 bgp_dest_unlock_node(dest);
5028
5029 return;
5030 }
5031
5032 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5033 int withdraw)
5034 {
5035 struct update_subgroup *subgrp;
5036 subgrp = peer_subgroup(peer, afi, safi);
5037 subgroup_default_originate(subgrp, withdraw);
5038 }
5039
5040
5041 /*
5042 * bgp_stop_announce_route_timer
5043 */
5044 void bgp_stop_announce_route_timer(struct peer_af *paf)
5045 {
5046 if (!paf->t_announce_route)
5047 return;
5048
5049 EVENT_OFF(paf->t_announce_route);
5050 }
5051
5052 /*
5053 * bgp_announce_route_timer_expired
5054 *
5055 * Callback that is invoked when the route announcement timer for a
5056 * peer_af expires.
5057 */
5058 static void bgp_announce_route_timer_expired(struct event *t)
5059 {
5060 struct peer_af *paf;
5061 struct peer *peer;
5062
5063 paf = EVENT_ARG(t);
5064 peer = paf->peer;
5065
5066 if (!peer_established(peer))
5067 return;
5068
5069 if (!peer->afc_nego[paf->afi][paf->safi])
5070 return;
5071
5072 peer_af_announce_route(paf, 1);
5073
5074 /* Notify BGP conditional advertisement scanner percess */
5075 peer->advmap_config_change[paf->afi][paf->safi] = true;
5076 }
5077
5078 /*
5079 * bgp_announce_route
5080 *
5081 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5082 *
5083 * if force is true we will force an update even if the update
5084 * limiting code is attempted to kick in.
5085 */
5086 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5087 {
5088 struct peer_af *paf;
5089 struct update_subgroup *subgrp;
5090
5091 paf = peer_af_find(peer, afi, safi);
5092 if (!paf)
5093 return;
5094 subgrp = PAF_SUBGRP(paf);
5095
5096 /*
5097 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5098 * or a refresh has already been triggered.
5099 */
5100 if (!subgrp || paf->t_announce_route)
5101 return;
5102
5103 if (force)
5104 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5105
5106 /*
5107 * Start a timer to stagger/delay the announce. This serves
5108 * two purposes - announcement can potentially be combined for
5109 * multiple peers and the announcement doesn't happen in the
5110 * vty context.
5111 */
5112 event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5113 (subgrp->peer_count == 1)
5114 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5115 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5116 &paf->t_announce_route);
5117 }
5118
5119 /*
5120 * Announce routes from all AF tables to a peer.
5121 *
5122 * This should ONLY be called when there is a need to refresh the
5123 * routes to the peer based on a policy change for this peer alone
5124 * or a route refresh request received from the peer.
5125 * The operation will result in splitting the peer from its existing
5126 * subgroups and putting it in new subgroups.
5127 */
5128 void bgp_announce_route_all(struct peer *peer)
5129 {
5130 afi_t afi;
5131 safi_t safi;
5132
5133 FOREACH_AFI_SAFI (afi, safi)
5134 bgp_announce_route(peer, afi, safi, false);
5135 }
5136
5137 /* Flag or unflag bgp_dest to determine whether it should be treated by
5138 * bgp_soft_reconfig_table_task.
5139 * Flag if flag is true. Unflag if flag is false.
5140 */
5141 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5142 {
5143 struct bgp_dest *dest;
5144 struct bgp_adj_in *ain;
5145
5146 if (!table)
5147 return;
5148
5149 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5150 for (ain = dest->adj_in; ain; ain = ain->next) {
5151 if (ain->peer != NULL)
5152 break;
5153 }
5154 if (flag && ain != NULL && ain->peer != NULL)
5155 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5156 else
5157 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5158 }
5159 }
5160
5161 static void bgp_soft_reconfig_table_update(struct peer *peer,
5162 struct bgp_dest *dest,
5163 struct bgp_adj_in *ain, afi_t afi,
5164 safi_t safi, struct prefix_rd *prd)
5165 {
5166 struct bgp_path_info *pi;
5167 uint32_t num_labels = 0;
5168 mpls_label_t *label_pnt = NULL;
5169 struct bgp_route_evpn evpn;
5170
5171 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5172 if (pi->peer == peer)
5173 break;
5174
5175 if (pi && pi->extra)
5176 num_labels = pi->extra->num_labels;
5177 if (num_labels)
5178 label_pnt = &pi->extra->label[0];
5179 if (pi)
5180 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5181 sizeof(evpn));
5182 else
5183 memset(&evpn, 0, sizeof(evpn));
5184
5185 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5186 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5187 label_pnt, num_labels, 1, &evpn);
5188 }
5189
5190 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5191 struct bgp_table *table,
5192 struct prefix_rd *prd)
5193 {
5194 struct bgp_dest *dest;
5195 struct bgp_adj_in *ain;
5196
5197 if (!table)
5198 table = peer->bgp->rib[afi][safi];
5199
5200 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5201 for (ain = dest->adj_in; ain; ain = ain->next) {
5202 if (ain->peer != peer)
5203 continue;
5204
5205 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5206 safi, prd);
5207 }
5208 }
5209
5210 /* Do soft reconfig table per bgp table.
5211 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5212 * when BGP_NODE_SOFT_RECONFIG is set,
5213 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5214 * Schedule a new thread to continue the job.
5215 * Without splitting the full job into several part,
5216 * vtysh waits for the job to finish before responding to a BGP command
5217 */
5218 static void bgp_soft_reconfig_table_task(struct event *thread)
5219 {
5220 uint32_t iter, max_iter;
5221 struct bgp_dest *dest;
5222 struct bgp_adj_in *ain;
5223 struct peer *peer;
5224 struct bgp_table *table;
5225 struct prefix_rd *prd;
5226 struct listnode *node, *nnode;
5227
5228 table = EVENT_ARG(thread);
5229 prd = NULL;
5230
5231 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5232 if (table->soft_reconfig_init) {
5233 /* first call of the function with a new srta structure.
5234 * Don't do any treatment this time on nodes
5235 * in order vtysh to respond quickly
5236 */
5237 max_iter = 0;
5238 }
5239
5240 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5241 dest = bgp_route_next(dest)) {
5242 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5243 continue;
5244
5245 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5246
5247 for (ain = dest->adj_in; ain; ain = ain->next) {
5248 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5249 nnode, peer)) {
5250 if (ain->peer != peer)
5251 continue;
5252
5253 bgp_soft_reconfig_table_update(
5254 peer, dest, ain, table->afi,
5255 table->safi, prd);
5256 iter++;
5257 }
5258 }
5259 }
5260
5261 /* we're either starting the initial iteration,
5262 * or we're going to continue an ongoing iteration
5263 */
5264 if (dest || table->soft_reconfig_init) {
5265 table->soft_reconfig_init = false;
5266 event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
5267 0, &table->soft_reconfig_thread);
5268 return;
5269 }
5270 /* we're done, clean up the background iteration context info and
5271 schedule route annoucement
5272 */
5273 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5274 listnode_delete(table->soft_reconfig_peers, peer);
5275 bgp_announce_route(peer, table->afi, table->safi, false);
5276 }
5277
5278 list_delete(&table->soft_reconfig_peers);
5279 }
5280
5281
5282 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5283 * and peer.
5284 * - bgp cannot be NULL
5285 * - if table and peer are NULL, cancel all threads within the bgp instance
5286 * - if table is NULL and peer is not,
5287 * remove peer in all threads within the bgp instance
5288 * - if peer is NULL, cancel all threads matching table within the bgp instance
5289 */
5290 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5291 const struct bgp_table *table,
5292 const struct peer *peer)
5293 {
5294 struct peer *npeer;
5295 struct listnode *node, *nnode;
5296 int afi, safi;
5297 struct bgp_table *ntable;
5298
5299 if (!bgp)
5300 return;
5301
5302 FOREACH_AFI_SAFI (afi, safi) {
5303 ntable = bgp->rib[afi][safi];
5304 if (!ntable)
5305 continue;
5306 if (table && table != ntable)
5307 continue;
5308
5309 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5310 npeer)) {
5311 if (peer && peer != npeer)
5312 continue;
5313 listnode_delete(ntable->soft_reconfig_peers, npeer);
5314 }
5315
5316 if (!ntable->soft_reconfig_peers
5317 || !list_isempty(ntable->soft_reconfig_peers))
5318 continue;
5319
5320 list_delete(&ntable->soft_reconfig_peers);
5321 bgp_soft_reconfig_table_flag(ntable, false);
5322 EVENT_OFF(ntable->soft_reconfig_thread);
5323 }
5324 }
5325
5326 /*
5327 * Returns false if the peer is not configured for soft reconfig in
5328 */
5329 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5330 {
5331 struct bgp_dest *dest;
5332 struct bgp_table *table;
5333 struct listnode *node, *nnode;
5334 struct peer *npeer;
5335 struct peer_af *paf;
5336
5337 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5338 return false;
5339
5340 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5341 && (safi != SAFI_EVPN)) {
5342 table = peer->bgp->rib[afi][safi];
5343 if (!table)
5344 return true;
5345
5346 table->soft_reconfig_init = true;
5347
5348 if (!table->soft_reconfig_peers)
5349 table->soft_reconfig_peers = list_new();
5350 npeer = NULL;
5351 /* add peer to the table soft_reconfig_peers if not already
5352 * there
5353 */
5354 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5355 npeer)) {
5356 if (peer == npeer)
5357 break;
5358 }
5359 if (peer != npeer)
5360 listnode_add(table->soft_reconfig_peers, peer);
5361
5362 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5363 * on table would start back at the beginning.
5364 */
5365 bgp_soft_reconfig_table_flag(table, true);
5366
5367 if (!table->soft_reconfig_thread)
5368 event_add_event(bm->master,
5369 bgp_soft_reconfig_table_task, table, 0,
5370 &table->soft_reconfig_thread);
5371 /* Cancel bgp_announce_route_timer_expired threads.
5372 * bgp_announce_route_timer_expired threads have been scheduled
5373 * to announce routes as soon as the soft_reconfigure process
5374 * finishes.
5375 * In this case, soft_reconfigure is also scheduled by using
5376 * a thread but is planned after the
5377 * bgp_announce_route_timer_expired threads. It means that,
5378 * without cancelling the threads, the route announcement task
5379 * would run before the soft reconfiguration one. That would
5380 * useless and would block vtysh during several seconds. Route
5381 * announcements are rescheduled as soon as the soft_reconfigure
5382 * process finishes.
5383 */
5384 paf = peer_af_find(peer, afi, safi);
5385 if (paf)
5386 bgp_stop_announce_route_timer(paf);
5387 } else
5388 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5389 dest = bgp_route_next(dest)) {
5390 table = bgp_dest_get_bgp_table_info(dest);
5391
5392 if (table == NULL)
5393 continue;
5394
5395 const struct prefix *p = bgp_dest_get_prefix(dest);
5396 struct prefix_rd prd;
5397
5398 prd.family = AF_UNSPEC;
5399 prd.prefixlen = 64;
5400 memcpy(&prd.val, p->u.val, 8);
5401
5402 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5403 }
5404
5405 return true;
5406 }
5407
5408
5409 struct bgp_clear_node_queue {
5410 struct bgp_dest *dest;
5411 };
5412
5413 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5414 {
5415 struct bgp_clear_node_queue *cnq = data;
5416 struct bgp_dest *dest = cnq->dest;
5417 struct peer *peer = wq->spec.data;
5418 struct bgp_path_info *pi;
5419 struct bgp *bgp;
5420 afi_t afi = bgp_dest_table(dest)->afi;
5421 safi_t safi = bgp_dest_table(dest)->safi;
5422
5423 assert(dest && peer);
5424 bgp = peer->bgp;
5425
5426 /* It is possible that we have multiple paths for a prefix from a peer
5427 * if that peer is using AddPath.
5428 */
5429 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5430 if (pi->peer != peer)
5431 continue;
5432
5433 /* graceful restart STALE flag set. */
5434 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5435 && peer->nsf[afi][safi])
5436 || CHECK_FLAG(peer->af_sflags[afi][safi],
5437 PEER_STATUS_ENHANCED_REFRESH))
5438 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5439 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5440 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5441 else {
5442 /* If this is an EVPN route, process for
5443 * un-import. */
5444 if (safi == SAFI_EVPN)
5445 bgp_evpn_unimport_route(
5446 bgp, afi, safi,
5447 bgp_dest_get_prefix(dest), pi);
5448 /* Handle withdraw for VRF route-leaking and L3VPN */
5449 if (SAFI_UNICAST == safi
5450 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5451 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5452 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5453 bgp, pi);
5454 }
5455 if (SAFI_MPLS_VPN == safi &&
5456 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5457 vpn_leak_to_vrf_withdraw(pi);
5458 }
5459
5460 bgp_rib_remove(dest, pi, peer, afi, safi);
5461 }
5462 }
5463 return WQ_SUCCESS;
5464 }
5465
5466 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5467 {
5468 struct bgp_clear_node_queue *cnq = data;
5469 struct bgp_dest *dest = cnq->dest;
5470 struct bgp_table *table = bgp_dest_table(dest);
5471
5472 bgp_dest_unlock_node(dest);
5473 bgp_table_unlock(table);
5474 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5475 }
5476
5477 static void bgp_clear_node_complete(struct work_queue *wq)
5478 {
5479 struct peer *peer = wq->spec.data;
5480
5481 /* Tickle FSM to start moving again */
5482 BGP_EVENT_ADD(peer, Clearing_Completed);
5483
5484 peer_unlock(peer); /* bgp_clear_route */
5485 }
5486
5487 static void bgp_clear_node_queue_init(struct peer *peer)
5488 {
5489 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5490
5491 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5492 #undef CLEAR_QUEUE_NAME_LEN
5493
5494 peer->clear_node_queue = work_queue_new(bm->master, wname);
5495 peer->clear_node_queue->spec.hold = 10;
5496 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5497 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5498 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5499 peer->clear_node_queue->spec.max_retries = 0;
5500
5501 /* we only 'lock' this peer reference when the queue is actually active
5502 */
5503 peer->clear_node_queue->spec.data = peer;
5504 }
5505
5506 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5507 struct bgp_table *table)
5508 {
5509 struct bgp_dest *dest;
5510 int force = peer->bgp->process_queue ? 0 : 1;
5511
5512 if (!table)
5513 table = peer->bgp->rib[afi][safi];
5514
5515 /* If still no table => afi/safi isn't configured at all or smth. */
5516 if (!table)
5517 return;
5518
5519 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5520 struct bgp_path_info *pi, *next;
5521 struct bgp_adj_in *ain;
5522 struct bgp_adj_in *ain_next;
5523
5524 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5525 * queued for every clearing peer, regardless of whether it is
5526 * relevant to the peer at hand.
5527 *
5528 * Overview: There are 3 different indices which need to be
5529 * scrubbed, potentially, when a peer is removed:
5530 *
5531 * 1 peer's routes visible via the RIB (ie accepted routes)
5532 * 2 peer's routes visible by the (optional) peer's adj-in index
5533 * 3 other routes visible by the peer's adj-out index
5534 *
5535 * 3 there is no hurry in scrubbing, once the struct peer is
5536 * removed from bgp->peer, we could just GC such deleted peer's
5537 * adj-outs at our leisure.
5538 *
5539 * 1 and 2 must be 'scrubbed' in some way, at least made
5540 * invisible via RIB index before peer session is allowed to be
5541 * brought back up. So one needs to know when such a 'search' is
5542 * complete.
5543 *
5544 * Ideally:
5545 *
5546 * - there'd be a single global queue or a single RIB walker
5547 * - rather than tracking which route_nodes still need to be
5548 * examined on a peer basis, we'd track which peers still
5549 * aren't cleared
5550 *
5551 * Given that our per-peer prefix-counts now should be reliable,
5552 * this may actually be achievable. It doesn't seem to be a huge
5553 * problem at this time,
5554 *
5555 * It is possible that we have multiple paths for a prefix from
5556 * a peer
5557 * if that peer is using AddPath.
5558 */
5559 ain = dest->adj_in;
5560 while (ain) {
5561 ain_next = ain->next;
5562
5563 if (ain->peer == peer)
5564 bgp_adj_in_remove(dest, ain);
5565
5566 ain = ain_next;
5567 }
5568
5569 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5570 next = pi->next;
5571 if (pi->peer != peer)
5572 continue;
5573
5574 if (force)
5575 bgp_path_info_reap(dest, pi);
5576 else {
5577 struct bgp_clear_node_queue *cnq;
5578
5579 /* both unlocked in bgp_clear_node_queue_del */
5580 bgp_table_lock(bgp_dest_table(dest));
5581 bgp_dest_lock_node(dest);
5582 cnq = XCALLOC(
5583 MTYPE_BGP_CLEAR_NODE_QUEUE,
5584 sizeof(struct bgp_clear_node_queue));
5585 cnq->dest = dest;
5586 work_queue_add(peer->clear_node_queue, cnq);
5587 break;
5588 }
5589 }
5590 }
5591 return;
5592 }
5593
5594 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5595 {
5596 struct bgp_dest *dest;
5597 struct bgp_table *table;
5598
5599 if (peer->clear_node_queue == NULL)
5600 bgp_clear_node_queue_init(peer);
5601
5602 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5603 * Idle until it receives a Clearing_Completed event. This protects
5604 * against peers which flap faster than we can we clear, which could
5605 * lead to:
5606 *
5607 * a) race with routes from the new session being installed before
5608 * clear_route_node visits the node (to delete the route of that
5609 * peer)
5610 * b) resource exhaustion, clear_route_node likely leads to an entry
5611 * on the process_main queue. Fast-flapping could cause that queue
5612 * to grow and grow.
5613 */
5614
5615 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5616 * the unlock will happen upon work-queue completion; other wise, the
5617 * unlock happens at the end of this function.
5618 */
5619 if (!peer->clear_node_queue->thread)
5620 peer_lock(peer);
5621
5622 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5623 bgp_clear_route_table(peer, afi, safi, NULL);
5624 else
5625 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5626 dest = bgp_route_next(dest)) {
5627 table = bgp_dest_get_bgp_table_info(dest);
5628 if (!table)
5629 continue;
5630
5631 bgp_clear_route_table(peer, afi, safi, table);
5632 }
5633
5634 /* unlock if no nodes got added to the clear-node-queue. */
5635 if (!peer->clear_node_queue->thread)
5636 peer_unlock(peer);
5637 }
5638
5639 void bgp_clear_route_all(struct peer *peer)
5640 {
5641 afi_t afi;
5642 safi_t safi;
5643
5644 FOREACH_AFI_SAFI (afi, safi)
5645 bgp_clear_route(peer, afi, safi);
5646
5647 #ifdef ENABLE_BGP_VNC
5648 rfapiProcessPeerDown(peer);
5649 #endif
5650 }
5651
5652 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5653 {
5654 struct bgp_table *table;
5655 struct bgp_dest *dest;
5656 struct bgp_adj_in *ain;
5657 struct bgp_adj_in *ain_next;
5658
5659 table = peer->bgp->rib[afi][safi];
5660
5661 /* It is possible that we have multiple paths for a prefix from a peer
5662 * if that peer is using AddPath.
5663 */
5664 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5665 ain = dest->adj_in;
5666
5667 while (ain) {
5668 ain_next = ain->next;
5669
5670 if (ain->peer == peer)
5671 bgp_adj_in_remove(dest, ain);
5672
5673 ain = ain_next;
5674 }
5675 }
5676 }
5677
5678 /* If any of the routes from the peer have been marked with the NO_LLGR
5679 * community, either as sent by the peer, or as the result of a configured
5680 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5681 * operation of [RFC4271].
5682 */
5683 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5684 {
5685 struct bgp_dest *dest;
5686 struct bgp_path_info *pi;
5687 struct bgp_table *table;
5688
5689 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5690 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5691 dest = bgp_route_next(dest)) {
5692 struct bgp_dest *rm;
5693
5694 /* look for neighbor in tables */
5695 table = bgp_dest_get_bgp_table_info(dest);
5696 if (!table)
5697 continue;
5698
5699 for (rm = bgp_table_top(table); rm;
5700 rm = bgp_route_next(rm))
5701 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5702 pi = pi->next) {
5703 if (pi->peer != peer)
5704 continue;
5705 if (CHECK_FLAG(
5706 peer->af_sflags[afi][safi],
5707 PEER_STATUS_LLGR_WAIT) &&
5708 bgp_attr_get_community(pi->attr) &&
5709 !community_include(
5710 bgp_attr_get_community(
5711 pi->attr),
5712 COMMUNITY_NO_LLGR))
5713 continue;
5714 if (!CHECK_FLAG(pi->flags,
5715 BGP_PATH_STALE))
5716 continue;
5717
5718 /*
5719 * If this is VRF leaked route
5720 * process for withdraw.
5721 */
5722 if (pi->sub_type ==
5723 BGP_ROUTE_IMPORTED &&
5724 peer->bgp->inst_type ==
5725 BGP_INSTANCE_TYPE_DEFAULT)
5726 vpn_leak_to_vrf_withdraw(pi);
5727
5728 bgp_rib_remove(rm, pi, peer, afi, safi);
5729 break;
5730 }
5731 }
5732 } else {
5733 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5734 dest = bgp_route_next(dest))
5735 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5736 pi = pi->next) {
5737 if (pi->peer != peer)
5738 continue;
5739 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5740 PEER_STATUS_LLGR_WAIT) &&
5741 bgp_attr_get_community(pi->attr) &&
5742 !community_include(
5743 bgp_attr_get_community(pi->attr),
5744 COMMUNITY_NO_LLGR))
5745 continue;
5746 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5747 continue;
5748 if (safi == SAFI_UNICAST &&
5749 (peer->bgp->inst_type ==
5750 BGP_INSTANCE_TYPE_VRF ||
5751 peer->bgp->inst_type ==
5752 BGP_INSTANCE_TYPE_DEFAULT))
5753 vpn_leak_from_vrf_withdraw(
5754 bgp_get_default(), peer->bgp,
5755 pi);
5756
5757 bgp_rib_remove(dest, pi, peer, afi, safi);
5758 break;
5759 }
5760 }
5761 }
5762
5763 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5764 {
5765 struct bgp_dest *dest, *ndest;
5766 struct bgp_path_info *pi;
5767 struct bgp_table *table;
5768
5769 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5770 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5771 dest = bgp_route_next(dest)) {
5772 table = bgp_dest_get_bgp_table_info(dest);
5773 if (!table)
5774 continue;
5775
5776 for (ndest = bgp_table_top(table); ndest;
5777 ndest = bgp_route_next(ndest)) {
5778 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5779 pi = pi->next) {
5780 if (pi->peer != peer)
5781 continue;
5782
5783 if ((CHECK_FLAG(
5784 peer->af_sflags[afi][safi],
5785 PEER_STATUS_ENHANCED_REFRESH))
5786 && !CHECK_FLAG(pi->flags,
5787 BGP_PATH_STALE)
5788 && !CHECK_FLAG(
5789 pi->flags,
5790 BGP_PATH_UNUSEABLE)) {
5791 if (bgp_debug_neighbor_events(
5792 peer))
5793 zlog_debug(
5794 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5795 peer,
5796 afi2str(afi),
5797 safi2str(safi),
5798 bgp_dest_get_prefix(
5799 ndest));
5800
5801 bgp_path_info_set_flag(
5802 ndest, pi,
5803 BGP_PATH_STALE);
5804 }
5805 }
5806 }
5807 }
5808 } else {
5809 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5810 dest = bgp_route_next(dest)) {
5811 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5812 pi = pi->next) {
5813 if (pi->peer != peer)
5814 continue;
5815
5816 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5817 PEER_STATUS_ENHANCED_REFRESH))
5818 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5819 && !CHECK_FLAG(pi->flags,
5820 BGP_PATH_UNUSEABLE)) {
5821 if (bgp_debug_neighbor_events(peer))
5822 zlog_debug(
5823 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5824 peer, afi2str(afi),
5825 safi2str(safi),
5826 bgp_dest_get_prefix(
5827 dest));
5828
5829 bgp_path_info_set_flag(dest, pi,
5830 BGP_PATH_STALE);
5831 }
5832 }
5833 }
5834 }
5835 }
5836
5837 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5838 {
5839 if (peer->sort == BGP_PEER_IBGP)
5840 return true;
5841
5842 if (peer->sort == BGP_PEER_EBGP
5843 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5844 || FILTER_LIST_OUT_NAME(filter)
5845 || DISTRIBUTE_OUT_NAME(filter)))
5846 return true;
5847 return false;
5848 }
5849
5850 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5851 {
5852 if (peer->sort == BGP_PEER_IBGP)
5853 return true;
5854
5855 if (peer->sort == BGP_PEER_EBGP
5856 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5857 || FILTER_LIST_IN_NAME(filter)
5858 || DISTRIBUTE_IN_NAME(filter)))
5859 return true;
5860 return false;
5861 }
5862
5863 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5864 safi_t safi)
5865 {
5866 struct bgp_dest *dest;
5867 struct bgp_path_info *pi;
5868 struct bgp_path_info *next;
5869
5870 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5871 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5872 const struct prefix *p = bgp_dest_get_prefix(dest);
5873
5874 next = pi->next;
5875
5876 /* Unimport EVPN routes from VRFs */
5877 if (safi == SAFI_EVPN)
5878 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5879 SAFI_EVPN, p, pi);
5880
5881 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5882 && pi->type == ZEBRA_ROUTE_BGP
5883 && (pi->sub_type == BGP_ROUTE_NORMAL
5884 || pi->sub_type == BGP_ROUTE_AGGREGATE
5885 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5886
5887 if (bgp_fibupd_safi(safi))
5888 bgp_zebra_withdraw(p, pi, bgp, safi);
5889 }
5890
5891 bgp_path_info_reap(dest, pi);
5892 }
5893 }
5894
5895 /* Delete all kernel routes. */
5896 void bgp_cleanup_routes(struct bgp *bgp)
5897 {
5898 afi_t afi;
5899 struct bgp_dest *dest;
5900 struct bgp_table *table;
5901
5902 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5903 if (afi == AFI_L2VPN)
5904 continue;
5905 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5906 SAFI_UNICAST);
5907 /*
5908 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5909 */
5910 if (afi != AFI_L2VPN) {
5911 safi_t safi;
5912 safi = SAFI_MPLS_VPN;
5913 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5914 dest = bgp_route_next(dest)) {
5915 table = bgp_dest_get_bgp_table_info(dest);
5916 if (table != NULL) {
5917 bgp_cleanup_table(bgp, table, safi);
5918 bgp_table_finish(&table);
5919 bgp_dest_set_bgp_table_info(dest, NULL);
5920 bgp_dest_unlock_node(dest);
5921 }
5922 }
5923 safi = SAFI_ENCAP;
5924 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5925 dest = bgp_route_next(dest)) {
5926 table = bgp_dest_get_bgp_table_info(dest);
5927 if (table != NULL) {
5928 bgp_cleanup_table(bgp, table, safi);
5929 bgp_table_finish(&table);
5930 bgp_dest_set_bgp_table_info(dest, NULL);
5931 bgp_dest_unlock_node(dest);
5932 }
5933 }
5934 }
5935 }
5936 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5937 dest = bgp_route_next(dest)) {
5938 table = bgp_dest_get_bgp_table_info(dest);
5939 if (table != NULL) {
5940 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5941 bgp_table_finish(&table);
5942 bgp_dest_set_bgp_table_info(dest, NULL);
5943 bgp_dest_unlock_node(dest);
5944 }
5945 }
5946 }
5947
5948 void bgp_reset(void)
5949 {
5950 vty_reset();
5951 bgp_zclient_reset();
5952 access_list_reset();
5953 prefix_list_reset();
5954 }
5955
5956 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5957 {
5958 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5959 && CHECK_FLAG(peer->af_cap[afi][safi],
5960 PEER_CAP_ADDPATH_AF_TX_RCV));
5961 }
5962
5963 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5964 value. */
5965 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5966 struct bgp_nlri *packet)
5967 {
5968 uint8_t *pnt;
5969 uint8_t *lim;
5970 struct prefix p;
5971 int psize;
5972 afi_t afi;
5973 safi_t safi;
5974 bool addpath_capable;
5975 uint32_t addpath_id;
5976
5977 pnt = packet->nlri;
5978 lim = pnt + packet->length;
5979 afi = packet->afi;
5980 safi = packet->safi;
5981 addpath_id = 0;
5982 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5983
5984 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5985 syntactic validity. If the field is syntactically incorrect,
5986 then the Error Subcode is set to Invalid Network Field. */
5987 for (; pnt < lim; pnt += psize) {
5988 /* Clear prefix structure. */
5989 memset(&p, 0, sizeof(p));
5990
5991 if (addpath_capable) {
5992
5993 /* When packet overflow occurs return immediately. */
5994 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5995 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5996
5997 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5998 addpath_id = ntohl(addpath_id);
5999 pnt += BGP_ADDPATH_ID_LEN;
6000 }
6001
6002 /* Fetch prefix length. */
6003 p.prefixlen = *pnt++;
6004 /* afi/safi validity already verified by caller,
6005 * bgp_update_receive */
6006 p.family = afi2family(afi);
6007
6008 /* Prefix length check. */
6009 if (p.prefixlen > prefix_blen(&p) * 8) {
6010 flog_err(
6011 EC_BGP_UPDATE_RCV,
6012 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6013 peer->host, p.prefixlen, packet->afi);
6014 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6015 }
6016
6017 /* Packet size overflow check. */
6018 psize = PSIZE(p.prefixlen);
6019
6020 /* When packet overflow occur return immediately. */
6021 if (pnt + psize > lim) {
6022 flog_err(
6023 EC_BGP_UPDATE_RCV,
6024 "%s [Error] Update packet error (prefix length %d overflows packet)",
6025 peer->host, p.prefixlen);
6026 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6027 }
6028
6029 /* Defensive coding, double-check the psize fits in a struct
6030 * prefix for the v4 and v6 afi's and unicast/multicast */
6031 if (psize > (ssize_t)sizeof(p.u.val)) {
6032 flog_err(
6033 EC_BGP_UPDATE_RCV,
6034 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6035 peer->host, p.prefixlen, sizeof(p.u.val));
6036 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6037 }
6038
6039 /* Fetch prefix from NLRI packet. */
6040 memcpy(p.u.val, pnt, psize);
6041
6042 /* Check address. */
6043 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6044 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6045 /* From RFC4271 Section 6.3:
6046 *
6047 * If a prefix in the NLRI field is semantically
6048 * incorrect
6049 * (e.g., an unexpected multicast IP address),
6050 * an error SHOULD
6051 * be logged locally, and the prefix SHOULD be
6052 * ignored.
6053 */
6054 flog_err(
6055 EC_BGP_UPDATE_RCV,
6056 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6057 peer->host, &p.u.prefix4);
6058 continue;
6059 }
6060 }
6061
6062 /* Check address. */
6063 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6064 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6065 flog_err(
6066 EC_BGP_UPDATE_RCV,
6067 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6068 peer->host, &p.u.prefix6);
6069
6070 continue;
6071 }
6072 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6073 flog_err(
6074 EC_BGP_UPDATE_RCV,
6075 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6076 peer->host, &p.u.prefix6);
6077
6078 continue;
6079 }
6080 }
6081
6082 /* Normal process. */
6083 if (attr)
6084 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6085 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6086 NULL, 0, 0, NULL);
6087 else
6088 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6089 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6090 NULL, 0, NULL);
6091
6092 /* Do not send BGP notification twice when maximum-prefix count
6093 * overflow. */
6094 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6095 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6096 }
6097
6098 /* Packet length consistency check. */
6099 if (pnt != lim) {
6100 flog_err(
6101 EC_BGP_UPDATE_RCV,
6102 "%s [Error] Update packet error (prefix length mismatch with total length)",
6103 peer->host);
6104 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6105 }
6106
6107 return BGP_NLRI_PARSE_OK;
6108 }
6109
6110 static struct bgp_static *bgp_static_new(void)
6111 {
6112 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6113 }
6114
6115 static void bgp_static_free(struct bgp_static *bgp_static)
6116 {
6117 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6118 route_map_counter_decrement(bgp_static->rmap.map);
6119
6120 if (bgp_static->prd_pretty)
6121 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6122 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6123 XFREE(MTYPE_BGP_STATIC, bgp_static);
6124 }
6125
6126 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6127 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6128 {
6129 struct bgp_dest *dest;
6130 struct bgp_path_info *pi;
6131 struct bgp_path_info *new;
6132 struct bgp_path_info rmap_path;
6133 struct attr attr;
6134 struct attr *attr_new;
6135 route_map_result_t ret;
6136 #ifdef ENABLE_BGP_VNC
6137 int vnc_implicit_withdraw = 0;
6138 #endif
6139
6140 assert(bgp_static);
6141
6142 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6143
6144 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6145
6146 attr.nexthop = bgp_static->igpnexthop;
6147 attr.med = bgp_static->igpmetric;
6148 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6149
6150 if (afi == AFI_IP)
6151 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6152
6153 if (bgp_static->igpmetric)
6154 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6155
6156 if (bgp_static->atomic)
6157 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6158
6159 /* Store label index, if required. */
6160 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6161 attr.label_index = bgp_static->label_index;
6162 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6163 }
6164
6165 /* Apply route-map. */
6166 if (bgp_static->rmap.name) {
6167 struct attr attr_tmp = attr;
6168
6169 memset(&rmap_path, 0, sizeof(rmap_path));
6170 rmap_path.peer = bgp->peer_self;
6171 rmap_path.attr = &attr_tmp;
6172
6173 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6174
6175 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6176
6177 bgp->peer_self->rmap_type = 0;
6178
6179 if (ret == RMAP_DENYMATCH) {
6180 /* Free uninterned attribute. */
6181 bgp_attr_flush(&attr_tmp);
6182
6183 /* Unintern original. */
6184 aspath_unintern(&attr.aspath);
6185 bgp_static_withdraw(bgp, p, afi, safi);
6186 bgp_dest_unlock_node(dest);
6187 return;
6188 }
6189
6190 if (bgp_in_graceful_shutdown(bgp))
6191 bgp_attr_add_gshut_community(&attr_tmp);
6192
6193 attr_new = bgp_attr_intern(&attr_tmp);
6194 } else {
6195
6196 if (bgp_in_graceful_shutdown(bgp))
6197 bgp_attr_add_gshut_community(&attr);
6198
6199 attr_new = bgp_attr_intern(&attr);
6200 }
6201
6202 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6203 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6204 && pi->sub_type == BGP_ROUTE_STATIC)
6205 break;
6206
6207 if (pi) {
6208 if (attrhash_cmp(pi->attr, attr_new)
6209 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6210 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6211 bgp_dest_unlock_node(dest);
6212 bgp_attr_unintern(&attr_new);
6213 aspath_unintern(&attr.aspath);
6214 return;
6215 } else {
6216 /* The attribute is changed. */
6217 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6218
6219 /* Rewrite BGP route information. */
6220 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6221 bgp_path_info_restore(dest, pi);
6222 else
6223 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6224 #ifdef ENABLE_BGP_VNC
6225 if ((afi == AFI_IP || afi == AFI_IP6)
6226 && (safi == SAFI_UNICAST)) {
6227 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6228 /*
6229 * Implicit withdraw case.
6230 * We have to do this before pi is
6231 * changed
6232 */
6233 ++vnc_implicit_withdraw;
6234 vnc_import_bgp_del_route(bgp, p, pi);
6235 vnc_import_bgp_exterior_del_route(
6236 bgp, p, pi);
6237 }
6238 }
6239 #endif
6240 bgp_attr_unintern(&pi->attr);
6241 pi->attr = attr_new;
6242 pi->uptime = monotime(NULL);
6243 #ifdef ENABLE_BGP_VNC
6244 if ((afi == AFI_IP || afi == AFI_IP6)
6245 && (safi == SAFI_UNICAST)) {
6246 if (vnc_implicit_withdraw) {
6247 vnc_import_bgp_add_route(bgp, p, pi);
6248 vnc_import_bgp_exterior_add_route(
6249 bgp, p, pi);
6250 }
6251 }
6252 #endif
6253
6254 /* Nexthop reachability check. */
6255 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6256 && (safi == SAFI_UNICAST
6257 || safi == SAFI_LABELED_UNICAST)) {
6258
6259 struct bgp *bgp_nexthop = bgp;
6260
6261 if (pi->extra && pi->extra->bgp_orig)
6262 bgp_nexthop = pi->extra->bgp_orig;
6263
6264 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6265 afi, safi, pi, NULL,
6266 0, p))
6267 bgp_path_info_set_flag(dest, pi,
6268 BGP_PATH_VALID);
6269 else {
6270 if (BGP_DEBUG(nht, NHT)) {
6271 char buf1[INET6_ADDRSTRLEN];
6272 inet_ntop(p->family,
6273 &p->u.prefix, buf1,
6274 sizeof(buf1));
6275 zlog_debug(
6276 "%s(%s): Route not in table, not advertising",
6277 __func__, buf1);
6278 }
6279 bgp_path_info_unset_flag(
6280 dest, pi, BGP_PATH_VALID);
6281 }
6282 } else {
6283 /* Delete the NHT structure if any, if we're
6284 * toggling between
6285 * enabling/disabling import check. We
6286 * deregister the route
6287 * from NHT to avoid overloading NHT and the
6288 * process interaction
6289 */
6290 bgp_unlink_nexthop(pi);
6291 bgp_path_info_set_flag(dest, pi,
6292 BGP_PATH_VALID);
6293 }
6294 /* Process change. */
6295 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6296 bgp_process(bgp, dest, afi, safi);
6297
6298 if (SAFI_UNICAST == safi
6299 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6300 || bgp->inst_type
6301 == BGP_INSTANCE_TYPE_DEFAULT)) {
6302 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6303 pi);
6304 }
6305
6306 bgp_dest_unlock_node(dest);
6307 aspath_unintern(&attr.aspath);
6308 return;
6309 }
6310 }
6311
6312 /* Make new BGP info. */
6313 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6314 attr_new, dest);
6315 /* Nexthop reachability check. */
6316 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6317 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6318 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6319 p))
6320 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6321 else {
6322 if (BGP_DEBUG(nht, NHT)) {
6323 char buf1[INET6_ADDRSTRLEN];
6324
6325 inet_ntop(p->family, &p->u.prefix, buf1,
6326 sizeof(buf1));
6327 zlog_debug(
6328 "%s(%s): Route not in table, not advertising",
6329 __func__, buf1);
6330 }
6331 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6332 }
6333 } else {
6334 /* Delete the NHT structure if any, if we're toggling between
6335 * enabling/disabling import check. We deregister the route
6336 * from NHT to avoid overloading NHT and the process interaction
6337 */
6338 bgp_unlink_nexthop(new);
6339
6340 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6341 }
6342
6343 /* Aggregate address increment. */
6344 bgp_aggregate_increment(bgp, p, new, afi, safi);
6345
6346 /* Register new BGP information. */
6347 bgp_path_info_add(dest, new);
6348
6349 /* route_node_get lock */
6350 bgp_dest_unlock_node(dest);
6351
6352 /* Process change. */
6353 bgp_process(bgp, dest, afi, safi);
6354
6355 if (SAFI_UNICAST == safi
6356 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6357 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6358 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6359 }
6360
6361 /* Unintern original. */
6362 aspath_unintern(&attr.aspath);
6363 }
6364
6365 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6366 safi_t safi)
6367 {
6368 struct bgp_dest *dest;
6369 struct bgp_path_info *pi;
6370
6371 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6372
6373 /* Check selected route and self inserted route. */
6374 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6375 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6376 && pi->sub_type == BGP_ROUTE_STATIC)
6377 break;
6378
6379 /* Withdraw static BGP route from routing table. */
6380 if (pi) {
6381 if (SAFI_UNICAST == safi
6382 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6383 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6384 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6385 }
6386 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6387 bgp_unlink_nexthop(pi);
6388 bgp_path_info_delete(dest, pi);
6389 bgp_process(bgp, dest, afi, safi);
6390 }
6391
6392 /* Unlock bgp_node_lookup. */
6393 bgp_dest_unlock_node(dest);
6394 }
6395
6396 /*
6397 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6398 */
6399 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6400 afi_t afi, safi_t safi,
6401 struct prefix_rd *prd)
6402 {
6403 struct bgp_dest *dest;
6404 struct bgp_path_info *pi;
6405
6406 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6407
6408 /* Check selected route and self inserted route. */
6409 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6410 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6411 && pi->sub_type == BGP_ROUTE_STATIC)
6412 break;
6413
6414 /* Withdraw static BGP route from routing table. */
6415 if (pi) {
6416 #ifdef ENABLE_BGP_VNC
6417 rfapiProcessWithdraw(
6418 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6419 1); /* Kill, since it is an administrative change */
6420 #endif
6421 if (SAFI_MPLS_VPN == safi
6422 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6423 vpn_leak_to_vrf_withdraw(pi);
6424 }
6425 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6426 bgp_path_info_delete(dest, pi);
6427 bgp_process(bgp, dest, afi, safi);
6428 }
6429
6430 /* Unlock bgp_node_lookup. */
6431 bgp_dest_unlock_node(dest);
6432 }
6433
6434 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6435 struct bgp_static *bgp_static, afi_t afi,
6436 safi_t safi)
6437 {
6438 struct bgp_dest *dest;
6439 struct bgp_path_info *new;
6440 struct attr *attr_new;
6441 struct attr attr = {0};
6442 struct bgp_path_info *pi;
6443 #ifdef ENABLE_BGP_VNC
6444 mpls_label_t label = 0;
6445 #endif
6446 uint32_t num_labels = 0;
6447
6448 assert(bgp_static);
6449
6450 if (bgp_static->label != MPLS_INVALID_LABEL)
6451 num_labels = 1;
6452 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6453 &bgp_static->prd);
6454
6455 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6456
6457 attr.nexthop = bgp_static->igpnexthop;
6458 attr.med = bgp_static->igpmetric;
6459 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6460
6461 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6462 || (safi == SAFI_ENCAP)) {
6463 if (afi == AFI_IP) {
6464 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6465 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6466 }
6467 }
6468 if (afi == AFI_L2VPN) {
6469 if (bgp_static->gatewayIp.family == AF_INET) {
6470 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6471 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6472 &bgp_static->gatewayIp.u.prefix4,
6473 IPV4_MAX_BYTELEN);
6474 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6475 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6476 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6477 &bgp_static->gatewayIp.u.prefix6,
6478 IPV6_MAX_BYTELEN);
6479 }
6480 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6481 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6482 struct bgp_encap_type_vxlan bet;
6483 memset(&bet, 0, sizeof(bet));
6484 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6485 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6486 }
6487 if (bgp_static->router_mac) {
6488 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6489 }
6490 }
6491 /* Apply route-map. */
6492 if (bgp_static->rmap.name) {
6493 struct attr attr_tmp = attr;
6494 struct bgp_path_info rmap_path;
6495 route_map_result_t ret;
6496
6497 rmap_path.peer = bgp->peer_self;
6498 rmap_path.attr = &attr_tmp;
6499
6500 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6501
6502 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6503
6504 bgp->peer_self->rmap_type = 0;
6505
6506 if (ret == RMAP_DENYMATCH) {
6507 /* Free uninterned attribute. */
6508 bgp_attr_flush(&attr_tmp);
6509
6510 /* Unintern original. */
6511 aspath_unintern(&attr.aspath);
6512 bgp_static_withdraw_safi(bgp, p, afi, safi,
6513 &bgp_static->prd);
6514 bgp_dest_unlock_node(dest);
6515 return;
6516 }
6517
6518 attr_new = bgp_attr_intern(&attr_tmp);
6519 } else {
6520 attr_new = bgp_attr_intern(&attr);
6521 }
6522
6523 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6524 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6525 && pi->sub_type == BGP_ROUTE_STATIC)
6526 break;
6527
6528 if (pi) {
6529 if (attrhash_cmp(pi->attr, attr_new)
6530 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6531 bgp_dest_unlock_node(dest);
6532 bgp_attr_unintern(&attr_new);
6533 aspath_unintern(&attr.aspath);
6534 return;
6535 } else {
6536 /* The attribute is changed. */
6537 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6538
6539 /* Rewrite BGP route information. */
6540 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6541 bgp_path_info_restore(dest, pi);
6542 else
6543 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6544 bgp_attr_unintern(&pi->attr);
6545 pi->attr = attr_new;
6546 pi->uptime = monotime(NULL);
6547 #ifdef ENABLE_BGP_VNC
6548 if (pi->extra)
6549 label = decode_label(&pi->extra->label[0]);
6550 #endif
6551
6552 /* Process change. */
6553 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6554 bgp_process(bgp, dest, afi, safi);
6555
6556 if (SAFI_MPLS_VPN == safi
6557 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6558 vpn_leak_to_vrf_update(bgp, pi,
6559 &bgp_static->prd);
6560 }
6561 #ifdef ENABLE_BGP_VNC
6562 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6563 pi->attr, afi, safi, pi->type,
6564 pi->sub_type, &label);
6565 #endif
6566 bgp_dest_unlock_node(dest);
6567 aspath_unintern(&attr.aspath);
6568 return;
6569 }
6570 }
6571
6572
6573 /* Make new BGP info. */
6574 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6575 attr_new, dest);
6576 SET_FLAG(new->flags, BGP_PATH_VALID);
6577 bgp_path_info_extra_get(new);
6578 if (num_labels) {
6579 new->extra->label[0] = bgp_static->label;
6580 new->extra->num_labels = num_labels;
6581 }
6582 #ifdef ENABLE_BGP_VNC
6583 label = decode_label(&bgp_static->label);
6584 #endif
6585
6586 /* Aggregate address increment. */
6587 bgp_aggregate_increment(bgp, p, new, afi, safi);
6588
6589 /* Register new BGP information. */
6590 bgp_path_info_add(dest, new);
6591 /* route_node_get lock */
6592 bgp_dest_unlock_node(dest);
6593
6594 /* Process change. */
6595 bgp_process(bgp, dest, afi, safi);
6596
6597 if (SAFI_MPLS_VPN == safi
6598 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6599 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6600 }
6601 #ifdef ENABLE_BGP_VNC
6602 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6603 safi, new->type, new->sub_type, &label);
6604 #endif
6605
6606 /* Unintern original. */
6607 aspath_unintern(&attr.aspath);
6608 }
6609
6610 /* Configure static BGP network. When user don't run zebra, static
6611 route should be installed as valid. */
6612 static int bgp_static_set(struct vty *vty, const char *negate,
6613 const char *ip_str, afi_t afi, safi_t safi,
6614 const char *rmap, int backdoor, uint32_t label_index)
6615 {
6616 VTY_DECLVAR_CONTEXT(bgp, bgp);
6617 int ret;
6618 struct prefix p;
6619 struct bgp_static *bgp_static;
6620 struct bgp_dest *dest;
6621 uint8_t need_update = 0;
6622
6623 /* Convert IP prefix string to struct prefix. */
6624 ret = str2prefix(ip_str, &p);
6625 if (!ret) {
6626 vty_out(vty, "%% Malformed prefix\n");
6627 return CMD_WARNING_CONFIG_FAILED;
6628 }
6629 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6630 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6631 return CMD_WARNING_CONFIG_FAILED;
6632 }
6633
6634 apply_mask(&p);
6635
6636 if (negate) {
6637
6638 /* Set BGP static route configuration. */
6639 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6640
6641 if (!dest) {
6642 vty_out(vty, "%% Can't find static route specified\n");
6643 return CMD_WARNING_CONFIG_FAILED;
6644 }
6645
6646 bgp_static = bgp_dest_get_bgp_static_info(dest);
6647
6648 if ((label_index != BGP_INVALID_LABEL_INDEX)
6649 && (label_index != bgp_static->label_index)) {
6650 vty_out(vty,
6651 "%% label-index doesn't match static route\n");
6652 bgp_dest_unlock_node(dest);
6653 return CMD_WARNING_CONFIG_FAILED;
6654 }
6655
6656 if ((rmap && bgp_static->rmap.name)
6657 && strcmp(rmap, bgp_static->rmap.name)) {
6658 vty_out(vty,
6659 "%% route-map name doesn't match static route\n");
6660 bgp_dest_unlock_node(dest);
6661 return CMD_WARNING_CONFIG_FAILED;
6662 }
6663
6664 /* Update BGP RIB. */
6665 if (!bgp_static->backdoor)
6666 bgp_static_withdraw(bgp, &p, afi, safi);
6667
6668 /* Clear configuration. */
6669 bgp_static_free(bgp_static);
6670 bgp_dest_set_bgp_static_info(dest, NULL);
6671 bgp_dest_unlock_node(dest);
6672 bgp_dest_unlock_node(dest);
6673 } else {
6674
6675 /* Set BGP static route configuration. */
6676 dest = bgp_node_get(bgp->route[afi][safi], &p);
6677 bgp_static = bgp_dest_get_bgp_static_info(dest);
6678 if (bgp_static) {
6679 /* Configuration change. */
6680 /* Label index cannot be changed. */
6681 if (bgp_static->label_index != label_index) {
6682 vty_out(vty, "%% cannot change label-index\n");
6683 bgp_dest_unlock_node(dest);
6684 return CMD_WARNING_CONFIG_FAILED;
6685 }
6686
6687 /* Check previous routes are installed into BGP. */
6688 if (bgp_static->valid
6689 && bgp_static->backdoor != backdoor)
6690 need_update = 1;
6691
6692 bgp_static->backdoor = backdoor;
6693
6694 if (rmap) {
6695 XFREE(MTYPE_ROUTE_MAP_NAME,
6696 bgp_static->rmap.name);
6697 route_map_counter_decrement(
6698 bgp_static->rmap.map);
6699 bgp_static->rmap.name =
6700 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6701 bgp_static->rmap.map =
6702 route_map_lookup_by_name(rmap);
6703 route_map_counter_increment(
6704 bgp_static->rmap.map);
6705 } else {
6706 XFREE(MTYPE_ROUTE_MAP_NAME,
6707 bgp_static->rmap.name);
6708 route_map_counter_decrement(
6709 bgp_static->rmap.map);
6710 bgp_static->rmap.map = NULL;
6711 bgp_static->valid = 0;
6712 }
6713 bgp_dest_unlock_node(dest);
6714 } else {
6715 /* New configuration. */
6716 bgp_static = bgp_static_new();
6717 bgp_static->backdoor = backdoor;
6718 bgp_static->valid = 0;
6719 bgp_static->igpmetric = 0;
6720 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6721 bgp_static->label_index = label_index;
6722
6723 if (rmap) {
6724 XFREE(MTYPE_ROUTE_MAP_NAME,
6725 bgp_static->rmap.name);
6726 route_map_counter_decrement(
6727 bgp_static->rmap.map);
6728 bgp_static->rmap.name =
6729 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6730 bgp_static->rmap.map =
6731 route_map_lookup_by_name(rmap);
6732 route_map_counter_increment(
6733 bgp_static->rmap.map);
6734 }
6735 bgp_dest_set_bgp_static_info(dest, bgp_static);
6736 }
6737
6738 bgp_static->valid = 1;
6739 if (need_update)
6740 bgp_static_withdraw(bgp, &p, afi, safi);
6741
6742 if (!bgp_static->backdoor)
6743 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6744 }
6745
6746 return CMD_SUCCESS;
6747 }
6748
6749 void bgp_static_add(struct bgp *bgp)
6750 {
6751 afi_t afi;
6752 safi_t safi;
6753 struct bgp_dest *dest;
6754 struct bgp_dest *rm;
6755 struct bgp_table *table;
6756 struct bgp_static *bgp_static;
6757
6758 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6759 FOREACH_AFI_SAFI (afi, safi)
6760 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6761 dest = bgp_route_next(dest)) {
6762 if (!bgp_dest_has_bgp_path_info_data(dest))
6763 continue;
6764
6765 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6766 || (safi == SAFI_EVPN)) {
6767 table = bgp_dest_get_bgp_table_info(dest);
6768
6769 for (rm = bgp_table_top(table); rm;
6770 rm = bgp_route_next(rm)) {
6771 bgp_static =
6772 bgp_dest_get_bgp_static_info(
6773 rm);
6774 bgp_static_update_safi(
6775 bgp, bgp_dest_get_prefix(rm),
6776 bgp_static, afi, safi);
6777 }
6778 } else {
6779 bgp_static_update(
6780 bgp, bgp_dest_get_prefix(dest),
6781 bgp_dest_get_bgp_static_info(dest), afi,
6782 safi);
6783 }
6784 }
6785 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6786 }
6787
6788 /* Called from bgp_delete(). Delete all static routes from the BGP
6789 instance. */
6790 void bgp_static_delete(struct bgp *bgp)
6791 {
6792 afi_t afi;
6793 safi_t safi;
6794 struct bgp_dest *dest;
6795 struct bgp_dest *rm;
6796 struct bgp_table *table;
6797 struct bgp_static *bgp_static;
6798
6799 FOREACH_AFI_SAFI (afi, safi)
6800 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6801 dest = bgp_route_next(dest)) {
6802 if (!bgp_dest_has_bgp_path_info_data(dest))
6803 continue;
6804
6805 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6806 || (safi == SAFI_EVPN)) {
6807 table = bgp_dest_get_bgp_table_info(dest);
6808
6809 for (rm = bgp_table_top(table); rm;
6810 rm = bgp_route_next(rm)) {
6811 bgp_static =
6812 bgp_dest_get_bgp_static_info(
6813 rm);
6814 if (!bgp_static)
6815 continue;
6816
6817 bgp_static_withdraw_safi(
6818 bgp, bgp_dest_get_prefix(rm),
6819 AFI_IP, safi,
6820 (struct prefix_rd *)
6821 bgp_dest_get_prefix(
6822 dest));
6823 bgp_static_free(bgp_static);
6824 bgp_dest_set_bgp_static_info(rm,
6825 NULL);
6826 bgp_dest_unlock_node(rm);
6827 }
6828 } else {
6829 bgp_static = bgp_dest_get_bgp_static_info(dest);
6830 bgp_static_withdraw(bgp,
6831 bgp_dest_get_prefix(dest),
6832 afi, safi);
6833 bgp_static_free(bgp_static);
6834 bgp_dest_set_bgp_static_info(dest, NULL);
6835 bgp_dest_unlock_node(dest);
6836 }
6837 }
6838 }
6839
6840 void bgp_static_redo_import_check(struct bgp *bgp)
6841 {
6842 afi_t afi;
6843 safi_t safi;
6844 struct bgp_dest *dest;
6845 struct bgp_dest *rm;
6846 struct bgp_table *table;
6847 struct bgp_static *bgp_static;
6848
6849 /* Use this flag to force reprocessing of the route */
6850 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6851 FOREACH_AFI_SAFI (afi, safi) {
6852 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6853 dest = bgp_route_next(dest)) {
6854 if (!bgp_dest_has_bgp_path_info_data(dest))
6855 continue;
6856
6857 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6858 || (safi == SAFI_EVPN)) {
6859 table = bgp_dest_get_bgp_table_info(dest);
6860
6861 for (rm = bgp_table_top(table); rm;
6862 rm = bgp_route_next(rm)) {
6863 bgp_static =
6864 bgp_dest_get_bgp_static_info(
6865 rm);
6866 bgp_static_update_safi(
6867 bgp, bgp_dest_get_prefix(rm),
6868 bgp_static, afi, safi);
6869 }
6870 } else {
6871 bgp_static = bgp_dest_get_bgp_static_info(dest);
6872 bgp_static_update(bgp,
6873 bgp_dest_get_prefix(dest),
6874 bgp_static, afi, safi);
6875 }
6876 }
6877 }
6878 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6879 }
6880
6881 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6882 safi_t safi)
6883 {
6884 struct bgp_table *table;
6885 struct bgp_dest *dest;
6886 struct bgp_path_info *pi;
6887
6888 /* Do not install the aggregate route if BGP is in the
6889 * process of termination.
6890 */
6891 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6892 || (bgp->peer_self == NULL))
6893 return;
6894
6895 table = bgp->rib[afi][safi];
6896 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6897 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6898 if (pi->peer == bgp->peer_self
6899 && ((pi->type == ZEBRA_ROUTE_BGP
6900 && pi->sub_type == BGP_ROUTE_STATIC)
6901 || (pi->type != ZEBRA_ROUTE_BGP
6902 && pi->sub_type
6903 == BGP_ROUTE_REDISTRIBUTE))) {
6904 bgp_aggregate_decrement(
6905 bgp, bgp_dest_get_prefix(dest), pi, afi,
6906 safi);
6907 bgp_unlink_nexthop(pi);
6908 bgp_path_info_delete(dest, pi);
6909 bgp_process(bgp, dest, afi, safi);
6910 }
6911 }
6912 }
6913 }
6914
6915 /*
6916 * Purge all networks and redistributed routes from routing table.
6917 * Invoked upon the instance going down.
6918 */
6919 void bgp_purge_static_redist_routes(struct bgp *bgp)
6920 {
6921 afi_t afi;
6922 safi_t safi;
6923
6924 FOREACH_AFI_SAFI (afi, safi)
6925 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6926 }
6927
6928 /*
6929 * gpz 110624
6930 * Currently this is used to set static routes for VPN and ENCAP.
6931 * I think it can probably be factored with bgp_static_set.
6932 */
6933 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6934 const char *ip_str, const char *rd_str,
6935 const char *label_str, const char *rmap_str,
6936 int evpn_type, const char *esi, const char *gwip,
6937 const char *ethtag, const char *routermac)
6938 {
6939 VTY_DECLVAR_CONTEXT(bgp, bgp);
6940 int ret;
6941 struct prefix p;
6942 struct prefix_rd prd;
6943 struct bgp_dest *pdest;
6944 struct bgp_dest *dest;
6945 struct bgp_table *table;
6946 struct bgp_static *bgp_static;
6947 mpls_label_t label = MPLS_INVALID_LABEL;
6948 struct prefix gw_ip;
6949
6950 /* validate ip prefix */
6951 ret = str2prefix(ip_str, &p);
6952 if (!ret) {
6953 vty_out(vty, "%% Malformed prefix\n");
6954 return CMD_WARNING_CONFIG_FAILED;
6955 }
6956 apply_mask(&p);
6957 if ((afi == AFI_L2VPN)
6958 && (bgp_build_evpn_prefix(evpn_type,
6959 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6960 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6961 return CMD_WARNING_CONFIG_FAILED;
6962 }
6963
6964 ret = str2prefix_rd(rd_str, &prd);
6965 if (!ret) {
6966 vty_out(vty, "%% Malformed rd\n");
6967 return CMD_WARNING_CONFIG_FAILED;
6968 }
6969
6970 if (label_str) {
6971 unsigned long label_val;
6972 label_val = strtoul(label_str, NULL, 10);
6973 encode_label(label_val, &label);
6974 }
6975
6976 if (safi == SAFI_EVPN) {
6977 if (esi && str2esi(esi, NULL) == 0) {
6978 vty_out(vty, "%% Malformed ESI\n");
6979 return CMD_WARNING_CONFIG_FAILED;
6980 }
6981 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6982 vty_out(vty, "%% Malformed Router MAC\n");
6983 return CMD_WARNING_CONFIG_FAILED;
6984 }
6985 if (gwip) {
6986 memset(&gw_ip, 0, sizeof(gw_ip));
6987 ret = str2prefix(gwip, &gw_ip);
6988 if (!ret) {
6989 vty_out(vty, "%% Malformed GatewayIp\n");
6990 return CMD_WARNING_CONFIG_FAILED;
6991 }
6992 if ((gw_ip.family == AF_INET
6993 && is_evpn_prefix_ipaddr_v6(
6994 (struct prefix_evpn *)&p))
6995 || (gw_ip.family == AF_INET6
6996 && is_evpn_prefix_ipaddr_v4(
6997 (struct prefix_evpn *)&p))) {
6998 vty_out(vty,
6999 "%% GatewayIp family differs with IP prefix\n");
7000 return CMD_WARNING_CONFIG_FAILED;
7001 }
7002 }
7003 }
7004 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7005 if (!bgp_dest_has_bgp_path_info_data(pdest))
7006 bgp_dest_set_bgp_table_info(pdest,
7007 bgp_table_init(bgp, afi, safi));
7008 table = bgp_dest_get_bgp_table_info(pdest);
7009
7010 dest = bgp_node_get(table, &p);
7011
7012 if (bgp_dest_has_bgp_path_info_data(dest)) {
7013 vty_out(vty, "%% Same network configuration exists\n");
7014 bgp_dest_unlock_node(dest);
7015 } else {
7016 /* New configuration. */
7017 bgp_static = bgp_static_new();
7018 bgp_static->backdoor = 0;
7019 bgp_static->valid = 0;
7020 bgp_static->igpmetric = 0;
7021 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7022 bgp_static->label = label;
7023 bgp_static->prd = prd;
7024
7025 if (rd_str)
7026 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
7027 if (rmap_str) {
7028 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7029 route_map_counter_decrement(bgp_static->rmap.map);
7030 bgp_static->rmap.name =
7031 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7032 bgp_static->rmap.map =
7033 route_map_lookup_by_name(rmap_str);
7034 route_map_counter_increment(bgp_static->rmap.map);
7035 }
7036
7037 if (safi == SAFI_EVPN) {
7038 if (esi) {
7039 bgp_static->eth_s_id =
7040 XCALLOC(MTYPE_ATTR,
7041 sizeof(esi_t));
7042 str2esi(esi, bgp_static->eth_s_id);
7043 }
7044 if (routermac) {
7045 bgp_static->router_mac =
7046 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7047 (void)prefix_str2mac(routermac,
7048 bgp_static->router_mac);
7049 }
7050 if (gwip)
7051 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7052 }
7053 bgp_dest_set_bgp_static_info(dest, bgp_static);
7054
7055 bgp_static->valid = 1;
7056 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7057 }
7058
7059 return CMD_SUCCESS;
7060 }
7061
7062 /* Configure static BGP network. */
7063 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7064 const char *ip_str, const char *rd_str,
7065 const char *label_str, int evpn_type, const char *esi,
7066 const char *gwip, const char *ethtag)
7067 {
7068 VTY_DECLVAR_CONTEXT(bgp, bgp);
7069 int ret;
7070 struct prefix p;
7071 struct prefix_rd prd;
7072 struct bgp_dest *pdest;
7073 struct bgp_dest *dest;
7074 struct bgp_table *table;
7075 struct bgp_static *bgp_static;
7076 mpls_label_t label = MPLS_INVALID_LABEL;
7077
7078 /* Convert IP prefix string to struct prefix. */
7079 ret = str2prefix(ip_str, &p);
7080 if (!ret) {
7081 vty_out(vty, "%% Malformed prefix\n");
7082 return CMD_WARNING_CONFIG_FAILED;
7083 }
7084 apply_mask(&p);
7085 if ((afi == AFI_L2VPN)
7086 && (bgp_build_evpn_prefix(evpn_type,
7087 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7088 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7089 return CMD_WARNING_CONFIG_FAILED;
7090 }
7091 ret = str2prefix_rd(rd_str, &prd);
7092 if (!ret) {
7093 vty_out(vty, "%% Malformed rd\n");
7094 return CMD_WARNING_CONFIG_FAILED;
7095 }
7096
7097 if (label_str) {
7098 unsigned long label_val;
7099 label_val = strtoul(label_str, NULL, 10);
7100 encode_label(label_val, &label);
7101 }
7102
7103 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7104 if (!bgp_dest_has_bgp_path_info_data(pdest))
7105 bgp_dest_set_bgp_table_info(pdest,
7106 bgp_table_init(bgp, afi, safi));
7107 else
7108 bgp_dest_unlock_node(pdest);
7109 table = bgp_dest_get_bgp_table_info(pdest);
7110
7111 dest = bgp_node_lookup(table, &p);
7112
7113 if (dest) {
7114 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7115
7116 bgp_static = bgp_dest_get_bgp_static_info(dest);
7117 bgp_static_free(bgp_static);
7118 bgp_dest_set_bgp_static_info(dest, NULL);
7119 bgp_dest_unlock_node(dest);
7120 bgp_dest_unlock_node(dest);
7121 } else
7122 vty_out(vty, "%% Can't find the route\n");
7123
7124 return CMD_SUCCESS;
7125 }
7126
7127 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7128 const char *rmap_name)
7129 {
7130 VTY_DECLVAR_CONTEXT(bgp, bgp);
7131 struct bgp_rmap *rmap;
7132
7133 rmap = &bgp->table_map[afi][safi];
7134 if (rmap_name) {
7135 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7136 route_map_counter_decrement(rmap->map);
7137 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7138 rmap->map = route_map_lookup_by_name(rmap_name);
7139 route_map_counter_increment(rmap->map);
7140 } else {
7141 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7142 route_map_counter_decrement(rmap->map);
7143 rmap->map = NULL;
7144 }
7145
7146 if (bgp_fibupd_safi(safi))
7147 bgp_zebra_announce_table(bgp, afi, safi);
7148
7149 return CMD_SUCCESS;
7150 }
7151
7152 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7153 const char *rmap_name)
7154 {
7155 VTY_DECLVAR_CONTEXT(bgp, bgp);
7156 struct bgp_rmap *rmap;
7157
7158 rmap = &bgp->table_map[afi][safi];
7159 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7160 route_map_counter_decrement(rmap->map);
7161 rmap->map = NULL;
7162
7163 if (bgp_fibupd_safi(safi))
7164 bgp_zebra_announce_table(bgp, afi, safi);
7165
7166 return CMD_SUCCESS;
7167 }
7168
7169 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7170 safi_t safi)
7171 {
7172 if (bgp->table_map[afi][safi].name) {
7173 vty_out(vty, " table-map %s\n",
7174 bgp->table_map[afi][safi].name);
7175 }
7176 }
7177
7178 DEFUN (bgp_table_map,
7179 bgp_table_map_cmd,
7180 "table-map WORD",
7181 "BGP table to RIB route download filter\n"
7182 "Name of the route map\n")
7183 {
7184 int idx_word = 1;
7185 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7186 argv[idx_word]->arg);
7187 }
7188 DEFUN (no_bgp_table_map,
7189 no_bgp_table_map_cmd,
7190 "no table-map WORD",
7191 NO_STR
7192 "BGP table to RIB route download filter\n"
7193 "Name of the route map\n")
7194 {
7195 int idx_word = 2;
7196 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7197 argv[idx_word]->arg);
7198 }
7199
7200 DEFPY(bgp_network,
7201 bgp_network_cmd,
7202 "[no] network \
7203 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7204 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7205 backdoor$backdoor}]",
7206 NO_STR
7207 "Specify a network to announce via BGP\n"
7208 "IPv4 prefix\n"
7209 "Network number\n"
7210 "Network mask\n"
7211 "Network mask\n"
7212 "Route-map to modify the attributes\n"
7213 "Name of the route map\n"
7214 "Label index to associate with the prefix\n"
7215 "Label index value\n"
7216 "Specify a BGP backdoor route\n")
7217 {
7218 char addr_prefix_str[BUFSIZ];
7219
7220 if (address_str) {
7221 int ret;
7222
7223 ret = netmask_str2prefix_str(address_str, netmask_str,
7224 addr_prefix_str,
7225 sizeof(addr_prefix_str));
7226 if (!ret) {
7227 vty_out(vty, "%% Inconsistent address and mask\n");
7228 return CMD_WARNING_CONFIG_FAILED;
7229 }
7230 }
7231
7232 return bgp_static_set(
7233 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7234 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7235 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7236 }
7237
7238 DEFPY(ipv6_bgp_network,
7239 ipv6_bgp_network_cmd,
7240 "[no] network X:X::X:X/M$prefix \
7241 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7242 NO_STR
7243 "Specify a network to announce via BGP\n"
7244 "IPv6 prefix\n"
7245 "Route-map to modify the attributes\n"
7246 "Name of the route map\n"
7247 "Label index to associate with the prefix\n"
7248 "Label index value\n")
7249 {
7250 return bgp_static_set(
7251 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7252 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7253 }
7254
7255 static struct bgp_aggregate *bgp_aggregate_new(void)
7256 {
7257 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7258 }
7259
7260 void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7261 {
7262 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7263 route_map_counter_decrement(aggregate->suppress_map);
7264 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7265 route_map_counter_decrement(aggregate->rmap.map);
7266 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7267 }
7268
7269 /**
7270 * Helper function to avoid repeated code: prepare variables for a
7271 * `route_map_apply` call.
7272 *
7273 * \returns `true` on route map match, otherwise `false`.
7274 */
7275 static bool aggr_suppress_map_test(struct bgp *bgp,
7276 struct bgp_aggregate *aggregate,
7277 struct bgp_path_info *pi)
7278 {
7279 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7280 route_map_result_t rmr = RMAP_DENYMATCH;
7281 struct bgp_path_info rmap_path = {};
7282 struct attr attr = {};
7283
7284 /* No route map entries created, just don't match. */
7285 if (aggregate->suppress_map == NULL)
7286 return false;
7287
7288 /* Call route map matching and return result. */
7289 attr.aspath = aspath_empty(bgp->asnotation);
7290 rmap_path.peer = bgp->peer_self;
7291 rmap_path.attr = &attr;
7292
7293 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7294 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7295 bgp->peer_self->rmap_type = 0;
7296
7297 bgp_attr_flush(&attr);
7298 aspath_unintern(&attr.aspath);
7299
7300 return rmr == RMAP_PERMITMATCH;
7301 }
7302
7303 /** Test whether the aggregation has suppressed this path or not. */
7304 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7305 struct bgp_path_info *pi)
7306 {
7307 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7308 return false;
7309
7310 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7311 }
7312
7313 /**
7314 * Suppress this path and keep the reference.
7315 *
7316 * \returns `true` if needs processing otherwise `false`.
7317 */
7318 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7319 struct bgp_path_info *pi)
7320 {
7321 struct bgp_path_info_extra *pie;
7322
7323 /* Path is already suppressed by this aggregation. */
7324 if (aggr_suppress_exists(aggregate, pi))
7325 return false;
7326
7327 pie = bgp_path_info_extra_get(pi);
7328
7329 /* This is the first suppression, allocate memory and list it. */
7330 if (pie->aggr_suppressors == NULL)
7331 pie->aggr_suppressors = list_new();
7332
7333 listnode_add(pie->aggr_suppressors, aggregate);
7334
7335 /* Only mark for processing if suppressed. */
7336 if (listcount(pie->aggr_suppressors) == 1) {
7337 if (BGP_DEBUG(update, UPDATE_OUT))
7338 zlog_debug("aggregate-address suppressing: %pFX",
7339 bgp_dest_get_prefix(pi->net));
7340
7341 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7342 return true;
7343 }
7344
7345 return false;
7346 }
7347
7348 /**
7349 * Unsuppress this path and remove the reference.
7350 *
7351 * \returns `true` if needs processing otherwise `false`.
7352 */
7353 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7354 struct bgp_path_info *pi)
7355 {
7356 /* Path wasn't suppressed. */
7357 if (!aggr_suppress_exists(aggregate, pi))
7358 return false;
7359
7360 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7361
7362 /* Unsuppress and free extra memory if last item. */
7363 if (listcount(pi->extra->aggr_suppressors) == 0) {
7364 if (BGP_DEBUG(update, UPDATE_OUT))
7365 zlog_debug("aggregate-address unsuppressing: %pFX",
7366 bgp_dest_get_prefix(pi->net));
7367
7368 list_delete(&pi->extra->aggr_suppressors);
7369 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7370 return true;
7371 }
7372
7373 return false;
7374 }
7375
7376 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7377 struct aspath *aspath,
7378 struct community *comm,
7379 struct ecommunity *ecomm,
7380 struct lcommunity *lcomm)
7381 {
7382 static struct aspath *ae = NULL;
7383 enum asnotation_mode asnotation;
7384
7385 asnotation = bgp_get_asnotation(NULL);
7386
7387 if (!ae)
7388 ae = aspath_empty(asnotation);
7389
7390 if (!pi)
7391 return false;
7392
7393 if (origin != pi->attr->origin)
7394 return false;
7395
7396 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7397 return false;
7398
7399 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7400 return false;
7401
7402 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7403 return false;
7404
7405 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7406 return false;
7407
7408 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7409 return false;
7410
7411 return true;
7412 }
7413
7414 static void bgp_aggregate_install(
7415 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7416 uint8_t origin, struct aspath *aspath, struct community *community,
7417 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7418 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7419 {
7420 struct bgp_dest *dest;
7421 struct bgp_table *table;
7422 struct bgp_path_info *pi, *orig, *new;
7423 struct attr *attr;
7424
7425 table = bgp->rib[afi][safi];
7426
7427 dest = bgp_node_get(table, p);
7428
7429 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7430 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7431 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7432 break;
7433
7434 /*
7435 * If we have paths with different MEDs, then don't install
7436 * (or uninstall) the aggregate route.
7437 */
7438 if (aggregate->match_med && aggregate->med_mismatched)
7439 goto uninstall_aggregate_route;
7440
7441 if (aggregate->count > 0) {
7442 /*
7443 * If the aggregate information has not changed
7444 * no need to re-install it again.
7445 */
7446 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7447 ecommunity, lcommunity)) {
7448 bgp_dest_unlock_node(dest);
7449
7450 if (aspath)
7451 aspath_free(aspath);
7452 if (community)
7453 community_free(&community);
7454 if (ecommunity)
7455 ecommunity_free(&ecommunity);
7456 if (lcommunity)
7457 lcommunity_free(&lcommunity);
7458
7459 return;
7460 }
7461
7462 /*
7463 * Mark the old as unusable
7464 */
7465 if (pi)
7466 bgp_path_info_delete(dest, pi);
7467
7468 attr = bgp_attr_aggregate_intern(
7469 bgp, origin, aspath, community, ecommunity, lcommunity,
7470 aggregate, atomic_aggregate, p);
7471
7472 if (!attr) {
7473 aspath_free(aspath);
7474 community_free(&community);
7475 ecommunity_free(&ecommunity);
7476 lcommunity_free(&lcommunity);
7477 bgp_dest_unlock_node(dest);
7478 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7479 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7480 zlog_debug("%s: %pFX null attribute", __func__,
7481 p);
7482 return;
7483 }
7484
7485 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7486 bgp->peer_self, attr, dest);
7487
7488 SET_FLAG(new->flags, BGP_PATH_VALID);
7489
7490 bgp_path_info_add(dest, new);
7491 bgp_process(bgp, dest, afi, safi);
7492 } else {
7493 uninstall_aggregate_route:
7494 for (pi = orig; pi; pi = pi->next)
7495 if (pi->peer == bgp->peer_self
7496 && pi->type == ZEBRA_ROUTE_BGP
7497 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7498 break;
7499
7500 /* Withdraw static BGP route from routing table. */
7501 if (pi) {
7502 bgp_path_info_delete(dest, pi);
7503 bgp_process(bgp, dest, afi, safi);
7504 }
7505 }
7506
7507 bgp_dest_unlock_node(dest);
7508 }
7509
7510 /**
7511 * Check if the current path has different MED than other known paths.
7512 *
7513 * \returns `true` if the MED matched the others else `false`.
7514 */
7515 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7516 struct bgp *bgp, struct bgp_path_info *pi)
7517 {
7518 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7519
7520 /* This is the first route being analyzed. */
7521 if (!aggregate->med_initialized) {
7522 aggregate->med_initialized = true;
7523 aggregate->med_mismatched = false;
7524 aggregate->med_matched_value = cur_med;
7525 } else {
7526 /* Check if routes with different MED showed up. */
7527 if (cur_med != aggregate->med_matched_value)
7528 aggregate->med_mismatched = true;
7529 }
7530
7531 return !aggregate->med_mismatched;
7532 }
7533
7534 /**
7535 * Initializes and tests all routes in the aggregate address path for MED
7536 * values.
7537 *
7538 * \returns `true` if all MEDs are the same otherwise `false`.
7539 */
7540 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7541 struct bgp *bgp, const struct prefix *p,
7542 afi_t afi, safi_t safi)
7543 {
7544 struct bgp_table *table = bgp->rib[afi][safi];
7545 const struct prefix *dest_p;
7546 struct bgp_dest *dest, *top;
7547 struct bgp_path_info *pi;
7548 bool med_matched = true;
7549
7550 aggregate->med_initialized = false;
7551
7552 top = bgp_node_get(table, p);
7553 for (dest = bgp_node_get(table, p); dest;
7554 dest = bgp_route_next_until(dest, top)) {
7555 dest_p = bgp_dest_get_prefix(dest);
7556 if (dest_p->prefixlen <= p->prefixlen)
7557 continue;
7558
7559 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7560 if (BGP_PATH_HOLDDOWN(pi))
7561 continue;
7562 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7563 continue;
7564 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7565 med_matched = false;
7566 break;
7567 }
7568 }
7569 if (!med_matched)
7570 break;
7571 }
7572 bgp_dest_unlock_node(top);
7573
7574 return med_matched;
7575 }
7576
7577 /**
7578 * Toggles the route suppression status for this aggregate address
7579 * configuration.
7580 */
7581 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7582 struct bgp *bgp, const struct prefix *p,
7583 afi_t afi, safi_t safi, bool suppress)
7584 {
7585 struct bgp_table *table = bgp->rib[afi][safi];
7586 const struct prefix *dest_p;
7587 struct bgp_dest *dest, *top;
7588 struct bgp_path_info *pi;
7589 bool toggle_suppression;
7590
7591 /* We've found a different MED we must revert any suppressed routes. */
7592 top = bgp_node_get(table, p);
7593 for (dest = bgp_node_get(table, p); dest;
7594 dest = bgp_route_next_until(dest, top)) {
7595 dest_p = bgp_dest_get_prefix(dest);
7596 if (dest_p->prefixlen <= p->prefixlen)
7597 continue;
7598
7599 toggle_suppression = false;
7600 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7601 if (BGP_PATH_HOLDDOWN(pi))
7602 continue;
7603 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7604 continue;
7605
7606 /* We are toggling suppression back. */
7607 if (suppress) {
7608 /* Suppress route if not suppressed already. */
7609 if (aggr_suppress_path(aggregate, pi))
7610 toggle_suppression = true;
7611 continue;
7612 }
7613
7614 /* Install route if there is no more suppression. */
7615 if (aggr_unsuppress_path(aggregate, pi))
7616 toggle_suppression = true;
7617 }
7618
7619 if (toggle_suppression)
7620 bgp_process(bgp, dest, afi, safi);
7621 }
7622 bgp_dest_unlock_node(top);
7623 }
7624
7625 /**
7626 * Aggregate address MED matching incremental test: this function is called
7627 * when the initial aggregation occurred and we are only testing a single
7628 * new path.
7629 *
7630 * In addition to testing and setting the MED validity it also installs back
7631 * suppressed routes (if summary is configured).
7632 *
7633 * Must not be called in `bgp_aggregate_route`.
7634 */
7635 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7636 struct bgp *bgp, const struct prefix *p,
7637 afi_t afi, safi_t safi,
7638 struct bgp_path_info *pi)
7639 {
7640 /* MED matching disabled. */
7641 if (!aggregate->match_med)
7642 return;
7643
7644 /* Aggregation with different MED, recheck if we have got equal MEDs
7645 * now.
7646 */
7647 if (aggregate->med_mismatched &&
7648 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7649 aggregate->summary_only)
7650 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7651 true);
7652 else
7653 bgp_aggregate_med_match(aggregate, bgp, pi);
7654
7655 /* No mismatches, just quit. */
7656 if (!aggregate->med_mismatched)
7657 return;
7658
7659 /* Route summarization is disabled. */
7660 if (!aggregate->summary_only)
7661 return;
7662
7663 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7664 }
7665
7666 /* Update an aggregate as routes are added/removed from the BGP table */
7667 bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7668 safi_t safi, struct bgp_aggregate *aggregate)
7669 {
7670 struct bgp_table *table;
7671 struct bgp_dest *top;
7672 struct bgp_dest *dest;
7673 uint8_t origin;
7674 struct aspath *aspath = NULL;
7675 struct community *community = NULL;
7676 struct ecommunity *ecommunity = NULL;
7677 struct lcommunity *lcommunity = NULL;
7678 struct bgp_path_info *pi;
7679 unsigned long match = 0;
7680 uint8_t atomic_aggregate = 0;
7681
7682 /* If the bgp instance is being deleted or self peer is deleted
7683 * then do not create aggregate route
7684 */
7685 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
7686 bgp->peer_self == NULL)
7687 return false;
7688
7689 /* Initialize and test routes for MED difference. */
7690 if (aggregate->match_med)
7691 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7692
7693 /*
7694 * Reset aggregate count: we might've been called from route map
7695 * update so in that case we must retest all more specific routes.
7696 *
7697 * \see `bgp_route_map_process_update`.
7698 */
7699 aggregate->count = 0;
7700 aggregate->incomplete_origin_count = 0;
7701 aggregate->incomplete_origin_count = 0;
7702 aggregate->egp_origin_count = 0;
7703
7704 /* ORIGIN attribute: If at least one route among routes that are
7705 aggregated has ORIGIN with the value INCOMPLETE, then the
7706 aggregated route must have the ORIGIN attribute with the value
7707 INCOMPLETE. Otherwise, if at least one route among routes that
7708 are aggregated has ORIGIN with the value EGP, then the aggregated
7709 route must have the origin attribute with the value EGP. In all
7710 other case the value of the ORIGIN attribute of the aggregated
7711 route is INTERNAL. */
7712 origin = BGP_ORIGIN_IGP;
7713
7714 table = bgp->rib[afi][safi];
7715
7716 top = bgp_node_get(table, p);
7717 for (dest = bgp_node_get(table, p); dest;
7718 dest = bgp_route_next_until(dest, top)) {
7719 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7720
7721 if (dest_p->prefixlen <= p->prefixlen)
7722 continue;
7723
7724 /* If suppress fib is enabled and route not installed
7725 * in FIB, skip the route
7726 */
7727 if (!bgp_check_advertise(bgp, dest))
7728 continue;
7729
7730 match = 0;
7731
7732 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7733 if (BGP_PATH_HOLDDOWN(pi))
7734 continue;
7735
7736 if (pi->attr->flag
7737 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7738 atomic_aggregate = 1;
7739
7740 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7741 continue;
7742
7743 /*
7744 * summary-only aggregate route suppress
7745 * aggregated route announcements.
7746 *
7747 * MED matching:
7748 * Don't create summaries if MED didn't match
7749 * otherwise neither the specific routes and the
7750 * aggregation will be announced.
7751 */
7752 if (aggregate->summary_only
7753 && AGGREGATE_MED_VALID(aggregate)) {
7754 if (aggr_suppress_path(aggregate, pi))
7755 match++;
7756 }
7757
7758 /*
7759 * Suppress more specific routes that match the route
7760 * map results.
7761 *
7762 * MED matching:
7763 * Don't suppress routes if MED matching is enabled and
7764 * it mismatched otherwise we might end up with no
7765 * routes for this path.
7766 */
7767 if (aggregate->suppress_map_name
7768 && AGGREGATE_MED_VALID(aggregate)
7769 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7770 if (aggr_suppress_path(aggregate, pi))
7771 match++;
7772 }
7773
7774 aggregate->count++;
7775
7776 /*
7777 * If at least one route among routes that are
7778 * aggregated has ORIGIN with the value INCOMPLETE,
7779 * then the aggregated route MUST have the ORIGIN
7780 * attribute with the value INCOMPLETE. Otherwise, if
7781 * at least one route among routes that are aggregated
7782 * has ORIGIN with the value EGP, then the aggregated
7783 * route MUST have the ORIGIN attribute with the value
7784 * EGP.
7785 */
7786 switch (pi->attr->origin) {
7787 case BGP_ORIGIN_INCOMPLETE:
7788 aggregate->incomplete_origin_count++;
7789 break;
7790 case BGP_ORIGIN_EGP:
7791 aggregate->egp_origin_count++;
7792 break;
7793 default:
7794 /*Do nothing.
7795 */
7796 break;
7797 }
7798
7799 if (!aggregate->as_set)
7800 continue;
7801
7802 /*
7803 * as-set aggregate route generate origin, as path,
7804 * and community aggregation.
7805 */
7806 /* Compute aggregate route's as-path.
7807 */
7808 bgp_compute_aggregate_aspath_hash(aggregate,
7809 pi->attr->aspath);
7810
7811 /* Compute aggregate route's community.
7812 */
7813 if (bgp_attr_get_community(pi->attr))
7814 bgp_compute_aggregate_community_hash(
7815 aggregate,
7816 bgp_attr_get_community(pi->attr));
7817
7818 /* Compute aggregate route's extended community.
7819 */
7820 if (bgp_attr_get_ecommunity(pi->attr))
7821 bgp_compute_aggregate_ecommunity_hash(
7822 aggregate,
7823 bgp_attr_get_ecommunity(pi->attr));
7824
7825 /* Compute aggregate route's large community.
7826 */
7827 if (bgp_attr_get_lcommunity(pi->attr))
7828 bgp_compute_aggregate_lcommunity_hash(
7829 aggregate,
7830 bgp_attr_get_lcommunity(pi->attr));
7831 }
7832 if (match)
7833 bgp_process(bgp, dest, afi, safi);
7834 }
7835 if (aggregate->as_set) {
7836 bgp_compute_aggregate_aspath_val(aggregate);
7837 bgp_compute_aggregate_community_val(aggregate);
7838 bgp_compute_aggregate_ecommunity_val(aggregate);
7839 bgp_compute_aggregate_lcommunity_val(aggregate);
7840 }
7841
7842
7843 bgp_dest_unlock_node(top);
7844
7845
7846 if (aggregate->incomplete_origin_count > 0)
7847 origin = BGP_ORIGIN_INCOMPLETE;
7848 else if (aggregate->egp_origin_count > 0)
7849 origin = BGP_ORIGIN_EGP;
7850
7851 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7852 origin = aggregate->origin;
7853
7854 if (aggregate->as_set) {
7855 if (aggregate->aspath)
7856 /* Retrieve aggregate route's as-path.
7857 */
7858 aspath = aspath_dup(aggregate->aspath);
7859
7860 if (aggregate->community)
7861 /* Retrieve aggregate route's community.
7862 */
7863 community = community_dup(aggregate->community);
7864
7865 if (aggregate->ecommunity)
7866 /* Retrieve aggregate route's ecommunity.
7867 */
7868 ecommunity = ecommunity_dup(aggregate->ecommunity);
7869
7870 if (aggregate->lcommunity)
7871 /* Retrieve aggregate route's lcommunity.
7872 */
7873 lcommunity = lcommunity_dup(aggregate->lcommunity);
7874 }
7875
7876 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7877 ecommunity, lcommunity, atomic_aggregate,
7878 aggregate);
7879
7880 return true;
7881 }
7882
7883 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7884 safi_t safi, struct bgp_aggregate *aggregate)
7885 {
7886 struct bgp_table *table;
7887 struct bgp_dest *top;
7888 struct bgp_dest *dest;
7889 struct bgp_path_info *pi;
7890 unsigned long match;
7891
7892 table = bgp->rib[afi][safi];
7893
7894 /* If routes exists below this node, generate aggregate routes. */
7895 top = bgp_node_get(table, p);
7896 for (dest = bgp_node_get(table, p); dest;
7897 dest = bgp_route_next_until(dest, top)) {
7898 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7899
7900 if (dest_p->prefixlen <= p->prefixlen)
7901 continue;
7902 match = 0;
7903
7904 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7905 if (BGP_PATH_HOLDDOWN(pi))
7906 continue;
7907
7908 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7909 continue;
7910
7911 /*
7912 * This route is suppressed: attempt to unsuppress it.
7913 *
7914 * `aggr_unsuppress_path` will fail if this particular
7915 * aggregate route was not the suppressor.
7916 */
7917 if (pi->extra && pi->extra->aggr_suppressors &&
7918 listcount(pi->extra->aggr_suppressors)) {
7919 if (aggr_unsuppress_path(aggregate, pi))
7920 match++;
7921 }
7922
7923 aggregate->count--;
7924
7925 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7926 aggregate->incomplete_origin_count--;
7927 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7928 aggregate->egp_origin_count--;
7929
7930 if (aggregate->as_set) {
7931 /* Remove as-path from aggregate.
7932 */
7933 bgp_remove_aspath_from_aggregate_hash(
7934 aggregate,
7935 pi->attr->aspath);
7936
7937 if (bgp_attr_get_community(pi->attr))
7938 /* Remove community from aggregate.
7939 */
7940 bgp_remove_comm_from_aggregate_hash(
7941 aggregate,
7942 bgp_attr_get_community(
7943 pi->attr));
7944
7945 if (bgp_attr_get_ecommunity(pi->attr))
7946 /* Remove ecommunity from aggregate.
7947 */
7948 bgp_remove_ecomm_from_aggregate_hash(
7949 aggregate,
7950 bgp_attr_get_ecommunity(
7951 pi->attr));
7952
7953 if (bgp_attr_get_lcommunity(pi->attr))
7954 /* Remove lcommunity from aggregate.
7955 */
7956 bgp_remove_lcomm_from_aggregate_hash(
7957 aggregate,
7958 bgp_attr_get_lcommunity(
7959 pi->attr));
7960 }
7961 }
7962
7963 /* If this node was suppressed, process the change. */
7964 if (match)
7965 bgp_process(bgp, dest, afi, safi);
7966 }
7967 if (aggregate->as_set) {
7968 aspath_free(aggregate->aspath);
7969 aggregate->aspath = NULL;
7970 if (aggregate->community)
7971 community_free(&aggregate->community);
7972 if (aggregate->ecommunity)
7973 ecommunity_free(&aggregate->ecommunity);
7974 if (aggregate->lcommunity)
7975 lcommunity_free(&aggregate->lcommunity);
7976 }
7977
7978 bgp_dest_unlock_node(top);
7979 }
7980
7981 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7982 const struct prefix *aggr_p,
7983 struct bgp_path_info *pinew, afi_t afi,
7984 safi_t safi,
7985 struct bgp_aggregate *aggregate)
7986 {
7987 uint8_t origin;
7988 struct aspath *aspath = NULL;
7989 uint8_t atomic_aggregate = 0;
7990 struct community *community = NULL;
7991 struct ecommunity *ecommunity = NULL;
7992 struct lcommunity *lcommunity = NULL;
7993
7994 /* If the bgp instance is being deleted or self peer is deleted
7995 * then do not create aggregate route
7996 */
7997 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7998 || (bgp->peer_self == NULL))
7999 return;
8000
8001 /* ORIGIN attribute: If at least one route among routes that are
8002 * aggregated has ORIGIN with the value INCOMPLETE, then the
8003 * aggregated route must have the ORIGIN attribute with the value
8004 * INCOMPLETE. Otherwise, if at least one route among routes that
8005 * are aggregated has ORIGIN with the value EGP, then the aggregated
8006 * route must have the origin attribute with the value EGP. In all
8007 * other case the value of the ORIGIN attribute of the aggregated
8008 * route is INTERNAL.
8009 */
8010 origin = BGP_ORIGIN_IGP;
8011
8012 aggregate->count++;
8013
8014 /*
8015 * This must be called before `summary` check to avoid
8016 * "suppressing" twice.
8017 */
8018 if (aggregate->match_med)
8019 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8020 pinew);
8021
8022 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8023 aggr_suppress_path(aggregate, pinew);
8024
8025 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8026 && aggr_suppress_map_test(bgp, aggregate, pinew))
8027 aggr_suppress_path(aggregate, pinew);
8028
8029 switch (pinew->attr->origin) {
8030 case BGP_ORIGIN_INCOMPLETE:
8031 aggregate->incomplete_origin_count++;
8032 break;
8033 case BGP_ORIGIN_EGP:
8034 aggregate->egp_origin_count++;
8035 break;
8036 default:
8037 /* Do nothing.
8038 */
8039 break;
8040 }
8041
8042 if (aggregate->incomplete_origin_count > 0)
8043 origin = BGP_ORIGIN_INCOMPLETE;
8044 else if (aggregate->egp_origin_count > 0)
8045 origin = BGP_ORIGIN_EGP;
8046
8047 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8048 origin = aggregate->origin;
8049
8050 if (aggregate->as_set) {
8051 /* Compute aggregate route's as-path.
8052 */
8053 bgp_compute_aggregate_aspath(aggregate,
8054 pinew->attr->aspath);
8055
8056 /* Compute aggregate route's community.
8057 */
8058 if (bgp_attr_get_community(pinew->attr))
8059 bgp_compute_aggregate_community(
8060 aggregate, bgp_attr_get_community(pinew->attr));
8061
8062 /* Compute aggregate route's extended community.
8063 */
8064 if (bgp_attr_get_ecommunity(pinew->attr))
8065 bgp_compute_aggregate_ecommunity(
8066 aggregate,
8067 bgp_attr_get_ecommunity(pinew->attr));
8068
8069 /* Compute aggregate route's large community.
8070 */
8071 if (bgp_attr_get_lcommunity(pinew->attr))
8072 bgp_compute_aggregate_lcommunity(
8073 aggregate,
8074 bgp_attr_get_lcommunity(pinew->attr));
8075
8076 /* Retrieve aggregate route's as-path.
8077 */
8078 if (aggregate->aspath)
8079 aspath = aspath_dup(aggregate->aspath);
8080
8081 /* Retrieve aggregate route's community.
8082 */
8083 if (aggregate->community)
8084 community = community_dup(aggregate->community);
8085
8086 /* Retrieve aggregate route's ecommunity.
8087 */
8088 if (aggregate->ecommunity)
8089 ecommunity = ecommunity_dup(aggregate->ecommunity);
8090
8091 /* Retrieve aggregate route's lcommunity.
8092 */
8093 if (aggregate->lcommunity)
8094 lcommunity = lcommunity_dup(aggregate->lcommunity);
8095 }
8096
8097 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8098 aspath, community, ecommunity,
8099 lcommunity, atomic_aggregate, aggregate);
8100 }
8101
8102 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8103 safi_t safi,
8104 struct bgp_path_info *pi,
8105 struct bgp_aggregate *aggregate,
8106 const struct prefix *aggr_p)
8107 {
8108 uint8_t origin;
8109 struct aspath *aspath = NULL;
8110 uint8_t atomic_aggregate = 0;
8111 struct community *community = NULL;
8112 struct ecommunity *ecommunity = NULL;
8113 struct lcommunity *lcommunity = NULL;
8114 unsigned long match = 0;
8115
8116 /* If the bgp instance is being deleted or self peer is deleted
8117 * then do not create aggregate route
8118 */
8119 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8120 || (bgp->peer_self == NULL))
8121 return;
8122
8123 if (BGP_PATH_HOLDDOWN(pi))
8124 return;
8125
8126 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8127 return;
8128
8129 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8130 if (aggr_unsuppress_path(aggregate, pi))
8131 match++;
8132
8133 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8134 && aggr_suppress_map_test(bgp, aggregate, pi))
8135 if (aggr_unsuppress_path(aggregate, pi))
8136 match++;
8137
8138 /*
8139 * This must be called after `summary`, `suppress-map` check to avoid
8140 * "unsuppressing" twice.
8141 */
8142 if (aggregate->match_med)
8143 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8144
8145 if (aggregate->count > 0)
8146 aggregate->count--;
8147
8148 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8149 aggregate->incomplete_origin_count--;
8150 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8151 aggregate->egp_origin_count--;
8152
8153 if (aggregate->as_set) {
8154 /* Remove as-path from aggregate.
8155 */
8156 bgp_remove_aspath_from_aggregate(aggregate,
8157 pi->attr->aspath);
8158
8159 if (bgp_attr_get_community(pi->attr))
8160 /* Remove community from aggregate.
8161 */
8162 bgp_remove_community_from_aggregate(
8163 aggregate, bgp_attr_get_community(pi->attr));
8164
8165 if (bgp_attr_get_ecommunity(pi->attr))
8166 /* Remove ecommunity from aggregate.
8167 */
8168 bgp_remove_ecommunity_from_aggregate(
8169 aggregate, bgp_attr_get_ecommunity(pi->attr));
8170
8171 if (bgp_attr_get_lcommunity(pi->attr))
8172 /* Remove lcommunity from aggregate.
8173 */
8174 bgp_remove_lcommunity_from_aggregate(
8175 aggregate, bgp_attr_get_lcommunity(pi->attr));
8176 }
8177
8178 /* If this node was suppressed, process the change. */
8179 if (match)
8180 bgp_process(bgp, pi->net, afi, safi);
8181
8182 origin = BGP_ORIGIN_IGP;
8183 if (aggregate->incomplete_origin_count > 0)
8184 origin = BGP_ORIGIN_INCOMPLETE;
8185 else if (aggregate->egp_origin_count > 0)
8186 origin = BGP_ORIGIN_EGP;
8187
8188 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8189 origin = aggregate->origin;
8190
8191 if (aggregate->as_set) {
8192 /* Retrieve aggregate route's as-path.
8193 */
8194 if (aggregate->aspath)
8195 aspath = aspath_dup(aggregate->aspath);
8196
8197 /* Retrieve aggregate route's community.
8198 */
8199 if (aggregate->community)
8200 community = community_dup(aggregate->community);
8201
8202 /* Retrieve aggregate route's ecommunity.
8203 */
8204 if (aggregate->ecommunity)
8205 ecommunity = ecommunity_dup(aggregate->ecommunity);
8206
8207 /* Retrieve aggregate route's lcommunity.
8208 */
8209 if (aggregate->lcommunity)
8210 lcommunity = lcommunity_dup(aggregate->lcommunity);
8211 }
8212
8213 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8214 aspath, community, ecommunity,
8215 lcommunity, atomic_aggregate, aggregate);
8216 }
8217
8218 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8219 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8220 {
8221 struct bgp_dest *child;
8222 struct bgp_dest *dest;
8223 struct bgp_aggregate *aggregate;
8224 struct bgp_table *table;
8225
8226 table = bgp->aggregate[afi][safi];
8227
8228 /* No aggregates configured. */
8229 if (bgp_table_top_nolock(table) == NULL)
8230 return;
8231
8232 if (p->prefixlen == 0)
8233 return;
8234
8235 if (BGP_PATH_HOLDDOWN(pi))
8236 return;
8237
8238 /* If suppress fib is enabled and route not installed
8239 * in FIB, do not update the aggregate route
8240 */
8241 if (!bgp_check_advertise(bgp, pi->net))
8242 return;
8243
8244 child = bgp_node_get(table, p);
8245
8246 /* Aggregate address configuration check. */
8247 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8248 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8249
8250 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8251 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8252 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8253 aggregate);
8254 }
8255 }
8256 bgp_dest_unlock_node(child);
8257 }
8258
8259 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8260 struct bgp_path_info *del, afi_t afi, safi_t safi)
8261 {
8262 struct bgp_dest *child;
8263 struct bgp_dest *dest;
8264 struct bgp_aggregate *aggregate;
8265 struct bgp_table *table;
8266
8267 table = bgp->aggregate[afi][safi];
8268
8269 /* No aggregates configured. */
8270 if (bgp_table_top_nolock(table) == NULL)
8271 return;
8272
8273 if (p->prefixlen == 0)
8274 return;
8275
8276 child = bgp_node_get(table, p);
8277
8278 /* Aggregate address configuration check. */
8279 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8280 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8281
8282 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8283 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8284 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8285 aggregate, dest_p);
8286 }
8287 }
8288 bgp_dest_unlock_node(child);
8289 }
8290
8291 /* Aggregate route attribute. */
8292 #define AGGREGATE_SUMMARY_ONLY 1
8293 #define AGGREGATE_AS_SET 1
8294 #define AGGREGATE_AS_UNSET 0
8295
8296 static const char *bgp_origin2str(uint8_t origin)
8297 {
8298 switch (origin) {
8299 case BGP_ORIGIN_IGP:
8300 return "igp";
8301 case BGP_ORIGIN_EGP:
8302 return "egp";
8303 case BGP_ORIGIN_INCOMPLETE:
8304 return "incomplete";
8305 }
8306 return "n/a";
8307 }
8308
8309 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8310 {
8311 switch (v_state) {
8312 case RPKI_NOT_BEING_USED:
8313 return "not used";
8314 case RPKI_VALID:
8315 return "valid";
8316 case RPKI_NOTFOUND:
8317 return "not found";
8318 case RPKI_INVALID:
8319 return "invalid";
8320 }
8321
8322 assert(!"We should never get here this is a dev escape");
8323 return "ERROR";
8324 }
8325
8326 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8327 afi_t afi, safi_t safi)
8328 {
8329 VTY_DECLVAR_CONTEXT(bgp, bgp);
8330 int ret;
8331 struct prefix p;
8332 struct bgp_dest *dest;
8333 struct bgp_aggregate *aggregate;
8334
8335 /* Convert string to prefix structure. */
8336 ret = str2prefix(prefix_str, &p);
8337 if (!ret) {
8338 vty_out(vty, "Malformed prefix\n");
8339 return CMD_WARNING_CONFIG_FAILED;
8340 }
8341 apply_mask(&p);
8342
8343 /* Old configuration check. */
8344 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8345 if (!dest) {
8346 vty_out(vty,
8347 "%% There is no aggregate-address configuration.\n");
8348 return CMD_WARNING_CONFIG_FAILED;
8349 }
8350
8351 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8352 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8353 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8354 NULL, NULL, 0, aggregate);
8355
8356 /* Unlock aggregate address configuration. */
8357 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8358
8359 bgp_free_aggregate_info(aggregate);
8360 bgp_dest_unlock_node(dest);
8361 bgp_dest_unlock_node(dest);
8362
8363 return CMD_SUCCESS;
8364 }
8365
8366 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8367 safi_t safi, const char *rmap,
8368 uint8_t summary_only, uint8_t as_set,
8369 uint8_t origin, bool match_med,
8370 const char *suppress_map)
8371 {
8372 VTY_DECLVAR_CONTEXT(bgp, bgp);
8373 int ret;
8374 struct prefix p;
8375 struct bgp_dest *dest;
8376 struct bgp_aggregate *aggregate;
8377 uint8_t as_set_new = as_set;
8378
8379 if (suppress_map && summary_only) {
8380 vty_out(vty,
8381 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8382 return CMD_WARNING_CONFIG_FAILED;
8383 }
8384
8385 /* Convert string to prefix structure. */
8386 ret = str2prefix(prefix_str, &p);
8387 if (!ret) {
8388 vty_out(vty, "Malformed prefix\n");
8389 return CMD_WARNING_CONFIG_FAILED;
8390 }
8391 apply_mask(&p);
8392
8393 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8394 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8395 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8396 prefix_str);
8397 return CMD_WARNING_CONFIG_FAILED;
8398 }
8399
8400 /* Old configuration check. */
8401 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8402 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8403
8404 if (aggregate) {
8405 vty_out(vty, "There is already same aggregate network.\n");
8406 /* try to remove the old entry */
8407 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8408 if (ret) {
8409 vty_out(vty, "Error deleting aggregate.\n");
8410 bgp_dest_unlock_node(dest);
8411 return CMD_WARNING_CONFIG_FAILED;
8412 }
8413 }
8414
8415 /* Make aggregate address structure. */
8416 aggregate = bgp_aggregate_new();
8417 aggregate->summary_only = summary_only;
8418 aggregate->match_med = match_med;
8419
8420 /* Network operators MUST NOT locally generate any new
8421 * announcements containing AS_SET or AS_CONFED_SET. If they have
8422 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8423 * SHOULD withdraw those routes and re-announce routes for the
8424 * aggregate or component prefixes (i.e., the more-specific routes
8425 * subsumed by the previously aggregated route) without AS_SET
8426 * or AS_CONFED_SET in the updates.
8427 */
8428 if (bgp->reject_as_sets) {
8429 if (as_set == AGGREGATE_AS_SET) {
8430 as_set_new = AGGREGATE_AS_UNSET;
8431 zlog_warn(
8432 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8433 __func__);
8434 vty_out(vty,
8435 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8436 }
8437 }
8438
8439 aggregate->as_set = as_set_new;
8440 aggregate->safi = safi;
8441 /* Override ORIGIN attribute if defined.
8442 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8443 * to IGP which is not what rfc4271 says.
8444 * This enables the same behavior, optionally.
8445 */
8446 aggregate->origin = origin;
8447
8448 if (rmap) {
8449 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8450 route_map_counter_decrement(aggregate->rmap.map);
8451 aggregate->rmap.name =
8452 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8453 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8454 route_map_counter_increment(aggregate->rmap.map);
8455 }
8456
8457 if (suppress_map) {
8458 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8459 route_map_counter_decrement(aggregate->suppress_map);
8460
8461 aggregate->suppress_map_name =
8462 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8463 aggregate->suppress_map =
8464 route_map_lookup_by_name(aggregate->suppress_map_name);
8465 route_map_counter_increment(aggregate->suppress_map);
8466 }
8467
8468 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8469
8470 /* Aggregate address insert into BGP routing table. */
8471 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8472 bgp_aggregate_free(aggregate);
8473 bgp_dest_unlock_node(dest);
8474 }
8475
8476 return CMD_SUCCESS;
8477 }
8478
8479 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8480 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8481 "as-set$as_set_s"
8482 "|summary-only$summary_only"
8483 "|route-map RMAP_NAME$rmap_name"
8484 "|origin <egp|igp|incomplete>$origin_s"
8485 "|matching-MED-only$match_med"
8486 "|suppress-map RMAP_NAME$suppress_map"
8487 "}]",
8488 NO_STR
8489 "Configure BGP aggregate entries\n"
8490 "Aggregate prefix\n"
8491 "Aggregate address\n"
8492 "Aggregate mask\n"
8493 "Generate AS set path information\n"
8494 "Filter more specific routes from updates\n"
8495 "Apply route map to aggregate network\n"
8496 "Route map name\n"
8497 "BGP origin code\n"
8498 "Remote EGP\n"
8499 "Local IGP\n"
8500 "Unknown heritage\n"
8501 "Only aggregate routes with matching MED\n"
8502 "Suppress the selected more specific routes\n"
8503 "Route map with the route selectors\n")
8504 {
8505 const char *prefix_s = NULL;
8506 safi_t safi = bgp_node_safi(vty);
8507 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8508 int as_set = AGGREGATE_AS_UNSET;
8509 char prefix_buf[PREFIX2STR_BUFFER];
8510
8511 if (addr_str) {
8512 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8513 sizeof(prefix_buf))
8514 == 0) {
8515 vty_out(vty, "%% Inconsistent address and mask\n");
8516 return CMD_WARNING_CONFIG_FAILED;
8517 }
8518 prefix_s = prefix_buf;
8519 } else
8520 prefix_s = prefix_str;
8521
8522 if (origin_s) {
8523 if (strcmp(origin_s, "egp") == 0)
8524 origin = BGP_ORIGIN_EGP;
8525 else if (strcmp(origin_s, "igp") == 0)
8526 origin = BGP_ORIGIN_IGP;
8527 else if (strcmp(origin_s, "incomplete") == 0)
8528 origin = BGP_ORIGIN_INCOMPLETE;
8529 }
8530
8531 if (as_set_s)
8532 as_set = AGGREGATE_AS_SET;
8533
8534 /* Handle configuration removal, otherwise installation. */
8535 if (no)
8536 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8537
8538 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8539 summary_only != NULL, as_set, origin,
8540 match_med != NULL, suppress_map);
8541 }
8542
8543 void bgp_free_aggregate_info(struct bgp_aggregate *aggregate)
8544 {
8545 if (aggregate->community)
8546 community_free(&aggregate->community);
8547
8548 hash_clean_and_free(&aggregate->community_hash,
8549 bgp_aggr_community_remove);
8550
8551 if (aggregate->ecommunity)
8552 ecommunity_free(&aggregate->ecommunity);
8553
8554 hash_clean_and_free(&aggregate->ecommunity_hash,
8555 bgp_aggr_ecommunity_remove);
8556
8557 if (aggregate->lcommunity)
8558 lcommunity_free(&aggregate->lcommunity);
8559
8560 hash_clean_and_free(&aggregate->lcommunity_hash,
8561 bgp_aggr_lcommunity_remove);
8562
8563 if (aggregate->aspath)
8564 aspath_free(aggregate->aspath);
8565
8566 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8567
8568 bgp_aggregate_free(aggregate);
8569 }
8570
8571 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8572 "[no] aggregate-address X:X::X:X/M$prefix [{"
8573 "as-set$as_set_s"
8574 "|summary-only$summary_only"
8575 "|route-map RMAP_NAME$rmap_name"
8576 "|origin <egp|igp|incomplete>$origin_s"
8577 "|matching-MED-only$match_med"
8578 "|suppress-map RMAP_NAME$suppress_map"
8579 "}]",
8580 NO_STR
8581 "Configure BGP aggregate entries\n"
8582 "Aggregate prefix\n"
8583 "Generate AS set path information\n"
8584 "Filter more specific routes from updates\n"
8585 "Apply route map to aggregate network\n"
8586 "Route map name\n"
8587 "BGP origin code\n"
8588 "Remote EGP\n"
8589 "Local IGP\n"
8590 "Unknown heritage\n"
8591 "Only aggregate routes with matching MED\n"
8592 "Suppress the selected more specific routes\n"
8593 "Route map with the route selectors\n")
8594 {
8595 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8596 int as_set = AGGREGATE_AS_UNSET;
8597
8598 if (origin_s) {
8599 if (strcmp(origin_s, "egp") == 0)
8600 origin = BGP_ORIGIN_EGP;
8601 else if (strcmp(origin_s, "igp") == 0)
8602 origin = BGP_ORIGIN_IGP;
8603 else if (strcmp(origin_s, "incomplete") == 0)
8604 origin = BGP_ORIGIN_INCOMPLETE;
8605 }
8606
8607 if (as_set_s)
8608 as_set = AGGREGATE_AS_SET;
8609
8610 /* Handle configuration removal, otherwise installation. */
8611 if (no)
8612 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8613 SAFI_UNICAST);
8614
8615 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8616 rmap_name, summary_only != NULL, as_set,
8617 origin, match_med != NULL, suppress_map);
8618 }
8619
8620 /* Redistribute route treatment. */
8621 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8622 const union g_addr *nexthop, ifindex_t ifindex,
8623 enum nexthop_types_t nhtype, uint8_t distance,
8624 enum blackhole_type bhtype, uint32_t metric,
8625 uint8_t type, unsigned short instance,
8626 route_tag_t tag)
8627 {
8628 struct bgp_path_info *new;
8629 struct bgp_path_info *bpi;
8630 struct bgp_path_info rmap_path;
8631 struct bgp_dest *bn;
8632 struct attr attr;
8633 struct attr *new_attr;
8634 afi_t afi;
8635 route_map_result_t ret;
8636 struct bgp_redist *red;
8637
8638 /* Make default attribute. */
8639 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8640 /*
8641 * This must not be NULL to satisfy Coverity SA
8642 */
8643 assert(attr.aspath);
8644
8645 switch (nhtype) {
8646 case NEXTHOP_TYPE_IFINDEX:
8647 switch (p->family) {
8648 case AF_INET:
8649 attr.nexthop.s_addr = INADDR_ANY;
8650 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8651 break;
8652 case AF_INET6:
8653 memset(&attr.mp_nexthop_global, 0,
8654 sizeof(attr.mp_nexthop_global));
8655 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8656 break;
8657 }
8658 break;
8659 case NEXTHOP_TYPE_IPV4:
8660 case NEXTHOP_TYPE_IPV4_IFINDEX:
8661 attr.nexthop = nexthop->ipv4;
8662 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8663 break;
8664 case NEXTHOP_TYPE_IPV6:
8665 case NEXTHOP_TYPE_IPV6_IFINDEX:
8666 attr.mp_nexthop_global = nexthop->ipv6;
8667 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8668 break;
8669 case NEXTHOP_TYPE_BLACKHOLE:
8670 switch (p->family) {
8671 case AF_INET:
8672 attr.nexthop.s_addr = INADDR_ANY;
8673 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8674 break;
8675 case AF_INET6:
8676 memset(&attr.mp_nexthop_global, 0,
8677 sizeof(attr.mp_nexthop_global));
8678 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8679 break;
8680 }
8681 attr.bh_type = bhtype;
8682 break;
8683 }
8684 attr.nh_type = nhtype;
8685 attr.nh_ifindex = ifindex;
8686
8687 attr.med = metric;
8688 attr.distance = distance;
8689 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8690 attr.tag = tag;
8691
8692 if (metric)
8693 bgp_attr_set_aigp_metric(&attr, metric);
8694
8695 afi = family2afi(p->family);
8696
8697 red = bgp_redist_lookup(bgp, afi, type, instance);
8698 if (red) {
8699 struct attr attr_new;
8700
8701 /* Copy attribute for modification. */
8702 attr_new = attr;
8703
8704 if (red->redist_metric_flag) {
8705 attr_new.med = red->redist_metric;
8706 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8707 }
8708
8709 /* Apply route-map. */
8710 if (red->rmap.name) {
8711 memset(&rmap_path, 0, sizeof(rmap_path));
8712 rmap_path.peer = bgp->peer_self;
8713 rmap_path.attr = &attr_new;
8714
8715 SET_FLAG(bgp->peer_self->rmap_type,
8716 PEER_RMAP_TYPE_REDISTRIBUTE);
8717
8718 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8719
8720 bgp->peer_self->rmap_type = 0;
8721
8722 if (ret == RMAP_DENYMATCH) {
8723 /* Free uninterned attribute. */
8724 bgp_attr_flush(&attr_new);
8725
8726 /* Unintern original. */
8727 aspath_unintern(&attr.aspath);
8728 bgp_redistribute_delete(bgp, p, type, instance);
8729 return;
8730 }
8731 }
8732
8733 if (bgp_in_graceful_shutdown(bgp))
8734 bgp_attr_add_gshut_community(&attr_new);
8735
8736 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8737 SAFI_UNICAST, p, NULL);
8738
8739 new_attr = bgp_attr_intern(&attr_new);
8740
8741 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8742 if (bpi->peer == bgp->peer_self
8743 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8744 break;
8745
8746 if (bpi) {
8747 /* Ensure the (source route) type is updated. */
8748 bpi->type = type;
8749 if (attrhash_cmp(bpi->attr, new_attr)
8750 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8751 bgp_attr_unintern(&new_attr);
8752 aspath_unintern(&attr.aspath);
8753 bgp_dest_unlock_node(bn);
8754 return;
8755 } else {
8756 /* The attribute is changed. */
8757 bgp_path_info_set_flag(bn, bpi,
8758 BGP_PATH_ATTR_CHANGED);
8759
8760 /* Rewrite BGP route information. */
8761 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8762 bgp_path_info_restore(bn, bpi);
8763 else
8764 bgp_aggregate_decrement(
8765 bgp, p, bpi, afi, SAFI_UNICAST);
8766 bgp_attr_unintern(&bpi->attr);
8767 bpi->attr = new_attr;
8768 bpi->uptime = monotime(NULL);
8769
8770 /* Process change. */
8771 bgp_aggregate_increment(bgp, p, bpi, afi,
8772 SAFI_UNICAST);
8773 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8774 bgp_dest_unlock_node(bn);
8775 aspath_unintern(&attr.aspath);
8776
8777 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8778 || (bgp->inst_type
8779 == BGP_INSTANCE_TYPE_DEFAULT)) {
8780
8781 vpn_leak_from_vrf_update(
8782 bgp_get_default(), bgp, bpi);
8783 }
8784 return;
8785 }
8786 }
8787
8788 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8789 bgp->peer_self, new_attr, bn);
8790 SET_FLAG(new->flags, BGP_PATH_VALID);
8791
8792 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8793 bgp_path_info_add(bn, new);
8794 bgp_dest_unlock_node(bn);
8795 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8796 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8797
8798 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8799 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8800
8801 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8802 }
8803 }
8804
8805 /* Unintern original. */
8806 aspath_unintern(&attr.aspath);
8807 }
8808
8809 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8810 unsigned short instance)
8811 {
8812 afi_t afi;
8813 struct bgp_dest *dest;
8814 struct bgp_path_info *pi;
8815 struct bgp_redist *red;
8816
8817 afi = family2afi(p->family);
8818
8819 red = bgp_redist_lookup(bgp, afi, type, instance);
8820 if (red) {
8821 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8822 SAFI_UNICAST, p, NULL);
8823
8824 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8825 if (pi->peer == bgp->peer_self && pi->type == type)
8826 break;
8827
8828 if (pi) {
8829 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8830 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8831
8832 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8833 bgp, pi);
8834 }
8835 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8836 bgp_path_info_delete(dest, pi);
8837 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8838 }
8839 bgp_dest_unlock_node(dest);
8840 }
8841 }
8842
8843 /* Withdraw specified route type's route. */
8844 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8845 unsigned short instance)
8846 {
8847 struct bgp_dest *dest;
8848 struct bgp_path_info *pi;
8849 struct bgp_table *table;
8850
8851 table = bgp->rib[afi][SAFI_UNICAST];
8852
8853 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8854 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8855 if (pi->peer == bgp->peer_self && pi->type == type
8856 && pi->instance == instance)
8857 break;
8858
8859 if (pi) {
8860 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8861 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8862
8863 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8864 bgp, pi);
8865 }
8866 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8867 pi, afi, SAFI_UNICAST);
8868 bgp_path_info_delete(dest, pi);
8869 if (!CHECK_FLAG(bgp->flags,
8870 BGP_FLAG_DELETE_IN_PROGRESS))
8871 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8872 else
8873 bgp_path_info_reap(dest, pi);
8874 }
8875 }
8876 }
8877
8878 /* Static function to display route. */
8879 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8880 struct vty *vty, json_object *json, bool wide)
8881 {
8882 int len = 0;
8883 char buf[INET6_ADDRSTRLEN];
8884
8885 if (p->family == AF_INET) {
8886 if (!json) {
8887 len = vty_out(vty, "%pFX", p);
8888 } else {
8889 json_object_string_add(json, "prefix",
8890 inet_ntop(p->family,
8891 &p->u.prefix, buf,
8892 sizeof(buf)));
8893 json_object_int_add(json, "prefixLen", p->prefixlen);
8894 json_object_string_addf(json, "network", "%pFX", p);
8895 json_object_int_add(json, "version", dest->version);
8896 }
8897 } else if (p->family == AF_ETHERNET) {
8898 len = vty_out(vty, "%pFX", p);
8899 } else if (p->family == AF_EVPN) {
8900 if (!json)
8901 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8902 else
8903 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8904 } else if (p->family == AF_FLOWSPEC) {
8905 route_vty_out_flowspec(vty, p, NULL,
8906 json ?
8907 NLRI_STRING_FORMAT_JSON_SIMPLE :
8908 NLRI_STRING_FORMAT_MIN, json);
8909 } else {
8910 if (!json)
8911 len = vty_out(vty, "%pFX", p);
8912 else {
8913 json_object_string_add(json, "prefix",
8914 inet_ntop(p->family,
8915 &p->u.prefix, buf,
8916 sizeof(buf)));
8917 json_object_int_add(json, "prefixLen", p->prefixlen);
8918 json_object_string_addf(json, "network", "%pFX", p);
8919 json_object_int_add(json, "version", dest->version);
8920 }
8921 }
8922
8923 if (!json) {
8924 len = wide ? (45 - len) : (17 - len);
8925 if (len < 1)
8926 vty_out(vty, "\n%*s", 20, " ");
8927 else
8928 vty_out(vty, "%*s", len, " ");
8929 }
8930 }
8931
8932 enum bgp_display_type {
8933 normal_list,
8934 };
8935
8936 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8937 {
8938 switch (reason) {
8939 case bgp_path_selection_none:
8940 return "Nothing to Select";
8941 case bgp_path_selection_first:
8942 return "First path received";
8943 case bgp_path_selection_evpn_sticky_mac:
8944 return "EVPN Sticky Mac";
8945 case bgp_path_selection_evpn_seq:
8946 return "EVPN sequence number";
8947 case bgp_path_selection_evpn_lower_ip:
8948 return "EVPN lower IP";
8949 case bgp_path_selection_evpn_local_path:
8950 return "EVPN local ES path";
8951 case bgp_path_selection_evpn_non_proxy:
8952 return "EVPN non proxy";
8953 case bgp_path_selection_weight:
8954 return "Weight";
8955 case bgp_path_selection_local_pref:
8956 return "Local Pref";
8957 case bgp_path_selection_accept_own:
8958 return "Accept Own";
8959 case bgp_path_selection_local_route:
8960 return "Local Route";
8961 case bgp_path_selection_aigp:
8962 return "AIGP";
8963 case bgp_path_selection_confed_as_path:
8964 return "Confederation based AS Path";
8965 case bgp_path_selection_as_path:
8966 return "AS Path";
8967 case bgp_path_selection_origin:
8968 return "Origin";
8969 case bgp_path_selection_med:
8970 return "MED";
8971 case bgp_path_selection_peer:
8972 return "Peer Type";
8973 case bgp_path_selection_confed:
8974 return "Confed Peer Type";
8975 case bgp_path_selection_igp_metric:
8976 return "IGP Metric";
8977 case bgp_path_selection_older:
8978 return "Older Path";
8979 case bgp_path_selection_router_id:
8980 return "Router ID";
8981 case bgp_path_selection_cluster_length:
8982 return "Cluster length";
8983 case bgp_path_selection_stale:
8984 return "Path Staleness";
8985 case bgp_path_selection_local_configured:
8986 return "Locally configured route";
8987 case bgp_path_selection_neighbor_ip:
8988 return "Neighbor IP";
8989 case bgp_path_selection_default:
8990 return "Nothing left to compare";
8991 }
8992 return "Invalid (internal error)";
8993 }
8994
8995 /* Print the short form route status for a bgp_path_info */
8996 static void route_vty_short_status_out(struct vty *vty,
8997 struct bgp_path_info *path,
8998 const struct prefix *p,
8999 json_object *json_path)
9000 {
9001 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9002
9003 if (json_path) {
9004
9005 /* Route status display. */
9006 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9007 json_object_boolean_true_add(json_path, "removed");
9008
9009 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9010 json_object_boolean_true_add(json_path, "stale");
9011
9012 if (path->extra && bgp_path_suppressed(path))
9013 json_object_boolean_true_add(json_path, "suppressed");
9014
9015 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9016 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9017 json_object_boolean_true_add(json_path, "valid");
9018
9019 /* Selected */
9020 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9021 json_object_boolean_true_add(json_path, "history");
9022
9023 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9024 json_object_boolean_true_add(json_path, "damped");
9025
9026 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9027 json_object_boolean_true_add(json_path, "bestpath");
9028 json_object_string_add(json_path, "selectionReason",
9029 bgp_path_selection_reason2str(
9030 path->net->reason));
9031 }
9032
9033 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9034 json_object_boolean_true_add(json_path, "multipath");
9035
9036 /* Internal route. */
9037 if ((path->peer->as)
9038 && (path->peer->as == path->peer->local_as))
9039 json_object_string_add(json_path, "pathFrom",
9040 "internal");
9041 else
9042 json_object_string_add(json_path, "pathFrom",
9043 "external");
9044
9045 return;
9046 }
9047
9048 /* RPKI validation state */
9049 rpki_state =
9050 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9051
9052 if (rpki_state == RPKI_VALID)
9053 vty_out(vty, "V");
9054 else if (rpki_state == RPKI_INVALID)
9055 vty_out(vty, "I");
9056 else if (rpki_state == RPKI_NOTFOUND)
9057 vty_out(vty, "N");
9058 else
9059 vty_out(vty, " ");
9060
9061 /* Route status display. */
9062 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9063 vty_out(vty, "R");
9064 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9065 vty_out(vty, "S");
9066 else if (bgp_path_suppressed(path))
9067 vty_out(vty, "s");
9068 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9069 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9070 vty_out(vty, "*");
9071 else
9072 vty_out(vty, " ");
9073
9074 /* Selected */
9075 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9076 vty_out(vty, "h");
9077 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9078 vty_out(vty, "d");
9079 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9080 vty_out(vty, ">");
9081 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9082 vty_out(vty, "=");
9083 else
9084 vty_out(vty, " ");
9085
9086 /* Internal route. */
9087 if (path->peer && (path->peer->as)
9088 && (path->peer->as == path->peer->local_as))
9089 vty_out(vty, "i");
9090 else
9091 vty_out(vty, " ");
9092 }
9093
9094 static char *bgp_nexthop_hostname(struct peer *peer,
9095 struct bgp_nexthop_cache *bnc)
9096 {
9097 if (peer->hostname
9098 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9099 return peer->hostname;
9100 return NULL;
9101 }
9102
9103 /* called from terminal list command */
9104 void route_vty_out(struct vty *vty, const struct prefix *p,
9105 struct bgp_path_info *path, int display, safi_t safi,
9106 json_object *json_paths, bool wide)
9107 {
9108 int len;
9109 struct attr *attr = path->attr;
9110 json_object *json_path = NULL;
9111 json_object *json_nexthops = NULL;
9112 json_object *json_nexthop_global = NULL;
9113 json_object *json_nexthop_ll = NULL;
9114 json_object *json_ext_community = NULL;
9115 char vrf_id_str[VRF_NAMSIZ] = {0};
9116 bool nexthop_self =
9117 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9118 bool nexthop_othervrf = false;
9119 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9120 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9121 char *nexthop_hostname =
9122 bgp_nexthop_hostname(path->peer, path->nexthop);
9123 char esi_buf[ESI_STR_LEN];
9124
9125 if (json_paths)
9126 json_path = json_object_new_object();
9127
9128 /* short status lead text */
9129 route_vty_short_status_out(vty, path, p, json_path);
9130
9131 if (!json_paths) {
9132 /* print prefix and mask */
9133 if (!display)
9134 route_vty_out_route(path->net, p, vty, json_path, wide);
9135 else
9136 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9137 } else {
9138 route_vty_out_route(path->net, p, vty, json_path, wide);
9139 }
9140
9141 /*
9142 * If vrf id of nexthop is different from that of prefix,
9143 * set up printable string to append
9144 */
9145 if (path->extra && path->extra->bgp_orig) {
9146 const char *self = "";
9147
9148 if (nexthop_self)
9149 self = "<";
9150
9151 nexthop_othervrf = true;
9152 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9153
9154 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9155 snprintf(vrf_id_str, sizeof(vrf_id_str),
9156 "@%s%s", VRFID_NONE_STR, self);
9157 else
9158 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9159 path->extra->bgp_orig->vrf_id, self);
9160
9161 if (path->extra->bgp_orig->inst_type
9162 != BGP_INSTANCE_TYPE_DEFAULT)
9163
9164 nexthop_vrfname = path->extra->bgp_orig->name;
9165 } else {
9166 const char *self = "";
9167
9168 if (nexthop_self)
9169 self = "<";
9170
9171 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9172 }
9173
9174 /*
9175 * For ENCAP and EVPN routes, nexthop address family is not
9176 * neccessarily the same as the prefix address family.
9177 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9178 * EVPN routes are also exchanged with a MP nexthop. Currently,
9179 * this
9180 * is only IPv4, the value will be present in either
9181 * attr->nexthop or
9182 * attr->mp_nexthop_global_in
9183 */
9184 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9185 char nexthop[128];
9186 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9187
9188 switch (af) {
9189 case AF_INET:
9190 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9191 &attr->mp_nexthop_global_in);
9192 break;
9193 case AF_INET6:
9194 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9195 &attr->mp_nexthop_global);
9196 break;
9197 default:
9198 snprintf(nexthop, sizeof(nexthop), "?");
9199 break;
9200 }
9201
9202 if (json_paths) {
9203 json_nexthop_global = json_object_new_object();
9204
9205 json_object_string_add(json_nexthop_global, "ip",
9206 nexthop);
9207
9208 if (path->peer->hostname)
9209 json_object_string_add(json_nexthop_global,
9210 "hostname",
9211 path->peer->hostname);
9212
9213 json_object_string_add(json_nexthop_global, "afi",
9214 (af == AF_INET) ? "ipv4"
9215 : "ipv6");
9216 json_object_boolean_true_add(json_nexthop_global,
9217 "used");
9218 } else {
9219 if (nexthop_hostname)
9220 len = vty_out(vty, "%s(%s)%s", nexthop,
9221 nexthop_hostname, vrf_id_str);
9222 else
9223 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9224
9225 len = wide ? (41 - len) : (16 - len);
9226 if (len < 1)
9227 vty_out(vty, "\n%*s", 36, " ");
9228 else
9229 vty_out(vty, "%*s", len, " ");
9230 }
9231 } else if (safi == SAFI_EVPN) {
9232 if (json_paths) {
9233 json_nexthop_global = json_object_new_object();
9234
9235 json_object_string_addf(json_nexthop_global, "ip",
9236 "%pI4",
9237 &attr->mp_nexthop_global_in);
9238
9239 if (path->peer->hostname)
9240 json_object_string_add(json_nexthop_global,
9241 "hostname",
9242 path->peer->hostname);
9243
9244 json_object_string_add(json_nexthop_global, "afi",
9245 "ipv4");
9246 json_object_boolean_true_add(json_nexthop_global,
9247 "used");
9248 } else {
9249 if (nexthop_hostname)
9250 len = vty_out(vty, "%pI4(%s)%s",
9251 &attr->mp_nexthop_global_in,
9252 nexthop_hostname, vrf_id_str);
9253 else
9254 len = vty_out(vty, "%pI4%s",
9255 &attr->mp_nexthop_global_in,
9256 vrf_id_str);
9257
9258 len = wide ? (41 - len) : (16 - len);
9259 if (len < 1)
9260 vty_out(vty, "\n%*s", 36, " ");
9261 else
9262 vty_out(vty, "%*s", len, " ");
9263 }
9264 } else if (safi == SAFI_FLOWSPEC) {
9265 if (attr->nexthop.s_addr != INADDR_ANY) {
9266 if (json_paths) {
9267 json_nexthop_global = json_object_new_object();
9268
9269 json_object_string_add(json_nexthop_global,
9270 "afi", "ipv4");
9271 json_object_string_addf(json_nexthop_global,
9272 "ip", "%pI4",
9273 &attr->nexthop);
9274
9275 if (path->peer->hostname)
9276 json_object_string_add(
9277 json_nexthop_global, "hostname",
9278 path->peer->hostname);
9279
9280 json_object_boolean_true_add(
9281 json_nexthop_global,
9282 "used");
9283 } else {
9284 if (nexthop_hostname)
9285 len = vty_out(vty, "%pI4(%s)%s",
9286 &attr->nexthop,
9287 nexthop_hostname,
9288 vrf_id_str);
9289 else
9290 len = vty_out(vty, "%pI4%s",
9291 &attr->nexthop,
9292 vrf_id_str);
9293
9294 len = wide ? (41 - len) : (16 - len);
9295 if (len < 1)
9296 vty_out(vty, "\n%*s", 36, " ");
9297 else
9298 vty_out(vty, "%*s", len, " ");
9299 }
9300 }
9301 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9302 if (json_paths) {
9303 json_nexthop_global = json_object_new_object();
9304
9305 json_object_string_addf(json_nexthop_global, "ip",
9306 "%pI4", &attr->nexthop);
9307
9308 if (path->peer->hostname)
9309 json_object_string_add(json_nexthop_global,
9310 "hostname",
9311 path->peer->hostname);
9312
9313 json_object_string_add(json_nexthop_global, "afi",
9314 "ipv4");
9315 json_object_boolean_true_add(json_nexthop_global,
9316 "used");
9317 } else {
9318 if (nexthop_hostname)
9319 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9320 nexthop_hostname, vrf_id_str);
9321 else
9322 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9323 vrf_id_str);
9324
9325 len = wide ? (41 - len) : (16 - len);
9326 if (len < 1)
9327 vty_out(vty, "\n%*s", 36, " ");
9328 else
9329 vty_out(vty, "%*s", len, " ");
9330 }
9331 }
9332
9333 /* IPv6 Next Hop */
9334 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9335 if (json_paths) {
9336 json_nexthop_global = json_object_new_object();
9337 json_object_string_addf(json_nexthop_global, "ip",
9338 "%pI6",
9339 &attr->mp_nexthop_global);
9340
9341 if (path->peer->hostname)
9342 json_object_string_add(json_nexthop_global,
9343 "hostname",
9344 path->peer->hostname);
9345
9346 json_object_string_add(json_nexthop_global, "afi",
9347 "ipv6");
9348 json_object_string_add(json_nexthop_global, "scope",
9349 "global");
9350
9351 /* We display both LL & GL if both have been
9352 * received */
9353 if ((attr->mp_nexthop_len
9354 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9355 || (path->peer->conf_if)) {
9356 json_nexthop_ll = json_object_new_object();
9357 json_object_string_addf(
9358 json_nexthop_ll, "ip", "%pI6",
9359 &attr->mp_nexthop_local);
9360
9361 if (path->peer->hostname)
9362 json_object_string_add(
9363 json_nexthop_ll, "hostname",
9364 path->peer->hostname);
9365
9366 json_object_string_add(json_nexthop_ll, "afi",
9367 "ipv6");
9368 json_object_string_add(json_nexthop_ll, "scope",
9369 "link-local");
9370
9371 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9372 &attr->mp_nexthop_local)
9373 != 0)
9374 && !attr->mp_nexthop_prefer_global)
9375 json_object_boolean_true_add(
9376 json_nexthop_ll, "used");
9377 else
9378 json_object_boolean_true_add(
9379 json_nexthop_global, "used");
9380 } else
9381 json_object_boolean_true_add(
9382 json_nexthop_global, "used");
9383 } else {
9384 /* Display LL if LL/Global both in table unless
9385 * prefer-global is set */
9386 if (((attr->mp_nexthop_len
9387 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9388 && !attr->mp_nexthop_prefer_global)
9389 || (path->peer->conf_if)) {
9390 if (path->peer->conf_if) {
9391 len = vty_out(vty, "%s",
9392 path->peer->conf_if);
9393 /* len of IPv6 addr + max len of def
9394 * ifname */
9395 len = wide ? (41 - len) : (16 - len);
9396
9397 if (len < 1)
9398 vty_out(vty, "\n%*s", 36, " ");
9399 else
9400 vty_out(vty, "%*s", len, " ");
9401 } else {
9402 if (nexthop_hostname)
9403 len = vty_out(
9404 vty, "%pI6(%s)%s",
9405 &attr->mp_nexthop_local,
9406 nexthop_hostname,
9407 vrf_id_str);
9408 else
9409 len = vty_out(
9410 vty, "%pI6%s",
9411 &attr->mp_nexthop_local,
9412 vrf_id_str);
9413
9414 len = wide ? (41 - len) : (16 - len);
9415
9416 if (len < 1)
9417 vty_out(vty, "\n%*s", 36, " ");
9418 else
9419 vty_out(vty, "%*s", len, " ");
9420 }
9421 } else {
9422 if (nexthop_hostname)
9423 len = vty_out(vty, "%pI6(%s)%s",
9424 &attr->mp_nexthop_global,
9425 nexthop_hostname,
9426 vrf_id_str);
9427 else
9428 len = vty_out(vty, "%pI6%s",
9429 &attr->mp_nexthop_global,
9430 vrf_id_str);
9431
9432 len = wide ? (41 - len) : (16 - len);
9433
9434 if (len < 1)
9435 vty_out(vty, "\n%*s", 36, " ");
9436 else
9437 vty_out(vty, "%*s", len, " ");
9438 }
9439 }
9440 }
9441
9442 /* MED/Metric */
9443 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9444 if (json_paths)
9445 json_object_int_add(json_path, "metric", attr->med);
9446 else if (wide)
9447 vty_out(vty, "%7u", attr->med);
9448 else
9449 vty_out(vty, "%10u", attr->med);
9450 else if (!json_paths) {
9451 if (wide)
9452 vty_out(vty, "%*s", 7, " ");
9453 else
9454 vty_out(vty, "%*s", 10, " ");
9455 }
9456
9457 /* Local Pref */
9458 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9459 if (json_paths)
9460 json_object_int_add(json_path, "locPrf",
9461 attr->local_pref);
9462 else
9463 vty_out(vty, "%7u", attr->local_pref);
9464 else if (!json_paths)
9465 vty_out(vty, " ");
9466
9467 if (json_paths)
9468 json_object_int_add(json_path, "weight", attr->weight);
9469 else
9470 vty_out(vty, "%7u ", attr->weight);
9471
9472 if (json_paths)
9473 json_object_string_addf(json_path, "peerId", "%pSU",
9474 &path->peer->su);
9475
9476 /* Print aspath */
9477 if (attr->aspath) {
9478 if (json_paths)
9479 json_object_string_add(json_path, "path",
9480 attr->aspath->str);
9481 else
9482 aspath_print_vty(vty, attr->aspath);
9483 }
9484
9485 /* Print origin */
9486 if (json_paths)
9487 json_object_string_add(json_path, "origin",
9488 bgp_origin_long_str[attr->origin]);
9489 else
9490 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9491
9492 if (json_paths) {
9493 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9494 json_object_string_add(json_path, "esi",
9495 esi_to_str(&attr->esi,
9496 esi_buf, sizeof(esi_buf)));
9497 }
9498 if (safi == SAFI_EVPN &&
9499 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9500 json_ext_community = json_object_new_object();
9501 json_object_string_add(
9502 json_ext_community, "string",
9503 bgp_attr_get_ecommunity(attr)->str);
9504 json_object_object_add(json_path,
9505 "extendedCommunity",
9506 json_ext_community);
9507 }
9508
9509 if (nexthop_self)
9510 json_object_boolean_true_add(json_path,
9511 "announceNexthopSelf");
9512 if (nexthop_othervrf) {
9513 json_object_string_add(json_path, "nhVrfName",
9514 nexthop_vrfname);
9515
9516 json_object_int_add(json_path, "nhVrfId",
9517 ((nexthop_vrfid == VRF_UNKNOWN)
9518 ? -1
9519 : (int)nexthop_vrfid));
9520 }
9521 }
9522
9523 if (json_paths) {
9524 if (json_nexthop_global || json_nexthop_ll) {
9525 json_nexthops = json_object_new_array();
9526
9527 if (json_nexthop_global)
9528 json_object_array_add(json_nexthops,
9529 json_nexthop_global);
9530
9531 if (json_nexthop_ll)
9532 json_object_array_add(json_nexthops,
9533 json_nexthop_ll);
9534
9535 json_object_object_add(json_path, "nexthops",
9536 json_nexthops);
9537 }
9538
9539 json_object_array_add(json_paths, json_path);
9540 } else {
9541 vty_out(vty, "\n");
9542
9543 if (safi == SAFI_EVPN) {
9544 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9545 /* XXX - add these params to the json out */
9546 vty_out(vty, "%*s", 20, " ");
9547 vty_out(vty, "ESI:%s",
9548 esi_to_str(&attr->esi, esi_buf,
9549 sizeof(esi_buf)));
9550
9551 vty_out(vty, "\n");
9552 }
9553 if (attr->flag &
9554 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9555 vty_out(vty, "%*s", 20, " ");
9556 vty_out(vty, "%s\n",
9557 bgp_attr_get_ecommunity(attr)->str);
9558 }
9559 }
9560
9561 #ifdef ENABLE_BGP_VNC
9562 /* prints an additional line, indented, with VNC info, if
9563 * present */
9564 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9565 rfapi_vty_out_vncinfo(vty, p, path, safi);
9566 #endif
9567 }
9568 }
9569
9570 /* called from terminal list command */
9571 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9572 const struct prefix *p, struct attr *attr, safi_t safi,
9573 bool use_json, json_object *json_ar, bool wide)
9574 {
9575 json_object *json_status = NULL;
9576 json_object *json_net = NULL;
9577 int len;
9578 char buff[BUFSIZ];
9579
9580 /* Route status display. */
9581 if (use_json) {
9582 json_status = json_object_new_object();
9583 json_net = json_object_new_object();
9584 } else {
9585 vty_out(vty, " *");
9586 vty_out(vty, ">");
9587 vty_out(vty, " ");
9588 }
9589
9590 /* print prefix and mask */
9591 if (use_json) {
9592 if (safi == SAFI_EVPN)
9593 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9594 else if (p->family == AF_INET || p->family == AF_INET6) {
9595 json_object_string_add(
9596 json_net, "addrPrefix",
9597 inet_ntop(p->family, &p->u.prefix, buff,
9598 BUFSIZ));
9599 json_object_int_add(json_net, "prefixLen",
9600 p->prefixlen);
9601 json_object_string_addf(json_net, "network", "%pFX", p);
9602 }
9603 } else
9604 route_vty_out_route(dest, p, vty, NULL, wide);
9605
9606 /* Print attribute */
9607 if (attr) {
9608 if (use_json) {
9609 if (p->family == AF_INET &&
9610 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9611 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9612 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9613 json_object_string_addf(
9614 json_net, "nextHop", "%pI4",
9615 &attr->mp_nexthop_global_in);
9616 else
9617 json_object_string_addf(
9618 json_net, "nextHop", "%pI4",
9619 &attr->nexthop);
9620 } else if (p->family == AF_INET6 ||
9621 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9622 json_object_string_addf(
9623 json_net, "nextHopGlobal", "%pI6",
9624 &attr->mp_nexthop_global);
9625 } else if (p->family == AF_EVPN &&
9626 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9627 json_object_string_addf(
9628 json_net, "nextHop", "%pI4",
9629 &attr->mp_nexthop_global_in);
9630 }
9631
9632 if (attr->flag
9633 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9634 json_object_int_add(json_net, "metric",
9635 attr->med);
9636
9637 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9638 json_object_int_add(json_net, "locPrf",
9639 attr->local_pref);
9640
9641 json_object_int_add(json_net, "weight", attr->weight);
9642
9643 /* Print aspath */
9644 if (attr->aspath)
9645 json_object_string_add(json_net, "path",
9646 attr->aspath->str);
9647
9648 /* Print origin */
9649 #if CONFDATE > 20231208
9650 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9651 #endif
9652 json_object_string_add(json_net, "bgpOriginCode",
9653 bgp_origin_str[attr->origin]);
9654 json_object_string_add(
9655 json_net, "origin",
9656 bgp_origin_long_str[attr->origin]);
9657 } else {
9658 if (p->family == AF_INET &&
9659 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9660 safi == SAFI_EVPN ||
9661 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9662 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9663 || safi == SAFI_EVPN)
9664 vty_out(vty, "%-16pI4",
9665 &attr->mp_nexthop_global_in);
9666 else if (wide)
9667 vty_out(vty, "%-41pI4", &attr->nexthop);
9668 else
9669 vty_out(vty, "%-16pI4", &attr->nexthop);
9670 } else if (p->family == AF_INET6 ||
9671 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9672 len = vty_out(vty, "%pI6",
9673 &attr->mp_nexthop_global);
9674 len = wide ? (41 - len) : (16 - len);
9675 if (len < 1)
9676 vty_out(vty, "\n%*s", 36, " ");
9677 else
9678 vty_out(vty, "%*s", len, " ");
9679 }
9680 if (attr->flag
9681 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9682 if (wide)
9683 vty_out(vty, "%7u", attr->med);
9684 else
9685 vty_out(vty, "%10u", attr->med);
9686 else if (wide)
9687 vty_out(vty, " ");
9688 else
9689 vty_out(vty, " ");
9690
9691 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9692 vty_out(vty, "%7u", attr->local_pref);
9693 else
9694 vty_out(vty, " ");
9695
9696 vty_out(vty, "%7u ", attr->weight);
9697
9698 /* Print aspath */
9699 if (attr->aspath)
9700 aspath_print_vty(vty, attr->aspath);
9701
9702 /* Print origin */
9703 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9704 }
9705 }
9706 if (use_json) {
9707 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9708
9709 #if CONFDATE > 20231208
9710 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9711 #endif
9712 json_object_boolean_true_add(json_status, "*");
9713 json_object_boolean_true_add(json_status, ">");
9714 json_object_boolean_true_add(json_net, "valid");
9715 json_object_boolean_true_add(json_net, "best");
9716
9717 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9718 json_object_boolean_true_add(json_status, "=");
9719 json_object_boolean_true_add(json_net, "multipath");
9720 }
9721 json_object_object_add(json_net, "appliedStatusSymbols",
9722 json_status);
9723 json_object_object_addf(json_ar, json_net, "%pFX", p);
9724 } else
9725 vty_out(vty, "\n");
9726 }
9727
9728 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9729 struct bgp_path_info *path, int display, safi_t safi,
9730 json_object *json)
9731 {
9732 json_object *json_out = NULL;
9733 struct attr *attr;
9734 mpls_label_t label = MPLS_INVALID_LABEL;
9735
9736 if (!path->extra)
9737 return;
9738
9739 if (json)
9740 json_out = json_object_new_object();
9741
9742 /* short status lead text */
9743 route_vty_short_status_out(vty, path, p, json_out);
9744
9745 /* print prefix and mask */
9746 if (json == NULL) {
9747 if (!display)
9748 route_vty_out_route(path->net, p, vty, NULL, false);
9749 else
9750 vty_out(vty, "%*s", 17, " ");
9751 }
9752
9753 /* Print attribute */
9754 attr = path->attr;
9755 if (((p->family == AF_INET) &&
9756 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9757 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9758 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9759 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9760 || safi == SAFI_EVPN) {
9761 if (json)
9762 json_object_string_addf(
9763 json_out, "mpNexthopGlobalIn", "%pI4",
9764 &attr->mp_nexthop_global_in);
9765 else
9766 vty_out(vty, "%-16pI4",
9767 &attr->mp_nexthop_global_in);
9768 } else {
9769 if (json)
9770 json_object_string_addf(json_out, "nexthop",
9771 "%pI4", &attr->nexthop);
9772 else
9773 vty_out(vty, "%-16pI4", &attr->nexthop);
9774 }
9775 } else if (((p->family == AF_INET6) &&
9776 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9777 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9778 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9779 char buf_a[512];
9780
9781 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9782 if (json)
9783 json_object_string_addf(
9784 json_out, "mpNexthopGlobalIn", "%pI6",
9785 &attr->mp_nexthop_global);
9786 else
9787 vty_out(vty, "%s",
9788 inet_ntop(AF_INET6,
9789 &attr->mp_nexthop_global,
9790 buf_a, sizeof(buf_a)));
9791 } else if (attr->mp_nexthop_len
9792 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9793 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9794 &attr->mp_nexthop_global,
9795 &attr->mp_nexthop_local);
9796 if (json)
9797 json_object_string_add(json_out,
9798 "mpNexthopGlobalLocal",
9799 buf_a);
9800 else
9801 vty_out(vty, "%s", buf_a);
9802 }
9803 }
9804
9805 label = decode_label(&path->extra->label[0]);
9806
9807 if (bgp_is_valid_label(&label)) {
9808 if (json) {
9809 json_object_int_add(json_out, "notag", label);
9810 json_object_array_add(json, json_out);
9811 } else {
9812 vty_out(vty, "notag/%d", label);
9813 vty_out(vty, "\n");
9814 }
9815 } else if (!json)
9816 vty_out(vty, "\n");
9817 }
9818
9819 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9820 struct bgp_path_info *path, int display,
9821 json_object *json_paths)
9822 {
9823 struct attr *attr;
9824 json_object *json_path = NULL;
9825 json_object *json_nexthop = NULL;
9826 json_object *json_overlay = NULL;
9827
9828 if (!path->extra)
9829 return;
9830
9831 if (json_paths) {
9832 json_path = json_object_new_object();
9833 json_overlay = json_object_new_object();
9834 json_nexthop = json_object_new_object();
9835 }
9836
9837 /* short status lead text */
9838 route_vty_short_status_out(vty, path, p, json_path);
9839
9840 /* print prefix and mask */
9841 if (!display)
9842 route_vty_out_route(path->net, p, vty, json_path, false);
9843 else
9844 vty_out(vty, "%*s", 17, " ");
9845
9846 /* Print attribute */
9847 attr = path->attr;
9848 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9849
9850 switch (af) {
9851 case AF_INET:
9852 if (!json_path) {
9853 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9854 } else {
9855 json_object_string_addf(json_nexthop, "ip", "%pI4",
9856 &attr->mp_nexthop_global_in);
9857
9858 json_object_string_add(json_nexthop, "afi", "ipv4");
9859
9860 json_object_object_add(json_path, "nexthop",
9861 json_nexthop);
9862 }
9863 break;
9864 case AF_INET6:
9865 if (!json_path) {
9866 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9867 &attr->mp_nexthop_local);
9868 } else {
9869 json_object_string_addf(json_nexthop, "ipv6Global",
9870 "%pI6",
9871 &attr->mp_nexthop_global);
9872
9873 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9874 "%pI6",
9875 &attr->mp_nexthop_local);
9876
9877 json_object_string_add(json_nexthop, "afi", "ipv6");
9878
9879 json_object_object_add(json_path, "nexthop",
9880 json_nexthop);
9881 }
9882 break;
9883 default:
9884 if (!json_path) {
9885 vty_out(vty, "?");
9886 } else {
9887 json_object_string_add(json_nexthop, "error",
9888 "Unsupported address-family");
9889 }
9890 }
9891
9892 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9893
9894 if (!json_path)
9895 vty_out(vty, "/%pIA", &eo->gw_ip);
9896 else
9897 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9898
9899 if (bgp_attr_get_ecommunity(attr)) {
9900 char *mac = NULL;
9901 struct ecommunity_val *routermac = ecommunity_lookup(
9902 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9903 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9904
9905 if (routermac)
9906 mac = ecom_mac2str((char *)routermac->val);
9907 if (mac) {
9908 if (!json_path) {
9909 vty_out(vty, "/%s", mac);
9910 } else {
9911 json_object_string_add(json_overlay, "rmac",
9912 mac);
9913 }
9914 XFREE(MTYPE_TMP, mac);
9915 }
9916 }
9917
9918 if (!json_path) {
9919 vty_out(vty, "\n");
9920 } else {
9921 json_object_object_add(json_path, "overlay", json_overlay);
9922
9923 json_object_array_add(json_paths, json_path);
9924 }
9925 }
9926
9927 /* dampening route */
9928 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9929 struct bgp_path_info *path, int display,
9930 afi_t afi, safi_t safi, bool use_json,
9931 json_object *json_paths)
9932 {
9933 struct attr *attr = path->attr;
9934 int len;
9935 char timebuf[BGP_UPTIME_LEN];
9936 json_object *json_path = NULL;
9937
9938 if (use_json)
9939 json_path = json_object_new_object();
9940
9941 /* short status lead text */
9942 route_vty_short_status_out(vty, path, p, json_path);
9943
9944 /* print prefix and mask */
9945 if (!use_json) {
9946 if (!display)
9947 route_vty_out_route(path->net, p, vty, NULL, false);
9948 else
9949 vty_out(vty, "%*s", 17, " ");
9950
9951 len = vty_out(vty, "%s", path->peer->host);
9952 len = 17 - len;
9953
9954 if (len < 1)
9955 vty_out(vty, "\n%*s", 34, " ");
9956 else
9957 vty_out(vty, "%*s", len, " ");
9958
9959 vty_out(vty, "%s ",
9960 bgp_damp_reuse_time_vty(vty, path, timebuf,
9961 BGP_UPTIME_LEN, afi, safi,
9962 use_json, NULL));
9963
9964 if (attr->aspath)
9965 aspath_print_vty(vty, attr->aspath);
9966
9967 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9968
9969 vty_out(vty, "\n");
9970 } else {
9971 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9972 safi, use_json, json_path);
9973
9974 if (attr->aspath)
9975 json_object_string_add(json_path, "asPath",
9976 attr->aspath->str);
9977
9978 json_object_string_add(json_path, "origin",
9979 bgp_origin_str[attr->origin]);
9980 json_object_string_add(json_path, "peerHost", path->peer->host);
9981
9982 json_object_array_add(json_paths, json_path);
9983 }
9984 }
9985
9986 /* flap route */
9987 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9988 struct bgp_path_info *path, int display,
9989 afi_t afi, safi_t safi, bool use_json,
9990 json_object *json_paths)
9991 {
9992 struct attr *attr = path->attr;
9993 struct bgp_damp_info *bdi;
9994 char timebuf[BGP_UPTIME_LEN];
9995 int len;
9996 json_object *json_path = NULL;
9997
9998 if (!path->extra)
9999 return;
10000
10001 if (use_json)
10002 json_path = json_object_new_object();
10003
10004 bdi = path->extra->damp_info;
10005
10006 /* short status lead text */
10007 route_vty_short_status_out(vty, path, p, json_path);
10008
10009 if (!use_json) {
10010 if (!display)
10011 route_vty_out_route(path->net, p, vty, NULL, false);
10012 else
10013 vty_out(vty, "%*s", 17, " ");
10014
10015 len = vty_out(vty, "%s", path->peer->host);
10016 len = 16 - len;
10017 if (len < 1)
10018 vty_out(vty, "\n%*s", 33, " ");
10019 else
10020 vty_out(vty, "%*s", len, " ");
10021
10022 len = vty_out(vty, "%d", bdi->flap);
10023 len = 5 - len;
10024 if (len < 1)
10025 vty_out(vty, " ");
10026 else
10027 vty_out(vty, "%*s", len, " ");
10028
10029 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10030 BGP_UPTIME_LEN, 0, NULL));
10031
10032 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10033 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10034 vty_out(vty, "%s ",
10035 bgp_damp_reuse_time_vty(vty, path, timebuf,
10036 BGP_UPTIME_LEN, afi,
10037 safi, use_json, NULL));
10038 else
10039 vty_out(vty, "%*s ", 8, " ");
10040
10041 if (attr->aspath)
10042 aspath_print_vty(vty, attr->aspath);
10043
10044 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10045
10046 vty_out(vty, "\n");
10047 } else {
10048 json_object_string_add(json_path, "peerHost", path->peer->host);
10049 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10050
10051 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10052 json_path);
10053
10054 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10055 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10056 bgp_damp_reuse_time_vty(vty, path, timebuf,
10057 BGP_UPTIME_LEN, afi, safi,
10058 use_json, json_path);
10059
10060 if (attr->aspath)
10061 json_object_string_add(json_path, "asPath",
10062 attr->aspath->str);
10063
10064 json_object_string_add(json_path, "origin",
10065 bgp_origin_str[attr->origin]);
10066
10067 json_object_array_add(json_paths, json_path);
10068 }
10069 }
10070
10071 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10072 int *first, const char *header,
10073 json_object *json_adv_to)
10074 {
10075 json_object *json_peer = NULL;
10076
10077 if (json_adv_to) {
10078 /* 'advertised-to' is a dictionary of peers we have advertised
10079 * this
10080 * prefix too. The key is the peer's IP or swpX, the value is
10081 * the
10082 * hostname if we know it and "" if not.
10083 */
10084 json_peer = json_object_new_object();
10085
10086 if (peer->hostname)
10087 json_object_string_add(json_peer, "hostname",
10088 peer->hostname);
10089
10090 if (peer->conf_if)
10091 json_object_object_add(json_adv_to, peer->conf_if,
10092 json_peer);
10093 else
10094 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10095 &peer->su);
10096 } else {
10097 if (*first) {
10098 vty_out(vty, "%s", header);
10099 *first = 0;
10100 }
10101
10102 if (peer->hostname
10103 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10104 if (peer->conf_if)
10105 vty_out(vty, " %s(%s)", peer->hostname,
10106 peer->conf_if);
10107 else
10108 vty_out(vty, " %s(%pSU)", peer->hostname,
10109 &peer->su);
10110 } else {
10111 if (peer->conf_if)
10112 vty_out(vty, " %s", peer->conf_if);
10113 else
10114 vty_out(vty, " %pSU", &peer->su);
10115 }
10116 }
10117 }
10118
10119 static void route_vty_out_tx_ids(struct vty *vty,
10120 struct bgp_addpath_info_data *d)
10121 {
10122 int i;
10123
10124 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10125 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10126 d->addpath_tx_id[i],
10127 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10128 }
10129 }
10130
10131 static void route_vty_out_detail_es_info(struct vty *vty,
10132 struct bgp_path_info *pi,
10133 struct attr *attr,
10134 json_object *json_path)
10135 {
10136 char esi_buf[ESI_STR_LEN];
10137 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10138 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10139 ATTR_ES_PEER_ROUTER);
10140 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10141 ATTR_ES_PEER_ACTIVE);
10142 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10143 ATTR_ES_PEER_PROXY);
10144 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10145 if (json_path) {
10146 json_object *json_es_info = NULL;
10147
10148 json_object_string_add(
10149 json_path, "esi",
10150 esi_buf);
10151 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10152 json_es_info = json_object_new_object();
10153 if (es_local)
10154 json_object_boolean_true_add(
10155 json_es_info, "localEs");
10156 if (peer_active)
10157 json_object_boolean_true_add(
10158 json_es_info, "peerActive");
10159 if (peer_proxy)
10160 json_object_boolean_true_add(
10161 json_es_info, "peerProxy");
10162 if (peer_router)
10163 json_object_boolean_true_add(
10164 json_es_info, "peerRouter");
10165 if (attr->mm_sync_seqnum)
10166 json_object_int_add(
10167 json_es_info, "peerSeq",
10168 attr->mm_sync_seqnum);
10169 json_object_object_add(
10170 json_path, "es_info",
10171 json_es_info);
10172 }
10173 } else {
10174 if (bgp_evpn_attr_is_sync(attr))
10175 vty_out(vty,
10176 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10177 esi_buf,
10178 es_local ? "local-es":"",
10179 peer_proxy ? "proxy " : "",
10180 peer_active ? "active ":"",
10181 peer_router ? "router ":"",
10182 attr->mm_sync_seqnum);
10183 else
10184 vty_out(vty, " ESI %s %s\n",
10185 esi_buf,
10186 es_local ? "local-es":"");
10187 }
10188 }
10189
10190 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10191 const struct prefix *p, struct bgp_path_info *path,
10192 afi_t afi, safi_t safi,
10193 enum rpki_states rpki_curr_state,
10194 json_object *json_paths)
10195 {
10196 char buf[INET6_ADDRSTRLEN];
10197 char tag_buf[30];
10198 struct attr *attr = path->attr;
10199 time_t tbuf;
10200 json_object *json_bestpath = NULL;
10201 json_object *json_cluster_list = NULL;
10202 json_object *json_cluster_list_list = NULL;
10203 json_object *json_ext_community = NULL;
10204 json_object *json_last_update = NULL;
10205 json_object *json_pmsi = NULL;
10206 json_object *json_nexthop_global = NULL;
10207 json_object *json_nexthop_ll = NULL;
10208 json_object *json_nexthops = NULL;
10209 json_object *json_path = NULL;
10210 json_object *json_peer = NULL;
10211 json_object *json_string = NULL;
10212 json_object *json_adv_to = NULL;
10213 int first = 0;
10214 struct listnode *node, *nnode;
10215 struct peer *peer;
10216 bool addpath_capable;
10217 int has_adj;
10218 unsigned int first_as;
10219 bool nexthop_self =
10220 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10221 int i;
10222 char *nexthop_hostname =
10223 bgp_nexthop_hostname(path->peer, path->nexthop);
10224 uint32_t ttl = 0;
10225 uint32_t bos = 0;
10226 uint32_t exp = 0;
10227 mpls_label_t label = MPLS_INVALID_LABEL;
10228 tag_buf[0] = '\0';
10229 struct bgp_path_info *bpi_ultimate =
10230 bgp_get_imported_bpi_ultimate(path);
10231
10232 if (json_paths) {
10233 json_path = json_object_new_object();
10234 json_peer = json_object_new_object();
10235 json_nexthop_global = json_object_new_object();
10236 }
10237
10238 if (safi == SAFI_EVPN) {
10239 if (!json_paths)
10240 vty_out(vty, " Route %pFX", p);
10241 }
10242
10243 if (path->extra) {
10244 if (path->extra && path->extra->num_labels) {
10245 bgp_evpn_label2str(path->extra->label,
10246 path->extra->num_labels, tag_buf,
10247 sizeof(tag_buf));
10248 }
10249 if (safi == SAFI_EVPN) {
10250 if (!json_paths) {
10251 if (tag_buf[0] != '\0')
10252 vty_out(vty, " VNI %s", tag_buf);
10253 } else {
10254 if (tag_buf[0])
10255 json_object_string_add(json_path, "vni",
10256 tag_buf);
10257 }
10258 }
10259 }
10260
10261 if (safi == SAFI_EVPN
10262 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10263 char gwip_buf[INET6_ADDRSTRLEN];
10264
10265 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10266 sizeof(gwip_buf));
10267
10268 if (json_paths)
10269 json_object_string_add(json_path, "gatewayIP",
10270 gwip_buf);
10271 else
10272 vty_out(vty, " Gateway IP %s", gwip_buf);
10273 }
10274
10275 if (safi == SAFI_EVPN && !json_path)
10276 vty_out(vty, "\n");
10277
10278
10279 if (path->extra && path->extra->parent && !json_paths) {
10280 struct bgp_path_info *parent_ri;
10281 struct bgp_dest *dest, *pdest;
10282
10283 parent_ri = (struct bgp_path_info *)path->extra->parent;
10284 dest = parent_ri->net;
10285 if (dest && dest->pdest) {
10286 pdest = dest->pdest;
10287 if (is_pi_family_evpn(parent_ri)) {
10288 vty_out(vty, " Imported from ");
10289 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10290 (struct prefix_rd *)bgp_dest_get_prefix(
10291 pdest));
10292 vty_out(vty, ":%pFX, VNI %s",
10293 (struct prefix_evpn *)
10294 bgp_dest_get_prefix(dest),
10295 tag_buf);
10296 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10297 vty_out(vty, ", L3NHG %s",
10298 CHECK_FLAG(
10299 attr->es_flags,
10300 ATTR_ES_L3_NHG_ACTIVE)
10301 ? "active"
10302 : "inactive");
10303 vty_out(vty, "\n");
10304
10305 } else {
10306 vty_out(vty, " Imported from ");
10307 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10308 (struct prefix_rd *)bgp_dest_get_prefix(
10309 pdest));
10310 vty_out(vty, ":%pFX\n",
10311 (struct prefix_evpn *)
10312 bgp_dest_get_prefix(dest));
10313 }
10314 }
10315 }
10316
10317 /* Line1 display AS-path, Aggregator */
10318 if (attr->aspath) {
10319 if (json_paths) {
10320 if (!attr->aspath->json)
10321 aspath_str_update(attr->aspath, true);
10322 json_object_lock(attr->aspath->json);
10323 json_object_object_add(json_path, "aspath",
10324 attr->aspath->json);
10325 } else {
10326 if (attr->aspath->segments)
10327 vty_out(vty, " %s", attr->aspath->str);
10328 else
10329 vty_out(vty, " Local");
10330 }
10331 }
10332
10333 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10334 if (json_paths)
10335 json_object_boolean_true_add(json_path, "removed");
10336 else
10337 vty_out(vty, ", (removed)");
10338 }
10339
10340 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10341 if (json_paths)
10342 json_object_boolean_true_add(json_path, "stale");
10343 else
10344 vty_out(vty, ", (stale)");
10345 }
10346
10347 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10348 if (json_paths) {
10349 json_object_int_add(json_path, "aggregatorAs",
10350 attr->aggregator_as);
10351 json_object_string_addf(json_path, "aggregatorId",
10352 "%pI4", &attr->aggregator_addr);
10353 } else {
10354 vty_out(vty, ", (aggregated by %u %pI4)",
10355 attr->aggregator_as, &attr->aggregator_addr);
10356 }
10357 }
10358
10359 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10360 PEER_FLAG_REFLECTOR_CLIENT)) {
10361 if (json_paths)
10362 json_object_boolean_true_add(json_path,
10363 "rxedFromRrClient");
10364 else
10365 vty_out(vty, ", (Received from a RR-client)");
10366 }
10367
10368 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10369 PEER_FLAG_RSERVER_CLIENT)) {
10370 if (json_paths)
10371 json_object_boolean_true_add(json_path,
10372 "rxedFromRsClient");
10373 else
10374 vty_out(vty, ", (Received from a RS-client)");
10375 }
10376
10377 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10378 if (json_paths)
10379 json_object_boolean_true_add(json_path,
10380 "dampeningHistoryEntry");
10381 else
10382 vty_out(vty, ", (history entry)");
10383 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10384 if (json_paths)
10385 json_object_boolean_true_add(json_path,
10386 "dampeningSuppressed");
10387 else
10388 vty_out(vty, ", (suppressed due to dampening)");
10389 }
10390
10391 if (!json_paths)
10392 vty_out(vty, "\n");
10393
10394 /* Line2 display Next-hop, Neighbor, Router-id */
10395 /* Display the nexthop */
10396
10397 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10398 p->family == AF_EVPN) &&
10399 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10400 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10401 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10402 || safi == SAFI_EVPN) {
10403 if (json_paths) {
10404 json_object_string_addf(
10405 json_nexthop_global, "ip", "%pI4",
10406 &attr->mp_nexthop_global_in);
10407
10408 if (path->peer->hostname)
10409 json_object_string_add(
10410 json_nexthop_global, "hostname",
10411 path->peer->hostname);
10412 } else {
10413 if (nexthop_hostname)
10414 vty_out(vty, " %pI4(%s)",
10415 &attr->mp_nexthop_global_in,
10416 nexthop_hostname);
10417 else
10418 vty_out(vty, " %pI4",
10419 &attr->mp_nexthop_global_in);
10420 }
10421 } else {
10422 if (json_paths) {
10423 json_object_string_addf(json_nexthop_global,
10424 "ip", "%pI4",
10425 &attr->nexthop);
10426
10427 if (path->peer->hostname)
10428 json_object_string_add(
10429 json_nexthop_global, "hostname",
10430 path->peer->hostname);
10431 } else {
10432 if (nexthop_hostname)
10433 vty_out(vty, " %pI4(%s)",
10434 &attr->nexthop,
10435 nexthop_hostname);
10436 else
10437 vty_out(vty, " %pI4",
10438 &attr->nexthop);
10439 }
10440 }
10441
10442 if (json_paths)
10443 json_object_string_add(json_nexthop_global, "afi",
10444 "ipv4");
10445 } else {
10446 if (json_paths) {
10447 json_object_string_addf(json_nexthop_global, "ip",
10448 "%pI6",
10449 &attr->mp_nexthop_global);
10450
10451 if (path->peer->hostname)
10452 json_object_string_add(json_nexthop_global,
10453 "hostname",
10454 path->peer->hostname);
10455
10456 json_object_string_add(json_nexthop_global, "afi",
10457 "ipv6");
10458 json_object_string_add(json_nexthop_global, "scope",
10459 "global");
10460 } else {
10461 if (nexthop_hostname)
10462 vty_out(vty, " %pI6(%s)",
10463 &attr->mp_nexthop_global,
10464 nexthop_hostname);
10465 else
10466 vty_out(vty, " %pI6",
10467 &attr->mp_nexthop_global);
10468 }
10469 }
10470
10471 /* Display the IGP cost or 'inaccessible' */
10472 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10473 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10474
10475 if (json_paths) {
10476 json_object_boolean_false_add(json_nexthop_global,
10477 "accessible");
10478 json_object_boolean_add(json_nexthop_global,
10479 "importCheckEnabled", import);
10480 } else {
10481 vty_out(vty, " (inaccessible%s)",
10482 import ? ", import-check enabled" : "");
10483 }
10484 } else {
10485 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10486 if (json_paths)
10487 json_object_int_add(
10488 json_nexthop_global, "metric",
10489 bpi_ultimate->extra->igpmetric);
10490 else
10491 vty_out(vty, " (metric %u)",
10492 bpi_ultimate->extra->igpmetric);
10493 }
10494
10495 /* IGP cost is 0, display this only for json */
10496 else {
10497 if (json_paths)
10498 json_object_int_add(json_nexthop_global,
10499 "metric", 0);
10500 }
10501
10502 if (json_paths)
10503 json_object_boolean_true_add(json_nexthop_global,
10504 "accessible");
10505 }
10506
10507 /* Display peer "from" output */
10508 /* This path was originated locally */
10509 if (path->peer == bgp->peer_self) {
10510
10511 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10512 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10513 if (json_paths)
10514 json_object_string_add(json_peer, "peerId",
10515 "0.0.0.0");
10516 else
10517 vty_out(vty, " from 0.0.0.0 ");
10518 } else {
10519 if (json_paths)
10520 json_object_string_add(json_peer, "peerId",
10521 "::");
10522 else
10523 vty_out(vty, " from :: ");
10524 }
10525
10526 if (json_paths)
10527 json_object_string_addf(json_peer, "routerId", "%pI4",
10528 &bgp->router_id);
10529 else
10530 vty_out(vty, "(%pI4)", &bgp->router_id);
10531 }
10532
10533 /* We RXed this path from one of our peers */
10534 else {
10535
10536 if (json_paths) {
10537 json_object_string_addf(json_peer, "peerId", "%pSU",
10538 &path->peer->su);
10539 json_object_string_addf(json_peer, "routerId", "%pI4",
10540 &path->peer->remote_id);
10541
10542 if (path->peer->hostname)
10543 json_object_string_add(json_peer, "hostname",
10544 path->peer->hostname);
10545
10546 if (path->peer->domainname)
10547 json_object_string_add(json_peer, "domainname",
10548 path->peer->domainname);
10549
10550 if (path->peer->conf_if)
10551 json_object_string_add(json_peer, "interface",
10552 path->peer->conf_if);
10553 } else {
10554 if (path->peer->conf_if) {
10555 if (path->peer->hostname
10556 && CHECK_FLAG(path->peer->bgp->flags,
10557 BGP_FLAG_SHOW_HOSTNAME))
10558 vty_out(vty, " from %s(%s)",
10559 path->peer->hostname,
10560 path->peer->conf_if);
10561 else
10562 vty_out(vty, " from %s",
10563 path->peer->conf_if);
10564 } else {
10565 if (path->peer->hostname
10566 && CHECK_FLAG(path->peer->bgp->flags,
10567 BGP_FLAG_SHOW_HOSTNAME))
10568 vty_out(vty, " from %s(%s)",
10569 path->peer->hostname,
10570 path->peer->host);
10571 else
10572 vty_out(vty, " from %pSU",
10573 &path->peer->su);
10574 }
10575
10576 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10577 vty_out(vty, " (%pI4)", &attr->originator_id);
10578 else
10579 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10580 }
10581 }
10582
10583 /*
10584 * Note when vrfid of nexthop is different from that of prefix
10585 */
10586 if (path->extra && path->extra->bgp_orig) {
10587 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10588
10589 if (json_paths) {
10590 const char *vn;
10591
10592 if (path->extra->bgp_orig->inst_type
10593 == BGP_INSTANCE_TYPE_DEFAULT)
10594 vn = VRF_DEFAULT_NAME;
10595 else
10596 vn = path->extra->bgp_orig->name;
10597
10598 json_object_string_add(json_path, "nhVrfName", vn);
10599
10600 if (nexthop_vrfid == VRF_UNKNOWN) {
10601 json_object_int_add(json_path, "nhVrfId", -1);
10602 } else {
10603 json_object_int_add(json_path, "nhVrfId",
10604 (int)nexthop_vrfid);
10605 }
10606 } else {
10607 if (nexthop_vrfid == VRF_UNKNOWN)
10608 vty_out(vty, " vrf ?");
10609 else {
10610 struct vrf *vrf;
10611
10612 vrf = vrf_lookup_by_id(nexthop_vrfid);
10613 vty_out(vty, " vrf %s(%u)",
10614 VRF_LOGNAME(vrf), nexthop_vrfid);
10615 }
10616 }
10617 }
10618
10619 if (nexthop_self) {
10620 if (json_paths) {
10621 json_object_boolean_true_add(json_path,
10622 "announceNexthopSelf");
10623 } else {
10624 vty_out(vty, " announce-nh-self");
10625 }
10626 }
10627
10628 if (!json_paths)
10629 vty_out(vty, "\n");
10630
10631 /* display the link-local nexthop */
10632 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10633 if (json_paths) {
10634 json_nexthop_ll = json_object_new_object();
10635 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10636 &attr->mp_nexthop_local);
10637
10638 if (path->peer->hostname)
10639 json_object_string_add(json_nexthop_ll,
10640 "hostname",
10641 path->peer->hostname);
10642
10643 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10644 json_object_string_add(json_nexthop_ll, "scope",
10645 "link-local");
10646
10647 json_object_boolean_true_add(json_nexthop_ll,
10648 "accessible");
10649
10650 if (!attr->mp_nexthop_prefer_global)
10651 json_object_boolean_true_add(json_nexthop_ll,
10652 "used");
10653 else
10654 json_object_boolean_true_add(
10655 json_nexthop_global, "used");
10656 } else {
10657 vty_out(vty, " (%s) %s\n",
10658 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10659 buf, INET6_ADDRSTRLEN),
10660 attr->mp_nexthop_prefer_global
10661 ? "(prefer-global)"
10662 : "(used)");
10663 }
10664 }
10665 /* If we do not have a link-local nexthop then we must flag the
10666 global as "used" */
10667 else {
10668 if (json_paths)
10669 json_object_boolean_true_add(json_nexthop_global,
10670 "used");
10671 }
10672
10673 if (safi == SAFI_EVPN &&
10674 bgp_evpn_is_esi_valid(&attr->esi)) {
10675 route_vty_out_detail_es_info(vty, path, attr, json_path);
10676 }
10677
10678 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10679 * Int/Ext/Local, Atomic, best */
10680 if (json_paths)
10681 json_object_string_add(json_path, "origin",
10682 bgp_origin_long_str[attr->origin]);
10683 else
10684 vty_out(vty, " Origin %s",
10685 bgp_origin_long_str[attr->origin]);
10686
10687 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10688 if (json_paths)
10689 json_object_int_add(json_path, "metric", attr->med);
10690 else
10691 vty_out(vty, ", metric %u", attr->med);
10692 }
10693
10694 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10695 if (json_paths)
10696 json_object_int_add(json_path, "locPrf",
10697 attr->local_pref);
10698 else
10699 vty_out(vty, ", localpref %u", attr->local_pref);
10700 }
10701
10702 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10703 if (json_paths)
10704 json_object_int_add(json_path, "aigpMetric",
10705 bgp_attr_get_aigp_metric(attr));
10706 else
10707 vty_out(vty, ", aigp-metric %" PRIu64,
10708 bgp_attr_get_aigp_metric(attr));
10709 }
10710
10711 if (attr->weight != 0) {
10712 if (json_paths)
10713 json_object_int_add(json_path, "weight", attr->weight);
10714 else
10715 vty_out(vty, ", weight %u", attr->weight);
10716 }
10717
10718 if (attr->tag != 0) {
10719 if (json_paths)
10720 json_object_int_add(json_path, "tag", attr->tag);
10721 else
10722 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10723 }
10724
10725 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10726 if (json_paths)
10727 json_object_boolean_false_add(json_path, "valid");
10728 else
10729 vty_out(vty, ", invalid");
10730 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10731 if (json_paths)
10732 json_object_boolean_true_add(json_path, "valid");
10733 else
10734 vty_out(vty, ", valid");
10735 }
10736
10737 if (json_paths)
10738 json_object_int_add(json_path, "version", bn->version);
10739
10740 if (path->peer != bgp->peer_self) {
10741 if (path->peer->as == path->peer->local_as) {
10742 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10743 if (json_paths)
10744 json_object_string_add(
10745 json_peer, "type",
10746 "confed-internal");
10747 else
10748 vty_out(vty, ", confed-internal");
10749 } else {
10750 if (json_paths)
10751 json_object_string_add(
10752 json_peer, "type", "internal");
10753 else
10754 vty_out(vty, ", internal");
10755 }
10756 } else {
10757 if (bgp_confederation_peers_check(bgp,
10758 path->peer->as)) {
10759 if (json_paths)
10760 json_object_string_add(
10761 json_peer, "type",
10762 "confed-external");
10763 else
10764 vty_out(vty, ", confed-external");
10765 } else {
10766 if (json_paths)
10767 json_object_string_add(
10768 json_peer, "type", "external");
10769 else
10770 vty_out(vty, ", external");
10771 }
10772 }
10773 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10774 if (json_paths) {
10775 json_object_boolean_true_add(json_path, "aggregated");
10776 json_object_boolean_true_add(json_path, "local");
10777 } else {
10778 vty_out(vty, ", aggregated, local");
10779 }
10780 } else if (path->type != ZEBRA_ROUTE_BGP) {
10781 if (json_paths)
10782 json_object_boolean_true_add(json_path, "sourced");
10783 else
10784 vty_out(vty, ", sourced");
10785 } else {
10786 if (json_paths) {
10787 json_object_boolean_true_add(json_path, "sourced");
10788 json_object_boolean_true_add(json_path, "local");
10789 } else {
10790 vty_out(vty, ", sourced, local");
10791 }
10792 }
10793
10794 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10795 if (json_paths)
10796 json_object_boolean_true_add(json_path,
10797 "atomicAggregate");
10798 else
10799 vty_out(vty, ", atomic-aggregate");
10800 }
10801
10802 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10803 if (json_paths)
10804 json_object_int_add(json_path, "otc", attr->otc);
10805 else
10806 vty_out(vty, ", otc %u", attr->otc);
10807 }
10808
10809 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10810 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10811 && bgp_path_info_mpath_count(path))) {
10812 if (json_paths)
10813 json_object_boolean_true_add(json_path, "multipath");
10814 else
10815 vty_out(vty, ", multipath");
10816 }
10817
10818 // Mark the bestpath(s)
10819 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10820 first_as = aspath_get_first_as(attr->aspath);
10821
10822 if (json_paths) {
10823 if (!json_bestpath)
10824 json_bestpath = json_object_new_object();
10825 json_object_int_add(json_bestpath, "bestpathFromAs",
10826 first_as);
10827 } else {
10828 if (first_as)
10829 vty_out(vty, ", bestpath-from-AS %u", first_as);
10830 else
10831 vty_out(vty, ", bestpath-from-AS Local");
10832 }
10833 }
10834
10835 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10836 if (json_paths) {
10837 if (!json_bestpath)
10838 json_bestpath = json_object_new_object();
10839 json_object_boolean_true_add(json_bestpath, "overall");
10840 json_object_string_add(
10841 json_bestpath, "selectionReason",
10842 bgp_path_selection_reason2str(bn->reason));
10843 } else {
10844 vty_out(vty, ", best");
10845 vty_out(vty, " (%s)",
10846 bgp_path_selection_reason2str(bn->reason));
10847 }
10848 }
10849
10850 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10851 if (json_paths)
10852 json_object_string_add(
10853 json_path, "rpkiValidationState",
10854 bgp_rpki_validation2str(rpki_curr_state));
10855 else
10856 vty_out(vty, ", rpki validation-state: %s",
10857 bgp_rpki_validation2str(rpki_curr_state));
10858 }
10859
10860 if (json_bestpath)
10861 json_object_object_add(json_path, "bestpath", json_bestpath);
10862
10863 if (!json_paths)
10864 vty_out(vty, "\n");
10865
10866 /* Line 4 display Community */
10867 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10868 if (json_paths) {
10869 if (!bgp_attr_get_community(attr)->json)
10870 community_str(bgp_attr_get_community(attr),
10871 true, true);
10872 json_object_lock(bgp_attr_get_community(attr)->json);
10873 json_object_object_add(
10874 json_path, "community",
10875 bgp_attr_get_community(attr)->json);
10876 } else {
10877 vty_out(vty, " Community: %s\n",
10878 bgp_attr_get_community(attr)->str);
10879 }
10880 }
10881
10882 /* Line 5 display Extended-community */
10883 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10884 if (json_paths) {
10885 json_ext_community = json_object_new_object();
10886 json_object_string_add(
10887 json_ext_community, "string",
10888 bgp_attr_get_ecommunity(attr)->str);
10889 json_object_object_add(json_path, "extendedCommunity",
10890 json_ext_community);
10891 } else {
10892 vty_out(vty, " Extended Community: %s\n",
10893 bgp_attr_get_ecommunity(attr)->str);
10894 }
10895 }
10896
10897 /* Line 6 display Large community */
10898 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10899 if (json_paths) {
10900 if (!bgp_attr_get_lcommunity(attr)->json)
10901 lcommunity_str(bgp_attr_get_lcommunity(attr),
10902 true, true);
10903 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10904 json_object_object_add(
10905 json_path, "largeCommunity",
10906 bgp_attr_get_lcommunity(attr)->json);
10907 } else {
10908 vty_out(vty, " Large Community: %s\n",
10909 bgp_attr_get_lcommunity(attr)->str);
10910 }
10911 }
10912
10913 /* Line 7 display Originator, Cluster-id */
10914 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10915 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10916 char buf[BUFSIZ] = {0};
10917
10918 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10919 if (json_paths)
10920 json_object_string_addf(json_path,
10921 "originatorId", "%pI4",
10922 &attr->originator_id);
10923 else
10924 vty_out(vty, " Originator: %pI4",
10925 &attr->originator_id);
10926 }
10927
10928 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10929 struct cluster_list *cluster =
10930 bgp_attr_get_cluster(attr);
10931 int i;
10932
10933 if (json_paths) {
10934 json_cluster_list = json_object_new_object();
10935 json_cluster_list_list =
10936 json_object_new_array();
10937
10938 for (i = 0; i < cluster->length / 4; i++) {
10939 json_string = json_object_new_string(
10940 inet_ntop(AF_INET,
10941 &cluster->list[i],
10942 buf, sizeof(buf)));
10943 json_object_array_add(
10944 json_cluster_list_list,
10945 json_string);
10946 }
10947
10948 /*
10949 * struct cluster_list does not have
10950 * "str" variable like aspath and community
10951 * do. Add this someday if someone asks
10952 * for it.
10953 * json_object_string_add(json_cluster_list,
10954 * "string", cluster->str);
10955 */
10956 json_object_object_add(json_cluster_list,
10957 "list",
10958 json_cluster_list_list);
10959 json_object_object_add(json_path, "clusterList",
10960 json_cluster_list);
10961 } else {
10962 vty_out(vty, ", Cluster list: ");
10963
10964 for (i = 0; i < cluster->length / 4; i++) {
10965 vty_out(vty, "%pI4 ",
10966 &cluster->list[i]);
10967 }
10968 }
10969 }
10970
10971 if (!json_paths)
10972 vty_out(vty, "\n");
10973 }
10974
10975 if (path->extra && path->extra->damp_info)
10976 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10977
10978 /* Remote Label */
10979 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10980 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10981 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10982 &bos);
10983
10984 if (json_paths)
10985 json_object_int_add(json_path, "remoteLabel", label);
10986 else
10987 vty_out(vty, " Remote label: %d\n", label);
10988 }
10989
10990 /* Remote SID */
10991 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10992 if (json_paths)
10993 json_object_string_addf(json_path, "remoteSid", "%pI6",
10994 &path->extra->sid[0].sid);
10995 else
10996 vty_out(vty, " Remote SID: %pI6\n",
10997 &path->extra->sid[0].sid);
10998 }
10999
11000 /* Label Index */
11001 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11002 if (json_paths)
11003 json_object_int_add(json_path, "labelIndex",
11004 attr->label_index);
11005 else
11006 vty_out(vty, " Label Index: %d\n",
11007 attr->label_index);
11008 }
11009
11010 /* Line 8 display Addpath IDs */
11011 if (path->addpath_rx_id
11012 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11013 if (json_paths) {
11014 json_object_int_add(json_path, "addpathRxId",
11015 path->addpath_rx_id);
11016
11017 /* Keep backwards compatibility with the old API
11018 * by putting TX All's ID in the old field
11019 */
11020 json_object_int_add(
11021 json_path, "addpathTxId",
11022 path->tx_addpath
11023 .addpath_tx_id[BGP_ADDPATH_ALL]);
11024
11025 /* ... but create a specific field for each
11026 * strategy
11027 */
11028 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11029 json_object_int_add(
11030 json_path,
11031 bgp_addpath_names(i)->id_json_name,
11032 path->tx_addpath.addpath_tx_id[i]);
11033 }
11034 } else {
11035 vty_out(vty, " AddPath ID: RX %u, ",
11036 path->addpath_rx_id);
11037
11038 route_vty_out_tx_ids(vty, &path->tx_addpath);
11039 }
11040 }
11041
11042 /* If we used addpath to TX a non-bestpath we need to display
11043 * "Advertised to" on a path-by-path basis
11044 */
11045 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11046 first = 1;
11047
11048 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11049 addpath_capable =
11050 bgp_addpath_encode_tx(peer, afi, safi);
11051 has_adj = bgp_adj_out_lookup(
11052 peer, path->net,
11053 bgp_addpath_id_for_peer(peer, afi, safi,
11054 &path->tx_addpath));
11055
11056 if ((addpath_capable && has_adj)
11057 || (!addpath_capable && has_adj
11058 && CHECK_FLAG(path->flags,
11059 BGP_PATH_SELECTED))) {
11060 if (json_path && !json_adv_to)
11061 json_adv_to = json_object_new_object();
11062
11063 route_vty_out_advertised_to(
11064 vty, peer, &first,
11065 " Advertised to:", json_adv_to);
11066 }
11067 }
11068
11069 if (json_path) {
11070 if (json_adv_to) {
11071 json_object_object_add(
11072 json_path, "advertisedTo", json_adv_to);
11073 }
11074 } else {
11075 if (!first) {
11076 vty_out(vty, "\n");
11077 }
11078 }
11079 }
11080
11081 /* Line 9 display Uptime */
11082 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11083 if (json_paths) {
11084 json_last_update = json_object_new_object();
11085 json_object_int_add(json_last_update, "epoch", tbuf);
11086 json_object_string_add(json_last_update, "string",
11087 ctime(&tbuf));
11088 json_object_object_add(json_path, "lastUpdate",
11089 json_last_update);
11090 } else
11091 vty_out(vty, " Last update: %s", ctime(&tbuf));
11092
11093 /* Line 10 display PMSI tunnel attribute, if present */
11094 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11095 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11096 bgp_attr_get_pmsi_tnl_type(attr),
11097 PMSI_TNLTYPE_STR_DEFAULT);
11098
11099 if (json_paths) {
11100 json_pmsi = json_object_new_object();
11101 json_object_string_add(json_pmsi, "tunnelType", str);
11102 json_object_int_add(json_pmsi, "label",
11103 label2vni(&attr->label));
11104 json_object_object_add(json_path, "pmsi", json_pmsi);
11105 } else
11106 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11107 str, label2vni(&attr->label));
11108 }
11109
11110 if (path->peer->t_gr_restart &&
11111 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11112 unsigned long gr_remaining =
11113 event_timer_remain_second(path->peer->t_gr_restart);
11114
11115 if (json_paths) {
11116 json_object_int_add(json_path,
11117 "gracefulRestartSecondsRemaining",
11118 gr_remaining);
11119 } else
11120 vty_out(vty,
11121 " Time until Graceful Restart stale route deleted: %lu\n",
11122 gr_remaining);
11123 }
11124
11125 if (path->peer->t_llgr_stale[afi][safi] &&
11126 bgp_attr_get_community(attr) &&
11127 community_include(bgp_attr_get_community(attr),
11128 COMMUNITY_LLGR_STALE)) {
11129 unsigned long llgr_remaining = event_timer_remain_second(
11130 path->peer->t_llgr_stale[afi][safi]);
11131
11132 if (json_paths) {
11133 json_object_int_add(json_path, "llgrSecondsRemaining",
11134 llgr_remaining);
11135 } else
11136 vty_out(vty,
11137 " Time until Long-lived stale route deleted: %lu\n",
11138 llgr_remaining);
11139 }
11140
11141 /* Output some debug about internal state of the dest flags */
11142 if (json_paths) {
11143 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11144 json_object_boolean_true_add(json_path, "processScheduled");
11145 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11146 json_object_boolean_true_add(json_path, "userCleared");
11147 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11148 json_object_boolean_true_add(json_path, "labelChanged");
11149 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11150 json_object_boolean_true_add(json_path, "registeredForLabel");
11151 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11152 json_object_boolean_true_add(json_path, "selectDefered");
11153 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11154 json_object_boolean_true_add(json_path, "fibInstalled");
11155 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11156 json_object_boolean_true_add(json_path, "fibPending");
11157
11158 if (json_nexthop_global || json_nexthop_ll) {
11159 json_nexthops = json_object_new_array();
11160
11161 if (json_nexthop_global)
11162 json_object_array_add(json_nexthops,
11163 json_nexthop_global);
11164
11165 if (json_nexthop_ll)
11166 json_object_array_add(json_nexthops,
11167 json_nexthop_ll);
11168
11169 json_object_object_add(json_path, "nexthops",
11170 json_nexthops);
11171 }
11172
11173 json_object_object_add(json_path, "peer", json_peer);
11174 json_object_array_add(json_paths, json_path);
11175 }
11176 }
11177
11178 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11179 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11180 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11181
11182 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11183 afi_t afi, safi_t safi, enum bgp_show_type type,
11184 bool use_json);
11185 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11186 const char *comstr, int exact, afi_t afi,
11187 safi_t safi, uint16_t show_flags);
11188
11189 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11190 struct bgp_table *table, enum bgp_show_type type,
11191 void *output_arg, const char *rd, int is_last,
11192 unsigned long *output_cum, unsigned long *total_cum,
11193 unsigned long *json_header_depth, uint16_t show_flags,
11194 enum rpki_states rpki_target_state)
11195 {
11196 struct bgp_path_info *pi;
11197 struct bgp_dest *dest;
11198 bool header = true;
11199 bool json_detail_header = false;
11200 int display;
11201 unsigned long output_count = 0;
11202 unsigned long total_count = 0;
11203 struct prefix *p;
11204 json_object *json_paths = NULL;
11205 int first = 1;
11206 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11207 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11208 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11209 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11210 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11211
11212 if (output_cum && *output_cum != 0)
11213 header = false;
11214
11215 if (use_json && !*json_header_depth) {
11216 if (all)
11217 *json_header_depth = 1;
11218 else {
11219 vty_out(vty, "{\n");
11220 *json_header_depth = 2;
11221 }
11222 vty_out(vty,
11223 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11224 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11225 " \"localAS\": ",
11226 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11227 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11228 ? VRF_DEFAULT_NAME
11229 : bgp->name,
11230 table->version, &bgp->router_id,
11231 bgp->default_local_pref);
11232 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11233 ((bgp->asnotation == ASNOTATION_DOT) &&
11234 (bgp->as < UINT16_MAX)))
11235 vty_out(vty, "%u", bgp->as);
11236 else {
11237 vty_out(vty, "\"");
11238 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11239 vty_out(vty, "\"");
11240 }
11241 vty_out(vty, ",\n \"routes\": { ");
11242 if (rd) {
11243 vty_out(vty, " \"routeDistinguishers\" : {");
11244 ++*json_header_depth;
11245 }
11246 }
11247
11248 if (use_json && rd) {
11249 vty_out(vty, " \"%s\" : { ", rd);
11250 }
11251
11252 /* Check for 'json detail', where we need header output once per dest */
11253 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11254 type != bgp_show_type_damp_neighbor &&
11255 type != bgp_show_type_flap_statistics &&
11256 type != bgp_show_type_flap_neighbor)
11257 json_detail_header = true;
11258
11259 /* Start processing of routes. */
11260 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11261 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11262 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11263 bool json_detail_header_used = false;
11264
11265 pi = bgp_dest_get_bgp_path_info(dest);
11266 if (pi == NULL)
11267 continue;
11268
11269 display = 0;
11270 if (use_json)
11271 json_paths = json_object_new_array();
11272 else
11273 json_paths = NULL;
11274
11275 for (; pi; pi = pi->next) {
11276 struct community *picomm = NULL;
11277
11278 picomm = bgp_attr_get_community(pi->attr);
11279
11280 total_count++;
11281
11282 if (type == bgp_show_type_prefix_version) {
11283 uint32_t version =
11284 strtoul(output_arg, NULL, 10);
11285 if (dest->version < version)
11286 continue;
11287 }
11288
11289 if (type == bgp_show_type_community_alias) {
11290 char *alias = output_arg;
11291 char **communities;
11292 int num;
11293 bool found = false;
11294
11295 if (picomm) {
11296 frrstr_split(picomm->str, " ",
11297 &communities, &num);
11298 for (int i = 0; i < num; i++) {
11299 const char *com2alias =
11300 bgp_community2alias(
11301 communities[i]);
11302 if (!found
11303 && strcmp(alias, com2alias)
11304 == 0)
11305 found = true;
11306 XFREE(MTYPE_TMP,
11307 communities[i]);
11308 }
11309 XFREE(MTYPE_TMP, communities);
11310 }
11311
11312 if (!found &&
11313 bgp_attr_get_lcommunity(pi->attr)) {
11314 frrstr_split(bgp_attr_get_lcommunity(
11315 pi->attr)
11316 ->str,
11317 " ", &communities, &num);
11318 for (int i = 0; i < num; i++) {
11319 const char *com2alias =
11320 bgp_community2alias(
11321 communities[i]);
11322 if (!found
11323 && strcmp(alias, com2alias)
11324 == 0)
11325 found = true;
11326 XFREE(MTYPE_TMP,
11327 communities[i]);
11328 }
11329 XFREE(MTYPE_TMP, communities);
11330 }
11331
11332 if (!found)
11333 continue;
11334 }
11335
11336 if (type == bgp_show_type_rpki) {
11337 if (dest_p->family == AF_INET
11338 || dest_p->family == AF_INET6)
11339 rpki_curr_state = hook_call(
11340 bgp_rpki_prefix_status,
11341 pi->peer, pi->attr, dest_p);
11342 if (rpki_target_state != RPKI_NOT_BEING_USED
11343 && rpki_curr_state != rpki_target_state)
11344 continue;
11345 }
11346
11347 if (type == bgp_show_type_flap_statistics
11348 || type == bgp_show_type_flap_neighbor
11349 || type == bgp_show_type_dampend_paths
11350 || type == bgp_show_type_damp_neighbor) {
11351 if (!(pi->extra && pi->extra->damp_info))
11352 continue;
11353 }
11354 if (type == bgp_show_type_regexp) {
11355 regex_t *regex = output_arg;
11356
11357 if (bgp_regexec(regex, pi->attr->aspath)
11358 == REG_NOMATCH)
11359 continue;
11360 }
11361 if (type == bgp_show_type_prefix_list) {
11362 struct prefix_list *plist = output_arg;
11363
11364 if (prefix_list_apply(plist, dest_p)
11365 != PREFIX_PERMIT)
11366 continue;
11367 }
11368 if (type == bgp_show_type_access_list) {
11369 struct access_list *alist = output_arg;
11370
11371 if (access_list_apply(alist, dest_p) !=
11372 FILTER_PERMIT)
11373 continue;
11374 }
11375 if (type == bgp_show_type_filter_list) {
11376 struct as_list *as_list = output_arg;
11377
11378 if (as_list_apply(as_list, pi->attr->aspath)
11379 != AS_FILTER_PERMIT)
11380 continue;
11381 }
11382 if (type == bgp_show_type_route_map) {
11383 struct route_map *rmap = output_arg;
11384 struct bgp_path_info path;
11385 struct bgp_path_info_extra extra;
11386 struct attr dummy_attr = {};
11387 route_map_result_t ret;
11388
11389 dummy_attr = *pi->attr;
11390
11391 prep_for_rmap_apply(&path, &extra, dest, pi,
11392 pi->peer, &dummy_attr);
11393
11394 ret = route_map_apply(rmap, dest_p, &path);
11395 bgp_attr_flush(&dummy_attr);
11396 if (ret == RMAP_DENYMATCH)
11397 continue;
11398 }
11399 if (type == bgp_show_type_neighbor
11400 || type == bgp_show_type_flap_neighbor
11401 || type == bgp_show_type_damp_neighbor) {
11402 union sockunion *su = output_arg;
11403
11404 if (pi->peer == NULL
11405 || pi->peer->su_remote == NULL
11406 || !sockunion_same(pi->peer->su_remote, su))
11407 continue;
11408 }
11409 if (type == bgp_show_type_cidr_only) {
11410 uint32_t destination;
11411
11412 destination = ntohl(dest_p->u.prefix4.s_addr);
11413 if (IN_CLASSC(destination)
11414 && dest_p->prefixlen == 24)
11415 continue;
11416 if (IN_CLASSB(destination)
11417 && dest_p->prefixlen == 16)
11418 continue;
11419 if (IN_CLASSA(destination)
11420 && dest_p->prefixlen == 8)
11421 continue;
11422 }
11423 if (type == bgp_show_type_prefix_longer) {
11424 p = output_arg;
11425 if (!prefix_match(p, dest_p))
11426 continue;
11427 }
11428 if (type == bgp_show_type_community_all) {
11429 if (!picomm)
11430 continue;
11431 }
11432 if (type == bgp_show_type_community) {
11433 struct community *com = output_arg;
11434
11435 if (!picomm || !community_match(picomm, com))
11436 continue;
11437 }
11438 if (type == bgp_show_type_community_exact) {
11439 struct community *com = output_arg;
11440
11441 if (!picomm || !community_cmp(picomm, com))
11442 continue;
11443 }
11444 if (type == bgp_show_type_community_list) {
11445 struct community_list *list = output_arg;
11446
11447 if (!community_list_match(picomm, list))
11448 continue;
11449 }
11450 if (type == bgp_show_type_community_list_exact) {
11451 struct community_list *list = output_arg;
11452
11453 if (!community_list_exact_match(picomm, list))
11454 continue;
11455 }
11456 if (type == bgp_show_type_lcommunity) {
11457 struct lcommunity *lcom = output_arg;
11458
11459 if (!bgp_attr_get_lcommunity(pi->attr) ||
11460 !lcommunity_match(
11461 bgp_attr_get_lcommunity(pi->attr),
11462 lcom))
11463 continue;
11464 }
11465
11466 if (type == bgp_show_type_lcommunity_exact) {
11467 struct lcommunity *lcom = output_arg;
11468
11469 if (!bgp_attr_get_lcommunity(pi->attr) ||
11470 !lcommunity_cmp(
11471 bgp_attr_get_lcommunity(pi->attr),
11472 lcom))
11473 continue;
11474 }
11475 if (type == bgp_show_type_lcommunity_list) {
11476 struct community_list *list = output_arg;
11477
11478 if (!lcommunity_list_match(
11479 bgp_attr_get_lcommunity(pi->attr),
11480 list))
11481 continue;
11482 }
11483 if (type
11484 == bgp_show_type_lcommunity_list_exact) {
11485 struct community_list *list = output_arg;
11486
11487 if (!lcommunity_list_exact_match(
11488 bgp_attr_get_lcommunity(pi->attr),
11489 list))
11490 continue;
11491 }
11492 if (type == bgp_show_type_lcommunity_all) {
11493 if (!bgp_attr_get_lcommunity(pi->attr))
11494 continue;
11495 }
11496 if (type == bgp_show_type_dampend_paths
11497 || type == bgp_show_type_damp_neighbor) {
11498 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11499 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11500 continue;
11501 }
11502 if (type == bgp_show_type_self_originated) {
11503 if (pi->peer != bgp->peer_self)
11504 continue;
11505 }
11506
11507 if (!use_json && header) {
11508 vty_out(vty,
11509 "BGP table version is %" PRIu64
11510 ", local router ID is %pI4, vrf id ",
11511 table->version, &bgp->router_id);
11512 if (bgp->vrf_id == VRF_UNKNOWN)
11513 vty_out(vty, "%s", VRFID_NONE_STR);
11514 else
11515 vty_out(vty, "%u", bgp->vrf_id);
11516 vty_out(vty, "\n");
11517 vty_out(vty, "Default local pref %u, ",
11518 bgp->default_local_pref);
11519 vty_out(vty, "local AS ");
11520 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11521 &bgp->as);
11522 vty_out(vty, "\n");
11523 if (!detail_routes) {
11524 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11525 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11526 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11527 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11528 }
11529 if (type == bgp_show_type_dampend_paths
11530 || type == bgp_show_type_damp_neighbor)
11531 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11532 else if (type == bgp_show_type_flap_statistics
11533 || type == bgp_show_type_flap_neighbor)
11534 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11535 else if (!detail_routes)
11536 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11537 : BGP_SHOW_HEADER));
11538 header = false;
11539
11540 }
11541 if (rd != NULL && !display && !output_count) {
11542 if (!use_json)
11543 vty_out(vty,
11544 "Route Distinguisher: %s\n",
11545 rd);
11546 }
11547 if (type == bgp_show_type_dampend_paths
11548 || type == bgp_show_type_damp_neighbor)
11549 damp_route_vty_out(vty, dest_p, pi, display,
11550 AFI_IP, safi, use_json,
11551 json_paths);
11552 else if (type == bgp_show_type_flap_statistics
11553 || type == bgp_show_type_flap_neighbor)
11554 flap_route_vty_out(vty, dest_p, pi, display,
11555 AFI_IP, safi, use_json,
11556 json_paths);
11557 else {
11558 if (detail_routes || detail_json) {
11559 const struct prefix_rd *prd = NULL;
11560
11561 if (dest->pdest)
11562 prd = bgp_rd_from_dest(
11563 dest->pdest, safi);
11564
11565 if (!use_json)
11566 route_vty_out_detail_header(
11567 vty, bgp, dest,
11568 bgp_dest_get_prefix(
11569 dest),
11570 prd, table->afi, safi,
11571 NULL, false);
11572
11573 route_vty_out_detail(
11574 vty, bgp, dest, dest_p, pi,
11575 family2afi(dest_p->family),
11576 safi, RPKI_NOT_BEING_USED,
11577 json_paths);
11578 } else {
11579 route_vty_out(vty, dest_p, pi, display,
11580 safi, json_paths, wide);
11581 }
11582 }
11583 display++;
11584 }
11585
11586 if (display) {
11587 output_count++;
11588 if (!use_json)
11589 continue;
11590
11591 /* encode prefix */
11592 if (dest_p->family == AF_FLOWSPEC) {
11593 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11594
11595
11596 bgp_fs_nlri_get_string(
11597 (unsigned char *)
11598 dest_p->u.prefix_flowspec.ptr,
11599 dest_p->u.prefix_flowspec.prefixlen,
11600 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11601 family2afi(dest_p->u
11602 .prefix_flowspec.family));
11603 if (first)
11604 vty_out(vty, "\"%s/%d\": ", retstr,
11605 dest_p->u.prefix_flowspec
11606 .prefixlen);
11607 else
11608 vty_out(vty, ",\"%s/%d\": ", retstr,
11609 dest_p->u.prefix_flowspec
11610 .prefixlen);
11611 } else {
11612 if (first)
11613 vty_out(vty, "\"%pFX\": ", dest_p);
11614 else
11615 vty_out(vty, ",\"%pFX\": ", dest_p);
11616 }
11617
11618 /* This is used for 'json detail' vty keywords.
11619 *
11620 * In plain 'json' the per-prefix header is encoded
11621 * as a standalone dictionary in the first json_paths
11622 * array element:
11623 * "<prefix>": [{header}, {path-1}, {path-N}]
11624 * (which is confusing and borderline broken)
11625 *
11626 * For 'json detail' this changes the value
11627 * of each prefix-key to be a dictionary where each
11628 * header item has its own key, and json_paths is
11629 * tucked under the "paths" key:
11630 * "<prefix>": {
11631 * "<header-key-1>": <header-val-1>,
11632 * "<header-key-N>": <header-val-N>,
11633 * "paths": [{path-1}, {path-N}]
11634 * }
11635 */
11636 if (json_detail_header && json_paths != NULL) {
11637 const struct prefix_rd *prd;
11638
11639 /* Start per-prefix dictionary */
11640 vty_out(vty, "{\n");
11641
11642 prd = bgp_rd_from_dest(dest, safi);
11643
11644 route_vty_out_detail_header(
11645 vty, bgp, dest,
11646 bgp_dest_get_prefix(dest), prd,
11647 table->afi, safi, json_paths, true);
11648
11649 vty_out(vty, "\"paths\": ");
11650 json_detail_header_used = true;
11651 }
11652
11653 /*
11654 * We are using no_pretty here because under
11655 * extremely high settings( say lots and lots of
11656 * routes with lots and lots of ways to reach
11657 * that route via different paths ) this can
11658 * save several minutes of output when FRR
11659 * is run on older cpu's or more underperforming
11660 * routers out there
11661 */
11662 vty_json_no_pretty(vty, json_paths);
11663
11664 /* End per-prefix dictionary */
11665 if (json_detail_header_used)
11666 vty_out(vty, "} ");
11667
11668 json_paths = NULL;
11669 first = 0;
11670 } else
11671 json_object_free(json_paths);
11672 }
11673
11674 if (output_cum) {
11675 output_count += *output_cum;
11676 *output_cum = output_count;
11677 }
11678 if (total_cum) {
11679 total_count += *total_cum;
11680 *total_cum = total_count;
11681 }
11682 if (use_json) {
11683 if (rd) {
11684 vty_out(vty, " }%s ", (is_last ? "" : ","));
11685 }
11686 if (is_last) {
11687 unsigned long i;
11688 for (i = 0; i < *json_header_depth; ++i)
11689 vty_out(vty, " } ");
11690 if (!all)
11691 vty_out(vty, "\n");
11692 }
11693 } else {
11694 if (is_last) {
11695 /* No route is displayed */
11696 if (output_count == 0) {
11697 if (type == bgp_show_type_normal)
11698 vty_out(vty,
11699 "No BGP prefixes displayed, %ld exist\n",
11700 total_count);
11701 } else
11702 vty_out(vty,
11703 "\nDisplayed %ld routes and %ld total paths\n",
11704 output_count, total_count);
11705 }
11706 }
11707
11708 return CMD_SUCCESS;
11709 }
11710
11711 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11712 struct bgp_table *table, struct prefix_rd *prd_match,
11713 enum bgp_show_type type, void *output_arg,
11714 uint16_t show_flags)
11715 {
11716 struct bgp_dest *dest, *next;
11717 unsigned long output_cum = 0;
11718 unsigned long total_cum = 0;
11719 unsigned long json_header_depth = 0;
11720 struct bgp_table *itable;
11721 bool show_msg;
11722 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11723
11724 show_msg = (!use_json && type == bgp_show_type_normal);
11725
11726 for (dest = bgp_table_top(table); dest; dest = next) {
11727 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11728
11729 next = bgp_route_next(dest);
11730 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11731 continue;
11732
11733 itable = bgp_dest_get_bgp_table_info(dest);
11734 if (itable != NULL) {
11735 struct prefix_rd prd;
11736 char rd[RD_ADDRSTRLEN];
11737
11738 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11739 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11740 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11741 rd, next == NULL, &output_cum,
11742 &total_cum, &json_header_depth,
11743 show_flags, RPKI_NOT_BEING_USED);
11744 if (next == NULL)
11745 show_msg = false;
11746 }
11747 }
11748 if (show_msg) {
11749 if (output_cum == 0)
11750 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11751 total_cum);
11752 else
11753 vty_out(vty,
11754 "\nDisplayed %ld routes and %ld total paths\n",
11755 output_cum, total_cum);
11756 } else {
11757 if (use_json && output_cum == 0)
11758 vty_out(vty, "{}\n");
11759 }
11760 return CMD_SUCCESS;
11761 }
11762
11763 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11764 enum bgp_show_type type, void *output_arg,
11765 uint16_t show_flags, enum rpki_states rpki_target_state)
11766 {
11767 struct bgp_table *table;
11768 unsigned long json_header_depth = 0;
11769 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11770
11771 if (bgp == NULL) {
11772 bgp = bgp_get_default();
11773 }
11774
11775 if (bgp == NULL) {
11776 if (!use_json)
11777 vty_out(vty, "No BGP process is configured\n");
11778 else
11779 vty_out(vty, "{}\n");
11780 return CMD_WARNING;
11781 }
11782
11783 /* Labeled-unicast routes live in the unicast table. */
11784 if (safi == SAFI_LABELED_UNICAST)
11785 safi = SAFI_UNICAST;
11786
11787 table = bgp->rib[afi][safi];
11788 /* use MPLS and ENCAP specific shows until they are merged */
11789 if (safi == SAFI_MPLS_VPN) {
11790 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11791 output_arg, show_flags);
11792 }
11793
11794 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11795 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11796 output_arg, use_json,
11797 1, NULL, NULL);
11798 }
11799
11800 if (safi == SAFI_EVPN)
11801 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11802
11803 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11804 NULL, NULL, &json_header_depth, show_flags,
11805 rpki_target_state);
11806 }
11807
11808 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11809 safi_t safi, uint16_t show_flags)
11810 {
11811 struct listnode *node, *nnode;
11812 struct bgp *bgp;
11813 int is_first = 1;
11814 bool route_output = false;
11815 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11816
11817 if (use_json)
11818 vty_out(vty, "{\n");
11819
11820 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11821 route_output = true;
11822 if (use_json) {
11823 if (!is_first)
11824 vty_out(vty, ",\n");
11825 else
11826 is_first = 0;
11827
11828 vty_out(vty, "\"%s\":",
11829 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11830 ? VRF_DEFAULT_NAME
11831 : bgp->name);
11832 } else {
11833 vty_out(vty, "\nInstance %s:\n",
11834 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11835 ? VRF_DEFAULT_NAME
11836 : bgp->name);
11837 }
11838 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11839 show_flags, RPKI_NOT_BEING_USED);
11840 }
11841
11842 if (use_json)
11843 vty_out(vty, "}\n");
11844 else if (!route_output)
11845 vty_out(vty, "%% BGP instance not found\n");
11846 }
11847
11848 /* Header of detailed BGP route information */
11849 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11850 struct bgp_dest *dest, const struct prefix *p,
11851 const struct prefix_rd *prd, afi_t afi,
11852 safi_t safi, json_object *json,
11853 bool incremental_print)
11854 {
11855 struct bgp_path_info *pi;
11856 struct peer *peer;
11857 struct listnode *node, *nnode;
11858 char buf1[RD_ADDRSTRLEN];
11859 int count = 0;
11860 int best = 0;
11861 int suppress = 0;
11862 int accept_own = 0;
11863 int route_filter_translated_v4 = 0;
11864 int route_filter_v4 = 0;
11865 int route_filter_translated_v6 = 0;
11866 int route_filter_v6 = 0;
11867 int llgr_stale = 0;
11868 int no_llgr = 0;
11869 int accept_own_nexthop = 0;
11870 int blackhole = 0;
11871 int no_export = 0;
11872 int no_advertise = 0;
11873 int local_as = 0;
11874 int no_peer = 0;
11875 int first = 1;
11876 int has_valid_label = 0;
11877 mpls_label_t label = 0;
11878 json_object *json_adv_to = NULL;
11879 uint32_t ttl = 0;
11880 uint32_t bos = 0;
11881 uint32_t exp = 0;
11882
11883 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11884
11885 has_valid_label = bgp_is_valid_label(&label);
11886
11887 if (safi == SAFI_EVPN) {
11888 if (!json) {
11889 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11890 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11891 bgp->asnotation)
11892 : "",
11893 prd ? ":" : "", (struct prefix_evpn *)p);
11894 } else {
11895 json_object_string_add(
11896 json, "rd",
11897 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11898 bgp->asnotation)
11899 : "");
11900 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11901 }
11902 } else {
11903 if (!json) {
11904 vty_out(vty,
11905 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11906 "\n",
11907 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11908 ? prefix_rd2str(prd, buf1,
11909 sizeof(buf1),
11910 bgp->asnotation)
11911 : ""),
11912 safi == SAFI_MPLS_VPN ? ":" : "", p,
11913 dest->version);
11914
11915 } else {
11916 if (incremental_print) {
11917 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11918 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11919 dest->version);
11920 } else {
11921 json_object_string_addf(json, "prefix", "%pFX",
11922 p);
11923 json_object_int_add(json, "version",
11924 dest->version);
11925 }
11926 }
11927 }
11928
11929 if (has_valid_label) {
11930 if (json) {
11931 if (incremental_print)
11932 vty_out(vty, "\"localLabel\": \"%u\",\n",
11933 label);
11934 else
11935 json_object_int_add(json, "localLabel", label);
11936 } else
11937 vty_out(vty, "Local label: %d\n", label);
11938 }
11939
11940 if (!json)
11941 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11942 vty_out(vty, "not allocated\n");
11943
11944 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11945 struct community *picomm = NULL;
11946
11947 picomm = bgp_attr_get_community(pi->attr);
11948
11949 count++;
11950 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11951 best = count;
11952 if (bgp_path_suppressed(pi))
11953 suppress = 1;
11954
11955 if (!picomm)
11956 continue;
11957
11958 no_advertise += community_include(
11959 picomm, COMMUNITY_NO_ADVERTISE);
11960 no_export +=
11961 community_include(picomm, COMMUNITY_NO_EXPORT);
11962 local_as +=
11963 community_include(picomm, COMMUNITY_LOCAL_AS);
11964 accept_own +=
11965 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11966 route_filter_translated_v4 += community_include(
11967 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11968 route_filter_translated_v6 += community_include(
11969 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11970 route_filter_v4 += community_include(
11971 picomm, COMMUNITY_ROUTE_FILTER_v4);
11972 route_filter_v6 += community_include(
11973 picomm, COMMUNITY_ROUTE_FILTER_v6);
11974 llgr_stale +=
11975 community_include(picomm, COMMUNITY_LLGR_STALE);
11976 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11977 accept_own_nexthop += community_include(
11978 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11979 blackhole +=
11980 community_include(picomm, COMMUNITY_BLACKHOLE);
11981 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11982 }
11983 }
11984
11985 if (!json) {
11986 vty_out(vty, "Paths: (%d available", count);
11987 if (best) {
11988 vty_out(vty, ", best #%d", best);
11989 if (safi == SAFI_UNICAST) {
11990 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11991 vty_out(vty, ", table %s",
11992 VRF_DEFAULT_NAME);
11993 else
11994 vty_out(vty, ", vrf %s",
11995 bgp->name);
11996 }
11997 } else
11998 vty_out(vty, ", no best path");
11999
12000 if (accept_own)
12001 vty_out(vty,
12002 ", accept own local route exported and imported in different VRF");
12003 else if (route_filter_translated_v4)
12004 vty_out(vty,
12005 ", mark translated RTs for VPNv4 route filtering");
12006 else if (route_filter_v4)
12007 vty_out(vty,
12008 ", attach RT as-is for VPNv4 route filtering");
12009 else if (route_filter_translated_v6)
12010 vty_out(vty,
12011 ", mark translated RTs for VPNv6 route filtering");
12012 else if (route_filter_v6)
12013 vty_out(vty,
12014 ", attach RT as-is for VPNv6 route filtering");
12015 else if (llgr_stale)
12016 vty_out(vty,
12017 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
12018 else if (no_llgr)
12019 vty_out(vty,
12020 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
12021 else if (accept_own_nexthop)
12022 vty_out(vty,
12023 ", accept local nexthop");
12024 else if (blackhole)
12025 vty_out(vty, ", inform peer to blackhole prefix");
12026 else if (no_export)
12027 vty_out(vty, ", not advertised to EBGP peer");
12028 else if (no_advertise)
12029 vty_out(vty, ", not advertised to any peer");
12030 else if (local_as)
12031 vty_out(vty, ", not advertised outside local AS");
12032 else if (no_peer)
12033 vty_out(vty,
12034 ", inform EBGP peer not to advertise to their EBGP peers");
12035
12036 if (suppress)
12037 vty_out(vty,
12038 ", Advertisements suppressed by an aggregate.");
12039 vty_out(vty, ")\n");
12040 }
12041
12042 /* If we are not using addpath then we can display Advertised to and
12043 * that will
12044 * show what peers we advertised the bestpath to. If we are using
12045 * addpath
12046 * though then we must display Advertised to on a path-by-path basis. */
12047 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12048 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12049 if (bgp_adj_out_lookup(peer, dest, 0)) {
12050 if (json && !json_adv_to)
12051 json_adv_to = json_object_new_object();
12052
12053 route_vty_out_advertised_to(
12054 vty, peer, &first,
12055 " Advertised to non peer-group peers:\n ",
12056 json_adv_to);
12057 }
12058 }
12059
12060 if (json && json_adv_to) {
12061 if (incremental_print) {
12062 vty_out(vty, "\"advertisedTo\": ");
12063 vty_json(vty, json_adv_to);
12064 vty_out(vty, ",");
12065 } else
12066 json_object_object_add(json, "advertisedTo",
12067 json_adv_to);
12068 } else {
12069 if (!json && first)
12070 vty_out(vty, " Not advertised to any peer");
12071 vty_out(vty, "\n");
12072 }
12073 }
12074 }
12075
12076 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12077 struct bgp_dest *bgp_node, struct vty *vty,
12078 struct bgp *bgp, afi_t afi, safi_t safi,
12079 json_object *json, enum bgp_path_type pathtype,
12080 int *display, enum rpki_states rpki_target_state)
12081 {
12082 struct bgp_path_info *pi;
12083 int header = 1;
12084 json_object *json_header = NULL;
12085 json_object *json_paths = NULL;
12086 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12087
12088 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12089 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12090
12091 if (p->family == AF_INET || p->family == AF_INET6)
12092 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12093 pi->peer, pi->attr, p);
12094
12095 if (rpki_target_state != RPKI_NOT_BEING_USED
12096 && rpki_curr_state != rpki_target_state)
12097 continue;
12098
12099 if (json && !json_paths) {
12100 /* Instantiate json_paths only if path is valid */
12101 json_paths = json_object_new_array();
12102 if (pfx_rd)
12103 json_header = json_object_new_object();
12104 else
12105 json_header = json;
12106 }
12107
12108 if (header) {
12109 route_vty_out_detail_header(
12110 vty, bgp, bgp_node,
12111 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12112 safi, json_header, false);
12113 header = 0;
12114 }
12115 (*display)++;
12116
12117 if (pathtype == BGP_PATH_SHOW_ALL
12118 || (pathtype == BGP_PATH_SHOW_BESTPATH
12119 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12120 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12121 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12122 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12123 route_vty_out_detail(vty, bgp, bgp_node,
12124 bgp_dest_get_prefix(bgp_node), pi,
12125 AFI_IP, safi, rpki_curr_state,
12126 json_paths);
12127 }
12128
12129 if (json && json_paths) {
12130 json_object_object_add(json_header, "paths", json_paths);
12131
12132 if (pfx_rd)
12133 json_object_object_addf(
12134 json, json_header,
12135 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12136 }
12137 }
12138
12139 /*
12140 * Return rd based on safi
12141 */
12142 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12143 safi_t safi)
12144 {
12145 switch (safi) {
12146 case SAFI_MPLS_VPN:
12147 case SAFI_ENCAP:
12148 case SAFI_EVPN:
12149 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12150 case SAFI_UNSPEC:
12151 case SAFI_UNICAST:
12152 case SAFI_MULTICAST:
12153 case SAFI_LABELED_UNICAST:
12154 case SAFI_FLOWSPEC:
12155 case SAFI_MAX:
12156 return NULL;
12157 }
12158
12159 assert(!"Reached end of function when we were not expecting it");
12160 }
12161
12162 /* Display specified route of BGP table. */
12163 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12164 struct bgp_table *rib, const char *ip_str,
12165 afi_t afi, safi_t safi,
12166 enum rpki_states rpki_target_state,
12167 struct prefix_rd *prd, int prefix_check,
12168 enum bgp_path_type pathtype, bool use_json)
12169 {
12170 int ret;
12171 int display = 0;
12172 struct prefix match;
12173 struct bgp_dest *dest;
12174 struct bgp_dest *rm;
12175 struct bgp_table *table;
12176 json_object *json = NULL;
12177 json_object *json_paths = NULL;
12178
12179 /* Check IP address argument. */
12180 ret = str2prefix(ip_str, &match);
12181 if (!ret) {
12182 vty_out(vty, "address is malformed\n");
12183 return CMD_WARNING;
12184 }
12185
12186 match.family = afi2family(afi);
12187
12188 if (use_json)
12189 json = json_object_new_object();
12190
12191 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12192 for (dest = bgp_table_top(rib); dest;
12193 dest = bgp_route_next(dest)) {
12194 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12195
12196 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12197 continue;
12198 table = bgp_dest_get_bgp_table_info(dest);
12199 if (!table)
12200 continue;
12201
12202 rm = bgp_node_match(table, &match);
12203 if (rm == NULL)
12204 continue;
12205
12206 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12207 if (prefix_check
12208 && rm_p->prefixlen != match.prefixlen) {
12209 bgp_dest_unlock_node(rm);
12210 continue;
12211 }
12212
12213 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12214 bgp, afi, safi, json, pathtype,
12215 &display, rpki_target_state);
12216
12217 bgp_dest_unlock_node(rm);
12218 }
12219 } else if (safi == SAFI_EVPN) {
12220 struct bgp_dest *longest_pfx;
12221 bool is_exact_pfxlen_match = false;
12222
12223 for (dest = bgp_table_top(rib); dest;
12224 dest = bgp_route_next(dest)) {
12225 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12226
12227 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12228 continue;
12229 table = bgp_dest_get_bgp_table_info(dest);
12230 if (!table)
12231 continue;
12232
12233 longest_pfx = NULL;
12234 is_exact_pfxlen_match = false;
12235 /*
12236 * Search through all the prefixes for a match. The
12237 * pfx's are enumerated in ascending order of pfxlens.
12238 * So, the last pfx match is the longest match. Set
12239 * is_exact_pfxlen_match when we get exact pfxlen match
12240 */
12241 for (rm = bgp_table_top(table); rm;
12242 rm = bgp_route_next(rm)) {
12243 const struct prefix *rm_p =
12244 bgp_dest_get_prefix(rm);
12245 /*
12246 * Get prefixlen of the ip-prefix within type5
12247 * evpn route
12248 */
12249 if (evpn_type5_prefix_match(rm_p, &match)
12250 && rm->info) {
12251 longest_pfx = rm;
12252 int type5_pfxlen =
12253 bgp_evpn_get_type5_prefixlen(
12254 rm_p);
12255 if (type5_pfxlen == match.prefixlen) {
12256 is_exact_pfxlen_match = true;
12257 bgp_dest_unlock_node(rm);
12258 break;
12259 }
12260 }
12261 }
12262
12263 if (!longest_pfx)
12264 continue;
12265
12266 if (prefix_check && !is_exact_pfxlen_match)
12267 continue;
12268
12269 rm = longest_pfx;
12270 bgp_dest_lock_node(rm);
12271
12272 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12273 bgp, afi, safi, json, pathtype,
12274 &display, rpki_target_state);
12275
12276 bgp_dest_unlock_node(rm);
12277 }
12278 } else if (safi == SAFI_FLOWSPEC) {
12279 if (use_json)
12280 json_paths = json_object_new_array();
12281
12282 display = bgp_flowspec_display_match_per_ip(afi, rib,
12283 &match, prefix_check,
12284 vty,
12285 use_json,
12286 json_paths);
12287 if (use_json) {
12288 if (display)
12289 json_object_object_add(json, "paths",
12290 json_paths);
12291 else
12292 json_object_free(json_paths);
12293 }
12294 } else {
12295 dest = bgp_node_match(rib, &match);
12296 if (dest != NULL) {
12297 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12298 if (!prefix_check
12299 || dest_p->prefixlen == match.prefixlen) {
12300 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12301 safi, json, pathtype,
12302 &display, rpki_target_state);
12303 }
12304
12305 bgp_dest_unlock_node(dest);
12306 }
12307 }
12308
12309 if (use_json) {
12310 vty_json(vty, json);
12311 } else {
12312 if (!display) {
12313 vty_out(vty, "%% Network not in table\n");
12314 return CMD_WARNING;
12315 }
12316 }
12317
12318 return CMD_SUCCESS;
12319 }
12320
12321 /* Display specified route of Main RIB */
12322 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12323 afi_t afi, safi_t safi, struct prefix_rd *prd,
12324 int prefix_check, enum bgp_path_type pathtype,
12325 enum rpki_states rpki_target_state, bool use_json)
12326 {
12327 if (!bgp) {
12328 bgp = bgp_get_default();
12329 if (!bgp) {
12330 if (!use_json)
12331 vty_out(vty, "No BGP process is configured\n");
12332 else
12333 vty_out(vty, "{}\n");
12334 return CMD_WARNING;
12335 }
12336 }
12337
12338 /* labeled-unicast routes live in the unicast table */
12339 if (safi == SAFI_LABELED_UNICAST)
12340 safi = SAFI_UNICAST;
12341
12342 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12343 afi, safi, rpki_target_state, prd,
12344 prefix_check, pathtype, use_json);
12345 }
12346
12347 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12348 struct cmd_token **argv, bool exact, afi_t afi,
12349 safi_t safi, bool uj)
12350 {
12351 struct lcommunity *lcom;
12352 struct buffer *b;
12353 int i;
12354 char *str;
12355 int first = 0;
12356 uint16_t show_flags = 0;
12357 int ret;
12358
12359 if (uj)
12360 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12361
12362 b = buffer_new(1024);
12363 for (i = 0; i < argc; i++) {
12364 if (first)
12365 buffer_putc(b, ' ');
12366 else {
12367 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12368 first = 1;
12369 buffer_putstr(b, argv[i]->arg);
12370 }
12371 }
12372 }
12373 buffer_putc(b, '\0');
12374
12375 str = buffer_getstr(b);
12376 buffer_free(b);
12377
12378 lcom = lcommunity_str2com(str);
12379 XFREE(MTYPE_TMP, str);
12380 if (!lcom) {
12381 vty_out(vty, "%% Large-community malformed\n");
12382 return CMD_WARNING;
12383 }
12384
12385 ret = bgp_show(vty, bgp, afi, safi,
12386 (exact ? bgp_show_type_lcommunity_exact
12387 : bgp_show_type_lcommunity),
12388 lcom, show_flags, RPKI_NOT_BEING_USED);
12389
12390 lcommunity_free(&lcom);
12391 return ret;
12392 }
12393
12394 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12395 const char *lcom, bool exact, afi_t afi,
12396 safi_t safi, bool uj)
12397 {
12398 struct community_list *list;
12399 uint16_t show_flags = 0;
12400
12401 if (uj)
12402 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12403
12404
12405 list = community_list_lookup(bgp_clist, lcom, 0,
12406 LARGE_COMMUNITY_LIST_MASTER);
12407 if (list == NULL) {
12408 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12409 lcom);
12410 return CMD_WARNING;
12411 }
12412
12413 return bgp_show(vty, bgp, afi, safi,
12414 (exact ? bgp_show_type_lcommunity_list_exact
12415 : bgp_show_type_lcommunity_list),
12416 list, show_flags, RPKI_NOT_BEING_USED);
12417 }
12418
12419 DEFUN (show_ip_bgp_large_community_list,
12420 show_ip_bgp_large_community_list_cmd,
12421 "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]",
12422 SHOW_STR
12423 IP_STR
12424 BGP_STR
12425 BGP_INSTANCE_HELP_STR
12426 BGP_AFI_HELP_STR
12427 BGP_SAFI_WITH_LABEL_HELP_STR
12428 "Display routes matching the large-community-list\n"
12429 "large-community-list number\n"
12430 "large-community-list name\n"
12431 "Exact match of the large-communities\n"
12432 JSON_STR)
12433 {
12434 afi_t afi = AFI_IP6;
12435 safi_t safi = SAFI_UNICAST;
12436 int idx = 0;
12437 bool exact_match = 0;
12438 struct bgp *bgp = NULL;
12439 bool uj = use_json(argc, argv);
12440
12441 if (uj)
12442 argc--;
12443
12444 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12445 &bgp, uj);
12446 if (!idx)
12447 return CMD_WARNING;
12448
12449 argv_find(argv, argc, "large-community-list", &idx);
12450
12451 const char *clist_number_or_name = argv[++idx]->arg;
12452
12453 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12454 exact_match = 1;
12455
12456 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12457 exact_match, afi, safi, uj);
12458 }
12459 DEFUN (show_ip_bgp_large_community,
12460 show_ip_bgp_large_community_cmd,
12461 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12462 SHOW_STR
12463 IP_STR
12464 BGP_STR
12465 BGP_INSTANCE_HELP_STR
12466 BGP_AFI_HELP_STR
12467 BGP_SAFI_WITH_LABEL_HELP_STR
12468 "Display routes matching the large-communities\n"
12469 "List of large-community numbers\n"
12470 "Exact match of the large-communities\n"
12471 JSON_STR)
12472 {
12473 afi_t afi = AFI_IP6;
12474 safi_t safi = SAFI_UNICAST;
12475 int idx = 0;
12476 bool exact_match = 0;
12477 struct bgp *bgp = NULL;
12478 bool uj = use_json(argc, argv);
12479 uint16_t show_flags = 0;
12480
12481 if (uj) {
12482 argc--;
12483 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12484 }
12485
12486 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12487 &bgp, uj);
12488 if (!idx)
12489 return CMD_WARNING;
12490
12491 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12492 if (argv_find(argv, argc, "exact-match", &idx)) {
12493 argc--;
12494 exact_match = 1;
12495 }
12496 return bgp_show_lcommunity(vty, bgp, argc, argv,
12497 exact_match, afi, safi, uj);
12498 } else
12499 return bgp_show(vty, bgp, afi, safi,
12500 bgp_show_type_lcommunity_all, NULL, show_flags,
12501 RPKI_NOT_BEING_USED);
12502 }
12503
12504 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12505 safi_t safi, struct json_object *json_array);
12506 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12507 safi_t safi, struct json_object *json);
12508
12509
12510 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12511 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12512 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12513 "Display number of prefixes for all afi/safi\n" JSON_STR)
12514 {
12515 bool uj = use_json(argc, argv);
12516 struct bgp *bgp = NULL;
12517 safi_t safi = SAFI_UNICAST;
12518 afi_t afi = AFI_IP6;
12519 int idx = 0;
12520 struct json_object *json_all = NULL;
12521 struct json_object *json_afi_safi = NULL;
12522
12523 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12524 &bgp, false);
12525 if (!idx)
12526 return CMD_WARNING;
12527
12528 if (uj)
12529 json_all = json_object_new_object();
12530
12531 FOREACH_AFI_SAFI (afi, safi) {
12532 /*
12533 * So limit output to those afi/safi pairs that
12534 * actually have something interesting in them
12535 */
12536 if (strmatch(get_afi_safi_str(afi, safi, true),
12537 "Unknown")) {
12538 continue;
12539 }
12540 if (uj) {
12541 json_afi_safi = json_object_new_array();
12542 json_object_object_add(
12543 json_all,
12544 get_afi_safi_str(afi, safi, true),
12545 json_afi_safi);
12546 } else {
12547 json_afi_safi = NULL;
12548 }
12549
12550 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12551 }
12552
12553 if (uj)
12554 vty_json(vty, json_all);
12555
12556 return CMD_SUCCESS;
12557 }
12558
12559 /* BGP route print out function without JSON */
12560 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12561 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12562 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12563 SHOW_STR
12564 IP_STR
12565 BGP_STR
12566 BGP_INSTANCE_HELP_STR
12567 L2VPN_HELP_STR
12568 EVPN_HELP_STR
12569 "BGP RIB advertisement statistics\n"
12570 JSON_STR)
12571 {
12572 afi_t afi = AFI_IP6;
12573 safi_t safi = SAFI_UNICAST;
12574 struct bgp *bgp = NULL;
12575 int idx = 0, ret;
12576 bool uj = use_json(argc, argv);
12577 struct json_object *json_afi_safi = NULL, *json = NULL;
12578
12579 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12580 &bgp, false);
12581 if (!idx)
12582 return CMD_WARNING;
12583
12584 if (uj)
12585 json_afi_safi = json_object_new_array();
12586 else
12587 json_afi_safi = NULL;
12588
12589 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12590
12591 if (uj) {
12592 json = json_object_new_object();
12593 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12594 json_afi_safi);
12595 vty_json(vty, json);
12596 }
12597 return ret;
12598 }
12599
12600 /* BGP route print out function without JSON */
12601 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12602 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12603 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12604 "]]\
12605 statistics [json]",
12606 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12607 BGP_SAFI_WITH_LABEL_HELP_STR
12608 "BGP RIB advertisement statistics\n" JSON_STR)
12609 {
12610 afi_t afi = AFI_IP6;
12611 safi_t safi = SAFI_UNICAST;
12612 struct bgp *bgp = NULL;
12613 int idx = 0, ret;
12614 bool uj = use_json(argc, argv);
12615 struct json_object *json_afi_safi = NULL, *json = NULL;
12616
12617 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12618 &bgp, false);
12619 if (!idx)
12620 return CMD_WARNING;
12621
12622 if (uj)
12623 json_afi_safi = json_object_new_array();
12624 else
12625 json_afi_safi = NULL;
12626
12627 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12628
12629 if (uj) {
12630 json = json_object_new_object();
12631 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12632 json_afi_safi);
12633 vty_json(vty, json);
12634 }
12635 return ret;
12636 }
12637
12638 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12639 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12640 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12641 "]] [all$all] dampening parameters [json]",
12642 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12643 BGP_SAFI_WITH_LABEL_HELP_STR
12644 "Display the entries for all address families\n"
12645 "Display detailed information about dampening\n"
12646 "Display detail of configured dampening parameters\n"
12647 JSON_STR)
12648 {
12649 afi_t afi = AFI_IP6;
12650 safi_t safi = SAFI_UNICAST;
12651 struct bgp *bgp = NULL;
12652 int idx = 0;
12653 uint16_t show_flags = 0;
12654 bool uj = use_json(argc, argv);
12655
12656 if (uj) {
12657 argc--;
12658 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12659 }
12660
12661 /* [<ipv4|ipv6> [all]] */
12662 if (all) {
12663 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12664 if (argv_find(argv, argc, "ipv4", &idx))
12665 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12666
12667 if (argv_find(argv, argc, "ipv6", &idx))
12668 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12669 }
12670
12671 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12672 &bgp, false);
12673 if (!idx)
12674 return CMD_WARNING;
12675
12676 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12677 }
12678
12679 /* BGP route print out function */
12680 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12681 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12682 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12683 "]]\
12684 [all$all]\
12685 [cidr-only\
12686 |dampening <flap-statistics|dampened-paths>\
12687 |community [AA:NN|local-AS|no-advertise|no-export\
12688 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12689 |accept-own|accept-own-nexthop|route-filter-v6\
12690 |route-filter-v4|route-filter-translated-v6\
12691 |route-filter-translated-v4] [exact-match]\
12692 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12693 |filter-list AS_PATH_FILTER_NAME\
12694 |prefix-list WORD\
12695 |access-list ACCESSLIST_NAME\
12696 |route-map RMAP_NAME\
12697 |rpki <invalid|valid|notfound>\
12698 |version (1-4294967295)\
12699 |alias ALIAS_NAME\
12700 |A.B.C.D/M longer-prefixes\
12701 |X:X::X:X/M longer-prefixes\
12702 |"BGP_SELF_ORIG_CMD_STR"\
12703 |detail-routes$detail_routes\
12704 ] [json$uj [detail$detail_json] | wide$wide]",
12705 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12706 BGP_SAFI_WITH_LABEL_HELP_STR
12707 "Display the entries for all address families\n"
12708 "Display only routes with non-natural netmasks\n"
12709 "Display detailed information about dampening\n"
12710 "Display flap statistics of routes\n"
12711 "Display paths suppressed due to dampening\n"
12712 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12713 "Do not send outside local AS (well-known community)\n"
12714 "Do not advertise to any peer (well-known community)\n"
12715 "Do not export to next AS (well-known community)\n"
12716 "Graceful shutdown (well-known community)\n"
12717 "Do not export to any peer (well-known community)\n"
12718 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12719 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12720 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12721 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12722 "Should accept VPN route with local nexthop (well-known community)\n"
12723 "RT VPNv6 route filtering (well-known community)\n"
12724 "RT VPNv4 route filtering (well-known community)\n"
12725 "RT translated VPNv6 route filtering (well-known community)\n"
12726 "RT translated VPNv4 route filtering (well-known community)\n"
12727 "Exact match of the communities\n"
12728 "Community-list number\n"
12729 "Community-list name\n"
12730 "Display routes matching the community-list\n"
12731 "Exact match of the communities\n"
12732 "Display routes conforming to the filter-list\n"
12733 "Regular expression access list name\n"
12734 "Display routes conforming to the prefix-list\n"
12735 "Prefix-list name\n"
12736 "Display routes conforming to the access-list\n"
12737 "Access-list name\n"
12738 "Display routes matching the route-map\n"
12739 "A route-map to match on\n"
12740 "RPKI route types\n"
12741 "A valid path as determined by rpki\n"
12742 "A invalid path as determined by rpki\n"
12743 "A path that has no rpki data\n"
12744 "Display prefixes with matching version numbers\n"
12745 "Version number and above\n"
12746 "Display prefixes with matching BGP community alias\n"
12747 "BGP community alias\n"
12748 "IPv4 prefix\n"
12749 "Display route and more specific routes\n"
12750 "IPv6 prefix\n"
12751 "Display route and more specific routes\n"
12752 BGP_SELF_ORIG_HELP_STR
12753 "Display detailed version of all routes\n"
12754 JSON_STR
12755 "Display detailed version of JSON output\n"
12756 "Increase table width for longer prefixes\n")
12757 {
12758 afi_t afi = AFI_IP6;
12759 safi_t safi = SAFI_UNICAST;
12760 enum bgp_show_type sh_type = bgp_show_type_normal;
12761 void *output_arg = NULL;
12762 struct bgp *bgp = NULL;
12763 int idx = 0;
12764 int exact_match = 0;
12765 char *community = NULL;
12766 bool first = true;
12767 uint16_t show_flags = 0;
12768 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12769 struct prefix p;
12770
12771 if (uj) {
12772 argc--;
12773 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12774 }
12775
12776 if (detail_json)
12777 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12778
12779 if (detail_routes)
12780 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12781
12782 /* [<ipv4|ipv6> [all]] */
12783 if (all) {
12784 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12785
12786 if (argv_find(argv, argc, "ipv4", &idx))
12787 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12788
12789 if (argv_find(argv, argc, "ipv6", &idx))
12790 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12791 }
12792
12793 if (wide)
12794 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12795
12796 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12797 &bgp, uj);
12798 if (!idx)
12799 return CMD_WARNING;
12800
12801 if (argv_find(argv, argc, "cidr-only", &idx))
12802 sh_type = bgp_show_type_cidr_only;
12803
12804 if (argv_find(argv, argc, "dampening", &idx)) {
12805 if (argv_find(argv, argc, "dampened-paths", &idx))
12806 sh_type = bgp_show_type_dampend_paths;
12807 else if (argv_find(argv, argc, "flap-statistics", &idx))
12808 sh_type = bgp_show_type_flap_statistics;
12809 }
12810
12811 if (argv_find(argv, argc, "community", &idx)) {
12812 char *maybecomm = NULL;
12813
12814 if (idx + 1 < argc) {
12815 if (argv[idx + 1]->type == VARIABLE_TKN)
12816 maybecomm = argv[idx + 1]->arg;
12817 else
12818 maybecomm = argv[idx + 1]->text;
12819 }
12820
12821 if (maybecomm && !strmatch(maybecomm, "json")
12822 && !strmatch(maybecomm, "exact-match"))
12823 community = maybecomm;
12824
12825 if (argv_find(argv, argc, "exact-match", &idx))
12826 exact_match = 1;
12827
12828 if (!community)
12829 sh_type = bgp_show_type_community_all;
12830 }
12831
12832 if (argv_find(argv, argc, "community-list", &idx)) {
12833 const char *clist_number_or_name = argv[++idx]->arg;
12834 struct community_list *list;
12835
12836 if (argv_find(argv, argc, "exact-match", &idx))
12837 exact_match = 1;
12838
12839 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12840 COMMUNITY_LIST_MASTER);
12841 if (list == NULL) {
12842 vty_out(vty, "%% %s community-list not found\n",
12843 clist_number_or_name);
12844 return CMD_WARNING;
12845 }
12846
12847 if (exact_match)
12848 sh_type = bgp_show_type_community_list_exact;
12849 else
12850 sh_type = bgp_show_type_community_list;
12851 output_arg = list;
12852 }
12853
12854 if (argv_find(argv, argc, "filter-list", &idx)) {
12855 const char *filter = argv[++idx]->arg;
12856 struct as_list *as_list;
12857
12858 as_list = as_list_lookup(filter);
12859 if (as_list == NULL) {
12860 vty_out(vty, "%% %s AS-path access-list not found\n",
12861 filter);
12862 return CMD_WARNING;
12863 }
12864
12865 sh_type = bgp_show_type_filter_list;
12866 output_arg = as_list;
12867 }
12868
12869 if (argv_find(argv, argc, "prefix-list", &idx)) {
12870 const char *prefix_list_str = argv[++idx]->arg;
12871 struct prefix_list *plist;
12872
12873 plist = prefix_list_lookup(afi, prefix_list_str);
12874 if (plist == NULL) {
12875 vty_out(vty, "%% %s prefix-list not found\n",
12876 prefix_list_str);
12877 return CMD_WARNING;
12878 }
12879
12880 sh_type = bgp_show_type_prefix_list;
12881 output_arg = plist;
12882 }
12883
12884 if (argv_find(argv, argc, "access-list", &idx)) {
12885 const char *access_list_str = argv[++idx]->arg;
12886 struct access_list *alist;
12887
12888 alist = access_list_lookup(afi, access_list_str);
12889 if (!alist) {
12890 vty_out(vty, "%% %s access-list not found\n",
12891 access_list_str);
12892 return CMD_WARNING;
12893 }
12894
12895 sh_type = bgp_show_type_access_list;
12896 output_arg = alist;
12897 }
12898
12899 if (argv_find(argv, argc, "route-map", &idx)) {
12900 const char *rmap_str = argv[++idx]->arg;
12901 struct route_map *rmap;
12902
12903 rmap = route_map_lookup_by_name(rmap_str);
12904 if (!rmap) {
12905 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12906 return CMD_WARNING;
12907 }
12908
12909 sh_type = bgp_show_type_route_map;
12910 output_arg = rmap;
12911 }
12912
12913 if (argv_find(argv, argc, "rpki", &idx)) {
12914 sh_type = bgp_show_type_rpki;
12915 if (argv_find(argv, argc, "valid", &idx))
12916 rpki_target_state = RPKI_VALID;
12917 else if (argv_find(argv, argc, "invalid", &idx))
12918 rpki_target_state = RPKI_INVALID;
12919 }
12920
12921 /* Display prefixes with matching version numbers */
12922 if (argv_find(argv, argc, "version", &idx)) {
12923 sh_type = bgp_show_type_prefix_version;
12924 output_arg = argv[idx + 1]->arg;
12925 }
12926
12927 /* Display prefixes with matching BGP community alias */
12928 if (argv_find(argv, argc, "alias", &idx)) {
12929 sh_type = bgp_show_type_community_alias;
12930 output_arg = argv[idx + 1]->arg;
12931 }
12932
12933 /* prefix-longer */
12934 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12935 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12936 const char *prefix_str = argv[idx]->arg;
12937
12938 if (!str2prefix(prefix_str, &p)) {
12939 vty_out(vty, "%% Malformed Prefix\n");
12940 return CMD_WARNING;
12941 }
12942
12943 sh_type = bgp_show_type_prefix_longer;
12944 output_arg = &p;
12945 }
12946
12947 /* self originated only */
12948 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12949 sh_type = bgp_show_type_self_originated;
12950
12951 if (!all) {
12952 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12953 if (community)
12954 return bgp_show_community(vty, bgp, community,
12955 exact_match, afi, safi,
12956 show_flags);
12957 else
12958 return bgp_show(vty, bgp, afi, safi, sh_type,
12959 output_arg, show_flags,
12960 rpki_target_state);
12961 } else {
12962 struct listnode *node;
12963 struct bgp *abgp;
12964 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12965 * AFI_IP6 */
12966
12967 if (uj)
12968 vty_out(vty, "{\n");
12969
12970 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12971 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12972 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12973 ? AFI_IP
12974 : AFI_IP6;
12975 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12976 FOREACH_SAFI (safi) {
12977 if (!bgp_afi_safi_peer_exists(abgp, afi,
12978 safi))
12979 continue;
12980
12981 if (uj) {
12982 if (first)
12983 first = false;
12984 else
12985 vty_out(vty, ",\n");
12986 vty_out(vty, "\"%s\":{\n",
12987 get_afi_safi_str(afi,
12988 safi,
12989 true));
12990 } else
12991 vty_out(vty,
12992 "\nFor address family: %s\n",
12993 get_afi_safi_str(
12994 afi, safi,
12995 false));
12996
12997 if (community)
12998 bgp_show_community(
12999 vty, abgp, community,
13000 exact_match, afi, safi,
13001 show_flags);
13002 else
13003 bgp_show(vty, abgp, afi, safi,
13004 sh_type, output_arg,
13005 show_flags,
13006 rpki_target_state);
13007 if (uj)
13008 vty_out(vty, "}\n");
13009 }
13010 }
13011 } else {
13012 /* show <ip> bgp all: for each AFI and SAFI*/
13013 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13014 FOREACH_AFI_SAFI (afi, safi) {
13015 if (!bgp_afi_safi_peer_exists(abgp, afi,
13016 safi))
13017 continue;
13018
13019 if (uj) {
13020 if (first)
13021 first = false;
13022 else
13023 vty_out(vty, ",\n");
13024
13025 vty_out(vty, "\"%s\":{\n",
13026 get_afi_safi_str(afi,
13027 safi,
13028 true));
13029 } else
13030 vty_out(vty,
13031 "\nFor address family: %s\n",
13032 get_afi_safi_str(
13033 afi, safi,
13034 false));
13035
13036 if (community)
13037 bgp_show_community(
13038 vty, abgp, community,
13039 exact_match, afi, safi,
13040 show_flags);
13041 else
13042 bgp_show(vty, abgp, afi, safi,
13043 sh_type, output_arg,
13044 show_flags,
13045 rpki_target_state);
13046 if (uj)
13047 vty_out(vty, "}\n");
13048 }
13049 }
13050 }
13051 if (uj)
13052 vty_out(vty, "}\n");
13053 }
13054 return CMD_SUCCESS;
13055 }
13056
13057 DEFUN (show_ip_bgp_route,
13058 show_ip_bgp_route_cmd,
13059 "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]",
13060 SHOW_STR
13061 IP_STR
13062 BGP_STR
13063 BGP_INSTANCE_HELP_STR
13064 BGP_AFI_HELP_STR
13065 BGP_SAFI_WITH_LABEL_HELP_STR
13066 "Network in the BGP routing table to display\n"
13067 "IPv4 prefix\n"
13068 "Network in the BGP routing table to display\n"
13069 "IPv6 prefix\n"
13070 "Display only the bestpath\n"
13071 "Display only multipaths\n"
13072 "Display only paths that match the specified rpki state\n"
13073 "A valid path as determined by rpki\n"
13074 "A invalid path as determined by rpki\n"
13075 "A path that has no rpki data\n"
13076 JSON_STR)
13077 {
13078 int prefix_check = 0;
13079
13080 afi_t afi = AFI_IP6;
13081 safi_t safi = SAFI_UNICAST;
13082 char *prefix = NULL;
13083 struct bgp *bgp = NULL;
13084 enum bgp_path_type path_type;
13085 bool uj = use_json(argc, argv);
13086
13087 int idx = 0;
13088
13089 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13090 &bgp, uj);
13091 if (!idx)
13092 return CMD_WARNING;
13093
13094 if (!bgp) {
13095 vty_out(vty,
13096 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13097 return CMD_WARNING;
13098 }
13099
13100 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13101 if (argv_find(argv, argc, "A.B.C.D", &idx)
13102 || argv_find(argv, argc, "X:X::X:X", &idx))
13103 prefix_check = 0;
13104 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13105 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13106 prefix_check = 1;
13107
13108 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13109 && afi != AFI_IP6) {
13110 vty_out(vty,
13111 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13112 return CMD_WARNING;
13113 }
13114 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13115 && afi != AFI_IP) {
13116 vty_out(vty,
13117 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13118 return CMD_WARNING;
13119 }
13120
13121 prefix = argv[idx]->arg;
13122
13123 /* [<bestpath|multipath>] */
13124 if (argv_find(argv, argc, "bestpath", &idx))
13125 path_type = BGP_PATH_SHOW_BESTPATH;
13126 else if (argv_find(argv, argc, "multipath", &idx))
13127 path_type = BGP_PATH_SHOW_MULTIPATH;
13128 else
13129 path_type = BGP_PATH_SHOW_ALL;
13130
13131 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13132 path_type, RPKI_NOT_BEING_USED, uj);
13133 }
13134
13135 DEFUN (show_ip_bgp_regexp,
13136 show_ip_bgp_regexp_cmd,
13137 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13138 SHOW_STR
13139 IP_STR
13140 BGP_STR
13141 BGP_INSTANCE_HELP_STR
13142 BGP_AFI_HELP_STR
13143 BGP_SAFI_WITH_LABEL_HELP_STR
13144 "Display routes matching the AS path regular expression\n"
13145 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13146 JSON_STR)
13147 {
13148 afi_t afi = AFI_IP6;
13149 safi_t safi = SAFI_UNICAST;
13150 struct bgp *bgp = NULL;
13151 bool uj = use_json(argc, argv);
13152 char *regstr = NULL;
13153
13154 int idx = 0;
13155 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13156 &bgp, false);
13157 if (!idx)
13158 return CMD_WARNING;
13159
13160 // get index of regex
13161 if (argv_find(argv, argc, "REGEX", &idx))
13162 regstr = argv[idx]->arg;
13163
13164 assert(regstr);
13165 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13166 bgp_show_type_regexp, uj);
13167 }
13168
13169 DEFPY (show_ip_bgp_instance_all,
13170 show_ip_bgp_instance_all_cmd,
13171 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13172 SHOW_STR
13173 IP_STR
13174 BGP_STR
13175 BGP_INSTANCE_ALL_HELP_STR
13176 BGP_AFI_HELP_STR
13177 BGP_SAFI_WITH_LABEL_HELP_STR
13178 JSON_STR
13179 "Increase table width for longer prefixes\n")
13180 {
13181 afi_t afi = AFI_IP6;
13182 safi_t safi = SAFI_UNICAST;
13183 struct bgp *bgp = NULL;
13184 int idx = 0;
13185 uint16_t show_flags = 0;
13186
13187 if (uj) {
13188 argc--;
13189 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13190 }
13191
13192 if (wide)
13193 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13194
13195 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13196 &bgp, uj);
13197 if (!idx)
13198 return CMD_WARNING;
13199
13200 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13201 return CMD_SUCCESS;
13202 }
13203
13204 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13205 afi_t afi, safi_t safi, enum bgp_show_type type,
13206 bool use_json)
13207 {
13208 regex_t *regex;
13209 int rc;
13210 uint16_t show_flags = 0;
13211
13212 if (use_json)
13213 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13214
13215 if (!config_bgp_aspath_validate(regstr)) {
13216 vty_out(vty, "Invalid character in REGEX %s\n",
13217 regstr);
13218 return CMD_WARNING_CONFIG_FAILED;
13219 }
13220
13221 regex = bgp_regcomp(regstr);
13222 if (!regex) {
13223 vty_out(vty, "Can't compile regexp %s\n", regstr);
13224 return CMD_WARNING;
13225 }
13226
13227 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13228 RPKI_NOT_BEING_USED);
13229 bgp_regex_free(regex);
13230 return rc;
13231 }
13232
13233 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13234 const char *comstr, int exact, afi_t afi,
13235 safi_t safi, uint16_t show_flags)
13236 {
13237 struct community *com;
13238 int ret = 0;
13239
13240 com = community_str2com(comstr);
13241 if (!com) {
13242 vty_out(vty, "%% Community malformed: %s\n", comstr);
13243 return CMD_WARNING;
13244 }
13245
13246 ret = bgp_show(vty, bgp, afi, safi,
13247 (exact ? bgp_show_type_community_exact
13248 : bgp_show_type_community),
13249 com, show_flags, RPKI_NOT_BEING_USED);
13250 community_free(&com);
13251
13252 return ret;
13253 }
13254
13255 enum bgp_stats {
13256 BGP_STATS_MAXBITLEN = 0,
13257 BGP_STATS_RIB,
13258 BGP_STATS_PREFIXES,
13259 BGP_STATS_TOTPLEN,
13260 BGP_STATS_UNAGGREGATEABLE,
13261 BGP_STATS_MAX_AGGREGATEABLE,
13262 BGP_STATS_AGGREGATES,
13263 BGP_STATS_SPACE,
13264 BGP_STATS_ASPATH_COUNT,
13265 BGP_STATS_ASPATH_MAXHOPS,
13266 BGP_STATS_ASPATH_TOTHOPS,
13267 BGP_STATS_ASPATH_MAXSIZE,
13268 BGP_STATS_ASPATH_TOTSIZE,
13269 BGP_STATS_ASN_HIGHEST,
13270 BGP_STATS_MAX,
13271 };
13272
13273 #define TABLE_STATS_IDX_VTY 0
13274 #define TABLE_STATS_IDX_JSON 1
13275
13276 static const char *table_stats_strs[][2] = {
13277 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13278 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13279 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13280 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13281 "unaggregateablePrefixes"},
13282 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13283 "maximumAggregateablePrefixes"},
13284 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13285 "bgpAggregateAdvertisements"},
13286 [BGP_STATS_SPACE] = {"Address space advertised",
13287 "addressSpaceAdvertised"},
13288 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13289 "advertisementsWithPaths"},
13290 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13291 "longestAsPath"},
13292 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13293 "largestAsPath"},
13294 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13295 "averageAsPathLengthHops"},
13296 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13297 "averageAsPathSizeBytes"},
13298 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13299 [BGP_STATS_MAX] = {NULL, NULL}
13300 };
13301
13302 struct bgp_table_stats {
13303 struct bgp_table *table;
13304 unsigned long long counts[BGP_STATS_MAX];
13305
13306 unsigned long long
13307 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13308 1];
13309
13310 double total_space;
13311 };
13312
13313 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13314 struct bgp_table_stats *ts, unsigned int space)
13315 {
13316 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13317 struct bgp_path_info *pi;
13318 const struct prefix *rn_p;
13319
13320 if (!bgp_dest_has_bgp_path_info_data(dest))
13321 return;
13322
13323 rn_p = bgp_dest_get_prefix(dest);
13324 ts->counts[BGP_STATS_PREFIXES]++;
13325 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13326
13327 ts->prefix_len_count[rn_p->prefixlen]++;
13328 /* check if the prefix is included by any other announcements */
13329 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13330 pdest = bgp_dest_parent_nolock(pdest);
13331
13332 if (pdest == NULL || pdest == top) {
13333 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13334 /* announced address space */
13335 if (space)
13336 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13337 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13338 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13339
13340
13341 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13342 ts->counts[BGP_STATS_RIB]++;
13343
13344 if (CHECK_FLAG(pi->attr->flag,
13345 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13346 ts->counts[BGP_STATS_AGGREGATES]++;
13347
13348 /* as-path stats */
13349 if (pi->attr->aspath) {
13350 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13351 unsigned int size = aspath_size(pi->attr->aspath);
13352 as_t highest = aspath_highest(pi->attr->aspath);
13353
13354 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13355
13356 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13357 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13358
13359 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13360 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13361
13362 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13363 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13364 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13365 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13366 }
13367 }
13368 }
13369
13370 static void bgp_table_stats_walker(struct event *t)
13371 {
13372 struct bgp_dest *dest, *ndest;
13373 struct bgp_dest *top;
13374 struct bgp_table_stats *ts = EVENT_ARG(t);
13375 unsigned int space = 0;
13376
13377 if (!(top = bgp_table_top(ts->table)))
13378 return;
13379
13380 switch (ts->table->afi) {
13381 case AFI_IP:
13382 space = IPV4_MAX_BITLEN;
13383 break;
13384 case AFI_IP6:
13385 space = IPV6_MAX_BITLEN;
13386 break;
13387 case AFI_L2VPN:
13388 space = EVPN_ROUTE_PREFIXLEN;
13389 break;
13390 case AFI_UNSPEC:
13391 case AFI_MAX:
13392 return;
13393 }
13394
13395 ts->counts[BGP_STATS_MAXBITLEN] = space;
13396
13397 for (dest = top; dest; dest = bgp_route_next(dest)) {
13398 if (ts->table->safi == SAFI_MPLS_VPN
13399 || ts->table->safi == SAFI_ENCAP
13400 || ts->table->safi == SAFI_EVPN) {
13401 struct bgp_table *table;
13402
13403 table = bgp_dest_get_bgp_table_info(dest);
13404 if (!table)
13405 continue;
13406
13407 top = bgp_table_top(table);
13408 for (ndest = bgp_table_top(table); ndest;
13409 ndest = bgp_route_next(ndest))
13410 bgp_table_stats_rn(ndest, top, ts, space);
13411 } else {
13412 bgp_table_stats_rn(dest, top, ts, space);
13413 }
13414 }
13415 }
13416
13417 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13418 struct json_object *json_array)
13419 {
13420 struct listnode *node, *nnode;
13421 struct bgp *bgp;
13422
13423 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13424 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13425 }
13426
13427 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13428 safi_t safi, struct json_object *json_array)
13429 {
13430 struct bgp_table_stats ts;
13431 unsigned int i;
13432 int ret = CMD_SUCCESS;
13433 char temp_buf[20];
13434 struct json_object *json = NULL;
13435 uint32_t bitlen = 0;
13436 struct json_object *json_bitlen;
13437
13438 if (json_array)
13439 json = json_object_new_object();
13440
13441 if (!bgp->rib[afi][safi]) {
13442 char warning_msg[50];
13443
13444 snprintf(warning_msg, sizeof(warning_msg),
13445 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13446 safi);
13447
13448 if (!json)
13449 vty_out(vty, "%s\n", warning_msg);
13450 else
13451 json_object_string_add(json, "warning", warning_msg);
13452
13453 ret = CMD_WARNING;
13454 goto end_table_stats;
13455 }
13456
13457 if (!json)
13458 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13459 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13460 else
13461 json_object_string_add(json, "instance", bgp->name_pretty);
13462
13463 /* labeled-unicast routes live in the unicast table */
13464 if (safi == SAFI_LABELED_UNICAST)
13465 safi = SAFI_UNICAST;
13466
13467 memset(&ts, 0, sizeof(ts));
13468 ts.table = bgp->rib[afi][safi];
13469 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13470
13471 for (i = 0; i < BGP_STATS_MAX; i++) {
13472 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13473 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13474 continue;
13475
13476 switch (i) {
13477 case BGP_STATS_ASPATH_TOTHOPS:
13478 case BGP_STATS_ASPATH_TOTSIZE:
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_ASPATH_COUNT]
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_ASPATH_COUNT]
13500 : 0);
13501 }
13502 break;
13503 case BGP_STATS_TOTPLEN:
13504 if (!json) {
13505 snprintf(
13506 temp_buf, sizeof(temp_buf), "%12.2f",
13507 ts.counts[i]
13508 ? (float)ts.counts[i]
13509 / (float)ts.counts
13510 [BGP_STATS_PREFIXES]
13511 : 0);
13512 vty_out(vty, "%-30s: %s",
13513 table_stats_strs[i]
13514 [TABLE_STATS_IDX_VTY],
13515 temp_buf);
13516 } else {
13517 json_object_double_add(
13518 json,
13519 table_stats_strs[i]
13520 [TABLE_STATS_IDX_JSON],
13521 ts.counts[i]
13522 ? (double)ts.counts[i]
13523 / (double)ts.counts
13524 [BGP_STATS_PREFIXES]
13525 : 0);
13526 }
13527 break;
13528 case BGP_STATS_SPACE:
13529 if (!json) {
13530 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13531 ts.total_space);
13532 vty_out(vty, "%-30s: %s\n",
13533 table_stats_strs[i]
13534 [TABLE_STATS_IDX_VTY],
13535 temp_buf);
13536 } else {
13537 json_object_double_add(
13538 json,
13539 table_stats_strs[i]
13540 [TABLE_STATS_IDX_JSON],
13541 (double)ts.total_space);
13542 }
13543 if (afi == AFI_IP6) {
13544 if (!json) {
13545 snprintf(temp_buf, sizeof(temp_buf),
13546 "%12g",
13547 ts.total_space
13548 * pow(2.0, -128 + 32));
13549 vty_out(vty, "%30s: %s\n",
13550 "/32 equivalent %s\n",
13551 temp_buf);
13552 } else {
13553 json_object_double_add(
13554 json, "/32equivalent",
13555 (double)(ts.total_space
13556 * pow(2.0,
13557 -128 + 32)));
13558 }
13559 if (!json) {
13560 snprintf(temp_buf, sizeof(temp_buf),
13561 "%12g",
13562 ts.total_space
13563 * pow(2.0, -128 + 48));
13564 vty_out(vty, "%30s: %s\n",
13565 "/48 equivalent %s\n",
13566 temp_buf);
13567 } else {
13568 json_object_double_add(
13569 json, "/48equivalent",
13570 (double)(ts.total_space
13571 * pow(2.0,
13572 -128 + 48)));
13573 }
13574 } else {
13575 if (!json) {
13576 snprintf(temp_buf, sizeof(temp_buf),
13577 "%12.2f",
13578 ts.total_space * 100.
13579 * pow(2.0, -32));
13580 vty_out(vty, "%30s: %s\n",
13581 "% announced ", temp_buf);
13582 } else {
13583 json_object_double_add(
13584 json, "%announced",
13585 (double)(ts.total_space * 100.
13586 * pow(2.0, -32)));
13587 }
13588 if (!json) {
13589 snprintf(temp_buf, sizeof(temp_buf),
13590 "%12.2f",
13591 ts.total_space
13592 * pow(2.0, -32 + 8));
13593 vty_out(vty, "%30s: %s\n",
13594 "/8 equivalent ", temp_buf);
13595 } else {
13596 json_object_double_add(
13597 json, "/8equivalent",
13598 (double)(ts.total_space
13599 * pow(2.0, -32 + 8)));
13600 }
13601 if (!json) {
13602 snprintf(temp_buf, sizeof(temp_buf),
13603 "%12.2f",
13604 ts.total_space
13605 * pow(2.0, -32 + 24));
13606 vty_out(vty, "%30s: %s\n",
13607 "/24 equivalent ", temp_buf);
13608 } else {
13609 json_object_double_add(
13610 json, "/24equivalent",
13611 (double)(ts.total_space
13612 * pow(2.0, -32 + 24)));
13613 }
13614 }
13615 break;
13616 default:
13617 if (!json) {
13618 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13619 ts.counts[i]);
13620 vty_out(vty, "%-30s: %s",
13621 table_stats_strs[i]
13622 [TABLE_STATS_IDX_VTY],
13623 temp_buf);
13624 } else {
13625 json_object_int_add(
13626 json,
13627 table_stats_strs[i]
13628 [TABLE_STATS_IDX_JSON],
13629 ts.counts[i]);
13630 }
13631 }
13632 if (!json)
13633 vty_out(vty, "\n");
13634 }
13635
13636 switch (afi) {
13637 case AFI_IP:
13638 bitlen = IPV4_MAX_BITLEN;
13639 break;
13640 case AFI_IP6:
13641 bitlen = IPV6_MAX_BITLEN;
13642 break;
13643 case AFI_L2VPN:
13644 bitlen = EVPN_ROUTE_PREFIXLEN;
13645 break;
13646 case AFI_UNSPEC:
13647 case AFI_MAX:
13648 break;
13649 }
13650
13651 if (json) {
13652 json_bitlen = json_object_new_array();
13653
13654 for (i = 0; i <= bitlen; i++) {
13655 struct json_object *ind_bit = json_object_new_object();
13656
13657 if (!ts.prefix_len_count[i])
13658 continue;
13659
13660 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13661 json_object_int_add(ind_bit, temp_buf,
13662 ts.prefix_len_count[i]);
13663 json_object_array_add(json_bitlen, ind_bit);
13664 }
13665 json_object_object_add(json, "prefixLength", json_bitlen);
13666 }
13667
13668 end_table_stats:
13669 if (json)
13670 json_object_array_add(json_array, json);
13671 return ret;
13672 }
13673
13674 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13675 safi_t safi, struct json_object *json_array)
13676 {
13677 if (!bgp) {
13678 bgp_table_stats_all(vty, afi, safi, json_array);
13679 return CMD_SUCCESS;
13680 }
13681
13682 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13683 }
13684
13685 enum bgp_pcounts {
13686 PCOUNT_ADJ_IN = 0,
13687 PCOUNT_DAMPED,
13688 PCOUNT_REMOVED,
13689 PCOUNT_HISTORY,
13690 PCOUNT_STALE,
13691 PCOUNT_VALID,
13692 PCOUNT_ALL,
13693 PCOUNT_COUNTED,
13694 PCOUNT_BPATH_SELECTED,
13695 PCOUNT_PFCNT, /* the figure we display to users */
13696 PCOUNT_MAX,
13697 };
13698
13699 static const char *const pcount_strs[] = {
13700 [PCOUNT_ADJ_IN] = "Adj-in",
13701 [PCOUNT_DAMPED] = "Damped",
13702 [PCOUNT_REMOVED] = "Removed",
13703 [PCOUNT_HISTORY] = "History",
13704 [PCOUNT_STALE] = "Stale",
13705 [PCOUNT_VALID] = "Valid",
13706 [PCOUNT_ALL] = "All RIB",
13707 [PCOUNT_COUNTED] = "PfxCt counted",
13708 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13709 [PCOUNT_PFCNT] = "Useable",
13710 [PCOUNT_MAX] = NULL,
13711 };
13712
13713 struct peer_pcounts {
13714 unsigned int count[PCOUNT_MAX];
13715 const struct peer *peer;
13716 const struct bgp_table *table;
13717 safi_t safi;
13718 };
13719
13720 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13721 {
13722 const struct bgp_adj_in *ain;
13723 const struct bgp_path_info *pi;
13724 const struct peer *peer = pc->peer;
13725
13726 for (ain = rn->adj_in; ain; ain = ain->next)
13727 if (ain->peer == peer)
13728 pc->count[PCOUNT_ADJ_IN]++;
13729
13730 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13731
13732 if (pi->peer != peer)
13733 continue;
13734
13735 pc->count[PCOUNT_ALL]++;
13736
13737 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13738 pc->count[PCOUNT_DAMPED]++;
13739 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13740 pc->count[PCOUNT_HISTORY]++;
13741 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13742 pc->count[PCOUNT_REMOVED]++;
13743 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13744 pc->count[PCOUNT_STALE]++;
13745 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13746 pc->count[PCOUNT_VALID]++;
13747 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13748 pc->count[PCOUNT_PFCNT]++;
13749 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13750 pc->count[PCOUNT_BPATH_SELECTED]++;
13751
13752 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13753 pc->count[PCOUNT_COUNTED]++;
13754 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13755 flog_err(
13756 EC_LIB_DEVELOPMENT,
13757 "Attempting to count but flags say it is unusable");
13758 } else {
13759 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13760 flog_err(
13761 EC_LIB_DEVELOPMENT,
13762 "Not counted but flags say we should");
13763 }
13764 }
13765 }
13766
13767 static void bgp_peer_count_walker(struct event *t)
13768 {
13769 struct bgp_dest *rn, *rm;
13770 const struct bgp_table *table;
13771 struct peer_pcounts *pc = EVENT_ARG(t);
13772
13773 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13774 || pc->safi == SAFI_EVPN) {
13775 /* Special handling for 2-level routing tables. */
13776 for (rn = bgp_table_top(pc->table); rn;
13777 rn = bgp_route_next(rn)) {
13778 table = bgp_dest_get_bgp_table_info(rn);
13779 if (table != NULL)
13780 for (rm = bgp_table_top(table); rm;
13781 rm = bgp_route_next(rm))
13782 bgp_peer_count_proc(rm, pc);
13783 }
13784 } else
13785 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13786 bgp_peer_count_proc(rn, pc);
13787 }
13788
13789 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13790 safi_t safi, bool use_json)
13791 {
13792 struct peer_pcounts pcounts = {.peer = peer};
13793 unsigned int i;
13794 json_object *json = NULL;
13795 json_object *json_loop = NULL;
13796
13797 if (use_json) {
13798 json = json_object_new_object();
13799 json_loop = json_object_new_object();
13800 }
13801
13802 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13803 || !peer->bgp->rib[afi][safi]) {
13804 if (use_json) {
13805 json_object_string_add(
13806 json, "warning",
13807 "No such neighbor or address family");
13808 vty_out(vty, "%s\n", json_object_to_json_string(json));
13809 json_object_free(json);
13810 json_object_free(json_loop);
13811 } else
13812 vty_out(vty, "%% No such neighbor or address family\n");
13813
13814 return CMD_WARNING;
13815 }
13816
13817 memset(&pcounts, 0, sizeof(pcounts));
13818 pcounts.peer = peer;
13819 pcounts.table = peer->bgp->rib[afi][safi];
13820 pcounts.safi = safi;
13821
13822 /* in-place call via thread subsystem so as to record execution time
13823 * stats for the thread-walk (i.e. ensure this can't be blamed on
13824 * on just vty_read()).
13825 */
13826 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13827
13828 if (use_json) {
13829 json_object_string_add(json, "prefixCountsFor", peer->host);
13830 json_object_string_add(json, "multiProtocol",
13831 get_afi_safi_str(afi, safi, true));
13832 json_object_int_add(json, "pfxCounter",
13833 peer->pcount[afi][safi]);
13834
13835 for (i = 0; i < PCOUNT_MAX; i++)
13836 json_object_int_add(json_loop, pcount_strs[i],
13837 pcounts.count[i]);
13838
13839 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13840
13841 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13842 json_object_string_add(json, "pfxctDriftFor",
13843 peer->host);
13844 json_object_string_add(
13845 json, "recommended",
13846 "Please report this bug, with the above command output");
13847 }
13848 vty_json(vty, json);
13849 } else {
13850
13851 if (peer->hostname
13852 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13853 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13854 peer->hostname, peer->host,
13855 get_afi_safi_str(afi, safi, false));
13856 } else {
13857 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13858 get_afi_safi_str(afi, safi, false));
13859 }
13860
13861 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13862 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13863
13864 for (i = 0; i < PCOUNT_MAX; i++)
13865 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13866 pcounts.count[i]);
13867
13868 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13869 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13870 vty_out(vty,
13871 "Please report this bug, with the above command output\n");
13872 }
13873 }
13874
13875 return CMD_SUCCESS;
13876 }
13877
13878 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13879 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13880 "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]",
13881 SHOW_STR
13882 IP_STR
13883 BGP_STR
13884 BGP_INSTANCE_HELP_STR
13885 BGP_AFI_HELP_STR
13886 BGP_SAFI_HELP_STR
13887 "Detailed information on TCP and BGP neighbor connections\n"
13888 "Neighbor to display information about\n"
13889 "Neighbor to display information about\n"
13890 "Neighbor on BGP configured interface\n"
13891 "Display detailed prefix count information\n"
13892 JSON_STR)
13893 {
13894 afi_t afi = AFI_IP6;
13895 safi_t safi = SAFI_UNICAST;
13896 struct peer *peer;
13897 int idx = 0;
13898 struct bgp *bgp = NULL;
13899 bool uj = use_json(argc, argv);
13900
13901 if (uj)
13902 argc--;
13903
13904 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13905 &bgp, uj);
13906 if (!idx)
13907 return CMD_WARNING;
13908
13909 argv_find(argv, argc, "neighbors", &idx);
13910 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13911 if (!peer)
13912 return CMD_WARNING;
13913
13914 return bgp_peer_counts(vty, peer, afi, safi, uj);
13915 }
13916
13917 #ifdef KEEP_OLD_VPN_COMMANDS
13918 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13919 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13920 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13921 SHOW_STR
13922 IP_STR
13923 BGP_STR
13924 BGP_VPNVX_HELP_STR
13925 "Display information about all VPNv4 NLRIs\n"
13926 "Detailed information on TCP and BGP neighbor connections\n"
13927 "Neighbor to display information about\n"
13928 "Neighbor to display information about\n"
13929 "Neighbor on BGP configured interface\n"
13930 "Display detailed prefix count information\n"
13931 JSON_STR)
13932 {
13933 int idx_peer = 6;
13934 struct peer *peer;
13935 bool uj = use_json(argc, argv);
13936
13937 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13938 if (!peer)
13939 return CMD_WARNING;
13940
13941 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13942 }
13943
13944 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13945 show_ip_bgp_vpn_all_route_prefix_cmd,
13946 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13947 SHOW_STR
13948 IP_STR
13949 BGP_STR
13950 BGP_VPNVX_HELP_STR
13951 "Display information about all VPNv4 NLRIs\n"
13952 "Network in the BGP routing table to display\n"
13953 "Network in the BGP routing table to display\n"
13954 JSON_STR)
13955 {
13956 int idx = 0;
13957 char *network = NULL;
13958 struct bgp *bgp = bgp_get_default();
13959 if (!bgp) {
13960 vty_out(vty, "Can't find default instance\n");
13961 return CMD_WARNING;
13962 }
13963
13964 if (argv_find(argv, argc, "A.B.C.D", &idx))
13965 network = argv[idx]->arg;
13966 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13967 network = argv[idx]->arg;
13968 else {
13969 vty_out(vty, "Unable to figure out Network\n");
13970 return CMD_WARNING;
13971 }
13972
13973 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13974 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13975 use_json(argc, argv));
13976 }
13977 #endif /* KEEP_OLD_VPN_COMMANDS */
13978
13979 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13980 show_bgp_l2vpn_evpn_route_prefix_cmd,
13981 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13982 SHOW_STR
13983 BGP_STR
13984 L2VPN_HELP_STR
13985 EVPN_HELP_STR
13986 "Network in the BGP routing table to display\n"
13987 "Network in the BGP routing table to display\n"
13988 "Network in the BGP routing table to display\n"
13989 "Network in the BGP routing table to display\n"
13990 JSON_STR)
13991 {
13992 int idx = 0;
13993 char *network = NULL;
13994 int prefix_check = 0;
13995
13996 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13997 argv_find(argv, argc, "X:X::X:X", &idx))
13998 network = argv[idx]->arg;
13999 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
14000 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
14001 network = argv[idx]->arg;
14002 prefix_check = 1;
14003 } else {
14004 vty_out(vty, "Unable to figure out Network\n");
14005 return CMD_WARNING;
14006 }
14007 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
14008 prefix_check, BGP_PATH_SHOW_ALL,
14009 RPKI_NOT_BEING_USED, use_json(argc, argv));
14010 }
14011
14012 static void show_adj_route_header(struct vty *vty, struct peer *peer,
14013 struct bgp_table *table, int *header1,
14014 int *header2, json_object *json,
14015 json_object *json_scode,
14016 json_object *json_ocode, bool wide,
14017 bool detail)
14018 {
14019 uint64_t version = table ? table->version : 0;
14020
14021 if (*header1) {
14022 if (json) {
14023 json_object_int_add(json, "bgpTableVersion", version);
14024 json_object_string_addf(json, "bgpLocalRouterId",
14025 "%pI4", &peer->bgp->router_id);
14026 json_object_int_add(json, "defaultLocPrf",
14027 peer->bgp->default_local_pref);
14028 json_object_int_add(json, "localAS",
14029 peer->change_local_as
14030 ? peer->change_local_as
14031 : peer->local_as);
14032 json_object_object_add(json, "bgpStatusCodes",
14033 json_scode);
14034 json_object_object_add(json, "bgpOriginCodes",
14035 json_ocode);
14036 } else {
14037 vty_out(vty,
14038 "BGP table version is %" PRIu64
14039 ", local router ID is %pI4, vrf id ",
14040 version, &peer->bgp->router_id);
14041 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14042 vty_out(vty, "%s", VRFID_NONE_STR);
14043 else
14044 vty_out(vty, "%u", peer->bgp->vrf_id);
14045 vty_out(vty, "\n");
14046 vty_out(vty, "Default local pref %u, ",
14047 peer->bgp->default_local_pref);
14048 vty_out(vty, "local AS %u\n",
14049 peer->change_local_as ? peer->change_local_as
14050 : peer->local_as);
14051 if (!detail) {
14052 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14053 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14054 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14055 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14056 }
14057 }
14058 *header1 = 0;
14059 }
14060 if (*header2) {
14061 if (!json && !detail)
14062 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14063 : BGP_SHOW_HEADER));
14064 *header2 = 0;
14065 }
14066 }
14067
14068 static void
14069 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14070 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14071 const char *rmap_name, json_object *json, json_object *json_ar,
14072 json_object *json_scode, json_object *json_ocode,
14073 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14074 const struct prefix *match, unsigned long *output_count,
14075 unsigned long *filtered_count)
14076 {
14077 struct bgp_adj_in *ain = NULL;
14078 struct bgp_adj_out *adj = NULL;
14079 struct bgp_dest *dest;
14080 struct bgp *bgp;
14081 struct attr attr;
14082 int ret;
14083 struct update_subgroup *subgrp;
14084 struct peer_af *paf = NULL;
14085 bool route_filtered;
14086 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14087 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14088 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14089 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14090 || (safi == SAFI_EVPN))
14091 ? true
14092 : false;
14093 int display = 0;
14094 json_object *json_net = NULL;
14095
14096 bgp = peer->bgp;
14097
14098 /* If the user supplied a prefix, look for a matching route instead
14099 * of walking the whole table.
14100 */
14101 if (match) {
14102 dest = bgp_node_match(table, match);
14103 if (!dest) {
14104 if (!use_json)
14105 vty_out(vty, "Network not in table\n");
14106 return;
14107 }
14108
14109 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14110
14111 if (rn_p->prefixlen != match->prefixlen) {
14112 if (!use_json)
14113 vty_out(vty, "Network not in table\n");
14114 bgp_dest_unlock_node(dest);
14115 return;
14116 }
14117
14118 if (type == bgp_show_adj_route_received ||
14119 type == bgp_show_adj_route_filtered) {
14120 for (ain = dest->adj_in; ain; ain = ain->next) {
14121 if (ain->peer == peer) {
14122 attr = *ain->attr;
14123 break;
14124 }
14125 }
14126 /* bail out if if adj_out is empty, or
14127 * if the prefix isn't in this peer's
14128 * adj_in
14129 */
14130 if (!ain || ain->peer != peer) {
14131 if (!use_json)
14132 vty_out(vty, "Network not in table\n");
14133 bgp_dest_unlock_node(dest);
14134 return;
14135 }
14136 } else if (type == bgp_show_adj_route_advertised) {
14137 bool peer_found = false;
14138
14139 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14140 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14141 if (paf->peer == peer && adj->attr) {
14142 attr = *adj->attr;
14143 peer_found = true;
14144 break;
14145 }
14146 }
14147 if (peer_found)
14148 break;
14149 }
14150 /* bail out if if adj_out is empty, or
14151 * if the prefix isn't in this peer's
14152 * adj_out
14153 */
14154 if (!paf || !peer_found) {
14155 if (!use_json)
14156 vty_out(vty, "Network not in table\n");
14157 bgp_dest_unlock_node(dest);
14158 return;
14159 }
14160 }
14161
14162 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14163 rmap_name);
14164
14165 if (ret != RMAP_DENY) {
14166 show_adj_route_header(vty, peer, table, header1,
14167 header2, json, json_scode,
14168 json_ocode, wide, detail);
14169
14170 if (use_json)
14171 json_net = json_object_new_object();
14172
14173 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14174 afi, safi, json_net,
14175 BGP_PATH_SHOW_ALL, &display,
14176 RPKI_NOT_BEING_USED);
14177 if (use_json)
14178 json_object_object_addf(json_ar, json_net,
14179 "%pFX", rn_p);
14180 (*output_count)++;
14181 } else
14182 (*filtered_count)++;
14183
14184 bgp_attr_flush(&attr);
14185 bgp_dest_unlock_node(dest);
14186 return;
14187 }
14188
14189
14190 subgrp = peer_subgroup(peer, afi, safi);
14191
14192 if (type == bgp_show_adj_route_advertised && subgrp
14193 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14194 if (use_json) {
14195 json_object_int_add(json, "bgpTableVersion",
14196 table->version);
14197 json_object_string_addf(json, "bgpLocalRouterId",
14198 "%pI4", &bgp->router_id);
14199 json_object_int_add(json, "defaultLocPrf",
14200 bgp->default_local_pref);
14201 json_object_int_add(json, "localAS",
14202 peer->change_local_as
14203 ? peer->change_local_as
14204 : peer->local_as);
14205 json_object_object_add(json, "bgpStatusCodes",
14206 json_scode);
14207 json_object_object_add(json, "bgpOriginCodes",
14208 json_ocode);
14209 json_object_string_add(
14210 json, "bgpOriginatingDefaultNetwork",
14211 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14212 } else {
14213 vty_out(vty,
14214 "BGP table version is %" PRIu64
14215 ", local router ID is %pI4, vrf id ",
14216 table->version, &bgp->router_id);
14217 if (bgp->vrf_id == VRF_UNKNOWN)
14218 vty_out(vty, "%s", VRFID_NONE_STR);
14219 else
14220 vty_out(vty, "%u", bgp->vrf_id);
14221 vty_out(vty, "\n");
14222 vty_out(vty, "Default local pref %u, ",
14223 bgp->default_local_pref);
14224 vty_out(vty, "local AS %u\n",
14225 peer->change_local_as ? peer->change_local_as
14226 : peer->local_as);
14227 if (!detail) {
14228 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14229 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14230 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14231 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14232 }
14233
14234 vty_out(vty, "Originating default network %s\n\n",
14235 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14236 }
14237 (*output_count)++;
14238 *header1 = 0;
14239 }
14240
14241 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14242 if (type == bgp_show_adj_route_received
14243 || type == bgp_show_adj_route_filtered) {
14244 for (ain = dest->adj_in; ain; ain = ain->next) {
14245 if (ain->peer != peer)
14246 continue;
14247
14248 show_adj_route_header(vty, peer, table, header1,
14249 header2, json, json_scode,
14250 json_ocode, wide, detail);
14251
14252 if ((safi == SAFI_MPLS_VPN)
14253 || (safi == SAFI_ENCAP)
14254 || (safi == SAFI_EVPN)) {
14255 if (use_json)
14256 json_object_string_add(
14257 json_ar, "rd", rd_str);
14258 else if (show_rd && rd_str) {
14259 vty_out(vty,
14260 "Route Distinguisher: %s\n",
14261 rd_str);
14262 show_rd = false;
14263 }
14264 }
14265
14266 attr = *ain->attr;
14267 route_filtered = false;
14268
14269 /* Filter prefix using distribute list,
14270 * filter list or prefix list
14271 */
14272 const struct prefix *rn_p =
14273 bgp_dest_get_prefix(dest);
14274 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14275 safi))
14276 == FILTER_DENY)
14277 route_filtered = true;
14278
14279 /* Filter prefix using route-map */
14280 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14281 safi, rmap_name, NULL,
14282 0, NULL);
14283
14284 if (type == bgp_show_adj_route_filtered &&
14285 !route_filtered && ret != RMAP_DENY) {
14286 bgp_attr_flush(&attr);
14287 continue;
14288 }
14289
14290 if (type == bgp_show_adj_route_received
14291 && (route_filtered || ret == RMAP_DENY))
14292 (*filtered_count)++;
14293
14294 if (detail) {
14295 if (use_json)
14296 json_net =
14297 json_object_new_object();
14298 bgp_show_path_info(
14299 NULL /* prefix_rd */, dest, vty,
14300 bgp, afi, safi, json_net,
14301 BGP_PATH_SHOW_ALL, &display,
14302 RPKI_NOT_BEING_USED);
14303 if (use_json)
14304 json_object_object_addf(
14305 json_ar, json_net,
14306 "%pFX", rn_p);
14307 } else
14308 route_vty_out_tmp(vty, dest, rn_p,
14309 &attr, safi, use_json,
14310 json_ar, wide);
14311 bgp_attr_flush(&attr);
14312 (*output_count)++;
14313 }
14314 } else if (type == bgp_show_adj_route_advertised) {
14315 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14316 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14317 if (paf->peer != peer || !adj->attr)
14318 continue;
14319
14320 show_adj_route_header(
14321 vty, peer, table, header1,
14322 header2, json, json_scode,
14323 json_ocode, wide, detail);
14324
14325 const struct prefix *rn_p =
14326 bgp_dest_get_prefix(dest);
14327
14328 attr = *adj->attr;
14329 ret = bgp_output_modifier(
14330 peer, rn_p, &attr, afi, safi,
14331 rmap_name);
14332
14333 if (ret != RMAP_DENY) {
14334 if ((safi == SAFI_MPLS_VPN)
14335 || (safi == SAFI_ENCAP)
14336 || (safi == SAFI_EVPN)) {
14337 if (use_json)
14338 json_object_string_add(
14339 json_ar,
14340 "rd",
14341 rd_str);
14342 else if (show_rd
14343 && rd_str) {
14344 vty_out(vty,
14345 "Route Distinguisher: %s\n",
14346 rd_str);
14347 show_rd = false;
14348 }
14349 }
14350 if (detail) {
14351 if (use_json)
14352 json_net =
14353 json_object_new_object();
14354 bgp_show_path_info(
14355 NULL /* prefix_rd
14356 */
14357 ,
14358 dest, vty, bgp,
14359 afi, safi,
14360 json_net,
14361 BGP_PATH_SHOW_ALL,
14362 &display,
14363 RPKI_NOT_BEING_USED);
14364 if (use_json)
14365 json_object_object_addf(
14366 json_ar,
14367 json_net,
14368 "%pFX",
14369 rn_p);
14370 } else
14371 route_vty_out_tmp(
14372 vty, dest, rn_p,
14373 &attr, safi,
14374 use_json,
14375 json_ar, wide);
14376 (*output_count)++;
14377 } else {
14378 (*filtered_count)++;
14379 }
14380
14381 bgp_attr_flush(&attr);
14382 }
14383 } else if (type == bgp_show_adj_route_bestpath) {
14384 struct bgp_path_info *pi;
14385
14386 show_adj_route_header(vty, peer, table, header1,
14387 header2, json, json_scode,
14388 json_ocode, wide, detail);
14389
14390 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14391
14392 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14393 pi = pi->next) {
14394 if (pi->peer != peer)
14395 continue;
14396
14397 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14398 continue;
14399
14400 if (detail) {
14401 if (use_json)
14402 json_net =
14403 json_object_new_object();
14404 bgp_show_path_info(
14405 NULL /* prefix_rd */, dest, vty,
14406 bgp, afi, safi, json_net,
14407 BGP_PATH_SHOW_BESTPATH,
14408 &display, RPKI_NOT_BEING_USED);
14409 if (use_json)
14410 json_object_object_addf(
14411 json_ar, json_net,
14412 "%pFX", rn_p);
14413 } else
14414 route_vty_out_tmp(
14415 vty, dest, rn_p, pi->attr, safi,
14416 use_json, json_ar, wide);
14417 (*output_count)++;
14418 }
14419 }
14420 }
14421 }
14422
14423 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14424 safi_t safi, enum bgp_show_adj_route_type type,
14425 const char *rmap_name, const struct prefix *match,
14426 uint16_t show_flags)
14427 {
14428 struct bgp *bgp;
14429 struct bgp_table *table;
14430 json_object *json = NULL;
14431 json_object *json_scode = NULL;
14432 json_object *json_ocode = NULL;
14433 json_object *json_ar = NULL;
14434 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14435
14436 /* Init BGP headers here so they're only displayed once
14437 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14438 */
14439 int header1 = 1;
14440 int header2 = 1;
14441
14442 /*
14443 * Initialize variables for each RD
14444 * All prefixes under an RD is aggregated within "json_routes"
14445 */
14446 char rd_str[BUFSIZ] = {0};
14447 json_object *json_routes = NULL;
14448
14449
14450 /* For 2-tier tables, prefix counts need to be
14451 * maintained across multiple runs of show_adj_route()
14452 */
14453 unsigned long output_count_per_rd;
14454 unsigned long filtered_count_per_rd;
14455 unsigned long output_count = 0;
14456 unsigned long filtered_count = 0;
14457
14458 if (use_json) {
14459 json = json_object_new_object();
14460 json_ar = json_object_new_object();
14461 json_scode = json_object_new_object();
14462 json_ocode = json_object_new_object();
14463 #if CONFDATE > 20231208
14464 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14465 #endif
14466 json_object_string_add(json_scode, "suppressed", "s");
14467 json_object_string_add(json_scode, "damped", "d");
14468 json_object_string_add(json_scode, "history", "h");
14469 json_object_string_add(json_scode, "valid", "*");
14470 json_object_string_add(json_scode, "best", ">");
14471 json_object_string_add(json_scode, "multipath", "=");
14472 json_object_string_add(json_scode, "internal", "i");
14473 json_object_string_add(json_scode, "ribFailure", "r");
14474 json_object_string_add(json_scode, "stale", "S");
14475 json_object_string_add(json_scode, "removed", "R");
14476
14477 #if CONFDATE > 20231208
14478 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14479 #endif
14480 json_object_string_add(json_ocode, "igp", "i");
14481 json_object_string_add(json_ocode, "egp", "e");
14482 json_object_string_add(json_ocode, "incomplete", "?");
14483 }
14484
14485 if (!peer || !peer->afc[afi][safi]) {
14486 if (use_json) {
14487 json_object_string_add(
14488 json, "warning",
14489 "No such neighbor or address family");
14490 vty_out(vty, "%s\n", json_object_to_json_string(json));
14491 json_object_free(json);
14492 json_object_free(json_ar);
14493 json_object_free(json_scode);
14494 json_object_free(json_ocode);
14495 } else
14496 vty_out(vty, "%% No such neighbor or address family\n");
14497
14498 return CMD_WARNING;
14499 }
14500
14501 if ((type == bgp_show_adj_route_received
14502 || type == bgp_show_adj_route_filtered)
14503 && !CHECK_FLAG(peer->af_flags[afi][safi],
14504 PEER_FLAG_SOFT_RECONFIG)) {
14505 if (use_json) {
14506 json_object_string_add(
14507 json, "warning",
14508 "Inbound soft reconfiguration not enabled");
14509 vty_out(vty, "%s\n", json_object_to_json_string(json));
14510 json_object_free(json);
14511 json_object_free(json_ar);
14512 json_object_free(json_scode);
14513 json_object_free(json_ocode);
14514 } else
14515 vty_out(vty,
14516 "%% Inbound soft reconfiguration not enabled\n");
14517
14518 return CMD_WARNING;
14519 }
14520
14521 bgp = peer->bgp;
14522
14523 /* labeled-unicast routes live in the unicast table */
14524 if (safi == SAFI_LABELED_UNICAST)
14525 table = bgp->rib[afi][SAFI_UNICAST];
14526 else
14527 table = bgp->rib[afi][safi];
14528
14529 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14530 || (safi == SAFI_EVPN)) {
14531
14532 struct bgp_dest *dest;
14533
14534 for (dest = bgp_table_top(table); dest;
14535 dest = bgp_route_next(dest)) {
14536 table = bgp_dest_get_bgp_table_info(dest);
14537 if (!table)
14538 continue;
14539
14540 output_count_per_rd = 0;
14541 filtered_count_per_rd = 0;
14542
14543 if (use_json)
14544 json_routes = json_object_new_object();
14545
14546 const struct prefix_rd *prd;
14547 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14548 dest);
14549
14550 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14551 bgp->asnotation);
14552
14553 show_adj_route(
14554 vty, peer, table, afi, safi, type, rmap_name,
14555 json, json_routes, json_scode, json_ocode,
14556 show_flags, &header1, &header2, rd_str, match,
14557 &output_count_per_rd, &filtered_count_per_rd);
14558
14559 /* Don't include an empty RD in the output! */
14560 if (json_routes && (output_count_per_rd > 0))
14561 json_object_object_add(json_ar, rd_str,
14562 json_routes);
14563
14564 output_count += output_count_per_rd;
14565 filtered_count += filtered_count_per_rd;
14566 }
14567 } else
14568 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14569 json, json_ar, json_scode, json_ocode,
14570 show_flags, &header1, &header2, rd_str, match,
14571 &output_count, &filtered_count);
14572
14573 if (use_json) {
14574 if (type == bgp_show_adj_route_advertised)
14575 json_object_object_add(json, "advertisedRoutes",
14576 json_ar);
14577 else
14578 json_object_object_add(json, "receivedRoutes", json_ar);
14579 json_object_int_add(json, "totalPrefixCounter", output_count);
14580 json_object_int_add(json, "filteredPrefixCounter",
14581 filtered_count);
14582
14583 /*
14584 * These fields only give up ownership to `json` when `header1`
14585 * is used (set to zero). See code in `show_adj_route` and
14586 * `show_adj_route_header`.
14587 */
14588 if (header1 == 1) {
14589 json_object_free(json_scode);
14590 json_object_free(json_ocode);
14591 }
14592
14593 vty_json(vty, json);
14594 } else if (output_count > 0) {
14595 if (!match && filtered_count > 0)
14596 vty_out(vty,
14597 "\nTotal number of prefixes %ld (%ld filtered)\n",
14598 output_count, filtered_count);
14599 else
14600 vty_out(vty, "\nTotal number of prefixes %ld\n",
14601 output_count);
14602 }
14603
14604 return CMD_SUCCESS;
14605 }
14606
14607 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14608 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14609 "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]",
14610 SHOW_STR
14611 IP_STR
14612 BGP_STR
14613 BGP_INSTANCE_HELP_STR
14614 BGP_AFI_HELP_STR
14615 BGP_SAFI_WITH_LABEL_HELP_STR
14616 "Detailed information on TCP and BGP neighbor connections\n"
14617 "Neighbor to display information about\n"
14618 "Neighbor to display information about\n"
14619 "Neighbor on BGP configured interface\n"
14620 "Display the routes selected by best path\n"
14621 "Display detailed version of routes\n"
14622 JSON_STR
14623 "Increase table width for longer prefixes\n")
14624 {
14625 afi_t afi = AFI_IP6;
14626 safi_t safi = SAFI_UNICAST;
14627 char *rmap_name = NULL;
14628 char *peerstr = NULL;
14629 struct bgp *bgp = NULL;
14630 struct peer *peer;
14631 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14632 int idx = 0;
14633 uint16_t show_flags = 0;
14634
14635 if (detail)
14636 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14637
14638 if (uj)
14639 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14640
14641 if (wide)
14642 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14643
14644 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14645 &bgp, uj);
14646
14647 if (!idx)
14648 return CMD_WARNING;
14649
14650 argv_find(argv, argc, "neighbors", &idx);
14651 peerstr = argv[++idx]->arg;
14652
14653 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14654 if (!peer)
14655 return CMD_WARNING;
14656
14657 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14658 show_flags);
14659 }
14660
14661 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14662 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14663 "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]",
14664 SHOW_STR
14665 IP_STR
14666 BGP_STR
14667 BGP_INSTANCE_HELP_STR
14668 BGP_AFI_HELP_STR
14669 BGP_SAFI_WITH_LABEL_HELP_STR
14670 "Display the entries for all address families\n"
14671 "Detailed information on TCP and BGP neighbor connections\n"
14672 "Neighbor to display information about\n"
14673 "Neighbor to display information about\n"
14674 "Neighbor on BGP configured interface\n"
14675 "Display the routes advertised to a BGP neighbor\n"
14676 "Display the received routes from neighbor\n"
14677 "Display the filtered routes received from neighbor\n"
14678 "Route-map to modify the attributes\n"
14679 "Name of the route map\n"
14680 "IPv4 prefix\n"
14681 "IPv6 prefix\n"
14682 "Display detailed version of routes\n"
14683 JSON_STR
14684 "Increase table width for longer prefixes\n")
14685 {
14686 afi_t afi = AFI_IP6;
14687 safi_t safi = SAFI_UNICAST;
14688 char *peerstr = NULL;
14689 struct bgp *bgp = NULL;
14690 struct peer *peer;
14691 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14692 int idx = 0;
14693 bool first = true;
14694 uint16_t show_flags = 0;
14695 struct listnode *node;
14696 struct bgp *abgp;
14697
14698 if (detail || prefix_str)
14699 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14700
14701 if (uj) {
14702 argc--;
14703 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14704 }
14705
14706 if (all) {
14707 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14708 if (argv_find(argv, argc, "ipv4", &idx))
14709 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14710
14711 if (argv_find(argv, argc, "ipv6", &idx))
14712 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14713 }
14714
14715 if (wide)
14716 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14717
14718 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14719 &bgp, uj);
14720 if (!idx)
14721 return CMD_WARNING;
14722
14723 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14724 argv_find(argv, argc, "neighbors", &idx);
14725 peerstr = argv[++idx]->arg;
14726
14727 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14728 if (!peer)
14729 return CMD_WARNING;
14730
14731 if (argv_find(argv, argc, "advertised-routes", &idx))
14732 type = bgp_show_adj_route_advertised;
14733 else if (argv_find(argv, argc, "received-routes", &idx))
14734 type = bgp_show_adj_route_received;
14735 else if (argv_find(argv, argc, "filtered-routes", &idx))
14736 type = bgp_show_adj_route_filtered;
14737
14738 if (!all)
14739 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14740 prefix_str ? prefix : NULL, show_flags);
14741 if (uj)
14742 vty_out(vty, "{\n");
14743
14744 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14745 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14746 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14747 : AFI_IP6;
14748 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14749 FOREACH_SAFI (safi) {
14750 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14751 continue;
14752
14753 if (uj) {
14754 if (first)
14755 first = false;
14756 else
14757 vty_out(vty, ",\n");
14758 vty_out(vty, "\"%s\":",
14759 get_afi_safi_str(afi, safi,
14760 true));
14761 } else
14762 vty_out(vty,
14763 "\nFor address family: %s\n",
14764 get_afi_safi_str(afi, safi,
14765 false));
14766
14767 peer_adj_routes(vty, peer, afi, safi, type,
14768 route_map, prefix, show_flags);
14769 }
14770 }
14771 } else {
14772 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14773 FOREACH_AFI_SAFI (afi, safi) {
14774 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14775 continue;
14776
14777 if (uj) {
14778 if (first)
14779 first = false;
14780 else
14781 vty_out(vty, ",\n");
14782 vty_out(vty, "\"%s\":",
14783 get_afi_safi_str(afi, safi,
14784 true));
14785 } else
14786 vty_out(vty,
14787 "\nFor address family: %s\n",
14788 get_afi_safi_str(afi, safi,
14789 false));
14790
14791 peer_adj_routes(vty, peer, afi, safi, type,
14792 route_map, prefix, show_flags);
14793 }
14794 }
14795 }
14796 if (uj)
14797 vty_out(vty, "}\n");
14798
14799 return CMD_SUCCESS;
14800 }
14801
14802 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14803 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14804 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14805 SHOW_STR
14806 IP_STR
14807 BGP_STR
14808 BGP_INSTANCE_HELP_STR
14809 BGP_AF_STR
14810 BGP_AF_STR
14811 BGP_AF_MODIFIER_STR
14812 "Detailed information on TCP and BGP neighbor connections\n"
14813 "Neighbor to display information about\n"
14814 "Neighbor to display information about\n"
14815 "Neighbor on BGP configured interface\n"
14816 "Display information received from a BGP neighbor\n"
14817 "Display the prefixlist filter\n"
14818 JSON_STR)
14819 {
14820 afi_t afi = AFI_IP6;
14821 safi_t safi = SAFI_UNICAST;
14822 char *peerstr = NULL;
14823 char name[BUFSIZ];
14824 struct peer *peer;
14825 int count;
14826 int idx = 0;
14827 struct bgp *bgp = NULL;
14828 bool uj = use_json(argc, argv);
14829
14830 if (uj)
14831 argc--;
14832
14833 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14834 &bgp, uj);
14835 if (!idx)
14836 return CMD_WARNING;
14837
14838 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14839 argv_find(argv, argc, "neighbors", &idx);
14840 peerstr = argv[++idx]->arg;
14841
14842 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14843 if (!peer)
14844 return CMD_WARNING;
14845
14846 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14847 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14848 if (count) {
14849 if (!uj)
14850 vty_out(vty, "Address Family: %s\n",
14851 get_afi_safi_str(afi, safi, false));
14852 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14853 } else {
14854 if (uj)
14855 vty_out(vty, "{}\n");
14856 else
14857 vty_out(vty, "No functional output\n");
14858 }
14859
14860 return CMD_SUCCESS;
14861 }
14862
14863 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14864 afi_t afi, safi_t safi,
14865 enum bgp_show_type type, bool use_json)
14866 {
14867 uint16_t show_flags = 0;
14868
14869 if (use_json)
14870 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14871
14872 if (!peer || !peer->afc[afi][safi]) {
14873 if (use_json) {
14874 json_object *json_no = NULL;
14875 json_no = json_object_new_object();
14876 json_object_string_add(
14877 json_no, "warning",
14878 "No such neighbor or address family");
14879 vty_out(vty, "%s\n",
14880 json_object_to_json_string(json_no));
14881 json_object_free(json_no);
14882 } else
14883 vty_out(vty, "%% No such neighbor or address family\n");
14884 return CMD_WARNING;
14885 }
14886
14887 /* labeled-unicast routes live in the unicast table */
14888 if (safi == SAFI_LABELED_UNICAST)
14889 safi = SAFI_UNICAST;
14890
14891 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14892 RPKI_NOT_BEING_USED);
14893 }
14894
14895 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14896 show_ip_bgp_flowspec_routes_detailed_cmd,
14897 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14898 SHOW_STR
14899 IP_STR
14900 BGP_STR
14901 BGP_INSTANCE_HELP_STR
14902 BGP_AFI_HELP_STR
14903 "SAFI Flowspec\n"
14904 "Detailed information on flowspec entries\n"
14905 JSON_STR)
14906 {
14907 afi_t afi = AFI_IP6;
14908 safi_t safi = SAFI_UNICAST;
14909 struct bgp *bgp = NULL;
14910 int idx = 0;
14911 bool uj = use_json(argc, argv);
14912 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14913
14914 if (uj) {
14915 argc--;
14916 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14917 }
14918
14919 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14920 &bgp, uj);
14921 if (!idx)
14922 return CMD_WARNING;
14923
14924 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14925 show_flags, RPKI_NOT_BEING_USED);
14926 }
14927
14928 DEFUN (show_ip_bgp_neighbor_routes,
14929 show_ip_bgp_neighbor_routes_cmd,
14930 "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]",
14931 SHOW_STR
14932 IP_STR
14933 BGP_STR
14934 BGP_INSTANCE_HELP_STR
14935 BGP_AFI_HELP_STR
14936 BGP_SAFI_WITH_LABEL_HELP_STR
14937 "Detailed information on TCP and BGP neighbor connections\n"
14938 "Neighbor to display information about\n"
14939 "Neighbor to display information about\n"
14940 "Neighbor on BGP configured interface\n"
14941 "Display flap statistics of the routes learned from neighbor\n"
14942 "Display the dampened routes received from neighbor\n"
14943 "Display routes learned from neighbor\n"
14944 JSON_STR)
14945 {
14946 char *peerstr = NULL;
14947 struct bgp *bgp = NULL;
14948 afi_t afi = AFI_IP6;
14949 safi_t safi = SAFI_UNICAST;
14950 struct peer *peer;
14951 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14952 int idx = 0;
14953 bool uj = use_json(argc, argv);
14954
14955 if (uj)
14956 argc--;
14957
14958 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14959 &bgp, uj);
14960 if (!idx)
14961 return CMD_WARNING;
14962
14963 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14964 argv_find(argv, argc, "neighbors", &idx);
14965 peerstr = argv[++idx]->arg;
14966
14967 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14968 if (!peer)
14969 return CMD_WARNING;
14970
14971 if (argv_find(argv, argc, "flap-statistics", &idx))
14972 sh_type = bgp_show_type_flap_neighbor;
14973 else if (argv_find(argv, argc, "dampened-routes", &idx))
14974 sh_type = bgp_show_type_damp_neighbor;
14975 else if (argv_find(argv, argc, "routes", &idx))
14976 sh_type = bgp_show_type_neighbor;
14977
14978 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14979 }
14980
14981 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14982
14983 struct bgp_distance {
14984 /* Distance value for the IP source prefix. */
14985 uint8_t distance;
14986
14987 /* Name of the access-list to be matched. */
14988 char *access_list;
14989 };
14990
14991 DEFUN (show_bgp_afi_vpn_rd_route,
14992 show_bgp_afi_vpn_rd_route_cmd,
14993 "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]",
14994 SHOW_STR
14995 BGP_STR
14996 BGP_AFI_HELP_STR
14997 BGP_AF_MODIFIER_STR
14998 "Display information for a route distinguisher\n"
14999 "Route Distinguisher\n"
15000 "All Route Distinguishers\n"
15001 "Network in the BGP routing table to display\n"
15002 "Network in the BGP routing table to display\n"
15003 JSON_STR)
15004 {
15005 int ret;
15006 struct prefix_rd prd;
15007 afi_t afi = AFI_MAX;
15008 int idx = 0;
15009
15010 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
15011 vty_out(vty, "%% Malformed Address Family\n");
15012 return CMD_WARNING;
15013 }
15014
15015 if (!strcmp(argv[5]->arg, "all"))
15016 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
15017 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
15018 RPKI_NOT_BEING_USED,
15019 use_json(argc, argv));
15020
15021 ret = str2prefix_rd(argv[5]->arg, &prd);
15022 if (!ret) {
15023 vty_out(vty, "%% Malformed Route Distinguisher\n");
15024 return CMD_WARNING;
15025 }
15026
15027 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
15028 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
15029 use_json(argc, argv));
15030 }
15031
15032 static struct bgp_distance *bgp_distance_new(void)
15033 {
15034 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
15035 }
15036
15037 static void bgp_distance_free(struct bgp_distance *bdistance)
15038 {
15039 XFREE(MTYPE_BGP_DISTANCE, bdistance);
15040 }
15041
15042 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15043 const char *ip_str, const char *access_list_str)
15044 {
15045 int ret;
15046 afi_t afi;
15047 safi_t safi;
15048 struct prefix p;
15049 uint8_t distance;
15050 struct bgp_dest *dest;
15051 struct bgp_distance *bdistance;
15052
15053 afi = bgp_node_afi(vty);
15054 safi = bgp_node_safi(vty);
15055
15056 ret = str2prefix(ip_str, &p);
15057 if (ret == 0) {
15058 vty_out(vty, "Malformed prefix\n");
15059 return CMD_WARNING_CONFIG_FAILED;
15060 }
15061
15062 distance = atoi(distance_str);
15063
15064 /* Get BGP distance node. */
15065 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15066 bdistance = bgp_dest_get_bgp_distance_info(dest);
15067 if (bdistance)
15068 bgp_dest_unlock_node(dest);
15069 else {
15070 bdistance = bgp_distance_new();
15071 bgp_dest_set_bgp_distance_info(dest, bdistance);
15072 }
15073
15074 /* Set distance value. */
15075 bdistance->distance = distance;
15076
15077 /* Reset access-list configuration. */
15078 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15079 if (access_list_str)
15080 bdistance->access_list =
15081 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15082
15083 return CMD_SUCCESS;
15084 }
15085
15086 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15087 const char *ip_str, const char *access_list_str)
15088 {
15089 int ret;
15090 afi_t afi;
15091 safi_t safi;
15092 struct prefix p;
15093 int distance;
15094 struct bgp_dest *dest;
15095 struct bgp_distance *bdistance;
15096
15097 afi = bgp_node_afi(vty);
15098 safi = bgp_node_safi(vty);
15099
15100 ret = str2prefix(ip_str, &p);
15101 if (ret == 0) {
15102 vty_out(vty, "Malformed prefix\n");
15103 return CMD_WARNING_CONFIG_FAILED;
15104 }
15105
15106 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15107 if (!dest) {
15108 vty_out(vty, "Can't find specified prefix\n");
15109 return CMD_WARNING_CONFIG_FAILED;
15110 }
15111
15112 bdistance = bgp_dest_get_bgp_distance_info(dest);
15113 distance = atoi(distance_str);
15114
15115 if (bdistance->distance != distance) {
15116 vty_out(vty, "Distance does not match configured\n");
15117 bgp_dest_unlock_node(dest);
15118 return CMD_WARNING_CONFIG_FAILED;
15119 }
15120
15121 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15122 bgp_distance_free(bdistance);
15123
15124 bgp_dest_set_bgp_path_info(dest, NULL);
15125 bgp_dest_unlock_node(dest);
15126 bgp_dest_unlock_node(dest);
15127
15128 return CMD_SUCCESS;
15129 }
15130
15131 /* Apply BGP information to distance method. */
15132 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15133 afi_t afi, safi_t safi, struct bgp *bgp)
15134 {
15135 struct bgp_dest *dest;
15136 struct prefix q = {0};
15137 struct peer *peer;
15138 struct bgp_distance *bdistance;
15139 struct access_list *alist;
15140 struct bgp_static *bgp_static;
15141 struct bgp_path_info *bpi_ultimate;
15142
15143 if (!bgp)
15144 return 0;
15145
15146 peer = pinfo->peer;
15147
15148 if (pinfo->attr->distance)
15149 return pinfo->attr->distance;
15150
15151 /* get peer origin to calculate appropriate distance */
15152 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15153 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15154 peer = bpi_ultimate->peer;
15155 }
15156
15157 /* Check source address.
15158 * Note: for aggregate route, peer can have unspec af type.
15159 */
15160 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15161 && !sockunion2hostprefix(&peer->su, &q))
15162 return 0;
15163
15164 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15165 if (dest) {
15166 bdistance = bgp_dest_get_bgp_distance_info(dest);
15167 bgp_dest_unlock_node(dest);
15168
15169 if (bdistance->access_list) {
15170 alist = access_list_lookup(afi, bdistance->access_list);
15171 if (alist
15172 && access_list_apply(alist, p) == FILTER_PERMIT)
15173 return bdistance->distance;
15174 } else
15175 return bdistance->distance;
15176 }
15177
15178 /* Backdoor check. */
15179 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15180 if (dest) {
15181 bgp_static = bgp_dest_get_bgp_static_info(dest);
15182 bgp_dest_unlock_node(dest);
15183
15184 if (bgp_static->backdoor) {
15185 if (bgp->distance_local[afi][safi])
15186 return bgp->distance_local[afi][safi];
15187 else
15188 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15189 }
15190 }
15191
15192 if (peer->sort == BGP_PEER_EBGP) {
15193 if (bgp->distance_ebgp[afi][safi])
15194 return bgp->distance_ebgp[afi][safi];
15195 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15196 } else if (peer->sort == BGP_PEER_IBGP) {
15197 if (bgp->distance_ibgp[afi][safi])
15198 return bgp->distance_ibgp[afi][safi];
15199 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15200 } else {
15201 if (bgp->distance_local[afi][safi])
15202 return bgp->distance_local[afi][safi];
15203 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15204 }
15205 }
15206
15207 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15208 * we should tell ZEBRA update the routes for a specific
15209 * AFI/SAFI to reflect changes in RIB.
15210 */
15211 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15212 afi_t update_afi,
15213 safi_t update_safi)
15214 {
15215 afi_t afi;
15216 safi_t safi;
15217
15218 FOREACH_AFI_SAFI (afi, safi) {
15219 if (!bgp_fibupd_safi(safi))
15220 continue;
15221
15222 if (afi != update_afi && safi != update_safi)
15223 continue;
15224
15225 if (BGP_DEBUG(zebra, ZEBRA))
15226 zlog_debug(
15227 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15228 __func__, afi, safi);
15229 bgp_zebra_announce_table(bgp, afi, safi);
15230 }
15231 }
15232
15233 DEFUN (bgp_distance,
15234 bgp_distance_cmd,
15235 "distance bgp (1-255) (1-255) (1-255)",
15236 "Define an administrative distance\n"
15237 "BGP distance\n"
15238 "Distance for routes external to the AS\n"
15239 "Distance for routes internal to the AS\n"
15240 "Distance for local routes\n")
15241 {
15242 VTY_DECLVAR_CONTEXT(bgp, bgp);
15243 int idx_number = 2;
15244 int idx_number_2 = 3;
15245 int idx_number_3 = 4;
15246 int distance_ebgp = atoi(argv[idx_number]->arg);
15247 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15248 int distance_local = atoi(argv[idx_number_3]->arg);
15249 afi_t afi;
15250 safi_t safi;
15251
15252 afi = bgp_node_afi(vty);
15253 safi = bgp_node_safi(vty);
15254
15255 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15256 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15257 || bgp->distance_local[afi][safi] != distance_local) {
15258 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15259 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15260 bgp->distance_local[afi][safi] = distance_local;
15261 bgp_announce_routes_distance_update(bgp, afi, safi);
15262 }
15263 return CMD_SUCCESS;
15264 }
15265
15266 DEFUN (no_bgp_distance,
15267 no_bgp_distance_cmd,
15268 "no distance bgp [(1-255) (1-255) (1-255)]",
15269 NO_STR
15270 "Define an administrative distance\n"
15271 "BGP distance\n"
15272 "Distance for routes external to the AS\n"
15273 "Distance for routes internal to the AS\n"
15274 "Distance for local routes\n")
15275 {
15276 VTY_DECLVAR_CONTEXT(bgp, bgp);
15277 afi_t afi;
15278 safi_t safi;
15279
15280 afi = bgp_node_afi(vty);
15281 safi = bgp_node_safi(vty);
15282
15283 if (bgp->distance_ebgp[afi][safi] != 0
15284 || bgp->distance_ibgp[afi][safi] != 0
15285 || bgp->distance_local[afi][safi] != 0) {
15286 bgp->distance_ebgp[afi][safi] = 0;
15287 bgp->distance_ibgp[afi][safi] = 0;
15288 bgp->distance_local[afi][safi] = 0;
15289 bgp_announce_routes_distance_update(bgp, afi, safi);
15290 }
15291 return CMD_SUCCESS;
15292 }
15293
15294
15295 DEFUN (bgp_distance_source,
15296 bgp_distance_source_cmd,
15297 "distance (1-255) A.B.C.D/M",
15298 "Define an administrative distance\n"
15299 "Administrative distance\n"
15300 "IP source prefix\n")
15301 {
15302 int idx_number = 1;
15303 int idx_ipv4_prefixlen = 2;
15304 bgp_distance_set(vty, argv[idx_number]->arg,
15305 argv[idx_ipv4_prefixlen]->arg, NULL);
15306 return CMD_SUCCESS;
15307 }
15308
15309 DEFUN (no_bgp_distance_source,
15310 no_bgp_distance_source_cmd,
15311 "no distance (1-255) A.B.C.D/M",
15312 NO_STR
15313 "Define an administrative distance\n"
15314 "Administrative distance\n"
15315 "IP source prefix\n")
15316 {
15317 int idx_number = 2;
15318 int idx_ipv4_prefixlen = 3;
15319 bgp_distance_unset(vty, argv[idx_number]->arg,
15320 argv[idx_ipv4_prefixlen]->arg, NULL);
15321 return CMD_SUCCESS;
15322 }
15323
15324 DEFUN (bgp_distance_source_access_list,
15325 bgp_distance_source_access_list_cmd,
15326 "distance (1-255) A.B.C.D/M WORD",
15327 "Define an administrative distance\n"
15328 "Administrative distance\n"
15329 "IP source prefix\n"
15330 "Access list name\n")
15331 {
15332 int idx_number = 1;
15333 int idx_ipv4_prefixlen = 2;
15334 int idx_word = 3;
15335 bgp_distance_set(vty, argv[idx_number]->arg,
15336 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15337 return CMD_SUCCESS;
15338 }
15339
15340 DEFUN (no_bgp_distance_source_access_list,
15341 no_bgp_distance_source_access_list_cmd,
15342 "no distance (1-255) A.B.C.D/M WORD",
15343 NO_STR
15344 "Define an administrative distance\n"
15345 "Administrative distance\n"
15346 "IP source prefix\n"
15347 "Access list name\n")
15348 {
15349 int idx_number = 2;
15350 int idx_ipv4_prefixlen = 3;
15351 int idx_word = 4;
15352 bgp_distance_unset(vty, argv[idx_number]->arg,
15353 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15354 return CMD_SUCCESS;
15355 }
15356
15357 DEFUN (ipv6_bgp_distance_source,
15358 ipv6_bgp_distance_source_cmd,
15359 "distance (1-255) X:X::X:X/M",
15360 "Define an administrative distance\n"
15361 "Administrative distance\n"
15362 "IP source prefix\n")
15363 {
15364 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15365 return CMD_SUCCESS;
15366 }
15367
15368 DEFUN (no_ipv6_bgp_distance_source,
15369 no_ipv6_bgp_distance_source_cmd,
15370 "no distance (1-255) X:X::X:X/M",
15371 NO_STR
15372 "Define an administrative distance\n"
15373 "Administrative distance\n"
15374 "IP source prefix\n")
15375 {
15376 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15377 return CMD_SUCCESS;
15378 }
15379
15380 DEFUN (ipv6_bgp_distance_source_access_list,
15381 ipv6_bgp_distance_source_access_list_cmd,
15382 "distance (1-255) X:X::X:X/M WORD",
15383 "Define an administrative distance\n"
15384 "Administrative distance\n"
15385 "IP source prefix\n"
15386 "Access list name\n")
15387 {
15388 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15389 return CMD_SUCCESS;
15390 }
15391
15392 DEFUN (no_ipv6_bgp_distance_source_access_list,
15393 no_ipv6_bgp_distance_source_access_list_cmd,
15394 "no distance (1-255) X:X::X:X/M WORD",
15395 NO_STR
15396 "Define an administrative distance\n"
15397 "Administrative distance\n"
15398 "IP source prefix\n"
15399 "Access list name\n")
15400 {
15401 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15402 return CMD_SUCCESS;
15403 }
15404
15405 DEFUN (bgp_damp_set,
15406 bgp_damp_set_cmd,
15407 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15408 "BGP Specific commands\n"
15409 "Enable route-flap dampening\n"
15410 "Half-life time for the penalty\n"
15411 "Value to start reusing a route\n"
15412 "Value to start suppressing a route\n"
15413 "Maximum duration to suppress a stable route\n")
15414 {
15415 VTY_DECLVAR_CONTEXT(bgp, bgp);
15416 int idx_half_life = 2;
15417 int idx_reuse = 3;
15418 int idx_suppress = 4;
15419 int idx_max_suppress = 5;
15420 int half = DEFAULT_HALF_LIFE * 60;
15421 int reuse = DEFAULT_REUSE;
15422 int suppress = DEFAULT_SUPPRESS;
15423 int max = 4 * half;
15424
15425 if (argc == 6) {
15426 half = atoi(argv[idx_half_life]->arg) * 60;
15427 reuse = atoi(argv[idx_reuse]->arg);
15428 suppress = atoi(argv[idx_suppress]->arg);
15429 max = atoi(argv[idx_max_suppress]->arg) * 60;
15430 } else if (argc == 3) {
15431 half = atoi(argv[idx_half_life]->arg) * 60;
15432 max = 4 * half;
15433 }
15434
15435 /*
15436 * These can't be 0 but our SA doesn't understand the
15437 * way our cli is constructed
15438 */
15439 assert(reuse);
15440 assert(half);
15441 if (suppress < reuse) {
15442 vty_out(vty,
15443 "Suppress value cannot be less than reuse value \n");
15444 return 0;
15445 }
15446
15447 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15448 reuse, suppress, max);
15449 }
15450
15451 DEFUN (bgp_damp_unset,
15452 bgp_damp_unset_cmd,
15453 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15454 NO_STR
15455 "BGP Specific commands\n"
15456 "Enable route-flap dampening\n"
15457 "Half-life time for the penalty\n"
15458 "Value to start reusing a route\n"
15459 "Value to start suppressing a route\n"
15460 "Maximum duration to suppress a stable route\n")
15461 {
15462 VTY_DECLVAR_CONTEXT(bgp, bgp);
15463 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15464 }
15465
15466 /* Display specified route of BGP table. */
15467 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15468 const char *ip_str, afi_t afi, safi_t safi,
15469 struct prefix_rd *prd, int prefix_check)
15470 {
15471 int ret;
15472 struct prefix match;
15473 struct bgp_dest *dest;
15474 struct bgp_dest *rm;
15475 struct bgp_path_info *pi;
15476 struct bgp_path_info *pi_temp;
15477 struct bgp *bgp;
15478 struct bgp_table *table;
15479
15480 /* BGP structure lookup. */
15481 if (view_name) {
15482 bgp = bgp_lookup_by_name(view_name);
15483 if (bgp == NULL) {
15484 vty_out(vty, "%% Can't find BGP instance %s\n",
15485 view_name);
15486 return CMD_WARNING;
15487 }
15488 } else {
15489 bgp = bgp_get_default();
15490 if (bgp == NULL) {
15491 vty_out(vty, "%% No BGP process is configured\n");
15492 return CMD_WARNING;
15493 }
15494 }
15495
15496 /* Check IP address argument. */
15497 ret = str2prefix(ip_str, &match);
15498 if (!ret) {
15499 vty_out(vty, "%% address is malformed\n");
15500 return CMD_WARNING;
15501 }
15502
15503 match.family = afi2family(afi);
15504
15505 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15506 || (safi == SAFI_EVPN)) {
15507 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15508 dest = bgp_route_next(dest)) {
15509 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15510
15511 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15512 continue;
15513 table = bgp_dest_get_bgp_table_info(dest);
15514 if (!table)
15515 continue;
15516 rm = bgp_node_match(table, &match);
15517 if (rm == NULL)
15518 continue;
15519
15520 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15521
15522 if (!prefix_check
15523 || rm_p->prefixlen == match.prefixlen) {
15524 pi = bgp_dest_get_bgp_path_info(rm);
15525 while (pi) {
15526 if (pi->extra && pi->extra->damp_info) {
15527 pi_temp = pi->next;
15528 bgp_damp_info_free(
15529 pi->extra->damp_info,
15530 1, afi, safi);
15531 pi = pi_temp;
15532 } else
15533 pi = pi->next;
15534 }
15535 }
15536
15537 bgp_dest_unlock_node(rm);
15538 }
15539 } else {
15540 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15541 if (dest != NULL) {
15542 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15543
15544 if (!prefix_check
15545 || dest_p->prefixlen == match.prefixlen) {
15546 pi = bgp_dest_get_bgp_path_info(dest);
15547 while (pi) {
15548 if (pi->extra && pi->extra->damp_info) {
15549 pi_temp = pi->next;
15550 bgp_damp_info_free(
15551 pi->extra->damp_info,
15552 1, afi, safi);
15553 pi = pi_temp;
15554 } else
15555 pi = pi->next;
15556 }
15557 }
15558
15559 bgp_dest_unlock_node(dest);
15560 }
15561 }
15562
15563 return CMD_SUCCESS;
15564 }
15565
15566 DEFUN (clear_ip_bgp_dampening,
15567 clear_ip_bgp_dampening_cmd,
15568 "clear ip bgp dampening",
15569 CLEAR_STR
15570 IP_STR
15571 BGP_STR
15572 "Clear route flap dampening information\n")
15573 {
15574 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15575 return CMD_SUCCESS;
15576 }
15577
15578 DEFUN (clear_ip_bgp_dampening_prefix,
15579 clear_ip_bgp_dampening_prefix_cmd,
15580 "clear ip bgp dampening A.B.C.D/M",
15581 CLEAR_STR
15582 IP_STR
15583 BGP_STR
15584 "Clear route flap dampening information\n"
15585 "IPv4 prefix\n")
15586 {
15587 int idx_ipv4_prefixlen = 4;
15588 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15589 AFI_IP, SAFI_UNICAST, NULL, 1);
15590 }
15591
15592 DEFUN (clear_ip_bgp_dampening_address,
15593 clear_ip_bgp_dampening_address_cmd,
15594 "clear ip bgp dampening A.B.C.D",
15595 CLEAR_STR
15596 IP_STR
15597 BGP_STR
15598 "Clear route flap dampening information\n"
15599 "Network to clear damping information\n")
15600 {
15601 int idx_ipv4 = 4;
15602 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15603 SAFI_UNICAST, NULL, 0);
15604 }
15605
15606 DEFUN (clear_ip_bgp_dampening_address_mask,
15607 clear_ip_bgp_dampening_address_mask_cmd,
15608 "clear ip bgp dampening A.B.C.D A.B.C.D",
15609 CLEAR_STR
15610 IP_STR
15611 BGP_STR
15612 "Clear route flap dampening information\n"
15613 "Network to clear damping information\n"
15614 "Network mask\n")
15615 {
15616 int idx_ipv4 = 4;
15617 int idx_ipv4_2 = 5;
15618 int ret;
15619 char prefix_str[BUFSIZ];
15620
15621 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15622 prefix_str, sizeof(prefix_str));
15623 if (!ret) {
15624 vty_out(vty, "%% Inconsistent address and mask\n");
15625 return CMD_WARNING;
15626 }
15627
15628 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15629 NULL, 0);
15630 }
15631
15632 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15633 {
15634 struct vty *vty = arg;
15635 struct peer *peer = bucket->data;
15636
15637 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15638 }
15639
15640 DEFUN (show_bgp_listeners,
15641 show_bgp_listeners_cmd,
15642 "show bgp listeners",
15643 SHOW_STR
15644 BGP_STR
15645 "Display Listen Sockets and who created them\n")
15646 {
15647 bgp_dump_listener_info(vty);
15648
15649 return CMD_SUCCESS;
15650 }
15651
15652 DEFUN (show_bgp_peerhash,
15653 show_bgp_peerhash_cmd,
15654 "show bgp peerhash",
15655 SHOW_STR
15656 BGP_STR
15657 "Display information about the BGP peerhash\n")
15658 {
15659 struct list *instances = bm->bgp;
15660 struct listnode *node;
15661 struct bgp *bgp;
15662
15663 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15664 vty_out(vty, "BGP: %s\n", bgp->name);
15665 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15666 vty);
15667 }
15668
15669 return CMD_SUCCESS;
15670 }
15671
15672 /* also used for encap safi */
15673 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15674 afi_t afi, safi_t safi)
15675 {
15676 struct bgp_dest *pdest;
15677 struct bgp_dest *dest;
15678 struct bgp_table *table;
15679 const struct prefix *p;
15680 struct bgp_static *bgp_static;
15681 mpls_label_t label;
15682
15683 /* Network configuration. */
15684 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15685 pdest = bgp_route_next(pdest)) {
15686 table = bgp_dest_get_bgp_table_info(pdest);
15687 if (!table)
15688 continue;
15689
15690 for (dest = bgp_table_top(table); dest;
15691 dest = bgp_route_next(dest)) {
15692 bgp_static = bgp_dest_get_bgp_static_info(dest);
15693 if (bgp_static == NULL)
15694 continue;
15695
15696 p = bgp_dest_get_prefix(dest);
15697
15698 /* "network" configuration display. */
15699 label = decode_label(&bgp_static->label);
15700
15701 vty_out(vty, " network %pFX rd %s", p,
15702 bgp_static->prd_pretty);
15703 if (safi == SAFI_MPLS_VPN)
15704 vty_out(vty, " label %u", label);
15705
15706 if (bgp_static->rmap.name)
15707 vty_out(vty, " route-map %s",
15708 bgp_static->rmap.name);
15709
15710 if (bgp_static->backdoor)
15711 vty_out(vty, " backdoor");
15712
15713 vty_out(vty, "\n");
15714 }
15715 }
15716 }
15717
15718 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15719 afi_t afi, safi_t safi)
15720 {
15721 struct bgp_dest *pdest;
15722 struct bgp_dest *dest;
15723 struct bgp_table *table;
15724 const struct prefix *p;
15725 struct bgp_static *bgp_static;
15726 char buf[PREFIX_STRLEN * 2];
15727 char buf2[SU_ADDRSTRLEN];
15728 char esi_buf[ESI_STR_LEN];
15729
15730 /* Network configuration. */
15731 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15732 pdest = bgp_route_next(pdest)) {
15733 table = bgp_dest_get_bgp_table_info(pdest);
15734 if (!table)
15735 continue;
15736
15737 for (dest = bgp_table_top(table); dest;
15738 dest = bgp_route_next(dest)) {
15739 bgp_static = bgp_dest_get_bgp_static_info(dest);
15740 if (bgp_static == NULL)
15741 continue;
15742
15743 char *macrouter = NULL;
15744
15745 if (bgp_static->router_mac)
15746 macrouter = prefix_mac2str(
15747 bgp_static->router_mac, NULL, 0);
15748 if (bgp_static->eth_s_id)
15749 esi_to_str(bgp_static->eth_s_id,
15750 esi_buf, sizeof(esi_buf));
15751 p = bgp_dest_get_prefix(dest);
15752
15753 /* "network" configuration display. */
15754 if (p->u.prefix_evpn.route_type == 5) {
15755 char local_buf[PREFIX_STRLEN];
15756
15757 uint8_t family = is_evpn_prefix_ipaddr_v4((
15758 struct prefix_evpn *)p)
15759 ? AF_INET
15760 : AF_INET6;
15761 inet_ntop(family,
15762 &p->u.prefix_evpn.prefix_addr.ip.ip
15763 .addr,
15764 local_buf, sizeof(local_buf));
15765 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15766 p->u.prefix_evpn.prefix_addr
15767 .ip_prefix_length);
15768 } else {
15769 prefix2str(p, buf, sizeof(buf));
15770 }
15771
15772 if (bgp_static->gatewayIp.family == AF_INET
15773 || bgp_static->gatewayIp.family == AF_INET6)
15774 inet_ntop(bgp_static->gatewayIp.family,
15775 &bgp_static->gatewayIp.u.prefix, buf2,
15776 sizeof(buf2));
15777 vty_out(vty,
15778 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15779 buf, bgp_static->prd_pretty,
15780 p->u.prefix_evpn.prefix_addr.eth_tag,
15781 decode_label(&bgp_static->label), esi_buf, buf2,
15782 macrouter);
15783
15784 XFREE(MTYPE_TMP, macrouter);
15785 }
15786 }
15787 }
15788
15789 /* Configuration of static route announcement and aggregate
15790 information. */
15791 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15792 safi_t safi)
15793 {
15794 struct bgp_dest *dest;
15795 const struct prefix *p;
15796 struct bgp_static *bgp_static;
15797 struct bgp_aggregate *bgp_aggregate;
15798
15799 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15800 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15801 return;
15802 }
15803
15804 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15805 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15806 return;
15807 }
15808
15809 /* Network configuration. */
15810 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15811 dest = bgp_route_next(dest)) {
15812 bgp_static = bgp_dest_get_bgp_static_info(dest);
15813 if (bgp_static == NULL)
15814 continue;
15815
15816 p = bgp_dest_get_prefix(dest);
15817
15818 vty_out(vty, " network %pFX", p);
15819
15820 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15821 vty_out(vty, " label-index %u",
15822 bgp_static->label_index);
15823
15824 if (bgp_static->rmap.name)
15825 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15826
15827 if (bgp_static->backdoor)
15828 vty_out(vty, " backdoor");
15829
15830 vty_out(vty, "\n");
15831 }
15832
15833 /* Aggregate-address configuration. */
15834 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15835 dest = bgp_route_next(dest)) {
15836 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15837 if (bgp_aggregate == NULL)
15838 continue;
15839
15840 p = bgp_dest_get_prefix(dest);
15841
15842 vty_out(vty, " aggregate-address %pFX", p);
15843
15844 if (bgp_aggregate->as_set)
15845 vty_out(vty, " as-set");
15846
15847 if (bgp_aggregate->summary_only)
15848 vty_out(vty, " summary-only");
15849
15850 if (bgp_aggregate->rmap.name)
15851 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15852
15853 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15854 vty_out(vty, " origin %s",
15855 bgp_origin2str(bgp_aggregate->origin));
15856
15857 if (bgp_aggregate->match_med)
15858 vty_out(vty, " matching-MED-only");
15859
15860 if (bgp_aggregate->suppress_map_name)
15861 vty_out(vty, " suppress-map %s",
15862 bgp_aggregate->suppress_map_name);
15863
15864 vty_out(vty, "\n");
15865 }
15866 }
15867
15868 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15869 safi_t safi)
15870 {
15871 struct bgp_dest *dest;
15872 struct bgp_distance *bdistance;
15873
15874 /* Distance configuration. */
15875 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15876 && bgp->distance_local[afi][safi]
15877 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15878 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15879 || bgp->distance_local[afi][safi]
15880 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15881 vty_out(vty, " distance bgp %d %d %d\n",
15882 bgp->distance_ebgp[afi][safi],
15883 bgp->distance_ibgp[afi][safi],
15884 bgp->distance_local[afi][safi]);
15885 }
15886
15887 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15888 dest = bgp_route_next(dest)) {
15889 bdistance = bgp_dest_get_bgp_distance_info(dest);
15890 if (bdistance != NULL)
15891 vty_out(vty, " distance %d %pBD %s\n",
15892 bdistance->distance, dest,
15893 bdistance->access_list ? bdistance->access_list
15894 : "");
15895 }
15896 }
15897
15898 /* Allocate routing table structure and install commands. */
15899 void bgp_route_init(void)
15900 {
15901 afi_t afi;
15902 safi_t safi;
15903
15904 /* Init BGP distance table. */
15905 FOREACH_AFI_SAFI (afi, safi)
15906 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15907
15908 /* IPv4 BGP commands. */
15909 install_element(BGP_NODE, &bgp_table_map_cmd);
15910 install_element(BGP_NODE, &bgp_network_cmd);
15911 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15912
15913 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15914
15915 /* IPv4 unicast configuration. */
15916 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15917 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15918 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15919
15920 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15921
15922 /* IPv4 multicast configuration. */
15923 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15924 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15925 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15926 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15927
15928 /* IPv4 labeled-unicast configuration. */
15929 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15930 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15931
15932 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15933 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15934 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15935 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15936 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15937 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15938 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15939 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15940
15941 install_element(VIEW_NODE,
15942 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15943 install_element(VIEW_NODE,
15944 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15945 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15946 install_element(VIEW_NODE,
15947 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15948 #ifdef KEEP_OLD_VPN_COMMANDS
15949 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15950 #endif /* KEEP_OLD_VPN_COMMANDS */
15951 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15952 install_element(VIEW_NODE,
15953 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15954
15955 /* BGP dampening clear commands */
15956 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15957 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15958
15959 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15960 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15961
15962 /* prefix count */
15963 install_element(ENABLE_NODE,
15964 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15965 #ifdef KEEP_OLD_VPN_COMMANDS
15966 install_element(ENABLE_NODE,
15967 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15968 #endif /* KEEP_OLD_VPN_COMMANDS */
15969
15970 /* New config IPv6 BGP commands. */
15971 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15972 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15973 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15974
15975 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15976
15977 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15978
15979 /* IPv6 labeled unicast address family. */
15980 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15981 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15982
15983 install_element(BGP_NODE, &bgp_distance_cmd);
15984 install_element(BGP_NODE, &no_bgp_distance_cmd);
15985 install_element(BGP_NODE, &bgp_distance_source_cmd);
15986 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15987 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15988 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15989 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15990 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15991 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15992 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15993 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15994 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15995 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15996 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15997 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15998 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15999 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
16000 install_element(BGP_IPV4M_NODE,
16001 &no_bgp_distance_source_access_list_cmd);
16002 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
16003 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
16004 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
16005 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
16006 install_element(BGP_IPV6_NODE,
16007 &ipv6_bgp_distance_source_access_list_cmd);
16008 install_element(BGP_IPV6_NODE,
16009 &no_ipv6_bgp_distance_source_access_list_cmd);
16010 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
16011 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
16012 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
16013 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
16014 install_element(BGP_IPV6M_NODE,
16015 &ipv6_bgp_distance_source_access_list_cmd);
16016 install_element(BGP_IPV6M_NODE,
16017 &no_ipv6_bgp_distance_source_access_list_cmd);
16018
16019 /* BGP dampening */
16020 install_element(BGP_NODE, &bgp_damp_set_cmd);
16021 install_element(BGP_NODE, &bgp_damp_unset_cmd);
16022 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
16023 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
16024 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
16025 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
16026 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
16027 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
16028 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
16029 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
16030 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
16031 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
16032 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
16033 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
16034
16035 /* Large Communities */
16036 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
16037 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
16038
16039 /* show bgp ipv4 flowspec detailed */
16040 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
16041
16042 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16043 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16044 }
16045
16046 void bgp_route_finish(void)
16047 {
16048 afi_t afi;
16049 safi_t safi;
16050
16051 FOREACH_AFI_SAFI (afi, safi) {
16052 bgp_table_unlock(bgp_distance_table[afi][safi]);
16053 bgp_distance_table[afi][safi] = NULL;
16054 }
16055 }