]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #12837 from donaldsharp/unlikely_routemap
[mirror_frr.git] / bgpd / bgp_route.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP routing information
3 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
4 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 */
6
7 #include <zebra.h>
8 #include <math.h>
9
10 #include "printfrr.h"
11 #include "frrstr.h"
12 #include "prefix.h"
13 #include "linklist.h"
14 #include "memory.h"
15 #include "command.h"
16 #include "stream.h"
17 #include "filter.h"
18 #include "log.h"
19 #include "routemap.h"
20 #include "buffer.h"
21 #include "sockunion.h"
22 #include "plist.h"
23 #include "frrevent.h"
24 #include "workqueue.h"
25 #include "queue.h"
26 #include "memory.h"
27 #include "srv6.h"
28 #include "lib/json.h"
29 #include "lib_errors.h"
30 #include "zclient.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_regex.h"
39 #include "bgpd/bgp_community.h"
40 #include "bgpd/bgp_community_alias.h"
41 #include "bgpd/bgp_ecommunity.h"
42 #include "bgpd/bgp_lcommunity.h"
43 #include "bgpd/bgp_clist.h"
44 #include "bgpd/bgp_packet.h"
45 #include "bgpd/bgp_filter.h"
46 #include "bgpd/bgp_fsm.h"
47 #include "bgpd/bgp_mplsvpn.h"
48 #include "bgpd/bgp_nexthop.h"
49 #include "bgpd/bgp_damp.h"
50 #include "bgpd/bgp_advertise.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_vty.h"
53 #include "bgpd/bgp_mpath.h"
54 #include "bgpd/bgp_nht.h"
55 #include "bgpd/bgp_updgrp.h"
56 #include "bgpd/bgp_label.h"
57 #include "bgpd/bgp_addpath.h"
58 #include "bgpd/bgp_mac.h"
59 #include "bgpd/bgp_network.h"
60 #include "bgpd/bgp_trace.h"
61 #include "bgpd/bgp_rpki.h"
62
63 #ifdef ENABLE_BGP_VNC
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #include "bgpd/rfapi/vnc_import_bgp.h"
66 #include "bgpd/rfapi/vnc_export_bgp.h"
67 #endif
68 #include "bgpd/bgp_encap_types.h"
69 #include "bgpd/bgp_encap_tlv.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_evpn_mh.h"
72 #include "bgpd/bgp_evpn_vty.h"
73 #include "bgpd/bgp_flowspec.h"
74 #include "bgpd/bgp_flowspec_util.h"
75 #include "bgpd/bgp_pbr.h"
76
77 #include "bgpd/bgp_route_clippy.c"
78
79 DEFINE_HOOK(bgp_snmp_update_stats,
80 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
81 (rn, pi, added));
82
83 DEFINE_HOOK(bgp_rpki_prefix_status,
84 (struct peer *peer, struct attr *attr,
85 const struct prefix *prefix),
86 (peer, attr, prefix));
87
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str[];
90 extern const char *bgp_origin_long_str[];
91
92 /* PMSI strings. */
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str[] = {
96 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
104 {0}
105 };
106
107 #define VRFID_NONE_STR "-"
108 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
109
110 DEFINE_HOOK(bgp_process,
111 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
112 struct peer *peer, bool withdraw),
113 (bgp, afi, safi, bn, peer, withdraw));
114
115 /** Test if path is suppressed. */
116 static bool bgp_path_suppressed(struct bgp_path_info *pi)
117 {
118 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
119 return false;
120
121 return listcount(pi->extra->aggr_suppressors) > 0;
122 }
123
124 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
125 safi_t safi, const struct prefix *p,
126 struct prefix_rd *prd)
127 {
128 struct bgp_dest *dest;
129 struct bgp_dest *pdest = NULL;
130
131 assert(table);
132
133 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
134 || (safi == SAFI_EVPN)) {
135 pdest = bgp_node_get(table, (struct prefix *)prd);
136
137 if (!bgp_dest_has_bgp_path_info_data(pdest))
138 bgp_dest_set_bgp_table_info(
139 pdest, bgp_table_init(table->bgp, afi, safi));
140 else
141 bgp_dest_unlock_node(pdest);
142 table = bgp_dest_get_bgp_table_info(pdest);
143 }
144
145 dest = bgp_node_get(table, p);
146
147 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
148 || (safi == SAFI_EVPN))
149 dest->pdest = pdest;
150
151 return dest;
152 }
153
154 struct bgp_dest *bgp_safi_node_lookup(struct bgp_table *table, safi_t safi,
155 const struct prefix *p,
156 struct prefix_rd *prd)
157 {
158 struct bgp_dest *dest;
159 struct bgp_dest *pdest = NULL;
160
161 if (!table)
162 return NULL;
163
164 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
165 || (safi == SAFI_EVPN)) {
166 pdest = bgp_node_lookup(table, (struct prefix *)prd);
167 if (!pdest)
168 return NULL;
169
170 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
171 bgp_dest_unlock_node(pdest);
172 return NULL;
173 }
174
175 table = bgp_dest_get_bgp_table_info(pdest);
176 }
177
178 dest = bgp_node_lookup(table, p);
179
180 return dest;
181 }
182
183 /* Allocate bgp_path_info_extra */
184 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
185 {
186 struct bgp_path_info_extra *new;
187 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
188 sizeof(struct bgp_path_info_extra));
189 new->label[0] = MPLS_INVALID_LABEL;
190 new->num_labels = 0;
191 new->bgp_fs_pbr = NULL;
192 new->bgp_fs_iprule = NULL;
193 return new;
194 }
195
196 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
197 {
198 struct bgp_path_info_extra *e;
199
200 if (!extra || !*extra)
201 return;
202
203 e = *extra;
204 if (e->damp_info)
205 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
206 e->damp_info->safi);
207
208 e->damp_info = NULL;
209 if (e->parent) {
210 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
211
212 if (bpi->net) {
213 /* FIXME: since multiple e may have the same e->parent
214 * and e->parent->net is holding a refcount for each
215 * of them, we need to do some fudging here.
216 *
217 * WARNING: if bpi->net->lock drops to 0, bpi may be
218 * freed as well (because bpi->net was holding the
219 * last reference to bpi) => write after free!
220 */
221 unsigned refcount;
222
223 bpi = bgp_path_info_lock(bpi);
224 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
225 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
226 if (!refcount)
227 bpi->net = NULL;
228 bgp_path_info_unlock(bpi);
229 }
230 bgp_path_info_unlock(e->parent);
231 e->parent = NULL;
232 }
233
234 if (e->bgp_orig)
235 bgp_unlock(e->bgp_orig);
236
237 if (e->peer_orig)
238 peer_unlock(e->peer_orig);
239
240 if (e->aggr_suppressors)
241 list_delete(&e->aggr_suppressors);
242
243 if (e->mh_info)
244 bgp_evpn_path_mh_info_free(e->mh_info);
245
246 if ((*extra)->bgp_fs_iprule)
247 list_delete(&((*extra)->bgp_fs_iprule));
248 if ((*extra)->bgp_fs_pbr)
249 list_delete(&((*extra)->bgp_fs_pbr));
250 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
251 }
252
253 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
254 * allocated if required.
255 */
256 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
257 {
258 if (!pi->extra)
259 pi->extra = bgp_path_info_extra_new();
260 return pi->extra;
261 }
262
263 /* Free bgp route information. */
264 void bgp_path_info_free_with_caller(const char *name,
265 struct bgp_path_info *path)
266 {
267 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
268 bgp_attr_unintern(&path->attr);
269
270 bgp_unlink_nexthop(path);
271 bgp_path_info_extra_free(&path->extra);
272 bgp_path_info_mpath_free(&path->mpath);
273 if (path->net)
274 bgp_addpath_free_info_data(&path->tx_addpath,
275 &path->net->tx_addpath);
276
277 peer_unlock(path->peer); /* bgp_path_info peer reference */
278
279 XFREE(MTYPE_BGP_ROUTE, path);
280 }
281
282 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
283 {
284 path->lock++;
285 return path;
286 }
287
288 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
289 {
290 assert(path && path->lock > 0);
291 path->lock--;
292
293 if (path->lock == 0) {
294 bgp_path_info_free(path);
295 return NULL;
296 }
297
298 return path;
299 }
300
301 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
302 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
303 {
304 struct peer *peer;
305 struct bgp_path_info *old_pi, *nextpi;
306 bool set_flag = false;
307 struct bgp *bgp = NULL;
308 struct bgp_table *table = NULL;
309 afi_t afi = 0;
310 safi_t safi = 0;
311
312 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
313 * then the route selection is deferred
314 */
315 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
316 return 0;
317
318 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
319 if (BGP_DEBUG(update, UPDATE_OUT)) {
320 table = bgp_dest_table(dest);
321 if (table)
322 bgp = table->bgp;
323
324 zlog_debug(
325 "Route %pBD(%s) is in workqueue and being processed, not deferred.",
326 dest, bgp ? bgp->name_pretty : "(Unknown)");
327 }
328
329 return 0;
330 }
331
332 table = bgp_dest_table(dest);
333 if (table) {
334 bgp = table->bgp;
335 afi = table->afi;
336 safi = table->safi;
337 }
338
339 for (old_pi = bgp_dest_get_bgp_path_info(dest);
340 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
341 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
342 continue;
343
344 /* Route selection is deferred if there is a stale path which
345 * which indicates peer is in restart mode
346 */
347 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
348 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
349 set_flag = true;
350 } else {
351 /* If the peer is graceful restart capable and peer is
352 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
353 */
354 peer = old_pi->peer;
355 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
356 && BGP_PEER_RESTARTING_MODE(peer)
357 && (old_pi
358 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
359 set_flag = true;
360 }
361 }
362 if (set_flag)
363 break;
364 }
365
366 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
367 * is active
368 */
369 if (set_flag && table) {
370 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
371 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
372 bgp->gr_info[afi][safi].gr_deferred++;
373 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
374 if (BGP_DEBUG(update, UPDATE_OUT))
375 zlog_debug("DEFER route %pBD(%s), dest %p",
376 dest, bgp->name_pretty, dest);
377 return 0;
378 }
379 }
380 return -1;
381 }
382
383 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
384 struct bgp_path_info *pi)
385 {
386 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
387 struct bgp_path_info *top;
388
389 top = bgp_dest_get_bgp_path_info(dest);
390
391 pi->next = top;
392 pi->prev = NULL;
393 if (top)
394 top->prev = pi;
395 bgp_dest_set_bgp_path_info(dest, pi);
396
397 bgp_path_info_lock(pi);
398 bgp_dest_lock_node(dest);
399 peer_lock(pi->peer); /* bgp_path_info peer reference */
400 bgp_dest_set_defer_flag(dest, false);
401 hook_call(bgp_snmp_update_stats, dest, pi, true);
402 }
403
404 /* Do the actual removal of info from RIB, for use by bgp_process
405 completion callback *only* */
406 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
407 {
408 if (pi->next)
409 pi->next->prev = pi->prev;
410 if (pi->prev)
411 pi->prev->next = pi->next;
412 else
413 bgp_dest_set_bgp_path_info(dest, pi->next);
414
415 bgp_path_info_mpath_dequeue(pi);
416 bgp_path_info_unlock(pi);
417 hook_call(bgp_snmp_update_stats, dest, pi, false);
418 bgp_dest_unlock_node(dest);
419 }
420
421 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
422 {
423 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
424 /* set of previous already took care of pcount */
425 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
426 }
427
428 /* undo the effects of a previous call to bgp_path_info_delete; typically
429 called when a route is deleted and then quickly re-added before the
430 deletion has been processed */
431 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
432 {
433 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
434 /* unset of previous already took care of pcount */
435 SET_FLAG(pi->flags, BGP_PATH_VALID);
436 }
437
438 /* Adjust pcount as required */
439 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
440 {
441 struct bgp_table *table;
442
443 assert(dest && bgp_dest_table(dest));
444 assert(pi && pi->peer && pi->peer->bgp);
445
446 table = bgp_dest_table(dest);
447
448 if (pi->peer == pi->peer->bgp->peer_self)
449 return;
450
451 if (!BGP_PATH_COUNTABLE(pi)
452 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
453
454 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
455
456 /* slight hack, but more robust against errors. */
457 if (pi->peer->pcount[table->afi][table->safi])
458 pi->peer->pcount[table->afi][table->safi]--;
459 else
460 flog_err(EC_LIB_DEVELOPMENT,
461 "Asked to decrement 0 prefix count for peer");
462 } else if (BGP_PATH_COUNTABLE(pi)
463 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
464 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
465 pi->peer->pcount[table->afi][table->safi]++;
466 }
467 }
468
469 static int bgp_label_index_differs(struct bgp_path_info *pi1,
470 struct bgp_path_info *pi2)
471 {
472 return (!(pi1->attr->label_index == pi2->attr->label_index));
473 }
474
475 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
476 * This is here primarily to keep prefix-count in check.
477 */
478 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
479 uint32_t flag)
480 {
481 SET_FLAG(pi->flags, flag);
482
483 /* early bath if we know it's not a flag that changes countability state
484 */
485 if (!CHECK_FLAG(flag,
486 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
487 return;
488
489 bgp_pcount_adjust(dest, pi);
490 }
491
492 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
493 uint32_t flag)
494 {
495 UNSET_FLAG(pi->flags, flag);
496
497 /* early bath if we know it's not a flag that changes countability state
498 */
499 if (!CHECK_FLAG(flag,
500 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
501 return;
502
503 bgp_pcount_adjust(dest, pi);
504 }
505
506 /* Get MED value. If MED value is missing and "bgp bestpath
507 missing-as-worst" is specified, treat it as the worst value. */
508 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
509 {
510 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
511 return attr->med;
512 else {
513 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
514 return BGP_MED_MAX;
515 else
516 return 0;
517 }
518 }
519
520 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
521 size_t buf_len)
522 {
523 struct peer *peer;
524
525 if (pi->sub_type == BGP_ROUTE_IMPORTED &&
526 bgp_get_imported_bpi_ultimate(pi))
527 peer = bgp_get_imported_bpi_ultimate(pi)->peer;
528 else
529 peer = pi->peer;
530
531 if (pi->addpath_rx_id)
532 snprintf(buf, buf_len, "path %s (addpath rxid %d)", peer->host,
533 pi->addpath_rx_id);
534 else
535 snprintf(buf, buf_len, "path %s", peer->host);
536 }
537
538
539 /*
540 * Get the ultimate path info.
541 */
542 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
543 {
544 struct bgp_path_info *bpi_ultimate;
545
546 if (info->sub_type != BGP_ROUTE_IMPORTED)
547 return info;
548
549 for (bpi_ultimate = info;
550 bpi_ultimate->extra && bpi_ultimate->extra->parent;
551 bpi_ultimate = bpi_ultimate->extra->parent)
552 ;
553
554 return bpi_ultimate;
555 }
556
557 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
558 */
559 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
560 struct bgp_path_info *exist, int *paths_eq,
561 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
562 char *pfx_buf, afi_t afi, safi_t safi,
563 enum bgp_path_selection_reason *reason)
564 {
565 const struct prefix *new_p;
566 struct attr *newattr, *existattr;
567 enum bgp_peer_sort new_sort;
568 enum bgp_peer_sort exist_sort;
569 uint32_t new_pref;
570 uint32_t exist_pref;
571 uint32_t new_med;
572 uint32_t exist_med;
573 uint32_t new_weight;
574 uint32_t exist_weight;
575 uint32_t newm, existm;
576 struct in_addr new_id;
577 struct in_addr exist_id;
578 int new_cluster;
579 int exist_cluster;
580 int internal_as_route;
581 int confed_as_route;
582 int ret = 0;
583 int igp_metric_ret = 0;
584 int peer_sort_ret = -1;
585 char new_buf[PATH_ADDPATH_STR_BUFFER];
586 char exist_buf[PATH_ADDPATH_STR_BUFFER];
587 uint32_t new_mm_seq;
588 uint32_t exist_mm_seq;
589 int nh_cmp;
590 esi_t *exist_esi;
591 esi_t *new_esi;
592 bool same_esi;
593 bool old_proxy;
594 bool new_proxy;
595 bool new_origin, exist_origin;
596 struct bgp_path_info *bpi_ultimate;
597 struct peer *peer_new, *peer_exist;
598
599 *paths_eq = 0;
600
601 /* 0. Null check. */
602 if (new == NULL) {
603 *reason = bgp_path_selection_none;
604 if (debug)
605 zlog_debug("%s: new is NULL", pfx_buf);
606 return 0;
607 }
608
609 if (debug) {
610 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
611 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
612 sizeof(new_buf));
613 }
614
615 if (exist == NULL) {
616 *reason = bgp_path_selection_first;
617 if (debug)
618 zlog_debug("%s(%s): %s is the initial bestpath",
619 pfx_buf, bgp->name_pretty, new_buf);
620 return 1;
621 }
622
623 if (debug) {
624 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
625 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
626 sizeof(exist_buf));
627 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
628 pfx_buf, bgp->name_pretty, new_buf, new->flags,
629 exist_buf, exist->flags);
630 }
631
632 newattr = new->attr;
633 existattr = exist->attr;
634
635 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
636 * Capability" to a neighbor MUST perform the following upon receiving
637 * a route from that neighbor with the "LLGR_STALE" community, or upon
638 * attaching the "LLGR_STALE" community itself per Section 4.2:
639 *
640 * Treat the route as the least-preferred in route selection (see
641 * below). See the Risks of Depreferencing Routes section (Section 5.2)
642 * for a discussion of potential risks inherent in doing this.
643 */
644 if (bgp_attr_get_community(newattr) &&
645 community_include(bgp_attr_get_community(newattr),
646 COMMUNITY_LLGR_STALE)) {
647 if (debug)
648 zlog_debug(
649 "%s: %s wins over %s due to LLGR_STALE community",
650 pfx_buf, new_buf, exist_buf);
651 return 0;
652 }
653
654 if (bgp_attr_get_community(existattr) &&
655 community_include(bgp_attr_get_community(existattr),
656 COMMUNITY_LLGR_STALE)) {
657 if (debug)
658 zlog_debug(
659 "%s: %s loses to %s due to LLGR_STALE community",
660 pfx_buf, new_buf, exist_buf);
661 return 1;
662 }
663
664 new_p = bgp_dest_get_prefix(new->net);
665
666 /* For EVPN routes, we cannot just go by local vs remote, we have to
667 * look at the MAC mobility sequence number, if present.
668 */
669 if ((safi == SAFI_EVPN)
670 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
671 /* This is an error condition described in RFC 7432 Section
672 * 15.2. The RFC
673 * states that in this scenario "the PE MUST alert the operator"
674 * but it
675 * does not state what other action to take. In order to provide
676 * some
677 * consistency in this scenario we are going to prefer the path
678 * with the
679 * sticky flag.
680 */
681 if (newattr->sticky != existattr->sticky) {
682 if (!debug) {
683 prefix2str(new_p, pfx_buf,
684 sizeof(*pfx_buf)
685 * PREFIX2STR_BUFFER);
686 bgp_path_info_path_with_addpath_rx_str(
687 new, new_buf, sizeof(new_buf));
688 bgp_path_info_path_with_addpath_rx_str(
689 exist, exist_buf, sizeof(exist_buf));
690 }
691
692 if (newattr->sticky && !existattr->sticky) {
693 *reason = bgp_path_selection_evpn_sticky_mac;
694 if (debug)
695 zlog_debug(
696 "%s: %s wins over %s due to sticky MAC flag",
697 pfx_buf, new_buf, exist_buf);
698 return 1;
699 }
700
701 if (!newattr->sticky && existattr->sticky) {
702 *reason = bgp_path_selection_evpn_sticky_mac;
703 if (debug)
704 zlog_debug(
705 "%s: %s loses to %s due to sticky MAC flag",
706 pfx_buf, new_buf, exist_buf);
707 return 0;
708 }
709 }
710
711 new_esi = bgp_evpn_attr_get_esi(newattr);
712 exist_esi = bgp_evpn_attr_get_esi(existattr);
713 if (bgp_evpn_is_esi_valid(new_esi) &&
714 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
715 same_esi = true;
716 } else {
717 same_esi = false;
718 }
719
720 /* If both paths have the same non-zero ES and
721 * one path is local it wins.
722 * PS: Note the local path wins even if the remote
723 * has the higher MM seq. The local path's
724 * MM seq will be fixed up to match the highest
725 * rem seq, subsequently.
726 */
727 if (same_esi) {
728 char esi_buf[ESI_STR_LEN];
729
730 if (bgp_evpn_is_path_local(bgp, new)) {
731 *reason = bgp_path_selection_evpn_local_path;
732 if (debug)
733 zlog_debug(
734 "%s: %s wins over %s as ES %s is same and local",
735 pfx_buf, new_buf, exist_buf,
736 esi_to_str(new_esi, esi_buf,
737 sizeof(esi_buf)));
738 return 1;
739 }
740 if (bgp_evpn_is_path_local(bgp, exist)) {
741 *reason = bgp_path_selection_evpn_local_path;
742 if (debug)
743 zlog_debug(
744 "%s: %s loses to %s as ES %s is same and local",
745 pfx_buf, new_buf, exist_buf,
746 esi_to_str(new_esi, esi_buf,
747 sizeof(esi_buf)));
748 return 0;
749 }
750 }
751
752 new_mm_seq = mac_mobility_seqnum(newattr);
753 exist_mm_seq = mac_mobility_seqnum(existattr);
754
755 if (new_mm_seq > exist_mm_seq) {
756 *reason = bgp_path_selection_evpn_seq;
757 if (debug)
758 zlog_debug(
759 "%s: %s wins over %s due to MM seq %u > %u",
760 pfx_buf, new_buf, exist_buf, new_mm_seq,
761 exist_mm_seq);
762 return 1;
763 }
764
765 if (new_mm_seq < exist_mm_seq) {
766 *reason = bgp_path_selection_evpn_seq;
767 if (debug)
768 zlog_debug(
769 "%s: %s loses to %s due to MM seq %u < %u",
770 pfx_buf, new_buf, exist_buf, new_mm_seq,
771 exist_mm_seq);
772 return 0;
773 }
774
775 /* if the sequence numbers and ESI are the same and one path
776 * is non-proxy it wins (over proxy)
777 */
778 new_proxy = bgp_evpn_attr_is_proxy(newattr);
779 old_proxy = bgp_evpn_attr_is_proxy(existattr);
780 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
781 old_proxy != new_proxy) {
782 if (!new_proxy) {
783 *reason = bgp_path_selection_evpn_non_proxy;
784 if (debug)
785 zlog_debug(
786 "%s: %s wins over %s, same seq/es and non-proxy",
787 pfx_buf, new_buf, exist_buf);
788 return 1;
789 }
790
791 *reason = bgp_path_selection_evpn_non_proxy;
792 if (debug)
793 zlog_debug(
794 "%s: %s loses to %s, same seq/es and non-proxy",
795 pfx_buf, new_buf, exist_buf);
796 return 0;
797 }
798
799 /*
800 * if sequence numbers are the same path with the lowest IP
801 * wins
802 */
803 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
804 if (nh_cmp < 0) {
805 *reason = bgp_path_selection_evpn_lower_ip;
806 if (debug)
807 zlog_debug(
808 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
809 pfx_buf, new_buf, exist_buf, new_mm_seq,
810 &new->attr->nexthop);
811 return 1;
812 }
813 if (nh_cmp > 0) {
814 *reason = bgp_path_selection_evpn_lower_ip;
815 if (debug)
816 zlog_debug(
817 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
818 pfx_buf, new_buf, exist_buf, new_mm_seq,
819 &new->attr->nexthop);
820 return 0;
821 }
822 }
823
824 /* 1. Weight check. */
825 new_weight = newattr->weight;
826 exist_weight = existattr->weight;
827
828 if (new_weight > exist_weight) {
829 *reason = bgp_path_selection_weight;
830 if (debug)
831 zlog_debug("%s: %s wins over %s due to weight %d > %d",
832 pfx_buf, new_buf, exist_buf, new_weight,
833 exist_weight);
834 return 1;
835 }
836
837 if (new_weight < exist_weight) {
838 *reason = bgp_path_selection_weight;
839 if (debug)
840 zlog_debug("%s: %s loses to %s due to weight %d < %d",
841 pfx_buf, new_buf, exist_buf, new_weight,
842 exist_weight);
843 return 0;
844 }
845
846 /* 2. Local preference check. */
847 new_pref = exist_pref = bgp->default_local_pref;
848
849 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
850 new_pref = newattr->local_pref;
851 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
852 exist_pref = existattr->local_pref;
853
854 if (new_pref > exist_pref) {
855 *reason = bgp_path_selection_local_pref;
856 if (debug)
857 zlog_debug(
858 "%s: %s wins over %s due to localpref %d > %d",
859 pfx_buf, new_buf, exist_buf, new_pref,
860 exist_pref);
861 return 1;
862 }
863
864 if (new_pref < exist_pref) {
865 *reason = bgp_path_selection_local_pref;
866 if (debug)
867 zlog_debug(
868 "%s: %s loses to %s due to localpref %d < %d",
869 pfx_buf, new_buf, exist_buf, new_pref,
870 exist_pref);
871 return 0;
872 }
873
874 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
875 * extensions defined in this document, the following step is inserted
876 * after the LOCAL_PREF comparison step in the BGP decision process:
877 * When comparing a pair of routes for a BGP destination, the
878 * route with the ACCEPT_OWN community attached is preferred over
879 * the route that does not have the community.
880 * This extra step MUST only be invoked during the best path selection
881 * process of VPN-IP routes.
882 */
883 if (safi == SAFI_MPLS_VPN &&
884 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
885 CHECK_FLAG(exist->peer->af_flags[afi][safi],
886 PEER_FLAG_ACCEPT_OWN))) {
887 bool new_accept_own = false;
888 bool exist_accept_own = false;
889 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
890
891 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
892 new_accept_own = community_include(
893 bgp_attr_get_community(newattr), accept_own);
894 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
895 exist_accept_own = community_include(
896 bgp_attr_get_community(existattr), accept_own);
897
898 if (new_accept_own && !exist_accept_own) {
899 *reason = bgp_path_selection_accept_own;
900 if (debug)
901 zlog_debug(
902 "%s: %s wins over %s due to accept-own",
903 pfx_buf, new_buf, exist_buf);
904 return 1;
905 }
906
907 if (!new_accept_own && exist_accept_own) {
908 *reason = bgp_path_selection_accept_own;
909 if (debug)
910 zlog_debug(
911 "%s: %s loses to %s due to accept-own",
912 pfx_buf, new_buf, exist_buf);
913 return 0;
914 }
915 }
916
917 /* Tie-breaker - AIGP (Metric TLV) attribute */
918 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
919 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
920 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
921 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
922 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
923
924 if (new_aigp < exist_aigp) {
925 *reason = bgp_path_selection_aigp;
926 if (debug)
927 zlog_debug(
928 "%s: %s wins over %s due to AIGP %" PRIu64
929 " < %" PRIu64,
930 pfx_buf, new_buf, exist_buf, new_aigp,
931 exist_aigp);
932 return 1;
933 }
934
935 if (new_aigp > exist_aigp) {
936 *reason = bgp_path_selection_aigp;
937 if (debug)
938 zlog_debug(
939 "%s: %s loses to %s due to AIGP %" PRIu64
940 " > %" PRIu64,
941 pfx_buf, new_buf, exist_buf, new_aigp,
942 exist_aigp);
943 return 0;
944 }
945 }
946
947 /* 3. Local route check. We prefer:
948 * - BGP_ROUTE_STATIC
949 * - BGP_ROUTE_AGGREGATE
950 * - BGP_ROUTE_REDISTRIBUTE
951 */
952 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
953 new->sub_type == BGP_ROUTE_IMPORTED);
954 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
955 exist->sub_type == BGP_ROUTE_IMPORTED);
956
957 if (new_origin && !exist_origin) {
958 *reason = bgp_path_selection_local_route;
959 if (debug)
960 zlog_debug(
961 "%s: %s wins over %s due to preferred BGP_ROUTE type",
962 pfx_buf, new_buf, exist_buf);
963 return 1;
964 }
965
966 if (!new_origin && exist_origin) {
967 *reason = bgp_path_selection_local_route;
968 if (debug)
969 zlog_debug(
970 "%s: %s loses to %s due to preferred BGP_ROUTE type",
971 pfx_buf, new_buf, exist_buf);
972 return 0;
973 }
974
975 /* Here if these are imported routes then get ultimate pi for
976 * path compare.
977 */
978 new = bgp_get_imported_bpi_ultimate(new);
979 exist = bgp_get_imported_bpi_ultimate(exist);
980 newattr = new->attr;
981 existattr = exist->attr;
982
983 /* 4. AS path length check. */
984 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
985 int exist_hops = aspath_count_hops(existattr->aspath);
986 int exist_confeds = aspath_count_confeds(existattr->aspath);
987
988 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
989 int aspath_hops;
990
991 aspath_hops = aspath_count_hops(newattr->aspath);
992 aspath_hops += aspath_count_confeds(newattr->aspath);
993
994 if (aspath_hops < (exist_hops + exist_confeds)) {
995 *reason = bgp_path_selection_confed_as_path;
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
999 pfx_buf, new_buf, exist_buf,
1000 aspath_hops,
1001 (exist_hops + exist_confeds));
1002 return 1;
1003 }
1004
1005 if (aspath_hops > (exist_hops + exist_confeds)) {
1006 *reason = bgp_path_selection_confed_as_path;
1007 if (debug)
1008 zlog_debug(
1009 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1010 pfx_buf, new_buf, exist_buf,
1011 aspath_hops,
1012 (exist_hops + exist_confeds));
1013 return 0;
1014 }
1015 } else {
1016 int newhops = aspath_count_hops(newattr->aspath);
1017
1018 if (newhops < exist_hops) {
1019 *reason = bgp_path_selection_as_path;
1020 if (debug)
1021 zlog_debug(
1022 "%s: %s wins over %s due to aspath hopcount %d < %d",
1023 pfx_buf, new_buf, exist_buf,
1024 newhops, exist_hops);
1025 return 1;
1026 }
1027
1028 if (newhops > exist_hops) {
1029 *reason = bgp_path_selection_as_path;
1030 if (debug)
1031 zlog_debug(
1032 "%s: %s loses to %s due to aspath hopcount %d > %d",
1033 pfx_buf, new_buf, exist_buf,
1034 newhops, exist_hops);
1035 return 0;
1036 }
1037 }
1038 }
1039
1040 /* 5. Origin check. */
1041 if (newattr->origin < existattr->origin) {
1042 *reason = bgp_path_selection_origin;
1043 if (debug)
1044 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1045 pfx_buf, new_buf, exist_buf,
1046 bgp_origin_long_str[newattr->origin],
1047 bgp_origin_long_str[existattr->origin]);
1048 return 1;
1049 }
1050
1051 if (newattr->origin > existattr->origin) {
1052 *reason = bgp_path_selection_origin;
1053 if (debug)
1054 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1055 pfx_buf, new_buf, exist_buf,
1056 bgp_origin_long_str[newattr->origin],
1057 bgp_origin_long_str[existattr->origin]);
1058 return 0;
1059 }
1060
1061 /* 6. MED check. */
1062 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1063 && aspath_count_hops(existattr->aspath) == 0);
1064 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1065 && aspath_count_confeds(existattr->aspath) > 0
1066 && aspath_count_hops(newattr->aspath) == 0
1067 && aspath_count_hops(existattr->aspath) == 0);
1068
1069 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1070 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1071 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1072 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1073 || internal_as_route) {
1074 new_med = bgp_med_value(new->attr, bgp);
1075 exist_med = bgp_med_value(exist->attr, bgp);
1076
1077 if (new_med < exist_med) {
1078 *reason = bgp_path_selection_med;
1079 if (debug)
1080 zlog_debug(
1081 "%s: %s wins over %s due to MED %d < %d",
1082 pfx_buf, new_buf, exist_buf, new_med,
1083 exist_med);
1084 return 1;
1085 }
1086
1087 if (new_med > exist_med) {
1088 *reason = bgp_path_selection_med;
1089 if (debug)
1090 zlog_debug(
1091 "%s: %s loses to %s due to MED %d > %d",
1092 pfx_buf, new_buf, exist_buf, new_med,
1093 exist_med);
1094 return 0;
1095 }
1096 }
1097
1098 if (exist->sub_type == BGP_ROUTE_IMPORTED) {
1099 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
1100 peer_exist = bpi_ultimate->peer;
1101 } else
1102 peer_exist = exist->peer;
1103
1104 if (new->sub_type == BGP_ROUTE_IMPORTED) {
1105 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
1106 peer_new = bpi_ultimate->peer;
1107 } else
1108 peer_new = new->peer;
1109
1110 /* 7. Peer type check. */
1111 new_sort = peer_new->sort;
1112 exist_sort = peer_exist->sort;
1113
1114 if (new_sort == BGP_PEER_EBGP
1115 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1116 *reason = bgp_path_selection_peer;
1117 if (debug)
1118 zlog_debug(
1119 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1120 pfx_buf, new_buf, exist_buf);
1121 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_EBGP
1127 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1128 *reason = bgp_path_selection_peer;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1134 return 0;
1135 peer_sort_ret = 0;
1136 }
1137
1138 /* 8. IGP metric check. */
1139 newm = existm = 0;
1140
1141 if (new->extra)
1142 newm = new->extra->igpmetric;
1143 if (exist->extra)
1144 existm = exist->extra->igpmetric;
1145
1146 if (newm < existm) {
1147 if (debug && peer_sort_ret < 0)
1148 zlog_debug(
1149 "%s: %s wins over %s due to IGP metric %u < %u",
1150 pfx_buf, new_buf, exist_buf, newm, existm);
1151 igp_metric_ret = 1;
1152 }
1153
1154 if (newm > existm) {
1155 if (debug && peer_sort_ret < 0)
1156 zlog_debug(
1157 "%s: %s loses to %s due to IGP metric %u > %u",
1158 pfx_buf, new_buf, exist_buf, newm, existm);
1159 igp_metric_ret = 0;
1160 }
1161
1162 /* 9. Same IGP metric. Compare the cluster list length as
1163 representative of IGP hops metric. Rewrite the metric value
1164 pair (newm, existm) with the cluster list length. Prefer the
1165 path with smaller cluster list length. */
1166 if (newm == existm) {
1167 if (peer_sort_lookup(peer_new) == BGP_PEER_IBGP &&
1168 peer_sort_lookup(peer_exist) == BGP_PEER_IBGP &&
1169 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1170 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1171 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1172
1173 if (newm < existm) {
1174 if (debug && peer_sort_ret < 0)
1175 zlog_debug(
1176 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1177 pfx_buf, new_buf, exist_buf,
1178 newm, existm);
1179 igp_metric_ret = 1;
1180 }
1181
1182 if (newm > existm) {
1183 if (debug && peer_sort_ret < 0)
1184 zlog_debug(
1185 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1186 pfx_buf, new_buf, exist_buf,
1187 newm, existm);
1188 igp_metric_ret = 0;
1189 }
1190 }
1191 }
1192
1193 /* 10. confed-external vs. confed-internal */
1194 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1195 if (new_sort == BGP_PEER_CONFED
1196 && exist_sort == BGP_PEER_IBGP) {
1197 *reason = bgp_path_selection_confed;
1198 if (debug)
1199 zlog_debug(
1200 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1201 pfx_buf, new_buf, exist_buf);
1202 if (!CHECK_FLAG(bgp->flags,
1203 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1204 return 1;
1205 peer_sort_ret = 1;
1206 }
1207
1208 if (exist_sort == BGP_PEER_CONFED
1209 && new_sort == BGP_PEER_IBGP) {
1210 *reason = bgp_path_selection_confed;
1211 if (debug)
1212 zlog_debug(
1213 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1214 pfx_buf, new_buf, exist_buf);
1215 if (!CHECK_FLAG(bgp->flags,
1216 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1217 return 0;
1218 peer_sort_ret = 0;
1219 }
1220 }
1221
1222 /* 11. Maximum path check. */
1223 if (newm == existm) {
1224 /* If one path has a label but the other does not, do not treat
1225 * them as equals for multipath
1226 */
1227 int newl, existl;
1228
1229 newl = existl = 0;
1230
1231 if (new->extra)
1232 newl = new->extra->num_labels;
1233 if (exist->extra)
1234 existl = exist->extra->num_labels;
1235 if (((new->extra &&bgp_is_valid_label(&new->extra->label[0])) !=
1236 (exist->extra &&
1237 bgp_is_valid_label(&exist->extra->label[0]))) ||
1238 (newl != existl)) {
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1242 pfx_buf, new_buf, exist_buf);
1243 } else if (CHECK_FLAG(bgp->flags,
1244 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1245
1246 /*
1247 * For the two paths, all comparison steps till IGP
1248 * metric
1249 * have succeeded - including AS_PATH hop count. Since
1250 * 'bgp
1251 * bestpath as-path multipath-relax' knob is on, we
1252 * don't need
1253 * an exact match of AS_PATH. Thus, mark the paths are
1254 * equal.
1255 * That will trigger both these paths to get into the
1256 * multipath
1257 * array.
1258 */
1259 *paths_eq = 1;
1260
1261 if (debug)
1262 zlog_debug(
1263 "%s: %s and %s are equal via multipath-relax",
1264 pfx_buf, new_buf, exist_buf);
1265 } else if (peer_new->sort == BGP_PEER_IBGP) {
1266 if (aspath_cmp(new->attr->aspath,
1267 exist->attr->aspath)) {
1268 *paths_eq = 1;
1269
1270 if (debug)
1271 zlog_debug(
1272 "%s: %s and %s are equal via matching aspaths",
1273 pfx_buf, new_buf, exist_buf);
1274 }
1275 } else if (peer_new->as == peer_exist->as) {
1276 *paths_eq = 1;
1277
1278 if (debug)
1279 zlog_debug(
1280 "%s: %s and %s are equal via same remote-as",
1281 pfx_buf, new_buf, exist_buf);
1282 }
1283 } else {
1284 /*
1285 * TODO: If unequal cost ibgp multipath is enabled we can
1286 * mark the paths as equal here instead of returning
1287 */
1288
1289 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1290 * if either step 7 or 10 (peer type checks) yielded a winner,
1291 * that result was returned immediately. Returning from step 10
1292 * ignored the return value computed in steps 8 and 9 (IGP
1293 * metric checks). In order to preserve that behavior, if
1294 * peer_sort_ret is set, return that rather than igp_metric_ret.
1295 */
1296 ret = peer_sort_ret;
1297 if (peer_sort_ret < 0) {
1298 ret = igp_metric_ret;
1299 if (debug) {
1300 if (ret == 1)
1301 zlog_debug(
1302 "%s: %s wins over %s after IGP metric comparison",
1303 pfx_buf, new_buf, exist_buf);
1304 else
1305 zlog_debug(
1306 "%s: %s loses to %s after IGP metric comparison",
1307 pfx_buf, new_buf, exist_buf);
1308 }
1309 *reason = bgp_path_selection_igp_metric;
1310 }
1311 return ret;
1312 }
1313
1314 /*
1315 * At this point, the decision whether to set *paths_eq = 1 has been
1316 * completed. If we deferred returning because of bestpath peer-type
1317 * relax configuration, return now.
1318 */
1319 if (peer_sort_ret >= 0)
1320 return peer_sort_ret;
1321
1322 /* 12. If both paths are external, prefer the path that was received
1323 first (the oldest one). This step minimizes route-flap, since a
1324 newer path won't displace an older one, even if it was the
1325 preferred route based on the additional decision criteria below. */
1326 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1327 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1328 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1329 *reason = bgp_path_selection_older;
1330 if (debug)
1331 zlog_debug(
1332 "%s: %s wins over %s due to oldest external",
1333 pfx_buf, new_buf, exist_buf);
1334 return 1;
1335 }
1336
1337 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1338 *reason = bgp_path_selection_older;
1339 if (debug)
1340 zlog_debug(
1341 "%s: %s loses to %s due to oldest external",
1342 pfx_buf, new_buf, exist_buf);
1343 return 0;
1344 }
1345 }
1346
1347 /* 13. Router-ID comparison. */
1348 /* If one of the paths is "stale", the corresponding peer router-id will
1349 * be 0 and would always win over the other path. If originator id is
1350 * used for the comparison, it will decide which path is better.
1351 */
1352 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1353 new_id.s_addr = newattr->originator_id.s_addr;
1354 else
1355 new_id.s_addr = peer_new->remote_id.s_addr;
1356 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1357 exist_id.s_addr = existattr->originator_id.s_addr;
1358 else
1359 exist_id.s_addr = peer_exist->remote_id.s_addr;
1360
1361 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1362 *reason = bgp_path_selection_router_id;
1363 if (debug)
1364 zlog_debug(
1365 "%s: %s wins over %s due to Router-ID comparison",
1366 pfx_buf, new_buf, exist_buf);
1367 return 1;
1368 }
1369
1370 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1371 *reason = bgp_path_selection_router_id;
1372 if (debug)
1373 zlog_debug(
1374 "%s: %s loses to %s due to Router-ID comparison",
1375 pfx_buf, new_buf, exist_buf);
1376 return 0;
1377 }
1378
1379 /* 14. Cluster length comparison. */
1380 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1381 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1382
1383 if (new_cluster < exist_cluster) {
1384 *reason = bgp_path_selection_cluster_length;
1385 if (debug)
1386 zlog_debug(
1387 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1388 pfx_buf, new_buf, exist_buf, new_cluster,
1389 exist_cluster);
1390 return 1;
1391 }
1392
1393 if (new_cluster > exist_cluster) {
1394 *reason = bgp_path_selection_cluster_length;
1395 if (debug)
1396 zlog_debug(
1397 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1398 pfx_buf, new_buf, exist_buf, new_cluster,
1399 exist_cluster);
1400 return 0;
1401 }
1402
1403 /* 15. Neighbor address comparison. */
1404 /* Do this only if neither path is "stale" as stale paths do not have
1405 * valid peer information (as the connection may or may not be up).
1406 */
1407 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1408 *reason = bgp_path_selection_stale;
1409 if (debug)
1410 zlog_debug(
1411 "%s: %s wins over %s due to latter path being STALE",
1412 pfx_buf, new_buf, exist_buf);
1413 return 1;
1414 }
1415
1416 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1417 *reason = bgp_path_selection_stale;
1418 if (debug)
1419 zlog_debug(
1420 "%s: %s loses to %s due to former path being STALE",
1421 pfx_buf, new_buf, exist_buf);
1422 return 0;
1423 }
1424
1425 /* locally configured routes to advertise do not have su_remote */
1426 if (peer_new->su_remote == NULL) {
1427 *reason = bgp_path_selection_local_configured;
1428 return 0;
1429 }
1430
1431 if (peer_exist->su_remote == NULL) {
1432 *reason = bgp_path_selection_local_configured;
1433 return 1;
1434 }
1435
1436 ret = sockunion_cmp(peer_new->su_remote, peer_exist->su_remote);
1437
1438 if (ret == 1) {
1439 *reason = bgp_path_selection_neighbor_ip;
1440 if (debug)
1441 zlog_debug(
1442 "%s: %s loses to %s due to Neighor IP comparison",
1443 pfx_buf, new_buf, exist_buf);
1444 return 0;
1445 }
1446
1447 if (ret == -1) {
1448 *reason = bgp_path_selection_neighbor_ip;
1449 if (debug)
1450 zlog_debug(
1451 "%s: %s wins over %s due to Neighor IP comparison",
1452 pfx_buf, new_buf, exist_buf);
1453 return 1;
1454 }
1455
1456 *reason = bgp_path_selection_default;
1457 if (debug)
1458 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1459 pfx_buf, new_buf, exist_buf);
1460
1461 return 1;
1462 }
1463
1464
1465 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1466 struct bgp_path_info *exist, int *paths_eq)
1467 {
1468 enum bgp_path_selection_reason reason;
1469 char pfx_buf[PREFIX2STR_BUFFER];
1470
1471 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1472 AFI_L2VPN, SAFI_EVPN, &reason);
1473 }
1474
1475 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1476 * is preferred, or 0 if they are the same (usually will only occur if
1477 * multipath is enabled
1478 * This version is compatible with */
1479 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1480 struct bgp_path_info *exist, char *pfx_buf,
1481 afi_t afi, safi_t safi,
1482 enum bgp_path_selection_reason *reason)
1483 {
1484 int paths_eq;
1485 int ret;
1486 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1487 afi, safi, reason);
1488
1489 if (paths_eq)
1490 ret = 0;
1491 else {
1492 if (ret == 1)
1493 ret = -1;
1494 else
1495 ret = 1;
1496 }
1497 return ret;
1498 }
1499
1500 static enum filter_type bgp_input_filter(struct peer *peer,
1501 const struct prefix *p,
1502 struct attr *attr, afi_t afi,
1503 safi_t safi)
1504 {
1505 struct bgp_filter *filter;
1506 enum filter_type ret = FILTER_PERMIT;
1507
1508 filter = &peer->filter[afi][safi];
1509
1510 #define FILTER_EXIST_WARN(F, f, filter) \
1511 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1512 zlog_debug("%s: Could not find configured input %s-list %s!", \
1513 peer->host, #f, F##_IN_NAME(filter));
1514
1515 if (DISTRIBUTE_IN_NAME(filter)) {
1516 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1517
1518 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1519 == FILTER_DENY) {
1520 ret = FILTER_DENY;
1521 goto done;
1522 }
1523 }
1524
1525 if (PREFIX_LIST_IN_NAME(filter)) {
1526 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1527
1528 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1529 == PREFIX_DENY) {
1530 ret = FILTER_DENY;
1531 goto done;
1532 }
1533 }
1534
1535 if (FILTER_LIST_IN_NAME(filter)) {
1536 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1537
1538 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1539 == AS_FILTER_DENY) {
1540 ret = FILTER_DENY;
1541 goto done;
1542 }
1543 }
1544
1545 done:
1546 if (frrtrace_enabled(frr_bgp, input_filter)) {
1547 char pfxprint[PREFIX2STR_BUFFER];
1548
1549 prefix2str(p, pfxprint, sizeof(pfxprint));
1550 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1551 ret == FILTER_PERMIT ? "permit" : "deny");
1552 }
1553
1554 return ret;
1555 #undef FILTER_EXIST_WARN
1556 }
1557
1558 static enum filter_type bgp_output_filter(struct peer *peer,
1559 const struct prefix *p,
1560 struct attr *attr, afi_t afi,
1561 safi_t safi)
1562 {
1563 struct bgp_filter *filter;
1564 enum filter_type ret = FILTER_PERMIT;
1565
1566 filter = &peer->filter[afi][safi];
1567
1568 #define FILTER_EXIST_WARN(F, f, filter) \
1569 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1570 zlog_debug("%s: Could not find configured output %s-list %s!", \
1571 peer->host, #f, F##_OUT_NAME(filter));
1572
1573 if (DISTRIBUTE_OUT_NAME(filter)) {
1574 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1575
1576 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1577 == FILTER_DENY) {
1578 ret = FILTER_DENY;
1579 goto done;
1580 }
1581 }
1582
1583 if (PREFIX_LIST_OUT_NAME(filter)) {
1584 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1585
1586 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1587 == PREFIX_DENY) {
1588 ret = FILTER_DENY;
1589 goto done;
1590 }
1591 }
1592
1593 if (FILTER_LIST_OUT_NAME(filter)) {
1594 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1595
1596 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1597 == AS_FILTER_DENY) {
1598 ret = FILTER_DENY;
1599 goto done;
1600 }
1601 }
1602
1603 if (frrtrace_enabled(frr_bgp, output_filter)) {
1604 char pfxprint[PREFIX2STR_BUFFER];
1605
1606 prefix2str(p, pfxprint, sizeof(pfxprint));
1607 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1608 ret == FILTER_PERMIT ? "permit" : "deny");
1609 }
1610
1611 done:
1612 return ret;
1613 #undef FILTER_EXIST_WARN
1614 }
1615
1616 /* If community attribute includes no_export then return 1. */
1617 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1618 {
1619 if (bgp_attr_get_community(attr)) {
1620 /* NO_ADVERTISE check. */
1621 if (community_include(bgp_attr_get_community(attr),
1622 COMMUNITY_NO_ADVERTISE))
1623 return true;
1624
1625 /* NO_EXPORT check. */
1626 if (peer->sort == BGP_PEER_EBGP &&
1627 community_include(bgp_attr_get_community(attr),
1628 COMMUNITY_NO_EXPORT))
1629 return true;
1630
1631 /* NO_EXPORT_SUBCONFED check. */
1632 if (peer->sort == BGP_PEER_EBGP
1633 || peer->sort == BGP_PEER_CONFED)
1634 if (community_include(bgp_attr_get_community(attr),
1635 COMMUNITY_NO_EXPORT_SUBCONFED))
1636 return true;
1637 }
1638 return false;
1639 }
1640
1641 /* Route reflection loop check. */
1642 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1643 {
1644 struct in_addr cluster_id;
1645 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1646
1647 if (cluster) {
1648 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1649 cluster_id = peer->bgp->cluster_id;
1650 else
1651 cluster_id = peer->bgp->router_id;
1652
1653 if (cluster_loop_check(cluster, cluster_id))
1654 return true;
1655 }
1656 return false;
1657 }
1658
1659 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1660 {
1661 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1662 if (peer->local_role == ROLE_PROVIDER ||
1663 peer->local_role == ROLE_RS_SERVER)
1664 return true;
1665 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1666 return true;
1667 return false;
1668 }
1669 if (peer->local_role == ROLE_CUSTOMER ||
1670 peer->local_role == ROLE_PEER ||
1671 peer->local_role == ROLE_RS_CLIENT) {
1672 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1673 attr->otc = peer->as;
1674 }
1675 return false;
1676 }
1677
1678 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1679 {
1680 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1681 if (peer->local_role == ROLE_CUSTOMER ||
1682 peer->local_role == ROLE_RS_CLIENT ||
1683 peer->local_role == ROLE_PEER)
1684 return true;
1685 return false;
1686 }
1687 if (peer->local_role == ROLE_PROVIDER ||
1688 peer->local_role == ROLE_PEER ||
1689 peer->local_role == ROLE_RS_SERVER) {
1690 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1691 attr->otc = peer->bgp->as;
1692 }
1693 return false;
1694 }
1695
1696 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1697 {
1698 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1699 }
1700
1701 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1702 struct attr *attr, afi_t afi, safi_t safi,
1703 const char *rmap_name, mpls_label_t *label,
1704 uint32_t num_labels, struct bgp_dest *dest)
1705 {
1706 struct bgp_filter *filter;
1707 struct bgp_path_info rmap_path = { 0 };
1708 struct bgp_path_info_extra extra = { 0 };
1709 route_map_result_t ret;
1710 struct route_map *rmap = NULL;
1711
1712 filter = &peer->filter[afi][safi];
1713
1714 /* Apply default weight value. */
1715 if (peer->weight[afi][safi])
1716 attr->weight = peer->weight[afi][safi];
1717
1718 if (rmap_name) {
1719 rmap = route_map_lookup_by_name(rmap_name);
1720
1721 if (rmap == NULL)
1722 return RMAP_DENY;
1723 } else {
1724 if (ROUTE_MAP_IN_NAME(filter)) {
1725 rmap = ROUTE_MAP_IN(filter);
1726
1727 if (rmap == NULL)
1728 return RMAP_DENY;
1729 }
1730 }
1731
1732 /* Route map apply. */
1733 if (rmap) {
1734 memset(&rmap_path, 0, sizeof(rmap_path));
1735 /* Duplicate current value to new structure for modification. */
1736 rmap_path.peer = peer;
1737 rmap_path.attr = attr;
1738 rmap_path.extra = &extra;
1739 rmap_path.net = dest;
1740
1741 extra.num_labels = num_labels;
1742 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1743 memcpy(extra.label, label,
1744 num_labels * sizeof(mpls_label_t));
1745
1746 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1747
1748 /* Apply BGP route map to the attribute. */
1749 ret = route_map_apply(rmap, p, &rmap_path);
1750
1751 peer->rmap_type = 0;
1752
1753 if (ret == RMAP_DENYMATCH)
1754 return RMAP_DENY;
1755 }
1756 return RMAP_PERMIT;
1757 }
1758
1759 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1760 struct attr *attr, afi_t afi, safi_t safi,
1761 const char *rmap_name)
1762 {
1763 struct bgp_path_info rmap_path;
1764 route_map_result_t ret;
1765 struct route_map *rmap = NULL;
1766 uint8_t rmap_type;
1767
1768 /*
1769 * So if we get to this point and have no rmap_name
1770 * we want to just show the output as it currently
1771 * exists.
1772 */
1773 if (!rmap_name)
1774 return RMAP_PERMIT;
1775
1776 /* Apply default weight value. */
1777 if (peer->weight[afi][safi])
1778 attr->weight = peer->weight[afi][safi];
1779
1780 rmap = route_map_lookup_by_name(rmap_name);
1781
1782 /*
1783 * If we have a route map name and we do not find
1784 * the routemap that means we have an implicit
1785 * deny.
1786 */
1787 if (rmap == NULL)
1788 return RMAP_DENY;
1789
1790 memset(&rmap_path, 0, sizeof(rmap_path));
1791 /* Route map apply. */
1792 /* Duplicate current value to new structure for modification. */
1793 rmap_path.peer = peer;
1794 rmap_path.attr = attr;
1795
1796 rmap_type = peer->rmap_type;
1797 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1798
1799 /* Apply BGP route map to the attribute. */
1800 ret = route_map_apply(rmap, p, &rmap_path);
1801
1802 peer->rmap_type = rmap_type;
1803
1804 if (ret == RMAP_DENYMATCH)
1805 /*
1806 * caller has multiple error paths with bgp_attr_flush()
1807 */
1808 return RMAP_DENY;
1809
1810 return RMAP_PERMIT;
1811 }
1812
1813 /* If this is an EBGP peer with remove-private-AS */
1814 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1815 struct peer *peer, struct attr *attr)
1816 {
1817 if (peer->sort == BGP_PEER_EBGP
1818 && (peer_af_flag_check(peer, afi, safi,
1819 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1820 || peer_af_flag_check(peer, afi, safi,
1821 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1822 || peer_af_flag_check(peer, afi, safi,
1823 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1824 || peer_af_flag_check(peer, afi, safi,
1825 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1826 // Take action on the entire aspath
1827 if (peer_af_flag_check(peer, afi, safi,
1828 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1829 || peer_af_flag_check(peer, afi, safi,
1830 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1831 if (peer_af_flag_check(
1832 peer, afi, safi,
1833 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1834 attr->aspath = aspath_replace_private_asns(
1835 attr->aspath, bgp->as, peer->as);
1836
1837 /*
1838 * Even if the aspath consists of just private ASNs we
1839 * need to walk the AS-Path to maintain all instances
1840 * of the peer's ASN to break possible loops.
1841 */
1842 else
1843 attr->aspath = aspath_remove_private_asns(
1844 attr->aspath, peer->as);
1845 }
1846
1847 // 'all' was not specified so the entire aspath must be private
1848 // ASNs
1849 // for us to do anything
1850 else if (aspath_private_as_check(attr->aspath)) {
1851 if (peer_af_flag_check(
1852 peer, afi, safi,
1853 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1854 attr->aspath = aspath_replace_private_asns(
1855 attr->aspath, bgp->as, peer->as);
1856 else
1857 /*
1858 * Walk the aspath to retain any instances of
1859 * the peer_asn
1860 */
1861 attr->aspath = aspath_remove_private_asns(
1862 attr->aspath, peer->as);
1863 }
1864 }
1865 }
1866
1867 /* If this is an EBGP peer with as-override */
1868 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1869 struct peer *peer, struct attr *attr)
1870 {
1871 struct aspath *aspath;
1872
1873 if (peer->sort == BGP_PEER_EBGP &&
1874 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1875 if (attr->aspath->refcnt)
1876 aspath = aspath_dup(attr->aspath);
1877 else
1878 aspath = attr->aspath;
1879
1880 attr->aspath = aspath_intern(
1881 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1882
1883 aspath_free(aspath);
1884 }
1885 }
1886
1887 void bgp_attr_add_llgr_community(struct attr *attr)
1888 {
1889 struct community *old;
1890 struct community *new;
1891 struct community *merge;
1892 struct community *llgr;
1893
1894 old = bgp_attr_get_community(attr);
1895 llgr = community_str2com("llgr-stale");
1896
1897 assert(llgr);
1898
1899 if (old) {
1900 merge = community_merge(community_dup(old), llgr);
1901
1902 if (old->refcnt == 0)
1903 community_free(&old);
1904
1905 new = community_uniq_sort(merge);
1906 community_free(&merge);
1907 } else {
1908 new = community_dup(llgr);
1909 }
1910
1911 community_free(&llgr);
1912
1913 bgp_attr_set_community(attr, new);
1914 }
1915
1916 void bgp_attr_add_gshut_community(struct attr *attr)
1917 {
1918 struct community *old;
1919 struct community *new;
1920 struct community *merge;
1921 struct community *gshut;
1922
1923 old = bgp_attr_get_community(attr);
1924 gshut = community_str2com("graceful-shutdown");
1925
1926 assert(gshut);
1927
1928 if (old) {
1929 merge = community_merge(community_dup(old), gshut);
1930
1931 if (old->refcnt == 0)
1932 community_free(&old);
1933
1934 new = community_uniq_sort(merge);
1935 community_free(&merge);
1936 } else {
1937 new = community_dup(gshut);
1938 }
1939
1940 community_free(&gshut);
1941 bgp_attr_set_community(attr, new);
1942
1943 /* When we add the graceful-shutdown community we must also
1944 * lower the local-preference */
1945 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1946 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1947 }
1948
1949
1950 /* Notify BGP Conditional advertisement scanner process. */
1951 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1952 {
1953 struct peer *peer = SUBGRP_PEER(subgrp);
1954 afi_t afi = SUBGRP_AFI(subgrp);
1955 safi_t safi = SUBGRP_SAFI(subgrp);
1956 struct bgp_filter *filter = &peer->filter[afi][safi];
1957
1958 if (!ADVERTISE_MAP_NAME(filter))
1959 return;
1960
1961 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1962 return;
1963
1964 peer->advmap_table_change = true;
1965 }
1966
1967
1968 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1969 {
1970 if (family == AF_INET) {
1971 attr->nexthop.s_addr = INADDR_ANY;
1972 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1973 }
1974 if (family == AF_INET6)
1975 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1976 if (family == AF_EVPN)
1977 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1978 }
1979
1980 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1981 struct update_subgroup *subgrp,
1982 const struct prefix *p, struct attr *attr,
1983 struct attr *post_attr)
1984 {
1985 struct bgp_filter *filter;
1986 struct peer *from;
1987 struct peer *peer;
1988 struct peer *onlypeer;
1989 struct bgp *bgp;
1990 struct attr *piattr;
1991 route_map_result_t ret;
1992 int transparent;
1993 int reflect;
1994 afi_t afi;
1995 safi_t safi;
1996 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1997 bool nh_reset = false;
1998 uint64_t cum_bw;
1999
2000 if (DISABLE_BGP_ANNOUNCE)
2001 return false;
2002
2003 afi = SUBGRP_AFI(subgrp);
2004 safi = SUBGRP_SAFI(subgrp);
2005 peer = SUBGRP_PEER(subgrp);
2006 onlypeer = NULL;
2007 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2008 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2009
2010 from = pi->peer;
2011 filter = &peer->filter[afi][safi];
2012 bgp = SUBGRP_INST(subgrp);
2013 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2014 : pi->attr;
2015
2016 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2017 peer->pmax_out[afi][safi] != 0 &&
2018 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2019 if (BGP_DEBUG(update, UPDATE_OUT) ||
2020 BGP_DEBUG(update, UPDATE_PREFIX)) {
2021 zlog_debug("%s reached maximum prefix to be send (%u)",
2022 peer->host, peer->pmax_out[afi][safi]);
2023 }
2024 return false;
2025 }
2026
2027 #ifdef ENABLE_BGP_VNC
2028 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2029 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2030 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2031
2032 /*
2033 * direct and direct_ext type routes originate internally even
2034 * though they can have peer pointers that reference other
2035 * systems
2036 */
2037 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2038 __func__, p);
2039 samepeer_safe = 1;
2040 }
2041 #endif
2042
2043 if (((afi == AFI_IP) || (afi == AFI_IP6))
2044 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2045 && (pi->type == ZEBRA_ROUTE_BGP)
2046 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2047
2048 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2049
2050 samepeer_safe = 1;
2051 }
2052
2053 /* With addpath we may be asked to TX all kinds of paths so make sure
2054 * pi is valid */
2055 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2056 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2057 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2058 return false;
2059 }
2060
2061 /* If this is not the bestpath then check to see if there is an enabled
2062 * addpath
2063 * feature that requires us to advertise it */
2064 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2065 if (!bgp_addpath_capable(pi, peer, afi, safi))
2066 return false;
2067
2068 /* Aggregate-address suppress check. */
2069 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2070 return false;
2071
2072 /*
2073 * If we are doing VRF 2 VRF leaking via the import
2074 * statement, we want to prevent the route going
2075 * off box as that the RT and RD created are localy
2076 * significant and globaly useless.
2077 */
2078 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2079 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2080 return false;
2081
2082 /* If it's labeled safi, make sure the route has a valid label. */
2083 if (safi == SAFI_LABELED_UNICAST) {
2084 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2085 if (!bgp_is_valid_label(&label)) {
2086 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2087 zlog_debug("u%" PRIu64 ":s%" PRIu64
2088 " %pFX is filtered - no label (%p)",
2089 subgrp->update_group->id, subgrp->id,
2090 p, &label);
2091 return false;
2092 }
2093 }
2094
2095 /* Do not send back route to sender. */
2096 if (onlypeer && from == onlypeer) {
2097 return false;
2098 }
2099
2100 /* Do not send the default route in the BGP table if the neighbor is
2101 * configured for default-originate */
2102 if (CHECK_FLAG(peer->af_flags[afi][safi],
2103 PEER_FLAG_DEFAULT_ORIGINATE)) {
2104 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2105 return false;
2106 else if (p->family == AF_INET6 && p->prefixlen == 0)
2107 return false;
2108 }
2109
2110 /* Transparency check. */
2111 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2112 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2113 transparent = 1;
2114 else
2115 transparent = 0;
2116
2117 /* If community is not disabled check the no-export and local. */
2118 if (!transparent && bgp_community_filter(peer, piattr)) {
2119 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2120 zlog_debug("%s: community filter check fail for %pFX",
2121 __func__, p);
2122 return false;
2123 }
2124
2125 /* If the attribute has originator-id and it is same as remote
2126 peer's id. */
2127 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2128 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2129 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2130 zlog_debug(
2131 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2132 onlypeer, p);
2133 return false;
2134 }
2135
2136 /* ORF prefix-list filter check */
2137 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2138 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2139 || CHECK_FLAG(peer->af_cap[afi][safi],
2140 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2141 if (peer->orf_plist[afi][safi]) {
2142 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2143 == PREFIX_DENY) {
2144 if (bgp_debug_update(NULL, p,
2145 subgrp->update_group, 0))
2146 zlog_debug(
2147 "%pBP [Update:SEND] %pFX is filtered via ORF",
2148 peer, p);
2149 return false;
2150 }
2151 }
2152
2153 /* Output filter check. */
2154 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2155 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2156 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2157 p);
2158 return false;
2159 }
2160
2161 /* AS path loop check. */
2162 if (peer->as_path_loop_detection &&
2163 aspath_loop_check(piattr->aspath, peer->as)) {
2164 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2165 zlog_debug(
2166 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2167 peer, peer->as);
2168 return false;
2169 }
2170
2171 /* If we're a CONFED we need to loop check the CONFED ID too */
2172 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2173 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2174 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2175 zlog_debug(
2176 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2177 peer, bgp->confed_id);
2178 return false;
2179 }
2180 }
2181
2182 /* Route-Reflect check. */
2183 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2184 reflect = 1;
2185 else
2186 reflect = 0;
2187
2188 /* IBGP reflection check. */
2189 if (reflect && !samepeer_safe) {
2190 /* A route from a Client peer. */
2191 if (CHECK_FLAG(from->af_flags[afi][safi],
2192 PEER_FLAG_REFLECTOR_CLIENT)) {
2193 /* Reflect to all the Non-Client peers and also to the
2194 Client peers other than the originator. Originator
2195 check
2196 is already done. So there is noting to do. */
2197 /* no bgp client-to-client reflection check. */
2198 if (CHECK_FLAG(bgp->flags,
2199 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2200 if (CHECK_FLAG(peer->af_flags[afi][safi],
2201 PEER_FLAG_REFLECTOR_CLIENT))
2202 return false;
2203 } else {
2204 /* A route from a Non-client peer. Reflect to all other
2205 clients. */
2206 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2207 PEER_FLAG_REFLECTOR_CLIENT))
2208 return false;
2209 }
2210 }
2211
2212 /* For modify attribute, copy it to temporary structure.
2213 * post_attr comes from BGP conditional advertisements, where
2214 * attributes are already processed by advertise-map route-map,
2215 * and this needs to be saved instead of overwriting from the
2216 * path attributes.
2217 */
2218 if (post_attr)
2219 *attr = *post_attr;
2220 else
2221 *attr = *piattr;
2222
2223 /* If local-preference is not set. */
2224 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2225 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2226 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2227 attr->local_pref = bgp->default_local_pref;
2228 }
2229
2230 /* If originator-id is not set and the route is to be reflected,
2231 set the originator id */
2232 if (reflect
2233 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2234 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2235 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2236 }
2237
2238 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2239 */
2240 if (peer->sort == BGP_PEER_EBGP
2241 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2242 if (from != bgp->peer_self && !transparent
2243 && !CHECK_FLAG(peer->af_flags[afi][safi],
2244 PEER_FLAG_MED_UNCHANGED))
2245 attr->flag &=
2246 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2247 }
2248
2249 /* Since the nexthop attribute can vary per peer, it is not explicitly
2250 * set
2251 * in announce check, only certain flags and length (or number of
2252 * nexthops
2253 * -- for IPv6/MP_REACH) are set here in order to guide the update
2254 * formation
2255 * code in setting the nexthop(s) on a per peer basis in
2256 * reformat_peer().
2257 * Typically, the source nexthop in the attribute is preserved but in
2258 * the
2259 * scenarios where we know it will always be overwritten, we reset the
2260 * nexthop to "0" in an attempt to achieve better Update packing. An
2261 * example of this is when a prefix from each of 2 IBGP peers needs to
2262 * be
2263 * announced to an EBGP peer (and they have the same attributes barring
2264 * their nexthop).
2265 */
2266 if (reflect)
2267 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2268
2269 #define NEXTHOP_IS_V6 \
2270 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2271 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2272 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2273 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2274
2275 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2276 * if
2277 * the peer (group) is configured to receive link-local nexthop
2278 * unchanged
2279 * and it is available in the prefix OR we're not reflecting the route,
2280 * link-local nexthop address is valid and
2281 * the peer (group) to whom we're going to announce is on a shared
2282 * network
2283 * and this is either a self-originated route or the peer is EBGP.
2284 * By checking if nexthop LL address is valid we are sure that
2285 * we do not announce LL address as `::`.
2286 */
2287 if (NEXTHOP_IS_V6) {
2288 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2289 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2290 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2291 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2292 || (!reflect && !transparent
2293 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2294 && peer->shared_network
2295 && (from == bgp->peer_self
2296 || peer->sort == BGP_PEER_EBGP))) {
2297 if (safi == SAFI_MPLS_VPN)
2298 attr->mp_nexthop_len =
2299 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2300 else
2301 attr->mp_nexthop_len =
2302 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2303 }
2304
2305 /* Clear off link-local nexthop in source, whenever it is not
2306 * needed to
2307 * ensure more prefixes share the same attribute for
2308 * announcement.
2309 */
2310 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2311 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2312 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2313 }
2314
2315 if (bgp_check_role_applicability(afi, safi) &&
2316 bgp_otc_egress(peer, attr))
2317 return false;
2318
2319 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2320 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2321
2322 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2323 filter->advmap.aname &&
2324 route_map_lookup_by_name(filter->advmap.aname)) {
2325 struct bgp_path_info rmap_path = {0};
2326 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2327 struct attr dummy_attr = *attr;
2328
2329 /* Fill temp path_info */
2330 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2331 pi, peer, &dummy_attr);
2332
2333 struct route_map *amap =
2334 route_map_lookup_by_name(filter->advmap.aname);
2335
2336 ret = route_map_apply(amap, p, &rmap_path);
2337
2338 bgp_attr_flush(&dummy_attr);
2339
2340 /*
2341 * The conditional advertisement mode is Withdraw and this
2342 * prefix is a conditional prefix. Don't advertise it
2343 */
2344 if (ret == RMAP_PERMITMATCH)
2345 return false;
2346 }
2347
2348 /* Route map & unsuppress-map apply. */
2349 if (!post_attr &&
2350 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2351 struct bgp_path_info rmap_path = {0};
2352 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2353 struct attr dummy_attr = {0};
2354
2355 /* Fill temp path_info */
2356 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2357 pi, peer, attr);
2358
2359 /* don't confuse inbound and outbound setting */
2360 RESET_FLAG(attr->rmap_change_flags);
2361
2362 /*
2363 * The route reflector is not allowed to modify the attributes
2364 * of the reflected IBGP routes unless explicitly allowed.
2365 */
2366 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2367 && !CHECK_FLAG(bgp->flags,
2368 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2369 dummy_attr = *attr;
2370 rmap_path.attr = &dummy_attr;
2371 }
2372
2373 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2374
2375 if (bgp_path_suppressed(pi))
2376 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2377 &rmap_path);
2378 else
2379 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2380 &rmap_path);
2381
2382 bgp_attr_flush(&dummy_attr);
2383 peer->rmap_type = 0;
2384
2385 if (ret == RMAP_DENYMATCH) {
2386 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2387 zlog_debug(
2388 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2389 peer, p,
2390 bgp_path_suppressed(pi)
2391 ? UNSUPPRESS_MAP_NAME(filter)
2392 : ROUTE_MAP_OUT_NAME(filter));
2393 bgp_attr_flush(rmap_path.attr);
2394 return false;
2395 }
2396 }
2397
2398 /* RFC 8212 to prevent route leaks.
2399 * This specification intends to improve this situation by requiring the
2400 * explicit configuration of both BGP Import and Export Policies for any
2401 * External BGP (EBGP) session such as customers, peers, or
2402 * confederation boundaries for all enabled address families. Through
2403 * codification of the aforementioned requirement, operators will
2404 * benefit from consistent behavior across different BGP
2405 * implementations.
2406 */
2407 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2408 if (!bgp_outbound_policy_exists(peer, filter)) {
2409 if (monotime_since(&bgp->ebgprequirespolicywarning,
2410 NULL) > FIFTEENMINUTE2USEC ||
2411 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2412 zlog_warn(
2413 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2414 monotime(&bgp->ebgprequirespolicywarning);
2415 }
2416 return false;
2417 }
2418
2419 /* draft-ietf-idr-deprecate-as-set-confed-set
2420 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2421 * Eventually, This document (if approved) updates RFC 4271
2422 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2423 * and obsoletes RFC 6472.
2424 */
2425 if (peer->bgp->reject_as_sets)
2426 if (aspath_check_as_sets(attr->aspath))
2427 return false;
2428
2429 /* If neighbor soo is configured, then check if the route has
2430 * SoO extended community and validate against the configured
2431 * one. If they match, do not announce, to prevent routing
2432 * loops.
2433 */
2434 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2435 peer->soo[afi][safi]) {
2436 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2437 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2438
2439 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2440 ECOMMUNITY_SITE_ORIGIN) ||
2441 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2442 ECOMMUNITY_SITE_ORIGIN) ||
2443 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2444 ECOMMUNITY_SITE_ORIGIN)) &&
2445 ecommunity_include(ecomm, ecomm_soo)) {
2446 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2447 zlog_debug(
2448 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2449 peer, p, ecommunity_str(ecomm_soo));
2450 return false;
2451 }
2452 }
2453
2454 /* Codification of AS 0 Processing */
2455 if (aspath_check_as_zero(attr->aspath))
2456 return false;
2457
2458 if (bgp_in_graceful_shutdown(bgp)) {
2459 if (peer->sort == BGP_PEER_IBGP
2460 || peer->sort == BGP_PEER_CONFED) {
2461 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2462 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2463 } else {
2464 bgp_attr_add_gshut_community(attr);
2465 }
2466 }
2467
2468 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2469 * Capability" to a neighbor MUST perform the following upon receiving
2470 * a route from that neighbor with the "LLGR_STALE" community, or upon
2471 * attaching the "LLGR_STALE" community itself per Section 4.2:
2472 *
2473 * The route SHOULD NOT be advertised to any neighbor from which the
2474 * Long-lived Graceful Restart Capability has not been received.
2475 */
2476 if (bgp_attr_get_community(attr) &&
2477 community_include(bgp_attr_get_community(attr),
2478 COMMUNITY_LLGR_STALE) &&
2479 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2480 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2481 return false;
2482
2483 /* After route-map has been applied, we check to see if the nexthop to
2484 * be carried in the attribute (that is used for the announcement) can
2485 * be cleared off or not. We do this in all cases where we would be
2486 * setting the nexthop to "ourselves". For IPv6, we only need to
2487 * consider
2488 * the global nexthop here; the link-local nexthop would have been
2489 * cleared
2490 * already, and if not, it is required by the update formation code.
2491 * Also see earlier comments in this function.
2492 */
2493 /*
2494 * If route-map has performed some operation on the nexthop or the peer
2495 * configuration says to pass it unchanged, we cannot reset the nexthop
2496 * here, so only attempt to do it if these aren't true. Note that the
2497 * route-map handler itself might have cleared the nexthop, if for
2498 * example,
2499 * it is configured as 'peer-address'.
2500 */
2501 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2502 piattr->rmap_change_flags)
2503 && !transparent
2504 && !CHECK_FLAG(peer->af_flags[afi][safi],
2505 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2506 /* We can reset the nexthop, if setting (or forcing) it to
2507 * 'self' */
2508 if (CHECK_FLAG(peer->af_flags[afi][safi],
2509 PEER_FLAG_NEXTHOP_SELF)
2510 || CHECK_FLAG(peer->af_flags[afi][safi],
2511 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2512 if (!reflect
2513 || CHECK_FLAG(peer->af_flags[afi][safi],
2514 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2515 subgroup_announce_reset_nhop(
2516 (peer_cap_enhe(peer, afi, safi)
2517 ? AF_INET6
2518 : p->family),
2519 attr);
2520 nh_reset = true;
2521 }
2522 } else if (peer->sort == BGP_PEER_EBGP) {
2523 /* Can also reset the nexthop if announcing to EBGP, but
2524 * only if
2525 * no peer in the subgroup is on a shared subnet.
2526 * Note: 3rd party nexthop currently implemented for
2527 * IPv4 only.
2528 */
2529 if ((p->family == AF_INET) &&
2530 (!bgp_subgrp_multiaccess_check_v4(
2531 piattr->nexthop,
2532 subgrp, from))) {
2533 subgroup_announce_reset_nhop(
2534 (peer_cap_enhe(peer, afi, safi)
2535 ? AF_INET6
2536 : p->family),
2537 attr);
2538 nh_reset = true;
2539 }
2540
2541 if ((p->family == AF_INET6) &&
2542 (!bgp_subgrp_multiaccess_check_v6(
2543 piattr->mp_nexthop_global,
2544 subgrp, from))) {
2545 subgroup_announce_reset_nhop(
2546 (peer_cap_enhe(peer, afi, safi)
2547 ? AF_INET6
2548 : p->family),
2549 attr);
2550 nh_reset = true;
2551 }
2552
2553
2554
2555 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2556 /*
2557 * This flag is used for leaked vpn-vrf routes
2558 */
2559 int family = p->family;
2560
2561 if (peer_cap_enhe(peer, afi, safi))
2562 family = AF_INET6;
2563
2564 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2565 zlog_debug(
2566 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2567 __func__, p, family2str(family));
2568 subgroup_announce_reset_nhop(family, attr);
2569 nh_reset = true;
2570 }
2571 }
2572
2573 /* If IPv6/MP and nexthop does not have any override and happens
2574 * to
2575 * be a link-local address, reset it so that we don't pass along
2576 * the
2577 * source's link-local IPv6 address to recipients who may not be
2578 * on
2579 * the same interface.
2580 */
2581 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2582 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2583 subgroup_announce_reset_nhop(AF_INET6, attr);
2584 nh_reset = true;
2585 }
2586 }
2587
2588 /* If this is an iBGP, send Origin Validation State (OVS)
2589 * extended community (rfc8097).
2590 */
2591 if (peer->sort == BGP_PEER_IBGP) {
2592 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2593
2594 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2595
2596 if (rpki_state != RPKI_NOT_BEING_USED)
2597 bgp_attr_set_ecommunity(
2598 attr, ecommunity_add_origin_validation_state(
2599 rpki_state,
2600 bgp_attr_get_ecommunity(attr)));
2601 }
2602
2603 /*
2604 * When the next hop is set to ourselves, if all multipaths have
2605 * link-bandwidth announce the cumulative bandwidth as that makes
2606 * the most sense. However, don't modify if the link-bandwidth has
2607 * been explicitly set by user policy.
2608 */
2609 if (nh_reset &&
2610 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2611 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2612 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2613 bgp_attr_set_ecommunity(
2614 attr,
2615 ecommunity_replace_linkbw(
2616 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2617 CHECK_FLAG(
2618 peer->flags,
2619 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2620
2621 return true;
2622 }
2623
2624 static void bgp_route_select_timer_expire(struct event *thread)
2625 {
2626 struct afi_safi_info *info;
2627 afi_t afi;
2628 safi_t safi;
2629 struct bgp *bgp;
2630
2631 info = EVENT_ARG(thread);
2632 afi = info->afi;
2633 safi = info->safi;
2634 bgp = info->bgp;
2635
2636 bgp->gr_info[afi][safi].t_route_select = NULL;
2637 XFREE(MTYPE_TMP, info);
2638
2639 /* Best path selection */
2640 bgp_best_path_select_defer(bgp, afi, safi);
2641 }
2642
2643 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2644 struct bgp_maxpaths_cfg *mpath_cfg,
2645 struct bgp_path_info_pair *result, afi_t afi,
2646 safi_t safi)
2647 {
2648 struct bgp_path_info *new_select;
2649 struct bgp_path_info *old_select;
2650 struct bgp_path_info *pi;
2651 struct bgp_path_info *pi1;
2652 struct bgp_path_info *pi2;
2653 struct bgp_path_info *nextpi = NULL;
2654 int paths_eq, do_mpath, debug;
2655 struct list mp_list;
2656 char pfx_buf[PREFIX2STR_BUFFER];
2657 char path_buf[PATH_ADDPATH_STR_BUFFER];
2658
2659 bgp_mp_list_init(&mp_list);
2660 do_mpath =
2661 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2662
2663 debug = bgp_debug_bestpath(dest);
2664
2665 if (debug)
2666 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2667
2668 dest->reason = bgp_path_selection_none;
2669 /* bgp deterministic-med */
2670 new_select = NULL;
2671 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2672
2673 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2674 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2675 pi1 = pi1->next)
2676 bgp_path_info_unset_flag(dest, pi1,
2677 BGP_PATH_DMED_SELECTED);
2678
2679 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2680 pi1 = pi1->next) {
2681 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2682 continue;
2683 if (BGP_PATH_HOLDDOWN(pi1))
2684 continue;
2685 if (pi1->peer != bgp->peer_self &&
2686 !CHECK_FLAG(pi1->peer->sflags,
2687 PEER_STATUS_NSF_WAIT)) {
2688 if (!peer_established(pi1->peer))
2689 continue;
2690 }
2691
2692 new_select = pi1;
2693 if (pi1->next) {
2694 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2695 if (CHECK_FLAG(pi2->flags,
2696 BGP_PATH_DMED_CHECK))
2697 continue;
2698 if (BGP_PATH_HOLDDOWN(pi2))
2699 continue;
2700 if (pi2->peer != bgp->peer_self
2701 && !CHECK_FLAG(
2702 pi2->peer->sflags,
2703 PEER_STATUS_NSF_WAIT))
2704 if (pi2->peer->status
2705 != Established)
2706 continue;
2707
2708 if (!aspath_cmp_left(pi1->attr->aspath,
2709 pi2->attr->aspath)
2710 && !aspath_cmp_left_confed(
2711 pi1->attr->aspath,
2712 pi2->attr->aspath))
2713 continue;
2714
2715 if (bgp_path_info_cmp(
2716 bgp, pi2, new_select,
2717 &paths_eq, mpath_cfg, debug,
2718 pfx_buf, afi, safi,
2719 &dest->reason)) {
2720 bgp_path_info_unset_flag(
2721 dest, new_select,
2722 BGP_PATH_DMED_SELECTED);
2723 new_select = pi2;
2724 }
2725
2726 bgp_path_info_set_flag(
2727 dest, pi2, BGP_PATH_DMED_CHECK);
2728 }
2729 }
2730 bgp_path_info_set_flag(dest, new_select,
2731 BGP_PATH_DMED_CHECK);
2732 bgp_path_info_set_flag(dest, new_select,
2733 BGP_PATH_DMED_SELECTED);
2734
2735 if (debug) {
2736 bgp_path_info_path_with_addpath_rx_str(
2737 new_select, path_buf, sizeof(path_buf));
2738 zlog_debug(
2739 "%pBD(%s): %s is the bestpath from AS %u",
2740 dest, bgp->name_pretty, path_buf,
2741 aspath_get_first_as(
2742 new_select->attr->aspath));
2743 }
2744 }
2745 }
2746
2747 /* Check old selected route and new selected route. */
2748 old_select = NULL;
2749 new_select = NULL;
2750 for (pi = bgp_dest_get_bgp_path_info(dest);
2751 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2752 enum bgp_path_selection_reason reason;
2753
2754 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2755 old_select = pi;
2756
2757 if (BGP_PATH_HOLDDOWN(pi)) {
2758 /* reap REMOVED routes, if needs be
2759 * selected route must stay for a while longer though
2760 */
2761 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2762 && (pi != old_select))
2763 bgp_path_info_reap(dest, pi);
2764
2765 if (debug)
2766 zlog_debug(
2767 "%s: %pBD(%s) pi from %s in holddown",
2768 __func__, dest, bgp->name_pretty,
2769 pi->peer->host);
2770
2771 continue;
2772 }
2773
2774 if (pi->peer && pi->peer != bgp->peer_self
2775 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2776 if (!peer_established(pi->peer)) {
2777
2778 if (debug)
2779 zlog_debug(
2780 "%s: %pBD(%s) non self peer %s not estab state",
2781 __func__, dest,
2782 bgp->name_pretty,
2783 pi->peer->host);
2784
2785 continue;
2786 }
2787
2788 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2789 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2790 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2791 if (debug)
2792 zlog_debug("%s: %pBD(%s) pi %s dmed", __func__,
2793 dest, bgp->name_pretty,
2794 pi->peer->host);
2795 continue;
2796 }
2797
2798 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2799
2800 reason = dest->reason;
2801 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2802 debug, pfx_buf, afi, safi,
2803 &dest->reason)) {
2804 if (new_select == NULL &&
2805 reason != bgp_path_selection_none)
2806 dest->reason = reason;
2807 new_select = pi;
2808 }
2809 }
2810
2811 /* Now that we know which path is the bestpath see if any of the other
2812 * paths
2813 * qualify as multipaths
2814 */
2815 if (debug) {
2816 if (new_select)
2817 bgp_path_info_path_with_addpath_rx_str(
2818 new_select, path_buf, sizeof(path_buf));
2819 else
2820 snprintf(path_buf, sizeof(path_buf), "NONE");
2821 zlog_debug(
2822 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2823 dest, bgp->name_pretty, path_buf,
2824 old_select ? old_select->peer->host : "NONE");
2825 }
2826
2827 if (do_mpath && new_select) {
2828 for (pi = bgp_dest_get_bgp_path_info(dest);
2829 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2830
2831 if (debug)
2832 bgp_path_info_path_with_addpath_rx_str(
2833 pi, path_buf, sizeof(path_buf));
2834
2835 if (pi == new_select) {
2836 if (debug)
2837 zlog_debug(
2838 "%pBD(%s): %s is the bestpath, add to the multipath list",
2839 dest, bgp->name_pretty,
2840 path_buf);
2841 bgp_mp_list_add(&mp_list, pi);
2842 continue;
2843 }
2844
2845 if (BGP_PATH_HOLDDOWN(pi))
2846 continue;
2847
2848 if (pi->peer && pi->peer != bgp->peer_self
2849 && !CHECK_FLAG(pi->peer->sflags,
2850 PEER_STATUS_NSF_WAIT))
2851 if (!peer_established(pi->peer))
2852 continue;
2853
2854 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2855 if (debug)
2856 zlog_debug(
2857 "%pBD(%s): %s has the same nexthop as the bestpath, skip it",
2858 dest, bgp->name_pretty,
2859 path_buf);
2860 continue;
2861 }
2862
2863 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2864 mpath_cfg, debug, pfx_buf, afi, safi,
2865 &dest->reason);
2866
2867 if (paths_eq) {
2868 if (debug)
2869 zlog_debug(
2870 "%pBD(%s): %s is equivalent to the bestpath, add to the multipath list",
2871 dest, bgp->name_pretty,
2872 path_buf);
2873 bgp_mp_list_add(&mp_list, pi);
2874 }
2875 }
2876 }
2877
2878 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2879 mpath_cfg);
2880 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2881 bgp_mp_list_clear(&mp_list);
2882
2883 bgp_addpath_update_ids(bgp, dest, afi, safi);
2884
2885 result->old = old_select;
2886 result->new = new_select;
2887
2888 return;
2889 }
2890
2891 /*
2892 * A new route/change in bestpath of an existing route. Evaluate the path
2893 * for advertisement to the subgroup.
2894 */
2895 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2896 struct bgp_path_info *selected,
2897 struct bgp_dest *dest,
2898 uint32_t addpath_tx_id)
2899 {
2900 const struct prefix *p;
2901 struct peer *onlypeer;
2902 struct attr attr;
2903 afi_t afi;
2904 safi_t safi;
2905 struct bgp *bgp;
2906 bool advertise;
2907
2908 p = bgp_dest_get_prefix(dest);
2909 afi = SUBGRP_AFI(subgrp);
2910 safi = SUBGRP_SAFI(subgrp);
2911 bgp = SUBGRP_INST(subgrp);
2912 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2913 : NULL);
2914
2915 if (BGP_DEBUG(update, UPDATE_OUT))
2916 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2917
2918 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2919 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2920 PEER_STATUS_ORF_WAIT_REFRESH))
2921 return;
2922
2923 memset(&attr, 0, sizeof(attr));
2924 /* It's initialized in bgp_announce_check() */
2925
2926 /* Announcement to the subgroup. If the route is filtered withdraw it.
2927 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2928 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2929 * route
2930 */
2931 advertise = bgp_check_advertise(bgp, dest);
2932
2933 if (selected) {
2934 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2935 NULL)) {
2936 /* Route is selected, if the route is already installed
2937 * in FIB, then it is advertised
2938 */
2939 if (advertise) {
2940 if (!bgp_check_withdrawal(bgp, dest)) {
2941 struct attr *adv_attr =
2942 bgp_attr_intern(&attr);
2943
2944 bgp_adj_out_set_subgroup(dest, subgrp,
2945 adv_attr,
2946 selected);
2947 } else
2948 bgp_adj_out_unset_subgroup(
2949 dest, subgrp, 1, addpath_tx_id);
2950 }
2951 } else
2952 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2953 addpath_tx_id);
2954 }
2955
2956 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2957 else {
2958 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2959 }
2960 }
2961
2962 /*
2963 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2964 * This is called at the end of route processing.
2965 */
2966 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2967 {
2968 struct bgp_path_info *pi;
2969
2970 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2971 if (BGP_PATH_HOLDDOWN(pi))
2972 continue;
2973 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2974 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2975 }
2976 }
2977
2978 /*
2979 * Has the route changed from the RIB's perspective? This is invoked only
2980 * if the route selection returns the same best route as earlier - to
2981 * determine if we need to update zebra or not.
2982 */
2983 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2984 {
2985 struct bgp_path_info *mpinfo;
2986
2987 /* If this is multipath, check all selected paths for any nexthop
2988 * change or attribute change. Some attribute changes (e.g., community)
2989 * aren't of relevance to the RIB, but we'll update zebra to ensure
2990 * we handle the case of BGP nexthop change. This is the behavior
2991 * when the best path has an attribute change anyway.
2992 */
2993 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2994 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2995 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2996 return true;
2997
2998 /*
2999 * If this is multipath, check all selected paths for any nexthop change
3000 */
3001 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
3002 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3003 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3004 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3005 return true;
3006 }
3007
3008 /* Nothing has changed from the RIB's perspective. */
3009 return false;
3010 }
3011
3012 struct bgp_process_queue {
3013 struct bgp *bgp;
3014 STAILQ_HEAD(, bgp_dest) pqueue;
3015 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3016 unsigned int flags;
3017 unsigned int queued;
3018 };
3019
3020 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3021 safi_t safi, struct bgp_dest *dest,
3022 struct bgp_path_info *new_select,
3023 struct bgp_path_info *old_select)
3024 {
3025 const struct prefix *p = bgp_dest_get_prefix(dest);
3026
3027 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3028 return;
3029
3030 if (advertise_type5_routes(bgp, afi) && new_select
3031 && is_route_injectable_into_evpn(new_select)) {
3032
3033 /* apply the route-map */
3034 if (bgp->adv_cmd_rmap[afi][safi].map) {
3035 route_map_result_t ret;
3036 struct bgp_path_info rmap_path;
3037 struct bgp_path_info_extra rmap_path_extra;
3038 struct attr dummy_attr;
3039
3040 dummy_attr = *new_select->attr;
3041
3042 /* Fill temp path_info */
3043 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3044 new_select, new_select->peer,
3045 &dummy_attr);
3046
3047 RESET_FLAG(dummy_attr.rmap_change_flags);
3048
3049 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3050 p, &rmap_path);
3051
3052 if (ret == RMAP_DENYMATCH) {
3053 bgp_attr_flush(&dummy_attr);
3054 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3055 safi);
3056 } else
3057 bgp_evpn_advertise_type5_route(
3058 bgp, p, &dummy_attr, afi, safi);
3059 } else {
3060 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3061 afi, safi);
3062 }
3063 } else if (advertise_type5_routes(bgp, afi) && old_select
3064 && is_route_injectable_into_evpn(old_select))
3065 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3066 }
3067
3068 /*
3069 * Utility to determine whether a particular path_info should use
3070 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3071 * in a path where we basically _know_ this is a BGP-LU route.
3072 */
3073 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3074 {
3075 /* Certain types get imp null; so do paths where the nexthop is
3076 * not labeled.
3077 */
3078 if (new_select->sub_type == BGP_ROUTE_STATIC
3079 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3080 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3081 return true;
3082 else if (new_select->extra == NULL ||
3083 !bgp_is_valid_label(&new_select->extra->label[0]))
3084 /* TODO -- should be configurable? */
3085 return true;
3086 else
3087 return false;
3088 }
3089
3090 /*
3091 * old_select = The old best path
3092 * new_select = the new best path
3093 *
3094 * if (!old_select && new_select)
3095 * We are sending new information on.
3096 *
3097 * if (old_select && new_select) {
3098 * if (new_select != old_select)
3099 * We have a new best path send a change
3100 * else
3101 * We've received a update with new attributes that needs
3102 * to be passed on.
3103 * }
3104 *
3105 * if (old_select && !new_select)
3106 * We have no eligible route that we can announce or the rn
3107 * is being removed.
3108 */
3109 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3110 afi_t afi, safi_t safi)
3111 {
3112 struct bgp_path_info *new_select;
3113 struct bgp_path_info *old_select;
3114 struct bgp_path_info_pair old_and_new;
3115 int debug = 0;
3116
3117 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3118 if (dest)
3119 debug = bgp_debug_bestpath(dest);
3120 if (debug)
3121 zlog_debug(
3122 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3123 __func__, dest, bgp->name_pretty);
3124 return;
3125 }
3126 /* Is it end of initial update? (after startup) */
3127 if (!dest) {
3128 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3129 sizeof(bgp->update_delay_zebra_resume_time));
3130
3131 bgp->main_zebra_update_hold = 0;
3132 FOREACH_AFI_SAFI (afi, safi) {
3133 if (bgp_fibupd_safi(safi))
3134 bgp_zebra_announce_table(bgp, afi, safi);
3135 }
3136 bgp->main_peers_update_hold = 0;
3137
3138 bgp_start_routeadv(bgp);
3139 return;
3140 }
3141
3142 const struct prefix *p = bgp_dest_get_prefix(dest);
3143
3144 debug = bgp_debug_bestpath(dest);
3145 if (debug)
3146 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3147 dest, bgp->name_pretty, afi2str(afi),
3148 safi2str(safi));
3149
3150 /* The best path calculation for the route is deferred if
3151 * BGP_NODE_SELECT_DEFER is set
3152 */
3153 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3154 if (BGP_DEBUG(update, UPDATE_OUT))
3155 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3156 dest, bgp->name_pretty);
3157 return;
3158 }
3159
3160 /* Best path selection. */
3161 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3162 afi, safi);
3163 old_select = old_and_new.old;
3164 new_select = old_and_new.new;
3165
3166 /* Do we need to allocate or free labels?
3167 * Right now, since we only deal with per-prefix labels, it is not
3168 * necessary to do this upon changes to best path. Exceptions:
3169 * - label index has changed -> recalculate resulting label
3170 * - path_info sub_type changed -> switch to/from implicit-null
3171 * - no valid label (due to removed static label binding) -> get new one
3172 */
3173 if (bgp->allocate_mpls_labels[afi][safi]) {
3174 if (new_select) {
3175 if (!old_select
3176 || bgp_label_index_differs(new_select, old_select)
3177 || new_select->sub_type != old_select->sub_type
3178 || !bgp_is_valid_label(&dest->local_label)) {
3179 /* Enforced penultimate hop popping:
3180 * implicit-null for local routes, aggregate
3181 * and redistributed routes
3182 */
3183 if (bgp_lu_need_imp_null(new_select)) {
3184 if (CHECK_FLAG(
3185 dest->flags,
3186 BGP_NODE_REGISTERED_FOR_LABEL)
3187 || CHECK_FLAG(
3188 dest->flags,
3189 BGP_NODE_LABEL_REQUESTED))
3190 bgp_unregister_for_label(dest);
3191 dest->local_label = mpls_lse_encode(
3192 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3193 1);
3194 bgp_set_valid_label(&dest->local_label);
3195 } else
3196 bgp_register_for_label(dest,
3197 new_select);
3198 }
3199 } else if (CHECK_FLAG(dest->flags,
3200 BGP_NODE_REGISTERED_FOR_LABEL)
3201 || CHECK_FLAG(dest->flags,
3202 BGP_NODE_LABEL_REQUESTED)) {
3203 bgp_unregister_for_label(dest);
3204 }
3205 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3206 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3207 bgp_unregister_for_label(dest);
3208 }
3209
3210 if (debug)
3211 zlog_debug(
3212 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3213 __func__, dest, bgp->name_pretty, afi2str(afi),
3214 safi2str(safi), old_select, new_select);
3215
3216 /* If best route remains the same and this is not due to user-initiated
3217 * clear, see exactly what needs to be done.
3218 */
3219 if (old_select && old_select == new_select
3220 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3221 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3222 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3223 if (bgp_zebra_has_route_changed(old_select)) {
3224 #ifdef ENABLE_BGP_VNC
3225 vnc_import_bgp_add_route(bgp, p, old_select);
3226 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3227 #endif
3228 if (bgp_fibupd_safi(safi)
3229 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3230
3231 if (new_select->type == ZEBRA_ROUTE_BGP
3232 && (new_select->sub_type == BGP_ROUTE_NORMAL
3233 || new_select->sub_type
3234 == BGP_ROUTE_IMPORTED))
3235
3236 bgp_zebra_announce(dest, p, old_select,
3237 bgp, afi, safi);
3238 }
3239 }
3240
3241 /* If there is a change of interest to peers, reannounce the
3242 * route. */
3243 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3244 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3245 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3246 group_announce_route(bgp, afi, safi, dest, new_select);
3247
3248 /* unicast routes must also be annouced to
3249 * labeled-unicast update-groups */
3250 if (safi == SAFI_UNICAST)
3251 group_announce_route(bgp, afi,
3252 SAFI_LABELED_UNICAST, dest,
3253 new_select);
3254
3255 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3256 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3257 }
3258
3259 /* advertise/withdraw type-5 routes */
3260 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3261 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3262 bgp_process_evpn_route_injection(
3263 bgp, afi, safi, dest, old_select, old_select);
3264
3265 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3266 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3267 bgp_zebra_clear_route_change_flags(dest);
3268 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3269 return;
3270 }
3271
3272 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3273 */
3274 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3275
3276 /* bestpath has changed; bump version */
3277 if (old_select || new_select) {
3278 bgp_bump_version(dest);
3279
3280 if (!bgp->t_rmap_def_originate_eval) {
3281 bgp_lock(bgp);
3282 event_add_timer(
3283 bm->master,
3284 update_group_refresh_default_originate_route_map,
3285 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3286 &bgp->t_rmap_def_originate_eval);
3287 }
3288 }
3289
3290 if (old_select)
3291 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3292 if (new_select) {
3293 if (debug)
3294 zlog_debug("%s: setting SELECTED flag", __func__);
3295 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3296 bgp_path_info_unset_flag(dest, new_select,
3297 BGP_PATH_ATTR_CHANGED);
3298 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3299 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3300 }
3301
3302 #ifdef ENABLE_BGP_VNC
3303 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3304 if (old_select != new_select) {
3305 if (old_select) {
3306 vnc_import_bgp_exterior_del_route(bgp, p,
3307 old_select);
3308 vnc_import_bgp_del_route(bgp, p, old_select);
3309 }
3310 if (new_select) {
3311 vnc_import_bgp_exterior_add_route(bgp, p,
3312 new_select);
3313 vnc_import_bgp_add_route(bgp, p, new_select);
3314 }
3315 }
3316 }
3317 #endif
3318
3319 group_announce_route(bgp, afi, safi, dest, new_select);
3320
3321 /* unicast routes must also be annouced to labeled-unicast update-groups
3322 */
3323 if (safi == SAFI_UNICAST)
3324 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3325 new_select);
3326
3327 /* FIB update. */
3328 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3329 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3330
3331 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3332 && (new_select->sub_type == BGP_ROUTE_NORMAL
3333 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3334 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3335
3336 /* if this is an evpn imported type-5 prefix,
3337 * we need to withdraw the route first to clear
3338 * the nh neigh and the RMAC entry.
3339 */
3340 if (old_select &&
3341 is_route_parent_evpn(old_select))
3342 bgp_zebra_withdraw(p, old_select, bgp, safi);
3343
3344 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3345 } else {
3346 /* Withdraw the route from the kernel. */
3347 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3348 && (old_select->sub_type == BGP_ROUTE_NORMAL
3349 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3350 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3351
3352 bgp_zebra_withdraw(p, old_select, bgp, safi);
3353 }
3354 }
3355
3356 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3357 old_select);
3358
3359 /* Clear any route change flags. */
3360 bgp_zebra_clear_route_change_flags(dest);
3361
3362 /* Reap old select bgp_path_info, if it has been removed */
3363 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3364 bgp_path_info_reap(dest, old_select);
3365
3366 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3367 return;
3368 }
3369
3370 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3371 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3372 {
3373 struct bgp_dest *dest;
3374 int cnt = 0;
3375 struct afi_safi_info *thread_info;
3376
3377 if (bgp->gr_info[afi][safi].t_route_select) {
3378 struct event *t = bgp->gr_info[afi][safi].t_route_select;
3379
3380 thread_info = EVENT_ARG(t);
3381 XFREE(MTYPE_TMP, thread_info);
3382 EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
3383 }
3384
3385 if (BGP_DEBUG(update, UPDATE_OUT)) {
3386 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3387 get_afi_safi_str(afi, safi, false),
3388 bgp->gr_info[afi][safi].gr_deferred);
3389 }
3390
3391 /* Process the route list */
3392 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3393 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3394 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3395 dest = bgp_route_next(dest)) {
3396 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3397 continue;
3398
3399 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3400 bgp->gr_info[afi][safi].gr_deferred--;
3401 bgp_process_main_one(bgp, dest, afi, safi);
3402 cnt++;
3403 }
3404 /* If iteration stopped before the entire table was traversed then the
3405 * node needs to be unlocked.
3406 */
3407 if (dest) {
3408 bgp_dest_unlock_node(dest);
3409 dest = NULL;
3410 }
3411
3412 /* Send EOR message when all routes are processed */
3413 if (!bgp->gr_info[afi][safi].gr_deferred) {
3414 bgp_send_delayed_eor(bgp);
3415 /* Send route processing complete message to RIB */
3416 bgp_zebra_update(bgp, afi, safi,
3417 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3418 return;
3419 }
3420
3421 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3422
3423 thread_info->afi = afi;
3424 thread_info->safi = safi;
3425 thread_info->bgp = bgp;
3426
3427 /* If there are more routes to be processed, start the
3428 * selection timer
3429 */
3430 event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3431 BGP_ROUTE_SELECT_DELAY,
3432 &bgp->gr_info[afi][safi].t_route_select);
3433 }
3434
3435 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3436 {
3437 struct bgp_process_queue *pqnode = data;
3438 struct bgp *bgp = pqnode->bgp;
3439 struct bgp_table *table;
3440 struct bgp_dest *dest;
3441
3442 /* eoiu marker */
3443 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3444 bgp_process_main_one(bgp, NULL, 0, 0);
3445 /* should always have dedicated wq call */
3446 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3447 return WQ_SUCCESS;
3448 }
3449
3450 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3451 dest = STAILQ_FIRST(&pqnode->pqueue);
3452 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3453 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3454 table = bgp_dest_table(dest);
3455 /* note, new DESTs may be added as part of processing */
3456 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3457
3458 bgp_dest_unlock_node(dest);
3459 bgp_table_unlock(table);
3460 }
3461
3462 return WQ_SUCCESS;
3463 }
3464
3465 static void bgp_processq_del(struct work_queue *wq, void *data)
3466 {
3467 struct bgp_process_queue *pqnode = data;
3468
3469 bgp_unlock(pqnode->bgp);
3470
3471 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3472 }
3473
3474 void bgp_process_queue_init(struct bgp *bgp)
3475 {
3476 if (!bgp->process_queue) {
3477 char name[BUFSIZ];
3478
3479 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3480 bgp->process_queue = work_queue_new(bm->master, name);
3481 }
3482
3483 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3484 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3485 bgp->process_queue->spec.max_retries = 0;
3486 bgp->process_queue->spec.hold = 50;
3487 /* Use a higher yield value of 50ms for main queue processing */
3488 bgp->process_queue->spec.yield = 50 * 1000L;
3489 }
3490
3491 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3492 {
3493 struct bgp_process_queue *pqnode;
3494
3495 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3496 sizeof(struct bgp_process_queue));
3497
3498 /* unlocked in bgp_processq_del */
3499 pqnode->bgp = bgp_lock(bgp);
3500 STAILQ_INIT(&pqnode->pqueue);
3501
3502 return pqnode;
3503 }
3504
3505 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3506 {
3507 #define ARBITRARY_PROCESS_QLEN 10000
3508 struct work_queue *wq = bgp->process_queue;
3509 struct bgp_process_queue *pqnode;
3510 int pqnode_reuse = 0;
3511
3512 /* already scheduled for processing? */
3513 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3514 return;
3515
3516 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3517 * the workqueue
3518 */
3519 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3520 if (BGP_DEBUG(update, UPDATE_OUT))
3521 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3522 dest);
3523 return;
3524 }
3525
3526 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3527 if (BGP_DEBUG(update, UPDATE_OUT))
3528 zlog_debug(
3529 "Soft reconfigure table in progress for route %p",
3530 dest);
3531 return;
3532 }
3533
3534 if (wq == NULL)
3535 return;
3536
3537 /* Add route nodes to an existing work queue item until reaching the
3538 limit only if is from the same BGP view and it's not an EOIU marker
3539 */
3540 if (work_queue_item_count(wq)) {
3541 struct work_queue_item *item = work_queue_last_item(wq);
3542 pqnode = item->data;
3543
3544 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3545 || pqnode->bgp != bgp
3546 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3547 pqnode = bgp_processq_alloc(bgp);
3548 else
3549 pqnode_reuse = 1;
3550 } else
3551 pqnode = bgp_processq_alloc(bgp);
3552 /* all unlocked in bgp_process_wq */
3553 bgp_table_lock(bgp_dest_table(dest));
3554
3555 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3556 bgp_dest_lock_node(dest);
3557
3558 /* can't be enqueued twice */
3559 assert(STAILQ_NEXT(dest, pq) == NULL);
3560 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3561 pqnode->queued++;
3562
3563 if (!pqnode_reuse)
3564 work_queue_add(wq, pqnode);
3565
3566 return;
3567 }
3568
3569 void bgp_add_eoiu_mark(struct bgp *bgp)
3570 {
3571 struct bgp_process_queue *pqnode;
3572
3573 if (bgp->process_queue == NULL)
3574 return;
3575
3576 pqnode = bgp_processq_alloc(bgp);
3577
3578 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3579 work_queue_add(bgp->process_queue, pqnode);
3580 }
3581
3582 static void bgp_maximum_prefix_restart_timer(struct event *thread)
3583 {
3584 struct peer *peer;
3585
3586 peer = EVENT_ARG(thread);
3587 peer->t_pmax_restart = NULL;
3588
3589 if (bgp_debug_neighbor_events(peer))
3590 zlog_debug(
3591 "%s Maximum-prefix restart timer expired, restore peering",
3592 peer->host);
3593
3594 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3595 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3596 }
3597
3598 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3599 safi_t safi)
3600 {
3601 uint32_t count = 0;
3602 bool filtered = false;
3603 struct bgp_dest *dest;
3604 struct bgp_adj_in *ain;
3605 struct attr attr = {};
3606 struct bgp_table *table = peer->bgp->rib[afi][safi];
3607
3608 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3609 for (ain = dest->adj_in; ain; ain = ain->next) {
3610 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3611
3612 attr = *ain->attr;
3613
3614 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3615 == FILTER_DENY)
3616 filtered = true;
3617
3618 if (bgp_input_modifier(
3619 peer, rn_p, &attr, afi, safi,
3620 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3621 NULL, 0, NULL)
3622 == RMAP_DENY)
3623 filtered = true;
3624
3625 if (filtered)
3626 count++;
3627
3628 bgp_attr_flush(&attr);
3629 }
3630 }
3631
3632 return count;
3633 }
3634
3635 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3636 int always)
3637 {
3638 iana_afi_t pkt_afi;
3639 iana_safi_t pkt_safi;
3640 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3641 PEER_FLAG_MAX_PREFIX_FORCE))
3642 ? bgp_filtered_routes_count(peer, afi, safi)
3643 + peer->pcount[afi][safi]
3644 : peer->pcount[afi][safi];
3645
3646 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3647 return false;
3648
3649 if (pcount > peer->pmax[afi][safi]) {
3650 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3651 PEER_STATUS_PREFIX_LIMIT)
3652 && !always)
3653 return false;
3654
3655 zlog_info(
3656 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3657 get_afi_safi_str(afi, safi, false), peer, pcount,
3658 peer->pmax[afi][safi]);
3659 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3660
3661 if (CHECK_FLAG(peer->af_flags[afi][safi],
3662 PEER_FLAG_MAX_PREFIX_WARNING))
3663 return false;
3664
3665 /* Convert AFI, SAFI to values for packet. */
3666 pkt_afi = afi_int2iana(afi);
3667 pkt_safi = safi_int2iana(safi);
3668 {
3669 uint8_t ndata[7];
3670
3671 ndata[0] = (pkt_afi >> 8);
3672 ndata[1] = pkt_afi;
3673 ndata[2] = pkt_safi;
3674 ndata[3] = (peer->pmax[afi][safi] >> 24);
3675 ndata[4] = (peer->pmax[afi][safi] >> 16);
3676 ndata[5] = (peer->pmax[afi][safi] >> 8);
3677 ndata[6] = (peer->pmax[afi][safi]);
3678
3679 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3680 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3681 BGP_NOTIFY_CEASE_MAX_PREFIX,
3682 ndata, 7);
3683 }
3684
3685 /* Dynamic peers will just close their connection. */
3686 if (peer_dynamic_neighbor(peer))
3687 return true;
3688
3689 /* restart timer start */
3690 if (peer->pmax_restart[afi][safi]) {
3691 peer->v_pmax_restart =
3692 peer->pmax_restart[afi][safi] * 60;
3693
3694 if (bgp_debug_neighbor_events(peer))
3695 zlog_debug(
3696 "%pBP Maximum-prefix restart timer started for %d secs",
3697 peer, peer->v_pmax_restart);
3698
3699 BGP_TIMER_ON(peer->t_pmax_restart,
3700 bgp_maximum_prefix_restart_timer,
3701 peer->v_pmax_restart);
3702 }
3703
3704 return true;
3705 } else
3706 UNSET_FLAG(peer->af_sflags[afi][safi],
3707 PEER_STATUS_PREFIX_LIMIT);
3708
3709 if (pcount
3710 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3711 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3712 PEER_STATUS_PREFIX_THRESHOLD)
3713 && !always)
3714 return false;
3715
3716 zlog_info(
3717 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3718 get_afi_safi_str(afi, safi, false), peer, pcount,
3719 peer->pmax[afi][safi]);
3720 SET_FLAG(peer->af_sflags[afi][safi],
3721 PEER_STATUS_PREFIX_THRESHOLD);
3722 } else
3723 UNSET_FLAG(peer->af_sflags[afi][safi],
3724 PEER_STATUS_PREFIX_THRESHOLD);
3725 return false;
3726 }
3727
3728 /* Unconditionally remove the route from the RIB, without taking
3729 * damping into consideration (eg, because the session went down)
3730 */
3731 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3732 struct peer *peer, afi_t afi, safi_t safi)
3733 {
3734
3735 struct bgp *bgp = NULL;
3736 bool delete_route = false;
3737
3738 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3739 safi);
3740
3741 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3742 bgp_path_info_delete(dest, pi); /* keep historical info */
3743
3744 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3745 * flag
3746 */
3747 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3748 delete_route = true;
3749 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3750 delete_route = true;
3751 if (delete_route) {
3752 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3753 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3754 bgp = pi->peer->bgp;
3755 bgp->gr_info[afi][safi].gr_deferred--;
3756 }
3757 }
3758 }
3759
3760 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3761 bgp_process(peer->bgp, dest, afi, safi);
3762 }
3763
3764 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3765 struct peer *peer, afi_t afi, safi_t safi,
3766 struct prefix_rd *prd)
3767 {
3768 const struct prefix *p = bgp_dest_get_prefix(dest);
3769
3770 /* apply dampening, if result is suppressed, we'll be retaining
3771 * the bgp_path_info in the RIB for historical reference.
3772 */
3773 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3774 && peer->sort == BGP_PEER_EBGP)
3775 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3776 == BGP_DAMP_SUPPRESSED) {
3777 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3778 safi);
3779 return;
3780 }
3781
3782 #ifdef ENABLE_BGP_VNC
3783 if (safi == SAFI_MPLS_VPN) {
3784 struct bgp_dest *pdest = NULL;
3785 struct bgp_table *table = NULL;
3786
3787 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3788 (struct prefix *)prd);
3789 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3790 table = bgp_dest_get_bgp_table_info(pdest);
3791
3792 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3793 peer->bgp, prd, table, p, pi);
3794 }
3795 bgp_dest_unlock_node(pdest);
3796 }
3797 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3798 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3799
3800 vnc_import_bgp_del_route(peer->bgp, p, pi);
3801 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3802 }
3803 }
3804 #endif
3805
3806 /* If this is an EVPN route, process for un-import. */
3807 if (safi == SAFI_EVPN)
3808 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3809
3810 bgp_rib_remove(dest, pi, peer, afi, safi);
3811 }
3812
3813 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3814 struct peer *peer, struct attr *attr,
3815 struct bgp_dest *dest)
3816 {
3817 struct bgp_path_info *new;
3818
3819 /* Make new BGP info. */
3820 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3821 new->type = type;
3822 new->instance = instance;
3823 new->sub_type = sub_type;
3824 new->peer = peer;
3825 new->attr = attr;
3826 new->uptime = monotime(NULL);
3827 new->net = dest;
3828 return new;
3829 }
3830
3831 /* Check if received nexthop is valid or not. */
3832 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3833 uint8_t type, uint8_t stype, struct attr *attr,
3834 struct bgp_dest *dest)
3835 {
3836 bool ret = false;
3837 bool is_bgp_static_route =
3838 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3839 : false;
3840
3841 /* If `bgp allow-martian-nexthop` is turned on, return next-hop
3842 * as good.
3843 */
3844 if (bgp->allow_martian)
3845 return false;
3846
3847 /*
3848 * Only validated for unicast and multicast currently.
3849 * Also valid for EVPN where the nexthop is an IP address.
3850 * If we are a bgp static route being checked then there is
3851 * no need to check to see if the nexthop is martian as
3852 * that it should be ok.
3853 */
3854 if (is_bgp_static_route ||
3855 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3856 return false;
3857
3858 /* If NEXT_HOP is present, validate it. */
3859 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3860 if (attr->nexthop.s_addr == INADDR_ANY ||
3861 !ipv4_unicast_valid(&attr->nexthop) ||
3862 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3863 return true;
3864 }
3865
3866 /* If MP_NEXTHOP is present, validate it. */
3867 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3868 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3869 * it is not an IPv6 link-local address.
3870 *
3871 * If we receive an UPDATE with nexthop length set to 32 bytes
3872 * we shouldn't discard an UPDATE if it's set to (::).
3873 * The link-local (2st) is validated along the code path later.
3874 */
3875 if (attr->mp_nexthop_len) {
3876 switch (attr->mp_nexthop_len) {
3877 case BGP_ATTR_NHLEN_IPV4:
3878 case BGP_ATTR_NHLEN_VPNV4:
3879 ret = (attr->mp_nexthop_global_in.s_addr ==
3880 INADDR_ANY ||
3881 !ipv4_unicast_valid(
3882 &attr->mp_nexthop_global_in) ||
3883 bgp_nexthop_self(bgp, afi, type, stype, attr,
3884 dest));
3885 break;
3886
3887 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3888 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3889 ret = (IN6_IS_ADDR_UNSPECIFIED(
3890 &attr->mp_nexthop_global)
3891 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3892 || IN6_IS_ADDR_MULTICAST(
3893 &attr->mp_nexthop_global)
3894 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3895 dest));
3896 break;
3897 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3898 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3899 || IN6_IS_ADDR_MULTICAST(
3900 &attr->mp_nexthop_global)
3901 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3902 dest));
3903 break;
3904
3905 default:
3906 ret = true;
3907 break;
3908 }
3909 }
3910
3911 return ret;
3912 }
3913
3914 static void bgp_attr_add_no_export_community(struct attr *attr)
3915 {
3916 struct community *old;
3917 struct community *new;
3918 struct community *merge;
3919 struct community *no_export;
3920
3921 old = bgp_attr_get_community(attr);
3922 no_export = community_str2com("no-export");
3923
3924 assert(no_export);
3925
3926 if (old) {
3927 merge = community_merge(community_dup(old), no_export);
3928
3929 if (!old->refcnt)
3930 community_free(&old);
3931
3932 new = community_uniq_sort(merge);
3933 community_free(&merge);
3934 } else {
3935 new = community_dup(no_export);
3936 }
3937
3938 community_free(&no_export);
3939
3940 bgp_attr_set_community(attr, new);
3941 }
3942
3943 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3944 struct attr *attr, const struct prefix *prefix,
3945 int *sub_type)
3946 {
3947 struct listnode *node, *nnode;
3948 struct bgp *bgp;
3949 bool accept_own_found = false;
3950
3951 if (safi != SAFI_MPLS_VPN)
3952 return false;
3953
3954 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3955 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3956 return false;
3957
3958 /* The route in question carries the ACCEPT_OWN community */
3959 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3960 struct community *comm = bgp_attr_get_community(attr);
3961
3962 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3963 accept_own_found = true;
3964 }
3965
3966 /* The route in question is targeted to one or more destination VRFs
3967 * on the router (as determined by inspecting the Route Target(s)).
3968 */
3969 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3970 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3971 continue;
3972
3973 if (accept_own_found &&
3974 ecommunity_include(
3975 bgp->vpn_policy[afi]
3976 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3977 bgp_attr_get_ecommunity(attr))) {
3978 if (bgp_debug_update(peer, prefix, NULL, 1))
3979 zlog_debug(
3980 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3981 peer, prefix);
3982
3983 /* Treat this route as imported, because it's leaked
3984 * already from another VRF, and we got an updated
3985 * version from route-reflector with ACCEPT_OWN
3986 * community.
3987 */
3988 *sub_type = BGP_ROUTE_IMPORTED;
3989
3990 return true;
3991 }
3992 }
3993
3994 return false;
3995 }
3996
3997 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3998 struct attr *attr, afi_t afi, safi_t safi, int type,
3999 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4000 uint32_t num_labels, int soft_reconfig,
4001 struct bgp_route_evpn *evpn)
4002 {
4003 int ret;
4004 int aspath_loop_count = 0;
4005 struct bgp_dest *dest;
4006 struct bgp *bgp;
4007 struct attr new_attr;
4008 struct attr *attr_new;
4009 struct bgp_path_info *pi;
4010 struct bgp_path_info *new = NULL;
4011 struct bgp_path_info_extra *extra;
4012 const char *reason;
4013 char pfx_buf[BGP_PRD_PATH_STRLEN];
4014 int connected = 0;
4015 int do_loop_check = 1;
4016 int has_valid_label = 0;
4017 afi_t nh_afi;
4018 bool force_evpn_import = false;
4019 safi_t orig_safi = safi;
4020 bool leak_success = true;
4021 int allowas_in = 0;
4022
4023 if (frrtrace_enabled(frr_bgp, process_update)) {
4024 char pfxprint[PREFIX2STR_BUFFER];
4025
4026 prefix2str(p, pfxprint, sizeof(pfxprint));
4027 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4028 afi, safi, attr);
4029 }
4030
4031 #ifdef ENABLE_BGP_VNC
4032 int vnc_implicit_withdraw = 0;
4033 #endif
4034 int same_attr = 0;
4035 const struct prefix *bgp_nht_param_prefix;
4036
4037 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4038 if (orig_safi == SAFI_LABELED_UNICAST)
4039 safi = SAFI_UNICAST;
4040
4041 memset(&new_attr, 0, sizeof(new_attr));
4042 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4043 new_attr.label = MPLS_INVALID_LABEL;
4044
4045 bgp = peer->bgp;
4046 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4047 /* TODO: Check to see if we can get rid of "is_valid_label" */
4048 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4049 has_valid_label = (num_labels > 0) ? 1 : 0;
4050 else
4051 has_valid_label = bgp_is_valid_label(label);
4052
4053 if (has_valid_label)
4054 assert(label != NULL);
4055
4056 /* Update overlay index of the attribute */
4057 if (afi == AFI_L2VPN && evpn)
4058 memcpy(&attr->evpn_overlay, evpn,
4059 sizeof(struct bgp_route_evpn));
4060
4061 /* When peer's soft reconfiguration enabled. Record input packet in
4062 Adj-RIBs-In. */
4063 if (!soft_reconfig
4064 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4065 && peer != bgp->peer_self)
4066 bgp_adj_in_set(dest, peer, attr, addpath_id);
4067
4068 /* Update permitted loop count */
4069 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4070 allowas_in = peer->allowas_in[afi][safi];
4071
4072 /* Check previously received route. */
4073 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4074 if (pi->peer == peer && pi->type == type
4075 && pi->sub_type == sub_type
4076 && pi->addpath_rx_id == addpath_id)
4077 break;
4078
4079 /* AS path local-as loop check. */
4080 if (peer->change_local_as) {
4081 if (allowas_in)
4082 aspath_loop_count = allowas_in;
4083 else if (!CHECK_FLAG(peer->flags,
4084 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4085 aspath_loop_count = 1;
4086
4087 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4088 > aspath_loop_count) {
4089 peer->stat_pfx_aspath_loop++;
4090 reason = "as-path contains our own AS;";
4091 goto filtered;
4092 }
4093 }
4094
4095 /* If the peer is configured for "allowas-in origin" and the last ASN in
4096 * the
4097 * as-path is our ASN then we do not need to call aspath_loop_check
4098 */
4099 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4100 if (aspath_get_last_as(attr->aspath) == bgp->as)
4101 do_loop_check = 0;
4102
4103 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4104 bgp_nht_param_prefix = NULL;
4105 else
4106 bgp_nht_param_prefix = p;
4107
4108 /* AS path loop check. */
4109 if (do_loop_check) {
4110 if (aspath_loop_check(attr->aspath, bgp->as) >
4111 peer->allowas_in[afi][safi]) {
4112 peer->stat_pfx_aspath_loop++;
4113 reason = "as-path contains our own AS;";
4114 goto filtered;
4115 }
4116 }
4117
4118 /* If we're a CONFED we need to loop check the CONFED ID too */
4119 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4120 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4121 peer->allowas_in[afi][safi]) {
4122 peer->stat_pfx_aspath_loop++;
4123 reason = "as-path contains our own confed AS;";
4124 goto filtered;
4125 }
4126
4127 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4128 * enabled, then take care of that too.
4129 */
4130 bool accept_own = false;
4131
4132 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4133 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4134 accept_own =
4135 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4136 if (!accept_own) {
4137 peer->stat_pfx_originator_loop++;
4138 reason = "originator is us;";
4139 goto filtered;
4140 }
4141 }
4142
4143 /* Route reflector cluster ID check. */
4144 if (bgp_cluster_filter(peer, attr)) {
4145 peer->stat_pfx_cluster_loop++;
4146 reason = "reflected from the same cluster;";
4147 goto filtered;
4148 }
4149
4150 /* Apply incoming filter. */
4151 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4152 peer->stat_pfx_filter++;
4153 reason = "filter;";
4154 goto filtered;
4155 }
4156
4157 /* RFC 8212 to prevent route leaks.
4158 * This specification intends to improve this situation by requiring the
4159 * explicit configuration of both BGP Import and Export Policies for any
4160 * External BGP (EBGP) session such as customers, peers, or
4161 * confederation boundaries for all enabled address families. Through
4162 * codification of the aforementioned requirement, operators will
4163 * benefit from consistent behavior across different BGP
4164 * implementations.
4165 */
4166 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4167 if (!bgp_inbound_policy_exists(peer,
4168 &peer->filter[afi][safi])) {
4169 reason = "inbound policy missing";
4170 if (monotime_since(&bgp->ebgprequirespolicywarning,
4171 NULL) > FIFTEENMINUTE2USEC ||
4172 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4173 zlog_warn(
4174 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4175 monotime(&bgp->ebgprequirespolicywarning);
4176 }
4177 goto filtered;
4178 }
4179
4180 /* draft-ietf-idr-deprecate-as-set-confed-set
4181 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4182 * Eventually, This document (if approved) updates RFC 4271
4183 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4184 * and obsoletes RFC 6472.
4185 */
4186 if (peer->bgp->reject_as_sets)
4187 if (aspath_check_as_sets(attr->aspath)) {
4188 reason =
4189 "as-path contains AS_SET or AS_CONFED_SET type;";
4190 goto filtered;
4191 }
4192
4193 new_attr = *attr;
4194
4195 /* Apply incoming route-map.
4196 * NB: new_attr may now contain newly allocated values from route-map
4197 * "set"
4198 * commands, so we need bgp_attr_flush in the error paths, until we
4199 * intern
4200 * the attr (which takes over the memory references) */
4201 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4202 num_labels, dest)
4203 == RMAP_DENY) {
4204 peer->stat_pfx_filter++;
4205 reason = "route-map;";
4206 bgp_attr_flush(&new_attr);
4207 goto filtered;
4208 }
4209
4210 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4211 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4212 /* remove from RIB previous entry */
4213 bgp_zebra_withdraw(p, pi, bgp, safi);
4214 }
4215
4216 if (peer->sort == BGP_PEER_EBGP) {
4217
4218 /* rfc7999:
4219 * A BGP speaker receiving an announcement tagged with the
4220 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4221 * NO_EXPORT community as defined in RFC1997, or a
4222 * similar community, to prevent propagation of the
4223 * prefix outside the local AS. The community to prevent
4224 * propagation SHOULD be chosen according to the operator's
4225 * routing policy.
4226 */
4227 if (bgp_attr_get_community(&new_attr) &&
4228 community_include(bgp_attr_get_community(&new_attr),
4229 COMMUNITY_BLACKHOLE))
4230 bgp_attr_add_no_export_community(&new_attr);
4231
4232 /* If we receive the graceful-shutdown community from an eBGP
4233 * peer we must lower local-preference */
4234 if (bgp_attr_get_community(&new_attr) &&
4235 community_include(bgp_attr_get_community(&new_attr),
4236 COMMUNITY_GSHUT)) {
4237 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4238 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4239
4240 /* If graceful-shutdown is configured globally or
4241 * per neighbor, then add the GSHUT community to
4242 * all paths received from eBGP peers. */
4243 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4244 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4245 bgp_attr_add_gshut_community(&new_attr);
4246 }
4247
4248 /* next hop check. */
4249 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4250 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4251 &new_attr, dest)) {
4252 peer->stat_pfx_nh_invalid++;
4253 reason = "martian or self next-hop;";
4254 bgp_attr_flush(&new_attr);
4255 goto filtered;
4256 }
4257
4258 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4259 peer->stat_pfx_nh_invalid++;
4260 reason = "self mac;";
4261 bgp_attr_flush(&new_attr);
4262 goto filtered;
4263 }
4264
4265 if (bgp_check_role_applicability(afi, safi) &&
4266 bgp_otc_filter(peer, &new_attr)) {
4267 reason = "failing otc validation";
4268 bgp_attr_flush(&new_attr);
4269 goto filtered;
4270 }
4271
4272 /* If neighbor soo is configured, tag all incoming routes with
4273 * this SoO tag and then filter out advertisements in
4274 * subgroup_announce_check() if it matches the configured SoO
4275 * on the other peer.
4276 */
4277 if (peer->soo[afi][safi]) {
4278 struct ecommunity *old_ecomm =
4279 bgp_attr_get_ecommunity(&new_attr);
4280 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4281 struct ecommunity *new_ecomm;
4282
4283 if (old_ecomm) {
4284 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4285 ecomm_soo);
4286
4287 if (!old_ecomm->refcnt)
4288 ecommunity_free(&old_ecomm);
4289 } else {
4290 new_ecomm = ecommunity_dup(ecomm_soo);
4291 }
4292
4293 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4294 }
4295
4296 attr_new = bgp_attr_intern(&new_attr);
4297
4298 /* If the update is implicit withdraw. */
4299 if (pi) {
4300 pi->uptime = monotime(NULL);
4301 same_attr = attrhash_cmp(pi->attr, attr_new);
4302
4303 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4304
4305 /* Same attribute comes in. */
4306 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4307 && same_attr
4308 && (!has_valid_label
4309 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4310 num_labels * sizeof(mpls_label_t))
4311 == 0)) {
4312 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4313 BGP_CONFIG_DAMPENING)
4314 && peer->sort == BGP_PEER_EBGP
4315 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4316 if (bgp_debug_update(peer, p, NULL, 1)) {
4317 bgp_debug_rdpfxpath2str(
4318 afi, safi, prd, p, label,
4319 num_labels, addpath_id ? 1 : 0,
4320 addpath_id, evpn, pfx_buf,
4321 sizeof(pfx_buf));
4322 zlog_debug("%pBP rcvd %s", peer,
4323 pfx_buf);
4324 }
4325
4326 if (bgp_damp_update(pi, dest, afi, safi)
4327 != BGP_DAMP_SUPPRESSED) {
4328 bgp_aggregate_increment(bgp, p, pi, afi,
4329 safi);
4330 bgp_process(bgp, dest, afi, safi);
4331 }
4332 } else /* Duplicate - odd */
4333 {
4334 if (bgp_debug_update(peer, p, NULL, 1)) {
4335 if (!peer->rcvd_attr_printed) {
4336 zlog_debug(
4337 "%pBP rcvd UPDATE w/ attr: %s",
4338 peer,
4339 peer->rcvd_attr_str);
4340 peer->rcvd_attr_printed = 1;
4341 }
4342
4343 bgp_debug_rdpfxpath2str(
4344 afi, safi, prd, p, label,
4345 num_labels, addpath_id ? 1 : 0,
4346 addpath_id, evpn, pfx_buf,
4347 sizeof(pfx_buf));
4348 zlog_debug(
4349 "%pBP rcvd %s...duplicate ignored",
4350 peer, pfx_buf);
4351 }
4352
4353 /* graceful restart STALE flag unset. */
4354 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4355 bgp_path_info_unset_flag(
4356 dest, pi, BGP_PATH_STALE);
4357 bgp_dest_set_defer_flag(dest, false);
4358 bgp_process(bgp, dest, afi, safi);
4359 }
4360 }
4361
4362 bgp_dest_unlock_node(dest);
4363 bgp_attr_unintern(&attr_new);
4364
4365 return;
4366 }
4367
4368 /* Withdraw/Announce before we fully processed the withdraw */
4369 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4370 if (bgp_debug_update(peer, p, NULL, 1)) {
4371 bgp_debug_rdpfxpath2str(
4372 afi, safi, prd, p, label, num_labels,
4373 addpath_id ? 1 : 0, addpath_id, evpn,
4374 pfx_buf, sizeof(pfx_buf));
4375 zlog_debug(
4376 "%pBP rcvd %s, flapped quicker than processing",
4377 peer, pfx_buf);
4378 }
4379
4380 bgp_path_info_restore(dest, pi);
4381
4382 /*
4383 * If the BGP_PATH_REMOVED flag is set, then EVPN
4384 * routes would have been unimported already when a
4385 * prior BGP withdraw processing happened. Such routes
4386 * need to be imported again, so flag accordingly.
4387 */
4388 force_evpn_import = true;
4389 } else {
4390 /* implicit withdraw, decrement aggregate and pcount
4391 * here. only if update is accepted, they'll increment
4392 * below.
4393 */
4394 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4395 }
4396
4397 /* Received Logging. */
4398 if (bgp_debug_update(peer, p, NULL, 1)) {
4399 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4400 num_labels, addpath_id ? 1 : 0,
4401 addpath_id, evpn, pfx_buf,
4402 sizeof(pfx_buf));
4403 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4404 }
4405
4406 /* graceful restart STALE flag unset. */
4407 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4408 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4409 bgp_dest_set_defer_flag(dest, false);
4410 }
4411
4412 /* The attribute is changed. */
4413 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4414
4415 /* Update bgp route dampening information. */
4416 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4417 && peer->sort == BGP_PEER_EBGP) {
4418 /* This is implicit withdraw so we should update
4419 dampening
4420 information. */
4421 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4422 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4423 }
4424 #ifdef ENABLE_BGP_VNC
4425 if (safi == SAFI_MPLS_VPN) {
4426 struct bgp_dest *pdest = NULL;
4427 struct bgp_table *table = NULL;
4428
4429 pdest = bgp_node_get(bgp->rib[afi][safi],
4430 (struct prefix *)prd);
4431 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4432 table = bgp_dest_get_bgp_table_info(pdest);
4433
4434 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4435 bgp, prd, table, p, pi);
4436 }
4437 bgp_dest_unlock_node(pdest);
4438 }
4439 if ((afi == AFI_IP || afi == AFI_IP6)
4440 && (safi == SAFI_UNICAST)) {
4441 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4442 /*
4443 * Implicit withdraw case.
4444 */
4445 ++vnc_implicit_withdraw;
4446 vnc_import_bgp_del_route(bgp, p, pi);
4447 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4448 }
4449 }
4450 #endif
4451
4452 /* Special handling for EVPN update of an existing route. If the
4453 * extended community attribute has changed, we need to
4454 * un-import
4455 * the route using its existing extended community. It will be
4456 * subsequently processed for import with the new extended
4457 * community.
4458 */
4459 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4460 && !same_attr) {
4461 if ((pi->attr->flag
4462 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4463 && (attr_new->flag
4464 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4465 int cmp;
4466
4467 cmp = ecommunity_cmp(
4468 bgp_attr_get_ecommunity(pi->attr),
4469 bgp_attr_get_ecommunity(attr_new));
4470 if (!cmp) {
4471 if (bgp_debug_update(peer, p, NULL, 1))
4472 zlog_debug(
4473 "Change in EXT-COMM, existing %s new %s",
4474 ecommunity_str(
4475 bgp_attr_get_ecommunity(
4476 pi->attr)),
4477 ecommunity_str(
4478 bgp_attr_get_ecommunity(
4479 attr_new)));
4480 if (safi == SAFI_EVPN)
4481 bgp_evpn_unimport_route(
4482 bgp, afi, safi, p, pi);
4483 else /* SAFI_MPLS_VPN */
4484 vpn_leak_to_vrf_withdraw(pi);
4485 }
4486 }
4487 }
4488
4489 /* Update to new attribute. */
4490 bgp_attr_unintern(&pi->attr);
4491 pi->attr = attr_new;
4492
4493 /* Update MPLS label */
4494 if (has_valid_label) {
4495 extra = bgp_path_info_extra_get(pi);
4496 if (extra->label != label) {
4497 memcpy(&extra->label, label,
4498 num_labels * sizeof(mpls_label_t));
4499 extra->num_labels = num_labels;
4500 }
4501 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4502 bgp_set_valid_label(&extra->label[0]);
4503 }
4504
4505 /* Update SRv6 SID */
4506 if (attr->srv6_l3vpn) {
4507 extra = bgp_path_info_extra_get(pi);
4508 if (sid_diff(&extra->sid[0].sid,
4509 &attr->srv6_l3vpn->sid)) {
4510 sid_copy(&extra->sid[0].sid,
4511 &attr->srv6_l3vpn->sid);
4512 extra->num_sids = 1;
4513
4514 extra->sid[0].loc_block_len = 0;
4515 extra->sid[0].loc_node_len = 0;
4516 extra->sid[0].func_len = 0;
4517 extra->sid[0].arg_len = 0;
4518 extra->sid[0].transposition_len = 0;
4519 extra->sid[0].transposition_offset = 0;
4520
4521 if (attr->srv6_l3vpn->loc_block_len != 0) {
4522 extra->sid[0].loc_block_len =
4523 attr->srv6_l3vpn->loc_block_len;
4524 extra->sid[0].loc_node_len =
4525 attr->srv6_l3vpn->loc_node_len;
4526 extra->sid[0].func_len =
4527 attr->srv6_l3vpn->func_len;
4528 extra->sid[0].arg_len =
4529 attr->srv6_l3vpn->arg_len;
4530 extra->sid[0].transposition_len =
4531 attr->srv6_l3vpn
4532 ->transposition_len;
4533 extra->sid[0].transposition_offset =
4534 attr->srv6_l3vpn
4535 ->transposition_offset;
4536 }
4537 }
4538 } else if (attr->srv6_vpn) {
4539 extra = bgp_path_info_extra_get(pi);
4540 if (sid_diff(&extra->sid[0].sid,
4541 &attr->srv6_vpn->sid)) {
4542 sid_copy(&extra->sid[0].sid,
4543 &attr->srv6_vpn->sid);
4544 extra->num_sids = 1;
4545 }
4546 }
4547
4548 #ifdef ENABLE_BGP_VNC
4549 if ((afi == AFI_IP || afi == AFI_IP6)
4550 && (safi == SAFI_UNICAST)) {
4551 if (vnc_implicit_withdraw) {
4552 /*
4553 * Add back the route with its new attributes
4554 * (e.g., nexthop).
4555 * The route is still selected, until the route
4556 * selection
4557 * queued by bgp_process actually runs. We have
4558 * to make this
4559 * update to the VNC side immediately to avoid
4560 * racing against
4561 * configuration changes (e.g., route-map
4562 * changes) which
4563 * trigger re-importation of the entire RIB.
4564 */
4565 vnc_import_bgp_add_route(bgp, p, pi);
4566 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4567 }
4568 }
4569 #endif
4570
4571 /* Update bgp route dampening information. */
4572 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4573 && peer->sort == BGP_PEER_EBGP) {
4574 /* Now we do normal update dampening. */
4575 ret = bgp_damp_update(pi, dest, afi, safi);
4576 if (ret == BGP_DAMP_SUPPRESSED) {
4577 bgp_dest_unlock_node(dest);
4578 return;
4579 }
4580 }
4581
4582 /* Nexthop reachability check - for unicast and
4583 * labeled-unicast.. */
4584 if (((afi == AFI_IP || afi == AFI_IP6)
4585 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4586 || (safi == SAFI_EVPN &&
4587 bgp_evpn_is_prefix_nht_supported(p))) {
4588 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4589 && peer->ttl == BGP_DEFAULT_TTL
4590 && !CHECK_FLAG(peer->flags,
4591 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4592 && !CHECK_FLAG(bgp->flags,
4593 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4594 connected = 1;
4595 else
4596 connected = 0;
4597
4598 struct bgp *bgp_nexthop = bgp;
4599
4600 if (pi->extra && pi->extra->bgp_orig)
4601 bgp_nexthop = pi->extra->bgp_orig;
4602
4603 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4604
4605 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4606 safi, pi, NULL, connected,
4607 bgp_nht_param_prefix) ||
4608 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4609 bgp_path_info_set_flag(dest, pi,
4610 BGP_PATH_VALID);
4611 else {
4612 if (BGP_DEBUG(nht, NHT)) {
4613 zlog_debug("%s(%pI4): NH unresolved",
4614 __func__,
4615 (in_addr_t *)&attr_new->nexthop);
4616 }
4617 bgp_path_info_unset_flag(dest, pi,
4618 BGP_PATH_VALID);
4619 }
4620 } else {
4621 if (accept_own)
4622 bgp_path_info_set_flag(dest, pi,
4623 BGP_PATH_ACCEPT_OWN);
4624
4625 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4626 }
4627
4628 #ifdef ENABLE_BGP_VNC
4629 if (safi == SAFI_MPLS_VPN) {
4630 struct bgp_dest *pdest = NULL;
4631 struct bgp_table *table = NULL;
4632
4633 pdest = bgp_node_get(bgp->rib[afi][safi],
4634 (struct prefix *)prd);
4635 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4636 table = bgp_dest_get_bgp_table_info(pdest);
4637
4638 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4639 bgp, prd, table, p, pi);
4640 }
4641 bgp_dest_unlock_node(pdest);
4642 }
4643 #endif
4644
4645 /* If this is an EVPN route and some attribute has changed,
4646 * or we are explicitly told to perform a route import, process
4647 * route for import. If the extended community has changed, we
4648 * would
4649 * have done the un-import earlier and the import would result
4650 * in the
4651 * route getting injected into appropriate L2 VNIs. If it is
4652 * just
4653 * some other attribute change, the import will result in
4654 * updating
4655 * the attributes for the route in the VNI(s).
4656 */
4657 if (safi == SAFI_EVPN &&
4658 (!same_attr || force_evpn_import) &&
4659 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4660 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4661
4662 /* Process change. */
4663 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4664
4665 bgp_process(bgp, dest, afi, safi);
4666 bgp_dest_unlock_node(dest);
4667
4668 if (SAFI_UNICAST == safi
4669 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4670 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4671
4672 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4673 }
4674 if ((SAFI_MPLS_VPN == safi)
4675 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4676 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4677 }
4678
4679 #ifdef ENABLE_BGP_VNC
4680 if (SAFI_MPLS_VPN == safi) {
4681 mpls_label_t label_decoded = decode_label(label);
4682
4683 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4684 type, sub_type, &label_decoded);
4685 }
4686 if (SAFI_ENCAP == safi) {
4687 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4688 type, sub_type, NULL);
4689 }
4690 #endif
4691 if ((safi == SAFI_MPLS_VPN) &&
4692 !CHECK_FLAG(bgp->af_flags[afi][safi],
4693 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4694 !leak_success) {
4695 bgp_unlink_nexthop(pi);
4696 bgp_path_info_delete(dest, pi);
4697 }
4698 return;
4699 } // End of implicit withdraw
4700
4701 /* Received Logging. */
4702 if (bgp_debug_update(peer, p, NULL, 1)) {
4703 if (!peer->rcvd_attr_printed) {
4704 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4705 peer->rcvd_attr_str);
4706 peer->rcvd_attr_printed = 1;
4707 }
4708
4709 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4710 addpath_id ? 1 : 0, addpath_id, evpn,
4711 pfx_buf, sizeof(pfx_buf));
4712 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4713 }
4714
4715 /* Make new BGP info. */
4716 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4717
4718 /* Update MPLS label */
4719 if (has_valid_label) {
4720 extra = bgp_path_info_extra_get(new);
4721 if (extra->label != label) {
4722 memcpy(&extra->label, label,
4723 num_labels * sizeof(mpls_label_t));
4724 extra->num_labels = num_labels;
4725 }
4726 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4727 bgp_set_valid_label(&extra->label[0]);
4728 }
4729
4730 /* Update SRv6 SID */
4731 if (safi == SAFI_MPLS_VPN) {
4732 extra = bgp_path_info_extra_get(new);
4733 if (attr->srv6_l3vpn) {
4734 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4735 extra->num_sids = 1;
4736
4737 extra->sid[0].loc_block_len =
4738 attr->srv6_l3vpn->loc_block_len;
4739 extra->sid[0].loc_node_len =
4740 attr->srv6_l3vpn->loc_node_len;
4741 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4742 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4743 extra->sid[0].transposition_len =
4744 attr->srv6_l3vpn->transposition_len;
4745 extra->sid[0].transposition_offset =
4746 attr->srv6_l3vpn->transposition_offset;
4747 } else if (attr->srv6_vpn) {
4748 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4749 extra->num_sids = 1;
4750 }
4751 }
4752
4753 /* Nexthop reachability check. */
4754 if (((afi == AFI_IP || afi == AFI_IP6)
4755 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4756 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4757 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4758 && peer->ttl == BGP_DEFAULT_TTL
4759 && !CHECK_FLAG(peer->flags,
4760 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4761 && !CHECK_FLAG(bgp->flags,
4762 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4763 connected = 1;
4764 else
4765 connected = 0;
4766
4767 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4768
4769 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4770 connected, bgp_nht_param_prefix) ||
4771 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4772 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4773 else {
4774 if (BGP_DEBUG(nht, NHT))
4775 zlog_debug("%s(%pI4): NH unresolved", __func__,
4776 &attr_new->nexthop);
4777 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4778 }
4779 } else {
4780 if (accept_own)
4781 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4782
4783 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4784 }
4785
4786 /* If maximum prefix count is configured and current prefix
4787 * count exeed it.
4788 */
4789 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4790 reason = "maximum-prefix overflow";
4791 bgp_attr_flush(&new_attr);
4792 goto filtered;
4793 }
4794
4795 /* Addpath ID */
4796 new->addpath_rx_id = addpath_id;
4797
4798 /* Increment prefix */
4799 bgp_aggregate_increment(bgp, p, new, afi, safi);
4800
4801 /* Register new BGP information. */
4802 bgp_path_info_add(dest, new);
4803
4804 /* route_node_get lock */
4805 bgp_dest_unlock_node(dest);
4806
4807 #ifdef ENABLE_BGP_VNC
4808 if (safi == SAFI_MPLS_VPN) {
4809 struct bgp_dest *pdest = NULL;
4810 struct bgp_table *table = NULL;
4811
4812 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4813 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4814 table = bgp_dest_get_bgp_table_info(pdest);
4815
4816 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4817 bgp, prd, table, p, new);
4818 }
4819 bgp_dest_unlock_node(pdest);
4820 }
4821 #endif
4822
4823 /* If this is an EVPN route, process for import. */
4824 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4825 bgp_evpn_import_route(bgp, afi, safi, p, new);
4826
4827 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4828
4829 /* Process change. */
4830 bgp_process(bgp, dest, afi, safi);
4831
4832 if (SAFI_UNICAST == safi
4833 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4834 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4835 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4836 }
4837 if ((SAFI_MPLS_VPN == safi)
4838 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4839 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4840 }
4841 #ifdef ENABLE_BGP_VNC
4842 if (SAFI_MPLS_VPN == safi) {
4843 mpls_label_t label_decoded = decode_label(label);
4844
4845 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4846 sub_type, &label_decoded);
4847 }
4848 if (SAFI_ENCAP == safi) {
4849 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4850 sub_type, NULL);
4851 }
4852 #endif
4853 if ((safi == SAFI_MPLS_VPN) &&
4854 !CHECK_FLAG(bgp->af_flags[afi][safi],
4855 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4856 !leak_success) {
4857 bgp_unlink_nexthop(new);
4858 bgp_path_info_delete(dest, new);
4859 }
4860
4861 return;
4862
4863 /* This BGP update is filtered. Log the reason then update BGP
4864 entry. */
4865 filtered:
4866 if (new) {
4867 bgp_unlink_nexthop(new);
4868 bgp_path_info_delete(dest, new);
4869 bgp_path_info_extra_free(&new->extra);
4870 XFREE(MTYPE_BGP_ROUTE, new);
4871 }
4872
4873 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4874
4875 if (bgp_debug_update(peer, p, NULL, 1)) {
4876 if (!peer->rcvd_attr_printed) {
4877 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4878 peer->rcvd_attr_str);
4879 peer->rcvd_attr_printed = 1;
4880 }
4881
4882 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4883 addpath_id ? 1 : 0, addpath_id, evpn,
4884 pfx_buf, sizeof(pfx_buf));
4885 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4886 peer, pfx_buf, reason);
4887 }
4888
4889 if (pi) {
4890 /* If this is an EVPN route, un-import it as it is now filtered.
4891 */
4892 if (safi == SAFI_EVPN)
4893 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4894
4895 if (SAFI_UNICAST == safi
4896 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4897 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4898
4899 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4900 }
4901 if ((SAFI_MPLS_VPN == safi)
4902 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4903
4904 vpn_leak_to_vrf_withdraw(pi);
4905 }
4906
4907 bgp_rib_remove(dest, pi, peer, afi, safi);
4908 }
4909
4910 bgp_dest_unlock_node(dest);
4911
4912 #ifdef ENABLE_BGP_VNC
4913 /*
4914 * Filtered update is treated as an implicit withdrawal (see
4915 * bgp_rib_remove()
4916 * a few lines above)
4917 */
4918 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4919 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4920 0);
4921 }
4922 #endif
4923
4924 return;
4925 }
4926
4927 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4928 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4929 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4930 uint32_t num_labels, struct bgp_route_evpn *evpn)
4931 {
4932 struct bgp *bgp;
4933 char pfx_buf[BGP_PRD_PATH_STRLEN];
4934 struct bgp_dest *dest;
4935 struct bgp_path_info *pi;
4936
4937 #ifdef ENABLE_BGP_VNC
4938 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4939 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4940 0);
4941 }
4942 #endif
4943
4944 bgp = peer->bgp;
4945
4946 /* Lookup node. */
4947 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4948
4949 /* If peer is soft reconfiguration enabled. Record input packet for
4950 * further calculation.
4951 *
4952 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4953 * routes that are filtered. This tanks out Quagga RS pretty badly due
4954 * to
4955 * the iteration over all RS clients.
4956 * Since we need to remove the entry from adj_in anyway, do that first
4957 * and
4958 * if there was no entry, we don't need to do anything more.
4959 */
4960 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4961 && peer != bgp->peer_self)
4962 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4963 peer->stat_pfx_dup_withdraw++;
4964
4965 if (bgp_debug_update(peer, p, NULL, 1)) {
4966 bgp_debug_rdpfxpath2str(
4967 afi, safi, prd, p, label, num_labels,
4968 addpath_id ? 1 : 0, addpath_id, NULL,
4969 pfx_buf, sizeof(pfx_buf));
4970 zlog_debug(
4971 "%s withdrawing route %s not in adj-in",
4972 peer->host, pfx_buf);
4973 }
4974 bgp_dest_unlock_node(dest);
4975 return;
4976 }
4977
4978 /* Lookup withdrawn route. */
4979 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4980 if (pi->peer == peer && pi->type == type
4981 && pi->sub_type == sub_type
4982 && pi->addpath_rx_id == addpath_id)
4983 break;
4984
4985 /* Logging. */
4986 if (bgp_debug_update(peer, p, NULL, 1)) {
4987 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4988 addpath_id ? 1 : 0, addpath_id, NULL,
4989 pfx_buf, sizeof(pfx_buf));
4990 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4991 pfx_buf);
4992 }
4993
4994 /* Withdraw specified route from routing table. */
4995 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4996 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4997 if (SAFI_UNICAST == safi
4998 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4999 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5000 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5001 }
5002 if ((SAFI_MPLS_VPN == safi)
5003 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5004
5005 vpn_leak_to_vrf_withdraw(pi);
5006 }
5007 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5008 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5009 addpath_id ? 1 : 0, addpath_id, NULL,
5010 pfx_buf, sizeof(pfx_buf));
5011 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5012 }
5013
5014 /* Unlock bgp_node_get() lock. */
5015 bgp_dest_unlock_node(dest);
5016
5017 return;
5018 }
5019
5020 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5021 int withdraw)
5022 {
5023 struct update_subgroup *subgrp;
5024 subgrp = peer_subgroup(peer, afi, safi);
5025 subgroup_default_originate(subgrp, withdraw);
5026 }
5027
5028
5029 /*
5030 * bgp_stop_announce_route_timer
5031 */
5032 void bgp_stop_announce_route_timer(struct peer_af *paf)
5033 {
5034 if (!paf->t_announce_route)
5035 return;
5036
5037 EVENT_OFF(paf->t_announce_route);
5038 }
5039
5040 /*
5041 * bgp_announce_route_timer_expired
5042 *
5043 * Callback that is invoked when the route announcement timer for a
5044 * peer_af expires.
5045 */
5046 static void bgp_announce_route_timer_expired(struct event *t)
5047 {
5048 struct peer_af *paf;
5049 struct peer *peer;
5050
5051 paf = EVENT_ARG(t);
5052 peer = paf->peer;
5053
5054 if (!peer_established(peer))
5055 return;
5056
5057 if (!peer->afc_nego[paf->afi][paf->safi])
5058 return;
5059
5060 peer_af_announce_route(paf, 1);
5061
5062 /* Notify BGP conditional advertisement scanner percess */
5063 peer->advmap_config_change[paf->afi][paf->safi] = true;
5064 }
5065
5066 /*
5067 * bgp_announce_route
5068 *
5069 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5070 *
5071 * if force is true we will force an update even if the update
5072 * limiting code is attempted to kick in.
5073 */
5074 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5075 {
5076 struct peer_af *paf;
5077 struct update_subgroup *subgrp;
5078
5079 paf = peer_af_find(peer, afi, safi);
5080 if (!paf)
5081 return;
5082 subgrp = PAF_SUBGRP(paf);
5083
5084 /*
5085 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5086 * or a refresh has already been triggered.
5087 */
5088 if (!subgrp || paf->t_announce_route)
5089 return;
5090
5091 if (force)
5092 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5093
5094 /*
5095 * Start a timer to stagger/delay the announce. This serves
5096 * two purposes - announcement can potentially be combined for
5097 * multiple peers and the announcement doesn't happen in the
5098 * vty context.
5099 */
5100 event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5101 (subgrp->peer_count == 1)
5102 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5103 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5104 &paf->t_announce_route);
5105 }
5106
5107 /*
5108 * Announce routes from all AF tables to a peer.
5109 *
5110 * This should ONLY be called when there is a need to refresh the
5111 * routes to the peer based on a policy change for this peer alone
5112 * or a route refresh request received from the peer.
5113 * The operation will result in splitting the peer from its existing
5114 * subgroups and putting it in new subgroups.
5115 */
5116 void bgp_announce_route_all(struct peer *peer)
5117 {
5118 afi_t afi;
5119 safi_t safi;
5120
5121 FOREACH_AFI_SAFI (afi, safi)
5122 bgp_announce_route(peer, afi, safi, false);
5123 }
5124
5125 /* Flag or unflag bgp_dest to determine whether it should be treated by
5126 * bgp_soft_reconfig_table_task.
5127 * Flag if flag is true. Unflag if flag is false.
5128 */
5129 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5130 {
5131 struct bgp_dest *dest;
5132 struct bgp_adj_in *ain;
5133
5134 if (!table)
5135 return;
5136
5137 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5138 for (ain = dest->adj_in; ain; ain = ain->next) {
5139 if (ain->peer != NULL)
5140 break;
5141 }
5142 if (flag && ain != NULL && ain->peer != NULL)
5143 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5144 else
5145 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5146 }
5147 }
5148
5149 static void bgp_soft_reconfig_table_update(struct peer *peer,
5150 struct bgp_dest *dest,
5151 struct bgp_adj_in *ain, afi_t afi,
5152 safi_t safi, struct prefix_rd *prd)
5153 {
5154 struct bgp_path_info *pi;
5155 uint32_t num_labels = 0;
5156 mpls_label_t *label_pnt = NULL;
5157 struct bgp_route_evpn evpn;
5158
5159 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5160 if (pi->peer == peer)
5161 break;
5162
5163 if (pi && pi->extra)
5164 num_labels = pi->extra->num_labels;
5165 if (num_labels)
5166 label_pnt = &pi->extra->label[0];
5167 if (pi)
5168 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5169 sizeof(evpn));
5170 else
5171 memset(&evpn, 0, sizeof(evpn));
5172
5173 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5174 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5175 label_pnt, num_labels, 1, &evpn);
5176 }
5177
5178 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5179 struct bgp_table *table,
5180 struct prefix_rd *prd)
5181 {
5182 struct bgp_dest *dest;
5183 struct bgp_adj_in *ain;
5184
5185 if (!table)
5186 table = peer->bgp->rib[afi][safi];
5187
5188 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5189 for (ain = dest->adj_in; ain; ain = ain->next) {
5190 if (ain->peer != peer)
5191 continue;
5192
5193 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5194 safi, prd);
5195 }
5196 }
5197
5198 /* Do soft reconfig table per bgp table.
5199 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5200 * when BGP_NODE_SOFT_RECONFIG is set,
5201 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5202 * Schedule a new thread to continue the job.
5203 * Without splitting the full job into several part,
5204 * vtysh waits for the job to finish before responding to a BGP command
5205 */
5206 static void bgp_soft_reconfig_table_task(struct event *thread)
5207 {
5208 uint32_t iter, max_iter;
5209 struct bgp_dest *dest;
5210 struct bgp_adj_in *ain;
5211 struct peer *peer;
5212 struct bgp_table *table;
5213 struct prefix_rd *prd;
5214 struct listnode *node, *nnode;
5215
5216 table = EVENT_ARG(thread);
5217 prd = NULL;
5218
5219 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5220 if (table->soft_reconfig_init) {
5221 /* first call of the function with a new srta structure.
5222 * Don't do any treatment this time on nodes
5223 * in order vtysh to respond quickly
5224 */
5225 max_iter = 0;
5226 }
5227
5228 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5229 dest = bgp_route_next(dest)) {
5230 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5231 continue;
5232
5233 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5234
5235 for (ain = dest->adj_in; ain; ain = ain->next) {
5236 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5237 nnode, peer)) {
5238 if (ain->peer != peer)
5239 continue;
5240
5241 bgp_soft_reconfig_table_update(
5242 peer, dest, ain, table->afi,
5243 table->safi, prd);
5244 iter++;
5245 }
5246 }
5247 }
5248
5249 /* we're either starting the initial iteration,
5250 * or we're going to continue an ongoing iteration
5251 */
5252 if (dest || table->soft_reconfig_init) {
5253 table->soft_reconfig_init = false;
5254 event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
5255 0, &table->soft_reconfig_thread);
5256 return;
5257 }
5258 /* we're done, clean up the background iteration context info and
5259 schedule route annoucement
5260 */
5261 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5262 listnode_delete(table->soft_reconfig_peers, peer);
5263 bgp_announce_route(peer, table->afi, table->safi, false);
5264 }
5265
5266 list_delete(&table->soft_reconfig_peers);
5267 }
5268
5269
5270 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5271 * and peer.
5272 * - bgp cannot be NULL
5273 * - if table and peer are NULL, cancel all threads within the bgp instance
5274 * - if table is NULL and peer is not,
5275 * remove peer in all threads within the bgp instance
5276 * - if peer is NULL, cancel all threads matching table within the bgp instance
5277 */
5278 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5279 const struct bgp_table *table,
5280 const struct peer *peer)
5281 {
5282 struct peer *npeer;
5283 struct listnode *node, *nnode;
5284 int afi, safi;
5285 struct bgp_table *ntable;
5286
5287 if (!bgp)
5288 return;
5289
5290 FOREACH_AFI_SAFI (afi, safi) {
5291 ntable = bgp->rib[afi][safi];
5292 if (!ntable)
5293 continue;
5294 if (table && table != ntable)
5295 continue;
5296
5297 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5298 npeer)) {
5299 if (peer && peer != npeer)
5300 continue;
5301 listnode_delete(ntable->soft_reconfig_peers, npeer);
5302 }
5303
5304 if (!ntable->soft_reconfig_peers
5305 || !list_isempty(ntable->soft_reconfig_peers))
5306 continue;
5307
5308 list_delete(&ntable->soft_reconfig_peers);
5309 bgp_soft_reconfig_table_flag(ntable, false);
5310 EVENT_OFF(ntable->soft_reconfig_thread);
5311 }
5312 }
5313
5314 /*
5315 * Returns false if the peer is not configured for soft reconfig in
5316 */
5317 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5318 {
5319 struct bgp_dest *dest;
5320 struct bgp_table *table;
5321 struct listnode *node, *nnode;
5322 struct peer *npeer;
5323 struct peer_af *paf;
5324
5325 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5326 return false;
5327
5328 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5329 && (safi != SAFI_EVPN)) {
5330 table = peer->bgp->rib[afi][safi];
5331 if (!table)
5332 return true;
5333
5334 table->soft_reconfig_init = true;
5335
5336 if (!table->soft_reconfig_peers)
5337 table->soft_reconfig_peers = list_new();
5338 npeer = NULL;
5339 /* add peer to the table soft_reconfig_peers if not already
5340 * there
5341 */
5342 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5343 npeer)) {
5344 if (peer == npeer)
5345 break;
5346 }
5347 if (peer != npeer)
5348 listnode_add(table->soft_reconfig_peers, peer);
5349
5350 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5351 * on table would start back at the beginning.
5352 */
5353 bgp_soft_reconfig_table_flag(table, true);
5354
5355 if (!table->soft_reconfig_thread)
5356 event_add_event(bm->master,
5357 bgp_soft_reconfig_table_task, table, 0,
5358 &table->soft_reconfig_thread);
5359 /* Cancel bgp_announce_route_timer_expired threads.
5360 * bgp_announce_route_timer_expired threads have been scheduled
5361 * to announce routes as soon as the soft_reconfigure process
5362 * finishes.
5363 * In this case, soft_reconfigure is also scheduled by using
5364 * a thread but is planned after the
5365 * bgp_announce_route_timer_expired threads. It means that,
5366 * without cancelling the threads, the route announcement task
5367 * would run before the soft reconfiguration one. That would
5368 * useless and would block vtysh during several seconds. Route
5369 * announcements are rescheduled as soon as the soft_reconfigure
5370 * process finishes.
5371 */
5372 paf = peer_af_find(peer, afi, safi);
5373 if (paf)
5374 bgp_stop_announce_route_timer(paf);
5375 } else
5376 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5377 dest = bgp_route_next(dest)) {
5378 table = bgp_dest_get_bgp_table_info(dest);
5379
5380 if (table == NULL)
5381 continue;
5382
5383 const struct prefix *p = bgp_dest_get_prefix(dest);
5384 struct prefix_rd prd;
5385
5386 prd.family = AF_UNSPEC;
5387 prd.prefixlen = 64;
5388 memcpy(&prd.val, p->u.val, 8);
5389
5390 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5391 }
5392
5393 return true;
5394 }
5395
5396
5397 struct bgp_clear_node_queue {
5398 struct bgp_dest *dest;
5399 };
5400
5401 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5402 {
5403 struct bgp_clear_node_queue *cnq = data;
5404 struct bgp_dest *dest = cnq->dest;
5405 struct peer *peer = wq->spec.data;
5406 struct bgp_path_info *pi;
5407 struct bgp *bgp;
5408 afi_t afi = bgp_dest_table(dest)->afi;
5409 safi_t safi = bgp_dest_table(dest)->safi;
5410
5411 assert(dest && peer);
5412 bgp = peer->bgp;
5413
5414 /* It is possible that we have multiple paths for a prefix from a peer
5415 * if that peer is using AddPath.
5416 */
5417 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5418 if (pi->peer != peer)
5419 continue;
5420
5421 /* graceful restart STALE flag set. */
5422 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5423 && peer->nsf[afi][safi])
5424 || CHECK_FLAG(peer->af_sflags[afi][safi],
5425 PEER_STATUS_ENHANCED_REFRESH))
5426 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5427 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5428 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5429 else {
5430 /* If this is an EVPN route, process for
5431 * un-import. */
5432 if (safi == SAFI_EVPN)
5433 bgp_evpn_unimport_route(
5434 bgp, afi, safi,
5435 bgp_dest_get_prefix(dest), pi);
5436 /* Handle withdraw for VRF route-leaking and L3VPN */
5437 if (SAFI_UNICAST == safi
5438 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5439 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5440 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5441 bgp, pi);
5442 }
5443 if (SAFI_MPLS_VPN == safi &&
5444 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5445 vpn_leak_to_vrf_withdraw(pi);
5446 }
5447
5448 bgp_rib_remove(dest, pi, peer, afi, safi);
5449 }
5450 }
5451 return WQ_SUCCESS;
5452 }
5453
5454 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5455 {
5456 struct bgp_clear_node_queue *cnq = data;
5457 struct bgp_dest *dest = cnq->dest;
5458 struct bgp_table *table = bgp_dest_table(dest);
5459
5460 bgp_dest_unlock_node(dest);
5461 bgp_table_unlock(table);
5462 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5463 }
5464
5465 static void bgp_clear_node_complete(struct work_queue *wq)
5466 {
5467 struct peer *peer = wq->spec.data;
5468
5469 /* Tickle FSM to start moving again */
5470 BGP_EVENT_ADD(peer, Clearing_Completed);
5471
5472 peer_unlock(peer); /* bgp_clear_route */
5473 }
5474
5475 static void bgp_clear_node_queue_init(struct peer *peer)
5476 {
5477 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5478
5479 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5480 #undef CLEAR_QUEUE_NAME_LEN
5481
5482 peer->clear_node_queue = work_queue_new(bm->master, wname);
5483 peer->clear_node_queue->spec.hold = 10;
5484 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5485 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5486 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5487 peer->clear_node_queue->spec.max_retries = 0;
5488
5489 /* we only 'lock' this peer reference when the queue is actually active
5490 */
5491 peer->clear_node_queue->spec.data = peer;
5492 }
5493
5494 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5495 struct bgp_table *table)
5496 {
5497 struct bgp_dest *dest;
5498 int force = peer->bgp->process_queue ? 0 : 1;
5499
5500 if (!table)
5501 table = peer->bgp->rib[afi][safi];
5502
5503 /* If still no table => afi/safi isn't configured at all or smth. */
5504 if (!table)
5505 return;
5506
5507 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5508 struct bgp_path_info *pi, *next;
5509 struct bgp_adj_in *ain;
5510 struct bgp_adj_in *ain_next;
5511
5512 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5513 * queued for every clearing peer, regardless of whether it is
5514 * relevant to the peer at hand.
5515 *
5516 * Overview: There are 3 different indices which need to be
5517 * scrubbed, potentially, when a peer is removed:
5518 *
5519 * 1 peer's routes visible via the RIB (ie accepted routes)
5520 * 2 peer's routes visible by the (optional) peer's adj-in index
5521 * 3 other routes visible by the peer's adj-out index
5522 *
5523 * 3 there is no hurry in scrubbing, once the struct peer is
5524 * removed from bgp->peer, we could just GC such deleted peer's
5525 * adj-outs at our leisure.
5526 *
5527 * 1 and 2 must be 'scrubbed' in some way, at least made
5528 * invisible via RIB index before peer session is allowed to be
5529 * brought back up. So one needs to know when such a 'search' is
5530 * complete.
5531 *
5532 * Ideally:
5533 *
5534 * - there'd be a single global queue or a single RIB walker
5535 * - rather than tracking which route_nodes still need to be
5536 * examined on a peer basis, we'd track which peers still
5537 * aren't cleared
5538 *
5539 * Given that our per-peer prefix-counts now should be reliable,
5540 * this may actually be achievable. It doesn't seem to be a huge
5541 * problem at this time,
5542 *
5543 * It is possible that we have multiple paths for a prefix from
5544 * a peer
5545 * if that peer is using AddPath.
5546 */
5547 ain = dest->adj_in;
5548 while (ain) {
5549 ain_next = ain->next;
5550
5551 if (ain->peer == peer)
5552 bgp_adj_in_remove(dest, ain);
5553
5554 ain = ain_next;
5555 }
5556
5557 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5558 next = pi->next;
5559 if (pi->peer != peer)
5560 continue;
5561
5562 if (force)
5563 bgp_path_info_reap(dest, pi);
5564 else {
5565 struct bgp_clear_node_queue *cnq;
5566
5567 /* both unlocked in bgp_clear_node_queue_del */
5568 bgp_table_lock(bgp_dest_table(dest));
5569 bgp_dest_lock_node(dest);
5570 cnq = XCALLOC(
5571 MTYPE_BGP_CLEAR_NODE_QUEUE,
5572 sizeof(struct bgp_clear_node_queue));
5573 cnq->dest = dest;
5574 work_queue_add(peer->clear_node_queue, cnq);
5575 break;
5576 }
5577 }
5578 }
5579 return;
5580 }
5581
5582 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5583 {
5584 struct bgp_dest *dest;
5585 struct bgp_table *table;
5586
5587 if (peer->clear_node_queue == NULL)
5588 bgp_clear_node_queue_init(peer);
5589
5590 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5591 * Idle until it receives a Clearing_Completed event. This protects
5592 * against peers which flap faster than we can we clear, which could
5593 * lead to:
5594 *
5595 * a) race with routes from the new session being installed before
5596 * clear_route_node visits the node (to delete the route of that
5597 * peer)
5598 * b) resource exhaustion, clear_route_node likely leads to an entry
5599 * on the process_main queue. Fast-flapping could cause that queue
5600 * to grow and grow.
5601 */
5602
5603 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5604 * the unlock will happen upon work-queue completion; other wise, the
5605 * unlock happens at the end of this function.
5606 */
5607 if (!peer->clear_node_queue->thread)
5608 peer_lock(peer);
5609
5610 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5611 bgp_clear_route_table(peer, afi, safi, NULL);
5612 else
5613 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5614 dest = bgp_route_next(dest)) {
5615 table = bgp_dest_get_bgp_table_info(dest);
5616 if (!table)
5617 continue;
5618
5619 bgp_clear_route_table(peer, afi, safi, table);
5620 }
5621
5622 /* unlock if no nodes got added to the clear-node-queue. */
5623 if (!peer->clear_node_queue->thread)
5624 peer_unlock(peer);
5625 }
5626
5627 void bgp_clear_route_all(struct peer *peer)
5628 {
5629 afi_t afi;
5630 safi_t safi;
5631
5632 FOREACH_AFI_SAFI (afi, safi)
5633 bgp_clear_route(peer, afi, safi);
5634
5635 #ifdef ENABLE_BGP_VNC
5636 rfapiProcessPeerDown(peer);
5637 #endif
5638 }
5639
5640 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5641 {
5642 struct bgp_table *table;
5643 struct bgp_dest *dest;
5644 struct bgp_adj_in *ain;
5645 struct bgp_adj_in *ain_next;
5646
5647 table = peer->bgp->rib[afi][safi];
5648
5649 /* It is possible that we have multiple paths for a prefix from a peer
5650 * if that peer is using AddPath.
5651 */
5652 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5653 ain = dest->adj_in;
5654
5655 while (ain) {
5656 ain_next = ain->next;
5657
5658 if (ain->peer == peer)
5659 bgp_adj_in_remove(dest, ain);
5660
5661 ain = ain_next;
5662 }
5663 }
5664 }
5665
5666 /* If any of the routes from the peer have been marked with the NO_LLGR
5667 * community, either as sent by the peer, or as the result of a configured
5668 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5669 * operation of [RFC4271].
5670 */
5671 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5672 {
5673 struct bgp_dest *dest;
5674 struct bgp_path_info *pi;
5675 struct bgp_table *table;
5676
5677 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5678 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5679 dest = bgp_route_next(dest)) {
5680 struct bgp_dest *rm;
5681
5682 /* look for neighbor in tables */
5683 table = bgp_dest_get_bgp_table_info(dest);
5684 if (!table)
5685 continue;
5686
5687 for (rm = bgp_table_top(table); rm;
5688 rm = bgp_route_next(rm))
5689 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5690 pi = pi->next) {
5691 if (pi->peer != peer)
5692 continue;
5693 if (CHECK_FLAG(
5694 peer->af_sflags[afi][safi],
5695 PEER_STATUS_LLGR_WAIT) &&
5696 bgp_attr_get_community(pi->attr) &&
5697 !community_include(
5698 bgp_attr_get_community(
5699 pi->attr),
5700 COMMUNITY_NO_LLGR))
5701 continue;
5702 if (!CHECK_FLAG(pi->flags,
5703 BGP_PATH_STALE))
5704 continue;
5705
5706 /*
5707 * If this is VRF leaked route
5708 * process for withdraw.
5709 */
5710 if (pi->sub_type ==
5711 BGP_ROUTE_IMPORTED &&
5712 peer->bgp->inst_type ==
5713 BGP_INSTANCE_TYPE_DEFAULT)
5714 vpn_leak_to_vrf_withdraw(pi);
5715
5716 bgp_rib_remove(rm, pi, peer, afi, safi);
5717 break;
5718 }
5719 }
5720 } else {
5721 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5722 dest = bgp_route_next(dest))
5723 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5724 pi = pi->next) {
5725 if (pi->peer != peer)
5726 continue;
5727 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5728 PEER_STATUS_LLGR_WAIT) &&
5729 bgp_attr_get_community(pi->attr) &&
5730 !community_include(
5731 bgp_attr_get_community(pi->attr),
5732 COMMUNITY_NO_LLGR))
5733 continue;
5734 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5735 continue;
5736 if (safi == SAFI_UNICAST &&
5737 (peer->bgp->inst_type ==
5738 BGP_INSTANCE_TYPE_VRF ||
5739 peer->bgp->inst_type ==
5740 BGP_INSTANCE_TYPE_DEFAULT))
5741 vpn_leak_from_vrf_withdraw(
5742 bgp_get_default(), peer->bgp,
5743 pi);
5744
5745 bgp_rib_remove(dest, pi, peer, afi, safi);
5746 break;
5747 }
5748 }
5749 }
5750
5751 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5752 {
5753 struct bgp_dest *dest, *ndest;
5754 struct bgp_path_info *pi;
5755 struct bgp_table *table;
5756
5757 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5758 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5759 dest = bgp_route_next(dest)) {
5760 table = bgp_dest_get_bgp_table_info(dest);
5761 if (!table)
5762 continue;
5763
5764 for (ndest = bgp_table_top(table); ndest;
5765 ndest = bgp_route_next(ndest)) {
5766 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5767 pi = pi->next) {
5768 if (pi->peer != peer)
5769 continue;
5770
5771 if ((CHECK_FLAG(
5772 peer->af_sflags[afi][safi],
5773 PEER_STATUS_ENHANCED_REFRESH))
5774 && !CHECK_FLAG(pi->flags,
5775 BGP_PATH_STALE)
5776 && !CHECK_FLAG(
5777 pi->flags,
5778 BGP_PATH_UNUSEABLE)) {
5779 if (bgp_debug_neighbor_events(
5780 peer))
5781 zlog_debug(
5782 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5783 peer,
5784 afi2str(afi),
5785 safi2str(safi),
5786 bgp_dest_get_prefix(
5787 ndest));
5788
5789 bgp_path_info_set_flag(
5790 ndest, pi,
5791 BGP_PATH_STALE);
5792 }
5793 }
5794 }
5795 }
5796 } else {
5797 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5798 dest = bgp_route_next(dest)) {
5799 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5800 pi = pi->next) {
5801 if (pi->peer != peer)
5802 continue;
5803
5804 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5805 PEER_STATUS_ENHANCED_REFRESH))
5806 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5807 && !CHECK_FLAG(pi->flags,
5808 BGP_PATH_UNUSEABLE)) {
5809 if (bgp_debug_neighbor_events(peer))
5810 zlog_debug(
5811 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5812 peer, afi2str(afi),
5813 safi2str(safi),
5814 bgp_dest_get_prefix(
5815 dest));
5816
5817 bgp_path_info_set_flag(dest, pi,
5818 BGP_PATH_STALE);
5819 }
5820 }
5821 }
5822 }
5823 }
5824
5825 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5826 {
5827 if (peer->sort == BGP_PEER_IBGP)
5828 return true;
5829
5830 if (peer->sort == BGP_PEER_EBGP
5831 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5832 || FILTER_LIST_OUT_NAME(filter)
5833 || DISTRIBUTE_OUT_NAME(filter)))
5834 return true;
5835 return false;
5836 }
5837
5838 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5839 {
5840 if (peer->sort == BGP_PEER_IBGP)
5841 return true;
5842
5843 if (peer->sort == BGP_PEER_EBGP
5844 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5845 || FILTER_LIST_IN_NAME(filter)
5846 || DISTRIBUTE_IN_NAME(filter)))
5847 return true;
5848 return false;
5849 }
5850
5851 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5852 safi_t safi)
5853 {
5854 struct bgp_dest *dest;
5855 struct bgp_path_info *pi;
5856 struct bgp_path_info *next;
5857
5858 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5859 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5860 const struct prefix *p = bgp_dest_get_prefix(dest);
5861
5862 next = pi->next;
5863
5864 /* Unimport EVPN routes from VRFs */
5865 if (safi == SAFI_EVPN)
5866 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5867 SAFI_EVPN, p, pi);
5868
5869 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5870 && pi->type == ZEBRA_ROUTE_BGP
5871 && (pi->sub_type == BGP_ROUTE_NORMAL
5872 || pi->sub_type == BGP_ROUTE_AGGREGATE
5873 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5874
5875 if (bgp_fibupd_safi(safi))
5876 bgp_zebra_withdraw(p, pi, bgp, safi);
5877 }
5878
5879 bgp_path_info_reap(dest, pi);
5880 }
5881 }
5882
5883 /* Delete all kernel routes. */
5884 void bgp_cleanup_routes(struct bgp *bgp)
5885 {
5886 afi_t afi;
5887 struct bgp_dest *dest;
5888 struct bgp_table *table;
5889
5890 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5891 if (afi == AFI_L2VPN)
5892 continue;
5893 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5894 SAFI_UNICAST);
5895 /*
5896 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5897 */
5898 if (afi != AFI_L2VPN) {
5899 safi_t safi;
5900 safi = SAFI_MPLS_VPN;
5901 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5902 dest = bgp_route_next(dest)) {
5903 table = bgp_dest_get_bgp_table_info(dest);
5904 if (table != NULL) {
5905 bgp_cleanup_table(bgp, table, safi);
5906 bgp_table_finish(&table);
5907 bgp_dest_set_bgp_table_info(dest, NULL);
5908 bgp_dest_unlock_node(dest);
5909 }
5910 }
5911 safi = SAFI_ENCAP;
5912 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5913 dest = bgp_route_next(dest)) {
5914 table = bgp_dest_get_bgp_table_info(dest);
5915 if (table != NULL) {
5916 bgp_cleanup_table(bgp, table, safi);
5917 bgp_table_finish(&table);
5918 bgp_dest_set_bgp_table_info(dest, NULL);
5919 bgp_dest_unlock_node(dest);
5920 }
5921 }
5922 }
5923 }
5924 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5925 dest = bgp_route_next(dest)) {
5926 table = bgp_dest_get_bgp_table_info(dest);
5927 if (table != NULL) {
5928 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5929 bgp_table_finish(&table);
5930 bgp_dest_set_bgp_table_info(dest, NULL);
5931 bgp_dest_unlock_node(dest);
5932 }
5933 }
5934 }
5935
5936 void bgp_reset(void)
5937 {
5938 vty_reset();
5939 bgp_zclient_reset();
5940 access_list_reset();
5941 prefix_list_reset();
5942 }
5943
5944 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5945 {
5946 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5947 && CHECK_FLAG(peer->af_cap[afi][safi],
5948 PEER_CAP_ADDPATH_AF_TX_RCV));
5949 }
5950
5951 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5952 value. */
5953 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5954 struct bgp_nlri *packet)
5955 {
5956 uint8_t *pnt;
5957 uint8_t *lim;
5958 struct prefix p;
5959 int psize;
5960 afi_t afi;
5961 safi_t safi;
5962 bool addpath_capable;
5963 uint32_t addpath_id;
5964
5965 pnt = packet->nlri;
5966 lim = pnt + packet->length;
5967 afi = packet->afi;
5968 safi = packet->safi;
5969 addpath_id = 0;
5970 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5971
5972 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5973 syntactic validity. If the field is syntactically incorrect,
5974 then the Error Subcode is set to Invalid Network Field. */
5975 for (; pnt < lim; pnt += psize) {
5976 /* Clear prefix structure. */
5977 memset(&p, 0, sizeof(p));
5978
5979 if (addpath_capable) {
5980
5981 /* When packet overflow occurs return immediately. */
5982 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5983 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5984
5985 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5986 addpath_id = ntohl(addpath_id);
5987 pnt += BGP_ADDPATH_ID_LEN;
5988 }
5989
5990 /* Fetch prefix length. */
5991 p.prefixlen = *pnt++;
5992 /* afi/safi validity already verified by caller,
5993 * bgp_update_receive */
5994 p.family = afi2family(afi);
5995
5996 /* Prefix length check. */
5997 if (p.prefixlen > prefix_blen(&p) * 8) {
5998 flog_err(
5999 EC_BGP_UPDATE_RCV,
6000 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6001 peer->host, p.prefixlen, packet->afi);
6002 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6003 }
6004
6005 /* Packet size overflow check. */
6006 psize = PSIZE(p.prefixlen);
6007
6008 /* When packet overflow occur return immediately. */
6009 if (pnt + psize > lim) {
6010 flog_err(
6011 EC_BGP_UPDATE_RCV,
6012 "%s [Error] Update packet error (prefix length %d overflows packet)",
6013 peer->host, p.prefixlen);
6014 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6015 }
6016
6017 /* Defensive coding, double-check the psize fits in a struct
6018 * prefix for the v4 and v6 afi's and unicast/multicast */
6019 if (psize > (ssize_t)sizeof(p.u.val)) {
6020 flog_err(
6021 EC_BGP_UPDATE_RCV,
6022 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6023 peer->host, p.prefixlen, sizeof(p.u.val));
6024 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6025 }
6026
6027 /* Fetch prefix from NLRI packet. */
6028 memcpy(p.u.val, pnt, psize);
6029
6030 /* Check address. */
6031 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6032 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6033 /* From RFC4271 Section 6.3:
6034 *
6035 * If a prefix in the NLRI field is semantically
6036 * incorrect
6037 * (e.g., an unexpected multicast IP address),
6038 * an error SHOULD
6039 * be logged locally, and the prefix SHOULD be
6040 * ignored.
6041 */
6042 flog_err(
6043 EC_BGP_UPDATE_RCV,
6044 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6045 peer->host, &p.u.prefix4);
6046 continue;
6047 }
6048 }
6049
6050 /* Check address. */
6051 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6052 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6053 flog_err(
6054 EC_BGP_UPDATE_RCV,
6055 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6056 peer->host, &p.u.prefix6);
6057
6058 continue;
6059 }
6060 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6061 flog_err(
6062 EC_BGP_UPDATE_RCV,
6063 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6064 peer->host, &p.u.prefix6);
6065
6066 continue;
6067 }
6068 }
6069
6070 /* Normal process. */
6071 if (attr)
6072 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6073 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6074 NULL, 0, 0, NULL);
6075 else
6076 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6077 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6078 NULL, 0, NULL);
6079
6080 /* Do not send BGP notification twice when maximum-prefix count
6081 * overflow. */
6082 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6083 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6084 }
6085
6086 /* Packet length consistency check. */
6087 if (pnt != lim) {
6088 flog_err(
6089 EC_BGP_UPDATE_RCV,
6090 "%s [Error] Update packet error (prefix length mismatch with total length)",
6091 peer->host);
6092 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6093 }
6094
6095 return BGP_NLRI_PARSE_OK;
6096 }
6097
6098 static struct bgp_static *bgp_static_new(void)
6099 {
6100 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6101 }
6102
6103 static void bgp_static_free(struct bgp_static *bgp_static)
6104 {
6105 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6106 route_map_counter_decrement(bgp_static->rmap.map);
6107
6108 if (bgp_static->prd_pretty)
6109 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6110 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6111 XFREE(MTYPE_BGP_STATIC, bgp_static);
6112 }
6113
6114 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6115 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6116 {
6117 struct bgp_dest *dest;
6118 struct bgp_path_info *pi;
6119 struct bgp_path_info *new;
6120 struct bgp_path_info rmap_path;
6121 struct attr attr;
6122 struct attr *attr_new;
6123 route_map_result_t ret;
6124 #ifdef ENABLE_BGP_VNC
6125 int vnc_implicit_withdraw = 0;
6126 #endif
6127
6128 assert(bgp_static);
6129
6130 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6131
6132 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6133
6134 attr.nexthop = bgp_static->igpnexthop;
6135 attr.med = bgp_static->igpmetric;
6136 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6137
6138 if (afi == AFI_IP)
6139 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6140
6141 if (bgp_static->igpmetric)
6142 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6143
6144 if (bgp_static->atomic)
6145 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6146
6147 /* Store label index, if required. */
6148 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6149 attr.label_index = bgp_static->label_index;
6150 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6151 }
6152
6153 /* Apply route-map. */
6154 if (bgp_static->rmap.name) {
6155 struct attr attr_tmp = attr;
6156
6157 memset(&rmap_path, 0, sizeof(rmap_path));
6158 rmap_path.peer = bgp->peer_self;
6159 rmap_path.attr = &attr_tmp;
6160
6161 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6162
6163 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6164
6165 bgp->peer_self->rmap_type = 0;
6166
6167 if (ret == RMAP_DENYMATCH) {
6168 /* Free uninterned attribute. */
6169 bgp_attr_flush(&attr_tmp);
6170
6171 /* Unintern original. */
6172 aspath_unintern(&attr.aspath);
6173 bgp_static_withdraw(bgp, p, afi, safi);
6174 bgp_dest_unlock_node(dest);
6175 return;
6176 }
6177
6178 if (bgp_in_graceful_shutdown(bgp))
6179 bgp_attr_add_gshut_community(&attr_tmp);
6180
6181 attr_new = bgp_attr_intern(&attr_tmp);
6182 } else {
6183
6184 if (bgp_in_graceful_shutdown(bgp))
6185 bgp_attr_add_gshut_community(&attr);
6186
6187 attr_new = bgp_attr_intern(&attr);
6188 }
6189
6190 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6191 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6192 && pi->sub_type == BGP_ROUTE_STATIC)
6193 break;
6194
6195 if (pi) {
6196 if (attrhash_cmp(pi->attr, attr_new)
6197 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6198 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6199 bgp_dest_unlock_node(dest);
6200 bgp_attr_unintern(&attr_new);
6201 aspath_unintern(&attr.aspath);
6202 return;
6203 } else {
6204 /* The attribute is changed. */
6205 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6206
6207 /* Rewrite BGP route information. */
6208 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6209 bgp_path_info_restore(dest, pi);
6210 else
6211 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6212 #ifdef ENABLE_BGP_VNC
6213 if ((afi == AFI_IP || afi == AFI_IP6)
6214 && (safi == SAFI_UNICAST)) {
6215 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6216 /*
6217 * Implicit withdraw case.
6218 * We have to do this before pi is
6219 * changed
6220 */
6221 ++vnc_implicit_withdraw;
6222 vnc_import_bgp_del_route(bgp, p, pi);
6223 vnc_import_bgp_exterior_del_route(
6224 bgp, p, pi);
6225 }
6226 }
6227 #endif
6228 bgp_attr_unintern(&pi->attr);
6229 pi->attr = attr_new;
6230 pi->uptime = monotime(NULL);
6231 #ifdef ENABLE_BGP_VNC
6232 if ((afi == AFI_IP || afi == AFI_IP6)
6233 && (safi == SAFI_UNICAST)) {
6234 if (vnc_implicit_withdraw) {
6235 vnc_import_bgp_add_route(bgp, p, pi);
6236 vnc_import_bgp_exterior_add_route(
6237 bgp, p, pi);
6238 }
6239 }
6240 #endif
6241
6242 /* Nexthop reachability check. */
6243 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6244 && (safi == SAFI_UNICAST
6245 || safi == SAFI_LABELED_UNICAST)) {
6246
6247 struct bgp *bgp_nexthop = bgp;
6248
6249 if (pi->extra && pi->extra->bgp_orig)
6250 bgp_nexthop = pi->extra->bgp_orig;
6251
6252 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6253 afi, safi, pi, NULL,
6254 0, p))
6255 bgp_path_info_set_flag(dest, pi,
6256 BGP_PATH_VALID);
6257 else {
6258 if (BGP_DEBUG(nht, NHT)) {
6259 char buf1[INET6_ADDRSTRLEN];
6260 inet_ntop(p->family,
6261 &p->u.prefix, buf1,
6262 sizeof(buf1));
6263 zlog_debug(
6264 "%s(%s): Route not in table, not advertising",
6265 __func__, buf1);
6266 }
6267 bgp_path_info_unset_flag(
6268 dest, pi, BGP_PATH_VALID);
6269 }
6270 } else {
6271 /* Delete the NHT structure if any, if we're
6272 * toggling between
6273 * enabling/disabling import check. We
6274 * deregister the route
6275 * from NHT to avoid overloading NHT and the
6276 * process interaction
6277 */
6278 bgp_unlink_nexthop(pi);
6279 bgp_path_info_set_flag(dest, pi,
6280 BGP_PATH_VALID);
6281 }
6282 /* Process change. */
6283 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6284 bgp_process(bgp, dest, afi, safi);
6285
6286 if (SAFI_UNICAST == safi
6287 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6288 || bgp->inst_type
6289 == BGP_INSTANCE_TYPE_DEFAULT)) {
6290 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6291 pi);
6292 }
6293
6294 bgp_dest_unlock_node(dest);
6295 aspath_unintern(&attr.aspath);
6296 return;
6297 }
6298 }
6299
6300 /* Make new BGP info. */
6301 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6302 attr_new, dest);
6303 /* Nexthop reachability check. */
6304 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6305 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6306 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6307 p))
6308 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6309 else {
6310 if (BGP_DEBUG(nht, NHT)) {
6311 char buf1[INET6_ADDRSTRLEN];
6312
6313 inet_ntop(p->family, &p->u.prefix, buf1,
6314 sizeof(buf1));
6315 zlog_debug(
6316 "%s(%s): Route not in table, not advertising",
6317 __func__, buf1);
6318 }
6319 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6320 }
6321 } else {
6322 /* Delete the NHT structure if any, if we're toggling between
6323 * enabling/disabling import check. We deregister the route
6324 * from NHT to avoid overloading NHT and the process interaction
6325 */
6326 bgp_unlink_nexthop(new);
6327
6328 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6329 }
6330
6331 /* Aggregate address increment. */
6332 bgp_aggregate_increment(bgp, p, new, afi, safi);
6333
6334 /* Register new BGP information. */
6335 bgp_path_info_add(dest, new);
6336
6337 /* route_node_get lock */
6338 bgp_dest_unlock_node(dest);
6339
6340 /* Process change. */
6341 bgp_process(bgp, dest, afi, safi);
6342
6343 if (SAFI_UNICAST == safi
6344 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6345 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6346 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6347 }
6348
6349 /* Unintern original. */
6350 aspath_unintern(&attr.aspath);
6351 }
6352
6353 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6354 safi_t safi)
6355 {
6356 struct bgp_dest *dest;
6357 struct bgp_path_info *pi;
6358
6359 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6360
6361 /* Check selected route and self inserted route. */
6362 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6363 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6364 && pi->sub_type == BGP_ROUTE_STATIC)
6365 break;
6366
6367 /* Withdraw static BGP route from routing table. */
6368 if (pi) {
6369 if (SAFI_UNICAST == safi
6370 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6371 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6372 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6373 }
6374 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6375 bgp_unlink_nexthop(pi);
6376 bgp_path_info_delete(dest, pi);
6377 bgp_process(bgp, dest, afi, safi);
6378 }
6379
6380 /* Unlock bgp_node_lookup. */
6381 bgp_dest_unlock_node(dest);
6382 }
6383
6384 /*
6385 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6386 */
6387 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6388 afi_t afi, safi_t safi,
6389 struct prefix_rd *prd)
6390 {
6391 struct bgp_dest *dest;
6392 struct bgp_path_info *pi;
6393
6394 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6395
6396 /* Check selected route and self inserted route. */
6397 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6398 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6399 && pi->sub_type == BGP_ROUTE_STATIC)
6400 break;
6401
6402 /* Withdraw static BGP route from routing table. */
6403 if (pi) {
6404 #ifdef ENABLE_BGP_VNC
6405 rfapiProcessWithdraw(
6406 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6407 1); /* Kill, since it is an administrative change */
6408 #endif
6409 if (SAFI_MPLS_VPN == safi
6410 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6411 vpn_leak_to_vrf_withdraw(pi);
6412 }
6413 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6414 bgp_path_info_delete(dest, pi);
6415 bgp_process(bgp, dest, afi, safi);
6416 }
6417
6418 /* Unlock bgp_node_lookup. */
6419 bgp_dest_unlock_node(dest);
6420 }
6421
6422 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6423 struct bgp_static *bgp_static, afi_t afi,
6424 safi_t safi)
6425 {
6426 struct bgp_dest *dest;
6427 struct bgp_path_info *new;
6428 struct attr *attr_new;
6429 struct attr attr = {0};
6430 struct bgp_path_info *pi;
6431 #ifdef ENABLE_BGP_VNC
6432 mpls_label_t label = 0;
6433 #endif
6434 uint32_t num_labels = 0;
6435
6436 assert(bgp_static);
6437
6438 if (bgp_static->label != MPLS_INVALID_LABEL)
6439 num_labels = 1;
6440 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6441 &bgp_static->prd);
6442
6443 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6444
6445 attr.nexthop = bgp_static->igpnexthop;
6446 attr.med = bgp_static->igpmetric;
6447 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6448
6449 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6450 || (safi == SAFI_ENCAP)) {
6451 if (afi == AFI_IP) {
6452 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6453 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6454 }
6455 }
6456 if (afi == AFI_L2VPN) {
6457 if (bgp_static->gatewayIp.family == AF_INET) {
6458 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6459 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6460 &bgp_static->gatewayIp.u.prefix4,
6461 IPV4_MAX_BYTELEN);
6462 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6463 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6464 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6465 &bgp_static->gatewayIp.u.prefix6,
6466 IPV6_MAX_BYTELEN);
6467 }
6468 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6469 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6470 struct bgp_encap_type_vxlan bet;
6471 memset(&bet, 0, sizeof(bet));
6472 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6473 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6474 }
6475 if (bgp_static->router_mac) {
6476 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6477 }
6478 }
6479 /* Apply route-map. */
6480 if (bgp_static->rmap.name) {
6481 struct attr attr_tmp = attr;
6482 struct bgp_path_info rmap_path;
6483 route_map_result_t ret;
6484
6485 rmap_path.peer = bgp->peer_self;
6486 rmap_path.attr = &attr_tmp;
6487
6488 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6489
6490 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6491
6492 bgp->peer_self->rmap_type = 0;
6493
6494 if (ret == RMAP_DENYMATCH) {
6495 /* Free uninterned attribute. */
6496 bgp_attr_flush(&attr_tmp);
6497
6498 /* Unintern original. */
6499 aspath_unintern(&attr.aspath);
6500 bgp_static_withdraw_safi(bgp, p, afi, safi,
6501 &bgp_static->prd);
6502 bgp_dest_unlock_node(dest);
6503 return;
6504 }
6505
6506 attr_new = bgp_attr_intern(&attr_tmp);
6507 } else {
6508 attr_new = bgp_attr_intern(&attr);
6509 }
6510
6511 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6512 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6513 && pi->sub_type == BGP_ROUTE_STATIC)
6514 break;
6515
6516 if (pi) {
6517 if (attrhash_cmp(pi->attr, attr_new)
6518 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6519 bgp_dest_unlock_node(dest);
6520 bgp_attr_unintern(&attr_new);
6521 aspath_unintern(&attr.aspath);
6522 return;
6523 } else {
6524 /* The attribute is changed. */
6525 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6526
6527 /* Rewrite BGP route information. */
6528 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6529 bgp_path_info_restore(dest, pi);
6530 else
6531 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6532 bgp_attr_unintern(&pi->attr);
6533 pi->attr = attr_new;
6534 pi->uptime = monotime(NULL);
6535 #ifdef ENABLE_BGP_VNC
6536 if (pi->extra)
6537 label = decode_label(&pi->extra->label[0]);
6538 #endif
6539
6540 /* Process change. */
6541 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6542 bgp_process(bgp, dest, afi, safi);
6543
6544 if (SAFI_MPLS_VPN == safi
6545 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6546 vpn_leak_to_vrf_update(bgp, pi,
6547 &bgp_static->prd);
6548 }
6549 #ifdef ENABLE_BGP_VNC
6550 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6551 pi->attr, afi, safi, pi->type,
6552 pi->sub_type, &label);
6553 #endif
6554 bgp_dest_unlock_node(dest);
6555 aspath_unintern(&attr.aspath);
6556 return;
6557 }
6558 }
6559
6560
6561 /* Make new BGP info. */
6562 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6563 attr_new, dest);
6564 SET_FLAG(new->flags, BGP_PATH_VALID);
6565 bgp_path_info_extra_get(new);
6566 if (num_labels) {
6567 new->extra->label[0] = bgp_static->label;
6568 new->extra->num_labels = num_labels;
6569 }
6570 #ifdef ENABLE_BGP_VNC
6571 label = decode_label(&bgp_static->label);
6572 #endif
6573
6574 /* Aggregate address increment. */
6575 bgp_aggregate_increment(bgp, p, new, afi, safi);
6576
6577 /* Register new BGP information. */
6578 bgp_path_info_add(dest, new);
6579 /* route_node_get lock */
6580 bgp_dest_unlock_node(dest);
6581
6582 /* Process change. */
6583 bgp_process(bgp, dest, afi, safi);
6584
6585 if (SAFI_MPLS_VPN == safi
6586 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6587 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6588 }
6589 #ifdef ENABLE_BGP_VNC
6590 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6591 safi, new->type, new->sub_type, &label);
6592 #endif
6593
6594 /* Unintern original. */
6595 aspath_unintern(&attr.aspath);
6596 }
6597
6598 /* Configure static BGP network. When user don't run zebra, static
6599 route should be installed as valid. */
6600 static int bgp_static_set(struct vty *vty, const char *negate,
6601 const char *ip_str, afi_t afi, safi_t safi,
6602 const char *rmap, int backdoor, uint32_t label_index)
6603 {
6604 VTY_DECLVAR_CONTEXT(bgp, bgp);
6605 int ret;
6606 struct prefix p;
6607 struct bgp_static *bgp_static;
6608 struct bgp_dest *dest;
6609 uint8_t need_update = 0;
6610
6611 /* Convert IP prefix string to struct prefix. */
6612 ret = str2prefix(ip_str, &p);
6613 if (!ret) {
6614 vty_out(vty, "%% Malformed prefix\n");
6615 return CMD_WARNING_CONFIG_FAILED;
6616 }
6617 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6618 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6619 return CMD_WARNING_CONFIG_FAILED;
6620 }
6621
6622 apply_mask(&p);
6623
6624 if (negate) {
6625
6626 /* Set BGP static route configuration. */
6627 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6628
6629 if (!dest) {
6630 vty_out(vty, "%% Can't find static route specified\n");
6631 return CMD_WARNING_CONFIG_FAILED;
6632 }
6633
6634 bgp_static = bgp_dest_get_bgp_static_info(dest);
6635
6636 if ((label_index != BGP_INVALID_LABEL_INDEX)
6637 && (label_index != bgp_static->label_index)) {
6638 vty_out(vty,
6639 "%% label-index doesn't match static route\n");
6640 bgp_dest_unlock_node(dest);
6641 return CMD_WARNING_CONFIG_FAILED;
6642 }
6643
6644 if ((rmap && bgp_static->rmap.name)
6645 && strcmp(rmap, bgp_static->rmap.name)) {
6646 vty_out(vty,
6647 "%% route-map name doesn't match static route\n");
6648 bgp_dest_unlock_node(dest);
6649 return CMD_WARNING_CONFIG_FAILED;
6650 }
6651
6652 /* Update BGP RIB. */
6653 if (!bgp_static->backdoor)
6654 bgp_static_withdraw(bgp, &p, afi, safi);
6655
6656 /* Clear configuration. */
6657 bgp_static_free(bgp_static);
6658 bgp_dest_set_bgp_static_info(dest, NULL);
6659 bgp_dest_unlock_node(dest);
6660 bgp_dest_unlock_node(dest);
6661 } else {
6662
6663 /* Set BGP static route configuration. */
6664 dest = bgp_node_get(bgp->route[afi][safi], &p);
6665 bgp_static = bgp_dest_get_bgp_static_info(dest);
6666 if (bgp_static) {
6667 /* Configuration change. */
6668 /* Label index cannot be changed. */
6669 if (bgp_static->label_index != label_index) {
6670 vty_out(vty, "%% cannot change label-index\n");
6671 bgp_dest_unlock_node(dest);
6672 return CMD_WARNING_CONFIG_FAILED;
6673 }
6674
6675 /* Check previous routes are installed into BGP. */
6676 if (bgp_static->valid
6677 && bgp_static->backdoor != backdoor)
6678 need_update = 1;
6679
6680 bgp_static->backdoor = backdoor;
6681
6682 if (rmap) {
6683 XFREE(MTYPE_ROUTE_MAP_NAME,
6684 bgp_static->rmap.name);
6685 route_map_counter_decrement(
6686 bgp_static->rmap.map);
6687 bgp_static->rmap.name =
6688 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6689 bgp_static->rmap.map =
6690 route_map_lookup_by_name(rmap);
6691 route_map_counter_increment(
6692 bgp_static->rmap.map);
6693 } else {
6694 XFREE(MTYPE_ROUTE_MAP_NAME,
6695 bgp_static->rmap.name);
6696 route_map_counter_decrement(
6697 bgp_static->rmap.map);
6698 bgp_static->rmap.map = NULL;
6699 bgp_static->valid = 0;
6700 }
6701 bgp_dest_unlock_node(dest);
6702 } else {
6703 /* New configuration. */
6704 bgp_static = bgp_static_new();
6705 bgp_static->backdoor = backdoor;
6706 bgp_static->valid = 0;
6707 bgp_static->igpmetric = 0;
6708 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6709 bgp_static->label_index = label_index;
6710
6711 if (rmap) {
6712 XFREE(MTYPE_ROUTE_MAP_NAME,
6713 bgp_static->rmap.name);
6714 route_map_counter_decrement(
6715 bgp_static->rmap.map);
6716 bgp_static->rmap.name =
6717 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6718 bgp_static->rmap.map =
6719 route_map_lookup_by_name(rmap);
6720 route_map_counter_increment(
6721 bgp_static->rmap.map);
6722 }
6723 bgp_dest_set_bgp_static_info(dest, bgp_static);
6724 }
6725
6726 bgp_static->valid = 1;
6727 if (need_update)
6728 bgp_static_withdraw(bgp, &p, afi, safi);
6729
6730 if (!bgp_static->backdoor)
6731 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6732 }
6733
6734 return CMD_SUCCESS;
6735 }
6736
6737 void bgp_static_add(struct bgp *bgp)
6738 {
6739 afi_t afi;
6740 safi_t safi;
6741 struct bgp_dest *dest;
6742 struct bgp_dest *rm;
6743 struct bgp_table *table;
6744 struct bgp_static *bgp_static;
6745
6746 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6747 FOREACH_AFI_SAFI (afi, safi)
6748 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6749 dest = bgp_route_next(dest)) {
6750 if (!bgp_dest_has_bgp_path_info_data(dest))
6751 continue;
6752
6753 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6754 || (safi == SAFI_EVPN)) {
6755 table = bgp_dest_get_bgp_table_info(dest);
6756
6757 for (rm = bgp_table_top(table); rm;
6758 rm = bgp_route_next(rm)) {
6759 bgp_static =
6760 bgp_dest_get_bgp_static_info(
6761 rm);
6762 bgp_static_update_safi(
6763 bgp, bgp_dest_get_prefix(rm),
6764 bgp_static, afi, safi);
6765 }
6766 } else {
6767 bgp_static_update(
6768 bgp, bgp_dest_get_prefix(dest),
6769 bgp_dest_get_bgp_static_info(dest), afi,
6770 safi);
6771 }
6772 }
6773 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6774 }
6775
6776 /* Called from bgp_delete(). Delete all static routes from the BGP
6777 instance. */
6778 void bgp_static_delete(struct bgp *bgp)
6779 {
6780 afi_t afi;
6781 safi_t safi;
6782 struct bgp_dest *dest;
6783 struct bgp_dest *rm;
6784 struct bgp_table *table;
6785 struct bgp_static *bgp_static;
6786
6787 FOREACH_AFI_SAFI (afi, safi)
6788 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6789 dest = bgp_route_next(dest)) {
6790 if (!bgp_dest_has_bgp_path_info_data(dest))
6791 continue;
6792
6793 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6794 || (safi == SAFI_EVPN)) {
6795 table = bgp_dest_get_bgp_table_info(dest);
6796
6797 for (rm = bgp_table_top(table); rm;
6798 rm = bgp_route_next(rm)) {
6799 bgp_static =
6800 bgp_dest_get_bgp_static_info(
6801 rm);
6802 if (!bgp_static)
6803 continue;
6804
6805 bgp_static_withdraw_safi(
6806 bgp, bgp_dest_get_prefix(rm),
6807 AFI_IP, safi,
6808 (struct prefix_rd *)
6809 bgp_dest_get_prefix(
6810 dest));
6811 bgp_static_free(bgp_static);
6812 bgp_dest_set_bgp_static_info(rm,
6813 NULL);
6814 bgp_dest_unlock_node(rm);
6815 }
6816 } else {
6817 bgp_static = bgp_dest_get_bgp_static_info(dest);
6818 bgp_static_withdraw(bgp,
6819 bgp_dest_get_prefix(dest),
6820 afi, safi);
6821 bgp_static_free(bgp_static);
6822 bgp_dest_set_bgp_static_info(dest, NULL);
6823 bgp_dest_unlock_node(dest);
6824 }
6825 }
6826 }
6827
6828 void bgp_static_redo_import_check(struct bgp *bgp)
6829 {
6830 afi_t afi;
6831 safi_t safi;
6832 struct bgp_dest *dest;
6833 struct bgp_dest *rm;
6834 struct bgp_table *table;
6835 struct bgp_static *bgp_static;
6836
6837 /* Use this flag to force reprocessing of the route */
6838 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6839 FOREACH_AFI_SAFI (afi, safi) {
6840 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6841 dest = bgp_route_next(dest)) {
6842 if (!bgp_dest_has_bgp_path_info_data(dest))
6843 continue;
6844
6845 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6846 || (safi == SAFI_EVPN)) {
6847 table = bgp_dest_get_bgp_table_info(dest);
6848
6849 for (rm = bgp_table_top(table); rm;
6850 rm = bgp_route_next(rm)) {
6851 bgp_static =
6852 bgp_dest_get_bgp_static_info(
6853 rm);
6854 bgp_static_update_safi(
6855 bgp, bgp_dest_get_prefix(rm),
6856 bgp_static, afi, safi);
6857 }
6858 } else {
6859 bgp_static = bgp_dest_get_bgp_static_info(dest);
6860 bgp_static_update(bgp,
6861 bgp_dest_get_prefix(dest),
6862 bgp_static, afi, safi);
6863 }
6864 }
6865 }
6866 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6867 }
6868
6869 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6870 safi_t safi)
6871 {
6872 struct bgp_table *table;
6873 struct bgp_dest *dest;
6874 struct bgp_path_info *pi;
6875
6876 /* Do not install the aggregate route if BGP is in the
6877 * process of termination.
6878 */
6879 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6880 || (bgp->peer_self == NULL))
6881 return;
6882
6883 table = bgp->rib[afi][safi];
6884 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6885 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6886 if (pi->peer == bgp->peer_self
6887 && ((pi->type == ZEBRA_ROUTE_BGP
6888 && pi->sub_type == BGP_ROUTE_STATIC)
6889 || (pi->type != ZEBRA_ROUTE_BGP
6890 && pi->sub_type
6891 == BGP_ROUTE_REDISTRIBUTE))) {
6892 bgp_aggregate_decrement(
6893 bgp, bgp_dest_get_prefix(dest), pi, afi,
6894 safi);
6895 bgp_unlink_nexthop(pi);
6896 bgp_path_info_delete(dest, pi);
6897 bgp_process(bgp, dest, afi, safi);
6898 }
6899 }
6900 }
6901 }
6902
6903 /*
6904 * Purge all networks and redistributed routes from routing table.
6905 * Invoked upon the instance going down.
6906 */
6907 void bgp_purge_static_redist_routes(struct bgp *bgp)
6908 {
6909 afi_t afi;
6910 safi_t safi;
6911
6912 FOREACH_AFI_SAFI (afi, safi)
6913 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6914 }
6915
6916 /*
6917 * gpz 110624
6918 * Currently this is used to set static routes for VPN and ENCAP.
6919 * I think it can probably be factored with bgp_static_set.
6920 */
6921 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6922 const char *ip_str, const char *rd_str,
6923 const char *label_str, const char *rmap_str,
6924 int evpn_type, const char *esi, const char *gwip,
6925 const char *ethtag, const char *routermac)
6926 {
6927 VTY_DECLVAR_CONTEXT(bgp, bgp);
6928 int ret;
6929 struct prefix p;
6930 struct prefix_rd prd;
6931 struct bgp_dest *pdest;
6932 struct bgp_dest *dest;
6933 struct bgp_table *table;
6934 struct bgp_static *bgp_static;
6935 mpls_label_t label = MPLS_INVALID_LABEL;
6936 struct prefix gw_ip;
6937
6938 /* validate ip prefix */
6939 ret = str2prefix(ip_str, &p);
6940 if (!ret) {
6941 vty_out(vty, "%% Malformed prefix\n");
6942 return CMD_WARNING_CONFIG_FAILED;
6943 }
6944 apply_mask(&p);
6945 if ((afi == AFI_L2VPN)
6946 && (bgp_build_evpn_prefix(evpn_type,
6947 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6948 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6949 return CMD_WARNING_CONFIG_FAILED;
6950 }
6951
6952 ret = str2prefix_rd(rd_str, &prd);
6953 if (!ret) {
6954 vty_out(vty, "%% Malformed rd\n");
6955 return CMD_WARNING_CONFIG_FAILED;
6956 }
6957
6958 if (label_str) {
6959 unsigned long label_val;
6960 label_val = strtoul(label_str, NULL, 10);
6961 encode_label(label_val, &label);
6962 }
6963
6964 if (safi == SAFI_EVPN) {
6965 if (esi && str2esi(esi, NULL) == 0) {
6966 vty_out(vty, "%% Malformed ESI\n");
6967 return CMD_WARNING_CONFIG_FAILED;
6968 }
6969 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6970 vty_out(vty, "%% Malformed Router MAC\n");
6971 return CMD_WARNING_CONFIG_FAILED;
6972 }
6973 if (gwip) {
6974 memset(&gw_ip, 0, sizeof(gw_ip));
6975 ret = str2prefix(gwip, &gw_ip);
6976 if (!ret) {
6977 vty_out(vty, "%% Malformed GatewayIp\n");
6978 return CMD_WARNING_CONFIG_FAILED;
6979 }
6980 if ((gw_ip.family == AF_INET
6981 && is_evpn_prefix_ipaddr_v6(
6982 (struct prefix_evpn *)&p))
6983 || (gw_ip.family == AF_INET6
6984 && is_evpn_prefix_ipaddr_v4(
6985 (struct prefix_evpn *)&p))) {
6986 vty_out(vty,
6987 "%% GatewayIp family differs with IP prefix\n");
6988 return CMD_WARNING_CONFIG_FAILED;
6989 }
6990 }
6991 }
6992 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6993 if (!bgp_dest_has_bgp_path_info_data(pdest))
6994 bgp_dest_set_bgp_table_info(pdest,
6995 bgp_table_init(bgp, afi, safi));
6996 table = bgp_dest_get_bgp_table_info(pdest);
6997
6998 dest = bgp_node_get(table, &p);
6999
7000 if (bgp_dest_has_bgp_path_info_data(dest)) {
7001 vty_out(vty, "%% Same network configuration exists\n");
7002 bgp_dest_unlock_node(dest);
7003 } else {
7004 /* New configuration. */
7005 bgp_static = bgp_static_new();
7006 bgp_static->backdoor = 0;
7007 bgp_static->valid = 0;
7008 bgp_static->igpmetric = 0;
7009 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7010 bgp_static->label = label;
7011 bgp_static->prd = prd;
7012
7013 if (rd_str)
7014 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
7015 if (rmap_str) {
7016 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7017 route_map_counter_decrement(bgp_static->rmap.map);
7018 bgp_static->rmap.name =
7019 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7020 bgp_static->rmap.map =
7021 route_map_lookup_by_name(rmap_str);
7022 route_map_counter_increment(bgp_static->rmap.map);
7023 }
7024
7025 if (safi == SAFI_EVPN) {
7026 if (esi) {
7027 bgp_static->eth_s_id =
7028 XCALLOC(MTYPE_ATTR,
7029 sizeof(esi_t));
7030 str2esi(esi, bgp_static->eth_s_id);
7031 }
7032 if (routermac) {
7033 bgp_static->router_mac =
7034 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7035 (void)prefix_str2mac(routermac,
7036 bgp_static->router_mac);
7037 }
7038 if (gwip)
7039 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7040 }
7041 bgp_dest_set_bgp_static_info(dest, bgp_static);
7042
7043 bgp_static->valid = 1;
7044 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7045 }
7046
7047 return CMD_SUCCESS;
7048 }
7049
7050 /* Configure static BGP network. */
7051 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7052 const char *ip_str, const char *rd_str,
7053 const char *label_str, int evpn_type, const char *esi,
7054 const char *gwip, const char *ethtag)
7055 {
7056 VTY_DECLVAR_CONTEXT(bgp, bgp);
7057 int ret;
7058 struct prefix p;
7059 struct prefix_rd prd;
7060 struct bgp_dest *pdest;
7061 struct bgp_dest *dest;
7062 struct bgp_table *table;
7063 struct bgp_static *bgp_static;
7064 mpls_label_t label = MPLS_INVALID_LABEL;
7065
7066 /* Convert IP prefix string to struct prefix. */
7067 ret = str2prefix(ip_str, &p);
7068 if (!ret) {
7069 vty_out(vty, "%% Malformed prefix\n");
7070 return CMD_WARNING_CONFIG_FAILED;
7071 }
7072 apply_mask(&p);
7073 if ((afi == AFI_L2VPN)
7074 && (bgp_build_evpn_prefix(evpn_type,
7075 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7076 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7077 return CMD_WARNING_CONFIG_FAILED;
7078 }
7079 ret = str2prefix_rd(rd_str, &prd);
7080 if (!ret) {
7081 vty_out(vty, "%% Malformed rd\n");
7082 return CMD_WARNING_CONFIG_FAILED;
7083 }
7084
7085 if (label_str) {
7086 unsigned long label_val;
7087 label_val = strtoul(label_str, NULL, 10);
7088 encode_label(label_val, &label);
7089 }
7090
7091 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7092 if (!bgp_dest_has_bgp_path_info_data(pdest))
7093 bgp_dest_set_bgp_table_info(pdest,
7094 bgp_table_init(bgp, afi, safi));
7095 else
7096 bgp_dest_unlock_node(pdest);
7097 table = bgp_dest_get_bgp_table_info(pdest);
7098
7099 dest = bgp_node_lookup(table, &p);
7100
7101 if (dest) {
7102 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7103
7104 bgp_static = bgp_dest_get_bgp_static_info(dest);
7105 bgp_static_free(bgp_static);
7106 bgp_dest_set_bgp_static_info(dest, NULL);
7107 bgp_dest_unlock_node(dest);
7108 bgp_dest_unlock_node(dest);
7109 } else
7110 vty_out(vty, "%% Can't find the route\n");
7111
7112 return CMD_SUCCESS;
7113 }
7114
7115 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7116 const char *rmap_name)
7117 {
7118 VTY_DECLVAR_CONTEXT(bgp, bgp);
7119 struct bgp_rmap *rmap;
7120
7121 rmap = &bgp->table_map[afi][safi];
7122 if (rmap_name) {
7123 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7124 route_map_counter_decrement(rmap->map);
7125 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7126 rmap->map = route_map_lookup_by_name(rmap_name);
7127 route_map_counter_increment(rmap->map);
7128 } else {
7129 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7130 route_map_counter_decrement(rmap->map);
7131 rmap->map = NULL;
7132 }
7133
7134 if (bgp_fibupd_safi(safi))
7135 bgp_zebra_announce_table(bgp, afi, safi);
7136
7137 return CMD_SUCCESS;
7138 }
7139
7140 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7141 const char *rmap_name)
7142 {
7143 VTY_DECLVAR_CONTEXT(bgp, bgp);
7144 struct bgp_rmap *rmap;
7145
7146 rmap = &bgp->table_map[afi][safi];
7147 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7148 route_map_counter_decrement(rmap->map);
7149 rmap->map = NULL;
7150
7151 if (bgp_fibupd_safi(safi))
7152 bgp_zebra_announce_table(bgp, afi, safi);
7153
7154 return CMD_SUCCESS;
7155 }
7156
7157 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7158 safi_t safi)
7159 {
7160 if (bgp->table_map[afi][safi].name) {
7161 vty_out(vty, " table-map %s\n",
7162 bgp->table_map[afi][safi].name);
7163 }
7164 }
7165
7166 DEFUN (bgp_table_map,
7167 bgp_table_map_cmd,
7168 "table-map WORD",
7169 "BGP table to RIB route download filter\n"
7170 "Name of the route map\n")
7171 {
7172 int idx_word = 1;
7173 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7174 argv[idx_word]->arg);
7175 }
7176 DEFUN (no_bgp_table_map,
7177 no_bgp_table_map_cmd,
7178 "no table-map WORD",
7179 NO_STR
7180 "BGP table to RIB route download filter\n"
7181 "Name of the route map\n")
7182 {
7183 int idx_word = 2;
7184 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7185 argv[idx_word]->arg);
7186 }
7187
7188 DEFPY(bgp_network,
7189 bgp_network_cmd,
7190 "[no] network \
7191 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7192 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7193 backdoor$backdoor}]",
7194 NO_STR
7195 "Specify a network to announce via BGP\n"
7196 "IPv4 prefix\n"
7197 "Network number\n"
7198 "Network mask\n"
7199 "Network mask\n"
7200 "Route-map to modify the attributes\n"
7201 "Name of the route map\n"
7202 "Label index to associate with the prefix\n"
7203 "Label index value\n"
7204 "Specify a BGP backdoor route\n")
7205 {
7206 char addr_prefix_str[BUFSIZ];
7207
7208 if (address_str) {
7209 int ret;
7210
7211 ret = netmask_str2prefix_str(address_str, netmask_str,
7212 addr_prefix_str,
7213 sizeof(addr_prefix_str));
7214 if (!ret) {
7215 vty_out(vty, "%% Inconsistent address and mask\n");
7216 return CMD_WARNING_CONFIG_FAILED;
7217 }
7218 }
7219
7220 return bgp_static_set(
7221 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7222 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7223 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7224 }
7225
7226 DEFPY(ipv6_bgp_network,
7227 ipv6_bgp_network_cmd,
7228 "[no] network X:X::X:X/M$prefix \
7229 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7230 NO_STR
7231 "Specify a network to announce via BGP\n"
7232 "IPv6 prefix\n"
7233 "Route-map to modify the attributes\n"
7234 "Name of the route map\n"
7235 "Label index to associate with the prefix\n"
7236 "Label index value\n")
7237 {
7238 return bgp_static_set(
7239 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7240 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7241 }
7242
7243 static struct bgp_aggregate *bgp_aggregate_new(void)
7244 {
7245 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7246 }
7247
7248 void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7249 {
7250 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7251 route_map_counter_decrement(aggregate->suppress_map);
7252 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7253 route_map_counter_decrement(aggregate->rmap.map);
7254 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7255 }
7256
7257 /**
7258 * Helper function to avoid repeated code: prepare variables for a
7259 * `route_map_apply` call.
7260 *
7261 * \returns `true` on route map match, otherwise `false`.
7262 */
7263 static bool aggr_suppress_map_test(struct bgp *bgp,
7264 struct bgp_aggregate *aggregate,
7265 struct bgp_path_info *pi)
7266 {
7267 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7268 route_map_result_t rmr = RMAP_DENYMATCH;
7269 struct bgp_path_info rmap_path = {};
7270 struct attr attr = {};
7271
7272 /* No route map entries created, just don't match. */
7273 if (aggregate->suppress_map == NULL)
7274 return false;
7275
7276 /* Call route map matching and return result. */
7277 attr.aspath = aspath_empty(bgp->asnotation);
7278 rmap_path.peer = bgp->peer_self;
7279 rmap_path.attr = &attr;
7280
7281 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7282 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7283 bgp->peer_self->rmap_type = 0;
7284
7285 bgp_attr_flush(&attr);
7286 aspath_unintern(&attr.aspath);
7287
7288 return rmr == RMAP_PERMITMATCH;
7289 }
7290
7291 /** Test whether the aggregation has suppressed this path or not. */
7292 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7293 struct bgp_path_info *pi)
7294 {
7295 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7296 return false;
7297
7298 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7299 }
7300
7301 /**
7302 * Suppress this path and keep the reference.
7303 *
7304 * \returns `true` if needs processing otherwise `false`.
7305 */
7306 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7307 struct bgp_path_info *pi)
7308 {
7309 struct bgp_path_info_extra *pie;
7310
7311 /* Path is already suppressed by this aggregation. */
7312 if (aggr_suppress_exists(aggregate, pi))
7313 return false;
7314
7315 pie = bgp_path_info_extra_get(pi);
7316
7317 /* This is the first suppression, allocate memory and list it. */
7318 if (pie->aggr_suppressors == NULL)
7319 pie->aggr_suppressors = list_new();
7320
7321 listnode_add(pie->aggr_suppressors, aggregate);
7322
7323 /* Only mark for processing if suppressed. */
7324 if (listcount(pie->aggr_suppressors) == 1) {
7325 if (BGP_DEBUG(update, UPDATE_OUT))
7326 zlog_debug("aggregate-address suppressing: %pFX",
7327 bgp_dest_get_prefix(pi->net));
7328
7329 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7330 return true;
7331 }
7332
7333 return false;
7334 }
7335
7336 /**
7337 * Unsuppress this path and remove the reference.
7338 *
7339 * \returns `true` if needs processing otherwise `false`.
7340 */
7341 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7342 struct bgp_path_info *pi)
7343 {
7344 /* Path wasn't suppressed. */
7345 if (!aggr_suppress_exists(aggregate, pi))
7346 return false;
7347
7348 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7349
7350 /* Unsuppress and free extra memory if last item. */
7351 if (listcount(pi->extra->aggr_suppressors) == 0) {
7352 if (BGP_DEBUG(update, UPDATE_OUT))
7353 zlog_debug("aggregate-address unsuppressing: %pFX",
7354 bgp_dest_get_prefix(pi->net));
7355
7356 list_delete(&pi->extra->aggr_suppressors);
7357 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7358 return true;
7359 }
7360
7361 return false;
7362 }
7363
7364 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7365 struct aspath *aspath,
7366 struct community *comm,
7367 struct ecommunity *ecomm,
7368 struct lcommunity *lcomm)
7369 {
7370 static struct aspath *ae = NULL;
7371 enum asnotation_mode asnotation;
7372
7373 asnotation = bgp_get_asnotation(NULL);
7374
7375 if (!ae)
7376 ae = aspath_empty(asnotation);
7377
7378 if (!pi)
7379 return false;
7380
7381 if (origin != pi->attr->origin)
7382 return false;
7383
7384 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7385 return false;
7386
7387 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7388 return false;
7389
7390 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7391 return false;
7392
7393 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7394 return false;
7395
7396 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7397 return false;
7398
7399 return true;
7400 }
7401
7402 static void bgp_aggregate_install(
7403 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7404 uint8_t origin, struct aspath *aspath, struct community *community,
7405 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7406 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7407 {
7408 struct bgp_dest *dest;
7409 struct bgp_table *table;
7410 struct bgp_path_info *pi, *orig, *new;
7411 struct attr *attr;
7412
7413 table = bgp->rib[afi][safi];
7414
7415 dest = bgp_node_get(table, p);
7416
7417 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7418 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7419 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7420 break;
7421
7422 /*
7423 * If we have paths with different MEDs, then don't install
7424 * (or uninstall) the aggregate route.
7425 */
7426 if (aggregate->match_med && aggregate->med_mismatched)
7427 goto uninstall_aggregate_route;
7428
7429 if (aggregate->count > 0) {
7430 /*
7431 * If the aggregate information has not changed
7432 * no need to re-install it again.
7433 */
7434 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7435 ecommunity, lcommunity)) {
7436 bgp_dest_unlock_node(dest);
7437
7438 if (aspath)
7439 aspath_free(aspath);
7440 if (community)
7441 community_free(&community);
7442 if (ecommunity)
7443 ecommunity_free(&ecommunity);
7444 if (lcommunity)
7445 lcommunity_free(&lcommunity);
7446
7447 return;
7448 }
7449
7450 /*
7451 * Mark the old as unusable
7452 */
7453 if (pi)
7454 bgp_path_info_delete(dest, pi);
7455
7456 attr = bgp_attr_aggregate_intern(
7457 bgp, origin, aspath, community, ecommunity, lcommunity,
7458 aggregate, atomic_aggregate, p);
7459
7460 if (!attr) {
7461 aspath_free(aspath);
7462 community_free(&community);
7463 ecommunity_free(&ecommunity);
7464 lcommunity_free(&lcommunity);
7465 bgp_dest_unlock_node(dest);
7466 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7467 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7468 zlog_debug("%s: %pFX null attribute", __func__,
7469 p);
7470 return;
7471 }
7472
7473 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7474 bgp->peer_self, attr, dest);
7475
7476 SET_FLAG(new->flags, BGP_PATH_VALID);
7477
7478 bgp_path_info_add(dest, new);
7479 bgp_process(bgp, dest, afi, safi);
7480 } else {
7481 uninstall_aggregate_route:
7482 for (pi = orig; pi; pi = pi->next)
7483 if (pi->peer == bgp->peer_self
7484 && pi->type == ZEBRA_ROUTE_BGP
7485 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7486 break;
7487
7488 /* Withdraw static BGP route from routing table. */
7489 if (pi) {
7490 bgp_path_info_delete(dest, pi);
7491 bgp_process(bgp, dest, afi, safi);
7492 }
7493 }
7494
7495 bgp_dest_unlock_node(dest);
7496 }
7497
7498 /**
7499 * Check if the current path has different MED than other known paths.
7500 *
7501 * \returns `true` if the MED matched the others else `false`.
7502 */
7503 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7504 struct bgp *bgp, struct bgp_path_info *pi)
7505 {
7506 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7507
7508 /* This is the first route being analyzed. */
7509 if (!aggregate->med_initialized) {
7510 aggregate->med_initialized = true;
7511 aggregate->med_mismatched = false;
7512 aggregate->med_matched_value = cur_med;
7513 } else {
7514 /* Check if routes with different MED showed up. */
7515 if (cur_med != aggregate->med_matched_value)
7516 aggregate->med_mismatched = true;
7517 }
7518
7519 return !aggregate->med_mismatched;
7520 }
7521
7522 /**
7523 * Initializes and tests all routes in the aggregate address path for MED
7524 * values.
7525 *
7526 * \returns `true` if all MEDs are the same otherwise `false`.
7527 */
7528 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7529 struct bgp *bgp, const struct prefix *p,
7530 afi_t afi, safi_t safi)
7531 {
7532 struct bgp_table *table = bgp->rib[afi][safi];
7533 const struct prefix *dest_p;
7534 struct bgp_dest *dest, *top;
7535 struct bgp_path_info *pi;
7536 bool med_matched = true;
7537
7538 aggregate->med_initialized = false;
7539
7540 top = bgp_node_get(table, p);
7541 for (dest = bgp_node_get(table, p); dest;
7542 dest = bgp_route_next_until(dest, top)) {
7543 dest_p = bgp_dest_get_prefix(dest);
7544 if (dest_p->prefixlen <= p->prefixlen)
7545 continue;
7546
7547 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7548 if (BGP_PATH_HOLDDOWN(pi))
7549 continue;
7550 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7551 continue;
7552 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7553 med_matched = false;
7554 break;
7555 }
7556 }
7557 if (!med_matched)
7558 break;
7559 }
7560 bgp_dest_unlock_node(top);
7561
7562 return med_matched;
7563 }
7564
7565 /**
7566 * Toggles the route suppression status for this aggregate address
7567 * configuration.
7568 */
7569 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7570 struct bgp *bgp, const struct prefix *p,
7571 afi_t afi, safi_t safi, bool suppress)
7572 {
7573 struct bgp_table *table = bgp->rib[afi][safi];
7574 const struct prefix *dest_p;
7575 struct bgp_dest *dest, *top;
7576 struct bgp_path_info *pi;
7577 bool toggle_suppression;
7578
7579 /* We've found a different MED we must revert any suppressed routes. */
7580 top = bgp_node_get(table, p);
7581 for (dest = bgp_node_get(table, p); dest;
7582 dest = bgp_route_next_until(dest, top)) {
7583 dest_p = bgp_dest_get_prefix(dest);
7584 if (dest_p->prefixlen <= p->prefixlen)
7585 continue;
7586
7587 toggle_suppression = false;
7588 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7589 if (BGP_PATH_HOLDDOWN(pi))
7590 continue;
7591 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7592 continue;
7593
7594 /* We are toggling suppression back. */
7595 if (suppress) {
7596 /* Suppress route if not suppressed already. */
7597 if (aggr_suppress_path(aggregate, pi))
7598 toggle_suppression = true;
7599 continue;
7600 }
7601
7602 /* Install route if there is no more suppression. */
7603 if (aggr_unsuppress_path(aggregate, pi))
7604 toggle_suppression = true;
7605 }
7606
7607 if (toggle_suppression)
7608 bgp_process(bgp, dest, afi, safi);
7609 }
7610 bgp_dest_unlock_node(top);
7611 }
7612
7613 /**
7614 * Aggregate address MED matching incremental test: this function is called
7615 * when the initial aggregation occurred and we are only testing a single
7616 * new path.
7617 *
7618 * In addition to testing and setting the MED validity it also installs back
7619 * suppressed routes (if summary is configured).
7620 *
7621 * Must not be called in `bgp_aggregate_route`.
7622 */
7623 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7624 struct bgp *bgp, const struct prefix *p,
7625 afi_t afi, safi_t safi,
7626 struct bgp_path_info *pi)
7627 {
7628 /* MED matching disabled. */
7629 if (!aggregate->match_med)
7630 return;
7631
7632 /* Aggregation with different MED, recheck if we have got equal MEDs
7633 * now.
7634 */
7635 if (aggregate->med_mismatched &&
7636 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7637 aggregate->summary_only)
7638 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7639 true);
7640 else
7641 bgp_aggregate_med_match(aggregate, bgp, pi);
7642
7643 /* No mismatches, just quit. */
7644 if (!aggregate->med_mismatched)
7645 return;
7646
7647 /* Route summarization is disabled. */
7648 if (!aggregate->summary_only)
7649 return;
7650
7651 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7652 }
7653
7654 /* Update an aggregate as routes are added/removed from the BGP table */
7655 bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7656 safi_t safi, struct bgp_aggregate *aggregate)
7657 {
7658 struct bgp_table *table;
7659 struct bgp_dest *top;
7660 struct bgp_dest *dest;
7661 uint8_t origin;
7662 struct aspath *aspath = NULL;
7663 struct community *community = NULL;
7664 struct ecommunity *ecommunity = NULL;
7665 struct lcommunity *lcommunity = NULL;
7666 struct bgp_path_info *pi;
7667 unsigned long match = 0;
7668 uint8_t atomic_aggregate = 0;
7669
7670 /* If the bgp instance is being deleted or self peer is deleted
7671 * then do not create aggregate route
7672 */
7673 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
7674 bgp->peer_self == NULL)
7675 return false;
7676
7677 /* Initialize and test routes for MED difference. */
7678 if (aggregate->match_med)
7679 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7680
7681 /*
7682 * Reset aggregate count: we might've been called from route map
7683 * update so in that case we must retest all more specific routes.
7684 *
7685 * \see `bgp_route_map_process_update`.
7686 */
7687 aggregate->count = 0;
7688 aggregate->incomplete_origin_count = 0;
7689 aggregate->incomplete_origin_count = 0;
7690 aggregate->egp_origin_count = 0;
7691
7692 /* ORIGIN attribute: If at least one route among routes that are
7693 aggregated has ORIGIN with the value INCOMPLETE, then the
7694 aggregated route must have the ORIGIN attribute with the value
7695 INCOMPLETE. Otherwise, if at least one route among routes that
7696 are aggregated has ORIGIN with the value EGP, then the aggregated
7697 route must have the origin attribute with the value EGP. In all
7698 other case the value of the ORIGIN attribute of the aggregated
7699 route is INTERNAL. */
7700 origin = BGP_ORIGIN_IGP;
7701
7702 table = bgp->rib[afi][safi];
7703
7704 top = bgp_node_get(table, p);
7705 for (dest = bgp_node_get(table, p); dest;
7706 dest = bgp_route_next_until(dest, top)) {
7707 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7708
7709 if (dest_p->prefixlen <= p->prefixlen)
7710 continue;
7711
7712 /* If suppress fib is enabled and route not installed
7713 * in FIB, skip the route
7714 */
7715 if (!bgp_check_advertise(bgp, dest))
7716 continue;
7717
7718 match = 0;
7719
7720 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7721 if (BGP_PATH_HOLDDOWN(pi))
7722 continue;
7723
7724 if (pi->attr->flag
7725 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7726 atomic_aggregate = 1;
7727
7728 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7729 continue;
7730
7731 /*
7732 * summary-only aggregate route suppress
7733 * aggregated route announcements.
7734 *
7735 * MED matching:
7736 * Don't create summaries if MED didn't match
7737 * otherwise neither the specific routes and the
7738 * aggregation will be announced.
7739 */
7740 if (aggregate->summary_only
7741 && AGGREGATE_MED_VALID(aggregate)) {
7742 if (aggr_suppress_path(aggregate, pi))
7743 match++;
7744 }
7745
7746 /*
7747 * Suppress more specific routes that match the route
7748 * map results.
7749 *
7750 * MED matching:
7751 * Don't suppress routes if MED matching is enabled and
7752 * it mismatched otherwise we might end up with no
7753 * routes for this path.
7754 */
7755 if (aggregate->suppress_map_name
7756 && AGGREGATE_MED_VALID(aggregate)
7757 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7758 if (aggr_suppress_path(aggregate, pi))
7759 match++;
7760 }
7761
7762 aggregate->count++;
7763
7764 /*
7765 * If at least one route among routes that are
7766 * aggregated has ORIGIN with the value INCOMPLETE,
7767 * then the aggregated route MUST have the ORIGIN
7768 * attribute with the value INCOMPLETE. Otherwise, if
7769 * at least one route among routes that are aggregated
7770 * has ORIGIN with the value EGP, then the aggregated
7771 * route MUST have the ORIGIN attribute with the value
7772 * EGP.
7773 */
7774 switch (pi->attr->origin) {
7775 case BGP_ORIGIN_INCOMPLETE:
7776 aggregate->incomplete_origin_count++;
7777 break;
7778 case BGP_ORIGIN_EGP:
7779 aggregate->egp_origin_count++;
7780 break;
7781 default:
7782 /*Do nothing.
7783 */
7784 break;
7785 }
7786
7787 if (!aggregate->as_set)
7788 continue;
7789
7790 /*
7791 * as-set aggregate route generate origin, as path,
7792 * and community aggregation.
7793 */
7794 /* Compute aggregate route's as-path.
7795 */
7796 bgp_compute_aggregate_aspath_hash(aggregate,
7797 pi->attr->aspath);
7798
7799 /* Compute aggregate route's community.
7800 */
7801 if (bgp_attr_get_community(pi->attr))
7802 bgp_compute_aggregate_community_hash(
7803 aggregate,
7804 bgp_attr_get_community(pi->attr));
7805
7806 /* Compute aggregate route's extended community.
7807 */
7808 if (bgp_attr_get_ecommunity(pi->attr))
7809 bgp_compute_aggregate_ecommunity_hash(
7810 aggregate,
7811 bgp_attr_get_ecommunity(pi->attr));
7812
7813 /* Compute aggregate route's large community.
7814 */
7815 if (bgp_attr_get_lcommunity(pi->attr))
7816 bgp_compute_aggregate_lcommunity_hash(
7817 aggregate,
7818 bgp_attr_get_lcommunity(pi->attr));
7819 }
7820 if (match)
7821 bgp_process(bgp, dest, afi, safi);
7822 }
7823 if (aggregate->as_set) {
7824 bgp_compute_aggregate_aspath_val(aggregate);
7825 bgp_compute_aggregate_community_val(aggregate);
7826 bgp_compute_aggregate_ecommunity_val(aggregate);
7827 bgp_compute_aggregate_lcommunity_val(aggregate);
7828 }
7829
7830
7831 bgp_dest_unlock_node(top);
7832
7833
7834 if (aggregate->incomplete_origin_count > 0)
7835 origin = BGP_ORIGIN_INCOMPLETE;
7836 else if (aggregate->egp_origin_count > 0)
7837 origin = BGP_ORIGIN_EGP;
7838
7839 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7840 origin = aggregate->origin;
7841
7842 if (aggregate->as_set) {
7843 if (aggregate->aspath)
7844 /* Retrieve aggregate route's as-path.
7845 */
7846 aspath = aspath_dup(aggregate->aspath);
7847
7848 if (aggregate->community)
7849 /* Retrieve aggregate route's community.
7850 */
7851 community = community_dup(aggregate->community);
7852
7853 if (aggregate->ecommunity)
7854 /* Retrieve aggregate route's ecommunity.
7855 */
7856 ecommunity = ecommunity_dup(aggregate->ecommunity);
7857
7858 if (aggregate->lcommunity)
7859 /* Retrieve aggregate route's lcommunity.
7860 */
7861 lcommunity = lcommunity_dup(aggregate->lcommunity);
7862 }
7863
7864 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7865 ecommunity, lcommunity, atomic_aggregate,
7866 aggregate);
7867
7868 return true;
7869 }
7870
7871 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7872 safi_t safi, struct bgp_aggregate *aggregate)
7873 {
7874 struct bgp_table *table;
7875 struct bgp_dest *top;
7876 struct bgp_dest *dest;
7877 struct bgp_path_info *pi;
7878 unsigned long match;
7879
7880 table = bgp->rib[afi][safi];
7881
7882 /* If routes exists below this node, generate aggregate routes. */
7883 top = bgp_node_get(table, p);
7884 for (dest = bgp_node_get(table, p); dest;
7885 dest = bgp_route_next_until(dest, top)) {
7886 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7887
7888 if (dest_p->prefixlen <= p->prefixlen)
7889 continue;
7890 match = 0;
7891
7892 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7893 if (BGP_PATH_HOLDDOWN(pi))
7894 continue;
7895
7896 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7897 continue;
7898
7899 /*
7900 * This route is suppressed: attempt to unsuppress it.
7901 *
7902 * `aggr_unsuppress_path` will fail if this particular
7903 * aggregate route was not the suppressor.
7904 */
7905 if (pi->extra && pi->extra->aggr_suppressors &&
7906 listcount(pi->extra->aggr_suppressors)) {
7907 if (aggr_unsuppress_path(aggregate, pi))
7908 match++;
7909 }
7910
7911 aggregate->count--;
7912
7913 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7914 aggregate->incomplete_origin_count--;
7915 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7916 aggregate->egp_origin_count--;
7917
7918 if (aggregate->as_set) {
7919 /* Remove as-path from aggregate.
7920 */
7921 bgp_remove_aspath_from_aggregate_hash(
7922 aggregate,
7923 pi->attr->aspath);
7924
7925 if (bgp_attr_get_community(pi->attr))
7926 /* Remove community from aggregate.
7927 */
7928 bgp_remove_comm_from_aggregate_hash(
7929 aggregate,
7930 bgp_attr_get_community(
7931 pi->attr));
7932
7933 if (bgp_attr_get_ecommunity(pi->attr))
7934 /* Remove ecommunity from aggregate.
7935 */
7936 bgp_remove_ecomm_from_aggregate_hash(
7937 aggregate,
7938 bgp_attr_get_ecommunity(
7939 pi->attr));
7940
7941 if (bgp_attr_get_lcommunity(pi->attr))
7942 /* Remove lcommunity from aggregate.
7943 */
7944 bgp_remove_lcomm_from_aggregate_hash(
7945 aggregate,
7946 bgp_attr_get_lcommunity(
7947 pi->attr));
7948 }
7949 }
7950
7951 /* If this node was suppressed, process the change. */
7952 if (match)
7953 bgp_process(bgp, dest, afi, safi);
7954 }
7955 if (aggregate->as_set) {
7956 aspath_free(aggregate->aspath);
7957 aggregate->aspath = NULL;
7958 if (aggregate->community)
7959 community_free(&aggregate->community);
7960 if (aggregate->ecommunity)
7961 ecommunity_free(&aggregate->ecommunity);
7962 if (aggregate->lcommunity)
7963 lcommunity_free(&aggregate->lcommunity);
7964 }
7965
7966 bgp_dest_unlock_node(top);
7967 }
7968
7969 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7970 const struct prefix *aggr_p,
7971 struct bgp_path_info *pinew, afi_t afi,
7972 safi_t safi,
7973 struct bgp_aggregate *aggregate)
7974 {
7975 uint8_t origin;
7976 struct aspath *aspath = NULL;
7977 uint8_t atomic_aggregate = 0;
7978 struct community *community = NULL;
7979 struct ecommunity *ecommunity = NULL;
7980 struct lcommunity *lcommunity = NULL;
7981
7982 /* If the bgp instance is being deleted or self peer is deleted
7983 * then do not create aggregate route
7984 */
7985 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7986 || (bgp->peer_self == NULL))
7987 return;
7988
7989 /* ORIGIN attribute: If at least one route among routes that are
7990 * aggregated has ORIGIN with the value INCOMPLETE, then the
7991 * aggregated route must have the ORIGIN attribute with the value
7992 * INCOMPLETE. Otherwise, if at least one route among routes that
7993 * are aggregated has ORIGIN with the value EGP, then the aggregated
7994 * route must have the origin attribute with the value EGP. In all
7995 * other case the value of the ORIGIN attribute of the aggregated
7996 * route is INTERNAL.
7997 */
7998 origin = BGP_ORIGIN_IGP;
7999
8000 aggregate->count++;
8001
8002 /*
8003 * This must be called before `summary` check to avoid
8004 * "suppressing" twice.
8005 */
8006 if (aggregate->match_med)
8007 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8008 pinew);
8009
8010 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8011 aggr_suppress_path(aggregate, pinew);
8012
8013 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8014 && aggr_suppress_map_test(bgp, aggregate, pinew))
8015 aggr_suppress_path(aggregate, pinew);
8016
8017 switch (pinew->attr->origin) {
8018 case BGP_ORIGIN_INCOMPLETE:
8019 aggregate->incomplete_origin_count++;
8020 break;
8021 case BGP_ORIGIN_EGP:
8022 aggregate->egp_origin_count++;
8023 break;
8024 default:
8025 /* Do nothing.
8026 */
8027 break;
8028 }
8029
8030 if (aggregate->incomplete_origin_count > 0)
8031 origin = BGP_ORIGIN_INCOMPLETE;
8032 else if (aggregate->egp_origin_count > 0)
8033 origin = BGP_ORIGIN_EGP;
8034
8035 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8036 origin = aggregate->origin;
8037
8038 if (aggregate->as_set) {
8039 /* Compute aggregate route's as-path.
8040 */
8041 bgp_compute_aggregate_aspath(aggregate,
8042 pinew->attr->aspath);
8043
8044 /* Compute aggregate route's community.
8045 */
8046 if (bgp_attr_get_community(pinew->attr))
8047 bgp_compute_aggregate_community(
8048 aggregate, bgp_attr_get_community(pinew->attr));
8049
8050 /* Compute aggregate route's extended community.
8051 */
8052 if (bgp_attr_get_ecommunity(pinew->attr))
8053 bgp_compute_aggregate_ecommunity(
8054 aggregate,
8055 bgp_attr_get_ecommunity(pinew->attr));
8056
8057 /* Compute aggregate route's large community.
8058 */
8059 if (bgp_attr_get_lcommunity(pinew->attr))
8060 bgp_compute_aggregate_lcommunity(
8061 aggregate,
8062 bgp_attr_get_lcommunity(pinew->attr));
8063
8064 /* Retrieve aggregate route's as-path.
8065 */
8066 if (aggregate->aspath)
8067 aspath = aspath_dup(aggregate->aspath);
8068
8069 /* Retrieve aggregate route's community.
8070 */
8071 if (aggregate->community)
8072 community = community_dup(aggregate->community);
8073
8074 /* Retrieve aggregate route's ecommunity.
8075 */
8076 if (aggregate->ecommunity)
8077 ecommunity = ecommunity_dup(aggregate->ecommunity);
8078
8079 /* Retrieve aggregate route's lcommunity.
8080 */
8081 if (aggregate->lcommunity)
8082 lcommunity = lcommunity_dup(aggregate->lcommunity);
8083 }
8084
8085 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8086 aspath, community, ecommunity,
8087 lcommunity, atomic_aggregate, aggregate);
8088 }
8089
8090 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8091 safi_t safi,
8092 struct bgp_path_info *pi,
8093 struct bgp_aggregate *aggregate,
8094 const struct prefix *aggr_p)
8095 {
8096 uint8_t origin;
8097 struct aspath *aspath = NULL;
8098 uint8_t atomic_aggregate = 0;
8099 struct community *community = NULL;
8100 struct ecommunity *ecommunity = NULL;
8101 struct lcommunity *lcommunity = NULL;
8102 unsigned long match = 0;
8103
8104 /* If the bgp instance is being deleted or self peer is deleted
8105 * then do not create aggregate route
8106 */
8107 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8108 || (bgp->peer_self == NULL))
8109 return;
8110
8111 if (BGP_PATH_HOLDDOWN(pi))
8112 return;
8113
8114 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8115 return;
8116
8117 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8118 if (aggr_unsuppress_path(aggregate, pi))
8119 match++;
8120
8121 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8122 && aggr_suppress_map_test(bgp, aggregate, pi))
8123 if (aggr_unsuppress_path(aggregate, pi))
8124 match++;
8125
8126 /*
8127 * This must be called after `summary`, `suppress-map` check to avoid
8128 * "unsuppressing" twice.
8129 */
8130 if (aggregate->match_med)
8131 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8132
8133 if (aggregate->count > 0)
8134 aggregate->count--;
8135
8136 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8137 aggregate->incomplete_origin_count--;
8138 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8139 aggregate->egp_origin_count--;
8140
8141 if (aggregate->as_set) {
8142 /* Remove as-path from aggregate.
8143 */
8144 bgp_remove_aspath_from_aggregate(aggregate,
8145 pi->attr->aspath);
8146
8147 if (bgp_attr_get_community(pi->attr))
8148 /* Remove community from aggregate.
8149 */
8150 bgp_remove_community_from_aggregate(
8151 aggregate, bgp_attr_get_community(pi->attr));
8152
8153 if (bgp_attr_get_ecommunity(pi->attr))
8154 /* Remove ecommunity from aggregate.
8155 */
8156 bgp_remove_ecommunity_from_aggregate(
8157 aggregate, bgp_attr_get_ecommunity(pi->attr));
8158
8159 if (bgp_attr_get_lcommunity(pi->attr))
8160 /* Remove lcommunity from aggregate.
8161 */
8162 bgp_remove_lcommunity_from_aggregate(
8163 aggregate, bgp_attr_get_lcommunity(pi->attr));
8164 }
8165
8166 /* If this node was suppressed, process the change. */
8167 if (match)
8168 bgp_process(bgp, pi->net, afi, safi);
8169
8170 origin = BGP_ORIGIN_IGP;
8171 if (aggregate->incomplete_origin_count > 0)
8172 origin = BGP_ORIGIN_INCOMPLETE;
8173 else if (aggregate->egp_origin_count > 0)
8174 origin = BGP_ORIGIN_EGP;
8175
8176 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8177 origin = aggregate->origin;
8178
8179 if (aggregate->as_set) {
8180 /* Retrieve aggregate route's as-path.
8181 */
8182 if (aggregate->aspath)
8183 aspath = aspath_dup(aggregate->aspath);
8184
8185 /* Retrieve aggregate route's community.
8186 */
8187 if (aggregate->community)
8188 community = community_dup(aggregate->community);
8189
8190 /* Retrieve aggregate route's ecommunity.
8191 */
8192 if (aggregate->ecommunity)
8193 ecommunity = ecommunity_dup(aggregate->ecommunity);
8194
8195 /* Retrieve aggregate route's lcommunity.
8196 */
8197 if (aggregate->lcommunity)
8198 lcommunity = lcommunity_dup(aggregate->lcommunity);
8199 }
8200
8201 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8202 aspath, community, ecommunity,
8203 lcommunity, atomic_aggregate, aggregate);
8204 }
8205
8206 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8207 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8208 {
8209 struct bgp_dest *child;
8210 struct bgp_dest *dest;
8211 struct bgp_aggregate *aggregate;
8212 struct bgp_table *table;
8213
8214 table = bgp->aggregate[afi][safi];
8215
8216 /* No aggregates configured. */
8217 if (bgp_table_top_nolock(table) == NULL)
8218 return;
8219
8220 if (p->prefixlen == 0)
8221 return;
8222
8223 if (BGP_PATH_HOLDDOWN(pi))
8224 return;
8225
8226 /* If suppress fib is enabled and route not installed
8227 * in FIB, do not update the aggregate route
8228 */
8229 if (!bgp_check_advertise(bgp, pi->net))
8230 return;
8231
8232 child = bgp_node_get(table, p);
8233
8234 /* Aggregate address configuration check. */
8235 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8236 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8237
8238 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8239 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8240 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8241 aggregate);
8242 }
8243 }
8244 bgp_dest_unlock_node(child);
8245 }
8246
8247 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8248 struct bgp_path_info *del, afi_t afi, safi_t safi)
8249 {
8250 struct bgp_dest *child;
8251 struct bgp_dest *dest;
8252 struct bgp_aggregate *aggregate;
8253 struct bgp_table *table;
8254
8255 table = bgp->aggregate[afi][safi];
8256
8257 /* No aggregates configured. */
8258 if (bgp_table_top_nolock(table) == NULL)
8259 return;
8260
8261 if (p->prefixlen == 0)
8262 return;
8263
8264 child = bgp_node_get(table, p);
8265
8266 /* Aggregate address configuration check. */
8267 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8268 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8269
8270 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8271 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8272 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8273 aggregate, dest_p);
8274 }
8275 }
8276 bgp_dest_unlock_node(child);
8277 }
8278
8279 /* Aggregate route attribute. */
8280 #define AGGREGATE_SUMMARY_ONLY 1
8281 #define AGGREGATE_AS_SET 1
8282 #define AGGREGATE_AS_UNSET 0
8283
8284 static const char *bgp_origin2str(uint8_t origin)
8285 {
8286 switch (origin) {
8287 case BGP_ORIGIN_IGP:
8288 return "igp";
8289 case BGP_ORIGIN_EGP:
8290 return "egp";
8291 case BGP_ORIGIN_INCOMPLETE:
8292 return "incomplete";
8293 }
8294 return "n/a";
8295 }
8296
8297 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8298 {
8299 switch (v_state) {
8300 case RPKI_NOT_BEING_USED:
8301 return "not used";
8302 case RPKI_VALID:
8303 return "valid";
8304 case RPKI_NOTFOUND:
8305 return "not found";
8306 case RPKI_INVALID:
8307 return "invalid";
8308 }
8309
8310 assert(!"We should never get here this is a dev escape");
8311 return "ERROR";
8312 }
8313
8314 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8315 afi_t afi, safi_t safi)
8316 {
8317 VTY_DECLVAR_CONTEXT(bgp, bgp);
8318 int ret;
8319 struct prefix p;
8320 struct bgp_dest *dest;
8321 struct bgp_aggregate *aggregate;
8322
8323 /* Convert string to prefix structure. */
8324 ret = str2prefix(prefix_str, &p);
8325 if (!ret) {
8326 vty_out(vty, "Malformed prefix\n");
8327 return CMD_WARNING_CONFIG_FAILED;
8328 }
8329 apply_mask(&p);
8330
8331 /* Old configuration check. */
8332 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8333 if (!dest) {
8334 vty_out(vty,
8335 "%% There is no aggregate-address configuration.\n");
8336 return CMD_WARNING_CONFIG_FAILED;
8337 }
8338
8339 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8340 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8341 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8342 NULL, NULL, 0, aggregate);
8343
8344 /* Unlock aggregate address configuration. */
8345 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8346
8347 bgp_free_aggregate_info(aggregate);
8348 bgp_dest_unlock_node(dest);
8349 bgp_dest_unlock_node(dest);
8350
8351 return CMD_SUCCESS;
8352 }
8353
8354 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8355 safi_t safi, const char *rmap,
8356 uint8_t summary_only, uint8_t as_set,
8357 uint8_t origin, bool match_med,
8358 const char *suppress_map)
8359 {
8360 VTY_DECLVAR_CONTEXT(bgp, bgp);
8361 int ret;
8362 struct prefix p;
8363 struct bgp_dest *dest;
8364 struct bgp_aggregate *aggregate;
8365 uint8_t as_set_new = as_set;
8366
8367 if (suppress_map && summary_only) {
8368 vty_out(vty,
8369 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8370 return CMD_WARNING_CONFIG_FAILED;
8371 }
8372
8373 /* Convert string to prefix structure. */
8374 ret = str2prefix(prefix_str, &p);
8375 if (!ret) {
8376 vty_out(vty, "Malformed prefix\n");
8377 return CMD_WARNING_CONFIG_FAILED;
8378 }
8379 apply_mask(&p);
8380
8381 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8382 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8383 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8384 prefix_str);
8385 return CMD_WARNING_CONFIG_FAILED;
8386 }
8387
8388 /* Old configuration check. */
8389 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8390 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8391
8392 if (aggregate) {
8393 vty_out(vty, "There is already same aggregate network.\n");
8394 /* try to remove the old entry */
8395 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8396 if (ret) {
8397 vty_out(vty, "Error deleting aggregate.\n");
8398 bgp_dest_unlock_node(dest);
8399 return CMD_WARNING_CONFIG_FAILED;
8400 }
8401 }
8402
8403 /* Make aggregate address structure. */
8404 aggregate = bgp_aggregate_new();
8405 aggregate->summary_only = summary_only;
8406 aggregate->match_med = match_med;
8407
8408 /* Network operators MUST NOT locally generate any new
8409 * announcements containing AS_SET or AS_CONFED_SET. If they have
8410 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8411 * SHOULD withdraw those routes and re-announce routes for the
8412 * aggregate or component prefixes (i.e., the more-specific routes
8413 * subsumed by the previously aggregated route) without AS_SET
8414 * or AS_CONFED_SET in the updates.
8415 */
8416 if (bgp->reject_as_sets) {
8417 if (as_set == AGGREGATE_AS_SET) {
8418 as_set_new = AGGREGATE_AS_UNSET;
8419 zlog_warn(
8420 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8421 __func__);
8422 vty_out(vty,
8423 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8424 }
8425 }
8426
8427 aggregate->as_set = as_set_new;
8428 aggregate->safi = safi;
8429 /* Override ORIGIN attribute if defined.
8430 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8431 * to IGP which is not what rfc4271 says.
8432 * This enables the same behavior, optionally.
8433 */
8434 aggregate->origin = origin;
8435
8436 if (rmap) {
8437 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8438 route_map_counter_decrement(aggregate->rmap.map);
8439 aggregate->rmap.name =
8440 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8441 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8442 route_map_counter_increment(aggregate->rmap.map);
8443 }
8444
8445 if (suppress_map) {
8446 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8447 route_map_counter_decrement(aggregate->suppress_map);
8448
8449 aggregate->suppress_map_name =
8450 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8451 aggregate->suppress_map =
8452 route_map_lookup_by_name(aggregate->suppress_map_name);
8453 route_map_counter_increment(aggregate->suppress_map);
8454 }
8455
8456 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8457
8458 /* Aggregate address insert into BGP routing table. */
8459 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8460 bgp_aggregate_free(aggregate);
8461 bgp_dest_unlock_node(dest);
8462 }
8463
8464 return CMD_SUCCESS;
8465 }
8466
8467 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8468 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8469 "as-set$as_set_s"
8470 "|summary-only$summary_only"
8471 "|route-map RMAP_NAME$rmap_name"
8472 "|origin <egp|igp|incomplete>$origin_s"
8473 "|matching-MED-only$match_med"
8474 "|suppress-map RMAP_NAME$suppress_map"
8475 "}]",
8476 NO_STR
8477 "Configure BGP aggregate entries\n"
8478 "Aggregate prefix\n"
8479 "Aggregate address\n"
8480 "Aggregate mask\n"
8481 "Generate AS set path information\n"
8482 "Filter more specific routes from updates\n"
8483 "Apply route map to aggregate network\n"
8484 "Route map name\n"
8485 "BGP origin code\n"
8486 "Remote EGP\n"
8487 "Local IGP\n"
8488 "Unknown heritage\n"
8489 "Only aggregate routes with matching MED\n"
8490 "Suppress the selected more specific routes\n"
8491 "Route map with the route selectors\n")
8492 {
8493 const char *prefix_s = NULL;
8494 safi_t safi = bgp_node_safi(vty);
8495 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8496 int as_set = AGGREGATE_AS_UNSET;
8497 char prefix_buf[PREFIX2STR_BUFFER];
8498
8499 if (addr_str) {
8500 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8501 sizeof(prefix_buf))
8502 == 0) {
8503 vty_out(vty, "%% Inconsistent address and mask\n");
8504 return CMD_WARNING_CONFIG_FAILED;
8505 }
8506 prefix_s = prefix_buf;
8507 } else
8508 prefix_s = prefix_str;
8509
8510 if (origin_s) {
8511 if (strcmp(origin_s, "egp") == 0)
8512 origin = BGP_ORIGIN_EGP;
8513 else if (strcmp(origin_s, "igp") == 0)
8514 origin = BGP_ORIGIN_IGP;
8515 else if (strcmp(origin_s, "incomplete") == 0)
8516 origin = BGP_ORIGIN_INCOMPLETE;
8517 }
8518
8519 if (as_set_s)
8520 as_set = AGGREGATE_AS_SET;
8521
8522 /* Handle configuration removal, otherwise installation. */
8523 if (no)
8524 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8525
8526 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8527 summary_only != NULL, as_set, origin,
8528 match_med != NULL, suppress_map);
8529 }
8530
8531 void bgp_free_aggregate_info(struct bgp_aggregate *aggregate)
8532 {
8533 if (aggregate->community)
8534 community_free(&aggregate->community);
8535
8536 hash_clean_and_free(&aggregate->community_hash,
8537 bgp_aggr_community_remove);
8538
8539 if (aggregate->ecommunity)
8540 ecommunity_free(&aggregate->ecommunity);
8541
8542 hash_clean_and_free(&aggregate->ecommunity_hash,
8543 bgp_aggr_ecommunity_remove);
8544
8545 if (aggregate->lcommunity)
8546 lcommunity_free(&aggregate->lcommunity);
8547
8548 hash_clean_and_free(&aggregate->lcommunity_hash,
8549 bgp_aggr_lcommunity_remove);
8550
8551 if (aggregate->aspath)
8552 aspath_free(aggregate->aspath);
8553
8554 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8555
8556 bgp_aggregate_free(aggregate);
8557 }
8558
8559 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8560 "[no] aggregate-address X:X::X:X/M$prefix [{"
8561 "as-set$as_set_s"
8562 "|summary-only$summary_only"
8563 "|route-map RMAP_NAME$rmap_name"
8564 "|origin <egp|igp|incomplete>$origin_s"
8565 "|matching-MED-only$match_med"
8566 "|suppress-map RMAP_NAME$suppress_map"
8567 "}]",
8568 NO_STR
8569 "Configure BGP aggregate entries\n"
8570 "Aggregate prefix\n"
8571 "Generate AS set path information\n"
8572 "Filter more specific routes from updates\n"
8573 "Apply route map to aggregate network\n"
8574 "Route map name\n"
8575 "BGP origin code\n"
8576 "Remote EGP\n"
8577 "Local IGP\n"
8578 "Unknown heritage\n"
8579 "Only aggregate routes with matching MED\n"
8580 "Suppress the selected more specific routes\n"
8581 "Route map with the route selectors\n")
8582 {
8583 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8584 int as_set = AGGREGATE_AS_UNSET;
8585
8586 if (origin_s) {
8587 if (strcmp(origin_s, "egp") == 0)
8588 origin = BGP_ORIGIN_EGP;
8589 else if (strcmp(origin_s, "igp") == 0)
8590 origin = BGP_ORIGIN_IGP;
8591 else if (strcmp(origin_s, "incomplete") == 0)
8592 origin = BGP_ORIGIN_INCOMPLETE;
8593 }
8594
8595 if (as_set_s)
8596 as_set = AGGREGATE_AS_SET;
8597
8598 /* Handle configuration removal, otherwise installation. */
8599 if (no)
8600 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8601 SAFI_UNICAST);
8602
8603 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8604 rmap_name, summary_only != NULL, as_set,
8605 origin, match_med != NULL, suppress_map);
8606 }
8607
8608 /* Redistribute route treatment. */
8609 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8610 const union g_addr *nexthop, ifindex_t ifindex,
8611 enum nexthop_types_t nhtype, uint8_t distance,
8612 enum blackhole_type bhtype, uint32_t metric,
8613 uint8_t type, unsigned short instance,
8614 route_tag_t tag)
8615 {
8616 struct bgp_path_info *new;
8617 struct bgp_path_info *bpi;
8618 struct bgp_path_info rmap_path;
8619 struct bgp_dest *bn;
8620 struct attr attr;
8621 struct attr *new_attr;
8622 afi_t afi;
8623 route_map_result_t ret;
8624 struct bgp_redist *red;
8625
8626 /* Make default attribute. */
8627 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8628 /*
8629 * This must not be NULL to satisfy Coverity SA
8630 */
8631 assert(attr.aspath);
8632
8633 switch (nhtype) {
8634 case NEXTHOP_TYPE_IFINDEX:
8635 switch (p->family) {
8636 case AF_INET:
8637 attr.nexthop.s_addr = INADDR_ANY;
8638 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8639 break;
8640 case AF_INET6:
8641 memset(&attr.mp_nexthop_global, 0,
8642 sizeof(attr.mp_nexthop_global));
8643 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8644 break;
8645 }
8646 break;
8647 case NEXTHOP_TYPE_IPV4:
8648 case NEXTHOP_TYPE_IPV4_IFINDEX:
8649 attr.nexthop = nexthop->ipv4;
8650 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8651 break;
8652 case NEXTHOP_TYPE_IPV6:
8653 case NEXTHOP_TYPE_IPV6_IFINDEX:
8654 attr.mp_nexthop_global = nexthop->ipv6;
8655 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8656 break;
8657 case NEXTHOP_TYPE_BLACKHOLE:
8658 switch (p->family) {
8659 case AF_INET:
8660 attr.nexthop.s_addr = INADDR_ANY;
8661 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8662 break;
8663 case AF_INET6:
8664 memset(&attr.mp_nexthop_global, 0,
8665 sizeof(attr.mp_nexthop_global));
8666 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8667 break;
8668 }
8669 attr.bh_type = bhtype;
8670 break;
8671 }
8672 attr.nh_type = nhtype;
8673 attr.nh_ifindex = ifindex;
8674
8675 attr.med = metric;
8676 attr.distance = distance;
8677 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8678 attr.tag = tag;
8679
8680 if (metric)
8681 bgp_attr_set_aigp_metric(&attr, metric);
8682
8683 afi = family2afi(p->family);
8684
8685 red = bgp_redist_lookup(bgp, afi, type, instance);
8686 if (red) {
8687 struct attr attr_new;
8688
8689 /* Copy attribute for modification. */
8690 attr_new = attr;
8691
8692 if (red->redist_metric_flag) {
8693 attr_new.med = red->redist_metric;
8694 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8695 }
8696
8697 /* Apply route-map. */
8698 if (red->rmap.name) {
8699 memset(&rmap_path, 0, sizeof(rmap_path));
8700 rmap_path.peer = bgp->peer_self;
8701 rmap_path.attr = &attr_new;
8702
8703 SET_FLAG(bgp->peer_self->rmap_type,
8704 PEER_RMAP_TYPE_REDISTRIBUTE);
8705
8706 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8707
8708 bgp->peer_self->rmap_type = 0;
8709
8710 if (ret == RMAP_DENYMATCH) {
8711 /* Free uninterned attribute. */
8712 bgp_attr_flush(&attr_new);
8713
8714 /* Unintern original. */
8715 aspath_unintern(&attr.aspath);
8716 bgp_redistribute_delete(bgp, p, type, instance);
8717 return;
8718 }
8719 }
8720
8721 if (bgp_in_graceful_shutdown(bgp))
8722 bgp_attr_add_gshut_community(&attr_new);
8723
8724 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8725 SAFI_UNICAST, p, NULL);
8726
8727 new_attr = bgp_attr_intern(&attr_new);
8728
8729 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8730 if (bpi->peer == bgp->peer_self
8731 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8732 break;
8733
8734 if (bpi) {
8735 /* Ensure the (source route) type is updated. */
8736 bpi->type = type;
8737 if (attrhash_cmp(bpi->attr, new_attr)
8738 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8739 bgp_attr_unintern(&new_attr);
8740 aspath_unintern(&attr.aspath);
8741 bgp_dest_unlock_node(bn);
8742 return;
8743 } else {
8744 /* The attribute is changed. */
8745 bgp_path_info_set_flag(bn, bpi,
8746 BGP_PATH_ATTR_CHANGED);
8747
8748 /* Rewrite BGP route information. */
8749 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8750 bgp_path_info_restore(bn, bpi);
8751 else
8752 bgp_aggregate_decrement(
8753 bgp, p, bpi, afi, SAFI_UNICAST);
8754 bgp_attr_unintern(&bpi->attr);
8755 bpi->attr = new_attr;
8756 bpi->uptime = monotime(NULL);
8757
8758 /* Process change. */
8759 bgp_aggregate_increment(bgp, p, bpi, afi,
8760 SAFI_UNICAST);
8761 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8762 bgp_dest_unlock_node(bn);
8763 aspath_unintern(&attr.aspath);
8764
8765 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8766 || (bgp->inst_type
8767 == BGP_INSTANCE_TYPE_DEFAULT)) {
8768
8769 vpn_leak_from_vrf_update(
8770 bgp_get_default(), bgp, bpi);
8771 }
8772 return;
8773 }
8774 }
8775
8776 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8777 bgp->peer_self, new_attr, bn);
8778 SET_FLAG(new->flags, BGP_PATH_VALID);
8779
8780 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8781 bgp_path_info_add(bn, new);
8782 bgp_dest_unlock_node(bn);
8783 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8784 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8785
8786 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8787 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8788
8789 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8790 }
8791 }
8792
8793 /* Unintern original. */
8794 aspath_unintern(&attr.aspath);
8795 }
8796
8797 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8798 unsigned short instance)
8799 {
8800 afi_t afi;
8801 struct bgp_dest *dest;
8802 struct bgp_path_info *pi;
8803 struct bgp_redist *red;
8804
8805 afi = family2afi(p->family);
8806
8807 red = bgp_redist_lookup(bgp, afi, type, instance);
8808 if (red) {
8809 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8810 SAFI_UNICAST, p, NULL);
8811
8812 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8813 if (pi->peer == bgp->peer_self && pi->type == type)
8814 break;
8815
8816 if (pi) {
8817 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8818 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8819
8820 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8821 bgp, pi);
8822 }
8823 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8824 bgp_path_info_delete(dest, pi);
8825 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8826 }
8827 bgp_dest_unlock_node(dest);
8828 }
8829 }
8830
8831 /* Withdraw specified route type's route. */
8832 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8833 unsigned short instance)
8834 {
8835 struct bgp_dest *dest;
8836 struct bgp_path_info *pi;
8837 struct bgp_table *table;
8838
8839 table = bgp->rib[afi][SAFI_UNICAST];
8840
8841 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8842 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8843 if (pi->peer == bgp->peer_self && pi->type == type
8844 && pi->instance == instance)
8845 break;
8846
8847 if (pi) {
8848 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8849 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8850
8851 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8852 bgp, pi);
8853 }
8854 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8855 pi, afi, SAFI_UNICAST);
8856 bgp_path_info_delete(dest, pi);
8857 if (!CHECK_FLAG(bgp->flags,
8858 BGP_FLAG_DELETE_IN_PROGRESS))
8859 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8860 else
8861 bgp_path_info_reap(dest, pi);
8862 }
8863 }
8864 }
8865
8866 /* Static function to display route. */
8867 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8868 struct vty *vty, json_object *json, bool wide)
8869 {
8870 int len = 0;
8871 char buf[INET6_ADDRSTRLEN];
8872
8873 if (p->family == AF_INET) {
8874 if (!json) {
8875 len = vty_out(vty, "%pFX", p);
8876 } else {
8877 json_object_string_add(json, "prefix",
8878 inet_ntop(p->family,
8879 &p->u.prefix, buf,
8880 sizeof(buf)));
8881 json_object_int_add(json, "prefixLen", p->prefixlen);
8882 json_object_string_addf(json, "network", "%pFX", p);
8883 json_object_int_add(json, "version", dest->version);
8884 }
8885 } else if (p->family == AF_ETHERNET) {
8886 len = vty_out(vty, "%pFX", p);
8887 } else if (p->family == AF_EVPN) {
8888 if (!json)
8889 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8890 else
8891 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8892 } else if (p->family == AF_FLOWSPEC) {
8893 route_vty_out_flowspec(vty, p, NULL,
8894 json ?
8895 NLRI_STRING_FORMAT_JSON_SIMPLE :
8896 NLRI_STRING_FORMAT_MIN, json);
8897 } else {
8898 if (!json)
8899 len = vty_out(vty, "%pFX", p);
8900 else {
8901 json_object_string_add(json, "prefix",
8902 inet_ntop(p->family,
8903 &p->u.prefix, buf,
8904 sizeof(buf)));
8905 json_object_int_add(json, "prefixLen", p->prefixlen);
8906 json_object_string_addf(json, "network", "%pFX", p);
8907 json_object_int_add(json, "version", dest->version);
8908 }
8909 }
8910
8911 if (!json) {
8912 len = wide ? (45 - len) : (17 - len);
8913 if (len < 1)
8914 vty_out(vty, "\n%*s", 20, " ");
8915 else
8916 vty_out(vty, "%*s", len, " ");
8917 }
8918 }
8919
8920 enum bgp_display_type {
8921 normal_list,
8922 };
8923
8924 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8925 {
8926 switch (reason) {
8927 case bgp_path_selection_none:
8928 return "Nothing to Select";
8929 case bgp_path_selection_first:
8930 return "First path received";
8931 case bgp_path_selection_evpn_sticky_mac:
8932 return "EVPN Sticky Mac";
8933 case bgp_path_selection_evpn_seq:
8934 return "EVPN sequence number";
8935 case bgp_path_selection_evpn_lower_ip:
8936 return "EVPN lower IP";
8937 case bgp_path_selection_evpn_local_path:
8938 return "EVPN local ES path";
8939 case bgp_path_selection_evpn_non_proxy:
8940 return "EVPN non proxy";
8941 case bgp_path_selection_weight:
8942 return "Weight";
8943 case bgp_path_selection_local_pref:
8944 return "Local Pref";
8945 case bgp_path_selection_accept_own:
8946 return "Accept Own";
8947 case bgp_path_selection_local_route:
8948 return "Local Route";
8949 case bgp_path_selection_aigp:
8950 return "AIGP";
8951 case bgp_path_selection_confed_as_path:
8952 return "Confederation based AS Path";
8953 case bgp_path_selection_as_path:
8954 return "AS Path";
8955 case bgp_path_selection_origin:
8956 return "Origin";
8957 case bgp_path_selection_med:
8958 return "MED";
8959 case bgp_path_selection_peer:
8960 return "Peer Type";
8961 case bgp_path_selection_confed:
8962 return "Confed Peer Type";
8963 case bgp_path_selection_igp_metric:
8964 return "IGP Metric";
8965 case bgp_path_selection_older:
8966 return "Older Path";
8967 case bgp_path_selection_router_id:
8968 return "Router ID";
8969 case bgp_path_selection_cluster_length:
8970 return "Cluster length";
8971 case bgp_path_selection_stale:
8972 return "Path Staleness";
8973 case bgp_path_selection_local_configured:
8974 return "Locally configured route";
8975 case bgp_path_selection_neighbor_ip:
8976 return "Neighbor IP";
8977 case bgp_path_selection_default:
8978 return "Nothing left to compare";
8979 }
8980 return "Invalid (internal error)";
8981 }
8982
8983 /* Print the short form route status for a bgp_path_info */
8984 static void route_vty_short_status_out(struct vty *vty,
8985 struct bgp_path_info *path,
8986 const struct prefix *p,
8987 json_object *json_path)
8988 {
8989 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8990
8991 if (json_path) {
8992
8993 /* Route status display. */
8994 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8995 json_object_boolean_true_add(json_path, "removed");
8996
8997 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8998 json_object_boolean_true_add(json_path, "stale");
8999
9000 if (path->extra && bgp_path_suppressed(path))
9001 json_object_boolean_true_add(json_path, "suppressed");
9002
9003 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9004 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9005 json_object_boolean_true_add(json_path, "valid");
9006
9007 /* Selected */
9008 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9009 json_object_boolean_true_add(json_path, "history");
9010
9011 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9012 json_object_boolean_true_add(json_path, "damped");
9013
9014 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9015 json_object_boolean_true_add(json_path, "bestpath");
9016 json_object_string_add(json_path, "selectionReason",
9017 bgp_path_selection_reason2str(
9018 path->net->reason));
9019 }
9020
9021 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9022 json_object_boolean_true_add(json_path, "multipath");
9023
9024 /* Internal route. */
9025 if ((path->peer->as)
9026 && (path->peer->as == path->peer->local_as))
9027 json_object_string_add(json_path, "pathFrom",
9028 "internal");
9029 else
9030 json_object_string_add(json_path, "pathFrom",
9031 "external");
9032
9033 return;
9034 }
9035
9036 /* RPKI validation state */
9037 rpki_state =
9038 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9039
9040 if (rpki_state == RPKI_VALID)
9041 vty_out(vty, "V");
9042 else if (rpki_state == RPKI_INVALID)
9043 vty_out(vty, "I");
9044 else if (rpki_state == RPKI_NOTFOUND)
9045 vty_out(vty, "N");
9046 else
9047 vty_out(vty, " ");
9048
9049 /* Route status display. */
9050 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9051 vty_out(vty, "R");
9052 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9053 vty_out(vty, "S");
9054 else if (bgp_path_suppressed(path))
9055 vty_out(vty, "s");
9056 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9057 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9058 vty_out(vty, "*");
9059 else
9060 vty_out(vty, " ");
9061
9062 /* Selected */
9063 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9064 vty_out(vty, "h");
9065 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9066 vty_out(vty, "d");
9067 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9068 vty_out(vty, ">");
9069 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9070 vty_out(vty, "=");
9071 else
9072 vty_out(vty, " ");
9073
9074 /* Internal route. */
9075 if (path->peer && (path->peer->as)
9076 && (path->peer->as == path->peer->local_as))
9077 vty_out(vty, "i");
9078 else
9079 vty_out(vty, " ");
9080 }
9081
9082 static char *bgp_nexthop_hostname(struct peer *peer,
9083 struct bgp_nexthop_cache *bnc)
9084 {
9085 if (peer->hostname
9086 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9087 return peer->hostname;
9088 return NULL;
9089 }
9090
9091 /* called from terminal list command */
9092 void route_vty_out(struct vty *vty, const struct prefix *p,
9093 struct bgp_path_info *path, int display, safi_t safi,
9094 json_object *json_paths, bool wide)
9095 {
9096 int len;
9097 struct attr *attr = path->attr;
9098 json_object *json_path = NULL;
9099 json_object *json_nexthops = NULL;
9100 json_object *json_nexthop_global = NULL;
9101 json_object *json_nexthop_ll = NULL;
9102 json_object *json_ext_community = NULL;
9103 char vrf_id_str[VRF_NAMSIZ] = {0};
9104 bool nexthop_self =
9105 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9106 bool nexthop_othervrf = false;
9107 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9108 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9109 char *nexthop_hostname =
9110 bgp_nexthop_hostname(path->peer, path->nexthop);
9111 char esi_buf[ESI_STR_LEN];
9112
9113 if (json_paths)
9114 json_path = json_object_new_object();
9115
9116 /* short status lead text */
9117 route_vty_short_status_out(vty, path, p, json_path);
9118
9119 if (!json_paths) {
9120 /* print prefix and mask */
9121 if (!display)
9122 route_vty_out_route(path->net, p, vty, json_path, wide);
9123 else
9124 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9125 } else {
9126 route_vty_out_route(path->net, p, vty, json_path, wide);
9127 }
9128
9129 /*
9130 * If vrf id of nexthop is different from that of prefix,
9131 * set up printable string to append
9132 */
9133 if (path->extra && path->extra->bgp_orig) {
9134 const char *self = "";
9135
9136 if (nexthop_self)
9137 self = "<";
9138
9139 nexthop_othervrf = true;
9140 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9141
9142 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9143 snprintf(vrf_id_str, sizeof(vrf_id_str),
9144 "@%s%s", VRFID_NONE_STR, self);
9145 else
9146 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9147 path->extra->bgp_orig->vrf_id, self);
9148
9149 if (path->extra->bgp_orig->inst_type
9150 != BGP_INSTANCE_TYPE_DEFAULT)
9151
9152 nexthop_vrfname = path->extra->bgp_orig->name;
9153 } else {
9154 const char *self = "";
9155
9156 if (nexthop_self)
9157 self = "<";
9158
9159 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9160 }
9161
9162 /*
9163 * For ENCAP and EVPN routes, nexthop address family is not
9164 * neccessarily the same as the prefix address family.
9165 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9166 * EVPN routes are also exchanged with a MP nexthop. Currently,
9167 * this
9168 * is only IPv4, the value will be present in either
9169 * attr->nexthop or
9170 * attr->mp_nexthop_global_in
9171 */
9172 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9173 char nexthop[128];
9174 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9175
9176 switch (af) {
9177 case AF_INET:
9178 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9179 &attr->mp_nexthop_global_in);
9180 break;
9181 case AF_INET6:
9182 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9183 &attr->mp_nexthop_global);
9184 break;
9185 default:
9186 snprintf(nexthop, sizeof(nexthop), "?");
9187 break;
9188 }
9189
9190 if (json_paths) {
9191 json_nexthop_global = json_object_new_object();
9192
9193 json_object_string_add(json_nexthop_global, "ip",
9194 nexthop);
9195
9196 if (path->peer->hostname)
9197 json_object_string_add(json_nexthop_global,
9198 "hostname",
9199 path->peer->hostname);
9200
9201 json_object_string_add(json_nexthop_global, "afi",
9202 (af == AF_INET) ? "ipv4"
9203 : "ipv6");
9204 json_object_boolean_true_add(json_nexthop_global,
9205 "used");
9206 } else {
9207 if (nexthop_hostname)
9208 len = vty_out(vty, "%s(%s)%s", nexthop,
9209 nexthop_hostname, vrf_id_str);
9210 else
9211 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9212
9213 len = wide ? (41 - len) : (16 - len);
9214 if (len < 1)
9215 vty_out(vty, "\n%*s", 36, " ");
9216 else
9217 vty_out(vty, "%*s", len, " ");
9218 }
9219 } else if (safi == SAFI_EVPN) {
9220 if (json_paths) {
9221 json_nexthop_global = json_object_new_object();
9222
9223 json_object_string_addf(json_nexthop_global, "ip",
9224 "%pI4",
9225 &attr->mp_nexthop_global_in);
9226
9227 if (path->peer->hostname)
9228 json_object_string_add(json_nexthop_global,
9229 "hostname",
9230 path->peer->hostname);
9231
9232 json_object_string_add(json_nexthop_global, "afi",
9233 "ipv4");
9234 json_object_boolean_true_add(json_nexthop_global,
9235 "used");
9236 } else {
9237 if (nexthop_hostname)
9238 len = vty_out(vty, "%pI4(%s)%s",
9239 &attr->mp_nexthop_global_in,
9240 nexthop_hostname, vrf_id_str);
9241 else
9242 len = vty_out(vty, "%pI4%s",
9243 &attr->mp_nexthop_global_in,
9244 vrf_id_str);
9245
9246 len = wide ? (41 - len) : (16 - len);
9247 if (len < 1)
9248 vty_out(vty, "\n%*s", 36, " ");
9249 else
9250 vty_out(vty, "%*s", len, " ");
9251 }
9252 } else if (safi == SAFI_FLOWSPEC) {
9253 if (attr->nexthop.s_addr != INADDR_ANY) {
9254 if (json_paths) {
9255 json_nexthop_global = json_object_new_object();
9256
9257 json_object_string_add(json_nexthop_global,
9258 "afi", "ipv4");
9259 json_object_string_addf(json_nexthop_global,
9260 "ip", "%pI4",
9261 &attr->nexthop);
9262
9263 if (path->peer->hostname)
9264 json_object_string_add(
9265 json_nexthop_global, "hostname",
9266 path->peer->hostname);
9267
9268 json_object_boolean_true_add(
9269 json_nexthop_global,
9270 "used");
9271 } else {
9272 if (nexthop_hostname)
9273 len = vty_out(vty, "%pI4(%s)%s",
9274 &attr->nexthop,
9275 nexthop_hostname,
9276 vrf_id_str);
9277 else
9278 len = vty_out(vty, "%pI4%s",
9279 &attr->nexthop,
9280 vrf_id_str);
9281
9282 len = wide ? (41 - len) : (16 - len);
9283 if (len < 1)
9284 vty_out(vty, "\n%*s", 36, " ");
9285 else
9286 vty_out(vty, "%*s", len, " ");
9287 }
9288 }
9289 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9290 if (json_paths) {
9291 json_nexthop_global = json_object_new_object();
9292
9293 json_object_string_addf(json_nexthop_global, "ip",
9294 "%pI4", &attr->nexthop);
9295
9296 if (path->peer->hostname)
9297 json_object_string_add(json_nexthop_global,
9298 "hostname",
9299 path->peer->hostname);
9300
9301 json_object_string_add(json_nexthop_global, "afi",
9302 "ipv4");
9303 json_object_boolean_true_add(json_nexthop_global,
9304 "used");
9305 } else {
9306 if (nexthop_hostname)
9307 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9308 nexthop_hostname, vrf_id_str);
9309 else
9310 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9311 vrf_id_str);
9312
9313 len = wide ? (41 - len) : (16 - len);
9314 if (len < 1)
9315 vty_out(vty, "\n%*s", 36, " ");
9316 else
9317 vty_out(vty, "%*s", len, " ");
9318 }
9319 }
9320
9321 /* IPv6 Next Hop */
9322 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9323 if (json_paths) {
9324 json_nexthop_global = json_object_new_object();
9325 json_object_string_addf(json_nexthop_global, "ip",
9326 "%pI6",
9327 &attr->mp_nexthop_global);
9328
9329 if (path->peer->hostname)
9330 json_object_string_add(json_nexthop_global,
9331 "hostname",
9332 path->peer->hostname);
9333
9334 json_object_string_add(json_nexthop_global, "afi",
9335 "ipv6");
9336 json_object_string_add(json_nexthop_global, "scope",
9337 "global");
9338
9339 /* We display both LL & GL if both have been
9340 * received */
9341 if ((attr->mp_nexthop_len
9342 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9343 || (path->peer->conf_if)) {
9344 json_nexthop_ll = json_object_new_object();
9345 json_object_string_addf(
9346 json_nexthop_ll, "ip", "%pI6",
9347 &attr->mp_nexthop_local);
9348
9349 if (path->peer->hostname)
9350 json_object_string_add(
9351 json_nexthop_ll, "hostname",
9352 path->peer->hostname);
9353
9354 json_object_string_add(json_nexthop_ll, "afi",
9355 "ipv6");
9356 json_object_string_add(json_nexthop_ll, "scope",
9357 "link-local");
9358
9359 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9360 &attr->mp_nexthop_local)
9361 != 0)
9362 && !attr->mp_nexthop_prefer_global)
9363 json_object_boolean_true_add(
9364 json_nexthop_ll, "used");
9365 else
9366 json_object_boolean_true_add(
9367 json_nexthop_global, "used");
9368 } else
9369 json_object_boolean_true_add(
9370 json_nexthop_global, "used");
9371 } else {
9372 /* Display LL if LL/Global both in table unless
9373 * prefer-global is set */
9374 if (((attr->mp_nexthop_len
9375 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9376 && !attr->mp_nexthop_prefer_global)
9377 || (path->peer->conf_if)) {
9378 if (path->peer->conf_if) {
9379 len = vty_out(vty, "%s",
9380 path->peer->conf_if);
9381 /* len of IPv6 addr + max len of def
9382 * ifname */
9383 len = wide ? (41 - len) : (16 - len);
9384
9385 if (len < 1)
9386 vty_out(vty, "\n%*s", 36, " ");
9387 else
9388 vty_out(vty, "%*s", len, " ");
9389 } else {
9390 if (nexthop_hostname)
9391 len = vty_out(
9392 vty, "%pI6(%s)%s",
9393 &attr->mp_nexthop_local,
9394 nexthop_hostname,
9395 vrf_id_str);
9396 else
9397 len = vty_out(
9398 vty, "%pI6%s",
9399 &attr->mp_nexthop_local,
9400 vrf_id_str);
9401
9402 len = wide ? (41 - len) : (16 - len);
9403
9404 if (len < 1)
9405 vty_out(vty, "\n%*s", 36, " ");
9406 else
9407 vty_out(vty, "%*s", len, " ");
9408 }
9409 } else {
9410 if (nexthop_hostname)
9411 len = vty_out(vty, "%pI6(%s)%s",
9412 &attr->mp_nexthop_global,
9413 nexthop_hostname,
9414 vrf_id_str);
9415 else
9416 len = vty_out(vty, "%pI6%s",
9417 &attr->mp_nexthop_global,
9418 vrf_id_str);
9419
9420 len = wide ? (41 - len) : (16 - len);
9421
9422 if (len < 1)
9423 vty_out(vty, "\n%*s", 36, " ");
9424 else
9425 vty_out(vty, "%*s", len, " ");
9426 }
9427 }
9428 }
9429
9430 /* MED/Metric */
9431 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9432 if (json_paths)
9433 json_object_int_add(json_path, "metric", attr->med);
9434 else if (wide)
9435 vty_out(vty, "%7u", attr->med);
9436 else
9437 vty_out(vty, "%10u", attr->med);
9438 else if (!json_paths) {
9439 if (wide)
9440 vty_out(vty, "%*s", 7, " ");
9441 else
9442 vty_out(vty, "%*s", 10, " ");
9443 }
9444
9445 /* Local Pref */
9446 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9447 if (json_paths)
9448 json_object_int_add(json_path, "locPrf",
9449 attr->local_pref);
9450 else
9451 vty_out(vty, "%7u", attr->local_pref);
9452 else if (!json_paths)
9453 vty_out(vty, " ");
9454
9455 if (json_paths)
9456 json_object_int_add(json_path, "weight", attr->weight);
9457 else
9458 vty_out(vty, "%7u ", attr->weight);
9459
9460 if (json_paths)
9461 json_object_string_addf(json_path, "peerId", "%pSU",
9462 &path->peer->su);
9463
9464 /* Print aspath */
9465 if (attr->aspath) {
9466 if (json_paths)
9467 json_object_string_add(json_path, "path",
9468 attr->aspath->str);
9469 else
9470 aspath_print_vty(vty, attr->aspath);
9471 }
9472
9473 /* Print origin */
9474 if (json_paths)
9475 json_object_string_add(json_path, "origin",
9476 bgp_origin_long_str[attr->origin]);
9477 else
9478 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9479
9480 if (json_paths) {
9481 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9482 json_object_string_add(json_path, "esi",
9483 esi_to_str(&attr->esi,
9484 esi_buf, sizeof(esi_buf)));
9485 }
9486 if (safi == SAFI_EVPN &&
9487 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9488 json_ext_community = json_object_new_object();
9489 json_object_string_add(
9490 json_ext_community, "string",
9491 bgp_attr_get_ecommunity(attr)->str);
9492 json_object_object_add(json_path,
9493 "extendedCommunity",
9494 json_ext_community);
9495 }
9496
9497 if (nexthop_self)
9498 json_object_boolean_true_add(json_path,
9499 "announceNexthopSelf");
9500 if (nexthop_othervrf) {
9501 json_object_string_add(json_path, "nhVrfName",
9502 nexthop_vrfname);
9503
9504 json_object_int_add(json_path, "nhVrfId",
9505 ((nexthop_vrfid == VRF_UNKNOWN)
9506 ? -1
9507 : (int)nexthop_vrfid));
9508 }
9509 }
9510
9511 if (json_paths) {
9512 if (json_nexthop_global || json_nexthop_ll) {
9513 json_nexthops = json_object_new_array();
9514
9515 if (json_nexthop_global)
9516 json_object_array_add(json_nexthops,
9517 json_nexthop_global);
9518
9519 if (json_nexthop_ll)
9520 json_object_array_add(json_nexthops,
9521 json_nexthop_ll);
9522
9523 json_object_object_add(json_path, "nexthops",
9524 json_nexthops);
9525 }
9526
9527 json_object_array_add(json_paths, json_path);
9528 } else {
9529 vty_out(vty, "\n");
9530
9531 if (safi == SAFI_EVPN) {
9532 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9533 /* XXX - add these params to the json out */
9534 vty_out(vty, "%*s", 20, " ");
9535 vty_out(vty, "ESI:%s",
9536 esi_to_str(&attr->esi, esi_buf,
9537 sizeof(esi_buf)));
9538
9539 vty_out(vty, "\n");
9540 }
9541 if (attr->flag &
9542 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9543 vty_out(vty, "%*s", 20, " ");
9544 vty_out(vty, "%s\n",
9545 bgp_attr_get_ecommunity(attr)->str);
9546 }
9547 }
9548
9549 #ifdef ENABLE_BGP_VNC
9550 /* prints an additional line, indented, with VNC info, if
9551 * present */
9552 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9553 rfapi_vty_out_vncinfo(vty, p, path, safi);
9554 #endif
9555 }
9556 }
9557
9558 /* called from terminal list command */
9559 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9560 const struct prefix *p, struct attr *attr, safi_t safi,
9561 bool use_json, json_object *json_ar, bool wide)
9562 {
9563 json_object *json_status = NULL;
9564 json_object *json_net = NULL;
9565 int len;
9566 char buff[BUFSIZ];
9567
9568 /* Route status display. */
9569 if (use_json) {
9570 json_status = json_object_new_object();
9571 json_net = json_object_new_object();
9572 } else {
9573 vty_out(vty, " *");
9574 vty_out(vty, ">");
9575 vty_out(vty, " ");
9576 }
9577
9578 /* print prefix and mask */
9579 if (use_json) {
9580 if (safi == SAFI_EVPN)
9581 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9582 else if (p->family == AF_INET || p->family == AF_INET6) {
9583 json_object_string_add(
9584 json_net, "addrPrefix",
9585 inet_ntop(p->family, &p->u.prefix, buff,
9586 BUFSIZ));
9587 json_object_int_add(json_net, "prefixLen",
9588 p->prefixlen);
9589 json_object_string_addf(json_net, "network", "%pFX", p);
9590 }
9591 } else
9592 route_vty_out_route(dest, p, vty, NULL, wide);
9593
9594 /* Print attribute */
9595 if (attr) {
9596 if (use_json) {
9597 if (p->family == AF_INET &&
9598 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9599 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9600 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9601 json_object_string_addf(
9602 json_net, "nextHop", "%pI4",
9603 &attr->mp_nexthop_global_in);
9604 else
9605 json_object_string_addf(
9606 json_net, "nextHop", "%pI4",
9607 &attr->nexthop);
9608 } else if (p->family == AF_INET6 ||
9609 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9610 json_object_string_addf(
9611 json_net, "nextHopGlobal", "%pI6",
9612 &attr->mp_nexthop_global);
9613 } else if (p->family == AF_EVPN &&
9614 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9615 json_object_string_addf(
9616 json_net, "nextHop", "%pI4",
9617 &attr->mp_nexthop_global_in);
9618 }
9619
9620 if (attr->flag
9621 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9622 json_object_int_add(json_net, "metric",
9623 attr->med);
9624
9625 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9626 json_object_int_add(json_net, "locPrf",
9627 attr->local_pref);
9628
9629 json_object_int_add(json_net, "weight", attr->weight);
9630
9631 /* Print aspath */
9632 if (attr->aspath)
9633 json_object_string_add(json_net, "path",
9634 attr->aspath->str);
9635
9636 /* Print origin */
9637 #if CONFDATE > 20231208
9638 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9639 #endif
9640 json_object_string_add(json_net, "bgpOriginCode",
9641 bgp_origin_str[attr->origin]);
9642 json_object_string_add(
9643 json_net, "origin",
9644 bgp_origin_long_str[attr->origin]);
9645 } else {
9646 if (p->family == AF_INET &&
9647 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9648 safi == SAFI_EVPN ||
9649 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9650 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9651 || safi == SAFI_EVPN)
9652 vty_out(vty, "%-16pI4",
9653 &attr->mp_nexthop_global_in);
9654 else if (wide)
9655 vty_out(vty, "%-41pI4", &attr->nexthop);
9656 else
9657 vty_out(vty, "%-16pI4", &attr->nexthop);
9658 } else if (p->family == AF_INET6 ||
9659 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9660 len = vty_out(vty, "%pI6",
9661 &attr->mp_nexthop_global);
9662 len = wide ? (41 - len) : (16 - len);
9663 if (len < 1)
9664 vty_out(vty, "\n%*s", 36, " ");
9665 else
9666 vty_out(vty, "%*s", len, " ");
9667 }
9668 if (attr->flag
9669 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9670 if (wide)
9671 vty_out(vty, "%7u", attr->med);
9672 else
9673 vty_out(vty, "%10u", attr->med);
9674 else if (wide)
9675 vty_out(vty, " ");
9676 else
9677 vty_out(vty, " ");
9678
9679 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9680 vty_out(vty, "%7u", attr->local_pref);
9681 else
9682 vty_out(vty, " ");
9683
9684 vty_out(vty, "%7u ", attr->weight);
9685
9686 /* Print aspath */
9687 if (attr->aspath)
9688 aspath_print_vty(vty, attr->aspath);
9689
9690 /* Print origin */
9691 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9692 }
9693 }
9694 if (use_json) {
9695 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9696
9697 #if CONFDATE > 20231208
9698 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9699 #endif
9700 json_object_boolean_true_add(json_status, "*");
9701 json_object_boolean_true_add(json_status, ">");
9702 json_object_boolean_true_add(json_net, "valid");
9703 json_object_boolean_true_add(json_net, "best");
9704
9705 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9706 json_object_boolean_true_add(json_status, "=");
9707 json_object_boolean_true_add(json_net, "multipath");
9708 }
9709 json_object_object_add(json_net, "appliedStatusSymbols",
9710 json_status);
9711 json_object_object_addf(json_ar, json_net, "%pFX", p);
9712 } else
9713 vty_out(vty, "\n");
9714 }
9715
9716 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9717 struct bgp_path_info *path, int display, safi_t safi,
9718 json_object *json)
9719 {
9720 json_object *json_out = NULL;
9721 struct attr *attr;
9722 mpls_label_t label = MPLS_INVALID_LABEL;
9723
9724 if (!path->extra)
9725 return;
9726
9727 if (json)
9728 json_out = json_object_new_object();
9729
9730 /* short status lead text */
9731 route_vty_short_status_out(vty, path, p, json_out);
9732
9733 /* print prefix and mask */
9734 if (json == NULL) {
9735 if (!display)
9736 route_vty_out_route(path->net, p, vty, NULL, false);
9737 else
9738 vty_out(vty, "%*s", 17, " ");
9739 }
9740
9741 /* Print attribute */
9742 attr = path->attr;
9743 if (((p->family == AF_INET) &&
9744 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9745 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9746 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9747 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9748 || safi == SAFI_EVPN) {
9749 if (json)
9750 json_object_string_addf(
9751 json_out, "mpNexthopGlobalIn", "%pI4",
9752 &attr->mp_nexthop_global_in);
9753 else
9754 vty_out(vty, "%-16pI4",
9755 &attr->mp_nexthop_global_in);
9756 } else {
9757 if (json)
9758 json_object_string_addf(json_out, "nexthop",
9759 "%pI4", &attr->nexthop);
9760 else
9761 vty_out(vty, "%-16pI4", &attr->nexthop);
9762 }
9763 } else if (((p->family == AF_INET6) &&
9764 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9765 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9766 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9767 char buf_a[512];
9768
9769 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9770 if (json)
9771 json_object_string_addf(
9772 json_out, "mpNexthopGlobalIn", "%pI6",
9773 &attr->mp_nexthop_global);
9774 else
9775 vty_out(vty, "%s",
9776 inet_ntop(AF_INET6,
9777 &attr->mp_nexthop_global,
9778 buf_a, sizeof(buf_a)));
9779 } else if (attr->mp_nexthop_len
9780 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9781 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9782 &attr->mp_nexthop_global,
9783 &attr->mp_nexthop_local);
9784 if (json)
9785 json_object_string_add(json_out,
9786 "mpNexthopGlobalLocal",
9787 buf_a);
9788 else
9789 vty_out(vty, "%s", buf_a);
9790 }
9791 }
9792
9793 label = decode_label(&path->extra->label[0]);
9794
9795 if (bgp_is_valid_label(&label)) {
9796 if (json) {
9797 json_object_int_add(json_out, "notag", label);
9798 json_object_array_add(json, json_out);
9799 } else {
9800 vty_out(vty, "notag/%d", label);
9801 vty_out(vty, "\n");
9802 }
9803 } else if (!json)
9804 vty_out(vty, "\n");
9805 }
9806
9807 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9808 struct bgp_path_info *path, int display,
9809 json_object *json_paths)
9810 {
9811 struct attr *attr;
9812 json_object *json_path = NULL;
9813 json_object *json_nexthop = NULL;
9814 json_object *json_overlay = NULL;
9815
9816 if (!path->extra)
9817 return;
9818
9819 if (json_paths) {
9820 json_path = json_object_new_object();
9821 json_overlay = json_object_new_object();
9822 json_nexthop = json_object_new_object();
9823 }
9824
9825 /* short status lead text */
9826 route_vty_short_status_out(vty, path, p, json_path);
9827
9828 /* print prefix and mask */
9829 if (!display)
9830 route_vty_out_route(path->net, p, vty, json_path, false);
9831 else
9832 vty_out(vty, "%*s", 17, " ");
9833
9834 /* Print attribute */
9835 attr = path->attr;
9836 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9837
9838 switch (af) {
9839 case AF_INET:
9840 if (!json_path) {
9841 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9842 } else {
9843 json_object_string_addf(json_nexthop, "ip", "%pI4",
9844 &attr->mp_nexthop_global_in);
9845
9846 json_object_string_add(json_nexthop, "afi", "ipv4");
9847
9848 json_object_object_add(json_path, "nexthop",
9849 json_nexthop);
9850 }
9851 break;
9852 case AF_INET6:
9853 if (!json_path) {
9854 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9855 &attr->mp_nexthop_local);
9856 } else {
9857 json_object_string_addf(json_nexthop, "ipv6Global",
9858 "%pI6",
9859 &attr->mp_nexthop_global);
9860
9861 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9862 "%pI6",
9863 &attr->mp_nexthop_local);
9864
9865 json_object_string_add(json_nexthop, "afi", "ipv6");
9866
9867 json_object_object_add(json_path, "nexthop",
9868 json_nexthop);
9869 }
9870 break;
9871 default:
9872 if (!json_path) {
9873 vty_out(vty, "?");
9874 } else {
9875 json_object_string_add(json_nexthop, "error",
9876 "Unsupported address-family");
9877 }
9878 }
9879
9880 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9881
9882 if (!json_path)
9883 vty_out(vty, "/%pIA", &eo->gw_ip);
9884 else
9885 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9886
9887 if (bgp_attr_get_ecommunity(attr)) {
9888 char *mac = NULL;
9889 struct ecommunity_val *routermac = ecommunity_lookup(
9890 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9891 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9892
9893 if (routermac)
9894 mac = ecom_mac2str((char *)routermac->val);
9895 if (mac) {
9896 if (!json_path) {
9897 vty_out(vty, "/%s", mac);
9898 } else {
9899 json_object_string_add(json_overlay, "rmac",
9900 mac);
9901 }
9902 XFREE(MTYPE_TMP, mac);
9903 }
9904 }
9905
9906 if (!json_path) {
9907 vty_out(vty, "\n");
9908 } else {
9909 json_object_object_add(json_path, "overlay", json_overlay);
9910
9911 json_object_array_add(json_paths, json_path);
9912 }
9913 }
9914
9915 /* dampening route */
9916 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9917 struct bgp_path_info *path, int display,
9918 afi_t afi, safi_t safi, bool use_json,
9919 json_object *json_paths)
9920 {
9921 struct attr *attr = path->attr;
9922 int len;
9923 char timebuf[BGP_UPTIME_LEN];
9924 json_object *json_path = NULL;
9925
9926 if (use_json)
9927 json_path = json_object_new_object();
9928
9929 /* short status lead text */
9930 route_vty_short_status_out(vty, path, p, json_path);
9931
9932 /* print prefix and mask */
9933 if (!use_json) {
9934 if (!display)
9935 route_vty_out_route(path->net, p, vty, NULL, false);
9936 else
9937 vty_out(vty, "%*s", 17, " ");
9938
9939 len = vty_out(vty, "%s", path->peer->host);
9940 len = 17 - len;
9941
9942 if (len < 1)
9943 vty_out(vty, "\n%*s", 34, " ");
9944 else
9945 vty_out(vty, "%*s", len, " ");
9946
9947 vty_out(vty, "%s ",
9948 bgp_damp_reuse_time_vty(vty, path, timebuf,
9949 BGP_UPTIME_LEN, afi, safi,
9950 use_json, NULL));
9951
9952 if (attr->aspath)
9953 aspath_print_vty(vty, attr->aspath);
9954
9955 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9956
9957 vty_out(vty, "\n");
9958 } else {
9959 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9960 safi, use_json, json_path);
9961
9962 if (attr->aspath)
9963 json_object_string_add(json_path, "asPath",
9964 attr->aspath->str);
9965
9966 json_object_string_add(json_path, "origin",
9967 bgp_origin_str[attr->origin]);
9968 json_object_string_add(json_path, "peerHost", path->peer->host);
9969
9970 json_object_array_add(json_paths, json_path);
9971 }
9972 }
9973
9974 /* flap route */
9975 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9976 struct bgp_path_info *path, int display,
9977 afi_t afi, safi_t safi, bool use_json,
9978 json_object *json_paths)
9979 {
9980 struct attr *attr = path->attr;
9981 struct bgp_damp_info *bdi;
9982 char timebuf[BGP_UPTIME_LEN];
9983 int len;
9984 json_object *json_path = NULL;
9985
9986 if (!path->extra)
9987 return;
9988
9989 if (use_json)
9990 json_path = json_object_new_object();
9991
9992 bdi = path->extra->damp_info;
9993
9994 /* short status lead text */
9995 route_vty_short_status_out(vty, path, p, json_path);
9996
9997 if (!use_json) {
9998 if (!display)
9999 route_vty_out_route(path->net, p, vty, NULL, false);
10000 else
10001 vty_out(vty, "%*s", 17, " ");
10002
10003 len = vty_out(vty, "%s", path->peer->host);
10004 len = 16 - len;
10005 if (len < 1)
10006 vty_out(vty, "\n%*s", 33, " ");
10007 else
10008 vty_out(vty, "%*s", len, " ");
10009
10010 len = vty_out(vty, "%d", bdi->flap);
10011 len = 5 - len;
10012 if (len < 1)
10013 vty_out(vty, " ");
10014 else
10015 vty_out(vty, "%*s", len, " ");
10016
10017 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10018 BGP_UPTIME_LEN, 0, NULL));
10019
10020 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10021 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10022 vty_out(vty, "%s ",
10023 bgp_damp_reuse_time_vty(vty, path, timebuf,
10024 BGP_UPTIME_LEN, afi,
10025 safi, use_json, NULL));
10026 else
10027 vty_out(vty, "%*s ", 8, " ");
10028
10029 if (attr->aspath)
10030 aspath_print_vty(vty, attr->aspath);
10031
10032 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10033
10034 vty_out(vty, "\n");
10035 } else {
10036 json_object_string_add(json_path, "peerHost", path->peer->host);
10037 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10038
10039 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10040 json_path);
10041
10042 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10043 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10044 bgp_damp_reuse_time_vty(vty, path, timebuf,
10045 BGP_UPTIME_LEN, afi, safi,
10046 use_json, json_path);
10047
10048 if (attr->aspath)
10049 json_object_string_add(json_path, "asPath",
10050 attr->aspath->str);
10051
10052 json_object_string_add(json_path, "origin",
10053 bgp_origin_str[attr->origin]);
10054
10055 json_object_array_add(json_paths, json_path);
10056 }
10057 }
10058
10059 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10060 int *first, const char *header,
10061 json_object *json_adv_to)
10062 {
10063 json_object *json_peer = NULL;
10064
10065 if (json_adv_to) {
10066 /* 'advertised-to' is a dictionary of peers we have advertised
10067 * this
10068 * prefix too. The key is the peer's IP or swpX, the value is
10069 * the
10070 * hostname if we know it and "" if not.
10071 */
10072 json_peer = json_object_new_object();
10073
10074 if (peer->hostname)
10075 json_object_string_add(json_peer, "hostname",
10076 peer->hostname);
10077
10078 if (peer->conf_if)
10079 json_object_object_add(json_adv_to, peer->conf_if,
10080 json_peer);
10081 else
10082 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10083 &peer->su);
10084 } else {
10085 if (*first) {
10086 vty_out(vty, "%s", header);
10087 *first = 0;
10088 }
10089
10090 if (peer->hostname
10091 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10092 if (peer->conf_if)
10093 vty_out(vty, " %s(%s)", peer->hostname,
10094 peer->conf_if);
10095 else
10096 vty_out(vty, " %s(%pSU)", peer->hostname,
10097 &peer->su);
10098 } else {
10099 if (peer->conf_if)
10100 vty_out(vty, " %s", peer->conf_if);
10101 else
10102 vty_out(vty, " %pSU", &peer->su);
10103 }
10104 }
10105 }
10106
10107 static void route_vty_out_tx_ids(struct vty *vty,
10108 struct bgp_addpath_info_data *d)
10109 {
10110 int i;
10111
10112 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10113 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10114 d->addpath_tx_id[i],
10115 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10116 }
10117 }
10118
10119 static void route_vty_out_detail_es_info(struct vty *vty,
10120 struct bgp_path_info *pi,
10121 struct attr *attr,
10122 json_object *json_path)
10123 {
10124 char esi_buf[ESI_STR_LEN];
10125 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10126 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10127 ATTR_ES_PEER_ROUTER);
10128 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10129 ATTR_ES_PEER_ACTIVE);
10130 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10131 ATTR_ES_PEER_PROXY);
10132 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10133 if (json_path) {
10134 json_object *json_es_info = NULL;
10135
10136 json_object_string_add(
10137 json_path, "esi",
10138 esi_buf);
10139 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10140 json_es_info = json_object_new_object();
10141 if (es_local)
10142 json_object_boolean_true_add(
10143 json_es_info, "localEs");
10144 if (peer_active)
10145 json_object_boolean_true_add(
10146 json_es_info, "peerActive");
10147 if (peer_proxy)
10148 json_object_boolean_true_add(
10149 json_es_info, "peerProxy");
10150 if (peer_router)
10151 json_object_boolean_true_add(
10152 json_es_info, "peerRouter");
10153 if (attr->mm_sync_seqnum)
10154 json_object_int_add(
10155 json_es_info, "peerSeq",
10156 attr->mm_sync_seqnum);
10157 json_object_object_add(
10158 json_path, "es_info",
10159 json_es_info);
10160 }
10161 } else {
10162 if (bgp_evpn_attr_is_sync(attr))
10163 vty_out(vty,
10164 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10165 esi_buf,
10166 es_local ? "local-es":"",
10167 peer_proxy ? "proxy " : "",
10168 peer_active ? "active ":"",
10169 peer_router ? "router ":"",
10170 attr->mm_sync_seqnum);
10171 else
10172 vty_out(vty, " ESI %s %s\n",
10173 esi_buf,
10174 es_local ? "local-es":"");
10175 }
10176 }
10177
10178 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10179 const struct prefix *p, struct bgp_path_info *path,
10180 afi_t afi, safi_t safi,
10181 enum rpki_states rpki_curr_state,
10182 json_object *json_paths)
10183 {
10184 char buf[INET6_ADDRSTRLEN];
10185 char tag_buf[30];
10186 struct attr *attr = path->attr;
10187 time_t tbuf;
10188 json_object *json_bestpath = NULL;
10189 json_object *json_cluster_list = NULL;
10190 json_object *json_cluster_list_list = NULL;
10191 json_object *json_ext_community = NULL;
10192 json_object *json_last_update = NULL;
10193 json_object *json_pmsi = NULL;
10194 json_object *json_nexthop_global = NULL;
10195 json_object *json_nexthop_ll = NULL;
10196 json_object *json_nexthops = NULL;
10197 json_object *json_path = NULL;
10198 json_object *json_peer = NULL;
10199 json_object *json_string = NULL;
10200 json_object *json_adv_to = NULL;
10201 int first = 0;
10202 struct listnode *node, *nnode;
10203 struct peer *peer;
10204 bool addpath_capable;
10205 int has_adj;
10206 unsigned int first_as;
10207 bool nexthop_self =
10208 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10209 int i;
10210 char *nexthop_hostname =
10211 bgp_nexthop_hostname(path->peer, path->nexthop);
10212 uint32_t ttl = 0;
10213 uint32_t bos = 0;
10214 uint32_t exp = 0;
10215 mpls_label_t label = MPLS_INVALID_LABEL;
10216 tag_buf[0] = '\0';
10217 struct bgp_path_info *bpi_ultimate =
10218 bgp_get_imported_bpi_ultimate(path);
10219
10220 if (json_paths) {
10221 json_path = json_object_new_object();
10222 json_peer = json_object_new_object();
10223 json_nexthop_global = json_object_new_object();
10224 }
10225
10226 if (safi == SAFI_EVPN) {
10227 if (!json_paths)
10228 vty_out(vty, " Route %pFX", p);
10229 }
10230
10231 if (path->extra) {
10232 if (path->extra && path->extra->num_labels) {
10233 bgp_evpn_label2str(path->extra->label,
10234 path->extra->num_labels, tag_buf,
10235 sizeof(tag_buf));
10236 }
10237 if (safi == SAFI_EVPN) {
10238 if (!json_paths) {
10239 if (tag_buf[0] != '\0')
10240 vty_out(vty, " VNI %s", tag_buf);
10241 } else {
10242 if (tag_buf[0])
10243 json_object_string_add(json_path, "vni",
10244 tag_buf);
10245 }
10246 }
10247 }
10248
10249 if (safi == SAFI_EVPN
10250 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10251 char gwip_buf[INET6_ADDRSTRLEN];
10252
10253 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10254 sizeof(gwip_buf));
10255
10256 if (json_paths)
10257 json_object_string_add(json_path, "gatewayIP",
10258 gwip_buf);
10259 else
10260 vty_out(vty, " Gateway IP %s", gwip_buf);
10261 }
10262
10263 if (safi == SAFI_EVPN && !json_path)
10264 vty_out(vty, "\n");
10265
10266
10267 if (path->extra && path->extra->parent && !json_paths) {
10268 struct bgp_path_info *parent_ri;
10269 struct bgp_dest *dest, *pdest;
10270
10271 parent_ri = (struct bgp_path_info *)path->extra->parent;
10272 dest = parent_ri->net;
10273 if (dest && dest->pdest) {
10274 pdest = dest->pdest;
10275 if (is_pi_family_evpn(parent_ri)) {
10276 vty_out(vty, " Imported from ");
10277 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10278 (struct prefix_rd *)bgp_dest_get_prefix(
10279 pdest));
10280 vty_out(vty, ":%pFX, VNI %s",
10281 (struct prefix_evpn *)
10282 bgp_dest_get_prefix(dest),
10283 tag_buf);
10284 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10285 vty_out(vty, ", L3NHG %s",
10286 CHECK_FLAG(
10287 attr->es_flags,
10288 ATTR_ES_L3_NHG_ACTIVE)
10289 ? "active"
10290 : "inactive");
10291 vty_out(vty, "\n");
10292
10293 } else {
10294 vty_out(vty, " Imported from ");
10295 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10296 (struct prefix_rd *)bgp_dest_get_prefix(
10297 pdest));
10298 vty_out(vty, ":%pFX\n",
10299 (struct prefix_evpn *)
10300 bgp_dest_get_prefix(dest));
10301 }
10302 }
10303 }
10304
10305 /* Line1 display AS-path, Aggregator */
10306 if (attr->aspath) {
10307 if (json_paths) {
10308 if (!attr->aspath->json)
10309 aspath_str_update(attr->aspath, true);
10310 json_object_lock(attr->aspath->json);
10311 json_object_object_add(json_path, "aspath",
10312 attr->aspath->json);
10313 } else {
10314 if (attr->aspath->segments)
10315 vty_out(vty, " %s", attr->aspath->str);
10316 else
10317 vty_out(vty, " Local");
10318 }
10319 }
10320
10321 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10322 if (json_paths)
10323 json_object_boolean_true_add(json_path, "removed");
10324 else
10325 vty_out(vty, ", (removed)");
10326 }
10327
10328 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10329 if (json_paths)
10330 json_object_boolean_true_add(json_path, "stale");
10331 else
10332 vty_out(vty, ", (stale)");
10333 }
10334
10335 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10336 if (json_paths) {
10337 json_object_int_add(json_path, "aggregatorAs",
10338 attr->aggregator_as);
10339 json_object_string_addf(json_path, "aggregatorId",
10340 "%pI4", &attr->aggregator_addr);
10341 } else {
10342 vty_out(vty, ", (aggregated by %u %pI4)",
10343 attr->aggregator_as, &attr->aggregator_addr);
10344 }
10345 }
10346
10347 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10348 PEER_FLAG_REFLECTOR_CLIENT)) {
10349 if (json_paths)
10350 json_object_boolean_true_add(json_path,
10351 "rxedFromRrClient");
10352 else
10353 vty_out(vty, ", (Received from a RR-client)");
10354 }
10355
10356 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10357 PEER_FLAG_RSERVER_CLIENT)) {
10358 if (json_paths)
10359 json_object_boolean_true_add(json_path,
10360 "rxedFromRsClient");
10361 else
10362 vty_out(vty, ", (Received from a RS-client)");
10363 }
10364
10365 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10366 if (json_paths)
10367 json_object_boolean_true_add(json_path,
10368 "dampeningHistoryEntry");
10369 else
10370 vty_out(vty, ", (history entry)");
10371 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10372 if (json_paths)
10373 json_object_boolean_true_add(json_path,
10374 "dampeningSuppressed");
10375 else
10376 vty_out(vty, ", (suppressed due to dampening)");
10377 }
10378
10379 if (!json_paths)
10380 vty_out(vty, "\n");
10381
10382 /* Line2 display Next-hop, Neighbor, Router-id */
10383 /* Display the nexthop */
10384
10385 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10386 p->family == AF_EVPN) &&
10387 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10388 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10389 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10390 || safi == SAFI_EVPN) {
10391 if (json_paths) {
10392 json_object_string_addf(
10393 json_nexthop_global, "ip", "%pI4",
10394 &attr->mp_nexthop_global_in);
10395
10396 if (path->peer->hostname)
10397 json_object_string_add(
10398 json_nexthop_global, "hostname",
10399 path->peer->hostname);
10400 } else {
10401 if (nexthop_hostname)
10402 vty_out(vty, " %pI4(%s)",
10403 &attr->mp_nexthop_global_in,
10404 nexthop_hostname);
10405 else
10406 vty_out(vty, " %pI4",
10407 &attr->mp_nexthop_global_in);
10408 }
10409 } else {
10410 if (json_paths) {
10411 json_object_string_addf(json_nexthop_global,
10412 "ip", "%pI4",
10413 &attr->nexthop);
10414
10415 if (path->peer->hostname)
10416 json_object_string_add(
10417 json_nexthop_global, "hostname",
10418 path->peer->hostname);
10419 } else {
10420 if (nexthop_hostname)
10421 vty_out(vty, " %pI4(%s)",
10422 &attr->nexthop,
10423 nexthop_hostname);
10424 else
10425 vty_out(vty, " %pI4",
10426 &attr->nexthop);
10427 }
10428 }
10429
10430 if (json_paths)
10431 json_object_string_add(json_nexthop_global, "afi",
10432 "ipv4");
10433 } else {
10434 if (json_paths) {
10435 json_object_string_addf(json_nexthop_global, "ip",
10436 "%pI6",
10437 &attr->mp_nexthop_global);
10438
10439 if (path->peer->hostname)
10440 json_object_string_add(json_nexthop_global,
10441 "hostname",
10442 path->peer->hostname);
10443
10444 json_object_string_add(json_nexthop_global, "afi",
10445 "ipv6");
10446 json_object_string_add(json_nexthop_global, "scope",
10447 "global");
10448 } else {
10449 if (nexthop_hostname)
10450 vty_out(vty, " %pI6(%s)",
10451 &attr->mp_nexthop_global,
10452 nexthop_hostname);
10453 else
10454 vty_out(vty, " %pI6",
10455 &attr->mp_nexthop_global);
10456 }
10457 }
10458
10459 /* Display the IGP cost or 'inaccessible' */
10460 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10461 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10462
10463 if (json_paths) {
10464 json_object_boolean_false_add(json_nexthop_global,
10465 "accessible");
10466 json_object_boolean_add(json_nexthop_global,
10467 "importCheckEnabled", import);
10468 } else {
10469 vty_out(vty, " (inaccessible%s)",
10470 import ? ", import-check enabled" : "");
10471 }
10472 } else {
10473 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10474 if (json_paths)
10475 json_object_int_add(
10476 json_nexthop_global, "metric",
10477 bpi_ultimate->extra->igpmetric);
10478 else
10479 vty_out(vty, " (metric %u)",
10480 bpi_ultimate->extra->igpmetric);
10481 }
10482
10483 /* IGP cost is 0, display this only for json */
10484 else {
10485 if (json_paths)
10486 json_object_int_add(json_nexthop_global,
10487 "metric", 0);
10488 }
10489
10490 if (json_paths)
10491 json_object_boolean_true_add(json_nexthop_global,
10492 "accessible");
10493 }
10494
10495 /* Display peer "from" output */
10496 /* This path was originated locally */
10497 if (path->peer == bgp->peer_self) {
10498
10499 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10500 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10501 if (json_paths)
10502 json_object_string_add(json_peer, "peerId",
10503 "0.0.0.0");
10504 else
10505 vty_out(vty, " from 0.0.0.0 ");
10506 } else {
10507 if (json_paths)
10508 json_object_string_add(json_peer, "peerId",
10509 "::");
10510 else
10511 vty_out(vty, " from :: ");
10512 }
10513
10514 if (json_paths)
10515 json_object_string_addf(json_peer, "routerId", "%pI4",
10516 &bgp->router_id);
10517 else
10518 vty_out(vty, "(%pI4)", &bgp->router_id);
10519 }
10520
10521 /* We RXed this path from one of our peers */
10522 else {
10523
10524 if (json_paths) {
10525 json_object_string_addf(json_peer, "peerId", "%pSU",
10526 &path->peer->su);
10527 json_object_string_addf(json_peer, "routerId", "%pI4",
10528 &path->peer->remote_id);
10529
10530 if (path->peer->hostname)
10531 json_object_string_add(json_peer, "hostname",
10532 path->peer->hostname);
10533
10534 if (path->peer->domainname)
10535 json_object_string_add(json_peer, "domainname",
10536 path->peer->domainname);
10537
10538 if (path->peer->conf_if)
10539 json_object_string_add(json_peer, "interface",
10540 path->peer->conf_if);
10541 } else {
10542 if (path->peer->conf_if) {
10543 if (path->peer->hostname
10544 && CHECK_FLAG(path->peer->bgp->flags,
10545 BGP_FLAG_SHOW_HOSTNAME))
10546 vty_out(vty, " from %s(%s)",
10547 path->peer->hostname,
10548 path->peer->conf_if);
10549 else
10550 vty_out(vty, " from %s",
10551 path->peer->conf_if);
10552 } else {
10553 if (path->peer->hostname
10554 && CHECK_FLAG(path->peer->bgp->flags,
10555 BGP_FLAG_SHOW_HOSTNAME))
10556 vty_out(vty, " from %s(%s)",
10557 path->peer->hostname,
10558 path->peer->host);
10559 else
10560 vty_out(vty, " from %pSU",
10561 &path->peer->su);
10562 }
10563
10564 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10565 vty_out(vty, " (%pI4)", &attr->originator_id);
10566 else
10567 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10568 }
10569 }
10570
10571 /*
10572 * Note when vrfid of nexthop is different from that of prefix
10573 */
10574 if (path->extra && path->extra->bgp_orig) {
10575 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10576
10577 if (json_paths) {
10578 const char *vn;
10579
10580 if (path->extra->bgp_orig->inst_type
10581 == BGP_INSTANCE_TYPE_DEFAULT)
10582 vn = VRF_DEFAULT_NAME;
10583 else
10584 vn = path->extra->bgp_orig->name;
10585
10586 json_object_string_add(json_path, "nhVrfName", vn);
10587
10588 if (nexthop_vrfid == VRF_UNKNOWN) {
10589 json_object_int_add(json_path, "nhVrfId", -1);
10590 } else {
10591 json_object_int_add(json_path, "nhVrfId",
10592 (int)nexthop_vrfid);
10593 }
10594 } else {
10595 if (nexthop_vrfid == VRF_UNKNOWN)
10596 vty_out(vty, " vrf ?");
10597 else {
10598 struct vrf *vrf;
10599
10600 vrf = vrf_lookup_by_id(nexthop_vrfid);
10601 vty_out(vty, " vrf %s(%u)",
10602 VRF_LOGNAME(vrf), nexthop_vrfid);
10603 }
10604 }
10605 }
10606
10607 if (nexthop_self) {
10608 if (json_paths) {
10609 json_object_boolean_true_add(json_path,
10610 "announceNexthopSelf");
10611 } else {
10612 vty_out(vty, " announce-nh-self");
10613 }
10614 }
10615
10616 if (!json_paths)
10617 vty_out(vty, "\n");
10618
10619 /* display the link-local nexthop */
10620 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10621 if (json_paths) {
10622 json_nexthop_ll = json_object_new_object();
10623 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10624 &attr->mp_nexthop_local);
10625
10626 if (path->peer->hostname)
10627 json_object_string_add(json_nexthop_ll,
10628 "hostname",
10629 path->peer->hostname);
10630
10631 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10632 json_object_string_add(json_nexthop_ll, "scope",
10633 "link-local");
10634
10635 json_object_boolean_true_add(json_nexthop_ll,
10636 "accessible");
10637
10638 if (!attr->mp_nexthop_prefer_global)
10639 json_object_boolean_true_add(json_nexthop_ll,
10640 "used");
10641 else
10642 json_object_boolean_true_add(
10643 json_nexthop_global, "used");
10644 } else {
10645 vty_out(vty, " (%s) %s\n",
10646 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10647 buf, INET6_ADDRSTRLEN),
10648 attr->mp_nexthop_prefer_global
10649 ? "(prefer-global)"
10650 : "(used)");
10651 }
10652 }
10653 /* If we do not have a link-local nexthop then we must flag the
10654 global as "used" */
10655 else {
10656 if (json_paths)
10657 json_object_boolean_true_add(json_nexthop_global,
10658 "used");
10659 }
10660
10661 if (safi == SAFI_EVPN &&
10662 bgp_evpn_is_esi_valid(&attr->esi)) {
10663 route_vty_out_detail_es_info(vty, path, attr, json_path);
10664 }
10665
10666 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10667 * Int/Ext/Local, Atomic, best */
10668 if (json_paths)
10669 json_object_string_add(json_path, "origin",
10670 bgp_origin_long_str[attr->origin]);
10671 else
10672 vty_out(vty, " Origin %s",
10673 bgp_origin_long_str[attr->origin]);
10674
10675 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10676 if (json_paths)
10677 json_object_int_add(json_path, "metric", attr->med);
10678 else
10679 vty_out(vty, ", metric %u", attr->med);
10680 }
10681
10682 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10683 if (json_paths)
10684 json_object_int_add(json_path, "locPrf",
10685 attr->local_pref);
10686 else
10687 vty_out(vty, ", localpref %u", attr->local_pref);
10688 }
10689
10690 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10691 if (json_paths)
10692 json_object_int_add(json_path, "aigpMetric",
10693 bgp_attr_get_aigp_metric(attr));
10694 else
10695 vty_out(vty, ", aigp-metric %" PRIu64,
10696 bgp_attr_get_aigp_metric(attr));
10697 }
10698
10699 if (attr->weight != 0) {
10700 if (json_paths)
10701 json_object_int_add(json_path, "weight", attr->weight);
10702 else
10703 vty_out(vty, ", weight %u", attr->weight);
10704 }
10705
10706 if (attr->tag != 0) {
10707 if (json_paths)
10708 json_object_int_add(json_path, "tag", attr->tag);
10709 else
10710 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10711 }
10712
10713 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10714 if (json_paths)
10715 json_object_boolean_false_add(json_path, "valid");
10716 else
10717 vty_out(vty, ", invalid");
10718 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10719 if (json_paths)
10720 json_object_boolean_true_add(json_path, "valid");
10721 else
10722 vty_out(vty, ", valid");
10723 }
10724
10725 if (json_paths)
10726 json_object_int_add(json_path, "version", bn->version);
10727
10728 if (path->peer != bgp->peer_self) {
10729 if (path->peer->as == path->peer->local_as) {
10730 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10731 if (json_paths)
10732 json_object_string_add(
10733 json_peer, "type",
10734 "confed-internal");
10735 else
10736 vty_out(vty, ", confed-internal");
10737 } else {
10738 if (json_paths)
10739 json_object_string_add(
10740 json_peer, "type", "internal");
10741 else
10742 vty_out(vty, ", internal");
10743 }
10744 } else {
10745 if (bgp_confederation_peers_check(bgp,
10746 path->peer->as)) {
10747 if (json_paths)
10748 json_object_string_add(
10749 json_peer, "type",
10750 "confed-external");
10751 else
10752 vty_out(vty, ", confed-external");
10753 } else {
10754 if (json_paths)
10755 json_object_string_add(
10756 json_peer, "type", "external");
10757 else
10758 vty_out(vty, ", external");
10759 }
10760 }
10761 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10762 if (json_paths) {
10763 json_object_boolean_true_add(json_path, "aggregated");
10764 json_object_boolean_true_add(json_path, "local");
10765 } else {
10766 vty_out(vty, ", aggregated, local");
10767 }
10768 } else if (path->type != ZEBRA_ROUTE_BGP) {
10769 if (json_paths)
10770 json_object_boolean_true_add(json_path, "sourced");
10771 else
10772 vty_out(vty, ", sourced");
10773 } else {
10774 if (json_paths) {
10775 json_object_boolean_true_add(json_path, "sourced");
10776 json_object_boolean_true_add(json_path, "local");
10777 } else {
10778 vty_out(vty, ", sourced, local");
10779 }
10780 }
10781
10782 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10783 if (json_paths)
10784 json_object_boolean_true_add(json_path,
10785 "atomicAggregate");
10786 else
10787 vty_out(vty, ", atomic-aggregate");
10788 }
10789
10790 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10791 if (json_paths)
10792 json_object_int_add(json_path, "otc", attr->otc);
10793 else
10794 vty_out(vty, ", otc %u", attr->otc);
10795 }
10796
10797 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10798 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10799 && bgp_path_info_mpath_count(path))) {
10800 if (json_paths)
10801 json_object_boolean_true_add(json_path, "multipath");
10802 else
10803 vty_out(vty, ", multipath");
10804 }
10805
10806 // Mark the bestpath(s)
10807 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10808 first_as = aspath_get_first_as(attr->aspath);
10809
10810 if (json_paths) {
10811 if (!json_bestpath)
10812 json_bestpath = json_object_new_object();
10813 json_object_int_add(json_bestpath, "bestpathFromAs",
10814 first_as);
10815 } else {
10816 if (first_as)
10817 vty_out(vty, ", bestpath-from-AS %u", first_as);
10818 else
10819 vty_out(vty, ", bestpath-from-AS Local");
10820 }
10821 }
10822
10823 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10824 if (json_paths) {
10825 if (!json_bestpath)
10826 json_bestpath = json_object_new_object();
10827 json_object_boolean_true_add(json_bestpath, "overall");
10828 json_object_string_add(
10829 json_bestpath, "selectionReason",
10830 bgp_path_selection_reason2str(bn->reason));
10831 } else {
10832 vty_out(vty, ", best");
10833 vty_out(vty, " (%s)",
10834 bgp_path_selection_reason2str(bn->reason));
10835 }
10836 }
10837
10838 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10839 if (json_paths)
10840 json_object_string_add(
10841 json_path, "rpkiValidationState",
10842 bgp_rpki_validation2str(rpki_curr_state));
10843 else
10844 vty_out(vty, ", rpki validation-state: %s",
10845 bgp_rpki_validation2str(rpki_curr_state));
10846 }
10847
10848 if (json_bestpath)
10849 json_object_object_add(json_path, "bestpath", json_bestpath);
10850
10851 if (!json_paths)
10852 vty_out(vty, "\n");
10853
10854 /* Line 4 display Community */
10855 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10856 if (json_paths) {
10857 if (!bgp_attr_get_community(attr)->json)
10858 community_str(bgp_attr_get_community(attr),
10859 true, true);
10860 json_object_lock(bgp_attr_get_community(attr)->json);
10861 json_object_object_add(
10862 json_path, "community",
10863 bgp_attr_get_community(attr)->json);
10864 } else {
10865 vty_out(vty, " Community: %s\n",
10866 bgp_attr_get_community(attr)->str);
10867 }
10868 }
10869
10870 /* Line 5 display Extended-community */
10871 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10872 if (json_paths) {
10873 json_ext_community = json_object_new_object();
10874 json_object_string_add(
10875 json_ext_community, "string",
10876 bgp_attr_get_ecommunity(attr)->str);
10877 json_object_object_add(json_path, "extendedCommunity",
10878 json_ext_community);
10879 } else {
10880 vty_out(vty, " Extended Community: %s\n",
10881 bgp_attr_get_ecommunity(attr)->str);
10882 }
10883 }
10884
10885 /* Line 6 display Large community */
10886 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10887 if (json_paths) {
10888 if (!bgp_attr_get_lcommunity(attr)->json)
10889 lcommunity_str(bgp_attr_get_lcommunity(attr),
10890 true, true);
10891 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10892 json_object_object_add(
10893 json_path, "largeCommunity",
10894 bgp_attr_get_lcommunity(attr)->json);
10895 } else {
10896 vty_out(vty, " Large Community: %s\n",
10897 bgp_attr_get_lcommunity(attr)->str);
10898 }
10899 }
10900
10901 /* Line 7 display Originator, Cluster-id */
10902 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10903 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10904 char buf[BUFSIZ] = {0};
10905
10906 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10907 if (json_paths)
10908 json_object_string_addf(json_path,
10909 "originatorId", "%pI4",
10910 &attr->originator_id);
10911 else
10912 vty_out(vty, " Originator: %pI4",
10913 &attr->originator_id);
10914 }
10915
10916 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10917 struct cluster_list *cluster =
10918 bgp_attr_get_cluster(attr);
10919 int i;
10920
10921 if (json_paths) {
10922 json_cluster_list = json_object_new_object();
10923 json_cluster_list_list =
10924 json_object_new_array();
10925
10926 for (i = 0; i < cluster->length / 4; i++) {
10927 json_string = json_object_new_string(
10928 inet_ntop(AF_INET,
10929 &cluster->list[i],
10930 buf, sizeof(buf)));
10931 json_object_array_add(
10932 json_cluster_list_list,
10933 json_string);
10934 }
10935
10936 /*
10937 * struct cluster_list does not have
10938 * "str" variable like aspath and community
10939 * do. Add this someday if someone asks
10940 * for it.
10941 * json_object_string_add(json_cluster_list,
10942 * "string", cluster->str);
10943 */
10944 json_object_object_add(json_cluster_list,
10945 "list",
10946 json_cluster_list_list);
10947 json_object_object_add(json_path, "clusterList",
10948 json_cluster_list);
10949 } else {
10950 vty_out(vty, ", Cluster list: ");
10951
10952 for (i = 0; i < cluster->length / 4; i++) {
10953 vty_out(vty, "%pI4 ",
10954 &cluster->list[i]);
10955 }
10956 }
10957 }
10958
10959 if (!json_paths)
10960 vty_out(vty, "\n");
10961 }
10962
10963 if (path->extra && path->extra->damp_info)
10964 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10965
10966 /* Remote Label */
10967 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10968 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10969 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10970 &bos);
10971
10972 if (json_paths)
10973 json_object_int_add(json_path, "remoteLabel", label);
10974 else
10975 vty_out(vty, " Remote label: %d\n", label);
10976 }
10977
10978 /* Remote SID */
10979 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10980 if (json_paths)
10981 json_object_string_addf(json_path, "remoteSid", "%pI6",
10982 &path->extra->sid[0].sid);
10983 else
10984 vty_out(vty, " Remote SID: %pI6\n",
10985 &path->extra->sid[0].sid);
10986 }
10987
10988 /* Label Index */
10989 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10990 if (json_paths)
10991 json_object_int_add(json_path, "labelIndex",
10992 attr->label_index);
10993 else
10994 vty_out(vty, " Label Index: %d\n",
10995 attr->label_index);
10996 }
10997
10998 /* Line 8 display Addpath IDs */
10999 if (path->addpath_rx_id
11000 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11001 if (json_paths) {
11002 json_object_int_add(json_path, "addpathRxId",
11003 path->addpath_rx_id);
11004
11005 /* Keep backwards compatibility with the old API
11006 * by putting TX All's ID in the old field
11007 */
11008 json_object_int_add(
11009 json_path, "addpathTxId",
11010 path->tx_addpath
11011 .addpath_tx_id[BGP_ADDPATH_ALL]);
11012
11013 /* ... but create a specific field for each
11014 * strategy
11015 */
11016 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11017 json_object_int_add(
11018 json_path,
11019 bgp_addpath_names(i)->id_json_name,
11020 path->tx_addpath.addpath_tx_id[i]);
11021 }
11022 } else {
11023 vty_out(vty, " AddPath ID: RX %u, ",
11024 path->addpath_rx_id);
11025
11026 route_vty_out_tx_ids(vty, &path->tx_addpath);
11027 }
11028 }
11029
11030 /* If we used addpath to TX a non-bestpath we need to display
11031 * "Advertised to" on a path-by-path basis
11032 */
11033 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11034 first = 1;
11035
11036 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11037 addpath_capable =
11038 bgp_addpath_encode_tx(peer, afi, safi);
11039 has_adj = bgp_adj_out_lookup(
11040 peer, path->net,
11041 bgp_addpath_id_for_peer(peer, afi, safi,
11042 &path->tx_addpath));
11043
11044 if ((addpath_capable && has_adj)
11045 || (!addpath_capable && has_adj
11046 && CHECK_FLAG(path->flags,
11047 BGP_PATH_SELECTED))) {
11048 if (json_path && !json_adv_to)
11049 json_adv_to = json_object_new_object();
11050
11051 route_vty_out_advertised_to(
11052 vty, peer, &first,
11053 " Advertised to:", json_adv_to);
11054 }
11055 }
11056
11057 if (json_path) {
11058 if (json_adv_to) {
11059 json_object_object_add(
11060 json_path, "advertisedTo", json_adv_to);
11061 }
11062 } else {
11063 if (!first) {
11064 vty_out(vty, "\n");
11065 }
11066 }
11067 }
11068
11069 /* Line 9 display Uptime */
11070 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11071 if (json_paths) {
11072 json_last_update = json_object_new_object();
11073 json_object_int_add(json_last_update, "epoch", tbuf);
11074 json_object_string_add(json_last_update, "string",
11075 ctime(&tbuf));
11076 json_object_object_add(json_path, "lastUpdate",
11077 json_last_update);
11078 } else
11079 vty_out(vty, " Last update: %s", ctime(&tbuf));
11080
11081 /* Line 10 display PMSI tunnel attribute, if present */
11082 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11083 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11084 bgp_attr_get_pmsi_tnl_type(attr),
11085 PMSI_TNLTYPE_STR_DEFAULT);
11086
11087 if (json_paths) {
11088 json_pmsi = json_object_new_object();
11089 json_object_string_add(json_pmsi, "tunnelType", str);
11090 json_object_int_add(json_pmsi, "label",
11091 label2vni(&attr->label));
11092 json_object_object_add(json_path, "pmsi", json_pmsi);
11093 } else
11094 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11095 str, label2vni(&attr->label));
11096 }
11097
11098 if (path->peer->t_gr_restart &&
11099 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11100 unsigned long gr_remaining =
11101 event_timer_remain_second(path->peer->t_gr_restart);
11102
11103 if (json_paths) {
11104 json_object_int_add(json_path,
11105 "gracefulRestartSecondsRemaining",
11106 gr_remaining);
11107 } else
11108 vty_out(vty,
11109 " Time until Graceful Restart stale route deleted: %lu\n",
11110 gr_remaining);
11111 }
11112
11113 if (path->peer->t_llgr_stale[afi][safi] &&
11114 bgp_attr_get_community(attr) &&
11115 community_include(bgp_attr_get_community(attr),
11116 COMMUNITY_LLGR_STALE)) {
11117 unsigned long llgr_remaining = event_timer_remain_second(
11118 path->peer->t_llgr_stale[afi][safi]);
11119
11120 if (json_paths) {
11121 json_object_int_add(json_path, "llgrSecondsRemaining",
11122 llgr_remaining);
11123 } else
11124 vty_out(vty,
11125 " Time until Long-lived stale route deleted: %lu\n",
11126 llgr_remaining);
11127 }
11128
11129 /* Output some debug about internal state of the dest flags */
11130 if (json_paths) {
11131 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11132 json_object_boolean_true_add(json_path, "processScheduled");
11133 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11134 json_object_boolean_true_add(json_path, "userCleared");
11135 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11136 json_object_boolean_true_add(json_path, "labelChanged");
11137 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11138 json_object_boolean_true_add(json_path, "registeredForLabel");
11139 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11140 json_object_boolean_true_add(json_path, "selectDefered");
11141 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11142 json_object_boolean_true_add(json_path, "fibInstalled");
11143 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11144 json_object_boolean_true_add(json_path, "fibPending");
11145
11146 if (json_nexthop_global || json_nexthop_ll) {
11147 json_nexthops = json_object_new_array();
11148
11149 if (json_nexthop_global)
11150 json_object_array_add(json_nexthops,
11151 json_nexthop_global);
11152
11153 if (json_nexthop_ll)
11154 json_object_array_add(json_nexthops,
11155 json_nexthop_ll);
11156
11157 json_object_object_add(json_path, "nexthops",
11158 json_nexthops);
11159 }
11160
11161 json_object_object_add(json_path, "peer", json_peer);
11162 json_object_array_add(json_paths, json_path);
11163 }
11164 }
11165
11166 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11167 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11168 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11169
11170 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11171 afi_t afi, safi_t safi, enum bgp_show_type type,
11172 bool use_json);
11173 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11174 const char *comstr, int exact, afi_t afi,
11175 safi_t safi, uint16_t show_flags);
11176
11177 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11178 struct bgp_table *table, enum bgp_show_type type,
11179 void *output_arg, const char *rd, int is_last,
11180 unsigned long *output_cum, unsigned long *total_cum,
11181 unsigned long *json_header_depth, uint16_t show_flags,
11182 enum rpki_states rpki_target_state)
11183 {
11184 struct bgp_path_info *pi;
11185 struct bgp_dest *dest;
11186 bool header = true;
11187 bool json_detail_header = false;
11188 int display;
11189 unsigned long output_count = 0;
11190 unsigned long total_count = 0;
11191 struct prefix *p;
11192 json_object *json_paths = NULL;
11193 int first = 1;
11194 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11195 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11196 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11197 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11198 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11199
11200 if (output_cum && *output_cum != 0)
11201 header = false;
11202
11203 if (use_json && !*json_header_depth) {
11204 if (all)
11205 *json_header_depth = 1;
11206 else {
11207 vty_out(vty, "{\n");
11208 *json_header_depth = 2;
11209 }
11210 vty_out(vty,
11211 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11212 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11213 " \"localAS\": ",
11214 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11215 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11216 ? VRF_DEFAULT_NAME
11217 : bgp->name,
11218 table->version, &bgp->router_id,
11219 bgp->default_local_pref);
11220 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11221 ((bgp->asnotation == ASNOTATION_DOT) &&
11222 (bgp->as < UINT16_MAX)))
11223 vty_out(vty, "%u", bgp->as);
11224 else {
11225 vty_out(vty, "\"");
11226 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11227 vty_out(vty, "\"");
11228 }
11229 vty_out(vty, ",\n \"routes\": { ");
11230 if (rd) {
11231 vty_out(vty, " \"routeDistinguishers\" : {");
11232 ++*json_header_depth;
11233 }
11234 }
11235
11236 if (use_json && rd) {
11237 vty_out(vty, " \"%s\" : { ", rd);
11238 }
11239
11240 /* Check for 'json detail', where we need header output once per dest */
11241 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11242 type != bgp_show_type_damp_neighbor &&
11243 type != bgp_show_type_flap_statistics &&
11244 type != bgp_show_type_flap_neighbor)
11245 json_detail_header = true;
11246
11247 /* Start processing of routes. */
11248 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11249 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11250 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11251 bool json_detail_header_used = false;
11252
11253 pi = bgp_dest_get_bgp_path_info(dest);
11254 if (pi == NULL)
11255 continue;
11256
11257 display = 0;
11258 if (use_json)
11259 json_paths = json_object_new_array();
11260 else
11261 json_paths = NULL;
11262
11263 for (; pi; pi = pi->next) {
11264 struct community *picomm = NULL;
11265
11266 picomm = bgp_attr_get_community(pi->attr);
11267
11268 total_count++;
11269
11270 if (type == bgp_show_type_prefix_version) {
11271 uint32_t version =
11272 strtoul(output_arg, NULL, 10);
11273 if (dest->version < version)
11274 continue;
11275 }
11276
11277 if (type == bgp_show_type_community_alias) {
11278 char *alias = output_arg;
11279 char **communities;
11280 int num;
11281 bool found = false;
11282
11283 if (picomm) {
11284 frrstr_split(picomm->str, " ",
11285 &communities, &num);
11286 for (int i = 0; i < num; i++) {
11287 const char *com2alias =
11288 bgp_community2alias(
11289 communities[i]);
11290 if (!found
11291 && strcmp(alias, com2alias)
11292 == 0)
11293 found = true;
11294 XFREE(MTYPE_TMP,
11295 communities[i]);
11296 }
11297 XFREE(MTYPE_TMP, communities);
11298 }
11299
11300 if (!found &&
11301 bgp_attr_get_lcommunity(pi->attr)) {
11302 frrstr_split(bgp_attr_get_lcommunity(
11303 pi->attr)
11304 ->str,
11305 " ", &communities, &num);
11306 for (int i = 0; i < num; i++) {
11307 const char *com2alias =
11308 bgp_community2alias(
11309 communities[i]);
11310 if (!found
11311 && strcmp(alias, com2alias)
11312 == 0)
11313 found = true;
11314 XFREE(MTYPE_TMP,
11315 communities[i]);
11316 }
11317 XFREE(MTYPE_TMP, communities);
11318 }
11319
11320 if (!found)
11321 continue;
11322 }
11323
11324 if (type == bgp_show_type_rpki) {
11325 if (dest_p->family == AF_INET
11326 || dest_p->family == AF_INET6)
11327 rpki_curr_state = hook_call(
11328 bgp_rpki_prefix_status,
11329 pi->peer, pi->attr, dest_p);
11330 if (rpki_target_state != RPKI_NOT_BEING_USED
11331 && rpki_curr_state != rpki_target_state)
11332 continue;
11333 }
11334
11335 if (type == bgp_show_type_flap_statistics
11336 || type == bgp_show_type_flap_neighbor
11337 || type == bgp_show_type_dampend_paths
11338 || type == bgp_show_type_damp_neighbor) {
11339 if (!(pi->extra && pi->extra->damp_info))
11340 continue;
11341 }
11342 if (type == bgp_show_type_regexp) {
11343 regex_t *regex = output_arg;
11344
11345 if (bgp_regexec(regex, pi->attr->aspath)
11346 == REG_NOMATCH)
11347 continue;
11348 }
11349 if (type == bgp_show_type_prefix_list) {
11350 struct prefix_list *plist = output_arg;
11351
11352 if (prefix_list_apply(plist, dest_p)
11353 != PREFIX_PERMIT)
11354 continue;
11355 }
11356 if (type == bgp_show_type_access_list) {
11357 struct access_list *alist = output_arg;
11358
11359 if (access_list_apply(alist, dest_p) !=
11360 FILTER_PERMIT)
11361 continue;
11362 }
11363 if (type == bgp_show_type_filter_list) {
11364 struct as_list *as_list = output_arg;
11365
11366 if (as_list_apply(as_list, pi->attr->aspath)
11367 != AS_FILTER_PERMIT)
11368 continue;
11369 }
11370 if (type == bgp_show_type_route_map) {
11371 struct route_map *rmap = output_arg;
11372 struct bgp_path_info path;
11373 struct bgp_path_info_extra extra;
11374 struct attr dummy_attr = {};
11375 route_map_result_t ret;
11376
11377 dummy_attr = *pi->attr;
11378
11379 prep_for_rmap_apply(&path, &extra, dest, pi,
11380 pi->peer, &dummy_attr);
11381
11382 ret = route_map_apply(rmap, dest_p, &path);
11383 bgp_attr_flush(&dummy_attr);
11384 if (ret == RMAP_DENYMATCH)
11385 continue;
11386 }
11387 if (type == bgp_show_type_neighbor
11388 || type == bgp_show_type_flap_neighbor
11389 || type == bgp_show_type_damp_neighbor) {
11390 union sockunion *su = output_arg;
11391
11392 if (pi->peer == NULL
11393 || pi->peer->su_remote == NULL
11394 || !sockunion_same(pi->peer->su_remote, su))
11395 continue;
11396 }
11397 if (type == bgp_show_type_cidr_only) {
11398 uint32_t destination;
11399
11400 destination = ntohl(dest_p->u.prefix4.s_addr);
11401 if (IN_CLASSC(destination)
11402 && dest_p->prefixlen == 24)
11403 continue;
11404 if (IN_CLASSB(destination)
11405 && dest_p->prefixlen == 16)
11406 continue;
11407 if (IN_CLASSA(destination)
11408 && dest_p->prefixlen == 8)
11409 continue;
11410 }
11411 if (type == bgp_show_type_prefix_longer) {
11412 p = output_arg;
11413 if (!prefix_match(p, dest_p))
11414 continue;
11415 }
11416 if (type == bgp_show_type_community_all) {
11417 if (!picomm)
11418 continue;
11419 }
11420 if (type == bgp_show_type_community) {
11421 struct community *com = output_arg;
11422
11423 if (!picomm || !community_match(picomm, com))
11424 continue;
11425 }
11426 if (type == bgp_show_type_community_exact) {
11427 struct community *com = output_arg;
11428
11429 if (!picomm || !community_cmp(picomm, com))
11430 continue;
11431 }
11432 if (type == bgp_show_type_community_list) {
11433 struct community_list *list = output_arg;
11434
11435 if (!community_list_match(picomm, list))
11436 continue;
11437 }
11438 if (type == bgp_show_type_community_list_exact) {
11439 struct community_list *list = output_arg;
11440
11441 if (!community_list_exact_match(picomm, list))
11442 continue;
11443 }
11444 if (type == bgp_show_type_lcommunity) {
11445 struct lcommunity *lcom = output_arg;
11446
11447 if (!bgp_attr_get_lcommunity(pi->attr) ||
11448 !lcommunity_match(
11449 bgp_attr_get_lcommunity(pi->attr),
11450 lcom))
11451 continue;
11452 }
11453
11454 if (type == bgp_show_type_lcommunity_exact) {
11455 struct lcommunity *lcom = output_arg;
11456
11457 if (!bgp_attr_get_lcommunity(pi->attr) ||
11458 !lcommunity_cmp(
11459 bgp_attr_get_lcommunity(pi->attr),
11460 lcom))
11461 continue;
11462 }
11463 if (type == bgp_show_type_lcommunity_list) {
11464 struct community_list *list = output_arg;
11465
11466 if (!lcommunity_list_match(
11467 bgp_attr_get_lcommunity(pi->attr),
11468 list))
11469 continue;
11470 }
11471 if (type
11472 == bgp_show_type_lcommunity_list_exact) {
11473 struct community_list *list = output_arg;
11474
11475 if (!lcommunity_list_exact_match(
11476 bgp_attr_get_lcommunity(pi->attr),
11477 list))
11478 continue;
11479 }
11480 if (type == bgp_show_type_lcommunity_all) {
11481 if (!bgp_attr_get_lcommunity(pi->attr))
11482 continue;
11483 }
11484 if (type == bgp_show_type_dampend_paths
11485 || type == bgp_show_type_damp_neighbor) {
11486 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11487 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11488 continue;
11489 }
11490 if (type == bgp_show_type_self_originated) {
11491 if (pi->peer != bgp->peer_self)
11492 continue;
11493 }
11494
11495 if (!use_json && header) {
11496 vty_out(vty,
11497 "BGP table version is %" PRIu64
11498 ", local router ID is %pI4, vrf id ",
11499 table->version, &bgp->router_id);
11500 if (bgp->vrf_id == VRF_UNKNOWN)
11501 vty_out(vty, "%s", VRFID_NONE_STR);
11502 else
11503 vty_out(vty, "%u", bgp->vrf_id);
11504 vty_out(vty, "\n");
11505 vty_out(vty, "Default local pref %u, ",
11506 bgp->default_local_pref);
11507 vty_out(vty, "local AS ");
11508 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11509 &bgp->as);
11510 vty_out(vty, "\n");
11511 if (!detail_routes) {
11512 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11513 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11514 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11515 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11516 }
11517 if (type == bgp_show_type_dampend_paths
11518 || type == bgp_show_type_damp_neighbor)
11519 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11520 else if (type == bgp_show_type_flap_statistics
11521 || type == bgp_show_type_flap_neighbor)
11522 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11523 else if (!detail_routes)
11524 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11525 : BGP_SHOW_HEADER));
11526 header = false;
11527
11528 }
11529 if (rd != NULL && !display && !output_count) {
11530 if (!use_json)
11531 vty_out(vty,
11532 "Route Distinguisher: %s\n",
11533 rd);
11534 }
11535 if (type == bgp_show_type_dampend_paths
11536 || type == bgp_show_type_damp_neighbor)
11537 damp_route_vty_out(vty, dest_p, pi, display,
11538 AFI_IP, safi, use_json,
11539 json_paths);
11540 else if (type == bgp_show_type_flap_statistics
11541 || type == bgp_show_type_flap_neighbor)
11542 flap_route_vty_out(vty, dest_p, pi, display,
11543 AFI_IP, safi, use_json,
11544 json_paths);
11545 else {
11546 if (detail_routes || detail_json) {
11547 const struct prefix_rd *prd = NULL;
11548
11549 if (dest->pdest)
11550 prd = bgp_rd_from_dest(
11551 dest->pdest, safi);
11552
11553 if (!use_json)
11554 route_vty_out_detail_header(
11555 vty, bgp, dest,
11556 bgp_dest_get_prefix(
11557 dest),
11558 prd, table->afi, safi,
11559 NULL, false);
11560
11561 route_vty_out_detail(
11562 vty, bgp, dest, dest_p, pi,
11563 family2afi(dest_p->family),
11564 safi, RPKI_NOT_BEING_USED,
11565 json_paths);
11566 } else {
11567 route_vty_out(vty, dest_p, pi, display,
11568 safi, json_paths, wide);
11569 }
11570 }
11571 display++;
11572 }
11573
11574 if (display) {
11575 output_count++;
11576 if (!use_json)
11577 continue;
11578
11579 /* encode prefix */
11580 if (dest_p->family == AF_FLOWSPEC) {
11581 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11582
11583
11584 bgp_fs_nlri_get_string(
11585 (unsigned char *)
11586 dest_p->u.prefix_flowspec.ptr,
11587 dest_p->u.prefix_flowspec.prefixlen,
11588 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11589 family2afi(dest_p->u
11590 .prefix_flowspec.family));
11591 if (first)
11592 vty_out(vty, "\"%s/%d\": ", retstr,
11593 dest_p->u.prefix_flowspec
11594 .prefixlen);
11595 else
11596 vty_out(vty, ",\"%s/%d\": ", retstr,
11597 dest_p->u.prefix_flowspec
11598 .prefixlen);
11599 } else {
11600 if (first)
11601 vty_out(vty, "\"%pFX\": ", dest_p);
11602 else
11603 vty_out(vty, ",\"%pFX\": ", dest_p);
11604 }
11605
11606 /* This is used for 'json detail' vty keywords.
11607 *
11608 * In plain 'json' the per-prefix header is encoded
11609 * as a standalone dictionary in the first json_paths
11610 * array element:
11611 * "<prefix>": [{header}, {path-1}, {path-N}]
11612 * (which is confusing and borderline broken)
11613 *
11614 * For 'json detail' this changes the value
11615 * of each prefix-key to be a dictionary where each
11616 * header item has its own key, and json_paths is
11617 * tucked under the "paths" key:
11618 * "<prefix>": {
11619 * "<header-key-1>": <header-val-1>,
11620 * "<header-key-N>": <header-val-N>,
11621 * "paths": [{path-1}, {path-N}]
11622 * }
11623 */
11624 if (json_detail_header && json_paths != NULL) {
11625 const struct prefix_rd *prd;
11626
11627 /* Start per-prefix dictionary */
11628 vty_out(vty, "{\n");
11629
11630 prd = bgp_rd_from_dest(dest, safi);
11631
11632 route_vty_out_detail_header(
11633 vty, bgp, dest,
11634 bgp_dest_get_prefix(dest), prd,
11635 table->afi, safi, json_paths, true);
11636
11637 vty_out(vty, "\"paths\": ");
11638 json_detail_header_used = true;
11639 }
11640
11641 /*
11642 * We are using no_pretty here because under
11643 * extremely high settings( say lots and lots of
11644 * routes with lots and lots of ways to reach
11645 * that route via different paths ) this can
11646 * save several minutes of output when FRR
11647 * is run on older cpu's or more underperforming
11648 * routers out there
11649 */
11650 vty_json_no_pretty(vty, json_paths);
11651
11652 /* End per-prefix dictionary */
11653 if (json_detail_header_used)
11654 vty_out(vty, "} ");
11655
11656 json_paths = NULL;
11657 first = 0;
11658 } else
11659 json_object_free(json_paths);
11660 }
11661
11662 if (output_cum) {
11663 output_count += *output_cum;
11664 *output_cum = output_count;
11665 }
11666 if (total_cum) {
11667 total_count += *total_cum;
11668 *total_cum = total_count;
11669 }
11670 if (use_json) {
11671 if (rd) {
11672 vty_out(vty, " }%s ", (is_last ? "" : ","));
11673 }
11674 if (is_last) {
11675 unsigned long i;
11676 for (i = 0; i < *json_header_depth; ++i)
11677 vty_out(vty, " } ");
11678 if (!all)
11679 vty_out(vty, "\n");
11680 }
11681 } else {
11682 if (is_last) {
11683 /* No route is displayed */
11684 if (output_count == 0) {
11685 if (type == bgp_show_type_normal)
11686 vty_out(vty,
11687 "No BGP prefixes displayed, %ld exist\n",
11688 total_count);
11689 } else
11690 vty_out(vty,
11691 "\nDisplayed %ld routes and %ld total paths\n",
11692 output_count, total_count);
11693 }
11694 }
11695
11696 return CMD_SUCCESS;
11697 }
11698
11699 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11700 struct bgp_table *table, struct prefix_rd *prd_match,
11701 enum bgp_show_type type, void *output_arg,
11702 uint16_t show_flags)
11703 {
11704 struct bgp_dest *dest, *next;
11705 unsigned long output_cum = 0;
11706 unsigned long total_cum = 0;
11707 unsigned long json_header_depth = 0;
11708 struct bgp_table *itable;
11709 bool show_msg;
11710 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11711
11712 show_msg = (!use_json && type == bgp_show_type_normal);
11713
11714 for (dest = bgp_table_top(table); dest; dest = next) {
11715 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11716
11717 next = bgp_route_next(dest);
11718 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11719 continue;
11720
11721 itable = bgp_dest_get_bgp_table_info(dest);
11722 if (itable != NULL) {
11723 struct prefix_rd prd;
11724 char rd[RD_ADDRSTRLEN];
11725
11726 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11727 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11728 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11729 rd, next == NULL, &output_cum,
11730 &total_cum, &json_header_depth,
11731 show_flags, RPKI_NOT_BEING_USED);
11732 if (next == NULL)
11733 show_msg = false;
11734 }
11735 }
11736 if (show_msg) {
11737 if (output_cum == 0)
11738 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11739 total_cum);
11740 else
11741 vty_out(vty,
11742 "\nDisplayed %ld routes and %ld total paths\n",
11743 output_cum, total_cum);
11744 } else {
11745 if (use_json && output_cum == 0)
11746 vty_out(vty, "{}\n");
11747 }
11748 return CMD_SUCCESS;
11749 }
11750
11751 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11752 enum bgp_show_type type, void *output_arg,
11753 uint16_t show_flags, enum rpki_states rpki_target_state)
11754 {
11755 struct bgp_table *table;
11756 unsigned long json_header_depth = 0;
11757 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11758
11759 if (bgp == NULL) {
11760 bgp = bgp_get_default();
11761 }
11762
11763 if (bgp == NULL) {
11764 if (!use_json)
11765 vty_out(vty, "No BGP process is configured\n");
11766 else
11767 vty_out(vty, "{}\n");
11768 return CMD_WARNING;
11769 }
11770
11771 /* Labeled-unicast routes live in the unicast table. */
11772 if (safi == SAFI_LABELED_UNICAST)
11773 safi = SAFI_UNICAST;
11774
11775 table = bgp->rib[afi][safi];
11776 /* use MPLS and ENCAP specific shows until they are merged */
11777 if (safi == SAFI_MPLS_VPN) {
11778 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11779 output_arg, show_flags);
11780 }
11781
11782 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11783 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11784 output_arg, use_json,
11785 1, NULL, NULL);
11786 }
11787
11788 if (safi == SAFI_EVPN)
11789 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11790
11791 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11792 NULL, NULL, &json_header_depth, show_flags,
11793 rpki_target_state);
11794 }
11795
11796 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11797 safi_t safi, uint16_t show_flags)
11798 {
11799 struct listnode *node, *nnode;
11800 struct bgp *bgp;
11801 int is_first = 1;
11802 bool route_output = false;
11803 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11804
11805 if (use_json)
11806 vty_out(vty, "{\n");
11807
11808 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11809 route_output = true;
11810 if (use_json) {
11811 if (!is_first)
11812 vty_out(vty, ",\n");
11813 else
11814 is_first = 0;
11815
11816 vty_out(vty, "\"%s\":",
11817 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11818 ? VRF_DEFAULT_NAME
11819 : bgp->name);
11820 } else {
11821 vty_out(vty, "\nInstance %s:\n",
11822 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11823 ? VRF_DEFAULT_NAME
11824 : bgp->name);
11825 }
11826 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11827 show_flags, RPKI_NOT_BEING_USED);
11828 }
11829
11830 if (use_json)
11831 vty_out(vty, "}\n");
11832 else if (!route_output)
11833 vty_out(vty, "%% BGP instance not found\n");
11834 }
11835
11836 /* Header of detailed BGP route information */
11837 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11838 struct bgp_dest *dest, const struct prefix *p,
11839 const struct prefix_rd *prd, afi_t afi,
11840 safi_t safi, json_object *json,
11841 bool incremental_print)
11842 {
11843 struct bgp_path_info *pi;
11844 struct peer *peer;
11845 struct listnode *node, *nnode;
11846 char buf1[RD_ADDRSTRLEN];
11847 int count = 0;
11848 int best = 0;
11849 int suppress = 0;
11850 int accept_own = 0;
11851 int route_filter_translated_v4 = 0;
11852 int route_filter_v4 = 0;
11853 int route_filter_translated_v6 = 0;
11854 int route_filter_v6 = 0;
11855 int llgr_stale = 0;
11856 int no_llgr = 0;
11857 int accept_own_nexthop = 0;
11858 int blackhole = 0;
11859 int no_export = 0;
11860 int no_advertise = 0;
11861 int local_as = 0;
11862 int no_peer = 0;
11863 int first = 1;
11864 int has_valid_label = 0;
11865 mpls_label_t label = 0;
11866 json_object *json_adv_to = NULL;
11867 uint32_t ttl = 0;
11868 uint32_t bos = 0;
11869 uint32_t exp = 0;
11870
11871 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11872
11873 has_valid_label = bgp_is_valid_label(&label);
11874
11875 if (safi == SAFI_EVPN) {
11876 if (!json) {
11877 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11878 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11879 bgp->asnotation)
11880 : "",
11881 prd ? ":" : "", (struct prefix_evpn *)p);
11882 } else {
11883 json_object_string_add(
11884 json, "rd",
11885 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11886 bgp->asnotation)
11887 : "");
11888 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11889 }
11890 } else {
11891 if (!json) {
11892 vty_out(vty,
11893 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11894 "\n",
11895 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11896 ? prefix_rd2str(prd, buf1,
11897 sizeof(buf1),
11898 bgp->asnotation)
11899 : ""),
11900 safi == SAFI_MPLS_VPN ? ":" : "", p,
11901 dest->version);
11902
11903 } else {
11904 if (incremental_print) {
11905 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11906 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11907 dest->version);
11908 } else {
11909 json_object_string_addf(json, "prefix", "%pFX",
11910 p);
11911 json_object_int_add(json, "version",
11912 dest->version);
11913 }
11914 }
11915 }
11916
11917 if (has_valid_label) {
11918 if (json) {
11919 if (incremental_print)
11920 vty_out(vty, "\"localLabel\": \"%u\",\n",
11921 label);
11922 else
11923 json_object_int_add(json, "localLabel", label);
11924 } else
11925 vty_out(vty, "Local label: %d\n", label);
11926 }
11927
11928 if (!json)
11929 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11930 vty_out(vty, "not allocated\n");
11931
11932 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11933 struct community *picomm = NULL;
11934
11935 picomm = bgp_attr_get_community(pi->attr);
11936
11937 count++;
11938 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11939 best = count;
11940 if (bgp_path_suppressed(pi))
11941 suppress = 1;
11942
11943 if (!picomm)
11944 continue;
11945
11946 no_advertise += community_include(
11947 picomm, COMMUNITY_NO_ADVERTISE);
11948 no_export +=
11949 community_include(picomm, COMMUNITY_NO_EXPORT);
11950 local_as +=
11951 community_include(picomm, COMMUNITY_LOCAL_AS);
11952 accept_own +=
11953 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11954 route_filter_translated_v4 += community_include(
11955 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11956 route_filter_translated_v6 += community_include(
11957 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11958 route_filter_v4 += community_include(
11959 picomm, COMMUNITY_ROUTE_FILTER_v4);
11960 route_filter_v6 += community_include(
11961 picomm, COMMUNITY_ROUTE_FILTER_v6);
11962 llgr_stale +=
11963 community_include(picomm, COMMUNITY_LLGR_STALE);
11964 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11965 accept_own_nexthop += community_include(
11966 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11967 blackhole +=
11968 community_include(picomm, COMMUNITY_BLACKHOLE);
11969 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11970 }
11971 }
11972
11973 if (!json) {
11974 vty_out(vty, "Paths: (%d available", count);
11975 if (best) {
11976 vty_out(vty, ", best #%d", best);
11977 if (safi == SAFI_UNICAST) {
11978 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11979 vty_out(vty, ", table %s",
11980 VRF_DEFAULT_NAME);
11981 else
11982 vty_out(vty, ", vrf %s",
11983 bgp->name);
11984 }
11985 } else
11986 vty_out(vty, ", no best path");
11987
11988 if (accept_own)
11989 vty_out(vty,
11990 ", accept own local route exported and imported in different VRF");
11991 else if (route_filter_translated_v4)
11992 vty_out(vty,
11993 ", mark translated RTs for VPNv4 route filtering");
11994 else if (route_filter_v4)
11995 vty_out(vty,
11996 ", attach RT as-is for VPNv4 route filtering");
11997 else if (route_filter_translated_v6)
11998 vty_out(vty,
11999 ", mark translated RTs for VPNv6 route filtering");
12000 else if (route_filter_v6)
12001 vty_out(vty,
12002 ", attach RT as-is for VPNv6 route filtering");
12003 else if (llgr_stale)
12004 vty_out(vty,
12005 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
12006 else if (no_llgr)
12007 vty_out(vty,
12008 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
12009 else if (accept_own_nexthop)
12010 vty_out(vty,
12011 ", accept local nexthop");
12012 else if (blackhole)
12013 vty_out(vty, ", inform peer to blackhole prefix");
12014 else if (no_export)
12015 vty_out(vty, ", not advertised to EBGP peer");
12016 else if (no_advertise)
12017 vty_out(vty, ", not advertised to any peer");
12018 else if (local_as)
12019 vty_out(vty, ", not advertised outside local AS");
12020 else if (no_peer)
12021 vty_out(vty,
12022 ", inform EBGP peer not to advertise to their EBGP peers");
12023
12024 if (suppress)
12025 vty_out(vty,
12026 ", Advertisements suppressed by an aggregate.");
12027 vty_out(vty, ")\n");
12028 }
12029
12030 /* If we are not using addpath then we can display Advertised to and
12031 * that will
12032 * show what peers we advertised the bestpath to. If we are using
12033 * addpath
12034 * though then we must display Advertised to on a path-by-path basis. */
12035 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12036 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12037 if (bgp_adj_out_lookup(peer, dest, 0)) {
12038 if (json && !json_adv_to)
12039 json_adv_to = json_object_new_object();
12040
12041 route_vty_out_advertised_to(
12042 vty, peer, &first,
12043 " Advertised to non peer-group peers:\n ",
12044 json_adv_to);
12045 }
12046 }
12047
12048 if (json && json_adv_to) {
12049 if (incremental_print) {
12050 vty_out(vty, "\"advertisedTo\": ");
12051 vty_json(vty, json_adv_to);
12052 vty_out(vty, ",");
12053 } else
12054 json_object_object_add(json, "advertisedTo",
12055 json_adv_to);
12056 } else {
12057 if (!json && first)
12058 vty_out(vty, " Not advertised to any peer");
12059 vty_out(vty, "\n");
12060 }
12061 }
12062 }
12063
12064 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12065 struct bgp_dest *bgp_node, struct vty *vty,
12066 struct bgp *bgp, afi_t afi, safi_t safi,
12067 json_object *json, enum bgp_path_type pathtype,
12068 int *display, enum rpki_states rpki_target_state)
12069 {
12070 struct bgp_path_info *pi;
12071 int header = 1;
12072 json_object *json_header = NULL;
12073 json_object *json_paths = NULL;
12074 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12075
12076 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12077 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12078
12079 if (p->family == AF_INET || p->family == AF_INET6)
12080 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12081 pi->peer, pi->attr, p);
12082
12083 if (rpki_target_state != RPKI_NOT_BEING_USED
12084 && rpki_curr_state != rpki_target_state)
12085 continue;
12086
12087 if (json && !json_paths) {
12088 /* Instantiate json_paths only if path is valid */
12089 json_paths = json_object_new_array();
12090 if (pfx_rd)
12091 json_header = json_object_new_object();
12092 else
12093 json_header = json;
12094 }
12095
12096 if (header) {
12097 route_vty_out_detail_header(
12098 vty, bgp, bgp_node,
12099 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12100 safi, json_header, false);
12101 header = 0;
12102 }
12103 (*display)++;
12104
12105 if (pathtype == BGP_PATH_SHOW_ALL
12106 || (pathtype == BGP_PATH_SHOW_BESTPATH
12107 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12108 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12109 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12110 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12111 route_vty_out_detail(vty, bgp, bgp_node,
12112 bgp_dest_get_prefix(bgp_node), pi,
12113 AFI_IP, safi, rpki_curr_state,
12114 json_paths);
12115 }
12116
12117 if (json && json_paths) {
12118 json_object_object_add(json_header, "paths", json_paths);
12119
12120 if (pfx_rd)
12121 json_object_object_addf(
12122 json, json_header,
12123 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12124 }
12125 }
12126
12127 /*
12128 * Return rd based on safi
12129 */
12130 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12131 safi_t safi)
12132 {
12133 switch (safi) {
12134 case SAFI_MPLS_VPN:
12135 case SAFI_ENCAP:
12136 case SAFI_EVPN:
12137 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12138 case SAFI_UNSPEC:
12139 case SAFI_UNICAST:
12140 case SAFI_MULTICAST:
12141 case SAFI_LABELED_UNICAST:
12142 case SAFI_FLOWSPEC:
12143 case SAFI_MAX:
12144 return NULL;
12145 }
12146
12147 assert(!"Reached end of function when we were not expecting it");
12148 }
12149
12150 /* Display specified route of BGP table. */
12151 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12152 struct bgp_table *rib, const char *ip_str,
12153 afi_t afi, safi_t safi,
12154 enum rpki_states rpki_target_state,
12155 struct prefix_rd *prd, int prefix_check,
12156 enum bgp_path_type pathtype, bool use_json)
12157 {
12158 int ret;
12159 int display = 0;
12160 struct prefix match;
12161 struct bgp_dest *dest;
12162 struct bgp_dest *rm;
12163 struct bgp_table *table;
12164 json_object *json = NULL;
12165 json_object *json_paths = NULL;
12166
12167 /* Check IP address argument. */
12168 ret = str2prefix(ip_str, &match);
12169 if (!ret) {
12170 vty_out(vty, "address is malformed\n");
12171 return CMD_WARNING;
12172 }
12173
12174 match.family = afi2family(afi);
12175
12176 if (use_json)
12177 json = json_object_new_object();
12178
12179 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12180 for (dest = bgp_table_top(rib); dest;
12181 dest = bgp_route_next(dest)) {
12182 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12183
12184 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12185 continue;
12186 table = bgp_dest_get_bgp_table_info(dest);
12187 if (!table)
12188 continue;
12189
12190 rm = bgp_node_match(table, &match);
12191 if (rm == NULL)
12192 continue;
12193
12194 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12195 if (prefix_check
12196 && rm_p->prefixlen != match.prefixlen) {
12197 bgp_dest_unlock_node(rm);
12198 continue;
12199 }
12200
12201 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12202 bgp, afi, safi, json, pathtype,
12203 &display, rpki_target_state);
12204
12205 bgp_dest_unlock_node(rm);
12206 }
12207 } else if (safi == SAFI_EVPN) {
12208 struct bgp_dest *longest_pfx;
12209 bool is_exact_pfxlen_match = false;
12210
12211 for (dest = bgp_table_top(rib); dest;
12212 dest = bgp_route_next(dest)) {
12213 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12214
12215 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12216 continue;
12217 table = bgp_dest_get_bgp_table_info(dest);
12218 if (!table)
12219 continue;
12220
12221 longest_pfx = NULL;
12222 is_exact_pfxlen_match = false;
12223 /*
12224 * Search through all the prefixes for a match. The
12225 * pfx's are enumerated in ascending order of pfxlens.
12226 * So, the last pfx match is the longest match. Set
12227 * is_exact_pfxlen_match when we get exact pfxlen match
12228 */
12229 for (rm = bgp_table_top(table); rm;
12230 rm = bgp_route_next(rm)) {
12231 const struct prefix *rm_p =
12232 bgp_dest_get_prefix(rm);
12233 /*
12234 * Get prefixlen of the ip-prefix within type5
12235 * evpn route
12236 */
12237 if (evpn_type5_prefix_match(rm_p, &match)
12238 && rm->info) {
12239 longest_pfx = rm;
12240 int type5_pfxlen =
12241 bgp_evpn_get_type5_prefixlen(
12242 rm_p);
12243 if (type5_pfxlen == match.prefixlen) {
12244 is_exact_pfxlen_match = true;
12245 bgp_dest_unlock_node(rm);
12246 break;
12247 }
12248 }
12249 }
12250
12251 if (!longest_pfx)
12252 continue;
12253
12254 if (prefix_check && !is_exact_pfxlen_match)
12255 continue;
12256
12257 rm = longest_pfx;
12258 bgp_dest_lock_node(rm);
12259
12260 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12261 bgp, afi, safi, json, pathtype,
12262 &display, rpki_target_state);
12263
12264 bgp_dest_unlock_node(rm);
12265 }
12266 } else if (safi == SAFI_FLOWSPEC) {
12267 if (use_json)
12268 json_paths = json_object_new_array();
12269
12270 display = bgp_flowspec_display_match_per_ip(afi, rib,
12271 &match, prefix_check,
12272 vty,
12273 use_json,
12274 json_paths);
12275 if (use_json) {
12276 if (display)
12277 json_object_object_add(json, "paths",
12278 json_paths);
12279 else
12280 json_object_free(json_paths);
12281 }
12282 } else {
12283 dest = bgp_node_match(rib, &match);
12284 if (dest != NULL) {
12285 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12286 if (!prefix_check
12287 || dest_p->prefixlen == match.prefixlen) {
12288 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12289 safi, json, pathtype,
12290 &display, rpki_target_state);
12291 }
12292
12293 bgp_dest_unlock_node(dest);
12294 }
12295 }
12296
12297 if (use_json) {
12298 vty_json(vty, json);
12299 } else {
12300 if (!display) {
12301 vty_out(vty, "%% Network not in table\n");
12302 return CMD_WARNING;
12303 }
12304 }
12305
12306 return CMD_SUCCESS;
12307 }
12308
12309 /* Display specified route of Main RIB */
12310 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12311 afi_t afi, safi_t safi, struct prefix_rd *prd,
12312 int prefix_check, enum bgp_path_type pathtype,
12313 enum rpki_states rpki_target_state, bool use_json)
12314 {
12315 if (!bgp) {
12316 bgp = bgp_get_default();
12317 if (!bgp) {
12318 if (!use_json)
12319 vty_out(vty, "No BGP process is configured\n");
12320 else
12321 vty_out(vty, "{}\n");
12322 return CMD_WARNING;
12323 }
12324 }
12325
12326 /* labeled-unicast routes live in the unicast table */
12327 if (safi == SAFI_LABELED_UNICAST)
12328 safi = SAFI_UNICAST;
12329
12330 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12331 afi, safi, rpki_target_state, prd,
12332 prefix_check, pathtype, use_json);
12333 }
12334
12335 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12336 struct cmd_token **argv, bool exact, afi_t afi,
12337 safi_t safi, bool uj)
12338 {
12339 struct lcommunity *lcom;
12340 struct buffer *b;
12341 int i;
12342 char *str;
12343 int first = 0;
12344 uint16_t show_flags = 0;
12345 int ret;
12346
12347 if (uj)
12348 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12349
12350 b = buffer_new(1024);
12351 for (i = 0; i < argc; i++) {
12352 if (first)
12353 buffer_putc(b, ' ');
12354 else {
12355 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12356 first = 1;
12357 buffer_putstr(b, argv[i]->arg);
12358 }
12359 }
12360 }
12361 buffer_putc(b, '\0');
12362
12363 str = buffer_getstr(b);
12364 buffer_free(b);
12365
12366 lcom = lcommunity_str2com(str);
12367 XFREE(MTYPE_TMP, str);
12368 if (!lcom) {
12369 vty_out(vty, "%% Large-community malformed\n");
12370 return CMD_WARNING;
12371 }
12372
12373 ret = bgp_show(vty, bgp, afi, safi,
12374 (exact ? bgp_show_type_lcommunity_exact
12375 : bgp_show_type_lcommunity),
12376 lcom, show_flags, RPKI_NOT_BEING_USED);
12377
12378 lcommunity_free(&lcom);
12379 return ret;
12380 }
12381
12382 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12383 const char *lcom, bool exact, afi_t afi,
12384 safi_t safi, bool uj)
12385 {
12386 struct community_list *list;
12387 uint16_t show_flags = 0;
12388
12389 if (uj)
12390 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12391
12392
12393 list = community_list_lookup(bgp_clist, lcom, 0,
12394 LARGE_COMMUNITY_LIST_MASTER);
12395 if (list == NULL) {
12396 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12397 lcom);
12398 return CMD_WARNING;
12399 }
12400
12401 return bgp_show(vty, bgp, afi, safi,
12402 (exact ? bgp_show_type_lcommunity_list_exact
12403 : bgp_show_type_lcommunity_list),
12404 list, show_flags, RPKI_NOT_BEING_USED);
12405 }
12406
12407 DEFUN (show_ip_bgp_large_community_list,
12408 show_ip_bgp_large_community_list_cmd,
12409 "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]",
12410 SHOW_STR
12411 IP_STR
12412 BGP_STR
12413 BGP_INSTANCE_HELP_STR
12414 BGP_AFI_HELP_STR
12415 BGP_SAFI_WITH_LABEL_HELP_STR
12416 "Display routes matching the large-community-list\n"
12417 "large-community-list number\n"
12418 "large-community-list name\n"
12419 "Exact match of the large-communities\n"
12420 JSON_STR)
12421 {
12422 afi_t afi = AFI_IP6;
12423 safi_t safi = SAFI_UNICAST;
12424 int idx = 0;
12425 bool exact_match = 0;
12426 struct bgp *bgp = NULL;
12427 bool uj = use_json(argc, argv);
12428
12429 if (uj)
12430 argc--;
12431
12432 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12433 &bgp, uj);
12434 if (!idx)
12435 return CMD_WARNING;
12436
12437 argv_find(argv, argc, "large-community-list", &idx);
12438
12439 const char *clist_number_or_name = argv[++idx]->arg;
12440
12441 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12442 exact_match = 1;
12443
12444 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12445 exact_match, afi, safi, uj);
12446 }
12447 DEFUN (show_ip_bgp_large_community,
12448 show_ip_bgp_large_community_cmd,
12449 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12450 SHOW_STR
12451 IP_STR
12452 BGP_STR
12453 BGP_INSTANCE_HELP_STR
12454 BGP_AFI_HELP_STR
12455 BGP_SAFI_WITH_LABEL_HELP_STR
12456 "Display routes matching the large-communities\n"
12457 "List of large-community numbers\n"
12458 "Exact match of the large-communities\n"
12459 JSON_STR)
12460 {
12461 afi_t afi = AFI_IP6;
12462 safi_t safi = SAFI_UNICAST;
12463 int idx = 0;
12464 bool exact_match = 0;
12465 struct bgp *bgp = NULL;
12466 bool uj = use_json(argc, argv);
12467 uint16_t show_flags = 0;
12468
12469 if (uj) {
12470 argc--;
12471 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12472 }
12473
12474 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12475 &bgp, uj);
12476 if (!idx)
12477 return CMD_WARNING;
12478
12479 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12480 if (argv_find(argv, argc, "exact-match", &idx)) {
12481 argc--;
12482 exact_match = 1;
12483 }
12484 return bgp_show_lcommunity(vty, bgp, argc, argv,
12485 exact_match, afi, safi, uj);
12486 } else
12487 return bgp_show(vty, bgp, afi, safi,
12488 bgp_show_type_lcommunity_all, NULL, show_flags,
12489 RPKI_NOT_BEING_USED);
12490 }
12491
12492 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12493 safi_t safi, struct json_object *json_array);
12494 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12495 safi_t safi, struct json_object *json);
12496
12497
12498 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12499 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12500 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12501 "Display number of prefixes for all afi/safi\n" JSON_STR)
12502 {
12503 bool uj = use_json(argc, argv);
12504 struct bgp *bgp = NULL;
12505 safi_t safi = SAFI_UNICAST;
12506 afi_t afi = AFI_IP6;
12507 int idx = 0;
12508 struct json_object *json_all = NULL;
12509 struct json_object *json_afi_safi = NULL;
12510
12511 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12512 &bgp, false);
12513 if (!idx)
12514 return CMD_WARNING;
12515
12516 if (uj)
12517 json_all = json_object_new_object();
12518
12519 FOREACH_AFI_SAFI (afi, safi) {
12520 /*
12521 * So limit output to those afi/safi pairs that
12522 * actually have something interesting in them
12523 */
12524 if (strmatch(get_afi_safi_str(afi, safi, true),
12525 "Unknown")) {
12526 continue;
12527 }
12528 if (uj) {
12529 json_afi_safi = json_object_new_array();
12530 json_object_object_add(
12531 json_all,
12532 get_afi_safi_str(afi, safi, true),
12533 json_afi_safi);
12534 } else {
12535 json_afi_safi = NULL;
12536 }
12537
12538 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12539 }
12540
12541 if (uj)
12542 vty_json(vty, json_all);
12543
12544 return CMD_SUCCESS;
12545 }
12546
12547 /* BGP route print out function without JSON */
12548 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12549 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12550 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12551 SHOW_STR
12552 IP_STR
12553 BGP_STR
12554 BGP_INSTANCE_HELP_STR
12555 L2VPN_HELP_STR
12556 EVPN_HELP_STR
12557 "BGP RIB advertisement statistics\n"
12558 JSON_STR)
12559 {
12560 afi_t afi = AFI_IP6;
12561 safi_t safi = SAFI_UNICAST;
12562 struct bgp *bgp = NULL;
12563 int idx = 0, ret;
12564 bool uj = use_json(argc, argv);
12565 struct json_object *json_afi_safi = NULL, *json = NULL;
12566
12567 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12568 &bgp, false);
12569 if (!idx)
12570 return CMD_WARNING;
12571
12572 if (uj)
12573 json_afi_safi = json_object_new_array();
12574 else
12575 json_afi_safi = NULL;
12576
12577 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12578
12579 if (uj) {
12580 json = json_object_new_object();
12581 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12582 json_afi_safi);
12583 vty_json(vty, json);
12584 }
12585 return ret;
12586 }
12587
12588 /* BGP route print out function without JSON */
12589 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12590 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12591 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12592 "]]\
12593 statistics [json]",
12594 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12595 BGP_SAFI_WITH_LABEL_HELP_STR
12596 "BGP RIB advertisement statistics\n" JSON_STR)
12597 {
12598 afi_t afi = AFI_IP6;
12599 safi_t safi = SAFI_UNICAST;
12600 struct bgp *bgp = NULL;
12601 int idx = 0, ret;
12602 bool uj = use_json(argc, argv);
12603 struct json_object *json_afi_safi = NULL, *json = NULL;
12604
12605 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12606 &bgp, false);
12607 if (!idx)
12608 return CMD_WARNING;
12609
12610 if (uj)
12611 json_afi_safi = json_object_new_array();
12612 else
12613 json_afi_safi = NULL;
12614
12615 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12616
12617 if (uj) {
12618 json = json_object_new_object();
12619 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12620 json_afi_safi);
12621 vty_json(vty, json);
12622 }
12623 return ret;
12624 }
12625
12626 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12627 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12628 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12629 "]] [all$all] dampening parameters [json]",
12630 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12631 BGP_SAFI_WITH_LABEL_HELP_STR
12632 "Display the entries for all address families\n"
12633 "Display detailed information about dampening\n"
12634 "Display detail of configured dampening parameters\n"
12635 JSON_STR)
12636 {
12637 afi_t afi = AFI_IP6;
12638 safi_t safi = SAFI_UNICAST;
12639 struct bgp *bgp = NULL;
12640 int idx = 0;
12641 uint16_t show_flags = 0;
12642 bool uj = use_json(argc, argv);
12643
12644 if (uj) {
12645 argc--;
12646 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12647 }
12648
12649 /* [<ipv4|ipv6> [all]] */
12650 if (all) {
12651 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12652 if (argv_find(argv, argc, "ipv4", &idx))
12653 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12654
12655 if (argv_find(argv, argc, "ipv6", &idx))
12656 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12657 }
12658
12659 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12660 &bgp, false);
12661 if (!idx)
12662 return CMD_WARNING;
12663
12664 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12665 }
12666
12667 /* BGP route print out function */
12668 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12669 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12670 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12671 "]]\
12672 [all$all]\
12673 [cidr-only\
12674 |dampening <flap-statistics|dampened-paths>\
12675 |community [AA:NN|local-AS|no-advertise|no-export\
12676 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12677 |accept-own|accept-own-nexthop|route-filter-v6\
12678 |route-filter-v4|route-filter-translated-v6\
12679 |route-filter-translated-v4] [exact-match]\
12680 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12681 |filter-list AS_PATH_FILTER_NAME\
12682 |prefix-list WORD\
12683 |access-list ACCESSLIST_NAME\
12684 |route-map RMAP_NAME\
12685 |rpki <invalid|valid|notfound>\
12686 |version (1-4294967295)\
12687 |alias ALIAS_NAME\
12688 |A.B.C.D/M longer-prefixes\
12689 |X:X::X:X/M longer-prefixes\
12690 |"BGP_SELF_ORIG_CMD_STR"\
12691 |detail-routes$detail_routes\
12692 ] [json$uj [detail$detail_json] | wide$wide]",
12693 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12694 BGP_SAFI_WITH_LABEL_HELP_STR
12695 "Display the entries for all address families\n"
12696 "Display only routes with non-natural netmasks\n"
12697 "Display detailed information about dampening\n"
12698 "Display flap statistics of routes\n"
12699 "Display paths suppressed due to dampening\n"
12700 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12701 "Do not send outside local AS (well-known community)\n"
12702 "Do not advertise to any peer (well-known community)\n"
12703 "Do not export to next AS (well-known community)\n"
12704 "Graceful shutdown (well-known community)\n"
12705 "Do not export to any peer (well-known community)\n"
12706 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12707 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12708 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12709 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12710 "Should accept VPN route with local nexthop (well-known community)\n"
12711 "RT VPNv6 route filtering (well-known community)\n"
12712 "RT VPNv4 route filtering (well-known community)\n"
12713 "RT translated VPNv6 route filtering (well-known community)\n"
12714 "RT translated VPNv4 route filtering (well-known community)\n"
12715 "Exact match of the communities\n"
12716 "Community-list number\n"
12717 "Community-list name\n"
12718 "Display routes matching the community-list\n"
12719 "Exact match of the communities\n"
12720 "Display routes conforming to the filter-list\n"
12721 "Regular expression access list name\n"
12722 "Display routes conforming to the prefix-list\n"
12723 "Prefix-list name\n"
12724 "Display routes conforming to the access-list\n"
12725 "Access-list name\n"
12726 "Display routes matching the route-map\n"
12727 "A route-map to match on\n"
12728 "RPKI route types\n"
12729 "A valid path as determined by rpki\n"
12730 "A invalid path as determined by rpki\n"
12731 "A path that has no rpki data\n"
12732 "Display prefixes with matching version numbers\n"
12733 "Version number and above\n"
12734 "Display prefixes with matching BGP community alias\n"
12735 "BGP community alias\n"
12736 "IPv4 prefix\n"
12737 "Display route and more specific routes\n"
12738 "IPv6 prefix\n"
12739 "Display route and more specific routes\n"
12740 BGP_SELF_ORIG_HELP_STR
12741 "Display detailed version of all routes\n"
12742 JSON_STR
12743 "Display detailed version of JSON output\n"
12744 "Increase table width for longer prefixes\n")
12745 {
12746 afi_t afi = AFI_IP6;
12747 safi_t safi = SAFI_UNICAST;
12748 enum bgp_show_type sh_type = bgp_show_type_normal;
12749 void *output_arg = NULL;
12750 struct bgp *bgp = NULL;
12751 int idx = 0;
12752 int exact_match = 0;
12753 char *community = NULL;
12754 bool first = true;
12755 uint16_t show_flags = 0;
12756 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12757 struct prefix p;
12758
12759 if (uj) {
12760 argc--;
12761 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12762 }
12763
12764 if (detail_json)
12765 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12766
12767 if (detail_routes)
12768 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12769
12770 /* [<ipv4|ipv6> [all]] */
12771 if (all) {
12772 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12773
12774 if (argv_find(argv, argc, "ipv4", &idx))
12775 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12776
12777 if (argv_find(argv, argc, "ipv6", &idx))
12778 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12779 }
12780
12781 if (wide)
12782 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12783
12784 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12785 &bgp, uj);
12786 if (!idx)
12787 return CMD_WARNING;
12788
12789 if (argv_find(argv, argc, "cidr-only", &idx))
12790 sh_type = bgp_show_type_cidr_only;
12791
12792 if (argv_find(argv, argc, "dampening", &idx)) {
12793 if (argv_find(argv, argc, "dampened-paths", &idx))
12794 sh_type = bgp_show_type_dampend_paths;
12795 else if (argv_find(argv, argc, "flap-statistics", &idx))
12796 sh_type = bgp_show_type_flap_statistics;
12797 }
12798
12799 if (argv_find(argv, argc, "community", &idx)) {
12800 char *maybecomm = NULL;
12801
12802 if (idx + 1 < argc) {
12803 if (argv[idx + 1]->type == VARIABLE_TKN)
12804 maybecomm = argv[idx + 1]->arg;
12805 else
12806 maybecomm = argv[idx + 1]->text;
12807 }
12808
12809 if (maybecomm && !strmatch(maybecomm, "json")
12810 && !strmatch(maybecomm, "exact-match"))
12811 community = maybecomm;
12812
12813 if (argv_find(argv, argc, "exact-match", &idx))
12814 exact_match = 1;
12815
12816 if (!community)
12817 sh_type = bgp_show_type_community_all;
12818 }
12819
12820 if (argv_find(argv, argc, "community-list", &idx)) {
12821 const char *clist_number_or_name = argv[++idx]->arg;
12822 struct community_list *list;
12823
12824 if (argv_find(argv, argc, "exact-match", &idx))
12825 exact_match = 1;
12826
12827 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12828 COMMUNITY_LIST_MASTER);
12829 if (list == NULL) {
12830 vty_out(vty, "%% %s community-list not found\n",
12831 clist_number_or_name);
12832 return CMD_WARNING;
12833 }
12834
12835 if (exact_match)
12836 sh_type = bgp_show_type_community_list_exact;
12837 else
12838 sh_type = bgp_show_type_community_list;
12839 output_arg = list;
12840 }
12841
12842 if (argv_find(argv, argc, "filter-list", &idx)) {
12843 const char *filter = argv[++idx]->arg;
12844 struct as_list *as_list;
12845
12846 as_list = as_list_lookup(filter);
12847 if (as_list == NULL) {
12848 vty_out(vty, "%% %s AS-path access-list not found\n",
12849 filter);
12850 return CMD_WARNING;
12851 }
12852
12853 sh_type = bgp_show_type_filter_list;
12854 output_arg = as_list;
12855 }
12856
12857 if (argv_find(argv, argc, "prefix-list", &idx)) {
12858 const char *prefix_list_str = argv[++idx]->arg;
12859 struct prefix_list *plist;
12860
12861 plist = prefix_list_lookup(afi, prefix_list_str);
12862 if (plist == NULL) {
12863 vty_out(vty, "%% %s prefix-list not found\n",
12864 prefix_list_str);
12865 return CMD_WARNING;
12866 }
12867
12868 sh_type = bgp_show_type_prefix_list;
12869 output_arg = plist;
12870 }
12871
12872 if (argv_find(argv, argc, "access-list", &idx)) {
12873 const char *access_list_str = argv[++idx]->arg;
12874 struct access_list *alist;
12875
12876 alist = access_list_lookup(afi, access_list_str);
12877 if (!alist) {
12878 vty_out(vty, "%% %s access-list not found\n",
12879 access_list_str);
12880 return CMD_WARNING;
12881 }
12882
12883 sh_type = bgp_show_type_access_list;
12884 output_arg = alist;
12885 }
12886
12887 if (argv_find(argv, argc, "route-map", &idx)) {
12888 const char *rmap_str = argv[++idx]->arg;
12889 struct route_map *rmap;
12890
12891 rmap = route_map_lookup_by_name(rmap_str);
12892 if (!rmap) {
12893 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12894 return CMD_WARNING;
12895 }
12896
12897 sh_type = bgp_show_type_route_map;
12898 output_arg = rmap;
12899 }
12900
12901 if (argv_find(argv, argc, "rpki", &idx)) {
12902 sh_type = bgp_show_type_rpki;
12903 if (argv_find(argv, argc, "valid", &idx))
12904 rpki_target_state = RPKI_VALID;
12905 else if (argv_find(argv, argc, "invalid", &idx))
12906 rpki_target_state = RPKI_INVALID;
12907 }
12908
12909 /* Display prefixes with matching version numbers */
12910 if (argv_find(argv, argc, "version", &idx)) {
12911 sh_type = bgp_show_type_prefix_version;
12912 output_arg = argv[idx + 1]->arg;
12913 }
12914
12915 /* Display prefixes with matching BGP community alias */
12916 if (argv_find(argv, argc, "alias", &idx)) {
12917 sh_type = bgp_show_type_community_alias;
12918 output_arg = argv[idx + 1]->arg;
12919 }
12920
12921 /* prefix-longer */
12922 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12923 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12924 const char *prefix_str = argv[idx]->arg;
12925
12926 if (!str2prefix(prefix_str, &p)) {
12927 vty_out(vty, "%% Malformed Prefix\n");
12928 return CMD_WARNING;
12929 }
12930
12931 sh_type = bgp_show_type_prefix_longer;
12932 output_arg = &p;
12933 }
12934
12935 /* self originated only */
12936 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12937 sh_type = bgp_show_type_self_originated;
12938
12939 if (!all) {
12940 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12941 if (community)
12942 return bgp_show_community(vty, bgp, community,
12943 exact_match, afi, safi,
12944 show_flags);
12945 else
12946 return bgp_show(vty, bgp, afi, safi, sh_type,
12947 output_arg, show_flags,
12948 rpki_target_state);
12949 } else {
12950 struct listnode *node;
12951 struct bgp *abgp;
12952 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12953 * AFI_IP6 */
12954
12955 if (uj)
12956 vty_out(vty, "{\n");
12957
12958 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12959 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12960 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12961 ? AFI_IP
12962 : AFI_IP6;
12963 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12964 FOREACH_SAFI (safi) {
12965 if (!bgp_afi_safi_peer_exists(abgp, afi,
12966 safi))
12967 continue;
12968
12969 if (uj) {
12970 if (first)
12971 first = false;
12972 else
12973 vty_out(vty, ",\n");
12974 vty_out(vty, "\"%s\":{\n",
12975 get_afi_safi_str(afi,
12976 safi,
12977 true));
12978 } else
12979 vty_out(vty,
12980 "\nFor address family: %s\n",
12981 get_afi_safi_str(
12982 afi, safi,
12983 false));
12984
12985 if (community)
12986 bgp_show_community(
12987 vty, abgp, community,
12988 exact_match, afi, safi,
12989 show_flags);
12990 else
12991 bgp_show(vty, abgp, afi, safi,
12992 sh_type, output_arg,
12993 show_flags,
12994 rpki_target_state);
12995 if (uj)
12996 vty_out(vty, "}\n");
12997 }
12998 }
12999 } else {
13000 /* show <ip> bgp all: for each AFI and SAFI*/
13001 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13002 FOREACH_AFI_SAFI (afi, safi) {
13003 if (!bgp_afi_safi_peer_exists(abgp, afi,
13004 safi))
13005 continue;
13006
13007 if (uj) {
13008 if (first)
13009 first = false;
13010 else
13011 vty_out(vty, ",\n");
13012
13013 vty_out(vty, "\"%s\":{\n",
13014 get_afi_safi_str(afi,
13015 safi,
13016 true));
13017 } else
13018 vty_out(vty,
13019 "\nFor address family: %s\n",
13020 get_afi_safi_str(
13021 afi, safi,
13022 false));
13023
13024 if (community)
13025 bgp_show_community(
13026 vty, abgp, community,
13027 exact_match, afi, safi,
13028 show_flags);
13029 else
13030 bgp_show(vty, abgp, afi, safi,
13031 sh_type, output_arg,
13032 show_flags,
13033 rpki_target_state);
13034 if (uj)
13035 vty_out(vty, "}\n");
13036 }
13037 }
13038 }
13039 if (uj)
13040 vty_out(vty, "}\n");
13041 }
13042 return CMD_SUCCESS;
13043 }
13044
13045 DEFUN (show_ip_bgp_route,
13046 show_ip_bgp_route_cmd,
13047 "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]",
13048 SHOW_STR
13049 IP_STR
13050 BGP_STR
13051 BGP_INSTANCE_HELP_STR
13052 BGP_AFI_HELP_STR
13053 BGP_SAFI_WITH_LABEL_HELP_STR
13054 "Network in the BGP routing table to display\n"
13055 "IPv4 prefix\n"
13056 "Network in the BGP routing table to display\n"
13057 "IPv6 prefix\n"
13058 "Display only the bestpath\n"
13059 "Display only multipaths\n"
13060 "Display only paths that match the specified rpki state\n"
13061 "A valid path as determined by rpki\n"
13062 "A invalid path as determined by rpki\n"
13063 "A path that has no rpki data\n"
13064 JSON_STR)
13065 {
13066 int prefix_check = 0;
13067
13068 afi_t afi = AFI_IP6;
13069 safi_t safi = SAFI_UNICAST;
13070 char *prefix = NULL;
13071 struct bgp *bgp = NULL;
13072 enum bgp_path_type path_type;
13073 bool uj = use_json(argc, argv);
13074
13075 int idx = 0;
13076
13077 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13078 &bgp, uj);
13079 if (!idx)
13080 return CMD_WARNING;
13081
13082 if (!bgp) {
13083 vty_out(vty,
13084 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13085 return CMD_WARNING;
13086 }
13087
13088 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13089 if (argv_find(argv, argc, "A.B.C.D", &idx)
13090 || argv_find(argv, argc, "X:X::X:X", &idx))
13091 prefix_check = 0;
13092 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13093 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13094 prefix_check = 1;
13095
13096 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13097 && afi != AFI_IP6) {
13098 vty_out(vty,
13099 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13100 return CMD_WARNING;
13101 }
13102 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13103 && afi != AFI_IP) {
13104 vty_out(vty,
13105 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13106 return CMD_WARNING;
13107 }
13108
13109 prefix = argv[idx]->arg;
13110
13111 /* [<bestpath|multipath>] */
13112 if (argv_find(argv, argc, "bestpath", &idx))
13113 path_type = BGP_PATH_SHOW_BESTPATH;
13114 else if (argv_find(argv, argc, "multipath", &idx))
13115 path_type = BGP_PATH_SHOW_MULTIPATH;
13116 else
13117 path_type = BGP_PATH_SHOW_ALL;
13118
13119 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13120 path_type, RPKI_NOT_BEING_USED, uj);
13121 }
13122
13123 DEFUN (show_ip_bgp_regexp,
13124 show_ip_bgp_regexp_cmd,
13125 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13126 SHOW_STR
13127 IP_STR
13128 BGP_STR
13129 BGP_INSTANCE_HELP_STR
13130 BGP_AFI_HELP_STR
13131 BGP_SAFI_WITH_LABEL_HELP_STR
13132 "Display routes matching the AS path regular expression\n"
13133 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13134 JSON_STR)
13135 {
13136 afi_t afi = AFI_IP6;
13137 safi_t safi = SAFI_UNICAST;
13138 struct bgp *bgp = NULL;
13139 bool uj = use_json(argc, argv);
13140 char *regstr = NULL;
13141
13142 int idx = 0;
13143 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13144 &bgp, false);
13145 if (!idx)
13146 return CMD_WARNING;
13147
13148 // get index of regex
13149 if (argv_find(argv, argc, "REGEX", &idx))
13150 regstr = argv[idx]->arg;
13151
13152 assert(regstr);
13153 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13154 bgp_show_type_regexp, uj);
13155 }
13156
13157 DEFPY (show_ip_bgp_instance_all,
13158 show_ip_bgp_instance_all_cmd,
13159 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13160 SHOW_STR
13161 IP_STR
13162 BGP_STR
13163 BGP_INSTANCE_ALL_HELP_STR
13164 BGP_AFI_HELP_STR
13165 BGP_SAFI_WITH_LABEL_HELP_STR
13166 JSON_STR
13167 "Increase table width for longer prefixes\n")
13168 {
13169 afi_t afi = AFI_IP6;
13170 safi_t safi = SAFI_UNICAST;
13171 struct bgp *bgp = NULL;
13172 int idx = 0;
13173 uint16_t show_flags = 0;
13174
13175 if (uj) {
13176 argc--;
13177 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13178 }
13179
13180 if (wide)
13181 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13182
13183 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13184 &bgp, uj);
13185 if (!idx)
13186 return CMD_WARNING;
13187
13188 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13189 return CMD_SUCCESS;
13190 }
13191
13192 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13193 afi_t afi, safi_t safi, enum bgp_show_type type,
13194 bool use_json)
13195 {
13196 regex_t *regex;
13197 int rc;
13198 uint16_t show_flags = 0;
13199
13200 if (use_json)
13201 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13202
13203 if (!config_bgp_aspath_validate(regstr)) {
13204 vty_out(vty, "Invalid character in REGEX %s\n",
13205 regstr);
13206 return CMD_WARNING_CONFIG_FAILED;
13207 }
13208
13209 regex = bgp_regcomp(regstr);
13210 if (!regex) {
13211 vty_out(vty, "Can't compile regexp %s\n", regstr);
13212 return CMD_WARNING;
13213 }
13214
13215 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13216 RPKI_NOT_BEING_USED);
13217 bgp_regex_free(regex);
13218 return rc;
13219 }
13220
13221 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13222 const char *comstr, int exact, afi_t afi,
13223 safi_t safi, uint16_t show_flags)
13224 {
13225 struct community *com;
13226 int ret = 0;
13227
13228 com = community_str2com(comstr);
13229 if (!com) {
13230 vty_out(vty, "%% Community malformed: %s\n", comstr);
13231 return CMD_WARNING;
13232 }
13233
13234 ret = bgp_show(vty, bgp, afi, safi,
13235 (exact ? bgp_show_type_community_exact
13236 : bgp_show_type_community),
13237 com, show_flags, RPKI_NOT_BEING_USED);
13238 community_free(&com);
13239
13240 return ret;
13241 }
13242
13243 enum bgp_stats {
13244 BGP_STATS_MAXBITLEN = 0,
13245 BGP_STATS_RIB,
13246 BGP_STATS_PREFIXES,
13247 BGP_STATS_TOTPLEN,
13248 BGP_STATS_UNAGGREGATEABLE,
13249 BGP_STATS_MAX_AGGREGATEABLE,
13250 BGP_STATS_AGGREGATES,
13251 BGP_STATS_SPACE,
13252 BGP_STATS_ASPATH_COUNT,
13253 BGP_STATS_ASPATH_MAXHOPS,
13254 BGP_STATS_ASPATH_TOTHOPS,
13255 BGP_STATS_ASPATH_MAXSIZE,
13256 BGP_STATS_ASPATH_TOTSIZE,
13257 BGP_STATS_ASN_HIGHEST,
13258 BGP_STATS_MAX,
13259 };
13260
13261 #define TABLE_STATS_IDX_VTY 0
13262 #define TABLE_STATS_IDX_JSON 1
13263
13264 static const char *table_stats_strs[][2] = {
13265 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13266 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13267 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13268 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13269 "unaggregateablePrefixes"},
13270 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13271 "maximumAggregateablePrefixes"},
13272 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13273 "bgpAggregateAdvertisements"},
13274 [BGP_STATS_SPACE] = {"Address space advertised",
13275 "addressSpaceAdvertised"},
13276 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13277 "advertisementsWithPaths"},
13278 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13279 "longestAsPath"},
13280 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13281 "largestAsPath"},
13282 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13283 "averageAsPathLengthHops"},
13284 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13285 "averageAsPathSizeBytes"},
13286 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13287 [BGP_STATS_MAX] = {NULL, NULL}
13288 };
13289
13290 struct bgp_table_stats {
13291 struct bgp_table *table;
13292 unsigned long long counts[BGP_STATS_MAX];
13293
13294 unsigned long long
13295 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13296 1];
13297
13298 double total_space;
13299 };
13300
13301 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13302 struct bgp_table_stats *ts, unsigned int space)
13303 {
13304 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13305 struct bgp_path_info *pi;
13306 const struct prefix *rn_p;
13307
13308 if (!bgp_dest_has_bgp_path_info_data(dest))
13309 return;
13310
13311 rn_p = bgp_dest_get_prefix(dest);
13312 ts->counts[BGP_STATS_PREFIXES]++;
13313 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13314
13315 ts->prefix_len_count[rn_p->prefixlen]++;
13316 /* check if the prefix is included by any other announcements */
13317 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13318 pdest = bgp_dest_parent_nolock(pdest);
13319
13320 if (pdest == NULL || pdest == top) {
13321 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13322 /* announced address space */
13323 if (space)
13324 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13325 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13326 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13327
13328
13329 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13330 ts->counts[BGP_STATS_RIB]++;
13331
13332 if (CHECK_FLAG(pi->attr->flag,
13333 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13334 ts->counts[BGP_STATS_AGGREGATES]++;
13335
13336 /* as-path stats */
13337 if (pi->attr->aspath) {
13338 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13339 unsigned int size = aspath_size(pi->attr->aspath);
13340 as_t highest = aspath_highest(pi->attr->aspath);
13341
13342 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13343
13344 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13345 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13346
13347 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13348 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13349
13350 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13351 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13352 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13353 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13354 }
13355 }
13356 }
13357
13358 static void bgp_table_stats_walker(struct event *t)
13359 {
13360 struct bgp_dest *dest, *ndest;
13361 struct bgp_dest *top;
13362 struct bgp_table_stats *ts = EVENT_ARG(t);
13363 unsigned int space = 0;
13364
13365 if (!(top = bgp_table_top(ts->table)))
13366 return;
13367
13368 switch (ts->table->afi) {
13369 case AFI_IP:
13370 space = IPV4_MAX_BITLEN;
13371 break;
13372 case AFI_IP6:
13373 space = IPV6_MAX_BITLEN;
13374 break;
13375 case AFI_L2VPN:
13376 space = EVPN_ROUTE_PREFIXLEN;
13377 break;
13378 case AFI_UNSPEC:
13379 case AFI_MAX:
13380 return;
13381 }
13382
13383 ts->counts[BGP_STATS_MAXBITLEN] = space;
13384
13385 for (dest = top; dest; dest = bgp_route_next(dest)) {
13386 if (ts->table->safi == SAFI_MPLS_VPN
13387 || ts->table->safi == SAFI_ENCAP
13388 || ts->table->safi == SAFI_EVPN) {
13389 struct bgp_table *table;
13390
13391 table = bgp_dest_get_bgp_table_info(dest);
13392 if (!table)
13393 continue;
13394
13395 top = bgp_table_top(table);
13396 for (ndest = bgp_table_top(table); ndest;
13397 ndest = bgp_route_next(ndest))
13398 bgp_table_stats_rn(ndest, top, ts, space);
13399 } else {
13400 bgp_table_stats_rn(dest, top, ts, space);
13401 }
13402 }
13403 }
13404
13405 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13406 struct json_object *json_array)
13407 {
13408 struct listnode *node, *nnode;
13409 struct bgp *bgp;
13410
13411 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13412 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13413 }
13414
13415 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13416 safi_t safi, struct json_object *json_array)
13417 {
13418 struct bgp_table_stats ts;
13419 unsigned int i;
13420 int ret = CMD_SUCCESS;
13421 char temp_buf[20];
13422 struct json_object *json = NULL;
13423 uint32_t bitlen = 0;
13424 struct json_object *json_bitlen;
13425
13426 if (json_array)
13427 json = json_object_new_object();
13428
13429 if (!bgp->rib[afi][safi]) {
13430 char warning_msg[50];
13431
13432 snprintf(warning_msg, sizeof(warning_msg),
13433 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13434 safi);
13435
13436 if (!json)
13437 vty_out(vty, "%s\n", warning_msg);
13438 else
13439 json_object_string_add(json, "warning", warning_msg);
13440
13441 ret = CMD_WARNING;
13442 goto end_table_stats;
13443 }
13444
13445 if (!json)
13446 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13447 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13448 else
13449 json_object_string_add(json, "instance", bgp->name_pretty);
13450
13451 /* labeled-unicast routes live in the unicast table */
13452 if (safi == SAFI_LABELED_UNICAST)
13453 safi = SAFI_UNICAST;
13454
13455 memset(&ts, 0, sizeof(ts));
13456 ts.table = bgp->rib[afi][safi];
13457 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13458
13459 for (i = 0; i < BGP_STATS_MAX; i++) {
13460 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13461 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13462 continue;
13463
13464 switch (i) {
13465 case BGP_STATS_ASPATH_TOTHOPS:
13466 case BGP_STATS_ASPATH_TOTSIZE:
13467 if (!json) {
13468 snprintf(
13469 temp_buf, sizeof(temp_buf), "%12.2f",
13470 ts.counts[i]
13471 ? (float)ts.counts[i]
13472 / (float)ts.counts
13473 [BGP_STATS_ASPATH_COUNT]
13474 : 0);
13475 vty_out(vty, "%-30s: %s",
13476 table_stats_strs[i]
13477 [TABLE_STATS_IDX_VTY],
13478 temp_buf);
13479 } else {
13480 json_object_double_add(
13481 json,
13482 table_stats_strs[i]
13483 [TABLE_STATS_IDX_JSON],
13484 ts.counts[i]
13485 ? (double)ts.counts[i]
13486 / (double)ts.counts
13487 [BGP_STATS_ASPATH_COUNT]
13488 : 0);
13489 }
13490 break;
13491 case BGP_STATS_TOTPLEN:
13492 if (!json) {
13493 snprintf(
13494 temp_buf, sizeof(temp_buf), "%12.2f",
13495 ts.counts[i]
13496 ? (float)ts.counts[i]
13497 / (float)ts.counts
13498 [BGP_STATS_PREFIXES]
13499 : 0);
13500 vty_out(vty, "%-30s: %s",
13501 table_stats_strs[i]
13502 [TABLE_STATS_IDX_VTY],
13503 temp_buf);
13504 } else {
13505 json_object_double_add(
13506 json,
13507 table_stats_strs[i]
13508 [TABLE_STATS_IDX_JSON],
13509 ts.counts[i]
13510 ? (double)ts.counts[i]
13511 / (double)ts.counts
13512 [BGP_STATS_PREFIXES]
13513 : 0);
13514 }
13515 break;
13516 case BGP_STATS_SPACE:
13517 if (!json) {
13518 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13519 ts.total_space);
13520 vty_out(vty, "%-30s: %s\n",
13521 table_stats_strs[i]
13522 [TABLE_STATS_IDX_VTY],
13523 temp_buf);
13524 } else {
13525 json_object_double_add(
13526 json,
13527 table_stats_strs[i]
13528 [TABLE_STATS_IDX_JSON],
13529 (double)ts.total_space);
13530 }
13531 if (afi == AFI_IP6) {
13532 if (!json) {
13533 snprintf(temp_buf, sizeof(temp_buf),
13534 "%12g",
13535 ts.total_space
13536 * pow(2.0, -128 + 32));
13537 vty_out(vty, "%30s: %s\n",
13538 "/32 equivalent %s\n",
13539 temp_buf);
13540 } else {
13541 json_object_double_add(
13542 json, "/32equivalent",
13543 (double)(ts.total_space
13544 * pow(2.0,
13545 -128 + 32)));
13546 }
13547 if (!json) {
13548 snprintf(temp_buf, sizeof(temp_buf),
13549 "%12g",
13550 ts.total_space
13551 * pow(2.0, -128 + 48));
13552 vty_out(vty, "%30s: %s\n",
13553 "/48 equivalent %s\n",
13554 temp_buf);
13555 } else {
13556 json_object_double_add(
13557 json, "/48equivalent",
13558 (double)(ts.total_space
13559 * pow(2.0,
13560 -128 + 48)));
13561 }
13562 } else {
13563 if (!json) {
13564 snprintf(temp_buf, sizeof(temp_buf),
13565 "%12.2f",
13566 ts.total_space * 100.
13567 * pow(2.0, -32));
13568 vty_out(vty, "%30s: %s\n",
13569 "% announced ", temp_buf);
13570 } else {
13571 json_object_double_add(
13572 json, "%announced",
13573 (double)(ts.total_space * 100.
13574 * pow(2.0, -32)));
13575 }
13576 if (!json) {
13577 snprintf(temp_buf, sizeof(temp_buf),
13578 "%12.2f",
13579 ts.total_space
13580 * pow(2.0, -32 + 8));
13581 vty_out(vty, "%30s: %s\n",
13582 "/8 equivalent ", temp_buf);
13583 } else {
13584 json_object_double_add(
13585 json, "/8equivalent",
13586 (double)(ts.total_space
13587 * pow(2.0, -32 + 8)));
13588 }
13589 if (!json) {
13590 snprintf(temp_buf, sizeof(temp_buf),
13591 "%12.2f",
13592 ts.total_space
13593 * pow(2.0, -32 + 24));
13594 vty_out(vty, "%30s: %s\n",
13595 "/24 equivalent ", temp_buf);
13596 } else {
13597 json_object_double_add(
13598 json, "/24equivalent",
13599 (double)(ts.total_space
13600 * pow(2.0, -32 + 24)));
13601 }
13602 }
13603 break;
13604 default:
13605 if (!json) {
13606 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13607 ts.counts[i]);
13608 vty_out(vty, "%-30s: %s",
13609 table_stats_strs[i]
13610 [TABLE_STATS_IDX_VTY],
13611 temp_buf);
13612 } else {
13613 json_object_int_add(
13614 json,
13615 table_stats_strs[i]
13616 [TABLE_STATS_IDX_JSON],
13617 ts.counts[i]);
13618 }
13619 }
13620 if (!json)
13621 vty_out(vty, "\n");
13622 }
13623
13624 switch (afi) {
13625 case AFI_IP:
13626 bitlen = IPV4_MAX_BITLEN;
13627 break;
13628 case AFI_IP6:
13629 bitlen = IPV6_MAX_BITLEN;
13630 break;
13631 case AFI_L2VPN:
13632 bitlen = EVPN_ROUTE_PREFIXLEN;
13633 break;
13634 case AFI_UNSPEC:
13635 case AFI_MAX:
13636 break;
13637 }
13638
13639 if (json) {
13640 json_bitlen = json_object_new_array();
13641
13642 for (i = 0; i <= bitlen; i++) {
13643 struct json_object *ind_bit = json_object_new_object();
13644
13645 if (!ts.prefix_len_count[i])
13646 continue;
13647
13648 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13649 json_object_int_add(ind_bit, temp_buf,
13650 ts.prefix_len_count[i]);
13651 json_object_array_add(json_bitlen, ind_bit);
13652 }
13653 json_object_object_add(json, "prefixLength", json_bitlen);
13654 }
13655
13656 end_table_stats:
13657 if (json)
13658 json_object_array_add(json_array, json);
13659 return ret;
13660 }
13661
13662 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13663 safi_t safi, struct json_object *json_array)
13664 {
13665 if (!bgp) {
13666 bgp_table_stats_all(vty, afi, safi, json_array);
13667 return CMD_SUCCESS;
13668 }
13669
13670 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13671 }
13672
13673 enum bgp_pcounts {
13674 PCOUNT_ADJ_IN = 0,
13675 PCOUNT_DAMPED,
13676 PCOUNT_REMOVED,
13677 PCOUNT_HISTORY,
13678 PCOUNT_STALE,
13679 PCOUNT_VALID,
13680 PCOUNT_ALL,
13681 PCOUNT_COUNTED,
13682 PCOUNT_BPATH_SELECTED,
13683 PCOUNT_PFCNT, /* the figure we display to users */
13684 PCOUNT_MAX,
13685 };
13686
13687 static const char *const pcount_strs[] = {
13688 [PCOUNT_ADJ_IN] = "Adj-in",
13689 [PCOUNT_DAMPED] = "Damped",
13690 [PCOUNT_REMOVED] = "Removed",
13691 [PCOUNT_HISTORY] = "History",
13692 [PCOUNT_STALE] = "Stale",
13693 [PCOUNT_VALID] = "Valid",
13694 [PCOUNT_ALL] = "All RIB",
13695 [PCOUNT_COUNTED] = "PfxCt counted",
13696 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13697 [PCOUNT_PFCNT] = "Useable",
13698 [PCOUNT_MAX] = NULL,
13699 };
13700
13701 struct peer_pcounts {
13702 unsigned int count[PCOUNT_MAX];
13703 const struct peer *peer;
13704 const struct bgp_table *table;
13705 safi_t safi;
13706 };
13707
13708 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13709 {
13710 const struct bgp_adj_in *ain;
13711 const struct bgp_path_info *pi;
13712 const struct peer *peer = pc->peer;
13713
13714 for (ain = rn->adj_in; ain; ain = ain->next)
13715 if (ain->peer == peer)
13716 pc->count[PCOUNT_ADJ_IN]++;
13717
13718 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13719
13720 if (pi->peer != peer)
13721 continue;
13722
13723 pc->count[PCOUNT_ALL]++;
13724
13725 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13726 pc->count[PCOUNT_DAMPED]++;
13727 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13728 pc->count[PCOUNT_HISTORY]++;
13729 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13730 pc->count[PCOUNT_REMOVED]++;
13731 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13732 pc->count[PCOUNT_STALE]++;
13733 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13734 pc->count[PCOUNT_VALID]++;
13735 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13736 pc->count[PCOUNT_PFCNT]++;
13737 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13738 pc->count[PCOUNT_BPATH_SELECTED]++;
13739
13740 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13741 pc->count[PCOUNT_COUNTED]++;
13742 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13743 flog_err(
13744 EC_LIB_DEVELOPMENT,
13745 "Attempting to count but flags say it is unusable");
13746 } else {
13747 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13748 flog_err(
13749 EC_LIB_DEVELOPMENT,
13750 "Not counted but flags say we should");
13751 }
13752 }
13753 }
13754
13755 static void bgp_peer_count_walker(struct event *t)
13756 {
13757 struct bgp_dest *rn, *rm;
13758 const struct bgp_table *table;
13759 struct peer_pcounts *pc = EVENT_ARG(t);
13760
13761 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13762 || pc->safi == SAFI_EVPN) {
13763 /* Special handling for 2-level routing tables. */
13764 for (rn = bgp_table_top(pc->table); rn;
13765 rn = bgp_route_next(rn)) {
13766 table = bgp_dest_get_bgp_table_info(rn);
13767 if (table != NULL)
13768 for (rm = bgp_table_top(table); rm;
13769 rm = bgp_route_next(rm))
13770 bgp_peer_count_proc(rm, pc);
13771 }
13772 } else
13773 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13774 bgp_peer_count_proc(rn, pc);
13775 }
13776
13777 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13778 safi_t safi, bool use_json)
13779 {
13780 struct peer_pcounts pcounts = {.peer = peer};
13781 unsigned int i;
13782 json_object *json = NULL;
13783 json_object *json_loop = NULL;
13784
13785 if (use_json) {
13786 json = json_object_new_object();
13787 json_loop = json_object_new_object();
13788 }
13789
13790 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13791 || !peer->bgp->rib[afi][safi]) {
13792 if (use_json) {
13793 json_object_string_add(
13794 json, "warning",
13795 "No such neighbor or address family");
13796 vty_out(vty, "%s\n", json_object_to_json_string(json));
13797 json_object_free(json);
13798 json_object_free(json_loop);
13799 } else
13800 vty_out(vty, "%% No such neighbor or address family\n");
13801
13802 return CMD_WARNING;
13803 }
13804
13805 memset(&pcounts, 0, sizeof(pcounts));
13806 pcounts.peer = peer;
13807 pcounts.table = peer->bgp->rib[afi][safi];
13808 pcounts.safi = safi;
13809
13810 /* in-place call via thread subsystem so as to record execution time
13811 * stats for the thread-walk (i.e. ensure this can't be blamed on
13812 * on just vty_read()).
13813 */
13814 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13815
13816 if (use_json) {
13817 json_object_string_add(json, "prefixCountsFor", peer->host);
13818 json_object_string_add(json, "multiProtocol",
13819 get_afi_safi_str(afi, safi, true));
13820 json_object_int_add(json, "pfxCounter",
13821 peer->pcount[afi][safi]);
13822
13823 for (i = 0; i < PCOUNT_MAX; i++)
13824 json_object_int_add(json_loop, pcount_strs[i],
13825 pcounts.count[i]);
13826
13827 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13828
13829 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13830 json_object_string_add(json, "pfxctDriftFor",
13831 peer->host);
13832 json_object_string_add(
13833 json, "recommended",
13834 "Please report this bug, with the above command output");
13835 }
13836 vty_json(vty, json);
13837 } else {
13838
13839 if (peer->hostname
13840 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13841 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13842 peer->hostname, peer->host,
13843 get_afi_safi_str(afi, safi, false));
13844 } else {
13845 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13846 get_afi_safi_str(afi, safi, false));
13847 }
13848
13849 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13850 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13851
13852 for (i = 0; i < PCOUNT_MAX; i++)
13853 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13854 pcounts.count[i]);
13855
13856 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13857 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13858 vty_out(vty,
13859 "Please report this bug, with the above command output\n");
13860 }
13861 }
13862
13863 return CMD_SUCCESS;
13864 }
13865
13866 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13867 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13868 "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]",
13869 SHOW_STR
13870 IP_STR
13871 BGP_STR
13872 BGP_INSTANCE_HELP_STR
13873 BGP_AFI_HELP_STR
13874 BGP_SAFI_HELP_STR
13875 "Detailed information on TCP and BGP neighbor connections\n"
13876 "Neighbor to display information about\n"
13877 "Neighbor to display information about\n"
13878 "Neighbor on BGP configured interface\n"
13879 "Display detailed prefix count information\n"
13880 JSON_STR)
13881 {
13882 afi_t afi = AFI_IP6;
13883 safi_t safi = SAFI_UNICAST;
13884 struct peer *peer;
13885 int idx = 0;
13886 struct bgp *bgp = NULL;
13887 bool uj = use_json(argc, argv);
13888
13889 if (uj)
13890 argc--;
13891
13892 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13893 &bgp, uj);
13894 if (!idx)
13895 return CMD_WARNING;
13896
13897 argv_find(argv, argc, "neighbors", &idx);
13898 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13899 if (!peer)
13900 return CMD_WARNING;
13901
13902 return bgp_peer_counts(vty, peer, afi, safi, uj);
13903 }
13904
13905 #ifdef KEEP_OLD_VPN_COMMANDS
13906 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13907 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13908 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13909 SHOW_STR
13910 IP_STR
13911 BGP_STR
13912 BGP_VPNVX_HELP_STR
13913 "Display information about all VPNv4 NLRIs\n"
13914 "Detailed information on TCP and BGP neighbor connections\n"
13915 "Neighbor to display information about\n"
13916 "Neighbor to display information about\n"
13917 "Neighbor on BGP configured interface\n"
13918 "Display detailed prefix count information\n"
13919 JSON_STR)
13920 {
13921 int idx_peer = 6;
13922 struct peer *peer;
13923 bool uj = use_json(argc, argv);
13924
13925 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13926 if (!peer)
13927 return CMD_WARNING;
13928
13929 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13930 }
13931
13932 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13933 show_ip_bgp_vpn_all_route_prefix_cmd,
13934 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13935 SHOW_STR
13936 IP_STR
13937 BGP_STR
13938 BGP_VPNVX_HELP_STR
13939 "Display information about all VPNv4 NLRIs\n"
13940 "Network in the BGP routing table to display\n"
13941 "Network in the BGP routing table to display\n"
13942 JSON_STR)
13943 {
13944 int idx = 0;
13945 char *network = NULL;
13946 struct bgp *bgp = bgp_get_default();
13947 if (!bgp) {
13948 vty_out(vty, "Can't find default instance\n");
13949 return CMD_WARNING;
13950 }
13951
13952 if (argv_find(argv, argc, "A.B.C.D", &idx))
13953 network = argv[idx]->arg;
13954 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13955 network = argv[idx]->arg;
13956 else {
13957 vty_out(vty, "Unable to figure out Network\n");
13958 return CMD_WARNING;
13959 }
13960
13961 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13962 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13963 use_json(argc, argv));
13964 }
13965 #endif /* KEEP_OLD_VPN_COMMANDS */
13966
13967 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13968 show_bgp_l2vpn_evpn_route_prefix_cmd,
13969 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13970 SHOW_STR
13971 BGP_STR
13972 L2VPN_HELP_STR
13973 EVPN_HELP_STR
13974 "Network in the BGP routing table to display\n"
13975 "Network in the BGP routing table to display\n"
13976 "Network in the BGP routing table to display\n"
13977 "Network in the BGP routing table to display\n"
13978 JSON_STR)
13979 {
13980 int idx = 0;
13981 char *network = NULL;
13982 int prefix_check = 0;
13983
13984 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13985 argv_find(argv, argc, "X:X::X:X", &idx))
13986 network = argv[idx]->arg;
13987 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13988 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13989 network = argv[idx]->arg;
13990 prefix_check = 1;
13991 } else {
13992 vty_out(vty, "Unable to figure out Network\n");
13993 return CMD_WARNING;
13994 }
13995 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13996 prefix_check, BGP_PATH_SHOW_ALL,
13997 RPKI_NOT_BEING_USED, use_json(argc, argv));
13998 }
13999
14000 static void show_adj_route_header(struct vty *vty, struct peer *peer,
14001 struct bgp_table *table, int *header1,
14002 int *header2, json_object *json,
14003 json_object *json_scode,
14004 json_object *json_ocode, bool wide,
14005 bool detail)
14006 {
14007 uint64_t version = table ? table->version : 0;
14008
14009 if (*header1) {
14010 if (json) {
14011 json_object_int_add(json, "bgpTableVersion", version);
14012 json_object_string_addf(json, "bgpLocalRouterId",
14013 "%pI4", &peer->bgp->router_id);
14014 json_object_int_add(json, "defaultLocPrf",
14015 peer->bgp->default_local_pref);
14016 json_object_int_add(json, "localAS",
14017 peer->change_local_as
14018 ? peer->change_local_as
14019 : peer->local_as);
14020 json_object_object_add(json, "bgpStatusCodes",
14021 json_scode);
14022 json_object_object_add(json, "bgpOriginCodes",
14023 json_ocode);
14024 } else {
14025 vty_out(vty,
14026 "BGP table version is %" PRIu64
14027 ", local router ID is %pI4, vrf id ",
14028 version, &peer->bgp->router_id);
14029 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14030 vty_out(vty, "%s", VRFID_NONE_STR);
14031 else
14032 vty_out(vty, "%u", peer->bgp->vrf_id);
14033 vty_out(vty, "\n");
14034 vty_out(vty, "Default local pref %u, ",
14035 peer->bgp->default_local_pref);
14036 vty_out(vty, "local AS %u\n",
14037 peer->change_local_as ? peer->change_local_as
14038 : peer->local_as);
14039 if (!detail) {
14040 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14041 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14042 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14043 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14044 }
14045 }
14046 *header1 = 0;
14047 }
14048 if (*header2) {
14049 if (!json && !detail)
14050 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14051 : BGP_SHOW_HEADER));
14052 *header2 = 0;
14053 }
14054 }
14055
14056 static void
14057 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14058 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14059 const char *rmap_name, json_object *json, json_object *json_ar,
14060 json_object *json_scode, json_object *json_ocode,
14061 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14062 const struct prefix *match, unsigned long *output_count,
14063 unsigned long *filtered_count)
14064 {
14065 struct bgp_adj_in *ain = NULL;
14066 struct bgp_adj_out *adj = NULL;
14067 struct bgp_dest *dest;
14068 struct bgp *bgp;
14069 struct attr attr;
14070 int ret;
14071 struct update_subgroup *subgrp;
14072 struct peer_af *paf = NULL;
14073 bool route_filtered;
14074 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14075 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14076 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14077 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14078 || (safi == SAFI_EVPN))
14079 ? true
14080 : false;
14081 int display = 0;
14082 json_object *json_net = NULL;
14083
14084 bgp = peer->bgp;
14085
14086 /* If the user supplied a prefix, look for a matching route instead
14087 * of walking the whole table.
14088 */
14089 if (match) {
14090 dest = bgp_node_match(table, match);
14091 if (!dest) {
14092 if (!use_json)
14093 vty_out(vty, "Network not in table\n");
14094 return;
14095 }
14096
14097 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14098
14099 if (rn_p->prefixlen != match->prefixlen) {
14100 if (!use_json)
14101 vty_out(vty, "Network not in table\n");
14102 bgp_dest_unlock_node(dest);
14103 return;
14104 }
14105
14106 if (type == bgp_show_adj_route_received ||
14107 type == bgp_show_adj_route_filtered) {
14108 for (ain = dest->adj_in; ain; ain = ain->next) {
14109 if (ain->peer == peer) {
14110 attr = *ain->attr;
14111 break;
14112 }
14113 }
14114 /* bail out if if adj_out is empty, or
14115 * if the prefix isn't in this peer's
14116 * adj_in
14117 */
14118 if (!ain || ain->peer != peer) {
14119 if (!use_json)
14120 vty_out(vty, "Network not in table\n");
14121 bgp_dest_unlock_node(dest);
14122 return;
14123 }
14124 } else if (type == bgp_show_adj_route_advertised) {
14125 bool peer_found = false;
14126
14127 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14128 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14129 if (paf->peer == peer && adj->attr) {
14130 attr = *adj->attr;
14131 peer_found = true;
14132 break;
14133 }
14134 }
14135 if (peer_found)
14136 break;
14137 }
14138 /* bail out if if adj_out is empty, or
14139 * if the prefix isn't in this peer's
14140 * adj_out
14141 */
14142 if (!paf || !peer_found) {
14143 if (!use_json)
14144 vty_out(vty, "Network not in table\n");
14145 bgp_dest_unlock_node(dest);
14146 return;
14147 }
14148 }
14149
14150 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14151 rmap_name);
14152
14153 if (ret != RMAP_DENY) {
14154 show_adj_route_header(vty, peer, table, header1,
14155 header2, json, json_scode,
14156 json_ocode, wide, detail);
14157
14158 if (use_json)
14159 json_net = json_object_new_object();
14160
14161 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14162 afi, safi, json_net,
14163 BGP_PATH_SHOW_ALL, &display,
14164 RPKI_NOT_BEING_USED);
14165 if (use_json)
14166 json_object_object_addf(json_ar, json_net,
14167 "%pFX", rn_p);
14168 (*output_count)++;
14169 } else
14170 (*filtered_count)++;
14171
14172 bgp_attr_flush(&attr);
14173 bgp_dest_unlock_node(dest);
14174 return;
14175 }
14176
14177
14178 subgrp = peer_subgroup(peer, afi, safi);
14179
14180 if (type == bgp_show_adj_route_advertised && subgrp
14181 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14182 if (use_json) {
14183 json_object_int_add(json, "bgpTableVersion",
14184 table->version);
14185 json_object_string_addf(json, "bgpLocalRouterId",
14186 "%pI4", &bgp->router_id);
14187 json_object_int_add(json, "defaultLocPrf",
14188 bgp->default_local_pref);
14189 json_object_int_add(json, "localAS",
14190 peer->change_local_as
14191 ? peer->change_local_as
14192 : peer->local_as);
14193 json_object_object_add(json, "bgpStatusCodes",
14194 json_scode);
14195 json_object_object_add(json, "bgpOriginCodes",
14196 json_ocode);
14197 json_object_string_add(
14198 json, "bgpOriginatingDefaultNetwork",
14199 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14200 } else {
14201 vty_out(vty,
14202 "BGP table version is %" PRIu64
14203 ", local router ID is %pI4, vrf id ",
14204 table->version, &bgp->router_id);
14205 if (bgp->vrf_id == VRF_UNKNOWN)
14206 vty_out(vty, "%s", VRFID_NONE_STR);
14207 else
14208 vty_out(vty, "%u", bgp->vrf_id);
14209 vty_out(vty, "\n");
14210 vty_out(vty, "Default local pref %u, ",
14211 bgp->default_local_pref);
14212 vty_out(vty, "local AS %u\n",
14213 peer->change_local_as ? peer->change_local_as
14214 : peer->local_as);
14215 if (!detail) {
14216 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14217 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14218 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14219 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14220 }
14221
14222 vty_out(vty, "Originating default network %s\n\n",
14223 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14224 }
14225 (*output_count)++;
14226 *header1 = 0;
14227 }
14228
14229 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14230 if (type == bgp_show_adj_route_received
14231 || type == bgp_show_adj_route_filtered) {
14232 for (ain = dest->adj_in; ain; ain = ain->next) {
14233 if (ain->peer != peer)
14234 continue;
14235
14236 show_adj_route_header(vty, peer, table, header1,
14237 header2, json, json_scode,
14238 json_ocode, wide, detail);
14239
14240 if ((safi == SAFI_MPLS_VPN)
14241 || (safi == SAFI_ENCAP)
14242 || (safi == SAFI_EVPN)) {
14243 if (use_json)
14244 json_object_string_add(
14245 json_ar, "rd", rd_str);
14246 else if (show_rd && rd_str) {
14247 vty_out(vty,
14248 "Route Distinguisher: %s\n",
14249 rd_str);
14250 show_rd = false;
14251 }
14252 }
14253
14254 attr = *ain->attr;
14255 route_filtered = false;
14256
14257 /* Filter prefix using distribute list,
14258 * filter list or prefix list
14259 */
14260 const struct prefix *rn_p =
14261 bgp_dest_get_prefix(dest);
14262 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14263 safi))
14264 == FILTER_DENY)
14265 route_filtered = true;
14266
14267 /* Filter prefix using route-map */
14268 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14269 safi, rmap_name, NULL,
14270 0, NULL);
14271
14272 if (type == bgp_show_adj_route_filtered &&
14273 !route_filtered && ret != RMAP_DENY) {
14274 bgp_attr_flush(&attr);
14275 continue;
14276 }
14277
14278 if (type == bgp_show_adj_route_received
14279 && (route_filtered || ret == RMAP_DENY))
14280 (*filtered_count)++;
14281
14282 if (detail) {
14283 if (use_json)
14284 json_net =
14285 json_object_new_object();
14286 bgp_show_path_info(
14287 NULL /* prefix_rd */, dest, vty,
14288 bgp, afi, safi, json_net,
14289 BGP_PATH_SHOW_ALL, &display,
14290 RPKI_NOT_BEING_USED);
14291 if (use_json)
14292 json_object_object_addf(
14293 json_ar, json_net,
14294 "%pFX", rn_p);
14295 } else
14296 route_vty_out_tmp(vty, dest, rn_p,
14297 &attr, safi, use_json,
14298 json_ar, wide);
14299 bgp_attr_flush(&attr);
14300 (*output_count)++;
14301 }
14302 } else if (type == bgp_show_adj_route_advertised) {
14303 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14304 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14305 if (paf->peer != peer || !adj->attr)
14306 continue;
14307
14308 show_adj_route_header(
14309 vty, peer, table, header1,
14310 header2, json, json_scode,
14311 json_ocode, wide, detail);
14312
14313 const struct prefix *rn_p =
14314 bgp_dest_get_prefix(dest);
14315
14316 attr = *adj->attr;
14317 ret = bgp_output_modifier(
14318 peer, rn_p, &attr, afi, safi,
14319 rmap_name);
14320
14321 if (ret != RMAP_DENY) {
14322 if ((safi == SAFI_MPLS_VPN)
14323 || (safi == SAFI_ENCAP)
14324 || (safi == SAFI_EVPN)) {
14325 if (use_json)
14326 json_object_string_add(
14327 json_ar,
14328 "rd",
14329 rd_str);
14330 else if (show_rd
14331 && rd_str) {
14332 vty_out(vty,
14333 "Route Distinguisher: %s\n",
14334 rd_str);
14335 show_rd = false;
14336 }
14337 }
14338 if (detail) {
14339 if (use_json)
14340 json_net =
14341 json_object_new_object();
14342 bgp_show_path_info(
14343 NULL /* prefix_rd
14344 */
14345 ,
14346 dest, vty, bgp,
14347 afi, safi,
14348 json_net,
14349 BGP_PATH_SHOW_ALL,
14350 &display,
14351 RPKI_NOT_BEING_USED);
14352 if (use_json)
14353 json_object_object_addf(
14354 json_ar,
14355 json_net,
14356 "%pFX",
14357 rn_p);
14358 } else
14359 route_vty_out_tmp(
14360 vty, dest, rn_p,
14361 &attr, safi,
14362 use_json,
14363 json_ar, wide);
14364 (*output_count)++;
14365 } else {
14366 (*filtered_count)++;
14367 }
14368
14369 bgp_attr_flush(&attr);
14370 }
14371 } else if (type == bgp_show_adj_route_bestpath) {
14372 struct bgp_path_info *pi;
14373
14374 show_adj_route_header(vty, peer, table, header1,
14375 header2, json, json_scode,
14376 json_ocode, wide, detail);
14377
14378 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14379
14380 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14381 pi = pi->next) {
14382 if (pi->peer != peer)
14383 continue;
14384
14385 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14386 continue;
14387
14388 if (detail) {
14389 if (use_json)
14390 json_net =
14391 json_object_new_object();
14392 bgp_show_path_info(
14393 NULL /* prefix_rd */, dest, vty,
14394 bgp, afi, safi, json_net,
14395 BGP_PATH_SHOW_BESTPATH,
14396 &display, RPKI_NOT_BEING_USED);
14397 if (use_json)
14398 json_object_object_addf(
14399 json_ar, json_net,
14400 "%pFX", rn_p);
14401 } else
14402 route_vty_out_tmp(
14403 vty, dest, rn_p, pi->attr, safi,
14404 use_json, json_ar, wide);
14405 (*output_count)++;
14406 }
14407 }
14408 }
14409 }
14410
14411 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14412 safi_t safi, enum bgp_show_adj_route_type type,
14413 const char *rmap_name, const struct prefix *match,
14414 uint16_t show_flags)
14415 {
14416 struct bgp *bgp;
14417 struct bgp_table *table;
14418 json_object *json = NULL;
14419 json_object *json_scode = NULL;
14420 json_object *json_ocode = NULL;
14421 json_object *json_ar = NULL;
14422 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14423
14424 /* Init BGP headers here so they're only displayed once
14425 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14426 */
14427 int header1 = 1;
14428 int header2 = 1;
14429
14430 /*
14431 * Initialize variables for each RD
14432 * All prefixes under an RD is aggregated within "json_routes"
14433 */
14434 char rd_str[BUFSIZ] = {0};
14435 json_object *json_routes = NULL;
14436
14437
14438 /* For 2-tier tables, prefix counts need to be
14439 * maintained across multiple runs of show_adj_route()
14440 */
14441 unsigned long output_count_per_rd;
14442 unsigned long filtered_count_per_rd;
14443 unsigned long output_count = 0;
14444 unsigned long filtered_count = 0;
14445
14446 if (use_json) {
14447 json = json_object_new_object();
14448 json_ar = json_object_new_object();
14449 json_scode = json_object_new_object();
14450 json_ocode = json_object_new_object();
14451 #if CONFDATE > 20231208
14452 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14453 #endif
14454 json_object_string_add(json_scode, "suppressed", "s");
14455 json_object_string_add(json_scode, "damped", "d");
14456 json_object_string_add(json_scode, "history", "h");
14457 json_object_string_add(json_scode, "valid", "*");
14458 json_object_string_add(json_scode, "best", ">");
14459 json_object_string_add(json_scode, "multipath", "=");
14460 json_object_string_add(json_scode, "internal", "i");
14461 json_object_string_add(json_scode, "ribFailure", "r");
14462 json_object_string_add(json_scode, "stale", "S");
14463 json_object_string_add(json_scode, "removed", "R");
14464
14465 #if CONFDATE > 20231208
14466 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14467 #endif
14468 json_object_string_add(json_ocode, "igp", "i");
14469 json_object_string_add(json_ocode, "egp", "e");
14470 json_object_string_add(json_ocode, "incomplete", "?");
14471 }
14472
14473 if (!peer || !peer->afc[afi][safi]) {
14474 if (use_json) {
14475 json_object_string_add(
14476 json, "warning",
14477 "No such neighbor or address family");
14478 vty_out(vty, "%s\n", json_object_to_json_string(json));
14479 json_object_free(json);
14480 json_object_free(json_ar);
14481 json_object_free(json_scode);
14482 json_object_free(json_ocode);
14483 } else
14484 vty_out(vty, "%% No such neighbor or address family\n");
14485
14486 return CMD_WARNING;
14487 }
14488
14489 if ((type == bgp_show_adj_route_received
14490 || type == bgp_show_adj_route_filtered)
14491 && !CHECK_FLAG(peer->af_flags[afi][safi],
14492 PEER_FLAG_SOFT_RECONFIG)) {
14493 if (use_json) {
14494 json_object_string_add(
14495 json, "warning",
14496 "Inbound soft reconfiguration not enabled");
14497 vty_out(vty, "%s\n", json_object_to_json_string(json));
14498 json_object_free(json);
14499 json_object_free(json_ar);
14500 json_object_free(json_scode);
14501 json_object_free(json_ocode);
14502 } else
14503 vty_out(vty,
14504 "%% Inbound soft reconfiguration not enabled\n");
14505
14506 return CMD_WARNING;
14507 }
14508
14509 bgp = peer->bgp;
14510
14511 /* labeled-unicast routes live in the unicast table */
14512 if (safi == SAFI_LABELED_UNICAST)
14513 table = bgp->rib[afi][SAFI_UNICAST];
14514 else
14515 table = bgp->rib[afi][safi];
14516
14517 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14518 || (safi == SAFI_EVPN)) {
14519
14520 struct bgp_dest *dest;
14521
14522 for (dest = bgp_table_top(table); dest;
14523 dest = bgp_route_next(dest)) {
14524 table = bgp_dest_get_bgp_table_info(dest);
14525 if (!table)
14526 continue;
14527
14528 output_count_per_rd = 0;
14529 filtered_count_per_rd = 0;
14530
14531 if (use_json)
14532 json_routes = json_object_new_object();
14533
14534 const struct prefix_rd *prd;
14535 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14536 dest);
14537
14538 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14539 bgp->asnotation);
14540
14541 show_adj_route(
14542 vty, peer, table, afi, safi, type, rmap_name,
14543 json, json_routes, json_scode, json_ocode,
14544 show_flags, &header1, &header2, rd_str, match,
14545 &output_count_per_rd, &filtered_count_per_rd);
14546
14547 /* Don't include an empty RD in the output! */
14548 if (json_routes && (output_count_per_rd > 0))
14549 json_object_object_add(json_ar, rd_str,
14550 json_routes);
14551
14552 output_count += output_count_per_rd;
14553 filtered_count += filtered_count_per_rd;
14554 }
14555 } else
14556 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14557 json, json_ar, json_scode, json_ocode,
14558 show_flags, &header1, &header2, rd_str, match,
14559 &output_count, &filtered_count);
14560
14561 if (use_json) {
14562 if (type == bgp_show_adj_route_advertised)
14563 json_object_object_add(json, "advertisedRoutes",
14564 json_ar);
14565 else
14566 json_object_object_add(json, "receivedRoutes", json_ar);
14567 json_object_int_add(json, "totalPrefixCounter", output_count);
14568 json_object_int_add(json, "filteredPrefixCounter",
14569 filtered_count);
14570
14571 /*
14572 * These fields only give up ownership to `json` when `header1`
14573 * is used (set to zero). See code in `show_adj_route` and
14574 * `show_adj_route_header`.
14575 */
14576 if (header1 == 1) {
14577 json_object_free(json_scode);
14578 json_object_free(json_ocode);
14579 }
14580
14581 vty_json(vty, json);
14582 } else if (output_count > 0) {
14583 if (!match && filtered_count > 0)
14584 vty_out(vty,
14585 "\nTotal number of prefixes %ld (%ld filtered)\n",
14586 output_count, filtered_count);
14587 else
14588 vty_out(vty, "\nTotal number of prefixes %ld\n",
14589 output_count);
14590 }
14591
14592 return CMD_SUCCESS;
14593 }
14594
14595 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14596 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14597 "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]",
14598 SHOW_STR
14599 IP_STR
14600 BGP_STR
14601 BGP_INSTANCE_HELP_STR
14602 BGP_AFI_HELP_STR
14603 BGP_SAFI_WITH_LABEL_HELP_STR
14604 "Detailed information on TCP and BGP neighbor connections\n"
14605 "Neighbor to display information about\n"
14606 "Neighbor to display information about\n"
14607 "Neighbor on BGP configured interface\n"
14608 "Display the routes selected by best path\n"
14609 "Display detailed version of routes\n"
14610 JSON_STR
14611 "Increase table width for longer prefixes\n")
14612 {
14613 afi_t afi = AFI_IP6;
14614 safi_t safi = SAFI_UNICAST;
14615 char *rmap_name = NULL;
14616 char *peerstr = NULL;
14617 struct bgp *bgp = NULL;
14618 struct peer *peer;
14619 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14620 int idx = 0;
14621 uint16_t show_flags = 0;
14622
14623 if (detail)
14624 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14625
14626 if (uj)
14627 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14628
14629 if (wide)
14630 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14631
14632 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14633 &bgp, uj);
14634
14635 if (!idx)
14636 return CMD_WARNING;
14637
14638 argv_find(argv, argc, "neighbors", &idx);
14639 peerstr = argv[++idx]->arg;
14640
14641 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14642 if (!peer)
14643 return CMD_WARNING;
14644
14645 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14646 show_flags);
14647 }
14648
14649 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14650 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14651 "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]",
14652 SHOW_STR
14653 IP_STR
14654 BGP_STR
14655 BGP_INSTANCE_HELP_STR
14656 BGP_AFI_HELP_STR
14657 BGP_SAFI_WITH_LABEL_HELP_STR
14658 "Display the entries for all address families\n"
14659 "Detailed information on TCP and BGP neighbor connections\n"
14660 "Neighbor to display information about\n"
14661 "Neighbor to display information about\n"
14662 "Neighbor on BGP configured interface\n"
14663 "Display the routes advertised to a BGP neighbor\n"
14664 "Display the received routes from neighbor\n"
14665 "Display the filtered routes received from neighbor\n"
14666 "Route-map to modify the attributes\n"
14667 "Name of the route map\n"
14668 "IPv4 prefix\n"
14669 "IPv6 prefix\n"
14670 "Display detailed version of routes\n"
14671 JSON_STR
14672 "Increase table width for longer prefixes\n")
14673 {
14674 afi_t afi = AFI_IP6;
14675 safi_t safi = SAFI_UNICAST;
14676 char *peerstr = NULL;
14677 struct bgp *bgp = NULL;
14678 struct peer *peer;
14679 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14680 int idx = 0;
14681 bool first = true;
14682 uint16_t show_flags = 0;
14683 struct listnode *node;
14684 struct bgp *abgp;
14685
14686 if (detail || prefix_str)
14687 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14688
14689 if (uj) {
14690 argc--;
14691 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14692 }
14693
14694 if (all) {
14695 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14696 if (argv_find(argv, argc, "ipv4", &idx))
14697 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14698
14699 if (argv_find(argv, argc, "ipv6", &idx))
14700 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14701 }
14702
14703 if (wide)
14704 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14705
14706 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14707 &bgp, uj);
14708 if (!idx)
14709 return CMD_WARNING;
14710
14711 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14712 argv_find(argv, argc, "neighbors", &idx);
14713 peerstr = argv[++idx]->arg;
14714
14715 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14716 if (!peer)
14717 return CMD_WARNING;
14718
14719 if (argv_find(argv, argc, "advertised-routes", &idx))
14720 type = bgp_show_adj_route_advertised;
14721 else if (argv_find(argv, argc, "received-routes", &idx))
14722 type = bgp_show_adj_route_received;
14723 else if (argv_find(argv, argc, "filtered-routes", &idx))
14724 type = bgp_show_adj_route_filtered;
14725
14726 if (!all)
14727 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14728 prefix_str ? prefix : NULL, show_flags);
14729 if (uj)
14730 vty_out(vty, "{\n");
14731
14732 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14733 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14734 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14735 : AFI_IP6;
14736 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14737 FOREACH_SAFI (safi) {
14738 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14739 continue;
14740
14741 if (uj) {
14742 if (first)
14743 first = false;
14744 else
14745 vty_out(vty, ",\n");
14746 vty_out(vty, "\"%s\":",
14747 get_afi_safi_str(afi, safi,
14748 true));
14749 } else
14750 vty_out(vty,
14751 "\nFor address family: %s\n",
14752 get_afi_safi_str(afi, safi,
14753 false));
14754
14755 peer_adj_routes(vty, peer, afi, safi, type,
14756 route_map, prefix, show_flags);
14757 }
14758 }
14759 } else {
14760 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14761 FOREACH_AFI_SAFI (afi, safi) {
14762 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14763 continue;
14764
14765 if (uj) {
14766 if (first)
14767 first = false;
14768 else
14769 vty_out(vty, ",\n");
14770 vty_out(vty, "\"%s\":",
14771 get_afi_safi_str(afi, safi,
14772 true));
14773 } else
14774 vty_out(vty,
14775 "\nFor address family: %s\n",
14776 get_afi_safi_str(afi, safi,
14777 false));
14778
14779 peer_adj_routes(vty, peer, afi, safi, type,
14780 route_map, prefix, show_flags);
14781 }
14782 }
14783 }
14784 if (uj)
14785 vty_out(vty, "}\n");
14786
14787 return CMD_SUCCESS;
14788 }
14789
14790 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14791 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14792 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14793 SHOW_STR
14794 IP_STR
14795 BGP_STR
14796 BGP_INSTANCE_HELP_STR
14797 BGP_AF_STR
14798 BGP_AF_STR
14799 BGP_AF_MODIFIER_STR
14800 "Detailed information on TCP and BGP neighbor connections\n"
14801 "Neighbor to display information about\n"
14802 "Neighbor to display information about\n"
14803 "Neighbor on BGP configured interface\n"
14804 "Display information received from a BGP neighbor\n"
14805 "Display the prefixlist filter\n"
14806 JSON_STR)
14807 {
14808 afi_t afi = AFI_IP6;
14809 safi_t safi = SAFI_UNICAST;
14810 char *peerstr = NULL;
14811 char name[BUFSIZ];
14812 struct peer *peer;
14813 int count;
14814 int idx = 0;
14815 struct bgp *bgp = NULL;
14816 bool uj = use_json(argc, argv);
14817
14818 if (uj)
14819 argc--;
14820
14821 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14822 &bgp, uj);
14823 if (!idx)
14824 return CMD_WARNING;
14825
14826 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14827 argv_find(argv, argc, "neighbors", &idx);
14828 peerstr = argv[++idx]->arg;
14829
14830 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14831 if (!peer)
14832 return CMD_WARNING;
14833
14834 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14835 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14836 if (count) {
14837 if (!uj)
14838 vty_out(vty, "Address Family: %s\n",
14839 get_afi_safi_str(afi, safi, false));
14840 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14841 } else {
14842 if (uj)
14843 vty_out(vty, "{}\n");
14844 else
14845 vty_out(vty, "No functional output\n");
14846 }
14847
14848 return CMD_SUCCESS;
14849 }
14850
14851 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14852 afi_t afi, safi_t safi,
14853 enum bgp_show_type type, bool use_json)
14854 {
14855 uint16_t show_flags = 0;
14856
14857 if (use_json)
14858 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14859
14860 if (!peer || !peer->afc[afi][safi]) {
14861 if (use_json) {
14862 json_object *json_no = NULL;
14863 json_no = json_object_new_object();
14864 json_object_string_add(
14865 json_no, "warning",
14866 "No such neighbor or address family");
14867 vty_out(vty, "%s\n",
14868 json_object_to_json_string(json_no));
14869 json_object_free(json_no);
14870 } else
14871 vty_out(vty, "%% No such neighbor or address family\n");
14872 return CMD_WARNING;
14873 }
14874
14875 /* labeled-unicast routes live in the unicast table */
14876 if (safi == SAFI_LABELED_UNICAST)
14877 safi = SAFI_UNICAST;
14878
14879 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14880 RPKI_NOT_BEING_USED);
14881 }
14882
14883 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14884 show_ip_bgp_flowspec_routes_detailed_cmd,
14885 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14886 SHOW_STR
14887 IP_STR
14888 BGP_STR
14889 BGP_INSTANCE_HELP_STR
14890 BGP_AFI_HELP_STR
14891 "SAFI Flowspec\n"
14892 "Detailed information on flowspec entries\n"
14893 JSON_STR)
14894 {
14895 afi_t afi = AFI_IP6;
14896 safi_t safi = SAFI_UNICAST;
14897 struct bgp *bgp = NULL;
14898 int idx = 0;
14899 bool uj = use_json(argc, argv);
14900 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14901
14902 if (uj) {
14903 argc--;
14904 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14905 }
14906
14907 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14908 &bgp, uj);
14909 if (!idx)
14910 return CMD_WARNING;
14911
14912 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14913 show_flags, RPKI_NOT_BEING_USED);
14914 }
14915
14916 DEFUN (show_ip_bgp_neighbor_routes,
14917 show_ip_bgp_neighbor_routes_cmd,
14918 "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]",
14919 SHOW_STR
14920 IP_STR
14921 BGP_STR
14922 BGP_INSTANCE_HELP_STR
14923 BGP_AFI_HELP_STR
14924 BGP_SAFI_WITH_LABEL_HELP_STR
14925 "Detailed information on TCP and BGP neighbor connections\n"
14926 "Neighbor to display information about\n"
14927 "Neighbor to display information about\n"
14928 "Neighbor on BGP configured interface\n"
14929 "Display flap statistics of the routes learned from neighbor\n"
14930 "Display the dampened routes received from neighbor\n"
14931 "Display routes learned from neighbor\n"
14932 JSON_STR)
14933 {
14934 char *peerstr = NULL;
14935 struct bgp *bgp = NULL;
14936 afi_t afi = AFI_IP6;
14937 safi_t safi = SAFI_UNICAST;
14938 struct peer *peer;
14939 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14940 int idx = 0;
14941 bool uj = use_json(argc, argv);
14942
14943 if (uj)
14944 argc--;
14945
14946 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14947 &bgp, uj);
14948 if (!idx)
14949 return CMD_WARNING;
14950
14951 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14952 argv_find(argv, argc, "neighbors", &idx);
14953 peerstr = argv[++idx]->arg;
14954
14955 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14956 if (!peer)
14957 return CMD_WARNING;
14958
14959 if (argv_find(argv, argc, "flap-statistics", &idx))
14960 sh_type = bgp_show_type_flap_neighbor;
14961 else if (argv_find(argv, argc, "dampened-routes", &idx))
14962 sh_type = bgp_show_type_damp_neighbor;
14963 else if (argv_find(argv, argc, "routes", &idx))
14964 sh_type = bgp_show_type_neighbor;
14965
14966 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14967 }
14968
14969 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14970
14971 struct bgp_distance {
14972 /* Distance value for the IP source prefix. */
14973 uint8_t distance;
14974
14975 /* Name of the access-list to be matched. */
14976 char *access_list;
14977 };
14978
14979 DEFUN (show_bgp_afi_vpn_rd_route,
14980 show_bgp_afi_vpn_rd_route_cmd,
14981 "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]",
14982 SHOW_STR
14983 BGP_STR
14984 BGP_AFI_HELP_STR
14985 BGP_AF_MODIFIER_STR
14986 "Display information for a route distinguisher\n"
14987 "Route Distinguisher\n"
14988 "All Route Distinguishers\n"
14989 "Network in the BGP routing table to display\n"
14990 "Network in the BGP routing table to display\n"
14991 JSON_STR)
14992 {
14993 int ret;
14994 struct prefix_rd prd;
14995 afi_t afi = AFI_MAX;
14996 int idx = 0;
14997
14998 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14999 vty_out(vty, "%% Malformed Address Family\n");
15000 return CMD_WARNING;
15001 }
15002
15003 if (!strcmp(argv[5]->arg, "all"))
15004 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
15005 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
15006 RPKI_NOT_BEING_USED,
15007 use_json(argc, argv));
15008
15009 ret = str2prefix_rd(argv[5]->arg, &prd);
15010 if (!ret) {
15011 vty_out(vty, "%% Malformed Route Distinguisher\n");
15012 return CMD_WARNING;
15013 }
15014
15015 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
15016 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
15017 use_json(argc, argv));
15018 }
15019
15020 static struct bgp_distance *bgp_distance_new(void)
15021 {
15022 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
15023 }
15024
15025 static void bgp_distance_free(struct bgp_distance *bdistance)
15026 {
15027 XFREE(MTYPE_BGP_DISTANCE, bdistance);
15028 }
15029
15030 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15031 const char *ip_str, const char *access_list_str)
15032 {
15033 int ret;
15034 afi_t afi;
15035 safi_t safi;
15036 struct prefix p;
15037 uint8_t distance;
15038 struct bgp_dest *dest;
15039 struct bgp_distance *bdistance;
15040
15041 afi = bgp_node_afi(vty);
15042 safi = bgp_node_safi(vty);
15043
15044 ret = str2prefix(ip_str, &p);
15045 if (ret == 0) {
15046 vty_out(vty, "Malformed prefix\n");
15047 return CMD_WARNING_CONFIG_FAILED;
15048 }
15049
15050 distance = atoi(distance_str);
15051
15052 /* Get BGP distance node. */
15053 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15054 bdistance = bgp_dest_get_bgp_distance_info(dest);
15055 if (bdistance)
15056 bgp_dest_unlock_node(dest);
15057 else {
15058 bdistance = bgp_distance_new();
15059 bgp_dest_set_bgp_distance_info(dest, bdistance);
15060 }
15061
15062 /* Set distance value. */
15063 bdistance->distance = distance;
15064
15065 /* Reset access-list configuration. */
15066 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15067 if (access_list_str)
15068 bdistance->access_list =
15069 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15070
15071 return CMD_SUCCESS;
15072 }
15073
15074 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15075 const char *ip_str, const char *access_list_str)
15076 {
15077 int ret;
15078 afi_t afi;
15079 safi_t safi;
15080 struct prefix p;
15081 int distance;
15082 struct bgp_dest *dest;
15083 struct bgp_distance *bdistance;
15084
15085 afi = bgp_node_afi(vty);
15086 safi = bgp_node_safi(vty);
15087
15088 ret = str2prefix(ip_str, &p);
15089 if (ret == 0) {
15090 vty_out(vty, "Malformed prefix\n");
15091 return CMD_WARNING_CONFIG_FAILED;
15092 }
15093
15094 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15095 if (!dest) {
15096 vty_out(vty, "Can't find specified prefix\n");
15097 return CMD_WARNING_CONFIG_FAILED;
15098 }
15099
15100 bdistance = bgp_dest_get_bgp_distance_info(dest);
15101 distance = atoi(distance_str);
15102
15103 if (bdistance->distance != distance) {
15104 vty_out(vty, "Distance does not match configured\n");
15105 bgp_dest_unlock_node(dest);
15106 return CMD_WARNING_CONFIG_FAILED;
15107 }
15108
15109 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15110 bgp_distance_free(bdistance);
15111
15112 bgp_dest_set_bgp_path_info(dest, NULL);
15113 bgp_dest_unlock_node(dest);
15114 bgp_dest_unlock_node(dest);
15115
15116 return CMD_SUCCESS;
15117 }
15118
15119 /* Apply BGP information to distance method. */
15120 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15121 afi_t afi, safi_t safi, struct bgp *bgp)
15122 {
15123 struct bgp_dest *dest;
15124 struct prefix q = {0};
15125 struct peer *peer;
15126 struct bgp_distance *bdistance;
15127 struct access_list *alist;
15128 struct bgp_static *bgp_static;
15129 struct bgp_path_info *bpi_ultimate;
15130
15131 if (!bgp)
15132 return 0;
15133
15134 peer = pinfo->peer;
15135
15136 if (pinfo->attr->distance)
15137 return pinfo->attr->distance;
15138
15139 /* get peer origin to calculate appropriate distance */
15140 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15141 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15142 peer = bpi_ultimate->peer;
15143 }
15144
15145 /* Check source address.
15146 * Note: for aggregate route, peer can have unspec af type.
15147 */
15148 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15149 && !sockunion2hostprefix(&peer->su, &q))
15150 return 0;
15151
15152 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15153 if (dest) {
15154 bdistance = bgp_dest_get_bgp_distance_info(dest);
15155 bgp_dest_unlock_node(dest);
15156
15157 if (bdistance->access_list) {
15158 alist = access_list_lookup(afi, bdistance->access_list);
15159 if (alist
15160 && access_list_apply(alist, p) == FILTER_PERMIT)
15161 return bdistance->distance;
15162 } else
15163 return bdistance->distance;
15164 }
15165
15166 /* Backdoor check. */
15167 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15168 if (dest) {
15169 bgp_static = bgp_dest_get_bgp_static_info(dest);
15170 bgp_dest_unlock_node(dest);
15171
15172 if (bgp_static->backdoor) {
15173 if (bgp->distance_local[afi][safi])
15174 return bgp->distance_local[afi][safi];
15175 else
15176 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15177 }
15178 }
15179
15180 if (peer->sort == BGP_PEER_EBGP) {
15181 if (bgp->distance_ebgp[afi][safi])
15182 return bgp->distance_ebgp[afi][safi];
15183 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15184 } else if (peer->sort == BGP_PEER_IBGP) {
15185 if (bgp->distance_ibgp[afi][safi])
15186 return bgp->distance_ibgp[afi][safi];
15187 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15188 } else {
15189 if (bgp->distance_local[afi][safi])
15190 return bgp->distance_local[afi][safi];
15191 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15192 }
15193 }
15194
15195 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15196 * we should tell ZEBRA update the routes for a specific
15197 * AFI/SAFI to reflect changes in RIB.
15198 */
15199 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15200 afi_t update_afi,
15201 safi_t update_safi)
15202 {
15203 afi_t afi;
15204 safi_t safi;
15205
15206 FOREACH_AFI_SAFI (afi, safi) {
15207 if (!bgp_fibupd_safi(safi))
15208 continue;
15209
15210 if (afi != update_afi && safi != update_safi)
15211 continue;
15212
15213 if (BGP_DEBUG(zebra, ZEBRA))
15214 zlog_debug(
15215 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15216 __func__, afi, safi);
15217 bgp_zebra_announce_table(bgp, afi, safi);
15218 }
15219 }
15220
15221 DEFUN (bgp_distance,
15222 bgp_distance_cmd,
15223 "distance bgp (1-255) (1-255) (1-255)",
15224 "Define an administrative distance\n"
15225 "BGP distance\n"
15226 "Distance for routes external to the AS\n"
15227 "Distance for routes internal to the AS\n"
15228 "Distance for local routes\n")
15229 {
15230 VTY_DECLVAR_CONTEXT(bgp, bgp);
15231 int idx_number = 2;
15232 int idx_number_2 = 3;
15233 int idx_number_3 = 4;
15234 int distance_ebgp = atoi(argv[idx_number]->arg);
15235 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15236 int distance_local = atoi(argv[idx_number_3]->arg);
15237 afi_t afi;
15238 safi_t safi;
15239
15240 afi = bgp_node_afi(vty);
15241 safi = bgp_node_safi(vty);
15242
15243 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15244 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15245 || bgp->distance_local[afi][safi] != distance_local) {
15246 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15247 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15248 bgp->distance_local[afi][safi] = distance_local;
15249 bgp_announce_routes_distance_update(bgp, afi, safi);
15250 }
15251 return CMD_SUCCESS;
15252 }
15253
15254 DEFUN (no_bgp_distance,
15255 no_bgp_distance_cmd,
15256 "no distance bgp [(1-255) (1-255) (1-255)]",
15257 NO_STR
15258 "Define an administrative distance\n"
15259 "BGP distance\n"
15260 "Distance for routes external to the AS\n"
15261 "Distance for routes internal to the AS\n"
15262 "Distance for local routes\n")
15263 {
15264 VTY_DECLVAR_CONTEXT(bgp, bgp);
15265 afi_t afi;
15266 safi_t safi;
15267
15268 afi = bgp_node_afi(vty);
15269 safi = bgp_node_safi(vty);
15270
15271 if (bgp->distance_ebgp[afi][safi] != 0
15272 || bgp->distance_ibgp[afi][safi] != 0
15273 || bgp->distance_local[afi][safi] != 0) {
15274 bgp->distance_ebgp[afi][safi] = 0;
15275 bgp->distance_ibgp[afi][safi] = 0;
15276 bgp->distance_local[afi][safi] = 0;
15277 bgp_announce_routes_distance_update(bgp, afi, safi);
15278 }
15279 return CMD_SUCCESS;
15280 }
15281
15282
15283 DEFUN (bgp_distance_source,
15284 bgp_distance_source_cmd,
15285 "distance (1-255) A.B.C.D/M",
15286 "Define an administrative distance\n"
15287 "Administrative distance\n"
15288 "IP source prefix\n")
15289 {
15290 int idx_number = 1;
15291 int idx_ipv4_prefixlen = 2;
15292 bgp_distance_set(vty, argv[idx_number]->arg,
15293 argv[idx_ipv4_prefixlen]->arg, NULL);
15294 return CMD_SUCCESS;
15295 }
15296
15297 DEFUN (no_bgp_distance_source,
15298 no_bgp_distance_source_cmd,
15299 "no distance (1-255) A.B.C.D/M",
15300 NO_STR
15301 "Define an administrative distance\n"
15302 "Administrative distance\n"
15303 "IP source prefix\n")
15304 {
15305 int idx_number = 2;
15306 int idx_ipv4_prefixlen = 3;
15307 bgp_distance_unset(vty, argv[idx_number]->arg,
15308 argv[idx_ipv4_prefixlen]->arg, NULL);
15309 return CMD_SUCCESS;
15310 }
15311
15312 DEFUN (bgp_distance_source_access_list,
15313 bgp_distance_source_access_list_cmd,
15314 "distance (1-255) A.B.C.D/M WORD",
15315 "Define an administrative distance\n"
15316 "Administrative distance\n"
15317 "IP source prefix\n"
15318 "Access list name\n")
15319 {
15320 int idx_number = 1;
15321 int idx_ipv4_prefixlen = 2;
15322 int idx_word = 3;
15323 bgp_distance_set(vty, argv[idx_number]->arg,
15324 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15325 return CMD_SUCCESS;
15326 }
15327
15328 DEFUN (no_bgp_distance_source_access_list,
15329 no_bgp_distance_source_access_list_cmd,
15330 "no distance (1-255) A.B.C.D/M WORD",
15331 NO_STR
15332 "Define an administrative distance\n"
15333 "Administrative distance\n"
15334 "IP source prefix\n"
15335 "Access list name\n")
15336 {
15337 int idx_number = 2;
15338 int idx_ipv4_prefixlen = 3;
15339 int idx_word = 4;
15340 bgp_distance_unset(vty, argv[idx_number]->arg,
15341 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15342 return CMD_SUCCESS;
15343 }
15344
15345 DEFUN (ipv6_bgp_distance_source,
15346 ipv6_bgp_distance_source_cmd,
15347 "distance (1-255) X:X::X:X/M",
15348 "Define an administrative distance\n"
15349 "Administrative distance\n"
15350 "IP source prefix\n")
15351 {
15352 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15353 return CMD_SUCCESS;
15354 }
15355
15356 DEFUN (no_ipv6_bgp_distance_source,
15357 no_ipv6_bgp_distance_source_cmd,
15358 "no distance (1-255) X:X::X:X/M",
15359 NO_STR
15360 "Define an administrative distance\n"
15361 "Administrative distance\n"
15362 "IP source prefix\n")
15363 {
15364 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15365 return CMD_SUCCESS;
15366 }
15367
15368 DEFUN (ipv6_bgp_distance_source_access_list,
15369 ipv6_bgp_distance_source_access_list_cmd,
15370 "distance (1-255) X:X::X:X/M WORD",
15371 "Define an administrative distance\n"
15372 "Administrative distance\n"
15373 "IP source prefix\n"
15374 "Access list name\n")
15375 {
15376 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15377 return CMD_SUCCESS;
15378 }
15379
15380 DEFUN (no_ipv6_bgp_distance_source_access_list,
15381 no_ipv6_bgp_distance_source_access_list_cmd,
15382 "no distance (1-255) X:X::X:X/M WORD",
15383 NO_STR
15384 "Define an administrative distance\n"
15385 "Administrative distance\n"
15386 "IP source prefix\n"
15387 "Access list name\n")
15388 {
15389 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15390 return CMD_SUCCESS;
15391 }
15392
15393 DEFUN (bgp_damp_set,
15394 bgp_damp_set_cmd,
15395 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15396 "BGP Specific commands\n"
15397 "Enable route-flap dampening\n"
15398 "Half-life time for the penalty\n"
15399 "Value to start reusing a route\n"
15400 "Value to start suppressing a route\n"
15401 "Maximum duration to suppress a stable route\n")
15402 {
15403 VTY_DECLVAR_CONTEXT(bgp, bgp);
15404 int idx_half_life = 2;
15405 int idx_reuse = 3;
15406 int idx_suppress = 4;
15407 int idx_max_suppress = 5;
15408 int half = DEFAULT_HALF_LIFE * 60;
15409 int reuse = DEFAULT_REUSE;
15410 int suppress = DEFAULT_SUPPRESS;
15411 int max = 4 * half;
15412
15413 if (argc == 6) {
15414 half = atoi(argv[idx_half_life]->arg) * 60;
15415 reuse = atoi(argv[idx_reuse]->arg);
15416 suppress = atoi(argv[idx_suppress]->arg);
15417 max = atoi(argv[idx_max_suppress]->arg) * 60;
15418 } else if (argc == 3) {
15419 half = atoi(argv[idx_half_life]->arg) * 60;
15420 max = 4 * half;
15421 }
15422
15423 /*
15424 * These can't be 0 but our SA doesn't understand the
15425 * way our cli is constructed
15426 */
15427 assert(reuse);
15428 assert(half);
15429 if (suppress < reuse) {
15430 vty_out(vty,
15431 "Suppress value cannot be less than reuse value \n");
15432 return 0;
15433 }
15434
15435 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15436 reuse, suppress, max);
15437 }
15438
15439 DEFUN (bgp_damp_unset,
15440 bgp_damp_unset_cmd,
15441 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15442 NO_STR
15443 "BGP Specific commands\n"
15444 "Enable route-flap dampening\n"
15445 "Half-life time for the penalty\n"
15446 "Value to start reusing a route\n"
15447 "Value to start suppressing a route\n"
15448 "Maximum duration to suppress a stable route\n")
15449 {
15450 VTY_DECLVAR_CONTEXT(bgp, bgp);
15451 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15452 }
15453
15454 /* Display specified route of BGP table. */
15455 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15456 const char *ip_str, afi_t afi, safi_t safi,
15457 struct prefix_rd *prd, int prefix_check)
15458 {
15459 int ret;
15460 struct prefix match;
15461 struct bgp_dest *dest;
15462 struct bgp_dest *rm;
15463 struct bgp_path_info *pi;
15464 struct bgp_path_info *pi_temp;
15465 struct bgp *bgp;
15466 struct bgp_table *table;
15467
15468 /* BGP structure lookup. */
15469 if (view_name) {
15470 bgp = bgp_lookup_by_name(view_name);
15471 if (bgp == NULL) {
15472 vty_out(vty, "%% Can't find BGP instance %s\n",
15473 view_name);
15474 return CMD_WARNING;
15475 }
15476 } else {
15477 bgp = bgp_get_default();
15478 if (bgp == NULL) {
15479 vty_out(vty, "%% No BGP process is configured\n");
15480 return CMD_WARNING;
15481 }
15482 }
15483
15484 /* Check IP address argument. */
15485 ret = str2prefix(ip_str, &match);
15486 if (!ret) {
15487 vty_out(vty, "%% address is malformed\n");
15488 return CMD_WARNING;
15489 }
15490
15491 match.family = afi2family(afi);
15492
15493 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15494 || (safi == SAFI_EVPN)) {
15495 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15496 dest = bgp_route_next(dest)) {
15497 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15498
15499 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15500 continue;
15501 table = bgp_dest_get_bgp_table_info(dest);
15502 if (!table)
15503 continue;
15504 rm = bgp_node_match(table, &match);
15505 if (rm == NULL)
15506 continue;
15507
15508 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15509
15510 if (!prefix_check
15511 || rm_p->prefixlen == match.prefixlen) {
15512 pi = bgp_dest_get_bgp_path_info(rm);
15513 while (pi) {
15514 if (pi->extra && pi->extra->damp_info) {
15515 pi_temp = pi->next;
15516 bgp_damp_info_free(
15517 pi->extra->damp_info,
15518 1, afi, safi);
15519 pi = pi_temp;
15520 } else
15521 pi = pi->next;
15522 }
15523 }
15524
15525 bgp_dest_unlock_node(rm);
15526 }
15527 } else {
15528 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15529 if (dest != NULL) {
15530 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15531
15532 if (!prefix_check
15533 || dest_p->prefixlen == match.prefixlen) {
15534 pi = bgp_dest_get_bgp_path_info(dest);
15535 while (pi) {
15536 if (pi->extra && pi->extra->damp_info) {
15537 pi_temp = pi->next;
15538 bgp_damp_info_free(
15539 pi->extra->damp_info,
15540 1, afi, safi);
15541 pi = pi_temp;
15542 } else
15543 pi = pi->next;
15544 }
15545 }
15546
15547 bgp_dest_unlock_node(dest);
15548 }
15549 }
15550
15551 return CMD_SUCCESS;
15552 }
15553
15554 DEFUN (clear_ip_bgp_dampening,
15555 clear_ip_bgp_dampening_cmd,
15556 "clear ip bgp dampening",
15557 CLEAR_STR
15558 IP_STR
15559 BGP_STR
15560 "Clear route flap dampening information\n")
15561 {
15562 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15563 return CMD_SUCCESS;
15564 }
15565
15566 DEFUN (clear_ip_bgp_dampening_prefix,
15567 clear_ip_bgp_dampening_prefix_cmd,
15568 "clear ip bgp dampening A.B.C.D/M",
15569 CLEAR_STR
15570 IP_STR
15571 BGP_STR
15572 "Clear route flap dampening information\n"
15573 "IPv4 prefix\n")
15574 {
15575 int idx_ipv4_prefixlen = 4;
15576 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15577 AFI_IP, SAFI_UNICAST, NULL, 1);
15578 }
15579
15580 DEFUN (clear_ip_bgp_dampening_address,
15581 clear_ip_bgp_dampening_address_cmd,
15582 "clear ip bgp dampening A.B.C.D",
15583 CLEAR_STR
15584 IP_STR
15585 BGP_STR
15586 "Clear route flap dampening information\n"
15587 "Network to clear damping information\n")
15588 {
15589 int idx_ipv4 = 4;
15590 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15591 SAFI_UNICAST, NULL, 0);
15592 }
15593
15594 DEFUN (clear_ip_bgp_dampening_address_mask,
15595 clear_ip_bgp_dampening_address_mask_cmd,
15596 "clear ip bgp dampening A.B.C.D A.B.C.D",
15597 CLEAR_STR
15598 IP_STR
15599 BGP_STR
15600 "Clear route flap dampening information\n"
15601 "Network to clear damping information\n"
15602 "Network mask\n")
15603 {
15604 int idx_ipv4 = 4;
15605 int idx_ipv4_2 = 5;
15606 int ret;
15607 char prefix_str[BUFSIZ];
15608
15609 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15610 prefix_str, sizeof(prefix_str));
15611 if (!ret) {
15612 vty_out(vty, "%% Inconsistent address and mask\n");
15613 return CMD_WARNING;
15614 }
15615
15616 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15617 NULL, 0);
15618 }
15619
15620 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15621 {
15622 struct vty *vty = arg;
15623 struct peer *peer = bucket->data;
15624
15625 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15626 }
15627
15628 DEFUN (show_bgp_listeners,
15629 show_bgp_listeners_cmd,
15630 "show bgp listeners",
15631 SHOW_STR
15632 BGP_STR
15633 "Display Listen Sockets and who created them\n")
15634 {
15635 bgp_dump_listener_info(vty);
15636
15637 return CMD_SUCCESS;
15638 }
15639
15640 DEFUN (show_bgp_peerhash,
15641 show_bgp_peerhash_cmd,
15642 "show bgp peerhash",
15643 SHOW_STR
15644 BGP_STR
15645 "Display information about the BGP peerhash\n")
15646 {
15647 struct list *instances = bm->bgp;
15648 struct listnode *node;
15649 struct bgp *bgp;
15650
15651 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15652 vty_out(vty, "BGP: %s\n", bgp->name);
15653 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15654 vty);
15655 }
15656
15657 return CMD_SUCCESS;
15658 }
15659
15660 /* also used for encap safi */
15661 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15662 afi_t afi, safi_t safi)
15663 {
15664 struct bgp_dest *pdest;
15665 struct bgp_dest *dest;
15666 struct bgp_table *table;
15667 const struct prefix *p;
15668 struct bgp_static *bgp_static;
15669 mpls_label_t label;
15670
15671 /* Network configuration. */
15672 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15673 pdest = bgp_route_next(pdest)) {
15674 table = bgp_dest_get_bgp_table_info(pdest);
15675 if (!table)
15676 continue;
15677
15678 for (dest = bgp_table_top(table); dest;
15679 dest = bgp_route_next(dest)) {
15680 bgp_static = bgp_dest_get_bgp_static_info(dest);
15681 if (bgp_static == NULL)
15682 continue;
15683
15684 p = bgp_dest_get_prefix(dest);
15685
15686 /* "network" configuration display. */
15687 label = decode_label(&bgp_static->label);
15688
15689 vty_out(vty, " network %pFX rd %s", p,
15690 bgp_static->prd_pretty);
15691 if (safi == SAFI_MPLS_VPN)
15692 vty_out(vty, " label %u", label);
15693
15694 if (bgp_static->rmap.name)
15695 vty_out(vty, " route-map %s",
15696 bgp_static->rmap.name);
15697
15698 if (bgp_static->backdoor)
15699 vty_out(vty, " backdoor");
15700
15701 vty_out(vty, "\n");
15702 }
15703 }
15704 }
15705
15706 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15707 afi_t afi, safi_t safi)
15708 {
15709 struct bgp_dest *pdest;
15710 struct bgp_dest *dest;
15711 struct bgp_table *table;
15712 const struct prefix *p;
15713 struct bgp_static *bgp_static;
15714 char buf[PREFIX_STRLEN * 2];
15715 char buf2[SU_ADDRSTRLEN];
15716 char esi_buf[ESI_STR_LEN];
15717
15718 /* Network configuration. */
15719 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15720 pdest = bgp_route_next(pdest)) {
15721 table = bgp_dest_get_bgp_table_info(pdest);
15722 if (!table)
15723 continue;
15724
15725 for (dest = bgp_table_top(table); dest;
15726 dest = bgp_route_next(dest)) {
15727 bgp_static = bgp_dest_get_bgp_static_info(dest);
15728 if (bgp_static == NULL)
15729 continue;
15730
15731 char *macrouter = NULL;
15732
15733 if (bgp_static->router_mac)
15734 macrouter = prefix_mac2str(
15735 bgp_static->router_mac, NULL, 0);
15736 if (bgp_static->eth_s_id)
15737 esi_to_str(bgp_static->eth_s_id,
15738 esi_buf, sizeof(esi_buf));
15739 p = bgp_dest_get_prefix(dest);
15740
15741 /* "network" configuration display. */
15742 if (p->u.prefix_evpn.route_type == 5) {
15743 char local_buf[PREFIX_STRLEN];
15744
15745 uint8_t family = is_evpn_prefix_ipaddr_v4((
15746 struct prefix_evpn *)p)
15747 ? AF_INET
15748 : AF_INET6;
15749 inet_ntop(family,
15750 &p->u.prefix_evpn.prefix_addr.ip.ip
15751 .addr,
15752 local_buf, sizeof(local_buf));
15753 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15754 p->u.prefix_evpn.prefix_addr
15755 .ip_prefix_length);
15756 } else {
15757 prefix2str(p, buf, sizeof(buf));
15758 }
15759
15760 if (bgp_static->gatewayIp.family == AF_INET
15761 || bgp_static->gatewayIp.family == AF_INET6)
15762 inet_ntop(bgp_static->gatewayIp.family,
15763 &bgp_static->gatewayIp.u.prefix, buf2,
15764 sizeof(buf2));
15765 vty_out(vty,
15766 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15767 buf, bgp_static->prd_pretty,
15768 p->u.prefix_evpn.prefix_addr.eth_tag,
15769 decode_label(&bgp_static->label), esi_buf, buf2,
15770 macrouter);
15771
15772 XFREE(MTYPE_TMP, macrouter);
15773 }
15774 }
15775 }
15776
15777 /* Configuration of static route announcement and aggregate
15778 information. */
15779 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15780 safi_t safi)
15781 {
15782 struct bgp_dest *dest;
15783 const struct prefix *p;
15784 struct bgp_static *bgp_static;
15785 struct bgp_aggregate *bgp_aggregate;
15786
15787 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15788 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15789 return;
15790 }
15791
15792 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15793 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15794 return;
15795 }
15796
15797 /* Network configuration. */
15798 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15799 dest = bgp_route_next(dest)) {
15800 bgp_static = bgp_dest_get_bgp_static_info(dest);
15801 if (bgp_static == NULL)
15802 continue;
15803
15804 p = bgp_dest_get_prefix(dest);
15805
15806 vty_out(vty, " network %pFX", p);
15807
15808 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15809 vty_out(vty, " label-index %u",
15810 bgp_static->label_index);
15811
15812 if (bgp_static->rmap.name)
15813 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15814
15815 if (bgp_static->backdoor)
15816 vty_out(vty, " backdoor");
15817
15818 vty_out(vty, "\n");
15819 }
15820
15821 /* Aggregate-address configuration. */
15822 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15823 dest = bgp_route_next(dest)) {
15824 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15825 if (bgp_aggregate == NULL)
15826 continue;
15827
15828 p = bgp_dest_get_prefix(dest);
15829
15830 vty_out(vty, " aggregate-address %pFX", p);
15831
15832 if (bgp_aggregate->as_set)
15833 vty_out(vty, " as-set");
15834
15835 if (bgp_aggregate->summary_only)
15836 vty_out(vty, " summary-only");
15837
15838 if (bgp_aggregate->rmap.name)
15839 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15840
15841 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15842 vty_out(vty, " origin %s",
15843 bgp_origin2str(bgp_aggregate->origin));
15844
15845 if (bgp_aggregate->match_med)
15846 vty_out(vty, " matching-MED-only");
15847
15848 if (bgp_aggregate->suppress_map_name)
15849 vty_out(vty, " suppress-map %s",
15850 bgp_aggregate->suppress_map_name);
15851
15852 vty_out(vty, "\n");
15853 }
15854 }
15855
15856 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15857 safi_t safi)
15858 {
15859 struct bgp_dest *dest;
15860 struct bgp_distance *bdistance;
15861
15862 /* Distance configuration. */
15863 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15864 && bgp->distance_local[afi][safi]
15865 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15866 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15867 || bgp->distance_local[afi][safi]
15868 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15869 vty_out(vty, " distance bgp %d %d %d\n",
15870 bgp->distance_ebgp[afi][safi],
15871 bgp->distance_ibgp[afi][safi],
15872 bgp->distance_local[afi][safi]);
15873 }
15874
15875 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15876 dest = bgp_route_next(dest)) {
15877 bdistance = bgp_dest_get_bgp_distance_info(dest);
15878 if (bdistance != NULL)
15879 vty_out(vty, " distance %d %pBD %s\n",
15880 bdistance->distance, dest,
15881 bdistance->access_list ? bdistance->access_list
15882 : "");
15883 }
15884 }
15885
15886 /* Allocate routing table structure and install commands. */
15887 void bgp_route_init(void)
15888 {
15889 afi_t afi;
15890 safi_t safi;
15891
15892 /* Init BGP distance table. */
15893 FOREACH_AFI_SAFI (afi, safi)
15894 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15895
15896 /* IPv4 BGP commands. */
15897 install_element(BGP_NODE, &bgp_table_map_cmd);
15898 install_element(BGP_NODE, &bgp_network_cmd);
15899 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15900
15901 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15902
15903 /* IPv4 unicast configuration. */
15904 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15905 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15906 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15907
15908 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15909
15910 /* IPv4 multicast configuration. */
15911 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15912 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15913 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15914 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15915
15916 /* IPv4 labeled-unicast configuration. */
15917 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15918 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15919
15920 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15921 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15922 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15923 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15924 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15925 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15926 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15927 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15928
15929 install_element(VIEW_NODE,
15930 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15931 install_element(VIEW_NODE,
15932 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15933 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15934 install_element(VIEW_NODE,
15935 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15936 #ifdef KEEP_OLD_VPN_COMMANDS
15937 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15938 #endif /* KEEP_OLD_VPN_COMMANDS */
15939 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15940 install_element(VIEW_NODE,
15941 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15942
15943 /* BGP dampening clear commands */
15944 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15945 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15946
15947 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15948 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15949
15950 /* prefix count */
15951 install_element(ENABLE_NODE,
15952 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15953 #ifdef KEEP_OLD_VPN_COMMANDS
15954 install_element(ENABLE_NODE,
15955 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15956 #endif /* KEEP_OLD_VPN_COMMANDS */
15957
15958 /* New config IPv6 BGP commands. */
15959 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15960 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15961 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15962
15963 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15964
15965 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15966
15967 /* IPv6 labeled unicast address family. */
15968 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15969 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15970
15971 install_element(BGP_NODE, &bgp_distance_cmd);
15972 install_element(BGP_NODE, &no_bgp_distance_cmd);
15973 install_element(BGP_NODE, &bgp_distance_source_cmd);
15974 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15975 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15976 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15977 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15978 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15979 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15980 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15981 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15982 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15983 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15984 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15985 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15986 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15987 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15988 install_element(BGP_IPV4M_NODE,
15989 &no_bgp_distance_source_access_list_cmd);
15990 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15991 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15992 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15993 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15994 install_element(BGP_IPV6_NODE,
15995 &ipv6_bgp_distance_source_access_list_cmd);
15996 install_element(BGP_IPV6_NODE,
15997 &no_ipv6_bgp_distance_source_access_list_cmd);
15998 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15999 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
16000 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
16001 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
16002 install_element(BGP_IPV6M_NODE,
16003 &ipv6_bgp_distance_source_access_list_cmd);
16004 install_element(BGP_IPV6M_NODE,
16005 &no_ipv6_bgp_distance_source_access_list_cmd);
16006
16007 /* BGP dampening */
16008 install_element(BGP_NODE, &bgp_damp_set_cmd);
16009 install_element(BGP_NODE, &bgp_damp_unset_cmd);
16010 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
16011 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
16012 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
16013 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
16014 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
16015 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
16016 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
16017 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
16018 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
16019 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
16020 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
16021 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
16022
16023 /* Large Communities */
16024 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
16025 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
16026
16027 /* show bgp ipv4 flowspec detailed */
16028 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
16029
16030 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16031 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16032 }
16033
16034 void bgp_route_finish(void)
16035 {
16036 afi_t afi;
16037 safi_t safi;
16038
16039 FOREACH_AFI_SAFI (afi, safi) {
16040 bgp_table_unlock(bgp_distance_table[afi][safi]);
16041 bgp_distance_table[afi][safi] = NULL;
16042 }
16043 }