]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Fix continue/break change from old commit
[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 }
9533 }
9534
9535 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9536
9537 ipaddr2str(&eo->gw_ip, buf, BUFSIZ);
9538
9539 if (!json_path)
9540 vty_out(vty, "/%s", buf);
9541 else
9542 json_object_string_add(json_overlay, "gw", buf);
9543
9544 if (bgp_attr_get_ecommunity(attr)) {
9545 char *mac = NULL;
9546 struct ecommunity_val *routermac = ecommunity_lookup(
9547 bgp_attr_get_ecommunity(attr), ECOMMUNITY_ENCODE_EVPN,
9548 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9549
9550 if (routermac)
9551 mac = ecom_mac2str((char *)routermac->val);
9552 if (mac) {
9553 if (!json_path) {
9554 vty_out(vty, "/%s", mac);
9555 } else {
9556 json_object_string_add(json_overlay, "rmac",
9557 mac);
9558 }
9559 XFREE(MTYPE_TMP, mac);
9560 }
9561 }
9562
9563 if (!json_path) {
9564 vty_out(vty, "\n");
9565 } else {
9566 json_object_object_add(json_path, "overlay", json_overlay);
9567
9568 json_object_array_add(json_paths, json_path);
9569 }
9570 }
9571
9572 /* dampening route */
9573 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9574 struct bgp_path_info *path, int display,
9575 afi_t afi, safi_t safi, bool use_json,
9576 json_object *json_paths)
9577 {
9578 struct attr *attr = path->attr;
9579 int len;
9580 char timebuf[BGP_UPTIME_LEN];
9581 json_object *json_path = NULL;
9582
9583 if (use_json)
9584 json_path = json_object_new_object();
9585
9586 /* short status lead text */
9587 route_vty_short_status_out(vty, path, p, json_path);
9588
9589 /* print prefix and mask */
9590 if (!use_json) {
9591 if (!display)
9592 route_vty_out_route(path->net, p, vty, NULL, false);
9593 else
9594 vty_out(vty, "%*s", 17, " ");
9595
9596 len = vty_out(vty, "%s", path->peer->host);
9597 len = 17 - len;
9598
9599 if (len < 1)
9600 vty_out(vty, "\n%*s", 34, " ");
9601 else
9602 vty_out(vty, "%*s", len, " ");
9603
9604 vty_out(vty, "%s ",
9605 bgp_damp_reuse_time_vty(vty, path, timebuf,
9606 BGP_UPTIME_LEN, afi, safi,
9607 use_json, NULL));
9608
9609 if (attr->aspath)
9610 aspath_print_vty(vty, "%s", attr->aspath, " ");
9611
9612 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9613
9614 vty_out(vty, "\n");
9615 } else {
9616 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9617 safi, use_json, json_path);
9618
9619 if (attr->aspath)
9620 json_object_string_add(json_path, "asPath",
9621 attr->aspath->str);
9622
9623 json_object_string_add(json_path, "origin",
9624 bgp_origin_str[attr->origin]);
9625 json_object_string_add(json_path, "peerHost", path->peer->host);
9626
9627 json_object_array_add(json_paths, json_path);
9628 }
9629 }
9630
9631 /* flap route */
9632 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9633 struct bgp_path_info *path, int display,
9634 afi_t afi, safi_t safi, bool use_json,
9635 json_object *json_paths)
9636 {
9637 struct attr *attr = path->attr;
9638 struct bgp_damp_info *bdi;
9639 char timebuf[BGP_UPTIME_LEN];
9640 int len;
9641 json_object *json_path = NULL;
9642
9643 if (!path->extra)
9644 return;
9645
9646 if (use_json)
9647 json_path = json_object_new_object();
9648
9649 bdi = path->extra->damp_info;
9650
9651 /* short status lead text */
9652 route_vty_short_status_out(vty, path, p, json_path);
9653
9654 if (!use_json) {
9655 if (!display)
9656 route_vty_out_route(path->net, p, vty, NULL, false);
9657 else
9658 vty_out(vty, "%*s", 17, " ");
9659
9660 len = vty_out(vty, "%s", path->peer->host);
9661 len = 16 - len;
9662 if (len < 1)
9663 vty_out(vty, "\n%*s", 33, " ");
9664 else
9665 vty_out(vty, "%*s", len, " ");
9666
9667 len = vty_out(vty, "%d", bdi->flap);
9668 len = 5 - len;
9669 if (len < 1)
9670 vty_out(vty, " ");
9671 else
9672 vty_out(vty, "%*s", len, " ");
9673
9674 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9675 BGP_UPTIME_LEN, 0, NULL));
9676
9677 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9678 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9679 vty_out(vty, "%s ",
9680 bgp_damp_reuse_time_vty(vty, path, timebuf,
9681 BGP_UPTIME_LEN, afi,
9682 safi, use_json, NULL));
9683 else
9684 vty_out(vty, "%*s ", 8, " ");
9685
9686 if (attr->aspath)
9687 aspath_print_vty(vty, "%s", attr->aspath, " ");
9688
9689 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9690
9691 vty_out(vty, "\n");
9692 } else {
9693 json_object_string_add(json_path, "peerHost", path->peer->host);
9694 json_object_int_add(json_path, "bdiFlap", bdi->flap);
9695
9696 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9697 json_path);
9698
9699 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9700 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9701 bgp_damp_reuse_time_vty(vty, path, timebuf,
9702 BGP_UPTIME_LEN, afi, safi,
9703 use_json, json_path);
9704
9705 if (attr->aspath)
9706 json_object_string_add(json_path, "asPath",
9707 attr->aspath->str);
9708
9709 json_object_string_add(json_path, "origin",
9710 bgp_origin_str[attr->origin]);
9711
9712 json_object_array_add(json_paths, json_path);
9713 }
9714 }
9715
9716 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9717 int *first, const char *header,
9718 json_object *json_adv_to)
9719 {
9720 char buf1[INET6_ADDRSTRLEN];
9721 json_object *json_peer = NULL;
9722
9723 if (json_adv_to) {
9724 /* 'advertised-to' is a dictionary of peers we have advertised
9725 * this
9726 * prefix too. The key is the peer's IP or swpX, the value is
9727 * the
9728 * hostname if we know it and "" if not.
9729 */
9730 json_peer = json_object_new_object();
9731
9732 if (peer->hostname)
9733 json_object_string_add(json_peer, "hostname",
9734 peer->hostname);
9735
9736 if (peer->conf_if)
9737 json_object_object_add(json_adv_to, peer->conf_if,
9738 json_peer);
9739 else
9740 json_object_object_add(
9741 json_adv_to,
9742 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
9743 json_peer);
9744 } else {
9745 if (*first) {
9746 vty_out(vty, "%s", header);
9747 *first = 0;
9748 }
9749
9750 if (peer->hostname
9751 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9752 if (peer->conf_if)
9753 vty_out(vty, " %s(%s)", peer->hostname,
9754 peer->conf_if);
9755 else
9756 vty_out(vty, " %s(%s)", peer->hostname,
9757 sockunion2str(&peer->su, buf1,
9758 SU_ADDRSTRLEN));
9759 } else {
9760 if (peer->conf_if)
9761 vty_out(vty, " %s", peer->conf_if);
9762 else
9763 vty_out(vty, " %s",
9764 sockunion2str(&peer->su, buf1,
9765 SU_ADDRSTRLEN));
9766 }
9767 }
9768 }
9769
9770 static void route_vty_out_tx_ids(struct vty *vty,
9771 struct bgp_addpath_info_data *d)
9772 {
9773 int i;
9774
9775 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9776 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9777 d->addpath_tx_id[i],
9778 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9779 }
9780 }
9781
9782 static void route_vty_out_detail_es_info(struct vty *vty,
9783 struct bgp_path_info *pi,
9784 struct attr *attr,
9785 json_object *json_path)
9786 {
9787 char esi_buf[ESI_STR_LEN];
9788 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9789 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9790 ATTR_ES_PEER_ROUTER);
9791 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9792 ATTR_ES_PEER_ACTIVE);
9793 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9794 ATTR_ES_PEER_PROXY);
9795 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9796 if (json_path) {
9797 json_object *json_es_info = NULL;
9798
9799 json_object_string_add(
9800 json_path, "esi",
9801 esi_buf);
9802 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9803 json_es_info = json_object_new_object();
9804 if (es_local)
9805 json_object_boolean_true_add(
9806 json_es_info, "localEs");
9807 if (peer_active)
9808 json_object_boolean_true_add(
9809 json_es_info, "peerActive");
9810 if (peer_proxy)
9811 json_object_boolean_true_add(
9812 json_es_info, "peerProxy");
9813 if (peer_router)
9814 json_object_boolean_true_add(
9815 json_es_info, "peerRouter");
9816 if (attr->mm_sync_seqnum)
9817 json_object_int_add(
9818 json_es_info, "peerSeq",
9819 attr->mm_sync_seqnum);
9820 json_object_object_add(
9821 json_path, "es_info",
9822 json_es_info);
9823 }
9824 } else {
9825 if (bgp_evpn_attr_is_sync(attr))
9826 vty_out(vty,
9827 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9828 esi_buf,
9829 es_local ? "local-es":"",
9830 peer_proxy ? "proxy " : "",
9831 peer_active ? "active ":"",
9832 peer_router ? "router ":"",
9833 attr->mm_sync_seqnum);
9834 else
9835 vty_out(vty, " ESI %s %s\n",
9836 esi_buf,
9837 es_local ? "local-es":"");
9838 }
9839 }
9840
9841 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
9842 struct bgp_path_info *path, afi_t afi, safi_t safi,
9843 enum rpki_states rpki_curr_state,
9844 json_object *json_paths)
9845 {
9846 char buf[INET6_ADDRSTRLEN];
9847 char buf1[BUFSIZ];
9848 struct attr *attr = path->attr;
9849 int sockunion_vty_out(struct vty *, union sockunion *);
9850 time_t tbuf;
9851 json_object *json_bestpath = NULL;
9852 json_object *json_cluster_list = NULL;
9853 json_object *json_cluster_list_list = NULL;
9854 json_object *json_ext_community = NULL;
9855 json_object *json_last_update = NULL;
9856 json_object *json_pmsi = NULL;
9857 json_object *json_nexthop_global = NULL;
9858 json_object *json_nexthop_ll = NULL;
9859 json_object *json_nexthops = NULL;
9860 json_object *json_path = NULL;
9861 json_object *json_peer = NULL;
9862 json_object *json_string = NULL;
9863 json_object *json_adv_to = NULL;
9864 int first = 0;
9865 struct listnode *node, *nnode;
9866 struct peer *peer;
9867 bool addpath_capable;
9868 int has_adj;
9869 unsigned int first_as;
9870 bool nexthop_self =
9871 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9872 int i;
9873 char *nexthop_hostname =
9874 bgp_nexthop_hostname(path->peer, path->nexthop);
9875
9876 if (json_paths) {
9877 json_path = json_object_new_object();
9878 json_peer = json_object_new_object();
9879 json_nexthop_global = json_object_new_object();
9880 }
9881
9882 if (safi == SAFI_EVPN) {
9883 if (!json_paths)
9884 vty_out(vty, " Route %pRN", bn);
9885 }
9886
9887 if (path->extra) {
9888 char tag_buf[30];
9889
9890 tag_buf[0] = '\0';
9891 if (path->extra && path->extra->num_labels) {
9892 bgp_evpn_label2str(path->extra->label,
9893 path->extra->num_labels, tag_buf,
9894 sizeof(tag_buf));
9895 }
9896 if (safi == SAFI_EVPN) {
9897 if (!json_paths) {
9898 if (tag_buf[0] != '\0')
9899 vty_out(vty, " VNI %s", tag_buf);
9900 } else {
9901 if (tag_buf[0])
9902 json_object_string_add(json_path, "VNI",
9903 tag_buf);
9904 }
9905 }
9906
9907 if (path->extra && path->extra->parent && !json_paths) {
9908 struct bgp_path_info *parent_ri;
9909 struct bgp_dest *dest, *pdest;
9910
9911 parent_ri = (struct bgp_path_info *)path->extra->parent;
9912 dest = parent_ri->net;
9913 if (dest && dest->pdest) {
9914 pdest = dest->pdest;
9915 prefix_rd2str(
9916 (struct prefix_rd *)bgp_dest_get_prefix(
9917 pdest),
9918 buf1, sizeof(buf1));
9919 if (is_pi_family_evpn(parent_ri)) {
9920 vty_out(vty,
9921 " Imported from %s:%pFX, VNI %s",
9922 buf1,
9923 (struct prefix_evpn *)
9924 bgp_dest_get_prefix(
9925 dest),
9926 tag_buf);
9927 if (attr->es_flags & ATTR_ES_L3_NHG)
9928 vty_out(vty, ", L3NHG %s",
9929 (attr->es_flags
9930 & ATTR_ES_L3_NHG_ACTIVE)
9931 ? "active"
9932 : "inactive");
9933 vty_out(vty, "\n");
9934
9935 } else
9936 vty_out(vty,
9937 " Imported from %s:%pFX\n",
9938 buf1,
9939 (struct prefix_evpn *)
9940 bgp_dest_get_prefix(
9941 dest));
9942 }
9943 }
9944 }
9945
9946 if (safi == SAFI_EVPN
9947 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
9948 char gwip_buf[INET6_ADDRSTRLEN];
9949
9950 ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf,
9951 sizeof(gwip_buf));
9952
9953 if (json_paths)
9954 json_object_string_add(json_path, "gatewayIP",
9955 gwip_buf);
9956 else
9957 vty_out(vty, " Gateway IP %s", gwip_buf);
9958 }
9959
9960 if (safi == SAFI_EVPN)
9961 vty_out(vty, "\n");
9962
9963 /* Line1 display AS-path, Aggregator */
9964 if (attr->aspath) {
9965 if (json_paths) {
9966 if (!attr->aspath->json)
9967 aspath_str_update(attr->aspath, true);
9968 json_object_lock(attr->aspath->json);
9969 json_object_object_add(json_path, "aspath",
9970 attr->aspath->json);
9971 } else {
9972 if (attr->aspath->segments)
9973 aspath_print_vty(vty, " %s", attr->aspath, "");
9974 else
9975 vty_out(vty, " Local");
9976 }
9977 }
9978
9979 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9980 if (json_paths)
9981 json_object_boolean_true_add(json_path, "removed");
9982 else
9983 vty_out(vty, ", (removed)");
9984 }
9985
9986 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9987 if (json_paths)
9988 json_object_boolean_true_add(json_path, "stale");
9989 else
9990 vty_out(vty, ", (stale)");
9991 }
9992
9993 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
9994 if (json_paths) {
9995 json_object_int_add(json_path, "aggregatorAs",
9996 attr->aggregator_as);
9997 json_object_string_addf(json_path, "aggregatorId",
9998 "%pI4", &attr->aggregator_addr);
9999 } else {
10000 vty_out(vty, ", (aggregated by %u %pI4)",
10001 attr->aggregator_as, &attr->aggregator_addr);
10002 }
10003 }
10004
10005 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10006 PEER_FLAG_REFLECTOR_CLIENT)) {
10007 if (json_paths)
10008 json_object_boolean_true_add(json_path,
10009 "rxedFromRrClient");
10010 else
10011 vty_out(vty, ", (Received from a RR-client)");
10012 }
10013
10014 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10015 PEER_FLAG_RSERVER_CLIENT)) {
10016 if (json_paths)
10017 json_object_boolean_true_add(json_path,
10018 "rxedFromRsClient");
10019 else
10020 vty_out(vty, ", (Received from a RS-client)");
10021 }
10022
10023 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10024 if (json_paths)
10025 json_object_boolean_true_add(json_path,
10026 "dampeningHistoryEntry");
10027 else
10028 vty_out(vty, ", (history entry)");
10029 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10030 if (json_paths)
10031 json_object_boolean_true_add(json_path,
10032 "dampeningSuppressed");
10033 else
10034 vty_out(vty, ", (suppressed due to dampening)");
10035 }
10036
10037 if (!json_paths)
10038 vty_out(vty, "\n");
10039
10040 /* Line2 display Next-hop, Neighbor, Router-id */
10041 /* Display the nexthop */
10042 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10043
10044 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
10045 || bn_p->family == AF_EVPN)
10046 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
10047 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
10048 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10049 || safi == SAFI_EVPN) {
10050 if (json_paths) {
10051 json_object_string_addf(
10052 json_nexthop_global, "ip", "%pI4",
10053 &attr->mp_nexthop_global_in);
10054
10055 if (path->peer->hostname)
10056 json_object_string_add(
10057 json_nexthop_global, "hostname",
10058 path->peer->hostname);
10059 } else {
10060 if (nexthop_hostname)
10061 vty_out(vty, " %pI4(%s)",
10062 &attr->mp_nexthop_global_in,
10063 nexthop_hostname);
10064 else
10065 vty_out(vty, " %pI4",
10066 &attr->mp_nexthop_global_in);
10067 }
10068 } else {
10069 if (json_paths) {
10070 json_object_string_addf(json_nexthop_global,
10071 "ip", "%pI4",
10072 &attr->nexthop);
10073
10074 if (path->peer->hostname)
10075 json_object_string_add(
10076 json_nexthop_global, "hostname",
10077 path->peer->hostname);
10078 } else {
10079 if (nexthop_hostname)
10080 vty_out(vty, " %pI4(%s)",
10081 &attr->nexthop,
10082 nexthop_hostname);
10083 else
10084 vty_out(vty, " %pI4",
10085 &attr->nexthop);
10086 }
10087 }
10088
10089 if (json_paths)
10090 json_object_string_add(json_nexthop_global, "afi",
10091 "ipv4");
10092 } else {
10093 if (json_paths) {
10094 json_object_string_addf(json_nexthop_global, "ip",
10095 "%pI6",
10096 &attr->mp_nexthop_global);
10097
10098 if (path->peer->hostname)
10099 json_object_string_add(json_nexthop_global,
10100 "hostname",
10101 path->peer->hostname);
10102
10103 json_object_string_add(json_nexthop_global, "afi",
10104 "ipv6");
10105 json_object_string_add(json_nexthop_global, "scope",
10106 "global");
10107 } else {
10108 if (nexthop_hostname)
10109 vty_out(vty, " %pI6(%s)",
10110 &attr->mp_nexthop_global,
10111 nexthop_hostname);
10112 else
10113 vty_out(vty, " %pI6",
10114 &attr->mp_nexthop_global);
10115 }
10116 }
10117
10118 /* Display the IGP cost or 'inaccessible' */
10119 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10120 if (json_paths)
10121 json_object_boolean_false_add(json_nexthop_global,
10122 "accessible");
10123 else
10124 vty_out(vty, " (inaccessible)");
10125 } else {
10126 if (path->extra && path->extra->igpmetric) {
10127 if (json_paths)
10128 json_object_int_add(json_nexthop_global,
10129 "metric",
10130 path->extra->igpmetric);
10131 else
10132 vty_out(vty, " (metric %u)",
10133 path->extra->igpmetric);
10134 }
10135
10136 /* IGP cost is 0, display this only for json */
10137 else {
10138 if (json_paths)
10139 json_object_int_add(json_nexthop_global,
10140 "metric", 0);
10141 }
10142
10143 if (json_paths)
10144 json_object_boolean_true_add(json_nexthop_global,
10145 "accessible");
10146 }
10147
10148 /* Display peer "from" output */
10149 /* This path was originated locally */
10150 if (path->peer == bgp->peer_self) {
10151
10152 if (safi == SAFI_EVPN
10153 || (bn_p->family == AF_INET
10154 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
10155 if (json_paths)
10156 json_object_string_add(json_peer, "peerId",
10157 "0.0.0.0");
10158 else
10159 vty_out(vty, " from 0.0.0.0 ");
10160 } else {
10161 if (json_paths)
10162 json_object_string_add(json_peer, "peerId",
10163 "::");
10164 else
10165 vty_out(vty, " from :: ");
10166 }
10167
10168 if (json_paths)
10169 json_object_string_addf(json_peer, "routerId", "%pI4",
10170 &bgp->router_id);
10171 else
10172 vty_out(vty, "(%pI4)", &bgp->router_id);
10173 }
10174
10175 /* We RXed this path from one of our peers */
10176 else {
10177
10178 if (json_paths) {
10179 json_object_string_add(json_peer, "peerId",
10180 sockunion2str(&path->peer->su,
10181 buf,
10182 SU_ADDRSTRLEN));
10183 json_object_string_addf(json_peer, "routerId", "%pI4",
10184 &path->peer->remote_id);
10185
10186 if (path->peer->hostname)
10187 json_object_string_add(json_peer, "hostname",
10188 path->peer->hostname);
10189
10190 if (path->peer->domainname)
10191 json_object_string_add(json_peer, "domainname",
10192 path->peer->domainname);
10193
10194 if (path->peer->conf_if)
10195 json_object_string_add(json_peer, "interface",
10196 path->peer->conf_if);
10197 } else {
10198 if (path->peer->conf_if) {
10199 if (path->peer->hostname
10200 && CHECK_FLAG(path->peer->bgp->flags,
10201 BGP_FLAG_SHOW_HOSTNAME))
10202 vty_out(vty, " from %s(%s)",
10203 path->peer->hostname,
10204 path->peer->conf_if);
10205 else
10206 vty_out(vty, " from %s",
10207 path->peer->conf_if);
10208 } else {
10209 if (path->peer->hostname
10210 && CHECK_FLAG(path->peer->bgp->flags,
10211 BGP_FLAG_SHOW_HOSTNAME))
10212 vty_out(vty, " from %s(%s)",
10213 path->peer->hostname,
10214 path->peer->host);
10215 else
10216 vty_out(vty, " from %s",
10217 sockunion2str(&path->peer->su,
10218 buf,
10219 SU_ADDRSTRLEN));
10220 }
10221
10222 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10223 vty_out(vty, " (%pI4)", &attr->originator_id);
10224 else
10225 vty_out(vty, " (%s)",
10226 inet_ntop(AF_INET,
10227 &path->peer->remote_id, buf1,
10228 sizeof(buf1)));
10229 }
10230 }
10231
10232 /*
10233 * Note when vrfid of nexthop is different from that of prefix
10234 */
10235 if (path->extra && path->extra->bgp_orig) {
10236 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10237
10238 if (json_paths) {
10239 const char *vn;
10240
10241 if (path->extra->bgp_orig->inst_type
10242 == BGP_INSTANCE_TYPE_DEFAULT)
10243 vn = VRF_DEFAULT_NAME;
10244 else
10245 vn = path->extra->bgp_orig->name;
10246
10247 json_object_string_add(json_path, "nhVrfName", vn);
10248
10249 if (nexthop_vrfid == VRF_UNKNOWN) {
10250 json_object_int_add(json_path, "nhVrfId", -1);
10251 } else {
10252 json_object_int_add(json_path, "nhVrfId",
10253 (int)nexthop_vrfid);
10254 }
10255 } else {
10256 if (nexthop_vrfid == VRF_UNKNOWN)
10257 vty_out(vty, " vrf ?");
10258 else {
10259 struct vrf *vrf;
10260
10261 vrf = vrf_lookup_by_id(nexthop_vrfid);
10262 vty_out(vty, " vrf %s(%u)",
10263 VRF_LOGNAME(vrf), nexthop_vrfid);
10264 }
10265 }
10266 }
10267
10268 if (nexthop_self) {
10269 if (json_paths) {
10270 json_object_boolean_true_add(json_path,
10271 "announceNexthopSelf");
10272 } else {
10273 vty_out(vty, " announce-nh-self");
10274 }
10275 }
10276
10277 if (!json_paths)
10278 vty_out(vty, "\n");
10279
10280 /* display the link-local nexthop */
10281 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10282 if (json_paths) {
10283 json_nexthop_ll = json_object_new_object();
10284 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10285 &attr->mp_nexthop_local);
10286
10287 if (path->peer->hostname)
10288 json_object_string_add(json_nexthop_ll,
10289 "hostname",
10290 path->peer->hostname);
10291
10292 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10293 json_object_string_add(json_nexthop_ll, "scope",
10294 "link-local");
10295
10296 json_object_boolean_true_add(json_nexthop_ll,
10297 "accessible");
10298
10299 if (!attr->mp_nexthop_prefer_global)
10300 json_object_boolean_true_add(json_nexthop_ll,
10301 "used");
10302 else
10303 json_object_boolean_true_add(
10304 json_nexthop_global, "used");
10305 } else {
10306 vty_out(vty, " (%s) %s\n",
10307 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10308 buf, INET6_ADDRSTRLEN),
10309 attr->mp_nexthop_prefer_global
10310 ? "(prefer-global)"
10311 : "(used)");
10312 }
10313 }
10314 /* If we do not have a link-local nexthop then we must flag the
10315 global as "used" */
10316 else {
10317 if (json_paths)
10318 json_object_boolean_true_add(json_nexthop_global,
10319 "used");
10320 }
10321
10322 if (safi == SAFI_EVPN &&
10323 bgp_evpn_is_esi_valid(&attr->esi)) {
10324 route_vty_out_detail_es_info(vty, path, attr, json_path);
10325 }
10326
10327 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10328 * Int/Ext/Local, Atomic, best */
10329 if (json_paths)
10330 json_object_string_add(json_path, "origin",
10331 bgp_origin_long_str[attr->origin]);
10332 else
10333 vty_out(vty, " Origin %s",
10334 bgp_origin_long_str[attr->origin]);
10335
10336 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10337 if (json_paths)
10338 json_object_int_add(json_path, "metric", attr->med);
10339 else
10340 vty_out(vty, ", metric %u", attr->med);
10341 }
10342
10343 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10344 if (json_paths)
10345 json_object_int_add(json_path, "locPrf",
10346 attr->local_pref);
10347 else
10348 vty_out(vty, ", localpref %u", attr->local_pref);
10349 }
10350
10351 if (attr->weight != 0) {
10352 if (json_paths)
10353 json_object_int_add(json_path, "weight", attr->weight);
10354 else
10355 vty_out(vty, ", weight %u", attr->weight);
10356 }
10357
10358 if (attr->tag != 0) {
10359 if (json_paths)
10360 json_object_int_add(json_path, "tag", attr->tag);
10361 else
10362 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10363 }
10364
10365 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10366 if (json_paths)
10367 json_object_boolean_false_add(json_path, "valid");
10368 else
10369 vty_out(vty, ", invalid");
10370 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10371 if (json_paths)
10372 json_object_boolean_true_add(json_path, "valid");
10373 else
10374 vty_out(vty, ", valid");
10375 }
10376
10377 if (json_paths)
10378 json_object_int_add(json_path, "version", bn->version);
10379
10380 if (path->peer != bgp->peer_self) {
10381 if (path->peer->as == path->peer->local_as) {
10382 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10383 if (json_paths)
10384 json_object_string_add(
10385 json_peer, "type",
10386 "confed-internal");
10387 else
10388 vty_out(vty, ", confed-internal");
10389 } else {
10390 if (json_paths)
10391 json_object_string_add(
10392 json_peer, "type", "internal");
10393 else
10394 vty_out(vty, ", internal");
10395 }
10396 } else {
10397 if (bgp_confederation_peers_check(bgp,
10398 path->peer->as)) {
10399 if (json_paths)
10400 json_object_string_add(
10401 json_peer, "type",
10402 "confed-external");
10403 else
10404 vty_out(vty, ", confed-external");
10405 } else {
10406 if (json_paths)
10407 json_object_string_add(
10408 json_peer, "type", "external");
10409 else
10410 vty_out(vty, ", external");
10411 }
10412 }
10413 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10414 if (json_paths) {
10415 json_object_boolean_true_add(json_path, "aggregated");
10416 json_object_boolean_true_add(json_path, "local");
10417 } else {
10418 vty_out(vty, ", aggregated, local");
10419 }
10420 } else if (path->type != ZEBRA_ROUTE_BGP) {
10421 if (json_paths)
10422 json_object_boolean_true_add(json_path, "sourced");
10423 else
10424 vty_out(vty, ", sourced");
10425 } else {
10426 if (json_paths) {
10427 json_object_boolean_true_add(json_path, "sourced");
10428 json_object_boolean_true_add(json_path, "local");
10429 } else {
10430 vty_out(vty, ", sourced, local");
10431 }
10432 }
10433
10434 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10435 if (json_paths)
10436 json_object_boolean_true_add(json_path,
10437 "atomicAggregate");
10438 else
10439 vty_out(vty, ", atomic-aggregate");
10440 }
10441
10442 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10443 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10444 && bgp_path_info_mpath_count(path))) {
10445 if (json_paths)
10446 json_object_boolean_true_add(json_path, "multipath");
10447 else
10448 vty_out(vty, ", multipath");
10449 }
10450
10451 // Mark the bestpath(s)
10452 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10453 first_as = aspath_get_first_as(attr->aspath);
10454
10455 if (json_paths) {
10456 if (!json_bestpath)
10457 json_bestpath = json_object_new_object();
10458 json_object_int_add(json_bestpath, "bestpathFromAs",
10459 first_as);
10460 } else {
10461 if (first_as)
10462 vty_out(vty, ", bestpath-from-AS %u", first_as);
10463 else
10464 vty_out(vty, ", bestpath-from-AS Local");
10465 }
10466 }
10467
10468 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10469 if (json_paths) {
10470 if (!json_bestpath)
10471 json_bestpath = json_object_new_object();
10472 json_object_boolean_true_add(json_bestpath, "overall");
10473 json_object_string_add(
10474 json_bestpath, "selectionReason",
10475 bgp_path_selection_reason2str(bn->reason));
10476 } else {
10477 vty_out(vty, ", best");
10478 vty_out(vty, " (%s)",
10479 bgp_path_selection_reason2str(bn->reason));
10480 }
10481 }
10482
10483 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10484 if (json_paths)
10485 json_object_string_add(
10486 json_path, "rpkiValidationState",
10487 bgp_rpki_validation2str(rpki_curr_state));
10488 else
10489 vty_out(vty, ", rpki validation-state: %s",
10490 bgp_rpki_validation2str(rpki_curr_state));
10491 }
10492
10493 if (json_bestpath)
10494 json_object_object_add(json_path, "bestpath", json_bestpath);
10495
10496 if (!json_paths)
10497 vty_out(vty, "\n");
10498
10499 /* Line 4 display Community */
10500 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10501 if (json_paths) {
10502 if (!bgp_attr_get_community(attr)->json)
10503 community_str(bgp_attr_get_community(attr),
10504 true);
10505 json_object_lock(bgp_attr_get_community(attr)->json);
10506 json_object_object_add(
10507 json_path, "community",
10508 bgp_attr_get_community(attr)->json);
10509 } else {
10510 vty_out(vty, " Community: %s\n",
10511 bgp_attr_get_community(attr)->str);
10512 }
10513 }
10514
10515 /* Line 5 display Extended-community */
10516 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10517 if (json_paths) {
10518 json_ext_community = json_object_new_object();
10519 json_object_string_add(
10520 json_ext_community, "string",
10521 bgp_attr_get_ecommunity(attr)->str);
10522 json_object_object_add(json_path, "extendedCommunity",
10523 json_ext_community);
10524 } else {
10525 vty_out(vty, " Extended Community: %s\n",
10526 bgp_attr_get_ecommunity(attr)->str);
10527 }
10528 }
10529
10530 /* Line 6 display Large community */
10531 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10532 if (json_paths) {
10533 if (!bgp_attr_get_lcommunity(attr)->json)
10534 lcommunity_str(bgp_attr_get_lcommunity(attr),
10535 true);
10536 json_object_lock(bgp_attr_get_lcommunity(attr)->json);
10537 json_object_object_add(
10538 json_path, "largeCommunity",
10539 bgp_attr_get_lcommunity(attr)->json);
10540 } else {
10541 vty_out(vty, " Large Community: %s\n",
10542 bgp_attr_get_lcommunity(attr)->str);
10543 }
10544 }
10545
10546 /* Line 7 display Originator, Cluster-id */
10547 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10548 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10549 char buf[BUFSIZ] = {0};
10550
10551 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10552 if (json_paths)
10553 json_object_string_addf(json_path,
10554 "originatorId", "%pI4",
10555 &attr->originator_id);
10556 else
10557 vty_out(vty, " Originator: %pI4",
10558 &attr->originator_id);
10559 }
10560
10561 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10562 struct cluster_list *cluster =
10563 bgp_attr_get_cluster(attr);
10564 int i;
10565
10566 if (json_paths) {
10567 json_cluster_list = json_object_new_object();
10568 json_cluster_list_list =
10569 json_object_new_array();
10570
10571 for (i = 0; i < cluster->length / 4; i++) {
10572 json_string = json_object_new_string(
10573 inet_ntop(AF_INET,
10574 &cluster->list[i],
10575 buf, sizeof(buf)));
10576 json_object_array_add(
10577 json_cluster_list_list,
10578 json_string);
10579 }
10580
10581 /*
10582 * struct cluster_list does not have
10583 * "str" variable like aspath and community
10584 * do. Add this someday if someone asks
10585 * for it.
10586 * json_object_string_add(json_cluster_list,
10587 * "string", cluster->str);
10588 */
10589 json_object_object_add(json_cluster_list,
10590 "list",
10591 json_cluster_list_list);
10592 json_object_object_add(json_path, "clusterList",
10593 json_cluster_list);
10594 } else {
10595 vty_out(vty, ", Cluster list: ");
10596
10597 for (i = 0; i < cluster->length / 4; i++) {
10598 vty_out(vty, "%pI4 ",
10599 &cluster->list[i]);
10600 }
10601 }
10602 }
10603
10604 if (!json_paths)
10605 vty_out(vty, "\n");
10606 }
10607
10608 if (path->extra && path->extra->damp_info)
10609 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10610
10611 /* Remote Label */
10612 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10613 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10614 mpls_label_t label = label_pton(&path->extra->label[0]);
10615
10616 if (json_paths)
10617 json_object_int_add(json_path, "remoteLabel", label);
10618 else
10619 vty_out(vty, " Remote label: %d\n", label);
10620 }
10621
10622 /* Remote SID */
10623 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10624 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
10625 if (json_paths)
10626 json_object_string_add(json_path, "remoteSid", buf);
10627 else
10628 vty_out(vty, " Remote SID: %s\n", buf);
10629 }
10630
10631 /* Label Index */
10632 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10633 if (json_paths)
10634 json_object_int_add(json_path, "labelIndex",
10635 attr->label_index);
10636 else
10637 vty_out(vty, " Label Index: %d\n",
10638 attr->label_index);
10639 }
10640
10641 /* Line 8 display Addpath IDs */
10642 if (path->addpath_rx_id
10643 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10644 if (json_paths) {
10645 json_object_int_add(json_path, "addpathRxId",
10646 path->addpath_rx_id);
10647
10648 /* Keep backwards compatibility with the old API
10649 * by putting TX All's ID in the old field
10650 */
10651 json_object_int_add(
10652 json_path, "addpathTxId",
10653 path->tx_addpath
10654 .addpath_tx_id[BGP_ADDPATH_ALL]);
10655
10656 /* ... but create a specific field for each
10657 * strategy
10658 */
10659 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10660 json_object_int_add(
10661 json_path,
10662 bgp_addpath_names(i)->id_json_name,
10663 path->tx_addpath.addpath_tx_id[i]);
10664 }
10665 } else {
10666 vty_out(vty, " AddPath ID: RX %u, ",
10667 path->addpath_rx_id);
10668
10669 route_vty_out_tx_ids(vty, &path->tx_addpath);
10670 }
10671 }
10672
10673 /* If we used addpath to TX a non-bestpath we need to display
10674 * "Advertised to" on a path-by-path basis
10675 */
10676 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10677 first = 1;
10678
10679 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10680 addpath_capable =
10681 bgp_addpath_encode_tx(peer, afi, safi);
10682 has_adj = bgp_adj_out_lookup(
10683 peer, path->net,
10684 bgp_addpath_id_for_peer(peer, afi, safi,
10685 &path->tx_addpath));
10686
10687 if ((addpath_capable && has_adj)
10688 || (!addpath_capable && has_adj
10689 && CHECK_FLAG(path->flags,
10690 BGP_PATH_SELECTED))) {
10691 if (json_path && !json_adv_to)
10692 json_adv_to = json_object_new_object();
10693
10694 route_vty_out_advertised_to(
10695 vty, peer, &first,
10696 " Advertised to:", json_adv_to);
10697 }
10698 }
10699
10700 if (json_path) {
10701 if (json_adv_to) {
10702 json_object_object_add(
10703 json_path, "advertisedTo", json_adv_to);
10704 }
10705 } else {
10706 if (!first) {
10707 vty_out(vty, "\n");
10708 }
10709 }
10710 }
10711
10712 /* Line 9 display Uptime */
10713 tbuf = time(NULL) - (bgp_clock() - path->uptime);
10714 if (json_paths) {
10715 json_last_update = json_object_new_object();
10716 json_object_int_add(json_last_update, "epoch", tbuf);
10717 json_object_string_add(json_last_update, "string",
10718 ctime(&tbuf));
10719 json_object_object_add(json_path, "lastUpdate",
10720 json_last_update);
10721 } else
10722 vty_out(vty, " Last update: %s", ctime(&tbuf));
10723
10724 /* Line 10 display PMSI tunnel attribute, if present */
10725 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10726 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10727 bgp_attr_get_pmsi_tnl_type(attr),
10728 PMSI_TNLTYPE_STR_DEFAULT);
10729
10730 if (json_paths) {
10731 json_pmsi = json_object_new_object();
10732 json_object_string_add(json_pmsi, "tunnelType", str);
10733 json_object_int_add(json_pmsi, "label",
10734 label2vni(&attr->label));
10735 json_object_object_add(json_path, "pmsi", json_pmsi);
10736 } else
10737 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10738 str, label2vni(&attr->label));
10739 }
10740
10741 if (path->peer->t_gr_restart &&
10742 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10743 unsigned long gr_remaining =
10744 thread_timer_remain_second(path->peer->t_gr_restart);
10745
10746 if (json_paths) {
10747 json_object_int_add(json_path,
10748 "gracefulRestartSecondsRemaining",
10749 gr_remaining);
10750 } else
10751 vty_out(vty,
10752 " Time until Graceful Restart stale route deleted: %lu\n",
10753 gr_remaining);
10754 }
10755
10756 if (path->peer->t_llgr_stale[afi][safi] &&
10757 bgp_attr_get_community(attr) &&
10758 community_include(bgp_attr_get_community(attr),
10759 COMMUNITY_LLGR_STALE)) {
10760 unsigned long llgr_remaining = thread_timer_remain_second(
10761 path->peer->t_llgr_stale[afi][safi]);
10762
10763 if (json_paths) {
10764 json_object_int_add(json_path, "llgrSecondsRemaining",
10765 llgr_remaining);
10766 } else
10767 vty_out(vty,
10768 " Time until Long-lived stale route deleted: %lu\n",
10769 llgr_remaining);
10770 }
10771
10772 /* Output some debug about internal state of the dest flags */
10773 if (json_paths) {
10774 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10775 json_object_boolean_true_add(json_path, "processScheduled");
10776 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10777 json_object_boolean_true_add(json_path, "userCleared");
10778 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10779 json_object_boolean_true_add(json_path, "labelChanged");
10780 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10781 json_object_boolean_true_add(json_path, "registeredForLabel");
10782 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10783 json_object_boolean_true_add(json_path, "selectDefered");
10784 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10785 json_object_boolean_true_add(json_path, "fibInstalled");
10786 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10787 json_object_boolean_true_add(json_path, "fibPending");
10788
10789 if (json_nexthop_global || json_nexthop_ll) {
10790 json_nexthops = json_object_new_array();
10791
10792 if (json_nexthop_global)
10793 json_object_array_add(json_nexthops,
10794 json_nexthop_global);
10795
10796 if (json_nexthop_ll)
10797 json_object_array_add(json_nexthops,
10798 json_nexthop_ll);
10799
10800 json_object_object_add(json_path, "nexthops",
10801 json_nexthops);
10802 }
10803
10804 json_object_object_add(json_path, "peer", json_peer);
10805 json_object_array_add(json_paths, json_path);
10806 }
10807 }
10808
10809 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10810 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10811 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10812
10813 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10814 afi_t afi, safi_t safi, enum bgp_show_type type,
10815 bool use_json);
10816 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10817 const char *comstr, int exact, afi_t afi,
10818 safi_t safi, uint16_t show_flags);
10819
10820 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10821 struct bgp_table *table, enum bgp_show_type type,
10822 void *output_arg, const char *rd, int is_last,
10823 unsigned long *output_cum, unsigned long *total_cum,
10824 unsigned long *json_header_depth, uint16_t show_flags,
10825 enum rpki_states rpki_target_state)
10826 {
10827 struct bgp_path_info *pi;
10828 struct bgp_dest *dest;
10829 bool header = true;
10830 bool json_detail_header = false;
10831 int display;
10832 unsigned long output_count = 0;
10833 unsigned long total_count = 0;
10834 struct prefix *p;
10835 json_object *json_paths = NULL;
10836 int first = 1;
10837 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10838 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10839 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10840
10841 if (output_cum && *output_cum != 0)
10842 header = false;
10843
10844 if (use_json && !*json_header_depth) {
10845 if (all)
10846 *json_header_depth = 1;
10847 else {
10848 vty_out(vty, "{\n");
10849 *json_header_depth = 2;
10850 }
10851
10852 vty_out(vty,
10853 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10854 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10855 " \"localAS\": %u,\n \"routes\": { ",
10856 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10857 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
10858 ? VRF_DEFAULT_NAME
10859 : bgp->name,
10860 table->version, &bgp->router_id,
10861 bgp->default_local_pref, bgp->as);
10862 if (rd) {
10863 vty_out(vty, " \"routeDistinguishers\" : {");
10864 ++*json_header_depth;
10865 }
10866 }
10867
10868 if (use_json && rd) {
10869 vty_out(vty, " \"%s\" : { ", rd);
10870 }
10871
10872 /* Check for 'json detail', where we need header output once per dest */
10873 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
10874 type != bgp_show_type_dampend_paths &&
10875 type != bgp_show_type_damp_neighbor &&
10876 type != bgp_show_type_flap_statistics &&
10877 type != bgp_show_type_flap_neighbor)
10878 json_detail_header = true;
10879
10880 /* Start processing of routes. */
10881 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
10882 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10883 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
10884 bool json_detail = json_detail_header;
10885
10886 pi = bgp_dest_get_bgp_path_info(dest);
10887 if (pi == NULL)
10888 continue;
10889
10890 display = 0;
10891 if (use_json)
10892 json_paths = json_object_new_array();
10893 else
10894 json_paths = NULL;
10895
10896 for (; pi; pi = pi->next) {
10897 struct community *picomm = NULL;
10898
10899 picomm = bgp_attr_get_community(pi->attr);
10900
10901 total_count++;
10902
10903 if (type == bgp_show_type_prefix_version) {
10904 uint32_t version =
10905 strtoul(output_arg, NULL, 10);
10906 if (dest->version < version)
10907 continue;
10908 }
10909
10910 if (type == bgp_show_type_community_alias) {
10911 char *alias = output_arg;
10912 char **communities;
10913 int num;
10914 bool found = false;
10915
10916 if (picomm) {
10917 frrstr_split(picomm->str, " ",
10918 &communities, &num);
10919 for (int i = 0; i < num; i++) {
10920 const char *com2alias =
10921 bgp_community2alias(
10922 communities[i]);
10923 if (!found
10924 && strcmp(alias, com2alias)
10925 == 0)
10926 found = true;
10927 XFREE(MTYPE_TMP,
10928 communities[i]);
10929 }
10930 XFREE(MTYPE_TMP, communities);
10931 }
10932
10933 if (!found &&
10934 bgp_attr_get_lcommunity(pi->attr)) {
10935 frrstr_split(bgp_attr_get_lcommunity(
10936 pi->attr)
10937 ->str,
10938 " ", &communities, &num);
10939 for (int i = 0; i < num; i++) {
10940 const char *com2alias =
10941 bgp_community2alias(
10942 communities[i]);
10943 if (!found
10944 && strcmp(alias, com2alias)
10945 == 0)
10946 found = true;
10947 XFREE(MTYPE_TMP,
10948 communities[i]);
10949 }
10950 XFREE(MTYPE_TMP, communities);
10951 }
10952
10953 if (!found)
10954 continue;
10955 }
10956
10957 if (type == bgp_show_type_rpki) {
10958 if (dest_p->family == AF_INET
10959 || dest_p->family == AF_INET6)
10960 rpki_curr_state = hook_call(
10961 bgp_rpki_prefix_status,
10962 pi->peer, pi->attr, dest_p);
10963 if (rpki_target_state != RPKI_NOT_BEING_USED
10964 && rpki_curr_state != rpki_target_state)
10965 continue;
10966 }
10967
10968 if (type == bgp_show_type_flap_statistics
10969 || type == bgp_show_type_flap_neighbor
10970 || type == bgp_show_type_dampend_paths
10971 || type == bgp_show_type_damp_neighbor) {
10972 if (!(pi->extra && pi->extra->damp_info))
10973 continue;
10974 }
10975 if (type == bgp_show_type_regexp) {
10976 regex_t *regex = output_arg;
10977
10978 if (bgp_regexec(regex, pi->attr->aspath)
10979 == REG_NOMATCH)
10980 continue;
10981 }
10982 if (type == bgp_show_type_prefix_list) {
10983 struct prefix_list *plist = output_arg;
10984
10985 if (prefix_list_apply(plist, dest_p)
10986 != PREFIX_PERMIT)
10987 continue;
10988 }
10989 if (type == bgp_show_type_filter_list) {
10990 struct as_list *as_list = output_arg;
10991
10992 if (as_list_apply(as_list, pi->attr->aspath)
10993 != AS_FILTER_PERMIT)
10994 continue;
10995 }
10996 if (type == bgp_show_type_route_map) {
10997 struct route_map *rmap = output_arg;
10998 struct bgp_path_info path;
10999 struct attr dummy_attr;
11000 route_map_result_t ret;
11001
11002 dummy_attr = *pi->attr;
11003
11004 path.peer = pi->peer;
11005 path.attr = &dummy_attr;
11006
11007 ret = route_map_apply(rmap, dest_p, &path);
11008 bgp_attr_flush(&dummy_attr);
11009 if (ret == RMAP_DENYMATCH)
11010 continue;
11011 }
11012 if (type == bgp_show_type_neighbor
11013 || type == bgp_show_type_flap_neighbor
11014 || type == bgp_show_type_damp_neighbor) {
11015 union sockunion *su = output_arg;
11016
11017 if (pi->peer == NULL
11018 || pi->peer->su_remote == NULL
11019 || !sockunion_same(pi->peer->su_remote, su))
11020 continue;
11021 }
11022 if (type == bgp_show_type_cidr_only) {
11023 uint32_t destination;
11024
11025 destination = ntohl(dest_p->u.prefix4.s_addr);
11026 if (IN_CLASSC(destination)
11027 && dest_p->prefixlen == 24)
11028 continue;
11029 if (IN_CLASSB(destination)
11030 && dest_p->prefixlen == 16)
11031 continue;
11032 if (IN_CLASSA(destination)
11033 && dest_p->prefixlen == 8)
11034 continue;
11035 }
11036 if (type == bgp_show_type_prefix_longer) {
11037 p = output_arg;
11038 if (!prefix_match(p, dest_p))
11039 continue;
11040 }
11041 if (type == bgp_show_type_community_all) {
11042 if (!picomm)
11043 continue;
11044 }
11045 if (type == bgp_show_type_community) {
11046 struct community *com = output_arg;
11047
11048 if (!picomm || !community_match(picomm, com))
11049 continue;
11050 }
11051 if (type == bgp_show_type_community_exact) {
11052 struct community *com = output_arg;
11053
11054 if (!picomm || !community_cmp(picomm, com))
11055 continue;
11056 }
11057 if (type == bgp_show_type_community_list) {
11058 struct community_list *list = output_arg;
11059
11060 if (!community_list_match(picomm, list))
11061 continue;
11062 }
11063 if (type == bgp_show_type_community_list_exact) {
11064 struct community_list *list = output_arg;
11065
11066 if (!community_list_exact_match(picomm, list))
11067 continue;
11068 }
11069 if (type == bgp_show_type_lcommunity) {
11070 struct lcommunity *lcom = output_arg;
11071
11072 if (!bgp_attr_get_lcommunity(pi->attr) ||
11073 !lcommunity_match(
11074 bgp_attr_get_lcommunity(pi->attr),
11075 lcom))
11076 continue;
11077 }
11078
11079 if (type == bgp_show_type_lcommunity_exact) {
11080 struct lcommunity *lcom = output_arg;
11081
11082 if (!bgp_attr_get_lcommunity(pi->attr) ||
11083 !lcommunity_cmp(
11084 bgp_attr_get_lcommunity(pi->attr),
11085 lcom))
11086 continue;
11087 }
11088 if (type == bgp_show_type_lcommunity_list) {
11089 struct community_list *list = output_arg;
11090
11091 if (!lcommunity_list_match(
11092 bgp_attr_get_lcommunity(pi->attr),
11093 list))
11094 continue;
11095 }
11096 if (type
11097 == bgp_show_type_lcommunity_list_exact) {
11098 struct community_list *list = output_arg;
11099
11100 if (!lcommunity_list_exact_match(
11101 bgp_attr_get_lcommunity(pi->attr),
11102 list))
11103 continue;
11104 }
11105 if (type == bgp_show_type_lcommunity_all) {
11106 if (!bgp_attr_get_lcommunity(pi->attr))
11107 continue;
11108 }
11109 if (type == bgp_show_type_dampend_paths
11110 || type == bgp_show_type_damp_neighbor) {
11111 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11112 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11113 continue;
11114 }
11115
11116 if (!use_json && header) {
11117 vty_out(vty,
11118 "BGP table version is %" PRIu64
11119 ", local router ID is %pI4, vrf id ",
11120 table->version, &bgp->router_id);
11121 if (bgp->vrf_id == VRF_UNKNOWN)
11122 vty_out(vty, "%s", VRFID_NONE_STR);
11123 else
11124 vty_out(vty, "%u", bgp->vrf_id);
11125 vty_out(vty, "\n");
11126 vty_out(vty, "Default local pref %u, ",
11127 bgp->default_local_pref);
11128 vty_out(vty, "local AS %u\n", bgp->as);
11129 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11130 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11131 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11132 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11133 if (type == bgp_show_type_dampend_paths
11134 || type == bgp_show_type_damp_neighbor)
11135 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11136 else if (type == bgp_show_type_flap_statistics
11137 || type == bgp_show_type_flap_neighbor)
11138 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11139 else
11140 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11141 : BGP_SHOW_HEADER));
11142 header = false;
11143
11144 } else if (json_detail && json_paths != NULL) {
11145 const struct prefix_rd *prd;
11146 json_object *jtemp;
11147
11148 /* Use common detail header, for most types;
11149 * need a json 'object'.
11150 */
11151
11152 jtemp = json_object_new_object();
11153 prd = bgp_rd_from_dest(dest, safi);
11154
11155 route_vty_out_detail_header(
11156 vty, bgp, dest, prd, table->afi,
11157 safi, jtemp);
11158
11159 json_object_array_add(json_paths, jtemp);
11160
11161 json_detail = false;
11162 }
11163
11164 if (rd != NULL && !display && !output_count) {
11165 if (!use_json)
11166 vty_out(vty,
11167 "Route Distinguisher: %s\n",
11168 rd);
11169 }
11170 if (type == bgp_show_type_dampend_paths
11171 || type == bgp_show_type_damp_neighbor)
11172 damp_route_vty_out(vty, dest_p, pi, display,
11173 AFI_IP, safi, use_json,
11174 json_paths);
11175 else if (type == bgp_show_type_flap_statistics
11176 || type == bgp_show_type_flap_neighbor)
11177 flap_route_vty_out(vty, dest_p, pi, display,
11178 AFI_IP, safi, use_json,
11179 json_paths);
11180 else {
11181 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11182 route_vty_out_detail(
11183 vty, bgp, dest, pi,
11184 family2afi(dest_p->family),
11185 safi, RPKI_NOT_BEING_USED,
11186 json_paths);
11187 else
11188 route_vty_out(vty, dest_p, pi, display,
11189 safi, json_paths, wide);
11190 }
11191 display++;
11192 }
11193
11194 if (display) {
11195 output_count++;
11196 if (!use_json)
11197 continue;
11198
11199 /* encode prefix */
11200 if (dest_p->family == AF_FLOWSPEC) {
11201 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11202
11203
11204 bgp_fs_nlri_get_string(
11205 (unsigned char *)
11206 dest_p->u.prefix_flowspec.ptr,
11207 dest_p->u.prefix_flowspec.prefixlen,
11208 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11209 family2afi(dest_p->u
11210 .prefix_flowspec.family));
11211 if (first)
11212 vty_out(vty, "\"%s/%d\": ", retstr,
11213 dest_p->u.prefix_flowspec
11214 .prefixlen);
11215 else
11216 vty_out(vty, ",\"%s/%d\": ", retstr,
11217 dest_p->u.prefix_flowspec
11218 .prefixlen);
11219 } else {
11220 if (first)
11221 vty_out(vty, "\"%pFX\": ", dest_p);
11222 else
11223 vty_out(vty, ",\"%pFX\": ", dest_p);
11224 }
11225 vty_json(vty, json_paths);
11226 json_paths = NULL;
11227 first = 0;
11228 } else
11229 json_object_free(json_paths);
11230 }
11231
11232 if (output_cum) {
11233 output_count += *output_cum;
11234 *output_cum = output_count;
11235 }
11236 if (total_cum) {
11237 total_count += *total_cum;
11238 *total_cum = total_count;
11239 }
11240 if (use_json) {
11241 if (rd) {
11242 vty_out(vty, " }%s ", (is_last ? "" : ","));
11243 }
11244 if (is_last) {
11245 unsigned long i;
11246 for (i = 0; i < *json_header_depth; ++i)
11247 vty_out(vty, " } ");
11248 if (!all)
11249 vty_out(vty, "\n");
11250 }
11251 } else {
11252 if (is_last) {
11253 /* No route is displayed */
11254 if (output_count == 0) {
11255 if (type == bgp_show_type_normal)
11256 vty_out(vty,
11257 "No BGP prefixes displayed, %ld exist\n",
11258 total_count);
11259 } else
11260 vty_out(vty,
11261 "\nDisplayed %ld routes and %ld total paths\n",
11262 output_count, total_count);
11263 }
11264 }
11265
11266 return CMD_SUCCESS;
11267 }
11268
11269 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11270 struct bgp_table *table, struct prefix_rd *prd_match,
11271 enum bgp_show_type type, void *output_arg, bool use_json)
11272 {
11273 struct bgp_dest *dest, *next;
11274 unsigned long output_cum = 0;
11275 unsigned long total_cum = 0;
11276 unsigned long json_header_depth = 0;
11277 struct bgp_table *itable;
11278 bool show_msg;
11279 uint16_t show_flags = 0;
11280
11281 show_msg = (!use_json && type == bgp_show_type_normal);
11282
11283 if (use_json)
11284 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11285
11286 for (dest = bgp_table_top(table); dest; dest = next) {
11287 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11288
11289 next = bgp_route_next(dest);
11290 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11291 continue;
11292
11293 itable = bgp_dest_get_bgp_table_info(dest);
11294 if (itable != NULL) {
11295 struct prefix_rd prd;
11296 char rd[RD_ADDRSTRLEN];
11297
11298 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11299 prefix_rd2str(&prd, rd, sizeof(rd));
11300 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11301 rd, next == NULL, &output_cum,
11302 &total_cum, &json_header_depth,
11303 show_flags, RPKI_NOT_BEING_USED);
11304 if (next == NULL)
11305 show_msg = false;
11306 }
11307 }
11308 if (show_msg) {
11309 if (output_cum == 0)
11310 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11311 total_cum);
11312 else
11313 vty_out(vty,
11314 "\nDisplayed %ld routes and %ld total paths\n",
11315 output_cum, total_cum);
11316 }
11317 return CMD_SUCCESS;
11318 }
11319
11320 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11321 enum bgp_show_type type, void *output_arg,
11322 uint16_t show_flags, enum rpki_states rpki_target_state)
11323 {
11324 struct bgp_table *table;
11325 unsigned long json_header_depth = 0;
11326 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11327
11328 if (bgp == NULL) {
11329 bgp = bgp_get_default();
11330 }
11331
11332 if (bgp == NULL) {
11333 if (!use_json)
11334 vty_out(vty, "No BGP process is configured\n");
11335 else
11336 vty_out(vty, "{}\n");
11337 return CMD_WARNING;
11338 }
11339
11340 /* Labeled-unicast routes live in the unicast table. */
11341 if (safi == SAFI_LABELED_UNICAST)
11342 safi = SAFI_UNICAST;
11343
11344 table = bgp->rib[afi][safi];
11345 /* use MPLS and ENCAP specific shows until they are merged */
11346 if (safi == SAFI_MPLS_VPN) {
11347 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11348 output_arg, use_json);
11349 }
11350
11351 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11352 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11353 output_arg, use_json,
11354 1, NULL, NULL);
11355 }
11356
11357 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11358 NULL, NULL, &json_header_depth, show_flags,
11359 rpki_target_state);
11360 }
11361
11362 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11363 safi_t safi, uint16_t show_flags)
11364 {
11365 struct listnode *node, *nnode;
11366 struct bgp *bgp;
11367 int is_first = 1;
11368 bool route_output = false;
11369 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11370
11371 if (use_json)
11372 vty_out(vty, "{\n");
11373
11374 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11375 route_output = true;
11376 if (use_json) {
11377 if (!is_first)
11378 vty_out(vty, ",\n");
11379 else
11380 is_first = 0;
11381
11382 vty_out(vty, "\"%s\":",
11383 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11384 ? VRF_DEFAULT_NAME
11385 : bgp->name);
11386 } else {
11387 vty_out(vty, "\nInstance %s:\n",
11388 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11389 ? VRF_DEFAULT_NAME
11390 : bgp->name);
11391 }
11392 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11393 show_flags, RPKI_NOT_BEING_USED);
11394 }
11395
11396 if (use_json)
11397 vty_out(vty, "}\n");
11398 else if (!route_output)
11399 vty_out(vty, "%% BGP instance not found\n");
11400 }
11401
11402 /* Header of detailed BGP route information */
11403 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11404 struct bgp_dest *dest,
11405 const struct prefix_rd *prd,
11406 afi_t afi, safi_t safi, json_object *json)
11407 {
11408 struct bgp_path_info *pi;
11409 const struct prefix *p;
11410 struct peer *peer;
11411 struct listnode *node, *nnode;
11412 char buf1[RD_ADDRSTRLEN];
11413 int count = 0;
11414 int best = 0;
11415 int suppress = 0;
11416 int accept_own = 0;
11417 int route_filter_translated_v4 = 0;
11418 int route_filter_v4 = 0;
11419 int route_filter_translated_v6 = 0;
11420 int route_filter_v6 = 0;
11421 int llgr_stale = 0;
11422 int no_llgr = 0;
11423 int accept_own_nexthop = 0;
11424 int blackhole = 0;
11425 int no_export = 0;
11426 int no_advertise = 0;
11427 int local_as = 0;
11428 int no_peer = 0;
11429 int first = 1;
11430 int has_valid_label = 0;
11431 mpls_label_t label = 0;
11432 json_object *json_adv_to = NULL;
11433
11434 p = bgp_dest_get_prefix(dest);
11435 has_valid_label = bgp_is_valid_label(&dest->local_label);
11436
11437 if (has_valid_label)
11438 label = label_pton(&dest->local_label);
11439
11440 if (safi == SAFI_EVPN) {
11441
11442 if (!json) {
11443 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11444 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11445 : "",
11446 prd ? ":" : "", (struct prefix_evpn *)p);
11447 } else {
11448 json_object_string_add(json, "rd",
11449 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11450 "");
11451 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11452 }
11453 } else {
11454 if (!json) {
11455 vty_out(vty,
11456 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11457 "\n",
11458 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11459 ? prefix_rd2str(prd, buf1,
11460 sizeof(buf1))
11461 : ""),
11462 safi == SAFI_MPLS_VPN ? ":" : "", p,
11463 dest->version);
11464
11465 } else {
11466 json_object_string_addf(json, "prefix", "%pFX", p);
11467 json_object_int_add(json, "version", dest->version);
11468
11469 }
11470 }
11471
11472 if (has_valid_label) {
11473 if (json)
11474 json_object_int_add(json, "localLabel", label);
11475 else
11476 vty_out(vty, "Local label: %d\n", label);
11477 }
11478
11479 if (!json)
11480 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11481 vty_out(vty, "not allocated\n");
11482
11483 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11484 struct community *picomm = NULL;
11485
11486 picomm = bgp_attr_get_community(pi->attr);
11487
11488 count++;
11489 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11490 best = count;
11491 if (bgp_path_suppressed(pi))
11492 suppress = 1;
11493
11494 if (!picomm)
11495 continue;
11496
11497 no_advertise += community_include(
11498 picomm, COMMUNITY_NO_ADVERTISE);
11499 no_export +=
11500 community_include(picomm, COMMUNITY_NO_EXPORT);
11501 local_as +=
11502 community_include(picomm, COMMUNITY_LOCAL_AS);
11503 accept_own +=
11504 community_include(picomm, COMMUNITY_ACCEPT_OWN);
11505 route_filter_translated_v4 += community_include(
11506 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11507 route_filter_translated_v6 += community_include(
11508 picomm, COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11509 route_filter_v4 += community_include(
11510 picomm, COMMUNITY_ROUTE_FILTER_v4);
11511 route_filter_v6 += community_include(
11512 picomm, COMMUNITY_ROUTE_FILTER_v6);
11513 llgr_stale +=
11514 community_include(picomm, COMMUNITY_LLGR_STALE);
11515 no_llgr += community_include(picomm, COMMUNITY_NO_LLGR);
11516 accept_own_nexthop += community_include(
11517 picomm, COMMUNITY_ACCEPT_OWN_NEXTHOP);
11518 blackhole +=
11519 community_include(picomm, COMMUNITY_BLACKHOLE);
11520 no_peer += community_include(picomm, COMMUNITY_NO_PEER);
11521 }
11522 }
11523
11524 if (!json) {
11525 vty_out(vty, "Paths: (%d available", count);
11526 if (best) {
11527 vty_out(vty, ", best #%d", best);
11528 if (safi == SAFI_UNICAST) {
11529 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11530 vty_out(vty, ", table %s",
11531 VRF_DEFAULT_NAME);
11532 else
11533 vty_out(vty, ", vrf %s",
11534 bgp->name);
11535 }
11536 } else
11537 vty_out(vty, ", no best path");
11538
11539 if (accept_own)
11540 vty_out(vty,
11541 ", accept own local route exported and imported in different VRF");
11542 else if (route_filter_translated_v4)
11543 vty_out(vty,
11544 ", mark translated RTs for VPNv4 route filtering");
11545 else if (route_filter_v4)
11546 vty_out(vty,
11547 ", attach RT as-is for VPNv4 route filtering");
11548 else if (route_filter_translated_v6)
11549 vty_out(vty,
11550 ", mark translated RTs for VPNv6 route filtering");
11551 else if (route_filter_v6)
11552 vty_out(vty,
11553 ", attach RT as-is for VPNv6 route filtering");
11554 else if (llgr_stale)
11555 vty_out(vty,
11556 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11557 else if (no_llgr)
11558 vty_out(vty,
11559 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11560 else if (accept_own_nexthop)
11561 vty_out(vty,
11562 ", accept local nexthop");
11563 else if (blackhole)
11564 vty_out(vty, ", inform peer to blackhole prefix");
11565 else if (no_export)
11566 vty_out(vty, ", not advertised to EBGP peer");
11567 else if (no_advertise)
11568 vty_out(vty, ", not advertised to any peer");
11569 else if (local_as)
11570 vty_out(vty, ", not advertised outside local AS");
11571 else if (no_peer)
11572 vty_out(vty,
11573 ", inform EBGP peer not to advertise to their EBGP peers");
11574
11575 if (suppress)
11576 vty_out(vty,
11577 ", Advertisements suppressed by an aggregate.");
11578 vty_out(vty, ")\n");
11579 }
11580
11581 /* If we are not using addpath then we can display Advertised to and
11582 * that will
11583 * show what peers we advertised the bestpath to. If we are using
11584 * addpath
11585 * though then we must display Advertised to on a path-by-path basis. */
11586 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11587 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11588 if (bgp_adj_out_lookup(peer, dest, 0)) {
11589 if (json && !json_adv_to)
11590 json_adv_to = json_object_new_object();
11591
11592 route_vty_out_advertised_to(
11593 vty, peer, &first,
11594 " Advertised to non peer-group peers:\n ",
11595 json_adv_to);
11596 }
11597 }
11598
11599 if (json) {
11600 if (json_adv_to) {
11601 json_object_object_add(json, "advertisedTo",
11602 json_adv_to);
11603 }
11604 } else {
11605 if (first)
11606 vty_out(vty, " Not advertised to any peer");
11607 vty_out(vty, "\n");
11608 }
11609 }
11610 }
11611
11612 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11613 struct bgp_dest *bgp_node, struct vty *vty,
11614 struct bgp *bgp, afi_t afi, safi_t safi,
11615 json_object *json, enum bgp_path_type pathtype,
11616 int *display, enum rpki_states rpki_target_state)
11617 {
11618 struct bgp_path_info *pi;
11619 int header = 1;
11620 char rdbuf[RD_ADDRSTRLEN];
11621 json_object *json_header = NULL;
11622 json_object *json_paths = NULL;
11623 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11624
11625 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11626 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11627
11628 if (p->family == AF_INET || p->family == AF_INET6)
11629 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11630 pi->peer, pi->attr, p);
11631
11632 if (rpki_target_state != RPKI_NOT_BEING_USED
11633 && rpki_curr_state != rpki_target_state)
11634 continue;
11635
11636 if (json && !json_paths) {
11637 /* Instantiate json_paths only if path is valid */
11638 json_paths = json_object_new_array();
11639 if (pfx_rd) {
11640 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11641 json_header = json_object_new_object();
11642 } else
11643 json_header = json;
11644 }
11645
11646 if (header) {
11647 route_vty_out_detail_header(
11648 vty, bgp, bgp_node, pfx_rd,
11649 AFI_IP, safi, json_header);
11650 header = 0;
11651 }
11652 (*display)++;
11653
11654 if (pathtype == BGP_PATH_SHOW_ALL
11655 || (pathtype == BGP_PATH_SHOW_BESTPATH
11656 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11657 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11658 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11659 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11660 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
11661 safi, rpki_curr_state, json_paths);
11662 }
11663
11664 if (json && json_paths) {
11665 json_object_object_add(json_header, "paths", json_paths);
11666
11667 if (pfx_rd)
11668 json_object_object_add(json, rdbuf, json_header);
11669 }
11670 }
11671
11672 /*
11673 * Return rd based on safi
11674 */
11675 static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
11676 safi_t safi)
11677 {
11678 switch (safi) {
11679 case SAFI_MPLS_VPN:
11680 case SAFI_ENCAP:
11681 case SAFI_EVPN:
11682 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
11683 default:
11684 return NULL;
11685
11686 }
11687 }
11688
11689 /* Display specified route of BGP table. */
11690 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11691 struct bgp_table *rib, const char *ip_str,
11692 afi_t afi, safi_t safi,
11693 enum rpki_states rpki_target_state,
11694 struct prefix_rd *prd, int prefix_check,
11695 enum bgp_path_type pathtype, bool use_json)
11696 {
11697 int ret;
11698 int display = 0;
11699 struct prefix match;
11700 struct bgp_dest *dest;
11701 struct bgp_dest *rm;
11702 struct bgp_table *table;
11703 json_object *json = NULL;
11704 json_object *json_paths = NULL;
11705
11706 /* Check IP address argument. */
11707 ret = str2prefix(ip_str, &match);
11708 if (!ret) {
11709 vty_out(vty, "address is malformed\n");
11710 return CMD_WARNING;
11711 }
11712
11713 match.family = afi2family(afi);
11714
11715 if (use_json)
11716 json = json_object_new_object();
11717
11718 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11719 for (dest = bgp_table_top(rib); dest;
11720 dest = bgp_route_next(dest)) {
11721 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11722
11723 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11724 continue;
11725 table = bgp_dest_get_bgp_table_info(dest);
11726 if (!table)
11727 continue;
11728
11729 rm = bgp_node_match(table, &match);
11730 if (rm == NULL)
11731 continue;
11732
11733 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11734 if (prefix_check
11735 && rm_p->prefixlen != match.prefixlen) {
11736 bgp_dest_unlock_node(rm);
11737 continue;
11738 }
11739
11740 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11741 bgp, afi, safi, json, pathtype,
11742 &display, rpki_target_state);
11743
11744 bgp_dest_unlock_node(rm);
11745 }
11746 } else if (safi == SAFI_EVPN) {
11747 struct bgp_dest *longest_pfx;
11748 bool is_exact_pfxlen_match = false;
11749
11750 for (dest = bgp_table_top(rib); dest;
11751 dest = bgp_route_next(dest)) {
11752 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11753
11754 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11755 continue;
11756 table = bgp_dest_get_bgp_table_info(dest);
11757 if (!table)
11758 continue;
11759
11760 longest_pfx = NULL;
11761 is_exact_pfxlen_match = false;
11762 /*
11763 * Search through all the prefixes for a match. The
11764 * pfx's are enumerated in ascending order of pfxlens.
11765 * So, the last pfx match is the longest match. Set
11766 * is_exact_pfxlen_match when we get exact pfxlen match
11767 */
11768 for (rm = bgp_table_top(table); rm;
11769 rm = bgp_route_next(rm)) {
11770 const struct prefix *rm_p =
11771 bgp_dest_get_prefix(rm);
11772 /*
11773 * Get prefixlen of the ip-prefix within type5
11774 * evpn route
11775 */
11776 if (evpn_type5_prefix_match(rm_p, &match)
11777 && rm->info) {
11778 longest_pfx = rm;
11779 int type5_pfxlen =
11780 bgp_evpn_get_type5_prefixlen(
11781 rm_p);
11782 if (type5_pfxlen == match.prefixlen) {
11783 is_exact_pfxlen_match = true;
11784 bgp_dest_unlock_node(rm);
11785 break;
11786 }
11787 }
11788 }
11789
11790 if (!longest_pfx)
11791 continue;
11792
11793 if (prefix_check && !is_exact_pfxlen_match)
11794 continue;
11795
11796 rm = longest_pfx;
11797 bgp_dest_lock_node(rm);
11798
11799 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11800 bgp, afi, safi, json, pathtype,
11801 &display, rpki_target_state);
11802
11803 bgp_dest_unlock_node(rm);
11804 }
11805 } else if (safi == SAFI_FLOWSPEC) {
11806 if (use_json)
11807 json_paths = json_object_new_array();
11808
11809 display = bgp_flowspec_display_match_per_ip(afi, rib,
11810 &match, prefix_check,
11811 vty,
11812 use_json,
11813 json_paths);
11814 if (use_json) {
11815 if (display)
11816 json_object_object_add(json, "paths",
11817 json_paths);
11818 else
11819 json_object_free(json_paths);
11820 }
11821 } else {
11822 dest = bgp_node_match(rib, &match);
11823 if (dest != NULL) {
11824 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11825 if (!prefix_check
11826 || dest_p->prefixlen == match.prefixlen) {
11827 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11828 safi, json, pathtype,
11829 &display, rpki_target_state);
11830 }
11831
11832 bgp_dest_unlock_node(dest);
11833 }
11834 }
11835
11836 if (use_json) {
11837 vty_json(vty, json);
11838 } else {
11839 if (!display) {
11840 vty_out(vty, "%% Network not in table\n");
11841 return CMD_WARNING;
11842 }
11843 }
11844
11845 return CMD_SUCCESS;
11846 }
11847
11848 /* Display specified route of Main RIB */
11849 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
11850 afi_t afi, safi_t safi, struct prefix_rd *prd,
11851 int prefix_check, enum bgp_path_type pathtype,
11852 enum rpki_states rpki_target_state, bool use_json)
11853 {
11854 if (!bgp) {
11855 bgp = bgp_get_default();
11856 if (!bgp) {
11857 if (!use_json)
11858 vty_out(vty, "No BGP process is configured\n");
11859 else
11860 vty_out(vty, "{}\n");
11861 return CMD_WARNING;
11862 }
11863 }
11864
11865 /* labeled-unicast routes live in the unicast table */
11866 if (safi == SAFI_LABELED_UNICAST)
11867 safi = SAFI_UNICAST;
11868
11869 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
11870 afi, safi, rpki_target_state, prd,
11871 prefix_check, pathtype, use_json);
11872 }
11873
11874 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
11875 struct cmd_token **argv, bool exact, afi_t afi,
11876 safi_t safi, bool uj)
11877 {
11878 struct lcommunity *lcom;
11879 struct buffer *b;
11880 int i;
11881 char *str;
11882 int first = 0;
11883 uint16_t show_flags = 0;
11884 int ret;
11885
11886 if (uj)
11887 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11888
11889 b = buffer_new(1024);
11890 for (i = 0; i < argc; i++) {
11891 if (first)
11892 buffer_putc(b, ' ');
11893 else {
11894 if (strmatch(argv[i]->text, "AA:BB:CC")) {
11895 first = 1;
11896 buffer_putstr(b, argv[i]->arg);
11897 }
11898 }
11899 }
11900 buffer_putc(b, '\0');
11901
11902 str = buffer_getstr(b);
11903 buffer_free(b);
11904
11905 lcom = lcommunity_str2com(str);
11906 XFREE(MTYPE_TMP, str);
11907 if (!lcom) {
11908 vty_out(vty, "%% Large-community malformed\n");
11909 return CMD_WARNING;
11910 }
11911
11912 ret = bgp_show(vty, bgp, afi, safi,
11913 (exact ? bgp_show_type_lcommunity_exact
11914 : bgp_show_type_lcommunity),
11915 lcom, show_flags, RPKI_NOT_BEING_USED);
11916
11917 lcommunity_free(&lcom);
11918 return ret;
11919 }
11920
11921 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
11922 const char *lcom, bool exact, afi_t afi,
11923 safi_t safi, bool uj)
11924 {
11925 struct community_list *list;
11926 uint16_t show_flags = 0;
11927
11928 if (uj)
11929 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11930
11931
11932 list = community_list_lookup(bgp_clist, lcom, 0,
11933 LARGE_COMMUNITY_LIST_MASTER);
11934 if (list == NULL) {
11935 vty_out(vty, "%% %s is not a valid large-community-list name\n",
11936 lcom);
11937 return CMD_WARNING;
11938 }
11939
11940 return bgp_show(vty, bgp, afi, safi,
11941 (exact ? bgp_show_type_lcommunity_list_exact
11942 : bgp_show_type_lcommunity_list),
11943 list, show_flags, RPKI_NOT_BEING_USED);
11944 }
11945
11946 DEFUN (show_ip_bgp_large_community_list,
11947 show_ip_bgp_large_community_list_cmd,
11948 "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]",
11949 SHOW_STR
11950 IP_STR
11951 BGP_STR
11952 BGP_INSTANCE_HELP_STR
11953 BGP_AFI_HELP_STR
11954 BGP_SAFI_WITH_LABEL_HELP_STR
11955 "Display routes matching the large-community-list\n"
11956 "large-community-list number\n"
11957 "large-community-list name\n"
11958 "Exact match of the large-communities\n"
11959 JSON_STR)
11960 {
11961 afi_t afi = AFI_IP6;
11962 safi_t safi = SAFI_UNICAST;
11963 int idx = 0;
11964 bool exact_match = 0;
11965 struct bgp *bgp = NULL;
11966 bool uj = use_json(argc, argv);
11967
11968 if (uj)
11969 argc--;
11970
11971 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11972 &bgp, uj);
11973 if (!idx)
11974 return CMD_WARNING;
11975
11976 argv_find(argv, argc, "large-community-list", &idx);
11977
11978 const char *clist_number_or_name = argv[++idx]->arg;
11979
11980 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11981 exact_match = 1;
11982
11983 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
11984 exact_match, afi, safi, uj);
11985 }
11986 DEFUN (show_ip_bgp_large_community,
11987 show_ip_bgp_large_community_cmd,
11988 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
11989 SHOW_STR
11990 IP_STR
11991 BGP_STR
11992 BGP_INSTANCE_HELP_STR
11993 BGP_AFI_HELP_STR
11994 BGP_SAFI_WITH_LABEL_HELP_STR
11995 "Display routes matching the large-communities\n"
11996 "List of large-community numbers\n"
11997 "Exact match of the large-communities\n"
11998 JSON_STR)
11999 {
12000 afi_t afi = AFI_IP6;
12001 safi_t safi = SAFI_UNICAST;
12002 int idx = 0;
12003 bool exact_match = 0;
12004 struct bgp *bgp = NULL;
12005 bool uj = use_json(argc, argv);
12006 uint16_t show_flags = 0;
12007
12008 if (uj) {
12009 argc--;
12010 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12011 }
12012
12013 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12014 &bgp, uj);
12015 if (!idx)
12016 return CMD_WARNING;
12017
12018 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12019 if (argv_find(argv, argc, "exact-match", &idx))
12020 exact_match = 1;
12021 return bgp_show_lcommunity(vty, bgp, argc, argv,
12022 exact_match, afi, safi, uj);
12023 } else
12024 return bgp_show(vty, bgp, afi, safi,
12025 bgp_show_type_lcommunity_all, NULL, show_flags,
12026 RPKI_NOT_BEING_USED);
12027 }
12028
12029 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12030 safi_t safi, struct json_object *json_array);
12031 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12032 safi_t safi, struct json_object *json);
12033
12034
12035 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12036 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12037 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12038 "Display number of prefixes for all afi/safi\n" JSON_STR)
12039 {
12040 bool uj = use_json(argc, argv);
12041 struct bgp *bgp = NULL;
12042 safi_t safi = SAFI_UNICAST;
12043 afi_t afi = AFI_IP6;
12044 int idx = 0;
12045 struct json_object *json_all = NULL;
12046 struct json_object *json_afi_safi = NULL;
12047
12048 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12049 &bgp, false);
12050 if (!idx)
12051 return CMD_WARNING;
12052
12053 if (uj)
12054 json_all = json_object_new_object();
12055
12056 FOREACH_AFI_SAFI (afi, safi) {
12057 /*
12058 * So limit output to those afi/safi pairs that
12059 * actually have something interesting in them
12060 */
12061 if (strmatch(get_afi_safi_str(afi, safi, true),
12062 "Unknown")) {
12063 continue;
12064 }
12065 if (uj) {
12066 json_afi_safi = json_object_new_array();
12067 json_object_object_add(
12068 json_all,
12069 get_afi_safi_str(afi, safi, true),
12070 json_afi_safi);
12071 } else {
12072 json_afi_safi = NULL;
12073 }
12074
12075 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12076 }
12077
12078 if (uj)
12079 vty_json(vty, json_all);
12080
12081 return CMD_SUCCESS;
12082 }
12083
12084 /* BGP route print out function without JSON */
12085 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12086 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12087 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12088 SHOW_STR
12089 IP_STR
12090 BGP_STR
12091 BGP_INSTANCE_HELP_STR
12092 L2VPN_HELP_STR
12093 EVPN_HELP_STR
12094 "BGP RIB advertisement statistics\n"
12095 JSON_STR)
12096 {
12097 afi_t afi = AFI_IP6;
12098 safi_t safi = SAFI_UNICAST;
12099 struct bgp *bgp = NULL;
12100 int idx = 0, ret;
12101 bool uj = use_json(argc, argv);
12102 struct json_object *json_afi_safi = NULL, *json = NULL;
12103
12104 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12105 &bgp, false);
12106 if (!idx)
12107 return CMD_WARNING;
12108
12109 if (uj)
12110 json_afi_safi = json_object_new_array();
12111 else
12112 json_afi_safi = NULL;
12113
12114 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12115
12116 if (uj) {
12117 json = json_object_new_object();
12118 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12119 json_afi_safi);
12120 vty_json(vty, json);
12121 }
12122 return ret;
12123 }
12124
12125 /* BGP route print out function without JSON */
12126 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12127 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12128 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12129 "]]\
12130 statistics [json]",
12131 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12132 BGP_SAFI_WITH_LABEL_HELP_STR
12133 "BGP RIB advertisement statistics\n" JSON_STR)
12134 {
12135 afi_t afi = AFI_IP6;
12136 safi_t safi = SAFI_UNICAST;
12137 struct bgp *bgp = NULL;
12138 int idx = 0, ret;
12139 bool uj = use_json(argc, argv);
12140 struct json_object *json_afi_safi = NULL, *json = NULL;
12141
12142 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12143 &bgp, false);
12144 if (!idx)
12145 return CMD_WARNING;
12146
12147 if (uj)
12148 json_afi_safi = json_object_new_array();
12149 else
12150 json_afi_safi = NULL;
12151
12152 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12153
12154 if (uj) {
12155 json = json_object_new_object();
12156 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12157 json_afi_safi);
12158 vty_json(vty, json);
12159 }
12160 return ret;
12161 }
12162
12163 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12164 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12165 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12166 "]] [all$all] dampening parameters [json]",
12167 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12168 BGP_SAFI_WITH_LABEL_HELP_STR
12169 "Display the entries for all address families\n"
12170 "Display detailed information about dampening\n"
12171 "Display detail of configured dampening parameters\n"
12172 JSON_STR)
12173 {
12174 afi_t afi = AFI_IP6;
12175 safi_t safi = SAFI_UNICAST;
12176 struct bgp *bgp = NULL;
12177 int idx = 0;
12178 uint16_t show_flags = 0;
12179 bool uj = use_json(argc, argv);
12180
12181 if (uj) {
12182 argc--;
12183 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12184 }
12185
12186 /* [<ipv4|ipv6> [all]] */
12187 if (all) {
12188 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12189 if (argv_find(argv, argc, "ipv4", &idx))
12190 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12191
12192 if (argv_find(argv, argc, "ipv6", &idx))
12193 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12194 }
12195
12196 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12197 &bgp, false);
12198 if (!idx)
12199 return CMD_WARNING;
12200
12201 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12202 }
12203
12204 /* BGP route print out function */
12205 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12206 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12207 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12208 "]]\
12209 [all$all]\
12210 [cidr-only\
12211 |dampening <flap-statistics|dampened-paths>\
12212 |community [AA:NN|local-AS|no-advertise|no-export\
12213 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12214 |accept-own|accept-own-nexthop|route-filter-v6\
12215 |route-filter-v4|route-filter-translated-v6\
12216 |route-filter-translated-v4] [exact-match]\
12217 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12218 |filter-list AS_PATH_FILTER_NAME\
12219 |prefix-list WORD\
12220 |route-map WORD\
12221 |rpki <invalid|valid|notfound>\
12222 |version (1-4294967295)\
12223 |alias ALIAS_NAME\
12224 |A.B.C.D/M longer-prefixes\
12225 |X:X::X:X/M longer-prefixes\
12226 ] [json$uj [detail$detail] | wide$wide]",
12227 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12228 BGP_SAFI_WITH_LABEL_HELP_STR
12229 "Display the entries for all address families\n"
12230 "Display only routes with non-natural netmasks\n"
12231 "Display detailed information about dampening\n"
12232 "Display flap statistics of routes\n"
12233 "Display paths suppressed due to dampening\n"
12234 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12235 "Do not send outside local AS (well-known community)\n"
12236 "Do not advertise to any peer (well-known community)\n"
12237 "Do not export to next AS (well-known community)\n"
12238 "Graceful shutdown (well-known community)\n"
12239 "Do not export to any peer (well-known community)\n"
12240 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12241 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12242 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12243 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12244 "Should accept VPN route with local nexthop (well-known community)\n"
12245 "RT VPNv6 route filtering (well-known community)\n"
12246 "RT VPNv4 route filtering (well-known community)\n"
12247 "RT translated VPNv6 route filtering (well-known community)\n"
12248 "RT translated VPNv4 route filtering (well-known community)\n"
12249 "Exact match of the communities\n"
12250 "Community-list number\n"
12251 "Community-list name\n"
12252 "Display routes matching the community-list\n"
12253 "Exact match of the communities\n"
12254 "Display routes conforming to the filter-list\n"
12255 "Regular expression access list name\n"
12256 "Display routes conforming to the prefix-list\n"
12257 "Prefix-list name\n"
12258 "Display routes matching the route-map\n"
12259 "A route-map to match on\n"
12260 "RPKI route types\n"
12261 "A valid path as determined by rpki\n"
12262 "A invalid path as determined by rpki\n"
12263 "A path that has no rpki data\n"
12264 "Display prefixes with matching version numbers\n"
12265 "Version number and above\n"
12266 "Display prefixes with matching BGP community alias\n"
12267 "BGP community alias\n"
12268 "IPv4 prefix\n"
12269 "Display route and more specific routes\n"
12270 "IPv6 prefix\n"
12271 "Display route and more specific routes\n"
12272 JSON_STR
12273 "Display detailed version of JSON output\n"
12274 "Increase table width for longer prefixes\n")
12275 {
12276 afi_t afi = AFI_IP6;
12277 safi_t safi = SAFI_UNICAST;
12278 enum bgp_show_type sh_type = bgp_show_type_normal;
12279 void *output_arg = NULL;
12280 struct bgp *bgp = NULL;
12281 int idx = 0;
12282 int exact_match = 0;
12283 char *community = NULL;
12284 bool first = true;
12285 uint16_t show_flags = 0;
12286 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12287 struct prefix p;
12288
12289 if (uj) {
12290 argc--;
12291 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12292 }
12293
12294 if (detail)
12295 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12296
12297 /* [<ipv4|ipv6> [all]] */
12298 if (all) {
12299 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12300
12301 if (argv_find(argv, argc, "ipv4", &idx))
12302 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12303
12304 if (argv_find(argv, argc, "ipv6", &idx))
12305 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12306 }
12307
12308 if (wide)
12309 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12310
12311 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12312 &bgp, uj);
12313 if (!idx)
12314 return CMD_WARNING;
12315
12316 if (argv_find(argv, argc, "cidr-only", &idx))
12317 sh_type = bgp_show_type_cidr_only;
12318
12319 if (argv_find(argv, argc, "dampening", &idx)) {
12320 if (argv_find(argv, argc, "dampened-paths", &idx))
12321 sh_type = bgp_show_type_dampend_paths;
12322 else if (argv_find(argv, argc, "flap-statistics", &idx))
12323 sh_type = bgp_show_type_flap_statistics;
12324 }
12325
12326 if (argv_find(argv, argc, "community", &idx)) {
12327 char *maybecomm = NULL;
12328
12329 if (idx + 1 < argc) {
12330 if (argv[idx + 1]->type == VARIABLE_TKN)
12331 maybecomm = argv[idx + 1]->arg;
12332 else
12333 maybecomm = argv[idx + 1]->text;
12334 }
12335
12336 if (maybecomm && !strmatch(maybecomm, "json")
12337 && !strmatch(maybecomm, "exact-match"))
12338 community = maybecomm;
12339
12340 if (argv_find(argv, argc, "exact-match", &idx))
12341 exact_match = 1;
12342
12343 if (!community)
12344 sh_type = bgp_show_type_community_all;
12345 }
12346
12347 if (argv_find(argv, argc, "community-list", &idx)) {
12348 const char *clist_number_or_name = argv[++idx]->arg;
12349 struct community_list *list;
12350
12351 if (argv_find(argv, argc, "exact-match", &idx))
12352 exact_match = 1;
12353
12354 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12355 COMMUNITY_LIST_MASTER);
12356 if (list == NULL) {
12357 vty_out(vty,
12358 "%% %s is not a valid community-list name\n",
12359 clist_number_or_name);
12360 return CMD_WARNING;
12361 }
12362
12363 if (exact_match)
12364 sh_type = bgp_show_type_community_list_exact;
12365 else
12366 sh_type = bgp_show_type_community_list;
12367 output_arg = list;
12368 }
12369
12370 if (argv_find(argv, argc, "filter-list", &idx)) {
12371 const char *filter = argv[++idx]->arg;
12372 struct as_list *as_list;
12373
12374 as_list = as_list_lookup(filter);
12375 if (as_list == NULL) {
12376 vty_out(vty,
12377 "%% %s is not a valid AS-path access-list name\n",
12378 filter);
12379 return CMD_WARNING;
12380 }
12381
12382 sh_type = bgp_show_type_filter_list;
12383 output_arg = as_list;
12384 }
12385
12386 if (argv_find(argv, argc, "prefix-list", &idx)) {
12387 const char *prefix_list_str = argv[++idx]->arg;
12388 struct prefix_list *plist;
12389
12390 plist = prefix_list_lookup(afi, prefix_list_str);
12391 if (plist == NULL) {
12392 vty_out(vty, "%% %s is not a valid prefix-list name\n",
12393 prefix_list_str);
12394 return CMD_WARNING;
12395 }
12396
12397 sh_type = bgp_show_type_prefix_list;
12398 output_arg = plist;
12399 }
12400
12401 if (argv_find(argv, argc, "route-map", &idx)) {
12402 const char *rmap_str = argv[++idx]->arg;
12403 struct route_map *rmap;
12404
12405 rmap = route_map_lookup_by_name(rmap_str);
12406 if (!rmap) {
12407 vty_out(vty, "%% %s is not a valid route-map name\n",
12408 rmap_str);
12409 return CMD_WARNING;
12410 }
12411
12412 sh_type = bgp_show_type_route_map;
12413 output_arg = rmap;
12414 }
12415
12416 if (argv_find(argv, argc, "rpki", &idx)) {
12417 sh_type = bgp_show_type_rpki;
12418 if (argv_find(argv, argc, "valid", &idx))
12419 rpki_target_state = RPKI_VALID;
12420 else if (argv_find(argv, argc, "invalid", &idx))
12421 rpki_target_state = RPKI_INVALID;
12422 }
12423
12424 /* Display prefixes with matching version numbers */
12425 if (argv_find(argv, argc, "version", &idx)) {
12426 sh_type = bgp_show_type_prefix_version;
12427 output_arg = argv[idx + 1]->arg;
12428 }
12429
12430 /* Display prefixes with matching BGP community alias */
12431 if (argv_find(argv, argc, "alias", &idx)) {
12432 sh_type = bgp_show_type_community_alias;
12433 output_arg = argv[idx + 1]->arg;
12434 }
12435
12436 /* prefix-longer */
12437 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12438 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12439 const char *prefix_str = argv[idx]->arg;
12440
12441 if (!str2prefix(prefix_str, &p)) {
12442 vty_out(vty, "%% Malformed Prefix\n");
12443 return CMD_WARNING;
12444 }
12445
12446 sh_type = bgp_show_type_prefix_longer;
12447 output_arg = &p;
12448 }
12449
12450 if (!all) {
12451 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12452 if (community)
12453 return bgp_show_community(vty, bgp, community,
12454 exact_match, afi, safi,
12455 show_flags);
12456 else
12457 return bgp_show(vty, bgp, afi, safi, sh_type,
12458 output_arg, show_flags,
12459 rpki_target_state);
12460 } else {
12461 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12462 * AFI_IP6 */
12463
12464 if (uj)
12465 vty_out(vty, "{\n");
12466
12467 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12468 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12469 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12470 ? AFI_IP
12471 : AFI_IP6;
12472 FOREACH_SAFI (safi) {
12473 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12474 continue;
12475
12476 if (uj) {
12477 if (first)
12478 first = false;
12479 else
12480 vty_out(vty, ",\n");
12481 vty_out(vty, "\"%s\":{\n",
12482 get_afi_safi_str(afi, safi,
12483 true));
12484 } else
12485 vty_out(vty,
12486 "\nFor address family: %s\n",
12487 get_afi_safi_str(afi, safi,
12488 false));
12489
12490 if (community)
12491 bgp_show_community(vty, bgp, community,
12492 exact_match, afi,
12493 safi, show_flags);
12494 else
12495 bgp_show(vty, bgp, afi, safi, sh_type,
12496 output_arg, show_flags,
12497 rpki_target_state);
12498 if (uj)
12499 vty_out(vty, "}\n");
12500 }
12501 } else {
12502 /* show <ip> bgp all: for each AFI and SAFI*/
12503 FOREACH_AFI_SAFI (afi, safi) {
12504 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12505 continue;
12506
12507 if (uj) {
12508 if (first)
12509 first = false;
12510 else
12511 vty_out(vty, ",\n");
12512
12513 vty_out(vty, "\"%s\":{\n",
12514 get_afi_safi_str(afi, safi,
12515 true));
12516 } else
12517 vty_out(vty,
12518 "\nFor address family: %s\n",
12519 get_afi_safi_str(afi, safi,
12520 false));
12521
12522 if (community)
12523 bgp_show_community(vty, bgp, community,
12524 exact_match, afi,
12525 safi, show_flags);
12526 else
12527 bgp_show(vty, bgp, afi, safi, sh_type,
12528 output_arg, show_flags,
12529 rpki_target_state);
12530 if (uj)
12531 vty_out(vty, "}\n");
12532 }
12533 }
12534 if (uj)
12535 vty_out(vty, "}\n");
12536 }
12537 return CMD_SUCCESS;
12538 }
12539
12540 DEFUN (show_ip_bgp_route,
12541 show_ip_bgp_route_cmd,
12542 "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]",
12543 SHOW_STR
12544 IP_STR
12545 BGP_STR
12546 BGP_INSTANCE_HELP_STR
12547 BGP_AFI_HELP_STR
12548 BGP_SAFI_WITH_LABEL_HELP_STR
12549 "Network in the BGP routing table to display\n"
12550 "IPv4 prefix\n"
12551 "Network in the BGP routing table to display\n"
12552 "IPv6 prefix\n"
12553 "Display only the bestpath\n"
12554 "Display only multipaths\n"
12555 "Display only paths that match the specified rpki state\n"
12556 "A valid path as determined by rpki\n"
12557 "A invalid path as determined by rpki\n"
12558 "A path that has no rpki data\n"
12559 JSON_STR)
12560 {
12561 int prefix_check = 0;
12562
12563 afi_t afi = AFI_IP6;
12564 safi_t safi = SAFI_UNICAST;
12565 char *prefix = NULL;
12566 struct bgp *bgp = NULL;
12567 enum bgp_path_type path_type;
12568 bool uj = use_json(argc, argv);
12569
12570 int idx = 0;
12571
12572 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12573 &bgp, uj);
12574 if (!idx)
12575 return CMD_WARNING;
12576
12577 if (!bgp) {
12578 vty_out(vty,
12579 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12580 return CMD_WARNING;
12581 }
12582
12583 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12584 if (argv_find(argv, argc, "A.B.C.D", &idx)
12585 || argv_find(argv, argc, "X:X::X:X", &idx))
12586 prefix_check = 0;
12587 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12588 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12589 prefix_check = 1;
12590
12591 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12592 && afi != AFI_IP6) {
12593 vty_out(vty,
12594 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12595 return CMD_WARNING;
12596 }
12597 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12598 && afi != AFI_IP) {
12599 vty_out(vty,
12600 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12601 return CMD_WARNING;
12602 }
12603
12604 prefix = argv[idx]->arg;
12605
12606 /* [<bestpath|multipath>] */
12607 if (argv_find(argv, argc, "bestpath", &idx))
12608 path_type = BGP_PATH_SHOW_BESTPATH;
12609 else if (argv_find(argv, argc, "multipath", &idx))
12610 path_type = BGP_PATH_SHOW_MULTIPATH;
12611 else
12612 path_type = BGP_PATH_SHOW_ALL;
12613
12614 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12615 path_type, RPKI_NOT_BEING_USED, uj);
12616 }
12617
12618 DEFUN (show_ip_bgp_regexp,
12619 show_ip_bgp_regexp_cmd,
12620 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12621 SHOW_STR
12622 IP_STR
12623 BGP_STR
12624 BGP_INSTANCE_HELP_STR
12625 BGP_AFI_HELP_STR
12626 BGP_SAFI_WITH_LABEL_HELP_STR
12627 "Display routes matching the AS path regular expression\n"
12628 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12629 JSON_STR)
12630 {
12631 afi_t afi = AFI_IP6;
12632 safi_t safi = SAFI_UNICAST;
12633 struct bgp *bgp = NULL;
12634 bool uj = use_json(argc, argv);
12635 char *regstr = NULL;
12636
12637 int idx = 0;
12638 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12639 &bgp, false);
12640 if (!idx)
12641 return CMD_WARNING;
12642
12643 // get index of regex
12644 if (argv_find(argv, argc, "REGEX", &idx))
12645 regstr = argv[idx]->arg;
12646
12647 assert(regstr);
12648 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12649 bgp_show_type_regexp, uj);
12650 }
12651
12652 DEFPY (show_ip_bgp_instance_all,
12653 show_ip_bgp_instance_all_cmd,
12654 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12655 SHOW_STR
12656 IP_STR
12657 BGP_STR
12658 BGP_INSTANCE_ALL_HELP_STR
12659 BGP_AFI_HELP_STR
12660 BGP_SAFI_WITH_LABEL_HELP_STR
12661 JSON_STR
12662 "Increase table width for longer prefixes\n")
12663 {
12664 afi_t afi = AFI_IP6;
12665 safi_t safi = SAFI_UNICAST;
12666 struct bgp *bgp = NULL;
12667 int idx = 0;
12668 uint16_t show_flags = 0;
12669
12670 if (uj) {
12671 argc--;
12672 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12673 }
12674
12675 if (wide)
12676 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12677
12678 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12679 &bgp, uj);
12680 if (!idx)
12681 return CMD_WARNING;
12682
12683 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12684 return CMD_SUCCESS;
12685 }
12686
12687 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12688 afi_t afi, safi_t safi, enum bgp_show_type type,
12689 bool use_json)
12690 {
12691 regex_t *regex;
12692 int rc;
12693 uint16_t show_flags = 0;
12694
12695 if (use_json)
12696 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12697
12698 if (!config_bgp_aspath_validate(regstr)) {
12699 vty_out(vty, "Invalid character in REGEX %s\n",
12700 regstr);
12701 return CMD_WARNING_CONFIG_FAILED;
12702 }
12703
12704 regex = bgp_regcomp(regstr);
12705 if (!regex) {
12706 vty_out(vty, "Can't compile regexp %s\n", regstr);
12707 return CMD_WARNING;
12708 }
12709
12710 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
12711 RPKI_NOT_BEING_USED);
12712 bgp_regex_free(regex);
12713 return rc;
12714 }
12715
12716 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12717 const char *comstr, int exact, afi_t afi,
12718 safi_t safi, uint16_t show_flags)
12719 {
12720 struct community *com;
12721 int ret = 0;
12722
12723 com = community_str2com(comstr);
12724 if (!com) {
12725 vty_out(vty, "%% Community malformed: %s\n", comstr);
12726 return CMD_WARNING;
12727 }
12728
12729 ret = bgp_show(vty, bgp, afi, safi,
12730 (exact ? bgp_show_type_community_exact
12731 : bgp_show_type_community),
12732 com, show_flags, RPKI_NOT_BEING_USED);
12733 community_free(&com);
12734
12735 return ret;
12736 }
12737
12738 enum bgp_stats {
12739 BGP_STATS_MAXBITLEN = 0,
12740 BGP_STATS_RIB,
12741 BGP_STATS_PREFIXES,
12742 BGP_STATS_TOTPLEN,
12743 BGP_STATS_UNAGGREGATEABLE,
12744 BGP_STATS_MAX_AGGREGATEABLE,
12745 BGP_STATS_AGGREGATES,
12746 BGP_STATS_SPACE,
12747 BGP_STATS_ASPATH_COUNT,
12748 BGP_STATS_ASPATH_MAXHOPS,
12749 BGP_STATS_ASPATH_TOTHOPS,
12750 BGP_STATS_ASPATH_MAXSIZE,
12751 BGP_STATS_ASPATH_TOTSIZE,
12752 BGP_STATS_ASN_HIGHEST,
12753 BGP_STATS_MAX,
12754 };
12755
12756 #define TABLE_STATS_IDX_VTY 0
12757 #define TABLE_STATS_IDX_JSON 1
12758
12759 static const char *table_stats_strs[][2] = {
12760 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12761 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12762 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12763 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12764 "unaggregateablePrefixes"},
12765 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12766 "maximumAggregateablePrefixes"},
12767 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12768 "bgpAggregateAdvertisements"},
12769 [BGP_STATS_SPACE] = {"Address space advertised",
12770 "addressSpaceAdvertised"},
12771 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12772 "advertisementsWithPaths"},
12773 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12774 "longestAsPath"},
12775 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12776 "largestAsPath"},
12777 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12778 "averageAsPathLengthHops"},
12779 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12780 "averageAsPathSizeBytes"},
12781 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12782 [BGP_STATS_MAX] = {NULL, NULL}
12783 };
12784
12785 struct bgp_table_stats {
12786 struct bgp_table *table;
12787 unsigned long long counts[BGP_STATS_MAX];
12788 double total_space;
12789 };
12790
12791 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12792 struct bgp_table_stats *ts, unsigned int space)
12793 {
12794 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12795 struct bgp_path_info *pi;
12796 const struct prefix *rn_p;
12797
12798 if (!bgp_dest_has_bgp_path_info_data(dest))
12799 return;
12800
12801 rn_p = bgp_dest_get_prefix(dest);
12802 ts->counts[BGP_STATS_PREFIXES]++;
12803 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12804
12805 /* check if the prefix is included by any other announcements */
12806 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12807 pdest = bgp_dest_parent_nolock(pdest);
12808
12809 if (pdest == NULL || pdest == top) {
12810 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12811 /* announced address space */
12812 if (space)
12813 ts->total_space += pow(2.0, space - rn_p->prefixlen);
12814 } else if (bgp_dest_has_bgp_path_info_data(pdest))
12815 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
12816
12817
12818 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
12819 ts->counts[BGP_STATS_RIB]++;
12820
12821 if (CHECK_FLAG(pi->attr->flag,
12822 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
12823 ts->counts[BGP_STATS_AGGREGATES]++;
12824
12825 /* as-path stats */
12826 if (pi->attr->aspath) {
12827 unsigned int hops = aspath_count_hops(pi->attr->aspath);
12828 unsigned int size = aspath_size(pi->attr->aspath);
12829 as_t highest = aspath_highest(pi->attr->aspath);
12830
12831 ts->counts[BGP_STATS_ASPATH_COUNT]++;
12832
12833 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
12834 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
12835
12836 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
12837 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
12838
12839 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
12840 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
12841 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
12842 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
12843 }
12844 }
12845 }
12846
12847 static void bgp_table_stats_walker(struct thread *t)
12848 {
12849 struct bgp_dest *dest, *ndest;
12850 struct bgp_dest *top;
12851 struct bgp_table_stats *ts = THREAD_ARG(t);
12852 unsigned int space = 0;
12853
12854 if (!(top = bgp_table_top(ts->table)))
12855 return;
12856
12857 switch (ts->table->afi) {
12858 case AFI_IP:
12859 space = IPV4_MAX_BITLEN;
12860 break;
12861 case AFI_IP6:
12862 space = IPV6_MAX_BITLEN;
12863 break;
12864 case AFI_L2VPN:
12865 space = EVPN_ROUTE_PREFIXLEN;
12866 break;
12867 default:
12868 return;
12869 }
12870
12871 ts->counts[BGP_STATS_MAXBITLEN] = space;
12872
12873 for (dest = top; dest; dest = bgp_route_next(dest)) {
12874 if (ts->table->safi == SAFI_MPLS_VPN
12875 || ts->table->safi == SAFI_ENCAP
12876 || ts->table->safi == SAFI_EVPN) {
12877 struct bgp_table *table;
12878
12879 table = bgp_dest_get_bgp_table_info(dest);
12880 if (!table)
12881 continue;
12882
12883 top = bgp_table_top(table);
12884 for (ndest = bgp_table_top(table); ndest;
12885 ndest = bgp_route_next(ndest))
12886 bgp_table_stats_rn(ndest, top, ts, space);
12887 } else {
12888 bgp_table_stats_rn(dest, top, ts, space);
12889 }
12890 }
12891 }
12892
12893 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
12894 struct json_object *json_array)
12895 {
12896 struct listnode *node, *nnode;
12897 struct bgp *bgp;
12898
12899 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
12900 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12901 }
12902
12903 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12904 safi_t safi, struct json_object *json_array)
12905 {
12906 struct bgp_table_stats ts;
12907 unsigned int i;
12908 int ret = CMD_SUCCESS;
12909 char temp_buf[20];
12910 struct json_object *json = NULL;
12911
12912 if (json_array)
12913 json = json_object_new_object();
12914
12915 if (!bgp->rib[afi][safi]) {
12916 char warning_msg[50];
12917
12918 snprintf(warning_msg, sizeof(warning_msg),
12919 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
12920 safi);
12921
12922 if (!json)
12923 vty_out(vty, "%s\n", warning_msg);
12924 else
12925 json_object_string_add(json, "warning", warning_msg);
12926
12927 ret = CMD_WARNING;
12928 goto end_table_stats;
12929 }
12930
12931 if (!json)
12932 vty_out(vty, "BGP %s RIB statistics (%s)\n",
12933 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
12934 else
12935 json_object_string_add(json, "instance", bgp->name_pretty);
12936
12937 /* labeled-unicast routes live in the unicast table */
12938 if (safi == SAFI_LABELED_UNICAST)
12939 safi = SAFI_UNICAST;
12940
12941 memset(&ts, 0, sizeof(ts));
12942 ts.table = bgp->rib[afi][safi];
12943 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
12944
12945 for (i = 0; i < BGP_STATS_MAX; i++) {
12946 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
12947 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
12948 continue;
12949
12950 switch (i) {
12951 case BGP_STATS_ASPATH_TOTHOPS:
12952 case BGP_STATS_ASPATH_TOTSIZE:
12953 if (!json) {
12954 snprintf(
12955 temp_buf, sizeof(temp_buf), "%12.2f",
12956 ts.counts[i]
12957 ? (float)ts.counts[i]
12958 / (float)ts.counts
12959 [BGP_STATS_ASPATH_COUNT]
12960 : 0);
12961 vty_out(vty, "%-30s: %s",
12962 table_stats_strs[i]
12963 [TABLE_STATS_IDX_VTY],
12964 temp_buf);
12965 } else {
12966 json_object_double_add(
12967 json,
12968 table_stats_strs[i]
12969 [TABLE_STATS_IDX_JSON],
12970 ts.counts[i]
12971 ? (double)ts.counts[i]
12972 / (double)ts.counts
12973 [BGP_STATS_ASPATH_COUNT]
12974 : 0);
12975 }
12976 break;
12977 case BGP_STATS_TOTPLEN:
12978 if (!json) {
12979 snprintf(
12980 temp_buf, sizeof(temp_buf), "%12.2f",
12981 ts.counts[i]
12982 ? (float)ts.counts[i]
12983 / (float)ts.counts
12984 [BGP_STATS_PREFIXES]
12985 : 0);
12986 vty_out(vty, "%-30s: %s",
12987 table_stats_strs[i]
12988 [TABLE_STATS_IDX_VTY],
12989 temp_buf);
12990 } else {
12991 json_object_double_add(
12992 json,
12993 table_stats_strs[i]
12994 [TABLE_STATS_IDX_JSON],
12995 ts.counts[i]
12996 ? (double)ts.counts[i]
12997 / (double)ts.counts
12998 [BGP_STATS_PREFIXES]
12999 : 0);
13000 }
13001 break;
13002 case BGP_STATS_SPACE:
13003 if (!json) {
13004 snprintf(temp_buf, sizeof(temp_buf), "%12g",
13005 ts.total_space);
13006 vty_out(vty, "%-30s: %s\n",
13007 table_stats_strs[i]
13008 [TABLE_STATS_IDX_VTY],
13009 temp_buf);
13010 } else {
13011 json_object_double_add(
13012 json,
13013 table_stats_strs[i]
13014 [TABLE_STATS_IDX_JSON],
13015 (double)ts.total_space);
13016 }
13017 if (afi == AFI_IP6) {
13018 if (!json) {
13019 snprintf(temp_buf, sizeof(temp_buf),
13020 "%12g",
13021 ts.total_space
13022 * pow(2.0, -128 + 32));
13023 vty_out(vty, "%30s: %s\n",
13024 "/32 equivalent %s\n",
13025 temp_buf);
13026 } else {
13027 json_object_double_add(
13028 json, "/32equivalent",
13029 (double)(ts.total_space
13030 * pow(2.0,
13031 -128 + 32)));
13032 }
13033 if (!json) {
13034 snprintf(temp_buf, sizeof(temp_buf),
13035 "%12g",
13036 ts.total_space
13037 * pow(2.0, -128 + 48));
13038 vty_out(vty, "%30s: %s\n",
13039 "/48 equivalent %s\n",
13040 temp_buf);
13041 } else {
13042 json_object_double_add(
13043 json, "/48equivalent",
13044 (double)(ts.total_space
13045 * pow(2.0,
13046 -128 + 48)));
13047 }
13048 } else {
13049 if (!json) {
13050 snprintf(temp_buf, sizeof(temp_buf),
13051 "%12.2f",
13052 ts.total_space * 100.
13053 * pow(2.0, -32));
13054 vty_out(vty, "%30s: %s\n",
13055 "% announced ", temp_buf);
13056 } else {
13057 json_object_double_add(
13058 json, "%announced",
13059 (double)(ts.total_space * 100.
13060 * pow(2.0, -32)));
13061 }
13062 if (!json) {
13063 snprintf(temp_buf, sizeof(temp_buf),
13064 "%12.2f",
13065 ts.total_space
13066 * pow(2.0, -32 + 8));
13067 vty_out(vty, "%30s: %s\n",
13068 "/8 equivalent ", temp_buf);
13069 } else {
13070 json_object_double_add(
13071 json, "/8equivalent",
13072 (double)(ts.total_space
13073 * pow(2.0, -32 + 8)));
13074 }
13075 if (!json) {
13076 snprintf(temp_buf, sizeof(temp_buf),
13077 "%12.2f",
13078 ts.total_space
13079 * pow(2.0, -32 + 24));
13080 vty_out(vty, "%30s: %s\n",
13081 "/24 equivalent ", temp_buf);
13082 } else {
13083 json_object_double_add(
13084 json, "/24equivalent",
13085 (double)(ts.total_space
13086 * pow(2.0, -32 + 24)));
13087 }
13088 }
13089 break;
13090 default:
13091 if (!json) {
13092 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13093 ts.counts[i]);
13094 vty_out(vty, "%-30s: %s",
13095 table_stats_strs[i]
13096 [TABLE_STATS_IDX_VTY],
13097 temp_buf);
13098 } else {
13099 json_object_int_add(
13100 json,
13101 table_stats_strs[i]
13102 [TABLE_STATS_IDX_JSON],
13103 ts.counts[i]);
13104 }
13105 }
13106 if (!json)
13107 vty_out(vty, "\n");
13108 }
13109 end_table_stats:
13110 if (json)
13111 json_object_array_add(json_array, json);
13112 return ret;
13113 }
13114
13115 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13116 safi_t safi, struct json_object *json_array)
13117 {
13118 if (!bgp) {
13119 bgp_table_stats_all(vty, afi, safi, json_array);
13120 return CMD_SUCCESS;
13121 }
13122
13123 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13124 }
13125
13126 enum bgp_pcounts {
13127 PCOUNT_ADJ_IN = 0,
13128 PCOUNT_DAMPED,
13129 PCOUNT_REMOVED,
13130 PCOUNT_HISTORY,
13131 PCOUNT_STALE,
13132 PCOUNT_VALID,
13133 PCOUNT_ALL,
13134 PCOUNT_COUNTED,
13135 PCOUNT_BPATH_SELECTED,
13136 PCOUNT_PFCNT, /* the figure we display to users */
13137 PCOUNT_MAX,
13138 };
13139
13140 static const char *const pcount_strs[] = {
13141 [PCOUNT_ADJ_IN] = "Adj-in",
13142 [PCOUNT_DAMPED] = "Damped",
13143 [PCOUNT_REMOVED] = "Removed",
13144 [PCOUNT_HISTORY] = "History",
13145 [PCOUNT_STALE] = "Stale",
13146 [PCOUNT_VALID] = "Valid",
13147 [PCOUNT_ALL] = "All RIB",
13148 [PCOUNT_COUNTED] = "PfxCt counted",
13149 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13150 [PCOUNT_PFCNT] = "Useable",
13151 [PCOUNT_MAX] = NULL,
13152 };
13153
13154 struct peer_pcounts {
13155 unsigned int count[PCOUNT_MAX];
13156 const struct peer *peer;
13157 const struct bgp_table *table;
13158 safi_t safi;
13159 };
13160
13161 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13162 {
13163 const struct bgp_adj_in *ain;
13164 const struct bgp_path_info *pi;
13165 const struct peer *peer = pc->peer;
13166
13167 for (ain = rn->adj_in; ain; ain = ain->next)
13168 if (ain->peer == peer)
13169 pc->count[PCOUNT_ADJ_IN]++;
13170
13171 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13172
13173 if (pi->peer != peer)
13174 continue;
13175
13176 pc->count[PCOUNT_ALL]++;
13177
13178 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13179 pc->count[PCOUNT_DAMPED]++;
13180 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13181 pc->count[PCOUNT_HISTORY]++;
13182 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13183 pc->count[PCOUNT_REMOVED]++;
13184 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13185 pc->count[PCOUNT_STALE]++;
13186 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13187 pc->count[PCOUNT_VALID]++;
13188 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13189 pc->count[PCOUNT_PFCNT]++;
13190 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13191 pc->count[PCOUNT_BPATH_SELECTED]++;
13192
13193 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13194 pc->count[PCOUNT_COUNTED]++;
13195 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13196 flog_err(
13197 EC_LIB_DEVELOPMENT,
13198 "Attempting to count but flags say it is unusable");
13199 } else {
13200 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13201 flog_err(
13202 EC_LIB_DEVELOPMENT,
13203 "Not counted but flags say we should");
13204 }
13205 }
13206 }
13207
13208 static void bgp_peer_count_walker(struct thread *t)
13209 {
13210 struct bgp_dest *rn, *rm;
13211 const struct bgp_table *table;
13212 struct peer_pcounts *pc = THREAD_ARG(t);
13213
13214 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13215 || pc->safi == SAFI_EVPN) {
13216 /* Special handling for 2-level routing tables. */
13217 for (rn = bgp_table_top(pc->table); rn;
13218 rn = bgp_route_next(rn)) {
13219 table = bgp_dest_get_bgp_table_info(rn);
13220 if (table != NULL)
13221 for (rm = bgp_table_top(table); rm;
13222 rm = bgp_route_next(rm))
13223 bgp_peer_count_proc(rm, pc);
13224 }
13225 } else
13226 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13227 bgp_peer_count_proc(rn, pc);
13228 }
13229
13230 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13231 safi_t safi, bool use_json)
13232 {
13233 struct peer_pcounts pcounts = {.peer = peer};
13234 unsigned int i;
13235 json_object *json = NULL;
13236 json_object *json_loop = NULL;
13237
13238 if (use_json) {
13239 json = json_object_new_object();
13240 json_loop = json_object_new_object();
13241 }
13242
13243 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13244 || !peer->bgp->rib[afi][safi]) {
13245 if (use_json) {
13246 json_object_string_add(
13247 json, "warning",
13248 "No such neighbor or address family");
13249 vty_out(vty, "%s\n", json_object_to_json_string(json));
13250 json_object_free(json);
13251 json_object_free(json_loop);
13252 } else
13253 vty_out(vty, "%% No such neighbor or address family\n");
13254
13255 return CMD_WARNING;
13256 }
13257
13258 memset(&pcounts, 0, sizeof(pcounts));
13259 pcounts.peer = peer;
13260 pcounts.table = peer->bgp->rib[afi][safi];
13261 pcounts.safi = safi;
13262
13263 /* in-place call via thread subsystem so as to record execution time
13264 * stats for the thread-walk (i.e. ensure this can't be blamed on
13265 * on just vty_read()).
13266 */
13267 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13268
13269 if (use_json) {
13270 json_object_string_add(json, "prefixCountsFor", peer->host);
13271 json_object_string_add(json, "multiProtocol",
13272 get_afi_safi_str(afi, safi, true));
13273 json_object_int_add(json, "pfxCounter",
13274 peer->pcount[afi][safi]);
13275
13276 for (i = 0; i < PCOUNT_MAX; i++)
13277 json_object_int_add(json_loop, pcount_strs[i],
13278 pcounts.count[i]);
13279
13280 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13281
13282 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13283 json_object_string_add(json, "pfxctDriftFor",
13284 peer->host);
13285 json_object_string_add(
13286 json, "recommended",
13287 "Please report this bug, with the above command output");
13288 }
13289 vty_json(vty, json);
13290 } else {
13291
13292 if (peer->hostname
13293 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13294 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13295 peer->hostname, peer->host,
13296 get_afi_safi_str(afi, safi, false));
13297 } else {
13298 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13299 get_afi_safi_str(afi, safi, false));
13300 }
13301
13302 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13303 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13304
13305 for (i = 0; i < PCOUNT_MAX; i++)
13306 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13307 pcounts.count[i]);
13308
13309 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13310 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13311 vty_out(vty,
13312 "Please report this bug, with the above command output\n");
13313 }
13314 }
13315
13316 return CMD_SUCCESS;
13317 }
13318
13319 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13320 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13321 "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]",
13322 SHOW_STR
13323 IP_STR
13324 BGP_STR
13325 BGP_INSTANCE_HELP_STR
13326 BGP_AFI_HELP_STR
13327 BGP_SAFI_HELP_STR
13328 "Detailed information on TCP and BGP neighbor connections\n"
13329 "Neighbor to display information about\n"
13330 "Neighbor to display information about\n"
13331 "Neighbor on BGP configured interface\n"
13332 "Display detailed prefix count information\n"
13333 JSON_STR)
13334 {
13335 afi_t afi = AFI_IP6;
13336 safi_t safi = SAFI_UNICAST;
13337 struct peer *peer;
13338 int idx = 0;
13339 struct bgp *bgp = NULL;
13340 bool uj = use_json(argc, argv);
13341
13342 if (uj)
13343 argc--;
13344
13345 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13346 &bgp, uj);
13347 if (!idx)
13348 return CMD_WARNING;
13349
13350 argv_find(argv, argc, "neighbors", &idx);
13351 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13352 if (!peer)
13353 return CMD_WARNING;
13354
13355 return bgp_peer_counts(vty, peer, afi, safi, uj);
13356 }
13357
13358 #ifdef KEEP_OLD_VPN_COMMANDS
13359 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13360 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13361 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13362 SHOW_STR
13363 IP_STR
13364 BGP_STR
13365 BGP_VPNVX_HELP_STR
13366 "Display information about all VPNv4 NLRIs\n"
13367 "Detailed information on TCP and BGP neighbor connections\n"
13368 "Neighbor to display information about\n"
13369 "Neighbor to display information about\n"
13370 "Neighbor on BGP configured interface\n"
13371 "Display detailed prefix count information\n"
13372 JSON_STR)
13373 {
13374 int idx_peer = 6;
13375 struct peer *peer;
13376 bool uj = use_json(argc, argv);
13377
13378 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13379 if (!peer)
13380 return CMD_WARNING;
13381
13382 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13383 }
13384
13385 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13386 show_ip_bgp_vpn_all_route_prefix_cmd,
13387 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13388 SHOW_STR
13389 IP_STR
13390 BGP_STR
13391 BGP_VPNVX_HELP_STR
13392 "Display information about all VPNv4 NLRIs\n"
13393 "Network in the BGP routing table to display\n"
13394 "Network in the BGP routing table to display\n"
13395 JSON_STR)
13396 {
13397 int idx = 0;
13398 char *network = NULL;
13399 struct bgp *bgp = bgp_get_default();
13400 if (!bgp) {
13401 vty_out(vty, "Can't find default instance\n");
13402 return CMD_WARNING;
13403 }
13404
13405 if (argv_find(argv, argc, "A.B.C.D", &idx))
13406 network = argv[idx]->arg;
13407 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13408 network = argv[idx]->arg;
13409 else {
13410 vty_out(vty, "Unable to figure out Network\n");
13411 return CMD_WARNING;
13412 }
13413
13414 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13415 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13416 use_json(argc, argv));
13417 }
13418 #endif /* KEEP_OLD_VPN_COMMANDS */
13419
13420 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13421 show_bgp_l2vpn_evpn_route_prefix_cmd,
13422 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13423 SHOW_STR
13424 BGP_STR
13425 L2VPN_HELP_STR
13426 EVPN_HELP_STR
13427 "Network in the BGP routing table to display\n"
13428 "Network in the BGP routing table to display\n"
13429 "Network in the BGP routing table to display\n"
13430 "Network in the BGP routing table to display\n"
13431 JSON_STR)
13432 {
13433 int idx = 0;
13434 char *network = NULL;
13435 int prefix_check = 0;
13436
13437 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13438 argv_find(argv, argc, "X:X::X:X", &idx))
13439 network = argv[idx]->arg;
13440 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13441 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13442 network = argv[idx]->arg;
13443 prefix_check = 1;
13444 } else {
13445 vty_out(vty, "Unable to figure out Network\n");
13446 return CMD_WARNING;
13447 }
13448 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13449 prefix_check, BGP_PATH_SHOW_ALL,
13450 RPKI_NOT_BEING_USED, use_json(argc, argv));
13451 }
13452
13453 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
13454 struct bgp_table *table, int *header1,
13455 int *header2, json_object *json,
13456 json_object *json_scode,
13457 json_object *json_ocode, bool wide)
13458 {
13459 uint64_t version = table ? table->version : 0;
13460
13461 if (*header1) {
13462 if (json) {
13463 json_object_int_add(json, "bgpTableVersion", version);
13464 json_object_string_addf(json, "bgpLocalRouterId",
13465 "%pI4", &bgp->router_id);
13466 json_object_int_add(json, "defaultLocPrf",
13467 bgp->default_local_pref);
13468 json_object_int_add(json, "localAS", bgp->as);
13469 json_object_object_add(json, "bgpStatusCodes",
13470 json_scode);
13471 json_object_object_add(json, "bgpOriginCodes",
13472 json_ocode);
13473 } else {
13474 vty_out(vty,
13475 "BGP table version is %" PRIu64
13476 ", local router ID is %pI4, vrf id ",
13477 version, &bgp->router_id);
13478 if (bgp->vrf_id == VRF_UNKNOWN)
13479 vty_out(vty, "%s", VRFID_NONE_STR);
13480 else
13481 vty_out(vty, "%u", bgp->vrf_id);
13482 vty_out(vty, "\n");
13483 vty_out(vty, "Default local pref %u, ",
13484 bgp->default_local_pref);
13485 vty_out(vty, "local AS %u\n", bgp->as);
13486 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13487 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13488 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13489 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13490 }
13491 *header1 = 0;
13492 }
13493 if (*header2) {
13494 if (!json)
13495 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13496 : BGP_SHOW_HEADER));
13497 *header2 = 0;
13498 }
13499 }
13500
13501 static void
13502 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13503 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13504 const char *rmap_name, json_object *json, json_object *json_ar,
13505 json_object *json_scode, json_object *json_ocode,
13506 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13507 unsigned long *output_count, unsigned long *filtered_count)
13508 {
13509 struct bgp_adj_in *ain;
13510 struct bgp_adj_out *adj;
13511 struct bgp_dest *dest;
13512 struct bgp *bgp;
13513 struct attr attr;
13514 int ret;
13515 struct update_subgroup *subgrp;
13516 struct peer_af *paf;
13517 bool route_filtered;
13518 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13519 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13520 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13521 || (safi == SAFI_EVPN))
13522 ? true
13523 : false;
13524
13525 bgp = peer->bgp;
13526
13527 subgrp = peer_subgroup(peer, afi, safi);
13528
13529 if (type == bgp_show_adj_route_advertised && subgrp
13530 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13531 if (use_json) {
13532 json_object_int_add(json, "bgpTableVersion",
13533 table->version);
13534 json_object_string_addf(json, "bgpLocalRouterId",
13535 "%pI4", &bgp->router_id);
13536 json_object_int_add(json, "defaultLocPrf",
13537 bgp->default_local_pref);
13538 json_object_int_add(json, "localAS", bgp->as);
13539 json_object_object_add(json, "bgpStatusCodes",
13540 json_scode);
13541 json_object_object_add(json, "bgpOriginCodes",
13542 json_ocode);
13543 json_object_string_add(
13544 json, "bgpOriginatingDefaultNetwork",
13545 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13546 } else {
13547 vty_out(vty,
13548 "BGP table version is %" PRIu64
13549 ", local router ID is %pI4, vrf id ",
13550 table->version, &bgp->router_id);
13551 if (bgp->vrf_id == VRF_UNKNOWN)
13552 vty_out(vty, "%s", VRFID_NONE_STR);
13553 else
13554 vty_out(vty, "%u", bgp->vrf_id);
13555 vty_out(vty, "\n");
13556 vty_out(vty, "Default local pref %u, ",
13557 bgp->default_local_pref);
13558 vty_out(vty, "local AS %u\n", bgp->as);
13559 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13560 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13561 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13562 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13563
13564 vty_out(vty, "Originating default network %s\n\n",
13565 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13566 }
13567 *header1 = 0;
13568 }
13569
13570 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13571 if (type == bgp_show_adj_route_received
13572 || type == bgp_show_adj_route_filtered) {
13573 for (ain = dest->adj_in; ain; ain = ain->next) {
13574 if (ain->peer != peer)
13575 continue;
13576
13577 show_adj_route_header(vty, bgp, table, header1,
13578 header2, json, json_scode,
13579 json_ocode, wide);
13580
13581 if ((safi == SAFI_MPLS_VPN)
13582 || (safi == SAFI_ENCAP)
13583 || (safi == SAFI_EVPN)) {
13584 if (use_json)
13585 json_object_string_add(
13586 json_ar, "rd", rd_str);
13587 else if (show_rd && rd_str) {
13588 vty_out(vty,
13589 "Route Distinguisher: %s\n",
13590 rd_str);
13591 show_rd = false;
13592 }
13593 }
13594
13595 attr = *ain->attr;
13596 route_filtered = false;
13597
13598 /* Filter prefix using distribute list,
13599 * filter list or prefix list
13600 */
13601 const struct prefix *rn_p =
13602 bgp_dest_get_prefix(dest);
13603 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13604 safi))
13605 == FILTER_DENY)
13606 route_filtered = true;
13607
13608 /* Filter prefix using route-map */
13609 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13610 safi, rmap_name, NULL,
13611 0, NULL);
13612
13613 if (type == bgp_show_adj_route_filtered &&
13614 !route_filtered && ret != RMAP_DENY) {
13615 bgp_attr_flush(&attr);
13616 continue;
13617 }
13618
13619 if (type == bgp_show_adj_route_received
13620 && (route_filtered || ret == RMAP_DENY))
13621 (*filtered_count)++;
13622
13623 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
13624 use_json, json_ar, wide);
13625 bgp_attr_flush(&attr);
13626 (*output_count)++;
13627 }
13628 } else if (type == bgp_show_adj_route_advertised) {
13629 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13630 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13631 if (paf->peer != peer || !adj->attr)
13632 continue;
13633
13634 show_adj_route_header(vty, bgp, table,
13635 header1, header2,
13636 json, json_scode,
13637 json_ocode, wide);
13638
13639 const struct prefix *rn_p =
13640 bgp_dest_get_prefix(dest);
13641
13642 attr = *adj->attr;
13643 ret = bgp_output_modifier(
13644 peer, rn_p, &attr, afi, safi,
13645 rmap_name);
13646
13647 if (ret != RMAP_DENY) {
13648 if ((safi == SAFI_MPLS_VPN)
13649 || (safi == SAFI_ENCAP)
13650 || (safi == SAFI_EVPN)) {
13651 if (use_json)
13652 json_object_string_add(
13653 json_ar,
13654 "rd",
13655 rd_str);
13656 else if (show_rd
13657 && rd_str) {
13658 vty_out(vty,
13659 "Route Distinguisher: %s\n",
13660 rd_str);
13661 show_rd = false;
13662 }
13663 }
13664 route_vty_out_tmp(
13665 vty, dest, rn_p, &attr,
13666 safi, use_json, json_ar,
13667 wide);
13668 (*output_count)++;
13669 } else {
13670 (*filtered_count)++;
13671 }
13672
13673 bgp_attr_flush(&attr);
13674 }
13675 } else if (type == bgp_show_adj_route_bestpath) {
13676 struct bgp_path_info *pi;
13677
13678 show_adj_route_header(vty, bgp, table, header1, header2,
13679 json, json_scode, json_ocode,
13680 wide);
13681
13682 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13683 pi = pi->next) {
13684 if (pi->peer != peer)
13685 continue;
13686
13687 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13688 continue;
13689
13690 route_vty_out_tmp(vty, dest,
13691 bgp_dest_get_prefix(dest),
13692 pi->attr, safi, use_json,
13693 json_ar, wide);
13694 (*output_count)++;
13695 }
13696 }
13697 }
13698 }
13699
13700 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13701 safi_t safi, enum bgp_show_adj_route_type type,
13702 const char *rmap_name, uint16_t show_flags)
13703 {
13704 struct bgp *bgp;
13705 struct bgp_table *table;
13706 json_object *json = NULL;
13707 json_object *json_scode = NULL;
13708 json_object *json_ocode = NULL;
13709 json_object *json_ar = NULL;
13710 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13711
13712 /* Init BGP headers here so they're only displayed once
13713 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13714 */
13715 int header1 = 1;
13716 int header2 = 1;
13717
13718 /*
13719 * Initialize variables for each RD
13720 * All prefixes under an RD is aggregated within "json_routes"
13721 */
13722 char rd_str[BUFSIZ] = {0};
13723 json_object *json_routes = NULL;
13724
13725
13726 /* For 2-tier tables, prefix counts need to be
13727 * maintained across multiple runs of show_adj_route()
13728 */
13729 unsigned long output_count_per_rd;
13730 unsigned long filtered_count_per_rd;
13731 unsigned long output_count = 0;
13732 unsigned long filtered_count = 0;
13733
13734 if (use_json) {
13735 json = json_object_new_object();
13736 json_ar = json_object_new_object();
13737 json_scode = json_object_new_object();
13738 json_ocode = json_object_new_object();
13739
13740 json_object_string_add(json_scode, "suppressed", "s");
13741 json_object_string_add(json_scode, "damped", "d");
13742 json_object_string_add(json_scode, "history", "h");
13743 json_object_string_add(json_scode, "valid", "*");
13744 json_object_string_add(json_scode, "best", ">");
13745 json_object_string_add(json_scode, "multipath", "=");
13746 json_object_string_add(json_scode, "internal", "i");
13747 json_object_string_add(json_scode, "ribFailure", "r");
13748 json_object_string_add(json_scode, "stale", "S");
13749 json_object_string_add(json_scode, "removed", "R");
13750
13751 json_object_string_add(json_ocode, "igp", "i");
13752 json_object_string_add(json_ocode, "egp", "e");
13753 json_object_string_add(json_ocode, "incomplete", "?");
13754 }
13755
13756 if (!peer || !peer->afc[afi][safi]) {
13757 if (use_json) {
13758 json_object_string_add(
13759 json, "warning",
13760 "No such neighbor or address family");
13761 vty_out(vty, "%s\n", json_object_to_json_string(json));
13762 json_object_free(json);
13763 json_object_free(json_ar);
13764 json_object_free(json_scode);
13765 json_object_free(json_ocode);
13766 } else
13767 vty_out(vty, "%% No such neighbor or address family\n");
13768
13769 return CMD_WARNING;
13770 }
13771
13772 if ((type == bgp_show_adj_route_received
13773 || type == bgp_show_adj_route_filtered)
13774 && !CHECK_FLAG(peer->af_flags[afi][safi],
13775 PEER_FLAG_SOFT_RECONFIG)) {
13776 if (use_json) {
13777 json_object_string_add(
13778 json, "warning",
13779 "Inbound soft reconfiguration not enabled");
13780 vty_out(vty, "%s\n", json_object_to_json_string(json));
13781 json_object_free(json);
13782 json_object_free(json_ar);
13783 json_object_free(json_scode);
13784 json_object_free(json_ocode);
13785 } else
13786 vty_out(vty,
13787 "%% Inbound soft reconfiguration not enabled\n");
13788
13789 return CMD_WARNING;
13790 }
13791
13792 bgp = peer->bgp;
13793
13794 /* labeled-unicast routes live in the unicast table */
13795 if (safi == SAFI_LABELED_UNICAST)
13796 table = bgp->rib[afi][SAFI_UNICAST];
13797 else
13798 table = bgp->rib[afi][safi];
13799
13800 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13801 || (safi == SAFI_EVPN)) {
13802
13803 struct bgp_dest *dest;
13804
13805 for (dest = bgp_table_top(table); dest;
13806 dest = bgp_route_next(dest)) {
13807 table = bgp_dest_get_bgp_table_info(dest);
13808 if (!table)
13809 continue;
13810
13811 output_count_per_rd = 0;
13812 filtered_count_per_rd = 0;
13813
13814 if (use_json)
13815 json_routes = json_object_new_object();
13816
13817 const struct prefix_rd *prd;
13818 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13819 dest);
13820
13821 prefix_rd2str(prd, rd_str, sizeof(rd_str));
13822
13823 show_adj_route(vty, peer, table, afi, safi, type,
13824 rmap_name, json, json_routes, json_scode,
13825 json_ocode, show_flags, &header1,
13826 &header2, rd_str, &output_count_per_rd,
13827 &filtered_count_per_rd);
13828
13829 /* Don't include an empty RD in the output! */
13830 if (json_routes && (output_count_per_rd > 0))
13831 json_object_object_add(json_ar, rd_str,
13832 json_routes);
13833
13834 output_count += output_count_per_rd;
13835 filtered_count += filtered_count_per_rd;
13836 }
13837 } else
13838 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
13839 json, json_ar, json_scode, json_ocode,
13840 show_flags, &header1, &header2, rd_str,
13841 &output_count, &filtered_count);
13842
13843 if (use_json) {
13844 if (type == bgp_show_adj_route_advertised)
13845 json_object_object_add(json, "advertisedRoutes",
13846 json_ar);
13847 else
13848 json_object_object_add(json, "receivedRoutes", json_ar);
13849 json_object_int_add(json, "totalPrefixCounter", output_count);
13850 json_object_int_add(json, "filteredPrefixCounter",
13851 filtered_count);
13852
13853 /*
13854 * These fields only give up ownership to `json` when `header1`
13855 * is used (set to zero). See code in `show_adj_route` and
13856 * `show_adj_route_header`.
13857 */
13858 if (header1 == 1) {
13859 json_object_free(json_scode);
13860 json_object_free(json_ocode);
13861 }
13862
13863 vty_json(vty, json);
13864 } else if (output_count > 0) {
13865 if (filtered_count > 0)
13866 vty_out(vty,
13867 "\nTotal number of prefixes %ld (%ld filtered)\n",
13868 output_count, filtered_count);
13869 else
13870 vty_out(vty, "\nTotal number of prefixes %ld\n",
13871 output_count);
13872 }
13873
13874 return CMD_SUCCESS;
13875 }
13876
13877 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
13878 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
13879 "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]",
13880 SHOW_STR
13881 IP_STR
13882 BGP_STR
13883 BGP_INSTANCE_HELP_STR
13884 BGP_AFI_HELP_STR
13885 BGP_SAFI_WITH_LABEL_HELP_STR
13886 "Detailed information on TCP and BGP neighbor connections\n"
13887 "Neighbor to display information about\n"
13888 "Neighbor to display information about\n"
13889 "Neighbor on BGP configured interface\n"
13890 "Display the routes selected by best path\n"
13891 JSON_STR
13892 "Increase table width for longer prefixes\n")
13893 {
13894 afi_t afi = AFI_IP6;
13895 safi_t safi = SAFI_UNICAST;
13896 char *rmap_name = NULL;
13897 char *peerstr = NULL;
13898 struct bgp *bgp = NULL;
13899 struct peer *peer;
13900 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
13901 int idx = 0;
13902 uint16_t show_flags = 0;
13903
13904 if (uj)
13905 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13906
13907 if (wide)
13908 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13909
13910 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13911 &bgp, uj);
13912
13913 if (!idx)
13914 return CMD_WARNING;
13915
13916 argv_find(argv, argc, "neighbors", &idx);
13917 peerstr = argv[++idx]->arg;
13918
13919 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13920 if (!peer)
13921 return CMD_WARNING;
13922
13923 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13924 show_flags);
13925 }
13926
13927 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
13928 show_ip_bgp_instance_neighbor_advertised_route_cmd,
13929 "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]",
13930 SHOW_STR
13931 IP_STR
13932 BGP_STR
13933 BGP_INSTANCE_HELP_STR
13934 BGP_AFI_HELP_STR
13935 BGP_SAFI_WITH_LABEL_HELP_STR
13936 "Display the entries for all address families\n"
13937 "Detailed information on TCP and BGP neighbor connections\n"
13938 "Neighbor to display information about\n"
13939 "Neighbor to display information about\n"
13940 "Neighbor on BGP configured interface\n"
13941 "Display the routes advertised to a BGP neighbor\n"
13942 "Display the received routes from neighbor\n"
13943 "Display the filtered routes received from neighbor\n"
13944 "Route-map to modify the attributes\n"
13945 "Name of the route map\n"
13946 JSON_STR
13947 "Increase table width for longer prefixes\n")
13948 {
13949 afi_t afi = AFI_IP6;
13950 safi_t safi = SAFI_UNICAST;
13951 char *rmap_name = NULL;
13952 char *peerstr = NULL;
13953 struct bgp *bgp = NULL;
13954 struct peer *peer;
13955 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
13956 int idx = 0;
13957 bool first = true;
13958 uint16_t show_flags = 0;
13959
13960 if (uj) {
13961 argc--;
13962 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13963 }
13964
13965 if (all) {
13966 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
13967 if (argv_find(argv, argc, "ipv4", &idx))
13968 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
13969
13970 if (argv_find(argv, argc, "ipv6", &idx))
13971 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
13972 }
13973
13974 if (wide)
13975 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13976
13977 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13978 &bgp, uj);
13979 if (!idx)
13980 return CMD_WARNING;
13981
13982 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13983 argv_find(argv, argc, "neighbors", &idx);
13984 peerstr = argv[++idx]->arg;
13985
13986 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13987 if (!peer)
13988 return CMD_WARNING;
13989
13990 if (argv_find(argv, argc, "advertised-routes", &idx))
13991 type = bgp_show_adj_route_advertised;
13992 else if (argv_find(argv, argc, "received-routes", &idx))
13993 type = bgp_show_adj_route_received;
13994 else if (argv_find(argv, argc, "filtered-routes", &idx))
13995 type = bgp_show_adj_route_filtered;
13996
13997 if (argv_find(argv, argc, "route-map", &idx))
13998 rmap_name = argv[++idx]->arg;
13999
14000 if (!all)
14001 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14002 show_flags);
14003 if (uj)
14004 vty_out(vty, "{\n");
14005
14006 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14007 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14008 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14009 : AFI_IP6;
14010 FOREACH_SAFI (safi) {
14011 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
14012 continue;
14013
14014 if (uj) {
14015 if (first)
14016 first = false;
14017 else
14018 vty_out(vty, ",\n");
14019 vty_out(vty, "\"%s\":",
14020 get_afi_safi_str(afi, safi, true));
14021 } else
14022 vty_out(vty, "\nFor address family: %s\n",
14023 get_afi_safi_str(afi, safi, false));
14024
14025 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14026 show_flags);
14027 }
14028 } else {
14029 FOREACH_AFI_SAFI (afi, safi) {
14030 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
14031 continue;
14032
14033 if (uj) {
14034 if (first)
14035 first = false;
14036 else
14037 vty_out(vty, ",\n");
14038 vty_out(vty, "\"%s\":",
14039 get_afi_safi_str(afi, safi, true));
14040 } else
14041 vty_out(vty, "\nFor address family: %s\n",
14042 get_afi_safi_str(afi, safi, false));
14043
14044 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14045 show_flags);
14046 }
14047 }
14048 if (uj)
14049 vty_out(vty, "}\n");
14050
14051 return CMD_SUCCESS;
14052 }
14053
14054 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14055 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14056 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14057 SHOW_STR
14058 IP_STR
14059 BGP_STR
14060 BGP_INSTANCE_HELP_STR
14061 "Address Family\n"
14062 "Address Family\n"
14063 "Address Family modifier\n"
14064 "Detailed information on TCP and BGP neighbor connections\n"
14065 "Neighbor to display information about\n"
14066 "Neighbor to display information about\n"
14067 "Neighbor on BGP configured interface\n"
14068 "Display information received from a BGP neighbor\n"
14069 "Display the prefixlist filter\n"
14070 JSON_STR)
14071 {
14072 afi_t afi = AFI_IP6;
14073 safi_t safi = SAFI_UNICAST;
14074 char *peerstr = NULL;
14075 char name[BUFSIZ];
14076 struct peer *peer;
14077 int count;
14078 int idx = 0;
14079 struct bgp *bgp = NULL;
14080 bool uj = use_json(argc, argv);
14081
14082 if (uj)
14083 argc--;
14084
14085 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14086 &bgp, uj);
14087 if (!idx)
14088 return CMD_WARNING;
14089
14090 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14091 argv_find(argv, argc, "neighbors", &idx);
14092 peerstr = argv[++idx]->arg;
14093
14094 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14095 if (!peer)
14096 return CMD_WARNING;
14097
14098 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14099 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14100 if (count) {
14101 if (!uj)
14102 vty_out(vty, "Address Family: %s\n",
14103 get_afi_safi_str(afi, safi, false));
14104 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14105 } else {
14106 if (uj)
14107 vty_out(vty, "{}\n");
14108 else
14109 vty_out(vty, "No functional output\n");
14110 }
14111
14112 return CMD_SUCCESS;
14113 }
14114
14115 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14116 afi_t afi, safi_t safi,
14117 enum bgp_show_type type, bool use_json)
14118 {
14119 uint16_t show_flags = 0;
14120
14121 if (use_json)
14122 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14123
14124 if (!peer || !peer->afc[afi][safi]) {
14125 if (use_json) {
14126 json_object *json_no = NULL;
14127 json_no = json_object_new_object();
14128 json_object_string_add(
14129 json_no, "warning",
14130 "No such neighbor or address family");
14131 vty_out(vty, "%s\n",
14132 json_object_to_json_string(json_no));
14133 json_object_free(json_no);
14134 } else
14135 vty_out(vty, "%% No such neighbor or address family\n");
14136 return CMD_WARNING;
14137 }
14138
14139 /* labeled-unicast routes live in the unicast table */
14140 if (safi == SAFI_LABELED_UNICAST)
14141 safi = SAFI_UNICAST;
14142
14143 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14144 RPKI_NOT_BEING_USED);
14145 }
14146
14147 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14148 show_ip_bgp_flowspec_routes_detailed_cmd,
14149 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14150 SHOW_STR
14151 IP_STR
14152 BGP_STR
14153 BGP_INSTANCE_HELP_STR
14154 BGP_AFI_HELP_STR
14155 "SAFI Flowspec\n"
14156 "Detailed information on flowspec entries\n"
14157 JSON_STR)
14158 {
14159 afi_t afi = AFI_IP6;
14160 safi_t safi = SAFI_UNICAST;
14161 struct bgp *bgp = NULL;
14162 int idx = 0;
14163 bool uj = use_json(argc, argv);
14164 uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
14165
14166 if (uj) {
14167 argc--;
14168 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14169 }
14170
14171 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14172 &bgp, uj);
14173 if (!idx)
14174 return CMD_WARNING;
14175
14176 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14177 show_flags, RPKI_NOT_BEING_USED);
14178 }
14179
14180 DEFUN (show_ip_bgp_neighbor_routes,
14181 show_ip_bgp_neighbor_routes_cmd,
14182 "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]",
14183 SHOW_STR
14184 IP_STR
14185 BGP_STR
14186 BGP_INSTANCE_HELP_STR
14187 BGP_AFI_HELP_STR
14188 BGP_SAFI_WITH_LABEL_HELP_STR
14189 "Detailed information on TCP and BGP neighbor connections\n"
14190 "Neighbor to display information about\n"
14191 "Neighbor to display information about\n"
14192 "Neighbor on BGP configured interface\n"
14193 "Display flap statistics of the routes learned from neighbor\n"
14194 "Display the dampened routes received from neighbor\n"
14195 "Display routes learned from neighbor\n"
14196 JSON_STR)
14197 {
14198 char *peerstr = NULL;
14199 struct bgp *bgp = NULL;
14200 afi_t afi = AFI_IP6;
14201 safi_t safi = SAFI_UNICAST;
14202 struct peer *peer;
14203 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14204 int idx = 0;
14205 bool uj = use_json(argc, argv);
14206
14207 if (uj)
14208 argc--;
14209
14210 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14211 &bgp, uj);
14212 if (!idx)
14213 return CMD_WARNING;
14214
14215 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14216 argv_find(argv, argc, "neighbors", &idx);
14217 peerstr = argv[++idx]->arg;
14218
14219 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14220 if (!peer)
14221 return CMD_WARNING;
14222
14223 if (argv_find(argv, argc, "flap-statistics", &idx))
14224 sh_type = bgp_show_type_flap_neighbor;
14225 else if (argv_find(argv, argc, "dampened-routes", &idx))
14226 sh_type = bgp_show_type_damp_neighbor;
14227 else if (argv_find(argv, argc, "routes", &idx))
14228 sh_type = bgp_show_type_neighbor;
14229
14230 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14231 }
14232
14233 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14234
14235 struct bgp_distance {
14236 /* Distance value for the IP source prefix. */
14237 uint8_t distance;
14238
14239 /* Name of the access-list to be matched. */
14240 char *access_list;
14241 };
14242
14243 DEFUN (show_bgp_afi_vpn_rd_route,
14244 show_bgp_afi_vpn_rd_route_cmd,
14245 "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]",
14246 SHOW_STR
14247 BGP_STR
14248 BGP_AFI_HELP_STR
14249 "Address Family modifier\n"
14250 "Display information for a route distinguisher\n"
14251 "Route Distinguisher\n"
14252 "All Route Distinguishers\n"
14253 "Network in the BGP routing table to display\n"
14254 "Network in the BGP routing table to display\n"
14255 JSON_STR)
14256 {
14257 int ret;
14258 struct prefix_rd prd;
14259 afi_t afi = AFI_MAX;
14260 int idx = 0;
14261
14262 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14263 vty_out(vty, "%% Malformed Address Family\n");
14264 return CMD_WARNING;
14265 }
14266
14267 if (!strcmp(argv[5]->arg, "all"))
14268 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14269 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14270 RPKI_NOT_BEING_USED,
14271 use_json(argc, argv));
14272
14273 ret = str2prefix_rd(argv[5]->arg, &prd);
14274 if (!ret) {
14275 vty_out(vty, "%% Malformed Route Distinguisher\n");
14276 return CMD_WARNING;
14277 }
14278
14279 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14280 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14281 use_json(argc, argv));
14282 }
14283
14284 static struct bgp_distance *bgp_distance_new(void)
14285 {
14286 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14287 }
14288
14289 static void bgp_distance_free(struct bgp_distance *bdistance)
14290 {
14291 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14292 }
14293
14294 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14295 const char *ip_str, const char *access_list_str)
14296 {
14297 int ret;
14298 afi_t afi;
14299 safi_t safi;
14300 struct prefix p;
14301 uint8_t distance;
14302 struct bgp_dest *dest;
14303 struct bgp_distance *bdistance;
14304
14305 afi = bgp_node_afi(vty);
14306 safi = bgp_node_safi(vty);
14307
14308 ret = str2prefix(ip_str, &p);
14309 if (ret == 0) {
14310 vty_out(vty, "Malformed prefix\n");
14311 return CMD_WARNING_CONFIG_FAILED;
14312 }
14313
14314 distance = atoi(distance_str);
14315
14316 /* Get BGP distance node. */
14317 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14318 bdistance = bgp_dest_get_bgp_distance_info(dest);
14319 if (bdistance)
14320 bgp_dest_unlock_node(dest);
14321 else {
14322 bdistance = bgp_distance_new();
14323 bgp_dest_set_bgp_distance_info(dest, bdistance);
14324 }
14325
14326 /* Set distance value. */
14327 bdistance->distance = distance;
14328
14329 /* Reset access-list configuration. */
14330 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14331 if (access_list_str)
14332 bdistance->access_list =
14333 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14334
14335 return CMD_SUCCESS;
14336 }
14337
14338 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14339 const char *ip_str, const char *access_list_str)
14340 {
14341 int ret;
14342 afi_t afi;
14343 safi_t safi;
14344 struct prefix p;
14345 int distance;
14346 struct bgp_dest *dest;
14347 struct bgp_distance *bdistance;
14348
14349 afi = bgp_node_afi(vty);
14350 safi = bgp_node_safi(vty);
14351
14352 ret = str2prefix(ip_str, &p);
14353 if (ret == 0) {
14354 vty_out(vty, "Malformed prefix\n");
14355 return CMD_WARNING_CONFIG_FAILED;
14356 }
14357
14358 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14359 if (!dest) {
14360 vty_out(vty, "Can't find specified prefix\n");
14361 return CMD_WARNING_CONFIG_FAILED;
14362 }
14363
14364 bdistance = bgp_dest_get_bgp_distance_info(dest);
14365 distance = atoi(distance_str);
14366
14367 if (bdistance->distance != distance) {
14368 vty_out(vty, "Distance does not match configured\n");
14369 bgp_dest_unlock_node(dest);
14370 return CMD_WARNING_CONFIG_FAILED;
14371 }
14372
14373 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14374 bgp_distance_free(bdistance);
14375
14376 bgp_dest_set_bgp_path_info(dest, NULL);
14377 bgp_dest_unlock_node(dest);
14378 bgp_dest_unlock_node(dest);
14379
14380 return CMD_SUCCESS;
14381 }
14382
14383 /* Apply BGP information to distance method. */
14384 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14385 afi_t afi, safi_t safi, struct bgp *bgp)
14386 {
14387 struct bgp_dest *dest;
14388 struct prefix q = {0};
14389 struct peer *peer;
14390 struct bgp_distance *bdistance;
14391 struct access_list *alist;
14392 struct bgp_static *bgp_static;
14393
14394 if (!bgp)
14395 return 0;
14396
14397 peer = pinfo->peer;
14398
14399 if (pinfo->attr->distance)
14400 return pinfo->attr->distance;
14401
14402 /* Check source address.
14403 * Note: for aggregate route, peer can have unspec af type.
14404 */
14405 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14406 && !sockunion2hostprefix(&peer->su, &q))
14407 return 0;
14408
14409 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14410 if (dest) {
14411 bdistance = bgp_dest_get_bgp_distance_info(dest);
14412 bgp_dest_unlock_node(dest);
14413
14414 if (bdistance->access_list) {
14415 alist = access_list_lookup(afi, bdistance->access_list);
14416 if (alist
14417 && access_list_apply(alist, p) == FILTER_PERMIT)
14418 return bdistance->distance;
14419 } else
14420 return bdistance->distance;
14421 }
14422
14423 /* Backdoor check. */
14424 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14425 if (dest) {
14426 bgp_static = bgp_dest_get_bgp_static_info(dest);
14427 bgp_dest_unlock_node(dest);
14428
14429 if (bgp_static->backdoor) {
14430 if (bgp->distance_local[afi][safi])
14431 return bgp->distance_local[afi][safi];
14432 else
14433 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14434 }
14435 }
14436
14437 if (peer->sort == BGP_PEER_EBGP) {
14438 if (bgp->distance_ebgp[afi][safi])
14439 return bgp->distance_ebgp[afi][safi];
14440 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14441 } else if (peer->sort == BGP_PEER_IBGP) {
14442 if (bgp->distance_ibgp[afi][safi])
14443 return bgp->distance_ibgp[afi][safi];
14444 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14445 } else {
14446 if (bgp->distance_local[afi][safi])
14447 return bgp->distance_local[afi][safi];
14448 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14449 }
14450 }
14451
14452 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14453 * we should tell ZEBRA update the routes for a specific
14454 * AFI/SAFI to reflect changes in RIB.
14455 */
14456 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14457 afi_t update_afi,
14458 safi_t update_safi)
14459 {
14460 afi_t afi;
14461 safi_t safi;
14462
14463 FOREACH_AFI_SAFI (afi, safi) {
14464 if (!bgp_fibupd_safi(safi))
14465 continue;
14466
14467 if (afi != update_afi && safi != update_safi)
14468 continue;
14469
14470 if (BGP_DEBUG(zebra, ZEBRA))
14471 zlog_debug(
14472 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14473 __func__, afi, safi);
14474 bgp_zebra_announce_table(bgp, afi, safi);
14475 }
14476 }
14477
14478 DEFUN (bgp_distance,
14479 bgp_distance_cmd,
14480 "distance bgp (1-255) (1-255) (1-255)",
14481 "Define an administrative distance\n"
14482 "BGP distance\n"
14483 "Distance for routes external to the AS\n"
14484 "Distance for routes internal to the AS\n"
14485 "Distance for local routes\n")
14486 {
14487 VTY_DECLVAR_CONTEXT(bgp, bgp);
14488 int idx_number = 2;
14489 int idx_number_2 = 3;
14490 int idx_number_3 = 4;
14491 int distance_ebgp = atoi(argv[idx_number]->arg);
14492 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14493 int distance_local = atoi(argv[idx_number_3]->arg);
14494 afi_t afi;
14495 safi_t safi;
14496
14497 afi = bgp_node_afi(vty);
14498 safi = bgp_node_safi(vty);
14499
14500 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14501 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14502 || bgp->distance_local[afi][safi] != distance_local) {
14503 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14504 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14505 bgp->distance_local[afi][safi] = distance_local;
14506 bgp_announce_routes_distance_update(bgp, afi, safi);
14507 }
14508 return CMD_SUCCESS;
14509 }
14510
14511 DEFUN (no_bgp_distance,
14512 no_bgp_distance_cmd,
14513 "no distance bgp [(1-255) (1-255) (1-255)]",
14514 NO_STR
14515 "Define an administrative distance\n"
14516 "BGP distance\n"
14517 "Distance for routes external to the AS\n"
14518 "Distance for routes internal to the AS\n"
14519 "Distance for local routes\n")
14520 {
14521 VTY_DECLVAR_CONTEXT(bgp, bgp);
14522 afi_t afi;
14523 safi_t safi;
14524
14525 afi = bgp_node_afi(vty);
14526 safi = bgp_node_safi(vty);
14527
14528 if (bgp->distance_ebgp[afi][safi] != 0
14529 || bgp->distance_ibgp[afi][safi] != 0
14530 || bgp->distance_local[afi][safi] != 0) {
14531 bgp->distance_ebgp[afi][safi] = 0;
14532 bgp->distance_ibgp[afi][safi] = 0;
14533 bgp->distance_local[afi][safi] = 0;
14534 bgp_announce_routes_distance_update(bgp, afi, safi);
14535 }
14536 return CMD_SUCCESS;
14537 }
14538
14539
14540 DEFUN (bgp_distance_source,
14541 bgp_distance_source_cmd,
14542 "distance (1-255) A.B.C.D/M",
14543 "Define an administrative distance\n"
14544 "Administrative distance\n"
14545 "IP source prefix\n")
14546 {
14547 int idx_number = 1;
14548 int idx_ipv4_prefixlen = 2;
14549 bgp_distance_set(vty, argv[idx_number]->arg,
14550 argv[idx_ipv4_prefixlen]->arg, NULL);
14551 return CMD_SUCCESS;
14552 }
14553
14554 DEFUN (no_bgp_distance_source,
14555 no_bgp_distance_source_cmd,
14556 "no distance (1-255) A.B.C.D/M",
14557 NO_STR
14558 "Define an administrative distance\n"
14559 "Administrative distance\n"
14560 "IP source prefix\n")
14561 {
14562 int idx_number = 2;
14563 int idx_ipv4_prefixlen = 3;
14564 bgp_distance_unset(vty, argv[idx_number]->arg,
14565 argv[idx_ipv4_prefixlen]->arg, NULL);
14566 return CMD_SUCCESS;
14567 }
14568
14569 DEFUN (bgp_distance_source_access_list,
14570 bgp_distance_source_access_list_cmd,
14571 "distance (1-255) A.B.C.D/M WORD",
14572 "Define an administrative distance\n"
14573 "Administrative distance\n"
14574 "IP source prefix\n"
14575 "Access list name\n")
14576 {
14577 int idx_number = 1;
14578 int idx_ipv4_prefixlen = 2;
14579 int idx_word = 3;
14580 bgp_distance_set(vty, argv[idx_number]->arg,
14581 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14582 return CMD_SUCCESS;
14583 }
14584
14585 DEFUN (no_bgp_distance_source_access_list,
14586 no_bgp_distance_source_access_list_cmd,
14587 "no distance (1-255) A.B.C.D/M WORD",
14588 NO_STR
14589 "Define an administrative distance\n"
14590 "Administrative distance\n"
14591 "IP source prefix\n"
14592 "Access list name\n")
14593 {
14594 int idx_number = 2;
14595 int idx_ipv4_prefixlen = 3;
14596 int idx_word = 4;
14597 bgp_distance_unset(vty, argv[idx_number]->arg,
14598 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14599 return CMD_SUCCESS;
14600 }
14601
14602 DEFUN (ipv6_bgp_distance_source,
14603 ipv6_bgp_distance_source_cmd,
14604 "distance (1-255) X:X::X:X/M",
14605 "Define an administrative distance\n"
14606 "Administrative distance\n"
14607 "IP source prefix\n")
14608 {
14609 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
14610 return CMD_SUCCESS;
14611 }
14612
14613 DEFUN (no_ipv6_bgp_distance_source,
14614 no_ipv6_bgp_distance_source_cmd,
14615 "no distance (1-255) X:X::X:X/M",
14616 NO_STR
14617 "Define an administrative distance\n"
14618 "Administrative distance\n"
14619 "IP source prefix\n")
14620 {
14621 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
14622 return CMD_SUCCESS;
14623 }
14624
14625 DEFUN (ipv6_bgp_distance_source_access_list,
14626 ipv6_bgp_distance_source_access_list_cmd,
14627 "distance (1-255) X:X::X:X/M WORD",
14628 "Define an administrative distance\n"
14629 "Administrative distance\n"
14630 "IP source prefix\n"
14631 "Access list name\n")
14632 {
14633 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
14634 return CMD_SUCCESS;
14635 }
14636
14637 DEFUN (no_ipv6_bgp_distance_source_access_list,
14638 no_ipv6_bgp_distance_source_access_list_cmd,
14639 "no distance (1-255) X:X::X:X/M WORD",
14640 NO_STR
14641 "Define an administrative distance\n"
14642 "Administrative distance\n"
14643 "IP source prefix\n"
14644 "Access list name\n")
14645 {
14646 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
14647 return CMD_SUCCESS;
14648 }
14649
14650 DEFUN (bgp_damp_set,
14651 bgp_damp_set_cmd,
14652 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14653 "BGP Specific commands\n"
14654 "Enable route-flap dampening\n"
14655 "Half-life time for the penalty\n"
14656 "Value to start reusing a route\n"
14657 "Value to start suppressing a route\n"
14658 "Maximum duration to suppress a stable route\n")
14659 {
14660 VTY_DECLVAR_CONTEXT(bgp, bgp);
14661 int idx_half_life = 2;
14662 int idx_reuse = 3;
14663 int idx_suppress = 4;
14664 int idx_max_suppress = 5;
14665 int half = DEFAULT_HALF_LIFE * 60;
14666 int reuse = DEFAULT_REUSE;
14667 int suppress = DEFAULT_SUPPRESS;
14668 int max = 4 * half;
14669
14670 if (argc == 6) {
14671 half = atoi(argv[idx_half_life]->arg) * 60;
14672 reuse = atoi(argv[idx_reuse]->arg);
14673 suppress = atoi(argv[idx_suppress]->arg);
14674 max = atoi(argv[idx_max_suppress]->arg) * 60;
14675 } else if (argc == 3) {
14676 half = atoi(argv[idx_half_life]->arg) * 60;
14677 max = 4 * half;
14678 }
14679
14680 /*
14681 * These can't be 0 but our SA doesn't understand the
14682 * way our cli is constructed
14683 */
14684 assert(reuse);
14685 assert(half);
14686 if (suppress < reuse) {
14687 vty_out(vty,
14688 "Suppress value cannot be less than reuse value \n");
14689 return 0;
14690 }
14691
14692 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
14693 reuse, suppress, max);
14694 }
14695
14696 DEFUN (bgp_damp_unset,
14697 bgp_damp_unset_cmd,
14698 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14699 NO_STR
14700 "BGP Specific commands\n"
14701 "Enable route-flap dampening\n"
14702 "Half-life time for the penalty\n"
14703 "Value to start reusing a route\n"
14704 "Value to start suppressing a route\n"
14705 "Maximum duration to suppress a stable route\n")
14706 {
14707 VTY_DECLVAR_CONTEXT(bgp, bgp);
14708 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
14709 }
14710
14711 /* Display specified route of BGP table. */
14712 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14713 const char *ip_str, afi_t afi, safi_t safi,
14714 struct prefix_rd *prd, int prefix_check)
14715 {
14716 int ret;
14717 struct prefix match;
14718 struct bgp_dest *dest;
14719 struct bgp_dest *rm;
14720 struct bgp_path_info *pi;
14721 struct bgp_path_info *pi_temp;
14722 struct bgp *bgp;
14723 struct bgp_table *table;
14724
14725 /* BGP structure lookup. */
14726 if (view_name) {
14727 bgp = bgp_lookup_by_name(view_name);
14728 if (bgp == NULL) {
14729 vty_out(vty, "%% Can't find BGP instance %s\n",
14730 view_name);
14731 return CMD_WARNING;
14732 }
14733 } else {
14734 bgp = bgp_get_default();
14735 if (bgp == NULL) {
14736 vty_out(vty, "%% No BGP process is configured\n");
14737 return CMD_WARNING;
14738 }
14739 }
14740
14741 /* Check IP address argument. */
14742 ret = str2prefix(ip_str, &match);
14743 if (!ret) {
14744 vty_out(vty, "%% address is malformed\n");
14745 return CMD_WARNING;
14746 }
14747
14748 match.family = afi2family(afi);
14749
14750 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14751 || (safi == SAFI_EVPN)) {
14752 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14753 dest = bgp_route_next(dest)) {
14754 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14755
14756 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14757 continue;
14758 table = bgp_dest_get_bgp_table_info(dest);
14759 if (!table)
14760 continue;
14761 rm = bgp_node_match(table, &match);
14762 if (rm == NULL)
14763 continue;
14764
14765 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
14766
14767 if (!prefix_check
14768 || rm_p->prefixlen == match.prefixlen) {
14769 pi = bgp_dest_get_bgp_path_info(rm);
14770 while (pi) {
14771 if (pi->extra && pi->extra->damp_info) {
14772 pi_temp = pi->next;
14773 bgp_damp_info_free(
14774 pi->extra->damp_info,
14775 1, afi, safi);
14776 pi = pi_temp;
14777 } else
14778 pi = pi->next;
14779 }
14780 }
14781
14782 bgp_dest_unlock_node(rm);
14783 }
14784 } else {
14785 dest = bgp_node_match(bgp->rib[afi][safi], &match);
14786 if (dest != NULL) {
14787 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14788
14789 if (!prefix_check
14790 || dest_p->prefixlen == match.prefixlen) {
14791 pi = bgp_dest_get_bgp_path_info(dest);
14792 while (pi) {
14793 if (pi->extra && pi->extra->damp_info) {
14794 pi_temp = pi->next;
14795 bgp_damp_info_free(
14796 pi->extra->damp_info,
14797 1, afi, safi);
14798 pi = pi_temp;
14799 } else
14800 pi = pi->next;
14801 }
14802 }
14803
14804 bgp_dest_unlock_node(dest);
14805 }
14806 }
14807
14808 return CMD_SUCCESS;
14809 }
14810
14811 DEFUN (clear_ip_bgp_dampening,
14812 clear_ip_bgp_dampening_cmd,
14813 "clear ip bgp dampening",
14814 CLEAR_STR
14815 IP_STR
14816 BGP_STR
14817 "Clear route flap dampening information\n")
14818 {
14819 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
14820 return CMD_SUCCESS;
14821 }
14822
14823 DEFUN (clear_ip_bgp_dampening_prefix,
14824 clear_ip_bgp_dampening_prefix_cmd,
14825 "clear ip bgp dampening A.B.C.D/M",
14826 CLEAR_STR
14827 IP_STR
14828 BGP_STR
14829 "Clear route flap dampening information\n"
14830 "IPv4 prefix\n")
14831 {
14832 int idx_ipv4_prefixlen = 4;
14833 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
14834 AFI_IP, SAFI_UNICAST, NULL, 1);
14835 }
14836
14837 DEFUN (clear_ip_bgp_dampening_address,
14838 clear_ip_bgp_dampening_address_cmd,
14839 "clear ip bgp dampening A.B.C.D",
14840 CLEAR_STR
14841 IP_STR
14842 BGP_STR
14843 "Clear route flap dampening information\n"
14844 "Network to clear damping information\n")
14845 {
14846 int idx_ipv4 = 4;
14847 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
14848 SAFI_UNICAST, NULL, 0);
14849 }
14850
14851 DEFUN (clear_ip_bgp_dampening_address_mask,
14852 clear_ip_bgp_dampening_address_mask_cmd,
14853 "clear ip bgp dampening A.B.C.D A.B.C.D",
14854 CLEAR_STR
14855 IP_STR
14856 BGP_STR
14857 "Clear route flap dampening information\n"
14858 "Network to clear damping information\n"
14859 "Network mask\n")
14860 {
14861 int idx_ipv4 = 4;
14862 int idx_ipv4_2 = 5;
14863 int ret;
14864 char prefix_str[BUFSIZ];
14865
14866 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
14867 prefix_str, sizeof(prefix_str));
14868 if (!ret) {
14869 vty_out(vty, "%% Inconsistent address and mask\n");
14870 return CMD_WARNING;
14871 }
14872
14873 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
14874 NULL, 0);
14875 }
14876
14877 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
14878 {
14879 struct vty *vty = arg;
14880 struct peer *peer = bucket->data;
14881 char buf[SU_ADDRSTRLEN];
14882
14883 vty_out(vty, "\tPeer: %s %s\n", peer->host,
14884 sockunion2str(&peer->su, buf, sizeof(buf)));
14885 }
14886
14887 DEFUN (show_bgp_listeners,
14888 show_bgp_listeners_cmd,
14889 "show bgp listeners",
14890 SHOW_STR
14891 BGP_STR
14892 "Display Listen Sockets and who created them\n")
14893 {
14894 bgp_dump_listener_info(vty);
14895
14896 return CMD_SUCCESS;
14897 }
14898
14899 DEFUN (show_bgp_peerhash,
14900 show_bgp_peerhash_cmd,
14901 "show bgp peerhash",
14902 SHOW_STR
14903 BGP_STR
14904 "Display information about the BGP peerhash\n")
14905 {
14906 struct list *instances = bm->bgp;
14907 struct listnode *node;
14908 struct bgp *bgp;
14909
14910 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
14911 vty_out(vty, "BGP: %s\n", bgp->name);
14912 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
14913 vty);
14914 }
14915
14916 return CMD_SUCCESS;
14917 }
14918
14919 /* also used for encap safi */
14920 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
14921 afi_t afi, safi_t safi)
14922 {
14923 struct bgp_dest *pdest;
14924 struct bgp_dest *dest;
14925 struct bgp_table *table;
14926 const struct prefix *p;
14927 const struct prefix_rd *prd;
14928 struct bgp_static *bgp_static;
14929 mpls_label_t label;
14930 char rdbuf[RD_ADDRSTRLEN];
14931
14932 /* Network configuration. */
14933 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14934 pdest = bgp_route_next(pdest)) {
14935 table = bgp_dest_get_bgp_table_info(pdest);
14936 if (!table)
14937 continue;
14938
14939 for (dest = bgp_table_top(table); dest;
14940 dest = bgp_route_next(dest)) {
14941 bgp_static = bgp_dest_get_bgp_static_info(dest);
14942 if (bgp_static == NULL)
14943 continue;
14944
14945 p = bgp_dest_get_prefix(dest);
14946 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14947 pdest);
14948
14949 /* "network" configuration display. */
14950 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14951 label = decode_label(&bgp_static->label);
14952
14953 vty_out(vty, " network %pFX rd %s", p, rdbuf);
14954 if (safi == SAFI_MPLS_VPN)
14955 vty_out(vty, " label %u", label);
14956
14957 if (bgp_static->rmap.name)
14958 vty_out(vty, " route-map %s",
14959 bgp_static->rmap.name);
14960
14961 if (bgp_static->backdoor)
14962 vty_out(vty, " backdoor");
14963
14964 vty_out(vty, "\n");
14965 }
14966 }
14967 }
14968
14969 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
14970 afi_t afi, safi_t safi)
14971 {
14972 struct bgp_dest *pdest;
14973 struct bgp_dest *dest;
14974 struct bgp_table *table;
14975 const struct prefix *p;
14976 const struct prefix_rd *prd;
14977 struct bgp_static *bgp_static;
14978 char buf[PREFIX_STRLEN * 2];
14979 char buf2[SU_ADDRSTRLEN];
14980 char rdbuf[RD_ADDRSTRLEN];
14981 char esi_buf[ESI_BYTES];
14982
14983 /* Network configuration. */
14984 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14985 pdest = bgp_route_next(pdest)) {
14986 table = bgp_dest_get_bgp_table_info(pdest);
14987 if (!table)
14988 continue;
14989
14990 for (dest = bgp_table_top(table); dest;
14991 dest = bgp_route_next(dest)) {
14992 bgp_static = bgp_dest_get_bgp_static_info(dest);
14993 if (bgp_static == NULL)
14994 continue;
14995
14996 char *macrouter = NULL;
14997
14998 if (bgp_static->router_mac)
14999 macrouter = prefix_mac2str(
15000 bgp_static->router_mac, NULL, 0);
15001 if (bgp_static->eth_s_id)
15002 esi_to_str(bgp_static->eth_s_id,
15003 esi_buf, sizeof(esi_buf));
15004 p = bgp_dest_get_prefix(dest);
15005 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15006
15007 /* "network" configuration display. */
15008 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
15009 if (p->u.prefix_evpn.route_type == 5) {
15010 char local_buf[PREFIX_STRLEN];
15011 uint8_t family = is_evpn_prefix_ipaddr_v4((
15012 struct prefix_evpn *)p)
15013 ? AF_INET
15014 : AF_INET6;
15015 inet_ntop(family,
15016 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15017 local_buf, PREFIX_STRLEN);
15018 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15019 p->u.prefix_evpn.prefix_addr
15020 .ip_prefix_length);
15021 } else {
15022 prefix2str(p, buf, sizeof(buf));
15023 }
15024
15025 if (bgp_static->gatewayIp.family == AF_INET
15026 || bgp_static->gatewayIp.family == AF_INET6)
15027 inet_ntop(bgp_static->gatewayIp.family,
15028 &bgp_static->gatewayIp.u.prefix, buf2,
15029 sizeof(buf2));
15030 vty_out(vty,
15031 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15032 buf, rdbuf,
15033 p->u.prefix_evpn.prefix_addr.eth_tag,
15034 decode_label(&bgp_static->label), esi_buf, buf2,
15035 macrouter);
15036
15037 XFREE(MTYPE_TMP, macrouter);
15038 }
15039 }
15040 }
15041
15042 /* Configuration of static route announcement and aggregate
15043 information. */
15044 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15045 safi_t safi)
15046 {
15047 struct bgp_dest *dest;
15048 const struct prefix *p;
15049 struct bgp_static *bgp_static;
15050 struct bgp_aggregate *bgp_aggregate;
15051
15052 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15053 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15054 return;
15055 }
15056
15057 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15058 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15059 return;
15060 }
15061
15062 /* Network configuration. */
15063 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15064 dest = bgp_route_next(dest)) {
15065 bgp_static = bgp_dest_get_bgp_static_info(dest);
15066 if (bgp_static == NULL)
15067 continue;
15068
15069 p = bgp_dest_get_prefix(dest);
15070
15071 vty_out(vty, " network %pFX", p);
15072
15073 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15074 vty_out(vty, " label-index %u",
15075 bgp_static->label_index);
15076
15077 if (bgp_static->rmap.name)
15078 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15079
15080 if (bgp_static->backdoor)
15081 vty_out(vty, " backdoor");
15082
15083 vty_out(vty, "\n");
15084 }
15085
15086 /* Aggregate-address configuration. */
15087 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15088 dest = bgp_route_next(dest)) {
15089 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15090 if (bgp_aggregate == NULL)
15091 continue;
15092
15093 p = bgp_dest_get_prefix(dest);
15094
15095 vty_out(vty, " aggregate-address %pFX", p);
15096
15097 if (bgp_aggregate->as_set)
15098 vty_out(vty, " as-set");
15099
15100 if (bgp_aggregate->summary_only)
15101 vty_out(vty, " summary-only");
15102
15103 if (bgp_aggregate->rmap.name)
15104 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15105
15106 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15107 vty_out(vty, " origin %s",
15108 bgp_origin2str(bgp_aggregate->origin));
15109
15110 if (bgp_aggregate->match_med)
15111 vty_out(vty, " matching-MED-only");
15112
15113 if (bgp_aggregate->suppress_map_name)
15114 vty_out(vty, " suppress-map %s",
15115 bgp_aggregate->suppress_map_name);
15116
15117 vty_out(vty, "\n");
15118 }
15119 }
15120
15121 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15122 safi_t safi)
15123 {
15124 struct bgp_dest *dest;
15125 struct bgp_distance *bdistance;
15126
15127 /* Distance configuration. */
15128 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15129 && bgp->distance_local[afi][safi]
15130 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15131 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15132 || bgp->distance_local[afi][safi]
15133 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15134 vty_out(vty, " distance bgp %d %d %d\n",
15135 bgp->distance_ebgp[afi][safi],
15136 bgp->distance_ibgp[afi][safi],
15137 bgp->distance_local[afi][safi]);
15138 }
15139
15140 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15141 dest = bgp_route_next(dest)) {
15142 bdistance = bgp_dest_get_bgp_distance_info(dest);
15143 if (bdistance != NULL)
15144 vty_out(vty, " distance %d %pBD %s\n",
15145 bdistance->distance, dest,
15146 bdistance->access_list ? bdistance->access_list
15147 : "");
15148 }
15149 }
15150
15151 /* Allocate routing table structure and install commands. */
15152 void bgp_route_init(void)
15153 {
15154 afi_t afi;
15155 safi_t safi;
15156
15157 /* Init BGP distance table. */
15158 FOREACH_AFI_SAFI (afi, safi)
15159 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15160
15161 /* IPv4 BGP commands. */
15162 install_element(BGP_NODE, &bgp_table_map_cmd);
15163 install_element(BGP_NODE, &bgp_network_cmd);
15164 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15165
15166 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15167
15168 /* IPv4 unicast configuration. */
15169 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15170 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15171 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15172
15173 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15174
15175 /* IPv4 multicast configuration. */
15176 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15177 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15178 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15179 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15180
15181 /* IPv4 labeled-unicast configuration. */
15182 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15183 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15184
15185 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15186 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15187 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15188 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15189 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15190 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15191 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15192 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15193
15194 install_element(VIEW_NODE,
15195 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15196 install_element(VIEW_NODE,
15197 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15198 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15199 install_element(VIEW_NODE,
15200 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15201 #ifdef KEEP_OLD_VPN_COMMANDS
15202 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15203 #endif /* KEEP_OLD_VPN_COMMANDS */
15204 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15205 install_element(VIEW_NODE,
15206 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15207
15208 /* BGP dampening clear commands */
15209 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15210 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15211
15212 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15213 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15214
15215 /* prefix count */
15216 install_element(ENABLE_NODE,
15217 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15218 #ifdef KEEP_OLD_VPN_COMMANDS
15219 install_element(ENABLE_NODE,
15220 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15221 #endif /* KEEP_OLD_VPN_COMMANDS */
15222
15223 /* New config IPv6 BGP commands. */
15224 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15225 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15226 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15227
15228 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15229
15230 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15231
15232 /* IPv6 labeled unicast address family. */
15233 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15234 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15235
15236 install_element(BGP_NODE, &bgp_distance_cmd);
15237 install_element(BGP_NODE, &no_bgp_distance_cmd);
15238 install_element(BGP_NODE, &bgp_distance_source_cmd);
15239 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15240 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15241 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15242 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15243 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15244 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15245 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15246 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15247 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15248 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15249 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15250 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15251 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15252 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15253 install_element(BGP_IPV4M_NODE,
15254 &no_bgp_distance_source_access_list_cmd);
15255 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15256 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15257 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15258 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15259 install_element(BGP_IPV6_NODE,
15260 &ipv6_bgp_distance_source_access_list_cmd);
15261 install_element(BGP_IPV6_NODE,
15262 &no_ipv6_bgp_distance_source_access_list_cmd);
15263 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15264 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15265 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15266 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15267 install_element(BGP_IPV6M_NODE,
15268 &ipv6_bgp_distance_source_access_list_cmd);
15269 install_element(BGP_IPV6M_NODE,
15270 &no_ipv6_bgp_distance_source_access_list_cmd);
15271
15272 /* BGP dampening */
15273 install_element(BGP_NODE, &bgp_damp_set_cmd);
15274 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15275 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15276 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15277 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15278 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15279 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15280 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15281 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15282 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15283 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15284 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15285 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15286 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15287
15288 /* Large Communities */
15289 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15290 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15291
15292 /* show bgp ipv4 flowspec detailed */
15293 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15294
15295 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15296 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15297 }
15298
15299 void bgp_route_finish(void)
15300 {
15301 afi_t afi;
15302 safi_t safi;
15303
15304 FOREACH_AFI_SAFI (afi, safi) {
15305 bgp_table_unlock(bgp_distance_table[afi][safi]);
15306 bgp_distance_table[afi][safi] = NULL;
15307 }
15308 }