]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Fix crash for `show ip bgp vrf all all`
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23 #include <math.h>
24
25 #include "printfrr.h"
26 #include "frrstr.h"
27 #include "prefix.h"
28 #include "linklist.h"
29 #include "memory.h"
30 #include "command.h"
31 #include "stream.h"
32 #include "filter.h"
33 #include "log.h"
34 #include "routemap.h"
35 #include "buffer.h"
36 #include "sockunion.h"
37 #include "plist.h"
38 #include "thread.h"
39 #include "workqueue.h"
40 #include "queue.h"
41 #include "memory.h"
42 #include "srv6.h"
43 #include "lib/json.h"
44 #include "lib_errors.h"
45 #include "zclient.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_route.h"
49 #include "bgpd/bgp_attr.h"
50 #include "bgpd/bgp_debug.h"
51 #include "bgpd/bgp_errors.h"
52 #include "bgpd/bgp_aspath.h"
53 #include "bgpd/bgp_regex.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_community_alias.h"
56 #include "bgpd/bgp_ecommunity.h"
57 #include "bgpd/bgp_lcommunity.h"
58 #include "bgpd/bgp_clist.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_filter.h"
61 #include "bgpd/bgp_fsm.h"
62 #include "bgpd/bgp_mplsvpn.h"
63 #include "bgpd/bgp_nexthop.h"
64 #include "bgpd/bgp_damp.h"
65 #include "bgpd/bgp_advertise.h"
66 #include "bgpd/bgp_zebra.h"
67 #include "bgpd/bgp_vty.h"
68 #include "bgpd/bgp_mpath.h"
69 #include "bgpd/bgp_nht.h"
70 #include "bgpd/bgp_updgrp.h"
71 #include "bgpd/bgp_label.h"
72 #include "bgpd/bgp_addpath.h"
73 #include "bgpd/bgp_mac.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_trace.h"
76 #include "bgpd/bgp_rpki.h"
77
78 #ifdef ENABLE_BGP_VNC
79 #include "bgpd/rfapi/rfapi_backend.h"
80 #include "bgpd/rfapi/vnc_import_bgp.h"
81 #include "bgpd/rfapi/vnc_export_bgp.h"
82 #endif
83 #include "bgpd/bgp_encap_types.h"
84 #include "bgpd/bgp_encap_tlv.h"
85 #include "bgpd/bgp_evpn.h"
86 #include "bgpd/bgp_evpn_mh.h"
87 #include "bgpd/bgp_evpn_vty.h"
88 #include "bgpd/bgp_flowspec.h"
89 #include "bgpd/bgp_flowspec_util.h"
90 #include "bgpd/bgp_pbr.h"
91
92 #ifndef VTYSH_EXTRACT_PL
93 #include "bgpd/bgp_route_clippy.c"
94 #endif
95
96 DEFINE_HOOK(bgp_snmp_update_stats,
97 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
98 (rn, pi, added));
99
100 DEFINE_HOOK(bgp_rpki_prefix_status,
101 (struct peer *peer, struct attr *attr,
102 const struct prefix *prefix),
103 (peer, attr, prefix));
104
105 /* Render dest to prefix_rd based on safi */
106 static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
107 safi_t safi);
108
109 /* Extern from bgp_dump.c */
110 extern const char *bgp_origin_str[];
111 extern const char *bgp_origin_long_str[];
112
113 /* PMSI strings. */
114 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
115 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
116 static const struct message bgp_pmsi_tnltype_str[] = {
117 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
118 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
119 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
120 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
121 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
122 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
123 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
124 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
125 {0}
126 };
127
128 #define VRFID_NONE_STR "-"
129 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
130
131 DEFINE_HOOK(bgp_process,
132 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
133 struct peer *peer, bool withdraw),
134 (bgp, afi, safi, bn, peer, withdraw));
135
136 /** Test if path is suppressed. */
137 static bool bgp_path_suppressed(struct bgp_path_info *pi)
138 {
139 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
140 return false;
141
142 return listcount(pi->extra->aggr_suppressors) > 0;
143 }
144
145 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
146 safi_t safi, const struct prefix *p,
147 struct prefix_rd *prd)
148 {
149 struct bgp_dest *dest;
150 struct bgp_dest *pdest = NULL;
151
152 assert(table);
153
154 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
155 || (safi == SAFI_EVPN)) {
156 pdest = bgp_node_get(table, (struct prefix *)prd);
157
158 if (!bgp_dest_has_bgp_path_info_data(pdest))
159 bgp_dest_set_bgp_table_info(
160 pdest, bgp_table_init(table->bgp, afi, safi));
161 else
162 bgp_dest_unlock_node(pdest);
163 table = bgp_dest_get_bgp_table_info(pdest);
164 }
165
166 dest = bgp_node_get(table, p);
167
168 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
169 || (safi == SAFI_EVPN))
170 dest->pdest = pdest;
171
172 return dest;
173 }
174
175 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
176 safi_t safi, const struct prefix *p,
177 struct prefix_rd *prd)
178 {
179 struct bgp_dest *dest;
180 struct bgp_dest *pdest = NULL;
181
182 if (!table)
183 return NULL;
184
185 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
186 || (safi == SAFI_EVPN)) {
187 pdest = bgp_node_lookup(table, (struct prefix *)prd);
188 if (!pdest)
189 return NULL;
190
191 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
192 bgp_dest_unlock_node(pdest);
193 return NULL;
194 }
195
196 table = bgp_dest_get_bgp_table_info(pdest);
197 }
198
199 dest = bgp_node_lookup(table, p);
200
201 return dest;
202 }
203
204 /* Allocate bgp_path_info_extra */
205 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
206 {
207 struct bgp_path_info_extra *new;
208 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
209 sizeof(struct bgp_path_info_extra));
210 new->label[0] = MPLS_INVALID_LABEL;
211 new->num_labels = 0;
212 new->bgp_fs_pbr = NULL;
213 new->bgp_fs_iprule = NULL;
214 return new;
215 }
216
217 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
218 {
219 struct bgp_path_info_extra *e;
220
221 if (!extra || !*extra)
222 return;
223
224 e = *extra;
225 if (e->damp_info)
226 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
227 e->damp_info->safi);
228
229 e->damp_info = NULL;
230 if (e->parent) {
231 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
232
233 if (bpi->net) {
234 /* FIXME: since multiple e may have the same e->parent
235 * and e->parent->net is holding a refcount for each
236 * of them, we need to do some fudging here.
237 *
238 * WARNING: if bpi->net->lock drops to 0, bpi may be
239 * freed as well (because bpi->net was holding the
240 * last reference to bpi) => write after free!
241 */
242 unsigned refcount;
243
244 bpi = bgp_path_info_lock(bpi);
245 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
246 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
247 if (!refcount)
248 bpi->net = NULL;
249 bgp_path_info_unlock(bpi);
250 }
251 bgp_path_info_unlock(e->parent);
252 e->parent = NULL;
253 }
254
255 if (e->bgp_orig)
256 bgp_unlock(e->bgp_orig);
257
258 if (e->aggr_suppressors)
259 list_delete(&e->aggr_suppressors);
260
261 if (e->mh_info)
262 bgp_evpn_path_mh_info_free(e->mh_info);
263
264 if ((*extra)->bgp_fs_iprule)
265 list_delete(&((*extra)->bgp_fs_iprule));
266 if ((*extra)->bgp_fs_pbr)
267 list_delete(&((*extra)->bgp_fs_pbr));
268 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
269 }
270
271 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
272 * allocated if required.
273 */
274 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
275 {
276 if (!pi->extra)
277 pi->extra = bgp_path_info_extra_new();
278 return pi->extra;
279 }
280
281 /* Free bgp route information. */
282 static void bgp_path_info_free(struct bgp_path_info *path)
283 {
284 bgp_attr_unintern(&path->attr);
285
286 bgp_unlink_nexthop(path);
287 bgp_path_info_extra_free(&path->extra);
288 bgp_path_info_mpath_free(&path->mpath);
289 if (path->net)
290 bgp_addpath_free_info_data(&path->tx_addpath,
291 &path->net->tx_addpath);
292
293 peer_unlock(path->peer); /* bgp_path_info peer reference */
294
295 XFREE(MTYPE_BGP_ROUTE, path);
296 }
297
298 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
299 {
300 path->lock++;
301 return path;
302 }
303
304 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
305 {
306 assert(path && path->lock > 0);
307 path->lock--;
308
309 if (path->lock == 0) {
310 bgp_path_info_free(path);
311 return NULL;
312 }
313
314 return path;
315 }
316
317 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
318 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
319 {
320 struct peer *peer;
321 struct bgp_path_info *old_pi, *nextpi;
322 bool set_flag = false;
323 struct bgp *bgp = NULL;
324 struct bgp_table *table = NULL;
325 afi_t afi = 0;
326 safi_t safi = 0;
327
328 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
329 * then the route selection is deferred
330 */
331 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
332 return 0;
333
334 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
335 if (BGP_DEBUG(update, UPDATE_OUT))
336 zlog_debug(
337 "Route %pBD is in workqueue and being processed, not deferred.",
338 dest);
339
340 return 0;
341 }
342
343 table = bgp_dest_table(dest);
344 if (table) {
345 bgp = table->bgp;
346 afi = table->afi;
347 safi = table->safi;
348 }
349
350 for (old_pi = bgp_dest_get_bgp_path_info(dest);
351 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
352 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
353 continue;
354
355 /* Route selection is deferred if there is a stale path which
356 * which indicates peer is in restart mode
357 */
358 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
359 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
360 set_flag = true;
361 } else {
362 /* If the peer is graceful restart capable and peer is
363 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
364 */
365 peer = old_pi->peer;
366 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
367 && BGP_PEER_RESTARTING_MODE(peer)
368 && (old_pi
369 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
370 set_flag = true;
371 }
372 }
373 if (set_flag)
374 break;
375 }
376
377 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
378 * is active
379 */
380 if (set_flag && table) {
381 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
382 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
383 bgp->gr_info[afi][safi].gr_deferred++;
384 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
385 if (BGP_DEBUG(update, UPDATE_OUT))
386 zlog_debug("DEFER route %pBD, dest %p", dest,
387 dest);
388 return 0;
389 }
390 }
391 return -1;
392 }
393
394 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
395 {
396 struct bgp_path_info *top;
397
398 top = bgp_dest_get_bgp_path_info(dest);
399
400 pi->next = top;
401 pi->prev = NULL;
402 if (top)
403 top->prev = pi;
404 bgp_dest_set_bgp_path_info(dest, pi);
405
406 bgp_path_info_lock(pi);
407 bgp_dest_lock_node(dest);
408 peer_lock(pi->peer); /* bgp_path_info peer reference */
409 bgp_dest_set_defer_flag(dest, false);
410 hook_call(bgp_snmp_update_stats, dest, pi, true);
411 }
412
413 /* Do the actual removal of info from RIB, for use by bgp_process
414 completion callback *only* */
415 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
416 {
417 if (pi->next)
418 pi->next->prev = pi->prev;
419 if (pi->prev)
420 pi->prev->next = pi->next;
421 else
422 bgp_dest_set_bgp_path_info(dest, pi->next);
423
424 bgp_path_info_mpath_dequeue(pi);
425 bgp_path_info_unlock(pi);
426 hook_call(bgp_snmp_update_stats, dest, pi, false);
427 bgp_dest_unlock_node(dest);
428 }
429
430 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
431 {
432 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
433 /* set of previous already took care of pcount */
434 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
435 }
436
437 /* undo the effects of a previous call to bgp_path_info_delete; typically
438 called when a route is deleted and then quickly re-added before the
439 deletion has been processed */
440 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
441 {
442 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
443 /* unset of previous already took care of pcount */
444 SET_FLAG(pi->flags, BGP_PATH_VALID);
445 }
446
447 /* Adjust pcount as required */
448 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
449 {
450 struct bgp_table *table;
451
452 assert(dest && bgp_dest_table(dest));
453 assert(pi && pi->peer && pi->peer->bgp);
454
455 table = bgp_dest_table(dest);
456
457 if (pi->peer == pi->peer->bgp->peer_self)
458 return;
459
460 if (!BGP_PATH_COUNTABLE(pi)
461 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
462
463 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
464
465 /* slight hack, but more robust against errors. */
466 if (pi->peer->pcount[table->afi][table->safi])
467 pi->peer->pcount[table->afi][table->safi]--;
468 else
469 flog_err(EC_LIB_DEVELOPMENT,
470 "Asked to decrement 0 prefix count for peer");
471 } else if (BGP_PATH_COUNTABLE(pi)
472 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
473 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
474 pi->peer->pcount[table->afi][table->safi]++;
475 }
476 }
477
478 static int bgp_label_index_differs(struct bgp_path_info *pi1,
479 struct bgp_path_info *pi2)
480 {
481 return (!(pi1->attr->label_index == pi2->attr->label_index));
482 }
483
484 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
485 * This is here primarily to keep prefix-count in check.
486 */
487 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
488 uint32_t flag)
489 {
490 SET_FLAG(pi->flags, flag);
491
492 /* early bath if we know it's not a flag that changes countability state
493 */
494 if (!CHECK_FLAG(flag,
495 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
496 return;
497
498 bgp_pcount_adjust(dest, pi);
499 }
500
501 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
502 uint32_t flag)
503 {
504 UNSET_FLAG(pi->flags, flag);
505
506 /* early bath if we know it's not a flag that changes countability state
507 */
508 if (!CHECK_FLAG(flag,
509 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
510 return;
511
512 bgp_pcount_adjust(dest, pi);
513 }
514
515 /* Get MED value. If MED value is missing and "bgp bestpath
516 missing-as-worst" is specified, treat it as the worst value. */
517 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
518 {
519 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
520 return attr->med;
521 else {
522 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
523 return BGP_MED_MAX;
524 else
525 return 0;
526 }
527 }
528
529 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
530 size_t buf_len)
531 {
532 if (pi->addpath_rx_id)
533 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
534 pi->peer->host, pi->addpath_rx_id);
535 else
536 snprintf(buf, buf_len, "path %s", pi->peer->host);
537 }
538
539
540 /*
541 * Get the ultimate path info.
542 */
543 struct bgp_path_info *bgp_get_imported_bpi_ultimate(struct bgp_path_info *info)
544 {
545 struct bgp_path_info *bpi_ultimate;
546
547 if (info->sub_type != BGP_ROUTE_IMPORTED)
548 return info;
549
550 for (bpi_ultimate = info;
551 bpi_ultimate->extra && bpi_ultimate->extra->parent;
552 bpi_ultimate = bpi_ultimate->extra->parent)
553 ;
554
555 return bpi_ultimate;
556 }
557
558 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
559 */
560 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
561 struct bgp_path_info *exist, int *paths_eq,
562 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
563 char *pfx_buf, afi_t afi, safi_t safi,
564 enum bgp_path_selection_reason *reason)
565 {
566 const struct prefix *new_p;
567 struct attr *newattr, *existattr;
568 bgp_peer_sort_t new_sort;
569 bgp_peer_sort_t exist_sort;
570 uint32_t new_pref;
571 uint32_t exist_pref;
572 uint32_t new_med;
573 uint32_t exist_med;
574 uint32_t new_weight;
575 uint32_t exist_weight;
576 uint32_t newm, existm;
577 struct in_addr new_id;
578 struct in_addr exist_id;
579 int new_cluster;
580 int exist_cluster;
581 int internal_as_route;
582 int confed_as_route;
583 int ret = 0;
584 int igp_metric_ret = 0;
585 int peer_sort_ret = -1;
586 char new_buf[PATH_ADDPATH_STR_BUFFER];
587 char exist_buf[PATH_ADDPATH_STR_BUFFER];
588 uint32_t new_mm_seq;
589 uint32_t exist_mm_seq;
590 int nh_cmp;
591 esi_t *exist_esi;
592 esi_t *new_esi;
593 bool same_esi;
594 bool old_proxy;
595 bool new_proxy;
596 bool new_origin, exist_origin;
597 struct bgp_path_info *bpi_ultimate;
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 /* 3. Local route check. We prefer:
875 * - BGP_ROUTE_STATIC
876 * - BGP_ROUTE_AGGREGATE
877 * - BGP_ROUTE_REDISTRIBUTE
878 */
879 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
880 new->sub_type == BGP_ROUTE_IMPORTED);
881 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
882 exist->sub_type == BGP_ROUTE_IMPORTED);
883
884 if (new_origin && !exist_origin) {
885 *reason = bgp_path_selection_local_route;
886 if (debug)
887 zlog_debug(
888 "%s: %s wins over %s due to preferred BGP_ROUTE type",
889 pfx_buf, new_buf, exist_buf);
890 return 1;
891 }
892
893 if (!new_origin && exist_origin) {
894 *reason = bgp_path_selection_local_route;
895 if (debug)
896 zlog_debug(
897 "%s: %s loses to %s due to preferred BGP_ROUTE type",
898 pfx_buf, new_buf, exist_buf);
899 return 0;
900 }
901
902 /* Here if these are imported routes then get ultimate pi for
903 * path compare.
904 */
905 new = bgp_get_imported_bpi_ultimate(new);
906 exist = bgp_get_imported_bpi_ultimate(exist);
907 newattr = new->attr;
908 existattr = exist->attr;
909
910 /* 4. AS path length check. */
911 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
912 int exist_hops = aspath_count_hops(existattr->aspath);
913 int exist_confeds = aspath_count_confeds(existattr->aspath);
914
915 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
916 int aspath_hops;
917
918 aspath_hops = aspath_count_hops(newattr->aspath);
919 aspath_hops += aspath_count_confeds(newattr->aspath);
920
921 if (aspath_hops < (exist_hops + exist_confeds)) {
922 *reason = bgp_path_selection_confed_as_path;
923 if (debug)
924 zlog_debug(
925 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
926 pfx_buf, new_buf, exist_buf,
927 aspath_hops,
928 (exist_hops + exist_confeds));
929 return 1;
930 }
931
932 if (aspath_hops > (exist_hops + exist_confeds)) {
933 *reason = bgp_path_selection_confed_as_path;
934 if (debug)
935 zlog_debug(
936 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
937 pfx_buf, new_buf, exist_buf,
938 aspath_hops,
939 (exist_hops + exist_confeds));
940 return 0;
941 }
942 } else {
943 int newhops = aspath_count_hops(newattr->aspath);
944
945 if (newhops < exist_hops) {
946 *reason = bgp_path_selection_as_path;
947 if (debug)
948 zlog_debug(
949 "%s: %s wins over %s due to aspath hopcount %d < %d",
950 pfx_buf, new_buf, exist_buf,
951 newhops, exist_hops);
952 return 1;
953 }
954
955 if (newhops > exist_hops) {
956 *reason = bgp_path_selection_as_path;
957 if (debug)
958 zlog_debug(
959 "%s: %s loses to %s due to aspath hopcount %d > %d",
960 pfx_buf, new_buf, exist_buf,
961 newhops, exist_hops);
962 return 0;
963 }
964 }
965 }
966
967 /* 5. Origin check. */
968 if (newattr->origin < existattr->origin) {
969 *reason = bgp_path_selection_origin;
970 if (debug)
971 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
972 pfx_buf, new_buf, exist_buf,
973 bgp_origin_long_str[newattr->origin],
974 bgp_origin_long_str[existattr->origin]);
975 return 1;
976 }
977
978 if (newattr->origin > existattr->origin) {
979 *reason = bgp_path_selection_origin;
980 if (debug)
981 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
982 pfx_buf, new_buf, exist_buf,
983 bgp_origin_long_str[newattr->origin],
984 bgp_origin_long_str[existattr->origin]);
985 return 0;
986 }
987
988 /* 6. MED check. */
989 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
990 && aspath_count_hops(existattr->aspath) == 0);
991 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
992 && aspath_count_confeds(existattr->aspath) > 0
993 && aspath_count_hops(newattr->aspath) == 0
994 && aspath_count_hops(existattr->aspath) == 0);
995
996 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
997 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
998 || aspath_cmp_left(newattr->aspath, existattr->aspath)
999 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
1000 || internal_as_route) {
1001 new_med = bgp_med_value(new->attr, bgp);
1002 exist_med = bgp_med_value(exist->attr, bgp);
1003
1004 if (new_med < exist_med) {
1005 *reason = bgp_path_selection_med;
1006 if (debug)
1007 zlog_debug(
1008 "%s: %s wins over %s due to MED %d < %d",
1009 pfx_buf, new_buf, exist_buf, new_med,
1010 exist_med);
1011 return 1;
1012 }
1013
1014 if (new_med > exist_med) {
1015 *reason = bgp_path_selection_med;
1016 if (debug)
1017 zlog_debug(
1018 "%s: %s loses to %s due to MED %d > %d",
1019 pfx_buf, new_buf, exist_buf, new_med,
1020 exist_med);
1021 return 0;
1022 }
1023 }
1024
1025 /* 7. Peer type check. */
1026 new_sort = new->peer->sort;
1027 exist_sort = exist->peer->sort;
1028
1029 if (new_sort == BGP_PEER_EBGP
1030 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1031 *reason = bgp_path_selection_peer;
1032 if (debug)
1033 zlog_debug(
1034 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1035 pfx_buf, new_buf, exist_buf);
1036 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1037 return 1;
1038 peer_sort_ret = 1;
1039 }
1040
1041 if (exist_sort == BGP_PEER_EBGP
1042 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1043 *reason = bgp_path_selection_peer;
1044 if (debug)
1045 zlog_debug(
1046 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1047 pfx_buf, new_buf, exist_buf);
1048 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1049 return 0;
1050 peer_sort_ret = 0;
1051 }
1052
1053 /* 8. IGP metric check. */
1054 newm = existm = 0;
1055
1056 if (new->extra)
1057 newm = new->extra->igpmetric;
1058 if (exist->extra)
1059 existm = exist->extra->igpmetric;
1060
1061 if (newm < existm) {
1062 if (debug && peer_sort_ret < 0)
1063 zlog_debug(
1064 "%s: %s wins over %s due to IGP metric %u < %u",
1065 pfx_buf, new_buf, exist_buf, newm, existm);
1066 igp_metric_ret = 1;
1067 }
1068
1069 if (newm > existm) {
1070 if (debug && peer_sort_ret < 0)
1071 zlog_debug(
1072 "%s: %s loses to %s due to IGP metric %u > %u",
1073 pfx_buf, new_buf, exist_buf, newm, existm);
1074 igp_metric_ret = 0;
1075 }
1076
1077 /* 9. Same IGP metric. Compare the cluster list length as
1078 representative of IGP hops metric. Rewrite the metric value
1079 pair (newm, existm) with the cluster list length. Prefer the
1080 path with smaller cluster list length. */
1081 if (newm == existm) {
1082 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
1083 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
1084 && (mpath_cfg == NULL
1085 || CHECK_FLAG(
1086 mpath_cfg->ibgp_flags,
1087 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
1088 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1089 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1090
1091 if (newm < existm) {
1092 if (debug && peer_sort_ret < 0)
1093 zlog_debug(
1094 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1095 pfx_buf, new_buf, exist_buf,
1096 newm, existm);
1097 igp_metric_ret = 1;
1098 }
1099
1100 if (newm > existm) {
1101 if (debug && peer_sort_ret < 0)
1102 zlog_debug(
1103 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1104 pfx_buf, new_buf, exist_buf,
1105 newm, existm);
1106 igp_metric_ret = 0;
1107 }
1108 }
1109 }
1110
1111 /* 10. confed-external vs. confed-internal */
1112 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1113 if (new_sort == BGP_PEER_CONFED
1114 && exist_sort == BGP_PEER_IBGP) {
1115 *reason = bgp_path_selection_confed;
1116 if (debug)
1117 zlog_debug(
1118 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1119 pfx_buf, new_buf, exist_buf);
1120 if (!CHECK_FLAG(bgp->flags,
1121 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1122 return 1;
1123 peer_sort_ret = 1;
1124 }
1125
1126 if (exist_sort == BGP_PEER_CONFED
1127 && new_sort == BGP_PEER_IBGP) {
1128 *reason = bgp_path_selection_confed;
1129 if (debug)
1130 zlog_debug(
1131 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1132 pfx_buf, new_buf, exist_buf);
1133 if (!CHECK_FLAG(bgp->flags,
1134 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1135 return 0;
1136 peer_sort_ret = 0;
1137 }
1138 }
1139
1140 /* 11. Maximum path check. */
1141 if (newm == existm) {
1142 /* If one path has a label but the other does not, do not treat
1143 * them as equals for multipath
1144 */
1145 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1146 != (exist->extra
1147 && bgp_is_valid_label(&exist->extra->label[0]))) {
1148 if (debug)
1149 zlog_debug(
1150 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1151 pfx_buf, new_buf, exist_buf);
1152 } else if (CHECK_FLAG(bgp->flags,
1153 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1154
1155 /*
1156 * For the two paths, all comparison steps till IGP
1157 * metric
1158 * have succeeded - including AS_PATH hop count. Since
1159 * 'bgp
1160 * bestpath as-path multipath-relax' knob is on, we
1161 * don't need
1162 * an exact match of AS_PATH. Thus, mark the paths are
1163 * equal.
1164 * That will trigger both these paths to get into the
1165 * multipath
1166 * array.
1167 */
1168 *paths_eq = 1;
1169
1170 if (debug)
1171 zlog_debug(
1172 "%s: %s and %s are equal via multipath-relax",
1173 pfx_buf, new_buf, exist_buf);
1174 } else if (new->peer->sort == BGP_PEER_IBGP) {
1175 if (aspath_cmp(new->attr->aspath,
1176 exist->attr->aspath)) {
1177 *paths_eq = 1;
1178
1179 if (debug)
1180 zlog_debug(
1181 "%s: %s and %s are equal via matching aspaths",
1182 pfx_buf, new_buf, exist_buf);
1183 }
1184 } else if (new->peer->as == exist->peer->as) {
1185 *paths_eq = 1;
1186
1187 if (debug)
1188 zlog_debug(
1189 "%s: %s and %s are equal via same remote-as",
1190 pfx_buf, new_buf, exist_buf);
1191 }
1192 } else {
1193 /*
1194 * TODO: If unequal cost ibgp multipath is enabled we can
1195 * mark the paths as equal here instead of returning
1196 */
1197
1198 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1199 * if either step 7 or 10 (peer type checks) yielded a winner,
1200 * that result was returned immediately. Returning from step 10
1201 * ignored the return value computed in steps 8 and 9 (IGP
1202 * metric checks). In order to preserve that behavior, if
1203 * peer_sort_ret is set, return that rather than igp_metric_ret.
1204 */
1205 ret = peer_sort_ret;
1206 if (peer_sort_ret < 0) {
1207 ret = igp_metric_ret;
1208 if (debug) {
1209 if (ret == 1)
1210 zlog_debug(
1211 "%s: %s wins over %s after IGP metric comparison",
1212 pfx_buf, new_buf, exist_buf);
1213 else
1214 zlog_debug(
1215 "%s: %s loses to %s after IGP metric comparison",
1216 pfx_buf, new_buf, exist_buf);
1217 }
1218 *reason = bgp_path_selection_igp_metric;
1219 }
1220 return ret;
1221 }
1222
1223 /*
1224 * At this point, the decision whether to set *paths_eq = 1 has been
1225 * completed. If we deferred returning because of bestpath peer-type
1226 * relax configuration, return now.
1227 */
1228 if (peer_sort_ret >= 0)
1229 return peer_sort_ret;
1230
1231 /* 12. If both paths are external, prefer the path that was received
1232 first (the oldest one). This step minimizes route-flap, since a
1233 newer path won't displace an older one, even if it was the
1234 preferred route based on the additional decision criteria below. */
1235 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1236 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1237 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1238 *reason = bgp_path_selection_older;
1239 if (debug)
1240 zlog_debug(
1241 "%s: %s wins over %s due to oldest external",
1242 pfx_buf, new_buf, exist_buf);
1243 return 1;
1244 }
1245
1246 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1247 *reason = bgp_path_selection_older;
1248 if (debug)
1249 zlog_debug(
1250 "%s: %s loses to %s due to oldest external",
1251 pfx_buf, new_buf, exist_buf);
1252 return 0;
1253 }
1254 }
1255
1256 /* 13. Router-ID comparision. */
1257 /* If one of the paths is "stale", the corresponding peer router-id will
1258 * be 0 and would always win over the other path. If originator id is
1259 * used for the comparision, it will decide which path is better.
1260 */
1261 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1262 new_id.s_addr = newattr->originator_id.s_addr;
1263 else
1264 new_id.s_addr = new->peer->remote_id.s_addr;
1265 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1266 exist_id.s_addr = existattr->originator_id.s_addr;
1267 else
1268 exist_id.s_addr = exist->peer->remote_id.s_addr;
1269
1270 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1271 *reason = bgp_path_selection_router_id;
1272 if (debug)
1273 zlog_debug(
1274 "%s: %s wins over %s due to Router-ID comparison",
1275 pfx_buf, new_buf, exist_buf);
1276 return 1;
1277 }
1278
1279 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1280 *reason = bgp_path_selection_router_id;
1281 if (debug)
1282 zlog_debug(
1283 "%s: %s loses to %s due to Router-ID comparison",
1284 pfx_buf, new_buf, exist_buf);
1285 return 0;
1286 }
1287
1288 /* 14. Cluster length comparision. */
1289 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1290 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1291
1292 if (new_cluster < exist_cluster) {
1293 *reason = bgp_path_selection_cluster_length;
1294 if (debug)
1295 zlog_debug(
1296 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1297 pfx_buf, new_buf, exist_buf, new_cluster,
1298 exist_cluster);
1299 return 1;
1300 }
1301
1302 if (new_cluster > exist_cluster) {
1303 *reason = bgp_path_selection_cluster_length;
1304 if (debug)
1305 zlog_debug(
1306 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1307 pfx_buf, new_buf, exist_buf, new_cluster,
1308 exist_cluster);
1309 return 0;
1310 }
1311
1312 /* 15. Neighbor address comparision. */
1313 /* Do this only if neither path is "stale" as stale paths do not have
1314 * valid peer information (as the connection may or may not be up).
1315 */
1316 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1317 *reason = bgp_path_selection_stale;
1318 if (debug)
1319 zlog_debug(
1320 "%s: %s wins over %s due to latter path being STALE",
1321 pfx_buf, new_buf, exist_buf);
1322 return 1;
1323 }
1324
1325 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1326 *reason = bgp_path_selection_stale;
1327 if (debug)
1328 zlog_debug(
1329 "%s: %s loses to %s due to former path being STALE",
1330 pfx_buf, new_buf, exist_buf);
1331 return 0;
1332 }
1333
1334 /* locally configured routes to advertise do not have su_remote */
1335 if (new->peer->su_remote == NULL) {
1336 *reason = bgp_path_selection_local_configured;
1337 return 0;
1338 }
1339 if (exist->peer->su_remote == NULL) {
1340 *reason = bgp_path_selection_local_configured;
1341 return 1;
1342 }
1343
1344 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1345
1346 if (ret == 1) {
1347 *reason = bgp_path_selection_neighbor_ip;
1348 if (debug)
1349 zlog_debug(
1350 "%s: %s loses to %s due to Neighor IP comparison",
1351 pfx_buf, new_buf, exist_buf);
1352 return 0;
1353 }
1354
1355 if (ret == -1) {
1356 *reason = bgp_path_selection_neighbor_ip;
1357 if (debug)
1358 zlog_debug(
1359 "%s: %s wins over %s due to Neighor IP comparison",
1360 pfx_buf, new_buf, exist_buf);
1361 return 1;
1362 }
1363
1364 *reason = bgp_path_selection_default;
1365 if (debug)
1366 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1367 pfx_buf, new_buf, exist_buf);
1368
1369 return 1;
1370 }
1371
1372
1373 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1374 struct bgp_path_info *exist, int *paths_eq)
1375 {
1376 enum bgp_path_selection_reason reason;
1377 char pfx_buf[PREFIX2STR_BUFFER];
1378
1379 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1380 AFI_L2VPN, SAFI_EVPN, &reason);
1381 }
1382
1383 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1384 * is preferred, or 0 if they are the same (usually will only occur if
1385 * multipath is enabled
1386 * This version is compatible with */
1387 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1388 struct bgp_path_info *exist, char *pfx_buf,
1389 afi_t afi, safi_t safi,
1390 enum bgp_path_selection_reason *reason)
1391 {
1392 int paths_eq;
1393 int ret;
1394 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1395 afi, safi, reason);
1396
1397 if (paths_eq)
1398 ret = 0;
1399 else {
1400 if (ret == 1)
1401 ret = -1;
1402 else
1403 ret = 1;
1404 }
1405 return ret;
1406 }
1407
1408 static enum filter_type bgp_input_filter(struct peer *peer,
1409 const struct prefix *p,
1410 struct attr *attr, afi_t afi,
1411 safi_t safi)
1412 {
1413 struct bgp_filter *filter;
1414 enum filter_type ret = FILTER_PERMIT;
1415
1416 filter = &peer->filter[afi][safi];
1417
1418 #define FILTER_EXIST_WARN(F, f, filter) \
1419 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1420 zlog_debug("%s: Could not find configured input %s-list %s!", \
1421 peer->host, #f, F##_IN_NAME(filter));
1422
1423 if (DISTRIBUTE_IN_NAME(filter)) {
1424 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1425
1426 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1427 == FILTER_DENY) {
1428 ret = FILTER_DENY;
1429 goto done;
1430 }
1431 }
1432
1433 if (PREFIX_LIST_IN_NAME(filter)) {
1434 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1435
1436 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1437 == PREFIX_DENY) {
1438 ret = FILTER_DENY;
1439 goto done;
1440 }
1441 }
1442
1443 if (FILTER_LIST_IN_NAME(filter)) {
1444 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1445
1446 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1447 == AS_FILTER_DENY) {
1448 ret = FILTER_DENY;
1449 goto done;
1450 }
1451 }
1452
1453 done:
1454 if (frrtrace_enabled(frr_bgp, input_filter)) {
1455 char pfxprint[PREFIX2STR_BUFFER];
1456
1457 prefix2str(p, pfxprint, sizeof(pfxprint));
1458 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1459 ret == FILTER_PERMIT ? "permit" : "deny");
1460 }
1461
1462 return ret;
1463 #undef FILTER_EXIST_WARN
1464 }
1465
1466 static enum filter_type bgp_output_filter(struct peer *peer,
1467 const struct prefix *p,
1468 struct attr *attr, afi_t afi,
1469 safi_t safi)
1470 {
1471 struct bgp_filter *filter;
1472 enum filter_type ret = FILTER_PERMIT;
1473
1474 filter = &peer->filter[afi][safi];
1475
1476 #define FILTER_EXIST_WARN(F, f, filter) \
1477 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1478 zlog_debug("%s: Could not find configured output %s-list %s!", \
1479 peer->host, #f, F##_OUT_NAME(filter));
1480
1481 if (DISTRIBUTE_OUT_NAME(filter)) {
1482 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1483
1484 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1485 == FILTER_DENY) {
1486 ret = FILTER_DENY;
1487 goto done;
1488 }
1489 }
1490
1491 if (PREFIX_LIST_OUT_NAME(filter)) {
1492 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1493
1494 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1495 == PREFIX_DENY) {
1496 ret = FILTER_DENY;
1497 goto done;
1498 }
1499 }
1500
1501 if (FILTER_LIST_OUT_NAME(filter)) {
1502 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1503
1504 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1505 == AS_FILTER_DENY) {
1506 ret = FILTER_DENY;
1507 goto done;
1508 }
1509 }
1510
1511 if (frrtrace_enabled(frr_bgp, output_filter)) {
1512 char pfxprint[PREFIX2STR_BUFFER];
1513
1514 prefix2str(p, pfxprint, sizeof(pfxprint));
1515 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1516 ret == FILTER_PERMIT ? "permit" : "deny");
1517 }
1518
1519 done:
1520 return ret;
1521 #undef FILTER_EXIST_WARN
1522 }
1523
1524 /* If community attribute includes no_export then return 1. */
1525 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1526 {
1527 if (bgp_attr_get_community(attr)) {
1528 /* NO_ADVERTISE check. */
1529 if (community_include(bgp_attr_get_community(attr),
1530 COMMUNITY_NO_ADVERTISE))
1531 return true;
1532
1533 /* NO_EXPORT check. */
1534 if (peer->sort == BGP_PEER_EBGP &&
1535 community_include(bgp_attr_get_community(attr),
1536 COMMUNITY_NO_EXPORT))
1537 return true;
1538
1539 /* NO_EXPORT_SUBCONFED check. */
1540 if (peer->sort == BGP_PEER_EBGP
1541 || peer->sort == BGP_PEER_CONFED)
1542 if (community_include(bgp_attr_get_community(attr),
1543 COMMUNITY_NO_EXPORT_SUBCONFED))
1544 return true;
1545 }
1546 return false;
1547 }
1548
1549 /* Route reflection loop check. */
1550 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1551 {
1552 struct in_addr cluster_id;
1553 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1554
1555 if (cluster) {
1556 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1557 cluster_id = peer->bgp->cluster_id;
1558 else
1559 cluster_id = peer->bgp->router_id;
1560
1561 if (cluster_loop_check(cluster, cluster_id))
1562 return true;
1563 }
1564 return false;
1565 }
1566
1567 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1568 struct attr *attr, afi_t afi, safi_t safi,
1569 const char *rmap_name, mpls_label_t *label,
1570 uint32_t num_labels, struct bgp_dest *dest)
1571 {
1572 struct bgp_filter *filter;
1573 struct bgp_path_info rmap_path = { 0 };
1574 struct bgp_path_info_extra extra = { 0 };
1575 route_map_result_t ret;
1576 struct route_map *rmap = NULL;
1577
1578 filter = &peer->filter[afi][safi];
1579
1580 /* Apply default weight value. */
1581 if (peer->weight[afi][safi])
1582 attr->weight = peer->weight[afi][safi];
1583
1584 if (rmap_name) {
1585 rmap = route_map_lookup_by_name(rmap_name);
1586
1587 if (rmap == NULL)
1588 return RMAP_DENY;
1589 } else {
1590 if (ROUTE_MAP_IN_NAME(filter)) {
1591 rmap = ROUTE_MAP_IN(filter);
1592
1593 if (rmap == NULL)
1594 return RMAP_DENY;
1595 }
1596 }
1597
1598 /* Route map apply. */
1599 if (rmap) {
1600 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1601 /* Duplicate current value to new strucutre for modification. */
1602 rmap_path.peer = peer;
1603 rmap_path.attr = attr;
1604 rmap_path.extra = &extra;
1605 rmap_path.net = dest;
1606
1607 extra.num_labels = num_labels;
1608 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1609 memcpy(extra.label, label,
1610 num_labels * sizeof(mpls_label_t));
1611
1612 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1613
1614 /* Apply BGP route map to the attribute. */
1615 ret = route_map_apply(rmap, p, &rmap_path);
1616
1617 peer->rmap_type = 0;
1618
1619 if (ret == RMAP_DENYMATCH)
1620 return RMAP_DENY;
1621 }
1622 return RMAP_PERMIT;
1623 }
1624
1625 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1626 struct attr *attr, afi_t afi, safi_t safi,
1627 const char *rmap_name)
1628 {
1629 struct bgp_path_info rmap_path;
1630 route_map_result_t ret;
1631 struct route_map *rmap = NULL;
1632 uint8_t rmap_type;
1633
1634 /*
1635 * So if we get to this point and have no rmap_name
1636 * we want to just show the output as it currently
1637 * exists.
1638 */
1639 if (!rmap_name)
1640 return RMAP_PERMIT;
1641
1642 /* Apply default weight value. */
1643 if (peer->weight[afi][safi])
1644 attr->weight = peer->weight[afi][safi];
1645
1646 rmap = route_map_lookup_by_name(rmap_name);
1647
1648 /*
1649 * If we have a route map name and we do not find
1650 * the routemap that means we have an implicit
1651 * deny.
1652 */
1653 if (rmap == NULL)
1654 return RMAP_DENY;
1655
1656 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1657 /* Route map apply. */
1658 /* Duplicate current value to new strucutre for modification. */
1659 rmap_path.peer = peer;
1660 rmap_path.attr = attr;
1661
1662 rmap_type = peer->rmap_type;
1663 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1664
1665 /* Apply BGP route map to the attribute. */
1666 ret = route_map_apply(rmap, p, &rmap_path);
1667
1668 peer->rmap_type = rmap_type;
1669
1670 if (ret == RMAP_DENYMATCH)
1671 /*
1672 * caller has multiple error paths with bgp_attr_flush()
1673 */
1674 return RMAP_DENY;
1675
1676 return RMAP_PERMIT;
1677 }
1678
1679 /* If this is an EBGP peer with remove-private-AS */
1680 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1681 struct peer *peer, struct attr *attr)
1682 {
1683 if (peer->sort == BGP_PEER_EBGP
1684 && (peer_af_flag_check(peer, afi, safi,
1685 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1686 || peer_af_flag_check(peer, afi, safi,
1687 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1688 || peer_af_flag_check(peer, afi, safi,
1689 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1690 || peer_af_flag_check(peer, afi, safi,
1691 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1692 // Take action on the entire aspath
1693 if (peer_af_flag_check(peer, afi, safi,
1694 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1695 || peer_af_flag_check(peer, afi, safi,
1696 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1697 if (peer_af_flag_check(
1698 peer, afi, safi,
1699 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1700 attr->aspath = aspath_replace_private_asns(
1701 attr->aspath, bgp->as, peer->as);
1702
1703 /*
1704 * Even if the aspath consists of just private ASNs we
1705 * need to walk the AS-Path to maintain all instances
1706 * of the peer's ASN to break possible loops.
1707 */
1708 else
1709 attr->aspath = aspath_remove_private_asns(
1710 attr->aspath, peer->as);
1711 }
1712
1713 // 'all' was not specified so the entire aspath must be private
1714 // ASNs
1715 // for us to do anything
1716 else if (aspath_private_as_check(attr->aspath)) {
1717 if (peer_af_flag_check(
1718 peer, afi, safi,
1719 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1720 attr->aspath = aspath_replace_private_asns(
1721 attr->aspath, bgp->as, peer->as);
1722 else
1723 /*
1724 * Walk the aspath to retain any instances of
1725 * the peer_asn
1726 */
1727 attr->aspath = aspath_remove_private_asns(
1728 attr->aspath, peer->as);
1729 }
1730 }
1731 }
1732
1733 /* If this is an EBGP peer with as-override */
1734 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1735 struct peer *peer, struct attr *attr)
1736 {
1737 if (peer->sort == BGP_PEER_EBGP
1738 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1739 if (aspath_single_asn_check(attr->aspath, peer->as))
1740 attr->aspath = aspath_replace_specific_asn(
1741 attr->aspath, peer->as, bgp->as);
1742 }
1743 }
1744
1745 void bgp_attr_add_llgr_community(struct attr *attr)
1746 {
1747 struct community *old;
1748 struct community *new;
1749 struct community *merge;
1750 struct community *llgr;
1751
1752 old = bgp_attr_get_community(attr);
1753 llgr = community_str2com("llgr-stale");
1754
1755 assert(llgr);
1756
1757 if (old) {
1758 merge = community_merge(community_dup(old), llgr);
1759
1760 if (old->refcnt == 0)
1761 community_free(&old);
1762
1763 new = community_uniq_sort(merge);
1764 community_free(&merge);
1765 } else {
1766 new = community_dup(llgr);
1767 }
1768
1769 community_free(&llgr);
1770
1771 bgp_attr_set_community(attr, new);
1772 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1773 }
1774
1775 void bgp_attr_add_gshut_community(struct attr *attr)
1776 {
1777 struct community *old;
1778 struct community *new;
1779 struct community *merge;
1780 struct community *gshut;
1781
1782 old = bgp_attr_get_community(attr);
1783 gshut = community_str2com("graceful-shutdown");
1784
1785 assert(gshut);
1786
1787 if (old) {
1788 merge = community_merge(community_dup(old), gshut);
1789
1790 if (old->refcnt == 0)
1791 community_free(&old);
1792
1793 new = community_uniq_sort(merge);
1794 community_free(&merge);
1795 } else {
1796 new = community_dup(gshut);
1797 }
1798
1799 community_free(&gshut);
1800 bgp_attr_set_community(attr, new);
1801 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1802
1803 /* When we add the graceful-shutdown community we must also
1804 * lower the local-preference */
1805 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1806 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1807 }
1808
1809
1810 /* Notify BGP Conditional advertisement scanner process. */
1811 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1812 {
1813 struct peer *peer = SUBGRP_PEER(subgrp);
1814 afi_t afi = SUBGRP_AFI(subgrp);
1815 safi_t safi = SUBGRP_SAFI(subgrp);
1816 struct bgp_filter *filter = &peer->filter[afi][safi];
1817
1818 if (!ADVERTISE_MAP_NAME(filter))
1819 return;
1820
1821 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1822 return;
1823
1824 peer->advmap_table_change = true;
1825 }
1826
1827
1828 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1829 {
1830 if (family == AF_INET) {
1831 attr->nexthop.s_addr = INADDR_ANY;
1832 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1833 }
1834 if (family == AF_INET6)
1835 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1836 if (family == AF_EVPN)
1837 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1838 }
1839
1840 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1841 struct update_subgroup *subgrp,
1842 const struct prefix *p, struct attr *attr,
1843 struct attr *post_attr)
1844 {
1845 struct bgp_filter *filter;
1846 struct peer *from;
1847 struct peer *peer;
1848 struct peer *onlypeer;
1849 struct bgp *bgp;
1850 struct attr *piattr;
1851 route_map_result_t ret;
1852 int transparent;
1853 int reflect;
1854 afi_t afi;
1855 safi_t safi;
1856 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1857 bool nh_reset = false;
1858 uint64_t cum_bw;
1859
1860 if (DISABLE_BGP_ANNOUNCE)
1861 return false;
1862
1863 afi = SUBGRP_AFI(subgrp);
1864 safi = SUBGRP_SAFI(subgrp);
1865 peer = SUBGRP_PEER(subgrp);
1866 onlypeer = NULL;
1867 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1868 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1869
1870 from = pi->peer;
1871 filter = &peer->filter[afi][safi];
1872 bgp = SUBGRP_INST(subgrp);
1873 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1874 : pi->attr;
1875
1876 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_OUT) &&
1877 peer->pmax_out[afi][safi] != 0 &&
1878 subgrp->pscount >= peer->pmax_out[afi][safi]) {
1879 if (BGP_DEBUG(update, UPDATE_OUT) ||
1880 BGP_DEBUG(update, UPDATE_PREFIX)) {
1881 zlog_debug("%s reached maximum prefix to be send (%u)",
1882 peer->host, peer->pmax_out[afi][safi]);
1883 }
1884 return false;
1885 }
1886
1887 #ifdef ENABLE_BGP_VNC
1888 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1889 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1890 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1891
1892 /*
1893 * direct and direct_ext type routes originate internally even
1894 * though they can have peer pointers that reference other
1895 * systems
1896 */
1897 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1898 __func__, p);
1899 samepeer_safe = 1;
1900 }
1901 #endif
1902
1903 if (((afi == AFI_IP) || (afi == AFI_IP6))
1904 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1905 && (pi->type == ZEBRA_ROUTE_BGP)
1906 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1907
1908 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1909
1910 samepeer_safe = 1;
1911 }
1912
1913 /* With addpath we may be asked to TX all kinds of paths so make sure
1914 * pi is valid */
1915 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1916 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1917 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1918 return false;
1919 }
1920
1921 /* If this is not the bestpath then check to see if there is an enabled
1922 * addpath
1923 * feature that requires us to advertise it */
1924 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1925 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1926 return false;
1927 }
1928 }
1929
1930 /* Aggregate-address suppress check. */
1931 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1932 return false;
1933
1934 /*
1935 * If we are doing VRF 2 VRF leaking via the import
1936 * statement, we want to prevent the route going
1937 * off box as that the RT and RD created are localy
1938 * significant and globaly useless.
1939 */
1940 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1941 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1942 return false;
1943
1944 /* If it's labeled safi, make sure the route has a valid label. */
1945 if (safi == SAFI_LABELED_UNICAST) {
1946 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1947 if (!bgp_is_valid_label(&label)) {
1948 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1949 zlog_debug("u%" PRIu64 ":s%" PRIu64
1950 " %pFX is filtered - no label (%p)",
1951 subgrp->update_group->id, subgrp->id,
1952 p, &label);
1953 return false;
1954 }
1955 }
1956
1957 /* Do not send back route to sender. */
1958 if (onlypeer && from == onlypeer) {
1959 return false;
1960 }
1961
1962 /* Do not send the default route in the BGP table if the neighbor is
1963 * configured for default-originate */
1964 if (CHECK_FLAG(peer->af_flags[afi][safi],
1965 PEER_FLAG_DEFAULT_ORIGINATE)) {
1966 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1967 return false;
1968 else if (p->family == AF_INET6 && p->prefixlen == 0)
1969 return false;
1970 }
1971
1972 /* Transparency check. */
1973 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1974 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1975 transparent = 1;
1976 else
1977 transparent = 0;
1978
1979 /* If community is not disabled check the no-export and local. */
1980 if (!transparent && bgp_community_filter(peer, piattr)) {
1981 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1982 zlog_debug("%s: community filter check fail for %pFX",
1983 __func__, p);
1984 return false;
1985 }
1986
1987 /* If the attribute has originator-id and it is same as remote
1988 peer's id. */
1989 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1990 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1991 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1992 zlog_debug(
1993 "%s [Update:SEND] %pFX originator-id is same as remote router-id",
1994 onlypeer->host, p);
1995 return false;
1996 }
1997
1998 /* ORF prefix-list filter check */
1999 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
2000 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
2001 || CHECK_FLAG(peer->af_cap[afi][safi],
2002 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
2003 if (peer->orf_plist[afi][safi]) {
2004 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
2005 == PREFIX_DENY) {
2006 if (bgp_debug_update(NULL, p,
2007 subgrp->update_group, 0))
2008 zlog_debug(
2009 "%s [Update:SEND] %pFX is filtered via ORF",
2010 peer->host, p);
2011 return false;
2012 }
2013 }
2014
2015 /* Output filter check. */
2016 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
2017 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2018 zlog_debug("%s [Update:SEND] %pFX is filtered",
2019 peer->host, p);
2020 return false;
2021 }
2022
2023 /* AS path loop check. */
2024 if (onlypeer && onlypeer->as_path_loop_detection
2025 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2026 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2027 zlog_debug(
2028 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2029 onlypeer->host, onlypeer->as);
2030 return false;
2031 }
2032
2033 /* If we're a CONFED we need to loop check the CONFED ID too */
2034 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2035 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
2036 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2037 zlog_debug(
2038 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
2039 peer->host, bgp->confed_id);
2040 return false;
2041 }
2042 }
2043
2044 /* Route-Reflect check. */
2045 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2046 reflect = 1;
2047 else
2048 reflect = 0;
2049
2050 /* IBGP reflection check. */
2051 if (reflect && !samepeer_safe) {
2052 /* A route from a Client peer. */
2053 if (CHECK_FLAG(from->af_flags[afi][safi],
2054 PEER_FLAG_REFLECTOR_CLIENT)) {
2055 /* Reflect to all the Non-Client peers and also to the
2056 Client peers other than the originator. Originator
2057 check
2058 is already done. So there is noting to do. */
2059 /* no bgp client-to-client reflection check. */
2060 if (CHECK_FLAG(bgp->flags,
2061 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2062 if (CHECK_FLAG(peer->af_flags[afi][safi],
2063 PEER_FLAG_REFLECTOR_CLIENT))
2064 return false;
2065 } else {
2066 /* A route from a Non-client peer. Reflect to all other
2067 clients. */
2068 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2069 PEER_FLAG_REFLECTOR_CLIENT))
2070 return false;
2071 }
2072 }
2073
2074 /* For modify attribute, copy it to temporary structure.
2075 * post_attr comes from BGP conditional advertisements, where
2076 * attributes are already processed by advertise-map route-map,
2077 * and this needs to be saved instead of overwriting from the
2078 * path attributes.
2079 */
2080 if (post_attr)
2081 *attr = *post_attr;
2082 else
2083 *attr = *piattr;
2084
2085 /* If local-preference is not set. */
2086 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2087 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2088 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2089 attr->local_pref = bgp->default_local_pref;
2090 }
2091
2092 /* If originator-id is not set and the route is to be reflected,
2093 set the originator id */
2094 if (reflect
2095 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2096 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2097 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2098 }
2099
2100 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2101 */
2102 if (peer->sort == BGP_PEER_EBGP
2103 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2104 if (from != bgp->peer_self && !transparent
2105 && !CHECK_FLAG(peer->af_flags[afi][safi],
2106 PEER_FLAG_MED_UNCHANGED))
2107 attr->flag &=
2108 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2109 }
2110
2111 /* Since the nexthop attribute can vary per peer, it is not explicitly
2112 * set
2113 * in announce check, only certain flags and length (or number of
2114 * nexthops
2115 * -- for IPv6/MP_REACH) are set here in order to guide the update
2116 * formation
2117 * code in setting the nexthop(s) on a per peer basis in
2118 * reformat_peer().
2119 * Typically, the source nexthop in the attribute is preserved but in
2120 * the
2121 * scenarios where we know it will always be overwritten, we reset the
2122 * nexthop to "0" in an attempt to achieve better Update packing. An
2123 * example of this is when a prefix from each of 2 IBGP peers needs to
2124 * be
2125 * announced to an EBGP peer (and they have the same attributes barring
2126 * their nexthop).
2127 */
2128 if (reflect)
2129 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2130
2131 #define NEXTHOP_IS_V6 \
2132 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2133 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2134 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2135 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2136
2137 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2138 * if
2139 * the peer (group) is configured to receive link-local nexthop
2140 * unchanged
2141 * and it is available in the prefix OR we're not reflecting the route,
2142 * link-local nexthop address is valid and
2143 * the peer (group) to whom we're going to announce is on a shared
2144 * network
2145 * and this is either a self-originated route or the peer is EBGP.
2146 * By checking if nexthop LL address is valid we are sure that
2147 * we do not announce LL address as `::`.
2148 */
2149 if (NEXTHOP_IS_V6) {
2150 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2151 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2152 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2153 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2154 || (!reflect && !transparent
2155 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2156 && peer->shared_network
2157 && (from == bgp->peer_self
2158 || peer->sort == BGP_PEER_EBGP))) {
2159 attr->mp_nexthop_len =
2160 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2161 }
2162
2163 /* Clear off link-local nexthop in source, whenever it is not
2164 * needed to
2165 * ensure more prefixes share the same attribute for
2166 * announcement.
2167 */
2168 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2169 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2170 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2171 }
2172
2173 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2174 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2175
2176 /* Route map & unsuppress-map apply. */
2177 if (!post_attr &&
2178 (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2179 struct bgp_path_info rmap_path = {0};
2180 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2181 struct attr dummy_attr = {0};
2182
2183 /* Fill temp path_info */
2184 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2185 pi, peer, attr);
2186
2187 /* don't confuse inbound and outbound setting */
2188 RESET_FLAG(attr->rmap_change_flags);
2189
2190 /*
2191 * The route reflector is not allowed to modify the attributes
2192 * of the reflected IBGP routes unless explicitly allowed.
2193 */
2194 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2195 && !CHECK_FLAG(bgp->flags,
2196 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2197 dummy_attr = *attr;
2198 rmap_path.attr = &dummy_attr;
2199 }
2200
2201 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2202
2203 if (bgp_path_suppressed(pi))
2204 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2205 &rmap_path);
2206 else
2207 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2208 &rmap_path);
2209
2210 peer->rmap_type = 0;
2211
2212 if (ret == RMAP_DENYMATCH) {
2213 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2214 zlog_debug(
2215 "%s [Update:SEND] %pFX is filtered by route-map '%s'",
2216 peer->host, p,
2217 ROUTE_MAP_OUT_NAME(filter));
2218
2219 bgp_attr_flush(&dummy_attr);
2220 return false;
2221 }
2222 }
2223
2224 /* RFC 8212 to prevent route leaks.
2225 * This specification intends to improve this situation by requiring the
2226 * explicit configuration of both BGP Import and Export Policies for any
2227 * External BGP (EBGP) session such as customers, peers, or
2228 * confederation boundaries for all enabled address families. Through
2229 * codification of the aforementioned requirement, operators will
2230 * benefit from consistent behavior across different BGP
2231 * implementations.
2232 */
2233 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2234 if (!bgp_outbound_policy_exists(peer, filter)) {
2235 if (monotime_since(&bgp->ebgprequirespolicywarning,
2236 NULL) > FIFTEENMINUTE2USEC ||
2237 bgp->ebgprequirespolicywarning.tv_sec == 0) {
2238 zlog_warn(
2239 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
2240 monotime(&bgp->ebgprequirespolicywarning);
2241 }
2242 return false;
2243 }
2244
2245 /* draft-ietf-idr-deprecate-as-set-confed-set
2246 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2247 * Eventually, This document (if approved) updates RFC 4271
2248 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2249 * and obsoletes RFC 6472.
2250 */
2251 if (peer->bgp->reject_as_sets)
2252 if (aspath_check_as_sets(attr->aspath))
2253 return false;
2254
2255 /* Codification of AS 0 Processing */
2256 if (aspath_check_as_zero(attr->aspath))
2257 return false;
2258
2259 if (bgp_in_graceful_shutdown(bgp)) {
2260 if (peer->sort == BGP_PEER_IBGP
2261 || peer->sort == BGP_PEER_CONFED) {
2262 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2263 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2264 } else {
2265 bgp_attr_add_gshut_community(attr);
2266 }
2267 }
2268
2269 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2270 * Capability" to a neighbor MUST perform the following upon receiving
2271 * a route from that neighbor with the "LLGR_STALE" community, or upon
2272 * attaching the "LLGR_STALE" community itself per Section 4.2:
2273 *
2274 * The route SHOULD NOT be advertised to any neighbor from which the
2275 * Long-lived Graceful Restart Capability has not been received.
2276 */
2277 if (bgp_attr_get_community(attr) &&
2278 community_include(bgp_attr_get_community(attr),
2279 COMMUNITY_LLGR_STALE) &&
2280 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2281 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2282 return false;
2283
2284 /* After route-map has been applied, we check to see if the nexthop to
2285 * be carried in the attribute (that is used for the announcement) can
2286 * be cleared off or not. We do this in all cases where we would be
2287 * setting the nexthop to "ourselves". For IPv6, we only need to
2288 * consider
2289 * the global nexthop here; the link-local nexthop would have been
2290 * cleared
2291 * already, and if not, it is required by the update formation code.
2292 * Also see earlier comments in this function.
2293 */
2294 /*
2295 * If route-map has performed some operation on the nexthop or the peer
2296 * configuration says to pass it unchanged, we cannot reset the nexthop
2297 * here, so only attempt to do it if these aren't true. Note that the
2298 * route-map handler itself might have cleared the nexthop, if for
2299 * example,
2300 * it is configured as 'peer-address'.
2301 */
2302 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2303 piattr->rmap_change_flags)
2304 && !transparent
2305 && !CHECK_FLAG(peer->af_flags[afi][safi],
2306 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2307 /* We can reset the nexthop, if setting (or forcing) it to
2308 * 'self' */
2309 if (CHECK_FLAG(peer->af_flags[afi][safi],
2310 PEER_FLAG_NEXTHOP_SELF)
2311 || CHECK_FLAG(peer->af_flags[afi][safi],
2312 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2313 if (!reflect
2314 || CHECK_FLAG(peer->af_flags[afi][safi],
2315 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2316 subgroup_announce_reset_nhop(
2317 (peer_cap_enhe(peer, afi, safi)
2318 ? AF_INET6
2319 : p->family),
2320 attr);
2321 nh_reset = true;
2322 }
2323 } else if (peer->sort == BGP_PEER_EBGP) {
2324 /* Can also reset the nexthop if announcing to EBGP, but
2325 * only if
2326 * no peer in the subgroup is on a shared subnet.
2327 * Note: 3rd party nexthop currently implemented for
2328 * IPv4 only.
2329 */
2330 if ((p->family == AF_INET) &&
2331 (!bgp_subgrp_multiaccess_check_v4(
2332 piattr->nexthop,
2333 subgrp, from))) {
2334 subgroup_announce_reset_nhop(
2335 (peer_cap_enhe(peer, afi, safi)
2336 ? AF_INET6
2337 : p->family),
2338 attr);
2339 nh_reset = true;
2340 }
2341
2342 if ((p->family == AF_INET6) &&
2343 (!bgp_subgrp_multiaccess_check_v6(
2344 piattr->mp_nexthop_global,
2345 subgrp, from))) {
2346 subgroup_announce_reset_nhop(
2347 (peer_cap_enhe(peer, afi, safi)
2348 ? AF_INET6
2349 : p->family),
2350 attr);
2351 nh_reset = true;
2352 }
2353
2354
2355
2356 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2357 /*
2358 * This flag is used for leaked vpn-vrf routes
2359 */
2360 int family = p->family;
2361
2362 if (peer_cap_enhe(peer, afi, safi))
2363 family = AF_INET6;
2364
2365 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2366 zlog_debug(
2367 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2368 __func__, family2str(family));
2369 subgroup_announce_reset_nhop(family, attr);
2370 nh_reset = true;
2371 }
2372 }
2373
2374 /* If IPv6/MP and nexthop does not have any override and happens
2375 * to
2376 * be a link-local address, reset it so that we don't pass along
2377 * the
2378 * source's link-local IPv6 address to recipients who may not be
2379 * on
2380 * the same interface.
2381 */
2382 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2383 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2384 subgroup_announce_reset_nhop(AF_INET6, attr);
2385 nh_reset = true;
2386 }
2387 }
2388
2389 /*
2390 * When the next hop is set to ourselves, if all multipaths have
2391 * link-bandwidth announce the cumulative bandwidth as that makes
2392 * the most sense. However, don't modify if the link-bandwidth has
2393 * been explicitly set by user policy.
2394 */
2395 if (nh_reset &&
2396 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2397 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2398 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2399 bgp_attr_set_ecommunity(
2400 attr,
2401 ecommunity_replace_linkbw(
2402 bgp->as, bgp_attr_get_ecommunity(attr), cum_bw,
2403 CHECK_FLAG(
2404 peer->flags,
2405 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE)));
2406
2407 return true;
2408 }
2409
2410 static void bgp_route_select_timer_expire(struct thread *thread)
2411 {
2412 struct afi_safi_info *info;
2413 afi_t afi;
2414 safi_t safi;
2415 struct bgp *bgp;
2416
2417 info = THREAD_ARG(thread);
2418 afi = info->afi;
2419 safi = info->safi;
2420 bgp = info->bgp;
2421
2422 if (BGP_DEBUG(update, UPDATE_OUT))
2423 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2424 safi);
2425
2426 bgp->gr_info[afi][safi].t_route_select = NULL;
2427
2428 XFREE(MTYPE_TMP, info);
2429
2430 /* Best path selection */
2431 bgp_best_path_select_defer(bgp, afi, safi);
2432 }
2433
2434 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2435 struct bgp_maxpaths_cfg *mpath_cfg,
2436 struct bgp_path_info_pair *result, afi_t afi,
2437 safi_t safi)
2438 {
2439 struct bgp_path_info *new_select;
2440 struct bgp_path_info *old_select;
2441 struct bgp_path_info *pi;
2442 struct bgp_path_info *pi1;
2443 struct bgp_path_info *pi2;
2444 struct bgp_path_info *nextpi = NULL;
2445 int paths_eq, do_mpath, debug;
2446 struct list mp_list;
2447 char pfx_buf[PREFIX2STR_BUFFER];
2448 char path_buf[PATH_ADDPATH_STR_BUFFER];
2449
2450 bgp_mp_list_init(&mp_list);
2451 do_mpath =
2452 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2453
2454 debug = bgp_debug_bestpath(dest);
2455
2456 if (debug)
2457 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2458
2459 dest->reason = bgp_path_selection_none;
2460 /* bgp deterministic-med */
2461 new_select = NULL;
2462 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2463
2464 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2465 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2466 pi1 = pi1->next)
2467 bgp_path_info_unset_flag(dest, pi1,
2468 BGP_PATH_DMED_SELECTED);
2469
2470 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2471 pi1 = pi1->next) {
2472 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2473 continue;
2474 if (BGP_PATH_HOLDDOWN(pi1))
2475 continue;
2476 if (pi1->peer != bgp->peer_self)
2477 if (!peer_established(pi1->peer))
2478 continue;
2479
2480 new_select = pi1;
2481 if (pi1->next) {
2482 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2483 if (CHECK_FLAG(pi2->flags,
2484 BGP_PATH_DMED_CHECK))
2485 continue;
2486 if (BGP_PATH_HOLDDOWN(pi2))
2487 continue;
2488 if (pi2->peer != bgp->peer_self
2489 && !CHECK_FLAG(
2490 pi2->peer->sflags,
2491 PEER_STATUS_NSF_WAIT))
2492 if (pi2->peer->status
2493 != Established)
2494 continue;
2495
2496 if (!aspath_cmp_left(pi1->attr->aspath,
2497 pi2->attr->aspath)
2498 && !aspath_cmp_left_confed(
2499 pi1->attr->aspath,
2500 pi2->attr->aspath))
2501 continue;
2502
2503 if (bgp_path_info_cmp(
2504 bgp, pi2, new_select,
2505 &paths_eq, mpath_cfg, debug,
2506 pfx_buf, afi, safi,
2507 &dest->reason)) {
2508 bgp_path_info_unset_flag(
2509 dest, new_select,
2510 BGP_PATH_DMED_SELECTED);
2511 new_select = pi2;
2512 }
2513
2514 bgp_path_info_set_flag(
2515 dest, pi2, BGP_PATH_DMED_CHECK);
2516 }
2517 }
2518 bgp_path_info_set_flag(dest, new_select,
2519 BGP_PATH_DMED_CHECK);
2520 bgp_path_info_set_flag(dest, new_select,
2521 BGP_PATH_DMED_SELECTED);
2522
2523 if (debug) {
2524 bgp_path_info_path_with_addpath_rx_str(
2525 new_select, path_buf, sizeof(path_buf));
2526 zlog_debug(
2527 "%pBD(%s): %s is the bestpath from AS %u",
2528 dest, bgp->name_pretty, path_buf,
2529 aspath_get_first_as(
2530 new_select->attr->aspath));
2531 }
2532 }
2533 }
2534
2535 /* Check old selected route and new selected route. */
2536 old_select = NULL;
2537 new_select = NULL;
2538 for (pi = bgp_dest_get_bgp_path_info(dest);
2539 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2540 enum bgp_path_selection_reason reason;
2541
2542 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2543 old_select = pi;
2544
2545 if (BGP_PATH_HOLDDOWN(pi)) {
2546 /* reap REMOVED routes, if needs be
2547 * selected route must stay for a while longer though
2548 */
2549 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2550 && (pi != old_select))
2551 bgp_path_info_reap(dest, pi);
2552
2553 if (debug)
2554 zlog_debug("%s: pi %p in holddown", __func__,
2555 pi);
2556
2557 continue;
2558 }
2559
2560 if (pi->peer && pi->peer != bgp->peer_self
2561 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2562 if (!peer_established(pi->peer)) {
2563
2564 if (debug)
2565 zlog_debug(
2566 "%s: pi %p non self peer %s not estab state",
2567 __func__, pi, pi->peer->host);
2568
2569 continue;
2570 }
2571
2572 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2573 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2574 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2575 if (debug)
2576 zlog_debug("%s: pi %p dmed", __func__, pi);
2577 continue;
2578 }
2579
2580 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2581
2582 reason = dest->reason;
2583 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2584 debug, pfx_buf, afi, safi,
2585 &dest->reason)) {
2586 if (new_select == NULL &&
2587 reason != bgp_path_selection_none)
2588 dest->reason = reason;
2589 new_select = pi;
2590 }
2591 }
2592
2593 /* Now that we know which path is the bestpath see if any of the other
2594 * paths
2595 * qualify as multipaths
2596 */
2597 if (debug) {
2598 if (new_select)
2599 bgp_path_info_path_with_addpath_rx_str(
2600 new_select, path_buf, sizeof(path_buf));
2601 else
2602 snprintf(path_buf, sizeof(path_buf), "NONE");
2603 zlog_debug(
2604 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2605 dest, bgp->name_pretty, path_buf,
2606 old_select ? old_select->peer->host : "NONE");
2607 }
2608
2609 if (do_mpath && new_select) {
2610 for (pi = bgp_dest_get_bgp_path_info(dest);
2611 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2612
2613 if (debug)
2614 bgp_path_info_path_with_addpath_rx_str(
2615 pi, path_buf, sizeof(path_buf));
2616
2617 if (pi == new_select) {
2618 if (debug)
2619 zlog_debug(
2620 "%pBD(%s): %s is the bestpath, add to the multipath list",
2621 dest, bgp->name_pretty,
2622 path_buf);
2623 bgp_mp_list_add(&mp_list, pi);
2624 continue;
2625 }
2626
2627 if (BGP_PATH_HOLDDOWN(pi))
2628 continue;
2629
2630 if (pi->peer && pi->peer != bgp->peer_self
2631 && !CHECK_FLAG(pi->peer->sflags,
2632 PEER_STATUS_NSF_WAIT))
2633 if (!peer_established(pi->peer))
2634 continue;
2635
2636 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2637 if (debug)
2638 zlog_debug(
2639 "%pBD: %s has the same nexthop as the bestpath, skip it",
2640 dest, path_buf);
2641 continue;
2642 }
2643
2644 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2645 mpath_cfg, debug, pfx_buf, afi, safi,
2646 &dest->reason);
2647
2648 if (paths_eq) {
2649 if (debug)
2650 zlog_debug(
2651 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2652 dest, path_buf);
2653 bgp_mp_list_add(&mp_list, pi);
2654 }
2655 }
2656 }
2657
2658 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2659 mpath_cfg);
2660 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2661 bgp_mp_list_clear(&mp_list);
2662
2663 bgp_addpath_update_ids(bgp, dest, afi, safi);
2664
2665 result->old = old_select;
2666 result->new = new_select;
2667
2668 return;
2669 }
2670
2671 /*
2672 * A new route/change in bestpath of an existing route. Evaluate the path
2673 * for advertisement to the subgroup.
2674 */
2675 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2676 struct bgp_path_info *selected,
2677 struct bgp_dest *dest,
2678 uint32_t addpath_tx_id)
2679 {
2680 const struct prefix *p;
2681 struct peer *onlypeer;
2682 struct attr attr;
2683 afi_t afi;
2684 safi_t safi;
2685 struct bgp *bgp;
2686 bool advertise;
2687
2688 p = bgp_dest_get_prefix(dest);
2689 afi = SUBGRP_AFI(subgrp);
2690 safi = SUBGRP_SAFI(subgrp);
2691 bgp = SUBGRP_INST(subgrp);
2692 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2693 : NULL);
2694
2695 if (BGP_DEBUG(update, UPDATE_OUT))
2696 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2697
2698 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2699 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2700 PEER_STATUS_ORF_WAIT_REFRESH))
2701 return;
2702
2703 memset(&attr, 0, sizeof(struct attr));
2704 /* It's initialized in bgp_announce_check() */
2705
2706 /* Announcement to the subgroup. If the route is filtered withdraw it.
2707 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2708 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2709 * route
2710 */
2711 advertise = bgp_check_advertise(bgp, dest);
2712
2713 if (selected) {
2714 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2715 NULL)) {
2716 /* Route is selected, if the route is already installed
2717 * in FIB, then it is advertised
2718 */
2719 if (advertise) {
2720 if (!bgp_check_withdrawal(bgp, dest))
2721 bgp_adj_out_set_subgroup(
2722 dest, subgrp, &attr, selected);
2723 else
2724 bgp_adj_out_unset_subgroup(
2725 dest, subgrp, 1, addpath_tx_id);
2726 }
2727 } else
2728 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2729 addpath_tx_id);
2730 }
2731
2732 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2733 else {
2734 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2735 }
2736 }
2737
2738 /*
2739 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2740 * This is called at the end of route processing.
2741 */
2742 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2743 {
2744 struct bgp_path_info *pi;
2745
2746 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2747 if (BGP_PATH_HOLDDOWN(pi))
2748 continue;
2749 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2750 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2751 }
2752 }
2753
2754 /*
2755 * Has the route changed from the RIB's perspective? This is invoked only
2756 * if the route selection returns the same best route as earlier - to
2757 * determine if we need to update zebra or not.
2758 */
2759 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2760 {
2761 struct bgp_path_info *mpinfo;
2762
2763 /* If this is multipath, check all selected paths for any nexthop
2764 * change or attribute change. Some attribute changes (e.g., community)
2765 * aren't of relevance to the RIB, but we'll update zebra to ensure
2766 * we handle the case of BGP nexthop change. This is the behavior
2767 * when the best path has an attribute change anyway.
2768 */
2769 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2770 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2771 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2772 return true;
2773
2774 /*
2775 * If this is multipath, check all selected paths for any nexthop change
2776 */
2777 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2778 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2779 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2780 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2781 return true;
2782 }
2783
2784 /* Nothing has changed from the RIB's perspective. */
2785 return false;
2786 }
2787
2788 struct bgp_process_queue {
2789 struct bgp *bgp;
2790 STAILQ_HEAD(, bgp_dest) pqueue;
2791 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2792 unsigned int flags;
2793 unsigned int queued;
2794 };
2795
2796 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2797 safi_t safi, struct bgp_dest *dest,
2798 struct bgp_path_info *new_select,
2799 struct bgp_path_info *old_select)
2800 {
2801 const struct prefix *p = bgp_dest_get_prefix(dest);
2802
2803 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2804 return;
2805
2806 if (advertise_type5_routes(bgp, afi) && new_select
2807 && is_route_injectable_into_evpn(new_select)) {
2808
2809 /* apply the route-map */
2810 if (bgp->adv_cmd_rmap[afi][safi].map) {
2811 route_map_result_t ret;
2812 struct bgp_path_info rmap_path;
2813 struct bgp_path_info_extra rmap_path_extra;
2814 struct attr dummy_attr;
2815
2816 dummy_attr = *new_select->attr;
2817
2818 /* Fill temp path_info */
2819 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2820 new_select, new_select->peer,
2821 &dummy_attr);
2822
2823 RESET_FLAG(dummy_attr.rmap_change_flags);
2824
2825 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2826 p, &rmap_path);
2827
2828 if (ret == RMAP_DENYMATCH) {
2829 bgp_attr_flush(&dummy_attr);
2830 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2831 safi);
2832 } else
2833 bgp_evpn_advertise_type5_route(
2834 bgp, p, &dummy_attr, afi, safi);
2835 } else {
2836 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2837 afi, safi);
2838 }
2839 } else if (advertise_type5_routes(bgp, afi) && old_select
2840 && is_route_injectable_into_evpn(old_select))
2841 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2842 }
2843
2844 /*
2845 * Utility to determine whether a particular path_info should use
2846 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
2847 * in a path where we basically _know_ this is a BGP-LU route.
2848 */
2849 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
2850 {
2851 /* Certain types get imp null; so do paths where the nexthop is
2852 * not labeled.
2853 */
2854 if (new_select->sub_type == BGP_ROUTE_STATIC
2855 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2856 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
2857 return true;
2858 else if (new_select->extra == NULL ||
2859 !bgp_is_valid_label(&new_select->extra->label[0]))
2860 /* TODO -- should be configurable? */
2861 return true;
2862 else
2863 return false;
2864 }
2865
2866 /*
2867 * old_select = The old best path
2868 * new_select = the new best path
2869 *
2870 * if (!old_select && new_select)
2871 * We are sending new information on.
2872 *
2873 * if (old_select && new_select) {
2874 * if (new_select != old_select)
2875 * We have a new best path send a change
2876 * else
2877 * We've received a update with new attributes that needs
2878 * to be passed on.
2879 * }
2880 *
2881 * if (old_select && !new_select)
2882 * We have no eligible route that we can announce or the rn
2883 * is being removed.
2884 */
2885 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2886 afi_t afi, safi_t safi)
2887 {
2888 struct bgp_path_info *new_select;
2889 struct bgp_path_info *old_select;
2890 struct bgp_path_info_pair old_and_new;
2891 int debug = 0;
2892
2893 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2894 if (dest)
2895 debug = bgp_debug_bestpath(dest);
2896 if (debug)
2897 zlog_debug(
2898 "%s: bgp delete in progress, ignoring event, p=%pBD",
2899 __func__, dest);
2900 return;
2901 }
2902 /* Is it end of initial update? (after startup) */
2903 if (!dest) {
2904 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
2905 sizeof(bgp->update_delay_zebra_resume_time));
2906
2907 bgp->main_zebra_update_hold = 0;
2908 FOREACH_AFI_SAFI (afi, safi) {
2909 if (bgp_fibupd_safi(safi))
2910 bgp_zebra_announce_table(bgp, afi, safi);
2911 }
2912 bgp->main_peers_update_hold = 0;
2913
2914 bgp_start_routeadv(bgp);
2915 return;
2916 }
2917
2918 const struct prefix *p = bgp_dest_get_prefix(dest);
2919
2920 debug = bgp_debug_bestpath(dest);
2921 if (debug)
2922 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
2923 dest, bgp->name_pretty, afi2str(afi),
2924 safi2str(safi));
2925
2926 /* The best path calculation for the route is deferred if
2927 * BGP_NODE_SELECT_DEFER is set
2928 */
2929 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2930 if (BGP_DEBUG(update, UPDATE_OUT))
2931 zlog_debug("SELECT_DEFER flag set for route %p", dest);
2932 return;
2933 }
2934
2935 /* Best path selection. */
2936 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2937 afi, safi);
2938 old_select = old_and_new.old;
2939 new_select = old_and_new.new;
2940
2941 /* Do we need to allocate or free labels?
2942 * Right now, since we only deal with per-prefix labels, it is not
2943 * necessary to do this upon changes to best path. Exceptions:
2944 * - label index has changed -> recalculate resulting label
2945 * - path_info sub_type changed -> switch to/from implicit-null
2946 * - no valid label (due to removed static label binding) -> get new one
2947 */
2948 if (bgp->allocate_mpls_labels[afi][safi]) {
2949 if (new_select) {
2950 if (!old_select
2951 || bgp_label_index_differs(new_select, old_select)
2952 || new_select->sub_type != old_select->sub_type
2953 || !bgp_is_valid_label(&dest->local_label)) {
2954 /* Enforced penultimate hop popping:
2955 * implicit-null for local routes, aggregate
2956 * and redistributed routes
2957 */
2958 if (bgp_lu_need_imp_null(new_select)) {
2959 if (CHECK_FLAG(
2960 dest->flags,
2961 BGP_NODE_REGISTERED_FOR_LABEL)
2962 || CHECK_FLAG(
2963 dest->flags,
2964 BGP_NODE_LABEL_REQUESTED))
2965 bgp_unregister_for_label(dest);
2966 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2967 &dest->local_label);
2968 bgp_set_valid_label(&dest->local_label);
2969 } else
2970 bgp_register_for_label(dest,
2971 new_select);
2972 }
2973 } else if (CHECK_FLAG(dest->flags,
2974 BGP_NODE_REGISTERED_FOR_LABEL)
2975 || CHECK_FLAG(dest->flags,
2976 BGP_NODE_LABEL_REQUESTED)) {
2977 bgp_unregister_for_label(dest);
2978 }
2979 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
2980 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
2981 bgp_unregister_for_label(dest);
2982 }
2983
2984 if (debug)
2985 zlog_debug(
2986 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
2987 __func__, dest, bgp->name_pretty, afi2str(afi),
2988 safi2str(safi), old_select, new_select);
2989
2990 /* If best route remains the same and this is not due to user-initiated
2991 * clear, see exactly what needs to be done.
2992 */
2993 if (old_select && old_select == new_select
2994 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2995 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2996 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2997 if (bgp_zebra_has_route_changed(old_select)) {
2998 #ifdef ENABLE_BGP_VNC
2999 vnc_import_bgp_add_route(bgp, p, old_select);
3000 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
3001 #endif
3002 if (bgp_fibupd_safi(safi)
3003 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3004
3005 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
3006 && new_select->sub_type == BGP_ROUTE_NORMAL)
3007 SET_FLAG(dest->flags,
3008 BGP_NODE_FIB_INSTALL_PENDING);
3009
3010 if (new_select->type == ZEBRA_ROUTE_BGP
3011 && (new_select->sub_type == BGP_ROUTE_NORMAL
3012 || new_select->sub_type
3013 == BGP_ROUTE_IMPORTED))
3014
3015 bgp_zebra_announce(dest, p, old_select,
3016 bgp, afi, safi);
3017 }
3018 }
3019
3020 /* If there is a change of interest to peers, reannounce the
3021 * route. */
3022 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
3023 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3024 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
3025 group_announce_route(bgp, afi, safi, dest, new_select);
3026
3027 /* unicast routes must also be annouced to
3028 * labeled-unicast update-groups */
3029 if (safi == SAFI_UNICAST)
3030 group_announce_route(bgp, afi,
3031 SAFI_LABELED_UNICAST, dest,
3032 new_select);
3033
3034 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
3035 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
3036 }
3037
3038 /* advertise/withdraw type-5 routes */
3039 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3040 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3041 bgp_process_evpn_route_injection(
3042 bgp, afi, safi, dest, old_select, old_select);
3043
3044 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3045 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3046 bgp_zebra_clear_route_change_flags(dest);
3047 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3048 return;
3049 }
3050
3051 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3052 */
3053 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3054
3055 /* bestpath has changed; bump version */
3056 if (old_select || new_select) {
3057 bgp_bump_version(dest);
3058
3059 if (!bgp->t_rmap_def_originate_eval) {
3060 bgp_lock(bgp);
3061 thread_add_timer(
3062 bm->master,
3063 update_group_refresh_default_originate_route_map,
3064 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3065 &bgp->t_rmap_def_originate_eval);
3066 }
3067 }
3068
3069 if (old_select)
3070 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3071 if (new_select) {
3072 if (debug)
3073 zlog_debug("%s: setting SELECTED flag", __func__);
3074 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3075 bgp_path_info_unset_flag(dest, new_select,
3076 BGP_PATH_ATTR_CHANGED);
3077 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3078 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3079 }
3080
3081 #ifdef ENABLE_BGP_VNC
3082 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3083 if (old_select != new_select) {
3084 if (old_select) {
3085 vnc_import_bgp_exterior_del_route(bgp, p,
3086 old_select);
3087 vnc_import_bgp_del_route(bgp, p, old_select);
3088 }
3089 if (new_select) {
3090 vnc_import_bgp_exterior_add_route(bgp, p,
3091 new_select);
3092 vnc_import_bgp_add_route(bgp, p, new_select);
3093 }
3094 }
3095 }
3096 #endif
3097
3098 group_announce_route(bgp, afi, safi, dest, new_select);
3099
3100 /* unicast routes must also be annouced to labeled-unicast update-groups
3101 */
3102 if (safi == SAFI_UNICAST)
3103 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3104 new_select);
3105
3106 /* FIB update. */
3107 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3108 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3109
3110 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3111 && (new_select->sub_type == BGP_ROUTE_NORMAL
3112 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3113 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3114
3115 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3116 SET_FLAG(dest->flags,
3117 BGP_NODE_FIB_INSTALL_PENDING);
3118
3119 /* if this is an evpn imported type-5 prefix,
3120 * we need to withdraw the route first to clear
3121 * the nh neigh and the RMAC entry.
3122 */
3123 if (old_select &&
3124 is_route_parent_evpn(old_select))
3125 bgp_zebra_withdraw(p, old_select, bgp, safi);
3126
3127 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3128 } else {
3129 /* Withdraw the route from the kernel. */
3130 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3131 && (old_select->sub_type == BGP_ROUTE_NORMAL
3132 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3133 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3134
3135 bgp_zebra_withdraw(p, old_select, bgp, safi);
3136 }
3137 }
3138
3139 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3140 old_select);
3141
3142 /* Clear any route change flags. */
3143 bgp_zebra_clear_route_change_flags(dest);
3144
3145 /* Reap old select bgp_path_info, if it has been removed */
3146 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3147 bgp_path_info_reap(dest, old_select);
3148
3149 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3150 return;
3151 }
3152
3153 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3154 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3155 {
3156 struct bgp_dest *dest;
3157 int cnt = 0;
3158 struct afi_safi_info *thread_info;
3159
3160 if (bgp->gr_info[afi][safi].t_route_select) {
3161 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3162
3163 thread_info = THREAD_ARG(t);
3164 XFREE(MTYPE_TMP, thread_info);
3165 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
3166 }
3167
3168 if (BGP_DEBUG(update, UPDATE_OUT)) {
3169 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3170 get_afi_safi_str(afi, safi, false),
3171 bgp->gr_info[afi][safi].gr_deferred);
3172 }
3173
3174 /* Process the route list */
3175 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3176 dest && bgp->gr_info[afi][safi].gr_deferred != 0;
3177 dest = bgp_route_next(dest)) {
3178 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3179 continue;
3180
3181 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3182 bgp->gr_info[afi][safi].gr_deferred--;
3183 bgp_process_main_one(bgp, dest, afi, safi);
3184 cnt++;
3185 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) {
3186 bgp_dest_unlock_node(dest);
3187 break;
3188 }
3189 }
3190
3191 /* Send EOR message when all routes are processed */
3192 if (!bgp->gr_info[afi][safi].gr_deferred) {
3193 bgp_send_delayed_eor(bgp);
3194 /* Send route processing complete message to RIB */
3195 bgp_zebra_update(afi, safi, bgp->vrf_id,
3196 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3197 return 0;
3198 }
3199
3200 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3201
3202 thread_info->afi = afi;
3203 thread_info->safi = safi;
3204 thread_info->bgp = bgp;
3205
3206 /* If there are more routes to be processed, start the
3207 * selection timer
3208 */
3209 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3210 BGP_ROUTE_SELECT_DELAY,
3211 &bgp->gr_info[afi][safi].t_route_select);
3212 return 0;
3213 }
3214
3215 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3216 {
3217 struct bgp_process_queue *pqnode = data;
3218 struct bgp *bgp = pqnode->bgp;
3219 struct bgp_table *table;
3220 struct bgp_dest *dest;
3221
3222 /* eoiu marker */
3223 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3224 bgp_process_main_one(bgp, NULL, 0, 0);
3225 /* should always have dedicated wq call */
3226 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3227 return WQ_SUCCESS;
3228 }
3229
3230 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3231 dest = STAILQ_FIRST(&pqnode->pqueue);
3232 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3233 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3234 table = bgp_dest_table(dest);
3235 /* note, new DESTs may be added as part of processing */
3236 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3237
3238 bgp_dest_unlock_node(dest);
3239 bgp_table_unlock(table);
3240 }
3241
3242 return WQ_SUCCESS;
3243 }
3244
3245 static void bgp_processq_del(struct work_queue *wq, void *data)
3246 {
3247 struct bgp_process_queue *pqnode = data;
3248
3249 bgp_unlock(pqnode->bgp);
3250
3251 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3252 }
3253
3254 void bgp_process_queue_init(struct bgp *bgp)
3255 {
3256 if (!bgp->process_queue) {
3257 char name[BUFSIZ];
3258
3259 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3260 bgp->process_queue = work_queue_new(bm->master, name);
3261 }
3262
3263 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3264 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3265 bgp->process_queue->spec.max_retries = 0;
3266 bgp->process_queue->spec.hold = 50;
3267 /* Use a higher yield value of 50ms for main queue processing */
3268 bgp->process_queue->spec.yield = 50 * 1000L;
3269 }
3270
3271 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3272 {
3273 struct bgp_process_queue *pqnode;
3274
3275 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3276 sizeof(struct bgp_process_queue));
3277
3278 /* unlocked in bgp_processq_del */
3279 pqnode->bgp = bgp_lock(bgp);
3280 STAILQ_INIT(&pqnode->pqueue);
3281
3282 return pqnode;
3283 }
3284
3285 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3286 {
3287 #define ARBITRARY_PROCESS_QLEN 10000
3288 struct work_queue *wq = bgp->process_queue;
3289 struct bgp_process_queue *pqnode;
3290 int pqnode_reuse = 0;
3291
3292 /* already scheduled for processing? */
3293 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3294 return;
3295
3296 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3297 * the workqueue
3298 */
3299 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3300 if (BGP_DEBUG(update, UPDATE_OUT))
3301 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3302 dest);
3303 return;
3304 }
3305
3306 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3307 if (BGP_DEBUG(update, UPDATE_OUT))
3308 zlog_debug(
3309 "Soft reconfigure table in progress for route %p",
3310 dest);
3311 return;
3312 }
3313
3314 if (wq == NULL)
3315 return;
3316
3317 /* Add route nodes to an existing work queue item until reaching the
3318 limit only if is from the same BGP view and it's not an EOIU marker
3319 */
3320 if (work_queue_item_count(wq)) {
3321 struct work_queue_item *item = work_queue_last_item(wq);
3322 pqnode = item->data;
3323
3324 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3325 || pqnode->bgp != bgp
3326 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3327 pqnode = bgp_processq_alloc(bgp);
3328 else
3329 pqnode_reuse = 1;
3330 } else
3331 pqnode = bgp_processq_alloc(bgp);
3332 /* all unlocked in bgp_process_wq */
3333 bgp_table_lock(bgp_dest_table(dest));
3334
3335 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3336 bgp_dest_lock_node(dest);
3337
3338 /* can't be enqueued twice */
3339 assert(STAILQ_NEXT(dest, pq) == NULL);
3340 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3341 pqnode->queued++;
3342
3343 if (!pqnode_reuse)
3344 work_queue_add(wq, pqnode);
3345
3346 return;
3347 }
3348
3349 void bgp_add_eoiu_mark(struct bgp *bgp)
3350 {
3351 struct bgp_process_queue *pqnode;
3352
3353 if (bgp->process_queue == NULL)
3354 return;
3355
3356 pqnode = bgp_processq_alloc(bgp);
3357
3358 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3359 work_queue_add(bgp->process_queue, pqnode);
3360 }
3361
3362 static void bgp_maximum_prefix_restart_timer(struct thread *thread)
3363 {
3364 struct peer *peer;
3365
3366 peer = THREAD_ARG(thread);
3367 peer->t_pmax_restart = NULL;
3368
3369 if (bgp_debug_neighbor_events(peer))
3370 zlog_debug(
3371 "%s Maximum-prefix restart timer expired, restore peering",
3372 peer->host);
3373
3374 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3375 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3376 }
3377
3378 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3379 safi_t safi)
3380 {
3381 uint32_t count = 0;
3382 bool filtered = false;
3383 struct bgp_dest *dest;
3384 struct bgp_adj_in *ain;
3385 struct attr attr = {};
3386 struct bgp_table *table = peer->bgp->rib[afi][safi];
3387
3388 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3389 for (ain = dest->adj_in; ain; ain = ain->next) {
3390 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3391
3392 attr = *ain->attr;
3393
3394 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3395 == FILTER_DENY)
3396 filtered = true;
3397
3398 if (bgp_input_modifier(
3399 peer, rn_p, &attr, afi, safi,
3400 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3401 NULL, 0, NULL)
3402 == RMAP_DENY)
3403 filtered = true;
3404
3405 if (filtered)
3406 count++;
3407
3408 bgp_attr_flush(&attr);
3409 }
3410 }
3411
3412 return count;
3413 }
3414
3415 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3416 int always)
3417 {
3418 iana_afi_t pkt_afi;
3419 iana_safi_t pkt_safi;
3420 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3421 PEER_FLAG_MAX_PREFIX_FORCE))
3422 ? bgp_filtered_routes_count(peer, afi, safi)
3423 + peer->pcount[afi][safi]
3424 : peer->pcount[afi][safi];
3425
3426 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3427 return false;
3428
3429 if (pcount > peer->pmax[afi][safi]) {
3430 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3431 PEER_STATUS_PREFIX_LIMIT)
3432 && !always)
3433 return false;
3434
3435 zlog_info(
3436 "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u",
3437 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3438 peer->pmax[afi][safi]);
3439 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3440
3441 if (CHECK_FLAG(peer->af_flags[afi][safi],
3442 PEER_FLAG_MAX_PREFIX_WARNING))
3443 return false;
3444
3445 /* Convert AFI, SAFI to values for packet. */
3446 pkt_afi = afi_int2iana(afi);
3447 pkt_safi = safi_int2iana(safi);
3448 {
3449 uint8_t ndata[7];
3450
3451 ndata[0] = (pkt_afi >> 8);
3452 ndata[1] = pkt_afi;
3453 ndata[2] = pkt_safi;
3454 ndata[3] = (peer->pmax[afi][safi] >> 24);
3455 ndata[4] = (peer->pmax[afi][safi] >> 16);
3456 ndata[5] = (peer->pmax[afi][safi] >> 8);
3457 ndata[6] = (peer->pmax[afi][safi]);
3458
3459 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3460 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3461 BGP_NOTIFY_CEASE_MAX_PREFIX,
3462 ndata, 7);
3463 }
3464
3465 /* Dynamic peers will just close their connection. */
3466 if (peer_dynamic_neighbor(peer))
3467 return true;
3468
3469 /* restart timer start */
3470 if (peer->pmax_restart[afi][safi]) {
3471 peer->v_pmax_restart =
3472 peer->pmax_restart[afi][safi] * 60;
3473
3474 if (bgp_debug_neighbor_events(peer))
3475 zlog_debug(
3476 "%s Maximum-prefix restart timer started for %d secs",
3477 peer->host, peer->v_pmax_restart);
3478
3479 BGP_TIMER_ON(peer->t_pmax_restart,
3480 bgp_maximum_prefix_restart_timer,
3481 peer->v_pmax_restart);
3482 }
3483
3484 return true;
3485 } else
3486 UNSET_FLAG(peer->af_sflags[afi][safi],
3487 PEER_STATUS_PREFIX_LIMIT);
3488
3489 if (pcount
3490 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3491 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3492 PEER_STATUS_PREFIX_THRESHOLD)
3493 && !always)
3494 return false;
3495
3496 zlog_info(
3497 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3498 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3499 peer->pmax[afi][safi]);
3500 SET_FLAG(peer->af_sflags[afi][safi],
3501 PEER_STATUS_PREFIX_THRESHOLD);
3502 } else
3503 UNSET_FLAG(peer->af_sflags[afi][safi],
3504 PEER_STATUS_PREFIX_THRESHOLD);
3505 return false;
3506 }
3507
3508 /* Unconditionally remove the route from the RIB, without taking
3509 * damping into consideration (eg, because the session went down)
3510 */
3511 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3512 struct peer *peer, afi_t afi, safi_t safi)
3513 {
3514
3515 struct bgp *bgp = NULL;
3516 bool delete_route = false;
3517
3518 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3519 safi);
3520
3521 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3522 bgp_path_info_delete(dest, pi); /* keep historical info */
3523
3524 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3525 * flag
3526 */
3527 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3528 delete_route = true;
3529 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3530 delete_route = true;
3531 if (delete_route) {
3532 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3533 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3534 bgp = pi->peer->bgp;
3535 bgp->gr_info[afi][safi].gr_deferred--;
3536 }
3537 }
3538 }
3539
3540 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3541 bgp_process(peer->bgp, dest, afi, safi);
3542 }
3543
3544 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3545 struct peer *peer, afi_t afi, safi_t safi,
3546 struct prefix_rd *prd)
3547 {
3548 const struct prefix *p = bgp_dest_get_prefix(dest);
3549
3550 /* apply dampening, if result is suppressed, we'll be retaining
3551 * the bgp_path_info in the RIB for historical reference.
3552 */
3553 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3554 && peer->sort == BGP_PEER_EBGP)
3555 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3556 == BGP_DAMP_SUPPRESSED) {
3557 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3558 safi);
3559 return;
3560 }
3561
3562 #ifdef ENABLE_BGP_VNC
3563 if (safi == SAFI_MPLS_VPN) {
3564 struct bgp_dest *pdest = NULL;
3565 struct bgp_table *table = NULL;
3566
3567 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3568 (struct prefix *)prd);
3569 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3570 table = bgp_dest_get_bgp_table_info(pdest);
3571
3572 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3573 peer->bgp, prd, table, p, pi);
3574 }
3575 bgp_dest_unlock_node(pdest);
3576 }
3577 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3578 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3579
3580 vnc_import_bgp_del_route(peer->bgp, p, pi);
3581 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3582 }
3583 }
3584 #endif
3585
3586 /* If this is an EVPN route, process for un-import. */
3587 if (safi == SAFI_EVPN)
3588 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3589
3590 bgp_rib_remove(dest, pi, peer, afi, safi);
3591 }
3592
3593 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3594 struct peer *peer, struct attr *attr,
3595 struct bgp_dest *dest)
3596 {
3597 struct bgp_path_info *new;
3598
3599 /* Make new BGP info. */
3600 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3601 new->type = type;
3602 new->instance = instance;
3603 new->sub_type = sub_type;
3604 new->peer = peer;
3605 new->attr = attr;
3606 new->uptime = bgp_clock();
3607 new->net = dest;
3608 return new;
3609 }
3610
3611 /* Check if received nexthop is valid or not. */
3612 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3613 uint8_t type, uint8_t stype, struct attr *attr,
3614 struct bgp_dest *dest)
3615 {
3616 bool ret = false;
3617 bool is_bgp_static_route =
3618 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3619 : false;
3620
3621 /*
3622 * Only validated for unicast and multicast currently.
3623 * Also valid for EVPN where the nexthop is an IP address.
3624 * If we are a bgp static route being checked then there is
3625 * no need to check to see if the nexthop is martian as
3626 * that it should be ok.
3627 */
3628 if (is_bgp_static_route ||
3629 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3630 return false;
3631
3632 /* If NEXT_HOP is present, validate it. */
3633 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3634 if (attr->nexthop.s_addr == INADDR_ANY
3635 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3636 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3637 return true;
3638 }
3639
3640 /* If MP_NEXTHOP is present, validate it. */
3641 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3642 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3643 * it is not an IPv6 link-local address.
3644 *
3645 * If we receive an UPDATE with nexthop length set to 32 bytes
3646 * we shouldn't discard an UPDATE if it's set to (::).
3647 * The link-local (2st) is validated along the code path later.
3648 */
3649 if (attr->mp_nexthop_len) {
3650 switch (attr->mp_nexthop_len) {
3651 case BGP_ATTR_NHLEN_IPV4:
3652 case BGP_ATTR_NHLEN_VPNV4:
3653 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3654 || IPV4_CLASS_DE(
3655 ntohl(attr->mp_nexthop_global_in.s_addr))
3656 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3657 dest));
3658 break;
3659
3660 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3661 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3662 ret = (IN6_IS_ADDR_UNSPECIFIED(
3663 &attr->mp_nexthop_global)
3664 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3665 || IN6_IS_ADDR_MULTICAST(
3666 &attr->mp_nexthop_global)
3667 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3668 dest));
3669 break;
3670 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3671 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3672 || IN6_IS_ADDR_MULTICAST(
3673 &attr->mp_nexthop_global)
3674 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3675 dest));
3676 break;
3677
3678 default:
3679 ret = true;
3680 break;
3681 }
3682 }
3683
3684 return ret;
3685 }
3686
3687 static void bgp_attr_add_no_export_community(struct attr *attr)
3688 {
3689 struct community *old;
3690 struct community *new;
3691 struct community *merge;
3692 struct community *no_export;
3693
3694 old = bgp_attr_get_community(attr);
3695 no_export = community_str2com("no-export");
3696
3697 assert(no_export);
3698
3699 if (old) {
3700 merge = community_merge(community_dup(old), no_export);
3701
3702 if (!old->refcnt)
3703 community_free(&old);
3704
3705 new = community_uniq_sort(merge);
3706 community_free(&merge);
3707 } else {
3708 new = community_dup(no_export);
3709 }
3710
3711 community_free(&no_export);
3712
3713 bgp_attr_set_community(attr, new);
3714 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
3715 }
3716
3717 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3718 struct attr *attr, afi_t afi, safi_t safi, int type,
3719 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3720 uint32_t num_labels, int soft_reconfig,
3721 struct bgp_route_evpn *evpn)
3722 {
3723 int ret;
3724 int aspath_loop_count = 0;
3725 struct bgp_dest *dest;
3726 struct bgp *bgp;
3727 struct attr new_attr;
3728 struct attr *attr_new;
3729 struct bgp_path_info *pi;
3730 struct bgp_path_info *new;
3731 struct bgp_path_info_extra *extra;
3732 const char *reason;
3733 char pfx_buf[BGP_PRD_PATH_STRLEN];
3734 int connected = 0;
3735 int do_loop_check = 1;
3736 int has_valid_label = 0;
3737 afi_t nh_afi;
3738 uint8_t pi_type = 0;
3739 uint8_t pi_sub_type = 0;
3740 bool force_evpn_import = false;
3741 safi_t orig_safi = safi;
3742
3743 if (frrtrace_enabled(frr_bgp, process_update)) {
3744 char pfxprint[PREFIX2STR_BUFFER];
3745
3746 prefix2str(p, pfxprint, sizeof(pfxprint));
3747 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3748 afi, safi, attr);
3749 }
3750
3751 #ifdef ENABLE_BGP_VNC
3752 int vnc_implicit_withdraw = 0;
3753 #endif
3754 int same_attr = 0;
3755
3756 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
3757 if (orig_safi == SAFI_LABELED_UNICAST)
3758 safi = SAFI_UNICAST;
3759
3760 memset(&new_attr, 0, sizeof(struct attr));
3761 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3762 new_attr.label = MPLS_INVALID_LABEL;
3763
3764 bgp = peer->bgp;
3765 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3766 /* TODO: Check to see if we can get rid of "is_valid_label" */
3767 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3768 has_valid_label = (num_labels > 0) ? 1 : 0;
3769 else
3770 has_valid_label = bgp_is_valid_label(label);
3771
3772 if (has_valid_label)
3773 assert(label != NULL);
3774
3775 /* Update overlay index of the attribute */
3776 if (afi == AFI_L2VPN && evpn)
3777 memcpy(&attr->evpn_overlay, evpn,
3778 sizeof(struct bgp_route_evpn));
3779
3780 /* When peer's soft reconfiguration enabled. Record input packet in
3781 Adj-RIBs-In. */
3782 if (!soft_reconfig
3783 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3784 && peer != bgp->peer_self)
3785 bgp_adj_in_set(dest, peer, attr, addpath_id);
3786
3787 /* Check previously received route. */
3788 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3789 if (pi->peer == peer && pi->type == type
3790 && pi->sub_type == sub_type
3791 && pi->addpath_rx_id == addpath_id)
3792 break;
3793
3794 /* AS path local-as loop check. */
3795 if (peer->change_local_as) {
3796 if (peer->allowas_in[afi][safi])
3797 aspath_loop_count = peer->allowas_in[afi][safi];
3798 else if (!CHECK_FLAG(peer->flags,
3799 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3800 aspath_loop_count = 1;
3801
3802 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3803 > aspath_loop_count) {
3804 peer->stat_pfx_aspath_loop++;
3805 reason = "as-path contains our own AS;";
3806 goto filtered;
3807 }
3808 }
3809
3810 /* If the peer is configured for "allowas-in origin" and the last ASN in
3811 * the
3812 * as-path is our ASN then we do not need to call aspath_loop_check
3813 */
3814 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3815 if (aspath_get_last_as(attr->aspath) == bgp->as)
3816 do_loop_check = 0;
3817
3818 /* AS path loop check. */
3819 if (do_loop_check) {
3820 if (aspath_loop_check(attr->aspath, bgp->as)
3821 > peer->allowas_in[afi][safi]
3822 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3823 && aspath_loop_check(attr->aspath, bgp->confed_id)
3824 > peer->allowas_in[afi][safi])) {
3825 peer->stat_pfx_aspath_loop++;
3826 reason = "as-path contains our own AS;";
3827 goto filtered;
3828 }
3829 }
3830
3831 /* Route reflector originator ID check. */
3832 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3833 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3834 peer->stat_pfx_originator_loop++;
3835 reason = "originator is us;";
3836 goto filtered;
3837 }
3838
3839 /* Route reflector cluster ID check. */
3840 if (bgp_cluster_filter(peer, attr)) {
3841 peer->stat_pfx_cluster_loop++;
3842 reason = "reflected from the same cluster;";
3843 goto filtered;
3844 }
3845
3846 /* Apply incoming filter. */
3847 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
3848 peer->stat_pfx_filter++;
3849 reason = "filter;";
3850 goto filtered;
3851 }
3852
3853 /* RFC 8212 to prevent route leaks.
3854 * This specification intends to improve this situation by requiring the
3855 * explicit configuration of both BGP Import and Export Policies for any
3856 * External BGP (EBGP) session such as customers, peers, or
3857 * confederation boundaries for all enabled address families. Through
3858 * codification of the aforementioned requirement, operators will
3859 * benefit from consistent behavior across different BGP
3860 * implementations.
3861 */
3862 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3863 if (!bgp_inbound_policy_exists(peer,
3864 &peer->filter[afi][safi])) {
3865 reason = "inbound policy missing";
3866 if (monotime_since(&bgp->ebgprequirespolicywarning,
3867 NULL) > FIFTEENMINUTE2USEC ||
3868 bgp->ebgprequirespolicywarning.tv_sec == 0) {
3869 zlog_warn(
3870 "EBGP inbound/outbound policy not properly setup, please configure in order for your peering to work correctly");
3871 monotime(&bgp->ebgprequirespolicywarning);
3872 }
3873 goto filtered;
3874 }
3875
3876 /* draft-ietf-idr-deprecate-as-set-confed-set
3877 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3878 * Eventually, This document (if approved) updates RFC 4271
3879 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3880 * and obsoletes RFC 6472.
3881 */
3882 if (peer->bgp->reject_as_sets)
3883 if (aspath_check_as_sets(attr->aspath)) {
3884 reason =
3885 "as-path contains AS_SET or AS_CONFED_SET type;";
3886 goto filtered;
3887 }
3888
3889 new_attr = *attr;
3890
3891 /* Apply incoming route-map.
3892 * NB: new_attr may now contain newly allocated values from route-map
3893 * "set"
3894 * commands, so we need bgp_attr_flush in the error paths, until we
3895 * intern
3896 * the attr (which takes over the memory references) */
3897 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
3898 num_labels, dest)
3899 == RMAP_DENY) {
3900 peer->stat_pfx_filter++;
3901 reason = "route-map;";
3902 bgp_attr_flush(&new_attr);
3903 goto filtered;
3904 }
3905
3906 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3907 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3908 /* remove from RIB previous entry */
3909 bgp_zebra_withdraw(p, pi, bgp, safi);
3910 }
3911
3912 if (peer->sort == BGP_PEER_EBGP) {
3913
3914 /* rfc7999:
3915 * A BGP speaker receiving an announcement tagged with the
3916 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
3917 * NO_EXPORT community as defined in RFC1997, or a
3918 * similar community, to prevent propagation of the
3919 * prefix outside the local AS. The community to prevent
3920 * propagation SHOULD be chosen according to the operator's
3921 * routing policy.
3922 */
3923 if (bgp_attr_get_community(&new_attr) &&
3924 community_include(bgp_attr_get_community(&new_attr),
3925 COMMUNITY_BLACKHOLE))
3926 bgp_attr_add_no_export_community(&new_attr);
3927
3928 /* If we receive the graceful-shutdown community from an eBGP
3929 * peer we must lower local-preference */
3930 if (bgp_attr_get_community(&new_attr) &&
3931 community_include(bgp_attr_get_community(&new_attr),
3932 COMMUNITY_GSHUT)) {
3933 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3934 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3935
3936 /* If graceful-shutdown is configured then add the GSHUT
3937 * community to all paths received from eBGP peers */
3938 } else if (bgp_in_graceful_shutdown(peer->bgp))
3939 bgp_attr_add_gshut_community(&new_attr);
3940 }
3941
3942 if (pi) {
3943 pi_type = pi->type;
3944 pi_sub_type = pi->sub_type;
3945 }
3946
3947 /* next hop check. */
3948 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3949 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3950 &new_attr, dest)) {
3951 peer->stat_pfx_nh_invalid++;
3952 reason = "martian or self next-hop;";
3953 bgp_attr_flush(&new_attr);
3954 goto filtered;
3955 }
3956
3957 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3958 peer->stat_pfx_nh_invalid++;
3959 reason = "self mac;";
3960 bgp_attr_flush(&new_attr);
3961 goto filtered;
3962 }
3963
3964 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
3965 * condition :
3966 * Suppress fib is enabled
3967 * BGP_OPT_NO_FIB is not enabled
3968 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
3969 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
3970 */
3971 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
3972 && (sub_type == BGP_ROUTE_NORMAL)
3973 && (!bgp_option_check(BGP_OPT_NO_FIB))
3974 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
3975 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
3976
3977 /* If maximum prefix count is configured and current prefix
3978 * count exeed it.
3979 */
3980 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0)) {
3981 bgp_attr_flush(&new_attr);
3982 return -1;
3983 }
3984
3985 attr_new = bgp_attr_intern(&new_attr);
3986
3987 /* If the update is implicit withdraw. */
3988 if (pi) {
3989 pi->uptime = bgp_clock();
3990 same_attr = attrhash_cmp(pi->attr, attr_new);
3991
3992 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3993
3994 /* Same attribute comes in. */
3995 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3996 && same_attr
3997 && (!has_valid_label
3998 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3999 num_labels * sizeof(mpls_label_t))
4000 == 0)) {
4001 if (CHECK_FLAG(bgp->af_flags[afi][safi],
4002 BGP_CONFIG_DAMPENING)
4003 && peer->sort == BGP_PEER_EBGP
4004 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4005 if (bgp_debug_update(peer, p, NULL, 1)) {
4006 bgp_debug_rdpfxpath2str(
4007 afi, safi, prd, p, label,
4008 num_labels, addpath_id ? 1 : 0,
4009 addpath_id, evpn, pfx_buf,
4010 sizeof(pfx_buf));
4011 zlog_debug("%s rcvd %s", peer->host,
4012 pfx_buf);
4013 }
4014
4015 if (bgp_damp_update(pi, dest, afi, safi)
4016 != BGP_DAMP_SUPPRESSED) {
4017 bgp_aggregate_increment(bgp, p, pi, afi,
4018 safi);
4019 bgp_process(bgp, dest, afi, safi);
4020 }
4021 } else /* Duplicate - odd */
4022 {
4023 if (bgp_debug_update(peer, p, NULL, 1)) {
4024 if (!peer->rcvd_attr_printed) {
4025 zlog_debug(
4026 "%s rcvd UPDATE w/ attr: %s",
4027 peer->host,
4028 peer->rcvd_attr_str);
4029 peer->rcvd_attr_printed = 1;
4030 }
4031
4032 bgp_debug_rdpfxpath2str(
4033 afi, safi, prd, p, label,
4034 num_labels, addpath_id ? 1 : 0,
4035 addpath_id, evpn, pfx_buf,
4036 sizeof(pfx_buf));
4037 zlog_debug(
4038 "%s rcvd %s...duplicate ignored",
4039 peer->host, pfx_buf);
4040 }
4041
4042 /* graceful restart STALE flag unset. */
4043 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4044 bgp_path_info_unset_flag(
4045 dest, pi, BGP_PATH_STALE);
4046 bgp_dest_set_defer_flag(dest, false);
4047 bgp_process(bgp, dest, afi, safi);
4048 }
4049 }
4050
4051 bgp_dest_unlock_node(dest);
4052 bgp_attr_unintern(&attr_new);
4053
4054 return 0;
4055 }
4056
4057 /* Withdraw/Announce before we fully processed the withdraw */
4058 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4059 if (bgp_debug_update(peer, p, NULL, 1)) {
4060 bgp_debug_rdpfxpath2str(
4061 afi, safi, prd, p, label, num_labels,
4062 addpath_id ? 1 : 0, addpath_id, evpn,
4063 pfx_buf, sizeof(pfx_buf));
4064 zlog_debug(
4065 "%s rcvd %s, flapped quicker than processing",
4066 peer->host, pfx_buf);
4067 }
4068
4069 bgp_path_info_restore(dest, pi);
4070
4071 /*
4072 * If the BGP_PATH_REMOVED flag is set, then EVPN
4073 * routes would have been unimported already when a
4074 * prior BGP withdraw processing happened. Such routes
4075 * need to be imported again, so flag accordingly.
4076 */
4077 force_evpn_import = true;
4078 }
4079
4080 /* Received Logging. */
4081 if (bgp_debug_update(peer, p, NULL, 1)) {
4082 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4083 num_labels, addpath_id ? 1 : 0,
4084 addpath_id, evpn, pfx_buf,
4085 sizeof(pfx_buf));
4086 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
4087 }
4088
4089 /* graceful restart STALE flag unset. */
4090 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4091 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4092 bgp_dest_set_defer_flag(dest, false);
4093 }
4094
4095 /* The attribute is changed. */
4096 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4097
4098 /* implicit withdraw, decrement aggregate and pcount here.
4099 * only if update is accepted, they'll increment below.
4100 */
4101 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4102
4103 /* Update bgp route dampening information. */
4104 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4105 && peer->sort == BGP_PEER_EBGP) {
4106 /* This is implicit withdraw so we should update
4107 dampening
4108 information. */
4109 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4110 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4111 }
4112 #ifdef ENABLE_BGP_VNC
4113 if (safi == SAFI_MPLS_VPN) {
4114 struct bgp_dest *pdest = NULL;
4115 struct bgp_table *table = NULL;
4116
4117 pdest = bgp_node_get(bgp->rib[afi][safi],
4118 (struct prefix *)prd);
4119 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4120 table = bgp_dest_get_bgp_table_info(pdest);
4121
4122 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4123 bgp, prd, table, p, pi);
4124 }
4125 bgp_dest_unlock_node(pdest);
4126 }
4127 if ((afi == AFI_IP || afi == AFI_IP6)
4128 && (safi == SAFI_UNICAST)) {
4129 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4130 /*
4131 * Implicit withdraw case.
4132 */
4133 ++vnc_implicit_withdraw;
4134 vnc_import_bgp_del_route(bgp, p, pi);
4135 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4136 }
4137 }
4138 #endif
4139
4140 /* Special handling for EVPN update of an existing route. If the
4141 * extended community attribute has changed, we need to
4142 * un-import
4143 * the route using its existing extended community. It will be
4144 * subsequently processed for import with the new extended
4145 * community.
4146 */
4147 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4148 && !same_attr) {
4149 if ((pi->attr->flag
4150 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4151 && (attr_new->flag
4152 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4153 int cmp;
4154
4155 cmp = ecommunity_cmp(
4156 bgp_attr_get_ecommunity(pi->attr),
4157 bgp_attr_get_ecommunity(attr_new));
4158 if (!cmp) {
4159 if (bgp_debug_update(peer, p, NULL, 1))
4160 zlog_debug(
4161 "Change in EXT-COMM, existing %s new %s",
4162 ecommunity_str(
4163 bgp_attr_get_ecommunity(
4164 pi->attr)),
4165 ecommunity_str(
4166 bgp_attr_get_ecommunity(
4167 attr_new)));
4168 if (safi == SAFI_EVPN)
4169 bgp_evpn_unimport_route(
4170 bgp, afi, safi, p, pi);
4171 else /* SAFI_MPLS_VPN */
4172 vpn_leak_to_vrf_withdraw(bgp,
4173 pi);
4174 }
4175 }
4176 }
4177
4178 /* Update to new attribute. */
4179 bgp_attr_unintern(&pi->attr);
4180 pi->attr = attr_new;
4181
4182 /* Update MPLS label */
4183 if (has_valid_label) {
4184 extra = bgp_path_info_extra_get(pi);
4185 if (extra->label != label) {
4186 memcpy(&extra->label, label,
4187 num_labels * sizeof(mpls_label_t));
4188 extra->num_labels = num_labels;
4189 }
4190 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4191 bgp_set_valid_label(&extra->label[0]);
4192 }
4193
4194 /* Update SRv6 SID */
4195 if (attr->srv6_l3vpn) {
4196 extra = bgp_path_info_extra_get(pi);
4197 if (sid_diff(&extra->sid[0].sid,
4198 &attr->srv6_l3vpn->sid)) {
4199 sid_copy(&extra->sid[0].sid,
4200 &attr->srv6_l3vpn->sid);
4201 extra->num_sids = 1;
4202
4203 extra->sid[0].loc_block_len = 0;
4204 extra->sid[0].loc_node_len = 0;
4205 extra->sid[0].func_len = 0;
4206 extra->sid[0].arg_len = 0;
4207 extra->sid[0].transposition_len = 0;
4208 extra->sid[0].transposition_offset = 0;
4209
4210 if (attr->srv6_l3vpn->loc_block_len != 0) {
4211 extra->sid[0].loc_block_len =
4212 attr->srv6_l3vpn->loc_block_len;
4213 extra->sid[0].loc_node_len =
4214 attr->srv6_l3vpn->loc_node_len;
4215 extra->sid[0].func_len =
4216 attr->srv6_l3vpn->func_len;
4217 extra->sid[0].arg_len =
4218 attr->srv6_l3vpn->arg_len;
4219 extra->sid[0].transposition_len =
4220 attr->srv6_l3vpn
4221 ->transposition_len;
4222 extra->sid[0].transposition_offset =
4223 attr->srv6_l3vpn
4224 ->transposition_offset;
4225 }
4226 }
4227 } else if (attr->srv6_vpn) {
4228 extra = bgp_path_info_extra_get(pi);
4229 if (sid_diff(&extra->sid[0].sid,
4230 &attr->srv6_vpn->sid)) {
4231 sid_copy(&extra->sid[0].sid,
4232 &attr->srv6_vpn->sid);
4233 extra->num_sids = 1;
4234 }
4235 }
4236
4237 #ifdef ENABLE_BGP_VNC
4238 if ((afi == AFI_IP || afi == AFI_IP6)
4239 && (safi == SAFI_UNICAST)) {
4240 if (vnc_implicit_withdraw) {
4241 /*
4242 * Add back the route with its new attributes
4243 * (e.g., nexthop).
4244 * The route is still selected, until the route
4245 * selection
4246 * queued by bgp_process actually runs. We have
4247 * to make this
4248 * update to the VNC side immediately to avoid
4249 * racing against
4250 * configuration changes (e.g., route-map
4251 * changes) which
4252 * trigger re-importation of the entire RIB.
4253 */
4254 vnc_import_bgp_add_route(bgp, p, pi);
4255 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4256 }
4257 }
4258 #endif
4259
4260 /* Update bgp route dampening information. */
4261 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4262 && peer->sort == BGP_PEER_EBGP) {
4263 /* Now we do normal update dampening. */
4264 ret = bgp_damp_update(pi, dest, afi, safi);
4265 if (ret == BGP_DAMP_SUPPRESSED) {
4266 bgp_dest_unlock_node(dest);
4267 return 0;
4268 }
4269 }
4270
4271 /* Nexthop reachability check - for unicast and
4272 * labeled-unicast.. */
4273 if (((afi == AFI_IP || afi == AFI_IP6)
4274 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4275 || (safi == SAFI_EVPN &&
4276 bgp_evpn_is_prefix_nht_supported(p))) {
4277 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4278 && peer->ttl == BGP_DEFAULT_TTL
4279 && !CHECK_FLAG(peer->flags,
4280 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4281 && !CHECK_FLAG(bgp->flags,
4282 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4283 connected = 1;
4284 else
4285 connected = 0;
4286
4287 struct bgp *bgp_nexthop = bgp;
4288
4289 if (pi->extra && pi->extra->bgp_orig)
4290 bgp_nexthop = pi->extra->bgp_orig;
4291
4292 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4293
4294 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4295 safi, pi, NULL, connected,
4296 p)
4297 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4298 bgp_path_info_set_flag(dest, pi,
4299 BGP_PATH_VALID);
4300 else {
4301 if (BGP_DEBUG(nht, NHT)) {
4302 zlog_debug("%s(%pI4): NH unresolved",
4303 __func__,
4304 (in_addr_t *)&attr_new->nexthop);
4305 }
4306 bgp_path_info_unset_flag(dest, pi,
4307 BGP_PATH_VALID);
4308 }
4309 } else
4310 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4311
4312 #ifdef ENABLE_BGP_VNC
4313 if (safi == SAFI_MPLS_VPN) {
4314 struct bgp_dest *pdest = NULL;
4315 struct bgp_table *table = NULL;
4316
4317 pdest = bgp_node_get(bgp->rib[afi][safi],
4318 (struct prefix *)prd);
4319 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4320 table = bgp_dest_get_bgp_table_info(pdest);
4321
4322 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4323 bgp, prd, table, p, pi);
4324 }
4325 bgp_dest_unlock_node(pdest);
4326 }
4327 #endif
4328
4329 /* If this is an EVPN route and some attribute has changed,
4330 * or we are explicitly told to perform a route import, process
4331 * route for import. If the extended community has changed, we
4332 * would
4333 * have done the un-import earlier and the import would result
4334 * in the
4335 * route getting injected into appropriate L2 VNIs. If it is
4336 * just
4337 * some other attribute change, the import will result in
4338 * updating
4339 * the attributes for the route in the VNI(s).
4340 */
4341 if (safi == SAFI_EVPN &&
4342 (!same_attr || force_evpn_import) &&
4343 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4344 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4345
4346 /* Process change. */
4347 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4348
4349 bgp_process(bgp, dest, afi, safi);
4350 bgp_dest_unlock_node(dest);
4351
4352 if (SAFI_UNICAST == safi
4353 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4354 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4355
4356 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4357 }
4358 if ((SAFI_MPLS_VPN == safi)
4359 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4360
4361 vpn_leak_to_vrf_update(bgp, pi);
4362 }
4363
4364 #ifdef ENABLE_BGP_VNC
4365 if (SAFI_MPLS_VPN == safi) {
4366 mpls_label_t label_decoded = decode_label(label);
4367
4368 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4369 type, sub_type, &label_decoded);
4370 }
4371 if (SAFI_ENCAP == safi) {
4372 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4373 type, sub_type, NULL);
4374 }
4375 #endif
4376
4377 return 0;
4378 } // End of implicit withdraw
4379
4380 /* Received Logging. */
4381 if (bgp_debug_update(peer, p, NULL, 1)) {
4382 if (!peer->rcvd_attr_printed) {
4383 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4384 peer->rcvd_attr_str);
4385 peer->rcvd_attr_printed = 1;
4386 }
4387
4388 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4389 addpath_id ? 1 : 0, addpath_id, evpn,
4390 pfx_buf, sizeof(pfx_buf));
4391 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
4392 }
4393
4394 /* Make new BGP info. */
4395 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4396
4397 /* Update MPLS label */
4398 if (has_valid_label) {
4399 extra = bgp_path_info_extra_get(new);
4400 if (extra->label != label) {
4401 memcpy(&extra->label, label,
4402 num_labels * sizeof(mpls_label_t));
4403 extra->num_labels = num_labels;
4404 }
4405 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4406 bgp_set_valid_label(&extra->label[0]);
4407 }
4408
4409 /* Update SRv6 SID */
4410 if (safi == SAFI_MPLS_VPN) {
4411 extra = bgp_path_info_extra_get(new);
4412 if (attr->srv6_l3vpn) {
4413 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4414 extra->num_sids = 1;
4415
4416 extra->sid[0].loc_block_len =
4417 attr->srv6_l3vpn->loc_block_len;
4418 extra->sid[0].loc_node_len =
4419 attr->srv6_l3vpn->loc_node_len;
4420 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4421 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4422 extra->sid[0].transposition_len =
4423 attr->srv6_l3vpn->transposition_len;
4424 extra->sid[0].transposition_offset =
4425 attr->srv6_l3vpn->transposition_offset;
4426 } else if (attr->srv6_vpn) {
4427 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4428 extra->num_sids = 1;
4429 }
4430 }
4431
4432 /* Nexthop reachability check. */
4433 if (((afi == AFI_IP || afi == AFI_IP6)
4434 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4435 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4436 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4437 && peer->ttl == BGP_DEFAULT_TTL
4438 && !CHECK_FLAG(peer->flags,
4439 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4440 && !CHECK_FLAG(bgp->flags,
4441 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4442 connected = 1;
4443 else
4444 connected = 0;
4445
4446 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4447
4448 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4449 connected, p)
4450 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4451 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4452 else {
4453 if (BGP_DEBUG(nht, NHT)) {
4454 char buf1[INET6_ADDRSTRLEN];
4455 inet_ntop(AF_INET,
4456 (const void *)&attr_new->nexthop,
4457 buf1, INET6_ADDRSTRLEN);
4458 zlog_debug("%s(%s): NH unresolved", __func__,
4459 buf1);
4460 }
4461 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4462 }
4463 } else
4464 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4465
4466 /* Addpath ID */
4467 new->addpath_rx_id = addpath_id;
4468
4469 /* Increment prefix */
4470 bgp_aggregate_increment(bgp, p, new, afi, safi);
4471
4472 /* Register new BGP information. */
4473 bgp_path_info_add(dest, new);
4474
4475 /* route_node_get lock */
4476 bgp_dest_unlock_node(dest);
4477
4478 #ifdef ENABLE_BGP_VNC
4479 if (safi == SAFI_MPLS_VPN) {
4480 struct bgp_dest *pdest = NULL;
4481 struct bgp_table *table = NULL;
4482
4483 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4484 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4485 table = bgp_dest_get_bgp_table_info(pdest);
4486
4487 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4488 bgp, prd, table, p, new);
4489 }
4490 bgp_dest_unlock_node(pdest);
4491 }
4492 #endif
4493
4494 /* If this is an EVPN route, process for import. */
4495 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4496 bgp_evpn_import_route(bgp, afi, safi, p, new);
4497
4498 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4499
4500 /* Process change. */
4501 bgp_process(bgp, dest, afi, safi);
4502
4503 if (SAFI_UNICAST == safi
4504 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4505 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4506 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4507 }
4508 if ((SAFI_MPLS_VPN == safi)
4509 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4510
4511 vpn_leak_to_vrf_update(bgp, new);
4512 }
4513 #ifdef ENABLE_BGP_VNC
4514 if (SAFI_MPLS_VPN == safi) {
4515 mpls_label_t label_decoded = decode_label(label);
4516
4517 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4518 sub_type, &label_decoded);
4519 }
4520 if (SAFI_ENCAP == safi) {
4521 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4522 sub_type, NULL);
4523 }
4524 #endif
4525
4526 return 0;
4527
4528 /* This BGP update is filtered. Log the reason then update BGP
4529 entry. */
4530 filtered:
4531 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4532
4533 if (bgp_debug_update(peer, p, NULL, 1)) {
4534 if (!peer->rcvd_attr_printed) {
4535 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4536 peer->rcvd_attr_str);
4537 peer->rcvd_attr_printed = 1;
4538 }
4539
4540 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4541 addpath_id ? 1 : 0, addpath_id, evpn,
4542 pfx_buf, sizeof(pfx_buf));
4543 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4544 peer->host, pfx_buf, reason);
4545 }
4546
4547 if (pi) {
4548 /* If this is an EVPN route, un-import it as it is now filtered.
4549 */
4550 if (safi == SAFI_EVPN)
4551 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4552
4553 if (SAFI_UNICAST == safi
4554 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4555 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4556
4557 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4558 }
4559 if ((SAFI_MPLS_VPN == safi)
4560 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4561
4562 vpn_leak_to_vrf_withdraw(bgp, pi);
4563 }
4564
4565 bgp_rib_remove(dest, pi, peer, afi, safi);
4566 }
4567
4568 bgp_dest_unlock_node(dest);
4569
4570 #ifdef ENABLE_BGP_VNC
4571 /*
4572 * Filtered update is treated as an implicit withdrawal (see
4573 * bgp_rib_remove()
4574 * a few lines above)
4575 */
4576 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4577 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4578 0);
4579 }
4580 #endif
4581
4582 return 0;
4583 }
4584
4585 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4586 struct attr *attr, afi_t afi, safi_t safi, int type,
4587 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4588 uint32_t num_labels, struct bgp_route_evpn *evpn)
4589 {
4590 struct bgp *bgp;
4591 char pfx_buf[BGP_PRD_PATH_STRLEN];
4592 struct bgp_dest *dest;
4593 struct bgp_path_info *pi;
4594
4595 #ifdef ENABLE_BGP_VNC
4596 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4597 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4598 0);
4599 }
4600 #endif
4601
4602 bgp = peer->bgp;
4603
4604 /* Lookup node. */
4605 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4606
4607 /* If peer is soft reconfiguration enabled. Record input packet for
4608 * further calculation.
4609 *
4610 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4611 * routes that are filtered. This tanks out Quagga RS pretty badly due
4612 * to
4613 * the iteration over all RS clients.
4614 * Since we need to remove the entry from adj_in anyway, do that first
4615 * and
4616 * if there was no entry, we don't need to do anything more.
4617 */
4618 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4619 && peer != bgp->peer_self)
4620 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4621 peer->stat_pfx_dup_withdraw++;
4622
4623 if (bgp_debug_update(peer, p, NULL, 1)) {
4624 bgp_debug_rdpfxpath2str(
4625 afi, safi, prd, p, label, num_labels,
4626 addpath_id ? 1 : 0, addpath_id, NULL,
4627 pfx_buf, sizeof(pfx_buf));
4628 zlog_debug(
4629 "%s withdrawing route %s not in adj-in",
4630 peer->host, pfx_buf);
4631 }
4632 bgp_dest_unlock_node(dest);
4633 return 0;
4634 }
4635
4636 /* Lookup withdrawn route. */
4637 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4638 if (pi->peer == peer && pi->type == type
4639 && pi->sub_type == sub_type
4640 && pi->addpath_rx_id == addpath_id)
4641 break;
4642
4643 /* Logging. */
4644 if (bgp_debug_update(peer, p, NULL, 1)) {
4645 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4646 addpath_id ? 1 : 0, addpath_id, NULL,
4647 pfx_buf, sizeof(pfx_buf));
4648 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4649 pfx_buf);
4650 }
4651
4652 /* Withdraw specified route from routing table. */
4653 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4654 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4655 if (SAFI_UNICAST == safi
4656 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4657 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4658 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4659 }
4660 if ((SAFI_MPLS_VPN == safi)
4661 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4662
4663 vpn_leak_to_vrf_withdraw(bgp, pi);
4664 }
4665 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4666 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4667 addpath_id ? 1 : 0, addpath_id, NULL,
4668 pfx_buf, sizeof(pfx_buf));
4669 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4670 }
4671
4672 /* Unlock bgp_node_get() lock. */
4673 bgp_dest_unlock_node(dest);
4674
4675 return 0;
4676 }
4677
4678 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4679 int withdraw)
4680 {
4681 struct update_subgroup *subgrp;
4682 subgrp = peer_subgroup(peer, afi, safi);
4683 subgroup_default_originate(subgrp, withdraw);
4684 }
4685
4686
4687 /*
4688 * bgp_stop_announce_route_timer
4689 */
4690 void bgp_stop_announce_route_timer(struct peer_af *paf)
4691 {
4692 if (!paf->t_announce_route)
4693 return;
4694
4695 thread_cancel(&paf->t_announce_route);
4696 }
4697
4698 /*
4699 * bgp_announce_route_timer_expired
4700 *
4701 * Callback that is invoked when the route announcement timer for a
4702 * peer_af expires.
4703 */
4704 static void bgp_announce_route_timer_expired(struct thread *t)
4705 {
4706 struct peer_af *paf;
4707 struct peer *peer;
4708
4709 paf = THREAD_ARG(t);
4710 peer = paf->peer;
4711
4712 if (!peer_established(peer))
4713 return;
4714
4715 if (!peer->afc_nego[paf->afi][paf->safi])
4716 return;
4717
4718 peer_af_announce_route(paf, 1);
4719
4720 /* Notify BGP conditional advertisement scanner percess */
4721 peer->advmap_config_change[paf->afi][paf->safi] = true;
4722 }
4723
4724 /*
4725 * bgp_announce_route
4726 *
4727 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4728 *
4729 * if force is true we will force an update even if the update
4730 * limiting code is attempted to kick in.
4731 */
4732 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
4733 {
4734 struct peer_af *paf;
4735 struct update_subgroup *subgrp;
4736
4737 paf = peer_af_find(peer, afi, safi);
4738 if (!paf)
4739 return;
4740 subgrp = PAF_SUBGRP(paf);
4741
4742 /*
4743 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4744 * or a refresh has already been triggered.
4745 */
4746 if (!subgrp || paf->t_announce_route)
4747 return;
4748
4749 if (force)
4750 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
4751
4752 /*
4753 * Start a timer to stagger/delay the announce. This serves
4754 * two purposes - announcement can potentially be combined for
4755 * multiple peers and the announcement doesn't happen in the
4756 * vty context.
4757 */
4758 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4759 (subgrp->peer_count == 1)
4760 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4761 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4762 &paf->t_announce_route);
4763 }
4764
4765 /*
4766 * Announce routes from all AF tables to a peer.
4767 *
4768 * This should ONLY be called when there is a need to refresh the
4769 * routes to the peer based on a policy change for this peer alone
4770 * or a route refresh request received from the peer.
4771 * The operation will result in splitting the peer from its existing
4772 * subgroups and putting it in new subgroups.
4773 */
4774 void bgp_announce_route_all(struct peer *peer)
4775 {
4776 afi_t afi;
4777 safi_t safi;
4778
4779 FOREACH_AFI_SAFI (afi, safi)
4780 bgp_announce_route(peer, afi, safi, false);
4781 }
4782
4783 /* Flag or unflag bgp_dest to determine whether it should be treated by
4784 * bgp_soft_reconfig_table_task.
4785 * Flag if flag is true. Unflag if flag is false.
4786 */
4787 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
4788 {
4789 struct bgp_dest *dest;
4790 struct bgp_adj_in *ain;
4791
4792 if (!table)
4793 return;
4794
4795 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4796 for (ain = dest->adj_in; ain; ain = ain->next) {
4797 if (ain->peer != NULL)
4798 break;
4799 }
4800 if (flag && ain != NULL && ain->peer != NULL)
4801 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4802 else
4803 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4804 }
4805 }
4806
4807 static int bgp_soft_reconfig_table_update(struct peer *peer,
4808 struct bgp_dest *dest,
4809 struct bgp_adj_in *ain, afi_t afi,
4810 safi_t safi, struct prefix_rd *prd)
4811 {
4812 struct bgp_path_info *pi;
4813 uint32_t num_labels = 0;
4814 mpls_label_t *label_pnt = NULL;
4815 struct bgp_route_evpn evpn;
4816
4817 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4818 if (pi->peer == peer)
4819 break;
4820
4821 if (pi && pi->extra)
4822 num_labels = pi->extra->num_labels;
4823 if (num_labels)
4824 label_pnt = &pi->extra->label[0];
4825 if (pi)
4826 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
4827 sizeof(evpn));
4828 else
4829 memset(&evpn, 0, sizeof(evpn));
4830
4831 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
4832 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
4833 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
4834 &evpn);
4835 }
4836
4837 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4838 struct bgp_table *table,
4839 struct prefix_rd *prd)
4840 {
4841 int ret;
4842 struct bgp_dest *dest;
4843 struct bgp_adj_in *ain;
4844
4845 if (!table)
4846 table = peer->bgp->rib[afi][safi];
4847
4848 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4849 for (ain = dest->adj_in; ain; ain = ain->next) {
4850 if (ain->peer != peer)
4851 continue;
4852
4853 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
4854 afi, safi, prd);
4855
4856 if (ret < 0) {
4857 bgp_dest_unlock_node(dest);
4858 return;
4859 }
4860 }
4861 }
4862
4863 /* Do soft reconfig table per bgp table.
4864 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
4865 * when BGP_NODE_SOFT_RECONFIG is set,
4866 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
4867 * Schedule a new thread to continue the job.
4868 * Without splitting the full job into several part,
4869 * vtysh waits for the job to finish before responding to a BGP command
4870 */
4871 static void bgp_soft_reconfig_table_task(struct thread *thread)
4872 {
4873 uint32_t iter, max_iter;
4874 int ret;
4875 struct bgp_dest *dest;
4876 struct bgp_adj_in *ain;
4877 struct peer *peer;
4878 struct bgp_table *table;
4879 struct prefix_rd *prd;
4880 struct listnode *node, *nnode;
4881
4882 table = THREAD_ARG(thread);
4883 prd = NULL;
4884
4885 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
4886 if (table->soft_reconfig_init) {
4887 /* first call of the function with a new srta structure.
4888 * Don't do any treatment this time on nodes
4889 * in order vtysh to respond quickly
4890 */
4891 max_iter = 0;
4892 }
4893
4894 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
4895 dest = bgp_route_next(dest)) {
4896 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
4897 continue;
4898
4899 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4900
4901 for (ain = dest->adj_in; ain; ain = ain->next) {
4902 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
4903 nnode, peer)) {
4904 if (ain->peer != peer)
4905 continue;
4906
4907 ret = bgp_soft_reconfig_table_update(
4908 peer, dest, ain, table->afi,
4909 table->safi, prd);
4910 iter++;
4911
4912 if (ret < 0) {
4913 bgp_dest_unlock_node(dest);
4914 listnode_delete(
4915 table->soft_reconfig_peers,
4916 peer);
4917 bgp_announce_route(peer, table->afi,
4918 table->safi, false);
4919 if (list_isempty(
4920 table->soft_reconfig_peers)) {
4921 list_delete(
4922 &table->soft_reconfig_peers);
4923 bgp_soft_reconfig_table_flag(
4924 table, false);
4925 return;
4926 }
4927 }
4928 }
4929 }
4930 }
4931
4932 /* we're either starting the initial iteration,
4933 * or we're going to continue an ongoing iteration
4934 */
4935 if (dest || table->soft_reconfig_init) {
4936 table->soft_reconfig_init = false;
4937 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
4938 table, 0, &table->soft_reconfig_thread);
4939 return;
4940 }
4941 /* we're done, clean up the background iteration context info and
4942 schedule route annoucement
4943 */
4944 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
4945 listnode_delete(table->soft_reconfig_peers, peer);
4946 bgp_announce_route(peer, table->afi, table->safi, false);
4947 }
4948
4949 list_delete(&table->soft_reconfig_peers);
4950 }
4951
4952
4953 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
4954 * and peer.
4955 * - bgp cannot be NULL
4956 * - if table and peer are NULL, cancel all threads within the bgp instance
4957 * - if table is NULL and peer is not,
4958 * remove peer in all threads within the bgp instance
4959 * - if peer is NULL, cancel all threads matching table within the bgp instance
4960 */
4961 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
4962 const struct bgp_table *table,
4963 const struct peer *peer)
4964 {
4965 struct peer *npeer;
4966 struct listnode *node, *nnode;
4967 int afi, safi;
4968 struct bgp_table *ntable;
4969
4970 if (!bgp)
4971 return;
4972
4973 FOREACH_AFI_SAFI (afi, safi) {
4974 ntable = bgp->rib[afi][safi];
4975 if (!ntable)
4976 continue;
4977 if (table && table != ntable)
4978 continue;
4979
4980 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
4981 npeer)) {
4982 if (peer && peer != npeer)
4983 continue;
4984 listnode_delete(ntable->soft_reconfig_peers, npeer);
4985 }
4986
4987 if (!ntable->soft_reconfig_peers
4988 || !list_isempty(ntable->soft_reconfig_peers))
4989 continue;
4990
4991 list_delete(&ntable->soft_reconfig_peers);
4992 bgp_soft_reconfig_table_flag(ntable, false);
4993 BGP_TIMER_OFF(ntable->soft_reconfig_thread);
4994 }
4995 }
4996
4997 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4998 {
4999 struct bgp_dest *dest;
5000 struct bgp_table *table;
5001 struct listnode *node, *nnode;
5002 struct peer *npeer;
5003 struct peer_af *paf;
5004
5005 if (!peer_established(peer))
5006 return;
5007
5008 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
5009 && (safi != SAFI_EVPN)) {
5010 table = peer->bgp->rib[afi][safi];
5011 if (!table)
5012 return;
5013
5014 table->soft_reconfig_init = true;
5015
5016 if (!table->soft_reconfig_peers)
5017 table->soft_reconfig_peers = list_new();
5018 npeer = NULL;
5019 /* add peer to the table soft_reconfig_peers if not already
5020 * there
5021 */
5022 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5023 npeer)) {
5024 if (peer == npeer)
5025 break;
5026 }
5027 if (peer != npeer)
5028 listnode_add(table->soft_reconfig_peers, peer);
5029
5030 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5031 * on table would start back at the beginning.
5032 */
5033 bgp_soft_reconfig_table_flag(table, true);
5034
5035 if (!table->soft_reconfig_thread)
5036 thread_add_event(bm->master,
5037 bgp_soft_reconfig_table_task, table, 0,
5038 &table->soft_reconfig_thread);
5039 /* Cancel bgp_announce_route_timer_expired threads.
5040 * bgp_announce_route_timer_expired threads have been scheduled
5041 * to announce routes as soon as the soft_reconfigure process
5042 * finishes.
5043 * In this case, soft_reconfigure is also scheduled by using
5044 * a thread but is planned after the
5045 * bgp_announce_route_timer_expired threads. It means that,
5046 * without cancelling the threads, the route announcement task
5047 * would run before the soft reconfiguration one. That would
5048 * useless and would block vtysh during several seconds. Route
5049 * announcements are rescheduled as soon as the soft_reconfigure
5050 * process finishes.
5051 */
5052 paf = peer_af_find(peer, afi, safi);
5053 if (paf)
5054 bgp_stop_announce_route_timer(paf);
5055 } else
5056 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5057 dest = bgp_route_next(dest)) {
5058 table = bgp_dest_get_bgp_table_info(dest);
5059
5060 if (table == NULL)
5061 continue;
5062
5063 const struct prefix *p = bgp_dest_get_prefix(dest);
5064 struct prefix_rd prd;
5065
5066 prd.family = AF_UNSPEC;
5067 prd.prefixlen = 64;
5068 memcpy(&prd.val, p->u.val, 8);
5069
5070 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5071 }
5072 }
5073
5074
5075 struct bgp_clear_node_queue {
5076 struct bgp_dest *dest;
5077 };
5078
5079 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5080 {
5081 struct bgp_clear_node_queue *cnq = data;
5082 struct bgp_dest *dest = cnq->dest;
5083 struct peer *peer = wq->spec.data;
5084 struct bgp_path_info *pi;
5085 struct bgp *bgp;
5086 afi_t afi = bgp_dest_table(dest)->afi;
5087 safi_t safi = bgp_dest_table(dest)->safi;
5088
5089 assert(dest && peer);
5090 bgp = peer->bgp;
5091
5092 /* It is possible that we have multiple paths for a prefix from a peer
5093 * if that peer is using AddPath.
5094 */
5095 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5096 if (pi->peer != peer)
5097 continue;
5098
5099 /* graceful restart STALE flag set. */
5100 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5101 && peer->nsf[afi][safi])
5102 || CHECK_FLAG(peer->af_sflags[afi][safi],
5103 PEER_STATUS_ENHANCED_REFRESH))
5104 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5105 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5106 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5107 else {
5108 /* If this is an EVPN route, process for
5109 * un-import. */
5110 if (safi == SAFI_EVPN)
5111 bgp_evpn_unimport_route(
5112 bgp, afi, safi,
5113 bgp_dest_get_prefix(dest), pi);
5114 /* Handle withdraw for VRF route-leaking and L3VPN */
5115 if (SAFI_UNICAST == safi
5116 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5117 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5118 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5119 bgp, pi);
5120 }
5121 if (SAFI_MPLS_VPN == safi &&
5122 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5123 vpn_leak_to_vrf_withdraw(bgp, pi);
5124 }
5125
5126 bgp_rib_remove(dest, pi, peer, afi, safi);
5127 }
5128 }
5129 return WQ_SUCCESS;
5130 }
5131
5132 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5133 {
5134 struct bgp_clear_node_queue *cnq = data;
5135 struct bgp_dest *dest = cnq->dest;
5136 struct bgp_table *table = bgp_dest_table(dest);
5137
5138 bgp_dest_unlock_node(dest);
5139 bgp_table_unlock(table);
5140 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5141 }
5142
5143 static void bgp_clear_node_complete(struct work_queue *wq)
5144 {
5145 struct peer *peer = wq->spec.data;
5146
5147 /* Tickle FSM to start moving again */
5148 BGP_EVENT_ADD(peer, Clearing_Completed);
5149
5150 peer_unlock(peer); /* bgp_clear_route */
5151 }
5152
5153 static void bgp_clear_node_queue_init(struct peer *peer)
5154 {
5155 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5156
5157 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5158 #undef CLEAR_QUEUE_NAME_LEN
5159
5160 peer->clear_node_queue = work_queue_new(bm->master, wname);
5161 peer->clear_node_queue->spec.hold = 10;
5162 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5163 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5164 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5165 peer->clear_node_queue->spec.max_retries = 0;
5166
5167 /* we only 'lock' this peer reference when the queue is actually active
5168 */
5169 peer->clear_node_queue->spec.data = peer;
5170 }
5171
5172 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5173 struct bgp_table *table)
5174 {
5175 struct bgp_dest *dest;
5176 int force = peer->bgp->process_queue ? 0 : 1;
5177
5178 if (!table)
5179 table = peer->bgp->rib[afi][safi];
5180
5181 /* If still no table => afi/safi isn't configured at all or smth. */
5182 if (!table)
5183 return;
5184
5185 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5186 struct bgp_path_info *pi, *next;
5187 struct bgp_adj_in *ain;
5188 struct bgp_adj_in *ain_next;
5189
5190 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5191 * queued for every clearing peer, regardless of whether it is
5192 * relevant to the peer at hand.
5193 *
5194 * Overview: There are 3 different indices which need to be
5195 * scrubbed, potentially, when a peer is removed:
5196 *
5197 * 1 peer's routes visible via the RIB (ie accepted routes)
5198 * 2 peer's routes visible by the (optional) peer's adj-in index
5199 * 3 other routes visible by the peer's adj-out index
5200 *
5201 * 3 there is no hurry in scrubbing, once the struct peer is
5202 * removed from bgp->peer, we could just GC such deleted peer's
5203 * adj-outs at our leisure.
5204 *
5205 * 1 and 2 must be 'scrubbed' in some way, at least made
5206 * invisible via RIB index before peer session is allowed to be
5207 * brought back up. So one needs to know when such a 'search' is
5208 * complete.
5209 *
5210 * Ideally:
5211 *
5212 * - there'd be a single global queue or a single RIB walker
5213 * - rather than tracking which route_nodes still need to be
5214 * examined on a peer basis, we'd track which peers still
5215 * aren't cleared
5216 *
5217 * Given that our per-peer prefix-counts now should be reliable,
5218 * this may actually be achievable. It doesn't seem to be a huge
5219 * problem at this time,
5220 *
5221 * It is possible that we have multiple paths for a prefix from
5222 * a peer
5223 * if that peer is using AddPath.
5224 */
5225 ain = dest->adj_in;
5226 while (ain) {
5227 ain_next = ain->next;
5228
5229 if (ain->peer == peer)
5230 bgp_adj_in_remove(dest, ain);
5231
5232 ain = ain_next;
5233 }
5234
5235 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5236 next = pi->next;
5237 if (pi->peer != peer)
5238 continue;
5239
5240 if (force)
5241 bgp_path_info_reap(dest, pi);
5242 else {
5243 struct bgp_clear_node_queue *cnq;
5244
5245 /* both unlocked in bgp_clear_node_queue_del */
5246 bgp_table_lock(bgp_dest_table(dest));
5247 bgp_dest_lock_node(dest);
5248 cnq = XCALLOC(
5249 MTYPE_BGP_CLEAR_NODE_QUEUE,
5250 sizeof(struct bgp_clear_node_queue));
5251 cnq->dest = dest;
5252 work_queue_add(peer->clear_node_queue, cnq);
5253 break;
5254 }
5255 }
5256 }
5257 return;
5258 }
5259
5260 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5261 {
5262 struct bgp_dest *dest;
5263 struct bgp_table *table;
5264
5265 if (peer->clear_node_queue == NULL)
5266 bgp_clear_node_queue_init(peer);
5267
5268 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5269 * Idle until it receives a Clearing_Completed event. This protects
5270 * against peers which flap faster than we can we clear, which could
5271 * lead to:
5272 *
5273 * a) race with routes from the new session being installed before
5274 * clear_route_node visits the node (to delete the route of that
5275 * peer)
5276 * b) resource exhaustion, clear_route_node likely leads to an entry
5277 * on the process_main queue. Fast-flapping could cause that queue
5278 * to grow and grow.
5279 */
5280
5281 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5282 * the unlock will happen upon work-queue completion; other wise, the
5283 * unlock happens at the end of this function.
5284 */
5285 if (!peer->clear_node_queue->thread)
5286 peer_lock(peer);
5287
5288 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5289 bgp_clear_route_table(peer, afi, safi, NULL);
5290 else
5291 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5292 dest = bgp_route_next(dest)) {
5293 table = bgp_dest_get_bgp_table_info(dest);
5294 if (!table)
5295 continue;
5296
5297 bgp_clear_route_table(peer, afi, safi, table);
5298 }
5299
5300 /* unlock if no nodes got added to the clear-node-queue. */
5301 if (!peer->clear_node_queue->thread)
5302 peer_unlock(peer);
5303 }
5304
5305 void bgp_clear_route_all(struct peer *peer)
5306 {
5307 afi_t afi;
5308 safi_t safi;
5309
5310 FOREACH_AFI_SAFI (afi, safi)
5311 bgp_clear_route(peer, afi, safi);
5312
5313 #ifdef ENABLE_BGP_VNC
5314 rfapiProcessPeerDown(peer);
5315 #endif
5316 }
5317
5318 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5319 {
5320 struct bgp_table *table;
5321 struct bgp_dest *dest;
5322 struct bgp_adj_in *ain;
5323 struct bgp_adj_in *ain_next;
5324
5325 table = peer->bgp->rib[afi][safi];
5326
5327 /* It is possible that we have multiple paths for a prefix from a peer
5328 * if that peer is using AddPath.
5329 */
5330 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5331 ain = dest->adj_in;
5332
5333 while (ain) {
5334 ain_next = ain->next;
5335
5336 if (ain->peer == peer)
5337 bgp_adj_in_remove(dest, ain);
5338
5339 ain = ain_next;
5340 }
5341 }
5342 }
5343
5344 /* If any of the routes from the peer have been marked with the NO_LLGR
5345 * community, either as sent by the peer, or as the result of a configured
5346 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5347 * operation of [RFC4271].
5348 */
5349 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5350 {
5351 struct bgp_dest *dest;
5352 struct bgp_path_info *pi;
5353 struct bgp_table *table;
5354
5355 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5356 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5357 dest = bgp_route_next(dest)) {
5358 struct bgp_dest *rm;
5359
5360 /* look for neighbor in tables */
5361 table = bgp_dest_get_bgp_table_info(dest);
5362 if (!table)
5363 continue;
5364
5365 for (rm = bgp_table_top(table); rm;
5366 rm = bgp_route_next(rm))
5367 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5368 pi = pi->next) {
5369 if (pi->peer != peer)
5370 continue;
5371 if (CHECK_FLAG(
5372 peer->af_sflags[afi][safi],
5373 PEER_STATUS_LLGR_WAIT) &&
5374 bgp_attr_get_community(pi->attr) &&
5375 !community_include(
5376 bgp_attr_get_community(
5377 pi->attr),
5378 COMMUNITY_NO_LLGR))
5379 continue;
5380 if (!CHECK_FLAG(pi->flags,
5381 BGP_PATH_STALE))
5382 continue;
5383
5384 /*
5385 * If this is VRF leaked route
5386 * process for withdraw.
5387 */
5388 if (pi->sub_type ==
5389 BGP_ROUTE_IMPORTED &&
5390 peer->bgp->inst_type ==
5391 BGP_INSTANCE_TYPE_DEFAULT)
5392 vpn_leak_to_vrf_withdraw(
5393 peer->bgp, pi);
5394
5395 bgp_rib_remove(rm, pi, peer, afi, safi);
5396 break;
5397 }
5398 }
5399 } else {
5400 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5401 dest = bgp_route_next(dest))
5402 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5403 pi = pi->next) {
5404 if (pi->peer != peer)
5405 continue;
5406 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5407 PEER_STATUS_LLGR_WAIT) &&
5408 bgp_attr_get_community(pi->attr) &&
5409 !community_include(
5410 bgp_attr_get_community(pi->attr),
5411 COMMUNITY_NO_LLGR))
5412 continue;
5413 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5414 continue;
5415 if (safi == SAFI_UNICAST &&
5416 (peer->bgp->inst_type ==
5417 BGP_INSTANCE_TYPE_VRF ||
5418 peer->bgp->inst_type ==
5419 BGP_INSTANCE_TYPE_DEFAULT))
5420 vpn_leak_from_vrf_withdraw(
5421 bgp_get_default(), peer->bgp,
5422 pi);
5423
5424 bgp_rib_remove(dest, pi, peer, afi, safi);
5425 break;
5426 }
5427 }
5428 }
5429
5430 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5431 {
5432 struct bgp_dest *dest, *ndest;
5433 struct bgp_path_info *pi;
5434 struct bgp_table *table;
5435
5436 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5437 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5438 dest = bgp_route_next(dest)) {
5439 table = bgp_dest_get_bgp_table_info(dest);
5440 if (!table)
5441 continue;
5442
5443 for (ndest = bgp_table_top(table); ndest;
5444 ndest = bgp_route_next(ndest)) {
5445 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5446 pi = pi->next) {
5447 if (pi->peer != peer)
5448 continue;
5449
5450 if ((CHECK_FLAG(
5451 peer->af_sflags[afi][safi],
5452 PEER_STATUS_ENHANCED_REFRESH))
5453 && !CHECK_FLAG(pi->flags,
5454 BGP_PATH_STALE)
5455 && !CHECK_FLAG(
5456 pi->flags,
5457 BGP_PATH_UNUSEABLE)) {
5458 if (bgp_debug_neighbor_events(
5459 peer))
5460 zlog_debug(
5461 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5462 peer->host,
5463 afi2str(afi),
5464 safi2str(safi),
5465 bgp_dest_get_prefix(
5466 ndest));
5467
5468 bgp_path_info_set_flag(
5469 ndest, pi,
5470 BGP_PATH_STALE);
5471 }
5472 }
5473 }
5474 }
5475 } else {
5476 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5477 dest = bgp_route_next(dest)) {
5478 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5479 pi = pi->next) {
5480 if (pi->peer != peer)
5481 continue;
5482
5483 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5484 PEER_STATUS_ENHANCED_REFRESH))
5485 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5486 && !CHECK_FLAG(pi->flags,
5487 BGP_PATH_UNUSEABLE)) {
5488 if (bgp_debug_neighbor_events(peer))
5489 zlog_debug(
5490 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5491 peer->host,
5492 afi2str(afi),
5493 safi2str(safi),
5494 bgp_dest_get_prefix(
5495 dest));
5496
5497 bgp_path_info_set_flag(dest, pi,
5498 BGP_PATH_STALE);
5499 }
5500 }
5501 }
5502 }
5503 }
5504
5505 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5506 {
5507 if (peer->sort == BGP_PEER_IBGP)
5508 return true;
5509
5510 if (peer->sort == BGP_PEER_EBGP
5511 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5512 || FILTER_LIST_OUT_NAME(filter)
5513 || DISTRIBUTE_OUT_NAME(filter)))
5514 return true;
5515 return false;
5516 }
5517
5518 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5519 {
5520 if (peer->sort == BGP_PEER_IBGP)
5521 return true;
5522
5523 if (peer->sort == BGP_PEER_EBGP
5524 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5525 || FILTER_LIST_IN_NAME(filter)
5526 || DISTRIBUTE_IN_NAME(filter)))
5527 return true;
5528 return false;
5529 }
5530
5531 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5532 safi_t safi)
5533 {
5534 struct bgp_dest *dest;
5535 struct bgp_path_info *pi;
5536 struct bgp_path_info *next;
5537
5538 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5539 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5540 const struct prefix *p = bgp_dest_get_prefix(dest);
5541
5542 next = pi->next;
5543
5544 /* Unimport EVPN routes from VRFs */
5545 if (safi == SAFI_EVPN)
5546 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5547 SAFI_EVPN, p, pi);
5548
5549 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5550 && pi->type == ZEBRA_ROUTE_BGP
5551 && (pi->sub_type == BGP_ROUTE_NORMAL
5552 || pi->sub_type == BGP_ROUTE_AGGREGATE
5553 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5554
5555 if (bgp_fibupd_safi(safi))
5556 bgp_zebra_withdraw(p, pi, bgp, safi);
5557 }
5558
5559 bgp_path_info_reap(dest, pi);
5560 }
5561 }
5562
5563 /* Delete all kernel routes. */
5564 void bgp_cleanup_routes(struct bgp *bgp)
5565 {
5566 afi_t afi;
5567 struct bgp_dest *dest;
5568 struct bgp_table *table;
5569
5570 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5571 if (afi == AFI_L2VPN)
5572 continue;
5573 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5574 SAFI_UNICAST);
5575 /*
5576 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5577 */
5578 if (afi != AFI_L2VPN) {
5579 safi_t safi;
5580 safi = SAFI_MPLS_VPN;
5581 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5582 dest = bgp_route_next(dest)) {
5583 table = bgp_dest_get_bgp_table_info(dest);
5584 if (table != NULL) {
5585 bgp_cleanup_table(bgp, table, safi);
5586 bgp_table_finish(&table);
5587 bgp_dest_set_bgp_table_info(dest, NULL);
5588 bgp_dest_unlock_node(dest);
5589 }
5590 }
5591 safi = SAFI_ENCAP;
5592 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5593 dest = bgp_route_next(dest)) {
5594 table = bgp_dest_get_bgp_table_info(dest);
5595 if (table != NULL) {
5596 bgp_cleanup_table(bgp, table, safi);
5597 bgp_table_finish(&table);
5598 bgp_dest_set_bgp_table_info(dest, NULL);
5599 bgp_dest_unlock_node(dest);
5600 }
5601 }
5602 }
5603 }
5604 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5605 dest = bgp_route_next(dest)) {
5606 table = bgp_dest_get_bgp_table_info(dest);
5607 if (table != NULL) {
5608 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5609 bgp_table_finish(&table);
5610 bgp_dest_set_bgp_table_info(dest, NULL);
5611 bgp_dest_unlock_node(dest);
5612 }
5613 }
5614 }
5615
5616 void bgp_reset(void)
5617 {
5618 vty_reset();
5619 bgp_zclient_reset();
5620 access_list_reset();
5621 prefix_list_reset();
5622 }
5623
5624 bool bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5625 {
5626 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5627 && CHECK_FLAG(peer->af_cap[afi][safi],
5628 PEER_CAP_ADDPATH_AF_TX_RCV));
5629 }
5630
5631 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5632 value. */
5633 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5634 struct bgp_nlri *packet)
5635 {
5636 uint8_t *pnt;
5637 uint8_t *lim;
5638 struct prefix p;
5639 int psize;
5640 int ret;
5641 afi_t afi;
5642 safi_t safi;
5643 bool addpath_capable;
5644 uint32_t addpath_id;
5645
5646 pnt = packet->nlri;
5647 lim = pnt + packet->length;
5648 afi = packet->afi;
5649 safi = packet->safi;
5650 addpath_id = 0;
5651 addpath_capable = bgp_addpath_encode_rx(peer, afi, safi);
5652
5653 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5654 syntactic validity. If the field is syntactically incorrect,
5655 then the Error Subcode is set to Invalid Network Field. */
5656 for (; pnt < lim; pnt += psize) {
5657 /* Clear prefix structure. */
5658 memset(&p, 0, sizeof(struct prefix));
5659
5660 if (addpath_capable) {
5661
5662 /* When packet overflow occurs return immediately. */
5663 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5664 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5665
5666 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5667 addpath_id = ntohl(addpath_id);
5668 pnt += BGP_ADDPATH_ID_LEN;
5669 }
5670
5671 /* Fetch prefix length. */
5672 p.prefixlen = *pnt++;
5673 /* afi/safi validity already verified by caller,
5674 * bgp_update_receive */
5675 p.family = afi2family(afi);
5676
5677 /* Prefix length check. */
5678 if (p.prefixlen > prefix_blen(&p) * 8) {
5679 flog_err(
5680 EC_BGP_UPDATE_RCV,
5681 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5682 peer->host, p.prefixlen, packet->afi);
5683 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5684 }
5685
5686 /* Packet size overflow check. */
5687 psize = PSIZE(p.prefixlen);
5688
5689 /* When packet overflow occur return immediately. */
5690 if (pnt + psize > lim) {
5691 flog_err(
5692 EC_BGP_UPDATE_RCV,
5693 "%s [Error] Update packet error (prefix length %d overflows packet)",
5694 peer->host, p.prefixlen);
5695 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5696 }
5697
5698 /* Defensive coding, double-check the psize fits in a struct
5699 * prefix */
5700 if (psize > (ssize_t)sizeof(p.u)) {
5701 flog_err(
5702 EC_BGP_UPDATE_RCV,
5703 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5704 peer->host, p.prefixlen, sizeof(p.u));
5705 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5706 }
5707
5708 /* Fetch prefix from NLRI packet. */
5709 memcpy(p.u.val, pnt, psize);
5710
5711 /* Check address. */
5712 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5713 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5714 /* From RFC4271 Section 6.3:
5715 *
5716 * If a prefix in the NLRI field is semantically
5717 * incorrect
5718 * (e.g., an unexpected multicast IP address),
5719 * an error SHOULD
5720 * be logged locally, and the prefix SHOULD be
5721 * ignored.
5722 */
5723 flog_err(
5724 EC_BGP_UPDATE_RCV,
5725 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5726 peer->host, &p.u.prefix4);
5727 continue;
5728 }
5729 }
5730
5731 /* Check address. */
5732 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5733 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5734 flog_err(
5735 EC_BGP_UPDATE_RCV,
5736 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
5737 peer->host, &p.u.prefix6);
5738
5739 continue;
5740 }
5741 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5742 flog_err(
5743 EC_BGP_UPDATE_RCV,
5744 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
5745 peer->host, &p.u.prefix6);
5746
5747 continue;
5748 }
5749 }
5750
5751 /* Normal process. */
5752 if (attr)
5753 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5754 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5755 NULL, NULL, 0, 0, NULL);
5756 else
5757 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5758 safi, ZEBRA_ROUTE_BGP,
5759 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5760 NULL);
5761
5762 /* Do not send BGP notification twice when maximum-prefix count
5763 * overflow. */
5764 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5765 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5766
5767 /* Address family configuration mismatch. */
5768 if (ret < 0)
5769 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5770 }
5771
5772 /* Packet length consistency check. */
5773 if (pnt != lim) {
5774 flog_err(
5775 EC_BGP_UPDATE_RCV,
5776 "%s [Error] Update packet error (prefix length mismatch with total length)",
5777 peer->host);
5778 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5779 }
5780
5781 return BGP_NLRI_PARSE_OK;
5782 }
5783
5784 static struct bgp_static *bgp_static_new(void)
5785 {
5786 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5787 }
5788
5789 static void bgp_static_free(struct bgp_static *bgp_static)
5790 {
5791 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5792 route_map_counter_decrement(bgp_static->rmap.map);
5793
5794 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5795 XFREE(MTYPE_BGP_STATIC, bgp_static);
5796 }
5797
5798 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5799 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5800 {
5801 struct bgp_dest *dest;
5802 struct bgp_path_info *pi;
5803 struct bgp_path_info *new;
5804 struct bgp_path_info rmap_path;
5805 struct attr attr;
5806 struct attr *attr_new;
5807 route_map_result_t ret;
5808 #ifdef ENABLE_BGP_VNC
5809 int vnc_implicit_withdraw = 0;
5810 #endif
5811
5812 assert(bgp_static);
5813
5814 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5815
5816 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5817
5818 attr.nexthop = bgp_static->igpnexthop;
5819 attr.med = bgp_static->igpmetric;
5820 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5821
5822 if (bgp_static->atomic)
5823 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5824
5825 /* Store label index, if required. */
5826 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5827 attr.label_index = bgp_static->label_index;
5828 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5829 }
5830
5831 /* Apply route-map. */
5832 if (bgp_static->rmap.name) {
5833 struct attr attr_tmp = attr;
5834
5835 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5836 rmap_path.peer = bgp->peer_self;
5837 rmap_path.attr = &attr_tmp;
5838
5839 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5840
5841 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5842
5843 bgp->peer_self->rmap_type = 0;
5844
5845 if (ret == RMAP_DENYMATCH) {
5846 /* Free uninterned attribute. */
5847 bgp_attr_flush(&attr_tmp);
5848
5849 /* Unintern original. */
5850 aspath_unintern(&attr.aspath);
5851 bgp_static_withdraw(bgp, p, afi, safi);
5852 return;
5853 }
5854
5855 if (bgp_in_graceful_shutdown(bgp))
5856 bgp_attr_add_gshut_community(&attr_tmp);
5857
5858 attr_new = bgp_attr_intern(&attr_tmp);
5859 } else {
5860
5861 if (bgp_in_graceful_shutdown(bgp))
5862 bgp_attr_add_gshut_community(&attr);
5863
5864 attr_new = bgp_attr_intern(&attr);
5865 }
5866
5867 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5868 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5869 && pi->sub_type == BGP_ROUTE_STATIC)
5870 break;
5871
5872 if (pi) {
5873 if (attrhash_cmp(pi->attr, attr_new)
5874 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5875 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5876 bgp_dest_unlock_node(dest);
5877 bgp_attr_unintern(&attr_new);
5878 aspath_unintern(&attr.aspath);
5879 return;
5880 } else {
5881 /* The attribute is changed. */
5882 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5883
5884 /* Rewrite BGP route information. */
5885 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5886 bgp_path_info_restore(dest, pi);
5887 else
5888 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5889 #ifdef ENABLE_BGP_VNC
5890 if ((afi == AFI_IP || afi == AFI_IP6)
5891 && (safi == SAFI_UNICAST)) {
5892 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5893 /*
5894 * Implicit withdraw case.
5895 * We have to do this before pi is
5896 * changed
5897 */
5898 ++vnc_implicit_withdraw;
5899 vnc_import_bgp_del_route(bgp, p, pi);
5900 vnc_import_bgp_exterior_del_route(
5901 bgp, p, pi);
5902 }
5903 }
5904 #endif
5905 bgp_attr_unintern(&pi->attr);
5906 pi->attr = attr_new;
5907 pi->uptime = bgp_clock();
5908 #ifdef ENABLE_BGP_VNC
5909 if ((afi == AFI_IP || afi == AFI_IP6)
5910 && (safi == SAFI_UNICAST)) {
5911 if (vnc_implicit_withdraw) {
5912 vnc_import_bgp_add_route(bgp, p, pi);
5913 vnc_import_bgp_exterior_add_route(
5914 bgp, p, pi);
5915 }
5916 }
5917 #endif
5918
5919 /* Nexthop reachability check. */
5920 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5921 && (safi == SAFI_UNICAST
5922 || safi == SAFI_LABELED_UNICAST)) {
5923
5924 struct bgp *bgp_nexthop = bgp;
5925
5926 if (pi->extra && pi->extra->bgp_orig)
5927 bgp_nexthop = pi->extra->bgp_orig;
5928
5929 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5930 afi, safi, pi, NULL,
5931 0, p))
5932 bgp_path_info_set_flag(dest, pi,
5933 BGP_PATH_VALID);
5934 else {
5935 if (BGP_DEBUG(nht, NHT)) {
5936 char buf1[INET6_ADDRSTRLEN];
5937 inet_ntop(p->family,
5938 &p->u.prefix, buf1,
5939 INET6_ADDRSTRLEN);
5940 zlog_debug(
5941 "%s(%s): Route not in table, not advertising",
5942 __func__, buf1);
5943 }
5944 bgp_path_info_unset_flag(
5945 dest, pi, BGP_PATH_VALID);
5946 }
5947 } else {
5948 /* Delete the NHT structure if any, if we're
5949 * toggling between
5950 * enabling/disabling import check. We
5951 * deregister the route
5952 * from NHT to avoid overloading NHT and the
5953 * process interaction
5954 */
5955 bgp_unlink_nexthop(pi);
5956 bgp_path_info_set_flag(dest, pi,
5957 BGP_PATH_VALID);
5958 }
5959 /* Process change. */
5960 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5961 bgp_process(bgp, dest, afi, safi);
5962
5963 if (SAFI_UNICAST == safi
5964 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5965 || bgp->inst_type
5966 == BGP_INSTANCE_TYPE_DEFAULT)) {
5967 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5968 pi);
5969 }
5970
5971 bgp_dest_unlock_node(dest);
5972 aspath_unintern(&attr.aspath);
5973 return;
5974 }
5975 }
5976
5977 /* Make new BGP info. */
5978 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5979 attr_new, dest);
5980 /* Nexthop reachability check. */
5981 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5982 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5983 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
5984 p))
5985 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5986 else {
5987 if (BGP_DEBUG(nht, NHT)) {
5988 char buf1[INET6_ADDRSTRLEN];
5989 inet_ntop(p->family, &p->u.prefix, buf1,
5990 INET6_ADDRSTRLEN);
5991 zlog_debug(
5992 "%s(%s): Route not in table, not advertising",
5993 __func__, buf1);
5994 }
5995 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5996 }
5997 } else {
5998 /* Delete the NHT structure if any, if we're toggling between
5999 * enabling/disabling import check. We deregister the route
6000 * from NHT to avoid overloading NHT and the process interaction
6001 */
6002 bgp_unlink_nexthop(new);
6003
6004 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
6005 }
6006
6007 /* Aggregate address increment. */
6008 bgp_aggregate_increment(bgp, p, new, afi, safi);
6009
6010 /* Register new BGP information. */
6011 bgp_path_info_add(dest, new);
6012
6013 /* route_node_get lock */
6014 bgp_dest_unlock_node(dest);
6015
6016 /* Process change. */
6017 bgp_process(bgp, dest, afi, safi);
6018
6019 if (SAFI_UNICAST == safi
6020 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6021 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6022 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6023 }
6024
6025 /* Unintern original. */
6026 aspath_unintern(&attr.aspath);
6027 }
6028
6029 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6030 safi_t safi)
6031 {
6032 struct bgp_dest *dest;
6033 struct bgp_path_info *pi;
6034
6035 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6036
6037 /* Check selected route and self inserted route. */
6038 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6039 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6040 && pi->sub_type == BGP_ROUTE_STATIC)
6041 break;
6042
6043 /* Withdraw static BGP route from routing table. */
6044 if (pi) {
6045 if (SAFI_UNICAST == safi
6046 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6047 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6048 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6049 }
6050 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6051 bgp_unlink_nexthop(pi);
6052 bgp_path_info_delete(dest, pi);
6053 bgp_process(bgp, dest, afi, safi);
6054 }
6055
6056 /* Unlock bgp_node_lookup. */
6057 bgp_dest_unlock_node(dest);
6058 }
6059
6060 /*
6061 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6062 */
6063 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6064 afi_t afi, safi_t safi,
6065 struct prefix_rd *prd)
6066 {
6067 struct bgp_dest *dest;
6068 struct bgp_path_info *pi;
6069
6070 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6071
6072 /* Check selected route and self inserted route. */
6073 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6074 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6075 && pi->sub_type == BGP_ROUTE_STATIC)
6076 break;
6077
6078 /* Withdraw static BGP route from routing table. */
6079 if (pi) {
6080 #ifdef ENABLE_BGP_VNC
6081 rfapiProcessWithdraw(
6082 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6083 1); /* Kill, since it is an administrative change */
6084 #endif
6085 if (SAFI_MPLS_VPN == safi
6086 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6087 vpn_leak_to_vrf_withdraw(bgp, pi);
6088 }
6089 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6090 bgp_path_info_delete(dest, pi);
6091 bgp_process(bgp, dest, afi, safi);
6092 }
6093
6094 /* Unlock bgp_node_lookup. */
6095 bgp_dest_unlock_node(dest);
6096 }
6097
6098 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6099 struct bgp_static *bgp_static, afi_t afi,
6100 safi_t safi)
6101 {
6102 struct bgp_dest *dest;
6103 struct bgp_path_info *new;
6104 struct attr *attr_new;
6105 struct attr attr = {0};
6106 struct bgp_path_info *pi;
6107 #ifdef ENABLE_BGP_VNC
6108 mpls_label_t label = 0;
6109 #endif
6110 uint32_t num_labels = 0;
6111
6112 assert(bgp_static);
6113
6114 if (bgp_static->label != MPLS_INVALID_LABEL)
6115 num_labels = 1;
6116 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6117 &bgp_static->prd);
6118
6119 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
6120
6121 attr.nexthop = bgp_static->igpnexthop;
6122 attr.med = bgp_static->igpmetric;
6123 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6124
6125 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6126 || (safi == SAFI_ENCAP)) {
6127 if (afi == AFI_IP) {
6128 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6129 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6130 }
6131 }
6132 if (afi == AFI_L2VPN) {
6133 if (bgp_static->gatewayIp.family == AF_INET) {
6134 SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
6135 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
6136 &bgp_static->gatewayIp.u.prefix4,
6137 IPV4_MAX_BYTELEN);
6138 } else if (bgp_static->gatewayIp.family == AF_INET6) {
6139 SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
6140 memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
6141 &bgp_static->gatewayIp.u.prefix6,
6142 IPV6_MAX_BYTELEN);
6143 }
6144 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6145 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6146 struct bgp_encap_type_vxlan bet;
6147 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
6148 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6149 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6150 }
6151 if (bgp_static->router_mac) {
6152 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6153 }
6154 }
6155 /* Apply route-map. */
6156 if (bgp_static->rmap.name) {
6157 struct attr attr_tmp = attr;
6158 struct bgp_path_info rmap_path;
6159 route_map_result_t ret;
6160
6161 rmap_path.peer = bgp->peer_self;
6162 rmap_path.attr = &attr_tmp;
6163
6164 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6165
6166 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6167
6168 bgp->peer_self->rmap_type = 0;
6169
6170 if (ret == RMAP_DENYMATCH) {
6171 /* Free uninterned attribute. */
6172 bgp_attr_flush(&attr_tmp);
6173
6174 /* Unintern original. */
6175 aspath_unintern(&attr.aspath);
6176 bgp_static_withdraw_safi(bgp, p, afi, safi,
6177 &bgp_static->prd);
6178 return;
6179 }
6180
6181 attr_new = bgp_attr_intern(&attr_tmp);
6182 } else {
6183 attr_new = bgp_attr_intern(&attr);
6184 }
6185
6186 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6187 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6188 && pi->sub_type == BGP_ROUTE_STATIC)
6189 break;
6190
6191 if (pi) {
6192 if (attrhash_cmp(pi->attr, attr_new)
6193 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6194 bgp_dest_unlock_node(dest);
6195 bgp_attr_unintern(&attr_new);
6196 aspath_unintern(&attr.aspath);
6197 return;
6198 } else {
6199 /* The attribute is changed. */
6200 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6201
6202 /* Rewrite BGP route information. */
6203 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6204 bgp_path_info_restore(dest, pi);
6205 else
6206 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6207 bgp_attr_unintern(&pi->attr);
6208 pi->attr = attr_new;
6209 pi->uptime = bgp_clock();
6210 #ifdef ENABLE_BGP_VNC
6211 if (pi->extra)
6212 label = decode_label(&pi->extra->label[0]);
6213 #endif
6214
6215 /* Process change. */
6216 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6217 bgp_process(bgp, dest, afi, safi);
6218
6219 if (SAFI_MPLS_VPN == safi
6220 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6221 vpn_leak_to_vrf_update(bgp, pi);
6222 }
6223 #ifdef ENABLE_BGP_VNC
6224 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6225 pi->attr, afi, safi, pi->type,
6226 pi->sub_type, &label);
6227 #endif
6228 bgp_dest_unlock_node(dest);
6229 aspath_unintern(&attr.aspath);
6230 return;
6231 }
6232 }
6233
6234
6235 /* Make new BGP info. */
6236 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6237 attr_new, dest);
6238 SET_FLAG(new->flags, BGP_PATH_VALID);
6239 bgp_path_info_extra_get(new);
6240 if (num_labels) {
6241 new->extra->label[0] = bgp_static->label;
6242 new->extra->num_labels = num_labels;
6243 }
6244 #ifdef ENABLE_BGP_VNC
6245 label = decode_label(&bgp_static->label);
6246 #endif
6247
6248 /* Aggregate address increment. */
6249 bgp_aggregate_increment(bgp, p, new, afi, safi);
6250
6251 /* Register new BGP information. */
6252 bgp_path_info_add(dest, new);
6253 /* route_node_get lock */
6254 bgp_dest_unlock_node(dest);
6255
6256 /* Process change. */
6257 bgp_process(bgp, dest, afi, safi);
6258
6259 if (SAFI_MPLS_VPN == safi
6260 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6261 vpn_leak_to_vrf_update(bgp, new);
6262 }
6263 #ifdef ENABLE_BGP_VNC
6264 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6265 safi, new->type, new->sub_type, &label);
6266 #endif
6267
6268 /* Unintern original. */
6269 aspath_unintern(&attr.aspath);
6270 }
6271
6272 /* Configure static BGP network. When user don't run zebra, static
6273 route should be installed as valid. */
6274 static int bgp_static_set(struct vty *vty, const char *negate,
6275 const char *ip_str, afi_t afi, safi_t safi,
6276 const char *rmap, int backdoor, uint32_t label_index)
6277 {
6278 VTY_DECLVAR_CONTEXT(bgp, bgp);
6279 int ret;
6280 struct prefix p;
6281 struct bgp_static *bgp_static;
6282 struct bgp_dest *dest;
6283 uint8_t need_update = 0;
6284
6285 /* Convert IP prefix string to struct prefix. */
6286 ret = str2prefix(ip_str, &p);
6287 if (!ret) {
6288 vty_out(vty, "%% Malformed prefix\n");
6289 return CMD_WARNING_CONFIG_FAILED;
6290 }
6291 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6292 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6293 return CMD_WARNING_CONFIG_FAILED;
6294 }
6295
6296 apply_mask(&p);
6297
6298 if (negate) {
6299
6300 /* Set BGP static route configuration. */
6301 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6302
6303 if (!dest) {
6304 vty_out(vty, "%% Can't find static route specified\n");
6305 return CMD_WARNING_CONFIG_FAILED;
6306 }
6307
6308 bgp_static = bgp_dest_get_bgp_static_info(dest);
6309
6310 if ((label_index != BGP_INVALID_LABEL_INDEX)
6311 && (label_index != bgp_static->label_index)) {
6312 vty_out(vty,
6313 "%% label-index doesn't match static route\n");
6314 bgp_dest_unlock_node(dest);
6315 return CMD_WARNING_CONFIG_FAILED;
6316 }
6317
6318 if ((rmap && bgp_static->rmap.name)
6319 && strcmp(rmap, bgp_static->rmap.name)) {
6320 vty_out(vty,
6321 "%% route-map name doesn't match static route\n");
6322 bgp_dest_unlock_node(dest);
6323 return CMD_WARNING_CONFIG_FAILED;
6324 }
6325
6326 /* Update BGP RIB. */
6327 if (!bgp_static->backdoor)
6328 bgp_static_withdraw(bgp, &p, afi, safi);
6329
6330 /* Clear configuration. */
6331 bgp_static_free(bgp_static);
6332 bgp_dest_set_bgp_static_info(dest, NULL);
6333 bgp_dest_unlock_node(dest);
6334 bgp_dest_unlock_node(dest);
6335 } else {
6336
6337 /* Set BGP static route configuration. */
6338 dest = bgp_node_get(bgp->route[afi][safi], &p);
6339 bgp_static = bgp_dest_get_bgp_static_info(dest);
6340 if (bgp_static) {
6341 /* Configuration change. */
6342 /* Label index cannot be changed. */
6343 if (bgp_static->label_index != label_index) {
6344 vty_out(vty, "%% cannot change label-index\n");
6345 return CMD_WARNING_CONFIG_FAILED;
6346 }
6347
6348 /* Check previous routes are installed into BGP. */
6349 if (bgp_static->valid
6350 && bgp_static->backdoor != backdoor)
6351 need_update = 1;
6352
6353 bgp_static->backdoor = backdoor;
6354
6355 if (rmap) {
6356 XFREE(MTYPE_ROUTE_MAP_NAME,
6357 bgp_static->rmap.name);
6358 route_map_counter_decrement(
6359 bgp_static->rmap.map);
6360 bgp_static->rmap.name =
6361 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6362 bgp_static->rmap.map =
6363 route_map_lookup_by_name(rmap);
6364 route_map_counter_increment(
6365 bgp_static->rmap.map);
6366 } else {
6367 XFREE(MTYPE_ROUTE_MAP_NAME,
6368 bgp_static->rmap.name);
6369 route_map_counter_decrement(
6370 bgp_static->rmap.map);
6371 bgp_static->rmap.map = NULL;
6372 bgp_static->valid = 0;
6373 }
6374 bgp_dest_unlock_node(dest);
6375 } else {
6376 /* New configuration. */
6377 bgp_static = bgp_static_new();
6378 bgp_static->backdoor = backdoor;
6379 bgp_static->valid = 0;
6380 bgp_static->igpmetric = 0;
6381 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6382 bgp_static->label_index = label_index;
6383
6384 if (rmap) {
6385 XFREE(MTYPE_ROUTE_MAP_NAME,
6386 bgp_static->rmap.name);
6387 route_map_counter_decrement(
6388 bgp_static->rmap.map);
6389 bgp_static->rmap.name =
6390 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6391 bgp_static->rmap.map =
6392 route_map_lookup_by_name(rmap);
6393 route_map_counter_increment(
6394 bgp_static->rmap.map);
6395 }
6396 bgp_dest_set_bgp_static_info(dest, bgp_static);
6397 }
6398
6399 bgp_static->valid = 1;
6400 if (need_update)
6401 bgp_static_withdraw(bgp, &p, afi, safi);
6402
6403 if (!bgp_static->backdoor)
6404 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6405 }
6406
6407 return CMD_SUCCESS;
6408 }
6409
6410 void bgp_static_add(struct bgp *bgp)
6411 {
6412 afi_t afi;
6413 safi_t safi;
6414 struct bgp_dest *dest;
6415 struct bgp_dest *rm;
6416 struct bgp_table *table;
6417 struct bgp_static *bgp_static;
6418
6419 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6420 FOREACH_AFI_SAFI (afi, safi)
6421 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6422 dest = bgp_route_next(dest)) {
6423 if (!bgp_dest_has_bgp_path_info_data(dest))
6424 continue;
6425
6426 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6427 || (safi == SAFI_EVPN)) {
6428 table = bgp_dest_get_bgp_table_info(dest);
6429
6430 for (rm = bgp_table_top(table); rm;
6431 rm = bgp_route_next(rm)) {
6432 bgp_static =
6433 bgp_dest_get_bgp_static_info(
6434 rm);
6435 bgp_static_update_safi(
6436 bgp, bgp_dest_get_prefix(rm),
6437 bgp_static, afi, safi);
6438 }
6439 } else {
6440 bgp_static_update(
6441 bgp, bgp_dest_get_prefix(dest),
6442 bgp_dest_get_bgp_static_info(dest), afi,
6443 safi);
6444 }
6445 }
6446 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6447 }
6448
6449 /* Called from bgp_delete(). Delete all static routes from the BGP
6450 instance. */
6451 void bgp_static_delete(struct bgp *bgp)
6452 {
6453 afi_t afi;
6454 safi_t safi;
6455 struct bgp_dest *dest;
6456 struct bgp_dest *rm;
6457 struct bgp_table *table;
6458 struct bgp_static *bgp_static;
6459
6460 FOREACH_AFI_SAFI (afi, safi)
6461 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6462 dest = bgp_route_next(dest)) {
6463 if (!bgp_dest_has_bgp_path_info_data(dest))
6464 continue;
6465
6466 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6467 || (safi == SAFI_EVPN)) {
6468 table = bgp_dest_get_bgp_table_info(dest);
6469
6470 for (rm = bgp_table_top(table); rm;
6471 rm = bgp_route_next(rm)) {
6472 bgp_static =
6473 bgp_dest_get_bgp_static_info(
6474 rm);
6475 if (!bgp_static)
6476 continue;
6477
6478 bgp_static_withdraw_safi(
6479 bgp, bgp_dest_get_prefix(rm),
6480 AFI_IP, safi,
6481 (struct prefix_rd *)
6482 bgp_dest_get_prefix(
6483 dest));
6484 bgp_static_free(bgp_static);
6485 bgp_dest_set_bgp_static_info(rm,
6486 NULL);
6487 bgp_dest_unlock_node(rm);
6488 }
6489 } else {
6490 bgp_static = bgp_dest_get_bgp_static_info(dest);
6491 bgp_static_withdraw(bgp,
6492 bgp_dest_get_prefix(dest),
6493 afi, safi);
6494 bgp_static_free(bgp_static);
6495 bgp_dest_set_bgp_static_info(dest, NULL);
6496 bgp_dest_unlock_node(dest);
6497 }
6498 }
6499 }
6500
6501 void bgp_static_redo_import_check(struct bgp *bgp)
6502 {
6503 afi_t afi;
6504 safi_t safi;
6505 struct bgp_dest *dest;
6506 struct bgp_dest *rm;
6507 struct bgp_table *table;
6508 struct bgp_static *bgp_static;
6509
6510 /* Use this flag to force reprocessing of the route */
6511 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6512 FOREACH_AFI_SAFI (afi, safi) {
6513 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6514 dest = bgp_route_next(dest)) {
6515 if (!bgp_dest_has_bgp_path_info_data(dest))
6516 continue;
6517
6518 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6519 || (safi == SAFI_EVPN)) {
6520 table = bgp_dest_get_bgp_table_info(dest);
6521
6522 for (rm = bgp_table_top(table); rm;
6523 rm = bgp_route_next(rm)) {
6524 bgp_static =
6525 bgp_dest_get_bgp_static_info(
6526 rm);
6527 bgp_static_update_safi(
6528 bgp, bgp_dest_get_prefix(rm),
6529 bgp_static, afi, safi);
6530 }
6531 } else {
6532 bgp_static = bgp_dest_get_bgp_static_info(dest);
6533 bgp_static_update(bgp,
6534 bgp_dest_get_prefix(dest),
6535 bgp_static, afi, safi);
6536 }
6537 }
6538 }
6539 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6540 }
6541
6542 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6543 safi_t safi)
6544 {
6545 struct bgp_table *table;
6546 struct bgp_dest *dest;
6547 struct bgp_path_info *pi;
6548
6549 /* Do not install the aggregate route if BGP is in the
6550 * process of termination.
6551 */
6552 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6553 || (bgp->peer_self == NULL))
6554 return;
6555
6556 table = bgp->rib[afi][safi];
6557 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6558 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6559 if (pi->peer == bgp->peer_self
6560 && ((pi->type == ZEBRA_ROUTE_BGP
6561 && pi->sub_type == BGP_ROUTE_STATIC)
6562 || (pi->type != ZEBRA_ROUTE_BGP
6563 && pi->sub_type
6564 == BGP_ROUTE_REDISTRIBUTE))) {
6565 bgp_aggregate_decrement(
6566 bgp, bgp_dest_get_prefix(dest), pi, afi,
6567 safi);
6568 bgp_unlink_nexthop(pi);
6569 bgp_path_info_delete(dest, pi);
6570 bgp_process(bgp, dest, afi, safi);
6571 }
6572 }
6573 }
6574 }
6575
6576 /*
6577 * Purge all networks and redistributed routes from routing table.
6578 * Invoked upon the instance going down.
6579 */
6580 void bgp_purge_static_redist_routes(struct bgp *bgp)
6581 {
6582 afi_t afi;
6583 safi_t safi;
6584
6585 FOREACH_AFI_SAFI (afi, safi)
6586 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6587 }
6588
6589 /*
6590 * gpz 110624
6591 * Currently this is used to set static routes for VPN and ENCAP.
6592 * I think it can probably be factored with bgp_static_set.
6593 */
6594 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6595 const char *ip_str, const char *rd_str,
6596 const char *label_str, const char *rmap_str,
6597 int evpn_type, const char *esi, const char *gwip,
6598 const char *ethtag, const char *routermac)
6599 {
6600 VTY_DECLVAR_CONTEXT(bgp, bgp);
6601 int ret;
6602 struct prefix p;
6603 struct prefix_rd prd;
6604 struct bgp_dest *pdest;
6605 struct bgp_dest *dest;
6606 struct bgp_table *table;
6607 struct bgp_static *bgp_static;
6608 mpls_label_t label = MPLS_INVALID_LABEL;
6609 struct prefix gw_ip;
6610
6611 /* validate ip prefix */
6612 ret = str2prefix(ip_str, &p);
6613 if (!ret) {
6614 vty_out(vty, "%% Malformed prefix\n");
6615 return CMD_WARNING_CONFIG_FAILED;
6616 }
6617 apply_mask(&p);
6618 if ((afi == AFI_L2VPN)
6619 && (bgp_build_evpn_prefix(evpn_type,
6620 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6621 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6622 return CMD_WARNING_CONFIG_FAILED;
6623 }
6624
6625 ret = str2prefix_rd(rd_str, &prd);
6626 if (!ret) {
6627 vty_out(vty, "%% Malformed rd\n");
6628 return CMD_WARNING_CONFIG_FAILED;
6629 }
6630
6631 if (label_str) {
6632 unsigned long label_val;
6633 label_val = strtoul(label_str, NULL, 10);
6634 encode_label(label_val, &label);
6635 }
6636
6637 if (safi == SAFI_EVPN) {
6638 if (esi && str2esi(esi, NULL) == 0) {
6639 vty_out(vty, "%% Malformed ESI\n");
6640 return CMD_WARNING_CONFIG_FAILED;
6641 }
6642 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6643 vty_out(vty, "%% Malformed Router MAC\n");
6644 return CMD_WARNING_CONFIG_FAILED;
6645 }
6646 if (gwip) {
6647 memset(&gw_ip, 0, sizeof(struct prefix));
6648 ret = str2prefix(gwip, &gw_ip);
6649 if (!ret) {
6650 vty_out(vty, "%% Malformed GatewayIp\n");
6651 return CMD_WARNING_CONFIG_FAILED;
6652 }
6653 if ((gw_ip.family == AF_INET
6654 && is_evpn_prefix_ipaddr_v6(
6655 (struct prefix_evpn *)&p))
6656 || (gw_ip.family == AF_INET6
6657 && is_evpn_prefix_ipaddr_v4(
6658 (struct prefix_evpn *)&p))) {
6659 vty_out(vty,
6660 "%% GatewayIp family differs with IP prefix\n");
6661 return CMD_WARNING_CONFIG_FAILED;
6662 }
6663 }
6664 }
6665 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6666 if (!bgp_dest_has_bgp_path_info_data(pdest))
6667 bgp_dest_set_bgp_table_info(pdest,
6668 bgp_table_init(bgp, afi, safi));
6669 table = bgp_dest_get_bgp_table_info(pdest);
6670
6671 dest = bgp_node_get(table, &p);
6672
6673 if (bgp_dest_has_bgp_path_info_data(dest)) {
6674 vty_out(vty, "%% Same network configuration exists\n");
6675 bgp_dest_unlock_node(dest);
6676 } else {
6677 /* New configuration. */
6678 bgp_static = bgp_static_new();
6679 bgp_static->backdoor = 0;
6680 bgp_static->valid = 0;
6681 bgp_static->igpmetric = 0;
6682 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6683 bgp_static->label = label;
6684 bgp_static->prd = prd;
6685
6686 if (rmap_str) {
6687 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6688 route_map_counter_decrement(bgp_static->rmap.map);
6689 bgp_static->rmap.name =
6690 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6691 bgp_static->rmap.map =
6692 route_map_lookup_by_name(rmap_str);
6693 route_map_counter_increment(bgp_static->rmap.map);
6694 }
6695
6696 if (safi == SAFI_EVPN) {
6697 if (esi) {
6698 bgp_static->eth_s_id =
6699 XCALLOC(MTYPE_ATTR,
6700 sizeof(esi_t));
6701 str2esi(esi, bgp_static->eth_s_id);
6702 }
6703 if (routermac) {
6704 bgp_static->router_mac =
6705 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6706 (void)prefix_str2mac(routermac,
6707 bgp_static->router_mac);
6708 }
6709 if (gwip)
6710 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6711 }
6712 bgp_dest_set_bgp_static_info(dest, bgp_static);
6713
6714 bgp_static->valid = 1;
6715 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6716 }
6717
6718 return CMD_SUCCESS;
6719 }
6720
6721 /* Configure static BGP network. */
6722 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6723 const char *ip_str, const char *rd_str,
6724 const char *label_str, int evpn_type, const char *esi,
6725 const char *gwip, const char *ethtag)
6726 {
6727 VTY_DECLVAR_CONTEXT(bgp, bgp);
6728 int ret;
6729 struct prefix p;
6730 struct prefix_rd prd;
6731 struct bgp_dest *pdest;
6732 struct bgp_dest *dest;
6733 struct bgp_table *table;
6734 struct bgp_static *bgp_static;
6735 mpls_label_t label = MPLS_INVALID_LABEL;
6736
6737 /* Convert IP prefix string to struct prefix. */
6738 ret = str2prefix(ip_str, &p);
6739 if (!ret) {
6740 vty_out(vty, "%% Malformed prefix\n");
6741 return CMD_WARNING_CONFIG_FAILED;
6742 }
6743 apply_mask(&p);
6744 if ((afi == AFI_L2VPN)
6745 && (bgp_build_evpn_prefix(evpn_type,
6746 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6747 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6748 return CMD_WARNING_CONFIG_FAILED;
6749 }
6750 ret = str2prefix_rd(rd_str, &prd);
6751 if (!ret) {
6752 vty_out(vty, "%% Malformed rd\n");
6753 return CMD_WARNING_CONFIG_FAILED;
6754 }
6755
6756 if (label_str) {
6757 unsigned long label_val;
6758 label_val = strtoul(label_str, NULL, 10);
6759 encode_label(label_val, &label);
6760 }
6761
6762 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6763 if (!bgp_dest_has_bgp_path_info_data(pdest))
6764 bgp_dest_set_bgp_table_info(pdest,
6765 bgp_table_init(bgp, afi, safi));
6766 else
6767 bgp_dest_unlock_node(pdest);
6768 table = bgp_dest_get_bgp_table_info(pdest);
6769
6770 dest = bgp_node_lookup(table, &p);
6771
6772 if (dest) {
6773 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6774
6775 bgp_static = bgp_dest_get_bgp_static_info(dest);
6776 bgp_static_free(bgp_static);
6777 bgp_dest_set_bgp_static_info(dest, NULL);
6778 bgp_dest_unlock_node(dest);
6779 bgp_dest_unlock_node(dest);
6780 } else
6781 vty_out(vty, "%% Can't find the route\n");
6782
6783 return CMD_SUCCESS;
6784 }
6785
6786 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6787 const char *rmap_name)
6788 {
6789 VTY_DECLVAR_CONTEXT(bgp, bgp);
6790 struct bgp_rmap *rmap;
6791
6792 rmap = &bgp->table_map[afi][safi];
6793 if (rmap_name) {
6794 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6795 route_map_counter_decrement(rmap->map);
6796 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6797 rmap->map = route_map_lookup_by_name(rmap_name);
6798 route_map_counter_increment(rmap->map);
6799 } else {
6800 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6801 route_map_counter_decrement(rmap->map);
6802 rmap->map = NULL;
6803 }
6804
6805 if (bgp_fibupd_safi(safi))
6806 bgp_zebra_announce_table(bgp, afi, safi);
6807
6808 return CMD_SUCCESS;
6809 }
6810
6811 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6812 const char *rmap_name)
6813 {
6814 VTY_DECLVAR_CONTEXT(bgp, bgp);
6815 struct bgp_rmap *rmap;
6816
6817 rmap = &bgp->table_map[afi][safi];
6818 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6819 route_map_counter_decrement(rmap->map);
6820 rmap->map = NULL;
6821
6822 if (bgp_fibupd_safi(safi))
6823 bgp_zebra_announce_table(bgp, afi, safi);
6824
6825 return CMD_SUCCESS;
6826 }
6827
6828 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6829 safi_t safi)
6830 {
6831 if (bgp->table_map[afi][safi].name) {
6832 vty_out(vty, " table-map %s\n",
6833 bgp->table_map[afi][safi].name);
6834 }
6835 }
6836
6837 DEFUN (bgp_table_map,
6838 bgp_table_map_cmd,
6839 "table-map WORD",
6840 "BGP table to RIB route download filter\n"
6841 "Name of the route map\n")
6842 {
6843 int idx_word = 1;
6844 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6845 argv[idx_word]->arg);
6846 }
6847 DEFUN (no_bgp_table_map,
6848 no_bgp_table_map_cmd,
6849 "no table-map WORD",
6850 NO_STR
6851 "BGP table to RIB route download filter\n"
6852 "Name of the route map\n")
6853 {
6854 int idx_word = 2;
6855 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6856 argv[idx_word]->arg);
6857 }
6858
6859 DEFPY(bgp_network,
6860 bgp_network_cmd,
6861 "[no] network \
6862 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6863 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6864 backdoor$backdoor}]",
6865 NO_STR
6866 "Specify a network to announce via BGP\n"
6867 "IPv4 prefix\n"
6868 "Network number\n"
6869 "Network mask\n"
6870 "Network mask\n"
6871 "Route-map to modify the attributes\n"
6872 "Name of the route map\n"
6873 "Label index to associate with the prefix\n"
6874 "Label index value\n"
6875 "Specify a BGP backdoor route\n")
6876 {
6877 char addr_prefix_str[BUFSIZ];
6878
6879 if (address_str) {
6880 int ret;
6881
6882 ret = netmask_str2prefix_str(address_str, netmask_str,
6883 addr_prefix_str,
6884 sizeof(addr_prefix_str));
6885 if (!ret) {
6886 vty_out(vty, "%% Inconsistent address and mask\n");
6887 return CMD_WARNING_CONFIG_FAILED;
6888 }
6889 }
6890
6891 return bgp_static_set(
6892 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
6893 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
6894 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6895 }
6896
6897 DEFPY(ipv6_bgp_network,
6898 ipv6_bgp_network_cmd,
6899 "[no] network X:X::X:X/M$prefix \
6900 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6901 NO_STR
6902 "Specify a network to announce via BGP\n"
6903 "IPv6 prefix\n"
6904 "Route-map to modify the attributes\n"
6905 "Name of the route map\n"
6906 "Label index to associate with the prefix\n"
6907 "Label index value\n")
6908 {
6909 return bgp_static_set(
6910 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
6911 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6912 }
6913
6914 static struct bgp_aggregate *bgp_aggregate_new(void)
6915 {
6916 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6917 }
6918
6919 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6920 {
6921 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
6922 route_map_counter_decrement(aggregate->suppress_map);
6923 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6924 route_map_counter_decrement(aggregate->rmap.map);
6925 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6926 }
6927
6928 /**
6929 * Helper function to avoid repeated code: prepare variables for a
6930 * `route_map_apply` call.
6931 *
6932 * \returns `true` on route map match, otherwise `false`.
6933 */
6934 static bool aggr_suppress_map_test(struct bgp *bgp,
6935 struct bgp_aggregate *aggregate,
6936 struct bgp_path_info *pi)
6937 {
6938 const struct prefix *p = bgp_dest_get_prefix(pi->net);
6939 route_map_result_t rmr = RMAP_DENYMATCH;
6940 struct bgp_path_info rmap_path = {};
6941 struct attr attr = {};
6942
6943 /* No route map entries created, just don't match. */
6944 if (aggregate->suppress_map == NULL)
6945 return false;
6946
6947 /* Call route map matching and return result. */
6948 attr.aspath = aspath_empty();
6949 rmap_path.peer = bgp->peer_self;
6950 rmap_path.attr = &attr;
6951
6952 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
6953 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
6954 bgp->peer_self->rmap_type = 0;
6955
6956 bgp_attr_flush(&attr);
6957 aspath_unintern(&attr.aspath);
6958
6959 return rmr == RMAP_PERMITMATCH;
6960 }
6961
6962 /** Test whether the aggregation has suppressed this path or not. */
6963 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
6964 struct bgp_path_info *pi)
6965 {
6966 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
6967 return false;
6968
6969 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
6970 }
6971
6972 /**
6973 * Suppress this path and keep the reference.
6974 *
6975 * \returns `true` if needs processing otherwise `false`.
6976 */
6977 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
6978 struct bgp_path_info *pi)
6979 {
6980 struct bgp_path_info_extra *pie;
6981
6982 /* Path is already suppressed by this aggregation. */
6983 if (aggr_suppress_exists(aggregate, pi))
6984 return false;
6985
6986 pie = bgp_path_info_extra_get(pi);
6987
6988 /* This is the first suppression, allocate memory and list it. */
6989 if (pie->aggr_suppressors == NULL)
6990 pie->aggr_suppressors = list_new();
6991
6992 listnode_add(pie->aggr_suppressors, aggregate);
6993
6994 /* Only mark for processing if suppressed. */
6995 if (listcount(pie->aggr_suppressors) == 1) {
6996 if (BGP_DEBUG(update, UPDATE_OUT))
6997 zlog_debug("aggregate-address suppressing: %pFX",
6998 bgp_dest_get_prefix(pi->net));
6999
7000 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7001 return true;
7002 }
7003
7004 return false;
7005 }
7006
7007 /**
7008 * Unsuppress this path and remove the reference.
7009 *
7010 * \returns `true` if needs processing otherwise `false`.
7011 */
7012 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
7013 struct bgp_path_info *pi)
7014 {
7015 /* Path wasn't suppressed. */
7016 if (!aggr_suppress_exists(aggregate, pi))
7017 return false;
7018
7019 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7020
7021 /* Unsuppress and free extra memory if last item. */
7022 if (listcount(pi->extra->aggr_suppressors) == 0) {
7023 if (BGP_DEBUG(update, UPDATE_OUT))
7024 zlog_debug("aggregate-address unsuppressing: %pFX",
7025 bgp_dest_get_prefix(pi->net));
7026
7027 list_delete(&pi->extra->aggr_suppressors);
7028 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7029 return true;
7030 }
7031
7032 return false;
7033 }
7034
7035 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7036 struct aspath *aspath,
7037 struct community *comm,
7038 struct ecommunity *ecomm,
7039 struct lcommunity *lcomm)
7040 {
7041 static struct aspath *ae = NULL;
7042
7043 if (!ae)
7044 ae = aspath_empty();
7045
7046 if (!pi)
7047 return false;
7048
7049 if (origin != pi->attr->origin)
7050 return false;
7051
7052 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7053 return false;
7054
7055 if (!community_cmp(bgp_attr_get_community(pi->attr), comm))
7056 return false;
7057
7058 if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
7059 return false;
7060
7061 if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
7062 return false;
7063
7064 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7065 return false;
7066
7067 return true;
7068 }
7069
7070 static void bgp_aggregate_install(
7071 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7072 uint8_t origin, struct aspath *aspath, struct community *community,
7073 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7074 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7075 {
7076 struct bgp_dest *dest;
7077 struct bgp_table *table;
7078 struct bgp_path_info *pi, *orig, *new;
7079 struct attr *attr;
7080
7081 table = bgp->rib[afi][safi];
7082
7083 dest = bgp_node_get(table, p);
7084
7085 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7086 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7087 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7088 break;
7089
7090 /*
7091 * If we have paths with different MEDs, then don't install
7092 * (or uninstall) the aggregate route.
7093 */
7094 if (aggregate->match_med && aggregate->med_mismatched)
7095 goto uninstall_aggregate_route;
7096
7097 if (aggregate->count > 0) {
7098 /*
7099 * If the aggregate information has not changed
7100 * no need to re-install it again.
7101 */
7102 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7103 ecommunity, lcommunity)) {
7104 bgp_dest_unlock_node(dest);
7105
7106 if (aspath)
7107 aspath_free(aspath);
7108 if (community)
7109 community_free(&community);
7110 if (ecommunity)
7111 ecommunity_free(&ecommunity);
7112 if (lcommunity)
7113 lcommunity_free(&lcommunity);
7114
7115 return;
7116 }
7117
7118 /*
7119 * Mark the old as unusable
7120 */
7121 if (pi)
7122 bgp_path_info_delete(dest, pi);
7123
7124 attr = bgp_attr_aggregate_intern(
7125 bgp, origin, aspath, community, ecommunity, lcommunity,
7126 aggregate, atomic_aggregate, p);
7127
7128 if (!attr) {
7129 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7130 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7131 zlog_debug("%s: %pFX null attribute", __func__,
7132 p);
7133 return;
7134 }
7135
7136 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7137 bgp->peer_self, attr, dest);
7138
7139 SET_FLAG(new->flags, BGP_PATH_VALID);
7140
7141 bgp_path_info_add(dest, new);
7142 bgp_process(bgp, dest, afi, safi);
7143 } else {
7144 uninstall_aggregate_route:
7145 for (pi = orig; pi; pi = pi->next)
7146 if (pi->peer == bgp->peer_self
7147 && pi->type == ZEBRA_ROUTE_BGP
7148 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7149 break;
7150
7151 /* Withdraw static BGP route from routing table. */
7152 if (pi) {
7153 bgp_path_info_delete(dest, pi);
7154 bgp_process(bgp, dest, afi, safi);
7155 }
7156 }
7157
7158 bgp_dest_unlock_node(dest);
7159 }
7160
7161 /**
7162 * Check if the current path has different MED than other known paths.
7163 *
7164 * \returns `true` if the MED matched the others else `false`.
7165 */
7166 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7167 struct bgp *bgp, struct bgp_path_info *pi)
7168 {
7169 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7170
7171 /* This is the first route being analyzed. */
7172 if (!aggregate->med_initialized) {
7173 aggregate->med_initialized = true;
7174 aggregate->med_mismatched = false;
7175 aggregate->med_matched_value = cur_med;
7176 } else {
7177 /* Check if routes with different MED showed up. */
7178 if (cur_med != aggregate->med_matched_value)
7179 aggregate->med_mismatched = true;
7180 }
7181
7182 return !aggregate->med_mismatched;
7183 }
7184
7185 /**
7186 * Initializes and tests all routes in the aggregate address path for MED
7187 * values.
7188 *
7189 * \returns `true` if all MEDs are the same otherwise `false`.
7190 */
7191 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7192 struct bgp *bgp, const struct prefix *p,
7193 afi_t afi, safi_t safi)
7194 {
7195 struct bgp_table *table = bgp->rib[afi][safi];
7196 const struct prefix *dest_p;
7197 struct bgp_dest *dest, *top;
7198 struct bgp_path_info *pi;
7199 bool med_matched = true;
7200
7201 aggregate->med_initialized = false;
7202
7203 top = bgp_node_get(table, p);
7204 for (dest = bgp_node_get(table, p); dest;
7205 dest = bgp_route_next_until(dest, top)) {
7206 dest_p = bgp_dest_get_prefix(dest);
7207 if (dest_p->prefixlen <= p->prefixlen)
7208 continue;
7209
7210 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7211 if (BGP_PATH_HOLDDOWN(pi))
7212 continue;
7213 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7214 continue;
7215 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7216 med_matched = false;
7217 break;
7218 }
7219 }
7220 if (!med_matched)
7221 break;
7222 }
7223 bgp_dest_unlock_node(top);
7224
7225 return med_matched;
7226 }
7227
7228 /**
7229 * Toggles the route suppression status for this aggregate address
7230 * configuration.
7231 */
7232 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7233 struct bgp *bgp, const struct prefix *p,
7234 afi_t afi, safi_t safi, bool suppress)
7235 {
7236 struct bgp_table *table = bgp->rib[afi][safi];
7237 const struct prefix *dest_p;
7238 struct bgp_dest *dest, *top;
7239 struct bgp_path_info *pi;
7240 bool toggle_suppression;
7241
7242 /* We've found a different MED we must revert any suppressed routes. */
7243 top = bgp_node_get(table, p);
7244 for (dest = bgp_node_get(table, p); dest;
7245 dest = bgp_route_next_until(dest, top)) {
7246 dest_p = bgp_dest_get_prefix(dest);
7247 if (dest_p->prefixlen <= p->prefixlen)
7248 continue;
7249
7250 toggle_suppression = false;
7251 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7252 if (BGP_PATH_HOLDDOWN(pi))
7253 continue;
7254 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7255 continue;
7256
7257 /* We are toggling suppression back. */
7258 if (suppress) {
7259 /* Suppress route if not suppressed already. */
7260 if (aggr_suppress_path(aggregate, pi))
7261 toggle_suppression = true;
7262 continue;
7263 }
7264
7265 /* Install route if there is no more suppression. */
7266 if (aggr_unsuppress_path(aggregate, pi))
7267 toggle_suppression = true;
7268 }
7269
7270 if (toggle_suppression)
7271 bgp_process(bgp, dest, afi, safi);
7272 }
7273 bgp_dest_unlock_node(top);
7274 }
7275
7276 /**
7277 * Aggregate address MED matching incremental test: this function is called
7278 * when the initial aggregation occurred and we are only testing a single
7279 * new path.
7280 *
7281 * In addition to testing and setting the MED validity it also installs back
7282 * suppressed routes (if summary is configured).
7283 *
7284 * Must not be called in `bgp_aggregate_route`.
7285 */
7286 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7287 struct bgp *bgp, const struct prefix *p,
7288 afi_t afi, safi_t safi,
7289 struct bgp_path_info *pi, bool is_adding)
7290 {
7291 /* MED matching disabled. */
7292 if (!aggregate->match_med)
7293 return;
7294
7295 /* Aggregation with different MED, nothing to do. */
7296 if (aggregate->med_mismatched)
7297 return;
7298
7299 /*
7300 * Test the current entry:
7301 *
7302 * is_adding == true: if the new entry doesn't match then we must
7303 * install all suppressed routes.
7304 *
7305 * is_adding == false: if the entry being removed was the last
7306 * unmatching entry then we can suppress all routes.
7307 */
7308 if (!is_adding) {
7309 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
7310 && aggregate->summary_only)
7311 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
7312 safi, true);
7313 } else
7314 bgp_aggregate_med_match(aggregate, bgp, pi);
7315
7316 /* No mismatches, just quit. */
7317 if (!aggregate->med_mismatched)
7318 return;
7319
7320 /* Route summarization is disabled. */
7321 if (!aggregate->summary_only)
7322 return;
7323
7324 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7325 }
7326
7327 /* Update an aggregate as routes are added/removed from the BGP table */
7328 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7329 safi_t safi, struct bgp_aggregate *aggregate)
7330 {
7331 struct bgp_table *table;
7332 struct bgp_dest *top;
7333 struct bgp_dest *dest;
7334 uint8_t origin;
7335 struct aspath *aspath = NULL;
7336 struct community *community = NULL;
7337 struct ecommunity *ecommunity = NULL;
7338 struct lcommunity *lcommunity = NULL;
7339 struct bgp_path_info *pi;
7340 unsigned long match = 0;
7341 uint8_t atomic_aggregate = 0;
7342
7343 /* If the bgp instance is being deleted or self peer is deleted
7344 * then do not create aggregate route
7345 */
7346 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7347 || (bgp->peer_self == NULL))
7348 return;
7349
7350 /* Initialize and test routes for MED difference. */
7351 if (aggregate->match_med)
7352 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7353
7354 /*
7355 * Reset aggregate count: we might've been called from route map
7356 * update so in that case we must retest all more specific routes.
7357 *
7358 * \see `bgp_route_map_process_update`.
7359 */
7360 aggregate->count = 0;
7361 aggregate->incomplete_origin_count = 0;
7362 aggregate->incomplete_origin_count = 0;
7363 aggregate->egp_origin_count = 0;
7364
7365 /* ORIGIN attribute: If at least one route among routes that are
7366 aggregated has ORIGIN with the value INCOMPLETE, then the
7367 aggregated route must have the ORIGIN attribute with the value
7368 INCOMPLETE. Otherwise, if at least one route among routes that
7369 are aggregated has ORIGIN with the value EGP, then the aggregated
7370 route must have the origin attribute with the value EGP. In all
7371 other case the value of the ORIGIN attribute of the aggregated
7372 route is INTERNAL. */
7373 origin = BGP_ORIGIN_IGP;
7374
7375 table = bgp->rib[afi][safi];
7376
7377 top = bgp_node_get(table, p);
7378 for (dest = bgp_node_get(table, p); dest;
7379 dest = bgp_route_next_until(dest, top)) {
7380 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7381
7382 if (dest_p->prefixlen <= p->prefixlen)
7383 continue;
7384
7385 /* If suppress fib is enabled and route not installed
7386 * in FIB, skip the route
7387 */
7388 if (!bgp_check_advertise(bgp, dest))
7389 continue;
7390
7391 match = 0;
7392
7393 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7394 if (BGP_PATH_HOLDDOWN(pi))
7395 continue;
7396
7397 if (pi->attr->flag
7398 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7399 atomic_aggregate = 1;
7400
7401 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7402 continue;
7403
7404 /*
7405 * summary-only aggregate route suppress
7406 * aggregated route announcements.
7407 *
7408 * MED matching:
7409 * Don't create summaries if MED didn't match
7410 * otherwise neither the specific routes and the
7411 * aggregation will be announced.
7412 */
7413 if (aggregate->summary_only
7414 && AGGREGATE_MED_VALID(aggregate)) {
7415 if (aggr_suppress_path(aggregate, pi))
7416 match++;
7417 }
7418
7419 /*
7420 * Suppress more specific routes that match the route
7421 * map results.
7422 *
7423 * MED matching:
7424 * Don't suppress routes if MED matching is enabled and
7425 * it mismatched otherwise we might end up with no
7426 * routes for this path.
7427 */
7428 if (aggregate->suppress_map_name
7429 && AGGREGATE_MED_VALID(aggregate)
7430 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7431 if (aggr_suppress_path(aggregate, pi))
7432 match++;
7433 }
7434
7435 aggregate->count++;
7436
7437 /*
7438 * If at least one route among routes that are
7439 * aggregated has ORIGIN with the value INCOMPLETE,
7440 * then the aggregated route MUST have the ORIGIN
7441 * attribute with the value INCOMPLETE. Otherwise, if
7442 * at least one route among routes that are aggregated
7443 * has ORIGIN with the value EGP, then the aggregated
7444 * route MUST have the ORIGIN attribute with the value
7445 * EGP.
7446 */
7447 switch (pi->attr->origin) {
7448 case BGP_ORIGIN_INCOMPLETE:
7449 aggregate->incomplete_origin_count++;
7450 break;
7451 case BGP_ORIGIN_EGP:
7452 aggregate->egp_origin_count++;
7453 break;
7454 default:
7455 /*Do nothing.
7456 */
7457 break;
7458 }
7459
7460 if (!aggregate->as_set)
7461 continue;
7462
7463 /*
7464 * as-set aggregate route generate origin, as path,
7465 * and community aggregation.
7466 */
7467 /* Compute aggregate route's as-path.
7468 */
7469 bgp_compute_aggregate_aspath_hash(aggregate,
7470 pi->attr->aspath);
7471
7472 /* Compute aggregate route's community.
7473 */
7474 if (bgp_attr_get_community(pi->attr))
7475 bgp_compute_aggregate_community_hash(
7476 aggregate,
7477 bgp_attr_get_community(pi->attr));
7478
7479 /* Compute aggregate route's extended community.
7480 */
7481 if (bgp_attr_get_ecommunity(pi->attr))
7482 bgp_compute_aggregate_ecommunity_hash(
7483 aggregate,
7484 bgp_attr_get_ecommunity(pi->attr));
7485
7486 /* Compute aggregate route's large community.
7487 */
7488 if (bgp_attr_get_lcommunity(pi->attr))
7489 bgp_compute_aggregate_lcommunity_hash(
7490 aggregate,
7491 bgp_attr_get_lcommunity(pi->attr));
7492 }
7493 if (match)
7494 bgp_process(bgp, dest, afi, safi);
7495 }
7496 if (aggregate->as_set) {
7497 bgp_compute_aggregate_aspath_val(aggregate);
7498 bgp_compute_aggregate_community_val(aggregate);
7499 bgp_compute_aggregate_ecommunity_val(aggregate);
7500 bgp_compute_aggregate_lcommunity_val(aggregate);
7501 }
7502
7503
7504 bgp_dest_unlock_node(top);
7505
7506
7507 if (aggregate->incomplete_origin_count > 0)
7508 origin = BGP_ORIGIN_INCOMPLETE;
7509 else if (aggregate->egp_origin_count > 0)
7510 origin = BGP_ORIGIN_EGP;
7511
7512 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7513 origin = aggregate->origin;
7514
7515 if (aggregate->as_set) {
7516 if (aggregate->aspath)
7517 /* Retrieve aggregate route's as-path.
7518 */
7519 aspath = aspath_dup(aggregate->aspath);
7520
7521 if (aggregate->community)
7522 /* Retrieve aggregate route's community.
7523 */
7524 community = community_dup(aggregate->community);
7525
7526 if (aggregate->ecommunity)
7527 /* Retrieve aggregate route's ecommunity.
7528 */
7529 ecommunity = ecommunity_dup(aggregate->ecommunity);
7530
7531 if (aggregate->lcommunity)
7532 /* Retrieve aggregate route's lcommunity.
7533 */
7534 lcommunity = lcommunity_dup(aggregate->lcommunity);
7535 }
7536
7537 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7538 ecommunity, lcommunity, atomic_aggregate,
7539 aggregate);
7540 }
7541
7542 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7543 safi_t safi, struct bgp_aggregate *aggregate)
7544 {
7545 struct bgp_table *table;
7546 struct bgp_dest *top;
7547 struct bgp_dest *dest;
7548 struct bgp_path_info *pi;
7549 unsigned long match;
7550
7551 table = bgp->rib[afi][safi];
7552
7553 /* If routes exists below this node, generate aggregate routes. */
7554 top = bgp_node_get(table, p);
7555 for (dest = bgp_node_get(table, p); dest;
7556 dest = bgp_route_next_until(dest, top)) {
7557 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7558
7559 if (dest_p->prefixlen <= p->prefixlen)
7560 continue;
7561 match = 0;
7562
7563 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7564 if (BGP_PATH_HOLDDOWN(pi))
7565 continue;
7566
7567 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7568 continue;
7569
7570 /*
7571 * This route is suppressed: attempt to unsuppress it.
7572 *
7573 * `aggr_unsuppress_path` will fail if this particular
7574 * aggregate route was not the suppressor.
7575 */
7576 if (pi->extra && pi->extra->aggr_suppressors &&
7577 listcount(pi->extra->aggr_suppressors)) {
7578 if (aggr_unsuppress_path(aggregate, pi))
7579 match++;
7580 }
7581
7582 aggregate->count--;
7583
7584 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7585 aggregate->incomplete_origin_count--;
7586 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7587 aggregate->egp_origin_count--;
7588
7589 if (aggregate->as_set) {
7590 /* Remove as-path from aggregate.
7591 */
7592 bgp_remove_aspath_from_aggregate_hash(
7593 aggregate,
7594 pi->attr->aspath);
7595
7596 if (bgp_attr_get_community(pi->attr))
7597 /* Remove community from aggregate.
7598 */
7599 bgp_remove_comm_from_aggregate_hash(
7600 aggregate,
7601 bgp_attr_get_community(
7602 pi->attr));
7603
7604 if (bgp_attr_get_ecommunity(pi->attr))
7605 /* Remove ecommunity from aggregate.
7606 */
7607 bgp_remove_ecomm_from_aggregate_hash(
7608 aggregate,
7609 bgp_attr_get_ecommunity(
7610 pi->attr));
7611
7612 if (bgp_attr_get_lcommunity(pi->attr))
7613 /* Remove lcommunity from aggregate.
7614 */
7615 bgp_remove_lcomm_from_aggregate_hash(
7616 aggregate,
7617 bgp_attr_get_lcommunity(
7618 pi->attr));
7619 }
7620 }
7621
7622 /* If this node was suppressed, process the change. */
7623 if (match)
7624 bgp_process(bgp, dest, afi, safi);
7625 }
7626 if (aggregate->as_set) {
7627 aspath_free(aggregate->aspath);
7628 aggregate->aspath = NULL;
7629 if (aggregate->community)
7630 community_free(&aggregate->community);
7631 if (aggregate->ecommunity)
7632 ecommunity_free(&aggregate->ecommunity);
7633 if (aggregate->lcommunity)
7634 lcommunity_free(&aggregate->lcommunity);
7635 }
7636
7637 bgp_dest_unlock_node(top);
7638 }
7639
7640 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7641 const struct prefix *aggr_p,
7642 struct bgp_path_info *pinew, afi_t afi,
7643 safi_t safi,
7644 struct bgp_aggregate *aggregate)
7645 {
7646 uint8_t origin;
7647 struct aspath *aspath = NULL;
7648 uint8_t atomic_aggregate = 0;
7649 struct community *community = NULL;
7650 struct ecommunity *ecommunity = NULL;
7651 struct lcommunity *lcommunity = NULL;
7652
7653 /* If the bgp instance is being deleted or self peer is deleted
7654 * then do not create aggregate route
7655 */
7656 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7657 || (bgp->peer_self == NULL))
7658 return;
7659
7660 /* ORIGIN attribute: If at least one route among routes that are
7661 * aggregated has ORIGIN with the value INCOMPLETE, then the
7662 * aggregated route must have the ORIGIN attribute with the value
7663 * INCOMPLETE. Otherwise, if at least one route among routes that
7664 * are aggregated has ORIGIN with the value EGP, then the aggregated
7665 * route must have the origin attribute with the value EGP. In all
7666 * other case the value of the ORIGIN attribute of the aggregated
7667 * route is INTERNAL.
7668 */
7669 origin = BGP_ORIGIN_IGP;
7670
7671 aggregate->count++;
7672
7673 /*
7674 * This must be called before `summary` check to avoid
7675 * "suppressing" twice.
7676 */
7677 if (aggregate->match_med)
7678 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7679 pinew, true);
7680
7681 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7682 aggr_suppress_path(aggregate, pinew);
7683
7684 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7685 && aggr_suppress_map_test(bgp, aggregate, pinew))
7686 aggr_suppress_path(aggregate, pinew);
7687
7688 switch (pinew->attr->origin) {
7689 case BGP_ORIGIN_INCOMPLETE:
7690 aggregate->incomplete_origin_count++;
7691 break;
7692 case BGP_ORIGIN_EGP:
7693 aggregate->egp_origin_count++;
7694 break;
7695 default:
7696 /* Do nothing.
7697 */
7698 break;
7699 }
7700
7701 if (aggregate->incomplete_origin_count > 0)
7702 origin = BGP_ORIGIN_INCOMPLETE;
7703 else if (aggregate->egp_origin_count > 0)
7704 origin = BGP_ORIGIN_EGP;
7705
7706 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7707 origin = aggregate->origin;
7708
7709 if (aggregate->as_set) {
7710 /* Compute aggregate route's as-path.
7711 */
7712 bgp_compute_aggregate_aspath(aggregate,
7713 pinew->attr->aspath);
7714
7715 /* Compute aggregate route's community.
7716 */
7717 if (bgp_attr_get_community(pinew->attr))
7718 bgp_compute_aggregate_community(
7719 aggregate, bgp_attr_get_community(pinew->attr));
7720
7721 /* Compute aggregate route's extended community.
7722 */
7723 if (bgp_attr_get_ecommunity(pinew->attr))
7724 bgp_compute_aggregate_ecommunity(
7725 aggregate,
7726 bgp_attr_get_ecommunity(pinew->attr));
7727
7728 /* Compute aggregate route's large community.
7729 */
7730 if (bgp_attr_get_lcommunity(pinew->attr))
7731 bgp_compute_aggregate_lcommunity(
7732 aggregate,
7733 bgp_attr_get_lcommunity(pinew->attr));
7734
7735 /* Retrieve aggregate route's as-path.
7736 */
7737 if (aggregate->aspath)
7738 aspath = aspath_dup(aggregate->aspath);
7739
7740 /* Retrieve aggregate route's community.
7741 */
7742 if (aggregate->community)
7743 community = community_dup(aggregate->community);
7744
7745 /* Retrieve aggregate route's ecommunity.
7746 */
7747 if (aggregate->ecommunity)
7748 ecommunity = ecommunity_dup(aggregate->ecommunity);
7749
7750 /* Retrieve aggregate route's lcommunity.
7751 */
7752 if (aggregate->lcommunity)
7753 lcommunity = lcommunity_dup(aggregate->lcommunity);
7754 }
7755
7756 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7757 aspath, community, ecommunity,
7758 lcommunity, atomic_aggregate, aggregate);
7759 }
7760
7761 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7762 safi_t safi,
7763 struct bgp_path_info *pi,
7764 struct bgp_aggregate *aggregate,
7765 const struct prefix *aggr_p)
7766 {
7767 uint8_t origin;
7768 struct aspath *aspath = NULL;
7769 uint8_t atomic_aggregate = 0;
7770 struct community *community = NULL;
7771 struct ecommunity *ecommunity = NULL;
7772 struct lcommunity *lcommunity = NULL;
7773 unsigned long match = 0;
7774
7775 /* If the bgp instance is being deleted or self peer is deleted
7776 * then do not create aggregate route
7777 */
7778 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7779 || (bgp->peer_self == NULL))
7780 return;
7781
7782 if (BGP_PATH_HOLDDOWN(pi))
7783 return;
7784
7785 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7786 return;
7787
7788 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7789 if (aggr_unsuppress_path(aggregate, pi))
7790 match++;
7791
7792 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7793 && aggr_suppress_map_test(bgp, aggregate, pi))
7794 if (aggr_unsuppress_path(aggregate, pi))
7795 match++;
7796
7797 /*
7798 * This must be called after `summary`, `suppress-map` check to avoid
7799 * "unsuppressing" twice.
7800 */
7801 if (aggregate->match_med)
7802 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
7803 true);
7804
7805 if (aggregate->count > 0)
7806 aggregate->count--;
7807
7808 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7809 aggregate->incomplete_origin_count--;
7810 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7811 aggregate->egp_origin_count--;
7812
7813 if (aggregate->as_set) {
7814 /* Remove as-path from aggregate.
7815 */
7816 bgp_remove_aspath_from_aggregate(aggregate,
7817 pi->attr->aspath);
7818
7819 if (bgp_attr_get_community(pi->attr))
7820 /* Remove community from aggregate.
7821 */
7822 bgp_remove_community_from_aggregate(
7823 aggregate, bgp_attr_get_community(pi->attr));
7824
7825 if (bgp_attr_get_ecommunity(pi->attr))
7826 /* Remove ecommunity from aggregate.
7827 */
7828 bgp_remove_ecommunity_from_aggregate(
7829 aggregate, bgp_attr_get_ecommunity(pi->attr));
7830
7831 if (bgp_attr_get_lcommunity(pi->attr))
7832 /* Remove lcommunity from aggregate.
7833 */
7834 bgp_remove_lcommunity_from_aggregate(
7835 aggregate, bgp_attr_get_lcommunity(pi->attr));
7836 }
7837
7838 /* If this node was suppressed, process the change. */
7839 if (match)
7840 bgp_process(bgp, pi->net, afi, safi);
7841
7842 origin = BGP_ORIGIN_IGP;
7843 if (aggregate->incomplete_origin_count > 0)
7844 origin = BGP_ORIGIN_INCOMPLETE;
7845 else if (aggregate->egp_origin_count > 0)
7846 origin = BGP_ORIGIN_EGP;
7847
7848 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7849 origin = aggregate->origin;
7850
7851 if (aggregate->as_set) {
7852 /* Retrieve aggregate route's as-path.
7853 */
7854 if (aggregate->aspath)
7855 aspath = aspath_dup(aggregate->aspath);
7856
7857 /* Retrieve aggregate route's community.
7858 */
7859 if (aggregate->community)
7860 community = community_dup(aggregate->community);
7861
7862 /* Retrieve aggregate route's ecommunity.
7863 */
7864 if (aggregate->ecommunity)
7865 ecommunity = ecommunity_dup(aggregate->ecommunity);
7866
7867 /* Retrieve aggregate route's lcommunity.
7868 */
7869 if (aggregate->lcommunity)
7870 lcommunity = lcommunity_dup(aggregate->lcommunity);
7871 }
7872
7873 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7874 aspath, community, ecommunity,
7875 lcommunity, atomic_aggregate, aggregate);
7876 }
7877
7878 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
7879 struct bgp_path_info *pi, afi_t afi, safi_t safi)
7880 {
7881 struct bgp_dest *child;
7882 struct bgp_dest *dest;
7883 struct bgp_aggregate *aggregate;
7884 struct bgp_table *table;
7885
7886 table = bgp->aggregate[afi][safi];
7887
7888 /* No aggregates configured. */
7889 if (bgp_table_top_nolock(table) == NULL)
7890 return;
7891
7892 if (p->prefixlen == 0)
7893 return;
7894
7895 if (BGP_PATH_HOLDDOWN(pi))
7896 return;
7897
7898 /* If suppress fib is enabled and route not installed
7899 * in FIB, do not update the aggregate route
7900 */
7901 if (!bgp_check_advertise(bgp, pi->net))
7902 return;
7903
7904 child = bgp_node_get(table, p);
7905
7906 /* Aggregate address configuration check. */
7907 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7908 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7909
7910 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7911 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7912 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
7913 aggregate);
7914 }
7915 }
7916 bgp_dest_unlock_node(child);
7917 }
7918
7919 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
7920 struct bgp_path_info *del, afi_t afi, safi_t safi)
7921 {
7922 struct bgp_dest *child;
7923 struct bgp_dest *dest;
7924 struct bgp_aggregate *aggregate;
7925 struct bgp_table *table;
7926
7927 table = bgp->aggregate[afi][safi];
7928
7929 /* No aggregates configured. */
7930 if (bgp_table_top_nolock(table) == NULL)
7931 return;
7932
7933 if (p->prefixlen == 0)
7934 return;
7935
7936 child = bgp_node_get(table, p);
7937
7938 /* Aggregate address configuration check. */
7939 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7940 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7941
7942 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7943 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7944 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
7945 aggregate, dest_p);
7946 }
7947 }
7948 bgp_dest_unlock_node(child);
7949 }
7950
7951 /* Aggregate route attribute. */
7952 #define AGGREGATE_SUMMARY_ONLY 1
7953 #define AGGREGATE_AS_SET 1
7954 #define AGGREGATE_AS_UNSET 0
7955
7956 static const char *bgp_origin2str(uint8_t origin)
7957 {
7958 switch (origin) {
7959 case BGP_ORIGIN_IGP:
7960 return "igp";
7961 case BGP_ORIGIN_EGP:
7962 return "egp";
7963 case BGP_ORIGIN_INCOMPLETE:
7964 return "incomplete";
7965 }
7966 return "n/a";
7967 }
7968
7969 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
7970 {
7971 switch (v_state) {
7972 case RPKI_NOT_BEING_USED:
7973 return "not used";
7974 case RPKI_VALID:
7975 return "valid";
7976 case RPKI_NOTFOUND:
7977 return "not found";
7978 case RPKI_INVALID:
7979 return "invalid";
7980 }
7981
7982 assert(!"We should never get here this is a dev escape");
7983 return "ERROR";
7984 }
7985
7986 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
7987 afi_t afi, safi_t safi)
7988 {
7989 VTY_DECLVAR_CONTEXT(bgp, bgp);
7990 int ret;
7991 struct prefix p;
7992 struct bgp_dest *dest;
7993 struct bgp_aggregate *aggregate;
7994
7995 /* Convert string to prefix structure. */
7996 ret = str2prefix(prefix_str, &p);
7997 if (!ret) {
7998 vty_out(vty, "Malformed prefix\n");
7999 return CMD_WARNING_CONFIG_FAILED;
8000 }
8001 apply_mask(&p);
8002
8003 /* Old configuration check. */
8004 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
8005 if (!dest) {
8006 vty_out(vty,
8007 "%% There is no aggregate-address configuration.\n");
8008 return CMD_WARNING_CONFIG_FAILED;
8009 }
8010
8011 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8012 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
8013 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8014 NULL, NULL, 0, aggregate);
8015
8016 /* Unlock aggregate address configuration. */
8017 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8018
8019 if (aggregate->community)
8020 community_free(&aggregate->community);
8021
8022 if (aggregate->community_hash) {
8023 /* Delete all communities in the hash.
8024 */
8025 hash_clean(aggregate->community_hash,
8026 bgp_aggr_community_remove);
8027 /* Free up the community_hash.
8028 */
8029 hash_free(aggregate->community_hash);
8030 }
8031
8032 if (aggregate->ecommunity)
8033 ecommunity_free(&aggregate->ecommunity);
8034
8035 if (aggregate->ecommunity_hash) {
8036 /* Delete all ecommunities in the hash.
8037 */
8038 hash_clean(aggregate->ecommunity_hash,
8039 bgp_aggr_ecommunity_remove);
8040 /* Free up the ecommunity_hash.
8041 */
8042 hash_free(aggregate->ecommunity_hash);
8043 }
8044
8045 if (aggregate->lcommunity)
8046 lcommunity_free(&aggregate->lcommunity);
8047
8048 if (aggregate->lcommunity_hash) {
8049 /* Delete all lcommunities in the hash.
8050 */
8051 hash_clean(aggregate->lcommunity_hash,
8052 bgp_aggr_lcommunity_remove);
8053 /* Free up the lcommunity_hash.
8054 */
8055 hash_free(aggregate->lcommunity_hash);
8056 }
8057
8058 if (aggregate->aspath)
8059 aspath_free(aggregate->aspath);
8060
8061 if (aggregate->aspath_hash) {
8062 /* Delete all as-paths in the hash.
8063 */
8064 hash_clean(aggregate->aspath_hash,
8065 bgp_aggr_aspath_remove);
8066 /* Free up the aspath_hash.
8067 */
8068 hash_free(aggregate->aspath_hash);
8069 }
8070
8071 bgp_aggregate_free(aggregate);
8072 bgp_dest_unlock_node(dest);
8073 bgp_dest_unlock_node(dest);
8074
8075 return CMD_SUCCESS;
8076 }
8077
8078 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8079 safi_t safi, const char *rmap,
8080 uint8_t summary_only, uint8_t as_set,
8081 uint8_t origin, bool match_med,
8082 const char *suppress_map)
8083 {
8084 VTY_DECLVAR_CONTEXT(bgp, bgp);
8085 int ret;
8086 struct prefix p;
8087 struct bgp_dest *dest;
8088 struct bgp_aggregate *aggregate;
8089 uint8_t as_set_new = as_set;
8090
8091 if (suppress_map && summary_only) {
8092 vty_out(vty,
8093 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8094 return CMD_WARNING_CONFIG_FAILED;
8095 }
8096
8097 /* Convert string to prefix structure. */
8098 ret = str2prefix(prefix_str, &p);
8099 if (!ret) {
8100 vty_out(vty, "Malformed prefix\n");
8101 return CMD_WARNING_CONFIG_FAILED;
8102 }
8103 apply_mask(&p);
8104
8105 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8106 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8107 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8108 prefix_str);
8109 return CMD_WARNING_CONFIG_FAILED;
8110 }
8111
8112 /* Old configuration check. */
8113 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8114 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8115
8116 if (aggregate) {
8117 vty_out(vty, "There is already same aggregate network.\n");
8118 /* try to remove the old entry */
8119 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8120 if (ret) {
8121 vty_out(vty, "Error deleting aggregate.\n");
8122 bgp_dest_unlock_node(dest);
8123 return CMD_WARNING_CONFIG_FAILED;
8124 }
8125 }
8126
8127 /* Make aggregate address structure. */
8128 aggregate = bgp_aggregate_new();
8129 aggregate->summary_only = summary_only;
8130 aggregate->match_med = match_med;
8131
8132 /* Network operators MUST NOT locally generate any new
8133 * announcements containing AS_SET or AS_CONFED_SET. If they have
8134 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8135 * SHOULD withdraw those routes and re-announce routes for the
8136 * aggregate or component prefixes (i.e., the more-specific routes
8137 * subsumed by the previously aggregated route) without AS_SET
8138 * or AS_CONFED_SET in the updates.
8139 */
8140 if (bgp->reject_as_sets) {
8141 if (as_set == AGGREGATE_AS_SET) {
8142 as_set_new = AGGREGATE_AS_UNSET;
8143 zlog_warn(
8144 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8145 __func__);
8146 vty_out(vty,
8147 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8148 }
8149 }
8150
8151 aggregate->as_set = as_set_new;
8152 aggregate->safi = safi;
8153 /* Override ORIGIN attribute if defined.
8154 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8155 * to IGP which is not what rfc4271 says.
8156 * This enables the same behavior, optionally.
8157 */
8158 aggregate->origin = origin;
8159
8160 if (rmap) {
8161 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8162 route_map_counter_decrement(aggregate->rmap.map);
8163 aggregate->rmap.name =
8164 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8165 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8166 route_map_counter_increment(aggregate->rmap.map);
8167 }
8168
8169 if (suppress_map) {
8170 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8171 route_map_counter_decrement(aggregate->suppress_map);
8172
8173 aggregate->suppress_map_name =
8174 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8175 aggregate->suppress_map =
8176 route_map_lookup_by_name(aggregate->suppress_map_name);
8177 route_map_counter_increment(aggregate->suppress_map);
8178 }
8179
8180 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8181
8182 /* Aggregate address insert into BGP routing table. */
8183 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8184
8185 return CMD_SUCCESS;
8186 }
8187
8188 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8189 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8190 "as-set$as_set_s"
8191 "|summary-only$summary_only"
8192 "|route-map WORD$rmap_name"
8193 "|origin <egp|igp|incomplete>$origin_s"
8194 "|matching-MED-only$match_med"
8195 "|suppress-map WORD$suppress_map"
8196 "}]",
8197 NO_STR
8198 "Configure BGP aggregate entries\n"
8199 "Aggregate prefix\n" "Aggregate address\n" "Aggregate mask\n"
8200 "Generate AS set path information\n"
8201 "Filter more specific routes from updates\n"
8202 "Apply route map to aggregate network\n"
8203 "Route map name\n"
8204 "BGP origin code\n"
8205 "Remote EGP\n"
8206 "Local IGP\n"
8207 "Unknown heritage\n"
8208 "Only aggregate routes with matching MED\n"
8209 "Suppress the selected more specific routes\n"
8210 "Route map with the route selectors\n")
8211 {
8212 const char *prefix_s = NULL;
8213 safi_t safi = bgp_node_safi(vty);
8214 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8215 int as_set = AGGREGATE_AS_UNSET;
8216 char prefix_buf[PREFIX2STR_BUFFER];
8217
8218 if (addr_str) {
8219 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8220 sizeof(prefix_buf))
8221 == 0) {
8222 vty_out(vty, "%% Inconsistent address and mask\n");
8223 return CMD_WARNING_CONFIG_FAILED;
8224 }
8225 prefix_s = prefix_buf;
8226 } else
8227 prefix_s = prefix_str;
8228
8229 if (origin_s) {
8230 if (strcmp(origin_s, "egp") == 0)
8231 origin = BGP_ORIGIN_EGP;
8232 else if (strcmp(origin_s, "igp") == 0)
8233 origin = BGP_ORIGIN_IGP;
8234 else if (strcmp(origin_s, "incomplete") == 0)
8235 origin = BGP_ORIGIN_INCOMPLETE;
8236 }
8237
8238 if (as_set_s)
8239 as_set = AGGREGATE_AS_SET;
8240
8241 /* Handle configuration removal, otherwise installation. */
8242 if (no)
8243 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8244
8245 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8246 summary_only != NULL, as_set, origin,
8247 match_med != NULL, suppress_map);
8248 }
8249
8250 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8251 "[no] aggregate-address X:X::X:X/M$prefix [{"
8252 "as-set$as_set_s"
8253 "|summary-only$summary_only"
8254 "|route-map WORD$rmap_name"
8255 "|origin <egp|igp|incomplete>$origin_s"
8256 "|matching-MED-only$match_med"
8257 "|suppress-map WORD$suppress_map"
8258 "}]",
8259 NO_STR
8260 "Configure BGP aggregate entries\n"
8261 "Aggregate prefix\n"
8262 "Generate AS set path information\n"
8263 "Filter more specific routes from updates\n"
8264 "Apply route map to aggregate network\n"
8265 "Route map name\n"
8266 "BGP origin code\n"
8267 "Remote EGP\n"
8268 "Local IGP\n"
8269 "Unknown heritage\n"
8270 "Only aggregate routes with matching MED\n"
8271 "Suppress the selected more specific routes\n"
8272 "Route map with the route selectors\n")
8273 {
8274 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8275 int as_set = AGGREGATE_AS_UNSET;
8276
8277 if (origin_s) {
8278 if (strcmp(origin_s, "egp") == 0)
8279 origin = BGP_ORIGIN_EGP;
8280 else if (strcmp(origin_s, "igp") == 0)
8281 origin = BGP_ORIGIN_IGP;
8282 else if (strcmp(origin_s, "incomplete") == 0)
8283 origin = BGP_ORIGIN_INCOMPLETE;
8284 }
8285
8286 if (as_set_s)
8287 as_set = AGGREGATE_AS_SET;
8288
8289 /* Handle configuration removal, otherwise installation. */
8290 if (no)
8291 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8292 SAFI_UNICAST);
8293
8294 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8295 rmap_name, summary_only != NULL, as_set,
8296 origin, match_med != NULL, suppress_map);
8297 }
8298
8299 /* Redistribute route treatment. */
8300 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8301 const union g_addr *nexthop, ifindex_t ifindex,
8302 enum nexthop_types_t nhtype, uint8_t distance,
8303 enum blackhole_type bhtype, uint32_t metric,
8304 uint8_t type, unsigned short instance,
8305 route_tag_t tag)
8306 {
8307 struct bgp_path_info *new;
8308 struct bgp_path_info *bpi;
8309 struct bgp_path_info rmap_path;
8310 struct bgp_dest *bn;
8311 struct attr attr;
8312 struct attr *new_attr;
8313 afi_t afi;
8314 route_map_result_t ret;
8315 struct bgp_redist *red;
8316
8317 /* Make default attribute. */
8318 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
8319 /*
8320 * This must not be NULL to satisfy Coverity SA
8321 */
8322 assert(attr.aspath);
8323
8324 switch (nhtype) {
8325 case NEXTHOP_TYPE_IFINDEX:
8326 break;
8327 case NEXTHOP_TYPE_IPV4:
8328 case NEXTHOP_TYPE_IPV4_IFINDEX:
8329 attr.nexthop = nexthop->ipv4;
8330 break;
8331 case NEXTHOP_TYPE_IPV6:
8332 case NEXTHOP_TYPE_IPV6_IFINDEX:
8333 attr.mp_nexthop_global = nexthop->ipv6;
8334 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8335 break;
8336 case NEXTHOP_TYPE_BLACKHOLE:
8337 switch (p->family) {
8338 case AF_INET:
8339 attr.nexthop.s_addr = INADDR_ANY;
8340 break;
8341 case AF_INET6:
8342 memset(&attr.mp_nexthop_global, 0,
8343 sizeof(attr.mp_nexthop_global));
8344 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8345 break;
8346 }
8347 attr.bh_type = bhtype;
8348 break;
8349 }
8350 attr.nh_type = nhtype;
8351 attr.nh_ifindex = ifindex;
8352
8353 attr.med = metric;
8354 attr.distance = distance;
8355 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8356 attr.tag = tag;
8357
8358 afi = family2afi(p->family);
8359
8360 red = bgp_redist_lookup(bgp, afi, type, instance);
8361 if (red) {
8362 struct attr attr_new;
8363
8364 /* Copy attribute for modification. */
8365 attr_new = attr;
8366
8367 if (red->redist_metric_flag)
8368 attr_new.med = red->redist_metric;
8369
8370 /* Apply route-map. */
8371 if (red->rmap.name) {
8372 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
8373 rmap_path.peer = bgp->peer_self;
8374 rmap_path.attr = &attr_new;
8375
8376 SET_FLAG(bgp->peer_self->rmap_type,
8377 PEER_RMAP_TYPE_REDISTRIBUTE);
8378
8379 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8380
8381 bgp->peer_self->rmap_type = 0;
8382
8383 if (ret == RMAP_DENYMATCH) {
8384 /* Free uninterned attribute. */
8385 bgp_attr_flush(&attr_new);
8386
8387 /* Unintern original. */
8388 aspath_unintern(&attr.aspath);
8389 bgp_redistribute_delete(bgp, p, type, instance);
8390 return;
8391 }
8392 }
8393
8394 if (bgp_in_graceful_shutdown(bgp))
8395 bgp_attr_add_gshut_community(&attr_new);
8396
8397 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8398 SAFI_UNICAST, p, NULL);
8399
8400 new_attr = bgp_attr_intern(&attr_new);
8401
8402 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8403 if (bpi->peer == bgp->peer_self
8404 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8405 break;
8406
8407 if (bpi) {
8408 /* Ensure the (source route) type is updated. */
8409 bpi->type = type;
8410 if (attrhash_cmp(bpi->attr, new_attr)
8411 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8412 bgp_attr_unintern(&new_attr);
8413 aspath_unintern(&attr.aspath);
8414 bgp_dest_unlock_node(bn);
8415 return;
8416 } else {
8417 /* The attribute is changed. */
8418 bgp_path_info_set_flag(bn, bpi,
8419 BGP_PATH_ATTR_CHANGED);
8420
8421 /* Rewrite BGP route information. */
8422 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8423 bgp_path_info_restore(bn, bpi);
8424 else
8425 bgp_aggregate_decrement(
8426 bgp, p, bpi, afi, SAFI_UNICAST);
8427 bgp_attr_unintern(&bpi->attr);
8428 bpi->attr = new_attr;
8429 bpi->uptime = bgp_clock();
8430
8431 /* Process change. */
8432 bgp_aggregate_increment(bgp, p, bpi, afi,
8433 SAFI_UNICAST);
8434 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8435 bgp_dest_unlock_node(bn);
8436 aspath_unintern(&attr.aspath);
8437
8438 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8439 || (bgp->inst_type
8440 == BGP_INSTANCE_TYPE_DEFAULT)) {
8441
8442 vpn_leak_from_vrf_update(
8443 bgp_get_default(), bgp, bpi);
8444 }
8445 return;
8446 }
8447 }
8448
8449 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8450 bgp->peer_self, new_attr, bn);
8451 SET_FLAG(new->flags, BGP_PATH_VALID);
8452
8453 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8454 bgp_path_info_add(bn, new);
8455 bgp_dest_unlock_node(bn);
8456 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8457 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8458
8459 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8460 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8461
8462 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8463 }
8464 }
8465
8466 /* Unintern original. */
8467 aspath_unintern(&attr.aspath);
8468 }
8469
8470 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8471 unsigned short instance)
8472 {
8473 afi_t afi;
8474 struct bgp_dest *dest;
8475 struct bgp_path_info *pi;
8476 struct bgp_redist *red;
8477
8478 afi = family2afi(p->family);
8479
8480 red = bgp_redist_lookup(bgp, afi, type, instance);
8481 if (red) {
8482 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8483 SAFI_UNICAST, p, NULL);
8484
8485 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8486 if (pi->peer == bgp->peer_self && pi->type == type)
8487 break;
8488
8489 if (pi) {
8490 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8491 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8492
8493 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8494 bgp, pi);
8495 }
8496 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8497 bgp_path_info_delete(dest, pi);
8498 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8499 }
8500 bgp_dest_unlock_node(dest);
8501 }
8502 }
8503
8504 /* Withdraw specified route type's route. */
8505 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8506 unsigned short instance)
8507 {
8508 struct bgp_dest *dest;
8509 struct bgp_path_info *pi;
8510 struct bgp_table *table;
8511
8512 table = bgp->rib[afi][SAFI_UNICAST];
8513
8514 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8515 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8516 if (pi->peer == bgp->peer_self && pi->type == type
8517 && pi->instance == instance)
8518 break;
8519
8520 if (pi) {
8521 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8522 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8523
8524 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8525 bgp, pi);
8526 }
8527 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8528 pi, afi, SAFI_UNICAST);
8529 bgp_path_info_delete(dest, pi);
8530 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8531 }
8532 }
8533 }
8534
8535 /* Static function to display route. */
8536 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8537 struct vty *vty, json_object *json, bool wide)
8538 {
8539 int len = 0;
8540 char buf[BUFSIZ];
8541
8542 if (p->family == AF_INET) {
8543 if (!json) {
8544 len = vty_out(vty, "%pFX", p);
8545 } else {
8546 json_object_string_add(json, "prefix",
8547 inet_ntop(p->family,
8548 &p->u.prefix, buf,
8549 BUFSIZ));
8550 json_object_int_add(json, "prefixLen", p->prefixlen);
8551 json_object_string_addf(json, "network", "%pFX", p);
8552 json_object_int_add(json, "version", dest->version);
8553 }
8554 } else if (p->family == AF_ETHERNET) {
8555 len = vty_out(vty, "%pFX", p);
8556 } else if (p->family == AF_EVPN) {
8557 if (!json)
8558 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8559 else
8560 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8561 } else if (p->family == AF_FLOWSPEC) {
8562 route_vty_out_flowspec(vty, p, NULL,
8563 json ?
8564 NLRI_STRING_FORMAT_JSON_SIMPLE :
8565 NLRI_STRING_FORMAT_MIN, json);
8566 } else {
8567 if (!json)
8568 len = vty_out(vty, "%pFX", p);
8569 else {
8570 json_object_string_add(json, "prefix",
8571 inet_ntop(p->family,
8572 &p->u.prefix, buf,
8573 BUFSIZ));
8574 json_object_int_add(json, "prefixLen", p->prefixlen);
8575 json_object_string_addf(json, "network", "%pFX", p);
8576 json_object_int_add(json, "version", dest->version);
8577 }
8578 }
8579
8580 if (!json) {
8581 len = wide ? (45 - len) : (17 - len);
8582 if (len < 1)
8583 vty_out(vty, "\n%*s", 20, " ");
8584 else
8585 vty_out(vty, "%*s", len, " ");
8586 }
8587 }
8588
8589 enum bgp_display_type {
8590 normal_list,
8591 };
8592
8593 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8594 {
8595 switch (reason) {
8596 case bgp_path_selection_none:
8597 return "Nothing to Select";
8598 case bgp_path_selection_first:
8599 return "First path received";
8600 case bgp_path_selection_evpn_sticky_mac:
8601 return "EVPN Sticky Mac";
8602 case bgp_path_selection_evpn_seq:
8603 return "EVPN sequence number";
8604 case bgp_path_selection_evpn_lower_ip:
8605 return "EVPN lower IP";
8606 case bgp_path_selection_evpn_local_path:
8607 return "EVPN local ES path";
8608 case bgp_path_selection_evpn_non_proxy:
8609 return "EVPN non proxy";
8610 case bgp_path_selection_weight:
8611 return "Weight";
8612 case bgp_path_selection_local_pref:
8613 return "Local Pref";
8614 case bgp_path_selection_local_route:
8615 return "Local Route";
8616 case bgp_path_selection_confed_as_path:
8617 return "Confederation based AS Path";
8618 case bgp_path_selection_as_path:
8619 return "AS Path";
8620 case bgp_path_selection_origin:
8621 return "Origin";
8622 case bgp_path_selection_med:
8623 return "MED";
8624 case bgp_path_selection_peer:
8625 return "Peer Type";
8626 case bgp_path_selection_confed:
8627 return "Confed Peer Type";
8628 case bgp_path_selection_igp_metric:
8629 return "IGP Metric";
8630 case bgp_path_selection_older:
8631 return "Older Path";
8632 case bgp_path_selection_router_id:
8633 return "Router ID";
8634 case bgp_path_selection_cluster_length:
8635 return "Cluster length";
8636 case bgp_path_selection_stale:
8637 return "Path Staleness";
8638 case bgp_path_selection_local_configured:
8639 return "Locally configured route";
8640 case bgp_path_selection_neighbor_ip:
8641 return "Neighbor IP";
8642 case bgp_path_selection_default:
8643 return "Nothing left to compare";
8644 }
8645 return "Invalid (internal error)";
8646 }
8647
8648 /* Print the short form route status for a bgp_path_info */
8649 static void route_vty_short_status_out(struct vty *vty,
8650 struct bgp_path_info *path,
8651 const struct prefix *p,
8652 json_object *json_path)
8653 {
8654 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8655
8656 if (json_path) {
8657
8658 /* Route status display. */
8659 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8660 json_object_boolean_true_add(json_path, "removed");
8661
8662 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8663 json_object_boolean_true_add(json_path, "stale");
8664
8665 if (path->extra && bgp_path_suppressed(path))
8666 json_object_boolean_true_add(json_path, "suppressed");
8667
8668 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8669 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8670 json_object_boolean_true_add(json_path, "valid");
8671
8672 /* Selected */
8673 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8674 json_object_boolean_true_add(json_path, "history");
8675
8676 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8677 json_object_boolean_true_add(json_path, "damped");
8678
8679 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8680 json_object_boolean_true_add(json_path, "bestpath");
8681 json_object_string_add(json_path, "selectionReason",
8682 bgp_path_selection_reason2str(
8683 path->net->reason));
8684 }
8685
8686 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8687 json_object_boolean_true_add(json_path, "multipath");
8688
8689 /* Internal route. */
8690 if ((path->peer->as)
8691 && (path->peer->as == path->peer->local_as))
8692 json_object_string_add(json_path, "pathFrom",
8693 "internal");
8694 else
8695 json_object_string_add(json_path, "pathFrom",
8696 "external");
8697
8698 return;
8699 }
8700
8701 /* RPKI validation state */
8702 rpki_state =
8703 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
8704
8705 if (rpki_state == RPKI_VALID)
8706 vty_out(vty, "V");
8707 else if (rpki_state == RPKI_INVALID)
8708 vty_out(vty, "I");
8709 else if (rpki_state == RPKI_NOTFOUND)
8710 vty_out(vty, "N");
8711
8712 /* Route status display. */
8713 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8714 vty_out(vty, "R");
8715 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8716 vty_out(vty, "S");
8717 else if (bgp_path_suppressed(path))
8718 vty_out(vty, "s");
8719 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8720 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8721 vty_out(vty, "*");
8722 else
8723 vty_out(vty, " ");
8724
8725 /* Selected */
8726 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8727 vty_out(vty, "h");
8728 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8729 vty_out(vty, "d");
8730 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8731 vty_out(vty, ">");
8732 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8733 vty_out(vty, "=");
8734 else
8735 vty_out(vty, " ");
8736
8737 /* Internal route. */
8738 if (path->peer && (path->peer->as)
8739 && (path->peer->as == path->peer->local_as))
8740 vty_out(vty, "i");
8741 else
8742 vty_out(vty, " ");
8743 }
8744
8745 static char *bgp_nexthop_hostname(struct peer *peer,
8746 struct bgp_nexthop_cache *bnc)
8747 {
8748 if (peer->hostname
8749 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8750 return peer->hostname;
8751 return NULL;
8752 }
8753
8754 /* called from terminal list command */
8755 void route_vty_out(struct vty *vty, const struct prefix *p,
8756 struct bgp_path_info *path, int display, safi_t safi,
8757 json_object *json_paths, bool wide)
8758 {
8759 int len;
8760 struct attr *attr = path->attr;
8761 json_object *json_path = NULL;
8762 json_object *json_nexthops = NULL;
8763 json_object *json_nexthop_global = NULL;
8764 json_object *json_nexthop_ll = NULL;
8765 json_object *json_ext_community = NULL;
8766 char vrf_id_str[VRF_NAMSIZ] = {0};
8767 bool nexthop_self =
8768 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8769 bool nexthop_othervrf = false;
8770 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8771 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8772 char *nexthop_hostname =
8773 bgp_nexthop_hostname(path->peer, path->nexthop);
8774 char esi_buf[ESI_STR_LEN];
8775
8776 if (json_paths)
8777 json_path = json_object_new_object();
8778
8779 /* short status lead text */
8780 route_vty_short_status_out(vty, path, p, json_path);
8781
8782 if (!json_paths) {
8783 /* print prefix and mask */
8784 if (!display)
8785 route_vty_out_route(path->net, p, vty, json_path, wide);
8786 else
8787 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8788 } else {
8789 route_vty_out_route(path->net, p, vty, json_path, wide);
8790 }
8791
8792 /*
8793 * If vrf id of nexthop is different from that of prefix,
8794 * set up printable string to append
8795 */
8796 if (path->extra && path->extra->bgp_orig) {
8797 const char *self = "";
8798
8799 if (nexthop_self)
8800 self = "<";
8801
8802 nexthop_othervrf = true;
8803 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8804
8805 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8806 snprintf(vrf_id_str, sizeof(vrf_id_str),
8807 "@%s%s", VRFID_NONE_STR, self);
8808 else
8809 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8810 path->extra->bgp_orig->vrf_id, self);
8811
8812 if (path->extra->bgp_orig->inst_type
8813 != BGP_INSTANCE_TYPE_DEFAULT)
8814
8815 nexthop_vrfname = path->extra->bgp_orig->name;
8816 } else {
8817 const char *self = "";
8818
8819 if (nexthop_self)
8820 self = "<";
8821
8822 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8823 }
8824
8825 /*
8826 * For ENCAP and EVPN routes, nexthop address family is not
8827 * neccessarily the same as the prefix address family.
8828 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
8829 * EVPN routes are also exchanged with a MP nexthop. Currently,
8830 * this
8831 * is only IPv4, the value will be present in either
8832 * attr->nexthop or
8833 * attr->mp_nexthop_global_in
8834 */
8835 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
8836 char buf[BUFSIZ];
8837 char nexthop[128];
8838 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8839
8840 switch (af) {
8841 case AF_INET:
8842 snprintf(nexthop, sizeof(nexthop), "%s",
8843 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
8844 BUFSIZ));
8845 break;
8846 case AF_INET6:
8847 snprintf(nexthop, sizeof(nexthop), "%s",
8848 inet_ntop(af, &attr->mp_nexthop_global, buf,
8849 BUFSIZ));
8850 break;
8851 default:
8852 snprintf(nexthop, sizeof(nexthop), "?");
8853 break;
8854 }
8855
8856 if (json_paths) {
8857 json_nexthop_global = json_object_new_object();
8858
8859 json_object_string_add(json_nexthop_global, "ip",
8860 nexthop);
8861
8862 if (path->peer->hostname)
8863 json_object_string_add(json_nexthop_global,
8864 "hostname",
8865 path->peer->hostname);
8866
8867 json_object_string_add(json_nexthop_global, "afi",
8868 (af == AF_INET) ? "ipv4"
8869 : "ipv6");
8870 json_object_boolean_true_add(json_nexthop_global,
8871 "used");
8872 } else {
8873 if (nexthop_hostname)
8874 len = vty_out(vty, "%s(%s)%s", nexthop,
8875 nexthop_hostname, vrf_id_str);
8876 else
8877 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
8878
8879 len = wide ? (41 - len) : (16 - len);
8880 if (len < 1)
8881 vty_out(vty, "\n%*s", 36, " ");
8882 else
8883 vty_out(vty, "%*s", len, " ");
8884 }
8885 } else if (safi == SAFI_EVPN) {
8886 if (json_paths) {
8887 json_nexthop_global = json_object_new_object();
8888
8889 json_object_string_addf(json_nexthop_global, "ip",
8890 "%pI4", &attr->nexthop);
8891
8892 if (path->peer->hostname)
8893 json_object_string_add(json_nexthop_global,
8894 "hostname",
8895 path->peer->hostname);
8896
8897 json_object_string_add(json_nexthop_global, "afi",
8898 "ipv4");
8899 json_object_boolean_true_add(json_nexthop_global,
8900 "used");
8901 } else {
8902 if (nexthop_hostname)
8903 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8904 nexthop_hostname, vrf_id_str);
8905 else
8906 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8907 vrf_id_str);
8908
8909 len = wide ? (41 - len) : (16 - len);
8910 if (len < 1)
8911 vty_out(vty, "\n%*s", 36, " ");
8912 else
8913 vty_out(vty, "%*s", len, " ");
8914 }
8915 } else if (safi == SAFI_FLOWSPEC) {
8916 if (attr->nexthop.s_addr != INADDR_ANY) {
8917 if (json_paths) {
8918 json_nexthop_global = json_object_new_object();
8919
8920 json_object_string_add(json_nexthop_global,
8921 "afi", "ipv4");
8922 json_object_string_addf(json_nexthop_global,
8923 "ip", "%pI4",
8924 &attr->nexthop);
8925
8926 if (path->peer->hostname)
8927 json_object_string_add(
8928 json_nexthop_global, "hostname",
8929 path->peer->hostname);
8930
8931 json_object_boolean_true_add(
8932 json_nexthop_global,
8933 "used");
8934 } else {
8935 if (nexthop_hostname)
8936 len = vty_out(vty, "%pI4(%s)%s",
8937 &attr->nexthop,
8938 nexthop_hostname,
8939 vrf_id_str);
8940 else
8941 len = vty_out(vty, "%pI4%s",
8942 &attr->nexthop,
8943 vrf_id_str);
8944
8945 len = wide ? (41 - len) : (16 - len);
8946 if (len < 1)
8947 vty_out(vty, "\n%*s", 36, " ");
8948 else
8949 vty_out(vty, "%*s", len, " ");
8950 }
8951 }
8952 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8953 if (json_paths) {
8954 json_nexthop_global = json_object_new_object();
8955
8956 json_object_string_addf(json_nexthop_global, "ip",
8957 "%pI4", &attr->nexthop);
8958
8959 if (path->peer->hostname)
8960 json_object_string_add(json_nexthop_global,
8961 "hostname",
8962 path->peer->hostname);
8963
8964 json_object_string_add(json_nexthop_global, "afi",
8965 "ipv4");
8966 json_object_boolean_true_add(json_nexthop_global,
8967 "used");
8968 } else {
8969 if (nexthop_hostname)
8970 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8971 nexthop_hostname, vrf_id_str);
8972 else
8973 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8974 vrf_id_str);
8975
8976 len = wide ? (41 - len) : (16 - len);
8977 if (len < 1)
8978 vty_out(vty, "\n%*s", 36, " ");
8979 else
8980 vty_out(vty, "%*s", len, " ");
8981 }
8982 }
8983
8984 /* IPv6 Next Hop */
8985 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8986 if (json_paths) {
8987 json_nexthop_global = json_object_new_object();
8988 json_object_string_addf(json_nexthop_global, "ip",
8989 "%pI6",
8990 &attr->mp_nexthop_global);
8991
8992 if (path->peer->hostname)
8993 json_object_string_add(json_nexthop_global,
8994 "hostname",
8995 path->peer->hostname);
8996
8997 json_object_string_add(json_nexthop_global, "afi",
8998 "ipv6");
8999 json_object_string_add(json_nexthop_global, "scope",
9000 "global");
9001
9002 /* We display both LL & GL if both have been
9003 * received */
9004 if ((attr->mp_nexthop_len
9005 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9006 || (path->peer->conf_if)) {
9007 json_nexthop_ll = json_object_new_object();
9008 json_object_string_addf(
9009 json_nexthop_ll, "ip", "%pI6",
9010 &attr->mp_nexthop_local);
9011
9012 if (path->peer->hostname)
9013 json_object_string_add(
9014 json_nexthop_ll, "hostname",
9015 path->peer->hostname);
9016
9017 json_object_string_add(json_nexthop_ll, "afi",
9018 "ipv6");
9019 json_object_string_add(json_nexthop_ll, "scope",
9020 "link-local");
9021
9022 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9023 &attr->mp_nexthop_local)
9024 != 0)
9025 && !attr->mp_nexthop_prefer_global)
9026 json_object_boolean_true_add(
9027 json_nexthop_ll, "used");
9028 else
9029 json_object_boolean_true_add(
9030 json_nexthop_global, "used");
9031 } else
9032 json_object_boolean_true_add(
9033 json_nexthop_global, "used");
9034 } else {
9035 /* Display LL if LL/Global both in table unless
9036 * prefer-global is set */
9037 if (((attr->mp_nexthop_len
9038 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9039 && !attr->mp_nexthop_prefer_global)
9040 || (path->peer->conf_if)) {
9041 if (path->peer->conf_if) {
9042 len = vty_out(vty, "%s",
9043 path->peer->conf_if);
9044 /* len of IPv6 addr + max len of def
9045 * ifname */
9046 len = wide ? (41 - len) : (16 - len);
9047
9048 if (len < 1)
9049 vty_out(vty, "\n%*s", 36, " ");
9050 else
9051 vty_out(vty, "%*s", len, " ");
9052 } else {
9053 if (nexthop_hostname)
9054 len = vty_out(
9055 vty, "%pI6(%s)%s",
9056 &attr->mp_nexthop_local,
9057 nexthop_hostname,
9058 vrf_id_str);
9059 else
9060 len = vty_out(
9061 vty, "%pI6%s",
9062 &attr->mp_nexthop_local,
9063 vrf_id_str);
9064
9065 len = wide ? (41 - len) : (16 - len);
9066
9067 if (len < 1)
9068 vty_out(vty, "\n%*s", 36, " ");
9069 else
9070 vty_out(vty, "%*s", len, " ");
9071 }
9072 } else {
9073 if (nexthop_hostname)
9074 len = vty_out(vty, "%pI6(%s)%s",
9075 &attr->mp_nexthop_global,
9076 nexthop_hostname,
9077 vrf_id_str);
9078 else
9079 len = vty_out(vty, "%pI6%s",
9080 &attr->mp_nexthop_global,
9081 vrf_id_str);
9082
9083 len = wide ? (41 - len) : (16 - len);
9084
9085 if (len < 1)
9086 vty_out(vty, "\n%*s", 36, " ");
9087 else
9088 vty_out(vty, "%*s", len, " ");
9089 }
9090 }
9091 }
9092
9093 /* MED/Metric */
9094 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9095 if (json_paths)
9096 json_object_int_add(json_path, "metric", attr->med);
9097 else if (wide)
9098 vty_out(vty, "%7u", attr->med);
9099 else
9100 vty_out(vty, "%10u", attr->med);
9101 else if (!json_paths) {
9102 if (wide)
9103 vty_out(vty, "%*s", 7, " ");
9104 else
9105 vty_out(vty, "%*s", 10, " ");
9106 }
9107
9108 /* Local Pref */
9109 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9110 if (json_paths)
9111 json_object_int_add(json_path, "locPrf",
9112 attr->local_pref);
9113 else
9114 vty_out(vty, "%7u", attr->local_pref);
9115 else if (!json_paths)
9116 vty_out(vty, " ");
9117
9118 if (json_paths)
9119 json_object_int_add(json_path, "weight", attr->weight);
9120 else
9121 vty_out(vty, "%7u ", attr->weight);
9122
9123 if (json_paths) {
9124 char buf[BUFSIZ];
9125 json_object_string_add(
9126 json_path, "peerId",
9127 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
9128 }
9129
9130 /* Print aspath */
9131 if (attr->aspath) {
9132 if (json_paths)
9133 json_object_string_add(json_path, "path",
9134 attr->aspath->str);
9135 else
9136 aspath_print_vty(vty, "%s", attr->aspath, " ");
9137 }
9138
9139 /* Print origin */
9140 if (json_paths)
9141 json_object_string_add(json_path, "origin",
9142 bgp_origin_long_str[attr->origin]);
9143 else
9144 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9145
9146 if (json_paths) {
9147 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9148 json_object_string_add(json_path, "esi",
9149 esi_to_str(&attr->esi,
9150 esi_buf, sizeof(esi_buf)));
9151 }
9152 if (safi == SAFI_EVPN &&
9153 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9154 json_ext_community = json_object_new_object();
9155 json_object_string_add(
9156 json_ext_community, "string",
9157 bgp_attr_get_ecommunity(attr)->str);
9158 json_object_object_add(json_path,
9159 "extendedCommunity",
9160 json_ext_community);
9161 }
9162
9163 if (nexthop_self)
9164 json_object_boolean_true_add(json_path,
9165 "announceNexthopSelf");
9166 if (nexthop_othervrf) {
9167 json_object_string_add(json_path, "nhVrfName",
9168 nexthop_vrfname);
9169
9170 json_object_int_add(json_path, "nhVrfId",
9171 ((nexthop_vrfid == VRF_UNKNOWN)
9172 ? -1
9173 : (int)nexthop_vrfid));
9174 }
9175 }
9176
9177 if (json_paths) {
9178 if (json_nexthop_global || json_nexthop_ll) {
9179 json_nexthops = json_object_new_array();
9180
9181 if (json_nexthop_global)
9182 json_object_array_add(json_nexthops,
9183 json_nexthop_global);
9184
9185 if (json_nexthop_ll)
9186 json_object_array_add(json_nexthops,
9187 json_nexthop_ll);
9188
9189 json_object_object_add(json_path, "nexthops",
9190 json_nexthops);
9191 }
9192
9193 json_object_array_add(json_paths, json_path);
9194 } else {
9195 vty_out(vty, "\n");
9196
9197 if (safi == SAFI_EVPN) {
9198 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9199 /* XXX - add these params to the json out */
9200 vty_out(vty, "%*s", 20, " ");
9201 vty_out(vty, "ESI:%s",
9202 esi_to_str(&attr->esi, esi_buf,
9203 sizeof(esi_buf)));
9204
9205 vty_out(vty, "\n");
9206 }
9207 if (attr->flag &
9208 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9209 vty_out(vty, "%*s", 20, " ");
9210 vty_out(vty, "%s\n",
9211 bgp_attr_get_ecommunity(attr)->str);
9212 }
9213 }
9214
9215 #ifdef ENABLE_BGP_VNC
9216 /* prints an additional line, indented, with VNC info, if
9217 * present */
9218 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9219 rfapi_vty_out_vncinfo(vty, p, path, safi);
9220 #endif
9221 }
9222 }
9223
9224 /* called from terminal list command */
9225 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9226 const struct prefix *p, struct attr *attr, safi_t safi,
9227 bool use_json, json_object *json_ar, bool wide)
9228 {
9229 json_object *json_status = NULL;
9230 json_object *json_net = NULL;
9231 int len;
9232 char buff[BUFSIZ];
9233
9234 /* Route status display. */
9235 if (use_json) {
9236 json_status = json_object_new_object();
9237 json_net = json_object_new_object();
9238 } else {
9239 vty_out(vty, "*");
9240 vty_out(vty, ">");
9241 vty_out(vty, " ");
9242 }
9243
9244 /* print prefix and mask */
9245 if (use_json) {
9246 if (safi == SAFI_EVPN)
9247 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9248 else if (p->family == AF_INET || p->family == AF_INET6) {
9249 json_object_string_add(
9250 json_net, "addrPrefix",
9251 inet_ntop(p->family, &p->u.prefix, buff,
9252 BUFSIZ));
9253 json_object_int_add(json_net, "prefixLen",
9254 p->prefixlen);
9255 json_object_string_addf(json_net, "network", "%pFX", p);
9256 }
9257 } else
9258 route_vty_out_route(dest, p, vty, NULL, wide);
9259
9260 /* Print attribute */
9261 if (attr) {
9262 if (use_json) {
9263 if (p->family == AF_INET
9264 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9265 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9266 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9267 json_object_string_addf(
9268 json_net, "nextHop", "%pI4",
9269 &attr->mp_nexthop_global_in);
9270 else
9271 json_object_string_addf(
9272 json_net, "nextHop", "%pI4",
9273 &attr->nexthop);
9274 } else if (p->family == AF_INET6
9275 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9276 json_object_string_addf(
9277 json_net, "nextHopGlobal", "%pI6",
9278 &attr->mp_nexthop_global);
9279 } else if (p->family == AF_EVPN
9280 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9281 json_object_string_addf(
9282 json_net, "nextHop", "%pI4",
9283 &attr->mp_nexthop_global_in);
9284 }
9285
9286 if (attr->flag
9287 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9288 json_object_int_add(json_net, "metric",
9289 attr->med);
9290
9291 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9292 json_object_int_add(json_net, "locPrf",
9293 attr->local_pref);
9294
9295 json_object_int_add(json_net, "weight", attr->weight);
9296
9297 /* Print aspath */
9298 if (attr->aspath)
9299 json_object_string_add(json_net, "path",
9300 attr->aspath->str);
9301
9302 /* Print origin */
9303 json_object_string_add(json_net, "bgpOriginCode",
9304 bgp_origin_str[attr->origin]);
9305 } else {
9306 if (p->family == AF_INET
9307 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9308 || safi == SAFI_EVPN
9309 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9310 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9311 || safi == SAFI_EVPN)
9312 vty_out(vty, "%-16pI4",
9313 &attr->mp_nexthop_global_in);
9314 else if (wide)
9315 vty_out(vty, "%-41pI4", &attr->nexthop);
9316 else
9317 vty_out(vty, "%-16pI4", &attr->nexthop);
9318 } else if (p->family == AF_INET6
9319 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9320 char buf[BUFSIZ];
9321
9322 len = vty_out(
9323 vty, "%s",
9324 inet_ntop(AF_INET6,
9325 &attr->mp_nexthop_global, buf,
9326 BUFSIZ));
9327 len = wide ? (41 - len) : (16 - len);
9328 if (len < 1)
9329 vty_out(vty, "\n%*s", 36, " ");
9330 else
9331 vty_out(vty, "%*s", len, " ");
9332 }
9333 if (attr->flag
9334 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9335 if (wide)
9336 vty_out(vty, "%7u", attr->med);
9337 else
9338 vty_out(vty, "%10u", attr->med);
9339 else if (wide)
9340 vty_out(vty, " ");
9341 else
9342 vty_out(vty, " ");
9343
9344 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9345 vty_out(vty, "%7u", attr->local_pref);
9346 else
9347 vty_out(vty, " ");
9348
9349 vty_out(vty, "%7u ", attr->weight);
9350
9351 /* Print aspath */
9352 if (attr->aspath)
9353 aspath_print_vty(vty, "%s", attr->aspath, " ");
9354
9355 /* Print origin */
9356 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9357 }
9358 }
9359 if (use_json) {
9360 json_object_boolean_true_add(json_status, "*");
9361 json_object_boolean_true_add(json_status, ">");
9362 json_object_object_add(json_net, "appliedStatusSymbols",
9363 json_status);
9364
9365 prefix2str(p, buff, PREFIX_STRLEN);
9366 json_object_object_add(json_ar, buff, json_net);
9367 } else
9368 vty_out(vty, "\n");
9369 }
9370
9371 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9372 struct bgp_path_info *path, int display, safi_t safi,
9373 json_object *json)
9374 {
9375 json_object *json_out = NULL;
9376 struct attr *attr;
9377 mpls_label_t label = MPLS_INVALID_LABEL;
9378
9379 if (!path->extra)
9380 return;
9381
9382 if (json)
9383 json_out = json_object_new_object();
9384
9385 /* short status lead text */
9386 route_vty_short_status_out(vty, path, p, json_out);
9387
9388 /* print prefix and mask */
9389 if (json == NULL) {
9390 if (!display)
9391 route_vty_out_route(path->net, p, vty, NULL, false);
9392 else
9393 vty_out(vty, "%*s", 17, " ");
9394 }
9395
9396 /* Print attribute */
9397 attr = path->attr;
9398 if (((p->family == AF_INET)
9399 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9400 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9401 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9402 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9403 || safi == SAFI_EVPN) {
9404 if (json)
9405 json_object_string_addf(
9406 json_out, "mpNexthopGlobalIn", "%pI4",
9407 &attr->mp_nexthop_global_in);
9408 else
9409 vty_out(vty, "%-16pI4",
9410 &attr->mp_nexthop_global_in);
9411 } else {
9412 if (json)
9413 json_object_string_addf(json_out, "nexthop",
9414 "%pI4", &attr->nexthop);
9415 else
9416 vty_out(vty, "%-16pI4", &attr->nexthop);
9417 }
9418 } else if (((p->family == AF_INET6)
9419 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9420 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9421 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9422 char buf_a[512];
9423
9424 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9425 if (json)
9426 json_object_string_addf(
9427 json_out, "mpNexthopGlobalIn", "%pI6",
9428 &attr->mp_nexthop_global);
9429 else
9430 vty_out(vty, "%s",
9431 inet_ntop(AF_INET6,
9432 &attr->mp_nexthop_global,
9433 buf_a, sizeof(buf_a)));
9434 } else if (attr->mp_nexthop_len
9435 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9436 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9437 &attr->mp_nexthop_global,
9438 &attr->mp_nexthop_local);
9439 if (json)
9440 json_object_string_add(json_out,
9441 "mpNexthopGlobalLocal",
9442 buf_a);
9443 else
9444 vty_out(vty, "%s", buf_a);
9445 }
9446 }
9447
9448 label = decode_label(&path->extra->label[0]);
9449
9450 if (bgp_is_valid_label(&label)) {
9451 if (json) {
9452 json_object_int_add(json_out, "notag", label);
9453 json_object_array_add(json, json_out);
9454 } else {
9455 vty_out(vty, "notag/%d", label);
9456 vty_out(vty, "\n");
9457 }
9458 } else if (!json)
9459 vty_out(vty, "\n");
9460 }
9461
9462 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9463 struct bgp_path_info *path, int display,
9464 json_object *json_paths)
9465 {
9466 struct attr *attr;
9467 char buf[BUFSIZ] = {0};
9468 json_object *json_path = NULL;
9469 json_object *json_nexthop = NULL;
9470 json_object *json_overlay = NULL;
9471
9472 if (!path->extra)
9473 return;
9474
9475 if (json_paths) {
9476 json_path = json_object_new_object();
9477 json_overlay = json_object_new_object();
9478 json_nexthop = json_object_new_object();
9479 }
9480
9481 /* short status lead text */
9482 route_vty_short_status_out(vty, path, p, json_path);
9483
9484 /* print prefix and mask */
9485 if (!display)
9486 route_vty_out_route(path->net, p, vty, json_path, false);
9487 else
9488 vty_out(vty, "%*s", 17, " ");
9489
9490 /* Print attribute */
9491 attr = path->attr;
9492 char buf1[BUFSIZ];
9493 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9494
9495 switch (af) {
9496 case AF_INET:
9497 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
9498 if (!json_path) {
9499 vty_out(vty, "%-16s", buf);
9500 } else {
9501 json_object_string_add(json_nexthop, "ip", buf);
9502
9503 json_object_string_add(json_nexthop, "afi", "ipv4");
9504
9505 json_object_object_add(json_path, "nexthop",
9506 json_nexthop);
9507 }
9508 break;
9509 case AF_INET6:
9510 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
9511 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
9512 if (!json_path) {
9513 vty_out(vty, "%s(%s)", buf, buf1);
9514 } else {
9515 json_object_string_add(json_nexthop, "ipv6Global", buf);
9516
9517 json_object_string_add(json_nexthop, "ipv6LinkLocal",
9518 buf1);
9519
9520 json_object_string_add(json_nexthop, "afi", "ipv6");
9521
9522 json_object_object_add(json_path, "nexthop",
9523 json_nexthop);
9524 }
9525 break;
9526 default:
9527 if (!json_path) {
9528 vty_out(vty, "?");
9529 } else {
9530 json_object_string_add(json_nexthop, "Error",
9531 "Unsupported address-family");
9532 json_object_string_add(json_nexthop, "error",
9533 "Unsupported address-family");
9534 }
9535 }
9536
9537 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9538
9539 ipaddr2str(&eo->gw_ip, buf, BUFSIZ);
9540
9541 if (!json_path)
9542 vty_out(vty, "/%s", buf);
9543 else
9544 json_object_string_add(json_overlay, "gw", buf);
9545
9546 if (bgp_attr_get_ecommunity(attr)) {
9547 char *mac = NULL;
9548 struct ecommunity_val *routermac = ecommunity_lookup(
9549 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9550 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9551
9552 if (routermac)
9553 mac = ecom_mac2str((char *)routermac->val);
9554 if (mac) {
9555 if (!json_path) {
9556 vty_out(vty, "/%s", mac);
9557 } else {
9558 json_object_string_add(json_overlay, "rmac",
9559 mac);
9560 }
9561 XFREE(MTYPE_TMP, mac);
9562 }
9563 }
9564
9565 if (!json_path) {
9566 vty_out(vty, "\n");
9567 } else {
9568 json_object_object_add(json_path, "overlay", json_overlay);
9569
9570 json_object_array_add(json_paths, json_path);
9571 }
9572 }
9573
9574 /* dampening route */
9575 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9576 struct bgp_path_info *path, int display,
9577 afi_t afi, safi_t safi, bool use_json,
9578 json_object *json_paths)
9579 {
9580 struct attr *attr = path->attr;
9581 int len;
9582 char timebuf[BGP_UPTIME_LEN];
9583 json_object *json_path = NULL;
9584
9585 if (use_json)
9586 json_path = json_object_new_object();
9587
9588 /* short status lead text */
9589 route_vty_short_status_out(vty, path, p, json_path);
9590
9591 /* print prefix and mask */
9592 if (!use_json) {
9593 if (!display)
9594 route_vty_out_route(path->net, p, vty, NULL, false);
9595 else
9596 vty_out(vty, "%*s", 17, " ");
9597
9598 len = vty_out(vty, "%s", path->peer->host);
9599 len = 17 - len;
9600
9601 if (len < 1)
9602 vty_out(vty, "\n%*s", 34, " ");
9603 else
9604 vty_out(vty, "%*s", len, " ");
9605
9606 vty_out(vty, "%s ",
9607 bgp_damp_reuse_time_vty(vty, path, timebuf,
9608 BGP_UPTIME_LEN, afi, safi,
9609 use_json, NULL));
9610
9611 if (attr->aspath)
9612 aspath_print_vty(vty, "%s", attr->aspath, " ");
9613
9614 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9615
9616 vty_out(vty, "\n");
9617 } else {
9618 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9619 safi, use_json, json_path);
9620
9621 if (attr->aspath)
9622 json_object_string_add(json_path, "asPath",
9623 attr->aspath->str);
9624
9625 json_object_string_add(json_path, "origin",
9626 bgp_origin_str[attr->origin]);
9627 json_object_string_add(json_path, "peerHost", path->peer->host);
9628
9629 json_object_array_add(json_paths, json_path);
9630 }
9631 }
9632
9633 /* flap route */
9634 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9635 struct bgp_path_info *path, int display,
9636 afi_t afi, safi_t safi, bool use_json,
9637 json_object *json_paths)
9638 {
9639 struct attr *attr = path->attr;
9640 struct bgp_damp_info *bdi;
9641 char timebuf[BGP_UPTIME_LEN];
9642 int len;
9643 json_object *json_path = NULL;
9644
9645 if (!path->extra)
9646 return;
9647
9648 if (use_json)
9649 json_path = json_object_new_object();
9650
9651 bdi = path->extra->damp_info;
9652
9653 /* short status lead text */
9654 route_vty_short_status_out(vty, path, p, json_path);
9655
9656 if (!use_json) {
9657 if (!display)
9658 route_vty_out_route(path->net, p, vty, NULL, false);
9659 else
9660 vty_out(vty, "%*s", 17, " ");
9661
9662 len = vty_out(vty, "%s", path->peer->host);
9663 len = 16 - len;
9664 if (len < 1)
9665 vty_out(vty, "\n%*s", 33, " ");
9666 else
9667 vty_out(vty, "%*s", len, " ");
9668
9669 len = vty_out(vty, "%d", bdi->flap);
9670 len = 5 - len;
9671 if (len < 1)
9672 vty_out(vty, " ");
9673 else
9674 vty_out(vty, "%*s", len, " ");
9675
9676 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9677 BGP_UPTIME_LEN, 0, NULL));
9678
9679 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9680 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9681 vty_out(vty, "%s ",
9682 bgp_damp_reuse_time_vty(vty, path, timebuf,
9683 BGP_UPTIME_LEN, afi,
9684 safi, use_json, NULL));
9685 else
9686 vty_out(vty, "%*s ", 8, " ");
9687
9688 if (attr->aspath)
9689 aspath_print_vty(vty, "%s", attr->aspath, " ");
9690
9691 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9692
9693 vty_out(vty, "\n");
9694 } else {
9695 json_object_string_add(json_path, "peerHost", path->peer->host);
9696 json_object_int_add(json_path, "bdiFlap", bdi->flap);
9697
9698 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9699 json_path);
9700
9701 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9702 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9703 bgp_damp_reuse_time_vty(vty, path, timebuf,
9704 BGP_UPTIME_LEN, afi, safi,
9705 use_json, json_path);
9706
9707 if (attr->aspath)
9708 json_object_string_add(json_path, "asPath",
9709 attr->aspath->str);
9710
9711 json_object_string_add(json_path, "origin",
9712 bgp_origin_str[attr->origin]);
9713
9714 json_object_array_add(json_paths, json_path);
9715 }
9716 }
9717
9718 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9719 int *first, const char *header,
9720 json_object *json_adv_to)
9721 {
9722 char buf1[INET6_ADDRSTRLEN];
9723 json_object *json_peer = NULL;
9724
9725 if (json_adv_to) {
9726 /* 'advertised-to' is a dictionary of peers we have advertised
9727 * this
9728 * prefix too. The key is the peer's IP or swpX, the value is
9729 * the
9730 * hostname if we know it and "" if not.
9731 */
9732 json_peer = json_object_new_object();
9733
9734 if (peer->hostname)
9735 json_object_string_add(json_peer, "hostname",
9736 peer->hostname);
9737
9738 if (peer->conf_if)
9739 json_object_object_add(json_adv_to, peer->conf_if,
9740 json_peer);
9741 else
9742 json_object_object_add(
9743 json_adv_to,
9744 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
9745 json_peer);
9746 } else {
9747 if (*first) {
9748 vty_out(vty, "%s", header);
9749 *first = 0;
9750 }
9751
9752 if (peer->hostname
9753 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9754 if (peer->conf_if)
9755 vty_out(vty, " %s(%s)", peer->hostname,
9756 peer->conf_if);
9757 else
9758 vty_out(vty, " %s(%s)", peer->hostname,
9759 sockunion2str(&peer->su, buf1,
9760 SU_ADDRSTRLEN));
9761 } else {
9762 if (peer->conf_if)
9763 vty_out(vty, " %s", peer->conf_if);
9764 else
9765 vty_out(vty, " %s",
9766 sockunion2str(&peer->su, buf1,
9767 SU_ADDRSTRLEN));
9768 }
9769 }
9770 }
9771
9772 static void route_vty_out_tx_ids(struct vty *vty,
9773 struct bgp_addpath_info_data *d)
9774 {
9775 int i;
9776
9777 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9778 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9779 d->addpath_tx_id[i],
9780 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9781 }
9782 }
9783
9784 static void route_vty_out_detail_es_info(struct vty *vty,
9785 struct bgp_path_info *pi,
9786 struct attr *attr,
9787 json_object *json_path)
9788 {
9789 char esi_buf[ESI_STR_LEN];
9790 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9791 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9792 ATTR_ES_PEER_ROUTER);
9793 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9794 ATTR_ES_PEER_ACTIVE);
9795 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9796 ATTR_ES_PEER_PROXY);
9797 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9798 if (json_path) {
9799 json_object *json_es_info = NULL;
9800
9801 json_object_string_add(
9802 json_path, "esi",
9803 esi_buf);
9804 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9805 json_es_info = json_object_new_object();
9806 if (es_local)
9807 json_object_boolean_true_add(
9808 json_es_info, "localEs");
9809 if (peer_active)
9810 json_object_boolean_true_add(
9811 json_es_info, "peerActive");
9812 if (peer_proxy)
9813 json_object_boolean_true_add(
9814 json_es_info, "peerProxy");
9815 if (peer_router)
9816 json_object_boolean_true_add(
9817 json_es_info, "peerRouter");
9818 if (attr->mm_sync_seqnum)
9819 json_object_int_add(
9820 json_es_info, "peerSeq",
9821 attr->mm_sync_seqnum);
9822 json_object_object_add(
9823 json_path, "es_info",
9824 json_es_info);
9825 }
9826 } else {
9827 if (bgp_evpn_attr_is_sync(attr))
9828 vty_out(vty,
9829 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9830 esi_buf,
9831 es_local ? "local-es":"",
9832 peer_proxy ? "proxy " : "",
9833 peer_active ? "active ":"",
9834 peer_router ? "router ":"",
9835 attr->mm_sync_seqnum);
9836 else
9837 vty_out(vty, " ESI %s %s\n",
9838 esi_buf,
9839 es_local ? "local-es":"");
9840 }
9841 }
9842
9843 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
9844 struct bgp_path_info *path, afi_t afi, safi_t safi,
9845 enum rpki_states rpki_curr_state,
9846 json_object *json_paths)
9847 {
9848 char buf[INET6_ADDRSTRLEN];
9849 char buf1[BUFSIZ];
9850 struct attr *attr = path->attr;
9851 int sockunion_vty_out(struct vty *, union sockunion *);
9852 time_t tbuf;
9853 json_object *json_bestpath = NULL;
9854 json_object *json_cluster_list = NULL;
9855 json_object *json_cluster_list_list = NULL;
9856 json_object *json_ext_community = NULL;
9857 json_object *json_last_update = NULL;
9858 json_object *json_pmsi = NULL;
9859 json_object *json_nexthop_global = NULL;
9860 json_object *json_nexthop_ll = NULL;
9861 json_object *json_nexthops = NULL;
9862 json_object *json_path = NULL;
9863 json_object *json_peer = NULL;
9864 json_object *json_string = NULL;
9865 json_object *json_adv_to = NULL;
9866 int first = 0;
9867 struct listnode *node, *nnode;
9868 struct peer *peer;
9869 bool addpath_capable;
9870 int has_adj;
9871 unsigned int first_as;
9872 bool nexthop_self =
9873 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9874 int i;
9875 char *nexthop_hostname =
9876 bgp_nexthop_hostname(path->peer, path->nexthop);
9877
9878 if (json_paths) {
9879 json_path = json_object_new_object();
9880 json_peer = json_object_new_object();
9881 json_nexthop_global = json_object_new_object();
9882 }
9883
9884 if (safi == SAFI_EVPN) {
9885 if (!json_paths)
9886 vty_out(vty, " Route %pRN", bn);
9887 }
9888
9889 if (path->extra) {
9890 char tag_buf[30];
9891
9892 tag_buf[0] = '\0';
9893 if (path->extra && path->extra->num_labels) {
9894 bgp_evpn_label2str(path->extra->label,
9895 path->extra->num_labels, tag_buf,
9896 sizeof(tag_buf));
9897 }
9898 if (safi == SAFI_EVPN) {
9899 if (!json_paths) {
9900 if (tag_buf[0] != '\0')
9901 vty_out(vty, " VNI %s", tag_buf);
9902 } else {
9903 if (tag_buf[0]) {
9904 json_object_string_add(json_path, "VNI",
9905 tag_buf);
9906 json_object_string_add(json_path, "vni",
9907 tag_buf);
9908 }
9909 }
9910 }
9911
9912 if (path->extra && path->extra->parent && !json_paths) {
9913 struct bgp_path_info *parent_ri;
9914 struct bgp_dest *dest, *pdest;
9915
9916 parent_ri = (struct bgp_path_info *)path->extra->parent;
9917 dest = parent_ri->net;
9918 if (dest && dest->pdest) {
9919 pdest = dest->pdest;
9920 prefix_rd2str(
9921 (struct prefix_rd *)bgp_dest_get_prefix(
9922 pdest),
9923 buf1, sizeof(buf1));
9924 if (is_pi_family_evpn(parent_ri)) {
9925 vty_out(vty,
9926 " Imported from %s:%pFX, VNI %s",
9927 buf1,
9928 (struct prefix_evpn *)
9929 bgp_dest_get_prefix(
9930 dest),
9931 tag_buf);
9932 if (attr->es_flags & ATTR_ES_L3_NHG)
9933 vty_out(vty, ", L3NHG %s",
9934 (attr->es_flags
9935 & ATTR_ES_L3_NHG_ACTIVE)
9936 ? "active"
9937 : "inactive");
9938 vty_out(vty, "\n");
9939
9940 } else
9941 vty_out(vty,
9942 " Imported from %s:%pFX\n",
9943 buf1,
9944 (struct prefix_evpn *)
9945 bgp_dest_get_prefix(
9946 dest));
9947 }
9948 }
9949 }
9950
9951 if (safi == SAFI_EVPN
9952 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
9953 char gwip_buf[INET6_ADDRSTRLEN];
9954
9955 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
9956 sizeof(gwip_buf));
9957
9958 if (json_paths)
9959 json_object_string_add(json_path, "gatewayIP",
9960 gwip_buf);
9961 else
9962 vty_out(vty, " Gateway IP %s", gwip_buf);
9963 }
9964
9965 if (safi == SAFI_EVPN)
9966 vty_out(vty, "\n");
9967
9968 /* Line1 display AS-path, Aggregator */
9969 if (attr->aspath) {
9970 if (json_paths) {
9971 if (!attr->aspath->json)
9972 aspath_str_update(attr->aspath, true);
9973 json_object_lock(attr->aspath->json);
9974 json_object_object_add(json_path, "aspath",
9975 attr->aspath->json);
9976 } else {
9977 if (attr->aspath->segments)
9978 aspath_print_vty(vty, " %s", attr->aspath, "");
9979 else
9980 vty_out(vty, " Local");
9981 }
9982 }
9983
9984 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9985 if (json_paths)
9986 json_object_boolean_true_add(json_path, "removed");
9987 else
9988 vty_out(vty, ", (removed)");
9989 }
9990
9991 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9992 if (json_paths)
9993 json_object_boolean_true_add(json_path, "stale");
9994 else
9995 vty_out(vty, ", (stale)");
9996 }
9997
9998 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
9999 if (json_paths) {
10000 json_object_int_add(json_path, "aggregatorAs",
10001 attr->aggregator_as);
10002 json_object_string_addf(json_path, "aggregatorId",
10003 "%pI4", &attr->aggregator_addr);
10004 } else {
10005 vty_out(vty, ", (aggregated by %u %pI4)",
10006 attr->aggregator_as, &attr->aggregator_addr);
10007 }
10008 }
10009
10010 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10011 PEER_FLAG_REFLECTOR_CLIENT)) {
10012 if (json_paths)
10013 json_object_boolean_true_add(json_path,
10014 "rxedFromRrClient");
10015 else
10016 vty_out(vty, ", (Received from a RR-client)");
10017 }
10018
10019 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10020 PEER_FLAG_RSERVER_CLIENT)) {
10021 if (json_paths)
10022 json_object_boolean_true_add(json_path,
10023 "rxedFromRsClient");
10024 else
10025 vty_out(vty, ", (Received from a RS-client)");
10026 }
10027
10028 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10029 if (json_paths)
10030 json_object_boolean_true_add(json_path,
10031 "dampeningHistoryEntry");
10032 else
10033 vty_out(vty, ", (history entry)");
10034 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10035 if (json_paths)
10036 json_object_boolean_true_add(json_path,
10037 "dampeningSuppressed");
10038 else
10039 vty_out(vty, ", (suppressed due to dampening)");
10040 }
10041
10042 if (!json_paths)
10043 vty_out(vty, "\n");
10044
10045 /* Line2 display Next-hop, Neighbor, Router-id */
10046 /* Display the nexthop */
10047 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10048
10049 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
10050 || bn_p->family == AF_EVPN)
10051 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
10052 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
10053 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10054 || safi == SAFI_EVPN) {
10055 if (json_paths) {
10056 json_object_string_addf(
10057 json_nexthop_global, "ip", "%pI4",
10058 &attr->mp_nexthop_global_in);
10059
10060 if (path->peer->hostname)
10061 json_object_string_add(
10062 json_nexthop_global, "hostname",
10063 path->peer->hostname);
10064 } else {
10065 if (nexthop_hostname)
10066 vty_out(vty, " %pI4(%s)",
10067 &attr->mp_nexthop_global_in,
10068 nexthop_hostname);
10069 else
10070 vty_out(vty, " %pI4",
10071 &attr->mp_nexthop_global_in);
10072 }
10073 } else {
10074 if (json_paths) {
10075 json_object_string_addf(json_nexthop_global,
10076 "ip", "%pI4",
10077 &attr->nexthop);
10078
10079 if (path->peer->hostname)
10080 json_object_string_add(
10081 json_nexthop_global, "hostname",
10082 path->peer->hostname);
10083 } else {
10084 if (nexthop_hostname)
10085 vty_out(vty, " %pI4(%s)",
10086 &attr->nexthop,
10087 nexthop_hostname);
10088 else
10089 vty_out(vty, " %pI4",
10090 &attr->nexthop);
10091 }
10092 }
10093
10094 if (json_paths)
10095 json_object_string_add(json_nexthop_global, "afi",
10096 "ipv4");
10097 } else {
10098 if (json_paths) {
10099 json_object_string_addf(json_nexthop_global, "ip",
10100 "%pI6",
10101 &attr->mp_nexthop_global);
10102
10103 if (path->peer->hostname)
10104 json_object_string_add(json_nexthop_global,
10105 "hostname",
10106 path->peer->hostname);
10107
10108 json_object_string_add(json_nexthop_global, "afi",
10109 "ipv6");
10110 json_object_string_add(json_nexthop_global, "scope",
10111 "global");
10112 } else {
10113 if (nexthop_hostname)
10114 vty_out(vty, " %pI6(%s)",
10115 &attr->mp_nexthop_global,
10116 nexthop_hostname);
10117 else
10118 vty_out(vty, " %pI6",
10119 &attr->mp_nexthop_global);
10120 }
10121 }
10122
10123 /* Display the IGP cost or 'inaccessible' */
10124 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10125 if (json_paths)
10126 json_object_boolean_false_add(json_nexthop_global,
10127 "accessible");
10128 else
10129 vty_out(vty, " (inaccessible)");
10130 } else {
10131 if (path->extra && path->extra->igpmetric) {
10132 if (json_paths)
10133 json_object_int_add(json_nexthop_global,
10134 "metric",
10135 path->extra->igpmetric);
10136 else
10137 vty_out(vty, " (metric %u)",
10138 path->extra->igpmetric);
10139 }
10140
10141 /* IGP cost is 0, display this only for json */
10142 else {
10143 if (json_paths)
10144 json_object_int_add(json_nexthop_global,
10145 "metric", 0);
10146 }
10147
10148 if (json_paths)
10149 json_object_boolean_true_add(json_nexthop_global,
10150 "accessible");
10151 }
10152
10153 /* Display peer "from" output */
10154 /* This path was originated locally */
10155 if (path->peer == bgp->peer_self) {
10156
10157 if (safi == SAFI_EVPN
10158 || (bn_p->family == AF_INET
10159 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
10160 if (json_paths)
10161 json_object_string_add(json_peer, "peerId",
10162 "0.0.0.0");
10163 else
10164 vty_out(vty, " from 0.0.0.0 ");
10165 } else {
10166 if (json_paths)
10167 json_object_string_add(json_peer, "peerId",
10168 "::");
10169 else
10170 vty_out(vty, " from :: ");
10171 }
10172
10173 if (json_paths)
10174 json_object_string_addf(json_peer, "routerId", "%pI4",
10175 &bgp->router_id);
10176 else
10177 vty_out(vty, "(%pI4)", &bgp->router_id);
10178 }
10179
10180 /* We RXed this path from one of our peers */
10181 else {
10182
10183 if (json_paths) {
10184 json_object_string_add(json_peer, "peerId",
10185 sockunion2str(&path->peer->su,
10186 buf,
10187 SU_ADDRSTRLEN));
10188 json_object_string_addf(json_peer, "routerId", "%pI4",
10189 &path->peer->remote_id);
10190
10191 if (path->peer->hostname)
10192 json_object_string_add(json_peer, "hostname",
10193 path->peer->hostname);
10194
10195 if (path->peer->domainname)
10196 json_object_string_add(json_peer, "domainname",
10197 path->peer->domainname);
10198
10199 if (path->peer->conf_if)
10200 json_object_string_add(json_peer, "interface",
10201 path->peer->conf_if);
10202 } else {
10203 if (path->peer->conf_if) {
10204 if (path->peer->hostname
10205 && CHECK_FLAG(path->peer->bgp->flags,
10206 BGP_FLAG_SHOW_HOSTNAME))
10207 vty_out(vty, " from %s(%s)",
10208 path->peer->hostname,
10209 path->peer->conf_if);
10210 else
10211 vty_out(vty, " from %s",
10212 path->peer->conf_if);
10213 } else {
10214 if (path->peer->hostname
10215 && CHECK_FLAG(path->peer->bgp->flags,
10216 BGP_FLAG_SHOW_HOSTNAME))
10217 vty_out(vty, " from %s(%s)",
10218 path->peer->hostname,
10219 path->peer->host);
10220 else
10221 vty_out(vty, " from %s",
10222 sockunion2str(&path->peer->su,
10223 buf,
10224 SU_ADDRSTRLEN));
10225 }
10226
10227 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10228 vty_out(vty, " (%pI4)", &attr->originator_id);
10229 else
10230 vty_out(vty, " (%s)",
10231 inet_ntop(AF_INET,
10232 &path->peer->remote_id, buf1,
10233 sizeof(buf1)));
10234 }
10235 }
10236
10237 /*
10238 * Note when vrfid of nexthop is different from that of prefix
10239 */
10240 if (path->extra && path->extra->bgp_orig) {
10241 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10242
10243 if (json_paths) {
10244 const char *vn;
10245
10246 if (path->extra->bgp_orig->inst_type
10247 == BGP_INSTANCE_TYPE_DEFAULT)
10248 vn = VRF_DEFAULT_NAME;
10249 else
10250 vn = path->extra->bgp_orig->name;
10251
10252 json_object_string_add(json_path, "nhVrfName", vn);
10253
10254 if (nexthop_vrfid == VRF_UNKNOWN) {
10255 json_object_int_add(json_path, "nhVrfId", -1);
10256 } else {
10257 json_object_int_add(json_path, "nhVrfId",
10258 (int)nexthop_vrfid);
10259 }
10260 } else {
10261 if (nexthop_vrfid == VRF_UNKNOWN)
10262 vty_out(vty, " vrf ?");
10263 else {
10264 struct vrf *vrf;
10265
10266 vrf = vrf_lookup_by_id(nexthop_vrfid);
10267 vty_out(vty, " vrf %s(%u)",
10268 VRF_LOGNAME(vrf), nexthop_vrfid);
10269 }
10270 }
10271 }
10272
10273 if (nexthop_self) {
10274 if (json_paths) {
10275 json_object_boolean_true_add(json_path,
10276 "announceNexthopSelf");
10277 } else {
10278 vty_out(vty, " announce-nh-self");
10279 }
10280 }
10281
10282 if (!json_paths)
10283 vty_out(vty, "\n");
10284
10285 /* display the link-local nexthop */
10286 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10287 if (json_paths) {
10288 json_nexthop_ll = json_object_new_object();
10289 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10290 &attr->mp_nexthop_local);
10291
10292 if (path->peer->hostname)
10293 json_object_string_add(json_nexthop_ll,
10294 "hostname",
10295 path->peer->hostname);
10296
10297 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10298 json_object_string_add(json_nexthop_ll, "scope",
10299 "link-local");
10300
10301 json_object_boolean_true_add(json_nexthop_ll,
10302 "accessible");
10303
10304 if (!attr->mp_nexthop_prefer_global)
10305 json_object_boolean_true_add(json_nexthop_ll,
10306 "used");
10307 else
10308 json_object_boolean_true_add(
10309 json_nexthop_global, "used");
10310 } else {
10311 vty_out(vty, " (%s) %s\n",
10312 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10313 buf, INET6_ADDRSTRLEN),
10314 attr->mp_nexthop_prefer_global
10315 ? "(prefer-global)"
10316 : "(used)");
10317 }
10318 }
10319 /* If we do not have a link-local nexthop then we must flag the
10320 global as "used" */
10321 else {
10322 if (json_paths)
10323 json_object_boolean_true_add(json_nexthop_global,
10324 "used");
10325 }
10326
10327 if (safi == SAFI_EVPN &&
10328 bgp_evpn_is_esi_valid(&attr->esi)) {
10329 route_vty_out_detail_es_info(vty, path, attr, json_path);
10330 }
10331
10332 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10333 * Int/Ext/Local, Atomic, best */
10334 if (json_paths)
10335 json_object_string_add(json_path, "origin",
10336 bgp_origin_long_str[attr->origin]);
10337 else
10338 vty_out(vty, " Origin %s",
10339 bgp_origin_long_str[attr->origin]);
10340
10341 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10342 if (json_paths)
10343 json_object_int_add(json_path, "metric", attr->med);
10344 else
10345 vty_out(vty, ", metric %u", attr->med);
10346 }
10347
10348 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10349 if (json_paths)
10350 json_object_int_add(json_path, "locPrf",
10351 attr->local_pref);
10352 else
10353 vty_out(vty, ", localpref %u", attr->local_pref);
10354 }
10355
10356 if (attr->weight != 0) {
10357 if (json_paths)
10358 json_object_int_add(json_path, "weight", attr->weight);
10359 else
10360 vty_out(vty, ", weight %u", attr->weight);
10361 }
10362
10363 if (attr->tag != 0) {
10364 if (json_paths)
10365 json_object_int_add(json_path, "tag", attr->tag);
10366 else
10367 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10368 }
10369
10370 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10371 if (json_paths)
10372 json_object_boolean_false_add(json_path, "valid");
10373 else
10374 vty_out(vty, ", invalid");
10375 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10376 if (json_paths)
10377 json_object_boolean_true_add(json_path, "valid");
10378 else
10379 vty_out(vty, ", valid");
10380 }
10381
10382 if (json_paths)
10383 json_object_int_add(json_path, "version", bn->version);
10384
10385 if (path->peer != bgp->peer_self) {
10386 if (path->peer->as == path->peer->local_as) {
10387 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10388 if (json_paths)
10389 json_object_string_add(
10390 json_peer, "type",
10391 "confed-internal");
10392 else
10393 vty_out(vty, ", confed-internal");
10394 } else {
10395 if (json_paths)
10396 json_object_string_add(
10397 json_peer, "type", "internal");
10398 else
10399 vty_out(vty, ", internal");
10400 }
10401 } else {
10402 if (bgp_confederation_peers_check(bgp,
10403 path->peer->as)) {
10404 if (json_paths)
10405 json_object_string_add(
10406 json_peer, "type",
10407 "confed-external");
10408 else
10409 vty_out(vty, ", confed-external");
10410 } else {
10411 if (json_paths)
10412 json_object_string_add(
10413 json_peer, "type", "external");
10414 else
10415 vty_out(vty, ", external");
10416 }
10417 }
10418 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10419 if (json_paths) {
10420 json_object_boolean_true_add(json_path, "aggregated");
10421 json_object_boolean_true_add(json_path, "local");
10422 } else {
10423 vty_out(vty, ", aggregated, local");
10424 }
10425 } else if (path->type != ZEBRA_ROUTE_BGP) {
10426 if (json_paths)
10427 json_object_boolean_true_add(json_path, "sourced");
10428 else
10429 vty_out(vty, ", sourced");
10430 } else {
10431 if (json_paths) {
10432 json_object_boolean_true_add(json_path, "sourced");
10433 json_object_boolean_true_add(json_path, "local");
10434 } else {
10435 vty_out(vty, ", sourced, local");
10436 }
10437 }
10438
10439 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10440 if (json_paths)
10441 json_object_boolean_true_add(json_path,
10442 "atomicAggregate");
10443 else
10444 vty_out(vty, ", atomic-aggregate");
10445 }
10446
10447 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10448 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10449 && bgp_path_info_mpath_count(path))) {
10450 if (json_paths)
10451 json_object_boolean_true_add(json_path, "multipath");
10452 else
10453 vty_out(vty, ", multipath");
10454 }
10455
10456 // Mark the bestpath(s)
10457 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10458 first_as = aspath_get_first_as(attr->aspath);
10459
10460 if (json_paths) {
10461 if (!json_bestpath)
10462 json_bestpath = json_object_new_object();
10463 json_object_int_add(json_bestpath, "bestpathFromAs",
10464 first_as);
10465 } else {
10466 if (first_as)
10467 vty_out(vty, ", bestpath-from-AS %u", first_as);
10468 else
10469 vty_out(vty, ", bestpath-from-AS Local");
10470 }
10471 }
10472
10473 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10474 if (json_paths) {
10475 if (!json_bestpath)
10476 json_bestpath = json_object_new_object();
10477 json_object_boolean_true_add(json_bestpath, "overall");
10478 json_object_string_add(
10479 json_bestpath, "selectionReason",
10480 bgp_path_selection_reason2str(bn->reason));
10481 } else {
10482 vty_out(vty, ", best");
10483 vty_out(vty, " (%s)",
10484 bgp_path_selection_reason2str(bn->reason));
10485 }
10486 }
10487
10488 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10489 if (json_paths)
10490 json_object_string_add(
10491 json_path, "rpkiValidationState",
10492 bgp_rpki_validation2str(rpki_curr_state));
10493 else
10494 vty_out(vty, ", rpki validation-state: %s",
10495 bgp_rpki_validation2str(rpki_curr_state));
10496 }
10497
10498 if (json_bestpath)
10499 json_object_object_add(json_path, "bestpath", json_bestpath);
10500
10501 if (!json_paths)
10502 vty_out(vty, "\n");
10503
10504 /* Line 4 display Community */
10505 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10506 if (json_paths) {
10507 if (!bgp_attr_get_community(attr)->json)
10508 community_str(bgp_attr_get_community(attr),
10509 true);
10510 json_object_lock(bgp_attr_get_community(attr)->json);
10511 json_object_object_add(
10512 json_path, "community",
10513 bgp_attr_get_community(attr)->json);
10514 } else {
10515 vty_out(vty, " Community: %s\n",
10516 bgp_attr_get_community(attr)->str);
10517 }
10518 }
10519
10520 /* Line 5 display Extended-community */
10521 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10522 if (json_paths) {
10523 json_ext_community = json_object_new_object();
10524 json_object_string_add(
10525 json_ext_community, "string",
10526 bgp_attr_get_ecommunity(attr)->str);
10527 json_object_object_add(json_path, "extendedCommunity",
10528 json_ext_community);
10529 } else {
10530 vty_out(vty, " Extended Community: %s\n",
10531 bgp_attr_get_ecommunity(attr)->str);
10532 }
10533 }
10534
10535 /* Line 6 display Large community */
10536 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10537 if (json_paths) {
10538 if (!bgp_attr_get_lcommunity(attr)->json)
10539 lcommunity_str(bgp_attr_get_lcommunity(attr),
10540 true);
10541 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10542 json_object_object_add(
10543 json_path, "largeCommunity",
10544 bgp_attr_get_lcommunity(attr)->json);
10545 } else {
10546 vty_out(vty, " Large Community: %s\n",
10547 bgp_attr_get_lcommunity(attr)->str);
10548 }
10549 }
10550
10551 /* Line 7 display Originator, Cluster-id */
10552 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10553 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10554 char buf[BUFSIZ] = {0};
10555
10556 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10557 if (json_paths)
10558 json_object_string_addf(json_path,
10559 "originatorId", "%pI4",
10560 &attr->originator_id);
10561 else
10562 vty_out(vty, " Originator: %pI4",
10563 &attr->originator_id);
10564 }
10565
10566 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10567 struct cluster_list *cluster =
10568 bgp_attr_get_cluster(attr);
10569 int i;
10570
10571 if (json_paths) {
10572 json_cluster_list = json_object_new_object();
10573 json_cluster_list_list =
10574 json_object_new_array();
10575
10576 for (i = 0; i < cluster->length / 4; i++) {
10577 json_string = json_object_new_string(
10578 inet_ntop(AF_INET,
10579 &cluster->list[i],
10580 buf, sizeof(buf)));
10581 json_object_array_add(
10582 json_cluster_list_list,
10583 json_string);
10584 }
10585
10586 /*
10587 * struct cluster_list does not have
10588 * "str" variable like aspath and community
10589 * do. Add this someday if someone asks
10590 * for it.
10591 * json_object_string_add(json_cluster_list,
10592 * "string", cluster->str);
10593 */
10594 json_object_object_add(json_cluster_list,
10595 "list",
10596 json_cluster_list_list);
10597 json_object_object_add(json_path, "clusterList",
10598 json_cluster_list);
10599 } else {
10600 vty_out(vty, ", Cluster list: ");
10601
10602 for (i = 0; i < cluster->length / 4; i++) {
10603 vty_out(vty, "%pI4 ",
10604 &cluster->list[i]);
10605 }
10606 }
10607 }
10608
10609 if (!json_paths)
10610 vty_out(vty, "\n");
10611 }
10612
10613 if (path->extra && path->extra->damp_info)
10614 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10615
10616 /* Remote Label */
10617 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10618 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10619 mpls_label_t label = label_pton(&path->extra->label[0]);
10620
10621 if (json_paths)
10622 json_object_int_add(json_path, "remoteLabel", label);
10623 else
10624 vty_out(vty, " Remote label: %d\n", label);
10625 }
10626
10627 /* Remote SID */
10628 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10629 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
10630 if (json_paths)
10631 json_object_string_add(json_path, "remoteSid", buf);
10632 else
10633 vty_out(vty, " Remote SID: %s\n", buf);
10634 }
10635
10636 /* Label Index */
10637 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10638 if (json_paths)
10639 json_object_int_add(json_path, "labelIndex",
10640 attr->label_index);
10641 else
10642 vty_out(vty, " Label Index: %d\n",
10643 attr->label_index);
10644 }
10645
10646 /* Line 8 display Addpath IDs */
10647 if (path->addpath_rx_id
10648 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10649 if (json_paths) {
10650 json_object_int_add(json_path, "addpathRxId",
10651 path->addpath_rx_id);
10652
10653 /* Keep backwards compatibility with the old API
10654 * by putting TX All's ID in the old field
10655 */
10656 json_object_int_add(
10657 json_path, "addpathTxId",
10658 path->tx_addpath
10659 .addpath_tx_id[BGP_ADDPATH_ALL]);
10660
10661 /* ... but create a specific field for each
10662 * strategy
10663 */
10664 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10665 json_object_int_add(
10666 json_path,
10667 bgp_addpath_names(i)->id_json_name,
10668 path->tx_addpath.addpath_tx_id[i]);
10669 }
10670 } else {
10671 vty_out(vty, " AddPath ID: RX %u, ",
10672 path->addpath_rx_id);
10673
10674 route_vty_out_tx_ids(vty, &path->tx_addpath);
10675 }
10676 }
10677
10678 /* If we used addpath to TX a non-bestpath we need to display
10679 * "Advertised to" on a path-by-path basis
10680 */
10681 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10682 first = 1;
10683
10684 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10685 addpath_capable =
10686 bgp_addpath_encode_tx(peer, afi, safi);
10687 has_adj = bgp_adj_out_lookup(
10688 peer, path->net,
10689 bgp_addpath_id_for_peer(peer, afi, safi,
10690 &path->tx_addpath));
10691
10692 if ((addpath_capable && has_adj)
10693 || (!addpath_capable && has_adj
10694 && CHECK_FLAG(path->flags,
10695 BGP_PATH_SELECTED))) {
10696 if (json_path && !json_adv_to)
10697 json_adv_to = json_object_new_object();
10698
10699 route_vty_out_advertised_to(
10700 vty, peer, &first,
10701 " Advertised to:", json_adv_to);
10702 }
10703 }
10704
10705 if (json_path) {
10706 if (json_adv_to) {
10707 json_object_object_add(
10708 json_path, "advertisedTo", json_adv_to);
10709 }
10710 } else {
10711 if (!first) {
10712 vty_out(vty, "\n");
10713 }
10714 }
10715 }
10716
10717 /* Line 9 display Uptime */
10718 tbuf = time(NULL) - (bgp_clock() - path->uptime);
10719 if (json_paths) {
10720 json_last_update = json_object_new_object();
10721 json_object_int_add(json_last_update, "epoch", tbuf);
10722 json_object_string_add(json_last_update, "string",
10723 ctime(&tbuf));
10724 json_object_object_add(json_path, "lastUpdate",
10725 json_last_update);
10726 } else
10727 vty_out(vty, " Last update: %s", ctime(&tbuf));
10728
10729 /* Line 10 display PMSI tunnel attribute, if present */
10730 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10731 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10732 bgp_attr_get_pmsi_tnl_type(attr),
10733 PMSI_TNLTYPE_STR_DEFAULT);
10734
10735 if (json_paths) {
10736 json_pmsi = json_object_new_object();
10737 json_object_string_add(json_pmsi, "tunnelType", str);
10738 json_object_int_add(json_pmsi, "label",
10739 label2vni(&attr->label));
10740 json_object_object_add(json_path, "pmsi", json_pmsi);
10741 } else
10742 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10743 str, label2vni(&attr->label));
10744 }
10745
10746 if (path->peer->t_gr_restart &&
10747 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10748 unsigned long gr_remaining =
10749 thread_timer_remain_second(path->peer->t_gr_restart);
10750
10751 if (json_paths) {
10752 json_object_int_add(json_path,
10753 "gracefulRestartSecondsRemaining",
10754 gr_remaining);
10755 } else
10756 vty_out(vty,
10757 " Time until Graceful Restart stale route deleted: %lu\n",
10758 gr_remaining);
10759 }
10760
10761 if (path->peer->t_llgr_stale[afi][safi] &&
10762 bgp_attr_get_community(attr) &&
10763 community_include(bgp_attr_get_community(attr),
10764 COMMUNITY_LLGR_STALE)) {
10765 unsigned long llgr_remaining = thread_timer_remain_second(
10766 path->peer->t_llgr_stale[afi][safi]);
10767
10768 if (json_paths) {
10769 json_object_int_add(json_path, "llgrSecondsRemaining",
10770 llgr_remaining);
10771 } else
10772 vty_out(vty,
10773 " Time until Long-lived stale route deleted: %lu\n",
10774 llgr_remaining);
10775 }
10776
10777 /* Output some debug about internal state of the dest flags */
10778 if (json_paths) {
10779 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10780 json_object_boolean_true_add(json_path, "processScheduled");
10781 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10782 json_object_boolean_true_add(json_path, "userCleared");
10783 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10784 json_object_boolean_true_add(json_path, "labelChanged");
10785 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10786 json_object_boolean_true_add(json_path, "registeredForLabel");
10787 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10788 json_object_boolean_true_add(json_path, "selectDefered");
10789 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10790 json_object_boolean_true_add(json_path, "fibInstalled");
10791 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10792 json_object_boolean_true_add(json_path, "fibPending");
10793
10794 if (json_nexthop_global || json_nexthop_ll) {
10795 json_nexthops = json_object_new_array();
10796
10797 if (json_nexthop_global)
10798 json_object_array_add(json_nexthops,
10799 json_nexthop_global);
10800
10801 if (json_nexthop_ll)
10802 json_object_array_add(json_nexthops,
10803 json_nexthop_ll);
10804
10805 json_object_object_add(json_path, "nexthops",
10806 json_nexthops);
10807 }
10808
10809 json_object_object_add(json_path, "peer", json_peer);
10810 json_object_array_add(json_paths, json_path);
10811 }
10812 }
10813
10814 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10815 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10816 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10817
10818 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10819 afi_t afi, safi_t safi, enum bgp_show_type type,
10820 bool use_json);
10821 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10822 const char *comstr, int exact, afi_t afi,
10823 safi_t safi, uint16_t show_flags);
10824
10825 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10826 struct bgp_table *table, enum bgp_show_type type,
10827 void *output_arg, const char *rd, int is_last,
10828 unsigned long *output_cum, unsigned long *total_cum,
10829 unsigned long *json_header_depth, uint16_t show_flags,
10830 enum rpki_states rpki_target_state)
10831 {
10832 struct bgp_path_info *pi;
10833 struct bgp_dest *dest;
10834 bool header = true;
10835 bool json_detail_header = false;
10836 int display;
10837 unsigned long output_count = 0;
10838 unsigned long total_count = 0;
10839 struct prefix *p;
10840 json_object *json_paths = NULL;
10841 int first = 1;
10842 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10843 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10844 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10845
10846 if (output_cum && *output_cum != 0)
10847 header = false;
10848
10849 if (use_json && !*json_header_depth) {
10850 if (all)
10851 *json_header_depth = 1;
10852 else {
10853 vty_out(vty, "{\n");
10854 *json_header_depth = 2;
10855 }
10856
10857 vty_out(vty,
10858 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10859 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10860 " \"localAS\": %u,\n \"routes\": { ",
10861 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10862 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
10863 ? VRF_DEFAULT_NAME
10864 : bgp->name,
10865 table->version, &bgp->router_id,
10866 bgp->default_local_pref, bgp->as);
10867 if (rd) {
10868 vty_out(vty, " \"routeDistinguishers\" : {");
10869 ++*json_header_depth;
10870 }
10871 }
10872
10873 if (use_json && rd) {
10874 vty_out(vty, " \"%s\" : { ", rd);
10875 }
10876
10877 /* Check for 'json detail', where we need header output once per dest */
10878 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
10879 type != bgp_show_type_dampend_paths &&
10880 type != bgp_show_type_damp_neighbor &&
10881 type != bgp_show_type_flap_statistics &&
10882 type != bgp_show_type_flap_neighbor)
10883 json_detail_header = true;
10884
10885 /* Start processing of routes. */
10886 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
10887 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10888 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
10889 bool json_detail = json_detail_header;
10890
10891 pi = bgp_dest_get_bgp_path_info(dest);
10892 if (pi == NULL)
10893 continue;
10894
10895 display = 0;
10896 if (use_json)
10897 json_paths = json_object_new_array();
10898 else
10899 json_paths = NULL;
10900
10901 for (; pi; pi = pi->next) {
10902 struct community *picomm = NULL;
10903
10904 picomm = bgp_attr_get_community(pi->attr);
10905
10906 total_count++;
10907
10908 if (type == bgp_show_type_prefix_version) {
10909 uint32_t version =
10910 strtoul(output_arg, NULL, 10);
10911 if (dest->version < version)
10912 continue;
10913 }
10914
10915 if (type == bgp_show_type_community_alias) {
10916 char *alias = output_arg;
10917 char **communities;
10918 int num;
10919 bool found = false;
10920
10921 if (picomm) {
10922 frrstr_split(picomm->str, " ",
10923 &communities, &num);
10924 for (int i = 0; i < num; i++) {
10925 const char *com2alias =
10926 bgp_community2alias(
10927 communities[i]);
10928 if (!found
10929 && strcmp(alias, com2alias)
10930 == 0)
10931 found = true;
10932 XFREE(MTYPE_TMP,
10933 communities[i]);
10934 }
10935 XFREE(MTYPE_TMP, communities);
10936 }
10937
10938 if (!found &&
10939 bgp_attr_get_lcommunity(pi->attr)) {
10940 frrstr_split(bgp_attr_get_lcommunity(
10941 pi->attr)
10942 ->str,
10943 " ", &communities, &num);
10944 for (int i = 0; i < num; i++) {
10945 const char *com2alias =
10946 bgp_community2alias(
10947 communities[i]);
10948 if (!found
10949 && strcmp(alias, com2alias)
10950 == 0)
10951 found = true;
10952 XFREE(MTYPE_TMP,
10953 communities[i]);
10954 }
10955 XFREE(MTYPE_TMP, communities);
10956 }
10957
10958 if (!found)
10959 continue;
10960 }
10961
10962 if (type == bgp_show_type_rpki) {
10963 if (dest_p->family == AF_INET
10964 || dest_p->family == AF_INET6)
10965 rpki_curr_state = hook_call(
10966 bgp_rpki_prefix_status,
10967 pi->peer, pi->attr, dest_p);
10968 if (rpki_target_state != RPKI_NOT_BEING_USED
10969 && rpki_curr_state != rpki_target_state)
10970 continue;
10971 }
10972
10973 if (type == bgp_show_type_flap_statistics
10974 || type == bgp_show_type_flap_neighbor
10975 || type == bgp_show_type_dampend_paths
10976 || type == bgp_show_type_damp_neighbor) {
10977 if (!(pi->extra && pi->extra->damp_info))
10978 continue;
10979 }
10980 if (type == bgp_show_type_regexp) {
10981 regex_t *regex = output_arg;
10982
10983 if (bgp_regexec(regex, pi->attr->aspath)
10984 == REG_NOMATCH)
10985 continue;
10986 }
10987 if (type == bgp_show_type_prefix_list) {
10988 struct prefix_list *plist = output_arg;
10989
10990 if (prefix_list_apply(plist, dest_p)
10991 != PREFIX_PERMIT)
10992 continue;
10993 }
10994 if (type == bgp_show_type_filter_list) {
10995 struct as_list *as_list = output_arg;
10996
10997 if (as_list_apply(as_list, pi->attr->aspath)
10998 != AS_FILTER_PERMIT)
10999 continue;
11000 }
11001 if (type == bgp_show_type_route_map) {
11002 struct route_map *rmap = output_arg;
11003 struct bgp_path_info path;
11004 struct attr dummy_attr;
11005 route_map_result_t ret;
11006
11007 dummy_attr = *pi->attr;
11008
11009 path.peer = pi->peer;
11010 path.attr = &dummy_attr;
11011
11012 ret = route_map_apply(rmap, dest_p, &path);
11013 bgp_attr_flush(&dummy_attr);
11014 if (ret == RMAP_DENYMATCH)
11015 continue;
11016 }
11017 if (type == bgp_show_type_neighbor
11018 || type == bgp_show_type_flap_neighbor
11019 || type == bgp_show_type_damp_neighbor) {
11020 union sockunion *su = output_arg;
11021
11022 if (pi->peer == NULL
11023 || pi->peer->su_remote == NULL
11024 || !sockunion_same(pi->peer->su_remote, su))
11025 continue;
11026 }
11027 if (type == bgp_show_type_cidr_only) {
11028 uint32_t destination;
11029
11030 destination = ntohl(dest_p->u.prefix4.s_addr);
11031 if (IN_CLASSC(destination)
11032 && dest_p->prefixlen == 24)
11033 continue;
11034 if (IN_CLASSB(destination)
11035 && dest_p->prefixlen == 16)
11036 continue;
11037 if (IN_CLASSA(destination)
11038 && dest_p->prefixlen == 8)
11039 continue;
11040 }
11041 if (type == bgp_show_type_prefix_longer) {
11042 p = output_arg;
11043 if (!prefix_match(p, dest_p))
11044 continue;
11045 }
11046 if (type == bgp_show_type_community_all) {
11047 if (!picomm)
11048 continue;
11049 }
11050 if (type == bgp_show_type_community) {
11051 struct community *com = output_arg;
11052
11053 if (!picomm || !community_match(picomm, com))
11054 continue;
11055 }
11056 if (type == bgp_show_type_community_exact) {
11057 struct community *com = output_arg;
11058
11059 if (!picomm || !community_cmp(picomm, com))
11060 continue;
11061 }
11062 if (type == bgp_show_type_community_list) {
11063 struct community_list *list = output_arg;
11064
11065 if (!community_list_match(picomm, list))
11066 continue;
11067 }
11068 if (type == bgp_show_type_community_list_exact) {
11069 struct community_list *list = output_arg;
11070
11071 if (!community_list_exact_match(picomm, list))
11072 continue;
11073 }
11074 if (type == bgp_show_type_lcommunity) {
11075 struct lcommunity *lcom = output_arg;
11076
11077 if (!bgp_attr_get_lcommunity(pi->attr) ||
11078 !lcommunity_match(
11079 bgp_attr_get_lcommunity(pi->attr),
11080 lcom))
11081 continue;
11082 }
11083
11084 if (type == bgp_show_type_lcommunity_exact) {
11085 struct lcommunity *lcom = output_arg;
11086
11087 if (!bgp_attr_get_lcommunity(pi->attr) ||
11088 !lcommunity_cmp(
11089 bgp_attr_get_lcommunity(pi->attr),
11090 lcom))
11091 continue;
11092 }
11093 if (type == bgp_show_type_lcommunity_list) {
11094 struct community_list *list = output_arg;
11095
11096 if (!lcommunity_list_match(
11097 bgp_attr_get_lcommunity(pi->attr),
11098 list))
11099 continue;
11100 }
11101 if (type
11102 == bgp_show_type_lcommunity_list_exact) {
11103 struct community_list *list = output_arg;
11104
11105 if (!lcommunity_list_exact_match(
11106 bgp_attr_get_lcommunity(pi->attr),
11107 list))
11108 continue;
11109 }
11110 if (type == bgp_show_type_lcommunity_all) {
11111 if (!bgp_attr_get_lcommunity(pi->attr))
11112 continue;
11113 }
11114 if (type == bgp_show_type_dampend_paths
11115 || type == bgp_show_type_damp_neighbor) {
11116 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11117 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11118 continue;
11119 }
11120
11121 if (!use_json && header) {
11122 vty_out(vty,
11123 "BGP table version is %" PRIu64
11124 ", local router ID is %pI4, vrf id ",
11125 table->version, &bgp->router_id);
11126 if (bgp->vrf_id == VRF_UNKNOWN)
11127 vty_out(vty, "%s", VRFID_NONE_STR);
11128 else
11129 vty_out(vty, "%u", bgp->vrf_id);
11130 vty_out(vty, "\n");
11131 vty_out(vty, "Default local pref %u, ",
11132 bgp->default_local_pref);
11133 vty_out(vty, "local AS %u\n", bgp->as);
11134 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11135 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11136 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11137 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11138 if (type == bgp_show_type_dampend_paths
11139 || type == bgp_show_type_damp_neighbor)
11140 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11141 else if (type == bgp_show_type_flap_statistics
11142 || type == bgp_show_type_flap_neighbor)
11143 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11144 else
11145 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11146 : BGP_SHOW_HEADER));
11147 header = false;
11148
11149 } else if (json_detail && json_paths != NULL) {
11150 const struct prefix_rd *prd;
11151 json_object *jtemp;
11152
11153 /* Use common detail header, for most types;
11154 * need a json 'object'.
11155 */
11156
11157 jtemp = json_object_new_object();
11158 prd = bgp_rd_from_dest(dest, safi);
11159
11160 route_vty_out_detail_header(
11161 vty, bgp, dest, prd, table->afi,
11162 safi, jtemp);
11163
11164 json_object_array_add(json_paths, jtemp);
11165
11166 json_detail = false;
11167 }
11168
11169 if (rd != NULL && !display && !output_count) {
11170 if (!use_json)
11171 vty_out(vty,
11172 "Route Distinguisher: %s\n",
11173 rd);
11174 }
11175 if (type == bgp_show_type_dampend_paths
11176 || type == bgp_show_type_damp_neighbor)
11177 damp_route_vty_out(vty, dest_p, pi, display,
11178 AFI_IP, safi, use_json,
11179 json_paths);
11180 else if (type == bgp_show_type_flap_statistics
11181 || type == bgp_show_type_flap_neighbor)
11182 flap_route_vty_out(vty, dest_p, pi, display,
11183 AFI_IP, safi, use_json,
11184 json_paths);
11185 else {
11186 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11187 route_vty_out_detail(
11188 vty, bgp, dest, pi,
11189 family2afi(dest_p->family),
11190 safi, RPKI_NOT_BEING_USED,
11191 json_paths);
11192 else
11193 route_vty_out(vty, dest_p, pi, display,
11194 safi, json_paths, wide);
11195 }
11196 display++;
11197 }
11198
11199 if (display) {
11200 output_count++;
11201 if (!use_json)
11202 continue;
11203
11204 /* encode prefix */
11205 if (dest_p->family == AF_FLOWSPEC) {
11206 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11207
11208
11209 bgp_fs_nlri_get_string(
11210 (unsigned char *)
11211 dest_p->u.prefix_flowspec.ptr,
11212 dest_p->u.prefix_flowspec.prefixlen,
11213 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11214 family2afi(dest_p->u
11215 .prefix_flowspec.family));
11216 if (first)
11217 vty_out(vty, "\"%s/%d\": ", retstr,
11218 dest_p->u.prefix_flowspec
11219 .prefixlen);
11220 else
11221 vty_out(vty, ",\"%s/%d\": ", retstr,
11222 dest_p->u.prefix_flowspec
11223 .prefixlen);
11224 } else {
11225 if (first)
11226 vty_out(vty, "\"%pFX\": ", dest_p);
11227 else
11228 vty_out(vty, ",\"%pFX\": ", dest_p);
11229 }
11230 vty_json(vty, json_paths);
11231 json_paths = NULL;
11232 first = 0;
11233 } else
11234 json_object_free(json_paths);
11235 }
11236
11237 if (output_cum) {
11238 output_count += *output_cum;
11239 *output_cum = output_count;
11240 }
11241 if (total_cum) {
11242 total_count += *total_cum;
11243 *total_cum = total_count;
11244 }
11245 if (use_json) {
11246 if (rd) {
11247 vty_out(vty, " }%s ", (is_last ? "" : ","));
11248 }
11249 if (is_last) {
11250 unsigned long i;
11251 for (i = 0; i < *json_header_depth; ++i)
11252 vty_out(vty, " } ");
11253 if (!all)
11254 vty_out(vty, "\n");
11255 }
11256 } else {
11257 if (is_last) {
11258 /* No route is displayed */
11259 if (output_count == 0) {
11260 if (type == bgp_show_type_normal)
11261 vty_out(vty,
11262 "No BGP prefixes displayed, %ld exist\n",
11263 total_count);
11264 } else
11265 vty_out(vty,
11266 "\nDisplayed %ld routes and %ld total paths\n",
11267 output_count, total_count);
11268 }
11269 }
11270
11271 return CMD_SUCCESS;
11272 }
11273
11274 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11275 struct bgp_table *table, struct prefix_rd *prd_match,
11276 enum bgp_show_type type, void *output_arg, bool use_json)
11277 {
11278 struct bgp_dest *dest, *next;
11279 unsigned long output_cum = 0;
11280 unsigned long total_cum = 0;
11281 unsigned long json_header_depth = 0;
11282 struct bgp_table *itable;
11283 bool show_msg;
11284 uint16_t show_flags = 0;
11285
11286 show_msg = (!use_json && type == bgp_show_type_normal);
11287
11288 if (use_json)
11289 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11290
11291 for (dest = bgp_table_top(table); dest; dest = next) {
11292 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11293
11294 next = bgp_route_next(dest);
11295 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11296 continue;
11297
11298 itable = bgp_dest_get_bgp_table_info(dest);
11299 if (itable != NULL) {
11300 struct prefix_rd prd;
11301 char rd[RD_ADDRSTRLEN];
11302
11303 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11304 prefix_rd2str(&prd, rd, sizeof(rd));
11305 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11306 rd, next == NULL, &output_cum,
11307 &total_cum, &json_header_depth,
11308 show_flags, RPKI_NOT_BEING_USED);
11309 if (next == NULL)
11310 show_msg = false;
11311 }
11312 }
11313 if (show_msg) {
11314 if (output_cum == 0)
11315 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11316 total_cum);
11317 else
11318 vty_out(vty,
11319 "\nDisplayed %ld routes and %ld total paths\n",
11320 output_cum, total_cum);
11321 }
11322 return CMD_SUCCESS;
11323 }
11324
11325 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11326 enum bgp_show_type type, void *output_arg,
11327 uint16_t show_flags, enum rpki_states rpki_target_state)
11328 {
11329 struct bgp_table *table;
11330 unsigned long json_header_depth = 0;
11331 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11332
11333 if (bgp == NULL) {
11334 bgp = bgp_get_default();
11335 }
11336
11337 if (bgp == NULL) {
11338 if (!use_json)
11339 vty_out(vty, "No BGP process is configured\n");
11340 else
11341 vty_out(vty, "{}\n");
11342 return CMD_WARNING;
11343 }
11344
11345 /* Labeled-unicast routes live in the unicast table. */
11346 if (safi == SAFI_LABELED_UNICAST)
11347 safi = SAFI_UNICAST;
11348
11349 table = bgp->rib[afi][safi];
11350 /* use MPLS and ENCAP specific shows until they are merged */
11351 if (safi == SAFI_MPLS_VPN) {
11352 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11353 output_arg, use_json);
11354 }
11355
11356 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11357 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11358 output_arg, use_json,
11359 1, NULL, NULL);
11360 }
11361
11362 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11363 NULL, NULL, &json_header_depth, show_flags,
11364 rpki_target_state);
11365 }
11366
11367 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11368 safi_t safi, uint16_t show_flags)
11369 {
11370 struct listnode *node, *nnode;
11371 struct bgp *bgp;
11372 int is_first = 1;
11373 bool route_output = false;
11374 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11375
11376 if (use_json)
11377 vty_out(vty, "{\n");
11378
11379 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11380 route_output = true;
11381 if (use_json) {
11382 if (!is_first)
11383 vty_out(vty, ",\n");
11384 else
11385 is_first = 0;
11386
11387 vty_out(vty, "\"%s\":",
11388 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11389 ? VRF_DEFAULT_NAME
11390 : bgp->name);
11391 } else {
11392 vty_out(vty, "\nInstance %s:\n",
11393 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11394 ? VRF_DEFAULT_NAME
11395 : bgp->name);
11396 }
11397 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11398 show_flags, RPKI_NOT_BEING_USED);
11399 }
11400
11401 if (use_json)
11402 vty_out(vty, "}\n");
11403 else if (!route_output)
11404 vty_out(vty, "%% BGP instance not found\n");
11405 }
11406
11407 /* Header of detailed BGP route information */
11408 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11409 struct bgp_dest *dest,
11410 const struct prefix_rd *prd,
11411 afi_t afi, safi_t safi, json_object *json)
11412 {
11413 struct bgp_path_info *pi;
11414 const struct prefix *p;
11415 struct peer *peer;
11416 struct listnode *node, *nnode;
11417 char buf1[RD_ADDRSTRLEN];
11418 int count = 0;
11419 int best = 0;
11420 int suppress = 0;
11421 int accept_own = 0;
11422 int route_filter_translated_v4 = 0;
11423 int route_filter_v4 = 0;
11424 int route_filter_translated_v6 = 0;
11425 int route_filter_v6 = 0;
11426 int llgr_stale = 0;
11427 int no_llgr = 0;
11428 int accept_own_nexthop = 0;
11429 int blackhole = 0;
11430 int no_export = 0;
11431 int no_advertise = 0;
11432 int local_as = 0;
11433 int no_peer = 0;
11434 int first = 1;
11435 int has_valid_label = 0;
11436 mpls_label_t label = 0;
11437 json_object *json_adv_to = NULL;
11438
11439 p = bgp_dest_get_prefix(dest);
11440 has_valid_label = bgp_is_valid_label(&dest->local_label);
11441
11442 if (has_valid_label)
11443 label = label_pton(&dest->local_label);
11444
11445 if (safi == SAFI_EVPN) {
11446
11447 if (!json) {
11448 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11449 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11450 : "",
11451 prd ? ":" : "", (struct prefix_evpn *)p);
11452 } else {
11453 json_object_string_add(json, "rd",
11454 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11455 "");
11456 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11457 }
11458 } else {
11459 if (!json) {
11460 vty_out(vty,
11461 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11462 "\n",
11463 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11464 ? prefix_rd2str(prd, buf1,
11465 sizeof(buf1))
11466 : ""),
11467 safi == SAFI_MPLS_VPN ? ":" : "", p,
11468 dest->version);
11469
11470 } else {
11471 json_object_string_addf(json, "prefix", "%pFX", p);
11472 json_object_int_add(json, "version", dest->version);
11473
11474 }
11475 }
11476
11477 if (has_valid_label) {
11478 if (json)
11479 json_object_int_add(json, "localLabel", label);
11480 else
11481 vty_out(vty, "Local label: %d\n", label);
11482 }
11483
11484 if (!json)
11485 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11486 vty_out(vty, "not allocated\n");
11487
11488 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11489 struct community *picomm = NULL;
11490
11491 picomm = bgp_attr_get_community(pi->attr);
11492
11493 count++;
11494 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11495 best = count;
11496 if (bgp_path_suppressed(pi))
11497 suppress = 1;
11498
11499 if (!picomm)
11500 continue;
11501
11502 no_advertise += community_include(
11503 picomm, COMMUNITY_NO_ADVERTISE);
11504 no_export +=
11505 community_include(picomm, COMMUNITY_NO_EXPORT);
11506 local_as +=
11507 community_include(picomm, COMMUNITY_LOCAL_AS);
11508 accept_own +=
11509 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11510 route_filter_translated_v4 += community_include(
11511 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11512 route_filter_translated_v6 += community_include(
11513 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11514 route_filter_v4 += community_include(
11515 picomm, COMMUNITY_ROUTE_FILTER_v4);
11516 route_filter_v6 += community_include(
11517 picomm, COMMUNITY_ROUTE_FILTER_v6);
11518 llgr_stale +=
11519 community_include(picomm, COMMUNITY_LLGR_STALE);
11520 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11521 accept_own_nexthop += community_include(
11522 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11523 blackhole +=
11524 community_include(picomm, COMMUNITY_BLACKHOLE);
11525 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11526 }
11527 }
11528
11529 if (!json) {
11530 vty_out(vty, "Paths: (%d available", count);
11531 if (best) {
11532 vty_out(vty, ", best #%d", best);
11533 if (safi == SAFI_UNICAST) {
11534 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11535 vty_out(vty, ", table %s",
11536 VRF_DEFAULT_NAME);
11537 else
11538 vty_out(vty, ", vrf %s",
11539 bgp->name);
11540 }
11541 } else
11542 vty_out(vty, ", no best path");
11543
11544 if (accept_own)
11545 vty_out(vty,
11546 ", accept own local route exported and imported in different VRF");
11547 else if (route_filter_translated_v4)
11548 vty_out(vty,
11549 ", mark translated RTs for VPNv4 route filtering");
11550 else if (route_filter_v4)
11551 vty_out(vty,
11552 ", attach RT as-is for VPNv4 route filtering");
11553 else if (route_filter_translated_v6)
11554 vty_out(vty,
11555 ", mark translated RTs for VPNv6 route filtering");
11556 else if (route_filter_v6)
11557 vty_out(vty,
11558 ", attach RT as-is for VPNv6 route filtering");
11559 else if (llgr_stale)
11560 vty_out(vty,
11561 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11562 else if (no_llgr)
11563 vty_out(vty,
11564 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11565 else if (accept_own_nexthop)
11566 vty_out(vty,
11567 ", accept local nexthop");
11568 else if (blackhole)
11569 vty_out(vty, ", inform peer to blackhole prefix");
11570 else if (no_export)
11571 vty_out(vty, ", not advertised to EBGP peer");
11572 else if (no_advertise)
11573 vty_out(vty, ", not advertised to any peer");
11574 else if (local_as)
11575 vty_out(vty, ", not advertised outside local AS");
11576 else if (no_peer)
11577 vty_out(vty,
11578 ", inform EBGP peer not to advertise to their EBGP peers");
11579
11580 if (suppress)
11581 vty_out(vty,
11582 ", Advertisements suppressed by an aggregate.");
11583 vty_out(vty, ")\n");
11584 }
11585
11586 /* If we are not using addpath then we can display Advertised to and
11587 * that will
11588 * show what peers we advertised the bestpath to. If we are using
11589 * addpath
11590 * though then we must display Advertised to on a path-by-path basis. */
11591 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11592 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11593 if (bgp_adj_out_lookup(peer, dest, 0)) {
11594 if (json && !json_adv_to)
11595 json_adv_to = json_object_new_object();
11596
11597 route_vty_out_advertised_to(
11598 vty, peer, &first,
11599 " Advertised to non peer-group peers:\n ",
11600 json_adv_to);
11601 }
11602 }
11603
11604 if (json) {
11605 if (json_adv_to) {
11606 json_object_object_add(json, "advertisedTo",
11607 json_adv_to);
11608 }
11609 } else {
11610 if (first)
11611 vty_out(vty, " Not advertised to any peer");
11612 vty_out(vty, "\n");
11613 }
11614 }
11615 }
11616
11617 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11618 struct bgp_dest *bgp_node, struct vty *vty,
11619 struct bgp *bgp, afi_t afi, safi_t safi,
11620 json_object *json, enum bgp_path_type pathtype,
11621 int *display, enum rpki_states rpki_target_state)
11622 {
11623 struct bgp_path_info *pi;
11624 int header = 1;
11625 char rdbuf[RD_ADDRSTRLEN];
11626 json_object *json_header = NULL;
11627 json_object *json_paths = NULL;
11628 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11629
11630 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11631 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11632
11633 if (p->family == AF_INET || p->family == AF_INET6)
11634 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11635 pi->peer, pi->attr, p);
11636
11637 if (rpki_target_state != RPKI_NOT_BEING_USED
11638 && rpki_curr_state != rpki_target_state)
11639 continue;
11640
11641 if (json && !json_paths) {
11642 /* Instantiate json_paths only if path is valid */
11643 json_paths = json_object_new_array();
11644 if (pfx_rd) {
11645 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11646 json_header = json_object_new_object();
11647 } else
11648 json_header = json;
11649 }
11650
11651 if (header) {
11652 route_vty_out_detail_header(
11653 vty, bgp, bgp_node, pfx_rd,
11654 AFI_IP, safi, json_header);
11655 header = 0;
11656 }
11657 (*display)++;
11658
11659 if (pathtype == BGP_PATH_SHOW_ALL
11660 || (pathtype == BGP_PATH_SHOW_BESTPATH
11661 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11662 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11663 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11664 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11665 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
11666 safi, rpki_curr_state, json_paths);
11667 }
11668
11669 if (json && json_paths) {
11670 json_object_object_add(json_header, "paths", json_paths);
11671
11672 if (pfx_rd)
11673 json_object_object_add(json, rdbuf, json_header);
11674 }
11675 }
11676
11677 /*
11678 * Return rd based on safi
11679 */
11680 static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
11681 safi_t safi)
11682 {
11683 switch (safi) {
11684 case SAFI_MPLS_VPN:
11685 case SAFI_ENCAP:
11686 case SAFI_EVPN:
11687 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
11688 default:
11689 return NULL;
11690
11691 }
11692 }
11693
11694 /* Display specified route of BGP table. */
11695 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11696 struct bgp_table *rib, const char *ip_str,
11697 afi_t afi, safi_t safi,
11698 enum rpki_states rpki_target_state,
11699 struct prefix_rd *prd, int prefix_check,
11700 enum bgp_path_type pathtype, bool use_json)
11701 {
11702 int ret;
11703 int display = 0;
11704 struct prefix match;
11705 struct bgp_dest *dest;
11706 struct bgp_dest *rm;
11707 struct bgp_table *table;
11708 json_object *json = NULL;
11709 json_object *json_paths = NULL;
11710
11711 /* Check IP address argument. */
11712 ret = str2prefix(ip_str, &match);
11713 if (!ret) {
11714 vty_out(vty, "address is malformed\n");
11715 return CMD_WARNING;
11716 }
11717
11718 match.family = afi2family(afi);
11719
11720 if (use_json)
11721 json = json_object_new_object();
11722
11723 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11724 for (dest = bgp_table_top(rib); dest;
11725 dest = bgp_route_next(dest)) {
11726 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11727
11728 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11729 continue;
11730 table = bgp_dest_get_bgp_table_info(dest);
11731 if (!table)
11732 continue;
11733
11734 rm = bgp_node_match(table, &match);
11735 if (rm == NULL)
11736 continue;
11737
11738 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11739 if (prefix_check
11740 && rm_p->prefixlen != match.prefixlen) {
11741 bgp_dest_unlock_node(rm);
11742 continue;
11743 }
11744
11745 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11746 bgp, afi, safi, json, pathtype,
11747 &display, rpki_target_state);
11748
11749 bgp_dest_unlock_node(rm);
11750 }
11751 } else if (safi == SAFI_EVPN) {
11752 struct bgp_dest *longest_pfx;
11753 bool is_exact_pfxlen_match = false;
11754
11755 for (dest = bgp_table_top(rib); dest;
11756 dest = bgp_route_next(dest)) {
11757 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11758
11759 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11760 continue;
11761 table = bgp_dest_get_bgp_table_info(dest);
11762 if (!table)
11763 continue;
11764
11765 longest_pfx = NULL;
11766 is_exact_pfxlen_match = false;
11767 /*
11768 * Search through all the prefixes for a match. The
11769 * pfx's are enumerated in ascending order of pfxlens.
11770 * So, the last pfx match is the longest match. Set
11771 * is_exact_pfxlen_match when we get exact pfxlen match
11772 */
11773 for (rm = bgp_table_top(table); rm;
11774 rm = bgp_route_next(rm)) {
11775 const struct prefix *rm_p =
11776 bgp_dest_get_prefix(rm);
11777 /*
11778 * Get prefixlen of the ip-prefix within type5
11779 * evpn route
11780 */
11781 if (evpn_type5_prefix_match(rm_p, &match)
11782 && rm->info) {
11783 longest_pfx = rm;
11784 int type5_pfxlen =
11785 bgp_evpn_get_type5_prefixlen(
11786 rm_p);
11787 if (type5_pfxlen == match.prefixlen) {
11788 is_exact_pfxlen_match = true;
11789 bgp_dest_unlock_node(rm);
11790 break;
11791 }
11792 }
11793 }
11794
11795 if (!longest_pfx)
11796 continue;
11797
11798 if (prefix_check && !is_exact_pfxlen_match)
11799 continue;
11800
11801 rm = longest_pfx;
11802 bgp_dest_lock_node(rm);
11803
11804 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11805 bgp, afi, safi, json, pathtype,
11806 &display, rpki_target_state);
11807
11808 bgp_dest_unlock_node(rm);
11809 }
11810 } else if (safi == SAFI_FLOWSPEC) {
11811 if (use_json)
11812 json_paths = json_object_new_array();
11813
11814 display = bgp_flowspec_display_match_per_ip(afi, rib,
11815 &match, prefix_check,
11816 vty,
11817 use_json,
11818 json_paths);
11819 if (use_json) {
11820 if (display)
11821 json_object_object_add(json, "paths",
11822 json_paths);
11823 else
11824 json_object_free(json_paths);
11825 }
11826 } else {
11827 dest = bgp_node_match(rib, &match);
11828 if (dest != NULL) {
11829 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11830 if (!prefix_check
11831 || dest_p->prefixlen == match.prefixlen) {
11832 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11833 safi, json, pathtype,
11834 &display, rpki_target_state);
11835 }
11836
11837 bgp_dest_unlock_node(dest);
11838 }
11839 }
11840
11841 if (use_json) {
11842 vty_json(vty, json);
11843 } else {
11844 if (!display) {
11845 vty_out(vty, "%% Network not in table\n");
11846 return CMD_WARNING;
11847 }
11848 }
11849
11850 return CMD_SUCCESS;
11851 }
11852
11853 /* Display specified route of Main RIB */
11854 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
11855 afi_t afi, safi_t safi, struct prefix_rd *prd,
11856 int prefix_check, enum bgp_path_type pathtype,
11857 enum rpki_states rpki_target_state, bool use_json)
11858 {
11859 if (!bgp) {
11860 bgp = bgp_get_default();
11861 if (!bgp) {
11862 if (!use_json)
11863 vty_out(vty, "No BGP process is configured\n");
11864 else
11865 vty_out(vty, "{}\n");
11866 return CMD_WARNING;
11867 }
11868 }
11869
11870 /* labeled-unicast routes live in the unicast table */
11871 if (safi == SAFI_LABELED_UNICAST)
11872 safi = SAFI_UNICAST;
11873
11874 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
11875 afi, safi, rpki_target_state, prd,
11876 prefix_check, pathtype, use_json);
11877 }
11878
11879 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
11880 struct cmd_token **argv, bool exact, afi_t afi,
11881 safi_t safi, bool uj)
11882 {
11883 struct lcommunity *lcom;
11884 struct buffer *b;
11885 int i;
11886 char *str;
11887 int first = 0;
11888 uint16_t show_flags = 0;
11889 int ret;
11890
11891 if (uj)
11892 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11893
11894 b = buffer_new(1024);
11895 for (i = 0; i < argc; i++) {
11896 if (first)
11897 buffer_putc(b, ' ');
11898 else {
11899 if (strmatch(argv[i]->text, "AA:BB:CC")) {
11900 first = 1;
11901 buffer_putstr(b, argv[i]->arg);
11902 }
11903 }
11904 }
11905 buffer_putc(b, '\0');
11906
11907 str = buffer_getstr(b);
11908 buffer_free(b);
11909
11910 lcom = lcommunity_str2com(str);
11911 XFREE(MTYPE_TMP, str);
11912 if (!lcom) {
11913 vty_out(vty, "%% Large-community malformed\n");
11914 return CMD_WARNING;
11915 }
11916
11917 ret = bgp_show(vty, bgp, afi, safi,
11918 (exact ? bgp_show_type_lcommunity_exact
11919 : bgp_show_type_lcommunity),
11920 lcom, show_flags, RPKI_NOT_BEING_USED);
11921
11922 lcommunity_free(&lcom);
11923 return ret;
11924 }
11925
11926 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
11927 const char *lcom, bool exact, afi_t afi,
11928 safi_t safi, bool uj)
11929 {
11930 struct community_list *list;
11931 uint16_t show_flags = 0;
11932
11933 if (uj)
11934 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11935
11936
11937 list = community_list_lookup(bgp_clist, lcom, 0,
11938 LARGE_COMMUNITY_LIST_MASTER);
11939 if (list == NULL) {
11940 vty_out(vty, "%% %s is not a valid large-community-list name\n",
11941 lcom);
11942 return CMD_WARNING;
11943 }
11944
11945 return bgp_show(vty, bgp, afi, safi,
11946 (exact ? bgp_show_type_lcommunity_list_exact
11947 : bgp_show_type_lcommunity_list),
11948 list, show_flags, RPKI_NOT_BEING_USED);
11949 }
11950
11951 DEFUN (show_ip_bgp_large_community_list,
11952 show_ip_bgp_large_community_list_cmd,
11953 "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]",
11954 SHOW_STR
11955 IP_STR
11956 BGP_STR
11957 BGP_INSTANCE_HELP_STR
11958 BGP_AFI_HELP_STR
11959 BGP_SAFI_WITH_LABEL_HELP_STR
11960 "Display routes matching the large-community-list\n"
11961 "large-community-list number\n"
11962 "large-community-list name\n"
11963 "Exact match of the large-communities\n"
11964 JSON_STR)
11965 {
11966 afi_t afi = AFI_IP6;
11967 safi_t safi = SAFI_UNICAST;
11968 int idx = 0;
11969 bool exact_match = 0;
11970 struct bgp *bgp = NULL;
11971 bool uj = use_json(argc, argv);
11972
11973 if (uj)
11974 argc--;
11975
11976 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11977 &bgp, uj);
11978 if (!idx)
11979 return CMD_WARNING;
11980
11981 argv_find(argv, argc, "large-community-list", &idx);
11982
11983 const char *clist_number_or_name = argv[++idx]->arg;
11984
11985 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11986 exact_match = 1;
11987
11988 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
11989 exact_match, afi, safi, uj);
11990 }
11991 DEFUN (show_ip_bgp_large_community,
11992 show_ip_bgp_large_community_cmd,
11993 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
11994 SHOW_STR
11995 IP_STR
11996 BGP_STR
11997 BGP_INSTANCE_HELP_STR
11998 BGP_AFI_HELP_STR
11999 BGP_SAFI_WITH_LABEL_HELP_STR
12000 "Display routes matching the large-communities\n"
12001 "List of large-community numbers\n"
12002 "Exact match of the large-communities\n"
12003 JSON_STR)
12004 {
12005 afi_t afi = AFI_IP6;
12006 safi_t safi = SAFI_UNICAST;
12007 int idx = 0;
12008 bool exact_match = 0;
12009 struct bgp *bgp = NULL;
12010 bool uj = use_json(argc, argv);
12011 uint16_t show_flags = 0;
12012
12013 if (uj) {
12014 argc--;
12015 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12016 }
12017
12018 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12019 &bgp, uj);
12020 if (!idx)
12021 return CMD_WARNING;
12022
12023 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12024 if (argv_find(argv, argc, "exact-match", &idx))
12025 exact_match = 1;
12026 return bgp_show_lcommunity(vty, bgp, argc, argv,
12027 exact_match, afi, safi, uj);
12028 } else
12029 return bgp_show(vty, bgp, afi, safi,
12030 bgp_show_type_lcommunity_all, NULL, show_flags,
12031 RPKI_NOT_BEING_USED);
12032 }
12033
12034 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12035 safi_t safi, struct json_object *json_array);
12036 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12037 safi_t safi, struct json_object *json);
12038
12039
12040 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12041 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12042 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12043 "Display number of prefixes for all afi/safi\n" JSON_STR)
12044 {
12045 bool uj = use_json(argc, argv);
12046 struct bgp *bgp = NULL;
12047 safi_t safi = SAFI_UNICAST;
12048 afi_t afi = AFI_IP6;
12049 int idx = 0;
12050 struct json_object *json_all = NULL;
12051 struct json_object *json_afi_safi = NULL;
12052
12053 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12054 &bgp, false);
12055 if (!idx)
12056 return CMD_WARNING;
12057
12058 if (uj)
12059 json_all = json_object_new_object();
12060
12061 FOREACH_AFI_SAFI (afi, safi) {
12062 /*
12063 * So limit output to those afi/safi pairs that
12064 * actually have something interesting in them
12065 */
12066 if (strmatch(get_afi_safi_str(afi, safi, true),
12067 "Unknown")) {
12068 continue;
12069 }
12070 if (uj) {
12071 json_afi_safi = json_object_new_array();
12072 json_object_object_add(
12073 json_all,
12074 get_afi_safi_str(afi, safi, true),
12075 json_afi_safi);
12076 } else {
12077 json_afi_safi = NULL;
12078 }
12079
12080 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12081 }
12082
12083 if (uj)
12084 vty_json(vty, json_all);
12085
12086 return CMD_SUCCESS;
12087 }
12088
12089 /* BGP route print out function without JSON */
12090 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12091 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12092 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12093 SHOW_STR
12094 IP_STR
12095 BGP_STR
12096 BGP_INSTANCE_HELP_STR
12097 L2VPN_HELP_STR
12098 EVPN_HELP_STR
12099 "BGP RIB advertisement statistics\n"
12100 JSON_STR)
12101 {
12102 afi_t afi = AFI_IP6;
12103 safi_t safi = SAFI_UNICAST;
12104 struct bgp *bgp = NULL;
12105 int idx = 0, ret;
12106 bool uj = use_json(argc, argv);
12107 struct json_object *json_afi_safi = NULL, *json = NULL;
12108
12109 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12110 &bgp, false);
12111 if (!idx)
12112 return CMD_WARNING;
12113
12114 if (uj)
12115 json_afi_safi = json_object_new_array();
12116 else
12117 json_afi_safi = NULL;
12118
12119 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12120
12121 if (uj) {
12122 json = json_object_new_object();
12123 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12124 json_afi_safi);
12125 vty_json(vty, json);
12126 }
12127 return ret;
12128 }
12129
12130 /* BGP route print out function without JSON */
12131 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12132 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12133 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12134 "]]\
12135 statistics [json]",
12136 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12137 BGP_SAFI_WITH_LABEL_HELP_STR
12138 "BGP RIB advertisement statistics\n" JSON_STR)
12139 {
12140 afi_t afi = AFI_IP6;
12141 safi_t safi = SAFI_UNICAST;
12142 struct bgp *bgp = NULL;
12143 int idx = 0, ret;
12144 bool uj = use_json(argc, argv);
12145 struct json_object *json_afi_safi = NULL, *json = NULL;
12146
12147 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12148 &bgp, false);
12149 if (!idx)
12150 return CMD_WARNING;
12151
12152 if (uj)
12153 json_afi_safi = json_object_new_array();
12154 else
12155 json_afi_safi = NULL;
12156
12157 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12158
12159 if (uj) {
12160 json = json_object_new_object();
12161 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12162 json_afi_safi);
12163 vty_json(vty, json);
12164 }
12165 return ret;
12166 }
12167
12168 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12169 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12170 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12171 "]] [all$all] dampening parameters [json]",
12172 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12173 BGP_SAFI_WITH_LABEL_HELP_STR
12174 "Display the entries for all address families\n"
12175 "Display detailed information about dampening\n"
12176 "Display detail of configured dampening parameters\n"
12177 JSON_STR)
12178 {
12179 afi_t afi = AFI_IP6;
12180 safi_t safi = SAFI_UNICAST;
12181 struct bgp *bgp = NULL;
12182 int idx = 0;
12183 uint16_t show_flags = 0;
12184 bool uj = use_json(argc, argv);
12185
12186 if (uj) {
12187 argc--;
12188 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12189 }
12190
12191 /* [<ipv4|ipv6> [all]] */
12192 if (all) {
12193 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12194 if (argv_find(argv, argc, "ipv4", &idx))
12195 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12196
12197 if (argv_find(argv, argc, "ipv6", &idx))
12198 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12199 }
12200
12201 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12202 &bgp, false);
12203 if (!idx)
12204 return CMD_WARNING;
12205
12206 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12207 }
12208
12209 /* BGP route print out function */
12210 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12211 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12212 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12213 "]]\
12214 [all$all]\
12215 [cidr-only\
12216 |dampening <flap-statistics|dampened-paths>\
12217 |community [AA:NN|local-AS|no-advertise|no-export\
12218 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12219 |accept-own|accept-own-nexthop|route-filter-v6\
12220 |route-filter-v4|route-filter-translated-v6\
12221 |route-filter-translated-v4] [exact-match]\
12222 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12223 |filter-list AS_PATH_FILTER_NAME\
12224 |prefix-list WORD\
12225 |route-map WORD\
12226 |rpki <invalid|valid|notfound>\
12227 |version (1-4294967295)\
12228 |alias ALIAS_NAME\
12229 |A.B.C.D/M longer-prefixes\
12230 |X:X::X:X/M longer-prefixes\
12231 ] [json$uj [detail$detail] | wide$wide]",
12232 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12233 BGP_SAFI_WITH_LABEL_HELP_STR
12234 "Display the entries for all address families\n"
12235 "Display only routes with non-natural netmasks\n"
12236 "Display detailed information about dampening\n"
12237 "Display flap statistics of routes\n"
12238 "Display paths suppressed due to dampening\n"
12239 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12240 "Do not send outside local AS (well-known community)\n"
12241 "Do not advertise to any peer (well-known community)\n"
12242 "Do not export to next AS (well-known community)\n"
12243 "Graceful shutdown (well-known community)\n"
12244 "Do not export to any peer (well-known community)\n"
12245 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12246 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12247 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12248 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12249 "Should accept VPN route with local nexthop (well-known community)\n"
12250 "RT VPNv6 route filtering (well-known community)\n"
12251 "RT VPNv4 route filtering (well-known community)\n"
12252 "RT translated VPNv6 route filtering (well-known community)\n"
12253 "RT translated VPNv4 route filtering (well-known community)\n"
12254 "Exact match of the communities\n"
12255 "Community-list number\n"
12256 "Community-list name\n"
12257 "Display routes matching the community-list\n"
12258 "Exact match of the communities\n"
12259 "Display routes conforming to the filter-list\n"
12260 "Regular expression access list name\n"
12261 "Display routes conforming to the prefix-list\n"
12262 "Prefix-list name\n"
12263 "Display routes matching the route-map\n"
12264 "A route-map to match on\n"
12265 "RPKI route types\n"
12266 "A valid path as determined by rpki\n"
12267 "A invalid path as determined by rpki\n"
12268 "A path that has no rpki data\n"
12269 "Display prefixes with matching version numbers\n"
12270 "Version number and above\n"
12271 "Display prefixes with matching BGP community alias\n"
12272 "BGP community alias\n"
12273 "IPv4 prefix\n"
12274 "Display route and more specific routes\n"
12275 "IPv6 prefix\n"
12276 "Display route and more specific routes\n"
12277 JSON_STR
12278 "Display detailed version of JSON output\n"
12279 "Increase table width for longer prefixes\n")
12280 {
12281 afi_t afi = AFI_IP6;
12282 safi_t safi = SAFI_UNICAST;
12283 enum bgp_show_type sh_type = bgp_show_type_normal;
12284 void *output_arg = NULL;
12285 struct bgp *bgp = NULL;
12286 int idx = 0;
12287 int exact_match = 0;
12288 char *community = NULL;
12289 bool first = true;
12290 uint16_t show_flags = 0;
12291 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12292 struct prefix p;
12293
12294 if (uj) {
12295 argc--;
12296 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12297 }
12298
12299 if (detail)
12300 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12301
12302 /* [<ipv4|ipv6> [all]] */
12303 if (all) {
12304 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12305
12306 if (argv_find(argv, argc, "ipv4", &idx))
12307 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12308
12309 if (argv_find(argv, argc, "ipv6", &idx))
12310 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12311 }
12312
12313 if (wide)
12314 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12315
12316 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12317 &bgp, uj);
12318 if (!idx)
12319 return CMD_WARNING;
12320
12321 if (argv_find(argv, argc, "cidr-only", &idx))
12322 sh_type = bgp_show_type_cidr_only;
12323
12324 if (argv_find(argv, argc, "dampening", &idx)) {
12325 if (argv_find(argv, argc, "dampened-paths", &idx))
12326 sh_type = bgp_show_type_dampend_paths;
12327 else if (argv_find(argv, argc, "flap-statistics", &idx))
12328 sh_type = bgp_show_type_flap_statistics;
12329 }
12330
12331 if (argv_find(argv, argc, "community", &idx)) {
12332 char *maybecomm = NULL;
12333
12334 if (idx + 1 < argc) {
12335 if (argv[idx + 1]->type == VARIABLE_TKN)
12336 maybecomm = argv[idx + 1]->arg;
12337 else
12338 maybecomm = argv[idx + 1]->text;
12339 }
12340
12341 if (maybecomm && !strmatch(maybecomm, "json")
12342 && !strmatch(maybecomm, "exact-match"))
12343 community = maybecomm;
12344
12345 if (argv_find(argv, argc, "exact-match", &idx))
12346 exact_match = 1;
12347
12348 if (!community)
12349 sh_type = bgp_show_type_community_all;
12350 }
12351
12352 if (argv_find(argv, argc, "community-list", &idx)) {
12353 const char *clist_number_or_name = argv[++idx]->arg;
12354 struct community_list *list;
12355
12356 if (argv_find(argv, argc, "exact-match", &idx))
12357 exact_match = 1;
12358
12359 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12360 COMMUNITY_LIST_MASTER);
12361 if (list == NULL) {
12362 vty_out(vty,
12363 "%% %s is not a valid community-list name\n",
12364 clist_number_or_name);
12365 return CMD_WARNING;
12366 }
12367
12368 if (exact_match)
12369 sh_type = bgp_show_type_community_list_exact;
12370 else
12371 sh_type = bgp_show_type_community_list;
12372 output_arg = list;
12373 }
12374
12375 if (argv_find(argv, argc, "filter-list", &idx)) {
12376 const char *filter = argv[++idx]->arg;
12377 struct as_list *as_list;
12378
12379 as_list = as_list_lookup(filter);
12380 if (as_list == NULL) {
12381 vty_out(vty,
12382 "%% %s is not a valid AS-path access-list name\n",
12383 filter);
12384 return CMD_WARNING;
12385 }
12386
12387 sh_type = bgp_show_type_filter_list;
12388 output_arg = as_list;
12389 }
12390
12391 if (argv_find(argv, argc, "prefix-list", &idx)) {
12392 const char *prefix_list_str = argv[++idx]->arg;
12393 struct prefix_list *plist;
12394
12395 plist = prefix_list_lookup(afi, prefix_list_str);
12396 if (plist == NULL) {
12397 vty_out(vty, "%% %s is not a valid prefix-list name\n",
12398 prefix_list_str);
12399 return CMD_WARNING;
12400 }
12401
12402 sh_type = bgp_show_type_prefix_list;
12403 output_arg = plist;
12404 }
12405
12406 if (argv_find(argv, argc, "route-map", &idx)) {
12407 const char *rmap_str = argv[++idx]->arg;
12408 struct route_map *rmap;
12409
12410 rmap = route_map_lookup_by_name(rmap_str);
12411 if (!rmap) {
12412 vty_out(vty, "%% %s is not a valid route-map name\n",
12413 rmap_str);
12414 return CMD_WARNING;
12415 }
12416
12417 sh_type = bgp_show_type_route_map;
12418 output_arg = rmap;
12419 }
12420
12421 if (argv_find(argv, argc, "rpki", &idx)) {
12422 sh_type = bgp_show_type_rpki;
12423 if (argv_find(argv, argc, "valid", &idx))
12424 rpki_target_state = RPKI_VALID;
12425 else if (argv_find(argv, argc, "invalid", &idx))
12426 rpki_target_state = RPKI_INVALID;
12427 }
12428
12429 /* Display prefixes with matching version numbers */
12430 if (argv_find(argv, argc, "version", &idx)) {
12431 sh_type = bgp_show_type_prefix_version;
12432 output_arg = argv[idx + 1]->arg;
12433 }
12434
12435 /* Display prefixes with matching BGP community alias */
12436 if (argv_find(argv, argc, "alias", &idx)) {
12437 sh_type = bgp_show_type_community_alias;
12438 output_arg = argv[idx + 1]->arg;
12439 }
12440
12441 /* prefix-longer */
12442 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12443 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12444 const char *prefix_str = argv[idx]->arg;
12445
12446 if (!str2prefix(prefix_str, &p)) {
12447 vty_out(vty, "%% Malformed Prefix\n");
12448 return CMD_WARNING;
12449 }
12450
12451 sh_type = bgp_show_type_prefix_longer;
12452 output_arg = &p;
12453 }
12454
12455 if (!all) {
12456 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12457 if (community)
12458 return bgp_show_community(vty, bgp, community,
12459 exact_match, afi, safi,
12460 show_flags);
12461 else
12462 return bgp_show(vty, bgp, afi, safi, sh_type,
12463 output_arg, show_flags,
12464 rpki_target_state);
12465 } else {
12466 struct listnode *node;
12467 struct bgp *abgp;
12468 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12469 * AFI_IP6 */
12470
12471 if (uj)
12472 vty_out(vty, "{\n");
12473
12474 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12475 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12476 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12477 ? AFI_IP
12478 : AFI_IP6;
12479 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12480 FOREACH_SAFI (safi) {
12481 if (!bgp_afi_safi_peer_exists(abgp, afi,
12482 safi))
12483 continue;
12484
12485 if (uj) {
12486 if (first)
12487 first = false;
12488 else
12489 vty_out(vty, ",\n");
12490 vty_out(vty, "\"%s\":{\n",
12491 get_afi_safi_str(afi,
12492 safi,
12493 true));
12494 } else
12495 vty_out(vty,
12496 "\nFor address family: %s\n",
12497 get_afi_safi_str(
12498 afi, safi,
12499 false));
12500
12501 if (community)
12502 bgp_show_community(
12503 vty, abgp, community,
12504 exact_match, afi, safi,
12505 show_flags);
12506 else
12507 bgp_show(vty, abgp, afi, safi,
12508 sh_type, output_arg,
12509 show_flags,
12510 rpki_target_state);
12511 if (uj)
12512 vty_out(vty, "}\n");
12513 }
12514 }
12515 } else {
12516 /* show <ip> bgp all: for each AFI and SAFI*/
12517 for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, abgp)) {
12518 FOREACH_AFI_SAFI (afi, safi) {
12519 if (!bgp_afi_safi_peer_exists(abgp, afi,
12520 safi))
12521 continue;
12522
12523 if (uj) {
12524 if (first)
12525 first = false;
12526 else
12527 vty_out(vty, ",\n");
12528
12529 vty_out(vty, "\"%s\":{\n",
12530 get_afi_safi_str(afi,
12531 safi,
12532 true));
12533 } else
12534 vty_out(vty,
12535 "\nFor address family: %s\n",
12536 get_afi_safi_str(
12537 afi, safi,
12538 false));
12539
12540 if (community)
12541 bgp_show_community(
12542 vty, abgp, community,
12543 exact_match, afi, safi,
12544 show_flags);
12545 else
12546 bgp_show(vty, abgp, afi, safi,
12547 sh_type, output_arg,
12548 show_flags,
12549 rpki_target_state);
12550 if (uj)
12551 vty_out(vty, "}\n");
12552 }
12553 }
12554 }
12555 if (uj)
12556 vty_out(vty, "}\n");
12557 }
12558 return CMD_SUCCESS;
12559 }
12560
12561 DEFUN (show_ip_bgp_route,
12562 show_ip_bgp_route_cmd,
12563 "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]",
12564 SHOW_STR
12565 IP_STR
12566 BGP_STR
12567 BGP_INSTANCE_HELP_STR
12568 BGP_AFI_HELP_STR
12569 BGP_SAFI_WITH_LABEL_HELP_STR
12570 "Network in the BGP routing table to display\n"
12571 "IPv4 prefix\n"
12572 "Network in the BGP routing table to display\n"
12573 "IPv6 prefix\n"
12574 "Display only the bestpath\n"
12575 "Display only multipaths\n"
12576 "Display only paths that match the specified rpki state\n"
12577 "A valid path as determined by rpki\n"
12578 "A invalid path as determined by rpki\n"
12579 "A path that has no rpki data\n"
12580 JSON_STR)
12581 {
12582 int prefix_check = 0;
12583
12584 afi_t afi = AFI_IP6;
12585 safi_t safi = SAFI_UNICAST;
12586 char *prefix = NULL;
12587 struct bgp *bgp = NULL;
12588 enum bgp_path_type path_type;
12589 bool uj = use_json(argc, argv);
12590
12591 int idx = 0;
12592
12593 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12594 &bgp, uj);
12595 if (!idx)
12596 return CMD_WARNING;
12597
12598 if (!bgp) {
12599 vty_out(vty,
12600 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12601 return CMD_WARNING;
12602 }
12603
12604 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12605 if (argv_find(argv, argc, "A.B.C.D", &idx)
12606 || argv_find(argv, argc, "X:X::X:X", &idx))
12607 prefix_check = 0;
12608 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12609 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12610 prefix_check = 1;
12611
12612 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12613 && afi != AFI_IP6) {
12614 vty_out(vty,
12615 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12616 return CMD_WARNING;
12617 }
12618 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12619 && afi != AFI_IP) {
12620 vty_out(vty,
12621 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12622 return CMD_WARNING;
12623 }
12624
12625 prefix = argv[idx]->arg;
12626
12627 /* [<bestpath|multipath>] */
12628 if (argv_find(argv, argc, "bestpath", &idx))
12629 path_type = BGP_PATH_SHOW_BESTPATH;
12630 else if (argv_find(argv, argc, "multipath", &idx))
12631 path_type = BGP_PATH_SHOW_MULTIPATH;
12632 else
12633 path_type = BGP_PATH_SHOW_ALL;
12634
12635 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12636 path_type, RPKI_NOT_BEING_USED, uj);
12637 }
12638
12639 DEFUN (show_ip_bgp_regexp,
12640 show_ip_bgp_regexp_cmd,
12641 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12642 SHOW_STR
12643 IP_STR
12644 BGP_STR
12645 BGP_INSTANCE_HELP_STR
12646 BGP_AFI_HELP_STR
12647 BGP_SAFI_WITH_LABEL_HELP_STR
12648 "Display routes matching the AS path regular expression\n"
12649 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12650 JSON_STR)
12651 {
12652 afi_t afi = AFI_IP6;
12653 safi_t safi = SAFI_UNICAST;
12654 struct bgp *bgp = NULL;
12655 bool uj = use_json(argc, argv);
12656 char *regstr = NULL;
12657
12658 int idx = 0;
12659 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12660 &bgp, false);
12661 if (!idx)
12662 return CMD_WARNING;
12663
12664 // get index of regex
12665 if (argv_find(argv, argc, "REGEX", &idx))
12666 regstr = argv[idx]->arg;
12667
12668 assert(regstr);
12669 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12670 bgp_show_type_regexp, uj);
12671 }
12672
12673 DEFPY (show_ip_bgp_instance_all,
12674 show_ip_bgp_instance_all_cmd,
12675 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12676 SHOW_STR
12677 IP_STR
12678 BGP_STR
12679 BGP_INSTANCE_ALL_HELP_STR
12680 BGP_AFI_HELP_STR
12681 BGP_SAFI_WITH_LABEL_HELP_STR
12682 JSON_STR
12683 "Increase table width for longer prefixes\n")
12684 {
12685 afi_t afi = AFI_IP6;
12686 safi_t safi = SAFI_UNICAST;
12687 struct bgp *bgp = NULL;
12688 int idx = 0;
12689 uint16_t show_flags = 0;
12690
12691 if (uj) {
12692 argc--;
12693 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12694 }
12695
12696 if (wide)
12697 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12698
12699 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12700 &bgp, uj);
12701 if (!idx)
12702 return CMD_WARNING;
12703
12704 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12705 return CMD_SUCCESS;
12706 }
12707
12708 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12709 afi_t afi, safi_t safi, enum bgp_show_type type,
12710 bool use_json)
12711 {
12712 regex_t *regex;
12713 int rc;
12714 uint16_t show_flags = 0;
12715
12716 if (use_json)
12717 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12718
12719 if (!config_bgp_aspath_validate(regstr)) {
12720 vty_out(vty, "Invalid character in REGEX %s\n",
12721 regstr);
12722 return CMD_WARNING_CONFIG_FAILED;
12723 }
12724
12725 regex = bgp_regcomp(regstr);
12726 if (!regex) {
12727 vty_out(vty, "Can't compile regexp %s\n", regstr);
12728 return CMD_WARNING;
12729 }
12730
12731 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
12732 RPKI_NOT_BEING_USED);
12733 bgp_regex_free(regex);
12734 return rc;
12735 }
12736
12737 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12738 const char *comstr, int exact, afi_t afi,
12739 safi_t safi, uint16_t show_flags)
12740 {
12741 struct community *com;
12742 int ret = 0;
12743
12744 com = community_str2com(comstr);
12745 if (!com) {
12746 vty_out(vty, "%% Community malformed: %s\n", comstr);
12747 return CMD_WARNING;
12748 }
12749
12750 ret = bgp_show(vty, bgp, afi, safi,
12751 (exact ? bgp_show_type_community_exact
12752 : bgp_show_type_community),
12753 com, show_flags, RPKI_NOT_BEING_USED);
12754 community_free(&com);
12755
12756 return ret;
12757 }
12758
12759 enum bgp_stats {
12760 BGP_STATS_MAXBITLEN = 0,
12761 BGP_STATS_RIB,
12762 BGP_STATS_PREFIXES,
12763 BGP_STATS_TOTPLEN,
12764 BGP_STATS_UNAGGREGATEABLE,
12765 BGP_STATS_MAX_AGGREGATEABLE,
12766 BGP_STATS_AGGREGATES,
12767 BGP_STATS_SPACE,
12768 BGP_STATS_ASPATH_COUNT,
12769 BGP_STATS_ASPATH_MAXHOPS,
12770 BGP_STATS_ASPATH_TOTHOPS,
12771 BGP_STATS_ASPATH_MAXSIZE,
12772 BGP_STATS_ASPATH_TOTSIZE,
12773 BGP_STATS_ASN_HIGHEST,
12774 BGP_STATS_MAX,
12775 };
12776
12777 #define TABLE_STATS_IDX_VTY 0
12778 #define TABLE_STATS_IDX_JSON 1
12779
12780 static const char *table_stats_strs[][2] = {
12781 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12782 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12783 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12784 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12785 "unaggregateablePrefixes"},
12786 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12787 "maximumAggregateablePrefixes"},
12788 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12789 "bgpAggregateAdvertisements"},
12790 [BGP_STATS_SPACE] = {"Address space advertised",
12791 "addressSpaceAdvertised"},
12792 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12793 "advertisementsWithPaths"},
12794 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12795 "longestAsPath"},
12796 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12797 "largestAsPath"},
12798 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12799 "averageAsPathLengthHops"},
12800 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12801 "averageAsPathSizeBytes"},
12802 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12803 [BGP_STATS_MAX] = {NULL, NULL}
12804 };
12805
12806 struct bgp_table_stats {
12807 struct bgp_table *table;
12808 unsigned long long counts[BGP_STATS_MAX];
12809 double total_space;
12810 };
12811
12812 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12813 struct bgp_table_stats *ts, unsigned int space)
12814 {
12815 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12816 struct bgp_path_info *pi;
12817 const struct prefix *rn_p;
12818
12819 if (!bgp_dest_has_bgp_path_info_data(dest))
12820 return;
12821
12822 rn_p = bgp_dest_get_prefix(dest);
12823 ts->counts[BGP_STATS_PREFIXES]++;
12824 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12825
12826 /* check if the prefix is included by any other announcements */
12827 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12828 pdest = bgp_dest_parent_nolock(pdest);
12829
12830 if (pdest == NULL || pdest == top) {
12831 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12832 /* announced address space */
12833 if (space)
12834 ts->total_space += pow(2.0, space - rn_p->prefixlen);
12835 } else if (bgp_dest_has_bgp_path_info_data(pdest))
12836 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
12837
12838
12839 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
12840 ts->counts[BGP_STATS_RIB]++;
12841
12842 if (CHECK_FLAG(pi->attr->flag,
12843 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
12844 ts->counts[BGP_STATS_AGGREGATES]++;
12845
12846 /* as-path stats */
12847 if (pi->attr->aspath) {
12848 unsigned int hops = aspath_count_hops(pi->attr->aspath);
12849 unsigned int size = aspath_size(pi->attr->aspath);
12850 as_t highest = aspath_highest(pi->attr->aspath);
12851
12852 ts->counts[BGP_STATS_ASPATH_COUNT]++;
12853
12854 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
12855 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
12856
12857 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
12858 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
12859
12860 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
12861 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
12862 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
12863 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
12864 }
12865 }
12866 }
12867
12868 static void bgp_table_stats_walker(struct thread *t)
12869 {
12870 struct bgp_dest *dest, *ndest;
12871 struct bgp_dest *top;
12872 struct bgp_table_stats *ts = THREAD_ARG(t);
12873 unsigned int space = 0;
12874
12875 if (!(top = bgp_table_top(ts->table)))
12876 return;
12877
12878 switch (ts->table->afi) {
12879 case AFI_IP:
12880 space = IPV4_MAX_BITLEN;
12881 break;
12882 case AFI_IP6:
12883 space = IPV6_MAX_BITLEN;
12884 break;
12885 case AFI_L2VPN:
12886 space = EVPN_ROUTE_PREFIXLEN;
12887 break;
12888 default:
12889 return;
12890 }
12891
12892 ts->counts[BGP_STATS_MAXBITLEN] = space;
12893
12894 for (dest = top; dest; dest = bgp_route_next(dest)) {
12895 if (ts->table->safi == SAFI_MPLS_VPN
12896 || ts->table->safi == SAFI_ENCAP
12897 || ts->table->safi == SAFI_EVPN) {
12898 struct bgp_table *table;
12899
12900 table = bgp_dest_get_bgp_table_info(dest);
12901 if (!table)
12902 continue;
12903
12904 top = bgp_table_top(table);
12905 for (ndest = bgp_table_top(table); ndest;
12906 ndest = bgp_route_next(ndest))
12907 bgp_table_stats_rn(ndest, top, ts, space);
12908 } else {
12909 bgp_table_stats_rn(dest, top, ts, space);
12910 }
12911 }
12912 }
12913
12914 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
12915 struct json_object *json_array)
12916 {
12917 struct listnode *node, *nnode;
12918 struct bgp *bgp;
12919
12920 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
12921 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12922 }
12923
12924 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12925 safi_t safi, struct json_object *json_array)
12926 {
12927 struct bgp_table_stats ts;
12928 unsigned int i;
12929 int ret = CMD_SUCCESS;
12930 char temp_buf[20];
12931 struct json_object *json = NULL;
12932
12933 if (json_array)
12934 json = json_object_new_object();
12935
12936 if (!bgp->rib[afi][safi]) {
12937 char warning_msg[50];
12938
12939 snprintf(warning_msg, sizeof(warning_msg),
12940 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
12941 safi);
12942
12943 if (!json)
12944 vty_out(vty, "%s\n", warning_msg);
12945 else
12946 json_object_string_add(json, "warning", warning_msg);
12947
12948 ret = CMD_WARNING;
12949 goto end_table_stats;
12950 }
12951
12952 if (!json)
12953 vty_out(vty, "BGP %s RIB statistics (%s)\n",
12954 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
12955 else
12956 json_object_string_add(json, "instance", bgp->name_pretty);
12957
12958 /* labeled-unicast routes live in the unicast table */
12959 if (safi == SAFI_LABELED_UNICAST)
12960 safi = SAFI_UNICAST;
12961
12962 memset(&ts, 0, sizeof(ts));
12963 ts.table = bgp->rib[afi][safi];
12964 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
12965
12966 for (i = 0; i < BGP_STATS_MAX; i++) {
12967 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
12968 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
12969 continue;
12970
12971 switch (i) {
12972 case BGP_STATS_ASPATH_TOTHOPS:
12973 case BGP_STATS_ASPATH_TOTSIZE:
12974 if (!json) {
12975 snprintf(
12976 temp_buf, sizeof(temp_buf), "%12.2f",
12977 ts.counts[i]
12978 ? (float)ts.counts[i]
12979 / (float)ts.counts
12980 [BGP_STATS_ASPATH_COUNT]
12981 : 0);
12982 vty_out(vty, "%-30s: %s",
12983 table_stats_strs[i]
12984 [TABLE_STATS_IDX_VTY],
12985 temp_buf);
12986 } else {
12987 json_object_double_add(
12988 json,
12989 table_stats_strs[i]
12990 [TABLE_STATS_IDX_JSON],
12991 ts.counts[i]
12992 ? (double)ts.counts[i]
12993 / (double)ts.counts
12994 [BGP_STATS_ASPATH_COUNT]
12995 : 0);
12996 }
12997 break;
12998 case BGP_STATS_TOTPLEN:
12999 if (!json) {
13000 snprintf(
13001 temp_buf, sizeof(temp_buf), "%12.2f",
13002 ts.counts[i]
13003 ? (float)ts.counts[i]
13004 / (float)ts.counts
13005 [BGP_STATS_PREFIXES]
13006 : 0);
13007 vty_out(vty, "%-30s: %s",
13008 table_stats_strs[i]
13009 [TABLE_STATS_IDX_VTY],
13010 temp_buf);
13011 } else {
13012 json_object_double_add(
13013 json,
13014 table_stats_strs[i]
13015 [TABLE_STATS_IDX_JSON],
13016 ts.counts[i]
13017 ? (double)ts.counts[i]
13018 / (double)ts.counts
13019 [BGP_STATS_PREFIXES]
13020 : 0);
13021 }
13022 break;
13023 case BGP_STATS_SPACE:
13024 if (!json) {
13025 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13026 ts.total_space);
13027 vty_out(vty, "%-30s: %s\n",
13028 table_stats_strs[i]
13029 [TABLE_STATS_IDX_VTY],
13030 temp_buf);
13031 } else {
13032 json_object_double_add(
13033 json,
13034 table_stats_strs[i]
13035 [TABLE_STATS_IDX_JSON],
13036 (double)ts.total_space);
13037 }
13038 if (afi == AFI_IP6) {
13039 if (!json) {
13040 snprintf(temp_buf, sizeof(temp_buf),
13041 "%12g",
13042 ts.total_space
13043 * pow(2.0, -128 + 32));
13044 vty_out(vty, "%30s: %s\n",
13045 "/32 equivalent %s\n",
13046 temp_buf);
13047 } else {
13048 json_object_double_add(
13049 json, "/32equivalent",
13050 (double)(ts.total_space
13051 * pow(2.0,
13052 -128 + 32)));
13053 }
13054 if (!json) {
13055 snprintf(temp_buf, sizeof(temp_buf),
13056 "%12g",
13057 ts.total_space
13058 * pow(2.0, -128 + 48));
13059 vty_out(vty, "%30s: %s\n",
13060 "/48 equivalent %s\n",
13061 temp_buf);
13062 } else {
13063 json_object_double_add(
13064 json, "/48equivalent",
13065 (double)(ts.total_space
13066 * pow(2.0,
13067 -128 + 48)));
13068 }
13069 } else {
13070 if (!json) {
13071 snprintf(temp_buf, sizeof(temp_buf),
13072 "%12.2f",
13073 ts.total_space * 100.
13074 * pow(2.0, -32));
13075 vty_out(vty, "%30s: %s\n",
13076 "% announced ", temp_buf);
13077 } else {
13078 json_object_double_add(
13079 json, "%announced",
13080 (double)(ts.total_space * 100.
13081 * pow(2.0, -32)));
13082 }
13083 if (!json) {
13084 snprintf(temp_buf, sizeof(temp_buf),
13085 "%12.2f",
13086 ts.total_space
13087 * pow(2.0, -32 + 8));
13088 vty_out(vty, "%30s: %s\n",
13089 "/8 equivalent ", temp_buf);
13090 } else {
13091 json_object_double_add(
13092 json, "/8equivalent",
13093 (double)(ts.total_space
13094 * pow(2.0, -32 + 8)));
13095 }
13096 if (!json) {
13097 snprintf(temp_buf, sizeof(temp_buf),
13098 "%12.2f",
13099 ts.total_space
13100 * pow(2.0, -32 + 24));
13101 vty_out(vty, "%30s: %s\n",
13102 "/24 equivalent ", temp_buf);
13103 } else {
13104 json_object_double_add(
13105 json, "/24equivalent",
13106 (double)(ts.total_space
13107 * pow(2.0, -32 + 24)));
13108 }
13109 }
13110 break;
13111 default:
13112 if (!json) {
13113 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13114 ts.counts[i]);
13115 vty_out(vty, "%-30s: %s",
13116 table_stats_strs[i]
13117 [TABLE_STATS_IDX_VTY],
13118 temp_buf);
13119 } else {
13120 json_object_int_add(
13121 json,
13122 table_stats_strs[i]
13123 [TABLE_STATS_IDX_JSON],
13124 ts.counts[i]);
13125 }
13126 }
13127 if (!json)
13128 vty_out(vty, "\n");
13129 }
13130 end_table_stats:
13131 if (json)
13132 json_object_array_add(json_array, json);
13133 return ret;
13134 }
13135
13136 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13137 safi_t safi, struct json_object *json_array)
13138 {
13139 if (!bgp) {
13140 bgp_table_stats_all(vty, afi, safi, json_array);
13141 return CMD_SUCCESS;
13142 }
13143
13144 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13145 }
13146
13147 enum bgp_pcounts {
13148 PCOUNT_ADJ_IN = 0,
13149 PCOUNT_DAMPED,
13150 PCOUNT_REMOVED,
13151 PCOUNT_HISTORY,
13152 PCOUNT_STALE,
13153 PCOUNT_VALID,
13154 PCOUNT_ALL,
13155 PCOUNT_COUNTED,
13156 PCOUNT_BPATH_SELECTED,
13157 PCOUNT_PFCNT, /* the figure we display to users */
13158 PCOUNT_MAX,
13159 };
13160
13161 static const char *const pcount_strs[] = {
13162 [PCOUNT_ADJ_IN] = "Adj-in",
13163 [PCOUNT_DAMPED] = "Damped",
13164 [PCOUNT_REMOVED] = "Removed",
13165 [PCOUNT_HISTORY] = "History",
13166 [PCOUNT_STALE] = "Stale",
13167 [PCOUNT_VALID] = "Valid",
13168 [PCOUNT_ALL] = "All RIB",
13169 [PCOUNT_COUNTED] = "PfxCt counted",
13170 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13171 [PCOUNT_PFCNT] = "Useable",
13172 [PCOUNT_MAX] = NULL,
13173 };
13174
13175 struct peer_pcounts {
13176 unsigned int count[PCOUNT_MAX];
13177 const struct peer *peer;
13178 const struct bgp_table *table;
13179 safi_t safi;
13180 };
13181
13182 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13183 {
13184 const struct bgp_adj_in *ain;
13185 const struct bgp_path_info *pi;
13186 const struct peer *peer = pc->peer;
13187
13188 for (ain = rn->adj_in; ain; ain = ain->next)
13189 if (ain->peer == peer)
13190 pc->count[PCOUNT_ADJ_IN]++;
13191
13192 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13193
13194 if (pi->peer != peer)
13195 continue;
13196
13197 pc->count[PCOUNT_ALL]++;
13198
13199 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13200 pc->count[PCOUNT_DAMPED]++;
13201 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13202 pc->count[PCOUNT_HISTORY]++;
13203 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13204 pc->count[PCOUNT_REMOVED]++;
13205 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13206 pc->count[PCOUNT_STALE]++;
13207 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13208 pc->count[PCOUNT_VALID]++;
13209 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13210 pc->count[PCOUNT_PFCNT]++;
13211 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13212 pc->count[PCOUNT_BPATH_SELECTED]++;
13213
13214 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13215 pc->count[PCOUNT_COUNTED]++;
13216 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13217 flog_err(
13218 EC_LIB_DEVELOPMENT,
13219 "Attempting to count but flags say it is unusable");
13220 } else {
13221 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13222 flog_err(
13223 EC_LIB_DEVELOPMENT,
13224 "Not counted but flags say we should");
13225 }
13226 }
13227 }
13228
13229 static void bgp_peer_count_walker(struct thread *t)
13230 {
13231 struct bgp_dest *rn, *rm;
13232 const struct bgp_table *table;
13233 struct peer_pcounts *pc = THREAD_ARG(t);
13234
13235 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13236 || pc->safi == SAFI_EVPN) {
13237 /* Special handling for 2-level routing tables. */
13238 for (rn = bgp_table_top(pc->table); rn;
13239 rn = bgp_route_next(rn)) {
13240 table = bgp_dest_get_bgp_table_info(rn);
13241 if (table != NULL)
13242 for (rm = bgp_table_top(table); rm;
13243 rm = bgp_route_next(rm))
13244 bgp_peer_count_proc(rm, pc);
13245 }
13246 } else
13247 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13248 bgp_peer_count_proc(rn, pc);
13249 }
13250
13251 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13252 safi_t safi, bool use_json)
13253 {
13254 struct peer_pcounts pcounts = {.peer = peer};
13255 unsigned int i;
13256 json_object *json = NULL;
13257 json_object *json_loop = NULL;
13258
13259 if (use_json) {
13260 json = json_object_new_object();
13261 json_loop = json_object_new_object();
13262 }
13263
13264 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13265 || !peer->bgp->rib[afi][safi]) {
13266 if (use_json) {
13267 json_object_string_add(
13268 json, "warning",
13269 "No such neighbor or address family");
13270 vty_out(vty, "%s\n", json_object_to_json_string(json));
13271 json_object_free(json);
13272 json_object_free(json_loop);
13273 } else
13274 vty_out(vty, "%% No such neighbor or address family\n");
13275
13276 return CMD_WARNING;
13277 }
13278
13279 memset(&pcounts, 0, sizeof(pcounts));
13280 pcounts.peer = peer;
13281 pcounts.table = peer->bgp->rib[afi][safi];
13282 pcounts.safi = safi;
13283
13284 /* in-place call via thread subsystem so as to record execution time
13285 * stats for the thread-walk (i.e. ensure this can't be blamed on
13286 * on just vty_read()).
13287 */
13288 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13289
13290 if (use_json) {
13291 json_object_string_add(json, "prefixCountsFor", peer->host);
13292 json_object_string_add(json, "multiProtocol",
13293 get_afi_safi_str(afi, safi, true));
13294 json_object_int_add(json, "pfxCounter",
13295 peer->pcount[afi][safi]);
13296
13297 for (i = 0; i < PCOUNT_MAX; i++)
13298 json_object_int_add(json_loop, pcount_strs[i],
13299 pcounts.count[i]);
13300
13301 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13302
13303 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13304 json_object_string_add(json, "pfxctDriftFor",
13305 peer->host);
13306 json_object_string_add(
13307 json, "recommended",
13308 "Please report this bug, with the above command output");
13309 }
13310 vty_json(vty, json);
13311 } else {
13312
13313 if (peer->hostname
13314 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13315 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13316 peer->hostname, peer->host,
13317 get_afi_safi_str(afi, safi, false));
13318 } else {
13319 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13320 get_afi_safi_str(afi, safi, false));
13321 }
13322
13323 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13324 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13325
13326 for (i = 0; i < PCOUNT_MAX; i++)
13327 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13328 pcounts.count[i]);
13329
13330 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13331 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13332 vty_out(vty,
13333 "Please report this bug, with the above command output\n");
13334 }
13335 }
13336
13337 return CMD_SUCCESS;
13338 }
13339
13340 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13341 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13342 "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]",
13343 SHOW_STR
13344 IP_STR
13345 BGP_STR
13346 BGP_INSTANCE_HELP_STR
13347 BGP_AFI_HELP_STR
13348 BGP_SAFI_HELP_STR
13349 "Detailed information on TCP and BGP neighbor connections\n"
13350 "Neighbor to display information about\n"
13351 "Neighbor to display information about\n"
13352 "Neighbor on BGP configured interface\n"
13353 "Display detailed prefix count information\n"
13354 JSON_STR)
13355 {
13356 afi_t afi = AFI_IP6;
13357 safi_t safi = SAFI_UNICAST;
13358 struct peer *peer;
13359 int idx = 0;
13360 struct bgp *bgp = NULL;
13361 bool uj = use_json(argc, argv);
13362
13363 if (uj)
13364 argc--;
13365
13366 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13367 &bgp, uj);
13368 if (!idx)
13369 return CMD_WARNING;
13370
13371 argv_find(argv, argc, "neighbors", &idx);
13372 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13373 if (!peer)
13374 return CMD_WARNING;
13375
13376 return bgp_peer_counts(vty, peer, afi, safi, uj);
13377 }
13378
13379 #ifdef KEEP_OLD_VPN_COMMANDS
13380 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13381 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13382 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13383 SHOW_STR
13384 IP_STR
13385 BGP_STR
13386 BGP_VPNVX_HELP_STR
13387 "Display information about all VPNv4 NLRIs\n"
13388 "Detailed information on TCP and BGP neighbor connections\n"
13389 "Neighbor to display information about\n"
13390 "Neighbor to display information about\n"
13391 "Neighbor on BGP configured interface\n"
13392 "Display detailed prefix count information\n"
13393 JSON_STR)
13394 {
13395 int idx_peer = 6;
13396 struct peer *peer;
13397 bool uj = use_json(argc, argv);
13398
13399 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13400 if (!peer)
13401 return CMD_WARNING;
13402
13403 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13404 }
13405
13406 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13407 show_ip_bgp_vpn_all_route_prefix_cmd,
13408 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13409 SHOW_STR
13410 IP_STR
13411 BGP_STR
13412 BGP_VPNVX_HELP_STR
13413 "Display information about all VPNv4 NLRIs\n"
13414 "Network in the BGP routing table to display\n"
13415 "Network in the BGP routing table to display\n"
13416 JSON_STR)
13417 {
13418 int idx = 0;
13419 char *network = NULL;
13420 struct bgp *bgp = bgp_get_default();
13421 if (!bgp) {
13422 vty_out(vty, "Can't find default instance\n");
13423 return CMD_WARNING;
13424 }
13425
13426 if (argv_find(argv, argc, "A.B.C.D", &idx))
13427 network = argv[idx]->arg;
13428 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13429 network = argv[idx]->arg;
13430 else {
13431 vty_out(vty, "Unable to figure out Network\n");
13432 return CMD_WARNING;
13433 }
13434
13435 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13436 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13437 use_json(argc, argv));
13438 }
13439 #endif /* KEEP_OLD_VPN_COMMANDS */
13440
13441 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13442 show_bgp_l2vpn_evpn_route_prefix_cmd,
13443 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13444 SHOW_STR
13445 BGP_STR
13446 L2VPN_HELP_STR
13447 EVPN_HELP_STR
13448 "Network in the BGP routing table to display\n"
13449 "Network in the BGP routing table to display\n"
13450 "Network in the BGP routing table to display\n"
13451 "Network in the BGP routing table to display\n"
13452 JSON_STR)
13453 {
13454 int idx = 0;
13455 char *network = NULL;
13456 int prefix_check = 0;
13457
13458 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13459 argv_find(argv, argc, "X:X::X:X", &idx))
13460 network = argv[idx]->arg;
13461 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13462 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13463 network = argv[idx]->arg;
13464 prefix_check = 1;
13465 } else {
13466 vty_out(vty, "Unable to figure out Network\n");
13467 return CMD_WARNING;
13468 }
13469 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13470 prefix_check, BGP_PATH_SHOW_ALL,
13471 RPKI_NOT_BEING_USED, use_json(argc, argv));
13472 }
13473
13474 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
13475 struct bgp_table *table, int *header1,
13476 int *header2, json_object *json,
13477 json_object *json_scode,
13478 json_object *json_ocode, bool wide)
13479 {
13480 uint64_t version = table ? table->version : 0;
13481
13482 if (*header1) {
13483 if (json) {
13484 json_object_int_add(json, "bgpTableVersion", version);
13485 json_object_string_addf(json, "bgpLocalRouterId",
13486 "%pI4", &bgp->router_id);
13487 json_object_int_add(json, "defaultLocPrf",
13488 bgp->default_local_pref);
13489 json_object_int_add(json, "localAS", bgp->as);
13490 json_object_object_add(json, "bgpStatusCodes",
13491 json_scode);
13492 json_object_object_add(json, "bgpOriginCodes",
13493 json_ocode);
13494 } else {
13495 vty_out(vty,
13496 "BGP table version is %" PRIu64
13497 ", local router ID is %pI4, vrf id ",
13498 version, &bgp->router_id);
13499 if (bgp->vrf_id == VRF_UNKNOWN)
13500 vty_out(vty, "%s", VRFID_NONE_STR);
13501 else
13502 vty_out(vty, "%u", bgp->vrf_id);
13503 vty_out(vty, "\n");
13504 vty_out(vty, "Default local pref %u, ",
13505 bgp->default_local_pref);
13506 vty_out(vty, "local AS %u\n", bgp->as);
13507 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13508 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13509 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13510 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13511 }
13512 *header1 = 0;
13513 }
13514 if (*header2) {
13515 if (!json)
13516 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13517 : BGP_SHOW_HEADER));
13518 *header2 = 0;
13519 }
13520 }
13521
13522 static void
13523 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13524 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13525 const char *rmap_name, json_object *json, json_object *json_ar,
13526 json_object *json_scode, json_object *json_ocode,
13527 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13528 unsigned long *output_count, unsigned long *filtered_count)
13529 {
13530 struct bgp_adj_in *ain;
13531 struct bgp_adj_out *adj;
13532 struct bgp_dest *dest;
13533 struct bgp *bgp;
13534 struct attr attr;
13535 int ret;
13536 struct update_subgroup *subgrp;
13537 struct peer_af *paf;
13538 bool route_filtered;
13539 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13540 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13541 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13542 || (safi == SAFI_EVPN))
13543 ? true
13544 : false;
13545
13546 bgp = peer->bgp;
13547
13548 subgrp = peer_subgroup(peer, afi, safi);
13549
13550 if (type == bgp_show_adj_route_advertised && subgrp
13551 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13552 if (use_json) {
13553 json_object_int_add(json, "bgpTableVersion",
13554 table->version);
13555 json_object_string_addf(json, "bgpLocalRouterId",
13556 "%pI4", &bgp->router_id);
13557 json_object_int_add(json, "defaultLocPrf",
13558 bgp->default_local_pref);
13559 json_object_int_add(json, "localAS", bgp->as);
13560 json_object_object_add(json, "bgpStatusCodes",
13561 json_scode);
13562 json_object_object_add(json, "bgpOriginCodes",
13563 json_ocode);
13564 json_object_string_add(
13565 json, "bgpOriginatingDefaultNetwork",
13566 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13567 } else {
13568 vty_out(vty,
13569 "BGP table version is %" PRIu64
13570 ", local router ID is %pI4, vrf id ",
13571 table->version, &bgp->router_id);
13572 if (bgp->vrf_id == VRF_UNKNOWN)
13573 vty_out(vty, "%s", VRFID_NONE_STR);
13574 else
13575 vty_out(vty, "%u", bgp->vrf_id);
13576 vty_out(vty, "\n");
13577 vty_out(vty, "Default local pref %u, ",
13578 bgp->default_local_pref);
13579 vty_out(vty, "local AS %u\n", bgp->as);
13580 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13581 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13582 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13583 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13584
13585 vty_out(vty, "Originating default network %s\n\n",
13586 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13587 }
13588 *header1 = 0;
13589 }
13590
13591 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13592 if (type == bgp_show_adj_route_received
13593 || type == bgp_show_adj_route_filtered) {
13594 for (ain = dest->adj_in; ain; ain = ain->next) {
13595 if (ain->peer != peer)
13596 continue;
13597
13598 show_adj_route_header(vty, bgp, table, header1,
13599 header2, json, json_scode,
13600 json_ocode, wide);
13601
13602 if ((safi == SAFI_MPLS_VPN)
13603 || (safi == SAFI_ENCAP)
13604 || (safi == SAFI_EVPN)) {
13605 if (use_json)
13606 json_object_string_add(
13607 json_ar, "rd", rd_str);
13608 else if (show_rd && rd_str) {
13609 vty_out(vty,
13610 "Route Distinguisher: %s\n",
13611 rd_str);
13612 show_rd = false;
13613 }
13614 }
13615
13616 attr = *ain->attr;
13617 route_filtered = false;
13618
13619 /* Filter prefix using distribute list,
13620 * filter list or prefix list
13621 */
13622 const struct prefix *rn_p =
13623 bgp_dest_get_prefix(dest);
13624 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13625 safi))
13626 == FILTER_DENY)
13627 route_filtered = true;
13628
13629 /* Filter prefix using route-map */
13630 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13631 safi, rmap_name, NULL,
13632 0, NULL);
13633
13634 if (type == bgp_show_adj_route_filtered &&
13635 !route_filtered && ret != RMAP_DENY) {
13636 bgp_attr_flush(&attr);
13637 continue;
13638 }
13639
13640 if (type == bgp_show_adj_route_received
13641 && (route_filtered || ret == RMAP_DENY))
13642 (*filtered_count)++;
13643
13644 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
13645 use_json, json_ar, wide);
13646 bgp_attr_flush(&attr);
13647 (*output_count)++;
13648 }
13649 } else if (type == bgp_show_adj_route_advertised) {
13650 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13651 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13652 if (paf->peer != peer || !adj->attr)
13653 continue;
13654
13655 show_adj_route_header(vty, bgp, table,
13656 header1, header2,
13657 json, json_scode,
13658 json_ocode, wide);
13659
13660 const struct prefix *rn_p =
13661 bgp_dest_get_prefix(dest);
13662
13663 attr = *adj->attr;
13664 ret = bgp_output_modifier(
13665 peer, rn_p, &attr, afi, safi,
13666 rmap_name);
13667
13668 if (ret != RMAP_DENY) {
13669 if ((safi == SAFI_MPLS_VPN)
13670 || (safi == SAFI_ENCAP)
13671 || (safi == SAFI_EVPN)) {
13672 if (use_json)
13673 json_object_string_add(
13674 json_ar,
13675 "rd",
13676 rd_str);
13677 else if (show_rd
13678 && rd_str) {
13679 vty_out(vty,
13680 "Route Distinguisher: %s\n",
13681 rd_str);
13682 show_rd = false;
13683 }
13684 }
13685 route_vty_out_tmp(
13686 vty, dest, rn_p, &attr,
13687 safi, use_json, json_ar,
13688 wide);
13689 (*output_count)++;
13690 } else {
13691 (*filtered_count)++;
13692 }
13693
13694 bgp_attr_flush(&attr);
13695 }
13696 } else if (type == bgp_show_adj_route_bestpath) {
13697 struct bgp_path_info *pi;
13698
13699 show_adj_route_header(vty, bgp, table, header1, header2,
13700 json, json_scode, json_ocode,
13701 wide);
13702
13703 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13704 pi = pi->next) {
13705 if (pi->peer != peer)
13706 continue;
13707
13708 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13709 continue;
13710
13711 route_vty_out_tmp(vty, dest,
13712 bgp_dest_get_prefix(dest),
13713 pi->attr, safi, use_json,
13714 json_ar, wide);
13715 (*output_count)++;
13716 }
13717 }
13718 }
13719 }
13720
13721 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13722 safi_t safi, enum bgp_show_adj_route_type type,
13723 const char *rmap_name, uint16_t show_flags)
13724 {
13725 struct bgp *bgp;
13726 struct bgp_table *table;
13727 json_object *json = NULL;
13728 json_object *json_scode = NULL;
13729 json_object *json_ocode = NULL;
13730 json_object *json_ar = NULL;
13731 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13732
13733 /* Init BGP headers here so they're only displayed once
13734 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13735 */
13736 int header1 = 1;
13737 int header2 = 1;
13738
13739 /*
13740 * Initialize variables for each RD
13741 * All prefixes under an RD is aggregated within "json_routes"
13742 */
13743 char rd_str[BUFSIZ] = {0};
13744 json_object *json_routes = NULL;
13745
13746
13747 /* For 2-tier tables, prefix counts need to be
13748 * maintained across multiple runs of show_adj_route()
13749 */
13750 unsigned long output_count_per_rd;
13751 unsigned long filtered_count_per_rd;
13752 unsigned long output_count = 0;
13753 unsigned long filtered_count = 0;
13754
13755 if (use_json) {
13756 json = json_object_new_object();
13757 json_ar = json_object_new_object();
13758 json_scode = json_object_new_object();
13759 json_ocode = json_object_new_object();
13760
13761 json_object_string_add(json_scode, "suppressed", "s");
13762 json_object_string_add(json_scode, "damped", "d");
13763 json_object_string_add(json_scode, "history", "h");
13764 json_object_string_add(json_scode, "valid", "*");
13765 json_object_string_add(json_scode, "best", ">");
13766 json_object_string_add(json_scode, "multipath", "=");
13767 json_object_string_add(json_scode, "internal", "i");
13768 json_object_string_add(json_scode, "ribFailure", "r");
13769 json_object_string_add(json_scode, "stale", "S");
13770 json_object_string_add(json_scode, "removed", "R");
13771
13772 json_object_string_add(json_ocode, "igp", "i");
13773 json_object_string_add(json_ocode, "egp", "e");
13774 json_object_string_add(json_ocode, "incomplete", "?");
13775 }
13776
13777 if (!peer || !peer->afc[afi][safi]) {
13778 if (use_json) {
13779 json_object_string_add(
13780 json, "warning",
13781 "No such neighbor or address family");
13782 vty_out(vty, "%s\n", json_object_to_json_string(json));
13783 json_object_free(json);
13784 json_object_free(json_ar);
13785 json_object_free(json_scode);
13786 json_object_free(json_ocode);
13787 } else
13788 vty_out(vty, "%% No such neighbor or address family\n");
13789
13790 return CMD_WARNING;
13791 }
13792
13793 if ((type == bgp_show_adj_route_received
13794 || type == bgp_show_adj_route_filtered)
13795 && !CHECK_FLAG(peer->af_flags[afi][safi],
13796 PEER_FLAG_SOFT_RECONFIG)) {
13797 if (use_json) {
13798 json_object_string_add(
13799 json, "warning",
13800 "Inbound soft reconfiguration not enabled");
13801 vty_out(vty, "%s\n", json_object_to_json_string(json));
13802 json_object_free(json);
13803 json_object_free(json_ar);
13804 json_object_free(json_scode);
13805 json_object_free(json_ocode);
13806 } else
13807 vty_out(vty,
13808 "%% Inbound soft reconfiguration not enabled\n");
13809
13810 return CMD_WARNING;
13811 }
13812
13813 bgp = peer->bgp;
13814
13815 /* labeled-unicast routes live in the unicast table */
13816 if (safi == SAFI_LABELED_UNICAST)
13817 table = bgp->rib[afi][SAFI_UNICAST];
13818 else
13819 table = bgp->rib[afi][safi];
13820
13821 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13822 || (safi == SAFI_EVPN)) {
13823
13824 struct bgp_dest *dest;
13825
13826 for (dest = bgp_table_top(table); dest;
13827 dest = bgp_route_next(dest)) {
13828 table = bgp_dest_get_bgp_table_info(dest);
13829 if (!table)
13830 continue;
13831
13832 output_count_per_rd = 0;
13833 filtered_count_per_rd = 0;
13834
13835 if (use_json)
13836 json_routes = json_object_new_object();
13837
13838 const struct prefix_rd *prd;
13839 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13840 dest);
13841
13842 prefix_rd2str(prd, rd_str, sizeof(rd_str));
13843
13844 show_adj_route(vty, peer, table, afi, safi, type,
13845 rmap_name, json, json_routes, json_scode,
13846 json_ocode, show_flags, &header1,
13847 &header2, rd_str, &output_count_per_rd,
13848 &filtered_count_per_rd);
13849
13850 /* Don't include an empty RD in the output! */
13851 if (json_routes && (output_count_per_rd > 0))
13852 json_object_object_add(json_ar, rd_str,
13853 json_routes);
13854
13855 output_count += output_count_per_rd;
13856 filtered_count += filtered_count_per_rd;
13857 }
13858 } else
13859 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
13860 json, json_ar, json_scode, json_ocode,
13861 show_flags, &header1, &header2, rd_str,
13862 &output_count, &filtered_count);
13863
13864 if (use_json) {
13865 if (type == bgp_show_adj_route_advertised)
13866 json_object_object_add(json, "advertisedRoutes",
13867 json_ar);
13868 else
13869 json_object_object_add(json, "receivedRoutes", json_ar);
13870 json_object_int_add(json, "totalPrefixCounter", output_count);
13871 json_object_int_add(json, "filteredPrefixCounter",
13872 filtered_count);
13873
13874 /*
13875 * These fields only give up ownership to `json` when `header1`
13876 * is used (set to zero). See code in `show_adj_route` and
13877 * `show_adj_route_header`.
13878 */
13879 if (header1 == 1) {
13880 json_object_free(json_scode);
13881 json_object_free(json_ocode);
13882 }
13883
13884 vty_json(vty, json);
13885 } else if (output_count > 0) {
13886 if (filtered_count > 0)
13887 vty_out(vty,
13888 "\nTotal number of prefixes %ld (%ld filtered)\n",
13889 output_count, filtered_count);
13890 else
13891 vty_out(vty, "\nTotal number of prefixes %ld\n",
13892 output_count);
13893 }
13894
13895 return CMD_SUCCESS;
13896 }
13897
13898 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
13899 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
13900 "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 [json$uj | wide$wide]",
13901 SHOW_STR
13902 IP_STR
13903 BGP_STR
13904 BGP_INSTANCE_HELP_STR
13905 BGP_AFI_HELP_STR
13906 BGP_SAFI_WITH_LABEL_HELP_STR
13907 "Detailed information on TCP and BGP neighbor connections\n"
13908 "Neighbor to display information about\n"
13909 "Neighbor to display information about\n"
13910 "Neighbor on BGP configured interface\n"
13911 "Display the routes selected by best path\n"
13912 JSON_STR
13913 "Increase table width for longer prefixes\n")
13914 {
13915 afi_t afi = AFI_IP6;
13916 safi_t safi = SAFI_UNICAST;
13917 char *rmap_name = NULL;
13918 char *peerstr = NULL;
13919 struct bgp *bgp = NULL;
13920 struct peer *peer;
13921 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
13922 int idx = 0;
13923 uint16_t show_flags = 0;
13924
13925 if (uj)
13926 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13927
13928 if (wide)
13929 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13930
13931 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13932 &bgp, uj);
13933
13934 if (!idx)
13935 return CMD_WARNING;
13936
13937 argv_find(argv, argc, "neighbors", &idx);
13938 peerstr = argv[++idx]->arg;
13939
13940 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13941 if (!peer)
13942 return CMD_WARNING;
13943
13944 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13945 show_flags);
13946 }
13947
13948 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
13949 show_ip_bgp_instance_neighbor_advertised_route_cmd,
13950 "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 WORD] [json$uj | wide$wide]",
13951 SHOW_STR
13952 IP_STR
13953 BGP_STR
13954 BGP_INSTANCE_HELP_STR
13955 BGP_AFI_HELP_STR
13956 BGP_SAFI_WITH_LABEL_HELP_STR
13957 "Display the entries for all address families\n"
13958 "Detailed information on TCP and BGP neighbor connections\n"
13959 "Neighbor to display information about\n"
13960 "Neighbor to display information about\n"
13961 "Neighbor on BGP configured interface\n"
13962 "Display the routes advertised to a BGP neighbor\n"
13963 "Display the received routes from neighbor\n"
13964 "Display the filtered routes received from neighbor\n"
13965 "Route-map to modify the attributes\n"
13966 "Name of the route map\n"
13967 JSON_STR
13968 "Increase table width for longer prefixes\n")
13969 {
13970 afi_t afi = AFI_IP6;
13971 safi_t safi = SAFI_UNICAST;
13972 char *rmap_name = NULL;
13973 char *peerstr = NULL;
13974 struct bgp *bgp = NULL;
13975 struct peer *peer;
13976 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
13977 int idx = 0;
13978 bool first = true;
13979 uint16_t show_flags = 0;
13980
13981 if (uj) {
13982 argc--;
13983 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13984 }
13985
13986 if (all) {
13987 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
13988 if (argv_find(argv, argc, "ipv4", &idx))
13989 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
13990
13991 if (argv_find(argv, argc, "ipv6", &idx))
13992 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
13993 }
13994
13995 if (wide)
13996 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13997
13998 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13999 &bgp, uj);
14000 if (!idx)
14001 return CMD_WARNING;
14002
14003 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14004 argv_find(argv, argc, "neighbors", &idx);
14005 peerstr = argv[++idx]->arg;
14006
14007 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14008 if (!peer)
14009 return CMD_WARNING;
14010
14011 if (argv_find(argv, argc, "advertised-routes", &idx))
14012 type = bgp_show_adj_route_advertised;
14013 else if (argv_find(argv, argc, "received-routes", &idx))
14014 type = bgp_show_adj_route_received;
14015 else if (argv_find(argv, argc, "filtered-routes", &idx))
14016 type = bgp_show_adj_route_filtered;
14017
14018 if (argv_find(argv, argc, "route-map", &idx))
14019 rmap_name = argv[++idx]->arg;
14020
14021 if (!all)
14022 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14023 show_flags);
14024 if (uj)
14025 vty_out(vty, "{\n");
14026
14027 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14028 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14029 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14030 : AFI_IP6;
14031 FOREACH_SAFI (safi) {
14032 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
14033 continue;
14034
14035 if (uj) {
14036 if (first)
14037 first = false;
14038 else
14039 vty_out(vty, ",\n");
14040 vty_out(vty, "\"%s\":",
14041 get_afi_safi_str(afi, safi, true));
14042 } else
14043 vty_out(vty, "\nFor address family: %s\n",
14044 get_afi_safi_str(afi, safi, false));
14045
14046 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14047 show_flags);
14048 }
14049 } else {
14050 FOREACH_AFI_SAFI (afi, safi) {
14051 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
14052 continue;
14053
14054 if (uj) {
14055 if (first)
14056 first = false;
14057 else
14058 vty_out(vty, ",\n");
14059 vty_out(vty, "\"%s\":",
14060 get_afi_safi_str(afi, safi, true));
14061 } else
14062 vty_out(vty, "\nFor address family: %s\n",
14063 get_afi_safi_str(afi, safi, false));
14064
14065 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14066 show_flags);
14067 }
14068 }
14069 if (uj)
14070 vty_out(vty, "}\n");
14071
14072 return CMD_SUCCESS;
14073 }
14074
14075 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14076 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14077 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14078 SHOW_STR
14079 IP_STR
14080 BGP_STR
14081 BGP_INSTANCE_HELP_STR
14082 "Address Family\n"
14083 "Address Family\n"
14084 "Address Family modifier\n"
14085 "Detailed information on TCP and BGP neighbor connections\n"
14086 "Neighbor to display information about\n"
14087 "Neighbor to display information about\n"
14088 "Neighbor on BGP configured interface\n"
14089 "Display information received from a BGP neighbor\n"
14090 "Display the prefixlist filter\n"
14091 JSON_STR)
14092 {
14093 afi_t afi = AFI_IP6;
14094 safi_t safi = SAFI_UNICAST;
14095 char *peerstr = NULL;
14096 char name[BUFSIZ];
14097 struct peer *peer;
14098 int count;
14099 int idx = 0;
14100 struct bgp *bgp = NULL;
14101 bool uj = use_json(argc, argv);
14102
14103 if (uj)
14104 argc--;
14105
14106 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14107 &bgp, uj);
14108 if (!idx)
14109 return CMD_WARNING;
14110
14111 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14112 argv_find(argv, argc, "neighbors", &idx);
14113 peerstr = argv[++idx]->arg;
14114
14115 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14116 if (!peer)
14117 return CMD_WARNING;
14118
14119 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14120 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14121 if (count) {
14122 if (!uj)
14123 vty_out(vty, "Address Family: %s\n",
14124 get_afi_safi_str(afi, safi, false));
14125 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14126 } else {
14127 if (uj)
14128 vty_out(vty, "{}\n");
14129 else
14130 vty_out(vty, "No functional output\n");
14131 }
14132
14133 return CMD_SUCCESS;
14134 }
14135
14136 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14137 afi_t afi, safi_t safi,
14138 enum bgp_show_type type, bool use_json)
14139 {
14140 uint16_t show_flags = 0;
14141
14142 if (use_json)
14143 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14144
14145 if (!peer || !peer->afc[afi][safi]) {
14146 if (use_json) {
14147 json_object *json_no = NULL;
14148 json_no = json_object_new_object();
14149 json_object_string_add(
14150 json_no, "warning",
14151 "No such neighbor or address family");
14152 vty_out(vty, "%s\n",
14153 json_object_to_json_string(json_no));
14154 json_object_free(json_no);
14155 } else
14156 vty_out(vty, "%% No such neighbor or address family\n");
14157 return CMD_WARNING;
14158 }
14159
14160 /* labeled-unicast routes live in the unicast table */
14161 if (safi == SAFI_LABELED_UNICAST)
14162 safi = SAFI_UNICAST;
14163
14164 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14165 RPKI_NOT_BEING_USED);
14166 }
14167
14168 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14169 show_ip_bgp_flowspec_routes_detailed_cmd,
14170 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14171 SHOW_STR
14172 IP_STR
14173 BGP_STR
14174 BGP_INSTANCE_HELP_STR
14175 BGP_AFI_HELP_STR
14176 "SAFI Flowspec\n"
14177 "Detailed information on flowspec entries\n"
14178 JSON_STR)
14179 {
14180 afi_t afi = AFI_IP6;
14181 safi_t safi = SAFI_UNICAST;
14182 struct bgp *bgp = NULL;
14183 int idx = 0;
14184 bool uj = use_json(argc, argv);
14185 uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
14186
14187 if (uj) {
14188 argc--;
14189 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14190 }
14191
14192 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14193 &bgp, uj);
14194 if (!idx)
14195 return CMD_WARNING;
14196
14197 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14198 show_flags, RPKI_NOT_BEING_USED);
14199 }
14200
14201 DEFUN (show_ip_bgp_neighbor_routes,
14202 show_ip_bgp_neighbor_routes_cmd,
14203 "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]",
14204 SHOW_STR
14205 IP_STR
14206 BGP_STR
14207 BGP_INSTANCE_HELP_STR
14208 BGP_AFI_HELP_STR
14209 BGP_SAFI_WITH_LABEL_HELP_STR
14210 "Detailed information on TCP and BGP neighbor connections\n"
14211 "Neighbor to display information about\n"
14212 "Neighbor to display information about\n"
14213 "Neighbor on BGP configured interface\n"
14214 "Display flap statistics of the routes learned from neighbor\n"
14215 "Display the dampened routes received from neighbor\n"
14216 "Display routes learned from neighbor\n"
14217 JSON_STR)
14218 {
14219 char *peerstr = NULL;
14220 struct bgp *bgp = NULL;
14221 afi_t afi = AFI_IP6;
14222 safi_t safi = SAFI_UNICAST;
14223 struct peer *peer;
14224 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14225 int idx = 0;
14226 bool uj = use_json(argc, argv);
14227
14228 if (uj)
14229 argc--;
14230
14231 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14232 &bgp, uj);
14233 if (!idx)
14234 return CMD_WARNING;
14235
14236 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14237 argv_find(argv, argc, "neighbors", &idx);
14238 peerstr = argv[++idx]->arg;
14239
14240 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14241 if (!peer)
14242 return CMD_WARNING;
14243
14244 if (argv_find(argv, argc, "flap-statistics", &idx))
14245 sh_type = bgp_show_type_flap_neighbor;
14246 else if (argv_find(argv, argc, "dampened-routes", &idx))
14247 sh_type = bgp_show_type_damp_neighbor;
14248 else if (argv_find(argv, argc, "routes", &idx))
14249 sh_type = bgp_show_type_neighbor;
14250
14251 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14252 }
14253
14254 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14255
14256 struct bgp_distance {
14257 /* Distance value for the IP source prefix. */
14258 uint8_t distance;
14259
14260 /* Name of the access-list to be matched. */
14261 char *access_list;
14262 };
14263
14264 DEFUN (show_bgp_afi_vpn_rd_route,
14265 show_bgp_afi_vpn_rd_route_cmd,
14266 "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]",
14267 SHOW_STR
14268 BGP_STR
14269 BGP_AFI_HELP_STR
14270 "Address Family modifier\n"
14271 "Display information for a route distinguisher\n"
14272 "Route Distinguisher\n"
14273 "All Route Distinguishers\n"
14274 "Network in the BGP routing table to display\n"
14275 "Network in the BGP routing table to display\n"
14276 JSON_STR)
14277 {
14278 int ret;
14279 struct prefix_rd prd;
14280 afi_t afi = AFI_MAX;
14281 int idx = 0;
14282
14283 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14284 vty_out(vty, "%% Malformed Address Family\n");
14285 return CMD_WARNING;
14286 }
14287
14288 if (!strcmp(argv[5]->arg, "all"))
14289 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14290 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14291 RPKI_NOT_BEING_USED,
14292 use_json(argc, argv));
14293
14294 ret = str2prefix_rd(argv[5]->arg, &prd);
14295 if (!ret) {
14296 vty_out(vty, "%% Malformed Route Distinguisher\n");
14297 return CMD_WARNING;
14298 }
14299
14300 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14301 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14302 use_json(argc, argv));
14303 }
14304
14305 static struct bgp_distance *bgp_distance_new(void)
14306 {
14307 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14308 }
14309
14310 static void bgp_distance_free(struct bgp_distance *bdistance)
14311 {
14312 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14313 }
14314
14315 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14316 const char *ip_str, const char *access_list_str)
14317 {
14318 int ret;
14319 afi_t afi;
14320 safi_t safi;
14321 struct prefix p;
14322 uint8_t distance;
14323 struct bgp_dest *dest;
14324 struct bgp_distance *bdistance;
14325
14326 afi = bgp_node_afi(vty);
14327 safi = bgp_node_safi(vty);
14328
14329 ret = str2prefix(ip_str, &p);
14330 if (ret == 0) {
14331 vty_out(vty, "Malformed prefix\n");
14332 return CMD_WARNING_CONFIG_FAILED;
14333 }
14334
14335 distance = atoi(distance_str);
14336
14337 /* Get BGP distance node. */
14338 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14339 bdistance = bgp_dest_get_bgp_distance_info(dest);
14340 if (bdistance)
14341 bgp_dest_unlock_node(dest);
14342 else {
14343 bdistance = bgp_distance_new();
14344 bgp_dest_set_bgp_distance_info(dest, bdistance);
14345 }
14346
14347 /* Set distance value. */
14348 bdistance->distance = distance;
14349
14350 /* Reset access-list configuration. */
14351 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14352 if (access_list_str)
14353 bdistance->access_list =
14354 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14355
14356 return CMD_SUCCESS;
14357 }
14358
14359 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14360 const char *ip_str, const char *access_list_str)
14361 {
14362 int ret;
14363 afi_t afi;
14364 safi_t safi;
14365 struct prefix p;
14366 int distance;
14367 struct bgp_dest *dest;
14368 struct bgp_distance *bdistance;
14369
14370 afi = bgp_node_afi(vty);
14371 safi = bgp_node_safi(vty);
14372
14373 ret = str2prefix(ip_str, &p);
14374 if (ret == 0) {
14375 vty_out(vty, "Malformed prefix\n");
14376 return CMD_WARNING_CONFIG_FAILED;
14377 }
14378
14379 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14380 if (!dest) {
14381 vty_out(vty, "Can't find specified prefix\n");
14382 return CMD_WARNING_CONFIG_FAILED;
14383 }
14384
14385 bdistance = bgp_dest_get_bgp_distance_info(dest);
14386 distance = atoi(distance_str);
14387
14388 if (bdistance->distance != distance) {
14389 vty_out(vty, "Distance does not match configured\n");
14390 bgp_dest_unlock_node(dest);
14391 return CMD_WARNING_CONFIG_FAILED;
14392 }
14393
14394 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14395 bgp_distance_free(bdistance);
14396
14397 bgp_dest_set_bgp_path_info(dest, NULL);
14398 bgp_dest_unlock_node(dest);
14399 bgp_dest_unlock_node(dest);
14400
14401 return CMD_SUCCESS;
14402 }
14403
14404 /* Apply BGP information to distance method. */
14405 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14406 afi_t afi, safi_t safi, struct bgp *bgp)
14407 {
14408 struct bgp_dest *dest;
14409 struct prefix q = {0};
14410 struct peer *peer;
14411 struct bgp_distance *bdistance;
14412 struct access_list *alist;
14413 struct bgp_static *bgp_static;
14414
14415 if (!bgp)
14416 return 0;
14417
14418 peer = pinfo->peer;
14419
14420 if (pinfo->attr->distance)
14421 return pinfo->attr->distance;
14422
14423 /* Check source address.
14424 * Note: for aggregate route, peer can have unspec af type.
14425 */
14426 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14427 && !sockunion2hostprefix(&peer->su, &q))
14428 return 0;
14429
14430 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14431 if (dest) {
14432 bdistance = bgp_dest_get_bgp_distance_info(dest);
14433 bgp_dest_unlock_node(dest);
14434
14435 if (bdistance->access_list) {
14436 alist = access_list_lookup(afi, bdistance->access_list);
14437 if (alist
14438 && access_list_apply(alist, p) == FILTER_PERMIT)
14439 return bdistance->distance;
14440 } else
14441 return bdistance->distance;
14442 }
14443
14444 /* Backdoor check. */
14445 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14446 if (dest) {
14447 bgp_static = bgp_dest_get_bgp_static_info(dest);
14448 bgp_dest_unlock_node(dest);
14449
14450 if (bgp_static->backdoor) {
14451 if (bgp->distance_local[afi][safi])
14452 return bgp->distance_local[afi][safi];
14453 else
14454 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14455 }
14456 }
14457
14458 if (peer->sort == BGP_PEER_EBGP) {
14459 if (bgp->distance_ebgp[afi][safi])
14460 return bgp->distance_ebgp[afi][safi];
14461 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14462 } else if (peer->sort == BGP_PEER_IBGP) {
14463 if (bgp->distance_ibgp[afi][safi])
14464 return bgp->distance_ibgp[afi][safi];
14465 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14466 } else {
14467 if (bgp->distance_local[afi][safi])
14468 return bgp->distance_local[afi][safi];
14469 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14470 }
14471 }
14472
14473 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14474 * we should tell ZEBRA update the routes for a specific
14475 * AFI/SAFI to reflect changes in RIB.
14476 */
14477 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14478 afi_t update_afi,
14479 safi_t update_safi)
14480 {
14481 afi_t afi;
14482 safi_t safi;
14483
14484 FOREACH_AFI_SAFI (afi, safi) {
14485 if (!bgp_fibupd_safi(safi))
14486 continue;
14487
14488 if (afi != update_afi && safi != update_safi)
14489 continue;
14490
14491 if (BGP_DEBUG(zebra, ZEBRA))
14492 zlog_debug(
14493 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14494 __func__, afi, safi);
14495 bgp_zebra_announce_table(bgp, afi, safi);
14496 }
14497 }
14498
14499 DEFUN (bgp_distance,
14500 bgp_distance_cmd,
14501 "distance bgp (1-255) (1-255) (1-255)",
14502 "Define an administrative distance\n"
14503 "BGP distance\n"
14504 "Distance for routes external to the AS\n"
14505 "Distance for routes internal to the AS\n"
14506 "Distance for local routes\n")
14507 {
14508 VTY_DECLVAR_CONTEXT(bgp, bgp);
14509 int idx_number = 2;
14510 int idx_number_2 = 3;
14511 int idx_number_3 = 4;
14512 int distance_ebgp = atoi(argv[idx_number]->arg);
14513 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14514 int distance_local = atoi(argv[idx_number_3]->arg);
14515 afi_t afi;
14516 safi_t safi;
14517
14518 afi = bgp_node_afi(vty);
14519 safi = bgp_node_safi(vty);
14520
14521 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14522 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14523 || bgp->distance_local[afi][safi] != distance_local) {
14524 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14525 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14526 bgp->distance_local[afi][safi] = distance_local;
14527 bgp_announce_routes_distance_update(bgp, afi, safi);
14528 }
14529 return CMD_SUCCESS;
14530 }
14531
14532 DEFUN (no_bgp_distance,
14533 no_bgp_distance_cmd,
14534 "no distance bgp [(1-255) (1-255) (1-255)]",
14535 NO_STR
14536 "Define an administrative distance\n"
14537 "BGP distance\n"
14538 "Distance for routes external to the AS\n"
14539 "Distance for routes internal to the AS\n"
14540 "Distance for local routes\n")
14541 {
14542 VTY_DECLVAR_CONTEXT(bgp, bgp);
14543 afi_t afi;
14544 safi_t safi;
14545
14546 afi = bgp_node_afi(vty);
14547 safi = bgp_node_safi(vty);
14548
14549 if (bgp->distance_ebgp[afi][safi] != 0
14550 || bgp->distance_ibgp[afi][safi] != 0
14551 || bgp->distance_local[afi][safi] != 0) {
14552 bgp->distance_ebgp[afi][safi] = 0;
14553 bgp->distance_ibgp[afi][safi] = 0;
14554 bgp->distance_local[afi][safi] = 0;
14555 bgp_announce_routes_distance_update(bgp, afi, safi);
14556 }
14557 return CMD_SUCCESS;
14558 }
14559
14560
14561 DEFUN (bgp_distance_source,
14562 bgp_distance_source_cmd,
14563 "distance (1-255) A.B.C.D/M",
14564 "Define an administrative distance\n"
14565 "Administrative distance\n"
14566 "IP source prefix\n")
14567 {
14568 int idx_number = 1;
14569 int idx_ipv4_prefixlen = 2;
14570 bgp_distance_set(vty, argv[idx_number]->arg,
14571 argv[idx_ipv4_prefixlen]->arg, NULL);
14572 return CMD_SUCCESS;
14573 }
14574
14575 DEFUN (no_bgp_distance_source,
14576 no_bgp_distance_source_cmd,
14577 "no distance (1-255) A.B.C.D/M",
14578 NO_STR
14579 "Define an administrative distance\n"
14580 "Administrative distance\n"
14581 "IP source prefix\n")
14582 {
14583 int idx_number = 2;
14584 int idx_ipv4_prefixlen = 3;
14585 bgp_distance_unset(vty, argv[idx_number]->arg,
14586 argv[idx_ipv4_prefixlen]->arg, NULL);
14587 return CMD_SUCCESS;
14588 }
14589
14590 DEFUN (bgp_distance_source_access_list,
14591 bgp_distance_source_access_list_cmd,
14592 "distance (1-255) A.B.C.D/M WORD",
14593 "Define an administrative distance\n"
14594 "Administrative distance\n"
14595 "IP source prefix\n"
14596 "Access list name\n")
14597 {
14598 int idx_number = 1;
14599 int idx_ipv4_prefixlen = 2;
14600 int idx_word = 3;
14601 bgp_distance_set(vty, argv[idx_number]->arg,
14602 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14603 return CMD_SUCCESS;
14604 }
14605
14606 DEFUN (no_bgp_distance_source_access_list,
14607 no_bgp_distance_source_access_list_cmd,
14608 "no distance (1-255) A.B.C.D/M WORD",
14609 NO_STR
14610 "Define an administrative distance\n"
14611 "Administrative distance\n"
14612 "IP source prefix\n"
14613 "Access list name\n")
14614 {
14615 int idx_number = 2;
14616 int idx_ipv4_prefixlen = 3;
14617 int idx_word = 4;
14618 bgp_distance_unset(vty, argv[idx_number]->arg,
14619 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14620 return CMD_SUCCESS;
14621 }
14622
14623 DEFUN (ipv6_bgp_distance_source,
14624 ipv6_bgp_distance_source_cmd,
14625 "distance (1-255) X:X::X:X/M",
14626 "Define an administrative distance\n"
14627 "Administrative distance\n"
14628 "IP source prefix\n")
14629 {
14630 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
14631 return CMD_SUCCESS;
14632 }
14633
14634 DEFUN (no_ipv6_bgp_distance_source,
14635 no_ipv6_bgp_distance_source_cmd,
14636 "no distance (1-255) X:X::X:X/M",
14637 NO_STR
14638 "Define an administrative distance\n"
14639 "Administrative distance\n"
14640 "IP source prefix\n")
14641 {
14642 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
14643 return CMD_SUCCESS;
14644 }
14645
14646 DEFUN (ipv6_bgp_distance_source_access_list,
14647 ipv6_bgp_distance_source_access_list_cmd,
14648 "distance (1-255) X:X::X:X/M WORD",
14649 "Define an administrative distance\n"
14650 "Administrative distance\n"
14651 "IP source prefix\n"
14652 "Access list name\n")
14653 {
14654 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
14655 return CMD_SUCCESS;
14656 }
14657
14658 DEFUN (no_ipv6_bgp_distance_source_access_list,
14659 no_ipv6_bgp_distance_source_access_list_cmd,
14660 "no distance (1-255) X:X::X:X/M WORD",
14661 NO_STR
14662 "Define an administrative distance\n"
14663 "Administrative distance\n"
14664 "IP source prefix\n"
14665 "Access list name\n")
14666 {
14667 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
14668 return CMD_SUCCESS;
14669 }
14670
14671 DEFUN (bgp_damp_set,
14672 bgp_damp_set_cmd,
14673 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14674 "BGP Specific commands\n"
14675 "Enable route-flap dampening\n"
14676 "Half-life time for the penalty\n"
14677 "Value to start reusing a route\n"
14678 "Value to start suppressing a route\n"
14679 "Maximum duration to suppress a stable route\n")
14680 {
14681 VTY_DECLVAR_CONTEXT(bgp, bgp);
14682 int idx_half_life = 2;
14683 int idx_reuse = 3;
14684 int idx_suppress = 4;
14685 int idx_max_suppress = 5;
14686 int half = DEFAULT_HALF_LIFE * 60;
14687 int reuse = DEFAULT_REUSE;
14688 int suppress = DEFAULT_SUPPRESS;
14689 int max = 4 * half;
14690
14691 if (argc == 6) {
14692 half = atoi(argv[idx_half_life]->arg) * 60;
14693 reuse = atoi(argv[idx_reuse]->arg);
14694 suppress = atoi(argv[idx_suppress]->arg);
14695 max = atoi(argv[idx_max_suppress]->arg) * 60;
14696 } else if (argc == 3) {
14697 half = atoi(argv[idx_half_life]->arg) * 60;
14698 max = 4 * half;
14699 }
14700
14701 /*
14702 * These can't be 0 but our SA doesn't understand the
14703 * way our cli is constructed
14704 */
14705 assert(reuse);
14706 assert(half);
14707 if (suppress < reuse) {
14708 vty_out(vty,
14709 "Suppress value cannot be less than reuse value \n");
14710 return 0;
14711 }
14712
14713 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
14714 reuse, suppress, max);
14715 }
14716
14717 DEFUN (bgp_damp_unset,
14718 bgp_damp_unset_cmd,
14719 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14720 NO_STR
14721 "BGP Specific commands\n"
14722 "Enable route-flap dampening\n"
14723 "Half-life time for the penalty\n"
14724 "Value to start reusing a route\n"
14725 "Value to start suppressing a route\n"
14726 "Maximum duration to suppress a stable route\n")
14727 {
14728 VTY_DECLVAR_CONTEXT(bgp, bgp);
14729 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
14730 }
14731
14732 /* Display specified route of BGP table. */
14733 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14734 const char *ip_str, afi_t afi, safi_t safi,
14735 struct prefix_rd *prd, int prefix_check)
14736 {
14737 int ret;
14738 struct prefix match;
14739 struct bgp_dest *dest;
14740 struct bgp_dest *rm;
14741 struct bgp_path_info *pi;
14742 struct bgp_path_info *pi_temp;
14743 struct bgp *bgp;
14744 struct bgp_table *table;
14745
14746 /* BGP structure lookup. */
14747 if (view_name) {
14748 bgp = bgp_lookup_by_name(view_name);
14749 if (bgp == NULL) {
14750 vty_out(vty, "%% Can't find BGP instance %s\n",
14751 view_name);
14752 return CMD_WARNING;
14753 }
14754 } else {
14755 bgp = bgp_get_default();
14756 if (bgp == NULL) {
14757 vty_out(vty, "%% No BGP process is configured\n");
14758 return CMD_WARNING;
14759 }
14760 }
14761
14762 /* Check IP address argument. */
14763 ret = str2prefix(ip_str, &match);
14764 if (!ret) {
14765 vty_out(vty, "%% address is malformed\n");
14766 return CMD_WARNING;
14767 }
14768
14769 match.family = afi2family(afi);
14770
14771 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14772 || (safi == SAFI_EVPN)) {
14773 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14774 dest = bgp_route_next(dest)) {
14775 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14776
14777 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14778 continue;
14779 table = bgp_dest_get_bgp_table_info(dest);
14780 if (!table)
14781 continue;
14782 rm = bgp_node_match(table, &match);
14783 if (rm == NULL)
14784 continue;
14785
14786 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
14787
14788 if (!prefix_check
14789 || rm_p->prefixlen == match.prefixlen) {
14790 pi = bgp_dest_get_bgp_path_info(rm);
14791 while (pi) {
14792 if (pi->extra && pi->extra->damp_info) {
14793 pi_temp = pi->next;
14794 bgp_damp_info_free(
14795 pi->extra->damp_info,
14796 1, afi, safi);
14797 pi = pi_temp;
14798 } else
14799 pi = pi->next;
14800 }
14801 }
14802
14803 bgp_dest_unlock_node(rm);
14804 }
14805 } else {
14806 dest = bgp_node_match(bgp->rib[afi][safi], &match);
14807 if (dest != NULL) {
14808 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14809
14810 if (!prefix_check
14811 || dest_p->prefixlen == match.prefixlen) {
14812 pi = bgp_dest_get_bgp_path_info(dest);
14813 while (pi) {
14814 if (pi->extra && pi->extra->damp_info) {
14815 pi_temp = pi->next;
14816 bgp_damp_info_free(
14817 pi->extra->damp_info,
14818 1, afi, safi);
14819 pi = pi_temp;
14820 } else
14821 pi = pi->next;
14822 }
14823 }
14824
14825 bgp_dest_unlock_node(dest);
14826 }
14827 }
14828
14829 return CMD_SUCCESS;
14830 }
14831
14832 DEFUN (clear_ip_bgp_dampening,
14833 clear_ip_bgp_dampening_cmd,
14834 "clear ip bgp dampening",
14835 CLEAR_STR
14836 IP_STR
14837 BGP_STR
14838 "Clear route flap dampening information\n")
14839 {
14840 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
14841 return CMD_SUCCESS;
14842 }
14843
14844 DEFUN (clear_ip_bgp_dampening_prefix,
14845 clear_ip_bgp_dampening_prefix_cmd,
14846 "clear ip bgp dampening A.B.C.D/M",
14847 CLEAR_STR
14848 IP_STR
14849 BGP_STR
14850 "Clear route flap dampening information\n"
14851 "IPv4 prefix\n")
14852 {
14853 int idx_ipv4_prefixlen = 4;
14854 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
14855 AFI_IP, SAFI_UNICAST, NULL, 1);
14856 }
14857
14858 DEFUN (clear_ip_bgp_dampening_address,
14859 clear_ip_bgp_dampening_address_cmd,
14860 "clear ip bgp dampening A.B.C.D",
14861 CLEAR_STR
14862 IP_STR
14863 BGP_STR
14864 "Clear route flap dampening information\n"
14865 "Network to clear damping information\n")
14866 {
14867 int idx_ipv4 = 4;
14868 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
14869 SAFI_UNICAST, NULL, 0);
14870 }
14871
14872 DEFUN (clear_ip_bgp_dampening_address_mask,
14873 clear_ip_bgp_dampening_address_mask_cmd,
14874 "clear ip bgp dampening A.B.C.D A.B.C.D",
14875 CLEAR_STR
14876 IP_STR
14877 BGP_STR
14878 "Clear route flap dampening information\n"
14879 "Network to clear damping information\n"
14880 "Network mask\n")
14881 {
14882 int idx_ipv4 = 4;
14883 int idx_ipv4_2 = 5;
14884 int ret;
14885 char prefix_str[BUFSIZ];
14886
14887 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
14888 prefix_str, sizeof(prefix_str));
14889 if (!ret) {
14890 vty_out(vty, "%% Inconsistent address and mask\n");
14891 return CMD_WARNING;
14892 }
14893
14894 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
14895 NULL, 0);
14896 }
14897
14898 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
14899 {
14900 struct vty *vty = arg;
14901 struct peer *peer = bucket->data;
14902 char buf[SU_ADDRSTRLEN];
14903
14904 vty_out(vty, "\tPeer: %s %s\n", peer->host,
14905 sockunion2str(&peer->su, buf, sizeof(buf)));
14906 }
14907
14908 DEFUN (show_bgp_listeners,
14909 show_bgp_listeners_cmd,
14910 "show bgp listeners",
14911 SHOW_STR
14912 BGP_STR
14913 "Display Listen Sockets and who created them\n")
14914 {
14915 bgp_dump_listener_info(vty);
14916
14917 return CMD_SUCCESS;
14918 }
14919
14920 DEFUN (show_bgp_peerhash,
14921 show_bgp_peerhash_cmd,
14922 "show bgp peerhash",
14923 SHOW_STR
14924 BGP_STR
14925 "Display information about the BGP peerhash\n")
14926 {
14927 struct list *instances = bm->bgp;
14928 struct listnode *node;
14929 struct bgp *bgp;
14930
14931 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
14932 vty_out(vty, "BGP: %s\n", bgp->name);
14933 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
14934 vty);
14935 }
14936
14937 return CMD_SUCCESS;
14938 }
14939
14940 /* also used for encap safi */
14941 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
14942 afi_t afi, safi_t safi)
14943 {
14944 struct bgp_dest *pdest;
14945 struct bgp_dest *dest;
14946 struct bgp_table *table;
14947 const struct prefix *p;
14948 const struct prefix_rd *prd;
14949 struct bgp_static *bgp_static;
14950 mpls_label_t label;
14951 char rdbuf[RD_ADDRSTRLEN];
14952
14953 /* Network configuration. */
14954 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14955 pdest = bgp_route_next(pdest)) {
14956 table = bgp_dest_get_bgp_table_info(pdest);
14957 if (!table)
14958 continue;
14959
14960 for (dest = bgp_table_top(table); dest;
14961 dest = bgp_route_next(dest)) {
14962 bgp_static = bgp_dest_get_bgp_static_info(dest);
14963 if (bgp_static == NULL)
14964 continue;
14965
14966 p = bgp_dest_get_prefix(dest);
14967 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14968 pdest);
14969
14970 /* "network" configuration display. */
14971 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14972 label = decode_label(&bgp_static->label);
14973
14974 vty_out(vty, " network %pFX rd %s", p, rdbuf);
14975 if (safi == SAFI_MPLS_VPN)
14976 vty_out(vty, " label %u", label);
14977
14978 if (bgp_static->rmap.name)
14979 vty_out(vty, " route-map %s",
14980 bgp_static->rmap.name);
14981
14982 if (bgp_static->backdoor)
14983 vty_out(vty, " backdoor");
14984
14985 vty_out(vty, "\n");
14986 }
14987 }
14988 }
14989
14990 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
14991 afi_t afi, safi_t safi)
14992 {
14993 struct bgp_dest *pdest;
14994 struct bgp_dest *dest;
14995 struct bgp_table *table;
14996 const struct prefix *p;
14997 const struct prefix_rd *prd;
14998 struct bgp_static *bgp_static;
14999 char buf[PREFIX_STRLEN * 2];
15000 char buf2[SU_ADDRSTRLEN];
15001 char rdbuf[RD_ADDRSTRLEN];
15002 char esi_buf[ESI_BYTES];
15003
15004 /* Network configuration. */
15005 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
15006 pdest = bgp_route_next(pdest)) {
15007 table = bgp_dest_get_bgp_table_info(pdest);
15008 if (!table)
15009 continue;
15010
15011 for (dest = bgp_table_top(table); dest;
15012 dest = bgp_route_next(dest)) {
15013 bgp_static = bgp_dest_get_bgp_static_info(dest);
15014 if (bgp_static == NULL)
15015 continue;
15016
15017 char *macrouter = NULL;
15018
15019 if (bgp_static->router_mac)
15020 macrouter = prefix_mac2str(
15021 bgp_static->router_mac, NULL, 0);
15022 if (bgp_static->eth_s_id)
15023 esi_to_str(bgp_static->eth_s_id,
15024 esi_buf, sizeof(esi_buf));
15025 p = bgp_dest_get_prefix(dest);
15026 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15027
15028 /* "network" configuration display. */
15029 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
15030 if (p->u.prefix_evpn.route_type == 5) {
15031 char local_buf[PREFIX_STRLEN];
15032 uint8_t family = is_evpn_prefix_ipaddr_v4((
15033 struct prefix_evpn *)p)
15034 ? AF_INET
15035 : AF_INET6;
15036 inet_ntop(family,
15037 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15038 local_buf, PREFIX_STRLEN);
15039 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15040 p->u.prefix_evpn.prefix_addr
15041 .ip_prefix_length);
15042 } else {
15043 prefix2str(p, buf, sizeof(buf));
15044 }
15045
15046 if (bgp_static->gatewayIp.family == AF_INET
15047 || bgp_static->gatewayIp.family == AF_INET6)
15048 inet_ntop(bgp_static->gatewayIp.family,
15049 &bgp_static->gatewayIp.u.prefix, buf2,
15050 sizeof(buf2));
15051 vty_out(vty,
15052 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15053 buf, rdbuf,
15054 p->u.prefix_evpn.prefix_addr.eth_tag,
15055 decode_label(&bgp_static->label), esi_buf, buf2,
15056 macrouter);
15057
15058 XFREE(MTYPE_TMP, macrouter);
15059 }
15060 }
15061 }
15062
15063 /* Configuration of static route announcement and aggregate
15064 information. */
15065 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15066 safi_t safi)
15067 {
15068 struct bgp_dest *dest;
15069 const struct prefix *p;
15070 struct bgp_static *bgp_static;
15071 struct bgp_aggregate *bgp_aggregate;
15072
15073 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15074 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15075 return;
15076 }
15077
15078 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15079 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15080 return;
15081 }
15082
15083 /* Network configuration. */
15084 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15085 dest = bgp_route_next(dest)) {
15086 bgp_static = bgp_dest_get_bgp_static_info(dest);
15087 if (bgp_static == NULL)
15088 continue;
15089
15090 p = bgp_dest_get_prefix(dest);
15091
15092 vty_out(vty, " network %pFX", p);
15093
15094 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15095 vty_out(vty, " label-index %u",
15096 bgp_static->label_index);
15097
15098 if (bgp_static->rmap.name)
15099 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15100
15101 if (bgp_static->backdoor)
15102 vty_out(vty, " backdoor");
15103
15104 vty_out(vty, "\n");
15105 }
15106
15107 /* Aggregate-address configuration. */
15108 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15109 dest = bgp_route_next(dest)) {
15110 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15111 if (bgp_aggregate == NULL)
15112 continue;
15113
15114 p = bgp_dest_get_prefix(dest);
15115
15116 vty_out(vty, " aggregate-address %pFX", p);
15117
15118 if (bgp_aggregate->as_set)
15119 vty_out(vty, " as-set");
15120
15121 if (bgp_aggregate->summary_only)
15122 vty_out(vty, " summary-only");
15123
15124 if (bgp_aggregate->rmap.name)
15125 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15126
15127 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15128 vty_out(vty, " origin %s",
15129 bgp_origin2str(bgp_aggregate->origin));
15130
15131 if (bgp_aggregate->match_med)
15132 vty_out(vty, " matching-MED-only");
15133
15134 if (bgp_aggregate->suppress_map_name)
15135 vty_out(vty, " suppress-map %s",
15136 bgp_aggregate->suppress_map_name);
15137
15138 vty_out(vty, "\n");
15139 }
15140 }
15141
15142 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15143 safi_t safi)
15144 {
15145 struct bgp_dest *dest;
15146 struct bgp_distance *bdistance;
15147
15148 /* Distance configuration. */
15149 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15150 && bgp->distance_local[afi][safi]
15151 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15152 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15153 || bgp->distance_local[afi][safi]
15154 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15155 vty_out(vty, " distance bgp %d %d %d\n",
15156 bgp->distance_ebgp[afi][safi],
15157 bgp->distance_ibgp[afi][safi],
15158 bgp->distance_local[afi][safi]);
15159 }
15160
15161 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15162 dest = bgp_route_next(dest)) {
15163 bdistance = bgp_dest_get_bgp_distance_info(dest);
15164 if (bdistance != NULL)
15165 vty_out(vty, " distance %d %pBD %s\n",
15166 bdistance->distance, dest,
15167 bdistance->access_list ? bdistance->access_list
15168 : "");
15169 }
15170 }
15171
15172 /* Allocate routing table structure and install commands. */
15173 void bgp_route_init(void)
15174 {
15175 afi_t afi;
15176 safi_t safi;
15177
15178 /* Init BGP distance table. */
15179 FOREACH_AFI_SAFI (afi, safi)
15180 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15181
15182 /* IPv4 BGP commands. */
15183 install_element(BGP_NODE, &bgp_table_map_cmd);
15184 install_element(BGP_NODE, &bgp_network_cmd);
15185 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15186
15187 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15188
15189 /* IPv4 unicast configuration. */
15190 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15191 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15192 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15193
15194 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15195
15196 /* IPv4 multicast configuration. */
15197 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15198 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15199 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15200 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15201
15202 /* IPv4 labeled-unicast configuration. */
15203 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15204 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15205
15206 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15207 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15208 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15209 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15210 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15211 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15212 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15213 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15214
15215 install_element(VIEW_NODE,
15216 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15217 install_element(VIEW_NODE,
15218 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15219 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15220 install_element(VIEW_NODE,
15221 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15222 #ifdef KEEP_OLD_VPN_COMMANDS
15223 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15224 #endif /* KEEP_OLD_VPN_COMMANDS */
15225 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15226 install_element(VIEW_NODE,
15227 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15228
15229 /* BGP dampening clear commands */
15230 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15231 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15232
15233 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15234 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15235
15236 /* prefix count */
15237 install_element(ENABLE_NODE,
15238 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15239 #ifdef KEEP_OLD_VPN_COMMANDS
15240 install_element(ENABLE_NODE,
15241 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15242 #endif /* KEEP_OLD_VPN_COMMANDS */
15243
15244 /* New config IPv6 BGP commands. */
15245 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15246 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15247 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15248
15249 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15250
15251 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15252
15253 /* IPv6 labeled unicast address family. */
15254 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15255 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15256
15257 install_element(BGP_NODE, &bgp_distance_cmd);
15258 install_element(BGP_NODE, &no_bgp_distance_cmd);
15259 install_element(BGP_NODE, &bgp_distance_source_cmd);
15260 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15261 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15262 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15263 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15264 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15265 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15266 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15267 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15268 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15269 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15270 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15271 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15272 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15273 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15274 install_element(BGP_IPV4M_NODE,
15275 &no_bgp_distance_source_access_list_cmd);
15276 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15277 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15278 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15279 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15280 install_element(BGP_IPV6_NODE,
15281 &ipv6_bgp_distance_source_access_list_cmd);
15282 install_element(BGP_IPV6_NODE,
15283 &no_ipv6_bgp_distance_source_access_list_cmd);
15284 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15285 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15286 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15287 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15288 install_element(BGP_IPV6M_NODE,
15289 &ipv6_bgp_distance_source_access_list_cmd);
15290 install_element(BGP_IPV6M_NODE,
15291 &no_ipv6_bgp_distance_source_access_list_cmd);
15292
15293 /* BGP dampening */
15294 install_element(BGP_NODE, &bgp_damp_set_cmd);
15295 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15296 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15297 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15298 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15299 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15300 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15301 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15302 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15303 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15304 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15305 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15306 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15307 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15308
15309 /* Large Communities */
15310 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15311 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15312
15313 /* show bgp ipv4 flowspec detailed */
15314 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15315
15316 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15317 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15318 }
15319
15320 void bgp_route_finish(void)
15321 {
15322 afi_t afi;
15323 safi_t safi;
15324
15325 FOREACH_AFI_SAFI (afi, safi) {
15326 bgp_table_unlock(bgp_distance_table[afi][safi]);
15327 bgp_distance_table[afi][safi] = NULL;
15328 }
15329 }