]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #13117 from donaldsharp/assert_unneeded
[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, ROUTE_MAP_OUT_NAME(filter));
2390 bgp_attr_flush(rmap_path.attr);
2391 return false;
2392 }
2393 }
2394
2395 /* RFC 8212 to prevent route leaks.
2396 * This specification intends to improve this situation by requiring the
2397 * explicit configuration of both BGP Import and Export Policies for any
2398 * External BGP (EBGP) session such as customers, peers, or
2399 * confederation boundaries for all enabled address families. Through
2400 * codification of the aforementioned requirement, operators will
2401 * benefit from consistent behavior across different BGP
2402 * implementations.
2403 */
2404 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2405 if (!bgp_outbound_policy_exists(peer, filter)) {
2406 if (monotime_since(&bgp->ebgprequirespolicywarning,
2407 NULL) > FIFTEENMINUTE2USEC ||
2408 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2409 zlog_warn(
2410 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2411 monotime(&bgp->ebgprequirespolicywarning);
2412 }
2413 return false;
2414 }
2415
2416 /* draft-ietf-idr-deprecate-as-set-confed-set
2417 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2418 * Eventually, This document (if approved) updates RFC 4271
2419 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2420 * and obsoletes RFC 6472.
2421 */
2422 if (peer->bgp->reject_as_sets)
2423 if (aspath_check_as_sets(attr->aspath))
2424 return false;
2425
2426 /* If neighbor soo is configured, then check if the route has
2427 * SoO extended community and validate against the configured
2428 * one. If they match, do not announce, to prevent routing
2429 * loops.
2430 */
2431 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2432 peer->soo[afi][safi]) {
2433 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2434 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2435
2436 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2437 ECOMMUNITY_SITE_ORIGIN) ||
2438 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2439 ECOMMUNITY_SITE_ORIGIN) ||
2440 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2441 ECOMMUNITY_SITE_ORIGIN)) &&
2442 ecommunity_include(ecomm, ecomm_soo)) {
2443 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2444 zlog_debug(
2445 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2446 peer, p, ecommunity_str(ecomm_soo));
2447 return false;
2448 }
2449 }
2450
2451 /* Codification of AS 0 Processing */
2452 if (aspath_check_as_zero(attr->aspath))
2453 return false;
2454
2455 if (bgp_in_graceful_shutdown(bgp)) {
2456 if (peer->sort == BGP_PEER_IBGP
2457 || peer->sort == BGP_PEER_CONFED) {
2458 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2459 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2460 } else {
2461 bgp_attr_add_gshut_community(attr);
2462 }
2463 }
2464
2465 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2466 * Capability" to a neighbor MUST perform the following upon receiving
2467 * a route from that neighbor with the "LLGR_STALE" community, or upon
2468 * attaching the "LLGR_STALE" community itself per Section 4.2:
2469 *
2470 * The route SHOULD NOT be advertised to any neighbor from which the
2471 * Long-lived Graceful Restart Capability has not been received.
2472 */
2473 if (bgp_attr_get_community(attr) &&
2474 community_include(bgp_attr_get_community(attr),
2475 COMMUNITY_LLGR_STALE) &&
2476 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2477 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2478 return false;
2479
2480 /* After route-map has been applied, we check to see if the nexthop to
2481 * be carried in the attribute (that is used for the announcement) can
2482 * be cleared off or not. We do this in all cases where we would be
2483 * setting the nexthop to "ourselves". For IPv6, we only need to
2484 * consider
2485 * the global nexthop here; the link-local nexthop would have been
2486 * cleared
2487 * already, and if not, it is required by the update formation code.
2488 * Also see earlier comments in this function.
2489 */
2490 /*
2491 * If route-map has performed some operation on the nexthop or the peer
2492 * configuration says to pass it unchanged, we cannot reset the nexthop
2493 * here, so only attempt to do it if these aren't true. Note that the
2494 * route-map handler itself might have cleared the nexthop, if for
2495 * example,
2496 * it is configured as 'peer-address'.
2497 */
2498 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2499 piattr->rmap_change_flags)
2500 && !transparent
2501 && !CHECK_FLAG(peer->af_flags[afi][safi],
2502 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2503 /* We can reset the nexthop, if setting (or forcing) it to
2504 * 'self' */
2505 if (CHECK_FLAG(peer->af_flags[afi][safi],
2506 PEER_FLAG_NEXTHOP_SELF)
2507 || CHECK_FLAG(peer->af_flags[afi][safi],
2508 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2509 if (!reflect
2510 || CHECK_FLAG(peer->af_flags[afi][safi],
2511 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2512 subgroup_announce_reset_nhop(
2513 (peer_cap_enhe(peer, afi, safi)
2514 ? AF_INET6
2515 : p->family),
2516 attr);
2517 nh_reset = true;
2518 }
2519 } else if (peer->sort == BGP_PEER_EBGP) {
2520 /* Can also reset the nexthop if announcing to EBGP, but
2521 * only if
2522 * no peer in the subgroup is on a shared subnet.
2523 * Note: 3rd party nexthop currently implemented for
2524 * IPv4 only.
2525 */
2526 if ((p->family == AF_INET) &&
2527 (!bgp_subgrp_multiaccess_check_v4(
2528 piattr->nexthop,
2529 subgrp, from))) {
2530 subgroup_announce_reset_nhop(
2531 (peer_cap_enhe(peer, afi, safi)
2532 ? AF_INET6
2533 : p->family),
2534 attr);
2535 nh_reset = true;
2536 }
2537
2538 if ((p->family == AF_INET6) &&
2539 (!bgp_subgrp_multiaccess_check_v6(
2540 piattr->mp_nexthop_global,
2541 subgrp, from))) {
2542 subgroup_announce_reset_nhop(
2543 (peer_cap_enhe(peer, afi, safi)
2544 ? AF_INET6
2545 : p->family),
2546 attr);
2547 nh_reset = true;
2548 }
2549
2550
2551
2552 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2553 /*
2554 * This flag is used for leaked vpn-vrf routes
2555 */
2556 int family = p->family;
2557
2558 if (peer_cap_enhe(peer, afi, safi))
2559 family = AF_INET6;
2560
2561 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2562 zlog_debug(
2563 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2564 __func__, p, family2str(family));
2565 subgroup_announce_reset_nhop(family, attr);
2566 nh_reset = true;
2567 }
2568 }
2569
2570 /* If IPv6/MP and nexthop does not have any override and happens
2571 * to
2572 * be a link-local address, reset it so that we don't pass along
2573 * the
2574 * source's link-local IPv6 address to recipients who may not be
2575 * on
2576 * the same interface.
2577 */
2578 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2579 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2580 subgroup_announce_reset_nhop(AF_INET6, attr);
2581 nh_reset = true;
2582 }
2583 }
2584
2585 /* If this is an iBGP, send Origin Validation State (OVS)
2586 * extended community (rfc8097).
2587 */
2588 if (peer->sort == BGP_PEER_IBGP) {
2589 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2590
2591 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2592
2593 if (rpki_state != RPKI_NOT_BEING_USED)
2594 bgp_attr_set_ecommunity(
2595 attr, ecommunity_add_origin_validation_state(
2596 rpki_state,
2597 bgp_attr_get_ecommunity(attr)));
2598 }
2599
2600 /*
2601 * When the next hop is set to ourselves, if all multipaths have
2602 * link-bandwidth announce the cumulative bandwidth as that makes
2603 * the most sense. However, don't modify if the link-bandwidth has
2604 * been explicitly set by user policy.
2605 */
2606 if (nh_reset &&
2607 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2608 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2609 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2610 bgp_attr_set_ecommunity(
2611 attr,
2612 ecommunity_replace_linkbw(
2613 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2614 CHECK_FLAG(
2615 peer->flags,
2616 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2617
2618 return true;
2619 }
2620
2621 static void bgp_route_select_timer_expire(struct event *thread)
2622 {
2623 struct afi_safi_info *info;
2624 afi_t afi;
2625 safi_t safi;
2626 struct bgp *bgp;
2627
2628 info = EVENT_ARG(thread);
2629 afi = info->afi;
2630 safi = info->safi;
2631 bgp = info->bgp;
2632
2633 bgp->gr_info[afi][safi].t_route_select = NULL;
2634 XFREE(MTYPE_TMP, info);
2635
2636 /* Best path selection */
2637 bgp_best_path_select_defer(bgp, afi, safi);
2638 }
2639
2640 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2641 struct bgp_maxpaths_cfg *mpath_cfg,
2642 struct bgp_path_info_pair *result, afi_t afi,
2643 safi_t safi)
2644 {
2645 struct bgp_path_info *new_select;
2646 struct bgp_path_info *old_select;
2647 struct bgp_path_info *pi;
2648 struct bgp_path_info *pi1;
2649 struct bgp_path_info *pi2;
2650 struct bgp_path_info *nextpi = NULL;
2651 int paths_eq, do_mpath, debug;
2652 struct list mp_list;
2653 char pfx_buf[PREFIX2STR_BUFFER];
2654 char path_buf[PATH_ADDPATH_STR_BUFFER];
2655
2656 bgp_mp_list_init(&mp_list);
2657 do_mpath =
2658 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2659
2660 debug = bgp_debug_bestpath(dest);
2661
2662 if (debug)
2663 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2664
2665 dest->reason = bgp_path_selection_none;
2666 /* bgp deterministic-med */
2667 new_select = NULL;
2668 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2669
2670 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2671 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2672 pi1 = pi1->next)
2673 bgp_path_info_unset_flag(dest, pi1,
2674 BGP_PATH_DMED_SELECTED);
2675
2676 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2677 pi1 = pi1->next) {
2678 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2679 continue;
2680 if (BGP_PATH_HOLDDOWN(pi1))
2681 continue;
2682 if (pi1->peer != bgp->peer_self &&
2683 !CHECK_FLAG(pi1->peer->sflags,
2684 PEER_STATUS_NSF_WAIT)) {
2685 if (!peer_established(pi1->peer))
2686 continue;
2687 }
2688
2689 new_select = pi1;
2690 if (pi1->next) {
2691 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2692 if (CHECK_FLAG(pi2->flags,
2693 BGP_PATH_DMED_CHECK))
2694 continue;
2695 if (BGP_PATH_HOLDDOWN(pi2))
2696 continue;
2697 if (pi2->peer != bgp->peer_self
2698 && !CHECK_FLAG(
2699 pi2->peer->sflags,
2700 PEER_STATUS_NSF_WAIT))
2701 if (pi2->peer->status
2702 != Established)
2703 continue;
2704
2705 if (!aspath_cmp_left(pi1->attr->aspath,
2706 pi2->attr->aspath)
2707 && !aspath_cmp_left_confed(
2708 pi1->attr->aspath,
2709 pi2->attr->aspath))
2710 continue;
2711
2712 if (bgp_path_info_cmp(
2713 bgp, pi2, new_select,
2714 &paths_eq, mpath_cfg, debug,
2715 pfx_buf, afi, safi,
2716 &dest->reason)) {
2717 bgp_path_info_unset_flag(
2718 dest, new_select,
2719 BGP_PATH_DMED_SELECTED);
2720 new_select = pi2;
2721 }
2722
2723 bgp_path_info_set_flag(
2724 dest, pi2, BGP_PATH_DMED_CHECK);
2725 }
2726 }
2727 bgp_path_info_set_flag(dest, new_select,
2728 BGP_PATH_DMED_CHECK);
2729 bgp_path_info_set_flag(dest, new_select,
2730 BGP_PATH_DMED_SELECTED);
2731
2732 if (debug) {
2733 bgp_path_info_path_with_addpath_rx_str(
2734 new_select, path_buf, sizeof(path_buf));
2735 zlog_debug(
2736 "%pBD(%s): %s is the bestpath from AS %u",
2737 dest, bgp->name_pretty, path_buf,
2738 aspath_get_first_as(
2739 new_select->attr->aspath));
2740 }
2741 }
2742 }
2743
2744 /* Check old selected route and new selected route. */
2745 old_select = NULL;
2746 new_select = NULL;
2747 for (pi = bgp_dest_get_bgp_path_info(dest);
2748 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2749 enum bgp_path_selection_reason reason;
2750
2751 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2752 old_select = pi;
2753
2754 if (BGP_PATH_HOLDDOWN(pi)) {
2755 /* reap REMOVED routes, if needs be
2756 * selected route must stay for a while longer though
2757 */
2758 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2759 && (pi != old_select))
2760 bgp_path_info_reap(dest, pi);
2761
2762 if (debug)
2763 zlog_debug(
2764 "%s: %pBD(%s) pi from %s in holddown",
2765 __func__, dest, bgp->name_pretty,
2766 pi->peer->host);
2767
2768 continue;
2769 }
2770
2771 if (pi->peer && pi->peer != bgp->peer_self
2772 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2773 if (!peer_established(pi->peer)) {
2774
2775 if (debug)
2776 zlog_debug(
2777 "%s: %pBD(%s) non self peer %s not estab state",
2778 __func__, dest,
2779 bgp->name_pretty,
2780 pi->peer->host);
2781
2782 continue;
2783 }
2784
2785 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2786 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2787 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2788 if (debug)
2789 zlog_debug("%s: %pBD(%s) pi %s dmed", __func__,
2790 dest, bgp->name_pretty,
2791 pi->peer->host);
2792 continue;
2793 }
2794
2795 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2796
2797 reason = dest->reason;
2798 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2799 debug, pfx_buf, afi, safi,
2800 &dest->reason)) {
2801 if (new_select == NULL &&
2802 reason != bgp_path_selection_none)
2803 dest->reason = reason;
2804 new_select = pi;
2805 }
2806 }
2807
2808 /* Now that we know which path is the bestpath see if any of the other
2809 * paths
2810 * qualify as multipaths
2811 */
2812 if (debug) {
2813 if (new_select)
2814 bgp_path_info_path_with_addpath_rx_str(
2815 new_select, path_buf, sizeof(path_buf));
2816 else
2817 snprintf(path_buf, sizeof(path_buf), "NONE");
2818 zlog_debug(
2819 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2820 dest, bgp->name_pretty, path_buf,
2821 old_select ? old_select->peer->host : "NONE");
2822 }
2823
2824 if (do_mpath && new_select) {
2825 for (pi = bgp_dest_get_bgp_path_info(dest);
2826 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2827
2828 if (debug)
2829 bgp_path_info_path_with_addpath_rx_str(
2830 pi, path_buf, sizeof(path_buf));
2831
2832 if (pi == new_select) {
2833 if (debug)
2834 zlog_debug(
2835 "%pBD(%s): %s is the bestpath, add to the multipath list",
2836 dest, bgp->name_pretty,
2837 path_buf);
2838 bgp_mp_list_add(&mp_list, pi);
2839 continue;
2840 }
2841
2842 if (BGP_PATH_HOLDDOWN(pi))
2843 continue;
2844
2845 if (pi->peer && pi->peer != bgp->peer_self
2846 && !CHECK_FLAG(pi->peer->sflags,
2847 PEER_STATUS_NSF_WAIT))
2848 if (!peer_established(pi->peer))
2849 continue;
2850
2851 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2852 if (debug)
2853 zlog_debug(
2854 "%pBD(%s): %s has the same nexthop as the bestpath, skip it",
2855 dest, bgp->name_pretty,
2856 path_buf);
2857 continue;
2858 }
2859
2860 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2861 mpath_cfg, debug, pfx_buf, afi, safi,
2862 &dest->reason);
2863
2864 if (paths_eq) {
2865 if (debug)
2866 zlog_debug(
2867 "%pBD(%s): %s is equivalent to the bestpath, add to the multipath list",
2868 dest, bgp->name_pretty,
2869 path_buf);
2870 bgp_mp_list_add(&mp_list, pi);
2871 }
2872 }
2873 }
2874
2875 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2876 mpath_cfg);
2877 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2878 bgp_mp_list_clear(&mp_list);
2879
2880 bgp_addpath_update_ids(bgp, dest, afi, safi);
2881
2882 result->old = old_select;
2883 result->new = new_select;
2884
2885 return;
2886 }
2887
2888 /*
2889 * A new route/change in bestpath of an existing route. Evaluate the path
2890 * for advertisement to the subgroup.
2891 */
2892 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2893 struct bgp_path_info *selected,
2894 struct bgp_dest *dest,
2895 uint32_t addpath_tx_id)
2896 {
2897 const struct prefix *p;
2898 struct peer *onlypeer;
2899 struct attr attr;
2900 afi_t afi;
2901 safi_t safi;
2902 struct bgp *bgp;
2903 bool advertise;
2904
2905 p = bgp_dest_get_prefix(dest);
2906 afi = SUBGRP_AFI(subgrp);
2907 safi = SUBGRP_SAFI(subgrp);
2908 bgp = SUBGRP_INST(subgrp);
2909 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2910 : NULL);
2911
2912 if (BGP_DEBUG(update, UPDATE_OUT))
2913 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2914
2915 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2916 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2917 PEER_STATUS_ORF_WAIT_REFRESH))
2918 return;
2919
2920 memset(&attr, 0, sizeof(attr));
2921 /* It's initialized in bgp_announce_check() */
2922
2923 /* Announcement to the subgroup. If the route is filtered withdraw it.
2924 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2925 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2926 * route
2927 */
2928 advertise = bgp_check_advertise(bgp, dest);
2929
2930 if (selected) {
2931 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2932 NULL)) {
2933 /* Route is selected, if the route is already installed
2934 * in FIB, then it is advertised
2935 */
2936 if (advertise) {
2937 if (!bgp_check_withdrawal(bgp, dest)) {
2938 struct attr *adv_attr =
2939 bgp_attr_intern(&attr);
2940
2941 bgp_adj_out_set_subgroup(dest, subgrp,
2942 adv_attr,
2943 selected);
2944 } else
2945 bgp_adj_out_unset_subgroup(
2946 dest, subgrp, 1, addpath_tx_id);
2947 }
2948 } else
2949 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2950 addpath_tx_id);
2951 }
2952
2953 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2954 else {
2955 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2956 }
2957 }
2958
2959 /*
2960 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2961 * This is called at the end of route processing.
2962 */
2963 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2964 {
2965 struct bgp_path_info *pi;
2966
2967 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2968 if (BGP_PATH_HOLDDOWN(pi))
2969 continue;
2970 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2971 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2972 }
2973 }
2974
2975 /*
2976 * Has the route changed from the RIB's perspective? This is invoked only
2977 * if the route selection returns the same best route as earlier - to
2978 * determine if we need to update zebra or not.
2979 */
2980 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2981 {
2982 struct bgp_path_info *mpinfo;
2983
2984 /* If this is multipath, check all selected paths for any nexthop
2985 * change or attribute change. Some attribute changes (e.g., community)
2986 * aren't of relevance to the RIB, but we'll update zebra to ensure
2987 * we handle the case of BGP nexthop change. This is the behavior
2988 * when the best path has an attribute change anyway.
2989 */
2990 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2991 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2992 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2993 return true;
2994
2995 /*
2996 * If this is multipath, check all selected paths for any nexthop change
2997 */
2998 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2999 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3000 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3001 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3002 return true;
3003 }
3004
3005 /* Nothing has changed from the RIB's perspective. */
3006 return false;
3007 }
3008
3009 struct bgp_process_queue {
3010 struct bgp *bgp;
3011 STAILQ_HEAD(, bgp_dest) pqueue;
3012 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3013 unsigned int flags;
3014 unsigned int queued;
3015 };
3016
3017 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3018 safi_t safi, struct bgp_dest *dest,
3019 struct bgp_path_info *new_select,
3020 struct bgp_path_info *old_select)
3021 {
3022 const struct prefix *p = bgp_dest_get_prefix(dest);
3023
3024 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3025 return;
3026
3027 if (advertise_type5_routes(bgp, afi) && new_select
3028 && is_route_injectable_into_evpn(new_select)) {
3029
3030 /* apply the route-map */
3031 if (bgp->adv_cmd_rmap[afi][safi].map) {
3032 route_map_result_t ret;
3033 struct bgp_path_info rmap_path;
3034 struct bgp_path_info_extra rmap_path_extra;
3035 struct attr dummy_attr;
3036
3037 dummy_attr = *new_select->attr;
3038
3039 /* Fill temp path_info */
3040 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3041 new_select, new_select->peer,
3042 &dummy_attr);
3043
3044 RESET_FLAG(dummy_attr.rmap_change_flags);
3045
3046 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3047 p, &rmap_path);
3048
3049 if (ret == RMAP_DENYMATCH) {
3050 bgp_attr_flush(&dummy_attr);
3051 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3052 safi);
3053 } else
3054 bgp_evpn_advertise_type5_route(
3055 bgp, p, &dummy_attr, afi, safi);
3056 } else {
3057 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3058 afi, safi);
3059 }
3060 } else if (advertise_type5_routes(bgp, afi) && old_select
3061 && is_route_injectable_into_evpn(old_select))
3062 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3063 }
3064
3065 /*
3066 * Utility to determine whether a particular path_info should use
3067 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3068 * in a path where we basically _know_ this is a BGP-LU route.
3069 */
3070 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3071 {
3072 /* Certain types get imp null; so do paths where the nexthop is
3073 * not labeled.
3074 */
3075 if (new_select->sub_type == BGP_ROUTE_STATIC
3076 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3077 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3078 return true;
3079 else if (new_select->extra == NULL ||
3080 !bgp_is_valid_label(&new_select->extra->label[0]))
3081 /* TODO -- should be configurable? */
3082 return true;
3083 else
3084 return false;
3085 }
3086
3087 /*
3088 * old_select = The old best path
3089 * new_select = the new best path
3090 *
3091 * if (!old_select && new_select)
3092 * We are sending new information on.
3093 *
3094 * if (old_select && new_select) {
3095 * if (new_select != old_select)
3096 * We have a new best path send a change
3097 * else
3098 * We've received a update with new attributes that needs
3099 * to be passed on.
3100 * }
3101 *
3102 * if (old_select && !new_select)
3103 * We have no eligible route that we can announce or the rn
3104 * is being removed.
3105 */
3106 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3107 afi_t afi, safi_t safi)
3108 {
3109 struct bgp_path_info *new_select;
3110 struct bgp_path_info *old_select;
3111 struct bgp_path_info_pair old_and_new;
3112 int debug = 0;
3113
3114 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3115 if (dest)
3116 debug = bgp_debug_bestpath(dest);
3117 if (debug)
3118 zlog_debug(
3119 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3120 __func__, dest, bgp->name_pretty);
3121 return;
3122 }
3123 /* Is it end of initial update? (after startup) */
3124 if (!dest) {
3125 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3126 sizeof(bgp->update_delay_zebra_resume_time));
3127
3128 bgp->main_zebra_update_hold = 0;
3129 FOREACH_AFI_SAFI (afi, safi) {
3130 if (bgp_fibupd_safi(safi))
3131 bgp_zebra_announce_table(bgp, afi, safi);
3132 }
3133 bgp->main_peers_update_hold = 0;
3134
3135 bgp_start_routeadv(bgp);
3136 return;
3137 }
3138
3139 const struct prefix *p = bgp_dest_get_prefix(dest);
3140
3141 debug = bgp_debug_bestpath(dest);
3142 if (debug)
3143 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3144 dest, bgp->name_pretty, afi2str(afi),
3145 safi2str(safi));
3146
3147 /* The best path calculation for the route is deferred if
3148 * BGP_NODE_SELECT_DEFER is set
3149 */
3150 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3151 if (BGP_DEBUG(update, UPDATE_OUT))
3152 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3153 dest, bgp->name_pretty);
3154 return;
3155 }
3156
3157 /* Best path selection. */
3158 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3159 afi, safi);
3160 old_select = old_and_new.old;
3161 new_select = old_and_new.new;
3162
3163 /* Do we need to allocate or free labels?
3164 * Right now, since we only deal with per-prefix labels, it is not
3165 * necessary to do this upon changes to best path. Exceptions:
3166 * - label index has changed -> recalculate resulting label
3167 * - path_info sub_type changed -> switch to/from implicit-null
3168 * - no valid label (due to removed static label binding) -> get new one
3169 */
3170 if (bgp->allocate_mpls_labels[afi][safi]) {
3171 if (new_select) {
3172 if (!old_select
3173 || bgp_label_index_differs(new_select, old_select)
3174 || new_select->sub_type != old_select->sub_type
3175 || !bgp_is_valid_label(&dest->local_label)) {
3176 /* Enforced penultimate hop popping:
3177 * implicit-null for local routes, aggregate
3178 * and redistributed routes
3179 */
3180 if (bgp_lu_need_imp_null(new_select)) {
3181 if (CHECK_FLAG(
3182 dest->flags,
3183 BGP_NODE_REGISTERED_FOR_LABEL)
3184 || CHECK_FLAG(
3185 dest->flags,
3186 BGP_NODE_LABEL_REQUESTED))
3187 bgp_unregister_for_label(dest);
3188 dest->local_label = mpls_lse_encode(
3189 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3190 1);
3191 bgp_set_valid_label(&dest->local_label);
3192 } else
3193 bgp_register_for_label(dest,
3194 new_select);
3195 }
3196 } else if (CHECK_FLAG(dest->flags,
3197 BGP_NODE_REGISTERED_FOR_LABEL)
3198 || CHECK_FLAG(dest->flags,
3199 BGP_NODE_LABEL_REQUESTED)) {
3200 bgp_unregister_for_label(dest);
3201 }
3202 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3203 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3204 bgp_unregister_for_label(dest);
3205 }
3206
3207 if (debug)
3208 zlog_debug(
3209 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3210 __func__, dest, bgp->name_pretty, afi2str(afi),
3211 safi2str(safi), old_select, new_select);
3212
3213 /* If best route remains the same and this is not due to user-initiated
3214 * clear, see exactly what needs to be done.
3215 */
3216 if (old_select && old_select == new_select
3217 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3218 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3219 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3220 if (bgp_zebra_has_route_changed(old_select)) {
3221 #ifdef ENABLE_BGP_VNC
3222 vnc_import_bgp_add_route(bgp, p, old_select);
3223 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3224 #endif
3225 if (bgp_fibupd_safi(safi)
3226 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3227
3228 if (new_select->type == ZEBRA_ROUTE_BGP
3229 && (new_select->sub_type == BGP_ROUTE_NORMAL
3230 || new_select->sub_type
3231 == BGP_ROUTE_IMPORTED))
3232
3233 bgp_zebra_announce(dest, p, old_select,
3234 bgp, afi, safi);
3235 }
3236 }
3237
3238 /* If there is a change of interest to peers, reannounce the
3239 * route. */
3240 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3241 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3242 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3243 group_announce_route(bgp, afi, safi, dest, new_select);
3244
3245 /* unicast routes must also be annouced to
3246 * labeled-unicast update-groups */
3247 if (safi == SAFI_UNICAST)
3248 group_announce_route(bgp, afi,
3249 SAFI_LABELED_UNICAST, dest,
3250 new_select);
3251
3252 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3253 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3254 }
3255
3256 /* advertise/withdraw type-5 routes */
3257 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3258 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3259 bgp_process_evpn_route_injection(
3260 bgp, afi, safi, dest, old_select, old_select);
3261
3262 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3263 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3264 bgp_zebra_clear_route_change_flags(dest);
3265 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3266 return;
3267 }
3268
3269 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3270 */
3271 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3272
3273 /* bestpath has changed; bump version */
3274 if (old_select || new_select) {
3275 bgp_bump_version(dest);
3276
3277 if (!bgp->t_rmap_def_originate_eval) {
3278 bgp_lock(bgp);
3279 event_add_timer(
3280 bm->master,
3281 update_group_refresh_default_originate_route_map,
3282 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3283 &bgp->t_rmap_def_originate_eval);
3284 }
3285 }
3286
3287 if (old_select)
3288 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3289 if (new_select) {
3290 if (debug)
3291 zlog_debug("%s: setting SELECTED flag", __func__);
3292 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3293 bgp_path_info_unset_flag(dest, new_select,
3294 BGP_PATH_ATTR_CHANGED);
3295 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3296 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3297 }
3298
3299 #ifdef ENABLE_BGP_VNC
3300 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3301 if (old_select != new_select) {
3302 if (old_select) {
3303 vnc_import_bgp_exterior_del_route(bgp, p,
3304 old_select);
3305 vnc_import_bgp_del_route(bgp, p, old_select);
3306 }
3307 if (new_select) {
3308 vnc_import_bgp_exterior_add_route(bgp, p,
3309 new_select);
3310 vnc_import_bgp_add_route(bgp, p, new_select);
3311 }
3312 }
3313 }
3314 #endif
3315
3316 group_announce_route(bgp, afi, safi, dest, new_select);
3317
3318 /* unicast routes must also be annouced to labeled-unicast update-groups
3319 */
3320 if (safi == SAFI_UNICAST)
3321 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3322 new_select);
3323
3324 /* FIB update. */
3325 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3326 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3327
3328 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3329 && (new_select->sub_type == BGP_ROUTE_NORMAL
3330 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3331 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3332
3333 /* if this is an evpn imported type-5 prefix,
3334 * we need to withdraw the route first to clear
3335 * the nh neigh and the RMAC entry.
3336 */
3337 if (old_select &&
3338 is_route_parent_evpn(old_select))
3339 bgp_zebra_withdraw(p, old_select, bgp, safi);
3340
3341 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3342 } else {
3343 /* Withdraw the route from the kernel. */
3344 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3345 && (old_select->sub_type == BGP_ROUTE_NORMAL
3346 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3347 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3348
3349 bgp_zebra_withdraw(p, old_select, bgp, safi);
3350 }
3351 }
3352
3353 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3354 old_select);
3355
3356 /* Clear any route change flags. */
3357 bgp_zebra_clear_route_change_flags(dest);
3358
3359 /* Reap old select bgp_path_info, if it has been removed */
3360 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3361 bgp_path_info_reap(dest, old_select);
3362
3363 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3364 return;
3365 }
3366
3367 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3368 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3369 {
3370 struct bgp_dest *dest;
3371 int cnt = 0;
3372 struct afi_safi_info *thread_info;
3373
3374 if (bgp->gr_info[afi][safi].t_route_select) {
3375 struct event *t = bgp->gr_info[afi][safi].t_route_select;
3376
3377 thread_info = EVENT_ARG(t);
3378 XFREE(MTYPE_TMP, thread_info);
3379 EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
3380 }
3381
3382 if (BGP_DEBUG(update, UPDATE_OUT)) {
3383 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3384 get_afi_safi_str(afi, safi, false),
3385 bgp->gr_info[afi][safi].gr_deferred);
3386 }
3387
3388 /* Process the route list */
3389 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3390 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3391 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3392 dest = bgp_route_next(dest)) {
3393 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3394 continue;
3395
3396 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3397 bgp->gr_info[afi][safi].gr_deferred--;
3398 bgp_process_main_one(bgp, dest, afi, safi);
3399 cnt++;
3400 }
3401 /* If iteration stopped before the entire table was traversed then the
3402 * node needs to be unlocked.
3403 */
3404 if (dest) {
3405 bgp_dest_unlock_node(dest);
3406 dest = NULL;
3407 }
3408
3409 /* Send EOR message when all routes are processed */
3410 if (!bgp->gr_info[afi][safi].gr_deferred) {
3411 bgp_send_delayed_eor(bgp);
3412 /* Send route processing complete message to RIB */
3413 bgp_zebra_update(bgp, afi, safi,
3414 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3415 return;
3416 }
3417
3418 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3419
3420 thread_info->afi = afi;
3421 thread_info->safi = safi;
3422 thread_info->bgp = bgp;
3423
3424 /* If there are more routes to be processed, start the
3425 * selection timer
3426 */
3427 event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3428 BGP_ROUTE_SELECT_DELAY,
3429 &bgp->gr_info[afi][safi].t_route_select);
3430 }
3431
3432 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3433 {
3434 struct bgp_process_queue *pqnode = data;
3435 struct bgp *bgp = pqnode->bgp;
3436 struct bgp_table *table;
3437 struct bgp_dest *dest;
3438
3439 /* eoiu marker */
3440 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3441 bgp_process_main_one(bgp, NULL, 0, 0);
3442 /* should always have dedicated wq call */
3443 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3444 return WQ_SUCCESS;
3445 }
3446
3447 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3448 dest = STAILQ_FIRST(&pqnode->pqueue);
3449 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3450 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3451 table = bgp_dest_table(dest);
3452 /* note, new DESTs may be added as part of processing */
3453 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3454
3455 bgp_dest_unlock_node(dest);
3456 bgp_table_unlock(table);
3457 }
3458
3459 return WQ_SUCCESS;
3460 }
3461
3462 static void bgp_processq_del(struct work_queue *wq, void *data)
3463 {
3464 struct bgp_process_queue *pqnode = data;
3465
3466 bgp_unlock(pqnode->bgp);
3467
3468 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3469 }
3470
3471 void bgp_process_queue_init(struct bgp *bgp)
3472 {
3473 if (!bgp->process_queue) {
3474 char name[BUFSIZ];
3475
3476 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3477 bgp->process_queue = work_queue_new(bm->master, name);
3478 }
3479
3480 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3481 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3482 bgp->process_queue->spec.max_retries = 0;
3483 bgp->process_queue->spec.hold = 50;
3484 /* Use a higher yield value of 50ms for main queue processing */
3485 bgp->process_queue->spec.yield = 50 * 1000L;
3486 }
3487
3488 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3489 {
3490 struct bgp_process_queue *pqnode;
3491
3492 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3493 sizeof(struct bgp_process_queue));
3494
3495 /* unlocked in bgp_processq_del */
3496 pqnode->bgp = bgp_lock(bgp);
3497 STAILQ_INIT(&pqnode->pqueue);
3498
3499 return pqnode;
3500 }
3501
3502 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3503 {
3504 #define ARBITRARY_PROCESS_QLEN 10000
3505 struct work_queue *wq = bgp->process_queue;
3506 struct bgp_process_queue *pqnode;
3507 int pqnode_reuse = 0;
3508
3509 /* already scheduled for processing? */
3510 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3511 return;
3512
3513 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3514 * the workqueue
3515 */
3516 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3517 if (BGP_DEBUG(update, UPDATE_OUT))
3518 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3519 dest);
3520 return;
3521 }
3522
3523 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3524 if (BGP_DEBUG(update, UPDATE_OUT))
3525 zlog_debug(
3526 "Soft reconfigure table in progress for route %p",
3527 dest);
3528 return;
3529 }
3530
3531 if (wq == NULL)
3532 return;
3533
3534 /* Add route nodes to an existing work queue item until reaching the
3535 limit only if is from the same BGP view and it's not an EOIU marker
3536 */
3537 if (work_queue_item_count(wq)) {
3538 struct work_queue_item *item = work_queue_last_item(wq);
3539 pqnode = item->data;
3540
3541 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3542 || pqnode->bgp != bgp
3543 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3544 pqnode = bgp_processq_alloc(bgp);
3545 else
3546 pqnode_reuse = 1;
3547 } else
3548 pqnode = bgp_processq_alloc(bgp);
3549 /* all unlocked in bgp_process_wq */
3550 bgp_table_lock(bgp_dest_table(dest));
3551
3552 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3553 bgp_dest_lock_node(dest);
3554
3555 /* can't be enqueued twice */
3556 assert(STAILQ_NEXT(dest, pq) == NULL);
3557 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3558 pqnode->queued++;
3559
3560 if (!pqnode_reuse)
3561 work_queue_add(wq, pqnode);
3562
3563 return;
3564 }
3565
3566 void bgp_add_eoiu_mark(struct bgp *bgp)
3567 {
3568 struct bgp_process_queue *pqnode;
3569
3570 if (bgp->process_queue == NULL)
3571 return;
3572
3573 pqnode = bgp_processq_alloc(bgp);
3574
3575 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3576 work_queue_add(bgp->process_queue, pqnode);
3577 }
3578
3579 static void bgp_maximum_prefix_restart_timer(struct event *thread)
3580 {
3581 struct peer *peer;
3582
3583 peer = EVENT_ARG(thread);
3584 peer->t_pmax_restart = NULL;
3585
3586 if (bgp_debug_neighbor_events(peer))
3587 zlog_debug(
3588 "%s Maximum-prefix restart timer expired, restore peering",
3589 peer->host);
3590
3591 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3592 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3593 }
3594
3595 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3596 safi_t safi)
3597 {
3598 uint32_t count = 0;
3599 bool filtered = false;
3600 struct bgp_dest *dest;
3601 struct bgp_adj_in *ain;
3602 struct attr attr = {};
3603 struct bgp_table *table = peer->bgp->rib[afi][safi];
3604
3605 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3606 for (ain = dest->adj_in; ain; ain = ain->next) {
3607 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3608
3609 attr = *ain->attr;
3610
3611 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3612 == FILTER_DENY)
3613 filtered = true;
3614
3615 if (bgp_input_modifier(
3616 peer, rn_p, &attr, afi, safi,
3617 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3618 NULL, 0, NULL)
3619 == RMAP_DENY)
3620 filtered = true;
3621
3622 if (filtered)
3623 count++;
3624
3625 bgp_attr_flush(&attr);
3626 }
3627 }
3628
3629 return count;
3630 }
3631
3632 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3633 int always)
3634 {
3635 iana_afi_t pkt_afi;
3636 iana_safi_t pkt_safi;
3637 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3638 PEER_FLAG_MAX_PREFIX_FORCE))
3639 ? bgp_filtered_routes_count(peer, afi, safi)
3640 + peer->pcount[afi][safi]
3641 : peer->pcount[afi][safi];
3642
3643 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3644 return false;
3645
3646 if (pcount > peer->pmax[afi][safi]) {
3647 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3648 PEER_STATUS_PREFIX_LIMIT)
3649 && !always)
3650 return false;
3651
3652 zlog_info(
3653 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3654 get_afi_safi_str(afi, safi, false), peer, pcount,
3655 peer->pmax[afi][safi]);
3656 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3657
3658 if (CHECK_FLAG(peer->af_flags[afi][safi],
3659 PEER_FLAG_MAX_PREFIX_WARNING))
3660 return false;
3661
3662 /* Convert AFI, SAFI to values for packet. */
3663 pkt_afi = afi_int2iana(afi);
3664 pkt_safi = safi_int2iana(safi);
3665 {
3666 uint8_t ndata[7];
3667
3668 ndata[0] = (pkt_afi >> 8);
3669 ndata[1] = pkt_afi;
3670 ndata[2] = pkt_safi;
3671 ndata[3] = (peer->pmax[afi][safi] >> 24);
3672 ndata[4] = (peer->pmax[afi][safi] >> 16);
3673 ndata[5] = (peer->pmax[afi][safi] >> 8);
3674 ndata[6] = (peer->pmax[afi][safi]);
3675
3676 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3677 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3678 BGP_NOTIFY_CEASE_MAX_PREFIX,
3679 ndata, 7);
3680 }
3681
3682 /* Dynamic peers will just close their connection. */
3683 if (peer_dynamic_neighbor(peer))
3684 return true;
3685
3686 /* restart timer start */
3687 if (peer->pmax_restart[afi][safi]) {
3688 peer->v_pmax_restart =
3689 peer->pmax_restart[afi][safi] * 60;
3690
3691 if (bgp_debug_neighbor_events(peer))
3692 zlog_debug(
3693 "%pBP Maximum-prefix restart timer started for %d secs",
3694 peer, peer->v_pmax_restart);
3695
3696 BGP_TIMER_ON(peer->t_pmax_restart,
3697 bgp_maximum_prefix_restart_timer,
3698 peer->v_pmax_restart);
3699 }
3700
3701 return true;
3702 } else
3703 UNSET_FLAG(peer->af_sflags[afi][safi],
3704 PEER_STATUS_PREFIX_LIMIT);
3705
3706 if (pcount
3707 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3708 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3709 PEER_STATUS_PREFIX_THRESHOLD)
3710 && !always)
3711 return false;
3712
3713 zlog_info(
3714 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3715 get_afi_safi_str(afi, safi, false), peer, pcount,
3716 peer->pmax[afi][safi]);
3717 SET_FLAG(peer->af_sflags[afi][safi],
3718 PEER_STATUS_PREFIX_THRESHOLD);
3719 } else
3720 UNSET_FLAG(peer->af_sflags[afi][safi],
3721 PEER_STATUS_PREFIX_THRESHOLD);
3722 return false;
3723 }
3724
3725 /* Unconditionally remove the route from the RIB, without taking
3726 * damping into consideration (eg, because the session went down)
3727 */
3728 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3729 struct peer *peer, afi_t afi, safi_t safi)
3730 {
3731
3732 struct bgp *bgp = NULL;
3733 bool delete_route = false;
3734
3735 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3736 safi);
3737
3738 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3739 bgp_path_info_delete(dest, pi); /* keep historical info */
3740
3741 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3742 * flag
3743 */
3744 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3745 delete_route = true;
3746 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3747 delete_route = true;
3748 if (delete_route) {
3749 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3750 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3751 bgp = pi->peer->bgp;
3752 bgp->gr_info[afi][safi].gr_deferred--;
3753 }
3754 }
3755 }
3756
3757 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3758 bgp_process(peer->bgp, dest, afi, safi);
3759 }
3760
3761 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3762 struct peer *peer, afi_t afi, safi_t safi,
3763 struct prefix_rd *prd)
3764 {
3765 const struct prefix *p = bgp_dest_get_prefix(dest);
3766
3767 /* apply dampening, if result is suppressed, we'll be retaining
3768 * the bgp_path_info in the RIB for historical reference.
3769 */
3770 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3771 && peer->sort == BGP_PEER_EBGP)
3772 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3773 == BGP_DAMP_SUPPRESSED) {
3774 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3775 safi);
3776 return;
3777 }
3778
3779 #ifdef ENABLE_BGP_VNC
3780 if (safi == SAFI_MPLS_VPN) {
3781 struct bgp_dest *pdest = NULL;
3782 struct bgp_table *table = NULL;
3783
3784 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3785 (struct prefix *)prd);
3786 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3787 table = bgp_dest_get_bgp_table_info(pdest);
3788
3789 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3790 peer->bgp, prd, table, p, pi);
3791 }
3792 bgp_dest_unlock_node(pdest);
3793 }
3794 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3795 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3796
3797 vnc_import_bgp_del_route(peer->bgp, p, pi);
3798 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3799 }
3800 }
3801 #endif
3802
3803 /* If this is an EVPN route, process for un-import. */
3804 if (safi == SAFI_EVPN)
3805 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3806
3807 bgp_rib_remove(dest, pi, peer, afi, safi);
3808 }
3809
3810 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3811 struct peer *peer, struct attr *attr,
3812 struct bgp_dest *dest)
3813 {
3814 struct bgp_path_info *new;
3815
3816 /* Make new BGP info. */
3817 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3818 new->type = type;
3819 new->instance = instance;
3820 new->sub_type = sub_type;
3821 new->peer = peer;
3822 new->attr = attr;
3823 new->uptime = monotime(NULL);
3824 new->net = dest;
3825 return new;
3826 }
3827
3828 /* Check if received nexthop is valid or not. */
3829 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3830 uint8_t type, uint8_t stype, struct attr *attr,
3831 struct bgp_dest *dest)
3832 {
3833 bool ret = false;
3834 bool is_bgp_static_route =
3835 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3836 : false;
3837
3838 /*
3839 * Only validated for unicast and multicast currently.
3840 * Also valid for EVPN where the nexthop is an IP address.
3841 * If we are a bgp static route being checked then there is
3842 * no need to check to see if the nexthop is martian as
3843 * that it should be ok.
3844 */
3845 if (is_bgp_static_route ||
3846 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3847 return false;
3848
3849 /* If NEXT_HOP is present, validate it. */
3850 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3851 if (attr->nexthop.s_addr == INADDR_ANY ||
3852 !ipv4_unicast_valid(&attr->nexthop) ||
3853 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3854 return true;
3855 }
3856
3857 /* If MP_NEXTHOP is present, validate it. */
3858 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3859 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3860 * it is not an IPv6 link-local address.
3861 *
3862 * If we receive an UPDATE with nexthop length set to 32 bytes
3863 * we shouldn't discard an UPDATE if it's set to (::).
3864 * The link-local (2st) is validated along the code path later.
3865 */
3866 if (attr->mp_nexthop_len) {
3867 switch (attr->mp_nexthop_len) {
3868 case BGP_ATTR_NHLEN_IPV4:
3869 case BGP_ATTR_NHLEN_VPNV4:
3870 ret = (attr->mp_nexthop_global_in.s_addr ==
3871 INADDR_ANY ||
3872 !ipv4_unicast_valid(
3873 &attr->mp_nexthop_global_in) ||
3874 bgp_nexthop_self(bgp, afi, type, stype, attr,
3875 dest));
3876 break;
3877
3878 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3879 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3880 ret = (IN6_IS_ADDR_UNSPECIFIED(
3881 &attr->mp_nexthop_global)
3882 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3883 || IN6_IS_ADDR_MULTICAST(
3884 &attr->mp_nexthop_global)
3885 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3886 dest));
3887 break;
3888 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3889 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3890 || IN6_IS_ADDR_MULTICAST(
3891 &attr->mp_nexthop_global)
3892 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3893 dest));
3894 break;
3895
3896 default:
3897 ret = true;
3898 break;
3899 }
3900 }
3901
3902 return ret;
3903 }
3904
3905 static void bgp_attr_add_no_export_community(struct attr *attr)
3906 {
3907 struct community *old;
3908 struct community *new;
3909 struct community *merge;
3910 struct community *no_export;
3911
3912 old = bgp_attr_get_community(attr);
3913 no_export = community_str2com("no-export");
3914
3915 assert(no_export);
3916
3917 if (old) {
3918 merge = community_merge(community_dup(old), no_export);
3919
3920 if (!old->refcnt)
3921 community_free(&old);
3922
3923 new = community_uniq_sort(merge);
3924 community_free(&merge);
3925 } else {
3926 new = community_dup(no_export);
3927 }
3928
3929 community_free(&no_export);
3930
3931 bgp_attr_set_community(attr, new);
3932 }
3933
3934 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3935 struct attr *attr, const struct prefix *prefix,
3936 int *sub_type)
3937 {
3938 struct listnode *node, *nnode;
3939 struct bgp *bgp;
3940 bool accept_own_found = false;
3941
3942 if (safi != SAFI_MPLS_VPN)
3943 return false;
3944
3945 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3946 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3947 return false;
3948
3949 /* The route in question carries the ACCEPT_OWN community */
3950 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3951 struct community *comm = bgp_attr_get_community(attr);
3952
3953 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3954 accept_own_found = true;
3955 }
3956
3957 /* The route in question is targeted to one or more destination VRFs
3958 * on the router (as determined by inspecting the Route Target(s)).
3959 */
3960 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3961 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3962 continue;
3963
3964 if (accept_own_found &&
3965 ecommunity_include(
3966 bgp->vpn_policy[afi]
3967 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3968 bgp_attr_get_ecommunity(attr))) {
3969 if (bgp_debug_update(peer, prefix, NULL, 1))
3970 zlog_debug(
3971 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3972 peer, prefix);
3973
3974 /* Treat this route as imported, because it's leaked
3975 * already from another VRF, and we got an updated
3976 * version from route-reflector with ACCEPT_OWN
3977 * community.
3978 */
3979 *sub_type = BGP_ROUTE_IMPORTED;
3980
3981 return true;
3982 }
3983 }
3984
3985 return false;
3986 }
3987
3988 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3989 struct attr *attr, afi_t afi, safi_t safi, int type,
3990 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3991 uint32_t num_labels, int soft_reconfig,
3992 struct bgp_route_evpn *evpn)
3993 {
3994 int ret;
3995 int aspath_loop_count = 0;
3996 struct bgp_dest *dest;
3997 struct bgp *bgp;
3998 struct attr new_attr;
3999 struct attr *attr_new;
4000 struct bgp_path_info *pi;
4001 struct bgp_path_info *new = NULL;
4002 struct bgp_path_info_extra *extra;
4003 const char *reason;
4004 char pfx_buf[BGP_PRD_PATH_STRLEN];
4005 int connected = 0;
4006 int do_loop_check = 1;
4007 int has_valid_label = 0;
4008 afi_t nh_afi;
4009 bool force_evpn_import = false;
4010 safi_t orig_safi = safi;
4011 bool leak_success = true;
4012 int allowas_in = 0;
4013
4014 if (frrtrace_enabled(frr_bgp, process_update)) {
4015 char pfxprint[PREFIX2STR_BUFFER];
4016
4017 prefix2str(p, pfxprint, sizeof(pfxprint));
4018 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4019 afi, safi, attr);
4020 }
4021
4022 #ifdef ENABLE_BGP_VNC
4023 int vnc_implicit_withdraw = 0;
4024 #endif
4025 int same_attr = 0;
4026 const struct prefix *bgp_nht_param_prefix;
4027
4028 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4029 if (orig_safi == SAFI_LABELED_UNICAST)
4030 safi = SAFI_UNICAST;
4031
4032 memset(&new_attr, 0, sizeof(new_attr));
4033 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4034 new_attr.label = MPLS_INVALID_LABEL;
4035
4036 bgp = peer->bgp;
4037 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4038 /* TODO: Check to see if we can get rid of "is_valid_label" */
4039 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4040 has_valid_label = (num_labels > 0) ? 1 : 0;
4041 else
4042 has_valid_label = bgp_is_valid_label(label);
4043
4044 if (has_valid_label)
4045 assert(label != NULL);
4046
4047 /* Update overlay index of the attribute */
4048 if (afi == AFI_L2VPN && evpn)
4049 memcpy(&attr->evpn_overlay, evpn,
4050 sizeof(struct bgp_route_evpn));
4051
4052 /* When peer's soft reconfiguration enabled. Record input packet in
4053 Adj-RIBs-In. */
4054 if (!soft_reconfig
4055 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4056 && peer != bgp->peer_self)
4057 bgp_adj_in_set(dest, peer, attr, addpath_id);
4058
4059 /* Update permitted loop count */
4060 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4061 allowas_in = peer->allowas_in[afi][safi];
4062
4063 /* Check previously received route. */
4064 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4065 if (pi->peer == peer && pi->type == type
4066 && pi->sub_type == sub_type
4067 && pi->addpath_rx_id == addpath_id)
4068 break;
4069
4070 /* AS path local-as loop check. */
4071 if (peer->change_local_as) {
4072 if (allowas_in)
4073 aspath_loop_count = allowas_in;
4074 else if (!CHECK_FLAG(peer->flags,
4075 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4076 aspath_loop_count = 1;
4077
4078 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4079 > aspath_loop_count) {
4080 peer->stat_pfx_aspath_loop++;
4081 reason = "as-path contains our own AS;";
4082 goto filtered;
4083 }
4084 }
4085
4086 /* If the peer is configured for "allowas-in origin" and the last ASN in
4087 * the
4088 * as-path is our ASN then we do not need to call aspath_loop_check
4089 */
4090 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4091 if (aspath_get_last_as(attr->aspath) == bgp->as)
4092 do_loop_check = 0;
4093
4094 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4095 bgp_nht_param_prefix = NULL;
4096 else
4097 bgp_nht_param_prefix = p;
4098
4099 /* AS path loop check. */
4100 if (do_loop_check) {
4101 if (aspath_loop_check(attr->aspath, bgp->as) >
4102 peer->allowas_in[afi][safi]) {
4103 peer->stat_pfx_aspath_loop++;
4104 reason = "as-path contains our own AS;";
4105 goto filtered;
4106 }
4107 }
4108
4109 /* If we're a CONFED we need to loop check the CONFED ID too */
4110 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4111 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4112 peer->allowas_in[afi][safi]) {
4113 peer->stat_pfx_aspath_loop++;
4114 reason = "as-path contains our own confed AS;";
4115 goto filtered;
4116 }
4117
4118 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4119 * enabled, then take care of that too.
4120 */
4121 bool accept_own = false;
4122
4123 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4124 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4125 accept_own =
4126 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4127 if (!accept_own) {
4128 peer->stat_pfx_originator_loop++;
4129 reason = "originator is us;";
4130 goto filtered;
4131 }
4132 }
4133
4134 /* Route reflector cluster ID check. */
4135 if (bgp_cluster_filter(peer, attr)) {
4136 peer->stat_pfx_cluster_loop++;
4137 reason = "reflected from the same cluster;";
4138 goto filtered;
4139 }
4140
4141 /* Apply incoming filter. */
4142 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4143 peer->stat_pfx_filter++;
4144 reason = "filter;";
4145 goto filtered;
4146 }
4147
4148 /* RFC 8212 to prevent route leaks.
4149 * This specification intends to improve this situation by requiring the
4150 * explicit configuration of both BGP Import and Export Policies for any
4151 * External BGP (EBGP) session such as customers, peers, or
4152 * confederation boundaries for all enabled address families. Through
4153 * codification of the aforementioned requirement, operators will
4154 * benefit from consistent behavior across different BGP
4155 * implementations.
4156 */
4157 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4158 if (!bgp_inbound_policy_exists(peer,
4159 &peer->filter[afi][safi])) {
4160 reason = "inbound policy missing";
4161 if (monotime_since(&bgp->ebgprequirespolicywarning,
4162 NULL) > FIFTEENMINUTE2USEC ||
4163 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4164 zlog_warn(
4165 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4166 monotime(&bgp->ebgprequirespolicywarning);
4167 }
4168 goto filtered;
4169 }
4170
4171 /* draft-ietf-idr-deprecate-as-set-confed-set
4172 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4173 * Eventually, This document (if approved) updates RFC 4271
4174 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4175 * and obsoletes RFC 6472.
4176 */
4177 if (peer->bgp->reject_as_sets)
4178 if (aspath_check_as_sets(attr->aspath)) {
4179 reason =
4180 "as-path contains AS_SET or AS_CONFED_SET type;";
4181 goto filtered;
4182 }
4183
4184 new_attr = *attr;
4185
4186 /* Apply incoming route-map.
4187 * NB: new_attr may now contain newly allocated values from route-map
4188 * "set"
4189 * commands, so we need bgp_attr_flush in the error paths, until we
4190 * intern
4191 * the attr (which takes over the memory references) */
4192 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4193 num_labels, dest)
4194 == RMAP_DENY) {
4195 peer->stat_pfx_filter++;
4196 reason = "route-map;";
4197 bgp_attr_flush(&new_attr);
4198 goto filtered;
4199 }
4200
4201 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4202 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4203 /* remove from RIB previous entry */
4204 bgp_zebra_withdraw(p, pi, bgp, safi);
4205 }
4206
4207 if (peer->sort == BGP_PEER_EBGP) {
4208
4209 /* rfc7999:
4210 * A BGP speaker receiving an announcement tagged with the
4211 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4212 * NO_EXPORT community as defined in RFC1997, or a
4213 * similar community, to prevent propagation of the
4214 * prefix outside the local AS. The community to prevent
4215 * propagation SHOULD be chosen according to the operator's
4216 * routing policy.
4217 */
4218 if (bgp_attr_get_community(&new_attr) &&
4219 community_include(bgp_attr_get_community(&new_attr),
4220 COMMUNITY_BLACKHOLE))
4221 bgp_attr_add_no_export_community(&new_attr);
4222
4223 /* If we receive the graceful-shutdown community from an eBGP
4224 * peer we must lower local-preference */
4225 if (bgp_attr_get_community(&new_attr) &&
4226 community_include(bgp_attr_get_community(&new_attr),
4227 COMMUNITY_GSHUT)) {
4228 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4229 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4230
4231 /* If graceful-shutdown is configured globally or
4232 * per neighbor, then add the GSHUT community to
4233 * all paths received from eBGP peers. */
4234 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4235 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4236 bgp_attr_add_gshut_community(&new_attr);
4237 }
4238
4239 /* next hop check. */
4240 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4241 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4242 &new_attr, dest)) {
4243 peer->stat_pfx_nh_invalid++;
4244 reason = "martian or self next-hop;";
4245 bgp_attr_flush(&new_attr);
4246 goto filtered;
4247 }
4248
4249 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4250 peer->stat_pfx_nh_invalid++;
4251 reason = "self mac;";
4252 bgp_attr_flush(&new_attr);
4253 goto filtered;
4254 }
4255
4256 if (bgp_check_role_applicability(afi, safi) &&
4257 bgp_otc_filter(peer, &new_attr)) {
4258 reason = "failing otc validation";
4259 bgp_attr_flush(&new_attr);
4260 goto filtered;
4261 }
4262
4263 /* If neighbor soo is configured, tag all incoming routes with
4264 * this SoO tag and then filter out advertisements in
4265 * subgroup_announce_check() if it matches the configured SoO
4266 * on the other peer.
4267 */
4268 if (peer->soo[afi][safi]) {
4269 struct ecommunity *old_ecomm =
4270 bgp_attr_get_ecommunity(&new_attr);
4271 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4272 struct ecommunity *new_ecomm;
4273
4274 if (old_ecomm) {
4275 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4276 ecomm_soo);
4277
4278 if (!old_ecomm->refcnt)
4279 ecommunity_free(&old_ecomm);
4280 } else {
4281 new_ecomm = ecommunity_dup(ecomm_soo);
4282 }
4283
4284 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4285 }
4286
4287 attr_new = bgp_attr_intern(&new_attr);
4288
4289 /* If the update is implicit withdraw. */
4290 if (pi) {
4291 pi->uptime = monotime(NULL);
4292 same_attr = attrhash_cmp(pi->attr, attr_new);
4293
4294 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4295
4296 /* Same attribute comes in. */
4297 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4298 && same_attr
4299 && (!has_valid_label
4300 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4301 num_labels * sizeof(mpls_label_t))
4302 == 0)) {
4303 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4304 BGP_CONFIG_DAMPENING)
4305 && peer->sort == BGP_PEER_EBGP
4306 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4307 if (bgp_debug_update(peer, p, NULL, 1)) {
4308 bgp_debug_rdpfxpath2str(
4309 afi, safi, prd, p, label,
4310 num_labels, addpath_id ? 1 : 0,
4311 addpath_id, evpn, pfx_buf,
4312 sizeof(pfx_buf));
4313 zlog_debug("%pBP rcvd %s", peer,
4314 pfx_buf);
4315 }
4316
4317 if (bgp_damp_update(pi, dest, afi, safi)
4318 != BGP_DAMP_SUPPRESSED) {
4319 bgp_aggregate_increment(bgp, p, pi, afi,
4320 safi);
4321 bgp_process(bgp, dest, afi, safi);
4322 }
4323 } else /* Duplicate - odd */
4324 {
4325 if (bgp_debug_update(peer, p, NULL, 1)) {
4326 if (!peer->rcvd_attr_printed) {
4327 zlog_debug(
4328 "%pBP rcvd UPDATE w/ attr: %s",
4329 peer,
4330 peer->rcvd_attr_str);
4331 peer->rcvd_attr_printed = 1;
4332 }
4333
4334 bgp_debug_rdpfxpath2str(
4335 afi, safi, prd, p, label,
4336 num_labels, addpath_id ? 1 : 0,
4337 addpath_id, evpn, pfx_buf,
4338 sizeof(pfx_buf));
4339 zlog_debug(
4340 "%pBP rcvd %s...duplicate ignored",
4341 peer, pfx_buf);
4342 }
4343
4344 /* graceful restart STALE flag unset. */
4345 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4346 bgp_path_info_unset_flag(
4347 dest, pi, BGP_PATH_STALE);
4348 bgp_dest_set_defer_flag(dest, false);
4349 bgp_process(bgp, dest, afi, safi);
4350 }
4351 }
4352
4353 bgp_dest_unlock_node(dest);
4354 bgp_attr_unintern(&attr_new);
4355
4356 return;
4357 }
4358
4359 /* Withdraw/Announce before we fully processed the withdraw */
4360 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4361 if (bgp_debug_update(peer, p, NULL, 1)) {
4362 bgp_debug_rdpfxpath2str(
4363 afi, safi, prd, p, label, num_labels,
4364 addpath_id ? 1 : 0, addpath_id, evpn,
4365 pfx_buf, sizeof(pfx_buf));
4366 zlog_debug(
4367 "%pBP rcvd %s, flapped quicker than processing",
4368 peer, pfx_buf);
4369 }
4370
4371 bgp_path_info_restore(dest, pi);
4372
4373 /*
4374 * If the BGP_PATH_REMOVED flag is set, then EVPN
4375 * routes would have been unimported already when a
4376 * prior BGP withdraw processing happened. Such routes
4377 * need to be imported again, so flag accordingly.
4378 */
4379 force_evpn_import = true;
4380 } else {
4381 /* implicit withdraw, decrement aggregate and pcount
4382 * here. only if update is accepted, they'll increment
4383 * below.
4384 */
4385 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4386 }
4387
4388 /* Received Logging. */
4389 if (bgp_debug_update(peer, p, NULL, 1)) {
4390 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4391 num_labels, addpath_id ? 1 : 0,
4392 addpath_id, evpn, pfx_buf,
4393 sizeof(pfx_buf));
4394 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4395 }
4396
4397 /* graceful restart STALE flag unset. */
4398 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4399 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4400 bgp_dest_set_defer_flag(dest, false);
4401 }
4402
4403 /* The attribute is changed. */
4404 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4405
4406 /* Update bgp route dampening information. */
4407 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4408 && peer->sort == BGP_PEER_EBGP) {
4409 /* This is implicit withdraw so we should update
4410 dampening
4411 information. */
4412 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4413 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4414 }
4415 #ifdef ENABLE_BGP_VNC
4416 if (safi == SAFI_MPLS_VPN) {
4417 struct bgp_dest *pdest = NULL;
4418 struct bgp_table *table = NULL;
4419
4420 pdest = bgp_node_get(bgp->rib[afi][safi],
4421 (struct prefix *)prd);
4422 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4423 table = bgp_dest_get_bgp_table_info(pdest);
4424
4425 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4426 bgp, prd, table, p, pi);
4427 }
4428 bgp_dest_unlock_node(pdest);
4429 }
4430 if ((afi == AFI_IP || afi == AFI_IP6)
4431 && (safi == SAFI_UNICAST)) {
4432 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4433 /*
4434 * Implicit withdraw case.
4435 */
4436 ++vnc_implicit_withdraw;
4437 vnc_import_bgp_del_route(bgp, p, pi);
4438 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4439 }
4440 }
4441 #endif
4442
4443 /* Special handling for EVPN update of an existing route. If the
4444 * extended community attribute has changed, we need to
4445 * un-import
4446 * the route using its existing extended community. It will be
4447 * subsequently processed for import with the new extended
4448 * community.
4449 */
4450 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4451 && !same_attr) {
4452 if ((pi->attr->flag
4453 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4454 && (attr_new->flag
4455 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4456 int cmp;
4457
4458 cmp = ecommunity_cmp(
4459 bgp_attr_get_ecommunity(pi->attr),
4460 bgp_attr_get_ecommunity(attr_new));
4461 if (!cmp) {
4462 if (bgp_debug_update(peer, p, NULL, 1))
4463 zlog_debug(
4464 "Change in EXT-COMM, existing %s new %s",
4465 ecommunity_str(
4466 bgp_attr_get_ecommunity(
4467 pi->attr)),
4468 ecommunity_str(
4469 bgp_attr_get_ecommunity(
4470 attr_new)));
4471 if (safi == SAFI_EVPN)
4472 bgp_evpn_unimport_route(
4473 bgp, afi, safi, p, pi);
4474 else /* SAFI_MPLS_VPN */
4475 vpn_leak_to_vrf_withdraw(pi);
4476 }
4477 }
4478 }
4479
4480 /* Update to new attribute. */
4481 bgp_attr_unintern(&pi->attr);
4482 pi->attr = attr_new;
4483
4484 /* Update MPLS label */
4485 if (has_valid_label) {
4486 extra = bgp_path_info_extra_get(pi);
4487 if (extra->label != label) {
4488 memcpy(&extra->label, label,
4489 num_labels * sizeof(mpls_label_t));
4490 extra->num_labels = num_labels;
4491 }
4492 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4493 bgp_set_valid_label(&extra->label[0]);
4494 }
4495
4496 /* Update SRv6 SID */
4497 if (attr->srv6_l3vpn) {
4498 extra = bgp_path_info_extra_get(pi);
4499 if (sid_diff(&extra->sid[0].sid,
4500 &attr->srv6_l3vpn->sid)) {
4501 sid_copy(&extra->sid[0].sid,
4502 &attr->srv6_l3vpn->sid);
4503 extra->num_sids = 1;
4504
4505 extra->sid[0].loc_block_len = 0;
4506 extra->sid[0].loc_node_len = 0;
4507 extra->sid[0].func_len = 0;
4508 extra->sid[0].arg_len = 0;
4509 extra->sid[0].transposition_len = 0;
4510 extra->sid[0].transposition_offset = 0;
4511
4512 if (attr->srv6_l3vpn->loc_block_len != 0) {
4513 extra->sid[0].loc_block_len =
4514 attr->srv6_l3vpn->loc_block_len;
4515 extra->sid[0].loc_node_len =
4516 attr->srv6_l3vpn->loc_node_len;
4517 extra->sid[0].func_len =
4518 attr->srv6_l3vpn->func_len;
4519 extra->sid[0].arg_len =
4520 attr->srv6_l3vpn->arg_len;
4521 extra->sid[0].transposition_len =
4522 attr->srv6_l3vpn
4523 ->transposition_len;
4524 extra->sid[0].transposition_offset =
4525 attr->srv6_l3vpn
4526 ->transposition_offset;
4527 }
4528 }
4529 } else if (attr->srv6_vpn) {
4530 extra = bgp_path_info_extra_get(pi);
4531 if (sid_diff(&extra->sid[0].sid,
4532 &attr->srv6_vpn->sid)) {
4533 sid_copy(&extra->sid[0].sid,
4534 &attr->srv6_vpn->sid);
4535 extra->num_sids = 1;
4536 }
4537 }
4538
4539 #ifdef ENABLE_BGP_VNC
4540 if ((afi == AFI_IP || afi == AFI_IP6)
4541 && (safi == SAFI_UNICAST)) {
4542 if (vnc_implicit_withdraw) {
4543 /*
4544 * Add back the route with its new attributes
4545 * (e.g., nexthop).
4546 * The route is still selected, until the route
4547 * selection
4548 * queued by bgp_process actually runs. We have
4549 * to make this
4550 * update to the VNC side immediately to avoid
4551 * racing against
4552 * configuration changes (e.g., route-map
4553 * changes) which
4554 * trigger re-importation of the entire RIB.
4555 */
4556 vnc_import_bgp_add_route(bgp, p, pi);
4557 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4558 }
4559 }
4560 #endif
4561
4562 /* Update bgp route dampening information. */
4563 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4564 && peer->sort == BGP_PEER_EBGP) {
4565 /* Now we do normal update dampening. */
4566 ret = bgp_damp_update(pi, dest, afi, safi);
4567 if (ret == BGP_DAMP_SUPPRESSED) {
4568 bgp_dest_unlock_node(dest);
4569 return;
4570 }
4571 }
4572
4573 /* Nexthop reachability check - for unicast and
4574 * labeled-unicast.. */
4575 if (((afi == AFI_IP || afi == AFI_IP6)
4576 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4577 || (safi == SAFI_EVPN &&
4578 bgp_evpn_is_prefix_nht_supported(p))) {
4579 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4580 && peer->ttl == BGP_DEFAULT_TTL
4581 && !CHECK_FLAG(peer->flags,
4582 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4583 && !CHECK_FLAG(bgp->flags,
4584 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4585 connected = 1;
4586 else
4587 connected = 0;
4588
4589 struct bgp *bgp_nexthop = bgp;
4590
4591 if (pi->extra && pi->extra->bgp_orig)
4592 bgp_nexthop = pi->extra->bgp_orig;
4593
4594 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4595
4596 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4597 safi, pi, NULL, connected,
4598 bgp_nht_param_prefix) ||
4599 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4600 bgp_path_info_set_flag(dest, pi,
4601 BGP_PATH_VALID);
4602 else {
4603 if (BGP_DEBUG(nht, NHT)) {
4604 zlog_debug("%s(%pI4): NH unresolved",
4605 __func__,
4606 (in_addr_t *)&attr_new->nexthop);
4607 }
4608 bgp_path_info_unset_flag(dest, pi,
4609 BGP_PATH_VALID);
4610 }
4611 } else {
4612 if (accept_own)
4613 bgp_path_info_set_flag(dest, pi,
4614 BGP_PATH_ACCEPT_OWN);
4615
4616 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4617 }
4618
4619 #ifdef ENABLE_BGP_VNC
4620 if (safi == SAFI_MPLS_VPN) {
4621 struct bgp_dest *pdest = NULL;
4622 struct bgp_table *table = NULL;
4623
4624 pdest = bgp_node_get(bgp->rib[afi][safi],
4625 (struct prefix *)prd);
4626 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4627 table = bgp_dest_get_bgp_table_info(pdest);
4628
4629 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4630 bgp, prd, table, p, pi);
4631 }
4632 bgp_dest_unlock_node(pdest);
4633 }
4634 #endif
4635
4636 /* If this is an EVPN route and some attribute has changed,
4637 * or we are explicitly told to perform a route import, process
4638 * route for import. If the extended community has changed, we
4639 * would
4640 * have done the un-import earlier and the import would result
4641 * in the
4642 * route getting injected into appropriate L2 VNIs. If it is
4643 * just
4644 * some other attribute change, the import will result in
4645 * updating
4646 * the attributes for the route in the VNI(s).
4647 */
4648 if (safi == SAFI_EVPN &&
4649 (!same_attr || force_evpn_import) &&
4650 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4651 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4652
4653 /* Process change. */
4654 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4655
4656 bgp_process(bgp, dest, afi, safi);
4657 bgp_dest_unlock_node(dest);
4658
4659 if (SAFI_UNICAST == safi
4660 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4661 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4662
4663 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4664 }
4665 if ((SAFI_MPLS_VPN == safi)
4666 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4667 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4668 }
4669
4670 #ifdef ENABLE_BGP_VNC
4671 if (SAFI_MPLS_VPN == safi) {
4672 mpls_label_t label_decoded = decode_label(label);
4673
4674 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4675 type, sub_type, &label_decoded);
4676 }
4677 if (SAFI_ENCAP == safi) {
4678 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4679 type, sub_type, NULL);
4680 }
4681 #endif
4682 if ((safi == SAFI_MPLS_VPN) &&
4683 !CHECK_FLAG(bgp->af_flags[afi][safi],
4684 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4685 !leak_success) {
4686 bgp_unlink_nexthop(pi);
4687 bgp_path_info_delete(dest, pi);
4688 }
4689 return;
4690 } // End of implicit withdraw
4691
4692 /* Received Logging. */
4693 if (bgp_debug_update(peer, p, NULL, 1)) {
4694 if (!peer->rcvd_attr_printed) {
4695 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4696 peer->rcvd_attr_str);
4697 peer->rcvd_attr_printed = 1;
4698 }
4699
4700 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4701 addpath_id ? 1 : 0, addpath_id, evpn,
4702 pfx_buf, sizeof(pfx_buf));
4703 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4704 }
4705
4706 /* Make new BGP info. */
4707 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4708
4709 /* Update MPLS label */
4710 if (has_valid_label) {
4711 extra = bgp_path_info_extra_get(new);
4712 if (extra->label != label) {
4713 memcpy(&extra->label, label,
4714 num_labels * sizeof(mpls_label_t));
4715 extra->num_labels = num_labels;
4716 }
4717 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4718 bgp_set_valid_label(&extra->label[0]);
4719 }
4720
4721 /* Update SRv6 SID */
4722 if (safi == SAFI_MPLS_VPN) {
4723 extra = bgp_path_info_extra_get(new);
4724 if (attr->srv6_l3vpn) {
4725 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4726 extra->num_sids = 1;
4727
4728 extra->sid[0].loc_block_len =
4729 attr->srv6_l3vpn->loc_block_len;
4730 extra->sid[0].loc_node_len =
4731 attr->srv6_l3vpn->loc_node_len;
4732 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4733 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4734 extra->sid[0].transposition_len =
4735 attr->srv6_l3vpn->transposition_len;
4736 extra->sid[0].transposition_offset =
4737 attr->srv6_l3vpn->transposition_offset;
4738 } else if (attr->srv6_vpn) {
4739 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4740 extra->num_sids = 1;
4741 }
4742 }
4743
4744 /* Nexthop reachability check. */
4745 if (((afi == AFI_IP || afi == AFI_IP6)
4746 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4747 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4748 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4749 && peer->ttl == BGP_DEFAULT_TTL
4750 && !CHECK_FLAG(peer->flags,
4751 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4752 && !CHECK_FLAG(bgp->flags,
4753 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4754 connected = 1;
4755 else
4756 connected = 0;
4757
4758 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4759
4760 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4761 connected, bgp_nht_param_prefix) ||
4762 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4763 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4764 else {
4765 if (BGP_DEBUG(nht, NHT))
4766 zlog_debug("%s(%pI4): NH unresolved", __func__,
4767 &attr_new->nexthop);
4768 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4769 }
4770 } else {
4771 if (accept_own)
4772 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4773
4774 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4775 }
4776
4777 /* If maximum prefix count is configured and current prefix
4778 * count exeed it.
4779 */
4780 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4781 reason = "maximum-prefix overflow";
4782 bgp_attr_flush(&new_attr);
4783 goto filtered;
4784 }
4785
4786 /* Addpath ID */
4787 new->addpath_rx_id = addpath_id;
4788
4789 /* Increment prefix */
4790 bgp_aggregate_increment(bgp, p, new, afi, safi);
4791
4792 /* Register new BGP information. */
4793 bgp_path_info_add(dest, new);
4794
4795 /* route_node_get lock */
4796 bgp_dest_unlock_node(dest);
4797
4798 #ifdef ENABLE_BGP_VNC
4799 if (safi == SAFI_MPLS_VPN) {
4800 struct bgp_dest *pdest = NULL;
4801 struct bgp_table *table = NULL;
4802
4803 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4804 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4805 table = bgp_dest_get_bgp_table_info(pdest);
4806
4807 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4808 bgp, prd, table, p, new);
4809 }
4810 bgp_dest_unlock_node(pdest);
4811 }
4812 #endif
4813
4814 /* If this is an EVPN route, process for import. */
4815 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4816 bgp_evpn_import_route(bgp, afi, safi, p, new);
4817
4818 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4819
4820 /* Process change. */
4821 bgp_process(bgp, dest, afi, safi);
4822
4823 if (SAFI_UNICAST == safi
4824 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4825 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4826 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4827 }
4828 if ((SAFI_MPLS_VPN == safi)
4829 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4830 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4831 }
4832 #ifdef ENABLE_BGP_VNC
4833 if (SAFI_MPLS_VPN == safi) {
4834 mpls_label_t label_decoded = decode_label(label);
4835
4836 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4837 sub_type, &label_decoded);
4838 }
4839 if (SAFI_ENCAP == safi) {
4840 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4841 sub_type, NULL);
4842 }
4843 #endif
4844 if ((safi == SAFI_MPLS_VPN) &&
4845 !CHECK_FLAG(bgp->af_flags[afi][safi],
4846 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4847 !leak_success) {
4848 bgp_unlink_nexthop(new);
4849 bgp_path_info_delete(dest, new);
4850 }
4851
4852 return;
4853
4854 /* This BGP update is filtered. Log the reason then update BGP
4855 entry. */
4856 filtered:
4857 if (new) {
4858 bgp_unlink_nexthop(new);
4859 bgp_path_info_delete(dest, new);
4860 bgp_path_info_extra_free(&new->extra);
4861 XFREE(MTYPE_BGP_ROUTE, new);
4862 }
4863
4864 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4865
4866 if (bgp_debug_update(peer, p, NULL, 1)) {
4867 if (!peer->rcvd_attr_printed) {
4868 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4869 peer->rcvd_attr_str);
4870 peer->rcvd_attr_printed = 1;
4871 }
4872
4873 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4874 addpath_id ? 1 : 0, addpath_id, evpn,
4875 pfx_buf, sizeof(pfx_buf));
4876 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4877 peer, pfx_buf, reason);
4878 }
4879
4880 if (pi) {
4881 /* If this is an EVPN route, un-import it as it is now filtered.
4882 */
4883 if (safi == SAFI_EVPN)
4884 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4885
4886 if (SAFI_UNICAST == safi
4887 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4888 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4889
4890 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4891 }
4892 if ((SAFI_MPLS_VPN == safi)
4893 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4894
4895 vpn_leak_to_vrf_withdraw(pi);
4896 }
4897
4898 bgp_rib_remove(dest, pi, peer, afi, safi);
4899 }
4900
4901 bgp_dest_unlock_node(dest);
4902
4903 #ifdef ENABLE_BGP_VNC
4904 /*
4905 * Filtered update is treated as an implicit withdrawal (see
4906 * bgp_rib_remove()
4907 * a few lines above)
4908 */
4909 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4910 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4911 0);
4912 }
4913 #endif
4914
4915 return;
4916 }
4917
4918 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4919 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4920 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4921 uint32_t num_labels, struct bgp_route_evpn *evpn)
4922 {
4923 struct bgp *bgp;
4924 char pfx_buf[BGP_PRD_PATH_STRLEN];
4925 struct bgp_dest *dest;
4926 struct bgp_path_info *pi;
4927
4928 #ifdef ENABLE_BGP_VNC
4929 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4930 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4931 0);
4932 }
4933 #endif
4934
4935 bgp = peer->bgp;
4936
4937 /* Lookup node. */
4938 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4939
4940 /* If peer is soft reconfiguration enabled. Record input packet for
4941 * further calculation.
4942 *
4943 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4944 * routes that are filtered. This tanks out Quagga RS pretty badly due
4945 * to
4946 * the iteration over all RS clients.
4947 * Since we need to remove the entry from adj_in anyway, do that first
4948 * and
4949 * if there was no entry, we don't need to do anything more.
4950 */
4951 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4952 && peer != bgp->peer_self)
4953 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4954 peer->stat_pfx_dup_withdraw++;
4955
4956 if (bgp_debug_update(peer, p, NULL, 1)) {
4957 bgp_debug_rdpfxpath2str(
4958 afi, safi, prd, p, label, num_labels,
4959 addpath_id ? 1 : 0, addpath_id, NULL,
4960 pfx_buf, sizeof(pfx_buf));
4961 zlog_debug(
4962 "%s withdrawing route %s not in adj-in",
4963 peer->host, pfx_buf);
4964 }
4965 bgp_dest_unlock_node(dest);
4966 return;
4967 }
4968
4969 /* Lookup withdrawn route. */
4970 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4971 if (pi->peer == peer && pi->type == type
4972 && pi->sub_type == sub_type
4973 && pi->addpath_rx_id == addpath_id)
4974 break;
4975
4976 /* Logging. */
4977 if (bgp_debug_update(peer, p, NULL, 1)) {
4978 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4979 addpath_id ? 1 : 0, addpath_id, NULL,
4980 pfx_buf, sizeof(pfx_buf));
4981 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4982 pfx_buf);
4983 }
4984
4985 /* Withdraw specified route from routing table. */
4986 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4987 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4988 if (SAFI_UNICAST == safi
4989 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4990 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4991 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4992 }
4993 if ((SAFI_MPLS_VPN == safi)
4994 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4995
4996 vpn_leak_to_vrf_withdraw(pi);
4997 }
4998 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4999 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5000 addpath_id ? 1 : 0, addpath_id, NULL,
5001 pfx_buf, sizeof(pfx_buf));
5002 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5003 }
5004
5005 /* Unlock bgp_node_get() lock. */
5006 bgp_dest_unlock_node(dest);
5007
5008 return;
5009 }
5010
5011 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5012 int withdraw)
5013 {
5014 struct update_subgroup *subgrp;
5015 subgrp = peer_subgroup(peer, afi, safi);
5016 subgroup_default_originate(subgrp, withdraw);
5017 }
5018
5019
5020 /*
5021 * bgp_stop_announce_route_timer
5022 */
5023 void bgp_stop_announce_route_timer(struct peer_af *paf)
5024 {
5025 if (!paf->t_announce_route)
5026 return;
5027
5028 EVENT_OFF(paf->t_announce_route);
5029 }
5030
5031 /*
5032 * bgp_announce_route_timer_expired
5033 *
5034 * Callback that is invoked when the route announcement timer for a
5035 * peer_af expires.
5036 */
5037 static void bgp_announce_route_timer_expired(struct event *t)
5038 {
5039 struct peer_af *paf;
5040 struct peer *peer;
5041
5042 paf = EVENT_ARG(t);
5043 peer = paf->peer;
5044
5045 if (!peer_established(peer))
5046 return;
5047
5048 if (!peer->afc_nego[paf->afi][paf->safi])
5049 return;
5050
5051 peer_af_announce_route(paf, 1);
5052
5053 /* Notify BGP conditional advertisement scanner percess */
5054 peer->advmap_config_change[paf->afi][paf->safi] = true;
5055 }
5056
5057 /*
5058 * bgp_announce_route
5059 *
5060 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5061 *
5062 * if force is true we will force an update even if the update
5063 * limiting code is attempted to kick in.
5064 */
5065 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5066 {
5067 struct peer_af *paf;
5068 struct update_subgroup *subgrp;
5069
5070 paf = peer_af_find(peer, afi, safi);
5071 if (!paf)
5072 return;
5073 subgrp = PAF_SUBGRP(paf);
5074
5075 /*
5076 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5077 * or a refresh has already been triggered.
5078 */
5079 if (!subgrp || paf->t_announce_route)
5080 return;
5081
5082 if (force)
5083 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5084
5085 /*
5086 * Start a timer to stagger/delay the announce. This serves
5087 * two purposes - announcement can potentially be combined for
5088 * multiple peers and the announcement doesn't happen in the
5089 * vty context.
5090 */
5091 event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5092 (subgrp->peer_count == 1)
5093 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5094 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5095 &paf->t_announce_route);
5096 }
5097
5098 /*
5099 * Announce routes from all AF tables to a peer.
5100 *
5101 * This should ONLY be called when there is a need to refresh the
5102 * routes to the peer based on a policy change for this peer alone
5103 * or a route refresh request received from the peer.
5104 * The operation will result in splitting the peer from its existing
5105 * subgroups and putting it in new subgroups.
5106 */
5107 void bgp_announce_route_all(struct peer *peer)
5108 {
5109 afi_t afi;
5110 safi_t safi;
5111
5112 FOREACH_AFI_SAFI (afi, safi)
5113 bgp_announce_route(peer, afi, safi, false);
5114 }
5115
5116 /* Flag or unflag bgp_dest to determine whether it should be treated by
5117 * bgp_soft_reconfig_table_task.
5118 * Flag if flag is true. Unflag if flag is false.
5119 */
5120 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5121 {
5122 struct bgp_dest *dest;
5123 struct bgp_adj_in *ain;
5124
5125 if (!table)
5126 return;
5127
5128 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5129 for (ain = dest->adj_in; ain; ain = ain->next) {
5130 if (ain->peer != NULL)
5131 break;
5132 }
5133 if (flag && ain != NULL && ain->peer != NULL)
5134 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5135 else
5136 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5137 }
5138 }
5139
5140 static void bgp_soft_reconfig_table_update(struct peer *peer,
5141 struct bgp_dest *dest,
5142 struct bgp_adj_in *ain, afi_t afi,
5143 safi_t safi, struct prefix_rd *prd)
5144 {
5145 struct bgp_path_info *pi;
5146 uint32_t num_labels = 0;
5147 mpls_label_t *label_pnt = NULL;
5148 struct bgp_route_evpn evpn;
5149
5150 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5151 if (pi->peer == peer)
5152 break;
5153
5154 if (pi && pi->extra)
5155 num_labels = pi->extra->num_labels;
5156 if (num_labels)
5157 label_pnt = &pi->extra->label[0];
5158 if (pi)
5159 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5160 sizeof(evpn));
5161 else
5162 memset(&evpn, 0, sizeof(evpn));
5163
5164 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5165 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5166 label_pnt, num_labels, 1, &evpn);
5167 }
5168
5169 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5170 struct bgp_table *table,
5171 struct prefix_rd *prd)
5172 {
5173 struct bgp_dest *dest;
5174 struct bgp_adj_in *ain;
5175
5176 if (!table)
5177 table = peer->bgp->rib[afi][safi];
5178
5179 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5180 for (ain = dest->adj_in; ain; ain = ain->next) {
5181 if (ain->peer != peer)
5182 continue;
5183
5184 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5185 safi, prd);
5186 }
5187 }
5188
5189 /* Do soft reconfig table per bgp table.
5190 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5191 * when BGP_NODE_SOFT_RECONFIG is set,
5192 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5193 * Schedule a new thread to continue the job.
5194 * Without splitting the full job into several part,
5195 * vtysh waits for the job to finish before responding to a BGP command
5196 */
5197 static void bgp_soft_reconfig_table_task(struct event *thread)
5198 {
5199 uint32_t iter, max_iter;
5200 struct bgp_dest *dest;
5201 struct bgp_adj_in *ain;
5202 struct peer *peer;
5203 struct bgp_table *table;
5204 struct prefix_rd *prd;
5205 struct listnode *node, *nnode;
5206
5207 table = EVENT_ARG(thread);
5208 prd = NULL;
5209
5210 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5211 if (table->soft_reconfig_init) {
5212 /* first call of the function with a new srta structure.
5213 * Don't do any treatment this time on nodes
5214 * in order vtysh to respond quickly
5215 */
5216 max_iter = 0;
5217 }
5218
5219 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5220 dest = bgp_route_next(dest)) {
5221 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5222 continue;
5223
5224 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5225
5226 for (ain = dest->adj_in; ain; ain = ain->next) {
5227 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5228 nnode, peer)) {
5229 if (ain->peer != peer)
5230 continue;
5231
5232 bgp_soft_reconfig_table_update(
5233 peer, dest, ain, table->afi,
5234 table->safi, prd);
5235 iter++;
5236 }
5237 }
5238 }
5239
5240 /* we're either starting the initial iteration,
5241 * or we're going to continue an ongoing iteration
5242 */
5243 if (dest || table->soft_reconfig_init) {
5244 table->soft_reconfig_init = false;
5245 event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
5246 0, &table->soft_reconfig_thread);
5247 return;
5248 }
5249 /* we're done, clean up the background iteration context info and
5250 schedule route annoucement
5251 */
5252 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5253 listnode_delete(table->soft_reconfig_peers, peer);
5254 bgp_announce_route(peer, table->afi, table->safi, false);
5255 }
5256
5257 list_delete(&table->soft_reconfig_peers);
5258 }
5259
5260
5261 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5262 * and peer.
5263 * - bgp cannot be NULL
5264 * - if table and peer are NULL, cancel all threads within the bgp instance
5265 * - if table is NULL and peer is not,
5266 * remove peer in all threads within the bgp instance
5267 * - if peer is NULL, cancel all threads matching table within the bgp instance
5268 */
5269 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5270 const struct bgp_table *table,
5271 const struct peer *peer)
5272 {
5273 struct peer *npeer;
5274 struct listnode *node, *nnode;
5275 int afi, safi;
5276 struct bgp_table *ntable;
5277
5278 if (!bgp)
5279 return;
5280
5281 FOREACH_AFI_SAFI (afi, safi) {
5282 ntable = bgp->rib[afi][safi];
5283 if (!ntable)
5284 continue;
5285 if (table && table != ntable)
5286 continue;
5287
5288 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5289 npeer)) {
5290 if (peer && peer != npeer)
5291 continue;
5292 listnode_delete(ntable->soft_reconfig_peers, npeer);
5293 }
5294
5295 if (!ntable->soft_reconfig_peers
5296 || !list_isempty(ntable->soft_reconfig_peers))
5297 continue;
5298
5299 list_delete(&ntable->soft_reconfig_peers);
5300 bgp_soft_reconfig_table_flag(ntable, false);
5301 EVENT_OFF(ntable->soft_reconfig_thread);
5302 }
5303 }
5304
5305 /*
5306 * Returns false if the peer is not configured for soft reconfig in
5307 */
5308 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5309 {
5310 struct bgp_dest *dest;
5311 struct bgp_table *table;
5312 struct listnode *node, *nnode;
5313 struct peer *npeer;
5314 struct peer_af *paf;
5315
5316 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5317 return false;
5318
5319 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5320 && (safi != SAFI_EVPN)) {
5321 table = peer->bgp->rib[afi][safi];
5322 if (!table)
5323 return true;
5324
5325 table->soft_reconfig_init = true;
5326
5327 if (!table->soft_reconfig_peers)
5328 table->soft_reconfig_peers = list_new();
5329 npeer = NULL;
5330 /* add peer to the table soft_reconfig_peers if not already
5331 * there
5332 */
5333 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5334 npeer)) {
5335 if (peer == npeer)
5336 break;
5337 }
5338 if (peer != npeer)
5339 listnode_add(table->soft_reconfig_peers, peer);
5340
5341 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5342 * on table would start back at the beginning.
5343 */
5344 bgp_soft_reconfig_table_flag(table, true);
5345
5346 if (!table->soft_reconfig_thread)
5347 event_add_event(bm->master,
5348 bgp_soft_reconfig_table_task, table, 0,
5349 &table->soft_reconfig_thread);
5350 /* Cancel bgp_announce_route_timer_expired threads.
5351 * bgp_announce_route_timer_expired threads have been scheduled
5352 * to announce routes as soon as the soft_reconfigure process
5353 * finishes.
5354 * In this case, soft_reconfigure is also scheduled by using
5355 * a thread but is planned after the
5356 * bgp_announce_route_timer_expired threads. It means that,
5357 * without cancelling the threads, the route announcement task
5358 * would run before the soft reconfiguration one. That would
5359 * useless and would block vtysh during several seconds. Route
5360 * announcements are rescheduled as soon as the soft_reconfigure
5361 * process finishes.
5362 */
5363 paf = peer_af_find(peer, afi, safi);
5364 if (paf)
5365 bgp_stop_announce_route_timer(paf);
5366 } else
5367 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5368 dest = bgp_route_next(dest)) {
5369 table = bgp_dest_get_bgp_table_info(dest);
5370
5371 if (table == NULL)
5372 continue;
5373
5374 const struct prefix *p = bgp_dest_get_prefix(dest);
5375 struct prefix_rd prd;
5376
5377 prd.family = AF_UNSPEC;
5378 prd.prefixlen = 64;
5379 memcpy(&prd.val, p->u.val, 8);
5380
5381 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5382 }
5383
5384 return true;
5385 }
5386
5387
5388 struct bgp_clear_node_queue {
5389 struct bgp_dest *dest;
5390 };
5391
5392 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5393 {
5394 struct bgp_clear_node_queue *cnq = data;
5395 struct bgp_dest *dest = cnq->dest;
5396 struct peer *peer = wq->spec.data;
5397 struct bgp_path_info *pi;
5398 struct bgp *bgp;
5399 afi_t afi = bgp_dest_table(dest)->afi;
5400 safi_t safi = bgp_dest_table(dest)->safi;
5401
5402 assert(dest && peer);
5403 bgp = peer->bgp;
5404
5405 /* It is possible that we have multiple paths for a prefix from a peer
5406 * if that peer is using AddPath.
5407 */
5408 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5409 if (pi->peer != peer)
5410 continue;
5411
5412 /* graceful restart STALE flag set. */
5413 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5414 && peer->nsf[afi][safi])
5415 || CHECK_FLAG(peer->af_sflags[afi][safi],
5416 PEER_STATUS_ENHANCED_REFRESH))
5417 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5418 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5419 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5420 else {
5421 /* If this is an EVPN route, process for
5422 * un-import. */
5423 if (safi == SAFI_EVPN)
5424 bgp_evpn_unimport_route(
5425 bgp, afi, safi,
5426 bgp_dest_get_prefix(dest), pi);
5427 /* Handle withdraw for VRF route-leaking and L3VPN */
5428 if (SAFI_UNICAST == safi
5429 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5430 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5431 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5432 bgp, pi);
5433 }
5434 if (SAFI_MPLS_VPN == safi &&
5435 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5436 vpn_leak_to_vrf_withdraw(pi);
5437 }
5438
5439 bgp_rib_remove(dest, pi, peer, afi, safi);
5440 }
5441 }
5442 return WQ_SUCCESS;
5443 }
5444
5445 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5446 {
5447 struct bgp_clear_node_queue *cnq = data;
5448 struct bgp_dest *dest = cnq->dest;
5449 struct bgp_table *table = bgp_dest_table(dest);
5450
5451 bgp_dest_unlock_node(dest);
5452 bgp_table_unlock(table);
5453 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5454 }
5455
5456 static void bgp_clear_node_complete(struct work_queue *wq)
5457 {
5458 struct peer *peer = wq->spec.data;
5459
5460 /* Tickle FSM to start moving again */
5461 BGP_EVENT_ADD(peer, Clearing_Completed);
5462
5463 peer_unlock(peer); /* bgp_clear_route */
5464 }
5465
5466 static void bgp_clear_node_queue_init(struct peer *peer)
5467 {
5468 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5469
5470 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5471 #undef CLEAR_QUEUE_NAME_LEN
5472
5473 peer->clear_node_queue = work_queue_new(bm->master, wname);
5474 peer->clear_node_queue->spec.hold = 10;
5475 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5476 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5477 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5478 peer->clear_node_queue->spec.max_retries = 0;
5479
5480 /* we only 'lock' this peer reference when the queue is actually active
5481 */
5482 peer->clear_node_queue->spec.data = peer;
5483 }
5484
5485 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5486 struct bgp_table *table)
5487 {
5488 struct bgp_dest *dest;
5489 int force = peer->bgp->process_queue ? 0 : 1;
5490
5491 if (!table)
5492 table = peer->bgp->rib[afi][safi];
5493
5494 /* If still no table => afi/safi isn't configured at all or smth. */
5495 if (!table)
5496 return;
5497
5498 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5499 struct bgp_path_info *pi, *next;
5500 struct bgp_adj_in *ain;
5501 struct bgp_adj_in *ain_next;
5502
5503 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5504 * queued for every clearing peer, regardless of whether it is
5505 * relevant to the peer at hand.
5506 *
5507 * Overview: There are 3 different indices which need to be
5508 * scrubbed, potentially, when a peer is removed:
5509 *
5510 * 1 peer's routes visible via the RIB (ie accepted routes)
5511 * 2 peer's routes visible by the (optional) peer's adj-in index
5512 * 3 other routes visible by the peer's adj-out index
5513 *
5514 * 3 there is no hurry in scrubbing, once the struct peer is
5515 * removed from bgp->peer, we could just GC such deleted peer's
5516 * adj-outs at our leisure.
5517 *
5518 * 1 and 2 must be 'scrubbed' in some way, at least made
5519 * invisible via RIB index before peer session is allowed to be
5520 * brought back up. So one needs to know when such a 'search' is
5521 * complete.
5522 *
5523 * Ideally:
5524 *
5525 * - there'd be a single global queue or a single RIB walker
5526 * - rather than tracking which route_nodes still need to be
5527 * examined on a peer basis, we'd track which peers still
5528 * aren't cleared
5529 *
5530 * Given that our per-peer prefix-counts now should be reliable,
5531 * this may actually be achievable. It doesn't seem to be a huge
5532 * problem at this time,
5533 *
5534 * It is possible that we have multiple paths for a prefix from
5535 * a peer
5536 * if that peer is using AddPath.
5537 */
5538 ain = dest->adj_in;
5539 while (ain) {
5540 ain_next = ain->next;
5541
5542 if (ain->peer == peer)
5543 bgp_adj_in_remove(dest, ain);
5544
5545 ain = ain_next;
5546 }
5547
5548 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5549 next = pi->next;
5550 if (pi->peer != peer)
5551 continue;
5552
5553 if (force)
5554 bgp_path_info_reap(dest, pi);
5555 else {
5556 struct bgp_clear_node_queue *cnq;
5557
5558 /* both unlocked in bgp_clear_node_queue_del */
5559 bgp_table_lock(bgp_dest_table(dest));
5560 bgp_dest_lock_node(dest);
5561 cnq = XCALLOC(
5562 MTYPE_BGP_CLEAR_NODE_QUEUE,
5563 sizeof(struct bgp_clear_node_queue));
5564 cnq->dest = dest;
5565 work_queue_add(peer->clear_node_queue, cnq);
5566 break;
5567 }
5568 }
5569 }
5570 return;
5571 }
5572
5573 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5574 {
5575 struct bgp_dest *dest;
5576 struct bgp_table *table;
5577
5578 if (peer->clear_node_queue == NULL)
5579 bgp_clear_node_queue_init(peer);
5580
5581 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5582 * Idle until it receives a Clearing_Completed event. This protects
5583 * against peers which flap faster than we can we clear, which could
5584 * lead to:
5585 *
5586 * a) race with routes from the new session being installed before
5587 * clear_route_node visits the node (to delete the route of that
5588 * peer)
5589 * b) resource exhaustion, clear_route_node likely leads to an entry
5590 * on the process_main queue. Fast-flapping could cause that queue
5591 * to grow and grow.
5592 */
5593
5594 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5595 * the unlock will happen upon work-queue completion; other wise, the
5596 * unlock happens at the end of this function.
5597 */
5598 if (!peer->clear_node_queue->thread)
5599 peer_lock(peer);
5600
5601 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5602 bgp_clear_route_table(peer, afi, safi, NULL);
5603 else
5604 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5605 dest = bgp_route_next(dest)) {
5606 table = bgp_dest_get_bgp_table_info(dest);
5607 if (!table)
5608 continue;
5609
5610 bgp_clear_route_table(peer, afi, safi, table);
5611 }
5612
5613 /* unlock if no nodes got added to the clear-node-queue. */
5614 if (!peer->clear_node_queue->thread)
5615 peer_unlock(peer);
5616 }
5617
5618 void bgp_clear_route_all(struct peer *peer)
5619 {
5620 afi_t afi;
5621 safi_t safi;
5622
5623 FOREACH_AFI_SAFI (afi, safi)
5624 bgp_clear_route(peer, afi, safi);
5625
5626 #ifdef ENABLE_BGP_VNC
5627 rfapiProcessPeerDown(peer);
5628 #endif
5629 }
5630
5631 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5632 {
5633 struct bgp_table *table;
5634 struct bgp_dest *dest;
5635 struct bgp_adj_in *ain;
5636 struct bgp_adj_in *ain_next;
5637
5638 table = peer->bgp->rib[afi][safi];
5639
5640 /* It is possible that we have multiple paths for a prefix from a peer
5641 * if that peer is using AddPath.
5642 */
5643 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5644 ain = dest->adj_in;
5645
5646 while (ain) {
5647 ain_next = ain->next;
5648
5649 if (ain->peer == peer)
5650 bgp_adj_in_remove(dest, ain);
5651
5652 ain = ain_next;
5653 }
5654 }
5655 }
5656
5657 /* If any of the routes from the peer have been marked with the NO_LLGR
5658 * community, either as sent by the peer, or as the result of a configured
5659 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5660 * operation of [RFC4271].
5661 */
5662 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5663 {
5664 struct bgp_dest *dest;
5665 struct bgp_path_info *pi;
5666 struct bgp_table *table;
5667
5668 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5669 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5670 dest = bgp_route_next(dest)) {
5671 struct bgp_dest *rm;
5672
5673 /* look for neighbor in tables */
5674 table = bgp_dest_get_bgp_table_info(dest);
5675 if (!table)
5676 continue;
5677
5678 for (rm = bgp_table_top(table); rm;
5679 rm = bgp_route_next(rm))
5680 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5681 pi = pi->next) {
5682 if (pi->peer != peer)
5683 continue;
5684 if (CHECK_FLAG(
5685 peer->af_sflags[afi][safi],
5686 PEER_STATUS_LLGR_WAIT) &&
5687 bgp_attr_get_community(pi->attr) &&
5688 !community_include(
5689 bgp_attr_get_community(
5690 pi->attr),
5691 COMMUNITY_NO_LLGR))
5692 continue;
5693 if (!CHECK_FLAG(pi->flags,
5694 BGP_PATH_STALE))
5695 continue;
5696
5697 /*
5698 * If this is VRF leaked route
5699 * process for withdraw.
5700 */
5701 if (pi->sub_type ==
5702 BGP_ROUTE_IMPORTED &&
5703 peer->bgp->inst_type ==
5704 BGP_INSTANCE_TYPE_DEFAULT)
5705 vpn_leak_to_vrf_withdraw(pi);
5706
5707 bgp_rib_remove(rm, pi, peer, afi, safi);
5708 break;
5709 }
5710 }
5711 } else {
5712 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5713 dest = bgp_route_next(dest))
5714 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5715 pi = pi->next) {
5716 if (pi->peer != peer)
5717 continue;
5718 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5719 PEER_STATUS_LLGR_WAIT) &&
5720 bgp_attr_get_community(pi->attr) &&
5721 !community_include(
5722 bgp_attr_get_community(pi->attr),
5723 COMMUNITY_NO_LLGR))
5724 continue;
5725 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5726 continue;
5727 if (safi == SAFI_UNICAST &&
5728 (peer->bgp->inst_type ==
5729 BGP_INSTANCE_TYPE_VRF ||
5730 peer->bgp->inst_type ==
5731 BGP_INSTANCE_TYPE_DEFAULT))
5732 vpn_leak_from_vrf_withdraw(
5733 bgp_get_default(), peer->bgp,
5734 pi);
5735
5736 bgp_rib_remove(dest, pi, peer, afi, safi);
5737 break;
5738 }
5739 }
5740 }
5741
5742 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5743 {
5744 struct bgp_dest *dest, *ndest;
5745 struct bgp_path_info *pi;
5746 struct bgp_table *table;
5747
5748 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5749 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5750 dest = bgp_route_next(dest)) {
5751 table = bgp_dest_get_bgp_table_info(dest);
5752 if (!table)
5753 continue;
5754
5755 for (ndest = bgp_table_top(table); ndest;
5756 ndest = bgp_route_next(ndest)) {
5757 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5758 pi = pi->next) {
5759 if (pi->peer != peer)
5760 continue;
5761
5762 if ((CHECK_FLAG(
5763 peer->af_sflags[afi][safi],
5764 PEER_STATUS_ENHANCED_REFRESH))
5765 && !CHECK_FLAG(pi->flags,
5766 BGP_PATH_STALE)
5767 && !CHECK_FLAG(
5768 pi->flags,
5769 BGP_PATH_UNUSEABLE)) {
5770 if (bgp_debug_neighbor_events(
5771 peer))
5772 zlog_debug(
5773 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5774 peer,
5775 afi2str(afi),
5776 safi2str(safi),
5777 bgp_dest_get_prefix(
5778 ndest));
5779
5780 bgp_path_info_set_flag(
5781 ndest, pi,
5782 BGP_PATH_STALE);
5783 }
5784 }
5785 }
5786 }
5787 } else {
5788 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5789 dest = bgp_route_next(dest)) {
5790 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5791 pi = pi->next) {
5792 if (pi->peer != peer)
5793 continue;
5794
5795 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5796 PEER_STATUS_ENHANCED_REFRESH))
5797 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5798 && !CHECK_FLAG(pi->flags,
5799 BGP_PATH_UNUSEABLE)) {
5800 if (bgp_debug_neighbor_events(peer))
5801 zlog_debug(
5802 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5803 peer, afi2str(afi),
5804 safi2str(safi),
5805 bgp_dest_get_prefix(
5806 dest));
5807
5808 bgp_path_info_set_flag(dest, pi,
5809 BGP_PATH_STALE);
5810 }
5811 }
5812 }
5813 }
5814 }
5815
5816 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5817 {
5818 if (peer->sort == BGP_PEER_IBGP)
5819 return true;
5820
5821 if (peer->sort == BGP_PEER_EBGP
5822 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5823 || FILTER_LIST_OUT_NAME(filter)
5824 || DISTRIBUTE_OUT_NAME(filter)))
5825 return true;
5826 return false;
5827 }
5828
5829 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5830 {
5831 if (peer->sort == BGP_PEER_IBGP)
5832 return true;
5833
5834 if (peer->sort == BGP_PEER_EBGP
5835 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5836 || FILTER_LIST_IN_NAME(filter)
5837 || DISTRIBUTE_IN_NAME(filter)))
5838 return true;
5839 return false;
5840 }
5841
5842 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5843 safi_t safi)
5844 {
5845 struct bgp_dest *dest;
5846 struct bgp_path_info *pi;
5847 struct bgp_path_info *next;
5848
5849 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5850 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5851 const struct prefix *p = bgp_dest_get_prefix(dest);
5852
5853 next = pi->next;
5854
5855 /* Unimport EVPN routes from VRFs */
5856 if (safi == SAFI_EVPN)
5857 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5858 SAFI_EVPN, p, pi);
5859
5860 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5861 && pi->type == ZEBRA_ROUTE_BGP
5862 && (pi->sub_type == BGP_ROUTE_NORMAL
5863 || pi->sub_type == BGP_ROUTE_AGGREGATE
5864 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5865
5866 if (bgp_fibupd_safi(safi))
5867 bgp_zebra_withdraw(p, pi, bgp, safi);
5868 }
5869
5870 bgp_path_info_reap(dest, pi);
5871 }
5872 }
5873
5874 /* Delete all kernel routes. */
5875 void bgp_cleanup_routes(struct bgp *bgp)
5876 {
5877 afi_t afi;
5878 struct bgp_dest *dest;
5879 struct bgp_table *table;
5880
5881 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5882 if (afi == AFI_L2VPN)
5883 continue;
5884 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5885 SAFI_UNICAST);
5886 /*
5887 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5888 */
5889 if (afi != AFI_L2VPN) {
5890 safi_t safi;
5891 safi = SAFI_MPLS_VPN;
5892 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5893 dest = bgp_route_next(dest)) {
5894 table = bgp_dest_get_bgp_table_info(dest);
5895 if (table != NULL) {
5896 bgp_cleanup_table(bgp, table, safi);
5897 bgp_table_finish(&table);
5898 bgp_dest_set_bgp_table_info(dest, NULL);
5899 bgp_dest_unlock_node(dest);
5900 }
5901 }
5902 safi = SAFI_ENCAP;
5903 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5904 dest = bgp_route_next(dest)) {
5905 table = bgp_dest_get_bgp_table_info(dest);
5906 if (table != NULL) {
5907 bgp_cleanup_table(bgp, table, safi);
5908 bgp_table_finish(&table);
5909 bgp_dest_set_bgp_table_info(dest, NULL);
5910 bgp_dest_unlock_node(dest);
5911 }
5912 }
5913 }
5914 }
5915 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5916 dest = bgp_route_next(dest)) {
5917 table = bgp_dest_get_bgp_table_info(dest);
5918 if (table != NULL) {
5919 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5920 bgp_table_finish(&table);
5921 bgp_dest_set_bgp_table_info(dest, NULL);
5922 bgp_dest_unlock_node(dest);
5923 }
5924 }
5925 }
5926
5927 void bgp_reset(void)
5928 {
5929 vty_reset();
5930 bgp_zclient_reset();
5931 access_list_reset();
5932 prefix_list_reset();
5933 }
5934
5935 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5936 {
5937 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5938 && CHECK_FLAG(peer->af_cap[afi][safi],
5939 PEER_CAP_ADDPATH_AF_TX_RCV));
5940 }
5941
5942 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5943 value. */
5944 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5945 struct bgp_nlri *packet)
5946 {
5947 uint8_t *pnt;
5948 uint8_t *lim;
5949 struct prefix p;
5950 int psize;
5951 afi_t afi;
5952 safi_t safi;
5953 bool addpath_capable;
5954 uint32_t addpath_id;
5955
5956 pnt = packet->nlri;
5957 lim = pnt + packet->length;
5958 afi = packet->afi;
5959 safi = packet->safi;
5960 addpath_id = 0;
5961 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5962
5963 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5964 syntactic validity. If the field is syntactically incorrect,
5965 then the Error Subcode is set to Invalid Network Field. */
5966 for (; pnt < lim; pnt += psize) {
5967 /* Clear prefix structure. */
5968 memset(&p, 0, sizeof(p));
5969
5970 if (addpath_capable) {
5971
5972 /* When packet overflow occurs return immediately. */
5973 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5974 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5975
5976 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5977 addpath_id = ntohl(addpath_id);
5978 pnt += BGP_ADDPATH_ID_LEN;
5979 }
5980
5981 /* Fetch prefix length. */
5982 p.prefixlen = *pnt++;
5983 /* afi/safi validity already verified by caller,
5984 * bgp_update_receive */
5985 p.family = afi2family(afi);
5986
5987 /* Prefix length check. */
5988 if (p.prefixlen > prefix_blen(&p) * 8) {
5989 flog_err(
5990 EC_BGP_UPDATE_RCV,
5991 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5992 peer->host, p.prefixlen, packet->afi);
5993 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5994 }
5995
5996 /* Packet size overflow check. */
5997 psize = PSIZE(p.prefixlen);
5998
5999 /* When packet overflow occur return immediately. */
6000 if (pnt + psize > lim) {
6001 flog_err(
6002 EC_BGP_UPDATE_RCV,
6003 "%s [Error] Update packet error (prefix length %d overflows packet)",
6004 peer->host, p.prefixlen);
6005 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6006 }
6007
6008 /* Defensive coding, double-check the psize fits in a struct
6009 * prefix for the v4 and v6 afi's and unicast/multicast */
6010 if (psize > (ssize_t)sizeof(p.u.val)) {
6011 flog_err(
6012 EC_BGP_UPDATE_RCV,
6013 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6014 peer->host, p.prefixlen, sizeof(p.u.val));
6015 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6016 }
6017
6018 /* Fetch prefix from NLRI packet. */
6019 memcpy(p.u.val, pnt, psize);
6020
6021 /* Check address. */
6022 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6023 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6024 /* From RFC4271 Section 6.3:
6025 *
6026 * If a prefix in the NLRI field is semantically
6027 * incorrect
6028 * (e.g., an unexpected multicast IP address),
6029 * an error SHOULD
6030 * be logged locally, and the prefix SHOULD be
6031 * ignored.
6032 */
6033 flog_err(
6034 EC_BGP_UPDATE_RCV,
6035 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6036 peer->host, &p.u.prefix4);
6037 continue;
6038 }
6039 }
6040
6041 /* Check address. */
6042 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6043 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6044 flog_err(
6045 EC_BGP_UPDATE_RCV,
6046 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6047 peer->host, &p.u.prefix6);
6048
6049 continue;
6050 }
6051 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6052 flog_err(
6053 EC_BGP_UPDATE_RCV,
6054 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6055 peer->host, &p.u.prefix6);
6056
6057 continue;
6058 }
6059 }
6060
6061 /* Normal process. */
6062 if (attr)
6063 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6064 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6065 NULL, 0, 0, NULL);
6066 else
6067 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6068 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6069 NULL, 0, NULL);
6070
6071 /* Do not send BGP notification twice when maximum-prefix count
6072 * overflow. */
6073 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6074 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6075 }
6076
6077 /* Packet length consistency check. */
6078 if (pnt != lim) {
6079 flog_err(
6080 EC_BGP_UPDATE_RCV,
6081 "%s [Error] Update packet error (prefix length mismatch with total length)",
6082 peer->host);
6083 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6084 }
6085
6086 return BGP_NLRI_PARSE_OK;
6087 }
6088
6089 static struct bgp_static *bgp_static_new(void)
6090 {
6091 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6092 }
6093
6094 static void bgp_static_free(struct bgp_static *bgp_static)
6095 {
6096 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6097 route_map_counter_decrement(bgp_static->rmap.map);
6098
6099 if (bgp_static->prd_pretty)
6100 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6101 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6102 XFREE(MTYPE_BGP_STATIC, bgp_static);
6103 }
6104
6105 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6106 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6107 {
6108 struct bgp_dest *dest;
6109 struct bgp_path_info *pi;
6110 struct bgp_path_info *new;
6111 struct bgp_path_info rmap_path;
6112 struct attr attr;
6113 struct attr *attr_new;
6114 route_map_result_t ret;
6115 #ifdef ENABLE_BGP_VNC
6116 int vnc_implicit_withdraw = 0;
6117 #endif
6118
6119 assert(bgp_static);
6120
6121 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6122
6123 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6124
6125 attr.nexthop = bgp_static->igpnexthop;
6126 attr.med = bgp_static->igpmetric;
6127 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6128
6129 if (afi == AFI_IP)
6130 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6131
6132 if (bgp_static->igpmetric)
6133 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6134
6135 if (bgp_static->atomic)
6136 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6137
6138 /* Store label index, if required. */
6139 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6140 attr.label_index = bgp_static->label_index;
6141 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6142 }
6143
6144 /* Apply route-map. */
6145 if (bgp_static->rmap.name) {
6146 struct attr attr_tmp = attr;
6147
6148 memset(&rmap_path, 0, sizeof(rmap_path));
6149 rmap_path.peer = bgp->peer_self;
6150 rmap_path.attr = &attr_tmp;
6151
6152 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6153
6154 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6155
6156 bgp->peer_self->rmap_type = 0;
6157
6158 if (ret == RMAP_DENYMATCH) {
6159 /* Free uninterned attribute. */
6160 bgp_attr_flush(&attr_tmp);
6161
6162 /* Unintern original. */
6163 aspath_unintern(&attr.aspath);
6164 bgp_static_withdraw(bgp, p, afi, safi);
6165 bgp_dest_unlock_node(dest);
6166 return;
6167 }
6168
6169 if (bgp_in_graceful_shutdown(bgp))
6170 bgp_attr_add_gshut_community(&attr_tmp);
6171
6172 attr_new = bgp_attr_intern(&attr_tmp);
6173 } else {
6174
6175 if (bgp_in_graceful_shutdown(bgp))
6176 bgp_attr_add_gshut_community(&attr);
6177
6178 attr_new = bgp_attr_intern(&attr);
6179 }
6180
6181 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6182 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6183 && pi->sub_type == BGP_ROUTE_STATIC)
6184 break;
6185
6186 if (pi) {
6187 if (attrhash_cmp(pi->attr, attr_new)
6188 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6189 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6190 bgp_dest_unlock_node(dest);
6191 bgp_attr_unintern(&attr_new);
6192 aspath_unintern(&attr.aspath);
6193 return;
6194 } else {
6195 /* The attribute is changed. */
6196 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6197
6198 /* Rewrite BGP route information. */
6199 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6200 bgp_path_info_restore(dest, pi);
6201 else
6202 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6203 #ifdef ENABLE_BGP_VNC
6204 if ((afi == AFI_IP || afi == AFI_IP6)
6205 && (safi == SAFI_UNICAST)) {
6206 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6207 /*
6208 * Implicit withdraw case.
6209 * We have to do this before pi is
6210 * changed
6211 */
6212 ++vnc_implicit_withdraw;
6213 vnc_import_bgp_del_route(bgp, p, pi);
6214 vnc_import_bgp_exterior_del_route(
6215 bgp, p, pi);
6216 }
6217 }
6218 #endif
6219 bgp_attr_unintern(&pi->attr);
6220 pi->attr = attr_new;
6221 pi->uptime = monotime(NULL);
6222 #ifdef ENABLE_BGP_VNC
6223 if ((afi == AFI_IP || afi == AFI_IP6)
6224 && (safi == SAFI_UNICAST)) {
6225 if (vnc_implicit_withdraw) {
6226 vnc_import_bgp_add_route(bgp, p, pi);
6227 vnc_import_bgp_exterior_add_route(
6228 bgp, p, pi);
6229 }
6230 }
6231 #endif
6232
6233 /* Nexthop reachability check. */
6234 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6235 && (safi == SAFI_UNICAST
6236 || safi == SAFI_LABELED_UNICAST)) {
6237
6238 struct bgp *bgp_nexthop = bgp;
6239
6240 if (pi->extra && pi->extra->bgp_orig)
6241 bgp_nexthop = pi->extra->bgp_orig;
6242
6243 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6244 afi, safi, pi, NULL,
6245 0, p))
6246 bgp_path_info_set_flag(dest, pi,
6247 BGP_PATH_VALID);
6248 else {
6249 if (BGP_DEBUG(nht, NHT)) {
6250 char buf1[INET6_ADDRSTRLEN];
6251 inet_ntop(p->family,
6252 &p->u.prefix, buf1,
6253 sizeof(buf1));
6254 zlog_debug(
6255 "%s(%s): Route not in table, not advertising",
6256 __func__, buf1);
6257 }
6258 bgp_path_info_unset_flag(
6259 dest, pi, BGP_PATH_VALID);
6260 }
6261 } else {
6262 /* Delete the NHT structure if any, if we're
6263 * toggling between
6264 * enabling/disabling import check. We
6265 * deregister the route
6266 * from NHT to avoid overloading NHT and the
6267 * process interaction
6268 */
6269 bgp_unlink_nexthop(pi);
6270 bgp_path_info_set_flag(dest, pi,
6271 BGP_PATH_VALID);
6272 }
6273 /* Process change. */
6274 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6275 bgp_process(bgp, dest, afi, safi);
6276
6277 if (SAFI_UNICAST == safi
6278 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6279 || bgp->inst_type
6280 == BGP_INSTANCE_TYPE_DEFAULT)) {
6281 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6282 pi);
6283 }
6284
6285 bgp_dest_unlock_node(dest);
6286 aspath_unintern(&attr.aspath);
6287 return;
6288 }
6289 }
6290
6291 /* Make new BGP info. */
6292 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6293 attr_new, dest);
6294 /* Nexthop reachability check. */
6295 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6296 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6297 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6298 p))
6299 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6300 else {
6301 if (BGP_DEBUG(nht, NHT)) {
6302 char buf1[INET6_ADDRSTRLEN];
6303
6304 inet_ntop(p->family, &p->u.prefix, buf1,
6305 sizeof(buf1));
6306 zlog_debug(
6307 "%s(%s): Route not in table, not advertising",
6308 __func__, buf1);
6309 }
6310 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6311 }
6312 } else {
6313 /* Delete the NHT structure if any, if we're toggling between
6314 * enabling/disabling import check. We deregister the route
6315 * from NHT to avoid overloading NHT and the process interaction
6316 */
6317 bgp_unlink_nexthop(new);
6318
6319 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6320 }
6321
6322 /* Aggregate address increment. */
6323 bgp_aggregate_increment(bgp, p, new, afi, safi);
6324
6325 /* Register new BGP information. */
6326 bgp_path_info_add(dest, new);
6327
6328 /* route_node_get lock */
6329 bgp_dest_unlock_node(dest);
6330
6331 /* Process change. */
6332 bgp_process(bgp, dest, afi, safi);
6333
6334 if (SAFI_UNICAST == safi
6335 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6336 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6337 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6338 }
6339
6340 /* Unintern original. */
6341 aspath_unintern(&attr.aspath);
6342 }
6343
6344 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6345 safi_t safi)
6346 {
6347 struct bgp_dest *dest;
6348 struct bgp_path_info *pi;
6349
6350 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6351
6352 /* Check selected route and self inserted route. */
6353 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6354 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6355 && pi->sub_type == BGP_ROUTE_STATIC)
6356 break;
6357
6358 /* Withdraw static BGP route from routing table. */
6359 if (pi) {
6360 if (SAFI_UNICAST == safi
6361 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6362 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6363 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6364 }
6365 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6366 bgp_unlink_nexthop(pi);
6367 bgp_path_info_delete(dest, pi);
6368 bgp_process(bgp, dest, afi, safi);
6369 }
6370
6371 /* Unlock bgp_node_lookup. */
6372 bgp_dest_unlock_node(dest);
6373 }
6374
6375 /*
6376 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6377 */
6378 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6379 afi_t afi, safi_t safi,
6380 struct prefix_rd *prd)
6381 {
6382 struct bgp_dest *dest;
6383 struct bgp_path_info *pi;
6384
6385 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6386
6387 /* Check selected route and self inserted route. */
6388 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6389 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6390 && pi->sub_type == BGP_ROUTE_STATIC)
6391 break;
6392
6393 /* Withdraw static BGP route from routing table. */
6394 if (pi) {
6395 #ifdef ENABLE_BGP_VNC
6396 rfapiProcessWithdraw(
6397 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6398 1); /* Kill, since it is an administrative change */
6399 #endif
6400 if (SAFI_MPLS_VPN == safi
6401 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6402 vpn_leak_to_vrf_withdraw(pi);
6403 }
6404 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6405 bgp_path_info_delete(dest, pi);
6406 bgp_process(bgp, dest, afi, safi);
6407 }
6408
6409 /* Unlock bgp_node_lookup. */
6410 bgp_dest_unlock_node(dest);
6411 }
6412
6413 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6414 struct bgp_static *bgp_static, afi_t afi,
6415 safi_t safi)
6416 {
6417 struct bgp_dest *dest;
6418 struct bgp_path_info *new;
6419 struct attr *attr_new;
6420 struct attr attr = {0};
6421 struct bgp_path_info *pi;
6422 #ifdef ENABLE_BGP_VNC
6423 mpls_label_t label = 0;
6424 #endif
6425 uint32_t num_labels = 0;
6426
6427 assert(bgp_static);
6428
6429 if (bgp_static->label != MPLS_INVALID_LABEL)
6430 num_labels = 1;
6431 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6432 &bgp_static->prd);
6433
6434 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6435
6436 attr.nexthop = bgp_static->igpnexthop;
6437 attr.med = bgp_static->igpmetric;
6438 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6439
6440 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6441 || (safi == SAFI_ENCAP)) {
6442 if (afi == AFI_IP) {
6443 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6444 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6445 }
6446 }
6447 if (afi == AFI_L2VPN) {
6448 if (bgp_static->gatewayIp.family == AF_INET) {
6449 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6450 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6451 &bgp_static->gatewayIp.u.prefix4,
6452 IPV4_MAX_BYTELEN);
6453 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6454 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6455 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6456 &bgp_static->gatewayIp.u.prefix6,
6457 IPV6_MAX_BYTELEN);
6458 }
6459 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6460 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6461 struct bgp_encap_type_vxlan bet;
6462 memset(&bet, 0, sizeof(bet));
6463 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6464 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6465 }
6466 if (bgp_static->router_mac) {
6467 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6468 }
6469 }
6470 /* Apply route-map. */
6471 if (bgp_static->rmap.name) {
6472 struct attr attr_tmp = attr;
6473 struct bgp_path_info rmap_path;
6474 route_map_result_t ret;
6475
6476 rmap_path.peer = bgp->peer_self;
6477 rmap_path.attr = &attr_tmp;
6478
6479 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6480
6481 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6482
6483 bgp->peer_self->rmap_type = 0;
6484
6485 if (ret == RMAP_DENYMATCH) {
6486 /* Free uninterned attribute. */
6487 bgp_attr_flush(&attr_tmp);
6488
6489 /* Unintern original. */
6490 aspath_unintern(&attr.aspath);
6491 bgp_static_withdraw_safi(bgp, p, afi, safi,
6492 &bgp_static->prd);
6493 bgp_dest_unlock_node(dest);
6494 return;
6495 }
6496
6497 attr_new = bgp_attr_intern(&attr_tmp);
6498 } else {
6499 attr_new = bgp_attr_intern(&attr);
6500 }
6501
6502 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6503 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6504 && pi->sub_type == BGP_ROUTE_STATIC)
6505 break;
6506
6507 if (pi) {
6508 if (attrhash_cmp(pi->attr, attr_new)
6509 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6510 bgp_dest_unlock_node(dest);
6511 bgp_attr_unintern(&attr_new);
6512 aspath_unintern(&attr.aspath);
6513 return;
6514 } else {
6515 /* The attribute is changed. */
6516 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6517
6518 /* Rewrite BGP route information. */
6519 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6520 bgp_path_info_restore(dest, pi);
6521 else
6522 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6523 bgp_attr_unintern(&pi->attr);
6524 pi->attr = attr_new;
6525 pi->uptime = monotime(NULL);
6526 #ifdef ENABLE_BGP_VNC
6527 if (pi->extra)
6528 label = decode_label(&pi->extra->label[0]);
6529 #endif
6530
6531 /* Process change. */
6532 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6533 bgp_process(bgp, dest, afi, safi);
6534
6535 if (SAFI_MPLS_VPN == safi
6536 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6537 vpn_leak_to_vrf_update(bgp, pi,
6538 &bgp_static->prd);
6539 }
6540 #ifdef ENABLE_BGP_VNC
6541 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6542 pi->attr, afi, safi, pi->type,
6543 pi->sub_type, &label);
6544 #endif
6545 bgp_dest_unlock_node(dest);
6546 aspath_unintern(&attr.aspath);
6547 return;
6548 }
6549 }
6550
6551
6552 /* Make new BGP info. */
6553 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6554 attr_new, dest);
6555 SET_FLAG(new->flags, BGP_PATH_VALID);
6556 bgp_path_info_extra_get(new);
6557 if (num_labels) {
6558 new->extra->label[0] = bgp_static->label;
6559 new->extra->num_labels = num_labels;
6560 }
6561 #ifdef ENABLE_BGP_VNC
6562 label = decode_label(&bgp_static->label);
6563 #endif
6564
6565 /* Aggregate address increment. */
6566 bgp_aggregate_increment(bgp, p, new, afi, safi);
6567
6568 /* Register new BGP information. */
6569 bgp_path_info_add(dest, new);
6570 /* route_node_get lock */
6571 bgp_dest_unlock_node(dest);
6572
6573 /* Process change. */
6574 bgp_process(bgp, dest, afi, safi);
6575
6576 if (SAFI_MPLS_VPN == safi
6577 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6578 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6579 }
6580 #ifdef ENABLE_BGP_VNC
6581 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6582 safi, new->type, new->sub_type, &label);
6583 #endif
6584
6585 /* Unintern original. */
6586 aspath_unintern(&attr.aspath);
6587 }
6588
6589 /* Configure static BGP network. When user don't run zebra, static
6590 route should be installed as valid. */
6591 static int bgp_static_set(struct vty *vty, const char *negate,
6592 const char *ip_str, afi_t afi, safi_t safi,
6593 const char *rmap, int backdoor, uint32_t label_index)
6594 {
6595 VTY_DECLVAR_CONTEXT(bgp, bgp);
6596 int ret;
6597 struct prefix p;
6598 struct bgp_static *bgp_static;
6599 struct bgp_dest *dest;
6600 uint8_t need_update = 0;
6601
6602 /* Convert IP prefix string to struct prefix. */
6603 ret = str2prefix(ip_str, &p);
6604 if (!ret) {
6605 vty_out(vty, "%% Malformed prefix\n");
6606 return CMD_WARNING_CONFIG_FAILED;
6607 }
6608 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6609 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6610 return CMD_WARNING_CONFIG_FAILED;
6611 }
6612
6613 apply_mask(&p);
6614
6615 if (negate) {
6616
6617 /* Set BGP static route configuration. */
6618 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6619
6620 if (!dest) {
6621 vty_out(vty, "%% Can't find static route specified\n");
6622 return CMD_WARNING_CONFIG_FAILED;
6623 }
6624
6625 bgp_static = bgp_dest_get_bgp_static_info(dest);
6626
6627 if ((label_index != BGP_INVALID_LABEL_INDEX)
6628 && (label_index != bgp_static->label_index)) {
6629 vty_out(vty,
6630 "%% label-index doesn't match static route\n");
6631 bgp_dest_unlock_node(dest);
6632 return CMD_WARNING_CONFIG_FAILED;
6633 }
6634
6635 if ((rmap && bgp_static->rmap.name)
6636 && strcmp(rmap, bgp_static->rmap.name)) {
6637 vty_out(vty,
6638 "%% route-map name doesn't match static route\n");
6639 bgp_dest_unlock_node(dest);
6640 return CMD_WARNING_CONFIG_FAILED;
6641 }
6642
6643 /* Update BGP RIB. */
6644 if (!bgp_static->backdoor)
6645 bgp_static_withdraw(bgp, &p, afi, safi);
6646
6647 /* Clear configuration. */
6648 bgp_static_free(bgp_static);
6649 bgp_dest_set_bgp_static_info(dest, NULL);
6650 bgp_dest_unlock_node(dest);
6651 bgp_dest_unlock_node(dest);
6652 } else {
6653
6654 /* Set BGP static route configuration. */
6655 dest = bgp_node_get(bgp->route[afi][safi], &p);
6656 bgp_static = bgp_dest_get_bgp_static_info(dest);
6657 if (bgp_static) {
6658 /* Configuration change. */
6659 /* Label index cannot be changed. */
6660 if (bgp_static->label_index != label_index) {
6661 vty_out(vty, "%% cannot change label-index\n");
6662 bgp_dest_unlock_node(dest);
6663 return CMD_WARNING_CONFIG_FAILED;
6664 }
6665
6666 /* Check previous routes are installed into BGP. */
6667 if (bgp_static->valid
6668 && bgp_static->backdoor != backdoor)
6669 need_update = 1;
6670
6671 bgp_static->backdoor = backdoor;
6672
6673 if (rmap) {
6674 XFREE(MTYPE_ROUTE_MAP_NAME,
6675 bgp_static->rmap.name);
6676 route_map_counter_decrement(
6677 bgp_static->rmap.map);
6678 bgp_static->rmap.name =
6679 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6680 bgp_static->rmap.map =
6681 route_map_lookup_by_name(rmap);
6682 route_map_counter_increment(
6683 bgp_static->rmap.map);
6684 } else {
6685 XFREE(MTYPE_ROUTE_MAP_NAME,
6686 bgp_static->rmap.name);
6687 route_map_counter_decrement(
6688 bgp_static->rmap.map);
6689 bgp_static->rmap.map = NULL;
6690 bgp_static->valid = 0;
6691 }
6692 bgp_dest_unlock_node(dest);
6693 } else {
6694 /* New configuration. */
6695 bgp_static = bgp_static_new();
6696 bgp_static->backdoor = backdoor;
6697 bgp_static->valid = 0;
6698 bgp_static->igpmetric = 0;
6699 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6700 bgp_static->label_index = label_index;
6701
6702 if (rmap) {
6703 XFREE(MTYPE_ROUTE_MAP_NAME,
6704 bgp_static->rmap.name);
6705 route_map_counter_decrement(
6706 bgp_static->rmap.map);
6707 bgp_static->rmap.name =
6708 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6709 bgp_static->rmap.map =
6710 route_map_lookup_by_name(rmap);
6711 route_map_counter_increment(
6712 bgp_static->rmap.map);
6713 }
6714 bgp_dest_set_bgp_static_info(dest, bgp_static);
6715 }
6716
6717 bgp_static->valid = 1;
6718 if (need_update)
6719 bgp_static_withdraw(bgp, &p, afi, safi);
6720
6721 if (!bgp_static->backdoor)
6722 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6723 }
6724
6725 return CMD_SUCCESS;
6726 }
6727
6728 void bgp_static_add(struct bgp *bgp)
6729 {
6730 afi_t afi;
6731 safi_t safi;
6732 struct bgp_dest *dest;
6733 struct bgp_dest *rm;
6734 struct bgp_table *table;
6735 struct bgp_static *bgp_static;
6736
6737 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6738 FOREACH_AFI_SAFI (afi, safi)
6739 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6740 dest = bgp_route_next(dest)) {
6741 if (!bgp_dest_has_bgp_path_info_data(dest))
6742 continue;
6743
6744 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6745 || (safi == SAFI_EVPN)) {
6746 table = bgp_dest_get_bgp_table_info(dest);
6747
6748 for (rm = bgp_table_top(table); rm;
6749 rm = bgp_route_next(rm)) {
6750 bgp_static =
6751 bgp_dest_get_bgp_static_info(
6752 rm);
6753 bgp_static_update_safi(
6754 bgp, bgp_dest_get_prefix(rm),
6755 bgp_static, afi, safi);
6756 }
6757 } else {
6758 bgp_static_update(
6759 bgp, bgp_dest_get_prefix(dest),
6760 bgp_dest_get_bgp_static_info(dest), afi,
6761 safi);
6762 }
6763 }
6764 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6765 }
6766
6767 /* Called from bgp_delete(). Delete all static routes from the BGP
6768 instance. */
6769 void bgp_static_delete(struct bgp *bgp)
6770 {
6771 afi_t afi;
6772 safi_t safi;
6773 struct bgp_dest *dest;
6774 struct bgp_dest *rm;
6775 struct bgp_table *table;
6776 struct bgp_static *bgp_static;
6777
6778 FOREACH_AFI_SAFI (afi, safi)
6779 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6780 dest = bgp_route_next(dest)) {
6781 if (!bgp_dest_has_bgp_path_info_data(dest))
6782 continue;
6783
6784 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6785 || (safi == SAFI_EVPN)) {
6786 table = bgp_dest_get_bgp_table_info(dest);
6787
6788 for (rm = bgp_table_top(table); rm;
6789 rm = bgp_route_next(rm)) {
6790 bgp_static =
6791 bgp_dest_get_bgp_static_info(
6792 rm);
6793 if (!bgp_static)
6794 continue;
6795
6796 bgp_static_withdraw_safi(
6797 bgp, bgp_dest_get_prefix(rm),
6798 AFI_IP, safi,
6799 (struct prefix_rd *)
6800 bgp_dest_get_prefix(
6801 dest));
6802 bgp_static_free(bgp_static);
6803 bgp_dest_set_bgp_static_info(rm,
6804 NULL);
6805 bgp_dest_unlock_node(rm);
6806 }
6807 } else {
6808 bgp_static = bgp_dest_get_bgp_static_info(dest);
6809 bgp_static_withdraw(bgp,
6810 bgp_dest_get_prefix(dest),
6811 afi, safi);
6812 bgp_static_free(bgp_static);
6813 bgp_dest_set_bgp_static_info(dest, NULL);
6814 bgp_dest_unlock_node(dest);
6815 }
6816 }
6817 }
6818
6819 void bgp_static_redo_import_check(struct bgp *bgp)
6820 {
6821 afi_t afi;
6822 safi_t safi;
6823 struct bgp_dest *dest;
6824 struct bgp_dest *rm;
6825 struct bgp_table *table;
6826 struct bgp_static *bgp_static;
6827
6828 /* Use this flag to force reprocessing of the route */
6829 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6830 FOREACH_AFI_SAFI (afi, safi) {
6831 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6832 dest = bgp_route_next(dest)) {
6833 if (!bgp_dest_has_bgp_path_info_data(dest))
6834 continue;
6835
6836 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6837 || (safi == SAFI_EVPN)) {
6838 table = bgp_dest_get_bgp_table_info(dest);
6839
6840 for (rm = bgp_table_top(table); rm;
6841 rm = bgp_route_next(rm)) {
6842 bgp_static =
6843 bgp_dest_get_bgp_static_info(
6844 rm);
6845 bgp_static_update_safi(
6846 bgp, bgp_dest_get_prefix(rm),
6847 bgp_static, afi, safi);
6848 }
6849 } else {
6850 bgp_static = bgp_dest_get_bgp_static_info(dest);
6851 bgp_static_update(bgp,
6852 bgp_dest_get_prefix(dest),
6853 bgp_static, afi, safi);
6854 }
6855 }
6856 }
6857 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6858 }
6859
6860 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6861 safi_t safi)
6862 {
6863 struct bgp_table *table;
6864 struct bgp_dest *dest;
6865 struct bgp_path_info *pi;
6866
6867 /* Do not install the aggregate route if BGP is in the
6868 * process of termination.
6869 */
6870 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6871 || (bgp->peer_self == NULL))
6872 return;
6873
6874 table = bgp->rib[afi][safi];
6875 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6876 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6877 if (pi->peer == bgp->peer_self
6878 && ((pi->type == ZEBRA_ROUTE_BGP
6879 && pi->sub_type == BGP_ROUTE_STATIC)
6880 || (pi->type != ZEBRA_ROUTE_BGP
6881 && pi->sub_type
6882 == BGP_ROUTE_REDISTRIBUTE))) {
6883 bgp_aggregate_decrement(
6884 bgp, bgp_dest_get_prefix(dest), pi, afi,
6885 safi);
6886 bgp_unlink_nexthop(pi);
6887 bgp_path_info_delete(dest, pi);
6888 bgp_process(bgp, dest, afi, safi);
6889 }
6890 }
6891 }
6892 }
6893
6894 /*
6895 * Purge all networks and redistributed routes from routing table.
6896 * Invoked upon the instance going down.
6897 */
6898 void bgp_purge_static_redist_routes(struct bgp *bgp)
6899 {
6900 afi_t afi;
6901 safi_t safi;
6902
6903 FOREACH_AFI_SAFI (afi, safi)
6904 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6905 }
6906
6907 /*
6908 * gpz 110624
6909 * Currently this is used to set static routes for VPN and ENCAP.
6910 * I think it can probably be factored with bgp_static_set.
6911 */
6912 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6913 const char *ip_str, const char *rd_str,
6914 const char *label_str, const char *rmap_str,
6915 int evpn_type, const char *esi, const char *gwip,
6916 const char *ethtag, const char *routermac)
6917 {
6918 VTY_DECLVAR_CONTEXT(bgp, bgp);
6919 int ret;
6920 struct prefix p;
6921 struct prefix_rd prd;
6922 struct bgp_dest *pdest;
6923 struct bgp_dest *dest;
6924 struct bgp_table *table;
6925 struct bgp_static *bgp_static;
6926 mpls_label_t label = MPLS_INVALID_LABEL;
6927 struct prefix gw_ip;
6928
6929 /* validate ip prefix */
6930 ret = str2prefix(ip_str, &p);
6931 if (!ret) {
6932 vty_out(vty, "%% Malformed prefix\n");
6933 return CMD_WARNING_CONFIG_FAILED;
6934 }
6935 apply_mask(&p);
6936 if ((afi == AFI_L2VPN)
6937 && (bgp_build_evpn_prefix(evpn_type,
6938 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6939 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6940 return CMD_WARNING_CONFIG_FAILED;
6941 }
6942
6943 ret = str2prefix_rd(rd_str, &prd);
6944 if (!ret) {
6945 vty_out(vty, "%% Malformed rd\n");
6946 return CMD_WARNING_CONFIG_FAILED;
6947 }
6948
6949 if (label_str) {
6950 unsigned long label_val;
6951 label_val = strtoul(label_str, NULL, 10);
6952 encode_label(label_val, &label);
6953 }
6954
6955 if (safi == SAFI_EVPN) {
6956 if (esi && str2esi(esi, NULL) == 0) {
6957 vty_out(vty, "%% Malformed ESI\n");
6958 return CMD_WARNING_CONFIG_FAILED;
6959 }
6960 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6961 vty_out(vty, "%% Malformed Router MAC\n");
6962 return CMD_WARNING_CONFIG_FAILED;
6963 }
6964 if (gwip) {
6965 memset(&gw_ip, 0, sizeof(gw_ip));
6966 ret = str2prefix(gwip, &gw_ip);
6967 if (!ret) {
6968 vty_out(vty, "%% Malformed GatewayIp\n");
6969 return CMD_WARNING_CONFIG_FAILED;
6970 }
6971 if ((gw_ip.family == AF_INET
6972 && is_evpn_prefix_ipaddr_v6(
6973 (struct prefix_evpn *)&p))
6974 || (gw_ip.family == AF_INET6
6975 && is_evpn_prefix_ipaddr_v4(
6976 (struct prefix_evpn *)&p))) {
6977 vty_out(vty,
6978 "%% GatewayIp family differs with IP prefix\n");
6979 return CMD_WARNING_CONFIG_FAILED;
6980 }
6981 }
6982 }
6983 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6984 if (!bgp_dest_has_bgp_path_info_data(pdest))
6985 bgp_dest_set_bgp_table_info(pdest,
6986 bgp_table_init(bgp, afi, safi));
6987 table = bgp_dest_get_bgp_table_info(pdest);
6988
6989 dest = bgp_node_get(table, &p);
6990
6991 if (bgp_dest_has_bgp_path_info_data(dest)) {
6992 vty_out(vty, "%% Same network configuration exists\n");
6993 bgp_dest_unlock_node(dest);
6994 } else {
6995 /* New configuration. */
6996 bgp_static = bgp_static_new();
6997 bgp_static->backdoor = 0;
6998 bgp_static->valid = 0;
6999 bgp_static->igpmetric = 0;
7000 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7001 bgp_static->label = label;
7002 bgp_static->prd = prd;
7003
7004 if (rd_str)
7005 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
7006 if (rmap_str) {
7007 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7008 route_map_counter_decrement(bgp_static->rmap.map);
7009 bgp_static->rmap.name =
7010 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7011 bgp_static->rmap.map =
7012 route_map_lookup_by_name(rmap_str);
7013 route_map_counter_increment(bgp_static->rmap.map);
7014 }
7015
7016 if (safi == SAFI_EVPN) {
7017 if (esi) {
7018 bgp_static->eth_s_id =
7019 XCALLOC(MTYPE_ATTR,
7020 sizeof(esi_t));
7021 str2esi(esi, bgp_static->eth_s_id);
7022 }
7023 if (routermac) {
7024 bgp_static->router_mac =
7025 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7026 (void)prefix_str2mac(routermac,
7027 bgp_static->router_mac);
7028 }
7029 if (gwip)
7030 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7031 }
7032 bgp_dest_set_bgp_static_info(dest, bgp_static);
7033
7034 bgp_static->valid = 1;
7035 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7036 }
7037
7038 return CMD_SUCCESS;
7039 }
7040
7041 /* Configure static BGP network. */
7042 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7043 const char *ip_str, const char *rd_str,
7044 const char *label_str, int evpn_type, const char *esi,
7045 const char *gwip, const char *ethtag)
7046 {
7047 VTY_DECLVAR_CONTEXT(bgp, bgp);
7048 int ret;
7049 struct prefix p;
7050 struct prefix_rd prd;
7051 struct bgp_dest *pdest;
7052 struct bgp_dest *dest;
7053 struct bgp_table *table;
7054 struct bgp_static *bgp_static;
7055 mpls_label_t label = MPLS_INVALID_LABEL;
7056
7057 /* Convert IP prefix string to struct prefix. */
7058 ret = str2prefix(ip_str, &p);
7059 if (!ret) {
7060 vty_out(vty, "%% Malformed prefix\n");
7061 return CMD_WARNING_CONFIG_FAILED;
7062 }
7063 apply_mask(&p);
7064 if ((afi == AFI_L2VPN)
7065 && (bgp_build_evpn_prefix(evpn_type,
7066 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7067 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7068 return CMD_WARNING_CONFIG_FAILED;
7069 }
7070 ret = str2prefix_rd(rd_str, &prd);
7071 if (!ret) {
7072 vty_out(vty, "%% Malformed rd\n");
7073 return CMD_WARNING_CONFIG_FAILED;
7074 }
7075
7076 if (label_str) {
7077 unsigned long label_val;
7078 label_val = strtoul(label_str, NULL, 10);
7079 encode_label(label_val, &label);
7080 }
7081
7082 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7083 if (!bgp_dest_has_bgp_path_info_data(pdest))
7084 bgp_dest_set_bgp_table_info(pdest,
7085 bgp_table_init(bgp, afi, safi));
7086 else
7087 bgp_dest_unlock_node(pdest);
7088 table = bgp_dest_get_bgp_table_info(pdest);
7089
7090 dest = bgp_node_lookup(table, &p);
7091
7092 if (dest) {
7093 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7094
7095 bgp_static = bgp_dest_get_bgp_static_info(dest);
7096 bgp_static_free(bgp_static);
7097 bgp_dest_set_bgp_static_info(dest, NULL);
7098 bgp_dest_unlock_node(dest);
7099 bgp_dest_unlock_node(dest);
7100 } else
7101 vty_out(vty, "%% Can't find the route\n");
7102
7103 return CMD_SUCCESS;
7104 }
7105
7106 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7107 const char *rmap_name)
7108 {
7109 VTY_DECLVAR_CONTEXT(bgp, bgp);
7110 struct bgp_rmap *rmap;
7111
7112 rmap = &bgp->table_map[afi][safi];
7113 if (rmap_name) {
7114 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7115 route_map_counter_decrement(rmap->map);
7116 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7117 rmap->map = route_map_lookup_by_name(rmap_name);
7118 route_map_counter_increment(rmap->map);
7119 } else {
7120 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7121 route_map_counter_decrement(rmap->map);
7122 rmap->map = NULL;
7123 }
7124
7125 if (bgp_fibupd_safi(safi))
7126 bgp_zebra_announce_table(bgp, afi, safi);
7127
7128 return CMD_SUCCESS;
7129 }
7130
7131 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7132 const char *rmap_name)
7133 {
7134 VTY_DECLVAR_CONTEXT(bgp, bgp);
7135 struct bgp_rmap *rmap;
7136
7137 rmap = &bgp->table_map[afi][safi];
7138 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7139 route_map_counter_decrement(rmap->map);
7140 rmap->map = NULL;
7141
7142 if (bgp_fibupd_safi(safi))
7143 bgp_zebra_announce_table(bgp, afi, safi);
7144
7145 return CMD_SUCCESS;
7146 }
7147
7148 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7149 safi_t safi)
7150 {
7151 if (bgp->table_map[afi][safi].name) {
7152 vty_out(vty, " table-map %s\n",
7153 bgp->table_map[afi][safi].name);
7154 }
7155 }
7156
7157 DEFUN (bgp_table_map,
7158 bgp_table_map_cmd,
7159 "table-map WORD",
7160 "BGP table to RIB route download filter\n"
7161 "Name of the route map\n")
7162 {
7163 int idx_word = 1;
7164 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7165 argv[idx_word]->arg);
7166 }
7167 DEFUN (no_bgp_table_map,
7168 no_bgp_table_map_cmd,
7169 "no table-map WORD",
7170 NO_STR
7171 "BGP table to RIB route download filter\n"
7172 "Name of the route map\n")
7173 {
7174 int idx_word = 2;
7175 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7176 argv[idx_word]->arg);
7177 }
7178
7179 DEFPY(bgp_network,
7180 bgp_network_cmd,
7181 "[no] network \
7182 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7183 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7184 backdoor$backdoor}]",
7185 NO_STR
7186 "Specify a network to announce via BGP\n"
7187 "IPv4 prefix\n"
7188 "Network number\n"
7189 "Network mask\n"
7190 "Network mask\n"
7191 "Route-map to modify the attributes\n"
7192 "Name of the route map\n"
7193 "Label index to associate with the prefix\n"
7194 "Label index value\n"
7195 "Specify a BGP backdoor route\n")
7196 {
7197 char addr_prefix_str[BUFSIZ];
7198
7199 if (address_str) {
7200 int ret;
7201
7202 ret = netmask_str2prefix_str(address_str, netmask_str,
7203 addr_prefix_str,
7204 sizeof(addr_prefix_str));
7205 if (!ret) {
7206 vty_out(vty, "%% Inconsistent address and mask\n");
7207 return CMD_WARNING_CONFIG_FAILED;
7208 }
7209 }
7210
7211 return bgp_static_set(
7212 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7213 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7214 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7215 }
7216
7217 DEFPY(ipv6_bgp_network,
7218 ipv6_bgp_network_cmd,
7219 "[no] network X:X::X:X/M$prefix \
7220 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7221 NO_STR
7222 "Specify a network to announce via BGP\n"
7223 "IPv6 prefix\n"
7224 "Route-map to modify the attributes\n"
7225 "Name of the route map\n"
7226 "Label index to associate with the prefix\n"
7227 "Label index value\n")
7228 {
7229 return bgp_static_set(
7230 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7231 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7232 }
7233
7234 static struct bgp_aggregate *bgp_aggregate_new(void)
7235 {
7236 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7237 }
7238
7239 void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7240 {
7241 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7242 route_map_counter_decrement(aggregate->suppress_map);
7243 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7244 route_map_counter_decrement(aggregate->rmap.map);
7245 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7246 }
7247
7248 /**
7249 * Helper function to avoid repeated code: prepare variables for a
7250 * `route_map_apply` call.
7251 *
7252 * \returns `true` on route map match, otherwise `false`.
7253 */
7254 static bool aggr_suppress_map_test(struct bgp *bgp,
7255 struct bgp_aggregate *aggregate,
7256 struct bgp_path_info *pi)
7257 {
7258 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7259 route_map_result_t rmr = RMAP_DENYMATCH;
7260 struct bgp_path_info rmap_path = {};
7261 struct attr attr = {};
7262
7263 /* No route map entries created, just don't match. */
7264 if (aggregate->suppress_map == NULL)
7265 return false;
7266
7267 /* Call route map matching and return result. */
7268 attr.aspath = aspath_empty(bgp->asnotation);
7269 rmap_path.peer = bgp->peer_self;
7270 rmap_path.attr = &attr;
7271
7272 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7273 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7274 bgp->peer_self->rmap_type = 0;
7275
7276 bgp_attr_flush(&attr);
7277 aspath_unintern(&attr.aspath);
7278
7279 return rmr == RMAP_PERMITMATCH;
7280 }
7281
7282 /** Test whether the aggregation has suppressed this path or not. */
7283 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7284 struct bgp_path_info *pi)
7285 {
7286 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7287 return false;
7288
7289 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7290 }
7291
7292 /**
7293 * Suppress this path and keep the reference.
7294 *
7295 * \returns `true` if needs processing otherwise `false`.
7296 */
7297 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7298 struct bgp_path_info *pi)
7299 {
7300 struct bgp_path_info_extra *pie;
7301
7302 /* Path is already suppressed by this aggregation. */
7303 if (aggr_suppress_exists(aggregate, pi))
7304 return false;
7305
7306 pie = bgp_path_info_extra_get(pi);
7307
7308 /* This is the first suppression, allocate memory and list it. */
7309 if (pie->aggr_suppressors == NULL)
7310 pie->aggr_suppressors = list_new();
7311
7312 listnode_add(pie->aggr_suppressors, aggregate);
7313
7314 /* Only mark for processing if suppressed. */
7315 if (listcount(pie->aggr_suppressors) == 1) {
7316 if (BGP_DEBUG(update, UPDATE_OUT))
7317 zlog_debug("aggregate-address suppressing: %pFX",
7318 bgp_dest_get_prefix(pi->net));
7319
7320 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7321 return true;
7322 }
7323
7324 return false;
7325 }
7326
7327 /**
7328 * Unsuppress this path and remove the reference.
7329 *
7330 * \returns `true` if needs processing otherwise `false`.
7331 */
7332 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7333 struct bgp_path_info *pi)
7334 {
7335 /* Path wasn't suppressed. */
7336 if (!aggr_suppress_exists(aggregate, pi))
7337 return false;
7338
7339 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7340
7341 /* Unsuppress and free extra memory if last item. */
7342 if (listcount(pi->extra->aggr_suppressors) == 0) {
7343 if (BGP_DEBUG(update, UPDATE_OUT))
7344 zlog_debug("aggregate-address unsuppressing: %pFX",
7345 bgp_dest_get_prefix(pi->net));
7346
7347 list_delete(&pi->extra->aggr_suppressors);
7348 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7349 return true;
7350 }
7351
7352 return false;
7353 }
7354
7355 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7356 struct aspath *aspath,
7357 struct community *comm,
7358 struct ecommunity *ecomm,
7359 struct lcommunity *lcomm)
7360 {
7361 static struct aspath *ae = NULL;
7362 enum asnotation_mode asnotation;
7363
7364 asnotation = bgp_get_asnotation(NULL);
7365
7366 if (!ae)
7367 ae = aspath_empty(asnotation);
7368
7369 if (!pi)
7370 return false;
7371
7372 if (origin != pi->attr->origin)
7373 return false;
7374
7375 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7376 return false;
7377
7378 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7379 return false;
7380
7381 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7382 return false;
7383
7384 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7385 return false;
7386
7387 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7388 return false;
7389
7390 return true;
7391 }
7392
7393 static void bgp_aggregate_install(
7394 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7395 uint8_t origin, struct aspath *aspath, struct community *community,
7396 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7397 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7398 {
7399 struct bgp_dest *dest;
7400 struct bgp_table *table;
7401 struct bgp_path_info *pi, *orig, *new;
7402 struct attr *attr;
7403
7404 table = bgp->rib[afi][safi];
7405
7406 dest = bgp_node_get(table, p);
7407
7408 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7409 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7410 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7411 break;
7412
7413 /*
7414 * If we have paths with different MEDs, then don't install
7415 * (or uninstall) the aggregate route.
7416 */
7417 if (aggregate->match_med && aggregate->med_mismatched)
7418 goto uninstall_aggregate_route;
7419
7420 if (aggregate->count > 0) {
7421 /*
7422 * If the aggregate information has not changed
7423 * no need to re-install it again.
7424 */
7425 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7426 ecommunity, lcommunity)) {
7427 bgp_dest_unlock_node(dest);
7428
7429 if (aspath)
7430 aspath_free(aspath);
7431 if (community)
7432 community_free(&community);
7433 if (ecommunity)
7434 ecommunity_free(&ecommunity);
7435 if (lcommunity)
7436 lcommunity_free(&lcommunity);
7437
7438 return;
7439 }
7440
7441 /*
7442 * Mark the old as unusable
7443 */
7444 if (pi)
7445 bgp_path_info_delete(dest, pi);
7446
7447 attr = bgp_attr_aggregate_intern(
7448 bgp, origin, aspath, community, ecommunity, lcommunity,
7449 aggregate, atomic_aggregate, p);
7450
7451 if (!attr) {
7452 aspath_free(aspath);
7453 community_free(&community);
7454 ecommunity_free(&ecommunity);
7455 lcommunity_free(&lcommunity);
7456 bgp_dest_unlock_node(dest);
7457 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7458 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7459 zlog_debug("%s: %pFX null attribute", __func__,
7460 p);
7461 return;
7462 }
7463
7464 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7465 bgp->peer_self, attr, dest);
7466
7467 SET_FLAG(new->flags, BGP_PATH_VALID);
7468
7469 bgp_path_info_add(dest, new);
7470 bgp_process(bgp, dest, afi, safi);
7471 } else {
7472 uninstall_aggregate_route:
7473 for (pi = orig; pi; pi = pi->next)
7474 if (pi->peer == bgp->peer_self
7475 && pi->type == ZEBRA_ROUTE_BGP
7476 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7477 break;
7478
7479 /* Withdraw static BGP route from routing table. */
7480 if (pi) {
7481 bgp_path_info_delete(dest, pi);
7482 bgp_process(bgp, dest, afi, safi);
7483 }
7484 }
7485
7486 bgp_dest_unlock_node(dest);
7487 }
7488
7489 /**
7490 * Check if the current path has different MED than other known paths.
7491 *
7492 * \returns `true` if the MED matched the others else `false`.
7493 */
7494 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7495 struct bgp *bgp, struct bgp_path_info *pi)
7496 {
7497 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7498
7499 /* This is the first route being analyzed. */
7500 if (!aggregate->med_initialized) {
7501 aggregate->med_initialized = true;
7502 aggregate->med_mismatched = false;
7503 aggregate->med_matched_value = cur_med;
7504 } else {
7505 /* Check if routes with different MED showed up. */
7506 if (cur_med != aggregate->med_matched_value)
7507 aggregate->med_mismatched = true;
7508 }
7509
7510 return !aggregate->med_mismatched;
7511 }
7512
7513 /**
7514 * Initializes and tests all routes in the aggregate address path for MED
7515 * values.
7516 *
7517 * \returns `true` if all MEDs are the same otherwise `false`.
7518 */
7519 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7520 struct bgp *bgp, const struct prefix *p,
7521 afi_t afi, safi_t safi)
7522 {
7523 struct bgp_table *table = bgp->rib[afi][safi];
7524 const struct prefix *dest_p;
7525 struct bgp_dest *dest, *top;
7526 struct bgp_path_info *pi;
7527 bool med_matched = true;
7528
7529 aggregate->med_initialized = false;
7530
7531 top = bgp_node_get(table, p);
7532 for (dest = bgp_node_get(table, p); dest;
7533 dest = bgp_route_next_until(dest, top)) {
7534 dest_p = bgp_dest_get_prefix(dest);
7535 if (dest_p->prefixlen <= p->prefixlen)
7536 continue;
7537
7538 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7539 if (BGP_PATH_HOLDDOWN(pi))
7540 continue;
7541 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7542 continue;
7543 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7544 med_matched = false;
7545 break;
7546 }
7547 }
7548 if (!med_matched)
7549 break;
7550 }
7551 bgp_dest_unlock_node(top);
7552
7553 return med_matched;
7554 }
7555
7556 /**
7557 * Toggles the route suppression status for this aggregate address
7558 * configuration.
7559 */
7560 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7561 struct bgp *bgp, const struct prefix *p,
7562 afi_t afi, safi_t safi, bool suppress)
7563 {
7564 struct bgp_table *table = bgp->rib[afi][safi];
7565 const struct prefix *dest_p;
7566 struct bgp_dest *dest, *top;
7567 struct bgp_path_info *pi;
7568 bool toggle_suppression;
7569
7570 /* We've found a different MED we must revert any suppressed routes. */
7571 top = bgp_node_get(table, p);
7572 for (dest = bgp_node_get(table, p); dest;
7573 dest = bgp_route_next_until(dest, top)) {
7574 dest_p = bgp_dest_get_prefix(dest);
7575 if (dest_p->prefixlen <= p->prefixlen)
7576 continue;
7577
7578 toggle_suppression = false;
7579 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7580 if (BGP_PATH_HOLDDOWN(pi))
7581 continue;
7582 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7583 continue;
7584
7585 /* We are toggling suppression back. */
7586 if (suppress) {
7587 /* Suppress route if not suppressed already. */
7588 if (aggr_suppress_path(aggregate, pi))
7589 toggle_suppression = true;
7590 continue;
7591 }
7592
7593 /* Install route if there is no more suppression. */
7594 if (aggr_unsuppress_path(aggregate, pi))
7595 toggle_suppression = true;
7596 }
7597
7598 if (toggle_suppression)
7599 bgp_process(bgp, dest, afi, safi);
7600 }
7601 bgp_dest_unlock_node(top);
7602 }
7603
7604 /**
7605 * Aggregate address MED matching incremental test: this function is called
7606 * when the initial aggregation occurred and we are only testing a single
7607 * new path.
7608 *
7609 * In addition to testing and setting the MED validity it also installs back
7610 * suppressed routes (if summary is configured).
7611 *
7612 * Must not be called in `bgp_aggregate_route`.
7613 */
7614 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7615 struct bgp *bgp, const struct prefix *p,
7616 afi_t afi, safi_t safi,
7617 struct bgp_path_info *pi)
7618 {
7619 /* MED matching disabled. */
7620 if (!aggregate->match_med)
7621 return;
7622
7623 /* Aggregation with different MED, recheck if we have got equal MEDs
7624 * now.
7625 */
7626 if (aggregate->med_mismatched &&
7627 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7628 aggregate->summary_only)
7629 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7630 true);
7631 else
7632 bgp_aggregate_med_match(aggregate, bgp, pi);
7633
7634 /* No mismatches, just quit. */
7635 if (!aggregate->med_mismatched)
7636 return;
7637
7638 /* Route summarization is disabled. */
7639 if (!aggregate->summary_only)
7640 return;
7641
7642 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7643 }
7644
7645 /* Update an aggregate as routes are added/removed from the BGP table */
7646 bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7647 safi_t safi, struct bgp_aggregate *aggregate)
7648 {
7649 struct bgp_table *table;
7650 struct bgp_dest *top;
7651 struct bgp_dest *dest;
7652 uint8_t origin;
7653 struct aspath *aspath = NULL;
7654 struct community *community = NULL;
7655 struct ecommunity *ecommunity = NULL;
7656 struct lcommunity *lcommunity = NULL;
7657 struct bgp_path_info *pi;
7658 unsigned long match = 0;
7659 uint8_t atomic_aggregate = 0;
7660
7661 /* If the bgp instance is being deleted or self peer is deleted
7662 * then do not create aggregate route
7663 */
7664 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
7665 bgp->peer_self == NULL)
7666 return false;
7667
7668 /* Initialize and test routes for MED difference. */
7669 if (aggregate->match_med)
7670 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7671
7672 /*
7673 * Reset aggregate count: we might've been called from route map
7674 * update so in that case we must retest all more specific routes.
7675 *
7676 * \see `bgp_route_map_process_update`.
7677 */
7678 aggregate->count = 0;
7679 aggregate->incomplete_origin_count = 0;
7680 aggregate->incomplete_origin_count = 0;
7681 aggregate->egp_origin_count = 0;
7682
7683 /* ORIGIN attribute: If at least one route among routes that are
7684 aggregated has ORIGIN with the value INCOMPLETE, then the
7685 aggregated route must have the ORIGIN attribute with the value
7686 INCOMPLETE. Otherwise, if at least one route among routes that
7687 are aggregated has ORIGIN with the value EGP, then the aggregated
7688 route must have the origin attribute with the value EGP. In all
7689 other case the value of the ORIGIN attribute of the aggregated
7690 route is INTERNAL. */
7691 origin = BGP_ORIGIN_IGP;
7692
7693 table = bgp->rib[afi][safi];
7694
7695 top = bgp_node_get(table, p);
7696 for (dest = bgp_node_get(table, p); dest;
7697 dest = bgp_route_next_until(dest, top)) {
7698 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7699
7700 if (dest_p->prefixlen <= p->prefixlen)
7701 continue;
7702
7703 /* If suppress fib is enabled and route not installed
7704 * in FIB, skip the route
7705 */
7706 if (!bgp_check_advertise(bgp, dest))
7707 continue;
7708
7709 match = 0;
7710
7711 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7712 if (BGP_PATH_HOLDDOWN(pi))
7713 continue;
7714
7715 if (pi->attr->flag
7716 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7717 atomic_aggregate = 1;
7718
7719 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7720 continue;
7721
7722 /*
7723 * summary-only aggregate route suppress
7724 * aggregated route announcements.
7725 *
7726 * MED matching:
7727 * Don't create summaries if MED didn't match
7728 * otherwise neither the specific routes and the
7729 * aggregation will be announced.
7730 */
7731 if (aggregate->summary_only
7732 && AGGREGATE_MED_VALID(aggregate)) {
7733 if (aggr_suppress_path(aggregate, pi))
7734 match++;
7735 }
7736
7737 /*
7738 * Suppress more specific routes that match the route
7739 * map results.
7740 *
7741 * MED matching:
7742 * Don't suppress routes if MED matching is enabled and
7743 * it mismatched otherwise we might end up with no
7744 * routes for this path.
7745 */
7746 if (aggregate->suppress_map_name
7747 && AGGREGATE_MED_VALID(aggregate)
7748 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7749 if (aggr_suppress_path(aggregate, pi))
7750 match++;
7751 }
7752
7753 aggregate->count++;
7754
7755 /*
7756 * If at least one route among routes that are
7757 * aggregated has ORIGIN with the value INCOMPLETE,
7758 * then the aggregated route MUST have the ORIGIN
7759 * attribute with the value INCOMPLETE. Otherwise, if
7760 * at least one route among routes that are aggregated
7761 * has ORIGIN with the value EGP, then the aggregated
7762 * route MUST have the ORIGIN attribute with the value
7763 * EGP.
7764 */
7765 switch (pi->attr->origin) {
7766 case BGP_ORIGIN_INCOMPLETE:
7767 aggregate->incomplete_origin_count++;
7768 break;
7769 case BGP_ORIGIN_EGP:
7770 aggregate->egp_origin_count++;
7771 break;
7772 default:
7773 /*Do nothing.
7774 */
7775 break;
7776 }
7777
7778 if (!aggregate->as_set)
7779 continue;
7780
7781 /*
7782 * as-set aggregate route generate origin, as path,
7783 * and community aggregation.
7784 */
7785 /* Compute aggregate route's as-path.
7786 */
7787 bgp_compute_aggregate_aspath_hash(aggregate,
7788 pi->attr->aspath);
7789
7790 /* Compute aggregate route's community.
7791 */
7792 if (bgp_attr_get_community(pi->attr))
7793 bgp_compute_aggregate_community_hash(
7794 aggregate,
7795 bgp_attr_get_community(pi->attr));
7796
7797 /* Compute aggregate route's extended community.
7798 */
7799 if (bgp_attr_get_ecommunity(pi->attr))
7800 bgp_compute_aggregate_ecommunity_hash(
7801 aggregate,
7802 bgp_attr_get_ecommunity(pi->attr));
7803
7804 /* Compute aggregate route's large community.
7805 */
7806 if (bgp_attr_get_lcommunity(pi->attr))
7807 bgp_compute_aggregate_lcommunity_hash(
7808 aggregate,
7809 bgp_attr_get_lcommunity(pi->attr));
7810 }
7811 if (match)
7812 bgp_process(bgp, dest, afi, safi);
7813 }
7814 if (aggregate->as_set) {
7815 bgp_compute_aggregate_aspath_val(aggregate);
7816 bgp_compute_aggregate_community_val(aggregate);
7817 bgp_compute_aggregate_ecommunity_val(aggregate);
7818 bgp_compute_aggregate_lcommunity_val(aggregate);
7819 }
7820
7821
7822 bgp_dest_unlock_node(top);
7823
7824
7825 if (aggregate->incomplete_origin_count > 0)
7826 origin = BGP_ORIGIN_INCOMPLETE;
7827 else if (aggregate->egp_origin_count > 0)
7828 origin = BGP_ORIGIN_EGP;
7829
7830 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7831 origin = aggregate->origin;
7832
7833 if (aggregate->as_set) {
7834 if (aggregate->aspath)
7835 /* Retrieve aggregate route's as-path.
7836 */
7837 aspath = aspath_dup(aggregate->aspath);
7838
7839 if (aggregate->community)
7840 /* Retrieve aggregate route's community.
7841 */
7842 community = community_dup(aggregate->community);
7843
7844 if (aggregate->ecommunity)
7845 /* Retrieve aggregate route's ecommunity.
7846 */
7847 ecommunity = ecommunity_dup(aggregate->ecommunity);
7848
7849 if (aggregate->lcommunity)
7850 /* Retrieve aggregate route's lcommunity.
7851 */
7852 lcommunity = lcommunity_dup(aggregate->lcommunity);
7853 }
7854
7855 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7856 ecommunity, lcommunity, atomic_aggregate,
7857 aggregate);
7858
7859 return true;
7860 }
7861
7862 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7863 safi_t safi, struct bgp_aggregate *aggregate)
7864 {
7865 struct bgp_table *table;
7866 struct bgp_dest *top;
7867 struct bgp_dest *dest;
7868 struct bgp_path_info *pi;
7869 unsigned long match;
7870
7871 table = bgp->rib[afi][safi];
7872
7873 /* If routes exists below this node, generate aggregate routes. */
7874 top = bgp_node_get(table, p);
7875 for (dest = bgp_node_get(table, p); dest;
7876 dest = bgp_route_next_until(dest, top)) {
7877 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7878
7879 if (dest_p->prefixlen <= p->prefixlen)
7880 continue;
7881 match = 0;
7882
7883 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7884 if (BGP_PATH_HOLDDOWN(pi))
7885 continue;
7886
7887 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7888 continue;
7889
7890 /*
7891 * This route is suppressed: attempt to unsuppress it.
7892 *
7893 * `aggr_unsuppress_path` will fail if this particular
7894 * aggregate route was not the suppressor.
7895 */
7896 if (pi->extra && pi->extra->aggr_suppressors &&
7897 listcount(pi->extra->aggr_suppressors)) {
7898 if (aggr_unsuppress_path(aggregate, pi))
7899 match++;
7900 }
7901
7902 aggregate->count--;
7903
7904 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7905 aggregate->incomplete_origin_count--;
7906 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7907 aggregate->egp_origin_count--;
7908
7909 if (aggregate->as_set) {
7910 /* Remove as-path from aggregate.
7911 */
7912 bgp_remove_aspath_from_aggregate_hash(
7913 aggregate,
7914 pi->attr->aspath);
7915
7916 if (bgp_attr_get_community(pi->attr))
7917 /* Remove community from aggregate.
7918 */
7919 bgp_remove_comm_from_aggregate_hash(
7920 aggregate,
7921 bgp_attr_get_community(
7922 pi->attr));
7923
7924 if (bgp_attr_get_ecommunity(pi->attr))
7925 /* Remove ecommunity from aggregate.
7926 */
7927 bgp_remove_ecomm_from_aggregate_hash(
7928 aggregate,
7929 bgp_attr_get_ecommunity(
7930 pi->attr));
7931
7932 if (bgp_attr_get_lcommunity(pi->attr))
7933 /* Remove lcommunity from aggregate.
7934 */
7935 bgp_remove_lcomm_from_aggregate_hash(
7936 aggregate,
7937 bgp_attr_get_lcommunity(
7938 pi->attr));
7939 }
7940 }
7941
7942 /* If this node was suppressed, process the change. */
7943 if (match)
7944 bgp_process(bgp, dest, afi, safi);
7945 }
7946 if (aggregate->as_set) {
7947 aspath_free(aggregate->aspath);
7948 aggregate->aspath = NULL;
7949 if (aggregate->community)
7950 community_free(&aggregate->community);
7951 if (aggregate->ecommunity)
7952 ecommunity_free(&aggregate->ecommunity);
7953 if (aggregate->lcommunity)
7954 lcommunity_free(&aggregate->lcommunity);
7955 }
7956
7957 bgp_dest_unlock_node(top);
7958 }
7959
7960 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7961 const struct prefix *aggr_p,
7962 struct bgp_path_info *pinew, afi_t afi,
7963 safi_t safi,
7964 struct bgp_aggregate *aggregate)
7965 {
7966 uint8_t origin;
7967 struct aspath *aspath = NULL;
7968 uint8_t atomic_aggregate = 0;
7969 struct community *community = NULL;
7970 struct ecommunity *ecommunity = NULL;
7971 struct lcommunity *lcommunity = NULL;
7972
7973 /* If the bgp instance is being deleted or self peer is deleted
7974 * then do not create aggregate route
7975 */
7976 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7977 || (bgp->peer_self == NULL))
7978 return;
7979
7980 /* ORIGIN attribute: If at least one route among routes that are
7981 * aggregated has ORIGIN with the value INCOMPLETE, then the
7982 * aggregated route must have the ORIGIN attribute with the value
7983 * INCOMPLETE. Otherwise, if at least one route among routes that
7984 * are aggregated has ORIGIN with the value EGP, then the aggregated
7985 * route must have the origin attribute with the value EGP. In all
7986 * other case the value of the ORIGIN attribute of the aggregated
7987 * route is INTERNAL.
7988 */
7989 origin = BGP_ORIGIN_IGP;
7990
7991 aggregate->count++;
7992
7993 /*
7994 * This must be called before `summary` check to avoid
7995 * "suppressing" twice.
7996 */
7997 if (aggregate->match_med)
7998 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7999 pinew);
8000
8001 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8002 aggr_suppress_path(aggregate, pinew);
8003
8004 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8005 && aggr_suppress_map_test(bgp, aggregate, pinew))
8006 aggr_suppress_path(aggregate, pinew);
8007
8008 switch (pinew->attr->origin) {
8009 case BGP_ORIGIN_INCOMPLETE:
8010 aggregate->incomplete_origin_count++;
8011 break;
8012 case BGP_ORIGIN_EGP:
8013 aggregate->egp_origin_count++;
8014 break;
8015 default:
8016 /* Do nothing.
8017 */
8018 break;
8019 }
8020
8021 if (aggregate->incomplete_origin_count > 0)
8022 origin = BGP_ORIGIN_INCOMPLETE;
8023 else if (aggregate->egp_origin_count > 0)
8024 origin = BGP_ORIGIN_EGP;
8025
8026 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8027 origin = aggregate->origin;
8028
8029 if (aggregate->as_set) {
8030 /* Compute aggregate route's as-path.
8031 */
8032 bgp_compute_aggregate_aspath(aggregate,
8033 pinew->attr->aspath);
8034
8035 /* Compute aggregate route's community.
8036 */
8037 if (bgp_attr_get_community(pinew->attr))
8038 bgp_compute_aggregate_community(
8039 aggregate, bgp_attr_get_community(pinew->attr));
8040
8041 /* Compute aggregate route's extended community.
8042 */
8043 if (bgp_attr_get_ecommunity(pinew->attr))
8044 bgp_compute_aggregate_ecommunity(
8045 aggregate,
8046 bgp_attr_get_ecommunity(pinew->attr));
8047
8048 /* Compute aggregate route's large community.
8049 */
8050 if (bgp_attr_get_lcommunity(pinew->attr))
8051 bgp_compute_aggregate_lcommunity(
8052 aggregate,
8053 bgp_attr_get_lcommunity(pinew->attr));
8054
8055 /* Retrieve aggregate route's as-path.
8056 */
8057 if (aggregate->aspath)
8058 aspath = aspath_dup(aggregate->aspath);
8059
8060 /* Retrieve aggregate route's community.
8061 */
8062 if (aggregate->community)
8063 community = community_dup(aggregate->community);
8064
8065 /* Retrieve aggregate route's ecommunity.
8066 */
8067 if (aggregate->ecommunity)
8068 ecommunity = ecommunity_dup(aggregate->ecommunity);
8069
8070 /* Retrieve aggregate route's lcommunity.
8071 */
8072 if (aggregate->lcommunity)
8073 lcommunity = lcommunity_dup(aggregate->lcommunity);
8074 }
8075
8076 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8077 aspath, community, ecommunity,
8078 lcommunity, atomic_aggregate, aggregate);
8079 }
8080
8081 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8082 safi_t safi,
8083 struct bgp_path_info *pi,
8084 struct bgp_aggregate *aggregate,
8085 const struct prefix *aggr_p)
8086 {
8087 uint8_t origin;
8088 struct aspath *aspath = NULL;
8089 uint8_t atomic_aggregate = 0;
8090 struct community *community = NULL;
8091 struct ecommunity *ecommunity = NULL;
8092 struct lcommunity *lcommunity = NULL;
8093 unsigned long match = 0;
8094
8095 /* If the bgp instance is being deleted or self peer is deleted
8096 * then do not create aggregate route
8097 */
8098 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8099 || (bgp->peer_self == NULL))
8100 return;
8101
8102 if (BGP_PATH_HOLDDOWN(pi))
8103 return;
8104
8105 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8106 return;
8107
8108 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8109 if (aggr_unsuppress_path(aggregate, pi))
8110 match++;
8111
8112 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8113 && aggr_suppress_map_test(bgp, aggregate, pi))
8114 if (aggr_unsuppress_path(aggregate, pi))
8115 match++;
8116
8117 /*
8118 * This must be called after `summary`, `suppress-map` check to avoid
8119 * "unsuppressing" twice.
8120 */
8121 if (aggregate->match_med)
8122 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8123
8124 if (aggregate->count > 0)
8125 aggregate->count--;
8126
8127 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8128 aggregate->incomplete_origin_count--;
8129 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8130 aggregate->egp_origin_count--;
8131
8132 if (aggregate->as_set) {
8133 /* Remove as-path from aggregate.
8134 */
8135 bgp_remove_aspath_from_aggregate(aggregate,
8136 pi->attr->aspath);
8137
8138 if (bgp_attr_get_community(pi->attr))
8139 /* Remove community from aggregate.
8140 */
8141 bgp_remove_community_from_aggregate(
8142 aggregate, bgp_attr_get_community(pi->attr));
8143
8144 if (bgp_attr_get_ecommunity(pi->attr))
8145 /* Remove ecommunity from aggregate.
8146 */
8147 bgp_remove_ecommunity_from_aggregate(
8148 aggregate, bgp_attr_get_ecommunity(pi->attr));
8149
8150 if (bgp_attr_get_lcommunity(pi->attr))
8151 /* Remove lcommunity from aggregate.
8152 */
8153 bgp_remove_lcommunity_from_aggregate(
8154 aggregate, bgp_attr_get_lcommunity(pi->attr));
8155 }
8156
8157 /* If this node was suppressed, process the change. */
8158 if (match)
8159 bgp_process(bgp, pi->net, afi, safi);
8160
8161 origin = BGP_ORIGIN_IGP;
8162 if (aggregate->incomplete_origin_count > 0)
8163 origin = BGP_ORIGIN_INCOMPLETE;
8164 else if (aggregate->egp_origin_count > 0)
8165 origin = BGP_ORIGIN_EGP;
8166
8167 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8168 origin = aggregate->origin;
8169
8170 if (aggregate->as_set) {
8171 /* Retrieve aggregate route's as-path.
8172 */
8173 if (aggregate->aspath)
8174 aspath = aspath_dup(aggregate->aspath);
8175
8176 /* Retrieve aggregate route's community.
8177 */
8178 if (aggregate->community)
8179 community = community_dup(aggregate->community);
8180
8181 /* Retrieve aggregate route's ecommunity.
8182 */
8183 if (aggregate->ecommunity)
8184 ecommunity = ecommunity_dup(aggregate->ecommunity);
8185
8186 /* Retrieve aggregate route's lcommunity.
8187 */
8188 if (aggregate->lcommunity)
8189 lcommunity = lcommunity_dup(aggregate->lcommunity);
8190 }
8191
8192 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8193 aspath, community, ecommunity,
8194 lcommunity, atomic_aggregate, aggregate);
8195 }
8196
8197 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8198 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8199 {
8200 struct bgp_dest *child;
8201 struct bgp_dest *dest;
8202 struct bgp_aggregate *aggregate;
8203 struct bgp_table *table;
8204
8205 table = bgp->aggregate[afi][safi];
8206
8207 /* No aggregates configured. */
8208 if (bgp_table_top_nolock(table) == NULL)
8209 return;
8210
8211 if (p->prefixlen == 0)
8212 return;
8213
8214 if (BGP_PATH_HOLDDOWN(pi))
8215 return;
8216
8217 /* If suppress fib is enabled and route not installed
8218 * in FIB, do not update the aggregate route
8219 */
8220 if (!bgp_check_advertise(bgp, pi->net))
8221 return;
8222
8223 child = bgp_node_get(table, p);
8224
8225 /* Aggregate address configuration check. */
8226 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8227 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8228
8229 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8230 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8231 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8232 aggregate);
8233 }
8234 }
8235 bgp_dest_unlock_node(child);
8236 }
8237
8238 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8239 struct bgp_path_info *del, afi_t afi, safi_t safi)
8240 {
8241 struct bgp_dest *child;
8242 struct bgp_dest *dest;
8243 struct bgp_aggregate *aggregate;
8244 struct bgp_table *table;
8245
8246 table = bgp->aggregate[afi][safi];
8247
8248 /* No aggregates configured. */
8249 if (bgp_table_top_nolock(table) == NULL)
8250 return;
8251
8252 if (p->prefixlen == 0)
8253 return;
8254
8255 child = bgp_node_get(table, p);
8256
8257 /* Aggregate address configuration check. */
8258 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8259 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8260
8261 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8262 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8263 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8264 aggregate, dest_p);
8265 }
8266 }
8267 bgp_dest_unlock_node(child);
8268 }
8269
8270 /* Aggregate route attribute. */
8271 #define AGGREGATE_SUMMARY_ONLY 1
8272 #define AGGREGATE_AS_SET 1
8273 #define AGGREGATE_AS_UNSET 0
8274
8275 static const char *bgp_origin2str(uint8_t origin)
8276 {
8277 switch (origin) {
8278 case BGP_ORIGIN_IGP:
8279 return "igp";
8280 case BGP_ORIGIN_EGP:
8281 return "egp";
8282 case BGP_ORIGIN_INCOMPLETE:
8283 return "incomplete";
8284 }
8285 return "n/a";
8286 }
8287
8288 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8289 {
8290 switch (v_state) {
8291 case RPKI_NOT_BEING_USED:
8292 return "not used";
8293 case RPKI_VALID:
8294 return "valid";
8295 case RPKI_NOTFOUND:
8296 return "not found";
8297 case RPKI_INVALID:
8298 return "invalid";
8299 }
8300
8301 assert(!"We should never get here this is a dev escape");
8302 return "ERROR";
8303 }
8304
8305 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8306 afi_t afi, safi_t safi)
8307 {
8308 VTY_DECLVAR_CONTEXT(bgp, bgp);
8309 int ret;
8310 struct prefix p;
8311 struct bgp_dest *dest;
8312 struct bgp_aggregate *aggregate;
8313
8314 /* Convert string to prefix structure. */
8315 ret = str2prefix(prefix_str, &p);
8316 if (!ret) {
8317 vty_out(vty, "Malformed prefix\n");
8318 return CMD_WARNING_CONFIG_FAILED;
8319 }
8320 apply_mask(&p);
8321
8322 /* Old configuration check. */
8323 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8324 if (!dest) {
8325 vty_out(vty,
8326 "%% There is no aggregate-address configuration.\n");
8327 return CMD_WARNING_CONFIG_FAILED;
8328 }
8329
8330 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8331 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8332 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8333 NULL, NULL, 0, aggregate);
8334
8335 /* Unlock aggregate address configuration. */
8336 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8337
8338 if (aggregate->community)
8339 community_free(&aggregate->community);
8340
8341 hash_clean_and_free(&aggregate->community_hash,
8342 bgp_aggr_community_remove);
8343
8344 if (aggregate->ecommunity)
8345 ecommunity_free(&aggregate->ecommunity);
8346
8347 hash_clean_and_free(&aggregate->ecommunity_hash,
8348 bgp_aggr_ecommunity_remove);
8349
8350 if (aggregate->lcommunity)
8351 lcommunity_free(&aggregate->lcommunity);
8352
8353 hash_clean_and_free(&aggregate->lcommunity_hash,
8354 bgp_aggr_lcommunity_remove);
8355
8356 if (aggregate->aspath)
8357 aspath_free(aggregate->aspath);
8358
8359 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8360
8361 bgp_aggregate_free(aggregate);
8362 bgp_dest_unlock_node(dest);
8363 bgp_dest_unlock_node(dest);
8364
8365 return CMD_SUCCESS;
8366 }
8367
8368 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8369 safi_t safi, const char *rmap,
8370 uint8_t summary_only, uint8_t as_set,
8371 uint8_t origin, bool match_med,
8372 const char *suppress_map)
8373 {
8374 VTY_DECLVAR_CONTEXT(bgp, bgp);
8375 int ret;
8376 struct prefix p;
8377 struct bgp_dest *dest;
8378 struct bgp_aggregate *aggregate;
8379 uint8_t as_set_new = as_set;
8380
8381 if (suppress_map && summary_only) {
8382 vty_out(vty,
8383 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8384 return CMD_WARNING_CONFIG_FAILED;
8385 }
8386
8387 /* Convert string to prefix structure. */
8388 ret = str2prefix(prefix_str, &p);
8389 if (!ret) {
8390 vty_out(vty, "Malformed prefix\n");
8391 return CMD_WARNING_CONFIG_FAILED;
8392 }
8393 apply_mask(&p);
8394
8395 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8396 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8397 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8398 prefix_str);
8399 return CMD_WARNING_CONFIG_FAILED;
8400 }
8401
8402 /* Old configuration check. */
8403 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8404 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8405
8406 if (aggregate) {
8407 vty_out(vty, "There is already same aggregate network.\n");
8408 /* try to remove the old entry */
8409 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8410 if (ret) {
8411 vty_out(vty, "Error deleting aggregate.\n");
8412 bgp_dest_unlock_node(dest);
8413 return CMD_WARNING_CONFIG_FAILED;
8414 }
8415 }
8416
8417 /* Make aggregate address structure. */
8418 aggregate = bgp_aggregate_new();
8419 aggregate->summary_only = summary_only;
8420 aggregate->match_med = match_med;
8421
8422 /* Network operators MUST NOT locally generate any new
8423 * announcements containing AS_SET or AS_CONFED_SET. If they have
8424 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8425 * SHOULD withdraw those routes and re-announce routes for the
8426 * aggregate or component prefixes (i.e., the more-specific routes
8427 * subsumed by the previously aggregated route) without AS_SET
8428 * or AS_CONFED_SET in the updates.
8429 */
8430 if (bgp->reject_as_sets) {
8431 if (as_set == AGGREGATE_AS_SET) {
8432 as_set_new = AGGREGATE_AS_UNSET;
8433 zlog_warn(
8434 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8435 __func__);
8436 vty_out(vty,
8437 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8438 }
8439 }
8440
8441 aggregate->as_set = as_set_new;
8442 aggregate->safi = safi;
8443 /* Override ORIGIN attribute if defined.
8444 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8445 * to IGP which is not what rfc4271 says.
8446 * This enables the same behavior, optionally.
8447 */
8448 aggregate->origin = origin;
8449
8450 if (rmap) {
8451 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8452 route_map_counter_decrement(aggregate->rmap.map);
8453 aggregate->rmap.name =
8454 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8455 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8456 route_map_counter_increment(aggregate->rmap.map);
8457 }
8458
8459 if (suppress_map) {
8460 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8461 route_map_counter_decrement(aggregate->suppress_map);
8462
8463 aggregate->suppress_map_name =
8464 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8465 aggregate->suppress_map =
8466 route_map_lookup_by_name(aggregate->suppress_map_name);
8467 route_map_counter_increment(aggregate->suppress_map);
8468 }
8469
8470 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8471
8472 /* Aggregate address insert into BGP routing table. */
8473 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8474 bgp_aggregate_free(aggregate);
8475 bgp_dest_unlock_node(dest);
8476 }
8477
8478 return CMD_SUCCESS;
8479 }
8480
8481 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8482 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8483 "as-set$as_set_s"
8484 "|summary-only$summary_only"
8485 "|route-map RMAP_NAME$rmap_name"
8486 "|origin <egp|igp|incomplete>$origin_s"
8487 "|matching-MED-only$match_med"
8488 "|suppress-map RMAP_NAME$suppress_map"
8489 "}]",
8490 NO_STR
8491 "Configure BGP aggregate entries\n"
8492 "Aggregate prefix\n"
8493 "Aggregate address\n"
8494 "Aggregate mask\n"
8495 "Generate AS set path information\n"
8496 "Filter more specific routes from updates\n"
8497 "Apply route map to aggregate network\n"
8498 "Route map name\n"
8499 "BGP origin code\n"
8500 "Remote EGP\n"
8501 "Local IGP\n"
8502 "Unknown heritage\n"
8503 "Only aggregate routes with matching MED\n"
8504 "Suppress the selected more specific routes\n"
8505 "Route map with the route selectors\n")
8506 {
8507 const char *prefix_s = NULL;
8508 safi_t safi = bgp_node_safi(vty);
8509 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8510 int as_set = AGGREGATE_AS_UNSET;
8511 char prefix_buf[PREFIX2STR_BUFFER];
8512
8513 if (addr_str) {
8514 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8515 sizeof(prefix_buf))
8516 == 0) {
8517 vty_out(vty, "%% Inconsistent address and mask\n");
8518 return CMD_WARNING_CONFIG_FAILED;
8519 }
8520 prefix_s = prefix_buf;
8521 } else
8522 prefix_s = prefix_str;
8523
8524 if (origin_s) {
8525 if (strcmp(origin_s, "egp") == 0)
8526 origin = BGP_ORIGIN_EGP;
8527 else if (strcmp(origin_s, "igp") == 0)
8528 origin = BGP_ORIGIN_IGP;
8529 else if (strcmp(origin_s, "incomplete") == 0)
8530 origin = BGP_ORIGIN_INCOMPLETE;
8531 }
8532
8533 if (as_set_s)
8534 as_set = AGGREGATE_AS_SET;
8535
8536 /* Handle configuration removal, otherwise installation. */
8537 if (no)
8538 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8539
8540 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8541 summary_only != NULL, as_set, origin,
8542 match_med != NULL, suppress_map);
8543 }
8544
8545 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8546 "[no] aggregate-address X:X::X:X/M$prefix [{"
8547 "as-set$as_set_s"
8548 "|summary-only$summary_only"
8549 "|route-map RMAP_NAME$rmap_name"
8550 "|origin <egp|igp|incomplete>$origin_s"
8551 "|matching-MED-only$match_med"
8552 "|suppress-map RMAP_NAME$suppress_map"
8553 "}]",
8554 NO_STR
8555 "Configure BGP aggregate entries\n"
8556 "Aggregate prefix\n"
8557 "Generate AS set path information\n"
8558 "Filter more specific routes from updates\n"
8559 "Apply route map to aggregate network\n"
8560 "Route map name\n"
8561 "BGP origin code\n"
8562 "Remote EGP\n"
8563 "Local IGP\n"
8564 "Unknown heritage\n"
8565 "Only aggregate routes with matching MED\n"
8566 "Suppress the selected more specific routes\n"
8567 "Route map with the route selectors\n")
8568 {
8569 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8570 int as_set = AGGREGATE_AS_UNSET;
8571
8572 if (origin_s) {
8573 if (strcmp(origin_s, "egp") == 0)
8574 origin = BGP_ORIGIN_EGP;
8575 else if (strcmp(origin_s, "igp") == 0)
8576 origin = BGP_ORIGIN_IGP;
8577 else if (strcmp(origin_s, "incomplete") == 0)
8578 origin = BGP_ORIGIN_INCOMPLETE;
8579 }
8580
8581 if (as_set_s)
8582 as_set = AGGREGATE_AS_SET;
8583
8584 /* Handle configuration removal, otherwise installation. */
8585 if (no)
8586 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8587 SAFI_UNICAST);
8588
8589 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8590 rmap_name, summary_only != NULL, as_set,
8591 origin, match_med != NULL, suppress_map);
8592 }
8593
8594 /* Redistribute route treatment. */
8595 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8596 const union g_addr *nexthop, ifindex_t ifindex,
8597 enum nexthop_types_t nhtype, uint8_t distance,
8598 enum blackhole_type bhtype, uint32_t metric,
8599 uint8_t type, unsigned short instance,
8600 route_tag_t tag)
8601 {
8602 struct bgp_path_info *new;
8603 struct bgp_path_info *bpi;
8604 struct bgp_path_info rmap_path;
8605 struct bgp_dest *bn;
8606 struct attr attr;
8607 struct attr *new_attr;
8608 afi_t afi;
8609 route_map_result_t ret;
8610 struct bgp_redist *red;
8611
8612 /* Make default attribute. */
8613 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8614 /*
8615 * This must not be NULL to satisfy Coverity SA
8616 */
8617 assert(attr.aspath);
8618
8619 switch (nhtype) {
8620 case NEXTHOP_TYPE_IFINDEX:
8621 switch (p->family) {
8622 case AF_INET:
8623 attr.nexthop.s_addr = INADDR_ANY;
8624 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8625 break;
8626 case AF_INET6:
8627 memset(&attr.mp_nexthop_global, 0,
8628 sizeof(attr.mp_nexthop_global));
8629 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8630 break;
8631 }
8632 break;
8633 case NEXTHOP_TYPE_IPV4:
8634 case NEXTHOP_TYPE_IPV4_IFINDEX:
8635 attr.nexthop = nexthop->ipv4;
8636 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8637 break;
8638 case NEXTHOP_TYPE_IPV6:
8639 case NEXTHOP_TYPE_IPV6_IFINDEX:
8640 attr.mp_nexthop_global = nexthop->ipv6;
8641 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8642 break;
8643 case NEXTHOP_TYPE_BLACKHOLE:
8644 switch (p->family) {
8645 case AF_INET:
8646 attr.nexthop.s_addr = INADDR_ANY;
8647 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8648 break;
8649 case AF_INET6:
8650 memset(&attr.mp_nexthop_global, 0,
8651 sizeof(attr.mp_nexthop_global));
8652 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8653 break;
8654 }
8655 attr.bh_type = bhtype;
8656 break;
8657 }
8658 attr.nh_type = nhtype;
8659 attr.nh_ifindex = ifindex;
8660
8661 attr.med = metric;
8662 attr.distance = distance;
8663 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8664 attr.tag = tag;
8665
8666 if (metric)
8667 bgp_attr_set_aigp_metric(&attr, metric);
8668
8669 afi = family2afi(p->family);
8670
8671 red = bgp_redist_lookup(bgp, afi, type, instance);
8672 if (red) {
8673 struct attr attr_new;
8674
8675 /* Copy attribute for modification. */
8676 attr_new = attr;
8677
8678 if (red->redist_metric_flag) {
8679 attr_new.med = red->redist_metric;
8680 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8681 }
8682
8683 /* Apply route-map. */
8684 if (red->rmap.name) {
8685 memset(&rmap_path, 0, sizeof(rmap_path));
8686 rmap_path.peer = bgp->peer_self;
8687 rmap_path.attr = &attr_new;
8688
8689 SET_FLAG(bgp->peer_self->rmap_type,
8690 PEER_RMAP_TYPE_REDISTRIBUTE);
8691
8692 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8693
8694 bgp->peer_self->rmap_type = 0;
8695
8696 if (ret == RMAP_DENYMATCH) {
8697 /* Free uninterned attribute. */
8698 bgp_attr_flush(&attr_new);
8699
8700 /* Unintern original. */
8701 aspath_unintern(&attr.aspath);
8702 bgp_redistribute_delete(bgp, p, type, instance);
8703 return;
8704 }
8705 }
8706
8707 if (bgp_in_graceful_shutdown(bgp))
8708 bgp_attr_add_gshut_community(&attr_new);
8709
8710 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8711 SAFI_UNICAST, p, NULL);
8712
8713 new_attr = bgp_attr_intern(&attr_new);
8714
8715 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8716 if (bpi->peer == bgp->peer_self
8717 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8718 break;
8719
8720 if (bpi) {
8721 /* Ensure the (source route) type is updated. */
8722 bpi->type = type;
8723 if (attrhash_cmp(bpi->attr, new_attr)
8724 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8725 bgp_attr_unintern(&new_attr);
8726 aspath_unintern(&attr.aspath);
8727 bgp_dest_unlock_node(bn);
8728 return;
8729 } else {
8730 /* The attribute is changed. */
8731 bgp_path_info_set_flag(bn, bpi,
8732 BGP_PATH_ATTR_CHANGED);
8733
8734 /* Rewrite BGP route information. */
8735 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8736 bgp_path_info_restore(bn, bpi);
8737 else
8738 bgp_aggregate_decrement(
8739 bgp, p, bpi, afi, SAFI_UNICAST);
8740 bgp_attr_unintern(&bpi->attr);
8741 bpi->attr = new_attr;
8742 bpi->uptime = monotime(NULL);
8743
8744 /* Process change. */
8745 bgp_aggregate_increment(bgp, p, bpi, afi,
8746 SAFI_UNICAST);
8747 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8748 bgp_dest_unlock_node(bn);
8749 aspath_unintern(&attr.aspath);
8750
8751 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8752 || (bgp->inst_type
8753 == BGP_INSTANCE_TYPE_DEFAULT)) {
8754
8755 vpn_leak_from_vrf_update(
8756 bgp_get_default(), bgp, bpi);
8757 }
8758 return;
8759 }
8760 }
8761
8762 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8763 bgp->peer_self, new_attr, bn);
8764 SET_FLAG(new->flags, BGP_PATH_VALID);
8765
8766 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8767 bgp_path_info_add(bn, new);
8768 bgp_dest_unlock_node(bn);
8769 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8770 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8771
8772 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8773 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8774
8775 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8776 }
8777 }
8778
8779 /* Unintern original. */
8780 aspath_unintern(&attr.aspath);
8781 }
8782
8783 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8784 unsigned short instance)
8785 {
8786 afi_t afi;
8787 struct bgp_dest *dest;
8788 struct bgp_path_info *pi;
8789 struct bgp_redist *red;
8790
8791 afi = family2afi(p->family);
8792
8793 red = bgp_redist_lookup(bgp, afi, type, instance);
8794 if (red) {
8795 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8796 SAFI_UNICAST, p, NULL);
8797
8798 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8799 if (pi->peer == bgp->peer_self && pi->type == type)
8800 break;
8801
8802 if (pi) {
8803 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8804 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8805
8806 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8807 bgp, pi);
8808 }
8809 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8810 bgp_path_info_delete(dest, pi);
8811 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8812 }
8813 bgp_dest_unlock_node(dest);
8814 }
8815 }
8816
8817 /* Withdraw specified route type's route. */
8818 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8819 unsigned short instance)
8820 {
8821 struct bgp_dest *dest;
8822 struct bgp_path_info *pi;
8823 struct bgp_table *table;
8824
8825 table = bgp->rib[afi][SAFI_UNICAST];
8826
8827 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8828 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8829 if (pi->peer == bgp->peer_self && pi->type == type
8830 && pi->instance == instance)
8831 break;
8832
8833 if (pi) {
8834 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8835 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8836
8837 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8838 bgp, pi);
8839 }
8840 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8841 pi, afi, SAFI_UNICAST);
8842 bgp_path_info_delete(dest, pi);
8843 if (!CHECK_FLAG(bgp->flags,
8844 BGP_FLAG_DELETE_IN_PROGRESS))
8845 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8846 else
8847 bgp_path_info_reap(dest, pi);
8848 }
8849 }
8850 }
8851
8852 /* Static function to display route. */
8853 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8854 struct vty *vty, json_object *json, bool wide)
8855 {
8856 int len = 0;
8857 char buf[INET6_ADDRSTRLEN];
8858
8859 if (p->family == AF_INET) {
8860 if (!json) {
8861 len = vty_out(vty, "%pFX", p);
8862 } else {
8863 json_object_string_add(json, "prefix",
8864 inet_ntop(p->family,
8865 &p->u.prefix, buf,
8866 sizeof(buf)));
8867 json_object_int_add(json, "prefixLen", p->prefixlen);
8868 json_object_string_addf(json, "network", "%pFX", p);
8869 json_object_int_add(json, "version", dest->version);
8870 }
8871 } else if (p->family == AF_ETHERNET) {
8872 len = vty_out(vty, "%pFX", p);
8873 } else if (p->family == AF_EVPN) {
8874 if (!json)
8875 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8876 else
8877 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8878 } else if (p->family == AF_FLOWSPEC) {
8879 route_vty_out_flowspec(vty, p, NULL,
8880 json ?
8881 NLRI_STRING_FORMAT_JSON_SIMPLE :
8882 NLRI_STRING_FORMAT_MIN, json);
8883 } else {
8884 if (!json)
8885 len = vty_out(vty, "%pFX", p);
8886 else {
8887 json_object_string_add(json, "prefix",
8888 inet_ntop(p->family,
8889 &p->u.prefix, buf,
8890 sizeof(buf)));
8891 json_object_int_add(json, "prefixLen", p->prefixlen);
8892 json_object_string_addf(json, "network", "%pFX", p);
8893 json_object_int_add(json, "version", dest->version);
8894 }
8895 }
8896
8897 if (!json) {
8898 len = wide ? (45 - len) : (17 - len);
8899 if (len < 1)
8900 vty_out(vty, "\n%*s", 20, " ");
8901 else
8902 vty_out(vty, "%*s", len, " ");
8903 }
8904 }
8905
8906 enum bgp_display_type {
8907 normal_list,
8908 };
8909
8910 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8911 {
8912 switch (reason) {
8913 case bgp_path_selection_none:
8914 return "Nothing to Select";
8915 case bgp_path_selection_first:
8916 return "First path received";
8917 case bgp_path_selection_evpn_sticky_mac:
8918 return "EVPN Sticky Mac";
8919 case bgp_path_selection_evpn_seq:
8920 return "EVPN sequence number";
8921 case bgp_path_selection_evpn_lower_ip:
8922 return "EVPN lower IP";
8923 case bgp_path_selection_evpn_local_path:
8924 return "EVPN local ES path";
8925 case bgp_path_selection_evpn_non_proxy:
8926 return "EVPN non proxy";
8927 case bgp_path_selection_weight:
8928 return "Weight";
8929 case bgp_path_selection_local_pref:
8930 return "Local Pref";
8931 case bgp_path_selection_accept_own:
8932 return "Accept Own";
8933 case bgp_path_selection_local_route:
8934 return "Local Route";
8935 case bgp_path_selection_aigp:
8936 return "AIGP";
8937 case bgp_path_selection_confed_as_path:
8938 return "Confederation based AS Path";
8939 case bgp_path_selection_as_path:
8940 return "AS Path";
8941 case bgp_path_selection_origin:
8942 return "Origin";
8943 case bgp_path_selection_med:
8944 return "MED";
8945 case bgp_path_selection_peer:
8946 return "Peer Type";
8947 case bgp_path_selection_confed:
8948 return "Confed Peer Type";
8949 case bgp_path_selection_igp_metric:
8950 return "IGP Metric";
8951 case bgp_path_selection_older:
8952 return "Older Path";
8953 case bgp_path_selection_router_id:
8954 return "Router ID";
8955 case bgp_path_selection_cluster_length:
8956 return "Cluster length";
8957 case bgp_path_selection_stale:
8958 return "Path Staleness";
8959 case bgp_path_selection_local_configured:
8960 return "Locally configured route";
8961 case bgp_path_selection_neighbor_ip:
8962 return "Neighbor IP";
8963 case bgp_path_selection_default:
8964 return "Nothing left to compare";
8965 }
8966 return "Invalid (internal error)";
8967 }
8968
8969 /* Print the short form route status for a bgp_path_info */
8970 static void route_vty_short_status_out(struct vty *vty,
8971 struct bgp_path_info *path,
8972 const struct prefix *p,
8973 json_object *json_path)
8974 {
8975 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8976
8977 if (json_path) {
8978
8979 /* Route status display. */
8980 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8981 json_object_boolean_true_add(json_path, "removed");
8982
8983 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8984 json_object_boolean_true_add(json_path, "stale");
8985
8986 if (path->extra && bgp_path_suppressed(path))
8987 json_object_boolean_true_add(json_path, "suppressed");
8988
8989 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8990 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8991 json_object_boolean_true_add(json_path, "valid");
8992
8993 /* Selected */
8994 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8995 json_object_boolean_true_add(json_path, "history");
8996
8997 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8998 json_object_boolean_true_add(json_path, "damped");
8999
9000 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9001 json_object_boolean_true_add(json_path, "bestpath");
9002 json_object_string_add(json_path, "selectionReason",
9003 bgp_path_selection_reason2str(
9004 path->net->reason));
9005 }
9006
9007 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9008 json_object_boolean_true_add(json_path, "multipath");
9009
9010 /* Internal route. */
9011 if ((path->peer->as)
9012 && (path->peer->as == path->peer->local_as))
9013 json_object_string_add(json_path, "pathFrom",
9014 "internal");
9015 else
9016 json_object_string_add(json_path, "pathFrom",
9017 "external");
9018
9019 return;
9020 }
9021
9022 /* RPKI validation state */
9023 rpki_state =
9024 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9025
9026 if (rpki_state == RPKI_VALID)
9027 vty_out(vty, "V");
9028 else if (rpki_state == RPKI_INVALID)
9029 vty_out(vty, "I");
9030 else if (rpki_state == RPKI_NOTFOUND)
9031 vty_out(vty, "N");
9032 else
9033 vty_out(vty, " ");
9034
9035 /* Route status display. */
9036 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9037 vty_out(vty, "R");
9038 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9039 vty_out(vty, "S");
9040 else if (bgp_path_suppressed(path))
9041 vty_out(vty, "s");
9042 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9043 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9044 vty_out(vty, "*");
9045 else
9046 vty_out(vty, " ");
9047
9048 /* Selected */
9049 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9050 vty_out(vty, "h");
9051 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9052 vty_out(vty, "d");
9053 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9054 vty_out(vty, ">");
9055 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9056 vty_out(vty, "=");
9057 else
9058 vty_out(vty, " ");
9059
9060 /* Internal route. */
9061 if (path->peer && (path->peer->as)
9062 && (path->peer->as == path->peer->local_as))
9063 vty_out(vty, "i");
9064 else
9065 vty_out(vty, " ");
9066 }
9067
9068 static char *bgp_nexthop_hostname(struct peer *peer,
9069 struct bgp_nexthop_cache *bnc)
9070 {
9071 if (peer->hostname
9072 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9073 return peer->hostname;
9074 return NULL;
9075 }
9076
9077 /* called from terminal list command */
9078 void route_vty_out(struct vty *vty, const struct prefix *p,
9079 struct bgp_path_info *path, int display, safi_t safi,
9080 json_object *json_paths, bool wide)
9081 {
9082 int len;
9083 struct attr *attr = path->attr;
9084 json_object *json_path = NULL;
9085 json_object *json_nexthops = NULL;
9086 json_object *json_nexthop_global = NULL;
9087 json_object *json_nexthop_ll = NULL;
9088 json_object *json_ext_community = NULL;
9089 char vrf_id_str[VRF_NAMSIZ] = {0};
9090 bool nexthop_self =
9091 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9092 bool nexthop_othervrf = false;
9093 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9094 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9095 char *nexthop_hostname =
9096 bgp_nexthop_hostname(path->peer, path->nexthop);
9097 char esi_buf[ESI_STR_LEN];
9098
9099 if (json_paths)
9100 json_path = json_object_new_object();
9101
9102 /* short status lead text */
9103 route_vty_short_status_out(vty, path, p, json_path);
9104
9105 if (!json_paths) {
9106 /* print prefix and mask */
9107 if (!display)
9108 route_vty_out_route(path->net, p, vty, json_path, wide);
9109 else
9110 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9111 } else {
9112 route_vty_out_route(path->net, p, vty, json_path, wide);
9113 }
9114
9115 /*
9116 * If vrf id of nexthop is different from that of prefix,
9117 * set up printable string to append
9118 */
9119 if (path->extra && path->extra->bgp_orig) {
9120 const char *self = "";
9121
9122 if (nexthop_self)
9123 self = "<";
9124
9125 nexthop_othervrf = true;
9126 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9127
9128 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9129 snprintf(vrf_id_str, sizeof(vrf_id_str),
9130 "@%s%s", VRFID_NONE_STR, self);
9131 else
9132 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9133 path->extra->bgp_orig->vrf_id, self);
9134
9135 if (path->extra->bgp_orig->inst_type
9136 != BGP_INSTANCE_TYPE_DEFAULT)
9137
9138 nexthop_vrfname = path->extra->bgp_orig->name;
9139 } else {
9140 const char *self = "";
9141
9142 if (nexthop_self)
9143 self = "<";
9144
9145 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9146 }
9147
9148 /*
9149 * For ENCAP and EVPN routes, nexthop address family is not
9150 * neccessarily the same as the prefix address family.
9151 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9152 * EVPN routes are also exchanged with a MP nexthop. Currently,
9153 * this
9154 * is only IPv4, the value will be present in either
9155 * attr->nexthop or
9156 * attr->mp_nexthop_global_in
9157 */
9158 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9159 char nexthop[128];
9160 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9161
9162 switch (af) {
9163 case AF_INET:
9164 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9165 &attr->mp_nexthop_global_in);
9166 break;
9167 case AF_INET6:
9168 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9169 &attr->mp_nexthop_global);
9170 break;
9171 default:
9172 snprintf(nexthop, sizeof(nexthop), "?");
9173 break;
9174 }
9175
9176 if (json_paths) {
9177 json_nexthop_global = json_object_new_object();
9178
9179 json_object_string_add(json_nexthop_global, "ip",
9180 nexthop);
9181
9182 if (path->peer->hostname)
9183 json_object_string_add(json_nexthop_global,
9184 "hostname",
9185 path->peer->hostname);
9186
9187 json_object_string_add(json_nexthop_global, "afi",
9188 (af == AF_INET) ? "ipv4"
9189 : "ipv6");
9190 json_object_boolean_true_add(json_nexthop_global,
9191 "used");
9192 } else {
9193 if (nexthop_hostname)
9194 len = vty_out(vty, "%s(%s)%s", nexthop,
9195 nexthop_hostname, vrf_id_str);
9196 else
9197 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9198
9199 len = wide ? (41 - len) : (16 - len);
9200 if (len < 1)
9201 vty_out(vty, "\n%*s", 36, " ");
9202 else
9203 vty_out(vty, "%*s", len, " ");
9204 }
9205 } else if (safi == SAFI_EVPN) {
9206 if (json_paths) {
9207 json_nexthop_global = json_object_new_object();
9208
9209 json_object_string_addf(json_nexthop_global, "ip",
9210 "%pI4",
9211 &attr->mp_nexthop_global_in);
9212
9213 if (path->peer->hostname)
9214 json_object_string_add(json_nexthop_global,
9215 "hostname",
9216 path->peer->hostname);
9217
9218 json_object_string_add(json_nexthop_global, "afi",
9219 "ipv4");
9220 json_object_boolean_true_add(json_nexthop_global,
9221 "used");
9222 } else {
9223 if (nexthop_hostname)
9224 len = vty_out(vty, "%pI4(%s)%s",
9225 &attr->mp_nexthop_global_in,
9226 nexthop_hostname, vrf_id_str);
9227 else
9228 len = vty_out(vty, "%pI4%s",
9229 &attr->mp_nexthop_global_in,
9230 vrf_id_str);
9231
9232 len = wide ? (41 - len) : (16 - len);
9233 if (len < 1)
9234 vty_out(vty, "\n%*s", 36, " ");
9235 else
9236 vty_out(vty, "%*s", len, " ");
9237 }
9238 } else if (safi == SAFI_FLOWSPEC) {
9239 if (attr->nexthop.s_addr != INADDR_ANY) {
9240 if (json_paths) {
9241 json_nexthop_global = json_object_new_object();
9242
9243 json_object_string_add(json_nexthop_global,
9244 "afi", "ipv4");
9245 json_object_string_addf(json_nexthop_global,
9246 "ip", "%pI4",
9247 &attr->nexthop);
9248
9249 if (path->peer->hostname)
9250 json_object_string_add(
9251 json_nexthop_global, "hostname",
9252 path->peer->hostname);
9253
9254 json_object_boolean_true_add(
9255 json_nexthop_global,
9256 "used");
9257 } else {
9258 if (nexthop_hostname)
9259 len = vty_out(vty, "%pI4(%s)%s",
9260 &attr->nexthop,
9261 nexthop_hostname,
9262 vrf_id_str);
9263 else
9264 len = vty_out(vty, "%pI4%s",
9265 &attr->nexthop,
9266 vrf_id_str);
9267
9268 len = wide ? (41 - len) : (16 - len);
9269 if (len < 1)
9270 vty_out(vty, "\n%*s", 36, " ");
9271 else
9272 vty_out(vty, "%*s", len, " ");
9273 }
9274 }
9275 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9276 if (json_paths) {
9277 json_nexthop_global = json_object_new_object();
9278
9279 json_object_string_addf(json_nexthop_global, "ip",
9280 "%pI4", &attr->nexthop);
9281
9282 if (path->peer->hostname)
9283 json_object_string_add(json_nexthop_global,
9284 "hostname",
9285 path->peer->hostname);
9286
9287 json_object_string_add(json_nexthop_global, "afi",
9288 "ipv4");
9289 json_object_boolean_true_add(json_nexthop_global,
9290 "used");
9291 } else {
9292 if (nexthop_hostname)
9293 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9294 nexthop_hostname, vrf_id_str);
9295 else
9296 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9297 vrf_id_str);
9298
9299 len = wide ? (41 - len) : (16 - len);
9300 if (len < 1)
9301 vty_out(vty, "\n%*s", 36, " ");
9302 else
9303 vty_out(vty, "%*s", len, " ");
9304 }
9305 }
9306
9307 /* IPv6 Next Hop */
9308 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9309 if (json_paths) {
9310 json_nexthop_global = json_object_new_object();
9311 json_object_string_addf(json_nexthop_global, "ip",
9312 "%pI6",
9313 &attr->mp_nexthop_global);
9314
9315 if (path->peer->hostname)
9316 json_object_string_add(json_nexthop_global,
9317 "hostname",
9318 path->peer->hostname);
9319
9320 json_object_string_add(json_nexthop_global, "afi",
9321 "ipv6");
9322 json_object_string_add(json_nexthop_global, "scope",
9323 "global");
9324
9325 /* We display both LL & GL if both have been
9326 * received */
9327 if ((attr->mp_nexthop_len
9328 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9329 || (path->peer->conf_if)) {
9330 json_nexthop_ll = json_object_new_object();
9331 json_object_string_addf(
9332 json_nexthop_ll, "ip", "%pI6",
9333 &attr->mp_nexthop_local);
9334
9335 if (path->peer->hostname)
9336 json_object_string_add(
9337 json_nexthop_ll, "hostname",
9338 path->peer->hostname);
9339
9340 json_object_string_add(json_nexthop_ll, "afi",
9341 "ipv6");
9342 json_object_string_add(json_nexthop_ll, "scope",
9343 "link-local");
9344
9345 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9346 &attr->mp_nexthop_local)
9347 != 0)
9348 && !attr->mp_nexthop_prefer_global)
9349 json_object_boolean_true_add(
9350 json_nexthop_ll, "used");
9351 else
9352 json_object_boolean_true_add(
9353 json_nexthop_global, "used");
9354 } else
9355 json_object_boolean_true_add(
9356 json_nexthop_global, "used");
9357 } else {
9358 /* Display LL if LL/Global both in table unless
9359 * prefer-global is set */
9360 if (((attr->mp_nexthop_len
9361 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9362 && !attr->mp_nexthop_prefer_global)
9363 || (path->peer->conf_if)) {
9364 if (path->peer->conf_if) {
9365 len = vty_out(vty, "%s",
9366 path->peer->conf_if);
9367 /* len of IPv6 addr + max len of def
9368 * ifname */
9369 len = wide ? (41 - len) : (16 - len);
9370
9371 if (len < 1)
9372 vty_out(vty, "\n%*s", 36, " ");
9373 else
9374 vty_out(vty, "%*s", len, " ");
9375 } else {
9376 if (nexthop_hostname)
9377 len = vty_out(
9378 vty, "%pI6(%s)%s",
9379 &attr->mp_nexthop_local,
9380 nexthop_hostname,
9381 vrf_id_str);
9382 else
9383 len = vty_out(
9384 vty, "%pI6%s",
9385 &attr->mp_nexthop_local,
9386 vrf_id_str);
9387
9388 len = wide ? (41 - len) : (16 - len);
9389
9390 if (len < 1)
9391 vty_out(vty, "\n%*s", 36, " ");
9392 else
9393 vty_out(vty, "%*s", len, " ");
9394 }
9395 } else {
9396 if (nexthop_hostname)
9397 len = vty_out(vty, "%pI6(%s)%s",
9398 &attr->mp_nexthop_global,
9399 nexthop_hostname,
9400 vrf_id_str);
9401 else
9402 len = vty_out(vty, "%pI6%s",
9403 &attr->mp_nexthop_global,
9404 vrf_id_str);
9405
9406 len = wide ? (41 - len) : (16 - len);
9407
9408 if (len < 1)
9409 vty_out(vty, "\n%*s", 36, " ");
9410 else
9411 vty_out(vty, "%*s", len, " ");
9412 }
9413 }
9414 }
9415
9416 /* MED/Metric */
9417 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9418 if (json_paths)
9419 json_object_int_add(json_path, "metric", attr->med);
9420 else if (wide)
9421 vty_out(vty, "%7u", attr->med);
9422 else
9423 vty_out(vty, "%10u", attr->med);
9424 else if (!json_paths) {
9425 if (wide)
9426 vty_out(vty, "%*s", 7, " ");
9427 else
9428 vty_out(vty, "%*s", 10, " ");
9429 }
9430
9431 /* Local Pref */
9432 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9433 if (json_paths)
9434 json_object_int_add(json_path, "locPrf",
9435 attr->local_pref);
9436 else
9437 vty_out(vty, "%7u", attr->local_pref);
9438 else if (!json_paths)
9439 vty_out(vty, " ");
9440
9441 if (json_paths)
9442 json_object_int_add(json_path, "weight", attr->weight);
9443 else
9444 vty_out(vty, "%7u ", attr->weight);
9445
9446 if (json_paths)
9447 json_object_string_addf(json_path, "peerId", "%pSU",
9448 &path->peer->su);
9449
9450 /* Print aspath */
9451 if (attr->aspath) {
9452 if (json_paths)
9453 json_object_string_add(json_path, "path",
9454 attr->aspath->str);
9455 else
9456 aspath_print_vty(vty, attr->aspath);
9457 }
9458
9459 /* Print origin */
9460 if (json_paths)
9461 json_object_string_add(json_path, "origin",
9462 bgp_origin_long_str[attr->origin]);
9463 else
9464 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9465
9466 if (json_paths) {
9467 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9468 json_object_string_add(json_path, "esi",
9469 esi_to_str(&attr->esi,
9470 esi_buf, sizeof(esi_buf)));
9471 }
9472 if (safi == SAFI_EVPN &&
9473 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9474 json_ext_community = json_object_new_object();
9475 json_object_string_add(
9476 json_ext_community, "string",
9477 bgp_attr_get_ecommunity(attr)->str);
9478 json_object_object_add(json_path,
9479 "extendedCommunity",
9480 json_ext_community);
9481 }
9482
9483 if (nexthop_self)
9484 json_object_boolean_true_add(json_path,
9485 "announceNexthopSelf");
9486 if (nexthop_othervrf) {
9487 json_object_string_add(json_path, "nhVrfName",
9488 nexthop_vrfname);
9489
9490 json_object_int_add(json_path, "nhVrfId",
9491 ((nexthop_vrfid == VRF_UNKNOWN)
9492 ? -1
9493 : (int)nexthop_vrfid));
9494 }
9495 }
9496
9497 if (json_paths) {
9498 if (json_nexthop_global || json_nexthop_ll) {
9499 json_nexthops = json_object_new_array();
9500
9501 if (json_nexthop_global)
9502 json_object_array_add(json_nexthops,
9503 json_nexthop_global);
9504
9505 if (json_nexthop_ll)
9506 json_object_array_add(json_nexthops,
9507 json_nexthop_ll);
9508
9509 json_object_object_add(json_path, "nexthops",
9510 json_nexthops);
9511 }
9512
9513 json_object_array_add(json_paths, json_path);
9514 } else {
9515 vty_out(vty, "\n");
9516
9517 if (safi == SAFI_EVPN) {
9518 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9519 /* XXX - add these params to the json out */
9520 vty_out(vty, "%*s", 20, " ");
9521 vty_out(vty, "ESI:%s",
9522 esi_to_str(&attr->esi, esi_buf,
9523 sizeof(esi_buf)));
9524
9525 vty_out(vty, "\n");
9526 }
9527 if (attr->flag &
9528 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9529 vty_out(vty, "%*s", 20, " ");
9530 vty_out(vty, "%s\n",
9531 bgp_attr_get_ecommunity(attr)->str);
9532 }
9533 }
9534
9535 #ifdef ENABLE_BGP_VNC
9536 /* prints an additional line, indented, with VNC info, if
9537 * present */
9538 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9539 rfapi_vty_out_vncinfo(vty, p, path, safi);
9540 #endif
9541 }
9542 }
9543
9544 /* called from terminal list command */
9545 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9546 const struct prefix *p, struct attr *attr, safi_t safi,
9547 bool use_json, json_object *json_ar, bool wide)
9548 {
9549 json_object *json_status = NULL;
9550 json_object *json_net = NULL;
9551 int len;
9552 char buff[BUFSIZ];
9553
9554 /* Route status display. */
9555 if (use_json) {
9556 json_status = json_object_new_object();
9557 json_net = json_object_new_object();
9558 } else {
9559 vty_out(vty, " *");
9560 vty_out(vty, ">");
9561 vty_out(vty, " ");
9562 }
9563
9564 /* print prefix and mask */
9565 if (use_json) {
9566 if (safi == SAFI_EVPN)
9567 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9568 else if (p->family == AF_INET || p->family == AF_INET6) {
9569 json_object_string_add(
9570 json_net, "addrPrefix",
9571 inet_ntop(p->family, &p->u.prefix, buff,
9572 BUFSIZ));
9573 json_object_int_add(json_net, "prefixLen",
9574 p->prefixlen);
9575 json_object_string_addf(json_net, "network", "%pFX", p);
9576 }
9577 } else
9578 route_vty_out_route(dest, p, vty, NULL, wide);
9579
9580 /* Print attribute */
9581 if (attr) {
9582 if (use_json) {
9583 if (p->family == AF_INET &&
9584 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9585 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9586 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9587 json_object_string_addf(
9588 json_net, "nextHop", "%pI4",
9589 &attr->mp_nexthop_global_in);
9590 else
9591 json_object_string_addf(
9592 json_net, "nextHop", "%pI4",
9593 &attr->nexthop);
9594 } else if (p->family == AF_INET6 ||
9595 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9596 json_object_string_addf(
9597 json_net, "nextHopGlobal", "%pI6",
9598 &attr->mp_nexthop_global);
9599 } else if (p->family == AF_EVPN &&
9600 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9601 json_object_string_addf(
9602 json_net, "nextHop", "%pI4",
9603 &attr->mp_nexthop_global_in);
9604 }
9605
9606 if (attr->flag
9607 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9608 json_object_int_add(json_net, "metric",
9609 attr->med);
9610
9611 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9612 json_object_int_add(json_net, "locPrf",
9613 attr->local_pref);
9614
9615 json_object_int_add(json_net, "weight", attr->weight);
9616
9617 /* Print aspath */
9618 if (attr->aspath)
9619 json_object_string_add(json_net, "path",
9620 attr->aspath->str);
9621
9622 /* Print origin */
9623 #if CONFDATE > 20231208
9624 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9625 #endif
9626 json_object_string_add(json_net, "bgpOriginCode",
9627 bgp_origin_str[attr->origin]);
9628 json_object_string_add(
9629 json_net, "origin",
9630 bgp_origin_long_str[attr->origin]);
9631 } else {
9632 if (p->family == AF_INET &&
9633 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9634 safi == SAFI_EVPN ||
9635 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9636 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9637 || safi == SAFI_EVPN)
9638 vty_out(vty, "%-16pI4",
9639 &attr->mp_nexthop_global_in);
9640 else if (wide)
9641 vty_out(vty, "%-41pI4", &attr->nexthop);
9642 else
9643 vty_out(vty, "%-16pI4", &attr->nexthop);
9644 } else if (p->family == AF_INET6 ||
9645 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9646 len = vty_out(vty, "%pI6",
9647 &attr->mp_nexthop_global);
9648 len = wide ? (41 - len) : (16 - len);
9649 if (len < 1)
9650 vty_out(vty, "\n%*s", 36, " ");
9651 else
9652 vty_out(vty, "%*s", len, " ");
9653 }
9654 if (attr->flag
9655 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9656 if (wide)
9657 vty_out(vty, "%7u", attr->med);
9658 else
9659 vty_out(vty, "%10u", attr->med);
9660 else if (wide)
9661 vty_out(vty, " ");
9662 else
9663 vty_out(vty, " ");
9664
9665 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9666 vty_out(vty, "%7u", attr->local_pref);
9667 else
9668 vty_out(vty, " ");
9669
9670 vty_out(vty, "%7u ", attr->weight);
9671
9672 /* Print aspath */
9673 if (attr->aspath)
9674 aspath_print_vty(vty, attr->aspath);
9675
9676 /* Print origin */
9677 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9678 }
9679 }
9680 if (use_json) {
9681 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9682
9683 #if CONFDATE > 20231208
9684 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9685 #endif
9686 json_object_boolean_true_add(json_status, "*");
9687 json_object_boolean_true_add(json_status, ">");
9688 json_object_boolean_true_add(json_net, "valid");
9689 json_object_boolean_true_add(json_net, "best");
9690
9691 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9692 json_object_boolean_true_add(json_status, "=");
9693 json_object_boolean_true_add(json_net, "multipath");
9694 }
9695 json_object_object_add(json_net, "appliedStatusSymbols",
9696 json_status);
9697 json_object_object_addf(json_ar, json_net, "%pFX", p);
9698 } else
9699 vty_out(vty, "\n");
9700 }
9701
9702 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9703 struct bgp_path_info *path, int display, safi_t safi,
9704 json_object *json)
9705 {
9706 json_object *json_out = NULL;
9707 struct attr *attr;
9708 mpls_label_t label = MPLS_INVALID_LABEL;
9709
9710 if (!path->extra)
9711 return;
9712
9713 if (json)
9714 json_out = json_object_new_object();
9715
9716 /* short status lead text */
9717 route_vty_short_status_out(vty, path, p, json_out);
9718
9719 /* print prefix and mask */
9720 if (json == NULL) {
9721 if (!display)
9722 route_vty_out_route(path->net, p, vty, NULL, false);
9723 else
9724 vty_out(vty, "%*s", 17, " ");
9725 }
9726
9727 /* Print attribute */
9728 attr = path->attr;
9729 if (((p->family == AF_INET) &&
9730 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9731 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9732 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9733 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9734 || safi == SAFI_EVPN) {
9735 if (json)
9736 json_object_string_addf(
9737 json_out, "mpNexthopGlobalIn", "%pI4",
9738 &attr->mp_nexthop_global_in);
9739 else
9740 vty_out(vty, "%-16pI4",
9741 &attr->mp_nexthop_global_in);
9742 } else {
9743 if (json)
9744 json_object_string_addf(json_out, "nexthop",
9745 "%pI4", &attr->nexthop);
9746 else
9747 vty_out(vty, "%-16pI4", &attr->nexthop);
9748 }
9749 } else if (((p->family == AF_INET6) &&
9750 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9751 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9752 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9753 char buf_a[512];
9754
9755 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9756 if (json)
9757 json_object_string_addf(
9758 json_out, "mpNexthopGlobalIn", "%pI6",
9759 &attr->mp_nexthop_global);
9760 else
9761 vty_out(vty, "%s",
9762 inet_ntop(AF_INET6,
9763 &attr->mp_nexthop_global,
9764 buf_a, sizeof(buf_a)));
9765 } else if (attr->mp_nexthop_len
9766 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9767 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9768 &attr->mp_nexthop_global,
9769 &attr->mp_nexthop_local);
9770 if (json)
9771 json_object_string_add(json_out,
9772 "mpNexthopGlobalLocal",
9773 buf_a);
9774 else
9775 vty_out(vty, "%s", buf_a);
9776 }
9777 }
9778
9779 label = decode_label(&path->extra->label[0]);
9780
9781 if (bgp_is_valid_label(&label)) {
9782 if (json) {
9783 json_object_int_add(json_out, "notag", label);
9784 json_object_array_add(json, json_out);
9785 } else {
9786 vty_out(vty, "notag/%d", label);
9787 vty_out(vty, "\n");
9788 }
9789 } else if (!json)
9790 vty_out(vty, "\n");
9791 }
9792
9793 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9794 struct bgp_path_info *path, int display,
9795 json_object *json_paths)
9796 {
9797 struct attr *attr;
9798 json_object *json_path = NULL;
9799 json_object *json_nexthop = NULL;
9800 json_object *json_overlay = NULL;
9801
9802 if (!path->extra)
9803 return;
9804
9805 if (json_paths) {
9806 json_path = json_object_new_object();
9807 json_overlay = json_object_new_object();
9808 json_nexthop = json_object_new_object();
9809 }
9810
9811 /* short status lead text */
9812 route_vty_short_status_out(vty, path, p, json_path);
9813
9814 /* print prefix and mask */
9815 if (!display)
9816 route_vty_out_route(path->net, p, vty, json_path, false);
9817 else
9818 vty_out(vty, "%*s", 17, " ");
9819
9820 /* Print attribute */
9821 attr = path->attr;
9822 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9823
9824 switch (af) {
9825 case AF_INET:
9826 if (!json_path) {
9827 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9828 } else {
9829 json_object_string_addf(json_nexthop, "ip", "%pI4",
9830 &attr->mp_nexthop_global_in);
9831
9832 json_object_string_add(json_nexthop, "afi", "ipv4");
9833
9834 json_object_object_add(json_path, "nexthop",
9835 json_nexthop);
9836 }
9837 break;
9838 case AF_INET6:
9839 if (!json_path) {
9840 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9841 &attr->mp_nexthop_local);
9842 } else {
9843 json_object_string_addf(json_nexthop, "ipv6Global",
9844 "%pI6",
9845 &attr->mp_nexthop_global);
9846
9847 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9848 "%pI6",
9849 &attr->mp_nexthop_local);
9850
9851 json_object_string_add(json_nexthop, "afi", "ipv6");
9852
9853 json_object_object_add(json_path, "nexthop",
9854 json_nexthop);
9855 }
9856 break;
9857 default:
9858 if (!json_path) {
9859 vty_out(vty, "?");
9860 } else {
9861 json_object_string_add(json_nexthop, "error",
9862 "Unsupported address-family");
9863 }
9864 }
9865
9866 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9867
9868 if (!json_path)
9869 vty_out(vty, "/%pIA", &eo->gw_ip);
9870 else
9871 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9872
9873 if (bgp_attr_get_ecommunity(attr)) {
9874 char *mac = NULL;
9875 struct ecommunity_val *routermac = ecommunity_lookup(
9876 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9877 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9878
9879 if (routermac)
9880 mac = ecom_mac2str((char *)routermac->val);
9881 if (mac) {
9882 if (!json_path) {
9883 vty_out(vty, "/%s", mac);
9884 } else {
9885 json_object_string_add(json_overlay, "rmac",
9886 mac);
9887 }
9888 XFREE(MTYPE_TMP, mac);
9889 }
9890 }
9891
9892 if (!json_path) {
9893 vty_out(vty, "\n");
9894 } else {
9895 json_object_object_add(json_path, "overlay", json_overlay);
9896
9897 json_object_array_add(json_paths, json_path);
9898 }
9899 }
9900
9901 /* dampening route */
9902 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9903 struct bgp_path_info *path, int display,
9904 afi_t afi, safi_t safi, bool use_json,
9905 json_object *json_paths)
9906 {
9907 struct attr *attr = path->attr;
9908 int len;
9909 char timebuf[BGP_UPTIME_LEN];
9910 json_object *json_path = NULL;
9911
9912 if (use_json)
9913 json_path = json_object_new_object();
9914
9915 /* short status lead text */
9916 route_vty_short_status_out(vty, path, p, json_path);
9917
9918 /* print prefix and mask */
9919 if (!use_json) {
9920 if (!display)
9921 route_vty_out_route(path->net, p, vty, NULL, false);
9922 else
9923 vty_out(vty, "%*s", 17, " ");
9924
9925 len = vty_out(vty, "%s", path->peer->host);
9926 len = 17 - len;
9927
9928 if (len < 1)
9929 vty_out(vty, "\n%*s", 34, " ");
9930 else
9931 vty_out(vty, "%*s", len, " ");
9932
9933 vty_out(vty, "%s ",
9934 bgp_damp_reuse_time_vty(vty, path, timebuf,
9935 BGP_UPTIME_LEN, afi, safi,
9936 use_json, NULL));
9937
9938 if (attr->aspath)
9939 aspath_print_vty(vty, attr->aspath);
9940
9941 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9942
9943 vty_out(vty, "\n");
9944 } else {
9945 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9946 safi, use_json, json_path);
9947
9948 if (attr->aspath)
9949 json_object_string_add(json_path, "asPath",
9950 attr->aspath->str);
9951
9952 json_object_string_add(json_path, "origin",
9953 bgp_origin_str[attr->origin]);
9954 json_object_string_add(json_path, "peerHost", path->peer->host);
9955
9956 json_object_array_add(json_paths, json_path);
9957 }
9958 }
9959
9960 /* flap route */
9961 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9962 struct bgp_path_info *path, int display,
9963 afi_t afi, safi_t safi, bool use_json,
9964 json_object *json_paths)
9965 {
9966 struct attr *attr = path->attr;
9967 struct bgp_damp_info *bdi;
9968 char timebuf[BGP_UPTIME_LEN];
9969 int len;
9970 json_object *json_path = NULL;
9971
9972 if (!path->extra)
9973 return;
9974
9975 if (use_json)
9976 json_path = json_object_new_object();
9977
9978 bdi = path->extra->damp_info;
9979
9980 /* short status lead text */
9981 route_vty_short_status_out(vty, path, p, json_path);
9982
9983 if (!use_json) {
9984 if (!display)
9985 route_vty_out_route(path->net, p, vty, NULL, false);
9986 else
9987 vty_out(vty, "%*s", 17, " ");
9988
9989 len = vty_out(vty, "%s", path->peer->host);
9990 len = 16 - len;
9991 if (len < 1)
9992 vty_out(vty, "\n%*s", 33, " ");
9993 else
9994 vty_out(vty, "%*s", len, " ");
9995
9996 len = vty_out(vty, "%d", bdi->flap);
9997 len = 5 - len;
9998 if (len < 1)
9999 vty_out(vty, " ");
10000 else
10001 vty_out(vty, "%*s", len, " ");
10002
10003 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10004 BGP_UPTIME_LEN, 0, NULL));
10005
10006 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10007 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10008 vty_out(vty, "%s ",
10009 bgp_damp_reuse_time_vty(vty, path, timebuf,
10010 BGP_UPTIME_LEN, afi,
10011 safi, use_json, NULL));
10012 else
10013 vty_out(vty, "%*s ", 8, " ");
10014
10015 if (attr->aspath)
10016 aspath_print_vty(vty, attr->aspath);
10017
10018 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10019
10020 vty_out(vty, "\n");
10021 } else {
10022 json_object_string_add(json_path, "peerHost", path->peer->host);
10023 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10024
10025 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10026 json_path);
10027
10028 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10029 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10030 bgp_damp_reuse_time_vty(vty, path, timebuf,
10031 BGP_UPTIME_LEN, afi, safi,
10032 use_json, json_path);
10033
10034 if (attr->aspath)
10035 json_object_string_add(json_path, "asPath",
10036 attr->aspath->str);
10037
10038 json_object_string_add(json_path, "origin",
10039 bgp_origin_str[attr->origin]);
10040
10041 json_object_array_add(json_paths, json_path);
10042 }
10043 }
10044
10045 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10046 int *first, const char *header,
10047 json_object *json_adv_to)
10048 {
10049 json_object *json_peer = NULL;
10050
10051 if (json_adv_to) {
10052 /* 'advertised-to' is a dictionary of peers we have advertised
10053 * this
10054 * prefix too. The key is the peer's IP or swpX, the value is
10055 * the
10056 * hostname if we know it and "" if not.
10057 */
10058 json_peer = json_object_new_object();
10059
10060 if (peer->hostname)
10061 json_object_string_add(json_peer, "hostname",
10062 peer->hostname);
10063
10064 if (peer->conf_if)
10065 json_object_object_add(json_adv_to, peer->conf_if,
10066 json_peer);
10067 else
10068 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10069 &peer->su);
10070 } else {
10071 if (*first) {
10072 vty_out(vty, "%s", header);
10073 *first = 0;
10074 }
10075
10076 if (peer->hostname
10077 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10078 if (peer->conf_if)
10079 vty_out(vty, " %s(%s)", peer->hostname,
10080 peer->conf_if);
10081 else
10082 vty_out(vty, " %s(%pSU)", peer->hostname,
10083 &peer->su);
10084 } else {
10085 if (peer->conf_if)
10086 vty_out(vty, " %s", peer->conf_if);
10087 else
10088 vty_out(vty, " %pSU", &peer->su);
10089 }
10090 }
10091 }
10092
10093 static void route_vty_out_tx_ids(struct vty *vty,
10094 struct bgp_addpath_info_data *d)
10095 {
10096 int i;
10097
10098 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10099 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10100 d->addpath_tx_id[i],
10101 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10102 }
10103 }
10104
10105 static void route_vty_out_detail_es_info(struct vty *vty,
10106 struct bgp_path_info *pi,
10107 struct attr *attr,
10108 json_object *json_path)
10109 {
10110 char esi_buf[ESI_STR_LEN];
10111 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10112 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10113 ATTR_ES_PEER_ROUTER);
10114 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10115 ATTR_ES_PEER_ACTIVE);
10116 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10117 ATTR_ES_PEER_PROXY);
10118 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10119 if (json_path) {
10120 json_object *json_es_info = NULL;
10121
10122 json_object_string_add(
10123 json_path, "esi",
10124 esi_buf);
10125 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10126 json_es_info = json_object_new_object();
10127 if (es_local)
10128 json_object_boolean_true_add(
10129 json_es_info, "localEs");
10130 if (peer_active)
10131 json_object_boolean_true_add(
10132 json_es_info, "peerActive");
10133 if (peer_proxy)
10134 json_object_boolean_true_add(
10135 json_es_info, "peerProxy");
10136 if (peer_router)
10137 json_object_boolean_true_add(
10138 json_es_info, "peerRouter");
10139 if (attr->mm_sync_seqnum)
10140 json_object_int_add(
10141 json_es_info, "peerSeq",
10142 attr->mm_sync_seqnum);
10143 json_object_object_add(
10144 json_path, "es_info",
10145 json_es_info);
10146 }
10147 } else {
10148 if (bgp_evpn_attr_is_sync(attr))
10149 vty_out(vty,
10150 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10151 esi_buf,
10152 es_local ? "local-es":"",
10153 peer_proxy ? "proxy " : "",
10154 peer_active ? "active ":"",
10155 peer_router ? "router ":"",
10156 attr->mm_sync_seqnum);
10157 else
10158 vty_out(vty, " ESI %s %s\n",
10159 esi_buf,
10160 es_local ? "local-es":"");
10161 }
10162 }
10163
10164 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10165 const struct prefix *p, struct bgp_path_info *path,
10166 afi_t afi, safi_t safi,
10167 enum rpki_states rpki_curr_state,
10168 json_object *json_paths)
10169 {
10170 char buf[INET6_ADDRSTRLEN];
10171 char tag_buf[30];
10172 struct attr *attr = path->attr;
10173 time_t tbuf;
10174 json_object *json_bestpath = NULL;
10175 json_object *json_cluster_list = NULL;
10176 json_object *json_cluster_list_list = NULL;
10177 json_object *json_ext_community = NULL;
10178 json_object *json_last_update = NULL;
10179 json_object *json_pmsi = NULL;
10180 json_object *json_nexthop_global = NULL;
10181 json_object *json_nexthop_ll = NULL;
10182 json_object *json_nexthops = NULL;
10183 json_object *json_path = NULL;
10184 json_object *json_peer = NULL;
10185 json_object *json_string = NULL;
10186 json_object *json_adv_to = NULL;
10187 int first = 0;
10188 struct listnode *node, *nnode;
10189 struct peer *peer;
10190 bool addpath_capable;
10191 int has_adj;
10192 unsigned int first_as;
10193 bool nexthop_self =
10194 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10195 int i;
10196 char *nexthop_hostname =
10197 bgp_nexthop_hostname(path->peer, path->nexthop);
10198 uint32_t ttl = 0;
10199 uint32_t bos = 0;
10200 uint32_t exp = 0;
10201 mpls_label_t label = MPLS_INVALID_LABEL;
10202 tag_buf[0] = '\0';
10203 struct bgp_path_info *bpi_ultimate =
10204 bgp_get_imported_bpi_ultimate(path);
10205
10206 if (json_paths) {
10207 json_path = json_object_new_object();
10208 json_peer = json_object_new_object();
10209 json_nexthop_global = json_object_new_object();
10210 }
10211
10212 if (safi == SAFI_EVPN) {
10213 if (!json_paths)
10214 vty_out(vty, " Route %pFX", p);
10215 }
10216
10217 if (path->extra) {
10218 if (path->extra && path->extra->num_labels) {
10219 bgp_evpn_label2str(path->extra->label,
10220 path->extra->num_labels, tag_buf,
10221 sizeof(tag_buf));
10222 }
10223 if (safi == SAFI_EVPN) {
10224 if (!json_paths) {
10225 if (tag_buf[0] != '\0')
10226 vty_out(vty, " VNI %s", tag_buf);
10227 } else {
10228 if (tag_buf[0])
10229 json_object_string_add(json_path, "vni",
10230 tag_buf);
10231 }
10232 }
10233 }
10234
10235 if (safi == SAFI_EVPN
10236 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10237 char gwip_buf[INET6_ADDRSTRLEN];
10238
10239 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10240 sizeof(gwip_buf));
10241
10242 if (json_paths)
10243 json_object_string_add(json_path, "gatewayIP",
10244 gwip_buf);
10245 else
10246 vty_out(vty, " Gateway IP %s", gwip_buf);
10247 }
10248
10249 if (safi == SAFI_EVPN && !json_path)
10250 vty_out(vty, "\n");
10251
10252
10253 if (path->extra && path->extra->parent && !json_paths) {
10254 struct bgp_path_info *parent_ri;
10255 struct bgp_dest *dest, *pdest;
10256
10257 parent_ri = (struct bgp_path_info *)path->extra->parent;
10258 dest = parent_ri->net;
10259 if (dest && dest->pdest) {
10260 pdest = dest->pdest;
10261 if (is_pi_family_evpn(parent_ri)) {
10262 vty_out(vty, " Imported from ");
10263 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10264 (struct prefix_rd *)bgp_dest_get_prefix(
10265 pdest));
10266 vty_out(vty, ":%pFX, VNI %s",
10267 (struct prefix_evpn *)
10268 bgp_dest_get_prefix(dest),
10269 tag_buf);
10270 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10271 vty_out(vty, ", L3NHG %s",
10272 CHECK_FLAG(
10273 attr->es_flags,
10274 ATTR_ES_L3_NHG_ACTIVE)
10275 ? "active"
10276 : "inactive");
10277 vty_out(vty, "\n");
10278
10279 } else {
10280 vty_out(vty, " Imported from ");
10281 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10282 (struct prefix_rd *)bgp_dest_get_prefix(
10283 pdest));
10284 vty_out(vty, ":%pFX\n",
10285 (struct prefix_evpn *)
10286 bgp_dest_get_prefix(dest));
10287 }
10288 }
10289 }
10290
10291 /* Line1 display AS-path, Aggregator */
10292 if (attr->aspath) {
10293 if (json_paths) {
10294 if (!attr->aspath->json)
10295 aspath_str_update(attr->aspath, true);
10296 json_object_lock(attr->aspath->json);
10297 json_object_object_add(json_path, "aspath",
10298 attr->aspath->json);
10299 } else {
10300 if (attr->aspath->segments)
10301 vty_out(vty, " %s", attr->aspath->str);
10302 else
10303 vty_out(vty, " Local");
10304 }
10305 }
10306
10307 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10308 if (json_paths)
10309 json_object_boolean_true_add(json_path, "removed");
10310 else
10311 vty_out(vty, ", (removed)");
10312 }
10313
10314 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10315 if (json_paths)
10316 json_object_boolean_true_add(json_path, "stale");
10317 else
10318 vty_out(vty, ", (stale)");
10319 }
10320
10321 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10322 if (json_paths) {
10323 json_object_int_add(json_path, "aggregatorAs",
10324 attr->aggregator_as);
10325 json_object_string_addf(json_path, "aggregatorId",
10326 "%pI4", &attr->aggregator_addr);
10327 } else {
10328 vty_out(vty, ", (aggregated by %u %pI4)",
10329 attr->aggregator_as, &attr->aggregator_addr);
10330 }
10331 }
10332
10333 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10334 PEER_FLAG_REFLECTOR_CLIENT)) {
10335 if (json_paths)
10336 json_object_boolean_true_add(json_path,
10337 "rxedFromRrClient");
10338 else
10339 vty_out(vty, ", (Received from a RR-client)");
10340 }
10341
10342 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10343 PEER_FLAG_RSERVER_CLIENT)) {
10344 if (json_paths)
10345 json_object_boolean_true_add(json_path,
10346 "rxedFromRsClient");
10347 else
10348 vty_out(vty, ", (Received from a RS-client)");
10349 }
10350
10351 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10352 if (json_paths)
10353 json_object_boolean_true_add(json_path,
10354 "dampeningHistoryEntry");
10355 else
10356 vty_out(vty, ", (history entry)");
10357 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10358 if (json_paths)
10359 json_object_boolean_true_add(json_path,
10360 "dampeningSuppressed");
10361 else
10362 vty_out(vty, ", (suppressed due to dampening)");
10363 }
10364
10365 if (!json_paths)
10366 vty_out(vty, "\n");
10367
10368 /* Line2 display Next-hop, Neighbor, Router-id */
10369 /* Display the nexthop */
10370
10371 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10372 p->family == AF_EVPN) &&
10373 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10374 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10375 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10376 || safi == SAFI_EVPN) {
10377 if (json_paths) {
10378 json_object_string_addf(
10379 json_nexthop_global, "ip", "%pI4",
10380 &attr->mp_nexthop_global_in);
10381
10382 if (path->peer->hostname)
10383 json_object_string_add(
10384 json_nexthop_global, "hostname",
10385 path->peer->hostname);
10386 } else {
10387 if (nexthop_hostname)
10388 vty_out(vty, " %pI4(%s)",
10389 &attr->mp_nexthop_global_in,
10390 nexthop_hostname);
10391 else
10392 vty_out(vty, " %pI4",
10393 &attr->mp_nexthop_global_in);
10394 }
10395 } else {
10396 if (json_paths) {
10397 json_object_string_addf(json_nexthop_global,
10398 "ip", "%pI4",
10399 &attr->nexthop);
10400
10401 if (path->peer->hostname)
10402 json_object_string_add(
10403 json_nexthop_global, "hostname",
10404 path->peer->hostname);
10405 } else {
10406 if (nexthop_hostname)
10407 vty_out(vty, " %pI4(%s)",
10408 &attr->nexthop,
10409 nexthop_hostname);
10410 else
10411 vty_out(vty, " %pI4",
10412 &attr->nexthop);
10413 }
10414 }
10415
10416 if (json_paths)
10417 json_object_string_add(json_nexthop_global, "afi",
10418 "ipv4");
10419 } else {
10420 if (json_paths) {
10421 json_object_string_addf(json_nexthop_global, "ip",
10422 "%pI6",
10423 &attr->mp_nexthop_global);
10424
10425 if (path->peer->hostname)
10426 json_object_string_add(json_nexthop_global,
10427 "hostname",
10428 path->peer->hostname);
10429
10430 json_object_string_add(json_nexthop_global, "afi",
10431 "ipv6");
10432 json_object_string_add(json_nexthop_global, "scope",
10433 "global");
10434 } else {
10435 if (nexthop_hostname)
10436 vty_out(vty, " %pI6(%s)",
10437 &attr->mp_nexthop_global,
10438 nexthop_hostname);
10439 else
10440 vty_out(vty, " %pI6",
10441 &attr->mp_nexthop_global);
10442 }
10443 }
10444
10445 /* Display the IGP cost or 'inaccessible' */
10446 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10447 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10448
10449 if (json_paths) {
10450 json_object_boolean_false_add(json_nexthop_global,
10451 "accessible");
10452 json_object_boolean_add(json_nexthop_global,
10453 "importCheckEnabled", import);
10454 } else {
10455 vty_out(vty, " (inaccessible%s)",
10456 import ? ", import-check enabled" : "");
10457 }
10458 } else {
10459 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10460 if (json_paths)
10461 json_object_int_add(
10462 json_nexthop_global, "metric",
10463 bpi_ultimate->extra->igpmetric);
10464 else
10465 vty_out(vty, " (metric %u)",
10466 bpi_ultimate->extra->igpmetric);
10467 }
10468
10469 /* IGP cost is 0, display this only for json */
10470 else {
10471 if (json_paths)
10472 json_object_int_add(json_nexthop_global,
10473 "metric", 0);
10474 }
10475
10476 if (json_paths)
10477 json_object_boolean_true_add(json_nexthop_global,
10478 "accessible");
10479 }
10480
10481 /* Display peer "from" output */
10482 /* This path was originated locally */
10483 if (path->peer == bgp->peer_self) {
10484
10485 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10486 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10487 if (json_paths)
10488 json_object_string_add(json_peer, "peerId",
10489 "0.0.0.0");
10490 else
10491 vty_out(vty, " from 0.0.0.0 ");
10492 } else {
10493 if (json_paths)
10494 json_object_string_add(json_peer, "peerId",
10495 "::");
10496 else
10497 vty_out(vty, " from :: ");
10498 }
10499
10500 if (json_paths)
10501 json_object_string_addf(json_peer, "routerId", "%pI4",
10502 &bgp->router_id);
10503 else
10504 vty_out(vty, "(%pI4)", &bgp->router_id);
10505 }
10506
10507 /* We RXed this path from one of our peers */
10508 else {
10509
10510 if (json_paths) {
10511 json_object_string_addf(json_peer, "peerId", "%pSU",
10512 &path->peer->su);
10513 json_object_string_addf(json_peer, "routerId", "%pI4",
10514 &path->peer->remote_id);
10515
10516 if (path->peer->hostname)
10517 json_object_string_add(json_peer, "hostname",
10518 path->peer->hostname);
10519
10520 if (path->peer->domainname)
10521 json_object_string_add(json_peer, "domainname",
10522 path->peer->domainname);
10523
10524 if (path->peer->conf_if)
10525 json_object_string_add(json_peer, "interface",
10526 path->peer->conf_if);
10527 } else {
10528 if (path->peer->conf_if) {
10529 if (path->peer->hostname
10530 && CHECK_FLAG(path->peer->bgp->flags,
10531 BGP_FLAG_SHOW_HOSTNAME))
10532 vty_out(vty, " from %s(%s)",
10533 path->peer->hostname,
10534 path->peer->conf_if);
10535 else
10536 vty_out(vty, " from %s",
10537 path->peer->conf_if);
10538 } else {
10539 if (path->peer->hostname
10540 && CHECK_FLAG(path->peer->bgp->flags,
10541 BGP_FLAG_SHOW_HOSTNAME))
10542 vty_out(vty, " from %s(%s)",
10543 path->peer->hostname,
10544 path->peer->host);
10545 else
10546 vty_out(vty, " from %pSU",
10547 &path->peer->su);
10548 }
10549
10550 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10551 vty_out(vty, " (%pI4)", &attr->originator_id);
10552 else
10553 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10554 }
10555 }
10556
10557 /*
10558 * Note when vrfid of nexthop is different from that of prefix
10559 */
10560 if (path->extra && path->extra->bgp_orig) {
10561 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10562
10563 if (json_paths) {
10564 const char *vn;
10565
10566 if (path->extra->bgp_orig->inst_type
10567 == BGP_INSTANCE_TYPE_DEFAULT)
10568 vn = VRF_DEFAULT_NAME;
10569 else
10570 vn = path->extra->bgp_orig->name;
10571
10572 json_object_string_add(json_path, "nhVrfName", vn);
10573
10574 if (nexthop_vrfid == VRF_UNKNOWN) {
10575 json_object_int_add(json_path, "nhVrfId", -1);
10576 } else {
10577 json_object_int_add(json_path, "nhVrfId",
10578 (int)nexthop_vrfid);
10579 }
10580 } else {
10581 if (nexthop_vrfid == VRF_UNKNOWN)
10582 vty_out(vty, " vrf ?");
10583 else {
10584 struct vrf *vrf;
10585
10586 vrf = vrf_lookup_by_id(nexthop_vrfid);
10587 vty_out(vty, " vrf %s(%u)",
10588 VRF_LOGNAME(vrf), nexthop_vrfid);
10589 }
10590 }
10591 }
10592
10593 if (nexthop_self) {
10594 if (json_paths) {
10595 json_object_boolean_true_add(json_path,
10596 "announceNexthopSelf");
10597 } else {
10598 vty_out(vty, " announce-nh-self");
10599 }
10600 }
10601
10602 if (!json_paths)
10603 vty_out(vty, "\n");
10604
10605 /* display the link-local nexthop */
10606 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10607 if (json_paths) {
10608 json_nexthop_ll = json_object_new_object();
10609 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10610 &attr->mp_nexthop_local);
10611
10612 if (path->peer->hostname)
10613 json_object_string_add(json_nexthop_ll,
10614 "hostname",
10615 path->peer->hostname);
10616
10617 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10618 json_object_string_add(json_nexthop_ll, "scope",
10619 "link-local");
10620
10621 json_object_boolean_true_add(json_nexthop_ll,
10622 "accessible");
10623
10624 if (!attr->mp_nexthop_prefer_global)
10625 json_object_boolean_true_add(json_nexthop_ll,
10626 "used");
10627 else
10628 json_object_boolean_true_add(
10629 json_nexthop_global, "used");
10630 } else {
10631 vty_out(vty, " (%s) %s\n",
10632 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10633 buf, INET6_ADDRSTRLEN),
10634 attr->mp_nexthop_prefer_global
10635 ? "(prefer-global)"
10636 : "(used)");
10637 }
10638 }
10639 /* If we do not have a link-local nexthop then we must flag the
10640 global as "used" */
10641 else {
10642 if (json_paths)
10643 json_object_boolean_true_add(json_nexthop_global,
10644 "used");
10645 }
10646
10647 if (safi == SAFI_EVPN &&
10648 bgp_evpn_is_esi_valid(&attr->esi)) {
10649 route_vty_out_detail_es_info(vty, path, attr, json_path);
10650 }
10651
10652 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10653 * Int/Ext/Local, Atomic, best */
10654 if (json_paths)
10655 json_object_string_add(json_path, "origin",
10656 bgp_origin_long_str[attr->origin]);
10657 else
10658 vty_out(vty, " Origin %s",
10659 bgp_origin_long_str[attr->origin]);
10660
10661 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10662 if (json_paths)
10663 json_object_int_add(json_path, "metric", attr->med);
10664 else
10665 vty_out(vty, ", metric %u", attr->med);
10666 }
10667
10668 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10669 if (json_paths)
10670 json_object_int_add(json_path, "locPrf",
10671 attr->local_pref);
10672 else
10673 vty_out(vty, ", localpref %u", attr->local_pref);
10674 }
10675
10676 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10677 if (json_paths)
10678 json_object_int_add(json_path, "aigpMetric",
10679 bgp_attr_get_aigp_metric(attr));
10680 else
10681 vty_out(vty, ", aigp-metric %" PRIu64,
10682 bgp_attr_get_aigp_metric(attr));
10683 }
10684
10685 if (attr->weight != 0) {
10686 if (json_paths)
10687 json_object_int_add(json_path, "weight", attr->weight);
10688 else
10689 vty_out(vty, ", weight %u", attr->weight);
10690 }
10691
10692 if (attr->tag != 0) {
10693 if (json_paths)
10694 json_object_int_add(json_path, "tag", attr->tag);
10695 else
10696 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10697 }
10698
10699 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10700 if (json_paths)
10701 json_object_boolean_false_add(json_path, "valid");
10702 else
10703 vty_out(vty, ", invalid");
10704 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10705 if (json_paths)
10706 json_object_boolean_true_add(json_path, "valid");
10707 else
10708 vty_out(vty, ", valid");
10709 }
10710
10711 if (json_paths)
10712 json_object_int_add(json_path, "version", bn->version);
10713
10714 if (path->peer != bgp->peer_self) {
10715 if (path->peer->as == path->peer->local_as) {
10716 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10717 if (json_paths)
10718 json_object_string_add(
10719 json_peer, "type",
10720 "confed-internal");
10721 else
10722 vty_out(vty, ", confed-internal");
10723 } else {
10724 if (json_paths)
10725 json_object_string_add(
10726 json_peer, "type", "internal");
10727 else
10728 vty_out(vty, ", internal");
10729 }
10730 } else {
10731 if (bgp_confederation_peers_check(bgp,
10732 path->peer->as)) {
10733 if (json_paths)
10734 json_object_string_add(
10735 json_peer, "type",
10736 "confed-external");
10737 else
10738 vty_out(vty, ", confed-external");
10739 } else {
10740 if (json_paths)
10741 json_object_string_add(
10742 json_peer, "type", "external");
10743 else
10744 vty_out(vty, ", external");
10745 }
10746 }
10747 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10748 if (json_paths) {
10749 json_object_boolean_true_add(json_path, "aggregated");
10750 json_object_boolean_true_add(json_path, "local");
10751 } else {
10752 vty_out(vty, ", aggregated, local");
10753 }
10754 } else if (path->type != ZEBRA_ROUTE_BGP) {
10755 if (json_paths)
10756 json_object_boolean_true_add(json_path, "sourced");
10757 else
10758 vty_out(vty, ", sourced");
10759 } else {
10760 if (json_paths) {
10761 json_object_boolean_true_add(json_path, "sourced");
10762 json_object_boolean_true_add(json_path, "local");
10763 } else {
10764 vty_out(vty, ", sourced, local");
10765 }
10766 }
10767
10768 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10769 if (json_paths)
10770 json_object_boolean_true_add(json_path,
10771 "atomicAggregate");
10772 else
10773 vty_out(vty, ", atomic-aggregate");
10774 }
10775
10776 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10777 if (json_paths)
10778 json_object_int_add(json_path, "otc", attr->otc);
10779 else
10780 vty_out(vty, ", otc %u", attr->otc);
10781 }
10782
10783 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10784 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10785 && bgp_path_info_mpath_count(path))) {
10786 if (json_paths)
10787 json_object_boolean_true_add(json_path, "multipath");
10788 else
10789 vty_out(vty, ", multipath");
10790 }
10791
10792 // Mark the bestpath(s)
10793 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10794 first_as = aspath_get_first_as(attr->aspath);
10795
10796 if (json_paths) {
10797 if (!json_bestpath)
10798 json_bestpath = json_object_new_object();
10799 json_object_int_add(json_bestpath, "bestpathFromAs",
10800 first_as);
10801 } else {
10802 if (first_as)
10803 vty_out(vty, ", bestpath-from-AS %u", first_as);
10804 else
10805 vty_out(vty, ", bestpath-from-AS Local");
10806 }
10807 }
10808
10809 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10810 if (json_paths) {
10811 if (!json_bestpath)
10812 json_bestpath = json_object_new_object();
10813 json_object_boolean_true_add(json_bestpath, "overall");
10814 json_object_string_add(
10815 json_bestpath, "selectionReason",
10816 bgp_path_selection_reason2str(bn->reason));
10817 } else {
10818 vty_out(vty, ", best");
10819 vty_out(vty, " (%s)",
10820 bgp_path_selection_reason2str(bn->reason));
10821 }
10822 }
10823
10824 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10825 if (json_paths)
10826 json_object_string_add(
10827 json_path, "rpkiValidationState",
10828 bgp_rpki_validation2str(rpki_curr_state));
10829 else
10830 vty_out(vty, ", rpki validation-state: %s",
10831 bgp_rpki_validation2str(rpki_curr_state));
10832 }
10833
10834 if (json_bestpath)
10835 json_object_object_add(json_path, "bestpath", json_bestpath);
10836
10837 if (!json_paths)
10838 vty_out(vty, "\n");
10839
10840 /* Line 4 display Community */
10841 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10842 if (json_paths) {
10843 if (!bgp_attr_get_community(attr)->json)
10844 community_str(bgp_attr_get_community(attr),
10845 true, true);
10846 json_object_lock(bgp_attr_get_community(attr)->json);
10847 json_object_object_add(
10848 json_path, "community",
10849 bgp_attr_get_community(attr)->json);
10850 } else {
10851 vty_out(vty, " Community: %s\n",
10852 bgp_attr_get_community(attr)->str);
10853 }
10854 }
10855
10856 /* Line 5 display Extended-community */
10857 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10858 if (json_paths) {
10859 json_ext_community = json_object_new_object();
10860 json_object_string_add(
10861 json_ext_community, "string",
10862 bgp_attr_get_ecommunity(attr)->str);
10863 json_object_object_add(json_path, "extendedCommunity",
10864 json_ext_community);
10865 } else {
10866 vty_out(vty, " Extended Community: %s\n",
10867 bgp_attr_get_ecommunity(attr)->str);
10868 }
10869 }
10870
10871 /* Line 6 display Large community */
10872 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10873 if (json_paths) {
10874 if (!bgp_attr_get_lcommunity(attr)->json)
10875 lcommunity_str(bgp_attr_get_lcommunity(attr),
10876 true, true);
10877 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10878 json_object_object_add(
10879 json_path, "largeCommunity",
10880 bgp_attr_get_lcommunity(attr)->json);
10881 } else {
10882 vty_out(vty, " Large Community: %s\n",
10883 bgp_attr_get_lcommunity(attr)->str);
10884 }
10885 }
10886
10887 /* Line 7 display Originator, Cluster-id */
10888 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10889 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10890 char buf[BUFSIZ] = {0};
10891
10892 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10893 if (json_paths)
10894 json_object_string_addf(json_path,
10895 "originatorId", "%pI4",
10896 &attr->originator_id);
10897 else
10898 vty_out(vty, " Originator: %pI4",
10899 &attr->originator_id);
10900 }
10901
10902 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10903 struct cluster_list *cluster =
10904 bgp_attr_get_cluster(attr);
10905 int i;
10906
10907 if (json_paths) {
10908 json_cluster_list = json_object_new_object();
10909 json_cluster_list_list =
10910 json_object_new_array();
10911
10912 for (i = 0; i < cluster->length / 4; i++) {
10913 json_string = json_object_new_string(
10914 inet_ntop(AF_INET,
10915 &cluster->list[i],
10916 buf, sizeof(buf)));
10917 json_object_array_add(
10918 json_cluster_list_list,
10919 json_string);
10920 }
10921
10922 /*
10923 * struct cluster_list does not have
10924 * "str" variable like aspath and community
10925 * do. Add this someday if someone asks
10926 * for it.
10927 * json_object_string_add(json_cluster_list,
10928 * "string", cluster->str);
10929 */
10930 json_object_object_add(json_cluster_list,
10931 "list",
10932 json_cluster_list_list);
10933 json_object_object_add(json_path, "clusterList",
10934 json_cluster_list);
10935 } else {
10936 vty_out(vty, ", Cluster list: ");
10937
10938 for (i = 0; i < cluster->length / 4; i++) {
10939 vty_out(vty, "%pI4 ",
10940 &cluster->list[i]);
10941 }
10942 }
10943 }
10944
10945 if (!json_paths)
10946 vty_out(vty, "\n");
10947 }
10948
10949 if (path->extra && path->extra->damp_info)
10950 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10951
10952 /* Remote Label */
10953 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10954 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10955 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10956 &bos);
10957
10958 if (json_paths)
10959 json_object_int_add(json_path, "remoteLabel", label);
10960 else
10961 vty_out(vty, " Remote label: %d\n", label);
10962 }
10963
10964 /* Remote SID */
10965 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10966 if (json_paths)
10967 json_object_string_addf(json_path, "remoteSid", "%pI6",
10968 &path->extra->sid[0].sid);
10969 else
10970 vty_out(vty, " Remote SID: %pI6\n",
10971 &path->extra->sid[0].sid);
10972 }
10973
10974 /* Label Index */
10975 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10976 if (json_paths)
10977 json_object_int_add(json_path, "labelIndex",
10978 attr->label_index);
10979 else
10980 vty_out(vty, " Label Index: %d\n",
10981 attr->label_index);
10982 }
10983
10984 /* Line 8 display Addpath IDs */
10985 if (path->addpath_rx_id
10986 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10987 if (json_paths) {
10988 json_object_int_add(json_path, "addpathRxId",
10989 path->addpath_rx_id);
10990
10991 /* Keep backwards compatibility with the old API
10992 * by putting TX All's ID in the old field
10993 */
10994 json_object_int_add(
10995 json_path, "addpathTxId",
10996 path->tx_addpath
10997 .addpath_tx_id[BGP_ADDPATH_ALL]);
10998
10999 /* ... but create a specific field for each
11000 * strategy
11001 */
11002 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11003 json_object_int_add(
11004 json_path,
11005 bgp_addpath_names(i)->id_json_name,
11006 path->tx_addpath.addpath_tx_id[i]);
11007 }
11008 } else {
11009 vty_out(vty, " AddPath ID: RX %u, ",
11010 path->addpath_rx_id);
11011
11012 route_vty_out_tx_ids(vty, &path->tx_addpath);
11013 }
11014 }
11015
11016 /* If we used addpath to TX a non-bestpath we need to display
11017 * "Advertised to" on a path-by-path basis
11018 */
11019 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11020 first = 1;
11021
11022 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11023 addpath_capable =
11024 bgp_addpath_encode_tx(peer, afi, safi);
11025 has_adj = bgp_adj_out_lookup(
11026 peer, path->net,
11027 bgp_addpath_id_for_peer(peer, afi, safi,
11028 &path->tx_addpath));
11029
11030 if ((addpath_capable && has_adj)
11031 || (!addpath_capable && has_adj
11032 && CHECK_FLAG(path->flags,
11033 BGP_PATH_SELECTED))) {
11034 if (json_path && !json_adv_to)
11035 json_adv_to = json_object_new_object();
11036
11037 route_vty_out_advertised_to(
11038 vty, peer, &first,
11039 " Advertised to:", json_adv_to);
11040 }
11041 }
11042
11043 if (json_path) {
11044 if (json_adv_to) {
11045 json_object_object_add(
11046 json_path, "advertisedTo", json_adv_to);
11047 }
11048 } else {
11049 if (!first) {
11050 vty_out(vty, "\n");
11051 }
11052 }
11053 }
11054
11055 /* Line 9 display Uptime */
11056 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11057 if (json_paths) {
11058 json_last_update = json_object_new_object();
11059 json_object_int_add(json_last_update, "epoch", tbuf);
11060 json_object_string_add(json_last_update, "string",
11061 ctime(&tbuf));
11062 json_object_object_add(json_path, "lastUpdate",
11063 json_last_update);
11064 } else
11065 vty_out(vty, " Last update: %s", ctime(&tbuf));
11066
11067 /* Line 10 display PMSI tunnel attribute, if present */
11068 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11069 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11070 bgp_attr_get_pmsi_tnl_type(attr),
11071 PMSI_TNLTYPE_STR_DEFAULT);
11072
11073 if (json_paths) {
11074 json_pmsi = json_object_new_object();
11075 json_object_string_add(json_pmsi, "tunnelType", str);
11076 json_object_int_add(json_pmsi, "label",
11077 label2vni(&attr->label));
11078 json_object_object_add(json_path, "pmsi", json_pmsi);
11079 } else
11080 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11081 str, label2vni(&attr->label));
11082 }
11083
11084 if (path->peer->t_gr_restart &&
11085 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11086 unsigned long gr_remaining =
11087 event_timer_remain_second(path->peer->t_gr_restart);
11088
11089 if (json_paths) {
11090 json_object_int_add(json_path,
11091 "gracefulRestartSecondsRemaining",
11092 gr_remaining);
11093 } else
11094 vty_out(vty,
11095 " Time until Graceful Restart stale route deleted: %lu\n",
11096 gr_remaining);
11097 }
11098
11099 if (path->peer->t_llgr_stale[afi][safi] &&
11100 bgp_attr_get_community(attr) &&
11101 community_include(bgp_attr_get_community(attr),
11102 COMMUNITY_LLGR_STALE)) {
11103 unsigned long llgr_remaining = event_timer_remain_second(
11104 path->peer->t_llgr_stale[afi][safi]);
11105
11106 if (json_paths) {
11107 json_object_int_add(json_path, "llgrSecondsRemaining",
11108 llgr_remaining);
11109 } else
11110 vty_out(vty,
11111 " Time until Long-lived stale route deleted: %lu\n",
11112 llgr_remaining);
11113 }
11114
11115 /* Output some debug about internal state of the dest flags */
11116 if (json_paths) {
11117 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11118 json_object_boolean_true_add(json_path, "processScheduled");
11119 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11120 json_object_boolean_true_add(json_path, "userCleared");
11121 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11122 json_object_boolean_true_add(json_path, "labelChanged");
11123 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11124 json_object_boolean_true_add(json_path, "registeredForLabel");
11125 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11126 json_object_boolean_true_add(json_path, "selectDefered");
11127 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11128 json_object_boolean_true_add(json_path, "fibInstalled");
11129 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11130 json_object_boolean_true_add(json_path, "fibPending");
11131
11132 if (json_nexthop_global || json_nexthop_ll) {
11133 json_nexthops = json_object_new_array();
11134
11135 if (json_nexthop_global)
11136 json_object_array_add(json_nexthops,
11137 json_nexthop_global);
11138
11139 if (json_nexthop_ll)
11140 json_object_array_add(json_nexthops,
11141 json_nexthop_ll);
11142
11143 json_object_object_add(json_path, "nexthops",
11144 json_nexthops);
11145 }
11146
11147 json_object_object_add(json_path, "peer", json_peer);
11148 json_object_array_add(json_paths, json_path);
11149 }
11150 }
11151
11152 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11153 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11154 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11155
11156 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11157 afi_t afi, safi_t safi, enum bgp_show_type type,
11158 bool use_json);
11159 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11160 const char *comstr, int exact, afi_t afi,
11161 safi_t safi, uint16_t show_flags);
11162
11163 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11164 struct bgp_table *table, enum bgp_show_type type,
11165 void *output_arg, const char *rd, int is_last,
11166 unsigned long *output_cum, unsigned long *total_cum,
11167 unsigned long *json_header_depth, uint16_t show_flags,
11168 enum rpki_states rpki_target_state)
11169 {
11170 struct bgp_path_info *pi;
11171 struct bgp_dest *dest;
11172 bool header = true;
11173 bool json_detail_header = false;
11174 int display;
11175 unsigned long output_count = 0;
11176 unsigned long total_count = 0;
11177 struct prefix *p;
11178 json_object *json_paths = NULL;
11179 int first = 1;
11180 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11181 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11182 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11183 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11184 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11185
11186 if (output_cum && *output_cum != 0)
11187 header = false;
11188
11189 if (use_json && !*json_header_depth) {
11190 if (all)
11191 *json_header_depth = 1;
11192 else {
11193 vty_out(vty, "{\n");
11194 *json_header_depth = 2;
11195 }
11196 vty_out(vty,
11197 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11198 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11199 " \"localAS\": ",
11200 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11201 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11202 ? VRF_DEFAULT_NAME
11203 : bgp->name,
11204 table->version, &bgp->router_id,
11205 bgp->default_local_pref);
11206 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11207 ((bgp->asnotation == ASNOTATION_DOT) &&
11208 (bgp->as < UINT16_MAX)))
11209 vty_out(vty, "%u", bgp->as);
11210 else {
11211 vty_out(vty, "\"");
11212 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11213 vty_out(vty, "\"");
11214 }
11215 vty_out(vty, ",\n \"routes\": { ");
11216 if (rd) {
11217 vty_out(vty, " \"routeDistinguishers\" : {");
11218 ++*json_header_depth;
11219 }
11220 }
11221
11222 if (use_json && rd) {
11223 vty_out(vty, " \"%s\" : { ", rd);
11224 }
11225
11226 /* Check for 'json detail', where we need header output once per dest */
11227 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11228 type != bgp_show_type_damp_neighbor &&
11229 type != bgp_show_type_flap_statistics &&
11230 type != bgp_show_type_flap_neighbor)
11231 json_detail_header = true;
11232
11233 /* Start processing of routes. */
11234 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11235 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11236 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11237 bool json_detail_header_used = false;
11238
11239 pi = bgp_dest_get_bgp_path_info(dest);
11240 if (pi == NULL)
11241 continue;
11242
11243 display = 0;
11244 if (use_json)
11245 json_paths = json_object_new_array();
11246 else
11247 json_paths = NULL;
11248
11249 for (; pi; pi = pi->next) {
11250 struct community *picomm = NULL;
11251
11252 picomm = bgp_attr_get_community(pi->attr);
11253
11254 total_count++;
11255
11256 if (type == bgp_show_type_prefix_version) {
11257 uint32_t version =
11258 strtoul(output_arg, NULL, 10);
11259 if (dest->version < version)
11260 continue;
11261 }
11262
11263 if (type == bgp_show_type_community_alias) {
11264 char *alias = output_arg;
11265 char **communities;
11266 int num;
11267 bool found = false;
11268
11269 if (picomm) {
11270 frrstr_split(picomm->str, " ",
11271 &communities, &num);
11272 for (int i = 0; i < num; i++) {
11273 const char *com2alias =
11274 bgp_community2alias(
11275 communities[i]);
11276 if (!found
11277 && strcmp(alias, com2alias)
11278 == 0)
11279 found = true;
11280 XFREE(MTYPE_TMP,
11281 communities[i]);
11282 }
11283 XFREE(MTYPE_TMP, communities);
11284 }
11285
11286 if (!found &&
11287 bgp_attr_get_lcommunity(pi->attr)) {
11288 frrstr_split(bgp_attr_get_lcommunity(
11289 pi->attr)
11290 ->str,
11291 " ", &communities, &num);
11292 for (int i = 0; i < num; i++) {
11293 const char *com2alias =
11294 bgp_community2alias(
11295 communities[i]);
11296 if (!found
11297 && strcmp(alias, com2alias)
11298 == 0)
11299 found = true;
11300 XFREE(MTYPE_TMP,
11301 communities[i]);
11302 }
11303 XFREE(MTYPE_TMP, communities);
11304 }
11305
11306 if (!found)
11307 continue;
11308 }
11309
11310 if (type == bgp_show_type_rpki) {
11311 if (dest_p->family == AF_INET
11312 || dest_p->family == AF_INET6)
11313 rpki_curr_state = hook_call(
11314 bgp_rpki_prefix_status,
11315 pi->peer, pi->attr, dest_p);
11316 if (rpki_target_state != RPKI_NOT_BEING_USED
11317 && rpki_curr_state != rpki_target_state)
11318 continue;
11319 }
11320
11321 if (type == bgp_show_type_flap_statistics
11322 || type == bgp_show_type_flap_neighbor
11323 || type == bgp_show_type_dampend_paths
11324 || type == bgp_show_type_damp_neighbor) {
11325 if (!(pi->extra && pi->extra->damp_info))
11326 continue;
11327 }
11328 if (type == bgp_show_type_regexp) {
11329 regex_t *regex = output_arg;
11330
11331 if (bgp_regexec(regex, pi->attr->aspath)
11332 == REG_NOMATCH)
11333 continue;
11334 }
11335 if (type == bgp_show_type_prefix_list) {
11336 struct prefix_list *plist = output_arg;
11337
11338 if (prefix_list_apply(plist, dest_p)
11339 != PREFIX_PERMIT)
11340 continue;
11341 }
11342 if (type == bgp_show_type_access_list) {
11343 struct access_list *alist = output_arg;
11344
11345 if (access_list_apply(alist, dest_p) !=
11346 FILTER_PERMIT)
11347 continue;
11348 }
11349 if (type == bgp_show_type_filter_list) {
11350 struct as_list *as_list = output_arg;
11351
11352 if (as_list_apply(as_list, pi->attr->aspath)
11353 != AS_FILTER_PERMIT)
11354 continue;
11355 }
11356 if (type == bgp_show_type_route_map) {
11357 struct route_map *rmap = output_arg;
11358 struct bgp_path_info path;
11359 struct bgp_path_info_extra extra;
11360 struct attr dummy_attr = {};
11361 route_map_result_t ret;
11362
11363 dummy_attr = *pi->attr;
11364
11365 prep_for_rmap_apply(&path, &extra, dest, pi,
11366 pi->peer, &dummy_attr);
11367
11368 ret = route_map_apply(rmap, dest_p, &path);
11369 bgp_attr_flush(&dummy_attr);
11370 if (ret == RMAP_DENYMATCH)
11371 continue;
11372 }
11373 if (type == bgp_show_type_neighbor
11374 || type == bgp_show_type_flap_neighbor
11375 || type == bgp_show_type_damp_neighbor) {
11376 union sockunion *su = output_arg;
11377
11378 if (pi->peer == NULL
11379 || pi->peer->su_remote == NULL
11380 || !sockunion_same(pi->peer->su_remote, su))
11381 continue;
11382 }
11383 if (type == bgp_show_type_cidr_only) {
11384 uint32_t destination;
11385
11386 destination = ntohl(dest_p->u.prefix4.s_addr);
11387 if (IN_CLASSC(destination)
11388 && dest_p->prefixlen == 24)
11389 continue;
11390 if (IN_CLASSB(destination)
11391 && dest_p->prefixlen == 16)
11392 continue;
11393 if (IN_CLASSA(destination)
11394 && dest_p->prefixlen == 8)
11395 continue;
11396 }
11397 if (type == bgp_show_type_prefix_longer) {
11398 p = output_arg;
11399 if (!prefix_match(p, dest_p))
11400 continue;
11401 }
11402 if (type == bgp_show_type_community_all) {
11403 if (!picomm)
11404 continue;
11405 }
11406 if (type == bgp_show_type_community) {
11407 struct community *com = output_arg;
11408
11409 if (!picomm || !community_match(picomm, com))
11410 continue;
11411 }
11412 if (type == bgp_show_type_community_exact) {
11413 struct community *com = output_arg;
11414
11415 if (!picomm || !community_cmp(picomm, com))
11416 continue;
11417 }
11418 if (type == bgp_show_type_community_list) {
11419 struct community_list *list = output_arg;
11420
11421 if (!community_list_match(picomm, list))
11422 continue;
11423 }
11424 if (type == bgp_show_type_community_list_exact) {
11425 struct community_list *list = output_arg;
11426
11427 if (!community_list_exact_match(picomm, list))
11428 continue;
11429 }
11430 if (type == bgp_show_type_lcommunity) {
11431 struct lcommunity *lcom = output_arg;
11432
11433 if (!bgp_attr_get_lcommunity(pi->attr) ||
11434 !lcommunity_match(
11435 bgp_attr_get_lcommunity(pi->attr),
11436 lcom))
11437 continue;
11438 }
11439
11440 if (type == bgp_show_type_lcommunity_exact) {
11441 struct lcommunity *lcom = output_arg;
11442
11443 if (!bgp_attr_get_lcommunity(pi->attr) ||
11444 !lcommunity_cmp(
11445 bgp_attr_get_lcommunity(pi->attr),
11446 lcom))
11447 continue;
11448 }
11449 if (type == bgp_show_type_lcommunity_list) {
11450 struct community_list *list = output_arg;
11451
11452 if (!lcommunity_list_match(
11453 bgp_attr_get_lcommunity(pi->attr),
11454 list))
11455 continue;
11456 }
11457 if (type
11458 == bgp_show_type_lcommunity_list_exact) {
11459 struct community_list *list = output_arg;
11460
11461 if (!lcommunity_list_exact_match(
11462 bgp_attr_get_lcommunity(pi->attr),
11463 list))
11464 continue;
11465 }
11466 if (type == bgp_show_type_lcommunity_all) {
11467 if (!bgp_attr_get_lcommunity(pi->attr))
11468 continue;
11469 }
11470 if (type == bgp_show_type_dampend_paths
11471 || type == bgp_show_type_damp_neighbor) {
11472 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11473 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11474 continue;
11475 }
11476 if (type == bgp_show_type_self_originated) {
11477 if (pi->peer != bgp->peer_self)
11478 continue;
11479 }
11480
11481 if (!use_json && header) {
11482 vty_out(vty,
11483 "BGP table version is %" PRIu64
11484 ", local router ID is %pI4, vrf id ",
11485 table->version, &bgp->router_id);
11486 if (bgp->vrf_id == VRF_UNKNOWN)
11487 vty_out(vty, "%s", VRFID_NONE_STR);
11488 else
11489 vty_out(vty, "%u", bgp->vrf_id);
11490 vty_out(vty, "\n");
11491 vty_out(vty, "Default local pref %u, ",
11492 bgp->default_local_pref);
11493 vty_out(vty, "local AS ");
11494 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11495 &bgp->as);
11496 vty_out(vty, "\n");
11497 if (!detail_routes) {
11498 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11499 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11500 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11501 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11502 }
11503 if (type == bgp_show_type_dampend_paths
11504 || type == bgp_show_type_damp_neighbor)
11505 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11506 else if (type == bgp_show_type_flap_statistics
11507 || type == bgp_show_type_flap_neighbor)
11508 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11509 else if (!detail_routes)
11510 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11511 : BGP_SHOW_HEADER));
11512 header = false;
11513
11514 }
11515 if (rd != NULL && !display && !output_count) {
11516 if (!use_json)
11517 vty_out(vty,
11518 "Route Distinguisher: %s\n",
11519 rd);
11520 }
11521 if (type == bgp_show_type_dampend_paths
11522 || type == bgp_show_type_damp_neighbor)
11523 damp_route_vty_out(vty, dest_p, pi, display,
11524 AFI_IP, safi, use_json,
11525 json_paths);
11526 else if (type == bgp_show_type_flap_statistics
11527 || type == bgp_show_type_flap_neighbor)
11528 flap_route_vty_out(vty, dest_p, pi, display,
11529 AFI_IP, safi, use_json,
11530 json_paths);
11531 else {
11532 if (detail_routes || detail_json) {
11533 const struct prefix_rd *prd = NULL;
11534
11535 if (dest->pdest)
11536 prd = bgp_rd_from_dest(
11537 dest->pdest, safi);
11538
11539 if (!use_json)
11540 route_vty_out_detail_header(
11541 vty, bgp, dest,
11542 bgp_dest_get_prefix(
11543 dest),
11544 prd, table->afi, safi,
11545 NULL, false);
11546
11547 route_vty_out_detail(
11548 vty, bgp, dest, dest_p, pi,
11549 family2afi(dest_p->family),
11550 safi, RPKI_NOT_BEING_USED,
11551 json_paths);
11552 } else {
11553 route_vty_out(vty, dest_p, pi, display,
11554 safi, json_paths, wide);
11555 }
11556 }
11557 display++;
11558 }
11559
11560 if (display) {
11561 output_count++;
11562 if (!use_json)
11563 continue;
11564
11565 /* encode prefix */
11566 if (dest_p->family == AF_FLOWSPEC) {
11567 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11568
11569
11570 bgp_fs_nlri_get_string(
11571 (unsigned char *)
11572 dest_p->u.prefix_flowspec.ptr,
11573 dest_p->u.prefix_flowspec.prefixlen,
11574 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11575 family2afi(dest_p->u
11576 .prefix_flowspec.family));
11577 if (first)
11578 vty_out(vty, "\"%s/%d\": ", retstr,
11579 dest_p->u.prefix_flowspec
11580 .prefixlen);
11581 else
11582 vty_out(vty, ",\"%s/%d\": ", retstr,
11583 dest_p->u.prefix_flowspec
11584 .prefixlen);
11585 } else {
11586 if (first)
11587 vty_out(vty, "\"%pFX\": ", dest_p);
11588 else
11589 vty_out(vty, ",\"%pFX\": ", dest_p);
11590 }
11591
11592 if (json_detail_header && json_paths != NULL) {
11593 const struct prefix_rd *prd;
11594
11595 vty_out(vty, "{\n");
11596
11597 prd = bgp_rd_from_dest(dest, safi);
11598
11599 route_vty_out_detail_header(
11600 vty, bgp, dest,
11601 bgp_dest_get_prefix(dest), prd,
11602 table->afi, safi, json_paths, true);
11603
11604 vty_out(vty, "\"paths\": ");
11605 json_detail_header_used = true;
11606 }
11607
11608 /*
11609 * We are using no_pretty here because under
11610 * extremely high settings( say lots and lots of
11611 * routes with lots and lots of ways to reach
11612 * that route via different paths ) this can
11613 * save several minutes of output when FRR
11614 * is run on older cpu's or more underperforming
11615 * routers out there
11616 */
11617 vty_json_no_pretty(vty, json_paths);
11618
11619 if (json_detail_header_used)
11620 vty_out(vty, "} ");
11621
11622 json_paths = NULL;
11623 first = 0;
11624 } else
11625 json_object_free(json_paths);
11626 }
11627
11628 if (output_cum) {
11629 output_count += *output_cum;
11630 *output_cum = output_count;
11631 }
11632 if (total_cum) {
11633 total_count += *total_cum;
11634 *total_cum = total_count;
11635 }
11636 if (use_json) {
11637 if (rd) {
11638 vty_out(vty, " }%s ", (is_last ? "" : ","));
11639 }
11640 if (is_last) {
11641 unsigned long i;
11642 for (i = 0; i < *json_header_depth; ++i)
11643 vty_out(vty, " } ");
11644 if (!all)
11645 vty_out(vty, "\n");
11646 }
11647 } else {
11648 if (is_last) {
11649 /* No route is displayed */
11650 if (output_count == 0) {
11651 if (type == bgp_show_type_normal)
11652 vty_out(vty,
11653 "No BGP prefixes displayed, %ld exist\n",
11654 total_count);
11655 } else
11656 vty_out(vty,
11657 "\nDisplayed %ld routes and %ld total paths\n",
11658 output_count, total_count);
11659 }
11660 }
11661
11662 return CMD_SUCCESS;
11663 }
11664
11665 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11666 struct bgp_table *table, struct prefix_rd *prd_match,
11667 enum bgp_show_type type, void *output_arg,
11668 uint16_t show_flags)
11669 {
11670 struct bgp_dest *dest, *next;
11671 unsigned long output_cum = 0;
11672 unsigned long total_cum = 0;
11673 unsigned long json_header_depth = 0;
11674 struct bgp_table *itable;
11675 bool show_msg;
11676 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11677
11678 show_msg = (!use_json && type == bgp_show_type_normal);
11679
11680 for (dest = bgp_table_top(table); dest; dest = next) {
11681 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11682
11683 next = bgp_route_next(dest);
11684 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11685 continue;
11686
11687 itable = bgp_dest_get_bgp_table_info(dest);
11688 if (itable != NULL) {
11689 struct prefix_rd prd;
11690 char rd[RD_ADDRSTRLEN];
11691
11692 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11693 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11694 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11695 rd, next == NULL, &output_cum,
11696 &total_cum, &json_header_depth,
11697 show_flags, RPKI_NOT_BEING_USED);
11698 if (next == NULL)
11699 show_msg = false;
11700 }
11701 }
11702 if (show_msg) {
11703 if (output_cum == 0)
11704 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11705 total_cum);
11706 else
11707 vty_out(vty,
11708 "\nDisplayed %ld routes and %ld total paths\n",
11709 output_cum, total_cum);
11710 } else {
11711 if (use_json && output_cum == 0)
11712 vty_out(vty, "{}\n");
11713 }
11714 return CMD_SUCCESS;
11715 }
11716
11717 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11718 enum bgp_show_type type, void *output_arg,
11719 uint16_t show_flags, enum rpki_states rpki_target_state)
11720 {
11721 struct bgp_table *table;
11722 unsigned long json_header_depth = 0;
11723 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11724
11725 if (bgp == NULL) {
11726 bgp = bgp_get_default();
11727 }
11728
11729 if (bgp == NULL) {
11730 if (!use_json)
11731 vty_out(vty, "No BGP process is configured\n");
11732 else
11733 vty_out(vty, "{}\n");
11734 return CMD_WARNING;
11735 }
11736
11737 /* Labeled-unicast routes live in the unicast table. */
11738 if (safi == SAFI_LABELED_UNICAST)
11739 safi = SAFI_UNICAST;
11740
11741 table = bgp->rib[afi][safi];
11742 /* use MPLS and ENCAP specific shows until they are merged */
11743 if (safi == SAFI_MPLS_VPN) {
11744 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11745 output_arg, show_flags);
11746 }
11747
11748 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11749 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11750 output_arg, use_json,
11751 1, NULL, NULL);
11752 }
11753
11754 if (safi == SAFI_EVPN)
11755 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11756
11757 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11758 NULL, NULL, &json_header_depth, show_flags,
11759 rpki_target_state);
11760 }
11761
11762 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11763 safi_t safi, uint16_t show_flags)
11764 {
11765 struct listnode *node, *nnode;
11766 struct bgp *bgp;
11767 int is_first = 1;
11768 bool route_output = false;
11769 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11770
11771 if (use_json)
11772 vty_out(vty, "{\n");
11773
11774 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11775 route_output = true;
11776 if (use_json) {
11777 if (!is_first)
11778 vty_out(vty, ",\n");
11779 else
11780 is_first = 0;
11781
11782 vty_out(vty, "\"%s\":",
11783 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11784 ? VRF_DEFAULT_NAME
11785 : bgp->name);
11786 } else {
11787 vty_out(vty, "\nInstance %s:\n",
11788 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11789 ? VRF_DEFAULT_NAME
11790 : bgp->name);
11791 }
11792 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11793 show_flags, RPKI_NOT_BEING_USED);
11794 }
11795
11796 if (use_json)
11797 vty_out(vty, "}\n");
11798 else if (!route_output)
11799 vty_out(vty, "%% BGP instance not found\n");
11800 }
11801
11802 /* Header of detailed BGP route information */
11803 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11804 struct bgp_dest *dest, const struct prefix *p,
11805 const struct prefix_rd *prd, afi_t afi,
11806 safi_t safi, json_object *json,
11807 bool incremental_print)
11808 {
11809 struct bgp_path_info *pi;
11810 struct peer *peer;
11811 struct listnode *node, *nnode;
11812 char buf1[RD_ADDRSTRLEN];
11813 int count = 0;
11814 int best = 0;
11815 int suppress = 0;
11816 int accept_own = 0;
11817 int route_filter_translated_v4 = 0;
11818 int route_filter_v4 = 0;
11819 int route_filter_translated_v6 = 0;
11820 int route_filter_v6 = 0;
11821 int llgr_stale = 0;
11822 int no_llgr = 0;
11823 int accept_own_nexthop = 0;
11824 int blackhole = 0;
11825 int no_export = 0;
11826 int no_advertise = 0;
11827 int local_as = 0;
11828 int no_peer = 0;
11829 int first = 1;
11830 int has_valid_label = 0;
11831 mpls_label_t label = 0;
11832 json_object *json_adv_to = NULL;
11833 uint32_t ttl = 0;
11834 uint32_t bos = 0;
11835 uint32_t exp = 0;
11836
11837 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11838
11839 has_valid_label = bgp_is_valid_label(&label);
11840
11841 if (safi == SAFI_EVPN) {
11842 if (!json) {
11843 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11844 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11845 bgp->asnotation)
11846 : "",
11847 prd ? ":" : "", (struct prefix_evpn *)p);
11848 } else {
11849 json_object_string_add(
11850 json, "rd",
11851 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11852 bgp->asnotation)
11853 : "");
11854 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11855 }
11856 } else {
11857 if (!json) {
11858 vty_out(vty,
11859 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11860 "\n",
11861 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11862 ? prefix_rd2str(prd, buf1,
11863 sizeof(buf1),
11864 bgp->asnotation)
11865 : ""),
11866 safi == SAFI_MPLS_VPN ? ":" : "", p,
11867 dest->version);
11868
11869 } else {
11870 if (incremental_print) {
11871 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11872 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11873 dest->version);
11874 } else {
11875 json_object_string_addf(json, "prefix", "%pFX",
11876 p);
11877 json_object_int_add(json, "version",
11878 dest->version);
11879 }
11880 }
11881 }
11882
11883 if (has_valid_label) {
11884 if (json) {
11885 if (incremental_print)
11886 vty_out(vty, "\"localLabel\": \"%u\",\n",
11887 label);
11888 else
11889 json_object_int_add(json, "localLabel", label);
11890 } else
11891 vty_out(vty, "Local label: %d\n", label);
11892 }
11893
11894 if (!json)
11895 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11896 vty_out(vty, "not allocated\n");
11897
11898 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11899 struct community *picomm = NULL;
11900
11901 picomm = bgp_attr_get_community(pi->attr);
11902
11903 count++;
11904 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11905 best = count;
11906 if (bgp_path_suppressed(pi))
11907 suppress = 1;
11908
11909 if (!picomm)
11910 continue;
11911
11912 no_advertise += community_include(
11913 picomm, COMMUNITY_NO_ADVERTISE);
11914 no_export +=
11915 community_include(picomm, COMMUNITY_NO_EXPORT);
11916 local_as +=
11917 community_include(picomm, COMMUNITY_LOCAL_AS);
11918 accept_own +=
11919 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11920 route_filter_translated_v4 += community_include(
11921 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11922 route_filter_translated_v6 += community_include(
11923 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11924 route_filter_v4 += community_include(
11925 picomm, COMMUNITY_ROUTE_FILTER_v4);
11926 route_filter_v6 += community_include(
11927 picomm, COMMUNITY_ROUTE_FILTER_v6);
11928 llgr_stale +=
11929 community_include(picomm, COMMUNITY_LLGR_STALE);
11930 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11931 accept_own_nexthop += community_include(
11932 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11933 blackhole +=
11934 community_include(picomm, COMMUNITY_BLACKHOLE);
11935 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11936 }
11937 }
11938
11939 if (!json) {
11940 vty_out(vty, "Paths: (%d available", count);
11941 if (best) {
11942 vty_out(vty, ", best #%d", best);
11943 if (safi == SAFI_UNICAST) {
11944 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11945 vty_out(vty, ", table %s",
11946 VRF_DEFAULT_NAME);
11947 else
11948 vty_out(vty, ", vrf %s",
11949 bgp->name);
11950 }
11951 } else
11952 vty_out(vty, ", no best path");
11953
11954 if (accept_own)
11955 vty_out(vty,
11956 ", accept own local route exported and imported in different VRF");
11957 else if (route_filter_translated_v4)
11958 vty_out(vty,
11959 ", mark translated RTs for VPNv4 route filtering");
11960 else if (route_filter_v4)
11961 vty_out(vty,
11962 ", attach RT as-is for VPNv4 route filtering");
11963 else if (route_filter_translated_v6)
11964 vty_out(vty,
11965 ", mark translated RTs for VPNv6 route filtering");
11966 else if (route_filter_v6)
11967 vty_out(vty,
11968 ", attach RT as-is for VPNv6 route filtering");
11969 else if (llgr_stale)
11970 vty_out(vty,
11971 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11972 else if (no_llgr)
11973 vty_out(vty,
11974 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11975 else if (accept_own_nexthop)
11976 vty_out(vty,
11977 ", accept local nexthop");
11978 else if (blackhole)
11979 vty_out(vty, ", inform peer to blackhole prefix");
11980 else if (no_export)
11981 vty_out(vty, ", not advertised to EBGP peer");
11982 else if (no_advertise)
11983 vty_out(vty, ", not advertised to any peer");
11984 else if (local_as)
11985 vty_out(vty, ", not advertised outside local AS");
11986 else if (no_peer)
11987 vty_out(vty,
11988 ", inform EBGP peer not to advertise to their EBGP peers");
11989
11990 if (suppress)
11991 vty_out(vty,
11992 ", Advertisements suppressed by an aggregate.");
11993 vty_out(vty, ")\n");
11994 }
11995
11996 /* If we are not using addpath then we can display Advertised to and
11997 * that will
11998 * show what peers we advertised the bestpath to. If we are using
11999 * addpath
12000 * though then we must display Advertised to on a path-by-path basis. */
12001 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12002 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12003 if (bgp_adj_out_lookup(peer, dest, 0)) {
12004 if (json && !json_adv_to)
12005 json_adv_to = json_object_new_object();
12006
12007 route_vty_out_advertised_to(
12008 vty, peer, &first,
12009 " Advertised to non peer-group peers:\n ",
12010 json_adv_to);
12011 }
12012 }
12013
12014 if (json && json_adv_to) {
12015 if (incremental_print) {
12016 vty_out(vty, "\"advertisedTo\": ");
12017 vty_json(vty, json_adv_to);
12018 vty_out(vty, ",");
12019 } else
12020 json_object_object_add(json, "advertisedTo",
12021 json_adv_to);
12022 } else {
12023 if (!json && first)
12024 vty_out(vty, " Not advertised to any peer");
12025 vty_out(vty, "\n");
12026 }
12027 }
12028 }
12029
12030 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12031 struct bgp_dest *bgp_node, struct vty *vty,
12032 struct bgp *bgp, afi_t afi, safi_t safi,
12033 json_object *json, enum bgp_path_type pathtype,
12034 int *display, enum rpki_states rpki_target_state)
12035 {
12036 struct bgp_path_info *pi;
12037 int header = 1;
12038 json_object *json_header = NULL;
12039 json_object *json_paths = NULL;
12040 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12041
12042 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12043 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12044
12045 if (p->family == AF_INET || p->family == AF_INET6)
12046 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12047 pi->peer, pi->attr, p);
12048
12049 if (rpki_target_state != RPKI_NOT_BEING_USED
12050 && rpki_curr_state != rpki_target_state)
12051 continue;
12052
12053 if (json && !json_paths) {
12054 /* Instantiate json_paths only if path is valid */
12055 json_paths = json_object_new_array();
12056 if (pfx_rd)
12057 json_header = json_object_new_object();
12058 else
12059 json_header = json;
12060 }
12061
12062 if (header) {
12063 route_vty_out_detail_header(
12064 vty, bgp, bgp_node,
12065 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12066 safi, json_header, false);
12067 header = 0;
12068 }
12069 (*display)++;
12070
12071 if (pathtype == BGP_PATH_SHOW_ALL
12072 || (pathtype == BGP_PATH_SHOW_BESTPATH
12073 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12074 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12075 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12076 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12077 route_vty_out_detail(vty, bgp, bgp_node,
12078 bgp_dest_get_prefix(bgp_node), pi,
12079 AFI_IP, safi, rpki_curr_state,
12080 json_paths);
12081 }
12082
12083 if (json && json_paths) {
12084 json_object_object_add(json_header, "paths", json_paths);
12085
12086 if (pfx_rd)
12087 json_object_object_addf(
12088 json, json_header,
12089 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12090 }
12091 }
12092
12093 /*
12094 * Return rd based on safi
12095 */
12096 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12097 safi_t safi)
12098 {
12099 switch (safi) {
12100 case SAFI_MPLS_VPN:
12101 case SAFI_ENCAP:
12102 case SAFI_EVPN:
12103 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12104 case SAFI_UNSPEC:
12105 case SAFI_UNICAST:
12106 case SAFI_MULTICAST:
12107 case SAFI_LABELED_UNICAST:
12108 case SAFI_FLOWSPEC:
12109 case SAFI_MAX:
12110 return NULL;
12111 }
12112
12113 assert(!"Reached end of function when we were not expecting it");
12114 }
12115
12116 /* Display specified route of BGP table. */
12117 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12118 struct bgp_table *rib, const char *ip_str,
12119 afi_t afi, safi_t safi,
12120 enum rpki_states rpki_target_state,
12121 struct prefix_rd *prd, int prefix_check,
12122 enum bgp_path_type pathtype, bool use_json)
12123 {
12124 int ret;
12125 int display = 0;
12126 struct prefix match;
12127 struct bgp_dest *dest;
12128 struct bgp_dest *rm;
12129 struct bgp_table *table;
12130 json_object *json = NULL;
12131 json_object *json_paths = NULL;
12132
12133 /* Check IP address argument. */
12134 ret = str2prefix(ip_str, &match);
12135 if (!ret) {
12136 vty_out(vty, "address is malformed\n");
12137 return CMD_WARNING;
12138 }
12139
12140 match.family = afi2family(afi);
12141
12142 if (use_json)
12143 json = json_object_new_object();
12144
12145 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12146 for (dest = bgp_table_top(rib); dest;
12147 dest = bgp_route_next(dest)) {
12148 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12149
12150 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12151 continue;
12152 table = bgp_dest_get_bgp_table_info(dest);
12153 if (!table)
12154 continue;
12155
12156 rm = bgp_node_match(table, &match);
12157 if (rm == NULL)
12158 continue;
12159
12160 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12161 if (prefix_check
12162 && rm_p->prefixlen != match.prefixlen) {
12163 bgp_dest_unlock_node(rm);
12164 continue;
12165 }
12166
12167 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12168 bgp, afi, safi, json, pathtype,
12169 &display, rpki_target_state);
12170
12171 bgp_dest_unlock_node(rm);
12172 }
12173 } else if (safi == SAFI_EVPN) {
12174 struct bgp_dest *longest_pfx;
12175 bool is_exact_pfxlen_match = false;
12176
12177 for (dest = bgp_table_top(rib); dest;
12178 dest = bgp_route_next(dest)) {
12179 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12180
12181 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12182 continue;
12183 table = bgp_dest_get_bgp_table_info(dest);
12184 if (!table)
12185 continue;
12186
12187 longest_pfx = NULL;
12188 is_exact_pfxlen_match = false;
12189 /*
12190 * Search through all the prefixes for a match. The
12191 * pfx's are enumerated in ascending order of pfxlens.
12192 * So, the last pfx match is the longest match. Set
12193 * is_exact_pfxlen_match when we get exact pfxlen match
12194 */
12195 for (rm = bgp_table_top(table); rm;
12196 rm = bgp_route_next(rm)) {
12197 const struct prefix *rm_p =
12198 bgp_dest_get_prefix(rm);
12199 /*
12200 * Get prefixlen of the ip-prefix within type5
12201 * evpn route
12202 */
12203 if (evpn_type5_prefix_match(rm_p, &match)
12204 && rm->info) {
12205 longest_pfx = rm;
12206 int type5_pfxlen =
12207 bgp_evpn_get_type5_prefixlen(
12208 rm_p);
12209 if (type5_pfxlen == match.prefixlen) {
12210 is_exact_pfxlen_match = true;
12211 bgp_dest_unlock_node(rm);
12212 break;
12213 }
12214 }
12215 }
12216
12217 if (!longest_pfx)
12218 continue;
12219
12220 if (prefix_check && !is_exact_pfxlen_match)
12221 continue;
12222
12223 rm = longest_pfx;
12224 bgp_dest_lock_node(rm);
12225
12226 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12227 bgp, afi, safi, json, pathtype,
12228 &display, rpki_target_state);
12229
12230 bgp_dest_unlock_node(rm);
12231 }
12232 } else if (safi == SAFI_FLOWSPEC) {
12233 if (use_json)
12234 json_paths = json_object_new_array();
12235
12236 display = bgp_flowspec_display_match_per_ip(afi, rib,
12237 &match, prefix_check,
12238 vty,
12239 use_json,
12240 json_paths);
12241 if (use_json) {
12242 if (display)
12243 json_object_object_add(json, "paths",
12244 json_paths);
12245 else
12246 json_object_free(json_paths);
12247 }
12248 } else {
12249 dest = bgp_node_match(rib, &match);
12250 if (dest != NULL) {
12251 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12252 if (!prefix_check
12253 || dest_p->prefixlen == match.prefixlen) {
12254 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12255 safi, json, pathtype,
12256 &display, rpki_target_state);
12257 }
12258
12259 bgp_dest_unlock_node(dest);
12260 }
12261 }
12262
12263 if (use_json) {
12264 vty_json(vty, json);
12265 } else {
12266 if (!display) {
12267 vty_out(vty, "%% Network not in table\n");
12268 return CMD_WARNING;
12269 }
12270 }
12271
12272 return CMD_SUCCESS;
12273 }
12274
12275 /* Display specified route of Main RIB */
12276 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12277 afi_t afi, safi_t safi, struct prefix_rd *prd,
12278 int prefix_check, enum bgp_path_type pathtype,
12279 enum rpki_states rpki_target_state, bool use_json)
12280 {
12281 if (!bgp) {
12282 bgp = bgp_get_default();
12283 if (!bgp) {
12284 if (!use_json)
12285 vty_out(vty, "No BGP process is configured\n");
12286 else
12287 vty_out(vty, "{}\n");
12288 return CMD_WARNING;
12289 }
12290 }
12291
12292 /* labeled-unicast routes live in the unicast table */
12293 if (safi == SAFI_LABELED_UNICAST)
12294 safi = SAFI_UNICAST;
12295
12296 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12297 afi, safi, rpki_target_state, prd,
12298 prefix_check, pathtype, use_json);
12299 }
12300
12301 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12302 struct cmd_token **argv, bool exact, afi_t afi,
12303 safi_t safi, bool uj)
12304 {
12305 struct lcommunity *lcom;
12306 struct buffer *b;
12307 int i;
12308 char *str;
12309 int first = 0;
12310 uint16_t show_flags = 0;
12311 int ret;
12312
12313 if (uj)
12314 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12315
12316 b = buffer_new(1024);
12317 for (i = 0; i < argc; i++) {
12318 if (first)
12319 buffer_putc(b, ' ');
12320 else {
12321 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12322 first = 1;
12323 buffer_putstr(b, argv[i]->arg);
12324 }
12325 }
12326 }
12327 buffer_putc(b, '\0');
12328
12329 str = buffer_getstr(b);
12330 buffer_free(b);
12331
12332 lcom = lcommunity_str2com(str);
12333 XFREE(MTYPE_TMP, str);
12334 if (!lcom) {
12335 vty_out(vty, "%% Large-community malformed\n");
12336 return CMD_WARNING;
12337 }
12338
12339 ret = bgp_show(vty, bgp, afi, safi,
12340 (exact ? bgp_show_type_lcommunity_exact
12341 : bgp_show_type_lcommunity),
12342 lcom, show_flags, RPKI_NOT_BEING_USED);
12343
12344 lcommunity_free(&lcom);
12345 return ret;
12346 }
12347
12348 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12349 const char *lcom, bool exact, afi_t afi,
12350 safi_t safi, bool uj)
12351 {
12352 struct community_list *list;
12353 uint16_t show_flags = 0;
12354
12355 if (uj)
12356 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12357
12358
12359 list = community_list_lookup(bgp_clist, lcom, 0,
12360 LARGE_COMMUNITY_LIST_MASTER);
12361 if (list == NULL) {
12362 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12363 lcom);
12364 return CMD_WARNING;
12365 }
12366
12367 return bgp_show(vty, bgp, afi, safi,
12368 (exact ? bgp_show_type_lcommunity_list_exact
12369 : bgp_show_type_lcommunity_list),
12370 list, show_flags, RPKI_NOT_BEING_USED);
12371 }
12372
12373 DEFUN (show_ip_bgp_large_community_list,
12374 show_ip_bgp_large_community_list_cmd,
12375 "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]",
12376 SHOW_STR
12377 IP_STR
12378 BGP_STR
12379 BGP_INSTANCE_HELP_STR
12380 BGP_AFI_HELP_STR
12381 BGP_SAFI_WITH_LABEL_HELP_STR
12382 "Display routes matching the large-community-list\n"
12383 "large-community-list number\n"
12384 "large-community-list name\n"
12385 "Exact match of the large-communities\n"
12386 JSON_STR)
12387 {
12388 afi_t afi = AFI_IP6;
12389 safi_t safi = SAFI_UNICAST;
12390 int idx = 0;
12391 bool exact_match = 0;
12392 struct bgp *bgp = NULL;
12393 bool uj = use_json(argc, argv);
12394
12395 if (uj)
12396 argc--;
12397
12398 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12399 &bgp, uj);
12400 if (!idx)
12401 return CMD_WARNING;
12402
12403 argv_find(argv, argc, "large-community-list", &idx);
12404
12405 const char *clist_number_or_name = argv[++idx]->arg;
12406
12407 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12408 exact_match = 1;
12409
12410 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12411 exact_match, afi, safi, uj);
12412 }
12413 DEFUN (show_ip_bgp_large_community,
12414 show_ip_bgp_large_community_cmd,
12415 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12416 SHOW_STR
12417 IP_STR
12418 BGP_STR
12419 BGP_INSTANCE_HELP_STR
12420 BGP_AFI_HELP_STR
12421 BGP_SAFI_WITH_LABEL_HELP_STR
12422 "Display routes matching the large-communities\n"
12423 "List of large-community numbers\n"
12424 "Exact match of the large-communities\n"
12425 JSON_STR)
12426 {
12427 afi_t afi = AFI_IP6;
12428 safi_t safi = SAFI_UNICAST;
12429 int idx = 0;
12430 bool exact_match = 0;
12431 struct bgp *bgp = NULL;
12432 bool uj = use_json(argc, argv);
12433 uint16_t show_flags = 0;
12434
12435 if (uj) {
12436 argc--;
12437 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12438 }
12439
12440 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12441 &bgp, uj);
12442 if (!idx)
12443 return CMD_WARNING;
12444
12445 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12446 if (argv_find(argv, argc, "exact-match", &idx)) {
12447 argc--;
12448 exact_match = 1;
12449 }
12450 return bgp_show_lcommunity(vty, bgp, argc, argv,
12451 exact_match, afi, safi, uj);
12452 } else
12453 return bgp_show(vty, bgp, afi, safi,
12454 bgp_show_type_lcommunity_all, NULL, show_flags,
12455 RPKI_NOT_BEING_USED);
12456 }
12457
12458 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12459 safi_t safi, struct json_object *json_array);
12460 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12461 safi_t safi, struct json_object *json);
12462
12463
12464 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12465 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12466 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12467 "Display number of prefixes for all afi/safi\n" JSON_STR)
12468 {
12469 bool uj = use_json(argc, argv);
12470 struct bgp *bgp = NULL;
12471 safi_t safi = SAFI_UNICAST;
12472 afi_t afi = AFI_IP6;
12473 int idx = 0;
12474 struct json_object *json_all = NULL;
12475 struct json_object *json_afi_safi = NULL;
12476
12477 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12478 &bgp, false);
12479 if (!idx)
12480 return CMD_WARNING;
12481
12482 if (uj)
12483 json_all = json_object_new_object();
12484
12485 FOREACH_AFI_SAFI (afi, safi) {
12486 /*
12487 * So limit output to those afi/safi pairs that
12488 * actually have something interesting in them
12489 */
12490 if (strmatch(get_afi_safi_str(afi, safi, true),
12491 "Unknown")) {
12492 continue;
12493 }
12494 if (uj) {
12495 json_afi_safi = json_object_new_array();
12496 json_object_object_add(
12497 json_all,
12498 get_afi_safi_str(afi, safi, true),
12499 json_afi_safi);
12500 } else {
12501 json_afi_safi = NULL;
12502 }
12503
12504 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12505 }
12506
12507 if (uj)
12508 vty_json(vty, json_all);
12509
12510 return CMD_SUCCESS;
12511 }
12512
12513 /* BGP route print out function without JSON */
12514 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12515 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12516 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12517 SHOW_STR
12518 IP_STR
12519 BGP_STR
12520 BGP_INSTANCE_HELP_STR
12521 L2VPN_HELP_STR
12522 EVPN_HELP_STR
12523 "BGP RIB advertisement statistics\n"
12524 JSON_STR)
12525 {
12526 afi_t afi = AFI_IP6;
12527 safi_t safi = SAFI_UNICAST;
12528 struct bgp *bgp = NULL;
12529 int idx = 0, ret;
12530 bool uj = use_json(argc, argv);
12531 struct json_object *json_afi_safi = NULL, *json = NULL;
12532
12533 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12534 &bgp, false);
12535 if (!idx)
12536 return CMD_WARNING;
12537
12538 if (uj)
12539 json_afi_safi = json_object_new_array();
12540 else
12541 json_afi_safi = NULL;
12542
12543 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12544
12545 if (uj) {
12546 json = json_object_new_object();
12547 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12548 json_afi_safi);
12549 vty_json(vty, json);
12550 }
12551 return ret;
12552 }
12553
12554 /* BGP route print out function without JSON */
12555 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12556 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12557 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12558 "]]\
12559 statistics [json]",
12560 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12561 BGP_SAFI_WITH_LABEL_HELP_STR
12562 "BGP RIB advertisement statistics\n" JSON_STR)
12563 {
12564 afi_t afi = AFI_IP6;
12565 safi_t safi = SAFI_UNICAST;
12566 struct bgp *bgp = NULL;
12567 int idx = 0, ret;
12568 bool uj = use_json(argc, argv);
12569 struct json_object *json_afi_safi = NULL, *json = NULL;
12570
12571 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12572 &bgp, false);
12573 if (!idx)
12574 return CMD_WARNING;
12575
12576 if (uj)
12577 json_afi_safi = json_object_new_array();
12578 else
12579 json_afi_safi = NULL;
12580
12581 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12582
12583 if (uj) {
12584 json = json_object_new_object();
12585 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12586 json_afi_safi);
12587 vty_json(vty, json);
12588 }
12589 return ret;
12590 }
12591
12592 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12593 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12594 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12595 "]] [all$all] dampening parameters [json]",
12596 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12597 BGP_SAFI_WITH_LABEL_HELP_STR
12598 "Display the entries for all address families\n"
12599 "Display detailed information about dampening\n"
12600 "Display detail of configured dampening parameters\n"
12601 JSON_STR)
12602 {
12603 afi_t afi = AFI_IP6;
12604 safi_t safi = SAFI_UNICAST;
12605 struct bgp *bgp = NULL;
12606 int idx = 0;
12607 uint16_t show_flags = 0;
12608 bool uj = use_json(argc, argv);
12609
12610 if (uj) {
12611 argc--;
12612 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12613 }
12614
12615 /* [<ipv4|ipv6> [all]] */
12616 if (all) {
12617 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12618 if (argv_find(argv, argc, "ipv4", &idx))
12619 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12620
12621 if (argv_find(argv, argc, "ipv6", &idx))
12622 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12623 }
12624
12625 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12626 &bgp, false);
12627 if (!idx)
12628 return CMD_WARNING;
12629
12630 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12631 }
12632
12633 /* BGP route print out function */
12634 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12635 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12636 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12637 "]]\
12638 [all$all]\
12639 [cidr-only\
12640 |dampening <flap-statistics|dampened-paths>\
12641 |community [AA:NN|local-AS|no-advertise|no-export\
12642 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12643 |accept-own|accept-own-nexthop|route-filter-v6\
12644 |route-filter-v4|route-filter-translated-v6\
12645 |route-filter-translated-v4] [exact-match]\
12646 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12647 |filter-list AS_PATH_FILTER_NAME\
12648 |prefix-list WORD\
12649 |access-list ACCESSLIST_NAME\
12650 |route-map RMAP_NAME\
12651 |rpki <invalid|valid|notfound>\
12652 |version (1-4294967295)\
12653 |alias ALIAS_NAME\
12654 |A.B.C.D/M longer-prefixes\
12655 |X:X::X:X/M longer-prefixes\
12656 |"BGP_SELF_ORIG_CMD_STR"\
12657 |detail-routes$detail_routes\
12658 ] [json$uj [detail$detail_json] | wide$wide]",
12659 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12660 BGP_SAFI_WITH_LABEL_HELP_STR
12661 "Display the entries for all address families\n"
12662 "Display only routes with non-natural netmasks\n"
12663 "Display detailed information about dampening\n"
12664 "Display flap statistics of routes\n"
12665 "Display paths suppressed due to dampening\n"
12666 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12667 "Do not send outside local AS (well-known community)\n"
12668 "Do not advertise to any peer (well-known community)\n"
12669 "Do not export to next AS (well-known community)\n"
12670 "Graceful shutdown (well-known community)\n"
12671 "Do not export to any peer (well-known community)\n"
12672 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12673 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12674 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12675 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12676 "Should accept VPN route with local nexthop (well-known community)\n"
12677 "RT VPNv6 route filtering (well-known community)\n"
12678 "RT VPNv4 route filtering (well-known community)\n"
12679 "RT translated VPNv6 route filtering (well-known community)\n"
12680 "RT translated VPNv4 route filtering (well-known community)\n"
12681 "Exact match of the communities\n"
12682 "Community-list number\n"
12683 "Community-list name\n"
12684 "Display routes matching the community-list\n"
12685 "Exact match of the communities\n"
12686 "Display routes conforming to the filter-list\n"
12687 "Regular expression access list name\n"
12688 "Display routes conforming to the prefix-list\n"
12689 "Prefix-list name\n"
12690 "Display routes conforming to the access-list\n"
12691 "Access-list name\n"
12692 "Display routes matching the route-map\n"
12693 "A route-map to match on\n"
12694 "RPKI route types\n"
12695 "A valid path as determined by rpki\n"
12696 "A invalid path as determined by rpki\n"
12697 "A path that has no rpki data\n"
12698 "Display prefixes with matching version numbers\n"
12699 "Version number and above\n"
12700 "Display prefixes with matching BGP community alias\n"
12701 "BGP community alias\n"
12702 "IPv4 prefix\n"
12703 "Display route and more specific routes\n"
12704 "IPv6 prefix\n"
12705 "Display route and more specific routes\n"
12706 BGP_SELF_ORIG_HELP_STR
12707 "Display detailed version of all routes\n"
12708 JSON_STR
12709 "Display detailed version of JSON output\n"
12710 "Increase table width for longer prefixes\n")
12711 {
12712 afi_t afi = AFI_IP6;
12713 safi_t safi = SAFI_UNICAST;
12714 enum bgp_show_type sh_type = bgp_show_type_normal;
12715 void *output_arg = NULL;
12716 struct bgp *bgp = NULL;
12717 int idx = 0;
12718 int exact_match = 0;
12719 char *community = NULL;
12720 bool first = true;
12721 uint16_t show_flags = 0;
12722 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12723 struct prefix p;
12724
12725 if (uj) {
12726 argc--;
12727 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12728 }
12729
12730 if (detail_json)
12731 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12732
12733 if (detail_routes)
12734 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12735
12736 /* [<ipv4|ipv6> [all]] */
12737 if (all) {
12738 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12739
12740 if (argv_find(argv, argc, "ipv4", &idx))
12741 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12742
12743 if (argv_find(argv, argc, "ipv6", &idx))
12744 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12745 }
12746
12747 if (wide)
12748 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12749
12750 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12751 &bgp, uj);
12752 if (!idx)
12753 return CMD_WARNING;
12754
12755 if (argv_find(argv, argc, "cidr-only", &idx))
12756 sh_type = bgp_show_type_cidr_only;
12757
12758 if (argv_find(argv, argc, "dampening", &idx)) {
12759 if (argv_find(argv, argc, "dampened-paths", &idx))
12760 sh_type = bgp_show_type_dampend_paths;
12761 else if (argv_find(argv, argc, "flap-statistics", &idx))
12762 sh_type = bgp_show_type_flap_statistics;
12763 }
12764
12765 if (argv_find(argv, argc, "community", &idx)) {
12766 char *maybecomm = NULL;
12767
12768 if (idx + 1 < argc) {
12769 if (argv[idx + 1]->type == VARIABLE_TKN)
12770 maybecomm = argv[idx + 1]->arg;
12771 else
12772 maybecomm = argv[idx + 1]->text;
12773 }
12774
12775 if (maybecomm && !strmatch(maybecomm, "json")
12776 && !strmatch(maybecomm, "exact-match"))
12777 community = maybecomm;
12778
12779 if (argv_find(argv, argc, "exact-match", &idx))
12780 exact_match = 1;
12781
12782 if (!community)
12783 sh_type = bgp_show_type_community_all;
12784 }
12785
12786 if (argv_find(argv, argc, "community-list", &idx)) {
12787 const char *clist_number_or_name = argv[++idx]->arg;
12788 struct community_list *list;
12789
12790 if (argv_find(argv, argc, "exact-match", &idx))
12791 exact_match = 1;
12792
12793 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12794 COMMUNITY_LIST_MASTER);
12795 if (list == NULL) {
12796 vty_out(vty, "%% %s community-list not found\n",
12797 clist_number_or_name);
12798 return CMD_WARNING;
12799 }
12800
12801 if (exact_match)
12802 sh_type = bgp_show_type_community_list_exact;
12803 else
12804 sh_type = bgp_show_type_community_list;
12805 output_arg = list;
12806 }
12807
12808 if (argv_find(argv, argc, "filter-list", &idx)) {
12809 const char *filter = argv[++idx]->arg;
12810 struct as_list *as_list;
12811
12812 as_list = as_list_lookup(filter);
12813 if (as_list == NULL) {
12814 vty_out(vty, "%% %s AS-path access-list not found\n",
12815 filter);
12816 return CMD_WARNING;
12817 }
12818
12819 sh_type = bgp_show_type_filter_list;
12820 output_arg = as_list;
12821 }
12822
12823 if (argv_find(argv, argc, "prefix-list", &idx)) {
12824 const char *prefix_list_str = argv[++idx]->arg;
12825 struct prefix_list *plist;
12826
12827 plist = prefix_list_lookup(afi, prefix_list_str);
12828 if (plist == NULL) {
12829 vty_out(vty, "%% %s prefix-list not found\n",
12830 prefix_list_str);
12831 return CMD_WARNING;
12832 }
12833
12834 sh_type = bgp_show_type_prefix_list;
12835 output_arg = plist;
12836 }
12837
12838 if (argv_find(argv, argc, "access-list", &idx)) {
12839 const char *access_list_str = argv[++idx]->arg;
12840 struct access_list *alist;
12841
12842 alist = access_list_lookup(afi, access_list_str);
12843 if (!alist) {
12844 vty_out(vty, "%% %s access-list not found\n",
12845 access_list_str);
12846 return CMD_WARNING;
12847 }
12848
12849 sh_type = bgp_show_type_access_list;
12850 output_arg = alist;
12851 }
12852
12853 if (argv_find(argv, argc, "route-map", &idx)) {
12854 const char *rmap_str = argv[++idx]->arg;
12855 struct route_map *rmap;
12856
12857 rmap = route_map_lookup_by_name(rmap_str);
12858 if (!rmap) {
12859 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12860 return CMD_WARNING;
12861 }
12862
12863 sh_type = bgp_show_type_route_map;
12864 output_arg = rmap;
12865 }
12866
12867 if (argv_find(argv, argc, "rpki", &idx)) {
12868 sh_type = bgp_show_type_rpki;
12869 if (argv_find(argv, argc, "valid", &idx))
12870 rpki_target_state = RPKI_VALID;
12871 else if (argv_find(argv, argc, "invalid", &idx))
12872 rpki_target_state = RPKI_INVALID;
12873 }
12874
12875 /* Display prefixes with matching version numbers */
12876 if (argv_find(argv, argc, "version", &idx)) {
12877 sh_type = bgp_show_type_prefix_version;
12878 output_arg = argv[idx + 1]->arg;
12879 }
12880
12881 /* Display prefixes with matching BGP community alias */
12882 if (argv_find(argv, argc, "alias", &idx)) {
12883 sh_type = bgp_show_type_community_alias;
12884 output_arg = argv[idx + 1]->arg;
12885 }
12886
12887 /* prefix-longer */
12888 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12889 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12890 const char *prefix_str = argv[idx]->arg;
12891
12892 if (!str2prefix(prefix_str, &p)) {
12893 vty_out(vty, "%% Malformed Prefix\n");
12894 return CMD_WARNING;
12895 }
12896
12897 sh_type = bgp_show_type_prefix_longer;
12898 output_arg = &p;
12899 }
12900
12901 /* self originated only */
12902 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12903 sh_type = bgp_show_type_self_originated;
12904
12905 if (!all) {
12906 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12907 if (community)
12908 return bgp_show_community(vty, bgp, community,
12909 exact_match, afi, safi,
12910 show_flags);
12911 else
12912 return bgp_show(vty, bgp, afi, safi, sh_type,
12913 output_arg, show_flags,
12914 rpki_target_state);
12915 } else {
12916 struct listnode *node;
12917 struct bgp *abgp;
12918 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12919 * AFI_IP6 */
12920
12921 if (uj)
12922 vty_out(vty, "{\n");
12923
12924 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12925 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12926 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12927 ? AFI_IP
12928 : AFI_IP6;
12929 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12930 FOREACH_SAFI (safi) {
12931 if (!bgp_afi_safi_peer_exists(abgp, afi,
12932 safi))
12933 continue;
12934
12935 if (uj) {
12936 if (first)
12937 first = false;
12938 else
12939 vty_out(vty, ",\n");
12940 vty_out(vty, "\"%s\":{\n",
12941 get_afi_safi_str(afi,
12942 safi,
12943 true));
12944 } else
12945 vty_out(vty,
12946 "\nFor address family: %s\n",
12947 get_afi_safi_str(
12948 afi, safi,
12949 false));
12950
12951 if (community)
12952 bgp_show_community(
12953 vty, abgp, community,
12954 exact_match, afi, safi,
12955 show_flags);
12956 else
12957 bgp_show(vty, abgp, afi, safi,
12958 sh_type, output_arg,
12959 show_flags,
12960 rpki_target_state);
12961 if (uj)
12962 vty_out(vty, "}\n");
12963 }
12964 }
12965 } else {
12966 /* show <ip> bgp all: for each AFI and SAFI*/
12967 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12968 FOREACH_AFI_SAFI (afi, safi) {
12969 if (!bgp_afi_safi_peer_exists(abgp, afi,
12970 safi))
12971 continue;
12972
12973 if (uj) {
12974 if (first)
12975 first = false;
12976 else
12977 vty_out(vty, ",\n");
12978
12979 vty_out(vty, "\"%s\":{\n",
12980 get_afi_safi_str(afi,
12981 safi,
12982 true));
12983 } else
12984 vty_out(vty,
12985 "\nFor address family: %s\n",
12986 get_afi_safi_str(
12987 afi, safi,
12988 false));
12989
12990 if (community)
12991 bgp_show_community(
12992 vty, abgp, community,
12993 exact_match, afi, safi,
12994 show_flags);
12995 else
12996 bgp_show(vty, abgp, afi, safi,
12997 sh_type, output_arg,
12998 show_flags,
12999 rpki_target_state);
13000 if (uj)
13001 vty_out(vty, "}\n");
13002 }
13003 }
13004 }
13005 if (uj)
13006 vty_out(vty, "}\n");
13007 }
13008 return CMD_SUCCESS;
13009 }
13010
13011 DEFUN (show_ip_bgp_route,
13012 show_ip_bgp_route_cmd,
13013 "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]",
13014 SHOW_STR
13015 IP_STR
13016 BGP_STR
13017 BGP_INSTANCE_HELP_STR
13018 BGP_AFI_HELP_STR
13019 BGP_SAFI_WITH_LABEL_HELP_STR
13020 "Network in the BGP routing table to display\n"
13021 "IPv4 prefix\n"
13022 "Network in the BGP routing table to display\n"
13023 "IPv6 prefix\n"
13024 "Display only the bestpath\n"
13025 "Display only multipaths\n"
13026 "Display only paths that match the specified rpki state\n"
13027 "A valid path as determined by rpki\n"
13028 "A invalid path as determined by rpki\n"
13029 "A path that has no rpki data\n"
13030 JSON_STR)
13031 {
13032 int prefix_check = 0;
13033
13034 afi_t afi = AFI_IP6;
13035 safi_t safi = SAFI_UNICAST;
13036 char *prefix = NULL;
13037 struct bgp *bgp = NULL;
13038 enum bgp_path_type path_type;
13039 bool uj = use_json(argc, argv);
13040
13041 int idx = 0;
13042
13043 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13044 &bgp, uj);
13045 if (!idx)
13046 return CMD_WARNING;
13047
13048 if (!bgp) {
13049 vty_out(vty,
13050 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13051 return CMD_WARNING;
13052 }
13053
13054 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13055 if (argv_find(argv, argc, "A.B.C.D", &idx)
13056 || argv_find(argv, argc, "X:X::X:X", &idx))
13057 prefix_check = 0;
13058 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13059 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13060 prefix_check = 1;
13061
13062 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13063 && afi != AFI_IP6) {
13064 vty_out(vty,
13065 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13066 return CMD_WARNING;
13067 }
13068 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13069 && afi != AFI_IP) {
13070 vty_out(vty,
13071 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13072 return CMD_WARNING;
13073 }
13074
13075 prefix = argv[idx]->arg;
13076
13077 /* [<bestpath|multipath>] */
13078 if (argv_find(argv, argc, "bestpath", &idx))
13079 path_type = BGP_PATH_SHOW_BESTPATH;
13080 else if (argv_find(argv, argc, "multipath", &idx))
13081 path_type = BGP_PATH_SHOW_MULTIPATH;
13082 else
13083 path_type = BGP_PATH_SHOW_ALL;
13084
13085 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13086 path_type, RPKI_NOT_BEING_USED, uj);
13087 }
13088
13089 DEFUN (show_ip_bgp_regexp,
13090 show_ip_bgp_regexp_cmd,
13091 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13092 SHOW_STR
13093 IP_STR
13094 BGP_STR
13095 BGP_INSTANCE_HELP_STR
13096 BGP_AFI_HELP_STR
13097 BGP_SAFI_WITH_LABEL_HELP_STR
13098 "Display routes matching the AS path regular expression\n"
13099 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13100 JSON_STR)
13101 {
13102 afi_t afi = AFI_IP6;
13103 safi_t safi = SAFI_UNICAST;
13104 struct bgp *bgp = NULL;
13105 bool uj = use_json(argc, argv);
13106 char *regstr = NULL;
13107
13108 int idx = 0;
13109 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13110 &bgp, false);
13111 if (!idx)
13112 return CMD_WARNING;
13113
13114 // get index of regex
13115 if (argv_find(argv, argc, "REGEX", &idx))
13116 regstr = argv[idx]->arg;
13117
13118 assert(regstr);
13119 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13120 bgp_show_type_regexp, uj);
13121 }
13122
13123 DEFPY (show_ip_bgp_instance_all,
13124 show_ip_bgp_instance_all_cmd,
13125 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13126 SHOW_STR
13127 IP_STR
13128 BGP_STR
13129 BGP_INSTANCE_ALL_HELP_STR
13130 BGP_AFI_HELP_STR
13131 BGP_SAFI_WITH_LABEL_HELP_STR
13132 JSON_STR
13133 "Increase table width for longer prefixes\n")
13134 {
13135 afi_t afi = AFI_IP6;
13136 safi_t safi = SAFI_UNICAST;
13137 struct bgp *bgp = NULL;
13138 int idx = 0;
13139 uint16_t show_flags = 0;
13140
13141 if (uj) {
13142 argc--;
13143 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13144 }
13145
13146 if (wide)
13147 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13148
13149 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13150 &bgp, uj);
13151 if (!idx)
13152 return CMD_WARNING;
13153
13154 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13155 return CMD_SUCCESS;
13156 }
13157
13158 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13159 afi_t afi, safi_t safi, enum bgp_show_type type,
13160 bool use_json)
13161 {
13162 regex_t *regex;
13163 int rc;
13164 uint16_t show_flags = 0;
13165
13166 if (use_json)
13167 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13168
13169 if (!config_bgp_aspath_validate(regstr)) {
13170 vty_out(vty, "Invalid character in REGEX %s\n",
13171 regstr);
13172 return CMD_WARNING_CONFIG_FAILED;
13173 }
13174
13175 regex = bgp_regcomp(regstr);
13176 if (!regex) {
13177 vty_out(vty, "Can't compile regexp %s\n", regstr);
13178 return CMD_WARNING;
13179 }
13180
13181 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13182 RPKI_NOT_BEING_USED);
13183 bgp_regex_free(regex);
13184 return rc;
13185 }
13186
13187 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13188 const char *comstr, int exact, afi_t afi,
13189 safi_t safi, uint16_t show_flags)
13190 {
13191 struct community *com;
13192 int ret = 0;
13193
13194 com = community_str2com(comstr);
13195 if (!com) {
13196 vty_out(vty, "%% Community malformed: %s\n", comstr);
13197 return CMD_WARNING;
13198 }
13199
13200 ret = bgp_show(vty, bgp, afi, safi,
13201 (exact ? bgp_show_type_community_exact
13202 : bgp_show_type_community),
13203 com, show_flags, RPKI_NOT_BEING_USED);
13204 community_free(&com);
13205
13206 return ret;
13207 }
13208
13209 enum bgp_stats {
13210 BGP_STATS_MAXBITLEN = 0,
13211 BGP_STATS_RIB,
13212 BGP_STATS_PREFIXES,
13213 BGP_STATS_TOTPLEN,
13214 BGP_STATS_UNAGGREGATEABLE,
13215 BGP_STATS_MAX_AGGREGATEABLE,
13216 BGP_STATS_AGGREGATES,
13217 BGP_STATS_SPACE,
13218 BGP_STATS_ASPATH_COUNT,
13219 BGP_STATS_ASPATH_MAXHOPS,
13220 BGP_STATS_ASPATH_TOTHOPS,
13221 BGP_STATS_ASPATH_MAXSIZE,
13222 BGP_STATS_ASPATH_TOTSIZE,
13223 BGP_STATS_ASN_HIGHEST,
13224 BGP_STATS_MAX,
13225 };
13226
13227 #define TABLE_STATS_IDX_VTY 0
13228 #define TABLE_STATS_IDX_JSON 1
13229
13230 static const char *table_stats_strs[][2] = {
13231 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13232 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13233 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13234 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13235 "unaggregateablePrefixes"},
13236 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13237 "maximumAggregateablePrefixes"},
13238 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13239 "bgpAggregateAdvertisements"},
13240 [BGP_STATS_SPACE] = {"Address space advertised",
13241 "addressSpaceAdvertised"},
13242 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13243 "advertisementsWithPaths"},
13244 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13245 "longestAsPath"},
13246 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13247 "largestAsPath"},
13248 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13249 "averageAsPathLengthHops"},
13250 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13251 "averageAsPathSizeBytes"},
13252 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13253 [BGP_STATS_MAX] = {NULL, NULL}
13254 };
13255
13256 struct bgp_table_stats {
13257 struct bgp_table *table;
13258 unsigned long long counts[BGP_STATS_MAX];
13259
13260 unsigned long long
13261 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13262 1];
13263
13264 double total_space;
13265 };
13266
13267 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13268 struct bgp_table_stats *ts, unsigned int space)
13269 {
13270 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13271 struct bgp_path_info *pi;
13272 const struct prefix *rn_p;
13273
13274 if (!bgp_dest_has_bgp_path_info_data(dest))
13275 return;
13276
13277 rn_p = bgp_dest_get_prefix(dest);
13278 ts->counts[BGP_STATS_PREFIXES]++;
13279 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13280
13281 ts->prefix_len_count[rn_p->prefixlen]++;
13282 /* check if the prefix is included by any other announcements */
13283 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13284 pdest = bgp_dest_parent_nolock(pdest);
13285
13286 if (pdest == NULL || pdest == top) {
13287 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13288 /* announced address space */
13289 if (space)
13290 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13291 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13292 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13293
13294
13295 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13296 ts->counts[BGP_STATS_RIB]++;
13297
13298 if (CHECK_FLAG(pi->attr->flag,
13299 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13300 ts->counts[BGP_STATS_AGGREGATES]++;
13301
13302 /* as-path stats */
13303 if (pi->attr->aspath) {
13304 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13305 unsigned int size = aspath_size(pi->attr->aspath);
13306 as_t highest = aspath_highest(pi->attr->aspath);
13307
13308 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13309
13310 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13311 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13312
13313 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13314 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13315
13316 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13317 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13318 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13319 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13320 }
13321 }
13322 }
13323
13324 static void bgp_table_stats_walker(struct event *t)
13325 {
13326 struct bgp_dest *dest, *ndest;
13327 struct bgp_dest *top;
13328 struct bgp_table_stats *ts = EVENT_ARG(t);
13329 unsigned int space = 0;
13330
13331 if (!(top = bgp_table_top(ts->table)))
13332 return;
13333
13334 switch (ts->table->afi) {
13335 case AFI_IP:
13336 space = IPV4_MAX_BITLEN;
13337 break;
13338 case AFI_IP6:
13339 space = IPV6_MAX_BITLEN;
13340 break;
13341 case AFI_L2VPN:
13342 space = EVPN_ROUTE_PREFIXLEN;
13343 break;
13344 case AFI_UNSPEC:
13345 case AFI_MAX:
13346 return;
13347 }
13348
13349 ts->counts[BGP_STATS_MAXBITLEN] = space;
13350
13351 for (dest = top; dest; dest = bgp_route_next(dest)) {
13352 if (ts->table->safi == SAFI_MPLS_VPN
13353 || ts->table->safi == SAFI_ENCAP
13354 || ts->table->safi == SAFI_EVPN) {
13355 struct bgp_table *table;
13356
13357 table = bgp_dest_get_bgp_table_info(dest);
13358 if (!table)
13359 continue;
13360
13361 top = bgp_table_top(table);
13362 for (ndest = bgp_table_top(table); ndest;
13363 ndest = bgp_route_next(ndest))
13364 bgp_table_stats_rn(ndest, top, ts, space);
13365 } else {
13366 bgp_table_stats_rn(dest, top, ts, space);
13367 }
13368 }
13369 }
13370
13371 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13372 struct json_object *json_array)
13373 {
13374 struct listnode *node, *nnode;
13375 struct bgp *bgp;
13376
13377 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13378 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13379 }
13380
13381 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13382 safi_t safi, struct json_object *json_array)
13383 {
13384 struct bgp_table_stats ts;
13385 unsigned int i;
13386 int ret = CMD_SUCCESS;
13387 char temp_buf[20];
13388 struct json_object *json = NULL;
13389 uint32_t bitlen = 0;
13390 struct json_object *json_bitlen;
13391
13392 if (json_array)
13393 json = json_object_new_object();
13394
13395 if (!bgp->rib[afi][safi]) {
13396 char warning_msg[50];
13397
13398 snprintf(warning_msg, sizeof(warning_msg),
13399 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13400 safi);
13401
13402 if (!json)
13403 vty_out(vty, "%s\n", warning_msg);
13404 else
13405 json_object_string_add(json, "warning", warning_msg);
13406
13407 ret = CMD_WARNING;
13408 goto end_table_stats;
13409 }
13410
13411 if (!json)
13412 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13413 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13414 else
13415 json_object_string_add(json, "instance", bgp->name_pretty);
13416
13417 /* labeled-unicast routes live in the unicast table */
13418 if (safi == SAFI_LABELED_UNICAST)
13419 safi = SAFI_UNICAST;
13420
13421 memset(&ts, 0, sizeof(ts));
13422 ts.table = bgp->rib[afi][safi];
13423 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13424
13425 for (i = 0; i < BGP_STATS_MAX; i++) {
13426 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13427 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13428 continue;
13429
13430 switch (i) {
13431 case BGP_STATS_ASPATH_TOTHOPS:
13432 case BGP_STATS_ASPATH_TOTSIZE:
13433 if (!json) {
13434 snprintf(
13435 temp_buf, sizeof(temp_buf), "%12.2f",
13436 ts.counts[i]
13437 ? (float)ts.counts[i]
13438 / (float)ts.counts
13439 [BGP_STATS_ASPATH_COUNT]
13440 : 0);
13441 vty_out(vty, "%-30s: %s",
13442 table_stats_strs[i]
13443 [TABLE_STATS_IDX_VTY],
13444 temp_buf);
13445 } else {
13446 json_object_double_add(
13447 json,
13448 table_stats_strs[i]
13449 [TABLE_STATS_IDX_JSON],
13450 ts.counts[i]
13451 ? (double)ts.counts[i]
13452 / (double)ts.counts
13453 [BGP_STATS_ASPATH_COUNT]
13454 : 0);
13455 }
13456 break;
13457 case BGP_STATS_TOTPLEN:
13458 if (!json) {
13459 snprintf(
13460 temp_buf, sizeof(temp_buf), "%12.2f",
13461 ts.counts[i]
13462 ? (float)ts.counts[i]
13463 / (float)ts.counts
13464 [BGP_STATS_PREFIXES]
13465 : 0);
13466 vty_out(vty, "%-30s: %s",
13467 table_stats_strs[i]
13468 [TABLE_STATS_IDX_VTY],
13469 temp_buf);
13470 } else {
13471 json_object_double_add(
13472 json,
13473 table_stats_strs[i]
13474 [TABLE_STATS_IDX_JSON],
13475 ts.counts[i]
13476 ? (double)ts.counts[i]
13477 / (double)ts.counts
13478 [BGP_STATS_PREFIXES]
13479 : 0);
13480 }
13481 break;
13482 case BGP_STATS_SPACE:
13483 if (!json) {
13484 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13485 ts.total_space);
13486 vty_out(vty, "%-30s: %s\n",
13487 table_stats_strs[i]
13488 [TABLE_STATS_IDX_VTY],
13489 temp_buf);
13490 } else {
13491 json_object_double_add(
13492 json,
13493 table_stats_strs[i]
13494 [TABLE_STATS_IDX_JSON],
13495 (double)ts.total_space);
13496 }
13497 if (afi == AFI_IP6) {
13498 if (!json) {
13499 snprintf(temp_buf, sizeof(temp_buf),
13500 "%12g",
13501 ts.total_space
13502 * pow(2.0, -128 + 32));
13503 vty_out(vty, "%30s: %s\n",
13504 "/32 equivalent %s\n",
13505 temp_buf);
13506 } else {
13507 json_object_double_add(
13508 json, "/32equivalent",
13509 (double)(ts.total_space
13510 * pow(2.0,
13511 -128 + 32)));
13512 }
13513 if (!json) {
13514 snprintf(temp_buf, sizeof(temp_buf),
13515 "%12g",
13516 ts.total_space
13517 * pow(2.0, -128 + 48));
13518 vty_out(vty, "%30s: %s\n",
13519 "/48 equivalent %s\n",
13520 temp_buf);
13521 } else {
13522 json_object_double_add(
13523 json, "/48equivalent",
13524 (double)(ts.total_space
13525 * pow(2.0,
13526 -128 + 48)));
13527 }
13528 } else {
13529 if (!json) {
13530 snprintf(temp_buf, sizeof(temp_buf),
13531 "%12.2f",
13532 ts.total_space * 100.
13533 * pow(2.0, -32));
13534 vty_out(vty, "%30s: %s\n",
13535 "% announced ", temp_buf);
13536 } else {
13537 json_object_double_add(
13538 json, "%announced",
13539 (double)(ts.total_space * 100.
13540 * pow(2.0, -32)));
13541 }
13542 if (!json) {
13543 snprintf(temp_buf, sizeof(temp_buf),
13544 "%12.2f",
13545 ts.total_space
13546 * pow(2.0, -32 + 8));
13547 vty_out(vty, "%30s: %s\n",
13548 "/8 equivalent ", temp_buf);
13549 } else {
13550 json_object_double_add(
13551 json, "/8equivalent",
13552 (double)(ts.total_space
13553 * pow(2.0, -32 + 8)));
13554 }
13555 if (!json) {
13556 snprintf(temp_buf, sizeof(temp_buf),
13557 "%12.2f",
13558 ts.total_space
13559 * pow(2.0, -32 + 24));
13560 vty_out(vty, "%30s: %s\n",
13561 "/24 equivalent ", temp_buf);
13562 } else {
13563 json_object_double_add(
13564 json, "/24equivalent",
13565 (double)(ts.total_space
13566 * pow(2.0, -32 + 24)));
13567 }
13568 }
13569 break;
13570 default:
13571 if (!json) {
13572 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13573 ts.counts[i]);
13574 vty_out(vty, "%-30s: %s",
13575 table_stats_strs[i]
13576 [TABLE_STATS_IDX_VTY],
13577 temp_buf);
13578 } else {
13579 json_object_int_add(
13580 json,
13581 table_stats_strs[i]
13582 [TABLE_STATS_IDX_JSON],
13583 ts.counts[i]);
13584 }
13585 }
13586 if (!json)
13587 vty_out(vty, "\n");
13588 }
13589
13590 switch (afi) {
13591 case AFI_IP:
13592 bitlen = IPV4_MAX_BITLEN;
13593 break;
13594 case AFI_IP6:
13595 bitlen = IPV6_MAX_BITLEN;
13596 break;
13597 case AFI_L2VPN:
13598 bitlen = EVPN_ROUTE_PREFIXLEN;
13599 break;
13600 case AFI_UNSPEC:
13601 case AFI_MAX:
13602 break;
13603 }
13604
13605 if (json) {
13606 json_bitlen = json_object_new_array();
13607
13608 for (i = 0; i <= bitlen; i++) {
13609 struct json_object *ind_bit = json_object_new_object();
13610
13611 if (!ts.prefix_len_count[i])
13612 continue;
13613
13614 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13615 json_object_int_add(ind_bit, temp_buf,
13616 ts.prefix_len_count[i]);
13617 json_object_array_add(json_bitlen, ind_bit);
13618 }
13619 json_object_object_add(json, "prefixLength", json_bitlen);
13620 }
13621
13622 end_table_stats:
13623 if (json)
13624 json_object_array_add(json_array, json);
13625 return ret;
13626 }
13627
13628 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13629 safi_t safi, struct json_object *json_array)
13630 {
13631 if (!bgp) {
13632 bgp_table_stats_all(vty, afi, safi, json_array);
13633 return CMD_SUCCESS;
13634 }
13635
13636 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13637 }
13638
13639 enum bgp_pcounts {
13640 PCOUNT_ADJ_IN = 0,
13641 PCOUNT_DAMPED,
13642 PCOUNT_REMOVED,
13643 PCOUNT_HISTORY,
13644 PCOUNT_STALE,
13645 PCOUNT_VALID,
13646 PCOUNT_ALL,
13647 PCOUNT_COUNTED,
13648 PCOUNT_BPATH_SELECTED,
13649 PCOUNT_PFCNT, /* the figure we display to users */
13650 PCOUNT_MAX,
13651 };
13652
13653 static const char *const pcount_strs[] = {
13654 [PCOUNT_ADJ_IN] = "Adj-in",
13655 [PCOUNT_DAMPED] = "Damped",
13656 [PCOUNT_REMOVED] = "Removed",
13657 [PCOUNT_HISTORY] = "History",
13658 [PCOUNT_STALE] = "Stale",
13659 [PCOUNT_VALID] = "Valid",
13660 [PCOUNT_ALL] = "All RIB",
13661 [PCOUNT_COUNTED] = "PfxCt counted",
13662 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13663 [PCOUNT_PFCNT] = "Useable",
13664 [PCOUNT_MAX] = NULL,
13665 };
13666
13667 struct peer_pcounts {
13668 unsigned int count[PCOUNT_MAX];
13669 const struct peer *peer;
13670 const struct bgp_table *table;
13671 safi_t safi;
13672 };
13673
13674 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13675 {
13676 const struct bgp_adj_in *ain;
13677 const struct bgp_path_info *pi;
13678 const struct peer *peer = pc->peer;
13679
13680 for (ain = rn->adj_in; ain; ain = ain->next)
13681 if (ain->peer == peer)
13682 pc->count[PCOUNT_ADJ_IN]++;
13683
13684 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13685
13686 if (pi->peer != peer)
13687 continue;
13688
13689 pc->count[PCOUNT_ALL]++;
13690
13691 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13692 pc->count[PCOUNT_DAMPED]++;
13693 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13694 pc->count[PCOUNT_HISTORY]++;
13695 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13696 pc->count[PCOUNT_REMOVED]++;
13697 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13698 pc->count[PCOUNT_STALE]++;
13699 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13700 pc->count[PCOUNT_VALID]++;
13701 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13702 pc->count[PCOUNT_PFCNT]++;
13703 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13704 pc->count[PCOUNT_BPATH_SELECTED]++;
13705
13706 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13707 pc->count[PCOUNT_COUNTED]++;
13708 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13709 flog_err(
13710 EC_LIB_DEVELOPMENT,
13711 "Attempting to count but flags say it is unusable");
13712 } else {
13713 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13714 flog_err(
13715 EC_LIB_DEVELOPMENT,
13716 "Not counted but flags say we should");
13717 }
13718 }
13719 }
13720
13721 static void bgp_peer_count_walker(struct event *t)
13722 {
13723 struct bgp_dest *rn, *rm;
13724 const struct bgp_table *table;
13725 struct peer_pcounts *pc = EVENT_ARG(t);
13726
13727 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13728 || pc->safi == SAFI_EVPN) {
13729 /* Special handling for 2-level routing tables. */
13730 for (rn = bgp_table_top(pc->table); rn;
13731 rn = bgp_route_next(rn)) {
13732 table = bgp_dest_get_bgp_table_info(rn);
13733 if (table != NULL)
13734 for (rm = bgp_table_top(table); rm;
13735 rm = bgp_route_next(rm))
13736 bgp_peer_count_proc(rm, pc);
13737 }
13738 } else
13739 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13740 bgp_peer_count_proc(rn, pc);
13741 }
13742
13743 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13744 safi_t safi, bool use_json)
13745 {
13746 struct peer_pcounts pcounts = {.peer = peer};
13747 unsigned int i;
13748 json_object *json = NULL;
13749 json_object *json_loop = NULL;
13750
13751 if (use_json) {
13752 json = json_object_new_object();
13753 json_loop = json_object_new_object();
13754 }
13755
13756 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13757 || !peer->bgp->rib[afi][safi]) {
13758 if (use_json) {
13759 json_object_string_add(
13760 json, "warning",
13761 "No such neighbor or address family");
13762 vty_out(vty, "%s\n", json_object_to_json_string(json));
13763 json_object_free(json);
13764 json_object_free(json_loop);
13765 } else
13766 vty_out(vty, "%% No such neighbor or address family\n");
13767
13768 return CMD_WARNING;
13769 }
13770
13771 memset(&pcounts, 0, sizeof(pcounts));
13772 pcounts.peer = peer;
13773 pcounts.table = peer->bgp->rib[afi][safi];
13774 pcounts.safi = safi;
13775
13776 /* in-place call via thread subsystem so as to record execution time
13777 * stats for the thread-walk (i.e. ensure this can't be blamed on
13778 * on just vty_read()).
13779 */
13780 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13781
13782 if (use_json) {
13783 json_object_string_add(json, "prefixCountsFor", peer->host);
13784 json_object_string_add(json, "multiProtocol",
13785 get_afi_safi_str(afi, safi, true));
13786 json_object_int_add(json, "pfxCounter",
13787 peer->pcount[afi][safi]);
13788
13789 for (i = 0; i < PCOUNT_MAX; i++)
13790 json_object_int_add(json_loop, pcount_strs[i],
13791 pcounts.count[i]);
13792
13793 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13794
13795 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13796 json_object_string_add(json, "pfxctDriftFor",
13797 peer->host);
13798 json_object_string_add(
13799 json, "recommended",
13800 "Please report this bug, with the above command output");
13801 }
13802 vty_json(vty, json);
13803 } else {
13804
13805 if (peer->hostname
13806 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13807 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13808 peer->hostname, peer->host,
13809 get_afi_safi_str(afi, safi, false));
13810 } else {
13811 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13812 get_afi_safi_str(afi, safi, false));
13813 }
13814
13815 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13816 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13817
13818 for (i = 0; i < PCOUNT_MAX; i++)
13819 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13820 pcounts.count[i]);
13821
13822 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13823 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13824 vty_out(vty,
13825 "Please report this bug, with the above command output\n");
13826 }
13827 }
13828
13829 return CMD_SUCCESS;
13830 }
13831
13832 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13833 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13834 "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]",
13835 SHOW_STR
13836 IP_STR
13837 BGP_STR
13838 BGP_INSTANCE_HELP_STR
13839 BGP_AFI_HELP_STR
13840 BGP_SAFI_HELP_STR
13841 "Detailed information on TCP and BGP neighbor connections\n"
13842 "Neighbor to display information about\n"
13843 "Neighbor to display information about\n"
13844 "Neighbor on BGP configured interface\n"
13845 "Display detailed prefix count information\n"
13846 JSON_STR)
13847 {
13848 afi_t afi = AFI_IP6;
13849 safi_t safi = SAFI_UNICAST;
13850 struct peer *peer;
13851 int idx = 0;
13852 struct bgp *bgp = NULL;
13853 bool uj = use_json(argc, argv);
13854
13855 if (uj)
13856 argc--;
13857
13858 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13859 &bgp, uj);
13860 if (!idx)
13861 return CMD_WARNING;
13862
13863 argv_find(argv, argc, "neighbors", &idx);
13864 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13865 if (!peer)
13866 return CMD_WARNING;
13867
13868 return bgp_peer_counts(vty, peer, afi, safi, uj);
13869 }
13870
13871 #ifdef KEEP_OLD_VPN_COMMANDS
13872 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13873 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13874 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13875 SHOW_STR
13876 IP_STR
13877 BGP_STR
13878 BGP_VPNVX_HELP_STR
13879 "Display information about all VPNv4 NLRIs\n"
13880 "Detailed information on TCP and BGP neighbor connections\n"
13881 "Neighbor to display information about\n"
13882 "Neighbor to display information about\n"
13883 "Neighbor on BGP configured interface\n"
13884 "Display detailed prefix count information\n"
13885 JSON_STR)
13886 {
13887 int idx_peer = 6;
13888 struct peer *peer;
13889 bool uj = use_json(argc, argv);
13890
13891 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13892 if (!peer)
13893 return CMD_WARNING;
13894
13895 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13896 }
13897
13898 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13899 show_ip_bgp_vpn_all_route_prefix_cmd,
13900 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13901 SHOW_STR
13902 IP_STR
13903 BGP_STR
13904 BGP_VPNVX_HELP_STR
13905 "Display information about all VPNv4 NLRIs\n"
13906 "Network in the BGP routing table to display\n"
13907 "Network in the BGP routing table to display\n"
13908 JSON_STR)
13909 {
13910 int idx = 0;
13911 char *network = NULL;
13912 struct bgp *bgp = bgp_get_default();
13913 if (!bgp) {
13914 vty_out(vty, "Can't find default instance\n");
13915 return CMD_WARNING;
13916 }
13917
13918 if (argv_find(argv, argc, "A.B.C.D", &idx))
13919 network = argv[idx]->arg;
13920 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13921 network = argv[idx]->arg;
13922 else {
13923 vty_out(vty, "Unable to figure out Network\n");
13924 return CMD_WARNING;
13925 }
13926
13927 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13928 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13929 use_json(argc, argv));
13930 }
13931 #endif /* KEEP_OLD_VPN_COMMANDS */
13932
13933 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13934 show_bgp_l2vpn_evpn_route_prefix_cmd,
13935 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13936 SHOW_STR
13937 BGP_STR
13938 L2VPN_HELP_STR
13939 EVPN_HELP_STR
13940 "Network in the BGP routing table to display\n"
13941 "Network in the BGP routing table to display\n"
13942 "Network in the BGP routing table to display\n"
13943 "Network in the BGP routing table to display\n"
13944 JSON_STR)
13945 {
13946 int idx = 0;
13947 char *network = NULL;
13948 int prefix_check = 0;
13949
13950 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13951 argv_find(argv, argc, "X:X::X:X", &idx))
13952 network = argv[idx]->arg;
13953 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13954 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13955 network = argv[idx]->arg;
13956 prefix_check = 1;
13957 } else {
13958 vty_out(vty, "Unable to figure out Network\n");
13959 return CMD_WARNING;
13960 }
13961 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13962 prefix_check, BGP_PATH_SHOW_ALL,
13963 RPKI_NOT_BEING_USED, use_json(argc, argv));
13964 }
13965
13966 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13967 struct bgp_table *table, int *header1,
13968 int *header2, json_object *json,
13969 json_object *json_scode,
13970 json_object *json_ocode, bool wide,
13971 bool detail)
13972 {
13973 uint64_t version = table ? table->version : 0;
13974
13975 if (*header1) {
13976 if (json) {
13977 json_object_int_add(json, "bgpTableVersion", version);
13978 json_object_string_addf(json, "bgpLocalRouterId",
13979 "%pI4", &peer->bgp->router_id);
13980 json_object_int_add(json, "defaultLocPrf",
13981 peer->bgp->default_local_pref);
13982 json_object_int_add(json, "localAS",
13983 peer->change_local_as
13984 ? peer->change_local_as
13985 : peer->local_as);
13986 json_object_object_add(json, "bgpStatusCodes",
13987 json_scode);
13988 json_object_object_add(json, "bgpOriginCodes",
13989 json_ocode);
13990 } else {
13991 vty_out(vty,
13992 "BGP table version is %" PRIu64
13993 ", local router ID is %pI4, vrf id ",
13994 version, &peer->bgp->router_id);
13995 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13996 vty_out(vty, "%s", VRFID_NONE_STR);
13997 else
13998 vty_out(vty, "%u", peer->bgp->vrf_id);
13999 vty_out(vty, "\n");
14000 vty_out(vty, "Default local pref %u, ",
14001 peer->bgp->default_local_pref);
14002 vty_out(vty, "local AS %u\n",
14003 peer->change_local_as ? peer->change_local_as
14004 : peer->local_as);
14005 if (!detail) {
14006 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14007 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14008 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14009 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14010 }
14011 }
14012 *header1 = 0;
14013 }
14014 if (*header2) {
14015 if (!json && !detail)
14016 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14017 : BGP_SHOW_HEADER));
14018 *header2 = 0;
14019 }
14020 }
14021
14022 static void
14023 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14024 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14025 const char *rmap_name, json_object *json, json_object *json_ar,
14026 json_object *json_scode, json_object *json_ocode,
14027 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14028 const struct prefix *match, unsigned long *output_count,
14029 unsigned long *filtered_count)
14030 {
14031 struct bgp_adj_in *ain = NULL;
14032 struct bgp_adj_out *adj = NULL;
14033 struct bgp_dest *dest;
14034 struct bgp *bgp;
14035 struct attr attr;
14036 int ret;
14037 struct update_subgroup *subgrp;
14038 struct peer_af *paf = NULL;
14039 bool route_filtered;
14040 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14041 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14042 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14043 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14044 || (safi == SAFI_EVPN))
14045 ? true
14046 : false;
14047 int display = 0;
14048 json_object *json_net = NULL;
14049
14050 bgp = peer->bgp;
14051
14052 /* If the user supplied a prefix, look for a matching route instead
14053 * of walking the whole table.
14054 */
14055 if (match) {
14056 dest = bgp_node_match(table, match);
14057 if (!dest) {
14058 if (!use_json)
14059 vty_out(vty, "Network not in table\n");
14060 return;
14061 }
14062
14063 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14064
14065 if (rn_p->prefixlen != match->prefixlen) {
14066 if (!use_json)
14067 vty_out(vty, "Network not in table\n");
14068 bgp_dest_unlock_node(dest);
14069 return;
14070 }
14071
14072 if (type == bgp_show_adj_route_received ||
14073 type == bgp_show_adj_route_filtered) {
14074 for (ain = dest->adj_in; ain; ain = ain->next) {
14075 if (ain->peer == peer) {
14076 attr = *ain->attr;
14077 break;
14078 }
14079 }
14080 /* bail out if if adj_out is empty, or
14081 * if the prefix isn't in this peer's
14082 * adj_in
14083 */
14084 if (!ain || ain->peer != peer) {
14085 if (!use_json)
14086 vty_out(vty, "Network not in table\n");
14087 bgp_dest_unlock_node(dest);
14088 return;
14089 }
14090 } else if (type == bgp_show_adj_route_advertised) {
14091 bool peer_found = false;
14092
14093 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14094 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14095 if (paf->peer == peer && adj->attr) {
14096 attr = *adj->attr;
14097 peer_found = true;
14098 break;
14099 }
14100 }
14101 if (peer_found)
14102 break;
14103 }
14104 /* bail out if if adj_out is empty, or
14105 * if the prefix isn't in this peer's
14106 * adj_out
14107 */
14108 if (!paf || !peer_found) {
14109 if (!use_json)
14110 vty_out(vty, "Network not in table\n");
14111 bgp_dest_unlock_node(dest);
14112 return;
14113 }
14114 }
14115
14116 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14117 rmap_name);
14118
14119 if (ret != RMAP_DENY) {
14120 show_adj_route_header(vty, peer, table, header1,
14121 header2, json, json_scode,
14122 json_ocode, wide, detail);
14123
14124 if (use_json)
14125 json_net = json_object_new_object();
14126
14127 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14128 afi, safi, json_net,
14129 BGP_PATH_SHOW_ALL, &display,
14130 RPKI_NOT_BEING_USED);
14131 if (use_json)
14132 json_object_object_addf(json_ar, json_net,
14133 "%pFX", rn_p);
14134 (*output_count)++;
14135 } else
14136 (*filtered_count)++;
14137
14138 bgp_attr_flush(&attr);
14139 bgp_dest_unlock_node(dest);
14140 return;
14141 }
14142
14143
14144 subgrp = peer_subgroup(peer, afi, safi);
14145
14146 if (type == bgp_show_adj_route_advertised && subgrp
14147 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14148 if (use_json) {
14149 json_object_int_add(json, "bgpTableVersion",
14150 table->version);
14151 json_object_string_addf(json, "bgpLocalRouterId",
14152 "%pI4", &bgp->router_id);
14153 json_object_int_add(json, "defaultLocPrf",
14154 bgp->default_local_pref);
14155 json_object_int_add(json, "localAS",
14156 peer->change_local_as
14157 ? peer->change_local_as
14158 : peer->local_as);
14159 json_object_object_add(json, "bgpStatusCodes",
14160 json_scode);
14161 json_object_object_add(json, "bgpOriginCodes",
14162 json_ocode);
14163 json_object_string_add(
14164 json, "bgpOriginatingDefaultNetwork",
14165 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14166 } else {
14167 vty_out(vty,
14168 "BGP table version is %" PRIu64
14169 ", local router ID is %pI4, vrf id ",
14170 table->version, &bgp->router_id);
14171 if (bgp->vrf_id == VRF_UNKNOWN)
14172 vty_out(vty, "%s", VRFID_NONE_STR);
14173 else
14174 vty_out(vty, "%u", bgp->vrf_id);
14175 vty_out(vty, "\n");
14176 vty_out(vty, "Default local pref %u, ",
14177 bgp->default_local_pref);
14178 vty_out(vty, "local AS %u\n",
14179 peer->change_local_as ? peer->change_local_as
14180 : peer->local_as);
14181 if (!detail) {
14182 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14183 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14184 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14185 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14186 }
14187
14188 vty_out(vty, "Originating default network %s\n\n",
14189 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14190 }
14191 (*output_count)++;
14192 *header1 = 0;
14193 }
14194
14195 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14196 if (type == bgp_show_adj_route_received
14197 || type == bgp_show_adj_route_filtered) {
14198 for (ain = dest->adj_in; ain; ain = ain->next) {
14199 if (ain->peer != peer)
14200 continue;
14201
14202 show_adj_route_header(vty, peer, table, header1,
14203 header2, json, json_scode,
14204 json_ocode, wide, detail);
14205
14206 if ((safi == SAFI_MPLS_VPN)
14207 || (safi == SAFI_ENCAP)
14208 || (safi == SAFI_EVPN)) {
14209 if (use_json)
14210 json_object_string_add(
14211 json_ar, "rd", rd_str);
14212 else if (show_rd && rd_str) {
14213 vty_out(vty,
14214 "Route Distinguisher: %s\n",
14215 rd_str);
14216 show_rd = false;
14217 }
14218 }
14219
14220 attr = *ain->attr;
14221 route_filtered = false;
14222
14223 /* Filter prefix using distribute list,
14224 * filter list or prefix list
14225 */
14226 const struct prefix *rn_p =
14227 bgp_dest_get_prefix(dest);
14228 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14229 safi))
14230 == FILTER_DENY)
14231 route_filtered = true;
14232
14233 /* Filter prefix using route-map */
14234 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14235 safi, rmap_name, NULL,
14236 0, NULL);
14237
14238 if (type == bgp_show_adj_route_filtered &&
14239 !route_filtered && ret != RMAP_DENY) {
14240 bgp_attr_flush(&attr);
14241 continue;
14242 }
14243
14244 if (type == bgp_show_adj_route_received
14245 && (route_filtered || ret == RMAP_DENY))
14246 (*filtered_count)++;
14247
14248 if (detail) {
14249 if (use_json)
14250 json_net =
14251 json_object_new_object();
14252 bgp_show_path_info(
14253 NULL /* prefix_rd */, dest, vty,
14254 bgp, afi, safi, json_net,
14255 BGP_PATH_SHOW_ALL, &display,
14256 RPKI_NOT_BEING_USED);
14257 if (use_json)
14258 json_object_object_addf(
14259 json_ar, json_net,
14260 "%pFX", rn_p);
14261 } else
14262 route_vty_out_tmp(vty, dest, rn_p,
14263 &attr, safi, use_json,
14264 json_ar, wide);
14265 bgp_attr_flush(&attr);
14266 (*output_count)++;
14267 }
14268 } else if (type == bgp_show_adj_route_advertised) {
14269 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14270 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14271 if (paf->peer != peer || !adj->attr)
14272 continue;
14273
14274 show_adj_route_header(
14275 vty, peer, table, header1,
14276 header2, json, json_scode,
14277 json_ocode, wide, detail);
14278
14279 const struct prefix *rn_p =
14280 bgp_dest_get_prefix(dest);
14281
14282 attr = *adj->attr;
14283 ret = bgp_output_modifier(
14284 peer, rn_p, &attr, afi, safi,
14285 rmap_name);
14286
14287 if (ret != RMAP_DENY) {
14288 if ((safi == SAFI_MPLS_VPN)
14289 || (safi == SAFI_ENCAP)
14290 || (safi == SAFI_EVPN)) {
14291 if (use_json)
14292 json_object_string_add(
14293 json_ar,
14294 "rd",
14295 rd_str);
14296 else if (show_rd
14297 && rd_str) {
14298 vty_out(vty,
14299 "Route Distinguisher: %s\n",
14300 rd_str);
14301 show_rd = false;
14302 }
14303 }
14304 if (detail) {
14305 if (use_json)
14306 json_net =
14307 json_object_new_object();
14308 bgp_show_path_info(
14309 NULL /* prefix_rd
14310 */
14311 ,
14312 dest, vty, bgp,
14313 afi, safi,
14314 json_net,
14315 BGP_PATH_SHOW_ALL,
14316 &display,
14317 RPKI_NOT_BEING_USED);
14318 if (use_json)
14319 json_object_object_addf(
14320 json_ar,
14321 json_net,
14322 "%pFX",
14323 rn_p);
14324 } else
14325 route_vty_out_tmp(
14326 vty, dest, rn_p,
14327 &attr, safi,
14328 use_json,
14329 json_ar, wide);
14330 (*output_count)++;
14331 } else {
14332 (*filtered_count)++;
14333 }
14334
14335 bgp_attr_flush(&attr);
14336 }
14337 } else if (type == bgp_show_adj_route_bestpath) {
14338 struct bgp_path_info *pi;
14339
14340 show_adj_route_header(vty, peer, table, header1,
14341 header2, json, json_scode,
14342 json_ocode, wide, detail);
14343
14344 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14345
14346 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14347 pi = pi->next) {
14348 if (pi->peer != peer)
14349 continue;
14350
14351 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14352 continue;
14353
14354 if (detail) {
14355 if (use_json)
14356 json_net =
14357 json_object_new_object();
14358 bgp_show_path_info(
14359 NULL /* prefix_rd */, dest, vty,
14360 bgp, afi, safi, json_net,
14361 BGP_PATH_SHOW_BESTPATH,
14362 &display, RPKI_NOT_BEING_USED);
14363 if (use_json)
14364 json_object_object_addf(
14365 json_ar, json_net,
14366 "%pFX", rn_p);
14367 } else
14368 route_vty_out_tmp(
14369 vty, dest, rn_p, pi->attr, safi,
14370 use_json, json_ar, wide);
14371 (*output_count)++;
14372 }
14373 }
14374 }
14375 }
14376
14377 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14378 safi_t safi, enum bgp_show_adj_route_type type,
14379 const char *rmap_name, const struct prefix *match,
14380 uint16_t show_flags)
14381 {
14382 struct bgp *bgp;
14383 struct bgp_table *table;
14384 json_object *json = NULL;
14385 json_object *json_scode = NULL;
14386 json_object *json_ocode = NULL;
14387 json_object *json_ar = NULL;
14388 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14389
14390 /* Init BGP headers here so they're only displayed once
14391 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14392 */
14393 int header1 = 1;
14394 int header2 = 1;
14395
14396 /*
14397 * Initialize variables for each RD
14398 * All prefixes under an RD is aggregated within "json_routes"
14399 */
14400 char rd_str[BUFSIZ] = {0};
14401 json_object *json_routes = NULL;
14402
14403
14404 /* For 2-tier tables, prefix counts need to be
14405 * maintained across multiple runs of show_adj_route()
14406 */
14407 unsigned long output_count_per_rd;
14408 unsigned long filtered_count_per_rd;
14409 unsigned long output_count = 0;
14410 unsigned long filtered_count = 0;
14411
14412 if (use_json) {
14413 json = json_object_new_object();
14414 json_ar = json_object_new_object();
14415 json_scode = json_object_new_object();
14416 json_ocode = json_object_new_object();
14417 #if CONFDATE > 20231208
14418 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14419 #endif
14420 json_object_string_add(json_scode, "suppressed", "s");
14421 json_object_string_add(json_scode, "damped", "d");
14422 json_object_string_add(json_scode, "history", "h");
14423 json_object_string_add(json_scode, "valid", "*");
14424 json_object_string_add(json_scode, "best", ">");
14425 json_object_string_add(json_scode, "multipath", "=");
14426 json_object_string_add(json_scode, "internal", "i");
14427 json_object_string_add(json_scode, "ribFailure", "r");
14428 json_object_string_add(json_scode, "stale", "S");
14429 json_object_string_add(json_scode, "removed", "R");
14430
14431 #if CONFDATE > 20231208
14432 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14433 #endif
14434 json_object_string_add(json_ocode, "igp", "i");
14435 json_object_string_add(json_ocode, "egp", "e");
14436 json_object_string_add(json_ocode, "incomplete", "?");
14437 }
14438
14439 if (!peer || !peer->afc[afi][safi]) {
14440 if (use_json) {
14441 json_object_string_add(
14442 json, "warning",
14443 "No such neighbor or address family");
14444 vty_out(vty, "%s\n", json_object_to_json_string(json));
14445 json_object_free(json);
14446 json_object_free(json_ar);
14447 json_object_free(json_scode);
14448 json_object_free(json_ocode);
14449 } else
14450 vty_out(vty, "%% No such neighbor or address family\n");
14451
14452 return CMD_WARNING;
14453 }
14454
14455 if ((type == bgp_show_adj_route_received
14456 || type == bgp_show_adj_route_filtered)
14457 && !CHECK_FLAG(peer->af_flags[afi][safi],
14458 PEER_FLAG_SOFT_RECONFIG)) {
14459 if (use_json) {
14460 json_object_string_add(
14461 json, "warning",
14462 "Inbound soft reconfiguration not enabled");
14463 vty_out(vty, "%s\n", json_object_to_json_string(json));
14464 json_object_free(json);
14465 json_object_free(json_ar);
14466 json_object_free(json_scode);
14467 json_object_free(json_ocode);
14468 } else
14469 vty_out(vty,
14470 "%% Inbound soft reconfiguration not enabled\n");
14471
14472 return CMD_WARNING;
14473 }
14474
14475 bgp = peer->bgp;
14476
14477 /* labeled-unicast routes live in the unicast table */
14478 if (safi == SAFI_LABELED_UNICAST)
14479 table = bgp->rib[afi][SAFI_UNICAST];
14480 else
14481 table = bgp->rib[afi][safi];
14482
14483 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14484 || (safi == SAFI_EVPN)) {
14485
14486 struct bgp_dest *dest;
14487
14488 for (dest = bgp_table_top(table); dest;
14489 dest = bgp_route_next(dest)) {
14490 table = bgp_dest_get_bgp_table_info(dest);
14491 if (!table)
14492 continue;
14493
14494 output_count_per_rd = 0;
14495 filtered_count_per_rd = 0;
14496
14497 if (use_json)
14498 json_routes = json_object_new_object();
14499
14500 const struct prefix_rd *prd;
14501 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14502 dest);
14503
14504 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14505 bgp->asnotation);
14506
14507 show_adj_route(
14508 vty, peer, table, afi, safi, type, rmap_name,
14509 json, json_routes, json_scode, json_ocode,
14510 show_flags, &header1, &header2, rd_str, match,
14511 &output_count_per_rd, &filtered_count_per_rd);
14512
14513 /* Don't include an empty RD in the output! */
14514 if (json_routes && (output_count_per_rd > 0))
14515 json_object_object_add(json_ar, rd_str,
14516 json_routes);
14517
14518 output_count += output_count_per_rd;
14519 filtered_count += filtered_count_per_rd;
14520 }
14521 } else
14522 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14523 json, json_ar, json_scode, json_ocode,
14524 show_flags, &header1, &header2, rd_str, match,
14525 &output_count, &filtered_count);
14526
14527 if (use_json) {
14528 if (type == bgp_show_adj_route_advertised)
14529 json_object_object_add(json, "advertisedRoutes",
14530 json_ar);
14531 else
14532 json_object_object_add(json, "receivedRoutes", json_ar);
14533 json_object_int_add(json, "totalPrefixCounter", output_count);
14534 json_object_int_add(json, "filteredPrefixCounter",
14535 filtered_count);
14536
14537 /*
14538 * These fields only give up ownership to `json` when `header1`
14539 * is used (set to zero). See code in `show_adj_route` and
14540 * `show_adj_route_header`.
14541 */
14542 if (header1 == 1) {
14543 json_object_free(json_scode);
14544 json_object_free(json_ocode);
14545 }
14546
14547 vty_json(vty, json);
14548 } else if (output_count > 0) {
14549 if (!match && filtered_count > 0)
14550 vty_out(vty,
14551 "\nTotal number of prefixes %ld (%ld filtered)\n",
14552 output_count, filtered_count);
14553 else
14554 vty_out(vty, "\nTotal number of prefixes %ld\n",
14555 output_count);
14556 }
14557
14558 return CMD_SUCCESS;
14559 }
14560
14561 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14562 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14563 "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]",
14564 SHOW_STR
14565 IP_STR
14566 BGP_STR
14567 BGP_INSTANCE_HELP_STR
14568 BGP_AFI_HELP_STR
14569 BGP_SAFI_WITH_LABEL_HELP_STR
14570 "Detailed information on TCP and BGP neighbor connections\n"
14571 "Neighbor to display information about\n"
14572 "Neighbor to display information about\n"
14573 "Neighbor on BGP configured interface\n"
14574 "Display the routes selected by best path\n"
14575 "Display detailed version of routes\n"
14576 JSON_STR
14577 "Increase table width for longer prefixes\n")
14578 {
14579 afi_t afi = AFI_IP6;
14580 safi_t safi = SAFI_UNICAST;
14581 char *rmap_name = NULL;
14582 char *peerstr = NULL;
14583 struct bgp *bgp = NULL;
14584 struct peer *peer;
14585 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14586 int idx = 0;
14587 uint16_t show_flags = 0;
14588
14589 if (detail)
14590 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14591
14592 if (uj)
14593 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14594
14595 if (wide)
14596 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14597
14598 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14599 &bgp, uj);
14600
14601 if (!idx)
14602 return CMD_WARNING;
14603
14604 argv_find(argv, argc, "neighbors", &idx);
14605 peerstr = argv[++idx]->arg;
14606
14607 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14608 if (!peer)
14609 return CMD_WARNING;
14610
14611 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14612 show_flags);
14613 }
14614
14615 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14616 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14617 "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]",
14618 SHOW_STR
14619 IP_STR
14620 BGP_STR
14621 BGP_INSTANCE_HELP_STR
14622 BGP_AFI_HELP_STR
14623 BGP_SAFI_WITH_LABEL_HELP_STR
14624 "Display the entries for all address families\n"
14625 "Detailed information on TCP and BGP neighbor connections\n"
14626 "Neighbor to display information about\n"
14627 "Neighbor to display information about\n"
14628 "Neighbor on BGP configured interface\n"
14629 "Display the routes advertised to a BGP neighbor\n"
14630 "Display the received routes from neighbor\n"
14631 "Display the filtered routes received from neighbor\n"
14632 "Route-map to modify the attributes\n"
14633 "Name of the route map\n"
14634 "IPv4 prefix\n"
14635 "IPv6 prefix\n"
14636 "Display detailed version of routes\n"
14637 JSON_STR
14638 "Increase table width for longer prefixes\n")
14639 {
14640 afi_t afi = AFI_IP6;
14641 safi_t safi = SAFI_UNICAST;
14642 char *peerstr = NULL;
14643 struct bgp *bgp = NULL;
14644 struct peer *peer;
14645 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14646 int idx = 0;
14647 bool first = true;
14648 uint16_t show_flags = 0;
14649 struct listnode *node;
14650 struct bgp *abgp;
14651
14652 if (detail || prefix_str)
14653 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14654
14655 if (uj) {
14656 argc--;
14657 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14658 }
14659
14660 if (all) {
14661 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14662 if (argv_find(argv, argc, "ipv4", &idx))
14663 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14664
14665 if (argv_find(argv, argc, "ipv6", &idx))
14666 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14667 }
14668
14669 if (wide)
14670 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14671
14672 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14673 &bgp, uj);
14674 if (!idx)
14675 return CMD_WARNING;
14676
14677 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14678 argv_find(argv, argc, "neighbors", &idx);
14679 peerstr = argv[++idx]->arg;
14680
14681 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14682 if (!peer)
14683 return CMD_WARNING;
14684
14685 if (argv_find(argv, argc, "advertised-routes", &idx))
14686 type = bgp_show_adj_route_advertised;
14687 else if (argv_find(argv, argc, "received-routes", &idx))
14688 type = bgp_show_adj_route_received;
14689 else if (argv_find(argv, argc, "filtered-routes", &idx))
14690 type = bgp_show_adj_route_filtered;
14691
14692 if (!all)
14693 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14694 prefix_str ? prefix : NULL, show_flags);
14695 if (uj)
14696 vty_out(vty, "{\n");
14697
14698 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14699 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14700 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14701 : AFI_IP6;
14702 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14703 FOREACH_SAFI (safi) {
14704 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14705 continue;
14706
14707 if (uj) {
14708 if (first)
14709 first = false;
14710 else
14711 vty_out(vty, ",\n");
14712 vty_out(vty, "\"%s\":",
14713 get_afi_safi_str(afi, safi,
14714 true));
14715 } else
14716 vty_out(vty,
14717 "\nFor address family: %s\n",
14718 get_afi_safi_str(afi, safi,
14719 false));
14720
14721 peer_adj_routes(vty, peer, afi, safi, type,
14722 route_map, prefix, show_flags);
14723 }
14724 }
14725 } else {
14726 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14727 FOREACH_AFI_SAFI (afi, safi) {
14728 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14729 continue;
14730
14731 if (uj) {
14732 if (first)
14733 first = false;
14734 else
14735 vty_out(vty, ",\n");
14736 vty_out(vty, "\"%s\":",
14737 get_afi_safi_str(afi, safi,
14738 true));
14739 } else
14740 vty_out(vty,
14741 "\nFor address family: %s\n",
14742 get_afi_safi_str(afi, safi,
14743 false));
14744
14745 peer_adj_routes(vty, peer, afi, safi, type,
14746 route_map, prefix, show_flags);
14747 }
14748 }
14749 }
14750 if (uj)
14751 vty_out(vty, "}\n");
14752
14753 return CMD_SUCCESS;
14754 }
14755
14756 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14757 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14758 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14759 SHOW_STR
14760 IP_STR
14761 BGP_STR
14762 BGP_INSTANCE_HELP_STR
14763 BGP_AF_STR
14764 BGP_AF_STR
14765 BGP_AF_MODIFIER_STR
14766 "Detailed information on TCP and BGP neighbor connections\n"
14767 "Neighbor to display information about\n"
14768 "Neighbor to display information about\n"
14769 "Neighbor on BGP configured interface\n"
14770 "Display information received from a BGP neighbor\n"
14771 "Display the prefixlist filter\n"
14772 JSON_STR)
14773 {
14774 afi_t afi = AFI_IP6;
14775 safi_t safi = SAFI_UNICAST;
14776 char *peerstr = NULL;
14777 char name[BUFSIZ];
14778 struct peer *peer;
14779 int count;
14780 int idx = 0;
14781 struct bgp *bgp = NULL;
14782 bool uj = use_json(argc, argv);
14783
14784 if (uj)
14785 argc--;
14786
14787 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14788 &bgp, uj);
14789 if (!idx)
14790 return CMD_WARNING;
14791
14792 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14793 argv_find(argv, argc, "neighbors", &idx);
14794 peerstr = argv[++idx]->arg;
14795
14796 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14797 if (!peer)
14798 return CMD_WARNING;
14799
14800 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14801 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14802 if (count) {
14803 if (!uj)
14804 vty_out(vty, "Address Family: %s\n",
14805 get_afi_safi_str(afi, safi, false));
14806 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14807 } else {
14808 if (uj)
14809 vty_out(vty, "{}\n");
14810 else
14811 vty_out(vty, "No functional output\n");
14812 }
14813
14814 return CMD_SUCCESS;
14815 }
14816
14817 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14818 afi_t afi, safi_t safi,
14819 enum bgp_show_type type, bool use_json)
14820 {
14821 uint16_t show_flags = 0;
14822
14823 if (use_json)
14824 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14825
14826 if (!peer || !peer->afc[afi][safi]) {
14827 if (use_json) {
14828 json_object *json_no = NULL;
14829 json_no = json_object_new_object();
14830 json_object_string_add(
14831 json_no, "warning",
14832 "No such neighbor or address family");
14833 vty_out(vty, "%s\n",
14834 json_object_to_json_string(json_no));
14835 json_object_free(json_no);
14836 } else
14837 vty_out(vty, "%% No such neighbor or address family\n");
14838 return CMD_WARNING;
14839 }
14840
14841 /* labeled-unicast routes live in the unicast table */
14842 if (safi == SAFI_LABELED_UNICAST)
14843 safi = SAFI_UNICAST;
14844
14845 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14846 RPKI_NOT_BEING_USED);
14847 }
14848
14849 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14850 show_ip_bgp_flowspec_routes_detailed_cmd,
14851 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14852 SHOW_STR
14853 IP_STR
14854 BGP_STR
14855 BGP_INSTANCE_HELP_STR
14856 BGP_AFI_HELP_STR
14857 "SAFI Flowspec\n"
14858 "Detailed information on flowspec entries\n"
14859 JSON_STR)
14860 {
14861 afi_t afi = AFI_IP6;
14862 safi_t safi = SAFI_UNICAST;
14863 struct bgp *bgp = NULL;
14864 int idx = 0;
14865 bool uj = use_json(argc, argv);
14866 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14867
14868 if (uj) {
14869 argc--;
14870 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14871 }
14872
14873 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14874 &bgp, uj);
14875 if (!idx)
14876 return CMD_WARNING;
14877
14878 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14879 show_flags, RPKI_NOT_BEING_USED);
14880 }
14881
14882 DEFUN (show_ip_bgp_neighbor_routes,
14883 show_ip_bgp_neighbor_routes_cmd,
14884 "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]",
14885 SHOW_STR
14886 IP_STR
14887 BGP_STR
14888 BGP_INSTANCE_HELP_STR
14889 BGP_AFI_HELP_STR
14890 BGP_SAFI_WITH_LABEL_HELP_STR
14891 "Detailed information on TCP and BGP neighbor connections\n"
14892 "Neighbor to display information about\n"
14893 "Neighbor to display information about\n"
14894 "Neighbor on BGP configured interface\n"
14895 "Display flap statistics of the routes learned from neighbor\n"
14896 "Display the dampened routes received from neighbor\n"
14897 "Display routes learned from neighbor\n"
14898 JSON_STR)
14899 {
14900 char *peerstr = NULL;
14901 struct bgp *bgp = NULL;
14902 afi_t afi = AFI_IP6;
14903 safi_t safi = SAFI_UNICAST;
14904 struct peer *peer;
14905 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14906 int idx = 0;
14907 bool uj = use_json(argc, argv);
14908
14909 if (uj)
14910 argc--;
14911
14912 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14913 &bgp, uj);
14914 if (!idx)
14915 return CMD_WARNING;
14916
14917 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14918 argv_find(argv, argc, "neighbors", &idx);
14919 peerstr = argv[++idx]->arg;
14920
14921 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14922 if (!peer)
14923 return CMD_WARNING;
14924
14925 if (argv_find(argv, argc, "flap-statistics", &idx))
14926 sh_type = bgp_show_type_flap_neighbor;
14927 else if (argv_find(argv, argc, "dampened-routes", &idx))
14928 sh_type = bgp_show_type_damp_neighbor;
14929 else if (argv_find(argv, argc, "routes", &idx))
14930 sh_type = bgp_show_type_neighbor;
14931
14932 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14933 }
14934
14935 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14936
14937 struct bgp_distance {
14938 /* Distance value for the IP source prefix. */
14939 uint8_t distance;
14940
14941 /* Name of the access-list to be matched. */
14942 char *access_list;
14943 };
14944
14945 DEFUN (show_bgp_afi_vpn_rd_route,
14946 show_bgp_afi_vpn_rd_route_cmd,
14947 "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]",
14948 SHOW_STR
14949 BGP_STR
14950 BGP_AFI_HELP_STR
14951 BGP_AF_MODIFIER_STR
14952 "Display information for a route distinguisher\n"
14953 "Route Distinguisher\n"
14954 "All Route Distinguishers\n"
14955 "Network in the BGP routing table to display\n"
14956 "Network in the BGP routing table to display\n"
14957 JSON_STR)
14958 {
14959 int ret;
14960 struct prefix_rd prd;
14961 afi_t afi = AFI_MAX;
14962 int idx = 0;
14963
14964 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14965 vty_out(vty, "%% Malformed Address Family\n");
14966 return CMD_WARNING;
14967 }
14968
14969 if (!strcmp(argv[5]->arg, "all"))
14970 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14971 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14972 RPKI_NOT_BEING_USED,
14973 use_json(argc, argv));
14974
14975 ret = str2prefix_rd(argv[5]->arg, &prd);
14976 if (!ret) {
14977 vty_out(vty, "%% Malformed Route Distinguisher\n");
14978 return CMD_WARNING;
14979 }
14980
14981 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14982 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14983 use_json(argc, argv));
14984 }
14985
14986 static struct bgp_distance *bgp_distance_new(void)
14987 {
14988 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14989 }
14990
14991 static void bgp_distance_free(struct bgp_distance *bdistance)
14992 {
14993 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14994 }
14995
14996 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14997 const char *ip_str, const char *access_list_str)
14998 {
14999 int ret;
15000 afi_t afi;
15001 safi_t safi;
15002 struct prefix p;
15003 uint8_t distance;
15004 struct bgp_dest *dest;
15005 struct bgp_distance *bdistance;
15006
15007 afi = bgp_node_afi(vty);
15008 safi = bgp_node_safi(vty);
15009
15010 ret = str2prefix(ip_str, &p);
15011 if (ret == 0) {
15012 vty_out(vty, "Malformed prefix\n");
15013 return CMD_WARNING_CONFIG_FAILED;
15014 }
15015
15016 distance = atoi(distance_str);
15017
15018 /* Get BGP distance node. */
15019 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15020 bdistance = bgp_dest_get_bgp_distance_info(dest);
15021 if (bdistance)
15022 bgp_dest_unlock_node(dest);
15023 else {
15024 bdistance = bgp_distance_new();
15025 bgp_dest_set_bgp_distance_info(dest, bdistance);
15026 }
15027
15028 /* Set distance value. */
15029 bdistance->distance = distance;
15030
15031 /* Reset access-list configuration. */
15032 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15033 if (access_list_str)
15034 bdistance->access_list =
15035 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15036
15037 return CMD_SUCCESS;
15038 }
15039
15040 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15041 const char *ip_str, const char *access_list_str)
15042 {
15043 int ret;
15044 afi_t afi;
15045 safi_t safi;
15046 struct prefix p;
15047 int distance;
15048 struct bgp_dest *dest;
15049 struct bgp_distance *bdistance;
15050
15051 afi = bgp_node_afi(vty);
15052 safi = bgp_node_safi(vty);
15053
15054 ret = str2prefix(ip_str, &p);
15055 if (ret == 0) {
15056 vty_out(vty, "Malformed prefix\n");
15057 return CMD_WARNING_CONFIG_FAILED;
15058 }
15059
15060 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15061 if (!dest) {
15062 vty_out(vty, "Can't find specified prefix\n");
15063 return CMD_WARNING_CONFIG_FAILED;
15064 }
15065
15066 bdistance = bgp_dest_get_bgp_distance_info(dest);
15067 distance = atoi(distance_str);
15068
15069 if (bdistance->distance != distance) {
15070 vty_out(vty, "Distance does not match configured\n");
15071 bgp_dest_unlock_node(dest);
15072 return CMD_WARNING_CONFIG_FAILED;
15073 }
15074
15075 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15076 bgp_distance_free(bdistance);
15077
15078 bgp_dest_set_bgp_path_info(dest, NULL);
15079 bgp_dest_unlock_node(dest);
15080 bgp_dest_unlock_node(dest);
15081
15082 return CMD_SUCCESS;
15083 }
15084
15085 /* Apply BGP information to distance method. */
15086 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15087 afi_t afi, safi_t safi, struct bgp *bgp)
15088 {
15089 struct bgp_dest *dest;
15090 struct prefix q = {0};
15091 struct peer *peer;
15092 struct bgp_distance *bdistance;
15093 struct access_list *alist;
15094 struct bgp_static *bgp_static;
15095 struct bgp_path_info *bpi_ultimate;
15096
15097 if (!bgp)
15098 return 0;
15099
15100 peer = pinfo->peer;
15101
15102 if (pinfo->attr->distance)
15103 return pinfo->attr->distance;
15104
15105 /* get peer origin to calculate appropriate distance */
15106 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15107 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15108 peer = bpi_ultimate->peer;
15109 }
15110
15111 /* Check source address.
15112 * Note: for aggregate route, peer can have unspec af type.
15113 */
15114 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15115 && !sockunion2hostprefix(&peer->su, &q))
15116 return 0;
15117
15118 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15119 if (dest) {
15120 bdistance = bgp_dest_get_bgp_distance_info(dest);
15121 bgp_dest_unlock_node(dest);
15122
15123 if (bdistance->access_list) {
15124 alist = access_list_lookup(afi, bdistance->access_list);
15125 if (alist
15126 && access_list_apply(alist, p) == FILTER_PERMIT)
15127 return bdistance->distance;
15128 } else
15129 return bdistance->distance;
15130 }
15131
15132 /* Backdoor check. */
15133 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15134 if (dest) {
15135 bgp_static = bgp_dest_get_bgp_static_info(dest);
15136 bgp_dest_unlock_node(dest);
15137
15138 if (bgp_static->backdoor) {
15139 if (bgp->distance_local[afi][safi])
15140 return bgp->distance_local[afi][safi];
15141 else
15142 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15143 }
15144 }
15145
15146 if (peer->sort == BGP_PEER_EBGP) {
15147 if (bgp->distance_ebgp[afi][safi])
15148 return bgp->distance_ebgp[afi][safi];
15149 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15150 } else if (peer->sort == BGP_PEER_IBGP) {
15151 if (bgp->distance_ibgp[afi][safi])
15152 return bgp->distance_ibgp[afi][safi];
15153 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15154 } else {
15155 if (bgp->distance_local[afi][safi])
15156 return bgp->distance_local[afi][safi];
15157 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15158 }
15159 }
15160
15161 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15162 * we should tell ZEBRA update the routes for a specific
15163 * AFI/SAFI to reflect changes in RIB.
15164 */
15165 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15166 afi_t update_afi,
15167 safi_t update_safi)
15168 {
15169 afi_t afi;
15170 safi_t safi;
15171
15172 FOREACH_AFI_SAFI (afi, safi) {
15173 if (!bgp_fibupd_safi(safi))
15174 continue;
15175
15176 if (afi != update_afi && safi != update_safi)
15177 continue;
15178
15179 if (BGP_DEBUG(zebra, ZEBRA))
15180 zlog_debug(
15181 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15182 __func__, afi, safi);
15183 bgp_zebra_announce_table(bgp, afi, safi);
15184 }
15185 }
15186
15187 DEFUN (bgp_distance,
15188 bgp_distance_cmd,
15189 "distance bgp (1-255) (1-255) (1-255)",
15190 "Define an administrative distance\n"
15191 "BGP distance\n"
15192 "Distance for routes external to the AS\n"
15193 "Distance for routes internal to the AS\n"
15194 "Distance for local routes\n")
15195 {
15196 VTY_DECLVAR_CONTEXT(bgp, bgp);
15197 int idx_number = 2;
15198 int idx_number_2 = 3;
15199 int idx_number_3 = 4;
15200 int distance_ebgp = atoi(argv[idx_number]->arg);
15201 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15202 int distance_local = atoi(argv[idx_number_3]->arg);
15203 afi_t afi;
15204 safi_t safi;
15205
15206 afi = bgp_node_afi(vty);
15207 safi = bgp_node_safi(vty);
15208
15209 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15210 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15211 || bgp->distance_local[afi][safi] != distance_local) {
15212 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15213 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15214 bgp->distance_local[afi][safi] = distance_local;
15215 bgp_announce_routes_distance_update(bgp, afi, safi);
15216 }
15217 return CMD_SUCCESS;
15218 }
15219
15220 DEFUN (no_bgp_distance,
15221 no_bgp_distance_cmd,
15222 "no distance bgp [(1-255) (1-255) (1-255)]",
15223 NO_STR
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 afi_t afi;
15232 safi_t safi;
15233
15234 afi = bgp_node_afi(vty);
15235 safi = bgp_node_safi(vty);
15236
15237 if (bgp->distance_ebgp[afi][safi] != 0
15238 || bgp->distance_ibgp[afi][safi] != 0
15239 || bgp->distance_local[afi][safi] != 0) {
15240 bgp->distance_ebgp[afi][safi] = 0;
15241 bgp->distance_ibgp[afi][safi] = 0;
15242 bgp->distance_local[afi][safi] = 0;
15243 bgp_announce_routes_distance_update(bgp, afi, safi);
15244 }
15245 return CMD_SUCCESS;
15246 }
15247
15248
15249 DEFUN (bgp_distance_source,
15250 bgp_distance_source_cmd,
15251 "distance (1-255) A.B.C.D/M",
15252 "Define an administrative distance\n"
15253 "Administrative distance\n"
15254 "IP source prefix\n")
15255 {
15256 int idx_number = 1;
15257 int idx_ipv4_prefixlen = 2;
15258 bgp_distance_set(vty, argv[idx_number]->arg,
15259 argv[idx_ipv4_prefixlen]->arg, NULL);
15260 return CMD_SUCCESS;
15261 }
15262
15263 DEFUN (no_bgp_distance_source,
15264 no_bgp_distance_source_cmd,
15265 "no distance (1-255) A.B.C.D/M",
15266 NO_STR
15267 "Define an administrative distance\n"
15268 "Administrative distance\n"
15269 "IP source prefix\n")
15270 {
15271 int idx_number = 2;
15272 int idx_ipv4_prefixlen = 3;
15273 bgp_distance_unset(vty, argv[idx_number]->arg,
15274 argv[idx_ipv4_prefixlen]->arg, NULL);
15275 return CMD_SUCCESS;
15276 }
15277
15278 DEFUN (bgp_distance_source_access_list,
15279 bgp_distance_source_access_list_cmd,
15280 "distance (1-255) A.B.C.D/M WORD",
15281 "Define an administrative distance\n"
15282 "Administrative distance\n"
15283 "IP source prefix\n"
15284 "Access list name\n")
15285 {
15286 int idx_number = 1;
15287 int idx_ipv4_prefixlen = 2;
15288 int idx_word = 3;
15289 bgp_distance_set(vty, argv[idx_number]->arg,
15290 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15291 return CMD_SUCCESS;
15292 }
15293
15294 DEFUN (no_bgp_distance_source_access_list,
15295 no_bgp_distance_source_access_list_cmd,
15296 "no distance (1-255) A.B.C.D/M WORD",
15297 NO_STR
15298 "Define an administrative distance\n"
15299 "Administrative distance\n"
15300 "IP source prefix\n"
15301 "Access list name\n")
15302 {
15303 int idx_number = 2;
15304 int idx_ipv4_prefixlen = 3;
15305 int idx_word = 4;
15306 bgp_distance_unset(vty, argv[idx_number]->arg,
15307 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15308 return CMD_SUCCESS;
15309 }
15310
15311 DEFUN (ipv6_bgp_distance_source,
15312 ipv6_bgp_distance_source_cmd,
15313 "distance (1-255) X:X::X:X/M",
15314 "Define an administrative distance\n"
15315 "Administrative distance\n"
15316 "IP source prefix\n")
15317 {
15318 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15319 return CMD_SUCCESS;
15320 }
15321
15322 DEFUN (no_ipv6_bgp_distance_source,
15323 no_ipv6_bgp_distance_source_cmd,
15324 "no distance (1-255) X:X::X:X/M",
15325 NO_STR
15326 "Define an administrative distance\n"
15327 "Administrative distance\n"
15328 "IP source prefix\n")
15329 {
15330 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15331 return CMD_SUCCESS;
15332 }
15333
15334 DEFUN (ipv6_bgp_distance_source_access_list,
15335 ipv6_bgp_distance_source_access_list_cmd,
15336 "distance (1-255) X:X::X:X/M WORD",
15337 "Define an administrative distance\n"
15338 "Administrative distance\n"
15339 "IP source prefix\n"
15340 "Access list name\n")
15341 {
15342 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15343 return CMD_SUCCESS;
15344 }
15345
15346 DEFUN (no_ipv6_bgp_distance_source_access_list,
15347 no_ipv6_bgp_distance_source_access_list_cmd,
15348 "no distance (1-255) X:X::X:X/M WORD",
15349 NO_STR
15350 "Define an administrative distance\n"
15351 "Administrative distance\n"
15352 "IP source prefix\n"
15353 "Access list name\n")
15354 {
15355 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15356 return CMD_SUCCESS;
15357 }
15358
15359 DEFUN (bgp_damp_set,
15360 bgp_damp_set_cmd,
15361 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15362 "BGP Specific commands\n"
15363 "Enable route-flap dampening\n"
15364 "Half-life time for the penalty\n"
15365 "Value to start reusing a route\n"
15366 "Value to start suppressing a route\n"
15367 "Maximum duration to suppress a stable route\n")
15368 {
15369 VTY_DECLVAR_CONTEXT(bgp, bgp);
15370 int idx_half_life = 2;
15371 int idx_reuse = 3;
15372 int idx_suppress = 4;
15373 int idx_max_suppress = 5;
15374 int half = DEFAULT_HALF_LIFE * 60;
15375 int reuse = DEFAULT_REUSE;
15376 int suppress = DEFAULT_SUPPRESS;
15377 int max = 4 * half;
15378
15379 if (argc == 6) {
15380 half = atoi(argv[idx_half_life]->arg) * 60;
15381 reuse = atoi(argv[idx_reuse]->arg);
15382 suppress = atoi(argv[idx_suppress]->arg);
15383 max = atoi(argv[idx_max_suppress]->arg) * 60;
15384 } else if (argc == 3) {
15385 half = atoi(argv[idx_half_life]->arg) * 60;
15386 max = 4 * half;
15387 }
15388
15389 /*
15390 * These can't be 0 but our SA doesn't understand the
15391 * way our cli is constructed
15392 */
15393 assert(reuse);
15394 assert(half);
15395 if (suppress < reuse) {
15396 vty_out(vty,
15397 "Suppress value cannot be less than reuse value \n");
15398 return 0;
15399 }
15400
15401 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15402 reuse, suppress, max);
15403 }
15404
15405 DEFUN (bgp_damp_unset,
15406 bgp_damp_unset_cmd,
15407 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15408 NO_STR
15409 "BGP Specific commands\n"
15410 "Enable route-flap dampening\n"
15411 "Half-life time for the penalty\n"
15412 "Value to start reusing a route\n"
15413 "Value to start suppressing a route\n"
15414 "Maximum duration to suppress a stable route\n")
15415 {
15416 VTY_DECLVAR_CONTEXT(bgp, bgp);
15417 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15418 }
15419
15420 /* Display specified route of BGP table. */
15421 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15422 const char *ip_str, afi_t afi, safi_t safi,
15423 struct prefix_rd *prd, int prefix_check)
15424 {
15425 int ret;
15426 struct prefix match;
15427 struct bgp_dest *dest;
15428 struct bgp_dest *rm;
15429 struct bgp_path_info *pi;
15430 struct bgp_path_info *pi_temp;
15431 struct bgp *bgp;
15432 struct bgp_table *table;
15433
15434 /* BGP structure lookup. */
15435 if (view_name) {
15436 bgp = bgp_lookup_by_name(view_name);
15437 if (bgp == NULL) {
15438 vty_out(vty, "%% Can't find BGP instance %s\n",
15439 view_name);
15440 return CMD_WARNING;
15441 }
15442 } else {
15443 bgp = bgp_get_default();
15444 if (bgp == NULL) {
15445 vty_out(vty, "%% No BGP process is configured\n");
15446 return CMD_WARNING;
15447 }
15448 }
15449
15450 /* Check IP address argument. */
15451 ret = str2prefix(ip_str, &match);
15452 if (!ret) {
15453 vty_out(vty, "%% address is malformed\n");
15454 return CMD_WARNING;
15455 }
15456
15457 match.family = afi2family(afi);
15458
15459 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15460 || (safi == SAFI_EVPN)) {
15461 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15462 dest = bgp_route_next(dest)) {
15463 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15464
15465 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15466 continue;
15467 table = bgp_dest_get_bgp_table_info(dest);
15468 if (!table)
15469 continue;
15470 rm = bgp_node_match(table, &match);
15471 if (rm == NULL)
15472 continue;
15473
15474 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15475
15476 if (!prefix_check
15477 || rm_p->prefixlen == match.prefixlen) {
15478 pi = bgp_dest_get_bgp_path_info(rm);
15479 while (pi) {
15480 if (pi->extra && pi->extra->damp_info) {
15481 pi_temp = pi->next;
15482 bgp_damp_info_free(
15483 pi->extra->damp_info,
15484 1, afi, safi);
15485 pi = pi_temp;
15486 } else
15487 pi = pi->next;
15488 }
15489 }
15490
15491 bgp_dest_unlock_node(rm);
15492 }
15493 } else {
15494 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15495 if (dest != NULL) {
15496 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15497
15498 if (!prefix_check
15499 || dest_p->prefixlen == match.prefixlen) {
15500 pi = bgp_dest_get_bgp_path_info(dest);
15501 while (pi) {
15502 if (pi->extra && pi->extra->damp_info) {
15503 pi_temp = pi->next;
15504 bgp_damp_info_free(
15505 pi->extra->damp_info,
15506 1, afi, safi);
15507 pi = pi_temp;
15508 } else
15509 pi = pi->next;
15510 }
15511 }
15512
15513 bgp_dest_unlock_node(dest);
15514 }
15515 }
15516
15517 return CMD_SUCCESS;
15518 }
15519
15520 DEFUN (clear_ip_bgp_dampening,
15521 clear_ip_bgp_dampening_cmd,
15522 "clear ip bgp dampening",
15523 CLEAR_STR
15524 IP_STR
15525 BGP_STR
15526 "Clear route flap dampening information\n")
15527 {
15528 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15529 return CMD_SUCCESS;
15530 }
15531
15532 DEFUN (clear_ip_bgp_dampening_prefix,
15533 clear_ip_bgp_dampening_prefix_cmd,
15534 "clear ip bgp dampening A.B.C.D/M",
15535 CLEAR_STR
15536 IP_STR
15537 BGP_STR
15538 "Clear route flap dampening information\n"
15539 "IPv4 prefix\n")
15540 {
15541 int idx_ipv4_prefixlen = 4;
15542 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15543 AFI_IP, SAFI_UNICAST, NULL, 1);
15544 }
15545
15546 DEFUN (clear_ip_bgp_dampening_address,
15547 clear_ip_bgp_dampening_address_cmd,
15548 "clear ip bgp dampening A.B.C.D",
15549 CLEAR_STR
15550 IP_STR
15551 BGP_STR
15552 "Clear route flap dampening information\n"
15553 "Network to clear damping information\n")
15554 {
15555 int idx_ipv4 = 4;
15556 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15557 SAFI_UNICAST, NULL, 0);
15558 }
15559
15560 DEFUN (clear_ip_bgp_dampening_address_mask,
15561 clear_ip_bgp_dampening_address_mask_cmd,
15562 "clear ip bgp dampening A.B.C.D A.B.C.D",
15563 CLEAR_STR
15564 IP_STR
15565 BGP_STR
15566 "Clear route flap dampening information\n"
15567 "Network to clear damping information\n"
15568 "Network mask\n")
15569 {
15570 int idx_ipv4 = 4;
15571 int idx_ipv4_2 = 5;
15572 int ret;
15573 char prefix_str[BUFSIZ];
15574
15575 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15576 prefix_str, sizeof(prefix_str));
15577 if (!ret) {
15578 vty_out(vty, "%% Inconsistent address and mask\n");
15579 return CMD_WARNING;
15580 }
15581
15582 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15583 NULL, 0);
15584 }
15585
15586 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15587 {
15588 struct vty *vty = arg;
15589 struct peer *peer = bucket->data;
15590
15591 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15592 }
15593
15594 DEFUN (show_bgp_listeners,
15595 show_bgp_listeners_cmd,
15596 "show bgp listeners",
15597 SHOW_STR
15598 BGP_STR
15599 "Display Listen Sockets and who created them\n")
15600 {
15601 bgp_dump_listener_info(vty);
15602
15603 return CMD_SUCCESS;
15604 }
15605
15606 DEFUN (show_bgp_peerhash,
15607 show_bgp_peerhash_cmd,
15608 "show bgp peerhash",
15609 SHOW_STR
15610 BGP_STR
15611 "Display information about the BGP peerhash\n")
15612 {
15613 struct list *instances = bm->bgp;
15614 struct listnode *node;
15615 struct bgp *bgp;
15616
15617 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15618 vty_out(vty, "BGP: %s\n", bgp->name);
15619 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15620 vty);
15621 }
15622
15623 return CMD_SUCCESS;
15624 }
15625
15626 /* also used for encap safi */
15627 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15628 afi_t afi, safi_t safi)
15629 {
15630 struct bgp_dest *pdest;
15631 struct bgp_dest *dest;
15632 struct bgp_table *table;
15633 const struct prefix *p;
15634 struct bgp_static *bgp_static;
15635 mpls_label_t label;
15636
15637 /* Network configuration. */
15638 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15639 pdest = bgp_route_next(pdest)) {
15640 table = bgp_dest_get_bgp_table_info(pdest);
15641 if (!table)
15642 continue;
15643
15644 for (dest = bgp_table_top(table); dest;
15645 dest = bgp_route_next(dest)) {
15646 bgp_static = bgp_dest_get_bgp_static_info(dest);
15647 if (bgp_static == NULL)
15648 continue;
15649
15650 p = bgp_dest_get_prefix(dest);
15651
15652 /* "network" configuration display. */
15653 label = decode_label(&bgp_static->label);
15654
15655 vty_out(vty, " network %pFX rd %s", p,
15656 bgp_static->prd_pretty);
15657 if (safi == SAFI_MPLS_VPN)
15658 vty_out(vty, " label %u", label);
15659
15660 if (bgp_static->rmap.name)
15661 vty_out(vty, " route-map %s",
15662 bgp_static->rmap.name);
15663
15664 if (bgp_static->backdoor)
15665 vty_out(vty, " backdoor");
15666
15667 vty_out(vty, "\n");
15668 }
15669 }
15670 }
15671
15672 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15673 afi_t afi, safi_t safi)
15674 {
15675 struct bgp_dest *pdest;
15676 struct bgp_dest *dest;
15677 struct bgp_table *table;
15678 const struct prefix *p;
15679 struct bgp_static *bgp_static;
15680 char buf[PREFIX_STRLEN * 2];
15681 char buf2[SU_ADDRSTRLEN];
15682 char esi_buf[ESI_STR_LEN];
15683
15684 /* Network configuration. */
15685 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15686 pdest = bgp_route_next(pdest)) {
15687 table = bgp_dest_get_bgp_table_info(pdest);
15688 if (!table)
15689 continue;
15690
15691 for (dest = bgp_table_top(table); dest;
15692 dest = bgp_route_next(dest)) {
15693 bgp_static = bgp_dest_get_bgp_static_info(dest);
15694 if (bgp_static == NULL)
15695 continue;
15696
15697 char *macrouter = NULL;
15698
15699 if (bgp_static->router_mac)
15700 macrouter = prefix_mac2str(
15701 bgp_static->router_mac, NULL, 0);
15702 if (bgp_static->eth_s_id)
15703 esi_to_str(bgp_static->eth_s_id,
15704 esi_buf, sizeof(esi_buf));
15705 p = bgp_dest_get_prefix(dest);
15706
15707 /* "network" configuration display. */
15708 if (p->u.prefix_evpn.route_type == 5) {
15709 char local_buf[PREFIX_STRLEN];
15710
15711 uint8_t family = is_evpn_prefix_ipaddr_v4((
15712 struct prefix_evpn *)p)
15713 ? AF_INET
15714 : AF_INET6;
15715 inet_ntop(family,
15716 &p->u.prefix_evpn.prefix_addr.ip.ip
15717 .addr,
15718 local_buf, sizeof(local_buf));
15719 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15720 p->u.prefix_evpn.prefix_addr
15721 .ip_prefix_length);
15722 } else {
15723 prefix2str(p, buf, sizeof(buf));
15724 }
15725
15726 if (bgp_static->gatewayIp.family == AF_INET
15727 || bgp_static->gatewayIp.family == AF_INET6)
15728 inet_ntop(bgp_static->gatewayIp.family,
15729 &bgp_static->gatewayIp.u.prefix, buf2,
15730 sizeof(buf2));
15731 vty_out(vty,
15732 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15733 buf, bgp_static->prd_pretty,
15734 p->u.prefix_evpn.prefix_addr.eth_tag,
15735 decode_label(&bgp_static->label), esi_buf, buf2,
15736 macrouter);
15737
15738 XFREE(MTYPE_TMP, macrouter);
15739 }
15740 }
15741 }
15742
15743 /* Configuration of static route announcement and aggregate
15744 information. */
15745 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15746 safi_t safi)
15747 {
15748 struct bgp_dest *dest;
15749 const struct prefix *p;
15750 struct bgp_static *bgp_static;
15751 struct bgp_aggregate *bgp_aggregate;
15752
15753 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15754 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15755 return;
15756 }
15757
15758 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15759 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15760 return;
15761 }
15762
15763 /* Network configuration. */
15764 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15765 dest = bgp_route_next(dest)) {
15766 bgp_static = bgp_dest_get_bgp_static_info(dest);
15767 if (bgp_static == NULL)
15768 continue;
15769
15770 p = bgp_dest_get_prefix(dest);
15771
15772 vty_out(vty, " network %pFX", p);
15773
15774 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15775 vty_out(vty, " label-index %u",
15776 bgp_static->label_index);
15777
15778 if (bgp_static->rmap.name)
15779 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15780
15781 if (bgp_static->backdoor)
15782 vty_out(vty, " backdoor");
15783
15784 vty_out(vty, "\n");
15785 }
15786
15787 /* Aggregate-address configuration. */
15788 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15789 dest = bgp_route_next(dest)) {
15790 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15791 if (bgp_aggregate == NULL)
15792 continue;
15793
15794 p = bgp_dest_get_prefix(dest);
15795
15796 vty_out(vty, " aggregate-address %pFX", p);
15797
15798 if (bgp_aggregate->as_set)
15799 vty_out(vty, " as-set");
15800
15801 if (bgp_aggregate->summary_only)
15802 vty_out(vty, " summary-only");
15803
15804 if (bgp_aggregate->rmap.name)
15805 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15806
15807 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15808 vty_out(vty, " origin %s",
15809 bgp_origin2str(bgp_aggregate->origin));
15810
15811 if (bgp_aggregate->match_med)
15812 vty_out(vty, " matching-MED-only");
15813
15814 if (bgp_aggregate->suppress_map_name)
15815 vty_out(vty, " suppress-map %s",
15816 bgp_aggregate->suppress_map_name);
15817
15818 vty_out(vty, "\n");
15819 }
15820 }
15821
15822 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15823 safi_t safi)
15824 {
15825 struct bgp_dest *dest;
15826 struct bgp_distance *bdistance;
15827
15828 /* Distance configuration. */
15829 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15830 && bgp->distance_local[afi][safi]
15831 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15832 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15833 || bgp->distance_local[afi][safi]
15834 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15835 vty_out(vty, " distance bgp %d %d %d\n",
15836 bgp->distance_ebgp[afi][safi],
15837 bgp->distance_ibgp[afi][safi],
15838 bgp->distance_local[afi][safi]);
15839 }
15840
15841 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15842 dest = bgp_route_next(dest)) {
15843 bdistance = bgp_dest_get_bgp_distance_info(dest);
15844 if (bdistance != NULL)
15845 vty_out(vty, " distance %d %pBD %s\n",
15846 bdistance->distance, dest,
15847 bdistance->access_list ? bdistance->access_list
15848 : "");
15849 }
15850 }
15851
15852 /* Allocate routing table structure and install commands. */
15853 void bgp_route_init(void)
15854 {
15855 afi_t afi;
15856 safi_t safi;
15857
15858 /* Init BGP distance table. */
15859 FOREACH_AFI_SAFI (afi, safi)
15860 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15861
15862 /* IPv4 BGP commands. */
15863 install_element(BGP_NODE, &bgp_table_map_cmd);
15864 install_element(BGP_NODE, &bgp_network_cmd);
15865 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15866
15867 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15868
15869 /* IPv4 unicast configuration. */
15870 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15871 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15872 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15873
15874 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15875
15876 /* IPv4 multicast configuration. */
15877 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15878 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15879 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15880 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15881
15882 /* IPv4 labeled-unicast configuration. */
15883 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15884 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15885
15886 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15887 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15888 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15889 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15890 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15891 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15892 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15893 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15894
15895 install_element(VIEW_NODE,
15896 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15897 install_element(VIEW_NODE,
15898 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15899 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15900 install_element(VIEW_NODE,
15901 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15902 #ifdef KEEP_OLD_VPN_COMMANDS
15903 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15904 #endif /* KEEP_OLD_VPN_COMMANDS */
15905 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15906 install_element(VIEW_NODE,
15907 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15908
15909 /* BGP dampening clear commands */
15910 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15911 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15912
15913 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15914 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15915
15916 /* prefix count */
15917 install_element(ENABLE_NODE,
15918 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15919 #ifdef KEEP_OLD_VPN_COMMANDS
15920 install_element(ENABLE_NODE,
15921 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15922 #endif /* KEEP_OLD_VPN_COMMANDS */
15923
15924 /* New config IPv6 BGP commands. */
15925 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15926 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15927 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15928
15929 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15930
15931 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15932
15933 /* IPv6 labeled unicast address family. */
15934 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15935 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15936
15937 install_element(BGP_NODE, &bgp_distance_cmd);
15938 install_element(BGP_NODE, &no_bgp_distance_cmd);
15939 install_element(BGP_NODE, &bgp_distance_source_cmd);
15940 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15941 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15942 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15943 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15944 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15945 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15946 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15947 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15948 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15949 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15950 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15951 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15952 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15953 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15954 install_element(BGP_IPV4M_NODE,
15955 &no_bgp_distance_source_access_list_cmd);
15956 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15957 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15958 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15959 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15960 install_element(BGP_IPV6_NODE,
15961 &ipv6_bgp_distance_source_access_list_cmd);
15962 install_element(BGP_IPV6_NODE,
15963 &no_ipv6_bgp_distance_source_access_list_cmd);
15964 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15965 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15966 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15967 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15968 install_element(BGP_IPV6M_NODE,
15969 &ipv6_bgp_distance_source_access_list_cmd);
15970 install_element(BGP_IPV6M_NODE,
15971 &no_ipv6_bgp_distance_source_access_list_cmd);
15972
15973 /* BGP dampening */
15974 install_element(BGP_NODE, &bgp_damp_set_cmd);
15975 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15976 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15977 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15978 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15979 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15980 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15981 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15982 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15983 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15984 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15985 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15986 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15987 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15988
15989 /* Large Communities */
15990 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15991 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15992
15993 /* show bgp ipv4 flowspec detailed */
15994 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15995
15996 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15997 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15998 }
15999
16000 void bgp_route_finish(void)
16001 {
16002 afi_t afi;
16003 safi_t safi;
16004
16005 FOREACH_AFI_SAFI (afi, safi) {
16006 bgp_table_unlock(bgp_distance_table[afi][safi]);
16007 bgp_distance_table[afi][safi] = NULL;
16008 }
16009 }