]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #13159 from mjstapp/ospf_sockets
[mirror_frr.git] / bgpd / bgp_route.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP routing information
3 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
4 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 */
6
7 #include <zebra.h>
8 #include <math.h>
9
10 #include "printfrr.h"
11 #include "frrstr.h"
12 #include "prefix.h"
13 #include "linklist.h"
14 #include "memory.h"
15 #include "command.h"
16 #include "stream.h"
17 #include "filter.h"
18 #include "log.h"
19 #include "routemap.h"
20 #include "buffer.h"
21 #include "sockunion.h"
22 #include "plist.h"
23 #include "frrevent.h"
24 #include "workqueue.h"
25 #include "queue.h"
26 #include "memory.h"
27 #include "srv6.h"
28 #include "lib/json.h"
29 #include "lib_errors.h"
30 #include "zclient.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_regex.h"
39 #include "bgpd/bgp_community.h"
40 #include "bgpd/bgp_community_alias.h"
41 #include "bgpd/bgp_ecommunity.h"
42 #include "bgpd/bgp_lcommunity.h"
43 #include "bgpd/bgp_clist.h"
44 #include "bgpd/bgp_packet.h"
45 #include "bgpd/bgp_filter.h"
46 #include "bgpd/bgp_fsm.h"
47 #include "bgpd/bgp_mplsvpn.h"
48 #include "bgpd/bgp_nexthop.h"
49 #include "bgpd/bgp_damp.h"
50 #include "bgpd/bgp_advertise.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_vty.h"
53 #include "bgpd/bgp_mpath.h"
54 #include "bgpd/bgp_nht.h"
55 #include "bgpd/bgp_updgrp.h"
56 #include "bgpd/bgp_label.h"
57 #include "bgpd/bgp_addpath.h"
58 #include "bgpd/bgp_mac.h"
59 #include "bgpd/bgp_network.h"
60 #include "bgpd/bgp_trace.h"
61 #include "bgpd/bgp_rpki.h"
62
63 #ifdef ENABLE_BGP_VNC
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #include "bgpd/rfapi/vnc_import_bgp.h"
66 #include "bgpd/rfapi/vnc_export_bgp.h"
67 #endif
68 #include "bgpd/bgp_encap_types.h"
69 #include "bgpd/bgp_encap_tlv.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_evpn_mh.h"
72 #include "bgpd/bgp_evpn_vty.h"
73 #include "bgpd/bgp_flowspec.h"
74 #include "bgpd/bgp_flowspec_util.h"
75 #include "bgpd/bgp_pbr.h"
76
77 #include "bgpd/bgp_route_clippy.c"
78
79 DEFINE_HOOK(bgp_snmp_update_stats,
80 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
81 (rn, pi, added));
82
83 DEFINE_HOOK(bgp_rpki_prefix_status,
84 (struct peer *peer, struct attr *attr,
85 const struct prefix *prefix),
86 (peer, attr, prefix));
87
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str[];
90 extern const char *bgp_origin_long_str[];
91
92 /* PMSI strings. */
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str[] = {
96 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
104 {0}
105 };
106
107 #define VRFID_NONE_STR "-"
108 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
109
110 DEFINE_HOOK(bgp_process,
111 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
112 struct peer *peer, bool withdraw),
113 (bgp, afi, safi, bn, peer, withdraw));
114
115 /** Test if path is suppressed. */
116 static bool bgp_path_suppressed(struct bgp_path_info *pi)
117 {
118 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
119 return false;
120
121 return listcount(pi->extra->aggr_suppressors) > 0;
122 }
123
124 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
125 safi_t safi, const struct prefix *p,
126 struct prefix_rd *prd)
127 {
128 struct bgp_dest *dest;
129 struct bgp_dest *pdest = NULL;
130
131 assert(table);
132
133 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
134 || (safi == SAFI_EVPN)) {
135 pdest = bgp_node_get(table, (struct prefix *)prd);
136
137 if (!bgp_dest_has_bgp_path_info_data(pdest))
138 bgp_dest_set_bgp_table_info(
139 pdest, bgp_table_init(table->bgp, afi, safi));
140 else
141 bgp_dest_unlock_node(pdest);
142 table = bgp_dest_get_bgp_table_info(pdest);
143 }
144
145 dest = bgp_node_get(table, p);
146
147 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
148 || (safi == SAFI_EVPN))
149 dest->pdest = pdest;
150
151 return dest;
152 }
153
154 struct bgp_dest *bgp_safi_node_lookup(struct bgp_table *table, safi_t safi,
155 const struct prefix *p,
156 struct prefix_rd *prd)
157 {
158 struct bgp_dest *dest;
159 struct bgp_dest *pdest = NULL;
160
161 if (!table)
162 return NULL;
163
164 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
165 || (safi == SAFI_EVPN)) {
166 pdest = bgp_node_lookup(table, (struct prefix *)prd);
167 if (!pdest)
168 return NULL;
169
170 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
171 bgp_dest_unlock_node(pdest);
172 return NULL;
173 }
174
175 table = bgp_dest_get_bgp_table_info(pdest);
176 }
177
178 dest = bgp_node_lookup(table, p);
179
180 return dest;
181 }
182
183 /* Allocate bgp_path_info_extra */
184 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
185 {
186 struct bgp_path_info_extra *new;
187 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
188 sizeof(struct bgp_path_info_extra));
189 new->label[0] = MPLS_INVALID_LABEL;
190 new->num_labels = 0;
191 new->bgp_fs_pbr = NULL;
192 new->bgp_fs_iprule = NULL;
193 return new;
194 }
195
196 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
197 {
198 struct bgp_path_info_extra *e;
199
200 if (!extra || !*extra)
201 return;
202
203 e = *extra;
204 if (e->damp_info)
205 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
206 e->damp_info->safi);
207
208 e->damp_info = NULL;
209 if (e->parent) {
210 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
211
212 if (bpi->net) {
213 /* FIXME: since multiple e may have the same e->parent
214 * and e->parent->net is holding a refcount for each
215 * of them, we need to do some fudging here.
216 *
217 * WARNING: if bpi->net->lock drops to 0, bpi may be
218 * freed as well (because bpi->net was holding the
219 * last reference to bpi) => write after free!
220 */
221 unsigned refcount;
222
223 bpi = bgp_path_info_lock(bpi);
224 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
225 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
226 if (!refcount)
227 bpi->net = NULL;
228 bgp_path_info_unlock(bpi);
229 }
230 bgp_path_info_unlock(e->parent);
231 e->parent = NULL;
232 }
233
234 if (e->bgp_orig)
235 bgp_unlock(e->bgp_orig);
236
237 if (e->peer_orig)
238 peer_unlock(e->peer_orig);
239
240 if (e->aggr_suppressors)
241 list_delete(&e->aggr_suppressors);
242
243 if (e->mh_info)
244 bgp_evpn_path_mh_info_free(e->mh_info);
245
246 if ((*extra)->bgp_fs_iprule)
247 list_delete(&((*extra)->bgp_fs_iprule));
248 if ((*extra)->bgp_fs_pbr)
249 list_delete(&((*extra)->bgp_fs_pbr));
250 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
251 }
252
253 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
254 * allocated if required.
255 */
256 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
257 {
258 if (!pi->extra)
259 pi->extra = bgp_path_info_extra_new();
260 return pi->extra;
261 }
262
263 /* Free bgp route information. */
264 void bgp_path_info_free_with_caller(const char *name,
265 struct bgp_path_info *path)
266 {
267 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
268 bgp_attr_unintern(&path->attr);
269
270 bgp_unlink_nexthop(path);
271 bgp_path_info_extra_free(&path->extra);
272 bgp_path_info_mpath_free(&path->mpath);
273 if (path->net)
274 bgp_addpath_free_info_data(&path->tx_addpath,
275 &path->net->tx_addpath);
276
277 peer_unlock(path->peer); /* bgp_path_info peer reference */
278
279 XFREE(MTYPE_BGP_ROUTE, path);
280 }
281
282 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
283 {
284 path->lock++;
285 return path;
286 }
287
288 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
289 {
290 assert(path && path->lock > 0);
291 path->lock--;
292
293 if (path->lock == 0) {
294 bgp_path_info_free(path);
295 return NULL;
296 }
297
298 return path;
299 }
300
301 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
302 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
303 {
304 struct peer *peer;
305 struct bgp_path_info *old_pi, *nextpi;
306 bool set_flag = false;
307 struct bgp *bgp = NULL;
308 struct bgp_table *table = NULL;
309 afi_t afi = 0;
310 safi_t safi = 0;
311
312 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
313 * then the route selection is deferred
314 */
315 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
316 return 0;
317
318 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
319 if (BGP_DEBUG(update, UPDATE_OUT)) {
320 table = bgp_dest_table(dest);
321 if (table)
322 bgp = table->bgp;
323
324 zlog_debug(
325 "Route %pBD(%s) is in workqueue and being processed, not deferred.",
326 dest, bgp ? bgp->name_pretty : "(Unknown)");
327 }
328
329 return 0;
330 }
331
332 table = bgp_dest_table(dest);
333 if (table) {
334 bgp = table->bgp;
335 afi = table->afi;
336 safi = table->safi;
337 }
338
339 for (old_pi = bgp_dest_get_bgp_path_info(dest);
340 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
341 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
342 continue;
343
344 /* Route selection is deferred if there is a stale path which
345 * which indicates peer is in restart mode
346 */
347 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
348 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
349 set_flag = true;
350 } else {
351 /* If the peer is graceful restart capable and peer is
352 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
353 */
354 peer = old_pi->peer;
355 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
356 && BGP_PEER_RESTARTING_MODE(peer)
357 && (old_pi
358 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
359 set_flag = true;
360 }
361 }
362 if (set_flag)
363 break;
364 }
365
366 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
367 * is active
368 */
369 if (set_flag && table) {
370 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
371 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
372 bgp->gr_info[afi][safi].gr_deferred++;
373 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
374 if (BGP_DEBUG(update, UPDATE_OUT))
375 zlog_debug("DEFER route %pBD(%s), dest %p",
376 dest, bgp->name_pretty, dest);
377 return 0;
378 }
379 }
380 return -1;
381 }
382
383 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
384 struct bgp_path_info *pi)
385 {
386 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
387 struct bgp_path_info *top;
388
389 top = bgp_dest_get_bgp_path_info(dest);
390
391 pi->next = top;
392 pi->prev = NULL;
393 if (top)
394 top->prev = pi;
395 bgp_dest_set_bgp_path_info(dest, pi);
396
397 bgp_path_info_lock(pi);
398 bgp_dest_lock_node(dest);
399 peer_lock(pi->peer); /* bgp_path_info peer reference */
400 bgp_dest_set_defer_flag(dest, false);
401 hook_call(bgp_snmp_update_stats, dest, pi, true);
402 }
403
404 /* Do the actual removal of info from RIB, for use by bgp_process
405 completion callback *only* */
406 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
407 {
408 if (pi->next)
409 pi->next->prev = pi->prev;
410 if (pi->prev)
411 pi->prev->next = pi->next;
412 else
413 bgp_dest_set_bgp_path_info(dest, pi->next);
414
415 bgp_path_info_mpath_dequeue(pi);
416 bgp_path_info_unlock(pi);
417 hook_call(bgp_snmp_update_stats, dest, pi, false);
418 bgp_dest_unlock_node(dest);
419 }
420
421 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
422 {
423 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
424 /* set of previous already took care of pcount */
425 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
426 }
427
428 /* undo the effects of a previous call to bgp_path_info_delete; typically
429 called when a route is deleted and then quickly re-added before the
430 deletion has been processed */
431 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
432 {
433 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
434 /* unset of previous already took care of pcount */
435 SET_FLAG(pi->flags, BGP_PATH_VALID);
436 }
437
438 /* Adjust pcount as required */
439 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
440 {
441 struct bgp_table *table;
442
443 assert(dest && bgp_dest_table(dest));
444 assert(pi && pi->peer && pi->peer->bgp);
445
446 table = bgp_dest_table(dest);
447
448 if (pi->peer == pi->peer->bgp->peer_self)
449 return;
450
451 if (!BGP_PATH_COUNTABLE(pi)
452 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
453
454 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
455
456 /* slight hack, but more robust against errors. */
457 if (pi->peer->pcount[table->afi][table->safi])
458 pi->peer->pcount[table->afi][table->safi]--;
459 else
460 flog_err(EC_LIB_DEVELOPMENT,
461 "Asked to decrement 0 prefix count for peer");
462 } else if (BGP_PATH_COUNTABLE(pi)
463 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
464 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
465 pi->peer->pcount[table->afi][table->safi]++;
466 }
467 }
468
469 static int bgp_label_index_differs(struct bgp_path_info *pi1,
470 struct bgp_path_info *pi2)
471 {
472 return (!(pi1->attr->label_index == pi2->attr->label_index));
473 }
474
475 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
476 * This is here primarily to keep prefix-count in check.
477 */
478 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
479 uint32_t flag)
480 {
481 SET_FLAG(pi->flags, flag);
482
483 /* early bath if we know it's not a flag that changes countability state
484 */
485 if (!CHECK_FLAG(flag,
486 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
487 return;
488
489 bgp_pcount_adjust(dest, pi);
490 }
491
492 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
493 uint32_t flag)
494 {
495 UNSET_FLAG(pi->flags, flag);
496
497 /* early bath if we know it's not a flag that changes countability state
498 */
499 if (!CHECK_FLAG(flag,
500 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
501 return;
502
503 bgp_pcount_adjust(dest, pi);
504 }
505
506 /* Get MED value. If MED value is missing and "bgp bestpath
507 missing-as-worst" is specified, treat it as the worst value. */
508 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
509 {
510 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
511 return attr->med;
512 else {
513 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
514 return BGP_MED_MAX;
515 else
516 return 0;
517 }
518 }
519
520 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
521 size_t buf_len)
522 {
523 struct peer *peer;
524
525 if (pi->sub_type == BGP_ROUTE_IMPORTED &&
526 bgp_get_imported_bpi_ultimate(pi))
527 peer = bgp_get_imported_bpi_ultimate(pi)->peer;
528 else
529 peer = pi->peer;
530
531 if (pi->addpath_rx_id)
532 snprintf(buf, buf_len, "path %s (addpath rxid %d)", peer->host,
533 pi->addpath_rx_id);
534 else
535 snprintf(buf, buf_len, "path %s", peer->host);
536 }
537
538
539 /*
540 * Get the ultimate path info.
541 */
542 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
543 {
544 struct bgp_path_info *bpi_ultimate;
545
546 if (info->sub_type != BGP_ROUTE_IMPORTED)
547 return info;
548
549 for (bpi_ultimate = info;
550 bpi_ultimate->extra && bpi_ultimate->extra->parent;
551 bpi_ultimate = bpi_ultimate->extra->parent)
552 ;
553
554 return bpi_ultimate;
555 }
556
557 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
558 */
559 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
560 struct bgp_path_info *exist, int *paths_eq,
561 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
562 char *pfx_buf, afi_t afi, safi_t safi,
563 enum bgp_path_selection_reason *reason)
564 {
565 const struct prefix *new_p;
566 struct attr *newattr, *existattr;
567 enum bgp_peer_sort new_sort;
568 enum bgp_peer_sort exist_sort;
569 uint32_t new_pref;
570 uint32_t exist_pref;
571 uint32_t new_med;
572 uint32_t exist_med;
573 uint32_t new_weight;
574 uint32_t exist_weight;
575 uint32_t newm, existm;
576 struct in_addr new_id;
577 struct in_addr exist_id;
578 int new_cluster;
579 int exist_cluster;
580 int internal_as_route;
581 int confed_as_route;
582 int ret = 0;
583 int igp_metric_ret = 0;
584 int peer_sort_ret = -1;
585 char new_buf[PATH_ADDPATH_STR_BUFFER];
586 char exist_buf[PATH_ADDPATH_STR_BUFFER];
587 uint32_t new_mm_seq;
588 uint32_t exist_mm_seq;
589 int nh_cmp;
590 esi_t *exist_esi;
591 esi_t *new_esi;
592 bool same_esi;
593 bool old_proxy;
594 bool new_proxy;
595 bool new_origin, exist_origin;
596 struct bgp_path_info *bpi_ultimate;
597 struct peer *peer_new, *peer_exist;
598
599 *paths_eq = 0;
600
601 /* 0. Null check. */
602 if (new == NULL) {
603 *reason = bgp_path_selection_none;
604 if (debug)
605 zlog_debug("%s: new is NULL", pfx_buf);
606 return 0;
607 }
608
609 if (debug) {
610 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
611 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
612 sizeof(new_buf));
613 }
614
615 if (exist == NULL) {
616 *reason = bgp_path_selection_first;
617 if (debug)
618 zlog_debug("%s(%s): %s is the initial bestpath",
619 pfx_buf, bgp->name_pretty, new_buf);
620 return 1;
621 }
622
623 if (debug) {
624 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
625 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
626 sizeof(exist_buf));
627 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
628 pfx_buf, bgp->name_pretty, new_buf, new->flags,
629 exist_buf, exist->flags);
630 }
631
632 newattr = new->attr;
633 existattr = exist->attr;
634
635 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
636 * Capability" to a neighbor MUST perform the following upon receiving
637 * a route from that neighbor with the "LLGR_STALE" community, or upon
638 * attaching the "LLGR_STALE" community itself per Section 4.2:
639 *
640 * Treat the route as the least-preferred in route selection (see
641 * below). See the Risks of Depreferencing Routes section (Section 5.2)
642 * for a discussion of potential risks inherent in doing this.
643 */
644 if (bgp_attr_get_community(newattr) &&
645 community_include(bgp_attr_get_community(newattr),
646 COMMUNITY_LLGR_STALE)) {
647 if (debug)
648 zlog_debug(
649 "%s: %s wins over %s due to LLGR_STALE community",
650 pfx_buf, new_buf, exist_buf);
651 return 0;
652 }
653
654 if (bgp_attr_get_community(existattr) &&
655 community_include(bgp_attr_get_community(existattr),
656 COMMUNITY_LLGR_STALE)) {
657 if (debug)
658 zlog_debug(
659 "%s: %s loses to %s due to LLGR_STALE community",
660 pfx_buf, new_buf, exist_buf);
661 return 1;
662 }
663
664 new_p = bgp_dest_get_prefix(new->net);
665
666 /* For EVPN routes, we cannot just go by local vs remote, we have to
667 * look at the MAC mobility sequence number, if present.
668 */
669 if ((safi == SAFI_EVPN)
670 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
671 /* This is an error condition described in RFC 7432 Section
672 * 15.2. The RFC
673 * states that in this scenario "the PE MUST alert the operator"
674 * but it
675 * does not state what other action to take. In order to provide
676 * some
677 * consistency in this scenario we are going to prefer the path
678 * with the
679 * sticky flag.
680 */
681 if (newattr->sticky != existattr->sticky) {
682 if (!debug) {
683 prefix2str(new_p, pfx_buf,
684 sizeof(*pfx_buf)
685 * PREFIX2STR_BUFFER);
686 bgp_path_info_path_with_addpath_rx_str(
687 new, new_buf, sizeof(new_buf));
688 bgp_path_info_path_with_addpath_rx_str(
689 exist, exist_buf, sizeof(exist_buf));
690 }
691
692 if (newattr->sticky && !existattr->sticky) {
693 *reason = bgp_path_selection_evpn_sticky_mac;
694 if (debug)
695 zlog_debug(
696 "%s: %s wins over %s due to sticky MAC flag",
697 pfx_buf, new_buf, exist_buf);
698 return 1;
699 }
700
701 if (!newattr->sticky && existattr->sticky) {
702 *reason = bgp_path_selection_evpn_sticky_mac;
703 if (debug)
704 zlog_debug(
705 "%s: %s loses to %s due to sticky MAC flag",
706 pfx_buf, new_buf, exist_buf);
707 return 0;
708 }
709 }
710
711 new_esi = bgp_evpn_attr_get_esi(newattr);
712 exist_esi = bgp_evpn_attr_get_esi(existattr);
713 if (bgp_evpn_is_esi_valid(new_esi) &&
714 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
715 same_esi = true;
716 } else {
717 same_esi = false;
718 }
719
720 /* If both paths have the same non-zero ES and
721 * one path is local it wins.
722 * PS: Note the local path wins even if the remote
723 * has the higher MM seq. The local path's
724 * MM seq will be fixed up to match the highest
725 * rem seq, subsequently.
726 */
727 if (same_esi) {
728 char esi_buf[ESI_STR_LEN];
729
730 if (bgp_evpn_is_path_local(bgp, new)) {
731 *reason = bgp_path_selection_evpn_local_path;
732 if (debug)
733 zlog_debug(
734 "%s: %s wins over %s as ES %s is same and local",
735 pfx_buf, new_buf, exist_buf,
736 esi_to_str(new_esi, esi_buf,
737 sizeof(esi_buf)));
738 return 1;
739 }
740 if (bgp_evpn_is_path_local(bgp, exist)) {
741 *reason = bgp_path_selection_evpn_local_path;
742 if (debug)
743 zlog_debug(
744 "%s: %s loses to %s as ES %s is same and local",
745 pfx_buf, new_buf, exist_buf,
746 esi_to_str(new_esi, esi_buf,
747 sizeof(esi_buf)));
748 return 0;
749 }
750 }
751
752 new_mm_seq = mac_mobility_seqnum(newattr);
753 exist_mm_seq = mac_mobility_seqnum(existattr);
754
755 if (new_mm_seq > exist_mm_seq) {
756 *reason = bgp_path_selection_evpn_seq;
757 if (debug)
758 zlog_debug(
759 "%s: %s wins over %s due to MM seq %u > %u",
760 pfx_buf, new_buf, exist_buf, new_mm_seq,
761 exist_mm_seq);
762 return 1;
763 }
764
765 if (new_mm_seq < exist_mm_seq) {
766 *reason = bgp_path_selection_evpn_seq;
767 if (debug)
768 zlog_debug(
769 "%s: %s loses to %s due to MM seq %u < %u",
770 pfx_buf, new_buf, exist_buf, new_mm_seq,
771 exist_mm_seq);
772 return 0;
773 }
774
775 /* if the sequence numbers and ESI are the same and one path
776 * is non-proxy it wins (over proxy)
777 */
778 new_proxy = bgp_evpn_attr_is_proxy(newattr);
779 old_proxy = bgp_evpn_attr_is_proxy(existattr);
780 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
781 old_proxy != new_proxy) {
782 if (!new_proxy) {
783 *reason = bgp_path_selection_evpn_non_proxy;
784 if (debug)
785 zlog_debug(
786 "%s: %s wins over %s, same seq/es and non-proxy",
787 pfx_buf, new_buf, exist_buf);
788 return 1;
789 }
790
791 *reason = bgp_path_selection_evpn_non_proxy;
792 if (debug)
793 zlog_debug(
794 "%s: %s loses to %s, same seq/es and non-proxy",
795 pfx_buf, new_buf, exist_buf);
796 return 0;
797 }
798
799 /*
800 * if sequence numbers are the same path with the lowest IP
801 * wins
802 */
803 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
804 if (nh_cmp < 0) {
805 *reason = bgp_path_selection_evpn_lower_ip;
806 if (debug)
807 zlog_debug(
808 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
809 pfx_buf, new_buf, exist_buf, new_mm_seq,
810 &new->attr->nexthop);
811 return 1;
812 }
813 if (nh_cmp > 0) {
814 *reason = bgp_path_selection_evpn_lower_ip;
815 if (debug)
816 zlog_debug(
817 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
818 pfx_buf, new_buf, exist_buf, new_mm_seq,
819 &new->attr->nexthop);
820 return 0;
821 }
822 }
823
824 /* 1. Weight check. */
825 new_weight = newattr->weight;
826 exist_weight = existattr->weight;
827
828 if (new_weight > exist_weight) {
829 *reason = bgp_path_selection_weight;
830 if (debug)
831 zlog_debug("%s: %s wins over %s due to weight %d > %d",
832 pfx_buf, new_buf, exist_buf, new_weight,
833 exist_weight);
834 return 1;
835 }
836
837 if (new_weight < exist_weight) {
838 *reason = bgp_path_selection_weight;
839 if (debug)
840 zlog_debug("%s: %s loses to %s due to weight %d < %d",
841 pfx_buf, new_buf, exist_buf, new_weight,
842 exist_weight);
843 return 0;
844 }
845
846 /* 2. Local preference check. */
847 new_pref = exist_pref = bgp->default_local_pref;
848
849 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
850 new_pref = newattr->local_pref;
851 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
852 exist_pref = existattr->local_pref;
853
854 if (new_pref > exist_pref) {
855 *reason = bgp_path_selection_local_pref;
856 if (debug)
857 zlog_debug(
858 "%s: %s wins over %s due to localpref %d > %d",
859 pfx_buf, new_buf, exist_buf, new_pref,
860 exist_pref);
861 return 1;
862 }
863
864 if (new_pref < exist_pref) {
865 *reason = bgp_path_selection_local_pref;
866 if (debug)
867 zlog_debug(
868 "%s: %s loses to %s due to localpref %d < %d",
869 pfx_buf, new_buf, exist_buf, new_pref,
870 exist_pref);
871 return 0;
872 }
873
874 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
875 * extensions defined in this document, the following step is inserted
876 * after the LOCAL_PREF comparison step in the BGP decision process:
877 * When comparing a pair of routes for a BGP destination, the
878 * route with the ACCEPT_OWN community attached is preferred over
879 * the route that does not have the community.
880 * This extra step MUST only be invoked during the best path selection
881 * process of VPN-IP routes.
882 */
883 if (safi == SAFI_MPLS_VPN &&
884 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
885 CHECK_FLAG(exist->peer->af_flags[afi][safi],
886 PEER_FLAG_ACCEPT_OWN))) {
887 bool new_accept_own = false;
888 bool exist_accept_own = false;
889 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
890
891 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
892 new_accept_own = community_include(
893 bgp_attr_get_community(newattr), accept_own);
894 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
895 exist_accept_own = community_include(
896 bgp_attr_get_community(existattr), accept_own);
897
898 if (new_accept_own && !exist_accept_own) {
899 *reason = bgp_path_selection_accept_own;
900 if (debug)
901 zlog_debug(
902 "%s: %s wins over %s due to accept-own",
903 pfx_buf, new_buf, exist_buf);
904 return 1;
905 }
906
907 if (!new_accept_own && exist_accept_own) {
908 *reason = bgp_path_selection_accept_own;
909 if (debug)
910 zlog_debug(
911 "%s: %s loses to %s due to accept-own",
912 pfx_buf, new_buf, exist_buf);
913 return 0;
914 }
915 }
916
917 /* Tie-breaker - AIGP (Metric TLV) attribute */
918 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
919 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
920 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
921 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
922 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
923
924 if (new_aigp < exist_aigp) {
925 *reason = bgp_path_selection_aigp;
926 if (debug)
927 zlog_debug(
928 "%s: %s wins over %s due to AIGP %" PRIu64
929 " < %" PRIu64,
930 pfx_buf, new_buf, exist_buf, new_aigp,
931 exist_aigp);
932 return 1;
933 }
934
935 if (new_aigp > exist_aigp) {
936 *reason = bgp_path_selection_aigp;
937 if (debug)
938 zlog_debug(
939 "%s: %s loses to %s due to AIGP %" PRIu64
940 " > %" PRIu64,
941 pfx_buf, new_buf, exist_buf, new_aigp,
942 exist_aigp);
943 return 0;
944 }
945 }
946
947 /* 3. Local route check. We prefer:
948 * - BGP_ROUTE_STATIC
949 * - BGP_ROUTE_AGGREGATE
950 * - BGP_ROUTE_REDISTRIBUTE
951 */
952 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
953 new->sub_type == BGP_ROUTE_IMPORTED);
954 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
955 exist->sub_type == BGP_ROUTE_IMPORTED);
956
957 if (new_origin && !exist_origin) {
958 *reason = bgp_path_selection_local_route;
959 if (debug)
960 zlog_debug(
961 "%s: %s wins over %s due to preferred BGP_ROUTE type",
962 pfx_buf, new_buf, exist_buf);
963 return 1;
964 }
965
966 if (!new_origin && exist_origin) {
967 *reason = bgp_path_selection_local_route;
968 if (debug)
969 zlog_debug(
970 "%s: %s loses to %s due to preferred BGP_ROUTE type",
971 pfx_buf, new_buf, exist_buf);
972 return 0;
973 }
974
975 /* Here if these are imported routes then get ultimate pi for
976 * path compare.
977 */
978 new = bgp_get_imported_bpi_ultimate(new);
979 exist = bgp_get_imported_bpi_ultimate(exist);
980 newattr = new->attr;
981 existattr = exist->attr;
982
983 /* 4. AS path length check. */
984 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
985 int exist_hops = aspath_count_hops(existattr->aspath);
986 int exist_confeds = aspath_count_confeds(existattr->aspath);
987
988 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
989 int aspath_hops;
990
991 aspath_hops = aspath_count_hops(newattr->aspath);
992 aspath_hops += aspath_count_confeds(newattr->aspath);
993
994 if (aspath_hops < (exist_hops + exist_confeds)) {
995 *reason = bgp_path_selection_confed_as_path;
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
999 pfx_buf, new_buf, exist_buf,
1000 aspath_hops,
1001 (exist_hops + exist_confeds));
1002 return 1;
1003 }
1004
1005 if (aspath_hops > (exist_hops + exist_confeds)) {
1006 *reason = bgp_path_selection_confed_as_path;
1007 if (debug)
1008 zlog_debug(
1009 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1010 pfx_buf, new_buf, exist_buf,
1011 aspath_hops,
1012 (exist_hops + exist_confeds));
1013 return 0;
1014 }
1015 } else {
1016 int newhops = aspath_count_hops(newattr->aspath);
1017
1018 if (newhops < exist_hops) {
1019 *reason = bgp_path_selection_as_path;
1020 if (debug)
1021 zlog_debug(
1022 "%s: %s wins over %s due to aspath hopcount %d < %d",
1023 pfx_buf, new_buf, exist_buf,
1024 newhops, exist_hops);
1025 return 1;
1026 }
1027
1028 if (newhops > exist_hops) {
1029 *reason = bgp_path_selection_as_path;
1030 if (debug)
1031 zlog_debug(
1032 "%s: %s loses to %s due to aspath hopcount %d > %d",
1033 pfx_buf, new_buf, exist_buf,
1034 newhops, exist_hops);
1035 return 0;
1036 }
1037 }
1038 }
1039
1040 /* 5. Origin check. */
1041 if (newattr->origin < existattr->origin) {
1042 *reason = bgp_path_selection_origin;
1043 if (debug)
1044 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1045 pfx_buf, new_buf, exist_buf,
1046 bgp_origin_long_str[newattr->origin],
1047 bgp_origin_long_str[existattr->origin]);
1048 return 1;
1049 }
1050
1051 if (newattr->origin > existattr->origin) {
1052 *reason = bgp_path_selection_origin;
1053 if (debug)
1054 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1055 pfx_buf, new_buf, exist_buf,
1056 bgp_origin_long_str[newattr->origin],
1057 bgp_origin_long_str[existattr->origin]);
1058 return 0;
1059 }
1060
1061 /* 6. MED check. */
1062 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1063 && aspath_count_hops(existattr->aspath) == 0);
1064 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1065 && aspath_count_confeds(existattr->aspath) > 0
1066 && aspath_count_hops(newattr->aspath) == 0
1067 && aspath_count_hops(existattr->aspath) == 0);
1068
1069 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1070 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1071 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1072 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1073 || internal_as_route) {
1074 new_med = bgp_med_value(new->attr, bgp);
1075 exist_med = bgp_med_value(exist->attr, bgp);
1076
1077 if (new_med < exist_med) {
1078 *reason = bgp_path_selection_med;
1079 if (debug)
1080 zlog_debug(
1081 "%s: %s wins over %s due to MED %d < %d",
1082 pfx_buf, new_buf, exist_buf, new_med,
1083 exist_med);
1084 return 1;
1085 }
1086
1087 if (new_med > exist_med) {
1088 *reason = bgp_path_selection_med;
1089 if (debug)
1090 zlog_debug(
1091 "%s: %s loses to %s due to MED %d > %d",
1092 pfx_buf, new_buf, exist_buf, new_med,
1093 exist_med);
1094 return 0;
1095 }
1096 }
1097
1098 if (exist->sub_type == BGP_ROUTE_IMPORTED) {
1099 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
1100 peer_exist = bpi_ultimate->peer;
1101 } else
1102 peer_exist = exist->peer;
1103
1104 if (new->sub_type == BGP_ROUTE_IMPORTED) {
1105 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
1106 peer_new = bpi_ultimate->peer;
1107 } else
1108 peer_new = new->peer;
1109
1110 /* 7. Peer type check. */
1111 new_sort = peer_new->sort;
1112 exist_sort = peer_exist->sort;
1113
1114 if (new_sort == BGP_PEER_EBGP
1115 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1116 *reason = bgp_path_selection_peer;
1117 if (debug)
1118 zlog_debug(
1119 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1120 pfx_buf, new_buf, exist_buf);
1121 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_EBGP
1127 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1128 *reason = bgp_path_selection_peer;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1134 return 0;
1135 peer_sort_ret = 0;
1136 }
1137
1138 /* 8. IGP metric check. */
1139 newm = existm = 0;
1140
1141 if (new->extra)
1142 newm = new->extra->igpmetric;
1143 if (exist->extra)
1144 existm = exist->extra->igpmetric;
1145
1146 if (newm < existm) {
1147 if (debug && peer_sort_ret < 0)
1148 zlog_debug(
1149 "%s: %s wins over %s due to IGP metric %u < %u",
1150 pfx_buf, new_buf, exist_buf, newm, existm);
1151 igp_metric_ret = 1;
1152 }
1153
1154 if (newm > existm) {
1155 if (debug && peer_sort_ret < 0)
1156 zlog_debug(
1157 "%s: %s loses to %s due to IGP metric %u > %u",
1158 pfx_buf, new_buf, exist_buf, newm, existm);
1159 igp_metric_ret = 0;
1160 }
1161
1162 /* 9. Same IGP metric. Compare the cluster list length as
1163 representative of IGP hops metric. Rewrite the metric value
1164 pair (newm, existm) with the cluster list length. Prefer the
1165 path with smaller cluster list length. */
1166 if (newm == existm) {
1167 if (peer_sort_lookup(peer_new) == BGP_PEER_IBGP &&
1168 peer_sort_lookup(peer_exist) == BGP_PEER_IBGP &&
1169 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1170 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1171 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1172
1173 if (newm < existm) {
1174 if (debug && peer_sort_ret < 0)
1175 zlog_debug(
1176 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1177 pfx_buf, new_buf, exist_buf,
1178 newm, existm);
1179 igp_metric_ret = 1;
1180 }
1181
1182 if (newm > existm) {
1183 if (debug && peer_sort_ret < 0)
1184 zlog_debug(
1185 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1186 pfx_buf, new_buf, exist_buf,
1187 newm, existm);
1188 igp_metric_ret = 0;
1189 }
1190 }
1191 }
1192
1193 /* 10. confed-external vs. confed-internal */
1194 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1195 if (new_sort == BGP_PEER_CONFED
1196 && exist_sort == BGP_PEER_IBGP) {
1197 *reason = bgp_path_selection_confed;
1198 if (debug)
1199 zlog_debug(
1200 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1201 pfx_buf, new_buf, exist_buf);
1202 if (!CHECK_FLAG(bgp->flags,
1203 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1204 return 1;
1205 peer_sort_ret = 1;
1206 }
1207
1208 if (exist_sort == BGP_PEER_CONFED
1209 && new_sort == BGP_PEER_IBGP) {
1210 *reason = bgp_path_selection_confed;
1211 if (debug)
1212 zlog_debug(
1213 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1214 pfx_buf, new_buf, exist_buf);
1215 if (!CHECK_FLAG(bgp->flags,
1216 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1217 return 0;
1218 peer_sort_ret = 0;
1219 }
1220 }
1221
1222 /* 11. Maximum path check. */
1223 if (newm == existm) {
1224 /* If one path has a label but the other does not, do not treat
1225 * them as equals for multipath
1226 */
1227 int newl, existl;
1228
1229 newl = existl = 0;
1230
1231 if (new->extra)
1232 newl = new->extra->num_labels;
1233 if (exist->extra)
1234 existl = exist->extra->num_labels;
1235 if (((new->extra &&bgp_is_valid_label(&new->extra->label[0])) !=
1236 (exist->extra &&
1237 bgp_is_valid_label(&exist->extra->label[0]))) ||
1238 (newl != existl)) {
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1242 pfx_buf, new_buf, exist_buf);
1243 } else if (CHECK_FLAG(bgp->flags,
1244 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1245
1246 /*
1247 * For the two paths, all comparison steps till IGP
1248 * metric
1249 * have succeeded - including AS_PATH hop count. Since
1250 * 'bgp
1251 * bestpath as-path multipath-relax' knob is on, we
1252 * don't need
1253 * an exact match of AS_PATH. Thus, mark the paths are
1254 * equal.
1255 * That will trigger both these paths to get into the
1256 * multipath
1257 * array.
1258 */
1259 *paths_eq = 1;
1260
1261 if (debug)
1262 zlog_debug(
1263 "%s: %s and %s are equal via multipath-relax",
1264 pfx_buf, new_buf, exist_buf);
1265 } else if (peer_new->sort == BGP_PEER_IBGP) {
1266 if (aspath_cmp(new->attr->aspath,
1267 exist->attr->aspath)) {
1268 *paths_eq = 1;
1269
1270 if (debug)
1271 zlog_debug(
1272 "%s: %s and %s are equal via matching aspaths",
1273 pfx_buf, new_buf, exist_buf);
1274 }
1275 } else if (peer_new->as == peer_exist->as) {
1276 *paths_eq = 1;
1277
1278 if (debug)
1279 zlog_debug(
1280 "%s: %s and %s are equal via same remote-as",
1281 pfx_buf, new_buf, exist_buf);
1282 }
1283 } else {
1284 /*
1285 * TODO: If unequal cost ibgp multipath is enabled we can
1286 * mark the paths as equal here instead of returning
1287 */
1288
1289 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1290 * if either step 7 or 10 (peer type checks) yielded a winner,
1291 * that result was returned immediately. Returning from step 10
1292 * ignored the return value computed in steps 8 and 9 (IGP
1293 * metric checks). In order to preserve that behavior, if
1294 * peer_sort_ret is set, return that rather than igp_metric_ret.
1295 */
1296 ret = peer_sort_ret;
1297 if (peer_sort_ret < 0) {
1298 ret = igp_metric_ret;
1299 if (debug) {
1300 if (ret == 1)
1301 zlog_debug(
1302 "%s: %s wins over %s after IGP metric comparison",
1303 pfx_buf, new_buf, exist_buf);
1304 else
1305 zlog_debug(
1306 "%s: %s loses to %s after IGP metric comparison",
1307 pfx_buf, new_buf, exist_buf);
1308 }
1309 *reason = bgp_path_selection_igp_metric;
1310 }
1311 return ret;
1312 }
1313
1314 /*
1315 * At this point, the decision whether to set *paths_eq = 1 has been
1316 * completed. If we deferred returning because of bestpath peer-type
1317 * relax configuration, return now.
1318 */
1319 if (peer_sort_ret >= 0)
1320 return peer_sort_ret;
1321
1322 /* 12. If both paths are external, prefer the path that was received
1323 first (the oldest one). This step minimizes route-flap, since a
1324 newer path won't displace an older one, even if it was the
1325 preferred route based on the additional decision criteria below. */
1326 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1327 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1328 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1329 *reason = bgp_path_selection_older;
1330 if (debug)
1331 zlog_debug(
1332 "%s: %s wins over %s due to oldest external",
1333 pfx_buf, new_buf, exist_buf);
1334 return 1;
1335 }
1336
1337 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1338 *reason = bgp_path_selection_older;
1339 if (debug)
1340 zlog_debug(
1341 "%s: %s loses to %s due to oldest external",
1342 pfx_buf, new_buf, exist_buf);
1343 return 0;
1344 }
1345 }
1346
1347 /* 13. Router-ID comparison. */
1348 /* If one of the paths is "stale", the corresponding peer router-id will
1349 * be 0 and would always win over the other path. If originator id is
1350 * used for the comparison, it will decide which path is better.
1351 */
1352 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1353 new_id.s_addr = newattr->originator_id.s_addr;
1354 else
1355 new_id.s_addr = peer_new->remote_id.s_addr;
1356 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1357 exist_id.s_addr = existattr->originator_id.s_addr;
1358 else
1359 exist_id.s_addr = peer_exist->remote_id.s_addr;
1360
1361 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1362 *reason = bgp_path_selection_router_id;
1363 if (debug)
1364 zlog_debug(
1365 "%s: %s wins over %s due to Router-ID comparison",
1366 pfx_buf, new_buf, exist_buf);
1367 return 1;
1368 }
1369
1370 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1371 *reason = bgp_path_selection_router_id;
1372 if (debug)
1373 zlog_debug(
1374 "%s: %s loses to %s due to Router-ID comparison",
1375 pfx_buf, new_buf, exist_buf);
1376 return 0;
1377 }
1378
1379 /* 14. Cluster length comparison. */
1380 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1381 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1382
1383 if (new_cluster < exist_cluster) {
1384 *reason = bgp_path_selection_cluster_length;
1385 if (debug)
1386 zlog_debug(
1387 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1388 pfx_buf, new_buf, exist_buf, new_cluster,
1389 exist_cluster);
1390 return 1;
1391 }
1392
1393 if (new_cluster > exist_cluster) {
1394 *reason = bgp_path_selection_cluster_length;
1395 if (debug)
1396 zlog_debug(
1397 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1398 pfx_buf, new_buf, exist_buf, new_cluster,
1399 exist_cluster);
1400 return 0;
1401 }
1402
1403 /* 15. Neighbor address comparison. */
1404 /* Do this only if neither path is "stale" as stale paths do not have
1405 * valid peer information (as the connection may or may not be up).
1406 */
1407 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1408 *reason = bgp_path_selection_stale;
1409 if (debug)
1410 zlog_debug(
1411 "%s: %s wins over %s due to latter path being STALE",
1412 pfx_buf, new_buf, exist_buf);
1413 return 1;
1414 }
1415
1416 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1417 *reason = bgp_path_selection_stale;
1418 if (debug)
1419 zlog_debug(
1420 "%s: %s loses to %s due to former path being STALE",
1421 pfx_buf, new_buf, exist_buf);
1422 return 0;
1423 }
1424
1425 /* locally configured routes to advertise do not have su_remote */
1426 if (peer_new->su_remote == NULL) {
1427 *reason = bgp_path_selection_local_configured;
1428 return 0;
1429 }
1430
1431 if (peer_exist->su_remote == NULL) {
1432 *reason = bgp_path_selection_local_configured;
1433 return 1;
1434 }
1435
1436 ret = sockunion_cmp(peer_new->su_remote, peer_exist->su_remote);
1437
1438 if (ret == 1) {
1439 *reason = bgp_path_selection_neighbor_ip;
1440 if (debug)
1441 zlog_debug(
1442 "%s: %s loses to %s due to Neighor IP comparison",
1443 pfx_buf, new_buf, exist_buf);
1444 return 0;
1445 }
1446
1447 if (ret == -1) {
1448 *reason = bgp_path_selection_neighbor_ip;
1449 if (debug)
1450 zlog_debug(
1451 "%s: %s wins over %s due to Neighor IP comparison",
1452 pfx_buf, new_buf, exist_buf);
1453 return 1;
1454 }
1455
1456 *reason = bgp_path_selection_default;
1457 if (debug)
1458 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1459 pfx_buf, new_buf, exist_buf);
1460
1461 return 1;
1462 }
1463
1464
1465 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1466 struct bgp_path_info *exist, int *paths_eq)
1467 {
1468 enum bgp_path_selection_reason reason;
1469 char pfx_buf[PREFIX2STR_BUFFER];
1470
1471 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1472 AFI_L2VPN, SAFI_EVPN, &reason);
1473 }
1474
1475 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1476 * is preferred, or 0 if they are the same (usually will only occur if
1477 * multipath is enabled
1478 * This version is compatible with */
1479 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1480 struct bgp_path_info *exist, char *pfx_buf,
1481 afi_t afi, safi_t safi,
1482 enum bgp_path_selection_reason *reason)
1483 {
1484 int paths_eq;
1485 int ret;
1486 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1487 afi, safi, reason);
1488
1489 if (paths_eq)
1490 ret = 0;
1491 else {
1492 if (ret == 1)
1493 ret = -1;
1494 else
1495 ret = 1;
1496 }
1497 return ret;
1498 }
1499
1500 static enum filter_type bgp_input_filter(struct peer *peer,
1501 const struct prefix *p,
1502 struct attr *attr, afi_t afi,
1503 safi_t safi)
1504 {
1505 struct bgp_filter *filter;
1506 enum filter_type ret = FILTER_PERMIT;
1507
1508 filter = &peer->filter[afi][safi];
1509
1510 #define FILTER_EXIST_WARN(F, f, filter) \
1511 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1512 zlog_debug("%s: Could not find configured input %s-list %s!", \
1513 peer->host, #f, F##_IN_NAME(filter));
1514
1515 if (DISTRIBUTE_IN_NAME(filter)) {
1516 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1517
1518 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1519 == FILTER_DENY) {
1520 ret = FILTER_DENY;
1521 goto done;
1522 }
1523 }
1524
1525 if (PREFIX_LIST_IN_NAME(filter)) {
1526 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1527
1528 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1529 == PREFIX_DENY) {
1530 ret = FILTER_DENY;
1531 goto done;
1532 }
1533 }
1534
1535 if (FILTER_LIST_IN_NAME(filter)) {
1536 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1537
1538 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1539 == AS_FILTER_DENY) {
1540 ret = FILTER_DENY;
1541 goto done;
1542 }
1543 }
1544
1545 done:
1546 if (frrtrace_enabled(frr_bgp, input_filter)) {
1547 char pfxprint[PREFIX2STR_BUFFER];
1548
1549 prefix2str(p, pfxprint, sizeof(pfxprint));
1550 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1551 ret == FILTER_PERMIT ? "permit" : "deny");
1552 }
1553
1554 return ret;
1555 #undef FILTER_EXIST_WARN
1556 }
1557
1558 static enum filter_type bgp_output_filter(struct peer *peer,
1559 const struct prefix *p,
1560 struct attr *attr, afi_t afi,
1561 safi_t safi)
1562 {
1563 struct bgp_filter *filter;
1564 enum filter_type ret = FILTER_PERMIT;
1565
1566 filter = &peer->filter[afi][safi];
1567
1568 #define FILTER_EXIST_WARN(F, f, filter) \
1569 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1570 zlog_debug("%s: Could not find configured output %s-list %s!", \
1571 peer->host, #f, F##_OUT_NAME(filter));
1572
1573 if (DISTRIBUTE_OUT_NAME(filter)) {
1574 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1575
1576 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1577 == FILTER_DENY) {
1578 ret = FILTER_DENY;
1579 goto done;
1580 }
1581 }
1582
1583 if (PREFIX_LIST_OUT_NAME(filter)) {
1584 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1585
1586 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1587 == PREFIX_DENY) {
1588 ret = FILTER_DENY;
1589 goto done;
1590 }
1591 }
1592
1593 if (FILTER_LIST_OUT_NAME(filter)) {
1594 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1595
1596 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1597 == AS_FILTER_DENY) {
1598 ret = FILTER_DENY;
1599 goto done;
1600 }
1601 }
1602
1603 if (frrtrace_enabled(frr_bgp, output_filter)) {
1604 char pfxprint[PREFIX2STR_BUFFER];
1605
1606 prefix2str(p, pfxprint, sizeof(pfxprint));
1607 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1608 ret == FILTER_PERMIT ? "permit" : "deny");
1609 }
1610
1611 done:
1612 return ret;
1613 #undef FILTER_EXIST_WARN
1614 }
1615
1616 /* If community attribute includes no_export then return 1. */
1617 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1618 {
1619 if (bgp_attr_get_community(attr)) {
1620 /* NO_ADVERTISE check. */
1621 if (community_include(bgp_attr_get_community(attr),
1622 COMMUNITY_NO_ADVERTISE))
1623 return true;
1624
1625 /* NO_EXPORT check. */
1626 if (peer->sort == BGP_PEER_EBGP &&
1627 community_include(bgp_attr_get_community(attr),
1628 COMMUNITY_NO_EXPORT))
1629 return true;
1630
1631 /* NO_EXPORT_SUBCONFED check. */
1632 if (peer->sort == BGP_PEER_EBGP
1633 || peer->sort == BGP_PEER_CONFED)
1634 if (community_include(bgp_attr_get_community(attr),
1635 COMMUNITY_NO_EXPORT_SUBCONFED))
1636 return true;
1637 }
1638 return false;
1639 }
1640
1641 /* Route reflection loop check. */
1642 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1643 {
1644 struct in_addr cluster_id;
1645 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1646
1647 if (cluster) {
1648 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1649 cluster_id = peer->bgp->cluster_id;
1650 else
1651 cluster_id = peer->bgp->router_id;
1652
1653 if (cluster_loop_check(cluster, cluster_id))
1654 return true;
1655 }
1656 return false;
1657 }
1658
1659 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1660 {
1661 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1662 if (peer->local_role == ROLE_PROVIDER ||
1663 peer->local_role == ROLE_RS_SERVER)
1664 return true;
1665 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1666 return true;
1667 return false;
1668 }
1669 if (peer->local_role == ROLE_CUSTOMER ||
1670 peer->local_role == ROLE_PEER ||
1671 peer->local_role == ROLE_RS_CLIENT) {
1672 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1673 attr->otc = peer->as;
1674 }
1675 return false;
1676 }
1677
1678 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1679 {
1680 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1681 if (peer->local_role == ROLE_CUSTOMER ||
1682 peer->local_role == ROLE_RS_CLIENT ||
1683 peer->local_role == ROLE_PEER)
1684 return true;
1685 return false;
1686 }
1687 if (peer->local_role == ROLE_PROVIDER ||
1688 peer->local_role == ROLE_PEER ||
1689 peer->local_role == ROLE_RS_SERVER) {
1690 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1691 attr->otc = peer->bgp->as;
1692 }
1693 return false;
1694 }
1695
1696 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1697 {
1698 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1699 }
1700
1701 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1702 struct attr *attr, afi_t afi, safi_t safi,
1703 const char *rmap_name, mpls_label_t *label,
1704 uint32_t num_labels, struct bgp_dest *dest)
1705 {
1706 struct bgp_filter *filter;
1707 struct bgp_path_info rmap_path = { 0 };
1708 struct bgp_path_info_extra extra = { 0 };
1709 route_map_result_t ret;
1710 struct route_map *rmap = NULL;
1711
1712 filter = &peer->filter[afi][safi];
1713
1714 /* Apply default weight value. */
1715 if (peer->weight[afi][safi])
1716 attr->weight = peer->weight[afi][safi];
1717
1718 if (rmap_name) {
1719 rmap = route_map_lookup_by_name(rmap_name);
1720
1721 if (rmap == NULL)
1722 return RMAP_DENY;
1723 } else {
1724 if (ROUTE_MAP_IN_NAME(filter)) {
1725 rmap = ROUTE_MAP_IN(filter);
1726
1727 if (rmap == NULL)
1728 return RMAP_DENY;
1729 }
1730 }
1731
1732 /* Route map apply. */
1733 if (rmap) {
1734 memset(&rmap_path, 0, sizeof(rmap_path));
1735 /* Duplicate current value to new structure for modification. */
1736 rmap_path.peer = peer;
1737 rmap_path.attr = attr;
1738 rmap_path.extra = &extra;
1739 rmap_path.net = dest;
1740
1741 extra.num_labels = num_labels;
1742 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1743 memcpy(extra.label, label,
1744 num_labels * sizeof(mpls_label_t));
1745
1746 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1747
1748 /* Apply BGP route map to the attribute. */
1749 ret = route_map_apply(rmap, p, &rmap_path);
1750
1751 peer->rmap_type = 0;
1752
1753 if (ret == RMAP_DENYMATCH)
1754 return RMAP_DENY;
1755 }
1756 return RMAP_PERMIT;
1757 }
1758
1759 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1760 struct attr *attr, afi_t afi, safi_t safi,
1761 const char *rmap_name)
1762 {
1763 struct bgp_path_info rmap_path;
1764 route_map_result_t ret;
1765 struct route_map *rmap = NULL;
1766 uint8_t rmap_type;
1767
1768 /*
1769 * So if we get to this point and have no rmap_name
1770 * we want to just show the output as it currently
1771 * exists.
1772 */
1773 if (!rmap_name)
1774 return RMAP_PERMIT;
1775
1776 /* Apply default weight value. */
1777 if (peer->weight[afi][safi])
1778 attr->weight = peer->weight[afi][safi];
1779
1780 rmap = route_map_lookup_by_name(rmap_name);
1781
1782 /*
1783 * If we have a route map name and we do not find
1784 * the routemap that means we have an implicit
1785 * deny.
1786 */
1787 if (rmap == NULL)
1788 return RMAP_DENY;
1789
1790 memset(&rmap_path, 0, sizeof(rmap_path));
1791 /* Route map apply. */
1792 /* Duplicate current value to new structure for modification. */
1793 rmap_path.peer = peer;
1794 rmap_path.attr = attr;
1795
1796 rmap_type = peer->rmap_type;
1797 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1798
1799 /* Apply BGP route map to the attribute. */
1800 ret = route_map_apply(rmap, p, &rmap_path);
1801
1802 peer->rmap_type = rmap_type;
1803
1804 if (ret == RMAP_DENYMATCH)
1805 /*
1806 * caller has multiple error paths with bgp_attr_flush()
1807 */
1808 return RMAP_DENY;
1809
1810 return RMAP_PERMIT;
1811 }
1812
1813 /* If this is an EBGP peer with remove-private-AS */
1814 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1815 struct peer *peer, struct attr *attr)
1816 {
1817 if (peer->sort == BGP_PEER_EBGP
1818 && (peer_af_flag_check(peer, afi, safi,
1819 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1820 || peer_af_flag_check(peer, afi, safi,
1821 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1822 || peer_af_flag_check(peer, afi, safi,
1823 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1824 || peer_af_flag_check(peer, afi, safi,
1825 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1826 // Take action on the entire aspath
1827 if (peer_af_flag_check(peer, afi, safi,
1828 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1829 || peer_af_flag_check(peer, afi, safi,
1830 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1831 if (peer_af_flag_check(
1832 peer, afi, safi,
1833 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1834 attr->aspath = aspath_replace_private_asns(
1835 attr->aspath, bgp->as, peer->as);
1836
1837 /*
1838 * Even if the aspath consists of just private ASNs we
1839 * need to walk the AS-Path to maintain all instances
1840 * of the peer's ASN to break possible loops.
1841 */
1842 else
1843 attr->aspath = aspath_remove_private_asns(
1844 attr->aspath, peer->as);
1845 }
1846
1847 // 'all' was not specified so the entire aspath must be private
1848 // ASNs
1849 // for us to do anything
1850 else if (aspath_private_as_check(attr->aspath)) {
1851 if (peer_af_flag_check(
1852 peer, afi, safi,
1853 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1854 attr->aspath = aspath_replace_private_asns(
1855 attr->aspath, bgp->as, peer->as);
1856 else
1857 /*
1858 * Walk the aspath to retain any instances of
1859 * the peer_asn
1860 */
1861 attr->aspath = aspath_remove_private_asns(
1862 attr->aspath, peer->as);
1863 }
1864 }
1865 }
1866
1867 /* If this is an EBGP peer with as-override */
1868 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1869 struct peer *peer, struct attr *attr)
1870 {
1871 struct aspath *aspath;
1872
1873 if (peer->sort == BGP_PEER_EBGP &&
1874 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1875 if (attr->aspath->refcnt)
1876 aspath = aspath_dup(attr->aspath);
1877 else
1878 aspath = attr->aspath;
1879
1880 attr->aspath = aspath_intern(
1881 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1882
1883 aspath_free(aspath);
1884 }
1885 }
1886
1887 void bgp_attr_add_llgr_community(struct attr *attr)
1888 {
1889 struct community *old;
1890 struct community *new;
1891 struct community *merge;
1892 struct community *llgr;
1893
1894 old = bgp_attr_get_community(attr);
1895 llgr = community_str2com("llgr-stale");
1896
1897 assert(llgr);
1898
1899 if (old) {
1900 merge = community_merge(community_dup(old), llgr);
1901
1902 if (old->refcnt == 0)
1903 community_free(&old);
1904
1905 new = community_uniq_sort(merge);
1906 community_free(&merge);
1907 } else {
1908 new = community_dup(llgr);
1909 }
1910
1911 community_free(&llgr);
1912
1913 bgp_attr_set_community(attr, new);
1914 }
1915
1916 void bgp_attr_add_gshut_community(struct attr *attr)
1917 {
1918 struct community *old;
1919 struct community *new;
1920 struct community *merge;
1921 struct community *gshut;
1922
1923 old = bgp_attr_get_community(attr);
1924 gshut = community_str2com("graceful-shutdown");
1925
1926 assert(gshut);
1927
1928 if (old) {
1929 merge = community_merge(community_dup(old), gshut);
1930
1931 if (old->refcnt == 0)
1932 community_free(&old);
1933
1934 new = community_uniq_sort(merge);
1935 community_free(&merge);
1936 } else {
1937 new = community_dup(gshut);
1938 }
1939
1940 community_free(&gshut);
1941 bgp_attr_set_community(attr, new);
1942
1943 /* When we add the graceful-shutdown community we must also
1944 * lower the local-preference */
1945 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1946 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1947 }
1948
1949
1950 /* Notify BGP Conditional advertisement scanner process. */
1951 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1952 {
1953 struct peer *peer = SUBGRP_PEER(subgrp);
1954 afi_t afi = SUBGRP_AFI(subgrp);
1955 safi_t safi = SUBGRP_SAFI(subgrp);
1956 struct bgp_filter *filter = &peer->filter[afi][safi];
1957
1958 if (!ADVERTISE_MAP_NAME(filter))
1959 return;
1960
1961 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1962 return;
1963
1964 peer->advmap_table_change = true;
1965 }
1966
1967
1968 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1969 {
1970 if (family == AF_INET) {
1971 attr->nexthop.s_addr = INADDR_ANY;
1972 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1973 }
1974 if (family == AF_INET6)
1975 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1976 if (family == AF_EVPN)
1977 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1978 }
1979
1980 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1981 struct update_subgroup *subgrp,
1982 const struct prefix *p, struct attr *attr,
1983 struct attr *post_attr)
1984 {
1985 struct bgp_filter *filter;
1986 struct peer *from;
1987 struct peer *peer;
1988 struct peer *onlypeer;
1989 struct bgp *bgp;
1990 struct attr *piattr;
1991 route_map_result_t ret;
1992 int transparent;
1993 int reflect;
1994 afi_t afi;
1995 safi_t safi;
1996 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1997 bool nh_reset = false;
1998 uint64_t cum_bw;
1999
2000 if (DISABLE_BGP_ANNOUNCE)
2001 return false;
2002
2003 afi = SUBGRP_AFI(subgrp);
2004 safi = SUBGRP_SAFI(subgrp);
2005 peer = SUBGRP_PEER(subgrp);
2006 onlypeer = NULL;
2007 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2008 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2009
2010 from = pi->peer;
2011 filter = &peer->filter[afi][safi];
2012 bgp = SUBGRP_INST(subgrp);
2013 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2014 : pi->attr;
2015
2016 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2017 peer->pmax_out[afi][safi] != 0 &&
2018 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2019 if (BGP_DEBUG(update, UPDATE_OUT) ||
2020 BGP_DEBUG(update, UPDATE_PREFIX)) {
2021 zlog_debug("%s reached maximum prefix to be send (%u)",
2022 peer->host, peer->pmax_out[afi][safi]);
2023 }
2024 return false;
2025 }
2026
2027 #ifdef ENABLE_BGP_VNC
2028 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2029 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2030 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2031
2032 /*
2033 * direct and direct_ext type routes originate internally even
2034 * though they can have peer pointers that reference other
2035 * systems
2036 */
2037 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2038 __func__, p);
2039 samepeer_safe = 1;
2040 }
2041 #endif
2042
2043 if (((afi == AFI_IP) || (afi == AFI_IP6))
2044 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2045 && (pi->type == ZEBRA_ROUTE_BGP)
2046 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2047
2048 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2049
2050 samepeer_safe = 1;
2051 }
2052
2053 /* With addpath we may be asked to TX all kinds of paths so make sure
2054 * pi is valid */
2055 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2056 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2057 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2058 return false;
2059 }
2060
2061 /* If this is not the bestpath then check to see if there is an enabled
2062 * addpath
2063 * feature that requires us to advertise it */
2064 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2065 if (!bgp_addpath_capable(pi, peer, afi, safi))
2066 return false;
2067
2068 /* Aggregate-address suppress check. */
2069 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2070 return false;
2071
2072 /*
2073 * If we are doing VRF 2 VRF leaking via the import
2074 * statement, we want to prevent the route going
2075 * off box as that the RT and RD created are localy
2076 * significant and globaly useless.
2077 */
2078 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2079 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2080 return false;
2081
2082 /* If it's labeled safi, make sure the route has a valid label. */
2083 if (safi == SAFI_LABELED_UNICAST) {
2084 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2085 if (!bgp_is_valid_label(&label)) {
2086 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2087 zlog_debug("u%" PRIu64 ":s%" PRIu64
2088 " %pFX is filtered - no label (%p)",
2089 subgrp->update_group->id, subgrp->id,
2090 p, &label);
2091 return false;
2092 }
2093 }
2094
2095 /* Do not send back route to sender. */
2096 if (onlypeer && from == onlypeer) {
2097 return false;
2098 }
2099
2100 /* Do not send the default route in the BGP table if the neighbor is
2101 * configured for default-originate */
2102 if (CHECK_FLAG(peer->af_flags[afi][safi],
2103 PEER_FLAG_DEFAULT_ORIGINATE)) {
2104 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2105 return false;
2106 else if (p->family == AF_INET6 && p->prefixlen == 0)
2107 return false;
2108 }
2109
2110 /* Transparency check. */
2111 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2112 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2113 transparent = 1;
2114 else
2115 transparent = 0;
2116
2117 /* If community is not disabled check the no-export and local. */
2118 if (!transparent && bgp_community_filter(peer, piattr)) {
2119 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2120 zlog_debug("%s: community filter check fail for %pFX",
2121 __func__, p);
2122 return false;
2123 }
2124
2125 /* If the attribute has originator-id and it is same as remote
2126 peer's id. */
2127 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2128 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2129 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2130 zlog_debug(
2131 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2132 onlypeer, p);
2133 return false;
2134 }
2135
2136 /* ORF prefix-list filter check */
2137 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2138 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2139 || CHECK_FLAG(peer->af_cap[afi][safi],
2140 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2141 if (peer->orf_plist[afi][safi]) {
2142 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2143 == PREFIX_DENY) {
2144 if (bgp_debug_update(NULL, p,
2145 subgrp->update_group, 0))
2146 zlog_debug(
2147 "%pBP [Update:SEND] %pFX is filtered via ORF",
2148 peer, p);
2149 return false;
2150 }
2151 }
2152
2153 /* Output filter check. */
2154 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2155 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2156 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2157 p);
2158 return false;
2159 }
2160
2161 /* AS path loop check. */
2162 if (peer->as_path_loop_detection &&
2163 aspath_loop_check(piattr->aspath, peer->as)) {
2164 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2165 zlog_debug(
2166 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2167 peer, peer->as);
2168 return false;
2169 }
2170
2171 /* If we're a CONFED we need to loop check the CONFED ID too */
2172 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2173 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2174 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2175 zlog_debug(
2176 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2177 peer, bgp->confed_id);
2178 return false;
2179 }
2180 }
2181
2182 /* Route-Reflect check. */
2183 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2184 reflect = 1;
2185 else
2186 reflect = 0;
2187
2188 /* IBGP reflection check. */
2189 if (reflect && !samepeer_safe) {
2190 /* A route from a Client peer. */
2191 if (CHECK_FLAG(from->af_flags[afi][safi],
2192 PEER_FLAG_REFLECTOR_CLIENT)) {
2193 /* Reflect to all the Non-Client peers and also to the
2194 Client peers other than the originator. Originator
2195 check
2196 is already done. So there is noting to do. */
2197 /* no bgp client-to-client reflection check. */
2198 if (CHECK_FLAG(bgp->flags,
2199 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2200 if (CHECK_FLAG(peer->af_flags[afi][safi],
2201 PEER_FLAG_REFLECTOR_CLIENT))
2202 return false;
2203 } else {
2204 /* A route from a Non-client peer. Reflect to all other
2205 clients. */
2206 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2207 PEER_FLAG_REFLECTOR_CLIENT))
2208 return false;
2209 }
2210 }
2211
2212 /* For modify attribute, copy it to temporary structure.
2213 * post_attr comes from BGP conditional advertisements, where
2214 * attributes are already processed by advertise-map route-map,
2215 * and this needs to be saved instead of overwriting from the
2216 * path attributes.
2217 */
2218 if (post_attr)
2219 *attr = *post_attr;
2220 else
2221 *attr = *piattr;
2222
2223 /* If local-preference is not set. */
2224 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2225 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2226 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2227 attr->local_pref = bgp->default_local_pref;
2228 }
2229
2230 /* If originator-id is not set and the route is to be reflected,
2231 set the originator id */
2232 if (reflect
2233 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2234 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2235 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2236 }
2237
2238 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2239 */
2240 if (peer->sort == BGP_PEER_EBGP
2241 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2242 if (from != bgp->peer_self && !transparent
2243 && !CHECK_FLAG(peer->af_flags[afi][safi],
2244 PEER_FLAG_MED_UNCHANGED))
2245 attr->flag &=
2246 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2247 }
2248
2249 /* Since the nexthop attribute can vary per peer, it is not explicitly
2250 * set
2251 * in announce check, only certain flags and length (or number of
2252 * nexthops
2253 * -- for IPv6/MP_REACH) are set here in order to guide the update
2254 * formation
2255 * code in setting the nexthop(s) on a per peer basis in
2256 * reformat_peer().
2257 * Typically, the source nexthop in the attribute is preserved but in
2258 * the
2259 * scenarios where we know it will always be overwritten, we reset the
2260 * nexthop to "0" in an attempt to achieve better Update packing. An
2261 * example of this is when a prefix from each of 2 IBGP peers needs to
2262 * be
2263 * announced to an EBGP peer (and they have the same attributes barring
2264 * their nexthop).
2265 */
2266 if (reflect)
2267 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2268
2269 #define NEXTHOP_IS_V6 \
2270 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2271 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2272 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2273 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2274
2275 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2276 * if
2277 * the peer (group) is configured to receive link-local nexthop
2278 * unchanged
2279 * and it is available in the prefix OR we're not reflecting the route,
2280 * link-local nexthop address is valid and
2281 * the peer (group) to whom we're going to announce is on a shared
2282 * network
2283 * and this is either a self-originated route or the peer is EBGP.
2284 * By checking if nexthop LL address is valid we are sure that
2285 * we do not announce LL address as `::`.
2286 */
2287 if (NEXTHOP_IS_V6) {
2288 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2289 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2290 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2291 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2292 || (!reflect && !transparent
2293 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2294 && peer->shared_network
2295 && (from == bgp->peer_self
2296 || peer->sort == BGP_PEER_EBGP))) {
2297 if (safi == SAFI_MPLS_VPN)
2298 attr->mp_nexthop_len =
2299 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2300 else
2301 attr->mp_nexthop_len =
2302 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2303 }
2304
2305 /* Clear off link-local nexthop in source, whenever it is not
2306 * needed to
2307 * ensure more prefixes share the same attribute for
2308 * announcement.
2309 */
2310 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2311 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2312 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2313 }
2314
2315 if (bgp_check_role_applicability(afi, safi) &&
2316 bgp_otc_egress(peer, attr))
2317 return false;
2318
2319 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2320 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2321
2322 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2323 filter->advmap.aname &&
2324 route_map_lookup_by_name(filter->advmap.aname)) {
2325 struct bgp_path_info rmap_path = {0};
2326 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2327 struct attr dummy_attr = *attr;
2328
2329 /* Fill temp path_info */
2330 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2331 pi, peer, &dummy_attr);
2332
2333 struct route_map *amap =
2334 route_map_lookup_by_name(filter->advmap.aname);
2335
2336 ret = route_map_apply(amap, p, &rmap_path);
2337
2338 bgp_attr_flush(&dummy_attr);
2339
2340 /*
2341 * The conditional advertisement mode is Withdraw and this
2342 * prefix is a conditional prefix. Don't advertise it
2343 */
2344 if (ret == RMAP_PERMITMATCH)
2345 return false;
2346 }
2347
2348 /* Route map & unsuppress-map apply. */
2349 if (!post_attr &&
2350 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2351 struct bgp_path_info rmap_path = {0};
2352 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2353 struct attr dummy_attr = {0};
2354
2355 /* Fill temp path_info */
2356 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2357 pi, peer, attr);
2358
2359 /* don't confuse inbound and outbound setting */
2360 RESET_FLAG(attr->rmap_change_flags);
2361
2362 /*
2363 * The route reflector is not allowed to modify the attributes
2364 * of the reflected IBGP routes unless explicitly allowed.
2365 */
2366 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2367 && !CHECK_FLAG(bgp->flags,
2368 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2369 dummy_attr = *attr;
2370 rmap_path.attr = &dummy_attr;
2371 }
2372
2373 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2374
2375 if (bgp_path_suppressed(pi))
2376 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2377 &rmap_path);
2378 else
2379 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2380 &rmap_path);
2381
2382 bgp_attr_flush(&dummy_attr);
2383 peer->rmap_type = 0;
2384
2385 if (ret == RMAP_DENYMATCH) {
2386 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2387 zlog_debug(
2388 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2389 peer, p,
2390 bgp_path_suppressed(pi)
2391 ? UNSUPPRESS_MAP_NAME(filter)
2392 : ROUTE_MAP_OUT_NAME(filter));
2393 bgp_attr_flush(rmap_path.attr);
2394 return false;
2395 }
2396 }
2397
2398 /* RFC 8212 to prevent route leaks.
2399 * This specification intends to improve this situation by requiring the
2400 * explicit configuration of both BGP Import and Export Policies for any
2401 * External BGP (EBGP) session such as customers, peers, or
2402 * confederation boundaries for all enabled address families. Through
2403 * codification of the aforementioned requirement, operators will
2404 * benefit from consistent behavior across different BGP
2405 * implementations.
2406 */
2407 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2408 if (!bgp_outbound_policy_exists(peer, filter)) {
2409 if (monotime_since(&bgp->ebgprequirespolicywarning,
2410 NULL) > FIFTEENMINUTE2USEC ||
2411 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2412 zlog_warn(
2413 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2414 monotime(&bgp->ebgprequirespolicywarning);
2415 }
2416 return false;
2417 }
2418
2419 /* draft-ietf-idr-deprecate-as-set-confed-set
2420 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2421 * Eventually, This document (if approved) updates RFC 4271
2422 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2423 * and obsoletes RFC 6472.
2424 */
2425 if (peer->bgp->reject_as_sets)
2426 if (aspath_check_as_sets(attr->aspath))
2427 return false;
2428
2429 /* If neighbor soo is configured, then check if the route has
2430 * SoO extended community and validate against the configured
2431 * one. If they match, do not announce, to prevent routing
2432 * loops.
2433 */
2434 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2435 peer->soo[afi][safi]) {
2436 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2437 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2438
2439 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2440 ECOMMUNITY_SITE_ORIGIN) ||
2441 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2442 ECOMMUNITY_SITE_ORIGIN) ||
2443 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2444 ECOMMUNITY_SITE_ORIGIN)) &&
2445 ecommunity_include(ecomm, ecomm_soo)) {
2446 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2447 zlog_debug(
2448 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2449 peer, p, ecommunity_str(ecomm_soo));
2450 return false;
2451 }
2452 }
2453
2454 /* Codification of AS 0 Processing */
2455 if (aspath_check_as_zero(attr->aspath))
2456 return false;
2457
2458 if (bgp_in_graceful_shutdown(bgp)) {
2459 if (peer->sort == BGP_PEER_IBGP
2460 || peer->sort == BGP_PEER_CONFED) {
2461 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2462 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2463 } else {
2464 bgp_attr_add_gshut_community(attr);
2465 }
2466 }
2467
2468 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2469 * Capability" to a neighbor MUST perform the following upon receiving
2470 * a route from that neighbor with the "LLGR_STALE" community, or upon
2471 * attaching the "LLGR_STALE" community itself per Section 4.2:
2472 *
2473 * The route SHOULD NOT be advertised to any neighbor from which the
2474 * Long-lived Graceful Restart Capability has not been received.
2475 */
2476 if (bgp_attr_get_community(attr) &&
2477 community_include(bgp_attr_get_community(attr),
2478 COMMUNITY_LLGR_STALE) &&
2479 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2480 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2481 return false;
2482
2483 /* After route-map has been applied, we check to see if the nexthop to
2484 * be carried in the attribute (that is used for the announcement) can
2485 * be cleared off or not. We do this in all cases where we would be
2486 * setting the nexthop to "ourselves". For IPv6, we only need to
2487 * consider
2488 * the global nexthop here; the link-local nexthop would have been
2489 * cleared
2490 * already, and if not, it is required by the update formation code.
2491 * Also see earlier comments in this function.
2492 */
2493 /*
2494 * If route-map has performed some operation on the nexthop or the peer
2495 * configuration says to pass it unchanged, we cannot reset the nexthop
2496 * here, so only attempt to do it if these aren't true. Note that the
2497 * route-map handler itself might have cleared the nexthop, if for
2498 * example,
2499 * it is configured as 'peer-address'.
2500 */
2501 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2502 piattr->rmap_change_flags)
2503 && !transparent
2504 && !CHECK_FLAG(peer->af_flags[afi][safi],
2505 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2506 /* We can reset the nexthop, if setting (or forcing) it to
2507 * 'self' */
2508 if (CHECK_FLAG(peer->af_flags[afi][safi],
2509 PEER_FLAG_NEXTHOP_SELF)
2510 || CHECK_FLAG(peer->af_flags[afi][safi],
2511 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2512 if (!reflect
2513 || CHECK_FLAG(peer->af_flags[afi][safi],
2514 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2515 subgroup_announce_reset_nhop(
2516 (peer_cap_enhe(peer, afi, safi)
2517 ? AF_INET6
2518 : p->family),
2519 attr);
2520 nh_reset = true;
2521 }
2522 } else if (peer->sort == BGP_PEER_EBGP) {
2523 /* Can also reset the nexthop if announcing to EBGP, but
2524 * only if
2525 * no peer in the subgroup is on a shared subnet.
2526 * Note: 3rd party nexthop currently implemented for
2527 * IPv4 only.
2528 */
2529 if ((p->family == AF_INET) &&
2530 (!bgp_subgrp_multiaccess_check_v4(
2531 piattr->nexthop,
2532 subgrp, from))) {
2533 subgroup_announce_reset_nhop(
2534 (peer_cap_enhe(peer, afi, safi)
2535 ? AF_INET6
2536 : p->family),
2537 attr);
2538 nh_reset = true;
2539 }
2540
2541 if ((p->family == AF_INET6) &&
2542 (!bgp_subgrp_multiaccess_check_v6(
2543 piattr->mp_nexthop_global,
2544 subgrp, from))) {
2545 subgroup_announce_reset_nhop(
2546 (peer_cap_enhe(peer, afi, safi)
2547 ? AF_INET6
2548 : p->family),
2549 attr);
2550 nh_reset = true;
2551 }
2552
2553
2554
2555 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2556 /*
2557 * This flag is used for leaked vpn-vrf routes
2558 */
2559 int family = p->family;
2560
2561 if (peer_cap_enhe(peer, afi, safi))
2562 family = AF_INET6;
2563
2564 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2565 zlog_debug(
2566 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2567 __func__, p, family2str(family));
2568 subgroup_announce_reset_nhop(family, attr);
2569 nh_reset = true;
2570 }
2571 }
2572
2573 /* If IPv6/MP and nexthop does not have any override and happens
2574 * to
2575 * be a link-local address, reset it so that we don't pass along
2576 * the
2577 * source's link-local IPv6 address to recipients who may not be
2578 * on
2579 * the same interface.
2580 */
2581 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2582 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2583 subgroup_announce_reset_nhop(AF_INET6, attr);
2584 nh_reset = true;
2585 }
2586 }
2587
2588 /* If this is an iBGP, send Origin Validation State (OVS)
2589 * extended community (rfc8097).
2590 */
2591 if (peer->sort == BGP_PEER_IBGP) {
2592 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2593
2594 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2595
2596 if (rpki_state != RPKI_NOT_BEING_USED)
2597 bgp_attr_set_ecommunity(
2598 attr, ecommunity_add_origin_validation_state(
2599 rpki_state,
2600 bgp_attr_get_ecommunity(attr)));
2601 }
2602
2603 /*
2604 * When the next hop is set to ourselves, if all multipaths have
2605 * link-bandwidth announce the cumulative bandwidth as that makes
2606 * the most sense. However, don't modify if the link-bandwidth has
2607 * been explicitly set by user policy.
2608 */
2609 if (nh_reset &&
2610 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2611 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2612 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2613 bgp_attr_set_ecommunity(
2614 attr,
2615 ecommunity_replace_linkbw(
2616 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2617 CHECK_FLAG(
2618 peer->flags,
2619 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2620
2621 return true;
2622 }
2623
2624 static void bgp_route_select_timer_expire(struct event *thread)
2625 {
2626 struct afi_safi_info *info;
2627 afi_t afi;
2628 safi_t safi;
2629 struct bgp *bgp;
2630
2631 info = EVENT_ARG(thread);
2632 afi = info->afi;
2633 safi = info->safi;
2634 bgp = info->bgp;
2635
2636 bgp->gr_info[afi][safi].t_route_select = NULL;
2637 XFREE(MTYPE_TMP, info);
2638
2639 /* Best path selection */
2640 bgp_best_path_select_defer(bgp, afi, safi);
2641 }
2642
2643 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2644 struct bgp_maxpaths_cfg *mpath_cfg,
2645 struct bgp_path_info_pair *result, afi_t afi,
2646 safi_t safi)
2647 {
2648 struct bgp_path_info *new_select;
2649 struct bgp_path_info *old_select;
2650 struct bgp_path_info *pi;
2651 struct bgp_path_info *pi1;
2652 struct bgp_path_info *pi2;
2653 struct bgp_path_info *nextpi = NULL;
2654 int paths_eq, do_mpath, debug;
2655 struct list mp_list;
2656 char pfx_buf[PREFIX2STR_BUFFER];
2657 char path_buf[PATH_ADDPATH_STR_BUFFER];
2658
2659 bgp_mp_list_init(&mp_list);
2660 do_mpath =
2661 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2662
2663 debug = bgp_debug_bestpath(dest);
2664
2665 if (debug)
2666 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2667
2668 dest->reason = bgp_path_selection_none;
2669 /* bgp deterministic-med */
2670 new_select = NULL;
2671 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2672
2673 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2674 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2675 pi1 = pi1->next)
2676 bgp_path_info_unset_flag(dest, pi1,
2677 BGP_PATH_DMED_SELECTED);
2678
2679 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2680 pi1 = pi1->next) {
2681 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2682 continue;
2683 if (BGP_PATH_HOLDDOWN(pi1))
2684 continue;
2685 if (pi1->peer != bgp->peer_self &&
2686 !CHECK_FLAG(pi1->peer->sflags,
2687 PEER_STATUS_NSF_WAIT)) {
2688 if (!peer_established(pi1->peer))
2689 continue;
2690 }
2691
2692 new_select = pi1;
2693 if (pi1->next) {
2694 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2695 if (CHECK_FLAG(pi2->flags,
2696 BGP_PATH_DMED_CHECK))
2697 continue;
2698 if (BGP_PATH_HOLDDOWN(pi2))
2699 continue;
2700 if (pi2->peer != bgp->peer_self
2701 && !CHECK_FLAG(
2702 pi2->peer->sflags,
2703 PEER_STATUS_NSF_WAIT))
2704 if (pi2->peer->status
2705 != Established)
2706 continue;
2707
2708 if (!aspath_cmp_left(pi1->attr->aspath,
2709 pi2->attr->aspath)
2710 && !aspath_cmp_left_confed(
2711 pi1->attr->aspath,
2712 pi2->attr->aspath))
2713 continue;
2714
2715 if (bgp_path_info_cmp(
2716 bgp, pi2, new_select,
2717 &paths_eq, mpath_cfg, debug,
2718 pfx_buf, afi, safi,
2719 &dest->reason)) {
2720 bgp_path_info_unset_flag(
2721 dest, new_select,
2722 BGP_PATH_DMED_SELECTED);
2723 new_select = pi2;
2724 }
2725
2726 bgp_path_info_set_flag(
2727 dest, pi2, BGP_PATH_DMED_CHECK);
2728 }
2729 }
2730 bgp_path_info_set_flag(dest, new_select,
2731 BGP_PATH_DMED_CHECK);
2732 bgp_path_info_set_flag(dest, new_select,
2733 BGP_PATH_DMED_SELECTED);
2734
2735 if (debug) {
2736 bgp_path_info_path_with_addpath_rx_str(
2737 new_select, path_buf, sizeof(path_buf));
2738 zlog_debug(
2739 "%pBD(%s): %s is the bestpath from AS %u",
2740 dest, bgp->name_pretty, path_buf,
2741 aspath_get_first_as(
2742 new_select->attr->aspath));
2743 }
2744 }
2745 }
2746
2747 /* Check old selected route and new selected route. */
2748 old_select = NULL;
2749 new_select = NULL;
2750 for (pi = bgp_dest_get_bgp_path_info(dest);
2751 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2752 enum bgp_path_selection_reason reason;
2753
2754 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2755 old_select = pi;
2756
2757 if (BGP_PATH_HOLDDOWN(pi)) {
2758 /* reap REMOVED routes, if needs be
2759 * selected route must stay for a while longer though
2760 */
2761 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2762 && (pi != old_select))
2763 bgp_path_info_reap(dest, pi);
2764
2765 if (debug)
2766 zlog_debug(
2767 "%s: %pBD(%s) pi from %s in holddown",
2768 __func__, dest, bgp->name_pretty,
2769 pi->peer->host);
2770
2771 continue;
2772 }
2773
2774 if (pi->peer && pi->peer != bgp->peer_self
2775 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2776 if (!peer_established(pi->peer)) {
2777
2778 if (debug)
2779 zlog_debug(
2780 "%s: %pBD(%s) non self peer %s not estab state",
2781 __func__, dest,
2782 bgp->name_pretty,
2783 pi->peer->host);
2784
2785 continue;
2786 }
2787
2788 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2789 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2790 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2791 if (debug)
2792 zlog_debug("%s: %pBD(%s) pi %s dmed", __func__,
2793 dest, bgp->name_pretty,
2794 pi->peer->host);
2795 continue;
2796 }
2797
2798 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2799
2800 reason = dest->reason;
2801 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2802 debug, pfx_buf, afi, safi,
2803 &dest->reason)) {
2804 if (new_select == NULL &&
2805 reason != bgp_path_selection_none)
2806 dest->reason = reason;
2807 new_select = pi;
2808 }
2809 }
2810
2811 /* Now that we know which path is the bestpath see if any of the other
2812 * paths
2813 * qualify as multipaths
2814 */
2815 if (debug) {
2816 if (new_select)
2817 bgp_path_info_path_with_addpath_rx_str(
2818 new_select, path_buf, sizeof(path_buf));
2819 else
2820 snprintf(path_buf, sizeof(path_buf), "NONE");
2821 zlog_debug(
2822 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2823 dest, bgp->name_pretty, path_buf,
2824 old_select ? old_select->peer->host : "NONE");
2825 }
2826
2827 if (do_mpath && new_select) {
2828 for (pi = bgp_dest_get_bgp_path_info(dest);
2829 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2830
2831 if (debug)
2832 bgp_path_info_path_with_addpath_rx_str(
2833 pi, path_buf, sizeof(path_buf));
2834
2835 if (pi == new_select) {
2836 if (debug)
2837 zlog_debug(
2838 "%pBD(%s): %s is the bestpath, add to the multipath list",
2839 dest, bgp->name_pretty,
2840 path_buf);
2841 bgp_mp_list_add(&mp_list, pi);
2842 continue;
2843 }
2844
2845 if (BGP_PATH_HOLDDOWN(pi))
2846 continue;
2847
2848 if (pi->peer && pi->peer != bgp->peer_self
2849 && !CHECK_FLAG(pi->peer->sflags,
2850 PEER_STATUS_NSF_WAIT))
2851 if (!peer_established(pi->peer))
2852 continue;
2853
2854 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2855 if (debug)
2856 zlog_debug(
2857 "%pBD(%s): %s has the same nexthop as the bestpath, skip it",
2858 dest, bgp->name_pretty,
2859 path_buf);
2860 continue;
2861 }
2862
2863 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2864 mpath_cfg, debug, pfx_buf, afi, safi,
2865 &dest->reason);
2866
2867 if (paths_eq) {
2868 if (debug)
2869 zlog_debug(
2870 "%pBD(%s): %s is equivalent to the bestpath, add to the multipath list",
2871 dest, bgp->name_pretty,
2872 path_buf);
2873 bgp_mp_list_add(&mp_list, pi);
2874 }
2875 }
2876 }
2877
2878 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2879 mpath_cfg);
2880 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2881 bgp_mp_list_clear(&mp_list);
2882
2883 bgp_addpath_update_ids(bgp, dest, afi, safi);
2884
2885 result->old = old_select;
2886 result->new = new_select;
2887
2888 return;
2889 }
2890
2891 /*
2892 * A new route/change in bestpath of an existing route. Evaluate the path
2893 * for advertisement to the subgroup.
2894 */
2895 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2896 struct bgp_path_info *selected,
2897 struct bgp_dest *dest,
2898 uint32_t addpath_tx_id)
2899 {
2900 const struct prefix *p;
2901 struct peer *onlypeer;
2902 struct attr attr;
2903 afi_t afi;
2904 safi_t safi;
2905 struct bgp *bgp;
2906 bool advertise;
2907
2908 p = bgp_dest_get_prefix(dest);
2909 afi = SUBGRP_AFI(subgrp);
2910 safi = SUBGRP_SAFI(subgrp);
2911 bgp = SUBGRP_INST(subgrp);
2912 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2913 : NULL);
2914
2915 if (BGP_DEBUG(update, UPDATE_OUT))
2916 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2917
2918 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2919 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2920 PEER_STATUS_ORF_WAIT_REFRESH))
2921 return;
2922
2923 memset(&attr, 0, sizeof(attr));
2924 /* It's initialized in bgp_announce_check() */
2925
2926 /* Announcement to the subgroup. If the route is filtered withdraw it.
2927 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2928 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2929 * route
2930 */
2931 advertise = bgp_check_advertise(bgp, dest);
2932
2933 if (selected) {
2934 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2935 NULL)) {
2936 /* Route is selected, if the route is already installed
2937 * in FIB, then it is advertised
2938 */
2939 if (advertise) {
2940 if (!bgp_check_withdrawal(bgp, dest)) {
2941 struct attr *adv_attr =
2942 bgp_attr_intern(&attr);
2943
2944 bgp_adj_out_set_subgroup(dest, subgrp,
2945 adv_attr,
2946 selected);
2947 } else
2948 bgp_adj_out_unset_subgroup(
2949 dest, subgrp, 1, addpath_tx_id);
2950 }
2951 } else
2952 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2953 addpath_tx_id);
2954 }
2955
2956 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2957 else {
2958 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2959 }
2960 }
2961
2962 /*
2963 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2964 * This is called at the end of route processing.
2965 */
2966 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2967 {
2968 struct bgp_path_info *pi;
2969
2970 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2971 if (BGP_PATH_HOLDDOWN(pi))
2972 continue;
2973 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2974 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2975 }
2976 }
2977
2978 /*
2979 * Has the route changed from the RIB's perspective? This is invoked only
2980 * if the route selection returns the same best route as earlier - to
2981 * determine if we need to update zebra or not.
2982 */
2983 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2984 {
2985 struct bgp_path_info *mpinfo;
2986
2987 /* If this is multipath, check all selected paths for any nexthop
2988 * change or attribute change. Some attribute changes (e.g., community)
2989 * aren't of relevance to the RIB, but we'll update zebra to ensure
2990 * we handle the case of BGP nexthop change. This is the behavior
2991 * when the best path has an attribute change anyway.
2992 */
2993 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2994 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2995 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2996 return true;
2997
2998 /*
2999 * If this is multipath, check all selected paths for any nexthop change
3000 */
3001 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
3002 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3003 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3004 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3005 return true;
3006 }
3007
3008 /* Nothing has changed from the RIB's perspective. */
3009 return false;
3010 }
3011
3012 struct bgp_process_queue {
3013 struct bgp *bgp;
3014 STAILQ_HEAD(, bgp_dest) pqueue;
3015 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3016 unsigned int flags;
3017 unsigned int queued;
3018 };
3019
3020 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3021 safi_t safi, struct bgp_dest *dest,
3022 struct bgp_path_info *new_select,
3023 struct bgp_path_info *old_select)
3024 {
3025 const struct prefix *p = bgp_dest_get_prefix(dest);
3026
3027 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3028 return;
3029
3030 if (advertise_type5_routes(bgp, afi) && new_select
3031 && is_route_injectable_into_evpn(new_select)) {
3032
3033 /* apply the route-map */
3034 if (bgp->adv_cmd_rmap[afi][safi].map) {
3035 route_map_result_t ret;
3036 struct bgp_path_info rmap_path;
3037 struct bgp_path_info_extra rmap_path_extra;
3038 struct attr dummy_attr;
3039
3040 dummy_attr = *new_select->attr;
3041
3042 /* Fill temp path_info */
3043 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3044 new_select, new_select->peer,
3045 &dummy_attr);
3046
3047 RESET_FLAG(dummy_attr.rmap_change_flags);
3048
3049 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3050 p, &rmap_path);
3051
3052 if (ret == RMAP_DENYMATCH) {
3053 bgp_attr_flush(&dummy_attr);
3054 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3055 safi);
3056 } else
3057 bgp_evpn_advertise_type5_route(
3058 bgp, p, &dummy_attr, afi, safi);
3059 } else {
3060 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3061 afi, safi);
3062 }
3063 } else if (advertise_type5_routes(bgp, afi) && old_select
3064 && is_route_injectable_into_evpn(old_select))
3065 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3066 }
3067
3068 /*
3069 * Utility to determine whether a particular path_info should use
3070 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3071 * in a path where we basically _know_ this is a BGP-LU route.
3072 */
3073 static bool bgp_lu_need_null_label(struct bgp *bgp,
3074 const struct bgp_path_info *new_select,
3075 afi_t afi, mpls_label_t *label)
3076 {
3077 /* Certain types get imp null; so do paths where the nexthop is
3078 * not labeled.
3079 */
3080 if (new_select->sub_type == BGP_ROUTE_STATIC
3081 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3082 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3083 return true;
3084 else if (new_select->extra &&
3085 bgp_is_valid_label(&new_select->extra->label[0]))
3086 return false;
3087 if (label == NULL)
3088 return true;
3089 if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LU_EXPLICIT_NULL))
3090 /* Disable PHP : explicit-null */
3091 *label = afi == AFI_IP ? MPLS_LABEL_IPV4_EXPLICIT_NULL
3092 : MPLS_LABEL_IPV6_EXPLICIT_NULL;
3093 else
3094 /* Enforced PHP popping: implicit-null */
3095 *label = MPLS_LABEL_IMPLICIT_NULL;
3096
3097 return true;
3098 }
3099
3100 /*
3101 * old_select = The old best path
3102 * new_select = the new best path
3103 *
3104 * if (!old_select && new_select)
3105 * We are sending new information on.
3106 *
3107 * if (old_select && new_select) {
3108 * if (new_select != old_select)
3109 * We have a new best path send a change
3110 * else
3111 * We've received a update with new attributes that needs
3112 * to be passed on.
3113 * }
3114 *
3115 * if (old_select && !new_select)
3116 * We have no eligible route that we can announce or the rn
3117 * is being removed.
3118 */
3119 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3120 afi_t afi, safi_t safi)
3121 {
3122 struct bgp_path_info *new_select;
3123 struct bgp_path_info *old_select;
3124 struct bgp_path_info_pair old_and_new;
3125 int debug = 0;
3126 mpls_label_t mpls_label_null;
3127
3128 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3129 if (dest)
3130 debug = bgp_debug_bestpath(dest);
3131 if (debug)
3132 zlog_debug(
3133 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3134 __func__, dest, bgp->name_pretty);
3135 return;
3136 }
3137 /* Is it end of initial update? (after startup) */
3138 if (!dest) {
3139 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3140 sizeof(bgp->update_delay_zebra_resume_time));
3141
3142 bgp->main_zebra_update_hold = 0;
3143 FOREACH_AFI_SAFI (afi, safi) {
3144 if (bgp_fibupd_safi(safi))
3145 bgp_zebra_announce_table(bgp, afi, safi);
3146 }
3147 bgp->main_peers_update_hold = 0;
3148
3149 bgp_start_routeadv(bgp);
3150 return;
3151 }
3152
3153 const struct prefix *p = bgp_dest_get_prefix(dest);
3154
3155 debug = bgp_debug_bestpath(dest);
3156 if (debug)
3157 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3158 dest, bgp->name_pretty, afi2str(afi),
3159 safi2str(safi));
3160
3161 /* The best path calculation for the route is deferred if
3162 * BGP_NODE_SELECT_DEFER is set
3163 */
3164 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3165 if (BGP_DEBUG(update, UPDATE_OUT))
3166 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3167 dest, bgp->name_pretty);
3168 return;
3169 }
3170
3171 /* Best path selection. */
3172 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3173 afi, safi);
3174 old_select = old_and_new.old;
3175 new_select = old_and_new.new;
3176
3177 /* Do we need to allocate or free labels?
3178 * Right now, since we only deal with per-prefix labels, it is not
3179 * necessary to do this upon changes to best path. Exceptions:
3180 * - label index has changed -> recalculate resulting label
3181 * - path_info sub_type changed -> switch to/from null label value
3182 * - no valid label (due to removed static label binding) -> get new one
3183 */
3184 if (bgp->allocate_mpls_labels[afi][safi]) {
3185 if (new_select) {
3186 if (!old_select
3187 || bgp_label_index_differs(new_select, old_select)
3188 || new_select->sub_type != old_select->sub_type
3189 || !bgp_is_valid_label(&dest->local_label)) {
3190 /* control label imposition for local routes,
3191 * aggregate and redistributed routes
3192 */
3193 mpls_label_null = MPLS_LABEL_IMPLICIT_NULL;
3194 if (bgp_lu_need_null_label(bgp, new_select, afi,
3195 &mpls_label_null)) {
3196 if (CHECK_FLAG(
3197 dest->flags,
3198 BGP_NODE_REGISTERED_FOR_LABEL)
3199 || CHECK_FLAG(
3200 dest->flags,
3201 BGP_NODE_LABEL_REQUESTED))
3202 bgp_unregister_for_label(dest);
3203 dest->local_label = mpls_lse_encode(
3204 mpls_label_null, 0, 0, 1);
3205 bgp_set_valid_label(&dest->local_label);
3206 } else
3207 bgp_register_for_label(dest,
3208 new_select);
3209 }
3210 } else if (CHECK_FLAG(dest->flags,
3211 BGP_NODE_REGISTERED_FOR_LABEL)
3212 || CHECK_FLAG(dest->flags,
3213 BGP_NODE_LABEL_REQUESTED)) {
3214 bgp_unregister_for_label(dest);
3215 }
3216 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3217 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3218 bgp_unregister_for_label(dest);
3219 }
3220
3221 if (debug)
3222 zlog_debug(
3223 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3224 __func__, dest, bgp->name_pretty, afi2str(afi),
3225 safi2str(safi), old_select, new_select);
3226
3227 /* If best route remains the same and this is not due to user-initiated
3228 * clear, see exactly what needs to be done.
3229 */
3230 if (old_select && old_select == new_select
3231 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3232 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3233 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3234 if (bgp_zebra_has_route_changed(old_select)) {
3235 #ifdef ENABLE_BGP_VNC
3236 vnc_import_bgp_add_route(bgp, p, old_select);
3237 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3238 #endif
3239 if (bgp_fibupd_safi(safi)
3240 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3241
3242 if (new_select->type == ZEBRA_ROUTE_BGP
3243 && (new_select->sub_type == BGP_ROUTE_NORMAL
3244 || new_select->sub_type
3245 == BGP_ROUTE_IMPORTED))
3246
3247 bgp_zebra_announce(dest, p, old_select,
3248 bgp, afi, safi);
3249 }
3250 }
3251
3252 /* If there is a change of interest to peers, reannounce the
3253 * route. */
3254 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3255 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3256 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3257 group_announce_route(bgp, afi, safi, dest, new_select);
3258
3259 /* unicast routes must also be annouced to
3260 * labeled-unicast update-groups */
3261 if (safi == SAFI_UNICAST)
3262 group_announce_route(bgp, afi,
3263 SAFI_LABELED_UNICAST, dest,
3264 new_select);
3265
3266 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3267 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3268 }
3269
3270 /* advertise/withdraw type-5 routes */
3271 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3272 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3273 bgp_process_evpn_route_injection(
3274 bgp, afi, safi, dest, old_select, old_select);
3275
3276 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3277 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3278 bgp_zebra_clear_route_change_flags(dest);
3279 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3280 return;
3281 }
3282
3283 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3284 */
3285 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3286
3287 /* bestpath has changed; bump version */
3288 if (old_select || new_select) {
3289 bgp_bump_version(dest);
3290
3291 if (!bgp->t_rmap_def_originate_eval) {
3292 bgp_lock(bgp);
3293 event_add_timer(
3294 bm->master,
3295 update_group_refresh_default_originate_route_map,
3296 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3297 &bgp->t_rmap_def_originate_eval);
3298 }
3299 }
3300
3301 if (old_select)
3302 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3303 if (new_select) {
3304 if (debug)
3305 zlog_debug("%s: setting SELECTED flag", __func__);
3306 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3307 bgp_path_info_unset_flag(dest, new_select,
3308 BGP_PATH_ATTR_CHANGED);
3309 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3310 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3311 }
3312
3313 #ifdef ENABLE_BGP_VNC
3314 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3315 if (old_select != new_select) {
3316 if (old_select) {
3317 vnc_import_bgp_exterior_del_route(bgp, p,
3318 old_select);
3319 vnc_import_bgp_del_route(bgp, p, old_select);
3320 }
3321 if (new_select) {
3322 vnc_import_bgp_exterior_add_route(bgp, p,
3323 new_select);
3324 vnc_import_bgp_add_route(bgp, p, new_select);
3325 }
3326 }
3327 }
3328 #endif
3329
3330 group_announce_route(bgp, afi, safi, dest, new_select);
3331
3332 /* unicast routes must also be annouced to labeled-unicast update-groups
3333 */
3334 if (safi == SAFI_UNICAST)
3335 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3336 new_select);
3337
3338 /* FIB update. */
3339 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3340 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3341
3342 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3343 && (new_select->sub_type == BGP_ROUTE_NORMAL
3344 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3345 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3346
3347 /* if this is an evpn imported type-5 prefix,
3348 * we need to withdraw the route first to clear
3349 * the nh neigh and the RMAC entry.
3350 */
3351 if (old_select &&
3352 is_route_parent_evpn(old_select))
3353 bgp_zebra_withdraw(p, old_select, bgp, safi);
3354
3355 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3356 } else {
3357 /* Withdraw the route from the kernel. */
3358 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3359 && (old_select->sub_type == BGP_ROUTE_NORMAL
3360 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3361 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3362
3363 bgp_zebra_withdraw(p, old_select, bgp, safi);
3364 }
3365 }
3366
3367 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3368 old_select);
3369
3370 /* Clear any route change flags. */
3371 bgp_zebra_clear_route_change_flags(dest);
3372
3373 /* Reap old select bgp_path_info, if it has been removed */
3374 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3375 bgp_path_info_reap(dest, old_select);
3376
3377 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3378 return;
3379 }
3380
3381 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3382 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3383 {
3384 struct bgp_dest *dest;
3385 int cnt = 0;
3386 struct afi_safi_info *thread_info;
3387
3388 if (bgp->gr_info[afi][safi].t_route_select) {
3389 struct event *t = bgp->gr_info[afi][safi].t_route_select;
3390
3391 thread_info = EVENT_ARG(t);
3392 XFREE(MTYPE_TMP, thread_info);
3393 EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
3394 }
3395
3396 if (BGP_DEBUG(update, UPDATE_OUT)) {
3397 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3398 get_afi_safi_str(afi, safi, false),
3399 bgp->gr_info[afi][safi].gr_deferred);
3400 }
3401
3402 /* Process the route list */
3403 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3404 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3405 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3406 dest = bgp_route_next(dest)) {
3407 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3408 continue;
3409
3410 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3411 bgp->gr_info[afi][safi].gr_deferred--;
3412 bgp_process_main_one(bgp, dest, afi, safi);
3413 cnt++;
3414 }
3415 /* If iteration stopped before the entire table was traversed then the
3416 * node needs to be unlocked.
3417 */
3418 if (dest) {
3419 bgp_dest_unlock_node(dest);
3420 dest = NULL;
3421 }
3422
3423 /* Send EOR message when all routes are processed */
3424 if (!bgp->gr_info[afi][safi].gr_deferred) {
3425 bgp_send_delayed_eor(bgp);
3426 /* Send route processing complete message to RIB */
3427 bgp_zebra_update(bgp, afi, safi,
3428 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3429 return;
3430 }
3431
3432 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3433
3434 thread_info->afi = afi;
3435 thread_info->safi = safi;
3436 thread_info->bgp = bgp;
3437
3438 /* If there are more routes to be processed, start the
3439 * selection timer
3440 */
3441 event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3442 BGP_ROUTE_SELECT_DELAY,
3443 &bgp->gr_info[afi][safi].t_route_select);
3444 }
3445
3446 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3447 {
3448 struct bgp_process_queue *pqnode = data;
3449 struct bgp *bgp = pqnode->bgp;
3450 struct bgp_table *table;
3451 struct bgp_dest *dest;
3452
3453 /* eoiu marker */
3454 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3455 bgp_process_main_one(bgp, NULL, 0, 0);
3456 /* should always have dedicated wq call */
3457 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3458 return WQ_SUCCESS;
3459 }
3460
3461 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3462 dest = STAILQ_FIRST(&pqnode->pqueue);
3463 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3464 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3465 table = bgp_dest_table(dest);
3466 /* note, new DESTs may be added as part of processing */
3467 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3468
3469 bgp_dest_unlock_node(dest);
3470 bgp_table_unlock(table);
3471 }
3472
3473 return WQ_SUCCESS;
3474 }
3475
3476 static void bgp_processq_del(struct work_queue *wq, void *data)
3477 {
3478 struct bgp_process_queue *pqnode = data;
3479
3480 bgp_unlock(pqnode->bgp);
3481
3482 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3483 }
3484
3485 void bgp_process_queue_init(struct bgp *bgp)
3486 {
3487 if (!bgp->process_queue) {
3488 char name[BUFSIZ];
3489
3490 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3491 bgp->process_queue = work_queue_new(bm->master, name);
3492 }
3493
3494 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3495 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3496 bgp->process_queue->spec.max_retries = 0;
3497 bgp->process_queue->spec.hold = 50;
3498 /* Use a higher yield value of 50ms for main queue processing */
3499 bgp->process_queue->spec.yield = 50 * 1000L;
3500 }
3501
3502 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3503 {
3504 struct bgp_process_queue *pqnode;
3505
3506 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3507 sizeof(struct bgp_process_queue));
3508
3509 /* unlocked in bgp_processq_del */
3510 pqnode->bgp = bgp_lock(bgp);
3511 STAILQ_INIT(&pqnode->pqueue);
3512
3513 return pqnode;
3514 }
3515
3516 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3517 {
3518 #define ARBITRARY_PROCESS_QLEN 10000
3519 struct work_queue *wq = bgp->process_queue;
3520 struct bgp_process_queue *pqnode;
3521 int pqnode_reuse = 0;
3522
3523 /* already scheduled for processing? */
3524 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3525 return;
3526
3527 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3528 * the workqueue
3529 */
3530 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3531 if (BGP_DEBUG(update, UPDATE_OUT))
3532 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3533 dest);
3534 return;
3535 }
3536
3537 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3538 if (BGP_DEBUG(update, UPDATE_OUT))
3539 zlog_debug(
3540 "Soft reconfigure table in progress for route %p",
3541 dest);
3542 return;
3543 }
3544
3545 if (wq == NULL)
3546 return;
3547
3548 /* Add route nodes to an existing work queue item until reaching the
3549 limit only if is from the same BGP view and it's not an EOIU marker
3550 */
3551 if (work_queue_item_count(wq)) {
3552 struct work_queue_item *item = work_queue_last_item(wq);
3553 pqnode = item->data;
3554
3555 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3556 || pqnode->bgp != bgp
3557 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3558 pqnode = bgp_processq_alloc(bgp);
3559 else
3560 pqnode_reuse = 1;
3561 } else
3562 pqnode = bgp_processq_alloc(bgp);
3563 /* all unlocked in bgp_process_wq */
3564 bgp_table_lock(bgp_dest_table(dest));
3565
3566 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3567 bgp_dest_lock_node(dest);
3568
3569 /* can't be enqueued twice */
3570 assert(STAILQ_NEXT(dest, pq) == NULL);
3571 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3572 pqnode->queued++;
3573
3574 if (!pqnode_reuse)
3575 work_queue_add(wq, pqnode);
3576
3577 return;
3578 }
3579
3580 void bgp_add_eoiu_mark(struct bgp *bgp)
3581 {
3582 struct bgp_process_queue *pqnode;
3583
3584 if (bgp->process_queue == NULL)
3585 return;
3586
3587 pqnode = bgp_processq_alloc(bgp);
3588
3589 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3590 work_queue_add(bgp->process_queue, pqnode);
3591 }
3592
3593 static void bgp_maximum_prefix_restart_timer(struct event *thread)
3594 {
3595 struct peer *peer;
3596
3597 peer = EVENT_ARG(thread);
3598 peer->t_pmax_restart = NULL;
3599
3600 if (bgp_debug_neighbor_events(peer))
3601 zlog_debug(
3602 "%s Maximum-prefix restart timer expired, restore peering",
3603 peer->host);
3604
3605 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3606 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3607 }
3608
3609 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3610 safi_t safi)
3611 {
3612 uint32_t count = 0;
3613 bool filtered = false;
3614 struct bgp_dest *dest;
3615 struct bgp_adj_in *ain;
3616 struct attr attr = {};
3617 struct bgp_table *table = peer->bgp->rib[afi][safi];
3618
3619 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3620 for (ain = dest->adj_in; ain; ain = ain->next) {
3621 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3622
3623 attr = *ain->attr;
3624
3625 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3626 == FILTER_DENY)
3627 filtered = true;
3628
3629 if (bgp_input_modifier(
3630 peer, rn_p, &attr, afi, safi,
3631 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3632 NULL, 0, NULL)
3633 == RMAP_DENY)
3634 filtered = true;
3635
3636 if (filtered)
3637 count++;
3638
3639 bgp_attr_flush(&attr);
3640 }
3641 }
3642
3643 return count;
3644 }
3645
3646 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3647 int always)
3648 {
3649 iana_afi_t pkt_afi;
3650 iana_safi_t pkt_safi;
3651 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3652 PEER_FLAG_MAX_PREFIX_FORCE))
3653 ? bgp_filtered_routes_count(peer, afi, safi)
3654 + peer->pcount[afi][safi]
3655 : peer->pcount[afi][safi];
3656
3657 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3658 return false;
3659
3660 if (pcount > peer->pmax[afi][safi]) {
3661 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3662 PEER_STATUS_PREFIX_LIMIT)
3663 && !always)
3664 return false;
3665
3666 zlog_info(
3667 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3668 get_afi_safi_str(afi, safi, false), peer, pcount,
3669 peer->pmax[afi][safi]);
3670 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3671
3672 if (CHECK_FLAG(peer->af_flags[afi][safi],
3673 PEER_FLAG_MAX_PREFIX_WARNING))
3674 return false;
3675
3676 /* Convert AFI, SAFI to values for packet. */
3677 pkt_afi = afi_int2iana(afi);
3678 pkt_safi = safi_int2iana(safi);
3679 {
3680 uint8_t ndata[7];
3681
3682 ndata[0] = (pkt_afi >> 8);
3683 ndata[1] = pkt_afi;
3684 ndata[2] = pkt_safi;
3685 ndata[3] = (peer->pmax[afi][safi] >> 24);
3686 ndata[4] = (peer->pmax[afi][safi] >> 16);
3687 ndata[5] = (peer->pmax[afi][safi] >> 8);
3688 ndata[6] = (peer->pmax[afi][safi]);
3689
3690 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3691 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3692 BGP_NOTIFY_CEASE_MAX_PREFIX,
3693 ndata, 7);
3694 }
3695
3696 /* Dynamic peers will just close their connection. */
3697 if (peer_dynamic_neighbor(peer))
3698 return true;
3699
3700 /* restart timer start */
3701 if (peer->pmax_restart[afi][safi]) {
3702 peer->v_pmax_restart =
3703 peer->pmax_restart[afi][safi] * 60;
3704
3705 if (bgp_debug_neighbor_events(peer))
3706 zlog_debug(
3707 "%pBP Maximum-prefix restart timer started for %d secs",
3708 peer, peer->v_pmax_restart);
3709
3710 BGP_TIMER_ON(peer->t_pmax_restart,
3711 bgp_maximum_prefix_restart_timer,
3712 peer->v_pmax_restart);
3713 }
3714
3715 return true;
3716 } else
3717 UNSET_FLAG(peer->af_sflags[afi][safi],
3718 PEER_STATUS_PREFIX_LIMIT);
3719
3720 if (pcount
3721 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3722 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3723 PEER_STATUS_PREFIX_THRESHOLD)
3724 && !always)
3725 return false;
3726
3727 zlog_info(
3728 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3729 get_afi_safi_str(afi, safi, false), peer, pcount,
3730 peer->pmax[afi][safi]);
3731 SET_FLAG(peer->af_sflags[afi][safi],
3732 PEER_STATUS_PREFIX_THRESHOLD);
3733 } else
3734 UNSET_FLAG(peer->af_sflags[afi][safi],
3735 PEER_STATUS_PREFIX_THRESHOLD);
3736 return false;
3737 }
3738
3739 /* Unconditionally remove the route from the RIB, without taking
3740 * damping into consideration (eg, because the session went down)
3741 */
3742 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3743 struct peer *peer, afi_t afi, safi_t safi)
3744 {
3745
3746 struct bgp *bgp = NULL;
3747 bool delete_route = false;
3748
3749 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3750 safi);
3751
3752 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3753 bgp_path_info_delete(dest, pi); /* keep historical info */
3754
3755 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3756 * flag
3757 */
3758 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3759 delete_route = true;
3760 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3761 delete_route = true;
3762 if (delete_route) {
3763 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3764 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3765 bgp = pi->peer->bgp;
3766 bgp->gr_info[afi][safi].gr_deferred--;
3767 }
3768 }
3769 }
3770
3771 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3772 bgp_process(peer->bgp, dest, afi, safi);
3773 }
3774
3775 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3776 struct peer *peer, afi_t afi, safi_t safi,
3777 struct prefix_rd *prd)
3778 {
3779 const struct prefix *p = bgp_dest_get_prefix(dest);
3780
3781 /* apply dampening, if result is suppressed, we'll be retaining
3782 * the bgp_path_info in the RIB for historical reference.
3783 */
3784 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3785 && peer->sort == BGP_PEER_EBGP)
3786 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3787 == BGP_DAMP_SUPPRESSED) {
3788 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3789 safi);
3790 return;
3791 }
3792
3793 #ifdef ENABLE_BGP_VNC
3794 if (safi == SAFI_MPLS_VPN) {
3795 struct bgp_dest *pdest = NULL;
3796 struct bgp_table *table = NULL;
3797
3798 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3799 (struct prefix *)prd);
3800 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3801 table = bgp_dest_get_bgp_table_info(pdest);
3802
3803 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3804 peer->bgp, prd, table, p, pi);
3805 }
3806 bgp_dest_unlock_node(pdest);
3807 }
3808 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3809 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3810
3811 vnc_import_bgp_del_route(peer->bgp, p, pi);
3812 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3813 }
3814 }
3815 #endif
3816
3817 /* If this is an EVPN route, process for un-import. */
3818 if (safi == SAFI_EVPN)
3819 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3820
3821 bgp_rib_remove(dest, pi, peer, afi, safi);
3822 }
3823
3824 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3825 struct peer *peer, struct attr *attr,
3826 struct bgp_dest *dest)
3827 {
3828 struct bgp_path_info *new;
3829
3830 /* Make new BGP info. */
3831 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3832 new->type = type;
3833 new->instance = instance;
3834 new->sub_type = sub_type;
3835 new->peer = peer;
3836 new->attr = attr;
3837 new->uptime = monotime(NULL);
3838 new->net = dest;
3839 return new;
3840 }
3841
3842 /* Check if received nexthop is valid or not. */
3843 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3844 uint8_t type, uint8_t stype, struct attr *attr,
3845 struct bgp_dest *dest)
3846 {
3847 bool ret = false;
3848 bool is_bgp_static_route =
3849 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3850 : false;
3851
3852 /* If `bgp allow-martian-nexthop` is turned on, return next-hop
3853 * as good.
3854 */
3855 if (bgp->allow_martian)
3856 return false;
3857
3858 /*
3859 * Only validated for unicast and multicast currently.
3860 * Also valid for EVPN where the nexthop is an IP address.
3861 * If we are a bgp static route being checked then there is
3862 * no need to check to see if the nexthop is martian as
3863 * that it should be ok.
3864 */
3865 if (is_bgp_static_route ||
3866 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3867 return false;
3868
3869 /* If NEXT_HOP is present, validate it. */
3870 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3871 if (attr->nexthop.s_addr == INADDR_ANY ||
3872 !ipv4_unicast_valid(&attr->nexthop) ||
3873 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3874 return true;
3875 }
3876
3877 /* If MP_NEXTHOP is present, validate it. */
3878 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3879 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3880 * it is not an IPv6 link-local address.
3881 *
3882 * If we receive an UPDATE with nexthop length set to 32 bytes
3883 * we shouldn't discard an UPDATE if it's set to (::).
3884 * The link-local (2st) is validated along the code path later.
3885 */
3886 if (attr->mp_nexthop_len) {
3887 switch (attr->mp_nexthop_len) {
3888 case BGP_ATTR_NHLEN_IPV4:
3889 case BGP_ATTR_NHLEN_VPNV4:
3890 ret = (attr->mp_nexthop_global_in.s_addr ==
3891 INADDR_ANY ||
3892 !ipv4_unicast_valid(
3893 &attr->mp_nexthop_global_in) ||
3894 bgp_nexthop_self(bgp, afi, type, stype, attr,
3895 dest));
3896 break;
3897
3898 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3899 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3900 ret = (IN6_IS_ADDR_UNSPECIFIED(
3901 &attr->mp_nexthop_global)
3902 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3903 || IN6_IS_ADDR_MULTICAST(
3904 &attr->mp_nexthop_global)
3905 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3906 dest));
3907 break;
3908 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3909 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3910 || IN6_IS_ADDR_MULTICAST(
3911 &attr->mp_nexthop_global)
3912 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3913 dest));
3914 break;
3915
3916 default:
3917 ret = true;
3918 break;
3919 }
3920 }
3921
3922 return ret;
3923 }
3924
3925 static void bgp_attr_add_no_export_community(struct attr *attr)
3926 {
3927 struct community *old;
3928 struct community *new;
3929 struct community *merge;
3930 struct community *no_export;
3931
3932 old = bgp_attr_get_community(attr);
3933 no_export = community_str2com("no-export");
3934
3935 assert(no_export);
3936
3937 if (old) {
3938 merge = community_merge(community_dup(old), no_export);
3939
3940 if (!old->refcnt)
3941 community_free(&old);
3942
3943 new = community_uniq_sort(merge);
3944 community_free(&merge);
3945 } else {
3946 new = community_dup(no_export);
3947 }
3948
3949 community_free(&no_export);
3950
3951 bgp_attr_set_community(attr, new);
3952 }
3953
3954 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3955 struct attr *attr, const struct prefix *prefix,
3956 int *sub_type)
3957 {
3958 struct listnode *node, *nnode;
3959 struct bgp *bgp;
3960 bool accept_own_found = false;
3961
3962 if (safi != SAFI_MPLS_VPN)
3963 return false;
3964
3965 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3966 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3967 return false;
3968
3969 /* The route in question carries the ACCEPT_OWN community */
3970 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3971 struct community *comm = bgp_attr_get_community(attr);
3972
3973 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3974 accept_own_found = true;
3975 }
3976
3977 /* The route in question is targeted to one or more destination VRFs
3978 * on the router (as determined by inspecting the Route Target(s)).
3979 */
3980 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3981 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3982 continue;
3983
3984 if (accept_own_found &&
3985 ecommunity_include(
3986 bgp->vpn_policy[afi]
3987 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3988 bgp_attr_get_ecommunity(attr))) {
3989 if (bgp_debug_update(peer, prefix, NULL, 1))
3990 zlog_debug(
3991 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3992 peer, prefix);
3993
3994 /* Treat this route as imported, because it's leaked
3995 * already from another VRF, and we got an updated
3996 * version from route-reflector with ACCEPT_OWN
3997 * community.
3998 */
3999 *sub_type = BGP_ROUTE_IMPORTED;
4000
4001 return true;
4002 }
4003 }
4004
4005 return false;
4006 }
4007
4008 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4009 struct attr *attr, afi_t afi, safi_t safi, int type,
4010 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4011 uint32_t num_labels, int soft_reconfig,
4012 struct bgp_route_evpn *evpn)
4013 {
4014 int ret;
4015 int aspath_loop_count = 0;
4016 struct bgp_dest *dest;
4017 struct bgp *bgp;
4018 struct attr new_attr;
4019 struct attr *attr_new;
4020 struct bgp_path_info *pi;
4021 struct bgp_path_info *new = NULL;
4022 struct bgp_path_info_extra *extra;
4023 const char *reason;
4024 char pfx_buf[BGP_PRD_PATH_STRLEN];
4025 int connected = 0;
4026 int do_loop_check = 1;
4027 int has_valid_label = 0;
4028 afi_t nh_afi;
4029 bool force_evpn_import = false;
4030 safi_t orig_safi = safi;
4031 bool leak_success = true;
4032 int allowas_in = 0;
4033
4034 if (frrtrace_enabled(frr_bgp, process_update)) {
4035 char pfxprint[PREFIX2STR_BUFFER];
4036
4037 prefix2str(p, pfxprint, sizeof(pfxprint));
4038 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4039 afi, safi, attr);
4040 }
4041
4042 #ifdef ENABLE_BGP_VNC
4043 int vnc_implicit_withdraw = 0;
4044 #endif
4045 int same_attr = 0;
4046 const struct prefix *bgp_nht_param_prefix;
4047
4048 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4049 if (orig_safi == SAFI_LABELED_UNICAST)
4050 safi = SAFI_UNICAST;
4051
4052 memset(&new_attr, 0, sizeof(new_attr));
4053 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4054 new_attr.label = MPLS_INVALID_LABEL;
4055
4056 bgp = peer->bgp;
4057 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4058 /* TODO: Check to see if we can get rid of "is_valid_label" */
4059 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4060 has_valid_label = (num_labels > 0) ? 1 : 0;
4061 else
4062 has_valid_label = bgp_is_valid_label(label);
4063
4064 if (has_valid_label)
4065 assert(label != NULL);
4066
4067 /* Update overlay index of the attribute */
4068 if (afi == AFI_L2VPN && evpn)
4069 memcpy(&attr->evpn_overlay, evpn,
4070 sizeof(struct bgp_route_evpn));
4071
4072 /* When peer's soft reconfiguration enabled. Record input packet in
4073 Adj-RIBs-In. */
4074 if (!soft_reconfig
4075 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4076 && peer != bgp->peer_self)
4077 bgp_adj_in_set(dest, peer, attr, addpath_id);
4078
4079 /* Update permitted loop count */
4080 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4081 allowas_in = peer->allowas_in[afi][safi];
4082
4083 /* Check previously received route. */
4084 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4085 if (pi->peer == peer && pi->type == type
4086 && pi->sub_type == sub_type
4087 && pi->addpath_rx_id == addpath_id)
4088 break;
4089
4090 /* AS path local-as loop check. */
4091 if (peer->change_local_as) {
4092 if (allowas_in)
4093 aspath_loop_count = allowas_in;
4094 else if (!CHECK_FLAG(peer->flags,
4095 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4096 aspath_loop_count = 1;
4097
4098 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4099 > aspath_loop_count) {
4100 peer->stat_pfx_aspath_loop++;
4101 reason = "as-path contains our own AS;";
4102 goto filtered;
4103 }
4104 }
4105
4106 /* If the peer is configured for "allowas-in origin" and the last ASN in
4107 * the
4108 * as-path is our ASN then we do not need to call aspath_loop_check
4109 */
4110 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4111 if (aspath_get_last_as(attr->aspath) == bgp->as)
4112 do_loop_check = 0;
4113
4114 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4115 bgp_nht_param_prefix = NULL;
4116 else
4117 bgp_nht_param_prefix = p;
4118
4119 /* AS path loop check. */
4120 if (do_loop_check) {
4121 if (aspath_loop_check(attr->aspath, bgp->as) >
4122 peer->allowas_in[afi][safi]) {
4123 peer->stat_pfx_aspath_loop++;
4124 reason = "as-path contains our own AS;";
4125 goto filtered;
4126 }
4127 }
4128
4129 /* If we're a CONFED we need to loop check the CONFED ID too */
4130 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4131 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4132 peer->allowas_in[afi][safi]) {
4133 peer->stat_pfx_aspath_loop++;
4134 reason = "as-path contains our own confed AS;";
4135 goto filtered;
4136 }
4137
4138 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4139 * enabled, then take care of that too.
4140 */
4141 bool accept_own = false;
4142
4143 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4144 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4145 accept_own =
4146 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4147 if (!accept_own) {
4148 peer->stat_pfx_originator_loop++;
4149 reason = "originator is us;";
4150 goto filtered;
4151 }
4152 }
4153
4154 /* Route reflector cluster ID check. */
4155 if (bgp_cluster_filter(peer, attr)) {
4156 peer->stat_pfx_cluster_loop++;
4157 reason = "reflected from the same cluster;";
4158 goto filtered;
4159 }
4160
4161 /* Apply incoming filter. */
4162 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4163 peer->stat_pfx_filter++;
4164 reason = "filter;";
4165 goto filtered;
4166 }
4167
4168 /* RFC 8212 to prevent route leaks.
4169 * This specification intends to improve this situation by requiring the
4170 * explicit configuration of both BGP Import and Export Policies for any
4171 * External BGP (EBGP) session such as customers, peers, or
4172 * confederation boundaries for all enabled address families. Through
4173 * codification of the aforementioned requirement, operators will
4174 * benefit from consistent behavior across different BGP
4175 * implementations.
4176 */
4177 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4178 if (!bgp_inbound_policy_exists(peer,
4179 &peer->filter[afi][safi])) {
4180 reason = "inbound policy missing";
4181 if (monotime_since(&bgp->ebgprequirespolicywarning,
4182 NULL) > FIFTEENMINUTE2USEC ||
4183 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4184 zlog_warn(
4185 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4186 monotime(&bgp->ebgprequirespolicywarning);
4187 }
4188 goto filtered;
4189 }
4190
4191 /* draft-ietf-idr-deprecate-as-set-confed-set
4192 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4193 * Eventually, This document (if approved) updates RFC 4271
4194 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4195 * and obsoletes RFC 6472.
4196 */
4197 if (peer->bgp->reject_as_sets)
4198 if (aspath_check_as_sets(attr->aspath)) {
4199 reason =
4200 "as-path contains AS_SET or AS_CONFED_SET type;";
4201 goto filtered;
4202 }
4203
4204 new_attr = *attr;
4205
4206 /* Apply incoming route-map.
4207 * NB: new_attr may now contain newly allocated values from route-map
4208 * "set"
4209 * commands, so we need bgp_attr_flush in the error paths, until we
4210 * intern
4211 * the attr (which takes over the memory references) */
4212 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4213 num_labels, dest)
4214 == RMAP_DENY) {
4215 peer->stat_pfx_filter++;
4216 reason = "route-map;";
4217 bgp_attr_flush(&new_attr);
4218 goto filtered;
4219 }
4220
4221 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4222 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4223 /* remove from RIB previous entry */
4224 bgp_zebra_withdraw(p, pi, bgp, safi);
4225 }
4226
4227 if (peer->sort == BGP_PEER_EBGP) {
4228
4229 /* rfc7999:
4230 * A BGP speaker receiving an announcement tagged with the
4231 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4232 * NO_EXPORT community as defined in RFC1997, or a
4233 * similar community, to prevent propagation of the
4234 * prefix outside the local AS. The community to prevent
4235 * propagation SHOULD be chosen according to the operator's
4236 * routing policy.
4237 */
4238 if (bgp_attr_get_community(&new_attr) &&
4239 community_include(bgp_attr_get_community(&new_attr),
4240 COMMUNITY_BLACKHOLE))
4241 bgp_attr_add_no_export_community(&new_attr);
4242
4243 /* If we receive the graceful-shutdown community from an eBGP
4244 * peer we must lower local-preference */
4245 if (bgp_attr_get_community(&new_attr) &&
4246 community_include(bgp_attr_get_community(&new_attr),
4247 COMMUNITY_GSHUT)) {
4248 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4249 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4250
4251 /* If graceful-shutdown is configured globally or
4252 * per neighbor, then add the GSHUT community to
4253 * all paths received from eBGP peers. */
4254 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4255 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4256 bgp_attr_add_gshut_community(&new_attr);
4257 }
4258
4259 /* next hop check. */
4260 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4261 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4262 &new_attr, dest)) {
4263 peer->stat_pfx_nh_invalid++;
4264 reason = "martian or self next-hop;";
4265 bgp_attr_flush(&new_attr);
4266 goto filtered;
4267 }
4268
4269 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4270 peer->stat_pfx_nh_invalid++;
4271 reason = "self mac;";
4272 bgp_attr_flush(&new_attr);
4273 goto filtered;
4274 }
4275
4276 if (bgp_check_role_applicability(afi, safi) &&
4277 bgp_otc_filter(peer, &new_attr)) {
4278 reason = "failing otc validation";
4279 bgp_attr_flush(&new_attr);
4280 goto filtered;
4281 }
4282
4283 /* If neighbor soo is configured, tag all incoming routes with
4284 * this SoO tag and then filter out advertisements in
4285 * subgroup_announce_check() if it matches the configured SoO
4286 * on the other peer.
4287 */
4288 if (peer->soo[afi][safi]) {
4289 struct ecommunity *old_ecomm =
4290 bgp_attr_get_ecommunity(&new_attr);
4291 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4292 struct ecommunity *new_ecomm;
4293
4294 if (old_ecomm) {
4295 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4296 ecomm_soo);
4297
4298 if (!old_ecomm->refcnt)
4299 ecommunity_free(&old_ecomm);
4300 } else {
4301 new_ecomm = ecommunity_dup(ecomm_soo);
4302 }
4303
4304 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4305 }
4306
4307 attr_new = bgp_attr_intern(&new_attr);
4308
4309 /* If the update is implicit withdraw. */
4310 if (pi) {
4311 pi->uptime = monotime(NULL);
4312 same_attr = attrhash_cmp(pi->attr, attr_new);
4313
4314 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4315
4316 /* Same attribute comes in. */
4317 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4318 && same_attr
4319 && (!has_valid_label
4320 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4321 num_labels * sizeof(mpls_label_t))
4322 == 0)) {
4323 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4324 BGP_CONFIG_DAMPENING)
4325 && peer->sort == BGP_PEER_EBGP
4326 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4327 if (bgp_debug_update(peer, p, NULL, 1)) {
4328 bgp_debug_rdpfxpath2str(
4329 afi, safi, prd, p, label,
4330 num_labels, addpath_id ? 1 : 0,
4331 addpath_id, evpn, pfx_buf,
4332 sizeof(pfx_buf));
4333 zlog_debug("%pBP rcvd %s", peer,
4334 pfx_buf);
4335 }
4336
4337 if (bgp_damp_update(pi, dest, afi, safi)
4338 != BGP_DAMP_SUPPRESSED) {
4339 bgp_aggregate_increment(bgp, p, pi, afi,
4340 safi);
4341 bgp_process(bgp, dest, afi, safi);
4342 }
4343 } else /* Duplicate - odd */
4344 {
4345 if (bgp_debug_update(peer, p, NULL, 1)) {
4346 if (!peer->rcvd_attr_printed) {
4347 zlog_debug(
4348 "%pBP rcvd UPDATE w/ attr: %s",
4349 peer,
4350 peer->rcvd_attr_str);
4351 peer->rcvd_attr_printed = 1;
4352 }
4353
4354 bgp_debug_rdpfxpath2str(
4355 afi, safi, prd, p, label,
4356 num_labels, addpath_id ? 1 : 0,
4357 addpath_id, evpn, pfx_buf,
4358 sizeof(pfx_buf));
4359 zlog_debug(
4360 "%pBP rcvd %s...duplicate ignored",
4361 peer, pfx_buf);
4362 }
4363
4364 /* graceful restart STALE flag unset. */
4365 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4366 bgp_path_info_unset_flag(
4367 dest, pi, BGP_PATH_STALE);
4368 bgp_dest_set_defer_flag(dest, false);
4369 bgp_process(bgp, dest, afi, safi);
4370 }
4371 }
4372
4373 bgp_dest_unlock_node(dest);
4374 bgp_attr_unintern(&attr_new);
4375
4376 return;
4377 }
4378
4379 /* Withdraw/Announce before we fully processed the withdraw */
4380 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4381 if (bgp_debug_update(peer, p, NULL, 1)) {
4382 bgp_debug_rdpfxpath2str(
4383 afi, safi, prd, p, label, num_labels,
4384 addpath_id ? 1 : 0, addpath_id, evpn,
4385 pfx_buf, sizeof(pfx_buf));
4386 zlog_debug(
4387 "%pBP rcvd %s, flapped quicker than processing",
4388 peer, pfx_buf);
4389 }
4390
4391 bgp_path_info_restore(dest, pi);
4392
4393 /*
4394 * If the BGP_PATH_REMOVED flag is set, then EVPN
4395 * routes would have been unimported already when a
4396 * prior BGP withdraw processing happened. Such routes
4397 * need to be imported again, so flag accordingly.
4398 */
4399 force_evpn_import = true;
4400 } else {
4401 /* implicit withdraw, decrement aggregate and pcount
4402 * here. only if update is accepted, they'll increment
4403 * below.
4404 */
4405 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4406 }
4407
4408 /* Received Logging. */
4409 if (bgp_debug_update(peer, p, NULL, 1)) {
4410 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4411 num_labels, addpath_id ? 1 : 0,
4412 addpath_id, evpn, pfx_buf,
4413 sizeof(pfx_buf));
4414 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4415 }
4416
4417 /* graceful restart STALE flag unset. */
4418 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4419 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4420 bgp_dest_set_defer_flag(dest, false);
4421 }
4422
4423 /* The attribute is changed. */
4424 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4425
4426 /* Update bgp route dampening information. */
4427 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4428 && peer->sort == BGP_PEER_EBGP) {
4429 /* This is implicit withdraw so we should update
4430 dampening
4431 information. */
4432 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4433 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4434 }
4435 #ifdef ENABLE_BGP_VNC
4436 if (safi == SAFI_MPLS_VPN) {
4437 struct bgp_dest *pdest = NULL;
4438 struct bgp_table *table = NULL;
4439
4440 pdest = bgp_node_get(bgp->rib[afi][safi],
4441 (struct prefix *)prd);
4442 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4443 table = bgp_dest_get_bgp_table_info(pdest);
4444
4445 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4446 bgp, prd, table, p, pi);
4447 }
4448 bgp_dest_unlock_node(pdest);
4449 }
4450 if ((afi == AFI_IP || afi == AFI_IP6)
4451 && (safi == SAFI_UNICAST)) {
4452 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4453 /*
4454 * Implicit withdraw case.
4455 */
4456 ++vnc_implicit_withdraw;
4457 vnc_import_bgp_del_route(bgp, p, pi);
4458 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4459 }
4460 }
4461 #endif
4462
4463 /* Special handling for EVPN update of an existing route. If the
4464 * extended community attribute has changed, we need to
4465 * un-import
4466 * the route using its existing extended community. It will be
4467 * subsequently processed for import with the new extended
4468 * community.
4469 */
4470 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4471 && !same_attr) {
4472 if ((pi->attr->flag
4473 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4474 && (attr_new->flag
4475 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4476 int cmp;
4477
4478 cmp = ecommunity_cmp(
4479 bgp_attr_get_ecommunity(pi->attr),
4480 bgp_attr_get_ecommunity(attr_new));
4481 if (!cmp) {
4482 if (bgp_debug_update(peer, p, NULL, 1))
4483 zlog_debug(
4484 "Change in EXT-COMM, existing %s new %s",
4485 ecommunity_str(
4486 bgp_attr_get_ecommunity(
4487 pi->attr)),
4488 ecommunity_str(
4489 bgp_attr_get_ecommunity(
4490 attr_new)));
4491 if (safi == SAFI_EVPN)
4492 bgp_evpn_unimport_route(
4493 bgp, afi, safi, p, pi);
4494 else /* SAFI_MPLS_VPN */
4495 vpn_leak_to_vrf_withdraw(pi);
4496 }
4497 }
4498 }
4499
4500 /* Update to new attribute. */
4501 bgp_attr_unintern(&pi->attr);
4502 pi->attr = attr_new;
4503
4504 /* Update MPLS label */
4505 if (has_valid_label) {
4506 extra = bgp_path_info_extra_get(pi);
4507 if (extra->label != label) {
4508 memcpy(&extra->label, label,
4509 num_labels * sizeof(mpls_label_t));
4510 extra->num_labels = num_labels;
4511 }
4512 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4513 bgp_set_valid_label(&extra->label[0]);
4514 }
4515
4516 /* Update SRv6 SID */
4517 if (attr->srv6_l3vpn) {
4518 extra = bgp_path_info_extra_get(pi);
4519 if (sid_diff(&extra->sid[0].sid,
4520 &attr->srv6_l3vpn->sid)) {
4521 sid_copy(&extra->sid[0].sid,
4522 &attr->srv6_l3vpn->sid);
4523 extra->num_sids = 1;
4524
4525 extra->sid[0].loc_block_len = 0;
4526 extra->sid[0].loc_node_len = 0;
4527 extra->sid[0].func_len = 0;
4528 extra->sid[0].arg_len = 0;
4529 extra->sid[0].transposition_len = 0;
4530 extra->sid[0].transposition_offset = 0;
4531
4532 if (attr->srv6_l3vpn->loc_block_len != 0) {
4533 extra->sid[0].loc_block_len =
4534 attr->srv6_l3vpn->loc_block_len;
4535 extra->sid[0].loc_node_len =
4536 attr->srv6_l3vpn->loc_node_len;
4537 extra->sid[0].func_len =
4538 attr->srv6_l3vpn->func_len;
4539 extra->sid[0].arg_len =
4540 attr->srv6_l3vpn->arg_len;
4541 extra->sid[0].transposition_len =
4542 attr->srv6_l3vpn
4543 ->transposition_len;
4544 extra->sid[0].transposition_offset =
4545 attr->srv6_l3vpn
4546 ->transposition_offset;
4547 }
4548 }
4549 } else if (attr->srv6_vpn) {
4550 extra = bgp_path_info_extra_get(pi);
4551 if (sid_diff(&extra->sid[0].sid,
4552 &attr->srv6_vpn->sid)) {
4553 sid_copy(&extra->sid[0].sid,
4554 &attr->srv6_vpn->sid);
4555 extra->num_sids = 1;
4556 }
4557 }
4558
4559 #ifdef ENABLE_BGP_VNC
4560 if ((afi == AFI_IP || afi == AFI_IP6)
4561 && (safi == SAFI_UNICAST)) {
4562 if (vnc_implicit_withdraw) {
4563 /*
4564 * Add back the route with its new attributes
4565 * (e.g., nexthop).
4566 * The route is still selected, until the route
4567 * selection
4568 * queued by bgp_process actually runs. We have
4569 * to make this
4570 * update to the VNC side immediately to avoid
4571 * racing against
4572 * configuration changes (e.g., route-map
4573 * changes) which
4574 * trigger re-importation of the entire RIB.
4575 */
4576 vnc_import_bgp_add_route(bgp, p, pi);
4577 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4578 }
4579 }
4580 #endif
4581
4582 /* Update bgp route dampening information. */
4583 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4584 && peer->sort == BGP_PEER_EBGP) {
4585 /* Now we do normal update dampening. */
4586 ret = bgp_damp_update(pi, dest, afi, safi);
4587 if (ret == BGP_DAMP_SUPPRESSED) {
4588 bgp_dest_unlock_node(dest);
4589 return;
4590 }
4591 }
4592
4593 /* Nexthop reachability check - for unicast and
4594 * labeled-unicast.. */
4595 if (((afi == AFI_IP || afi == AFI_IP6)
4596 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4597 || (safi == SAFI_EVPN &&
4598 bgp_evpn_is_prefix_nht_supported(p))) {
4599 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4600 && peer->ttl == BGP_DEFAULT_TTL
4601 && !CHECK_FLAG(peer->flags,
4602 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4603 && !CHECK_FLAG(bgp->flags,
4604 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4605 connected = 1;
4606 else
4607 connected = 0;
4608
4609 struct bgp *bgp_nexthop = bgp;
4610
4611 if (pi->extra && pi->extra->bgp_orig)
4612 bgp_nexthop = pi->extra->bgp_orig;
4613
4614 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4615
4616 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4617 safi, pi, NULL, connected,
4618 bgp_nht_param_prefix) ||
4619 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4620 bgp_path_info_set_flag(dest, pi,
4621 BGP_PATH_VALID);
4622 else {
4623 if (BGP_DEBUG(nht, NHT)) {
4624 zlog_debug("%s(%pI4): NH unresolved",
4625 __func__,
4626 (in_addr_t *)&attr_new->nexthop);
4627 }
4628 bgp_path_info_unset_flag(dest, pi,
4629 BGP_PATH_VALID);
4630 }
4631 } else {
4632 if (accept_own)
4633 bgp_path_info_set_flag(dest, pi,
4634 BGP_PATH_ACCEPT_OWN);
4635
4636 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4637 }
4638
4639 #ifdef ENABLE_BGP_VNC
4640 if (safi == SAFI_MPLS_VPN) {
4641 struct bgp_dest *pdest = NULL;
4642 struct bgp_table *table = NULL;
4643
4644 pdest = bgp_node_get(bgp->rib[afi][safi],
4645 (struct prefix *)prd);
4646 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4647 table = bgp_dest_get_bgp_table_info(pdest);
4648
4649 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4650 bgp, prd, table, p, pi);
4651 }
4652 bgp_dest_unlock_node(pdest);
4653 }
4654 #endif
4655
4656 /* If this is an EVPN route and some attribute has changed,
4657 * or we are explicitly told to perform a route import, process
4658 * route for import. If the extended community has changed, we
4659 * would
4660 * have done the un-import earlier and the import would result
4661 * in the
4662 * route getting injected into appropriate L2 VNIs. If it is
4663 * just
4664 * some other attribute change, the import will result in
4665 * updating
4666 * the attributes for the route in the VNI(s).
4667 */
4668 if (safi == SAFI_EVPN &&
4669 (!same_attr || force_evpn_import) &&
4670 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4671 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4672
4673 /* Process change. */
4674 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4675
4676 bgp_process(bgp, dest, afi, safi);
4677 bgp_dest_unlock_node(dest);
4678
4679 if (SAFI_UNICAST == safi
4680 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4681 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4682
4683 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4684 }
4685 if ((SAFI_MPLS_VPN == safi)
4686 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4687 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4688 }
4689
4690 #ifdef ENABLE_BGP_VNC
4691 if (SAFI_MPLS_VPN == safi) {
4692 mpls_label_t label_decoded = decode_label(label);
4693
4694 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4695 type, sub_type, &label_decoded);
4696 }
4697 if (SAFI_ENCAP == safi) {
4698 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4699 type, sub_type, NULL);
4700 }
4701 #endif
4702 if ((safi == SAFI_MPLS_VPN) &&
4703 !CHECK_FLAG(bgp->af_flags[afi][safi],
4704 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4705 !leak_success) {
4706 bgp_unlink_nexthop(pi);
4707 bgp_path_info_delete(dest, pi);
4708 }
4709 return;
4710 } // End of implicit withdraw
4711
4712 /* Received Logging. */
4713 if (bgp_debug_update(peer, p, NULL, 1)) {
4714 if (!peer->rcvd_attr_printed) {
4715 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4716 peer->rcvd_attr_str);
4717 peer->rcvd_attr_printed = 1;
4718 }
4719
4720 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4721 addpath_id ? 1 : 0, addpath_id, evpn,
4722 pfx_buf, sizeof(pfx_buf));
4723 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4724 }
4725
4726 /* Make new BGP info. */
4727 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4728
4729 /* Update MPLS label */
4730 if (has_valid_label) {
4731 extra = bgp_path_info_extra_get(new);
4732 if (extra->label != label) {
4733 memcpy(&extra->label, label,
4734 num_labels * sizeof(mpls_label_t));
4735 extra->num_labels = num_labels;
4736 }
4737 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4738 bgp_set_valid_label(&extra->label[0]);
4739 }
4740
4741 /* Update SRv6 SID */
4742 if (safi == SAFI_MPLS_VPN) {
4743 extra = bgp_path_info_extra_get(new);
4744 if (attr->srv6_l3vpn) {
4745 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4746 extra->num_sids = 1;
4747
4748 extra->sid[0].loc_block_len =
4749 attr->srv6_l3vpn->loc_block_len;
4750 extra->sid[0].loc_node_len =
4751 attr->srv6_l3vpn->loc_node_len;
4752 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4753 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4754 extra->sid[0].transposition_len =
4755 attr->srv6_l3vpn->transposition_len;
4756 extra->sid[0].transposition_offset =
4757 attr->srv6_l3vpn->transposition_offset;
4758 } else if (attr->srv6_vpn) {
4759 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4760 extra->num_sids = 1;
4761 }
4762 }
4763
4764 /* Nexthop reachability check. */
4765 if (((afi == AFI_IP || afi == AFI_IP6)
4766 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4767 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4768 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4769 && peer->ttl == BGP_DEFAULT_TTL
4770 && !CHECK_FLAG(peer->flags,
4771 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4772 && !CHECK_FLAG(bgp->flags,
4773 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4774 connected = 1;
4775 else
4776 connected = 0;
4777
4778 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4779
4780 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4781 connected, bgp_nht_param_prefix) ||
4782 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4783 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4784 else {
4785 if (BGP_DEBUG(nht, NHT))
4786 zlog_debug("%s(%pI4): NH unresolved", __func__,
4787 &attr_new->nexthop);
4788 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4789 }
4790 } else {
4791 if (accept_own)
4792 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4793
4794 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4795 }
4796
4797 /* If maximum prefix count is configured and current prefix
4798 * count exeed it.
4799 */
4800 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4801 reason = "maximum-prefix overflow";
4802 bgp_attr_flush(&new_attr);
4803 goto filtered;
4804 }
4805
4806 /* Addpath ID */
4807 new->addpath_rx_id = addpath_id;
4808
4809 /* Increment prefix */
4810 bgp_aggregate_increment(bgp, p, new, afi, safi);
4811
4812 /* Register new BGP information. */
4813 bgp_path_info_add(dest, new);
4814
4815 /* route_node_get lock */
4816 bgp_dest_unlock_node(dest);
4817
4818 #ifdef ENABLE_BGP_VNC
4819 if (safi == SAFI_MPLS_VPN) {
4820 struct bgp_dest *pdest = NULL;
4821 struct bgp_table *table = NULL;
4822
4823 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4824 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4825 table = bgp_dest_get_bgp_table_info(pdest);
4826
4827 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4828 bgp, prd, table, p, new);
4829 }
4830 bgp_dest_unlock_node(pdest);
4831 }
4832 #endif
4833
4834 /* If this is an EVPN route, process for import. */
4835 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4836 bgp_evpn_import_route(bgp, afi, safi, p, new);
4837
4838 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4839
4840 /* Process change. */
4841 bgp_process(bgp, dest, afi, safi);
4842
4843 if (SAFI_UNICAST == safi
4844 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4845 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4846 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4847 }
4848 if ((SAFI_MPLS_VPN == safi)
4849 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4850 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4851 }
4852 #ifdef ENABLE_BGP_VNC
4853 if (SAFI_MPLS_VPN == safi) {
4854 mpls_label_t label_decoded = decode_label(label);
4855
4856 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4857 sub_type, &label_decoded);
4858 }
4859 if (SAFI_ENCAP == safi) {
4860 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4861 sub_type, NULL);
4862 }
4863 #endif
4864 if ((safi == SAFI_MPLS_VPN) &&
4865 !CHECK_FLAG(bgp->af_flags[afi][safi],
4866 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4867 !leak_success) {
4868 bgp_unlink_nexthop(new);
4869 bgp_path_info_delete(dest, new);
4870 }
4871
4872 return;
4873
4874 /* This BGP update is filtered. Log the reason then update BGP
4875 entry. */
4876 filtered:
4877 if (new) {
4878 bgp_unlink_nexthop(new);
4879 bgp_path_info_delete(dest, new);
4880 bgp_path_info_extra_free(&new->extra);
4881 XFREE(MTYPE_BGP_ROUTE, new);
4882 }
4883
4884 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4885
4886 if (bgp_debug_update(peer, p, NULL, 1)) {
4887 if (!peer->rcvd_attr_printed) {
4888 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4889 peer->rcvd_attr_str);
4890 peer->rcvd_attr_printed = 1;
4891 }
4892
4893 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4894 addpath_id ? 1 : 0, addpath_id, evpn,
4895 pfx_buf, sizeof(pfx_buf));
4896 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4897 peer, pfx_buf, reason);
4898 }
4899
4900 if (pi) {
4901 /* If this is an EVPN route, un-import it as it is now filtered.
4902 */
4903 if (safi == SAFI_EVPN)
4904 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4905
4906 if (SAFI_UNICAST == safi
4907 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4908 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4909
4910 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4911 }
4912 if ((SAFI_MPLS_VPN == safi)
4913 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4914
4915 vpn_leak_to_vrf_withdraw(pi);
4916 }
4917
4918 bgp_rib_remove(dest, pi, peer, afi, safi);
4919 }
4920
4921 bgp_dest_unlock_node(dest);
4922
4923 #ifdef ENABLE_BGP_VNC
4924 /*
4925 * Filtered update is treated as an implicit withdrawal (see
4926 * bgp_rib_remove()
4927 * a few lines above)
4928 */
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 return;
4936 }
4937
4938 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4939 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4940 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4941 uint32_t num_labels, struct bgp_route_evpn *evpn)
4942 {
4943 struct bgp *bgp;
4944 char pfx_buf[BGP_PRD_PATH_STRLEN];
4945 struct bgp_dest *dest;
4946 struct bgp_path_info *pi;
4947
4948 #ifdef ENABLE_BGP_VNC
4949 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4950 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4951 0);
4952 }
4953 #endif
4954
4955 bgp = peer->bgp;
4956
4957 /* Lookup node. */
4958 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4959
4960 /* If peer is soft reconfiguration enabled. Record input packet for
4961 * further calculation.
4962 *
4963 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4964 * routes that are filtered. This tanks out Quagga RS pretty badly due
4965 * to
4966 * the iteration over all RS clients.
4967 * Since we need to remove the entry from adj_in anyway, do that first
4968 * and
4969 * if there was no entry, we don't need to do anything more.
4970 */
4971 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4972 && peer != bgp->peer_self)
4973 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4974 peer->stat_pfx_dup_withdraw++;
4975
4976 if (bgp_debug_update(peer, p, NULL, 1)) {
4977 bgp_debug_rdpfxpath2str(
4978 afi, safi, prd, p, label, num_labels,
4979 addpath_id ? 1 : 0, addpath_id, NULL,
4980 pfx_buf, sizeof(pfx_buf));
4981 zlog_debug(
4982 "%s withdrawing route %s not in adj-in",
4983 peer->host, pfx_buf);
4984 }
4985 bgp_dest_unlock_node(dest);
4986 return;
4987 }
4988
4989 /* Lookup withdrawn route. */
4990 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4991 if (pi->peer == peer && pi->type == type
4992 && pi->sub_type == sub_type
4993 && pi->addpath_rx_id == addpath_id)
4994 break;
4995
4996 /* Logging. */
4997 if (bgp_debug_update(peer, p, NULL, 1)) {
4998 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4999 addpath_id ? 1 : 0, addpath_id, NULL,
5000 pfx_buf, sizeof(pfx_buf));
5001 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
5002 pfx_buf);
5003 }
5004
5005 /* Withdraw specified route from routing table. */
5006 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
5007 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
5008 if (SAFI_UNICAST == safi
5009 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5010 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5011 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5012 }
5013 if ((SAFI_MPLS_VPN == safi)
5014 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5015
5016 vpn_leak_to_vrf_withdraw(pi);
5017 }
5018 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5019 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5020 addpath_id ? 1 : 0, addpath_id, NULL,
5021 pfx_buf, sizeof(pfx_buf));
5022 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5023 }
5024
5025 /* Unlock bgp_node_get() lock. */
5026 bgp_dest_unlock_node(dest);
5027
5028 return;
5029 }
5030
5031 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5032 int withdraw)
5033 {
5034 struct update_subgroup *subgrp;
5035 subgrp = peer_subgroup(peer, afi, safi);
5036 subgroup_default_originate(subgrp, withdraw);
5037 }
5038
5039
5040 /*
5041 * bgp_stop_announce_route_timer
5042 */
5043 void bgp_stop_announce_route_timer(struct peer_af *paf)
5044 {
5045 if (!paf->t_announce_route)
5046 return;
5047
5048 EVENT_OFF(paf->t_announce_route);
5049 }
5050
5051 /*
5052 * bgp_announce_route_timer_expired
5053 *
5054 * Callback that is invoked when the route announcement timer for a
5055 * peer_af expires.
5056 */
5057 static void bgp_announce_route_timer_expired(struct event *t)
5058 {
5059 struct peer_af *paf;
5060 struct peer *peer;
5061
5062 paf = EVENT_ARG(t);
5063 peer = paf->peer;
5064
5065 if (!peer_established(peer))
5066 return;
5067
5068 if (!peer->afc_nego[paf->afi][paf->safi])
5069 return;
5070
5071 peer_af_announce_route(paf, 1);
5072
5073 /* Notify BGP conditional advertisement scanner percess */
5074 peer->advmap_config_change[paf->afi][paf->safi] = true;
5075 }
5076
5077 /*
5078 * bgp_announce_route
5079 *
5080 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5081 *
5082 * if force is true we will force an update even if the update
5083 * limiting code is attempted to kick in.
5084 */
5085 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5086 {
5087 struct peer_af *paf;
5088 struct update_subgroup *subgrp;
5089
5090 paf = peer_af_find(peer, afi, safi);
5091 if (!paf)
5092 return;
5093 subgrp = PAF_SUBGRP(paf);
5094
5095 /*
5096 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5097 * or a refresh has already been triggered.
5098 */
5099 if (!subgrp || paf->t_announce_route)
5100 return;
5101
5102 if (force)
5103 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5104
5105 /*
5106 * Start a timer to stagger/delay the announce. This serves
5107 * two purposes - announcement can potentially be combined for
5108 * multiple peers and the announcement doesn't happen in the
5109 * vty context.
5110 */
5111 event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5112 (subgrp->peer_count == 1)
5113 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5114 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5115 &paf->t_announce_route);
5116 }
5117
5118 /*
5119 * Announce routes from all AF tables to a peer.
5120 *
5121 * This should ONLY be called when there is a need to refresh the
5122 * routes to the peer based on a policy change for this peer alone
5123 * or a route refresh request received from the peer.
5124 * The operation will result in splitting the peer from its existing
5125 * subgroups and putting it in new subgroups.
5126 */
5127 void bgp_announce_route_all(struct peer *peer)
5128 {
5129 afi_t afi;
5130 safi_t safi;
5131
5132 FOREACH_AFI_SAFI (afi, safi)
5133 bgp_announce_route(peer, afi, safi, false);
5134 }
5135
5136 /* Flag or unflag bgp_dest to determine whether it should be treated by
5137 * bgp_soft_reconfig_table_task.
5138 * Flag if flag is true. Unflag if flag is false.
5139 */
5140 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5141 {
5142 struct bgp_dest *dest;
5143 struct bgp_adj_in *ain;
5144
5145 if (!table)
5146 return;
5147
5148 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5149 for (ain = dest->adj_in; ain; ain = ain->next) {
5150 if (ain->peer != NULL)
5151 break;
5152 }
5153 if (flag && ain != NULL && ain->peer != NULL)
5154 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5155 else
5156 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5157 }
5158 }
5159
5160 static void bgp_soft_reconfig_table_update(struct peer *peer,
5161 struct bgp_dest *dest,
5162 struct bgp_adj_in *ain, afi_t afi,
5163 safi_t safi, struct prefix_rd *prd)
5164 {
5165 struct bgp_path_info *pi;
5166 uint32_t num_labels = 0;
5167 mpls_label_t *label_pnt = NULL;
5168 struct bgp_route_evpn evpn;
5169
5170 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5171 if (pi->peer == peer)
5172 break;
5173
5174 if (pi && pi->extra)
5175 num_labels = pi->extra->num_labels;
5176 if (num_labels)
5177 label_pnt = &pi->extra->label[0];
5178 if (pi)
5179 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5180 sizeof(evpn));
5181 else
5182 memset(&evpn, 0, sizeof(evpn));
5183
5184 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5185 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5186 label_pnt, num_labels, 1, &evpn);
5187 }
5188
5189 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5190 struct bgp_table *table,
5191 struct prefix_rd *prd)
5192 {
5193 struct bgp_dest *dest;
5194 struct bgp_adj_in *ain;
5195
5196 if (!table)
5197 table = peer->bgp->rib[afi][safi];
5198
5199 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5200 for (ain = dest->adj_in; ain; ain = ain->next) {
5201 if (ain->peer != peer)
5202 continue;
5203
5204 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5205 safi, prd);
5206 }
5207 }
5208
5209 /* Do soft reconfig table per bgp table.
5210 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5211 * when BGP_NODE_SOFT_RECONFIG is set,
5212 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5213 * Schedule a new thread to continue the job.
5214 * Without splitting the full job into several part,
5215 * vtysh waits for the job to finish before responding to a BGP command
5216 */
5217 static void bgp_soft_reconfig_table_task(struct event *thread)
5218 {
5219 uint32_t iter, max_iter;
5220 struct bgp_dest *dest;
5221 struct bgp_adj_in *ain;
5222 struct peer *peer;
5223 struct bgp_table *table;
5224 struct prefix_rd *prd;
5225 struct listnode *node, *nnode;
5226
5227 table = EVENT_ARG(thread);
5228 prd = NULL;
5229
5230 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5231 if (table->soft_reconfig_init) {
5232 /* first call of the function with a new srta structure.
5233 * Don't do any treatment this time on nodes
5234 * in order vtysh to respond quickly
5235 */
5236 max_iter = 0;
5237 }
5238
5239 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5240 dest = bgp_route_next(dest)) {
5241 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5242 continue;
5243
5244 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5245
5246 for (ain = dest->adj_in; ain; ain = ain->next) {
5247 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5248 nnode, peer)) {
5249 if (ain->peer != peer)
5250 continue;
5251
5252 bgp_soft_reconfig_table_update(
5253 peer, dest, ain, table->afi,
5254 table->safi, prd);
5255 iter++;
5256 }
5257 }
5258 }
5259
5260 /* we're either starting the initial iteration,
5261 * or we're going to continue an ongoing iteration
5262 */
5263 if (dest || table->soft_reconfig_init) {
5264 table->soft_reconfig_init = false;
5265 event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
5266 0, &table->soft_reconfig_thread);
5267 return;
5268 }
5269 /* we're done, clean up the background iteration context info and
5270 schedule route annoucement
5271 */
5272 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5273 listnode_delete(table->soft_reconfig_peers, peer);
5274 bgp_announce_route(peer, table->afi, table->safi, false);
5275 }
5276
5277 list_delete(&table->soft_reconfig_peers);
5278 }
5279
5280
5281 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5282 * and peer.
5283 * - bgp cannot be NULL
5284 * - if table and peer are NULL, cancel all threads within the bgp instance
5285 * - if table is NULL and peer is not,
5286 * remove peer in all threads within the bgp instance
5287 * - if peer is NULL, cancel all threads matching table within the bgp instance
5288 */
5289 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5290 const struct bgp_table *table,
5291 const struct peer *peer)
5292 {
5293 struct peer *npeer;
5294 struct listnode *node, *nnode;
5295 int afi, safi;
5296 struct bgp_table *ntable;
5297
5298 if (!bgp)
5299 return;
5300
5301 FOREACH_AFI_SAFI (afi, safi) {
5302 ntable = bgp->rib[afi][safi];
5303 if (!ntable)
5304 continue;
5305 if (table && table != ntable)
5306 continue;
5307
5308 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5309 npeer)) {
5310 if (peer && peer != npeer)
5311 continue;
5312 listnode_delete(ntable->soft_reconfig_peers, npeer);
5313 }
5314
5315 if (!ntable->soft_reconfig_peers
5316 || !list_isempty(ntable->soft_reconfig_peers))
5317 continue;
5318
5319 list_delete(&ntable->soft_reconfig_peers);
5320 bgp_soft_reconfig_table_flag(ntable, false);
5321 EVENT_OFF(ntable->soft_reconfig_thread);
5322 }
5323 }
5324
5325 /*
5326 * Returns false if the peer is not configured for soft reconfig in
5327 */
5328 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5329 {
5330 struct bgp_dest *dest;
5331 struct bgp_table *table;
5332 struct listnode *node, *nnode;
5333 struct peer *npeer;
5334 struct peer_af *paf;
5335
5336 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5337 return false;
5338
5339 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5340 && (safi != SAFI_EVPN)) {
5341 table = peer->bgp->rib[afi][safi];
5342 if (!table)
5343 return true;
5344
5345 table->soft_reconfig_init = true;
5346
5347 if (!table->soft_reconfig_peers)
5348 table->soft_reconfig_peers = list_new();
5349 npeer = NULL;
5350 /* add peer to the table soft_reconfig_peers if not already
5351 * there
5352 */
5353 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5354 npeer)) {
5355 if (peer == npeer)
5356 break;
5357 }
5358 if (peer != npeer)
5359 listnode_add(table->soft_reconfig_peers, peer);
5360
5361 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5362 * on table would start back at the beginning.
5363 */
5364 bgp_soft_reconfig_table_flag(table, true);
5365
5366 if (!table->soft_reconfig_thread)
5367 event_add_event(bm->master,
5368 bgp_soft_reconfig_table_task, table, 0,
5369 &table->soft_reconfig_thread);
5370 /* Cancel bgp_announce_route_timer_expired threads.
5371 * bgp_announce_route_timer_expired threads have been scheduled
5372 * to announce routes as soon as the soft_reconfigure process
5373 * finishes.
5374 * In this case, soft_reconfigure is also scheduled by using
5375 * a thread but is planned after the
5376 * bgp_announce_route_timer_expired threads. It means that,
5377 * without cancelling the threads, the route announcement task
5378 * would run before the soft reconfiguration one. That would
5379 * useless and would block vtysh during several seconds. Route
5380 * announcements are rescheduled as soon as the soft_reconfigure
5381 * process finishes.
5382 */
5383 paf = peer_af_find(peer, afi, safi);
5384 if (paf)
5385 bgp_stop_announce_route_timer(paf);
5386 } else
5387 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5388 dest = bgp_route_next(dest)) {
5389 table = bgp_dest_get_bgp_table_info(dest);
5390
5391 if (table == NULL)
5392 continue;
5393
5394 const struct prefix *p = bgp_dest_get_prefix(dest);
5395 struct prefix_rd prd;
5396
5397 prd.family = AF_UNSPEC;
5398 prd.prefixlen = 64;
5399 memcpy(&prd.val, p->u.val, 8);
5400
5401 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5402 }
5403
5404 return true;
5405 }
5406
5407
5408 struct bgp_clear_node_queue {
5409 struct bgp_dest *dest;
5410 };
5411
5412 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5413 {
5414 struct bgp_clear_node_queue *cnq = data;
5415 struct bgp_dest *dest = cnq->dest;
5416 struct peer *peer = wq->spec.data;
5417 struct bgp_path_info *pi;
5418 struct bgp *bgp;
5419 afi_t afi = bgp_dest_table(dest)->afi;
5420 safi_t safi = bgp_dest_table(dest)->safi;
5421
5422 assert(dest && peer);
5423 bgp = peer->bgp;
5424
5425 /* It is possible that we have multiple paths for a prefix from a peer
5426 * if that peer is using AddPath.
5427 */
5428 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5429 if (pi->peer != peer)
5430 continue;
5431
5432 /* graceful restart STALE flag set. */
5433 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5434 && peer->nsf[afi][safi])
5435 || CHECK_FLAG(peer->af_sflags[afi][safi],
5436 PEER_STATUS_ENHANCED_REFRESH))
5437 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5438 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5439 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5440 else {
5441 /* If this is an EVPN route, process for
5442 * un-import. */
5443 if (safi == SAFI_EVPN)
5444 bgp_evpn_unimport_route(
5445 bgp, afi, safi,
5446 bgp_dest_get_prefix(dest), pi);
5447 /* Handle withdraw for VRF route-leaking and L3VPN */
5448 if (SAFI_UNICAST == safi
5449 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5450 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5451 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5452 bgp, pi);
5453 }
5454 if (SAFI_MPLS_VPN == safi &&
5455 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5456 vpn_leak_to_vrf_withdraw(pi);
5457 }
5458
5459 bgp_rib_remove(dest, pi, peer, afi, safi);
5460 }
5461 }
5462 return WQ_SUCCESS;
5463 }
5464
5465 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5466 {
5467 struct bgp_clear_node_queue *cnq = data;
5468 struct bgp_dest *dest = cnq->dest;
5469 struct bgp_table *table = bgp_dest_table(dest);
5470
5471 bgp_dest_unlock_node(dest);
5472 bgp_table_unlock(table);
5473 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5474 }
5475
5476 static void bgp_clear_node_complete(struct work_queue *wq)
5477 {
5478 struct peer *peer = wq->spec.data;
5479
5480 /* Tickle FSM to start moving again */
5481 BGP_EVENT_ADD(peer, Clearing_Completed);
5482
5483 peer_unlock(peer); /* bgp_clear_route */
5484 }
5485
5486 static void bgp_clear_node_queue_init(struct peer *peer)
5487 {
5488 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5489
5490 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5491 #undef CLEAR_QUEUE_NAME_LEN
5492
5493 peer->clear_node_queue = work_queue_new(bm->master, wname);
5494 peer->clear_node_queue->spec.hold = 10;
5495 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5496 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5497 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5498 peer->clear_node_queue->spec.max_retries = 0;
5499
5500 /* we only 'lock' this peer reference when the queue is actually active
5501 */
5502 peer->clear_node_queue->spec.data = peer;
5503 }
5504
5505 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5506 struct bgp_table *table)
5507 {
5508 struct bgp_dest *dest;
5509 int force = peer->bgp->process_queue ? 0 : 1;
5510
5511 if (!table)
5512 table = peer->bgp->rib[afi][safi];
5513
5514 /* If still no table => afi/safi isn't configured at all or smth. */
5515 if (!table)
5516 return;
5517
5518 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5519 struct bgp_path_info *pi, *next;
5520 struct bgp_adj_in *ain;
5521 struct bgp_adj_in *ain_next;
5522
5523 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5524 * queued for every clearing peer, regardless of whether it is
5525 * relevant to the peer at hand.
5526 *
5527 * Overview: There are 3 different indices which need to be
5528 * scrubbed, potentially, when a peer is removed:
5529 *
5530 * 1 peer's routes visible via the RIB (ie accepted routes)
5531 * 2 peer's routes visible by the (optional) peer's adj-in index
5532 * 3 other routes visible by the peer's adj-out index
5533 *
5534 * 3 there is no hurry in scrubbing, once the struct peer is
5535 * removed from bgp->peer, we could just GC such deleted peer's
5536 * adj-outs at our leisure.
5537 *
5538 * 1 and 2 must be 'scrubbed' in some way, at least made
5539 * invisible via RIB index before peer session is allowed to be
5540 * brought back up. So one needs to know when such a 'search' is
5541 * complete.
5542 *
5543 * Ideally:
5544 *
5545 * - there'd be a single global queue or a single RIB walker
5546 * - rather than tracking which route_nodes still need to be
5547 * examined on a peer basis, we'd track which peers still
5548 * aren't cleared
5549 *
5550 * Given that our per-peer prefix-counts now should be reliable,
5551 * this may actually be achievable. It doesn't seem to be a huge
5552 * problem at this time,
5553 *
5554 * It is possible that we have multiple paths for a prefix from
5555 * a peer
5556 * if that peer is using AddPath.
5557 */
5558 ain = dest->adj_in;
5559 while (ain) {
5560 ain_next = ain->next;
5561
5562 if (ain->peer == peer)
5563 bgp_adj_in_remove(dest, ain);
5564
5565 ain = ain_next;
5566 }
5567
5568 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5569 next = pi->next;
5570 if (pi->peer != peer)
5571 continue;
5572
5573 if (force)
5574 bgp_path_info_reap(dest, pi);
5575 else {
5576 struct bgp_clear_node_queue *cnq;
5577
5578 /* both unlocked in bgp_clear_node_queue_del */
5579 bgp_table_lock(bgp_dest_table(dest));
5580 bgp_dest_lock_node(dest);
5581 cnq = XCALLOC(
5582 MTYPE_BGP_CLEAR_NODE_QUEUE,
5583 sizeof(struct bgp_clear_node_queue));
5584 cnq->dest = dest;
5585 work_queue_add(peer->clear_node_queue, cnq);
5586 break;
5587 }
5588 }
5589 }
5590 return;
5591 }
5592
5593 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5594 {
5595 struct bgp_dest *dest;
5596 struct bgp_table *table;
5597
5598 if (peer->clear_node_queue == NULL)
5599 bgp_clear_node_queue_init(peer);
5600
5601 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5602 * Idle until it receives a Clearing_Completed event. This protects
5603 * against peers which flap faster than we can we clear, which could
5604 * lead to:
5605 *
5606 * a) race with routes from the new session being installed before
5607 * clear_route_node visits the node (to delete the route of that
5608 * peer)
5609 * b) resource exhaustion, clear_route_node likely leads to an entry
5610 * on the process_main queue. Fast-flapping could cause that queue
5611 * to grow and grow.
5612 */
5613
5614 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5615 * the unlock will happen upon work-queue completion; other wise, the
5616 * unlock happens at the end of this function.
5617 */
5618 if (!peer->clear_node_queue->thread)
5619 peer_lock(peer);
5620
5621 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5622 bgp_clear_route_table(peer, afi, safi, NULL);
5623 else
5624 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5625 dest = bgp_route_next(dest)) {
5626 table = bgp_dest_get_bgp_table_info(dest);
5627 if (!table)
5628 continue;
5629
5630 bgp_clear_route_table(peer, afi, safi, table);
5631 }
5632
5633 /* unlock if no nodes got added to the clear-node-queue. */
5634 if (!peer->clear_node_queue->thread)
5635 peer_unlock(peer);
5636 }
5637
5638 void bgp_clear_route_all(struct peer *peer)
5639 {
5640 afi_t afi;
5641 safi_t safi;
5642
5643 FOREACH_AFI_SAFI (afi, safi)
5644 bgp_clear_route(peer, afi, safi);
5645
5646 #ifdef ENABLE_BGP_VNC
5647 rfapiProcessPeerDown(peer);
5648 #endif
5649 }
5650
5651 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5652 {
5653 struct bgp_table *table;
5654 struct bgp_dest *dest;
5655 struct bgp_adj_in *ain;
5656 struct bgp_adj_in *ain_next;
5657
5658 table = peer->bgp->rib[afi][safi];
5659
5660 /* It is possible that we have multiple paths for a prefix from a peer
5661 * if that peer is using AddPath.
5662 */
5663 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5664 ain = dest->adj_in;
5665
5666 while (ain) {
5667 ain_next = ain->next;
5668
5669 if (ain->peer == peer)
5670 bgp_adj_in_remove(dest, ain);
5671
5672 ain = ain_next;
5673 }
5674 }
5675 }
5676
5677 /* If any of the routes from the peer have been marked with the NO_LLGR
5678 * community, either as sent by the peer, or as the result of a configured
5679 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5680 * operation of [RFC4271].
5681 */
5682 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5683 {
5684 struct bgp_dest *dest;
5685 struct bgp_path_info *pi;
5686 struct bgp_table *table;
5687
5688 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5689 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5690 dest = bgp_route_next(dest)) {
5691 struct bgp_dest *rm;
5692
5693 /* look for neighbor in tables */
5694 table = bgp_dest_get_bgp_table_info(dest);
5695 if (!table)
5696 continue;
5697
5698 for (rm = bgp_table_top(table); rm;
5699 rm = bgp_route_next(rm))
5700 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5701 pi = pi->next) {
5702 if (pi->peer != peer)
5703 continue;
5704 if (CHECK_FLAG(
5705 peer->af_sflags[afi][safi],
5706 PEER_STATUS_LLGR_WAIT) &&
5707 bgp_attr_get_community(pi->attr) &&
5708 !community_include(
5709 bgp_attr_get_community(
5710 pi->attr),
5711 COMMUNITY_NO_LLGR))
5712 continue;
5713 if (!CHECK_FLAG(pi->flags,
5714 BGP_PATH_STALE))
5715 continue;
5716
5717 /*
5718 * If this is VRF leaked route
5719 * process for withdraw.
5720 */
5721 if (pi->sub_type ==
5722 BGP_ROUTE_IMPORTED &&
5723 peer->bgp->inst_type ==
5724 BGP_INSTANCE_TYPE_DEFAULT)
5725 vpn_leak_to_vrf_withdraw(pi);
5726
5727 bgp_rib_remove(rm, pi, peer, afi, safi);
5728 break;
5729 }
5730 }
5731 } else {
5732 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5733 dest = bgp_route_next(dest))
5734 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5735 pi = pi->next) {
5736 if (pi->peer != peer)
5737 continue;
5738 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5739 PEER_STATUS_LLGR_WAIT) &&
5740 bgp_attr_get_community(pi->attr) &&
5741 !community_include(
5742 bgp_attr_get_community(pi->attr),
5743 COMMUNITY_NO_LLGR))
5744 continue;
5745 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5746 continue;
5747 if (safi == SAFI_UNICAST &&
5748 (peer->bgp->inst_type ==
5749 BGP_INSTANCE_TYPE_VRF ||
5750 peer->bgp->inst_type ==
5751 BGP_INSTANCE_TYPE_DEFAULT))
5752 vpn_leak_from_vrf_withdraw(
5753 bgp_get_default(), peer->bgp,
5754 pi);
5755
5756 bgp_rib_remove(dest, pi, peer, afi, safi);
5757 break;
5758 }
5759 }
5760 }
5761
5762 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5763 {
5764 struct bgp_dest *dest, *ndest;
5765 struct bgp_path_info *pi;
5766 struct bgp_table *table;
5767
5768 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5769 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5770 dest = bgp_route_next(dest)) {
5771 table = bgp_dest_get_bgp_table_info(dest);
5772 if (!table)
5773 continue;
5774
5775 for (ndest = bgp_table_top(table); ndest;
5776 ndest = bgp_route_next(ndest)) {
5777 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5778 pi = pi->next) {
5779 if (pi->peer != peer)
5780 continue;
5781
5782 if ((CHECK_FLAG(
5783 peer->af_sflags[afi][safi],
5784 PEER_STATUS_ENHANCED_REFRESH))
5785 && !CHECK_FLAG(pi->flags,
5786 BGP_PATH_STALE)
5787 && !CHECK_FLAG(
5788 pi->flags,
5789 BGP_PATH_UNUSEABLE)) {
5790 if (bgp_debug_neighbor_events(
5791 peer))
5792 zlog_debug(
5793 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5794 peer,
5795 afi2str(afi),
5796 safi2str(safi),
5797 bgp_dest_get_prefix(
5798 ndest));
5799
5800 bgp_path_info_set_flag(
5801 ndest, pi,
5802 BGP_PATH_STALE);
5803 }
5804 }
5805 }
5806 }
5807 } else {
5808 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5809 dest = bgp_route_next(dest)) {
5810 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5811 pi = pi->next) {
5812 if (pi->peer != peer)
5813 continue;
5814
5815 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5816 PEER_STATUS_ENHANCED_REFRESH))
5817 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5818 && !CHECK_FLAG(pi->flags,
5819 BGP_PATH_UNUSEABLE)) {
5820 if (bgp_debug_neighbor_events(peer))
5821 zlog_debug(
5822 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5823 peer, afi2str(afi),
5824 safi2str(safi),
5825 bgp_dest_get_prefix(
5826 dest));
5827
5828 bgp_path_info_set_flag(dest, pi,
5829 BGP_PATH_STALE);
5830 }
5831 }
5832 }
5833 }
5834 }
5835
5836 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5837 {
5838 if (peer->sort == BGP_PEER_IBGP)
5839 return true;
5840
5841 if (peer->sort == BGP_PEER_EBGP
5842 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5843 || FILTER_LIST_OUT_NAME(filter)
5844 || DISTRIBUTE_OUT_NAME(filter)))
5845 return true;
5846 return false;
5847 }
5848
5849 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5850 {
5851 if (peer->sort == BGP_PEER_IBGP)
5852 return true;
5853
5854 if (peer->sort == BGP_PEER_EBGP
5855 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5856 || FILTER_LIST_IN_NAME(filter)
5857 || DISTRIBUTE_IN_NAME(filter)))
5858 return true;
5859 return false;
5860 }
5861
5862 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5863 safi_t safi)
5864 {
5865 struct bgp_dest *dest;
5866 struct bgp_path_info *pi;
5867 struct bgp_path_info *next;
5868
5869 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5870 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5871 const struct prefix *p = bgp_dest_get_prefix(dest);
5872
5873 next = pi->next;
5874
5875 /* Unimport EVPN routes from VRFs */
5876 if (safi == SAFI_EVPN)
5877 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5878 SAFI_EVPN, p, pi);
5879
5880 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5881 && pi->type == ZEBRA_ROUTE_BGP
5882 && (pi->sub_type == BGP_ROUTE_NORMAL
5883 || pi->sub_type == BGP_ROUTE_AGGREGATE
5884 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5885
5886 if (bgp_fibupd_safi(safi))
5887 bgp_zebra_withdraw(p, pi, bgp, safi);
5888 }
5889
5890 bgp_path_info_reap(dest, pi);
5891 }
5892 }
5893
5894 /* Delete all kernel routes. */
5895 void bgp_cleanup_routes(struct bgp *bgp)
5896 {
5897 afi_t afi;
5898 struct bgp_dest *dest;
5899 struct bgp_table *table;
5900
5901 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5902 if (afi == AFI_L2VPN)
5903 continue;
5904 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5905 SAFI_UNICAST);
5906 /*
5907 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5908 */
5909 if (afi != AFI_L2VPN) {
5910 safi_t safi;
5911 safi = SAFI_MPLS_VPN;
5912 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5913 dest = bgp_route_next(dest)) {
5914 table = bgp_dest_get_bgp_table_info(dest);
5915 if (table != NULL) {
5916 bgp_cleanup_table(bgp, table, safi);
5917 bgp_table_finish(&table);
5918 bgp_dest_set_bgp_table_info(dest, NULL);
5919 bgp_dest_unlock_node(dest);
5920 }
5921 }
5922 safi = SAFI_ENCAP;
5923 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5924 dest = bgp_route_next(dest)) {
5925 table = bgp_dest_get_bgp_table_info(dest);
5926 if (table != NULL) {
5927 bgp_cleanup_table(bgp, table, safi);
5928 bgp_table_finish(&table);
5929 bgp_dest_set_bgp_table_info(dest, NULL);
5930 bgp_dest_unlock_node(dest);
5931 }
5932 }
5933 }
5934 }
5935 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5936 dest = bgp_route_next(dest)) {
5937 table = bgp_dest_get_bgp_table_info(dest);
5938 if (table != NULL) {
5939 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5940 bgp_table_finish(&table);
5941 bgp_dest_set_bgp_table_info(dest, NULL);
5942 bgp_dest_unlock_node(dest);
5943 }
5944 }
5945 }
5946
5947 void bgp_reset(void)
5948 {
5949 vty_reset();
5950 bgp_zclient_reset();
5951 access_list_reset();
5952 prefix_list_reset();
5953 }
5954
5955 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5956 {
5957 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5958 && CHECK_FLAG(peer->af_cap[afi][safi],
5959 PEER_CAP_ADDPATH_AF_TX_RCV));
5960 }
5961
5962 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5963 value. */
5964 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5965 struct bgp_nlri *packet)
5966 {
5967 uint8_t *pnt;
5968 uint8_t *lim;
5969 struct prefix p;
5970 int psize;
5971 afi_t afi;
5972 safi_t safi;
5973 bool addpath_capable;
5974 uint32_t addpath_id;
5975
5976 pnt = packet->nlri;
5977 lim = pnt + packet->length;
5978 afi = packet->afi;
5979 safi = packet->safi;
5980 addpath_id = 0;
5981 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5982
5983 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5984 syntactic validity. If the field is syntactically incorrect,
5985 then the Error Subcode is set to Invalid Network Field. */
5986 for (; pnt < lim; pnt += psize) {
5987 /* Clear prefix structure. */
5988 memset(&p, 0, sizeof(p));
5989
5990 if (addpath_capable) {
5991
5992 /* When packet overflow occurs return immediately. */
5993 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5994 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5995
5996 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5997 addpath_id = ntohl(addpath_id);
5998 pnt += BGP_ADDPATH_ID_LEN;
5999 }
6000
6001 /* Fetch prefix length. */
6002 p.prefixlen = *pnt++;
6003 /* afi/safi validity already verified by caller,
6004 * bgp_update_receive */
6005 p.family = afi2family(afi);
6006
6007 /* Prefix length check. */
6008 if (p.prefixlen > prefix_blen(&p) * 8) {
6009 flog_err(
6010 EC_BGP_UPDATE_RCV,
6011 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
6012 peer->host, p.prefixlen, packet->afi);
6013 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
6014 }
6015
6016 /* Packet size overflow check. */
6017 psize = PSIZE(p.prefixlen);
6018
6019 /* When packet overflow occur return immediately. */
6020 if (pnt + psize > lim) {
6021 flog_err(
6022 EC_BGP_UPDATE_RCV,
6023 "%s [Error] Update packet error (prefix length %d overflows packet)",
6024 peer->host, p.prefixlen);
6025 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6026 }
6027
6028 /* Defensive coding, double-check the psize fits in a struct
6029 * prefix for the v4 and v6 afi's and unicast/multicast */
6030 if (psize > (ssize_t)sizeof(p.u.val)) {
6031 flog_err(
6032 EC_BGP_UPDATE_RCV,
6033 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6034 peer->host, p.prefixlen, sizeof(p.u.val));
6035 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6036 }
6037
6038 /* Fetch prefix from NLRI packet. */
6039 memcpy(p.u.val, pnt, psize);
6040
6041 /* Check address. */
6042 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6043 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6044 /* From RFC4271 Section 6.3:
6045 *
6046 * If a prefix in the NLRI field is semantically
6047 * incorrect
6048 * (e.g., an unexpected multicast IP address),
6049 * an error SHOULD
6050 * be logged locally, and the prefix SHOULD be
6051 * ignored.
6052 */
6053 flog_err(
6054 EC_BGP_UPDATE_RCV,
6055 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6056 peer->host, &p.u.prefix4);
6057 continue;
6058 }
6059 }
6060
6061 /* Check address. */
6062 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6063 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6064 flog_err(
6065 EC_BGP_UPDATE_RCV,
6066 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6067 peer->host, &p.u.prefix6);
6068
6069 continue;
6070 }
6071 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6072 flog_err(
6073 EC_BGP_UPDATE_RCV,
6074 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6075 peer->host, &p.u.prefix6);
6076
6077 continue;
6078 }
6079 }
6080
6081 /* Normal process. */
6082 if (attr)
6083 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6084 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6085 NULL, 0, 0, NULL);
6086 else
6087 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6088 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6089 NULL, 0, NULL);
6090
6091 /* Do not send BGP notification twice when maximum-prefix count
6092 * overflow. */
6093 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6094 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6095 }
6096
6097 /* Packet length consistency check. */
6098 if (pnt != lim) {
6099 flog_err(
6100 EC_BGP_UPDATE_RCV,
6101 "%s [Error] Update packet error (prefix length mismatch with total length)",
6102 peer->host);
6103 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6104 }
6105
6106 return BGP_NLRI_PARSE_OK;
6107 }
6108
6109 static struct bgp_static *bgp_static_new(void)
6110 {
6111 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6112 }
6113
6114 static void bgp_static_free(struct bgp_static *bgp_static)
6115 {
6116 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6117 route_map_counter_decrement(bgp_static->rmap.map);
6118
6119 if (bgp_static->prd_pretty)
6120 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6121 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6122 XFREE(MTYPE_BGP_STATIC, bgp_static);
6123 }
6124
6125 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6126 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6127 {
6128 struct bgp_dest *dest;
6129 struct bgp_path_info *pi;
6130 struct bgp_path_info *new;
6131 struct bgp_path_info rmap_path;
6132 struct attr attr;
6133 struct attr *attr_new;
6134 route_map_result_t ret;
6135 #ifdef ENABLE_BGP_VNC
6136 int vnc_implicit_withdraw = 0;
6137 #endif
6138
6139 assert(bgp_static);
6140
6141 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6142
6143 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6144
6145 attr.nexthop = bgp_static->igpnexthop;
6146 attr.med = bgp_static->igpmetric;
6147 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6148
6149 if (afi == AFI_IP)
6150 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6151
6152 if (bgp_static->igpmetric)
6153 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6154
6155 if (bgp_static->atomic)
6156 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6157
6158 /* Store label index, if required. */
6159 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6160 attr.label_index = bgp_static->label_index;
6161 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6162 }
6163
6164 /* Apply route-map. */
6165 if (bgp_static->rmap.name) {
6166 struct attr attr_tmp = attr;
6167
6168 memset(&rmap_path, 0, sizeof(rmap_path));
6169 rmap_path.peer = bgp->peer_self;
6170 rmap_path.attr = &attr_tmp;
6171
6172 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6173
6174 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6175
6176 bgp->peer_self->rmap_type = 0;
6177
6178 if (ret == RMAP_DENYMATCH) {
6179 /* Free uninterned attribute. */
6180 bgp_attr_flush(&attr_tmp);
6181
6182 /* Unintern original. */
6183 aspath_unintern(&attr.aspath);
6184 bgp_static_withdraw(bgp, p, afi, safi);
6185 bgp_dest_unlock_node(dest);
6186 return;
6187 }
6188
6189 if (bgp_in_graceful_shutdown(bgp))
6190 bgp_attr_add_gshut_community(&attr_tmp);
6191
6192 attr_new = bgp_attr_intern(&attr_tmp);
6193 } else {
6194
6195 if (bgp_in_graceful_shutdown(bgp))
6196 bgp_attr_add_gshut_community(&attr);
6197
6198 attr_new = bgp_attr_intern(&attr);
6199 }
6200
6201 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6202 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6203 && pi->sub_type == BGP_ROUTE_STATIC)
6204 break;
6205
6206 if (pi) {
6207 if (attrhash_cmp(pi->attr, attr_new)
6208 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6209 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6210 bgp_dest_unlock_node(dest);
6211 bgp_attr_unintern(&attr_new);
6212 aspath_unintern(&attr.aspath);
6213 return;
6214 } else {
6215 /* The attribute is changed. */
6216 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6217
6218 /* Rewrite BGP route information. */
6219 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6220 bgp_path_info_restore(dest, pi);
6221 else
6222 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6223 #ifdef ENABLE_BGP_VNC
6224 if ((afi == AFI_IP || afi == AFI_IP6)
6225 && (safi == SAFI_UNICAST)) {
6226 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6227 /*
6228 * Implicit withdraw case.
6229 * We have to do this before pi is
6230 * changed
6231 */
6232 ++vnc_implicit_withdraw;
6233 vnc_import_bgp_del_route(bgp, p, pi);
6234 vnc_import_bgp_exterior_del_route(
6235 bgp, p, pi);
6236 }
6237 }
6238 #endif
6239 bgp_attr_unintern(&pi->attr);
6240 pi->attr = attr_new;
6241 pi->uptime = monotime(NULL);
6242 #ifdef ENABLE_BGP_VNC
6243 if ((afi == AFI_IP || afi == AFI_IP6)
6244 && (safi == SAFI_UNICAST)) {
6245 if (vnc_implicit_withdraw) {
6246 vnc_import_bgp_add_route(bgp, p, pi);
6247 vnc_import_bgp_exterior_add_route(
6248 bgp, p, pi);
6249 }
6250 }
6251 #endif
6252
6253 /* Nexthop reachability check. */
6254 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6255 && (safi == SAFI_UNICAST
6256 || safi == SAFI_LABELED_UNICAST)) {
6257
6258 struct bgp *bgp_nexthop = bgp;
6259
6260 if (pi->extra && pi->extra->bgp_orig)
6261 bgp_nexthop = pi->extra->bgp_orig;
6262
6263 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6264 afi, safi, pi, NULL,
6265 0, p))
6266 bgp_path_info_set_flag(dest, pi,
6267 BGP_PATH_VALID);
6268 else {
6269 if (BGP_DEBUG(nht, NHT)) {
6270 char buf1[INET6_ADDRSTRLEN];
6271 inet_ntop(p->family,
6272 &p->u.prefix, buf1,
6273 sizeof(buf1));
6274 zlog_debug(
6275 "%s(%s): Route not in table, not advertising",
6276 __func__, buf1);
6277 }
6278 bgp_path_info_unset_flag(
6279 dest, pi, BGP_PATH_VALID);
6280 }
6281 } else {
6282 /* Delete the NHT structure if any, if we're
6283 * toggling between
6284 * enabling/disabling import check. We
6285 * deregister the route
6286 * from NHT to avoid overloading NHT and the
6287 * process interaction
6288 */
6289 bgp_unlink_nexthop(pi);
6290 bgp_path_info_set_flag(dest, pi,
6291 BGP_PATH_VALID);
6292 }
6293 /* Process change. */
6294 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6295 bgp_process(bgp, dest, afi, safi);
6296
6297 if (SAFI_UNICAST == safi
6298 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6299 || bgp->inst_type
6300 == BGP_INSTANCE_TYPE_DEFAULT)) {
6301 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6302 pi);
6303 }
6304
6305 bgp_dest_unlock_node(dest);
6306 aspath_unintern(&attr.aspath);
6307 return;
6308 }
6309 }
6310
6311 /* Make new BGP info. */
6312 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6313 attr_new, dest);
6314 /* Nexthop reachability check. */
6315 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6316 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6317 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6318 p))
6319 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6320 else {
6321 if (BGP_DEBUG(nht, NHT)) {
6322 char buf1[INET6_ADDRSTRLEN];
6323
6324 inet_ntop(p->family, &p->u.prefix, buf1,
6325 sizeof(buf1));
6326 zlog_debug(
6327 "%s(%s): Route not in table, not advertising",
6328 __func__, buf1);
6329 }
6330 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6331 }
6332 } else {
6333 /* Delete the NHT structure if any, if we're toggling between
6334 * enabling/disabling import check. We deregister the route
6335 * from NHT to avoid overloading NHT and the process interaction
6336 */
6337 bgp_unlink_nexthop(new);
6338
6339 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6340 }
6341
6342 /* Aggregate address increment. */
6343 bgp_aggregate_increment(bgp, p, new, afi, safi);
6344
6345 /* Register new BGP information. */
6346 bgp_path_info_add(dest, new);
6347
6348 /* route_node_get lock */
6349 bgp_dest_unlock_node(dest);
6350
6351 /* Process change. */
6352 bgp_process(bgp, dest, afi, safi);
6353
6354 if (SAFI_UNICAST == safi
6355 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6356 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6357 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6358 }
6359
6360 /* Unintern original. */
6361 aspath_unintern(&attr.aspath);
6362 }
6363
6364 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6365 safi_t safi)
6366 {
6367 struct bgp_dest *dest;
6368 struct bgp_path_info *pi;
6369
6370 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6371
6372 /* Check selected route and self inserted route. */
6373 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6374 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6375 && pi->sub_type == BGP_ROUTE_STATIC)
6376 break;
6377
6378 /* Withdraw static BGP route from routing table. */
6379 if (pi) {
6380 if (SAFI_UNICAST == safi
6381 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6382 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6383 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6384 }
6385 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6386 bgp_unlink_nexthop(pi);
6387 bgp_path_info_delete(dest, pi);
6388 bgp_process(bgp, dest, afi, safi);
6389 }
6390
6391 /* Unlock bgp_node_lookup. */
6392 bgp_dest_unlock_node(dest);
6393 }
6394
6395 /*
6396 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6397 */
6398 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6399 afi_t afi, safi_t safi,
6400 struct prefix_rd *prd)
6401 {
6402 struct bgp_dest *dest;
6403 struct bgp_path_info *pi;
6404
6405 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6406
6407 /* Check selected route and self inserted route. */
6408 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6409 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6410 && pi->sub_type == BGP_ROUTE_STATIC)
6411 break;
6412
6413 /* Withdraw static BGP route from routing table. */
6414 if (pi) {
6415 #ifdef ENABLE_BGP_VNC
6416 rfapiProcessWithdraw(
6417 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6418 1); /* Kill, since it is an administrative change */
6419 #endif
6420 if (SAFI_MPLS_VPN == safi
6421 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6422 vpn_leak_to_vrf_withdraw(pi);
6423 }
6424 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6425 bgp_path_info_delete(dest, pi);
6426 bgp_process(bgp, dest, afi, safi);
6427 }
6428
6429 /* Unlock bgp_node_lookup. */
6430 bgp_dest_unlock_node(dest);
6431 }
6432
6433 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6434 struct bgp_static *bgp_static, afi_t afi,
6435 safi_t safi)
6436 {
6437 struct bgp_dest *dest;
6438 struct bgp_path_info *new;
6439 struct attr *attr_new;
6440 struct attr attr = {0};
6441 struct bgp_path_info *pi;
6442 #ifdef ENABLE_BGP_VNC
6443 mpls_label_t label = 0;
6444 #endif
6445 uint32_t num_labels = 0;
6446
6447 assert(bgp_static);
6448
6449 if (bgp_static->label != MPLS_INVALID_LABEL)
6450 num_labels = 1;
6451 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6452 &bgp_static->prd);
6453
6454 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6455
6456 attr.nexthop = bgp_static->igpnexthop;
6457 attr.med = bgp_static->igpmetric;
6458 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6459
6460 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6461 || (safi == SAFI_ENCAP)) {
6462 if (afi == AFI_IP) {
6463 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6464 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6465 }
6466 }
6467 if (afi == AFI_L2VPN) {
6468 if (bgp_static->gatewayIp.family == AF_INET) {
6469 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6470 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6471 &bgp_static->gatewayIp.u.prefix4,
6472 IPV4_MAX_BYTELEN);
6473 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6474 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6475 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6476 &bgp_static->gatewayIp.u.prefix6,
6477 IPV6_MAX_BYTELEN);
6478 }
6479 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6480 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6481 struct bgp_encap_type_vxlan bet;
6482 memset(&bet, 0, sizeof(bet));
6483 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6484 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6485 }
6486 if (bgp_static->router_mac) {
6487 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6488 }
6489 }
6490 /* Apply route-map. */
6491 if (bgp_static->rmap.name) {
6492 struct attr attr_tmp = attr;
6493 struct bgp_path_info rmap_path;
6494 route_map_result_t ret;
6495
6496 rmap_path.peer = bgp->peer_self;
6497 rmap_path.attr = &attr_tmp;
6498
6499 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6500
6501 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6502
6503 bgp->peer_self->rmap_type = 0;
6504
6505 if (ret == RMAP_DENYMATCH) {
6506 /* Free uninterned attribute. */
6507 bgp_attr_flush(&attr_tmp);
6508
6509 /* Unintern original. */
6510 aspath_unintern(&attr.aspath);
6511 bgp_static_withdraw_safi(bgp, p, afi, safi,
6512 &bgp_static->prd);
6513 bgp_dest_unlock_node(dest);
6514 return;
6515 }
6516
6517 attr_new = bgp_attr_intern(&attr_tmp);
6518 } else {
6519 attr_new = bgp_attr_intern(&attr);
6520 }
6521
6522 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6523 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6524 && pi->sub_type == BGP_ROUTE_STATIC)
6525 break;
6526
6527 if (pi) {
6528 if (attrhash_cmp(pi->attr, attr_new)
6529 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6530 bgp_dest_unlock_node(dest);
6531 bgp_attr_unintern(&attr_new);
6532 aspath_unintern(&attr.aspath);
6533 return;
6534 } else {
6535 /* The attribute is changed. */
6536 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6537
6538 /* Rewrite BGP route information. */
6539 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6540 bgp_path_info_restore(dest, pi);
6541 else
6542 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6543 bgp_attr_unintern(&pi->attr);
6544 pi->attr = attr_new;
6545 pi->uptime = monotime(NULL);
6546 #ifdef ENABLE_BGP_VNC
6547 if (pi->extra)
6548 label = decode_label(&pi->extra->label[0]);
6549 #endif
6550
6551 /* Process change. */
6552 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6553 bgp_process(bgp, dest, afi, safi);
6554
6555 if (SAFI_MPLS_VPN == safi
6556 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6557 vpn_leak_to_vrf_update(bgp, pi,
6558 &bgp_static->prd);
6559 }
6560 #ifdef ENABLE_BGP_VNC
6561 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6562 pi->attr, afi, safi, pi->type,
6563 pi->sub_type, &label);
6564 #endif
6565 bgp_dest_unlock_node(dest);
6566 aspath_unintern(&attr.aspath);
6567 return;
6568 }
6569 }
6570
6571
6572 /* Make new BGP info. */
6573 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6574 attr_new, dest);
6575 SET_FLAG(new->flags, BGP_PATH_VALID);
6576 bgp_path_info_extra_get(new);
6577 if (num_labels) {
6578 new->extra->label[0] = bgp_static->label;
6579 new->extra->num_labels = num_labels;
6580 }
6581 #ifdef ENABLE_BGP_VNC
6582 label = decode_label(&bgp_static->label);
6583 #endif
6584
6585 /* Aggregate address increment. */
6586 bgp_aggregate_increment(bgp, p, new, afi, safi);
6587
6588 /* Register new BGP information. */
6589 bgp_path_info_add(dest, new);
6590 /* route_node_get lock */
6591 bgp_dest_unlock_node(dest);
6592
6593 /* Process change. */
6594 bgp_process(bgp, dest, afi, safi);
6595
6596 if (SAFI_MPLS_VPN == safi
6597 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6598 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6599 }
6600 #ifdef ENABLE_BGP_VNC
6601 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6602 safi, new->type, new->sub_type, &label);
6603 #endif
6604
6605 /* Unintern original. */
6606 aspath_unintern(&attr.aspath);
6607 }
6608
6609 /* Configure static BGP network. When user don't run zebra, static
6610 route should be installed as valid. */
6611 static int bgp_static_set(struct vty *vty, const char *negate,
6612 const char *ip_str, afi_t afi, safi_t safi,
6613 const char *rmap, int backdoor, uint32_t label_index)
6614 {
6615 VTY_DECLVAR_CONTEXT(bgp, bgp);
6616 int ret;
6617 struct prefix p;
6618 struct bgp_static *bgp_static;
6619 struct bgp_dest *dest;
6620 uint8_t need_update = 0;
6621
6622 /* Convert IP prefix string to struct prefix. */
6623 ret = str2prefix(ip_str, &p);
6624 if (!ret) {
6625 vty_out(vty, "%% Malformed prefix\n");
6626 return CMD_WARNING_CONFIG_FAILED;
6627 }
6628 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6629 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6630 return CMD_WARNING_CONFIG_FAILED;
6631 }
6632
6633 apply_mask(&p);
6634
6635 if (negate) {
6636
6637 /* Set BGP static route configuration. */
6638 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6639
6640 if (!dest) {
6641 vty_out(vty, "%% Can't find static route specified\n");
6642 return CMD_WARNING_CONFIG_FAILED;
6643 }
6644
6645 bgp_static = bgp_dest_get_bgp_static_info(dest);
6646
6647 if ((label_index != BGP_INVALID_LABEL_INDEX)
6648 && (label_index != bgp_static->label_index)) {
6649 vty_out(vty,
6650 "%% label-index doesn't match static route\n");
6651 bgp_dest_unlock_node(dest);
6652 return CMD_WARNING_CONFIG_FAILED;
6653 }
6654
6655 if ((rmap && bgp_static->rmap.name)
6656 && strcmp(rmap, bgp_static->rmap.name)) {
6657 vty_out(vty,
6658 "%% route-map name doesn't match static route\n");
6659 bgp_dest_unlock_node(dest);
6660 return CMD_WARNING_CONFIG_FAILED;
6661 }
6662
6663 /* Update BGP RIB. */
6664 if (!bgp_static->backdoor)
6665 bgp_static_withdraw(bgp, &p, afi, safi);
6666
6667 /* Clear configuration. */
6668 bgp_static_free(bgp_static);
6669 bgp_dest_set_bgp_static_info(dest, NULL);
6670 bgp_dest_unlock_node(dest);
6671 bgp_dest_unlock_node(dest);
6672 } else {
6673
6674 /* Set BGP static route configuration. */
6675 dest = bgp_node_get(bgp->route[afi][safi], &p);
6676 bgp_static = bgp_dest_get_bgp_static_info(dest);
6677 if (bgp_static) {
6678 /* Configuration change. */
6679 /* Label index cannot be changed. */
6680 if (bgp_static->label_index != label_index) {
6681 vty_out(vty, "%% cannot change label-index\n");
6682 bgp_dest_unlock_node(dest);
6683 return CMD_WARNING_CONFIG_FAILED;
6684 }
6685
6686 /* Check previous routes are installed into BGP. */
6687 if (bgp_static->valid
6688 && bgp_static->backdoor != backdoor)
6689 need_update = 1;
6690
6691 bgp_static->backdoor = backdoor;
6692
6693 if (rmap) {
6694 XFREE(MTYPE_ROUTE_MAP_NAME,
6695 bgp_static->rmap.name);
6696 route_map_counter_decrement(
6697 bgp_static->rmap.map);
6698 bgp_static->rmap.name =
6699 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6700 bgp_static->rmap.map =
6701 route_map_lookup_by_name(rmap);
6702 route_map_counter_increment(
6703 bgp_static->rmap.map);
6704 } else {
6705 XFREE(MTYPE_ROUTE_MAP_NAME,
6706 bgp_static->rmap.name);
6707 route_map_counter_decrement(
6708 bgp_static->rmap.map);
6709 bgp_static->rmap.map = NULL;
6710 bgp_static->valid = 0;
6711 }
6712 bgp_dest_unlock_node(dest);
6713 } else {
6714 /* New configuration. */
6715 bgp_static = bgp_static_new();
6716 bgp_static->backdoor = backdoor;
6717 bgp_static->valid = 0;
6718 bgp_static->igpmetric = 0;
6719 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6720 bgp_static->label_index = label_index;
6721
6722 if (rmap) {
6723 XFREE(MTYPE_ROUTE_MAP_NAME,
6724 bgp_static->rmap.name);
6725 route_map_counter_decrement(
6726 bgp_static->rmap.map);
6727 bgp_static->rmap.name =
6728 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6729 bgp_static->rmap.map =
6730 route_map_lookup_by_name(rmap);
6731 route_map_counter_increment(
6732 bgp_static->rmap.map);
6733 }
6734 bgp_dest_set_bgp_static_info(dest, bgp_static);
6735 }
6736
6737 bgp_static->valid = 1;
6738 if (need_update)
6739 bgp_static_withdraw(bgp, &p, afi, safi);
6740
6741 if (!bgp_static->backdoor)
6742 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6743 }
6744
6745 return CMD_SUCCESS;
6746 }
6747
6748 void bgp_static_add(struct bgp *bgp)
6749 {
6750 afi_t afi;
6751 safi_t safi;
6752 struct bgp_dest *dest;
6753 struct bgp_dest *rm;
6754 struct bgp_table *table;
6755 struct bgp_static *bgp_static;
6756
6757 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6758 FOREACH_AFI_SAFI (afi, safi)
6759 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6760 dest = bgp_route_next(dest)) {
6761 if (!bgp_dest_has_bgp_path_info_data(dest))
6762 continue;
6763
6764 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6765 || (safi == SAFI_EVPN)) {
6766 table = bgp_dest_get_bgp_table_info(dest);
6767
6768 for (rm = bgp_table_top(table); rm;
6769 rm = bgp_route_next(rm)) {
6770 bgp_static =
6771 bgp_dest_get_bgp_static_info(
6772 rm);
6773 bgp_static_update_safi(
6774 bgp, bgp_dest_get_prefix(rm),
6775 bgp_static, afi, safi);
6776 }
6777 } else {
6778 bgp_static_update(
6779 bgp, bgp_dest_get_prefix(dest),
6780 bgp_dest_get_bgp_static_info(dest), afi,
6781 safi);
6782 }
6783 }
6784 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6785 }
6786
6787 /* Called from bgp_delete(). Delete all static routes from the BGP
6788 instance. */
6789 void bgp_static_delete(struct bgp *bgp)
6790 {
6791 afi_t afi;
6792 safi_t safi;
6793 struct bgp_dest *dest;
6794 struct bgp_dest *rm;
6795 struct bgp_table *table;
6796 struct bgp_static *bgp_static;
6797
6798 FOREACH_AFI_SAFI (afi, safi)
6799 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6800 dest = bgp_route_next(dest)) {
6801 if (!bgp_dest_has_bgp_path_info_data(dest))
6802 continue;
6803
6804 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6805 || (safi == SAFI_EVPN)) {
6806 table = bgp_dest_get_bgp_table_info(dest);
6807
6808 for (rm = bgp_table_top(table); rm;
6809 rm = bgp_route_next(rm)) {
6810 bgp_static =
6811 bgp_dest_get_bgp_static_info(
6812 rm);
6813 if (!bgp_static)
6814 continue;
6815
6816 bgp_static_withdraw_safi(
6817 bgp, bgp_dest_get_prefix(rm),
6818 AFI_IP, safi,
6819 (struct prefix_rd *)
6820 bgp_dest_get_prefix(
6821 dest));
6822 bgp_static_free(bgp_static);
6823 bgp_dest_set_bgp_static_info(rm,
6824 NULL);
6825 bgp_dest_unlock_node(rm);
6826 }
6827 } else {
6828 bgp_static = bgp_dest_get_bgp_static_info(dest);
6829 bgp_static_withdraw(bgp,
6830 bgp_dest_get_prefix(dest),
6831 afi, safi);
6832 bgp_static_free(bgp_static);
6833 bgp_dest_set_bgp_static_info(dest, NULL);
6834 bgp_dest_unlock_node(dest);
6835 }
6836 }
6837 }
6838
6839 void bgp_static_redo_import_check(struct bgp *bgp)
6840 {
6841 afi_t afi;
6842 safi_t safi;
6843 struct bgp_dest *dest;
6844 struct bgp_dest *rm;
6845 struct bgp_table *table;
6846 struct bgp_static *bgp_static;
6847
6848 /* Use this flag to force reprocessing of the route */
6849 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6850 FOREACH_AFI_SAFI (afi, safi) {
6851 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6852 dest = bgp_route_next(dest)) {
6853 if (!bgp_dest_has_bgp_path_info_data(dest))
6854 continue;
6855
6856 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6857 || (safi == SAFI_EVPN)) {
6858 table = bgp_dest_get_bgp_table_info(dest);
6859
6860 for (rm = bgp_table_top(table); rm;
6861 rm = bgp_route_next(rm)) {
6862 bgp_static =
6863 bgp_dest_get_bgp_static_info(
6864 rm);
6865 bgp_static_update_safi(
6866 bgp, bgp_dest_get_prefix(rm),
6867 bgp_static, afi, safi);
6868 }
6869 } else {
6870 bgp_static = bgp_dest_get_bgp_static_info(dest);
6871 bgp_static_update(bgp,
6872 bgp_dest_get_prefix(dest),
6873 bgp_static, afi, safi);
6874 }
6875 }
6876 }
6877 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6878 }
6879
6880 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6881 safi_t safi)
6882 {
6883 struct bgp_table *table;
6884 struct bgp_dest *dest;
6885 struct bgp_path_info *pi;
6886
6887 /* Do not install the aggregate route if BGP is in the
6888 * process of termination.
6889 */
6890 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6891 || (bgp->peer_self == NULL))
6892 return;
6893
6894 table = bgp->rib[afi][safi];
6895 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6896 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6897 if (pi->peer == bgp->peer_self
6898 && ((pi->type == ZEBRA_ROUTE_BGP
6899 && pi->sub_type == BGP_ROUTE_STATIC)
6900 || (pi->type != ZEBRA_ROUTE_BGP
6901 && pi->sub_type
6902 == BGP_ROUTE_REDISTRIBUTE))) {
6903 bgp_aggregate_decrement(
6904 bgp, bgp_dest_get_prefix(dest), pi, afi,
6905 safi);
6906 bgp_unlink_nexthop(pi);
6907 bgp_path_info_delete(dest, pi);
6908 bgp_process(bgp, dest, afi, safi);
6909 }
6910 }
6911 }
6912 }
6913
6914 /*
6915 * Purge all networks and redistributed routes from routing table.
6916 * Invoked upon the instance going down.
6917 */
6918 void bgp_purge_static_redist_routes(struct bgp *bgp)
6919 {
6920 afi_t afi;
6921 safi_t safi;
6922
6923 FOREACH_AFI_SAFI (afi, safi)
6924 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6925 }
6926
6927 /*
6928 * gpz 110624
6929 * Currently this is used to set static routes for VPN and ENCAP.
6930 * I think it can probably be factored with bgp_static_set.
6931 */
6932 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6933 const char *ip_str, const char *rd_str,
6934 const char *label_str, const char *rmap_str,
6935 int evpn_type, const char *esi, const char *gwip,
6936 const char *ethtag, const char *routermac)
6937 {
6938 VTY_DECLVAR_CONTEXT(bgp, bgp);
6939 int ret;
6940 struct prefix p;
6941 struct prefix_rd prd;
6942 struct bgp_dest *pdest;
6943 struct bgp_dest *dest;
6944 struct bgp_table *table;
6945 struct bgp_static *bgp_static;
6946 mpls_label_t label = MPLS_INVALID_LABEL;
6947 struct prefix gw_ip;
6948
6949 /* validate ip prefix */
6950 ret = str2prefix(ip_str, &p);
6951 if (!ret) {
6952 vty_out(vty, "%% Malformed prefix\n");
6953 return CMD_WARNING_CONFIG_FAILED;
6954 }
6955 apply_mask(&p);
6956 if ((afi == AFI_L2VPN)
6957 && (bgp_build_evpn_prefix(evpn_type,
6958 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6959 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6960 return CMD_WARNING_CONFIG_FAILED;
6961 }
6962
6963 ret = str2prefix_rd(rd_str, &prd);
6964 if (!ret) {
6965 vty_out(vty, "%% Malformed rd\n");
6966 return CMD_WARNING_CONFIG_FAILED;
6967 }
6968
6969 if (label_str) {
6970 unsigned long label_val;
6971 label_val = strtoul(label_str, NULL, 10);
6972 encode_label(label_val, &label);
6973 }
6974
6975 if (safi == SAFI_EVPN) {
6976 if (esi && str2esi(esi, NULL) == 0) {
6977 vty_out(vty, "%% Malformed ESI\n");
6978 return CMD_WARNING_CONFIG_FAILED;
6979 }
6980 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6981 vty_out(vty, "%% Malformed Router MAC\n");
6982 return CMD_WARNING_CONFIG_FAILED;
6983 }
6984 if (gwip) {
6985 memset(&gw_ip, 0, sizeof(gw_ip));
6986 ret = str2prefix(gwip, &gw_ip);
6987 if (!ret) {
6988 vty_out(vty, "%% Malformed GatewayIp\n");
6989 return CMD_WARNING_CONFIG_FAILED;
6990 }
6991 if ((gw_ip.family == AF_INET
6992 && is_evpn_prefix_ipaddr_v6(
6993 (struct prefix_evpn *)&p))
6994 || (gw_ip.family == AF_INET6
6995 && is_evpn_prefix_ipaddr_v4(
6996 (struct prefix_evpn *)&p))) {
6997 vty_out(vty,
6998 "%% GatewayIp family differs with IP prefix\n");
6999 return CMD_WARNING_CONFIG_FAILED;
7000 }
7001 }
7002 }
7003 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7004 if (!bgp_dest_has_bgp_path_info_data(pdest))
7005 bgp_dest_set_bgp_table_info(pdest,
7006 bgp_table_init(bgp, afi, safi));
7007 table = bgp_dest_get_bgp_table_info(pdest);
7008
7009 dest = bgp_node_get(table, &p);
7010
7011 if (bgp_dest_has_bgp_path_info_data(dest)) {
7012 vty_out(vty, "%% Same network configuration exists\n");
7013 bgp_dest_unlock_node(dest);
7014 } else {
7015 /* New configuration. */
7016 bgp_static = bgp_static_new();
7017 bgp_static->backdoor = 0;
7018 bgp_static->valid = 0;
7019 bgp_static->igpmetric = 0;
7020 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7021 bgp_static->label = label;
7022 bgp_static->prd = prd;
7023
7024 if (rd_str)
7025 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
7026 if (rmap_str) {
7027 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7028 route_map_counter_decrement(bgp_static->rmap.map);
7029 bgp_static->rmap.name =
7030 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7031 bgp_static->rmap.map =
7032 route_map_lookup_by_name(rmap_str);
7033 route_map_counter_increment(bgp_static->rmap.map);
7034 }
7035
7036 if (safi == SAFI_EVPN) {
7037 if (esi) {
7038 bgp_static->eth_s_id =
7039 XCALLOC(MTYPE_ATTR,
7040 sizeof(esi_t));
7041 str2esi(esi, bgp_static->eth_s_id);
7042 }
7043 if (routermac) {
7044 bgp_static->router_mac =
7045 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7046 (void)prefix_str2mac(routermac,
7047 bgp_static->router_mac);
7048 }
7049 if (gwip)
7050 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7051 }
7052 bgp_dest_set_bgp_static_info(dest, bgp_static);
7053
7054 bgp_static->valid = 1;
7055 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7056 }
7057
7058 return CMD_SUCCESS;
7059 }
7060
7061 /* Configure static BGP network. */
7062 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7063 const char *ip_str, const char *rd_str,
7064 const char *label_str, int evpn_type, const char *esi,
7065 const char *gwip, const char *ethtag)
7066 {
7067 VTY_DECLVAR_CONTEXT(bgp, bgp);
7068 int ret;
7069 struct prefix p;
7070 struct prefix_rd prd;
7071 struct bgp_dest *pdest;
7072 struct bgp_dest *dest;
7073 struct bgp_table *table;
7074 struct bgp_static *bgp_static;
7075 mpls_label_t label = MPLS_INVALID_LABEL;
7076
7077 /* Convert IP prefix string to struct prefix. */
7078 ret = str2prefix(ip_str, &p);
7079 if (!ret) {
7080 vty_out(vty, "%% Malformed prefix\n");
7081 return CMD_WARNING_CONFIG_FAILED;
7082 }
7083 apply_mask(&p);
7084 if ((afi == AFI_L2VPN)
7085 && (bgp_build_evpn_prefix(evpn_type,
7086 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7087 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7088 return CMD_WARNING_CONFIG_FAILED;
7089 }
7090 ret = str2prefix_rd(rd_str, &prd);
7091 if (!ret) {
7092 vty_out(vty, "%% Malformed rd\n");
7093 return CMD_WARNING_CONFIG_FAILED;
7094 }
7095
7096 if (label_str) {
7097 unsigned long label_val;
7098 label_val = strtoul(label_str, NULL, 10);
7099 encode_label(label_val, &label);
7100 }
7101
7102 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7103 if (!bgp_dest_has_bgp_path_info_data(pdest))
7104 bgp_dest_set_bgp_table_info(pdest,
7105 bgp_table_init(bgp, afi, safi));
7106 else
7107 bgp_dest_unlock_node(pdest);
7108 table = bgp_dest_get_bgp_table_info(pdest);
7109
7110 dest = bgp_node_lookup(table, &p);
7111
7112 if (dest) {
7113 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7114
7115 bgp_static = bgp_dest_get_bgp_static_info(dest);
7116 bgp_static_free(bgp_static);
7117 bgp_dest_set_bgp_static_info(dest, NULL);
7118 bgp_dest_unlock_node(dest);
7119 bgp_dest_unlock_node(dest);
7120 } else
7121 vty_out(vty, "%% Can't find the route\n");
7122
7123 return CMD_SUCCESS;
7124 }
7125
7126 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7127 const char *rmap_name)
7128 {
7129 VTY_DECLVAR_CONTEXT(bgp, bgp);
7130 struct bgp_rmap *rmap;
7131
7132 rmap = &bgp->table_map[afi][safi];
7133 if (rmap_name) {
7134 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7135 route_map_counter_decrement(rmap->map);
7136 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7137 rmap->map = route_map_lookup_by_name(rmap_name);
7138 route_map_counter_increment(rmap->map);
7139 } else {
7140 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7141 route_map_counter_decrement(rmap->map);
7142 rmap->map = NULL;
7143 }
7144
7145 if (bgp_fibupd_safi(safi))
7146 bgp_zebra_announce_table(bgp, afi, safi);
7147
7148 return CMD_SUCCESS;
7149 }
7150
7151 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7152 const char *rmap_name)
7153 {
7154 VTY_DECLVAR_CONTEXT(bgp, bgp);
7155 struct bgp_rmap *rmap;
7156
7157 rmap = &bgp->table_map[afi][safi];
7158 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7159 route_map_counter_decrement(rmap->map);
7160 rmap->map = NULL;
7161
7162 if (bgp_fibupd_safi(safi))
7163 bgp_zebra_announce_table(bgp, afi, safi);
7164
7165 return CMD_SUCCESS;
7166 }
7167
7168 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7169 safi_t safi)
7170 {
7171 if (bgp->table_map[afi][safi].name) {
7172 vty_out(vty, " table-map %s\n",
7173 bgp->table_map[afi][safi].name);
7174 }
7175 }
7176
7177 DEFUN (bgp_table_map,
7178 bgp_table_map_cmd,
7179 "table-map WORD",
7180 "BGP table to RIB route download filter\n"
7181 "Name of the route map\n")
7182 {
7183 int idx_word = 1;
7184 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7185 argv[idx_word]->arg);
7186 }
7187 DEFUN (no_bgp_table_map,
7188 no_bgp_table_map_cmd,
7189 "no table-map WORD",
7190 NO_STR
7191 "BGP table to RIB route download filter\n"
7192 "Name of the route map\n")
7193 {
7194 int idx_word = 2;
7195 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7196 argv[idx_word]->arg);
7197 }
7198
7199 DEFPY(bgp_network,
7200 bgp_network_cmd,
7201 "[no] network \
7202 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7203 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7204 backdoor$backdoor}]",
7205 NO_STR
7206 "Specify a network to announce via BGP\n"
7207 "IPv4 prefix\n"
7208 "Network number\n"
7209 "Network mask\n"
7210 "Network mask\n"
7211 "Route-map to modify the attributes\n"
7212 "Name of the route map\n"
7213 "Label index to associate with the prefix\n"
7214 "Label index value\n"
7215 "Specify a BGP backdoor route\n")
7216 {
7217 char addr_prefix_str[BUFSIZ];
7218
7219 if (address_str) {
7220 int ret;
7221
7222 ret = netmask_str2prefix_str(address_str, netmask_str,
7223 addr_prefix_str,
7224 sizeof(addr_prefix_str));
7225 if (!ret) {
7226 vty_out(vty, "%% Inconsistent address and mask\n");
7227 return CMD_WARNING_CONFIG_FAILED;
7228 }
7229 }
7230
7231 return bgp_static_set(
7232 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7233 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7234 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7235 }
7236
7237 DEFPY(ipv6_bgp_network,
7238 ipv6_bgp_network_cmd,
7239 "[no] network X:X::X:X/M$prefix \
7240 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7241 NO_STR
7242 "Specify a network to announce via BGP\n"
7243 "IPv6 prefix\n"
7244 "Route-map to modify the attributes\n"
7245 "Name of the route map\n"
7246 "Label index to associate with the prefix\n"
7247 "Label index value\n")
7248 {
7249 return bgp_static_set(
7250 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7251 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7252 }
7253
7254 static struct bgp_aggregate *bgp_aggregate_new(void)
7255 {
7256 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7257 }
7258
7259 void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7260 {
7261 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7262 route_map_counter_decrement(aggregate->suppress_map);
7263 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7264 route_map_counter_decrement(aggregate->rmap.map);
7265 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7266 }
7267
7268 /**
7269 * Helper function to avoid repeated code: prepare variables for a
7270 * `route_map_apply` call.
7271 *
7272 * \returns `true` on route map match, otherwise `false`.
7273 */
7274 static bool aggr_suppress_map_test(struct bgp *bgp,
7275 struct bgp_aggregate *aggregate,
7276 struct bgp_path_info *pi)
7277 {
7278 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7279 route_map_result_t rmr = RMAP_DENYMATCH;
7280 struct bgp_path_info rmap_path = {};
7281 struct attr attr = {};
7282
7283 /* No route map entries created, just don't match. */
7284 if (aggregate->suppress_map == NULL)
7285 return false;
7286
7287 /* Call route map matching and return result. */
7288 attr.aspath = aspath_empty(bgp->asnotation);
7289 rmap_path.peer = bgp->peer_self;
7290 rmap_path.attr = &attr;
7291
7292 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7293 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7294 bgp->peer_self->rmap_type = 0;
7295
7296 bgp_attr_flush(&attr);
7297 aspath_unintern(&attr.aspath);
7298
7299 return rmr == RMAP_PERMITMATCH;
7300 }
7301
7302 /** Test whether the aggregation has suppressed this path or not. */
7303 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7304 struct bgp_path_info *pi)
7305 {
7306 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7307 return false;
7308
7309 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7310 }
7311
7312 /**
7313 * Suppress this path and keep the reference.
7314 *
7315 * \returns `true` if needs processing otherwise `false`.
7316 */
7317 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7318 struct bgp_path_info *pi)
7319 {
7320 struct bgp_path_info_extra *pie;
7321
7322 /* Path is already suppressed by this aggregation. */
7323 if (aggr_suppress_exists(aggregate, pi))
7324 return false;
7325
7326 pie = bgp_path_info_extra_get(pi);
7327
7328 /* This is the first suppression, allocate memory and list it. */
7329 if (pie->aggr_suppressors == NULL)
7330 pie->aggr_suppressors = list_new();
7331
7332 listnode_add(pie->aggr_suppressors, aggregate);
7333
7334 /* Only mark for processing if suppressed. */
7335 if (listcount(pie->aggr_suppressors) == 1) {
7336 if (BGP_DEBUG(update, UPDATE_OUT))
7337 zlog_debug("aggregate-address suppressing: %pFX",
7338 bgp_dest_get_prefix(pi->net));
7339
7340 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7341 return true;
7342 }
7343
7344 return false;
7345 }
7346
7347 /**
7348 * Unsuppress this path and remove the reference.
7349 *
7350 * \returns `true` if needs processing otherwise `false`.
7351 */
7352 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7353 struct bgp_path_info *pi)
7354 {
7355 /* Path wasn't suppressed. */
7356 if (!aggr_suppress_exists(aggregate, pi))
7357 return false;
7358
7359 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7360
7361 /* Unsuppress and free extra memory if last item. */
7362 if (listcount(pi->extra->aggr_suppressors) == 0) {
7363 if (BGP_DEBUG(update, UPDATE_OUT))
7364 zlog_debug("aggregate-address unsuppressing: %pFX",
7365 bgp_dest_get_prefix(pi->net));
7366
7367 list_delete(&pi->extra->aggr_suppressors);
7368 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7369 return true;
7370 }
7371
7372 return false;
7373 }
7374
7375 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7376 struct aspath *aspath,
7377 struct community *comm,
7378 struct ecommunity *ecomm,
7379 struct lcommunity *lcomm)
7380 {
7381 static struct aspath *ae = NULL;
7382 enum asnotation_mode asnotation;
7383
7384 asnotation = bgp_get_asnotation(NULL);
7385
7386 if (!ae)
7387 ae = aspath_empty(asnotation);
7388
7389 if (!pi)
7390 return false;
7391
7392 if (origin != pi->attr->origin)
7393 return false;
7394
7395 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7396 return false;
7397
7398 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7399 return false;
7400
7401 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7402 return false;
7403
7404 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7405 return false;
7406
7407 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7408 return false;
7409
7410 return true;
7411 }
7412
7413 static void bgp_aggregate_install(
7414 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7415 uint8_t origin, struct aspath *aspath, struct community *community,
7416 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7417 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7418 {
7419 struct bgp_dest *dest;
7420 struct bgp_table *table;
7421 struct bgp_path_info *pi, *orig, *new;
7422 struct attr *attr;
7423
7424 table = bgp->rib[afi][safi];
7425
7426 dest = bgp_node_get(table, p);
7427
7428 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7429 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7430 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7431 break;
7432
7433 /*
7434 * If we have paths with different MEDs, then don't install
7435 * (or uninstall) the aggregate route.
7436 */
7437 if (aggregate->match_med && aggregate->med_mismatched)
7438 goto uninstall_aggregate_route;
7439
7440 if (aggregate->count > 0) {
7441 /*
7442 * If the aggregate information has not changed
7443 * no need to re-install it again.
7444 */
7445 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7446 ecommunity, lcommunity)) {
7447 bgp_dest_unlock_node(dest);
7448
7449 if (aspath)
7450 aspath_free(aspath);
7451 if (community)
7452 community_free(&community);
7453 if (ecommunity)
7454 ecommunity_free(&ecommunity);
7455 if (lcommunity)
7456 lcommunity_free(&lcommunity);
7457
7458 return;
7459 }
7460
7461 /*
7462 * Mark the old as unusable
7463 */
7464 if (pi)
7465 bgp_path_info_delete(dest, pi);
7466
7467 attr = bgp_attr_aggregate_intern(
7468 bgp, origin, aspath, community, ecommunity, lcommunity,
7469 aggregate, atomic_aggregate, p);
7470
7471 if (!attr) {
7472 aspath_free(aspath);
7473 community_free(&community);
7474 ecommunity_free(&ecommunity);
7475 lcommunity_free(&lcommunity);
7476 bgp_dest_unlock_node(dest);
7477 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7478 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7479 zlog_debug("%s: %pFX null attribute", __func__,
7480 p);
7481 return;
7482 }
7483
7484 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7485 bgp->peer_self, attr, dest);
7486
7487 SET_FLAG(new->flags, BGP_PATH_VALID);
7488
7489 bgp_path_info_add(dest, new);
7490 bgp_process(bgp, dest, afi, safi);
7491 } else {
7492 uninstall_aggregate_route:
7493 for (pi = orig; pi; pi = pi->next)
7494 if (pi->peer == bgp->peer_self
7495 && pi->type == ZEBRA_ROUTE_BGP
7496 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7497 break;
7498
7499 /* Withdraw static BGP route from routing table. */
7500 if (pi) {
7501 bgp_path_info_delete(dest, pi);
7502 bgp_process(bgp, dest, afi, safi);
7503 }
7504 }
7505
7506 bgp_dest_unlock_node(dest);
7507 }
7508
7509 /**
7510 * Check if the current path has different MED than other known paths.
7511 *
7512 * \returns `true` if the MED matched the others else `false`.
7513 */
7514 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7515 struct bgp *bgp, struct bgp_path_info *pi)
7516 {
7517 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7518
7519 /* This is the first route being analyzed. */
7520 if (!aggregate->med_initialized) {
7521 aggregate->med_initialized = true;
7522 aggregate->med_mismatched = false;
7523 aggregate->med_matched_value = cur_med;
7524 } else {
7525 /* Check if routes with different MED showed up. */
7526 if (cur_med != aggregate->med_matched_value)
7527 aggregate->med_mismatched = true;
7528 }
7529
7530 return !aggregate->med_mismatched;
7531 }
7532
7533 /**
7534 * Initializes and tests all routes in the aggregate address path for MED
7535 * values.
7536 *
7537 * \returns `true` if all MEDs are the same otherwise `false`.
7538 */
7539 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7540 struct bgp *bgp, const struct prefix *p,
7541 afi_t afi, safi_t safi)
7542 {
7543 struct bgp_table *table = bgp->rib[afi][safi];
7544 const struct prefix *dest_p;
7545 struct bgp_dest *dest, *top;
7546 struct bgp_path_info *pi;
7547 bool med_matched = true;
7548
7549 aggregate->med_initialized = false;
7550
7551 top = bgp_node_get(table, p);
7552 for (dest = bgp_node_get(table, p); dest;
7553 dest = bgp_route_next_until(dest, top)) {
7554 dest_p = bgp_dest_get_prefix(dest);
7555 if (dest_p->prefixlen <= p->prefixlen)
7556 continue;
7557
7558 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7559 if (BGP_PATH_HOLDDOWN(pi))
7560 continue;
7561 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7562 continue;
7563 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7564 med_matched = false;
7565 break;
7566 }
7567 }
7568 if (!med_matched)
7569 break;
7570 }
7571 bgp_dest_unlock_node(top);
7572
7573 return med_matched;
7574 }
7575
7576 /**
7577 * Toggles the route suppression status for this aggregate address
7578 * configuration.
7579 */
7580 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7581 struct bgp *bgp, const struct prefix *p,
7582 afi_t afi, safi_t safi, bool suppress)
7583 {
7584 struct bgp_table *table = bgp->rib[afi][safi];
7585 const struct prefix *dest_p;
7586 struct bgp_dest *dest, *top;
7587 struct bgp_path_info *pi;
7588 bool toggle_suppression;
7589
7590 /* We've found a different MED we must revert any suppressed routes. */
7591 top = bgp_node_get(table, p);
7592 for (dest = bgp_node_get(table, p); dest;
7593 dest = bgp_route_next_until(dest, top)) {
7594 dest_p = bgp_dest_get_prefix(dest);
7595 if (dest_p->prefixlen <= p->prefixlen)
7596 continue;
7597
7598 toggle_suppression = false;
7599 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7600 if (BGP_PATH_HOLDDOWN(pi))
7601 continue;
7602 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7603 continue;
7604
7605 /* We are toggling suppression back. */
7606 if (suppress) {
7607 /* Suppress route if not suppressed already. */
7608 if (aggr_suppress_path(aggregate, pi))
7609 toggle_suppression = true;
7610 continue;
7611 }
7612
7613 /* Install route if there is no more suppression. */
7614 if (aggr_unsuppress_path(aggregate, pi))
7615 toggle_suppression = true;
7616 }
7617
7618 if (toggle_suppression)
7619 bgp_process(bgp, dest, afi, safi);
7620 }
7621 bgp_dest_unlock_node(top);
7622 }
7623
7624 /**
7625 * Aggregate address MED matching incremental test: this function is called
7626 * when the initial aggregation occurred and we are only testing a single
7627 * new path.
7628 *
7629 * In addition to testing and setting the MED validity it also installs back
7630 * suppressed routes (if summary is configured).
7631 *
7632 * Must not be called in `bgp_aggregate_route`.
7633 */
7634 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7635 struct bgp *bgp, const struct prefix *p,
7636 afi_t afi, safi_t safi,
7637 struct bgp_path_info *pi)
7638 {
7639 /* MED matching disabled. */
7640 if (!aggregate->match_med)
7641 return;
7642
7643 /* Aggregation with different MED, recheck if we have got equal MEDs
7644 * now.
7645 */
7646 if (aggregate->med_mismatched &&
7647 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7648 aggregate->summary_only)
7649 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7650 true);
7651 else
7652 bgp_aggregate_med_match(aggregate, bgp, pi);
7653
7654 /* No mismatches, just quit. */
7655 if (!aggregate->med_mismatched)
7656 return;
7657
7658 /* Route summarization is disabled. */
7659 if (!aggregate->summary_only)
7660 return;
7661
7662 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7663 }
7664
7665 /* Update an aggregate as routes are added/removed from the BGP table */
7666 bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7667 safi_t safi, struct bgp_aggregate *aggregate)
7668 {
7669 struct bgp_table *table;
7670 struct bgp_dest *top;
7671 struct bgp_dest *dest;
7672 uint8_t origin;
7673 struct aspath *aspath = NULL;
7674 struct community *community = NULL;
7675 struct ecommunity *ecommunity = NULL;
7676 struct lcommunity *lcommunity = NULL;
7677 struct bgp_path_info *pi;
7678 unsigned long match = 0;
7679 uint8_t atomic_aggregate = 0;
7680
7681 /* If the bgp instance is being deleted or self peer is deleted
7682 * then do not create aggregate route
7683 */
7684 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
7685 bgp->peer_self == NULL)
7686 return false;
7687
7688 /* Initialize and test routes for MED difference. */
7689 if (aggregate->match_med)
7690 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7691
7692 /*
7693 * Reset aggregate count: we might've been called from route map
7694 * update so in that case we must retest all more specific routes.
7695 *
7696 * \see `bgp_route_map_process_update`.
7697 */
7698 aggregate->count = 0;
7699 aggregate->incomplete_origin_count = 0;
7700 aggregate->incomplete_origin_count = 0;
7701 aggregate->egp_origin_count = 0;
7702
7703 /* ORIGIN attribute: If at least one route among routes that are
7704 aggregated has ORIGIN with the value INCOMPLETE, then the
7705 aggregated route must have the ORIGIN attribute with the value
7706 INCOMPLETE. Otherwise, if at least one route among routes that
7707 are aggregated has ORIGIN with the value EGP, then the aggregated
7708 route must have the origin attribute with the value EGP. In all
7709 other case the value of the ORIGIN attribute of the aggregated
7710 route is INTERNAL. */
7711 origin = BGP_ORIGIN_IGP;
7712
7713 table = bgp->rib[afi][safi];
7714
7715 top = bgp_node_get(table, p);
7716 for (dest = bgp_node_get(table, p); dest;
7717 dest = bgp_route_next_until(dest, top)) {
7718 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7719
7720 if (dest_p->prefixlen <= p->prefixlen)
7721 continue;
7722
7723 /* If suppress fib is enabled and route not installed
7724 * in FIB, skip the route
7725 */
7726 if (!bgp_check_advertise(bgp, dest))
7727 continue;
7728
7729 match = 0;
7730
7731 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7732 if (BGP_PATH_HOLDDOWN(pi))
7733 continue;
7734
7735 if (pi->attr->flag
7736 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7737 atomic_aggregate = 1;
7738
7739 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7740 continue;
7741
7742 /*
7743 * summary-only aggregate route suppress
7744 * aggregated route announcements.
7745 *
7746 * MED matching:
7747 * Don't create summaries if MED didn't match
7748 * otherwise neither the specific routes and the
7749 * aggregation will be announced.
7750 */
7751 if (aggregate->summary_only
7752 && AGGREGATE_MED_VALID(aggregate)) {
7753 if (aggr_suppress_path(aggregate, pi))
7754 match++;
7755 }
7756
7757 /*
7758 * Suppress more specific routes that match the route
7759 * map results.
7760 *
7761 * MED matching:
7762 * Don't suppress routes if MED matching is enabled and
7763 * it mismatched otherwise we might end up with no
7764 * routes for this path.
7765 */
7766 if (aggregate->suppress_map_name
7767 && AGGREGATE_MED_VALID(aggregate)
7768 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7769 if (aggr_suppress_path(aggregate, pi))
7770 match++;
7771 }
7772
7773 aggregate->count++;
7774
7775 /*
7776 * If at least one route among routes that are
7777 * aggregated has ORIGIN with the value INCOMPLETE,
7778 * then the aggregated route MUST have the ORIGIN
7779 * attribute with the value INCOMPLETE. Otherwise, if
7780 * at least one route among routes that are aggregated
7781 * has ORIGIN with the value EGP, then the aggregated
7782 * route MUST have the ORIGIN attribute with the value
7783 * EGP.
7784 */
7785 switch (pi->attr->origin) {
7786 case BGP_ORIGIN_INCOMPLETE:
7787 aggregate->incomplete_origin_count++;
7788 break;
7789 case BGP_ORIGIN_EGP:
7790 aggregate->egp_origin_count++;
7791 break;
7792 default:
7793 /*Do nothing.
7794 */
7795 break;
7796 }
7797
7798 if (!aggregate->as_set)
7799 continue;
7800
7801 /*
7802 * as-set aggregate route generate origin, as path,
7803 * and community aggregation.
7804 */
7805 /* Compute aggregate route's as-path.
7806 */
7807 bgp_compute_aggregate_aspath_hash(aggregate,
7808 pi->attr->aspath);
7809
7810 /* Compute aggregate route's community.
7811 */
7812 if (bgp_attr_get_community(pi->attr))
7813 bgp_compute_aggregate_community_hash(
7814 aggregate,
7815 bgp_attr_get_community(pi->attr));
7816
7817 /* Compute aggregate route's extended community.
7818 */
7819 if (bgp_attr_get_ecommunity(pi->attr))
7820 bgp_compute_aggregate_ecommunity_hash(
7821 aggregate,
7822 bgp_attr_get_ecommunity(pi->attr));
7823
7824 /* Compute aggregate route's large community.
7825 */
7826 if (bgp_attr_get_lcommunity(pi->attr))
7827 bgp_compute_aggregate_lcommunity_hash(
7828 aggregate,
7829 bgp_attr_get_lcommunity(pi->attr));
7830 }
7831 if (match)
7832 bgp_process(bgp, dest, afi, safi);
7833 }
7834 if (aggregate->as_set) {
7835 bgp_compute_aggregate_aspath_val(aggregate);
7836 bgp_compute_aggregate_community_val(aggregate);
7837 bgp_compute_aggregate_ecommunity_val(aggregate);
7838 bgp_compute_aggregate_lcommunity_val(aggregate);
7839 }
7840
7841
7842 bgp_dest_unlock_node(top);
7843
7844
7845 if (aggregate->incomplete_origin_count > 0)
7846 origin = BGP_ORIGIN_INCOMPLETE;
7847 else if (aggregate->egp_origin_count > 0)
7848 origin = BGP_ORIGIN_EGP;
7849
7850 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7851 origin = aggregate->origin;
7852
7853 if (aggregate->as_set) {
7854 if (aggregate->aspath)
7855 /* Retrieve aggregate route's as-path.
7856 */
7857 aspath = aspath_dup(aggregate->aspath);
7858
7859 if (aggregate->community)
7860 /* Retrieve aggregate route's community.
7861 */
7862 community = community_dup(aggregate->community);
7863
7864 if (aggregate->ecommunity)
7865 /* Retrieve aggregate route's ecommunity.
7866 */
7867 ecommunity = ecommunity_dup(aggregate->ecommunity);
7868
7869 if (aggregate->lcommunity)
7870 /* Retrieve aggregate route's lcommunity.
7871 */
7872 lcommunity = lcommunity_dup(aggregate->lcommunity);
7873 }
7874
7875 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7876 ecommunity, lcommunity, atomic_aggregate,
7877 aggregate);
7878
7879 return true;
7880 }
7881
7882 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7883 safi_t safi, struct bgp_aggregate *aggregate)
7884 {
7885 struct bgp_table *table;
7886 struct bgp_dest *top;
7887 struct bgp_dest *dest;
7888 struct bgp_path_info *pi;
7889 unsigned long match;
7890
7891 table = bgp->rib[afi][safi];
7892
7893 /* If routes exists below this node, generate aggregate routes. */
7894 top = bgp_node_get(table, p);
7895 for (dest = bgp_node_get(table, p); dest;
7896 dest = bgp_route_next_until(dest, top)) {
7897 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7898
7899 if (dest_p->prefixlen <= p->prefixlen)
7900 continue;
7901 match = 0;
7902
7903 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7904 if (BGP_PATH_HOLDDOWN(pi))
7905 continue;
7906
7907 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7908 continue;
7909
7910 /*
7911 * This route is suppressed: attempt to unsuppress it.
7912 *
7913 * `aggr_unsuppress_path` will fail if this particular
7914 * aggregate route was not the suppressor.
7915 */
7916 if (pi->extra && pi->extra->aggr_suppressors &&
7917 listcount(pi->extra->aggr_suppressors)) {
7918 if (aggr_unsuppress_path(aggregate, pi))
7919 match++;
7920 }
7921
7922 aggregate->count--;
7923
7924 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7925 aggregate->incomplete_origin_count--;
7926 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7927 aggregate->egp_origin_count--;
7928
7929 if (aggregate->as_set) {
7930 /* Remove as-path from aggregate.
7931 */
7932 bgp_remove_aspath_from_aggregate_hash(
7933 aggregate,
7934 pi->attr->aspath);
7935
7936 if (bgp_attr_get_community(pi->attr))
7937 /* Remove community from aggregate.
7938 */
7939 bgp_remove_comm_from_aggregate_hash(
7940 aggregate,
7941 bgp_attr_get_community(
7942 pi->attr));
7943
7944 if (bgp_attr_get_ecommunity(pi->attr))
7945 /* Remove ecommunity from aggregate.
7946 */
7947 bgp_remove_ecomm_from_aggregate_hash(
7948 aggregate,
7949 bgp_attr_get_ecommunity(
7950 pi->attr));
7951
7952 if (bgp_attr_get_lcommunity(pi->attr))
7953 /* Remove lcommunity from aggregate.
7954 */
7955 bgp_remove_lcomm_from_aggregate_hash(
7956 aggregate,
7957 bgp_attr_get_lcommunity(
7958 pi->attr));
7959 }
7960 }
7961
7962 /* If this node was suppressed, process the change. */
7963 if (match)
7964 bgp_process(bgp, dest, afi, safi);
7965 }
7966 if (aggregate->as_set) {
7967 aspath_free(aggregate->aspath);
7968 aggregate->aspath = NULL;
7969 if (aggregate->community)
7970 community_free(&aggregate->community);
7971 if (aggregate->ecommunity)
7972 ecommunity_free(&aggregate->ecommunity);
7973 if (aggregate->lcommunity)
7974 lcommunity_free(&aggregate->lcommunity);
7975 }
7976
7977 bgp_dest_unlock_node(top);
7978 }
7979
7980 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7981 const struct prefix *aggr_p,
7982 struct bgp_path_info *pinew, afi_t afi,
7983 safi_t safi,
7984 struct bgp_aggregate *aggregate)
7985 {
7986 uint8_t origin;
7987 struct aspath *aspath = NULL;
7988 uint8_t atomic_aggregate = 0;
7989 struct community *community = NULL;
7990 struct ecommunity *ecommunity = NULL;
7991 struct lcommunity *lcommunity = NULL;
7992
7993 /* If the bgp instance is being deleted or self peer is deleted
7994 * then do not create aggregate route
7995 */
7996 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7997 || (bgp->peer_self == NULL))
7998 return;
7999
8000 /* ORIGIN attribute: If at least one route among routes that are
8001 * aggregated has ORIGIN with the value INCOMPLETE, then the
8002 * aggregated route must have the ORIGIN attribute with the value
8003 * INCOMPLETE. Otherwise, if at least one route among routes that
8004 * are aggregated has ORIGIN with the value EGP, then the aggregated
8005 * route must have the origin attribute with the value EGP. In all
8006 * other case the value of the ORIGIN attribute of the aggregated
8007 * route is INTERNAL.
8008 */
8009 origin = BGP_ORIGIN_IGP;
8010
8011 aggregate->count++;
8012
8013 /*
8014 * This must be called before `summary` check to avoid
8015 * "suppressing" twice.
8016 */
8017 if (aggregate->match_med)
8018 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8019 pinew);
8020
8021 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8022 aggr_suppress_path(aggregate, pinew);
8023
8024 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8025 && aggr_suppress_map_test(bgp, aggregate, pinew))
8026 aggr_suppress_path(aggregate, pinew);
8027
8028 switch (pinew->attr->origin) {
8029 case BGP_ORIGIN_INCOMPLETE:
8030 aggregate->incomplete_origin_count++;
8031 break;
8032 case BGP_ORIGIN_EGP:
8033 aggregate->egp_origin_count++;
8034 break;
8035 default:
8036 /* Do nothing.
8037 */
8038 break;
8039 }
8040
8041 if (aggregate->incomplete_origin_count > 0)
8042 origin = BGP_ORIGIN_INCOMPLETE;
8043 else if (aggregate->egp_origin_count > 0)
8044 origin = BGP_ORIGIN_EGP;
8045
8046 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8047 origin = aggregate->origin;
8048
8049 if (aggregate->as_set) {
8050 /* Compute aggregate route's as-path.
8051 */
8052 bgp_compute_aggregate_aspath(aggregate,
8053 pinew->attr->aspath);
8054
8055 /* Compute aggregate route's community.
8056 */
8057 if (bgp_attr_get_community(pinew->attr))
8058 bgp_compute_aggregate_community(
8059 aggregate, bgp_attr_get_community(pinew->attr));
8060
8061 /* Compute aggregate route's extended community.
8062 */
8063 if (bgp_attr_get_ecommunity(pinew->attr))
8064 bgp_compute_aggregate_ecommunity(
8065 aggregate,
8066 bgp_attr_get_ecommunity(pinew->attr));
8067
8068 /* Compute aggregate route's large community.
8069 */
8070 if (bgp_attr_get_lcommunity(pinew->attr))
8071 bgp_compute_aggregate_lcommunity(
8072 aggregate,
8073 bgp_attr_get_lcommunity(pinew->attr));
8074
8075 /* Retrieve aggregate route's as-path.
8076 */
8077 if (aggregate->aspath)
8078 aspath = aspath_dup(aggregate->aspath);
8079
8080 /* Retrieve aggregate route's community.
8081 */
8082 if (aggregate->community)
8083 community = community_dup(aggregate->community);
8084
8085 /* Retrieve aggregate route's ecommunity.
8086 */
8087 if (aggregate->ecommunity)
8088 ecommunity = ecommunity_dup(aggregate->ecommunity);
8089
8090 /* Retrieve aggregate route's lcommunity.
8091 */
8092 if (aggregate->lcommunity)
8093 lcommunity = lcommunity_dup(aggregate->lcommunity);
8094 }
8095
8096 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8097 aspath, community, ecommunity,
8098 lcommunity, atomic_aggregate, aggregate);
8099 }
8100
8101 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8102 safi_t safi,
8103 struct bgp_path_info *pi,
8104 struct bgp_aggregate *aggregate,
8105 const struct prefix *aggr_p)
8106 {
8107 uint8_t origin;
8108 struct aspath *aspath = NULL;
8109 uint8_t atomic_aggregate = 0;
8110 struct community *community = NULL;
8111 struct ecommunity *ecommunity = NULL;
8112 struct lcommunity *lcommunity = NULL;
8113 unsigned long match = 0;
8114
8115 /* If the bgp instance is being deleted or self peer is deleted
8116 * then do not create aggregate route
8117 */
8118 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8119 || (bgp->peer_self == NULL))
8120 return;
8121
8122 if (BGP_PATH_HOLDDOWN(pi))
8123 return;
8124
8125 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8126 return;
8127
8128 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8129 if (aggr_unsuppress_path(aggregate, pi))
8130 match++;
8131
8132 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8133 && aggr_suppress_map_test(bgp, aggregate, pi))
8134 if (aggr_unsuppress_path(aggregate, pi))
8135 match++;
8136
8137 /*
8138 * This must be called after `summary`, `suppress-map` check to avoid
8139 * "unsuppressing" twice.
8140 */
8141 if (aggregate->match_med)
8142 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8143
8144 if (aggregate->count > 0)
8145 aggregate->count--;
8146
8147 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8148 aggregate->incomplete_origin_count--;
8149 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8150 aggregate->egp_origin_count--;
8151
8152 if (aggregate->as_set) {
8153 /* Remove as-path from aggregate.
8154 */
8155 bgp_remove_aspath_from_aggregate(aggregate,
8156 pi->attr->aspath);
8157
8158 if (bgp_attr_get_community(pi->attr))
8159 /* Remove community from aggregate.
8160 */
8161 bgp_remove_community_from_aggregate(
8162 aggregate, bgp_attr_get_community(pi->attr));
8163
8164 if (bgp_attr_get_ecommunity(pi->attr))
8165 /* Remove ecommunity from aggregate.
8166 */
8167 bgp_remove_ecommunity_from_aggregate(
8168 aggregate, bgp_attr_get_ecommunity(pi->attr));
8169
8170 if (bgp_attr_get_lcommunity(pi->attr))
8171 /* Remove lcommunity from aggregate.
8172 */
8173 bgp_remove_lcommunity_from_aggregate(
8174 aggregate, bgp_attr_get_lcommunity(pi->attr));
8175 }
8176
8177 /* If this node was suppressed, process the change. */
8178 if (match)
8179 bgp_process(bgp, pi->net, afi, safi);
8180
8181 origin = BGP_ORIGIN_IGP;
8182 if (aggregate->incomplete_origin_count > 0)
8183 origin = BGP_ORIGIN_INCOMPLETE;
8184 else if (aggregate->egp_origin_count > 0)
8185 origin = BGP_ORIGIN_EGP;
8186
8187 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8188 origin = aggregate->origin;
8189
8190 if (aggregate->as_set) {
8191 /* Retrieve aggregate route's as-path.
8192 */
8193 if (aggregate->aspath)
8194 aspath = aspath_dup(aggregate->aspath);
8195
8196 /* Retrieve aggregate route's community.
8197 */
8198 if (aggregate->community)
8199 community = community_dup(aggregate->community);
8200
8201 /* Retrieve aggregate route's ecommunity.
8202 */
8203 if (aggregate->ecommunity)
8204 ecommunity = ecommunity_dup(aggregate->ecommunity);
8205
8206 /* Retrieve aggregate route's lcommunity.
8207 */
8208 if (aggregate->lcommunity)
8209 lcommunity = lcommunity_dup(aggregate->lcommunity);
8210 }
8211
8212 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8213 aspath, community, ecommunity,
8214 lcommunity, atomic_aggregate, aggregate);
8215 }
8216
8217 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8218 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8219 {
8220 struct bgp_dest *child;
8221 struct bgp_dest *dest;
8222 struct bgp_aggregate *aggregate;
8223 struct bgp_table *table;
8224
8225 table = bgp->aggregate[afi][safi];
8226
8227 /* No aggregates configured. */
8228 if (bgp_table_top_nolock(table) == NULL)
8229 return;
8230
8231 if (p->prefixlen == 0)
8232 return;
8233
8234 if (BGP_PATH_HOLDDOWN(pi))
8235 return;
8236
8237 /* If suppress fib is enabled and route not installed
8238 * in FIB, do not update the aggregate route
8239 */
8240 if (!bgp_check_advertise(bgp, pi->net))
8241 return;
8242
8243 child = bgp_node_get(table, p);
8244
8245 /* Aggregate address configuration check. */
8246 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8247 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8248
8249 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8250 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8251 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8252 aggregate);
8253 }
8254 }
8255 bgp_dest_unlock_node(child);
8256 }
8257
8258 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8259 struct bgp_path_info *del, afi_t afi, safi_t safi)
8260 {
8261 struct bgp_dest *child;
8262 struct bgp_dest *dest;
8263 struct bgp_aggregate *aggregate;
8264 struct bgp_table *table;
8265
8266 table = bgp->aggregate[afi][safi];
8267
8268 /* No aggregates configured. */
8269 if (bgp_table_top_nolock(table) == NULL)
8270 return;
8271
8272 if (p->prefixlen == 0)
8273 return;
8274
8275 child = bgp_node_get(table, p);
8276
8277 /* Aggregate address configuration check. */
8278 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8279 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8280
8281 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8282 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8283 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8284 aggregate, dest_p);
8285 }
8286 }
8287 bgp_dest_unlock_node(child);
8288 }
8289
8290 /* Aggregate route attribute. */
8291 #define AGGREGATE_SUMMARY_ONLY 1
8292 #define AGGREGATE_AS_SET 1
8293 #define AGGREGATE_AS_UNSET 0
8294
8295 static const char *bgp_origin2str(uint8_t origin)
8296 {
8297 switch (origin) {
8298 case BGP_ORIGIN_IGP:
8299 return "igp";
8300 case BGP_ORIGIN_EGP:
8301 return "egp";
8302 case BGP_ORIGIN_INCOMPLETE:
8303 return "incomplete";
8304 }
8305 return "n/a";
8306 }
8307
8308 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8309 {
8310 switch (v_state) {
8311 case RPKI_NOT_BEING_USED:
8312 return "not used";
8313 case RPKI_VALID:
8314 return "valid";
8315 case RPKI_NOTFOUND:
8316 return "not found";
8317 case RPKI_INVALID:
8318 return "invalid";
8319 }
8320
8321 assert(!"We should never get here this is a dev escape");
8322 return "ERROR";
8323 }
8324
8325 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8326 afi_t afi, safi_t safi)
8327 {
8328 VTY_DECLVAR_CONTEXT(bgp, bgp);
8329 int ret;
8330 struct prefix p;
8331 struct bgp_dest *dest;
8332 struct bgp_aggregate *aggregate;
8333
8334 /* Convert string to prefix structure. */
8335 ret = str2prefix(prefix_str, &p);
8336 if (!ret) {
8337 vty_out(vty, "Malformed prefix\n");
8338 return CMD_WARNING_CONFIG_FAILED;
8339 }
8340 apply_mask(&p);
8341
8342 /* Old configuration check. */
8343 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8344 if (!dest) {
8345 vty_out(vty,
8346 "%% There is no aggregate-address configuration.\n");
8347 return CMD_WARNING_CONFIG_FAILED;
8348 }
8349
8350 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8351 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8352 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8353 NULL, NULL, 0, aggregate);
8354
8355 /* Unlock aggregate address configuration. */
8356 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8357
8358 bgp_free_aggregate_info(aggregate);
8359 bgp_dest_unlock_node(dest);
8360 bgp_dest_unlock_node(dest);
8361
8362 return CMD_SUCCESS;
8363 }
8364
8365 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8366 safi_t safi, const char *rmap,
8367 uint8_t summary_only, uint8_t as_set,
8368 uint8_t origin, bool match_med,
8369 const char *suppress_map)
8370 {
8371 VTY_DECLVAR_CONTEXT(bgp, bgp);
8372 int ret;
8373 struct prefix p;
8374 struct bgp_dest *dest;
8375 struct bgp_aggregate *aggregate;
8376 uint8_t as_set_new = as_set;
8377
8378 if (suppress_map && summary_only) {
8379 vty_out(vty,
8380 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8381 return CMD_WARNING_CONFIG_FAILED;
8382 }
8383
8384 /* Convert string to prefix structure. */
8385 ret = str2prefix(prefix_str, &p);
8386 if (!ret) {
8387 vty_out(vty, "Malformed prefix\n");
8388 return CMD_WARNING_CONFIG_FAILED;
8389 }
8390 apply_mask(&p);
8391
8392 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8393 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8394 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8395 prefix_str);
8396 return CMD_WARNING_CONFIG_FAILED;
8397 }
8398
8399 /* Old configuration check. */
8400 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8401 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8402
8403 if (aggregate) {
8404 vty_out(vty, "There is already same aggregate network.\n");
8405 /* try to remove the old entry */
8406 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8407 if (ret) {
8408 vty_out(vty, "Error deleting aggregate.\n");
8409 bgp_dest_unlock_node(dest);
8410 return CMD_WARNING_CONFIG_FAILED;
8411 }
8412 }
8413
8414 /* Make aggregate address structure. */
8415 aggregate = bgp_aggregate_new();
8416 aggregate->summary_only = summary_only;
8417 aggregate->match_med = match_med;
8418
8419 /* Network operators MUST NOT locally generate any new
8420 * announcements containing AS_SET or AS_CONFED_SET. If they have
8421 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8422 * SHOULD withdraw those routes and re-announce routes for the
8423 * aggregate or component prefixes (i.e., the more-specific routes
8424 * subsumed by the previously aggregated route) without AS_SET
8425 * or AS_CONFED_SET in the updates.
8426 */
8427 if (bgp->reject_as_sets) {
8428 if (as_set == AGGREGATE_AS_SET) {
8429 as_set_new = AGGREGATE_AS_UNSET;
8430 zlog_warn(
8431 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8432 __func__);
8433 vty_out(vty,
8434 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8435 }
8436 }
8437
8438 aggregate->as_set = as_set_new;
8439 aggregate->safi = safi;
8440 /* Override ORIGIN attribute if defined.
8441 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8442 * to IGP which is not what rfc4271 says.
8443 * This enables the same behavior, optionally.
8444 */
8445 aggregate->origin = origin;
8446
8447 if (rmap) {
8448 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8449 route_map_counter_decrement(aggregate->rmap.map);
8450 aggregate->rmap.name =
8451 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8452 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8453 route_map_counter_increment(aggregate->rmap.map);
8454 }
8455
8456 if (suppress_map) {
8457 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8458 route_map_counter_decrement(aggregate->suppress_map);
8459
8460 aggregate->suppress_map_name =
8461 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8462 aggregate->suppress_map =
8463 route_map_lookup_by_name(aggregate->suppress_map_name);
8464 route_map_counter_increment(aggregate->suppress_map);
8465 }
8466
8467 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8468
8469 /* Aggregate address insert into BGP routing table. */
8470 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8471 bgp_aggregate_free(aggregate);
8472 bgp_dest_unlock_node(dest);
8473 }
8474
8475 return CMD_SUCCESS;
8476 }
8477
8478 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8479 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8480 "as-set$as_set_s"
8481 "|summary-only$summary_only"
8482 "|route-map RMAP_NAME$rmap_name"
8483 "|origin <egp|igp|incomplete>$origin_s"
8484 "|matching-MED-only$match_med"
8485 "|suppress-map RMAP_NAME$suppress_map"
8486 "}]",
8487 NO_STR
8488 "Configure BGP aggregate entries\n"
8489 "Aggregate prefix\n"
8490 "Aggregate address\n"
8491 "Aggregate mask\n"
8492 "Generate AS set path information\n"
8493 "Filter more specific routes from updates\n"
8494 "Apply route map to aggregate network\n"
8495 "Route map name\n"
8496 "BGP origin code\n"
8497 "Remote EGP\n"
8498 "Local IGP\n"
8499 "Unknown heritage\n"
8500 "Only aggregate routes with matching MED\n"
8501 "Suppress the selected more specific routes\n"
8502 "Route map with the route selectors\n")
8503 {
8504 const char *prefix_s = NULL;
8505 safi_t safi = bgp_node_safi(vty);
8506 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8507 int as_set = AGGREGATE_AS_UNSET;
8508 char prefix_buf[PREFIX2STR_BUFFER];
8509
8510 if (addr_str) {
8511 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8512 sizeof(prefix_buf))
8513 == 0) {
8514 vty_out(vty, "%% Inconsistent address and mask\n");
8515 return CMD_WARNING_CONFIG_FAILED;
8516 }
8517 prefix_s = prefix_buf;
8518 } else
8519 prefix_s = prefix_str;
8520
8521 if (origin_s) {
8522 if (strcmp(origin_s, "egp") == 0)
8523 origin = BGP_ORIGIN_EGP;
8524 else if (strcmp(origin_s, "igp") == 0)
8525 origin = BGP_ORIGIN_IGP;
8526 else if (strcmp(origin_s, "incomplete") == 0)
8527 origin = BGP_ORIGIN_INCOMPLETE;
8528 }
8529
8530 if (as_set_s)
8531 as_set = AGGREGATE_AS_SET;
8532
8533 /* Handle configuration removal, otherwise installation. */
8534 if (no)
8535 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8536
8537 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8538 summary_only != NULL, as_set, origin,
8539 match_med != NULL, suppress_map);
8540 }
8541
8542 void bgp_free_aggregate_info(struct bgp_aggregate *aggregate)
8543 {
8544 if (aggregate->community)
8545 community_free(&aggregate->community);
8546
8547 hash_clean_and_free(&aggregate->community_hash,
8548 bgp_aggr_community_remove);
8549
8550 if (aggregate->ecommunity)
8551 ecommunity_free(&aggregate->ecommunity);
8552
8553 hash_clean_and_free(&aggregate->ecommunity_hash,
8554 bgp_aggr_ecommunity_remove);
8555
8556 if (aggregate->lcommunity)
8557 lcommunity_free(&aggregate->lcommunity);
8558
8559 hash_clean_and_free(&aggregate->lcommunity_hash,
8560 bgp_aggr_lcommunity_remove);
8561
8562 if (aggregate->aspath)
8563 aspath_free(aggregate->aspath);
8564
8565 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8566
8567 bgp_aggregate_free(aggregate);
8568 }
8569
8570 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8571 "[no] aggregate-address X:X::X:X/M$prefix [{"
8572 "as-set$as_set_s"
8573 "|summary-only$summary_only"
8574 "|route-map RMAP_NAME$rmap_name"
8575 "|origin <egp|igp|incomplete>$origin_s"
8576 "|matching-MED-only$match_med"
8577 "|suppress-map RMAP_NAME$suppress_map"
8578 "}]",
8579 NO_STR
8580 "Configure BGP aggregate entries\n"
8581 "Aggregate prefix\n"
8582 "Generate AS set path information\n"
8583 "Filter more specific routes from updates\n"
8584 "Apply route map to aggregate network\n"
8585 "Route map name\n"
8586 "BGP origin code\n"
8587 "Remote EGP\n"
8588 "Local IGP\n"
8589 "Unknown heritage\n"
8590 "Only aggregate routes with matching MED\n"
8591 "Suppress the selected more specific routes\n"
8592 "Route map with the route selectors\n")
8593 {
8594 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8595 int as_set = AGGREGATE_AS_UNSET;
8596
8597 if (origin_s) {
8598 if (strcmp(origin_s, "egp") == 0)
8599 origin = BGP_ORIGIN_EGP;
8600 else if (strcmp(origin_s, "igp") == 0)
8601 origin = BGP_ORIGIN_IGP;
8602 else if (strcmp(origin_s, "incomplete") == 0)
8603 origin = BGP_ORIGIN_INCOMPLETE;
8604 }
8605
8606 if (as_set_s)
8607 as_set = AGGREGATE_AS_SET;
8608
8609 /* Handle configuration removal, otherwise installation. */
8610 if (no)
8611 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8612 SAFI_UNICAST);
8613
8614 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8615 rmap_name, summary_only != NULL, as_set,
8616 origin, match_med != NULL, suppress_map);
8617 }
8618
8619 /* Redistribute route treatment. */
8620 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8621 const union g_addr *nexthop, ifindex_t ifindex,
8622 enum nexthop_types_t nhtype, uint8_t distance,
8623 enum blackhole_type bhtype, uint32_t metric,
8624 uint8_t type, unsigned short instance,
8625 route_tag_t tag)
8626 {
8627 struct bgp_path_info *new;
8628 struct bgp_path_info *bpi;
8629 struct bgp_path_info rmap_path;
8630 struct bgp_dest *bn;
8631 struct attr attr;
8632 struct attr *new_attr;
8633 afi_t afi;
8634 route_map_result_t ret;
8635 struct bgp_redist *red;
8636
8637 /* Make default attribute. */
8638 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8639 /*
8640 * This must not be NULL to satisfy Coverity SA
8641 */
8642 assert(attr.aspath);
8643
8644 switch (nhtype) {
8645 case NEXTHOP_TYPE_IFINDEX:
8646 switch (p->family) {
8647 case AF_INET:
8648 attr.nexthop.s_addr = INADDR_ANY;
8649 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8650 break;
8651 case AF_INET6:
8652 memset(&attr.mp_nexthop_global, 0,
8653 sizeof(attr.mp_nexthop_global));
8654 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8655 break;
8656 }
8657 break;
8658 case NEXTHOP_TYPE_IPV4:
8659 case NEXTHOP_TYPE_IPV4_IFINDEX:
8660 attr.nexthop = nexthop->ipv4;
8661 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8662 break;
8663 case NEXTHOP_TYPE_IPV6:
8664 case NEXTHOP_TYPE_IPV6_IFINDEX:
8665 attr.mp_nexthop_global = nexthop->ipv6;
8666 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8667 break;
8668 case NEXTHOP_TYPE_BLACKHOLE:
8669 switch (p->family) {
8670 case AF_INET:
8671 attr.nexthop.s_addr = INADDR_ANY;
8672 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8673 break;
8674 case AF_INET6:
8675 memset(&attr.mp_nexthop_global, 0,
8676 sizeof(attr.mp_nexthop_global));
8677 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8678 break;
8679 }
8680 attr.bh_type = bhtype;
8681 break;
8682 }
8683 attr.nh_type = nhtype;
8684 attr.nh_ifindex = ifindex;
8685
8686 attr.med = metric;
8687 attr.distance = distance;
8688 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8689 attr.tag = tag;
8690
8691 if (metric)
8692 bgp_attr_set_aigp_metric(&attr, metric);
8693
8694 afi = family2afi(p->family);
8695
8696 red = bgp_redist_lookup(bgp, afi, type, instance);
8697 if (red) {
8698 struct attr attr_new;
8699
8700 /* Copy attribute for modification. */
8701 attr_new = attr;
8702
8703 if (red->redist_metric_flag) {
8704 attr_new.med = red->redist_metric;
8705 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8706 }
8707
8708 /* Apply route-map. */
8709 if (red->rmap.name) {
8710 memset(&rmap_path, 0, sizeof(rmap_path));
8711 rmap_path.peer = bgp->peer_self;
8712 rmap_path.attr = &attr_new;
8713
8714 SET_FLAG(bgp->peer_self->rmap_type,
8715 PEER_RMAP_TYPE_REDISTRIBUTE);
8716
8717 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8718
8719 bgp->peer_self->rmap_type = 0;
8720
8721 if (ret == RMAP_DENYMATCH) {
8722 /* Free uninterned attribute. */
8723 bgp_attr_flush(&attr_new);
8724
8725 /* Unintern original. */
8726 aspath_unintern(&attr.aspath);
8727 bgp_redistribute_delete(bgp, p, type, instance);
8728 return;
8729 }
8730 }
8731
8732 if (bgp_in_graceful_shutdown(bgp))
8733 bgp_attr_add_gshut_community(&attr_new);
8734
8735 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8736 SAFI_UNICAST, p, NULL);
8737
8738 new_attr = bgp_attr_intern(&attr_new);
8739
8740 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8741 if (bpi->peer == bgp->peer_self
8742 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8743 break;
8744
8745 if (bpi) {
8746 /* Ensure the (source route) type is updated. */
8747 bpi->type = type;
8748 if (attrhash_cmp(bpi->attr, new_attr)
8749 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8750 bgp_attr_unintern(&new_attr);
8751 aspath_unintern(&attr.aspath);
8752 bgp_dest_unlock_node(bn);
8753 return;
8754 } else {
8755 /* The attribute is changed. */
8756 bgp_path_info_set_flag(bn, bpi,
8757 BGP_PATH_ATTR_CHANGED);
8758
8759 /* Rewrite BGP route information. */
8760 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8761 bgp_path_info_restore(bn, bpi);
8762 else
8763 bgp_aggregate_decrement(
8764 bgp, p, bpi, afi, SAFI_UNICAST);
8765 bgp_attr_unintern(&bpi->attr);
8766 bpi->attr = new_attr;
8767 bpi->uptime = monotime(NULL);
8768
8769 /* Process change. */
8770 bgp_aggregate_increment(bgp, p, bpi, afi,
8771 SAFI_UNICAST);
8772 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8773 bgp_dest_unlock_node(bn);
8774 aspath_unintern(&attr.aspath);
8775
8776 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8777 || (bgp->inst_type
8778 == BGP_INSTANCE_TYPE_DEFAULT)) {
8779
8780 vpn_leak_from_vrf_update(
8781 bgp_get_default(), bgp, bpi);
8782 }
8783 return;
8784 }
8785 }
8786
8787 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8788 bgp->peer_self, new_attr, bn);
8789 SET_FLAG(new->flags, BGP_PATH_VALID);
8790
8791 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8792 bgp_path_info_add(bn, new);
8793 bgp_dest_unlock_node(bn);
8794 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8795 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8796
8797 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8798 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8799
8800 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8801 }
8802 }
8803
8804 /* Unintern original. */
8805 aspath_unintern(&attr.aspath);
8806 }
8807
8808 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8809 unsigned short instance)
8810 {
8811 afi_t afi;
8812 struct bgp_dest *dest;
8813 struct bgp_path_info *pi;
8814 struct bgp_redist *red;
8815
8816 afi = family2afi(p->family);
8817
8818 red = bgp_redist_lookup(bgp, afi, type, instance);
8819 if (red) {
8820 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8821 SAFI_UNICAST, p, NULL);
8822
8823 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8824 if (pi->peer == bgp->peer_self && pi->type == type)
8825 break;
8826
8827 if (pi) {
8828 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8829 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8830
8831 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8832 bgp, pi);
8833 }
8834 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8835 bgp_path_info_delete(dest, pi);
8836 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8837 }
8838 bgp_dest_unlock_node(dest);
8839 }
8840 }
8841
8842 /* Withdraw specified route type's route. */
8843 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8844 unsigned short instance)
8845 {
8846 struct bgp_dest *dest;
8847 struct bgp_path_info *pi;
8848 struct bgp_table *table;
8849
8850 table = bgp->rib[afi][SAFI_UNICAST];
8851
8852 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8853 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8854 if (pi->peer == bgp->peer_self && pi->type == type
8855 && pi->instance == instance)
8856 break;
8857
8858 if (pi) {
8859 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8860 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8861
8862 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8863 bgp, pi);
8864 }
8865 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8866 pi, afi, SAFI_UNICAST);
8867 bgp_path_info_delete(dest, pi);
8868 if (!CHECK_FLAG(bgp->flags,
8869 BGP_FLAG_DELETE_IN_PROGRESS))
8870 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8871 else
8872 bgp_path_info_reap(dest, pi);
8873 }
8874 }
8875 }
8876
8877 /* Static function to display route. */
8878 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8879 struct vty *vty, json_object *json, bool wide)
8880 {
8881 int len = 0;
8882 char buf[INET6_ADDRSTRLEN];
8883
8884 if (p->family == AF_INET) {
8885 if (!json) {
8886 len = vty_out(vty, "%pFX", p);
8887 } else {
8888 json_object_string_add(json, "prefix",
8889 inet_ntop(p->family,
8890 &p->u.prefix, buf,
8891 sizeof(buf)));
8892 json_object_int_add(json, "prefixLen", p->prefixlen);
8893 json_object_string_addf(json, "network", "%pFX", p);
8894 json_object_int_add(json, "version", dest->version);
8895 }
8896 } else if (p->family == AF_ETHERNET) {
8897 len = vty_out(vty, "%pFX", p);
8898 } else if (p->family == AF_EVPN) {
8899 if (!json)
8900 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8901 else
8902 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8903 } else if (p->family == AF_FLOWSPEC) {
8904 route_vty_out_flowspec(vty, p, NULL,
8905 json ?
8906 NLRI_STRING_FORMAT_JSON_SIMPLE :
8907 NLRI_STRING_FORMAT_MIN, json);
8908 } else {
8909 if (!json)
8910 len = vty_out(vty, "%pFX", p);
8911 else {
8912 json_object_string_add(json, "prefix",
8913 inet_ntop(p->family,
8914 &p->u.prefix, buf,
8915 sizeof(buf)));
8916 json_object_int_add(json, "prefixLen", p->prefixlen);
8917 json_object_string_addf(json, "network", "%pFX", p);
8918 json_object_int_add(json, "version", dest->version);
8919 }
8920 }
8921
8922 if (!json) {
8923 len = wide ? (45 - len) : (17 - len);
8924 if (len < 1)
8925 vty_out(vty, "\n%*s", 20, " ");
8926 else
8927 vty_out(vty, "%*s", len, " ");
8928 }
8929 }
8930
8931 enum bgp_display_type {
8932 normal_list,
8933 };
8934
8935 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8936 {
8937 switch (reason) {
8938 case bgp_path_selection_none:
8939 return "Nothing to Select";
8940 case bgp_path_selection_first:
8941 return "First path received";
8942 case bgp_path_selection_evpn_sticky_mac:
8943 return "EVPN Sticky Mac";
8944 case bgp_path_selection_evpn_seq:
8945 return "EVPN sequence number";
8946 case bgp_path_selection_evpn_lower_ip:
8947 return "EVPN lower IP";
8948 case bgp_path_selection_evpn_local_path:
8949 return "EVPN local ES path";
8950 case bgp_path_selection_evpn_non_proxy:
8951 return "EVPN non proxy";
8952 case bgp_path_selection_weight:
8953 return "Weight";
8954 case bgp_path_selection_local_pref:
8955 return "Local Pref";
8956 case bgp_path_selection_accept_own:
8957 return "Accept Own";
8958 case bgp_path_selection_local_route:
8959 return "Local Route";
8960 case bgp_path_selection_aigp:
8961 return "AIGP";
8962 case bgp_path_selection_confed_as_path:
8963 return "Confederation based AS Path";
8964 case bgp_path_selection_as_path:
8965 return "AS Path";
8966 case bgp_path_selection_origin:
8967 return "Origin";
8968 case bgp_path_selection_med:
8969 return "MED";
8970 case bgp_path_selection_peer:
8971 return "Peer Type";
8972 case bgp_path_selection_confed:
8973 return "Confed Peer Type";
8974 case bgp_path_selection_igp_metric:
8975 return "IGP Metric";
8976 case bgp_path_selection_older:
8977 return "Older Path";
8978 case bgp_path_selection_router_id:
8979 return "Router ID";
8980 case bgp_path_selection_cluster_length:
8981 return "Cluster length";
8982 case bgp_path_selection_stale:
8983 return "Path Staleness";
8984 case bgp_path_selection_local_configured:
8985 return "Locally configured route";
8986 case bgp_path_selection_neighbor_ip:
8987 return "Neighbor IP";
8988 case bgp_path_selection_default:
8989 return "Nothing left to compare";
8990 }
8991 return "Invalid (internal error)";
8992 }
8993
8994 /* Print the short form route status for a bgp_path_info */
8995 static void route_vty_short_status_out(struct vty *vty,
8996 struct bgp_path_info *path,
8997 const struct prefix *p,
8998 json_object *json_path)
8999 {
9000 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
9001
9002 if (json_path) {
9003
9004 /* Route status display. */
9005 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9006 json_object_boolean_true_add(json_path, "removed");
9007
9008 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9009 json_object_boolean_true_add(json_path, "stale");
9010
9011 if (path->extra && bgp_path_suppressed(path))
9012 json_object_boolean_true_add(json_path, "suppressed");
9013
9014 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9015 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9016 json_object_boolean_true_add(json_path, "valid");
9017
9018 /* Selected */
9019 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9020 json_object_boolean_true_add(json_path, "history");
9021
9022 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9023 json_object_boolean_true_add(json_path, "damped");
9024
9025 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9026 json_object_boolean_true_add(json_path, "bestpath");
9027 json_object_string_add(json_path, "selectionReason",
9028 bgp_path_selection_reason2str(
9029 path->net->reason));
9030 }
9031
9032 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9033 json_object_boolean_true_add(json_path, "multipath");
9034
9035 /* Internal route. */
9036 if ((path->peer->as)
9037 && (path->peer->as == path->peer->local_as))
9038 json_object_string_add(json_path, "pathFrom",
9039 "internal");
9040 else
9041 json_object_string_add(json_path, "pathFrom",
9042 "external");
9043
9044 return;
9045 }
9046
9047 /* RPKI validation state */
9048 rpki_state =
9049 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9050
9051 if (rpki_state == RPKI_VALID)
9052 vty_out(vty, "V");
9053 else if (rpki_state == RPKI_INVALID)
9054 vty_out(vty, "I");
9055 else if (rpki_state == RPKI_NOTFOUND)
9056 vty_out(vty, "N");
9057 else
9058 vty_out(vty, " ");
9059
9060 /* Route status display. */
9061 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9062 vty_out(vty, "R");
9063 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9064 vty_out(vty, "S");
9065 else if (bgp_path_suppressed(path))
9066 vty_out(vty, "s");
9067 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9068 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9069 vty_out(vty, "*");
9070 else
9071 vty_out(vty, " ");
9072
9073 /* Selected */
9074 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9075 vty_out(vty, "h");
9076 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9077 vty_out(vty, "d");
9078 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9079 vty_out(vty, ">");
9080 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9081 vty_out(vty, "=");
9082 else
9083 vty_out(vty, " ");
9084
9085 /* Internal route. */
9086 if (path->peer && (path->peer->as)
9087 && (path->peer->as == path->peer->local_as))
9088 vty_out(vty, "i");
9089 else
9090 vty_out(vty, " ");
9091 }
9092
9093 static char *bgp_nexthop_hostname(struct peer *peer,
9094 struct bgp_nexthop_cache *bnc)
9095 {
9096 if (peer->hostname
9097 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9098 return peer->hostname;
9099 return NULL;
9100 }
9101
9102 /* called from terminal list command */
9103 void route_vty_out(struct vty *vty, const struct prefix *p,
9104 struct bgp_path_info *path, int display, safi_t safi,
9105 json_object *json_paths, bool wide)
9106 {
9107 int len;
9108 struct attr *attr = path->attr;
9109 json_object *json_path = NULL;
9110 json_object *json_nexthops = NULL;
9111 json_object *json_nexthop_global = NULL;
9112 json_object *json_nexthop_ll = NULL;
9113 json_object *json_ext_community = NULL;
9114 char vrf_id_str[VRF_NAMSIZ] = {0};
9115 bool nexthop_self =
9116 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9117 bool nexthop_othervrf = false;
9118 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9119 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9120 char *nexthop_hostname =
9121 bgp_nexthop_hostname(path->peer, path->nexthop);
9122 char esi_buf[ESI_STR_LEN];
9123
9124 if (json_paths)
9125 json_path = json_object_new_object();
9126
9127 /* short status lead text */
9128 route_vty_short_status_out(vty, path, p, json_path);
9129
9130 if (!json_paths) {
9131 /* print prefix and mask */
9132 if (!display)
9133 route_vty_out_route(path->net, p, vty, json_path, wide);
9134 else
9135 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9136 } else {
9137 route_vty_out_route(path->net, p, vty, json_path, wide);
9138 }
9139
9140 /*
9141 * If vrf id of nexthop is different from that of prefix,
9142 * set up printable string to append
9143 */
9144 if (path->extra && path->extra->bgp_orig) {
9145 const char *self = "";
9146
9147 if (nexthop_self)
9148 self = "<";
9149
9150 nexthop_othervrf = true;
9151 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9152
9153 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9154 snprintf(vrf_id_str, sizeof(vrf_id_str),
9155 "@%s%s", VRFID_NONE_STR, self);
9156 else
9157 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9158 path->extra->bgp_orig->vrf_id, self);
9159
9160 if (path->extra->bgp_orig->inst_type
9161 != BGP_INSTANCE_TYPE_DEFAULT)
9162
9163 nexthop_vrfname = path->extra->bgp_orig->name;
9164 } else {
9165 const char *self = "";
9166
9167 if (nexthop_self)
9168 self = "<";
9169
9170 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9171 }
9172
9173 /*
9174 * For ENCAP and EVPN routes, nexthop address family is not
9175 * neccessarily the same as the prefix address family.
9176 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9177 * EVPN routes are also exchanged with a MP nexthop. Currently,
9178 * this
9179 * is only IPv4, the value will be present in either
9180 * attr->nexthop or
9181 * attr->mp_nexthop_global_in
9182 */
9183 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9184 char nexthop[128];
9185 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9186
9187 switch (af) {
9188 case AF_INET:
9189 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9190 &attr->mp_nexthop_global_in);
9191 break;
9192 case AF_INET6:
9193 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9194 &attr->mp_nexthop_global);
9195 break;
9196 default:
9197 snprintf(nexthop, sizeof(nexthop), "?");
9198 break;
9199 }
9200
9201 if (json_paths) {
9202 json_nexthop_global = json_object_new_object();
9203
9204 json_object_string_add(json_nexthop_global, "ip",
9205 nexthop);
9206
9207 if (path->peer->hostname)
9208 json_object_string_add(json_nexthop_global,
9209 "hostname",
9210 path->peer->hostname);
9211
9212 json_object_string_add(json_nexthop_global, "afi",
9213 (af == AF_INET) ? "ipv4"
9214 : "ipv6");
9215 json_object_boolean_true_add(json_nexthop_global,
9216 "used");
9217 } else {
9218 if (nexthop_hostname)
9219 len = vty_out(vty, "%s(%s)%s", nexthop,
9220 nexthop_hostname, vrf_id_str);
9221 else
9222 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9223
9224 len = wide ? (41 - len) : (16 - len);
9225 if (len < 1)
9226 vty_out(vty, "\n%*s", 36, " ");
9227 else
9228 vty_out(vty, "%*s", len, " ");
9229 }
9230 } else if (safi == SAFI_EVPN) {
9231 if (json_paths) {
9232 json_nexthop_global = json_object_new_object();
9233
9234 json_object_string_addf(json_nexthop_global, "ip",
9235 "%pI4",
9236 &attr->mp_nexthop_global_in);
9237
9238 if (path->peer->hostname)
9239 json_object_string_add(json_nexthop_global,
9240 "hostname",
9241 path->peer->hostname);
9242
9243 json_object_string_add(json_nexthop_global, "afi",
9244 "ipv4");
9245 json_object_boolean_true_add(json_nexthop_global,
9246 "used");
9247 } else {
9248 if (nexthop_hostname)
9249 len = vty_out(vty, "%pI4(%s)%s",
9250 &attr->mp_nexthop_global_in,
9251 nexthop_hostname, vrf_id_str);
9252 else
9253 len = vty_out(vty, "%pI4%s",
9254 &attr->mp_nexthop_global_in,
9255 vrf_id_str);
9256
9257 len = wide ? (41 - len) : (16 - len);
9258 if (len < 1)
9259 vty_out(vty, "\n%*s", 36, " ");
9260 else
9261 vty_out(vty, "%*s", len, " ");
9262 }
9263 } else if (safi == SAFI_FLOWSPEC) {
9264 if (attr->nexthop.s_addr != INADDR_ANY) {
9265 if (json_paths) {
9266 json_nexthop_global = json_object_new_object();
9267
9268 json_object_string_add(json_nexthop_global,
9269 "afi", "ipv4");
9270 json_object_string_addf(json_nexthop_global,
9271 "ip", "%pI4",
9272 &attr->nexthop);
9273
9274 if (path->peer->hostname)
9275 json_object_string_add(
9276 json_nexthop_global, "hostname",
9277 path->peer->hostname);
9278
9279 json_object_boolean_true_add(
9280 json_nexthop_global,
9281 "used");
9282 } else {
9283 if (nexthop_hostname)
9284 len = vty_out(vty, "%pI4(%s)%s",
9285 &attr->nexthop,
9286 nexthop_hostname,
9287 vrf_id_str);
9288 else
9289 len = vty_out(vty, "%pI4%s",
9290 &attr->nexthop,
9291 vrf_id_str);
9292
9293 len = wide ? (41 - len) : (16 - len);
9294 if (len < 1)
9295 vty_out(vty, "\n%*s", 36, " ");
9296 else
9297 vty_out(vty, "%*s", len, " ");
9298 }
9299 }
9300 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9301 if (json_paths) {
9302 json_nexthop_global = json_object_new_object();
9303
9304 json_object_string_addf(json_nexthop_global, "ip",
9305 "%pI4", &attr->nexthop);
9306
9307 if (path->peer->hostname)
9308 json_object_string_add(json_nexthop_global,
9309 "hostname",
9310 path->peer->hostname);
9311
9312 json_object_string_add(json_nexthop_global, "afi",
9313 "ipv4");
9314 json_object_boolean_true_add(json_nexthop_global,
9315 "used");
9316 } else {
9317 if (nexthop_hostname)
9318 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9319 nexthop_hostname, vrf_id_str);
9320 else
9321 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9322 vrf_id_str);
9323
9324 len = wide ? (41 - len) : (16 - len);
9325 if (len < 1)
9326 vty_out(vty, "\n%*s", 36, " ");
9327 else
9328 vty_out(vty, "%*s", len, " ");
9329 }
9330 }
9331
9332 /* IPv6 Next Hop */
9333 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9334 if (json_paths) {
9335 json_nexthop_global = json_object_new_object();
9336 json_object_string_addf(json_nexthop_global, "ip",
9337 "%pI6",
9338 &attr->mp_nexthop_global);
9339
9340 if (path->peer->hostname)
9341 json_object_string_add(json_nexthop_global,
9342 "hostname",
9343 path->peer->hostname);
9344
9345 json_object_string_add(json_nexthop_global, "afi",
9346 "ipv6");
9347 json_object_string_add(json_nexthop_global, "scope",
9348 "global");
9349
9350 /* We display both LL & GL if both have been
9351 * received */
9352 if ((attr->mp_nexthop_len
9353 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9354 || (path->peer->conf_if)) {
9355 json_nexthop_ll = json_object_new_object();
9356 json_object_string_addf(
9357 json_nexthop_ll, "ip", "%pI6",
9358 &attr->mp_nexthop_local);
9359
9360 if (path->peer->hostname)
9361 json_object_string_add(
9362 json_nexthop_ll, "hostname",
9363 path->peer->hostname);
9364
9365 json_object_string_add(json_nexthop_ll, "afi",
9366 "ipv6");
9367 json_object_string_add(json_nexthop_ll, "scope",
9368 "link-local");
9369
9370 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9371 &attr->mp_nexthop_local)
9372 != 0)
9373 && !attr->mp_nexthop_prefer_global)
9374 json_object_boolean_true_add(
9375 json_nexthop_ll, "used");
9376 else
9377 json_object_boolean_true_add(
9378 json_nexthop_global, "used");
9379 } else
9380 json_object_boolean_true_add(
9381 json_nexthop_global, "used");
9382 } else {
9383 /* Display LL if LL/Global both in table unless
9384 * prefer-global is set */
9385 if (((attr->mp_nexthop_len
9386 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9387 && !attr->mp_nexthop_prefer_global)
9388 || (path->peer->conf_if)) {
9389 if (path->peer->conf_if) {
9390 len = vty_out(vty, "%s",
9391 path->peer->conf_if);
9392 /* len of IPv6 addr + max len of def
9393 * ifname */
9394 len = wide ? (41 - len) : (16 - len);
9395
9396 if (len < 1)
9397 vty_out(vty, "\n%*s", 36, " ");
9398 else
9399 vty_out(vty, "%*s", len, " ");
9400 } else {
9401 if (nexthop_hostname)
9402 len = vty_out(
9403 vty, "%pI6(%s)%s",
9404 &attr->mp_nexthop_local,
9405 nexthop_hostname,
9406 vrf_id_str);
9407 else
9408 len = vty_out(
9409 vty, "%pI6%s",
9410 &attr->mp_nexthop_local,
9411 vrf_id_str);
9412
9413 len = wide ? (41 - len) : (16 - len);
9414
9415 if (len < 1)
9416 vty_out(vty, "\n%*s", 36, " ");
9417 else
9418 vty_out(vty, "%*s", len, " ");
9419 }
9420 } else {
9421 if (nexthop_hostname)
9422 len = vty_out(vty, "%pI6(%s)%s",
9423 &attr->mp_nexthop_global,
9424 nexthop_hostname,
9425 vrf_id_str);
9426 else
9427 len = vty_out(vty, "%pI6%s",
9428 &attr->mp_nexthop_global,
9429 vrf_id_str);
9430
9431 len = wide ? (41 - len) : (16 - len);
9432
9433 if (len < 1)
9434 vty_out(vty, "\n%*s", 36, " ");
9435 else
9436 vty_out(vty, "%*s", len, " ");
9437 }
9438 }
9439 }
9440
9441 /* MED/Metric */
9442 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9443 if (json_paths)
9444 json_object_int_add(json_path, "metric", attr->med);
9445 else if (wide)
9446 vty_out(vty, "%7u", attr->med);
9447 else
9448 vty_out(vty, "%10u", attr->med);
9449 else if (!json_paths) {
9450 if (wide)
9451 vty_out(vty, "%*s", 7, " ");
9452 else
9453 vty_out(vty, "%*s", 10, " ");
9454 }
9455
9456 /* Local Pref */
9457 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9458 if (json_paths)
9459 json_object_int_add(json_path, "locPrf",
9460 attr->local_pref);
9461 else
9462 vty_out(vty, "%7u", attr->local_pref);
9463 else if (!json_paths)
9464 vty_out(vty, " ");
9465
9466 if (json_paths)
9467 json_object_int_add(json_path, "weight", attr->weight);
9468 else
9469 vty_out(vty, "%7u ", attr->weight);
9470
9471 if (json_paths)
9472 json_object_string_addf(json_path, "peerId", "%pSU",
9473 &path->peer->su);
9474
9475 /* Print aspath */
9476 if (attr->aspath) {
9477 if (json_paths)
9478 json_object_string_add(json_path, "path",
9479 attr->aspath->str);
9480 else
9481 aspath_print_vty(vty, attr->aspath);
9482 }
9483
9484 /* Print origin */
9485 if (json_paths)
9486 json_object_string_add(json_path, "origin",
9487 bgp_origin_long_str[attr->origin]);
9488 else
9489 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9490
9491 if (json_paths) {
9492 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9493 json_object_string_add(json_path, "esi",
9494 esi_to_str(&attr->esi,
9495 esi_buf, sizeof(esi_buf)));
9496 }
9497 if (safi == SAFI_EVPN &&
9498 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9499 json_ext_community = json_object_new_object();
9500 json_object_string_add(
9501 json_ext_community, "string",
9502 bgp_attr_get_ecommunity(attr)->str);
9503 json_object_object_add(json_path,
9504 "extendedCommunity",
9505 json_ext_community);
9506 }
9507
9508 if (nexthop_self)
9509 json_object_boolean_true_add(json_path,
9510 "announceNexthopSelf");
9511 if (nexthop_othervrf) {
9512 json_object_string_add(json_path, "nhVrfName",
9513 nexthop_vrfname);
9514
9515 json_object_int_add(json_path, "nhVrfId",
9516 ((nexthop_vrfid == VRF_UNKNOWN)
9517 ? -1
9518 : (int)nexthop_vrfid));
9519 }
9520 }
9521
9522 if (json_paths) {
9523 if (json_nexthop_global || json_nexthop_ll) {
9524 json_nexthops = json_object_new_array();
9525
9526 if (json_nexthop_global)
9527 json_object_array_add(json_nexthops,
9528 json_nexthop_global);
9529
9530 if (json_nexthop_ll)
9531 json_object_array_add(json_nexthops,
9532 json_nexthop_ll);
9533
9534 json_object_object_add(json_path, "nexthops",
9535 json_nexthops);
9536 }
9537
9538 json_object_array_add(json_paths, json_path);
9539 } else {
9540 vty_out(vty, "\n");
9541
9542 if (safi == SAFI_EVPN) {
9543 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9544 /* XXX - add these params to the json out */
9545 vty_out(vty, "%*s", 20, " ");
9546 vty_out(vty, "ESI:%s",
9547 esi_to_str(&attr->esi, esi_buf,
9548 sizeof(esi_buf)));
9549
9550 vty_out(vty, "\n");
9551 }
9552 if (attr->flag &
9553 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9554 vty_out(vty, "%*s", 20, " ");
9555 vty_out(vty, "%s\n",
9556 bgp_attr_get_ecommunity(attr)->str);
9557 }
9558 }
9559
9560 #ifdef ENABLE_BGP_VNC
9561 /* prints an additional line, indented, with VNC info, if
9562 * present */
9563 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9564 rfapi_vty_out_vncinfo(vty, p, path, safi);
9565 #endif
9566 }
9567 }
9568
9569 /* called from terminal list command */
9570 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9571 const struct prefix *p, struct attr *attr, safi_t safi,
9572 bool use_json, json_object *json_ar, bool wide)
9573 {
9574 json_object *json_status = NULL;
9575 json_object *json_net = NULL;
9576 int len;
9577 char buff[BUFSIZ];
9578
9579 /* Route status display. */
9580 if (use_json) {
9581 json_status = json_object_new_object();
9582 json_net = json_object_new_object();
9583 } else {
9584 vty_out(vty, " *");
9585 vty_out(vty, ">");
9586 vty_out(vty, " ");
9587 }
9588
9589 /* print prefix and mask */
9590 if (use_json) {
9591 if (safi == SAFI_EVPN)
9592 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9593 else if (p->family == AF_INET || p->family == AF_INET6) {
9594 json_object_string_add(
9595 json_net, "addrPrefix",
9596 inet_ntop(p->family, &p->u.prefix, buff,
9597 BUFSIZ));
9598 json_object_int_add(json_net, "prefixLen",
9599 p->prefixlen);
9600 json_object_string_addf(json_net, "network", "%pFX", p);
9601 }
9602 } else
9603 route_vty_out_route(dest, p, vty, NULL, wide);
9604
9605 /* Print attribute */
9606 if (attr) {
9607 if (use_json) {
9608 if (p->family == AF_INET &&
9609 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9610 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9611 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9612 json_object_string_addf(
9613 json_net, "nextHop", "%pI4",
9614 &attr->mp_nexthop_global_in);
9615 else
9616 json_object_string_addf(
9617 json_net, "nextHop", "%pI4",
9618 &attr->nexthop);
9619 } else if (p->family == AF_INET6 ||
9620 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9621 json_object_string_addf(
9622 json_net, "nextHopGlobal", "%pI6",
9623 &attr->mp_nexthop_global);
9624 } else if (p->family == AF_EVPN &&
9625 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9626 json_object_string_addf(
9627 json_net, "nextHop", "%pI4",
9628 &attr->mp_nexthop_global_in);
9629 }
9630
9631 if (attr->flag
9632 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9633 json_object_int_add(json_net, "metric",
9634 attr->med);
9635
9636 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9637 json_object_int_add(json_net, "locPrf",
9638 attr->local_pref);
9639
9640 json_object_int_add(json_net, "weight", attr->weight);
9641
9642 /* Print aspath */
9643 if (attr->aspath)
9644 json_object_string_add(json_net, "path",
9645 attr->aspath->str);
9646
9647 /* Print origin */
9648 #if CONFDATE > 20231208
9649 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9650 #endif
9651 json_object_string_add(json_net, "bgpOriginCode",
9652 bgp_origin_str[attr->origin]);
9653 json_object_string_add(
9654 json_net, "origin",
9655 bgp_origin_long_str[attr->origin]);
9656 } else {
9657 if (p->family == AF_INET &&
9658 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9659 safi == SAFI_EVPN ||
9660 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9661 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9662 || safi == SAFI_EVPN)
9663 vty_out(vty, "%-16pI4",
9664 &attr->mp_nexthop_global_in);
9665 else if (wide)
9666 vty_out(vty, "%-41pI4", &attr->nexthop);
9667 else
9668 vty_out(vty, "%-16pI4", &attr->nexthop);
9669 } else if (p->family == AF_INET6 ||
9670 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9671 len = vty_out(vty, "%pI6",
9672 &attr->mp_nexthop_global);
9673 len = wide ? (41 - len) : (16 - len);
9674 if (len < 1)
9675 vty_out(vty, "\n%*s", 36, " ");
9676 else
9677 vty_out(vty, "%*s", len, " ");
9678 }
9679 if (attr->flag
9680 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9681 if (wide)
9682 vty_out(vty, "%7u", attr->med);
9683 else
9684 vty_out(vty, "%10u", attr->med);
9685 else if (wide)
9686 vty_out(vty, " ");
9687 else
9688 vty_out(vty, " ");
9689
9690 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9691 vty_out(vty, "%7u", attr->local_pref);
9692 else
9693 vty_out(vty, " ");
9694
9695 vty_out(vty, "%7u ", attr->weight);
9696
9697 /* Print aspath */
9698 if (attr->aspath)
9699 aspath_print_vty(vty, attr->aspath);
9700
9701 /* Print origin */
9702 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9703 }
9704 }
9705 if (use_json) {
9706 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9707
9708 #if CONFDATE > 20231208
9709 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9710 #endif
9711 json_object_boolean_true_add(json_status, "*");
9712 json_object_boolean_true_add(json_status, ">");
9713 json_object_boolean_true_add(json_net, "valid");
9714 json_object_boolean_true_add(json_net, "best");
9715
9716 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9717 json_object_boolean_true_add(json_status, "=");
9718 json_object_boolean_true_add(json_net, "multipath");
9719 }
9720 json_object_object_add(json_net, "appliedStatusSymbols",
9721 json_status);
9722 json_object_object_addf(json_ar, json_net, "%pFX", p);
9723 } else
9724 vty_out(vty, "\n");
9725 }
9726
9727 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9728 struct bgp_path_info *path, int display, safi_t safi,
9729 json_object *json)
9730 {
9731 json_object *json_out = NULL;
9732 struct attr *attr;
9733 mpls_label_t label = MPLS_INVALID_LABEL;
9734
9735 if (!path->extra)
9736 return;
9737
9738 if (json)
9739 json_out = json_object_new_object();
9740
9741 /* short status lead text */
9742 route_vty_short_status_out(vty, path, p, json_out);
9743
9744 /* print prefix and mask */
9745 if (json == NULL) {
9746 if (!display)
9747 route_vty_out_route(path->net, p, vty, NULL, false);
9748 else
9749 vty_out(vty, "%*s", 17, " ");
9750 }
9751
9752 /* Print attribute */
9753 attr = path->attr;
9754 if (((p->family == AF_INET) &&
9755 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9756 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9757 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9758 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9759 || safi == SAFI_EVPN) {
9760 if (json)
9761 json_object_string_addf(
9762 json_out, "mpNexthopGlobalIn", "%pI4",
9763 &attr->mp_nexthop_global_in);
9764 else
9765 vty_out(vty, "%-16pI4",
9766 &attr->mp_nexthop_global_in);
9767 } else {
9768 if (json)
9769 json_object_string_addf(json_out, "nexthop",
9770 "%pI4", &attr->nexthop);
9771 else
9772 vty_out(vty, "%-16pI4", &attr->nexthop);
9773 }
9774 } else if (((p->family == AF_INET6) &&
9775 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9776 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9777 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9778 char buf_a[512];
9779
9780 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9781 if (json)
9782 json_object_string_addf(
9783 json_out, "mpNexthopGlobalIn", "%pI6",
9784 &attr->mp_nexthop_global);
9785 else
9786 vty_out(vty, "%s",
9787 inet_ntop(AF_INET6,
9788 &attr->mp_nexthop_global,
9789 buf_a, sizeof(buf_a)));
9790 } else if (attr->mp_nexthop_len
9791 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9792 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9793 &attr->mp_nexthop_global,
9794 &attr->mp_nexthop_local);
9795 if (json)
9796 json_object_string_add(json_out,
9797 "mpNexthopGlobalLocal",
9798 buf_a);
9799 else
9800 vty_out(vty, "%s", buf_a);
9801 }
9802 }
9803
9804 label = decode_label(&path->extra->label[0]);
9805
9806 if (bgp_is_valid_label(&label)) {
9807 if (json) {
9808 json_object_int_add(json_out, "notag", label);
9809 json_object_array_add(json, json_out);
9810 } else {
9811 vty_out(vty, "notag/%d", label);
9812 vty_out(vty, "\n");
9813 }
9814 } else if (!json)
9815 vty_out(vty, "\n");
9816 }
9817
9818 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9819 struct bgp_path_info *path, int display,
9820 json_object *json_paths)
9821 {
9822 struct attr *attr;
9823 json_object *json_path = NULL;
9824 json_object *json_nexthop = NULL;
9825 json_object *json_overlay = NULL;
9826
9827 if (!path->extra)
9828 return;
9829
9830 if (json_paths) {
9831 json_path = json_object_new_object();
9832 json_overlay = json_object_new_object();
9833 json_nexthop = json_object_new_object();
9834 }
9835
9836 /* short status lead text */
9837 route_vty_short_status_out(vty, path, p, json_path);
9838
9839 /* print prefix and mask */
9840 if (!display)
9841 route_vty_out_route(path->net, p, vty, json_path, false);
9842 else
9843 vty_out(vty, "%*s", 17, " ");
9844
9845 /* Print attribute */
9846 attr = path->attr;
9847 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9848
9849 switch (af) {
9850 case AF_INET:
9851 if (!json_path) {
9852 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9853 } else {
9854 json_object_string_addf(json_nexthop, "ip", "%pI4",
9855 &attr->mp_nexthop_global_in);
9856
9857 json_object_string_add(json_nexthop, "afi", "ipv4");
9858
9859 json_object_object_add(json_path, "nexthop",
9860 json_nexthop);
9861 }
9862 break;
9863 case AF_INET6:
9864 if (!json_path) {
9865 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9866 &attr->mp_nexthop_local);
9867 } else {
9868 json_object_string_addf(json_nexthop, "ipv6Global",
9869 "%pI6",
9870 &attr->mp_nexthop_global);
9871
9872 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9873 "%pI6",
9874 &attr->mp_nexthop_local);
9875
9876 json_object_string_add(json_nexthop, "afi", "ipv6");
9877
9878 json_object_object_add(json_path, "nexthop",
9879 json_nexthop);
9880 }
9881 break;
9882 default:
9883 if (!json_path) {
9884 vty_out(vty, "?");
9885 } else {
9886 json_object_string_add(json_nexthop, "error",
9887 "Unsupported address-family");
9888 }
9889 }
9890
9891 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9892
9893 if (!json_path)
9894 vty_out(vty, "/%pIA", &eo->gw_ip);
9895 else
9896 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9897
9898 if (bgp_attr_get_ecommunity(attr)) {
9899 char *mac = NULL;
9900 struct ecommunity_val *routermac = ecommunity_lookup(
9901 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9902 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9903
9904 if (routermac)
9905 mac = ecom_mac2str((char *)routermac->val);
9906 if (mac) {
9907 if (!json_path) {
9908 vty_out(vty, "/%s", mac);
9909 } else {
9910 json_object_string_add(json_overlay, "rmac",
9911 mac);
9912 }
9913 XFREE(MTYPE_TMP, mac);
9914 }
9915 }
9916
9917 if (!json_path) {
9918 vty_out(vty, "\n");
9919 } else {
9920 json_object_object_add(json_path, "overlay", json_overlay);
9921
9922 json_object_array_add(json_paths, json_path);
9923 }
9924 }
9925
9926 /* dampening route */
9927 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9928 struct bgp_path_info *path, int display,
9929 afi_t afi, safi_t safi, bool use_json,
9930 json_object *json_paths)
9931 {
9932 struct attr *attr = path->attr;
9933 int len;
9934 char timebuf[BGP_UPTIME_LEN];
9935 json_object *json_path = NULL;
9936
9937 if (use_json)
9938 json_path = json_object_new_object();
9939
9940 /* short status lead text */
9941 route_vty_short_status_out(vty, path, p, json_path);
9942
9943 /* print prefix and mask */
9944 if (!use_json) {
9945 if (!display)
9946 route_vty_out_route(path->net, p, vty, NULL, false);
9947 else
9948 vty_out(vty, "%*s", 17, " ");
9949
9950 len = vty_out(vty, "%s", path->peer->host);
9951 len = 17 - len;
9952
9953 if (len < 1)
9954 vty_out(vty, "\n%*s", 34, " ");
9955 else
9956 vty_out(vty, "%*s", len, " ");
9957
9958 vty_out(vty, "%s ",
9959 bgp_damp_reuse_time_vty(vty, path, timebuf,
9960 BGP_UPTIME_LEN, afi, safi,
9961 use_json, NULL));
9962
9963 if (attr->aspath)
9964 aspath_print_vty(vty, attr->aspath);
9965
9966 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9967
9968 vty_out(vty, "\n");
9969 } else {
9970 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9971 safi, use_json, json_path);
9972
9973 if (attr->aspath)
9974 json_object_string_add(json_path, "asPath",
9975 attr->aspath->str);
9976
9977 json_object_string_add(json_path, "origin",
9978 bgp_origin_str[attr->origin]);
9979 json_object_string_add(json_path, "peerHost", path->peer->host);
9980
9981 json_object_array_add(json_paths, json_path);
9982 }
9983 }
9984
9985 /* flap route */
9986 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9987 struct bgp_path_info *path, int display,
9988 afi_t afi, safi_t safi, bool use_json,
9989 json_object *json_paths)
9990 {
9991 struct attr *attr = path->attr;
9992 struct bgp_damp_info *bdi;
9993 char timebuf[BGP_UPTIME_LEN];
9994 int len;
9995 json_object *json_path = NULL;
9996
9997 if (!path->extra)
9998 return;
9999
10000 if (use_json)
10001 json_path = json_object_new_object();
10002
10003 bdi = path->extra->damp_info;
10004
10005 /* short status lead text */
10006 route_vty_short_status_out(vty, path, p, json_path);
10007
10008 if (!use_json) {
10009 if (!display)
10010 route_vty_out_route(path->net, p, vty, NULL, false);
10011 else
10012 vty_out(vty, "%*s", 17, " ");
10013
10014 len = vty_out(vty, "%s", path->peer->host);
10015 len = 16 - len;
10016 if (len < 1)
10017 vty_out(vty, "\n%*s", 33, " ");
10018 else
10019 vty_out(vty, "%*s", len, " ");
10020
10021 len = vty_out(vty, "%d", bdi->flap);
10022 len = 5 - len;
10023 if (len < 1)
10024 vty_out(vty, " ");
10025 else
10026 vty_out(vty, "%*s", len, " ");
10027
10028 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10029 BGP_UPTIME_LEN, 0, NULL));
10030
10031 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10032 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10033 vty_out(vty, "%s ",
10034 bgp_damp_reuse_time_vty(vty, path, timebuf,
10035 BGP_UPTIME_LEN, afi,
10036 safi, use_json, NULL));
10037 else
10038 vty_out(vty, "%*s ", 8, " ");
10039
10040 if (attr->aspath)
10041 aspath_print_vty(vty, attr->aspath);
10042
10043 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10044
10045 vty_out(vty, "\n");
10046 } else {
10047 json_object_string_add(json_path, "peerHost", path->peer->host);
10048 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10049
10050 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10051 json_path);
10052
10053 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10054 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10055 bgp_damp_reuse_time_vty(vty, path, timebuf,
10056 BGP_UPTIME_LEN, afi, safi,
10057 use_json, json_path);
10058
10059 if (attr->aspath)
10060 json_object_string_add(json_path, "asPath",
10061 attr->aspath->str);
10062
10063 json_object_string_add(json_path, "origin",
10064 bgp_origin_str[attr->origin]);
10065
10066 json_object_array_add(json_paths, json_path);
10067 }
10068 }
10069
10070 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10071 int *first, const char *header,
10072 json_object *json_adv_to)
10073 {
10074 json_object *json_peer = NULL;
10075
10076 if (json_adv_to) {
10077 /* 'advertised-to' is a dictionary of peers we have advertised
10078 * this
10079 * prefix too. The key is the peer's IP or swpX, the value is
10080 * the
10081 * hostname if we know it and "" if not.
10082 */
10083 json_peer = json_object_new_object();
10084
10085 if (peer->hostname)
10086 json_object_string_add(json_peer, "hostname",
10087 peer->hostname);
10088
10089 if (peer->conf_if)
10090 json_object_object_add(json_adv_to, peer->conf_if,
10091 json_peer);
10092 else
10093 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10094 &peer->su);
10095 } else {
10096 if (*first) {
10097 vty_out(vty, "%s", header);
10098 *first = 0;
10099 }
10100
10101 if (peer->hostname
10102 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10103 if (peer->conf_if)
10104 vty_out(vty, " %s(%s)", peer->hostname,
10105 peer->conf_if);
10106 else
10107 vty_out(vty, " %s(%pSU)", peer->hostname,
10108 &peer->su);
10109 } else {
10110 if (peer->conf_if)
10111 vty_out(vty, " %s", peer->conf_if);
10112 else
10113 vty_out(vty, " %pSU", &peer->su);
10114 }
10115 }
10116 }
10117
10118 static void route_vty_out_tx_ids(struct vty *vty,
10119 struct bgp_addpath_info_data *d)
10120 {
10121 int i;
10122
10123 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10124 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10125 d->addpath_tx_id[i],
10126 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10127 }
10128 }
10129
10130 static void route_vty_out_detail_es_info(struct vty *vty,
10131 struct bgp_path_info *pi,
10132 struct attr *attr,
10133 json_object *json_path)
10134 {
10135 char esi_buf[ESI_STR_LEN];
10136 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10137 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10138 ATTR_ES_PEER_ROUTER);
10139 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10140 ATTR_ES_PEER_ACTIVE);
10141 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10142 ATTR_ES_PEER_PROXY);
10143 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10144 if (json_path) {
10145 json_object *json_es_info = NULL;
10146
10147 json_object_string_add(
10148 json_path, "esi",
10149 esi_buf);
10150 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10151 json_es_info = json_object_new_object();
10152 if (es_local)
10153 json_object_boolean_true_add(
10154 json_es_info, "localEs");
10155 if (peer_active)
10156 json_object_boolean_true_add(
10157 json_es_info, "peerActive");
10158 if (peer_proxy)
10159 json_object_boolean_true_add(
10160 json_es_info, "peerProxy");
10161 if (peer_router)
10162 json_object_boolean_true_add(
10163 json_es_info, "peerRouter");
10164 if (attr->mm_sync_seqnum)
10165 json_object_int_add(
10166 json_es_info, "peerSeq",
10167 attr->mm_sync_seqnum);
10168 json_object_object_add(
10169 json_path, "es_info",
10170 json_es_info);
10171 }
10172 } else {
10173 if (bgp_evpn_attr_is_sync(attr))
10174 vty_out(vty,
10175 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10176 esi_buf,
10177 es_local ? "local-es":"",
10178 peer_proxy ? "proxy " : "",
10179 peer_active ? "active ":"",
10180 peer_router ? "router ":"",
10181 attr->mm_sync_seqnum);
10182 else
10183 vty_out(vty, " ESI %s %s\n",
10184 esi_buf,
10185 es_local ? "local-es":"");
10186 }
10187 }
10188
10189 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10190 const struct prefix *p, struct bgp_path_info *path,
10191 afi_t afi, safi_t safi,
10192 enum rpki_states rpki_curr_state,
10193 json_object *json_paths)
10194 {
10195 char buf[INET6_ADDRSTRLEN];
10196 char tag_buf[30];
10197 struct attr *attr = path->attr;
10198 time_t tbuf;
10199 json_object *json_bestpath = NULL;
10200 json_object *json_cluster_list = NULL;
10201 json_object *json_cluster_list_list = NULL;
10202 json_object *json_ext_community = NULL;
10203 json_object *json_last_update = NULL;
10204 json_object *json_pmsi = NULL;
10205 json_object *json_nexthop_global = NULL;
10206 json_object *json_nexthop_ll = NULL;
10207 json_object *json_nexthops = NULL;
10208 json_object *json_path = NULL;
10209 json_object *json_peer = NULL;
10210 json_object *json_string = NULL;
10211 json_object *json_adv_to = NULL;
10212 int first = 0;
10213 struct listnode *node, *nnode;
10214 struct peer *peer;
10215 bool addpath_capable;
10216 int has_adj;
10217 unsigned int first_as;
10218 bool nexthop_self =
10219 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10220 int i;
10221 char *nexthop_hostname =
10222 bgp_nexthop_hostname(path->peer, path->nexthop);
10223 uint32_t ttl = 0;
10224 uint32_t bos = 0;
10225 uint32_t exp = 0;
10226 mpls_label_t label = MPLS_INVALID_LABEL;
10227 tag_buf[0] = '\0';
10228 struct bgp_path_info *bpi_ultimate =
10229 bgp_get_imported_bpi_ultimate(path);
10230
10231 if (json_paths) {
10232 json_path = json_object_new_object();
10233 json_peer = json_object_new_object();
10234 json_nexthop_global = json_object_new_object();
10235 }
10236
10237 if (safi == SAFI_EVPN) {
10238 if (!json_paths)
10239 vty_out(vty, " Route %pFX", p);
10240 }
10241
10242 if (path->extra) {
10243 if (path->extra && path->extra->num_labels) {
10244 bgp_evpn_label2str(path->extra->label,
10245 path->extra->num_labels, tag_buf,
10246 sizeof(tag_buf));
10247 }
10248 if (safi == SAFI_EVPN) {
10249 if (!json_paths) {
10250 if (tag_buf[0] != '\0')
10251 vty_out(vty, " VNI %s", tag_buf);
10252 } else {
10253 if (tag_buf[0])
10254 json_object_string_add(json_path, "vni",
10255 tag_buf);
10256 }
10257 }
10258 }
10259
10260 if (safi == SAFI_EVPN
10261 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10262 char gwip_buf[INET6_ADDRSTRLEN];
10263
10264 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10265 sizeof(gwip_buf));
10266
10267 if (json_paths)
10268 json_object_string_add(json_path, "gatewayIP",
10269 gwip_buf);
10270 else
10271 vty_out(vty, " Gateway IP %s", gwip_buf);
10272 }
10273
10274 if (safi == SAFI_EVPN && !json_path)
10275 vty_out(vty, "\n");
10276
10277
10278 if (path->extra && path->extra->parent && !json_paths) {
10279 struct bgp_path_info *parent_ri;
10280 struct bgp_dest *dest, *pdest;
10281
10282 parent_ri = (struct bgp_path_info *)path->extra->parent;
10283 dest = parent_ri->net;
10284 if (dest && dest->pdest) {
10285 pdest = dest->pdest;
10286 if (is_pi_family_evpn(parent_ri)) {
10287 vty_out(vty, " Imported from ");
10288 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10289 (struct prefix_rd *)bgp_dest_get_prefix(
10290 pdest));
10291 vty_out(vty, ":%pFX, VNI %s",
10292 (struct prefix_evpn *)
10293 bgp_dest_get_prefix(dest),
10294 tag_buf);
10295 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10296 vty_out(vty, ", L3NHG %s",
10297 CHECK_FLAG(
10298 attr->es_flags,
10299 ATTR_ES_L3_NHG_ACTIVE)
10300 ? "active"
10301 : "inactive");
10302 vty_out(vty, "\n");
10303
10304 } else {
10305 vty_out(vty, " Imported from ");
10306 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10307 (struct prefix_rd *)bgp_dest_get_prefix(
10308 pdest));
10309 vty_out(vty, ":%pFX\n",
10310 (struct prefix_evpn *)
10311 bgp_dest_get_prefix(dest));
10312 }
10313 }
10314 }
10315
10316 /* Line1 display AS-path, Aggregator */
10317 if (attr->aspath) {
10318 if (json_paths) {
10319 if (!attr->aspath->json)
10320 aspath_str_update(attr->aspath, true);
10321 json_object_lock(attr->aspath->json);
10322 json_object_object_add(json_path, "aspath",
10323 attr->aspath->json);
10324 } else {
10325 if (attr->aspath->segments)
10326 vty_out(vty, " %s", attr->aspath->str);
10327 else
10328 vty_out(vty, " Local");
10329 }
10330 }
10331
10332 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10333 if (json_paths)
10334 json_object_boolean_true_add(json_path, "removed");
10335 else
10336 vty_out(vty, ", (removed)");
10337 }
10338
10339 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10340 if (json_paths)
10341 json_object_boolean_true_add(json_path, "stale");
10342 else
10343 vty_out(vty, ", (stale)");
10344 }
10345
10346 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10347 if (json_paths) {
10348 json_object_int_add(json_path, "aggregatorAs",
10349 attr->aggregator_as);
10350 json_object_string_addf(json_path, "aggregatorId",
10351 "%pI4", &attr->aggregator_addr);
10352 } else {
10353 vty_out(vty, ", (aggregated by %u %pI4)",
10354 attr->aggregator_as, &attr->aggregator_addr);
10355 }
10356 }
10357
10358 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10359 PEER_FLAG_REFLECTOR_CLIENT)) {
10360 if (json_paths)
10361 json_object_boolean_true_add(json_path,
10362 "rxedFromRrClient");
10363 else
10364 vty_out(vty, ", (Received from a RR-client)");
10365 }
10366
10367 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10368 PEER_FLAG_RSERVER_CLIENT)) {
10369 if (json_paths)
10370 json_object_boolean_true_add(json_path,
10371 "rxedFromRsClient");
10372 else
10373 vty_out(vty, ", (Received from a RS-client)");
10374 }
10375
10376 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10377 if (json_paths)
10378 json_object_boolean_true_add(json_path,
10379 "dampeningHistoryEntry");
10380 else
10381 vty_out(vty, ", (history entry)");
10382 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10383 if (json_paths)
10384 json_object_boolean_true_add(json_path,
10385 "dampeningSuppressed");
10386 else
10387 vty_out(vty, ", (suppressed due to dampening)");
10388 }
10389
10390 if (!json_paths)
10391 vty_out(vty, "\n");
10392
10393 /* Line2 display Next-hop, Neighbor, Router-id */
10394 /* Display the nexthop */
10395
10396 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10397 p->family == AF_EVPN) &&
10398 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10399 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10400 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10401 || safi == SAFI_EVPN) {
10402 if (json_paths) {
10403 json_object_string_addf(
10404 json_nexthop_global, "ip", "%pI4",
10405 &attr->mp_nexthop_global_in);
10406
10407 if (path->peer->hostname)
10408 json_object_string_add(
10409 json_nexthop_global, "hostname",
10410 path->peer->hostname);
10411 } else {
10412 if (nexthop_hostname)
10413 vty_out(vty, " %pI4(%s)",
10414 &attr->mp_nexthop_global_in,
10415 nexthop_hostname);
10416 else
10417 vty_out(vty, " %pI4",
10418 &attr->mp_nexthop_global_in);
10419 }
10420 } else {
10421 if (json_paths) {
10422 json_object_string_addf(json_nexthop_global,
10423 "ip", "%pI4",
10424 &attr->nexthop);
10425
10426 if (path->peer->hostname)
10427 json_object_string_add(
10428 json_nexthop_global, "hostname",
10429 path->peer->hostname);
10430 } else {
10431 if (nexthop_hostname)
10432 vty_out(vty, " %pI4(%s)",
10433 &attr->nexthop,
10434 nexthop_hostname);
10435 else
10436 vty_out(vty, " %pI4",
10437 &attr->nexthop);
10438 }
10439 }
10440
10441 if (json_paths)
10442 json_object_string_add(json_nexthop_global, "afi",
10443 "ipv4");
10444 } else {
10445 if (json_paths) {
10446 json_object_string_addf(json_nexthop_global, "ip",
10447 "%pI6",
10448 &attr->mp_nexthop_global);
10449
10450 if (path->peer->hostname)
10451 json_object_string_add(json_nexthop_global,
10452 "hostname",
10453 path->peer->hostname);
10454
10455 json_object_string_add(json_nexthop_global, "afi",
10456 "ipv6");
10457 json_object_string_add(json_nexthop_global, "scope",
10458 "global");
10459 } else {
10460 if (nexthop_hostname)
10461 vty_out(vty, " %pI6(%s)",
10462 &attr->mp_nexthop_global,
10463 nexthop_hostname);
10464 else
10465 vty_out(vty, " %pI6",
10466 &attr->mp_nexthop_global);
10467 }
10468 }
10469
10470 /* Display the IGP cost or 'inaccessible' */
10471 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10472 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10473
10474 if (json_paths) {
10475 json_object_boolean_false_add(json_nexthop_global,
10476 "accessible");
10477 json_object_boolean_add(json_nexthop_global,
10478 "importCheckEnabled", import);
10479 } else {
10480 vty_out(vty, " (inaccessible%s)",
10481 import ? ", import-check enabled" : "");
10482 }
10483 } else {
10484 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10485 if (json_paths)
10486 json_object_int_add(
10487 json_nexthop_global, "metric",
10488 bpi_ultimate->extra->igpmetric);
10489 else
10490 vty_out(vty, " (metric %u)",
10491 bpi_ultimate->extra->igpmetric);
10492 }
10493
10494 /* IGP cost is 0, display this only for json */
10495 else {
10496 if (json_paths)
10497 json_object_int_add(json_nexthop_global,
10498 "metric", 0);
10499 }
10500
10501 if (json_paths)
10502 json_object_boolean_true_add(json_nexthop_global,
10503 "accessible");
10504 }
10505
10506 /* Display peer "from" output */
10507 /* This path was originated locally */
10508 if (path->peer == bgp->peer_self) {
10509
10510 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10511 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10512 if (json_paths)
10513 json_object_string_add(json_peer, "peerId",
10514 "0.0.0.0");
10515 else
10516 vty_out(vty, " from 0.0.0.0 ");
10517 } else {
10518 if (json_paths)
10519 json_object_string_add(json_peer, "peerId",
10520 "::");
10521 else
10522 vty_out(vty, " from :: ");
10523 }
10524
10525 if (json_paths)
10526 json_object_string_addf(json_peer, "routerId", "%pI4",
10527 &bgp->router_id);
10528 else
10529 vty_out(vty, "(%pI4)", &bgp->router_id);
10530 }
10531
10532 /* We RXed this path from one of our peers */
10533 else {
10534
10535 if (json_paths) {
10536 json_object_string_addf(json_peer, "peerId", "%pSU",
10537 &path->peer->su);
10538 json_object_string_addf(json_peer, "routerId", "%pI4",
10539 &path->peer->remote_id);
10540
10541 if (path->peer->hostname)
10542 json_object_string_add(json_peer, "hostname",
10543 path->peer->hostname);
10544
10545 if (path->peer->domainname)
10546 json_object_string_add(json_peer, "domainname",
10547 path->peer->domainname);
10548
10549 if (path->peer->conf_if)
10550 json_object_string_add(json_peer, "interface",
10551 path->peer->conf_if);
10552 } else {
10553 if (path->peer->conf_if) {
10554 if (path->peer->hostname
10555 && CHECK_FLAG(path->peer->bgp->flags,
10556 BGP_FLAG_SHOW_HOSTNAME))
10557 vty_out(vty, " from %s(%s)",
10558 path->peer->hostname,
10559 path->peer->conf_if);
10560 else
10561 vty_out(vty, " from %s",
10562 path->peer->conf_if);
10563 } else {
10564 if (path->peer->hostname
10565 && CHECK_FLAG(path->peer->bgp->flags,
10566 BGP_FLAG_SHOW_HOSTNAME))
10567 vty_out(vty, " from %s(%s)",
10568 path->peer->hostname,
10569 path->peer->host);
10570 else
10571 vty_out(vty, " from %pSU",
10572 &path->peer->su);
10573 }
10574
10575 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10576 vty_out(vty, " (%pI4)", &attr->originator_id);
10577 else
10578 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10579 }
10580 }
10581
10582 /*
10583 * Note when vrfid of nexthop is different from that of prefix
10584 */
10585 if (path->extra && path->extra->bgp_orig) {
10586 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10587
10588 if (json_paths) {
10589 const char *vn;
10590
10591 if (path->extra->bgp_orig->inst_type
10592 == BGP_INSTANCE_TYPE_DEFAULT)
10593 vn = VRF_DEFAULT_NAME;
10594 else
10595 vn = path->extra->bgp_orig->name;
10596
10597 json_object_string_add(json_path, "nhVrfName", vn);
10598
10599 if (nexthop_vrfid == VRF_UNKNOWN) {
10600 json_object_int_add(json_path, "nhVrfId", -1);
10601 } else {
10602 json_object_int_add(json_path, "nhVrfId",
10603 (int)nexthop_vrfid);
10604 }
10605 } else {
10606 if (nexthop_vrfid == VRF_UNKNOWN)
10607 vty_out(vty, " vrf ?");
10608 else {
10609 struct vrf *vrf;
10610
10611 vrf = vrf_lookup_by_id(nexthop_vrfid);
10612 vty_out(vty, " vrf %s(%u)",
10613 VRF_LOGNAME(vrf), nexthop_vrfid);
10614 }
10615 }
10616 }
10617
10618 if (nexthop_self) {
10619 if (json_paths) {
10620 json_object_boolean_true_add(json_path,
10621 "announceNexthopSelf");
10622 } else {
10623 vty_out(vty, " announce-nh-self");
10624 }
10625 }
10626
10627 if (!json_paths)
10628 vty_out(vty, "\n");
10629
10630 /* display the link-local nexthop */
10631 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10632 if (json_paths) {
10633 json_nexthop_ll = json_object_new_object();
10634 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10635 &attr->mp_nexthop_local);
10636
10637 if (path->peer->hostname)
10638 json_object_string_add(json_nexthop_ll,
10639 "hostname",
10640 path->peer->hostname);
10641
10642 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10643 json_object_string_add(json_nexthop_ll, "scope",
10644 "link-local");
10645
10646 json_object_boolean_true_add(json_nexthop_ll,
10647 "accessible");
10648
10649 if (!attr->mp_nexthop_prefer_global)
10650 json_object_boolean_true_add(json_nexthop_ll,
10651 "used");
10652 else
10653 json_object_boolean_true_add(
10654 json_nexthop_global, "used");
10655 } else {
10656 vty_out(vty, " (%s) %s\n",
10657 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10658 buf, INET6_ADDRSTRLEN),
10659 attr->mp_nexthop_prefer_global
10660 ? "(prefer-global)"
10661 : "(used)");
10662 }
10663 }
10664 /* If we do not have a link-local nexthop then we must flag the
10665 global as "used" */
10666 else {
10667 if (json_paths)
10668 json_object_boolean_true_add(json_nexthop_global,
10669 "used");
10670 }
10671
10672 if (safi == SAFI_EVPN &&
10673 bgp_evpn_is_esi_valid(&attr->esi)) {
10674 route_vty_out_detail_es_info(vty, path, attr, json_path);
10675 }
10676
10677 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10678 * Int/Ext/Local, Atomic, best */
10679 if (json_paths)
10680 json_object_string_add(json_path, "origin",
10681 bgp_origin_long_str[attr->origin]);
10682 else
10683 vty_out(vty, " Origin %s",
10684 bgp_origin_long_str[attr->origin]);
10685
10686 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10687 if (json_paths)
10688 json_object_int_add(json_path, "metric", attr->med);
10689 else
10690 vty_out(vty, ", metric %u", attr->med);
10691 }
10692
10693 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10694 if (json_paths)
10695 json_object_int_add(json_path, "locPrf",
10696 attr->local_pref);
10697 else
10698 vty_out(vty, ", localpref %u", attr->local_pref);
10699 }
10700
10701 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10702 if (json_paths)
10703 json_object_int_add(json_path, "aigpMetric",
10704 bgp_attr_get_aigp_metric(attr));
10705 else
10706 vty_out(vty, ", aigp-metric %" PRIu64,
10707 bgp_attr_get_aigp_metric(attr));
10708 }
10709
10710 if (attr->weight != 0) {
10711 if (json_paths)
10712 json_object_int_add(json_path, "weight", attr->weight);
10713 else
10714 vty_out(vty, ", weight %u", attr->weight);
10715 }
10716
10717 if (attr->tag != 0) {
10718 if (json_paths)
10719 json_object_int_add(json_path, "tag", attr->tag);
10720 else
10721 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10722 }
10723
10724 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10725 if (json_paths)
10726 json_object_boolean_false_add(json_path, "valid");
10727 else
10728 vty_out(vty, ", invalid");
10729 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10730 if (json_paths)
10731 json_object_boolean_true_add(json_path, "valid");
10732 else
10733 vty_out(vty, ", valid");
10734 }
10735
10736 if (json_paths)
10737 json_object_int_add(json_path, "version", bn->version);
10738
10739 if (path->peer != bgp->peer_self) {
10740 if (path->peer->as == path->peer->local_as) {
10741 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10742 if (json_paths)
10743 json_object_string_add(
10744 json_peer, "type",
10745 "confed-internal");
10746 else
10747 vty_out(vty, ", confed-internal");
10748 } else {
10749 if (json_paths)
10750 json_object_string_add(
10751 json_peer, "type", "internal");
10752 else
10753 vty_out(vty, ", internal");
10754 }
10755 } else {
10756 if (bgp_confederation_peers_check(bgp,
10757 path->peer->as)) {
10758 if (json_paths)
10759 json_object_string_add(
10760 json_peer, "type",
10761 "confed-external");
10762 else
10763 vty_out(vty, ", confed-external");
10764 } else {
10765 if (json_paths)
10766 json_object_string_add(
10767 json_peer, "type", "external");
10768 else
10769 vty_out(vty, ", external");
10770 }
10771 }
10772 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10773 if (json_paths) {
10774 json_object_boolean_true_add(json_path, "aggregated");
10775 json_object_boolean_true_add(json_path, "local");
10776 } else {
10777 vty_out(vty, ", aggregated, local");
10778 }
10779 } else if (path->type != ZEBRA_ROUTE_BGP) {
10780 if (json_paths)
10781 json_object_boolean_true_add(json_path, "sourced");
10782 else
10783 vty_out(vty, ", sourced");
10784 } else {
10785 if (json_paths) {
10786 json_object_boolean_true_add(json_path, "sourced");
10787 json_object_boolean_true_add(json_path, "local");
10788 } else {
10789 vty_out(vty, ", sourced, local");
10790 }
10791 }
10792
10793 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10794 if (json_paths)
10795 json_object_boolean_true_add(json_path,
10796 "atomicAggregate");
10797 else
10798 vty_out(vty, ", atomic-aggregate");
10799 }
10800
10801 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10802 if (json_paths)
10803 json_object_int_add(json_path, "otc", attr->otc);
10804 else
10805 vty_out(vty, ", otc %u", attr->otc);
10806 }
10807
10808 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10809 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10810 && bgp_path_info_mpath_count(path))) {
10811 if (json_paths)
10812 json_object_boolean_true_add(json_path, "multipath");
10813 else
10814 vty_out(vty, ", multipath");
10815 }
10816
10817 // Mark the bestpath(s)
10818 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10819 first_as = aspath_get_first_as(attr->aspath);
10820
10821 if (json_paths) {
10822 if (!json_bestpath)
10823 json_bestpath = json_object_new_object();
10824 json_object_int_add(json_bestpath, "bestpathFromAs",
10825 first_as);
10826 } else {
10827 if (first_as)
10828 vty_out(vty, ", bestpath-from-AS %u", first_as);
10829 else
10830 vty_out(vty, ", bestpath-from-AS Local");
10831 }
10832 }
10833
10834 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10835 if (json_paths) {
10836 if (!json_bestpath)
10837 json_bestpath = json_object_new_object();
10838 json_object_boolean_true_add(json_bestpath, "overall");
10839 json_object_string_add(
10840 json_bestpath, "selectionReason",
10841 bgp_path_selection_reason2str(bn->reason));
10842 } else {
10843 vty_out(vty, ", best");
10844 vty_out(vty, " (%s)",
10845 bgp_path_selection_reason2str(bn->reason));
10846 }
10847 }
10848
10849 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10850 if (json_paths)
10851 json_object_string_add(
10852 json_path, "rpkiValidationState",
10853 bgp_rpki_validation2str(rpki_curr_state));
10854 else
10855 vty_out(vty, ", rpki validation-state: %s",
10856 bgp_rpki_validation2str(rpki_curr_state));
10857 }
10858
10859 if (json_bestpath)
10860 json_object_object_add(json_path, "bestpath", json_bestpath);
10861
10862 if (!json_paths)
10863 vty_out(vty, "\n");
10864
10865 /* Line 4 display Community */
10866 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10867 if (json_paths) {
10868 if (!bgp_attr_get_community(attr)->json)
10869 community_str(bgp_attr_get_community(attr),
10870 true, true);
10871 json_object_lock(bgp_attr_get_community(attr)->json);
10872 json_object_object_add(
10873 json_path, "community",
10874 bgp_attr_get_community(attr)->json);
10875 } else {
10876 vty_out(vty, " Community: %s\n",
10877 bgp_attr_get_community(attr)->str);
10878 }
10879 }
10880
10881 /* Line 5 display Extended-community */
10882 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10883 if (json_paths) {
10884 json_ext_community = json_object_new_object();
10885 json_object_string_add(
10886 json_ext_community, "string",
10887 bgp_attr_get_ecommunity(attr)->str);
10888 json_object_object_add(json_path, "extendedCommunity",
10889 json_ext_community);
10890 } else {
10891 vty_out(vty, " Extended Community: %s\n",
10892 bgp_attr_get_ecommunity(attr)->str);
10893 }
10894 }
10895
10896 /* Line 6 display Large community */
10897 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10898 if (json_paths) {
10899 if (!bgp_attr_get_lcommunity(attr)->json)
10900 lcommunity_str(bgp_attr_get_lcommunity(attr),
10901 true, true);
10902 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10903 json_object_object_add(
10904 json_path, "largeCommunity",
10905 bgp_attr_get_lcommunity(attr)->json);
10906 } else {
10907 vty_out(vty, " Large Community: %s\n",
10908 bgp_attr_get_lcommunity(attr)->str);
10909 }
10910 }
10911
10912 /* Line 7 display Originator, Cluster-id */
10913 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10914 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10915 char buf[BUFSIZ] = {0};
10916
10917 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10918 if (json_paths)
10919 json_object_string_addf(json_path,
10920 "originatorId", "%pI4",
10921 &attr->originator_id);
10922 else
10923 vty_out(vty, " Originator: %pI4",
10924 &attr->originator_id);
10925 }
10926
10927 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10928 struct cluster_list *cluster =
10929 bgp_attr_get_cluster(attr);
10930 int i;
10931
10932 if (json_paths) {
10933 json_cluster_list = json_object_new_object();
10934 json_cluster_list_list =
10935 json_object_new_array();
10936
10937 for (i = 0; i < cluster->length / 4; i++) {
10938 json_string = json_object_new_string(
10939 inet_ntop(AF_INET,
10940 &cluster->list[i],
10941 buf, sizeof(buf)));
10942 json_object_array_add(
10943 json_cluster_list_list,
10944 json_string);
10945 }
10946
10947 /*
10948 * struct cluster_list does not have
10949 * "str" variable like aspath and community
10950 * do. Add this someday if someone asks
10951 * for it.
10952 * json_object_string_add(json_cluster_list,
10953 * "string", cluster->str);
10954 */
10955 json_object_object_add(json_cluster_list,
10956 "list",
10957 json_cluster_list_list);
10958 json_object_object_add(json_path, "clusterList",
10959 json_cluster_list);
10960 } else {
10961 vty_out(vty, ", Cluster list: ");
10962
10963 for (i = 0; i < cluster->length / 4; i++) {
10964 vty_out(vty, "%pI4 ",
10965 &cluster->list[i]);
10966 }
10967 }
10968 }
10969
10970 if (!json_paths)
10971 vty_out(vty, "\n");
10972 }
10973
10974 if (path->extra && path->extra->damp_info)
10975 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10976
10977 /* Remote Label */
10978 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10979 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10980 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10981 &bos);
10982
10983 if (json_paths)
10984 json_object_int_add(json_path, "remoteLabel", label);
10985 else
10986 vty_out(vty, " Remote label: %d\n", label);
10987 }
10988
10989 /* Remote SID */
10990 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10991 if (json_paths)
10992 json_object_string_addf(json_path, "remoteSid", "%pI6",
10993 &path->extra->sid[0].sid);
10994 else
10995 vty_out(vty, " Remote SID: %pI6\n",
10996 &path->extra->sid[0].sid);
10997 }
10998
10999 /* Label Index */
11000 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
11001 if (json_paths)
11002 json_object_int_add(json_path, "labelIndex",
11003 attr->label_index);
11004 else
11005 vty_out(vty, " Label Index: %d\n",
11006 attr->label_index);
11007 }
11008
11009 /* Line 8 display Addpath IDs */
11010 if (path->addpath_rx_id
11011 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
11012 if (json_paths) {
11013 json_object_int_add(json_path, "addpathRxId",
11014 path->addpath_rx_id);
11015
11016 /* Keep backwards compatibility with the old API
11017 * by putting TX All's ID in the old field
11018 */
11019 json_object_int_add(
11020 json_path, "addpathTxId",
11021 path->tx_addpath
11022 .addpath_tx_id[BGP_ADDPATH_ALL]);
11023
11024 /* ... but create a specific field for each
11025 * strategy
11026 */
11027 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11028 json_object_int_add(
11029 json_path,
11030 bgp_addpath_names(i)->id_json_name,
11031 path->tx_addpath.addpath_tx_id[i]);
11032 }
11033 } else {
11034 vty_out(vty, " AddPath ID: RX %u, ",
11035 path->addpath_rx_id);
11036
11037 route_vty_out_tx_ids(vty, &path->tx_addpath);
11038 }
11039 }
11040
11041 /* If we used addpath to TX a non-bestpath we need to display
11042 * "Advertised to" on a path-by-path basis
11043 */
11044 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11045 first = 1;
11046
11047 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11048 addpath_capable =
11049 bgp_addpath_encode_tx(peer, afi, safi);
11050 has_adj = bgp_adj_out_lookup(
11051 peer, path->net,
11052 bgp_addpath_id_for_peer(peer, afi, safi,
11053 &path->tx_addpath));
11054
11055 if ((addpath_capable && has_adj)
11056 || (!addpath_capable && has_adj
11057 && CHECK_FLAG(path->flags,
11058 BGP_PATH_SELECTED))) {
11059 if (json_path && !json_adv_to)
11060 json_adv_to = json_object_new_object();
11061
11062 route_vty_out_advertised_to(
11063 vty, peer, &first,
11064 " Advertised to:", json_adv_to);
11065 }
11066 }
11067
11068 if (json_path) {
11069 if (json_adv_to) {
11070 json_object_object_add(
11071 json_path, "advertisedTo", json_adv_to);
11072 }
11073 } else {
11074 if (!first) {
11075 vty_out(vty, "\n");
11076 }
11077 }
11078 }
11079
11080 /* Line 9 display Uptime */
11081 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11082 if (json_paths) {
11083 json_last_update = json_object_new_object();
11084 json_object_int_add(json_last_update, "epoch", tbuf);
11085 json_object_string_add(json_last_update, "string",
11086 ctime(&tbuf));
11087 json_object_object_add(json_path, "lastUpdate",
11088 json_last_update);
11089 } else
11090 vty_out(vty, " Last update: %s", ctime(&tbuf));
11091
11092 /* Line 10 display PMSI tunnel attribute, if present */
11093 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11094 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11095 bgp_attr_get_pmsi_tnl_type(attr),
11096 PMSI_TNLTYPE_STR_DEFAULT);
11097
11098 if (json_paths) {
11099 json_pmsi = json_object_new_object();
11100 json_object_string_add(json_pmsi, "tunnelType", str);
11101 json_object_int_add(json_pmsi, "label",
11102 label2vni(&attr->label));
11103 json_object_object_add(json_path, "pmsi", json_pmsi);
11104 } else
11105 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11106 str, label2vni(&attr->label));
11107 }
11108
11109 if (path->peer->t_gr_restart &&
11110 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11111 unsigned long gr_remaining =
11112 event_timer_remain_second(path->peer->t_gr_restart);
11113
11114 if (json_paths) {
11115 json_object_int_add(json_path,
11116 "gracefulRestartSecondsRemaining",
11117 gr_remaining);
11118 } else
11119 vty_out(vty,
11120 " Time until Graceful Restart stale route deleted: %lu\n",
11121 gr_remaining);
11122 }
11123
11124 if (path->peer->t_llgr_stale[afi][safi] &&
11125 bgp_attr_get_community(attr) &&
11126 community_include(bgp_attr_get_community(attr),
11127 COMMUNITY_LLGR_STALE)) {
11128 unsigned long llgr_remaining = event_timer_remain_second(
11129 path->peer->t_llgr_stale[afi][safi]);
11130
11131 if (json_paths) {
11132 json_object_int_add(json_path, "llgrSecondsRemaining",
11133 llgr_remaining);
11134 } else
11135 vty_out(vty,
11136 " Time until Long-lived stale route deleted: %lu\n",
11137 llgr_remaining);
11138 }
11139
11140 /* Output some debug about internal state of the dest flags */
11141 if (json_paths) {
11142 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11143 json_object_boolean_true_add(json_path, "processScheduled");
11144 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11145 json_object_boolean_true_add(json_path, "userCleared");
11146 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11147 json_object_boolean_true_add(json_path, "labelChanged");
11148 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11149 json_object_boolean_true_add(json_path, "registeredForLabel");
11150 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11151 json_object_boolean_true_add(json_path, "selectDefered");
11152 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11153 json_object_boolean_true_add(json_path, "fibInstalled");
11154 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11155 json_object_boolean_true_add(json_path, "fibPending");
11156
11157 if (json_nexthop_global || json_nexthop_ll) {
11158 json_nexthops = json_object_new_array();
11159
11160 if (json_nexthop_global)
11161 json_object_array_add(json_nexthops,
11162 json_nexthop_global);
11163
11164 if (json_nexthop_ll)
11165 json_object_array_add(json_nexthops,
11166 json_nexthop_ll);
11167
11168 json_object_object_add(json_path, "nexthops",
11169 json_nexthops);
11170 }
11171
11172 json_object_object_add(json_path, "peer", json_peer);
11173 json_object_array_add(json_paths, json_path);
11174 }
11175 }
11176
11177 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11178 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11179 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11180
11181 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11182 afi_t afi, safi_t safi, enum bgp_show_type type,
11183 bool use_json);
11184 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11185 const char *comstr, int exact, afi_t afi,
11186 safi_t safi, uint16_t show_flags);
11187
11188 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11189 struct bgp_table *table, enum bgp_show_type type,
11190 void *output_arg, const char *rd, int is_last,
11191 unsigned long *output_cum, unsigned long *total_cum,
11192 unsigned long *json_header_depth, uint16_t show_flags,
11193 enum rpki_states rpki_target_state)
11194 {
11195 struct bgp_path_info *pi;
11196 struct bgp_dest *dest;
11197 bool header = true;
11198 bool json_detail_header = false;
11199 int display;
11200 unsigned long output_count = 0;
11201 unsigned long total_count = 0;
11202 struct prefix *p;
11203 json_object *json_paths = NULL;
11204 int first = 1;
11205 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11206 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11207 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11208 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11209 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11210
11211 if (output_cum && *output_cum != 0)
11212 header = false;
11213
11214 if (use_json && !*json_header_depth) {
11215 if (all)
11216 *json_header_depth = 1;
11217 else {
11218 vty_out(vty, "{\n");
11219 *json_header_depth = 2;
11220 }
11221 vty_out(vty,
11222 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11223 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11224 " \"localAS\": ",
11225 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11226 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11227 ? VRF_DEFAULT_NAME
11228 : bgp->name,
11229 table->version, &bgp->router_id,
11230 bgp->default_local_pref);
11231 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11232 ((bgp->asnotation == ASNOTATION_DOT) &&
11233 (bgp->as < UINT16_MAX)))
11234 vty_out(vty, "%u", bgp->as);
11235 else {
11236 vty_out(vty, "\"");
11237 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11238 vty_out(vty, "\"");
11239 }
11240 vty_out(vty, ",\n \"routes\": { ");
11241 if (rd) {
11242 vty_out(vty, " \"routeDistinguishers\" : {");
11243 ++*json_header_depth;
11244 }
11245 }
11246
11247 if (use_json && rd) {
11248 vty_out(vty, " \"%s\" : { ", rd);
11249 }
11250
11251 /* Check for 'json detail', where we need header output once per dest */
11252 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11253 type != bgp_show_type_damp_neighbor &&
11254 type != bgp_show_type_flap_statistics &&
11255 type != bgp_show_type_flap_neighbor)
11256 json_detail_header = true;
11257
11258 /* Start processing of routes. */
11259 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11260 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11261 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11262 bool json_detail_header_used = false;
11263
11264 pi = bgp_dest_get_bgp_path_info(dest);
11265 if (pi == NULL)
11266 continue;
11267
11268 display = 0;
11269 if (use_json)
11270 json_paths = json_object_new_array();
11271 else
11272 json_paths = NULL;
11273
11274 for (; pi; pi = pi->next) {
11275 struct community *picomm = NULL;
11276
11277 picomm = bgp_attr_get_community(pi->attr);
11278
11279 total_count++;
11280
11281 if (type == bgp_show_type_prefix_version) {
11282 uint32_t version =
11283 strtoul(output_arg, NULL, 10);
11284 if (dest->version < version)
11285 continue;
11286 }
11287
11288 if (type == bgp_show_type_community_alias) {
11289 char *alias = output_arg;
11290 char **communities;
11291 int num;
11292 bool found = false;
11293
11294 if (picomm) {
11295 frrstr_split(picomm->str, " ",
11296 &communities, &num);
11297 for (int i = 0; i < num; i++) {
11298 const char *com2alias =
11299 bgp_community2alias(
11300 communities[i]);
11301 if (!found
11302 && strcmp(alias, com2alias)
11303 == 0)
11304 found = true;
11305 XFREE(MTYPE_TMP,
11306 communities[i]);
11307 }
11308 XFREE(MTYPE_TMP, communities);
11309 }
11310
11311 if (!found &&
11312 bgp_attr_get_lcommunity(pi->attr)) {
11313 frrstr_split(bgp_attr_get_lcommunity(
11314 pi->attr)
11315 ->str,
11316 " ", &communities, &num);
11317 for (int i = 0; i < num; i++) {
11318 const char *com2alias =
11319 bgp_community2alias(
11320 communities[i]);
11321 if (!found
11322 && strcmp(alias, com2alias)
11323 == 0)
11324 found = true;
11325 XFREE(MTYPE_TMP,
11326 communities[i]);
11327 }
11328 XFREE(MTYPE_TMP, communities);
11329 }
11330
11331 if (!found)
11332 continue;
11333 }
11334
11335 if (type == bgp_show_type_rpki) {
11336 if (dest_p->family == AF_INET
11337 || dest_p->family == AF_INET6)
11338 rpki_curr_state = hook_call(
11339 bgp_rpki_prefix_status,
11340 pi->peer, pi->attr, dest_p);
11341 if (rpki_target_state != RPKI_NOT_BEING_USED
11342 && rpki_curr_state != rpki_target_state)
11343 continue;
11344 }
11345
11346 if (type == bgp_show_type_flap_statistics
11347 || type == bgp_show_type_flap_neighbor
11348 || type == bgp_show_type_dampend_paths
11349 || type == bgp_show_type_damp_neighbor) {
11350 if (!(pi->extra && pi->extra->damp_info))
11351 continue;
11352 }
11353 if (type == bgp_show_type_regexp) {
11354 regex_t *regex = output_arg;
11355
11356 if (bgp_regexec(regex, pi->attr->aspath)
11357 == REG_NOMATCH)
11358 continue;
11359 }
11360 if (type == bgp_show_type_prefix_list) {
11361 struct prefix_list *plist = output_arg;
11362
11363 if (prefix_list_apply(plist, dest_p)
11364 != PREFIX_PERMIT)
11365 continue;
11366 }
11367 if (type == bgp_show_type_access_list) {
11368 struct access_list *alist = output_arg;
11369
11370 if (access_list_apply(alist, dest_p) !=
11371 FILTER_PERMIT)
11372 continue;
11373 }
11374 if (type == bgp_show_type_filter_list) {
11375 struct as_list *as_list = output_arg;
11376
11377 if (as_list_apply(as_list, pi->attr->aspath)
11378 != AS_FILTER_PERMIT)
11379 continue;
11380 }
11381 if (type == bgp_show_type_route_map) {
11382 struct route_map *rmap = output_arg;
11383 struct bgp_path_info path;
11384 struct bgp_path_info_extra extra;
11385 struct attr dummy_attr = {};
11386 route_map_result_t ret;
11387
11388 dummy_attr = *pi->attr;
11389
11390 prep_for_rmap_apply(&path, &extra, dest, pi,
11391 pi->peer, &dummy_attr);
11392
11393 ret = route_map_apply(rmap, dest_p, &path);
11394 bgp_attr_flush(&dummy_attr);
11395 if (ret == RMAP_DENYMATCH)
11396 continue;
11397 }
11398 if (type == bgp_show_type_neighbor
11399 || type == bgp_show_type_flap_neighbor
11400 || type == bgp_show_type_damp_neighbor) {
11401 union sockunion *su = output_arg;
11402
11403 if (pi->peer == NULL
11404 || pi->peer->su_remote == NULL
11405 || !sockunion_same(pi->peer->su_remote, su))
11406 continue;
11407 }
11408 if (type == bgp_show_type_cidr_only) {
11409 uint32_t destination;
11410
11411 destination = ntohl(dest_p->u.prefix4.s_addr);
11412 if (IN_CLASSC(destination)
11413 && dest_p->prefixlen == 24)
11414 continue;
11415 if (IN_CLASSB(destination)
11416 && dest_p->prefixlen == 16)
11417 continue;
11418 if (IN_CLASSA(destination)
11419 && dest_p->prefixlen == 8)
11420 continue;
11421 }
11422 if (type == bgp_show_type_prefix_longer) {
11423 p = output_arg;
11424 if (!prefix_match(p, dest_p))
11425 continue;
11426 }
11427 if (type == bgp_show_type_community_all) {
11428 if (!picomm)
11429 continue;
11430 }
11431 if (type == bgp_show_type_community) {
11432 struct community *com = output_arg;
11433
11434 if (!picomm || !community_match(picomm, com))
11435 continue;
11436 }
11437 if (type == bgp_show_type_community_exact) {
11438 struct community *com = output_arg;
11439
11440 if (!picomm || !community_cmp(picomm, com))
11441 continue;
11442 }
11443 if (type == bgp_show_type_community_list) {
11444 struct community_list *list = output_arg;
11445
11446 if (!community_list_match(picomm, list))
11447 continue;
11448 }
11449 if (type == bgp_show_type_community_list_exact) {
11450 struct community_list *list = output_arg;
11451
11452 if (!community_list_exact_match(picomm, list))
11453 continue;
11454 }
11455 if (type == bgp_show_type_lcommunity) {
11456 struct lcommunity *lcom = output_arg;
11457
11458 if (!bgp_attr_get_lcommunity(pi->attr) ||
11459 !lcommunity_match(
11460 bgp_attr_get_lcommunity(pi->attr),
11461 lcom))
11462 continue;
11463 }
11464
11465 if (type == bgp_show_type_lcommunity_exact) {
11466 struct lcommunity *lcom = output_arg;
11467
11468 if (!bgp_attr_get_lcommunity(pi->attr) ||
11469 !lcommunity_cmp(
11470 bgp_attr_get_lcommunity(pi->attr),
11471 lcom))
11472 continue;
11473 }
11474 if (type == bgp_show_type_lcommunity_list) {
11475 struct community_list *list = output_arg;
11476
11477 if (!lcommunity_list_match(
11478 bgp_attr_get_lcommunity(pi->attr),
11479 list))
11480 continue;
11481 }
11482 if (type
11483 == bgp_show_type_lcommunity_list_exact) {
11484 struct community_list *list = output_arg;
11485
11486 if (!lcommunity_list_exact_match(
11487 bgp_attr_get_lcommunity(pi->attr),
11488 list))
11489 continue;
11490 }
11491 if (type == bgp_show_type_lcommunity_all) {
11492 if (!bgp_attr_get_lcommunity(pi->attr))
11493 continue;
11494 }
11495 if (type == bgp_show_type_dampend_paths
11496 || type == bgp_show_type_damp_neighbor) {
11497 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11498 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11499 continue;
11500 }
11501 if (type == bgp_show_type_self_originated) {
11502 if (pi->peer != bgp->peer_self)
11503 continue;
11504 }
11505
11506 if (!use_json && header) {
11507 vty_out(vty,
11508 "BGP table version is %" PRIu64
11509 ", local router ID is %pI4, vrf id ",
11510 table->version, &bgp->router_id);
11511 if (bgp->vrf_id == VRF_UNKNOWN)
11512 vty_out(vty, "%s", VRFID_NONE_STR);
11513 else
11514 vty_out(vty, "%u", bgp->vrf_id);
11515 vty_out(vty, "\n");
11516 vty_out(vty, "Default local pref %u, ",
11517 bgp->default_local_pref);
11518 vty_out(vty, "local AS ");
11519 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11520 &bgp->as);
11521 vty_out(vty, "\n");
11522 if (!detail_routes) {
11523 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11524 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11525 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11526 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11527 }
11528 if (type == bgp_show_type_dampend_paths
11529 || type == bgp_show_type_damp_neighbor)
11530 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11531 else if (type == bgp_show_type_flap_statistics
11532 || type == bgp_show_type_flap_neighbor)
11533 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11534 else if (!detail_routes)
11535 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11536 : BGP_SHOW_HEADER));
11537 header = false;
11538
11539 }
11540 if (rd != NULL && !display && !output_count) {
11541 if (!use_json)
11542 vty_out(vty,
11543 "Route Distinguisher: %s\n",
11544 rd);
11545 }
11546 if (type == bgp_show_type_dampend_paths
11547 || type == bgp_show_type_damp_neighbor)
11548 damp_route_vty_out(vty, dest_p, pi, display,
11549 AFI_IP, safi, use_json,
11550 json_paths);
11551 else if (type == bgp_show_type_flap_statistics
11552 || type == bgp_show_type_flap_neighbor)
11553 flap_route_vty_out(vty, dest_p, pi, display,
11554 AFI_IP, safi, use_json,
11555 json_paths);
11556 else {
11557 if (detail_routes || detail_json) {
11558 const struct prefix_rd *prd = NULL;
11559
11560 if (dest->pdest)
11561 prd = bgp_rd_from_dest(
11562 dest->pdest, safi);
11563
11564 if (!use_json)
11565 route_vty_out_detail_header(
11566 vty, bgp, dest,
11567 bgp_dest_get_prefix(
11568 dest),
11569 prd, table->afi, safi,
11570 NULL, false);
11571
11572 route_vty_out_detail(
11573 vty, bgp, dest, dest_p, pi,
11574 family2afi(dest_p->family),
11575 safi, RPKI_NOT_BEING_USED,
11576 json_paths);
11577 } else {
11578 route_vty_out(vty, dest_p, pi, display,
11579 safi, json_paths, wide);
11580 }
11581 }
11582 display++;
11583 }
11584
11585 if (display) {
11586 output_count++;
11587 if (!use_json)
11588 continue;
11589
11590 /* encode prefix */
11591 if (dest_p->family == AF_FLOWSPEC) {
11592 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11593
11594
11595 bgp_fs_nlri_get_string(
11596 (unsigned char *)
11597 dest_p->u.prefix_flowspec.ptr,
11598 dest_p->u.prefix_flowspec.prefixlen,
11599 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11600 family2afi(dest_p->u
11601 .prefix_flowspec.family));
11602 if (first)
11603 vty_out(vty, "\"%s/%d\": ", retstr,
11604 dest_p->u.prefix_flowspec
11605 .prefixlen);
11606 else
11607 vty_out(vty, ",\"%s/%d\": ", retstr,
11608 dest_p->u.prefix_flowspec
11609 .prefixlen);
11610 } else {
11611 if (first)
11612 vty_out(vty, "\"%pFX\": ", dest_p);
11613 else
11614 vty_out(vty, ",\"%pFX\": ", dest_p);
11615 }
11616
11617 /* This is used for 'json detail' vty keywords.
11618 *
11619 * In plain 'json' the per-prefix header is encoded
11620 * as a standalone dictionary in the first json_paths
11621 * array element:
11622 * "<prefix>": [{header}, {path-1}, {path-N}]
11623 * (which is confusing and borderline broken)
11624 *
11625 * For 'json detail' this changes the value
11626 * of each prefix-key to be a dictionary where each
11627 * header item has its own key, and json_paths is
11628 * tucked under the "paths" key:
11629 * "<prefix>": {
11630 * "<header-key-1>": <header-val-1>,
11631 * "<header-key-N>": <header-val-N>,
11632 * "paths": [{path-1}, {path-N}]
11633 * }
11634 */
11635 if (json_detail_header && json_paths != NULL) {
11636 const struct prefix_rd *prd;
11637
11638 /* Start per-prefix dictionary */
11639 vty_out(vty, "{\n");
11640
11641 prd = bgp_rd_from_dest(dest, safi);
11642
11643 route_vty_out_detail_header(
11644 vty, bgp, dest,
11645 bgp_dest_get_prefix(dest), prd,
11646 table->afi, safi, json_paths, true);
11647
11648 vty_out(vty, "\"paths\": ");
11649 json_detail_header_used = true;
11650 }
11651
11652 /*
11653 * We are using no_pretty here because under
11654 * extremely high settings( say lots and lots of
11655 * routes with lots and lots of ways to reach
11656 * that route via different paths ) this can
11657 * save several minutes of output when FRR
11658 * is run on older cpu's or more underperforming
11659 * routers out there
11660 */
11661 vty_json_no_pretty(vty, json_paths);
11662
11663 /* End per-prefix dictionary */
11664 if (json_detail_header_used)
11665 vty_out(vty, "} ");
11666
11667 json_paths = NULL;
11668 first = 0;
11669 } else
11670 json_object_free(json_paths);
11671 }
11672
11673 if (output_cum) {
11674 output_count += *output_cum;
11675 *output_cum = output_count;
11676 }
11677 if (total_cum) {
11678 total_count += *total_cum;
11679 *total_cum = total_count;
11680 }
11681 if (use_json) {
11682 if (rd) {
11683 vty_out(vty, " }%s ", (is_last ? "" : ","));
11684 }
11685 if (is_last) {
11686 unsigned long i;
11687 for (i = 0; i < *json_header_depth; ++i)
11688 vty_out(vty, " } ");
11689 if (!all)
11690 vty_out(vty, "\n");
11691 }
11692 } else {
11693 if (is_last) {
11694 /* No route is displayed */
11695 if (output_count == 0) {
11696 if (type == bgp_show_type_normal)
11697 vty_out(vty,
11698 "No BGP prefixes displayed, %ld exist\n",
11699 total_count);
11700 } else
11701 vty_out(vty,
11702 "\nDisplayed %ld routes and %ld total paths\n",
11703 output_count, total_count);
11704 }
11705 }
11706
11707 return CMD_SUCCESS;
11708 }
11709
11710 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11711 struct bgp_table *table, struct prefix_rd *prd_match,
11712 enum bgp_show_type type, void *output_arg,
11713 uint16_t show_flags)
11714 {
11715 struct bgp_dest *dest, *next;
11716 unsigned long output_cum = 0;
11717 unsigned long total_cum = 0;
11718 unsigned long json_header_depth = 0;
11719 struct bgp_table *itable;
11720 bool show_msg;
11721 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11722
11723 show_msg = (!use_json && type == bgp_show_type_normal);
11724
11725 for (dest = bgp_table_top(table); dest; dest = next) {
11726 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11727
11728 next = bgp_route_next(dest);
11729 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11730 continue;
11731
11732 itable = bgp_dest_get_bgp_table_info(dest);
11733 if (itable != NULL) {
11734 struct prefix_rd prd;
11735 char rd[RD_ADDRSTRLEN];
11736
11737 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11738 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11739 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11740 rd, next == NULL, &output_cum,
11741 &total_cum, &json_header_depth,
11742 show_flags, RPKI_NOT_BEING_USED);
11743 if (next == NULL)
11744 show_msg = false;
11745 }
11746 }
11747 if (show_msg) {
11748 if (output_cum == 0)
11749 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11750 total_cum);
11751 else
11752 vty_out(vty,
11753 "\nDisplayed %ld routes and %ld total paths\n",
11754 output_cum, total_cum);
11755 } else {
11756 if (use_json && output_cum == 0)
11757 vty_out(vty, "{}\n");
11758 }
11759 return CMD_SUCCESS;
11760 }
11761
11762 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11763 enum bgp_show_type type, void *output_arg,
11764 uint16_t show_flags, enum rpki_states rpki_target_state)
11765 {
11766 struct bgp_table *table;
11767 unsigned long json_header_depth = 0;
11768 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11769
11770 if (bgp == NULL) {
11771 bgp = bgp_get_default();
11772 }
11773
11774 if (bgp == NULL) {
11775 if (!use_json)
11776 vty_out(vty, "No BGP process is configured\n");
11777 else
11778 vty_out(vty, "{}\n");
11779 return CMD_WARNING;
11780 }
11781
11782 /* Labeled-unicast routes live in the unicast table. */
11783 if (safi == SAFI_LABELED_UNICAST)
11784 safi = SAFI_UNICAST;
11785
11786 table = bgp->rib[afi][safi];
11787 /* use MPLS and ENCAP specific shows until they are merged */
11788 if (safi == SAFI_MPLS_VPN) {
11789 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11790 output_arg, show_flags);
11791 }
11792
11793 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11794 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11795 output_arg, use_json,
11796 1, NULL, NULL);
11797 }
11798
11799 if (safi == SAFI_EVPN)
11800 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11801
11802 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11803 NULL, NULL, &json_header_depth, show_flags,
11804 rpki_target_state);
11805 }
11806
11807 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11808 safi_t safi, uint16_t show_flags)
11809 {
11810 struct listnode *node, *nnode;
11811 struct bgp *bgp;
11812 int is_first = 1;
11813 bool route_output = false;
11814 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11815
11816 if (use_json)
11817 vty_out(vty, "{\n");
11818
11819 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11820 route_output = true;
11821 if (use_json) {
11822 if (!is_first)
11823 vty_out(vty, ",\n");
11824 else
11825 is_first = 0;
11826
11827 vty_out(vty, "\"%s\":",
11828 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11829 ? VRF_DEFAULT_NAME
11830 : bgp->name);
11831 } else {
11832 vty_out(vty, "\nInstance %s:\n",
11833 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11834 ? VRF_DEFAULT_NAME
11835 : bgp->name);
11836 }
11837 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11838 show_flags, RPKI_NOT_BEING_USED);
11839 }
11840
11841 if (use_json)
11842 vty_out(vty, "}\n");
11843 else if (!route_output)
11844 vty_out(vty, "%% BGP instance not found\n");
11845 }
11846
11847 /* Header of detailed BGP route information */
11848 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11849 struct bgp_dest *dest, const struct prefix *p,
11850 const struct prefix_rd *prd, afi_t afi,
11851 safi_t safi, json_object *json,
11852 bool incremental_print)
11853 {
11854 struct bgp_path_info *pi;
11855 struct peer *peer;
11856 struct listnode *node, *nnode;
11857 char buf1[RD_ADDRSTRLEN];
11858 int count = 0;
11859 int best = 0;
11860 int suppress = 0;
11861 int accept_own = 0;
11862 int route_filter_translated_v4 = 0;
11863 int route_filter_v4 = 0;
11864 int route_filter_translated_v6 = 0;
11865 int route_filter_v6 = 0;
11866 int llgr_stale = 0;
11867 int no_llgr = 0;
11868 int accept_own_nexthop = 0;
11869 int blackhole = 0;
11870 int no_export = 0;
11871 int no_advertise = 0;
11872 int local_as = 0;
11873 int no_peer = 0;
11874 int first = 1;
11875 int has_valid_label = 0;
11876 mpls_label_t label = 0;
11877 json_object *json_adv_to = NULL;
11878 uint32_t ttl = 0;
11879 uint32_t bos = 0;
11880 uint32_t exp = 0;
11881
11882 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11883
11884 has_valid_label = bgp_is_valid_label(&label);
11885
11886 if (safi == SAFI_EVPN) {
11887 if (!json) {
11888 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11889 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11890 bgp->asnotation)
11891 : "",
11892 prd ? ":" : "", (struct prefix_evpn *)p);
11893 } else {
11894 json_object_string_add(
11895 json, "rd",
11896 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11897 bgp->asnotation)
11898 : "");
11899 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11900 }
11901 } else {
11902 if (!json) {
11903 vty_out(vty,
11904 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11905 "\n",
11906 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11907 ? prefix_rd2str(prd, buf1,
11908 sizeof(buf1),
11909 bgp->asnotation)
11910 : ""),
11911 safi == SAFI_MPLS_VPN ? ":" : "", p,
11912 dest->version);
11913
11914 } else {
11915 if (incremental_print) {
11916 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11917 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11918 dest->version);
11919 } else {
11920 json_object_string_addf(json, "prefix", "%pFX",
11921 p);
11922 json_object_int_add(json, "version",
11923 dest->version);
11924 }
11925 }
11926 }
11927
11928 if (has_valid_label) {
11929 if (json) {
11930 if (incremental_print)
11931 vty_out(vty, "\"localLabel\": \"%u\",\n",
11932 label);
11933 else
11934 json_object_int_add(json, "localLabel", label);
11935 } else
11936 vty_out(vty, "Local label: %d\n", label);
11937 }
11938
11939 if (!json)
11940 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11941 vty_out(vty, "not allocated\n");
11942
11943 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11944 struct community *picomm = NULL;
11945
11946 picomm = bgp_attr_get_community(pi->attr);
11947
11948 count++;
11949 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11950 best = count;
11951 if (bgp_path_suppressed(pi))
11952 suppress = 1;
11953
11954 if (!picomm)
11955 continue;
11956
11957 no_advertise += community_include(
11958 picomm, COMMUNITY_NO_ADVERTISE);
11959 no_export +=
11960 community_include(picomm, COMMUNITY_NO_EXPORT);
11961 local_as +=
11962 community_include(picomm, COMMUNITY_LOCAL_AS);
11963 accept_own +=
11964 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11965 route_filter_translated_v4 += community_include(
11966 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11967 route_filter_translated_v6 += community_include(
11968 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11969 route_filter_v4 += community_include(
11970 picomm, COMMUNITY_ROUTE_FILTER_v4);
11971 route_filter_v6 += community_include(
11972 picomm, COMMUNITY_ROUTE_FILTER_v6);
11973 llgr_stale +=
11974 community_include(picomm, COMMUNITY_LLGR_STALE);
11975 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11976 accept_own_nexthop += community_include(
11977 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11978 blackhole +=
11979 community_include(picomm, COMMUNITY_BLACKHOLE);
11980 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11981 }
11982 }
11983
11984 if (!json) {
11985 vty_out(vty, "Paths: (%d available", count);
11986 if (best) {
11987 vty_out(vty, ", best #%d", best);
11988 if (safi == SAFI_UNICAST) {
11989 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11990 vty_out(vty, ", table %s",
11991 VRF_DEFAULT_NAME);
11992 else
11993 vty_out(vty, ", vrf %s",
11994 bgp->name);
11995 }
11996 } else
11997 vty_out(vty, ", no best path");
11998
11999 if (accept_own)
12000 vty_out(vty,
12001 ", accept own local route exported and imported in different VRF");
12002 else if (route_filter_translated_v4)
12003 vty_out(vty,
12004 ", mark translated RTs for VPNv4 route filtering");
12005 else if (route_filter_v4)
12006 vty_out(vty,
12007 ", attach RT as-is for VPNv4 route filtering");
12008 else if (route_filter_translated_v6)
12009 vty_out(vty,
12010 ", mark translated RTs for VPNv6 route filtering");
12011 else if (route_filter_v6)
12012 vty_out(vty,
12013 ", attach RT as-is for VPNv6 route filtering");
12014 else if (llgr_stale)
12015 vty_out(vty,
12016 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
12017 else if (no_llgr)
12018 vty_out(vty,
12019 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
12020 else if (accept_own_nexthop)
12021 vty_out(vty,
12022 ", accept local nexthop");
12023 else if (blackhole)
12024 vty_out(vty, ", inform peer to blackhole prefix");
12025 else if (no_export)
12026 vty_out(vty, ", not advertised to EBGP peer");
12027 else if (no_advertise)
12028 vty_out(vty, ", not advertised to any peer");
12029 else if (local_as)
12030 vty_out(vty, ", not advertised outside local AS");
12031 else if (no_peer)
12032 vty_out(vty,
12033 ", inform EBGP peer not to advertise to their EBGP peers");
12034
12035 if (suppress)
12036 vty_out(vty,
12037 ", Advertisements suppressed by an aggregate.");
12038 vty_out(vty, ")\n");
12039 }
12040
12041 /* If we are not using addpath then we can display Advertised to and
12042 * that will
12043 * show what peers we advertised the bestpath to. If we are using
12044 * addpath
12045 * though then we must display Advertised to on a path-by-path basis. */
12046 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12047 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12048 if (bgp_adj_out_lookup(peer, dest, 0)) {
12049 if (json && !json_adv_to)
12050 json_adv_to = json_object_new_object();
12051
12052 route_vty_out_advertised_to(
12053 vty, peer, &first,
12054 " Advertised to non peer-group peers:\n ",
12055 json_adv_to);
12056 }
12057 }
12058
12059 if (json && json_adv_to) {
12060 if (incremental_print) {
12061 vty_out(vty, "\"advertisedTo\": ");
12062 vty_json(vty, json_adv_to);
12063 vty_out(vty, ",");
12064 } else
12065 json_object_object_add(json, "advertisedTo",
12066 json_adv_to);
12067 } else {
12068 if (!json && first)
12069 vty_out(vty, " Not advertised to any peer");
12070 vty_out(vty, "\n");
12071 }
12072 }
12073 }
12074
12075 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12076 struct bgp_dest *bgp_node, struct vty *vty,
12077 struct bgp *bgp, afi_t afi, safi_t safi,
12078 json_object *json, enum bgp_path_type pathtype,
12079 int *display, enum rpki_states rpki_target_state)
12080 {
12081 struct bgp_path_info *pi;
12082 int header = 1;
12083 json_object *json_header = NULL;
12084 json_object *json_paths = NULL;
12085 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12086
12087 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12088 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12089
12090 if (p->family == AF_INET || p->family == AF_INET6)
12091 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12092 pi->peer, pi->attr, p);
12093
12094 if (rpki_target_state != RPKI_NOT_BEING_USED
12095 && rpki_curr_state != rpki_target_state)
12096 continue;
12097
12098 if (json && !json_paths) {
12099 /* Instantiate json_paths only if path is valid */
12100 json_paths = json_object_new_array();
12101 if (pfx_rd)
12102 json_header = json_object_new_object();
12103 else
12104 json_header = json;
12105 }
12106
12107 if (header) {
12108 route_vty_out_detail_header(
12109 vty, bgp, bgp_node,
12110 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12111 safi, json_header, false);
12112 header = 0;
12113 }
12114 (*display)++;
12115
12116 if (pathtype == BGP_PATH_SHOW_ALL
12117 || (pathtype == BGP_PATH_SHOW_BESTPATH
12118 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12119 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12120 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12121 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12122 route_vty_out_detail(vty, bgp, bgp_node,
12123 bgp_dest_get_prefix(bgp_node), pi,
12124 AFI_IP, safi, rpki_curr_state,
12125 json_paths);
12126 }
12127
12128 if (json && json_paths) {
12129 json_object_object_add(json_header, "paths", json_paths);
12130
12131 if (pfx_rd)
12132 json_object_object_addf(
12133 json, json_header,
12134 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12135 }
12136 }
12137
12138 /*
12139 * Return rd based on safi
12140 */
12141 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12142 safi_t safi)
12143 {
12144 switch (safi) {
12145 case SAFI_MPLS_VPN:
12146 case SAFI_ENCAP:
12147 case SAFI_EVPN:
12148 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12149 case SAFI_UNSPEC:
12150 case SAFI_UNICAST:
12151 case SAFI_MULTICAST:
12152 case SAFI_LABELED_UNICAST:
12153 case SAFI_FLOWSPEC:
12154 case SAFI_MAX:
12155 return NULL;
12156 }
12157
12158 assert(!"Reached end of function when we were not expecting it");
12159 }
12160
12161 /* Display specified route of BGP table. */
12162 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12163 struct bgp_table *rib, const char *ip_str,
12164 afi_t afi, safi_t safi,
12165 enum rpki_states rpki_target_state,
12166 struct prefix_rd *prd, int prefix_check,
12167 enum bgp_path_type pathtype, bool use_json)
12168 {
12169 int ret;
12170 int display = 0;
12171 struct prefix match;
12172 struct bgp_dest *dest;
12173 struct bgp_dest *rm;
12174 struct bgp_table *table;
12175 json_object *json = NULL;
12176 json_object *json_paths = NULL;
12177
12178 /* Check IP address argument. */
12179 ret = str2prefix(ip_str, &match);
12180 if (!ret) {
12181 vty_out(vty, "address is malformed\n");
12182 return CMD_WARNING;
12183 }
12184
12185 match.family = afi2family(afi);
12186
12187 if (use_json)
12188 json = json_object_new_object();
12189
12190 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12191 for (dest = bgp_table_top(rib); dest;
12192 dest = bgp_route_next(dest)) {
12193 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12194
12195 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12196 continue;
12197 table = bgp_dest_get_bgp_table_info(dest);
12198 if (!table)
12199 continue;
12200
12201 rm = bgp_node_match(table, &match);
12202 if (rm == NULL)
12203 continue;
12204
12205 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12206 if (prefix_check
12207 && rm_p->prefixlen != match.prefixlen) {
12208 bgp_dest_unlock_node(rm);
12209 continue;
12210 }
12211
12212 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12213 bgp, afi, safi, json, pathtype,
12214 &display, rpki_target_state);
12215
12216 bgp_dest_unlock_node(rm);
12217 }
12218 } else if (safi == SAFI_EVPN) {
12219 struct bgp_dest *longest_pfx;
12220 bool is_exact_pfxlen_match = false;
12221
12222 for (dest = bgp_table_top(rib); dest;
12223 dest = bgp_route_next(dest)) {
12224 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12225
12226 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12227 continue;
12228 table = bgp_dest_get_bgp_table_info(dest);
12229 if (!table)
12230 continue;
12231
12232 longest_pfx = NULL;
12233 is_exact_pfxlen_match = false;
12234 /*
12235 * Search through all the prefixes for a match. The
12236 * pfx's are enumerated in ascending order of pfxlens.
12237 * So, the last pfx match is the longest match. Set
12238 * is_exact_pfxlen_match when we get exact pfxlen match
12239 */
12240 for (rm = bgp_table_top(table); rm;
12241 rm = bgp_route_next(rm)) {
12242 const struct prefix *rm_p =
12243 bgp_dest_get_prefix(rm);
12244 /*
12245 * Get prefixlen of the ip-prefix within type5
12246 * evpn route
12247 */
12248 if (evpn_type5_prefix_match(rm_p, &match)
12249 && rm->info) {
12250 longest_pfx = rm;
12251 int type5_pfxlen =
12252 bgp_evpn_get_type5_prefixlen(
12253 rm_p);
12254 if (type5_pfxlen == match.prefixlen) {
12255 is_exact_pfxlen_match = true;
12256 bgp_dest_unlock_node(rm);
12257 break;
12258 }
12259 }
12260 }
12261
12262 if (!longest_pfx)
12263 continue;
12264
12265 if (prefix_check && !is_exact_pfxlen_match)
12266 continue;
12267
12268 rm = longest_pfx;
12269 bgp_dest_lock_node(rm);
12270
12271 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12272 bgp, afi, safi, json, pathtype,
12273 &display, rpki_target_state);
12274
12275 bgp_dest_unlock_node(rm);
12276 }
12277 } else if (safi == SAFI_FLOWSPEC) {
12278 if (use_json)
12279 json_paths = json_object_new_array();
12280
12281 display = bgp_flowspec_display_match_per_ip(afi, rib,
12282 &match, prefix_check,
12283 vty,
12284 use_json,
12285 json_paths);
12286 if (use_json) {
12287 if (display)
12288 json_object_object_add(json, "paths",
12289 json_paths);
12290 else
12291 json_object_free(json_paths);
12292 }
12293 } else {
12294 dest = bgp_node_match(rib, &match);
12295 if (dest != NULL) {
12296 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12297 if (!prefix_check
12298 || dest_p->prefixlen == match.prefixlen) {
12299 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12300 safi, json, pathtype,
12301 &display, rpki_target_state);
12302 }
12303
12304 bgp_dest_unlock_node(dest);
12305 }
12306 }
12307
12308 if (use_json) {
12309 vty_json(vty, json);
12310 } else {
12311 if (!display) {
12312 vty_out(vty, "%% Network not in table\n");
12313 return CMD_WARNING;
12314 }
12315 }
12316
12317 return CMD_SUCCESS;
12318 }
12319
12320 /* Display specified route of Main RIB */
12321 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12322 afi_t afi, safi_t safi, struct prefix_rd *prd,
12323 int prefix_check, enum bgp_path_type pathtype,
12324 enum rpki_states rpki_target_state, bool use_json)
12325 {
12326 if (!bgp) {
12327 bgp = bgp_get_default();
12328 if (!bgp) {
12329 if (!use_json)
12330 vty_out(vty, "No BGP process is configured\n");
12331 else
12332 vty_out(vty, "{}\n");
12333 return CMD_WARNING;
12334 }
12335 }
12336
12337 /* labeled-unicast routes live in the unicast table */
12338 if (safi == SAFI_LABELED_UNICAST)
12339 safi = SAFI_UNICAST;
12340
12341 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12342 afi, safi, rpki_target_state, prd,
12343 prefix_check, pathtype, use_json);
12344 }
12345
12346 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12347 struct cmd_token **argv, bool exact, afi_t afi,
12348 safi_t safi, bool uj)
12349 {
12350 struct lcommunity *lcom;
12351 struct buffer *b;
12352 int i;
12353 char *str;
12354 int first = 0;
12355 uint16_t show_flags = 0;
12356 int ret;
12357
12358 if (uj)
12359 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12360
12361 b = buffer_new(1024);
12362 for (i = 0; i < argc; i++) {
12363 if (first)
12364 buffer_putc(b, ' ');
12365 else {
12366 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12367 first = 1;
12368 buffer_putstr(b, argv[i]->arg);
12369 }
12370 }
12371 }
12372 buffer_putc(b, '\0');
12373
12374 str = buffer_getstr(b);
12375 buffer_free(b);
12376
12377 lcom = lcommunity_str2com(str);
12378 XFREE(MTYPE_TMP, str);
12379 if (!lcom) {
12380 vty_out(vty, "%% Large-community malformed\n");
12381 return CMD_WARNING;
12382 }
12383
12384 ret = bgp_show(vty, bgp, afi, safi,
12385 (exact ? bgp_show_type_lcommunity_exact
12386 : bgp_show_type_lcommunity),
12387 lcom, show_flags, RPKI_NOT_BEING_USED);
12388
12389 lcommunity_free(&lcom);
12390 return ret;
12391 }
12392
12393 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12394 const char *lcom, bool exact, afi_t afi,
12395 safi_t safi, bool uj)
12396 {
12397 struct community_list *list;
12398 uint16_t show_flags = 0;
12399
12400 if (uj)
12401 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12402
12403
12404 list = community_list_lookup(bgp_clist, lcom, 0,
12405 LARGE_COMMUNITY_LIST_MASTER);
12406 if (list == NULL) {
12407 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12408 lcom);
12409 return CMD_WARNING;
12410 }
12411
12412 return bgp_show(vty, bgp, afi, safi,
12413 (exact ? bgp_show_type_lcommunity_list_exact
12414 : bgp_show_type_lcommunity_list),
12415 list, show_flags, RPKI_NOT_BEING_USED);
12416 }
12417
12418 DEFUN (show_ip_bgp_large_community_list,
12419 show_ip_bgp_large_community_list_cmd,
12420 "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]",
12421 SHOW_STR
12422 IP_STR
12423 BGP_STR
12424 BGP_INSTANCE_HELP_STR
12425 BGP_AFI_HELP_STR
12426 BGP_SAFI_WITH_LABEL_HELP_STR
12427 "Display routes matching the large-community-list\n"
12428 "large-community-list number\n"
12429 "large-community-list name\n"
12430 "Exact match of the large-communities\n"
12431 JSON_STR)
12432 {
12433 afi_t afi = AFI_IP6;
12434 safi_t safi = SAFI_UNICAST;
12435 int idx = 0;
12436 bool exact_match = 0;
12437 struct bgp *bgp = NULL;
12438 bool uj = use_json(argc, argv);
12439
12440 if (uj)
12441 argc--;
12442
12443 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12444 &bgp, uj);
12445 if (!idx)
12446 return CMD_WARNING;
12447
12448 argv_find(argv, argc, "large-community-list", &idx);
12449
12450 const char *clist_number_or_name = argv[++idx]->arg;
12451
12452 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12453 exact_match = 1;
12454
12455 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12456 exact_match, afi, safi, uj);
12457 }
12458 DEFUN (show_ip_bgp_large_community,
12459 show_ip_bgp_large_community_cmd,
12460 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12461 SHOW_STR
12462 IP_STR
12463 BGP_STR
12464 BGP_INSTANCE_HELP_STR
12465 BGP_AFI_HELP_STR
12466 BGP_SAFI_WITH_LABEL_HELP_STR
12467 "Display routes matching the large-communities\n"
12468 "List of large-community numbers\n"
12469 "Exact match of the large-communities\n"
12470 JSON_STR)
12471 {
12472 afi_t afi = AFI_IP6;
12473 safi_t safi = SAFI_UNICAST;
12474 int idx = 0;
12475 bool exact_match = 0;
12476 struct bgp *bgp = NULL;
12477 bool uj = use_json(argc, argv);
12478 uint16_t show_flags = 0;
12479
12480 if (uj) {
12481 argc--;
12482 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12483 }
12484
12485 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12486 &bgp, uj);
12487 if (!idx)
12488 return CMD_WARNING;
12489
12490 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12491 if (argv_find(argv, argc, "exact-match", &idx)) {
12492 argc--;
12493 exact_match = 1;
12494 }
12495 return bgp_show_lcommunity(vty, bgp, argc, argv,
12496 exact_match, afi, safi, uj);
12497 } else
12498 return bgp_show(vty, bgp, afi, safi,
12499 bgp_show_type_lcommunity_all, NULL, show_flags,
12500 RPKI_NOT_BEING_USED);
12501 }
12502
12503 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12504 safi_t safi, struct json_object *json_array);
12505 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12506 safi_t safi, struct json_object *json);
12507
12508
12509 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12510 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12511 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12512 "Display number of prefixes for all afi/safi\n" JSON_STR)
12513 {
12514 bool uj = use_json(argc, argv);
12515 struct bgp *bgp = NULL;
12516 safi_t safi = SAFI_UNICAST;
12517 afi_t afi = AFI_IP6;
12518 int idx = 0;
12519 struct json_object *json_all = NULL;
12520 struct json_object *json_afi_safi = NULL;
12521
12522 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12523 &bgp, false);
12524 if (!idx)
12525 return CMD_WARNING;
12526
12527 if (uj)
12528 json_all = json_object_new_object();
12529
12530 FOREACH_AFI_SAFI (afi, safi) {
12531 /*
12532 * So limit output to those afi/safi pairs that
12533 * actually have something interesting in them
12534 */
12535 if (strmatch(get_afi_safi_str(afi, safi, true),
12536 "Unknown")) {
12537 continue;
12538 }
12539 if (uj) {
12540 json_afi_safi = json_object_new_array();
12541 json_object_object_add(
12542 json_all,
12543 get_afi_safi_str(afi, safi, true),
12544 json_afi_safi);
12545 } else {
12546 json_afi_safi = NULL;
12547 }
12548
12549 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12550 }
12551
12552 if (uj)
12553 vty_json(vty, json_all);
12554
12555 return CMD_SUCCESS;
12556 }
12557
12558 /* BGP route print out function without JSON */
12559 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12560 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12561 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12562 SHOW_STR
12563 IP_STR
12564 BGP_STR
12565 BGP_INSTANCE_HELP_STR
12566 L2VPN_HELP_STR
12567 EVPN_HELP_STR
12568 "BGP RIB advertisement statistics\n"
12569 JSON_STR)
12570 {
12571 afi_t afi = AFI_IP6;
12572 safi_t safi = SAFI_UNICAST;
12573 struct bgp *bgp = NULL;
12574 int idx = 0, ret;
12575 bool uj = use_json(argc, argv);
12576 struct json_object *json_afi_safi = NULL, *json = NULL;
12577
12578 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12579 &bgp, false);
12580 if (!idx)
12581 return CMD_WARNING;
12582
12583 if (uj)
12584 json_afi_safi = json_object_new_array();
12585 else
12586 json_afi_safi = NULL;
12587
12588 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12589
12590 if (uj) {
12591 json = json_object_new_object();
12592 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12593 json_afi_safi);
12594 vty_json(vty, json);
12595 }
12596 return ret;
12597 }
12598
12599 /* BGP route print out function without JSON */
12600 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12601 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12602 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12603 "]]\
12604 statistics [json]",
12605 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12606 BGP_SAFI_WITH_LABEL_HELP_STR
12607 "BGP RIB advertisement statistics\n" JSON_STR)
12608 {
12609 afi_t afi = AFI_IP6;
12610 safi_t safi = SAFI_UNICAST;
12611 struct bgp *bgp = NULL;
12612 int idx = 0, ret;
12613 bool uj = use_json(argc, argv);
12614 struct json_object *json_afi_safi = NULL, *json = NULL;
12615
12616 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12617 &bgp, false);
12618 if (!idx)
12619 return CMD_WARNING;
12620
12621 if (uj)
12622 json_afi_safi = json_object_new_array();
12623 else
12624 json_afi_safi = NULL;
12625
12626 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12627
12628 if (uj) {
12629 json = json_object_new_object();
12630 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12631 json_afi_safi);
12632 vty_json(vty, json);
12633 }
12634 return ret;
12635 }
12636
12637 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12638 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12639 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12640 "]] [all$all] dampening parameters [json]",
12641 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12642 BGP_SAFI_WITH_LABEL_HELP_STR
12643 "Display the entries for all address families\n"
12644 "Display detailed information about dampening\n"
12645 "Display detail of configured dampening parameters\n"
12646 JSON_STR)
12647 {
12648 afi_t afi = AFI_IP6;
12649 safi_t safi = SAFI_UNICAST;
12650 struct bgp *bgp = NULL;
12651 int idx = 0;
12652 uint16_t show_flags = 0;
12653 bool uj = use_json(argc, argv);
12654
12655 if (uj) {
12656 argc--;
12657 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12658 }
12659
12660 /* [<ipv4|ipv6> [all]] */
12661 if (all) {
12662 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12663 if (argv_find(argv, argc, "ipv4", &idx))
12664 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12665
12666 if (argv_find(argv, argc, "ipv6", &idx))
12667 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12668 }
12669
12670 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12671 &bgp, false);
12672 if (!idx)
12673 return CMD_WARNING;
12674
12675 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12676 }
12677
12678 /* BGP route print out function */
12679 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12680 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12681 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12682 "]]\
12683 [all$all]\
12684 [cidr-only\
12685 |dampening <flap-statistics|dampened-paths>\
12686 |community [AA:NN|local-AS|no-advertise|no-export\
12687 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12688 |accept-own|accept-own-nexthop|route-filter-v6\
12689 |route-filter-v4|route-filter-translated-v6\
12690 |route-filter-translated-v4] [exact-match]\
12691 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12692 |filter-list AS_PATH_FILTER_NAME\
12693 |prefix-list WORD\
12694 |access-list ACCESSLIST_NAME\
12695 |route-map RMAP_NAME\
12696 |rpki <invalid|valid|notfound>\
12697 |version (1-4294967295)\
12698 |alias ALIAS_NAME\
12699 |A.B.C.D/M longer-prefixes\
12700 |X:X::X:X/M longer-prefixes\
12701 |"BGP_SELF_ORIG_CMD_STR"\
12702 |detail-routes$detail_routes\
12703 ] [json$uj [detail$detail_json] | wide$wide]",
12704 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12705 BGP_SAFI_WITH_LABEL_HELP_STR
12706 "Display the entries for all address families\n"
12707 "Display only routes with non-natural netmasks\n"
12708 "Display detailed information about dampening\n"
12709 "Display flap statistics of routes\n"
12710 "Display paths suppressed due to dampening\n"
12711 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12712 "Do not send outside local AS (well-known community)\n"
12713 "Do not advertise to any peer (well-known community)\n"
12714 "Do not export to next AS (well-known community)\n"
12715 "Graceful shutdown (well-known community)\n"
12716 "Do not export to any peer (well-known community)\n"
12717 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12718 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12719 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12720 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12721 "Should accept VPN route with local nexthop (well-known community)\n"
12722 "RT VPNv6 route filtering (well-known community)\n"
12723 "RT VPNv4 route filtering (well-known community)\n"
12724 "RT translated VPNv6 route filtering (well-known community)\n"
12725 "RT translated VPNv4 route filtering (well-known community)\n"
12726 "Exact match of the communities\n"
12727 "Community-list number\n"
12728 "Community-list name\n"
12729 "Display routes matching the community-list\n"
12730 "Exact match of the communities\n"
12731 "Display routes conforming to the filter-list\n"
12732 "Regular expression access list name\n"
12733 "Display routes conforming to the prefix-list\n"
12734 "Prefix-list name\n"
12735 "Display routes conforming to the access-list\n"
12736 "Access-list name\n"
12737 "Display routes matching the route-map\n"
12738 "A route-map to match on\n"
12739 "RPKI route types\n"
12740 "A valid path as determined by rpki\n"
12741 "A invalid path as determined by rpki\n"
12742 "A path that has no rpki data\n"
12743 "Display prefixes with matching version numbers\n"
12744 "Version number and above\n"
12745 "Display prefixes with matching BGP community alias\n"
12746 "BGP community alias\n"
12747 "IPv4 prefix\n"
12748 "Display route and more specific routes\n"
12749 "IPv6 prefix\n"
12750 "Display route and more specific routes\n"
12751 BGP_SELF_ORIG_HELP_STR
12752 "Display detailed version of all routes\n"
12753 JSON_STR
12754 "Display detailed version of JSON output\n"
12755 "Increase table width for longer prefixes\n")
12756 {
12757 afi_t afi = AFI_IP6;
12758 safi_t safi = SAFI_UNICAST;
12759 enum bgp_show_type sh_type = bgp_show_type_normal;
12760 void *output_arg = NULL;
12761 struct bgp *bgp = NULL;
12762 int idx = 0;
12763 int exact_match = 0;
12764 char *community = NULL;
12765 bool first = true;
12766 uint16_t show_flags = 0;
12767 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12768 struct prefix p;
12769
12770 if (uj) {
12771 argc--;
12772 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12773 }
12774
12775 if (detail_json)
12776 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12777
12778 if (detail_routes)
12779 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12780
12781 /* [<ipv4|ipv6> [all]] */
12782 if (all) {
12783 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12784
12785 if (argv_find(argv, argc, "ipv4", &idx))
12786 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12787
12788 if (argv_find(argv, argc, "ipv6", &idx))
12789 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12790 }
12791
12792 if (wide)
12793 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12794
12795 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12796 &bgp, uj);
12797 if (!idx)
12798 return CMD_WARNING;
12799
12800 if (argv_find(argv, argc, "cidr-only", &idx))
12801 sh_type = bgp_show_type_cidr_only;
12802
12803 if (argv_find(argv, argc, "dampening", &idx)) {
12804 if (argv_find(argv, argc, "dampened-paths", &idx))
12805 sh_type = bgp_show_type_dampend_paths;
12806 else if (argv_find(argv, argc, "flap-statistics", &idx))
12807 sh_type = bgp_show_type_flap_statistics;
12808 }
12809
12810 if (argv_find(argv, argc, "community", &idx)) {
12811 char *maybecomm = NULL;
12812
12813 if (idx + 1 < argc) {
12814 if (argv[idx + 1]->type == VARIABLE_TKN)
12815 maybecomm = argv[idx + 1]->arg;
12816 else
12817 maybecomm = argv[idx + 1]->text;
12818 }
12819
12820 if (maybecomm && !strmatch(maybecomm, "json")
12821 && !strmatch(maybecomm, "exact-match"))
12822 community = maybecomm;
12823
12824 if (argv_find(argv, argc, "exact-match", &idx))
12825 exact_match = 1;
12826
12827 if (!community)
12828 sh_type = bgp_show_type_community_all;
12829 }
12830
12831 if (argv_find(argv, argc, "community-list", &idx)) {
12832 const char *clist_number_or_name = argv[++idx]->arg;
12833 struct community_list *list;
12834
12835 if (argv_find(argv, argc, "exact-match", &idx))
12836 exact_match = 1;
12837
12838 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12839 COMMUNITY_LIST_MASTER);
12840 if (list == NULL) {
12841 vty_out(vty, "%% %s community-list not found\n",
12842 clist_number_or_name);
12843 return CMD_WARNING;
12844 }
12845
12846 if (exact_match)
12847 sh_type = bgp_show_type_community_list_exact;
12848 else
12849 sh_type = bgp_show_type_community_list;
12850 output_arg = list;
12851 }
12852
12853 if (argv_find(argv, argc, "filter-list", &idx)) {
12854 const char *filter = argv[++idx]->arg;
12855 struct as_list *as_list;
12856
12857 as_list = as_list_lookup(filter);
12858 if (as_list == NULL) {
12859 vty_out(vty, "%% %s AS-path access-list not found\n",
12860 filter);
12861 return CMD_WARNING;
12862 }
12863
12864 sh_type = bgp_show_type_filter_list;
12865 output_arg = as_list;
12866 }
12867
12868 if (argv_find(argv, argc, "prefix-list", &idx)) {
12869 const char *prefix_list_str = argv[++idx]->arg;
12870 struct prefix_list *plist;
12871
12872 plist = prefix_list_lookup(afi, prefix_list_str);
12873 if (plist == NULL) {
12874 vty_out(vty, "%% %s prefix-list not found\n",
12875 prefix_list_str);
12876 return CMD_WARNING;
12877 }
12878
12879 sh_type = bgp_show_type_prefix_list;
12880 output_arg = plist;
12881 }
12882
12883 if (argv_find(argv, argc, "access-list", &idx)) {
12884 const char *access_list_str = argv[++idx]->arg;
12885 struct access_list *alist;
12886
12887 alist = access_list_lookup(afi, access_list_str);
12888 if (!alist) {
12889 vty_out(vty, "%% %s access-list not found\n",
12890 access_list_str);
12891 return CMD_WARNING;
12892 }
12893
12894 sh_type = bgp_show_type_access_list;
12895 output_arg = alist;
12896 }
12897
12898 if (argv_find(argv, argc, "route-map", &idx)) {
12899 const char *rmap_str = argv[++idx]->arg;
12900 struct route_map *rmap;
12901
12902 rmap = route_map_lookup_by_name(rmap_str);
12903 if (!rmap) {
12904 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12905 return CMD_WARNING;
12906 }
12907
12908 sh_type = bgp_show_type_route_map;
12909 output_arg = rmap;
12910 }
12911
12912 if (argv_find(argv, argc, "rpki", &idx)) {
12913 sh_type = bgp_show_type_rpki;
12914 if (argv_find(argv, argc, "valid", &idx))
12915 rpki_target_state = RPKI_VALID;
12916 else if (argv_find(argv, argc, "invalid", &idx))
12917 rpki_target_state = RPKI_INVALID;
12918 }
12919
12920 /* Display prefixes with matching version numbers */
12921 if (argv_find(argv, argc, "version", &idx)) {
12922 sh_type = bgp_show_type_prefix_version;
12923 output_arg = argv[idx + 1]->arg;
12924 }
12925
12926 /* Display prefixes with matching BGP community alias */
12927 if (argv_find(argv, argc, "alias", &idx)) {
12928 sh_type = bgp_show_type_community_alias;
12929 output_arg = argv[idx + 1]->arg;
12930 }
12931
12932 /* prefix-longer */
12933 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12934 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12935 const char *prefix_str = argv[idx]->arg;
12936
12937 if (!str2prefix(prefix_str, &p)) {
12938 vty_out(vty, "%% Malformed Prefix\n");
12939 return CMD_WARNING;
12940 }
12941
12942 sh_type = bgp_show_type_prefix_longer;
12943 output_arg = &p;
12944 }
12945
12946 /* self originated only */
12947 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12948 sh_type = bgp_show_type_self_originated;
12949
12950 if (!all) {
12951 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12952 if (community)
12953 return bgp_show_community(vty, bgp, community,
12954 exact_match, afi, safi,
12955 show_flags);
12956 else
12957 return bgp_show(vty, bgp, afi, safi, sh_type,
12958 output_arg, show_flags,
12959 rpki_target_state);
12960 } else {
12961 struct listnode *node;
12962 struct bgp *abgp;
12963 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12964 * AFI_IP6 */
12965
12966 if (uj)
12967 vty_out(vty, "{\n");
12968
12969 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12970 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12971 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12972 ? AFI_IP
12973 : AFI_IP6;
12974 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12975 FOREACH_SAFI (safi) {
12976 if (!bgp_afi_safi_peer_exists(abgp, afi,
12977 safi))
12978 continue;
12979
12980 if (uj) {
12981 if (first)
12982 first = false;
12983 else
12984 vty_out(vty, ",\n");
12985 vty_out(vty, "\"%s\":{\n",
12986 get_afi_safi_str(afi,
12987 safi,
12988 true));
12989 } else
12990 vty_out(vty,
12991 "\nFor address family: %s\n",
12992 get_afi_safi_str(
12993 afi, safi,
12994 false));
12995
12996 if (community)
12997 bgp_show_community(
12998 vty, abgp, community,
12999 exact_match, afi, safi,
13000 show_flags);
13001 else
13002 bgp_show(vty, abgp, afi, safi,
13003 sh_type, output_arg,
13004 show_flags,
13005 rpki_target_state);
13006 if (uj)
13007 vty_out(vty, "}\n");
13008 }
13009 }
13010 } else {
13011 /* show <ip> bgp all: for each AFI and SAFI*/
13012 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
13013 FOREACH_AFI_SAFI (afi, safi) {
13014 if (!bgp_afi_safi_peer_exists(abgp, afi,
13015 safi))
13016 continue;
13017
13018 if (uj) {
13019 if (first)
13020 first = false;
13021 else
13022 vty_out(vty, ",\n");
13023
13024 vty_out(vty, "\"%s\":{\n",
13025 get_afi_safi_str(afi,
13026 safi,
13027 true));
13028 } else
13029 vty_out(vty,
13030 "\nFor address family: %s\n",
13031 get_afi_safi_str(
13032 afi, safi,
13033 false));
13034
13035 if (community)
13036 bgp_show_community(
13037 vty, abgp, community,
13038 exact_match, afi, safi,
13039 show_flags);
13040 else
13041 bgp_show(vty, abgp, afi, safi,
13042 sh_type, output_arg,
13043 show_flags,
13044 rpki_target_state);
13045 if (uj)
13046 vty_out(vty, "}\n");
13047 }
13048 }
13049 }
13050 if (uj)
13051 vty_out(vty, "}\n");
13052 }
13053 return CMD_SUCCESS;
13054 }
13055
13056 DEFUN (show_ip_bgp_route,
13057 show_ip_bgp_route_cmd,
13058 "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]",
13059 SHOW_STR
13060 IP_STR
13061 BGP_STR
13062 BGP_INSTANCE_HELP_STR
13063 BGP_AFI_HELP_STR
13064 BGP_SAFI_WITH_LABEL_HELP_STR
13065 "Network in the BGP routing table to display\n"
13066 "IPv4 prefix\n"
13067 "Network in the BGP routing table to display\n"
13068 "IPv6 prefix\n"
13069 "Display only the bestpath\n"
13070 "Display only multipaths\n"
13071 "Display only paths that match the specified rpki state\n"
13072 "A valid path as determined by rpki\n"
13073 "A invalid path as determined by rpki\n"
13074 "A path that has no rpki data\n"
13075 JSON_STR)
13076 {
13077 int prefix_check = 0;
13078
13079 afi_t afi = AFI_IP6;
13080 safi_t safi = SAFI_UNICAST;
13081 char *prefix = NULL;
13082 struct bgp *bgp = NULL;
13083 enum bgp_path_type path_type;
13084 bool uj = use_json(argc, argv);
13085
13086 int idx = 0;
13087
13088 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13089 &bgp, uj);
13090 if (!idx)
13091 return CMD_WARNING;
13092
13093 if (!bgp) {
13094 vty_out(vty,
13095 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13096 return CMD_WARNING;
13097 }
13098
13099 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13100 if (argv_find(argv, argc, "A.B.C.D", &idx)
13101 || argv_find(argv, argc, "X:X::X:X", &idx))
13102 prefix_check = 0;
13103 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13104 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13105 prefix_check = 1;
13106
13107 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13108 && afi != AFI_IP6) {
13109 vty_out(vty,
13110 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13111 return CMD_WARNING;
13112 }
13113 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13114 && afi != AFI_IP) {
13115 vty_out(vty,
13116 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13117 return CMD_WARNING;
13118 }
13119
13120 prefix = argv[idx]->arg;
13121
13122 /* [<bestpath|multipath>] */
13123 if (argv_find(argv, argc, "bestpath", &idx))
13124 path_type = BGP_PATH_SHOW_BESTPATH;
13125 else if (argv_find(argv, argc, "multipath", &idx))
13126 path_type = BGP_PATH_SHOW_MULTIPATH;
13127 else
13128 path_type = BGP_PATH_SHOW_ALL;
13129
13130 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13131 path_type, RPKI_NOT_BEING_USED, uj);
13132 }
13133
13134 DEFUN (show_ip_bgp_regexp,
13135 show_ip_bgp_regexp_cmd,
13136 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13137 SHOW_STR
13138 IP_STR
13139 BGP_STR
13140 BGP_INSTANCE_HELP_STR
13141 BGP_AFI_HELP_STR
13142 BGP_SAFI_WITH_LABEL_HELP_STR
13143 "Display routes matching the AS path regular expression\n"
13144 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13145 JSON_STR)
13146 {
13147 afi_t afi = AFI_IP6;
13148 safi_t safi = SAFI_UNICAST;
13149 struct bgp *bgp = NULL;
13150 bool uj = use_json(argc, argv);
13151 char *regstr = NULL;
13152
13153 int idx = 0;
13154 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13155 &bgp, false);
13156 if (!idx)
13157 return CMD_WARNING;
13158
13159 // get index of regex
13160 if (argv_find(argv, argc, "REGEX", &idx))
13161 regstr = argv[idx]->arg;
13162
13163 assert(regstr);
13164 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13165 bgp_show_type_regexp, uj);
13166 }
13167
13168 DEFPY (show_ip_bgp_instance_all,
13169 show_ip_bgp_instance_all_cmd,
13170 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13171 SHOW_STR
13172 IP_STR
13173 BGP_STR
13174 BGP_INSTANCE_ALL_HELP_STR
13175 BGP_AFI_HELP_STR
13176 BGP_SAFI_WITH_LABEL_HELP_STR
13177 JSON_STR
13178 "Increase table width for longer prefixes\n")
13179 {
13180 afi_t afi = AFI_IP6;
13181 safi_t safi = SAFI_UNICAST;
13182 struct bgp *bgp = NULL;
13183 int idx = 0;
13184 uint16_t show_flags = 0;
13185
13186 if (uj) {
13187 argc--;
13188 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13189 }
13190
13191 if (wide)
13192 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13193
13194 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13195 &bgp, uj);
13196 if (!idx)
13197 return CMD_WARNING;
13198
13199 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13200 return CMD_SUCCESS;
13201 }
13202
13203 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13204 afi_t afi, safi_t safi, enum bgp_show_type type,
13205 bool use_json)
13206 {
13207 regex_t *regex;
13208 int rc;
13209 uint16_t show_flags = 0;
13210
13211 if (use_json)
13212 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13213
13214 if (!config_bgp_aspath_validate(regstr)) {
13215 vty_out(vty, "Invalid character in REGEX %s\n",
13216 regstr);
13217 return CMD_WARNING_CONFIG_FAILED;
13218 }
13219
13220 regex = bgp_regcomp(regstr);
13221 if (!regex) {
13222 vty_out(vty, "Can't compile regexp %s\n", regstr);
13223 return CMD_WARNING;
13224 }
13225
13226 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13227 RPKI_NOT_BEING_USED);
13228 bgp_regex_free(regex);
13229 return rc;
13230 }
13231
13232 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13233 const char *comstr, int exact, afi_t afi,
13234 safi_t safi, uint16_t show_flags)
13235 {
13236 struct community *com;
13237 int ret = 0;
13238
13239 com = community_str2com(comstr);
13240 if (!com) {
13241 vty_out(vty, "%% Community malformed: %s\n", comstr);
13242 return CMD_WARNING;
13243 }
13244
13245 ret = bgp_show(vty, bgp, afi, safi,
13246 (exact ? bgp_show_type_community_exact
13247 : bgp_show_type_community),
13248 com, show_flags, RPKI_NOT_BEING_USED);
13249 community_free(&com);
13250
13251 return ret;
13252 }
13253
13254 enum bgp_stats {
13255 BGP_STATS_MAXBITLEN = 0,
13256 BGP_STATS_RIB,
13257 BGP_STATS_PREFIXES,
13258 BGP_STATS_TOTPLEN,
13259 BGP_STATS_UNAGGREGATEABLE,
13260 BGP_STATS_MAX_AGGREGATEABLE,
13261 BGP_STATS_AGGREGATES,
13262 BGP_STATS_SPACE,
13263 BGP_STATS_ASPATH_COUNT,
13264 BGP_STATS_ASPATH_MAXHOPS,
13265 BGP_STATS_ASPATH_TOTHOPS,
13266 BGP_STATS_ASPATH_MAXSIZE,
13267 BGP_STATS_ASPATH_TOTSIZE,
13268 BGP_STATS_ASN_HIGHEST,
13269 BGP_STATS_MAX,
13270 };
13271
13272 #define TABLE_STATS_IDX_VTY 0
13273 #define TABLE_STATS_IDX_JSON 1
13274
13275 static const char *table_stats_strs[][2] = {
13276 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13277 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13278 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13279 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13280 "unaggregateablePrefixes"},
13281 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13282 "maximumAggregateablePrefixes"},
13283 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13284 "bgpAggregateAdvertisements"},
13285 [BGP_STATS_SPACE] = {"Address space advertised",
13286 "addressSpaceAdvertised"},
13287 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13288 "advertisementsWithPaths"},
13289 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13290 "longestAsPath"},
13291 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13292 "largestAsPath"},
13293 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13294 "averageAsPathLengthHops"},
13295 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13296 "averageAsPathSizeBytes"},
13297 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13298 [BGP_STATS_MAX] = {NULL, NULL}
13299 };
13300
13301 struct bgp_table_stats {
13302 struct bgp_table *table;
13303 unsigned long long counts[BGP_STATS_MAX];
13304
13305 unsigned long long
13306 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13307 1];
13308
13309 double total_space;
13310 };
13311
13312 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13313 struct bgp_table_stats *ts, unsigned int space)
13314 {
13315 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13316 struct bgp_path_info *pi;
13317 const struct prefix *rn_p;
13318
13319 if (!bgp_dest_has_bgp_path_info_data(dest))
13320 return;
13321
13322 rn_p = bgp_dest_get_prefix(dest);
13323 ts->counts[BGP_STATS_PREFIXES]++;
13324 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13325
13326 ts->prefix_len_count[rn_p->prefixlen]++;
13327 /* check if the prefix is included by any other announcements */
13328 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13329 pdest = bgp_dest_parent_nolock(pdest);
13330
13331 if (pdest == NULL || pdest == top) {
13332 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13333 /* announced address space */
13334 if (space)
13335 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13336 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13337 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13338
13339
13340 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13341 ts->counts[BGP_STATS_RIB]++;
13342
13343 if (CHECK_FLAG(pi->attr->flag,
13344 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13345 ts->counts[BGP_STATS_AGGREGATES]++;
13346
13347 /* as-path stats */
13348 if (pi->attr->aspath) {
13349 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13350 unsigned int size = aspath_size(pi->attr->aspath);
13351 as_t highest = aspath_highest(pi->attr->aspath);
13352
13353 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13354
13355 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13356 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13357
13358 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13359 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13360
13361 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13362 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13363 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13364 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13365 }
13366 }
13367 }
13368
13369 static void bgp_table_stats_walker(struct event *t)
13370 {
13371 struct bgp_dest *dest, *ndest;
13372 struct bgp_dest *top;
13373 struct bgp_table_stats *ts = EVENT_ARG(t);
13374 unsigned int space = 0;
13375
13376 if (!(top = bgp_table_top(ts->table)))
13377 return;
13378
13379 switch (ts->table->afi) {
13380 case AFI_IP:
13381 space = IPV4_MAX_BITLEN;
13382 break;
13383 case AFI_IP6:
13384 space = IPV6_MAX_BITLEN;
13385 break;
13386 case AFI_L2VPN:
13387 space = EVPN_ROUTE_PREFIXLEN;
13388 break;
13389 case AFI_UNSPEC:
13390 case AFI_MAX:
13391 return;
13392 }
13393
13394 ts->counts[BGP_STATS_MAXBITLEN] = space;
13395
13396 for (dest = top; dest; dest = bgp_route_next(dest)) {
13397 if (ts->table->safi == SAFI_MPLS_VPN
13398 || ts->table->safi == SAFI_ENCAP
13399 || ts->table->safi == SAFI_EVPN) {
13400 struct bgp_table *table;
13401
13402 table = bgp_dest_get_bgp_table_info(dest);
13403 if (!table)
13404 continue;
13405
13406 top = bgp_table_top(table);
13407 for (ndest = bgp_table_top(table); ndest;
13408 ndest = bgp_route_next(ndest))
13409 bgp_table_stats_rn(ndest, top, ts, space);
13410 } else {
13411 bgp_table_stats_rn(dest, top, ts, space);
13412 }
13413 }
13414 }
13415
13416 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13417 struct json_object *json_array)
13418 {
13419 struct listnode *node, *nnode;
13420 struct bgp *bgp;
13421
13422 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13423 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13424 }
13425
13426 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13427 safi_t safi, struct json_object *json_array)
13428 {
13429 struct bgp_table_stats ts;
13430 unsigned int i;
13431 int ret = CMD_SUCCESS;
13432 char temp_buf[20];
13433 struct json_object *json = NULL;
13434 uint32_t bitlen = 0;
13435 struct json_object *json_bitlen;
13436
13437 if (json_array)
13438 json = json_object_new_object();
13439
13440 if (!bgp->rib[afi][safi]) {
13441 char warning_msg[50];
13442
13443 snprintf(warning_msg, sizeof(warning_msg),
13444 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13445 safi);
13446
13447 if (!json)
13448 vty_out(vty, "%s\n", warning_msg);
13449 else
13450 json_object_string_add(json, "warning", warning_msg);
13451
13452 ret = CMD_WARNING;
13453 goto end_table_stats;
13454 }
13455
13456 if (!json)
13457 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13458 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13459 else
13460 json_object_string_add(json, "instance", bgp->name_pretty);
13461
13462 /* labeled-unicast routes live in the unicast table */
13463 if (safi == SAFI_LABELED_UNICAST)
13464 safi = SAFI_UNICAST;
13465
13466 memset(&ts, 0, sizeof(ts));
13467 ts.table = bgp->rib[afi][safi];
13468 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13469
13470 for (i = 0; i < BGP_STATS_MAX; i++) {
13471 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13472 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13473 continue;
13474
13475 switch (i) {
13476 case BGP_STATS_ASPATH_TOTHOPS:
13477 case BGP_STATS_ASPATH_TOTSIZE:
13478 if (!json) {
13479 snprintf(
13480 temp_buf, sizeof(temp_buf), "%12.2f",
13481 ts.counts[i]
13482 ? (float)ts.counts[i]
13483 / (float)ts.counts
13484 [BGP_STATS_ASPATH_COUNT]
13485 : 0);
13486 vty_out(vty, "%-30s: %s",
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 ts.counts[i]
13496 ? (double)ts.counts[i]
13497 / (double)ts.counts
13498 [BGP_STATS_ASPATH_COUNT]
13499 : 0);
13500 }
13501 break;
13502 case BGP_STATS_TOTPLEN:
13503 if (!json) {
13504 snprintf(
13505 temp_buf, sizeof(temp_buf), "%12.2f",
13506 ts.counts[i]
13507 ? (float)ts.counts[i]
13508 / (float)ts.counts
13509 [BGP_STATS_PREFIXES]
13510 : 0);
13511 vty_out(vty, "%-30s: %s",
13512 table_stats_strs[i]
13513 [TABLE_STATS_IDX_VTY],
13514 temp_buf);
13515 } else {
13516 json_object_double_add(
13517 json,
13518 table_stats_strs[i]
13519 [TABLE_STATS_IDX_JSON],
13520 ts.counts[i]
13521 ? (double)ts.counts[i]
13522 / (double)ts.counts
13523 [BGP_STATS_PREFIXES]
13524 : 0);
13525 }
13526 break;
13527 case BGP_STATS_SPACE:
13528 if (!json) {
13529 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13530 ts.total_space);
13531 vty_out(vty, "%-30s: %s\n",
13532 table_stats_strs[i]
13533 [TABLE_STATS_IDX_VTY],
13534 temp_buf);
13535 } else {
13536 json_object_double_add(
13537 json,
13538 table_stats_strs[i]
13539 [TABLE_STATS_IDX_JSON],
13540 (double)ts.total_space);
13541 }
13542 if (afi == AFI_IP6) {
13543 if (!json) {
13544 snprintf(temp_buf, sizeof(temp_buf),
13545 "%12g",
13546 ts.total_space
13547 * pow(2.0, -128 + 32));
13548 vty_out(vty, "%30s: %s\n",
13549 "/32 equivalent %s\n",
13550 temp_buf);
13551 } else {
13552 json_object_double_add(
13553 json, "/32equivalent",
13554 (double)(ts.total_space
13555 * pow(2.0,
13556 -128 + 32)));
13557 }
13558 if (!json) {
13559 snprintf(temp_buf, sizeof(temp_buf),
13560 "%12g",
13561 ts.total_space
13562 * pow(2.0, -128 + 48));
13563 vty_out(vty, "%30s: %s\n",
13564 "/48 equivalent %s\n",
13565 temp_buf);
13566 } else {
13567 json_object_double_add(
13568 json, "/48equivalent",
13569 (double)(ts.total_space
13570 * pow(2.0,
13571 -128 + 48)));
13572 }
13573 } else {
13574 if (!json) {
13575 snprintf(temp_buf, sizeof(temp_buf),
13576 "%12.2f",
13577 ts.total_space * 100.
13578 * pow(2.0, -32));
13579 vty_out(vty, "%30s: %s\n",
13580 "% announced ", temp_buf);
13581 } else {
13582 json_object_double_add(
13583 json, "%announced",
13584 (double)(ts.total_space * 100.
13585 * pow(2.0, -32)));
13586 }
13587 if (!json) {
13588 snprintf(temp_buf, sizeof(temp_buf),
13589 "%12.2f",
13590 ts.total_space
13591 * pow(2.0, -32 + 8));
13592 vty_out(vty, "%30s: %s\n",
13593 "/8 equivalent ", temp_buf);
13594 } else {
13595 json_object_double_add(
13596 json, "/8equivalent",
13597 (double)(ts.total_space
13598 * pow(2.0, -32 + 8)));
13599 }
13600 if (!json) {
13601 snprintf(temp_buf, sizeof(temp_buf),
13602 "%12.2f",
13603 ts.total_space
13604 * pow(2.0, -32 + 24));
13605 vty_out(vty, "%30s: %s\n",
13606 "/24 equivalent ", temp_buf);
13607 } else {
13608 json_object_double_add(
13609 json, "/24equivalent",
13610 (double)(ts.total_space
13611 * pow(2.0, -32 + 24)));
13612 }
13613 }
13614 break;
13615 default:
13616 if (!json) {
13617 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13618 ts.counts[i]);
13619 vty_out(vty, "%-30s: %s",
13620 table_stats_strs[i]
13621 [TABLE_STATS_IDX_VTY],
13622 temp_buf);
13623 } else {
13624 json_object_int_add(
13625 json,
13626 table_stats_strs[i]
13627 [TABLE_STATS_IDX_JSON],
13628 ts.counts[i]);
13629 }
13630 }
13631 if (!json)
13632 vty_out(vty, "\n");
13633 }
13634
13635 switch (afi) {
13636 case AFI_IP:
13637 bitlen = IPV4_MAX_BITLEN;
13638 break;
13639 case AFI_IP6:
13640 bitlen = IPV6_MAX_BITLEN;
13641 break;
13642 case AFI_L2VPN:
13643 bitlen = EVPN_ROUTE_PREFIXLEN;
13644 break;
13645 case AFI_UNSPEC:
13646 case AFI_MAX:
13647 break;
13648 }
13649
13650 if (json) {
13651 json_bitlen = json_object_new_array();
13652
13653 for (i = 0; i <= bitlen; i++) {
13654 struct json_object *ind_bit = json_object_new_object();
13655
13656 if (!ts.prefix_len_count[i])
13657 continue;
13658
13659 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13660 json_object_int_add(ind_bit, temp_buf,
13661 ts.prefix_len_count[i]);
13662 json_object_array_add(json_bitlen, ind_bit);
13663 }
13664 json_object_object_add(json, "prefixLength", json_bitlen);
13665 }
13666
13667 end_table_stats:
13668 if (json)
13669 json_object_array_add(json_array, json);
13670 return ret;
13671 }
13672
13673 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13674 safi_t safi, struct json_object *json_array)
13675 {
13676 if (!bgp) {
13677 bgp_table_stats_all(vty, afi, safi, json_array);
13678 return CMD_SUCCESS;
13679 }
13680
13681 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13682 }
13683
13684 enum bgp_pcounts {
13685 PCOUNT_ADJ_IN = 0,
13686 PCOUNT_DAMPED,
13687 PCOUNT_REMOVED,
13688 PCOUNT_HISTORY,
13689 PCOUNT_STALE,
13690 PCOUNT_VALID,
13691 PCOUNT_ALL,
13692 PCOUNT_COUNTED,
13693 PCOUNT_BPATH_SELECTED,
13694 PCOUNT_PFCNT, /* the figure we display to users */
13695 PCOUNT_MAX,
13696 };
13697
13698 static const char *const pcount_strs[] = {
13699 [PCOUNT_ADJ_IN] = "Adj-in",
13700 [PCOUNT_DAMPED] = "Damped",
13701 [PCOUNT_REMOVED] = "Removed",
13702 [PCOUNT_HISTORY] = "History",
13703 [PCOUNT_STALE] = "Stale",
13704 [PCOUNT_VALID] = "Valid",
13705 [PCOUNT_ALL] = "All RIB",
13706 [PCOUNT_COUNTED] = "PfxCt counted",
13707 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13708 [PCOUNT_PFCNT] = "Useable",
13709 [PCOUNT_MAX] = NULL,
13710 };
13711
13712 struct peer_pcounts {
13713 unsigned int count[PCOUNT_MAX];
13714 const struct peer *peer;
13715 const struct bgp_table *table;
13716 safi_t safi;
13717 };
13718
13719 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13720 {
13721 const struct bgp_adj_in *ain;
13722 const struct bgp_path_info *pi;
13723 const struct peer *peer = pc->peer;
13724
13725 for (ain = rn->adj_in; ain; ain = ain->next)
13726 if (ain->peer == peer)
13727 pc->count[PCOUNT_ADJ_IN]++;
13728
13729 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13730
13731 if (pi->peer != peer)
13732 continue;
13733
13734 pc->count[PCOUNT_ALL]++;
13735
13736 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13737 pc->count[PCOUNT_DAMPED]++;
13738 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13739 pc->count[PCOUNT_HISTORY]++;
13740 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13741 pc->count[PCOUNT_REMOVED]++;
13742 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13743 pc->count[PCOUNT_STALE]++;
13744 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13745 pc->count[PCOUNT_VALID]++;
13746 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13747 pc->count[PCOUNT_PFCNT]++;
13748 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13749 pc->count[PCOUNT_BPATH_SELECTED]++;
13750
13751 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13752 pc->count[PCOUNT_COUNTED]++;
13753 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13754 flog_err(
13755 EC_LIB_DEVELOPMENT,
13756 "Attempting to count but flags say it is unusable");
13757 } else {
13758 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13759 flog_err(
13760 EC_LIB_DEVELOPMENT,
13761 "Not counted but flags say we should");
13762 }
13763 }
13764 }
13765
13766 static void bgp_peer_count_walker(struct event *t)
13767 {
13768 struct bgp_dest *rn, *rm;
13769 const struct bgp_table *table;
13770 struct peer_pcounts *pc = EVENT_ARG(t);
13771
13772 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13773 || pc->safi == SAFI_EVPN) {
13774 /* Special handling for 2-level routing tables. */
13775 for (rn = bgp_table_top(pc->table); rn;
13776 rn = bgp_route_next(rn)) {
13777 table = bgp_dest_get_bgp_table_info(rn);
13778 if (table != NULL)
13779 for (rm = bgp_table_top(table); rm;
13780 rm = bgp_route_next(rm))
13781 bgp_peer_count_proc(rm, pc);
13782 }
13783 } else
13784 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13785 bgp_peer_count_proc(rn, pc);
13786 }
13787
13788 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13789 safi_t safi, bool use_json)
13790 {
13791 struct peer_pcounts pcounts = {.peer = peer};
13792 unsigned int i;
13793 json_object *json = NULL;
13794 json_object *json_loop = NULL;
13795
13796 if (use_json) {
13797 json = json_object_new_object();
13798 json_loop = json_object_new_object();
13799 }
13800
13801 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13802 || !peer->bgp->rib[afi][safi]) {
13803 if (use_json) {
13804 json_object_string_add(
13805 json, "warning",
13806 "No such neighbor or address family");
13807 vty_out(vty, "%s\n", json_object_to_json_string(json));
13808 json_object_free(json);
13809 json_object_free(json_loop);
13810 } else
13811 vty_out(vty, "%% No such neighbor or address family\n");
13812
13813 return CMD_WARNING;
13814 }
13815
13816 memset(&pcounts, 0, sizeof(pcounts));
13817 pcounts.peer = peer;
13818 pcounts.table = peer->bgp->rib[afi][safi];
13819 pcounts.safi = safi;
13820
13821 /* in-place call via thread subsystem so as to record execution time
13822 * stats for the thread-walk (i.e. ensure this can't be blamed on
13823 * on just vty_read()).
13824 */
13825 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13826
13827 if (use_json) {
13828 json_object_string_add(json, "prefixCountsFor", peer->host);
13829 json_object_string_add(json, "multiProtocol",
13830 get_afi_safi_str(afi, safi, true));
13831 json_object_int_add(json, "pfxCounter",
13832 peer->pcount[afi][safi]);
13833
13834 for (i = 0; i < PCOUNT_MAX; i++)
13835 json_object_int_add(json_loop, pcount_strs[i],
13836 pcounts.count[i]);
13837
13838 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13839
13840 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13841 json_object_string_add(json, "pfxctDriftFor",
13842 peer->host);
13843 json_object_string_add(
13844 json, "recommended",
13845 "Please report this bug, with the above command output");
13846 }
13847 vty_json(vty, json);
13848 } else {
13849
13850 if (peer->hostname
13851 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13852 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13853 peer->hostname, peer->host,
13854 get_afi_safi_str(afi, safi, false));
13855 } else {
13856 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13857 get_afi_safi_str(afi, safi, false));
13858 }
13859
13860 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13861 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13862
13863 for (i = 0; i < PCOUNT_MAX; i++)
13864 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13865 pcounts.count[i]);
13866
13867 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13868 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13869 vty_out(vty,
13870 "Please report this bug, with the above command output\n");
13871 }
13872 }
13873
13874 return CMD_SUCCESS;
13875 }
13876
13877 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13878 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13879 "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]",
13880 SHOW_STR
13881 IP_STR
13882 BGP_STR
13883 BGP_INSTANCE_HELP_STR
13884 BGP_AFI_HELP_STR
13885 BGP_SAFI_HELP_STR
13886 "Detailed information on TCP and BGP neighbor connections\n"
13887 "Neighbor to display information about\n"
13888 "Neighbor to display information about\n"
13889 "Neighbor on BGP configured interface\n"
13890 "Display detailed prefix count information\n"
13891 JSON_STR)
13892 {
13893 afi_t afi = AFI_IP6;
13894 safi_t safi = SAFI_UNICAST;
13895 struct peer *peer;
13896 int idx = 0;
13897 struct bgp *bgp = NULL;
13898 bool uj = use_json(argc, argv);
13899
13900 if (uj)
13901 argc--;
13902
13903 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13904 &bgp, uj);
13905 if (!idx)
13906 return CMD_WARNING;
13907
13908 argv_find(argv, argc, "neighbors", &idx);
13909 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13910 if (!peer)
13911 return CMD_WARNING;
13912
13913 return bgp_peer_counts(vty, peer, afi, safi, uj);
13914 }
13915
13916 #ifdef KEEP_OLD_VPN_COMMANDS
13917 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13918 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13919 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13920 SHOW_STR
13921 IP_STR
13922 BGP_STR
13923 BGP_VPNVX_HELP_STR
13924 "Display information about all VPNv4 NLRIs\n"
13925 "Detailed information on TCP and BGP neighbor connections\n"
13926 "Neighbor to display information about\n"
13927 "Neighbor to display information about\n"
13928 "Neighbor on BGP configured interface\n"
13929 "Display detailed prefix count information\n"
13930 JSON_STR)
13931 {
13932 int idx_peer = 6;
13933 struct peer *peer;
13934 bool uj = use_json(argc, argv);
13935
13936 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13937 if (!peer)
13938 return CMD_WARNING;
13939
13940 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13941 }
13942
13943 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13944 show_ip_bgp_vpn_all_route_prefix_cmd,
13945 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13946 SHOW_STR
13947 IP_STR
13948 BGP_STR
13949 BGP_VPNVX_HELP_STR
13950 "Display information about all VPNv4 NLRIs\n"
13951 "Network in the BGP routing table to display\n"
13952 "Network in the BGP routing table to display\n"
13953 JSON_STR)
13954 {
13955 int idx = 0;
13956 char *network = NULL;
13957 struct bgp *bgp = bgp_get_default();
13958 if (!bgp) {
13959 vty_out(vty, "Can't find default instance\n");
13960 return CMD_WARNING;
13961 }
13962
13963 if (argv_find(argv, argc, "A.B.C.D", &idx))
13964 network = argv[idx]->arg;
13965 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13966 network = argv[idx]->arg;
13967 else {
13968 vty_out(vty, "Unable to figure out Network\n");
13969 return CMD_WARNING;
13970 }
13971
13972 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13973 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13974 use_json(argc, argv));
13975 }
13976 #endif /* KEEP_OLD_VPN_COMMANDS */
13977
13978 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13979 show_bgp_l2vpn_evpn_route_prefix_cmd,
13980 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13981 SHOW_STR
13982 BGP_STR
13983 L2VPN_HELP_STR
13984 EVPN_HELP_STR
13985 "Network in the BGP routing table to display\n"
13986 "Network in the BGP routing table to display\n"
13987 "Network in the BGP routing table to display\n"
13988 "Network in the BGP routing table to display\n"
13989 JSON_STR)
13990 {
13991 int idx = 0;
13992 char *network = NULL;
13993 int prefix_check = 0;
13994
13995 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13996 argv_find(argv, argc, "X:X::X:X", &idx))
13997 network = argv[idx]->arg;
13998 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13999 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
14000 network = argv[idx]->arg;
14001 prefix_check = 1;
14002 } else {
14003 vty_out(vty, "Unable to figure out Network\n");
14004 return CMD_WARNING;
14005 }
14006 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
14007 prefix_check, BGP_PATH_SHOW_ALL,
14008 RPKI_NOT_BEING_USED, use_json(argc, argv));
14009 }
14010
14011 static void show_adj_route_header(struct vty *vty, struct peer *peer,
14012 struct bgp_table *table, int *header1,
14013 int *header2, json_object *json,
14014 json_object *json_scode,
14015 json_object *json_ocode, bool wide,
14016 bool detail)
14017 {
14018 uint64_t version = table ? table->version : 0;
14019
14020 if (*header1) {
14021 if (json) {
14022 json_object_int_add(json, "bgpTableVersion", version);
14023 json_object_string_addf(json, "bgpLocalRouterId",
14024 "%pI4", &peer->bgp->router_id);
14025 json_object_int_add(json, "defaultLocPrf",
14026 peer->bgp->default_local_pref);
14027 json_object_int_add(json, "localAS",
14028 peer->change_local_as
14029 ? peer->change_local_as
14030 : peer->local_as);
14031 json_object_object_add(json, "bgpStatusCodes",
14032 json_scode);
14033 json_object_object_add(json, "bgpOriginCodes",
14034 json_ocode);
14035 } else {
14036 vty_out(vty,
14037 "BGP table version is %" PRIu64
14038 ", local router ID is %pI4, vrf id ",
14039 version, &peer->bgp->router_id);
14040 if (peer->bgp->vrf_id == VRF_UNKNOWN)
14041 vty_out(vty, "%s", VRFID_NONE_STR);
14042 else
14043 vty_out(vty, "%u", peer->bgp->vrf_id);
14044 vty_out(vty, "\n");
14045 vty_out(vty, "Default local pref %u, ",
14046 peer->bgp->default_local_pref);
14047 vty_out(vty, "local AS %u\n",
14048 peer->change_local_as ? peer->change_local_as
14049 : peer->local_as);
14050 if (!detail) {
14051 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14052 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14053 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14054 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14055 }
14056 }
14057 *header1 = 0;
14058 }
14059 if (*header2) {
14060 if (!json && !detail)
14061 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14062 : BGP_SHOW_HEADER));
14063 *header2 = 0;
14064 }
14065 }
14066
14067 static void
14068 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14069 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14070 const char *rmap_name, json_object *json, json_object *json_ar,
14071 json_object *json_scode, json_object *json_ocode,
14072 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14073 const struct prefix *match, unsigned long *output_count,
14074 unsigned long *filtered_count)
14075 {
14076 struct bgp_adj_in *ain = NULL;
14077 struct bgp_adj_out *adj = NULL;
14078 struct bgp_dest *dest;
14079 struct bgp *bgp;
14080 struct attr attr;
14081 int ret;
14082 struct update_subgroup *subgrp;
14083 struct peer_af *paf = NULL;
14084 bool route_filtered;
14085 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14086 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14087 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14088 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14089 || (safi == SAFI_EVPN))
14090 ? true
14091 : false;
14092 int display = 0;
14093 json_object *json_net = NULL;
14094
14095 bgp = peer->bgp;
14096
14097 /* If the user supplied a prefix, look for a matching route instead
14098 * of walking the whole table.
14099 */
14100 if (match) {
14101 dest = bgp_node_match(table, match);
14102 if (!dest) {
14103 if (!use_json)
14104 vty_out(vty, "Network not in table\n");
14105 return;
14106 }
14107
14108 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14109
14110 if (rn_p->prefixlen != match->prefixlen) {
14111 if (!use_json)
14112 vty_out(vty, "Network not in table\n");
14113 bgp_dest_unlock_node(dest);
14114 return;
14115 }
14116
14117 if (type == bgp_show_adj_route_received ||
14118 type == bgp_show_adj_route_filtered) {
14119 for (ain = dest->adj_in; ain; ain = ain->next) {
14120 if (ain->peer == peer) {
14121 attr = *ain->attr;
14122 break;
14123 }
14124 }
14125 /* bail out if if adj_out is empty, or
14126 * if the prefix isn't in this peer's
14127 * adj_in
14128 */
14129 if (!ain || ain->peer != peer) {
14130 if (!use_json)
14131 vty_out(vty, "Network not in table\n");
14132 bgp_dest_unlock_node(dest);
14133 return;
14134 }
14135 } else if (type == bgp_show_adj_route_advertised) {
14136 bool peer_found = false;
14137
14138 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14139 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14140 if (paf->peer == peer && adj->attr) {
14141 attr = *adj->attr;
14142 peer_found = true;
14143 break;
14144 }
14145 }
14146 if (peer_found)
14147 break;
14148 }
14149 /* bail out if if adj_out is empty, or
14150 * if the prefix isn't in this peer's
14151 * adj_out
14152 */
14153 if (!paf || !peer_found) {
14154 if (!use_json)
14155 vty_out(vty, "Network not in table\n");
14156 bgp_dest_unlock_node(dest);
14157 return;
14158 }
14159 }
14160
14161 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14162 rmap_name);
14163
14164 if (ret != RMAP_DENY) {
14165 show_adj_route_header(vty, peer, table, header1,
14166 header2, json, json_scode,
14167 json_ocode, wide, detail);
14168
14169 if (use_json)
14170 json_net = json_object_new_object();
14171
14172 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14173 afi, safi, json_net,
14174 BGP_PATH_SHOW_ALL, &display,
14175 RPKI_NOT_BEING_USED);
14176 if (use_json)
14177 json_object_object_addf(json_ar, json_net,
14178 "%pFX", rn_p);
14179 (*output_count)++;
14180 } else
14181 (*filtered_count)++;
14182
14183 bgp_attr_flush(&attr);
14184 bgp_dest_unlock_node(dest);
14185 return;
14186 }
14187
14188
14189 subgrp = peer_subgroup(peer, afi, safi);
14190
14191 if (type == bgp_show_adj_route_advertised && subgrp
14192 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14193 if (use_json) {
14194 json_object_int_add(json, "bgpTableVersion",
14195 table->version);
14196 json_object_string_addf(json, "bgpLocalRouterId",
14197 "%pI4", &bgp->router_id);
14198 json_object_int_add(json, "defaultLocPrf",
14199 bgp->default_local_pref);
14200 json_object_int_add(json, "localAS",
14201 peer->change_local_as
14202 ? peer->change_local_as
14203 : peer->local_as);
14204 json_object_object_add(json, "bgpStatusCodes",
14205 json_scode);
14206 json_object_object_add(json, "bgpOriginCodes",
14207 json_ocode);
14208 json_object_string_add(
14209 json, "bgpOriginatingDefaultNetwork",
14210 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14211 } else {
14212 vty_out(vty,
14213 "BGP table version is %" PRIu64
14214 ", local router ID is %pI4, vrf id ",
14215 table->version, &bgp->router_id);
14216 if (bgp->vrf_id == VRF_UNKNOWN)
14217 vty_out(vty, "%s", VRFID_NONE_STR);
14218 else
14219 vty_out(vty, "%u", bgp->vrf_id);
14220 vty_out(vty, "\n");
14221 vty_out(vty, "Default local pref %u, ",
14222 bgp->default_local_pref);
14223 vty_out(vty, "local AS %u\n",
14224 peer->change_local_as ? peer->change_local_as
14225 : peer->local_as);
14226 if (!detail) {
14227 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14228 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14229 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14230 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14231 }
14232
14233 vty_out(vty, "Originating default network %s\n\n",
14234 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14235 }
14236 (*output_count)++;
14237 *header1 = 0;
14238 }
14239
14240 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14241 if (type == bgp_show_adj_route_received
14242 || type == bgp_show_adj_route_filtered) {
14243 for (ain = dest->adj_in; ain; ain = ain->next) {
14244 if (ain->peer != peer)
14245 continue;
14246
14247 show_adj_route_header(vty, peer, table, header1,
14248 header2, json, json_scode,
14249 json_ocode, wide, detail);
14250
14251 if ((safi == SAFI_MPLS_VPN)
14252 || (safi == SAFI_ENCAP)
14253 || (safi == SAFI_EVPN)) {
14254 if (use_json)
14255 json_object_string_add(
14256 json_ar, "rd", rd_str);
14257 else if (show_rd && rd_str) {
14258 vty_out(vty,
14259 "Route Distinguisher: %s\n",
14260 rd_str);
14261 show_rd = false;
14262 }
14263 }
14264
14265 attr = *ain->attr;
14266 route_filtered = false;
14267
14268 /* Filter prefix using distribute list,
14269 * filter list or prefix list
14270 */
14271 const struct prefix *rn_p =
14272 bgp_dest_get_prefix(dest);
14273 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14274 safi))
14275 == FILTER_DENY)
14276 route_filtered = true;
14277
14278 /* Filter prefix using route-map */
14279 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14280 safi, rmap_name, NULL,
14281 0, NULL);
14282
14283 if (type == bgp_show_adj_route_filtered &&
14284 !route_filtered && ret != RMAP_DENY) {
14285 bgp_attr_flush(&attr);
14286 continue;
14287 }
14288
14289 if (type == bgp_show_adj_route_received
14290 && (route_filtered || ret == RMAP_DENY))
14291 (*filtered_count)++;
14292
14293 if (detail) {
14294 if (use_json)
14295 json_net =
14296 json_object_new_object();
14297 bgp_show_path_info(
14298 NULL /* prefix_rd */, dest, vty,
14299 bgp, afi, safi, json_net,
14300 BGP_PATH_SHOW_ALL, &display,
14301 RPKI_NOT_BEING_USED);
14302 if (use_json)
14303 json_object_object_addf(
14304 json_ar, json_net,
14305 "%pFX", rn_p);
14306 } else
14307 route_vty_out_tmp(vty, dest, rn_p,
14308 &attr, safi, use_json,
14309 json_ar, wide);
14310 bgp_attr_flush(&attr);
14311 (*output_count)++;
14312 }
14313 } else if (type == bgp_show_adj_route_advertised) {
14314 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14315 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14316 if (paf->peer != peer || !adj->attr)
14317 continue;
14318
14319 show_adj_route_header(
14320 vty, peer, table, header1,
14321 header2, json, json_scode,
14322 json_ocode, wide, detail);
14323
14324 const struct prefix *rn_p =
14325 bgp_dest_get_prefix(dest);
14326
14327 attr = *adj->attr;
14328 ret = bgp_output_modifier(
14329 peer, rn_p, &attr, afi, safi,
14330 rmap_name);
14331
14332 if (ret != RMAP_DENY) {
14333 if ((safi == SAFI_MPLS_VPN)
14334 || (safi == SAFI_ENCAP)
14335 || (safi == SAFI_EVPN)) {
14336 if (use_json)
14337 json_object_string_add(
14338 json_ar,
14339 "rd",
14340 rd_str);
14341 else if (show_rd
14342 && rd_str) {
14343 vty_out(vty,
14344 "Route Distinguisher: %s\n",
14345 rd_str);
14346 show_rd = false;
14347 }
14348 }
14349 if (detail) {
14350 if (use_json)
14351 json_net =
14352 json_object_new_object();
14353 bgp_show_path_info(
14354 NULL /* prefix_rd
14355 */
14356 ,
14357 dest, vty, bgp,
14358 afi, safi,
14359 json_net,
14360 BGP_PATH_SHOW_ALL,
14361 &display,
14362 RPKI_NOT_BEING_USED);
14363 if (use_json)
14364 json_object_object_addf(
14365 json_ar,
14366 json_net,
14367 "%pFX",
14368 rn_p);
14369 } else
14370 route_vty_out_tmp(
14371 vty, dest, rn_p,
14372 &attr, safi,
14373 use_json,
14374 json_ar, wide);
14375 (*output_count)++;
14376 } else {
14377 (*filtered_count)++;
14378 }
14379
14380 bgp_attr_flush(&attr);
14381 }
14382 } else if (type == bgp_show_adj_route_bestpath) {
14383 struct bgp_path_info *pi;
14384
14385 show_adj_route_header(vty, peer, table, header1,
14386 header2, json, json_scode,
14387 json_ocode, wide, detail);
14388
14389 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14390
14391 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14392 pi = pi->next) {
14393 if (pi->peer != peer)
14394 continue;
14395
14396 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14397 continue;
14398
14399 if (detail) {
14400 if (use_json)
14401 json_net =
14402 json_object_new_object();
14403 bgp_show_path_info(
14404 NULL /* prefix_rd */, dest, vty,
14405 bgp, afi, safi, json_net,
14406 BGP_PATH_SHOW_BESTPATH,
14407 &display, RPKI_NOT_BEING_USED);
14408 if (use_json)
14409 json_object_object_addf(
14410 json_ar, json_net,
14411 "%pFX", rn_p);
14412 } else
14413 route_vty_out_tmp(
14414 vty, dest, rn_p, pi->attr, safi,
14415 use_json, json_ar, wide);
14416 (*output_count)++;
14417 }
14418 }
14419 }
14420 }
14421
14422 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14423 safi_t safi, enum bgp_show_adj_route_type type,
14424 const char *rmap_name, const struct prefix *match,
14425 uint16_t show_flags)
14426 {
14427 struct bgp *bgp;
14428 struct bgp_table *table;
14429 json_object *json = NULL;
14430 json_object *json_scode = NULL;
14431 json_object *json_ocode = NULL;
14432 json_object *json_ar = NULL;
14433 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14434
14435 /* Init BGP headers here so they're only displayed once
14436 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14437 */
14438 int header1 = 1;
14439 int header2 = 1;
14440
14441 /*
14442 * Initialize variables for each RD
14443 * All prefixes under an RD is aggregated within "json_routes"
14444 */
14445 char rd_str[BUFSIZ] = {0};
14446 json_object *json_routes = NULL;
14447
14448
14449 /* For 2-tier tables, prefix counts need to be
14450 * maintained across multiple runs of show_adj_route()
14451 */
14452 unsigned long output_count_per_rd;
14453 unsigned long filtered_count_per_rd;
14454 unsigned long output_count = 0;
14455 unsigned long filtered_count = 0;
14456
14457 if (use_json) {
14458 json = json_object_new_object();
14459 json_ar = json_object_new_object();
14460 json_scode = json_object_new_object();
14461 json_ocode = json_object_new_object();
14462 #if CONFDATE > 20231208
14463 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14464 #endif
14465 json_object_string_add(json_scode, "suppressed", "s");
14466 json_object_string_add(json_scode, "damped", "d");
14467 json_object_string_add(json_scode, "history", "h");
14468 json_object_string_add(json_scode, "valid", "*");
14469 json_object_string_add(json_scode, "best", ">");
14470 json_object_string_add(json_scode, "multipath", "=");
14471 json_object_string_add(json_scode, "internal", "i");
14472 json_object_string_add(json_scode, "ribFailure", "r");
14473 json_object_string_add(json_scode, "stale", "S");
14474 json_object_string_add(json_scode, "removed", "R");
14475
14476 #if CONFDATE > 20231208
14477 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14478 #endif
14479 json_object_string_add(json_ocode, "igp", "i");
14480 json_object_string_add(json_ocode, "egp", "e");
14481 json_object_string_add(json_ocode, "incomplete", "?");
14482 }
14483
14484 if (!peer || !peer->afc[afi][safi]) {
14485 if (use_json) {
14486 json_object_string_add(
14487 json, "warning",
14488 "No such neighbor or address family");
14489 vty_out(vty, "%s\n", json_object_to_json_string(json));
14490 json_object_free(json);
14491 json_object_free(json_ar);
14492 json_object_free(json_scode);
14493 json_object_free(json_ocode);
14494 } else
14495 vty_out(vty, "%% No such neighbor or address family\n");
14496
14497 return CMD_WARNING;
14498 }
14499
14500 if ((type == bgp_show_adj_route_received
14501 || type == bgp_show_adj_route_filtered)
14502 && !CHECK_FLAG(peer->af_flags[afi][safi],
14503 PEER_FLAG_SOFT_RECONFIG)) {
14504 if (use_json) {
14505 json_object_string_add(
14506 json, "warning",
14507 "Inbound soft reconfiguration not enabled");
14508 vty_out(vty, "%s\n", json_object_to_json_string(json));
14509 json_object_free(json);
14510 json_object_free(json_ar);
14511 json_object_free(json_scode);
14512 json_object_free(json_ocode);
14513 } else
14514 vty_out(vty,
14515 "%% Inbound soft reconfiguration not enabled\n");
14516
14517 return CMD_WARNING;
14518 }
14519
14520 bgp = peer->bgp;
14521
14522 /* labeled-unicast routes live in the unicast table */
14523 if (safi == SAFI_LABELED_UNICAST)
14524 table = bgp->rib[afi][SAFI_UNICAST];
14525 else
14526 table = bgp->rib[afi][safi];
14527
14528 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14529 || (safi == SAFI_EVPN)) {
14530
14531 struct bgp_dest *dest;
14532
14533 for (dest = bgp_table_top(table); dest;
14534 dest = bgp_route_next(dest)) {
14535 table = bgp_dest_get_bgp_table_info(dest);
14536 if (!table)
14537 continue;
14538
14539 output_count_per_rd = 0;
14540 filtered_count_per_rd = 0;
14541
14542 if (use_json)
14543 json_routes = json_object_new_object();
14544
14545 const struct prefix_rd *prd;
14546 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14547 dest);
14548
14549 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14550 bgp->asnotation);
14551
14552 show_adj_route(
14553 vty, peer, table, afi, safi, type, rmap_name,
14554 json, json_routes, json_scode, json_ocode,
14555 show_flags, &header1, &header2, rd_str, match,
14556 &output_count_per_rd, &filtered_count_per_rd);
14557
14558 /* Don't include an empty RD in the output! */
14559 if (json_routes && (output_count_per_rd > 0))
14560 json_object_object_add(json_ar, rd_str,
14561 json_routes);
14562
14563 output_count += output_count_per_rd;
14564 filtered_count += filtered_count_per_rd;
14565 }
14566 } else
14567 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14568 json, json_ar, json_scode, json_ocode,
14569 show_flags, &header1, &header2, rd_str, match,
14570 &output_count, &filtered_count);
14571
14572 if (use_json) {
14573 if (type == bgp_show_adj_route_advertised)
14574 json_object_object_add(json, "advertisedRoutes",
14575 json_ar);
14576 else
14577 json_object_object_add(json, "receivedRoutes", json_ar);
14578 json_object_int_add(json, "totalPrefixCounter", output_count);
14579 json_object_int_add(json, "filteredPrefixCounter",
14580 filtered_count);
14581
14582 /*
14583 * These fields only give up ownership to `json` when `header1`
14584 * is used (set to zero). See code in `show_adj_route` and
14585 * `show_adj_route_header`.
14586 */
14587 if (header1 == 1) {
14588 json_object_free(json_scode);
14589 json_object_free(json_ocode);
14590 }
14591
14592 vty_json(vty, json);
14593 } else if (output_count > 0) {
14594 if (!match && filtered_count > 0)
14595 vty_out(vty,
14596 "\nTotal number of prefixes %ld (%ld filtered)\n",
14597 output_count, filtered_count);
14598 else
14599 vty_out(vty, "\nTotal number of prefixes %ld\n",
14600 output_count);
14601 }
14602
14603 return CMD_SUCCESS;
14604 }
14605
14606 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14607 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14608 "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]",
14609 SHOW_STR
14610 IP_STR
14611 BGP_STR
14612 BGP_INSTANCE_HELP_STR
14613 BGP_AFI_HELP_STR
14614 BGP_SAFI_WITH_LABEL_HELP_STR
14615 "Detailed information on TCP and BGP neighbor connections\n"
14616 "Neighbor to display information about\n"
14617 "Neighbor to display information about\n"
14618 "Neighbor on BGP configured interface\n"
14619 "Display the routes selected by best path\n"
14620 "Display detailed version of routes\n"
14621 JSON_STR
14622 "Increase table width for longer prefixes\n")
14623 {
14624 afi_t afi = AFI_IP6;
14625 safi_t safi = SAFI_UNICAST;
14626 char *rmap_name = NULL;
14627 char *peerstr = NULL;
14628 struct bgp *bgp = NULL;
14629 struct peer *peer;
14630 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14631 int idx = 0;
14632 uint16_t show_flags = 0;
14633
14634 if (detail)
14635 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14636
14637 if (uj)
14638 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14639
14640 if (wide)
14641 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14642
14643 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14644 &bgp, uj);
14645
14646 if (!idx)
14647 return CMD_WARNING;
14648
14649 argv_find(argv, argc, "neighbors", &idx);
14650 peerstr = argv[++idx]->arg;
14651
14652 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14653 if (!peer)
14654 return CMD_WARNING;
14655
14656 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14657 show_flags);
14658 }
14659
14660 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14661 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14662 "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]",
14663 SHOW_STR
14664 IP_STR
14665 BGP_STR
14666 BGP_INSTANCE_HELP_STR
14667 BGP_AFI_HELP_STR
14668 BGP_SAFI_WITH_LABEL_HELP_STR
14669 "Display the entries for all address families\n"
14670 "Detailed information on TCP and BGP neighbor connections\n"
14671 "Neighbor to display information about\n"
14672 "Neighbor to display information about\n"
14673 "Neighbor on BGP configured interface\n"
14674 "Display the routes advertised to a BGP neighbor\n"
14675 "Display the received routes from neighbor\n"
14676 "Display the filtered routes received from neighbor\n"
14677 "Route-map to modify the attributes\n"
14678 "Name of the route map\n"
14679 "IPv4 prefix\n"
14680 "IPv6 prefix\n"
14681 "Display detailed version of routes\n"
14682 JSON_STR
14683 "Increase table width for longer prefixes\n")
14684 {
14685 afi_t afi = AFI_IP6;
14686 safi_t safi = SAFI_UNICAST;
14687 char *peerstr = NULL;
14688 struct bgp *bgp = NULL;
14689 struct peer *peer;
14690 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14691 int idx = 0;
14692 bool first = true;
14693 uint16_t show_flags = 0;
14694 struct listnode *node;
14695 struct bgp *abgp;
14696
14697 if (detail || prefix_str)
14698 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14699
14700 if (uj) {
14701 argc--;
14702 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14703 }
14704
14705 if (all) {
14706 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14707 if (argv_find(argv, argc, "ipv4", &idx))
14708 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14709
14710 if (argv_find(argv, argc, "ipv6", &idx))
14711 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14712 }
14713
14714 if (wide)
14715 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14716
14717 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14718 &bgp, uj);
14719 if (!idx)
14720 return CMD_WARNING;
14721
14722 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14723 argv_find(argv, argc, "neighbors", &idx);
14724 peerstr = argv[++idx]->arg;
14725
14726 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14727 if (!peer)
14728 return CMD_WARNING;
14729
14730 if (argv_find(argv, argc, "advertised-routes", &idx))
14731 type = bgp_show_adj_route_advertised;
14732 else if (argv_find(argv, argc, "received-routes", &idx))
14733 type = bgp_show_adj_route_received;
14734 else if (argv_find(argv, argc, "filtered-routes", &idx))
14735 type = bgp_show_adj_route_filtered;
14736
14737 if (!all)
14738 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14739 prefix_str ? prefix : NULL, show_flags);
14740 if (uj)
14741 vty_out(vty, "{\n");
14742
14743 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14744 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14745 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14746 : AFI_IP6;
14747 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14748 FOREACH_SAFI (safi) {
14749 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14750 continue;
14751
14752 if (uj) {
14753 if (first)
14754 first = false;
14755 else
14756 vty_out(vty, ",\n");
14757 vty_out(vty, "\"%s\":",
14758 get_afi_safi_str(afi, safi,
14759 true));
14760 } else
14761 vty_out(vty,
14762 "\nFor address family: %s\n",
14763 get_afi_safi_str(afi, safi,
14764 false));
14765
14766 peer_adj_routes(vty, peer, afi, safi, type,
14767 route_map, prefix, show_flags);
14768 }
14769 }
14770 } else {
14771 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14772 FOREACH_AFI_SAFI (afi, safi) {
14773 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14774 continue;
14775
14776 if (uj) {
14777 if (first)
14778 first = false;
14779 else
14780 vty_out(vty, ",\n");
14781 vty_out(vty, "\"%s\":",
14782 get_afi_safi_str(afi, safi,
14783 true));
14784 } else
14785 vty_out(vty,
14786 "\nFor address family: %s\n",
14787 get_afi_safi_str(afi, safi,
14788 false));
14789
14790 peer_adj_routes(vty, peer, afi, safi, type,
14791 route_map, prefix, show_flags);
14792 }
14793 }
14794 }
14795 if (uj)
14796 vty_out(vty, "}\n");
14797
14798 return CMD_SUCCESS;
14799 }
14800
14801 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14802 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14803 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14804 SHOW_STR
14805 IP_STR
14806 BGP_STR
14807 BGP_INSTANCE_HELP_STR
14808 BGP_AF_STR
14809 BGP_AF_STR
14810 BGP_AF_MODIFIER_STR
14811 "Detailed information on TCP and BGP neighbor connections\n"
14812 "Neighbor to display information about\n"
14813 "Neighbor to display information about\n"
14814 "Neighbor on BGP configured interface\n"
14815 "Display information received from a BGP neighbor\n"
14816 "Display the prefixlist filter\n"
14817 JSON_STR)
14818 {
14819 afi_t afi = AFI_IP6;
14820 safi_t safi = SAFI_UNICAST;
14821 char *peerstr = NULL;
14822 char name[BUFSIZ];
14823 struct peer *peer;
14824 int count;
14825 int idx = 0;
14826 struct bgp *bgp = NULL;
14827 bool uj = use_json(argc, argv);
14828
14829 if (uj)
14830 argc--;
14831
14832 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14833 &bgp, uj);
14834 if (!idx)
14835 return CMD_WARNING;
14836
14837 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14838 argv_find(argv, argc, "neighbors", &idx);
14839 peerstr = argv[++idx]->arg;
14840
14841 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14842 if (!peer)
14843 return CMD_WARNING;
14844
14845 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14846 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14847 if (count) {
14848 if (!uj)
14849 vty_out(vty, "Address Family: %s\n",
14850 get_afi_safi_str(afi, safi, false));
14851 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14852 } else {
14853 if (uj)
14854 vty_out(vty, "{}\n");
14855 else
14856 vty_out(vty, "No functional output\n");
14857 }
14858
14859 return CMD_SUCCESS;
14860 }
14861
14862 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14863 afi_t afi, safi_t safi,
14864 enum bgp_show_type type, bool use_json)
14865 {
14866 uint16_t show_flags = 0;
14867
14868 if (use_json)
14869 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14870
14871 if (!peer || !peer->afc[afi][safi]) {
14872 if (use_json) {
14873 json_object *json_no = NULL;
14874 json_no = json_object_new_object();
14875 json_object_string_add(
14876 json_no, "warning",
14877 "No such neighbor or address family");
14878 vty_out(vty, "%s\n",
14879 json_object_to_json_string(json_no));
14880 json_object_free(json_no);
14881 } else
14882 vty_out(vty, "%% No such neighbor or address family\n");
14883 return CMD_WARNING;
14884 }
14885
14886 /* labeled-unicast routes live in the unicast table */
14887 if (safi == SAFI_LABELED_UNICAST)
14888 safi = SAFI_UNICAST;
14889
14890 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14891 RPKI_NOT_BEING_USED);
14892 }
14893
14894 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14895 show_ip_bgp_flowspec_routes_detailed_cmd,
14896 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14897 SHOW_STR
14898 IP_STR
14899 BGP_STR
14900 BGP_INSTANCE_HELP_STR
14901 BGP_AFI_HELP_STR
14902 "SAFI Flowspec\n"
14903 "Detailed information on flowspec entries\n"
14904 JSON_STR)
14905 {
14906 afi_t afi = AFI_IP6;
14907 safi_t safi = SAFI_UNICAST;
14908 struct bgp *bgp = NULL;
14909 int idx = 0;
14910 bool uj = use_json(argc, argv);
14911 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14912
14913 if (uj) {
14914 argc--;
14915 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14916 }
14917
14918 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14919 &bgp, uj);
14920 if (!idx)
14921 return CMD_WARNING;
14922
14923 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14924 show_flags, RPKI_NOT_BEING_USED);
14925 }
14926
14927 DEFUN (show_ip_bgp_neighbor_routes,
14928 show_ip_bgp_neighbor_routes_cmd,
14929 "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]",
14930 SHOW_STR
14931 IP_STR
14932 BGP_STR
14933 BGP_INSTANCE_HELP_STR
14934 BGP_AFI_HELP_STR
14935 BGP_SAFI_WITH_LABEL_HELP_STR
14936 "Detailed information on TCP and BGP neighbor connections\n"
14937 "Neighbor to display information about\n"
14938 "Neighbor to display information about\n"
14939 "Neighbor on BGP configured interface\n"
14940 "Display flap statistics of the routes learned from neighbor\n"
14941 "Display the dampened routes received from neighbor\n"
14942 "Display routes learned from neighbor\n"
14943 JSON_STR)
14944 {
14945 char *peerstr = NULL;
14946 struct bgp *bgp = NULL;
14947 afi_t afi = AFI_IP6;
14948 safi_t safi = SAFI_UNICAST;
14949 struct peer *peer;
14950 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14951 int idx = 0;
14952 bool uj = use_json(argc, argv);
14953
14954 if (uj)
14955 argc--;
14956
14957 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14958 &bgp, uj);
14959 if (!idx)
14960 return CMD_WARNING;
14961
14962 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14963 argv_find(argv, argc, "neighbors", &idx);
14964 peerstr = argv[++idx]->arg;
14965
14966 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14967 if (!peer)
14968 return CMD_WARNING;
14969
14970 if (argv_find(argv, argc, "flap-statistics", &idx))
14971 sh_type = bgp_show_type_flap_neighbor;
14972 else if (argv_find(argv, argc, "dampened-routes", &idx))
14973 sh_type = bgp_show_type_damp_neighbor;
14974 else if (argv_find(argv, argc, "routes", &idx))
14975 sh_type = bgp_show_type_neighbor;
14976
14977 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14978 }
14979
14980 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14981
14982 struct bgp_distance {
14983 /* Distance value for the IP source prefix. */
14984 uint8_t distance;
14985
14986 /* Name of the access-list to be matched. */
14987 char *access_list;
14988 };
14989
14990 DEFUN (show_bgp_afi_vpn_rd_route,
14991 show_bgp_afi_vpn_rd_route_cmd,
14992 "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]",
14993 SHOW_STR
14994 BGP_STR
14995 BGP_AFI_HELP_STR
14996 BGP_AF_MODIFIER_STR
14997 "Display information for a route distinguisher\n"
14998 "Route Distinguisher\n"
14999 "All Route Distinguishers\n"
15000 "Network in the BGP routing table to display\n"
15001 "Network in the BGP routing table to display\n"
15002 JSON_STR)
15003 {
15004 int ret;
15005 struct prefix_rd prd;
15006 afi_t afi = AFI_MAX;
15007 int idx = 0;
15008
15009 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
15010 vty_out(vty, "%% Malformed Address Family\n");
15011 return CMD_WARNING;
15012 }
15013
15014 if (!strcmp(argv[5]->arg, "all"))
15015 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
15016 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
15017 RPKI_NOT_BEING_USED,
15018 use_json(argc, argv));
15019
15020 ret = str2prefix_rd(argv[5]->arg, &prd);
15021 if (!ret) {
15022 vty_out(vty, "%% Malformed Route Distinguisher\n");
15023 return CMD_WARNING;
15024 }
15025
15026 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
15027 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
15028 use_json(argc, argv));
15029 }
15030
15031 static struct bgp_distance *bgp_distance_new(void)
15032 {
15033 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
15034 }
15035
15036 static void bgp_distance_free(struct bgp_distance *bdistance)
15037 {
15038 XFREE(MTYPE_BGP_DISTANCE, bdistance);
15039 }
15040
15041 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15042 const char *ip_str, const char *access_list_str)
15043 {
15044 int ret;
15045 afi_t afi;
15046 safi_t safi;
15047 struct prefix p;
15048 uint8_t distance;
15049 struct bgp_dest *dest;
15050 struct bgp_distance *bdistance;
15051
15052 afi = bgp_node_afi(vty);
15053 safi = bgp_node_safi(vty);
15054
15055 ret = str2prefix(ip_str, &p);
15056 if (ret == 0) {
15057 vty_out(vty, "Malformed prefix\n");
15058 return CMD_WARNING_CONFIG_FAILED;
15059 }
15060
15061 distance = atoi(distance_str);
15062
15063 /* Get BGP distance node. */
15064 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15065 bdistance = bgp_dest_get_bgp_distance_info(dest);
15066 if (bdistance)
15067 bgp_dest_unlock_node(dest);
15068 else {
15069 bdistance = bgp_distance_new();
15070 bgp_dest_set_bgp_distance_info(dest, bdistance);
15071 }
15072
15073 /* Set distance value. */
15074 bdistance->distance = distance;
15075
15076 /* Reset access-list configuration. */
15077 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15078 if (access_list_str)
15079 bdistance->access_list =
15080 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15081
15082 return CMD_SUCCESS;
15083 }
15084
15085 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15086 const char *ip_str, const char *access_list_str)
15087 {
15088 int ret;
15089 afi_t afi;
15090 safi_t safi;
15091 struct prefix p;
15092 int distance;
15093 struct bgp_dest *dest;
15094 struct bgp_distance *bdistance;
15095
15096 afi = bgp_node_afi(vty);
15097 safi = bgp_node_safi(vty);
15098
15099 ret = str2prefix(ip_str, &p);
15100 if (ret == 0) {
15101 vty_out(vty, "Malformed prefix\n");
15102 return CMD_WARNING_CONFIG_FAILED;
15103 }
15104
15105 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15106 if (!dest) {
15107 vty_out(vty, "Can't find specified prefix\n");
15108 return CMD_WARNING_CONFIG_FAILED;
15109 }
15110
15111 bdistance = bgp_dest_get_bgp_distance_info(dest);
15112 distance = atoi(distance_str);
15113
15114 if (bdistance->distance != distance) {
15115 vty_out(vty, "Distance does not match configured\n");
15116 bgp_dest_unlock_node(dest);
15117 return CMD_WARNING_CONFIG_FAILED;
15118 }
15119
15120 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15121 bgp_distance_free(bdistance);
15122
15123 bgp_dest_set_bgp_path_info(dest, NULL);
15124 bgp_dest_unlock_node(dest);
15125 bgp_dest_unlock_node(dest);
15126
15127 return CMD_SUCCESS;
15128 }
15129
15130 /* Apply BGP information to distance method. */
15131 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15132 afi_t afi, safi_t safi, struct bgp *bgp)
15133 {
15134 struct bgp_dest *dest;
15135 struct prefix q = {0};
15136 struct peer *peer;
15137 struct bgp_distance *bdistance;
15138 struct access_list *alist;
15139 struct bgp_static *bgp_static;
15140 struct bgp_path_info *bpi_ultimate;
15141
15142 if (!bgp)
15143 return 0;
15144
15145 peer = pinfo->peer;
15146
15147 if (pinfo->attr->distance)
15148 return pinfo->attr->distance;
15149
15150 /* get peer origin to calculate appropriate distance */
15151 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15152 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15153 peer = bpi_ultimate->peer;
15154 }
15155
15156 /* Check source address.
15157 * Note: for aggregate route, peer can have unspec af type.
15158 */
15159 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15160 && !sockunion2hostprefix(&peer->su, &q))
15161 return 0;
15162
15163 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15164 if (dest) {
15165 bdistance = bgp_dest_get_bgp_distance_info(dest);
15166 bgp_dest_unlock_node(dest);
15167
15168 if (bdistance->access_list) {
15169 alist = access_list_lookup(afi, bdistance->access_list);
15170 if (alist
15171 && access_list_apply(alist, p) == FILTER_PERMIT)
15172 return bdistance->distance;
15173 } else
15174 return bdistance->distance;
15175 }
15176
15177 /* Backdoor check. */
15178 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15179 if (dest) {
15180 bgp_static = bgp_dest_get_bgp_static_info(dest);
15181 bgp_dest_unlock_node(dest);
15182
15183 if (bgp_static->backdoor) {
15184 if (bgp->distance_local[afi][safi])
15185 return bgp->distance_local[afi][safi];
15186 else
15187 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15188 }
15189 }
15190
15191 if (peer->sort == BGP_PEER_EBGP) {
15192 if (bgp->distance_ebgp[afi][safi])
15193 return bgp->distance_ebgp[afi][safi];
15194 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15195 } else if (peer->sort == BGP_PEER_IBGP) {
15196 if (bgp->distance_ibgp[afi][safi])
15197 return bgp->distance_ibgp[afi][safi];
15198 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15199 } else {
15200 if (bgp->distance_local[afi][safi])
15201 return bgp->distance_local[afi][safi];
15202 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15203 }
15204 }
15205
15206 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15207 * we should tell ZEBRA update the routes for a specific
15208 * AFI/SAFI to reflect changes in RIB.
15209 */
15210 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15211 afi_t update_afi,
15212 safi_t update_safi)
15213 {
15214 afi_t afi;
15215 safi_t safi;
15216
15217 FOREACH_AFI_SAFI (afi, safi) {
15218 if (!bgp_fibupd_safi(safi))
15219 continue;
15220
15221 if (afi != update_afi && safi != update_safi)
15222 continue;
15223
15224 if (BGP_DEBUG(zebra, ZEBRA))
15225 zlog_debug(
15226 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15227 __func__, afi, safi);
15228 bgp_zebra_announce_table(bgp, afi, safi);
15229 }
15230 }
15231
15232 DEFUN (bgp_distance,
15233 bgp_distance_cmd,
15234 "distance bgp (1-255) (1-255) (1-255)",
15235 "Define an administrative distance\n"
15236 "BGP distance\n"
15237 "Distance for routes external to the AS\n"
15238 "Distance for routes internal to the AS\n"
15239 "Distance for local routes\n")
15240 {
15241 VTY_DECLVAR_CONTEXT(bgp, bgp);
15242 int idx_number = 2;
15243 int idx_number_2 = 3;
15244 int idx_number_3 = 4;
15245 int distance_ebgp = atoi(argv[idx_number]->arg);
15246 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15247 int distance_local = atoi(argv[idx_number_3]->arg);
15248 afi_t afi;
15249 safi_t safi;
15250
15251 afi = bgp_node_afi(vty);
15252 safi = bgp_node_safi(vty);
15253
15254 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15255 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15256 || bgp->distance_local[afi][safi] != distance_local) {
15257 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15258 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15259 bgp->distance_local[afi][safi] = distance_local;
15260 bgp_announce_routes_distance_update(bgp, afi, safi);
15261 }
15262 return CMD_SUCCESS;
15263 }
15264
15265 DEFUN (no_bgp_distance,
15266 no_bgp_distance_cmd,
15267 "no distance bgp [(1-255) (1-255) (1-255)]",
15268 NO_STR
15269 "Define an administrative distance\n"
15270 "BGP distance\n"
15271 "Distance for routes external to the AS\n"
15272 "Distance for routes internal to the AS\n"
15273 "Distance for local routes\n")
15274 {
15275 VTY_DECLVAR_CONTEXT(bgp, bgp);
15276 afi_t afi;
15277 safi_t safi;
15278
15279 afi = bgp_node_afi(vty);
15280 safi = bgp_node_safi(vty);
15281
15282 if (bgp->distance_ebgp[afi][safi] != 0
15283 || bgp->distance_ibgp[afi][safi] != 0
15284 || bgp->distance_local[afi][safi] != 0) {
15285 bgp->distance_ebgp[afi][safi] = 0;
15286 bgp->distance_ibgp[afi][safi] = 0;
15287 bgp->distance_local[afi][safi] = 0;
15288 bgp_announce_routes_distance_update(bgp, afi, safi);
15289 }
15290 return CMD_SUCCESS;
15291 }
15292
15293
15294 DEFUN (bgp_distance_source,
15295 bgp_distance_source_cmd,
15296 "distance (1-255) A.B.C.D/M",
15297 "Define an administrative distance\n"
15298 "Administrative distance\n"
15299 "IP source prefix\n")
15300 {
15301 int idx_number = 1;
15302 int idx_ipv4_prefixlen = 2;
15303 bgp_distance_set(vty, argv[idx_number]->arg,
15304 argv[idx_ipv4_prefixlen]->arg, NULL);
15305 return CMD_SUCCESS;
15306 }
15307
15308 DEFUN (no_bgp_distance_source,
15309 no_bgp_distance_source_cmd,
15310 "no distance (1-255) A.B.C.D/M",
15311 NO_STR
15312 "Define an administrative distance\n"
15313 "Administrative distance\n"
15314 "IP source prefix\n")
15315 {
15316 int idx_number = 2;
15317 int idx_ipv4_prefixlen = 3;
15318 bgp_distance_unset(vty, argv[idx_number]->arg,
15319 argv[idx_ipv4_prefixlen]->arg, NULL);
15320 return CMD_SUCCESS;
15321 }
15322
15323 DEFUN (bgp_distance_source_access_list,
15324 bgp_distance_source_access_list_cmd,
15325 "distance (1-255) A.B.C.D/M WORD",
15326 "Define an administrative distance\n"
15327 "Administrative distance\n"
15328 "IP source prefix\n"
15329 "Access list name\n")
15330 {
15331 int idx_number = 1;
15332 int idx_ipv4_prefixlen = 2;
15333 int idx_word = 3;
15334 bgp_distance_set(vty, argv[idx_number]->arg,
15335 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15336 return CMD_SUCCESS;
15337 }
15338
15339 DEFUN (no_bgp_distance_source_access_list,
15340 no_bgp_distance_source_access_list_cmd,
15341 "no distance (1-255) A.B.C.D/M WORD",
15342 NO_STR
15343 "Define an administrative distance\n"
15344 "Administrative distance\n"
15345 "IP source prefix\n"
15346 "Access list name\n")
15347 {
15348 int idx_number = 2;
15349 int idx_ipv4_prefixlen = 3;
15350 int idx_word = 4;
15351 bgp_distance_unset(vty, argv[idx_number]->arg,
15352 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15353 return CMD_SUCCESS;
15354 }
15355
15356 DEFUN (ipv6_bgp_distance_source,
15357 ipv6_bgp_distance_source_cmd,
15358 "distance (1-255) X:X::X:X/M",
15359 "Define an administrative distance\n"
15360 "Administrative distance\n"
15361 "IP source prefix\n")
15362 {
15363 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15364 return CMD_SUCCESS;
15365 }
15366
15367 DEFUN (no_ipv6_bgp_distance_source,
15368 no_ipv6_bgp_distance_source_cmd,
15369 "no distance (1-255) X:X::X:X/M",
15370 NO_STR
15371 "Define an administrative distance\n"
15372 "Administrative distance\n"
15373 "IP source prefix\n")
15374 {
15375 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15376 return CMD_SUCCESS;
15377 }
15378
15379 DEFUN (ipv6_bgp_distance_source_access_list,
15380 ipv6_bgp_distance_source_access_list_cmd,
15381 "distance (1-255) X:X::X:X/M WORD",
15382 "Define an administrative distance\n"
15383 "Administrative distance\n"
15384 "IP source prefix\n"
15385 "Access list name\n")
15386 {
15387 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15388 return CMD_SUCCESS;
15389 }
15390
15391 DEFUN (no_ipv6_bgp_distance_source_access_list,
15392 no_ipv6_bgp_distance_source_access_list_cmd,
15393 "no distance (1-255) X:X::X:X/M WORD",
15394 NO_STR
15395 "Define an administrative distance\n"
15396 "Administrative distance\n"
15397 "IP source prefix\n"
15398 "Access list name\n")
15399 {
15400 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15401 return CMD_SUCCESS;
15402 }
15403
15404 DEFUN (bgp_damp_set,
15405 bgp_damp_set_cmd,
15406 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15407 "BGP Specific commands\n"
15408 "Enable route-flap dampening\n"
15409 "Half-life time for the penalty\n"
15410 "Value to start reusing a route\n"
15411 "Value to start suppressing a route\n"
15412 "Maximum duration to suppress a stable route\n")
15413 {
15414 VTY_DECLVAR_CONTEXT(bgp, bgp);
15415 int idx_half_life = 2;
15416 int idx_reuse = 3;
15417 int idx_suppress = 4;
15418 int idx_max_suppress = 5;
15419 int half = DEFAULT_HALF_LIFE * 60;
15420 int reuse = DEFAULT_REUSE;
15421 int suppress = DEFAULT_SUPPRESS;
15422 int max = 4 * half;
15423
15424 if (argc == 6) {
15425 half = atoi(argv[idx_half_life]->arg) * 60;
15426 reuse = atoi(argv[idx_reuse]->arg);
15427 suppress = atoi(argv[idx_suppress]->arg);
15428 max = atoi(argv[idx_max_suppress]->arg) * 60;
15429 } else if (argc == 3) {
15430 half = atoi(argv[idx_half_life]->arg) * 60;
15431 max = 4 * half;
15432 }
15433
15434 /*
15435 * These can't be 0 but our SA doesn't understand the
15436 * way our cli is constructed
15437 */
15438 assert(reuse);
15439 assert(half);
15440 if (suppress < reuse) {
15441 vty_out(vty,
15442 "Suppress value cannot be less than reuse value \n");
15443 return 0;
15444 }
15445
15446 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15447 reuse, suppress, max);
15448 }
15449
15450 DEFUN (bgp_damp_unset,
15451 bgp_damp_unset_cmd,
15452 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15453 NO_STR
15454 "BGP Specific commands\n"
15455 "Enable route-flap dampening\n"
15456 "Half-life time for the penalty\n"
15457 "Value to start reusing a route\n"
15458 "Value to start suppressing a route\n"
15459 "Maximum duration to suppress a stable route\n")
15460 {
15461 VTY_DECLVAR_CONTEXT(bgp, bgp);
15462 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15463 }
15464
15465 /* Display specified route of BGP table. */
15466 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15467 const char *ip_str, afi_t afi, safi_t safi,
15468 struct prefix_rd *prd, int prefix_check)
15469 {
15470 int ret;
15471 struct prefix match;
15472 struct bgp_dest *dest;
15473 struct bgp_dest *rm;
15474 struct bgp_path_info *pi;
15475 struct bgp_path_info *pi_temp;
15476 struct bgp *bgp;
15477 struct bgp_table *table;
15478
15479 /* BGP structure lookup. */
15480 if (view_name) {
15481 bgp = bgp_lookup_by_name(view_name);
15482 if (bgp == NULL) {
15483 vty_out(vty, "%% Can't find BGP instance %s\n",
15484 view_name);
15485 return CMD_WARNING;
15486 }
15487 } else {
15488 bgp = bgp_get_default();
15489 if (bgp == NULL) {
15490 vty_out(vty, "%% No BGP process is configured\n");
15491 return CMD_WARNING;
15492 }
15493 }
15494
15495 /* Check IP address argument. */
15496 ret = str2prefix(ip_str, &match);
15497 if (!ret) {
15498 vty_out(vty, "%% address is malformed\n");
15499 return CMD_WARNING;
15500 }
15501
15502 match.family = afi2family(afi);
15503
15504 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15505 || (safi == SAFI_EVPN)) {
15506 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15507 dest = bgp_route_next(dest)) {
15508 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15509
15510 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15511 continue;
15512 table = bgp_dest_get_bgp_table_info(dest);
15513 if (!table)
15514 continue;
15515 rm = bgp_node_match(table, &match);
15516 if (rm == NULL)
15517 continue;
15518
15519 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15520
15521 if (!prefix_check
15522 || rm_p->prefixlen == match.prefixlen) {
15523 pi = bgp_dest_get_bgp_path_info(rm);
15524 while (pi) {
15525 if (pi->extra && pi->extra->damp_info) {
15526 pi_temp = pi->next;
15527 bgp_damp_info_free(
15528 pi->extra->damp_info,
15529 1, afi, safi);
15530 pi = pi_temp;
15531 } else
15532 pi = pi->next;
15533 }
15534 }
15535
15536 bgp_dest_unlock_node(rm);
15537 }
15538 } else {
15539 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15540 if (dest != NULL) {
15541 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15542
15543 if (!prefix_check
15544 || dest_p->prefixlen == match.prefixlen) {
15545 pi = bgp_dest_get_bgp_path_info(dest);
15546 while (pi) {
15547 if (pi->extra && pi->extra->damp_info) {
15548 pi_temp = pi->next;
15549 bgp_damp_info_free(
15550 pi->extra->damp_info,
15551 1, afi, safi);
15552 pi = pi_temp;
15553 } else
15554 pi = pi->next;
15555 }
15556 }
15557
15558 bgp_dest_unlock_node(dest);
15559 }
15560 }
15561
15562 return CMD_SUCCESS;
15563 }
15564
15565 DEFUN (clear_ip_bgp_dampening,
15566 clear_ip_bgp_dampening_cmd,
15567 "clear ip bgp dampening",
15568 CLEAR_STR
15569 IP_STR
15570 BGP_STR
15571 "Clear route flap dampening information\n")
15572 {
15573 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15574 return CMD_SUCCESS;
15575 }
15576
15577 DEFUN (clear_ip_bgp_dampening_prefix,
15578 clear_ip_bgp_dampening_prefix_cmd,
15579 "clear ip bgp dampening A.B.C.D/M",
15580 CLEAR_STR
15581 IP_STR
15582 BGP_STR
15583 "Clear route flap dampening information\n"
15584 "IPv4 prefix\n")
15585 {
15586 int idx_ipv4_prefixlen = 4;
15587 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15588 AFI_IP, SAFI_UNICAST, NULL, 1);
15589 }
15590
15591 DEFUN (clear_ip_bgp_dampening_address,
15592 clear_ip_bgp_dampening_address_cmd,
15593 "clear ip bgp dampening A.B.C.D",
15594 CLEAR_STR
15595 IP_STR
15596 BGP_STR
15597 "Clear route flap dampening information\n"
15598 "Network to clear damping information\n")
15599 {
15600 int idx_ipv4 = 4;
15601 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15602 SAFI_UNICAST, NULL, 0);
15603 }
15604
15605 DEFUN (clear_ip_bgp_dampening_address_mask,
15606 clear_ip_bgp_dampening_address_mask_cmd,
15607 "clear ip bgp dampening A.B.C.D A.B.C.D",
15608 CLEAR_STR
15609 IP_STR
15610 BGP_STR
15611 "Clear route flap dampening information\n"
15612 "Network to clear damping information\n"
15613 "Network mask\n")
15614 {
15615 int idx_ipv4 = 4;
15616 int idx_ipv4_2 = 5;
15617 int ret;
15618 char prefix_str[BUFSIZ];
15619
15620 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15621 prefix_str, sizeof(prefix_str));
15622 if (!ret) {
15623 vty_out(vty, "%% Inconsistent address and mask\n");
15624 return CMD_WARNING;
15625 }
15626
15627 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15628 NULL, 0);
15629 }
15630
15631 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15632 {
15633 struct vty *vty = arg;
15634 struct peer *peer = bucket->data;
15635
15636 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15637 }
15638
15639 DEFUN (show_bgp_listeners,
15640 show_bgp_listeners_cmd,
15641 "show bgp listeners",
15642 SHOW_STR
15643 BGP_STR
15644 "Display Listen Sockets and who created them\n")
15645 {
15646 bgp_dump_listener_info(vty);
15647
15648 return CMD_SUCCESS;
15649 }
15650
15651 DEFUN (show_bgp_peerhash,
15652 show_bgp_peerhash_cmd,
15653 "show bgp peerhash",
15654 SHOW_STR
15655 BGP_STR
15656 "Display information about the BGP peerhash\n")
15657 {
15658 struct list *instances = bm->bgp;
15659 struct listnode *node;
15660 struct bgp *bgp;
15661
15662 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15663 vty_out(vty, "BGP: %s\n", bgp->name);
15664 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15665 vty);
15666 }
15667
15668 return CMD_SUCCESS;
15669 }
15670
15671 /* also used for encap safi */
15672 static void bgp_config_write_network_vpn(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 mpls_label_t label;
15681
15682 /* Network configuration. */
15683 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15684 pdest = bgp_route_next(pdest)) {
15685 table = bgp_dest_get_bgp_table_info(pdest);
15686 if (!table)
15687 continue;
15688
15689 for (dest = bgp_table_top(table); dest;
15690 dest = bgp_route_next(dest)) {
15691 bgp_static = bgp_dest_get_bgp_static_info(dest);
15692 if (bgp_static == NULL)
15693 continue;
15694
15695 p = bgp_dest_get_prefix(dest);
15696
15697 /* "network" configuration display. */
15698 label = decode_label(&bgp_static->label);
15699
15700 vty_out(vty, " network %pFX rd %s", p,
15701 bgp_static->prd_pretty);
15702 if (safi == SAFI_MPLS_VPN)
15703 vty_out(vty, " label %u", label);
15704
15705 if (bgp_static->rmap.name)
15706 vty_out(vty, " route-map %s",
15707 bgp_static->rmap.name);
15708
15709 if (bgp_static->backdoor)
15710 vty_out(vty, " backdoor");
15711
15712 vty_out(vty, "\n");
15713 }
15714 }
15715 }
15716
15717 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15718 afi_t afi, safi_t safi)
15719 {
15720 struct bgp_dest *pdest;
15721 struct bgp_dest *dest;
15722 struct bgp_table *table;
15723 const struct prefix *p;
15724 struct bgp_static *bgp_static;
15725 char buf[PREFIX_STRLEN * 2];
15726 char buf2[SU_ADDRSTRLEN];
15727 char esi_buf[ESI_STR_LEN];
15728
15729 /* Network configuration. */
15730 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15731 pdest = bgp_route_next(pdest)) {
15732 table = bgp_dest_get_bgp_table_info(pdest);
15733 if (!table)
15734 continue;
15735
15736 for (dest = bgp_table_top(table); dest;
15737 dest = bgp_route_next(dest)) {
15738 bgp_static = bgp_dest_get_bgp_static_info(dest);
15739 if (bgp_static == NULL)
15740 continue;
15741
15742 char *macrouter = NULL;
15743
15744 if (bgp_static->router_mac)
15745 macrouter = prefix_mac2str(
15746 bgp_static->router_mac, NULL, 0);
15747 if (bgp_static->eth_s_id)
15748 esi_to_str(bgp_static->eth_s_id,
15749 esi_buf, sizeof(esi_buf));
15750 p = bgp_dest_get_prefix(dest);
15751
15752 /* "network" configuration display. */
15753 if (p->u.prefix_evpn.route_type == 5) {
15754 char local_buf[PREFIX_STRLEN];
15755
15756 uint8_t family = is_evpn_prefix_ipaddr_v4((
15757 struct prefix_evpn *)p)
15758 ? AF_INET
15759 : AF_INET6;
15760 inet_ntop(family,
15761 &p->u.prefix_evpn.prefix_addr.ip.ip
15762 .addr,
15763 local_buf, sizeof(local_buf));
15764 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15765 p->u.prefix_evpn.prefix_addr
15766 .ip_prefix_length);
15767 } else {
15768 prefix2str(p, buf, sizeof(buf));
15769 }
15770
15771 if (bgp_static->gatewayIp.family == AF_INET
15772 || bgp_static->gatewayIp.family == AF_INET6)
15773 inet_ntop(bgp_static->gatewayIp.family,
15774 &bgp_static->gatewayIp.u.prefix, buf2,
15775 sizeof(buf2));
15776 vty_out(vty,
15777 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15778 buf, bgp_static->prd_pretty,
15779 p->u.prefix_evpn.prefix_addr.eth_tag,
15780 decode_label(&bgp_static->label), esi_buf, buf2,
15781 macrouter);
15782
15783 XFREE(MTYPE_TMP, macrouter);
15784 }
15785 }
15786 }
15787
15788 /* Configuration of static route announcement and aggregate
15789 information. */
15790 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15791 safi_t safi)
15792 {
15793 struct bgp_dest *dest;
15794 const struct prefix *p;
15795 struct bgp_static *bgp_static;
15796 struct bgp_aggregate *bgp_aggregate;
15797
15798 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15799 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15800 return;
15801 }
15802
15803 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15804 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15805 return;
15806 }
15807
15808 /* Network configuration. */
15809 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15810 dest = bgp_route_next(dest)) {
15811 bgp_static = bgp_dest_get_bgp_static_info(dest);
15812 if (bgp_static == NULL)
15813 continue;
15814
15815 p = bgp_dest_get_prefix(dest);
15816
15817 vty_out(vty, " network %pFX", p);
15818
15819 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15820 vty_out(vty, " label-index %u",
15821 bgp_static->label_index);
15822
15823 if (bgp_static->rmap.name)
15824 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15825
15826 if (bgp_static->backdoor)
15827 vty_out(vty, " backdoor");
15828
15829 vty_out(vty, "\n");
15830 }
15831
15832 /* Aggregate-address configuration. */
15833 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15834 dest = bgp_route_next(dest)) {
15835 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15836 if (bgp_aggregate == NULL)
15837 continue;
15838
15839 p = bgp_dest_get_prefix(dest);
15840
15841 vty_out(vty, " aggregate-address %pFX", p);
15842
15843 if (bgp_aggregate->as_set)
15844 vty_out(vty, " as-set");
15845
15846 if (bgp_aggregate->summary_only)
15847 vty_out(vty, " summary-only");
15848
15849 if (bgp_aggregate->rmap.name)
15850 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15851
15852 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15853 vty_out(vty, " origin %s",
15854 bgp_origin2str(bgp_aggregate->origin));
15855
15856 if (bgp_aggregate->match_med)
15857 vty_out(vty, " matching-MED-only");
15858
15859 if (bgp_aggregate->suppress_map_name)
15860 vty_out(vty, " suppress-map %s",
15861 bgp_aggregate->suppress_map_name);
15862
15863 vty_out(vty, "\n");
15864 }
15865 }
15866
15867 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15868 safi_t safi)
15869 {
15870 struct bgp_dest *dest;
15871 struct bgp_distance *bdistance;
15872
15873 /* Distance configuration. */
15874 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15875 && bgp->distance_local[afi][safi]
15876 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15877 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15878 || bgp->distance_local[afi][safi]
15879 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15880 vty_out(vty, " distance bgp %d %d %d\n",
15881 bgp->distance_ebgp[afi][safi],
15882 bgp->distance_ibgp[afi][safi],
15883 bgp->distance_local[afi][safi]);
15884 }
15885
15886 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15887 dest = bgp_route_next(dest)) {
15888 bdistance = bgp_dest_get_bgp_distance_info(dest);
15889 if (bdistance != NULL)
15890 vty_out(vty, " distance %d %pBD %s\n",
15891 bdistance->distance, dest,
15892 bdistance->access_list ? bdistance->access_list
15893 : "");
15894 }
15895 }
15896
15897 /* Allocate routing table structure and install commands. */
15898 void bgp_route_init(void)
15899 {
15900 afi_t afi;
15901 safi_t safi;
15902
15903 /* Init BGP distance table. */
15904 FOREACH_AFI_SAFI (afi, safi)
15905 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15906
15907 /* IPv4 BGP commands. */
15908 install_element(BGP_NODE, &bgp_table_map_cmd);
15909 install_element(BGP_NODE, &bgp_network_cmd);
15910 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15911
15912 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15913
15914 /* IPv4 unicast configuration. */
15915 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15916 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15917 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15918
15919 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15920
15921 /* IPv4 multicast configuration. */
15922 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15923 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15924 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15925 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15926
15927 /* IPv4 labeled-unicast configuration. */
15928 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15929 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15930
15931 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15932 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15933 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15934 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15935 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15936 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15937 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15938 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15939
15940 install_element(VIEW_NODE,
15941 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15942 install_element(VIEW_NODE,
15943 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15944 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15945 install_element(VIEW_NODE,
15946 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15947 #ifdef KEEP_OLD_VPN_COMMANDS
15948 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15949 #endif /* KEEP_OLD_VPN_COMMANDS */
15950 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15951 install_element(VIEW_NODE,
15952 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15953
15954 /* BGP dampening clear commands */
15955 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15956 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15957
15958 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15959 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15960
15961 /* prefix count */
15962 install_element(ENABLE_NODE,
15963 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15964 #ifdef KEEP_OLD_VPN_COMMANDS
15965 install_element(ENABLE_NODE,
15966 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15967 #endif /* KEEP_OLD_VPN_COMMANDS */
15968
15969 /* New config IPv6 BGP commands. */
15970 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15971 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15972 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15973
15974 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15975
15976 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15977
15978 /* IPv6 labeled unicast address family. */
15979 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15980 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15981
15982 install_element(BGP_NODE, &bgp_distance_cmd);
15983 install_element(BGP_NODE, &no_bgp_distance_cmd);
15984 install_element(BGP_NODE, &bgp_distance_source_cmd);
15985 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15986 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15987 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15988 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15989 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15990 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15991 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15992 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15993 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15994 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15995 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15996 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15997 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15998 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15999 install_element(BGP_IPV4M_NODE,
16000 &no_bgp_distance_source_access_list_cmd);
16001 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
16002 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
16003 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
16004 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
16005 install_element(BGP_IPV6_NODE,
16006 &ipv6_bgp_distance_source_access_list_cmd);
16007 install_element(BGP_IPV6_NODE,
16008 &no_ipv6_bgp_distance_source_access_list_cmd);
16009 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
16010 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
16011 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
16012 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
16013 install_element(BGP_IPV6M_NODE,
16014 &ipv6_bgp_distance_source_access_list_cmd);
16015 install_element(BGP_IPV6M_NODE,
16016 &no_ipv6_bgp_distance_source_access_list_cmd);
16017
16018 /* BGP dampening */
16019 install_element(BGP_NODE, &bgp_damp_set_cmd);
16020 install_element(BGP_NODE, &bgp_damp_unset_cmd);
16021 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
16022 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
16023 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
16024 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
16025 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
16026 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
16027 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
16028 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
16029 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
16030 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
16031 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
16032 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
16033
16034 /* Large Communities */
16035 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
16036 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
16037
16038 /* show bgp ipv4 flowspec detailed */
16039 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
16040
16041 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16042 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16043 }
16044
16045 void bgp_route_finish(void)
16046 {
16047 afi_t afi;
16048 safi_t safi;
16049
16050 FOREACH_AFI_SAFI (afi, safi) {
16051 bgp_table_unlock(bgp_distance_table[afi][safi]);
16052 bgp_distance_table[afi][safi] = NULL;
16053 }
16054 }