]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / bgpd / bgp_route.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP routing information
3 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
4 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 */
6
7 #include <zebra.h>
8 #include <math.h>
9
10 #include "printfrr.h"
11 #include "frrstr.h"
12 #include "prefix.h"
13 #include "linklist.h"
14 #include "memory.h"
15 #include "command.h"
16 #include "stream.h"
17 #include "filter.h"
18 #include "log.h"
19 #include "routemap.h"
20 #include "buffer.h"
21 #include "sockunion.h"
22 #include "plist.h"
23 #include "thread.h"
24 #include "workqueue.h"
25 #include "queue.h"
26 #include "memory.h"
27 #include "srv6.h"
28 #include "lib/json.h"
29 #include "lib_errors.h"
30 #include "zclient.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_regex.h"
39 #include "bgpd/bgp_community.h"
40 #include "bgpd/bgp_community_alias.h"
41 #include "bgpd/bgp_ecommunity.h"
42 #include "bgpd/bgp_lcommunity.h"
43 #include "bgpd/bgp_clist.h"
44 #include "bgpd/bgp_packet.h"
45 #include "bgpd/bgp_filter.h"
46 #include "bgpd/bgp_fsm.h"
47 #include "bgpd/bgp_mplsvpn.h"
48 #include "bgpd/bgp_nexthop.h"
49 #include "bgpd/bgp_damp.h"
50 #include "bgpd/bgp_advertise.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_vty.h"
53 #include "bgpd/bgp_mpath.h"
54 #include "bgpd/bgp_nht.h"
55 #include "bgpd/bgp_updgrp.h"
56 #include "bgpd/bgp_label.h"
57 #include "bgpd/bgp_addpath.h"
58 #include "bgpd/bgp_mac.h"
59 #include "bgpd/bgp_network.h"
60 #include "bgpd/bgp_trace.h"
61 #include "bgpd/bgp_rpki.h"
62
63 #ifdef ENABLE_BGP_VNC
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #include "bgpd/rfapi/vnc_import_bgp.h"
66 #include "bgpd/rfapi/vnc_export_bgp.h"
67 #endif
68 #include "bgpd/bgp_encap_types.h"
69 #include "bgpd/bgp_encap_tlv.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_evpn_mh.h"
72 #include "bgpd/bgp_evpn_vty.h"
73 #include "bgpd/bgp_flowspec.h"
74 #include "bgpd/bgp_flowspec_util.h"
75 #include "bgpd/bgp_pbr.h"
76
77 #include "bgpd/bgp_route_clippy.c"
78
79 DEFINE_HOOK(bgp_snmp_update_stats,
80 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
81 (rn, pi, added));
82
83 DEFINE_HOOK(bgp_rpki_prefix_status,
84 (struct peer *peer, struct attr *attr,
85 const struct prefix *prefix),
86 (peer, attr, prefix));
87
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str[];
90 extern const char *bgp_origin_long_str[];
91
92 /* PMSI strings. */
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str[] = {
96 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
104 {0}
105 };
106
107 #define VRFID_NONE_STR "-"
108 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
109
110 DEFINE_HOOK(bgp_process,
111 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
112 struct peer *peer, bool withdraw),
113 (bgp, afi, safi, bn, peer, withdraw));
114
115 /** Test if path is suppressed. */
116 static bool bgp_path_suppressed(struct bgp_path_info *pi)
117 {
118 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
119 return false;
120
121 return listcount(pi->extra->aggr_suppressors) > 0;
122 }
123
124 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
125 safi_t safi, const struct prefix *p,
126 struct prefix_rd *prd)
127 {
128 struct bgp_dest *dest;
129 struct bgp_dest *pdest = NULL;
130
131 assert(table);
132
133 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
134 || (safi == SAFI_EVPN)) {
135 pdest = bgp_node_get(table, (struct prefix *)prd);
136
137 if (!bgp_dest_has_bgp_path_info_data(pdest))
138 bgp_dest_set_bgp_table_info(
139 pdest, bgp_table_init(table->bgp, afi, safi));
140 else
141 bgp_dest_unlock_node(pdest);
142 table = bgp_dest_get_bgp_table_info(pdest);
143 }
144
145 dest = bgp_node_get(table, p);
146
147 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
148 || (safi == SAFI_EVPN))
149 dest->pdest = pdest;
150
151 return dest;
152 }
153
154 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
155 safi_t safi, 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 zlog_debug(
321 "Route %pBD is in workqueue and being processed, not deferred.",
322 dest);
323
324 return 0;
325 }
326
327 table = bgp_dest_table(dest);
328 if (table) {
329 bgp = table->bgp;
330 afi = table->afi;
331 safi = table->safi;
332 }
333
334 for (old_pi = bgp_dest_get_bgp_path_info(dest);
335 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
336 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
337 continue;
338
339 /* Route selection is deferred if there is a stale path which
340 * which indicates peer is in restart mode
341 */
342 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
343 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
344 set_flag = true;
345 } else {
346 /* If the peer is graceful restart capable and peer is
347 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
348 */
349 peer = old_pi->peer;
350 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
351 && BGP_PEER_RESTARTING_MODE(peer)
352 && (old_pi
353 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
354 set_flag = true;
355 }
356 }
357 if (set_flag)
358 break;
359 }
360
361 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
362 * is active
363 */
364 if (set_flag && table) {
365 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
366 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
367 bgp->gr_info[afi][safi].gr_deferred++;
368 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
369 if (BGP_DEBUG(update, UPDATE_OUT))
370 zlog_debug("DEFER route %pBD, dest %p", dest,
371 dest);
372 return 0;
373 }
374 }
375 return -1;
376 }
377
378 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
379 struct bgp_path_info *pi)
380 {
381 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
382 struct bgp_path_info *top;
383
384 top = bgp_dest_get_bgp_path_info(dest);
385
386 pi->next = top;
387 pi->prev = NULL;
388 if (top)
389 top->prev = pi;
390 bgp_dest_set_bgp_path_info(dest, pi);
391
392 bgp_path_info_lock(pi);
393 bgp_dest_lock_node(dest);
394 peer_lock(pi->peer); /* bgp_path_info peer reference */
395 bgp_dest_set_defer_flag(dest, false);
396 hook_call(bgp_snmp_update_stats, dest, pi, true);
397 }
398
399 /* Do the actual removal of info from RIB, for use by bgp_process
400 completion callback *only* */
401 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
402 {
403 if (pi->next)
404 pi->next->prev = pi->prev;
405 if (pi->prev)
406 pi->prev->next = pi->next;
407 else
408 bgp_dest_set_bgp_path_info(dest, pi->next);
409
410 bgp_path_info_mpath_dequeue(pi);
411 bgp_path_info_unlock(pi);
412 hook_call(bgp_snmp_update_stats, dest, pi, false);
413 bgp_dest_unlock_node(dest);
414 }
415
416 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
417 {
418 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
419 /* set of previous already took care of pcount */
420 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
421 }
422
423 /* undo the effects of a previous call to bgp_path_info_delete; typically
424 called when a route is deleted and then quickly re-added before the
425 deletion has been processed */
426 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
427 {
428 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
429 /* unset of previous already took care of pcount */
430 SET_FLAG(pi->flags, BGP_PATH_VALID);
431 }
432
433 /* Adjust pcount as required */
434 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
435 {
436 struct bgp_table *table;
437
438 assert(dest && bgp_dest_table(dest));
439 assert(pi && pi->peer && pi->peer->bgp);
440
441 table = bgp_dest_table(dest);
442
443 if (pi->peer == pi->peer->bgp->peer_self)
444 return;
445
446 if (!BGP_PATH_COUNTABLE(pi)
447 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
448
449 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
450
451 /* slight hack, but more robust against errors. */
452 if (pi->peer->pcount[table->afi][table->safi])
453 pi->peer->pcount[table->afi][table->safi]--;
454 else
455 flog_err(EC_LIB_DEVELOPMENT,
456 "Asked to decrement 0 prefix count for peer");
457 } else if (BGP_PATH_COUNTABLE(pi)
458 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
459 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
460 pi->peer->pcount[table->afi][table->safi]++;
461 }
462 }
463
464 static int bgp_label_index_differs(struct bgp_path_info *pi1,
465 struct bgp_path_info *pi2)
466 {
467 return (!(pi1->attr->label_index == pi2->attr->label_index));
468 }
469
470 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
471 * This is here primarily to keep prefix-count in check.
472 */
473 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
474 uint32_t flag)
475 {
476 SET_FLAG(pi->flags, flag);
477
478 /* early bath if we know it's not a flag that changes countability state
479 */
480 if (!CHECK_FLAG(flag,
481 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
482 return;
483
484 bgp_pcount_adjust(dest, pi);
485 }
486
487 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
488 uint32_t flag)
489 {
490 UNSET_FLAG(pi->flags, flag);
491
492 /* early bath if we know it's not a flag that changes countability state
493 */
494 if (!CHECK_FLAG(flag,
495 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
496 return;
497
498 bgp_pcount_adjust(dest, pi);
499 }
500
501 /* Get MED value. If MED value is missing and "bgp bestpath
502 missing-as-worst" is specified, treat it as the worst value. */
503 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
504 {
505 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
506 return attr->med;
507 else {
508 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
509 return BGP_MED_MAX;
510 else
511 return 0;
512 }
513 }
514
515 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
516 size_t buf_len)
517 {
518 if (pi->addpath_rx_id)
519 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
520 pi->peer->host, pi->addpath_rx_id);
521 else
522 snprintf(buf, buf_len, "path %s", pi->peer->host);
523 }
524
525
526 /*
527 * Get the ultimate path info.
528 */
529 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
530 {
531 struct bgp_path_info *bpi_ultimate;
532
533 if (info->sub_type != BGP_ROUTE_IMPORTED)
534 return info;
535
536 for (bpi_ultimate = info;
537 bpi_ultimate->extra && bpi_ultimate->extra->parent;
538 bpi_ultimate = bpi_ultimate->extra->parent)
539 ;
540
541 return bpi_ultimate;
542 }
543
544 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
545 */
546 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
547 struct bgp_path_info *exist, int *paths_eq,
548 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
549 char *pfx_buf, afi_t afi, safi_t safi,
550 enum bgp_path_selection_reason *reason)
551 {
552 const struct prefix *new_p;
553 struct attr *newattr, *existattr;
554 enum bgp_peer_sort new_sort;
555 enum bgp_peer_sort exist_sort;
556 uint32_t new_pref;
557 uint32_t exist_pref;
558 uint32_t new_med;
559 uint32_t exist_med;
560 uint32_t new_weight;
561 uint32_t exist_weight;
562 uint32_t newm, existm;
563 struct in_addr new_id;
564 struct in_addr exist_id;
565 int new_cluster;
566 int exist_cluster;
567 int internal_as_route;
568 int confed_as_route;
569 int ret = 0;
570 int igp_metric_ret = 0;
571 int peer_sort_ret = -1;
572 char new_buf[PATH_ADDPATH_STR_BUFFER];
573 char exist_buf[PATH_ADDPATH_STR_BUFFER];
574 uint32_t new_mm_seq;
575 uint32_t exist_mm_seq;
576 int nh_cmp;
577 esi_t *exist_esi;
578 esi_t *new_esi;
579 bool same_esi;
580 bool old_proxy;
581 bool new_proxy;
582 bool new_origin, exist_origin;
583 struct bgp_path_info *bpi_ultimate;
584
585 *paths_eq = 0;
586
587 /* 0. Null check. */
588 if (new == NULL) {
589 *reason = bgp_path_selection_none;
590 if (debug)
591 zlog_debug("%s: new is NULL", pfx_buf);
592 return 0;
593 }
594
595 if (debug) {
596 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
597 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
598 sizeof(new_buf));
599 }
600
601 if (exist == NULL) {
602 *reason = bgp_path_selection_first;
603 if (debug)
604 zlog_debug("%s(%s): %s is the initial bestpath",
605 pfx_buf, bgp->name_pretty, new_buf);
606 return 1;
607 }
608
609 if (debug) {
610 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
611 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
612 sizeof(exist_buf));
613 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
614 pfx_buf, bgp->name_pretty, new_buf, new->flags,
615 exist_buf, exist->flags);
616 }
617
618 newattr = new->attr;
619 existattr = exist->attr;
620
621 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
622 * Capability" to a neighbor MUST perform the following upon receiving
623 * a route from that neighbor with the "LLGR_STALE" community, or upon
624 * attaching the "LLGR_STALE" community itself per Section 4.2:
625 *
626 * Treat the route as the least-preferred in route selection (see
627 * below). See the Risks of Depreferencing Routes section (Section 5.2)
628 * for a discussion of potential risks inherent in doing this.
629 */
630 if (bgp_attr_get_community(newattr) &&
631 community_include(bgp_attr_get_community(newattr),
632 COMMUNITY_LLGR_STALE)) {
633 if (debug)
634 zlog_debug(
635 "%s: %s wins over %s due to LLGR_STALE community",
636 pfx_buf, new_buf, exist_buf);
637 return 0;
638 }
639
640 if (bgp_attr_get_community(existattr) &&
641 community_include(bgp_attr_get_community(existattr),
642 COMMUNITY_LLGR_STALE)) {
643 if (debug)
644 zlog_debug(
645 "%s: %s loses to %s due to LLGR_STALE community",
646 pfx_buf, new_buf, exist_buf);
647 return 1;
648 }
649
650 new_p = bgp_dest_get_prefix(new->net);
651
652 /* For EVPN routes, we cannot just go by local vs remote, we have to
653 * look at the MAC mobility sequence number, if present.
654 */
655 if ((safi == SAFI_EVPN)
656 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
657 /* This is an error condition described in RFC 7432 Section
658 * 15.2. The RFC
659 * states that in this scenario "the PE MUST alert the operator"
660 * but it
661 * does not state what other action to take. In order to provide
662 * some
663 * consistency in this scenario we are going to prefer the path
664 * with the
665 * sticky flag.
666 */
667 if (newattr->sticky != existattr->sticky) {
668 if (!debug) {
669 prefix2str(new_p, pfx_buf,
670 sizeof(*pfx_buf)
671 * PREFIX2STR_BUFFER);
672 bgp_path_info_path_with_addpath_rx_str(
673 new, new_buf, sizeof(new_buf));
674 bgp_path_info_path_with_addpath_rx_str(
675 exist, exist_buf, sizeof(exist_buf));
676 }
677
678 if (newattr->sticky && !existattr->sticky) {
679 *reason = bgp_path_selection_evpn_sticky_mac;
680 if (debug)
681 zlog_debug(
682 "%s: %s wins over %s due to sticky MAC flag",
683 pfx_buf, new_buf, exist_buf);
684 return 1;
685 }
686
687 if (!newattr->sticky && existattr->sticky) {
688 *reason = bgp_path_selection_evpn_sticky_mac;
689 if (debug)
690 zlog_debug(
691 "%s: %s loses to %s due to sticky MAC flag",
692 pfx_buf, new_buf, exist_buf);
693 return 0;
694 }
695 }
696
697 new_esi = bgp_evpn_attr_get_esi(newattr);
698 exist_esi = bgp_evpn_attr_get_esi(existattr);
699 if (bgp_evpn_is_esi_valid(new_esi) &&
700 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
701 same_esi = true;
702 } else {
703 same_esi = false;
704 }
705
706 /* If both paths have the same non-zero ES and
707 * one path is local it wins.
708 * PS: Note the local path wins even if the remote
709 * has the higher MM seq. The local path's
710 * MM seq will be fixed up to match the highest
711 * rem seq, subsequently.
712 */
713 if (same_esi) {
714 char esi_buf[ESI_STR_LEN];
715
716 if (bgp_evpn_is_path_local(bgp, new)) {
717 *reason = bgp_path_selection_evpn_local_path;
718 if (debug)
719 zlog_debug(
720 "%s: %s wins over %s as ES %s is same and local",
721 pfx_buf, new_buf, exist_buf,
722 esi_to_str(new_esi, esi_buf,
723 sizeof(esi_buf)));
724 return 1;
725 }
726 if (bgp_evpn_is_path_local(bgp, exist)) {
727 *reason = bgp_path_selection_evpn_local_path;
728 if (debug)
729 zlog_debug(
730 "%s: %s loses to %s as ES %s is same and local",
731 pfx_buf, new_buf, exist_buf,
732 esi_to_str(new_esi, esi_buf,
733 sizeof(esi_buf)));
734 return 0;
735 }
736 }
737
738 new_mm_seq = mac_mobility_seqnum(newattr);
739 exist_mm_seq = mac_mobility_seqnum(existattr);
740
741 if (new_mm_seq > exist_mm_seq) {
742 *reason = bgp_path_selection_evpn_seq;
743 if (debug)
744 zlog_debug(
745 "%s: %s wins over %s due to MM seq %u > %u",
746 pfx_buf, new_buf, exist_buf, new_mm_seq,
747 exist_mm_seq);
748 return 1;
749 }
750
751 if (new_mm_seq < exist_mm_seq) {
752 *reason = bgp_path_selection_evpn_seq;
753 if (debug)
754 zlog_debug(
755 "%s: %s loses to %s due to MM seq %u < %u",
756 pfx_buf, new_buf, exist_buf, new_mm_seq,
757 exist_mm_seq);
758 return 0;
759 }
760
761 /* if the sequence numbers and ESI are the same and one path
762 * is non-proxy it wins (over proxy)
763 */
764 new_proxy = bgp_evpn_attr_is_proxy(newattr);
765 old_proxy = bgp_evpn_attr_is_proxy(existattr);
766 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
767 old_proxy != new_proxy) {
768 if (!new_proxy) {
769 *reason = bgp_path_selection_evpn_non_proxy;
770 if (debug)
771 zlog_debug(
772 "%s: %s wins over %s, same seq/es and non-proxy",
773 pfx_buf, new_buf, exist_buf);
774 return 1;
775 }
776
777 *reason = bgp_path_selection_evpn_non_proxy;
778 if (debug)
779 zlog_debug(
780 "%s: %s loses to %s, same seq/es and non-proxy",
781 pfx_buf, new_buf, exist_buf);
782 return 0;
783 }
784
785 /*
786 * if sequence numbers are the same path with the lowest IP
787 * wins
788 */
789 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
790 if (nh_cmp < 0) {
791 *reason = bgp_path_selection_evpn_lower_ip;
792 if (debug)
793 zlog_debug(
794 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
795 pfx_buf, new_buf, exist_buf, new_mm_seq,
796 &new->attr->nexthop);
797 return 1;
798 }
799 if (nh_cmp > 0) {
800 *reason = bgp_path_selection_evpn_lower_ip;
801 if (debug)
802 zlog_debug(
803 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
804 pfx_buf, new_buf, exist_buf, new_mm_seq,
805 &new->attr->nexthop);
806 return 0;
807 }
808 }
809
810 /* 1. Weight check. */
811 new_weight = newattr->weight;
812 exist_weight = existattr->weight;
813
814 if (new_weight > exist_weight) {
815 *reason = bgp_path_selection_weight;
816 if (debug)
817 zlog_debug("%s: %s wins over %s due to weight %d > %d",
818 pfx_buf, new_buf, exist_buf, new_weight,
819 exist_weight);
820 return 1;
821 }
822
823 if (new_weight < exist_weight) {
824 *reason = bgp_path_selection_weight;
825 if (debug)
826 zlog_debug("%s: %s loses to %s due to weight %d < %d",
827 pfx_buf, new_buf, exist_buf, new_weight,
828 exist_weight);
829 return 0;
830 }
831
832 /* 2. Local preference check. */
833 new_pref = exist_pref = bgp->default_local_pref;
834
835 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
836 new_pref = newattr->local_pref;
837 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
838 exist_pref = existattr->local_pref;
839
840 if (new_pref > exist_pref) {
841 *reason = bgp_path_selection_local_pref;
842 if (debug)
843 zlog_debug(
844 "%s: %s wins over %s due to localpref %d > %d",
845 pfx_buf, new_buf, exist_buf, new_pref,
846 exist_pref);
847 return 1;
848 }
849
850 if (new_pref < exist_pref) {
851 *reason = bgp_path_selection_local_pref;
852 if (debug)
853 zlog_debug(
854 "%s: %s loses to %s due to localpref %d < %d",
855 pfx_buf, new_buf, exist_buf, new_pref,
856 exist_pref);
857 return 0;
858 }
859
860 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
861 * extensions defined in this document, the following step is inserted
862 * after the LOCAL_PREF comparison step in the BGP decision process:
863 * When comparing a pair of routes for a BGP destination, the
864 * route with the ACCEPT_OWN community attached is preferred over
865 * the route that does not have the community.
866 * This extra step MUST only be invoked during the best path selection
867 * process of VPN-IP routes.
868 */
869 if (safi == SAFI_MPLS_VPN &&
870 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
871 CHECK_FLAG(exist->peer->af_flags[afi][safi],
872 PEER_FLAG_ACCEPT_OWN))) {
873 bool new_accept_own = false;
874 bool exist_accept_own = false;
875 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
876
877 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
878 new_accept_own = community_include(
879 bgp_attr_get_community(newattr), accept_own);
880 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
881 exist_accept_own = community_include(
882 bgp_attr_get_community(existattr), accept_own);
883
884 if (new_accept_own && !exist_accept_own) {
885 *reason = bgp_path_selection_accept_own;
886 if (debug)
887 zlog_debug(
888 "%s: %s wins over %s due to accept-own",
889 pfx_buf, new_buf, exist_buf);
890 return 1;
891 }
892
893 if (!new_accept_own && exist_accept_own) {
894 *reason = bgp_path_selection_accept_own;
895 if (debug)
896 zlog_debug(
897 "%s: %s loses to %s due to accept-own",
898 pfx_buf, new_buf, exist_buf);
899 return 0;
900 }
901 }
902
903 /* Tie-breaker - AIGP (Metric TLV) attribute */
904 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
905 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
906 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
907 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
908 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
909
910 if (new_aigp < exist_aigp) {
911 *reason = bgp_path_selection_aigp;
912 if (debug)
913 zlog_debug(
914 "%s: %s wins over %s due to AIGP %" PRIu64
915 " < %" PRIu64,
916 pfx_buf, new_buf, exist_buf, new_aigp,
917 exist_aigp);
918 return 1;
919 }
920
921 if (new_aigp > exist_aigp) {
922 *reason = bgp_path_selection_aigp;
923 if (debug)
924 zlog_debug(
925 "%s: %s loses to %s due to AIGP %" PRIu64
926 " > %" PRIu64,
927 pfx_buf, new_buf, exist_buf, new_aigp,
928 exist_aigp);
929 return 0;
930 }
931 }
932
933 /* 3. Local route check. We prefer:
934 * - BGP_ROUTE_STATIC
935 * - BGP_ROUTE_AGGREGATE
936 * - BGP_ROUTE_REDISTRIBUTE
937 */
938 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
939 new->sub_type == BGP_ROUTE_IMPORTED);
940 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
941 exist->sub_type == BGP_ROUTE_IMPORTED);
942
943 if (new_origin && !exist_origin) {
944 *reason = bgp_path_selection_local_route;
945 if (debug)
946 zlog_debug(
947 "%s: %s wins over %s due to preferred BGP_ROUTE type",
948 pfx_buf, new_buf, exist_buf);
949 return 1;
950 }
951
952 if (!new_origin && exist_origin) {
953 *reason = bgp_path_selection_local_route;
954 if (debug)
955 zlog_debug(
956 "%s: %s loses to %s due to preferred BGP_ROUTE type",
957 pfx_buf, new_buf, exist_buf);
958 return 0;
959 }
960
961 /* Here if these are imported routes then get ultimate pi for
962 * path compare.
963 */
964 new = bgp_get_imported_bpi_ultimate(new);
965 exist = bgp_get_imported_bpi_ultimate(exist);
966 newattr = new->attr;
967 existattr = exist->attr;
968
969 /* 4. AS path length check. */
970 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
971 int exist_hops = aspath_count_hops(existattr->aspath);
972 int exist_confeds = aspath_count_confeds(existattr->aspath);
973
974 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
975 int aspath_hops;
976
977 aspath_hops = aspath_count_hops(newattr->aspath);
978 aspath_hops += aspath_count_confeds(newattr->aspath);
979
980 if (aspath_hops < (exist_hops + exist_confeds)) {
981 *reason = bgp_path_selection_confed_as_path;
982 if (debug)
983 zlog_debug(
984 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
985 pfx_buf, new_buf, exist_buf,
986 aspath_hops,
987 (exist_hops + exist_confeds));
988 return 1;
989 }
990
991 if (aspath_hops > (exist_hops + exist_confeds)) {
992 *reason = bgp_path_selection_confed_as_path;
993 if (debug)
994 zlog_debug(
995 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
996 pfx_buf, new_buf, exist_buf,
997 aspath_hops,
998 (exist_hops + exist_confeds));
999 return 0;
1000 }
1001 } else {
1002 int newhops = aspath_count_hops(newattr->aspath);
1003
1004 if (newhops < exist_hops) {
1005 *reason = bgp_path_selection_as_path;
1006 if (debug)
1007 zlog_debug(
1008 "%s: %s wins over %s due to aspath hopcount %d < %d",
1009 pfx_buf, new_buf, exist_buf,
1010 newhops, exist_hops);
1011 return 1;
1012 }
1013
1014 if (newhops > exist_hops) {
1015 *reason = bgp_path_selection_as_path;
1016 if (debug)
1017 zlog_debug(
1018 "%s: %s loses to %s due to aspath hopcount %d > %d",
1019 pfx_buf, new_buf, exist_buf,
1020 newhops, exist_hops);
1021 return 0;
1022 }
1023 }
1024 }
1025
1026 /* 5. Origin check. */
1027 if (newattr->origin < existattr->origin) {
1028 *reason = bgp_path_selection_origin;
1029 if (debug)
1030 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1031 pfx_buf, new_buf, exist_buf,
1032 bgp_origin_long_str[newattr->origin],
1033 bgp_origin_long_str[existattr->origin]);
1034 return 1;
1035 }
1036
1037 if (newattr->origin > existattr->origin) {
1038 *reason = bgp_path_selection_origin;
1039 if (debug)
1040 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1041 pfx_buf, new_buf, exist_buf,
1042 bgp_origin_long_str[newattr->origin],
1043 bgp_origin_long_str[existattr->origin]);
1044 return 0;
1045 }
1046
1047 /* 6. MED check. */
1048 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1049 && aspath_count_hops(existattr->aspath) == 0);
1050 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1051 && aspath_count_confeds(existattr->aspath) > 0
1052 && aspath_count_hops(newattr->aspath) == 0
1053 && aspath_count_hops(existattr->aspath) == 0);
1054
1055 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1056 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1057 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1058 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1059 || internal_as_route) {
1060 new_med = bgp_med_value(new->attr, bgp);
1061 exist_med = bgp_med_value(exist->attr, bgp);
1062
1063 if (new_med < exist_med) {
1064 *reason = bgp_path_selection_med;
1065 if (debug)
1066 zlog_debug(
1067 "%s: %s wins over %s due to MED %d < %d",
1068 pfx_buf, new_buf, exist_buf, new_med,
1069 exist_med);
1070 return 1;
1071 }
1072
1073 if (new_med > exist_med) {
1074 *reason = bgp_path_selection_med;
1075 if (debug)
1076 zlog_debug(
1077 "%s: %s loses to %s due to MED %d > %d",
1078 pfx_buf, new_buf, exist_buf, new_med,
1079 exist_med);
1080 return 0;
1081 }
1082 }
1083
1084 /* 7. Peer type check. */
1085 new_sort = new->peer->sort;
1086 exist_sort = exist->peer->sort;
1087
1088 if (new_sort == BGP_PEER_EBGP
1089 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1090 *reason = bgp_path_selection_peer;
1091 if (debug)
1092 zlog_debug(
1093 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1094 pfx_buf, new_buf, exist_buf);
1095 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1096 return 1;
1097 peer_sort_ret = 1;
1098 }
1099
1100 if (exist_sort == BGP_PEER_EBGP
1101 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1102 *reason = bgp_path_selection_peer;
1103 if (debug)
1104 zlog_debug(
1105 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1106 pfx_buf, new_buf, exist_buf);
1107 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1108 return 0;
1109 peer_sort_ret = 0;
1110 }
1111
1112 /* 8. IGP metric check. */
1113 newm = existm = 0;
1114
1115 if (new->extra)
1116 newm = new->extra->igpmetric;
1117 if (exist->extra)
1118 existm = exist->extra->igpmetric;
1119
1120 if (newm < existm) {
1121 if (debug && peer_sort_ret < 0)
1122 zlog_debug(
1123 "%s: %s wins over %s due to IGP metric %u < %u",
1124 pfx_buf, new_buf, exist_buf, newm, existm);
1125 igp_metric_ret = 1;
1126 }
1127
1128 if (newm > existm) {
1129 if (debug && peer_sort_ret < 0)
1130 zlog_debug(
1131 "%s: %s loses to %s due to IGP metric %u > %u",
1132 pfx_buf, new_buf, exist_buf, newm, existm);
1133 igp_metric_ret = 0;
1134 }
1135
1136 /* 9. Same IGP metric. Compare the cluster list length as
1137 representative of IGP hops metric. Rewrite the metric value
1138 pair (newm, existm) with the cluster list length. Prefer the
1139 path with smaller cluster list length. */
1140 if (newm == existm) {
1141 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP &&
1142 peer_sort_lookup(exist->peer) == BGP_PEER_IBGP &&
1143 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1144 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1145 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1146
1147 if (newm < existm) {
1148 if (debug && peer_sort_ret < 0)
1149 zlog_debug(
1150 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1151 pfx_buf, new_buf, exist_buf,
1152 newm, existm);
1153 igp_metric_ret = 1;
1154 }
1155
1156 if (newm > existm) {
1157 if (debug && peer_sort_ret < 0)
1158 zlog_debug(
1159 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1160 pfx_buf, new_buf, exist_buf,
1161 newm, existm);
1162 igp_metric_ret = 0;
1163 }
1164 }
1165 }
1166
1167 /* 10. confed-external vs. confed-internal */
1168 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1169 if (new_sort == BGP_PEER_CONFED
1170 && exist_sort == BGP_PEER_IBGP) {
1171 *reason = bgp_path_selection_confed;
1172 if (debug)
1173 zlog_debug(
1174 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1175 pfx_buf, new_buf, exist_buf);
1176 if (!CHECK_FLAG(bgp->flags,
1177 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1178 return 1;
1179 peer_sort_ret = 1;
1180 }
1181
1182 if (exist_sort == BGP_PEER_CONFED
1183 && new_sort == BGP_PEER_IBGP) {
1184 *reason = bgp_path_selection_confed;
1185 if (debug)
1186 zlog_debug(
1187 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1188 pfx_buf, new_buf, exist_buf);
1189 if (!CHECK_FLAG(bgp->flags,
1190 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1191 return 0;
1192 peer_sort_ret = 0;
1193 }
1194 }
1195
1196 /* 11. Maximum path check. */
1197 if (newm == existm) {
1198 /* If one path has a label but the other does not, do not treat
1199 * them as equals for multipath
1200 */
1201 int newl, existl;
1202
1203 newl = existl = 0;
1204
1205 if (new->extra)
1206 newl = new->extra->num_labels;
1207 if (exist->extra)
1208 existl = exist->extra->num_labels;
1209 if (((new->extra &&bgp_is_valid_label(&new->extra->label[0])) !=
1210 (exist->extra &&
1211 bgp_is_valid_label(&exist->extra->label[0]))) ||
1212 (newl != existl)) {
1213 if (debug)
1214 zlog_debug(
1215 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1216 pfx_buf, new_buf, exist_buf);
1217 } else if (CHECK_FLAG(bgp->flags,
1218 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1219
1220 /*
1221 * For the two paths, all comparison steps till IGP
1222 * metric
1223 * have succeeded - including AS_PATH hop count. Since
1224 * 'bgp
1225 * bestpath as-path multipath-relax' knob is on, we
1226 * don't need
1227 * an exact match of AS_PATH. Thus, mark the paths are
1228 * equal.
1229 * That will trigger both these paths to get into the
1230 * multipath
1231 * array.
1232 */
1233 *paths_eq = 1;
1234
1235 if (debug)
1236 zlog_debug(
1237 "%s: %s and %s are equal via multipath-relax",
1238 pfx_buf, new_buf, exist_buf);
1239 } else if (new->peer->sort == BGP_PEER_IBGP) {
1240 if (aspath_cmp(new->attr->aspath,
1241 exist->attr->aspath)) {
1242 *paths_eq = 1;
1243
1244 if (debug)
1245 zlog_debug(
1246 "%s: %s and %s are equal via matching aspaths",
1247 pfx_buf, new_buf, exist_buf);
1248 }
1249 } else if (new->peer->as == exist->peer->as) {
1250 *paths_eq = 1;
1251
1252 if (debug)
1253 zlog_debug(
1254 "%s: %s and %s are equal via same remote-as",
1255 pfx_buf, new_buf, exist_buf);
1256 }
1257 } else {
1258 /*
1259 * TODO: If unequal cost ibgp multipath is enabled we can
1260 * mark the paths as equal here instead of returning
1261 */
1262
1263 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1264 * if either step 7 or 10 (peer type checks) yielded a winner,
1265 * that result was returned immediately. Returning from step 10
1266 * ignored the return value computed in steps 8 and 9 (IGP
1267 * metric checks). In order to preserve that behavior, if
1268 * peer_sort_ret is set, return that rather than igp_metric_ret.
1269 */
1270 ret = peer_sort_ret;
1271 if (peer_sort_ret < 0) {
1272 ret = igp_metric_ret;
1273 if (debug) {
1274 if (ret == 1)
1275 zlog_debug(
1276 "%s: %s wins over %s after IGP metric comparison",
1277 pfx_buf, new_buf, exist_buf);
1278 else
1279 zlog_debug(
1280 "%s: %s loses to %s after IGP metric comparison",
1281 pfx_buf, new_buf, exist_buf);
1282 }
1283 *reason = bgp_path_selection_igp_metric;
1284 }
1285 return ret;
1286 }
1287
1288 /*
1289 * At this point, the decision whether to set *paths_eq = 1 has been
1290 * completed. If we deferred returning because of bestpath peer-type
1291 * relax configuration, return now.
1292 */
1293 if (peer_sort_ret >= 0)
1294 return peer_sort_ret;
1295
1296 /* 12. If both paths are external, prefer the path that was received
1297 first (the oldest one). This step minimizes route-flap, since a
1298 newer path won't displace an older one, even if it was the
1299 preferred route based on the additional decision criteria below. */
1300 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1301 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1302 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1303 *reason = bgp_path_selection_older;
1304 if (debug)
1305 zlog_debug(
1306 "%s: %s wins over %s due to oldest external",
1307 pfx_buf, new_buf, exist_buf);
1308 return 1;
1309 }
1310
1311 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1312 *reason = bgp_path_selection_older;
1313 if (debug)
1314 zlog_debug(
1315 "%s: %s loses to %s due to oldest external",
1316 pfx_buf, new_buf, exist_buf);
1317 return 0;
1318 }
1319 }
1320
1321 /* 13. Router-ID comparison. */
1322 /* If one of the paths is "stale", the corresponding peer router-id will
1323 * be 0 and would always win over the other path. If originator id is
1324 * used for the comparison, it will decide which path is better.
1325 */
1326 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1327 new_id.s_addr = newattr->originator_id.s_addr;
1328 else
1329 new_id.s_addr = new->peer->remote_id.s_addr;
1330 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1331 exist_id.s_addr = existattr->originator_id.s_addr;
1332 else
1333 exist_id.s_addr = exist->peer->remote_id.s_addr;
1334
1335 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1336 *reason = bgp_path_selection_router_id;
1337 if (debug)
1338 zlog_debug(
1339 "%s: %s wins over %s due to Router-ID comparison",
1340 pfx_buf, new_buf, exist_buf);
1341 return 1;
1342 }
1343
1344 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1345 *reason = bgp_path_selection_router_id;
1346 if (debug)
1347 zlog_debug(
1348 "%s: %s loses to %s due to Router-ID comparison",
1349 pfx_buf, new_buf, exist_buf);
1350 return 0;
1351 }
1352
1353 /* 14. Cluster length comparison. */
1354 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1355 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1356
1357 if (new_cluster < exist_cluster) {
1358 *reason = bgp_path_selection_cluster_length;
1359 if (debug)
1360 zlog_debug(
1361 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1362 pfx_buf, new_buf, exist_buf, new_cluster,
1363 exist_cluster);
1364 return 1;
1365 }
1366
1367 if (new_cluster > exist_cluster) {
1368 *reason = bgp_path_selection_cluster_length;
1369 if (debug)
1370 zlog_debug(
1371 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1372 pfx_buf, new_buf, exist_buf, new_cluster,
1373 exist_cluster);
1374 return 0;
1375 }
1376
1377 /* 15. Neighbor address comparison. */
1378 /* Do this only if neither path is "stale" as stale paths do not have
1379 * valid peer information (as the connection may or may not be up).
1380 */
1381 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1382 *reason = bgp_path_selection_stale;
1383 if (debug)
1384 zlog_debug(
1385 "%s: %s wins over %s due to latter path being STALE",
1386 pfx_buf, new_buf, exist_buf);
1387 return 1;
1388 }
1389
1390 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1391 *reason = bgp_path_selection_stale;
1392 if (debug)
1393 zlog_debug(
1394 "%s: %s loses to %s due to former path being STALE",
1395 pfx_buf, new_buf, exist_buf);
1396 return 0;
1397 }
1398
1399 /* locally configured routes to advertise do not have su_remote */
1400 if (new->peer->su_remote == NULL) {
1401 *reason = bgp_path_selection_local_configured;
1402 return 0;
1403 }
1404 if (exist->peer->su_remote == NULL) {
1405 *reason = bgp_path_selection_local_configured;
1406 return 1;
1407 }
1408
1409 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1410
1411 if (ret == 1) {
1412 *reason = bgp_path_selection_neighbor_ip;
1413 if (debug)
1414 zlog_debug(
1415 "%s: %s loses to %s due to Neighor IP comparison",
1416 pfx_buf, new_buf, exist_buf);
1417 return 0;
1418 }
1419
1420 if (ret == -1) {
1421 *reason = bgp_path_selection_neighbor_ip;
1422 if (debug)
1423 zlog_debug(
1424 "%s: %s wins over %s due to Neighor IP comparison",
1425 pfx_buf, new_buf, exist_buf);
1426 return 1;
1427 }
1428
1429 *reason = bgp_path_selection_default;
1430 if (debug)
1431 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1432 pfx_buf, new_buf, exist_buf);
1433
1434 return 1;
1435 }
1436
1437
1438 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1439 struct bgp_path_info *exist, int *paths_eq)
1440 {
1441 enum bgp_path_selection_reason reason;
1442 char pfx_buf[PREFIX2STR_BUFFER];
1443
1444 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1445 AFI_L2VPN, SAFI_EVPN, &reason);
1446 }
1447
1448 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1449 * is preferred, or 0 if they are the same (usually will only occur if
1450 * multipath is enabled
1451 * This version is compatible with */
1452 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1453 struct bgp_path_info *exist, char *pfx_buf,
1454 afi_t afi, safi_t safi,
1455 enum bgp_path_selection_reason *reason)
1456 {
1457 int paths_eq;
1458 int ret;
1459 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1460 afi, safi, reason);
1461
1462 if (paths_eq)
1463 ret = 0;
1464 else {
1465 if (ret == 1)
1466 ret = -1;
1467 else
1468 ret = 1;
1469 }
1470 return ret;
1471 }
1472
1473 static enum filter_type bgp_input_filter(struct peer *peer,
1474 const struct prefix *p,
1475 struct attr *attr, afi_t afi,
1476 safi_t safi)
1477 {
1478 struct bgp_filter *filter;
1479 enum filter_type ret = FILTER_PERMIT;
1480
1481 filter = &peer->filter[afi][safi];
1482
1483 #define FILTER_EXIST_WARN(F, f, filter) \
1484 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1485 zlog_debug("%s: Could not find configured input %s-list %s!", \
1486 peer->host, #f, F##_IN_NAME(filter));
1487
1488 if (DISTRIBUTE_IN_NAME(filter)) {
1489 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1490
1491 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1492 == FILTER_DENY) {
1493 ret = FILTER_DENY;
1494 goto done;
1495 }
1496 }
1497
1498 if (PREFIX_LIST_IN_NAME(filter)) {
1499 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1500
1501 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1502 == PREFIX_DENY) {
1503 ret = FILTER_DENY;
1504 goto done;
1505 }
1506 }
1507
1508 if (FILTER_LIST_IN_NAME(filter)) {
1509 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1510
1511 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1512 == AS_FILTER_DENY) {
1513 ret = FILTER_DENY;
1514 goto done;
1515 }
1516 }
1517
1518 done:
1519 if (frrtrace_enabled(frr_bgp, input_filter)) {
1520 char pfxprint[PREFIX2STR_BUFFER];
1521
1522 prefix2str(p, pfxprint, sizeof(pfxprint));
1523 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1524 ret == FILTER_PERMIT ? "permit" : "deny");
1525 }
1526
1527 return ret;
1528 #undef FILTER_EXIST_WARN
1529 }
1530
1531 static enum filter_type bgp_output_filter(struct peer *peer,
1532 const struct prefix *p,
1533 struct attr *attr, afi_t afi,
1534 safi_t safi)
1535 {
1536 struct bgp_filter *filter;
1537 enum filter_type ret = FILTER_PERMIT;
1538
1539 filter = &peer->filter[afi][safi];
1540
1541 #define FILTER_EXIST_WARN(F, f, filter) \
1542 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1543 zlog_debug("%s: Could not find configured output %s-list %s!", \
1544 peer->host, #f, F##_OUT_NAME(filter));
1545
1546 if (DISTRIBUTE_OUT_NAME(filter)) {
1547 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1548
1549 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1550 == FILTER_DENY) {
1551 ret = FILTER_DENY;
1552 goto done;
1553 }
1554 }
1555
1556 if (PREFIX_LIST_OUT_NAME(filter)) {
1557 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1558
1559 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1560 == PREFIX_DENY) {
1561 ret = FILTER_DENY;
1562 goto done;
1563 }
1564 }
1565
1566 if (FILTER_LIST_OUT_NAME(filter)) {
1567 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1568
1569 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1570 == AS_FILTER_DENY) {
1571 ret = FILTER_DENY;
1572 goto done;
1573 }
1574 }
1575
1576 if (frrtrace_enabled(frr_bgp, output_filter)) {
1577 char pfxprint[PREFIX2STR_BUFFER];
1578
1579 prefix2str(p, pfxprint, sizeof(pfxprint));
1580 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1581 ret == FILTER_PERMIT ? "permit" : "deny");
1582 }
1583
1584 done:
1585 return ret;
1586 #undef FILTER_EXIST_WARN
1587 }
1588
1589 /* If community attribute includes no_export then return 1. */
1590 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1591 {
1592 if (bgp_attr_get_community(attr)) {
1593 /* NO_ADVERTISE check. */
1594 if (community_include(bgp_attr_get_community(attr),
1595 COMMUNITY_NO_ADVERTISE))
1596 return true;
1597
1598 /* NO_EXPORT check. */
1599 if (peer->sort == BGP_PEER_EBGP &&
1600 community_include(bgp_attr_get_community(attr),
1601 COMMUNITY_NO_EXPORT))
1602 return true;
1603
1604 /* NO_EXPORT_SUBCONFED check. */
1605 if (peer->sort == BGP_PEER_EBGP
1606 || peer->sort == BGP_PEER_CONFED)
1607 if (community_include(bgp_attr_get_community(attr),
1608 COMMUNITY_NO_EXPORT_SUBCONFED))
1609 return true;
1610 }
1611 return false;
1612 }
1613
1614 /* Route reflection loop check. */
1615 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1616 {
1617 struct in_addr cluster_id;
1618 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1619
1620 if (cluster) {
1621 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1622 cluster_id = peer->bgp->cluster_id;
1623 else
1624 cluster_id = peer->bgp->router_id;
1625
1626 if (cluster_loop_check(cluster, cluster_id))
1627 return true;
1628 }
1629 return false;
1630 }
1631
1632 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1633 {
1634 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1635 if (peer->local_role == ROLE_PROVIDER ||
1636 peer->local_role == ROLE_RS_SERVER)
1637 return true;
1638 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1639 return true;
1640 return false;
1641 }
1642 if (peer->local_role == ROLE_CUSTOMER ||
1643 peer->local_role == ROLE_PEER ||
1644 peer->local_role == ROLE_RS_CLIENT) {
1645 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1646 attr->otc = peer->as;
1647 }
1648 return false;
1649 }
1650
1651 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1652 {
1653 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1654 if (peer->local_role == ROLE_CUSTOMER ||
1655 peer->local_role == ROLE_RS_CLIENT ||
1656 peer->local_role == ROLE_PEER)
1657 return true;
1658 return false;
1659 }
1660 if (peer->local_role == ROLE_PROVIDER ||
1661 peer->local_role == ROLE_PEER ||
1662 peer->local_role == ROLE_RS_SERVER) {
1663 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1664 attr->otc = peer->bgp->as;
1665 }
1666 return false;
1667 }
1668
1669 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1670 {
1671 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1672 }
1673
1674 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1675 struct attr *attr, afi_t afi, safi_t safi,
1676 const char *rmap_name, mpls_label_t *label,
1677 uint32_t num_labels, struct bgp_dest *dest)
1678 {
1679 struct bgp_filter *filter;
1680 struct bgp_path_info rmap_path = { 0 };
1681 struct bgp_path_info_extra extra = { 0 };
1682 route_map_result_t ret;
1683 struct route_map *rmap = NULL;
1684
1685 filter = &peer->filter[afi][safi];
1686
1687 /* Apply default weight value. */
1688 if (peer->weight[afi][safi])
1689 attr->weight = peer->weight[afi][safi];
1690
1691 if (rmap_name) {
1692 rmap = route_map_lookup_by_name(rmap_name);
1693
1694 if (rmap == NULL)
1695 return RMAP_DENY;
1696 } else {
1697 if (ROUTE_MAP_IN_NAME(filter)) {
1698 rmap = ROUTE_MAP_IN(filter);
1699
1700 if (rmap == NULL)
1701 return RMAP_DENY;
1702 }
1703 }
1704
1705 /* Route map apply. */
1706 if (rmap) {
1707 memset(&rmap_path, 0, sizeof(rmap_path));
1708 /* Duplicate current value to new structure for modification. */
1709 rmap_path.peer = peer;
1710 rmap_path.attr = attr;
1711 rmap_path.extra = &extra;
1712 rmap_path.net = dest;
1713
1714 extra.num_labels = num_labels;
1715 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1716 memcpy(extra.label, label,
1717 num_labels * sizeof(mpls_label_t));
1718
1719 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1720
1721 /* Apply BGP route map to the attribute. */
1722 ret = route_map_apply(rmap, p, &rmap_path);
1723
1724 peer->rmap_type = 0;
1725
1726 if (ret == RMAP_DENYMATCH)
1727 return RMAP_DENY;
1728 }
1729 return RMAP_PERMIT;
1730 }
1731
1732 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1733 struct attr *attr, afi_t afi, safi_t safi,
1734 const char *rmap_name)
1735 {
1736 struct bgp_path_info rmap_path;
1737 route_map_result_t ret;
1738 struct route_map *rmap = NULL;
1739 uint8_t rmap_type;
1740
1741 /*
1742 * So if we get to this point and have no rmap_name
1743 * we want to just show the output as it currently
1744 * exists.
1745 */
1746 if (!rmap_name)
1747 return RMAP_PERMIT;
1748
1749 /* Apply default weight value. */
1750 if (peer->weight[afi][safi])
1751 attr->weight = peer->weight[afi][safi];
1752
1753 rmap = route_map_lookup_by_name(rmap_name);
1754
1755 /*
1756 * If we have a route map name and we do not find
1757 * the routemap that means we have an implicit
1758 * deny.
1759 */
1760 if (rmap == NULL)
1761 return RMAP_DENY;
1762
1763 memset(&rmap_path, 0, sizeof(rmap_path));
1764 /* Route map apply. */
1765 /* Duplicate current value to new structure for modification. */
1766 rmap_path.peer = peer;
1767 rmap_path.attr = attr;
1768
1769 rmap_type = peer->rmap_type;
1770 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1771
1772 /* Apply BGP route map to the attribute. */
1773 ret = route_map_apply(rmap, p, &rmap_path);
1774
1775 peer->rmap_type = rmap_type;
1776
1777 if (ret == RMAP_DENYMATCH)
1778 /*
1779 * caller has multiple error paths with bgp_attr_flush()
1780 */
1781 return RMAP_DENY;
1782
1783 return RMAP_PERMIT;
1784 }
1785
1786 /* If this is an EBGP peer with remove-private-AS */
1787 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1788 struct peer *peer, struct attr *attr)
1789 {
1790 if (peer->sort == BGP_PEER_EBGP
1791 && (peer_af_flag_check(peer, afi, safi,
1792 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1793 || peer_af_flag_check(peer, afi, safi,
1794 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1795 || peer_af_flag_check(peer, afi, safi,
1796 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1797 || peer_af_flag_check(peer, afi, safi,
1798 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1799 // Take action on the entire aspath
1800 if (peer_af_flag_check(peer, afi, safi,
1801 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1802 || peer_af_flag_check(peer, afi, safi,
1803 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1804 if (peer_af_flag_check(
1805 peer, afi, safi,
1806 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1807 attr->aspath = aspath_replace_private_asns(
1808 attr->aspath, bgp->as, peer->as);
1809
1810 /*
1811 * Even if the aspath consists of just private ASNs we
1812 * need to walk the AS-Path to maintain all instances
1813 * of the peer's ASN to break possible loops.
1814 */
1815 else
1816 attr->aspath = aspath_remove_private_asns(
1817 attr->aspath, peer->as);
1818 }
1819
1820 // 'all' was not specified so the entire aspath must be private
1821 // ASNs
1822 // for us to do anything
1823 else if (aspath_private_as_check(attr->aspath)) {
1824 if (peer_af_flag_check(
1825 peer, afi, safi,
1826 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1827 attr->aspath = aspath_replace_private_asns(
1828 attr->aspath, bgp->as, peer->as);
1829 else
1830 /*
1831 * Walk the aspath to retain any instances of
1832 * the peer_asn
1833 */
1834 attr->aspath = aspath_remove_private_asns(
1835 attr->aspath, peer->as);
1836 }
1837 }
1838 }
1839
1840 /* If this is an EBGP peer with as-override */
1841 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1842 struct peer *peer, struct attr *attr)
1843 {
1844 struct aspath *aspath;
1845
1846 if (peer->sort == BGP_PEER_EBGP &&
1847 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1848 if (attr->aspath->refcnt)
1849 aspath = aspath_dup(attr->aspath);
1850 else
1851 aspath = attr->aspath;
1852
1853 attr->aspath = aspath_intern(
1854 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1855
1856 aspath_free(aspath);
1857 }
1858 }
1859
1860 void bgp_attr_add_llgr_community(struct attr *attr)
1861 {
1862 struct community *old;
1863 struct community *new;
1864 struct community *merge;
1865 struct community *llgr;
1866
1867 old = bgp_attr_get_community(attr);
1868 llgr = community_str2com("llgr-stale");
1869
1870 assert(llgr);
1871
1872 if (old) {
1873 merge = community_merge(community_dup(old), llgr);
1874
1875 if (old->refcnt == 0)
1876 community_free(&old);
1877
1878 new = community_uniq_sort(merge);
1879 community_free(&merge);
1880 } else {
1881 new = community_dup(llgr);
1882 }
1883
1884 community_free(&llgr);
1885
1886 bgp_attr_set_community(attr, new);
1887 }
1888
1889 void bgp_attr_add_gshut_community(struct attr *attr)
1890 {
1891 struct community *old;
1892 struct community *new;
1893 struct community *merge;
1894 struct community *gshut;
1895
1896 old = bgp_attr_get_community(attr);
1897 gshut = community_str2com("graceful-shutdown");
1898
1899 assert(gshut);
1900
1901 if (old) {
1902 merge = community_merge(community_dup(old), gshut);
1903
1904 if (old->refcnt == 0)
1905 community_free(&old);
1906
1907 new = community_uniq_sort(merge);
1908 community_free(&merge);
1909 } else {
1910 new = community_dup(gshut);
1911 }
1912
1913 community_free(&gshut);
1914 bgp_attr_set_community(attr, new);
1915
1916 /* When we add the graceful-shutdown community we must also
1917 * lower the local-preference */
1918 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1919 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1920 }
1921
1922
1923 /* Notify BGP Conditional advertisement scanner process. */
1924 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1925 {
1926 struct peer *peer = SUBGRP_PEER(subgrp);
1927 afi_t afi = SUBGRP_AFI(subgrp);
1928 safi_t safi = SUBGRP_SAFI(subgrp);
1929 struct bgp_filter *filter = &peer->filter[afi][safi];
1930
1931 if (!ADVERTISE_MAP_NAME(filter))
1932 return;
1933
1934 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1935 return;
1936
1937 peer->advmap_table_change = true;
1938 }
1939
1940
1941 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1942 {
1943 if (family == AF_INET) {
1944 attr->nexthop.s_addr = INADDR_ANY;
1945 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1946 }
1947 if (family == AF_INET6)
1948 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1949 if (family == AF_EVPN)
1950 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1951 }
1952
1953 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1954 struct update_subgroup *subgrp,
1955 const struct prefix *p, struct attr *attr,
1956 struct attr *post_attr)
1957 {
1958 struct bgp_filter *filter;
1959 struct peer *from;
1960 struct peer *peer;
1961 struct peer *onlypeer;
1962 struct bgp *bgp;
1963 struct attr *piattr;
1964 route_map_result_t ret;
1965 int transparent;
1966 int reflect;
1967 afi_t afi;
1968 safi_t safi;
1969 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1970 bool nh_reset = false;
1971 uint64_t cum_bw;
1972
1973 if (DISABLE_BGP_ANNOUNCE)
1974 return false;
1975
1976 afi = SUBGRP_AFI(subgrp);
1977 safi = SUBGRP_SAFI(subgrp);
1978 peer = SUBGRP_PEER(subgrp);
1979 onlypeer = NULL;
1980 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1981 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1982
1983 from = pi->peer;
1984 filter = &peer->filter[afi][safi];
1985 bgp = SUBGRP_INST(subgrp);
1986 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1987 : pi->attr;
1988
1989 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
1990 peer->pmax_out[afi][safi] != 0 &&
1991 subgrp->pscount >= peer->pmax_out[afi][safi]) {
1992 if (BGP_DEBUG(update, UPDATE_OUT) ||
1993 BGP_DEBUG(update, UPDATE_PREFIX)) {
1994 zlog_debug("%s reached maximum prefix to be send (%u)",
1995 peer->host, peer->pmax_out[afi][safi]);
1996 }
1997 return false;
1998 }
1999
2000 #ifdef ENABLE_BGP_VNC
2001 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2002 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2003 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2004
2005 /*
2006 * direct and direct_ext type routes originate internally even
2007 * though they can have peer pointers that reference other
2008 * systems
2009 */
2010 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2011 __func__, p);
2012 samepeer_safe = 1;
2013 }
2014 #endif
2015
2016 if (((afi == AFI_IP) || (afi == AFI_IP6))
2017 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2018 && (pi->type == ZEBRA_ROUTE_BGP)
2019 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2020
2021 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2022
2023 samepeer_safe = 1;
2024 }
2025
2026 /* With addpath we may be asked to TX all kinds of paths so make sure
2027 * pi is valid */
2028 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2029 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2030 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2031 return false;
2032 }
2033
2034 /* If this is not the bestpath then check to see if there is an enabled
2035 * addpath
2036 * feature that requires us to advertise it */
2037 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2038 if (!bgp_addpath_capable(pi, peer, afi, safi))
2039 return false;
2040
2041 /* Aggregate-address suppress check. */
2042 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2043 return false;
2044
2045 /*
2046 * If we are doing VRF 2 VRF leaking via the import
2047 * statement, we want to prevent the route going
2048 * off box as that the RT and RD created are localy
2049 * significant and globaly useless.
2050 */
2051 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2052 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2053 return false;
2054
2055 /* If it's labeled safi, make sure the route has a valid label. */
2056 if (safi == SAFI_LABELED_UNICAST) {
2057 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2058 if (!bgp_is_valid_label(&label)) {
2059 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2060 zlog_debug("u%" PRIu64 ":s%" PRIu64
2061 " %pFX is filtered - no label (%p)",
2062 subgrp->update_group->id, subgrp->id,
2063 p, &label);
2064 return false;
2065 }
2066 }
2067
2068 /* Do not send back route to sender. */
2069 if (onlypeer && from == onlypeer) {
2070 return false;
2071 }
2072
2073 /* Do not send the default route in the BGP table if the neighbor is
2074 * configured for default-originate */
2075 if (CHECK_FLAG(peer->af_flags[afi][safi],
2076 PEER_FLAG_DEFAULT_ORIGINATE)) {
2077 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2078 return false;
2079 else if (p->family == AF_INET6 && p->prefixlen == 0)
2080 return false;
2081 }
2082
2083 /* Transparency check. */
2084 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2085 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2086 transparent = 1;
2087 else
2088 transparent = 0;
2089
2090 /* If community is not disabled check the no-export and local. */
2091 if (!transparent && bgp_community_filter(peer, piattr)) {
2092 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2093 zlog_debug("%s: community filter check fail for %pFX",
2094 __func__, p);
2095 return false;
2096 }
2097
2098 /* If the attribute has originator-id and it is same as remote
2099 peer's id. */
2100 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2101 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2102 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2103 zlog_debug(
2104 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2105 onlypeer, p);
2106 return false;
2107 }
2108
2109 /* ORF prefix-list filter check */
2110 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2111 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2112 || CHECK_FLAG(peer->af_cap[afi][safi],
2113 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2114 if (peer->orf_plist[afi][safi]) {
2115 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2116 == PREFIX_DENY) {
2117 if (bgp_debug_update(NULL, p,
2118 subgrp->update_group, 0))
2119 zlog_debug(
2120 "%pBP [Update:SEND] %pFX is filtered via ORF",
2121 peer, p);
2122 return false;
2123 }
2124 }
2125
2126 /* Output filter check. */
2127 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2128 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2129 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2130 p);
2131 return false;
2132 }
2133
2134 /* AS path loop check. */
2135 if (peer->as_path_loop_detection &&
2136 aspath_loop_check(piattr->aspath, peer->as)) {
2137 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2138 zlog_debug(
2139 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2140 peer, peer->as);
2141 return false;
2142 }
2143
2144 /* If we're a CONFED we need to loop check the CONFED ID too */
2145 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2146 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2147 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2148 zlog_debug(
2149 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2150 peer, bgp->confed_id);
2151 return false;
2152 }
2153 }
2154
2155 /* Route-Reflect check. */
2156 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2157 reflect = 1;
2158 else
2159 reflect = 0;
2160
2161 /* IBGP reflection check. */
2162 if (reflect && !samepeer_safe) {
2163 /* A route from a Client peer. */
2164 if (CHECK_FLAG(from->af_flags[afi][safi],
2165 PEER_FLAG_REFLECTOR_CLIENT)) {
2166 /* Reflect to all the Non-Client peers and also to the
2167 Client peers other than the originator. Originator
2168 check
2169 is already done. So there is noting to do. */
2170 /* no bgp client-to-client reflection check. */
2171 if (CHECK_FLAG(bgp->flags,
2172 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2173 if (CHECK_FLAG(peer->af_flags[afi][safi],
2174 PEER_FLAG_REFLECTOR_CLIENT))
2175 return false;
2176 } else {
2177 /* A route from a Non-client peer. Reflect to all other
2178 clients. */
2179 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2180 PEER_FLAG_REFLECTOR_CLIENT))
2181 return false;
2182 }
2183 }
2184
2185 /* For modify attribute, copy it to temporary structure.
2186 * post_attr comes from BGP conditional advertisements, where
2187 * attributes are already processed by advertise-map route-map,
2188 * and this needs to be saved instead of overwriting from the
2189 * path attributes.
2190 */
2191 if (post_attr)
2192 *attr = *post_attr;
2193 else
2194 *attr = *piattr;
2195
2196 /* If local-preference is not set. */
2197 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2198 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2199 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2200 attr->local_pref = bgp->default_local_pref;
2201 }
2202
2203 /* If originator-id is not set and the route is to be reflected,
2204 set the originator id */
2205 if (reflect
2206 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2207 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2208 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2209 }
2210
2211 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2212 */
2213 if (peer->sort == BGP_PEER_EBGP
2214 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2215 if (from != bgp->peer_self && !transparent
2216 && !CHECK_FLAG(peer->af_flags[afi][safi],
2217 PEER_FLAG_MED_UNCHANGED))
2218 attr->flag &=
2219 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2220 }
2221
2222 /* Since the nexthop attribute can vary per peer, it is not explicitly
2223 * set
2224 * in announce check, only certain flags and length (or number of
2225 * nexthops
2226 * -- for IPv6/MP_REACH) are set here in order to guide the update
2227 * formation
2228 * code in setting the nexthop(s) on a per peer basis in
2229 * reformat_peer().
2230 * Typically, the source nexthop in the attribute is preserved but in
2231 * the
2232 * scenarios where we know it will always be overwritten, we reset the
2233 * nexthop to "0" in an attempt to achieve better Update packing. An
2234 * example of this is when a prefix from each of 2 IBGP peers needs to
2235 * be
2236 * announced to an EBGP peer (and they have the same attributes barring
2237 * their nexthop).
2238 */
2239 if (reflect)
2240 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2241
2242 #define NEXTHOP_IS_V6 \
2243 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2244 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2245 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2246 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2247
2248 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2249 * if
2250 * the peer (group) is configured to receive link-local nexthop
2251 * unchanged
2252 * and it is available in the prefix OR we're not reflecting the route,
2253 * link-local nexthop address is valid and
2254 * the peer (group) to whom we're going to announce is on a shared
2255 * network
2256 * and this is either a self-originated route or the peer is EBGP.
2257 * By checking if nexthop LL address is valid we are sure that
2258 * we do not announce LL address as `::`.
2259 */
2260 if (NEXTHOP_IS_V6) {
2261 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2262 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2263 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2264 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2265 || (!reflect && !transparent
2266 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2267 && peer->shared_network
2268 && (from == bgp->peer_self
2269 || peer->sort == BGP_PEER_EBGP))) {
2270 if (safi == SAFI_MPLS_VPN)
2271 attr->mp_nexthop_len =
2272 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2273 else
2274 attr->mp_nexthop_len =
2275 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2276 }
2277
2278 /* Clear off link-local nexthop in source, whenever it is not
2279 * needed to
2280 * ensure more prefixes share the same attribute for
2281 * announcement.
2282 */
2283 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2284 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2285 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2286 }
2287
2288 if (bgp_check_role_applicability(afi, safi) &&
2289 bgp_otc_egress(peer, attr))
2290 return false;
2291
2292 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2293 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2294
2295 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2296 filter->advmap.aname &&
2297 route_map_lookup_by_name(filter->advmap.aname)) {
2298 struct bgp_path_info rmap_path = {0};
2299 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2300 struct attr dummy_attr = *attr;
2301
2302 /* Fill temp path_info */
2303 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2304 pi, peer, &dummy_attr);
2305
2306 struct route_map *amap =
2307 route_map_lookup_by_name(filter->advmap.aname);
2308
2309 ret = route_map_apply(amap, p, &rmap_path);
2310
2311 bgp_attr_flush(&dummy_attr);
2312
2313 /*
2314 * The conditional advertisement mode is Withdraw and this
2315 * prefix is a conditional prefix. Don't advertise it
2316 */
2317 if (ret == RMAP_PERMITMATCH)
2318 return false;
2319 }
2320
2321 /* Route map & unsuppress-map apply. */
2322 if (!post_attr &&
2323 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2324 struct bgp_path_info rmap_path = {0};
2325 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2326 struct attr dummy_attr = {0};
2327
2328 /* Fill temp path_info */
2329 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2330 pi, peer, attr);
2331
2332 /* don't confuse inbound and outbound setting */
2333 RESET_FLAG(attr->rmap_change_flags);
2334
2335 /*
2336 * The route reflector is not allowed to modify the attributes
2337 * of the reflected IBGP routes unless explicitly allowed.
2338 */
2339 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2340 && !CHECK_FLAG(bgp->flags,
2341 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2342 dummy_attr = *attr;
2343 rmap_path.attr = &dummy_attr;
2344 }
2345
2346 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2347
2348 if (bgp_path_suppressed(pi))
2349 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2350 &rmap_path);
2351 else
2352 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2353 &rmap_path);
2354
2355 bgp_attr_flush(&dummy_attr);
2356 peer->rmap_type = 0;
2357
2358 if (ret == RMAP_DENYMATCH) {
2359 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2360 zlog_debug(
2361 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2362 peer, p, ROUTE_MAP_OUT_NAME(filter));
2363 bgp_attr_flush(rmap_path.attr);
2364 return false;
2365 }
2366 }
2367
2368 /* RFC 8212 to prevent route leaks.
2369 * This specification intends to improve this situation by requiring the
2370 * explicit configuration of both BGP Import and Export Policies for any
2371 * External BGP (EBGP) session such as customers, peers, or
2372 * confederation boundaries for all enabled address families. Through
2373 * codification of the aforementioned requirement, operators will
2374 * benefit from consistent behavior across different BGP
2375 * implementations.
2376 */
2377 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2378 if (!bgp_outbound_policy_exists(peer, filter)) {
2379 if (monotime_since(&bgp->ebgprequirespolicywarning,
2380 NULL) > FIFTEENMINUTE2USEC ||
2381 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2382 zlog_warn(
2383 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2384 monotime(&bgp->ebgprequirespolicywarning);
2385 }
2386 return false;
2387 }
2388
2389 /* draft-ietf-idr-deprecate-as-set-confed-set
2390 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2391 * Eventually, This document (if approved) updates RFC 4271
2392 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2393 * and obsoletes RFC 6472.
2394 */
2395 if (peer->bgp->reject_as_sets)
2396 if (aspath_check_as_sets(attr->aspath))
2397 return false;
2398
2399 /* If neighbor soo is configured, then check if the route has
2400 * SoO extended community and validate against the configured
2401 * one. If they match, do not announce, to prevent routing
2402 * loops.
2403 */
2404 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2405 peer->soo[afi][safi]) {
2406 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2407 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2408
2409 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2410 ECOMMUNITY_SITE_ORIGIN) ||
2411 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2412 ECOMMUNITY_SITE_ORIGIN) ||
2413 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2414 ECOMMUNITY_SITE_ORIGIN)) &&
2415 ecommunity_include(ecomm, ecomm_soo)) {
2416 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2417 zlog_debug(
2418 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2419 peer, p, ecommunity_str(ecomm_soo));
2420 return false;
2421 }
2422 }
2423
2424 /* Codification of AS 0 Processing */
2425 if (aspath_check_as_zero(attr->aspath))
2426 return false;
2427
2428 if (bgp_in_graceful_shutdown(bgp)) {
2429 if (peer->sort == BGP_PEER_IBGP
2430 || peer->sort == BGP_PEER_CONFED) {
2431 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2432 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2433 } else {
2434 bgp_attr_add_gshut_community(attr);
2435 }
2436 }
2437
2438 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2439 * Capability" to a neighbor MUST perform the following upon receiving
2440 * a route from that neighbor with the "LLGR_STALE" community, or upon
2441 * attaching the "LLGR_STALE" community itself per Section 4.2:
2442 *
2443 * The route SHOULD NOT be advertised to any neighbor from which the
2444 * Long-lived Graceful Restart Capability has not been received.
2445 */
2446 if (bgp_attr_get_community(attr) &&
2447 community_include(bgp_attr_get_community(attr),
2448 COMMUNITY_LLGR_STALE) &&
2449 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2450 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2451 return false;
2452
2453 /* After route-map has been applied, we check to see if the nexthop to
2454 * be carried in the attribute (that is used for the announcement) can
2455 * be cleared off or not. We do this in all cases where we would be
2456 * setting the nexthop to "ourselves". For IPv6, we only need to
2457 * consider
2458 * the global nexthop here; the link-local nexthop would have been
2459 * cleared
2460 * already, and if not, it is required by the update formation code.
2461 * Also see earlier comments in this function.
2462 */
2463 /*
2464 * If route-map has performed some operation on the nexthop or the peer
2465 * configuration says to pass it unchanged, we cannot reset the nexthop
2466 * here, so only attempt to do it if these aren't true. Note that the
2467 * route-map handler itself might have cleared the nexthop, if for
2468 * example,
2469 * it is configured as 'peer-address'.
2470 */
2471 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2472 piattr->rmap_change_flags)
2473 && !transparent
2474 && !CHECK_FLAG(peer->af_flags[afi][safi],
2475 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2476 /* We can reset the nexthop, if setting (or forcing) it to
2477 * 'self' */
2478 if (CHECK_FLAG(peer->af_flags[afi][safi],
2479 PEER_FLAG_NEXTHOP_SELF)
2480 || CHECK_FLAG(peer->af_flags[afi][safi],
2481 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2482 if (!reflect
2483 || CHECK_FLAG(peer->af_flags[afi][safi],
2484 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2485 subgroup_announce_reset_nhop(
2486 (peer_cap_enhe(peer, afi, safi)
2487 ? AF_INET6
2488 : p->family),
2489 attr);
2490 nh_reset = true;
2491 }
2492 } else if (peer->sort == BGP_PEER_EBGP) {
2493 /* Can also reset the nexthop if announcing to EBGP, but
2494 * only if
2495 * no peer in the subgroup is on a shared subnet.
2496 * Note: 3rd party nexthop currently implemented for
2497 * IPv4 only.
2498 */
2499 if ((p->family == AF_INET) &&
2500 (!bgp_subgrp_multiaccess_check_v4(
2501 piattr->nexthop,
2502 subgrp, from))) {
2503 subgroup_announce_reset_nhop(
2504 (peer_cap_enhe(peer, afi, safi)
2505 ? AF_INET6
2506 : p->family),
2507 attr);
2508 nh_reset = true;
2509 }
2510
2511 if ((p->family == AF_INET6) &&
2512 (!bgp_subgrp_multiaccess_check_v6(
2513 piattr->mp_nexthop_global,
2514 subgrp, from))) {
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
2523
2524
2525 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2526 /*
2527 * This flag is used for leaked vpn-vrf routes
2528 */
2529 int family = p->family;
2530
2531 if (peer_cap_enhe(peer, afi, safi))
2532 family = AF_INET6;
2533
2534 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2535 zlog_debug(
2536 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2537 __func__, p, family2str(family));
2538 subgroup_announce_reset_nhop(family, attr);
2539 nh_reset = true;
2540 }
2541 }
2542
2543 /* If IPv6/MP and nexthop does not have any override and happens
2544 * to
2545 * be a link-local address, reset it so that we don't pass along
2546 * the
2547 * source's link-local IPv6 address to recipients who may not be
2548 * on
2549 * the same interface.
2550 */
2551 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2552 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2553 subgroup_announce_reset_nhop(AF_INET6, attr);
2554 nh_reset = true;
2555 }
2556 }
2557
2558 /* If this is an iBGP, send Origin Validation State (OVS)
2559 * extended community (rfc8097).
2560 */
2561 if (peer->sort == BGP_PEER_IBGP) {
2562 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2563
2564 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2565
2566 if (rpki_state != RPKI_NOT_BEING_USED)
2567 bgp_attr_set_ecommunity(
2568 attr, ecommunity_add_origin_validation_state(
2569 rpki_state,
2570 bgp_attr_get_ecommunity(attr)));
2571 }
2572
2573 /*
2574 * When the next hop is set to ourselves, if all multipaths have
2575 * link-bandwidth announce the cumulative bandwidth as that makes
2576 * the most sense. However, don't modify if the link-bandwidth has
2577 * been explicitly set by user policy.
2578 */
2579 if (nh_reset &&
2580 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2581 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2582 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2583 bgp_attr_set_ecommunity(
2584 attr,
2585 ecommunity_replace_linkbw(
2586 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2587 CHECK_FLAG(
2588 peer->flags,
2589 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2590
2591 return true;
2592 }
2593
2594 static void bgp_route_select_timer_expire(struct thread *thread)
2595 {
2596 struct afi_safi_info *info;
2597 afi_t afi;
2598 safi_t safi;
2599 struct bgp *bgp;
2600
2601 info = THREAD_ARG(thread);
2602 afi = info->afi;
2603 safi = info->safi;
2604 bgp = info->bgp;
2605
2606 bgp->gr_info[afi][safi].t_route_select = NULL;
2607 XFREE(MTYPE_TMP, info);
2608
2609 /* Best path selection */
2610 bgp_best_path_select_defer(bgp, afi, safi);
2611 }
2612
2613 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2614 struct bgp_maxpaths_cfg *mpath_cfg,
2615 struct bgp_path_info_pair *result, afi_t afi,
2616 safi_t safi)
2617 {
2618 struct bgp_path_info *new_select;
2619 struct bgp_path_info *old_select;
2620 struct bgp_path_info *pi;
2621 struct bgp_path_info *pi1;
2622 struct bgp_path_info *pi2;
2623 struct bgp_path_info *nextpi = NULL;
2624 int paths_eq, do_mpath, debug;
2625 struct list mp_list;
2626 char pfx_buf[PREFIX2STR_BUFFER];
2627 char path_buf[PATH_ADDPATH_STR_BUFFER];
2628
2629 bgp_mp_list_init(&mp_list);
2630 do_mpath =
2631 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2632
2633 debug = bgp_debug_bestpath(dest);
2634
2635 if (debug)
2636 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2637
2638 dest->reason = bgp_path_selection_none;
2639 /* bgp deterministic-med */
2640 new_select = NULL;
2641 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2642
2643 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2644 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2645 pi1 = pi1->next)
2646 bgp_path_info_unset_flag(dest, pi1,
2647 BGP_PATH_DMED_SELECTED);
2648
2649 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2650 pi1 = pi1->next) {
2651 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2652 continue;
2653 if (BGP_PATH_HOLDDOWN(pi1))
2654 continue;
2655 if (pi1->peer != bgp->peer_self &&
2656 !CHECK_FLAG(pi1->peer->sflags,
2657 PEER_STATUS_NSF_WAIT)) {
2658 if (!peer_established(pi1->peer))
2659 continue;
2660 }
2661
2662 new_select = pi1;
2663 if (pi1->next) {
2664 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2665 if (CHECK_FLAG(pi2->flags,
2666 BGP_PATH_DMED_CHECK))
2667 continue;
2668 if (BGP_PATH_HOLDDOWN(pi2))
2669 continue;
2670 if (pi2->peer != bgp->peer_self
2671 && !CHECK_FLAG(
2672 pi2->peer->sflags,
2673 PEER_STATUS_NSF_WAIT))
2674 if (pi2->peer->status
2675 != Established)
2676 continue;
2677
2678 if (!aspath_cmp_left(pi1->attr->aspath,
2679 pi2->attr->aspath)
2680 && !aspath_cmp_left_confed(
2681 pi1->attr->aspath,
2682 pi2->attr->aspath))
2683 continue;
2684
2685 if (bgp_path_info_cmp(
2686 bgp, pi2, new_select,
2687 &paths_eq, mpath_cfg, debug,
2688 pfx_buf, afi, safi,
2689 &dest->reason)) {
2690 bgp_path_info_unset_flag(
2691 dest, new_select,
2692 BGP_PATH_DMED_SELECTED);
2693 new_select = pi2;
2694 }
2695
2696 bgp_path_info_set_flag(
2697 dest, pi2, BGP_PATH_DMED_CHECK);
2698 }
2699 }
2700 bgp_path_info_set_flag(dest, new_select,
2701 BGP_PATH_DMED_CHECK);
2702 bgp_path_info_set_flag(dest, new_select,
2703 BGP_PATH_DMED_SELECTED);
2704
2705 if (debug) {
2706 bgp_path_info_path_with_addpath_rx_str(
2707 new_select, path_buf, sizeof(path_buf));
2708 zlog_debug(
2709 "%pBD(%s): %s is the bestpath from AS %u",
2710 dest, bgp->name_pretty, path_buf,
2711 aspath_get_first_as(
2712 new_select->attr->aspath));
2713 }
2714 }
2715 }
2716
2717 /* Check old selected route and new selected route. */
2718 old_select = NULL;
2719 new_select = NULL;
2720 for (pi = bgp_dest_get_bgp_path_info(dest);
2721 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2722 enum bgp_path_selection_reason reason;
2723
2724 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2725 old_select = pi;
2726
2727 if (BGP_PATH_HOLDDOWN(pi)) {
2728 /* reap REMOVED routes, if needs be
2729 * selected route must stay for a while longer though
2730 */
2731 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2732 && (pi != old_select))
2733 bgp_path_info_reap(dest, pi);
2734
2735 if (debug)
2736 zlog_debug("%s: pi %p in holddown", __func__,
2737 pi);
2738
2739 continue;
2740 }
2741
2742 if (pi->peer && pi->peer != bgp->peer_self
2743 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2744 if (!peer_established(pi->peer)) {
2745
2746 if (debug)
2747 zlog_debug(
2748 "%s: pi %p non self peer %s not estab state",
2749 __func__, pi, pi->peer->host);
2750
2751 continue;
2752 }
2753
2754 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2755 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2756 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2757 if (debug)
2758 zlog_debug("%s: pi %p dmed", __func__, pi);
2759 continue;
2760 }
2761
2762 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2763
2764 reason = dest->reason;
2765 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2766 debug, pfx_buf, afi, safi,
2767 &dest->reason)) {
2768 if (new_select == NULL &&
2769 reason != bgp_path_selection_none)
2770 dest->reason = reason;
2771 new_select = pi;
2772 }
2773 }
2774
2775 /* Now that we know which path is the bestpath see if any of the other
2776 * paths
2777 * qualify as multipaths
2778 */
2779 if (debug) {
2780 if (new_select)
2781 bgp_path_info_path_with_addpath_rx_str(
2782 new_select, path_buf, sizeof(path_buf));
2783 else
2784 snprintf(path_buf, sizeof(path_buf), "NONE");
2785 zlog_debug(
2786 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2787 dest, bgp->name_pretty, path_buf,
2788 old_select ? old_select->peer->host : "NONE");
2789 }
2790
2791 if (do_mpath && new_select) {
2792 for (pi = bgp_dest_get_bgp_path_info(dest);
2793 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2794
2795 if (debug)
2796 bgp_path_info_path_with_addpath_rx_str(
2797 pi, path_buf, sizeof(path_buf));
2798
2799 if (pi == new_select) {
2800 if (debug)
2801 zlog_debug(
2802 "%pBD(%s): %s is the bestpath, add to the multipath list",
2803 dest, bgp->name_pretty,
2804 path_buf);
2805 bgp_mp_list_add(&mp_list, pi);
2806 continue;
2807 }
2808
2809 if (BGP_PATH_HOLDDOWN(pi))
2810 continue;
2811
2812 if (pi->peer && pi->peer != bgp->peer_self
2813 && !CHECK_FLAG(pi->peer->sflags,
2814 PEER_STATUS_NSF_WAIT))
2815 if (!peer_established(pi->peer))
2816 continue;
2817
2818 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2819 if (debug)
2820 zlog_debug(
2821 "%pBD: %s has the same nexthop as the bestpath, skip it",
2822 dest, path_buf);
2823 continue;
2824 }
2825
2826 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2827 mpath_cfg, debug, pfx_buf, afi, safi,
2828 &dest->reason);
2829
2830 if (paths_eq) {
2831 if (debug)
2832 zlog_debug(
2833 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2834 dest, path_buf);
2835 bgp_mp_list_add(&mp_list, pi);
2836 }
2837 }
2838 }
2839
2840 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2841 mpath_cfg);
2842 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2843 bgp_mp_list_clear(&mp_list);
2844
2845 bgp_addpath_update_ids(bgp, dest, afi, safi);
2846
2847 result->old = old_select;
2848 result->new = new_select;
2849
2850 return;
2851 }
2852
2853 /*
2854 * A new route/change in bestpath of an existing route. Evaluate the path
2855 * for advertisement to the subgroup.
2856 */
2857 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2858 struct bgp_path_info *selected,
2859 struct bgp_dest *dest,
2860 uint32_t addpath_tx_id)
2861 {
2862 const struct prefix *p;
2863 struct peer *onlypeer;
2864 struct attr attr;
2865 afi_t afi;
2866 safi_t safi;
2867 struct bgp *bgp;
2868 bool advertise;
2869
2870 p = bgp_dest_get_prefix(dest);
2871 afi = SUBGRP_AFI(subgrp);
2872 safi = SUBGRP_SAFI(subgrp);
2873 bgp = SUBGRP_INST(subgrp);
2874 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2875 : NULL);
2876
2877 if (BGP_DEBUG(update, UPDATE_OUT))
2878 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2879
2880 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2881 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2882 PEER_STATUS_ORF_WAIT_REFRESH))
2883 return;
2884
2885 memset(&attr, 0, sizeof(attr));
2886 /* It's initialized in bgp_announce_check() */
2887
2888 /* Announcement to the subgroup. If the route is filtered withdraw it.
2889 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2890 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2891 * route
2892 */
2893 advertise = bgp_check_advertise(bgp, dest);
2894
2895 if (selected) {
2896 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2897 NULL)) {
2898 /* Route is selected, if the route is already installed
2899 * in FIB, then it is advertised
2900 */
2901 if (advertise) {
2902 if (!bgp_check_withdrawal(bgp, dest))
2903 bgp_adj_out_set_subgroup(
2904 dest, subgrp, &attr, selected);
2905 else
2906 bgp_adj_out_unset_subgroup(
2907 dest, subgrp, 1, addpath_tx_id);
2908 }
2909 } else
2910 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2911 addpath_tx_id);
2912 }
2913
2914 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2915 else {
2916 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2917 }
2918 }
2919
2920 /*
2921 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2922 * This is called at the end of route processing.
2923 */
2924 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2925 {
2926 struct bgp_path_info *pi;
2927
2928 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2929 if (BGP_PATH_HOLDDOWN(pi))
2930 continue;
2931 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2932 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2933 }
2934 }
2935
2936 /*
2937 * Has the route changed from the RIB's perspective? This is invoked only
2938 * if the route selection returns the same best route as earlier - to
2939 * determine if we need to update zebra or not.
2940 */
2941 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2942 {
2943 struct bgp_path_info *mpinfo;
2944
2945 /* If this is multipath, check all selected paths for any nexthop
2946 * change or attribute change. Some attribute changes (e.g., community)
2947 * aren't of relevance to the RIB, but we'll update zebra to ensure
2948 * we handle the case of BGP nexthop change. This is the behavior
2949 * when the best path has an attribute change anyway.
2950 */
2951 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2952 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2953 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2954 return true;
2955
2956 /*
2957 * If this is multipath, check all selected paths for any nexthop change
2958 */
2959 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2960 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2961 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2962 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2963 return true;
2964 }
2965
2966 /* Nothing has changed from the RIB's perspective. */
2967 return false;
2968 }
2969
2970 struct bgp_process_queue {
2971 struct bgp *bgp;
2972 STAILQ_HEAD(, bgp_dest) pqueue;
2973 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2974 unsigned int flags;
2975 unsigned int queued;
2976 };
2977
2978 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2979 safi_t safi, struct bgp_dest *dest,
2980 struct bgp_path_info *new_select,
2981 struct bgp_path_info *old_select)
2982 {
2983 const struct prefix *p = bgp_dest_get_prefix(dest);
2984
2985 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2986 return;
2987
2988 if (advertise_type5_routes(bgp, afi) && new_select
2989 && is_route_injectable_into_evpn(new_select)) {
2990
2991 /* apply the route-map */
2992 if (bgp->adv_cmd_rmap[afi][safi].map) {
2993 route_map_result_t ret;
2994 struct bgp_path_info rmap_path;
2995 struct bgp_path_info_extra rmap_path_extra;
2996 struct attr dummy_attr;
2997
2998 dummy_attr = *new_select->attr;
2999
3000 /* Fill temp path_info */
3001 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3002 new_select, new_select->peer,
3003 &dummy_attr);
3004
3005 RESET_FLAG(dummy_attr.rmap_change_flags);
3006
3007 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3008 p, &rmap_path);
3009
3010 if (ret == RMAP_DENYMATCH) {
3011 bgp_attr_flush(&dummy_attr);
3012 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3013 safi);
3014 } else
3015 bgp_evpn_advertise_type5_route(
3016 bgp, p, &dummy_attr, afi, safi);
3017 } else {
3018 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3019 afi, safi);
3020 }
3021 } else if (advertise_type5_routes(bgp, afi) && old_select
3022 && is_route_injectable_into_evpn(old_select))
3023 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3024 }
3025
3026 /*
3027 * Utility to determine whether a particular path_info should use
3028 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3029 * in a path where we basically _know_ this is a BGP-LU route.
3030 */
3031 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3032 {
3033 /* Certain types get imp null; so do paths where the nexthop is
3034 * not labeled.
3035 */
3036 if (new_select->sub_type == BGP_ROUTE_STATIC
3037 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3038 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3039 return true;
3040 else if (new_select->extra == NULL ||
3041 !bgp_is_valid_label(&new_select->extra->label[0]))
3042 /* TODO -- should be configurable? */
3043 return true;
3044 else
3045 return false;
3046 }
3047
3048 /*
3049 * old_select = The old best path
3050 * new_select = the new best path
3051 *
3052 * if (!old_select && new_select)
3053 * We are sending new information on.
3054 *
3055 * if (old_select && new_select) {
3056 * if (new_select != old_select)
3057 * We have a new best path send a change
3058 * else
3059 * We've received a update with new attributes that needs
3060 * to be passed on.
3061 * }
3062 *
3063 * if (old_select && !new_select)
3064 * We have no eligible route that we can announce or the rn
3065 * is being removed.
3066 */
3067 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3068 afi_t afi, safi_t safi)
3069 {
3070 struct bgp_path_info *new_select;
3071 struct bgp_path_info *old_select;
3072 struct bgp_path_info_pair old_and_new;
3073 int debug = 0;
3074
3075 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3076 if (dest)
3077 debug = bgp_debug_bestpath(dest);
3078 if (debug)
3079 zlog_debug(
3080 "%s: bgp delete in progress, ignoring event, p=%pBD",
3081 __func__, dest);
3082 return;
3083 }
3084 /* Is it end of initial update? (after startup) */
3085 if (!dest) {
3086 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3087 sizeof(bgp->update_delay_zebra_resume_time));
3088
3089 bgp->main_zebra_update_hold = 0;
3090 FOREACH_AFI_SAFI (afi, safi) {
3091 if (bgp_fibupd_safi(safi))
3092 bgp_zebra_announce_table(bgp, afi, safi);
3093 }
3094 bgp->main_peers_update_hold = 0;
3095
3096 bgp_start_routeadv(bgp);
3097 return;
3098 }
3099
3100 const struct prefix *p = bgp_dest_get_prefix(dest);
3101
3102 debug = bgp_debug_bestpath(dest);
3103 if (debug)
3104 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
3105 dest, bgp->name_pretty, afi2str(afi),
3106 safi2str(safi));
3107
3108 /* The best path calculation for the route is deferred if
3109 * BGP_NODE_SELECT_DEFER is set
3110 */
3111 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3112 if (BGP_DEBUG(update, UPDATE_OUT))
3113 zlog_debug("SELECT_DEFER flag set for route %p", dest);
3114 return;
3115 }
3116
3117 /* Best path selection. */
3118 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3119 afi, safi);
3120 old_select = old_and_new.old;
3121 new_select = old_and_new.new;
3122
3123 /* Do we need to allocate or free labels?
3124 * Right now, since we only deal with per-prefix labels, it is not
3125 * necessary to do this upon changes to best path. Exceptions:
3126 * - label index has changed -> recalculate resulting label
3127 * - path_info sub_type changed -> switch to/from implicit-null
3128 * - no valid label (due to removed static label binding) -> get new one
3129 */
3130 if (bgp->allocate_mpls_labels[afi][safi]) {
3131 if (new_select) {
3132 if (!old_select
3133 || bgp_label_index_differs(new_select, old_select)
3134 || new_select->sub_type != old_select->sub_type
3135 || !bgp_is_valid_label(&dest->local_label)) {
3136 /* Enforced penultimate hop popping:
3137 * implicit-null for local routes, aggregate
3138 * and redistributed routes
3139 */
3140 if (bgp_lu_need_imp_null(new_select)) {
3141 if (CHECK_FLAG(
3142 dest->flags,
3143 BGP_NODE_REGISTERED_FOR_LABEL)
3144 || CHECK_FLAG(
3145 dest->flags,
3146 BGP_NODE_LABEL_REQUESTED))
3147 bgp_unregister_for_label(dest);
3148 dest->local_label = mpls_lse_encode(
3149 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3150 1);
3151 bgp_set_valid_label(&dest->local_label);
3152 } else
3153 bgp_register_for_label(dest,
3154 new_select);
3155 }
3156 } else if (CHECK_FLAG(dest->flags,
3157 BGP_NODE_REGISTERED_FOR_LABEL)
3158 || CHECK_FLAG(dest->flags,
3159 BGP_NODE_LABEL_REQUESTED)) {
3160 bgp_unregister_for_label(dest);
3161 }
3162 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3163 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3164 bgp_unregister_for_label(dest);
3165 }
3166
3167 if (debug)
3168 zlog_debug(
3169 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3170 __func__, dest, bgp->name_pretty, afi2str(afi),
3171 safi2str(safi), old_select, new_select);
3172
3173 /* If best route remains the same and this is not due to user-initiated
3174 * clear, see exactly what needs to be done.
3175 */
3176 if (old_select && old_select == new_select
3177 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3178 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3179 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3180 if (bgp_zebra_has_route_changed(old_select)) {
3181 #ifdef ENABLE_BGP_VNC
3182 vnc_import_bgp_add_route(bgp, p, old_select);
3183 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3184 #endif
3185 if (bgp_fibupd_safi(safi)
3186 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3187
3188 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3189 && new_select->sub_type == BGP_ROUTE_NORMAL)
3190 SET_FLAG(dest->flags,
3191 BGP_NODE_FIB_INSTALL_PENDING);
3192
3193 if (new_select->type == ZEBRA_ROUTE_BGP
3194 && (new_select->sub_type == BGP_ROUTE_NORMAL
3195 || new_select->sub_type
3196 == BGP_ROUTE_IMPORTED))
3197
3198 bgp_zebra_announce(dest, p, old_select,
3199 bgp, afi, safi);
3200 }
3201 }
3202
3203 /* If there is a change of interest to peers, reannounce the
3204 * route. */
3205 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3206 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3207 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3208 group_announce_route(bgp, afi, safi, dest, new_select);
3209
3210 /* unicast routes must also be annouced to
3211 * labeled-unicast update-groups */
3212 if (safi == SAFI_UNICAST)
3213 group_announce_route(bgp, afi,
3214 SAFI_LABELED_UNICAST, dest,
3215 new_select);
3216
3217 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3218 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3219 }
3220
3221 /* advertise/withdraw type-5 routes */
3222 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3223 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3224 bgp_process_evpn_route_injection(
3225 bgp, afi, safi, dest, old_select, old_select);
3226
3227 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3228 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3229 bgp_zebra_clear_route_change_flags(dest);
3230 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3231 return;
3232 }
3233
3234 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3235 */
3236 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3237
3238 /* bestpath has changed; bump version */
3239 if (old_select || new_select) {
3240 bgp_bump_version(dest);
3241
3242 if (!bgp->t_rmap_def_originate_eval) {
3243 bgp_lock(bgp);
3244 thread_add_timer(
3245 bm->master,
3246 update_group_refresh_default_originate_route_map,
3247 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3248 &bgp->t_rmap_def_originate_eval);
3249 }
3250 }
3251
3252 if (old_select)
3253 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3254 if (new_select) {
3255 if (debug)
3256 zlog_debug("%s: setting SELECTED flag", __func__);
3257 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3258 bgp_path_info_unset_flag(dest, new_select,
3259 BGP_PATH_ATTR_CHANGED);
3260 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3261 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3262 }
3263
3264 #ifdef ENABLE_BGP_VNC
3265 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3266 if (old_select != new_select) {
3267 if (old_select) {
3268 vnc_import_bgp_exterior_del_route(bgp, p,
3269 old_select);
3270 vnc_import_bgp_del_route(bgp, p, old_select);
3271 }
3272 if (new_select) {
3273 vnc_import_bgp_exterior_add_route(bgp, p,
3274 new_select);
3275 vnc_import_bgp_add_route(bgp, p, new_select);
3276 }
3277 }
3278 }
3279 #endif
3280
3281 group_announce_route(bgp, afi, safi, dest, new_select);
3282
3283 /* unicast routes must also be annouced to labeled-unicast update-groups
3284 */
3285 if (safi == SAFI_UNICAST)
3286 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3287 new_select);
3288
3289 /* FIB update. */
3290 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3291 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3292
3293 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3294 && (new_select->sub_type == BGP_ROUTE_NORMAL
3295 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3296 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3297
3298 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3299 SET_FLAG(dest->flags,
3300 BGP_NODE_FIB_INSTALL_PENDING);
3301
3302 /* if this is an evpn imported type-5 prefix,
3303 * we need to withdraw the route first to clear
3304 * the nh neigh and the RMAC entry.
3305 */
3306 if (old_select &&
3307 is_route_parent_evpn(old_select))
3308 bgp_zebra_withdraw(p, old_select, bgp, safi);
3309
3310 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3311 } else {
3312 /* Withdraw the route from the kernel. */
3313 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3314 && (old_select->sub_type == BGP_ROUTE_NORMAL
3315 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3316 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3317
3318 bgp_zebra_withdraw(p, old_select, bgp, safi);
3319 }
3320 }
3321
3322 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3323 old_select);
3324
3325 /* Clear any route change flags. */
3326 bgp_zebra_clear_route_change_flags(dest);
3327
3328 /* Reap old select bgp_path_info, if it has been removed */
3329 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3330 bgp_path_info_reap(dest, old_select);
3331
3332 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3333 return;
3334 }
3335
3336 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3337 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3338 {
3339 struct bgp_dest *dest;
3340 int cnt = 0;
3341 struct afi_safi_info *thread_info;
3342
3343 if (bgp->gr_info[afi][safi].t_route_select) {
3344 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3345
3346 thread_info = THREAD_ARG(t);
3347 XFREE(MTYPE_TMP, thread_info);
3348 THREAD_OFF(bgp->gr_info[afi][safi].t_route_select);
3349 }
3350
3351 if (BGP_DEBUG(update, UPDATE_OUT)) {
3352 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3353 get_afi_safi_str(afi, safi, false),
3354 bgp->gr_info[afi][safi].gr_deferred);
3355 }
3356
3357 /* Process the route list */
3358 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3359 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3360 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3361 dest = bgp_route_next(dest)) {
3362 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3363 continue;
3364
3365 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3366 bgp->gr_info[afi][safi].gr_deferred--;
3367 bgp_process_main_one(bgp, dest, afi, safi);
3368 cnt++;
3369 }
3370 /* If iteration stopped before the entire table was traversed then the
3371 * node needs to be unlocked.
3372 */
3373 if (dest) {
3374 bgp_dest_unlock_node(dest);
3375 dest = NULL;
3376 }
3377
3378 /* Send EOR message when all routes are processed */
3379 if (!bgp->gr_info[afi][safi].gr_deferred) {
3380 bgp_send_delayed_eor(bgp);
3381 /* Send route processing complete message to RIB */
3382 bgp_zebra_update(afi, safi, bgp->vrf_id,
3383 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3384 return;
3385 }
3386
3387 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3388
3389 thread_info->afi = afi;
3390 thread_info->safi = safi;
3391 thread_info->bgp = bgp;
3392
3393 /* If there are more routes to be processed, start the
3394 * selection timer
3395 */
3396 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3397 BGP_ROUTE_SELECT_DELAY,
3398 &bgp->gr_info[afi][safi].t_route_select);
3399 }
3400
3401 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3402 {
3403 struct bgp_process_queue *pqnode = data;
3404 struct bgp *bgp = pqnode->bgp;
3405 struct bgp_table *table;
3406 struct bgp_dest *dest;
3407
3408 /* eoiu marker */
3409 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3410 bgp_process_main_one(bgp, NULL, 0, 0);
3411 /* should always have dedicated wq call */
3412 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3413 return WQ_SUCCESS;
3414 }
3415
3416 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3417 dest = STAILQ_FIRST(&pqnode->pqueue);
3418 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3419 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3420 table = bgp_dest_table(dest);
3421 /* note, new DESTs may be added as part of processing */
3422 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3423
3424 bgp_dest_unlock_node(dest);
3425 bgp_table_unlock(table);
3426 }
3427
3428 return WQ_SUCCESS;
3429 }
3430
3431 static void bgp_processq_del(struct work_queue *wq, void *data)
3432 {
3433 struct bgp_process_queue *pqnode = data;
3434
3435 bgp_unlock(pqnode->bgp);
3436
3437 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3438 }
3439
3440 void bgp_process_queue_init(struct bgp *bgp)
3441 {
3442 if (!bgp->process_queue) {
3443 char name[BUFSIZ];
3444
3445 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3446 bgp->process_queue = work_queue_new(bm->master, name);
3447 }
3448
3449 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3450 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3451 bgp->process_queue->spec.max_retries = 0;
3452 bgp->process_queue->spec.hold = 50;
3453 /* Use a higher yield value of 50ms for main queue processing */
3454 bgp->process_queue->spec.yield = 50 * 1000L;
3455 }
3456
3457 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3458 {
3459 struct bgp_process_queue *pqnode;
3460
3461 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3462 sizeof(struct bgp_process_queue));
3463
3464 /* unlocked in bgp_processq_del */
3465 pqnode->bgp = bgp_lock(bgp);
3466 STAILQ_INIT(&pqnode->pqueue);
3467
3468 return pqnode;
3469 }
3470
3471 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3472 {
3473 #define ARBITRARY_PROCESS_QLEN 10000
3474 struct work_queue *wq = bgp->process_queue;
3475 struct bgp_process_queue *pqnode;
3476 int pqnode_reuse = 0;
3477
3478 /* already scheduled for processing? */
3479 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3480 return;
3481
3482 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3483 * the workqueue
3484 */
3485 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3486 if (BGP_DEBUG(update, UPDATE_OUT))
3487 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3488 dest);
3489 return;
3490 }
3491
3492 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3493 if (BGP_DEBUG(update, UPDATE_OUT))
3494 zlog_debug(
3495 "Soft reconfigure table in progress for route %p",
3496 dest);
3497 return;
3498 }
3499
3500 if (wq == NULL)
3501 return;
3502
3503 /* Add route nodes to an existing work queue item until reaching the
3504 limit only if is from the same BGP view and it's not an EOIU marker
3505 */
3506 if (work_queue_item_count(wq)) {
3507 struct work_queue_item *item = work_queue_last_item(wq);
3508 pqnode = item->data;
3509
3510 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3511 || pqnode->bgp != bgp
3512 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3513 pqnode = bgp_processq_alloc(bgp);
3514 else
3515 pqnode_reuse = 1;
3516 } else
3517 pqnode = bgp_processq_alloc(bgp);
3518 /* all unlocked in bgp_process_wq */
3519 bgp_table_lock(bgp_dest_table(dest));
3520
3521 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3522 bgp_dest_lock_node(dest);
3523
3524 /* can't be enqueued twice */
3525 assert(STAILQ_NEXT(dest, pq) == NULL);
3526 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3527 pqnode->queued++;
3528
3529 if (!pqnode_reuse)
3530 work_queue_add(wq, pqnode);
3531
3532 return;
3533 }
3534
3535 void bgp_add_eoiu_mark(struct bgp *bgp)
3536 {
3537 struct bgp_process_queue *pqnode;
3538
3539 if (bgp->process_queue == NULL)
3540 return;
3541
3542 pqnode = bgp_processq_alloc(bgp);
3543
3544 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3545 work_queue_add(bgp->process_queue, pqnode);
3546 }
3547
3548 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3549 {
3550 struct peer *peer;
3551
3552 peer = THREAD_ARG(thread);
3553 peer->t_pmax_restart = NULL;
3554
3555 if (bgp_debug_neighbor_events(peer))
3556 zlog_debug(
3557 "%s Maximum-prefix restart timer expired, restore peering",
3558 peer->host);
3559
3560 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3561 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3562 }
3563
3564 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3565 safi_t safi)
3566 {
3567 uint32_t count = 0;
3568 bool filtered = false;
3569 struct bgp_dest *dest;
3570 struct bgp_adj_in *ain;
3571 struct attr attr = {};
3572 struct bgp_table *table = peer->bgp->rib[afi][safi];
3573
3574 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3575 for (ain = dest->adj_in; ain; ain = ain->next) {
3576 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3577
3578 attr = *ain->attr;
3579
3580 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3581 == FILTER_DENY)
3582 filtered = true;
3583
3584 if (bgp_input_modifier(
3585 peer, rn_p, &attr, afi, safi,
3586 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3587 NULL, 0, NULL)
3588 == RMAP_DENY)
3589 filtered = true;
3590
3591 if (filtered)
3592 count++;
3593
3594 bgp_attr_flush(&attr);
3595 }
3596 }
3597
3598 return count;
3599 }
3600
3601 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3602 int always)
3603 {
3604 iana_afi_t pkt_afi;
3605 iana_safi_t pkt_safi;
3606 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3607 PEER_FLAG_MAX_PREFIX_FORCE))
3608 ? bgp_filtered_routes_count(peer, afi, safi)
3609 + peer->pcount[afi][safi]
3610 : peer->pcount[afi][safi];
3611
3612 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3613 return false;
3614
3615 if (pcount > peer->pmax[afi][safi]) {
3616 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3617 PEER_STATUS_PREFIX_LIMIT)
3618 && !always)
3619 return false;
3620
3621 zlog_info(
3622 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3623 get_afi_safi_str(afi, safi, false), peer, pcount,
3624 peer->pmax[afi][safi]);
3625 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3626
3627 if (CHECK_FLAG(peer->af_flags[afi][safi],
3628 PEER_FLAG_MAX_PREFIX_WARNING))
3629 return false;
3630
3631 /* Convert AFI, SAFI to values for packet. */
3632 pkt_afi = afi_int2iana(afi);
3633 pkt_safi = safi_int2iana(safi);
3634 {
3635 uint8_t ndata[7];
3636
3637 ndata[0] = (pkt_afi >> 8);
3638 ndata[1] = pkt_afi;
3639 ndata[2] = pkt_safi;
3640 ndata[3] = (peer->pmax[afi][safi] >> 24);
3641 ndata[4] = (peer->pmax[afi][safi] >> 16);
3642 ndata[5] = (peer->pmax[afi][safi] >> 8);
3643 ndata[6] = (peer->pmax[afi][safi]);
3644
3645 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3646 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3647 BGP_NOTIFY_CEASE_MAX_PREFIX,
3648 ndata, 7);
3649 }
3650
3651 /* Dynamic peers will just close their connection. */
3652 if (peer_dynamic_neighbor(peer))
3653 return true;
3654
3655 /* restart timer start */
3656 if (peer->pmax_restart[afi][safi]) {
3657 peer->v_pmax_restart =
3658 peer->pmax_restart[afi][safi] * 60;
3659
3660 if (bgp_debug_neighbor_events(peer))
3661 zlog_debug(
3662 "%pBP Maximum-prefix restart timer started for %d secs",
3663 peer, peer->v_pmax_restart);
3664
3665 BGP_TIMER_ON(peer->t_pmax_restart,
3666 bgp_maximum_prefix_restart_timer,
3667 peer->v_pmax_restart);
3668 }
3669
3670 return true;
3671 } else
3672 UNSET_FLAG(peer->af_sflags[afi][safi],
3673 PEER_STATUS_PREFIX_LIMIT);
3674
3675 if (pcount
3676 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3677 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3678 PEER_STATUS_PREFIX_THRESHOLD)
3679 && !always)
3680 return false;
3681
3682 zlog_info(
3683 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3684 get_afi_safi_str(afi, safi, false), peer, pcount,
3685 peer->pmax[afi][safi]);
3686 SET_FLAG(peer->af_sflags[afi][safi],
3687 PEER_STATUS_PREFIX_THRESHOLD);
3688 } else
3689 UNSET_FLAG(peer->af_sflags[afi][safi],
3690 PEER_STATUS_PREFIX_THRESHOLD);
3691 return false;
3692 }
3693
3694 /* Unconditionally remove the route from the RIB, without taking
3695 * damping into consideration (eg, because the session went down)
3696 */
3697 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3698 struct peer *peer, afi_t afi, safi_t safi)
3699 {
3700
3701 struct bgp *bgp = NULL;
3702 bool delete_route = false;
3703
3704 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3705 safi);
3706
3707 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3708 bgp_path_info_delete(dest, pi); /* keep historical info */
3709
3710 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3711 * flag
3712 */
3713 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3714 delete_route = true;
3715 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3716 delete_route = true;
3717 if (delete_route) {
3718 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3719 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3720 bgp = pi->peer->bgp;
3721 bgp->gr_info[afi][safi].gr_deferred--;
3722 }
3723 }
3724 }
3725
3726 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3727 bgp_process(peer->bgp, dest, afi, safi);
3728 }
3729
3730 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3731 struct peer *peer, afi_t afi, safi_t safi,
3732 struct prefix_rd *prd)
3733 {
3734 const struct prefix *p = bgp_dest_get_prefix(dest);
3735
3736 /* apply dampening, if result is suppressed, we'll be retaining
3737 * the bgp_path_info in the RIB for historical reference.
3738 */
3739 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3740 && peer->sort == BGP_PEER_EBGP)
3741 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3742 == BGP_DAMP_SUPPRESSED) {
3743 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3744 safi);
3745 return;
3746 }
3747
3748 #ifdef ENABLE_BGP_VNC
3749 if (safi == SAFI_MPLS_VPN) {
3750 struct bgp_dest *pdest = NULL;
3751 struct bgp_table *table = NULL;
3752
3753 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3754 (struct prefix *)prd);
3755 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3756 table = bgp_dest_get_bgp_table_info(pdest);
3757
3758 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3759 peer->bgp, prd, table, p, pi);
3760 }
3761 bgp_dest_unlock_node(pdest);
3762 }
3763 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3764 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3765
3766 vnc_import_bgp_del_route(peer->bgp, p, pi);
3767 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3768 }
3769 }
3770 #endif
3771
3772 /* If this is an EVPN route, process for un-import. */
3773 if (safi == SAFI_EVPN)
3774 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3775
3776 bgp_rib_remove(dest, pi, peer, afi, safi);
3777 }
3778
3779 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3780 struct peer *peer, struct attr *attr,
3781 struct bgp_dest *dest)
3782 {
3783 struct bgp_path_info *new;
3784
3785 /* Make new BGP info. */
3786 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3787 new->type = type;
3788 new->instance = instance;
3789 new->sub_type = sub_type;
3790 new->peer = peer;
3791 new->attr = attr;
3792 new->uptime = monotime(NULL);
3793 new->net = dest;
3794 return new;
3795 }
3796
3797 /* Check if received nexthop is valid or not. */
3798 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3799 uint8_t type, uint8_t stype, struct attr *attr,
3800 struct bgp_dest *dest)
3801 {
3802 bool ret = false;
3803 bool is_bgp_static_route =
3804 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3805 : false;
3806
3807 /*
3808 * Only validated for unicast and multicast currently.
3809 * Also valid for EVPN where the nexthop is an IP address.
3810 * If we are a bgp static route being checked then there is
3811 * no need to check to see if the nexthop is martian as
3812 * that it should be ok.
3813 */
3814 if (is_bgp_static_route ||
3815 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3816 return false;
3817
3818 /* If NEXT_HOP is present, validate it. */
3819 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3820 if (attr->nexthop.s_addr == INADDR_ANY ||
3821 !ipv4_unicast_valid(&attr->nexthop) ||
3822 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3823 return true;
3824 }
3825
3826 /* If MP_NEXTHOP is present, validate it. */
3827 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3828 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3829 * it is not an IPv6 link-local address.
3830 *
3831 * If we receive an UPDATE with nexthop length set to 32 bytes
3832 * we shouldn't discard an UPDATE if it's set to (::).
3833 * The link-local (2st) is validated along the code path later.
3834 */
3835 if (attr->mp_nexthop_len) {
3836 switch (attr->mp_nexthop_len) {
3837 case BGP_ATTR_NHLEN_IPV4:
3838 case BGP_ATTR_NHLEN_VPNV4:
3839 ret = (attr->mp_nexthop_global_in.s_addr ==
3840 INADDR_ANY ||
3841 !ipv4_unicast_valid(
3842 &attr->mp_nexthop_global_in) ||
3843 bgp_nexthop_self(bgp, afi, type, stype, attr,
3844 dest));
3845 break;
3846
3847 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3848 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3849 ret = (IN6_IS_ADDR_UNSPECIFIED(
3850 &attr->mp_nexthop_global)
3851 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3852 || IN6_IS_ADDR_MULTICAST(
3853 &attr->mp_nexthop_global)
3854 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3855 dest));
3856 break;
3857 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3858 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3859 || IN6_IS_ADDR_MULTICAST(
3860 &attr->mp_nexthop_global)
3861 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3862 dest));
3863 break;
3864
3865 default:
3866 ret = true;
3867 break;
3868 }
3869 }
3870
3871 return ret;
3872 }
3873
3874 static void bgp_attr_add_no_export_community(struct attr *attr)
3875 {
3876 struct community *old;
3877 struct community *new;
3878 struct community *merge;
3879 struct community *no_export;
3880
3881 old = bgp_attr_get_community(attr);
3882 no_export = community_str2com("no-export");
3883
3884 assert(no_export);
3885
3886 if (old) {
3887 merge = community_merge(community_dup(old), no_export);
3888
3889 if (!old->refcnt)
3890 community_free(&old);
3891
3892 new = community_uniq_sort(merge);
3893 community_free(&merge);
3894 } else {
3895 new = community_dup(no_export);
3896 }
3897
3898 community_free(&no_export);
3899
3900 bgp_attr_set_community(attr, new);
3901 }
3902
3903 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3904 struct attr *attr, const struct prefix *prefix,
3905 int *sub_type)
3906 {
3907 struct listnode *node, *nnode;
3908 struct bgp *bgp;
3909 bool accept_own_found = false;
3910
3911 if (safi != SAFI_MPLS_VPN)
3912 return false;
3913
3914 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3915 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3916 return false;
3917
3918 /* The route in question carries the ACCEPT_OWN community */
3919 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3920 struct community *comm = bgp_attr_get_community(attr);
3921
3922 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3923 accept_own_found = true;
3924 }
3925
3926 /* The route in question is targeted to one or more destination VRFs
3927 * on the router (as determined by inspecting the Route Target(s)).
3928 */
3929 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3930 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3931 continue;
3932
3933 if (accept_own_found &&
3934 ecommunity_include(
3935 bgp->vpn_policy[afi]
3936 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3937 bgp_attr_get_ecommunity(attr))) {
3938 if (bgp_debug_update(peer, prefix, NULL, 1))
3939 zlog_debug(
3940 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3941 peer, prefix);
3942
3943 /* Treat this route as imported, because it's leaked
3944 * already from another VRF, and we got an updated
3945 * version from route-reflector with ACCEPT_OWN
3946 * community.
3947 */
3948 *sub_type = BGP_ROUTE_IMPORTED;
3949
3950 return true;
3951 }
3952 }
3953
3954 return false;
3955 }
3956
3957 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3958 struct attr *attr, afi_t afi, safi_t safi, int type,
3959 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3960 uint32_t num_labels, int soft_reconfig,
3961 struct bgp_route_evpn *evpn)
3962 {
3963 int ret;
3964 int aspath_loop_count = 0;
3965 struct bgp_dest *dest;
3966 struct bgp *bgp;
3967 struct attr new_attr;
3968 struct attr *attr_new;
3969 struct bgp_path_info *pi;
3970 struct bgp_path_info *new = NULL;
3971 struct bgp_path_info_extra *extra;
3972 const char *reason;
3973 char pfx_buf[BGP_PRD_PATH_STRLEN];
3974 int connected = 0;
3975 int do_loop_check = 1;
3976 int has_valid_label = 0;
3977 afi_t nh_afi;
3978 bool force_evpn_import = false;
3979 safi_t orig_safi = safi;
3980 bool leak_success = true;
3981 int allowas_in = 0;
3982
3983 if (frrtrace_enabled(frr_bgp, process_update)) {
3984 char pfxprint[PREFIX2STR_BUFFER];
3985
3986 prefix2str(p, pfxprint, sizeof(pfxprint));
3987 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3988 afi, safi, attr);
3989 }
3990
3991 #ifdef ENABLE_BGP_VNC
3992 int vnc_implicit_withdraw = 0;
3993 #endif
3994 int same_attr = 0;
3995 const struct prefix *bgp_nht_param_prefix;
3996
3997 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
3998 if (orig_safi == SAFI_LABELED_UNICAST)
3999 safi = SAFI_UNICAST;
4000
4001 memset(&new_attr, 0, sizeof(new_attr));
4002 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4003 new_attr.label = MPLS_INVALID_LABEL;
4004
4005 bgp = peer->bgp;
4006 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4007 /* TODO: Check to see if we can get rid of "is_valid_label" */
4008 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4009 has_valid_label = (num_labels > 0) ? 1 : 0;
4010 else
4011 has_valid_label = bgp_is_valid_label(label);
4012
4013 if (has_valid_label)
4014 assert(label != NULL);
4015
4016 /* Update overlay index of the attribute */
4017 if (afi == AFI_L2VPN && evpn)
4018 memcpy(&attr->evpn_overlay, evpn,
4019 sizeof(struct bgp_route_evpn));
4020
4021 /* When peer's soft reconfiguration enabled. Record input packet in
4022 Adj-RIBs-In. */
4023 if (!soft_reconfig
4024 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4025 && peer != bgp->peer_self)
4026 bgp_adj_in_set(dest, peer, attr, addpath_id);
4027
4028 /* Update permitted loop count */
4029 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4030 allowas_in = peer->allowas_in[afi][safi];
4031
4032 /* Check previously received route. */
4033 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4034 if (pi->peer == peer && pi->type == type
4035 && pi->sub_type == sub_type
4036 && pi->addpath_rx_id == addpath_id)
4037 break;
4038
4039 /* AS path local-as loop check. */
4040 if (peer->change_local_as) {
4041 if (allowas_in)
4042 aspath_loop_count = allowas_in;
4043 else if (!CHECK_FLAG(peer->flags,
4044 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4045 aspath_loop_count = 1;
4046
4047 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4048 > aspath_loop_count) {
4049 peer->stat_pfx_aspath_loop++;
4050 reason = "as-path contains our own AS;";
4051 goto filtered;
4052 }
4053 }
4054
4055 /* If the peer is configured for "allowas-in origin" and the last ASN in
4056 * the
4057 * as-path is our ASN then we do not need to call aspath_loop_check
4058 */
4059 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4060 if (aspath_get_last_as(attr->aspath) == bgp->as)
4061 do_loop_check = 0;
4062
4063 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4064 bgp_nht_param_prefix = NULL;
4065 else
4066 bgp_nht_param_prefix = p;
4067
4068 /* AS path loop check. */
4069 if (do_loop_check) {
4070 if (aspath_loop_check(attr->aspath, bgp->as) >
4071 peer->allowas_in[afi][safi]) {
4072 peer->stat_pfx_aspath_loop++;
4073 reason = "as-path contains our own AS;";
4074 goto filtered;
4075 }
4076 }
4077
4078 /* If we're a CONFED we need to loop check the CONFED ID too */
4079 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4080 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4081 peer->allowas_in[afi][safi]) {
4082 peer->stat_pfx_aspath_loop++;
4083 reason = "as-path contains our own confed AS;";
4084 goto filtered;
4085 }
4086
4087 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4088 * enabled, then take care of that too.
4089 */
4090 bool accept_own = false;
4091
4092 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4093 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4094 accept_own =
4095 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4096 if (!accept_own) {
4097 peer->stat_pfx_originator_loop++;
4098 reason = "originator is us;";
4099 goto filtered;
4100 }
4101 }
4102
4103 /* Route reflector cluster ID check. */
4104 if (bgp_cluster_filter(peer, attr)) {
4105 peer->stat_pfx_cluster_loop++;
4106 reason = "reflected from the same cluster;";
4107 goto filtered;
4108 }
4109
4110 /* Apply incoming filter. */
4111 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4112 peer->stat_pfx_filter++;
4113 reason = "filter;";
4114 goto filtered;
4115 }
4116
4117 /* RFC 8212 to prevent route leaks.
4118 * This specification intends to improve this situation by requiring the
4119 * explicit configuration of both BGP Import and Export Policies for any
4120 * External BGP (EBGP) session such as customers, peers, or
4121 * confederation boundaries for all enabled address families. Through
4122 * codification of the aforementioned requirement, operators will
4123 * benefit from consistent behavior across different BGP
4124 * implementations.
4125 */
4126 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4127 if (!bgp_inbound_policy_exists(peer,
4128 &peer->filter[afi][safi])) {
4129 reason = "inbound policy missing";
4130 if (monotime_since(&bgp->ebgprequirespolicywarning,
4131 NULL) > FIFTEENMINUTE2USEC ||
4132 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4133 zlog_warn(
4134 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4135 monotime(&bgp->ebgprequirespolicywarning);
4136 }
4137 goto filtered;
4138 }
4139
4140 /* draft-ietf-idr-deprecate-as-set-confed-set
4141 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4142 * Eventually, This document (if approved) updates RFC 4271
4143 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4144 * and obsoletes RFC 6472.
4145 */
4146 if (peer->bgp->reject_as_sets)
4147 if (aspath_check_as_sets(attr->aspath)) {
4148 reason =
4149 "as-path contains AS_SET or AS_CONFED_SET type;";
4150 goto filtered;
4151 }
4152
4153 new_attr = *attr;
4154
4155 /* Apply incoming route-map.
4156 * NB: new_attr may now contain newly allocated values from route-map
4157 * "set"
4158 * commands, so we need bgp_attr_flush in the error paths, until we
4159 * intern
4160 * the attr (which takes over the memory references) */
4161 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4162 num_labels, dest)
4163 == RMAP_DENY) {
4164 peer->stat_pfx_filter++;
4165 reason = "route-map;";
4166 bgp_attr_flush(&new_attr);
4167 goto filtered;
4168 }
4169
4170 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4171 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4172 /* remove from RIB previous entry */
4173 bgp_zebra_withdraw(p, pi, bgp, safi);
4174 }
4175
4176 if (peer->sort == BGP_PEER_EBGP) {
4177
4178 /* rfc7999:
4179 * A BGP speaker receiving an announcement tagged with the
4180 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4181 * NO_EXPORT community as defined in RFC1997, or a
4182 * similar community, to prevent propagation of the
4183 * prefix outside the local AS. The community to prevent
4184 * propagation SHOULD be chosen according to the operator's
4185 * routing policy.
4186 */
4187 if (bgp_attr_get_community(&new_attr) &&
4188 community_include(bgp_attr_get_community(&new_attr),
4189 COMMUNITY_BLACKHOLE))
4190 bgp_attr_add_no_export_community(&new_attr);
4191
4192 /* If we receive the graceful-shutdown community from an eBGP
4193 * peer we must lower local-preference */
4194 if (bgp_attr_get_community(&new_attr) &&
4195 community_include(bgp_attr_get_community(&new_attr),
4196 COMMUNITY_GSHUT)) {
4197 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4198 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4199
4200 /* If graceful-shutdown is configured globally or
4201 * per neighbor, then add the GSHUT community to
4202 * all paths received from eBGP peers. */
4203 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4204 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4205 bgp_attr_add_gshut_community(&new_attr);
4206 }
4207
4208 /* next hop check. */
4209 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4210 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4211 &new_attr, dest)) {
4212 peer->stat_pfx_nh_invalid++;
4213 reason = "martian or self next-hop;";
4214 bgp_attr_flush(&new_attr);
4215 goto filtered;
4216 }
4217
4218 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4219 peer->stat_pfx_nh_invalid++;
4220 reason = "self mac;";
4221 bgp_attr_flush(&new_attr);
4222 goto filtered;
4223 }
4224
4225 if (bgp_check_role_applicability(afi, safi) &&
4226 bgp_otc_filter(peer, &new_attr)) {
4227 reason = "failing otc validation";
4228 bgp_attr_flush(&new_attr);
4229 goto filtered;
4230 }
4231 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
4232 * condition :
4233 * Suppress fib is enabled
4234 * BGP_OPT_NO_FIB is not enabled
4235 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
4236 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
4237 */
4238 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
4239 && (sub_type == BGP_ROUTE_NORMAL)
4240 && (!bgp_option_check(BGP_OPT_NO_FIB))
4241 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
4242 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
4243
4244 /* If neighbor soo is configured, tag all incoming routes with
4245 * this SoO tag and then filter out advertisements in
4246 * subgroup_announce_check() if it matches the configured SoO
4247 * on the other peer.
4248 */
4249 if (peer->soo[afi][safi]) {
4250 struct ecommunity *old_ecomm =
4251 bgp_attr_get_ecommunity(&new_attr);
4252 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4253 struct ecommunity *new_ecomm;
4254
4255 if (old_ecomm) {
4256 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4257 ecomm_soo);
4258
4259 if (!old_ecomm->refcnt)
4260 ecommunity_free(&old_ecomm);
4261 } else {
4262 new_ecomm = ecommunity_dup(ecomm_soo);
4263 }
4264
4265 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4266 }
4267
4268 attr_new = bgp_attr_intern(&new_attr);
4269
4270 /* If the update is implicit withdraw. */
4271 if (pi) {
4272 pi->uptime = monotime(NULL);
4273 same_attr = attrhash_cmp(pi->attr, attr_new);
4274
4275 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4276
4277 /* Same attribute comes in. */
4278 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4279 && same_attr
4280 && (!has_valid_label
4281 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4282 num_labels * sizeof(mpls_label_t))
4283 == 0)) {
4284 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4285 BGP_CONFIG_DAMPENING)
4286 && peer->sort == BGP_PEER_EBGP
4287 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4288 if (bgp_debug_update(peer, p, NULL, 1)) {
4289 bgp_debug_rdpfxpath2str(
4290 afi, safi, prd, p, label,
4291 num_labels, addpath_id ? 1 : 0,
4292 addpath_id, evpn, pfx_buf,
4293 sizeof(pfx_buf));
4294 zlog_debug("%pBP rcvd %s", peer,
4295 pfx_buf);
4296 }
4297
4298 if (bgp_damp_update(pi, dest, afi, safi)
4299 != BGP_DAMP_SUPPRESSED) {
4300 bgp_aggregate_increment(bgp, p, pi, afi,
4301 safi);
4302 bgp_process(bgp, dest, afi, safi);
4303 }
4304 } else /* Duplicate - odd */
4305 {
4306 if (bgp_debug_update(peer, p, NULL, 1)) {
4307 if (!peer->rcvd_attr_printed) {
4308 zlog_debug(
4309 "%pBP rcvd UPDATE w/ attr: %s",
4310 peer,
4311 peer->rcvd_attr_str);
4312 peer->rcvd_attr_printed = 1;
4313 }
4314
4315 bgp_debug_rdpfxpath2str(
4316 afi, safi, prd, p, label,
4317 num_labels, addpath_id ? 1 : 0,
4318 addpath_id, evpn, pfx_buf,
4319 sizeof(pfx_buf));
4320 zlog_debug(
4321 "%pBP rcvd %s...duplicate ignored",
4322 peer, pfx_buf);
4323 }
4324
4325 /* graceful restart STALE flag unset. */
4326 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4327 bgp_path_info_unset_flag(
4328 dest, pi, BGP_PATH_STALE);
4329 bgp_dest_set_defer_flag(dest, false);
4330 bgp_process(bgp, dest, afi, safi);
4331 }
4332 }
4333
4334 bgp_dest_unlock_node(dest);
4335 bgp_attr_unintern(&attr_new);
4336
4337 return;
4338 }
4339
4340 /* Withdraw/Announce before we fully processed the withdraw */
4341 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4342 if (bgp_debug_update(peer, p, NULL, 1)) {
4343 bgp_debug_rdpfxpath2str(
4344 afi, safi, prd, p, label, num_labels,
4345 addpath_id ? 1 : 0, addpath_id, evpn,
4346 pfx_buf, sizeof(pfx_buf));
4347 zlog_debug(
4348 "%pBP rcvd %s, flapped quicker than processing",
4349 peer, pfx_buf);
4350 }
4351
4352 bgp_path_info_restore(dest, pi);
4353
4354 /*
4355 * If the BGP_PATH_REMOVED flag is set, then EVPN
4356 * routes would have been unimported already when a
4357 * prior BGP withdraw processing happened. Such routes
4358 * need to be imported again, so flag accordingly.
4359 */
4360 force_evpn_import = true;
4361 } else {
4362 /* implicit withdraw, decrement aggregate and pcount
4363 * here. only if update is accepted, they'll increment
4364 * below.
4365 */
4366 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4367 }
4368
4369 /* Received Logging. */
4370 if (bgp_debug_update(peer, p, NULL, 1)) {
4371 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4372 num_labels, addpath_id ? 1 : 0,
4373 addpath_id, evpn, pfx_buf,
4374 sizeof(pfx_buf));
4375 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4376 }
4377
4378 /* graceful restart STALE flag unset. */
4379 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4380 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4381 bgp_dest_set_defer_flag(dest, false);
4382 }
4383
4384 /* The attribute is changed. */
4385 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4386
4387 /* Update bgp route dampening information. */
4388 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4389 && peer->sort == BGP_PEER_EBGP) {
4390 /* This is implicit withdraw so we should update
4391 dampening
4392 information. */
4393 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4394 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4395 }
4396 #ifdef ENABLE_BGP_VNC
4397 if (safi == SAFI_MPLS_VPN) {
4398 struct bgp_dest *pdest = NULL;
4399 struct bgp_table *table = NULL;
4400
4401 pdest = bgp_node_get(bgp->rib[afi][safi],
4402 (struct prefix *)prd);
4403 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4404 table = bgp_dest_get_bgp_table_info(pdest);
4405
4406 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4407 bgp, prd, table, p, pi);
4408 }
4409 bgp_dest_unlock_node(pdest);
4410 }
4411 if ((afi == AFI_IP || afi == AFI_IP6)
4412 && (safi == SAFI_UNICAST)) {
4413 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4414 /*
4415 * Implicit withdraw case.
4416 */
4417 ++vnc_implicit_withdraw;
4418 vnc_import_bgp_del_route(bgp, p, pi);
4419 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4420 }
4421 }
4422 #endif
4423
4424 /* Special handling for EVPN update of an existing route. If the
4425 * extended community attribute has changed, we need to
4426 * un-import
4427 * the route using its existing extended community. It will be
4428 * subsequently processed for import with the new extended
4429 * community.
4430 */
4431 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4432 && !same_attr) {
4433 if ((pi->attr->flag
4434 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4435 && (attr_new->flag
4436 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4437 int cmp;
4438
4439 cmp = ecommunity_cmp(
4440 bgp_attr_get_ecommunity(pi->attr),
4441 bgp_attr_get_ecommunity(attr_new));
4442 if (!cmp) {
4443 if (bgp_debug_update(peer, p, NULL, 1))
4444 zlog_debug(
4445 "Change in EXT-COMM, existing %s new %s",
4446 ecommunity_str(
4447 bgp_attr_get_ecommunity(
4448 pi->attr)),
4449 ecommunity_str(
4450 bgp_attr_get_ecommunity(
4451 attr_new)));
4452 if (safi == SAFI_EVPN)
4453 bgp_evpn_unimport_route(
4454 bgp, afi, safi, p, pi);
4455 else /* SAFI_MPLS_VPN */
4456 vpn_leak_to_vrf_withdraw(pi);
4457 }
4458 }
4459 }
4460
4461 /* Update to new attribute. */
4462 bgp_attr_unintern(&pi->attr);
4463 pi->attr = attr_new;
4464
4465 /* Update MPLS label */
4466 if (has_valid_label) {
4467 extra = bgp_path_info_extra_get(pi);
4468 if (extra->label != label) {
4469 memcpy(&extra->label, label,
4470 num_labels * sizeof(mpls_label_t));
4471 extra->num_labels = num_labels;
4472 }
4473 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4474 bgp_set_valid_label(&extra->label[0]);
4475 }
4476
4477 /* Update SRv6 SID */
4478 if (attr->srv6_l3vpn) {
4479 extra = bgp_path_info_extra_get(pi);
4480 if (sid_diff(&extra->sid[0].sid,
4481 &attr->srv6_l3vpn->sid)) {
4482 sid_copy(&extra->sid[0].sid,
4483 &attr->srv6_l3vpn->sid);
4484 extra->num_sids = 1;
4485
4486 extra->sid[0].loc_block_len = 0;
4487 extra->sid[0].loc_node_len = 0;
4488 extra->sid[0].func_len = 0;
4489 extra->sid[0].arg_len = 0;
4490 extra->sid[0].transposition_len = 0;
4491 extra->sid[0].transposition_offset = 0;
4492
4493 if (attr->srv6_l3vpn->loc_block_len != 0) {
4494 extra->sid[0].loc_block_len =
4495 attr->srv6_l3vpn->loc_block_len;
4496 extra->sid[0].loc_node_len =
4497 attr->srv6_l3vpn->loc_node_len;
4498 extra->sid[0].func_len =
4499 attr->srv6_l3vpn->func_len;
4500 extra->sid[0].arg_len =
4501 attr->srv6_l3vpn->arg_len;
4502 extra->sid[0].transposition_len =
4503 attr->srv6_l3vpn
4504 ->transposition_len;
4505 extra->sid[0].transposition_offset =
4506 attr->srv6_l3vpn
4507 ->transposition_offset;
4508 }
4509 }
4510 } else if (attr->srv6_vpn) {
4511 extra = bgp_path_info_extra_get(pi);
4512 if (sid_diff(&extra->sid[0].sid,
4513 &attr->srv6_vpn->sid)) {
4514 sid_copy(&extra->sid[0].sid,
4515 &attr->srv6_vpn->sid);
4516 extra->num_sids = 1;
4517 }
4518 }
4519
4520 #ifdef ENABLE_BGP_VNC
4521 if ((afi == AFI_IP || afi == AFI_IP6)
4522 && (safi == SAFI_UNICAST)) {
4523 if (vnc_implicit_withdraw) {
4524 /*
4525 * Add back the route with its new attributes
4526 * (e.g., nexthop).
4527 * The route is still selected, until the route
4528 * selection
4529 * queued by bgp_process actually runs. We have
4530 * to make this
4531 * update to the VNC side immediately to avoid
4532 * racing against
4533 * configuration changes (e.g., route-map
4534 * changes) which
4535 * trigger re-importation of the entire RIB.
4536 */
4537 vnc_import_bgp_add_route(bgp, p, pi);
4538 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4539 }
4540 }
4541 #endif
4542
4543 /* Update bgp route dampening information. */
4544 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4545 && peer->sort == BGP_PEER_EBGP) {
4546 /* Now we do normal update dampening. */
4547 ret = bgp_damp_update(pi, dest, afi, safi);
4548 if (ret == BGP_DAMP_SUPPRESSED) {
4549 bgp_dest_unlock_node(dest);
4550 return;
4551 }
4552 }
4553
4554 /* Nexthop reachability check - for unicast and
4555 * labeled-unicast.. */
4556 if (((afi == AFI_IP || afi == AFI_IP6)
4557 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4558 || (safi == SAFI_EVPN &&
4559 bgp_evpn_is_prefix_nht_supported(p))) {
4560 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4561 && peer->ttl == BGP_DEFAULT_TTL
4562 && !CHECK_FLAG(peer->flags,
4563 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4564 && !CHECK_FLAG(bgp->flags,
4565 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4566 connected = 1;
4567 else
4568 connected = 0;
4569
4570 struct bgp *bgp_nexthop = bgp;
4571
4572 if (pi->extra && pi->extra->bgp_orig)
4573 bgp_nexthop = pi->extra->bgp_orig;
4574
4575 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4576
4577 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4578 safi, pi, NULL, connected,
4579 bgp_nht_param_prefix) ||
4580 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4581 bgp_path_info_set_flag(dest, pi,
4582 BGP_PATH_VALID);
4583 else {
4584 if (BGP_DEBUG(nht, NHT)) {
4585 zlog_debug("%s(%pI4): NH unresolved",
4586 __func__,
4587 (in_addr_t *)&attr_new->nexthop);
4588 }
4589 bgp_path_info_unset_flag(dest, pi,
4590 BGP_PATH_VALID);
4591 }
4592 } else {
4593 if (accept_own)
4594 bgp_path_info_set_flag(dest, pi,
4595 BGP_PATH_ACCEPT_OWN);
4596
4597 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4598 }
4599
4600 #ifdef ENABLE_BGP_VNC
4601 if (safi == SAFI_MPLS_VPN) {
4602 struct bgp_dest *pdest = NULL;
4603 struct bgp_table *table = NULL;
4604
4605 pdest = bgp_node_get(bgp->rib[afi][safi],
4606 (struct prefix *)prd);
4607 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4608 table = bgp_dest_get_bgp_table_info(pdest);
4609
4610 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4611 bgp, prd, table, p, pi);
4612 }
4613 bgp_dest_unlock_node(pdest);
4614 }
4615 #endif
4616
4617 /* If this is an EVPN route and some attribute has changed,
4618 * or we are explicitly told to perform a route import, process
4619 * route for import. If the extended community has changed, we
4620 * would
4621 * have done the un-import earlier and the import would result
4622 * in the
4623 * route getting injected into appropriate L2 VNIs. If it is
4624 * just
4625 * some other attribute change, the import will result in
4626 * updating
4627 * the attributes for the route in the VNI(s).
4628 */
4629 if (safi == SAFI_EVPN &&
4630 (!same_attr || force_evpn_import) &&
4631 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4632 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4633
4634 /* Process change. */
4635 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4636
4637 bgp_process(bgp, dest, afi, safi);
4638 bgp_dest_unlock_node(dest);
4639
4640 if (SAFI_UNICAST == safi
4641 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4642 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4643
4644 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4645 }
4646 if ((SAFI_MPLS_VPN == safi)
4647 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4648 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4649 }
4650
4651 #ifdef ENABLE_BGP_VNC
4652 if (SAFI_MPLS_VPN == safi) {
4653 mpls_label_t label_decoded = decode_label(label);
4654
4655 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4656 type, sub_type, &label_decoded);
4657 }
4658 if (SAFI_ENCAP == safi) {
4659 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4660 type, sub_type, NULL);
4661 }
4662 #endif
4663 if ((safi == SAFI_MPLS_VPN) &&
4664 !CHECK_FLAG(bgp->af_flags[afi][safi],
4665 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4666 !leak_success) {
4667 bgp_unlink_nexthop(pi);
4668 bgp_path_info_delete(dest, pi);
4669 }
4670 return;
4671 } // End of implicit withdraw
4672
4673 /* Received Logging. */
4674 if (bgp_debug_update(peer, p, NULL, 1)) {
4675 if (!peer->rcvd_attr_printed) {
4676 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4677 peer->rcvd_attr_str);
4678 peer->rcvd_attr_printed = 1;
4679 }
4680
4681 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4682 addpath_id ? 1 : 0, addpath_id, evpn,
4683 pfx_buf, sizeof(pfx_buf));
4684 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4685 }
4686
4687 /* Make new BGP info. */
4688 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4689
4690 /* Update MPLS label */
4691 if (has_valid_label) {
4692 extra = bgp_path_info_extra_get(new);
4693 if (extra->label != label) {
4694 memcpy(&extra->label, label,
4695 num_labels * sizeof(mpls_label_t));
4696 extra->num_labels = num_labels;
4697 }
4698 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4699 bgp_set_valid_label(&extra->label[0]);
4700 }
4701
4702 /* Update SRv6 SID */
4703 if (safi == SAFI_MPLS_VPN) {
4704 extra = bgp_path_info_extra_get(new);
4705 if (attr->srv6_l3vpn) {
4706 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4707 extra->num_sids = 1;
4708
4709 extra->sid[0].loc_block_len =
4710 attr->srv6_l3vpn->loc_block_len;
4711 extra->sid[0].loc_node_len =
4712 attr->srv6_l3vpn->loc_node_len;
4713 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4714 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4715 extra->sid[0].transposition_len =
4716 attr->srv6_l3vpn->transposition_len;
4717 extra->sid[0].transposition_offset =
4718 attr->srv6_l3vpn->transposition_offset;
4719 } else if (attr->srv6_vpn) {
4720 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4721 extra->num_sids = 1;
4722 }
4723 }
4724
4725 /* Nexthop reachability check. */
4726 if (((afi == AFI_IP || afi == AFI_IP6)
4727 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4728 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4729 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4730 && peer->ttl == BGP_DEFAULT_TTL
4731 && !CHECK_FLAG(peer->flags,
4732 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4733 && !CHECK_FLAG(bgp->flags,
4734 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4735 connected = 1;
4736 else
4737 connected = 0;
4738
4739 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4740
4741 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4742 connected, bgp_nht_param_prefix) ||
4743 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4744 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4745 else {
4746 if (BGP_DEBUG(nht, NHT))
4747 zlog_debug("%s(%pI4): NH unresolved", __func__,
4748 &attr_new->nexthop);
4749 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4750 }
4751 } else {
4752 if (accept_own)
4753 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4754
4755 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4756 }
4757
4758 /* If maximum prefix count is configured and current prefix
4759 * count exeed it.
4760 */
4761 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4762 reason = "maximum-prefix overflow";
4763 bgp_attr_flush(&new_attr);
4764 goto filtered;
4765 }
4766
4767 /* Addpath ID */
4768 new->addpath_rx_id = addpath_id;
4769
4770 /* Increment prefix */
4771 bgp_aggregate_increment(bgp, p, new, afi, safi);
4772
4773 /* Register new BGP information. */
4774 bgp_path_info_add(dest, new);
4775
4776 /* route_node_get lock */
4777 bgp_dest_unlock_node(dest);
4778
4779 #ifdef ENABLE_BGP_VNC
4780 if (safi == SAFI_MPLS_VPN) {
4781 struct bgp_dest *pdest = NULL;
4782 struct bgp_table *table = NULL;
4783
4784 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4785 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4786 table = bgp_dest_get_bgp_table_info(pdest);
4787
4788 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4789 bgp, prd, table, p, new);
4790 }
4791 bgp_dest_unlock_node(pdest);
4792 }
4793 #endif
4794
4795 /* If this is an EVPN route, process for import. */
4796 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4797 bgp_evpn_import_route(bgp, afi, safi, p, new);
4798
4799 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4800
4801 /* Process change. */
4802 bgp_process(bgp, dest, afi, safi);
4803
4804 if (SAFI_UNICAST == safi
4805 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4806 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4807 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4808 }
4809 if ((SAFI_MPLS_VPN == safi)
4810 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4811 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4812 }
4813 #ifdef ENABLE_BGP_VNC
4814 if (SAFI_MPLS_VPN == safi) {
4815 mpls_label_t label_decoded = decode_label(label);
4816
4817 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4818 sub_type, &label_decoded);
4819 }
4820 if (SAFI_ENCAP == safi) {
4821 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4822 sub_type, NULL);
4823 }
4824 #endif
4825 if ((safi == SAFI_MPLS_VPN) &&
4826 !CHECK_FLAG(bgp->af_flags[afi][safi],
4827 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4828 !leak_success) {
4829 bgp_unlink_nexthop(new);
4830 bgp_path_info_delete(dest, new);
4831 }
4832
4833 return;
4834
4835 /* This BGP update is filtered. Log the reason then update BGP
4836 entry. */
4837 filtered:
4838 if (new) {
4839 bgp_unlink_nexthop(new);
4840 bgp_path_info_delete(dest, new);
4841 bgp_path_info_extra_free(&new->extra);
4842 XFREE(MTYPE_BGP_ROUTE, new);
4843 }
4844
4845 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4846
4847 if (bgp_debug_update(peer, p, NULL, 1)) {
4848 if (!peer->rcvd_attr_printed) {
4849 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4850 peer->rcvd_attr_str);
4851 peer->rcvd_attr_printed = 1;
4852 }
4853
4854 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4855 addpath_id ? 1 : 0, addpath_id, evpn,
4856 pfx_buf, sizeof(pfx_buf));
4857 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4858 peer, pfx_buf, reason);
4859 }
4860
4861 if (pi) {
4862 /* If this is an EVPN route, un-import it as it is now filtered.
4863 */
4864 if (safi == SAFI_EVPN)
4865 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4866
4867 if (SAFI_UNICAST == safi
4868 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4869 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4870
4871 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4872 }
4873 if ((SAFI_MPLS_VPN == safi)
4874 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4875
4876 vpn_leak_to_vrf_withdraw(pi);
4877 }
4878
4879 bgp_rib_remove(dest, pi, peer, afi, safi);
4880 }
4881
4882 bgp_dest_unlock_node(dest);
4883
4884 #ifdef ENABLE_BGP_VNC
4885 /*
4886 * Filtered update is treated as an implicit withdrawal (see
4887 * bgp_rib_remove()
4888 * a few lines above)
4889 */
4890 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4891 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4892 0);
4893 }
4894 #endif
4895
4896 return;
4897 }
4898
4899 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4900 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4901 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4902 uint32_t num_labels, struct bgp_route_evpn *evpn)
4903 {
4904 struct bgp *bgp;
4905 char pfx_buf[BGP_PRD_PATH_STRLEN];
4906 struct bgp_dest *dest;
4907 struct bgp_path_info *pi;
4908
4909 #ifdef ENABLE_BGP_VNC
4910 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4911 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4912 0);
4913 }
4914 #endif
4915
4916 bgp = peer->bgp;
4917
4918 /* Lookup node. */
4919 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4920
4921 /* If peer is soft reconfiguration enabled. Record input packet for
4922 * further calculation.
4923 *
4924 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4925 * routes that are filtered. This tanks out Quagga RS pretty badly due
4926 * to
4927 * the iteration over all RS clients.
4928 * Since we need to remove the entry from adj_in anyway, do that first
4929 * and
4930 * if there was no entry, we don't need to do anything more.
4931 */
4932 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4933 && peer != bgp->peer_self)
4934 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4935 peer->stat_pfx_dup_withdraw++;
4936
4937 if (bgp_debug_update(peer, p, NULL, 1)) {
4938 bgp_debug_rdpfxpath2str(
4939 afi, safi, prd, p, label, num_labels,
4940 addpath_id ? 1 : 0, addpath_id, NULL,
4941 pfx_buf, sizeof(pfx_buf));
4942 zlog_debug(
4943 "%s withdrawing route %s not in adj-in",
4944 peer->host, pfx_buf);
4945 }
4946 bgp_dest_unlock_node(dest);
4947 return;
4948 }
4949
4950 /* Lookup withdrawn route. */
4951 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4952 if (pi->peer == peer && pi->type == type
4953 && pi->sub_type == sub_type
4954 && pi->addpath_rx_id == addpath_id)
4955 break;
4956
4957 /* Logging. */
4958 if (bgp_debug_update(peer, p, NULL, 1)) {
4959 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4960 addpath_id ? 1 : 0, addpath_id, NULL,
4961 pfx_buf, sizeof(pfx_buf));
4962 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4963 pfx_buf);
4964 }
4965
4966 /* Withdraw specified route from routing table. */
4967 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4968 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4969 if (SAFI_UNICAST == safi
4970 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4971 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4972 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4973 }
4974 if ((SAFI_MPLS_VPN == safi)
4975 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4976
4977 vpn_leak_to_vrf_withdraw(pi);
4978 }
4979 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4980 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4981 addpath_id ? 1 : 0, addpath_id, NULL,
4982 pfx_buf, sizeof(pfx_buf));
4983 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4984 }
4985
4986 /* Unlock bgp_node_get() lock. */
4987 bgp_dest_unlock_node(dest);
4988
4989 return;
4990 }
4991
4992 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4993 int withdraw)
4994 {
4995 struct update_subgroup *subgrp;
4996 subgrp = peer_subgroup(peer, afi, safi);
4997 subgroup_default_originate(subgrp, withdraw);
4998 }
4999
5000
5001 /*
5002 * bgp_stop_announce_route_timer
5003 */
5004 void bgp_stop_announce_route_timer(struct peer_af *paf)
5005 {
5006 if (!paf->t_announce_route)
5007 return;
5008
5009 THREAD_OFF(paf->t_announce_route);
5010 }
5011
5012 /*
5013 * bgp_announce_route_timer_expired
5014 *
5015 * Callback that is invoked when the route announcement timer for a
5016 * peer_af expires.
5017 */
5018 static void bgp_announce_route_timer_expired(struct thread *t)
5019 {
5020 struct peer_af *paf;
5021 struct peer *peer;
5022
5023 paf = THREAD_ARG(t);
5024 peer = paf->peer;
5025
5026 if (!peer_established(peer))
5027 return;
5028
5029 if (!peer->afc_nego[paf->afi][paf->safi])
5030 return;
5031
5032 peer_af_announce_route(paf, 1);
5033
5034 /* Notify BGP conditional advertisement scanner percess */
5035 peer->advmap_config_change[paf->afi][paf->safi] = true;
5036 }
5037
5038 /*
5039 * bgp_announce_route
5040 *
5041 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5042 *
5043 * if force is true we will force an update even if the update
5044 * limiting code is attempted to kick in.
5045 */
5046 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5047 {
5048 struct peer_af *paf;
5049 struct update_subgroup *subgrp;
5050
5051 paf = peer_af_find(peer, afi, safi);
5052 if (!paf)
5053 return;
5054 subgrp = PAF_SUBGRP(paf);
5055
5056 /*
5057 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5058 * or a refresh has already been triggered.
5059 */
5060 if (!subgrp || paf->t_announce_route)
5061 return;
5062
5063 if (force)
5064 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5065
5066 /*
5067 * Start a timer to stagger/delay the announce. This serves
5068 * two purposes - announcement can potentially be combined for
5069 * multiple peers and the announcement doesn't happen in the
5070 * vty context.
5071 */
5072 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5073 (subgrp->peer_count == 1)
5074 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5075 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5076 &paf->t_announce_route);
5077 }
5078
5079 /*
5080 * Announce routes from all AF tables to a peer.
5081 *
5082 * This should ONLY be called when there is a need to refresh the
5083 * routes to the peer based on a policy change for this peer alone
5084 * or a route refresh request received from the peer.
5085 * The operation will result in splitting the peer from its existing
5086 * subgroups and putting it in new subgroups.
5087 */
5088 void bgp_announce_route_all(struct peer *peer)
5089 {
5090 afi_t afi;
5091 safi_t safi;
5092
5093 FOREACH_AFI_SAFI (afi, safi)
5094 bgp_announce_route(peer, afi, safi, false);
5095 }
5096
5097 /* Flag or unflag bgp_dest to determine whether it should be treated by
5098 * bgp_soft_reconfig_table_task.
5099 * Flag if flag is true. Unflag if flag is false.
5100 */
5101 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5102 {
5103 struct bgp_dest *dest;
5104 struct bgp_adj_in *ain;
5105
5106 if (!table)
5107 return;
5108
5109 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5110 for (ain = dest->adj_in; ain; ain = ain->next) {
5111 if (ain->peer != NULL)
5112 break;
5113 }
5114 if (flag && ain != NULL && ain->peer != NULL)
5115 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5116 else
5117 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5118 }
5119 }
5120
5121 static void bgp_soft_reconfig_table_update(struct peer *peer,
5122 struct bgp_dest *dest,
5123 struct bgp_adj_in *ain, afi_t afi,
5124 safi_t safi, struct prefix_rd *prd)
5125 {
5126 struct bgp_path_info *pi;
5127 uint32_t num_labels = 0;
5128 mpls_label_t *label_pnt = NULL;
5129 struct bgp_route_evpn evpn;
5130
5131 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5132 if (pi->peer == peer)
5133 break;
5134
5135 if (pi && pi->extra)
5136 num_labels = pi->extra->num_labels;
5137 if (num_labels)
5138 label_pnt = &pi->extra->label[0];
5139 if (pi)
5140 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5141 sizeof(evpn));
5142 else
5143 memset(&evpn, 0, sizeof(evpn));
5144
5145 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5146 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5147 label_pnt, num_labels, 1, &evpn);
5148 }
5149
5150 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5151 struct bgp_table *table,
5152 struct prefix_rd *prd)
5153 {
5154 struct bgp_dest *dest;
5155 struct bgp_adj_in *ain;
5156
5157 if (!table)
5158 table = peer->bgp->rib[afi][safi];
5159
5160 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5161 for (ain = dest->adj_in; ain; ain = ain->next) {
5162 if (ain->peer != peer)
5163 continue;
5164
5165 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5166 safi, prd);
5167 }
5168 }
5169
5170 /* Do soft reconfig table per bgp table.
5171 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5172 * when BGP_NODE_SOFT_RECONFIG is set,
5173 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5174 * Schedule a new thread to continue the job.
5175 * Without splitting the full job into several part,
5176 * vtysh waits for the job to finish before responding to a BGP command
5177 */
5178 static void bgp_soft_reconfig_table_task(struct thread *thread)
5179 {
5180 uint32_t iter, max_iter;
5181 struct bgp_dest *dest;
5182 struct bgp_adj_in *ain;
5183 struct peer *peer;
5184 struct bgp_table *table;
5185 struct prefix_rd *prd;
5186 struct listnode *node, *nnode;
5187
5188 table = THREAD_ARG(thread);
5189 prd = NULL;
5190
5191 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5192 if (table->soft_reconfig_init) {
5193 /* first call of the function with a new srta structure.
5194 * Don't do any treatment this time on nodes
5195 * in order vtysh to respond quickly
5196 */
5197 max_iter = 0;
5198 }
5199
5200 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5201 dest = bgp_route_next(dest)) {
5202 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5203 continue;
5204
5205 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5206
5207 for (ain = dest->adj_in; ain; ain = ain->next) {
5208 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5209 nnode, peer)) {
5210 if (ain->peer != peer)
5211 continue;
5212
5213 bgp_soft_reconfig_table_update(
5214 peer, dest, ain, table->afi,
5215 table->safi, prd);
5216 iter++;
5217 }
5218 }
5219 }
5220
5221 /* we're either starting the initial iteration,
5222 * or we're going to continue an ongoing iteration
5223 */
5224 if (dest || table->soft_reconfig_init) {
5225 table->soft_reconfig_init = false;
5226 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
5227 table, 0, &table->soft_reconfig_thread);
5228 return;
5229 }
5230 /* we're done, clean up the background iteration context info and
5231 schedule route annoucement
5232 */
5233 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5234 listnode_delete(table->soft_reconfig_peers, peer);
5235 bgp_announce_route(peer, table->afi, table->safi, false);
5236 }
5237
5238 list_delete(&table->soft_reconfig_peers);
5239 }
5240
5241
5242 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5243 * and peer.
5244 * - bgp cannot be NULL
5245 * - if table and peer are NULL, cancel all threads within the bgp instance
5246 * - if table is NULL and peer is not,
5247 * remove peer in all threads within the bgp instance
5248 * - if peer is NULL, cancel all threads matching table within the bgp instance
5249 */
5250 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5251 const struct bgp_table *table,
5252 const struct peer *peer)
5253 {
5254 struct peer *npeer;
5255 struct listnode *node, *nnode;
5256 int afi, safi;
5257 struct bgp_table *ntable;
5258
5259 if (!bgp)
5260 return;
5261
5262 FOREACH_AFI_SAFI (afi, safi) {
5263 ntable = bgp->rib[afi][safi];
5264 if (!ntable)
5265 continue;
5266 if (table && table != ntable)
5267 continue;
5268
5269 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5270 npeer)) {
5271 if (peer && peer != npeer)
5272 continue;
5273 listnode_delete(ntable->soft_reconfig_peers, npeer);
5274 }
5275
5276 if (!ntable->soft_reconfig_peers
5277 || !list_isempty(ntable->soft_reconfig_peers))
5278 continue;
5279
5280 list_delete(&ntable->soft_reconfig_peers);
5281 bgp_soft_reconfig_table_flag(ntable, false);
5282 THREAD_OFF(ntable->soft_reconfig_thread);
5283 }
5284 }
5285
5286 /*
5287 * Returns false if the peer is not configured for soft reconfig in
5288 */
5289 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5290 {
5291 struct bgp_dest *dest;
5292 struct bgp_table *table;
5293 struct listnode *node, *nnode;
5294 struct peer *npeer;
5295 struct peer_af *paf;
5296
5297 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5298 return false;
5299
5300 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5301 && (safi != SAFI_EVPN)) {
5302 table = peer->bgp->rib[afi][safi];
5303 if (!table)
5304 return true;
5305
5306 table->soft_reconfig_init = true;
5307
5308 if (!table->soft_reconfig_peers)
5309 table->soft_reconfig_peers = list_new();
5310 npeer = NULL;
5311 /* add peer to the table soft_reconfig_peers if not already
5312 * there
5313 */
5314 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5315 npeer)) {
5316 if (peer == npeer)
5317 break;
5318 }
5319 if (peer != npeer)
5320 listnode_add(table->soft_reconfig_peers, peer);
5321
5322 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5323 * on table would start back at the beginning.
5324 */
5325 bgp_soft_reconfig_table_flag(table, true);
5326
5327 if (!table->soft_reconfig_thread)
5328 thread_add_event(bm->master,
5329 bgp_soft_reconfig_table_task, table, 0,
5330 &table->soft_reconfig_thread);
5331 /* Cancel bgp_announce_route_timer_expired threads.
5332 * bgp_announce_route_timer_expired threads have been scheduled
5333 * to announce routes as soon as the soft_reconfigure process
5334 * finishes.
5335 * In this case, soft_reconfigure is also scheduled by using
5336 * a thread but is planned after the
5337 * bgp_announce_route_timer_expired threads. It means that,
5338 * without cancelling the threads, the route announcement task
5339 * would run before the soft reconfiguration one. That would
5340 * useless and would block vtysh during several seconds. Route
5341 * announcements are rescheduled as soon as the soft_reconfigure
5342 * process finishes.
5343 */
5344 paf = peer_af_find(peer, afi, safi);
5345 if (paf)
5346 bgp_stop_announce_route_timer(paf);
5347 } else
5348 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5349 dest = bgp_route_next(dest)) {
5350 table = bgp_dest_get_bgp_table_info(dest);
5351
5352 if (table == NULL)
5353 continue;
5354
5355 const struct prefix *p = bgp_dest_get_prefix(dest);
5356 struct prefix_rd prd;
5357
5358 prd.family = AF_UNSPEC;
5359 prd.prefixlen = 64;
5360 memcpy(&prd.val, p->u.val, 8);
5361
5362 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5363 }
5364
5365 return true;
5366 }
5367
5368
5369 struct bgp_clear_node_queue {
5370 struct bgp_dest *dest;
5371 };
5372
5373 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5374 {
5375 struct bgp_clear_node_queue *cnq = data;
5376 struct bgp_dest *dest = cnq->dest;
5377 struct peer *peer = wq->spec.data;
5378 struct bgp_path_info *pi;
5379 struct bgp *bgp;
5380 afi_t afi = bgp_dest_table(dest)->afi;
5381 safi_t safi = bgp_dest_table(dest)->safi;
5382
5383 assert(dest && peer);
5384 bgp = peer->bgp;
5385
5386 /* It is possible that we have multiple paths for a prefix from a peer
5387 * if that peer is using AddPath.
5388 */
5389 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5390 if (pi->peer != peer)
5391 continue;
5392
5393 /* graceful restart STALE flag set. */
5394 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5395 && peer->nsf[afi][safi])
5396 || CHECK_FLAG(peer->af_sflags[afi][safi],
5397 PEER_STATUS_ENHANCED_REFRESH))
5398 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5399 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5400 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5401 else {
5402 /* If this is an EVPN route, process for
5403 * un-import. */
5404 if (safi == SAFI_EVPN)
5405 bgp_evpn_unimport_route(
5406 bgp, afi, safi,
5407 bgp_dest_get_prefix(dest), pi);
5408 /* Handle withdraw for VRF route-leaking and L3VPN */
5409 if (SAFI_UNICAST == safi
5410 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5411 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5412 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5413 bgp, pi);
5414 }
5415 if (SAFI_MPLS_VPN == safi &&
5416 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5417 vpn_leak_to_vrf_withdraw(pi);
5418 }
5419
5420 bgp_rib_remove(dest, pi, peer, afi, safi);
5421 }
5422 }
5423 return WQ_SUCCESS;
5424 }
5425
5426 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5427 {
5428 struct bgp_clear_node_queue *cnq = data;
5429 struct bgp_dest *dest = cnq->dest;
5430 struct bgp_table *table = bgp_dest_table(dest);
5431
5432 bgp_dest_unlock_node(dest);
5433 bgp_table_unlock(table);
5434 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5435 }
5436
5437 static void bgp_clear_node_complete(struct work_queue *wq)
5438 {
5439 struct peer *peer = wq->spec.data;
5440
5441 /* Tickle FSM to start moving again */
5442 BGP_EVENT_ADD(peer, Clearing_Completed);
5443
5444 peer_unlock(peer); /* bgp_clear_route */
5445 }
5446
5447 static void bgp_clear_node_queue_init(struct peer *peer)
5448 {
5449 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5450
5451 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5452 #undef CLEAR_QUEUE_NAME_LEN
5453
5454 peer->clear_node_queue = work_queue_new(bm->master, wname);
5455 peer->clear_node_queue->spec.hold = 10;
5456 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5457 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5458 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5459 peer->clear_node_queue->spec.max_retries = 0;
5460
5461 /* we only 'lock' this peer reference when the queue is actually active
5462 */
5463 peer->clear_node_queue->spec.data = peer;
5464 }
5465
5466 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5467 struct bgp_table *table)
5468 {
5469 struct bgp_dest *dest;
5470 int force = peer->bgp->process_queue ? 0 : 1;
5471
5472 if (!table)
5473 table = peer->bgp->rib[afi][safi];
5474
5475 /* If still no table => afi/safi isn't configured at all or smth. */
5476 if (!table)
5477 return;
5478
5479 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5480 struct bgp_path_info *pi, *next;
5481 struct bgp_adj_in *ain;
5482 struct bgp_adj_in *ain_next;
5483
5484 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5485 * queued for every clearing peer, regardless of whether it is
5486 * relevant to the peer at hand.
5487 *
5488 * Overview: There are 3 different indices which need to be
5489 * scrubbed, potentially, when a peer is removed:
5490 *
5491 * 1 peer's routes visible via the RIB (ie accepted routes)
5492 * 2 peer's routes visible by the (optional) peer's adj-in index
5493 * 3 other routes visible by the peer's adj-out index
5494 *
5495 * 3 there is no hurry in scrubbing, once the struct peer is
5496 * removed from bgp->peer, we could just GC such deleted peer's
5497 * adj-outs at our leisure.
5498 *
5499 * 1 and 2 must be 'scrubbed' in some way, at least made
5500 * invisible via RIB index before peer session is allowed to be
5501 * brought back up. So one needs to know when such a 'search' is
5502 * complete.
5503 *
5504 * Ideally:
5505 *
5506 * - there'd be a single global queue or a single RIB walker
5507 * - rather than tracking which route_nodes still need to be
5508 * examined on a peer basis, we'd track which peers still
5509 * aren't cleared
5510 *
5511 * Given that our per-peer prefix-counts now should be reliable,
5512 * this may actually be achievable. It doesn't seem to be a huge
5513 * problem at this time,
5514 *
5515 * It is possible that we have multiple paths for a prefix from
5516 * a peer
5517 * if that peer is using AddPath.
5518 */
5519 ain = dest->adj_in;
5520 while (ain) {
5521 ain_next = ain->next;
5522
5523 if (ain->peer == peer)
5524 bgp_adj_in_remove(dest, ain);
5525
5526 ain = ain_next;
5527 }
5528
5529 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5530 next = pi->next;
5531 if (pi->peer != peer)
5532 continue;
5533
5534 if (force)
5535 bgp_path_info_reap(dest, pi);
5536 else {
5537 struct bgp_clear_node_queue *cnq;
5538
5539 /* both unlocked in bgp_clear_node_queue_del */
5540 bgp_table_lock(bgp_dest_table(dest));
5541 bgp_dest_lock_node(dest);
5542 cnq = XCALLOC(
5543 MTYPE_BGP_CLEAR_NODE_QUEUE,
5544 sizeof(struct bgp_clear_node_queue));
5545 cnq->dest = dest;
5546 work_queue_add(peer->clear_node_queue, cnq);
5547 break;
5548 }
5549 }
5550 }
5551 return;
5552 }
5553
5554 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5555 {
5556 struct bgp_dest *dest;
5557 struct bgp_table *table;
5558
5559 if (peer->clear_node_queue == NULL)
5560 bgp_clear_node_queue_init(peer);
5561
5562 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5563 * Idle until it receives a Clearing_Completed event. This protects
5564 * against peers which flap faster than we can we clear, which could
5565 * lead to:
5566 *
5567 * a) race with routes from the new session being installed before
5568 * clear_route_node visits the node (to delete the route of that
5569 * peer)
5570 * b) resource exhaustion, clear_route_node likely leads to an entry
5571 * on the process_main queue. Fast-flapping could cause that queue
5572 * to grow and grow.
5573 */
5574
5575 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5576 * the unlock will happen upon work-queue completion; other wise, the
5577 * unlock happens at the end of this function.
5578 */
5579 if (!peer->clear_node_queue->thread)
5580 peer_lock(peer);
5581
5582 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5583 bgp_clear_route_table(peer, afi, safi, NULL);
5584 else
5585 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5586 dest = bgp_route_next(dest)) {
5587 table = bgp_dest_get_bgp_table_info(dest);
5588 if (!table)
5589 continue;
5590
5591 bgp_clear_route_table(peer, afi, safi, table);
5592 }
5593
5594 /* unlock if no nodes got added to the clear-node-queue. */
5595 if (!peer->clear_node_queue->thread)
5596 peer_unlock(peer);
5597 }
5598
5599 void bgp_clear_route_all(struct peer *peer)
5600 {
5601 afi_t afi;
5602 safi_t safi;
5603
5604 FOREACH_AFI_SAFI (afi, safi)
5605 bgp_clear_route(peer, afi, safi);
5606
5607 #ifdef ENABLE_BGP_VNC
5608 rfapiProcessPeerDown(peer);
5609 #endif
5610 }
5611
5612 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5613 {
5614 struct bgp_table *table;
5615 struct bgp_dest *dest;
5616 struct bgp_adj_in *ain;
5617 struct bgp_adj_in *ain_next;
5618
5619 table = peer->bgp->rib[afi][safi];
5620
5621 /* It is possible that we have multiple paths for a prefix from a peer
5622 * if that peer is using AddPath.
5623 */
5624 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5625 ain = dest->adj_in;
5626
5627 while (ain) {
5628 ain_next = ain->next;
5629
5630 if (ain->peer == peer)
5631 bgp_adj_in_remove(dest, ain);
5632
5633 ain = ain_next;
5634 }
5635 }
5636 }
5637
5638 /* If any of the routes from the peer have been marked with the NO_LLGR
5639 * community, either as sent by the peer, or as the result of a configured
5640 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5641 * operation of [RFC4271].
5642 */
5643 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5644 {
5645 struct bgp_dest *dest;
5646 struct bgp_path_info *pi;
5647 struct bgp_table *table;
5648
5649 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5650 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5651 dest = bgp_route_next(dest)) {
5652 struct bgp_dest *rm;
5653
5654 /* look for neighbor in tables */
5655 table = bgp_dest_get_bgp_table_info(dest);
5656 if (!table)
5657 continue;
5658
5659 for (rm = bgp_table_top(table); rm;
5660 rm = bgp_route_next(rm))
5661 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5662 pi = pi->next) {
5663 if (pi->peer != peer)
5664 continue;
5665 if (CHECK_FLAG(
5666 peer->af_sflags[afi][safi],
5667 PEER_STATUS_LLGR_WAIT) &&
5668 bgp_attr_get_community(pi->attr) &&
5669 !community_include(
5670 bgp_attr_get_community(
5671 pi->attr),
5672 COMMUNITY_NO_LLGR))
5673 continue;
5674 if (!CHECK_FLAG(pi->flags,
5675 BGP_PATH_STALE))
5676 continue;
5677
5678 /*
5679 * If this is VRF leaked route
5680 * process for withdraw.
5681 */
5682 if (pi->sub_type ==
5683 BGP_ROUTE_IMPORTED &&
5684 peer->bgp->inst_type ==
5685 BGP_INSTANCE_TYPE_DEFAULT)
5686 vpn_leak_to_vrf_withdraw(pi);
5687
5688 bgp_rib_remove(rm, pi, peer, afi, safi);
5689 break;
5690 }
5691 }
5692 } else {
5693 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5694 dest = bgp_route_next(dest))
5695 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5696 pi = pi->next) {
5697 if (pi->peer != peer)
5698 continue;
5699 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5700 PEER_STATUS_LLGR_WAIT) &&
5701 bgp_attr_get_community(pi->attr) &&
5702 !community_include(
5703 bgp_attr_get_community(pi->attr),
5704 COMMUNITY_NO_LLGR))
5705 continue;
5706 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5707 continue;
5708 if (safi == SAFI_UNICAST &&
5709 (peer->bgp->inst_type ==
5710 BGP_INSTANCE_TYPE_VRF ||
5711 peer->bgp->inst_type ==
5712 BGP_INSTANCE_TYPE_DEFAULT))
5713 vpn_leak_from_vrf_withdraw(
5714 bgp_get_default(), peer->bgp,
5715 pi);
5716
5717 bgp_rib_remove(dest, pi, peer, afi, safi);
5718 break;
5719 }
5720 }
5721 }
5722
5723 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5724 {
5725 struct bgp_dest *dest, *ndest;
5726 struct bgp_path_info *pi;
5727 struct bgp_table *table;
5728
5729 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5730 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5731 dest = bgp_route_next(dest)) {
5732 table = bgp_dest_get_bgp_table_info(dest);
5733 if (!table)
5734 continue;
5735
5736 for (ndest = bgp_table_top(table); ndest;
5737 ndest = bgp_route_next(ndest)) {
5738 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5739 pi = pi->next) {
5740 if (pi->peer != peer)
5741 continue;
5742
5743 if ((CHECK_FLAG(
5744 peer->af_sflags[afi][safi],
5745 PEER_STATUS_ENHANCED_REFRESH))
5746 && !CHECK_FLAG(pi->flags,
5747 BGP_PATH_STALE)
5748 && !CHECK_FLAG(
5749 pi->flags,
5750 BGP_PATH_UNUSEABLE)) {
5751 if (bgp_debug_neighbor_events(
5752 peer))
5753 zlog_debug(
5754 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5755 peer,
5756 afi2str(afi),
5757 safi2str(safi),
5758 bgp_dest_get_prefix(
5759 ndest));
5760
5761 bgp_path_info_set_flag(
5762 ndest, pi,
5763 BGP_PATH_STALE);
5764 }
5765 }
5766 }
5767 }
5768 } else {
5769 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5770 dest = bgp_route_next(dest)) {
5771 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5772 pi = pi->next) {
5773 if (pi->peer != peer)
5774 continue;
5775
5776 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5777 PEER_STATUS_ENHANCED_REFRESH))
5778 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5779 && !CHECK_FLAG(pi->flags,
5780 BGP_PATH_UNUSEABLE)) {
5781 if (bgp_debug_neighbor_events(peer))
5782 zlog_debug(
5783 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5784 peer, afi2str(afi),
5785 safi2str(safi),
5786 bgp_dest_get_prefix(
5787 dest));
5788
5789 bgp_path_info_set_flag(dest, pi,
5790 BGP_PATH_STALE);
5791 }
5792 }
5793 }
5794 }
5795 }
5796
5797 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5798 {
5799 if (peer->sort == BGP_PEER_IBGP)
5800 return true;
5801
5802 if (peer->sort == BGP_PEER_EBGP
5803 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5804 || FILTER_LIST_OUT_NAME(filter)
5805 || DISTRIBUTE_OUT_NAME(filter)))
5806 return true;
5807 return false;
5808 }
5809
5810 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5811 {
5812 if (peer->sort == BGP_PEER_IBGP)
5813 return true;
5814
5815 if (peer->sort == BGP_PEER_EBGP
5816 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5817 || FILTER_LIST_IN_NAME(filter)
5818 || DISTRIBUTE_IN_NAME(filter)))
5819 return true;
5820 return false;
5821 }
5822
5823 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5824 safi_t safi)
5825 {
5826 struct bgp_dest *dest;
5827 struct bgp_path_info *pi;
5828 struct bgp_path_info *next;
5829
5830 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5831 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5832 const struct prefix *p = bgp_dest_get_prefix(dest);
5833
5834 next = pi->next;
5835
5836 /* Unimport EVPN routes from VRFs */
5837 if (safi == SAFI_EVPN)
5838 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5839 SAFI_EVPN, p, pi);
5840
5841 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5842 && pi->type == ZEBRA_ROUTE_BGP
5843 && (pi->sub_type == BGP_ROUTE_NORMAL
5844 || pi->sub_type == BGP_ROUTE_AGGREGATE
5845 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5846
5847 if (bgp_fibupd_safi(safi))
5848 bgp_zebra_withdraw(p, pi, bgp, safi);
5849 }
5850
5851 bgp_path_info_reap(dest, pi);
5852 }
5853 }
5854
5855 /* Delete all kernel routes. */
5856 void bgp_cleanup_routes(struct bgp *bgp)
5857 {
5858 afi_t afi;
5859 struct bgp_dest *dest;
5860 struct bgp_table *table;
5861
5862 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5863 if (afi == AFI_L2VPN)
5864 continue;
5865 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5866 SAFI_UNICAST);
5867 /*
5868 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5869 */
5870 if (afi != AFI_L2VPN) {
5871 safi_t safi;
5872 safi = SAFI_MPLS_VPN;
5873 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5874 dest = bgp_route_next(dest)) {
5875 table = bgp_dest_get_bgp_table_info(dest);
5876 if (table != NULL) {
5877 bgp_cleanup_table(bgp, table, safi);
5878 bgp_table_finish(&table);
5879 bgp_dest_set_bgp_table_info(dest, NULL);
5880 bgp_dest_unlock_node(dest);
5881 }
5882 }
5883 safi = SAFI_ENCAP;
5884 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5885 dest = bgp_route_next(dest)) {
5886 table = bgp_dest_get_bgp_table_info(dest);
5887 if (table != NULL) {
5888 bgp_cleanup_table(bgp, table, safi);
5889 bgp_table_finish(&table);
5890 bgp_dest_set_bgp_table_info(dest, NULL);
5891 bgp_dest_unlock_node(dest);
5892 }
5893 }
5894 }
5895 }
5896 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5897 dest = bgp_route_next(dest)) {
5898 table = bgp_dest_get_bgp_table_info(dest);
5899 if (table != NULL) {
5900 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5901 bgp_table_finish(&table);
5902 bgp_dest_set_bgp_table_info(dest, NULL);
5903 bgp_dest_unlock_node(dest);
5904 }
5905 }
5906 }
5907
5908 void bgp_reset(void)
5909 {
5910 vty_reset();
5911 bgp_zclient_reset();
5912 access_list_reset();
5913 prefix_list_reset();
5914 }
5915
5916 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5917 {
5918 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5919 && CHECK_FLAG(peer->af_cap[afi][safi],
5920 PEER_CAP_ADDPATH_AF_TX_RCV));
5921 }
5922
5923 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5924 value. */
5925 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5926 struct bgp_nlri *packet)
5927 {
5928 uint8_t *pnt;
5929 uint8_t *lim;
5930 struct prefix p;
5931 int psize;
5932 afi_t afi;
5933 safi_t safi;
5934 bool addpath_capable;
5935 uint32_t addpath_id;
5936
5937 pnt = packet->nlri;
5938 lim = pnt + packet->length;
5939 afi = packet->afi;
5940 safi = packet->safi;
5941 addpath_id = 0;
5942 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5943
5944 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5945 syntactic validity. If the field is syntactically incorrect,
5946 then the Error Subcode is set to Invalid Network Field. */
5947 for (; pnt < lim; pnt += psize) {
5948 /* Clear prefix structure. */
5949 memset(&p, 0, sizeof(p));
5950
5951 if (addpath_capable) {
5952
5953 /* When packet overflow occurs return immediately. */
5954 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5955 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5956
5957 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5958 addpath_id = ntohl(addpath_id);
5959 pnt += BGP_ADDPATH_ID_LEN;
5960 }
5961
5962 /* Fetch prefix length. */
5963 p.prefixlen = *pnt++;
5964 /* afi/safi validity already verified by caller,
5965 * bgp_update_receive */
5966 p.family = afi2family(afi);
5967
5968 /* Prefix length check. */
5969 if (p.prefixlen > prefix_blen(&p) * 8) {
5970 flog_err(
5971 EC_BGP_UPDATE_RCV,
5972 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5973 peer->host, p.prefixlen, packet->afi);
5974 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5975 }
5976
5977 /* Packet size overflow check. */
5978 psize = PSIZE(p.prefixlen);
5979
5980 /* When packet overflow occur return immediately. */
5981 if (pnt + psize > lim) {
5982 flog_err(
5983 EC_BGP_UPDATE_RCV,
5984 "%s [Error] Update packet error (prefix length %d overflows packet)",
5985 peer->host, p.prefixlen);
5986 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5987 }
5988
5989 /* Defensive coding, double-check the psize fits in a struct
5990 * prefix for the v4 and v6 afi's and unicast/multicast */
5991 if (psize > (ssize_t)sizeof(p.u.val)) {
5992 flog_err(
5993 EC_BGP_UPDATE_RCV,
5994 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5995 peer->host, p.prefixlen, sizeof(p.u.val));
5996 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5997 }
5998
5999 /* Fetch prefix from NLRI packet. */
6000 memcpy(p.u.val, pnt, psize);
6001
6002 /* Check address. */
6003 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6004 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6005 /* From RFC4271 Section 6.3:
6006 *
6007 * If a prefix in the NLRI field is semantically
6008 * incorrect
6009 * (e.g., an unexpected multicast IP address),
6010 * an error SHOULD
6011 * be logged locally, and the prefix SHOULD be
6012 * ignored.
6013 */
6014 flog_err(
6015 EC_BGP_UPDATE_RCV,
6016 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6017 peer->host, &p.u.prefix4);
6018 continue;
6019 }
6020 }
6021
6022 /* Check address. */
6023 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6024 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6025 flog_err(
6026 EC_BGP_UPDATE_RCV,
6027 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6028 peer->host, &p.u.prefix6);
6029
6030 continue;
6031 }
6032 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6033 flog_err(
6034 EC_BGP_UPDATE_RCV,
6035 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6036 peer->host, &p.u.prefix6);
6037
6038 continue;
6039 }
6040 }
6041
6042 /* Normal process. */
6043 if (attr)
6044 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6045 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6046 NULL, 0, 0, NULL);
6047 else
6048 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6049 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6050 NULL, 0, NULL);
6051
6052 /* Do not send BGP notification twice when maximum-prefix count
6053 * overflow. */
6054 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6055 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6056 }
6057
6058 /* Packet length consistency check. */
6059 if (pnt != lim) {
6060 flog_err(
6061 EC_BGP_UPDATE_RCV,
6062 "%s [Error] Update packet error (prefix length mismatch with total length)",
6063 peer->host);
6064 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6065 }
6066
6067 return BGP_NLRI_PARSE_OK;
6068 }
6069
6070 static struct bgp_static *bgp_static_new(void)
6071 {
6072 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6073 }
6074
6075 static void bgp_static_free(struct bgp_static *bgp_static)
6076 {
6077 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6078 route_map_counter_decrement(bgp_static->rmap.map);
6079
6080 if (bgp_static->prd_pretty)
6081 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6082 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6083 XFREE(MTYPE_BGP_STATIC, bgp_static);
6084 }
6085
6086 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6087 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6088 {
6089 struct bgp_dest *dest;
6090 struct bgp_path_info *pi;
6091 struct bgp_path_info *new;
6092 struct bgp_path_info rmap_path;
6093 struct attr attr;
6094 struct attr *attr_new;
6095 route_map_result_t ret;
6096 #ifdef ENABLE_BGP_VNC
6097 int vnc_implicit_withdraw = 0;
6098 #endif
6099
6100 assert(bgp_static);
6101
6102 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6103
6104 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6105
6106 attr.nexthop = bgp_static->igpnexthop;
6107 attr.med = bgp_static->igpmetric;
6108 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6109
6110 if (afi == AFI_IP)
6111 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6112
6113 if (bgp_static->igpmetric)
6114 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6115
6116 if (bgp_static->atomic)
6117 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6118
6119 /* Store label index, if required. */
6120 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6121 attr.label_index = bgp_static->label_index;
6122 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6123 }
6124
6125 /* Apply route-map. */
6126 if (bgp_static->rmap.name) {
6127 struct attr attr_tmp = attr;
6128
6129 memset(&rmap_path, 0, sizeof(rmap_path));
6130 rmap_path.peer = bgp->peer_self;
6131 rmap_path.attr = &attr_tmp;
6132
6133 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6134
6135 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6136
6137 bgp->peer_self->rmap_type = 0;
6138
6139 if (ret == RMAP_DENYMATCH) {
6140 /* Free uninterned attribute. */
6141 bgp_attr_flush(&attr_tmp);
6142
6143 /* Unintern original. */
6144 aspath_unintern(&attr.aspath);
6145 bgp_static_withdraw(bgp, p, afi, safi);
6146 bgp_dest_unlock_node(dest);
6147 return;
6148 }
6149
6150 if (bgp_in_graceful_shutdown(bgp))
6151 bgp_attr_add_gshut_community(&attr_tmp);
6152
6153 attr_new = bgp_attr_intern(&attr_tmp);
6154 } else {
6155
6156 if (bgp_in_graceful_shutdown(bgp))
6157 bgp_attr_add_gshut_community(&attr);
6158
6159 attr_new = bgp_attr_intern(&attr);
6160 }
6161
6162 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6163 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6164 && pi->sub_type == BGP_ROUTE_STATIC)
6165 break;
6166
6167 if (pi) {
6168 if (attrhash_cmp(pi->attr, attr_new)
6169 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6170 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6171 bgp_dest_unlock_node(dest);
6172 bgp_attr_unintern(&attr_new);
6173 aspath_unintern(&attr.aspath);
6174 return;
6175 } else {
6176 /* The attribute is changed. */
6177 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6178
6179 /* Rewrite BGP route information. */
6180 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6181 bgp_path_info_restore(dest, pi);
6182 else
6183 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6184 #ifdef ENABLE_BGP_VNC
6185 if ((afi == AFI_IP || afi == AFI_IP6)
6186 && (safi == SAFI_UNICAST)) {
6187 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6188 /*
6189 * Implicit withdraw case.
6190 * We have to do this before pi is
6191 * changed
6192 */
6193 ++vnc_implicit_withdraw;
6194 vnc_import_bgp_del_route(bgp, p, pi);
6195 vnc_import_bgp_exterior_del_route(
6196 bgp, p, pi);
6197 }
6198 }
6199 #endif
6200 bgp_attr_unintern(&pi->attr);
6201 pi->attr = attr_new;
6202 pi->uptime = monotime(NULL);
6203 #ifdef ENABLE_BGP_VNC
6204 if ((afi == AFI_IP || afi == AFI_IP6)
6205 && (safi == SAFI_UNICAST)) {
6206 if (vnc_implicit_withdraw) {
6207 vnc_import_bgp_add_route(bgp, p, pi);
6208 vnc_import_bgp_exterior_add_route(
6209 bgp, p, pi);
6210 }
6211 }
6212 #endif
6213
6214 /* Nexthop reachability check. */
6215 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6216 && (safi == SAFI_UNICAST
6217 || safi == SAFI_LABELED_UNICAST)) {
6218
6219 struct bgp *bgp_nexthop = bgp;
6220
6221 if (pi->extra && pi->extra->bgp_orig)
6222 bgp_nexthop = pi->extra->bgp_orig;
6223
6224 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6225 afi, safi, pi, NULL,
6226 0, p))
6227 bgp_path_info_set_flag(dest, pi,
6228 BGP_PATH_VALID);
6229 else {
6230 if (BGP_DEBUG(nht, NHT)) {
6231 char buf1[INET6_ADDRSTRLEN];
6232 inet_ntop(p->family,
6233 &p->u.prefix, buf1,
6234 sizeof(buf1));
6235 zlog_debug(
6236 "%s(%s): Route not in table, not advertising",
6237 __func__, buf1);
6238 }
6239 bgp_path_info_unset_flag(
6240 dest, pi, BGP_PATH_VALID);
6241 }
6242 } else {
6243 /* Delete the NHT structure if any, if we're
6244 * toggling between
6245 * enabling/disabling import check. We
6246 * deregister the route
6247 * from NHT to avoid overloading NHT and the
6248 * process interaction
6249 */
6250 bgp_unlink_nexthop(pi);
6251 bgp_path_info_set_flag(dest, pi,
6252 BGP_PATH_VALID);
6253 }
6254 /* Process change. */
6255 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6256 bgp_process(bgp, dest, afi, safi);
6257
6258 if (SAFI_UNICAST == safi
6259 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6260 || bgp->inst_type
6261 == BGP_INSTANCE_TYPE_DEFAULT)) {
6262 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6263 pi);
6264 }
6265
6266 bgp_dest_unlock_node(dest);
6267 aspath_unintern(&attr.aspath);
6268 return;
6269 }
6270 }
6271
6272 /* Make new BGP info. */
6273 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6274 attr_new, dest);
6275 /* Nexthop reachability check. */
6276 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6277 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6278 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6279 p))
6280 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6281 else {
6282 if (BGP_DEBUG(nht, NHT)) {
6283 char buf1[INET6_ADDRSTRLEN];
6284
6285 inet_ntop(p->family, &p->u.prefix, buf1,
6286 sizeof(buf1));
6287 zlog_debug(
6288 "%s(%s): Route not in table, not advertising",
6289 __func__, buf1);
6290 }
6291 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6292 }
6293 } else {
6294 /* Delete the NHT structure if any, if we're toggling between
6295 * enabling/disabling import check. We deregister the route
6296 * from NHT to avoid overloading NHT and the process interaction
6297 */
6298 bgp_unlink_nexthop(new);
6299
6300 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6301 }
6302
6303 /* Aggregate address increment. */
6304 bgp_aggregate_increment(bgp, p, new, afi, safi);
6305
6306 /* Register new BGP information. */
6307 bgp_path_info_add(dest, new);
6308
6309 /* route_node_get lock */
6310 bgp_dest_unlock_node(dest);
6311
6312 /* Process change. */
6313 bgp_process(bgp, dest, afi, safi);
6314
6315 if (SAFI_UNICAST == safi
6316 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6317 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6318 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6319 }
6320
6321 /* Unintern original. */
6322 aspath_unintern(&attr.aspath);
6323 }
6324
6325 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6326 safi_t safi)
6327 {
6328 struct bgp_dest *dest;
6329 struct bgp_path_info *pi;
6330
6331 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6332
6333 /* Check selected route and self inserted route. */
6334 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6335 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6336 && pi->sub_type == BGP_ROUTE_STATIC)
6337 break;
6338
6339 /* Withdraw static BGP route from routing table. */
6340 if (pi) {
6341 if (SAFI_UNICAST == safi
6342 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6343 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6344 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6345 }
6346 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6347 bgp_unlink_nexthop(pi);
6348 bgp_path_info_delete(dest, pi);
6349 bgp_process(bgp, dest, afi, safi);
6350 }
6351
6352 /* Unlock bgp_node_lookup. */
6353 bgp_dest_unlock_node(dest);
6354 }
6355
6356 /*
6357 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6358 */
6359 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6360 afi_t afi, safi_t safi,
6361 struct prefix_rd *prd)
6362 {
6363 struct bgp_dest *dest;
6364 struct bgp_path_info *pi;
6365
6366 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6367
6368 /* Check selected route and self inserted route. */
6369 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6370 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6371 && pi->sub_type == BGP_ROUTE_STATIC)
6372 break;
6373
6374 /* Withdraw static BGP route from routing table. */
6375 if (pi) {
6376 #ifdef ENABLE_BGP_VNC
6377 rfapiProcessWithdraw(
6378 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6379 1); /* Kill, since it is an administrative change */
6380 #endif
6381 if (SAFI_MPLS_VPN == safi
6382 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6383 vpn_leak_to_vrf_withdraw(pi);
6384 }
6385 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6386 bgp_path_info_delete(dest, pi);
6387 bgp_process(bgp, dest, afi, safi);
6388 }
6389
6390 /* Unlock bgp_node_lookup. */
6391 bgp_dest_unlock_node(dest);
6392 }
6393
6394 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6395 struct bgp_static *bgp_static, afi_t afi,
6396 safi_t safi)
6397 {
6398 struct bgp_dest *dest;
6399 struct bgp_path_info *new;
6400 struct attr *attr_new;
6401 struct attr attr = {0};
6402 struct bgp_path_info *pi;
6403 #ifdef ENABLE_BGP_VNC
6404 mpls_label_t label = 0;
6405 #endif
6406 uint32_t num_labels = 0;
6407
6408 assert(bgp_static);
6409
6410 if (bgp_static->label != MPLS_INVALID_LABEL)
6411 num_labels = 1;
6412 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6413 &bgp_static->prd);
6414
6415 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6416
6417 attr.nexthop = bgp_static->igpnexthop;
6418 attr.med = bgp_static->igpmetric;
6419 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6420
6421 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6422 || (safi == SAFI_ENCAP)) {
6423 if (afi == AFI_IP) {
6424 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6425 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6426 }
6427 }
6428 if (afi == AFI_L2VPN) {
6429 if (bgp_static->gatewayIp.family == AF_INET) {
6430 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6431 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6432 &bgp_static->gatewayIp.u.prefix4,
6433 IPV4_MAX_BYTELEN);
6434 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6435 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6436 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6437 &bgp_static->gatewayIp.u.prefix6,
6438 IPV6_MAX_BYTELEN);
6439 }
6440 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6441 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6442 struct bgp_encap_type_vxlan bet;
6443 memset(&bet, 0, sizeof(bet));
6444 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6445 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6446 }
6447 if (bgp_static->router_mac) {
6448 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6449 }
6450 }
6451 /* Apply route-map. */
6452 if (bgp_static->rmap.name) {
6453 struct attr attr_tmp = attr;
6454 struct bgp_path_info rmap_path;
6455 route_map_result_t ret;
6456
6457 rmap_path.peer = bgp->peer_self;
6458 rmap_path.attr = &attr_tmp;
6459
6460 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6461
6462 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6463
6464 bgp->peer_self->rmap_type = 0;
6465
6466 if (ret == RMAP_DENYMATCH) {
6467 /* Free uninterned attribute. */
6468 bgp_attr_flush(&attr_tmp);
6469
6470 /* Unintern original. */
6471 aspath_unintern(&attr.aspath);
6472 bgp_static_withdraw_safi(bgp, p, afi, safi,
6473 &bgp_static->prd);
6474 bgp_dest_unlock_node(dest);
6475 return;
6476 }
6477
6478 attr_new = bgp_attr_intern(&attr_tmp);
6479 } else {
6480 attr_new = bgp_attr_intern(&attr);
6481 }
6482
6483 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6484 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6485 && pi->sub_type == BGP_ROUTE_STATIC)
6486 break;
6487
6488 if (pi) {
6489 if (attrhash_cmp(pi->attr, attr_new)
6490 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6491 bgp_dest_unlock_node(dest);
6492 bgp_attr_unintern(&attr_new);
6493 aspath_unintern(&attr.aspath);
6494 return;
6495 } else {
6496 /* The attribute is changed. */
6497 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6498
6499 /* Rewrite BGP route information. */
6500 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6501 bgp_path_info_restore(dest, pi);
6502 else
6503 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6504 bgp_attr_unintern(&pi->attr);
6505 pi->attr = attr_new;
6506 pi->uptime = monotime(NULL);
6507 #ifdef ENABLE_BGP_VNC
6508 if (pi->extra)
6509 label = decode_label(&pi->extra->label[0]);
6510 #endif
6511
6512 /* Process change. */
6513 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6514 bgp_process(bgp, dest, afi, safi);
6515
6516 if (SAFI_MPLS_VPN == safi
6517 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6518 vpn_leak_to_vrf_update(bgp, pi,
6519 &bgp_static->prd);
6520 }
6521 #ifdef ENABLE_BGP_VNC
6522 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6523 pi->attr, afi, safi, pi->type,
6524 pi->sub_type, &label);
6525 #endif
6526 bgp_dest_unlock_node(dest);
6527 aspath_unintern(&attr.aspath);
6528 return;
6529 }
6530 }
6531
6532
6533 /* Make new BGP info. */
6534 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6535 attr_new, dest);
6536 SET_FLAG(new->flags, BGP_PATH_VALID);
6537 bgp_path_info_extra_get(new);
6538 if (num_labels) {
6539 new->extra->label[0] = bgp_static->label;
6540 new->extra->num_labels = num_labels;
6541 }
6542 #ifdef ENABLE_BGP_VNC
6543 label = decode_label(&bgp_static->label);
6544 #endif
6545
6546 /* Aggregate address increment. */
6547 bgp_aggregate_increment(bgp, p, new, afi, safi);
6548
6549 /* Register new BGP information. */
6550 bgp_path_info_add(dest, new);
6551 /* route_node_get lock */
6552 bgp_dest_unlock_node(dest);
6553
6554 /* Process change. */
6555 bgp_process(bgp, dest, afi, safi);
6556
6557 if (SAFI_MPLS_VPN == safi
6558 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6559 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6560 }
6561 #ifdef ENABLE_BGP_VNC
6562 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6563 safi, new->type, new->sub_type, &label);
6564 #endif
6565
6566 /* Unintern original. */
6567 aspath_unintern(&attr.aspath);
6568 }
6569
6570 /* Configure static BGP network. When user don't run zebra, static
6571 route should be installed as valid. */
6572 static int bgp_static_set(struct vty *vty, const char *negate,
6573 const char *ip_str, afi_t afi, safi_t safi,
6574 const char *rmap, int backdoor, uint32_t label_index)
6575 {
6576 VTY_DECLVAR_CONTEXT(bgp, bgp);
6577 int ret;
6578 struct prefix p;
6579 struct bgp_static *bgp_static;
6580 struct bgp_dest *dest;
6581 uint8_t need_update = 0;
6582
6583 /* Convert IP prefix string to struct prefix. */
6584 ret = str2prefix(ip_str, &p);
6585 if (!ret) {
6586 vty_out(vty, "%% Malformed prefix\n");
6587 return CMD_WARNING_CONFIG_FAILED;
6588 }
6589 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6590 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6591 return CMD_WARNING_CONFIG_FAILED;
6592 }
6593
6594 apply_mask(&p);
6595
6596 if (negate) {
6597
6598 /* Set BGP static route configuration. */
6599 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6600
6601 if (!dest) {
6602 vty_out(vty, "%% Can't find static route specified\n");
6603 return CMD_WARNING_CONFIG_FAILED;
6604 }
6605
6606 bgp_static = bgp_dest_get_bgp_static_info(dest);
6607
6608 if ((label_index != BGP_INVALID_LABEL_INDEX)
6609 && (label_index != bgp_static->label_index)) {
6610 vty_out(vty,
6611 "%% label-index doesn't match static route\n");
6612 bgp_dest_unlock_node(dest);
6613 return CMD_WARNING_CONFIG_FAILED;
6614 }
6615
6616 if ((rmap && bgp_static->rmap.name)
6617 && strcmp(rmap, bgp_static->rmap.name)) {
6618 vty_out(vty,
6619 "%% route-map name doesn't match static route\n");
6620 bgp_dest_unlock_node(dest);
6621 return CMD_WARNING_CONFIG_FAILED;
6622 }
6623
6624 /* Update BGP RIB. */
6625 if (!bgp_static->backdoor)
6626 bgp_static_withdraw(bgp, &p, afi, safi);
6627
6628 /* Clear configuration. */
6629 bgp_static_free(bgp_static);
6630 bgp_dest_set_bgp_static_info(dest, NULL);
6631 bgp_dest_unlock_node(dest);
6632 bgp_dest_unlock_node(dest);
6633 } else {
6634
6635 /* Set BGP static route configuration. */
6636 dest = bgp_node_get(bgp->route[afi][safi], &p);
6637 bgp_static = bgp_dest_get_bgp_static_info(dest);
6638 if (bgp_static) {
6639 /* Configuration change. */
6640 /* Label index cannot be changed. */
6641 if (bgp_static->label_index != label_index) {
6642 vty_out(vty, "%% cannot change label-index\n");
6643 bgp_dest_unlock_node(dest);
6644 return CMD_WARNING_CONFIG_FAILED;
6645 }
6646
6647 /* Check previous routes are installed into BGP. */
6648 if (bgp_static->valid
6649 && bgp_static->backdoor != backdoor)
6650 need_update = 1;
6651
6652 bgp_static->backdoor = backdoor;
6653
6654 if (rmap) {
6655 XFREE(MTYPE_ROUTE_MAP_NAME,
6656 bgp_static->rmap.name);
6657 route_map_counter_decrement(
6658 bgp_static->rmap.map);
6659 bgp_static->rmap.name =
6660 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6661 bgp_static->rmap.map =
6662 route_map_lookup_by_name(rmap);
6663 route_map_counter_increment(
6664 bgp_static->rmap.map);
6665 } else {
6666 XFREE(MTYPE_ROUTE_MAP_NAME,
6667 bgp_static->rmap.name);
6668 route_map_counter_decrement(
6669 bgp_static->rmap.map);
6670 bgp_static->rmap.map = NULL;
6671 bgp_static->valid = 0;
6672 }
6673 bgp_dest_unlock_node(dest);
6674 } else {
6675 /* New configuration. */
6676 bgp_static = bgp_static_new();
6677 bgp_static->backdoor = backdoor;
6678 bgp_static->valid = 0;
6679 bgp_static->igpmetric = 0;
6680 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6681 bgp_static->label_index = label_index;
6682
6683 if (rmap) {
6684 XFREE(MTYPE_ROUTE_MAP_NAME,
6685 bgp_static->rmap.name);
6686 route_map_counter_decrement(
6687 bgp_static->rmap.map);
6688 bgp_static->rmap.name =
6689 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6690 bgp_static->rmap.map =
6691 route_map_lookup_by_name(rmap);
6692 route_map_counter_increment(
6693 bgp_static->rmap.map);
6694 }
6695 bgp_dest_set_bgp_static_info(dest, bgp_static);
6696 }
6697
6698 bgp_static->valid = 1;
6699 if (need_update)
6700 bgp_static_withdraw(bgp, &p, afi, safi);
6701
6702 if (!bgp_static->backdoor)
6703 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6704 }
6705
6706 return CMD_SUCCESS;
6707 }
6708
6709 void bgp_static_add(struct bgp *bgp)
6710 {
6711 afi_t afi;
6712 safi_t safi;
6713 struct bgp_dest *dest;
6714 struct bgp_dest *rm;
6715 struct bgp_table *table;
6716 struct bgp_static *bgp_static;
6717
6718 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6719 FOREACH_AFI_SAFI (afi, safi)
6720 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6721 dest = bgp_route_next(dest)) {
6722 if (!bgp_dest_has_bgp_path_info_data(dest))
6723 continue;
6724
6725 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6726 || (safi == SAFI_EVPN)) {
6727 table = bgp_dest_get_bgp_table_info(dest);
6728
6729 for (rm = bgp_table_top(table); rm;
6730 rm = bgp_route_next(rm)) {
6731 bgp_static =
6732 bgp_dest_get_bgp_static_info(
6733 rm);
6734 bgp_static_update_safi(
6735 bgp, bgp_dest_get_prefix(rm),
6736 bgp_static, afi, safi);
6737 }
6738 } else {
6739 bgp_static_update(
6740 bgp, bgp_dest_get_prefix(dest),
6741 bgp_dest_get_bgp_static_info(dest), afi,
6742 safi);
6743 }
6744 }
6745 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6746 }
6747
6748 /* Called from bgp_delete(). Delete all static routes from the BGP
6749 instance. */
6750 void bgp_static_delete(struct bgp *bgp)
6751 {
6752 afi_t afi;
6753 safi_t safi;
6754 struct bgp_dest *dest;
6755 struct bgp_dest *rm;
6756 struct bgp_table *table;
6757 struct bgp_static *bgp_static;
6758
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 if (!bgp_static)
6775 continue;
6776
6777 bgp_static_withdraw_safi(
6778 bgp, bgp_dest_get_prefix(rm),
6779 AFI_IP, safi,
6780 (struct prefix_rd *)
6781 bgp_dest_get_prefix(
6782 dest));
6783 bgp_static_free(bgp_static);
6784 bgp_dest_set_bgp_static_info(rm,
6785 NULL);
6786 bgp_dest_unlock_node(rm);
6787 }
6788 } else {
6789 bgp_static = bgp_dest_get_bgp_static_info(dest);
6790 bgp_static_withdraw(bgp,
6791 bgp_dest_get_prefix(dest),
6792 afi, safi);
6793 bgp_static_free(bgp_static);
6794 bgp_dest_set_bgp_static_info(dest, NULL);
6795 bgp_dest_unlock_node(dest);
6796 }
6797 }
6798 }
6799
6800 void bgp_static_redo_import_check(struct bgp *bgp)
6801 {
6802 afi_t afi;
6803 safi_t safi;
6804 struct bgp_dest *dest;
6805 struct bgp_dest *rm;
6806 struct bgp_table *table;
6807 struct bgp_static *bgp_static;
6808
6809 /* Use this flag to force reprocessing of the route */
6810 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6811 FOREACH_AFI_SAFI (afi, safi) {
6812 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6813 dest = bgp_route_next(dest)) {
6814 if (!bgp_dest_has_bgp_path_info_data(dest))
6815 continue;
6816
6817 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6818 || (safi == SAFI_EVPN)) {
6819 table = bgp_dest_get_bgp_table_info(dest);
6820
6821 for (rm = bgp_table_top(table); rm;
6822 rm = bgp_route_next(rm)) {
6823 bgp_static =
6824 bgp_dest_get_bgp_static_info(
6825 rm);
6826 bgp_static_update_safi(
6827 bgp, bgp_dest_get_prefix(rm),
6828 bgp_static, afi, safi);
6829 }
6830 } else {
6831 bgp_static = bgp_dest_get_bgp_static_info(dest);
6832 bgp_static_update(bgp,
6833 bgp_dest_get_prefix(dest),
6834 bgp_static, afi, safi);
6835 }
6836 }
6837 }
6838 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6839 }
6840
6841 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6842 safi_t safi)
6843 {
6844 struct bgp_table *table;
6845 struct bgp_dest *dest;
6846 struct bgp_path_info *pi;
6847
6848 /* Do not install the aggregate route if BGP is in the
6849 * process of termination.
6850 */
6851 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6852 || (bgp->peer_self == NULL))
6853 return;
6854
6855 table = bgp->rib[afi][safi];
6856 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6857 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6858 if (pi->peer == bgp->peer_self
6859 && ((pi->type == ZEBRA_ROUTE_BGP
6860 && pi->sub_type == BGP_ROUTE_STATIC)
6861 || (pi->type != ZEBRA_ROUTE_BGP
6862 && pi->sub_type
6863 == BGP_ROUTE_REDISTRIBUTE))) {
6864 bgp_aggregate_decrement(
6865 bgp, bgp_dest_get_prefix(dest), pi, afi,
6866 safi);
6867 bgp_unlink_nexthop(pi);
6868 bgp_path_info_delete(dest, pi);
6869 bgp_process(bgp, dest, afi, safi);
6870 }
6871 }
6872 }
6873 }
6874
6875 /*
6876 * Purge all networks and redistributed routes from routing table.
6877 * Invoked upon the instance going down.
6878 */
6879 void bgp_purge_static_redist_routes(struct bgp *bgp)
6880 {
6881 afi_t afi;
6882 safi_t safi;
6883
6884 FOREACH_AFI_SAFI (afi, safi)
6885 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6886 }
6887
6888 /*
6889 * gpz 110624
6890 * Currently this is used to set static routes for VPN and ENCAP.
6891 * I think it can probably be factored with bgp_static_set.
6892 */
6893 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6894 const char *ip_str, const char *rd_str,
6895 const char *label_str, const char *rmap_str,
6896 int evpn_type, const char *esi, const char *gwip,
6897 const char *ethtag, const char *routermac)
6898 {
6899 VTY_DECLVAR_CONTEXT(bgp, bgp);
6900 int ret;
6901 struct prefix p;
6902 struct prefix_rd prd;
6903 struct bgp_dest *pdest;
6904 struct bgp_dest *dest;
6905 struct bgp_table *table;
6906 struct bgp_static *bgp_static;
6907 mpls_label_t label = MPLS_INVALID_LABEL;
6908 struct prefix gw_ip;
6909
6910 /* validate ip prefix */
6911 ret = str2prefix(ip_str, &p);
6912 if (!ret) {
6913 vty_out(vty, "%% Malformed prefix\n");
6914 return CMD_WARNING_CONFIG_FAILED;
6915 }
6916 apply_mask(&p);
6917 if ((afi == AFI_L2VPN)
6918 && (bgp_build_evpn_prefix(evpn_type,
6919 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6920 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6921 return CMD_WARNING_CONFIG_FAILED;
6922 }
6923
6924 ret = str2prefix_rd(rd_str, &prd);
6925 if (!ret) {
6926 vty_out(vty, "%% Malformed rd\n");
6927 return CMD_WARNING_CONFIG_FAILED;
6928 }
6929
6930 if (label_str) {
6931 unsigned long label_val;
6932 label_val = strtoul(label_str, NULL, 10);
6933 encode_label(label_val, &label);
6934 }
6935
6936 if (safi == SAFI_EVPN) {
6937 if (esi && str2esi(esi, NULL) == 0) {
6938 vty_out(vty, "%% Malformed ESI\n");
6939 return CMD_WARNING_CONFIG_FAILED;
6940 }
6941 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6942 vty_out(vty, "%% Malformed Router MAC\n");
6943 return CMD_WARNING_CONFIG_FAILED;
6944 }
6945 if (gwip) {
6946 memset(&gw_ip, 0, sizeof(gw_ip));
6947 ret = str2prefix(gwip, &gw_ip);
6948 if (!ret) {
6949 vty_out(vty, "%% Malformed GatewayIp\n");
6950 return CMD_WARNING_CONFIG_FAILED;
6951 }
6952 if ((gw_ip.family == AF_INET
6953 && is_evpn_prefix_ipaddr_v6(
6954 (struct prefix_evpn *)&p))
6955 || (gw_ip.family == AF_INET6
6956 && is_evpn_prefix_ipaddr_v4(
6957 (struct prefix_evpn *)&p))) {
6958 vty_out(vty,
6959 "%% GatewayIp family differs with IP prefix\n");
6960 return CMD_WARNING_CONFIG_FAILED;
6961 }
6962 }
6963 }
6964 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6965 if (!bgp_dest_has_bgp_path_info_data(pdest))
6966 bgp_dest_set_bgp_table_info(pdest,
6967 bgp_table_init(bgp, afi, safi));
6968 table = bgp_dest_get_bgp_table_info(pdest);
6969
6970 dest = bgp_node_get(table, &p);
6971
6972 if (bgp_dest_has_bgp_path_info_data(dest)) {
6973 vty_out(vty, "%% Same network configuration exists\n");
6974 bgp_dest_unlock_node(dest);
6975 } else {
6976 /* New configuration. */
6977 bgp_static = bgp_static_new();
6978 bgp_static->backdoor = 0;
6979 bgp_static->valid = 0;
6980 bgp_static->igpmetric = 0;
6981 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6982 bgp_static->label = label;
6983 bgp_static->prd = prd;
6984
6985 if (rd_str)
6986 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
6987 if (rmap_str) {
6988 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6989 route_map_counter_decrement(bgp_static->rmap.map);
6990 bgp_static->rmap.name =
6991 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6992 bgp_static->rmap.map =
6993 route_map_lookup_by_name(rmap_str);
6994 route_map_counter_increment(bgp_static->rmap.map);
6995 }
6996
6997 if (safi == SAFI_EVPN) {
6998 if (esi) {
6999 bgp_static->eth_s_id =
7000 XCALLOC(MTYPE_ATTR,
7001 sizeof(esi_t));
7002 str2esi(esi, bgp_static->eth_s_id);
7003 }
7004 if (routermac) {
7005 bgp_static->router_mac =
7006 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7007 (void)prefix_str2mac(routermac,
7008 bgp_static->router_mac);
7009 }
7010 if (gwip)
7011 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7012 }
7013 bgp_dest_set_bgp_static_info(dest, bgp_static);
7014
7015 bgp_static->valid = 1;
7016 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7017 }
7018
7019 return CMD_SUCCESS;
7020 }
7021
7022 /* Configure static BGP network. */
7023 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7024 const char *ip_str, const char *rd_str,
7025 const char *label_str, int evpn_type, const char *esi,
7026 const char *gwip, const char *ethtag)
7027 {
7028 VTY_DECLVAR_CONTEXT(bgp, bgp);
7029 int ret;
7030 struct prefix p;
7031 struct prefix_rd prd;
7032 struct bgp_dest *pdest;
7033 struct bgp_dest *dest;
7034 struct bgp_table *table;
7035 struct bgp_static *bgp_static;
7036 mpls_label_t label = MPLS_INVALID_LABEL;
7037
7038 /* Convert IP prefix string to struct prefix. */
7039 ret = str2prefix(ip_str, &p);
7040 if (!ret) {
7041 vty_out(vty, "%% Malformed prefix\n");
7042 return CMD_WARNING_CONFIG_FAILED;
7043 }
7044 apply_mask(&p);
7045 if ((afi == AFI_L2VPN)
7046 && (bgp_build_evpn_prefix(evpn_type,
7047 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7048 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7049 return CMD_WARNING_CONFIG_FAILED;
7050 }
7051 ret = str2prefix_rd(rd_str, &prd);
7052 if (!ret) {
7053 vty_out(vty, "%% Malformed rd\n");
7054 return CMD_WARNING_CONFIG_FAILED;
7055 }
7056
7057 if (label_str) {
7058 unsigned long label_val;
7059 label_val = strtoul(label_str, NULL, 10);
7060 encode_label(label_val, &label);
7061 }
7062
7063 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7064 if (!bgp_dest_has_bgp_path_info_data(pdest))
7065 bgp_dest_set_bgp_table_info(pdest,
7066 bgp_table_init(bgp, afi, safi));
7067 else
7068 bgp_dest_unlock_node(pdest);
7069 table = bgp_dest_get_bgp_table_info(pdest);
7070
7071 dest = bgp_node_lookup(table, &p);
7072
7073 if (dest) {
7074 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7075
7076 bgp_static = bgp_dest_get_bgp_static_info(dest);
7077 bgp_static_free(bgp_static);
7078 bgp_dest_set_bgp_static_info(dest, NULL);
7079 bgp_dest_unlock_node(dest);
7080 bgp_dest_unlock_node(dest);
7081 } else
7082 vty_out(vty, "%% Can't find the route\n");
7083
7084 return CMD_SUCCESS;
7085 }
7086
7087 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7088 const char *rmap_name)
7089 {
7090 VTY_DECLVAR_CONTEXT(bgp, bgp);
7091 struct bgp_rmap *rmap;
7092
7093 rmap = &bgp->table_map[afi][safi];
7094 if (rmap_name) {
7095 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7096 route_map_counter_decrement(rmap->map);
7097 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7098 rmap->map = route_map_lookup_by_name(rmap_name);
7099 route_map_counter_increment(rmap->map);
7100 } else {
7101 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7102 route_map_counter_decrement(rmap->map);
7103 rmap->map = NULL;
7104 }
7105
7106 if (bgp_fibupd_safi(safi))
7107 bgp_zebra_announce_table(bgp, afi, safi);
7108
7109 return CMD_SUCCESS;
7110 }
7111
7112 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7113 const char *rmap_name)
7114 {
7115 VTY_DECLVAR_CONTEXT(bgp, bgp);
7116 struct bgp_rmap *rmap;
7117
7118 rmap = &bgp->table_map[afi][safi];
7119 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7120 route_map_counter_decrement(rmap->map);
7121 rmap->map = NULL;
7122
7123 if (bgp_fibupd_safi(safi))
7124 bgp_zebra_announce_table(bgp, afi, safi);
7125
7126 return CMD_SUCCESS;
7127 }
7128
7129 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7130 safi_t safi)
7131 {
7132 if (bgp->table_map[afi][safi].name) {
7133 vty_out(vty, " table-map %s\n",
7134 bgp->table_map[afi][safi].name);
7135 }
7136 }
7137
7138 DEFUN (bgp_table_map,
7139 bgp_table_map_cmd,
7140 "table-map WORD",
7141 "BGP table to RIB route download filter\n"
7142 "Name of the route map\n")
7143 {
7144 int idx_word = 1;
7145 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7146 argv[idx_word]->arg);
7147 }
7148 DEFUN (no_bgp_table_map,
7149 no_bgp_table_map_cmd,
7150 "no table-map WORD",
7151 NO_STR
7152 "BGP table to RIB route download filter\n"
7153 "Name of the route map\n")
7154 {
7155 int idx_word = 2;
7156 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7157 argv[idx_word]->arg);
7158 }
7159
7160 DEFPY(bgp_network,
7161 bgp_network_cmd,
7162 "[no] network \
7163 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7164 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7165 backdoor$backdoor}]",
7166 NO_STR
7167 "Specify a network to announce via BGP\n"
7168 "IPv4 prefix\n"
7169 "Network number\n"
7170 "Network mask\n"
7171 "Network mask\n"
7172 "Route-map to modify the attributes\n"
7173 "Name of the route map\n"
7174 "Label index to associate with the prefix\n"
7175 "Label index value\n"
7176 "Specify a BGP backdoor route\n")
7177 {
7178 char addr_prefix_str[BUFSIZ];
7179
7180 if (address_str) {
7181 int ret;
7182
7183 ret = netmask_str2prefix_str(address_str, netmask_str,
7184 addr_prefix_str,
7185 sizeof(addr_prefix_str));
7186 if (!ret) {
7187 vty_out(vty, "%% Inconsistent address and mask\n");
7188 return CMD_WARNING_CONFIG_FAILED;
7189 }
7190 }
7191
7192 return bgp_static_set(
7193 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7194 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7195 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7196 }
7197
7198 DEFPY(ipv6_bgp_network,
7199 ipv6_bgp_network_cmd,
7200 "[no] network X:X::X:X/M$prefix \
7201 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7202 NO_STR
7203 "Specify a network to announce via BGP\n"
7204 "IPv6 prefix\n"
7205 "Route-map to modify the attributes\n"
7206 "Name of the route map\n"
7207 "Label index to associate with the prefix\n"
7208 "Label index value\n")
7209 {
7210 return bgp_static_set(
7211 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7212 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7213 }
7214
7215 static struct bgp_aggregate *bgp_aggregate_new(void)
7216 {
7217 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7218 }
7219
7220 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7221 {
7222 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7223 route_map_counter_decrement(aggregate->suppress_map);
7224 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7225 route_map_counter_decrement(aggregate->rmap.map);
7226 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7227 }
7228
7229 /**
7230 * Helper function to avoid repeated code: prepare variables for a
7231 * `route_map_apply` call.
7232 *
7233 * \returns `true` on route map match, otherwise `false`.
7234 */
7235 static bool aggr_suppress_map_test(struct bgp *bgp,
7236 struct bgp_aggregate *aggregate,
7237 struct bgp_path_info *pi)
7238 {
7239 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7240 route_map_result_t rmr = RMAP_DENYMATCH;
7241 struct bgp_path_info rmap_path = {};
7242 struct attr attr = {};
7243
7244 /* No route map entries created, just don't match. */
7245 if (aggregate->suppress_map == NULL)
7246 return false;
7247
7248 /* Call route map matching and return result. */
7249 attr.aspath = aspath_empty(bgp->asnotation);
7250 rmap_path.peer = bgp->peer_self;
7251 rmap_path.attr = &attr;
7252
7253 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7254 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7255 bgp->peer_self->rmap_type = 0;
7256
7257 bgp_attr_flush(&attr);
7258 aspath_unintern(&attr.aspath);
7259
7260 return rmr == RMAP_PERMITMATCH;
7261 }
7262
7263 /** Test whether the aggregation has suppressed this path or not. */
7264 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7265 struct bgp_path_info *pi)
7266 {
7267 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7268 return false;
7269
7270 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7271 }
7272
7273 /**
7274 * Suppress this path and keep the reference.
7275 *
7276 * \returns `true` if needs processing otherwise `false`.
7277 */
7278 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7279 struct bgp_path_info *pi)
7280 {
7281 struct bgp_path_info_extra *pie;
7282
7283 /* Path is already suppressed by this aggregation. */
7284 if (aggr_suppress_exists(aggregate, pi))
7285 return false;
7286
7287 pie = bgp_path_info_extra_get(pi);
7288
7289 /* This is the first suppression, allocate memory and list it. */
7290 if (pie->aggr_suppressors == NULL)
7291 pie->aggr_suppressors = list_new();
7292
7293 listnode_add(pie->aggr_suppressors, aggregate);
7294
7295 /* Only mark for processing if suppressed. */
7296 if (listcount(pie->aggr_suppressors) == 1) {
7297 if (BGP_DEBUG(update, UPDATE_OUT))
7298 zlog_debug("aggregate-address suppressing: %pFX",
7299 bgp_dest_get_prefix(pi->net));
7300
7301 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7302 return true;
7303 }
7304
7305 return false;
7306 }
7307
7308 /**
7309 * Unsuppress this path and remove the reference.
7310 *
7311 * \returns `true` if needs processing otherwise `false`.
7312 */
7313 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7314 struct bgp_path_info *pi)
7315 {
7316 /* Path wasn't suppressed. */
7317 if (!aggr_suppress_exists(aggregate, pi))
7318 return false;
7319
7320 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7321
7322 /* Unsuppress and free extra memory if last item. */
7323 if (listcount(pi->extra->aggr_suppressors) == 0) {
7324 if (BGP_DEBUG(update, UPDATE_OUT))
7325 zlog_debug("aggregate-address unsuppressing: %pFX",
7326 bgp_dest_get_prefix(pi->net));
7327
7328 list_delete(&pi->extra->aggr_suppressors);
7329 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7330 return true;
7331 }
7332
7333 return false;
7334 }
7335
7336 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7337 struct aspath *aspath,
7338 struct community *comm,
7339 struct ecommunity *ecomm,
7340 struct lcommunity *lcomm)
7341 {
7342 static struct aspath *ae = NULL;
7343 enum asnotation_mode asnotation;
7344
7345 asnotation = bgp_get_asnotation(NULL);
7346
7347 if (!ae)
7348 ae = aspath_empty(asnotation);
7349
7350 if (!pi)
7351 return false;
7352
7353 if (origin != pi->attr->origin)
7354 return false;
7355
7356 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7357 return false;
7358
7359 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7360 return false;
7361
7362 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7363 return false;
7364
7365 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7366 return false;
7367
7368 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7369 return false;
7370
7371 return true;
7372 }
7373
7374 static void bgp_aggregate_install(
7375 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7376 uint8_t origin, struct aspath *aspath, struct community *community,
7377 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7378 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7379 {
7380 struct bgp_dest *dest;
7381 struct bgp_table *table;
7382 struct bgp_path_info *pi, *orig, *new;
7383 struct attr *attr;
7384
7385 table = bgp->rib[afi][safi];
7386
7387 dest = bgp_node_get(table, p);
7388
7389 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7390 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7391 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7392 break;
7393
7394 /*
7395 * If we have paths with different MEDs, then don't install
7396 * (or uninstall) the aggregate route.
7397 */
7398 if (aggregate->match_med && aggregate->med_mismatched)
7399 goto uninstall_aggregate_route;
7400
7401 if (aggregate->count > 0) {
7402 /*
7403 * If the aggregate information has not changed
7404 * no need to re-install it again.
7405 */
7406 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7407 ecommunity, lcommunity)) {
7408 bgp_dest_unlock_node(dest);
7409
7410 if (aspath)
7411 aspath_free(aspath);
7412 if (community)
7413 community_free(&community);
7414 if (ecommunity)
7415 ecommunity_free(&ecommunity);
7416 if (lcommunity)
7417 lcommunity_free(&lcommunity);
7418
7419 return;
7420 }
7421
7422 /*
7423 * Mark the old as unusable
7424 */
7425 if (pi)
7426 bgp_path_info_delete(dest, pi);
7427
7428 attr = bgp_attr_aggregate_intern(
7429 bgp, origin, aspath, community, ecommunity, lcommunity,
7430 aggregate, atomic_aggregate, p);
7431
7432 if (!attr) {
7433 bgp_dest_unlock_node(dest);
7434 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7435 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7436 zlog_debug("%s: %pFX null attribute", __func__,
7437 p);
7438 return;
7439 }
7440
7441 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7442 bgp->peer_self, attr, dest);
7443
7444 SET_FLAG(new->flags, BGP_PATH_VALID);
7445
7446 bgp_path_info_add(dest, new);
7447 bgp_process(bgp, dest, afi, safi);
7448 } else {
7449 uninstall_aggregate_route:
7450 for (pi = orig; pi; pi = pi->next)
7451 if (pi->peer == bgp->peer_self
7452 && pi->type == ZEBRA_ROUTE_BGP
7453 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7454 break;
7455
7456 /* Withdraw static BGP route from routing table. */
7457 if (pi) {
7458 bgp_path_info_delete(dest, pi);
7459 bgp_process(bgp, dest, afi, safi);
7460 }
7461 }
7462
7463 bgp_dest_unlock_node(dest);
7464 }
7465
7466 /**
7467 * Check if the current path has different MED than other known paths.
7468 *
7469 * \returns `true` if the MED matched the others else `false`.
7470 */
7471 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7472 struct bgp *bgp, struct bgp_path_info *pi)
7473 {
7474 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7475
7476 /* This is the first route being analyzed. */
7477 if (!aggregate->med_initialized) {
7478 aggregate->med_initialized = true;
7479 aggregate->med_mismatched = false;
7480 aggregate->med_matched_value = cur_med;
7481 } else {
7482 /* Check if routes with different MED showed up. */
7483 if (cur_med != aggregate->med_matched_value)
7484 aggregate->med_mismatched = true;
7485 }
7486
7487 return !aggregate->med_mismatched;
7488 }
7489
7490 /**
7491 * Initializes and tests all routes in the aggregate address path for MED
7492 * values.
7493 *
7494 * \returns `true` if all MEDs are the same otherwise `false`.
7495 */
7496 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7497 struct bgp *bgp, const struct prefix *p,
7498 afi_t afi, safi_t safi)
7499 {
7500 struct bgp_table *table = bgp->rib[afi][safi];
7501 const struct prefix *dest_p;
7502 struct bgp_dest *dest, *top;
7503 struct bgp_path_info *pi;
7504 bool med_matched = true;
7505
7506 aggregate->med_initialized = false;
7507
7508 top = bgp_node_get(table, p);
7509 for (dest = bgp_node_get(table, p); dest;
7510 dest = bgp_route_next_until(dest, top)) {
7511 dest_p = bgp_dest_get_prefix(dest);
7512 if (dest_p->prefixlen <= p->prefixlen)
7513 continue;
7514
7515 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7516 if (BGP_PATH_HOLDDOWN(pi))
7517 continue;
7518 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7519 continue;
7520 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7521 med_matched = false;
7522 break;
7523 }
7524 }
7525 if (!med_matched)
7526 break;
7527 }
7528 bgp_dest_unlock_node(top);
7529
7530 return med_matched;
7531 }
7532
7533 /**
7534 * Toggles the route suppression status for this aggregate address
7535 * configuration.
7536 */
7537 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7538 struct bgp *bgp, const struct prefix *p,
7539 afi_t afi, safi_t safi, bool suppress)
7540 {
7541 struct bgp_table *table = bgp->rib[afi][safi];
7542 const struct prefix *dest_p;
7543 struct bgp_dest *dest, *top;
7544 struct bgp_path_info *pi;
7545 bool toggle_suppression;
7546
7547 /* We've found a different MED we must revert any suppressed routes. */
7548 top = bgp_node_get(table, p);
7549 for (dest = bgp_node_get(table, p); dest;
7550 dest = bgp_route_next_until(dest, top)) {
7551 dest_p = bgp_dest_get_prefix(dest);
7552 if (dest_p->prefixlen <= p->prefixlen)
7553 continue;
7554
7555 toggle_suppression = false;
7556 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7557 if (BGP_PATH_HOLDDOWN(pi))
7558 continue;
7559 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7560 continue;
7561
7562 /* We are toggling suppression back. */
7563 if (suppress) {
7564 /* Suppress route if not suppressed already. */
7565 if (aggr_suppress_path(aggregate, pi))
7566 toggle_suppression = true;
7567 continue;
7568 }
7569
7570 /* Install route if there is no more suppression. */
7571 if (aggr_unsuppress_path(aggregate, pi))
7572 toggle_suppression = true;
7573 }
7574
7575 if (toggle_suppression)
7576 bgp_process(bgp, dest, afi, safi);
7577 }
7578 bgp_dest_unlock_node(top);
7579 }
7580
7581 /**
7582 * Aggregate address MED matching incremental test: this function is called
7583 * when the initial aggregation occurred and we are only testing a single
7584 * new path.
7585 *
7586 * In addition to testing and setting the MED validity it also installs back
7587 * suppressed routes (if summary is configured).
7588 *
7589 * Must not be called in `bgp_aggregate_route`.
7590 */
7591 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7592 struct bgp *bgp, const struct prefix *p,
7593 afi_t afi, safi_t safi,
7594 struct bgp_path_info *pi)
7595 {
7596 /* MED matching disabled. */
7597 if (!aggregate->match_med)
7598 return;
7599
7600 /* Aggregation with different MED, recheck if we have got equal MEDs
7601 * now.
7602 */
7603 if (aggregate->med_mismatched &&
7604 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7605 aggregate->summary_only)
7606 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7607 true);
7608 else
7609 bgp_aggregate_med_match(aggregate, bgp, pi);
7610
7611 /* No mismatches, just quit. */
7612 if (!aggregate->med_mismatched)
7613 return;
7614
7615 /* Route summarization is disabled. */
7616 if (!aggregate->summary_only)
7617 return;
7618
7619 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7620 }
7621
7622 /* Update an aggregate as routes are added/removed from the BGP table */
7623 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7624 safi_t safi, struct bgp_aggregate *aggregate)
7625 {
7626 struct bgp_table *table;
7627 struct bgp_dest *top;
7628 struct bgp_dest *dest;
7629 uint8_t origin;
7630 struct aspath *aspath = NULL;
7631 struct community *community = NULL;
7632 struct ecommunity *ecommunity = NULL;
7633 struct lcommunity *lcommunity = NULL;
7634 struct bgp_path_info *pi;
7635 unsigned long match = 0;
7636 uint8_t atomic_aggregate = 0;
7637
7638 /* If the bgp instance is being deleted or self peer is deleted
7639 * then do not create aggregate route
7640 */
7641 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7642 || (bgp->peer_self == NULL))
7643 return;
7644
7645 /* Initialize and test routes for MED difference. */
7646 if (aggregate->match_med)
7647 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7648
7649 /*
7650 * Reset aggregate count: we might've been called from route map
7651 * update so in that case we must retest all more specific routes.
7652 *
7653 * \see `bgp_route_map_process_update`.
7654 */
7655 aggregate->count = 0;
7656 aggregate->incomplete_origin_count = 0;
7657 aggregate->incomplete_origin_count = 0;
7658 aggregate->egp_origin_count = 0;
7659
7660 /* ORIGIN attribute: If at least one route among routes that are
7661 aggregated has ORIGIN with the value INCOMPLETE, then the
7662 aggregated route must have the ORIGIN attribute with the value
7663 INCOMPLETE. Otherwise, if at least one route among routes that
7664 are aggregated has ORIGIN with the value EGP, then the aggregated
7665 route must have the origin attribute with the value EGP. In all
7666 other case the value of the ORIGIN attribute of the aggregated
7667 route is INTERNAL. */
7668 origin = BGP_ORIGIN_IGP;
7669
7670 table = bgp->rib[afi][safi];
7671
7672 top = bgp_node_get(table, p);
7673 for (dest = bgp_node_get(table, p); dest;
7674 dest = bgp_route_next_until(dest, top)) {
7675 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7676
7677 if (dest_p->prefixlen <= p->prefixlen)
7678 continue;
7679
7680 /* If suppress fib is enabled and route not installed
7681 * in FIB, skip the route
7682 */
7683 if (!bgp_check_advertise(bgp, dest))
7684 continue;
7685
7686 match = 0;
7687
7688 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7689 if (BGP_PATH_HOLDDOWN(pi))
7690 continue;
7691
7692 if (pi->attr->flag
7693 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7694 atomic_aggregate = 1;
7695
7696 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7697 continue;
7698
7699 /*
7700 * summary-only aggregate route suppress
7701 * aggregated route announcements.
7702 *
7703 * MED matching:
7704 * Don't create summaries if MED didn't match
7705 * otherwise neither the specific routes and the
7706 * aggregation will be announced.
7707 */
7708 if (aggregate->summary_only
7709 && AGGREGATE_MED_VALID(aggregate)) {
7710 if (aggr_suppress_path(aggregate, pi))
7711 match++;
7712 }
7713
7714 /*
7715 * Suppress more specific routes that match the route
7716 * map results.
7717 *
7718 * MED matching:
7719 * Don't suppress routes if MED matching is enabled and
7720 * it mismatched otherwise we might end up with no
7721 * routes for this path.
7722 */
7723 if (aggregate->suppress_map_name
7724 && AGGREGATE_MED_VALID(aggregate)
7725 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7726 if (aggr_suppress_path(aggregate, pi))
7727 match++;
7728 }
7729
7730 aggregate->count++;
7731
7732 /*
7733 * If at least one route among routes that are
7734 * aggregated has ORIGIN with the value INCOMPLETE,
7735 * then the aggregated route MUST have the ORIGIN
7736 * attribute with the value INCOMPLETE. Otherwise, if
7737 * at least one route among routes that are aggregated
7738 * has ORIGIN with the value EGP, then the aggregated
7739 * route MUST have the ORIGIN attribute with the value
7740 * EGP.
7741 */
7742 switch (pi->attr->origin) {
7743 case BGP_ORIGIN_INCOMPLETE:
7744 aggregate->incomplete_origin_count++;
7745 break;
7746 case BGP_ORIGIN_EGP:
7747 aggregate->egp_origin_count++;
7748 break;
7749 default:
7750 /*Do nothing.
7751 */
7752 break;
7753 }
7754
7755 if (!aggregate->as_set)
7756 continue;
7757
7758 /*
7759 * as-set aggregate route generate origin, as path,
7760 * and community aggregation.
7761 */
7762 /* Compute aggregate route's as-path.
7763 */
7764 bgp_compute_aggregate_aspath_hash(aggregate,
7765 pi->attr->aspath);
7766
7767 /* Compute aggregate route's community.
7768 */
7769 if (bgp_attr_get_community(pi->attr))
7770 bgp_compute_aggregate_community_hash(
7771 aggregate,
7772 bgp_attr_get_community(pi->attr));
7773
7774 /* Compute aggregate route's extended community.
7775 */
7776 if (bgp_attr_get_ecommunity(pi->attr))
7777 bgp_compute_aggregate_ecommunity_hash(
7778 aggregate,
7779 bgp_attr_get_ecommunity(pi->attr));
7780
7781 /* Compute aggregate route's large community.
7782 */
7783 if (bgp_attr_get_lcommunity(pi->attr))
7784 bgp_compute_aggregate_lcommunity_hash(
7785 aggregate,
7786 bgp_attr_get_lcommunity(pi->attr));
7787 }
7788 if (match)
7789 bgp_process(bgp, dest, afi, safi);
7790 }
7791 if (aggregate->as_set) {
7792 bgp_compute_aggregate_aspath_val(aggregate);
7793 bgp_compute_aggregate_community_val(aggregate);
7794 bgp_compute_aggregate_ecommunity_val(aggregate);
7795 bgp_compute_aggregate_lcommunity_val(aggregate);
7796 }
7797
7798
7799 bgp_dest_unlock_node(top);
7800
7801
7802 if (aggregate->incomplete_origin_count > 0)
7803 origin = BGP_ORIGIN_INCOMPLETE;
7804 else if (aggregate->egp_origin_count > 0)
7805 origin = BGP_ORIGIN_EGP;
7806
7807 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7808 origin = aggregate->origin;
7809
7810 if (aggregate->as_set) {
7811 if (aggregate->aspath)
7812 /* Retrieve aggregate route's as-path.
7813 */
7814 aspath = aspath_dup(aggregate->aspath);
7815
7816 if (aggregate->community)
7817 /* Retrieve aggregate route's community.
7818 */
7819 community = community_dup(aggregate->community);
7820
7821 if (aggregate->ecommunity)
7822 /* Retrieve aggregate route's ecommunity.
7823 */
7824 ecommunity = ecommunity_dup(aggregate->ecommunity);
7825
7826 if (aggregate->lcommunity)
7827 /* Retrieve aggregate route's lcommunity.
7828 */
7829 lcommunity = lcommunity_dup(aggregate->lcommunity);
7830 }
7831
7832 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7833 ecommunity, lcommunity, atomic_aggregate,
7834 aggregate);
7835 }
7836
7837 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7838 safi_t safi, struct bgp_aggregate *aggregate)
7839 {
7840 struct bgp_table *table;
7841 struct bgp_dest *top;
7842 struct bgp_dest *dest;
7843 struct bgp_path_info *pi;
7844 unsigned long match;
7845
7846 table = bgp->rib[afi][safi];
7847
7848 /* If routes exists below this node, generate aggregate routes. */
7849 top = bgp_node_get(table, p);
7850 for (dest = bgp_node_get(table, p); dest;
7851 dest = bgp_route_next_until(dest, top)) {
7852 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7853
7854 if (dest_p->prefixlen <= p->prefixlen)
7855 continue;
7856 match = 0;
7857
7858 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7859 if (BGP_PATH_HOLDDOWN(pi))
7860 continue;
7861
7862 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7863 continue;
7864
7865 /*
7866 * This route is suppressed: attempt to unsuppress it.
7867 *
7868 * `aggr_unsuppress_path` will fail if this particular
7869 * aggregate route was not the suppressor.
7870 */
7871 if (pi->extra && pi->extra->aggr_suppressors &&
7872 listcount(pi->extra->aggr_suppressors)) {
7873 if (aggr_unsuppress_path(aggregate, pi))
7874 match++;
7875 }
7876
7877 aggregate->count--;
7878
7879 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7880 aggregate->incomplete_origin_count--;
7881 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7882 aggregate->egp_origin_count--;
7883
7884 if (aggregate->as_set) {
7885 /* Remove as-path from aggregate.
7886 */
7887 bgp_remove_aspath_from_aggregate_hash(
7888 aggregate,
7889 pi->attr->aspath);
7890
7891 if (bgp_attr_get_community(pi->attr))
7892 /* Remove community from aggregate.
7893 */
7894 bgp_remove_comm_from_aggregate_hash(
7895 aggregate,
7896 bgp_attr_get_community(
7897 pi->attr));
7898
7899 if (bgp_attr_get_ecommunity(pi->attr))
7900 /* Remove ecommunity from aggregate.
7901 */
7902 bgp_remove_ecomm_from_aggregate_hash(
7903 aggregate,
7904 bgp_attr_get_ecommunity(
7905 pi->attr));
7906
7907 if (bgp_attr_get_lcommunity(pi->attr))
7908 /* Remove lcommunity from aggregate.
7909 */
7910 bgp_remove_lcomm_from_aggregate_hash(
7911 aggregate,
7912 bgp_attr_get_lcommunity(
7913 pi->attr));
7914 }
7915 }
7916
7917 /* If this node was suppressed, process the change. */
7918 if (match)
7919 bgp_process(bgp, dest, afi, safi);
7920 }
7921 if (aggregate->as_set) {
7922 aspath_free(aggregate->aspath);
7923 aggregate->aspath = NULL;
7924 if (aggregate->community)
7925 community_free(&aggregate->community);
7926 if (aggregate->ecommunity)
7927 ecommunity_free(&aggregate->ecommunity);
7928 if (aggregate->lcommunity)
7929 lcommunity_free(&aggregate->lcommunity);
7930 }
7931
7932 bgp_dest_unlock_node(top);
7933 }
7934
7935 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7936 const struct prefix *aggr_p,
7937 struct bgp_path_info *pinew, afi_t afi,
7938 safi_t safi,
7939 struct bgp_aggregate *aggregate)
7940 {
7941 uint8_t origin;
7942 struct aspath *aspath = NULL;
7943 uint8_t atomic_aggregate = 0;
7944 struct community *community = NULL;
7945 struct ecommunity *ecommunity = NULL;
7946 struct lcommunity *lcommunity = NULL;
7947
7948 /* If the bgp instance is being deleted or self peer is deleted
7949 * then do not create aggregate route
7950 */
7951 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7952 || (bgp->peer_self == NULL))
7953 return;
7954
7955 /* ORIGIN attribute: If at least one route among routes that are
7956 * aggregated has ORIGIN with the value INCOMPLETE, then the
7957 * aggregated route must have the ORIGIN attribute with the value
7958 * INCOMPLETE. Otherwise, if at least one route among routes that
7959 * are aggregated has ORIGIN with the value EGP, then the aggregated
7960 * route must have the origin attribute with the value EGP. In all
7961 * other case the value of the ORIGIN attribute of the aggregated
7962 * route is INTERNAL.
7963 */
7964 origin = BGP_ORIGIN_IGP;
7965
7966 aggregate->count++;
7967
7968 /*
7969 * This must be called before `summary` check to avoid
7970 * "suppressing" twice.
7971 */
7972 if (aggregate->match_med)
7973 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7974 pinew);
7975
7976 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7977 aggr_suppress_path(aggregate, pinew);
7978
7979 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7980 && aggr_suppress_map_test(bgp, aggregate, pinew))
7981 aggr_suppress_path(aggregate, pinew);
7982
7983 switch (pinew->attr->origin) {
7984 case BGP_ORIGIN_INCOMPLETE:
7985 aggregate->incomplete_origin_count++;
7986 break;
7987 case BGP_ORIGIN_EGP:
7988 aggregate->egp_origin_count++;
7989 break;
7990 default:
7991 /* Do nothing.
7992 */
7993 break;
7994 }
7995
7996 if (aggregate->incomplete_origin_count > 0)
7997 origin = BGP_ORIGIN_INCOMPLETE;
7998 else if (aggregate->egp_origin_count > 0)
7999 origin = BGP_ORIGIN_EGP;
8000
8001 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8002 origin = aggregate->origin;
8003
8004 if (aggregate->as_set) {
8005 /* Compute aggregate route's as-path.
8006 */
8007 bgp_compute_aggregate_aspath(aggregate,
8008 pinew->attr->aspath);
8009
8010 /* Compute aggregate route's community.
8011 */
8012 if (bgp_attr_get_community(pinew->attr))
8013 bgp_compute_aggregate_community(
8014 aggregate, bgp_attr_get_community(pinew->attr));
8015
8016 /* Compute aggregate route's extended community.
8017 */
8018 if (bgp_attr_get_ecommunity(pinew->attr))
8019 bgp_compute_aggregate_ecommunity(
8020 aggregate,
8021 bgp_attr_get_ecommunity(pinew->attr));
8022
8023 /* Compute aggregate route's large community.
8024 */
8025 if (bgp_attr_get_lcommunity(pinew->attr))
8026 bgp_compute_aggregate_lcommunity(
8027 aggregate,
8028 bgp_attr_get_lcommunity(pinew->attr));
8029
8030 /* Retrieve aggregate route's as-path.
8031 */
8032 if (aggregate->aspath)
8033 aspath = aspath_dup(aggregate->aspath);
8034
8035 /* Retrieve aggregate route's community.
8036 */
8037 if (aggregate->community)
8038 community = community_dup(aggregate->community);
8039
8040 /* Retrieve aggregate route's ecommunity.
8041 */
8042 if (aggregate->ecommunity)
8043 ecommunity = ecommunity_dup(aggregate->ecommunity);
8044
8045 /* Retrieve aggregate route's lcommunity.
8046 */
8047 if (aggregate->lcommunity)
8048 lcommunity = lcommunity_dup(aggregate->lcommunity);
8049 }
8050
8051 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8052 aspath, community, ecommunity,
8053 lcommunity, atomic_aggregate, aggregate);
8054 }
8055
8056 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8057 safi_t safi,
8058 struct bgp_path_info *pi,
8059 struct bgp_aggregate *aggregate,
8060 const struct prefix *aggr_p)
8061 {
8062 uint8_t origin;
8063 struct aspath *aspath = NULL;
8064 uint8_t atomic_aggregate = 0;
8065 struct community *community = NULL;
8066 struct ecommunity *ecommunity = NULL;
8067 struct lcommunity *lcommunity = NULL;
8068 unsigned long match = 0;
8069
8070 /* If the bgp instance is being deleted or self peer is deleted
8071 * then do not create aggregate route
8072 */
8073 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8074 || (bgp->peer_self == NULL))
8075 return;
8076
8077 if (BGP_PATH_HOLDDOWN(pi))
8078 return;
8079
8080 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8081 return;
8082
8083 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8084 if (aggr_unsuppress_path(aggregate, pi))
8085 match++;
8086
8087 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8088 && aggr_suppress_map_test(bgp, aggregate, pi))
8089 if (aggr_unsuppress_path(aggregate, pi))
8090 match++;
8091
8092 /*
8093 * This must be called after `summary`, `suppress-map` check to avoid
8094 * "unsuppressing" twice.
8095 */
8096 if (aggregate->match_med)
8097 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8098
8099 if (aggregate->count > 0)
8100 aggregate->count--;
8101
8102 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8103 aggregate->incomplete_origin_count--;
8104 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8105 aggregate->egp_origin_count--;
8106
8107 if (aggregate->as_set) {
8108 /* Remove as-path from aggregate.
8109 */
8110 bgp_remove_aspath_from_aggregate(aggregate,
8111 pi->attr->aspath);
8112
8113 if (bgp_attr_get_community(pi->attr))
8114 /* Remove community from aggregate.
8115 */
8116 bgp_remove_community_from_aggregate(
8117 aggregate, bgp_attr_get_community(pi->attr));
8118
8119 if (bgp_attr_get_ecommunity(pi->attr))
8120 /* Remove ecommunity from aggregate.
8121 */
8122 bgp_remove_ecommunity_from_aggregate(
8123 aggregate, bgp_attr_get_ecommunity(pi->attr));
8124
8125 if (bgp_attr_get_lcommunity(pi->attr))
8126 /* Remove lcommunity from aggregate.
8127 */
8128 bgp_remove_lcommunity_from_aggregate(
8129 aggregate, bgp_attr_get_lcommunity(pi->attr));
8130 }
8131
8132 /* If this node was suppressed, process the change. */
8133 if (match)
8134 bgp_process(bgp, pi->net, afi, safi);
8135
8136 origin = BGP_ORIGIN_IGP;
8137 if (aggregate->incomplete_origin_count > 0)
8138 origin = BGP_ORIGIN_INCOMPLETE;
8139 else if (aggregate->egp_origin_count > 0)
8140 origin = BGP_ORIGIN_EGP;
8141
8142 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8143 origin = aggregate->origin;
8144
8145 if (aggregate->as_set) {
8146 /* Retrieve aggregate route's as-path.
8147 */
8148 if (aggregate->aspath)
8149 aspath = aspath_dup(aggregate->aspath);
8150
8151 /* Retrieve aggregate route's community.
8152 */
8153 if (aggregate->community)
8154 community = community_dup(aggregate->community);
8155
8156 /* Retrieve aggregate route's ecommunity.
8157 */
8158 if (aggregate->ecommunity)
8159 ecommunity = ecommunity_dup(aggregate->ecommunity);
8160
8161 /* Retrieve aggregate route's lcommunity.
8162 */
8163 if (aggregate->lcommunity)
8164 lcommunity = lcommunity_dup(aggregate->lcommunity);
8165 }
8166
8167 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8168 aspath, community, ecommunity,
8169 lcommunity, atomic_aggregate, aggregate);
8170 }
8171
8172 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8173 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8174 {
8175 struct bgp_dest *child;
8176 struct bgp_dest *dest;
8177 struct bgp_aggregate *aggregate;
8178 struct bgp_table *table;
8179
8180 table = bgp->aggregate[afi][safi];
8181
8182 /* No aggregates configured. */
8183 if (bgp_table_top_nolock(table) == NULL)
8184 return;
8185
8186 if (p->prefixlen == 0)
8187 return;
8188
8189 if (BGP_PATH_HOLDDOWN(pi))
8190 return;
8191
8192 /* If suppress fib is enabled and route not installed
8193 * in FIB, do not update the aggregate route
8194 */
8195 if (!bgp_check_advertise(bgp, pi->net))
8196 return;
8197
8198 child = bgp_node_get(table, p);
8199
8200 /* Aggregate address configuration check. */
8201 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8202 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8203
8204 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8205 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8206 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8207 aggregate);
8208 }
8209 }
8210 bgp_dest_unlock_node(child);
8211 }
8212
8213 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8214 struct bgp_path_info *del, afi_t afi, safi_t safi)
8215 {
8216 struct bgp_dest *child;
8217 struct bgp_dest *dest;
8218 struct bgp_aggregate *aggregate;
8219 struct bgp_table *table;
8220
8221 table = bgp->aggregate[afi][safi];
8222
8223 /* No aggregates configured. */
8224 if (bgp_table_top_nolock(table) == NULL)
8225 return;
8226
8227 if (p->prefixlen == 0)
8228 return;
8229
8230 child = bgp_node_get(table, p);
8231
8232 /* Aggregate address configuration check. */
8233 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8234 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8235
8236 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8237 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8238 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8239 aggregate, dest_p);
8240 }
8241 }
8242 bgp_dest_unlock_node(child);
8243 }
8244
8245 /* Aggregate route attribute. */
8246 #define AGGREGATE_SUMMARY_ONLY 1
8247 #define AGGREGATE_AS_SET 1
8248 #define AGGREGATE_AS_UNSET 0
8249
8250 static const char *bgp_origin2str(uint8_t origin)
8251 {
8252 switch (origin) {
8253 case BGP_ORIGIN_IGP:
8254 return "igp";
8255 case BGP_ORIGIN_EGP:
8256 return "egp";
8257 case BGP_ORIGIN_INCOMPLETE:
8258 return "incomplete";
8259 }
8260 return "n/a";
8261 }
8262
8263 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8264 {
8265 switch (v_state) {
8266 case RPKI_NOT_BEING_USED:
8267 return "not used";
8268 case RPKI_VALID:
8269 return "valid";
8270 case RPKI_NOTFOUND:
8271 return "not found";
8272 case RPKI_INVALID:
8273 return "invalid";
8274 }
8275
8276 assert(!"We should never get here this is a dev escape");
8277 return "ERROR";
8278 }
8279
8280 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8281 afi_t afi, safi_t safi)
8282 {
8283 VTY_DECLVAR_CONTEXT(bgp, bgp);
8284 int ret;
8285 struct prefix p;
8286 struct bgp_dest *dest;
8287 struct bgp_aggregate *aggregate;
8288
8289 /* Convert string to prefix structure. */
8290 ret = str2prefix(prefix_str, &p);
8291 if (!ret) {
8292 vty_out(vty, "Malformed prefix\n");
8293 return CMD_WARNING_CONFIG_FAILED;
8294 }
8295 apply_mask(&p);
8296
8297 /* Old configuration check. */
8298 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8299 if (!dest) {
8300 vty_out(vty,
8301 "%% There is no aggregate-address configuration.\n");
8302 return CMD_WARNING_CONFIG_FAILED;
8303 }
8304
8305 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8306 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8307 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8308 NULL, NULL, 0, aggregate);
8309
8310 /* Unlock aggregate address configuration. */
8311 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8312
8313 if (aggregate->community)
8314 community_free(&aggregate->community);
8315
8316 if (aggregate->community_hash) {
8317 /* Delete all communities in the hash.
8318 */
8319 hash_clean(aggregate->community_hash,
8320 bgp_aggr_community_remove);
8321 /* Free up the community_hash.
8322 */
8323 hash_free(aggregate->community_hash);
8324 }
8325
8326 if (aggregate->ecommunity)
8327 ecommunity_free(&aggregate->ecommunity);
8328
8329 if (aggregate->ecommunity_hash) {
8330 /* Delete all ecommunities in the hash.
8331 */
8332 hash_clean(aggregate->ecommunity_hash,
8333 bgp_aggr_ecommunity_remove);
8334 /* Free up the ecommunity_hash.
8335 */
8336 hash_free(aggregate->ecommunity_hash);
8337 }
8338
8339 if (aggregate->lcommunity)
8340 lcommunity_free(&aggregate->lcommunity);
8341
8342 if (aggregate->lcommunity_hash) {
8343 /* Delete all lcommunities in the hash.
8344 */
8345 hash_clean(aggregate->lcommunity_hash,
8346 bgp_aggr_lcommunity_remove);
8347 /* Free up the lcommunity_hash.
8348 */
8349 hash_free(aggregate->lcommunity_hash);
8350 }
8351
8352 if (aggregate->aspath)
8353 aspath_free(aggregate->aspath);
8354
8355 if (aggregate->aspath_hash) {
8356 /* Delete all as-paths in the hash.
8357 */
8358 hash_clean(aggregate->aspath_hash,
8359 bgp_aggr_aspath_remove);
8360 /* Free up the aspath_hash.
8361 */
8362 hash_free(aggregate->aspath_hash);
8363 }
8364
8365 bgp_aggregate_free(aggregate);
8366 bgp_dest_unlock_node(dest);
8367 bgp_dest_unlock_node(dest);
8368
8369 return CMD_SUCCESS;
8370 }
8371
8372 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8373 safi_t safi, const char *rmap,
8374 uint8_t summary_only, uint8_t as_set,
8375 uint8_t origin, bool match_med,
8376 const char *suppress_map)
8377 {
8378 VTY_DECLVAR_CONTEXT(bgp, bgp);
8379 int ret;
8380 struct prefix p;
8381 struct bgp_dest *dest;
8382 struct bgp_aggregate *aggregate;
8383 uint8_t as_set_new = as_set;
8384
8385 if (suppress_map && summary_only) {
8386 vty_out(vty,
8387 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8388 return CMD_WARNING_CONFIG_FAILED;
8389 }
8390
8391 /* Convert string to prefix structure. */
8392 ret = str2prefix(prefix_str, &p);
8393 if (!ret) {
8394 vty_out(vty, "Malformed prefix\n");
8395 return CMD_WARNING_CONFIG_FAILED;
8396 }
8397 apply_mask(&p);
8398
8399 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8400 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8401 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8402 prefix_str);
8403 return CMD_WARNING_CONFIG_FAILED;
8404 }
8405
8406 /* Old configuration check. */
8407 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8408 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8409
8410 if (aggregate) {
8411 vty_out(vty, "There is already same aggregate network.\n");
8412 /* try to remove the old entry */
8413 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8414 if (ret) {
8415 vty_out(vty, "Error deleting aggregate.\n");
8416 bgp_dest_unlock_node(dest);
8417 return CMD_WARNING_CONFIG_FAILED;
8418 }
8419 }
8420
8421 /* Make aggregate address structure. */
8422 aggregate = bgp_aggregate_new();
8423 aggregate->summary_only = summary_only;
8424 aggregate->match_med = match_med;
8425
8426 /* Network operators MUST NOT locally generate any new
8427 * announcements containing AS_SET or AS_CONFED_SET. If they have
8428 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8429 * SHOULD withdraw those routes and re-announce routes for the
8430 * aggregate or component prefixes (i.e., the more-specific routes
8431 * subsumed by the previously aggregated route) without AS_SET
8432 * or AS_CONFED_SET in the updates.
8433 */
8434 if (bgp->reject_as_sets) {
8435 if (as_set == AGGREGATE_AS_SET) {
8436 as_set_new = AGGREGATE_AS_UNSET;
8437 zlog_warn(
8438 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8439 __func__);
8440 vty_out(vty,
8441 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8442 }
8443 }
8444
8445 aggregate->as_set = as_set_new;
8446 aggregate->safi = safi;
8447 /* Override ORIGIN attribute if defined.
8448 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8449 * to IGP which is not what rfc4271 says.
8450 * This enables the same behavior, optionally.
8451 */
8452 aggregate->origin = origin;
8453
8454 if (rmap) {
8455 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8456 route_map_counter_decrement(aggregate->rmap.map);
8457 aggregate->rmap.name =
8458 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8459 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8460 route_map_counter_increment(aggregate->rmap.map);
8461 }
8462
8463 if (suppress_map) {
8464 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8465 route_map_counter_decrement(aggregate->suppress_map);
8466
8467 aggregate->suppress_map_name =
8468 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8469 aggregate->suppress_map =
8470 route_map_lookup_by_name(aggregate->suppress_map_name);
8471 route_map_counter_increment(aggregate->suppress_map);
8472 }
8473
8474 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8475
8476 /* Aggregate address insert into BGP routing table. */
8477 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8478
8479 return CMD_SUCCESS;
8480 }
8481
8482 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8483 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8484 "as-set$as_set_s"
8485 "|summary-only$summary_only"
8486 "|route-map RMAP_NAME$rmap_name"
8487 "|origin <egp|igp|incomplete>$origin_s"
8488 "|matching-MED-only$match_med"
8489 "|suppress-map RMAP_NAME$suppress_map"
8490 "}]",
8491 NO_STR
8492 "Configure BGP aggregate entries\n"
8493 "Aggregate prefix\n"
8494 "Aggregate address\n"
8495 "Aggregate mask\n"
8496 "Generate AS set path information\n"
8497 "Filter more specific routes from updates\n"
8498 "Apply route map to aggregate network\n"
8499 "Route map name\n"
8500 "BGP origin code\n"
8501 "Remote EGP\n"
8502 "Local IGP\n"
8503 "Unknown heritage\n"
8504 "Only aggregate routes with matching MED\n"
8505 "Suppress the selected more specific routes\n"
8506 "Route map with the route selectors\n")
8507 {
8508 const char *prefix_s = NULL;
8509 safi_t safi = bgp_node_safi(vty);
8510 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8511 int as_set = AGGREGATE_AS_UNSET;
8512 char prefix_buf[PREFIX2STR_BUFFER];
8513
8514 if (addr_str) {
8515 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8516 sizeof(prefix_buf))
8517 == 0) {
8518 vty_out(vty, "%% Inconsistent address and mask\n");
8519 return CMD_WARNING_CONFIG_FAILED;
8520 }
8521 prefix_s = prefix_buf;
8522 } else
8523 prefix_s = prefix_str;
8524
8525 if (origin_s) {
8526 if (strcmp(origin_s, "egp") == 0)
8527 origin = BGP_ORIGIN_EGP;
8528 else if (strcmp(origin_s, "igp") == 0)
8529 origin = BGP_ORIGIN_IGP;
8530 else if (strcmp(origin_s, "incomplete") == 0)
8531 origin = BGP_ORIGIN_INCOMPLETE;
8532 }
8533
8534 if (as_set_s)
8535 as_set = AGGREGATE_AS_SET;
8536
8537 /* Handle configuration removal, otherwise installation. */
8538 if (no)
8539 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8540
8541 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8542 summary_only != NULL, as_set, origin,
8543 match_med != NULL, suppress_map);
8544 }
8545
8546 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8547 "[no] aggregate-address X:X::X:X/M$prefix [{"
8548 "as-set$as_set_s"
8549 "|summary-only$summary_only"
8550 "|route-map RMAP_NAME$rmap_name"
8551 "|origin <egp|igp|incomplete>$origin_s"
8552 "|matching-MED-only$match_med"
8553 "|suppress-map RMAP_NAME$suppress_map"
8554 "}]",
8555 NO_STR
8556 "Configure BGP aggregate entries\n"
8557 "Aggregate prefix\n"
8558 "Generate AS set path information\n"
8559 "Filter more specific routes from updates\n"
8560 "Apply route map to aggregate network\n"
8561 "Route map name\n"
8562 "BGP origin code\n"
8563 "Remote EGP\n"
8564 "Local IGP\n"
8565 "Unknown heritage\n"
8566 "Only aggregate routes with matching MED\n"
8567 "Suppress the selected more specific routes\n"
8568 "Route map with the route selectors\n")
8569 {
8570 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8571 int as_set = AGGREGATE_AS_UNSET;
8572
8573 if (origin_s) {
8574 if (strcmp(origin_s, "egp") == 0)
8575 origin = BGP_ORIGIN_EGP;
8576 else if (strcmp(origin_s, "igp") == 0)
8577 origin = BGP_ORIGIN_IGP;
8578 else if (strcmp(origin_s, "incomplete") == 0)
8579 origin = BGP_ORIGIN_INCOMPLETE;
8580 }
8581
8582 if (as_set_s)
8583 as_set = AGGREGATE_AS_SET;
8584
8585 /* Handle configuration removal, otherwise installation. */
8586 if (no)
8587 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8588 SAFI_UNICAST);
8589
8590 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8591 rmap_name, summary_only != NULL, as_set,
8592 origin, match_med != NULL, suppress_map);
8593 }
8594
8595 /* Redistribute route treatment. */
8596 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8597 const union g_addr *nexthop, ifindex_t ifindex,
8598 enum nexthop_types_t nhtype, uint8_t distance,
8599 enum blackhole_type bhtype, uint32_t metric,
8600 uint8_t type, unsigned short instance,
8601 route_tag_t tag)
8602 {
8603 struct bgp_path_info *new;
8604 struct bgp_path_info *bpi;
8605 struct bgp_path_info rmap_path;
8606 struct bgp_dest *bn;
8607 struct attr attr;
8608 struct attr *new_attr;
8609 afi_t afi;
8610 route_map_result_t ret;
8611 struct bgp_redist *red;
8612
8613 /* Make default attribute. */
8614 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8615 /*
8616 * This must not be NULL to satisfy Coverity SA
8617 */
8618 assert(attr.aspath);
8619
8620 switch (nhtype) {
8621 case NEXTHOP_TYPE_IFINDEX:
8622 switch (p->family) {
8623 case AF_INET:
8624 attr.nexthop.s_addr = INADDR_ANY;
8625 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8626 break;
8627 case AF_INET6:
8628 memset(&attr.mp_nexthop_global, 0,
8629 sizeof(attr.mp_nexthop_global));
8630 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8631 break;
8632 }
8633 break;
8634 case NEXTHOP_TYPE_IPV4:
8635 case NEXTHOP_TYPE_IPV4_IFINDEX:
8636 attr.nexthop = nexthop->ipv4;
8637 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8638 break;
8639 case NEXTHOP_TYPE_IPV6:
8640 case NEXTHOP_TYPE_IPV6_IFINDEX:
8641 attr.mp_nexthop_global = nexthop->ipv6;
8642 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8643 break;
8644 case NEXTHOP_TYPE_BLACKHOLE:
8645 switch (p->family) {
8646 case AF_INET:
8647 attr.nexthop.s_addr = INADDR_ANY;
8648 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8649 break;
8650 case AF_INET6:
8651 memset(&attr.mp_nexthop_global, 0,
8652 sizeof(attr.mp_nexthop_global));
8653 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8654 break;
8655 }
8656 attr.bh_type = bhtype;
8657 break;
8658 }
8659 attr.nh_type = nhtype;
8660 attr.nh_ifindex = ifindex;
8661
8662 attr.med = metric;
8663 attr.distance = distance;
8664 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8665 attr.tag = tag;
8666
8667 if (metric)
8668 bgp_attr_set_aigp_metric(&attr, metric);
8669
8670 afi = family2afi(p->family);
8671
8672 red = bgp_redist_lookup(bgp, afi, type, instance);
8673 if (red) {
8674 struct attr attr_new;
8675
8676 /* Copy attribute for modification. */
8677 attr_new = attr;
8678
8679 if (red->redist_metric_flag) {
8680 attr_new.med = red->redist_metric;
8681 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8682 }
8683
8684 /* Apply route-map. */
8685 if (red->rmap.name) {
8686 memset(&rmap_path, 0, sizeof(rmap_path));
8687 rmap_path.peer = bgp->peer_self;
8688 rmap_path.attr = &attr_new;
8689
8690 SET_FLAG(bgp->peer_self->rmap_type,
8691 PEER_RMAP_TYPE_REDISTRIBUTE);
8692
8693 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8694
8695 bgp->peer_self->rmap_type = 0;
8696
8697 if (ret == RMAP_DENYMATCH) {
8698 /* Free uninterned attribute. */
8699 bgp_attr_flush(&attr_new);
8700
8701 /* Unintern original. */
8702 aspath_unintern(&attr.aspath);
8703 bgp_redistribute_delete(bgp, p, type, instance);
8704 return;
8705 }
8706 }
8707
8708 if (bgp_in_graceful_shutdown(bgp))
8709 bgp_attr_add_gshut_community(&attr_new);
8710
8711 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8712 SAFI_UNICAST, p, NULL);
8713
8714 new_attr = bgp_attr_intern(&attr_new);
8715
8716 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8717 if (bpi->peer == bgp->peer_self
8718 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8719 break;
8720
8721 if (bpi) {
8722 /* Ensure the (source route) type is updated. */
8723 bpi->type = type;
8724 if (attrhash_cmp(bpi->attr, new_attr)
8725 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8726 bgp_attr_unintern(&new_attr);
8727 aspath_unintern(&attr.aspath);
8728 bgp_dest_unlock_node(bn);
8729 return;
8730 } else {
8731 /* The attribute is changed. */
8732 bgp_path_info_set_flag(bn, bpi,
8733 BGP_PATH_ATTR_CHANGED);
8734
8735 /* Rewrite BGP route information. */
8736 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8737 bgp_path_info_restore(bn, bpi);
8738 else
8739 bgp_aggregate_decrement(
8740 bgp, p, bpi, afi, SAFI_UNICAST);
8741 bgp_attr_unintern(&bpi->attr);
8742 bpi->attr = new_attr;
8743 bpi->uptime = monotime(NULL);
8744
8745 /* Process change. */
8746 bgp_aggregate_increment(bgp, p, bpi, afi,
8747 SAFI_UNICAST);
8748 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8749 bgp_dest_unlock_node(bn);
8750 aspath_unintern(&attr.aspath);
8751
8752 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8753 || (bgp->inst_type
8754 == BGP_INSTANCE_TYPE_DEFAULT)) {
8755
8756 vpn_leak_from_vrf_update(
8757 bgp_get_default(), bgp, bpi);
8758 }
8759 return;
8760 }
8761 }
8762
8763 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8764 bgp->peer_self, new_attr, bn);
8765 SET_FLAG(new->flags, BGP_PATH_VALID);
8766
8767 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8768 bgp_path_info_add(bn, new);
8769 bgp_dest_unlock_node(bn);
8770 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8771 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8772
8773 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8774 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8775
8776 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8777 }
8778 }
8779
8780 /* Unintern original. */
8781 aspath_unintern(&attr.aspath);
8782 }
8783
8784 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8785 unsigned short instance)
8786 {
8787 afi_t afi;
8788 struct bgp_dest *dest;
8789 struct bgp_path_info *pi;
8790 struct bgp_redist *red;
8791
8792 afi = family2afi(p->family);
8793
8794 red = bgp_redist_lookup(bgp, afi, type, instance);
8795 if (red) {
8796 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8797 SAFI_UNICAST, p, NULL);
8798
8799 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8800 if (pi->peer == bgp->peer_self && pi->type == type)
8801 break;
8802
8803 if (pi) {
8804 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8805 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8806
8807 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8808 bgp, pi);
8809 }
8810 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8811 bgp_path_info_delete(dest, pi);
8812 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8813 }
8814 bgp_dest_unlock_node(dest);
8815 }
8816 }
8817
8818 /* Withdraw specified route type's route. */
8819 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8820 unsigned short instance)
8821 {
8822 struct bgp_dest *dest;
8823 struct bgp_path_info *pi;
8824 struct bgp_table *table;
8825
8826 table = bgp->rib[afi][SAFI_UNICAST];
8827
8828 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8829 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8830 if (pi->peer == bgp->peer_self && pi->type == type
8831 && pi->instance == instance)
8832 break;
8833
8834 if (pi) {
8835 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8836 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8837
8838 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8839 bgp, pi);
8840 }
8841 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8842 pi, afi, SAFI_UNICAST);
8843 bgp_path_info_delete(dest, pi);
8844 if (!CHECK_FLAG(bgp->flags,
8845 BGP_FLAG_DELETE_IN_PROGRESS))
8846 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8847 else
8848 bgp_path_info_reap(dest, pi);
8849 }
8850 }
8851 }
8852
8853 /* Static function to display route. */
8854 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8855 struct vty *vty, json_object *json, bool wide)
8856 {
8857 int len = 0;
8858 char buf[INET6_ADDRSTRLEN];
8859
8860 if (p->family == AF_INET) {
8861 if (!json) {
8862 len = vty_out(vty, "%pFX", p);
8863 } else {
8864 json_object_string_add(json, "prefix",
8865 inet_ntop(p->family,
8866 &p->u.prefix, buf,
8867 sizeof(buf)));
8868 json_object_int_add(json, "prefixLen", p->prefixlen);
8869 json_object_string_addf(json, "network", "%pFX", p);
8870 json_object_int_add(json, "version", dest->version);
8871 }
8872 } else if (p->family == AF_ETHERNET) {
8873 len = vty_out(vty, "%pFX", p);
8874 } else if (p->family == AF_EVPN) {
8875 if (!json)
8876 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8877 else
8878 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8879 } else if (p->family == AF_FLOWSPEC) {
8880 route_vty_out_flowspec(vty, p, NULL,
8881 json ?
8882 NLRI_STRING_FORMAT_JSON_SIMPLE :
8883 NLRI_STRING_FORMAT_MIN, json);
8884 } else {
8885 if (!json)
8886 len = vty_out(vty, "%pFX", p);
8887 else {
8888 json_object_string_add(json, "prefix",
8889 inet_ntop(p->family,
8890 &p->u.prefix, buf,
8891 sizeof(buf)));
8892 json_object_int_add(json, "prefixLen", p->prefixlen);
8893 json_object_string_addf(json, "network", "%pFX", p);
8894 json_object_int_add(json, "version", dest->version);
8895 }
8896 }
8897
8898 if (!json) {
8899 len = wide ? (45 - len) : (17 - len);
8900 if (len < 1)
8901 vty_out(vty, "\n%*s", 20, " ");
8902 else
8903 vty_out(vty, "%*s", len, " ");
8904 }
8905 }
8906
8907 enum bgp_display_type {
8908 normal_list,
8909 };
8910
8911 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8912 {
8913 switch (reason) {
8914 case bgp_path_selection_none:
8915 return "Nothing to Select";
8916 case bgp_path_selection_first:
8917 return "First path received";
8918 case bgp_path_selection_evpn_sticky_mac:
8919 return "EVPN Sticky Mac";
8920 case bgp_path_selection_evpn_seq:
8921 return "EVPN sequence number";
8922 case bgp_path_selection_evpn_lower_ip:
8923 return "EVPN lower IP";
8924 case bgp_path_selection_evpn_local_path:
8925 return "EVPN local ES path";
8926 case bgp_path_selection_evpn_non_proxy:
8927 return "EVPN non proxy";
8928 case bgp_path_selection_weight:
8929 return "Weight";
8930 case bgp_path_selection_local_pref:
8931 return "Local Pref";
8932 case bgp_path_selection_accept_own:
8933 return "Accept Own";
8934 case bgp_path_selection_local_route:
8935 return "Local Route";
8936 case bgp_path_selection_aigp:
8937 return "AIGP";
8938 case bgp_path_selection_confed_as_path:
8939 return "Confederation based AS Path";
8940 case bgp_path_selection_as_path:
8941 return "AS Path";
8942 case bgp_path_selection_origin:
8943 return "Origin";
8944 case bgp_path_selection_med:
8945 return "MED";
8946 case bgp_path_selection_peer:
8947 return "Peer Type";
8948 case bgp_path_selection_confed:
8949 return "Confed Peer Type";
8950 case bgp_path_selection_igp_metric:
8951 return "IGP Metric";
8952 case bgp_path_selection_older:
8953 return "Older Path";
8954 case bgp_path_selection_router_id:
8955 return "Router ID";
8956 case bgp_path_selection_cluster_length:
8957 return "Cluster length";
8958 case bgp_path_selection_stale:
8959 return "Path Staleness";
8960 case bgp_path_selection_local_configured:
8961 return "Locally configured route";
8962 case bgp_path_selection_neighbor_ip:
8963 return "Neighbor IP";
8964 case bgp_path_selection_default:
8965 return "Nothing left to compare";
8966 }
8967 return "Invalid (internal error)";
8968 }
8969
8970 /* Print the short form route status for a bgp_path_info */
8971 static void route_vty_short_status_out(struct vty *vty,
8972 struct bgp_path_info *path,
8973 const struct prefix *p,
8974 json_object *json_path)
8975 {
8976 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8977
8978 if (json_path) {
8979
8980 /* Route status display. */
8981 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8982 json_object_boolean_true_add(json_path, "removed");
8983
8984 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8985 json_object_boolean_true_add(json_path, "stale");
8986
8987 if (path->extra && bgp_path_suppressed(path))
8988 json_object_boolean_true_add(json_path, "suppressed");
8989
8990 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8991 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8992 json_object_boolean_true_add(json_path, "valid");
8993
8994 /* Selected */
8995 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8996 json_object_boolean_true_add(json_path, "history");
8997
8998 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8999 json_object_boolean_true_add(json_path, "damped");
9000
9001 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9002 json_object_boolean_true_add(json_path, "bestpath");
9003 json_object_string_add(json_path, "selectionReason",
9004 bgp_path_selection_reason2str(
9005 path->net->reason));
9006 }
9007
9008 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9009 json_object_boolean_true_add(json_path, "multipath");
9010
9011 /* Internal route. */
9012 if ((path->peer->as)
9013 && (path->peer->as == path->peer->local_as))
9014 json_object_string_add(json_path, "pathFrom",
9015 "internal");
9016 else
9017 json_object_string_add(json_path, "pathFrom",
9018 "external");
9019
9020 return;
9021 }
9022
9023 /* RPKI validation state */
9024 rpki_state =
9025 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9026
9027 if (rpki_state == RPKI_VALID)
9028 vty_out(vty, "V");
9029 else if (rpki_state == RPKI_INVALID)
9030 vty_out(vty, "I");
9031 else if (rpki_state == RPKI_NOTFOUND)
9032 vty_out(vty, "N");
9033 else
9034 vty_out(vty, " ");
9035
9036 /* Route status display. */
9037 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9038 vty_out(vty, "R");
9039 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9040 vty_out(vty, "S");
9041 else if (bgp_path_suppressed(path))
9042 vty_out(vty, "s");
9043 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9044 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9045 vty_out(vty, "*");
9046 else
9047 vty_out(vty, " ");
9048
9049 /* Selected */
9050 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9051 vty_out(vty, "h");
9052 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9053 vty_out(vty, "d");
9054 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9055 vty_out(vty, ">");
9056 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9057 vty_out(vty, "=");
9058 else
9059 vty_out(vty, " ");
9060
9061 /* Internal route. */
9062 if (path->peer && (path->peer->as)
9063 && (path->peer->as == path->peer->local_as))
9064 vty_out(vty, "i");
9065 else
9066 vty_out(vty, " ");
9067 }
9068
9069 static char *bgp_nexthop_hostname(struct peer *peer,
9070 struct bgp_nexthop_cache *bnc)
9071 {
9072 if (peer->hostname
9073 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9074 return peer->hostname;
9075 return NULL;
9076 }
9077
9078 /* called from terminal list command */
9079 void route_vty_out(struct vty *vty, const struct prefix *p,
9080 struct bgp_path_info *path, int display, safi_t safi,
9081 json_object *json_paths, bool wide)
9082 {
9083 int len;
9084 struct attr *attr = path->attr;
9085 json_object *json_path = NULL;
9086 json_object *json_nexthops = NULL;
9087 json_object *json_nexthop_global = NULL;
9088 json_object *json_nexthop_ll = NULL;
9089 json_object *json_ext_community = NULL;
9090 char vrf_id_str[VRF_NAMSIZ] = {0};
9091 bool nexthop_self =
9092 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9093 bool nexthop_othervrf = false;
9094 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9095 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9096 char *nexthop_hostname =
9097 bgp_nexthop_hostname(path->peer, path->nexthop);
9098 char esi_buf[ESI_STR_LEN];
9099
9100 if (json_paths)
9101 json_path = json_object_new_object();
9102
9103 /* short status lead text */
9104 route_vty_short_status_out(vty, path, p, json_path);
9105
9106 if (!json_paths) {
9107 /* print prefix and mask */
9108 if (!display)
9109 route_vty_out_route(path->net, p, vty, json_path, wide);
9110 else
9111 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9112 } else {
9113 route_vty_out_route(path->net, p, vty, json_path, wide);
9114 }
9115
9116 /*
9117 * If vrf id of nexthop is different from that of prefix,
9118 * set up printable string to append
9119 */
9120 if (path->extra && path->extra->bgp_orig) {
9121 const char *self = "";
9122
9123 if (nexthop_self)
9124 self = "<";
9125
9126 nexthop_othervrf = true;
9127 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9128
9129 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9130 snprintf(vrf_id_str, sizeof(vrf_id_str),
9131 "@%s%s", VRFID_NONE_STR, self);
9132 else
9133 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9134 path->extra->bgp_orig->vrf_id, self);
9135
9136 if (path->extra->bgp_orig->inst_type
9137 != BGP_INSTANCE_TYPE_DEFAULT)
9138
9139 nexthop_vrfname = path->extra->bgp_orig->name;
9140 } else {
9141 const char *self = "";
9142
9143 if (nexthop_self)
9144 self = "<";
9145
9146 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9147 }
9148
9149 /*
9150 * For ENCAP and EVPN routes, nexthop address family is not
9151 * neccessarily the same as the prefix address family.
9152 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9153 * EVPN routes are also exchanged with a MP nexthop. Currently,
9154 * this
9155 * is only IPv4, the value will be present in either
9156 * attr->nexthop or
9157 * attr->mp_nexthop_global_in
9158 */
9159 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9160 char nexthop[128];
9161 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9162
9163 switch (af) {
9164 case AF_INET:
9165 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9166 &attr->mp_nexthop_global_in);
9167 break;
9168 case AF_INET6:
9169 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9170 &attr->mp_nexthop_global);
9171 break;
9172 default:
9173 snprintf(nexthop, sizeof(nexthop), "?");
9174 break;
9175 }
9176
9177 if (json_paths) {
9178 json_nexthop_global = json_object_new_object();
9179
9180 json_object_string_add(json_nexthop_global, "ip",
9181 nexthop);
9182
9183 if (path->peer->hostname)
9184 json_object_string_add(json_nexthop_global,
9185 "hostname",
9186 path->peer->hostname);
9187
9188 json_object_string_add(json_nexthop_global, "afi",
9189 (af == AF_INET) ? "ipv4"
9190 : "ipv6");
9191 json_object_boolean_true_add(json_nexthop_global,
9192 "used");
9193 } else {
9194 if (nexthop_hostname)
9195 len = vty_out(vty, "%s(%s)%s", nexthop,
9196 nexthop_hostname, vrf_id_str);
9197 else
9198 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9199
9200 len = wide ? (41 - len) : (16 - len);
9201 if (len < 1)
9202 vty_out(vty, "\n%*s", 36, " ");
9203 else
9204 vty_out(vty, "%*s", len, " ");
9205 }
9206 } else if (safi == SAFI_EVPN) {
9207 if (json_paths) {
9208 json_nexthop_global = json_object_new_object();
9209
9210 json_object_string_addf(json_nexthop_global, "ip",
9211 "%pI4",
9212 &attr->mp_nexthop_global_in);
9213
9214 if (path->peer->hostname)
9215 json_object_string_add(json_nexthop_global,
9216 "hostname",
9217 path->peer->hostname);
9218
9219 json_object_string_add(json_nexthop_global, "afi",
9220 "ipv4");
9221 json_object_boolean_true_add(json_nexthop_global,
9222 "used");
9223 } else {
9224 if (nexthop_hostname)
9225 len = vty_out(vty, "%pI4(%s)%s",
9226 &attr->mp_nexthop_global_in,
9227 nexthop_hostname, vrf_id_str);
9228 else
9229 len = vty_out(vty, "%pI4%s",
9230 &attr->mp_nexthop_global_in,
9231 vrf_id_str);
9232
9233 len = wide ? (41 - len) : (16 - len);
9234 if (len < 1)
9235 vty_out(vty, "\n%*s", 36, " ");
9236 else
9237 vty_out(vty, "%*s", len, " ");
9238 }
9239 } else if (safi == SAFI_FLOWSPEC) {
9240 if (attr->nexthop.s_addr != INADDR_ANY) {
9241 if (json_paths) {
9242 json_nexthop_global = json_object_new_object();
9243
9244 json_object_string_add(json_nexthop_global,
9245 "afi", "ipv4");
9246 json_object_string_addf(json_nexthop_global,
9247 "ip", "%pI4",
9248 &attr->nexthop);
9249
9250 if (path->peer->hostname)
9251 json_object_string_add(
9252 json_nexthop_global, "hostname",
9253 path->peer->hostname);
9254
9255 json_object_boolean_true_add(
9256 json_nexthop_global,
9257 "used");
9258 } else {
9259 if (nexthop_hostname)
9260 len = vty_out(vty, "%pI4(%s)%s",
9261 &attr->nexthop,
9262 nexthop_hostname,
9263 vrf_id_str);
9264 else
9265 len = vty_out(vty, "%pI4%s",
9266 &attr->nexthop,
9267 vrf_id_str);
9268
9269 len = wide ? (41 - len) : (16 - len);
9270 if (len < 1)
9271 vty_out(vty, "\n%*s", 36, " ");
9272 else
9273 vty_out(vty, "%*s", len, " ");
9274 }
9275 }
9276 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9277 if (json_paths) {
9278 json_nexthop_global = json_object_new_object();
9279
9280 json_object_string_addf(json_nexthop_global, "ip",
9281 "%pI4", &attr->nexthop);
9282
9283 if (path->peer->hostname)
9284 json_object_string_add(json_nexthop_global,
9285 "hostname",
9286 path->peer->hostname);
9287
9288 json_object_string_add(json_nexthop_global, "afi",
9289 "ipv4");
9290 json_object_boolean_true_add(json_nexthop_global,
9291 "used");
9292 } else {
9293 if (nexthop_hostname)
9294 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9295 nexthop_hostname, vrf_id_str);
9296 else
9297 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9298 vrf_id_str);
9299
9300 len = wide ? (41 - len) : (16 - len);
9301 if (len < 1)
9302 vty_out(vty, "\n%*s", 36, " ");
9303 else
9304 vty_out(vty, "%*s", len, " ");
9305 }
9306 }
9307
9308 /* IPv6 Next Hop */
9309 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9310 if (json_paths) {
9311 json_nexthop_global = json_object_new_object();
9312 json_object_string_addf(json_nexthop_global, "ip",
9313 "%pI6",
9314 &attr->mp_nexthop_global);
9315
9316 if (path->peer->hostname)
9317 json_object_string_add(json_nexthop_global,
9318 "hostname",
9319 path->peer->hostname);
9320
9321 json_object_string_add(json_nexthop_global, "afi",
9322 "ipv6");
9323 json_object_string_add(json_nexthop_global, "scope",
9324 "global");
9325
9326 /* We display both LL & GL if both have been
9327 * received */
9328 if ((attr->mp_nexthop_len
9329 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9330 || (path->peer->conf_if)) {
9331 json_nexthop_ll = json_object_new_object();
9332 json_object_string_addf(
9333 json_nexthop_ll, "ip", "%pI6",
9334 &attr->mp_nexthop_local);
9335
9336 if (path->peer->hostname)
9337 json_object_string_add(
9338 json_nexthop_ll, "hostname",
9339 path->peer->hostname);
9340
9341 json_object_string_add(json_nexthop_ll, "afi",
9342 "ipv6");
9343 json_object_string_add(json_nexthop_ll, "scope",
9344 "link-local");
9345
9346 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9347 &attr->mp_nexthop_local)
9348 != 0)
9349 && !attr->mp_nexthop_prefer_global)
9350 json_object_boolean_true_add(
9351 json_nexthop_ll, "used");
9352 else
9353 json_object_boolean_true_add(
9354 json_nexthop_global, "used");
9355 } else
9356 json_object_boolean_true_add(
9357 json_nexthop_global, "used");
9358 } else {
9359 /* Display LL if LL/Global both in table unless
9360 * prefer-global is set */
9361 if (((attr->mp_nexthop_len
9362 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9363 && !attr->mp_nexthop_prefer_global)
9364 || (path->peer->conf_if)) {
9365 if (path->peer->conf_if) {
9366 len = vty_out(vty, "%s",
9367 path->peer->conf_if);
9368 /* len of IPv6 addr + max len of def
9369 * ifname */
9370 len = wide ? (41 - len) : (16 - len);
9371
9372 if (len < 1)
9373 vty_out(vty, "\n%*s", 36, " ");
9374 else
9375 vty_out(vty, "%*s", len, " ");
9376 } else {
9377 if (nexthop_hostname)
9378 len = vty_out(
9379 vty, "%pI6(%s)%s",
9380 &attr->mp_nexthop_local,
9381 nexthop_hostname,
9382 vrf_id_str);
9383 else
9384 len = vty_out(
9385 vty, "%pI6%s",
9386 &attr->mp_nexthop_local,
9387 vrf_id_str);
9388
9389 len = wide ? (41 - len) : (16 - len);
9390
9391 if (len < 1)
9392 vty_out(vty, "\n%*s", 36, " ");
9393 else
9394 vty_out(vty, "%*s", len, " ");
9395 }
9396 } else {
9397 if (nexthop_hostname)
9398 len = vty_out(vty, "%pI6(%s)%s",
9399 &attr->mp_nexthop_global,
9400 nexthop_hostname,
9401 vrf_id_str);
9402 else
9403 len = vty_out(vty, "%pI6%s",
9404 &attr->mp_nexthop_global,
9405 vrf_id_str);
9406
9407 len = wide ? (41 - len) : (16 - len);
9408
9409 if (len < 1)
9410 vty_out(vty, "\n%*s", 36, " ");
9411 else
9412 vty_out(vty, "%*s", len, " ");
9413 }
9414 }
9415 }
9416
9417 /* MED/Metric */
9418 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9419 if (json_paths)
9420 json_object_int_add(json_path, "metric", attr->med);
9421 else if (wide)
9422 vty_out(vty, "%7u", attr->med);
9423 else
9424 vty_out(vty, "%10u", attr->med);
9425 else if (!json_paths) {
9426 if (wide)
9427 vty_out(vty, "%*s", 7, " ");
9428 else
9429 vty_out(vty, "%*s", 10, " ");
9430 }
9431
9432 /* Local Pref */
9433 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9434 if (json_paths)
9435 json_object_int_add(json_path, "locPrf",
9436 attr->local_pref);
9437 else
9438 vty_out(vty, "%7u", attr->local_pref);
9439 else if (!json_paths)
9440 vty_out(vty, " ");
9441
9442 if (json_paths)
9443 json_object_int_add(json_path, "weight", attr->weight);
9444 else
9445 vty_out(vty, "%7u ", attr->weight);
9446
9447 if (json_paths)
9448 json_object_string_addf(json_path, "peerId", "%pSU",
9449 &path->peer->su);
9450
9451 /* Print aspath */
9452 if (attr->aspath) {
9453 if (json_paths)
9454 json_object_string_add(json_path, "path",
9455 attr->aspath->str);
9456 else
9457 aspath_print_vty(vty, attr->aspath);
9458 }
9459
9460 /* Print origin */
9461 if (json_paths)
9462 json_object_string_add(json_path, "origin",
9463 bgp_origin_long_str[attr->origin]);
9464 else
9465 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9466
9467 if (json_paths) {
9468 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9469 json_object_string_add(json_path, "esi",
9470 esi_to_str(&attr->esi,
9471 esi_buf, sizeof(esi_buf)));
9472 }
9473 if (safi == SAFI_EVPN &&
9474 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9475 json_ext_community = json_object_new_object();
9476 json_object_string_add(
9477 json_ext_community, "string",
9478 bgp_attr_get_ecommunity(attr)->str);
9479 json_object_object_add(json_path,
9480 "extendedCommunity",
9481 json_ext_community);
9482 }
9483
9484 if (nexthop_self)
9485 json_object_boolean_true_add(json_path,
9486 "announceNexthopSelf");
9487 if (nexthop_othervrf) {
9488 json_object_string_add(json_path, "nhVrfName",
9489 nexthop_vrfname);
9490
9491 json_object_int_add(json_path, "nhVrfId",
9492 ((nexthop_vrfid == VRF_UNKNOWN)
9493 ? -1
9494 : (int)nexthop_vrfid));
9495 }
9496 }
9497
9498 if (json_paths) {
9499 if (json_nexthop_global || json_nexthop_ll) {
9500 json_nexthops = json_object_new_array();
9501
9502 if (json_nexthop_global)
9503 json_object_array_add(json_nexthops,
9504 json_nexthop_global);
9505
9506 if (json_nexthop_ll)
9507 json_object_array_add(json_nexthops,
9508 json_nexthop_ll);
9509
9510 json_object_object_add(json_path, "nexthops",
9511 json_nexthops);
9512 }
9513
9514 json_object_array_add(json_paths, json_path);
9515 } else {
9516 vty_out(vty, "\n");
9517
9518 if (safi == SAFI_EVPN) {
9519 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9520 /* XXX - add these params to the json out */
9521 vty_out(vty, "%*s", 20, " ");
9522 vty_out(vty, "ESI:%s",
9523 esi_to_str(&attr->esi, esi_buf,
9524 sizeof(esi_buf)));
9525
9526 vty_out(vty, "\n");
9527 }
9528 if (attr->flag &
9529 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9530 vty_out(vty, "%*s", 20, " ");
9531 vty_out(vty, "%s\n",
9532 bgp_attr_get_ecommunity(attr)->str);
9533 }
9534 }
9535
9536 #ifdef ENABLE_BGP_VNC
9537 /* prints an additional line, indented, with VNC info, if
9538 * present */
9539 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9540 rfapi_vty_out_vncinfo(vty, p, path, safi);
9541 #endif
9542 }
9543 }
9544
9545 /* called from terminal list command */
9546 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9547 const struct prefix *p, struct attr *attr, safi_t safi,
9548 bool use_json, json_object *json_ar, bool wide)
9549 {
9550 json_object *json_status = NULL;
9551 json_object *json_net = NULL;
9552 int len;
9553 char buff[BUFSIZ];
9554
9555 /* Route status display. */
9556 if (use_json) {
9557 json_status = json_object_new_object();
9558 json_net = json_object_new_object();
9559 } else {
9560 vty_out(vty, " *");
9561 vty_out(vty, ">");
9562 vty_out(vty, " ");
9563 }
9564
9565 /* print prefix and mask */
9566 if (use_json) {
9567 if (safi == SAFI_EVPN)
9568 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9569 else if (p->family == AF_INET || p->family == AF_INET6) {
9570 json_object_string_add(
9571 json_net, "addrPrefix",
9572 inet_ntop(p->family, &p->u.prefix, buff,
9573 BUFSIZ));
9574 json_object_int_add(json_net, "prefixLen",
9575 p->prefixlen);
9576 json_object_string_addf(json_net, "network", "%pFX", p);
9577 }
9578 } else
9579 route_vty_out_route(dest, p, vty, NULL, wide);
9580
9581 /* Print attribute */
9582 if (attr) {
9583 if (use_json) {
9584 if (p->family == AF_INET &&
9585 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9586 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9587 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9588 json_object_string_addf(
9589 json_net, "nextHop", "%pI4",
9590 &attr->mp_nexthop_global_in);
9591 else
9592 json_object_string_addf(
9593 json_net, "nextHop", "%pI4",
9594 &attr->nexthop);
9595 } else if (p->family == AF_INET6 ||
9596 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9597 json_object_string_addf(
9598 json_net, "nextHopGlobal", "%pI6",
9599 &attr->mp_nexthop_global);
9600 } else if (p->family == AF_EVPN &&
9601 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9602 json_object_string_addf(
9603 json_net, "nextHop", "%pI4",
9604 &attr->mp_nexthop_global_in);
9605 }
9606
9607 if (attr->flag
9608 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9609 json_object_int_add(json_net, "metric",
9610 attr->med);
9611
9612 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9613 json_object_int_add(json_net, "locPrf",
9614 attr->local_pref);
9615
9616 json_object_int_add(json_net, "weight", attr->weight);
9617
9618 /* Print aspath */
9619 if (attr->aspath)
9620 json_object_string_add(json_net, "path",
9621 attr->aspath->str);
9622
9623 /* Print origin */
9624 #if CONFDATE > 20231208
9625 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9626 #endif
9627 json_object_string_add(json_net, "bgpOriginCode",
9628 bgp_origin_str[attr->origin]);
9629 json_object_string_add(
9630 json_net, "origin",
9631 bgp_origin_long_str[attr->origin]);
9632 } else {
9633 if (p->family == AF_INET &&
9634 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9635 safi == SAFI_EVPN ||
9636 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9637 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9638 || safi == SAFI_EVPN)
9639 vty_out(vty, "%-16pI4",
9640 &attr->mp_nexthop_global_in);
9641 else if (wide)
9642 vty_out(vty, "%-41pI4", &attr->nexthop);
9643 else
9644 vty_out(vty, "%-16pI4", &attr->nexthop);
9645 } else if (p->family == AF_INET6 ||
9646 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9647 len = vty_out(vty, "%pI6",
9648 &attr->mp_nexthop_global);
9649 len = wide ? (41 - len) : (16 - len);
9650 if (len < 1)
9651 vty_out(vty, "\n%*s", 36, " ");
9652 else
9653 vty_out(vty, "%*s", len, " ");
9654 }
9655 if (attr->flag
9656 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9657 if (wide)
9658 vty_out(vty, "%7u", attr->med);
9659 else
9660 vty_out(vty, "%10u", attr->med);
9661 else if (wide)
9662 vty_out(vty, " ");
9663 else
9664 vty_out(vty, " ");
9665
9666 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9667 vty_out(vty, "%7u", attr->local_pref);
9668 else
9669 vty_out(vty, " ");
9670
9671 vty_out(vty, "%7u ", attr->weight);
9672
9673 /* Print aspath */
9674 if (attr->aspath)
9675 aspath_print_vty(vty, attr->aspath);
9676
9677 /* Print origin */
9678 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9679 }
9680 }
9681 if (use_json) {
9682 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9683
9684 #if CONFDATE > 20231208
9685 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9686 #endif
9687 json_object_boolean_true_add(json_status, "*");
9688 json_object_boolean_true_add(json_status, ">");
9689 json_object_boolean_true_add(json_net, "valid");
9690 json_object_boolean_true_add(json_net, "best");
9691
9692 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9693 json_object_boolean_true_add(json_status, "=");
9694 json_object_boolean_true_add(json_net, "multipath");
9695 }
9696 json_object_object_add(json_net, "appliedStatusSymbols",
9697 json_status);
9698 json_object_object_addf(json_ar, json_net, "%pFX", p);
9699 } else
9700 vty_out(vty, "\n");
9701 }
9702
9703 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9704 struct bgp_path_info *path, int display, safi_t safi,
9705 json_object *json)
9706 {
9707 json_object *json_out = NULL;
9708 struct attr *attr;
9709 mpls_label_t label = MPLS_INVALID_LABEL;
9710
9711 if (!path->extra)
9712 return;
9713
9714 if (json)
9715 json_out = json_object_new_object();
9716
9717 /* short status lead text */
9718 route_vty_short_status_out(vty, path, p, json_out);
9719
9720 /* print prefix and mask */
9721 if (json == NULL) {
9722 if (!display)
9723 route_vty_out_route(path->net, p, vty, NULL, false);
9724 else
9725 vty_out(vty, "%*s", 17, " ");
9726 }
9727
9728 /* Print attribute */
9729 attr = path->attr;
9730 if (((p->family == AF_INET) &&
9731 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9732 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9733 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9734 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9735 || safi == SAFI_EVPN) {
9736 if (json)
9737 json_object_string_addf(
9738 json_out, "mpNexthopGlobalIn", "%pI4",
9739 &attr->mp_nexthop_global_in);
9740 else
9741 vty_out(vty, "%-16pI4",
9742 &attr->mp_nexthop_global_in);
9743 } else {
9744 if (json)
9745 json_object_string_addf(json_out, "nexthop",
9746 "%pI4", &attr->nexthop);
9747 else
9748 vty_out(vty, "%-16pI4", &attr->nexthop);
9749 }
9750 } else if (((p->family == AF_INET6) &&
9751 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9752 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9753 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9754 char buf_a[512];
9755
9756 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9757 if (json)
9758 json_object_string_addf(
9759 json_out, "mpNexthopGlobalIn", "%pI6",
9760 &attr->mp_nexthop_global);
9761 else
9762 vty_out(vty, "%s",
9763 inet_ntop(AF_INET6,
9764 &attr->mp_nexthop_global,
9765 buf_a, sizeof(buf_a)));
9766 } else if (attr->mp_nexthop_len
9767 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9768 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9769 &attr->mp_nexthop_global,
9770 &attr->mp_nexthop_local);
9771 if (json)
9772 json_object_string_add(json_out,
9773 "mpNexthopGlobalLocal",
9774 buf_a);
9775 else
9776 vty_out(vty, "%s", buf_a);
9777 }
9778 }
9779
9780 label = decode_label(&path->extra->label[0]);
9781
9782 if (bgp_is_valid_label(&label)) {
9783 if (json) {
9784 json_object_int_add(json_out, "notag", label);
9785 json_object_array_add(json, json_out);
9786 } else {
9787 vty_out(vty, "notag/%d", label);
9788 vty_out(vty, "\n");
9789 }
9790 } else if (!json)
9791 vty_out(vty, "\n");
9792 }
9793
9794 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9795 struct bgp_path_info *path, int display,
9796 json_object *json_paths)
9797 {
9798 struct attr *attr;
9799 json_object *json_path = NULL;
9800 json_object *json_nexthop = NULL;
9801 json_object *json_overlay = NULL;
9802
9803 if (!path->extra)
9804 return;
9805
9806 if (json_paths) {
9807 json_path = json_object_new_object();
9808 json_overlay = json_object_new_object();
9809 json_nexthop = json_object_new_object();
9810 }
9811
9812 /* short status lead text */
9813 route_vty_short_status_out(vty, path, p, json_path);
9814
9815 /* print prefix and mask */
9816 if (!display)
9817 route_vty_out_route(path->net, p, vty, json_path, false);
9818 else
9819 vty_out(vty, "%*s", 17, " ");
9820
9821 /* Print attribute */
9822 attr = path->attr;
9823 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9824
9825 switch (af) {
9826 case AF_INET:
9827 if (!json_path) {
9828 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9829 } else {
9830 json_object_string_addf(json_nexthop, "ip", "%pI4",
9831 &attr->mp_nexthop_global_in);
9832
9833 json_object_string_add(json_nexthop, "afi", "ipv4");
9834
9835 json_object_object_add(json_path, "nexthop",
9836 json_nexthop);
9837 }
9838 break;
9839 case AF_INET6:
9840 if (!json_path) {
9841 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9842 &attr->mp_nexthop_local);
9843 } else {
9844 json_object_string_addf(json_nexthop, "ipv6Global",
9845 "%pI6",
9846 &attr->mp_nexthop_global);
9847
9848 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9849 "%pI6",
9850 &attr->mp_nexthop_local);
9851
9852 json_object_string_add(json_nexthop, "afi", "ipv6");
9853
9854 json_object_object_add(json_path, "nexthop",
9855 json_nexthop);
9856 }
9857 break;
9858 default:
9859 if (!json_path) {
9860 vty_out(vty, "?");
9861 } else {
9862 json_object_string_add(json_nexthop, "error",
9863 "Unsupported address-family");
9864 }
9865 }
9866
9867 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9868
9869 if (!json_path)
9870 vty_out(vty, "/%pIA", &eo->gw_ip);
9871 else
9872 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9873
9874 if (bgp_attr_get_ecommunity(attr)) {
9875 char *mac = NULL;
9876 struct ecommunity_val *routermac = ecommunity_lookup(
9877 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9878 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9879
9880 if (routermac)
9881 mac = ecom_mac2str((char *)routermac->val);
9882 if (mac) {
9883 if (!json_path) {
9884 vty_out(vty, "/%s", mac);
9885 } else {
9886 json_object_string_add(json_overlay, "rmac",
9887 mac);
9888 }
9889 XFREE(MTYPE_TMP, mac);
9890 }
9891 }
9892
9893 if (!json_path) {
9894 vty_out(vty, "\n");
9895 } else {
9896 json_object_object_add(json_path, "overlay", json_overlay);
9897
9898 json_object_array_add(json_paths, json_path);
9899 }
9900 }
9901
9902 /* dampening route */
9903 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9904 struct bgp_path_info *path, int display,
9905 afi_t afi, safi_t safi, bool use_json,
9906 json_object *json_paths)
9907 {
9908 struct attr *attr = path->attr;
9909 int len;
9910 char timebuf[BGP_UPTIME_LEN];
9911 json_object *json_path = NULL;
9912
9913 if (use_json)
9914 json_path = json_object_new_object();
9915
9916 /* short status lead text */
9917 route_vty_short_status_out(vty, path, p, json_path);
9918
9919 /* print prefix and mask */
9920 if (!use_json) {
9921 if (!display)
9922 route_vty_out_route(path->net, p, vty, NULL, false);
9923 else
9924 vty_out(vty, "%*s", 17, " ");
9925
9926 len = vty_out(vty, "%s", path->peer->host);
9927 len = 17 - len;
9928
9929 if (len < 1)
9930 vty_out(vty, "\n%*s", 34, " ");
9931 else
9932 vty_out(vty, "%*s", len, " ");
9933
9934 vty_out(vty, "%s ",
9935 bgp_damp_reuse_time_vty(vty, path, timebuf,
9936 BGP_UPTIME_LEN, afi, safi,
9937 use_json, NULL));
9938
9939 if (attr->aspath)
9940 aspath_print_vty(vty, attr->aspath);
9941
9942 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9943
9944 vty_out(vty, "\n");
9945 } else {
9946 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9947 safi, use_json, json_path);
9948
9949 if (attr->aspath)
9950 json_object_string_add(json_path, "asPath",
9951 attr->aspath->str);
9952
9953 json_object_string_add(json_path, "origin",
9954 bgp_origin_str[attr->origin]);
9955 json_object_string_add(json_path, "peerHost", path->peer->host);
9956
9957 json_object_array_add(json_paths, json_path);
9958 }
9959 }
9960
9961 /* flap route */
9962 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9963 struct bgp_path_info *path, int display,
9964 afi_t afi, safi_t safi, bool use_json,
9965 json_object *json_paths)
9966 {
9967 struct attr *attr = path->attr;
9968 struct bgp_damp_info *bdi;
9969 char timebuf[BGP_UPTIME_LEN];
9970 int len;
9971 json_object *json_path = NULL;
9972
9973 if (!path->extra)
9974 return;
9975
9976 if (use_json)
9977 json_path = json_object_new_object();
9978
9979 bdi = path->extra->damp_info;
9980
9981 /* short status lead text */
9982 route_vty_short_status_out(vty, path, p, json_path);
9983
9984 if (!use_json) {
9985 if (!display)
9986 route_vty_out_route(path->net, p, vty, NULL, false);
9987 else
9988 vty_out(vty, "%*s", 17, " ");
9989
9990 len = vty_out(vty, "%s", path->peer->host);
9991 len = 16 - len;
9992 if (len < 1)
9993 vty_out(vty, "\n%*s", 33, " ");
9994 else
9995 vty_out(vty, "%*s", len, " ");
9996
9997 len = vty_out(vty, "%d", bdi->flap);
9998 len = 5 - len;
9999 if (len < 1)
10000 vty_out(vty, " ");
10001 else
10002 vty_out(vty, "%*s", len, " ");
10003
10004 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10005 BGP_UPTIME_LEN, 0, NULL));
10006
10007 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10008 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10009 vty_out(vty, "%s ",
10010 bgp_damp_reuse_time_vty(vty, path, timebuf,
10011 BGP_UPTIME_LEN, afi,
10012 safi, use_json, NULL));
10013 else
10014 vty_out(vty, "%*s ", 8, " ");
10015
10016 if (attr->aspath)
10017 aspath_print_vty(vty, attr->aspath);
10018
10019 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10020
10021 vty_out(vty, "\n");
10022 } else {
10023 json_object_string_add(json_path, "peerHost", path->peer->host);
10024 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10025
10026 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10027 json_path);
10028
10029 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10030 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10031 bgp_damp_reuse_time_vty(vty, path, timebuf,
10032 BGP_UPTIME_LEN, afi, safi,
10033 use_json, json_path);
10034
10035 if (attr->aspath)
10036 json_object_string_add(json_path, "asPath",
10037 attr->aspath->str);
10038
10039 json_object_string_add(json_path, "origin",
10040 bgp_origin_str[attr->origin]);
10041
10042 json_object_array_add(json_paths, json_path);
10043 }
10044 }
10045
10046 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10047 int *first, const char *header,
10048 json_object *json_adv_to)
10049 {
10050 json_object *json_peer = NULL;
10051
10052 if (json_adv_to) {
10053 /* 'advertised-to' is a dictionary of peers we have advertised
10054 * this
10055 * prefix too. The key is the peer's IP or swpX, the value is
10056 * the
10057 * hostname if we know it and "" if not.
10058 */
10059 json_peer = json_object_new_object();
10060
10061 if (peer->hostname)
10062 json_object_string_add(json_peer, "hostname",
10063 peer->hostname);
10064
10065 if (peer->conf_if)
10066 json_object_object_add(json_adv_to, peer->conf_if,
10067 json_peer);
10068 else
10069 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10070 &peer->su);
10071 } else {
10072 if (*first) {
10073 vty_out(vty, "%s", header);
10074 *first = 0;
10075 }
10076
10077 if (peer->hostname
10078 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10079 if (peer->conf_if)
10080 vty_out(vty, " %s(%s)", peer->hostname,
10081 peer->conf_if);
10082 else
10083 vty_out(vty, " %s(%pSU)", peer->hostname,
10084 &peer->su);
10085 } else {
10086 if (peer->conf_if)
10087 vty_out(vty, " %s", peer->conf_if);
10088 else
10089 vty_out(vty, " %pSU", &peer->su);
10090 }
10091 }
10092 }
10093
10094 static void route_vty_out_tx_ids(struct vty *vty,
10095 struct bgp_addpath_info_data *d)
10096 {
10097 int i;
10098
10099 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10100 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10101 d->addpath_tx_id[i],
10102 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10103 }
10104 }
10105
10106 static void route_vty_out_detail_es_info(struct vty *vty,
10107 struct bgp_path_info *pi,
10108 struct attr *attr,
10109 json_object *json_path)
10110 {
10111 char esi_buf[ESI_STR_LEN];
10112 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10113 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10114 ATTR_ES_PEER_ROUTER);
10115 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10116 ATTR_ES_PEER_ACTIVE);
10117 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10118 ATTR_ES_PEER_PROXY);
10119 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10120 if (json_path) {
10121 json_object *json_es_info = NULL;
10122
10123 json_object_string_add(
10124 json_path, "esi",
10125 esi_buf);
10126 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10127 json_es_info = json_object_new_object();
10128 if (es_local)
10129 json_object_boolean_true_add(
10130 json_es_info, "localEs");
10131 if (peer_active)
10132 json_object_boolean_true_add(
10133 json_es_info, "peerActive");
10134 if (peer_proxy)
10135 json_object_boolean_true_add(
10136 json_es_info, "peerProxy");
10137 if (peer_router)
10138 json_object_boolean_true_add(
10139 json_es_info, "peerRouter");
10140 if (attr->mm_sync_seqnum)
10141 json_object_int_add(
10142 json_es_info, "peerSeq",
10143 attr->mm_sync_seqnum);
10144 json_object_object_add(
10145 json_path, "es_info",
10146 json_es_info);
10147 }
10148 } else {
10149 if (bgp_evpn_attr_is_sync(attr))
10150 vty_out(vty,
10151 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10152 esi_buf,
10153 es_local ? "local-es":"",
10154 peer_proxy ? "proxy " : "",
10155 peer_active ? "active ":"",
10156 peer_router ? "router ":"",
10157 attr->mm_sync_seqnum);
10158 else
10159 vty_out(vty, " ESI %s %s\n",
10160 esi_buf,
10161 es_local ? "local-es":"");
10162 }
10163 }
10164
10165 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10166 const struct prefix *p, struct bgp_path_info *path,
10167 afi_t afi, safi_t safi,
10168 enum rpki_states rpki_curr_state,
10169 json_object *json_paths)
10170 {
10171 char buf[INET6_ADDRSTRLEN];
10172 char tag_buf[30];
10173 struct attr *attr = path->attr;
10174 time_t tbuf;
10175 json_object *json_bestpath = NULL;
10176 json_object *json_cluster_list = NULL;
10177 json_object *json_cluster_list_list = NULL;
10178 json_object *json_ext_community = NULL;
10179 json_object *json_last_update = NULL;
10180 json_object *json_pmsi = NULL;
10181 json_object *json_nexthop_global = NULL;
10182 json_object *json_nexthop_ll = NULL;
10183 json_object *json_nexthops = NULL;
10184 json_object *json_path = NULL;
10185 json_object *json_peer = NULL;
10186 json_object *json_string = NULL;
10187 json_object *json_adv_to = NULL;
10188 int first = 0;
10189 struct listnode *node, *nnode;
10190 struct peer *peer;
10191 bool addpath_capable;
10192 int has_adj;
10193 unsigned int first_as;
10194 bool nexthop_self =
10195 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10196 int i;
10197 char *nexthop_hostname =
10198 bgp_nexthop_hostname(path->peer, path->nexthop);
10199 uint32_t ttl = 0;
10200 uint32_t bos = 0;
10201 uint32_t exp = 0;
10202 mpls_label_t label = MPLS_INVALID_LABEL;
10203 tag_buf[0] = '\0';
10204 struct bgp_path_info *bpi_ultimate =
10205 bgp_get_imported_bpi_ultimate(path);
10206
10207 if (json_paths) {
10208 json_path = json_object_new_object();
10209 json_peer = json_object_new_object();
10210 json_nexthop_global = json_object_new_object();
10211 }
10212
10213 if (safi == SAFI_EVPN) {
10214 if (!json_paths)
10215 vty_out(vty, " Route %pFX", p);
10216 }
10217
10218 if (path->extra) {
10219 if (path->extra && path->extra->num_labels) {
10220 bgp_evpn_label2str(path->extra->label,
10221 path->extra->num_labels, tag_buf,
10222 sizeof(tag_buf));
10223 }
10224 if (safi == SAFI_EVPN) {
10225 if (!json_paths) {
10226 if (tag_buf[0] != '\0')
10227 vty_out(vty, " VNI %s", tag_buf);
10228 } else {
10229 if (tag_buf[0])
10230 json_object_string_add(json_path, "vni",
10231 tag_buf);
10232 }
10233 }
10234 }
10235
10236 if (safi == SAFI_EVPN
10237 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10238 char gwip_buf[INET6_ADDRSTRLEN];
10239
10240 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10241 sizeof(gwip_buf));
10242
10243 if (json_paths)
10244 json_object_string_add(json_path, "gatewayIP",
10245 gwip_buf);
10246 else
10247 vty_out(vty, " Gateway IP %s", gwip_buf);
10248 }
10249
10250 if (safi == SAFI_EVPN && !json_path)
10251 vty_out(vty, "\n");
10252
10253
10254 if (path->extra && path->extra->parent && !json_paths) {
10255 struct bgp_path_info *parent_ri;
10256 struct bgp_dest *dest, *pdest;
10257
10258 parent_ri = (struct bgp_path_info *)path->extra->parent;
10259 dest = parent_ri->net;
10260 if (dest && dest->pdest) {
10261 pdest = dest->pdest;
10262 if (is_pi_family_evpn(parent_ri)) {
10263 vty_out(vty, " Imported from ");
10264 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10265 (struct prefix_rd *)bgp_dest_get_prefix(
10266 pdest));
10267 vty_out(vty, ":%pFX, VNI %s",
10268 (struct prefix_evpn *)
10269 bgp_dest_get_prefix(dest),
10270 tag_buf);
10271 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10272 vty_out(vty, ", L3NHG %s",
10273 CHECK_FLAG(
10274 attr->es_flags,
10275 ATTR_ES_L3_NHG_ACTIVE)
10276 ? "active"
10277 : "inactive");
10278 vty_out(vty, "\n");
10279
10280 } else {
10281 vty_out(vty, " Imported from ");
10282 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10283 (struct prefix_rd *)bgp_dest_get_prefix(
10284 pdest));
10285 vty_out(vty, ":%pFX\n",
10286 (struct prefix_evpn *)
10287 bgp_dest_get_prefix(dest));
10288 }
10289 }
10290 }
10291
10292 /* Line1 display AS-path, Aggregator */
10293 if (attr->aspath) {
10294 if (json_paths) {
10295 if (!attr->aspath->json)
10296 aspath_str_update(attr->aspath, true);
10297 json_object_lock(attr->aspath->json);
10298 json_object_object_add(json_path, "aspath",
10299 attr->aspath->json);
10300 } else {
10301 if (attr->aspath->segments)
10302 vty_out(vty, " %s", attr->aspath->str);
10303 else
10304 vty_out(vty, " Local");
10305 }
10306 }
10307
10308 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10309 if (json_paths)
10310 json_object_boolean_true_add(json_path, "removed");
10311 else
10312 vty_out(vty, ", (removed)");
10313 }
10314
10315 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10316 if (json_paths)
10317 json_object_boolean_true_add(json_path, "stale");
10318 else
10319 vty_out(vty, ", (stale)");
10320 }
10321
10322 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10323 if (json_paths) {
10324 json_object_int_add(json_path, "aggregatorAs",
10325 attr->aggregator_as);
10326 json_object_string_addf(json_path, "aggregatorId",
10327 "%pI4", &attr->aggregator_addr);
10328 } else {
10329 vty_out(vty, ", (aggregated by %u %pI4)",
10330 attr->aggregator_as, &attr->aggregator_addr);
10331 }
10332 }
10333
10334 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10335 PEER_FLAG_REFLECTOR_CLIENT)) {
10336 if (json_paths)
10337 json_object_boolean_true_add(json_path,
10338 "rxedFromRrClient");
10339 else
10340 vty_out(vty, ", (Received from a RR-client)");
10341 }
10342
10343 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10344 PEER_FLAG_RSERVER_CLIENT)) {
10345 if (json_paths)
10346 json_object_boolean_true_add(json_path,
10347 "rxedFromRsClient");
10348 else
10349 vty_out(vty, ", (Received from a RS-client)");
10350 }
10351
10352 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10353 if (json_paths)
10354 json_object_boolean_true_add(json_path,
10355 "dampeningHistoryEntry");
10356 else
10357 vty_out(vty, ", (history entry)");
10358 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10359 if (json_paths)
10360 json_object_boolean_true_add(json_path,
10361 "dampeningSuppressed");
10362 else
10363 vty_out(vty, ", (suppressed due to dampening)");
10364 }
10365
10366 if (!json_paths)
10367 vty_out(vty, "\n");
10368
10369 /* Line2 display Next-hop, Neighbor, Router-id */
10370 /* Display the nexthop */
10371
10372 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10373 p->family == AF_EVPN) &&
10374 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10375 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10376 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10377 || safi == SAFI_EVPN) {
10378 if (json_paths) {
10379 json_object_string_addf(
10380 json_nexthop_global, "ip", "%pI4",
10381 &attr->mp_nexthop_global_in);
10382
10383 if (path->peer->hostname)
10384 json_object_string_add(
10385 json_nexthop_global, "hostname",
10386 path->peer->hostname);
10387 } else {
10388 if (nexthop_hostname)
10389 vty_out(vty, " %pI4(%s)",
10390 &attr->mp_nexthop_global_in,
10391 nexthop_hostname);
10392 else
10393 vty_out(vty, " %pI4",
10394 &attr->mp_nexthop_global_in);
10395 }
10396 } else {
10397 if (json_paths) {
10398 json_object_string_addf(json_nexthop_global,
10399 "ip", "%pI4",
10400 &attr->nexthop);
10401
10402 if (path->peer->hostname)
10403 json_object_string_add(
10404 json_nexthop_global, "hostname",
10405 path->peer->hostname);
10406 } else {
10407 if (nexthop_hostname)
10408 vty_out(vty, " %pI4(%s)",
10409 &attr->nexthop,
10410 nexthop_hostname);
10411 else
10412 vty_out(vty, " %pI4",
10413 &attr->nexthop);
10414 }
10415 }
10416
10417 if (json_paths)
10418 json_object_string_add(json_nexthop_global, "afi",
10419 "ipv4");
10420 } else {
10421 if (json_paths) {
10422 json_object_string_addf(json_nexthop_global, "ip",
10423 "%pI6",
10424 &attr->mp_nexthop_global);
10425
10426 if (path->peer->hostname)
10427 json_object_string_add(json_nexthop_global,
10428 "hostname",
10429 path->peer->hostname);
10430
10431 json_object_string_add(json_nexthop_global, "afi",
10432 "ipv6");
10433 json_object_string_add(json_nexthop_global, "scope",
10434 "global");
10435 } else {
10436 if (nexthop_hostname)
10437 vty_out(vty, " %pI6(%s)",
10438 &attr->mp_nexthop_global,
10439 nexthop_hostname);
10440 else
10441 vty_out(vty, " %pI6",
10442 &attr->mp_nexthop_global);
10443 }
10444 }
10445
10446 /* Display the IGP cost or 'inaccessible' */
10447 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10448 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10449
10450 if (json_paths) {
10451 json_object_boolean_false_add(json_nexthop_global,
10452 "accessible");
10453 json_object_boolean_add(json_nexthop_global,
10454 "importCheckEnabled", import);
10455 } else {
10456 vty_out(vty, " (inaccessible%s)",
10457 import ? ", import-check enabled" : "");
10458 }
10459 } else {
10460 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10461 if (json_paths)
10462 json_object_int_add(
10463 json_nexthop_global, "metric",
10464 bpi_ultimate->extra->igpmetric);
10465 else
10466 vty_out(vty, " (metric %u)",
10467 bpi_ultimate->extra->igpmetric);
10468 }
10469
10470 /* IGP cost is 0, display this only for json */
10471 else {
10472 if (json_paths)
10473 json_object_int_add(json_nexthop_global,
10474 "metric", 0);
10475 }
10476
10477 if (json_paths)
10478 json_object_boolean_true_add(json_nexthop_global,
10479 "accessible");
10480 }
10481
10482 /* Display peer "from" output */
10483 /* This path was originated locally */
10484 if (path->peer == bgp->peer_self) {
10485
10486 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10487 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10488 if (json_paths)
10489 json_object_string_add(json_peer, "peerId",
10490 "0.0.0.0");
10491 else
10492 vty_out(vty, " from 0.0.0.0 ");
10493 } else {
10494 if (json_paths)
10495 json_object_string_add(json_peer, "peerId",
10496 "::");
10497 else
10498 vty_out(vty, " from :: ");
10499 }
10500
10501 if (json_paths)
10502 json_object_string_addf(json_peer, "routerId", "%pI4",
10503 &bgp->router_id);
10504 else
10505 vty_out(vty, "(%pI4)", &bgp->router_id);
10506 }
10507
10508 /* We RXed this path from one of our peers */
10509 else {
10510
10511 if (json_paths) {
10512 json_object_string_addf(json_peer, "peerId", "%pSU",
10513 &path->peer->su);
10514 json_object_string_addf(json_peer, "routerId", "%pI4",
10515 &path->peer->remote_id);
10516
10517 if (path->peer->hostname)
10518 json_object_string_add(json_peer, "hostname",
10519 path->peer->hostname);
10520
10521 if (path->peer->domainname)
10522 json_object_string_add(json_peer, "domainname",
10523 path->peer->domainname);
10524
10525 if (path->peer->conf_if)
10526 json_object_string_add(json_peer, "interface",
10527 path->peer->conf_if);
10528 } else {
10529 if (path->peer->conf_if) {
10530 if (path->peer->hostname
10531 && CHECK_FLAG(path->peer->bgp->flags,
10532 BGP_FLAG_SHOW_HOSTNAME))
10533 vty_out(vty, " from %s(%s)",
10534 path->peer->hostname,
10535 path->peer->conf_if);
10536 else
10537 vty_out(vty, " from %s",
10538 path->peer->conf_if);
10539 } else {
10540 if (path->peer->hostname
10541 && CHECK_FLAG(path->peer->bgp->flags,
10542 BGP_FLAG_SHOW_HOSTNAME))
10543 vty_out(vty, " from %s(%s)",
10544 path->peer->hostname,
10545 path->peer->host);
10546 else
10547 vty_out(vty, " from %pSU",
10548 &path->peer->su);
10549 }
10550
10551 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10552 vty_out(vty, " (%pI4)", &attr->originator_id);
10553 else
10554 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10555 }
10556 }
10557
10558 /*
10559 * Note when vrfid of nexthop is different from that of prefix
10560 */
10561 if (path->extra && path->extra->bgp_orig) {
10562 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10563
10564 if (json_paths) {
10565 const char *vn;
10566
10567 if (path->extra->bgp_orig->inst_type
10568 == BGP_INSTANCE_TYPE_DEFAULT)
10569 vn = VRF_DEFAULT_NAME;
10570 else
10571 vn = path->extra->bgp_orig->name;
10572
10573 json_object_string_add(json_path, "nhVrfName", vn);
10574
10575 if (nexthop_vrfid == VRF_UNKNOWN) {
10576 json_object_int_add(json_path, "nhVrfId", -1);
10577 } else {
10578 json_object_int_add(json_path, "nhVrfId",
10579 (int)nexthop_vrfid);
10580 }
10581 } else {
10582 if (nexthop_vrfid == VRF_UNKNOWN)
10583 vty_out(vty, " vrf ?");
10584 else {
10585 struct vrf *vrf;
10586
10587 vrf = vrf_lookup_by_id(nexthop_vrfid);
10588 vty_out(vty, " vrf %s(%u)",
10589 VRF_LOGNAME(vrf), nexthop_vrfid);
10590 }
10591 }
10592 }
10593
10594 if (nexthop_self) {
10595 if (json_paths) {
10596 json_object_boolean_true_add(json_path,
10597 "announceNexthopSelf");
10598 } else {
10599 vty_out(vty, " announce-nh-self");
10600 }
10601 }
10602
10603 if (!json_paths)
10604 vty_out(vty, "\n");
10605
10606 /* display the link-local nexthop */
10607 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10608 if (json_paths) {
10609 json_nexthop_ll = json_object_new_object();
10610 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10611 &attr->mp_nexthop_local);
10612
10613 if (path->peer->hostname)
10614 json_object_string_add(json_nexthop_ll,
10615 "hostname",
10616 path->peer->hostname);
10617
10618 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10619 json_object_string_add(json_nexthop_ll, "scope",
10620 "link-local");
10621
10622 json_object_boolean_true_add(json_nexthop_ll,
10623 "accessible");
10624
10625 if (!attr->mp_nexthop_prefer_global)
10626 json_object_boolean_true_add(json_nexthop_ll,
10627 "used");
10628 else
10629 json_object_boolean_true_add(
10630 json_nexthop_global, "used");
10631 } else {
10632 vty_out(vty, " (%s) %s\n",
10633 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10634 buf, INET6_ADDRSTRLEN),
10635 attr->mp_nexthop_prefer_global
10636 ? "(prefer-global)"
10637 : "(used)");
10638 }
10639 }
10640 /* If we do not have a link-local nexthop then we must flag the
10641 global as "used" */
10642 else {
10643 if (json_paths)
10644 json_object_boolean_true_add(json_nexthop_global,
10645 "used");
10646 }
10647
10648 if (safi == SAFI_EVPN &&
10649 bgp_evpn_is_esi_valid(&attr->esi)) {
10650 route_vty_out_detail_es_info(vty, path, attr, json_path);
10651 }
10652
10653 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10654 * Int/Ext/Local, Atomic, best */
10655 if (json_paths)
10656 json_object_string_add(json_path, "origin",
10657 bgp_origin_long_str[attr->origin]);
10658 else
10659 vty_out(vty, " Origin %s",
10660 bgp_origin_long_str[attr->origin]);
10661
10662 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10663 if (json_paths)
10664 json_object_int_add(json_path, "metric", attr->med);
10665 else
10666 vty_out(vty, ", metric %u", attr->med);
10667 }
10668
10669 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10670 if (json_paths)
10671 json_object_int_add(json_path, "locPrf",
10672 attr->local_pref);
10673 else
10674 vty_out(vty, ", localpref %u", attr->local_pref);
10675 }
10676
10677 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10678 if (json_paths)
10679 json_object_int_add(json_path, "aigpMetric",
10680 bgp_attr_get_aigp_metric(attr));
10681 else
10682 vty_out(vty, ", aigp-metric %" PRIu64,
10683 bgp_attr_get_aigp_metric(attr));
10684 }
10685
10686 if (attr->weight != 0) {
10687 if (json_paths)
10688 json_object_int_add(json_path, "weight", attr->weight);
10689 else
10690 vty_out(vty, ", weight %u", attr->weight);
10691 }
10692
10693 if (attr->tag != 0) {
10694 if (json_paths)
10695 json_object_int_add(json_path, "tag", attr->tag);
10696 else
10697 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10698 }
10699
10700 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10701 if (json_paths)
10702 json_object_boolean_false_add(json_path, "valid");
10703 else
10704 vty_out(vty, ", invalid");
10705 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10706 if (json_paths)
10707 json_object_boolean_true_add(json_path, "valid");
10708 else
10709 vty_out(vty, ", valid");
10710 }
10711
10712 if (json_paths)
10713 json_object_int_add(json_path, "version", bn->version);
10714
10715 if (path->peer != bgp->peer_self) {
10716 if (path->peer->as == path->peer->local_as) {
10717 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10718 if (json_paths)
10719 json_object_string_add(
10720 json_peer, "type",
10721 "confed-internal");
10722 else
10723 vty_out(vty, ", confed-internal");
10724 } else {
10725 if (json_paths)
10726 json_object_string_add(
10727 json_peer, "type", "internal");
10728 else
10729 vty_out(vty, ", internal");
10730 }
10731 } else {
10732 if (bgp_confederation_peers_check(bgp,
10733 path->peer->as)) {
10734 if (json_paths)
10735 json_object_string_add(
10736 json_peer, "type",
10737 "confed-external");
10738 else
10739 vty_out(vty, ", confed-external");
10740 } else {
10741 if (json_paths)
10742 json_object_string_add(
10743 json_peer, "type", "external");
10744 else
10745 vty_out(vty, ", external");
10746 }
10747 }
10748 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10749 if (json_paths) {
10750 json_object_boolean_true_add(json_path, "aggregated");
10751 json_object_boolean_true_add(json_path, "local");
10752 } else {
10753 vty_out(vty, ", aggregated, local");
10754 }
10755 } else if (path->type != ZEBRA_ROUTE_BGP) {
10756 if (json_paths)
10757 json_object_boolean_true_add(json_path, "sourced");
10758 else
10759 vty_out(vty, ", sourced");
10760 } else {
10761 if (json_paths) {
10762 json_object_boolean_true_add(json_path, "sourced");
10763 json_object_boolean_true_add(json_path, "local");
10764 } else {
10765 vty_out(vty, ", sourced, local");
10766 }
10767 }
10768
10769 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10770 if (json_paths)
10771 json_object_boolean_true_add(json_path,
10772 "atomicAggregate");
10773 else
10774 vty_out(vty, ", atomic-aggregate");
10775 }
10776
10777 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10778 if (json_paths)
10779 json_object_int_add(json_path, "otc", attr->otc);
10780 else
10781 vty_out(vty, ", otc %u", attr->otc);
10782 }
10783
10784 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10785 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10786 && bgp_path_info_mpath_count(path))) {
10787 if (json_paths)
10788 json_object_boolean_true_add(json_path, "multipath");
10789 else
10790 vty_out(vty, ", multipath");
10791 }
10792
10793 // Mark the bestpath(s)
10794 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10795 first_as = aspath_get_first_as(attr->aspath);
10796
10797 if (json_paths) {
10798 if (!json_bestpath)
10799 json_bestpath = json_object_new_object();
10800 json_object_int_add(json_bestpath, "bestpathFromAs",
10801 first_as);
10802 } else {
10803 if (first_as)
10804 vty_out(vty, ", bestpath-from-AS %u", first_as);
10805 else
10806 vty_out(vty, ", bestpath-from-AS Local");
10807 }
10808 }
10809
10810 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10811 if (json_paths) {
10812 if (!json_bestpath)
10813 json_bestpath = json_object_new_object();
10814 json_object_boolean_true_add(json_bestpath, "overall");
10815 json_object_string_add(
10816 json_bestpath, "selectionReason",
10817 bgp_path_selection_reason2str(bn->reason));
10818 } else {
10819 vty_out(vty, ", best");
10820 vty_out(vty, " (%s)",
10821 bgp_path_selection_reason2str(bn->reason));
10822 }
10823 }
10824
10825 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10826 if (json_paths)
10827 json_object_string_add(
10828 json_path, "rpkiValidationState",
10829 bgp_rpki_validation2str(rpki_curr_state));
10830 else
10831 vty_out(vty, ", rpki validation-state: %s",
10832 bgp_rpki_validation2str(rpki_curr_state));
10833 }
10834
10835 if (json_bestpath)
10836 json_object_object_add(json_path, "bestpath", json_bestpath);
10837
10838 if (!json_paths)
10839 vty_out(vty, "\n");
10840
10841 /* Line 4 display Community */
10842 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10843 if (json_paths) {
10844 if (!bgp_attr_get_community(attr)->json)
10845 community_str(bgp_attr_get_community(attr),
10846 true, true);
10847 json_object_lock(bgp_attr_get_community(attr)->json);
10848 json_object_object_add(
10849 json_path, "community",
10850 bgp_attr_get_community(attr)->json);
10851 } else {
10852 vty_out(vty, " Community: %s\n",
10853 bgp_attr_get_community(attr)->str);
10854 }
10855 }
10856
10857 /* Line 5 display Extended-community */
10858 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10859 if (json_paths) {
10860 json_ext_community = json_object_new_object();
10861 json_object_string_add(
10862 json_ext_community, "string",
10863 bgp_attr_get_ecommunity(attr)->str);
10864 json_object_object_add(json_path, "extendedCommunity",
10865 json_ext_community);
10866 } else {
10867 vty_out(vty, " Extended Community: %s\n",
10868 bgp_attr_get_ecommunity(attr)->str);
10869 }
10870 }
10871
10872 /* Line 6 display Large community */
10873 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10874 if (json_paths) {
10875 if (!bgp_attr_get_lcommunity(attr)->json)
10876 lcommunity_str(bgp_attr_get_lcommunity(attr),
10877 true, true);
10878 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10879 json_object_object_add(
10880 json_path, "largeCommunity",
10881 bgp_attr_get_lcommunity(attr)->json);
10882 } else {
10883 vty_out(vty, " Large Community: %s\n",
10884 bgp_attr_get_lcommunity(attr)->str);
10885 }
10886 }
10887
10888 /* Line 7 display Originator, Cluster-id */
10889 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10890 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10891 char buf[BUFSIZ] = {0};
10892
10893 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10894 if (json_paths)
10895 json_object_string_addf(json_path,
10896 "originatorId", "%pI4",
10897 &attr->originator_id);
10898 else
10899 vty_out(vty, " Originator: %pI4",
10900 &attr->originator_id);
10901 }
10902
10903 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10904 struct cluster_list *cluster =
10905 bgp_attr_get_cluster(attr);
10906 int i;
10907
10908 if (json_paths) {
10909 json_cluster_list = json_object_new_object();
10910 json_cluster_list_list =
10911 json_object_new_array();
10912
10913 for (i = 0; i < cluster->length / 4; i++) {
10914 json_string = json_object_new_string(
10915 inet_ntop(AF_INET,
10916 &cluster->list[i],
10917 buf, sizeof(buf)));
10918 json_object_array_add(
10919 json_cluster_list_list,
10920 json_string);
10921 }
10922
10923 /*
10924 * struct cluster_list does not have
10925 * "str" variable like aspath and community
10926 * do. Add this someday if someone asks
10927 * for it.
10928 * json_object_string_add(json_cluster_list,
10929 * "string", cluster->str);
10930 */
10931 json_object_object_add(json_cluster_list,
10932 "list",
10933 json_cluster_list_list);
10934 json_object_object_add(json_path, "clusterList",
10935 json_cluster_list);
10936 } else {
10937 vty_out(vty, ", Cluster list: ");
10938
10939 for (i = 0; i < cluster->length / 4; i++) {
10940 vty_out(vty, "%pI4 ",
10941 &cluster->list[i]);
10942 }
10943 }
10944 }
10945
10946 if (!json_paths)
10947 vty_out(vty, "\n");
10948 }
10949
10950 if (path->extra && path->extra->damp_info)
10951 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10952
10953 /* Remote Label */
10954 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10955 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10956 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10957 &bos);
10958
10959 if (json_paths)
10960 json_object_int_add(json_path, "remoteLabel", label);
10961 else
10962 vty_out(vty, " Remote label: %d\n", label);
10963 }
10964
10965 /* Remote SID */
10966 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10967 if (json_paths)
10968 json_object_string_addf(json_path, "remoteSid", "%pI6",
10969 &path->extra->sid[0].sid);
10970 else
10971 vty_out(vty, " Remote SID: %pI6\n",
10972 &path->extra->sid[0].sid);
10973 }
10974
10975 /* Label Index */
10976 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10977 if (json_paths)
10978 json_object_int_add(json_path, "labelIndex",
10979 attr->label_index);
10980 else
10981 vty_out(vty, " Label Index: %d\n",
10982 attr->label_index);
10983 }
10984
10985 /* Line 8 display Addpath IDs */
10986 if (path->addpath_rx_id
10987 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10988 if (json_paths) {
10989 json_object_int_add(json_path, "addpathRxId",
10990 path->addpath_rx_id);
10991
10992 /* Keep backwards compatibility with the old API
10993 * by putting TX All's ID in the old field
10994 */
10995 json_object_int_add(
10996 json_path, "addpathTxId",
10997 path->tx_addpath
10998 .addpath_tx_id[BGP_ADDPATH_ALL]);
10999
11000 /* ... but create a specific field for each
11001 * strategy
11002 */
11003 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11004 json_object_int_add(
11005 json_path,
11006 bgp_addpath_names(i)->id_json_name,
11007 path->tx_addpath.addpath_tx_id[i]);
11008 }
11009 } else {
11010 vty_out(vty, " AddPath ID: RX %u, ",
11011 path->addpath_rx_id);
11012
11013 route_vty_out_tx_ids(vty, &path->tx_addpath);
11014 }
11015 }
11016
11017 /* If we used addpath to TX a non-bestpath we need to display
11018 * "Advertised to" on a path-by-path basis
11019 */
11020 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11021 first = 1;
11022
11023 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11024 addpath_capable =
11025 bgp_addpath_encode_tx(peer, afi, safi);
11026 has_adj = bgp_adj_out_lookup(
11027 peer, path->net,
11028 bgp_addpath_id_for_peer(peer, afi, safi,
11029 &path->tx_addpath));
11030
11031 if ((addpath_capable && has_adj)
11032 || (!addpath_capable && has_adj
11033 && CHECK_FLAG(path->flags,
11034 BGP_PATH_SELECTED))) {
11035 if (json_path && !json_adv_to)
11036 json_adv_to = json_object_new_object();
11037
11038 route_vty_out_advertised_to(
11039 vty, peer, &first,
11040 " Advertised to:", json_adv_to);
11041 }
11042 }
11043
11044 if (json_path) {
11045 if (json_adv_to) {
11046 json_object_object_add(
11047 json_path, "advertisedTo", json_adv_to);
11048 }
11049 } else {
11050 if (!first) {
11051 vty_out(vty, "\n");
11052 }
11053 }
11054 }
11055
11056 /* Line 9 display Uptime */
11057 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11058 if (json_paths) {
11059 json_last_update = json_object_new_object();
11060 json_object_int_add(json_last_update, "epoch", tbuf);
11061 json_object_string_add(json_last_update, "string",
11062 ctime(&tbuf));
11063 json_object_object_add(json_path, "lastUpdate",
11064 json_last_update);
11065 } else
11066 vty_out(vty, " Last update: %s", ctime(&tbuf));
11067
11068 /* Line 10 display PMSI tunnel attribute, if present */
11069 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11070 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11071 bgp_attr_get_pmsi_tnl_type(attr),
11072 PMSI_TNLTYPE_STR_DEFAULT);
11073
11074 if (json_paths) {
11075 json_pmsi = json_object_new_object();
11076 json_object_string_add(json_pmsi, "tunnelType", str);
11077 json_object_int_add(json_pmsi, "label",
11078 label2vni(&attr->label));
11079 json_object_object_add(json_path, "pmsi", json_pmsi);
11080 } else
11081 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11082 str, label2vni(&attr->label));
11083 }
11084
11085 if (path->peer->t_gr_restart &&
11086 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11087 unsigned long gr_remaining =
11088 thread_timer_remain_second(path->peer->t_gr_restart);
11089
11090 if (json_paths) {
11091 json_object_int_add(json_path,
11092 "gracefulRestartSecondsRemaining",
11093 gr_remaining);
11094 } else
11095 vty_out(vty,
11096 " Time until Graceful Restart stale route deleted: %lu\n",
11097 gr_remaining);
11098 }
11099
11100 if (path->peer->t_llgr_stale[afi][safi] &&
11101 bgp_attr_get_community(attr) &&
11102 community_include(bgp_attr_get_community(attr),
11103 COMMUNITY_LLGR_STALE)) {
11104 unsigned long llgr_remaining = thread_timer_remain_second(
11105 path->peer->t_llgr_stale[afi][safi]);
11106
11107 if (json_paths) {
11108 json_object_int_add(json_path, "llgrSecondsRemaining",
11109 llgr_remaining);
11110 } else
11111 vty_out(vty,
11112 " Time until Long-lived stale route deleted: %lu\n",
11113 llgr_remaining);
11114 }
11115
11116 /* Output some debug about internal state of the dest flags */
11117 if (json_paths) {
11118 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11119 json_object_boolean_true_add(json_path, "processScheduled");
11120 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11121 json_object_boolean_true_add(json_path, "userCleared");
11122 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11123 json_object_boolean_true_add(json_path, "labelChanged");
11124 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11125 json_object_boolean_true_add(json_path, "registeredForLabel");
11126 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11127 json_object_boolean_true_add(json_path, "selectDefered");
11128 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11129 json_object_boolean_true_add(json_path, "fibInstalled");
11130 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11131 json_object_boolean_true_add(json_path, "fibPending");
11132
11133 if (json_nexthop_global || json_nexthop_ll) {
11134 json_nexthops = json_object_new_array();
11135
11136 if (json_nexthop_global)
11137 json_object_array_add(json_nexthops,
11138 json_nexthop_global);
11139
11140 if (json_nexthop_ll)
11141 json_object_array_add(json_nexthops,
11142 json_nexthop_ll);
11143
11144 json_object_object_add(json_path, "nexthops",
11145 json_nexthops);
11146 }
11147
11148 json_object_object_add(json_path, "peer", json_peer);
11149 json_object_array_add(json_paths, json_path);
11150 }
11151 }
11152
11153 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11154 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11155 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11156
11157 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11158 afi_t afi, safi_t safi, enum bgp_show_type type,
11159 bool use_json);
11160 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11161 const char *comstr, int exact, afi_t afi,
11162 safi_t safi, uint16_t show_flags);
11163
11164 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11165 struct bgp_table *table, enum bgp_show_type type,
11166 void *output_arg, const char *rd, int is_last,
11167 unsigned long *output_cum, unsigned long *total_cum,
11168 unsigned long *json_header_depth, uint16_t show_flags,
11169 enum rpki_states rpki_target_state)
11170 {
11171 struct bgp_path_info *pi;
11172 struct bgp_dest *dest;
11173 bool header = true;
11174 bool json_detail_header = false;
11175 int display;
11176 unsigned long output_count = 0;
11177 unsigned long total_count = 0;
11178 struct prefix *p;
11179 json_object *json_paths = NULL;
11180 int first = 1;
11181 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11182 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11183 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11184 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11185 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11186
11187 if (output_cum && *output_cum != 0)
11188 header = false;
11189
11190 if (use_json && !*json_header_depth) {
11191 if (all)
11192 *json_header_depth = 1;
11193 else {
11194 vty_out(vty, "{\n");
11195 *json_header_depth = 2;
11196 }
11197 vty_out(vty,
11198 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11199 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11200 " \"localAS\": ",
11201 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11202 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11203 ? VRF_DEFAULT_NAME
11204 : bgp->name,
11205 table->version, &bgp->router_id,
11206 bgp->default_local_pref);
11207 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11208 ((bgp->asnotation == ASNOTATION_DOT) &&
11209 (bgp->as < UINT16_MAX)))
11210 vty_out(vty, "%u", bgp->as);
11211 else {
11212 vty_out(vty, "\"");
11213 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11214 vty_out(vty, "\"");
11215 }
11216 vty_out(vty, ",\n \"routes\": { ");
11217 if (rd) {
11218 vty_out(vty, " \"routeDistinguishers\" : {");
11219 ++*json_header_depth;
11220 }
11221 }
11222
11223 if (use_json && rd) {
11224 vty_out(vty, " \"%s\" : { ", rd);
11225 }
11226
11227 /* Check for 'json detail', where we need header output once per dest */
11228 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11229 type != bgp_show_type_damp_neighbor &&
11230 type != bgp_show_type_flap_statistics &&
11231 type != bgp_show_type_flap_neighbor)
11232 json_detail_header = true;
11233
11234 /* Start processing of routes. */
11235 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11236 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11237 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11238 bool json_detail_header_used = false;
11239
11240 pi = bgp_dest_get_bgp_path_info(dest);
11241 if (pi == NULL)
11242 continue;
11243
11244 display = 0;
11245 if (use_json)
11246 json_paths = json_object_new_array();
11247 else
11248 json_paths = NULL;
11249
11250 for (; pi; pi = pi->next) {
11251 struct community *picomm = NULL;
11252
11253 picomm = bgp_attr_get_community(pi->attr);
11254
11255 total_count++;
11256
11257 if (type == bgp_show_type_prefix_version) {
11258 uint32_t version =
11259 strtoul(output_arg, NULL, 10);
11260 if (dest->version < version)
11261 continue;
11262 }
11263
11264 if (type == bgp_show_type_community_alias) {
11265 char *alias = output_arg;
11266 char **communities;
11267 int num;
11268 bool found = false;
11269
11270 if (picomm) {
11271 frrstr_split(picomm->str, " ",
11272 &communities, &num);
11273 for (int i = 0; i < num; i++) {
11274 const char *com2alias =
11275 bgp_community2alias(
11276 communities[i]);
11277 if (!found
11278 && strcmp(alias, com2alias)
11279 == 0)
11280 found = true;
11281 XFREE(MTYPE_TMP,
11282 communities[i]);
11283 }
11284 XFREE(MTYPE_TMP, communities);
11285 }
11286
11287 if (!found &&
11288 bgp_attr_get_lcommunity(pi->attr)) {
11289 frrstr_split(bgp_attr_get_lcommunity(
11290 pi->attr)
11291 ->str,
11292 " ", &communities, &num);
11293 for (int i = 0; i < num; i++) {
11294 const char *com2alias =
11295 bgp_community2alias(
11296 communities[i]);
11297 if (!found
11298 && strcmp(alias, com2alias)
11299 == 0)
11300 found = true;
11301 XFREE(MTYPE_TMP,
11302 communities[i]);
11303 }
11304 XFREE(MTYPE_TMP, communities);
11305 }
11306
11307 if (!found)
11308 continue;
11309 }
11310
11311 if (type == bgp_show_type_rpki) {
11312 if (dest_p->family == AF_INET
11313 || dest_p->family == AF_INET6)
11314 rpki_curr_state = hook_call(
11315 bgp_rpki_prefix_status,
11316 pi->peer, pi->attr, dest_p);
11317 if (rpki_target_state != RPKI_NOT_BEING_USED
11318 && rpki_curr_state != rpki_target_state)
11319 continue;
11320 }
11321
11322 if (type == bgp_show_type_flap_statistics
11323 || type == bgp_show_type_flap_neighbor
11324 || type == bgp_show_type_dampend_paths
11325 || type == bgp_show_type_damp_neighbor) {
11326 if (!(pi->extra && pi->extra->damp_info))
11327 continue;
11328 }
11329 if (type == bgp_show_type_regexp) {
11330 regex_t *regex = output_arg;
11331
11332 if (bgp_regexec(regex, pi->attr->aspath)
11333 == REG_NOMATCH)
11334 continue;
11335 }
11336 if (type == bgp_show_type_prefix_list) {
11337 struct prefix_list *plist = output_arg;
11338
11339 if (prefix_list_apply(plist, dest_p)
11340 != PREFIX_PERMIT)
11341 continue;
11342 }
11343 if (type == bgp_show_type_access_list) {
11344 struct access_list *alist = output_arg;
11345
11346 if (access_list_apply(alist, dest_p) !=
11347 FILTER_PERMIT)
11348 continue;
11349 }
11350 if (type == bgp_show_type_filter_list) {
11351 struct as_list *as_list = output_arg;
11352
11353 if (as_list_apply(as_list, pi->attr->aspath)
11354 != AS_FILTER_PERMIT)
11355 continue;
11356 }
11357 if (type == bgp_show_type_route_map) {
11358 struct route_map *rmap = output_arg;
11359 struct bgp_path_info path;
11360 struct bgp_path_info_extra extra;
11361 struct attr dummy_attr = {};
11362 route_map_result_t ret;
11363
11364 dummy_attr = *pi->attr;
11365
11366 prep_for_rmap_apply(&path, &extra, dest, pi,
11367 pi->peer, &dummy_attr);
11368
11369 ret = route_map_apply(rmap, dest_p, &path);
11370 bgp_attr_flush(&dummy_attr);
11371 if (ret == RMAP_DENYMATCH)
11372 continue;
11373 }
11374 if (type == bgp_show_type_neighbor
11375 || type == bgp_show_type_flap_neighbor
11376 || type == bgp_show_type_damp_neighbor) {
11377 union sockunion *su = output_arg;
11378
11379 if (pi->peer == NULL
11380 || pi->peer->su_remote == NULL
11381 || !sockunion_same(pi->peer->su_remote, su))
11382 continue;
11383 }
11384 if (type == bgp_show_type_cidr_only) {
11385 uint32_t destination;
11386
11387 destination = ntohl(dest_p->u.prefix4.s_addr);
11388 if (IN_CLASSC(destination)
11389 && dest_p->prefixlen == 24)
11390 continue;
11391 if (IN_CLASSB(destination)
11392 && dest_p->prefixlen == 16)
11393 continue;
11394 if (IN_CLASSA(destination)
11395 && dest_p->prefixlen == 8)
11396 continue;
11397 }
11398 if (type == bgp_show_type_prefix_longer) {
11399 p = output_arg;
11400 if (!prefix_match(p, dest_p))
11401 continue;
11402 }
11403 if (type == bgp_show_type_community_all) {
11404 if (!picomm)
11405 continue;
11406 }
11407 if (type == bgp_show_type_community) {
11408 struct community *com = output_arg;
11409
11410 if (!picomm || !community_match(picomm, com))
11411 continue;
11412 }
11413 if (type == bgp_show_type_community_exact) {
11414 struct community *com = output_arg;
11415
11416 if (!picomm || !community_cmp(picomm, com))
11417 continue;
11418 }
11419 if (type == bgp_show_type_community_list) {
11420 struct community_list *list = output_arg;
11421
11422 if (!community_list_match(picomm, list))
11423 continue;
11424 }
11425 if (type == bgp_show_type_community_list_exact) {
11426 struct community_list *list = output_arg;
11427
11428 if (!community_list_exact_match(picomm, list))
11429 continue;
11430 }
11431 if (type == bgp_show_type_lcommunity) {
11432 struct lcommunity *lcom = output_arg;
11433
11434 if (!bgp_attr_get_lcommunity(pi->attr) ||
11435 !lcommunity_match(
11436 bgp_attr_get_lcommunity(pi->attr),
11437 lcom))
11438 continue;
11439 }
11440
11441 if (type == bgp_show_type_lcommunity_exact) {
11442 struct lcommunity *lcom = output_arg;
11443
11444 if (!bgp_attr_get_lcommunity(pi->attr) ||
11445 !lcommunity_cmp(
11446 bgp_attr_get_lcommunity(pi->attr),
11447 lcom))
11448 continue;
11449 }
11450 if (type == bgp_show_type_lcommunity_list) {
11451 struct community_list *list = output_arg;
11452
11453 if (!lcommunity_list_match(
11454 bgp_attr_get_lcommunity(pi->attr),
11455 list))
11456 continue;
11457 }
11458 if (type
11459 == bgp_show_type_lcommunity_list_exact) {
11460 struct community_list *list = output_arg;
11461
11462 if (!lcommunity_list_exact_match(
11463 bgp_attr_get_lcommunity(pi->attr),
11464 list))
11465 continue;
11466 }
11467 if (type == bgp_show_type_lcommunity_all) {
11468 if (!bgp_attr_get_lcommunity(pi->attr))
11469 continue;
11470 }
11471 if (type == bgp_show_type_dampend_paths
11472 || type == bgp_show_type_damp_neighbor) {
11473 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11474 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11475 continue;
11476 }
11477 if (type == bgp_show_type_self_originated) {
11478 if (pi->peer != bgp->peer_self)
11479 continue;
11480 }
11481
11482 if (!use_json && header) {
11483 vty_out(vty,
11484 "BGP table version is %" PRIu64
11485 ", local router ID is %pI4, vrf id ",
11486 table->version, &bgp->router_id);
11487 if (bgp->vrf_id == VRF_UNKNOWN)
11488 vty_out(vty, "%s", VRFID_NONE_STR);
11489 else
11490 vty_out(vty, "%u", bgp->vrf_id);
11491 vty_out(vty, "\n");
11492 vty_out(vty, "Default local pref %u, ",
11493 bgp->default_local_pref);
11494 vty_out(vty, "local AS ");
11495 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11496 &bgp->as);
11497 vty_out(vty, "\n");
11498 if (!detail_routes) {
11499 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11500 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11501 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11502 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11503 }
11504 if (type == bgp_show_type_dampend_paths
11505 || type == bgp_show_type_damp_neighbor)
11506 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11507 else if (type == bgp_show_type_flap_statistics
11508 || type == bgp_show_type_flap_neighbor)
11509 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11510 else if (!detail_routes)
11511 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11512 : BGP_SHOW_HEADER));
11513 header = false;
11514
11515 }
11516 if (rd != NULL && !display && !output_count) {
11517 if (!use_json)
11518 vty_out(vty,
11519 "Route Distinguisher: %s\n",
11520 rd);
11521 }
11522 if (type == bgp_show_type_dampend_paths
11523 || type == bgp_show_type_damp_neighbor)
11524 damp_route_vty_out(vty, dest_p, pi, display,
11525 AFI_IP, safi, use_json,
11526 json_paths);
11527 else if (type == bgp_show_type_flap_statistics
11528 || type == bgp_show_type_flap_neighbor)
11529 flap_route_vty_out(vty, dest_p, pi, display,
11530 AFI_IP, safi, use_json,
11531 json_paths);
11532 else {
11533 if (detail_routes || detail_json) {
11534 const struct prefix_rd *prd = NULL;
11535
11536 if (dest->pdest)
11537 prd = bgp_rd_from_dest(
11538 dest->pdest, safi);
11539
11540 if (!use_json)
11541 route_vty_out_detail_header(
11542 vty, bgp, dest,
11543 bgp_dest_get_prefix(
11544 dest),
11545 prd, table->afi, safi,
11546 NULL, false);
11547
11548 route_vty_out_detail(
11549 vty, bgp, dest, dest_p, pi,
11550 family2afi(dest_p->family),
11551 safi, RPKI_NOT_BEING_USED,
11552 json_paths);
11553 } else {
11554 route_vty_out(vty, dest_p, pi, display,
11555 safi, json_paths, wide);
11556 }
11557 }
11558 display++;
11559 }
11560
11561 if (display) {
11562 output_count++;
11563 if (!use_json)
11564 continue;
11565
11566 /* encode prefix */
11567 if (dest_p->family == AF_FLOWSPEC) {
11568 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11569
11570
11571 bgp_fs_nlri_get_string(
11572 (unsigned char *)
11573 dest_p->u.prefix_flowspec.ptr,
11574 dest_p->u.prefix_flowspec.prefixlen,
11575 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11576 family2afi(dest_p->u
11577 .prefix_flowspec.family));
11578 if (first)
11579 vty_out(vty, "\"%s/%d\": ", retstr,
11580 dest_p->u.prefix_flowspec
11581 .prefixlen);
11582 else
11583 vty_out(vty, ",\"%s/%d\": ", retstr,
11584 dest_p->u.prefix_flowspec
11585 .prefixlen);
11586 } else {
11587 if (first)
11588 vty_out(vty, "\"%pFX\": ", dest_p);
11589 else
11590 vty_out(vty, ",\"%pFX\": ", dest_p);
11591 }
11592
11593 if (json_detail_header && json_paths != NULL) {
11594 const struct prefix_rd *prd;
11595
11596 vty_out(vty, "{\n");
11597
11598 prd = bgp_rd_from_dest(dest, safi);
11599
11600 route_vty_out_detail_header(
11601 vty, bgp, dest,
11602 bgp_dest_get_prefix(dest), prd,
11603 table->afi, safi, json_paths, true);
11604
11605 vty_out(vty, "\"paths\": ");
11606 json_detail_header_used = true;
11607 }
11608
11609 /*
11610 * We are using no_pretty here because under
11611 * extremely high settings( say lots and lots of
11612 * routes with lots and lots of ways to reach
11613 * that route via different paths ) this can
11614 * save several minutes of output when FRR
11615 * is run on older cpu's or more underperforming
11616 * routers out there
11617 */
11618 vty_json_no_pretty(vty, json_paths);
11619
11620 if (json_detail_header_used)
11621 vty_out(vty, "} ");
11622
11623 json_paths = NULL;
11624 first = 0;
11625 } else
11626 json_object_free(json_paths);
11627 }
11628
11629 if (output_cum) {
11630 output_count += *output_cum;
11631 *output_cum = output_count;
11632 }
11633 if (total_cum) {
11634 total_count += *total_cum;
11635 *total_cum = total_count;
11636 }
11637 if (use_json) {
11638 if (rd) {
11639 vty_out(vty, " }%s ", (is_last ? "" : ","));
11640 }
11641 if (is_last) {
11642 unsigned long i;
11643 for (i = 0; i < *json_header_depth; ++i)
11644 vty_out(vty, " } ");
11645 if (!all)
11646 vty_out(vty, "\n");
11647 }
11648 } else {
11649 if (is_last) {
11650 /* No route is displayed */
11651 if (output_count == 0) {
11652 if (type == bgp_show_type_normal)
11653 vty_out(vty,
11654 "No BGP prefixes displayed, %ld exist\n",
11655 total_count);
11656 } else
11657 vty_out(vty,
11658 "\nDisplayed %ld routes and %ld total paths\n",
11659 output_count, total_count);
11660 }
11661 }
11662
11663 return CMD_SUCCESS;
11664 }
11665
11666 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11667 struct bgp_table *table, struct prefix_rd *prd_match,
11668 enum bgp_show_type type, void *output_arg,
11669 uint16_t show_flags)
11670 {
11671 struct bgp_dest *dest, *next;
11672 unsigned long output_cum = 0;
11673 unsigned long total_cum = 0;
11674 unsigned long json_header_depth = 0;
11675 struct bgp_table *itable;
11676 bool show_msg;
11677 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11678
11679 show_msg = (!use_json && type == bgp_show_type_normal);
11680
11681 for (dest = bgp_table_top(table); dest; dest = next) {
11682 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11683
11684 next = bgp_route_next(dest);
11685 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11686 continue;
11687
11688 itable = bgp_dest_get_bgp_table_info(dest);
11689 if (itable != NULL) {
11690 struct prefix_rd prd;
11691 char rd[RD_ADDRSTRLEN];
11692
11693 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11694 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11695 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11696 rd, next == NULL, &output_cum,
11697 &total_cum, &json_header_depth,
11698 show_flags, RPKI_NOT_BEING_USED);
11699 if (next == NULL)
11700 show_msg = false;
11701 }
11702 }
11703 if (show_msg) {
11704 if (output_cum == 0)
11705 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11706 total_cum);
11707 else
11708 vty_out(vty,
11709 "\nDisplayed %ld routes and %ld total paths\n",
11710 output_cum, total_cum);
11711 } else {
11712 if (use_json && output_cum == 0)
11713 vty_out(vty, "{}\n");
11714 }
11715 return CMD_SUCCESS;
11716 }
11717
11718 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11719 enum bgp_show_type type, void *output_arg,
11720 uint16_t show_flags, enum rpki_states rpki_target_state)
11721 {
11722 struct bgp_table *table;
11723 unsigned long json_header_depth = 0;
11724 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11725
11726 if (bgp == NULL) {
11727 bgp = bgp_get_default();
11728 }
11729
11730 if (bgp == NULL) {
11731 if (!use_json)
11732 vty_out(vty, "No BGP process is configured\n");
11733 else
11734 vty_out(vty, "{}\n");
11735 return CMD_WARNING;
11736 }
11737
11738 /* Labeled-unicast routes live in the unicast table. */
11739 if (safi == SAFI_LABELED_UNICAST)
11740 safi = SAFI_UNICAST;
11741
11742 table = bgp->rib[afi][safi];
11743 /* use MPLS and ENCAP specific shows until they are merged */
11744 if (safi == SAFI_MPLS_VPN) {
11745 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11746 output_arg, show_flags);
11747 }
11748
11749 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11750 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11751 output_arg, use_json,
11752 1, NULL, NULL);
11753 }
11754
11755 if (safi == SAFI_EVPN)
11756 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11757
11758 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11759 NULL, NULL, &json_header_depth, show_flags,
11760 rpki_target_state);
11761 }
11762
11763 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11764 safi_t safi, uint16_t show_flags)
11765 {
11766 struct listnode *node, *nnode;
11767 struct bgp *bgp;
11768 int is_first = 1;
11769 bool route_output = false;
11770 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11771
11772 if (use_json)
11773 vty_out(vty, "{\n");
11774
11775 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11776 route_output = true;
11777 if (use_json) {
11778 if (!is_first)
11779 vty_out(vty, ",\n");
11780 else
11781 is_first = 0;
11782
11783 vty_out(vty, "\"%s\":",
11784 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11785 ? VRF_DEFAULT_NAME
11786 : bgp->name);
11787 } else {
11788 vty_out(vty, "\nInstance %s:\n",
11789 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11790 ? VRF_DEFAULT_NAME
11791 : bgp->name);
11792 }
11793 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11794 show_flags, RPKI_NOT_BEING_USED);
11795 }
11796
11797 if (use_json)
11798 vty_out(vty, "}\n");
11799 else if (!route_output)
11800 vty_out(vty, "%% BGP instance not found\n");
11801 }
11802
11803 /* Header of detailed BGP route information */
11804 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11805 struct bgp_dest *dest, const struct prefix *p,
11806 const struct prefix_rd *prd, afi_t afi,
11807 safi_t safi, json_object *json,
11808 bool incremental_print)
11809 {
11810 struct bgp_path_info *pi;
11811 struct peer *peer;
11812 struct listnode *node, *nnode;
11813 char buf1[RD_ADDRSTRLEN];
11814 int count = 0;
11815 int best = 0;
11816 int suppress = 0;
11817 int accept_own = 0;
11818 int route_filter_translated_v4 = 0;
11819 int route_filter_v4 = 0;
11820 int route_filter_translated_v6 = 0;
11821 int route_filter_v6 = 0;
11822 int llgr_stale = 0;
11823 int no_llgr = 0;
11824 int accept_own_nexthop = 0;
11825 int blackhole = 0;
11826 int no_export = 0;
11827 int no_advertise = 0;
11828 int local_as = 0;
11829 int no_peer = 0;
11830 int first = 1;
11831 int has_valid_label = 0;
11832 mpls_label_t label = 0;
11833 json_object *json_adv_to = NULL;
11834 uint32_t ttl = 0;
11835 uint32_t bos = 0;
11836 uint32_t exp = 0;
11837
11838 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11839
11840 has_valid_label = bgp_is_valid_label(&label);
11841
11842 if (safi == SAFI_EVPN) {
11843 if (!json) {
11844 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11845 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11846 bgp->asnotation)
11847 : "",
11848 prd ? ":" : "", (struct prefix_evpn *)p);
11849 } else {
11850 json_object_string_add(
11851 json, "rd",
11852 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11853 bgp->asnotation)
11854 : "");
11855 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11856 }
11857 } else {
11858 if (!json) {
11859 vty_out(vty,
11860 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11861 "\n",
11862 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11863 ? prefix_rd2str(prd, buf1,
11864 sizeof(buf1),
11865 bgp->asnotation)
11866 : ""),
11867 safi == SAFI_MPLS_VPN ? ":" : "", p,
11868 dest->version);
11869
11870 } else {
11871 if (incremental_print) {
11872 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11873 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11874 dest->version);
11875 } else {
11876 json_object_string_addf(json, "prefix", "%pFX",
11877 p);
11878 json_object_int_add(json, "version",
11879 dest->version);
11880 }
11881 }
11882 }
11883
11884 if (has_valid_label) {
11885 if (json) {
11886 if (incremental_print)
11887 vty_out(vty, "\"localLabel\": \"%u\",\n",
11888 label);
11889 else
11890 json_object_int_add(json, "localLabel", label);
11891 } else
11892 vty_out(vty, "Local label: %d\n", label);
11893 }
11894
11895 if (!json)
11896 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11897 vty_out(vty, "not allocated\n");
11898
11899 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11900 struct community *picomm = NULL;
11901
11902 picomm = bgp_attr_get_community(pi->attr);
11903
11904 count++;
11905 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11906 best = count;
11907 if (bgp_path_suppressed(pi))
11908 suppress = 1;
11909
11910 if (!picomm)
11911 continue;
11912
11913 no_advertise += community_include(
11914 picomm, COMMUNITY_NO_ADVERTISE);
11915 no_export +=
11916 community_include(picomm, COMMUNITY_NO_EXPORT);
11917 local_as +=
11918 community_include(picomm, COMMUNITY_LOCAL_AS);
11919 accept_own +=
11920 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11921 route_filter_translated_v4 += community_include(
11922 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11923 route_filter_translated_v6 += community_include(
11924 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11925 route_filter_v4 += community_include(
11926 picomm, COMMUNITY_ROUTE_FILTER_v4);
11927 route_filter_v6 += community_include(
11928 picomm, COMMUNITY_ROUTE_FILTER_v6);
11929 llgr_stale +=
11930 community_include(picomm, COMMUNITY_LLGR_STALE);
11931 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11932 accept_own_nexthop += community_include(
11933 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11934 blackhole +=
11935 community_include(picomm, COMMUNITY_BLACKHOLE);
11936 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11937 }
11938 }
11939
11940 if (!json) {
11941 vty_out(vty, "Paths: (%d available", count);
11942 if (best) {
11943 vty_out(vty, ", best #%d", best);
11944 if (safi == SAFI_UNICAST) {
11945 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11946 vty_out(vty, ", table %s",
11947 VRF_DEFAULT_NAME);
11948 else
11949 vty_out(vty, ", vrf %s",
11950 bgp->name);
11951 }
11952 } else
11953 vty_out(vty, ", no best path");
11954
11955 if (accept_own)
11956 vty_out(vty,
11957 ", accept own local route exported and imported in different VRF");
11958 else if (route_filter_translated_v4)
11959 vty_out(vty,
11960 ", mark translated RTs for VPNv4 route filtering");
11961 else if (route_filter_v4)
11962 vty_out(vty,
11963 ", attach RT as-is for VPNv4 route filtering");
11964 else if (route_filter_translated_v6)
11965 vty_out(vty,
11966 ", mark translated RTs for VPNv6 route filtering");
11967 else if (route_filter_v6)
11968 vty_out(vty,
11969 ", attach RT as-is for VPNv6 route filtering");
11970 else if (llgr_stale)
11971 vty_out(vty,
11972 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11973 else if (no_llgr)
11974 vty_out(vty,
11975 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11976 else if (accept_own_nexthop)
11977 vty_out(vty,
11978 ", accept local nexthop");
11979 else if (blackhole)
11980 vty_out(vty, ", inform peer to blackhole prefix");
11981 else if (no_export)
11982 vty_out(vty, ", not advertised to EBGP peer");
11983 else if (no_advertise)
11984 vty_out(vty, ", not advertised to any peer");
11985 else if (local_as)
11986 vty_out(vty, ", not advertised outside local AS");
11987 else if (no_peer)
11988 vty_out(vty,
11989 ", inform EBGP peer not to advertise to their EBGP peers");
11990
11991 if (suppress)
11992 vty_out(vty,
11993 ", Advertisements suppressed by an aggregate.");
11994 vty_out(vty, ")\n");
11995 }
11996
11997 /* If we are not using addpath then we can display Advertised to and
11998 * that will
11999 * show what peers we advertised the bestpath to. If we are using
12000 * addpath
12001 * though then we must display Advertised to on a path-by-path basis. */
12002 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12003 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12004 if (bgp_adj_out_lookup(peer, dest, 0)) {
12005 if (json && !json_adv_to)
12006 json_adv_to = json_object_new_object();
12007
12008 route_vty_out_advertised_to(
12009 vty, peer, &first,
12010 " Advertised to non peer-group peers:\n ",
12011 json_adv_to);
12012 }
12013 }
12014
12015 if (json && json_adv_to) {
12016 if (incremental_print) {
12017 vty_out(vty, "\"advertisedTo\": ");
12018 vty_json(vty, json_adv_to);
12019 vty_out(vty, ",");
12020 } else
12021 json_object_object_add(json, "advertisedTo",
12022 json_adv_to);
12023 } else {
12024 if (!json && first)
12025 vty_out(vty, " Not advertised to any peer");
12026 vty_out(vty, "\n");
12027 }
12028 }
12029 }
12030
12031 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12032 struct bgp_dest *bgp_node, struct vty *vty,
12033 struct bgp *bgp, afi_t afi, safi_t safi,
12034 json_object *json, enum bgp_path_type pathtype,
12035 int *display, enum rpki_states rpki_target_state)
12036 {
12037 struct bgp_path_info *pi;
12038 int header = 1;
12039 json_object *json_header = NULL;
12040 json_object *json_paths = NULL;
12041 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12042
12043 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12044 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12045
12046 if (p->family == AF_INET || p->family == AF_INET6)
12047 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12048 pi->peer, pi->attr, p);
12049
12050 if (rpki_target_state != RPKI_NOT_BEING_USED
12051 && rpki_curr_state != rpki_target_state)
12052 continue;
12053
12054 if (json && !json_paths) {
12055 /* Instantiate json_paths only if path is valid */
12056 json_paths = json_object_new_array();
12057 if (pfx_rd)
12058 json_header = json_object_new_object();
12059 else
12060 json_header = json;
12061 }
12062
12063 if (header) {
12064 route_vty_out_detail_header(
12065 vty, bgp, bgp_node,
12066 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12067 safi, json_header, false);
12068 header = 0;
12069 }
12070 (*display)++;
12071
12072 if (pathtype == BGP_PATH_SHOW_ALL
12073 || (pathtype == BGP_PATH_SHOW_BESTPATH
12074 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12075 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12076 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12077 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12078 route_vty_out_detail(vty, bgp, bgp_node,
12079 bgp_dest_get_prefix(bgp_node), pi,
12080 AFI_IP, safi, rpki_curr_state,
12081 json_paths);
12082 }
12083
12084 if (json && json_paths) {
12085 json_object_object_add(json_header, "paths", json_paths);
12086
12087 if (pfx_rd)
12088 json_object_object_addf(
12089 json, json_header,
12090 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12091 }
12092 }
12093
12094 /*
12095 * Return rd based on safi
12096 */
12097 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12098 safi_t safi)
12099 {
12100 switch (safi) {
12101 case SAFI_MPLS_VPN:
12102 case SAFI_ENCAP:
12103 case SAFI_EVPN:
12104 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12105 case SAFI_UNSPEC:
12106 case SAFI_UNICAST:
12107 case SAFI_MULTICAST:
12108 case SAFI_LABELED_UNICAST:
12109 case SAFI_FLOWSPEC:
12110 case SAFI_MAX:
12111 return NULL;
12112 }
12113
12114 assert(!"Reached end of function when we were not expecting it");
12115 }
12116
12117 /* Display specified route of BGP table. */
12118 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12119 struct bgp_table *rib, const char *ip_str,
12120 afi_t afi, safi_t safi,
12121 enum rpki_states rpki_target_state,
12122 struct prefix_rd *prd, int prefix_check,
12123 enum bgp_path_type pathtype, bool use_json)
12124 {
12125 int ret;
12126 int display = 0;
12127 struct prefix match;
12128 struct bgp_dest *dest;
12129 struct bgp_dest *rm;
12130 struct bgp_table *table;
12131 json_object *json = NULL;
12132 json_object *json_paths = NULL;
12133
12134 /* Check IP address argument. */
12135 ret = str2prefix(ip_str, &match);
12136 if (!ret) {
12137 vty_out(vty, "address is malformed\n");
12138 return CMD_WARNING;
12139 }
12140
12141 match.family = afi2family(afi);
12142
12143 if (use_json)
12144 json = json_object_new_object();
12145
12146 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12147 for (dest = bgp_table_top(rib); dest;
12148 dest = bgp_route_next(dest)) {
12149 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12150
12151 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12152 continue;
12153 table = bgp_dest_get_bgp_table_info(dest);
12154 if (!table)
12155 continue;
12156
12157 rm = bgp_node_match(table, &match);
12158 if (rm == NULL)
12159 continue;
12160
12161 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12162 if (prefix_check
12163 && rm_p->prefixlen != match.prefixlen) {
12164 bgp_dest_unlock_node(rm);
12165 continue;
12166 }
12167
12168 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12169 bgp, afi, safi, json, pathtype,
12170 &display, rpki_target_state);
12171
12172 bgp_dest_unlock_node(rm);
12173 }
12174 } else if (safi == SAFI_EVPN) {
12175 struct bgp_dest *longest_pfx;
12176 bool is_exact_pfxlen_match = false;
12177
12178 for (dest = bgp_table_top(rib); dest;
12179 dest = bgp_route_next(dest)) {
12180 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12181
12182 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12183 continue;
12184 table = bgp_dest_get_bgp_table_info(dest);
12185 if (!table)
12186 continue;
12187
12188 longest_pfx = NULL;
12189 is_exact_pfxlen_match = false;
12190 /*
12191 * Search through all the prefixes for a match. The
12192 * pfx's are enumerated in ascending order of pfxlens.
12193 * So, the last pfx match is the longest match. Set
12194 * is_exact_pfxlen_match when we get exact pfxlen match
12195 */
12196 for (rm = bgp_table_top(table); rm;
12197 rm = bgp_route_next(rm)) {
12198 const struct prefix *rm_p =
12199 bgp_dest_get_prefix(rm);
12200 /*
12201 * Get prefixlen of the ip-prefix within type5
12202 * evpn route
12203 */
12204 if (evpn_type5_prefix_match(rm_p, &match)
12205 && rm->info) {
12206 longest_pfx = rm;
12207 int type5_pfxlen =
12208 bgp_evpn_get_type5_prefixlen(
12209 rm_p);
12210 if (type5_pfxlen == match.prefixlen) {
12211 is_exact_pfxlen_match = true;
12212 bgp_dest_unlock_node(rm);
12213 break;
12214 }
12215 }
12216 }
12217
12218 if (!longest_pfx)
12219 continue;
12220
12221 if (prefix_check && !is_exact_pfxlen_match)
12222 continue;
12223
12224 rm = longest_pfx;
12225 bgp_dest_lock_node(rm);
12226
12227 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12228 bgp, afi, safi, json, pathtype,
12229 &display, rpki_target_state);
12230
12231 bgp_dest_unlock_node(rm);
12232 }
12233 } else if (safi == SAFI_FLOWSPEC) {
12234 if (use_json)
12235 json_paths = json_object_new_array();
12236
12237 display = bgp_flowspec_display_match_per_ip(afi, rib,
12238 &match, prefix_check,
12239 vty,
12240 use_json,
12241 json_paths);
12242 if (use_json) {
12243 if (display)
12244 json_object_object_add(json, "paths",
12245 json_paths);
12246 else
12247 json_object_free(json_paths);
12248 }
12249 } else {
12250 dest = bgp_node_match(rib, &match);
12251 if (dest != NULL) {
12252 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12253 if (!prefix_check
12254 || dest_p->prefixlen == match.prefixlen) {
12255 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12256 safi, json, pathtype,
12257 &display, rpki_target_state);
12258 }
12259
12260 bgp_dest_unlock_node(dest);
12261 }
12262 }
12263
12264 if (use_json) {
12265 vty_json(vty, json);
12266 } else {
12267 if (!display) {
12268 vty_out(vty, "%% Network not in table\n");
12269 return CMD_WARNING;
12270 }
12271 }
12272
12273 return CMD_SUCCESS;
12274 }
12275
12276 /* Display specified route of Main RIB */
12277 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12278 afi_t afi, safi_t safi, struct prefix_rd *prd,
12279 int prefix_check, enum bgp_path_type pathtype,
12280 enum rpki_states rpki_target_state, bool use_json)
12281 {
12282 if (!bgp) {
12283 bgp = bgp_get_default();
12284 if (!bgp) {
12285 if (!use_json)
12286 vty_out(vty, "No BGP process is configured\n");
12287 else
12288 vty_out(vty, "{}\n");
12289 return CMD_WARNING;
12290 }
12291 }
12292
12293 /* labeled-unicast routes live in the unicast table */
12294 if (safi == SAFI_LABELED_UNICAST)
12295 safi = SAFI_UNICAST;
12296
12297 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12298 afi, safi, rpki_target_state, prd,
12299 prefix_check, pathtype, use_json);
12300 }
12301
12302 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12303 struct cmd_token **argv, bool exact, afi_t afi,
12304 safi_t safi, bool uj)
12305 {
12306 struct lcommunity *lcom;
12307 struct buffer *b;
12308 int i;
12309 char *str;
12310 int first = 0;
12311 uint16_t show_flags = 0;
12312 int ret;
12313
12314 if (uj)
12315 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12316
12317 b = buffer_new(1024);
12318 for (i = 0; i < argc; i++) {
12319 if (first)
12320 buffer_putc(b, ' ');
12321 else {
12322 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12323 first = 1;
12324 buffer_putstr(b, argv[i]->arg);
12325 }
12326 }
12327 }
12328 buffer_putc(b, '\0');
12329
12330 str = buffer_getstr(b);
12331 buffer_free(b);
12332
12333 lcom = lcommunity_str2com(str);
12334 XFREE(MTYPE_TMP, str);
12335 if (!lcom) {
12336 vty_out(vty, "%% Large-community malformed\n");
12337 return CMD_WARNING;
12338 }
12339
12340 ret = bgp_show(vty, bgp, afi, safi,
12341 (exact ? bgp_show_type_lcommunity_exact
12342 : bgp_show_type_lcommunity),
12343 lcom, show_flags, RPKI_NOT_BEING_USED);
12344
12345 lcommunity_free(&lcom);
12346 return ret;
12347 }
12348
12349 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12350 const char *lcom, bool exact, afi_t afi,
12351 safi_t safi, bool uj)
12352 {
12353 struct community_list *list;
12354 uint16_t show_flags = 0;
12355
12356 if (uj)
12357 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12358
12359
12360 list = community_list_lookup(bgp_clist, lcom, 0,
12361 LARGE_COMMUNITY_LIST_MASTER);
12362 if (list == NULL) {
12363 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12364 lcom);
12365 return CMD_WARNING;
12366 }
12367
12368 return bgp_show(vty, bgp, afi, safi,
12369 (exact ? bgp_show_type_lcommunity_list_exact
12370 : bgp_show_type_lcommunity_list),
12371 list, show_flags, RPKI_NOT_BEING_USED);
12372 }
12373
12374 DEFUN (show_ip_bgp_large_community_list,
12375 show_ip_bgp_large_community_list_cmd,
12376 "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]",
12377 SHOW_STR
12378 IP_STR
12379 BGP_STR
12380 BGP_INSTANCE_HELP_STR
12381 BGP_AFI_HELP_STR
12382 BGP_SAFI_WITH_LABEL_HELP_STR
12383 "Display routes matching the large-community-list\n"
12384 "large-community-list number\n"
12385 "large-community-list name\n"
12386 "Exact match of the large-communities\n"
12387 JSON_STR)
12388 {
12389 afi_t afi = AFI_IP6;
12390 safi_t safi = SAFI_UNICAST;
12391 int idx = 0;
12392 bool exact_match = 0;
12393 struct bgp *bgp = NULL;
12394 bool uj = use_json(argc, argv);
12395
12396 if (uj)
12397 argc--;
12398
12399 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12400 &bgp, uj);
12401 if (!idx)
12402 return CMD_WARNING;
12403
12404 argv_find(argv, argc, "large-community-list", &idx);
12405
12406 const char *clist_number_or_name = argv[++idx]->arg;
12407
12408 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12409 exact_match = 1;
12410
12411 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12412 exact_match, afi, safi, uj);
12413 }
12414 DEFUN (show_ip_bgp_large_community,
12415 show_ip_bgp_large_community_cmd,
12416 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12417 SHOW_STR
12418 IP_STR
12419 BGP_STR
12420 BGP_INSTANCE_HELP_STR
12421 BGP_AFI_HELP_STR
12422 BGP_SAFI_WITH_LABEL_HELP_STR
12423 "Display routes matching the large-communities\n"
12424 "List of large-community numbers\n"
12425 "Exact match of the large-communities\n"
12426 JSON_STR)
12427 {
12428 afi_t afi = AFI_IP6;
12429 safi_t safi = SAFI_UNICAST;
12430 int idx = 0;
12431 bool exact_match = 0;
12432 struct bgp *bgp = NULL;
12433 bool uj = use_json(argc, argv);
12434 uint16_t show_flags = 0;
12435
12436 if (uj) {
12437 argc--;
12438 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12439 }
12440
12441 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12442 &bgp, uj);
12443 if (!idx)
12444 return CMD_WARNING;
12445
12446 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12447 if (argv_find(argv, argc, "exact-match", &idx)) {
12448 argc--;
12449 exact_match = 1;
12450 }
12451 return bgp_show_lcommunity(vty, bgp, argc, argv,
12452 exact_match, afi, safi, uj);
12453 } else
12454 return bgp_show(vty, bgp, afi, safi,
12455 bgp_show_type_lcommunity_all, NULL, show_flags,
12456 RPKI_NOT_BEING_USED);
12457 }
12458
12459 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12460 safi_t safi, struct json_object *json_array);
12461 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12462 safi_t safi, struct json_object *json);
12463
12464
12465 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12466 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12467 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12468 "Display number of prefixes for all afi/safi\n" JSON_STR)
12469 {
12470 bool uj = use_json(argc, argv);
12471 struct bgp *bgp = NULL;
12472 safi_t safi = SAFI_UNICAST;
12473 afi_t afi = AFI_IP6;
12474 int idx = 0;
12475 struct json_object *json_all = NULL;
12476 struct json_object *json_afi_safi = NULL;
12477
12478 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12479 &bgp, false);
12480 if (!idx)
12481 return CMD_WARNING;
12482
12483 if (uj)
12484 json_all = json_object_new_object();
12485
12486 FOREACH_AFI_SAFI (afi, safi) {
12487 /*
12488 * So limit output to those afi/safi pairs that
12489 * actually have something interesting in them
12490 */
12491 if (strmatch(get_afi_safi_str(afi, safi, true),
12492 "Unknown")) {
12493 continue;
12494 }
12495 if (uj) {
12496 json_afi_safi = json_object_new_array();
12497 json_object_object_add(
12498 json_all,
12499 get_afi_safi_str(afi, safi, true),
12500 json_afi_safi);
12501 } else {
12502 json_afi_safi = NULL;
12503 }
12504
12505 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12506 }
12507
12508 if (uj)
12509 vty_json(vty, json_all);
12510
12511 return CMD_SUCCESS;
12512 }
12513
12514 /* BGP route print out function without JSON */
12515 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12516 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12517 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12518 SHOW_STR
12519 IP_STR
12520 BGP_STR
12521 BGP_INSTANCE_HELP_STR
12522 L2VPN_HELP_STR
12523 EVPN_HELP_STR
12524 "BGP RIB advertisement statistics\n"
12525 JSON_STR)
12526 {
12527 afi_t afi = AFI_IP6;
12528 safi_t safi = SAFI_UNICAST;
12529 struct bgp *bgp = NULL;
12530 int idx = 0, ret;
12531 bool uj = use_json(argc, argv);
12532 struct json_object *json_afi_safi = NULL, *json = NULL;
12533
12534 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12535 &bgp, false);
12536 if (!idx)
12537 return CMD_WARNING;
12538
12539 if (uj)
12540 json_afi_safi = json_object_new_array();
12541 else
12542 json_afi_safi = NULL;
12543
12544 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12545
12546 if (uj) {
12547 json = json_object_new_object();
12548 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12549 json_afi_safi);
12550 vty_json(vty, json);
12551 }
12552 return ret;
12553 }
12554
12555 /* BGP route print out function without JSON */
12556 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12557 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12558 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12559 "]]\
12560 statistics [json]",
12561 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12562 BGP_SAFI_WITH_LABEL_HELP_STR
12563 "BGP RIB advertisement statistics\n" JSON_STR)
12564 {
12565 afi_t afi = AFI_IP6;
12566 safi_t safi = SAFI_UNICAST;
12567 struct bgp *bgp = NULL;
12568 int idx = 0, ret;
12569 bool uj = use_json(argc, argv);
12570 struct json_object *json_afi_safi = NULL, *json = NULL;
12571
12572 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12573 &bgp, false);
12574 if (!idx)
12575 return CMD_WARNING;
12576
12577 if (uj)
12578 json_afi_safi = json_object_new_array();
12579 else
12580 json_afi_safi = NULL;
12581
12582 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12583
12584 if (uj) {
12585 json = json_object_new_object();
12586 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12587 json_afi_safi);
12588 vty_json(vty, json);
12589 }
12590 return ret;
12591 }
12592
12593 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12594 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12595 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12596 "]] [all$all] dampening parameters [json]",
12597 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12598 BGP_SAFI_WITH_LABEL_HELP_STR
12599 "Display the entries for all address families\n"
12600 "Display detailed information about dampening\n"
12601 "Display detail of configured dampening parameters\n"
12602 JSON_STR)
12603 {
12604 afi_t afi = AFI_IP6;
12605 safi_t safi = SAFI_UNICAST;
12606 struct bgp *bgp = NULL;
12607 int idx = 0;
12608 uint16_t show_flags = 0;
12609 bool uj = use_json(argc, argv);
12610
12611 if (uj) {
12612 argc--;
12613 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12614 }
12615
12616 /* [<ipv4|ipv6> [all]] */
12617 if (all) {
12618 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12619 if (argv_find(argv, argc, "ipv4", &idx))
12620 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12621
12622 if (argv_find(argv, argc, "ipv6", &idx))
12623 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12624 }
12625
12626 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12627 &bgp, false);
12628 if (!idx)
12629 return CMD_WARNING;
12630
12631 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12632 }
12633
12634 /* BGP route print out function */
12635 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12636 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12637 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12638 "]]\
12639 [all$all]\
12640 [cidr-only\
12641 |dampening <flap-statistics|dampened-paths>\
12642 |community [AA:NN|local-AS|no-advertise|no-export\
12643 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12644 |accept-own|accept-own-nexthop|route-filter-v6\
12645 |route-filter-v4|route-filter-translated-v6\
12646 |route-filter-translated-v4] [exact-match]\
12647 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12648 |filter-list AS_PATH_FILTER_NAME\
12649 |prefix-list WORD\
12650 |access-list ACCESSLIST_NAME\
12651 |route-map RMAP_NAME\
12652 |rpki <invalid|valid|notfound>\
12653 |version (1-4294967295)\
12654 |alias ALIAS_NAME\
12655 |A.B.C.D/M longer-prefixes\
12656 |X:X::X:X/M longer-prefixes\
12657 |"BGP_SELF_ORIG_CMD_STR"\
12658 |detail-routes$detail_routes\
12659 ] [json$uj [detail$detail_json] | wide$wide]",
12660 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12661 BGP_SAFI_WITH_LABEL_HELP_STR
12662 "Display the entries for all address families\n"
12663 "Display only routes with non-natural netmasks\n"
12664 "Display detailed information about dampening\n"
12665 "Display flap statistics of routes\n"
12666 "Display paths suppressed due to dampening\n"
12667 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12668 "Do not send outside local AS (well-known community)\n"
12669 "Do not advertise to any peer (well-known community)\n"
12670 "Do not export to next AS (well-known community)\n"
12671 "Graceful shutdown (well-known community)\n"
12672 "Do not export to any peer (well-known community)\n"
12673 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12674 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12675 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12676 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12677 "Should accept VPN route with local nexthop (well-known community)\n"
12678 "RT VPNv6 route filtering (well-known community)\n"
12679 "RT VPNv4 route filtering (well-known community)\n"
12680 "RT translated VPNv6 route filtering (well-known community)\n"
12681 "RT translated VPNv4 route filtering (well-known community)\n"
12682 "Exact match of the communities\n"
12683 "Community-list number\n"
12684 "Community-list name\n"
12685 "Display routes matching the community-list\n"
12686 "Exact match of the communities\n"
12687 "Display routes conforming to the filter-list\n"
12688 "Regular expression access list name\n"
12689 "Display routes conforming to the prefix-list\n"
12690 "Prefix-list name\n"
12691 "Display routes conforming to the access-list\n"
12692 "Access-list name\n"
12693 "Display routes matching the route-map\n"
12694 "A route-map to match on\n"
12695 "RPKI route types\n"
12696 "A valid path as determined by rpki\n"
12697 "A invalid path as determined by rpki\n"
12698 "A path that has no rpki data\n"
12699 "Display prefixes with matching version numbers\n"
12700 "Version number and above\n"
12701 "Display prefixes with matching BGP community alias\n"
12702 "BGP community alias\n"
12703 "IPv4 prefix\n"
12704 "Display route and more specific routes\n"
12705 "IPv6 prefix\n"
12706 "Display route and more specific routes\n"
12707 BGP_SELF_ORIG_HELP_STR
12708 "Display detailed version of all routes\n"
12709 JSON_STR
12710 "Display detailed version of JSON output\n"
12711 "Increase table width for longer prefixes\n")
12712 {
12713 afi_t afi = AFI_IP6;
12714 safi_t safi = SAFI_UNICAST;
12715 enum bgp_show_type sh_type = bgp_show_type_normal;
12716 void *output_arg = NULL;
12717 struct bgp *bgp = NULL;
12718 int idx = 0;
12719 int exact_match = 0;
12720 char *community = NULL;
12721 bool first = true;
12722 uint16_t show_flags = 0;
12723 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12724 struct prefix p;
12725
12726 if (uj) {
12727 argc--;
12728 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12729 }
12730
12731 if (detail_json)
12732 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12733
12734 if (detail_routes)
12735 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12736
12737 /* [<ipv4|ipv6> [all]] */
12738 if (all) {
12739 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12740
12741 if (argv_find(argv, argc, "ipv4", &idx))
12742 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12743
12744 if (argv_find(argv, argc, "ipv6", &idx))
12745 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12746 }
12747
12748 if (wide)
12749 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12750
12751 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12752 &bgp, uj);
12753 if (!idx)
12754 return CMD_WARNING;
12755
12756 if (argv_find(argv, argc, "cidr-only", &idx))
12757 sh_type = bgp_show_type_cidr_only;
12758
12759 if (argv_find(argv, argc, "dampening", &idx)) {
12760 if (argv_find(argv, argc, "dampened-paths", &idx))
12761 sh_type = bgp_show_type_dampend_paths;
12762 else if (argv_find(argv, argc, "flap-statistics", &idx))
12763 sh_type = bgp_show_type_flap_statistics;
12764 }
12765
12766 if (argv_find(argv, argc, "community", &idx)) {
12767 char *maybecomm = NULL;
12768
12769 if (idx + 1 < argc) {
12770 if (argv[idx + 1]->type == VARIABLE_TKN)
12771 maybecomm = argv[idx + 1]->arg;
12772 else
12773 maybecomm = argv[idx + 1]->text;
12774 }
12775
12776 if (maybecomm && !strmatch(maybecomm, "json")
12777 && !strmatch(maybecomm, "exact-match"))
12778 community = maybecomm;
12779
12780 if (argv_find(argv, argc, "exact-match", &idx))
12781 exact_match = 1;
12782
12783 if (!community)
12784 sh_type = bgp_show_type_community_all;
12785 }
12786
12787 if (argv_find(argv, argc, "community-list", &idx)) {
12788 const char *clist_number_or_name = argv[++idx]->arg;
12789 struct community_list *list;
12790
12791 if (argv_find(argv, argc, "exact-match", &idx))
12792 exact_match = 1;
12793
12794 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12795 COMMUNITY_LIST_MASTER);
12796 if (list == NULL) {
12797 vty_out(vty, "%% %s community-list not found\n",
12798 clist_number_or_name);
12799 return CMD_WARNING;
12800 }
12801
12802 if (exact_match)
12803 sh_type = bgp_show_type_community_list_exact;
12804 else
12805 sh_type = bgp_show_type_community_list;
12806 output_arg = list;
12807 }
12808
12809 if (argv_find(argv, argc, "filter-list", &idx)) {
12810 const char *filter = argv[++idx]->arg;
12811 struct as_list *as_list;
12812
12813 as_list = as_list_lookup(filter);
12814 if (as_list == NULL) {
12815 vty_out(vty, "%% %s AS-path access-list not found\n",
12816 filter);
12817 return CMD_WARNING;
12818 }
12819
12820 sh_type = bgp_show_type_filter_list;
12821 output_arg = as_list;
12822 }
12823
12824 if (argv_find(argv, argc, "prefix-list", &idx)) {
12825 const char *prefix_list_str = argv[++idx]->arg;
12826 struct prefix_list *plist;
12827
12828 plist = prefix_list_lookup(afi, prefix_list_str);
12829 if (plist == NULL) {
12830 vty_out(vty, "%% %s prefix-list not found\n",
12831 prefix_list_str);
12832 return CMD_WARNING;
12833 }
12834
12835 sh_type = bgp_show_type_prefix_list;
12836 output_arg = plist;
12837 }
12838
12839 if (argv_find(argv, argc, "access-list", &idx)) {
12840 const char *access_list_str = argv[++idx]->arg;
12841 struct access_list *alist;
12842
12843 alist = access_list_lookup(afi, access_list_str);
12844 if (!alist) {
12845 vty_out(vty, "%% %s access-list not found\n",
12846 access_list_str);
12847 return CMD_WARNING;
12848 }
12849
12850 sh_type = bgp_show_type_access_list;
12851 output_arg = alist;
12852 }
12853
12854 if (argv_find(argv, argc, "route-map", &idx)) {
12855 const char *rmap_str = argv[++idx]->arg;
12856 struct route_map *rmap;
12857
12858 rmap = route_map_lookup_by_name(rmap_str);
12859 if (!rmap) {
12860 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12861 return CMD_WARNING;
12862 }
12863
12864 sh_type = bgp_show_type_route_map;
12865 output_arg = rmap;
12866 }
12867
12868 if (argv_find(argv, argc, "rpki", &idx)) {
12869 sh_type = bgp_show_type_rpki;
12870 if (argv_find(argv, argc, "valid", &idx))
12871 rpki_target_state = RPKI_VALID;
12872 else if (argv_find(argv, argc, "invalid", &idx))
12873 rpki_target_state = RPKI_INVALID;
12874 }
12875
12876 /* Display prefixes with matching version numbers */
12877 if (argv_find(argv, argc, "version", &idx)) {
12878 sh_type = bgp_show_type_prefix_version;
12879 output_arg = argv[idx + 1]->arg;
12880 }
12881
12882 /* Display prefixes with matching BGP community alias */
12883 if (argv_find(argv, argc, "alias", &idx)) {
12884 sh_type = bgp_show_type_community_alias;
12885 output_arg = argv[idx + 1]->arg;
12886 }
12887
12888 /* prefix-longer */
12889 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12890 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12891 const char *prefix_str = argv[idx]->arg;
12892
12893 if (!str2prefix(prefix_str, &p)) {
12894 vty_out(vty, "%% Malformed Prefix\n");
12895 return CMD_WARNING;
12896 }
12897
12898 sh_type = bgp_show_type_prefix_longer;
12899 output_arg = &p;
12900 }
12901
12902 /* self originated only */
12903 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12904 sh_type = bgp_show_type_self_originated;
12905
12906 if (!all) {
12907 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12908 if (community)
12909 return bgp_show_community(vty, bgp, community,
12910 exact_match, afi, safi,
12911 show_flags);
12912 else
12913 return bgp_show(vty, bgp, afi, safi, sh_type,
12914 output_arg, show_flags,
12915 rpki_target_state);
12916 } else {
12917 struct listnode *node;
12918 struct bgp *abgp;
12919 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12920 * AFI_IP6 */
12921
12922 if (uj)
12923 vty_out(vty, "{\n");
12924
12925 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12926 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12927 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12928 ? AFI_IP
12929 : AFI_IP6;
12930 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12931 FOREACH_SAFI (safi) {
12932 if (!bgp_afi_safi_peer_exists(abgp, afi,
12933 safi))
12934 continue;
12935
12936 if (uj) {
12937 if (first)
12938 first = false;
12939 else
12940 vty_out(vty, ",\n");
12941 vty_out(vty, "\"%s\":{\n",
12942 get_afi_safi_str(afi,
12943 safi,
12944 true));
12945 } else
12946 vty_out(vty,
12947 "\nFor address family: %s\n",
12948 get_afi_safi_str(
12949 afi, safi,
12950 false));
12951
12952 if (community)
12953 bgp_show_community(
12954 vty, abgp, community,
12955 exact_match, afi, safi,
12956 show_flags);
12957 else
12958 bgp_show(vty, abgp, afi, safi,
12959 sh_type, output_arg,
12960 show_flags,
12961 rpki_target_state);
12962 if (uj)
12963 vty_out(vty, "}\n");
12964 }
12965 }
12966 } else {
12967 /* show <ip> bgp all: for each AFI and SAFI*/
12968 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12969 FOREACH_AFI_SAFI (afi, safi) {
12970 if (!bgp_afi_safi_peer_exists(abgp, afi,
12971 safi))
12972 continue;
12973
12974 if (uj) {
12975 if (first)
12976 first = false;
12977 else
12978 vty_out(vty, ",\n");
12979
12980 vty_out(vty, "\"%s\":{\n",
12981 get_afi_safi_str(afi,
12982 safi,
12983 true));
12984 } else
12985 vty_out(vty,
12986 "\nFor address family: %s\n",
12987 get_afi_safi_str(
12988 afi, safi,
12989 false));
12990
12991 if (community)
12992 bgp_show_community(
12993 vty, abgp, community,
12994 exact_match, afi, safi,
12995 show_flags);
12996 else
12997 bgp_show(vty, abgp, afi, safi,
12998 sh_type, output_arg,
12999 show_flags,
13000 rpki_target_state);
13001 if (uj)
13002 vty_out(vty, "}\n");
13003 }
13004 }
13005 }
13006 if (uj)
13007 vty_out(vty, "}\n");
13008 }
13009 return CMD_SUCCESS;
13010 }
13011
13012 DEFUN (show_ip_bgp_route,
13013 show_ip_bgp_route_cmd,
13014 "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]",
13015 SHOW_STR
13016 IP_STR
13017 BGP_STR
13018 BGP_INSTANCE_HELP_STR
13019 BGP_AFI_HELP_STR
13020 BGP_SAFI_WITH_LABEL_HELP_STR
13021 "Network in the BGP routing table to display\n"
13022 "IPv4 prefix\n"
13023 "Network in the BGP routing table to display\n"
13024 "IPv6 prefix\n"
13025 "Display only the bestpath\n"
13026 "Display only multipaths\n"
13027 "Display only paths that match the specified rpki state\n"
13028 "A valid path as determined by rpki\n"
13029 "A invalid path as determined by rpki\n"
13030 "A path that has no rpki data\n"
13031 JSON_STR)
13032 {
13033 int prefix_check = 0;
13034
13035 afi_t afi = AFI_IP6;
13036 safi_t safi = SAFI_UNICAST;
13037 char *prefix = NULL;
13038 struct bgp *bgp = NULL;
13039 enum bgp_path_type path_type;
13040 bool uj = use_json(argc, argv);
13041
13042 int idx = 0;
13043
13044 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13045 &bgp, uj);
13046 if (!idx)
13047 return CMD_WARNING;
13048
13049 if (!bgp) {
13050 vty_out(vty,
13051 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13052 return CMD_WARNING;
13053 }
13054
13055 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13056 if (argv_find(argv, argc, "A.B.C.D", &idx)
13057 || argv_find(argv, argc, "X:X::X:X", &idx))
13058 prefix_check = 0;
13059 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13060 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13061 prefix_check = 1;
13062
13063 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13064 && afi != AFI_IP6) {
13065 vty_out(vty,
13066 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13067 return CMD_WARNING;
13068 }
13069 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13070 && afi != AFI_IP) {
13071 vty_out(vty,
13072 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13073 return CMD_WARNING;
13074 }
13075
13076 prefix = argv[idx]->arg;
13077
13078 /* [<bestpath|multipath>] */
13079 if (argv_find(argv, argc, "bestpath", &idx))
13080 path_type = BGP_PATH_SHOW_BESTPATH;
13081 else if (argv_find(argv, argc, "multipath", &idx))
13082 path_type = BGP_PATH_SHOW_MULTIPATH;
13083 else
13084 path_type = BGP_PATH_SHOW_ALL;
13085
13086 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13087 path_type, RPKI_NOT_BEING_USED, uj);
13088 }
13089
13090 DEFUN (show_ip_bgp_regexp,
13091 show_ip_bgp_regexp_cmd,
13092 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13093 SHOW_STR
13094 IP_STR
13095 BGP_STR
13096 BGP_INSTANCE_HELP_STR
13097 BGP_AFI_HELP_STR
13098 BGP_SAFI_WITH_LABEL_HELP_STR
13099 "Display routes matching the AS path regular expression\n"
13100 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13101 JSON_STR)
13102 {
13103 afi_t afi = AFI_IP6;
13104 safi_t safi = SAFI_UNICAST;
13105 struct bgp *bgp = NULL;
13106 bool uj = use_json(argc, argv);
13107 char *regstr = NULL;
13108
13109 int idx = 0;
13110 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13111 &bgp, false);
13112 if (!idx)
13113 return CMD_WARNING;
13114
13115 // get index of regex
13116 if (argv_find(argv, argc, "REGEX", &idx))
13117 regstr = argv[idx]->arg;
13118
13119 assert(regstr);
13120 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13121 bgp_show_type_regexp, uj);
13122 }
13123
13124 DEFPY (show_ip_bgp_instance_all,
13125 show_ip_bgp_instance_all_cmd,
13126 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13127 SHOW_STR
13128 IP_STR
13129 BGP_STR
13130 BGP_INSTANCE_ALL_HELP_STR
13131 BGP_AFI_HELP_STR
13132 BGP_SAFI_WITH_LABEL_HELP_STR
13133 JSON_STR
13134 "Increase table width for longer prefixes\n")
13135 {
13136 afi_t afi = AFI_IP6;
13137 safi_t safi = SAFI_UNICAST;
13138 struct bgp *bgp = NULL;
13139 int idx = 0;
13140 uint16_t show_flags = 0;
13141
13142 if (uj) {
13143 argc--;
13144 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13145 }
13146
13147 if (wide)
13148 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13149
13150 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13151 &bgp, uj);
13152 if (!idx)
13153 return CMD_WARNING;
13154
13155 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13156 return CMD_SUCCESS;
13157 }
13158
13159 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13160 afi_t afi, safi_t safi, enum bgp_show_type type,
13161 bool use_json)
13162 {
13163 regex_t *regex;
13164 int rc;
13165 uint16_t show_flags = 0;
13166
13167 if (use_json)
13168 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13169
13170 if (!config_bgp_aspath_validate(regstr)) {
13171 vty_out(vty, "Invalid character in REGEX %s\n",
13172 regstr);
13173 return CMD_WARNING_CONFIG_FAILED;
13174 }
13175
13176 regex = bgp_regcomp(regstr);
13177 if (!regex) {
13178 vty_out(vty, "Can't compile regexp %s\n", regstr);
13179 return CMD_WARNING;
13180 }
13181
13182 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13183 RPKI_NOT_BEING_USED);
13184 bgp_regex_free(regex);
13185 return rc;
13186 }
13187
13188 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13189 const char *comstr, int exact, afi_t afi,
13190 safi_t safi, uint16_t show_flags)
13191 {
13192 struct community *com;
13193 int ret = 0;
13194
13195 com = community_str2com(comstr);
13196 if (!com) {
13197 vty_out(vty, "%% Community malformed: %s\n", comstr);
13198 return CMD_WARNING;
13199 }
13200
13201 ret = bgp_show(vty, bgp, afi, safi,
13202 (exact ? bgp_show_type_community_exact
13203 : bgp_show_type_community),
13204 com, show_flags, RPKI_NOT_BEING_USED);
13205 community_free(&com);
13206
13207 return ret;
13208 }
13209
13210 enum bgp_stats {
13211 BGP_STATS_MAXBITLEN = 0,
13212 BGP_STATS_RIB,
13213 BGP_STATS_PREFIXES,
13214 BGP_STATS_TOTPLEN,
13215 BGP_STATS_UNAGGREGATEABLE,
13216 BGP_STATS_MAX_AGGREGATEABLE,
13217 BGP_STATS_AGGREGATES,
13218 BGP_STATS_SPACE,
13219 BGP_STATS_ASPATH_COUNT,
13220 BGP_STATS_ASPATH_MAXHOPS,
13221 BGP_STATS_ASPATH_TOTHOPS,
13222 BGP_STATS_ASPATH_MAXSIZE,
13223 BGP_STATS_ASPATH_TOTSIZE,
13224 BGP_STATS_ASN_HIGHEST,
13225 BGP_STATS_MAX,
13226 };
13227
13228 #define TABLE_STATS_IDX_VTY 0
13229 #define TABLE_STATS_IDX_JSON 1
13230
13231 static const char *table_stats_strs[][2] = {
13232 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13233 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13234 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13235 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13236 "unaggregateablePrefixes"},
13237 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13238 "maximumAggregateablePrefixes"},
13239 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13240 "bgpAggregateAdvertisements"},
13241 [BGP_STATS_SPACE] = {"Address space advertised",
13242 "addressSpaceAdvertised"},
13243 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13244 "advertisementsWithPaths"},
13245 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13246 "longestAsPath"},
13247 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13248 "largestAsPath"},
13249 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13250 "averageAsPathLengthHops"},
13251 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13252 "averageAsPathSizeBytes"},
13253 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13254 [BGP_STATS_MAX] = {NULL, NULL}
13255 };
13256
13257 struct bgp_table_stats {
13258 struct bgp_table *table;
13259 unsigned long long counts[BGP_STATS_MAX];
13260
13261 unsigned long long
13262 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13263 1];
13264
13265 double total_space;
13266 };
13267
13268 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13269 struct bgp_table_stats *ts, unsigned int space)
13270 {
13271 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13272 struct bgp_path_info *pi;
13273 const struct prefix *rn_p;
13274
13275 if (!bgp_dest_has_bgp_path_info_data(dest))
13276 return;
13277
13278 rn_p = bgp_dest_get_prefix(dest);
13279 ts->counts[BGP_STATS_PREFIXES]++;
13280 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13281
13282 ts->prefix_len_count[rn_p->prefixlen]++;
13283 /* check if the prefix is included by any other announcements */
13284 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13285 pdest = bgp_dest_parent_nolock(pdest);
13286
13287 if (pdest == NULL || pdest == top) {
13288 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13289 /* announced address space */
13290 if (space)
13291 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13292 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13293 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13294
13295
13296 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13297 ts->counts[BGP_STATS_RIB]++;
13298
13299 if (CHECK_FLAG(pi->attr->flag,
13300 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13301 ts->counts[BGP_STATS_AGGREGATES]++;
13302
13303 /* as-path stats */
13304 if (pi->attr->aspath) {
13305 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13306 unsigned int size = aspath_size(pi->attr->aspath);
13307 as_t highest = aspath_highest(pi->attr->aspath);
13308
13309 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13310
13311 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13312 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13313
13314 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13315 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13316
13317 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13318 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13319 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13320 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13321 }
13322 }
13323 }
13324
13325 static void bgp_table_stats_walker(struct thread *t)
13326 {
13327 struct bgp_dest *dest, *ndest;
13328 struct bgp_dest *top;
13329 struct bgp_table_stats *ts = THREAD_ARG(t);
13330 unsigned int space = 0;
13331
13332 if (!(top = bgp_table_top(ts->table)))
13333 return;
13334
13335 switch (ts->table->afi) {
13336 case AFI_IP:
13337 space = IPV4_MAX_BITLEN;
13338 break;
13339 case AFI_IP6:
13340 space = IPV6_MAX_BITLEN;
13341 break;
13342 case AFI_L2VPN:
13343 space = EVPN_ROUTE_PREFIXLEN;
13344 break;
13345 case AFI_UNSPEC:
13346 case AFI_MAX:
13347 return;
13348 }
13349
13350 ts->counts[BGP_STATS_MAXBITLEN] = space;
13351
13352 for (dest = top; dest; dest = bgp_route_next(dest)) {
13353 if (ts->table->safi == SAFI_MPLS_VPN
13354 || ts->table->safi == SAFI_ENCAP
13355 || ts->table->safi == SAFI_EVPN) {
13356 struct bgp_table *table;
13357
13358 table = bgp_dest_get_bgp_table_info(dest);
13359 if (!table)
13360 continue;
13361
13362 top = bgp_table_top(table);
13363 for (ndest = bgp_table_top(table); ndest;
13364 ndest = bgp_route_next(ndest))
13365 bgp_table_stats_rn(ndest, top, ts, space);
13366 } else {
13367 bgp_table_stats_rn(dest, top, ts, space);
13368 }
13369 }
13370 }
13371
13372 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13373 struct json_object *json_array)
13374 {
13375 struct listnode *node, *nnode;
13376 struct bgp *bgp;
13377
13378 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13379 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13380 }
13381
13382 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13383 safi_t safi, struct json_object *json_array)
13384 {
13385 struct bgp_table_stats ts;
13386 unsigned int i;
13387 int ret = CMD_SUCCESS;
13388 char temp_buf[20];
13389 struct json_object *json = NULL;
13390 uint32_t bitlen = 0;
13391 struct json_object *json_bitlen;
13392
13393 if (json_array)
13394 json = json_object_new_object();
13395
13396 if (!bgp->rib[afi][safi]) {
13397 char warning_msg[50];
13398
13399 snprintf(warning_msg, sizeof(warning_msg),
13400 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13401 safi);
13402
13403 if (!json)
13404 vty_out(vty, "%s\n", warning_msg);
13405 else
13406 json_object_string_add(json, "warning", warning_msg);
13407
13408 ret = CMD_WARNING;
13409 goto end_table_stats;
13410 }
13411
13412 if (!json)
13413 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13414 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13415 else
13416 json_object_string_add(json, "instance", bgp->name_pretty);
13417
13418 /* labeled-unicast routes live in the unicast table */
13419 if (safi == SAFI_LABELED_UNICAST)
13420 safi = SAFI_UNICAST;
13421
13422 memset(&ts, 0, sizeof(ts));
13423 ts.table = bgp->rib[afi][safi];
13424 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13425
13426 for (i = 0; i < BGP_STATS_MAX; i++) {
13427 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13428 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13429 continue;
13430
13431 switch (i) {
13432 case BGP_STATS_ASPATH_TOTHOPS:
13433 case BGP_STATS_ASPATH_TOTSIZE:
13434 if (!json) {
13435 snprintf(
13436 temp_buf, sizeof(temp_buf), "%12.2f",
13437 ts.counts[i]
13438 ? (float)ts.counts[i]
13439 / (float)ts.counts
13440 [BGP_STATS_ASPATH_COUNT]
13441 : 0);
13442 vty_out(vty, "%-30s: %s",
13443 table_stats_strs[i]
13444 [TABLE_STATS_IDX_VTY],
13445 temp_buf);
13446 } else {
13447 json_object_double_add(
13448 json,
13449 table_stats_strs[i]
13450 [TABLE_STATS_IDX_JSON],
13451 ts.counts[i]
13452 ? (double)ts.counts[i]
13453 / (double)ts.counts
13454 [BGP_STATS_ASPATH_COUNT]
13455 : 0);
13456 }
13457 break;
13458 case BGP_STATS_TOTPLEN:
13459 if (!json) {
13460 snprintf(
13461 temp_buf, sizeof(temp_buf), "%12.2f",
13462 ts.counts[i]
13463 ? (float)ts.counts[i]
13464 / (float)ts.counts
13465 [BGP_STATS_PREFIXES]
13466 : 0);
13467 vty_out(vty, "%-30s: %s",
13468 table_stats_strs[i]
13469 [TABLE_STATS_IDX_VTY],
13470 temp_buf);
13471 } else {
13472 json_object_double_add(
13473 json,
13474 table_stats_strs[i]
13475 [TABLE_STATS_IDX_JSON],
13476 ts.counts[i]
13477 ? (double)ts.counts[i]
13478 / (double)ts.counts
13479 [BGP_STATS_PREFIXES]
13480 : 0);
13481 }
13482 break;
13483 case BGP_STATS_SPACE:
13484 if (!json) {
13485 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13486 ts.total_space);
13487 vty_out(vty, "%-30s: %s\n",
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 (double)ts.total_space);
13497 }
13498 if (afi == AFI_IP6) {
13499 if (!json) {
13500 snprintf(temp_buf, sizeof(temp_buf),
13501 "%12g",
13502 ts.total_space
13503 * pow(2.0, -128 + 32));
13504 vty_out(vty, "%30s: %s\n",
13505 "/32 equivalent %s\n",
13506 temp_buf);
13507 } else {
13508 json_object_double_add(
13509 json, "/32equivalent",
13510 (double)(ts.total_space
13511 * pow(2.0,
13512 -128 + 32)));
13513 }
13514 if (!json) {
13515 snprintf(temp_buf, sizeof(temp_buf),
13516 "%12g",
13517 ts.total_space
13518 * pow(2.0, -128 + 48));
13519 vty_out(vty, "%30s: %s\n",
13520 "/48 equivalent %s\n",
13521 temp_buf);
13522 } else {
13523 json_object_double_add(
13524 json, "/48equivalent",
13525 (double)(ts.total_space
13526 * pow(2.0,
13527 -128 + 48)));
13528 }
13529 } else {
13530 if (!json) {
13531 snprintf(temp_buf, sizeof(temp_buf),
13532 "%12.2f",
13533 ts.total_space * 100.
13534 * pow(2.0, -32));
13535 vty_out(vty, "%30s: %s\n",
13536 "% announced ", temp_buf);
13537 } else {
13538 json_object_double_add(
13539 json, "%announced",
13540 (double)(ts.total_space * 100.
13541 * pow(2.0, -32)));
13542 }
13543 if (!json) {
13544 snprintf(temp_buf, sizeof(temp_buf),
13545 "%12.2f",
13546 ts.total_space
13547 * pow(2.0, -32 + 8));
13548 vty_out(vty, "%30s: %s\n",
13549 "/8 equivalent ", temp_buf);
13550 } else {
13551 json_object_double_add(
13552 json, "/8equivalent",
13553 (double)(ts.total_space
13554 * pow(2.0, -32 + 8)));
13555 }
13556 if (!json) {
13557 snprintf(temp_buf, sizeof(temp_buf),
13558 "%12.2f",
13559 ts.total_space
13560 * pow(2.0, -32 + 24));
13561 vty_out(vty, "%30s: %s\n",
13562 "/24 equivalent ", temp_buf);
13563 } else {
13564 json_object_double_add(
13565 json, "/24equivalent",
13566 (double)(ts.total_space
13567 * pow(2.0, -32 + 24)));
13568 }
13569 }
13570 break;
13571 default:
13572 if (!json) {
13573 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13574 ts.counts[i]);
13575 vty_out(vty, "%-30s: %s",
13576 table_stats_strs[i]
13577 [TABLE_STATS_IDX_VTY],
13578 temp_buf);
13579 } else {
13580 json_object_int_add(
13581 json,
13582 table_stats_strs[i]
13583 [TABLE_STATS_IDX_JSON],
13584 ts.counts[i]);
13585 }
13586 }
13587 if (!json)
13588 vty_out(vty, "\n");
13589 }
13590
13591 switch (afi) {
13592 case AFI_IP:
13593 bitlen = IPV4_MAX_BITLEN;
13594 break;
13595 case AFI_IP6:
13596 bitlen = IPV6_MAX_BITLEN;
13597 break;
13598 case AFI_L2VPN:
13599 bitlen = EVPN_ROUTE_PREFIXLEN;
13600 break;
13601 case AFI_UNSPEC:
13602 case AFI_MAX:
13603 break;
13604 }
13605
13606 if (json) {
13607 json_bitlen = json_object_new_array();
13608
13609 for (i = 0; i <= bitlen; i++) {
13610 struct json_object *ind_bit = json_object_new_object();
13611
13612 if (!ts.prefix_len_count[i])
13613 continue;
13614
13615 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13616 json_object_int_add(ind_bit, temp_buf,
13617 ts.prefix_len_count[i]);
13618 json_object_array_add(json_bitlen, ind_bit);
13619 }
13620 json_object_object_add(json, "prefixLength", json_bitlen);
13621 }
13622
13623 end_table_stats:
13624 if (json)
13625 json_object_array_add(json_array, json);
13626 return ret;
13627 }
13628
13629 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13630 safi_t safi, struct json_object *json_array)
13631 {
13632 if (!bgp) {
13633 bgp_table_stats_all(vty, afi, safi, json_array);
13634 return CMD_SUCCESS;
13635 }
13636
13637 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13638 }
13639
13640 enum bgp_pcounts {
13641 PCOUNT_ADJ_IN = 0,
13642 PCOUNT_DAMPED,
13643 PCOUNT_REMOVED,
13644 PCOUNT_HISTORY,
13645 PCOUNT_STALE,
13646 PCOUNT_VALID,
13647 PCOUNT_ALL,
13648 PCOUNT_COUNTED,
13649 PCOUNT_BPATH_SELECTED,
13650 PCOUNT_PFCNT, /* the figure we display to users */
13651 PCOUNT_MAX,
13652 };
13653
13654 static const char *const pcount_strs[] = {
13655 [PCOUNT_ADJ_IN] = "Adj-in",
13656 [PCOUNT_DAMPED] = "Damped",
13657 [PCOUNT_REMOVED] = "Removed",
13658 [PCOUNT_HISTORY] = "History",
13659 [PCOUNT_STALE] = "Stale",
13660 [PCOUNT_VALID] = "Valid",
13661 [PCOUNT_ALL] = "All RIB",
13662 [PCOUNT_COUNTED] = "PfxCt counted",
13663 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13664 [PCOUNT_PFCNT] = "Useable",
13665 [PCOUNT_MAX] = NULL,
13666 };
13667
13668 struct peer_pcounts {
13669 unsigned int count[PCOUNT_MAX];
13670 const struct peer *peer;
13671 const struct bgp_table *table;
13672 safi_t safi;
13673 };
13674
13675 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13676 {
13677 const struct bgp_adj_in *ain;
13678 const struct bgp_path_info *pi;
13679 const struct peer *peer = pc->peer;
13680
13681 for (ain = rn->adj_in; ain; ain = ain->next)
13682 if (ain->peer == peer)
13683 pc->count[PCOUNT_ADJ_IN]++;
13684
13685 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13686
13687 if (pi->peer != peer)
13688 continue;
13689
13690 pc->count[PCOUNT_ALL]++;
13691
13692 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13693 pc->count[PCOUNT_DAMPED]++;
13694 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13695 pc->count[PCOUNT_HISTORY]++;
13696 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13697 pc->count[PCOUNT_REMOVED]++;
13698 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13699 pc->count[PCOUNT_STALE]++;
13700 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13701 pc->count[PCOUNT_VALID]++;
13702 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13703 pc->count[PCOUNT_PFCNT]++;
13704 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13705 pc->count[PCOUNT_BPATH_SELECTED]++;
13706
13707 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13708 pc->count[PCOUNT_COUNTED]++;
13709 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13710 flog_err(
13711 EC_LIB_DEVELOPMENT,
13712 "Attempting to count but flags say it is unusable");
13713 } else {
13714 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13715 flog_err(
13716 EC_LIB_DEVELOPMENT,
13717 "Not counted but flags say we should");
13718 }
13719 }
13720 }
13721
13722 static void bgp_peer_count_walker(struct thread *t)
13723 {
13724 struct bgp_dest *rn, *rm;
13725 const struct bgp_table *table;
13726 struct peer_pcounts *pc = THREAD_ARG(t);
13727
13728 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13729 || pc->safi == SAFI_EVPN) {
13730 /* Special handling for 2-level routing tables. */
13731 for (rn = bgp_table_top(pc->table); rn;
13732 rn = bgp_route_next(rn)) {
13733 table = bgp_dest_get_bgp_table_info(rn);
13734 if (table != NULL)
13735 for (rm = bgp_table_top(table); rm;
13736 rm = bgp_route_next(rm))
13737 bgp_peer_count_proc(rm, pc);
13738 }
13739 } else
13740 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13741 bgp_peer_count_proc(rn, pc);
13742 }
13743
13744 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13745 safi_t safi, bool use_json)
13746 {
13747 struct peer_pcounts pcounts = {.peer = peer};
13748 unsigned int i;
13749 json_object *json = NULL;
13750 json_object *json_loop = NULL;
13751
13752 if (use_json) {
13753 json = json_object_new_object();
13754 json_loop = json_object_new_object();
13755 }
13756
13757 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13758 || !peer->bgp->rib[afi][safi]) {
13759 if (use_json) {
13760 json_object_string_add(
13761 json, "warning",
13762 "No such neighbor or address family");
13763 vty_out(vty, "%s\n", json_object_to_json_string(json));
13764 json_object_free(json);
13765 json_object_free(json_loop);
13766 } else
13767 vty_out(vty, "%% No such neighbor or address family\n");
13768
13769 return CMD_WARNING;
13770 }
13771
13772 memset(&pcounts, 0, sizeof(pcounts));
13773 pcounts.peer = peer;
13774 pcounts.table = peer->bgp->rib[afi][safi];
13775 pcounts.safi = safi;
13776
13777 /* in-place call via thread subsystem so as to record execution time
13778 * stats for the thread-walk (i.e. ensure this can't be blamed on
13779 * on just vty_read()).
13780 */
13781 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13782
13783 if (use_json) {
13784 json_object_string_add(json, "prefixCountsFor", peer->host);
13785 json_object_string_add(json, "multiProtocol",
13786 get_afi_safi_str(afi, safi, true));
13787 json_object_int_add(json, "pfxCounter",
13788 peer->pcount[afi][safi]);
13789
13790 for (i = 0; i < PCOUNT_MAX; i++)
13791 json_object_int_add(json_loop, pcount_strs[i],
13792 pcounts.count[i]);
13793
13794 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13795
13796 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13797 json_object_string_add(json, "pfxctDriftFor",
13798 peer->host);
13799 json_object_string_add(
13800 json, "recommended",
13801 "Please report this bug, with the above command output");
13802 }
13803 vty_json(vty, json);
13804 } else {
13805
13806 if (peer->hostname
13807 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13808 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13809 peer->hostname, peer->host,
13810 get_afi_safi_str(afi, safi, false));
13811 } else {
13812 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13813 get_afi_safi_str(afi, safi, false));
13814 }
13815
13816 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13817 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13818
13819 for (i = 0; i < PCOUNT_MAX; i++)
13820 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13821 pcounts.count[i]);
13822
13823 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13824 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13825 vty_out(vty,
13826 "Please report this bug, with the above command output\n");
13827 }
13828 }
13829
13830 return CMD_SUCCESS;
13831 }
13832
13833 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13834 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13835 "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]",
13836 SHOW_STR
13837 IP_STR
13838 BGP_STR
13839 BGP_INSTANCE_HELP_STR
13840 BGP_AFI_HELP_STR
13841 BGP_SAFI_HELP_STR
13842 "Detailed information on TCP and BGP neighbor connections\n"
13843 "Neighbor to display information about\n"
13844 "Neighbor to display information about\n"
13845 "Neighbor on BGP configured interface\n"
13846 "Display detailed prefix count information\n"
13847 JSON_STR)
13848 {
13849 afi_t afi = AFI_IP6;
13850 safi_t safi = SAFI_UNICAST;
13851 struct peer *peer;
13852 int idx = 0;
13853 struct bgp *bgp = NULL;
13854 bool uj = use_json(argc, argv);
13855
13856 if (uj)
13857 argc--;
13858
13859 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13860 &bgp, uj);
13861 if (!idx)
13862 return CMD_WARNING;
13863
13864 argv_find(argv, argc, "neighbors", &idx);
13865 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13866 if (!peer)
13867 return CMD_WARNING;
13868
13869 return bgp_peer_counts(vty, peer, afi, safi, uj);
13870 }
13871
13872 #ifdef KEEP_OLD_VPN_COMMANDS
13873 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13874 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13875 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13876 SHOW_STR
13877 IP_STR
13878 BGP_STR
13879 BGP_VPNVX_HELP_STR
13880 "Display information about all VPNv4 NLRIs\n"
13881 "Detailed information on TCP and BGP neighbor connections\n"
13882 "Neighbor to display information about\n"
13883 "Neighbor to display information about\n"
13884 "Neighbor on BGP configured interface\n"
13885 "Display detailed prefix count information\n"
13886 JSON_STR)
13887 {
13888 int idx_peer = 6;
13889 struct peer *peer;
13890 bool uj = use_json(argc, argv);
13891
13892 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13893 if (!peer)
13894 return CMD_WARNING;
13895
13896 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13897 }
13898
13899 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13900 show_ip_bgp_vpn_all_route_prefix_cmd,
13901 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13902 SHOW_STR
13903 IP_STR
13904 BGP_STR
13905 BGP_VPNVX_HELP_STR
13906 "Display information about all VPNv4 NLRIs\n"
13907 "Network in the BGP routing table to display\n"
13908 "Network in the BGP routing table to display\n"
13909 JSON_STR)
13910 {
13911 int idx = 0;
13912 char *network = NULL;
13913 struct bgp *bgp = bgp_get_default();
13914 if (!bgp) {
13915 vty_out(vty, "Can't find default instance\n");
13916 return CMD_WARNING;
13917 }
13918
13919 if (argv_find(argv, argc, "A.B.C.D", &idx))
13920 network = argv[idx]->arg;
13921 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13922 network = argv[idx]->arg;
13923 else {
13924 vty_out(vty, "Unable to figure out Network\n");
13925 return CMD_WARNING;
13926 }
13927
13928 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13929 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13930 use_json(argc, argv));
13931 }
13932 #endif /* KEEP_OLD_VPN_COMMANDS */
13933
13934 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13935 show_bgp_l2vpn_evpn_route_prefix_cmd,
13936 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13937 SHOW_STR
13938 BGP_STR
13939 L2VPN_HELP_STR
13940 EVPN_HELP_STR
13941 "Network in the BGP routing table to display\n"
13942 "Network in the BGP routing table to display\n"
13943 "Network in the BGP routing table to display\n"
13944 "Network in the BGP routing table to display\n"
13945 JSON_STR)
13946 {
13947 int idx = 0;
13948 char *network = NULL;
13949 int prefix_check = 0;
13950
13951 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13952 argv_find(argv, argc, "X:X::X:X", &idx))
13953 network = argv[idx]->arg;
13954 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13955 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13956 network = argv[idx]->arg;
13957 prefix_check = 1;
13958 } else {
13959 vty_out(vty, "Unable to figure out Network\n");
13960 return CMD_WARNING;
13961 }
13962 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13963 prefix_check, BGP_PATH_SHOW_ALL,
13964 RPKI_NOT_BEING_USED, use_json(argc, argv));
13965 }
13966
13967 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13968 struct bgp_table *table, int *header1,
13969 int *header2, json_object *json,
13970 json_object *json_scode,
13971 json_object *json_ocode, bool wide,
13972 bool detail)
13973 {
13974 uint64_t version = table ? table->version : 0;
13975
13976 if (*header1) {
13977 if (json) {
13978 json_object_int_add(json, "bgpTableVersion", version);
13979 json_object_string_addf(json, "bgpLocalRouterId",
13980 "%pI4", &peer->bgp->router_id);
13981 json_object_int_add(json, "defaultLocPrf",
13982 peer->bgp->default_local_pref);
13983 json_object_int_add(json, "localAS",
13984 peer->change_local_as
13985 ? peer->change_local_as
13986 : peer->local_as);
13987 json_object_object_add(json, "bgpStatusCodes",
13988 json_scode);
13989 json_object_object_add(json, "bgpOriginCodes",
13990 json_ocode);
13991 } else {
13992 vty_out(vty,
13993 "BGP table version is %" PRIu64
13994 ", local router ID is %pI4, vrf id ",
13995 version, &peer->bgp->router_id);
13996 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13997 vty_out(vty, "%s", VRFID_NONE_STR);
13998 else
13999 vty_out(vty, "%u", peer->bgp->vrf_id);
14000 vty_out(vty, "\n");
14001 vty_out(vty, "Default local pref %u, ",
14002 peer->bgp->default_local_pref);
14003 vty_out(vty, "local AS %u\n",
14004 peer->change_local_as ? peer->change_local_as
14005 : peer->local_as);
14006 if (!detail) {
14007 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14008 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14009 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14010 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14011 }
14012 }
14013 *header1 = 0;
14014 }
14015 if (*header2) {
14016 if (!json && !detail)
14017 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14018 : BGP_SHOW_HEADER));
14019 *header2 = 0;
14020 }
14021 }
14022
14023 static void
14024 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14025 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14026 const char *rmap_name, json_object *json, json_object *json_ar,
14027 json_object *json_scode, json_object *json_ocode,
14028 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14029 const struct prefix *match, unsigned long *output_count,
14030 unsigned long *filtered_count)
14031 {
14032 struct bgp_adj_in *ain = NULL;
14033 struct bgp_adj_out *adj = NULL;
14034 struct bgp_dest *dest;
14035 struct bgp *bgp;
14036 struct attr attr;
14037 int ret;
14038 struct update_subgroup *subgrp;
14039 struct peer_af *paf = NULL;
14040 bool route_filtered;
14041 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14042 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14043 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14044 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14045 || (safi == SAFI_EVPN))
14046 ? true
14047 : false;
14048 int display = 0;
14049 json_object *json_net = NULL;
14050
14051 bgp = peer->bgp;
14052
14053 /* If the user supplied a prefix, look for a matching route instead
14054 * of walking the whole table.
14055 */
14056 if (match) {
14057 dest = bgp_node_match(table, match);
14058 if (!dest) {
14059 if (!use_json)
14060 vty_out(vty, "Network not in table\n");
14061 return;
14062 }
14063
14064 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14065
14066 if (rn_p->prefixlen != match->prefixlen) {
14067 if (!use_json)
14068 vty_out(vty, "Network not in table\n");
14069 bgp_dest_unlock_node(dest);
14070 return;
14071 }
14072
14073 if (type == bgp_show_adj_route_received ||
14074 type == bgp_show_adj_route_filtered) {
14075 for (ain = dest->adj_in; ain; ain = ain->next) {
14076 if (ain->peer == peer) {
14077 attr = *ain->attr;
14078 break;
14079 }
14080 }
14081 /* bail out if if adj_out is empty, or
14082 * if the prefix isn't in this peer's
14083 * adj_in
14084 */
14085 if (!ain || ain->peer != peer) {
14086 if (!use_json)
14087 vty_out(vty, "Network not in table\n");
14088 bgp_dest_unlock_node(dest);
14089 return;
14090 }
14091 } else if (type == bgp_show_adj_route_advertised) {
14092 bool peer_found = false;
14093
14094 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14095 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14096 if (paf->peer == peer && adj->attr) {
14097 attr = *adj->attr;
14098 peer_found = true;
14099 break;
14100 }
14101 }
14102 if (peer_found)
14103 break;
14104 }
14105 /* bail out if if adj_out is empty, or
14106 * if the prefix isn't in this peer's
14107 * adj_out
14108 */
14109 if (!paf || !peer_found) {
14110 if (!use_json)
14111 vty_out(vty, "Network not in table\n");
14112 bgp_dest_unlock_node(dest);
14113 return;
14114 }
14115 }
14116
14117 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14118 rmap_name);
14119
14120 if (ret != RMAP_DENY) {
14121 show_adj_route_header(vty, peer, table, header1,
14122 header2, json, json_scode,
14123 json_ocode, wide, detail);
14124
14125 if (use_json)
14126 json_net = json_object_new_object();
14127
14128 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14129 afi, safi, json_net,
14130 BGP_PATH_SHOW_ALL, &display,
14131 RPKI_NOT_BEING_USED);
14132 if (use_json)
14133 json_object_object_addf(json_ar, json_net,
14134 "%pFX", rn_p);
14135 (*output_count)++;
14136 } else
14137 (*filtered_count)++;
14138
14139 bgp_attr_flush(&attr);
14140 bgp_dest_unlock_node(dest);
14141 return;
14142 }
14143
14144
14145 subgrp = peer_subgroup(peer, afi, safi);
14146
14147 if (type == bgp_show_adj_route_advertised && subgrp
14148 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14149 if (use_json) {
14150 json_object_int_add(json, "bgpTableVersion",
14151 table->version);
14152 json_object_string_addf(json, "bgpLocalRouterId",
14153 "%pI4", &bgp->router_id);
14154 json_object_int_add(json, "defaultLocPrf",
14155 bgp->default_local_pref);
14156 json_object_int_add(json, "localAS",
14157 peer->change_local_as
14158 ? peer->change_local_as
14159 : peer->local_as);
14160 json_object_object_add(json, "bgpStatusCodes",
14161 json_scode);
14162 json_object_object_add(json, "bgpOriginCodes",
14163 json_ocode);
14164 json_object_string_add(
14165 json, "bgpOriginatingDefaultNetwork",
14166 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14167 } else {
14168 vty_out(vty,
14169 "BGP table version is %" PRIu64
14170 ", local router ID is %pI4, vrf id ",
14171 table->version, &bgp->router_id);
14172 if (bgp->vrf_id == VRF_UNKNOWN)
14173 vty_out(vty, "%s", VRFID_NONE_STR);
14174 else
14175 vty_out(vty, "%u", bgp->vrf_id);
14176 vty_out(vty, "\n");
14177 vty_out(vty, "Default local pref %u, ",
14178 bgp->default_local_pref);
14179 vty_out(vty, "local AS %u\n",
14180 peer->change_local_as ? peer->change_local_as
14181 : peer->local_as);
14182 if (!detail) {
14183 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14184 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14185 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14186 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14187 }
14188
14189 vty_out(vty, "Originating default network %s\n\n",
14190 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14191 }
14192 (*output_count)++;
14193 *header1 = 0;
14194 }
14195
14196 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14197 if (type == bgp_show_adj_route_received
14198 || type == bgp_show_adj_route_filtered) {
14199 for (ain = dest->adj_in; ain; ain = ain->next) {
14200 if (ain->peer != peer)
14201 continue;
14202
14203 show_adj_route_header(vty, peer, table, header1,
14204 header2, json, json_scode,
14205 json_ocode, wide, detail);
14206
14207 if ((safi == SAFI_MPLS_VPN)
14208 || (safi == SAFI_ENCAP)
14209 || (safi == SAFI_EVPN)) {
14210 if (use_json)
14211 json_object_string_add(
14212 json_ar, "rd", rd_str);
14213 else if (show_rd && rd_str) {
14214 vty_out(vty,
14215 "Route Distinguisher: %s\n",
14216 rd_str);
14217 show_rd = false;
14218 }
14219 }
14220
14221 attr = *ain->attr;
14222 route_filtered = false;
14223
14224 /* Filter prefix using distribute list,
14225 * filter list or prefix list
14226 */
14227 const struct prefix *rn_p =
14228 bgp_dest_get_prefix(dest);
14229 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14230 safi))
14231 == FILTER_DENY)
14232 route_filtered = true;
14233
14234 /* Filter prefix using route-map */
14235 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14236 safi, rmap_name, NULL,
14237 0, NULL);
14238
14239 if (type == bgp_show_adj_route_filtered &&
14240 !route_filtered && ret != RMAP_DENY) {
14241 bgp_attr_flush(&attr);
14242 continue;
14243 }
14244
14245 if (type == bgp_show_adj_route_received
14246 && (route_filtered || ret == RMAP_DENY))
14247 (*filtered_count)++;
14248
14249 if (detail) {
14250 if (use_json)
14251 json_net =
14252 json_object_new_object();
14253 bgp_show_path_info(
14254 NULL /* prefix_rd */, dest, vty,
14255 bgp, afi, safi, json_net,
14256 BGP_PATH_SHOW_ALL, &display,
14257 RPKI_NOT_BEING_USED);
14258 if (use_json)
14259 json_object_object_addf(
14260 json_ar, json_net,
14261 "%pFX", rn_p);
14262 } else
14263 route_vty_out_tmp(vty, dest, rn_p,
14264 &attr, safi, use_json,
14265 json_ar, wide);
14266 bgp_attr_flush(&attr);
14267 (*output_count)++;
14268 }
14269 } else if (type == bgp_show_adj_route_advertised) {
14270 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14271 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14272 if (paf->peer != peer || !adj->attr)
14273 continue;
14274
14275 show_adj_route_header(
14276 vty, peer, table, header1,
14277 header2, json, json_scode,
14278 json_ocode, wide, detail);
14279
14280 const struct prefix *rn_p =
14281 bgp_dest_get_prefix(dest);
14282
14283 attr = *adj->attr;
14284 ret = bgp_output_modifier(
14285 peer, rn_p, &attr, afi, safi,
14286 rmap_name);
14287
14288 if (ret != RMAP_DENY) {
14289 if ((safi == SAFI_MPLS_VPN)
14290 || (safi == SAFI_ENCAP)
14291 || (safi == SAFI_EVPN)) {
14292 if (use_json)
14293 json_object_string_add(
14294 json_ar,
14295 "rd",
14296 rd_str);
14297 else if (show_rd
14298 && rd_str) {
14299 vty_out(vty,
14300 "Route Distinguisher: %s\n",
14301 rd_str);
14302 show_rd = false;
14303 }
14304 }
14305 if (detail) {
14306 if (use_json)
14307 json_net =
14308 json_object_new_object();
14309 bgp_show_path_info(
14310 NULL /* prefix_rd
14311 */
14312 ,
14313 dest, vty, bgp,
14314 afi, safi,
14315 json_net,
14316 BGP_PATH_SHOW_ALL,
14317 &display,
14318 RPKI_NOT_BEING_USED);
14319 if (use_json)
14320 json_object_object_addf(
14321 json_ar,
14322 json_net,
14323 "%pFX",
14324 rn_p);
14325 } else
14326 route_vty_out_tmp(
14327 vty, dest, rn_p,
14328 &attr, safi,
14329 use_json,
14330 json_ar, wide);
14331 (*output_count)++;
14332 } else {
14333 (*filtered_count)++;
14334 }
14335
14336 bgp_attr_flush(&attr);
14337 }
14338 } else if (type == bgp_show_adj_route_bestpath) {
14339 struct bgp_path_info *pi;
14340
14341 show_adj_route_header(vty, peer, table, header1,
14342 header2, json, json_scode,
14343 json_ocode, wide, detail);
14344
14345 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14346
14347 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14348 pi = pi->next) {
14349 if (pi->peer != peer)
14350 continue;
14351
14352 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14353 continue;
14354
14355 if (detail) {
14356 if (use_json)
14357 json_net =
14358 json_object_new_object();
14359 bgp_show_path_info(
14360 NULL /* prefix_rd */, dest, vty,
14361 bgp, afi, safi, json_net,
14362 BGP_PATH_SHOW_BESTPATH,
14363 &display, RPKI_NOT_BEING_USED);
14364 if (use_json)
14365 json_object_object_addf(
14366 json_ar, json_net,
14367 "%pFX", rn_p);
14368 } else
14369 route_vty_out_tmp(
14370 vty, dest, rn_p, pi->attr, safi,
14371 use_json, json_ar, wide);
14372 (*output_count)++;
14373 }
14374 }
14375 }
14376 }
14377
14378 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14379 safi_t safi, enum bgp_show_adj_route_type type,
14380 const char *rmap_name, const struct prefix *match,
14381 uint16_t show_flags)
14382 {
14383 struct bgp *bgp;
14384 struct bgp_table *table;
14385 json_object *json = NULL;
14386 json_object *json_scode = NULL;
14387 json_object *json_ocode = NULL;
14388 json_object *json_ar = NULL;
14389 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14390
14391 /* Init BGP headers here so they're only displayed once
14392 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14393 */
14394 int header1 = 1;
14395 int header2 = 1;
14396
14397 /*
14398 * Initialize variables for each RD
14399 * All prefixes under an RD is aggregated within "json_routes"
14400 */
14401 char rd_str[BUFSIZ] = {0};
14402 json_object *json_routes = NULL;
14403
14404
14405 /* For 2-tier tables, prefix counts need to be
14406 * maintained across multiple runs of show_adj_route()
14407 */
14408 unsigned long output_count_per_rd;
14409 unsigned long filtered_count_per_rd;
14410 unsigned long output_count = 0;
14411 unsigned long filtered_count = 0;
14412
14413 if (use_json) {
14414 json = json_object_new_object();
14415 json_ar = json_object_new_object();
14416 json_scode = json_object_new_object();
14417 json_ocode = json_object_new_object();
14418 #if CONFDATE > 20231208
14419 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14420 #endif
14421 json_object_string_add(json_scode, "suppressed", "s");
14422 json_object_string_add(json_scode, "damped", "d");
14423 json_object_string_add(json_scode, "history", "h");
14424 json_object_string_add(json_scode, "valid", "*");
14425 json_object_string_add(json_scode, "best", ">");
14426 json_object_string_add(json_scode, "multipath", "=");
14427 json_object_string_add(json_scode, "internal", "i");
14428 json_object_string_add(json_scode, "ribFailure", "r");
14429 json_object_string_add(json_scode, "stale", "S");
14430 json_object_string_add(json_scode, "removed", "R");
14431
14432 #if CONFDATE > 20231208
14433 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14434 #endif
14435 json_object_string_add(json_ocode, "igp", "i");
14436 json_object_string_add(json_ocode, "egp", "e");
14437 json_object_string_add(json_ocode, "incomplete", "?");
14438 }
14439
14440 if (!peer || !peer->afc[afi][safi]) {
14441 if (use_json) {
14442 json_object_string_add(
14443 json, "warning",
14444 "No such neighbor or address family");
14445 vty_out(vty, "%s\n", json_object_to_json_string(json));
14446 json_object_free(json);
14447 json_object_free(json_ar);
14448 json_object_free(json_scode);
14449 json_object_free(json_ocode);
14450 } else
14451 vty_out(vty, "%% No such neighbor or address family\n");
14452
14453 return CMD_WARNING;
14454 }
14455
14456 if ((type == bgp_show_adj_route_received
14457 || type == bgp_show_adj_route_filtered)
14458 && !CHECK_FLAG(peer->af_flags[afi][safi],
14459 PEER_FLAG_SOFT_RECONFIG)) {
14460 if (use_json) {
14461 json_object_string_add(
14462 json, "warning",
14463 "Inbound soft reconfiguration not enabled");
14464 vty_out(vty, "%s\n", json_object_to_json_string(json));
14465 json_object_free(json);
14466 json_object_free(json_ar);
14467 json_object_free(json_scode);
14468 json_object_free(json_ocode);
14469 } else
14470 vty_out(vty,
14471 "%% Inbound soft reconfiguration not enabled\n");
14472
14473 return CMD_WARNING;
14474 }
14475
14476 bgp = peer->bgp;
14477
14478 /* labeled-unicast routes live in the unicast table */
14479 if (safi == SAFI_LABELED_UNICAST)
14480 table = bgp->rib[afi][SAFI_UNICAST];
14481 else
14482 table = bgp->rib[afi][safi];
14483
14484 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14485 || (safi == SAFI_EVPN)) {
14486
14487 struct bgp_dest *dest;
14488
14489 for (dest = bgp_table_top(table); dest;
14490 dest = bgp_route_next(dest)) {
14491 table = bgp_dest_get_bgp_table_info(dest);
14492 if (!table)
14493 continue;
14494
14495 output_count_per_rd = 0;
14496 filtered_count_per_rd = 0;
14497
14498 if (use_json)
14499 json_routes = json_object_new_object();
14500
14501 const struct prefix_rd *prd;
14502 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14503 dest);
14504
14505 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14506 bgp->asnotation);
14507
14508 show_adj_route(
14509 vty, peer, table, afi, safi, type, rmap_name,
14510 json, json_routes, json_scode, json_ocode,
14511 show_flags, &header1, &header2, rd_str, match,
14512 &output_count_per_rd, &filtered_count_per_rd);
14513
14514 /* Don't include an empty RD in the output! */
14515 if (json_routes && (output_count_per_rd > 0))
14516 json_object_object_add(json_ar, rd_str,
14517 json_routes);
14518
14519 output_count += output_count_per_rd;
14520 filtered_count += filtered_count_per_rd;
14521 }
14522 } else
14523 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14524 json, json_ar, json_scode, json_ocode,
14525 show_flags, &header1, &header2, rd_str, match,
14526 &output_count, &filtered_count);
14527
14528 if (use_json) {
14529 if (type == bgp_show_adj_route_advertised)
14530 json_object_object_add(json, "advertisedRoutes",
14531 json_ar);
14532 else
14533 json_object_object_add(json, "receivedRoutes", json_ar);
14534 json_object_int_add(json, "totalPrefixCounter", output_count);
14535 json_object_int_add(json, "filteredPrefixCounter",
14536 filtered_count);
14537
14538 /*
14539 * These fields only give up ownership to `json` when `header1`
14540 * is used (set to zero). See code in `show_adj_route` and
14541 * `show_adj_route_header`.
14542 */
14543 if (header1 == 1) {
14544 json_object_free(json_scode);
14545 json_object_free(json_ocode);
14546 }
14547
14548 vty_json(vty, json);
14549 } else if (output_count > 0) {
14550 if (!match && filtered_count > 0)
14551 vty_out(vty,
14552 "\nTotal number of prefixes %ld (%ld filtered)\n",
14553 output_count, filtered_count);
14554 else
14555 vty_out(vty, "\nTotal number of prefixes %ld\n",
14556 output_count);
14557 }
14558
14559 return CMD_SUCCESS;
14560 }
14561
14562 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14563 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14564 "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]",
14565 SHOW_STR
14566 IP_STR
14567 BGP_STR
14568 BGP_INSTANCE_HELP_STR
14569 BGP_AFI_HELP_STR
14570 BGP_SAFI_WITH_LABEL_HELP_STR
14571 "Detailed information on TCP and BGP neighbor connections\n"
14572 "Neighbor to display information about\n"
14573 "Neighbor to display information about\n"
14574 "Neighbor on BGP configured interface\n"
14575 "Display the routes selected by best path\n"
14576 "Display detailed version of routes\n"
14577 JSON_STR
14578 "Increase table width for longer prefixes\n")
14579 {
14580 afi_t afi = AFI_IP6;
14581 safi_t safi = SAFI_UNICAST;
14582 char *rmap_name = NULL;
14583 char *peerstr = NULL;
14584 struct bgp *bgp = NULL;
14585 struct peer *peer;
14586 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14587 int idx = 0;
14588 uint16_t show_flags = 0;
14589
14590 if (detail)
14591 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14592
14593 if (uj)
14594 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14595
14596 if (wide)
14597 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14598
14599 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14600 &bgp, uj);
14601
14602 if (!idx)
14603 return CMD_WARNING;
14604
14605 argv_find(argv, argc, "neighbors", &idx);
14606 peerstr = argv[++idx]->arg;
14607
14608 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14609 if (!peer)
14610 return CMD_WARNING;
14611
14612 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14613 show_flags);
14614 }
14615
14616 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14617 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14618 "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]",
14619 SHOW_STR
14620 IP_STR
14621 BGP_STR
14622 BGP_INSTANCE_HELP_STR
14623 BGP_AFI_HELP_STR
14624 BGP_SAFI_WITH_LABEL_HELP_STR
14625 "Display the entries for all address families\n"
14626 "Detailed information on TCP and BGP neighbor connections\n"
14627 "Neighbor to display information about\n"
14628 "Neighbor to display information about\n"
14629 "Neighbor on BGP configured interface\n"
14630 "Display the routes advertised to a BGP neighbor\n"
14631 "Display the received routes from neighbor\n"
14632 "Display the filtered routes received from neighbor\n"
14633 "Route-map to modify the attributes\n"
14634 "Name of the route map\n"
14635 "IPv4 prefix\n"
14636 "IPv6 prefix\n"
14637 "Display detailed version of routes\n"
14638 JSON_STR
14639 "Increase table width for longer prefixes\n")
14640 {
14641 afi_t afi = AFI_IP6;
14642 safi_t safi = SAFI_UNICAST;
14643 char *peerstr = NULL;
14644 struct bgp *bgp = NULL;
14645 struct peer *peer;
14646 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14647 int idx = 0;
14648 bool first = true;
14649 uint16_t show_flags = 0;
14650 struct listnode *node;
14651 struct bgp *abgp;
14652
14653 if (detail || prefix_str)
14654 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14655
14656 if (uj) {
14657 argc--;
14658 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14659 }
14660
14661 if (all) {
14662 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14663 if (argv_find(argv, argc, "ipv4", &idx))
14664 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14665
14666 if (argv_find(argv, argc, "ipv6", &idx))
14667 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14668 }
14669
14670 if (wide)
14671 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14672
14673 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14674 &bgp, uj);
14675 if (!idx)
14676 return CMD_WARNING;
14677
14678 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14679 argv_find(argv, argc, "neighbors", &idx);
14680 peerstr = argv[++idx]->arg;
14681
14682 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14683 if (!peer)
14684 return CMD_WARNING;
14685
14686 if (argv_find(argv, argc, "advertised-routes", &idx))
14687 type = bgp_show_adj_route_advertised;
14688 else if (argv_find(argv, argc, "received-routes", &idx))
14689 type = bgp_show_adj_route_received;
14690 else if (argv_find(argv, argc, "filtered-routes", &idx))
14691 type = bgp_show_adj_route_filtered;
14692
14693 if (!all)
14694 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14695 prefix_str ? prefix : NULL, show_flags);
14696 if (uj)
14697 vty_out(vty, "{\n");
14698
14699 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14700 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14701 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14702 : AFI_IP6;
14703 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14704 FOREACH_SAFI (safi) {
14705 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14706 continue;
14707
14708 if (uj) {
14709 if (first)
14710 first = false;
14711 else
14712 vty_out(vty, ",\n");
14713 vty_out(vty, "\"%s\":",
14714 get_afi_safi_str(afi, safi,
14715 true));
14716 } else
14717 vty_out(vty,
14718 "\nFor address family: %s\n",
14719 get_afi_safi_str(afi, safi,
14720 false));
14721
14722 peer_adj_routes(vty, peer, afi, safi, type,
14723 route_map, prefix, show_flags);
14724 }
14725 }
14726 } else {
14727 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14728 FOREACH_AFI_SAFI (afi, safi) {
14729 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14730 continue;
14731
14732 if (uj) {
14733 if (first)
14734 first = false;
14735 else
14736 vty_out(vty, ",\n");
14737 vty_out(vty, "\"%s\":",
14738 get_afi_safi_str(afi, safi,
14739 true));
14740 } else
14741 vty_out(vty,
14742 "\nFor address family: %s\n",
14743 get_afi_safi_str(afi, safi,
14744 false));
14745
14746 peer_adj_routes(vty, peer, afi, safi, type,
14747 route_map, prefix, show_flags);
14748 }
14749 }
14750 }
14751 if (uj)
14752 vty_out(vty, "}\n");
14753
14754 return CMD_SUCCESS;
14755 }
14756
14757 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14758 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14759 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14760 SHOW_STR
14761 IP_STR
14762 BGP_STR
14763 BGP_INSTANCE_HELP_STR
14764 BGP_AF_STR
14765 BGP_AF_STR
14766 BGP_AF_MODIFIER_STR
14767 "Detailed information on TCP and BGP neighbor connections\n"
14768 "Neighbor to display information about\n"
14769 "Neighbor to display information about\n"
14770 "Neighbor on BGP configured interface\n"
14771 "Display information received from a BGP neighbor\n"
14772 "Display the prefixlist filter\n"
14773 JSON_STR)
14774 {
14775 afi_t afi = AFI_IP6;
14776 safi_t safi = SAFI_UNICAST;
14777 char *peerstr = NULL;
14778 char name[BUFSIZ];
14779 struct peer *peer;
14780 int count;
14781 int idx = 0;
14782 struct bgp *bgp = NULL;
14783 bool uj = use_json(argc, argv);
14784
14785 if (uj)
14786 argc--;
14787
14788 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14789 &bgp, uj);
14790 if (!idx)
14791 return CMD_WARNING;
14792
14793 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14794 argv_find(argv, argc, "neighbors", &idx);
14795 peerstr = argv[++idx]->arg;
14796
14797 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14798 if (!peer)
14799 return CMD_WARNING;
14800
14801 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14802 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14803 if (count) {
14804 if (!uj)
14805 vty_out(vty, "Address Family: %s\n",
14806 get_afi_safi_str(afi, safi, false));
14807 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14808 } else {
14809 if (uj)
14810 vty_out(vty, "{}\n");
14811 else
14812 vty_out(vty, "No functional output\n");
14813 }
14814
14815 return CMD_SUCCESS;
14816 }
14817
14818 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14819 afi_t afi, safi_t safi,
14820 enum bgp_show_type type, bool use_json)
14821 {
14822 uint16_t show_flags = 0;
14823
14824 if (use_json)
14825 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14826
14827 if (!peer || !peer->afc[afi][safi]) {
14828 if (use_json) {
14829 json_object *json_no = NULL;
14830 json_no = json_object_new_object();
14831 json_object_string_add(
14832 json_no, "warning",
14833 "No such neighbor or address family");
14834 vty_out(vty, "%s\n",
14835 json_object_to_json_string(json_no));
14836 json_object_free(json_no);
14837 } else
14838 vty_out(vty, "%% No such neighbor or address family\n");
14839 return CMD_WARNING;
14840 }
14841
14842 /* labeled-unicast routes live in the unicast table */
14843 if (safi == SAFI_LABELED_UNICAST)
14844 safi = SAFI_UNICAST;
14845
14846 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14847 RPKI_NOT_BEING_USED);
14848 }
14849
14850 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14851 show_ip_bgp_flowspec_routes_detailed_cmd,
14852 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14853 SHOW_STR
14854 IP_STR
14855 BGP_STR
14856 BGP_INSTANCE_HELP_STR
14857 BGP_AFI_HELP_STR
14858 "SAFI Flowspec\n"
14859 "Detailed information on flowspec entries\n"
14860 JSON_STR)
14861 {
14862 afi_t afi = AFI_IP6;
14863 safi_t safi = SAFI_UNICAST;
14864 struct bgp *bgp = NULL;
14865 int idx = 0;
14866 bool uj = use_json(argc, argv);
14867 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14868
14869 if (uj) {
14870 argc--;
14871 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14872 }
14873
14874 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14875 &bgp, uj);
14876 if (!idx)
14877 return CMD_WARNING;
14878
14879 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14880 show_flags, RPKI_NOT_BEING_USED);
14881 }
14882
14883 DEFUN (show_ip_bgp_neighbor_routes,
14884 show_ip_bgp_neighbor_routes_cmd,
14885 "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]",
14886 SHOW_STR
14887 IP_STR
14888 BGP_STR
14889 BGP_INSTANCE_HELP_STR
14890 BGP_AFI_HELP_STR
14891 BGP_SAFI_WITH_LABEL_HELP_STR
14892 "Detailed information on TCP and BGP neighbor connections\n"
14893 "Neighbor to display information about\n"
14894 "Neighbor to display information about\n"
14895 "Neighbor on BGP configured interface\n"
14896 "Display flap statistics of the routes learned from neighbor\n"
14897 "Display the dampened routes received from neighbor\n"
14898 "Display routes learned from neighbor\n"
14899 JSON_STR)
14900 {
14901 char *peerstr = NULL;
14902 struct bgp *bgp = NULL;
14903 afi_t afi = AFI_IP6;
14904 safi_t safi = SAFI_UNICAST;
14905 struct peer *peer;
14906 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14907 int idx = 0;
14908 bool uj = use_json(argc, argv);
14909
14910 if (uj)
14911 argc--;
14912
14913 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14914 &bgp, uj);
14915 if (!idx)
14916 return CMD_WARNING;
14917
14918 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14919 argv_find(argv, argc, "neighbors", &idx);
14920 peerstr = argv[++idx]->arg;
14921
14922 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14923 if (!peer)
14924 return CMD_WARNING;
14925
14926 if (argv_find(argv, argc, "flap-statistics", &idx))
14927 sh_type = bgp_show_type_flap_neighbor;
14928 else if (argv_find(argv, argc, "dampened-routes", &idx))
14929 sh_type = bgp_show_type_damp_neighbor;
14930 else if (argv_find(argv, argc, "routes", &idx))
14931 sh_type = bgp_show_type_neighbor;
14932
14933 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14934 }
14935
14936 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14937
14938 struct bgp_distance {
14939 /* Distance value for the IP source prefix. */
14940 uint8_t distance;
14941
14942 /* Name of the access-list to be matched. */
14943 char *access_list;
14944 };
14945
14946 DEFUN (show_bgp_afi_vpn_rd_route,
14947 show_bgp_afi_vpn_rd_route_cmd,
14948 "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]",
14949 SHOW_STR
14950 BGP_STR
14951 BGP_AFI_HELP_STR
14952 BGP_AF_MODIFIER_STR
14953 "Display information for a route distinguisher\n"
14954 "Route Distinguisher\n"
14955 "All Route Distinguishers\n"
14956 "Network in the BGP routing table to display\n"
14957 "Network in the BGP routing table to display\n"
14958 JSON_STR)
14959 {
14960 int ret;
14961 struct prefix_rd prd;
14962 afi_t afi = AFI_MAX;
14963 int idx = 0;
14964
14965 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14966 vty_out(vty, "%% Malformed Address Family\n");
14967 return CMD_WARNING;
14968 }
14969
14970 if (!strcmp(argv[5]->arg, "all"))
14971 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14972 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14973 RPKI_NOT_BEING_USED,
14974 use_json(argc, argv));
14975
14976 ret = str2prefix_rd(argv[5]->arg, &prd);
14977 if (!ret) {
14978 vty_out(vty, "%% Malformed Route Distinguisher\n");
14979 return CMD_WARNING;
14980 }
14981
14982 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14983 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14984 use_json(argc, argv));
14985 }
14986
14987 static struct bgp_distance *bgp_distance_new(void)
14988 {
14989 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14990 }
14991
14992 static void bgp_distance_free(struct bgp_distance *bdistance)
14993 {
14994 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14995 }
14996
14997 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14998 const char *ip_str, const char *access_list_str)
14999 {
15000 int ret;
15001 afi_t afi;
15002 safi_t safi;
15003 struct prefix p;
15004 uint8_t distance;
15005 struct bgp_dest *dest;
15006 struct bgp_distance *bdistance;
15007
15008 afi = bgp_node_afi(vty);
15009 safi = bgp_node_safi(vty);
15010
15011 ret = str2prefix(ip_str, &p);
15012 if (ret == 0) {
15013 vty_out(vty, "Malformed prefix\n");
15014 return CMD_WARNING_CONFIG_FAILED;
15015 }
15016
15017 distance = atoi(distance_str);
15018
15019 /* Get BGP distance node. */
15020 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15021 bdistance = bgp_dest_get_bgp_distance_info(dest);
15022 if (bdistance)
15023 bgp_dest_unlock_node(dest);
15024 else {
15025 bdistance = bgp_distance_new();
15026 bgp_dest_set_bgp_distance_info(dest, bdistance);
15027 }
15028
15029 /* Set distance value. */
15030 bdistance->distance = distance;
15031
15032 /* Reset access-list configuration. */
15033 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15034 if (access_list_str)
15035 bdistance->access_list =
15036 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15037
15038 return CMD_SUCCESS;
15039 }
15040
15041 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15042 const char *ip_str, const char *access_list_str)
15043 {
15044 int ret;
15045 afi_t afi;
15046 safi_t safi;
15047 struct prefix p;
15048 int distance;
15049 struct bgp_dest *dest;
15050 struct bgp_distance *bdistance;
15051
15052 afi = bgp_node_afi(vty);
15053 safi = bgp_node_safi(vty);
15054
15055 ret = str2prefix(ip_str, &p);
15056 if (ret == 0) {
15057 vty_out(vty, "Malformed prefix\n");
15058 return CMD_WARNING_CONFIG_FAILED;
15059 }
15060
15061 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15062 if (!dest) {
15063 vty_out(vty, "Can't find specified prefix\n");
15064 return CMD_WARNING_CONFIG_FAILED;
15065 }
15066
15067 bdistance = bgp_dest_get_bgp_distance_info(dest);
15068 distance = atoi(distance_str);
15069
15070 if (bdistance->distance != distance) {
15071 vty_out(vty, "Distance does not match configured\n");
15072 bgp_dest_unlock_node(dest);
15073 return CMD_WARNING_CONFIG_FAILED;
15074 }
15075
15076 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15077 bgp_distance_free(bdistance);
15078
15079 bgp_dest_set_bgp_path_info(dest, NULL);
15080 bgp_dest_unlock_node(dest);
15081 bgp_dest_unlock_node(dest);
15082
15083 return CMD_SUCCESS;
15084 }
15085
15086 /* Apply BGP information to distance method. */
15087 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15088 afi_t afi, safi_t safi, struct bgp *bgp)
15089 {
15090 struct bgp_dest *dest;
15091 struct prefix q = {0};
15092 struct peer *peer;
15093 struct bgp_distance *bdistance;
15094 struct access_list *alist;
15095 struct bgp_static *bgp_static;
15096 struct bgp_path_info *bpi_ultimate;
15097
15098 if (!bgp)
15099 return 0;
15100
15101 peer = pinfo->peer;
15102
15103 if (pinfo->attr->distance)
15104 return pinfo->attr->distance;
15105
15106 /* get peer origin to calculate appropriate distance */
15107 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15108 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15109 peer = bpi_ultimate->peer;
15110 }
15111
15112 /* Check source address.
15113 * Note: for aggregate route, peer can have unspec af type.
15114 */
15115 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15116 && !sockunion2hostprefix(&peer->su, &q))
15117 return 0;
15118
15119 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15120 if (dest) {
15121 bdistance = bgp_dest_get_bgp_distance_info(dest);
15122 bgp_dest_unlock_node(dest);
15123
15124 if (bdistance->access_list) {
15125 alist = access_list_lookup(afi, bdistance->access_list);
15126 if (alist
15127 && access_list_apply(alist, p) == FILTER_PERMIT)
15128 return bdistance->distance;
15129 } else
15130 return bdistance->distance;
15131 }
15132
15133 /* Backdoor check. */
15134 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15135 if (dest) {
15136 bgp_static = bgp_dest_get_bgp_static_info(dest);
15137 bgp_dest_unlock_node(dest);
15138
15139 if (bgp_static->backdoor) {
15140 if (bgp->distance_local[afi][safi])
15141 return bgp->distance_local[afi][safi];
15142 else
15143 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15144 }
15145 }
15146
15147 if (peer->sort == BGP_PEER_EBGP) {
15148 if (bgp->distance_ebgp[afi][safi])
15149 return bgp->distance_ebgp[afi][safi];
15150 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15151 } else if (peer->sort == BGP_PEER_IBGP) {
15152 if (bgp->distance_ibgp[afi][safi])
15153 return bgp->distance_ibgp[afi][safi];
15154 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15155 } else {
15156 if (bgp->distance_local[afi][safi])
15157 return bgp->distance_local[afi][safi];
15158 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15159 }
15160 }
15161
15162 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15163 * we should tell ZEBRA update the routes for a specific
15164 * AFI/SAFI to reflect changes in RIB.
15165 */
15166 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15167 afi_t update_afi,
15168 safi_t update_safi)
15169 {
15170 afi_t afi;
15171 safi_t safi;
15172
15173 FOREACH_AFI_SAFI (afi, safi) {
15174 if (!bgp_fibupd_safi(safi))
15175 continue;
15176
15177 if (afi != update_afi && safi != update_safi)
15178 continue;
15179
15180 if (BGP_DEBUG(zebra, ZEBRA))
15181 zlog_debug(
15182 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15183 __func__, afi, safi);
15184 bgp_zebra_announce_table(bgp, afi, safi);
15185 }
15186 }
15187
15188 DEFUN (bgp_distance,
15189 bgp_distance_cmd,
15190 "distance bgp (1-255) (1-255) (1-255)",
15191 "Define an administrative distance\n"
15192 "BGP distance\n"
15193 "Distance for routes external to the AS\n"
15194 "Distance for routes internal to the AS\n"
15195 "Distance for local routes\n")
15196 {
15197 VTY_DECLVAR_CONTEXT(bgp, bgp);
15198 int idx_number = 2;
15199 int idx_number_2 = 3;
15200 int idx_number_3 = 4;
15201 int distance_ebgp = atoi(argv[idx_number]->arg);
15202 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15203 int distance_local = atoi(argv[idx_number_3]->arg);
15204 afi_t afi;
15205 safi_t safi;
15206
15207 afi = bgp_node_afi(vty);
15208 safi = bgp_node_safi(vty);
15209
15210 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15211 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15212 || bgp->distance_local[afi][safi] != distance_local) {
15213 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15214 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15215 bgp->distance_local[afi][safi] = distance_local;
15216 bgp_announce_routes_distance_update(bgp, afi, safi);
15217 }
15218 return CMD_SUCCESS;
15219 }
15220
15221 DEFUN (no_bgp_distance,
15222 no_bgp_distance_cmd,
15223 "no distance bgp [(1-255) (1-255) (1-255)]",
15224 NO_STR
15225 "Define an administrative distance\n"
15226 "BGP distance\n"
15227 "Distance for routes external to the AS\n"
15228 "Distance for routes internal to the AS\n"
15229 "Distance for local routes\n")
15230 {
15231 VTY_DECLVAR_CONTEXT(bgp, bgp);
15232 afi_t afi;
15233 safi_t safi;
15234
15235 afi = bgp_node_afi(vty);
15236 safi = bgp_node_safi(vty);
15237
15238 if (bgp->distance_ebgp[afi][safi] != 0
15239 || bgp->distance_ibgp[afi][safi] != 0
15240 || bgp->distance_local[afi][safi] != 0) {
15241 bgp->distance_ebgp[afi][safi] = 0;
15242 bgp->distance_ibgp[afi][safi] = 0;
15243 bgp->distance_local[afi][safi] = 0;
15244 bgp_announce_routes_distance_update(bgp, afi, safi);
15245 }
15246 return CMD_SUCCESS;
15247 }
15248
15249
15250 DEFUN (bgp_distance_source,
15251 bgp_distance_source_cmd,
15252 "distance (1-255) A.B.C.D/M",
15253 "Define an administrative distance\n"
15254 "Administrative distance\n"
15255 "IP source prefix\n")
15256 {
15257 int idx_number = 1;
15258 int idx_ipv4_prefixlen = 2;
15259 bgp_distance_set(vty, argv[idx_number]->arg,
15260 argv[idx_ipv4_prefixlen]->arg, NULL);
15261 return CMD_SUCCESS;
15262 }
15263
15264 DEFUN (no_bgp_distance_source,
15265 no_bgp_distance_source_cmd,
15266 "no distance (1-255) A.B.C.D/M",
15267 NO_STR
15268 "Define an administrative distance\n"
15269 "Administrative distance\n"
15270 "IP source prefix\n")
15271 {
15272 int idx_number = 2;
15273 int idx_ipv4_prefixlen = 3;
15274 bgp_distance_unset(vty, argv[idx_number]->arg,
15275 argv[idx_ipv4_prefixlen]->arg, NULL);
15276 return CMD_SUCCESS;
15277 }
15278
15279 DEFUN (bgp_distance_source_access_list,
15280 bgp_distance_source_access_list_cmd,
15281 "distance (1-255) A.B.C.D/M WORD",
15282 "Define an administrative distance\n"
15283 "Administrative distance\n"
15284 "IP source prefix\n"
15285 "Access list name\n")
15286 {
15287 int idx_number = 1;
15288 int idx_ipv4_prefixlen = 2;
15289 int idx_word = 3;
15290 bgp_distance_set(vty, argv[idx_number]->arg,
15291 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15292 return CMD_SUCCESS;
15293 }
15294
15295 DEFUN (no_bgp_distance_source_access_list,
15296 no_bgp_distance_source_access_list_cmd,
15297 "no distance (1-255) A.B.C.D/M WORD",
15298 NO_STR
15299 "Define an administrative distance\n"
15300 "Administrative distance\n"
15301 "IP source prefix\n"
15302 "Access list name\n")
15303 {
15304 int idx_number = 2;
15305 int idx_ipv4_prefixlen = 3;
15306 int idx_word = 4;
15307 bgp_distance_unset(vty, argv[idx_number]->arg,
15308 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15309 return CMD_SUCCESS;
15310 }
15311
15312 DEFUN (ipv6_bgp_distance_source,
15313 ipv6_bgp_distance_source_cmd,
15314 "distance (1-255) X:X::X:X/M",
15315 "Define an administrative distance\n"
15316 "Administrative distance\n"
15317 "IP source prefix\n")
15318 {
15319 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15320 return CMD_SUCCESS;
15321 }
15322
15323 DEFUN (no_ipv6_bgp_distance_source,
15324 no_ipv6_bgp_distance_source_cmd,
15325 "no distance (1-255) X:X::X:X/M",
15326 NO_STR
15327 "Define an administrative distance\n"
15328 "Administrative distance\n"
15329 "IP source prefix\n")
15330 {
15331 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15332 return CMD_SUCCESS;
15333 }
15334
15335 DEFUN (ipv6_bgp_distance_source_access_list,
15336 ipv6_bgp_distance_source_access_list_cmd,
15337 "distance (1-255) X:X::X:X/M WORD",
15338 "Define an administrative distance\n"
15339 "Administrative distance\n"
15340 "IP source prefix\n"
15341 "Access list name\n")
15342 {
15343 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15344 return CMD_SUCCESS;
15345 }
15346
15347 DEFUN (no_ipv6_bgp_distance_source_access_list,
15348 no_ipv6_bgp_distance_source_access_list_cmd,
15349 "no distance (1-255) X:X::X:X/M WORD",
15350 NO_STR
15351 "Define an administrative distance\n"
15352 "Administrative distance\n"
15353 "IP source prefix\n"
15354 "Access list name\n")
15355 {
15356 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15357 return CMD_SUCCESS;
15358 }
15359
15360 DEFUN (bgp_damp_set,
15361 bgp_damp_set_cmd,
15362 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15363 "BGP Specific commands\n"
15364 "Enable route-flap dampening\n"
15365 "Half-life time for the penalty\n"
15366 "Value to start reusing a route\n"
15367 "Value to start suppressing a route\n"
15368 "Maximum duration to suppress a stable route\n")
15369 {
15370 VTY_DECLVAR_CONTEXT(bgp, bgp);
15371 int idx_half_life = 2;
15372 int idx_reuse = 3;
15373 int idx_suppress = 4;
15374 int idx_max_suppress = 5;
15375 int half = DEFAULT_HALF_LIFE * 60;
15376 int reuse = DEFAULT_REUSE;
15377 int suppress = DEFAULT_SUPPRESS;
15378 int max = 4 * half;
15379
15380 if (argc == 6) {
15381 half = atoi(argv[idx_half_life]->arg) * 60;
15382 reuse = atoi(argv[idx_reuse]->arg);
15383 suppress = atoi(argv[idx_suppress]->arg);
15384 max = atoi(argv[idx_max_suppress]->arg) * 60;
15385 } else if (argc == 3) {
15386 half = atoi(argv[idx_half_life]->arg) * 60;
15387 max = 4 * half;
15388 }
15389
15390 /*
15391 * These can't be 0 but our SA doesn't understand the
15392 * way our cli is constructed
15393 */
15394 assert(reuse);
15395 assert(half);
15396 if (suppress < reuse) {
15397 vty_out(vty,
15398 "Suppress value cannot be less than reuse value \n");
15399 return 0;
15400 }
15401
15402 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15403 reuse, suppress, max);
15404 }
15405
15406 DEFUN (bgp_damp_unset,
15407 bgp_damp_unset_cmd,
15408 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15409 NO_STR
15410 "BGP Specific commands\n"
15411 "Enable route-flap dampening\n"
15412 "Half-life time for the penalty\n"
15413 "Value to start reusing a route\n"
15414 "Value to start suppressing a route\n"
15415 "Maximum duration to suppress a stable route\n")
15416 {
15417 VTY_DECLVAR_CONTEXT(bgp, bgp);
15418 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15419 }
15420
15421 /* Display specified route of BGP table. */
15422 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15423 const char *ip_str, afi_t afi, safi_t safi,
15424 struct prefix_rd *prd, int prefix_check)
15425 {
15426 int ret;
15427 struct prefix match;
15428 struct bgp_dest *dest;
15429 struct bgp_dest *rm;
15430 struct bgp_path_info *pi;
15431 struct bgp_path_info *pi_temp;
15432 struct bgp *bgp;
15433 struct bgp_table *table;
15434
15435 /* BGP structure lookup. */
15436 if (view_name) {
15437 bgp = bgp_lookup_by_name(view_name);
15438 if (bgp == NULL) {
15439 vty_out(vty, "%% Can't find BGP instance %s\n",
15440 view_name);
15441 return CMD_WARNING;
15442 }
15443 } else {
15444 bgp = bgp_get_default();
15445 if (bgp == NULL) {
15446 vty_out(vty, "%% No BGP process is configured\n");
15447 return CMD_WARNING;
15448 }
15449 }
15450
15451 /* Check IP address argument. */
15452 ret = str2prefix(ip_str, &match);
15453 if (!ret) {
15454 vty_out(vty, "%% address is malformed\n");
15455 return CMD_WARNING;
15456 }
15457
15458 match.family = afi2family(afi);
15459
15460 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15461 || (safi == SAFI_EVPN)) {
15462 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15463 dest = bgp_route_next(dest)) {
15464 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15465
15466 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15467 continue;
15468 table = bgp_dest_get_bgp_table_info(dest);
15469 if (!table)
15470 continue;
15471 rm = bgp_node_match(table, &match);
15472 if (rm == NULL)
15473 continue;
15474
15475 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15476
15477 if (!prefix_check
15478 || rm_p->prefixlen == match.prefixlen) {
15479 pi = bgp_dest_get_bgp_path_info(rm);
15480 while (pi) {
15481 if (pi->extra && pi->extra->damp_info) {
15482 pi_temp = pi->next;
15483 bgp_damp_info_free(
15484 pi->extra->damp_info,
15485 1, afi, safi);
15486 pi = pi_temp;
15487 } else
15488 pi = pi->next;
15489 }
15490 }
15491
15492 bgp_dest_unlock_node(rm);
15493 }
15494 } else {
15495 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15496 if (dest != NULL) {
15497 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15498
15499 if (!prefix_check
15500 || dest_p->prefixlen == match.prefixlen) {
15501 pi = bgp_dest_get_bgp_path_info(dest);
15502 while (pi) {
15503 if (pi->extra && pi->extra->damp_info) {
15504 pi_temp = pi->next;
15505 bgp_damp_info_free(
15506 pi->extra->damp_info,
15507 1, afi, safi);
15508 pi = pi_temp;
15509 } else
15510 pi = pi->next;
15511 }
15512 }
15513
15514 bgp_dest_unlock_node(dest);
15515 }
15516 }
15517
15518 return CMD_SUCCESS;
15519 }
15520
15521 DEFUN (clear_ip_bgp_dampening,
15522 clear_ip_bgp_dampening_cmd,
15523 "clear ip bgp dampening",
15524 CLEAR_STR
15525 IP_STR
15526 BGP_STR
15527 "Clear route flap dampening information\n")
15528 {
15529 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15530 return CMD_SUCCESS;
15531 }
15532
15533 DEFUN (clear_ip_bgp_dampening_prefix,
15534 clear_ip_bgp_dampening_prefix_cmd,
15535 "clear ip bgp dampening A.B.C.D/M",
15536 CLEAR_STR
15537 IP_STR
15538 BGP_STR
15539 "Clear route flap dampening information\n"
15540 "IPv4 prefix\n")
15541 {
15542 int idx_ipv4_prefixlen = 4;
15543 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15544 AFI_IP, SAFI_UNICAST, NULL, 1);
15545 }
15546
15547 DEFUN (clear_ip_bgp_dampening_address,
15548 clear_ip_bgp_dampening_address_cmd,
15549 "clear ip bgp dampening A.B.C.D",
15550 CLEAR_STR
15551 IP_STR
15552 BGP_STR
15553 "Clear route flap dampening information\n"
15554 "Network to clear damping information\n")
15555 {
15556 int idx_ipv4 = 4;
15557 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15558 SAFI_UNICAST, NULL, 0);
15559 }
15560
15561 DEFUN (clear_ip_bgp_dampening_address_mask,
15562 clear_ip_bgp_dampening_address_mask_cmd,
15563 "clear ip bgp dampening A.B.C.D A.B.C.D",
15564 CLEAR_STR
15565 IP_STR
15566 BGP_STR
15567 "Clear route flap dampening information\n"
15568 "Network to clear damping information\n"
15569 "Network mask\n")
15570 {
15571 int idx_ipv4 = 4;
15572 int idx_ipv4_2 = 5;
15573 int ret;
15574 char prefix_str[BUFSIZ];
15575
15576 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15577 prefix_str, sizeof(prefix_str));
15578 if (!ret) {
15579 vty_out(vty, "%% Inconsistent address and mask\n");
15580 return CMD_WARNING;
15581 }
15582
15583 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15584 NULL, 0);
15585 }
15586
15587 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15588 {
15589 struct vty *vty = arg;
15590 struct peer *peer = bucket->data;
15591
15592 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15593 }
15594
15595 DEFUN (show_bgp_listeners,
15596 show_bgp_listeners_cmd,
15597 "show bgp listeners",
15598 SHOW_STR
15599 BGP_STR
15600 "Display Listen Sockets and who created them\n")
15601 {
15602 bgp_dump_listener_info(vty);
15603
15604 return CMD_SUCCESS;
15605 }
15606
15607 DEFUN (show_bgp_peerhash,
15608 show_bgp_peerhash_cmd,
15609 "show bgp peerhash",
15610 SHOW_STR
15611 BGP_STR
15612 "Display information about the BGP peerhash\n")
15613 {
15614 struct list *instances = bm->bgp;
15615 struct listnode *node;
15616 struct bgp *bgp;
15617
15618 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15619 vty_out(vty, "BGP: %s\n", bgp->name);
15620 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15621 vty);
15622 }
15623
15624 return CMD_SUCCESS;
15625 }
15626
15627 /* also used for encap safi */
15628 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15629 afi_t afi, safi_t safi)
15630 {
15631 struct bgp_dest *pdest;
15632 struct bgp_dest *dest;
15633 struct bgp_table *table;
15634 const struct prefix *p;
15635 struct bgp_static *bgp_static;
15636 mpls_label_t label;
15637
15638 /* Network configuration. */
15639 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15640 pdest = bgp_route_next(pdest)) {
15641 table = bgp_dest_get_bgp_table_info(pdest);
15642 if (!table)
15643 continue;
15644
15645 for (dest = bgp_table_top(table); dest;
15646 dest = bgp_route_next(dest)) {
15647 bgp_static = bgp_dest_get_bgp_static_info(dest);
15648 if (bgp_static == NULL)
15649 continue;
15650
15651 p = bgp_dest_get_prefix(dest);
15652
15653 /* "network" configuration display. */
15654 label = decode_label(&bgp_static->label);
15655
15656 vty_out(vty, " network %pFX rd %s", p,
15657 bgp_static->prd_pretty);
15658 if (safi == SAFI_MPLS_VPN)
15659 vty_out(vty, " label %u", label);
15660
15661 if (bgp_static->rmap.name)
15662 vty_out(vty, " route-map %s",
15663 bgp_static->rmap.name);
15664
15665 if (bgp_static->backdoor)
15666 vty_out(vty, " backdoor");
15667
15668 vty_out(vty, "\n");
15669 }
15670 }
15671 }
15672
15673 static void bgp_config_write_network_evpn(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 char buf[PREFIX_STRLEN * 2];
15682 char buf2[SU_ADDRSTRLEN];
15683 char esi_buf[ESI_STR_LEN];
15684
15685 /* Network configuration. */
15686 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15687 pdest = bgp_route_next(pdest)) {
15688 table = bgp_dest_get_bgp_table_info(pdest);
15689 if (!table)
15690 continue;
15691
15692 for (dest = bgp_table_top(table); dest;
15693 dest = bgp_route_next(dest)) {
15694 bgp_static = bgp_dest_get_bgp_static_info(dest);
15695 if (bgp_static == NULL)
15696 continue;
15697
15698 char *macrouter = NULL;
15699
15700 if (bgp_static->router_mac)
15701 macrouter = prefix_mac2str(
15702 bgp_static->router_mac, NULL, 0);
15703 if (bgp_static->eth_s_id)
15704 esi_to_str(bgp_static->eth_s_id,
15705 esi_buf, sizeof(esi_buf));
15706 p = bgp_dest_get_prefix(dest);
15707
15708 /* "network" configuration display. */
15709 if (p->u.prefix_evpn.route_type == 5) {
15710 char local_buf[PREFIX_STRLEN];
15711
15712 uint8_t family = is_evpn_prefix_ipaddr_v4((
15713 struct prefix_evpn *)p)
15714 ? AF_INET
15715 : AF_INET6;
15716 inet_ntop(family,
15717 &p->u.prefix_evpn.prefix_addr.ip.ip
15718 .addr,
15719 local_buf, sizeof(local_buf));
15720 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15721 p->u.prefix_evpn.prefix_addr
15722 .ip_prefix_length);
15723 } else {
15724 prefix2str(p, buf, sizeof(buf));
15725 }
15726
15727 if (bgp_static->gatewayIp.family == AF_INET
15728 || bgp_static->gatewayIp.family == AF_INET6)
15729 inet_ntop(bgp_static->gatewayIp.family,
15730 &bgp_static->gatewayIp.u.prefix, buf2,
15731 sizeof(buf2));
15732 vty_out(vty,
15733 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15734 buf, bgp_static->prd_pretty,
15735 p->u.prefix_evpn.prefix_addr.eth_tag,
15736 decode_label(&bgp_static->label), esi_buf, buf2,
15737 macrouter);
15738
15739 XFREE(MTYPE_TMP, macrouter);
15740 }
15741 }
15742 }
15743
15744 /* Configuration of static route announcement and aggregate
15745 information. */
15746 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15747 safi_t safi)
15748 {
15749 struct bgp_dest *dest;
15750 const struct prefix *p;
15751 struct bgp_static *bgp_static;
15752 struct bgp_aggregate *bgp_aggregate;
15753
15754 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15755 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15756 return;
15757 }
15758
15759 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15760 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15761 return;
15762 }
15763
15764 /* Network configuration. */
15765 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15766 dest = bgp_route_next(dest)) {
15767 bgp_static = bgp_dest_get_bgp_static_info(dest);
15768 if (bgp_static == NULL)
15769 continue;
15770
15771 p = bgp_dest_get_prefix(dest);
15772
15773 vty_out(vty, " network %pFX", p);
15774
15775 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15776 vty_out(vty, " label-index %u",
15777 bgp_static->label_index);
15778
15779 if (bgp_static->rmap.name)
15780 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15781
15782 if (bgp_static->backdoor)
15783 vty_out(vty, " backdoor");
15784
15785 vty_out(vty, "\n");
15786 }
15787
15788 /* Aggregate-address configuration. */
15789 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15790 dest = bgp_route_next(dest)) {
15791 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15792 if (bgp_aggregate == NULL)
15793 continue;
15794
15795 p = bgp_dest_get_prefix(dest);
15796
15797 vty_out(vty, " aggregate-address %pFX", p);
15798
15799 if (bgp_aggregate->as_set)
15800 vty_out(vty, " as-set");
15801
15802 if (bgp_aggregate->summary_only)
15803 vty_out(vty, " summary-only");
15804
15805 if (bgp_aggregate->rmap.name)
15806 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15807
15808 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15809 vty_out(vty, " origin %s",
15810 bgp_origin2str(bgp_aggregate->origin));
15811
15812 if (bgp_aggregate->match_med)
15813 vty_out(vty, " matching-MED-only");
15814
15815 if (bgp_aggregate->suppress_map_name)
15816 vty_out(vty, " suppress-map %s",
15817 bgp_aggregate->suppress_map_name);
15818
15819 vty_out(vty, "\n");
15820 }
15821 }
15822
15823 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15824 safi_t safi)
15825 {
15826 struct bgp_dest *dest;
15827 struct bgp_distance *bdistance;
15828
15829 /* Distance configuration. */
15830 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15831 && bgp->distance_local[afi][safi]
15832 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15833 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15834 || bgp->distance_local[afi][safi]
15835 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15836 vty_out(vty, " distance bgp %d %d %d\n",
15837 bgp->distance_ebgp[afi][safi],
15838 bgp->distance_ibgp[afi][safi],
15839 bgp->distance_local[afi][safi]);
15840 }
15841
15842 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15843 dest = bgp_route_next(dest)) {
15844 bdistance = bgp_dest_get_bgp_distance_info(dest);
15845 if (bdistance != NULL)
15846 vty_out(vty, " distance %d %pBD %s\n",
15847 bdistance->distance, dest,
15848 bdistance->access_list ? bdistance->access_list
15849 : "");
15850 }
15851 }
15852
15853 /* Allocate routing table structure and install commands. */
15854 void bgp_route_init(void)
15855 {
15856 afi_t afi;
15857 safi_t safi;
15858
15859 /* Init BGP distance table. */
15860 FOREACH_AFI_SAFI (afi, safi)
15861 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15862
15863 /* IPv4 BGP commands. */
15864 install_element(BGP_NODE, &bgp_table_map_cmd);
15865 install_element(BGP_NODE, &bgp_network_cmd);
15866 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15867
15868 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15869
15870 /* IPv4 unicast configuration. */
15871 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15872 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15873 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15874
15875 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15876
15877 /* IPv4 multicast configuration. */
15878 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15879 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15880 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15881 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15882
15883 /* IPv4 labeled-unicast configuration. */
15884 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15885 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15886
15887 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15888 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15889 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15890 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15891 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15892 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15893 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15894 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15895
15896 install_element(VIEW_NODE,
15897 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15898 install_element(VIEW_NODE,
15899 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15900 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15901 install_element(VIEW_NODE,
15902 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15903 #ifdef KEEP_OLD_VPN_COMMANDS
15904 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15905 #endif /* KEEP_OLD_VPN_COMMANDS */
15906 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15907 install_element(VIEW_NODE,
15908 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15909
15910 /* BGP dampening clear commands */
15911 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15912 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15913
15914 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15915 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15916
15917 /* prefix count */
15918 install_element(ENABLE_NODE,
15919 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15920 #ifdef KEEP_OLD_VPN_COMMANDS
15921 install_element(ENABLE_NODE,
15922 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15923 #endif /* KEEP_OLD_VPN_COMMANDS */
15924
15925 /* New config IPv6 BGP commands. */
15926 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15927 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15928 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15929
15930 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15931
15932 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15933
15934 /* IPv6 labeled unicast address family. */
15935 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15936 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15937
15938 install_element(BGP_NODE, &bgp_distance_cmd);
15939 install_element(BGP_NODE, &no_bgp_distance_cmd);
15940 install_element(BGP_NODE, &bgp_distance_source_cmd);
15941 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15942 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15943 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15944 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15945 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15946 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15947 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15948 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15949 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15950 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15951 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15952 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15953 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15954 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15955 install_element(BGP_IPV4M_NODE,
15956 &no_bgp_distance_source_access_list_cmd);
15957 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15958 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15959 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15960 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15961 install_element(BGP_IPV6_NODE,
15962 &ipv6_bgp_distance_source_access_list_cmd);
15963 install_element(BGP_IPV6_NODE,
15964 &no_ipv6_bgp_distance_source_access_list_cmd);
15965 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15966 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15967 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15968 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15969 install_element(BGP_IPV6M_NODE,
15970 &ipv6_bgp_distance_source_access_list_cmd);
15971 install_element(BGP_IPV6M_NODE,
15972 &no_ipv6_bgp_distance_source_access_list_cmd);
15973
15974 /* BGP dampening */
15975 install_element(BGP_NODE, &bgp_damp_set_cmd);
15976 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15977 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15978 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15979 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15980 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15981 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15982 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15983 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15984 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15985 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15986 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15987 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15988 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15989
15990 /* Large Communities */
15991 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15992 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15993
15994 /* show bgp ipv4 flowspec detailed */
15995 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15996
15997 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15998 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15999 }
16000
16001 void bgp_route_finish(void)
16002 {
16003 afi_t afi;
16004 safi_t safi;
16005
16006 FOREACH_AFI_SAFI (afi, safi) {
16007 bgp_table_unlock(bgp_distance_table[afi][safi]);
16008 bgp_distance_table[afi][safi] = NULL;
16009 }
16010 }