]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #13123 from donaldsharp/fix_route_map_name
[mirror_frr.git] / bgpd / bgp_route.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP routing information
3 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
4 * Copyright (C) 2016 Job Snijders <job@instituut.net>
5 */
6
7 #include <zebra.h>
8 #include <math.h>
9
10 #include "printfrr.h"
11 #include "frrstr.h"
12 #include "prefix.h"
13 #include "linklist.h"
14 #include "memory.h"
15 #include "command.h"
16 #include "stream.h"
17 #include "filter.h"
18 #include "log.h"
19 #include "routemap.h"
20 #include "buffer.h"
21 #include "sockunion.h"
22 #include "plist.h"
23 #include "frrevent.h"
24 #include "workqueue.h"
25 #include "queue.h"
26 #include "memory.h"
27 #include "srv6.h"
28 #include "lib/json.h"
29 #include "lib_errors.h"
30 #include "zclient.h"
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_table.h"
33 #include "bgpd/bgp_route.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_debug.h"
36 #include "bgpd/bgp_errors.h"
37 #include "bgpd/bgp_aspath.h"
38 #include "bgpd/bgp_regex.h"
39 #include "bgpd/bgp_community.h"
40 #include "bgpd/bgp_community_alias.h"
41 #include "bgpd/bgp_ecommunity.h"
42 #include "bgpd/bgp_lcommunity.h"
43 #include "bgpd/bgp_clist.h"
44 #include "bgpd/bgp_packet.h"
45 #include "bgpd/bgp_filter.h"
46 #include "bgpd/bgp_fsm.h"
47 #include "bgpd/bgp_mplsvpn.h"
48 #include "bgpd/bgp_nexthop.h"
49 #include "bgpd/bgp_damp.h"
50 #include "bgpd/bgp_advertise.h"
51 #include "bgpd/bgp_zebra.h"
52 #include "bgpd/bgp_vty.h"
53 #include "bgpd/bgp_mpath.h"
54 #include "bgpd/bgp_nht.h"
55 #include "bgpd/bgp_updgrp.h"
56 #include "bgpd/bgp_label.h"
57 #include "bgpd/bgp_addpath.h"
58 #include "bgpd/bgp_mac.h"
59 #include "bgpd/bgp_network.h"
60 #include "bgpd/bgp_trace.h"
61 #include "bgpd/bgp_rpki.h"
62
63 #ifdef ENABLE_BGP_VNC
64 #include "bgpd/rfapi/rfapi_backend.h"
65 #include "bgpd/rfapi/vnc_import_bgp.h"
66 #include "bgpd/rfapi/vnc_export_bgp.h"
67 #endif
68 #include "bgpd/bgp_encap_types.h"
69 #include "bgpd/bgp_encap_tlv.h"
70 #include "bgpd/bgp_evpn.h"
71 #include "bgpd/bgp_evpn_mh.h"
72 #include "bgpd/bgp_evpn_vty.h"
73 #include "bgpd/bgp_flowspec.h"
74 #include "bgpd/bgp_flowspec_util.h"
75 #include "bgpd/bgp_pbr.h"
76
77 #include "bgpd/bgp_route_clippy.c"
78
79 DEFINE_HOOK(bgp_snmp_update_stats,
80 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
81 (rn, pi, added));
82
83 DEFINE_HOOK(bgp_rpki_prefix_status,
84 (struct peer *peer, struct attr *attr,
85 const struct prefix *prefix),
86 (peer, attr, prefix));
87
88 /* Extern from bgp_dump.c */
89 extern const char *bgp_origin_str[];
90 extern const char *bgp_origin_long_str[];
91
92 /* PMSI strings. */
93 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
94 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
95 static const struct message bgp_pmsi_tnltype_str[] = {
96 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
97 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
98 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
99 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
100 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
101 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
102 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
103 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
104 {0}
105 };
106
107 #define VRFID_NONE_STR "-"
108 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
109
110 DEFINE_HOOK(bgp_process,
111 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
112 struct peer *peer, bool withdraw),
113 (bgp, afi, safi, bn, peer, withdraw));
114
115 /** Test if path is suppressed. */
116 static bool bgp_path_suppressed(struct bgp_path_info *pi)
117 {
118 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
119 return false;
120
121 return listcount(pi->extra->aggr_suppressors) > 0;
122 }
123
124 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
125 safi_t safi, const struct prefix *p,
126 struct prefix_rd *prd)
127 {
128 struct bgp_dest *dest;
129 struct bgp_dest *pdest = NULL;
130
131 assert(table);
132
133 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
134 || (safi == SAFI_EVPN)) {
135 pdest = bgp_node_get(table, (struct prefix *)prd);
136
137 if (!bgp_dest_has_bgp_path_info_data(pdest))
138 bgp_dest_set_bgp_table_info(
139 pdest, bgp_table_init(table->bgp, afi, safi));
140 else
141 bgp_dest_unlock_node(pdest);
142 table = bgp_dest_get_bgp_table_info(pdest);
143 }
144
145 dest = bgp_node_get(table, p);
146
147 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
148 || (safi == SAFI_EVPN))
149 dest->pdest = pdest;
150
151 return dest;
152 }
153
154 struct bgp_dest *bgp_safi_node_lookup(struct bgp_table *table, safi_t safi,
155 const struct prefix *p,
156 struct prefix_rd *prd)
157 {
158 struct bgp_dest *dest;
159 struct bgp_dest *pdest = NULL;
160
161 if (!table)
162 return NULL;
163
164 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
165 || (safi == SAFI_EVPN)) {
166 pdest = bgp_node_lookup(table, (struct prefix *)prd);
167 if (!pdest)
168 return NULL;
169
170 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
171 bgp_dest_unlock_node(pdest);
172 return NULL;
173 }
174
175 table = bgp_dest_get_bgp_table_info(pdest);
176 }
177
178 dest = bgp_node_lookup(table, p);
179
180 return dest;
181 }
182
183 /* Allocate bgp_path_info_extra */
184 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
185 {
186 struct bgp_path_info_extra *new;
187 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
188 sizeof(struct bgp_path_info_extra));
189 new->label[0] = MPLS_INVALID_LABEL;
190 new->num_labels = 0;
191 new->bgp_fs_pbr = NULL;
192 new->bgp_fs_iprule = NULL;
193 return new;
194 }
195
196 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
197 {
198 struct bgp_path_info_extra *e;
199
200 if (!extra || !*extra)
201 return;
202
203 e = *extra;
204 if (e->damp_info)
205 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
206 e->damp_info->safi);
207
208 e->damp_info = NULL;
209 if (e->parent) {
210 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
211
212 if (bpi->net) {
213 /* FIXME: since multiple e may have the same e->parent
214 * and e->parent->net is holding a refcount for each
215 * of them, we need to do some fudging here.
216 *
217 * WARNING: if bpi->net->lock drops to 0, bpi may be
218 * freed as well (because bpi->net was holding the
219 * last reference to bpi) => write after free!
220 */
221 unsigned refcount;
222
223 bpi = bgp_path_info_lock(bpi);
224 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
225 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
226 if (!refcount)
227 bpi->net = NULL;
228 bgp_path_info_unlock(bpi);
229 }
230 bgp_path_info_unlock(e->parent);
231 e->parent = NULL;
232 }
233
234 if (e->bgp_orig)
235 bgp_unlock(e->bgp_orig);
236
237 if (e->peer_orig)
238 peer_unlock(e->peer_orig);
239
240 if (e->aggr_suppressors)
241 list_delete(&e->aggr_suppressors);
242
243 if (e->mh_info)
244 bgp_evpn_path_mh_info_free(e->mh_info);
245
246 if ((*extra)->bgp_fs_iprule)
247 list_delete(&((*extra)->bgp_fs_iprule));
248 if ((*extra)->bgp_fs_pbr)
249 list_delete(&((*extra)->bgp_fs_pbr));
250 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
251 }
252
253 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
254 * allocated if required.
255 */
256 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
257 {
258 if (!pi->extra)
259 pi->extra = bgp_path_info_extra_new();
260 return pi->extra;
261 }
262
263 /* Free bgp route information. */
264 void bgp_path_info_free_with_caller(const char *name,
265 struct bgp_path_info *path)
266 {
267 frrtrace(2, frr_bgp, bgp_path_info_free, path, name);
268 bgp_attr_unintern(&path->attr);
269
270 bgp_unlink_nexthop(path);
271 bgp_path_info_extra_free(&path->extra);
272 bgp_path_info_mpath_free(&path->mpath);
273 if (path->net)
274 bgp_addpath_free_info_data(&path->tx_addpath,
275 &path->net->tx_addpath);
276
277 peer_unlock(path->peer); /* bgp_path_info peer reference */
278
279 XFREE(MTYPE_BGP_ROUTE, path);
280 }
281
282 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
283 {
284 path->lock++;
285 return path;
286 }
287
288 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
289 {
290 assert(path && path->lock > 0);
291 path->lock--;
292
293 if (path->lock == 0) {
294 bgp_path_info_free(path);
295 return NULL;
296 }
297
298 return path;
299 }
300
301 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
302 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
303 {
304 struct peer *peer;
305 struct bgp_path_info *old_pi, *nextpi;
306 bool set_flag = false;
307 struct bgp *bgp = NULL;
308 struct bgp_table *table = NULL;
309 afi_t afi = 0;
310 safi_t safi = 0;
311
312 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
313 * then the route selection is deferred
314 */
315 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
316 return 0;
317
318 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
319 if (BGP_DEBUG(update, UPDATE_OUT)) {
320 table = bgp_dest_table(dest);
321 if (table)
322 bgp = table->bgp;
323
324 zlog_debug(
325 "Route %pBD(%s) is in workqueue and being processed, not deferred.",
326 dest, bgp ? bgp->name_pretty : "(Unknown)");
327 }
328
329 return 0;
330 }
331
332 table = bgp_dest_table(dest);
333 if (table) {
334 bgp = table->bgp;
335 afi = table->afi;
336 safi = table->safi;
337 }
338
339 for (old_pi = bgp_dest_get_bgp_path_info(dest);
340 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
341 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
342 continue;
343
344 /* Route selection is deferred if there is a stale path which
345 * which indicates peer is in restart mode
346 */
347 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
348 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
349 set_flag = true;
350 } else {
351 /* If the peer is graceful restart capable and peer is
352 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
353 */
354 peer = old_pi->peer;
355 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
356 && BGP_PEER_RESTARTING_MODE(peer)
357 && (old_pi
358 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
359 set_flag = true;
360 }
361 }
362 if (set_flag)
363 break;
364 }
365
366 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
367 * is active
368 */
369 if (set_flag && table) {
370 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
371 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
372 bgp->gr_info[afi][safi].gr_deferred++;
373 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
374 if (BGP_DEBUG(update, UPDATE_OUT))
375 zlog_debug("DEFER route %pBD(%s), dest %p",
376 dest, bgp->name_pretty, dest);
377 return 0;
378 }
379 }
380 return -1;
381 }
382
383 void bgp_path_info_add_with_caller(const char *name, struct bgp_dest *dest,
384 struct bgp_path_info *pi)
385 {
386 frrtrace(3, frr_bgp, bgp_path_info_add, dest, pi, name);
387 struct bgp_path_info *top;
388
389 top = bgp_dest_get_bgp_path_info(dest);
390
391 pi->next = top;
392 pi->prev = NULL;
393 if (top)
394 top->prev = pi;
395 bgp_dest_set_bgp_path_info(dest, pi);
396
397 bgp_path_info_lock(pi);
398 bgp_dest_lock_node(dest);
399 peer_lock(pi->peer); /* bgp_path_info peer reference */
400 bgp_dest_set_defer_flag(dest, false);
401 hook_call(bgp_snmp_update_stats, dest, pi, true);
402 }
403
404 /* Do the actual removal of info from RIB, for use by bgp_process
405 completion callback *only* */
406 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
407 {
408 if (pi->next)
409 pi->next->prev = pi->prev;
410 if (pi->prev)
411 pi->prev->next = pi->next;
412 else
413 bgp_dest_set_bgp_path_info(dest, pi->next);
414
415 bgp_path_info_mpath_dequeue(pi);
416 bgp_path_info_unlock(pi);
417 hook_call(bgp_snmp_update_stats, dest, pi, false);
418 bgp_dest_unlock_node(dest);
419 }
420
421 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
422 {
423 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
424 /* set of previous already took care of pcount */
425 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
426 }
427
428 /* undo the effects of a previous call to bgp_path_info_delete; typically
429 called when a route is deleted and then quickly re-added before the
430 deletion has been processed */
431 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
432 {
433 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
434 /* unset of previous already took care of pcount */
435 SET_FLAG(pi->flags, BGP_PATH_VALID);
436 }
437
438 /* Adjust pcount as required */
439 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
440 {
441 struct bgp_table *table;
442
443 assert(dest && bgp_dest_table(dest));
444 assert(pi && pi->peer && pi->peer->bgp);
445
446 table = bgp_dest_table(dest);
447
448 if (pi->peer == pi->peer->bgp->peer_self)
449 return;
450
451 if (!BGP_PATH_COUNTABLE(pi)
452 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
453
454 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
455
456 /* slight hack, but more robust against errors. */
457 if (pi->peer->pcount[table->afi][table->safi])
458 pi->peer->pcount[table->afi][table->safi]--;
459 else
460 flog_err(EC_LIB_DEVELOPMENT,
461 "Asked to decrement 0 prefix count for peer");
462 } else if (BGP_PATH_COUNTABLE(pi)
463 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
464 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
465 pi->peer->pcount[table->afi][table->safi]++;
466 }
467 }
468
469 static int bgp_label_index_differs(struct bgp_path_info *pi1,
470 struct bgp_path_info *pi2)
471 {
472 return (!(pi1->attr->label_index == pi2->attr->label_index));
473 }
474
475 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
476 * This is here primarily to keep prefix-count in check.
477 */
478 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
479 uint32_t flag)
480 {
481 SET_FLAG(pi->flags, flag);
482
483 /* early bath if we know it's not a flag that changes countability state
484 */
485 if (!CHECK_FLAG(flag,
486 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
487 return;
488
489 bgp_pcount_adjust(dest, pi);
490 }
491
492 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
493 uint32_t flag)
494 {
495 UNSET_FLAG(pi->flags, flag);
496
497 /* early bath if we know it's not a flag that changes countability state
498 */
499 if (!CHECK_FLAG(flag,
500 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
501 return;
502
503 bgp_pcount_adjust(dest, pi);
504 }
505
506 /* Get MED value. If MED value is missing and "bgp bestpath
507 missing-as-worst" is specified, treat it as the worst value. */
508 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
509 {
510 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
511 return attr->med;
512 else {
513 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
514 return BGP_MED_MAX;
515 else
516 return 0;
517 }
518 }
519
520 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
521 size_t buf_len)
522 {
523 struct peer *peer;
524
525 if (pi->sub_type == BGP_ROUTE_IMPORTED &&
526 bgp_get_imported_bpi_ultimate(pi))
527 peer = bgp_get_imported_bpi_ultimate(pi)->peer;
528 else
529 peer = pi->peer;
530
531 if (pi->addpath_rx_id)
532 snprintf(buf, buf_len, "path %s (addpath rxid %d)", peer->host,
533 pi->addpath_rx_id);
534 else
535 snprintf(buf, buf_len, "path %s", peer->host);
536 }
537
538
539 /*
540 * Get the ultimate path info.
541 */
542 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
543 {
544 struct bgp_path_info *bpi_ultimate;
545
546 if (info->sub_type != BGP_ROUTE_IMPORTED)
547 return info;
548
549 for (bpi_ultimate = info;
550 bpi_ultimate->extra && bpi_ultimate->extra->parent;
551 bpi_ultimate = bpi_ultimate->extra->parent)
552 ;
553
554 return bpi_ultimate;
555 }
556
557 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
558 */
559 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
560 struct bgp_path_info *exist, int *paths_eq,
561 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
562 char *pfx_buf, afi_t afi, safi_t safi,
563 enum bgp_path_selection_reason *reason)
564 {
565 const struct prefix *new_p;
566 struct attr *newattr, *existattr;
567 enum bgp_peer_sort new_sort;
568 enum bgp_peer_sort exist_sort;
569 uint32_t new_pref;
570 uint32_t exist_pref;
571 uint32_t new_med;
572 uint32_t exist_med;
573 uint32_t new_weight;
574 uint32_t exist_weight;
575 uint32_t newm, existm;
576 struct in_addr new_id;
577 struct in_addr exist_id;
578 int new_cluster;
579 int exist_cluster;
580 int internal_as_route;
581 int confed_as_route;
582 int ret = 0;
583 int igp_metric_ret = 0;
584 int peer_sort_ret = -1;
585 char new_buf[PATH_ADDPATH_STR_BUFFER];
586 char exist_buf[PATH_ADDPATH_STR_BUFFER];
587 uint32_t new_mm_seq;
588 uint32_t exist_mm_seq;
589 int nh_cmp;
590 esi_t *exist_esi;
591 esi_t *new_esi;
592 bool same_esi;
593 bool old_proxy;
594 bool new_proxy;
595 bool new_origin, exist_origin;
596 struct bgp_path_info *bpi_ultimate;
597 struct peer *peer_new, *peer_exist;
598
599 *paths_eq = 0;
600
601 /* 0. Null check. */
602 if (new == NULL) {
603 *reason = bgp_path_selection_none;
604 if (debug)
605 zlog_debug("%s: new is NULL", pfx_buf);
606 return 0;
607 }
608
609 if (debug) {
610 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
611 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, new_buf,
612 sizeof(new_buf));
613 }
614
615 if (exist == NULL) {
616 *reason = bgp_path_selection_first;
617 if (debug)
618 zlog_debug("%s(%s): %s is the initial bestpath",
619 pfx_buf, bgp->name_pretty, new_buf);
620 return 1;
621 }
622
623 if (debug) {
624 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
625 bgp_path_info_path_with_addpath_rx_str(bpi_ultimate, exist_buf,
626 sizeof(exist_buf));
627 zlog_debug("%s(%s): Comparing %s flags 0x%x with %s flags 0x%x",
628 pfx_buf, bgp->name_pretty, new_buf, new->flags,
629 exist_buf, exist->flags);
630 }
631
632 newattr = new->attr;
633 existattr = exist->attr;
634
635 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
636 * Capability" to a neighbor MUST perform the following upon receiving
637 * a route from that neighbor with the "LLGR_STALE" community, or upon
638 * attaching the "LLGR_STALE" community itself per Section 4.2:
639 *
640 * Treat the route as the least-preferred in route selection (see
641 * below). See the Risks of Depreferencing Routes section (Section 5.2)
642 * for a discussion of potential risks inherent in doing this.
643 */
644 if (bgp_attr_get_community(newattr) &&
645 community_include(bgp_attr_get_community(newattr),
646 COMMUNITY_LLGR_STALE)) {
647 if (debug)
648 zlog_debug(
649 "%s: %s wins over %s due to LLGR_STALE community",
650 pfx_buf, new_buf, exist_buf);
651 return 0;
652 }
653
654 if (bgp_attr_get_community(existattr) &&
655 community_include(bgp_attr_get_community(existattr),
656 COMMUNITY_LLGR_STALE)) {
657 if (debug)
658 zlog_debug(
659 "%s: %s loses to %s due to LLGR_STALE community",
660 pfx_buf, new_buf, exist_buf);
661 return 1;
662 }
663
664 new_p = bgp_dest_get_prefix(new->net);
665
666 /* For EVPN routes, we cannot just go by local vs remote, we have to
667 * look at the MAC mobility sequence number, if present.
668 */
669 if ((safi == SAFI_EVPN)
670 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
671 /* This is an error condition described in RFC 7432 Section
672 * 15.2. The RFC
673 * states that in this scenario "the PE MUST alert the operator"
674 * but it
675 * does not state what other action to take. In order to provide
676 * some
677 * consistency in this scenario we are going to prefer the path
678 * with the
679 * sticky flag.
680 */
681 if (newattr->sticky != existattr->sticky) {
682 if (!debug) {
683 prefix2str(new_p, pfx_buf,
684 sizeof(*pfx_buf)
685 * PREFIX2STR_BUFFER);
686 bgp_path_info_path_with_addpath_rx_str(
687 new, new_buf, sizeof(new_buf));
688 bgp_path_info_path_with_addpath_rx_str(
689 exist, exist_buf, sizeof(exist_buf));
690 }
691
692 if (newattr->sticky && !existattr->sticky) {
693 *reason = bgp_path_selection_evpn_sticky_mac;
694 if (debug)
695 zlog_debug(
696 "%s: %s wins over %s due to sticky MAC flag",
697 pfx_buf, new_buf, exist_buf);
698 return 1;
699 }
700
701 if (!newattr->sticky && existattr->sticky) {
702 *reason = bgp_path_selection_evpn_sticky_mac;
703 if (debug)
704 zlog_debug(
705 "%s: %s loses to %s due to sticky MAC flag",
706 pfx_buf, new_buf, exist_buf);
707 return 0;
708 }
709 }
710
711 new_esi = bgp_evpn_attr_get_esi(newattr);
712 exist_esi = bgp_evpn_attr_get_esi(existattr);
713 if (bgp_evpn_is_esi_valid(new_esi) &&
714 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
715 same_esi = true;
716 } else {
717 same_esi = false;
718 }
719
720 /* If both paths have the same non-zero ES and
721 * one path is local it wins.
722 * PS: Note the local path wins even if the remote
723 * has the higher MM seq. The local path's
724 * MM seq will be fixed up to match the highest
725 * rem seq, subsequently.
726 */
727 if (same_esi) {
728 char esi_buf[ESI_STR_LEN];
729
730 if (bgp_evpn_is_path_local(bgp, new)) {
731 *reason = bgp_path_selection_evpn_local_path;
732 if (debug)
733 zlog_debug(
734 "%s: %s wins over %s as ES %s is same and local",
735 pfx_buf, new_buf, exist_buf,
736 esi_to_str(new_esi, esi_buf,
737 sizeof(esi_buf)));
738 return 1;
739 }
740 if (bgp_evpn_is_path_local(bgp, exist)) {
741 *reason = bgp_path_selection_evpn_local_path;
742 if (debug)
743 zlog_debug(
744 "%s: %s loses to %s as ES %s is same and local",
745 pfx_buf, new_buf, exist_buf,
746 esi_to_str(new_esi, esi_buf,
747 sizeof(esi_buf)));
748 return 0;
749 }
750 }
751
752 new_mm_seq = mac_mobility_seqnum(newattr);
753 exist_mm_seq = mac_mobility_seqnum(existattr);
754
755 if (new_mm_seq > exist_mm_seq) {
756 *reason = bgp_path_selection_evpn_seq;
757 if (debug)
758 zlog_debug(
759 "%s: %s wins over %s due to MM seq %u > %u",
760 pfx_buf, new_buf, exist_buf, new_mm_seq,
761 exist_mm_seq);
762 return 1;
763 }
764
765 if (new_mm_seq < exist_mm_seq) {
766 *reason = bgp_path_selection_evpn_seq;
767 if (debug)
768 zlog_debug(
769 "%s: %s loses to %s due to MM seq %u < %u",
770 pfx_buf, new_buf, exist_buf, new_mm_seq,
771 exist_mm_seq);
772 return 0;
773 }
774
775 /* if the sequence numbers and ESI are the same and one path
776 * is non-proxy it wins (over proxy)
777 */
778 new_proxy = bgp_evpn_attr_is_proxy(newattr);
779 old_proxy = bgp_evpn_attr_is_proxy(existattr);
780 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
781 old_proxy != new_proxy) {
782 if (!new_proxy) {
783 *reason = bgp_path_selection_evpn_non_proxy;
784 if (debug)
785 zlog_debug(
786 "%s: %s wins over %s, same seq/es and non-proxy",
787 pfx_buf, new_buf, exist_buf);
788 return 1;
789 }
790
791 *reason = bgp_path_selection_evpn_non_proxy;
792 if (debug)
793 zlog_debug(
794 "%s: %s loses to %s, same seq/es and non-proxy",
795 pfx_buf, new_buf, exist_buf);
796 return 0;
797 }
798
799 /*
800 * if sequence numbers are the same path with the lowest IP
801 * wins
802 */
803 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
804 if (nh_cmp < 0) {
805 *reason = bgp_path_selection_evpn_lower_ip;
806 if (debug)
807 zlog_debug(
808 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
809 pfx_buf, new_buf, exist_buf, new_mm_seq,
810 &new->attr->nexthop);
811 return 1;
812 }
813 if (nh_cmp > 0) {
814 *reason = bgp_path_selection_evpn_lower_ip;
815 if (debug)
816 zlog_debug(
817 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
818 pfx_buf, new_buf, exist_buf, new_mm_seq,
819 &new->attr->nexthop);
820 return 0;
821 }
822 }
823
824 /* 1. Weight check. */
825 new_weight = newattr->weight;
826 exist_weight = existattr->weight;
827
828 if (new_weight > exist_weight) {
829 *reason = bgp_path_selection_weight;
830 if (debug)
831 zlog_debug("%s: %s wins over %s due to weight %d > %d",
832 pfx_buf, new_buf, exist_buf, new_weight,
833 exist_weight);
834 return 1;
835 }
836
837 if (new_weight < exist_weight) {
838 *reason = bgp_path_selection_weight;
839 if (debug)
840 zlog_debug("%s: %s loses to %s due to weight %d < %d",
841 pfx_buf, new_buf, exist_buf, new_weight,
842 exist_weight);
843 return 0;
844 }
845
846 /* 2. Local preference check. */
847 new_pref = exist_pref = bgp->default_local_pref;
848
849 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
850 new_pref = newattr->local_pref;
851 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
852 exist_pref = existattr->local_pref;
853
854 if (new_pref > exist_pref) {
855 *reason = bgp_path_selection_local_pref;
856 if (debug)
857 zlog_debug(
858 "%s: %s wins over %s due to localpref %d > %d",
859 pfx_buf, new_buf, exist_buf, new_pref,
860 exist_pref);
861 return 1;
862 }
863
864 if (new_pref < exist_pref) {
865 *reason = bgp_path_selection_local_pref;
866 if (debug)
867 zlog_debug(
868 "%s: %s loses to %s due to localpref %d < %d",
869 pfx_buf, new_buf, exist_buf, new_pref,
870 exist_pref);
871 return 0;
872 }
873
874 /* If a BGP speaker supports ACCEPT_OWN and is configured for the
875 * extensions defined in this document, the following step is inserted
876 * after the LOCAL_PREF comparison step in the BGP decision process:
877 * When comparing a pair of routes for a BGP destination, the
878 * route with the ACCEPT_OWN community attached is preferred over
879 * the route that does not have the community.
880 * This extra step MUST only be invoked during the best path selection
881 * process of VPN-IP routes.
882 */
883 if (safi == SAFI_MPLS_VPN &&
884 (CHECK_FLAG(new->peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN) ||
885 CHECK_FLAG(exist->peer->af_flags[afi][safi],
886 PEER_FLAG_ACCEPT_OWN))) {
887 bool new_accept_own = false;
888 bool exist_accept_own = false;
889 uint32_t accept_own = COMMUNITY_ACCEPT_OWN;
890
891 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
892 new_accept_own = community_include(
893 bgp_attr_get_community(newattr), accept_own);
894 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))
895 exist_accept_own = community_include(
896 bgp_attr_get_community(existattr), accept_own);
897
898 if (new_accept_own && !exist_accept_own) {
899 *reason = bgp_path_selection_accept_own;
900 if (debug)
901 zlog_debug(
902 "%s: %s wins over %s due to accept-own",
903 pfx_buf, new_buf, exist_buf);
904 return 1;
905 }
906
907 if (!new_accept_own && exist_accept_own) {
908 *reason = bgp_path_selection_accept_own;
909 if (debug)
910 zlog_debug(
911 "%s: %s loses to %s due to accept-own",
912 pfx_buf, new_buf, exist_buf);
913 return 0;
914 }
915 }
916
917 /* Tie-breaker - AIGP (Metric TLV) attribute */
918 if (CHECK_FLAG(newattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
919 CHECK_FLAG(existattr->flag, ATTR_FLAG_BIT(BGP_ATTR_AIGP)) &&
920 CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP)) {
921 uint64_t new_aigp = bgp_attr_get_aigp_metric(newattr);
922 uint64_t exist_aigp = bgp_attr_get_aigp_metric(existattr);
923
924 if (new_aigp < exist_aigp) {
925 *reason = bgp_path_selection_aigp;
926 if (debug)
927 zlog_debug(
928 "%s: %s wins over %s due to AIGP %" PRIu64
929 " < %" PRIu64,
930 pfx_buf, new_buf, exist_buf, new_aigp,
931 exist_aigp);
932 return 1;
933 }
934
935 if (new_aigp > exist_aigp) {
936 *reason = bgp_path_selection_aigp;
937 if (debug)
938 zlog_debug(
939 "%s: %s loses to %s due to AIGP %" PRIu64
940 " > %" PRIu64,
941 pfx_buf, new_buf, exist_buf, new_aigp,
942 exist_aigp);
943 return 0;
944 }
945 }
946
947 /* 3. Local route check. We prefer:
948 * - BGP_ROUTE_STATIC
949 * - BGP_ROUTE_AGGREGATE
950 * - BGP_ROUTE_REDISTRIBUTE
951 */
952 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
953 new->sub_type == BGP_ROUTE_IMPORTED);
954 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
955 exist->sub_type == BGP_ROUTE_IMPORTED);
956
957 if (new_origin && !exist_origin) {
958 *reason = bgp_path_selection_local_route;
959 if (debug)
960 zlog_debug(
961 "%s: %s wins over %s due to preferred BGP_ROUTE type",
962 pfx_buf, new_buf, exist_buf);
963 return 1;
964 }
965
966 if (!new_origin && exist_origin) {
967 *reason = bgp_path_selection_local_route;
968 if (debug)
969 zlog_debug(
970 "%s: %s loses to %s due to preferred BGP_ROUTE type",
971 pfx_buf, new_buf, exist_buf);
972 return 0;
973 }
974
975 /* Here if these are imported routes then get ultimate pi for
976 * path compare.
977 */
978 new = bgp_get_imported_bpi_ultimate(new);
979 exist = bgp_get_imported_bpi_ultimate(exist);
980 newattr = new->attr;
981 existattr = exist->attr;
982
983 /* 4. AS path length check. */
984 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
985 int exist_hops = aspath_count_hops(existattr->aspath);
986 int exist_confeds = aspath_count_confeds(existattr->aspath);
987
988 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
989 int aspath_hops;
990
991 aspath_hops = aspath_count_hops(newattr->aspath);
992 aspath_hops += aspath_count_confeds(newattr->aspath);
993
994 if (aspath_hops < (exist_hops + exist_confeds)) {
995 *reason = bgp_path_selection_confed_as_path;
996 if (debug)
997 zlog_debug(
998 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
999 pfx_buf, new_buf, exist_buf,
1000 aspath_hops,
1001 (exist_hops + exist_confeds));
1002 return 1;
1003 }
1004
1005 if (aspath_hops > (exist_hops + exist_confeds)) {
1006 *reason = bgp_path_selection_confed_as_path;
1007 if (debug)
1008 zlog_debug(
1009 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
1010 pfx_buf, new_buf, exist_buf,
1011 aspath_hops,
1012 (exist_hops + exist_confeds));
1013 return 0;
1014 }
1015 } else {
1016 int newhops = aspath_count_hops(newattr->aspath);
1017
1018 if (newhops < exist_hops) {
1019 *reason = bgp_path_selection_as_path;
1020 if (debug)
1021 zlog_debug(
1022 "%s: %s wins over %s due to aspath hopcount %d < %d",
1023 pfx_buf, new_buf, exist_buf,
1024 newhops, exist_hops);
1025 return 1;
1026 }
1027
1028 if (newhops > exist_hops) {
1029 *reason = bgp_path_selection_as_path;
1030 if (debug)
1031 zlog_debug(
1032 "%s: %s loses to %s due to aspath hopcount %d > %d",
1033 pfx_buf, new_buf, exist_buf,
1034 newhops, exist_hops);
1035 return 0;
1036 }
1037 }
1038 }
1039
1040 /* 5. Origin check. */
1041 if (newattr->origin < existattr->origin) {
1042 *reason = bgp_path_selection_origin;
1043 if (debug)
1044 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
1045 pfx_buf, new_buf, exist_buf,
1046 bgp_origin_long_str[newattr->origin],
1047 bgp_origin_long_str[existattr->origin]);
1048 return 1;
1049 }
1050
1051 if (newattr->origin > existattr->origin) {
1052 *reason = bgp_path_selection_origin;
1053 if (debug)
1054 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
1055 pfx_buf, new_buf, exist_buf,
1056 bgp_origin_long_str[newattr->origin],
1057 bgp_origin_long_str[existattr->origin]);
1058 return 0;
1059 }
1060
1061 /* 6. MED check. */
1062 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
1063 && aspath_count_hops(existattr->aspath) == 0);
1064 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
1065 && aspath_count_confeds(existattr->aspath) > 0
1066 && aspath_count_hops(newattr->aspath) == 0
1067 && aspath_count_hops(existattr->aspath) == 0);
1068
1069 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
1070 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
1071 || aspath_cmp_left(newattr->aspath, existattr->aspath)
1072 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1073 || internal_as_route) {
1074 new_med = bgp_med_value(new->attr, bgp);
1075 exist_med = bgp_med_value(exist->attr, bgp);
1076
1077 if (new_med < exist_med) {
1078 *reason = bgp_path_selection_med;
1079 if (debug)
1080 zlog_debug(
1081 "%s: %s wins over %s due to MED %d < %d",
1082 pfx_buf, new_buf, exist_buf, new_med,
1083 exist_med);
1084 return 1;
1085 }
1086
1087 if (new_med > exist_med) {
1088 *reason = bgp_path_selection_med;
1089 if (debug)
1090 zlog_debug(
1091 "%s: %s loses to %s due to MED %d > %d",
1092 pfx_buf, new_buf, exist_buf, new_med,
1093 exist_med);
1094 return 0;
1095 }
1096 }
1097
1098 if (exist->sub_type == BGP_ROUTE_IMPORTED) {
1099 bpi_ultimate = bgp_get_imported_bpi_ultimate(exist);
1100 peer_exist = bpi_ultimate->peer;
1101 } else
1102 peer_exist = exist->peer;
1103
1104 if (new->sub_type == BGP_ROUTE_IMPORTED) {
1105 bpi_ultimate = bgp_get_imported_bpi_ultimate(new);
1106 peer_new = bpi_ultimate->peer;
1107 } else
1108 peer_new = new->peer;
1109
1110 /* 7. Peer type check. */
1111 new_sort = peer_new->sort;
1112 exist_sort = peer_exist->sort;
1113
1114 if (new_sort == BGP_PEER_EBGP
1115 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1116 *reason = bgp_path_selection_peer;
1117 if (debug)
1118 zlog_debug(
1119 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1120 pfx_buf, new_buf, exist_buf);
1121 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_EBGP
1127 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1128 *reason = bgp_path_selection_peer;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1134 return 0;
1135 peer_sort_ret = 0;
1136 }
1137
1138 /* 8. IGP metric check. */
1139 newm = existm = 0;
1140
1141 if (new->extra)
1142 newm = new->extra->igpmetric;
1143 if (exist->extra)
1144 existm = exist->extra->igpmetric;
1145
1146 if (newm < existm) {
1147 if (debug && peer_sort_ret < 0)
1148 zlog_debug(
1149 "%s: %s wins over %s due to IGP metric %u < %u",
1150 pfx_buf, new_buf, exist_buf, newm, existm);
1151 igp_metric_ret = 1;
1152 }
1153
1154 if (newm > existm) {
1155 if (debug && peer_sort_ret < 0)
1156 zlog_debug(
1157 "%s: %s loses to %s due to IGP metric %u > %u",
1158 pfx_buf, new_buf, exist_buf, newm, existm);
1159 igp_metric_ret = 0;
1160 }
1161
1162 /* 9. Same IGP metric. Compare the cluster list length as
1163 representative of IGP hops metric. Rewrite the metric value
1164 pair (newm, existm) with the cluster list length. Prefer the
1165 path with smaller cluster list length. */
1166 if (newm == existm) {
1167 if (peer_sort_lookup(peer_new) == BGP_PEER_IBGP &&
1168 peer_sort_lookup(peer_exist) == BGP_PEER_IBGP &&
1169 (mpath_cfg == NULL || mpath_cfg->same_clusterlen)) {
1170 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1171 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1172
1173 if (newm < existm) {
1174 if (debug && peer_sort_ret < 0)
1175 zlog_debug(
1176 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1177 pfx_buf, new_buf, exist_buf,
1178 newm, existm);
1179 igp_metric_ret = 1;
1180 }
1181
1182 if (newm > existm) {
1183 if (debug && peer_sort_ret < 0)
1184 zlog_debug(
1185 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1186 pfx_buf, new_buf, exist_buf,
1187 newm, existm);
1188 igp_metric_ret = 0;
1189 }
1190 }
1191 }
1192
1193 /* 10. confed-external vs. confed-internal */
1194 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1195 if (new_sort == BGP_PEER_CONFED
1196 && exist_sort == BGP_PEER_IBGP) {
1197 *reason = bgp_path_selection_confed;
1198 if (debug)
1199 zlog_debug(
1200 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1201 pfx_buf, new_buf, exist_buf);
1202 if (!CHECK_FLAG(bgp->flags,
1203 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1204 return 1;
1205 peer_sort_ret = 1;
1206 }
1207
1208 if (exist_sort == BGP_PEER_CONFED
1209 && new_sort == BGP_PEER_IBGP) {
1210 *reason = bgp_path_selection_confed;
1211 if (debug)
1212 zlog_debug(
1213 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1214 pfx_buf, new_buf, exist_buf);
1215 if (!CHECK_FLAG(bgp->flags,
1216 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1217 return 0;
1218 peer_sort_ret = 0;
1219 }
1220 }
1221
1222 /* 11. Maximum path check. */
1223 if (newm == existm) {
1224 /* If one path has a label but the other does not, do not treat
1225 * them as equals for multipath
1226 */
1227 int newl, existl;
1228
1229 newl = existl = 0;
1230
1231 if (new->extra)
1232 newl = new->extra->num_labels;
1233 if (exist->extra)
1234 existl = exist->extra->num_labels;
1235 if (((new->extra &&bgp_is_valid_label(&new->extra->label[0])) !=
1236 (exist->extra &&
1237 bgp_is_valid_label(&exist->extra->label[0]))) ||
1238 (newl != existl)) {
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1242 pfx_buf, new_buf, exist_buf);
1243 } else if (CHECK_FLAG(bgp->flags,
1244 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1245
1246 /*
1247 * For the two paths, all comparison steps till IGP
1248 * metric
1249 * have succeeded - including AS_PATH hop count. Since
1250 * 'bgp
1251 * bestpath as-path multipath-relax' knob is on, we
1252 * don't need
1253 * an exact match of AS_PATH. Thus, mark the paths are
1254 * equal.
1255 * That will trigger both these paths to get into the
1256 * multipath
1257 * array.
1258 */
1259 *paths_eq = 1;
1260
1261 if (debug)
1262 zlog_debug(
1263 "%s: %s and %s are equal via multipath-relax",
1264 pfx_buf, new_buf, exist_buf);
1265 } else if (peer_new->sort == BGP_PEER_IBGP) {
1266 if (aspath_cmp(new->attr->aspath,
1267 exist->attr->aspath)) {
1268 *paths_eq = 1;
1269
1270 if (debug)
1271 zlog_debug(
1272 "%s: %s and %s are equal via matching aspaths",
1273 pfx_buf, new_buf, exist_buf);
1274 }
1275 } else if (peer_new->as == peer_exist->as) {
1276 *paths_eq = 1;
1277
1278 if (debug)
1279 zlog_debug(
1280 "%s: %s and %s are equal via same remote-as",
1281 pfx_buf, new_buf, exist_buf);
1282 }
1283 } else {
1284 /*
1285 * TODO: If unequal cost ibgp multipath is enabled we can
1286 * mark the paths as equal here instead of returning
1287 */
1288
1289 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1290 * if either step 7 or 10 (peer type checks) yielded a winner,
1291 * that result was returned immediately. Returning from step 10
1292 * ignored the return value computed in steps 8 and 9 (IGP
1293 * metric checks). In order to preserve that behavior, if
1294 * peer_sort_ret is set, return that rather than igp_metric_ret.
1295 */
1296 ret = peer_sort_ret;
1297 if (peer_sort_ret < 0) {
1298 ret = igp_metric_ret;
1299 if (debug) {
1300 if (ret == 1)
1301 zlog_debug(
1302 "%s: %s wins over %s after IGP metric comparison",
1303 pfx_buf, new_buf, exist_buf);
1304 else
1305 zlog_debug(
1306 "%s: %s loses to %s after IGP metric comparison",
1307 pfx_buf, new_buf, exist_buf);
1308 }
1309 *reason = bgp_path_selection_igp_metric;
1310 }
1311 return ret;
1312 }
1313
1314 /*
1315 * At this point, the decision whether to set *paths_eq = 1 has been
1316 * completed. If we deferred returning because of bestpath peer-type
1317 * relax configuration, return now.
1318 */
1319 if (peer_sort_ret >= 0)
1320 return peer_sort_ret;
1321
1322 /* 12. If both paths are external, prefer the path that was received
1323 first (the oldest one). This step minimizes route-flap, since a
1324 newer path won't displace an older one, even if it was the
1325 preferred route based on the additional decision criteria below. */
1326 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1327 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1328 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1329 *reason = bgp_path_selection_older;
1330 if (debug)
1331 zlog_debug(
1332 "%s: %s wins over %s due to oldest external",
1333 pfx_buf, new_buf, exist_buf);
1334 return 1;
1335 }
1336
1337 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1338 *reason = bgp_path_selection_older;
1339 if (debug)
1340 zlog_debug(
1341 "%s: %s loses to %s due to oldest external",
1342 pfx_buf, new_buf, exist_buf);
1343 return 0;
1344 }
1345 }
1346
1347 /* 13. Router-ID comparison. */
1348 /* If one of the paths is "stale", the corresponding peer router-id will
1349 * be 0 and would always win over the other path. If originator id is
1350 * used for the comparison, it will decide which path is better.
1351 */
1352 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1353 new_id.s_addr = newattr->originator_id.s_addr;
1354 else
1355 new_id.s_addr = peer_new->remote_id.s_addr;
1356 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1357 exist_id.s_addr = existattr->originator_id.s_addr;
1358 else
1359 exist_id.s_addr = peer_exist->remote_id.s_addr;
1360
1361 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1362 *reason = bgp_path_selection_router_id;
1363 if (debug)
1364 zlog_debug(
1365 "%s: %s wins over %s due to Router-ID comparison",
1366 pfx_buf, new_buf, exist_buf);
1367 return 1;
1368 }
1369
1370 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1371 *reason = bgp_path_selection_router_id;
1372 if (debug)
1373 zlog_debug(
1374 "%s: %s loses to %s due to Router-ID comparison",
1375 pfx_buf, new_buf, exist_buf);
1376 return 0;
1377 }
1378
1379 /* 14. Cluster length comparison. */
1380 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1381 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1382
1383 if (new_cluster < exist_cluster) {
1384 *reason = bgp_path_selection_cluster_length;
1385 if (debug)
1386 zlog_debug(
1387 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1388 pfx_buf, new_buf, exist_buf, new_cluster,
1389 exist_cluster);
1390 return 1;
1391 }
1392
1393 if (new_cluster > exist_cluster) {
1394 *reason = bgp_path_selection_cluster_length;
1395 if (debug)
1396 zlog_debug(
1397 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1398 pfx_buf, new_buf, exist_buf, new_cluster,
1399 exist_cluster);
1400 return 0;
1401 }
1402
1403 /* 15. Neighbor address comparison. */
1404 /* Do this only if neither path is "stale" as stale paths do not have
1405 * valid peer information (as the connection may or may not be up).
1406 */
1407 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1408 *reason = bgp_path_selection_stale;
1409 if (debug)
1410 zlog_debug(
1411 "%s: %s wins over %s due to latter path being STALE",
1412 pfx_buf, new_buf, exist_buf);
1413 return 1;
1414 }
1415
1416 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1417 *reason = bgp_path_selection_stale;
1418 if (debug)
1419 zlog_debug(
1420 "%s: %s loses to %s due to former path being STALE",
1421 pfx_buf, new_buf, exist_buf);
1422 return 0;
1423 }
1424
1425 /* locally configured routes to advertise do not have su_remote */
1426 if (peer_new->su_remote == NULL) {
1427 *reason = bgp_path_selection_local_configured;
1428 return 0;
1429 }
1430
1431 if (peer_exist->su_remote == NULL) {
1432 *reason = bgp_path_selection_local_configured;
1433 return 1;
1434 }
1435
1436 ret = sockunion_cmp(peer_new->su_remote, peer_exist->su_remote);
1437
1438 if (ret == 1) {
1439 *reason = bgp_path_selection_neighbor_ip;
1440 if (debug)
1441 zlog_debug(
1442 "%s: %s loses to %s due to Neighor IP comparison",
1443 pfx_buf, new_buf, exist_buf);
1444 return 0;
1445 }
1446
1447 if (ret == -1) {
1448 *reason = bgp_path_selection_neighbor_ip;
1449 if (debug)
1450 zlog_debug(
1451 "%s: %s wins over %s due to Neighor IP comparison",
1452 pfx_buf, new_buf, exist_buf);
1453 return 1;
1454 }
1455
1456 *reason = bgp_path_selection_default;
1457 if (debug)
1458 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1459 pfx_buf, new_buf, exist_buf);
1460
1461 return 1;
1462 }
1463
1464
1465 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1466 struct bgp_path_info *exist, int *paths_eq)
1467 {
1468 enum bgp_path_selection_reason reason;
1469 char pfx_buf[PREFIX2STR_BUFFER];
1470
1471 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1472 AFI_L2VPN, SAFI_EVPN, &reason);
1473 }
1474
1475 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1476 * is preferred, or 0 if they are the same (usually will only occur if
1477 * multipath is enabled
1478 * This version is compatible with */
1479 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1480 struct bgp_path_info *exist, char *pfx_buf,
1481 afi_t afi, safi_t safi,
1482 enum bgp_path_selection_reason *reason)
1483 {
1484 int paths_eq;
1485 int ret;
1486 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1487 afi, safi, reason);
1488
1489 if (paths_eq)
1490 ret = 0;
1491 else {
1492 if (ret == 1)
1493 ret = -1;
1494 else
1495 ret = 1;
1496 }
1497 return ret;
1498 }
1499
1500 static enum filter_type bgp_input_filter(struct peer *peer,
1501 const struct prefix *p,
1502 struct attr *attr, afi_t afi,
1503 safi_t safi)
1504 {
1505 struct bgp_filter *filter;
1506 enum filter_type ret = FILTER_PERMIT;
1507
1508 filter = &peer->filter[afi][safi];
1509
1510 #define FILTER_EXIST_WARN(F, f, filter) \
1511 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1512 zlog_debug("%s: Could not find configured input %s-list %s!", \
1513 peer->host, #f, F##_IN_NAME(filter));
1514
1515 if (DISTRIBUTE_IN_NAME(filter)) {
1516 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1517
1518 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1519 == FILTER_DENY) {
1520 ret = FILTER_DENY;
1521 goto done;
1522 }
1523 }
1524
1525 if (PREFIX_LIST_IN_NAME(filter)) {
1526 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1527
1528 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1529 == PREFIX_DENY) {
1530 ret = FILTER_DENY;
1531 goto done;
1532 }
1533 }
1534
1535 if (FILTER_LIST_IN_NAME(filter)) {
1536 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1537
1538 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1539 == AS_FILTER_DENY) {
1540 ret = FILTER_DENY;
1541 goto done;
1542 }
1543 }
1544
1545 done:
1546 if (frrtrace_enabled(frr_bgp, input_filter)) {
1547 char pfxprint[PREFIX2STR_BUFFER];
1548
1549 prefix2str(p, pfxprint, sizeof(pfxprint));
1550 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1551 ret == FILTER_PERMIT ? "permit" : "deny");
1552 }
1553
1554 return ret;
1555 #undef FILTER_EXIST_WARN
1556 }
1557
1558 static enum filter_type bgp_output_filter(struct peer *peer,
1559 const struct prefix *p,
1560 struct attr *attr, afi_t afi,
1561 safi_t safi)
1562 {
1563 struct bgp_filter *filter;
1564 enum filter_type ret = FILTER_PERMIT;
1565
1566 filter = &peer->filter[afi][safi];
1567
1568 #define FILTER_EXIST_WARN(F, f, filter) \
1569 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1570 zlog_debug("%s: Could not find configured output %s-list %s!", \
1571 peer->host, #f, F##_OUT_NAME(filter));
1572
1573 if (DISTRIBUTE_OUT_NAME(filter)) {
1574 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1575
1576 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1577 == FILTER_DENY) {
1578 ret = FILTER_DENY;
1579 goto done;
1580 }
1581 }
1582
1583 if (PREFIX_LIST_OUT_NAME(filter)) {
1584 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1585
1586 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1587 == PREFIX_DENY) {
1588 ret = FILTER_DENY;
1589 goto done;
1590 }
1591 }
1592
1593 if (FILTER_LIST_OUT_NAME(filter)) {
1594 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1595
1596 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1597 == AS_FILTER_DENY) {
1598 ret = FILTER_DENY;
1599 goto done;
1600 }
1601 }
1602
1603 if (frrtrace_enabled(frr_bgp, output_filter)) {
1604 char pfxprint[PREFIX2STR_BUFFER];
1605
1606 prefix2str(p, pfxprint, sizeof(pfxprint));
1607 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1608 ret == FILTER_PERMIT ? "permit" : "deny");
1609 }
1610
1611 done:
1612 return ret;
1613 #undef FILTER_EXIST_WARN
1614 }
1615
1616 /* If community attribute includes no_export then return 1. */
1617 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1618 {
1619 if (bgp_attr_get_community(attr)) {
1620 /* NO_ADVERTISE check. */
1621 if (community_include(bgp_attr_get_community(attr),
1622 COMMUNITY_NO_ADVERTISE))
1623 return true;
1624
1625 /* NO_EXPORT check. */
1626 if (peer->sort == BGP_PEER_EBGP &&
1627 community_include(bgp_attr_get_community(attr),
1628 COMMUNITY_NO_EXPORT))
1629 return true;
1630
1631 /* NO_EXPORT_SUBCONFED check. */
1632 if (peer->sort == BGP_PEER_EBGP
1633 || peer->sort == BGP_PEER_CONFED)
1634 if (community_include(bgp_attr_get_community(attr),
1635 COMMUNITY_NO_EXPORT_SUBCONFED))
1636 return true;
1637 }
1638 return false;
1639 }
1640
1641 /* Route reflection loop check. */
1642 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1643 {
1644 struct in_addr cluster_id;
1645 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1646
1647 if (cluster) {
1648 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1649 cluster_id = peer->bgp->cluster_id;
1650 else
1651 cluster_id = peer->bgp->router_id;
1652
1653 if (cluster_loop_check(cluster, cluster_id))
1654 return true;
1655 }
1656 return false;
1657 }
1658
1659 static bool bgp_otc_filter(struct peer *peer, struct attr *attr)
1660 {
1661 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1662 if (peer->local_role == ROLE_PROVIDER ||
1663 peer->local_role == ROLE_RS_SERVER)
1664 return true;
1665 if (peer->local_role == ROLE_PEER && attr->otc != peer->as)
1666 return true;
1667 return false;
1668 }
1669 if (peer->local_role == ROLE_CUSTOMER ||
1670 peer->local_role == ROLE_PEER ||
1671 peer->local_role == ROLE_RS_CLIENT) {
1672 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1673 attr->otc = peer->as;
1674 }
1675 return false;
1676 }
1677
1678 static bool bgp_otc_egress(struct peer *peer, struct attr *attr)
1679 {
1680 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
1681 if (peer->local_role == ROLE_CUSTOMER ||
1682 peer->local_role == ROLE_RS_CLIENT ||
1683 peer->local_role == ROLE_PEER)
1684 return true;
1685 return false;
1686 }
1687 if (peer->local_role == ROLE_PROVIDER ||
1688 peer->local_role == ROLE_PEER ||
1689 peer->local_role == ROLE_RS_SERVER) {
1690 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_OTC);
1691 attr->otc = peer->bgp->as;
1692 }
1693 return false;
1694 }
1695
1696 static bool bgp_check_role_applicability(afi_t afi, safi_t safi)
1697 {
1698 return ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST);
1699 }
1700
1701 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1702 struct attr *attr, afi_t afi, safi_t safi,
1703 const char *rmap_name, mpls_label_t *label,
1704 uint32_t num_labels, struct bgp_dest *dest)
1705 {
1706 struct bgp_filter *filter;
1707 struct bgp_path_info rmap_path = { 0 };
1708 struct bgp_path_info_extra extra = { 0 };
1709 route_map_result_t ret;
1710 struct route_map *rmap = NULL;
1711
1712 filter = &peer->filter[afi][safi];
1713
1714 /* Apply default weight value. */
1715 if (peer->weight[afi][safi])
1716 attr->weight = peer->weight[afi][safi];
1717
1718 if (rmap_name) {
1719 rmap = route_map_lookup_by_name(rmap_name);
1720
1721 if (rmap == NULL)
1722 return RMAP_DENY;
1723 } else {
1724 if (ROUTE_MAP_IN_NAME(filter)) {
1725 rmap = ROUTE_MAP_IN(filter);
1726
1727 if (rmap == NULL)
1728 return RMAP_DENY;
1729 }
1730 }
1731
1732 /* Route map apply. */
1733 if (rmap) {
1734 memset(&rmap_path, 0, sizeof(rmap_path));
1735 /* Duplicate current value to new structure for modification. */
1736 rmap_path.peer = peer;
1737 rmap_path.attr = attr;
1738 rmap_path.extra = &extra;
1739 rmap_path.net = dest;
1740
1741 extra.num_labels = num_labels;
1742 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1743 memcpy(extra.label, label,
1744 num_labels * sizeof(mpls_label_t));
1745
1746 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1747
1748 /* Apply BGP route map to the attribute. */
1749 ret = route_map_apply(rmap, p, &rmap_path);
1750
1751 peer->rmap_type = 0;
1752
1753 if (ret == RMAP_DENYMATCH)
1754 return RMAP_DENY;
1755 }
1756 return RMAP_PERMIT;
1757 }
1758
1759 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1760 struct attr *attr, afi_t afi, safi_t safi,
1761 const char *rmap_name)
1762 {
1763 struct bgp_path_info rmap_path;
1764 route_map_result_t ret;
1765 struct route_map *rmap = NULL;
1766 uint8_t rmap_type;
1767
1768 /*
1769 * So if we get to this point and have no rmap_name
1770 * we want to just show the output as it currently
1771 * exists.
1772 */
1773 if (!rmap_name)
1774 return RMAP_PERMIT;
1775
1776 /* Apply default weight value. */
1777 if (peer->weight[afi][safi])
1778 attr->weight = peer->weight[afi][safi];
1779
1780 rmap = route_map_lookup_by_name(rmap_name);
1781
1782 /*
1783 * If we have a route map name and we do not find
1784 * the routemap that means we have an implicit
1785 * deny.
1786 */
1787 if (rmap == NULL)
1788 return RMAP_DENY;
1789
1790 memset(&rmap_path, 0, sizeof(rmap_path));
1791 /* Route map apply. */
1792 /* Duplicate current value to new structure for modification. */
1793 rmap_path.peer = peer;
1794 rmap_path.attr = attr;
1795
1796 rmap_type = peer->rmap_type;
1797 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1798
1799 /* Apply BGP route map to the attribute. */
1800 ret = route_map_apply(rmap, p, &rmap_path);
1801
1802 peer->rmap_type = rmap_type;
1803
1804 if (ret == RMAP_DENYMATCH)
1805 /*
1806 * caller has multiple error paths with bgp_attr_flush()
1807 */
1808 return RMAP_DENY;
1809
1810 return RMAP_PERMIT;
1811 }
1812
1813 /* If this is an EBGP peer with remove-private-AS */
1814 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1815 struct peer *peer, struct attr *attr)
1816 {
1817 if (peer->sort == BGP_PEER_EBGP
1818 && (peer_af_flag_check(peer, afi, safi,
1819 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1820 || peer_af_flag_check(peer, afi, safi,
1821 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1822 || peer_af_flag_check(peer, afi, safi,
1823 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1824 || peer_af_flag_check(peer, afi, safi,
1825 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1826 // Take action on the entire aspath
1827 if (peer_af_flag_check(peer, afi, safi,
1828 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1829 || peer_af_flag_check(peer, afi, safi,
1830 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1831 if (peer_af_flag_check(
1832 peer, afi, safi,
1833 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1834 attr->aspath = aspath_replace_private_asns(
1835 attr->aspath, bgp->as, peer->as);
1836
1837 /*
1838 * Even if the aspath consists of just private ASNs we
1839 * need to walk the AS-Path to maintain all instances
1840 * of the peer's ASN to break possible loops.
1841 */
1842 else
1843 attr->aspath = aspath_remove_private_asns(
1844 attr->aspath, peer->as);
1845 }
1846
1847 // 'all' was not specified so the entire aspath must be private
1848 // ASNs
1849 // for us to do anything
1850 else if (aspath_private_as_check(attr->aspath)) {
1851 if (peer_af_flag_check(
1852 peer, afi, safi,
1853 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1854 attr->aspath = aspath_replace_private_asns(
1855 attr->aspath, bgp->as, peer->as);
1856 else
1857 /*
1858 * Walk the aspath to retain any instances of
1859 * the peer_asn
1860 */
1861 attr->aspath = aspath_remove_private_asns(
1862 attr->aspath, peer->as);
1863 }
1864 }
1865 }
1866
1867 /* If this is an EBGP peer with as-override */
1868 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1869 struct peer *peer, struct attr *attr)
1870 {
1871 struct aspath *aspath;
1872
1873 if (peer->sort == BGP_PEER_EBGP &&
1874 peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1875 if (attr->aspath->refcnt)
1876 aspath = aspath_dup(attr->aspath);
1877 else
1878 aspath = attr->aspath;
1879
1880 attr->aspath = aspath_intern(
1881 aspath_replace_specific_asn(aspath, peer->as, bgp->as));
1882
1883 aspath_free(aspath);
1884 }
1885 }
1886
1887 void bgp_attr_add_llgr_community(struct attr *attr)
1888 {
1889 struct community *old;
1890 struct community *new;
1891 struct community *merge;
1892 struct community *llgr;
1893
1894 old = bgp_attr_get_community(attr);
1895 llgr = community_str2com("llgr-stale");
1896
1897 assert(llgr);
1898
1899 if (old) {
1900 merge = community_merge(community_dup(old), llgr);
1901
1902 if (old->refcnt == 0)
1903 community_free(&old);
1904
1905 new = community_uniq_sort(merge);
1906 community_free(&merge);
1907 } else {
1908 new = community_dup(llgr);
1909 }
1910
1911 community_free(&llgr);
1912
1913 bgp_attr_set_community(attr, new);
1914 }
1915
1916 void bgp_attr_add_gshut_community(struct attr *attr)
1917 {
1918 struct community *old;
1919 struct community *new;
1920 struct community *merge;
1921 struct community *gshut;
1922
1923 old = bgp_attr_get_community(attr);
1924 gshut = community_str2com("graceful-shutdown");
1925
1926 assert(gshut);
1927
1928 if (old) {
1929 merge = community_merge(community_dup(old), gshut);
1930
1931 if (old->refcnt == 0)
1932 community_free(&old);
1933
1934 new = community_uniq_sort(merge);
1935 community_free(&merge);
1936 } else {
1937 new = community_dup(gshut);
1938 }
1939
1940 community_free(&gshut);
1941 bgp_attr_set_community(attr, new);
1942
1943 /* When we add the graceful-shutdown community we must also
1944 * lower the local-preference */
1945 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1946 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1947 }
1948
1949
1950 /* Notify BGP Conditional advertisement scanner process. */
1951 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1952 {
1953 struct peer *peer = SUBGRP_PEER(subgrp);
1954 afi_t afi = SUBGRP_AFI(subgrp);
1955 safi_t safi = SUBGRP_SAFI(subgrp);
1956 struct bgp_filter *filter = &peer->filter[afi][safi];
1957
1958 if (!ADVERTISE_MAP_NAME(filter))
1959 return;
1960
1961 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1962 return;
1963
1964 peer->advmap_table_change = true;
1965 }
1966
1967
1968 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1969 {
1970 if (family == AF_INET) {
1971 attr->nexthop.s_addr = INADDR_ANY;
1972 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1973 }
1974 if (family == AF_INET6)
1975 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1976 if (family == AF_EVPN)
1977 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1978 }
1979
1980 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1981 struct update_subgroup *subgrp,
1982 const struct prefix *p, struct attr *attr,
1983 struct attr *post_attr)
1984 {
1985 struct bgp_filter *filter;
1986 struct peer *from;
1987 struct peer *peer;
1988 struct peer *onlypeer;
1989 struct bgp *bgp;
1990 struct attr *piattr;
1991 route_map_result_t ret;
1992 int transparent;
1993 int reflect;
1994 afi_t afi;
1995 safi_t safi;
1996 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1997 bool nh_reset = false;
1998 uint64_t cum_bw;
1999
2000 if (DISABLE_BGP_ANNOUNCE)
2001 return false;
2002
2003 afi = SUBGRP_AFI(subgrp);
2004 safi = SUBGRP_SAFI(subgrp);
2005 peer = SUBGRP_PEER(subgrp);
2006 onlypeer = NULL;
2007 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
2008 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
2009
2010 from = pi->peer;
2011 filter = &peer->filter[afi][safi];
2012 bgp = SUBGRP_INST(subgrp);
2013 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
2014 : pi->attr;
2015
2016 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
2017 peer->pmax_out[afi][safi] != 0 &&
2018 subgrp->pscount >= peer->pmax_out[afi][safi]) {
2019 if (BGP_DEBUG(update, UPDATE_OUT) ||
2020 BGP_DEBUG(update, UPDATE_PREFIX)) {
2021 zlog_debug("%s reached maximum prefix to be send (%u)",
2022 peer->host, peer->pmax_out[afi][safi]);
2023 }
2024 return false;
2025 }
2026
2027 #ifdef ENABLE_BGP_VNC
2028 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
2029 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
2030 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
2031
2032 /*
2033 * direct and direct_ext type routes originate internally even
2034 * though they can have peer pointers that reference other
2035 * systems
2036 */
2037 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
2038 __func__, p);
2039 samepeer_safe = 1;
2040 }
2041 #endif
2042
2043 if (((afi == AFI_IP) || (afi == AFI_IP6))
2044 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
2045 && (pi->type == ZEBRA_ROUTE_BGP)
2046 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
2047
2048 /* Applies to routes leaked vpn->vrf and vrf->vpn */
2049
2050 samepeer_safe = 1;
2051 }
2052
2053 /* With addpath we may be asked to TX all kinds of paths so make sure
2054 * pi is valid */
2055 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
2056 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
2057 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
2058 return false;
2059 }
2060
2061 /* If this is not the bestpath then check to see if there is an enabled
2062 * addpath
2063 * feature that requires us to advertise it */
2064 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2065 if (!bgp_addpath_capable(pi, peer, afi, safi))
2066 return false;
2067
2068 /* Aggregate-address suppress check. */
2069 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
2070 return false;
2071
2072 /*
2073 * If we are doing VRF 2 VRF leaking via the import
2074 * statement, we want to prevent the route going
2075 * off box as that the RT and RD created are localy
2076 * significant and globaly useless.
2077 */
2078 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
2079 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
2080 return false;
2081
2082 /* If it's labeled safi, make sure the route has a valid label. */
2083 if (safi == SAFI_LABELED_UNICAST) {
2084 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
2085 if (!bgp_is_valid_label(&label)) {
2086 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2087 zlog_debug("u%" PRIu64 ":s%" PRIu64
2088 " %pFX is filtered - no label (%p)",
2089 subgrp->update_group->id, subgrp->id,
2090 p, &label);
2091 return false;
2092 }
2093 }
2094
2095 /* Do not send back route to sender. */
2096 if (onlypeer && from == onlypeer) {
2097 return false;
2098 }
2099
2100 /* Do not send the default route in the BGP table if the neighbor is
2101 * configured for default-originate */
2102 if (CHECK_FLAG(peer->af_flags[afi][safi],
2103 PEER_FLAG_DEFAULT_ORIGINATE)) {
2104 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
2105 return false;
2106 else if (p->family == AF_INET6 && p->prefixlen == 0)
2107 return false;
2108 }
2109
2110 /* Transparency check. */
2111 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
2112 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
2113 transparent = 1;
2114 else
2115 transparent = 0;
2116
2117 /* If community is not disabled check the no-export and local. */
2118 if (!transparent && bgp_community_filter(peer, piattr)) {
2119 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2120 zlog_debug("%s: community filter check fail for %pFX",
2121 __func__, p);
2122 return false;
2123 }
2124
2125 /* If the attribute has originator-id and it is same as remote
2126 peer's id. */
2127 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
2128 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
2129 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2130 zlog_debug(
2131 "%pBP [Update:SEND] %pFX originator-id is same as remote router-id",
2132 onlypeer, p);
2133 return false;
2134 }
2135
2136 /* ORF prefix-list filter check */
2137 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2138 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2139 || CHECK_FLAG(peer->af_cap[afi][safi],
2140 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2141 if (peer->orf_plist[afi][safi]) {
2142 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2143 == PREFIX_DENY) {
2144 if (bgp_debug_update(NULL, p,
2145 subgrp->update_group, 0))
2146 zlog_debug(
2147 "%pBP [Update:SEND] %pFX is filtered via ORF",
2148 peer, p);
2149 return false;
2150 }
2151 }
2152
2153 /* Output filter check. */
2154 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2155 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2156 zlog_debug("%pBP [Update:SEND] %pFX is filtered", peer,
2157 p);
2158 return false;
2159 }
2160
2161 /* AS path loop check. */
2162 if (peer->as_path_loop_detection &&
2163 aspath_loop_check(piattr->aspath, peer->as)) {
2164 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2165 zlog_debug(
2166 "%pBP [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2167 peer, peer->as);
2168 return false;
2169 }
2170
2171 /* If we're a CONFED we need to loop check the CONFED ID too */
2172 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2173 if (aspath_loop_check_confed(piattr->aspath, bgp->confed_id)) {
2174 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2175 zlog_debug(
2176 "%pBP [Update:SEND] suppress announcement to peer AS %u is AS path.",
2177 peer, bgp->confed_id);
2178 return false;
2179 }
2180 }
2181
2182 /* Route-Reflect check. */
2183 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2184 reflect = 1;
2185 else
2186 reflect = 0;
2187
2188 /* IBGP reflection check. */
2189 if (reflect && !samepeer_safe) {
2190 /* A route from a Client peer. */
2191 if (CHECK_FLAG(from->af_flags[afi][safi],
2192 PEER_FLAG_REFLECTOR_CLIENT)) {
2193 /* Reflect to all the Non-Client peers and also to the
2194 Client peers other than the originator. Originator
2195 check
2196 is already done. So there is noting to do. */
2197 /* no bgp client-to-client reflection check. */
2198 if (CHECK_FLAG(bgp->flags,
2199 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2200 if (CHECK_FLAG(peer->af_flags[afi][safi],
2201 PEER_FLAG_REFLECTOR_CLIENT))
2202 return false;
2203 } else {
2204 /* A route from a Non-client peer. Reflect to all other
2205 clients. */
2206 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2207 PEER_FLAG_REFLECTOR_CLIENT))
2208 return false;
2209 }
2210 }
2211
2212 /* For modify attribute, copy it to temporary structure.
2213 * post_attr comes from BGP conditional advertisements, where
2214 * attributes are already processed by advertise-map route-map,
2215 * and this needs to be saved instead of overwriting from the
2216 * path attributes.
2217 */
2218 if (post_attr)
2219 *attr = *post_attr;
2220 else
2221 *attr = *piattr;
2222
2223 /* If local-preference is not set. */
2224 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2225 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2226 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2227 attr->local_pref = bgp->default_local_pref;
2228 }
2229
2230 /* If originator-id is not set and the route is to be reflected,
2231 set the originator id */
2232 if (reflect
2233 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2234 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2235 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2236 }
2237
2238 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2239 */
2240 if (peer->sort == BGP_PEER_EBGP
2241 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2242 if (from != bgp->peer_self && !transparent
2243 && !CHECK_FLAG(peer->af_flags[afi][safi],
2244 PEER_FLAG_MED_UNCHANGED))
2245 attr->flag &=
2246 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2247 }
2248
2249 /* Since the nexthop attribute can vary per peer, it is not explicitly
2250 * set
2251 * in announce check, only certain flags and length (or number of
2252 * nexthops
2253 * -- for IPv6/MP_REACH) are set here in order to guide the update
2254 * formation
2255 * code in setting the nexthop(s) on a per peer basis in
2256 * reformat_peer().
2257 * Typically, the source nexthop in the attribute is preserved but in
2258 * the
2259 * scenarios where we know it will always be overwritten, we reset the
2260 * nexthop to "0" in an attempt to achieve better Update packing. An
2261 * example of this is when a prefix from each of 2 IBGP peers needs to
2262 * be
2263 * announced to an EBGP peer (and they have the same attributes barring
2264 * their nexthop).
2265 */
2266 if (reflect)
2267 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2268
2269 #define NEXTHOP_IS_V6 \
2270 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2271 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2272 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2273 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2274
2275 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2276 * if
2277 * the peer (group) is configured to receive link-local nexthop
2278 * unchanged
2279 * and it is available in the prefix OR we're not reflecting the route,
2280 * link-local nexthop address is valid and
2281 * the peer (group) to whom we're going to announce is on a shared
2282 * network
2283 * and this is either a self-originated route or the peer is EBGP.
2284 * By checking if nexthop LL address is valid we are sure that
2285 * we do not announce LL address as `::`.
2286 */
2287 if (NEXTHOP_IS_V6) {
2288 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2289 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2290 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2291 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2292 || (!reflect && !transparent
2293 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2294 && peer->shared_network
2295 && (from == bgp->peer_self
2296 || peer->sort == BGP_PEER_EBGP))) {
2297 if (safi == SAFI_MPLS_VPN)
2298 attr->mp_nexthop_len =
2299 BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL;
2300 else
2301 attr->mp_nexthop_len =
2302 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2303 }
2304
2305 /* Clear off link-local nexthop in source, whenever it is not
2306 * needed to
2307 * ensure more prefixes share the same attribute for
2308 * announcement.
2309 */
2310 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2311 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2312 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2313 }
2314
2315 if (bgp_check_role_applicability(afi, safi) &&
2316 bgp_otc_egress(peer, attr))
2317 return false;
2318
2319 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2320 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2321
2322 if (filter->advmap.update_type == UPDATE_TYPE_WITHDRAW &&
2323 filter->advmap.aname &&
2324 route_map_lookup_by_name(filter->advmap.aname)) {
2325 struct bgp_path_info rmap_path = {0};
2326 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2327 struct attr dummy_attr = *attr;
2328
2329 /* Fill temp path_info */
2330 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2331 pi, peer, &dummy_attr);
2332
2333 struct route_map *amap =
2334 route_map_lookup_by_name(filter->advmap.aname);
2335
2336 ret = route_map_apply(amap, p, &rmap_path);
2337
2338 bgp_attr_flush(&dummy_attr);
2339
2340 /*
2341 * The conditional advertisement mode is Withdraw and this
2342 * prefix is a conditional prefix. Don't advertise it
2343 */
2344 if (ret == RMAP_PERMITMATCH)
2345 return false;
2346 }
2347
2348 /* Route map & unsuppress-map apply. */
2349 if (!post_attr &&
2350 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2351 struct bgp_path_info rmap_path = {0};
2352 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2353 struct attr dummy_attr = {0};
2354
2355 /* Fill temp path_info */
2356 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2357 pi, peer, attr);
2358
2359 /* don't confuse inbound and outbound setting */
2360 RESET_FLAG(attr->rmap_change_flags);
2361
2362 /*
2363 * The route reflector is not allowed to modify the attributes
2364 * of the reflected IBGP routes unless explicitly allowed.
2365 */
2366 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2367 && !CHECK_FLAG(bgp->flags,
2368 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2369 dummy_attr = *attr;
2370 rmap_path.attr = &dummy_attr;
2371 }
2372
2373 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2374
2375 if (bgp_path_suppressed(pi))
2376 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2377 &rmap_path);
2378 else
2379 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2380 &rmap_path);
2381
2382 bgp_attr_flush(&dummy_attr);
2383 peer->rmap_type = 0;
2384
2385 if (ret == RMAP_DENYMATCH) {
2386 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2387 zlog_debug(
2388 "%pBP [Update:SEND] %pFX is filtered by route-map '%s'",
2389 peer, p,
2390 bgp_path_suppressed(pi)
2391 ? UNSUPPRESS_MAP_NAME(filter)
2392 : ROUTE_MAP_OUT_NAME(filter));
2393 bgp_attr_flush(rmap_path.attr);
2394 return false;
2395 }
2396 }
2397
2398 /* RFC 8212 to prevent route leaks.
2399 * This specification intends to improve this situation by requiring the
2400 * explicit configuration of both BGP Import and Export Policies for any
2401 * External BGP (EBGP) session such as customers, peers, or
2402 * confederation boundaries for all enabled address families. Through
2403 * codification of the aforementioned requirement, operators will
2404 * benefit from consistent behavior across different BGP
2405 * implementations.
2406 */
2407 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2408 if (!bgp_outbound_policy_exists(peer, filter)) {
2409 if (monotime_since(&bgp->ebgprequirespolicywarning,
2410 NULL) > FIFTEENMINUTE2USEC ||
2411 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2412 zlog_warn(
2413 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2414 monotime(&bgp->ebgprequirespolicywarning);
2415 }
2416 return false;
2417 }
2418
2419 /* draft-ietf-idr-deprecate-as-set-confed-set
2420 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2421 * Eventually, This document (if approved) updates RFC 4271
2422 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2423 * and obsoletes RFC 6472.
2424 */
2425 if (peer->bgp->reject_as_sets)
2426 if (aspath_check_as_sets(attr->aspath))
2427 return false;
2428
2429 /* If neighbor soo is configured, then check if the route has
2430 * SoO extended community and validate against the configured
2431 * one. If they match, do not announce, to prevent routing
2432 * loops.
2433 */
2434 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) &&
2435 peer->soo[afi][safi]) {
2436 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
2437 struct ecommunity *ecomm = bgp_attr_get_ecommunity(attr);
2438
2439 if ((ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS,
2440 ECOMMUNITY_SITE_ORIGIN) ||
2441 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_AS4,
2442 ECOMMUNITY_SITE_ORIGIN) ||
2443 ecommunity_lookup(ecomm, ECOMMUNITY_ENCODE_IP,
2444 ECOMMUNITY_SITE_ORIGIN)) &&
2445 ecommunity_include(ecomm, ecomm_soo)) {
2446 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2447 zlog_debug(
2448 "%pBP [Update:SEND] %pFX is filtered by SoO extcommunity '%s'",
2449 peer, p, ecommunity_str(ecomm_soo));
2450 return false;
2451 }
2452 }
2453
2454 /* Codification of AS 0 Processing */
2455 if (aspath_check_as_zero(attr->aspath))
2456 return false;
2457
2458 if (bgp_in_graceful_shutdown(bgp)) {
2459 if (peer->sort == BGP_PEER_IBGP
2460 || peer->sort == BGP_PEER_CONFED) {
2461 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2462 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2463 } else {
2464 bgp_attr_add_gshut_community(attr);
2465 }
2466 }
2467
2468 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2469 * Capability" to a neighbor MUST perform the following upon receiving
2470 * a route from that neighbor with the "LLGR_STALE" community, or upon
2471 * attaching the "LLGR_STALE" community itself per Section 4.2:
2472 *
2473 * The route SHOULD NOT be advertised to any neighbor from which the
2474 * Long-lived Graceful Restart Capability has not been received.
2475 */
2476 if (bgp_attr_get_community(attr) &&
2477 community_include(bgp_attr_get_community(attr),
2478 COMMUNITY_LLGR_STALE) &&
2479 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2480 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2481 return false;
2482
2483 /* After route-map has been applied, we check to see if the nexthop to
2484 * be carried in the attribute (that is used for the announcement) can
2485 * be cleared off or not. We do this in all cases where we would be
2486 * setting the nexthop to "ourselves". For IPv6, we only need to
2487 * consider
2488 * the global nexthop here; the link-local nexthop would have been
2489 * cleared
2490 * already, and if not, it is required by the update formation code.
2491 * Also see earlier comments in this function.
2492 */
2493 /*
2494 * If route-map has performed some operation on the nexthop or the peer
2495 * configuration says to pass it unchanged, we cannot reset the nexthop
2496 * here, so only attempt to do it if these aren't true. Note that the
2497 * route-map handler itself might have cleared the nexthop, if for
2498 * example,
2499 * it is configured as 'peer-address'.
2500 */
2501 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2502 piattr->rmap_change_flags)
2503 && !transparent
2504 && !CHECK_FLAG(peer->af_flags[afi][safi],
2505 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2506 /* We can reset the nexthop, if setting (or forcing) it to
2507 * 'self' */
2508 if (CHECK_FLAG(peer->af_flags[afi][safi],
2509 PEER_FLAG_NEXTHOP_SELF)
2510 || CHECK_FLAG(peer->af_flags[afi][safi],
2511 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2512 if (!reflect
2513 || CHECK_FLAG(peer->af_flags[afi][safi],
2514 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2515 subgroup_announce_reset_nhop(
2516 (peer_cap_enhe(peer, afi, safi)
2517 ? AF_INET6
2518 : p->family),
2519 attr);
2520 nh_reset = true;
2521 }
2522 } else if (peer->sort == BGP_PEER_EBGP) {
2523 /* Can also reset the nexthop if announcing to EBGP, but
2524 * only if
2525 * no peer in the subgroup is on a shared subnet.
2526 * Note: 3rd party nexthop currently implemented for
2527 * IPv4 only.
2528 */
2529 if ((p->family == AF_INET) &&
2530 (!bgp_subgrp_multiaccess_check_v4(
2531 piattr->nexthop,
2532 subgrp, from))) {
2533 subgroup_announce_reset_nhop(
2534 (peer_cap_enhe(peer, afi, safi)
2535 ? AF_INET6
2536 : p->family),
2537 attr);
2538 nh_reset = true;
2539 }
2540
2541 if ((p->family == AF_INET6) &&
2542 (!bgp_subgrp_multiaccess_check_v6(
2543 piattr->mp_nexthop_global,
2544 subgrp, from))) {
2545 subgroup_announce_reset_nhop(
2546 (peer_cap_enhe(peer, afi, safi)
2547 ? AF_INET6
2548 : p->family),
2549 attr);
2550 nh_reset = true;
2551 }
2552
2553
2554
2555 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2556 /*
2557 * This flag is used for leaked vpn-vrf routes
2558 */
2559 int family = p->family;
2560
2561 if (peer_cap_enhe(peer, afi, safi))
2562 family = AF_INET6;
2563
2564 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2565 zlog_debug(
2566 "%s: %pFX BGP_PATH_ANNC_NH_SELF, family=%s",
2567 __func__, p, family2str(family));
2568 subgroup_announce_reset_nhop(family, attr);
2569 nh_reset = true;
2570 }
2571 }
2572
2573 /* If IPv6/MP and nexthop does not have any override and happens
2574 * to
2575 * be a link-local address, reset it so that we don't pass along
2576 * the
2577 * source's link-local IPv6 address to recipients who may not be
2578 * on
2579 * the same interface.
2580 */
2581 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2582 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2583 subgroup_announce_reset_nhop(AF_INET6, attr);
2584 nh_reset = true;
2585 }
2586 }
2587
2588 /* If this is an iBGP, send Origin Validation State (OVS)
2589 * extended community (rfc8097).
2590 */
2591 if (peer->sort == BGP_PEER_IBGP) {
2592 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
2593
2594 rpki_state = hook_call(bgp_rpki_prefix_status, peer, attr, p);
2595
2596 if (rpki_state != RPKI_NOT_BEING_USED)
2597 bgp_attr_set_ecommunity(
2598 attr, ecommunity_add_origin_validation_state(
2599 rpki_state,
2600 bgp_attr_get_ecommunity(attr)));
2601 }
2602
2603 /*
2604 * When the next hop is set to ourselves, if all multipaths have
2605 * link-bandwidth announce the cumulative bandwidth as that makes
2606 * the most sense. However, don't modify if the link-bandwidth has
2607 * been explicitly set by user policy.
2608 */
2609 if (nh_reset &&
2610 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2611 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2612 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2613 bgp_attr_set_ecommunity(
2614 attr,
2615 ecommunity_replace_linkbw(
2616 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2617 CHECK_FLAG(
2618 peer->flags,
2619 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2620
2621 return true;
2622 }
2623
2624 static void bgp_route_select_timer_expire(struct event *thread)
2625 {
2626 struct afi_safi_info *info;
2627 afi_t afi;
2628 safi_t safi;
2629 struct bgp *bgp;
2630
2631 info = EVENT_ARG(thread);
2632 afi = info->afi;
2633 safi = info->safi;
2634 bgp = info->bgp;
2635
2636 bgp->gr_info[afi][safi].t_route_select = NULL;
2637 XFREE(MTYPE_TMP, info);
2638
2639 /* Best path selection */
2640 bgp_best_path_select_defer(bgp, afi, safi);
2641 }
2642
2643 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2644 struct bgp_maxpaths_cfg *mpath_cfg,
2645 struct bgp_path_info_pair *result, afi_t afi,
2646 safi_t safi)
2647 {
2648 struct bgp_path_info *new_select;
2649 struct bgp_path_info *old_select;
2650 struct bgp_path_info *pi;
2651 struct bgp_path_info *pi1;
2652 struct bgp_path_info *pi2;
2653 struct bgp_path_info *nextpi = NULL;
2654 int paths_eq, do_mpath, debug;
2655 struct list mp_list;
2656 char pfx_buf[PREFIX2STR_BUFFER];
2657 char path_buf[PATH_ADDPATH_STR_BUFFER];
2658
2659 bgp_mp_list_init(&mp_list);
2660 do_mpath =
2661 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2662
2663 debug = bgp_debug_bestpath(dest);
2664
2665 if (debug)
2666 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2667
2668 dest->reason = bgp_path_selection_none;
2669 /* bgp deterministic-med */
2670 new_select = NULL;
2671 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2672
2673 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2674 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2675 pi1 = pi1->next)
2676 bgp_path_info_unset_flag(dest, pi1,
2677 BGP_PATH_DMED_SELECTED);
2678
2679 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2680 pi1 = pi1->next) {
2681 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2682 continue;
2683 if (BGP_PATH_HOLDDOWN(pi1))
2684 continue;
2685 if (pi1->peer != bgp->peer_self &&
2686 !CHECK_FLAG(pi1->peer->sflags,
2687 PEER_STATUS_NSF_WAIT)) {
2688 if (!peer_established(pi1->peer))
2689 continue;
2690 }
2691
2692 new_select = pi1;
2693 if (pi1->next) {
2694 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2695 if (CHECK_FLAG(pi2->flags,
2696 BGP_PATH_DMED_CHECK))
2697 continue;
2698 if (BGP_PATH_HOLDDOWN(pi2))
2699 continue;
2700 if (pi2->peer != bgp->peer_self
2701 && !CHECK_FLAG(
2702 pi2->peer->sflags,
2703 PEER_STATUS_NSF_WAIT))
2704 if (pi2->peer->status
2705 != Established)
2706 continue;
2707
2708 if (!aspath_cmp_left(pi1->attr->aspath,
2709 pi2->attr->aspath)
2710 && !aspath_cmp_left_confed(
2711 pi1->attr->aspath,
2712 pi2->attr->aspath))
2713 continue;
2714
2715 if (bgp_path_info_cmp(
2716 bgp, pi2, new_select,
2717 &paths_eq, mpath_cfg, debug,
2718 pfx_buf, afi, safi,
2719 &dest->reason)) {
2720 bgp_path_info_unset_flag(
2721 dest, new_select,
2722 BGP_PATH_DMED_SELECTED);
2723 new_select = pi2;
2724 }
2725
2726 bgp_path_info_set_flag(
2727 dest, pi2, BGP_PATH_DMED_CHECK);
2728 }
2729 }
2730 bgp_path_info_set_flag(dest, new_select,
2731 BGP_PATH_DMED_CHECK);
2732 bgp_path_info_set_flag(dest, new_select,
2733 BGP_PATH_DMED_SELECTED);
2734
2735 if (debug) {
2736 bgp_path_info_path_with_addpath_rx_str(
2737 new_select, path_buf, sizeof(path_buf));
2738 zlog_debug(
2739 "%pBD(%s): %s is the bestpath from AS %u",
2740 dest, bgp->name_pretty, path_buf,
2741 aspath_get_first_as(
2742 new_select->attr->aspath));
2743 }
2744 }
2745 }
2746
2747 /* Check old selected route and new selected route. */
2748 old_select = NULL;
2749 new_select = NULL;
2750 for (pi = bgp_dest_get_bgp_path_info(dest);
2751 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2752 enum bgp_path_selection_reason reason;
2753
2754 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2755 old_select = pi;
2756
2757 if (BGP_PATH_HOLDDOWN(pi)) {
2758 /* reap REMOVED routes, if needs be
2759 * selected route must stay for a while longer though
2760 */
2761 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2762 && (pi != old_select))
2763 bgp_path_info_reap(dest, pi);
2764
2765 if (debug)
2766 zlog_debug(
2767 "%s: %pBD(%s) pi from %s in holddown",
2768 __func__, dest, bgp->name_pretty,
2769 pi->peer->host);
2770
2771 continue;
2772 }
2773
2774 if (pi->peer && pi->peer != bgp->peer_self
2775 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2776 if (!peer_established(pi->peer)) {
2777
2778 if (debug)
2779 zlog_debug(
2780 "%s: %pBD(%s) non self peer %s not estab state",
2781 __func__, dest,
2782 bgp->name_pretty,
2783 pi->peer->host);
2784
2785 continue;
2786 }
2787
2788 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2789 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2790 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2791 if (debug)
2792 zlog_debug("%s: %pBD(%s) pi %s dmed", __func__,
2793 dest, bgp->name_pretty,
2794 pi->peer->host);
2795 continue;
2796 }
2797
2798 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2799
2800 reason = dest->reason;
2801 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2802 debug, pfx_buf, afi, safi,
2803 &dest->reason)) {
2804 if (new_select == NULL &&
2805 reason != bgp_path_selection_none)
2806 dest->reason = reason;
2807 new_select = pi;
2808 }
2809 }
2810
2811 /* Now that we know which path is the bestpath see if any of the other
2812 * paths
2813 * qualify as multipaths
2814 */
2815 if (debug) {
2816 if (new_select)
2817 bgp_path_info_path_with_addpath_rx_str(
2818 new_select, path_buf, sizeof(path_buf));
2819 else
2820 snprintf(path_buf, sizeof(path_buf), "NONE");
2821 zlog_debug(
2822 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2823 dest, bgp->name_pretty, path_buf,
2824 old_select ? old_select->peer->host : "NONE");
2825 }
2826
2827 if (do_mpath && new_select) {
2828 for (pi = bgp_dest_get_bgp_path_info(dest);
2829 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2830
2831 if (debug)
2832 bgp_path_info_path_with_addpath_rx_str(
2833 pi, path_buf, sizeof(path_buf));
2834
2835 if (pi == new_select) {
2836 if (debug)
2837 zlog_debug(
2838 "%pBD(%s): %s is the bestpath, add to the multipath list",
2839 dest, bgp->name_pretty,
2840 path_buf);
2841 bgp_mp_list_add(&mp_list, pi);
2842 continue;
2843 }
2844
2845 if (BGP_PATH_HOLDDOWN(pi))
2846 continue;
2847
2848 if (pi->peer && pi->peer != bgp->peer_self
2849 && !CHECK_FLAG(pi->peer->sflags,
2850 PEER_STATUS_NSF_WAIT))
2851 if (!peer_established(pi->peer))
2852 continue;
2853
2854 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2855 if (debug)
2856 zlog_debug(
2857 "%pBD(%s): %s has the same nexthop as the bestpath, skip it",
2858 dest, bgp->name_pretty,
2859 path_buf);
2860 continue;
2861 }
2862
2863 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2864 mpath_cfg, debug, pfx_buf, afi, safi,
2865 &dest->reason);
2866
2867 if (paths_eq) {
2868 if (debug)
2869 zlog_debug(
2870 "%pBD(%s): %s is equivalent to the bestpath, add to the multipath list",
2871 dest, bgp->name_pretty,
2872 path_buf);
2873 bgp_mp_list_add(&mp_list, pi);
2874 }
2875 }
2876 }
2877
2878 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2879 mpath_cfg);
2880 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2881 bgp_mp_list_clear(&mp_list);
2882
2883 bgp_addpath_update_ids(bgp, dest, afi, safi);
2884
2885 result->old = old_select;
2886 result->new = new_select;
2887
2888 return;
2889 }
2890
2891 /*
2892 * A new route/change in bestpath of an existing route. Evaluate the path
2893 * for advertisement to the subgroup.
2894 */
2895 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2896 struct bgp_path_info *selected,
2897 struct bgp_dest *dest,
2898 uint32_t addpath_tx_id)
2899 {
2900 const struct prefix *p;
2901 struct peer *onlypeer;
2902 struct attr attr;
2903 afi_t afi;
2904 safi_t safi;
2905 struct bgp *bgp;
2906 bool advertise;
2907
2908 p = bgp_dest_get_prefix(dest);
2909 afi = SUBGRP_AFI(subgrp);
2910 safi = SUBGRP_SAFI(subgrp);
2911 bgp = SUBGRP_INST(subgrp);
2912 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2913 : NULL);
2914
2915 if (BGP_DEBUG(update, UPDATE_OUT))
2916 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2917
2918 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2919 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2920 PEER_STATUS_ORF_WAIT_REFRESH))
2921 return;
2922
2923 memset(&attr, 0, sizeof(attr));
2924 /* It's initialized in bgp_announce_check() */
2925
2926 /* Announcement to the subgroup. If the route is filtered withdraw it.
2927 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2928 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2929 * route
2930 */
2931 advertise = bgp_check_advertise(bgp, dest);
2932
2933 if (selected) {
2934 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2935 NULL)) {
2936 /* Route is selected, if the route is already installed
2937 * in FIB, then it is advertised
2938 */
2939 if (advertise) {
2940 if (!bgp_check_withdrawal(bgp, dest)) {
2941 struct attr *adv_attr =
2942 bgp_attr_intern(&attr);
2943
2944 bgp_adj_out_set_subgroup(dest, subgrp,
2945 adv_attr,
2946 selected);
2947 } else
2948 bgp_adj_out_unset_subgroup(
2949 dest, subgrp, 1, addpath_tx_id);
2950 }
2951 } else
2952 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2953 addpath_tx_id);
2954 }
2955
2956 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2957 else {
2958 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2959 }
2960 }
2961
2962 /*
2963 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2964 * This is called at the end of route processing.
2965 */
2966 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2967 {
2968 struct bgp_path_info *pi;
2969
2970 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2971 if (BGP_PATH_HOLDDOWN(pi))
2972 continue;
2973 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2974 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2975 }
2976 }
2977
2978 /*
2979 * Has the route changed from the RIB's perspective? This is invoked only
2980 * if the route selection returns the same best route as earlier - to
2981 * determine if we need to update zebra or not.
2982 */
2983 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2984 {
2985 struct bgp_path_info *mpinfo;
2986
2987 /* If this is multipath, check all selected paths for any nexthop
2988 * change or attribute change. Some attribute changes (e.g., community)
2989 * aren't of relevance to the RIB, but we'll update zebra to ensure
2990 * we handle the case of BGP nexthop change. This is the behavior
2991 * when the best path has an attribute change anyway.
2992 */
2993 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2994 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2995 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2996 return true;
2997
2998 /*
2999 * If this is multipath, check all selected paths for any nexthop change
3000 */
3001 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
3002 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
3003 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
3004 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
3005 return true;
3006 }
3007
3008 /* Nothing has changed from the RIB's perspective. */
3009 return false;
3010 }
3011
3012 struct bgp_process_queue {
3013 struct bgp *bgp;
3014 STAILQ_HEAD(, bgp_dest) pqueue;
3015 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
3016 unsigned int flags;
3017 unsigned int queued;
3018 };
3019
3020 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
3021 safi_t safi, struct bgp_dest *dest,
3022 struct bgp_path_info *new_select,
3023 struct bgp_path_info *old_select)
3024 {
3025 const struct prefix *p = bgp_dest_get_prefix(dest);
3026
3027 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
3028 return;
3029
3030 if (advertise_type5_routes(bgp, afi) && new_select
3031 && is_route_injectable_into_evpn(new_select)) {
3032
3033 /* apply the route-map */
3034 if (bgp->adv_cmd_rmap[afi][safi].map) {
3035 route_map_result_t ret;
3036 struct bgp_path_info rmap_path;
3037 struct bgp_path_info_extra rmap_path_extra;
3038 struct attr dummy_attr;
3039
3040 dummy_attr = *new_select->attr;
3041
3042 /* Fill temp path_info */
3043 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
3044 new_select, new_select->peer,
3045 &dummy_attr);
3046
3047 RESET_FLAG(dummy_attr.rmap_change_flags);
3048
3049 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
3050 p, &rmap_path);
3051
3052 if (ret == RMAP_DENYMATCH) {
3053 bgp_attr_flush(&dummy_attr);
3054 bgp_evpn_withdraw_type5_route(bgp, p, afi,
3055 safi);
3056 } else
3057 bgp_evpn_advertise_type5_route(
3058 bgp, p, &dummy_attr, afi, safi);
3059 } else {
3060 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
3061 afi, safi);
3062 }
3063 } else if (advertise_type5_routes(bgp, afi) && old_select
3064 && is_route_injectable_into_evpn(old_select))
3065 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
3066 }
3067
3068 /*
3069 * Utility to determine whether a particular path_info should use
3070 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
3071 * in a path where we basically _know_ this is a BGP-LU route.
3072 */
3073 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
3074 {
3075 /* Certain types get imp null; so do paths where the nexthop is
3076 * not labeled.
3077 */
3078 if (new_select->sub_type == BGP_ROUTE_STATIC
3079 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3080 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
3081 return true;
3082 else if (new_select->extra == NULL ||
3083 !bgp_is_valid_label(&new_select->extra->label[0]))
3084 /* TODO -- should be configurable? */
3085 return true;
3086 else
3087 return false;
3088 }
3089
3090 /*
3091 * old_select = The old best path
3092 * new_select = the new best path
3093 *
3094 * if (!old_select && new_select)
3095 * We are sending new information on.
3096 *
3097 * if (old_select && new_select) {
3098 * if (new_select != old_select)
3099 * We have a new best path send a change
3100 * else
3101 * We've received a update with new attributes that needs
3102 * to be passed on.
3103 * }
3104 *
3105 * if (old_select && !new_select)
3106 * We have no eligible route that we can announce or the rn
3107 * is being removed.
3108 */
3109 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
3110 afi_t afi, safi_t safi)
3111 {
3112 struct bgp_path_info *new_select;
3113 struct bgp_path_info *old_select;
3114 struct bgp_path_info_pair old_and_new;
3115 int debug = 0;
3116
3117 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
3118 if (dest)
3119 debug = bgp_debug_bestpath(dest);
3120 if (debug)
3121 zlog_debug(
3122 "%s: bgp delete in progress, ignoring event, p=%pBD(%s)",
3123 __func__, dest, bgp->name_pretty);
3124 return;
3125 }
3126 /* Is it end of initial update? (after startup) */
3127 if (!dest) {
3128 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
3129 sizeof(bgp->update_delay_zebra_resume_time));
3130
3131 bgp->main_zebra_update_hold = 0;
3132 FOREACH_AFI_SAFI (afi, safi) {
3133 if (bgp_fibupd_safi(safi))
3134 bgp_zebra_announce_table(bgp, afi, safi);
3135 }
3136 bgp->main_peers_update_hold = 0;
3137
3138 bgp_start_routeadv(bgp);
3139 return;
3140 }
3141
3142 const struct prefix *p = bgp_dest_get_prefix(dest);
3143
3144 debug = bgp_debug_bestpath(dest);
3145 if (debug)
3146 zlog_debug("%s: p=%pBD(%s) afi=%s, safi=%s start", __func__,
3147 dest, bgp->name_pretty, afi2str(afi),
3148 safi2str(safi));
3149
3150 /* The best path calculation for the route is deferred if
3151 * BGP_NODE_SELECT_DEFER is set
3152 */
3153 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3154 if (BGP_DEBUG(update, UPDATE_OUT))
3155 zlog_debug("SELECT_DEFER flag set for route %p(%s)",
3156 dest, bgp->name_pretty);
3157 return;
3158 }
3159
3160 /* Best path selection. */
3161 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
3162 afi, safi);
3163 old_select = old_and_new.old;
3164 new_select = old_and_new.new;
3165
3166 /* Do we need to allocate or free labels?
3167 * Right now, since we only deal with per-prefix labels, it is not
3168 * necessary to do this upon changes to best path. Exceptions:
3169 * - label index has changed -> recalculate resulting label
3170 * - path_info sub_type changed -> switch to/from implicit-null
3171 * - no valid label (due to removed static label binding) -> get new one
3172 */
3173 if (bgp->allocate_mpls_labels[afi][safi]) {
3174 if (new_select) {
3175 if (!old_select
3176 || bgp_label_index_differs(new_select, old_select)
3177 || new_select->sub_type != old_select->sub_type
3178 || !bgp_is_valid_label(&dest->local_label)) {
3179 /* Enforced penultimate hop popping:
3180 * implicit-null for local routes, aggregate
3181 * and redistributed routes
3182 */
3183 if (bgp_lu_need_imp_null(new_select)) {
3184 if (CHECK_FLAG(
3185 dest->flags,
3186 BGP_NODE_REGISTERED_FOR_LABEL)
3187 || CHECK_FLAG(
3188 dest->flags,
3189 BGP_NODE_LABEL_REQUESTED))
3190 bgp_unregister_for_label(dest);
3191 dest->local_label = mpls_lse_encode(
3192 MPLS_LABEL_IMPLICIT_NULL, 0, 0,
3193 1);
3194 bgp_set_valid_label(&dest->local_label);
3195 } else
3196 bgp_register_for_label(dest,
3197 new_select);
3198 }
3199 } else if (CHECK_FLAG(dest->flags,
3200 BGP_NODE_REGISTERED_FOR_LABEL)
3201 || CHECK_FLAG(dest->flags,
3202 BGP_NODE_LABEL_REQUESTED)) {
3203 bgp_unregister_for_label(dest);
3204 }
3205 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
3206 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
3207 bgp_unregister_for_label(dest);
3208 }
3209
3210 if (debug)
3211 zlog_debug(
3212 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
3213 __func__, dest, bgp->name_pretty, afi2str(afi),
3214 safi2str(safi), old_select, new_select);
3215
3216 /* If best route remains the same and this is not due to user-initiated
3217 * clear, see exactly what needs to be done.
3218 */
3219 if (old_select && old_select == new_select
3220 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
3221 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3222 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
3223 if (bgp_zebra_has_route_changed(old_select)) {
3224 #ifdef ENABLE_BGP_VNC
3225 vnc_import_bgp_add_route(bgp, p, old_select);
3226 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3227 #endif
3228 if (bgp_fibupd_safi(safi)
3229 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3230
3231 if (new_select->type == ZEBRA_ROUTE_BGP
3232 && (new_select->sub_type == BGP_ROUTE_NORMAL
3233 || new_select->sub_type
3234 == BGP_ROUTE_IMPORTED))
3235
3236 bgp_zebra_announce(dest, p, old_select,
3237 bgp, afi, safi);
3238 }
3239 }
3240
3241 /* If there is a change of interest to peers, reannounce the
3242 * route. */
3243 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3244 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3245 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3246 group_announce_route(bgp, afi, safi, dest, new_select);
3247
3248 /* unicast routes must also be annouced to
3249 * labeled-unicast update-groups */
3250 if (safi == SAFI_UNICAST)
3251 group_announce_route(bgp, afi,
3252 SAFI_LABELED_UNICAST, dest,
3253 new_select);
3254
3255 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3256 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3257 }
3258
3259 /* advertise/withdraw type-5 routes */
3260 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3261 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3262 bgp_process_evpn_route_injection(
3263 bgp, afi, safi, dest, old_select, old_select);
3264
3265 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3266 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3267 bgp_zebra_clear_route_change_flags(dest);
3268 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3269 return;
3270 }
3271
3272 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3273 */
3274 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3275
3276 /* bestpath has changed; bump version */
3277 if (old_select || new_select) {
3278 bgp_bump_version(dest);
3279
3280 if (!bgp->t_rmap_def_originate_eval) {
3281 bgp_lock(bgp);
3282 event_add_timer(
3283 bm->master,
3284 update_group_refresh_default_originate_route_map,
3285 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3286 &bgp->t_rmap_def_originate_eval);
3287 }
3288 }
3289
3290 if (old_select)
3291 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3292 if (new_select) {
3293 if (debug)
3294 zlog_debug("%s: setting SELECTED flag", __func__);
3295 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3296 bgp_path_info_unset_flag(dest, new_select,
3297 BGP_PATH_ATTR_CHANGED);
3298 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3299 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3300 }
3301
3302 #ifdef ENABLE_BGP_VNC
3303 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3304 if (old_select != new_select) {
3305 if (old_select) {
3306 vnc_import_bgp_exterior_del_route(bgp, p,
3307 old_select);
3308 vnc_import_bgp_del_route(bgp, p, old_select);
3309 }
3310 if (new_select) {
3311 vnc_import_bgp_exterior_add_route(bgp, p,
3312 new_select);
3313 vnc_import_bgp_add_route(bgp, p, new_select);
3314 }
3315 }
3316 }
3317 #endif
3318
3319 group_announce_route(bgp, afi, safi, dest, new_select);
3320
3321 /* unicast routes must also be annouced to labeled-unicast update-groups
3322 */
3323 if (safi == SAFI_UNICAST)
3324 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3325 new_select);
3326
3327 /* FIB update. */
3328 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3329 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3330
3331 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3332 && (new_select->sub_type == BGP_ROUTE_NORMAL
3333 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3334 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3335
3336 /* if this is an evpn imported type-5 prefix,
3337 * we need to withdraw the route first to clear
3338 * the nh neigh and the RMAC entry.
3339 */
3340 if (old_select &&
3341 is_route_parent_evpn(old_select))
3342 bgp_zebra_withdraw(p, old_select, bgp, safi);
3343
3344 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3345 } else {
3346 /* Withdraw the route from the kernel. */
3347 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3348 && (old_select->sub_type == BGP_ROUTE_NORMAL
3349 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3350 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3351
3352 bgp_zebra_withdraw(p, old_select, bgp, safi);
3353 }
3354 }
3355
3356 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3357 old_select);
3358
3359 /* Clear any route change flags. */
3360 bgp_zebra_clear_route_change_flags(dest);
3361
3362 /* Reap old select bgp_path_info, if it has been removed */
3363 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3364 bgp_path_info_reap(dest, old_select);
3365
3366 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3367 return;
3368 }
3369
3370 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3371 void bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3372 {
3373 struct bgp_dest *dest;
3374 int cnt = 0;
3375 struct afi_safi_info *thread_info;
3376
3377 if (bgp->gr_info[afi][safi].t_route_select) {
3378 struct event *t = bgp->gr_info[afi][safi].t_route_select;
3379
3380 thread_info = EVENT_ARG(t);
3381 XFREE(MTYPE_TMP, thread_info);
3382 EVENT_OFF(bgp->gr_info[afi][safi].t_route_select);
3383 }
3384
3385 if (BGP_DEBUG(update, UPDATE_OUT)) {
3386 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3387 get_afi_safi_str(afi, safi, false),
3388 bgp->gr_info[afi][safi].gr_deferred);
3389 }
3390
3391 /* Process the route list */
3392 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3393 dest && bgp->gr_info[afi][safi].gr_deferred != 0 &&
3394 cnt < BGP_MAX_BEST_ROUTE_SELECT;
3395 dest = bgp_route_next(dest)) {
3396 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3397 continue;
3398
3399 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3400 bgp->gr_info[afi][safi].gr_deferred--;
3401 bgp_process_main_one(bgp, dest, afi, safi);
3402 cnt++;
3403 }
3404 /* If iteration stopped before the entire table was traversed then the
3405 * node needs to be unlocked.
3406 */
3407 if (dest) {
3408 bgp_dest_unlock_node(dest);
3409 dest = NULL;
3410 }
3411
3412 /* Send EOR message when all routes are processed */
3413 if (!bgp->gr_info[afi][safi].gr_deferred) {
3414 bgp_send_delayed_eor(bgp);
3415 /* Send route processing complete message to RIB */
3416 bgp_zebra_update(bgp, afi, safi,
3417 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3418 return;
3419 }
3420
3421 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3422
3423 thread_info->afi = afi;
3424 thread_info->safi = safi;
3425 thread_info->bgp = bgp;
3426
3427 /* If there are more routes to be processed, start the
3428 * selection timer
3429 */
3430 event_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3431 BGP_ROUTE_SELECT_DELAY,
3432 &bgp->gr_info[afi][safi].t_route_select);
3433 }
3434
3435 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3436 {
3437 struct bgp_process_queue *pqnode = data;
3438 struct bgp *bgp = pqnode->bgp;
3439 struct bgp_table *table;
3440 struct bgp_dest *dest;
3441
3442 /* eoiu marker */
3443 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3444 bgp_process_main_one(bgp, NULL, 0, 0);
3445 /* should always have dedicated wq call */
3446 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3447 return WQ_SUCCESS;
3448 }
3449
3450 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3451 dest = STAILQ_FIRST(&pqnode->pqueue);
3452 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3453 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3454 table = bgp_dest_table(dest);
3455 /* note, new DESTs may be added as part of processing */
3456 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3457
3458 bgp_dest_unlock_node(dest);
3459 bgp_table_unlock(table);
3460 }
3461
3462 return WQ_SUCCESS;
3463 }
3464
3465 static void bgp_processq_del(struct work_queue *wq, void *data)
3466 {
3467 struct bgp_process_queue *pqnode = data;
3468
3469 bgp_unlock(pqnode->bgp);
3470
3471 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3472 }
3473
3474 void bgp_process_queue_init(struct bgp *bgp)
3475 {
3476 if (!bgp->process_queue) {
3477 char name[BUFSIZ];
3478
3479 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3480 bgp->process_queue = work_queue_new(bm->master, name);
3481 }
3482
3483 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3484 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3485 bgp->process_queue->spec.max_retries = 0;
3486 bgp->process_queue->spec.hold = 50;
3487 /* Use a higher yield value of 50ms for main queue processing */
3488 bgp->process_queue->spec.yield = 50 * 1000L;
3489 }
3490
3491 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3492 {
3493 struct bgp_process_queue *pqnode;
3494
3495 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3496 sizeof(struct bgp_process_queue));
3497
3498 /* unlocked in bgp_processq_del */
3499 pqnode->bgp = bgp_lock(bgp);
3500 STAILQ_INIT(&pqnode->pqueue);
3501
3502 return pqnode;
3503 }
3504
3505 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3506 {
3507 #define ARBITRARY_PROCESS_QLEN 10000
3508 struct work_queue *wq = bgp->process_queue;
3509 struct bgp_process_queue *pqnode;
3510 int pqnode_reuse = 0;
3511
3512 /* already scheduled for processing? */
3513 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3514 return;
3515
3516 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3517 * the workqueue
3518 */
3519 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3520 if (BGP_DEBUG(update, UPDATE_OUT))
3521 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3522 dest);
3523 return;
3524 }
3525
3526 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3527 if (BGP_DEBUG(update, UPDATE_OUT))
3528 zlog_debug(
3529 "Soft reconfigure table in progress for route %p",
3530 dest);
3531 return;
3532 }
3533
3534 if (wq == NULL)
3535 return;
3536
3537 /* Add route nodes to an existing work queue item until reaching the
3538 limit only if is from the same BGP view and it's not an EOIU marker
3539 */
3540 if (work_queue_item_count(wq)) {
3541 struct work_queue_item *item = work_queue_last_item(wq);
3542 pqnode = item->data;
3543
3544 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3545 || pqnode->bgp != bgp
3546 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3547 pqnode = bgp_processq_alloc(bgp);
3548 else
3549 pqnode_reuse = 1;
3550 } else
3551 pqnode = bgp_processq_alloc(bgp);
3552 /* all unlocked in bgp_process_wq */
3553 bgp_table_lock(bgp_dest_table(dest));
3554
3555 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3556 bgp_dest_lock_node(dest);
3557
3558 /* can't be enqueued twice */
3559 assert(STAILQ_NEXT(dest, pq) == NULL);
3560 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3561 pqnode->queued++;
3562
3563 if (!pqnode_reuse)
3564 work_queue_add(wq, pqnode);
3565
3566 return;
3567 }
3568
3569 void bgp_add_eoiu_mark(struct bgp *bgp)
3570 {
3571 struct bgp_process_queue *pqnode;
3572
3573 if (bgp->process_queue == NULL)
3574 return;
3575
3576 pqnode = bgp_processq_alloc(bgp);
3577
3578 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3579 work_queue_add(bgp->process_queue, pqnode);
3580 }
3581
3582 static void bgp_maximum_prefix_restart_timer(struct event *thread)
3583 {
3584 struct peer *peer;
3585
3586 peer = EVENT_ARG(thread);
3587 peer->t_pmax_restart = NULL;
3588
3589 if (bgp_debug_neighbor_events(peer))
3590 zlog_debug(
3591 "%s Maximum-prefix restart timer expired, restore peering",
3592 peer->host);
3593
3594 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3595 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3596 }
3597
3598 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3599 safi_t safi)
3600 {
3601 uint32_t count = 0;
3602 bool filtered = false;
3603 struct bgp_dest *dest;
3604 struct bgp_adj_in *ain;
3605 struct attr attr = {};
3606 struct bgp_table *table = peer->bgp->rib[afi][safi];
3607
3608 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3609 for (ain = dest->adj_in; ain; ain = ain->next) {
3610 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3611
3612 attr = *ain->attr;
3613
3614 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3615 == FILTER_DENY)
3616 filtered = true;
3617
3618 if (bgp_input_modifier(
3619 peer, rn_p, &attr, afi, safi,
3620 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3621 NULL, 0, NULL)
3622 == RMAP_DENY)
3623 filtered = true;
3624
3625 if (filtered)
3626 count++;
3627
3628 bgp_attr_flush(&attr);
3629 }
3630 }
3631
3632 return count;
3633 }
3634
3635 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3636 int always)
3637 {
3638 iana_afi_t pkt_afi;
3639 iana_safi_t pkt_safi;
3640 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3641 PEER_FLAG_MAX_PREFIX_FORCE))
3642 ? bgp_filtered_routes_count(peer, afi, safi)
3643 + peer->pcount[afi][safi]
3644 : peer->pcount[afi][safi];
3645
3646 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3647 return false;
3648
3649 if (pcount > peer->pmax[afi][safi]) {
3650 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3651 PEER_STATUS_PREFIX_LIMIT)
3652 && !always)
3653 return false;
3654
3655 zlog_info(
3656 "%%MAXPFXEXCEED: No. of %s prefix received from %pBP %u exceed, limit %u",
3657 get_afi_safi_str(afi, safi, false), peer, pcount,
3658 peer->pmax[afi][safi]);
3659 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3660
3661 if (CHECK_FLAG(peer->af_flags[afi][safi],
3662 PEER_FLAG_MAX_PREFIX_WARNING))
3663 return false;
3664
3665 /* Convert AFI, SAFI to values for packet. */
3666 pkt_afi = afi_int2iana(afi);
3667 pkt_safi = safi_int2iana(safi);
3668 {
3669 uint8_t ndata[7];
3670
3671 ndata[0] = (pkt_afi >> 8);
3672 ndata[1] = pkt_afi;
3673 ndata[2] = pkt_safi;
3674 ndata[3] = (peer->pmax[afi][safi] >> 24);
3675 ndata[4] = (peer->pmax[afi][safi] >> 16);
3676 ndata[5] = (peer->pmax[afi][safi] >> 8);
3677 ndata[6] = (peer->pmax[afi][safi]);
3678
3679 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3680 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3681 BGP_NOTIFY_CEASE_MAX_PREFIX,
3682 ndata, 7);
3683 }
3684
3685 /* Dynamic peers will just close their connection. */
3686 if (peer_dynamic_neighbor(peer))
3687 return true;
3688
3689 /* restart timer start */
3690 if (peer->pmax_restart[afi][safi]) {
3691 peer->v_pmax_restart =
3692 peer->pmax_restart[afi][safi] * 60;
3693
3694 if (bgp_debug_neighbor_events(peer))
3695 zlog_debug(
3696 "%pBP Maximum-prefix restart timer started for %d secs",
3697 peer, peer->v_pmax_restart);
3698
3699 BGP_TIMER_ON(peer->t_pmax_restart,
3700 bgp_maximum_prefix_restart_timer,
3701 peer->v_pmax_restart);
3702 }
3703
3704 return true;
3705 } else
3706 UNSET_FLAG(peer->af_sflags[afi][safi],
3707 PEER_STATUS_PREFIX_LIMIT);
3708
3709 if (pcount
3710 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3711 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3712 PEER_STATUS_PREFIX_THRESHOLD)
3713 && !always)
3714 return false;
3715
3716 zlog_info(
3717 "%%MAXPFX: No. of %s prefix received from %pBP reaches %u, max %u",
3718 get_afi_safi_str(afi, safi, false), peer, pcount,
3719 peer->pmax[afi][safi]);
3720 SET_FLAG(peer->af_sflags[afi][safi],
3721 PEER_STATUS_PREFIX_THRESHOLD);
3722 } else
3723 UNSET_FLAG(peer->af_sflags[afi][safi],
3724 PEER_STATUS_PREFIX_THRESHOLD);
3725 return false;
3726 }
3727
3728 /* Unconditionally remove the route from the RIB, without taking
3729 * damping into consideration (eg, because the session went down)
3730 */
3731 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3732 struct peer *peer, afi_t afi, safi_t safi)
3733 {
3734
3735 struct bgp *bgp = NULL;
3736 bool delete_route = false;
3737
3738 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3739 safi);
3740
3741 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3742 bgp_path_info_delete(dest, pi); /* keep historical info */
3743
3744 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3745 * flag
3746 */
3747 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3748 delete_route = true;
3749 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3750 delete_route = true;
3751 if (delete_route) {
3752 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3753 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3754 bgp = pi->peer->bgp;
3755 bgp->gr_info[afi][safi].gr_deferred--;
3756 }
3757 }
3758 }
3759
3760 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3761 bgp_process(peer->bgp, dest, afi, safi);
3762 }
3763
3764 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3765 struct peer *peer, afi_t afi, safi_t safi,
3766 struct prefix_rd *prd)
3767 {
3768 const struct prefix *p = bgp_dest_get_prefix(dest);
3769
3770 /* apply dampening, if result is suppressed, we'll be retaining
3771 * the bgp_path_info in the RIB for historical reference.
3772 */
3773 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3774 && peer->sort == BGP_PEER_EBGP)
3775 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3776 == BGP_DAMP_SUPPRESSED) {
3777 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3778 safi);
3779 return;
3780 }
3781
3782 #ifdef ENABLE_BGP_VNC
3783 if (safi == SAFI_MPLS_VPN) {
3784 struct bgp_dest *pdest = NULL;
3785 struct bgp_table *table = NULL;
3786
3787 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3788 (struct prefix *)prd);
3789 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3790 table = bgp_dest_get_bgp_table_info(pdest);
3791
3792 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3793 peer->bgp, prd, table, p, pi);
3794 }
3795 bgp_dest_unlock_node(pdest);
3796 }
3797 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3798 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3799
3800 vnc_import_bgp_del_route(peer->bgp, p, pi);
3801 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3802 }
3803 }
3804 #endif
3805
3806 /* If this is an EVPN route, process for un-import. */
3807 if (safi == SAFI_EVPN)
3808 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3809
3810 bgp_rib_remove(dest, pi, peer, afi, safi);
3811 }
3812
3813 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3814 struct peer *peer, struct attr *attr,
3815 struct bgp_dest *dest)
3816 {
3817 struct bgp_path_info *new;
3818
3819 /* Make new BGP info. */
3820 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3821 new->type = type;
3822 new->instance = instance;
3823 new->sub_type = sub_type;
3824 new->peer = peer;
3825 new->attr = attr;
3826 new->uptime = monotime(NULL);
3827 new->net = dest;
3828 return new;
3829 }
3830
3831 /* Check if received nexthop is valid or not. */
3832 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3833 uint8_t type, uint8_t stype, struct attr *attr,
3834 struct bgp_dest *dest)
3835 {
3836 bool ret = false;
3837 bool is_bgp_static_route =
3838 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3839 : false;
3840
3841 /*
3842 * Only validated for unicast and multicast currently.
3843 * Also valid for EVPN where the nexthop is an IP address.
3844 * If we are a bgp static route being checked then there is
3845 * no need to check to see if the nexthop is martian as
3846 * that it should be ok.
3847 */
3848 if (is_bgp_static_route ||
3849 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3850 return false;
3851
3852 /* If NEXT_HOP is present, validate it. */
3853 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3854 if (attr->nexthop.s_addr == INADDR_ANY ||
3855 !ipv4_unicast_valid(&attr->nexthop) ||
3856 bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3857 return true;
3858 }
3859
3860 /* If MP_NEXTHOP is present, validate it. */
3861 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3862 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3863 * it is not an IPv6 link-local address.
3864 *
3865 * If we receive an UPDATE with nexthop length set to 32 bytes
3866 * we shouldn't discard an UPDATE if it's set to (::).
3867 * The link-local (2st) is validated along the code path later.
3868 */
3869 if (attr->mp_nexthop_len) {
3870 switch (attr->mp_nexthop_len) {
3871 case BGP_ATTR_NHLEN_IPV4:
3872 case BGP_ATTR_NHLEN_VPNV4:
3873 ret = (attr->mp_nexthop_global_in.s_addr ==
3874 INADDR_ANY ||
3875 !ipv4_unicast_valid(
3876 &attr->mp_nexthop_global_in) ||
3877 bgp_nexthop_self(bgp, afi, type, stype, attr,
3878 dest));
3879 break;
3880
3881 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3882 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3883 ret = (IN6_IS_ADDR_UNSPECIFIED(
3884 &attr->mp_nexthop_global)
3885 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3886 || IN6_IS_ADDR_MULTICAST(
3887 &attr->mp_nexthop_global)
3888 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3889 dest));
3890 break;
3891 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3892 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3893 || IN6_IS_ADDR_MULTICAST(
3894 &attr->mp_nexthop_global)
3895 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3896 dest));
3897 break;
3898
3899 default:
3900 ret = true;
3901 break;
3902 }
3903 }
3904
3905 return ret;
3906 }
3907
3908 static void bgp_attr_add_no_export_community(struct attr *attr)
3909 {
3910 struct community *old;
3911 struct community *new;
3912 struct community *merge;
3913 struct community *no_export;
3914
3915 old = bgp_attr_get_community(attr);
3916 no_export = community_str2com("no-export");
3917
3918 assert(no_export);
3919
3920 if (old) {
3921 merge = community_merge(community_dup(old), no_export);
3922
3923 if (!old->refcnt)
3924 community_free(&old);
3925
3926 new = community_uniq_sort(merge);
3927 community_free(&merge);
3928 } else {
3929 new = community_dup(no_export);
3930 }
3931
3932 community_free(&no_export);
3933
3934 bgp_attr_set_community(attr, new);
3935 }
3936
3937 static bool bgp_accept_own(struct peer *peer, afi_t afi, safi_t safi,
3938 struct attr *attr, const struct prefix *prefix,
3939 int *sub_type)
3940 {
3941 struct listnode *node, *nnode;
3942 struct bgp *bgp;
3943 bool accept_own_found = false;
3944
3945 if (safi != SAFI_MPLS_VPN)
3946 return false;
3947
3948 /* Processing of the ACCEPT_OWN community is enabled by configuration */
3949 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ACCEPT_OWN))
3950 return false;
3951
3952 /* The route in question carries the ACCEPT_OWN community */
3953 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
3954 struct community *comm = bgp_attr_get_community(attr);
3955
3956 if (community_include(comm, COMMUNITY_ACCEPT_OWN))
3957 accept_own_found = true;
3958 }
3959
3960 /* The route in question is targeted to one or more destination VRFs
3961 * on the router (as determined by inspecting the Route Target(s)).
3962 */
3963 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3964 if (bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
3965 continue;
3966
3967 if (accept_own_found &&
3968 ecommunity_include(
3969 bgp->vpn_policy[afi]
3970 .rtlist[BGP_VPN_POLICY_DIR_TOVPN],
3971 bgp_attr_get_ecommunity(attr))) {
3972 if (bgp_debug_update(peer, prefix, NULL, 1))
3973 zlog_debug(
3974 "%pBP prefix %pFX has ORIGINATOR_ID, but it's accepted due to ACCEPT_OWN",
3975 peer, prefix);
3976
3977 /* Treat this route as imported, because it's leaked
3978 * already from another VRF, and we got an updated
3979 * version from route-reflector with ACCEPT_OWN
3980 * community.
3981 */
3982 *sub_type = BGP_ROUTE_IMPORTED;
3983
3984 return true;
3985 }
3986 }
3987
3988 return false;
3989 }
3990
3991 void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3992 struct attr *attr, afi_t afi, safi_t safi, int type,
3993 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3994 uint32_t num_labels, int soft_reconfig,
3995 struct bgp_route_evpn *evpn)
3996 {
3997 int ret;
3998 int aspath_loop_count = 0;
3999 struct bgp_dest *dest;
4000 struct bgp *bgp;
4001 struct attr new_attr;
4002 struct attr *attr_new;
4003 struct bgp_path_info *pi;
4004 struct bgp_path_info *new = NULL;
4005 struct bgp_path_info_extra *extra;
4006 const char *reason;
4007 char pfx_buf[BGP_PRD_PATH_STRLEN];
4008 int connected = 0;
4009 int do_loop_check = 1;
4010 int has_valid_label = 0;
4011 afi_t nh_afi;
4012 bool force_evpn_import = false;
4013 safi_t orig_safi = safi;
4014 bool leak_success = true;
4015 int allowas_in = 0;
4016
4017 if (frrtrace_enabled(frr_bgp, process_update)) {
4018 char pfxprint[PREFIX2STR_BUFFER];
4019
4020 prefix2str(p, pfxprint, sizeof(pfxprint));
4021 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
4022 afi, safi, attr);
4023 }
4024
4025 #ifdef ENABLE_BGP_VNC
4026 int vnc_implicit_withdraw = 0;
4027 #endif
4028 int same_attr = 0;
4029 const struct prefix *bgp_nht_param_prefix;
4030
4031 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
4032 if (orig_safi == SAFI_LABELED_UNICAST)
4033 safi = SAFI_UNICAST;
4034
4035 memset(&new_attr, 0, sizeof(new_attr));
4036 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
4037 new_attr.label = MPLS_INVALID_LABEL;
4038
4039 bgp = peer->bgp;
4040 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4041 /* TODO: Check to see if we can get rid of "is_valid_label" */
4042 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
4043 has_valid_label = (num_labels > 0) ? 1 : 0;
4044 else
4045 has_valid_label = bgp_is_valid_label(label);
4046
4047 if (has_valid_label)
4048 assert(label != NULL);
4049
4050 /* Update overlay index of the attribute */
4051 if (afi == AFI_L2VPN && evpn)
4052 memcpy(&attr->evpn_overlay, evpn,
4053 sizeof(struct bgp_route_evpn));
4054
4055 /* When peer's soft reconfiguration enabled. Record input packet in
4056 Adj-RIBs-In. */
4057 if (!soft_reconfig
4058 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4059 && peer != bgp->peer_self)
4060 bgp_adj_in_set(dest, peer, attr, addpath_id);
4061
4062 /* Update permitted loop count */
4063 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
4064 allowas_in = peer->allowas_in[afi][safi];
4065
4066 /* Check previously received route. */
4067 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4068 if (pi->peer == peer && pi->type == type
4069 && pi->sub_type == sub_type
4070 && pi->addpath_rx_id == addpath_id)
4071 break;
4072
4073 /* AS path local-as loop check. */
4074 if (peer->change_local_as) {
4075 if (allowas_in)
4076 aspath_loop_count = allowas_in;
4077 else if (!CHECK_FLAG(peer->flags,
4078 PEER_FLAG_LOCAL_AS_NO_PREPEND))
4079 aspath_loop_count = 1;
4080
4081 if (aspath_loop_check(attr->aspath, peer->change_local_as)
4082 > aspath_loop_count) {
4083 peer->stat_pfx_aspath_loop++;
4084 reason = "as-path contains our own AS;";
4085 goto filtered;
4086 }
4087 }
4088
4089 /* If the peer is configured for "allowas-in origin" and the last ASN in
4090 * the
4091 * as-path is our ASN then we do not need to call aspath_loop_check
4092 */
4093 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
4094 if (aspath_get_last_as(attr->aspath) == bgp->as)
4095 do_loop_check = 0;
4096
4097 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
4098 bgp_nht_param_prefix = NULL;
4099 else
4100 bgp_nht_param_prefix = p;
4101
4102 /* AS path loop check. */
4103 if (do_loop_check) {
4104 if (aspath_loop_check(attr->aspath, bgp->as) >
4105 peer->allowas_in[afi][safi]) {
4106 peer->stat_pfx_aspath_loop++;
4107 reason = "as-path contains our own AS;";
4108 goto filtered;
4109 }
4110 }
4111
4112 /* If we're a CONFED we need to loop check the CONFED ID too */
4113 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION) && do_loop_check)
4114 if (aspath_loop_check_confed(attr->aspath, bgp->confed_id) >
4115 peer->allowas_in[afi][safi]) {
4116 peer->stat_pfx_aspath_loop++;
4117 reason = "as-path contains our own confed AS;";
4118 goto filtered;
4119 }
4120
4121 /* Route reflector originator ID check. If ACCEPT_OWN mechanism is
4122 * enabled, then take care of that too.
4123 */
4124 bool accept_own = false;
4125
4126 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
4127 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
4128 accept_own =
4129 bgp_accept_own(peer, afi, safi, attr, p, &sub_type);
4130 if (!accept_own) {
4131 peer->stat_pfx_originator_loop++;
4132 reason = "originator is us;";
4133 goto filtered;
4134 }
4135 }
4136
4137 /* Route reflector cluster ID check. */
4138 if (bgp_cluster_filter(peer, attr)) {
4139 peer->stat_pfx_cluster_loop++;
4140 reason = "reflected from the same cluster;";
4141 goto filtered;
4142 }
4143
4144 /* Apply incoming filter. */
4145 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
4146 peer->stat_pfx_filter++;
4147 reason = "filter;";
4148 goto filtered;
4149 }
4150
4151 /* RFC 8212 to prevent route leaks.
4152 * This specification intends to improve this situation by requiring the
4153 * explicit configuration of both BGP Import and Export Policies for any
4154 * External BGP (EBGP) session such as customers, peers, or
4155 * confederation boundaries for all enabled address families. Through
4156 * codification of the aforementioned requirement, operators will
4157 * benefit from consistent behavior across different BGP
4158 * implementations.
4159 */
4160 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
4161 if (!bgp_inbound_policy_exists(peer,
4162 &peer->filter[afi][safi])) {
4163 reason = "inbound policy missing";
4164 if (monotime_since(&bgp->ebgprequirespolicywarning,
4165 NULL) > FIFTEENMINUTE2USEC ||
4166 bgp->ebgprequirespolicywarning.tv_sec == 0) {
4167 zlog_warn(
4168 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
4169 monotime(&bgp->ebgprequirespolicywarning);
4170 }
4171 goto filtered;
4172 }
4173
4174 /* draft-ietf-idr-deprecate-as-set-confed-set
4175 * Filter routes having AS_SET or AS_CONFED_SET in the path.
4176 * Eventually, This document (if approved) updates RFC 4271
4177 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
4178 * and obsoletes RFC 6472.
4179 */
4180 if (peer->bgp->reject_as_sets)
4181 if (aspath_check_as_sets(attr->aspath)) {
4182 reason =
4183 "as-path contains AS_SET or AS_CONFED_SET type;";
4184 goto filtered;
4185 }
4186
4187 new_attr = *attr;
4188
4189 /* Apply incoming route-map.
4190 * NB: new_attr may now contain newly allocated values from route-map
4191 * "set"
4192 * commands, so we need bgp_attr_flush in the error paths, until we
4193 * intern
4194 * the attr (which takes over the memory references) */
4195 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
4196 num_labels, dest)
4197 == RMAP_DENY) {
4198 peer->stat_pfx_filter++;
4199 reason = "route-map;";
4200 bgp_attr_flush(&new_attr);
4201 goto filtered;
4202 }
4203
4204 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
4205 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
4206 /* remove from RIB previous entry */
4207 bgp_zebra_withdraw(p, pi, bgp, safi);
4208 }
4209
4210 if (peer->sort == BGP_PEER_EBGP) {
4211
4212 /* rfc7999:
4213 * A BGP speaker receiving an announcement tagged with the
4214 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
4215 * NO_EXPORT community as defined in RFC1997, or a
4216 * similar community, to prevent propagation of the
4217 * prefix outside the local AS. The community to prevent
4218 * propagation SHOULD be chosen according to the operator's
4219 * routing policy.
4220 */
4221 if (bgp_attr_get_community(&new_attr) &&
4222 community_include(bgp_attr_get_community(&new_attr),
4223 COMMUNITY_BLACKHOLE))
4224 bgp_attr_add_no_export_community(&new_attr);
4225
4226 /* If we receive the graceful-shutdown community from an eBGP
4227 * peer we must lower local-preference */
4228 if (bgp_attr_get_community(&new_attr) &&
4229 community_include(bgp_attr_get_community(&new_attr),
4230 COMMUNITY_GSHUT)) {
4231 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
4232 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
4233
4234 /* If graceful-shutdown is configured globally or
4235 * per neighbor, then add the GSHUT community to
4236 * all paths received from eBGP peers. */
4237 } else if (bgp_in_graceful_shutdown(peer->bgp) ||
4238 CHECK_FLAG(peer->flags, PEER_FLAG_GRACEFUL_SHUTDOWN))
4239 bgp_attr_add_gshut_community(&new_attr);
4240 }
4241
4242 /* next hop check. */
4243 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD) &&
4244 bgp_update_martian_nexthop(bgp, afi, safi, type, sub_type,
4245 &new_attr, dest)) {
4246 peer->stat_pfx_nh_invalid++;
4247 reason = "martian or self next-hop;";
4248 bgp_attr_flush(&new_attr);
4249 goto filtered;
4250 }
4251
4252 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
4253 peer->stat_pfx_nh_invalid++;
4254 reason = "self mac;";
4255 bgp_attr_flush(&new_attr);
4256 goto filtered;
4257 }
4258
4259 if (bgp_check_role_applicability(afi, safi) &&
4260 bgp_otc_filter(peer, &new_attr)) {
4261 reason = "failing otc validation";
4262 bgp_attr_flush(&new_attr);
4263 goto filtered;
4264 }
4265
4266 /* If neighbor soo is configured, tag all incoming routes with
4267 * this SoO tag and then filter out advertisements in
4268 * subgroup_announce_check() if it matches the configured SoO
4269 * on the other peer.
4270 */
4271 if (peer->soo[afi][safi]) {
4272 struct ecommunity *old_ecomm =
4273 bgp_attr_get_ecommunity(&new_attr);
4274 struct ecommunity *ecomm_soo = peer->soo[afi][safi];
4275 struct ecommunity *new_ecomm;
4276
4277 if (old_ecomm) {
4278 new_ecomm = ecommunity_merge(ecommunity_dup(old_ecomm),
4279 ecomm_soo);
4280
4281 if (!old_ecomm->refcnt)
4282 ecommunity_free(&old_ecomm);
4283 } else {
4284 new_ecomm = ecommunity_dup(ecomm_soo);
4285 }
4286
4287 bgp_attr_set_ecommunity(&new_attr, new_ecomm);
4288 }
4289
4290 attr_new = bgp_attr_intern(&new_attr);
4291
4292 /* If the update is implicit withdraw. */
4293 if (pi) {
4294 pi->uptime = monotime(NULL);
4295 same_attr = attrhash_cmp(pi->attr, attr_new);
4296
4297 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4298
4299 /* Same attribute comes in. */
4300 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
4301 && same_attr
4302 && (!has_valid_label
4303 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
4304 num_labels * sizeof(mpls_label_t))
4305 == 0)) {
4306 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4307 BGP_CONFIG_DAMPENING)
4308 && peer->sort == BGP_PEER_EBGP
4309 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4310 if (bgp_debug_update(peer, p, NULL, 1)) {
4311 bgp_debug_rdpfxpath2str(
4312 afi, safi, prd, p, label,
4313 num_labels, addpath_id ? 1 : 0,
4314 addpath_id, evpn, pfx_buf,
4315 sizeof(pfx_buf));
4316 zlog_debug("%pBP rcvd %s", peer,
4317 pfx_buf);
4318 }
4319
4320 if (bgp_damp_update(pi, dest, afi, safi)
4321 != BGP_DAMP_SUPPRESSED) {
4322 bgp_aggregate_increment(bgp, p, pi, afi,
4323 safi);
4324 bgp_process(bgp, dest, afi, safi);
4325 }
4326 } else /* Duplicate - odd */
4327 {
4328 if (bgp_debug_update(peer, p, NULL, 1)) {
4329 if (!peer->rcvd_attr_printed) {
4330 zlog_debug(
4331 "%pBP rcvd UPDATE w/ attr: %s",
4332 peer,
4333 peer->rcvd_attr_str);
4334 peer->rcvd_attr_printed = 1;
4335 }
4336
4337 bgp_debug_rdpfxpath2str(
4338 afi, safi, prd, p, label,
4339 num_labels, addpath_id ? 1 : 0,
4340 addpath_id, evpn, pfx_buf,
4341 sizeof(pfx_buf));
4342 zlog_debug(
4343 "%pBP rcvd %s...duplicate ignored",
4344 peer, pfx_buf);
4345 }
4346
4347 /* graceful restart STALE flag unset. */
4348 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4349 bgp_path_info_unset_flag(
4350 dest, pi, BGP_PATH_STALE);
4351 bgp_dest_set_defer_flag(dest, false);
4352 bgp_process(bgp, dest, afi, safi);
4353 }
4354 }
4355
4356 bgp_dest_unlock_node(dest);
4357 bgp_attr_unintern(&attr_new);
4358
4359 return;
4360 }
4361
4362 /* Withdraw/Announce before we fully processed the withdraw */
4363 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4364 if (bgp_debug_update(peer, p, NULL, 1)) {
4365 bgp_debug_rdpfxpath2str(
4366 afi, safi, prd, p, label, num_labels,
4367 addpath_id ? 1 : 0, addpath_id, evpn,
4368 pfx_buf, sizeof(pfx_buf));
4369 zlog_debug(
4370 "%pBP rcvd %s, flapped quicker than processing",
4371 peer, pfx_buf);
4372 }
4373
4374 bgp_path_info_restore(dest, pi);
4375
4376 /*
4377 * If the BGP_PATH_REMOVED flag is set, then EVPN
4378 * routes would have been unimported already when a
4379 * prior BGP withdraw processing happened. Such routes
4380 * need to be imported again, so flag accordingly.
4381 */
4382 force_evpn_import = true;
4383 } else {
4384 /* implicit withdraw, decrement aggregate and pcount
4385 * here. only if update is accepted, they'll increment
4386 * below.
4387 */
4388 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4389 }
4390
4391 /* Received Logging. */
4392 if (bgp_debug_update(peer, p, NULL, 1)) {
4393 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4394 num_labels, addpath_id ? 1 : 0,
4395 addpath_id, evpn, pfx_buf,
4396 sizeof(pfx_buf));
4397 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4398 }
4399
4400 /* graceful restart STALE flag unset. */
4401 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4402 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4403 bgp_dest_set_defer_flag(dest, false);
4404 }
4405
4406 /* The attribute is changed. */
4407 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4408
4409 /* Update bgp route dampening information. */
4410 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4411 && peer->sort == BGP_PEER_EBGP) {
4412 /* This is implicit withdraw so we should update
4413 dampening
4414 information. */
4415 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4416 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4417 }
4418 #ifdef ENABLE_BGP_VNC
4419 if (safi == SAFI_MPLS_VPN) {
4420 struct bgp_dest *pdest = NULL;
4421 struct bgp_table *table = NULL;
4422
4423 pdest = bgp_node_get(bgp->rib[afi][safi],
4424 (struct prefix *)prd);
4425 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4426 table = bgp_dest_get_bgp_table_info(pdest);
4427
4428 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4429 bgp, prd, table, p, pi);
4430 }
4431 bgp_dest_unlock_node(pdest);
4432 }
4433 if ((afi == AFI_IP || afi == AFI_IP6)
4434 && (safi == SAFI_UNICAST)) {
4435 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4436 /*
4437 * Implicit withdraw case.
4438 */
4439 ++vnc_implicit_withdraw;
4440 vnc_import_bgp_del_route(bgp, p, pi);
4441 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4442 }
4443 }
4444 #endif
4445
4446 /* Special handling for EVPN update of an existing route. If the
4447 * extended community attribute has changed, we need to
4448 * un-import
4449 * the route using its existing extended community. It will be
4450 * subsequently processed for import with the new extended
4451 * community.
4452 */
4453 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4454 && !same_attr) {
4455 if ((pi->attr->flag
4456 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4457 && (attr_new->flag
4458 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4459 int cmp;
4460
4461 cmp = ecommunity_cmp(
4462 bgp_attr_get_ecommunity(pi->attr),
4463 bgp_attr_get_ecommunity(attr_new));
4464 if (!cmp) {
4465 if (bgp_debug_update(peer, p, NULL, 1))
4466 zlog_debug(
4467 "Change in EXT-COMM, existing %s new %s",
4468 ecommunity_str(
4469 bgp_attr_get_ecommunity(
4470 pi->attr)),
4471 ecommunity_str(
4472 bgp_attr_get_ecommunity(
4473 attr_new)));
4474 if (safi == SAFI_EVPN)
4475 bgp_evpn_unimport_route(
4476 bgp, afi, safi, p, pi);
4477 else /* SAFI_MPLS_VPN */
4478 vpn_leak_to_vrf_withdraw(pi);
4479 }
4480 }
4481 }
4482
4483 /* Update to new attribute. */
4484 bgp_attr_unintern(&pi->attr);
4485 pi->attr = attr_new;
4486
4487 /* Update MPLS label */
4488 if (has_valid_label) {
4489 extra = bgp_path_info_extra_get(pi);
4490 if (extra->label != label) {
4491 memcpy(&extra->label, label,
4492 num_labels * sizeof(mpls_label_t));
4493 extra->num_labels = num_labels;
4494 }
4495 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4496 bgp_set_valid_label(&extra->label[0]);
4497 }
4498
4499 /* Update SRv6 SID */
4500 if (attr->srv6_l3vpn) {
4501 extra = bgp_path_info_extra_get(pi);
4502 if (sid_diff(&extra->sid[0].sid,
4503 &attr->srv6_l3vpn->sid)) {
4504 sid_copy(&extra->sid[0].sid,
4505 &attr->srv6_l3vpn->sid);
4506 extra->num_sids = 1;
4507
4508 extra->sid[0].loc_block_len = 0;
4509 extra->sid[0].loc_node_len = 0;
4510 extra->sid[0].func_len = 0;
4511 extra->sid[0].arg_len = 0;
4512 extra->sid[0].transposition_len = 0;
4513 extra->sid[0].transposition_offset = 0;
4514
4515 if (attr->srv6_l3vpn->loc_block_len != 0) {
4516 extra->sid[0].loc_block_len =
4517 attr->srv6_l3vpn->loc_block_len;
4518 extra->sid[0].loc_node_len =
4519 attr->srv6_l3vpn->loc_node_len;
4520 extra->sid[0].func_len =
4521 attr->srv6_l3vpn->func_len;
4522 extra->sid[0].arg_len =
4523 attr->srv6_l3vpn->arg_len;
4524 extra->sid[0].transposition_len =
4525 attr->srv6_l3vpn
4526 ->transposition_len;
4527 extra->sid[0].transposition_offset =
4528 attr->srv6_l3vpn
4529 ->transposition_offset;
4530 }
4531 }
4532 } else if (attr->srv6_vpn) {
4533 extra = bgp_path_info_extra_get(pi);
4534 if (sid_diff(&extra->sid[0].sid,
4535 &attr->srv6_vpn->sid)) {
4536 sid_copy(&extra->sid[0].sid,
4537 &attr->srv6_vpn->sid);
4538 extra->num_sids = 1;
4539 }
4540 }
4541
4542 #ifdef ENABLE_BGP_VNC
4543 if ((afi == AFI_IP || afi == AFI_IP6)
4544 && (safi == SAFI_UNICAST)) {
4545 if (vnc_implicit_withdraw) {
4546 /*
4547 * Add back the route with its new attributes
4548 * (e.g., nexthop).
4549 * The route is still selected, until the route
4550 * selection
4551 * queued by bgp_process actually runs. We have
4552 * to make this
4553 * update to the VNC side immediately to avoid
4554 * racing against
4555 * configuration changes (e.g., route-map
4556 * changes) which
4557 * trigger re-importation of the entire RIB.
4558 */
4559 vnc_import_bgp_add_route(bgp, p, pi);
4560 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4561 }
4562 }
4563 #endif
4564
4565 /* Update bgp route dampening information. */
4566 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4567 && peer->sort == BGP_PEER_EBGP) {
4568 /* Now we do normal update dampening. */
4569 ret = bgp_damp_update(pi, dest, afi, safi);
4570 if (ret == BGP_DAMP_SUPPRESSED) {
4571 bgp_dest_unlock_node(dest);
4572 return;
4573 }
4574 }
4575
4576 /* Nexthop reachability check - for unicast and
4577 * labeled-unicast.. */
4578 if (((afi == AFI_IP || afi == AFI_IP6)
4579 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4580 || (safi == SAFI_EVPN &&
4581 bgp_evpn_is_prefix_nht_supported(p))) {
4582 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4583 && peer->ttl == BGP_DEFAULT_TTL
4584 && !CHECK_FLAG(peer->flags,
4585 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4586 && !CHECK_FLAG(bgp->flags,
4587 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4588 connected = 1;
4589 else
4590 connected = 0;
4591
4592 struct bgp *bgp_nexthop = bgp;
4593
4594 if (pi->extra && pi->extra->bgp_orig)
4595 bgp_nexthop = pi->extra->bgp_orig;
4596
4597 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4598
4599 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4600 safi, pi, NULL, connected,
4601 bgp_nht_param_prefix) ||
4602 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4603 bgp_path_info_set_flag(dest, pi,
4604 BGP_PATH_VALID);
4605 else {
4606 if (BGP_DEBUG(nht, NHT)) {
4607 zlog_debug("%s(%pI4): NH unresolved",
4608 __func__,
4609 (in_addr_t *)&attr_new->nexthop);
4610 }
4611 bgp_path_info_unset_flag(dest, pi,
4612 BGP_PATH_VALID);
4613 }
4614 } else {
4615 if (accept_own)
4616 bgp_path_info_set_flag(dest, pi,
4617 BGP_PATH_ACCEPT_OWN);
4618
4619 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4620 }
4621
4622 #ifdef ENABLE_BGP_VNC
4623 if (safi == SAFI_MPLS_VPN) {
4624 struct bgp_dest *pdest = NULL;
4625 struct bgp_table *table = NULL;
4626
4627 pdest = bgp_node_get(bgp->rib[afi][safi],
4628 (struct prefix *)prd);
4629 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4630 table = bgp_dest_get_bgp_table_info(pdest);
4631
4632 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4633 bgp, prd, table, p, pi);
4634 }
4635 bgp_dest_unlock_node(pdest);
4636 }
4637 #endif
4638
4639 /* If this is an EVPN route and some attribute has changed,
4640 * or we are explicitly told to perform a route import, process
4641 * route for import. If the extended community has changed, we
4642 * would
4643 * have done the un-import earlier and the import would result
4644 * in the
4645 * route getting injected into appropriate L2 VNIs. If it is
4646 * just
4647 * some other attribute change, the import will result in
4648 * updating
4649 * the attributes for the route in the VNI(s).
4650 */
4651 if (safi == SAFI_EVPN &&
4652 (!same_attr || force_evpn_import) &&
4653 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4654 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4655
4656 /* Process change. */
4657 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4658
4659 bgp_process(bgp, dest, afi, safi);
4660 bgp_dest_unlock_node(dest);
4661
4662 if (SAFI_UNICAST == safi
4663 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4664 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4665
4666 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4667 }
4668 if ((SAFI_MPLS_VPN == safi)
4669 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4670 leak_success = vpn_leak_to_vrf_update(bgp, pi, prd);
4671 }
4672
4673 #ifdef ENABLE_BGP_VNC
4674 if (SAFI_MPLS_VPN == safi) {
4675 mpls_label_t label_decoded = decode_label(label);
4676
4677 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4678 type, sub_type, &label_decoded);
4679 }
4680 if (SAFI_ENCAP == safi) {
4681 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4682 type, sub_type, NULL);
4683 }
4684 #endif
4685 if ((safi == SAFI_MPLS_VPN) &&
4686 !CHECK_FLAG(bgp->af_flags[afi][safi],
4687 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4688 !leak_success) {
4689 bgp_unlink_nexthop(pi);
4690 bgp_path_info_delete(dest, pi);
4691 }
4692 return;
4693 } // End of implicit withdraw
4694
4695 /* Received Logging. */
4696 if (bgp_debug_update(peer, p, NULL, 1)) {
4697 if (!peer->rcvd_attr_printed) {
4698 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4699 peer->rcvd_attr_str);
4700 peer->rcvd_attr_printed = 1;
4701 }
4702
4703 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4704 addpath_id ? 1 : 0, addpath_id, evpn,
4705 pfx_buf, sizeof(pfx_buf));
4706 zlog_debug("%pBP rcvd %s", peer, pfx_buf);
4707 }
4708
4709 /* Make new BGP info. */
4710 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4711
4712 /* Update MPLS label */
4713 if (has_valid_label) {
4714 extra = bgp_path_info_extra_get(new);
4715 if (extra->label != label) {
4716 memcpy(&extra->label, label,
4717 num_labels * sizeof(mpls_label_t));
4718 extra->num_labels = num_labels;
4719 }
4720 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4721 bgp_set_valid_label(&extra->label[0]);
4722 }
4723
4724 /* Update SRv6 SID */
4725 if (safi == SAFI_MPLS_VPN) {
4726 extra = bgp_path_info_extra_get(new);
4727 if (attr->srv6_l3vpn) {
4728 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4729 extra->num_sids = 1;
4730
4731 extra->sid[0].loc_block_len =
4732 attr->srv6_l3vpn->loc_block_len;
4733 extra->sid[0].loc_node_len =
4734 attr->srv6_l3vpn->loc_node_len;
4735 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4736 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4737 extra->sid[0].transposition_len =
4738 attr->srv6_l3vpn->transposition_len;
4739 extra->sid[0].transposition_offset =
4740 attr->srv6_l3vpn->transposition_offset;
4741 } else if (attr->srv6_vpn) {
4742 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4743 extra->num_sids = 1;
4744 }
4745 }
4746
4747 /* Nexthop reachability check. */
4748 if (((afi == AFI_IP || afi == AFI_IP6)
4749 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4750 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4751 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4752 && peer->ttl == BGP_DEFAULT_TTL
4753 && !CHECK_FLAG(peer->flags,
4754 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4755 && !CHECK_FLAG(bgp->flags,
4756 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4757 connected = 1;
4758 else
4759 connected = 0;
4760
4761 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4762
4763 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4764 connected, bgp_nht_param_prefix) ||
4765 CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4766 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4767 else {
4768 if (BGP_DEBUG(nht, NHT))
4769 zlog_debug("%s(%pI4): NH unresolved", __func__,
4770 &attr_new->nexthop);
4771 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4772 }
4773 } else {
4774 if (accept_own)
4775 bgp_path_info_set_flag(dest, new, BGP_PATH_ACCEPT_OWN);
4776
4777 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4778 }
4779
4780 /* If maximum prefix count is configured and current prefix
4781 * count exeed it.
4782 */
4783 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
4784 reason = "maximum-prefix overflow";
4785 bgp_attr_flush(&new_attr);
4786 goto filtered;
4787 }
4788
4789 /* Addpath ID */
4790 new->addpath_rx_id = addpath_id;
4791
4792 /* Increment prefix */
4793 bgp_aggregate_increment(bgp, p, new, afi, safi);
4794
4795 /* Register new BGP information. */
4796 bgp_path_info_add(dest, new);
4797
4798 /* route_node_get lock */
4799 bgp_dest_unlock_node(dest);
4800
4801 #ifdef ENABLE_BGP_VNC
4802 if (safi == SAFI_MPLS_VPN) {
4803 struct bgp_dest *pdest = NULL;
4804 struct bgp_table *table = NULL;
4805
4806 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4807 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4808 table = bgp_dest_get_bgp_table_info(pdest);
4809
4810 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4811 bgp, prd, table, p, new);
4812 }
4813 bgp_dest_unlock_node(pdest);
4814 }
4815 #endif
4816
4817 /* If this is an EVPN route, process for import. */
4818 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4819 bgp_evpn_import_route(bgp, afi, safi, p, new);
4820
4821 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4822
4823 /* Process change. */
4824 bgp_process(bgp, dest, afi, safi);
4825
4826 if (SAFI_UNICAST == safi
4827 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4828 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4829 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4830 }
4831 if ((SAFI_MPLS_VPN == safi)
4832 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4833 leak_success = vpn_leak_to_vrf_update(bgp, new, prd);
4834 }
4835 #ifdef ENABLE_BGP_VNC
4836 if (SAFI_MPLS_VPN == safi) {
4837 mpls_label_t label_decoded = decode_label(label);
4838
4839 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4840 sub_type, &label_decoded);
4841 }
4842 if (SAFI_ENCAP == safi) {
4843 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4844 sub_type, NULL);
4845 }
4846 #endif
4847 if ((safi == SAFI_MPLS_VPN) &&
4848 !CHECK_FLAG(bgp->af_flags[afi][safi],
4849 BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
4850 !leak_success) {
4851 bgp_unlink_nexthop(new);
4852 bgp_path_info_delete(dest, new);
4853 }
4854
4855 return;
4856
4857 /* This BGP update is filtered. Log the reason then update BGP
4858 entry. */
4859 filtered:
4860 if (new) {
4861 bgp_unlink_nexthop(new);
4862 bgp_path_info_delete(dest, new);
4863 bgp_path_info_extra_free(&new->extra);
4864 XFREE(MTYPE_BGP_ROUTE, new);
4865 }
4866
4867 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4868
4869 if (bgp_debug_update(peer, p, NULL, 1)) {
4870 if (!peer->rcvd_attr_printed) {
4871 zlog_debug("%pBP rcvd UPDATE w/ attr: %s", peer,
4872 peer->rcvd_attr_str);
4873 peer->rcvd_attr_printed = 1;
4874 }
4875
4876 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4877 addpath_id ? 1 : 0, addpath_id, evpn,
4878 pfx_buf, sizeof(pfx_buf));
4879 zlog_debug("%pBP rcvd UPDATE about %s -- DENIED due to: %s",
4880 peer, pfx_buf, reason);
4881 }
4882
4883 if (pi) {
4884 /* If this is an EVPN route, un-import it as it is now filtered.
4885 */
4886 if (safi == SAFI_EVPN)
4887 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4888
4889 if (SAFI_UNICAST == safi
4890 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4891 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4892
4893 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4894 }
4895 if ((SAFI_MPLS_VPN == safi)
4896 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4897
4898 vpn_leak_to_vrf_withdraw(pi);
4899 }
4900
4901 bgp_rib_remove(dest, pi, peer, afi, safi);
4902 }
4903
4904 bgp_dest_unlock_node(dest);
4905
4906 #ifdef ENABLE_BGP_VNC
4907 /*
4908 * Filtered update is treated as an implicit withdrawal (see
4909 * bgp_rib_remove()
4910 * a few lines above)
4911 */
4912 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4913 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4914 0);
4915 }
4916 #endif
4917
4918 return;
4919 }
4920
4921 void bgp_withdraw(struct peer *peer, const struct prefix *p,
4922 uint32_t addpath_id, afi_t afi, safi_t safi, int type,
4923 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4924 uint32_t num_labels, struct bgp_route_evpn *evpn)
4925 {
4926 struct bgp *bgp;
4927 char pfx_buf[BGP_PRD_PATH_STRLEN];
4928 struct bgp_dest *dest;
4929 struct bgp_path_info *pi;
4930
4931 #ifdef ENABLE_BGP_VNC
4932 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4933 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4934 0);
4935 }
4936 #endif
4937
4938 bgp = peer->bgp;
4939
4940 /* Lookup node. */
4941 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4942
4943 /* If peer is soft reconfiguration enabled. Record input packet for
4944 * further calculation.
4945 *
4946 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4947 * routes that are filtered. This tanks out Quagga RS pretty badly due
4948 * to
4949 * the iteration over all RS clients.
4950 * Since we need to remove the entry from adj_in anyway, do that first
4951 * and
4952 * if there was no entry, we don't need to do anything more.
4953 */
4954 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4955 && peer != bgp->peer_self)
4956 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4957 peer->stat_pfx_dup_withdraw++;
4958
4959 if (bgp_debug_update(peer, p, NULL, 1)) {
4960 bgp_debug_rdpfxpath2str(
4961 afi, safi, prd, p, label, num_labels,
4962 addpath_id ? 1 : 0, addpath_id, NULL,
4963 pfx_buf, sizeof(pfx_buf));
4964 zlog_debug(
4965 "%s withdrawing route %s not in adj-in",
4966 peer->host, pfx_buf);
4967 }
4968 bgp_dest_unlock_node(dest);
4969 return;
4970 }
4971
4972 /* Lookup withdrawn route. */
4973 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4974 if (pi->peer == peer && pi->type == type
4975 && pi->sub_type == sub_type
4976 && pi->addpath_rx_id == addpath_id)
4977 break;
4978
4979 /* Logging. */
4980 if (bgp_debug_update(peer, p, NULL, 1)) {
4981 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4982 addpath_id ? 1 : 0, addpath_id, NULL,
4983 pfx_buf, sizeof(pfx_buf));
4984 zlog_debug("%pBP rcvd UPDATE about %s -- withdrawn", peer,
4985 pfx_buf);
4986 }
4987
4988 /* Withdraw specified route from routing table. */
4989 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4990 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4991 if (SAFI_UNICAST == safi
4992 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4993 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4994 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4995 }
4996 if ((SAFI_MPLS_VPN == safi)
4997 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4998
4999 vpn_leak_to_vrf_withdraw(pi);
5000 }
5001 } else if (bgp_debug_update(peer, p, NULL, 1)) {
5002 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
5003 addpath_id ? 1 : 0, addpath_id, NULL,
5004 pfx_buf, sizeof(pfx_buf));
5005 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
5006 }
5007
5008 /* Unlock bgp_node_get() lock. */
5009 bgp_dest_unlock_node(dest);
5010
5011 return;
5012 }
5013
5014 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
5015 int withdraw)
5016 {
5017 struct update_subgroup *subgrp;
5018 subgrp = peer_subgroup(peer, afi, safi);
5019 subgroup_default_originate(subgrp, withdraw);
5020 }
5021
5022
5023 /*
5024 * bgp_stop_announce_route_timer
5025 */
5026 void bgp_stop_announce_route_timer(struct peer_af *paf)
5027 {
5028 if (!paf->t_announce_route)
5029 return;
5030
5031 EVENT_OFF(paf->t_announce_route);
5032 }
5033
5034 /*
5035 * bgp_announce_route_timer_expired
5036 *
5037 * Callback that is invoked when the route announcement timer for a
5038 * peer_af expires.
5039 */
5040 static void bgp_announce_route_timer_expired(struct event *t)
5041 {
5042 struct peer_af *paf;
5043 struct peer *peer;
5044
5045 paf = EVENT_ARG(t);
5046 peer = paf->peer;
5047
5048 if (!peer_established(peer))
5049 return;
5050
5051 if (!peer->afc_nego[paf->afi][paf->safi])
5052 return;
5053
5054 peer_af_announce_route(paf, 1);
5055
5056 /* Notify BGP conditional advertisement scanner percess */
5057 peer->advmap_config_change[paf->afi][paf->safi] = true;
5058 }
5059
5060 /*
5061 * bgp_announce_route
5062 *
5063 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
5064 *
5065 * if force is true we will force an update even if the update
5066 * limiting code is attempted to kick in.
5067 */
5068 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
5069 {
5070 struct peer_af *paf;
5071 struct update_subgroup *subgrp;
5072
5073 paf = peer_af_find(peer, afi, safi);
5074 if (!paf)
5075 return;
5076 subgrp = PAF_SUBGRP(paf);
5077
5078 /*
5079 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
5080 * or a refresh has already been triggered.
5081 */
5082 if (!subgrp || paf->t_announce_route)
5083 return;
5084
5085 if (force)
5086 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
5087
5088 /*
5089 * Start a timer to stagger/delay the announce. This serves
5090 * two purposes - announcement can potentially be combined for
5091 * multiple peers and the announcement doesn't happen in the
5092 * vty context.
5093 */
5094 event_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
5095 (subgrp->peer_count == 1)
5096 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
5097 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
5098 &paf->t_announce_route);
5099 }
5100
5101 /*
5102 * Announce routes from all AF tables to a peer.
5103 *
5104 * This should ONLY be called when there is a need to refresh the
5105 * routes to the peer based on a policy change for this peer alone
5106 * or a route refresh request received from the peer.
5107 * The operation will result in splitting the peer from its existing
5108 * subgroups and putting it in new subgroups.
5109 */
5110 void bgp_announce_route_all(struct peer *peer)
5111 {
5112 afi_t afi;
5113 safi_t safi;
5114
5115 FOREACH_AFI_SAFI (afi, safi)
5116 bgp_announce_route(peer, afi, safi, false);
5117 }
5118
5119 /* Flag or unflag bgp_dest to determine whether it should be treated by
5120 * bgp_soft_reconfig_table_task.
5121 * Flag if flag is true. Unflag if flag is false.
5122 */
5123 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
5124 {
5125 struct bgp_dest *dest;
5126 struct bgp_adj_in *ain;
5127
5128 if (!table)
5129 return;
5130
5131 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5132 for (ain = dest->adj_in; ain; ain = ain->next) {
5133 if (ain->peer != NULL)
5134 break;
5135 }
5136 if (flag && ain != NULL && ain->peer != NULL)
5137 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5138 else
5139 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5140 }
5141 }
5142
5143 static void bgp_soft_reconfig_table_update(struct peer *peer,
5144 struct bgp_dest *dest,
5145 struct bgp_adj_in *ain, afi_t afi,
5146 safi_t safi, struct prefix_rd *prd)
5147 {
5148 struct bgp_path_info *pi;
5149 uint32_t num_labels = 0;
5150 mpls_label_t *label_pnt = NULL;
5151 struct bgp_route_evpn evpn;
5152
5153 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5154 if (pi->peer == peer)
5155 break;
5156
5157 if (pi && pi->extra)
5158 num_labels = pi->extra->num_labels;
5159 if (num_labels)
5160 label_pnt = &pi->extra->label[0];
5161 if (pi)
5162 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
5163 sizeof(evpn));
5164 else
5165 memset(&evpn, 0, sizeof(evpn));
5166
5167 bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
5168 ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
5169 label_pnt, num_labels, 1, &evpn);
5170 }
5171
5172 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
5173 struct bgp_table *table,
5174 struct prefix_rd *prd)
5175 {
5176 struct bgp_dest *dest;
5177 struct bgp_adj_in *ain;
5178
5179 if (!table)
5180 table = peer->bgp->rib[afi][safi];
5181
5182 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5183 for (ain = dest->adj_in; ain; ain = ain->next) {
5184 if (ain->peer != peer)
5185 continue;
5186
5187 bgp_soft_reconfig_table_update(peer, dest, ain, afi,
5188 safi, prd);
5189 }
5190 }
5191
5192 /* Do soft reconfig table per bgp table.
5193 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
5194 * when BGP_NODE_SOFT_RECONFIG is set,
5195 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
5196 * Schedule a new thread to continue the job.
5197 * Without splitting the full job into several part,
5198 * vtysh waits for the job to finish before responding to a BGP command
5199 */
5200 static void bgp_soft_reconfig_table_task(struct event *thread)
5201 {
5202 uint32_t iter, max_iter;
5203 struct bgp_dest *dest;
5204 struct bgp_adj_in *ain;
5205 struct peer *peer;
5206 struct bgp_table *table;
5207 struct prefix_rd *prd;
5208 struct listnode *node, *nnode;
5209
5210 table = EVENT_ARG(thread);
5211 prd = NULL;
5212
5213 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
5214 if (table->soft_reconfig_init) {
5215 /* first call of the function with a new srta structure.
5216 * Don't do any treatment this time on nodes
5217 * in order vtysh to respond quickly
5218 */
5219 max_iter = 0;
5220 }
5221
5222 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
5223 dest = bgp_route_next(dest)) {
5224 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
5225 continue;
5226
5227 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
5228
5229 for (ain = dest->adj_in; ain; ain = ain->next) {
5230 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
5231 nnode, peer)) {
5232 if (ain->peer != peer)
5233 continue;
5234
5235 bgp_soft_reconfig_table_update(
5236 peer, dest, ain, table->afi,
5237 table->safi, prd);
5238 iter++;
5239 }
5240 }
5241 }
5242
5243 /* we're either starting the initial iteration,
5244 * or we're going to continue an ongoing iteration
5245 */
5246 if (dest || table->soft_reconfig_init) {
5247 table->soft_reconfig_init = false;
5248 event_add_event(bm->master, bgp_soft_reconfig_table_task, table,
5249 0, &table->soft_reconfig_thread);
5250 return;
5251 }
5252 /* we're done, clean up the background iteration context info and
5253 schedule route annoucement
5254 */
5255 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
5256 listnode_delete(table->soft_reconfig_peers, peer);
5257 bgp_announce_route(peer, table->afi, table->safi, false);
5258 }
5259
5260 list_delete(&table->soft_reconfig_peers);
5261 }
5262
5263
5264 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
5265 * and peer.
5266 * - bgp cannot be NULL
5267 * - if table and peer are NULL, cancel all threads within the bgp instance
5268 * - if table is NULL and peer is not,
5269 * remove peer in all threads within the bgp instance
5270 * - if peer is NULL, cancel all threads matching table within the bgp instance
5271 */
5272 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
5273 const struct bgp_table *table,
5274 const struct peer *peer)
5275 {
5276 struct peer *npeer;
5277 struct listnode *node, *nnode;
5278 int afi, safi;
5279 struct bgp_table *ntable;
5280
5281 if (!bgp)
5282 return;
5283
5284 FOREACH_AFI_SAFI (afi, safi) {
5285 ntable = bgp->rib[afi][safi];
5286 if (!ntable)
5287 continue;
5288 if (table && table != ntable)
5289 continue;
5290
5291 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
5292 npeer)) {
5293 if (peer && peer != npeer)
5294 continue;
5295 listnode_delete(ntable->soft_reconfig_peers, npeer);
5296 }
5297
5298 if (!ntable->soft_reconfig_peers
5299 || !list_isempty(ntable->soft_reconfig_peers))
5300 continue;
5301
5302 list_delete(&ntable->soft_reconfig_peers);
5303 bgp_soft_reconfig_table_flag(ntable, false);
5304 EVENT_OFF(ntable->soft_reconfig_thread);
5305 }
5306 }
5307
5308 /*
5309 * Returns false if the peer is not configured for soft reconfig in
5310 */
5311 bool bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
5312 {
5313 struct bgp_dest *dest;
5314 struct bgp_table *table;
5315 struct listnode *node, *nnode;
5316 struct peer *npeer;
5317 struct peer_af *paf;
5318
5319 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
5320 return false;
5321
5322 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5323 && (safi != SAFI_EVPN)) {
5324 table = peer->bgp->rib[afi][safi];
5325 if (!table)
5326 return true;
5327
5328 table->soft_reconfig_init = true;
5329
5330 if (!table->soft_reconfig_peers)
5331 table->soft_reconfig_peers = list_new();
5332 npeer = NULL;
5333 /* add peer to the table soft_reconfig_peers if not already
5334 * there
5335 */
5336 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5337 npeer)) {
5338 if (peer == npeer)
5339 break;
5340 }
5341 if (peer != npeer)
5342 listnode_add(table->soft_reconfig_peers, peer);
5343
5344 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5345 * on table would start back at the beginning.
5346 */
5347 bgp_soft_reconfig_table_flag(table, true);
5348
5349 if (!table->soft_reconfig_thread)
5350 event_add_event(bm->master,
5351 bgp_soft_reconfig_table_task, table, 0,
5352 &table->soft_reconfig_thread);
5353 /* Cancel bgp_announce_route_timer_expired threads.
5354 * bgp_announce_route_timer_expired threads have been scheduled
5355 * to announce routes as soon as the soft_reconfigure process
5356 * finishes.
5357 * In this case, soft_reconfigure is also scheduled by using
5358 * a thread but is planned after the
5359 * bgp_announce_route_timer_expired threads. It means that,
5360 * without cancelling the threads, the route announcement task
5361 * would run before the soft reconfiguration one. That would
5362 * useless and would block vtysh during several seconds. Route
5363 * announcements are rescheduled as soon as the soft_reconfigure
5364 * process finishes.
5365 */
5366 paf = peer_af_find(peer, afi, safi);
5367 if (paf)
5368 bgp_stop_announce_route_timer(paf);
5369 } else
5370 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5371 dest = bgp_route_next(dest)) {
5372 table = bgp_dest_get_bgp_table_info(dest);
5373
5374 if (table == NULL)
5375 continue;
5376
5377 const struct prefix *p = bgp_dest_get_prefix(dest);
5378 struct prefix_rd prd;
5379
5380 prd.family = AF_UNSPEC;
5381 prd.prefixlen = 64;
5382 memcpy(&prd.val, p->u.val, 8);
5383
5384 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5385 }
5386
5387 return true;
5388 }
5389
5390
5391 struct bgp_clear_node_queue {
5392 struct bgp_dest *dest;
5393 };
5394
5395 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5396 {
5397 struct bgp_clear_node_queue *cnq = data;
5398 struct bgp_dest *dest = cnq->dest;
5399 struct peer *peer = wq->spec.data;
5400 struct bgp_path_info *pi;
5401 struct bgp *bgp;
5402 afi_t afi = bgp_dest_table(dest)->afi;
5403 safi_t safi = bgp_dest_table(dest)->safi;
5404
5405 assert(dest && peer);
5406 bgp = peer->bgp;
5407
5408 /* It is possible that we have multiple paths for a prefix from a peer
5409 * if that peer is using AddPath.
5410 */
5411 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5412 if (pi->peer != peer)
5413 continue;
5414
5415 /* graceful restart STALE flag set. */
5416 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5417 && peer->nsf[afi][safi])
5418 || CHECK_FLAG(peer->af_sflags[afi][safi],
5419 PEER_STATUS_ENHANCED_REFRESH))
5420 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5421 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5422 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5423 else {
5424 /* If this is an EVPN route, process for
5425 * un-import. */
5426 if (safi == SAFI_EVPN)
5427 bgp_evpn_unimport_route(
5428 bgp, afi, safi,
5429 bgp_dest_get_prefix(dest), pi);
5430 /* Handle withdraw for VRF route-leaking and L3VPN */
5431 if (SAFI_UNICAST == safi
5432 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5433 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5434 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5435 bgp, pi);
5436 }
5437 if (SAFI_MPLS_VPN == safi &&
5438 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5439 vpn_leak_to_vrf_withdraw(pi);
5440 }
5441
5442 bgp_rib_remove(dest, pi, peer, afi, safi);
5443 }
5444 }
5445 return WQ_SUCCESS;
5446 }
5447
5448 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5449 {
5450 struct bgp_clear_node_queue *cnq = data;
5451 struct bgp_dest *dest = cnq->dest;
5452 struct bgp_table *table = bgp_dest_table(dest);
5453
5454 bgp_dest_unlock_node(dest);
5455 bgp_table_unlock(table);
5456 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5457 }
5458
5459 static void bgp_clear_node_complete(struct work_queue *wq)
5460 {
5461 struct peer *peer = wq->spec.data;
5462
5463 /* Tickle FSM to start moving again */
5464 BGP_EVENT_ADD(peer, Clearing_Completed);
5465
5466 peer_unlock(peer); /* bgp_clear_route */
5467 }
5468
5469 static void bgp_clear_node_queue_init(struct peer *peer)
5470 {
5471 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5472
5473 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5474 #undef CLEAR_QUEUE_NAME_LEN
5475
5476 peer->clear_node_queue = work_queue_new(bm->master, wname);
5477 peer->clear_node_queue->spec.hold = 10;
5478 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5479 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5480 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5481 peer->clear_node_queue->spec.max_retries = 0;
5482
5483 /* we only 'lock' this peer reference when the queue is actually active
5484 */
5485 peer->clear_node_queue->spec.data = peer;
5486 }
5487
5488 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5489 struct bgp_table *table)
5490 {
5491 struct bgp_dest *dest;
5492 int force = peer->bgp->process_queue ? 0 : 1;
5493
5494 if (!table)
5495 table = peer->bgp->rib[afi][safi];
5496
5497 /* If still no table => afi/safi isn't configured at all or smth. */
5498 if (!table)
5499 return;
5500
5501 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5502 struct bgp_path_info *pi, *next;
5503 struct bgp_adj_in *ain;
5504 struct bgp_adj_in *ain_next;
5505
5506 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5507 * queued for every clearing peer, regardless of whether it is
5508 * relevant to the peer at hand.
5509 *
5510 * Overview: There are 3 different indices which need to be
5511 * scrubbed, potentially, when a peer is removed:
5512 *
5513 * 1 peer's routes visible via the RIB (ie accepted routes)
5514 * 2 peer's routes visible by the (optional) peer's adj-in index
5515 * 3 other routes visible by the peer's adj-out index
5516 *
5517 * 3 there is no hurry in scrubbing, once the struct peer is
5518 * removed from bgp->peer, we could just GC such deleted peer's
5519 * adj-outs at our leisure.
5520 *
5521 * 1 and 2 must be 'scrubbed' in some way, at least made
5522 * invisible via RIB index before peer session is allowed to be
5523 * brought back up. So one needs to know when such a 'search' is
5524 * complete.
5525 *
5526 * Ideally:
5527 *
5528 * - there'd be a single global queue or a single RIB walker
5529 * - rather than tracking which route_nodes still need to be
5530 * examined on a peer basis, we'd track which peers still
5531 * aren't cleared
5532 *
5533 * Given that our per-peer prefix-counts now should be reliable,
5534 * this may actually be achievable. It doesn't seem to be a huge
5535 * problem at this time,
5536 *
5537 * It is possible that we have multiple paths for a prefix from
5538 * a peer
5539 * if that peer is using AddPath.
5540 */
5541 ain = dest->adj_in;
5542 while (ain) {
5543 ain_next = ain->next;
5544
5545 if (ain->peer == peer)
5546 bgp_adj_in_remove(dest, ain);
5547
5548 ain = ain_next;
5549 }
5550
5551 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5552 next = pi->next;
5553 if (pi->peer != peer)
5554 continue;
5555
5556 if (force)
5557 bgp_path_info_reap(dest, pi);
5558 else {
5559 struct bgp_clear_node_queue *cnq;
5560
5561 /* both unlocked in bgp_clear_node_queue_del */
5562 bgp_table_lock(bgp_dest_table(dest));
5563 bgp_dest_lock_node(dest);
5564 cnq = XCALLOC(
5565 MTYPE_BGP_CLEAR_NODE_QUEUE,
5566 sizeof(struct bgp_clear_node_queue));
5567 cnq->dest = dest;
5568 work_queue_add(peer->clear_node_queue, cnq);
5569 break;
5570 }
5571 }
5572 }
5573 return;
5574 }
5575
5576 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5577 {
5578 struct bgp_dest *dest;
5579 struct bgp_table *table;
5580
5581 if (peer->clear_node_queue == NULL)
5582 bgp_clear_node_queue_init(peer);
5583
5584 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5585 * Idle until it receives a Clearing_Completed event. This protects
5586 * against peers which flap faster than we can we clear, which could
5587 * lead to:
5588 *
5589 * a) race with routes from the new session being installed before
5590 * clear_route_node visits the node (to delete the route of that
5591 * peer)
5592 * b) resource exhaustion, clear_route_node likely leads to an entry
5593 * on the process_main queue. Fast-flapping could cause that queue
5594 * to grow and grow.
5595 */
5596
5597 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5598 * the unlock will happen upon work-queue completion; other wise, the
5599 * unlock happens at the end of this function.
5600 */
5601 if (!peer->clear_node_queue->thread)
5602 peer_lock(peer);
5603
5604 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5605 bgp_clear_route_table(peer, afi, safi, NULL);
5606 else
5607 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5608 dest = bgp_route_next(dest)) {
5609 table = bgp_dest_get_bgp_table_info(dest);
5610 if (!table)
5611 continue;
5612
5613 bgp_clear_route_table(peer, afi, safi, table);
5614 }
5615
5616 /* unlock if no nodes got added to the clear-node-queue. */
5617 if (!peer->clear_node_queue->thread)
5618 peer_unlock(peer);
5619 }
5620
5621 void bgp_clear_route_all(struct peer *peer)
5622 {
5623 afi_t afi;
5624 safi_t safi;
5625
5626 FOREACH_AFI_SAFI (afi, safi)
5627 bgp_clear_route(peer, afi, safi);
5628
5629 #ifdef ENABLE_BGP_VNC
5630 rfapiProcessPeerDown(peer);
5631 #endif
5632 }
5633
5634 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5635 {
5636 struct bgp_table *table;
5637 struct bgp_dest *dest;
5638 struct bgp_adj_in *ain;
5639 struct bgp_adj_in *ain_next;
5640
5641 table = peer->bgp->rib[afi][safi];
5642
5643 /* It is possible that we have multiple paths for a prefix from a peer
5644 * if that peer is using AddPath.
5645 */
5646 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5647 ain = dest->adj_in;
5648
5649 while (ain) {
5650 ain_next = ain->next;
5651
5652 if (ain->peer == peer)
5653 bgp_adj_in_remove(dest, ain);
5654
5655 ain = ain_next;
5656 }
5657 }
5658 }
5659
5660 /* If any of the routes from the peer have been marked with the NO_LLGR
5661 * community, either as sent by the peer, or as the result of a configured
5662 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5663 * operation of [RFC4271].
5664 */
5665 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5666 {
5667 struct bgp_dest *dest;
5668 struct bgp_path_info *pi;
5669 struct bgp_table *table;
5670
5671 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5672 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5673 dest = bgp_route_next(dest)) {
5674 struct bgp_dest *rm;
5675
5676 /* look for neighbor in tables */
5677 table = bgp_dest_get_bgp_table_info(dest);
5678 if (!table)
5679 continue;
5680
5681 for (rm = bgp_table_top(table); rm;
5682 rm = bgp_route_next(rm))
5683 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5684 pi = pi->next) {
5685 if (pi->peer != peer)
5686 continue;
5687 if (CHECK_FLAG(
5688 peer->af_sflags[afi][safi],
5689 PEER_STATUS_LLGR_WAIT) &&
5690 bgp_attr_get_community(pi->attr) &&
5691 !community_include(
5692 bgp_attr_get_community(
5693 pi->attr),
5694 COMMUNITY_NO_LLGR))
5695 continue;
5696 if (!CHECK_FLAG(pi->flags,
5697 BGP_PATH_STALE))
5698 continue;
5699
5700 /*
5701 * If this is VRF leaked route
5702 * process for withdraw.
5703 */
5704 if (pi->sub_type ==
5705 BGP_ROUTE_IMPORTED &&
5706 peer->bgp->inst_type ==
5707 BGP_INSTANCE_TYPE_DEFAULT)
5708 vpn_leak_to_vrf_withdraw(pi);
5709
5710 bgp_rib_remove(rm, pi, peer, afi, safi);
5711 break;
5712 }
5713 }
5714 } else {
5715 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5716 dest = bgp_route_next(dest))
5717 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5718 pi = pi->next) {
5719 if (pi->peer != peer)
5720 continue;
5721 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5722 PEER_STATUS_LLGR_WAIT) &&
5723 bgp_attr_get_community(pi->attr) &&
5724 !community_include(
5725 bgp_attr_get_community(pi->attr),
5726 COMMUNITY_NO_LLGR))
5727 continue;
5728 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5729 continue;
5730 if (safi == SAFI_UNICAST &&
5731 (peer->bgp->inst_type ==
5732 BGP_INSTANCE_TYPE_VRF ||
5733 peer->bgp->inst_type ==
5734 BGP_INSTANCE_TYPE_DEFAULT))
5735 vpn_leak_from_vrf_withdraw(
5736 bgp_get_default(), peer->bgp,
5737 pi);
5738
5739 bgp_rib_remove(dest, pi, peer, afi, safi);
5740 break;
5741 }
5742 }
5743 }
5744
5745 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5746 {
5747 struct bgp_dest *dest, *ndest;
5748 struct bgp_path_info *pi;
5749 struct bgp_table *table;
5750
5751 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5752 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5753 dest = bgp_route_next(dest)) {
5754 table = bgp_dest_get_bgp_table_info(dest);
5755 if (!table)
5756 continue;
5757
5758 for (ndest = bgp_table_top(table); ndest;
5759 ndest = bgp_route_next(ndest)) {
5760 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5761 pi = pi->next) {
5762 if (pi->peer != peer)
5763 continue;
5764
5765 if ((CHECK_FLAG(
5766 peer->af_sflags[afi][safi],
5767 PEER_STATUS_ENHANCED_REFRESH))
5768 && !CHECK_FLAG(pi->flags,
5769 BGP_PATH_STALE)
5770 && !CHECK_FLAG(
5771 pi->flags,
5772 BGP_PATH_UNUSEABLE)) {
5773 if (bgp_debug_neighbor_events(
5774 peer))
5775 zlog_debug(
5776 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5777 peer,
5778 afi2str(afi),
5779 safi2str(safi),
5780 bgp_dest_get_prefix(
5781 ndest));
5782
5783 bgp_path_info_set_flag(
5784 ndest, pi,
5785 BGP_PATH_STALE);
5786 }
5787 }
5788 }
5789 }
5790 } else {
5791 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5792 dest = bgp_route_next(dest)) {
5793 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5794 pi = pi->next) {
5795 if (pi->peer != peer)
5796 continue;
5797
5798 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5799 PEER_STATUS_ENHANCED_REFRESH))
5800 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5801 && !CHECK_FLAG(pi->flags,
5802 BGP_PATH_UNUSEABLE)) {
5803 if (bgp_debug_neighbor_events(peer))
5804 zlog_debug(
5805 "%pBP route-refresh for %s/%s, marking prefix %pFX as stale",
5806 peer, afi2str(afi),
5807 safi2str(safi),
5808 bgp_dest_get_prefix(
5809 dest));
5810
5811 bgp_path_info_set_flag(dest, pi,
5812 BGP_PATH_STALE);
5813 }
5814 }
5815 }
5816 }
5817 }
5818
5819 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5820 {
5821 if (peer->sort == BGP_PEER_IBGP)
5822 return true;
5823
5824 if (peer->sort == BGP_PEER_EBGP
5825 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5826 || FILTER_LIST_OUT_NAME(filter)
5827 || DISTRIBUTE_OUT_NAME(filter)))
5828 return true;
5829 return false;
5830 }
5831
5832 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5833 {
5834 if (peer->sort == BGP_PEER_IBGP)
5835 return true;
5836
5837 if (peer->sort == BGP_PEER_EBGP
5838 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5839 || FILTER_LIST_IN_NAME(filter)
5840 || DISTRIBUTE_IN_NAME(filter)))
5841 return true;
5842 return false;
5843 }
5844
5845 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5846 safi_t safi)
5847 {
5848 struct bgp_dest *dest;
5849 struct bgp_path_info *pi;
5850 struct bgp_path_info *next;
5851
5852 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5853 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5854 const struct prefix *p = bgp_dest_get_prefix(dest);
5855
5856 next = pi->next;
5857
5858 /* Unimport EVPN routes from VRFs */
5859 if (safi == SAFI_EVPN)
5860 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5861 SAFI_EVPN, p, pi);
5862
5863 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5864 && pi->type == ZEBRA_ROUTE_BGP
5865 && (pi->sub_type == BGP_ROUTE_NORMAL
5866 || pi->sub_type == BGP_ROUTE_AGGREGATE
5867 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5868
5869 if (bgp_fibupd_safi(safi))
5870 bgp_zebra_withdraw(p, pi, bgp, safi);
5871 }
5872
5873 bgp_path_info_reap(dest, pi);
5874 }
5875 }
5876
5877 /* Delete all kernel routes. */
5878 void bgp_cleanup_routes(struct bgp *bgp)
5879 {
5880 afi_t afi;
5881 struct bgp_dest *dest;
5882 struct bgp_table *table;
5883
5884 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5885 if (afi == AFI_L2VPN)
5886 continue;
5887 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5888 SAFI_UNICAST);
5889 /*
5890 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5891 */
5892 if (afi != AFI_L2VPN) {
5893 safi_t safi;
5894 safi = SAFI_MPLS_VPN;
5895 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5896 dest = bgp_route_next(dest)) {
5897 table = bgp_dest_get_bgp_table_info(dest);
5898 if (table != NULL) {
5899 bgp_cleanup_table(bgp, table, safi);
5900 bgp_table_finish(&table);
5901 bgp_dest_set_bgp_table_info(dest, NULL);
5902 bgp_dest_unlock_node(dest);
5903 }
5904 }
5905 safi = SAFI_ENCAP;
5906 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5907 dest = bgp_route_next(dest)) {
5908 table = bgp_dest_get_bgp_table_info(dest);
5909 if (table != NULL) {
5910 bgp_cleanup_table(bgp, table, safi);
5911 bgp_table_finish(&table);
5912 bgp_dest_set_bgp_table_info(dest, NULL);
5913 bgp_dest_unlock_node(dest);
5914 }
5915 }
5916 }
5917 }
5918 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5919 dest = bgp_route_next(dest)) {
5920 table = bgp_dest_get_bgp_table_info(dest);
5921 if (table != NULL) {
5922 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5923 bgp_table_finish(&table);
5924 bgp_dest_set_bgp_table_info(dest, NULL);
5925 bgp_dest_unlock_node(dest);
5926 }
5927 }
5928 }
5929
5930 void bgp_reset(void)
5931 {
5932 vty_reset();
5933 bgp_zclient_reset();
5934 access_list_reset();
5935 prefix_list_reset();
5936 }
5937
5938 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5939 {
5940 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5941 && CHECK_FLAG(peer->af_cap[afi][safi],
5942 PEER_CAP_ADDPATH_AF_TX_RCV));
5943 }
5944
5945 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5946 value. */
5947 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5948 struct bgp_nlri *packet)
5949 {
5950 uint8_t *pnt;
5951 uint8_t *lim;
5952 struct prefix p;
5953 int psize;
5954 afi_t afi;
5955 safi_t safi;
5956 bool addpath_capable;
5957 uint32_t addpath_id;
5958
5959 pnt = packet->nlri;
5960 lim = pnt + packet->length;
5961 afi = packet->afi;
5962 safi = packet->safi;
5963 addpath_id = 0;
5964 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5965
5966 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5967 syntactic validity. If the field is syntactically incorrect,
5968 then the Error Subcode is set to Invalid Network Field. */
5969 for (; pnt < lim; pnt += psize) {
5970 /* Clear prefix structure. */
5971 memset(&p, 0, sizeof(p));
5972
5973 if (addpath_capable) {
5974
5975 /* When packet overflow occurs return immediately. */
5976 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5977 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5978
5979 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5980 addpath_id = ntohl(addpath_id);
5981 pnt += BGP_ADDPATH_ID_LEN;
5982 }
5983
5984 /* Fetch prefix length. */
5985 p.prefixlen = *pnt++;
5986 /* afi/safi validity already verified by caller,
5987 * bgp_update_receive */
5988 p.family = afi2family(afi);
5989
5990 /* Prefix length check. */
5991 if (p.prefixlen > prefix_blen(&p) * 8) {
5992 flog_err(
5993 EC_BGP_UPDATE_RCV,
5994 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5995 peer->host, p.prefixlen, packet->afi);
5996 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5997 }
5998
5999 /* Packet size overflow check. */
6000 psize = PSIZE(p.prefixlen);
6001
6002 /* When packet overflow occur return immediately. */
6003 if (pnt + psize > lim) {
6004 flog_err(
6005 EC_BGP_UPDATE_RCV,
6006 "%s [Error] Update packet error (prefix length %d overflows packet)",
6007 peer->host, p.prefixlen);
6008 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
6009 }
6010
6011 /* Defensive coding, double-check the psize fits in a struct
6012 * prefix for the v4 and v6 afi's and unicast/multicast */
6013 if (psize > (ssize_t)sizeof(p.u.val)) {
6014 flog_err(
6015 EC_BGP_UPDATE_RCV,
6016 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
6017 peer->host, p.prefixlen, sizeof(p.u.val));
6018 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6019 }
6020
6021 /* Fetch prefix from NLRI packet. */
6022 memcpy(p.u.val, pnt, psize);
6023
6024 /* Check address. */
6025 if (afi == AFI_IP && safi == SAFI_UNICAST) {
6026 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
6027 /* From RFC4271 Section 6.3:
6028 *
6029 * If a prefix in the NLRI field is semantically
6030 * incorrect
6031 * (e.g., an unexpected multicast IP address),
6032 * an error SHOULD
6033 * be logged locally, and the prefix SHOULD be
6034 * ignored.
6035 */
6036 flog_err(
6037 EC_BGP_UPDATE_RCV,
6038 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
6039 peer->host, &p.u.prefix4);
6040 continue;
6041 }
6042 }
6043
6044 /* Check address. */
6045 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
6046 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6047 flog_err(
6048 EC_BGP_UPDATE_RCV,
6049 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
6050 peer->host, &p.u.prefix6);
6051
6052 continue;
6053 }
6054 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
6055 flog_err(
6056 EC_BGP_UPDATE_RCV,
6057 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
6058 peer->host, &p.u.prefix6);
6059
6060 continue;
6061 }
6062 }
6063
6064 /* Normal process. */
6065 if (attr)
6066 bgp_update(peer, &p, addpath_id, attr, afi, safi,
6067 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6068 NULL, 0, 0, NULL);
6069 else
6070 bgp_withdraw(peer, &p, addpath_id, afi, safi,
6071 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
6072 NULL, 0, NULL);
6073
6074 /* Do not send BGP notification twice when maximum-prefix count
6075 * overflow. */
6076 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
6077 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
6078 }
6079
6080 /* Packet length consistency check. */
6081 if (pnt != lim) {
6082 flog_err(
6083 EC_BGP_UPDATE_RCV,
6084 "%s [Error] Update packet error (prefix length mismatch with total length)",
6085 peer->host);
6086 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
6087 }
6088
6089 return BGP_NLRI_PARSE_OK;
6090 }
6091
6092 static struct bgp_static *bgp_static_new(void)
6093 {
6094 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
6095 }
6096
6097 static void bgp_static_free(struct bgp_static *bgp_static)
6098 {
6099 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6100 route_map_counter_decrement(bgp_static->rmap.map);
6101
6102 if (bgp_static->prd_pretty)
6103 XFREE(MTYPE_BGP, bgp_static->prd_pretty);
6104 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
6105 XFREE(MTYPE_BGP_STATIC, bgp_static);
6106 }
6107
6108 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
6109 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
6110 {
6111 struct bgp_dest *dest;
6112 struct bgp_path_info *pi;
6113 struct bgp_path_info *new;
6114 struct bgp_path_info rmap_path;
6115 struct attr attr;
6116 struct attr *attr_new;
6117 route_map_result_t ret;
6118 #ifdef ENABLE_BGP_VNC
6119 int vnc_implicit_withdraw = 0;
6120 #endif
6121
6122 assert(bgp_static);
6123
6124 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6125
6126 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6127
6128 attr.nexthop = bgp_static->igpnexthop;
6129 attr.med = bgp_static->igpmetric;
6130 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6131
6132 if (afi == AFI_IP)
6133 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
6134
6135 if (bgp_static->igpmetric)
6136 bgp_attr_set_aigp_metric(&attr, bgp_static->igpmetric);
6137
6138 if (bgp_static->atomic)
6139 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
6140
6141 /* Store label index, if required. */
6142 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
6143 attr.label_index = bgp_static->label_index;
6144 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
6145 }
6146
6147 /* Apply route-map. */
6148 if (bgp_static->rmap.name) {
6149 struct attr attr_tmp = attr;
6150
6151 memset(&rmap_path, 0, sizeof(rmap_path));
6152 rmap_path.peer = bgp->peer_self;
6153 rmap_path.attr = &attr_tmp;
6154
6155 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6156
6157 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6158
6159 bgp->peer_self->rmap_type = 0;
6160
6161 if (ret == RMAP_DENYMATCH) {
6162 /* Free uninterned attribute. */
6163 bgp_attr_flush(&attr_tmp);
6164
6165 /* Unintern original. */
6166 aspath_unintern(&attr.aspath);
6167 bgp_static_withdraw(bgp, p, afi, safi);
6168 bgp_dest_unlock_node(dest);
6169 return;
6170 }
6171
6172 if (bgp_in_graceful_shutdown(bgp))
6173 bgp_attr_add_gshut_community(&attr_tmp);
6174
6175 attr_new = bgp_attr_intern(&attr_tmp);
6176 } else {
6177
6178 if (bgp_in_graceful_shutdown(bgp))
6179 bgp_attr_add_gshut_community(&attr);
6180
6181 attr_new = bgp_attr_intern(&attr);
6182 }
6183
6184 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6185 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6186 && pi->sub_type == BGP_ROUTE_STATIC)
6187 break;
6188
6189 if (pi) {
6190 if (attrhash_cmp(pi->attr, attr_new)
6191 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
6192 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
6193 bgp_dest_unlock_node(dest);
6194 bgp_attr_unintern(&attr_new);
6195 aspath_unintern(&attr.aspath);
6196 return;
6197 } else {
6198 /* The attribute is changed. */
6199 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6200
6201 /* Rewrite BGP route information. */
6202 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6203 bgp_path_info_restore(dest, pi);
6204 else
6205 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6206 #ifdef ENABLE_BGP_VNC
6207 if ((afi == AFI_IP || afi == AFI_IP6)
6208 && (safi == SAFI_UNICAST)) {
6209 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
6210 /*
6211 * Implicit withdraw case.
6212 * We have to do this before pi is
6213 * changed
6214 */
6215 ++vnc_implicit_withdraw;
6216 vnc_import_bgp_del_route(bgp, p, pi);
6217 vnc_import_bgp_exterior_del_route(
6218 bgp, p, pi);
6219 }
6220 }
6221 #endif
6222 bgp_attr_unintern(&pi->attr);
6223 pi->attr = attr_new;
6224 pi->uptime = monotime(NULL);
6225 #ifdef ENABLE_BGP_VNC
6226 if ((afi == AFI_IP || afi == AFI_IP6)
6227 && (safi == SAFI_UNICAST)) {
6228 if (vnc_implicit_withdraw) {
6229 vnc_import_bgp_add_route(bgp, p, pi);
6230 vnc_import_bgp_exterior_add_route(
6231 bgp, p, pi);
6232 }
6233 }
6234 #endif
6235
6236 /* Nexthop reachability check. */
6237 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6238 && (safi == SAFI_UNICAST
6239 || safi == SAFI_LABELED_UNICAST)) {
6240
6241 struct bgp *bgp_nexthop = bgp;
6242
6243 if (pi->extra && pi->extra->bgp_orig)
6244 bgp_nexthop = pi->extra->bgp_orig;
6245
6246 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
6247 afi, safi, pi, NULL,
6248 0, p))
6249 bgp_path_info_set_flag(dest, pi,
6250 BGP_PATH_VALID);
6251 else {
6252 if (BGP_DEBUG(nht, NHT)) {
6253 char buf1[INET6_ADDRSTRLEN];
6254 inet_ntop(p->family,
6255 &p->u.prefix, buf1,
6256 sizeof(buf1));
6257 zlog_debug(
6258 "%s(%s): Route not in table, not advertising",
6259 __func__, buf1);
6260 }
6261 bgp_path_info_unset_flag(
6262 dest, pi, BGP_PATH_VALID);
6263 }
6264 } else {
6265 /* Delete the NHT structure if any, if we're
6266 * toggling between
6267 * enabling/disabling import check. We
6268 * deregister the route
6269 * from NHT to avoid overloading NHT and the
6270 * process interaction
6271 */
6272 bgp_unlink_nexthop(pi);
6273 bgp_path_info_set_flag(dest, pi,
6274 BGP_PATH_VALID);
6275 }
6276 /* Process change. */
6277 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6278 bgp_process(bgp, dest, afi, safi);
6279
6280 if (SAFI_UNICAST == safi
6281 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6282 || bgp->inst_type
6283 == BGP_INSTANCE_TYPE_DEFAULT)) {
6284 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
6285 pi);
6286 }
6287
6288 bgp_dest_unlock_node(dest);
6289 aspath_unintern(&attr.aspath);
6290 return;
6291 }
6292 }
6293
6294 /* Make new BGP info. */
6295 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6296 attr_new, dest);
6297 /* Nexthop reachability check. */
6298 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
6299 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
6300 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
6301 p))
6302 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6303 else {
6304 if (BGP_DEBUG(nht, NHT)) {
6305 char buf1[INET6_ADDRSTRLEN];
6306
6307 inet_ntop(p->family, &p->u.prefix, buf1,
6308 sizeof(buf1));
6309 zlog_debug(
6310 "%s(%s): Route not in table, not advertising",
6311 __func__, buf1);
6312 }
6313 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
6314 }
6315 } else {
6316 /* Delete the NHT structure if any, if we're toggling between
6317 * enabling/disabling import check. We deregister the route
6318 * from NHT to avoid overloading NHT and the process interaction
6319 */
6320 bgp_unlink_nexthop(new);
6321
6322 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6323 }
6324
6325 /* Aggregate address increment. */
6326 bgp_aggregate_increment(bgp, p, new, afi, safi);
6327
6328 /* Register new BGP information. */
6329 bgp_path_info_add(dest, new);
6330
6331 /* route_node_get lock */
6332 bgp_dest_unlock_node(dest);
6333
6334 /* Process change. */
6335 bgp_process(bgp, dest, afi, safi);
6336
6337 if (SAFI_UNICAST == safi
6338 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6339 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6340 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6341 }
6342
6343 /* Unintern original. */
6344 aspath_unintern(&attr.aspath);
6345 }
6346
6347 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6348 safi_t safi)
6349 {
6350 struct bgp_dest *dest;
6351 struct bgp_path_info *pi;
6352
6353 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6354
6355 /* Check selected route and self inserted route. */
6356 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6357 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6358 && pi->sub_type == BGP_ROUTE_STATIC)
6359 break;
6360
6361 /* Withdraw static BGP route from routing table. */
6362 if (pi) {
6363 if (SAFI_UNICAST == safi
6364 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6365 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6366 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6367 }
6368 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6369 bgp_unlink_nexthop(pi);
6370 bgp_path_info_delete(dest, pi);
6371 bgp_process(bgp, dest, afi, safi);
6372 }
6373
6374 /* Unlock bgp_node_lookup. */
6375 bgp_dest_unlock_node(dest);
6376 }
6377
6378 /*
6379 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6380 */
6381 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6382 afi_t afi, safi_t safi,
6383 struct prefix_rd *prd)
6384 {
6385 struct bgp_dest *dest;
6386 struct bgp_path_info *pi;
6387
6388 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6389
6390 /* Check selected route and self inserted route. */
6391 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6392 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6393 && pi->sub_type == BGP_ROUTE_STATIC)
6394 break;
6395
6396 /* Withdraw static BGP route from routing table. */
6397 if (pi) {
6398 #ifdef ENABLE_BGP_VNC
6399 rfapiProcessWithdraw(
6400 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6401 1); /* Kill, since it is an administrative change */
6402 #endif
6403 if (SAFI_MPLS_VPN == safi
6404 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6405 vpn_leak_to_vrf_withdraw(pi);
6406 }
6407 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6408 bgp_path_info_delete(dest, pi);
6409 bgp_process(bgp, dest, afi, safi);
6410 }
6411
6412 /* Unlock bgp_node_lookup. */
6413 bgp_dest_unlock_node(dest);
6414 }
6415
6416 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6417 struct bgp_static *bgp_static, afi_t afi,
6418 safi_t safi)
6419 {
6420 struct bgp_dest *dest;
6421 struct bgp_path_info *new;
6422 struct attr *attr_new;
6423 struct attr attr = {0};
6424 struct bgp_path_info *pi;
6425 #ifdef ENABLE_BGP_VNC
6426 mpls_label_t label = 0;
6427 #endif
6428 uint32_t num_labels = 0;
6429
6430 assert(bgp_static);
6431
6432 if (bgp_static->label != MPLS_INVALID_LABEL)
6433 num_labels = 1;
6434 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6435 &bgp_static->prd);
6436
6437 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_IGP);
6438
6439 attr.nexthop = bgp_static->igpnexthop;
6440 attr.med = bgp_static->igpmetric;
6441 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6442
6443 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6444 || (safi == SAFI_ENCAP)) {
6445 if (afi == AFI_IP) {
6446 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6447 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6448 }
6449 }
6450 if (afi == AFI_L2VPN) {
6451 if (bgp_static->gatewayIp.family == AF_INET) {
6452 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6453 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6454 &bgp_static->gatewayIp.u.prefix4,
6455 IPV4_MAX_BYTELEN);
6456 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6457 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6458 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6459 &bgp_static->gatewayIp.u.prefix6,
6460 IPV6_MAX_BYTELEN);
6461 }
6462 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6463 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6464 struct bgp_encap_type_vxlan bet;
6465 memset(&bet, 0, sizeof(bet));
6466 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6467 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6468 }
6469 if (bgp_static->router_mac) {
6470 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6471 }
6472 }
6473 /* Apply route-map. */
6474 if (bgp_static->rmap.name) {
6475 struct attr attr_tmp = attr;
6476 struct bgp_path_info rmap_path;
6477 route_map_result_t ret;
6478
6479 rmap_path.peer = bgp->peer_self;
6480 rmap_path.attr = &attr_tmp;
6481
6482 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6483
6484 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6485
6486 bgp->peer_self->rmap_type = 0;
6487
6488 if (ret == RMAP_DENYMATCH) {
6489 /* Free uninterned attribute. */
6490 bgp_attr_flush(&attr_tmp);
6491
6492 /* Unintern original. */
6493 aspath_unintern(&attr.aspath);
6494 bgp_static_withdraw_safi(bgp, p, afi, safi,
6495 &bgp_static->prd);
6496 bgp_dest_unlock_node(dest);
6497 return;
6498 }
6499
6500 attr_new = bgp_attr_intern(&attr_tmp);
6501 } else {
6502 attr_new = bgp_attr_intern(&attr);
6503 }
6504
6505 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6506 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6507 && pi->sub_type == BGP_ROUTE_STATIC)
6508 break;
6509
6510 if (pi) {
6511 if (attrhash_cmp(pi->attr, attr_new)
6512 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6513 bgp_dest_unlock_node(dest);
6514 bgp_attr_unintern(&attr_new);
6515 aspath_unintern(&attr.aspath);
6516 return;
6517 } else {
6518 /* The attribute is changed. */
6519 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6520
6521 /* Rewrite BGP route information. */
6522 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6523 bgp_path_info_restore(dest, pi);
6524 else
6525 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6526 bgp_attr_unintern(&pi->attr);
6527 pi->attr = attr_new;
6528 pi->uptime = monotime(NULL);
6529 #ifdef ENABLE_BGP_VNC
6530 if (pi->extra)
6531 label = decode_label(&pi->extra->label[0]);
6532 #endif
6533
6534 /* Process change. */
6535 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6536 bgp_process(bgp, dest, afi, safi);
6537
6538 if (SAFI_MPLS_VPN == safi
6539 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6540 vpn_leak_to_vrf_update(bgp, pi,
6541 &bgp_static->prd);
6542 }
6543 #ifdef ENABLE_BGP_VNC
6544 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6545 pi->attr, afi, safi, pi->type,
6546 pi->sub_type, &label);
6547 #endif
6548 bgp_dest_unlock_node(dest);
6549 aspath_unintern(&attr.aspath);
6550 return;
6551 }
6552 }
6553
6554
6555 /* Make new BGP info. */
6556 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6557 attr_new, dest);
6558 SET_FLAG(new->flags, BGP_PATH_VALID);
6559 bgp_path_info_extra_get(new);
6560 if (num_labels) {
6561 new->extra->label[0] = bgp_static->label;
6562 new->extra->num_labels = num_labels;
6563 }
6564 #ifdef ENABLE_BGP_VNC
6565 label = decode_label(&bgp_static->label);
6566 #endif
6567
6568 /* Aggregate address increment. */
6569 bgp_aggregate_increment(bgp, p, new, afi, safi);
6570
6571 /* Register new BGP information. */
6572 bgp_path_info_add(dest, new);
6573 /* route_node_get lock */
6574 bgp_dest_unlock_node(dest);
6575
6576 /* Process change. */
6577 bgp_process(bgp, dest, afi, safi);
6578
6579 if (SAFI_MPLS_VPN == safi
6580 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6581 vpn_leak_to_vrf_update(bgp, new, &bgp_static->prd);
6582 }
6583 #ifdef ENABLE_BGP_VNC
6584 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6585 safi, new->type, new->sub_type, &label);
6586 #endif
6587
6588 /* Unintern original. */
6589 aspath_unintern(&attr.aspath);
6590 }
6591
6592 /* Configure static BGP network. When user don't run zebra, static
6593 route should be installed as valid. */
6594 static int bgp_static_set(struct vty *vty, const char *negate,
6595 const char *ip_str, afi_t afi, safi_t safi,
6596 const char *rmap, int backdoor, uint32_t label_index)
6597 {
6598 VTY_DECLVAR_CONTEXT(bgp, bgp);
6599 int ret;
6600 struct prefix p;
6601 struct bgp_static *bgp_static;
6602 struct bgp_dest *dest;
6603 uint8_t need_update = 0;
6604
6605 /* Convert IP prefix string to struct prefix. */
6606 ret = str2prefix(ip_str, &p);
6607 if (!ret) {
6608 vty_out(vty, "%% Malformed prefix\n");
6609 return CMD_WARNING_CONFIG_FAILED;
6610 }
6611 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6612 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6613 return CMD_WARNING_CONFIG_FAILED;
6614 }
6615
6616 apply_mask(&p);
6617
6618 if (negate) {
6619
6620 /* Set BGP static route configuration. */
6621 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6622
6623 if (!dest) {
6624 vty_out(vty, "%% Can't find static route specified\n");
6625 return CMD_WARNING_CONFIG_FAILED;
6626 }
6627
6628 bgp_static = bgp_dest_get_bgp_static_info(dest);
6629
6630 if ((label_index != BGP_INVALID_LABEL_INDEX)
6631 && (label_index != bgp_static->label_index)) {
6632 vty_out(vty,
6633 "%% label-index doesn't match static route\n");
6634 bgp_dest_unlock_node(dest);
6635 return CMD_WARNING_CONFIG_FAILED;
6636 }
6637
6638 if ((rmap && bgp_static->rmap.name)
6639 && strcmp(rmap, bgp_static->rmap.name)) {
6640 vty_out(vty,
6641 "%% route-map name doesn't match static route\n");
6642 bgp_dest_unlock_node(dest);
6643 return CMD_WARNING_CONFIG_FAILED;
6644 }
6645
6646 /* Update BGP RIB. */
6647 if (!bgp_static->backdoor)
6648 bgp_static_withdraw(bgp, &p, afi, safi);
6649
6650 /* Clear configuration. */
6651 bgp_static_free(bgp_static);
6652 bgp_dest_set_bgp_static_info(dest, NULL);
6653 bgp_dest_unlock_node(dest);
6654 bgp_dest_unlock_node(dest);
6655 } else {
6656
6657 /* Set BGP static route configuration. */
6658 dest = bgp_node_get(bgp->route[afi][safi], &p);
6659 bgp_static = bgp_dest_get_bgp_static_info(dest);
6660 if (bgp_static) {
6661 /* Configuration change. */
6662 /* Label index cannot be changed. */
6663 if (bgp_static->label_index != label_index) {
6664 vty_out(vty, "%% cannot change label-index\n");
6665 bgp_dest_unlock_node(dest);
6666 return CMD_WARNING_CONFIG_FAILED;
6667 }
6668
6669 /* Check previous routes are installed into BGP. */
6670 if (bgp_static->valid
6671 && bgp_static->backdoor != backdoor)
6672 need_update = 1;
6673
6674 bgp_static->backdoor = backdoor;
6675
6676 if (rmap) {
6677 XFREE(MTYPE_ROUTE_MAP_NAME,
6678 bgp_static->rmap.name);
6679 route_map_counter_decrement(
6680 bgp_static->rmap.map);
6681 bgp_static->rmap.name =
6682 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6683 bgp_static->rmap.map =
6684 route_map_lookup_by_name(rmap);
6685 route_map_counter_increment(
6686 bgp_static->rmap.map);
6687 } else {
6688 XFREE(MTYPE_ROUTE_MAP_NAME,
6689 bgp_static->rmap.name);
6690 route_map_counter_decrement(
6691 bgp_static->rmap.map);
6692 bgp_static->rmap.map = NULL;
6693 bgp_static->valid = 0;
6694 }
6695 bgp_dest_unlock_node(dest);
6696 } else {
6697 /* New configuration. */
6698 bgp_static = bgp_static_new();
6699 bgp_static->backdoor = backdoor;
6700 bgp_static->valid = 0;
6701 bgp_static->igpmetric = 0;
6702 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6703 bgp_static->label_index = label_index;
6704
6705 if (rmap) {
6706 XFREE(MTYPE_ROUTE_MAP_NAME,
6707 bgp_static->rmap.name);
6708 route_map_counter_decrement(
6709 bgp_static->rmap.map);
6710 bgp_static->rmap.name =
6711 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6712 bgp_static->rmap.map =
6713 route_map_lookup_by_name(rmap);
6714 route_map_counter_increment(
6715 bgp_static->rmap.map);
6716 }
6717 bgp_dest_set_bgp_static_info(dest, bgp_static);
6718 }
6719
6720 bgp_static->valid = 1;
6721 if (need_update)
6722 bgp_static_withdraw(bgp, &p, afi, safi);
6723
6724 if (!bgp_static->backdoor)
6725 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6726 }
6727
6728 return CMD_SUCCESS;
6729 }
6730
6731 void bgp_static_add(struct bgp *bgp)
6732 {
6733 afi_t afi;
6734 safi_t safi;
6735 struct bgp_dest *dest;
6736 struct bgp_dest *rm;
6737 struct bgp_table *table;
6738 struct bgp_static *bgp_static;
6739
6740 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6741 FOREACH_AFI_SAFI (afi, safi)
6742 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6743 dest = bgp_route_next(dest)) {
6744 if (!bgp_dest_has_bgp_path_info_data(dest))
6745 continue;
6746
6747 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6748 || (safi == SAFI_EVPN)) {
6749 table = bgp_dest_get_bgp_table_info(dest);
6750
6751 for (rm = bgp_table_top(table); rm;
6752 rm = bgp_route_next(rm)) {
6753 bgp_static =
6754 bgp_dest_get_bgp_static_info(
6755 rm);
6756 bgp_static_update_safi(
6757 bgp, bgp_dest_get_prefix(rm),
6758 bgp_static, afi, safi);
6759 }
6760 } else {
6761 bgp_static_update(
6762 bgp, bgp_dest_get_prefix(dest),
6763 bgp_dest_get_bgp_static_info(dest), afi,
6764 safi);
6765 }
6766 }
6767 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6768 }
6769
6770 /* Called from bgp_delete(). Delete all static routes from the BGP
6771 instance. */
6772 void bgp_static_delete(struct bgp *bgp)
6773 {
6774 afi_t afi;
6775 safi_t safi;
6776 struct bgp_dest *dest;
6777 struct bgp_dest *rm;
6778 struct bgp_table *table;
6779 struct bgp_static *bgp_static;
6780
6781 FOREACH_AFI_SAFI (afi, safi)
6782 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6783 dest = bgp_route_next(dest)) {
6784 if (!bgp_dest_has_bgp_path_info_data(dest))
6785 continue;
6786
6787 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6788 || (safi == SAFI_EVPN)) {
6789 table = bgp_dest_get_bgp_table_info(dest);
6790
6791 for (rm = bgp_table_top(table); rm;
6792 rm = bgp_route_next(rm)) {
6793 bgp_static =
6794 bgp_dest_get_bgp_static_info(
6795 rm);
6796 if (!bgp_static)
6797 continue;
6798
6799 bgp_static_withdraw_safi(
6800 bgp, bgp_dest_get_prefix(rm),
6801 AFI_IP, safi,
6802 (struct prefix_rd *)
6803 bgp_dest_get_prefix(
6804 dest));
6805 bgp_static_free(bgp_static);
6806 bgp_dest_set_bgp_static_info(rm,
6807 NULL);
6808 bgp_dest_unlock_node(rm);
6809 }
6810 } else {
6811 bgp_static = bgp_dest_get_bgp_static_info(dest);
6812 bgp_static_withdraw(bgp,
6813 bgp_dest_get_prefix(dest),
6814 afi, safi);
6815 bgp_static_free(bgp_static);
6816 bgp_dest_set_bgp_static_info(dest, NULL);
6817 bgp_dest_unlock_node(dest);
6818 }
6819 }
6820 }
6821
6822 void bgp_static_redo_import_check(struct bgp *bgp)
6823 {
6824 afi_t afi;
6825 safi_t safi;
6826 struct bgp_dest *dest;
6827 struct bgp_dest *rm;
6828 struct bgp_table *table;
6829 struct bgp_static *bgp_static;
6830
6831 /* Use this flag to force reprocessing of the route */
6832 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6833 FOREACH_AFI_SAFI (afi, safi) {
6834 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6835 dest = bgp_route_next(dest)) {
6836 if (!bgp_dest_has_bgp_path_info_data(dest))
6837 continue;
6838
6839 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6840 || (safi == SAFI_EVPN)) {
6841 table = bgp_dest_get_bgp_table_info(dest);
6842
6843 for (rm = bgp_table_top(table); rm;
6844 rm = bgp_route_next(rm)) {
6845 bgp_static =
6846 bgp_dest_get_bgp_static_info(
6847 rm);
6848 bgp_static_update_safi(
6849 bgp, bgp_dest_get_prefix(rm),
6850 bgp_static, afi, safi);
6851 }
6852 } else {
6853 bgp_static = bgp_dest_get_bgp_static_info(dest);
6854 bgp_static_update(bgp,
6855 bgp_dest_get_prefix(dest),
6856 bgp_static, afi, safi);
6857 }
6858 }
6859 }
6860 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6861 }
6862
6863 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6864 safi_t safi)
6865 {
6866 struct bgp_table *table;
6867 struct bgp_dest *dest;
6868 struct bgp_path_info *pi;
6869
6870 /* Do not install the aggregate route if BGP is in the
6871 * process of termination.
6872 */
6873 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6874 || (bgp->peer_self == NULL))
6875 return;
6876
6877 table = bgp->rib[afi][safi];
6878 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6879 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6880 if (pi->peer == bgp->peer_self
6881 && ((pi->type == ZEBRA_ROUTE_BGP
6882 && pi->sub_type == BGP_ROUTE_STATIC)
6883 || (pi->type != ZEBRA_ROUTE_BGP
6884 && pi->sub_type
6885 == BGP_ROUTE_REDISTRIBUTE))) {
6886 bgp_aggregate_decrement(
6887 bgp, bgp_dest_get_prefix(dest), pi, afi,
6888 safi);
6889 bgp_unlink_nexthop(pi);
6890 bgp_path_info_delete(dest, pi);
6891 bgp_process(bgp, dest, afi, safi);
6892 }
6893 }
6894 }
6895 }
6896
6897 /*
6898 * Purge all networks and redistributed routes from routing table.
6899 * Invoked upon the instance going down.
6900 */
6901 void bgp_purge_static_redist_routes(struct bgp *bgp)
6902 {
6903 afi_t afi;
6904 safi_t safi;
6905
6906 FOREACH_AFI_SAFI (afi, safi)
6907 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6908 }
6909
6910 /*
6911 * gpz 110624
6912 * Currently this is used to set static routes for VPN and ENCAP.
6913 * I think it can probably be factored with bgp_static_set.
6914 */
6915 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6916 const char *ip_str, const char *rd_str,
6917 const char *label_str, const char *rmap_str,
6918 int evpn_type, const char *esi, const char *gwip,
6919 const char *ethtag, const char *routermac)
6920 {
6921 VTY_DECLVAR_CONTEXT(bgp, bgp);
6922 int ret;
6923 struct prefix p;
6924 struct prefix_rd prd;
6925 struct bgp_dest *pdest;
6926 struct bgp_dest *dest;
6927 struct bgp_table *table;
6928 struct bgp_static *bgp_static;
6929 mpls_label_t label = MPLS_INVALID_LABEL;
6930 struct prefix gw_ip;
6931
6932 /* validate ip prefix */
6933 ret = str2prefix(ip_str, &p);
6934 if (!ret) {
6935 vty_out(vty, "%% Malformed prefix\n");
6936 return CMD_WARNING_CONFIG_FAILED;
6937 }
6938 apply_mask(&p);
6939 if ((afi == AFI_L2VPN)
6940 && (bgp_build_evpn_prefix(evpn_type,
6941 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6942 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6943 return CMD_WARNING_CONFIG_FAILED;
6944 }
6945
6946 ret = str2prefix_rd(rd_str, &prd);
6947 if (!ret) {
6948 vty_out(vty, "%% Malformed rd\n");
6949 return CMD_WARNING_CONFIG_FAILED;
6950 }
6951
6952 if (label_str) {
6953 unsigned long label_val;
6954 label_val = strtoul(label_str, NULL, 10);
6955 encode_label(label_val, &label);
6956 }
6957
6958 if (safi == SAFI_EVPN) {
6959 if (esi && str2esi(esi, NULL) == 0) {
6960 vty_out(vty, "%% Malformed ESI\n");
6961 return CMD_WARNING_CONFIG_FAILED;
6962 }
6963 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6964 vty_out(vty, "%% Malformed Router MAC\n");
6965 return CMD_WARNING_CONFIG_FAILED;
6966 }
6967 if (gwip) {
6968 memset(&gw_ip, 0, sizeof(gw_ip));
6969 ret = str2prefix(gwip, &gw_ip);
6970 if (!ret) {
6971 vty_out(vty, "%% Malformed GatewayIp\n");
6972 return CMD_WARNING_CONFIG_FAILED;
6973 }
6974 if ((gw_ip.family == AF_INET
6975 && is_evpn_prefix_ipaddr_v6(
6976 (struct prefix_evpn *)&p))
6977 || (gw_ip.family == AF_INET6
6978 && is_evpn_prefix_ipaddr_v4(
6979 (struct prefix_evpn *)&p))) {
6980 vty_out(vty,
6981 "%% GatewayIp family differs with IP prefix\n");
6982 return CMD_WARNING_CONFIG_FAILED;
6983 }
6984 }
6985 }
6986 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6987 if (!bgp_dest_has_bgp_path_info_data(pdest))
6988 bgp_dest_set_bgp_table_info(pdest,
6989 bgp_table_init(bgp, afi, safi));
6990 table = bgp_dest_get_bgp_table_info(pdest);
6991
6992 dest = bgp_node_get(table, &p);
6993
6994 if (bgp_dest_has_bgp_path_info_data(dest)) {
6995 vty_out(vty, "%% Same network configuration exists\n");
6996 bgp_dest_unlock_node(dest);
6997 } else {
6998 /* New configuration. */
6999 bgp_static = bgp_static_new();
7000 bgp_static->backdoor = 0;
7001 bgp_static->valid = 0;
7002 bgp_static->igpmetric = 0;
7003 bgp_static->igpnexthop.s_addr = INADDR_ANY;
7004 bgp_static->label = label;
7005 bgp_static->prd = prd;
7006
7007 if (rd_str)
7008 bgp_static->prd_pretty = XSTRDUP(MTYPE_BGP, rd_str);
7009 if (rmap_str) {
7010 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
7011 route_map_counter_decrement(bgp_static->rmap.map);
7012 bgp_static->rmap.name =
7013 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
7014 bgp_static->rmap.map =
7015 route_map_lookup_by_name(rmap_str);
7016 route_map_counter_increment(bgp_static->rmap.map);
7017 }
7018
7019 if (safi == SAFI_EVPN) {
7020 if (esi) {
7021 bgp_static->eth_s_id =
7022 XCALLOC(MTYPE_ATTR,
7023 sizeof(esi_t));
7024 str2esi(esi, bgp_static->eth_s_id);
7025 }
7026 if (routermac) {
7027 bgp_static->router_mac =
7028 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
7029 (void)prefix_str2mac(routermac,
7030 bgp_static->router_mac);
7031 }
7032 if (gwip)
7033 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
7034 }
7035 bgp_dest_set_bgp_static_info(dest, bgp_static);
7036
7037 bgp_static->valid = 1;
7038 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
7039 }
7040
7041 return CMD_SUCCESS;
7042 }
7043
7044 /* Configure static BGP network. */
7045 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
7046 const char *ip_str, const char *rd_str,
7047 const char *label_str, int evpn_type, const char *esi,
7048 const char *gwip, const char *ethtag)
7049 {
7050 VTY_DECLVAR_CONTEXT(bgp, bgp);
7051 int ret;
7052 struct prefix p;
7053 struct prefix_rd prd;
7054 struct bgp_dest *pdest;
7055 struct bgp_dest *dest;
7056 struct bgp_table *table;
7057 struct bgp_static *bgp_static;
7058 mpls_label_t label = MPLS_INVALID_LABEL;
7059
7060 /* Convert IP prefix string to struct prefix. */
7061 ret = str2prefix(ip_str, &p);
7062 if (!ret) {
7063 vty_out(vty, "%% Malformed prefix\n");
7064 return CMD_WARNING_CONFIG_FAILED;
7065 }
7066 apply_mask(&p);
7067 if ((afi == AFI_L2VPN)
7068 && (bgp_build_evpn_prefix(evpn_type,
7069 ethtag != NULL ? atol(ethtag) : 0, &p))) {
7070 vty_out(vty, "%% L2VPN prefix could not be forged\n");
7071 return CMD_WARNING_CONFIG_FAILED;
7072 }
7073 ret = str2prefix_rd(rd_str, &prd);
7074 if (!ret) {
7075 vty_out(vty, "%% Malformed rd\n");
7076 return CMD_WARNING_CONFIG_FAILED;
7077 }
7078
7079 if (label_str) {
7080 unsigned long label_val;
7081 label_val = strtoul(label_str, NULL, 10);
7082 encode_label(label_val, &label);
7083 }
7084
7085 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
7086 if (!bgp_dest_has_bgp_path_info_data(pdest))
7087 bgp_dest_set_bgp_table_info(pdest,
7088 bgp_table_init(bgp, afi, safi));
7089 else
7090 bgp_dest_unlock_node(pdest);
7091 table = bgp_dest_get_bgp_table_info(pdest);
7092
7093 dest = bgp_node_lookup(table, &p);
7094
7095 if (dest) {
7096 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
7097
7098 bgp_static = bgp_dest_get_bgp_static_info(dest);
7099 bgp_static_free(bgp_static);
7100 bgp_dest_set_bgp_static_info(dest, NULL);
7101 bgp_dest_unlock_node(dest);
7102 bgp_dest_unlock_node(dest);
7103 } else
7104 vty_out(vty, "%% Can't find the route\n");
7105
7106 return CMD_SUCCESS;
7107 }
7108
7109 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
7110 const char *rmap_name)
7111 {
7112 VTY_DECLVAR_CONTEXT(bgp, bgp);
7113 struct bgp_rmap *rmap;
7114
7115 rmap = &bgp->table_map[afi][safi];
7116 if (rmap_name) {
7117 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7118 route_map_counter_decrement(rmap->map);
7119 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
7120 rmap->map = route_map_lookup_by_name(rmap_name);
7121 route_map_counter_increment(rmap->map);
7122 } else {
7123 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7124 route_map_counter_decrement(rmap->map);
7125 rmap->map = NULL;
7126 }
7127
7128 if (bgp_fibupd_safi(safi))
7129 bgp_zebra_announce_table(bgp, afi, safi);
7130
7131 return CMD_SUCCESS;
7132 }
7133
7134 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
7135 const char *rmap_name)
7136 {
7137 VTY_DECLVAR_CONTEXT(bgp, bgp);
7138 struct bgp_rmap *rmap;
7139
7140 rmap = &bgp->table_map[afi][safi];
7141 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
7142 route_map_counter_decrement(rmap->map);
7143 rmap->map = NULL;
7144
7145 if (bgp_fibupd_safi(safi))
7146 bgp_zebra_announce_table(bgp, afi, safi);
7147
7148 return CMD_SUCCESS;
7149 }
7150
7151 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
7152 safi_t safi)
7153 {
7154 if (bgp->table_map[afi][safi].name) {
7155 vty_out(vty, " table-map %s\n",
7156 bgp->table_map[afi][safi].name);
7157 }
7158 }
7159
7160 DEFUN (bgp_table_map,
7161 bgp_table_map_cmd,
7162 "table-map WORD",
7163 "BGP table to RIB route download filter\n"
7164 "Name of the route map\n")
7165 {
7166 int idx_word = 1;
7167 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7168 argv[idx_word]->arg);
7169 }
7170 DEFUN (no_bgp_table_map,
7171 no_bgp_table_map_cmd,
7172 "no table-map WORD",
7173 NO_STR
7174 "BGP table to RIB route download filter\n"
7175 "Name of the route map\n")
7176 {
7177 int idx_word = 2;
7178 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
7179 argv[idx_word]->arg);
7180 }
7181
7182 DEFPY(bgp_network,
7183 bgp_network_cmd,
7184 "[no] network \
7185 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
7186 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index| \
7187 backdoor$backdoor}]",
7188 NO_STR
7189 "Specify a network to announce via BGP\n"
7190 "IPv4 prefix\n"
7191 "Network number\n"
7192 "Network mask\n"
7193 "Network mask\n"
7194 "Route-map to modify the attributes\n"
7195 "Name of the route map\n"
7196 "Label index to associate with the prefix\n"
7197 "Label index value\n"
7198 "Specify a BGP backdoor route\n")
7199 {
7200 char addr_prefix_str[BUFSIZ];
7201
7202 if (address_str) {
7203 int ret;
7204
7205 ret = netmask_str2prefix_str(address_str, netmask_str,
7206 addr_prefix_str,
7207 sizeof(addr_prefix_str));
7208 if (!ret) {
7209 vty_out(vty, "%% Inconsistent address and mask\n");
7210 return CMD_WARNING_CONFIG_FAILED;
7211 }
7212 }
7213
7214 return bgp_static_set(
7215 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
7216 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
7217 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7218 }
7219
7220 DEFPY(ipv6_bgp_network,
7221 ipv6_bgp_network_cmd,
7222 "[no] network X:X::X:X/M$prefix \
7223 [{route-map RMAP_NAME$map_name|label-index (0-1048560)$label_index}]",
7224 NO_STR
7225 "Specify a network to announce via BGP\n"
7226 "IPv6 prefix\n"
7227 "Route-map to modify the attributes\n"
7228 "Name of the route map\n"
7229 "Label index to associate with the prefix\n"
7230 "Label index value\n")
7231 {
7232 return bgp_static_set(
7233 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
7234 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
7235 }
7236
7237 static struct bgp_aggregate *bgp_aggregate_new(void)
7238 {
7239 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
7240 }
7241
7242 void bgp_aggregate_free(struct bgp_aggregate *aggregate)
7243 {
7244 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7245 route_map_counter_decrement(aggregate->suppress_map);
7246 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7247 route_map_counter_decrement(aggregate->rmap.map);
7248 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
7249 }
7250
7251 /**
7252 * Helper function to avoid repeated code: prepare variables for a
7253 * `route_map_apply` call.
7254 *
7255 * \returns `true` on route map match, otherwise `false`.
7256 */
7257 static bool aggr_suppress_map_test(struct bgp *bgp,
7258 struct bgp_aggregate *aggregate,
7259 struct bgp_path_info *pi)
7260 {
7261 const struct prefix *p = bgp_dest_get_prefix(pi->net);
7262 route_map_result_t rmr = RMAP_DENYMATCH;
7263 struct bgp_path_info rmap_path = {};
7264 struct attr attr = {};
7265
7266 /* No route map entries created, just don't match. */
7267 if (aggregate->suppress_map == NULL)
7268 return false;
7269
7270 /* Call route map matching and return result. */
7271 attr.aspath = aspath_empty(bgp->asnotation);
7272 rmap_path.peer = bgp->peer_self;
7273 rmap_path.attr = &attr;
7274
7275 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
7276 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
7277 bgp->peer_self->rmap_type = 0;
7278
7279 bgp_attr_flush(&attr);
7280 aspath_unintern(&attr.aspath);
7281
7282 return rmr == RMAP_PERMITMATCH;
7283 }
7284
7285 /** Test whether the aggregation has suppressed this path or not. */
7286 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
7287 struct bgp_path_info *pi)
7288 {
7289 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
7290 return false;
7291
7292 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
7293 }
7294
7295 /**
7296 * Suppress this path and keep the reference.
7297 *
7298 * \returns `true` if needs processing otherwise `false`.
7299 */
7300 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
7301 struct bgp_path_info *pi)
7302 {
7303 struct bgp_path_info_extra *pie;
7304
7305 /* Path is already suppressed by this aggregation. */
7306 if (aggr_suppress_exists(aggregate, pi))
7307 return false;
7308
7309 pie = bgp_path_info_extra_get(pi);
7310
7311 /* This is the first suppression, allocate memory and list it. */
7312 if (pie->aggr_suppressors == NULL)
7313 pie->aggr_suppressors = list_new();
7314
7315 listnode_add(pie->aggr_suppressors, aggregate);
7316
7317 /* Only mark for processing if suppressed. */
7318 if (listcount(pie->aggr_suppressors) == 1) {
7319 if (BGP_DEBUG(update, UPDATE_OUT))
7320 zlog_debug("aggregate-address suppressing: %pFX",
7321 bgp_dest_get_prefix(pi->net));
7322
7323 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7324 return true;
7325 }
7326
7327 return false;
7328 }
7329
7330 /**
7331 * Unsuppress this path and remove the reference.
7332 *
7333 * \returns `true` if needs processing otherwise `false`.
7334 */
7335 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7336 struct bgp_path_info *pi)
7337 {
7338 /* Path wasn't suppressed. */
7339 if (!aggr_suppress_exists(aggregate, pi))
7340 return false;
7341
7342 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7343
7344 /* Unsuppress and free extra memory if last item. */
7345 if (listcount(pi->extra->aggr_suppressors) == 0) {
7346 if (BGP_DEBUG(update, UPDATE_OUT))
7347 zlog_debug("aggregate-address unsuppressing: %pFX",
7348 bgp_dest_get_prefix(pi->net));
7349
7350 list_delete(&pi->extra->aggr_suppressors);
7351 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7352 return true;
7353 }
7354
7355 return false;
7356 }
7357
7358 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7359 struct aspath *aspath,
7360 struct community *comm,
7361 struct ecommunity *ecomm,
7362 struct lcommunity *lcomm)
7363 {
7364 static struct aspath *ae = NULL;
7365 enum asnotation_mode asnotation;
7366
7367 asnotation = bgp_get_asnotation(NULL);
7368
7369 if (!ae)
7370 ae = aspath_empty(asnotation);
7371
7372 if (!pi)
7373 return false;
7374
7375 if (origin != pi->attr->origin)
7376 return false;
7377
7378 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7379 return false;
7380
7381 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7382 return false;
7383
7384 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7385 return false;
7386
7387 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7388 return false;
7389
7390 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7391 return false;
7392
7393 return true;
7394 }
7395
7396 static void bgp_aggregate_install(
7397 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7398 uint8_t origin, struct aspath *aspath, struct community *community,
7399 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7400 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7401 {
7402 struct bgp_dest *dest;
7403 struct bgp_table *table;
7404 struct bgp_path_info *pi, *orig, *new;
7405 struct attr *attr;
7406
7407 table = bgp->rib[afi][safi];
7408
7409 dest = bgp_node_get(table, p);
7410
7411 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7412 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7413 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7414 break;
7415
7416 /*
7417 * If we have paths with different MEDs, then don't install
7418 * (or uninstall) the aggregate route.
7419 */
7420 if (aggregate->match_med && aggregate->med_mismatched)
7421 goto uninstall_aggregate_route;
7422
7423 if (aggregate->count > 0) {
7424 /*
7425 * If the aggregate information has not changed
7426 * no need to re-install it again.
7427 */
7428 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7429 ecommunity, lcommunity)) {
7430 bgp_dest_unlock_node(dest);
7431
7432 if (aspath)
7433 aspath_free(aspath);
7434 if (community)
7435 community_free(&community);
7436 if (ecommunity)
7437 ecommunity_free(&ecommunity);
7438 if (lcommunity)
7439 lcommunity_free(&lcommunity);
7440
7441 return;
7442 }
7443
7444 /*
7445 * Mark the old as unusable
7446 */
7447 if (pi)
7448 bgp_path_info_delete(dest, pi);
7449
7450 attr = bgp_attr_aggregate_intern(
7451 bgp, origin, aspath, community, ecommunity, lcommunity,
7452 aggregate, atomic_aggregate, p);
7453
7454 if (!attr) {
7455 aspath_free(aspath);
7456 community_free(&community);
7457 ecommunity_free(&ecommunity);
7458 lcommunity_free(&lcommunity);
7459 bgp_dest_unlock_node(dest);
7460 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7461 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7462 zlog_debug("%s: %pFX null attribute", __func__,
7463 p);
7464 return;
7465 }
7466
7467 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7468 bgp->peer_self, attr, dest);
7469
7470 SET_FLAG(new->flags, BGP_PATH_VALID);
7471
7472 bgp_path_info_add(dest, new);
7473 bgp_process(bgp, dest, afi, safi);
7474 } else {
7475 uninstall_aggregate_route:
7476 for (pi = orig; pi; pi = pi->next)
7477 if (pi->peer == bgp->peer_self
7478 && pi->type == ZEBRA_ROUTE_BGP
7479 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7480 break;
7481
7482 /* Withdraw static BGP route from routing table. */
7483 if (pi) {
7484 bgp_path_info_delete(dest, pi);
7485 bgp_process(bgp, dest, afi, safi);
7486 }
7487 }
7488
7489 bgp_dest_unlock_node(dest);
7490 }
7491
7492 /**
7493 * Check if the current path has different MED than other known paths.
7494 *
7495 * \returns `true` if the MED matched the others else `false`.
7496 */
7497 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7498 struct bgp *bgp, struct bgp_path_info *pi)
7499 {
7500 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7501
7502 /* This is the first route being analyzed. */
7503 if (!aggregate->med_initialized) {
7504 aggregate->med_initialized = true;
7505 aggregate->med_mismatched = false;
7506 aggregate->med_matched_value = cur_med;
7507 } else {
7508 /* Check if routes with different MED showed up. */
7509 if (cur_med != aggregate->med_matched_value)
7510 aggregate->med_mismatched = true;
7511 }
7512
7513 return !aggregate->med_mismatched;
7514 }
7515
7516 /**
7517 * Initializes and tests all routes in the aggregate address path for MED
7518 * values.
7519 *
7520 * \returns `true` if all MEDs are the same otherwise `false`.
7521 */
7522 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7523 struct bgp *bgp, const struct prefix *p,
7524 afi_t afi, safi_t safi)
7525 {
7526 struct bgp_table *table = bgp->rib[afi][safi];
7527 const struct prefix *dest_p;
7528 struct bgp_dest *dest, *top;
7529 struct bgp_path_info *pi;
7530 bool med_matched = true;
7531
7532 aggregate->med_initialized = false;
7533
7534 top = bgp_node_get(table, p);
7535 for (dest = bgp_node_get(table, p); dest;
7536 dest = bgp_route_next_until(dest, top)) {
7537 dest_p = bgp_dest_get_prefix(dest);
7538 if (dest_p->prefixlen <= p->prefixlen)
7539 continue;
7540
7541 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7542 if (BGP_PATH_HOLDDOWN(pi))
7543 continue;
7544 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7545 continue;
7546 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7547 med_matched = false;
7548 break;
7549 }
7550 }
7551 if (!med_matched)
7552 break;
7553 }
7554 bgp_dest_unlock_node(top);
7555
7556 return med_matched;
7557 }
7558
7559 /**
7560 * Toggles the route suppression status for this aggregate address
7561 * configuration.
7562 */
7563 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7564 struct bgp *bgp, const struct prefix *p,
7565 afi_t afi, safi_t safi, bool suppress)
7566 {
7567 struct bgp_table *table = bgp->rib[afi][safi];
7568 const struct prefix *dest_p;
7569 struct bgp_dest *dest, *top;
7570 struct bgp_path_info *pi;
7571 bool toggle_suppression;
7572
7573 /* We've found a different MED we must revert any suppressed routes. */
7574 top = bgp_node_get(table, p);
7575 for (dest = bgp_node_get(table, p); dest;
7576 dest = bgp_route_next_until(dest, top)) {
7577 dest_p = bgp_dest_get_prefix(dest);
7578 if (dest_p->prefixlen <= p->prefixlen)
7579 continue;
7580
7581 toggle_suppression = false;
7582 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7583 if (BGP_PATH_HOLDDOWN(pi))
7584 continue;
7585 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7586 continue;
7587
7588 /* We are toggling suppression back. */
7589 if (suppress) {
7590 /* Suppress route if not suppressed already. */
7591 if (aggr_suppress_path(aggregate, pi))
7592 toggle_suppression = true;
7593 continue;
7594 }
7595
7596 /* Install route if there is no more suppression. */
7597 if (aggr_unsuppress_path(aggregate, pi))
7598 toggle_suppression = true;
7599 }
7600
7601 if (toggle_suppression)
7602 bgp_process(bgp, dest, afi, safi);
7603 }
7604 bgp_dest_unlock_node(top);
7605 }
7606
7607 /**
7608 * Aggregate address MED matching incremental test: this function is called
7609 * when the initial aggregation occurred and we are only testing a single
7610 * new path.
7611 *
7612 * In addition to testing and setting the MED validity it also installs back
7613 * suppressed routes (if summary is configured).
7614 *
7615 * Must not be called in `bgp_aggregate_route`.
7616 */
7617 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7618 struct bgp *bgp, const struct prefix *p,
7619 afi_t afi, safi_t safi,
7620 struct bgp_path_info *pi)
7621 {
7622 /* MED matching disabled. */
7623 if (!aggregate->match_med)
7624 return;
7625
7626 /* Aggregation with different MED, recheck if we have got equal MEDs
7627 * now.
7628 */
7629 if (aggregate->med_mismatched &&
7630 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi) &&
7631 aggregate->summary_only)
7632 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi,
7633 true);
7634 else
7635 bgp_aggregate_med_match(aggregate, bgp, pi);
7636
7637 /* No mismatches, just quit. */
7638 if (!aggregate->med_mismatched)
7639 return;
7640
7641 /* Route summarization is disabled. */
7642 if (!aggregate->summary_only)
7643 return;
7644
7645 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7646 }
7647
7648 /* Update an aggregate as routes are added/removed from the BGP table */
7649 bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7650 safi_t safi, struct bgp_aggregate *aggregate)
7651 {
7652 struct bgp_table *table;
7653 struct bgp_dest *top;
7654 struct bgp_dest *dest;
7655 uint8_t origin;
7656 struct aspath *aspath = NULL;
7657 struct community *community = NULL;
7658 struct ecommunity *ecommunity = NULL;
7659 struct lcommunity *lcommunity = NULL;
7660 struct bgp_path_info *pi;
7661 unsigned long match = 0;
7662 uint8_t atomic_aggregate = 0;
7663
7664 /* If the bgp instance is being deleted or self peer is deleted
7665 * then do not create aggregate route
7666 */
7667 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
7668 bgp->peer_self == NULL)
7669 return false;
7670
7671 /* Initialize and test routes for MED difference. */
7672 if (aggregate->match_med)
7673 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7674
7675 /*
7676 * Reset aggregate count: we might've been called from route map
7677 * update so in that case we must retest all more specific routes.
7678 *
7679 * \see `bgp_route_map_process_update`.
7680 */
7681 aggregate->count = 0;
7682 aggregate->incomplete_origin_count = 0;
7683 aggregate->incomplete_origin_count = 0;
7684 aggregate->egp_origin_count = 0;
7685
7686 /* ORIGIN attribute: If at least one route among routes that are
7687 aggregated has ORIGIN with the value INCOMPLETE, then the
7688 aggregated route must have the ORIGIN attribute with the value
7689 INCOMPLETE. Otherwise, if at least one route among routes that
7690 are aggregated has ORIGIN with the value EGP, then the aggregated
7691 route must have the origin attribute with the value EGP. In all
7692 other case the value of the ORIGIN attribute of the aggregated
7693 route is INTERNAL. */
7694 origin = BGP_ORIGIN_IGP;
7695
7696 table = bgp->rib[afi][safi];
7697
7698 top = bgp_node_get(table, p);
7699 for (dest = bgp_node_get(table, p); dest;
7700 dest = bgp_route_next_until(dest, top)) {
7701 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7702
7703 if (dest_p->prefixlen <= p->prefixlen)
7704 continue;
7705
7706 /* If suppress fib is enabled and route not installed
7707 * in FIB, skip the route
7708 */
7709 if (!bgp_check_advertise(bgp, dest))
7710 continue;
7711
7712 match = 0;
7713
7714 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7715 if (BGP_PATH_HOLDDOWN(pi))
7716 continue;
7717
7718 if (pi->attr->flag
7719 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7720 atomic_aggregate = 1;
7721
7722 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7723 continue;
7724
7725 /*
7726 * summary-only aggregate route suppress
7727 * aggregated route announcements.
7728 *
7729 * MED matching:
7730 * Don't create summaries if MED didn't match
7731 * otherwise neither the specific routes and the
7732 * aggregation will be announced.
7733 */
7734 if (aggregate->summary_only
7735 && AGGREGATE_MED_VALID(aggregate)) {
7736 if (aggr_suppress_path(aggregate, pi))
7737 match++;
7738 }
7739
7740 /*
7741 * Suppress more specific routes that match the route
7742 * map results.
7743 *
7744 * MED matching:
7745 * Don't suppress routes if MED matching is enabled and
7746 * it mismatched otherwise we might end up with no
7747 * routes for this path.
7748 */
7749 if (aggregate->suppress_map_name
7750 && AGGREGATE_MED_VALID(aggregate)
7751 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7752 if (aggr_suppress_path(aggregate, pi))
7753 match++;
7754 }
7755
7756 aggregate->count++;
7757
7758 /*
7759 * If at least one route among routes that are
7760 * aggregated has ORIGIN with the value INCOMPLETE,
7761 * then the aggregated route MUST have the ORIGIN
7762 * attribute with the value INCOMPLETE. Otherwise, if
7763 * at least one route among routes that are aggregated
7764 * has ORIGIN with the value EGP, then the aggregated
7765 * route MUST have the ORIGIN attribute with the value
7766 * EGP.
7767 */
7768 switch (pi->attr->origin) {
7769 case BGP_ORIGIN_INCOMPLETE:
7770 aggregate->incomplete_origin_count++;
7771 break;
7772 case BGP_ORIGIN_EGP:
7773 aggregate->egp_origin_count++;
7774 break;
7775 default:
7776 /*Do nothing.
7777 */
7778 break;
7779 }
7780
7781 if (!aggregate->as_set)
7782 continue;
7783
7784 /*
7785 * as-set aggregate route generate origin, as path,
7786 * and community aggregation.
7787 */
7788 /* Compute aggregate route's as-path.
7789 */
7790 bgp_compute_aggregate_aspath_hash(aggregate,
7791 pi->attr->aspath);
7792
7793 /* Compute aggregate route's community.
7794 */
7795 if (bgp_attr_get_community(pi->attr))
7796 bgp_compute_aggregate_community_hash(
7797 aggregate,
7798 bgp_attr_get_community(pi->attr));
7799
7800 /* Compute aggregate route's extended community.
7801 */
7802 if (bgp_attr_get_ecommunity(pi->attr))
7803 bgp_compute_aggregate_ecommunity_hash(
7804 aggregate,
7805 bgp_attr_get_ecommunity(pi->attr));
7806
7807 /* Compute aggregate route's large community.
7808 */
7809 if (bgp_attr_get_lcommunity(pi->attr))
7810 bgp_compute_aggregate_lcommunity_hash(
7811 aggregate,
7812 bgp_attr_get_lcommunity(pi->attr));
7813 }
7814 if (match)
7815 bgp_process(bgp, dest, afi, safi);
7816 }
7817 if (aggregate->as_set) {
7818 bgp_compute_aggregate_aspath_val(aggregate);
7819 bgp_compute_aggregate_community_val(aggregate);
7820 bgp_compute_aggregate_ecommunity_val(aggregate);
7821 bgp_compute_aggregate_lcommunity_val(aggregate);
7822 }
7823
7824
7825 bgp_dest_unlock_node(top);
7826
7827
7828 if (aggregate->incomplete_origin_count > 0)
7829 origin = BGP_ORIGIN_INCOMPLETE;
7830 else if (aggregate->egp_origin_count > 0)
7831 origin = BGP_ORIGIN_EGP;
7832
7833 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7834 origin = aggregate->origin;
7835
7836 if (aggregate->as_set) {
7837 if (aggregate->aspath)
7838 /* Retrieve aggregate route's as-path.
7839 */
7840 aspath = aspath_dup(aggregate->aspath);
7841
7842 if (aggregate->community)
7843 /* Retrieve aggregate route's community.
7844 */
7845 community = community_dup(aggregate->community);
7846
7847 if (aggregate->ecommunity)
7848 /* Retrieve aggregate route's ecommunity.
7849 */
7850 ecommunity = ecommunity_dup(aggregate->ecommunity);
7851
7852 if (aggregate->lcommunity)
7853 /* Retrieve aggregate route's lcommunity.
7854 */
7855 lcommunity = lcommunity_dup(aggregate->lcommunity);
7856 }
7857
7858 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7859 ecommunity, lcommunity, atomic_aggregate,
7860 aggregate);
7861
7862 return true;
7863 }
7864
7865 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7866 safi_t safi, struct bgp_aggregate *aggregate)
7867 {
7868 struct bgp_table *table;
7869 struct bgp_dest *top;
7870 struct bgp_dest *dest;
7871 struct bgp_path_info *pi;
7872 unsigned long match;
7873
7874 table = bgp->rib[afi][safi];
7875
7876 /* If routes exists below this node, generate aggregate routes. */
7877 top = bgp_node_get(table, p);
7878 for (dest = bgp_node_get(table, p); dest;
7879 dest = bgp_route_next_until(dest, top)) {
7880 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7881
7882 if (dest_p->prefixlen <= p->prefixlen)
7883 continue;
7884 match = 0;
7885
7886 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7887 if (BGP_PATH_HOLDDOWN(pi))
7888 continue;
7889
7890 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7891 continue;
7892
7893 /*
7894 * This route is suppressed: attempt to unsuppress it.
7895 *
7896 * `aggr_unsuppress_path` will fail if this particular
7897 * aggregate route was not the suppressor.
7898 */
7899 if (pi->extra && pi->extra->aggr_suppressors &&
7900 listcount(pi->extra->aggr_suppressors)) {
7901 if (aggr_unsuppress_path(aggregate, pi))
7902 match++;
7903 }
7904
7905 aggregate->count--;
7906
7907 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7908 aggregate->incomplete_origin_count--;
7909 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7910 aggregate->egp_origin_count--;
7911
7912 if (aggregate->as_set) {
7913 /* Remove as-path from aggregate.
7914 */
7915 bgp_remove_aspath_from_aggregate_hash(
7916 aggregate,
7917 pi->attr->aspath);
7918
7919 if (bgp_attr_get_community(pi->attr))
7920 /* Remove community from aggregate.
7921 */
7922 bgp_remove_comm_from_aggregate_hash(
7923 aggregate,
7924 bgp_attr_get_community(
7925 pi->attr));
7926
7927 if (bgp_attr_get_ecommunity(pi->attr))
7928 /* Remove ecommunity from aggregate.
7929 */
7930 bgp_remove_ecomm_from_aggregate_hash(
7931 aggregate,
7932 bgp_attr_get_ecommunity(
7933 pi->attr));
7934
7935 if (bgp_attr_get_lcommunity(pi->attr))
7936 /* Remove lcommunity from aggregate.
7937 */
7938 bgp_remove_lcomm_from_aggregate_hash(
7939 aggregate,
7940 bgp_attr_get_lcommunity(
7941 pi->attr));
7942 }
7943 }
7944
7945 /* If this node was suppressed, process the change. */
7946 if (match)
7947 bgp_process(bgp, dest, afi, safi);
7948 }
7949 if (aggregate->as_set) {
7950 aspath_free(aggregate->aspath);
7951 aggregate->aspath = NULL;
7952 if (aggregate->community)
7953 community_free(&aggregate->community);
7954 if (aggregate->ecommunity)
7955 ecommunity_free(&aggregate->ecommunity);
7956 if (aggregate->lcommunity)
7957 lcommunity_free(&aggregate->lcommunity);
7958 }
7959
7960 bgp_dest_unlock_node(top);
7961 }
7962
7963 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7964 const struct prefix *aggr_p,
7965 struct bgp_path_info *pinew, afi_t afi,
7966 safi_t safi,
7967 struct bgp_aggregate *aggregate)
7968 {
7969 uint8_t origin;
7970 struct aspath *aspath = NULL;
7971 uint8_t atomic_aggregate = 0;
7972 struct community *community = NULL;
7973 struct ecommunity *ecommunity = NULL;
7974 struct lcommunity *lcommunity = NULL;
7975
7976 /* If the bgp instance is being deleted or self peer is deleted
7977 * then do not create aggregate route
7978 */
7979 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7980 || (bgp->peer_self == NULL))
7981 return;
7982
7983 /* ORIGIN attribute: If at least one route among routes that are
7984 * aggregated has ORIGIN with the value INCOMPLETE, then the
7985 * aggregated route must have the ORIGIN attribute with the value
7986 * INCOMPLETE. Otherwise, if at least one route among routes that
7987 * are aggregated has ORIGIN with the value EGP, then the aggregated
7988 * route must have the origin attribute with the value EGP. In all
7989 * other case the value of the ORIGIN attribute of the aggregated
7990 * route is INTERNAL.
7991 */
7992 origin = BGP_ORIGIN_IGP;
7993
7994 aggregate->count++;
7995
7996 /*
7997 * This must be called before `summary` check to avoid
7998 * "suppressing" twice.
7999 */
8000 if (aggregate->match_med)
8001 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
8002 pinew);
8003
8004 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8005 aggr_suppress_path(aggregate, pinew);
8006
8007 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8008 && aggr_suppress_map_test(bgp, aggregate, pinew))
8009 aggr_suppress_path(aggregate, pinew);
8010
8011 switch (pinew->attr->origin) {
8012 case BGP_ORIGIN_INCOMPLETE:
8013 aggregate->incomplete_origin_count++;
8014 break;
8015 case BGP_ORIGIN_EGP:
8016 aggregate->egp_origin_count++;
8017 break;
8018 default:
8019 /* Do nothing.
8020 */
8021 break;
8022 }
8023
8024 if (aggregate->incomplete_origin_count > 0)
8025 origin = BGP_ORIGIN_INCOMPLETE;
8026 else if (aggregate->egp_origin_count > 0)
8027 origin = BGP_ORIGIN_EGP;
8028
8029 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8030 origin = aggregate->origin;
8031
8032 if (aggregate->as_set) {
8033 /* Compute aggregate route's as-path.
8034 */
8035 bgp_compute_aggregate_aspath(aggregate,
8036 pinew->attr->aspath);
8037
8038 /* Compute aggregate route's community.
8039 */
8040 if (bgp_attr_get_community(pinew->attr))
8041 bgp_compute_aggregate_community(
8042 aggregate, bgp_attr_get_community(pinew->attr));
8043
8044 /* Compute aggregate route's extended community.
8045 */
8046 if (bgp_attr_get_ecommunity(pinew->attr))
8047 bgp_compute_aggregate_ecommunity(
8048 aggregate,
8049 bgp_attr_get_ecommunity(pinew->attr));
8050
8051 /* Compute aggregate route's large community.
8052 */
8053 if (bgp_attr_get_lcommunity(pinew->attr))
8054 bgp_compute_aggregate_lcommunity(
8055 aggregate,
8056 bgp_attr_get_lcommunity(pinew->attr));
8057
8058 /* Retrieve aggregate route's as-path.
8059 */
8060 if (aggregate->aspath)
8061 aspath = aspath_dup(aggregate->aspath);
8062
8063 /* Retrieve aggregate route's community.
8064 */
8065 if (aggregate->community)
8066 community = community_dup(aggregate->community);
8067
8068 /* Retrieve aggregate route's ecommunity.
8069 */
8070 if (aggregate->ecommunity)
8071 ecommunity = ecommunity_dup(aggregate->ecommunity);
8072
8073 /* Retrieve aggregate route's lcommunity.
8074 */
8075 if (aggregate->lcommunity)
8076 lcommunity = lcommunity_dup(aggregate->lcommunity);
8077 }
8078
8079 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8080 aspath, community, ecommunity,
8081 lcommunity, atomic_aggregate, aggregate);
8082 }
8083
8084 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
8085 safi_t safi,
8086 struct bgp_path_info *pi,
8087 struct bgp_aggregate *aggregate,
8088 const struct prefix *aggr_p)
8089 {
8090 uint8_t origin;
8091 struct aspath *aspath = NULL;
8092 uint8_t atomic_aggregate = 0;
8093 struct community *community = NULL;
8094 struct ecommunity *ecommunity = NULL;
8095 struct lcommunity *lcommunity = NULL;
8096 unsigned long match = 0;
8097
8098 /* If the bgp instance is being deleted or self peer is deleted
8099 * then do not create aggregate route
8100 */
8101 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
8102 || (bgp->peer_self == NULL))
8103 return;
8104
8105 if (BGP_PATH_HOLDDOWN(pi))
8106 return;
8107
8108 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
8109 return;
8110
8111 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
8112 if (aggr_unsuppress_path(aggregate, pi))
8113 match++;
8114
8115 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
8116 && aggr_suppress_map_test(bgp, aggregate, pi))
8117 if (aggr_unsuppress_path(aggregate, pi))
8118 match++;
8119
8120 /*
8121 * This must be called after `summary`, `suppress-map` check to avoid
8122 * "unsuppressing" twice.
8123 */
8124 if (aggregate->match_med)
8125 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi);
8126
8127 if (aggregate->count > 0)
8128 aggregate->count--;
8129
8130 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
8131 aggregate->incomplete_origin_count--;
8132 else if (pi->attr->origin == BGP_ORIGIN_EGP)
8133 aggregate->egp_origin_count--;
8134
8135 if (aggregate->as_set) {
8136 /* Remove as-path from aggregate.
8137 */
8138 bgp_remove_aspath_from_aggregate(aggregate,
8139 pi->attr->aspath);
8140
8141 if (bgp_attr_get_community(pi->attr))
8142 /* Remove community from aggregate.
8143 */
8144 bgp_remove_community_from_aggregate(
8145 aggregate, bgp_attr_get_community(pi->attr));
8146
8147 if (bgp_attr_get_ecommunity(pi->attr))
8148 /* Remove ecommunity from aggregate.
8149 */
8150 bgp_remove_ecommunity_from_aggregate(
8151 aggregate, bgp_attr_get_ecommunity(pi->attr));
8152
8153 if (bgp_attr_get_lcommunity(pi->attr))
8154 /* Remove lcommunity from aggregate.
8155 */
8156 bgp_remove_lcommunity_from_aggregate(
8157 aggregate, bgp_attr_get_lcommunity(pi->attr));
8158 }
8159
8160 /* If this node was suppressed, process the change. */
8161 if (match)
8162 bgp_process(bgp, pi->net, afi, safi);
8163
8164 origin = BGP_ORIGIN_IGP;
8165 if (aggregate->incomplete_origin_count > 0)
8166 origin = BGP_ORIGIN_INCOMPLETE;
8167 else if (aggregate->egp_origin_count > 0)
8168 origin = BGP_ORIGIN_EGP;
8169
8170 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
8171 origin = aggregate->origin;
8172
8173 if (aggregate->as_set) {
8174 /* Retrieve aggregate route's as-path.
8175 */
8176 if (aggregate->aspath)
8177 aspath = aspath_dup(aggregate->aspath);
8178
8179 /* Retrieve aggregate route's community.
8180 */
8181 if (aggregate->community)
8182 community = community_dup(aggregate->community);
8183
8184 /* Retrieve aggregate route's ecommunity.
8185 */
8186 if (aggregate->ecommunity)
8187 ecommunity = ecommunity_dup(aggregate->ecommunity);
8188
8189 /* Retrieve aggregate route's lcommunity.
8190 */
8191 if (aggregate->lcommunity)
8192 lcommunity = lcommunity_dup(aggregate->lcommunity);
8193 }
8194
8195 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
8196 aspath, community, ecommunity,
8197 lcommunity, atomic_aggregate, aggregate);
8198 }
8199
8200 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
8201 struct bgp_path_info *pi, afi_t afi, safi_t safi)
8202 {
8203 struct bgp_dest *child;
8204 struct bgp_dest *dest;
8205 struct bgp_aggregate *aggregate;
8206 struct bgp_table *table;
8207
8208 table = bgp->aggregate[afi][safi];
8209
8210 /* No aggregates configured. */
8211 if (bgp_table_top_nolock(table) == NULL)
8212 return;
8213
8214 if (p->prefixlen == 0)
8215 return;
8216
8217 if (BGP_PATH_HOLDDOWN(pi))
8218 return;
8219
8220 /* If suppress fib is enabled and route not installed
8221 * in FIB, do not update the aggregate route
8222 */
8223 if (!bgp_check_advertise(bgp, pi->net))
8224 return;
8225
8226 child = bgp_node_get(table, p);
8227
8228 /* Aggregate address configuration check. */
8229 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8230 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8231
8232 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8233 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8234 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
8235 aggregate);
8236 }
8237 }
8238 bgp_dest_unlock_node(child);
8239 }
8240
8241 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
8242 struct bgp_path_info *del, afi_t afi, safi_t safi)
8243 {
8244 struct bgp_dest *child;
8245 struct bgp_dest *dest;
8246 struct bgp_aggregate *aggregate;
8247 struct bgp_table *table;
8248
8249 table = bgp->aggregate[afi][safi];
8250
8251 /* No aggregates configured. */
8252 if (bgp_table_top_nolock(table) == NULL)
8253 return;
8254
8255 if (p->prefixlen == 0)
8256 return;
8257
8258 child = bgp_node_get(table, p);
8259
8260 /* Aggregate address configuration check. */
8261 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
8262 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
8263
8264 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8265 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
8266 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
8267 aggregate, dest_p);
8268 }
8269 }
8270 bgp_dest_unlock_node(child);
8271 }
8272
8273 /* Aggregate route attribute. */
8274 #define AGGREGATE_SUMMARY_ONLY 1
8275 #define AGGREGATE_AS_SET 1
8276 #define AGGREGATE_AS_UNSET 0
8277
8278 static const char *bgp_origin2str(uint8_t origin)
8279 {
8280 switch (origin) {
8281 case BGP_ORIGIN_IGP:
8282 return "igp";
8283 case BGP_ORIGIN_EGP:
8284 return "egp";
8285 case BGP_ORIGIN_INCOMPLETE:
8286 return "incomplete";
8287 }
8288 return "n/a";
8289 }
8290
8291 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
8292 {
8293 switch (v_state) {
8294 case RPKI_NOT_BEING_USED:
8295 return "not used";
8296 case RPKI_VALID:
8297 return "valid";
8298 case RPKI_NOTFOUND:
8299 return "not found";
8300 case RPKI_INVALID:
8301 return "invalid";
8302 }
8303
8304 assert(!"We should never get here this is a dev escape");
8305 return "ERROR";
8306 }
8307
8308 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
8309 afi_t afi, safi_t safi)
8310 {
8311 VTY_DECLVAR_CONTEXT(bgp, bgp);
8312 int ret;
8313 struct prefix p;
8314 struct bgp_dest *dest;
8315 struct bgp_aggregate *aggregate;
8316
8317 /* Convert string to prefix structure. */
8318 ret = str2prefix(prefix_str, &p);
8319 if (!ret) {
8320 vty_out(vty, "Malformed prefix\n");
8321 return CMD_WARNING_CONFIG_FAILED;
8322 }
8323 apply_mask(&p);
8324
8325 /* Old configuration check. */
8326 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8327 if (!dest) {
8328 vty_out(vty,
8329 "%% There is no aggregate-address configuration.\n");
8330 return CMD_WARNING_CONFIG_FAILED;
8331 }
8332
8333 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8334 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8335 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8336 NULL, NULL, 0, aggregate);
8337
8338 /* Unlock aggregate address configuration. */
8339 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8340
8341 if (aggregate->community)
8342 community_free(&aggregate->community);
8343
8344 hash_clean_and_free(&aggregate->community_hash,
8345 bgp_aggr_community_remove);
8346
8347 if (aggregate->ecommunity)
8348 ecommunity_free(&aggregate->ecommunity);
8349
8350 hash_clean_and_free(&aggregate->ecommunity_hash,
8351 bgp_aggr_ecommunity_remove);
8352
8353 if (aggregate->lcommunity)
8354 lcommunity_free(&aggregate->lcommunity);
8355
8356 hash_clean_and_free(&aggregate->lcommunity_hash,
8357 bgp_aggr_lcommunity_remove);
8358
8359 if (aggregate->aspath)
8360 aspath_free(aggregate->aspath);
8361
8362 hash_clean_and_free(&aggregate->aspath_hash, bgp_aggr_aspath_remove);
8363
8364 bgp_aggregate_free(aggregate);
8365 bgp_dest_unlock_node(dest);
8366 bgp_dest_unlock_node(dest);
8367
8368 return CMD_SUCCESS;
8369 }
8370
8371 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8372 safi_t safi, const char *rmap,
8373 uint8_t summary_only, uint8_t as_set,
8374 uint8_t origin, bool match_med,
8375 const char *suppress_map)
8376 {
8377 VTY_DECLVAR_CONTEXT(bgp, bgp);
8378 int ret;
8379 struct prefix p;
8380 struct bgp_dest *dest;
8381 struct bgp_aggregate *aggregate;
8382 uint8_t as_set_new = as_set;
8383
8384 if (suppress_map && summary_only) {
8385 vty_out(vty,
8386 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8387 return CMD_WARNING_CONFIG_FAILED;
8388 }
8389
8390 /* Convert string to prefix structure. */
8391 ret = str2prefix(prefix_str, &p);
8392 if (!ret) {
8393 vty_out(vty, "Malformed prefix\n");
8394 return CMD_WARNING_CONFIG_FAILED;
8395 }
8396 apply_mask(&p);
8397
8398 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8399 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8400 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8401 prefix_str);
8402 return CMD_WARNING_CONFIG_FAILED;
8403 }
8404
8405 /* Old configuration check. */
8406 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8407 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8408
8409 if (aggregate) {
8410 vty_out(vty, "There is already same aggregate network.\n");
8411 /* try to remove the old entry */
8412 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8413 if (ret) {
8414 vty_out(vty, "Error deleting aggregate.\n");
8415 bgp_dest_unlock_node(dest);
8416 return CMD_WARNING_CONFIG_FAILED;
8417 }
8418 }
8419
8420 /* Make aggregate address structure. */
8421 aggregate = bgp_aggregate_new();
8422 aggregate->summary_only = summary_only;
8423 aggregate->match_med = match_med;
8424
8425 /* Network operators MUST NOT locally generate any new
8426 * announcements containing AS_SET or AS_CONFED_SET. If they have
8427 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8428 * SHOULD withdraw those routes and re-announce routes for the
8429 * aggregate or component prefixes (i.e., the more-specific routes
8430 * subsumed by the previously aggregated route) without AS_SET
8431 * or AS_CONFED_SET in the updates.
8432 */
8433 if (bgp->reject_as_sets) {
8434 if (as_set == AGGREGATE_AS_SET) {
8435 as_set_new = AGGREGATE_AS_UNSET;
8436 zlog_warn(
8437 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8438 __func__);
8439 vty_out(vty,
8440 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8441 }
8442 }
8443
8444 aggregate->as_set = as_set_new;
8445 aggregate->safi = safi;
8446 /* Override ORIGIN attribute if defined.
8447 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8448 * to IGP which is not what rfc4271 says.
8449 * This enables the same behavior, optionally.
8450 */
8451 aggregate->origin = origin;
8452
8453 if (rmap) {
8454 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8455 route_map_counter_decrement(aggregate->rmap.map);
8456 aggregate->rmap.name =
8457 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8458 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8459 route_map_counter_increment(aggregate->rmap.map);
8460 }
8461
8462 if (suppress_map) {
8463 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8464 route_map_counter_decrement(aggregate->suppress_map);
8465
8466 aggregate->suppress_map_name =
8467 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8468 aggregate->suppress_map =
8469 route_map_lookup_by_name(aggregate->suppress_map_name);
8470 route_map_counter_increment(aggregate->suppress_map);
8471 }
8472
8473 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8474
8475 /* Aggregate address insert into BGP routing table. */
8476 if (!bgp_aggregate_route(bgp, &p, afi, safi, aggregate)) {
8477 bgp_aggregate_free(aggregate);
8478 bgp_dest_unlock_node(dest);
8479 }
8480
8481 return CMD_SUCCESS;
8482 }
8483
8484 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8485 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8486 "as-set$as_set_s"
8487 "|summary-only$summary_only"
8488 "|route-map RMAP_NAME$rmap_name"
8489 "|origin <egp|igp|incomplete>$origin_s"
8490 "|matching-MED-only$match_med"
8491 "|suppress-map RMAP_NAME$suppress_map"
8492 "}]",
8493 NO_STR
8494 "Configure BGP aggregate entries\n"
8495 "Aggregate prefix\n"
8496 "Aggregate address\n"
8497 "Aggregate mask\n"
8498 "Generate AS set path information\n"
8499 "Filter more specific routes from updates\n"
8500 "Apply route map to aggregate network\n"
8501 "Route map name\n"
8502 "BGP origin code\n"
8503 "Remote EGP\n"
8504 "Local IGP\n"
8505 "Unknown heritage\n"
8506 "Only aggregate routes with matching MED\n"
8507 "Suppress the selected more specific routes\n"
8508 "Route map with the route selectors\n")
8509 {
8510 const char *prefix_s = NULL;
8511 safi_t safi = bgp_node_safi(vty);
8512 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8513 int as_set = AGGREGATE_AS_UNSET;
8514 char prefix_buf[PREFIX2STR_BUFFER];
8515
8516 if (addr_str) {
8517 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8518 sizeof(prefix_buf))
8519 == 0) {
8520 vty_out(vty, "%% Inconsistent address and mask\n");
8521 return CMD_WARNING_CONFIG_FAILED;
8522 }
8523 prefix_s = prefix_buf;
8524 } else
8525 prefix_s = prefix_str;
8526
8527 if (origin_s) {
8528 if (strcmp(origin_s, "egp") == 0)
8529 origin = BGP_ORIGIN_EGP;
8530 else if (strcmp(origin_s, "igp") == 0)
8531 origin = BGP_ORIGIN_IGP;
8532 else if (strcmp(origin_s, "incomplete") == 0)
8533 origin = BGP_ORIGIN_INCOMPLETE;
8534 }
8535
8536 if (as_set_s)
8537 as_set = AGGREGATE_AS_SET;
8538
8539 /* Handle configuration removal, otherwise installation. */
8540 if (no)
8541 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8542
8543 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8544 summary_only != NULL, as_set, origin,
8545 match_med != NULL, suppress_map);
8546 }
8547
8548 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8549 "[no] aggregate-address X:X::X:X/M$prefix [{"
8550 "as-set$as_set_s"
8551 "|summary-only$summary_only"
8552 "|route-map RMAP_NAME$rmap_name"
8553 "|origin <egp|igp|incomplete>$origin_s"
8554 "|matching-MED-only$match_med"
8555 "|suppress-map RMAP_NAME$suppress_map"
8556 "}]",
8557 NO_STR
8558 "Configure BGP aggregate entries\n"
8559 "Aggregate prefix\n"
8560 "Generate AS set path information\n"
8561 "Filter more specific routes from updates\n"
8562 "Apply route map to aggregate network\n"
8563 "Route map name\n"
8564 "BGP origin code\n"
8565 "Remote EGP\n"
8566 "Local IGP\n"
8567 "Unknown heritage\n"
8568 "Only aggregate routes with matching MED\n"
8569 "Suppress the selected more specific routes\n"
8570 "Route map with the route selectors\n")
8571 {
8572 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8573 int as_set = AGGREGATE_AS_UNSET;
8574
8575 if (origin_s) {
8576 if (strcmp(origin_s, "egp") == 0)
8577 origin = BGP_ORIGIN_EGP;
8578 else if (strcmp(origin_s, "igp") == 0)
8579 origin = BGP_ORIGIN_IGP;
8580 else if (strcmp(origin_s, "incomplete") == 0)
8581 origin = BGP_ORIGIN_INCOMPLETE;
8582 }
8583
8584 if (as_set_s)
8585 as_set = AGGREGATE_AS_SET;
8586
8587 /* Handle configuration removal, otherwise installation. */
8588 if (no)
8589 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8590 SAFI_UNICAST);
8591
8592 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8593 rmap_name, summary_only != NULL, as_set,
8594 origin, match_med != NULL, suppress_map);
8595 }
8596
8597 /* Redistribute route treatment. */
8598 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8599 const union g_addr *nexthop, ifindex_t ifindex,
8600 enum nexthop_types_t nhtype, uint8_t distance,
8601 enum blackhole_type bhtype, uint32_t metric,
8602 uint8_t type, unsigned short instance,
8603 route_tag_t tag)
8604 {
8605 struct bgp_path_info *new;
8606 struct bgp_path_info *bpi;
8607 struct bgp_path_info rmap_path;
8608 struct bgp_dest *bn;
8609 struct attr attr;
8610 struct attr *new_attr;
8611 afi_t afi;
8612 route_map_result_t ret;
8613 struct bgp_redist *red;
8614
8615 /* Make default attribute. */
8616 bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
8617 /*
8618 * This must not be NULL to satisfy Coverity SA
8619 */
8620 assert(attr.aspath);
8621
8622 switch (nhtype) {
8623 case NEXTHOP_TYPE_IFINDEX:
8624 switch (p->family) {
8625 case AF_INET:
8626 attr.nexthop.s_addr = INADDR_ANY;
8627 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8628 break;
8629 case AF_INET6:
8630 memset(&attr.mp_nexthop_global, 0,
8631 sizeof(attr.mp_nexthop_global));
8632 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8633 break;
8634 }
8635 break;
8636 case NEXTHOP_TYPE_IPV4:
8637 case NEXTHOP_TYPE_IPV4_IFINDEX:
8638 attr.nexthop = nexthop->ipv4;
8639 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8640 break;
8641 case NEXTHOP_TYPE_IPV6:
8642 case NEXTHOP_TYPE_IPV6_IFINDEX:
8643 attr.mp_nexthop_global = nexthop->ipv6;
8644 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8645 break;
8646 case NEXTHOP_TYPE_BLACKHOLE:
8647 switch (p->family) {
8648 case AF_INET:
8649 attr.nexthop.s_addr = INADDR_ANY;
8650 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
8651 break;
8652 case AF_INET6:
8653 memset(&attr.mp_nexthop_global, 0,
8654 sizeof(attr.mp_nexthop_global));
8655 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8656 break;
8657 }
8658 attr.bh_type = bhtype;
8659 break;
8660 }
8661 attr.nh_type = nhtype;
8662 attr.nh_ifindex = ifindex;
8663
8664 attr.med = metric;
8665 attr.distance = distance;
8666 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8667 attr.tag = tag;
8668
8669 if (metric)
8670 bgp_attr_set_aigp_metric(&attr, metric);
8671
8672 afi = family2afi(p->family);
8673
8674 red = bgp_redist_lookup(bgp, afi, type, instance);
8675 if (red) {
8676 struct attr attr_new;
8677
8678 /* Copy attribute for modification. */
8679 attr_new = attr;
8680
8681 if (red->redist_metric_flag) {
8682 attr_new.med = red->redist_metric;
8683 bgp_attr_set_aigp_metric(&attr_new, red->redist_metric);
8684 }
8685
8686 /* Apply route-map. */
8687 if (red->rmap.name) {
8688 memset(&rmap_path, 0, sizeof(rmap_path));
8689 rmap_path.peer = bgp->peer_self;
8690 rmap_path.attr = &attr_new;
8691
8692 SET_FLAG(bgp->peer_self->rmap_type,
8693 PEER_RMAP_TYPE_REDISTRIBUTE);
8694
8695 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8696
8697 bgp->peer_self->rmap_type = 0;
8698
8699 if (ret == RMAP_DENYMATCH) {
8700 /* Free uninterned attribute. */
8701 bgp_attr_flush(&attr_new);
8702
8703 /* Unintern original. */
8704 aspath_unintern(&attr.aspath);
8705 bgp_redistribute_delete(bgp, p, type, instance);
8706 return;
8707 }
8708 }
8709
8710 if (bgp_in_graceful_shutdown(bgp))
8711 bgp_attr_add_gshut_community(&attr_new);
8712
8713 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8714 SAFI_UNICAST, p, NULL);
8715
8716 new_attr = bgp_attr_intern(&attr_new);
8717
8718 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8719 if (bpi->peer == bgp->peer_self
8720 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8721 break;
8722
8723 if (bpi) {
8724 /* Ensure the (source route) type is updated. */
8725 bpi->type = type;
8726 if (attrhash_cmp(bpi->attr, new_attr)
8727 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8728 bgp_attr_unintern(&new_attr);
8729 aspath_unintern(&attr.aspath);
8730 bgp_dest_unlock_node(bn);
8731 return;
8732 } else {
8733 /* The attribute is changed. */
8734 bgp_path_info_set_flag(bn, bpi,
8735 BGP_PATH_ATTR_CHANGED);
8736
8737 /* Rewrite BGP route information. */
8738 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8739 bgp_path_info_restore(bn, bpi);
8740 else
8741 bgp_aggregate_decrement(
8742 bgp, p, bpi, afi, SAFI_UNICAST);
8743 bgp_attr_unintern(&bpi->attr);
8744 bpi->attr = new_attr;
8745 bpi->uptime = monotime(NULL);
8746
8747 /* Process change. */
8748 bgp_aggregate_increment(bgp, p, bpi, afi,
8749 SAFI_UNICAST);
8750 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8751 bgp_dest_unlock_node(bn);
8752 aspath_unintern(&attr.aspath);
8753
8754 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8755 || (bgp->inst_type
8756 == BGP_INSTANCE_TYPE_DEFAULT)) {
8757
8758 vpn_leak_from_vrf_update(
8759 bgp_get_default(), bgp, bpi);
8760 }
8761 return;
8762 }
8763 }
8764
8765 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8766 bgp->peer_self, new_attr, bn);
8767 SET_FLAG(new->flags, BGP_PATH_VALID);
8768
8769 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8770 bgp_path_info_add(bn, new);
8771 bgp_dest_unlock_node(bn);
8772 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8773 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8774
8775 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8776 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8777
8778 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8779 }
8780 }
8781
8782 /* Unintern original. */
8783 aspath_unintern(&attr.aspath);
8784 }
8785
8786 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8787 unsigned short instance)
8788 {
8789 afi_t afi;
8790 struct bgp_dest *dest;
8791 struct bgp_path_info *pi;
8792 struct bgp_redist *red;
8793
8794 afi = family2afi(p->family);
8795
8796 red = bgp_redist_lookup(bgp, afi, type, instance);
8797 if (red) {
8798 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8799 SAFI_UNICAST, p, NULL);
8800
8801 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8802 if (pi->peer == bgp->peer_self && pi->type == type)
8803 break;
8804
8805 if (pi) {
8806 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8807 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8808
8809 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8810 bgp, pi);
8811 }
8812 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8813 bgp_path_info_delete(dest, pi);
8814 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8815 }
8816 bgp_dest_unlock_node(dest);
8817 }
8818 }
8819
8820 /* Withdraw specified route type's route. */
8821 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8822 unsigned short instance)
8823 {
8824 struct bgp_dest *dest;
8825 struct bgp_path_info *pi;
8826 struct bgp_table *table;
8827
8828 table = bgp->rib[afi][SAFI_UNICAST];
8829
8830 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8831 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8832 if (pi->peer == bgp->peer_self && pi->type == type
8833 && pi->instance == instance)
8834 break;
8835
8836 if (pi) {
8837 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8838 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8839
8840 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8841 bgp, pi);
8842 }
8843 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8844 pi, afi, SAFI_UNICAST);
8845 bgp_path_info_delete(dest, pi);
8846 if (!CHECK_FLAG(bgp->flags,
8847 BGP_FLAG_DELETE_IN_PROGRESS))
8848 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8849 else
8850 bgp_path_info_reap(dest, pi);
8851 }
8852 }
8853 }
8854
8855 /* Static function to display route. */
8856 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8857 struct vty *vty, json_object *json, bool wide)
8858 {
8859 int len = 0;
8860 char buf[INET6_ADDRSTRLEN];
8861
8862 if (p->family == AF_INET) {
8863 if (!json) {
8864 len = vty_out(vty, "%pFX", p);
8865 } else {
8866 json_object_string_add(json, "prefix",
8867 inet_ntop(p->family,
8868 &p->u.prefix, buf,
8869 sizeof(buf)));
8870 json_object_int_add(json, "prefixLen", p->prefixlen);
8871 json_object_string_addf(json, "network", "%pFX", p);
8872 json_object_int_add(json, "version", dest->version);
8873 }
8874 } else if (p->family == AF_ETHERNET) {
8875 len = vty_out(vty, "%pFX", p);
8876 } else if (p->family == AF_EVPN) {
8877 if (!json)
8878 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8879 else
8880 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8881 } else if (p->family == AF_FLOWSPEC) {
8882 route_vty_out_flowspec(vty, p, NULL,
8883 json ?
8884 NLRI_STRING_FORMAT_JSON_SIMPLE :
8885 NLRI_STRING_FORMAT_MIN, json);
8886 } else {
8887 if (!json)
8888 len = vty_out(vty, "%pFX", p);
8889 else {
8890 json_object_string_add(json, "prefix",
8891 inet_ntop(p->family,
8892 &p->u.prefix, buf,
8893 sizeof(buf)));
8894 json_object_int_add(json, "prefixLen", p->prefixlen);
8895 json_object_string_addf(json, "network", "%pFX", p);
8896 json_object_int_add(json, "version", dest->version);
8897 }
8898 }
8899
8900 if (!json) {
8901 len = wide ? (45 - len) : (17 - len);
8902 if (len < 1)
8903 vty_out(vty, "\n%*s", 20, " ");
8904 else
8905 vty_out(vty, "%*s", len, " ");
8906 }
8907 }
8908
8909 enum bgp_display_type {
8910 normal_list,
8911 };
8912
8913 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8914 {
8915 switch (reason) {
8916 case bgp_path_selection_none:
8917 return "Nothing to Select";
8918 case bgp_path_selection_first:
8919 return "First path received";
8920 case bgp_path_selection_evpn_sticky_mac:
8921 return "EVPN Sticky Mac";
8922 case bgp_path_selection_evpn_seq:
8923 return "EVPN sequence number";
8924 case bgp_path_selection_evpn_lower_ip:
8925 return "EVPN lower IP";
8926 case bgp_path_selection_evpn_local_path:
8927 return "EVPN local ES path";
8928 case bgp_path_selection_evpn_non_proxy:
8929 return "EVPN non proxy";
8930 case bgp_path_selection_weight:
8931 return "Weight";
8932 case bgp_path_selection_local_pref:
8933 return "Local Pref";
8934 case bgp_path_selection_accept_own:
8935 return "Accept Own";
8936 case bgp_path_selection_local_route:
8937 return "Local Route";
8938 case bgp_path_selection_aigp:
8939 return "AIGP";
8940 case bgp_path_selection_confed_as_path:
8941 return "Confederation based AS Path";
8942 case bgp_path_selection_as_path:
8943 return "AS Path";
8944 case bgp_path_selection_origin:
8945 return "Origin";
8946 case bgp_path_selection_med:
8947 return "MED";
8948 case bgp_path_selection_peer:
8949 return "Peer Type";
8950 case bgp_path_selection_confed:
8951 return "Confed Peer Type";
8952 case bgp_path_selection_igp_metric:
8953 return "IGP Metric";
8954 case bgp_path_selection_older:
8955 return "Older Path";
8956 case bgp_path_selection_router_id:
8957 return "Router ID";
8958 case bgp_path_selection_cluster_length:
8959 return "Cluster length";
8960 case bgp_path_selection_stale:
8961 return "Path Staleness";
8962 case bgp_path_selection_local_configured:
8963 return "Locally configured route";
8964 case bgp_path_selection_neighbor_ip:
8965 return "Neighbor IP";
8966 case bgp_path_selection_default:
8967 return "Nothing left to compare";
8968 }
8969 return "Invalid (internal error)";
8970 }
8971
8972 /* Print the short form route status for a bgp_path_info */
8973 static void route_vty_short_status_out(struct vty *vty,
8974 struct bgp_path_info *path,
8975 const struct prefix *p,
8976 json_object *json_path)
8977 {
8978 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8979
8980 if (json_path) {
8981
8982 /* Route status display. */
8983 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8984 json_object_boolean_true_add(json_path, "removed");
8985
8986 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8987 json_object_boolean_true_add(json_path, "stale");
8988
8989 if (path->extra && bgp_path_suppressed(path))
8990 json_object_boolean_true_add(json_path, "suppressed");
8991
8992 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8993 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8994 json_object_boolean_true_add(json_path, "valid");
8995
8996 /* Selected */
8997 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8998 json_object_boolean_true_add(json_path, "history");
8999
9000 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9001 json_object_boolean_true_add(json_path, "damped");
9002
9003 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
9004 json_object_boolean_true_add(json_path, "bestpath");
9005 json_object_string_add(json_path, "selectionReason",
9006 bgp_path_selection_reason2str(
9007 path->net->reason));
9008 }
9009
9010 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9011 json_object_boolean_true_add(json_path, "multipath");
9012
9013 /* Internal route. */
9014 if ((path->peer->as)
9015 && (path->peer->as == path->peer->local_as))
9016 json_object_string_add(json_path, "pathFrom",
9017 "internal");
9018 else
9019 json_object_string_add(json_path, "pathFrom",
9020 "external");
9021
9022 return;
9023 }
9024
9025 /* RPKI validation state */
9026 rpki_state =
9027 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
9028
9029 if (rpki_state == RPKI_VALID)
9030 vty_out(vty, "V");
9031 else if (rpki_state == RPKI_INVALID)
9032 vty_out(vty, "I");
9033 else if (rpki_state == RPKI_NOTFOUND)
9034 vty_out(vty, "N");
9035 else
9036 vty_out(vty, " ");
9037
9038 /* Route status display. */
9039 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
9040 vty_out(vty, "R");
9041 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
9042 vty_out(vty, "S");
9043 else if (bgp_path_suppressed(path))
9044 vty_out(vty, "s");
9045 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
9046 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9047 vty_out(vty, "*");
9048 else
9049 vty_out(vty, " ");
9050
9051 /* Selected */
9052 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9053 vty_out(vty, "h");
9054 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
9055 vty_out(vty, "d");
9056 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
9057 vty_out(vty, ">");
9058 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
9059 vty_out(vty, "=");
9060 else
9061 vty_out(vty, " ");
9062
9063 /* Internal route. */
9064 if (path->peer && (path->peer->as)
9065 && (path->peer->as == path->peer->local_as))
9066 vty_out(vty, "i");
9067 else
9068 vty_out(vty, " ");
9069 }
9070
9071 static char *bgp_nexthop_hostname(struct peer *peer,
9072 struct bgp_nexthop_cache *bnc)
9073 {
9074 if (peer->hostname
9075 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
9076 return peer->hostname;
9077 return NULL;
9078 }
9079
9080 /* called from terminal list command */
9081 void route_vty_out(struct vty *vty, const struct prefix *p,
9082 struct bgp_path_info *path, int display, safi_t safi,
9083 json_object *json_paths, bool wide)
9084 {
9085 int len;
9086 struct attr *attr = path->attr;
9087 json_object *json_path = NULL;
9088 json_object *json_nexthops = NULL;
9089 json_object *json_nexthop_global = NULL;
9090 json_object *json_nexthop_ll = NULL;
9091 json_object *json_ext_community = NULL;
9092 char vrf_id_str[VRF_NAMSIZ] = {0};
9093 bool nexthop_self =
9094 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9095 bool nexthop_othervrf = false;
9096 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
9097 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
9098 char *nexthop_hostname =
9099 bgp_nexthop_hostname(path->peer, path->nexthop);
9100 char esi_buf[ESI_STR_LEN];
9101
9102 if (json_paths)
9103 json_path = json_object_new_object();
9104
9105 /* short status lead text */
9106 route_vty_short_status_out(vty, path, p, json_path);
9107
9108 if (!json_paths) {
9109 /* print prefix and mask */
9110 if (!display)
9111 route_vty_out_route(path->net, p, vty, json_path, wide);
9112 else
9113 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
9114 } else {
9115 route_vty_out_route(path->net, p, vty, json_path, wide);
9116 }
9117
9118 /*
9119 * If vrf id of nexthop is different from that of prefix,
9120 * set up printable string to append
9121 */
9122 if (path->extra && path->extra->bgp_orig) {
9123 const char *self = "";
9124
9125 if (nexthop_self)
9126 self = "<";
9127
9128 nexthop_othervrf = true;
9129 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
9130
9131 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
9132 snprintf(vrf_id_str, sizeof(vrf_id_str),
9133 "@%s%s", VRFID_NONE_STR, self);
9134 else
9135 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
9136 path->extra->bgp_orig->vrf_id, self);
9137
9138 if (path->extra->bgp_orig->inst_type
9139 != BGP_INSTANCE_TYPE_DEFAULT)
9140
9141 nexthop_vrfname = path->extra->bgp_orig->name;
9142 } else {
9143 const char *self = "";
9144
9145 if (nexthop_self)
9146 self = "<";
9147
9148 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
9149 }
9150
9151 /*
9152 * For ENCAP and EVPN routes, nexthop address family is not
9153 * neccessarily the same as the prefix address family.
9154 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
9155 * EVPN routes are also exchanged with a MP nexthop. Currently,
9156 * this
9157 * is only IPv4, the value will be present in either
9158 * attr->nexthop or
9159 * attr->mp_nexthop_global_in
9160 */
9161 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
9162 char nexthop[128];
9163 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9164
9165 switch (af) {
9166 case AF_INET:
9167 snprintfrr(nexthop, sizeof(nexthop), "%pI4",
9168 &attr->mp_nexthop_global_in);
9169 break;
9170 case AF_INET6:
9171 snprintfrr(nexthop, sizeof(nexthop), "%pI6",
9172 &attr->mp_nexthop_global);
9173 break;
9174 default:
9175 snprintf(nexthop, sizeof(nexthop), "?");
9176 break;
9177 }
9178
9179 if (json_paths) {
9180 json_nexthop_global = json_object_new_object();
9181
9182 json_object_string_add(json_nexthop_global, "ip",
9183 nexthop);
9184
9185 if (path->peer->hostname)
9186 json_object_string_add(json_nexthop_global,
9187 "hostname",
9188 path->peer->hostname);
9189
9190 json_object_string_add(json_nexthop_global, "afi",
9191 (af == AF_INET) ? "ipv4"
9192 : "ipv6");
9193 json_object_boolean_true_add(json_nexthop_global,
9194 "used");
9195 } else {
9196 if (nexthop_hostname)
9197 len = vty_out(vty, "%s(%s)%s", nexthop,
9198 nexthop_hostname, vrf_id_str);
9199 else
9200 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
9201
9202 len = wide ? (41 - len) : (16 - len);
9203 if (len < 1)
9204 vty_out(vty, "\n%*s", 36, " ");
9205 else
9206 vty_out(vty, "%*s", len, " ");
9207 }
9208 } else if (safi == SAFI_EVPN) {
9209 if (json_paths) {
9210 json_nexthop_global = json_object_new_object();
9211
9212 json_object_string_addf(json_nexthop_global, "ip",
9213 "%pI4",
9214 &attr->mp_nexthop_global_in);
9215
9216 if (path->peer->hostname)
9217 json_object_string_add(json_nexthop_global,
9218 "hostname",
9219 path->peer->hostname);
9220
9221 json_object_string_add(json_nexthop_global, "afi",
9222 "ipv4");
9223 json_object_boolean_true_add(json_nexthop_global,
9224 "used");
9225 } else {
9226 if (nexthop_hostname)
9227 len = vty_out(vty, "%pI4(%s)%s",
9228 &attr->mp_nexthop_global_in,
9229 nexthop_hostname, vrf_id_str);
9230 else
9231 len = vty_out(vty, "%pI4%s",
9232 &attr->mp_nexthop_global_in,
9233 vrf_id_str);
9234
9235 len = wide ? (41 - len) : (16 - len);
9236 if (len < 1)
9237 vty_out(vty, "\n%*s", 36, " ");
9238 else
9239 vty_out(vty, "%*s", len, " ");
9240 }
9241 } else if (safi == SAFI_FLOWSPEC) {
9242 if (attr->nexthop.s_addr != INADDR_ANY) {
9243 if (json_paths) {
9244 json_nexthop_global = json_object_new_object();
9245
9246 json_object_string_add(json_nexthop_global,
9247 "afi", "ipv4");
9248 json_object_string_addf(json_nexthop_global,
9249 "ip", "%pI4",
9250 &attr->nexthop);
9251
9252 if (path->peer->hostname)
9253 json_object_string_add(
9254 json_nexthop_global, "hostname",
9255 path->peer->hostname);
9256
9257 json_object_boolean_true_add(
9258 json_nexthop_global,
9259 "used");
9260 } else {
9261 if (nexthop_hostname)
9262 len = vty_out(vty, "%pI4(%s)%s",
9263 &attr->nexthop,
9264 nexthop_hostname,
9265 vrf_id_str);
9266 else
9267 len = vty_out(vty, "%pI4%s",
9268 &attr->nexthop,
9269 vrf_id_str);
9270
9271 len = wide ? (41 - len) : (16 - len);
9272 if (len < 1)
9273 vty_out(vty, "\n%*s", 36, " ");
9274 else
9275 vty_out(vty, "%*s", len, " ");
9276 }
9277 }
9278 } else if (p->family == AF_INET && !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9279 if (json_paths) {
9280 json_nexthop_global = json_object_new_object();
9281
9282 json_object_string_addf(json_nexthop_global, "ip",
9283 "%pI4", &attr->nexthop);
9284
9285 if (path->peer->hostname)
9286 json_object_string_add(json_nexthop_global,
9287 "hostname",
9288 path->peer->hostname);
9289
9290 json_object_string_add(json_nexthop_global, "afi",
9291 "ipv4");
9292 json_object_boolean_true_add(json_nexthop_global,
9293 "used");
9294 } else {
9295 if (nexthop_hostname)
9296 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
9297 nexthop_hostname, vrf_id_str);
9298 else
9299 len = vty_out(vty, "%pI4%s", &attr->nexthop,
9300 vrf_id_str);
9301
9302 len = wide ? (41 - len) : (16 - len);
9303 if (len < 1)
9304 vty_out(vty, "\n%*s", 36, " ");
9305 else
9306 vty_out(vty, "%*s", len, " ");
9307 }
9308 }
9309
9310 /* IPv6 Next Hop */
9311 else if (p->family == AF_INET6 || BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9312 if (json_paths) {
9313 json_nexthop_global = json_object_new_object();
9314 json_object_string_addf(json_nexthop_global, "ip",
9315 "%pI6",
9316 &attr->mp_nexthop_global);
9317
9318 if (path->peer->hostname)
9319 json_object_string_add(json_nexthop_global,
9320 "hostname",
9321 path->peer->hostname);
9322
9323 json_object_string_add(json_nexthop_global, "afi",
9324 "ipv6");
9325 json_object_string_add(json_nexthop_global, "scope",
9326 "global");
9327
9328 /* We display both LL & GL if both have been
9329 * received */
9330 if ((attr->mp_nexthop_len
9331 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9332 || (path->peer->conf_if)) {
9333 json_nexthop_ll = json_object_new_object();
9334 json_object_string_addf(
9335 json_nexthop_ll, "ip", "%pI6",
9336 &attr->mp_nexthop_local);
9337
9338 if (path->peer->hostname)
9339 json_object_string_add(
9340 json_nexthop_ll, "hostname",
9341 path->peer->hostname);
9342
9343 json_object_string_add(json_nexthop_ll, "afi",
9344 "ipv6");
9345 json_object_string_add(json_nexthop_ll, "scope",
9346 "link-local");
9347
9348 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9349 &attr->mp_nexthop_local)
9350 != 0)
9351 && !attr->mp_nexthop_prefer_global)
9352 json_object_boolean_true_add(
9353 json_nexthop_ll, "used");
9354 else
9355 json_object_boolean_true_add(
9356 json_nexthop_global, "used");
9357 } else
9358 json_object_boolean_true_add(
9359 json_nexthop_global, "used");
9360 } else {
9361 /* Display LL if LL/Global both in table unless
9362 * prefer-global is set */
9363 if (((attr->mp_nexthop_len
9364 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9365 && !attr->mp_nexthop_prefer_global)
9366 || (path->peer->conf_if)) {
9367 if (path->peer->conf_if) {
9368 len = vty_out(vty, "%s",
9369 path->peer->conf_if);
9370 /* len of IPv6 addr + max len of def
9371 * ifname */
9372 len = wide ? (41 - len) : (16 - len);
9373
9374 if (len < 1)
9375 vty_out(vty, "\n%*s", 36, " ");
9376 else
9377 vty_out(vty, "%*s", len, " ");
9378 } else {
9379 if (nexthop_hostname)
9380 len = vty_out(
9381 vty, "%pI6(%s)%s",
9382 &attr->mp_nexthop_local,
9383 nexthop_hostname,
9384 vrf_id_str);
9385 else
9386 len = vty_out(
9387 vty, "%pI6%s",
9388 &attr->mp_nexthop_local,
9389 vrf_id_str);
9390
9391 len = wide ? (41 - len) : (16 - len);
9392
9393 if (len < 1)
9394 vty_out(vty, "\n%*s", 36, " ");
9395 else
9396 vty_out(vty, "%*s", len, " ");
9397 }
9398 } else {
9399 if (nexthop_hostname)
9400 len = vty_out(vty, "%pI6(%s)%s",
9401 &attr->mp_nexthop_global,
9402 nexthop_hostname,
9403 vrf_id_str);
9404 else
9405 len = vty_out(vty, "%pI6%s",
9406 &attr->mp_nexthop_global,
9407 vrf_id_str);
9408
9409 len = wide ? (41 - len) : (16 - len);
9410
9411 if (len < 1)
9412 vty_out(vty, "\n%*s", 36, " ");
9413 else
9414 vty_out(vty, "%*s", len, " ");
9415 }
9416 }
9417 }
9418
9419 /* MED/Metric */
9420 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9421 if (json_paths)
9422 json_object_int_add(json_path, "metric", attr->med);
9423 else if (wide)
9424 vty_out(vty, "%7u", attr->med);
9425 else
9426 vty_out(vty, "%10u", attr->med);
9427 else if (!json_paths) {
9428 if (wide)
9429 vty_out(vty, "%*s", 7, " ");
9430 else
9431 vty_out(vty, "%*s", 10, " ");
9432 }
9433
9434 /* Local Pref */
9435 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9436 if (json_paths)
9437 json_object_int_add(json_path, "locPrf",
9438 attr->local_pref);
9439 else
9440 vty_out(vty, "%7u", attr->local_pref);
9441 else if (!json_paths)
9442 vty_out(vty, " ");
9443
9444 if (json_paths)
9445 json_object_int_add(json_path, "weight", attr->weight);
9446 else
9447 vty_out(vty, "%7u ", attr->weight);
9448
9449 if (json_paths)
9450 json_object_string_addf(json_path, "peerId", "%pSU",
9451 &path->peer->su);
9452
9453 /* Print aspath */
9454 if (attr->aspath) {
9455 if (json_paths)
9456 json_object_string_add(json_path, "path",
9457 attr->aspath->str);
9458 else
9459 aspath_print_vty(vty, attr->aspath);
9460 }
9461
9462 /* Print origin */
9463 if (json_paths)
9464 json_object_string_add(json_path, "origin",
9465 bgp_origin_long_str[attr->origin]);
9466 else
9467 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9468
9469 if (json_paths) {
9470 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9471 json_object_string_add(json_path, "esi",
9472 esi_to_str(&attr->esi,
9473 esi_buf, sizeof(esi_buf)));
9474 }
9475 if (safi == SAFI_EVPN &&
9476 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9477 json_ext_community = json_object_new_object();
9478 json_object_string_add(
9479 json_ext_community, "string",
9480 bgp_attr_get_ecommunity(attr)->str);
9481 json_object_object_add(json_path,
9482 "extendedCommunity",
9483 json_ext_community);
9484 }
9485
9486 if (nexthop_self)
9487 json_object_boolean_true_add(json_path,
9488 "announceNexthopSelf");
9489 if (nexthop_othervrf) {
9490 json_object_string_add(json_path, "nhVrfName",
9491 nexthop_vrfname);
9492
9493 json_object_int_add(json_path, "nhVrfId",
9494 ((nexthop_vrfid == VRF_UNKNOWN)
9495 ? -1
9496 : (int)nexthop_vrfid));
9497 }
9498 }
9499
9500 if (json_paths) {
9501 if (json_nexthop_global || json_nexthop_ll) {
9502 json_nexthops = json_object_new_array();
9503
9504 if (json_nexthop_global)
9505 json_object_array_add(json_nexthops,
9506 json_nexthop_global);
9507
9508 if (json_nexthop_ll)
9509 json_object_array_add(json_nexthops,
9510 json_nexthop_ll);
9511
9512 json_object_object_add(json_path, "nexthops",
9513 json_nexthops);
9514 }
9515
9516 json_object_array_add(json_paths, json_path);
9517 } else {
9518 vty_out(vty, "\n");
9519
9520 if (safi == SAFI_EVPN) {
9521 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9522 /* XXX - add these params to the json out */
9523 vty_out(vty, "%*s", 20, " ");
9524 vty_out(vty, "ESI:%s",
9525 esi_to_str(&attr->esi, esi_buf,
9526 sizeof(esi_buf)));
9527
9528 vty_out(vty, "\n");
9529 }
9530 if (attr->flag &
9531 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9532 vty_out(vty, "%*s", 20, " ");
9533 vty_out(vty, "%s\n",
9534 bgp_attr_get_ecommunity(attr)->str);
9535 }
9536 }
9537
9538 #ifdef ENABLE_BGP_VNC
9539 /* prints an additional line, indented, with VNC info, if
9540 * present */
9541 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9542 rfapi_vty_out_vncinfo(vty, p, path, safi);
9543 #endif
9544 }
9545 }
9546
9547 /* called from terminal list command */
9548 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9549 const struct prefix *p, struct attr *attr, safi_t safi,
9550 bool use_json, json_object *json_ar, bool wide)
9551 {
9552 json_object *json_status = NULL;
9553 json_object *json_net = NULL;
9554 int len;
9555 char buff[BUFSIZ];
9556
9557 /* Route status display. */
9558 if (use_json) {
9559 json_status = json_object_new_object();
9560 json_net = json_object_new_object();
9561 } else {
9562 vty_out(vty, " *");
9563 vty_out(vty, ">");
9564 vty_out(vty, " ");
9565 }
9566
9567 /* print prefix and mask */
9568 if (use_json) {
9569 if (safi == SAFI_EVPN)
9570 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9571 else if (p->family == AF_INET || p->family == AF_INET6) {
9572 json_object_string_add(
9573 json_net, "addrPrefix",
9574 inet_ntop(p->family, &p->u.prefix, buff,
9575 BUFSIZ));
9576 json_object_int_add(json_net, "prefixLen",
9577 p->prefixlen);
9578 json_object_string_addf(json_net, "network", "%pFX", p);
9579 }
9580 } else
9581 route_vty_out_route(dest, p, vty, NULL, wide);
9582
9583 /* Print attribute */
9584 if (attr) {
9585 if (use_json) {
9586 if (p->family == AF_INET &&
9587 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9588 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9589 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9590 json_object_string_addf(
9591 json_net, "nextHop", "%pI4",
9592 &attr->mp_nexthop_global_in);
9593 else
9594 json_object_string_addf(
9595 json_net, "nextHop", "%pI4",
9596 &attr->nexthop);
9597 } else if (p->family == AF_INET6 ||
9598 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9599 json_object_string_addf(
9600 json_net, "nextHopGlobal", "%pI6",
9601 &attr->mp_nexthop_global);
9602 } else if (p->family == AF_EVPN &&
9603 !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9604 json_object_string_addf(
9605 json_net, "nextHop", "%pI4",
9606 &attr->mp_nexthop_global_in);
9607 }
9608
9609 if (attr->flag
9610 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9611 json_object_int_add(json_net, "metric",
9612 attr->med);
9613
9614 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9615 json_object_int_add(json_net, "locPrf",
9616 attr->local_pref);
9617
9618 json_object_int_add(json_net, "weight", attr->weight);
9619
9620 /* Print aspath */
9621 if (attr->aspath)
9622 json_object_string_add(json_net, "path",
9623 attr->aspath->str);
9624
9625 /* Print origin */
9626 #if CONFDATE > 20231208
9627 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
9628 #endif
9629 json_object_string_add(json_net, "bgpOriginCode",
9630 bgp_origin_str[attr->origin]);
9631 json_object_string_add(
9632 json_net, "origin",
9633 bgp_origin_long_str[attr->origin]);
9634 } else {
9635 if (p->family == AF_INET &&
9636 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP ||
9637 safi == SAFI_EVPN ||
9638 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9639 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9640 || safi == SAFI_EVPN)
9641 vty_out(vty, "%-16pI4",
9642 &attr->mp_nexthop_global_in);
9643 else if (wide)
9644 vty_out(vty, "%-41pI4", &attr->nexthop);
9645 else
9646 vty_out(vty, "%-16pI4", &attr->nexthop);
9647 } else if (p->family == AF_INET6 ||
9648 BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) {
9649 len = vty_out(vty, "%pI6",
9650 &attr->mp_nexthop_global);
9651 len = wide ? (41 - len) : (16 - len);
9652 if (len < 1)
9653 vty_out(vty, "\n%*s", 36, " ");
9654 else
9655 vty_out(vty, "%*s", len, " ");
9656 }
9657 if (attr->flag
9658 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9659 if (wide)
9660 vty_out(vty, "%7u", attr->med);
9661 else
9662 vty_out(vty, "%10u", attr->med);
9663 else if (wide)
9664 vty_out(vty, " ");
9665 else
9666 vty_out(vty, " ");
9667
9668 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9669 vty_out(vty, "%7u", attr->local_pref);
9670 else
9671 vty_out(vty, " ");
9672
9673 vty_out(vty, "%7u ", attr->weight);
9674
9675 /* Print aspath */
9676 if (attr->aspath)
9677 aspath_print_vty(vty, attr->aspath);
9678
9679 /* Print origin */
9680 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9681 }
9682 }
9683 if (use_json) {
9684 struct bgp_path_info *bpi = bgp_dest_get_bgp_path_info(dest);
9685
9686 #if CONFDATE > 20231208
9687 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
9688 #endif
9689 json_object_boolean_true_add(json_status, "*");
9690 json_object_boolean_true_add(json_status, ">");
9691 json_object_boolean_true_add(json_net, "valid");
9692 json_object_boolean_true_add(json_net, "best");
9693
9694 if (bpi && CHECK_FLAG(bpi->flags, BGP_PATH_MULTIPATH)) {
9695 json_object_boolean_true_add(json_status, "=");
9696 json_object_boolean_true_add(json_net, "multipath");
9697 }
9698 json_object_object_add(json_net, "appliedStatusSymbols",
9699 json_status);
9700 json_object_object_addf(json_ar, json_net, "%pFX", p);
9701 } else
9702 vty_out(vty, "\n");
9703 }
9704
9705 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9706 struct bgp_path_info *path, int display, safi_t safi,
9707 json_object *json)
9708 {
9709 json_object *json_out = NULL;
9710 struct attr *attr;
9711 mpls_label_t label = MPLS_INVALID_LABEL;
9712
9713 if (!path->extra)
9714 return;
9715
9716 if (json)
9717 json_out = json_object_new_object();
9718
9719 /* short status lead text */
9720 route_vty_short_status_out(vty, path, p, json_out);
9721
9722 /* print prefix and mask */
9723 if (json == NULL) {
9724 if (!display)
9725 route_vty_out_route(path->net, p, vty, NULL, false);
9726 else
9727 vty_out(vty, "%*s", 17, " ");
9728 }
9729
9730 /* Print attribute */
9731 attr = path->attr;
9732 if (((p->family == AF_INET) &&
9733 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9734 (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) ||
9735 (!BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9736 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9737 || safi == SAFI_EVPN) {
9738 if (json)
9739 json_object_string_addf(
9740 json_out, "mpNexthopGlobalIn", "%pI4",
9741 &attr->mp_nexthop_global_in);
9742 else
9743 vty_out(vty, "%-16pI4",
9744 &attr->mp_nexthop_global_in);
9745 } else {
9746 if (json)
9747 json_object_string_addf(json_out, "nexthop",
9748 "%pI4", &attr->nexthop);
9749 else
9750 vty_out(vty, "%-16pI4", &attr->nexthop);
9751 }
9752 } else if (((p->family == AF_INET6) &&
9753 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP))) ||
9754 (safi == SAFI_EVPN && BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr)) ||
9755 (BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
9756 char buf_a[512];
9757
9758 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9759 if (json)
9760 json_object_string_addf(
9761 json_out, "mpNexthopGlobalIn", "%pI6",
9762 &attr->mp_nexthop_global);
9763 else
9764 vty_out(vty, "%s",
9765 inet_ntop(AF_INET6,
9766 &attr->mp_nexthop_global,
9767 buf_a, sizeof(buf_a)));
9768 } else if (attr->mp_nexthop_len
9769 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9770 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9771 &attr->mp_nexthop_global,
9772 &attr->mp_nexthop_local);
9773 if (json)
9774 json_object_string_add(json_out,
9775 "mpNexthopGlobalLocal",
9776 buf_a);
9777 else
9778 vty_out(vty, "%s", buf_a);
9779 }
9780 }
9781
9782 label = decode_label(&path->extra->label[0]);
9783
9784 if (bgp_is_valid_label(&label)) {
9785 if (json) {
9786 json_object_int_add(json_out, "notag", label);
9787 json_object_array_add(json, json_out);
9788 } else {
9789 vty_out(vty, "notag/%d", label);
9790 vty_out(vty, "\n");
9791 }
9792 } else if (!json)
9793 vty_out(vty, "\n");
9794 }
9795
9796 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9797 struct bgp_path_info *path, int display,
9798 json_object *json_paths)
9799 {
9800 struct attr *attr;
9801 json_object *json_path = NULL;
9802 json_object *json_nexthop = NULL;
9803 json_object *json_overlay = NULL;
9804
9805 if (!path->extra)
9806 return;
9807
9808 if (json_paths) {
9809 json_path = json_object_new_object();
9810 json_overlay = json_object_new_object();
9811 json_nexthop = json_object_new_object();
9812 }
9813
9814 /* short status lead text */
9815 route_vty_short_status_out(vty, path, p, json_path);
9816
9817 /* print prefix and mask */
9818 if (!display)
9819 route_vty_out_route(path->net, p, vty, json_path, false);
9820 else
9821 vty_out(vty, "%*s", 17, " ");
9822
9823 /* Print attribute */
9824 attr = path->attr;
9825 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9826
9827 switch (af) {
9828 case AF_INET:
9829 if (!json_path) {
9830 vty_out(vty, "%-16pI4", &attr->mp_nexthop_global_in);
9831 } else {
9832 json_object_string_addf(json_nexthop, "ip", "%pI4",
9833 &attr->mp_nexthop_global_in);
9834
9835 json_object_string_add(json_nexthop, "afi", "ipv4");
9836
9837 json_object_object_add(json_path, "nexthop",
9838 json_nexthop);
9839 }
9840 break;
9841 case AF_INET6:
9842 if (!json_path) {
9843 vty_out(vty, "%pI6(%pI6)", &attr->mp_nexthop_global,
9844 &attr->mp_nexthop_local);
9845 } else {
9846 json_object_string_addf(json_nexthop, "ipv6Global",
9847 "%pI6",
9848 &attr->mp_nexthop_global);
9849
9850 json_object_string_addf(json_nexthop, "ipv6LinkLocal",
9851 "%pI6",
9852 &attr->mp_nexthop_local);
9853
9854 json_object_string_add(json_nexthop, "afi", "ipv6");
9855
9856 json_object_object_add(json_path, "nexthop",
9857 json_nexthop);
9858 }
9859 break;
9860 default:
9861 if (!json_path) {
9862 vty_out(vty, "?");
9863 } else {
9864 json_object_string_add(json_nexthop, "error",
9865 "Unsupported address-family");
9866 }
9867 }
9868
9869 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9870
9871 if (!json_path)
9872 vty_out(vty, "/%pIA", &eo->gw_ip);
9873 else
9874 json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip);
9875
9876 if (bgp_attr_get_ecommunity(attr)) {
9877 char *mac = NULL;
9878 struct ecommunity_val *routermac = ecommunity_lookup(
9879 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9880 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9881
9882 if (routermac)
9883 mac = ecom_mac2str((char *)routermac->val);
9884 if (mac) {
9885 if (!json_path) {
9886 vty_out(vty, "/%s", mac);
9887 } else {
9888 json_object_string_add(json_overlay, "rmac",
9889 mac);
9890 }
9891 XFREE(MTYPE_TMP, mac);
9892 }
9893 }
9894
9895 if (!json_path) {
9896 vty_out(vty, "\n");
9897 } else {
9898 json_object_object_add(json_path, "overlay", json_overlay);
9899
9900 json_object_array_add(json_paths, json_path);
9901 }
9902 }
9903
9904 /* dampening route */
9905 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9906 struct bgp_path_info *path, int display,
9907 afi_t afi, safi_t safi, bool use_json,
9908 json_object *json_paths)
9909 {
9910 struct attr *attr = path->attr;
9911 int len;
9912 char timebuf[BGP_UPTIME_LEN];
9913 json_object *json_path = NULL;
9914
9915 if (use_json)
9916 json_path = json_object_new_object();
9917
9918 /* short status lead text */
9919 route_vty_short_status_out(vty, path, p, json_path);
9920
9921 /* print prefix and mask */
9922 if (!use_json) {
9923 if (!display)
9924 route_vty_out_route(path->net, p, vty, NULL, false);
9925 else
9926 vty_out(vty, "%*s", 17, " ");
9927
9928 len = vty_out(vty, "%s", path->peer->host);
9929 len = 17 - len;
9930
9931 if (len < 1)
9932 vty_out(vty, "\n%*s", 34, " ");
9933 else
9934 vty_out(vty, "%*s", len, " ");
9935
9936 vty_out(vty, "%s ",
9937 bgp_damp_reuse_time_vty(vty, path, timebuf,
9938 BGP_UPTIME_LEN, afi, safi,
9939 use_json, NULL));
9940
9941 if (attr->aspath)
9942 aspath_print_vty(vty, attr->aspath);
9943
9944 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9945
9946 vty_out(vty, "\n");
9947 } else {
9948 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9949 safi, use_json, json_path);
9950
9951 if (attr->aspath)
9952 json_object_string_add(json_path, "asPath",
9953 attr->aspath->str);
9954
9955 json_object_string_add(json_path, "origin",
9956 bgp_origin_str[attr->origin]);
9957 json_object_string_add(json_path, "peerHost", path->peer->host);
9958
9959 json_object_array_add(json_paths, json_path);
9960 }
9961 }
9962
9963 /* flap route */
9964 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9965 struct bgp_path_info *path, int display,
9966 afi_t afi, safi_t safi, bool use_json,
9967 json_object *json_paths)
9968 {
9969 struct attr *attr = path->attr;
9970 struct bgp_damp_info *bdi;
9971 char timebuf[BGP_UPTIME_LEN];
9972 int len;
9973 json_object *json_path = NULL;
9974
9975 if (!path->extra)
9976 return;
9977
9978 if (use_json)
9979 json_path = json_object_new_object();
9980
9981 bdi = path->extra->damp_info;
9982
9983 /* short status lead text */
9984 route_vty_short_status_out(vty, path, p, json_path);
9985
9986 if (!use_json) {
9987 if (!display)
9988 route_vty_out_route(path->net, p, vty, NULL, false);
9989 else
9990 vty_out(vty, "%*s", 17, " ");
9991
9992 len = vty_out(vty, "%s", path->peer->host);
9993 len = 16 - len;
9994 if (len < 1)
9995 vty_out(vty, "\n%*s", 33, " ");
9996 else
9997 vty_out(vty, "%*s", len, " ");
9998
9999 len = vty_out(vty, "%d", bdi->flap);
10000 len = 5 - len;
10001 if (len < 1)
10002 vty_out(vty, " ");
10003 else
10004 vty_out(vty, "%*s", len, " ");
10005
10006 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
10007 BGP_UPTIME_LEN, 0, NULL));
10008
10009 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10010 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10011 vty_out(vty, "%s ",
10012 bgp_damp_reuse_time_vty(vty, path, timebuf,
10013 BGP_UPTIME_LEN, afi,
10014 safi, use_json, NULL));
10015 else
10016 vty_out(vty, "%*s ", 8, " ");
10017
10018 if (attr->aspath)
10019 aspath_print_vty(vty, attr->aspath);
10020
10021 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
10022
10023 vty_out(vty, "\n");
10024 } else {
10025 json_object_string_add(json_path, "peerHost", path->peer->host);
10026 json_object_int_add(json_path, "bdiFlap", bdi->flap);
10027
10028 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
10029 json_path);
10030
10031 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
10032 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
10033 bgp_damp_reuse_time_vty(vty, path, timebuf,
10034 BGP_UPTIME_LEN, afi, safi,
10035 use_json, json_path);
10036
10037 if (attr->aspath)
10038 json_object_string_add(json_path, "asPath",
10039 attr->aspath->str);
10040
10041 json_object_string_add(json_path, "origin",
10042 bgp_origin_str[attr->origin]);
10043
10044 json_object_array_add(json_paths, json_path);
10045 }
10046 }
10047
10048 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
10049 int *first, const char *header,
10050 json_object *json_adv_to)
10051 {
10052 json_object *json_peer = NULL;
10053
10054 if (json_adv_to) {
10055 /* 'advertised-to' is a dictionary of peers we have advertised
10056 * this
10057 * prefix too. The key is the peer's IP or swpX, the value is
10058 * the
10059 * hostname if we know it and "" if not.
10060 */
10061 json_peer = json_object_new_object();
10062
10063 if (peer->hostname)
10064 json_object_string_add(json_peer, "hostname",
10065 peer->hostname);
10066
10067 if (peer->conf_if)
10068 json_object_object_add(json_adv_to, peer->conf_if,
10069 json_peer);
10070 else
10071 json_object_object_addf(json_adv_to, json_peer, "%pSU",
10072 &peer->su);
10073 } else {
10074 if (*first) {
10075 vty_out(vty, "%s", header);
10076 *first = 0;
10077 }
10078
10079 if (peer->hostname
10080 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
10081 if (peer->conf_if)
10082 vty_out(vty, " %s(%s)", peer->hostname,
10083 peer->conf_if);
10084 else
10085 vty_out(vty, " %s(%pSU)", peer->hostname,
10086 &peer->su);
10087 } else {
10088 if (peer->conf_if)
10089 vty_out(vty, " %s", peer->conf_if);
10090 else
10091 vty_out(vty, " %pSU", &peer->su);
10092 }
10093 }
10094 }
10095
10096 static void route_vty_out_tx_ids(struct vty *vty,
10097 struct bgp_addpath_info_data *d)
10098 {
10099 int i;
10100
10101 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10102 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
10103 d->addpath_tx_id[i],
10104 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
10105 }
10106 }
10107
10108 static void route_vty_out_detail_es_info(struct vty *vty,
10109 struct bgp_path_info *pi,
10110 struct attr *attr,
10111 json_object *json_path)
10112 {
10113 char esi_buf[ESI_STR_LEN];
10114 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
10115 bool peer_router = !!CHECK_FLAG(attr->es_flags,
10116 ATTR_ES_PEER_ROUTER);
10117 bool peer_active = !!CHECK_FLAG(attr->es_flags,
10118 ATTR_ES_PEER_ACTIVE);
10119 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
10120 ATTR_ES_PEER_PROXY);
10121 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
10122 if (json_path) {
10123 json_object *json_es_info = NULL;
10124
10125 json_object_string_add(
10126 json_path, "esi",
10127 esi_buf);
10128 if (es_local || bgp_evpn_attr_is_sync(attr)) {
10129 json_es_info = json_object_new_object();
10130 if (es_local)
10131 json_object_boolean_true_add(
10132 json_es_info, "localEs");
10133 if (peer_active)
10134 json_object_boolean_true_add(
10135 json_es_info, "peerActive");
10136 if (peer_proxy)
10137 json_object_boolean_true_add(
10138 json_es_info, "peerProxy");
10139 if (peer_router)
10140 json_object_boolean_true_add(
10141 json_es_info, "peerRouter");
10142 if (attr->mm_sync_seqnum)
10143 json_object_int_add(
10144 json_es_info, "peerSeq",
10145 attr->mm_sync_seqnum);
10146 json_object_object_add(
10147 json_path, "es_info",
10148 json_es_info);
10149 }
10150 } else {
10151 if (bgp_evpn_attr_is_sync(attr))
10152 vty_out(vty,
10153 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
10154 esi_buf,
10155 es_local ? "local-es":"",
10156 peer_proxy ? "proxy " : "",
10157 peer_active ? "active ":"",
10158 peer_router ? "router ":"",
10159 attr->mm_sync_seqnum);
10160 else
10161 vty_out(vty, " ESI %s %s\n",
10162 esi_buf,
10163 es_local ? "local-es":"");
10164 }
10165 }
10166
10167 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
10168 const struct prefix *p, struct bgp_path_info *path,
10169 afi_t afi, safi_t safi,
10170 enum rpki_states rpki_curr_state,
10171 json_object *json_paths)
10172 {
10173 char buf[INET6_ADDRSTRLEN];
10174 char tag_buf[30];
10175 struct attr *attr = path->attr;
10176 time_t tbuf;
10177 json_object *json_bestpath = NULL;
10178 json_object *json_cluster_list = NULL;
10179 json_object *json_cluster_list_list = NULL;
10180 json_object *json_ext_community = NULL;
10181 json_object *json_last_update = NULL;
10182 json_object *json_pmsi = NULL;
10183 json_object *json_nexthop_global = NULL;
10184 json_object *json_nexthop_ll = NULL;
10185 json_object *json_nexthops = NULL;
10186 json_object *json_path = NULL;
10187 json_object *json_peer = NULL;
10188 json_object *json_string = NULL;
10189 json_object *json_adv_to = NULL;
10190 int first = 0;
10191 struct listnode *node, *nnode;
10192 struct peer *peer;
10193 bool addpath_capable;
10194 int has_adj;
10195 unsigned int first_as;
10196 bool nexthop_self =
10197 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
10198 int i;
10199 char *nexthop_hostname =
10200 bgp_nexthop_hostname(path->peer, path->nexthop);
10201 uint32_t ttl = 0;
10202 uint32_t bos = 0;
10203 uint32_t exp = 0;
10204 mpls_label_t label = MPLS_INVALID_LABEL;
10205 tag_buf[0] = '\0';
10206 struct bgp_path_info *bpi_ultimate =
10207 bgp_get_imported_bpi_ultimate(path);
10208
10209 if (json_paths) {
10210 json_path = json_object_new_object();
10211 json_peer = json_object_new_object();
10212 json_nexthop_global = json_object_new_object();
10213 }
10214
10215 if (safi == SAFI_EVPN) {
10216 if (!json_paths)
10217 vty_out(vty, " Route %pFX", p);
10218 }
10219
10220 if (path->extra) {
10221 if (path->extra && path->extra->num_labels) {
10222 bgp_evpn_label2str(path->extra->label,
10223 path->extra->num_labels, tag_buf,
10224 sizeof(tag_buf));
10225 }
10226 if (safi == SAFI_EVPN) {
10227 if (!json_paths) {
10228 if (tag_buf[0] != '\0')
10229 vty_out(vty, " VNI %s", tag_buf);
10230 } else {
10231 if (tag_buf[0])
10232 json_object_string_add(json_path, "vni",
10233 tag_buf);
10234 }
10235 }
10236 }
10237
10238 if (safi == SAFI_EVPN
10239 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
10240 char gwip_buf[INET6_ADDRSTRLEN];
10241
10242 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
10243 sizeof(gwip_buf));
10244
10245 if (json_paths)
10246 json_object_string_add(json_path, "gatewayIP",
10247 gwip_buf);
10248 else
10249 vty_out(vty, " Gateway IP %s", gwip_buf);
10250 }
10251
10252 if (safi == SAFI_EVPN && !json_path)
10253 vty_out(vty, "\n");
10254
10255
10256 if (path->extra && path->extra->parent && !json_paths) {
10257 struct bgp_path_info *parent_ri;
10258 struct bgp_dest *dest, *pdest;
10259
10260 parent_ri = (struct bgp_path_info *)path->extra->parent;
10261 dest = parent_ri->net;
10262 if (dest && dest->pdest) {
10263 pdest = dest->pdest;
10264 if (is_pi_family_evpn(parent_ri)) {
10265 vty_out(vty, " Imported from ");
10266 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10267 (struct prefix_rd *)bgp_dest_get_prefix(
10268 pdest));
10269 vty_out(vty, ":%pFX, VNI %s",
10270 (struct prefix_evpn *)
10271 bgp_dest_get_prefix(dest),
10272 tag_buf);
10273 if (CHECK_FLAG(attr->es_flags, ATTR_ES_L3_NHG))
10274 vty_out(vty, ", L3NHG %s",
10275 CHECK_FLAG(
10276 attr->es_flags,
10277 ATTR_ES_L3_NHG_ACTIVE)
10278 ? "active"
10279 : "inactive");
10280 vty_out(vty, "\n");
10281
10282 } else {
10283 vty_out(vty, " Imported from ");
10284 vty_out(vty, BGP_RD_AS_FORMAT(bgp->asnotation),
10285 (struct prefix_rd *)bgp_dest_get_prefix(
10286 pdest));
10287 vty_out(vty, ":%pFX\n",
10288 (struct prefix_evpn *)
10289 bgp_dest_get_prefix(dest));
10290 }
10291 }
10292 }
10293
10294 /* Line1 display AS-path, Aggregator */
10295 if (attr->aspath) {
10296 if (json_paths) {
10297 if (!attr->aspath->json)
10298 aspath_str_update(attr->aspath, true);
10299 json_object_lock(attr->aspath->json);
10300 json_object_object_add(json_path, "aspath",
10301 attr->aspath->json);
10302 } else {
10303 if (attr->aspath->segments)
10304 vty_out(vty, " %s", attr->aspath->str);
10305 else
10306 vty_out(vty, " Local");
10307 }
10308 }
10309
10310 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
10311 if (json_paths)
10312 json_object_boolean_true_add(json_path, "removed");
10313 else
10314 vty_out(vty, ", (removed)");
10315 }
10316
10317 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10318 if (json_paths)
10319 json_object_boolean_true_add(json_path, "stale");
10320 else
10321 vty_out(vty, ", (stale)");
10322 }
10323
10324 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
10325 if (json_paths) {
10326 json_object_int_add(json_path, "aggregatorAs",
10327 attr->aggregator_as);
10328 json_object_string_addf(json_path, "aggregatorId",
10329 "%pI4", &attr->aggregator_addr);
10330 } else {
10331 vty_out(vty, ", (aggregated by %u %pI4)",
10332 attr->aggregator_as, &attr->aggregator_addr);
10333 }
10334 }
10335
10336 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10337 PEER_FLAG_REFLECTOR_CLIENT)) {
10338 if (json_paths)
10339 json_object_boolean_true_add(json_path,
10340 "rxedFromRrClient");
10341 else
10342 vty_out(vty, ", (Received from a RR-client)");
10343 }
10344
10345 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10346 PEER_FLAG_RSERVER_CLIENT)) {
10347 if (json_paths)
10348 json_object_boolean_true_add(json_path,
10349 "rxedFromRsClient");
10350 else
10351 vty_out(vty, ", (Received from a RS-client)");
10352 }
10353
10354 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10355 if (json_paths)
10356 json_object_boolean_true_add(json_path,
10357 "dampeningHistoryEntry");
10358 else
10359 vty_out(vty, ", (history entry)");
10360 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10361 if (json_paths)
10362 json_object_boolean_true_add(json_path,
10363 "dampeningSuppressed");
10364 else
10365 vty_out(vty, ", (suppressed due to dampening)");
10366 }
10367
10368 if (!json_paths)
10369 vty_out(vty, "\n");
10370
10371 /* Line2 display Next-hop, Neighbor, Router-id */
10372 /* Display the nexthop */
10373
10374 if ((p->family == AF_INET || p->family == AF_ETHERNET ||
10375 p->family == AF_EVPN) &&
10376 (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN ||
10377 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10378 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10379 || safi == SAFI_EVPN) {
10380 if (json_paths) {
10381 json_object_string_addf(
10382 json_nexthop_global, "ip", "%pI4",
10383 &attr->mp_nexthop_global_in);
10384
10385 if (path->peer->hostname)
10386 json_object_string_add(
10387 json_nexthop_global, "hostname",
10388 path->peer->hostname);
10389 } else {
10390 if (nexthop_hostname)
10391 vty_out(vty, " %pI4(%s)",
10392 &attr->mp_nexthop_global_in,
10393 nexthop_hostname);
10394 else
10395 vty_out(vty, " %pI4",
10396 &attr->mp_nexthop_global_in);
10397 }
10398 } else {
10399 if (json_paths) {
10400 json_object_string_addf(json_nexthop_global,
10401 "ip", "%pI4",
10402 &attr->nexthop);
10403
10404 if (path->peer->hostname)
10405 json_object_string_add(
10406 json_nexthop_global, "hostname",
10407 path->peer->hostname);
10408 } else {
10409 if (nexthop_hostname)
10410 vty_out(vty, " %pI4(%s)",
10411 &attr->nexthop,
10412 nexthop_hostname);
10413 else
10414 vty_out(vty, " %pI4",
10415 &attr->nexthop);
10416 }
10417 }
10418
10419 if (json_paths)
10420 json_object_string_add(json_nexthop_global, "afi",
10421 "ipv4");
10422 } else {
10423 if (json_paths) {
10424 json_object_string_addf(json_nexthop_global, "ip",
10425 "%pI6",
10426 &attr->mp_nexthop_global);
10427
10428 if (path->peer->hostname)
10429 json_object_string_add(json_nexthop_global,
10430 "hostname",
10431 path->peer->hostname);
10432
10433 json_object_string_add(json_nexthop_global, "afi",
10434 "ipv6");
10435 json_object_string_add(json_nexthop_global, "scope",
10436 "global");
10437 } else {
10438 if (nexthop_hostname)
10439 vty_out(vty, " %pI6(%s)",
10440 &attr->mp_nexthop_global,
10441 nexthop_hostname);
10442 else
10443 vty_out(vty, " %pI6",
10444 &attr->mp_nexthop_global);
10445 }
10446 }
10447
10448 /* Display the IGP cost or 'inaccessible' */
10449 if (!CHECK_FLAG(bpi_ultimate->flags, BGP_PATH_VALID)) {
10450 bool import = CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
10451
10452 if (json_paths) {
10453 json_object_boolean_false_add(json_nexthop_global,
10454 "accessible");
10455 json_object_boolean_add(json_nexthop_global,
10456 "importCheckEnabled", import);
10457 } else {
10458 vty_out(vty, " (inaccessible%s)",
10459 import ? ", import-check enabled" : "");
10460 }
10461 } else {
10462 if (bpi_ultimate->extra && bpi_ultimate->extra->igpmetric) {
10463 if (json_paths)
10464 json_object_int_add(
10465 json_nexthop_global, "metric",
10466 bpi_ultimate->extra->igpmetric);
10467 else
10468 vty_out(vty, " (metric %u)",
10469 bpi_ultimate->extra->igpmetric);
10470 }
10471
10472 /* IGP cost is 0, display this only for json */
10473 else {
10474 if (json_paths)
10475 json_object_int_add(json_nexthop_global,
10476 "metric", 0);
10477 }
10478
10479 if (json_paths)
10480 json_object_boolean_true_add(json_nexthop_global,
10481 "accessible");
10482 }
10483
10484 /* Display peer "from" output */
10485 /* This path was originated locally */
10486 if (path->peer == bgp->peer_self) {
10487
10488 if (safi == SAFI_EVPN || (p->family == AF_INET &&
10489 !BGP_ATTR_MP_NEXTHOP_LEN_IP6(attr))) {
10490 if (json_paths)
10491 json_object_string_add(json_peer, "peerId",
10492 "0.0.0.0");
10493 else
10494 vty_out(vty, " from 0.0.0.0 ");
10495 } else {
10496 if (json_paths)
10497 json_object_string_add(json_peer, "peerId",
10498 "::");
10499 else
10500 vty_out(vty, " from :: ");
10501 }
10502
10503 if (json_paths)
10504 json_object_string_addf(json_peer, "routerId", "%pI4",
10505 &bgp->router_id);
10506 else
10507 vty_out(vty, "(%pI4)", &bgp->router_id);
10508 }
10509
10510 /* We RXed this path from one of our peers */
10511 else {
10512
10513 if (json_paths) {
10514 json_object_string_addf(json_peer, "peerId", "%pSU",
10515 &path->peer->su);
10516 json_object_string_addf(json_peer, "routerId", "%pI4",
10517 &path->peer->remote_id);
10518
10519 if (path->peer->hostname)
10520 json_object_string_add(json_peer, "hostname",
10521 path->peer->hostname);
10522
10523 if (path->peer->domainname)
10524 json_object_string_add(json_peer, "domainname",
10525 path->peer->domainname);
10526
10527 if (path->peer->conf_if)
10528 json_object_string_add(json_peer, "interface",
10529 path->peer->conf_if);
10530 } else {
10531 if (path->peer->conf_if) {
10532 if (path->peer->hostname
10533 && CHECK_FLAG(path->peer->bgp->flags,
10534 BGP_FLAG_SHOW_HOSTNAME))
10535 vty_out(vty, " from %s(%s)",
10536 path->peer->hostname,
10537 path->peer->conf_if);
10538 else
10539 vty_out(vty, " from %s",
10540 path->peer->conf_if);
10541 } else {
10542 if (path->peer->hostname
10543 && CHECK_FLAG(path->peer->bgp->flags,
10544 BGP_FLAG_SHOW_HOSTNAME))
10545 vty_out(vty, " from %s(%s)",
10546 path->peer->hostname,
10547 path->peer->host);
10548 else
10549 vty_out(vty, " from %pSU",
10550 &path->peer->su);
10551 }
10552
10553 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10554 vty_out(vty, " (%pI4)", &attr->originator_id);
10555 else
10556 vty_out(vty, " (%pI4)", &path->peer->remote_id);
10557 }
10558 }
10559
10560 /*
10561 * Note when vrfid of nexthop is different from that of prefix
10562 */
10563 if (path->extra && path->extra->bgp_orig) {
10564 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10565
10566 if (json_paths) {
10567 const char *vn;
10568
10569 if (path->extra->bgp_orig->inst_type
10570 == BGP_INSTANCE_TYPE_DEFAULT)
10571 vn = VRF_DEFAULT_NAME;
10572 else
10573 vn = path->extra->bgp_orig->name;
10574
10575 json_object_string_add(json_path, "nhVrfName", vn);
10576
10577 if (nexthop_vrfid == VRF_UNKNOWN) {
10578 json_object_int_add(json_path, "nhVrfId", -1);
10579 } else {
10580 json_object_int_add(json_path, "nhVrfId",
10581 (int)nexthop_vrfid);
10582 }
10583 } else {
10584 if (nexthop_vrfid == VRF_UNKNOWN)
10585 vty_out(vty, " vrf ?");
10586 else {
10587 struct vrf *vrf;
10588
10589 vrf = vrf_lookup_by_id(nexthop_vrfid);
10590 vty_out(vty, " vrf %s(%u)",
10591 VRF_LOGNAME(vrf), nexthop_vrfid);
10592 }
10593 }
10594 }
10595
10596 if (nexthop_self) {
10597 if (json_paths) {
10598 json_object_boolean_true_add(json_path,
10599 "announceNexthopSelf");
10600 } else {
10601 vty_out(vty, " announce-nh-self");
10602 }
10603 }
10604
10605 if (!json_paths)
10606 vty_out(vty, "\n");
10607
10608 /* display the link-local nexthop */
10609 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10610 if (json_paths) {
10611 json_nexthop_ll = json_object_new_object();
10612 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10613 &attr->mp_nexthop_local);
10614
10615 if (path->peer->hostname)
10616 json_object_string_add(json_nexthop_ll,
10617 "hostname",
10618 path->peer->hostname);
10619
10620 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10621 json_object_string_add(json_nexthop_ll, "scope",
10622 "link-local");
10623
10624 json_object_boolean_true_add(json_nexthop_ll,
10625 "accessible");
10626
10627 if (!attr->mp_nexthop_prefer_global)
10628 json_object_boolean_true_add(json_nexthop_ll,
10629 "used");
10630 else
10631 json_object_boolean_true_add(
10632 json_nexthop_global, "used");
10633 } else {
10634 vty_out(vty, " (%s) %s\n",
10635 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10636 buf, INET6_ADDRSTRLEN),
10637 attr->mp_nexthop_prefer_global
10638 ? "(prefer-global)"
10639 : "(used)");
10640 }
10641 }
10642 /* If we do not have a link-local nexthop then we must flag the
10643 global as "used" */
10644 else {
10645 if (json_paths)
10646 json_object_boolean_true_add(json_nexthop_global,
10647 "used");
10648 }
10649
10650 if (safi == SAFI_EVPN &&
10651 bgp_evpn_is_esi_valid(&attr->esi)) {
10652 route_vty_out_detail_es_info(vty, path, attr, json_path);
10653 }
10654
10655 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10656 * Int/Ext/Local, Atomic, best */
10657 if (json_paths)
10658 json_object_string_add(json_path, "origin",
10659 bgp_origin_long_str[attr->origin]);
10660 else
10661 vty_out(vty, " Origin %s",
10662 bgp_origin_long_str[attr->origin]);
10663
10664 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10665 if (json_paths)
10666 json_object_int_add(json_path, "metric", attr->med);
10667 else
10668 vty_out(vty, ", metric %u", attr->med);
10669 }
10670
10671 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10672 if (json_paths)
10673 json_object_int_add(json_path, "locPrf",
10674 attr->local_pref);
10675 else
10676 vty_out(vty, ", localpref %u", attr->local_pref);
10677 }
10678
10679 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AIGP)) {
10680 if (json_paths)
10681 json_object_int_add(json_path, "aigpMetric",
10682 bgp_attr_get_aigp_metric(attr));
10683 else
10684 vty_out(vty, ", aigp-metric %" PRIu64,
10685 bgp_attr_get_aigp_metric(attr));
10686 }
10687
10688 if (attr->weight != 0) {
10689 if (json_paths)
10690 json_object_int_add(json_path, "weight", attr->weight);
10691 else
10692 vty_out(vty, ", weight %u", attr->weight);
10693 }
10694
10695 if (attr->tag != 0) {
10696 if (json_paths)
10697 json_object_int_add(json_path, "tag", attr->tag);
10698 else
10699 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10700 }
10701
10702 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10703 if (json_paths)
10704 json_object_boolean_false_add(json_path, "valid");
10705 else
10706 vty_out(vty, ", invalid");
10707 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10708 if (json_paths)
10709 json_object_boolean_true_add(json_path, "valid");
10710 else
10711 vty_out(vty, ", valid");
10712 }
10713
10714 if (json_paths)
10715 json_object_int_add(json_path, "version", bn->version);
10716
10717 if (path->peer != bgp->peer_self) {
10718 if (path->peer->as == path->peer->local_as) {
10719 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10720 if (json_paths)
10721 json_object_string_add(
10722 json_peer, "type",
10723 "confed-internal");
10724 else
10725 vty_out(vty, ", confed-internal");
10726 } else {
10727 if (json_paths)
10728 json_object_string_add(
10729 json_peer, "type", "internal");
10730 else
10731 vty_out(vty, ", internal");
10732 }
10733 } else {
10734 if (bgp_confederation_peers_check(bgp,
10735 path->peer->as)) {
10736 if (json_paths)
10737 json_object_string_add(
10738 json_peer, "type",
10739 "confed-external");
10740 else
10741 vty_out(vty, ", confed-external");
10742 } else {
10743 if (json_paths)
10744 json_object_string_add(
10745 json_peer, "type", "external");
10746 else
10747 vty_out(vty, ", external");
10748 }
10749 }
10750 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10751 if (json_paths) {
10752 json_object_boolean_true_add(json_path, "aggregated");
10753 json_object_boolean_true_add(json_path, "local");
10754 } else {
10755 vty_out(vty, ", aggregated, local");
10756 }
10757 } else if (path->type != ZEBRA_ROUTE_BGP) {
10758 if (json_paths)
10759 json_object_boolean_true_add(json_path, "sourced");
10760 else
10761 vty_out(vty, ", sourced");
10762 } else {
10763 if (json_paths) {
10764 json_object_boolean_true_add(json_path, "sourced");
10765 json_object_boolean_true_add(json_path, "local");
10766 } else {
10767 vty_out(vty, ", sourced, local");
10768 }
10769 }
10770
10771 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10772 if (json_paths)
10773 json_object_boolean_true_add(json_path,
10774 "atomicAggregate");
10775 else
10776 vty_out(vty, ", atomic-aggregate");
10777 }
10778
10779 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_OTC)) {
10780 if (json_paths)
10781 json_object_int_add(json_path, "otc", attr->otc);
10782 else
10783 vty_out(vty, ", otc %u", attr->otc);
10784 }
10785
10786 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10787 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10788 && bgp_path_info_mpath_count(path))) {
10789 if (json_paths)
10790 json_object_boolean_true_add(json_path, "multipath");
10791 else
10792 vty_out(vty, ", multipath");
10793 }
10794
10795 // Mark the bestpath(s)
10796 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10797 first_as = aspath_get_first_as(attr->aspath);
10798
10799 if (json_paths) {
10800 if (!json_bestpath)
10801 json_bestpath = json_object_new_object();
10802 json_object_int_add(json_bestpath, "bestpathFromAs",
10803 first_as);
10804 } else {
10805 if (first_as)
10806 vty_out(vty, ", bestpath-from-AS %u", first_as);
10807 else
10808 vty_out(vty, ", bestpath-from-AS Local");
10809 }
10810 }
10811
10812 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10813 if (json_paths) {
10814 if (!json_bestpath)
10815 json_bestpath = json_object_new_object();
10816 json_object_boolean_true_add(json_bestpath, "overall");
10817 json_object_string_add(
10818 json_bestpath, "selectionReason",
10819 bgp_path_selection_reason2str(bn->reason));
10820 } else {
10821 vty_out(vty, ", best");
10822 vty_out(vty, " (%s)",
10823 bgp_path_selection_reason2str(bn->reason));
10824 }
10825 }
10826
10827 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10828 if (json_paths)
10829 json_object_string_add(
10830 json_path, "rpkiValidationState",
10831 bgp_rpki_validation2str(rpki_curr_state));
10832 else
10833 vty_out(vty, ", rpki validation-state: %s",
10834 bgp_rpki_validation2str(rpki_curr_state));
10835 }
10836
10837 if (json_bestpath)
10838 json_object_object_add(json_path, "bestpath", json_bestpath);
10839
10840 if (!json_paths)
10841 vty_out(vty, "\n");
10842
10843 /* Line 4 display Community */
10844 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10845 if (json_paths) {
10846 if (!bgp_attr_get_community(attr)->json)
10847 community_str(bgp_attr_get_community(attr),
10848 true, true);
10849 json_object_lock(bgp_attr_get_community(attr)->json);
10850 json_object_object_add(
10851 json_path, "community",
10852 bgp_attr_get_community(attr)->json);
10853 } else {
10854 vty_out(vty, " Community: %s\n",
10855 bgp_attr_get_community(attr)->str);
10856 }
10857 }
10858
10859 /* Line 5 display Extended-community */
10860 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10861 if (json_paths) {
10862 json_ext_community = json_object_new_object();
10863 json_object_string_add(
10864 json_ext_community, "string",
10865 bgp_attr_get_ecommunity(attr)->str);
10866 json_object_object_add(json_path, "extendedCommunity",
10867 json_ext_community);
10868 } else {
10869 vty_out(vty, " Extended Community: %s\n",
10870 bgp_attr_get_ecommunity(attr)->str);
10871 }
10872 }
10873
10874 /* Line 6 display Large community */
10875 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10876 if (json_paths) {
10877 if (!bgp_attr_get_lcommunity(attr)->json)
10878 lcommunity_str(bgp_attr_get_lcommunity(attr),
10879 true, true);
10880 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10881 json_object_object_add(
10882 json_path, "largeCommunity",
10883 bgp_attr_get_lcommunity(attr)->json);
10884 } else {
10885 vty_out(vty, " Large Community: %s\n",
10886 bgp_attr_get_lcommunity(attr)->str);
10887 }
10888 }
10889
10890 /* Line 7 display Originator, Cluster-id */
10891 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10892 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10893 char buf[BUFSIZ] = {0};
10894
10895 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10896 if (json_paths)
10897 json_object_string_addf(json_path,
10898 "originatorId", "%pI4",
10899 &attr->originator_id);
10900 else
10901 vty_out(vty, " Originator: %pI4",
10902 &attr->originator_id);
10903 }
10904
10905 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10906 struct cluster_list *cluster =
10907 bgp_attr_get_cluster(attr);
10908 int i;
10909
10910 if (json_paths) {
10911 json_cluster_list = json_object_new_object();
10912 json_cluster_list_list =
10913 json_object_new_array();
10914
10915 for (i = 0; i < cluster->length / 4; i++) {
10916 json_string = json_object_new_string(
10917 inet_ntop(AF_INET,
10918 &cluster->list[i],
10919 buf, sizeof(buf)));
10920 json_object_array_add(
10921 json_cluster_list_list,
10922 json_string);
10923 }
10924
10925 /*
10926 * struct cluster_list does not have
10927 * "str" variable like aspath and community
10928 * do. Add this someday if someone asks
10929 * for it.
10930 * json_object_string_add(json_cluster_list,
10931 * "string", cluster->str);
10932 */
10933 json_object_object_add(json_cluster_list,
10934 "list",
10935 json_cluster_list_list);
10936 json_object_object_add(json_path, "clusterList",
10937 json_cluster_list);
10938 } else {
10939 vty_out(vty, ", Cluster list: ");
10940
10941 for (i = 0; i < cluster->length / 4; i++) {
10942 vty_out(vty, "%pI4 ",
10943 &cluster->list[i]);
10944 }
10945 }
10946 }
10947
10948 if (!json_paths)
10949 vty_out(vty, "\n");
10950 }
10951
10952 if (path->extra && path->extra->damp_info)
10953 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10954
10955 /* Remote Label */
10956 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10957 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10958 mpls_lse_decode(path->extra->label[0], &label, &ttl, &exp,
10959 &bos);
10960
10961 if (json_paths)
10962 json_object_int_add(json_path, "remoteLabel", label);
10963 else
10964 vty_out(vty, " Remote label: %d\n", label);
10965 }
10966
10967 /* Remote SID */
10968 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10969 if (json_paths)
10970 json_object_string_addf(json_path, "remoteSid", "%pI6",
10971 &path->extra->sid[0].sid);
10972 else
10973 vty_out(vty, " Remote SID: %pI6\n",
10974 &path->extra->sid[0].sid);
10975 }
10976
10977 /* Label Index */
10978 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10979 if (json_paths)
10980 json_object_int_add(json_path, "labelIndex",
10981 attr->label_index);
10982 else
10983 vty_out(vty, " Label Index: %d\n",
10984 attr->label_index);
10985 }
10986
10987 /* Line 8 display Addpath IDs */
10988 if (path->addpath_rx_id
10989 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10990 if (json_paths) {
10991 json_object_int_add(json_path, "addpathRxId",
10992 path->addpath_rx_id);
10993
10994 /* Keep backwards compatibility with the old API
10995 * by putting TX All's ID in the old field
10996 */
10997 json_object_int_add(
10998 json_path, "addpathTxId",
10999 path->tx_addpath
11000 .addpath_tx_id[BGP_ADDPATH_ALL]);
11001
11002 /* ... but create a specific field for each
11003 * strategy
11004 */
11005 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
11006 json_object_int_add(
11007 json_path,
11008 bgp_addpath_names(i)->id_json_name,
11009 path->tx_addpath.addpath_tx_id[i]);
11010 }
11011 } else {
11012 vty_out(vty, " AddPath ID: RX %u, ",
11013 path->addpath_rx_id);
11014
11015 route_vty_out_tx_ids(vty, &path->tx_addpath);
11016 }
11017 }
11018
11019 /* If we used addpath to TX a non-bestpath we need to display
11020 * "Advertised to" on a path-by-path basis
11021 */
11022 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11023 first = 1;
11024
11025 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11026 addpath_capable =
11027 bgp_addpath_encode_tx(peer, afi, safi);
11028 has_adj = bgp_adj_out_lookup(
11029 peer, path->net,
11030 bgp_addpath_id_for_peer(peer, afi, safi,
11031 &path->tx_addpath));
11032
11033 if ((addpath_capable && has_adj)
11034 || (!addpath_capable && has_adj
11035 && CHECK_FLAG(path->flags,
11036 BGP_PATH_SELECTED))) {
11037 if (json_path && !json_adv_to)
11038 json_adv_to = json_object_new_object();
11039
11040 route_vty_out_advertised_to(
11041 vty, peer, &first,
11042 " Advertised to:", json_adv_to);
11043 }
11044 }
11045
11046 if (json_path) {
11047 if (json_adv_to) {
11048 json_object_object_add(
11049 json_path, "advertisedTo", json_adv_to);
11050 }
11051 } else {
11052 if (!first) {
11053 vty_out(vty, "\n");
11054 }
11055 }
11056 }
11057
11058 /* Line 9 display Uptime */
11059 tbuf = time(NULL) - (monotime(NULL) - path->uptime);
11060 if (json_paths) {
11061 json_last_update = json_object_new_object();
11062 json_object_int_add(json_last_update, "epoch", tbuf);
11063 json_object_string_add(json_last_update, "string",
11064 ctime(&tbuf));
11065 json_object_object_add(json_path, "lastUpdate",
11066 json_last_update);
11067 } else
11068 vty_out(vty, " Last update: %s", ctime(&tbuf));
11069
11070 /* Line 10 display PMSI tunnel attribute, if present */
11071 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
11072 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
11073 bgp_attr_get_pmsi_tnl_type(attr),
11074 PMSI_TNLTYPE_STR_DEFAULT);
11075
11076 if (json_paths) {
11077 json_pmsi = json_object_new_object();
11078 json_object_string_add(json_pmsi, "tunnelType", str);
11079 json_object_int_add(json_pmsi, "label",
11080 label2vni(&attr->label));
11081 json_object_object_add(json_path, "pmsi", json_pmsi);
11082 } else
11083 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
11084 str, label2vni(&attr->label));
11085 }
11086
11087 if (path->peer->t_gr_restart &&
11088 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
11089 unsigned long gr_remaining =
11090 event_timer_remain_second(path->peer->t_gr_restart);
11091
11092 if (json_paths) {
11093 json_object_int_add(json_path,
11094 "gracefulRestartSecondsRemaining",
11095 gr_remaining);
11096 } else
11097 vty_out(vty,
11098 " Time until Graceful Restart stale route deleted: %lu\n",
11099 gr_remaining);
11100 }
11101
11102 if (path->peer->t_llgr_stale[afi][safi] &&
11103 bgp_attr_get_community(attr) &&
11104 community_include(bgp_attr_get_community(attr),
11105 COMMUNITY_LLGR_STALE)) {
11106 unsigned long llgr_remaining = event_timer_remain_second(
11107 path->peer->t_llgr_stale[afi][safi]);
11108
11109 if (json_paths) {
11110 json_object_int_add(json_path, "llgrSecondsRemaining",
11111 llgr_remaining);
11112 } else
11113 vty_out(vty,
11114 " Time until Long-lived stale route deleted: %lu\n",
11115 llgr_remaining);
11116 }
11117
11118 /* Output some debug about internal state of the dest flags */
11119 if (json_paths) {
11120 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
11121 json_object_boolean_true_add(json_path, "processScheduled");
11122 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
11123 json_object_boolean_true_add(json_path, "userCleared");
11124 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
11125 json_object_boolean_true_add(json_path, "labelChanged");
11126 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
11127 json_object_boolean_true_add(json_path, "registeredForLabel");
11128 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
11129 json_object_boolean_true_add(json_path, "selectDefered");
11130 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
11131 json_object_boolean_true_add(json_path, "fibInstalled");
11132 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
11133 json_object_boolean_true_add(json_path, "fibPending");
11134
11135 if (json_nexthop_global || json_nexthop_ll) {
11136 json_nexthops = json_object_new_array();
11137
11138 if (json_nexthop_global)
11139 json_object_array_add(json_nexthops,
11140 json_nexthop_global);
11141
11142 if (json_nexthop_ll)
11143 json_object_array_add(json_nexthops,
11144 json_nexthop_ll);
11145
11146 json_object_object_add(json_path, "nexthops",
11147 json_nexthops);
11148 }
11149
11150 json_object_object_add(json_path, "peer", json_peer);
11151 json_object_array_add(json_paths, json_path);
11152 }
11153 }
11154
11155 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
11156 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
11157 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
11158
11159 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
11160 afi_t afi, safi_t safi, enum bgp_show_type type,
11161 bool use_json);
11162 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
11163 const char *comstr, int exact, afi_t afi,
11164 safi_t safi, uint16_t show_flags);
11165
11166 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
11167 struct bgp_table *table, enum bgp_show_type type,
11168 void *output_arg, const char *rd, int is_last,
11169 unsigned long *output_cum, unsigned long *total_cum,
11170 unsigned long *json_header_depth, uint16_t show_flags,
11171 enum rpki_states rpki_target_state)
11172 {
11173 struct bgp_path_info *pi;
11174 struct bgp_dest *dest;
11175 bool header = true;
11176 bool json_detail_header = false;
11177 int display;
11178 unsigned long output_count = 0;
11179 unsigned long total_count = 0;
11180 struct prefix *p;
11181 json_object *json_paths = NULL;
11182 int first = 1;
11183 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11184 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
11185 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11186 bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
11187 bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
11188
11189 if (output_cum && *output_cum != 0)
11190 header = false;
11191
11192 if (use_json && !*json_header_depth) {
11193 if (all)
11194 *json_header_depth = 1;
11195 else {
11196 vty_out(vty, "{\n");
11197 *json_header_depth = 2;
11198 }
11199 vty_out(vty,
11200 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
11201 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
11202 " \"localAS\": ",
11203 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
11204 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
11205 ? VRF_DEFAULT_NAME
11206 : bgp->name,
11207 table->version, &bgp->router_id,
11208 bgp->default_local_pref);
11209 if ((bgp->asnotation == ASNOTATION_PLAIN) ||
11210 ((bgp->asnotation == ASNOTATION_DOT) &&
11211 (bgp->as < UINT16_MAX)))
11212 vty_out(vty, "%u", bgp->as);
11213 else {
11214 vty_out(vty, "\"");
11215 vty_out(vty, ASN_FORMAT(bgp->asnotation), &bgp->as);
11216 vty_out(vty, "\"");
11217 }
11218 vty_out(vty, ",\n \"routes\": { ");
11219 if (rd) {
11220 vty_out(vty, " \"routeDistinguishers\" : {");
11221 ++*json_header_depth;
11222 }
11223 }
11224
11225 if (use_json && rd) {
11226 vty_out(vty, " \"%s\" : { ", rd);
11227 }
11228
11229 /* Check for 'json detail', where we need header output once per dest */
11230 if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
11231 type != bgp_show_type_damp_neighbor &&
11232 type != bgp_show_type_flap_statistics &&
11233 type != bgp_show_type_flap_neighbor)
11234 json_detail_header = true;
11235
11236 /* Start processing of routes. */
11237 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
11238 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11239 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11240 bool json_detail_header_used = false;
11241
11242 pi = bgp_dest_get_bgp_path_info(dest);
11243 if (pi == NULL)
11244 continue;
11245
11246 display = 0;
11247 if (use_json)
11248 json_paths = json_object_new_array();
11249 else
11250 json_paths = NULL;
11251
11252 for (; pi; pi = pi->next) {
11253 struct community *picomm = NULL;
11254
11255 picomm = bgp_attr_get_community(pi->attr);
11256
11257 total_count++;
11258
11259 if (type == bgp_show_type_prefix_version) {
11260 uint32_t version =
11261 strtoul(output_arg, NULL, 10);
11262 if (dest->version < version)
11263 continue;
11264 }
11265
11266 if (type == bgp_show_type_community_alias) {
11267 char *alias = output_arg;
11268 char **communities;
11269 int num;
11270 bool found = false;
11271
11272 if (picomm) {
11273 frrstr_split(picomm->str, " ",
11274 &communities, &num);
11275 for (int i = 0; i < num; i++) {
11276 const char *com2alias =
11277 bgp_community2alias(
11278 communities[i]);
11279 if (!found
11280 && strcmp(alias, com2alias)
11281 == 0)
11282 found = true;
11283 XFREE(MTYPE_TMP,
11284 communities[i]);
11285 }
11286 XFREE(MTYPE_TMP, communities);
11287 }
11288
11289 if (!found &&
11290 bgp_attr_get_lcommunity(pi->attr)) {
11291 frrstr_split(bgp_attr_get_lcommunity(
11292 pi->attr)
11293 ->str,
11294 " ", &communities, &num);
11295 for (int i = 0; i < num; i++) {
11296 const char *com2alias =
11297 bgp_community2alias(
11298 communities[i]);
11299 if (!found
11300 && strcmp(alias, com2alias)
11301 == 0)
11302 found = true;
11303 XFREE(MTYPE_TMP,
11304 communities[i]);
11305 }
11306 XFREE(MTYPE_TMP, communities);
11307 }
11308
11309 if (!found)
11310 continue;
11311 }
11312
11313 if (type == bgp_show_type_rpki) {
11314 if (dest_p->family == AF_INET
11315 || dest_p->family == AF_INET6)
11316 rpki_curr_state = hook_call(
11317 bgp_rpki_prefix_status,
11318 pi->peer, pi->attr, dest_p);
11319 if (rpki_target_state != RPKI_NOT_BEING_USED
11320 && rpki_curr_state != rpki_target_state)
11321 continue;
11322 }
11323
11324 if (type == bgp_show_type_flap_statistics
11325 || type == bgp_show_type_flap_neighbor
11326 || type == bgp_show_type_dampend_paths
11327 || type == bgp_show_type_damp_neighbor) {
11328 if (!(pi->extra && pi->extra->damp_info))
11329 continue;
11330 }
11331 if (type == bgp_show_type_regexp) {
11332 regex_t *regex = output_arg;
11333
11334 if (bgp_regexec(regex, pi->attr->aspath)
11335 == REG_NOMATCH)
11336 continue;
11337 }
11338 if (type == bgp_show_type_prefix_list) {
11339 struct prefix_list *plist = output_arg;
11340
11341 if (prefix_list_apply(plist, dest_p)
11342 != PREFIX_PERMIT)
11343 continue;
11344 }
11345 if (type == bgp_show_type_access_list) {
11346 struct access_list *alist = output_arg;
11347
11348 if (access_list_apply(alist, dest_p) !=
11349 FILTER_PERMIT)
11350 continue;
11351 }
11352 if (type == bgp_show_type_filter_list) {
11353 struct as_list *as_list = output_arg;
11354
11355 if (as_list_apply(as_list, pi->attr->aspath)
11356 != AS_FILTER_PERMIT)
11357 continue;
11358 }
11359 if (type == bgp_show_type_route_map) {
11360 struct route_map *rmap = output_arg;
11361 struct bgp_path_info path;
11362 struct bgp_path_info_extra extra;
11363 struct attr dummy_attr = {};
11364 route_map_result_t ret;
11365
11366 dummy_attr = *pi->attr;
11367
11368 prep_for_rmap_apply(&path, &extra, dest, pi,
11369 pi->peer, &dummy_attr);
11370
11371 ret = route_map_apply(rmap, dest_p, &path);
11372 bgp_attr_flush(&dummy_attr);
11373 if (ret == RMAP_DENYMATCH)
11374 continue;
11375 }
11376 if (type == bgp_show_type_neighbor
11377 || type == bgp_show_type_flap_neighbor
11378 || type == bgp_show_type_damp_neighbor) {
11379 union sockunion *su = output_arg;
11380
11381 if (pi->peer == NULL
11382 || pi->peer->su_remote == NULL
11383 || !sockunion_same(pi->peer->su_remote, su))
11384 continue;
11385 }
11386 if (type == bgp_show_type_cidr_only) {
11387 uint32_t destination;
11388
11389 destination = ntohl(dest_p->u.prefix4.s_addr);
11390 if (IN_CLASSC(destination)
11391 && dest_p->prefixlen == 24)
11392 continue;
11393 if (IN_CLASSB(destination)
11394 && dest_p->prefixlen == 16)
11395 continue;
11396 if (IN_CLASSA(destination)
11397 && dest_p->prefixlen == 8)
11398 continue;
11399 }
11400 if (type == bgp_show_type_prefix_longer) {
11401 p = output_arg;
11402 if (!prefix_match(p, dest_p))
11403 continue;
11404 }
11405 if (type == bgp_show_type_community_all) {
11406 if (!picomm)
11407 continue;
11408 }
11409 if (type == bgp_show_type_community) {
11410 struct community *com = output_arg;
11411
11412 if (!picomm || !community_match(picomm, com))
11413 continue;
11414 }
11415 if (type == bgp_show_type_community_exact) {
11416 struct community *com = output_arg;
11417
11418 if (!picomm || !community_cmp(picomm, com))
11419 continue;
11420 }
11421 if (type == bgp_show_type_community_list) {
11422 struct community_list *list = output_arg;
11423
11424 if (!community_list_match(picomm, list))
11425 continue;
11426 }
11427 if (type == bgp_show_type_community_list_exact) {
11428 struct community_list *list = output_arg;
11429
11430 if (!community_list_exact_match(picomm, list))
11431 continue;
11432 }
11433 if (type == bgp_show_type_lcommunity) {
11434 struct lcommunity *lcom = output_arg;
11435
11436 if (!bgp_attr_get_lcommunity(pi->attr) ||
11437 !lcommunity_match(
11438 bgp_attr_get_lcommunity(pi->attr),
11439 lcom))
11440 continue;
11441 }
11442
11443 if (type == bgp_show_type_lcommunity_exact) {
11444 struct lcommunity *lcom = output_arg;
11445
11446 if (!bgp_attr_get_lcommunity(pi->attr) ||
11447 !lcommunity_cmp(
11448 bgp_attr_get_lcommunity(pi->attr),
11449 lcom))
11450 continue;
11451 }
11452 if (type == bgp_show_type_lcommunity_list) {
11453 struct community_list *list = output_arg;
11454
11455 if (!lcommunity_list_match(
11456 bgp_attr_get_lcommunity(pi->attr),
11457 list))
11458 continue;
11459 }
11460 if (type
11461 == bgp_show_type_lcommunity_list_exact) {
11462 struct community_list *list = output_arg;
11463
11464 if (!lcommunity_list_exact_match(
11465 bgp_attr_get_lcommunity(pi->attr),
11466 list))
11467 continue;
11468 }
11469 if (type == bgp_show_type_lcommunity_all) {
11470 if (!bgp_attr_get_lcommunity(pi->attr))
11471 continue;
11472 }
11473 if (type == bgp_show_type_dampend_paths
11474 || type == bgp_show_type_damp_neighbor) {
11475 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11476 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11477 continue;
11478 }
11479 if (type == bgp_show_type_self_originated) {
11480 if (pi->peer != bgp->peer_self)
11481 continue;
11482 }
11483
11484 if (!use_json && header) {
11485 vty_out(vty,
11486 "BGP table version is %" PRIu64
11487 ", local router ID is %pI4, vrf id ",
11488 table->version, &bgp->router_id);
11489 if (bgp->vrf_id == VRF_UNKNOWN)
11490 vty_out(vty, "%s", VRFID_NONE_STR);
11491 else
11492 vty_out(vty, "%u", bgp->vrf_id);
11493 vty_out(vty, "\n");
11494 vty_out(vty, "Default local pref %u, ",
11495 bgp->default_local_pref);
11496 vty_out(vty, "local AS ");
11497 vty_out(vty, ASN_FORMAT(bgp->asnotation),
11498 &bgp->as);
11499 vty_out(vty, "\n");
11500 if (!detail_routes) {
11501 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11502 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11503 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11504 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11505 }
11506 if (type == bgp_show_type_dampend_paths
11507 || type == bgp_show_type_damp_neighbor)
11508 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11509 else if (type == bgp_show_type_flap_statistics
11510 || type == bgp_show_type_flap_neighbor)
11511 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11512 else if (!detail_routes)
11513 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11514 : BGP_SHOW_HEADER));
11515 header = false;
11516
11517 }
11518 if (rd != NULL && !display && !output_count) {
11519 if (!use_json)
11520 vty_out(vty,
11521 "Route Distinguisher: %s\n",
11522 rd);
11523 }
11524 if (type == bgp_show_type_dampend_paths
11525 || type == bgp_show_type_damp_neighbor)
11526 damp_route_vty_out(vty, dest_p, pi, display,
11527 AFI_IP, safi, use_json,
11528 json_paths);
11529 else if (type == bgp_show_type_flap_statistics
11530 || type == bgp_show_type_flap_neighbor)
11531 flap_route_vty_out(vty, dest_p, pi, display,
11532 AFI_IP, safi, use_json,
11533 json_paths);
11534 else {
11535 if (detail_routes || detail_json) {
11536 const struct prefix_rd *prd = NULL;
11537
11538 if (dest->pdest)
11539 prd = bgp_rd_from_dest(
11540 dest->pdest, safi);
11541
11542 if (!use_json)
11543 route_vty_out_detail_header(
11544 vty, bgp, dest,
11545 bgp_dest_get_prefix(
11546 dest),
11547 prd, table->afi, safi,
11548 NULL, false);
11549
11550 route_vty_out_detail(
11551 vty, bgp, dest, dest_p, pi,
11552 family2afi(dest_p->family),
11553 safi, RPKI_NOT_BEING_USED,
11554 json_paths);
11555 } else {
11556 route_vty_out(vty, dest_p, pi, display,
11557 safi, json_paths, wide);
11558 }
11559 }
11560 display++;
11561 }
11562
11563 if (display) {
11564 output_count++;
11565 if (!use_json)
11566 continue;
11567
11568 /* encode prefix */
11569 if (dest_p->family == AF_FLOWSPEC) {
11570 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11571
11572
11573 bgp_fs_nlri_get_string(
11574 (unsigned char *)
11575 dest_p->u.prefix_flowspec.ptr,
11576 dest_p->u.prefix_flowspec.prefixlen,
11577 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11578 family2afi(dest_p->u
11579 .prefix_flowspec.family));
11580 if (first)
11581 vty_out(vty, "\"%s/%d\": ", retstr,
11582 dest_p->u.prefix_flowspec
11583 .prefixlen);
11584 else
11585 vty_out(vty, ",\"%s/%d\": ", retstr,
11586 dest_p->u.prefix_flowspec
11587 .prefixlen);
11588 } else {
11589 if (first)
11590 vty_out(vty, "\"%pFX\": ", dest_p);
11591 else
11592 vty_out(vty, ",\"%pFX\": ", dest_p);
11593 }
11594
11595 if (json_detail_header && json_paths != NULL) {
11596 const struct prefix_rd *prd;
11597
11598 vty_out(vty, "{\n");
11599
11600 prd = bgp_rd_from_dest(dest, safi);
11601
11602 route_vty_out_detail_header(
11603 vty, bgp, dest,
11604 bgp_dest_get_prefix(dest), prd,
11605 table->afi, safi, json_paths, true);
11606
11607 vty_out(vty, "\"paths\": ");
11608 json_detail_header_used = true;
11609 }
11610
11611 /*
11612 * We are using no_pretty here because under
11613 * extremely high settings( say lots and lots of
11614 * routes with lots and lots of ways to reach
11615 * that route via different paths ) this can
11616 * save several minutes of output when FRR
11617 * is run on older cpu's or more underperforming
11618 * routers out there
11619 */
11620 vty_json_no_pretty(vty, json_paths);
11621
11622 if (json_detail_header_used)
11623 vty_out(vty, "} ");
11624
11625 json_paths = NULL;
11626 first = 0;
11627 } else
11628 json_object_free(json_paths);
11629 }
11630
11631 if (output_cum) {
11632 output_count += *output_cum;
11633 *output_cum = output_count;
11634 }
11635 if (total_cum) {
11636 total_count += *total_cum;
11637 *total_cum = total_count;
11638 }
11639 if (use_json) {
11640 if (rd) {
11641 vty_out(vty, " }%s ", (is_last ? "" : ","));
11642 }
11643 if (is_last) {
11644 unsigned long i;
11645 for (i = 0; i < *json_header_depth; ++i)
11646 vty_out(vty, " } ");
11647 if (!all)
11648 vty_out(vty, "\n");
11649 }
11650 } else {
11651 if (is_last) {
11652 /* No route is displayed */
11653 if (output_count == 0) {
11654 if (type == bgp_show_type_normal)
11655 vty_out(vty,
11656 "No BGP prefixes displayed, %ld exist\n",
11657 total_count);
11658 } else
11659 vty_out(vty,
11660 "\nDisplayed %ld routes and %ld total paths\n",
11661 output_count, total_count);
11662 }
11663 }
11664
11665 return CMD_SUCCESS;
11666 }
11667
11668 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11669 struct bgp_table *table, struct prefix_rd *prd_match,
11670 enum bgp_show_type type, void *output_arg,
11671 uint16_t show_flags)
11672 {
11673 struct bgp_dest *dest, *next;
11674 unsigned long output_cum = 0;
11675 unsigned long total_cum = 0;
11676 unsigned long json_header_depth = 0;
11677 struct bgp_table *itable;
11678 bool show_msg;
11679 bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11680
11681 show_msg = (!use_json && type == bgp_show_type_normal);
11682
11683 for (dest = bgp_table_top(table); dest; dest = next) {
11684 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11685
11686 next = bgp_route_next(dest);
11687 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11688 continue;
11689
11690 itable = bgp_dest_get_bgp_table_info(dest);
11691 if (itable != NULL) {
11692 struct prefix_rd prd;
11693 char rd[RD_ADDRSTRLEN];
11694
11695 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11696 prefix_rd2str(&prd, rd, sizeof(rd), bgp->asnotation);
11697 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11698 rd, next == NULL, &output_cum,
11699 &total_cum, &json_header_depth,
11700 show_flags, RPKI_NOT_BEING_USED);
11701 if (next == NULL)
11702 show_msg = false;
11703 }
11704 }
11705 if (show_msg) {
11706 if (output_cum == 0)
11707 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11708 total_cum);
11709 else
11710 vty_out(vty,
11711 "\nDisplayed %ld routes and %ld total paths\n",
11712 output_cum, total_cum);
11713 } else {
11714 if (use_json && output_cum == 0)
11715 vty_out(vty, "{}\n");
11716 }
11717 return CMD_SUCCESS;
11718 }
11719
11720 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11721 enum bgp_show_type type, void *output_arg,
11722 uint16_t show_flags, enum rpki_states rpki_target_state)
11723 {
11724 struct bgp_table *table;
11725 unsigned long json_header_depth = 0;
11726 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11727
11728 if (bgp == NULL) {
11729 bgp = bgp_get_default();
11730 }
11731
11732 if (bgp == NULL) {
11733 if (!use_json)
11734 vty_out(vty, "No BGP process is configured\n");
11735 else
11736 vty_out(vty, "{}\n");
11737 return CMD_WARNING;
11738 }
11739
11740 /* Labeled-unicast routes live in the unicast table. */
11741 if (safi == SAFI_LABELED_UNICAST)
11742 safi = SAFI_UNICAST;
11743
11744 table = bgp->rib[afi][safi];
11745 /* use MPLS and ENCAP specific shows until they are merged */
11746 if (safi == SAFI_MPLS_VPN) {
11747 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11748 output_arg, show_flags);
11749 }
11750
11751 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11752 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11753 output_arg, use_json,
11754 1, NULL, NULL);
11755 }
11756
11757 if (safi == SAFI_EVPN)
11758 return bgp_evpn_show_all_routes(vty, bgp, type, use_json, 0);
11759
11760 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11761 NULL, NULL, &json_header_depth, show_flags,
11762 rpki_target_state);
11763 }
11764
11765 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11766 safi_t safi, uint16_t show_flags)
11767 {
11768 struct listnode *node, *nnode;
11769 struct bgp *bgp;
11770 int is_first = 1;
11771 bool route_output = false;
11772 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11773
11774 if (use_json)
11775 vty_out(vty, "{\n");
11776
11777 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11778 route_output = true;
11779 if (use_json) {
11780 if (!is_first)
11781 vty_out(vty, ",\n");
11782 else
11783 is_first = 0;
11784
11785 vty_out(vty, "\"%s\":",
11786 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11787 ? VRF_DEFAULT_NAME
11788 : bgp->name);
11789 } else {
11790 vty_out(vty, "\nInstance %s:\n",
11791 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11792 ? VRF_DEFAULT_NAME
11793 : bgp->name);
11794 }
11795 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11796 show_flags, RPKI_NOT_BEING_USED);
11797 }
11798
11799 if (use_json)
11800 vty_out(vty, "}\n");
11801 else if (!route_output)
11802 vty_out(vty, "%% BGP instance not found\n");
11803 }
11804
11805 /* Header of detailed BGP route information */
11806 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11807 struct bgp_dest *dest, const struct prefix *p,
11808 const struct prefix_rd *prd, afi_t afi,
11809 safi_t safi, json_object *json,
11810 bool incremental_print)
11811 {
11812 struct bgp_path_info *pi;
11813 struct peer *peer;
11814 struct listnode *node, *nnode;
11815 char buf1[RD_ADDRSTRLEN];
11816 int count = 0;
11817 int best = 0;
11818 int suppress = 0;
11819 int accept_own = 0;
11820 int route_filter_translated_v4 = 0;
11821 int route_filter_v4 = 0;
11822 int route_filter_translated_v6 = 0;
11823 int route_filter_v6 = 0;
11824 int llgr_stale = 0;
11825 int no_llgr = 0;
11826 int accept_own_nexthop = 0;
11827 int blackhole = 0;
11828 int no_export = 0;
11829 int no_advertise = 0;
11830 int local_as = 0;
11831 int no_peer = 0;
11832 int first = 1;
11833 int has_valid_label = 0;
11834 mpls_label_t label = 0;
11835 json_object *json_adv_to = NULL;
11836 uint32_t ttl = 0;
11837 uint32_t bos = 0;
11838 uint32_t exp = 0;
11839
11840 mpls_lse_decode(dest->local_label, &label, &ttl, &exp, &bos);
11841
11842 has_valid_label = bgp_is_valid_label(&label);
11843
11844 if (safi == SAFI_EVPN) {
11845 if (!json) {
11846 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11847 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11848 bgp->asnotation)
11849 : "",
11850 prd ? ":" : "", (struct prefix_evpn *)p);
11851 } else {
11852 json_object_string_add(
11853 json, "rd",
11854 prd ? prefix_rd2str(prd, buf1, sizeof(buf1),
11855 bgp->asnotation)
11856 : "");
11857 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11858 }
11859 } else {
11860 if (!json) {
11861 vty_out(vty,
11862 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11863 "\n",
11864 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11865 ? prefix_rd2str(prd, buf1,
11866 sizeof(buf1),
11867 bgp->asnotation)
11868 : ""),
11869 safi == SAFI_MPLS_VPN ? ":" : "", p,
11870 dest->version);
11871
11872 } else {
11873 if (incremental_print) {
11874 vty_out(vty, "\"prefix\": \"%pFX\",\n", p);
11875 vty_out(vty, "\"version\": \"%" PRIu64 "\",\n",
11876 dest->version);
11877 } else {
11878 json_object_string_addf(json, "prefix", "%pFX",
11879 p);
11880 json_object_int_add(json, "version",
11881 dest->version);
11882 }
11883 }
11884 }
11885
11886 if (has_valid_label) {
11887 if (json) {
11888 if (incremental_print)
11889 vty_out(vty, "\"localLabel\": \"%u\",\n",
11890 label);
11891 else
11892 json_object_int_add(json, "localLabel", label);
11893 } else
11894 vty_out(vty, "Local label: %d\n", label);
11895 }
11896
11897 if (!json)
11898 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11899 vty_out(vty, "not allocated\n");
11900
11901 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11902 struct community *picomm = NULL;
11903
11904 picomm = bgp_attr_get_community(pi->attr);
11905
11906 count++;
11907 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11908 best = count;
11909 if (bgp_path_suppressed(pi))
11910 suppress = 1;
11911
11912 if (!picomm)
11913 continue;
11914
11915 no_advertise += community_include(
11916 picomm, COMMUNITY_NO_ADVERTISE);
11917 no_export +=
11918 community_include(picomm, COMMUNITY_NO_EXPORT);
11919 local_as +=
11920 community_include(picomm, COMMUNITY_LOCAL_AS);
11921 accept_own +=
11922 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11923 route_filter_translated_v4 += community_include(
11924 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11925 route_filter_translated_v6 += community_include(
11926 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11927 route_filter_v4 += community_include(
11928 picomm, COMMUNITY_ROUTE_FILTER_v4);
11929 route_filter_v6 += community_include(
11930 picomm, COMMUNITY_ROUTE_FILTER_v6);
11931 llgr_stale +=
11932 community_include(picomm, COMMUNITY_LLGR_STALE);
11933 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11934 accept_own_nexthop += community_include(
11935 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11936 blackhole +=
11937 community_include(picomm, COMMUNITY_BLACKHOLE);
11938 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11939 }
11940 }
11941
11942 if (!json) {
11943 vty_out(vty, "Paths: (%d available", count);
11944 if (best) {
11945 vty_out(vty, ", best #%d", best);
11946 if (safi == SAFI_UNICAST) {
11947 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11948 vty_out(vty, ", table %s",
11949 VRF_DEFAULT_NAME);
11950 else
11951 vty_out(vty, ", vrf %s",
11952 bgp->name);
11953 }
11954 } else
11955 vty_out(vty, ", no best path");
11956
11957 if (accept_own)
11958 vty_out(vty,
11959 ", accept own local route exported and imported in different VRF");
11960 else if (route_filter_translated_v4)
11961 vty_out(vty,
11962 ", mark translated RTs for VPNv4 route filtering");
11963 else if (route_filter_v4)
11964 vty_out(vty,
11965 ", attach RT as-is for VPNv4 route filtering");
11966 else if (route_filter_translated_v6)
11967 vty_out(vty,
11968 ", mark translated RTs for VPNv6 route filtering");
11969 else if (route_filter_v6)
11970 vty_out(vty,
11971 ", attach RT as-is for VPNv6 route filtering");
11972 else if (llgr_stale)
11973 vty_out(vty,
11974 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11975 else if (no_llgr)
11976 vty_out(vty,
11977 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11978 else if (accept_own_nexthop)
11979 vty_out(vty,
11980 ", accept local nexthop");
11981 else if (blackhole)
11982 vty_out(vty, ", inform peer to blackhole prefix");
11983 else if (no_export)
11984 vty_out(vty, ", not advertised to EBGP peer");
11985 else if (no_advertise)
11986 vty_out(vty, ", not advertised to any peer");
11987 else if (local_as)
11988 vty_out(vty, ", not advertised outside local AS");
11989 else if (no_peer)
11990 vty_out(vty,
11991 ", inform EBGP peer not to advertise to their EBGP peers");
11992
11993 if (suppress)
11994 vty_out(vty,
11995 ", Advertisements suppressed by an aggregate.");
11996 vty_out(vty, ")\n");
11997 }
11998
11999 /* If we are not using addpath then we can display Advertised to and
12000 * that will
12001 * show what peers we advertised the bestpath to. If we are using
12002 * addpath
12003 * though then we must display Advertised to on a path-by-path basis. */
12004 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
12005 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
12006 if (bgp_adj_out_lookup(peer, dest, 0)) {
12007 if (json && !json_adv_to)
12008 json_adv_to = json_object_new_object();
12009
12010 route_vty_out_advertised_to(
12011 vty, peer, &first,
12012 " Advertised to non peer-group peers:\n ",
12013 json_adv_to);
12014 }
12015 }
12016
12017 if (json && json_adv_to) {
12018 if (incremental_print) {
12019 vty_out(vty, "\"advertisedTo\": ");
12020 vty_json(vty, json_adv_to);
12021 vty_out(vty, ",");
12022 } else
12023 json_object_object_add(json, "advertisedTo",
12024 json_adv_to);
12025 } else {
12026 if (!json && first)
12027 vty_out(vty, " Not advertised to any peer");
12028 vty_out(vty, "\n");
12029 }
12030 }
12031 }
12032
12033 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
12034 struct bgp_dest *bgp_node, struct vty *vty,
12035 struct bgp *bgp, afi_t afi, safi_t safi,
12036 json_object *json, enum bgp_path_type pathtype,
12037 int *display, enum rpki_states rpki_target_state)
12038 {
12039 struct bgp_path_info *pi;
12040 int header = 1;
12041 json_object *json_header = NULL;
12042 json_object *json_paths = NULL;
12043 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
12044
12045 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
12046 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
12047
12048 if (p->family == AF_INET || p->family == AF_INET6)
12049 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
12050 pi->peer, pi->attr, p);
12051
12052 if (rpki_target_state != RPKI_NOT_BEING_USED
12053 && rpki_curr_state != rpki_target_state)
12054 continue;
12055
12056 if (json && !json_paths) {
12057 /* Instantiate json_paths only if path is valid */
12058 json_paths = json_object_new_array();
12059 if (pfx_rd)
12060 json_header = json_object_new_object();
12061 else
12062 json_header = json;
12063 }
12064
12065 if (header) {
12066 route_vty_out_detail_header(
12067 vty, bgp, bgp_node,
12068 bgp_dest_get_prefix(bgp_node), pfx_rd, AFI_IP,
12069 safi, json_header, false);
12070 header = 0;
12071 }
12072 (*display)++;
12073
12074 if (pathtype == BGP_PATH_SHOW_ALL
12075 || (pathtype == BGP_PATH_SHOW_BESTPATH
12076 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12077 || (pathtype == BGP_PATH_SHOW_MULTIPATH
12078 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
12079 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
12080 route_vty_out_detail(vty, bgp, bgp_node,
12081 bgp_dest_get_prefix(bgp_node), pi,
12082 AFI_IP, safi, rpki_curr_state,
12083 json_paths);
12084 }
12085
12086 if (json && json_paths) {
12087 json_object_object_add(json_header, "paths", json_paths);
12088
12089 if (pfx_rd)
12090 json_object_object_addf(
12091 json, json_header,
12092 BGP_RD_AS_FORMAT(bgp->asnotation), pfx_rd);
12093 }
12094 }
12095
12096 /*
12097 * Return rd based on safi
12098 */
12099 const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
12100 safi_t safi)
12101 {
12102 switch (safi) {
12103 case SAFI_MPLS_VPN:
12104 case SAFI_ENCAP:
12105 case SAFI_EVPN:
12106 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
12107 case SAFI_UNSPEC:
12108 case SAFI_UNICAST:
12109 case SAFI_MULTICAST:
12110 case SAFI_LABELED_UNICAST:
12111 case SAFI_FLOWSPEC:
12112 case SAFI_MAX:
12113 return NULL;
12114 }
12115
12116 assert(!"Reached end of function when we were not expecting it");
12117 }
12118
12119 /* Display specified route of BGP table. */
12120 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
12121 struct bgp_table *rib, const char *ip_str,
12122 afi_t afi, safi_t safi,
12123 enum rpki_states rpki_target_state,
12124 struct prefix_rd *prd, int prefix_check,
12125 enum bgp_path_type pathtype, bool use_json)
12126 {
12127 int ret;
12128 int display = 0;
12129 struct prefix match;
12130 struct bgp_dest *dest;
12131 struct bgp_dest *rm;
12132 struct bgp_table *table;
12133 json_object *json = NULL;
12134 json_object *json_paths = NULL;
12135
12136 /* Check IP address argument. */
12137 ret = str2prefix(ip_str, &match);
12138 if (!ret) {
12139 vty_out(vty, "address is malformed\n");
12140 return CMD_WARNING;
12141 }
12142
12143 match.family = afi2family(afi);
12144
12145 if (use_json)
12146 json = json_object_new_object();
12147
12148 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
12149 for (dest = bgp_table_top(rib); dest;
12150 dest = bgp_route_next(dest)) {
12151 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12152
12153 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
12154 continue;
12155 table = bgp_dest_get_bgp_table_info(dest);
12156 if (!table)
12157 continue;
12158
12159 rm = bgp_node_match(table, &match);
12160 if (rm == NULL)
12161 continue;
12162
12163 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
12164 if (prefix_check
12165 && rm_p->prefixlen != match.prefixlen) {
12166 bgp_dest_unlock_node(rm);
12167 continue;
12168 }
12169
12170 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12171 bgp, afi, safi, json, pathtype,
12172 &display, rpki_target_state);
12173
12174 bgp_dest_unlock_node(rm);
12175 }
12176 } else if (safi == SAFI_EVPN) {
12177 struct bgp_dest *longest_pfx;
12178 bool is_exact_pfxlen_match = false;
12179
12180 for (dest = bgp_table_top(rib); dest;
12181 dest = bgp_route_next(dest)) {
12182 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12183
12184 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
12185 continue;
12186 table = bgp_dest_get_bgp_table_info(dest);
12187 if (!table)
12188 continue;
12189
12190 longest_pfx = NULL;
12191 is_exact_pfxlen_match = false;
12192 /*
12193 * Search through all the prefixes for a match. The
12194 * pfx's are enumerated in ascending order of pfxlens.
12195 * So, the last pfx match is the longest match. Set
12196 * is_exact_pfxlen_match when we get exact pfxlen match
12197 */
12198 for (rm = bgp_table_top(table); rm;
12199 rm = bgp_route_next(rm)) {
12200 const struct prefix *rm_p =
12201 bgp_dest_get_prefix(rm);
12202 /*
12203 * Get prefixlen of the ip-prefix within type5
12204 * evpn route
12205 */
12206 if (evpn_type5_prefix_match(rm_p, &match)
12207 && rm->info) {
12208 longest_pfx = rm;
12209 int type5_pfxlen =
12210 bgp_evpn_get_type5_prefixlen(
12211 rm_p);
12212 if (type5_pfxlen == match.prefixlen) {
12213 is_exact_pfxlen_match = true;
12214 bgp_dest_unlock_node(rm);
12215 break;
12216 }
12217 }
12218 }
12219
12220 if (!longest_pfx)
12221 continue;
12222
12223 if (prefix_check && !is_exact_pfxlen_match)
12224 continue;
12225
12226 rm = longest_pfx;
12227 bgp_dest_lock_node(rm);
12228
12229 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
12230 bgp, afi, safi, json, pathtype,
12231 &display, rpki_target_state);
12232
12233 bgp_dest_unlock_node(rm);
12234 }
12235 } else if (safi == SAFI_FLOWSPEC) {
12236 if (use_json)
12237 json_paths = json_object_new_array();
12238
12239 display = bgp_flowspec_display_match_per_ip(afi, rib,
12240 &match, prefix_check,
12241 vty,
12242 use_json,
12243 json_paths);
12244 if (use_json) {
12245 if (display)
12246 json_object_object_add(json, "paths",
12247 json_paths);
12248 else
12249 json_object_free(json_paths);
12250 }
12251 } else {
12252 dest = bgp_node_match(rib, &match);
12253 if (dest != NULL) {
12254 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
12255 if (!prefix_check
12256 || dest_p->prefixlen == match.prefixlen) {
12257 bgp_show_path_info(NULL, dest, vty, bgp, afi,
12258 safi, json, pathtype,
12259 &display, rpki_target_state);
12260 }
12261
12262 bgp_dest_unlock_node(dest);
12263 }
12264 }
12265
12266 if (use_json) {
12267 vty_json(vty, json);
12268 } else {
12269 if (!display) {
12270 vty_out(vty, "%% Network not in table\n");
12271 return CMD_WARNING;
12272 }
12273 }
12274
12275 return CMD_SUCCESS;
12276 }
12277
12278 /* Display specified route of Main RIB */
12279 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
12280 afi_t afi, safi_t safi, struct prefix_rd *prd,
12281 int prefix_check, enum bgp_path_type pathtype,
12282 enum rpki_states rpki_target_state, bool use_json)
12283 {
12284 if (!bgp) {
12285 bgp = bgp_get_default();
12286 if (!bgp) {
12287 if (!use_json)
12288 vty_out(vty, "No BGP process is configured\n");
12289 else
12290 vty_out(vty, "{}\n");
12291 return CMD_WARNING;
12292 }
12293 }
12294
12295 /* labeled-unicast routes live in the unicast table */
12296 if (safi == SAFI_LABELED_UNICAST)
12297 safi = SAFI_UNICAST;
12298
12299 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
12300 afi, safi, rpki_target_state, prd,
12301 prefix_check, pathtype, use_json);
12302 }
12303
12304 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
12305 struct cmd_token **argv, bool exact, afi_t afi,
12306 safi_t safi, bool uj)
12307 {
12308 struct lcommunity *lcom;
12309 struct buffer *b;
12310 int i;
12311 char *str;
12312 int first = 0;
12313 uint16_t show_flags = 0;
12314 int ret;
12315
12316 if (uj)
12317 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12318
12319 b = buffer_new(1024);
12320 for (i = 0; i < argc; i++) {
12321 if (first)
12322 buffer_putc(b, ' ');
12323 else {
12324 if (strmatch(argv[i]->text, "AA:BB:CC")) {
12325 first = 1;
12326 buffer_putstr(b, argv[i]->arg);
12327 }
12328 }
12329 }
12330 buffer_putc(b, '\0');
12331
12332 str = buffer_getstr(b);
12333 buffer_free(b);
12334
12335 lcom = lcommunity_str2com(str);
12336 XFREE(MTYPE_TMP, str);
12337 if (!lcom) {
12338 vty_out(vty, "%% Large-community malformed\n");
12339 return CMD_WARNING;
12340 }
12341
12342 ret = bgp_show(vty, bgp, afi, safi,
12343 (exact ? bgp_show_type_lcommunity_exact
12344 : bgp_show_type_lcommunity),
12345 lcom, show_flags, RPKI_NOT_BEING_USED);
12346
12347 lcommunity_free(&lcom);
12348 return ret;
12349 }
12350
12351 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
12352 const char *lcom, bool exact, afi_t afi,
12353 safi_t safi, bool uj)
12354 {
12355 struct community_list *list;
12356 uint16_t show_flags = 0;
12357
12358 if (uj)
12359 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12360
12361
12362 list = community_list_lookup(bgp_clist, lcom, 0,
12363 LARGE_COMMUNITY_LIST_MASTER);
12364 if (list == NULL) {
12365 vty_out(vty, "%% %s is not a valid large-community-list name\n",
12366 lcom);
12367 return CMD_WARNING;
12368 }
12369
12370 return bgp_show(vty, bgp, afi, safi,
12371 (exact ? bgp_show_type_lcommunity_list_exact
12372 : bgp_show_type_lcommunity_list),
12373 list, show_flags, RPKI_NOT_BEING_USED);
12374 }
12375
12376 DEFUN (show_ip_bgp_large_community_list,
12377 show_ip_bgp_large_community_list_cmd,
12378 "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]",
12379 SHOW_STR
12380 IP_STR
12381 BGP_STR
12382 BGP_INSTANCE_HELP_STR
12383 BGP_AFI_HELP_STR
12384 BGP_SAFI_WITH_LABEL_HELP_STR
12385 "Display routes matching the large-community-list\n"
12386 "large-community-list number\n"
12387 "large-community-list name\n"
12388 "Exact match of the large-communities\n"
12389 JSON_STR)
12390 {
12391 afi_t afi = AFI_IP6;
12392 safi_t safi = SAFI_UNICAST;
12393 int idx = 0;
12394 bool exact_match = 0;
12395 struct bgp *bgp = NULL;
12396 bool uj = use_json(argc, argv);
12397
12398 if (uj)
12399 argc--;
12400
12401 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12402 &bgp, uj);
12403 if (!idx)
12404 return CMD_WARNING;
12405
12406 argv_find(argv, argc, "large-community-list", &idx);
12407
12408 const char *clist_number_or_name = argv[++idx]->arg;
12409
12410 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12411 exact_match = 1;
12412
12413 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
12414 exact_match, afi, safi, uj);
12415 }
12416 DEFUN (show_ip_bgp_large_community,
12417 show_ip_bgp_large_community_cmd,
12418 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
12419 SHOW_STR
12420 IP_STR
12421 BGP_STR
12422 BGP_INSTANCE_HELP_STR
12423 BGP_AFI_HELP_STR
12424 BGP_SAFI_WITH_LABEL_HELP_STR
12425 "Display routes matching the large-communities\n"
12426 "List of large-community numbers\n"
12427 "Exact match of the large-communities\n"
12428 JSON_STR)
12429 {
12430 afi_t afi = AFI_IP6;
12431 safi_t safi = SAFI_UNICAST;
12432 int idx = 0;
12433 bool exact_match = 0;
12434 struct bgp *bgp = NULL;
12435 bool uj = use_json(argc, argv);
12436 uint16_t show_flags = 0;
12437
12438 if (uj) {
12439 argc--;
12440 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12441 }
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 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12449 if (argv_find(argv, argc, "exact-match", &idx)) {
12450 argc--;
12451 exact_match = 1;
12452 }
12453 return bgp_show_lcommunity(vty, bgp, argc, argv,
12454 exact_match, afi, safi, uj);
12455 } else
12456 return bgp_show(vty, bgp, afi, safi,
12457 bgp_show_type_lcommunity_all, NULL, show_flags,
12458 RPKI_NOT_BEING_USED);
12459 }
12460
12461 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12462 safi_t safi, struct json_object *json_array);
12463 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12464 safi_t safi, struct json_object *json);
12465
12466
12467 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12468 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12469 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12470 "Display number of prefixes for all afi/safi\n" JSON_STR)
12471 {
12472 bool uj = use_json(argc, argv);
12473 struct bgp *bgp = NULL;
12474 safi_t safi = SAFI_UNICAST;
12475 afi_t afi = AFI_IP6;
12476 int idx = 0;
12477 struct json_object *json_all = NULL;
12478 struct json_object *json_afi_safi = NULL;
12479
12480 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12481 &bgp, false);
12482 if (!idx)
12483 return CMD_WARNING;
12484
12485 if (uj)
12486 json_all = json_object_new_object();
12487
12488 FOREACH_AFI_SAFI (afi, safi) {
12489 /*
12490 * So limit output to those afi/safi pairs that
12491 * actually have something interesting in them
12492 */
12493 if (strmatch(get_afi_safi_str(afi, safi, true),
12494 "Unknown")) {
12495 continue;
12496 }
12497 if (uj) {
12498 json_afi_safi = json_object_new_array();
12499 json_object_object_add(
12500 json_all,
12501 get_afi_safi_str(afi, safi, true),
12502 json_afi_safi);
12503 } else {
12504 json_afi_safi = NULL;
12505 }
12506
12507 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12508 }
12509
12510 if (uj)
12511 vty_json(vty, json_all);
12512
12513 return CMD_SUCCESS;
12514 }
12515
12516 /* BGP route print out function without JSON */
12517 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12518 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12519 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12520 SHOW_STR
12521 IP_STR
12522 BGP_STR
12523 BGP_INSTANCE_HELP_STR
12524 L2VPN_HELP_STR
12525 EVPN_HELP_STR
12526 "BGP RIB advertisement statistics\n"
12527 JSON_STR)
12528 {
12529 afi_t afi = AFI_IP6;
12530 safi_t safi = SAFI_UNICAST;
12531 struct bgp *bgp = NULL;
12532 int idx = 0, ret;
12533 bool uj = use_json(argc, argv);
12534 struct json_object *json_afi_safi = NULL, *json = NULL;
12535
12536 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12537 &bgp, false);
12538 if (!idx)
12539 return CMD_WARNING;
12540
12541 if (uj)
12542 json_afi_safi = json_object_new_array();
12543 else
12544 json_afi_safi = NULL;
12545
12546 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12547
12548 if (uj) {
12549 json = json_object_new_object();
12550 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12551 json_afi_safi);
12552 vty_json(vty, json);
12553 }
12554 return ret;
12555 }
12556
12557 /* BGP route print out function without JSON */
12558 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12559 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12560 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12561 "]]\
12562 statistics [json]",
12563 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12564 BGP_SAFI_WITH_LABEL_HELP_STR
12565 "BGP RIB advertisement statistics\n" JSON_STR)
12566 {
12567 afi_t afi = AFI_IP6;
12568 safi_t safi = SAFI_UNICAST;
12569 struct bgp *bgp = NULL;
12570 int idx = 0, ret;
12571 bool uj = use_json(argc, argv);
12572 struct json_object *json_afi_safi = NULL, *json = NULL;
12573
12574 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12575 &bgp, false);
12576 if (!idx)
12577 return CMD_WARNING;
12578
12579 if (uj)
12580 json_afi_safi = json_object_new_array();
12581 else
12582 json_afi_safi = NULL;
12583
12584 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12585
12586 if (uj) {
12587 json = json_object_new_object();
12588 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12589 json_afi_safi);
12590 vty_json(vty, json);
12591 }
12592 return ret;
12593 }
12594
12595 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12596 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12597 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12598 "]] [all$all] dampening parameters [json]",
12599 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12600 BGP_SAFI_WITH_LABEL_HELP_STR
12601 "Display the entries for all address families\n"
12602 "Display detailed information about dampening\n"
12603 "Display detail of configured dampening parameters\n"
12604 JSON_STR)
12605 {
12606 afi_t afi = AFI_IP6;
12607 safi_t safi = SAFI_UNICAST;
12608 struct bgp *bgp = NULL;
12609 int idx = 0;
12610 uint16_t show_flags = 0;
12611 bool uj = use_json(argc, argv);
12612
12613 if (uj) {
12614 argc--;
12615 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12616 }
12617
12618 /* [<ipv4|ipv6> [all]] */
12619 if (all) {
12620 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12621 if (argv_find(argv, argc, "ipv4", &idx))
12622 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12623
12624 if (argv_find(argv, argc, "ipv6", &idx))
12625 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12626 }
12627
12628 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12629 &bgp, false);
12630 if (!idx)
12631 return CMD_WARNING;
12632
12633 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12634 }
12635
12636 /* BGP route print out function */
12637 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12638 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12639 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12640 "]]\
12641 [all$all]\
12642 [cidr-only\
12643 |dampening <flap-statistics|dampened-paths>\
12644 |community [AA:NN|local-AS|no-advertise|no-export\
12645 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12646 |accept-own|accept-own-nexthop|route-filter-v6\
12647 |route-filter-v4|route-filter-translated-v6\
12648 |route-filter-translated-v4] [exact-match]\
12649 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12650 |filter-list AS_PATH_FILTER_NAME\
12651 |prefix-list WORD\
12652 |access-list ACCESSLIST_NAME\
12653 |route-map RMAP_NAME\
12654 |rpki <invalid|valid|notfound>\
12655 |version (1-4294967295)\
12656 |alias ALIAS_NAME\
12657 |A.B.C.D/M longer-prefixes\
12658 |X:X::X:X/M longer-prefixes\
12659 |"BGP_SELF_ORIG_CMD_STR"\
12660 |detail-routes$detail_routes\
12661 ] [json$uj [detail$detail_json] | wide$wide]",
12662 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12663 BGP_SAFI_WITH_LABEL_HELP_STR
12664 "Display the entries for all address families\n"
12665 "Display only routes with non-natural netmasks\n"
12666 "Display detailed information about dampening\n"
12667 "Display flap statistics of routes\n"
12668 "Display paths suppressed due to dampening\n"
12669 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12670 "Do not send outside local AS (well-known community)\n"
12671 "Do not advertise to any peer (well-known community)\n"
12672 "Do not export to next AS (well-known community)\n"
12673 "Graceful shutdown (well-known community)\n"
12674 "Do not export to any peer (well-known community)\n"
12675 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12676 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12677 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12678 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12679 "Should accept VPN route with local nexthop (well-known community)\n"
12680 "RT VPNv6 route filtering (well-known community)\n"
12681 "RT VPNv4 route filtering (well-known community)\n"
12682 "RT translated VPNv6 route filtering (well-known community)\n"
12683 "RT translated VPNv4 route filtering (well-known community)\n"
12684 "Exact match of the communities\n"
12685 "Community-list number\n"
12686 "Community-list name\n"
12687 "Display routes matching the community-list\n"
12688 "Exact match of the communities\n"
12689 "Display routes conforming to the filter-list\n"
12690 "Regular expression access list name\n"
12691 "Display routes conforming to the prefix-list\n"
12692 "Prefix-list name\n"
12693 "Display routes conforming to the access-list\n"
12694 "Access-list name\n"
12695 "Display routes matching the route-map\n"
12696 "A route-map to match on\n"
12697 "RPKI route types\n"
12698 "A valid path as determined by rpki\n"
12699 "A invalid path as determined by rpki\n"
12700 "A path that has no rpki data\n"
12701 "Display prefixes with matching version numbers\n"
12702 "Version number and above\n"
12703 "Display prefixes with matching BGP community alias\n"
12704 "BGP community alias\n"
12705 "IPv4 prefix\n"
12706 "Display route and more specific routes\n"
12707 "IPv6 prefix\n"
12708 "Display route and more specific routes\n"
12709 BGP_SELF_ORIG_HELP_STR
12710 "Display detailed version of all routes\n"
12711 JSON_STR
12712 "Display detailed version of JSON output\n"
12713 "Increase table width for longer prefixes\n")
12714 {
12715 afi_t afi = AFI_IP6;
12716 safi_t safi = SAFI_UNICAST;
12717 enum bgp_show_type sh_type = bgp_show_type_normal;
12718 void *output_arg = NULL;
12719 struct bgp *bgp = NULL;
12720 int idx = 0;
12721 int exact_match = 0;
12722 char *community = NULL;
12723 bool first = true;
12724 uint16_t show_flags = 0;
12725 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12726 struct prefix p;
12727
12728 if (uj) {
12729 argc--;
12730 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12731 }
12732
12733 if (detail_json)
12734 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
12735
12736 if (detail_routes)
12737 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
12738
12739 /* [<ipv4|ipv6> [all]] */
12740 if (all) {
12741 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12742
12743 if (argv_find(argv, argc, "ipv4", &idx))
12744 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12745
12746 if (argv_find(argv, argc, "ipv6", &idx))
12747 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12748 }
12749
12750 if (wide)
12751 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12752
12753 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12754 &bgp, uj);
12755 if (!idx)
12756 return CMD_WARNING;
12757
12758 if (argv_find(argv, argc, "cidr-only", &idx))
12759 sh_type = bgp_show_type_cidr_only;
12760
12761 if (argv_find(argv, argc, "dampening", &idx)) {
12762 if (argv_find(argv, argc, "dampened-paths", &idx))
12763 sh_type = bgp_show_type_dampend_paths;
12764 else if (argv_find(argv, argc, "flap-statistics", &idx))
12765 sh_type = bgp_show_type_flap_statistics;
12766 }
12767
12768 if (argv_find(argv, argc, "community", &idx)) {
12769 char *maybecomm = NULL;
12770
12771 if (idx + 1 < argc) {
12772 if (argv[idx + 1]->type == VARIABLE_TKN)
12773 maybecomm = argv[idx + 1]->arg;
12774 else
12775 maybecomm = argv[idx + 1]->text;
12776 }
12777
12778 if (maybecomm && !strmatch(maybecomm, "json")
12779 && !strmatch(maybecomm, "exact-match"))
12780 community = maybecomm;
12781
12782 if (argv_find(argv, argc, "exact-match", &idx))
12783 exact_match = 1;
12784
12785 if (!community)
12786 sh_type = bgp_show_type_community_all;
12787 }
12788
12789 if (argv_find(argv, argc, "community-list", &idx)) {
12790 const char *clist_number_or_name = argv[++idx]->arg;
12791 struct community_list *list;
12792
12793 if (argv_find(argv, argc, "exact-match", &idx))
12794 exact_match = 1;
12795
12796 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12797 COMMUNITY_LIST_MASTER);
12798 if (list == NULL) {
12799 vty_out(vty, "%% %s community-list not found\n",
12800 clist_number_or_name);
12801 return CMD_WARNING;
12802 }
12803
12804 if (exact_match)
12805 sh_type = bgp_show_type_community_list_exact;
12806 else
12807 sh_type = bgp_show_type_community_list;
12808 output_arg = list;
12809 }
12810
12811 if (argv_find(argv, argc, "filter-list", &idx)) {
12812 const char *filter = argv[++idx]->arg;
12813 struct as_list *as_list;
12814
12815 as_list = as_list_lookup(filter);
12816 if (as_list == NULL) {
12817 vty_out(vty, "%% %s AS-path access-list not found\n",
12818 filter);
12819 return CMD_WARNING;
12820 }
12821
12822 sh_type = bgp_show_type_filter_list;
12823 output_arg = as_list;
12824 }
12825
12826 if (argv_find(argv, argc, "prefix-list", &idx)) {
12827 const char *prefix_list_str = argv[++idx]->arg;
12828 struct prefix_list *plist;
12829
12830 plist = prefix_list_lookup(afi, prefix_list_str);
12831 if (plist == NULL) {
12832 vty_out(vty, "%% %s prefix-list not found\n",
12833 prefix_list_str);
12834 return CMD_WARNING;
12835 }
12836
12837 sh_type = bgp_show_type_prefix_list;
12838 output_arg = plist;
12839 }
12840
12841 if (argv_find(argv, argc, "access-list", &idx)) {
12842 const char *access_list_str = argv[++idx]->arg;
12843 struct access_list *alist;
12844
12845 alist = access_list_lookup(afi, access_list_str);
12846 if (!alist) {
12847 vty_out(vty, "%% %s access-list not found\n",
12848 access_list_str);
12849 return CMD_WARNING;
12850 }
12851
12852 sh_type = bgp_show_type_access_list;
12853 output_arg = alist;
12854 }
12855
12856 if (argv_find(argv, argc, "route-map", &idx)) {
12857 const char *rmap_str = argv[++idx]->arg;
12858 struct route_map *rmap;
12859
12860 rmap = route_map_lookup_by_name(rmap_str);
12861 if (!rmap) {
12862 vty_out(vty, "%% %s route-map not found\n", rmap_str);
12863 return CMD_WARNING;
12864 }
12865
12866 sh_type = bgp_show_type_route_map;
12867 output_arg = rmap;
12868 }
12869
12870 if (argv_find(argv, argc, "rpki", &idx)) {
12871 sh_type = bgp_show_type_rpki;
12872 if (argv_find(argv, argc, "valid", &idx))
12873 rpki_target_state = RPKI_VALID;
12874 else if (argv_find(argv, argc, "invalid", &idx))
12875 rpki_target_state = RPKI_INVALID;
12876 }
12877
12878 /* Display prefixes with matching version numbers */
12879 if (argv_find(argv, argc, "version", &idx)) {
12880 sh_type = bgp_show_type_prefix_version;
12881 output_arg = argv[idx + 1]->arg;
12882 }
12883
12884 /* Display prefixes with matching BGP community alias */
12885 if (argv_find(argv, argc, "alias", &idx)) {
12886 sh_type = bgp_show_type_community_alias;
12887 output_arg = argv[idx + 1]->arg;
12888 }
12889
12890 /* prefix-longer */
12891 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12892 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12893 const char *prefix_str = argv[idx]->arg;
12894
12895 if (!str2prefix(prefix_str, &p)) {
12896 vty_out(vty, "%% Malformed Prefix\n");
12897 return CMD_WARNING;
12898 }
12899
12900 sh_type = bgp_show_type_prefix_longer;
12901 output_arg = &p;
12902 }
12903
12904 /* self originated only */
12905 if (argv_find(argv, argc, BGP_SELF_ORIG_CMD_STR, &idx))
12906 sh_type = bgp_show_type_self_originated;
12907
12908 if (!all) {
12909 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12910 if (community)
12911 return bgp_show_community(vty, bgp, community,
12912 exact_match, afi, safi,
12913 show_flags);
12914 else
12915 return bgp_show(vty, bgp, afi, safi, sh_type,
12916 output_arg, show_flags,
12917 rpki_target_state);
12918 } else {
12919 struct listnode *node;
12920 struct bgp *abgp;
12921 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12922 * AFI_IP6 */
12923
12924 if (uj)
12925 vty_out(vty, "{\n");
12926
12927 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12928 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12929 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12930 ? AFI_IP
12931 : AFI_IP6;
12932 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12933 FOREACH_SAFI (safi) {
12934 if (!bgp_afi_safi_peer_exists(abgp, afi,
12935 safi))
12936 continue;
12937
12938 if (uj) {
12939 if (first)
12940 first = false;
12941 else
12942 vty_out(vty, ",\n");
12943 vty_out(vty, "\"%s\":{\n",
12944 get_afi_safi_str(afi,
12945 safi,
12946 true));
12947 } else
12948 vty_out(vty,
12949 "\nFor address family: %s\n",
12950 get_afi_safi_str(
12951 afi, safi,
12952 false));
12953
12954 if (community)
12955 bgp_show_community(
12956 vty, abgp, community,
12957 exact_match, afi, safi,
12958 show_flags);
12959 else
12960 bgp_show(vty, abgp, afi, safi,
12961 sh_type, output_arg,
12962 show_flags,
12963 rpki_target_state);
12964 if (uj)
12965 vty_out(vty, "}\n");
12966 }
12967 }
12968 } else {
12969 /* show <ip> bgp all: for each AFI and SAFI*/
12970 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12971 FOREACH_AFI_SAFI (afi, safi) {
12972 if (!bgp_afi_safi_peer_exists(abgp, afi,
12973 safi))
12974 continue;
12975
12976 if (uj) {
12977 if (first)
12978 first = false;
12979 else
12980 vty_out(vty, ",\n");
12981
12982 vty_out(vty, "\"%s\":{\n",
12983 get_afi_safi_str(afi,
12984 safi,
12985 true));
12986 } else
12987 vty_out(vty,
12988 "\nFor address family: %s\n",
12989 get_afi_safi_str(
12990 afi, safi,
12991 false));
12992
12993 if (community)
12994 bgp_show_community(
12995 vty, abgp, community,
12996 exact_match, afi, safi,
12997 show_flags);
12998 else
12999 bgp_show(vty, abgp, afi, safi,
13000 sh_type, output_arg,
13001 show_flags,
13002 rpki_target_state);
13003 if (uj)
13004 vty_out(vty, "}\n");
13005 }
13006 }
13007 }
13008 if (uj)
13009 vty_out(vty, "}\n");
13010 }
13011 return CMD_SUCCESS;
13012 }
13013
13014 DEFUN (show_ip_bgp_route,
13015 show_ip_bgp_route_cmd,
13016 "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]",
13017 SHOW_STR
13018 IP_STR
13019 BGP_STR
13020 BGP_INSTANCE_HELP_STR
13021 BGP_AFI_HELP_STR
13022 BGP_SAFI_WITH_LABEL_HELP_STR
13023 "Network in the BGP routing table to display\n"
13024 "IPv4 prefix\n"
13025 "Network in the BGP routing table to display\n"
13026 "IPv6 prefix\n"
13027 "Display only the bestpath\n"
13028 "Display only multipaths\n"
13029 "Display only paths that match the specified rpki state\n"
13030 "A valid path as determined by rpki\n"
13031 "A invalid path as determined by rpki\n"
13032 "A path that has no rpki data\n"
13033 JSON_STR)
13034 {
13035 int prefix_check = 0;
13036
13037 afi_t afi = AFI_IP6;
13038 safi_t safi = SAFI_UNICAST;
13039 char *prefix = NULL;
13040 struct bgp *bgp = NULL;
13041 enum bgp_path_type path_type;
13042 bool uj = use_json(argc, argv);
13043
13044 int idx = 0;
13045
13046 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13047 &bgp, uj);
13048 if (!idx)
13049 return CMD_WARNING;
13050
13051 if (!bgp) {
13052 vty_out(vty,
13053 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
13054 return CMD_WARNING;
13055 }
13056
13057 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
13058 if (argv_find(argv, argc, "A.B.C.D", &idx)
13059 || argv_find(argv, argc, "X:X::X:X", &idx))
13060 prefix_check = 0;
13061 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
13062 || argv_find(argv, argc, "X:X::X:X/M", &idx))
13063 prefix_check = 1;
13064
13065 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
13066 && afi != AFI_IP6) {
13067 vty_out(vty,
13068 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
13069 return CMD_WARNING;
13070 }
13071 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
13072 && afi != AFI_IP) {
13073 vty_out(vty,
13074 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
13075 return CMD_WARNING;
13076 }
13077
13078 prefix = argv[idx]->arg;
13079
13080 /* [<bestpath|multipath>] */
13081 if (argv_find(argv, argc, "bestpath", &idx))
13082 path_type = BGP_PATH_SHOW_BESTPATH;
13083 else if (argv_find(argv, argc, "multipath", &idx))
13084 path_type = BGP_PATH_SHOW_MULTIPATH;
13085 else
13086 path_type = BGP_PATH_SHOW_ALL;
13087
13088 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
13089 path_type, RPKI_NOT_BEING_USED, uj);
13090 }
13091
13092 DEFUN (show_ip_bgp_regexp,
13093 show_ip_bgp_regexp_cmd,
13094 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
13095 SHOW_STR
13096 IP_STR
13097 BGP_STR
13098 BGP_INSTANCE_HELP_STR
13099 BGP_AFI_HELP_STR
13100 BGP_SAFI_WITH_LABEL_HELP_STR
13101 "Display routes matching the AS path regular expression\n"
13102 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
13103 JSON_STR)
13104 {
13105 afi_t afi = AFI_IP6;
13106 safi_t safi = SAFI_UNICAST;
13107 struct bgp *bgp = NULL;
13108 bool uj = use_json(argc, argv);
13109 char *regstr = NULL;
13110
13111 int idx = 0;
13112 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13113 &bgp, false);
13114 if (!idx)
13115 return CMD_WARNING;
13116
13117 // get index of regex
13118 if (argv_find(argv, argc, "REGEX", &idx))
13119 regstr = argv[idx]->arg;
13120
13121 assert(regstr);
13122 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
13123 bgp_show_type_regexp, uj);
13124 }
13125
13126 DEFPY (show_ip_bgp_instance_all,
13127 show_ip_bgp_instance_all_cmd,
13128 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
13129 SHOW_STR
13130 IP_STR
13131 BGP_STR
13132 BGP_INSTANCE_ALL_HELP_STR
13133 BGP_AFI_HELP_STR
13134 BGP_SAFI_WITH_LABEL_HELP_STR
13135 JSON_STR
13136 "Increase table width for longer prefixes\n")
13137 {
13138 afi_t afi = AFI_IP6;
13139 safi_t safi = SAFI_UNICAST;
13140 struct bgp *bgp = NULL;
13141 int idx = 0;
13142 uint16_t show_flags = 0;
13143
13144 if (uj) {
13145 argc--;
13146 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13147 }
13148
13149 if (wide)
13150 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13151
13152 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13153 &bgp, uj);
13154 if (!idx)
13155 return CMD_WARNING;
13156
13157 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
13158 return CMD_SUCCESS;
13159 }
13160
13161 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
13162 afi_t afi, safi_t safi, enum bgp_show_type type,
13163 bool use_json)
13164 {
13165 regex_t *regex;
13166 int rc;
13167 uint16_t show_flags = 0;
13168
13169 if (use_json)
13170 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13171
13172 if (!config_bgp_aspath_validate(regstr)) {
13173 vty_out(vty, "Invalid character in REGEX %s\n",
13174 regstr);
13175 return CMD_WARNING_CONFIG_FAILED;
13176 }
13177
13178 regex = bgp_regcomp(regstr);
13179 if (!regex) {
13180 vty_out(vty, "Can't compile regexp %s\n", regstr);
13181 return CMD_WARNING;
13182 }
13183
13184 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
13185 RPKI_NOT_BEING_USED);
13186 bgp_regex_free(regex);
13187 return rc;
13188 }
13189
13190 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
13191 const char *comstr, int exact, afi_t afi,
13192 safi_t safi, uint16_t show_flags)
13193 {
13194 struct community *com;
13195 int ret = 0;
13196
13197 com = community_str2com(comstr);
13198 if (!com) {
13199 vty_out(vty, "%% Community malformed: %s\n", comstr);
13200 return CMD_WARNING;
13201 }
13202
13203 ret = bgp_show(vty, bgp, afi, safi,
13204 (exact ? bgp_show_type_community_exact
13205 : bgp_show_type_community),
13206 com, show_flags, RPKI_NOT_BEING_USED);
13207 community_free(&com);
13208
13209 return ret;
13210 }
13211
13212 enum bgp_stats {
13213 BGP_STATS_MAXBITLEN = 0,
13214 BGP_STATS_RIB,
13215 BGP_STATS_PREFIXES,
13216 BGP_STATS_TOTPLEN,
13217 BGP_STATS_UNAGGREGATEABLE,
13218 BGP_STATS_MAX_AGGREGATEABLE,
13219 BGP_STATS_AGGREGATES,
13220 BGP_STATS_SPACE,
13221 BGP_STATS_ASPATH_COUNT,
13222 BGP_STATS_ASPATH_MAXHOPS,
13223 BGP_STATS_ASPATH_TOTHOPS,
13224 BGP_STATS_ASPATH_MAXSIZE,
13225 BGP_STATS_ASPATH_TOTSIZE,
13226 BGP_STATS_ASN_HIGHEST,
13227 BGP_STATS_MAX,
13228 };
13229
13230 #define TABLE_STATS_IDX_VTY 0
13231 #define TABLE_STATS_IDX_JSON 1
13232
13233 static const char *table_stats_strs[][2] = {
13234 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
13235 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
13236 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
13237 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
13238 "unaggregateablePrefixes"},
13239 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
13240 "maximumAggregateablePrefixes"},
13241 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
13242 "bgpAggregateAdvertisements"},
13243 [BGP_STATS_SPACE] = {"Address space advertised",
13244 "addressSpaceAdvertised"},
13245 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
13246 "advertisementsWithPaths"},
13247 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
13248 "longestAsPath"},
13249 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
13250 "largestAsPath"},
13251 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
13252 "averageAsPathLengthHops"},
13253 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
13254 "averageAsPathSizeBytes"},
13255 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
13256 [BGP_STATS_MAX] = {NULL, NULL}
13257 };
13258
13259 struct bgp_table_stats {
13260 struct bgp_table *table;
13261 unsigned long long counts[BGP_STATS_MAX];
13262
13263 unsigned long long
13264 prefix_len_count[MAX(EVPN_ROUTE_PREFIXLEN, IPV6_MAX_BITLEN) +
13265 1];
13266
13267 double total_space;
13268 };
13269
13270 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
13271 struct bgp_table_stats *ts, unsigned int space)
13272 {
13273 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
13274 struct bgp_path_info *pi;
13275 const struct prefix *rn_p;
13276
13277 if (!bgp_dest_has_bgp_path_info_data(dest))
13278 return;
13279
13280 rn_p = bgp_dest_get_prefix(dest);
13281 ts->counts[BGP_STATS_PREFIXES]++;
13282 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
13283
13284 ts->prefix_len_count[rn_p->prefixlen]++;
13285 /* check if the prefix is included by any other announcements */
13286 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
13287 pdest = bgp_dest_parent_nolock(pdest);
13288
13289 if (pdest == NULL || pdest == top) {
13290 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
13291 /* announced address space */
13292 if (space)
13293 ts->total_space += pow(2.0, space - rn_p->prefixlen);
13294 } else if (bgp_dest_has_bgp_path_info_data(pdest))
13295 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
13296
13297
13298 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
13299 ts->counts[BGP_STATS_RIB]++;
13300
13301 if (CHECK_FLAG(pi->attr->flag,
13302 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
13303 ts->counts[BGP_STATS_AGGREGATES]++;
13304
13305 /* as-path stats */
13306 if (pi->attr->aspath) {
13307 unsigned int hops = aspath_count_hops(pi->attr->aspath);
13308 unsigned int size = aspath_size(pi->attr->aspath);
13309 as_t highest = aspath_highest(pi->attr->aspath);
13310
13311 ts->counts[BGP_STATS_ASPATH_COUNT]++;
13312
13313 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
13314 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
13315
13316 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
13317 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
13318
13319 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
13320 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
13321 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
13322 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
13323 }
13324 }
13325 }
13326
13327 static void bgp_table_stats_walker(struct event *t)
13328 {
13329 struct bgp_dest *dest, *ndest;
13330 struct bgp_dest *top;
13331 struct bgp_table_stats *ts = EVENT_ARG(t);
13332 unsigned int space = 0;
13333
13334 if (!(top = bgp_table_top(ts->table)))
13335 return;
13336
13337 switch (ts->table->afi) {
13338 case AFI_IP:
13339 space = IPV4_MAX_BITLEN;
13340 break;
13341 case AFI_IP6:
13342 space = IPV6_MAX_BITLEN;
13343 break;
13344 case AFI_L2VPN:
13345 space = EVPN_ROUTE_PREFIXLEN;
13346 break;
13347 case AFI_UNSPEC:
13348 case AFI_MAX:
13349 return;
13350 }
13351
13352 ts->counts[BGP_STATS_MAXBITLEN] = space;
13353
13354 for (dest = top; dest; dest = bgp_route_next(dest)) {
13355 if (ts->table->safi == SAFI_MPLS_VPN
13356 || ts->table->safi == SAFI_ENCAP
13357 || ts->table->safi == SAFI_EVPN) {
13358 struct bgp_table *table;
13359
13360 table = bgp_dest_get_bgp_table_info(dest);
13361 if (!table)
13362 continue;
13363
13364 top = bgp_table_top(table);
13365 for (ndest = bgp_table_top(table); ndest;
13366 ndest = bgp_route_next(ndest))
13367 bgp_table_stats_rn(ndest, top, ts, space);
13368 } else {
13369 bgp_table_stats_rn(dest, top, ts, space);
13370 }
13371 }
13372 }
13373
13374 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
13375 struct json_object *json_array)
13376 {
13377 struct listnode *node, *nnode;
13378 struct bgp *bgp;
13379
13380 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
13381 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13382 }
13383
13384 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
13385 safi_t safi, struct json_object *json_array)
13386 {
13387 struct bgp_table_stats ts;
13388 unsigned int i;
13389 int ret = CMD_SUCCESS;
13390 char temp_buf[20];
13391 struct json_object *json = NULL;
13392 uint32_t bitlen = 0;
13393 struct json_object *json_bitlen;
13394
13395 if (json_array)
13396 json = json_object_new_object();
13397
13398 if (!bgp->rib[afi][safi]) {
13399 char warning_msg[50];
13400
13401 snprintf(warning_msg, sizeof(warning_msg),
13402 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
13403 safi);
13404
13405 if (!json)
13406 vty_out(vty, "%s\n", warning_msg);
13407 else
13408 json_object_string_add(json, "warning", warning_msg);
13409
13410 ret = CMD_WARNING;
13411 goto end_table_stats;
13412 }
13413
13414 if (!json)
13415 vty_out(vty, "BGP %s RIB statistics (%s)\n",
13416 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
13417 else
13418 json_object_string_add(json, "instance", bgp->name_pretty);
13419
13420 /* labeled-unicast routes live in the unicast table */
13421 if (safi == SAFI_LABELED_UNICAST)
13422 safi = SAFI_UNICAST;
13423
13424 memset(&ts, 0, sizeof(ts));
13425 ts.table = bgp->rib[afi][safi];
13426 event_execute(bm->master, bgp_table_stats_walker, &ts, 0);
13427
13428 for (i = 0; i < BGP_STATS_MAX; i++) {
13429 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
13430 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
13431 continue;
13432
13433 switch (i) {
13434 case BGP_STATS_ASPATH_TOTHOPS:
13435 case BGP_STATS_ASPATH_TOTSIZE:
13436 if (!json) {
13437 snprintf(
13438 temp_buf, sizeof(temp_buf), "%12.2f",
13439 ts.counts[i]
13440 ? (float)ts.counts[i]
13441 / (float)ts.counts
13442 [BGP_STATS_ASPATH_COUNT]
13443 : 0);
13444 vty_out(vty, "%-30s: %s",
13445 table_stats_strs[i]
13446 [TABLE_STATS_IDX_VTY],
13447 temp_buf);
13448 } else {
13449 json_object_double_add(
13450 json,
13451 table_stats_strs[i]
13452 [TABLE_STATS_IDX_JSON],
13453 ts.counts[i]
13454 ? (double)ts.counts[i]
13455 / (double)ts.counts
13456 [BGP_STATS_ASPATH_COUNT]
13457 : 0);
13458 }
13459 break;
13460 case BGP_STATS_TOTPLEN:
13461 if (!json) {
13462 snprintf(
13463 temp_buf, sizeof(temp_buf), "%12.2f",
13464 ts.counts[i]
13465 ? (float)ts.counts[i]
13466 / (float)ts.counts
13467 [BGP_STATS_PREFIXES]
13468 : 0);
13469 vty_out(vty, "%-30s: %s",
13470 table_stats_strs[i]
13471 [TABLE_STATS_IDX_VTY],
13472 temp_buf);
13473 } else {
13474 json_object_double_add(
13475 json,
13476 table_stats_strs[i]
13477 [TABLE_STATS_IDX_JSON],
13478 ts.counts[i]
13479 ? (double)ts.counts[i]
13480 / (double)ts.counts
13481 [BGP_STATS_PREFIXES]
13482 : 0);
13483 }
13484 break;
13485 case BGP_STATS_SPACE:
13486 if (!json) {
13487 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13488 ts.total_space);
13489 vty_out(vty, "%-30s: %s\n",
13490 table_stats_strs[i]
13491 [TABLE_STATS_IDX_VTY],
13492 temp_buf);
13493 } else {
13494 json_object_double_add(
13495 json,
13496 table_stats_strs[i]
13497 [TABLE_STATS_IDX_JSON],
13498 (double)ts.total_space);
13499 }
13500 if (afi == AFI_IP6) {
13501 if (!json) {
13502 snprintf(temp_buf, sizeof(temp_buf),
13503 "%12g",
13504 ts.total_space
13505 * pow(2.0, -128 + 32));
13506 vty_out(vty, "%30s: %s\n",
13507 "/32 equivalent %s\n",
13508 temp_buf);
13509 } else {
13510 json_object_double_add(
13511 json, "/32equivalent",
13512 (double)(ts.total_space
13513 * pow(2.0,
13514 -128 + 32)));
13515 }
13516 if (!json) {
13517 snprintf(temp_buf, sizeof(temp_buf),
13518 "%12g",
13519 ts.total_space
13520 * pow(2.0, -128 + 48));
13521 vty_out(vty, "%30s: %s\n",
13522 "/48 equivalent %s\n",
13523 temp_buf);
13524 } else {
13525 json_object_double_add(
13526 json, "/48equivalent",
13527 (double)(ts.total_space
13528 * pow(2.0,
13529 -128 + 48)));
13530 }
13531 } else {
13532 if (!json) {
13533 snprintf(temp_buf, sizeof(temp_buf),
13534 "%12.2f",
13535 ts.total_space * 100.
13536 * pow(2.0, -32));
13537 vty_out(vty, "%30s: %s\n",
13538 "% announced ", temp_buf);
13539 } else {
13540 json_object_double_add(
13541 json, "%announced",
13542 (double)(ts.total_space * 100.
13543 * pow(2.0, -32)));
13544 }
13545 if (!json) {
13546 snprintf(temp_buf, sizeof(temp_buf),
13547 "%12.2f",
13548 ts.total_space
13549 * pow(2.0, -32 + 8));
13550 vty_out(vty, "%30s: %s\n",
13551 "/8 equivalent ", temp_buf);
13552 } else {
13553 json_object_double_add(
13554 json, "/8equivalent",
13555 (double)(ts.total_space
13556 * pow(2.0, -32 + 8)));
13557 }
13558 if (!json) {
13559 snprintf(temp_buf, sizeof(temp_buf),
13560 "%12.2f",
13561 ts.total_space
13562 * pow(2.0, -32 + 24));
13563 vty_out(vty, "%30s: %s\n",
13564 "/24 equivalent ", temp_buf);
13565 } else {
13566 json_object_double_add(
13567 json, "/24equivalent",
13568 (double)(ts.total_space
13569 * pow(2.0, -32 + 24)));
13570 }
13571 }
13572 break;
13573 default:
13574 if (!json) {
13575 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13576 ts.counts[i]);
13577 vty_out(vty, "%-30s: %s",
13578 table_stats_strs[i]
13579 [TABLE_STATS_IDX_VTY],
13580 temp_buf);
13581 } else {
13582 json_object_int_add(
13583 json,
13584 table_stats_strs[i]
13585 [TABLE_STATS_IDX_JSON],
13586 ts.counts[i]);
13587 }
13588 }
13589 if (!json)
13590 vty_out(vty, "\n");
13591 }
13592
13593 switch (afi) {
13594 case AFI_IP:
13595 bitlen = IPV4_MAX_BITLEN;
13596 break;
13597 case AFI_IP6:
13598 bitlen = IPV6_MAX_BITLEN;
13599 break;
13600 case AFI_L2VPN:
13601 bitlen = EVPN_ROUTE_PREFIXLEN;
13602 break;
13603 case AFI_UNSPEC:
13604 case AFI_MAX:
13605 break;
13606 }
13607
13608 if (json) {
13609 json_bitlen = json_object_new_array();
13610
13611 for (i = 0; i <= bitlen; i++) {
13612 struct json_object *ind_bit = json_object_new_object();
13613
13614 if (!ts.prefix_len_count[i])
13615 continue;
13616
13617 snprintf(temp_buf, sizeof(temp_buf), "%u", i);
13618 json_object_int_add(ind_bit, temp_buf,
13619 ts.prefix_len_count[i]);
13620 json_object_array_add(json_bitlen, ind_bit);
13621 }
13622 json_object_object_add(json, "prefixLength", json_bitlen);
13623 }
13624
13625 end_table_stats:
13626 if (json)
13627 json_object_array_add(json_array, json);
13628 return ret;
13629 }
13630
13631 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13632 safi_t safi, struct json_object *json_array)
13633 {
13634 if (!bgp) {
13635 bgp_table_stats_all(vty, afi, safi, json_array);
13636 return CMD_SUCCESS;
13637 }
13638
13639 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13640 }
13641
13642 enum bgp_pcounts {
13643 PCOUNT_ADJ_IN = 0,
13644 PCOUNT_DAMPED,
13645 PCOUNT_REMOVED,
13646 PCOUNT_HISTORY,
13647 PCOUNT_STALE,
13648 PCOUNT_VALID,
13649 PCOUNT_ALL,
13650 PCOUNT_COUNTED,
13651 PCOUNT_BPATH_SELECTED,
13652 PCOUNT_PFCNT, /* the figure we display to users */
13653 PCOUNT_MAX,
13654 };
13655
13656 static const char *const pcount_strs[] = {
13657 [PCOUNT_ADJ_IN] = "Adj-in",
13658 [PCOUNT_DAMPED] = "Damped",
13659 [PCOUNT_REMOVED] = "Removed",
13660 [PCOUNT_HISTORY] = "History",
13661 [PCOUNT_STALE] = "Stale",
13662 [PCOUNT_VALID] = "Valid",
13663 [PCOUNT_ALL] = "All RIB",
13664 [PCOUNT_COUNTED] = "PfxCt counted",
13665 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13666 [PCOUNT_PFCNT] = "Useable",
13667 [PCOUNT_MAX] = NULL,
13668 };
13669
13670 struct peer_pcounts {
13671 unsigned int count[PCOUNT_MAX];
13672 const struct peer *peer;
13673 const struct bgp_table *table;
13674 safi_t safi;
13675 };
13676
13677 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13678 {
13679 const struct bgp_adj_in *ain;
13680 const struct bgp_path_info *pi;
13681 const struct peer *peer = pc->peer;
13682
13683 for (ain = rn->adj_in; ain; ain = ain->next)
13684 if (ain->peer == peer)
13685 pc->count[PCOUNT_ADJ_IN]++;
13686
13687 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13688
13689 if (pi->peer != peer)
13690 continue;
13691
13692 pc->count[PCOUNT_ALL]++;
13693
13694 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13695 pc->count[PCOUNT_DAMPED]++;
13696 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13697 pc->count[PCOUNT_HISTORY]++;
13698 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13699 pc->count[PCOUNT_REMOVED]++;
13700 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13701 pc->count[PCOUNT_STALE]++;
13702 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13703 pc->count[PCOUNT_VALID]++;
13704 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13705 pc->count[PCOUNT_PFCNT]++;
13706 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13707 pc->count[PCOUNT_BPATH_SELECTED]++;
13708
13709 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13710 pc->count[PCOUNT_COUNTED]++;
13711 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13712 flog_err(
13713 EC_LIB_DEVELOPMENT,
13714 "Attempting to count but flags say it is unusable");
13715 } else {
13716 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13717 flog_err(
13718 EC_LIB_DEVELOPMENT,
13719 "Not counted but flags say we should");
13720 }
13721 }
13722 }
13723
13724 static void bgp_peer_count_walker(struct event *t)
13725 {
13726 struct bgp_dest *rn, *rm;
13727 const struct bgp_table *table;
13728 struct peer_pcounts *pc = EVENT_ARG(t);
13729
13730 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13731 || pc->safi == SAFI_EVPN) {
13732 /* Special handling for 2-level routing tables. */
13733 for (rn = bgp_table_top(pc->table); rn;
13734 rn = bgp_route_next(rn)) {
13735 table = bgp_dest_get_bgp_table_info(rn);
13736 if (table != NULL)
13737 for (rm = bgp_table_top(table); rm;
13738 rm = bgp_route_next(rm))
13739 bgp_peer_count_proc(rm, pc);
13740 }
13741 } else
13742 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13743 bgp_peer_count_proc(rn, pc);
13744 }
13745
13746 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13747 safi_t safi, bool use_json)
13748 {
13749 struct peer_pcounts pcounts = {.peer = peer};
13750 unsigned int i;
13751 json_object *json = NULL;
13752 json_object *json_loop = NULL;
13753
13754 if (use_json) {
13755 json = json_object_new_object();
13756 json_loop = json_object_new_object();
13757 }
13758
13759 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13760 || !peer->bgp->rib[afi][safi]) {
13761 if (use_json) {
13762 json_object_string_add(
13763 json, "warning",
13764 "No such neighbor or address family");
13765 vty_out(vty, "%s\n", json_object_to_json_string(json));
13766 json_object_free(json);
13767 json_object_free(json_loop);
13768 } else
13769 vty_out(vty, "%% No such neighbor or address family\n");
13770
13771 return CMD_WARNING;
13772 }
13773
13774 memset(&pcounts, 0, sizeof(pcounts));
13775 pcounts.peer = peer;
13776 pcounts.table = peer->bgp->rib[afi][safi];
13777 pcounts.safi = safi;
13778
13779 /* in-place call via thread subsystem so as to record execution time
13780 * stats for the thread-walk (i.e. ensure this can't be blamed on
13781 * on just vty_read()).
13782 */
13783 event_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13784
13785 if (use_json) {
13786 json_object_string_add(json, "prefixCountsFor", peer->host);
13787 json_object_string_add(json, "multiProtocol",
13788 get_afi_safi_str(afi, safi, true));
13789 json_object_int_add(json, "pfxCounter",
13790 peer->pcount[afi][safi]);
13791
13792 for (i = 0; i < PCOUNT_MAX; i++)
13793 json_object_int_add(json_loop, pcount_strs[i],
13794 pcounts.count[i]);
13795
13796 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13797
13798 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13799 json_object_string_add(json, "pfxctDriftFor",
13800 peer->host);
13801 json_object_string_add(
13802 json, "recommended",
13803 "Please report this bug, with the above command output");
13804 }
13805 vty_json(vty, json);
13806 } else {
13807
13808 if (peer->hostname
13809 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13810 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13811 peer->hostname, peer->host,
13812 get_afi_safi_str(afi, safi, false));
13813 } else {
13814 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13815 get_afi_safi_str(afi, safi, false));
13816 }
13817
13818 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13819 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13820
13821 for (i = 0; i < PCOUNT_MAX; i++)
13822 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13823 pcounts.count[i]);
13824
13825 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13826 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13827 vty_out(vty,
13828 "Please report this bug, with the above command output\n");
13829 }
13830 }
13831
13832 return CMD_SUCCESS;
13833 }
13834
13835 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13836 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13837 "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]",
13838 SHOW_STR
13839 IP_STR
13840 BGP_STR
13841 BGP_INSTANCE_HELP_STR
13842 BGP_AFI_HELP_STR
13843 BGP_SAFI_HELP_STR
13844 "Detailed information on TCP and BGP neighbor connections\n"
13845 "Neighbor to display information about\n"
13846 "Neighbor to display information about\n"
13847 "Neighbor on BGP configured interface\n"
13848 "Display detailed prefix count information\n"
13849 JSON_STR)
13850 {
13851 afi_t afi = AFI_IP6;
13852 safi_t safi = SAFI_UNICAST;
13853 struct peer *peer;
13854 int idx = 0;
13855 struct bgp *bgp = NULL;
13856 bool uj = use_json(argc, argv);
13857
13858 if (uj)
13859 argc--;
13860
13861 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13862 &bgp, uj);
13863 if (!idx)
13864 return CMD_WARNING;
13865
13866 argv_find(argv, argc, "neighbors", &idx);
13867 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13868 if (!peer)
13869 return CMD_WARNING;
13870
13871 return bgp_peer_counts(vty, peer, afi, safi, uj);
13872 }
13873
13874 #ifdef KEEP_OLD_VPN_COMMANDS
13875 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13876 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13877 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13878 SHOW_STR
13879 IP_STR
13880 BGP_STR
13881 BGP_VPNVX_HELP_STR
13882 "Display information about all VPNv4 NLRIs\n"
13883 "Detailed information on TCP and BGP neighbor connections\n"
13884 "Neighbor to display information about\n"
13885 "Neighbor to display information about\n"
13886 "Neighbor on BGP configured interface\n"
13887 "Display detailed prefix count information\n"
13888 JSON_STR)
13889 {
13890 int idx_peer = 6;
13891 struct peer *peer;
13892 bool uj = use_json(argc, argv);
13893
13894 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13895 if (!peer)
13896 return CMD_WARNING;
13897
13898 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13899 }
13900
13901 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13902 show_ip_bgp_vpn_all_route_prefix_cmd,
13903 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13904 SHOW_STR
13905 IP_STR
13906 BGP_STR
13907 BGP_VPNVX_HELP_STR
13908 "Display information about all VPNv4 NLRIs\n"
13909 "Network in the BGP routing table to display\n"
13910 "Network in the BGP routing table to display\n"
13911 JSON_STR)
13912 {
13913 int idx = 0;
13914 char *network = NULL;
13915 struct bgp *bgp = bgp_get_default();
13916 if (!bgp) {
13917 vty_out(vty, "Can't find default instance\n");
13918 return CMD_WARNING;
13919 }
13920
13921 if (argv_find(argv, argc, "A.B.C.D", &idx))
13922 network = argv[idx]->arg;
13923 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13924 network = argv[idx]->arg;
13925 else {
13926 vty_out(vty, "Unable to figure out Network\n");
13927 return CMD_WARNING;
13928 }
13929
13930 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13931 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13932 use_json(argc, argv));
13933 }
13934 #endif /* KEEP_OLD_VPN_COMMANDS */
13935
13936 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13937 show_bgp_l2vpn_evpn_route_prefix_cmd,
13938 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13939 SHOW_STR
13940 BGP_STR
13941 L2VPN_HELP_STR
13942 EVPN_HELP_STR
13943 "Network in the BGP routing table to display\n"
13944 "Network in the BGP routing table to display\n"
13945 "Network in the BGP routing table to display\n"
13946 "Network in the BGP routing table to display\n"
13947 JSON_STR)
13948 {
13949 int idx = 0;
13950 char *network = NULL;
13951 int prefix_check = 0;
13952
13953 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13954 argv_find(argv, argc, "X:X::X:X", &idx))
13955 network = argv[idx]->arg;
13956 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13957 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13958 network = argv[idx]->arg;
13959 prefix_check = 1;
13960 } else {
13961 vty_out(vty, "Unable to figure out Network\n");
13962 return CMD_WARNING;
13963 }
13964 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13965 prefix_check, BGP_PATH_SHOW_ALL,
13966 RPKI_NOT_BEING_USED, use_json(argc, argv));
13967 }
13968
13969 static void show_adj_route_header(struct vty *vty, struct peer *peer,
13970 struct bgp_table *table, int *header1,
13971 int *header2, json_object *json,
13972 json_object *json_scode,
13973 json_object *json_ocode, bool wide,
13974 bool detail)
13975 {
13976 uint64_t version = table ? table->version : 0;
13977
13978 if (*header1) {
13979 if (json) {
13980 json_object_int_add(json, "bgpTableVersion", version);
13981 json_object_string_addf(json, "bgpLocalRouterId",
13982 "%pI4", &peer->bgp->router_id);
13983 json_object_int_add(json, "defaultLocPrf",
13984 peer->bgp->default_local_pref);
13985 json_object_int_add(json, "localAS",
13986 peer->change_local_as
13987 ? peer->change_local_as
13988 : peer->local_as);
13989 json_object_object_add(json, "bgpStatusCodes",
13990 json_scode);
13991 json_object_object_add(json, "bgpOriginCodes",
13992 json_ocode);
13993 } else {
13994 vty_out(vty,
13995 "BGP table version is %" PRIu64
13996 ", local router ID is %pI4, vrf id ",
13997 version, &peer->bgp->router_id);
13998 if (peer->bgp->vrf_id == VRF_UNKNOWN)
13999 vty_out(vty, "%s", VRFID_NONE_STR);
14000 else
14001 vty_out(vty, "%u", peer->bgp->vrf_id);
14002 vty_out(vty, "\n");
14003 vty_out(vty, "Default local pref %u, ",
14004 peer->bgp->default_local_pref);
14005 vty_out(vty, "local AS %u\n",
14006 peer->change_local_as ? peer->change_local_as
14007 : peer->local_as);
14008 if (!detail) {
14009 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14010 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14011 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14012 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14013 }
14014 }
14015 *header1 = 0;
14016 }
14017 if (*header2) {
14018 if (!json && !detail)
14019 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
14020 : BGP_SHOW_HEADER));
14021 *header2 = 0;
14022 }
14023 }
14024
14025 static void
14026 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
14027 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
14028 const char *rmap_name, json_object *json, json_object *json_ar,
14029 json_object *json_scode, json_object *json_ocode,
14030 uint16_t show_flags, int *header1, int *header2, char *rd_str,
14031 const struct prefix *match, unsigned long *output_count,
14032 unsigned long *filtered_count)
14033 {
14034 struct bgp_adj_in *ain = NULL;
14035 struct bgp_adj_out *adj = NULL;
14036 struct bgp_dest *dest;
14037 struct bgp *bgp;
14038 struct attr attr;
14039 int ret;
14040 struct update_subgroup *subgrp;
14041 struct peer_af *paf = NULL;
14042 bool route_filtered;
14043 bool detail = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14044 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14045 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14046 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14047 || (safi == SAFI_EVPN))
14048 ? true
14049 : false;
14050 int display = 0;
14051 json_object *json_net = NULL;
14052
14053 bgp = peer->bgp;
14054
14055 /* If the user supplied a prefix, look for a matching route instead
14056 * of walking the whole table.
14057 */
14058 if (match) {
14059 dest = bgp_node_match(table, match);
14060 if (!dest) {
14061 if (!use_json)
14062 vty_out(vty, "Network not in table\n");
14063 return;
14064 }
14065
14066 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14067
14068 if (rn_p->prefixlen != match->prefixlen) {
14069 if (!use_json)
14070 vty_out(vty, "Network not in table\n");
14071 bgp_dest_unlock_node(dest);
14072 return;
14073 }
14074
14075 if (type == bgp_show_adj_route_received ||
14076 type == bgp_show_adj_route_filtered) {
14077 for (ain = dest->adj_in; ain; ain = ain->next) {
14078 if (ain->peer == peer) {
14079 attr = *ain->attr;
14080 break;
14081 }
14082 }
14083 /* bail out if if adj_out is empty, or
14084 * if the prefix isn't in this peer's
14085 * adj_in
14086 */
14087 if (!ain || ain->peer != peer) {
14088 if (!use_json)
14089 vty_out(vty, "Network not in table\n");
14090 bgp_dest_unlock_node(dest);
14091 return;
14092 }
14093 } else if (type == bgp_show_adj_route_advertised) {
14094 bool peer_found = false;
14095
14096 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out) {
14097 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14098 if (paf->peer == peer && adj->attr) {
14099 attr = *adj->attr;
14100 peer_found = true;
14101 break;
14102 }
14103 }
14104 if (peer_found)
14105 break;
14106 }
14107 /* bail out if if adj_out is empty, or
14108 * if the prefix isn't in this peer's
14109 * adj_out
14110 */
14111 if (!paf || !peer_found) {
14112 if (!use_json)
14113 vty_out(vty, "Network not in table\n");
14114 bgp_dest_unlock_node(dest);
14115 return;
14116 }
14117 }
14118
14119 ret = bgp_output_modifier(peer, rn_p, &attr, afi, safi,
14120 rmap_name);
14121
14122 if (ret != RMAP_DENY) {
14123 show_adj_route_header(vty, peer, table, header1,
14124 header2, json, json_scode,
14125 json_ocode, wide, detail);
14126
14127 if (use_json)
14128 json_net = json_object_new_object();
14129
14130 bgp_show_path_info(NULL /* prefix_rd */, dest, vty, bgp,
14131 afi, safi, json_net,
14132 BGP_PATH_SHOW_ALL, &display,
14133 RPKI_NOT_BEING_USED);
14134 if (use_json)
14135 json_object_object_addf(json_ar, json_net,
14136 "%pFX", rn_p);
14137 (*output_count)++;
14138 } else
14139 (*filtered_count)++;
14140
14141 bgp_attr_flush(&attr);
14142 bgp_dest_unlock_node(dest);
14143 return;
14144 }
14145
14146
14147 subgrp = peer_subgroup(peer, afi, safi);
14148
14149 if (type == bgp_show_adj_route_advertised && subgrp
14150 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
14151 if (use_json) {
14152 json_object_int_add(json, "bgpTableVersion",
14153 table->version);
14154 json_object_string_addf(json, "bgpLocalRouterId",
14155 "%pI4", &bgp->router_id);
14156 json_object_int_add(json, "defaultLocPrf",
14157 bgp->default_local_pref);
14158 json_object_int_add(json, "localAS",
14159 peer->change_local_as
14160 ? peer->change_local_as
14161 : peer->local_as);
14162 json_object_object_add(json, "bgpStatusCodes",
14163 json_scode);
14164 json_object_object_add(json, "bgpOriginCodes",
14165 json_ocode);
14166 json_object_string_add(
14167 json, "bgpOriginatingDefaultNetwork",
14168 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14169 } else {
14170 vty_out(vty,
14171 "BGP table version is %" PRIu64
14172 ", local router ID is %pI4, vrf id ",
14173 table->version, &bgp->router_id);
14174 if (bgp->vrf_id == VRF_UNKNOWN)
14175 vty_out(vty, "%s", VRFID_NONE_STR);
14176 else
14177 vty_out(vty, "%u", bgp->vrf_id);
14178 vty_out(vty, "\n");
14179 vty_out(vty, "Default local pref %u, ",
14180 bgp->default_local_pref);
14181 vty_out(vty, "local AS %u\n",
14182 peer->change_local_as ? peer->change_local_as
14183 : peer->local_as);
14184 if (!detail) {
14185 vty_out(vty, BGP_SHOW_SCODE_HEADER);
14186 vty_out(vty, BGP_SHOW_NCODE_HEADER);
14187 vty_out(vty, BGP_SHOW_OCODE_HEADER);
14188 vty_out(vty, BGP_SHOW_RPKI_HEADER);
14189 }
14190
14191 vty_out(vty, "Originating default network %s\n\n",
14192 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
14193 }
14194 (*output_count)++;
14195 *header1 = 0;
14196 }
14197
14198 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
14199 if (type == bgp_show_adj_route_received
14200 || type == bgp_show_adj_route_filtered) {
14201 for (ain = dest->adj_in; ain; ain = ain->next) {
14202 if (ain->peer != peer)
14203 continue;
14204
14205 show_adj_route_header(vty, peer, table, header1,
14206 header2, json, json_scode,
14207 json_ocode, wide, detail);
14208
14209 if ((safi == SAFI_MPLS_VPN)
14210 || (safi == SAFI_ENCAP)
14211 || (safi == SAFI_EVPN)) {
14212 if (use_json)
14213 json_object_string_add(
14214 json_ar, "rd", rd_str);
14215 else if (show_rd && rd_str) {
14216 vty_out(vty,
14217 "Route Distinguisher: %s\n",
14218 rd_str);
14219 show_rd = false;
14220 }
14221 }
14222
14223 attr = *ain->attr;
14224 route_filtered = false;
14225
14226 /* Filter prefix using distribute list,
14227 * filter list or prefix list
14228 */
14229 const struct prefix *rn_p =
14230 bgp_dest_get_prefix(dest);
14231 if ((bgp_input_filter(peer, rn_p, &attr, afi,
14232 safi))
14233 == FILTER_DENY)
14234 route_filtered = true;
14235
14236 /* Filter prefix using route-map */
14237 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
14238 safi, rmap_name, NULL,
14239 0, NULL);
14240
14241 if (type == bgp_show_adj_route_filtered &&
14242 !route_filtered && ret != RMAP_DENY) {
14243 bgp_attr_flush(&attr);
14244 continue;
14245 }
14246
14247 if (type == bgp_show_adj_route_received
14248 && (route_filtered || ret == RMAP_DENY))
14249 (*filtered_count)++;
14250
14251 if (detail) {
14252 if (use_json)
14253 json_net =
14254 json_object_new_object();
14255 bgp_show_path_info(
14256 NULL /* prefix_rd */, dest, vty,
14257 bgp, afi, safi, json_net,
14258 BGP_PATH_SHOW_ALL, &display,
14259 RPKI_NOT_BEING_USED);
14260 if (use_json)
14261 json_object_object_addf(
14262 json_ar, json_net,
14263 "%pFX", rn_p);
14264 } else
14265 route_vty_out_tmp(vty, dest, rn_p,
14266 &attr, safi, use_json,
14267 json_ar, wide);
14268 bgp_attr_flush(&attr);
14269 (*output_count)++;
14270 }
14271 } else if (type == bgp_show_adj_route_advertised) {
14272 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
14273 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
14274 if (paf->peer != peer || !adj->attr)
14275 continue;
14276
14277 show_adj_route_header(
14278 vty, peer, table, header1,
14279 header2, json, json_scode,
14280 json_ocode, wide, detail);
14281
14282 const struct prefix *rn_p =
14283 bgp_dest_get_prefix(dest);
14284
14285 attr = *adj->attr;
14286 ret = bgp_output_modifier(
14287 peer, rn_p, &attr, afi, safi,
14288 rmap_name);
14289
14290 if (ret != RMAP_DENY) {
14291 if ((safi == SAFI_MPLS_VPN)
14292 || (safi == SAFI_ENCAP)
14293 || (safi == SAFI_EVPN)) {
14294 if (use_json)
14295 json_object_string_add(
14296 json_ar,
14297 "rd",
14298 rd_str);
14299 else if (show_rd
14300 && rd_str) {
14301 vty_out(vty,
14302 "Route Distinguisher: %s\n",
14303 rd_str);
14304 show_rd = false;
14305 }
14306 }
14307 if (detail) {
14308 if (use_json)
14309 json_net =
14310 json_object_new_object();
14311 bgp_show_path_info(
14312 NULL /* prefix_rd
14313 */
14314 ,
14315 dest, vty, bgp,
14316 afi, safi,
14317 json_net,
14318 BGP_PATH_SHOW_ALL,
14319 &display,
14320 RPKI_NOT_BEING_USED);
14321 if (use_json)
14322 json_object_object_addf(
14323 json_ar,
14324 json_net,
14325 "%pFX",
14326 rn_p);
14327 } else
14328 route_vty_out_tmp(
14329 vty, dest, rn_p,
14330 &attr, safi,
14331 use_json,
14332 json_ar, wide);
14333 (*output_count)++;
14334 } else {
14335 (*filtered_count)++;
14336 }
14337
14338 bgp_attr_flush(&attr);
14339 }
14340 } else if (type == bgp_show_adj_route_bestpath) {
14341 struct bgp_path_info *pi;
14342
14343 show_adj_route_header(vty, peer, table, header1,
14344 header2, json, json_scode,
14345 json_ocode, wide, detail);
14346
14347 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
14348
14349 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
14350 pi = pi->next) {
14351 if (pi->peer != peer)
14352 continue;
14353
14354 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
14355 continue;
14356
14357 if (detail) {
14358 if (use_json)
14359 json_net =
14360 json_object_new_object();
14361 bgp_show_path_info(
14362 NULL /* prefix_rd */, dest, vty,
14363 bgp, afi, safi, json_net,
14364 BGP_PATH_SHOW_BESTPATH,
14365 &display, RPKI_NOT_BEING_USED);
14366 if (use_json)
14367 json_object_object_addf(
14368 json_ar, json_net,
14369 "%pFX", rn_p);
14370 } else
14371 route_vty_out_tmp(
14372 vty, dest, rn_p, pi->attr, safi,
14373 use_json, json_ar, wide);
14374 (*output_count)++;
14375 }
14376 }
14377 }
14378 }
14379
14380 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
14381 safi_t safi, enum bgp_show_adj_route_type type,
14382 const char *rmap_name, const struct prefix *match,
14383 uint16_t show_flags)
14384 {
14385 struct bgp *bgp;
14386 struct bgp_table *table;
14387 json_object *json = NULL;
14388 json_object *json_scode = NULL;
14389 json_object *json_ocode = NULL;
14390 json_object *json_ar = NULL;
14391 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14392
14393 /* Init BGP headers here so they're only displayed once
14394 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
14395 */
14396 int header1 = 1;
14397 int header2 = 1;
14398
14399 /*
14400 * Initialize variables for each RD
14401 * All prefixes under an RD is aggregated within "json_routes"
14402 */
14403 char rd_str[BUFSIZ] = {0};
14404 json_object *json_routes = NULL;
14405
14406
14407 /* For 2-tier tables, prefix counts need to be
14408 * maintained across multiple runs of show_adj_route()
14409 */
14410 unsigned long output_count_per_rd;
14411 unsigned long filtered_count_per_rd;
14412 unsigned long output_count = 0;
14413 unsigned long filtered_count = 0;
14414
14415 if (use_json) {
14416 json = json_object_new_object();
14417 json_ar = json_object_new_object();
14418 json_scode = json_object_new_object();
14419 json_ocode = json_object_new_object();
14420 #if CONFDATE > 20231208
14421 CPP_NOTICE("Drop `bgpStatusCodes` from JSON outputs")
14422 #endif
14423 json_object_string_add(json_scode, "suppressed", "s");
14424 json_object_string_add(json_scode, "damped", "d");
14425 json_object_string_add(json_scode, "history", "h");
14426 json_object_string_add(json_scode, "valid", "*");
14427 json_object_string_add(json_scode, "best", ">");
14428 json_object_string_add(json_scode, "multipath", "=");
14429 json_object_string_add(json_scode, "internal", "i");
14430 json_object_string_add(json_scode, "ribFailure", "r");
14431 json_object_string_add(json_scode, "stale", "S");
14432 json_object_string_add(json_scode, "removed", "R");
14433
14434 #if CONFDATE > 20231208
14435 CPP_NOTICE("Drop `bgpOriginCodes` from JSON outputs")
14436 #endif
14437 json_object_string_add(json_ocode, "igp", "i");
14438 json_object_string_add(json_ocode, "egp", "e");
14439 json_object_string_add(json_ocode, "incomplete", "?");
14440 }
14441
14442 if (!peer || !peer->afc[afi][safi]) {
14443 if (use_json) {
14444 json_object_string_add(
14445 json, "warning",
14446 "No such neighbor or address family");
14447 vty_out(vty, "%s\n", json_object_to_json_string(json));
14448 json_object_free(json);
14449 json_object_free(json_ar);
14450 json_object_free(json_scode);
14451 json_object_free(json_ocode);
14452 } else
14453 vty_out(vty, "%% No such neighbor or address family\n");
14454
14455 return CMD_WARNING;
14456 }
14457
14458 if ((type == bgp_show_adj_route_received
14459 || type == bgp_show_adj_route_filtered)
14460 && !CHECK_FLAG(peer->af_flags[afi][safi],
14461 PEER_FLAG_SOFT_RECONFIG)) {
14462 if (use_json) {
14463 json_object_string_add(
14464 json, "warning",
14465 "Inbound soft reconfiguration not enabled");
14466 vty_out(vty, "%s\n", json_object_to_json_string(json));
14467 json_object_free(json);
14468 json_object_free(json_ar);
14469 json_object_free(json_scode);
14470 json_object_free(json_ocode);
14471 } else
14472 vty_out(vty,
14473 "%% Inbound soft reconfiguration not enabled\n");
14474
14475 return CMD_WARNING;
14476 }
14477
14478 bgp = peer->bgp;
14479
14480 /* labeled-unicast routes live in the unicast table */
14481 if (safi == SAFI_LABELED_UNICAST)
14482 table = bgp->rib[afi][SAFI_UNICAST];
14483 else
14484 table = bgp->rib[afi][safi];
14485
14486 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14487 || (safi == SAFI_EVPN)) {
14488
14489 struct bgp_dest *dest;
14490
14491 for (dest = bgp_table_top(table); dest;
14492 dest = bgp_route_next(dest)) {
14493 table = bgp_dest_get_bgp_table_info(dest);
14494 if (!table)
14495 continue;
14496
14497 output_count_per_rd = 0;
14498 filtered_count_per_rd = 0;
14499
14500 if (use_json)
14501 json_routes = json_object_new_object();
14502
14503 const struct prefix_rd *prd;
14504 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14505 dest);
14506
14507 prefix_rd2str(prd, rd_str, sizeof(rd_str),
14508 bgp->asnotation);
14509
14510 show_adj_route(
14511 vty, peer, table, afi, safi, type, rmap_name,
14512 json, json_routes, json_scode, json_ocode,
14513 show_flags, &header1, &header2, rd_str, match,
14514 &output_count_per_rd, &filtered_count_per_rd);
14515
14516 /* Don't include an empty RD in the output! */
14517 if (json_routes && (output_count_per_rd > 0))
14518 json_object_object_add(json_ar, rd_str,
14519 json_routes);
14520
14521 output_count += output_count_per_rd;
14522 filtered_count += filtered_count_per_rd;
14523 }
14524 } else
14525 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
14526 json, json_ar, json_scode, json_ocode,
14527 show_flags, &header1, &header2, rd_str, match,
14528 &output_count, &filtered_count);
14529
14530 if (use_json) {
14531 if (type == bgp_show_adj_route_advertised)
14532 json_object_object_add(json, "advertisedRoutes",
14533 json_ar);
14534 else
14535 json_object_object_add(json, "receivedRoutes", json_ar);
14536 json_object_int_add(json, "totalPrefixCounter", output_count);
14537 json_object_int_add(json, "filteredPrefixCounter",
14538 filtered_count);
14539
14540 /*
14541 * These fields only give up ownership to `json` when `header1`
14542 * is used (set to zero). See code in `show_adj_route` and
14543 * `show_adj_route_header`.
14544 */
14545 if (header1 == 1) {
14546 json_object_free(json_scode);
14547 json_object_free(json_ocode);
14548 }
14549
14550 vty_json(vty, json);
14551 } else if (output_count > 0) {
14552 if (!match && filtered_count > 0)
14553 vty_out(vty,
14554 "\nTotal number of prefixes %ld (%ld filtered)\n",
14555 output_count, filtered_count);
14556 else
14557 vty_out(vty, "\nTotal number of prefixes %ld\n",
14558 output_count);
14559 }
14560
14561 return CMD_SUCCESS;
14562 }
14563
14564 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
14565 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
14566 "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]",
14567 SHOW_STR
14568 IP_STR
14569 BGP_STR
14570 BGP_INSTANCE_HELP_STR
14571 BGP_AFI_HELP_STR
14572 BGP_SAFI_WITH_LABEL_HELP_STR
14573 "Detailed information on TCP and BGP neighbor connections\n"
14574 "Neighbor to display information about\n"
14575 "Neighbor to display information about\n"
14576 "Neighbor on BGP configured interface\n"
14577 "Display the routes selected by best path\n"
14578 "Display detailed version of routes\n"
14579 JSON_STR
14580 "Increase table width for longer prefixes\n")
14581 {
14582 afi_t afi = AFI_IP6;
14583 safi_t safi = SAFI_UNICAST;
14584 char *rmap_name = NULL;
14585 char *peerstr = NULL;
14586 struct bgp *bgp = NULL;
14587 struct peer *peer;
14588 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
14589 int idx = 0;
14590 uint16_t show_flags = 0;
14591
14592 if (detail)
14593 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14594
14595 if (uj)
14596 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14597
14598 if (wide)
14599 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14600
14601 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14602 &bgp, uj);
14603
14604 if (!idx)
14605 return CMD_WARNING;
14606
14607 argv_find(argv, argc, "neighbors", &idx);
14608 peerstr = argv[++idx]->arg;
14609
14610 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14611 if (!peer)
14612 return CMD_WARNING;
14613
14614 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name, NULL,
14615 show_flags);
14616 }
14617
14618 DEFPY(show_ip_bgp_instance_neighbor_advertised_route,
14619 show_ip_bgp_instance_neighbor_advertised_route_cmd,
14620 "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]",
14621 SHOW_STR
14622 IP_STR
14623 BGP_STR
14624 BGP_INSTANCE_HELP_STR
14625 BGP_AFI_HELP_STR
14626 BGP_SAFI_WITH_LABEL_HELP_STR
14627 "Display the entries for all address families\n"
14628 "Detailed information on TCP and BGP neighbor connections\n"
14629 "Neighbor to display information about\n"
14630 "Neighbor to display information about\n"
14631 "Neighbor on BGP configured interface\n"
14632 "Display the routes advertised to a BGP neighbor\n"
14633 "Display the received routes from neighbor\n"
14634 "Display the filtered routes received from neighbor\n"
14635 "Route-map to modify the attributes\n"
14636 "Name of the route map\n"
14637 "IPv4 prefix\n"
14638 "IPv6 prefix\n"
14639 "Display detailed version of routes\n"
14640 JSON_STR
14641 "Increase table width for longer prefixes\n")
14642 {
14643 afi_t afi = AFI_IP6;
14644 safi_t safi = SAFI_UNICAST;
14645 char *peerstr = NULL;
14646 struct bgp *bgp = NULL;
14647 struct peer *peer;
14648 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
14649 int idx = 0;
14650 bool first = true;
14651 uint16_t show_flags = 0;
14652 struct listnode *node;
14653 struct bgp *abgp;
14654
14655 if (detail || prefix_str)
14656 SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
14657
14658 if (uj) {
14659 argc--;
14660 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14661 }
14662
14663 if (all) {
14664 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
14665 if (argv_find(argv, argc, "ipv4", &idx))
14666 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
14667
14668 if (argv_find(argv, argc, "ipv6", &idx))
14669 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
14670 }
14671
14672 if (wide)
14673 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
14674
14675 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14676 &bgp, uj);
14677 if (!idx)
14678 return CMD_WARNING;
14679
14680 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14681 argv_find(argv, argc, "neighbors", &idx);
14682 peerstr = argv[++idx]->arg;
14683
14684 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14685 if (!peer)
14686 return CMD_WARNING;
14687
14688 if (argv_find(argv, argc, "advertised-routes", &idx))
14689 type = bgp_show_adj_route_advertised;
14690 else if (argv_find(argv, argc, "received-routes", &idx))
14691 type = bgp_show_adj_route_received;
14692 else if (argv_find(argv, argc, "filtered-routes", &idx))
14693 type = bgp_show_adj_route_filtered;
14694
14695 if (!all)
14696 return peer_adj_routes(vty, peer, afi, safi, type, route_map,
14697 prefix_str ? prefix : NULL, show_flags);
14698 if (uj)
14699 vty_out(vty, "{\n");
14700
14701 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14702 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14703 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14704 : AFI_IP6;
14705 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14706 FOREACH_SAFI (safi) {
14707 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14708 continue;
14709
14710 if (uj) {
14711 if (first)
14712 first = false;
14713 else
14714 vty_out(vty, ",\n");
14715 vty_out(vty, "\"%s\":",
14716 get_afi_safi_str(afi, safi,
14717 true));
14718 } else
14719 vty_out(vty,
14720 "\nFor address family: %s\n",
14721 get_afi_safi_str(afi, safi,
14722 false));
14723
14724 peer_adj_routes(vty, peer, afi, safi, type,
14725 route_map, prefix, show_flags);
14726 }
14727 }
14728 } else {
14729 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
14730 FOREACH_AFI_SAFI (afi, safi) {
14731 if (!bgp_afi_safi_peer_exists(abgp, afi, safi))
14732 continue;
14733
14734 if (uj) {
14735 if (first)
14736 first = false;
14737 else
14738 vty_out(vty, ",\n");
14739 vty_out(vty, "\"%s\":",
14740 get_afi_safi_str(afi, safi,
14741 true));
14742 } else
14743 vty_out(vty,
14744 "\nFor address family: %s\n",
14745 get_afi_safi_str(afi, safi,
14746 false));
14747
14748 peer_adj_routes(vty, peer, afi, safi, type,
14749 route_map, prefix, show_flags);
14750 }
14751 }
14752 }
14753 if (uj)
14754 vty_out(vty, "}\n");
14755
14756 return CMD_SUCCESS;
14757 }
14758
14759 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14760 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14761 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14762 SHOW_STR
14763 IP_STR
14764 BGP_STR
14765 BGP_INSTANCE_HELP_STR
14766 BGP_AF_STR
14767 BGP_AF_STR
14768 BGP_AF_MODIFIER_STR
14769 "Detailed information on TCP and BGP neighbor connections\n"
14770 "Neighbor to display information about\n"
14771 "Neighbor to display information about\n"
14772 "Neighbor on BGP configured interface\n"
14773 "Display information received from a BGP neighbor\n"
14774 "Display the prefixlist filter\n"
14775 JSON_STR)
14776 {
14777 afi_t afi = AFI_IP6;
14778 safi_t safi = SAFI_UNICAST;
14779 char *peerstr = NULL;
14780 char name[BUFSIZ];
14781 struct peer *peer;
14782 int count;
14783 int idx = 0;
14784 struct bgp *bgp = NULL;
14785 bool uj = use_json(argc, argv);
14786
14787 if (uj)
14788 argc--;
14789
14790 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14791 &bgp, uj);
14792 if (!idx)
14793 return CMD_WARNING;
14794
14795 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14796 argv_find(argv, argc, "neighbors", &idx);
14797 peerstr = argv[++idx]->arg;
14798
14799 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14800 if (!peer)
14801 return CMD_WARNING;
14802
14803 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14804 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14805 if (count) {
14806 if (!uj)
14807 vty_out(vty, "Address Family: %s\n",
14808 get_afi_safi_str(afi, safi, false));
14809 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14810 } else {
14811 if (uj)
14812 vty_out(vty, "{}\n");
14813 else
14814 vty_out(vty, "No functional output\n");
14815 }
14816
14817 return CMD_SUCCESS;
14818 }
14819
14820 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14821 afi_t afi, safi_t safi,
14822 enum bgp_show_type type, bool use_json)
14823 {
14824 uint16_t show_flags = 0;
14825
14826 if (use_json)
14827 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14828
14829 if (!peer || !peer->afc[afi][safi]) {
14830 if (use_json) {
14831 json_object *json_no = NULL;
14832 json_no = json_object_new_object();
14833 json_object_string_add(
14834 json_no, "warning",
14835 "No such neighbor or address family");
14836 vty_out(vty, "%s\n",
14837 json_object_to_json_string(json_no));
14838 json_object_free(json_no);
14839 } else
14840 vty_out(vty, "%% No such neighbor or address family\n");
14841 return CMD_WARNING;
14842 }
14843
14844 /* labeled-unicast routes live in the unicast table */
14845 if (safi == SAFI_LABELED_UNICAST)
14846 safi = SAFI_UNICAST;
14847
14848 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14849 RPKI_NOT_BEING_USED);
14850 }
14851
14852 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14853 show_ip_bgp_flowspec_routes_detailed_cmd,
14854 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14855 SHOW_STR
14856 IP_STR
14857 BGP_STR
14858 BGP_INSTANCE_HELP_STR
14859 BGP_AFI_HELP_STR
14860 "SAFI Flowspec\n"
14861 "Detailed information on flowspec entries\n"
14862 JSON_STR)
14863 {
14864 afi_t afi = AFI_IP6;
14865 safi_t safi = SAFI_UNICAST;
14866 struct bgp *bgp = NULL;
14867 int idx = 0;
14868 bool uj = use_json(argc, argv);
14869 uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
14870
14871 if (uj) {
14872 argc--;
14873 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14874 }
14875
14876 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14877 &bgp, uj);
14878 if (!idx)
14879 return CMD_WARNING;
14880
14881 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14882 show_flags, RPKI_NOT_BEING_USED);
14883 }
14884
14885 DEFUN (show_ip_bgp_neighbor_routes,
14886 show_ip_bgp_neighbor_routes_cmd,
14887 "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]",
14888 SHOW_STR
14889 IP_STR
14890 BGP_STR
14891 BGP_INSTANCE_HELP_STR
14892 BGP_AFI_HELP_STR
14893 BGP_SAFI_WITH_LABEL_HELP_STR
14894 "Detailed information on TCP and BGP neighbor connections\n"
14895 "Neighbor to display information about\n"
14896 "Neighbor to display information about\n"
14897 "Neighbor on BGP configured interface\n"
14898 "Display flap statistics of the routes learned from neighbor\n"
14899 "Display the dampened routes received from neighbor\n"
14900 "Display routes learned from neighbor\n"
14901 JSON_STR)
14902 {
14903 char *peerstr = NULL;
14904 struct bgp *bgp = NULL;
14905 afi_t afi = AFI_IP6;
14906 safi_t safi = SAFI_UNICAST;
14907 struct peer *peer;
14908 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14909 int idx = 0;
14910 bool uj = use_json(argc, argv);
14911
14912 if (uj)
14913 argc--;
14914
14915 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14916 &bgp, uj);
14917 if (!idx)
14918 return CMD_WARNING;
14919
14920 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14921 argv_find(argv, argc, "neighbors", &idx);
14922 peerstr = argv[++idx]->arg;
14923
14924 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14925 if (!peer)
14926 return CMD_WARNING;
14927
14928 if (argv_find(argv, argc, "flap-statistics", &idx))
14929 sh_type = bgp_show_type_flap_neighbor;
14930 else if (argv_find(argv, argc, "dampened-routes", &idx))
14931 sh_type = bgp_show_type_damp_neighbor;
14932 else if (argv_find(argv, argc, "routes", &idx))
14933 sh_type = bgp_show_type_neighbor;
14934
14935 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14936 }
14937
14938 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14939
14940 struct bgp_distance {
14941 /* Distance value for the IP source prefix. */
14942 uint8_t distance;
14943
14944 /* Name of the access-list to be matched. */
14945 char *access_list;
14946 };
14947
14948 DEFUN (show_bgp_afi_vpn_rd_route,
14949 show_bgp_afi_vpn_rd_route_cmd,
14950 "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]",
14951 SHOW_STR
14952 BGP_STR
14953 BGP_AFI_HELP_STR
14954 BGP_AF_MODIFIER_STR
14955 "Display information for a route distinguisher\n"
14956 "Route Distinguisher\n"
14957 "All Route Distinguishers\n"
14958 "Network in the BGP routing table to display\n"
14959 "Network in the BGP routing table to display\n"
14960 JSON_STR)
14961 {
14962 int ret;
14963 struct prefix_rd prd;
14964 afi_t afi = AFI_MAX;
14965 int idx = 0;
14966
14967 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14968 vty_out(vty, "%% Malformed Address Family\n");
14969 return CMD_WARNING;
14970 }
14971
14972 if (!strcmp(argv[5]->arg, "all"))
14973 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14974 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14975 RPKI_NOT_BEING_USED,
14976 use_json(argc, argv));
14977
14978 ret = str2prefix_rd(argv[5]->arg, &prd);
14979 if (!ret) {
14980 vty_out(vty, "%% Malformed Route Distinguisher\n");
14981 return CMD_WARNING;
14982 }
14983
14984 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14985 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14986 use_json(argc, argv));
14987 }
14988
14989 static struct bgp_distance *bgp_distance_new(void)
14990 {
14991 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14992 }
14993
14994 static void bgp_distance_free(struct bgp_distance *bdistance)
14995 {
14996 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14997 }
14998
14999 static int bgp_distance_set(struct vty *vty, const char *distance_str,
15000 const char *ip_str, const char *access_list_str)
15001 {
15002 int ret;
15003 afi_t afi;
15004 safi_t safi;
15005 struct prefix p;
15006 uint8_t distance;
15007 struct bgp_dest *dest;
15008 struct bgp_distance *bdistance;
15009
15010 afi = bgp_node_afi(vty);
15011 safi = bgp_node_safi(vty);
15012
15013 ret = str2prefix(ip_str, &p);
15014 if (ret == 0) {
15015 vty_out(vty, "Malformed prefix\n");
15016 return CMD_WARNING_CONFIG_FAILED;
15017 }
15018
15019 distance = atoi(distance_str);
15020
15021 /* Get BGP distance node. */
15022 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
15023 bdistance = bgp_dest_get_bgp_distance_info(dest);
15024 if (bdistance)
15025 bgp_dest_unlock_node(dest);
15026 else {
15027 bdistance = bgp_distance_new();
15028 bgp_dest_set_bgp_distance_info(dest, bdistance);
15029 }
15030
15031 /* Set distance value. */
15032 bdistance->distance = distance;
15033
15034 /* Reset access-list configuration. */
15035 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15036 if (access_list_str)
15037 bdistance->access_list =
15038 XSTRDUP(MTYPE_AS_LIST, access_list_str);
15039
15040 return CMD_SUCCESS;
15041 }
15042
15043 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
15044 const char *ip_str, const char *access_list_str)
15045 {
15046 int ret;
15047 afi_t afi;
15048 safi_t safi;
15049 struct prefix p;
15050 int distance;
15051 struct bgp_dest *dest;
15052 struct bgp_distance *bdistance;
15053
15054 afi = bgp_node_afi(vty);
15055 safi = bgp_node_safi(vty);
15056
15057 ret = str2prefix(ip_str, &p);
15058 if (ret == 0) {
15059 vty_out(vty, "Malformed prefix\n");
15060 return CMD_WARNING_CONFIG_FAILED;
15061 }
15062
15063 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
15064 if (!dest) {
15065 vty_out(vty, "Can't find specified prefix\n");
15066 return CMD_WARNING_CONFIG_FAILED;
15067 }
15068
15069 bdistance = bgp_dest_get_bgp_distance_info(dest);
15070 distance = atoi(distance_str);
15071
15072 if (bdistance->distance != distance) {
15073 vty_out(vty, "Distance does not match configured\n");
15074 bgp_dest_unlock_node(dest);
15075 return CMD_WARNING_CONFIG_FAILED;
15076 }
15077
15078 XFREE(MTYPE_AS_LIST, bdistance->access_list);
15079 bgp_distance_free(bdistance);
15080
15081 bgp_dest_set_bgp_path_info(dest, NULL);
15082 bgp_dest_unlock_node(dest);
15083 bgp_dest_unlock_node(dest);
15084
15085 return CMD_SUCCESS;
15086 }
15087
15088 /* Apply BGP information to distance method. */
15089 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
15090 afi_t afi, safi_t safi, struct bgp *bgp)
15091 {
15092 struct bgp_dest *dest;
15093 struct prefix q = {0};
15094 struct peer *peer;
15095 struct bgp_distance *bdistance;
15096 struct access_list *alist;
15097 struct bgp_static *bgp_static;
15098 struct bgp_path_info *bpi_ultimate;
15099
15100 if (!bgp)
15101 return 0;
15102
15103 peer = pinfo->peer;
15104
15105 if (pinfo->attr->distance)
15106 return pinfo->attr->distance;
15107
15108 /* get peer origin to calculate appropriate distance */
15109 if (pinfo->sub_type == BGP_ROUTE_IMPORTED) {
15110 bpi_ultimate = bgp_get_imported_bpi_ultimate(pinfo);
15111 peer = bpi_ultimate->peer;
15112 }
15113
15114 /* Check source address.
15115 * Note: for aggregate route, peer can have unspec af type.
15116 */
15117 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
15118 && !sockunion2hostprefix(&peer->su, &q))
15119 return 0;
15120
15121 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
15122 if (dest) {
15123 bdistance = bgp_dest_get_bgp_distance_info(dest);
15124 bgp_dest_unlock_node(dest);
15125
15126 if (bdistance->access_list) {
15127 alist = access_list_lookup(afi, bdistance->access_list);
15128 if (alist
15129 && access_list_apply(alist, p) == FILTER_PERMIT)
15130 return bdistance->distance;
15131 } else
15132 return bdistance->distance;
15133 }
15134
15135 /* Backdoor check. */
15136 dest = bgp_node_lookup(bgp->route[afi][safi], p);
15137 if (dest) {
15138 bgp_static = bgp_dest_get_bgp_static_info(dest);
15139 bgp_dest_unlock_node(dest);
15140
15141 if (bgp_static->backdoor) {
15142 if (bgp->distance_local[afi][safi])
15143 return bgp->distance_local[afi][safi];
15144 else
15145 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15146 }
15147 }
15148
15149 if (peer->sort == BGP_PEER_EBGP) {
15150 if (bgp->distance_ebgp[afi][safi])
15151 return bgp->distance_ebgp[afi][safi];
15152 return ZEBRA_EBGP_DISTANCE_DEFAULT;
15153 } else if (peer->sort == BGP_PEER_IBGP) {
15154 if (bgp->distance_ibgp[afi][safi])
15155 return bgp->distance_ibgp[afi][safi];
15156 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15157 } else {
15158 if (bgp->distance_local[afi][safi])
15159 return bgp->distance_local[afi][safi];
15160 return ZEBRA_IBGP_DISTANCE_DEFAULT;
15161 }
15162 }
15163
15164 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
15165 * we should tell ZEBRA update the routes for a specific
15166 * AFI/SAFI to reflect changes in RIB.
15167 */
15168 static void bgp_announce_routes_distance_update(struct bgp *bgp,
15169 afi_t update_afi,
15170 safi_t update_safi)
15171 {
15172 afi_t afi;
15173 safi_t safi;
15174
15175 FOREACH_AFI_SAFI (afi, safi) {
15176 if (!bgp_fibupd_safi(safi))
15177 continue;
15178
15179 if (afi != update_afi && safi != update_safi)
15180 continue;
15181
15182 if (BGP_DEBUG(zebra, ZEBRA))
15183 zlog_debug(
15184 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
15185 __func__, afi, safi);
15186 bgp_zebra_announce_table(bgp, afi, safi);
15187 }
15188 }
15189
15190 DEFUN (bgp_distance,
15191 bgp_distance_cmd,
15192 "distance bgp (1-255) (1-255) (1-255)",
15193 "Define an administrative distance\n"
15194 "BGP distance\n"
15195 "Distance for routes external to the AS\n"
15196 "Distance for routes internal to the AS\n"
15197 "Distance for local routes\n")
15198 {
15199 VTY_DECLVAR_CONTEXT(bgp, bgp);
15200 int idx_number = 2;
15201 int idx_number_2 = 3;
15202 int idx_number_3 = 4;
15203 int distance_ebgp = atoi(argv[idx_number]->arg);
15204 int distance_ibgp = atoi(argv[idx_number_2]->arg);
15205 int distance_local = atoi(argv[idx_number_3]->arg);
15206 afi_t afi;
15207 safi_t safi;
15208
15209 afi = bgp_node_afi(vty);
15210 safi = bgp_node_safi(vty);
15211
15212 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
15213 || bgp->distance_ibgp[afi][safi] != distance_ibgp
15214 || bgp->distance_local[afi][safi] != distance_local) {
15215 bgp->distance_ebgp[afi][safi] = distance_ebgp;
15216 bgp->distance_ibgp[afi][safi] = distance_ibgp;
15217 bgp->distance_local[afi][safi] = distance_local;
15218 bgp_announce_routes_distance_update(bgp, afi, safi);
15219 }
15220 return CMD_SUCCESS;
15221 }
15222
15223 DEFUN (no_bgp_distance,
15224 no_bgp_distance_cmd,
15225 "no distance bgp [(1-255) (1-255) (1-255)]",
15226 NO_STR
15227 "Define an administrative distance\n"
15228 "BGP distance\n"
15229 "Distance for routes external to the AS\n"
15230 "Distance for routes internal to the AS\n"
15231 "Distance for local routes\n")
15232 {
15233 VTY_DECLVAR_CONTEXT(bgp, bgp);
15234 afi_t afi;
15235 safi_t safi;
15236
15237 afi = bgp_node_afi(vty);
15238 safi = bgp_node_safi(vty);
15239
15240 if (bgp->distance_ebgp[afi][safi] != 0
15241 || bgp->distance_ibgp[afi][safi] != 0
15242 || bgp->distance_local[afi][safi] != 0) {
15243 bgp->distance_ebgp[afi][safi] = 0;
15244 bgp->distance_ibgp[afi][safi] = 0;
15245 bgp->distance_local[afi][safi] = 0;
15246 bgp_announce_routes_distance_update(bgp, afi, safi);
15247 }
15248 return CMD_SUCCESS;
15249 }
15250
15251
15252 DEFUN (bgp_distance_source,
15253 bgp_distance_source_cmd,
15254 "distance (1-255) A.B.C.D/M",
15255 "Define an administrative distance\n"
15256 "Administrative distance\n"
15257 "IP source prefix\n")
15258 {
15259 int idx_number = 1;
15260 int idx_ipv4_prefixlen = 2;
15261 bgp_distance_set(vty, argv[idx_number]->arg,
15262 argv[idx_ipv4_prefixlen]->arg, NULL);
15263 return CMD_SUCCESS;
15264 }
15265
15266 DEFUN (no_bgp_distance_source,
15267 no_bgp_distance_source_cmd,
15268 "no distance (1-255) A.B.C.D/M",
15269 NO_STR
15270 "Define an administrative distance\n"
15271 "Administrative distance\n"
15272 "IP source prefix\n")
15273 {
15274 int idx_number = 2;
15275 int idx_ipv4_prefixlen = 3;
15276 bgp_distance_unset(vty, argv[idx_number]->arg,
15277 argv[idx_ipv4_prefixlen]->arg, NULL);
15278 return CMD_SUCCESS;
15279 }
15280
15281 DEFUN (bgp_distance_source_access_list,
15282 bgp_distance_source_access_list_cmd,
15283 "distance (1-255) A.B.C.D/M WORD",
15284 "Define an administrative distance\n"
15285 "Administrative distance\n"
15286 "IP source prefix\n"
15287 "Access list name\n")
15288 {
15289 int idx_number = 1;
15290 int idx_ipv4_prefixlen = 2;
15291 int idx_word = 3;
15292 bgp_distance_set(vty, argv[idx_number]->arg,
15293 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15294 return CMD_SUCCESS;
15295 }
15296
15297 DEFUN (no_bgp_distance_source_access_list,
15298 no_bgp_distance_source_access_list_cmd,
15299 "no distance (1-255) A.B.C.D/M WORD",
15300 NO_STR
15301 "Define an administrative distance\n"
15302 "Administrative distance\n"
15303 "IP source prefix\n"
15304 "Access list name\n")
15305 {
15306 int idx_number = 2;
15307 int idx_ipv4_prefixlen = 3;
15308 int idx_word = 4;
15309 bgp_distance_unset(vty, argv[idx_number]->arg,
15310 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
15311 return CMD_SUCCESS;
15312 }
15313
15314 DEFUN (ipv6_bgp_distance_source,
15315 ipv6_bgp_distance_source_cmd,
15316 "distance (1-255) X:X::X:X/M",
15317 "Define an administrative distance\n"
15318 "Administrative distance\n"
15319 "IP source prefix\n")
15320 {
15321 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
15322 return CMD_SUCCESS;
15323 }
15324
15325 DEFUN (no_ipv6_bgp_distance_source,
15326 no_ipv6_bgp_distance_source_cmd,
15327 "no distance (1-255) X:X::X:X/M",
15328 NO_STR
15329 "Define an administrative distance\n"
15330 "Administrative distance\n"
15331 "IP source prefix\n")
15332 {
15333 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
15334 return CMD_SUCCESS;
15335 }
15336
15337 DEFUN (ipv6_bgp_distance_source_access_list,
15338 ipv6_bgp_distance_source_access_list_cmd,
15339 "distance (1-255) X:X::X:X/M WORD",
15340 "Define an administrative distance\n"
15341 "Administrative distance\n"
15342 "IP source prefix\n"
15343 "Access list name\n")
15344 {
15345 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
15346 return CMD_SUCCESS;
15347 }
15348
15349 DEFUN (no_ipv6_bgp_distance_source_access_list,
15350 no_ipv6_bgp_distance_source_access_list_cmd,
15351 "no distance (1-255) X:X::X:X/M WORD",
15352 NO_STR
15353 "Define an administrative distance\n"
15354 "Administrative distance\n"
15355 "IP source prefix\n"
15356 "Access list name\n")
15357 {
15358 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
15359 return CMD_SUCCESS;
15360 }
15361
15362 DEFUN (bgp_damp_set,
15363 bgp_damp_set_cmd,
15364 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15365 "BGP Specific commands\n"
15366 "Enable route-flap dampening\n"
15367 "Half-life time for the penalty\n"
15368 "Value to start reusing a route\n"
15369 "Value to start suppressing a route\n"
15370 "Maximum duration to suppress a stable route\n")
15371 {
15372 VTY_DECLVAR_CONTEXT(bgp, bgp);
15373 int idx_half_life = 2;
15374 int idx_reuse = 3;
15375 int idx_suppress = 4;
15376 int idx_max_suppress = 5;
15377 int half = DEFAULT_HALF_LIFE * 60;
15378 int reuse = DEFAULT_REUSE;
15379 int suppress = DEFAULT_SUPPRESS;
15380 int max = 4 * half;
15381
15382 if (argc == 6) {
15383 half = atoi(argv[idx_half_life]->arg) * 60;
15384 reuse = atoi(argv[idx_reuse]->arg);
15385 suppress = atoi(argv[idx_suppress]->arg);
15386 max = atoi(argv[idx_max_suppress]->arg) * 60;
15387 } else if (argc == 3) {
15388 half = atoi(argv[idx_half_life]->arg) * 60;
15389 max = 4 * half;
15390 }
15391
15392 /*
15393 * These can't be 0 but our SA doesn't understand the
15394 * way our cli is constructed
15395 */
15396 assert(reuse);
15397 assert(half);
15398 if (suppress < reuse) {
15399 vty_out(vty,
15400 "Suppress value cannot be less than reuse value \n");
15401 return 0;
15402 }
15403
15404 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
15405 reuse, suppress, max);
15406 }
15407
15408 DEFUN (bgp_damp_unset,
15409 bgp_damp_unset_cmd,
15410 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
15411 NO_STR
15412 "BGP Specific commands\n"
15413 "Enable route-flap dampening\n"
15414 "Half-life time for the penalty\n"
15415 "Value to start reusing a route\n"
15416 "Value to start suppressing a route\n"
15417 "Maximum duration to suppress a stable route\n")
15418 {
15419 VTY_DECLVAR_CONTEXT(bgp, bgp);
15420 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
15421 }
15422
15423 /* Display specified route of BGP table. */
15424 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
15425 const char *ip_str, afi_t afi, safi_t safi,
15426 struct prefix_rd *prd, int prefix_check)
15427 {
15428 int ret;
15429 struct prefix match;
15430 struct bgp_dest *dest;
15431 struct bgp_dest *rm;
15432 struct bgp_path_info *pi;
15433 struct bgp_path_info *pi_temp;
15434 struct bgp *bgp;
15435 struct bgp_table *table;
15436
15437 /* BGP structure lookup. */
15438 if (view_name) {
15439 bgp = bgp_lookup_by_name(view_name);
15440 if (bgp == NULL) {
15441 vty_out(vty, "%% Can't find BGP instance %s\n",
15442 view_name);
15443 return CMD_WARNING;
15444 }
15445 } else {
15446 bgp = bgp_get_default();
15447 if (bgp == NULL) {
15448 vty_out(vty, "%% No BGP process is configured\n");
15449 return CMD_WARNING;
15450 }
15451 }
15452
15453 /* Check IP address argument. */
15454 ret = str2prefix(ip_str, &match);
15455 if (!ret) {
15456 vty_out(vty, "%% address is malformed\n");
15457 return CMD_WARNING;
15458 }
15459
15460 match.family = afi2family(afi);
15461
15462 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
15463 || (safi == SAFI_EVPN)) {
15464 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
15465 dest = bgp_route_next(dest)) {
15466 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15467
15468 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
15469 continue;
15470 table = bgp_dest_get_bgp_table_info(dest);
15471 if (!table)
15472 continue;
15473 rm = bgp_node_match(table, &match);
15474 if (rm == NULL)
15475 continue;
15476
15477 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
15478
15479 if (!prefix_check
15480 || rm_p->prefixlen == match.prefixlen) {
15481 pi = bgp_dest_get_bgp_path_info(rm);
15482 while (pi) {
15483 if (pi->extra && pi->extra->damp_info) {
15484 pi_temp = pi->next;
15485 bgp_damp_info_free(
15486 pi->extra->damp_info,
15487 1, afi, safi);
15488 pi = pi_temp;
15489 } else
15490 pi = pi->next;
15491 }
15492 }
15493
15494 bgp_dest_unlock_node(rm);
15495 }
15496 } else {
15497 dest = bgp_node_match(bgp->rib[afi][safi], &match);
15498 if (dest != NULL) {
15499 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
15500
15501 if (!prefix_check
15502 || dest_p->prefixlen == match.prefixlen) {
15503 pi = bgp_dest_get_bgp_path_info(dest);
15504 while (pi) {
15505 if (pi->extra && pi->extra->damp_info) {
15506 pi_temp = pi->next;
15507 bgp_damp_info_free(
15508 pi->extra->damp_info,
15509 1, afi, safi);
15510 pi = pi_temp;
15511 } else
15512 pi = pi->next;
15513 }
15514 }
15515
15516 bgp_dest_unlock_node(dest);
15517 }
15518 }
15519
15520 return CMD_SUCCESS;
15521 }
15522
15523 DEFUN (clear_ip_bgp_dampening,
15524 clear_ip_bgp_dampening_cmd,
15525 "clear ip bgp dampening",
15526 CLEAR_STR
15527 IP_STR
15528 BGP_STR
15529 "Clear route flap dampening information\n")
15530 {
15531 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
15532 return CMD_SUCCESS;
15533 }
15534
15535 DEFUN (clear_ip_bgp_dampening_prefix,
15536 clear_ip_bgp_dampening_prefix_cmd,
15537 "clear ip bgp dampening A.B.C.D/M",
15538 CLEAR_STR
15539 IP_STR
15540 BGP_STR
15541 "Clear route flap dampening information\n"
15542 "IPv4 prefix\n")
15543 {
15544 int idx_ipv4_prefixlen = 4;
15545 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
15546 AFI_IP, SAFI_UNICAST, NULL, 1);
15547 }
15548
15549 DEFUN (clear_ip_bgp_dampening_address,
15550 clear_ip_bgp_dampening_address_cmd,
15551 "clear ip bgp dampening A.B.C.D",
15552 CLEAR_STR
15553 IP_STR
15554 BGP_STR
15555 "Clear route flap dampening information\n"
15556 "Network to clear damping information\n")
15557 {
15558 int idx_ipv4 = 4;
15559 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
15560 SAFI_UNICAST, NULL, 0);
15561 }
15562
15563 DEFUN (clear_ip_bgp_dampening_address_mask,
15564 clear_ip_bgp_dampening_address_mask_cmd,
15565 "clear ip bgp dampening A.B.C.D A.B.C.D",
15566 CLEAR_STR
15567 IP_STR
15568 BGP_STR
15569 "Clear route flap dampening information\n"
15570 "Network to clear damping information\n"
15571 "Network mask\n")
15572 {
15573 int idx_ipv4 = 4;
15574 int idx_ipv4_2 = 5;
15575 int ret;
15576 char prefix_str[BUFSIZ];
15577
15578 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
15579 prefix_str, sizeof(prefix_str));
15580 if (!ret) {
15581 vty_out(vty, "%% Inconsistent address and mask\n");
15582 return CMD_WARNING;
15583 }
15584
15585 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
15586 NULL, 0);
15587 }
15588
15589 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
15590 {
15591 struct vty *vty = arg;
15592 struct peer *peer = bucket->data;
15593
15594 vty_out(vty, "\tPeer: %s %pSU\n", peer->host, &peer->su);
15595 }
15596
15597 DEFUN (show_bgp_listeners,
15598 show_bgp_listeners_cmd,
15599 "show bgp listeners",
15600 SHOW_STR
15601 BGP_STR
15602 "Display Listen Sockets and who created them\n")
15603 {
15604 bgp_dump_listener_info(vty);
15605
15606 return CMD_SUCCESS;
15607 }
15608
15609 DEFUN (show_bgp_peerhash,
15610 show_bgp_peerhash_cmd,
15611 "show bgp peerhash",
15612 SHOW_STR
15613 BGP_STR
15614 "Display information about the BGP peerhash\n")
15615 {
15616 struct list *instances = bm->bgp;
15617 struct listnode *node;
15618 struct bgp *bgp;
15619
15620 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
15621 vty_out(vty, "BGP: %s\n", bgp->name);
15622 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
15623 vty);
15624 }
15625
15626 return CMD_SUCCESS;
15627 }
15628
15629 /* also used for encap safi */
15630 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
15631 afi_t afi, safi_t safi)
15632 {
15633 struct bgp_dest *pdest;
15634 struct bgp_dest *dest;
15635 struct bgp_table *table;
15636 const struct prefix *p;
15637 struct bgp_static *bgp_static;
15638 mpls_label_t label;
15639
15640 /* Network configuration. */
15641 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15642 pdest = bgp_route_next(pdest)) {
15643 table = bgp_dest_get_bgp_table_info(pdest);
15644 if (!table)
15645 continue;
15646
15647 for (dest = bgp_table_top(table); dest;
15648 dest = bgp_route_next(dest)) {
15649 bgp_static = bgp_dest_get_bgp_static_info(dest);
15650 if (bgp_static == NULL)
15651 continue;
15652
15653 p = bgp_dest_get_prefix(dest);
15654
15655 /* "network" configuration display. */
15656 label = decode_label(&bgp_static->label);
15657
15658 vty_out(vty, " network %pFX rd %s", p,
15659 bgp_static->prd_pretty);
15660 if (safi == SAFI_MPLS_VPN)
15661 vty_out(vty, " label %u", label);
15662
15663 if (bgp_static->rmap.name)
15664 vty_out(vty, " route-map %s",
15665 bgp_static->rmap.name);
15666
15667 if (bgp_static->backdoor)
15668 vty_out(vty, " backdoor");
15669
15670 vty_out(vty, "\n");
15671 }
15672 }
15673 }
15674
15675 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
15676 afi_t afi, safi_t safi)
15677 {
15678 struct bgp_dest *pdest;
15679 struct bgp_dest *dest;
15680 struct bgp_table *table;
15681 const struct prefix *p;
15682 struct bgp_static *bgp_static;
15683 char buf[PREFIX_STRLEN * 2];
15684 char buf2[SU_ADDRSTRLEN];
15685 char esi_buf[ESI_STR_LEN];
15686
15687 /* Network configuration. */
15688 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15689 pdest = bgp_route_next(pdest)) {
15690 table = bgp_dest_get_bgp_table_info(pdest);
15691 if (!table)
15692 continue;
15693
15694 for (dest = bgp_table_top(table); dest;
15695 dest = bgp_route_next(dest)) {
15696 bgp_static = bgp_dest_get_bgp_static_info(dest);
15697 if (bgp_static == NULL)
15698 continue;
15699
15700 char *macrouter = NULL;
15701
15702 if (bgp_static->router_mac)
15703 macrouter = prefix_mac2str(
15704 bgp_static->router_mac, NULL, 0);
15705 if (bgp_static->eth_s_id)
15706 esi_to_str(bgp_static->eth_s_id,
15707 esi_buf, sizeof(esi_buf));
15708 p = bgp_dest_get_prefix(dest);
15709
15710 /* "network" configuration display. */
15711 if (p->u.prefix_evpn.route_type == 5) {
15712 char local_buf[PREFIX_STRLEN];
15713
15714 uint8_t family = is_evpn_prefix_ipaddr_v4((
15715 struct prefix_evpn *)p)
15716 ? AF_INET
15717 : AF_INET6;
15718 inet_ntop(family,
15719 &p->u.prefix_evpn.prefix_addr.ip.ip
15720 .addr,
15721 local_buf, sizeof(local_buf));
15722 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15723 p->u.prefix_evpn.prefix_addr
15724 .ip_prefix_length);
15725 } else {
15726 prefix2str(p, buf, sizeof(buf));
15727 }
15728
15729 if (bgp_static->gatewayIp.family == AF_INET
15730 || bgp_static->gatewayIp.family == AF_INET6)
15731 inet_ntop(bgp_static->gatewayIp.family,
15732 &bgp_static->gatewayIp.u.prefix, buf2,
15733 sizeof(buf2));
15734 vty_out(vty,
15735 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15736 buf, bgp_static->prd_pretty,
15737 p->u.prefix_evpn.prefix_addr.eth_tag,
15738 decode_label(&bgp_static->label), esi_buf, buf2,
15739 macrouter);
15740
15741 XFREE(MTYPE_TMP, macrouter);
15742 }
15743 }
15744 }
15745
15746 /* Configuration of static route announcement and aggregate
15747 information. */
15748 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15749 safi_t safi)
15750 {
15751 struct bgp_dest *dest;
15752 const struct prefix *p;
15753 struct bgp_static *bgp_static;
15754 struct bgp_aggregate *bgp_aggregate;
15755
15756 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15757 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15758 return;
15759 }
15760
15761 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15762 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15763 return;
15764 }
15765
15766 /* Network configuration. */
15767 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15768 dest = bgp_route_next(dest)) {
15769 bgp_static = bgp_dest_get_bgp_static_info(dest);
15770 if (bgp_static == NULL)
15771 continue;
15772
15773 p = bgp_dest_get_prefix(dest);
15774
15775 vty_out(vty, " network %pFX", p);
15776
15777 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15778 vty_out(vty, " label-index %u",
15779 bgp_static->label_index);
15780
15781 if (bgp_static->rmap.name)
15782 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15783
15784 if (bgp_static->backdoor)
15785 vty_out(vty, " backdoor");
15786
15787 vty_out(vty, "\n");
15788 }
15789
15790 /* Aggregate-address configuration. */
15791 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15792 dest = bgp_route_next(dest)) {
15793 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15794 if (bgp_aggregate == NULL)
15795 continue;
15796
15797 p = bgp_dest_get_prefix(dest);
15798
15799 vty_out(vty, " aggregate-address %pFX", p);
15800
15801 if (bgp_aggregate->as_set)
15802 vty_out(vty, " as-set");
15803
15804 if (bgp_aggregate->summary_only)
15805 vty_out(vty, " summary-only");
15806
15807 if (bgp_aggregate->rmap.name)
15808 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15809
15810 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15811 vty_out(vty, " origin %s",
15812 bgp_origin2str(bgp_aggregate->origin));
15813
15814 if (bgp_aggregate->match_med)
15815 vty_out(vty, " matching-MED-only");
15816
15817 if (bgp_aggregate->suppress_map_name)
15818 vty_out(vty, " suppress-map %s",
15819 bgp_aggregate->suppress_map_name);
15820
15821 vty_out(vty, "\n");
15822 }
15823 }
15824
15825 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15826 safi_t safi)
15827 {
15828 struct bgp_dest *dest;
15829 struct bgp_distance *bdistance;
15830
15831 /* Distance configuration. */
15832 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15833 && bgp->distance_local[afi][safi]
15834 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15835 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15836 || bgp->distance_local[afi][safi]
15837 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15838 vty_out(vty, " distance bgp %d %d %d\n",
15839 bgp->distance_ebgp[afi][safi],
15840 bgp->distance_ibgp[afi][safi],
15841 bgp->distance_local[afi][safi]);
15842 }
15843
15844 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15845 dest = bgp_route_next(dest)) {
15846 bdistance = bgp_dest_get_bgp_distance_info(dest);
15847 if (bdistance != NULL)
15848 vty_out(vty, " distance %d %pBD %s\n",
15849 bdistance->distance, dest,
15850 bdistance->access_list ? bdistance->access_list
15851 : "");
15852 }
15853 }
15854
15855 /* Allocate routing table structure and install commands. */
15856 void bgp_route_init(void)
15857 {
15858 afi_t afi;
15859 safi_t safi;
15860
15861 /* Init BGP distance table. */
15862 FOREACH_AFI_SAFI (afi, safi)
15863 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15864
15865 /* IPv4 BGP commands. */
15866 install_element(BGP_NODE, &bgp_table_map_cmd);
15867 install_element(BGP_NODE, &bgp_network_cmd);
15868 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15869
15870 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15871
15872 /* IPv4 unicast configuration. */
15873 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15874 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15875 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15876
15877 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15878
15879 /* IPv4 multicast configuration. */
15880 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15881 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15882 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15883 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15884
15885 /* IPv4 labeled-unicast configuration. */
15886 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15887 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15888
15889 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15890 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15891 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15892 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15893 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15894 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15895 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15896 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15897
15898 install_element(VIEW_NODE,
15899 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15900 install_element(VIEW_NODE,
15901 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15902 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15903 install_element(VIEW_NODE,
15904 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15905 #ifdef KEEP_OLD_VPN_COMMANDS
15906 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15907 #endif /* KEEP_OLD_VPN_COMMANDS */
15908 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15909 install_element(VIEW_NODE,
15910 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15911
15912 /* BGP dampening clear commands */
15913 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15914 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15915
15916 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15917 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15918
15919 /* prefix count */
15920 install_element(ENABLE_NODE,
15921 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15922 #ifdef KEEP_OLD_VPN_COMMANDS
15923 install_element(ENABLE_NODE,
15924 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15925 #endif /* KEEP_OLD_VPN_COMMANDS */
15926
15927 /* New config IPv6 BGP commands. */
15928 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15929 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15930 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15931
15932 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15933
15934 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15935
15936 /* IPv6 labeled unicast address family. */
15937 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15938 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15939
15940 install_element(BGP_NODE, &bgp_distance_cmd);
15941 install_element(BGP_NODE, &no_bgp_distance_cmd);
15942 install_element(BGP_NODE, &bgp_distance_source_cmd);
15943 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15944 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15945 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15946 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15947 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15948 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15949 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15950 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15951 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15952 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15953 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15954 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15955 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15956 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15957 install_element(BGP_IPV4M_NODE,
15958 &no_bgp_distance_source_access_list_cmd);
15959 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15960 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15961 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15962 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15963 install_element(BGP_IPV6_NODE,
15964 &ipv6_bgp_distance_source_access_list_cmd);
15965 install_element(BGP_IPV6_NODE,
15966 &no_ipv6_bgp_distance_source_access_list_cmd);
15967 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15968 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15969 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15970 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15971 install_element(BGP_IPV6M_NODE,
15972 &ipv6_bgp_distance_source_access_list_cmd);
15973 install_element(BGP_IPV6M_NODE,
15974 &no_ipv6_bgp_distance_source_access_list_cmd);
15975
15976 /* BGP dampening */
15977 install_element(BGP_NODE, &bgp_damp_set_cmd);
15978 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15979 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15980 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15981 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15982 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15983 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15984 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15985 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15986 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15987 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15988 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15989 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15990 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15991
15992 /* Large Communities */
15993 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15994 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15995
15996 /* show bgp ipv4 flowspec detailed */
15997 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15998
15999 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
16000 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
16001 }
16002
16003 void bgp_route_finish(void)
16004 {
16005 afi_t afi;
16006 safi_t safi;
16007
16008 FOREACH_AFI_SAFI (afi, safi) {
16009 bgp_table_unlock(bgp_distance_table[afi][safi]);
16010 bgp_distance_table[afi][safi] = NULL;
16011 }
16012 }