]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Add an empty line after new variable assignment
[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 (newattr->community &&
645 community_include(newattr->community, COMMUNITY_LLGR_STALE)) {
646 if (debug)
647 zlog_debug(
648 "%s: %s wins over %s due to LLGR_STALE community",
649 pfx_buf, new_buf, exist_buf);
650 return 0;
651 }
652
653 if (existattr->community &&
654 community_include(existattr->community, COMMUNITY_LLGR_STALE)) {
655 if (debug)
656 zlog_debug(
657 "%s: %s loses to %s due to LLGR_STALE community",
658 pfx_buf, new_buf, exist_buf);
659 return 1;
660 }
661
662 new_p = bgp_dest_get_prefix(new->net);
663
664 /* For EVPN routes, we cannot just go by local vs remote, we have to
665 * look at the MAC mobility sequence number, if present.
666 */
667 if ((safi == SAFI_EVPN)
668 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
669 /* This is an error condition described in RFC 7432 Section
670 * 15.2. The RFC
671 * states that in this scenario "the PE MUST alert the operator"
672 * but it
673 * does not state what other action to take. In order to provide
674 * some
675 * consistency in this scenario we are going to prefer the path
676 * with the
677 * sticky flag.
678 */
679 if (newattr->sticky != existattr->sticky) {
680 if (!debug) {
681 prefix2str(new_p, pfx_buf,
682 sizeof(*pfx_buf)
683 * PREFIX2STR_BUFFER);
684 bgp_path_info_path_with_addpath_rx_str(
685 new, new_buf, sizeof(new_buf));
686 bgp_path_info_path_with_addpath_rx_str(
687 exist, exist_buf, sizeof(exist_buf));
688 }
689
690 if (newattr->sticky && !existattr->sticky) {
691 *reason = bgp_path_selection_evpn_sticky_mac;
692 if (debug)
693 zlog_debug(
694 "%s: %s wins over %s due to sticky MAC flag",
695 pfx_buf, new_buf, exist_buf);
696 return 1;
697 }
698
699 if (!newattr->sticky && existattr->sticky) {
700 *reason = bgp_path_selection_evpn_sticky_mac;
701 if (debug)
702 zlog_debug(
703 "%s: %s loses to %s due to sticky MAC flag",
704 pfx_buf, new_buf, exist_buf);
705 return 0;
706 }
707 }
708
709 new_esi = bgp_evpn_attr_get_esi(newattr);
710 exist_esi = bgp_evpn_attr_get_esi(existattr);
711 if (bgp_evpn_is_esi_valid(new_esi) &&
712 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
713 same_esi = true;
714 } else {
715 same_esi = false;
716 }
717
718 /* If both paths have the same non-zero ES and
719 * one path is local it wins.
720 * PS: Note the local path wins even if the remote
721 * has the higher MM seq. The local path's
722 * MM seq will be fixed up to match the highest
723 * rem seq, subsequently.
724 */
725 if (same_esi) {
726 char esi_buf[ESI_STR_LEN];
727
728 if (bgp_evpn_is_path_local(bgp, new)) {
729 *reason = bgp_path_selection_evpn_local_path;
730 if (debug)
731 zlog_debug(
732 "%s: %s wins over %s as ES %s is same and local",
733 pfx_buf, new_buf, exist_buf,
734 esi_to_str(new_esi, esi_buf,
735 sizeof(esi_buf)));
736 return 1;
737 }
738 if (bgp_evpn_is_path_local(bgp, exist)) {
739 *reason = bgp_path_selection_evpn_local_path;
740 if (debug)
741 zlog_debug(
742 "%s: %s loses to %s as ES %s is same and local",
743 pfx_buf, new_buf, exist_buf,
744 esi_to_str(new_esi, esi_buf,
745 sizeof(esi_buf)));
746 return 0;
747 }
748 }
749
750 new_mm_seq = mac_mobility_seqnum(newattr);
751 exist_mm_seq = mac_mobility_seqnum(existattr);
752
753 if (new_mm_seq > exist_mm_seq) {
754 *reason = bgp_path_selection_evpn_seq;
755 if (debug)
756 zlog_debug(
757 "%s: %s wins over %s due to MM seq %u > %u",
758 pfx_buf, new_buf, exist_buf, new_mm_seq,
759 exist_mm_seq);
760 return 1;
761 }
762
763 if (new_mm_seq < exist_mm_seq) {
764 *reason = bgp_path_selection_evpn_seq;
765 if (debug)
766 zlog_debug(
767 "%s: %s loses to %s due to MM seq %u < %u",
768 pfx_buf, new_buf, exist_buf, new_mm_seq,
769 exist_mm_seq);
770 return 0;
771 }
772
773 /* if the sequence numbers and ESI are the same and one path
774 * is non-proxy it wins (over proxy)
775 */
776 new_proxy = bgp_evpn_attr_is_proxy(newattr);
777 old_proxy = bgp_evpn_attr_is_proxy(existattr);
778 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
779 old_proxy != new_proxy) {
780 if (!new_proxy) {
781 *reason = bgp_path_selection_evpn_non_proxy;
782 if (debug)
783 zlog_debug(
784 "%s: %s wins over %s, same seq/es and non-proxy",
785 pfx_buf, new_buf, exist_buf);
786 return 1;
787 }
788
789 *reason = bgp_path_selection_evpn_non_proxy;
790 if (debug)
791 zlog_debug(
792 "%s: %s loses to %s, same seq/es and non-proxy",
793 pfx_buf, new_buf, exist_buf);
794 return 0;
795 }
796
797 /*
798 * if sequence numbers are the same path with the lowest IP
799 * wins
800 */
801 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
802 if (nh_cmp < 0) {
803 *reason = bgp_path_selection_evpn_lower_ip;
804 if (debug)
805 zlog_debug(
806 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
807 pfx_buf, new_buf, exist_buf, new_mm_seq,
808 &new->attr->nexthop);
809 return 1;
810 }
811 if (nh_cmp > 0) {
812 *reason = bgp_path_selection_evpn_lower_ip;
813 if (debug)
814 zlog_debug(
815 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
816 pfx_buf, new_buf, exist_buf, new_mm_seq,
817 &new->attr->nexthop);
818 return 0;
819 }
820 }
821
822 /* 1. Weight check. */
823 new_weight = newattr->weight;
824 exist_weight = existattr->weight;
825
826 if (new_weight > exist_weight) {
827 *reason = bgp_path_selection_weight;
828 if (debug)
829 zlog_debug("%s: %s wins over %s due to weight %d > %d",
830 pfx_buf, new_buf, exist_buf, new_weight,
831 exist_weight);
832 return 1;
833 }
834
835 if (new_weight < exist_weight) {
836 *reason = bgp_path_selection_weight;
837 if (debug)
838 zlog_debug("%s: %s loses to %s due to weight %d < %d",
839 pfx_buf, new_buf, exist_buf, new_weight,
840 exist_weight);
841 return 0;
842 }
843
844 /* 2. Local preference check. */
845 new_pref = exist_pref = bgp->default_local_pref;
846
847 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
848 new_pref = newattr->local_pref;
849 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
850 exist_pref = existattr->local_pref;
851
852 if (new_pref > exist_pref) {
853 *reason = bgp_path_selection_local_pref;
854 if (debug)
855 zlog_debug(
856 "%s: %s wins over %s due to localpref %d > %d",
857 pfx_buf, new_buf, exist_buf, new_pref,
858 exist_pref);
859 return 1;
860 }
861
862 if (new_pref < exist_pref) {
863 *reason = bgp_path_selection_local_pref;
864 if (debug)
865 zlog_debug(
866 "%s: %s loses to %s due to localpref %d < %d",
867 pfx_buf, new_buf, exist_buf, new_pref,
868 exist_pref);
869 return 0;
870 }
871
872 /* 3. Local route check. We prefer:
873 * - BGP_ROUTE_STATIC
874 * - BGP_ROUTE_AGGREGATE
875 * - BGP_ROUTE_REDISTRIBUTE
876 */
877 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
878 new->sub_type == BGP_ROUTE_IMPORTED);
879 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
880 exist->sub_type == BGP_ROUTE_IMPORTED);
881
882 if (new_origin && !exist_origin) {
883 *reason = bgp_path_selection_local_route;
884 if (debug)
885 zlog_debug(
886 "%s: %s wins over %s due to preferred BGP_ROUTE type",
887 pfx_buf, new_buf, exist_buf);
888 return 1;
889 }
890
891 if (!new_origin && exist_origin) {
892 *reason = bgp_path_selection_local_route;
893 if (debug)
894 zlog_debug(
895 "%s: %s loses to %s due to preferred BGP_ROUTE type",
896 pfx_buf, new_buf, exist_buf);
897 return 0;
898 }
899
900 /* Here if these are imported routes then get ultimate pi for
901 * path compare.
902 */
903 new = bgp_get_imported_bpi_ultimate(new);
904 exist = bgp_get_imported_bpi_ultimate(exist);
905 newattr = new->attr;
906 existattr = exist->attr;
907
908 /* 4. AS path length check. */
909 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
910 int exist_hops = aspath_count_hops(existattr->aspath);
911 int exist_confeds = aspath_count_confeds(existattr->aspath);
912
913 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
914 int aspath_hops;
915
916 aspath_hops = aspath_count_hops(newattr->aspath);
917 aspath_hops += aspath_count_confeds(newattr->aspath);
918
919 if (aspath_hops < (exist_hops + exist_confeds)) {
920 *reason = bgp_path_selection_confed_as_path;
921 if (debug)
922 zlog_debug(
923 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
924 pfx_buf, new_buf, exist_buf,
925 aspath_hops,
926 (exist_hops + exist_confeds));
927 return 1;
928 }
929
930 if (aspath_hops > (exist_hops + exist_confeds)) {
931 *reason = bgp_path_selection_confed_as_path;
932 if (debug)
933 zlog_debug(
934 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
935 pfx_buf, new_buf, exist_buf,
936 aspath_hops,
937 (exist_hops + exist_confeds));
938 return 0;
939 }
940 } else {
941 int newhops = aspath_count_hops(newattr->aspath);
942
943 if (newhops < exist_hops) {
944 *reason = bgp_path_selection_as_path;
945 if (debug)
946 zlog_debug(
947 "%s: %s wins over %s due to aspath hopcount %d < %d",
948 pfx_buf, new_buf, exist_buf,
949 newhops, exist_hops);
950 return 1;
951 }
952
953 if (newhops > exist_hops) {
954 *reason = bgp_path_selection_as_path;
955 if (debug)
956 zlog_debug(
957 "%s: %s loses to %s due to aspath hopcount %d > %d",
958 pfx_buf, new_buf, exist_buf,
959 newhops, exist_hops);
960 return 0;
961 }
962 }
963 }
964
965 /* 5. Origin check. */
966 if (newattr->origin < existattr->origin) {
967 *reason = bgp_path_selection_origin;
968 if (debug)
969 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
970 pfx_buf, new_buf, exist_buf,
971 bgp_origin_long_str[newattr->origin],
972 bgp_origin_long_str[existattr->origin]);
973 return 1;
974 }
975
976 if (newattr->origin > existattr->origin) {
977 *reason = bgp_path_selection_origin;
978 if (debug)
979 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
980 pfx_buf, new_buf, exist_buf,
981 bgp_origin_long_str[newattr->origin],
982 bgp_origin_long_str[existattr->origin]);
983 return 0;
984 }
985
986 /* 6. MED check. */
987 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
988 && aspath_count_hops(existattr->aspath) == 0);
989 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
990 && aspath_count_confeds(existattr->aspath) > 0
991 && aspath_count_hops(newattr->aspath) == 0
992 && aspath_count_hops(existattr->aspath) == 0);
993
994 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
995 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
996 || aspath_cmp_left(newattr->aspath, existattr->aspath)
997 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
998 || internal_as_route) {
999 new_med = bgp_med_value(new->attr, bgp);
1000 exist_med = bgp_med_value(exist->attr, bgp);
1001
1002 if (new_med < exist_med) {
1003 *reason = bgp_path_selection_med;
1004 if (debug)
1005 zlog_debug(
1006 "%s: %s wins over %s due to MED %d < %d",
1007 pfx_buf, new_buf, exist_buf, new_med,
1008 exist_med);
1009 return 1;
1010 }
1011
1012 if (new_med > exist_med) {
1013 *reason = bgp_path_selection_med;
1014 if (debug)
1015 zlog_debug(
1016 "%s: %s loses to %s due to MED %d > %d",
1017 pfx_buf, new_buf, exist_buf, new_med,
1018 exist_med);
1019 return 0;
1020 }
1021 }
1022
1023 /* 7. Peer type check. */
1024 new_sort = new->peer->sort;
1025 exist_sort = exist->peer->sort;
1026
1027 if (new_sort == BGP_PEER_EBGP
1028 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
1029 *reason = bgp_path_selection_peer;
1030 if (debug)
1031 zlog_debug(
1032 "%s: %s wins over %s due to eBGP peer > iBGP peer",
1033 pfx_buf, new_buf, exist_buf);
1034 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1035 return 1;
1036 peer_sort_ret = 1;
1037 }
1038
1039 if (exist_sort == BGP_PEER_EBGP
1040 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
1041 *reason = bgp_path_selection_peer;
1042 if (debug)
1043 zlog_debug(
1044 "%s: %s loses to %s due to iBGP peer < eBGP peer",
1045 pfx_buf, new_buf, exist_buf);
1046 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1047 return 0;
1048 peer_sort_ret = 0;
1049 }
1050
1051 /* 8. IGP metric check. */
1052 newm = existm = 0;
1053
1054 if (new->extra)
1055 newm = new->extra->igpmetric;
1056 if (exist->extra)
1057 existm = exist->extra->igpmetric;
1058
1059 if (newm < existm) {
1060 if (debug && peer_sort_ret < 0)
1061 zlog_debug(
1062 "%s: %s wins over %s due to IGP metric %u < %u",
1063 pfx_buf, new_buf, exist_buf, newm, existm);
1064 igp_metric_ret = 1;
1065 }
1066
1067 if (newm > existm) {
1068 if (debug && peer_sort_ret < 0)
1069 zlog_debug(
1070 "%s: %s loses to %s due to IGP metric %u > %u",
1071 pfx_buf, new_buf, exist_buf, newm, existm);
1072 igp_metric_ret = 0;
1073 }
1074
1075 /* 9. Same IGP metric. Compare the cluster list length as
1076 representative of IGP hops metric. Rewrite the metric value
1077 pair (newm, existm) with the cluster list length. Prefer the
1078 path with smaller cluster list length. */
1079 if (newm == existm) {
1080 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
1081 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
1082 && (mpath_cfg == NULL
1083 || CHECK_FLAG(
1084 mpath_cfg->ibgp_flags,
1085 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
1086 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1087 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1088
1089 if (newm < existm) {
1090 if (debug && peer_sort_ret < 0)
1091 zlog_debug(
1092 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1093 pfx_buf, new_buf, exist_buf,
1094 newm, existm);
1095 igp_metric_ret = 1;
1096 }
1097
1098 if (newm > existm) {
1099 if (debug && peer_sort_ret < 0)
1100 zlog_debug(
1101 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1102 pfx_buf, new_buf, exist_buf,
1103 newm, existm);
1104 igp_metric_ret = 0;
1105 }
1106 }
1107 }
1108
1109 /* 10. confed-external vs. confed-internal */
1110 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1111 if (new_sort == BGP_PEER_CONFED
1112 && exist_sort == BGP_PEER_IBGP) {
1113 *reason = bgp_path_selection_confed;
1114 if (debug)
1115 zlog_debug(
1116 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1117 pfx_buf, new_buf, exist_buf);
1118 if (!CHECK_FLAG(bgp->flags,
1119 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1120 return 1;
1121 peer_sort_ret = 1;
1122 }
1123
1124 if (exist_sort == BGP_PEER_CONFED
1125 && new_sort == BGP_PEER_IBGP) {
1126 *reason = bgp_path_selection_confed;
1127 if (debug)
1128 zlog_debug(
1129 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1130 pfx_buf, new_buf, exist_buf);
1131 if (!CHECK_FLAG(bgp->flags,
1132 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1133 return 0;
1134 peer_sort_ret = 0;
1135 }
1136 }
1137
1138 /* 11. Maximum path check. */
1139 if (newm == existm) {
1140 /* If one path has a label but the other does not, do not treat
1141 * them as equals for multipath
1142 */
1143 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1144 != (exist->extra
1145 && bgp_is_valid_label(&exist->extra->label[0]))) {
1146 if (debug)
1147 zlog_debug(
1148 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1149 pfx_buf, new_buf, exist_buf);
1150 } else if (CHECK_FLAG(bgp->flags,
1151 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1152
1153 /*
1154 * For the two paths, all comparison steps till IGP
1155 * metric
1156 * have succeeded - including AS_PATH hop count. Since
1157 * 'bgp
1158 * bestpath as-path multipath-relax' knob is on, we
1159 * don't need
1160 * an exact match of AS_PATH. Thus, mark the paths are
1161 * equal.
1162 * That will trigger both these paths to get into the
1163 * multipath
1164 * array.
1165 */
1166 *paths_eq = 1;
1167
1168 if (debug)
1169 zlog_debug(
1170 "%s: %s and %s are equal via multipath-relax",
1171 pfx_buf, new_buf, exist_buf);
1172 } else if (new->peer->sort == BGP_PEER_IBGP) {
1173 if (aspath_cmp(new->attr->aspath,
1174 exist->attr->aspath)) {
1175 *paths_eq = 1;
1176
1177 if (debug)
1178 zlog_debug(
1179 "%s: %s and %s are equal via matching aspaths",
1180 pfx_buf, new_buf, exist_buf);
1181 }
1182 } else if (new->peer->as == exist->peer->as) {
1183 *paths_eq = 1;
1184
1185 if (debug)
1186 zlog_debug(
1187 "%s: %s and %s are equal via same remote-as",
1188 pfx_buf, new_buf, exist_buf);
1189 }
1190 } else {
1191 /*
1192 * TODO: If unequal cost ibgp multipath is enabled we can
1193 * mark the paths as equal here instead of returning
1194 */
1195
1196 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1197 * if either step 7 or 10 (peer type checks) yielded a winner,
1198 * that result was returned immediately. Returning from step 10
1199 * ignored the return value computed in steps 8 and 9 (IGP
1200 * metric checks). In order to preserve that behavior, if
1201 * peer_sort_ret is set, return that rather than igp_metric_ret.
1202 */
1203 ret = peer_sort_ret;
1204 if (peer_sort_ret < 0) {
1205 ret = igp_metric_ret;
1206 if (debug) {
1207 if (ret == 1)
1208 zlog_debug(
1209 "%s: %s wins over %s after IGP metric comparison",
1210 pfx_buf, new_buf, exist_buf);
1211 else
1212 zlog_debug(
1213 "%s: %s loses to %s after IGP metric comparison",
1214 pfx_buf, new_buf, exist_buf);
1215 }
1216 *reason = bgp_path_selection_igp_metric;
1217 }
1218 return ret;
1219 }
1220
1221 /*
1222 * At this point, the decision whether to set *paths_eq = 1 has been
1223 * completed. If we deferred returning because of bestpath peer-type
1224 * relax configuration, return now.
1225 */
1226 if (peer_sort_ret >= 0)
1227 return peer_sort_ret;
1228
1229 /* 12. If both paths are external, prefer the path that was received
1230 first (the oldest one). This step minimizes route-flap, since a
1231 newer path won't displace an older one, even if it was the
1232 preferred route based on the additional decision criteria below. */
1233 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1234 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1235 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1236 *reason = bgp_path_selection_older;
1237 if (debug)
1238 zlog_debug(
1239 "%s: %s wins over %s due to oldest external",
1240 pfx_buf, new_buf, exist_buf);
1241 return 1;
1242 }
1243
1244 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1245 *reason = bgp_path_selection_older;
1246 if (debug)
1247 zlog_debug(
1248 "%s: %s loses to %s due to oldest external",
1249 pfx_buf, new_buf, exist_buf);
1250 return 0;
1251 }
1252 }
1253
1254 /* 13. Router-ID comparision. */
1255 /* If one of the paths is "stale", the corresponding peer router-id will
1256 * be 0 and would always win over the other path. If originator id is
1257 * used for the comparision, it will decide which path is better.
1258 */
1259 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1260 new_id.s_addr = newattr->originator_id.s_addr;
1261 else
1262 new_id.s_addr = new->peer->remote_id.s_addr;
1263 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1264 exist_id.s_addr = existattr->originator_id.s_addr;
1265 else
1266 exist_id.s_addr = exist->peer->remote_id.s_addr;
1267
1268 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1269 *reason = bgp_path_selection_router_id;
1270 if (debug)
1271 zlog_debug(
1272 "%s: %s wins over %s due to Router-ID comparison",
1273 pfx_buf, new_buf, exist_buf);
1274 return 1;
1275 }
1276
1277 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1278 *reason = bgp_path_selection_router_id;
1279 if (debug)
1280 zlog_debug(
1281 "%s: %s loses to %s due to Router-ID comparison",
1282 pfx_buf, new_buf, exist_buf);
1283 return 0;
1284 }
1285
1286 /* 14. Cluster length comparision. */
1287 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1288 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1289
1290 if (new_cluster < exist_cluster) {
1291 *reason = bgp_path_selection_cluster_length;
1292 if (debug)
1293 zlog_debug(
1294 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1295 pfx_buf, new_buf, exist_buf, new_cluster,
1296 exist_cluster);
1297 return 1;
1298 }
1299
1300 if (new_cluster > exist_cluster) {
1301 *reason = bgp_path_selection_cluster_length;
1302 if (debug)
1303 zlog_debug(
1304 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1305 pfx_buf, new_buf, exist_buf, new_cluster,
1306 exist_cluster);
1307 return 0;
1308 }
1309
1310 /* 15. Neighbor address comparision. */
1311 /* Do this only if neither path is "stale" as stale paths do not have
1312 * valid peer information (as the connection may or may not be up).
1313 */
1314 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1315 *reason = bgp_path_selection_stale;
1316 if (debug)
1317 zlog_debug(
1318 "%s: %s wins over %s due to latter path being STALE",
1319 pfx_buf, new_buf, exist_buf);
1320 return 1;
1321 }
1322
1323 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1324 *reason = bgp_path_selection_stale;
1325 if (debug)
1326 zlog_debug(
1327 "%s: %s loses to %s due to former path being STALE",
1328 pfx_buf, new_buf, exist_buf);
1329 return 0;
1330 }
1331
1332 /* locally configured routes to advertise do not have su_remote */
1333 if (new->peer->su_remote == NULL) {
1334 *reason = bgp_path_selection_local_configured;
1335 return 0;
1336 }
1337 if (exist->peer->su_remote == NULL) {
1338 *reason = bgp_path_selection_local_configured;
1339 return 1;
1340 }
1341
1342 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1343
1344 if (ret == 1) {
1345 *reason = bgp_path_selection_neighbor_ip;
1346 if (debug)
1347 zlog_debug(
1348 "%s: %s loses to %s due to Neighor IP comparison",
1349 pfx_buf, new_buf, exist_buf);
1350 return 0;
1351 }
1352
1353 if (ret == -1) {
1354 *reason = bgp_path_selection_neighbor_ip;
1355 if (debug)
1356 zlog_debug(
1357 "%s: %s wins over %s due to Neighor IP comparison",
1358 pfx_buf, new_buf, exist_buf);
1359 return 1;
1360 }
1361
1362 *reason = bgp_path_selection_default;
1363 if (debug)
1364 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1365 pfx_buf, new_buf, exist_buf);
1366
1367 return 1;
1368 }
1369
1370
1371 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1372 struct bgp_path_info *exist, int *paths_eq)
1373 {
1374 enum bgp_path_selection_reason reason;
1375 char pfx_buf[PREFIX2STR_BUFFER];
1376
1377 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1378 AFI_L2VPN, SAFI_EVPN, &reason);
1379 }
1380
1381 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1382 * is preferred, or 0 if they are the same (usually will only occur if
1383 * multipath is enabled
1384 * This version is compatible with */
1385 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1386 struct bgp_path_info *exist, char *pfx_buf,
1387 afi_t afi, safi_t safi,
1388 enum bgp_path_selection_reason *reason)
1389 {
1390 int paths_eq;
1391 int ret;
1392 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1393 afi, safi, reason);
1394
1395 if (paths_eq)
1396 ret = 0;
1397 else {
1398 if (ret == 1)
1399 ret = -1;
1400 else
1401 ret = 1;
1402 }
1403 return ret;
1404 }
1405
1406 static enum filter_type bgp_input_filter(struct peer *peer,
1407 const struct prefix *p,
1408 struct attr *attr, afi_t afi,
1409 safi_t safi)
1410 {
1411 struct bgp_filter *filter;
1412 enum filter_type ret = FILTER_PERMIT;
1413
1414 filter = &peer->filter[afi][safi];
1415
1416 #define FILTER_EXIST_WARN(F, f, filter) \
1417 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1418 zlog_debug("%s: Could not find configured input %s-list %s!", \
1419 peer->host, #f, F##_IN_NAME(filter));
1420
1421 if (DISTRIBUTE_IN_NAME(filter)) {
1422 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1423
1424 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1425 == FILTER_DENY) {
1426 ret = FILTER_DENY;
1427 goto done;
1428 }
1429 }
1430
1431 if (PREFIX_LIST_IN_NAME(filter)) {
1432 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1433
1434 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1435 == PREFIX_DENY) {
1436 ret = FILTER_DENY;
1437 goto done;
1438 }
1439 }
1440
1441 if (FILTER_LIST_IN_NAME(filter)) {
1442 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1443
1444 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1445 == AS_FILTER_DENY) {
1446 ret = FILTER_DENY;
1447 goto done;
1448 }
1449 }
1450
1451 done:
1452 if (frrtrace_enabled(frr_bgp, input_filter)) {
1453 char pfxprint[PREFIX2STR_BUFFER];
1454
1455 prefix2str(p, pfxprint, sizeof(pfxprint));
1456 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1457 ret == FILTER_PERMIT ? "permit" : "deny");
1458 }
1459
1460 return ret;
1461 #undef FILTER_EXIST_WARN
1462 }
1463
1464 static enum filter_type bgp_output_filter(struct peer *peer,
1465 const struct prefix *p,
1466 struct attr *attr, afi_t afi,
1467 safi_t safi)
1468 {
1469 struct bgp_filter *filter;
1470 enum filter_type ret = FILTER_PERMIT;
1471
1472 filter = &peer->filter[afi][safi];
1473
1474 #define FILTER_EXIST_WARN(F, f, filter) \
1475 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1476 zlog_debug("%s: Could not find configured output %s-list %s!", \
1477 peer->host, #f, F##_OUT_NAME(filter));
1478
1479 if (DISTRIBUTE_OUT_NAME(filter)) {
1480 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1481
1482 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1483 == FILTER_DENY) {
1484 ret = FILTER_DENY;
1485 goto done;
1486 }
1487 }
1488
1489 if (PREFIX_LIST_OUT_NAME(filter)) {
1490 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1491
1492 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1493 == PREFIX_DENY) {
1494 ret = FILTER_DENY;
1495 goto done;
1496 }
1497 }
1498
1499 if (FILTER_LIST_OUT_NAME(filter)) {
1500 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1501
1502 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1503 == AS_FILTER_DENY) {
1504 ret = FILTER_DENY;
1505 goto done;
1506 }
1507 }
1508
1509 if (frrtrace_enabled(frr_bgp, output_filter)) {
1510 char pfxprint[PREFIX2STR_BUFFER];
1511
1512 prefix2str(p, pfxprint, sizeof(pfxprint));
1513 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1514 ret == FILTER_PERMIT ? "permit" : "deny");
1515 }
1516
1517 done:
1518 return ret;
1519 #undef FILTER_EXIST_WARN
1520 }
1521
1522 /* If community attribute includes no_export then return 1. */
1523 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1524 {
1525 if (attr->community) {
1526 /* NO_ADVERTISE check. */
1527 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1528 return true;
1529
1530 /* NO_EXPORT check. */
1531 if (peer->sort == BGP_PEER_EBGP
1532 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1533 return true;
1534
1535 /* NO_EXPORT_SUBCONFED check. */
1536 if (peer->sort == BGP_PEER_EBGP
1537 || peer->sort == BGP_PEER_CONFED)
1538 if (community_include(attr->community,
1539 COMMUNITY_NO_EXPORT_SUBCONFED))
1540 return true;
1541 }
1542 return false;
1543 }
1544
1545 /* Route reflection loop check. */
1546 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1547 {
1548 struct in_addr cluster_id;
1549 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1550
1551 if (cluster) {
1552 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1553 cluster_id = peer->bgp->cluster_id;
1554 else
1555 cluster_id = peer->bgp->router_id;
1556
1557 if (cluster_loop_check(cluster, cluster_id))
1558 return true;
1559 }
1560 return false;
1561 }
1562
1563 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1564 struct attr *attr, afi_t afi, safi_t safi,
1565 const char *rmap_name, mpls_label_t *label,
1566 uint32_t num_labels, struct bgp_dest *dest)
1567 {
1568 struct bgp_filter *filter;
1569 struct bgp_path_info rmap_path = { 0 };
1570 struct bgp_path_info_extra extra = { 0 };
1571 route_map_result_t ret;
1572 struct route_map *rmap = NULL;
1573
1574 filter = &peer->filter[afi][safi];
1575
1576 /* Apply default weight value. */
1577 if (peer->weight[afi][safi])
1578 attr->weight = peer->weight[afi][safi];
1579
1580 if (rmap_name) {
1581 rmap = route_map_lookup_by_name(rmap_name);
1582
1583 if (rmap == NULL)
1584 return RMAP_DENY;
1585 } else {
1586 if (ROUTE_MAP_IN_NAME(filter)) {
1587 rmap = ROUTE_MAP_IN(filter);
1588
1589 if (rmap == NULL)
1590 return RMAP_DENY;
1591 }
1592 }
1593
1594 /* Route map apply. */
1595 if (rmap) {
1596 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1597 /* Duplicate current value to new strucutre for modification. */
1598 rmap_path.peer = peer;
1599 rmap_path.attr = attr;
1600 rmap_path.extra = &extra;
1601 rmap_path.net = dest;
1602
1603 extra.num_labels = num_labels;
1604 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1605 memcpy(extra.label, label,
1606 num_labels * sizeof(mpls_label_t));
1607
1608 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1609
1610 /* Apply BGP route map to the attribute. */
1611 ret = route_map_apply(rmap, p, &rmap_path);
1612
1613 peer->rmap_type = 0;
1614
1615 if (ret == RMAP_DENYMATCH)
1616 return RMAP_DENY;
1617 }
1618 return RMAP_PERMIT;
1619 }
1620
1621 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1622 struct attr *attr, afi_t afi, safi_t safi,
1623 const char *rmap_name)
1624 {
1625 struct bgp_path_info rmap_path;
1626 route_map_result_t ret;
1627 struct route_map *rmap = NULL;
1628 uint8_t rmap_type;
1629
1630 /*
1631 * So if we get to this point and have no rmap_name
1632 * we want to just show the output as it currently
1633 * exists.
1634 */
1635 if (!rmap_name)
1636 return RMAP_PERMIT;
1637
1638 /* Apply default weight value. */
1639 if (peer->weight[afi][safi])
1640 attr->weight = peer->weight[afi][safi];
1641
1642 rmap = route_map_lookup_by_name(rmap_name);
1643
1644 /*
1645 * If we have a route map name and we do not find
1646 * the routemap that means we have an implicit
1647 * deny.
1648 */
1649 if (rmap == NULL)
1650 return RMAP_DENY;
1651
1652 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1653 /* Route map apply. */
1654 /* Duplicate current value to new strucutre for modification. */
1655 rmap_path.peer = peer;
1656 rmap_path.attr = attr;
1657
1658 rmap_type = peer->rmap_type;
1659 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1660
1661 /* Apply BGP route map to the attribute. */
1662 ret = route_map_apply(rmap, p, &rmap_path);
1663
1664 peer->rmap_type = rmap_type;
1665
1666 if (ret == RMAP_DENYMATCH)
1667 /*
1668 * caller has multiple error paths with bgp_attr_flush()
1669 */
1670 return RMAP_DENY;
1671
1672 return RMAP_PERMIT;
1673 }
1674
1675 /* If this is an EBGP peer with remove-private-AS */
1676 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1677 struct peer *peer, struct attr *attr)
1678 {
1679 if (peer->sort == BGP_PEER_EBGP
1680 && (peer_af_flag_check(peer, afi, safi,
1681 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1682 || peer_af_flag_check(peer, afi, safi,
1683 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1684 || peer_af_flag_check(peer, afi, safi,
1685 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1686 || peer_af_flag_check(peer, afi, safi,
1687 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1688 // Take action on the entire aspath
1689 if (peer_af_flag_check(peer, afi, safi,
1690 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1691 || peer_af_flag_check(peer, afi, safi,
1692 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1693 if (peer_af_flag_check(
1694 peer, afi, safi,
1695 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1696 attr->aspath = aspath_replace_private_asns(
1697 attr->aspath, bgp->as, peer->as);
1698
1699 // The entire aspath consists of private ASNs so create
1700 // an empty aspath
1701 else if (aspath_private_as_check(attr->aspath))
1702 attr->aspath = aspath_empty_get();
1703
1704 // There are some public and some private ASNs, remove
1705 // the private ASNs
1706 else
1707 attr->aspath = aspath_remove_private_asns(
1708 attr->aspath, peer->as);
1709 }
1710
1711 // 'all' was not specified so the entire aspath must be private
1712 // ASNs
1713 // for us to do anything
1714 else if (aspath_private_as_check(attr->aspath)) {
1715 if (peer_af_flag_check(
1716 peer, afi, safi,
1717 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1718 attr->aspath = aspath_replace_private_asns(
1719 attr->aspath, bgp->as, peer->as);
1720 else
1721 attr->aspath = aspath_empty_get();
1722 }
1723 }
1724 }
1725
1726 /* If this is an EBGP peer with as-override */
1727 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1728 struct peer *peer, struct attr *attr)
1729 {
1730 if (peer->sort == BGP_PEER_EBGP
1731 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1732 if (aspath_single_asn_check(attr->aspath, peer->as))
1733 attr->aspath = aspath_replace_specific_asn(
1734 attr->aspath, peer->as, bgp->as);
1735 }
1736 }
1737
1738 void bgp_attr_add_llgr_community(struct attr *attr)
1739 {
1740 struct community *old;
1741 struct community *new;
1742 struct community *merge;
1743 struct community *llgr;
1744
1745 old = attr->community;
1746 llgr = community_str2com("llgr-stale");
1747
1748 assert(llgr);
1749
1750 if (old) {
1751 merge = community_merge(community_dup(old), llgr);
1752
1753 if (old->refcnt == 0)
1754 community_free(&old);
1755
1756 new = community_uniq_sort(merge);
1757 community_free(&merge);
1758 } else {
1759 new = community_dup(llgr);
1760 }
1761
1762 community_free(&llgr);
1763
1764 attr->community = new;
1765 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1766 }
1767
1768 void bgp_attr_add_gshut_community(struct attr *attr)
1769 {
1770 struct community *old;
1771 struct community *new;
1772 struct community *merge;
1773 struct community *gshut;
1774
1775 old = attr->community;
1776 gshut = community_str2com("graceful-shutdown");
1777
1778 assert(gshut);
1779
1780 if (old) {
1781 merge = community_merge(community_dup(old), gshut);
1782
1783 if (old->refcnt == 0)
1784 community_free(&old);
1785
1786 new = community_uniq_sort(merge);
1787 community_free(&merge);
1788 } else {
1789 new = community_dup(gshut);
1790 }
1791
1792 community_free(&gshut);
1793 attr->community = new;
1794 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1795
1796 /* When we add the graceful-shutdown community we must also
1797 * lower the local-preference */
1798 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1799 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1800 }
1801
1802
1803 /* Notify BGP Conditional advertisement scanner process. */
1804 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1805 {
1806 struct peer *peer = SUBGRP_PEER(subgrp);
1807 afi_t afi = SUBGRP_AFI(subgrp);
1808 safi_t safi = SUBGRP_SAFI(subgrp);
1809 struct bgp_filter *filter = &peer->filter[afi][safi];
1810
1811 if (!ADVERTISE_MAP_NAME(filter))
1812 return;
1813
1814 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1815 return;
1816
1817 peer->advmap_table_change = true;
1818 }
1819
1820
1821 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1822 {
1823 if (family == AF_INET) {
1824 attr->nexthop.s_addr = INADDR_ANY;
1825 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1826 }
1827 if (family == AF_INET6)
1828 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1829 if (family == AF_EVPN)
1830 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1831 }
1832
1833 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1834 struct update_subgroup *subgrp,
1835 const struct prefix *p, struct attr *attr,
1836 bool skip_rmap_check)
1837 {
1838 struct bgp_filter *filter;
1839 struct peer *from;
1840 struct peer *peer;
1841 struct peer *onlypeer;
1842 struct bgp *bgp;
1843 struct attr *piattr;
1844 route_map_result_t ret;
1845 int transparent;
1846 int reflect;
1847 afi_t afi;
1848 safi_t safi;
1849 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1850 bool nh_reset = false;
1851 uint64_t cum_bw;
1852
1853 if (DISABLE_BGP_ANNOUNCE)
1854 return false;
1855
1856 afi = SUBGRP_AFI(subgrp);
1857 safi = SUBGRP_SAFI(subgrp);
1858 peer = SUBGRP_PEER(subgrp);
1859 onlypeer = NULL;
1860 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1861 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1862
1863 from = pi->peer;
1864 filter = &peer->filter[afi][safi];
1865 bgp = SUBGRP_INST(subgrp);
1866 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1867 : pi->attr;
1868
1869 #ifdef ENABLE_BGP_VNC
1870 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1871 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1872 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1873
1874 /*
1875 * direct and direct_ext type routes originate internally even
1876 * though they can have peer pointers that reference other
1877 * systems
1878 */
1879 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1880 __func__, p);
1881 samepeer_safe = 1;
1882 }
1883 #endif
1884
1885 if (((afi == AFI_IP) || (afi == AFI_IP6))
1886 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1887 && (pi->type == ZEBRA_ROUTE_BGP)
1888 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1889
1890 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1891
1892 samepeer_safe = 1;
1893 }
1894
1895 /* With addpath we may be asked to TX all kinds of paths so make sure
1896 * pi is valid */
1897 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1898 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1899 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1900 return false;
1901 }
1902
1903 /* If this is not the bestpath then check to see if there is an enabled
1904 * addpath
1905 * feature that requires us to advertise it */
1906 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1907 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1908 return false;
1909 }
1910 }
1911
1912 /* Aggregate-address suppress check. */
1913 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1914 return false;
1915
1916 /*
1917 * If we are doing VRF 2 VRF leaking via the import
1918 * statement, we want to prevent the route going
1919 * off box as that the RT and RD created are localy
1920 * significant and globaly useless.
1921 */
1922 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1923 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1924 return false;
1925
1926 /* If it's labeled safi, make sure the route has a valid label. */
1927 if (safi == SAFI_LABELED_UNICAST) {
1928 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1929 if (!bgp_is_valid_label(&label)) {
1930 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1931 zlog_debug("u%" PRIu64 ":s%" PRIu64
1932 " %pFX is filtered - no label (%p)",
1933 subgrp->update_group->id, subgrp->id,
1934 p, &label);
1935 return false;
1936 }
1937 }
1938
1939 /* Do not send back route to sender. */
1940 if (onlypeer && from == onlypeer) {
1941 return false;
1942 }
1943
1944 /* Do not send the default route in the BGP table if the neighbor is
1945 * configured for default-originate */
1946 if (CHECK_FLAG(peer->af_flags[afi][safi],
1947 PEER_FLAG_DEFAULT_ORIGINATE)) {
1948 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1949 return false;
1950 else if (p->family == AF_INET6 && p->prefixlen == 0)
1951 return false;
1952 }
1953
1954 /* Transparency check. */
1955 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1956 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1957 transparent = 1;
1958 else
1959 transparent = 0;
1960
1961 /* If community is not disabled check the no-export and local. */
1962 if (!transparent && bgp_community_filter(peer, piattr)) {
1963 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1964 zlog_debug("%s: community filter check fail for %pFX",
1965 __func__, p);
1966 return false;
1967 }
1968
1969 /* If the attribute has originator-id and it is same as remote
1970 peer's id. */
1971 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1972 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1973 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1974 zlog_debug(
1975 "%s [Update:SEND] %pFX originator-id is same as remote router-id",
1976 onlypeer->host, p);
1977 return false;
1978 }
1979
1980 /* ORF prefix-list filter check */
1981 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1982 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1983 || CHECK_FLAG(peer->af_cap[afi][safi],
1984 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1985 if (peer->orf_plist[afi][safi]) {
1986 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1987 == PREFIX_DENY) {
1988 if (bgp_debug_update(NULL, p,
1989 subgrp->update_group, 0))
1990 zlog_debug(
1991 "%s [Update:SEND] %pFX is filtered via ORF",
1992 peer->host, p);
1993 return false;
1994 }
1995 }
1996
1997 /* Output filter check. */
1998 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1999 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2000 zlog_debug("%s [Update:SEND] %pFX is filtered",
2001 peer->host, p);
2002 return false;
2003 }
2004
2005 /* AS path loop check. */
2006 if (onlypeer && onlypeer->as_path_loop_detection
2007 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
2008 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2009 zlog_debug(
2010 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
2011 onlypeer->host, onlypeer->as);
2012 return false;
2013 }
2014
2015 /* If we're a CONFED we need to loop check the CONFED ID too */
2016 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
2017 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
2018 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2019 zlog_debug(
2020 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
2021 peer->host, bgp->confed_id);
2022 return false;
2023 }
2024 }
2025
2026 /* Route-Reflect check. */
2027 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2028 reflect = 1;
2029 else
2030 reflect = 0;
2031
2032 /* IBGP reflection check. */
2033 if (reflect && !samepeer_safe) {
2034 /* A route from a Client peer. */
2035 if (CHECK_FLAG(from->af_flags[afi][safi],
2036 PEER_FLAG_REFLECTOR_CLIENT)) {
2037 /* Reflect to all the Non-Client peers and also to the
2038 Client peers other than the originator. Originator
2039 check
2040 is already done. So there is noting to do. */
2041 /* no bgp client-to-client reflection check. */
2042 if (CHECK_FLAG(bgp->flags,
2043 BGP_FLAG_NO_CLIENT_TO_CLIENT))
2044 if (CHECK_FLAG(peer->af_flags[afi][safi],
2045 PEER_FLAG_REFLECTOR_CLIENT))
2046 return false;
2047 } else {
2048 /* A route from a Non-client peer. Reflect to all other
2049 clients. */
2050 if (!CHECK_FLAG(peer->af_flags[afi][safi],
2051 PEER_FLAG_REFLECTOR_CLIENT))
2052 return false;
2053 }
2054 }
2055
2056 /* For modify attribute, copy it to temporary structure. */
2057 *attr = *piattr;
2058
2059 /* If local-preference is not set. */
2060 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
2061 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
2062 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2063 attr->local_pref = bgp->default_local_pref;
2064 }
2065
2066 /* If originator-id is not set and the route is to be reflected,
2067 set the originator id */
2068 if (reflect
2069 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
2070 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2071 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2072 }
2073
2074 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2075 */
2076 if (peer->sort == BGP_PEER_EBGP
2077 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2078 if (from != bgp->peer_self && !transparent
2079 && !CHECK_FLAG(peer->af_flags[afi][safi],
2080 PEER_FLAG_MED_UNCHANGED))
2081 attr->flag &=
2082 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2083 }
2084
2085 /* Since the nexthop attribute can vary per peer, it is not explicitly
2086 * set
2087 * in announce check, only certain flags and length (or number of
2088 * nexthops
2089 * -- for IPv6/MP_REACH) are set here in order to guide the update
2090 * formation
2091 * code in setting the nexthop(s) on a per peer basis in
2092 * reformat_peer().
2093 * Typically, the source nexthop in the attribute is preserved but in
2094 * the
2095 * scenarios where we know it will always be overwritten, we reset the
2096 * nexthop to "0" in an attempt to achieve better Update packing. An
2097 * example of this is when a prefix from each of 2 IBGP peers needs to
2098 * be
2099 * announced to an EBGP peer (and they have the same attributes barring
2100 * their nexthop).
2101 */
2102 if (reflect)
2103 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2104
2105 #define NEXTHOP_IS_V6 \
2106 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2107 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2108 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2109 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2110
2111 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2112 * if
2113 * the peer (group) is configured to receive link-local nexthop
2114 * unchanged
2115 * and it is available in the prefix OR we're not reflecting the route,
2116 * link-local nexthop address is valid and
2117 * the peer (group) to whom we're going to announce is on a shared
2118 * network
2119 * and this is either a self-originated route or the peer is EBGP.
2120 * By checking if nexthop LL address is valid we are sure that
2121 * we do not announce LL address as `::`.
2122 */
2123 if (NEXTHOP_IS_V6) {
2124 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2125 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2126 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2127 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2128 || (!reflect && !transparent
2129 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2130 && peer->shared_network
2131 && (from == bgp->peer_self
2132 || peer->sort == BGP_PEER_EBGP))) {
2133 attr->mp_nexthop_len =
2134 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2135 }
2136
2137 /* Clear off link-local nexthop in source, whenever it is not
2138 * needed to
2139 * ensure more prefixes share the same attribute for
2140 * announcement.
2141 */
2142 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2143 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2144 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2145 }
2146
2147 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2148 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2149
2150 /* Route map & unsuppress-map apply. */
2151 if (!skip_rmap_check
2152 && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2153 struct bgp_path_info rmap_path = {0};
2154 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2155 struct attr dummy_attr = {0};
2156
2157 /* Fill temp path_info */
2158 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2159 pi, peer, attr);
2160
2161 /* don't confuse inbound and outbound setting */
2162 RESET_FLAG(attr->rmap_change_flags);
2163
2164 /*
2165 * The route reflector is not allowed to modify the attributes
2166 * of the reflected IBGP routes unless explicitly allowed.
2167 */
2168 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2169 && !CHECK_FLAG(bgp->flags,
2170 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2171 dummy_attr = *attr;
2172 rmap_path.attr = &dummy_attr;
2173 }
2174
2175 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2176
2177 if (bgp_path_suppressed(pi))
2178 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2179 &rmap_path);
2180 else
2181 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2182 &rmap_path);
2183
2184 peer->rmap_type = 0;
2185
2186 if (ret == RMAP_DENYMATCH) {
2187 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2188 zlog_debug(
2189 "%s [Update:SEND] %pFX is filtered by route-map",
2190 peer->host, p);
2191
2192 bgp_attr_flush(attr);
2193 return false;
2194 }
2195 }
2196
2197 /* RFC 8212 to prevent route leaks.
2198 * This specification intends to improve this situation by requiring the
2199 * explicit configuration of both BGP Import and Export Policies for any
2200 * External BGP (EBGP) session such as customers, peers, or
2201 * confederation boundaries for all enabled address families. Through
2202 * codification of the aforementioned requirement, operators will
2203 * benefit from consistent behavior across different BGP
2204 * implementations.
2205 */
2206 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2207 if (!bgp_outbound_policy_exists(peer, filter))
2208 return false;
2209
2210 /* draft-ietf-idr-deprecate-as-set-confed-set
2211 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2212 * Eventually, This document (if approved) updates RFC 4271
2213 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2214 * and obsoletes RFC 6472.
2215 */
2216 if (peer->bgp->reject_as_sets)
2217 if (aspath_check_as_sets(attr->aspath))
2218 return false;
2219
2220 /* Codification of AS 0 Processing */
2221 if (aspath_check_as_zero(attr->aspath))
2222 return false;
2223
2224 if (bgp_in_graceful_shutdown(bgp)) {
2225 if (peer->sort == BGP_PEER_IBGP
2226 || peer->sort == BGP_PEER_CONFED) {
2227 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2228 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2229 } else {
2230 bgp_attr_add_gshut_community(attr);
2231 }
2232 }
2233
2234 /* A BGP speaker that has advertised the "Long-lived Graceful Restart
2235 * Capability" to a neighbor MUST perform the following upon receiving
2236 * a route from that neighbor with the "LLGR_STALE" community, or upon
2237 * attaching the "LLGR_STALE" community itself per Section 4.2:
2238 *
2239 * The route SHOULD NOT be advertised to any neighbor from which the
2240 * Long-lived Graceful Restart Capability has not been received.
2241 */
2242 if (attr->community &&
2243 community_include(attr->community, COMMUNITY_LLGR_STALE) &&
2244 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_RCV) &&
2245 !CHECK_FLAG(peer->cap, PEER_CAP_LLGR_ADV))
2246 return false;
2247
2248 /* After route-map has been applied, we check to see if the nexthop to
2249 * be carried in the attribute (that is used for the announcement) can
2250 * be cleared off or not. We do this in all cases where we would be
2251 * setting the nexthop to "ourselves". For IPv6, we only need to
2252 * consider
2253 * the global nexthop here; the link-local nexthop would have been
2254 * cleared
2255 * already, and if not, it is required by the update formation code.
2256 * Also see earlier comments in this function.
2257 */
2258 /*
2259 * If route-map has performed some operation on the nexthop or the peer
2260 * configuration says to pass it unchanged, we cannot reset the nexthop
2261 * here, so only attempt to do it if these aren't true. Note that the
2262 * route-map handler itself might have cleared the nexthop, if for
2263 * example,
2264 * it is configured as 'peer-address'.
2265 */
2266 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2267 piattr->rmap_change_flags)
2268 && !transparent
2269 && !CHECK_FLAG(peer->af_flags[afi][safi],
2270 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2271 /* We can reset the nexthop, if setting (or forcing) it to
2272 * 'self' */
2273 if (CHECK_FLAG(peer->af_flags[afi][safi],
2274 PEER_FLAG_NEXTHOP_SELF)
2275 || CHECK_FLAG(peer->af_flags[afi][safi],
2276 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2277 if (!reflect
2278 || CHECK_FLAG(peer->af_flags[afi][safi],
2279 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2280 subgroup_announce_reset_nhop(
2281 (peer_cap_enhe(peer, afi, safi)
2282 ? AF_INET6
2283 : p->family),
2284 attr);
2285 nh_reset = true;
2286 }
2287 } else if (peer->sort == BGP_PEER_EBGP) {
2288 /* Can also reset the nexthop if announcing to EBGP, but
2289 * only if
2290 * no peer in the subgroup is on a shared subnet.
2291 * Note: 3rd party nexthop currently implemented for
2292 * IPv4 only.
2293 */
2294 if ((p->family == AF_INET) &&
2295 (!bgp_subgrp_multiaccess_check_v4(
2296 piattr->nexthop,
2297 subgrp, from))) {
2298 subgroup_announce_reset_nhop(
2299 (peer_cap_enhe(peer, afi, safi)
2300 ? AF_INET6
2301 : p->family),
2302 attr);
2303 nh_reset = true;
2304 }
2305
2306 if ((p->family == AF_INET6) &&
2307 (!bgp_subgrp_multiaccess_check_v6(
2308 piattr->mp_nexthop_global,
2309 subgrp, from))) {
2310 subgroup_announce_reset_nhop(
2311 (peer_cap_enhe(peer, afi, safi)
2312 ? AF_INET6
2313 : p->family),
2314 attr);
2315 nh_reset = true;
2316 }
2317
2318
2319
2320 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2321 /*
2322 * This flag is used for leaked vpn-vrf routes
2323 */
2324 int family = p->family;
2325
2326 if (peer_cap_enhe(peer, afi, safi))
2327 family = AF_INET6;
2328
2329 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2330 zlog_debug(
2331 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2332 __func__, family2str(family));
2333 subgroup_announce_reset_nhop(family, attr);
2334 nh_reset = true;
2335 }
2336 }
2337
2338 /* If IPv6/MP and nexthop does not have any override and happens
2339 * to
2340 * be a link-local address, reset it so that we don't pass along
2341 * the
2342 * source's link-local IPv6 address to recipients who may not be
2343 * on
2344 * the same interface.
2345 */
2346 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2347 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2348 subgroup_announce_reset_nhop(AF_INET6, attr);
2349 nh_reset = true;
2350 }
2351 }
2352
2353 /*
2354 * When the next hop is set to ourselves, if all multipaths have
2355 * link-bandwidth announce the cumulative bandwidth as that makes
2356 * the most sense. However, don't modify if the link-bandwidth has
2357 * been explicitly set by user policy.
2358 */
2359 if (nh_reset &&
2360 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2361 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2362 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2363 attr->ecommunity = ecommunity_replace_linkbw(
2364 bgp->as, attr->ecommunity, cum_bw,
2365 CHECK_FLAG(peer->flags,
2366 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
2367
2368 return true;
2369 }
2370
2371 static int bgp_route_select_timer_expire(struct thread *thread)
2372 {
2373 struct afi_safi_info *info;
2374 afi_t afi;
2375 safi_t safi;
2376 struct bgp *bgp;
2377
2378 info = THREAD_ARG(thread);
2379 afi = info->afi;
2380 safi = info->safi;
2381 bgp = info->bgp;
2382
2383 if (BGP_DEBUG(update, UPDATE_OUT))
2384 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2385 safi);
2386
2387 bgp->gr_info[afi][safi].t_route_select = NULL;
2388
2389 XFREE(MTYPE_TMP, info);
2390
2391 /* Best path selection */
2392 return bgp_best_path_select_defer(bgp, afi, safi);
2393 }
2394
2395 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2396 struct bgp_maxpaths_cfg *mpath_cfg,
2397 struct bgp_path_info_pair *result, afi_t afi,
2398 safi_t safi)
2399 {
2400 struct bgp_path_info *new_select;
2401 struct bgp_path_info *old_select;
2402 struct bgp_path_info *pi;
2403 struct bgp_path_info *pi1;
2404 struct bgp_path_info *pi2;
2405 struct bgp_path_info *nextpi = NULL;
2406 int paths_eq, do_mpath, debug;
2407 struct list mp_list;
2408 char pfx_buf[PREFIX2STR_BUFFER];
2409 char path_buf[PATH_ADDPATH_STR_BUFFER];
2410
2411 bgp_mp_list_init(&mp_list);
2412 do_mpath =
2413 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2414
2415 debug = bgp_debug_bestpath(dest);
2416
2417 if (debug)
2418 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2419
2420 dest->reason = bgp_path_selection_none;
2421 /* bgp deterministic-med */
2422 new_select = NULL;
2423 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2424
2425 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2426 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2427 pi1 = pi1->next)
2428 bgp_path_info_unset_flag(dest, pi1,
2429 BGP_PATH_DMED_SELECTED);
2430
2431 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2432 pi1 = pi1->next) {
2433 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2434 continue;
2435 if (BGP_PATH_HOLDDOWN(pi1))
2436 continue;
2437 if (pi1->peer != bgp->peer_self)
2438 if (!peer_established(pi1->peer))
2439 continue;
2440
2441 new_select = pi1;
2442 if (pi1->next) {
2443 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2444 if (CHECK_FLAG(pi2->flags,
2445 BGP_PATH_DMED_CHECK))
2446 continue;
2447 if (BGP_PATH_HOLDDOWN(pi2))
2448 continue;
2449 if (pi2->peer != bgp->peer_self
2450 && !CHECK_FLAG(
2451 pi2->peer->sflags,
2452 PEER_STATUS_NSF_WAIT))
2453 if (pi2->peer->status
2454 != Established)
2455 continue;
2456
2457 if (!aspath_cmp_left(pi1->attr->aspath,
2458 pi2->attr->aspath)
2459 && !aspath_cmp_left_confed(
2460 pi1->attr->aspath,
2461 pi2->attr->aspath))
2462 continue;
2463
2464 if (bgp_path_info_cmp(
2465 bgp, pi2, new_select,
2466 &paths_eq, mpath_cfg, debug,
2467 pfx_buf, afi, safi,
2468 &dest->reason)) {
2469 bgp_path_info_unset_flag(
2470 dest, new_select,
2471 BGP_PATH_DMED_SELECTED);
2472 new_select = pi2;
2473 }
2474
2475 bgp_path_info_set_flag(
2476 dest, pi2, BGP_PATH_DMED_CHECK);
2477 }
2478 }
2479 bgp_path_info_set_flag(dest, new_select,
2480 BGP_PATH_DMED_CHECK);
2481 bgp_path_info_set_flag(dest, new_select,
2482 BGP_PATH_DMED_SELECTED);
2483
2484 if (debug) {
2485 bgp_path_info_path_with_addpath_rx_str(
2486 new_select, path_buf, sizeof(path_buf));
2487 zlog_debug(
2488 "%pBD(%s): %s is the bestpath from AS %u",
2489 dest, bgp->name_pretty, path_buf,
2490 aspath_get_first_as(
2491 new_select->attr->aspath));
2492 }
2493 }
2494 }
2495
2496 /* Check old selected route and new selected route. */
2497 old_select = NULL;
2498 new_select = NULL;
2499 for (pi = bgp_dest_get_bgp_path_info(dest);
2500 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2501 enum bgp_path_selection_reason reason;
2502
2503 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2504 old_select = pi;
2505
2506 if (BGP_PATH_HOLDDOWN(pi)) {
2507 /* reap REMOVED routes, if needs be
2508 * selected route must stay for a while longer though
2509 */
2510 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2511 && (pi != old_select))
2512 bgp_path_info_reap(dest, pi);
2513
2514 if (debug)
2515 zlog_debug("%s: pi %p in holddown", __func__,
2516 pi);
2517
2518 continue;
2519 }
2520
2521 if (pi->peer && pi->peer != bgp->peer_self
2522 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2523 if (!peer_established(pi->peer)) {
2524
2525 if (debug)
2526 zlog_debug(
2527 "%s: pi %p non self peer %s not estab state",
2528 __func__, pi, pi->peer->host);
2529
2530 continue;
2531 }
2532
2533 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2534 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2535 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2536 if (debug)
2537 zlog_debug("%s: pi %p dmed", __func__, pi);
2538 continue;
2539 }
2540
2541 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2542
2543 reason = dest->reason;
2544 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2545 debug, pfx_buf, afi, safi,
2546 &dest->reason)) {
2547 if (new_select == NULL &&
2548 reason != bgp_path_selection_none)
2549 dest->reason = reason;
2550 new_select = pi;
2551 }
2552 }
2553
2554 /* Now that we know which path is the bestpath see if any of the other
2555 * paths
2556 * qualify as multipaths
2557 */
2558 if (debug) {
2559 if (new_select)
2560 bgp_path_info_path_with_addpath_rx_str(
2561 new_select, path_buf, sizeof(path_buf));
2562 else
2563 snprintf(path_buf, sizeof(path_buf), "NONE");
2564 zlog_debug(
2565 "%pBD(%s): After path selection, newbest is %s oldbest was %s",
2566 dest, bgp->name_pretty, path_buf,
2567 old_select ? old_select->peer->host : "NONE");
2568 }
2569
2570 if (do_mpath && new_select) {
2571 for (pi = bgp_dest_get_bgp_path_info(dest);
2572 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2573
2574 if (debug)
2575 bgp_path_info_path_with_addpath_rx_str(
2576 pi, path_buf, sizeof(path_buf));
2577
2578 if (pi == new_select) {
2579 if (debug)
2580 zlog_debug(
2581 "%pBD(%s): %s is the bestpath, add to the multipath list",
2582 dest, bgp->name_pretty,
2583 path_buf);
2584 bgp_mp_list_add(&mp_list, pi);
2585 continue;
2586 }
2587
2588 if (BGP_PATH_HOLDDOWN(pi))
2589 continue;
2590
2591 if (pi->peer && pi->peer != bgp->peer_self
2592 && !CHECK_FLAG(pi->peer->sflags,
2593 PEER_STATUS_NSF_WAIT))
2594 if (!peer_established(pi->peer))
2595 continue;
2596
2597 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2598 if (debug)
2599 zlog_debug(
2600 "%pBD: %s has the same nexthop as the bestpath, skip it",
2601 dest, path_buf);
2602 continue;
2603 }
2604
2605 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2606 mpath_cfg, debug, pfx_buf, afi, safi,
2607 &dest->reason);
2608
2609 if (paths_eq) {
2610 if (debug)
2611 zlog_debug(
2612 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2613 dest, path_buf);
2614 bgp_mp_list_add(&mp_list, pi);
2615 }
2616 }
2617 }
2618
2619 bgp_path_info_mpath_update(bgp, dest, new_select, old_select, &mp_list,
2620 mpath_cfg);
2621 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2622 bgp_mp_list_clear(&mp_list);
2623
2624 bgp_addpath_update_ids(bgp, dest, afi, safi);
2625
2626 result->old = old_select;
2627 result->new = new_select;
2628
2629 return;
2630 }
2631
2632 /*
2633 * A new route/change in bestpath of an existing route. Evaluate the path
2634 * for advertisement to the subgroup.
2635 */
2636 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2637 struct bgp_path_info *selected,
2638 struct bgp_dest *dest,
2639 uint32_t addpath_tx_id)
2640 {
2641 const struct prefix *p;
2642 struct peer *onlypeer;
2643 struct attr attr;
2644 afi_t afi;
2645 safi_t safi;
2646 struct bgp *bgp;
2647 bool advertise;
2648
2649 p = bgp_dest_get_prefix(dest);
2650 afi = SUBGRP_AFI(subgrp);
2651 safi = SUBGRP_SAFI(subgrp);
2652 bgp = SUBGRP_INST(subgrp);
2653 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2654 : NULL);
2655
2656 if (BGP_DEBUG(update, UPDATE_OUT))
2657 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2658
2659 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2660 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2661 PEER_STATUS_ORF_WAIT_REFRESH))
2662 return;
2663
2664 memset(&attr, 0, sizeof(struct attr));
2665 /* It's initialized in bgp_announce_check() */
2666
2667 /* Announcement to the subgroup. If the route is filtered withdraw it.
2668 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2669 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2670 * route
2671 */
2672 advertise = bgp_check_advertise(bgp, dest);
2673
2674 if (selected) {
2675 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2676 false)) {
2677 /* Route is selected, if the route is already installed
2678 * in FIB, then it is advertised
2679 */
2680 if (advertise) {
2681 if (!bgp_check_withdrawal(bgp, dest))
2682 bgp_adj_out_set_subgroup(
2683 dest, subgrp, &attr, selected);
2684 else
2685 bgp_adj_out_unset_subgroup(
2686 dest, subgrp, 1, addpath_tx_id);
2687 }
2688 } else
2689 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2690 addpath_tx_id);
2691 }
2692
2693 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2694 else {
2695 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2696 }
2697 }
2698
2699 /*
2700 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2701 * This is called at the end of route processing.
2702 */
2703 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2704 {
2705 struct bgp_path_info *pi;
2706
2707 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2708 if (BGP_PATH_HOLDDOWN(pi))
2709 continue;
2710 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2711 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2712 }
2713 }
2714
2715 /*
2716 * Has the route changed from the RIB's perspective? This is invoked only
2717 * if the route selection returns the same best route as earlier - to
2718 * determine if we need to update zebra or not.
2719 */
2720 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2721 {
2722 struct bgp_path_info *mpinfo;
2723
2724 /* If this is multipath, check all selected paths for any nexthop
2725 * change or attribute change. Some attribute changes (e.g., community)
2726 * aren't of relevance to the RIB, but we'll update zebra to ensure
2727 * we handle the case of BGP nexthop change. This is the behavior
2728 * when the best path has an attribute change anyway.
2729 */
2730 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2731 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2732 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2733 return true;
2734
2735 /*
2736 * If this is multipath, check all selected paths for any nexthop change
2737 */
2738 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2739 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2740 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2741 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2742 return true;
2743 }
2744
2745 /* Nothing has changed from the RIB's perspective. */
2746 return false;
2747 }
2748
2749 struct bgp_process_queue {
2750 struct bgp *bgp;
2751 STAILQ_HEAD(, bgp_dest) pqueue;
2752 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2753 unsigned int flags;
2754 unsigned int queued;
2755 };
2756
2757 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2758 safi_t safi, struct bgp_dest *dest,
2759 struct bgp_path_info *new_select,
2760 struct bgp_path_info *old_select)
2761 {
2762 const struct prefix *p = bgp_dest_get_prefix(dest);
2763
2764 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2765 return;
2766
2767 if (advertise_type5_routes(bgp, afi) && new_select
2768 && is_route_injectable_into_evpn(new_select)) {
2769
2770 /* apply the route-map */
2771 if (bgp->adv_cmd_rmap[afi][safi].map) {
2772 route_map_result_t ret;
2773 struct bgp_path_info rmap_path;
2774 struct bgp_path_info_extra rmap_path_extra;
2775 struct attr dummy_attr;
2776
2777 dummy_attr = *new_select->attr;
2778
2779 /* Fill temp path_info */
2780 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2781 new_select, new_select->peer,
2782 &dummy_attr);
2783
2784 RESET_FLAG(dummy_attr.rmap_change_flags);
2785
2786 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2787 p, &rmap_path);
2788
2789 if (ret == RMAP_DENYMATCH) {
2790 bgp_attr_flush(&dummy_attr);
2791 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2792 safi);
2793 } else
2794 bgp_evpn_advertise_type5_route(
2795 bgp, p, &dummy_attr, afi, safi);
2796 } else {
2797 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2798 afi, safi);
2799 }
2800 } else if (advertise_type5_routes(bgp, afi) && old_select
2801 && is_route_injectable_into_evpn(old_select))
2802 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2803 }
2804
2805 /*
2806 * Utility to determine whether a particular path_info should use
2807 * the IMPLICIT_NULL label. This is pretty specialized: it's only called
2808 * in a path where we basically _know_ this is a BGP-LU route.
2809 */
2810 static bool bgp_lu_need_imp_null(const struct bgp_path_info *new_select)
2811 {
2812 /* Certain types get imp null; so do paths where the nexthop is
2813 * not labeled.
2814 */
2815 if (new_select->sub_type == BGP_ROUTE_STATIC
2816 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2817 || new_select->sub_type == BGP_ROUTE_REDISTRIBUTE)
2818 return true;
2819 else if (new_select->extra == NULL ||
2820 !bgp_is_valid_label(&new_select->extra->label[0]))
2821 /* TODO -- should be configurable? */
2822 return true;
2823 else
2824 return false;
2825 }
2826
2827 /*
2828 * old_select = The old best path
2829 * new_select = the new best path
2830 *
2831 * if (!old_select && new_select)
2832 * We are sending new information on.
2833 *
2834 * if (old_select && new_select) {
2835 * if (new_select != old_select)
2836 * We have a new best path send a change
2837 * else
2838 * We've received a update with new attributes that needs
2839 * to be passed on.
2840 * }
2841 *
2842 * if (old_select && !new_select)
2843 * We have no eligible route that we can announce or the rn
2844 * is being removed.
2845 */
2846 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2847 afi_t afi, safi_t safi)
2848 {
2849 struct bgp_path_info *new_select;
2850 struct bgp_path_info *old_select;
2851 struct bgp_path_info_pair old_and_new;
2852 int debug = 0;
2853
2854 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2855 if (dest)
2856 debug = bgp_debug_bestpath(dest);
2857 if (debug)
2858 zlog_debug(
2859 "%s: bgp delete in progress, ignoring event, p=%pBD",
2860 __func__, dest);
2861 return;
2862 }
2863 /* Is it end of initial update? (after startup) */
2864 if (!dest) {
2865 frr_timestamp(3, bgp->update_delay_zebra_resume_time,
2866 sizeof(bgp->update_delay_zebra_resume_time));
2867
2868 bgp->main_zebra_update_hold = 0;
2869 FOREACH_AFI_SAFI (afi, safi) {
2870 if (bgp_fibupd_safi(safi))
2871 bgp_zebra_announce_table(bgp, afi, safi);
2872 }
2873 bgp->main_peers_update_hold = 0;
2874
2875 bgp_start_routeadv(bgp);
2876 return;
2877 }
2878
2879 const struct prefix *p = bgp_dest_get_prefix(dest);
2880
2881 debug = bgp_debug_bestpath(dest);
2882 if (debug)
2883 zlog_debug("%s: p=%pBDi(%s) afi=%s, safi=%s start", __func__,
2884 dest, bgp->name_pretty, afi2str(afi),
2885 safi2str(safi));
2886
2887 /* The best path calculation for the route is deferred if
2888 * BGP_NODE_SELECT_DEFER is set
2889 */
2890 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2891 if (BGP_DEBUG(update, UPDATE_OUT))
2892 zlog_debug("SELECT_DEFER flag set for route %p", dest);
2893 return;
2894 }
2895
2896 /* Best path selection. */
2897 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2898 afi, safi);
2899 old_select = old_and_new.old;
2900 new_select = old_and_new.new;
2901
2902 /* Do we need to allocate or free labels?
2903 * Right now, since we only deal with per-prefix labels, it is not
2904 * necessary to do this upon changes to best path. Exceptions:
2905 * - label index has changed -> recalculate resulting label
2906 * - path_info sub_type changed -> switch to/from implicit-null
2907 * - no valid label (due to removed static label binding) -> get new one
2908 */
2909 if (bgp->allocate_mpls_labels[afi][safi]) {
2910 if (new_select) {
2911 if (!old_select
2912 || bgp_label_index_differs(new_select, old_select)
2913 || new_select->sub_type != old_select->sub_type
2914 || !bgp_is_valid_label(&dest->local_label)) {
2915 /* Enforced penultimate hop popping:
2916 * implicit-null for local routes, aggregate
2917 * and redistributed routes
2918 */
2919 if (bgp_lu_need_imp_null(new_select)) {
2920 if (CHECK_FLAG(
2921 dest->flags,
2922 BGP_NODE_REGISTERED_FOR_LABEL)
2923 || CHECK_FLAG(
2924 dest->flags,
2925 BGP_NODE_LABEL_REQUESTED))
2926 bgp_unregister_for_label(dest);
2927 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2928 &dest->local_label);
2929 bgp_set_valid_label(&dest->local_label);
2930 } else
2931 bgp_register_for_label(dest,
2932 new_select);
2933 }
2934 } else if (CHECK_FLAG(dest->flags,
2935 BGP_NODE_REGISTERED_FOR_LABEL)
2936 || CHECK_FLAG(dest->flags,
2937 BGP_NODE_LABEL_REQUESTED)) {
2938 bgp_unregister_for_label(dest);
2939 }
2940 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
2941 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
2942 bgp_unregister_for_label(dest);
2943 }
2944
2945 if (debug)
2946 zlog_debug(
2947 "%s: p=%pBD(%s) afi=%s, safi=%s, old_select=%p, new_select=%p",
2948 __func__, dest, bgp->name_pretty, afi2str(afi),
2949 safi2str(safi), old_select, new_select);
2950
2951 /* If best route remains the same and this is not due to user-initiated
2952 * clear, see exactly what needs to be done.
2953 */
2954 if (old_select && old_select == new_select
2955 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2956 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2957 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2958 if (bgp_zebra_has_route_changed(old_select)) {
2959 #ifdef ENABLE_BGP_VNC
2960 vnc_import_bgp_add_route(bgp, p, old_select);
2961 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2962 #endif
2963 if (bgp_fibupd_safi(safi)
2964 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2965
2966 if (BGP_SUPPRESS_FIB_ENABLED(bgp)
2967 && new_select->sub_type == BGP_ROUTE_NORMAL)
2968 SET_FLAG(dest->flags,
2969 BGP_NODE_FIB_INSTALL_PENDING);
2970
2971 if (new_select->type == ZEBRA_ROUTE_BGP
2972 && (new_select->sub_type == BGP_ROUTE_NORMAL
2973 || new_select->sub_type
2974 == BGP_ROUTE_IMPORTED))
2975
2976 bgp_zebra_announce(dest, p, old_select,
2977 bgp, afi, safi);
2978 }
2979 }
2980
2981 /* If there is a change of interest to peers, reannounce the
2982 * route. */
2983 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2984 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2985 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
2986 group_announce_route(bgp, afi, safi, dest, new_select);
2987
2988 /* unicast routes must also be annouced to
2989 * labeled-unicast update-groups */
2990 if (safi == SAFI_UNICAST)
2991 group_announce_route(bgp, afi,
2992 SAFI_LABELED_UNICAST, dest,
2993 new_select);
2994
2995 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2996 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
2997 }
2998
2999 /* advertise/withdraw type-5 routes */
3000 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
3001 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
3002 bgp_process_evpn_route_injection(
3003 bgp, afi, safi, dest, old_select, old_select);
3004
3005 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
3006 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
3007 bgp_zebra_clear_route_change_flags(dest);
3008 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3009 return;
3010 }
3011
3012 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
3013 */
3014 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
3015
3016 /* bestpath has changed; bump version */
3017 if (old_select || new_select) {
3018 bgp_bump_version(dest);
3019
3020 if (!bgp->t_rmap_def_originate_eval) {
3021 bgp_lock(bgp);
3022 thread_add_timer(
3023 bm->master,
3024 update_group_refresh_default_originate_route_map,
3025 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
3026 &bgp->t_rmap_def_originate_eval);
3027 }
3028 }
3029
3030 if (old_select)
3031 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
3032 if (new_select) {
3033 if (debug)
3034 zlog_debug("%s: setting SELECTED flag", __func__);
3035 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
3036 bgp_path_info_unset_flag(dest, new_select,
3037 BGP_PATH_ATTR_CHANGED);
3038 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
3039 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
3040 }
3041
3042 #ifdef ENABLE_BGP_VNC
3043 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3044 if (old_select != new_select) {
3045 if (old_select) {
3046 vnc_import_bgp_exterior_del_route(bgp, p,
3047 old_select);
3048 vnc_import_bgp_del_route(bgp, p, old_select);
3049 }
3050 if (new_select) {
3051 vnc_import_bgp_exterior_add_route(bgp, p,
3052 new_select);
3053 vnc_import_bgp_add_route(bgp, p, new_select);
3054 }
3055 }
3056 }
3057 #endif
3058
3059 group_announce_route(bgp, afi, safi, dest, new_select);
3060
3061 /* unicast routes must also be annouced to labeled-unicast update-groups
3062 */
3063 if (safi == SAFI_UNICAST)
3064 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
3065 new_select);
3066
3067 /* FIB update. */
3068 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
3069 && !bgp_option_check(BGP_OPT_NO_FIB)) {
3070
3071 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
3072 && (new_select->sub_type == BGP_ROUTE_NORMAL
3073 || new_select->sub_type == BGP_ROUTE_AGGREGATE
3074 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
3075
3076 if (BGP_SUPPRESS_FIB_ENABLED(bgp))
3077 SET_FLAG(dest->flags,
3078 BGP_NODE_FIB_INSTALL_PENDING);
3079
3080 /* if this is an evpn imported type-5 prefix,
3081 * we need to withdraw the route first to clear
3082 * the nh neigh and the RMAC entry.
3083 */
3084 if (old_select &&
3085 is_route_parent_evpn(old_select))
3086 bgp_zebra_withdraw(p, old_select, bgp, safi);
3087
3088 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
3089 } else {
3090 /* Withdraw the route from the kernel. */
3091 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
3092 && (old_select->sub_type == BGP_ROUTE_NORMAL
3093 || old_select->sub_type == BGP_ROUTE_AGGREGATE
3094 || old_select->sub_type == BGP_ROUTE_IMPORTED))
3095
3096 bgp_zebra_withdraw(p, old_select, bgp, safi);
3097 }
3098 }
3099
3100 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
3101 old_select);
3102
3103 /* Clear any route change flags. */
3104 bgp_zebra_clear_route_change_flags(dest);
3105
3106 /* Reap old select bgp_path_info, if it has been removed */
3107 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
3108 bgp_path_info_reap(dest, old_select);
3109
3110 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3111 return;
3112 }
3113
3114 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
3115 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
3116 {
3117 struct bgp_dest *dest;
3118 int cnt = 0;
3119 struct afi_safi_info *thread_info;
3120
3121 if (bgp->gr_info[afi][safi].t_route_select) {
3122 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3123
3124 thread_info = THREAD_ARG(t);
3125 XFREE(MTYPE_TMP, thread_info);
3126 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
3127 }
3128
3129 if (BGP_DEBUG(update, UPDATE_OUT)) {
3130 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3131 get_afi_safi_str(afi, safi, false),
3132 bgp->gr_info[afi][safi].gr_deferred);
3133 }
3134
3135 /* Process the route list */
3136 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3137 dest && bgp->gr_info[afi][safi].gr_deferred != 0;
3138 dest = bgp_route_next(dest)) {
3139 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3140 continue;
3141
3142 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3143 bgp->gr_info[afi][safi].gr_deferred--;
3144 bgp_process_main_one(bgp, dest, afi, safi);
3145 cnt++;
3146 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) {
3147 bgp_dest_unlock_node(dest);
3148 break;
3149 }
3150 }
3151
3152 /* Send EOR message when all routes are processed */
3153 if (!bgp->gr_info[afi][safi].gr_deferred) {
3154 bgp_send_delayed_eor(bgp);
3155 /* Send route processing complete message to RIB */
3156 bgp_zebra_update(afi, safi, bgp->vrf_id,
3157 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3158 return 0;
3159 }
3160
3161 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3162
3163 thread_info->afi = afi;
3164 thread_info->safi = safi;
3165 thread_info->bgp = bgp;
3166
3167 /* If there are more routes to be processed, start the
3168 * selection timer
3169 */
3170 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3171 BGP_ROUTE_SELECT_DELAY,
3172 &bgp->gr_info[afi][safi].t_route_select);
3173 return 0;
3174 }
3175
3176 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3177 {
3178 struct bgp_process_queue *pqnode = data;
3179 struct bgp *bgp = pqnode->bgp;
3180 struct bgp_table *table;
3181 struct bgp_dest *dest;
3182
3183 /* eoiu marker */
3184 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3185 bgp_process_main_one(bgp, NULL, 0, 0);
3186 /* should always have dedicated wq call */
3187 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3188 return WQ_SUCCESS;
3189 }
3190
3191 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3192 dest = STAILQ_FIRST(&pqnode->pqueue);
3193 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3194 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3195 table = bgp_dest_table(dest);
3196 /* note, new DESTs may be added as part of processing */
3197 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3198
3199 bgp_dest_unlock_node(dest);
3200 bgp_table_unlock(table);
3201 }
3202
3203 return WQ_SUCCESS;
3204 }
3205
3206 static void bgp_processq_del(struct work_queue *wq, void *data)
3207 {
3208 struct bgp_process_queue *pqnode = data;
3209
3210 bgp_unlock(pqnode->bgp);
3211
3212 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3213 }
3214
3215 void bgp_process_queue_init(struct bgp *bgp)
3216 {
3217 if (!bgp->process_queue) {
3218 char name[BUFSIZ];
3219
3220 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3221 bgp->process_queue = work_queue_new(bm->master, name);
3222 }
3223
3224 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3225 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3226 bgp->process_queue->spec.max_retries = 0;
3227 bgp->process_queue->spec.hold = 50;
3228 /* Use a higher yield value of 50ms for main queue processing */
3229 bgp->process_queue->spec.yield = 50 * 1000L;
3230 }
3231
3232 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3233 {
3234 struct bgp_process_queue *pqnode;
3235
3236 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3237 sizeof(struct bgp_process_queue));
3238
3239 /* unlocked in bgp_processq_del */
3240 pqnode->bgp = bgp_lock(bgp);
3241 STAILQ_INIT(&pqnode->pqueue);
3242
3243 return pqnode;
3244 }
3245
3246 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3247 {
3248 #define ARBITRARY_PROCESS_QLEN 10000
3249 struct work_queue *wq = bgp->process_queue;
3250 struct bgp_process_queue *pqnode;
3251 int pqnode_reuse = 0;
3252
3253 /* already scheduled for processing? */
3254 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3255 return;
3256
3257 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3258 * the workqueue
3259 */
3260 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3261 if (BGP_DEBUG(update, UPDATE_OUT))
3262 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3263 dest);
3264 return;
3265 }
3266
3267 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3268 if (BGP_DEBUG(update, UPDATE_OUT))
3269 zlog_debug(
3270 "Soft reconfigure table in progress for route %p",
3271 dest);
3272 return;
3273 }
3274
3275 if (wq == NULL)
3276 return;
3277
3278 /* Add route nodes to an existing work queue item until reaching the
3279 limit only if is from the same BGP view and it's not an EOIU marker
3280 */
3281 if (work_queue_item_count(wq)) {
3282 struct work_queue_item *item = work_queue_last_item(wq);
3283 pqnode = item->data;
3284
3285 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3286 || pqnode->bgp != bgp
3287 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3288 pqnode = bgp_processq_alloc(bgp);
3289 else
3290 pqnode_reuse = 1;
3291 } else
3292 pqnode = bgp_processq_alloc(bgp);
3293 /* all unlocked in bgp_process_wq */
3294 bgp_table_lock(bgp_dest_table(dest));
3295
3296 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3297 bgp_dest_lock_node(dest);
3298
3299 /* can't be enqueued twice */
3300 assert(STAILQ_NEXT(dest, pq) == NULL);
3301 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3302 pqnode->queued++;
3303
3304 if (!pqnode_reuse)
3305 work_queue_add(wq, pqnode);
3306
3307 return;
3308 }
3309
3310 void bgp_add_eoiu_mark(struct bgp *bgp)
3311 {
3312 struct bgp_process_queue *pqnode;
3313
3314 if (bgp->process_queue == NULL)
3315 return;
3316
3317 pqnode = bgp_processq_alloc(bgp);
3318
3319 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3320 work_queue_add(bgp->process_queue, pqnode);
3321 }
3322
3323 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
3324 {
3325 struct peer *peer;
3326
3327 peer = THREAD_ARG(thread);
3328 peer->t_pmax_restart = NULL;
3329
3330 if (bgp_debug_neighbor_events(peer))
3331 zlog_debug(
3332 "%s Maximum-prefix restart timer expired, restore peering",
3333 peer->host);
3334
3335 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3336 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3337
3338 return 0;
3339 }
3340
3341 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3342 safi_t safi)
3343 {
3344 uint32_t count = 0;
3345 bool filtered = false;
3346 struct bgp_dest *dest;
3347 struct bgp_adj_in *ain;
3348 struct attr attr = {};
3349 struct bgp_table *table = peer->bgp->rib[afi][safi];
3350
3351 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3352 for (ain = dest->adj_in; ain; ain = ain->next) {
3353 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3354
3355 attr = *ain->attr;
3356
3357 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3358 == FILTER_DENY)
3359 filtered = true;
3360
3361 if (bgp_input_modifier(
3362 peer, rn_p, &attr, afi, safi,
3363 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3364 NULL, 0, NULL)
3365 == RMAP_DENY)
3366 filtered = true;
3367
3368 if (filtered)
3369 count++;
3370
3371 bgp_attr_undup(&attr, ain->attr);
3372 }
3373 }
3374
3375 return count;
3376 }
3377
3378 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3379 int always)
3380 {
3381 iana_afi_t pkt_afi;
3382 iana_safi_t pkt_safi;
3383 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3384 PEER_FLAG_MAX_PREFIX_FORCE))
3385 ? bgp_filtered_routes_count(peer, afi, safi)
3386 + peer->pcount[afi][safi]
3387 : peer->pcount[afi][safi];
3388
3389 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3390 return false;
3391
3392 if (pcount > peer->pmax[afi][safi]) {
3393 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3394 PEER_STATUS_PREFIX_LIMIT)
3395 && !always)
3396 return false;
3397
3398 zlog_info(
3399 "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u",
3400 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3401 peer->pmax[afi][safi]);
3402 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3403
3404 if (CHECK_FLAG(peer->af_flags[afi][safi],
3405 PEER_FLAG_MAX_PREFIX_WARNING))
3406 return false;
3407
3408 /* Convert AFI, SAFI to values for packet. */
3409 pkt_afi = afi_int2iana(afi);
3410 pkt_safi = safi_int2iana(safi);
3411 {
3412 uint8_t ndata[7];
3413
3414 ndata[0] = (pkt_afi >> 8);
3415 ndata[1] = pkt_afi;
3416 ndata[2] = pkt_safi;
3417 ndata[3] = (peer->pmax[afi][safi] >> 24);
3418 ndata[4] = (peer->pmax[afi][safi] >> 16);
3419 ndata[5] = (peer->pmax[afi][safi] >> 8);
3420 ndata[6] = (peer->pmax[afi][safi]);
3421
3422 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3423 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3424 BGP_NOTIFY_CEASE_MAX_PREFIX,
3425 ndata, 7);
3426 }
3427
3428 /* Dynamic peers will just close their connection. */
3429 if (peer_dynamic_neighbor(peer))
3430 return true;
3431
3432 /* restart timer start */
3433 if (peer->pmax_restart[afi][safi]) {
3434 peer->v_pmax_restart =
3435 peer->pmax_restart[afi][safi] * 60;
3436
3437 if (bgp_debug_neighbor_events(peer))
3438 zlog_debug(
3439 "%s Maximum-prefix restart timer started for %d secs",
3440 peer->host, peer->v_pmax_restart);
3441
3442 BGP_TIMER_ON(peer->t_pmax_restart,
3443 bgp_maximum_prefix_restart_timer,
3444 peer->v_pmax_restart);
3445 }
3446
3447 return true;
3448 } else
3449 UNSET_FLAG(peer->af_sflags[afi][safi],
3450 PEER_STATUS_PREFIX_LIMIT);
3451
3452 if (pcount
3453 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3454 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3455 PEER_STATUS_PREFIX_THRESHOLD)
3456 && !always)
3457 return false;
3458
3459 zlog_info(
3460 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3461 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3462 peer->pmax[afi][safi]);
3463 SET_FLAG(peer->af_sflags[afi][safi],
3464 PEER_STATUS_PREFIX_THRESHOLD);
3465 } else
3466 UNSET_FLAG(peer->af_sflags[afi][safi],
3467 PEER_STATUS_PREFIX_THRESHOLD);
3468 return false;
3469 }
3470
3471 /* Unconditionally remove the route from the RIB, without taking
3472 * damping into consideration (eg, because the session went down)
3473 */
3474 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3475 struct peer *peer, afi_t afi, safi_t safi)
3476 {
3477
3478 struct bgp *bgp = NULL;
3479 bool delete_route = false;
3480
3481 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3482 safi);
3483
3484 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3485 bgp_path_info_delete(dest, pi); /* keep historical info */
3486
3487 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3488 * flag
3489 */
3490 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3491 delete_route = true;
3492 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3493 delete_route = true;
3494 if (delete_route) {
3495 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3496 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3497 bgp = pi->peer->bgp;
3498 bgp->gr_info[afi][safi].gr_deferred--;
3499 }
3500 }
3501 }
3502
3503 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3504 bgp_process(peer->bgp, dest, afi, safi);
3505 }
3506
3507 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3508 struct peer *peer, afi_t afi, safi_t safi,
3509 struct prefix_rd *prd)
3510 {
3511 const struct prefix *p = bgp_dest_get_prefix(dest);
3512
3513 /* apply dampening, if result is suppressed, we'll be retaining
3514 * the bgp_path_info in the RIB for historical reference.
3515 */
3516 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3517 && peer->sort == BGP_PEER_EBGP)
3518 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3519 == BGP_DAMP_SUPPRESSED) {
3520 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3521 safi);
3522 return;
3523 }
3524
3525 #ifdef ENABLE_BGP_VNC
3526 if (safi == SAFI_MPLS_VPN) {
3527 struct bgp_dest *pdest = NULL;
3528 struct bgp_table *table = NULL;
3529
3530 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3531 (struct prefix *)prd);
3532 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3533 table = bgp_dest_get_bgp_table_info(pdest);
3534
3535 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3536 peer->bgp, prd, table, p, pi);
3537 }
3538 bgp_dest_unlock_node(pdest);
3539 }
3540 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3541 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3542
3543 vnc_import_bgp_del_route(peer->bgp, p, pi);
3544 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3545 }
3546 }
3547 #endif
3548
3549 /* If this is an EVPN route, process for un-import. */
3550 if (safi == SAFI_EVPN)
3551 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3552
3553 bgp_rib_remove(dest, pi, peer, afi, safi);
3554 }
3555
3556 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3557 struct peer *peer, struct attr *attr,
3558 struct bgp_dest *dest)
3559 {
3560 struct bgp_path_info *new;
3561
3562 /* Make new BGP info. */
3563 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3564 new->type = type;
3565 new->instance = instance;
3566 new->sub_type = sub_type;
3567 new->peer = peer;
3568 new->attr = attr;
3569 new->uptime = bgp_clock();
3570 new->net = dest;
3571 return new;
3572 }
3573
3574 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3575 union gw_addr *gw_ip)
3576 {
3577 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(path->attr);
3578 union gw_addr path_gw_ip, *path_gw_ip_remote;
3579 union {
3580 esi_t esi;
3581 union gw_addr ip;
3582 } temp;
3583
3584 if (afi != AFI_L2VPN)
3585 return true;
3586
3587 path_gw_ip = eo->gw_ip;
3588
3589 if (gw_ip == NULL) {
3590 memset(&temp, 0, sizeof(temp));
3591 path_gw_ip_remote = &temp.ip;
3592 } else
3593 path_gw_ip_remote = gw_ip;
3594
3595 return !!memcmp(&path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
3596 }
3597
3598 /* Check if received nexthop is valid or not. */
3599 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3600 uint8_t type, uint8_t stype, struct attr *attr,
3601 struct bgp_dest *dest)
3602 {
3603 bool ret = false;
3604 bool is_bgp_static_route =
3605 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3606 : false;
3607
3608 /*
3609 * Only validated for unicast and multicast currently.
3610 * Also valid for EVPN where the nexthop is an IP address.
3611 * If we are a bgp static route being checked then there is
3612 * no need to check to see if the nexthop is martian as
3613 * that it should be ok.
3614 */
3615 if (is_bgp_static_route ||
3616 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3617 return false;
3618
3619 /* If NEXT_HOP is present, validate it. */
3620 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3621 if (attr->nexthop.s_addr == INADDR_ANY
3622 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3623 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3624 return true;
3625 }
3626
3627 /* If MP_NEXTHOP is present, validate it. */
3628 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3629 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3630 * it is not an IPv6 link-local address.
3631 *
3632 * If we receive an UPDATE with nexthop length set to 32 bytes
3633 * we shouldn't discard an UPDATE if it's set to (::).
3634 * The link-local (2st) is validated along the code path later.
3635 */
3636 if (attr->mp_nexthop_len) {
3637 switch (attr->mp_nexthop_len) {
3638 case BGP_ATTR_NHLEN_IPV4:
3639 case BGP_ATTR_NHLEN_VPNV4:
3640 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3641 || IPV4_CLASS_DE(
3642 ntohl(attr->mp_nexthop_global_in.s_addr))
3643 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3644 dest));
3645 break;
3646
3647 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3648 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3649 ret = (IN6_IS_ADDR_UNSPECIFIED(
3650 &attr->mp_nexthop_global)
3651 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3652 || IN6_IS_ADDR_MULTICAST(
3653 &attr->mp_nexthop_global)
3654 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3655 dest));
3656 break;
3657 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3658 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3659 || IN6_IS_ADDR_MULTICAST(
3660 &attr->mp_nexthop_global)
3661 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3662 dest));
3663 break;
3664
3665 default:
3666 ret = true;
3667 break;
3668 }
3669 }
3670
3671 return ret;
3672 }
3673
3674 static void bgp_attr_add_no_export_community(struct attr *attr)
3675 {
3676 struct community *old;
3677 struct community *new;
3678 struct community *merge;
3679 struct community *no_export;
3680
3681 old = attr->community;
3682 no_export = community_str2com("no-export");
3683
3684 assert(no_export);
3685
3686 if (old) {
3687 merge = community_merge(community_dup(old), no_export);
3688
3689 if (!old->refcnt)
3690 community_free(&old);
3691
3692 new = community_uniq_sort(merge);
3693 community_free(&merge);
3694 } else {
3695 new = community_dup(no_export);
3696 }
3697
3698 community_free(&no_export);
3699
3700 attr->community = new;
3701 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
3702 }
3703
3704 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3705 struct attr *attr, afi_t afi, safi_t safi, int type,
3706 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3707 uint32_t num_labels, int soft_reconfig,
3708 struct bgp_route_evpn *evpn)
3709 {
3710 int ret;
3711 int aspath_loop_count = 0;
3712 struct bgp_dest *dest;
3713 struct bgp *bgp;
3714 struct attr new_attr;
3715 struct attr *attr_new;
3716 struct bgp_path_info *pi;
3717 struct bgp_path_info *new;
3718 struct bgp_path_info_extra *extra;
3719 const char *reason;
3720 char pfx_buf[BGP_PRD_PATH_STRLEN];
3721 int connected = 0;
3722 int do_loop_check = 1;
3723 int has_valid_label = 0;
3724 afi_t nh_afi;
3725 uint8_t pi_type = 0;
3726 uint8_t pi_sub_type = 0;
3727 bool force_evpn_import = false;
3728 safi_t orig_safi = safi;
3729
3730 if (frrtrace_enabled(frr_bgp, process_update)) {
3731 char pfxprint[PREFIX2STR_BUFFER];
3732
3733 prefix2str(p, pfxprint, sizeof(pfxprint));
3734 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3735 afi, safi, attr);
3736 }
3737
3738 #ifdef ENABLE_BGP_VNC
3739 int vnc_implicit_withdraw = 0;
3740 #endif
3741 int same_attr = 0;
3742
3743 /* Special case for BGP-LU - map LU safi to ordinary unicast safi */
3744 if (orig_safi == SAFI_LABELED_UNICAST)
3745 safi = SAFI_UNICAST;
3746
3747 memset(&new_attr, 0, sizeof(struct attr));
3748 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3749 new_attr.label = MPLS_INVALID_LABEL;
3750
3751 bgp = peer->bgp;
3752 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3753 /* TODO: Check to see if we can get rid of "is_valid_label" */
3754 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3755 has_valid_label = (num_labels > 0) ? 1 : 0;
3756 else
3757 has_valid_label = bgp_is_valid_label(label);
3758
3759 if (has_valid_label)
3760 assert(label != NULL);
3761
3762 /* Update overlay index of the attribute */
3763 if (afi == AFI_L2VPN && evpn)
3764 memcpy(&attr->evpn_overlay, evpn,
3765 sizeof(struct bgp_route_evpn));
3766
3767 /* When peer's soft reconfiguration enabled. Record input packet in
3768 Adj-RIBs-In. */
3769 if (!soft_reconfig
3770 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3771 && peer != bgp->peer_self)
3772 bgp_adj_in_set(dest, peer, attr, addpath_id);
3773
3774 /* Check previously received route. */
3775 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3776 if (pi->peer == peer && pi->type == type
3777 && pi->sub_type == sub_type
3778 && pi->addpath_rx_id == addpath_id)
3779 break;
3780
3781 /* AS path local-as loop check. */
3782 if (peer->change_local_as) {
3783 if (peer->allowas_in[afi][safi])
3784 aspath_loop_count = peer->allowas_in[afi][safi];
3785 else if (!CHECK_FLAG(peer->flags,
3786 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3787 aspath_loop_count = 1;
3788
3789 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3790 > aspath_loop_count) {
3791 peer->stat_pfx_aspath_loop++;
3792 reason = "as-path contains our own AS;";
3793 goto filtered;
3794 }
3795 }
3796
3797 /* If the peer is configured for "allowas-in origin" and the last ASN in
3798 * the
3799 * as-path is our ASN then we do not need to call aspath_loop_check
3800 */
3801 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3802 if (aspath_get_last_as(attr->aspath) == bgp->as)
3803 do_loop_check = 0;
3804
3805 /* AS path loop check. */
3806 if (do_loop_check) {
3807 if (aspath_loop_check(attr->aspath, bgp->as)
3808 > peer->allowas_in[afi][safi]
3809 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3810 && aspath_loop_check(attr->aspath, bgp->confed_id)
3811 > peer->allowas_in[afi][safi])) {
3812 peer->stat_pfx_aspath_loop++;
3813 reason = "as-path contains our own AS;";
3814 goto filtered;
3815 }
3816 }
3817
3818 /* Route reflector originator ID check. */
3819 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3820 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3821 peer->stat_pfx_originator_loop++;
3822 reason = "originator is us;";
3823 goto filtered;
3824 }
3825
3826 /* Route reflector cluster ID check. */
3827 if (bgp_cluster_filter(peer, attr)) {
3828 peer->stat_pfx_cluster_loop++;
3829 reason = "reflected from the same cluster;";
3830 goto filtered;
3831 }
3832
3833 /* Apply incoming filter. */
3834 if (bgp_input_filter(peer, p, attr, afi, orig_safi) == FILTER_DENY) {
3835 peer->stat_pfx_filter++;
3836 reason = "filter;";
3837 goto filtered;
3838 }
3839
3840 /* RFC 8212 to prevent route leaks.
3841 * This specification intends to improve this situation by requiring the
3842 * explicit configuration of both BGP Import and Export Policies for any
3843 * External BGP (EBGP) session such as customers, peers, or
3844 * confederation boundaries for all enabled address families. Through
3845 * codification of the aforementioned requirement, operators will
3846 * benefit from consistent behavior across different BGP
3847 * implementations.
3848 */
3849 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3850 if (!bgp_inbound_policy_exists(peer,
3851 &peer->filter[afi][safi])) {
3852 reason = "inbound policy missing";
3853 goto filtered;
3854 }
3855
3856 /* draft-ietf-idr-deprecate-as-set-confed-set
3857 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3858 * Eventually, This document (if approved) updates RFC 4271
3859 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3860 * and obsoletes RFC 6472.
3861 */
3862 if (peer->bgp->reject_as_sets)
3863 if (aspath_check_as_sets(attr->aspath)) {
3864 reason =
3865 "as-path contains AS_SET or AS_CONFED_SET type;";
3866 goto filtered;
3867 }
3868
3869 new_attr = *attr;
3870
3871 /* Apply incoming route-map.
3872 * NB: new_attr may now contain newly allocated values from route-map
3873 * "set"
3874 * commands, so we need bgp_attr_flush in the error paths, until we
3875 * intern
3876 * the attr (which takes over the memory references) */
3877 if (bgp_input_modifier(peer, p, &new_attr, afi, orig_safi, NULL, label,
3878 num_labels, dest)
3879 == RMAP_DENY) {
3880 peer->stat_pfx_filter++;
3881 reason = "route-map;";
3882 bgp_attr_flush(&new_attr);
3883 goto filtered;
3884 }
3885
3886 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3887 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3888 /* remove from RIB previous entry */
3889 bgp_zebra_withdraw(p, pi, bgp, safi);
3890 }
3891
3892 if (peer->sort == BGP_PEER_EBGP) {
3893
3894 /* rfc7999:
3895 * A BGP speaker receiving an announcement tagged with the
3896 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
3897 * NO_EXPORT community as defined in RFC1997, or a
3898 * similar community, to prevent propagation of the
3899 * prefix outside the local AS. The community to prevent
3900 * propagation SHOULD be chosen according to the operator's
3901 * routing policy.
3902 */
3903 if (new_attr.community
3904 && community_include(new_attr.community,
3905 COMMUNITY_BLACKHOLE))
3906 bgp_attr_add_no_export_community(&new_attr);
3907
3908 /* If we receive the graceful-shutdown community from an eBGP
3909 * peer we must lower local-preference */
3910 if (new_attr.community
3911 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3912 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3913 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3914
3915 /* If graceful-shutdown is configured then add the GSHUT
3916 * community to all paths received from eBGP peers */
3917 } else if (bgp_in_graceful_shutdown(peer->bgp))
3918 bgp_attr_add_gshut_community(&new_attr);
3919 }
3920
3921 if (pi) {
3922 pi_type = pi->type;
3923 pi_sub_type = pi->sub_type;
3924 }
3925
3926 /* next hop check. */
3927 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3928 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3929 &new_attr, dest)) {
3930 peer->stat_pfx_nh_invalid++;
3931 reason = "martian or self next-hop;";
3932 bgp_attr_flush(&new_attr);
3933 goto filtered;
3934 }
3935
3936 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3937 peer->stat_pfx_nh_invalid++;
3938 reason = "self mac;";
3939 goto filtered;
3940 }
3941
3942 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
3943 * condition :
3944 * Suppress fib is enabled
3945 * BGP_OPT_NO_FIB is not enabled
3946 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
3947 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
3948 */
3949 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
3950 && (sub_type == BGP_ROUTE_NORMAL)
3951 && (!bgp_option_check(BGP_OPT_NO_FIB))
3952 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
3953 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
3954
3955 attr_new = bgp_attr_intern(&new_attr);
3956
3957 /* If maximum prefix count is configured and current prefix
3958 * count exeed it.
3959 */
3960 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3961 return -1;
3962
3963 /* If the update is implicit withdraw. */
3964 if (pi) {
3965 pi->uptime = bgp_clock();
3966 same_attr = attrhash_cmp(pi->attr, attr_new);
3967
3968 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3969
3970 /* Same attribute comes in. */
3971 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3972 && same_attr
3973 && (!has_valid_label
3974 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3975 num_labels * sizeof(mpls_label_t))
3976 == 0)) {
3977 if (CHECK_FLAG(bgp->af_flags[afi][safi],
3978 BGP_CONFIG_DAMPENING)
3979 && peer->sort == BGP_PEER_EBGP
3980 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3981 if (bgp_debug_update(peer, p, NULL, 1)) {
3982 bgp_debug_rdpfxpath2str(
3983 afi, safi, prd, p, label,
3984 num_labels, addpath_id ? 1 : 0,
3985 addpath_id, evpn, pfx_buf,
3986 sizeof(pfx_buf));
3987 zlog_debug("%s rcvd %s", peer->host,
3988 pfx_buf);
3989 }
3990
3991 if (bgp_damp_update(pi, dest, afi, safi)
3992 != BGP_DAMP_SUPPRESSED) {
3993 bgp_aggregate_increment(bgp, p, pi, afi,
3994 safi);
3995 bgp_process(bgp, dest, afi, safi);
3996 }
3997 } else /* Duplicate - odd */
3998 {
3999 if (bgp_debug_update(peer, p, NULL, 1)) {
4000 if (!peer->rcvd_attr_printed) {
4001 zlog_debug(
4002 "%s rcvd UPDATE w/ attr: %s",
4003 peer->host,
4004 peer->rcvd_attr_str);
4005 peer->rcvd_attr_printed = 1;
4006 }
4007
4008 bgp_debug_rdpfxpath2str(
4009 afi, safi, prd, p, label,
4010 num_labels, addpath_id ? 1 : 0,
4011 addpath_id, evpn, pfx_buf,
4012 sizeof(pfx_buf));
4013 zlog_debug(
4014 "%s rcvd %s...duplicate ignored",
4015 peer->host, pfx_buf);
4016 }
4017
4018 /* graceful restart STALE flag unset. */
4019 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4020 bgp_path_info_unset_flag(
4021 dest, pi, BGP_PATH_STALE);
4022 bgp_dest_set_defer_flag(dest, false);
4023 bgp_process(bgp, dest, afi, safi);
4024 }
4025 }
4026
4027 bgp_dest_unlock_node(dest);
4028 bgp_attr_unintern(&attr_new);
4029
4030 return 0;
4031 }
4032
4033 /* Withdraw/Announce before we fully processed the withdraw */
4034 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
4035 if (bgp_debug_update(peer, p, NULL, 1)) {
4036 bgp_debug_rdpfxpath2str(
4037 afi, safi, prd, p, label, num_labels,
4038 addpath_id ? 1 : 0, addpath_id, evpn,
4039 pfx_buf, sizeof(pfx_buf));
4040 zlog_debug(
4041 "%s rcvd %s, flapped quicker than processing",
4042 peer->host, pfx_buf);
4043 }
4044
4045 bgp_path_info_restore(dest, pi);
4046
4047 /*
4048 * If the BGP_PATH_REMOVED flag is set, then EVPN
4049 * routes would have been unimported already when a
4050 * prior BGP withdraw processing happened. Such routes
4051 * need to be imported again, so flag accordingly.
4052 */
4053 force_evpn_import = true;
4054 }
4055
4056 /* Received Logging. */
4057 if (bgp_debug_update(peer, p, NULL, 1)) {
4058 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
4059 num_labels, addpath_id ? 1 : 0,
4060 addpath_id, evpn, pfx_buf,
4061 sizeof(pfx_buf));
4062 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
4063 }
4064
4065 /* graceful restart STALE flag unset. */
4066 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
4067 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
4068 bgp_dest_set_defer_flag(dest, false);
4069 }
4070
4071 /* The attribute is changed. */
4072 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
4073
4074 /* implicit withdraw, decrement aggregate and pcount here.
4075 * only if update is accepted, they'll increment below.
4076 */
4077 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
4078
4079 /* Update bgp route dampening information. */
4080 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4081 && peer->sort == BGP_PEER_EBGP) {
4082 /* This is implicit withdraw so we should update
4083 dampening
4084 information. */
4085 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
4086 bgp_damp_withdraw(pi, dest, afi, safi, 1);
4087 }
4088 #ifdef ENABLE_BGP_VNC
4089 if (safi == SAFI_MPLS_VPN) {
4090 struct bgp_dest *pdest = NULL;
4091 struct bgp_table *table = NULL;
4092
4093 pdest = bgp_node_get(bgp->rib[afi][safi],
4094 (struct prefix *)prd);
4095 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4096 table = bgp_dest_get_bgp_table_info(pdest);
4097
4098 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
4099 bgp, prd, table, p, pi);
4100 }
4101 bgp_dest_unlock_node(pdest);
4102 }
4103 if ((afi == AFI_IP || afi == AFI_IP6)
4104 && (safi == SAFI_UNICAST)) {
4105 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
4106 /*
4107 * Implicit withdraw case.
4108 */
4109 ++vnc_implicit_withdraw;
4110 vnc_import_bgp_del_route(bgp, p, pi);
4111 vnc_import_bgp_exterior_del_route(bgp, p, pi);
4112 }
4113 }
4114 #endif
4115
4116 /* Special handling for EVPN update of an existing route. If the
4117 * extended community attribute has changed, we need to
4118 * un-import
4119 * the route using its existing extended community. It will be
4120 * subsequently processed for import with the new extended
4121 * community.
4122 */
4123 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4124 && !same_attr) {
4125 if ((pi->attr->flag
4126 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4127 && (attr_new->flag
4128 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4129 int cmp;
4130
4131 cmp = ecommunity_cmp(pi->attr->ecommunity,
4132 attr_new->ecommunity);
4133 if (!cmp) {
4134 if (bgp_debug_update(peer, p, NULL, 1))
4135 zlog_debug(
4136 "Change in EXT-COMM, existing %s new %s",
4137 ecommunity_str(
4138 pi->attr->ecommunity),
4139 ecommunity_str(
4140 attr_new->ecommunity));
4141 if (safi == SAFI_EVPN)
4142 bgp_evpn_unimport_route(
4143 bgp, afi, safi, p, pi);
4144 else /* SAFI_MPLS_VPN */
4145 vpn_leak_to_vrf_withdraw(bgp,
4146 pi);
4147 }
4148 }
4149 }
4150
4151 /* Update to new attribute. */
4152 bgp_attr_unintern(&pi->attr);
4153 pi->attr = attr_new;
4154
4155 /* Update MPLS label */
4156 if (has_valid_label) {
4157 extra = bgp_path_info_extra_get(pi);
4158 if (extra->label != label) {
4159 memcpy(&extra->label, label,
4160 num_labels * sizeof(mpls_label_t));
4161 extra->num_labels = num_labels;
4162 }
4163 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4164 bgp_set_valid_label(&extra->label[0]);
4165 }
4166
4167 /* Update SRv6 SID */
4168 if (attr->srv6_l3vpn) {
4169 extra = bgp_path_info_extra_get(pi);
4170 if (sid_diff(&extra->sid[0].sid,
4171 &attr->srv6_l3vpn->sid)) {
4172 sid_copy(&extra->sid[0].sid,
4173 &attr->srv6_l3vpn->sid);
4174 extra->num_sids = 1;
4175
4176 extra->sid[0].loc_block_len = 0;
4177 extra->sid[0].loc_node_len = 0;
4178 extra->sid[0].func_len = 0;
4179 extra->sid[0].arg_len = 0;
4180
4181 if (attr->srv6_l3vpn->loc_block_len != 0) {
4182 extra->sid[0].loc_block_len =
4183 attr->srv6_l3vpn->loc_block_len;
4184 extra->sid[0].loc_node_len =
4185 attr->srv6_l3vpn->loc_node_len;
4186 extra->sid[0].func_len =
4187 attr->srv6_l3vpn->func_len;
4188 extra->sid[0].arg_len =
4189 attr->srv6_l3vpn->arg_len;
4190 }
4191
4192 /*
4193 * draft-ietf-bess-srv6-services-07
4194 * The part of SRv6 SID may be encoded as MPLS
4195 * Label for the efficient packing.
4196 */
4197 if (attr->srv6_l3vpn->transposition_len != 0)
4198 transpose_sid(
4199 &extra->sid[0].sid,
4200 decode_label(label),
4201 attr->srv6_l3vpn
4202 ->transposition_offset,
4203 attr->srv6_l3vpn
4204 ->transposition_len);
4205 }
4206 } else if (attr->srv6_vpn) {
4207 extra = bgp_path_info_extra_get(pi);
4208 if (sid_diff(&extra->sid[0].sid,
4209 &attr->srv6_vpn->sid)) {
4210 sid_copy(&extra->sid[0].sid,
4211 &attr->srv6_vpn->sid);
4212 extra->num_sids = 1;
4213 }
4214 }
4215
4216 #ifdef ENABLE_BGP_VNC
4217 if ((afi == AFI_IP || afi == AFI_IP6)
4218 && (safi == SAFI_UNICAST)) {
4219 if (vnc_implicit_withdraw) {
4220 /*
4221 * Add back the route with its new attributes
4222 * (e.g., nexthop).
4223 * The route is still selected, until the route
4224 * selection
4225 * queued by bgp_process actually runs. We have
4226 * to make this
4227 * update to the VNC side immediately to avoid
4228 * racing against
4229 * configuration changes (e.g., route-map
4230 * changes) which
4231 * trigger re-importation of the entire RIB.
4232 */
4233 vnc_import_bgp_add_route(bgp, p, pi);
4234 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4235 }
4236 }
4237 #endif
4238
4239 /* Update bgp route dampening information. */
4240 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4241 && peer->sort == BGP_PEER_EBGP) {
4242 /* Now we do normal update dampening. */
4243 ret = bgp_damp_update(pi, dest, afi, safi);
4244 if (ret == BGP_DAMP_SUPPRESSED) {
4245 bgp_dest_unlock_node(dest);
4246 return 0;
4247 }
4248 }
4249
4250 /* Nexthop reachability check - for unicast and
4251 * labeled-unicast.. */
4252 if (((afi == AFI_IP || afi == AFI_IP6)
4253 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4254 || (safi == SAFI_EVPN &&
4255 bgp_evpn_is_prefix_nht_supported(p))) {
4256 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4257 && peer->ttl == BGP_DEFAULT_TTL
4258 && !CHECK_FLAG(peer->flags,
4259 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4260 && !CHECK_FLAG(bgp->flags,
4261 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4262 connected = 1;
4263 else
4264 connected = 0;
4265
4266 struct bgp *bgp_nexthop = bgp;
4267
4268 if (pi->extra && pi->extra->bgp_orig)
4269 bgp_nexthop = pi->extra->bgp_orig;
4270
4271 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4272
4273 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4274 safi, pi, NULL, connected,
4275 p)
4276 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4277 bgp_path_info_set_flag(dest, pi,
4278 BGP_PATH_VALID);
4279 else {
4280 if (BGP_DEBUG(nht, NHT)) {
4281 zlog_debug("%s(%pI4): NH unresolved",
4282 __func__,
4283 (in_addr_t *)&attr_new->nexthop);
4284 }
4285 bgp_path_info_unset_flag(dest, pi,
4286 BGP_PATH_VALID);
4287 }
4288 } else
4289 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4290
4291 #ifdef ENABLE_BGP_VNC
4292 if (safi == SAFI_MPLS_VPN) {
4293 struct bgp_dest *pdest = NULL;
4294 struct bgp_table *table = NULL;
4295
4296 pdest = bgp_node_get(bgp->rib[afi][safi],
4297 (struct prefix *)prd);
4298 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4299 table = bgp_dest_get_bgp_table_info(pdest);
4300
4301 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4302 bgp, prd, table, p, pi);
4303 }
4304 bgp_dest_unlock_node(pdest);
4305 }
4306 #endif
4307
4308 /* If this is an EVPN route and some attribute has changed,
4309 * or we are explicitly told to perform a route import, process
4310 * route for import. If the extended community has changed, we
4311 * would
4312 * have done the un-import earlier and the import would result
4313 * in the
4314 * route getting injected into appropriate L2 VNIs. If it is
4315 * just
4316 * some other attribute change, the import will result in
4317 * updating
4318 * the attributes for the route in the VNI(s).
4319 */
4320 if (safi == SAFI_EVPN &&
4321 (!same_attr || force_evpn_import) &&
4322 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4323 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4324
4325 /* Process change. */
4326 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4327
4328 bgp_process(bgp, dest, afi, safi);
4329 bgp_dest_unlock_node(dest);
4330
4331 if (SAFI_UNICAST == safi
4332 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4333 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4334
4335 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4336 }
4337 if ((SAFI_MPLS_VPN == safi)
4338 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4339
4340 vpn_leak_to_vrf_update(bgp, pi);
4341 }
4342
4343 #ifdef ENABLE_BGP_VNC
4344 if (SAFI_MPLS_VPN == safi) {
4345 mpls_label_t label_decoded = decode_label(label);
4346
4347 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4348 type, sub_type, &label_decoded);
4349 }
4350 if (SAFI_ENCAP == safi) {
4351 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4352 type, sub_type, NULL);
4353 }
4354 #endif
4355
4356 return 0;
4357 } // End of implicit withdraw
4358
4359 /* Received Logging. */
4360 if (bgp_debug_update(peer, p, NULL, 1)) {
4361 if (!peer->rcvd_attr_printed) {
4362 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4363 peer->rcvd_attr_str);
4364 peer->rcvd_attr_printed = 1;
4365 }
4366
4367 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4368 addpath_id ? 1 : 0, addpath_id, evpn,
4369 pfx_buf, sizeof(pfx_buf));
4370 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
4371 }
4372
4373 /* Make new BGP info. */
4374 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4375
4376 /* Update MPLS label */
4377 if (has_valid_label) {
4378 extra = bgp_path_info_extra_get(new);
4379 if (extra->label != label) {
4380 memcpy(&extra->label, label,
4381 num_labels * sizeof(mpls_label_t));
4382 extra->num_labels = num_labels;
4383 }
4384 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4385 bgp_set_valid_label(&extra->label[0]);
4386 }
4387
4388 /* Update SRv6 SID */
4389 if (safi == SAFI_MPLS_VPN) {
4390 extra = bgp_path_info_extra_get(new);
4391 if (attr->srv6_l3vpn) {
4392 sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid);
4393 extra->num_sids = 1;
4394
4395 extra->sid[0].loc_block_len =
4396 attr->srv6_l3vpn->loc_block_len;
4397 extra->sid[0].loc_node_len =
4398 attr->srv6_l3vpn->loc_node_len;
4399 extra->sid[0].func_len = attr->srv6_l3vpn->func_len;
4400 extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len;
4401
4402 /*
4403 * draft-ietf-bess-srv6-services-07
4404 * The part of SRv6 SID may be encoded as MPLS Label for
4405 * the efficient packing.
4406 */
4407 if (attr->srv6_l3vpn->transposition_len != 0)
4408 transpose_sid(
4409 &extra->sid[0].sid, decode_label(label),
4410 attr->srv6_l3vpn->transposition_offset,
4411 attr->srv6_l3vpn->transposition_len);
4412 } else if (attr->srv6_vpn) {
4413 sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid);
4414 extra->num_sids = 1;
4415 }
4416 }
4417
4418 /* Nexthop reachability check. */
4419 if (((afi == AFI_IP || afi == AFI_IP6)
4420 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4421 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4422 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4423 && peer->ttl == BGP_DEFAULT_TTL
4424 && !CHECK_FLAG(peer->flags,
4425 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4426 && !CHECK_FLAG(bgp->flags,
4427 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4428 connected = 1;
4429 else
4430 connected = 0;
4431
4432 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4433
4434 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4435 connected, p)
4436 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4437 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4438 else {
4439 if (BGP_DEBUG(nht, NHT)) {
4440 char buf1[INET6_ADDRSTRLEN];
4441 inet_ntop(AF_INET,
4442 (const void *)&attr_new->nexthop,
4443 buf1, INET6_ADDRSTRLEN);
4444 zlog_debug("%s(%s): NH unresolved", __func__,
4445 buf1);
4446 }
4447 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4448 }
4449 } else
4450 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4451
4452 /* Addpath ID */
4453 new->addpath_rx_id = addpath_id;
4454
4455 /* Increment prefix */
4456 bgp_aggregate_increment(bgp, p, new, afi, safi);
4457
4458 /* Register new BGP information. */
4459 bgp_path_info_add(dest, new);
4460
4461 /* route_node_get lock */
4462 bgp_dest_unlock_node(dest);
4463
4464 #ifdef ENABLE_BGP_VNC
4465 if (safi == SAFI_MPLS_VPN) {
4466 struct bgp_dest *pdest = NULL;
4467 struct bgp_table *table = NULL;
4468
4469 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4470 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4471 table = bgp_dest_get_bgp_table_info(pdest);
4472
4473 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4474 bgp, prd, table, p, new);
4475 }
4476 bgp_dest_unlock_node(pdest);
4477 }
4478 #endif
4479
4480 /* If this is an EVPN route, process for import. */
4481 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4482 bgp_evpn_import_route(bgp, afi, safi, p, new);
4483
4484 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4485
4486 /* Process change. */
4487 bgp_process(bgp, dest, afi, safi);
4488
4489 if (SAFI_UNICAST == safi
4490 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4491 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4492 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4493 }
4494 if ((SAFI_MPLS_VPN == safi)
4495 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4496
4497 vpn_leak_to_vrf_update(bgp, new);
4498 }
4499 #ifdef ENABLE_BGP_VNC
4500 if (SAFI_MPLS_VPN == safi) {
4501 mpls_label_t label_decoded = decode_label(label);
4502
4503 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4504 sub_type, &label_decoded);
4505 }
4506 if (SAFI_ENCAP == safi) {
4507 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4508 sub_type, NULL);
4509 }
4510 #endif
4511
4512 return 0;
4513
4514 /* This BGP update is filtered. Log the reason then update BGP
4515 entry. */
4516 filtered:
4517 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4518
4519 if (bgp_debug_update(peer, p, NULL, 1)) {
4520 if (!peer->rcvd_attr_printed) {
4521 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4522 peer->rcvd_attr_str);
4523 peer->rcvd_attr_printed = 1;
4524 }
4525
4526 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4527 addpath_id ? 1 : 0, addpath_id, evpn,
4528 pfx_buf, sizeof(pfx_buf));
4529 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4530 peer->host, pfx_buf, reason);
4531 }
4532
4533 if (pi) {
4534 /* If this is an EVPN route, un-import it as it is now filtered.
4535 */
4536 if (safi == SAFI_EVPN)
4537 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4538
4539 if (SAFI_UNICAST == safi
4540 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4541 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4542
4543 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4544 }
4545 if ((SAFI_MPLS_VPN == safi)
4546 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4547
4548 vpn_leak_to_vrf_withdraw(bgp, pi);
4549 }
4550
4551 bgp_rib_remove(dest, pi, peer, afi, safi);
4552 }
4553
4554 bgp_dest_unlock_node(dest);
4555
4556 #ifdef ENABLE_BGP_VNC
4557 /*
4558 * Filtered update is treated as an implicit withdrawal (see
4559 * bgp_rib_remove()
4560 * a few lines above)
4561 */
4562 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4563 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4564 0);
4565 }
4566 #endif
4567
4568 return 0;
4569 }
4570
4571 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4572 struct attr *attr, afi_t afi, safi_t safi, int type,
4573 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4574 uint32_t num_labels, struct bgp_route_evpn *evpn)
4575 {
4576 struct bgp *bgp;
4577 char pfx_buf[BGP_PRD_PATH_STRLEN];
4578 struct bgp_dest *dest;
4579 struct bgp_path_info *pi;
4580
4581 #ifdef ENABLE_BGP_VNC
4582 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4583 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4584 0);
4585 }
4586 #endif
4587
4588 bgp = peer->bgp;
4589
4590 /* Lookup node. */
4591 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4592
4593 /* If peer is soft reconfiguration enabled. Record input packet for
4594 * further calculation.
4595 *
4596 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4597 * routes that are filtered. This tanks out Quagga RS pretty badly due
4598 * to
4599 * the iteration over all RS clients.
4600 * Since we need to remove the entry from adj_in anyway, do that first
4601 * and
4602 * if there was no entry, we don't need to do anything more.
4603 */
4604 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4605 && peer != bgp->peer_self)
4606 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4607 peer->stat_pfx_dup_withdraw++;
4608
4609 if (bgp_debug_update(peer, p, NULL, 1)) {
4610 bgp_debug_rdpfxpath2str(
4611 afi, safi, prd, p, label, num_labels,
4612 addpath_id ? 1 : 0, addpath_id, NULL,
4613 pfx_buf, sizeof(pfx_buf));
4614 zlog_debug(
4615 "%s withdrawing route %s not in adj-in",
4616 peer->host, pfx_buf);
4617 }
4618 bgp_dest_unlock_node(dest);
4619 return 0;
4620 }
4621
4622 /* Lookup withdrawn route. */
4623 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4624 if (pi->peer == peer && pi->type == type
4625 && pi->sub_type == sub_type
4626 && pi->addpath_rx_id == addpath_id)
4627 break;
4628
4629 /* Logging. */
4630 if (bgp_debug_update(peer, p, NULL, 1)) {
4631 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4632 addpath_id ? 1 : 0, addpath_id, NULL,
4633 pfx_buf, sizeof(pfx_buf));
4634 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4635 pfx_buf);
4636 }
4637
4638 /* Withdraw specified route from routing table. */
4639 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4640 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4641 if (SAFI_UNICAST == safi
4642 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4643 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4644 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4645 }
4646 if ((SAFI_MPLS_VPN == safi)
4647 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4648
4649 vpn_leak_to_vrf_withdraw(bgp, pi);
4650 }
4651 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4652 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4653 addpath_id ? 1 : 0, addpath_id, NULL,
4654 pfx_buf, sizeof(pfx_buf));
4655 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4656 }
4657
4658 /* Unlock bgp_node_get() lock. */
4659 bgp_dest_unlock_node(dest);
4660
4661 return 0;
4662 }
4663
4664 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4665 int withdraw)
4666 {
4667 struct update_subgroup *subgrp;
4668 subgrp = peer_subgroup(peer, afi, safi);
4669 subgroup_default_originate(subgrp, withdraw);
4670 }
4671
4672
4673 /*
4674 * bgp_stop_announce_route_timer
4675 */
4676 void bgp_stop_announce_route_timer(struct peer_af *paf)
4677 {
4678 if (!paf->t_announce_route)
4679 return;
4680
4681 thread_cancel(&paf->t_announce_route);
4682 }
4683
4684 /*
4685 * bgp_announce_route_timer_expired
4686 *
4687 * Callback that is invoked when the route announcement timer for a
4688 * peer_af expires.
4689 */
4690 static int bgp_announce_route_timer_expired(struct thread *t)
4691 {
4692 struct peer_af *paf;
4693 struct peer *peer;
4694
4695 paf = THREAD_ARG(t);
4696 peer = paf->peer;
4697
4698 if (!peer_established(peer))
4699 return 0;
4700
4701 if (!peer->afc_nego[paf->afi][paf->safi])
4702 return 0;
4703
4704 peer_af_announce_route(paf, 1);
4705
4706 /* Notify BGP conditional advertisement scanner percess */
4707 peer->advmap_config_change[paf->afi][paf->safi] = true;
4708
4709 return 0;
4710 }
4711
4712 /*
4713 * bgp_announce_route
4714 *
4715 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4716 *
4717 * if force is true we will force an update even if the update
4718 * limiting code is attempted to kick in.
4719 */
4720 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi, bool force)
4721 {
4722 struct peer_af *paf;
4723 struct update_subgroup *subgrp;
4724
4725 paf = peer_af_find(peer, afi, safi);
4726 if (!paf)
4727 return;
4728 subgrp = PAF_SUBGRP(paf);
4729
4730 /*
4731 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4732 * or a refresh has already been triggered.
4733 */
4734 if (!subgrp || paf->t_announce_route)
4735 return;
4736
4737 if (force)
4738 SET_FLAG(subgrp->sflags, SUBGRP_STATUS_FORCE_UPDATES);
4739
4740 /*
4741 * Start a timer to stagger/delay the announce. This serves
4742 * two purposes - announcement can potentially be combined for
4743 * multiple peers and the announcement doesn't happen in the
4744 * vty context.
4745 */
4746 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4747 (subgrp->peer_count == 1)
4748 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4749 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4750 &paf->t_announce_route);
4751 }
4752
4753 /*
4754 * Announce routes from all AF tables to a peer.
4755 *
4756 * This should ONLY be called when there is a need to refresh the
4757 * routes to the peer based on a policy change for this peer alone
4758 * or a route refresh request received from the peer.
4759 * The operation will result in splitting the peer from its existing
4760 * subgroups and putting it in new subgroups.
4761 */
4762 void bgp_announce_route_all(struct peer *peer)
4763 {
4764 afi_t afi;
4765 safi_t safi;
4766
4767 FOREACH_AFI_SAFI (afi, safi)
4768 bgp_announce_route(peer, afi, safi, false);
4769 }
4770
4771 /* Flag or unflag bgp_dest to determine whether it should be treated by
4772 * bgp_soft_reconfig_table_task.
4773 * Flag if flag is true. Unflag if flag is false.
4774 */
4775 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
4776 {
4777 struct bgp_dest *dest;
4778 struct bgp_adj_in *ain;
4779
4780 if (!table)
4781 return;
4782
4783 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4784 for (ain = dest->adj_in; ain; ain = ain->next) {
4785 if (ain->peer != NULL)
4786 break;
4787 }
4788 if (flag && ain != NULL && ain->peer != NULL)
4789 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4790 else
4791 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4792 }
4793 }
4794
4795 static int bgp_soft_reconfig_table_update(struct peer *peer,
4796 struct bgp_dest *dest,
4797 struct bgp_adj_in *ain, afi_t afi,
4798 safi_t safi, struct prefix_rd *prd)
4799 {
4800 struct bgp_path_info *pi;
4801 uint32_t num_labels = 0;
4802 mpls_label_t *label_pnt = NULL;
4803 struct bgp_route_evpn evpn;
4804
4805 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4806 if (pi->peer == peer)
4807 break;
4808
4809 if (pi && pi->extra)
4810 num_labels = pi->extra->num_labels;
4811 if (num_labels)
4812 label_pnt = &pi->extra->label[0];
4813 if (pi)
4814 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
4815 sizeof(evpn));
4816 else
4817 memset(&evpn, 0, sizeof(evpn));
4818
4819 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
4820 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
4821 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
4822 &evpn);
4823 }
4824
4825 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4826 struct bgp_table *table,
4827 struct prefix_rd *prd)
4828 {
4829 int ret;
4830 struct bgp_dest *dest;
4831 struct bgp_adj_in *ain;
4832
4833 if (!table)
4834 table = peer->bgp->rib[afi][safi];
4835
4836 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4837 for (ain = dest->adj_in; ain; ain = ain->next) {
4838 if (ain->peer != peer)
4839 continue;
4840
4841 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
4842 afi, safi, prd);
4843
4844 if (ret < 0) {
4845 bgp_dest_unlock_node(dest);
4846 return;
4847 }
4848 }
4849 }
4850
4851 /* Do soft reconfig table per bgp table.
4852 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
4853 * when BGP_NODE_SOFT_RECONFIG is set,
4854 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
4855 * Schedule a new thread to continue the job.
4856 * Without splitting the full job into several part,
4857 * vtysh waits for the job to finish before responding to a BGP command
4858 */
4859 static int bgp_soft_reconfig_table_task(struct thread *thread)
4860 {
4861 uint32_t iter, max_iter;
4862 int ret;
4863 struct bgp_dest *dest;
4864 struct bgp_adj_in *ain;
4865 struct peer *peer;
4866 struct bgp_table *table;
4867 struct prefix_rd *prd;
4868 struct listnode *node, *nnode;
4869
4870 table = THREAD_ARG(thread);
4871 prd = NULL;
4872
4873 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
4874 if (table->soft_reconfig_init) {
4875 /* first call of the function with a new srta structure.
4876 * Don't do any treatment this time on nodes
4877 * in order vtysh to respond quickly
4878 */
4879 max_iter = 0;
4880 }
4881
4882 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
4883 dest = bgp_route_next(dest)) {
4884 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
4885 continue;
4886
4887 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4888
4889 for (ain = dest->adj_in; ain; ain = ain->next) {
4890 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
4891 nnode, peer)) {
4892 if (ain->peer != peer)
4893 continue;
4894
4895 ret = bgp_soft_reconfig_table_update(
4896 peer, dest, ain, table->afi,
4897 table->safi, prd);
4898 iter++;
4899
4900 if (ret < 0) {
4901 bgp_dest_unlock_node(dest);
4902 listnode_delete(
4903 table->soft_reconfig_peers,
4904 peer);
4905 bgp_announce_route(peer, table->afi,
4906 table->safi, false);
4907 if (list_isempty(
4908 table->soft_reconfig_peers)) {
4909 list_delete(
4910 &table->soft_reconfig_peers);
4911 bgp_soft_reconfig_table_flag(
4912 table, false);
4913 return 0;
4914 }
4915 }
4916 }
4917 }
4918 }
4919
4920 /* we're either starting the initial iteration,
4921 * or we're going to continue an ongoing iteration
4922 */
4923 if (dest || table->soft_reconfig_init) {
4924 table->soft_reconfig_init = false;
4925 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
4926 table, 0, &table->soft_reconfig_thread);
4927 return 0;
4928 }
4929 /* we're done, clean up the background iteration context info and
4930 schedule route annoucement
4931 */
4932 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
4933 listnode_delete(table->soft_reconfig_peers, peer);
4934 bgp_announce_route(peer, table->afi, table->safi, false);
4935 }
4936
4937 list_delete(&table->soft_reconfig_peers);
4938
4939 return 0;
4940 }
4941
4942
4943 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
4944 * and peer.
4945 * - bgp cannot be NULL
4946 * - if table and peer are NULL, cancel all threads within the bgp instance
4947 * - if table is NULL and peer is not,
4948 * remove peer in all threads within the bgp instance
4949 * - if peer is NULL, cancel all threads matching table within the bgp instance
4950 */
4951 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
4952 const struct bgp_table *table,
4953 const struct peer *peer)
4954 {
4955 struct peer *npeer;
4956 struct listnode *node, *nnode;
4957 int afi, safi;
4958 struct bgp_table *ntable;
4959
4960 if (!bgp)
4961 return;
4962
4963 FOREACH_AFI_SAFI (afi, safi) {
4964 ntable = bgp->rib[afi][safi];
4965 if (!ntable)
4966 continue;
4967 if (table && table != ntable)
4968 continue;
4969
4970 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
4971 npeer)) {
4972 if (peer && peer != npeer)
4973 continue;
4974 listnode_delete(ntable->soft_reconfig_peers, npeer);
4975 }
4976
4977 if (!ntable->soft_reconfig_peers
4978 || !list_isempty(ntable->soft_reconfig_peers))
4979 continue;
4980
4981 list_delete(&ntable->soft_reconfig_peers);
4982 bgp_soft_reconfig_table_flag(ntable, false);
4983 BGP_TIMER_OFF(ntable->soft_reconfig_thread);
4984 }
4985 }
4986
4987 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4988 {
4989 struct bgp_dest *dest;
4990 struct bgp_table *table;
4991 struct listnode *node, *nnode;
4992 struct peer *npeer;
4993 struct peer_af *paf;
4994
4995 if (!peer_established(peer))
4996 return;
4997
4998 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4999 && (safi != SAFI_EVPN)) {
5000 table = peer->bgp->rib[afi][safi];
5001 if (!table)
5002 return;
5003
5004 table->soft_reconfig_init = true;
5005
5006 if (!table->soft_reconfig_peers)
5007 table->soft_reconfig_peers = list_new();
5008 npeer = NULL;
5009 /* add peer to the table soft_reconfig_peers if not already
5010 * there
5011 */
5012 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
5013 npeer)) {
5014 if (peer == npeer)
5015 break;
5016 }
5017 if (peer != npeer)
5018 listnode_add(table->soft_reconfig_peers, peer);
5019
5020 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
5021 * on table would start back at the beginning.
5022 */
5023 bgp_soft_reconfig_table_flag(table, true);
5024
5025 if (!table->soft_reconfig_thread)
5026 thread_add_event(bm->master,
5027 bgp_soft_reconfig_table_task, table, 0,
5028 &table->soft_reconfig_thread);
5029 /* Cancel bgp_announce_route_timer_expired threads.
5030 * bgp_announce_route_timer_expired threads have been scheduled
5031 * to announce routes as soon as the soft_reconfigure process
5032 * finishes.
5033 * In this case, soft_reconfigure is also scheduled by using
5034 * a thread but is planned after the
5035 * bgp_announce_route_timer_expired threads. It means that,
5036 * without cancelling the threads, the route announcement task
5037 * would run before the soft reconfiguration one. That would
5038 * useless and would block vtysh during several seconds. Route
5039 * announcements are rescheduled as soon as the soft_reconfigure
5040 * process finishes.
5041 */
5042 paf = peer_af_find(peer, afi, safi);
5043 if (paf)
5044 bgp_stop_announce_route_timer(paf);
5045 } else
5046 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5047 dest = bgp_route_next(dest)) {
5048 table = bgp_dest_get_bgp_table_info(dest);
5049
5050 if (table == NULL)
5051 continue;
5052
5053 const struct prefix *p = bgp_dest_get_prefix(dest);
5054 struct prefix_rd prd;
5055
5056 prd.family = AF_UNSPEC;
5057 prd.prefixlen = 64;
5058 memcpy(&prd.val, p->u.val, 8);
5059
5060 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
5061 }
5062 }
5063
5064
5065 struct bgp_clear_node_queue {
5066 struct bgp_dest *dest;
5067 };
5068
5069 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
5070 {
5071 struct bgp_clear_node_queue *cnq = data;
5072 struct bgp_dest *dest = cnq->dest;
5073 struct peer *peer = wq->spec.data;
5074 struct bgp_path_info *pi;
5075 struct bgp *bgp;
5076 afi_t afi = bgp_dest_table(dest)->afi;
5077 safi_t safi = bgp_dest_table(dest)->safi;
5078
5079 assert(dest && peer);
5080 bgp = peer->bgp;
5081
5082 /* It is possible that we have multiple paths for a prefix from a peer
5083 * if that peer is using AddPath.
5084 */
5085 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
5086 if (pi->peer != peer)
5087 continue;
5088
5089 /* graceful restart STALE flag set. */
5090 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
5091 && peer->nsf[afi][safi])
5092 || CHECK_FLAG(peer->af_sflags[afi][safi],
5093 PEER_STATUS_ENHANCED_REFRESH))
5094 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5095 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
5096 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
5097 else {
5098 /* If this is an EVPN route, process for
5099 * un-import. */
5100 if (safi == SAFI_EVPN)
5101 bgp_evpn_unimport_route(
5102 bgp, afi, safi,
5103 bgp_dest_get_prefix(dest), pi);
5104 /* Handle withdraw for VRF route-leaking and L3VPN */
5105 if (SAFI_UNICAST == safi
5106 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
5107 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5108 vpn_leak_from_vrf_withdraw(bgp_get_default(),
5109 bgp, pi);
5110 }
5111 if (SAFI_MPLS_VPN == safi &&
5112 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5113 vpn_leak_to_vrf_withdraw(bgp, pi);
5114 }
5115
5116 bgp_rib_remove(dest, pi, peer, afi, safi);
5117 }
5118 }
5119 return WQ_SUCCESS;
5120 }
5121
5122 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
5123 {
5124 struct bgp_clear_node_queue *cnq = data;
5125 struct bgp_dest *dest = cnq->dest;
5126 struct bgp_table *table = bgp_dest_table(dest);
5127
5128 bgp_dest_unlock_node(dest);
5129 bgp_table_unlock(table);
5130 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
5131 }
5132
5133 static void bgp_clear_node_complete(struct work_queue *wq)
5134 {
5135 struct peer *peer = wq->spec.data;
5136
5137 /* Tickle FSM to start moving again */
5138 BGP_EVENT_ADD(peer, Clearing_Completed);
5139
5140 peer_unlock(peer); /* bgp_clear_route */
5141 }
5142
5143 static void bgp_clear_node_queue_init(struct peer *peer)
5144 {
5145 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
5146
5147 snprintf(wname, sizeof(wname), "clear %s", peer->host);
5148 #undef CLEAR_QUEUE_NAME_LEN
5149
5150 peer->clear_node_queue = work_queue_new(bm->master, wname);
5151 peer->clear_node_queue->spec.hold = 10;
5152 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
5153 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
5154 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
5155 peer->clear_node_queue->spec.max_retries = 0;
5156
5157 /* we only 'lock' this peer reference when the queue is actually active
5158 */
5159 peer->clear_node_queue->spec.data = peer;
5160 }
5161
5162 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
5163 struct bgp_table *table)
5164 {
5165 struct bgp_dest *dest;
5166 int force = peer->bgp->process_queue ? 0 : 1;
5167
5168 if (!table)
5169 table = peer->bgp->rib[afi][safi];
5170
5171 /* If still no table => afi/safi isn't configured at all or smth. */
5172 if (!table)
5173 return;
5174
5175 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5176 struct bgp_path_info *pi, *next;
5177 struct bgp_adj_in *ain;
5178 struct bgp_adj_in *ain_next;
5179
5180 /* XXX:TODO: This is suboptimal, every non-empty route_node is
5181 * queued for every clearing peer, regardless of whether it is
5182 * relevant to the peer at hand.
5183 *
5184 * Overview: There are 3 different indices which need to be
5185 * scrubbed, potentially, when a peer is removed:
5186 *
5187 * 1 peer's routes visible via the RIB (ie accepted routes)
5188 * 2 peer's routes visible by the (optional) peer's adj-in index
5189 * 3 other routes visible by the peer's adj-out index
5190 *
5191 * 3 there is no hurry in scrubbing, once the struct peer is
5192 * removed from bgp->peer, we could just GC such deleted peer's
5193 * adj-outs at our leisure.
5194 *
5195 * 1 and 2 must be 'scrubbed' in some way, at least made
5196 * invisible via RIB index before peer session is allowed to be
5197 * brought back up. So one needs to know when such a 'search' is
5198 * complete.
5199 *
5200 * Ideally:
5201 *
5202 * - there'd be a single global queue or a single RIB walker
5203 * - rather than tracking which route_nodes still need to be
5204 * examined on a peer basis, we'd track which peers still
5205 * aren't cleared
5206 *
5207 * Given that our per-peer prefix-counts now should be reliable,
5208 * this may actually be achievable. It doesn't seem to be a huge
5209 * problem at this time,
5210 *
5211 * It is possible that we have multiple paths for a prefix from
5212 * a peer
5213 * if that peer is using AddPath.
5214 */
5215 ain = dest->adj_in;
5216 while (ain) {
5217 ain_next = ain->next;
5218
5219 if (ain->peer == peer)
5220 bgp_adj_in_remove(dest, ain);
5221
5222 ain = ain_next;
5223 }
5224
5225 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5226 next = pi->next;
5227 if (pi->peer != peer)
5228 continue;
5229
5230 if (force)
5231 bgp_path_info_reap(dest, pi);
5232 else {
5233 struct bgp_clear_node_queue *cnq;
5234
5235 /* both unlocked in bgp_clear_node_queue_del */
5236 bgp_table_lock(bgp_dest_table(dest));
5237 bgp_dest_lock_node(dest);
5238 cnq = XCALLOC(
5239 MTYPE_BGP_CLEAR_NODE_QUEUE,
5240 sizeof(struct bgp_clear_node_queue));
5241 cnq->dest = dest;
5242 work_queue_add(peer->clear_node_queue, cnq);
5243 break;
5244 }
5245 }
5246 }
5247 return;
5248 }
5249
5250 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5251 {
5252 struct bgp_dest *dest;
5253 struct bgp_table *table;
5254
5255 if (peer->clear_node_queue == NULL)
5256 bgp_clear_node_queue_init(peer);
5257
5258 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5259 * Idle until it receives a Clearing_Completed event. This protects
5260 * against peers which flap faster than we can we clear, which could
5261 * lead to:
5262 *
5263 * a) race with routes from the new session being installed before
5264 * clear_route_node visits the node (to delete the route of that
5265 * peer)
5266 * b) resource exhaustion, clear_route_node likely leads to an entry
5267 * on the process_main queue. Fast-flapping could cause that queue
5268 * to grow and grow.
5269 */
5270
5271 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5272 * the unlock will happen upon work-queue completion; other wise, the
5273 * unlock happens at the end of this function.
5274 */
5275 if (!peer->clear_node_queue->thread)
5276 peer_lock(peer);
5277
5278 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5279 bgp_clear_route_table(peer, afi, safi, NULL);
5280 else
5281 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5282 dest = bgp_route_next(dest)) {
5283 table = bgp_dest_get_bgp_table_info(dest);
5284 if (!table)
5285 continue;
5286
5287 bgp_clear_route_table(peer, afi, safi, table);
5288 }
5289
5290 /* unlock if no nodes got added to the clear-node-queue. */
5291 if (!peer->clear_node_queue->thread)
5292 peer_unlock(peer);
5293 }
5294
5295 void bgp_clear_route_all(struct peer *peer)
5296 {
5297 afi_t afi;
5298 safi_t safi;
5299
5300 FOREACH_AFI_SAFI (afi, safi)
5301 bgp_clear_route(peer, afi, safi);
5302
5303 #ifdef ENABLE_BGP_VNC
5304 rfapiProcessPeerDown(peer);
5305 #endif
5306 }
5307
5308 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5309 {
5310 struct bgp_table *table;
5311 struct bgp_dest *dest;
5312 struct bgp_adj_in *ain;
5313 struct bgp_adj_in *ain_next;
5314
5315 table = peer->bgp->rib[afi][safi];
5316
5317 /* It is possible that we have multiple paths for a prefix from a peer
5318 * if that peer is using AddPath.
5319 */
5320 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5321 ain = dest->adj_in;
5322
5323 while (ain) {
5324 ain_next = ain->next;
5325
5326 if (ain->peer == peer)
5327 bgp_adj_in_remove(dest, ain);
5328
5329 ain = ain_next;
5330 }
5331 }
5332 }
5333
5334 /* If any of the routes from the peer have been marked with the NO_LLGR
5335 * community, either as sent by the peer, or as the result of a configured
5336 * policy, they MUST NOT be retained, but MUST be removed as per the normal
5337 * operation of [RFC4271].
5338 */
5339 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5340 {
5341 struct bgp_dest *dest;
5342 struct bgp_path_info *pi;
5343 struct bgp_table *table;
5344
5345 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5346 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5347 dest = bgp_route_next(dest)) {
5348 struct bgp_dest *rm;
5349
5350 /* look for neighbor in tables */
5351 table = bgp_dest_get_bgp_table_info(dest);
5352 if (!table)
5353 continue;
5354
5355 for (rm = bgp_table_top(table); rm;
5356 rm = bgp_route_next(rm))
5357 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5358 pi = pi->next) {
5359 if (pi->peer != peer)
5360 continue;
5361 if (CHECK_FLAG(
5362 peer->af_sflags[afi][safi],
5363 PEER_STATUS_LLGR_WAIT) &&
5364 pi->attr->community &&
5365 !community_include(
5366 pi->attr->community,
5367 COMMUNITY_NO_LLGR))
5368 break;
5369 if (!CHECK_FLAG(pi->flags,
5370 BGP_PATH_STALE))
5371 break;
5372
5373 /*
5374 * If this is VRF leaked route
5375 * process for withdraw.
5376 */
5377 if (pi->sub_type ==
5378 BGP_ROUTE_IMPORTED &&
5379 peer->bgp->inst_type ==
5380 BGP_INSTANCE_TYPE_DEFAULT)
5381 vpn_leak_to_vrf_withdraw(
5382 peer->bgp, pi);
5383
5384 bgp_rib_remove(rm, pi, peer, afi, safi);
5385 break;
5386 }
5387 }
5388 } else {
5389 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5390 dest = bgp_route_next(dest))
5391 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5392 pi = pi->next) {
5393 if (pi->peer != peer)
5394 continue;
5395 if (CHECK_FLAG(peer->af_sflags[afi][safi],
5396 PEER_STATUS_LLGR_WAIT) &&
5397 pi->attr->community &&
5398 !community_include(pi->attr->community,
5399 COMMUNITY_NO_LLGR))
5400 break;
5401 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5402 break;
5403 if (safi == SAFI_UNICAST &&
5404 (peer->bgp->inst_type ==
5405 BGP_INSTANCE_TYPE_VRF ||
5406 peer->bgp->inst_type ==
5407 BGP_INSTANCE_TYPE_DEFAULT))
5408 vpn_leak_from_vrf_withdraw(
5409 bgp_get_default(), peer->bgp,
5410 pi);
5411
5412 bgp_rib_remove(dest, pi, peer, afi, safi);
5413 break;
5414 }
5415 }
5416 }
5417
5418 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5419 {
5420 struct bgp_dest *dest, *ndest;
5421 struct bgp_path_info *pi;
5422 struct bgp_table *table;
5423
5424 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5425 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5426 dest = bgp_route_next(dest)) {
5427 table = bgp_dest_get_bgp_table_info(dest);
5428 if (!table)
5429 continue;
5430
5431 for (ndest = bgp_table_top(table); ndest;
5432 ndest = bgp_route_next(ndest)) {
5433 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5434 pi = pi->next) {
5435 if (pi->peer != peer)
5436 continue;
5437
5438 if ((CHECK_FLAG(
5439 peer->af_sflags[afi][safi],
5440 PEER_STATUS_ENHANCED_REFRESH))
5441 && !CHECK_FLAG(pi->flags,
5442 BGP_PATH_STALE)
5443 && !CHECK_FLAG(
5444 pi->flags,
5445 BGP_PATH_UNUSEABLE)) {
5446 if (bgp_debug_neighbor_events(
5447 peer))
5448 zlog_debug(
5449 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5450 peer->host,
5451 afi2str(afi),
5452 safi2str(safi),
5453 bgp_dest_get_prefix(
5454 ndest));
5455
5456 bgp_path_info_set_flag(
5457 ndest, pi,
5458 BGP_PATH_STALE);
5459 }
5460 }
5461 }
5462 }
5463 } else {
5464 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5465 dest = bgp_route_next(dest)) {
5466 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5467 pi = pi->next) {
5468 if (pi->peer != peer)
5469 continue;
5470
5471 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5472 PEER_STATUS_ENHANCED_REFRESH))
5473 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5474 && !CHECK_FLAG(pi->flags,
5475 BGP_PATH_UNUSEABLE)) {
5476 if (bgp_debug_neighbor_events(peer))
5477 zlog_debug(
5478 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5479 peer->host,
5480 afi2str(afi),
5481 safi2str(safi),
5482 bgp_dest_get_prefix(
5483 dest));
5484
5485 bgp_path_info_set_flag(dest, pi,
5486 BGP_PATH_STALE);
5487 }
5488 }
5489 }
5490 }
5491 }
5492
5493 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5494 {
5495 if (peer->sort == BGP_PEER_IBGP)
5496 return true;
5497
5498 if (peer->sort == BGP_PEER_EBGP
5499 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5500 || FILTER_LIST_OUT_NAME(filter)
5501 || DISTRIBUTE_OUT_NAME(filter)))
5502 return true;
5503 return false;
5504 }
5505
5506 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5507 {
5508 if (peer->sort == BGP_PEER_IBGP)
5509 return true;
5510
5511 if (peer->sort == BGP_PEER_EBGP
5512 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5513 || FILTER_LIST_IN_NAME(filter)
5514 || DISTRIBUTE_IN_NAME(filter)))
5515 return true;
5516 return false;
5517 }
5518
5519 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5520 safi_t safi)
5521 {
5522 struct bgp_dest *dest;
5523 struct bgp_path_info *pi;
5524 struct bgp_path_info *next;
5525
5526 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5527 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5528 const struct prefix *p = bgp_dest_get_prefix(dest);
5529
5530 next = pi->next;
5531
5532 /* Unimport EVPN routes from VRFs */
5533 if (safi == SAFI_EVPN)
5534 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5535 SAFI_EVPN, p, pi);
5536
5537 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5538 && pi->type == ZEBRA_ROUTE_BGP
5539 && (pi->sub_type == BGP_ROUTE_NORMAL
5540 || pi->sub_type == BGP_ROUTE_AGGREGATE
5541 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5542
5543 if (bgp_fibupd_safi(safi))
5544 bgp_zebra_withdraw(p, pi, bgp, safi);
5545 }
5546
5547 bgp_path_info_reap(dest, pi);
5548 }
5549 }
5550
5551 /* Delete all kernel routes. */
5552 void bgp_cleanup_routes(struct bgp *bgp)
5553 {
5554 afi_t afi;
5555 struct bgp_dest *dest;
5556 struct bgp_table *table;
5557
5558 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5559 if (afi == AFI_L2VPN)
5560 continue;
5561 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5562 SAFI_UNICAST);
5563 /*
5564 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5565 */
5566 if (afi != AFI_L2VPN) {
5567 safi_t safi;
5568 safi = SAFI_MPLS_VPN;
5569 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5570 dest = bgp_route_next(dest)) {
5571 table = bgp_dest_get_bgp_table_info(dest);
5572 if (table != NULL) {
5573 bgp_cleanup_table(bgp, table, safi);
5574 bgp_table_finish(&table);
5575 bgp_dest_set_bgp_table_info(dest, NULL);
5576 bgp_dest_unlock_node(dest);
5577 }
5578 }
5579 safi = SAFI_ENCAP;
5580 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5581 dest = bgp_route_next(dest)) {
5582 table = bgp_dest_get_bgp_table_info(dest);
5583 if (table != NULL) {
5584 bgp_cleanup_table(bgp, table, safi);
5585 bgp_table_finish(&table);
5586 bgp_dest_set_bgp_table_info(dest, NULL);
5587 bgp_dest_unlock_node(dest);
5588 }
5589 }
5590 }
5591 }
5592 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); 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_EVPN);
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 void bgp_reset(void)
5605 {
5606 vty_reset();
5607 bgp_zclient_reset();
5608 access_list_reset();
5609 prefix_list_reset();
5610 }
5611
5612 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5613 {
5614 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5615 && CHECK_FLAG(peer->af_cap[afi][safi],
5616 PEER_CAP_ADDPATH_AF_TX_RCV));
5617 }
5618
5619 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5620 value. */
5621 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5622 struct bgp_nlri *packet)
5623 {
5624 uint8_t *pnt;
5625 uint8_t *lim;
5626 struct prefix p;
5627 int psize;
5628 int ret;
5629 afi_t afi;
5630 safi_t safi;
5631 int addpath_encoded;
5632 uint32_t addpath_id;
5633
5634 pnt = packet->nlri;
5635 lim = pnt + packet->length;
5636 afi = packet->afi;
5637 safi = packet->safi;
5638 addpath_id = 0;
5639 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
5640
5641 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5642 syntactic validity. If the field is syntactically incorrect,
5643 then the Error Subcode is set to Invalid Network Field. */
5644 for (; pnt < lim; pnt += psize) {
5645 /* Clear prefix structure. */
5646 memset(&p, 0, sizeof(struct prefix));
5647
5648 if (addpath_encoded) {
5649
5650 /* When packet overflow occurs return immediately. */
5651 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5652 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5653
5654 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5655 addpath_id = ntohl(addpath_id);
5656 pnt += BGP_ADDPATH_ID_LEN;
5657 }
5658
5659 /* Fetch prefix length. */
5660 p.prefixlen = *pnt++;
5661 /* afi/safi validity already verified by caller,
5662 * bgp_update_receive */
5663 p.family = afi2family(afi);
5664
5665 /* Prefix length check. */
5666 if (p.prefixlen > prefix_blen(&p) * 8) {
5667 flog_err(
5668 EC_BGP_UPDATE_RCV,
5669 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5670 peer->host, p.prefixlen, packet->afi);
5671 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5672 }
5673
5674 /* Packet size overflow check. */
5675 psize = PSIZE(p.prefixlen);
5676
5677 /* When packet overflow occur return immediately. */
5678 if (pnt + psize > lim) {
5679 flog_err(
5680 EC_BGP_UPDATE_RCV,
5681 "%s [Error] Update packet error (prefix length %d overflows packet)",
5682 peer->host, p.prefixlen);
5683 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5684 }
5685
5686 /* Defensive coding, double-check the psize fits in a struct
5687 * prefix */
5688 if (psize > (ssize_t)sizeof(p.u)) {
5689 flog_err(
5690 EC_BGP_UPDATE_RCV,
5691 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5692 peer->host, p.prefixlen, sizeof(p.u));
5693 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5694 }
5695
5696 /* Fetch prefix from NLRI packet. */
5697 memcpy(p.u.val, pnt, psize);
5698
5699 /* Check address. */
5700 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5701 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5702 /* From RFC4271 Section 6.3:
5703 *
5704 * If a prefix in the NLRI field is semantically
5705 * incorrect
5706 * (e.g., an unexpected multicast IP address),
5707 * an error SHOULD
5708 * be logged locally, and the prefix SHOULD be
5709 * ignored.
5710 */
5711 flog_err(
5712 EC_BGP_UPDATE_RCV,
5713 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5714 peer->host, &p.u.prefix4);
5715 continue;
5716 }
5717 }
5718
5719 /* Check address. */
5720 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5721 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5722 flog_err(
5723 EC_BGP_UPDATE_RCV,
5724 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
5725 peer->host, &p.u.prefix6);
5726
5727 continue;
5728 }
5729 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5730 flog_err(
5731 EC_BGP_UPDATE_RCV,
5732 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
5733 peer->host, &p.u.prefix6);
5734
5735 continue;
5736 }
5737 }
5738
5739 /* Normal process. */
5740 if (attr)
5741 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5742 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5743 NULL, NULL, 0, 0, NULL);
5744 else
5745 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5746 safi, ZEBRA_ROUTE_BGP,
5747 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5748 NULL);
5749
5750 /* Do not send BGP notification twice when maximum-prefix count
5751 * overflow. */
5752 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5753 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5754
5755 /* Address family configuration mismatch. */
5756 if (ret < 0)
5757 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5758 }
5759
5760 /* Packet length consistency check. */
5761 if (pnt != lim) {
5762 flog_err(
5763 EC_BGP_UPDATE_RCV,
5764 "%s [Error] Update packet error (prefix length mismatch with total length)",
5765 peer->host);
5766 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5767 }
5768
5769 return BGP_NLRI_PARSE_OK;
5770 }
5771
5772 static struct bgp_static *bgp_static_new(void)
5773 {
5774 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5775 }
5776
5777 static void bgp_static_free(struct bgp_static *bgp_static)
5778 {
5779 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5780 route_map_counter_decrement(bgp_static->rmap.map);
5781
5782 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5783 XFREE(MTYPE_BGP_STATIC, bgp_static);
5784 }
5785
5786 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5787 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5788 {
5789 struct bgp_dest *dest;
5790 struct bgp_path_info *pi;
5791 struct bgp_path_info *new;
5792 struct bgp_path_info rmap_path;
5793 struct attr attr;
5794 struct attr *attr_new;
5795 route_map_result_t ret;
5796 #ifdef ENABLE_BGP_VNC
5797 int vnc_implicit_withdraw = 0;
5798 #endif
5799
5800 assert(bgp_static);
5801
5802 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5803
5804 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5805
5806 attr.nexthop = bgp_static->igpnexthop;
5807 attr.med = bgp_static->igpmetric;
5808 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5809
5810 if (bgp_static->atomic)
5811 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5812
5813 /* Store label index, if required. */
5814 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5815 attr.label_index = bgp_static->label_index;
5816 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5817 }
5818
5819 /* Apply route-map. */
5820 if (bgp_static->rmap.name) {
5821 struct attr attr_tmp = attr;
5822
5823 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5824 rmap_path.peer = bgp->peer_self;
5825 rmap_path.attr = &attr_tmp;
5826
5827 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5828
5829 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5830
5831 bgp->peer_self->rmap_type = 0;
5832
5833 if (ret == RMAP_DENYMATCH) {
5834 /* Free uninterned attribute. */
5835 bgp_attr_flush(&attr_tmp);
5836
5837 /* Unintern original. */
5838 aspath_unintern(&attr.aspath);
5839 bgp_static_withdraw(bgp, p, afi, safi);
5840 return;
5841 }
5842
5843 if (bgp_in_graceful_shutdown(bgp))
5844 bgp_attr_add_gshut_community(&attr_tmp);
5845
5846 attr_new = bgp_attr_intern(&attr_tmp);
5847 } else {
5848
5849 if (bgp_in_graceful_shutdown(bgp))
5850 bgp_attr_add_gshut_community(&attr);
5851
5852 attr_new = bgp_attr_intern(&attr);
5853 }
5854
5855 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5856 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5857 && pi->sub_type == BGP_ROUTE_STATIC)
5858 break;
5859
5860 if (pi) {
5861 if (attrhash_cmp(pi->attr, attr_new)
5862 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5863 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5864 bgp_dest_unlock_node(dest);
5865 bgp_attr_unintern(&attr_new);
5866 aspath_unintern(&attr.aspath);
5867 return;
5868 } else {
5869 /* The attribute is changed. */
5870 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5871
5872 /* Rewrite BGP route information. */
5873 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5874 bgp_path_info_restore(dest, pi);
5875 else
5876 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5877 #ifdef ENABLE_BGP_VNC
5878 if ((afi == AFI_IP || afi == AFI_IP6)
5879 && (safi == SAFI_UNICAST)) {
5880 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5881 /*
5882 * Implicit withdraw case.
5883 * We have to do this before pi is
5884 * changed
5885 */
5886 ++vnc_implicit_withdraw;
5887 vnc_import_bgp_del_route(bgp, p, pi);
5888 vnc_import_bgp_exterior_del_route(
5889 bgp, p, pi);
5890 }
5891 }
5892 #endif
5893 bgp_attr_unintern(&pi->attr);
5894 pi->attr = attr_new;
5895 pi->uptime = bgp_clock();
5896 #ifdef ENABLE_BGP_VNC
5897 if ((afi == AFI_IP || afi == AFI_IP6)
5898 && (safi == SAFI_UNICAST)) {
5899 if (vnc_implicit_withdraw) {
5900 vnc_import_bgp_add_route(bgp, p, pi);
5901 vnc_import_bgp_exterior_add_route(
5902 bgp, p, pi);
5903 }
5904 }
5905 #endif
5906
5907 /* Nexthop reachability check. */
5908 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5909 && (safi == SAFI_UNICAST
5910 || safi == SAFI_LABELED_UNICAST)) {
5911
5912 struct bgp *bgp_nexthop = bgp;
5913
5914 if (pi->extra && pi->extra->bgp_orig)
5915 bgp_nexthop = pi->extra->bgp_orig;
5916
5917 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5918 afi, safi, pi, NULL,
5919 0, p))
5920 bgp_path_info_set_flag(dest, pi,
5921 BGP_PATH_VALID);
5922 else {
5923 if (BGP_DEBUG(nht, NHT)) {
5924 char buf1[INET6_ADDRSTRLEN];
5925 inet_ntop(p->family,
5926 &p->u.prefix, buf1,
5927 INET6_ADDRSTRLEN);
5928 zlog_debug(
5929 "%s(%s): Route not in table, not advertising",
5930 __func__, buf1);
5931 }
5932 bgp_path_info_unset_flag(
5933 dest, pi, BGP_PATH_VALID);
5934 }
5935 } else {
5936 /* Delete the NHT structure if any, if we're
5937 * toggling between
5938 * enabling/disabling import check. We
5939 * deregister the route
5940 * from NHT to avoid overloading NHT and the
5941 * process interaction
5942 */
5943 bgp_unlink_nexthop(pi);
5944 bgp_path_info_set_flag(dest, pi,
5945 BGP_PATH_VALID);
5946 }
5947 /* Process change. */
5948 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5949 bgp_process(bgp, dest, afi, safi);
5950
5951 if (SAFI_UNICAST == safi
5952 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5953 || bgp->inst_type
5954 == BGP_INSTANCE_TYPE_DEFAULT)) {
5955 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5956 pi);
5957 }
5958
5959 bgp_dest_unlock_node(dest);
5960 aspath_unintern(&attr.aspath);
5961 return;
5962 }
5963 }
5964
5965 /* Make new BGP info. */
5966 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5967 attr_new, dest);
5968 /* Nexthop reachability check. */
5969 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5970 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5971 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
5972 p))
5973 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5974 else {
5975 if (BGP_DEBUG(nht, NHT)) {
5976 char buf1[INET6_ADDRSTRLEN];
5977 inet_ntop(p->family, &p->u.prefix, buf1,
5978 INET6_ADDRSTRLEN);
5979 zlog_debug(
5980 "%s(%s): Route not in table, not advertising",
5981 __func__, buf1);
5982 }
5983 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5984 }
5985 } else {
5986 /* Delete the NHT structure if any, if we're toggling between
5987 * enabling/disabling import check. We deregister the route
5988 * from NHT to avoid overloading NHT and the process interaction
5989 */
5990 bgp_unlink_nexthop(new);
5991
5992 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5993 }
5994
5995 /* Aggregate address increment. */
5996 bgp_aggregate_increment(bgp, p, new, afi, safi);
5997
5998 /* Register new BGP information. */
5999 bgp_path_info_add(dest, new);
6000
6001 /* route_node_get lock */
6002 bgp_dest_unlock_node(dest);
6003
6004 /* Process change. */
6005 bgp_process(bgp, dest, afi, safi);
6006
6007 if (SAFI_UNICAST == safi
6008 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6009 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6010 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
6011 }
6012
6013 /* Unintern original. */
6014 aspath_unintern(&attr.aspath);
6015 }
6016
6017 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
6018 safi_t safi)
6019 {
6020 struct bgp_dest *dest;
6021 struct bgp_path_info *pi;
6022
6023 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
6024
6025 /* Check selected route and self inserted route. */
6026 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6027 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6028 && pi->sub_type == BGP_ROUTE_STATIC)
6029 break;
6030
6031 /* Withdraw static BGP route from routing table. */
6032 if (pi) {
6033 if (SAFI_UNICAST == safi
6034 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
6035 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
6036 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
6037 }
6038 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6039 bgp_unlink_nexthop(pi);
6040 bgp_path_info_delete(dest, pi);
6041 bgp_process(bgp, dest, afi, safi);
6042 }
6043
6044 /* Unlock bgp_node_lookup. */
6045 bgp_dest_unlock_node(dest);
6046 }
6047
6048 /*
6049 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
6050 */
6051 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
6052 afi_t afi, safi_t safi,
6053 struct prefix_rd *prd)
6054 {
6055 struct bgp_dest *dest;
6056 struct bgp_path_info *pi;
6057
6058 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
6059
6060 /* Check selected route and self inserted route. */
6061 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6062 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6063 && pi->sub_type == BGP_ROUTE_STATIC)
6064 break;
6065
6066 /* Withdraw static BGP route from routing table. */
6067 if (pi) {
6068 #ifdef ENABLE_BGP_VNC
6069 rfapiProcessWithdraw(
6070 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
6071 1); /* Kill, since it is an administrative change */
6072 #endif
6073 if (SAFI_MPLS_VPN == safi
6074 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6075 vpn_leak_to_vrf_withdraw(bgp, pi);
6076 }
6077 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6078 bgp_path_info_delete(dest, pi);
6079 bgp_process(bgp, dest, afi, safi);
6080 }
6081
6082 /* Unlock bgp_node_lookup. */
6083 bgp_dest_unlock_node(dest);
6084 }
6085
6086 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
6087 struct bgp_static *bgp_static, afi_t afi,
6088 safi_t safi)
6089 {
6090 struct bgp_dest *dest;
6091 struct bgp_path_info *new;
6092 struct attr *attr_new;
6093 struct attr attr = {0};
6094 struct bgp_path_info *pi;
6095 #ifdef ENABLE_BGP_VNC
6096 mpls_label_t label = 0;
6097 #endif
6098 uint32_t num_labels = 0;
6099 union gw_addr add;
6100
6101 assert(bgp_static);
6102
6103 if (bgp_static->label != MPLS_INVALID_LABEL)
6104 num_labels = 1;
6105 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
6106 &bgp_static->prd);
6107
6108 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
6109
6110 attr.nexthop = bgp_static->igpnexthop;
6111 attr.med = bgp_static->igpmetric;
6112 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
6113
6114 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
6115 || (safi == SAFI_ENCAP)) {
6116 if (afi == AFI_IP) {
6117 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
6118 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
6119 }
6120 }
6121 if (afi == AFI_L2VPN) {
6122 if (bgp_static->gatewayIp.family == AF_INET)
6123 add.ipv4.s_addr =
6124 bgp_static->gatewayIp.u.prefix4.s_addr;
6125 else if (bgp_static->gatewayIp.family == AF_INET6)
6126 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
6127 sizeof(struct in6_addr));
6128 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
6129 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
6130 struct bgp_encap_type_vxlan bet;
6131 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
6132 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
6133 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
6134 }
6135 if (bgp_static->router_mac) {
6136 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
6137 }
6138 }
6139 /* Apply route-map. */
6140 if (bgp_static->rmap.name) {
6141 struct attr attr_tmp = attr;
6142 struct bgp_path_info rmap_path;
6143 route_map_result_t ret;
6144
6145 rmap_path.peer = bgp->peer_self;
6146 rmap_path.attr = &attr_tmp;
6147
6148 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
6149
6150 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
6151
6152 bgp->peer_self->rmap_type = 0;
6153
6154 if (ret == RMAP_DENYMATCH) {
6155 /* Free uninterned attribute. */
6156 bgp_attr_flush(&attr_tmp);
6157
6158 /* Unintern original. */
6159 aspath_unintern(&attr.aspath);
6160 bgp_static_withdraw_safi(bgp, p, afi, safi,
6161 &bgp_static->prd);
6162 return;
6163 }
6164
6165 attr_new = bgp_attr_intern(&attr_tmp);
6166 } else {
6167 attr_new = bgp_attr_intern(&attr);
6168 }
6169
6170 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6171 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6172 && pi->sub_type == BGP_ROUTE_STATIC)
6173 break;
6174
6175 if (pi) {
6176 memset(&add, 0, sizeof(union gw_addr));
6177 if (attrhash_cmp(pi->attr, attr_new)
6178 && overlay_index_equal(afi, pi, &add)
6179 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
6180 bgp_dest_unlock_node(dest);
6181 bgp_attr_unintern(&attr_new);
6182 aspath_unintern(&attr.aspath);
6183 return;
6184 } else {
6185 /* The attribute is changed. */
6186 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
6187
6188 /* Rewrite BGP route information. */
6189 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
6190 bgp_path_info_restore(dest, pi);
6191 else
6192 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
6193 bgp_attr_unintern(&pi->attr);
6194 pi->attr = attr_new;
6195 pi->uptime = bgp_clock();
6196 #ifdef ENABLE_BGP_VNC
6197 if (pi->extra)
6198 label = decode_label(&pi->extra->label[0]);
6199 #endif
6200
6201 /* Process change. */
6202 bgp_aggregate_increment(bgp, p, pi, afi, safi);
6203 bgp_process(bgp, dest, afi, safi);
6204
6205 if (SAFI_MPLS_VPN == safi
6206 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6207 vpn_leak_to_vrf_update(bgp, pi);
6208 }
6209 #ifdef ENABLE_BGP_VNC
6210 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
6211 pi->attr, afi, safi, pi->type,
6212 pi->sub_type, &label);
6213 #endif
6214 bgp_dest_unlock_node(dest);
6215 aspath_unintern(&attr.aspath);
6216 return;
6217 }
6218 }
6219
6220
6221 /* Make new BGP info. */
6222 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6223 attr_new, dest);
6224 SET_FLAG(new->flags, BGP_PATH_VALID);
6225 new->extra = bgp_path_info_extra_new();
6226 if (num_labels) {
6227 new->extra->label[0] = bgp_static->label;
6228 new->extra->num_labels = num_labels;
6229 }
6230 #ifdef ENABLE_BGP_VNC
6231 label = decode_label(&bgp_static->label);
6232 #endif
6233
6234 /* Aggregate address increment. */
6235 bgp_aggregate_increment(bgp, p, new, afi, safi);
6236
6237 /* Register new BGP information. */
6238 bgp_path_info_add(dest, new);
6239 /* route_node_get lock */
6240 bgp_dest_unlock_node(dest);
6241
6242 /* Process change. */
6243 bgp_process(bgp, dest, afi, safi);
6244
6245 if (SAFI_MPLS_VPN == safi
6246 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6247 vpn_leak_to_vrf_update(bgp, new);
6248 }
6249 #ifdef ENABLE_BGP_VNC
6250 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6251 safi, new->type, new->sub_type, &label);
6252 #endif
6253
6254 /* Unintern original. */
6255 aspath_unintern(&attr.aspath);
6256 }
6257
6258 /* Configure static BGP network. When user don't run zebra, static
6259 route should be installed as valid. */
6260 static int bgp_static_set(struct vty *vty, const char *negate,
6261 const char *ip_str, afi_t afi, safi_t safi,
6262 const char *rmap, int backdoor, uint32_t label_index)
6263 {
6264 VTY_DECLVAR_CONTEXT(bgp, bgp);
6265 int ret;
6266 struct prefix p;
6267 struct bgp_static *bgp_static;
6268 struct bgp_dest *dest;
6269 uint8_t need_update = 0;
6270
6271 /* Convert IP prefix string to struct prefix. */
6272 ret = str2prefix(ip_str, &p);
6273 if (!ret) {
6274 vty_out(vty, "%% Malformed prefix\n");
6275 return CMD_WARNING_CONFIG_FAILED;
6276 }
6277 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6278 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6279 return CMD_WARNING_CONFIG_FAILED;
6280 }
6281
6282 apply_mask(&p);
6283
6284 if (negate) {
6285
6286 /* Set BGP static route configuration. */
6287 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6288
6289 if (!dest) {
6290 vty_out(vty, "%% Can't find static route specified\n");
6291 return CMD_WARNING_CONFIG_FAILED;
6292 }
6293
6294 bgp_static = bgp_dest_get_bgp_static_info(dest);
6295
6296 if ((label_index != BGP_INVALID_LABEL_INDEX)
6297 && (label_index != bgp_static->label_index)) {
6298 vty_out(vty,
6299 "%% label-index doesn't match static route\n");
6300 bgp_dest_unlock_node(dest);
6301 return CMD_WARNING_CONFIG_FAILED;
6302 }
6303
6304 if ((rmap && bgp_static->rmap.name)
6305 && strcmp(rmap, bgp_static->rmap.name)) {
6306 vty_out(vty,
6307 "%% route-map name doesn't match static route\n");
6308 bgp_dest_unlock_node(dest);
6309 return CMD_WARNING_CONFIG_FAILED;
6310 }
6311
6312 /* Update BGP RIB. */
6313 if (!bgp_static->backdoor)
6314 bgp_static_withdraw(bgp, &p, afi, safi);
6315
6316 /* Clear configuration. */
6317 bgp_static_free(bgp_static);
6318 bgp_dest_set_bgp_static_info(dest, NULL);
6319 bgp_dest_unlock_node(dest);
6320 bgp_dest_unlock_node(dest);
6321 } else {
6322
6323 /* Set BGP static route configuration. */
6324 dest = bgp_node_get(bgp->route[afi][safi], &p);
6325 bgp_static = bgp_dest_get_bgp_static_info(dest);
6326 if (bgp_static) {
6327 /* Configuration change. */
6328 /* Label index cannot be changed. */
6329 if (bgp_static->label_index != label_index) {
6330 vty_out(vty, "%% cannot change label-index\n");
6331 return CMD_WARNING_CONFIG_FAILED;
6332 }
6333
6334 /* Check previous routes are installed into BGP. */
6335 if (bgp_static->valid
6336 && bgp_static->backdoor != backdoor)
6337 need_update = 1;
6338
6339 bgp_static->backdoor = backdoor;
6340
6341 if (rmap) {
6342 XFREE(MTYPE_ROUTE_MAP_NAME,
6343 bgp_static->rmap.name);
6344 route_map_counter_decrement(
6345 bgp_static->rmap.map);
6346 bgp_static->rmap.name =
6347 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6348 bgp_static->rmap.map =
6349 route_map_lookup_by_name(rmap);
6350 route_map_counter_increment(
6351 bgp_static->rmap.map);
6352 } else {
6353 XFREE(MTYPE_ROUTE_MAP_NAME,
6354 bgp_static->rmap.name);
6355 route_map_counter_decrement(
6356 bgp_static->rmap.map);
6357 bgp_static->rmap.map = NULL;
6358 bgp_static->valid = 0;
6359 }
6360 bgp_dest_unlock_node(dest);
6361 } else {
6362 /* New configuration. */
6363 bgp_static = bgp_static_new();
6364 bgp_static->backdoor = backdoor;
6365 bgp_static->valid = 0;
6366 bgp_static->igpmetric = 0;
6367 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6368 bgp_static->label_index = label_index;
6369
6370 if (rmap) {
6371 XFREE(MTYPE_ROUTE_MAP_NAME,
6372 bgp_static->rmap.name);
6373 route_map_counter_decrement(
6374 bgp_static->rmap.map);
6375 bgp_static->rmap.name =
6376 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6377 bgp_static->rmap.map =
6378 route_map_lookup_by_name(rmap);
6379 route_map_counter_increment(
6380 bgp_static->rmap.map);
6381 }
6382 bgp_dest_set_bgp_static_info(dest, bgp_static);
6383 }
6384
6385 bgp_static->valid = 1;
6386 if (need_update)
6387 bgp_static_withdraw(bgp, &p, afi, safi);
6388
6389 if (!bgp_static->backdoor)
6390 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6391 }
6392
6393 return CMD_SUCCESS;
6394 }
6395
6396 void bgp_static_add(struct bgp *bgp)
6397 {
6398 afi_t afi;
6399 safi_t safi;
6400 struct bgp_dest *dest;
6401 struct bgp_dest *rm;
6402 struct bgp_table *table;
6403 struct bgp_static *bgp_static;
6404
6405 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6406 FOREACH_AFI_SAFI (afi, safi)
6407 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6408 dest = bgp_route_next(dest)) {
6409 if (!bgp_dest_has_bgp_path_info_data(dest))
6410 continue;
6411
6412 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6413 || (safi == SAFI_EVPN)) {
6414 table = bgp_dest_get_bgp_table_info(dest);
6415
6416 for (rm = bgp_table_top(table); rm;
6417 rm = bgp_route_next(rm)) {
6418 bgp_static =
6419 bgp_dest_get_bgp_static_info(
6420 rm);
6421 bgp_static_update_safi(
6422 bgp, bgp_dest_get_prefix(rm),
6423 bgp_static, afi, safi);
6424 }
6425 } else {
6426 bgp_static_update(
6427 bgp, bgp_dest_get_prefix(dest),
6428 bgp_dest_get_bgp_static_info(dest), afi,
6429 safi);
6430 }
6431 }
6432 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6433 }
6434
6435 /* Called from bgp_delete(). Delete all static routes from the BGP
6436 instance. */
6437 void bgp_static_delete(struct bgp *bgp)
6438 {
6439 afi_t afi;
6440 safi_t safi;
6441 struct bgp_dest *dest;
6442 struct bgp_dest *rm;
6443 struct bgp_table *table;
6444 struct bgp_static *bgp_static;
6445
6446 FOREACH_AFI_SAFI (afi, safi)
6447 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6448 dest = bgp_route_next(dest)) {
6449 if (!bgp_dest_has_bgp_path_info_data(dest))
6450 continue;
6451
6452 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6453 || (safi == SAFI_EVPN)) {
6454 table = bgp_dest_get_bgp_table_info(dest);
6455
6456 for (rm = bgp_table_top(table); rm;
6457 rm = bgp_route_next(rm)) {
6458 bgp_static =
6459 bgp_dest_get_bgp_static_info(
6460 rm);
6461 if (!bgp_static)
6462 continue;
6463
6464 bgp_static_withdraw_safi(
6465 bgp, bgp_dest_get_prefix(rm),
6466 AFI_IP, safi,
6467 (struct prefix_rd *)
6468 bgp_dest_get_prefix(
6469 dest));
6470 bgp_static_free(bgp_static);
6471 bgp_dest_set_bgp_static_info(rm,
6472 NULL);
6473 bgp_dest_unlock_node(rm);
6474 }
6475 } else {
6476 bgp_static = bgp_dest_get_bgp_static_info(dest);
6477 bgp_static_withdraw(bgp,
6478 bgp_dest_get_prefix(dest),
6479 afi, safi);
6480 bgp_static_free(bgp_static);
6481 bgp_dest_set_bgp_static_info(dest, NULL);
6482 bgp_dest_unlock_node(dest);
6483 }
6484 }
6485 }
6486
6487 void bgp_static_redo_import_check(struct bgp *bgp)
6488 {
6489 afi_t afi;
6490 safi_t safi;
6491 struct bgp_dest *dest;
6492 struct bgp_dest *rm;
6493 struct bgp_table *table;
6494 struct bgp_static *bgp_static;
6495
6496 /* Use this flag to force reprocessing of the route */
6497 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6498 FOREACH_AFI_SAFI (afi, safi) {
6499 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6500 dest = bgp_route_next(dest)) {
6501 if (!bgp_dest_has_bgp_path_info_data(dest))
6502 continue;
6503
6504 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6505 || (safi == SAFI_EVPN)) {
6506 table = bgp_dest_get_bgp_table_info(dest);
6507
6508 for (rm = bgp_table_top(table); rm;
6509 rm = bgp_route_next(rm)) {
6510 bgp_static =
6511 bgp_dest_get_bgp_static_info(
6512 rm);
6513 bgp_static_update_safi(
6514 bgp, bgp_dest_get_prefix(rm),
6515 bgp_static, afi, safi);
6516 }
6517 } else {
6518 bgp_static = bgp_dest_get_bgp_static_info(dest);
6519 bgp_static_update(bgp,
6520 bgp_dest_get_prefix(dest),
6521 bgp_static, afi, safi);
6522 }
6523 }
6524 }
6525 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6526 }
6527
6528 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6529 safi_t safi)
6530 {
6531 struct bgp_table *table;
6532 struct bgp_dest *dest;
6533 struct bgp_path_info *pi;
6534
6535 /* Do not install the aggregate route if BGP is in the
6536 * process of termination.
6537 */
6538 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6539 || (bgp->peer_self == NULL))
6540 return;
6541
6542 table = bgp->rib[afi][safi];
6543 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6544 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6545 if (pi->peer == bgp->peer_self
6546 && ((pi->type == ZEBRA_ROUTE_BGP
6547 && pi->sub_type == BGP_ROUTE_STATIC)
6548 || (pi->type != ZEBRA_ROUTE_BGP
6549 && pi->sub_type
6550 == BGP_ROUTE_REDISTRIBUTE))) {
6551 bgp_aggregate_decrement(
6552 bgp, bgp_dest_get_prefix(dest), pi, afi,
6553 safi);
6554 bgp_unlink_nexthop(pi);
6555 bgp_path_info_delete(dest, pi);
6556 bgp_process(bgp, dest, afi, safi);
6557 }
6558 }
6559 }
6560 }
6561
6562 /*
6563 * Purge all networks and redistributed routes from routing table.
6564 * Invoked upon the instance going down.
6565 */
6566 void bgp_purge_static_redist_routes(struct bgp *bgp)
6567 {
6568 afi_t afi;
6569 safi_t safi;
6570
6571 FOREACH_AFI_SAFI (afi, safi)
6572 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6573 }
6574
6575 /*
6576 * gpz 110624
6577 * Currently this is used to set static routes for VPN and ENCAP.
6578 * I think it can probably be factored with bgp_static_set.
6579 */
6580 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6581 const char *ip_str, const char *rd_str,
6582 const char *label_str, const char *rmap_str,
6583 int evpn_type, const char *esi, const char *gwip,
6584 const char *ethtag, const char *routermac)
6585 {
6586 VTY_DECLVAR_CONTEXT(bgp, bgp);
6587 int ret;
6588 struct prefix p;
6589 struct prefix_rd prd;
6590 struct bgp_dest *pdest;
6591 struct bgp_dest *dest;
6592 struct bgp_table *table;
6593 struct bgp_static *bgp_static;
6594 mpls_label_t label = MPLS_INVALID_LABEL;
6595 struct prefix gw_ip;
6596
6597 /* validate ip prefix */
6598 ret = str2prefix(ip_str, &p);
6599 if (!ret) {
6600 vty_out(vty, "%% Malformed prefix\n");
6601 return CMD_WARNING_CONFIG_FAILED;
6602 }
6603 apply_mask(&p);
6604 if ((afi == AFI_L2VPN)
6605 && (bgp_build_evpn_prefix(evpn_type,
6606 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6607 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6608 return CMD_WARNING_CONFIG_FAILED;
6609 }
6610
6611 ret = str2prefix_rd(rd_str, &prd);
6612 if (!ret) {
6613 vty_out(vty, "%% Malformed rd\n");
6614 return CMD_WARNING_CONFIG_FAILED;
6615 }
6616
6617 if (label_str) {
6618 unsigned long label_val;
6619 label_val = strtoul(label_str, NULL, 10);
6620 encode_label(label_val, &label);
6621 }
6622
6623 if (safi == SAFI_EVPN) {
6624 if (esi && str2esi(esi, NULL) == 0) {
6625 vty_out(vty, "%% Malformed ESI\n");
6626 return CMD_WARNING_CONFIG_FAILED;
6627 }
6628 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6629 vty_out(vty, "%% Malformed Router MAC\n");
6630 return CMD_WARNING_CONFIG_FAILED;
6631 }
6632 if (gwip) {
6633 memset(&gw_ip, 0, sizeof(struct prefix));
6634 ret = str2prefix(gwip, &gw_ip);
6635 if (!ret) {
6636 vty_out(vty, "%% Malformed GatewayIp\n");
6637 return CMD_WARNING_CONFIG_FAILED;
6638 }
6639 if ((gw_ip.family == AF_INET
6640 && is_evpn_prefix_ipaddr_v6(
6641 (struct prefix_evpn *)&p))
6642 || (gw_ip.family == AF_INET6
6643 && is_evpn_prefix_ipaddr_v4(
6644 (struct prefix_evpn *)&p))) {
6645 vty_out(vty,
6646 "%% GatewayIp family differs with IP prefix\n");
6647 return CMD_WARNING_CONFIG_FAILED;
6648 }
6649 }
6650 }
6651 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6652 if (!bgp_dest_has_bgp_path_info_data(pdest))
6653 bgp_dest_set_bgp_table_info(pdest,
6654 bgp_table_init(bgp, afi, safi));
6655 table = bgp_dest_get_bgp_table_info(pdest);
6656
6657 dest = bgp_node_get(table, &p);
6658
6659 if (bgp_dest_has_bgp_path_info_data(dest)) {
6660 vty_out(vty, "%% Same network configuration exists\n");
6661 bgp_dest_unlock_node(dest);
6662 } else {
6663 /* New configuration. */
6664 bgp_static = bgp_static_new();
6665 bgp_static->backdoor = 0;
6666 bgp_static->valid = 0;
6667 bgp_static->igpmetric = 0;
6668 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6669 bgp_static->label = label;
6670 bgp_static->prd = prd;
6671
6672 if (rmap_str) {
6673 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6674 route_map_counter_decrement(bgp_static->rmap.map);
6675 bgp_static->rmap.name =
6676 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6677 bgp_static->rmap.map =
6678 route_map_lookup_by_name(rmap_str);
6679 route_map_counter_increment(bgp_static->rmap.map);
6680 }
6681
6682 if (safi == SAFI_EVPN) {
6683 if (esi) {
6684 bgp_static->eth_s_id =
6685 XCALLOC(MTYPE_ATTR,
6686 sizeof(esi_t));
6687 str2esi(esi, bgp_static->eth_s_id);
6688 }
6689 if (routermac) {
6690 bgp_static->router_mac =
6691 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6692 (void)prefix_str2mac(routermac,
6693 bgp_static->router_mac);
6694 }
6695 if (gwip)
6696 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6697 }
6698 bgp_dest_set_bgp_static_info(dest, bgp_static);
6699
6700 bgp_static->valid = 1;
6701 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6702 }
6703
6704 return CMD_SUCCESS;
6705 }
6706
6707 /* Configure static BGP network. */
6708 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6709 const char *ip_str, const char *rd_str,
6710 const char *label_str, int evpn_type, const char *esi,
6711 const char *gwip, const char *ethtag)
6712 {
6713 VTY_DECLVAR_CONTEXT(bgp, bgp);
6714 int ret;
6715 struct prefix p;
6716 struct prefix_rd prd;
6717 struct bgp_dest *pdest;
6718 struct bgp_dest *dest;
6719 struct bgp_table *table;
6720 struct bgp_static *bgp_static;
6721 mpls_label_t label = MPLS_INVALID_LABEL;
6722
6723 /* Convert IP prefix string to struct prefix. */
6724 ret = str2prefix(ip_str, &p);
6725 if (!ret) {
6726 vty_out(vty, "%% Malformed prefix\n");
6727 return CMD_WARNING_CONFIG_FAILED;
6728 }
6729 apply_mask(&p);
6730 if ((afi == AFI_L2VPN)
6731 && (bgp_build_evpn_prefix(evpn_type,
6732 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6733 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6734 return CMD_WARNING_CONFIG_FAILED;
6735 }
6736 ret = str2prefix_rd(rd_str, &prd);
6737 if (!ret) {
6738 vty_out(vty, "%% Malformed rd\n");
6739 return CMD_WARNING_CONFIG_FAILED;
6740 }
6741
6742 if (label_str) {
6743 unsigned long label_val;
6744 label_val = strtoul(label_str, NULL, 10);
6745 encode_label(label_val, &label);
6746 }
6747
6748 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6749 if (!bgp_dest_has_bgp_path_info_data(pdest))
6750 bgp_dest_set_bgp_table_info(pdest,
6751 bgp_table_init(bgp, afi, safi));
6752 else
6753 bgp_dest_unlock_node(pdest);
6754 table = bgp_dest_get_bgp_table_info(pdest);
6755
6756 dest = bgp_node_lookup(table, &p);
6757
6758 if (dest) {
6759 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6760
6761 bgp_static = bgp_dest_get_bgp_static_info(dest);
6762 bgp_static_free(bgp_static);
6763 bgp_dest_set_bgp_static_info(dest, NULL);
6764 bgp_dest_unlock_node(dest);
6765 bgp_dest_unlock_node(dest);
6766 } else
6767 vty_out(vty, "%% Can't find the route\n");
6768
6769 return CMD_SUCCESS;
6770 }
6771
6772 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6773 const char *rmap_name)
6774 {
6775 VTY_DECLVAR_CONTEXT(bgp, bgp);
6776 struct bgp_rmap *rmap;
6777
6778 rmap = &bgp->table_map[afi][safi];
6779 if (rmap_name) {
6780 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6781 route_map_counter_decrement(rmap->map);
6782 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6783 rmap->map = route_map_lookup_by_name(rmap_name);
6784 route_map_counter_increment(rmap->map);
6785 } else {
6786 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6787 route_map_counter_decrement(rmap->map);
6788 rmap->map = NULL;
6789 }
6790
6791 if (bgp_fibupd_safi(safi))
6792 bgp_zebra_announce_table(bgp, afi, safi);
6793
6794 return CMD_SUCCESS;
6795 }
6796
6797 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6798 const char *rmap_name)
6799 {
6800 VTY_DECLVAR_CONTEXT(bgp, bgp);
6801 struct bgp_rmap *rmap;
6802
6803 rmap = &bgp->table_map[afi][safi];
6804 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6805 route_map_counter_decrement(rmap->map);
6806 rmap->map = NULL;
6807
6808 if (bgp_fibupd_safi(safi))
6809 bgp_zebra_announce_table(bgp, afi, safi);
6810
6811 return CMD_SUCCESS;
6812 }
6813
6814 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6815 safi_t safi)
6816 {
6817 if (bgp->table_map[afi][safi].name) {
6818 vty_out(vty, " table-map %s\n",
6819 bgp->table_map[afi][safi].name);
6820 }
6821 }
6822
6823 DEFUN (bgp_table_map,
6824 bgp_table_map_cmd,
6825 "table-map WORD",
6826 "BGP table to RIB route download filter\n"
6827 "Name of the route map\n")
6828 {
6829 int idx_word = 1;
6830 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6831 argv[idx_word]->arg);
6832 }
6833 DEFUN (no_bgp_table_map,
6834 no_bgp_table_map_cmd,
6835 "no table-map WORD",
6836 NO_STR
6837 "BGP table to RIB route download filter\n"
6838 "Name of the route map\n")
6839 {
6840 int idx_word = 2;
6841 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6842 argv[idx_word]->arg);
6843 }
6844
6845 DEFPY(bgp_network,
6846 bgp_network_cmd,
6847 "[no] network \
6848 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6849 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6850 backdoor$backdoor}]",
6851 NO_STR
6852 "Specify a network to announce via BGP\n"
6853 "IPv4 prefix\n"
6854 "Network number\n"
6855 "Network mask\n"
6856 "Network mask\n"
6857 "Route-map to modify the attributes\n"
6858 "Name of the route map\n"
6859 "Label index to associate with the prefix\n"
6860 "Label index value\n"
6861 "Specify a BGP backdoor route\n")
6862 {
6863 char addr_prefix_str[BUFSIZ];
6864
6865 if (address_str) {
6866 int ret;
6867
6868 ret = netmask_str2prefix_str(address_str, netmask_str,
6869 addr_prefix_str,
6870 sizeof(addr_prefix_str));
6871 if (!ret) {
6872 vty_out(vty, "%% Inconsistent address and mask\n");
6873 return CMD_WARNING_CONFIG_FAILED;
6874 }
6875 }
6876
6877 return bgp_static_set(
6878 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
6879 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
6880 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6881 }
6882
6883 DEFPY(ipv6_bgp_network,
6884 ipv6_bgp_network_cmd,
6885 "[no] network X:X::X:X/M$prefix \
6886 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6887 NO_STR
6888 "Specify a network to announce via BGP\n"
6889 "IPv6 prefix\n"
6890 "Route-map to modify the attributes\n"
6891 "Name of the route map\n"
6892 "Label index to associate with the prefix\n"
6893 "Label index value\n")
6894 {
6895 return bgp_static_set(
6896 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
6897 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6898 }
6899
6900 static struct bgp_aggregate *bgp_aggregate_new(void)
6901 {
6902 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6903 }
6904
6905 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6906 {
6907 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
6908 route_map_counter_decrement(aggregate->suppress_map);
6909 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6910 route_map_counter_decrement(aggregate->rmap.map);
6911 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6912 }
6913
6914 /**
6915 * Helper function to avoid repeated code: prepare variables for a
6916 * `route_map_apply` call.
6917 *
6918 * \returns `true` on route map match, otherwise `false`.
6919 */
6920 static bool aggr_suppress_map_test(struct bgp *bgp,
6921 struct bgp_aggregate *aggregate,
6922 struct bgp_path_info *pi)
6923 {
6924 const struct prefix *p = bgp_dest_get_prefix(pi->net);
6925 route_map_result_t rmr = RMAP_DENYMATCH;
6926 struct bgp_path_info rmap_path = {};
6927 struct attr attr = {};
6928
6929 /* No route map entries created, just don't match. */
6930 if (aggregate->suppress_map == NULL)
6931 return false;
6932
6933 /* Call route map matching and return result. */
6934 attr.aspath = aspath_empty();
6935 rmap_path.peer = bgp->peer_self;
6936 rmap_path.attr = &attr;
6937
6938 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
6939 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
6940 bgp->peer_self->rmap_type = 0;
6941
6942 bgp_attr_flush(&attr);
6943
6944 return rmr == RMAP_PERMITMATCH;
6945 }
6946
6947 /** Test whether the aggregation has suppressed this path or not. */
6948 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
6949 struct bgp_path_info *pi)
6950 {
6951 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
6952 return false;
6953
6954 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
6955 }
6956
6957 /**
6958 * Suppress this path and keep the reference.
6959 *
6960 * \returns `true` if needs processing otherwise `false`.
6961 */
6962 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
6963 struct bgp_path_info *pi)
6964 {
6965 struct bgp_path_info_extra *pie;
6966
6967 /* Path is already suppressed by this aggregation. */
6968 if (aggr_suppress_exists(aggregate, pi))
6969 return false;
6970
6971 pie = bgp_path_info_extra_get(pi);
6972
6973 /* This is the first suppression, allocate memory and list it. */
6974 if (pie->aggr_suppressors == NULL)
6975 pie->aggr_suppressors = list_new();
6976
6977 listnode_add(pie->aggr_suppressors, aggregate);
6978
6979 /* Only mark for processing if suppressed. */
6980 if (listcount(pie->aggr_suppressors) == 1) {
6981 if (BGP_DEBUG(update, UPDATE_OUT))
6982 zlog_debug("aggregate-address suppressing: %pFX",
6983 bgp_dest_get_prefix(pi->net));
6984
6985 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6986 return true;
6987 }
6988
6989 return false;
6990 }
6991
6992 /**
6993 * Unsuppress this path and remove the reference.
6994 *
6995 * \returns `true` if needs processing otherwise `false`.
6996 */
6997 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
6998 struct bgp_path_info *pi)
6999 {
7000 /* Path wasn't suppressed. */
7001 if (!aggr_suppress_exists(aggregate, pi))
7002 return false;
7003
7004 listnode_delete(pi->extra->aggr_suppressors, aggregate);
7005
7006 /* Unsuppress and free extra memory if last item. */
7007 if (listcount(pi->extra->aggr_suppressors) == 0) {
7008 if (BGP_DEBUG(update, UPDATE_OUT))
7009 zlog_debug("aggregate-address unsuppressing: %pFX",
7010 bgp_dest_get_prefix(pi->net));
7011
7012 list_delete(&pi->extra->aggr_suppressors);
7013 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
7014 return true;
7015 }
7016
7017 return false;
7018 }
7019
7020 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
7021 struct aspath *aspath,
7022 struct community *comm,
7023 struct ecommunity *ecomm,
7024 struct lcommunity *lcomm)
7025 {
7026 static struct aspath *ae = NULL;
7027
7028 if (!ae)
7029 ae = aspath_empty();
7030
7031 if (!pi)
7032 return false;
7033
7034 if (origin != pi->attr->origin)
7035 return false;
7036
7037 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
7038 return false;
7039
7040 if (!community_cmp(pi->attr->community, comm))
7041 return false;
7042
7043 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
7044 return false;
7045
7046 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
7047 return false;
7048
7049 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
7050 return false;
7051
7052 return true;
7053 }
7054
7055 static void bgp_aggregate_install(
7056 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
7057 uint8_t origin, struct aspath *aspath, struct community *community,
7058 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
7059 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
7060 {
7061 struct bgp_dest *dest;
7062 struct bgp_table *table;
7063 struct bgp_path_info *pi, *orig, *new;
7064 struct attr *attr;
7065
7066 table = bgp->rib[afi][safi];
7067
7068 dest = bgp_node_get(table, p);
7069
7070 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
7071 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
7072 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7073 break;
7074
7075 /*
7076 * If we have paths with different MEDs, then don't install
7077 * (or uninstall) the aggregate route.
7078 */
7079 if (aggregate->match_med && aggregate->med_mismatched)
7080 goto uninstall_aggregate_route;
7081
7082 if (aggregate->count > 0) {
7083 /*
7084 * If the aggregate information has not changed
7085 * no need to re-install it again.
7086 */
7087 if (bgp_aggregate_info_same(orig, origin, aspath, community,
7088 ecommunity, lcommunity)) {
7089 bgp_dest_unlock_node(dest);
7090
7091 if (aspath)
7092 aspath_free(aspath);
7093 if (community)
7094 community_free(&community);
7095 if (ecommunity)
7096 ecommunity_free(&ecommunity);
7097 if (lcommunity)
7098 lcommunity_free(&lcommunity);
7099
7100 return;
7101 }
7102
7103 /*
7104 * Mark the old as unusable
7105 */
7106 if (pi)
7107 bgp_path_info_delete(dest, pi);
7108
7109 attr = bgp_attr_aggregate_intern(
7110 bgp, origin, aspath, community, ecommunity, lcommunity,
7111 aggregate, atomic_aggregate, p);
7112
7113 if (!attr) {
7114 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
7115 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
7116 zlog_debug("%s: %pFX null attribute", __func__,
7117 p);
7118 return;
7119 }
7120
7121 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
7122 bgp->peer_self, attr, dest);
7123
7124 SET_FLAG(new->flags, BGP_PATH_VALID);
7125
7126 bgp_path_info_add(dest, new);
7127 bgp_process(bgp, dest, afi, safi);
7128 } else {
7129 uninstall_aggregate_route:
7130 for (pi = orig; pi; pi = pi->next)
7131 if (pi->peer == bgp->peer_self
7132 && pi->type == ZEBRA_ROUTE_BGP
7133 && pi->sub_type == BGP_ROUTE_AGGREGATE)
7134 break;
7135
7136 /* Withdraw static BGP route from routing table. */
7137 if (pi) {
7138 bgp_path_info_delete(dest, pi);
7139 bgp_process(bgp, dest, afi, safi);
7140 }
7141 }
7142
7143 bgp_dest_unlock_node(dest);
7144 }
7145
7146 /**
7147 * Check if the current path has different MED than other known paths.
7148 *
7149 * \returns `true` if the MED matched the others else `false`.
7150 */
7151 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
7152 struct bgp *bgp, struct bgp_path_info *pi)
7153 {
7154 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
7155
7156 /* This is the first route being analyzed. */
7157 if (!aggregate->med_initialized) {
7158 aggregate->med_initialized = true;
7159 aggregate->med_mismatched = false;
7160 aggregate->med_matched_value = cur_med;
7161 } else {
7162 /* Check if routes with different MED showed up. */
7163 if (cur_med != aggregate->med_matched_value)
7164 aggregate->med_mismatched = true;
7165 }
7166
7167 return !aggregate->med_mismatched;
7168 }
7169
7170 /**
7171 * Initializes and tests all routes in the aggregate address path for MED
7172 * values.
7173 *
7174 * \returns `true` if all MEDs are the same otherwise `false`.
7175 */
7176 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
7177 struct bgp *bgp, const struct prefix *p,
7178 afi_t afi, safi_t safi)
7179 {
7180 struct bgp_table *table = bgp->rib[afi][safi];
7181 const struct prefix *dest_p;
7182 struct bgp_dest *dest, *top;
7183 struct bgp_path_info *pi;
7184 bool med_matched = true;
7185
7186 aggregate->med_initialized = false;
7187
7188 top = bgp_node_get(table, p);
7189 for (dest = bgp_node_get(table, p); dest;
7190 dest = bgp_route_next_until(dest, top)) {
7191 dest_p = bgp_dest_get_prefix(dest);
7192 if (dest_p->prefixlen <= p->prefixlen)
7193 continue;
7194
7195 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7196 if (BGP_PATH_HOLDDOWN(pi))
7197 continue;
7198 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7199 continue;
7200 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
7201 med_matched = false;
7202 break;
7203 }
7204 }
7205 if (!med_matched)
7206 break;
7207 }
7208 bgp_dest_unlock_node(top);
7209
7210 return med_matched;
7211 }
7212
7213 /**
7214 * Toggles the route suppression status for this aggregate address
7215 * configuration.
7216 */
7217 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
7218 struct bgp *bgp, const struct prefix *p,
7219 afi_t afi, safi_t safi, bool suppress)
7220 {
7221 struct bgp_table *table = bgp->rib[afi][safi];
7222 const struct prefix *dest_p;
7223 struct bgp_dest *dest, *top;
7224 struct bgp_path_info *pi;
7225 bool toggle_suppression;
7226
7227 /* We've found a different MED we must revert any suppressed routes. */
7228 top = bgp_node_get(table, p);
7229 for (dest = bgp_node_get(table, p); dest;
7230 dest = bgp_route_next_until(dest, top)) {
7231 dest_p = bgp_dest_get_prefix(dest);
7232 if (dest_p->prefixlen <= p->prefixlen)
7233 continue;
7234
7235 toggle_suppression = false;
7236 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7237 if (BGP_PATH_HOLDDOWN(pi))
7238 continue;
7239 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7240 continue;
7241
7242 /* We are toggling suppression back. */
7243 if (suppress) {
7244 /* Suppress route if not suppressed already. */
7245 if (aggr_suppress_path(aggregate, pi))
7246 toggle_suppression = true;
7247 continue;
7248 }
7249
7250 /* Install route if there is no more suppression. */
7251 if (aggr_unsuppress_path(aggregate, pi))
7252 toggle_suppression = true;
7253 }
7254
7255 if (toggle_suppression)
7256 bgp_process(bgp, dest, afi, safi);
7257 }
7258 bgp_dest_unlock_node(top);
7259 }
7260
7261 /**
7262 * Aggregate address MED matching incremental test: this function is called
7263 * when the initial aggregation occurred and we are only testing a single
7264 * new path.
7265 *
7266 * In addition to testing and setting the MED validity it also installs back
7267 * suppressed routes (if summary is configured).
7268 *
7269 * Must not be called in `bgp_aggregate_route`.
7270 */
7271 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7272 struct bgp *bgp, const struct prefix *p,
7273 afi_t afi, safi_t safi,
7274 struct bgp_path_info *pi, bool is_adding)
7275 {
7276 /* MED matching disabled. */
7277 if (!aggregate->match_med)
7278 return;
7279
7280 /* Aggregation with different MED, nothing to do. */
7281 if (aggregate->med_mismatched)
7282 return;
7283
7284 /*
7285 * Test the current entry:
7286 *
7287 * is_adding == true: if the new entry doesn't match then we must
7288 * install all suppressed routes.
7289 *
7290 * is_adding == false: if the entry being removed was the last
7291 * unmatching entry then we can suppress all routes.
7292 */
7293 if (!is_adding) {
7294 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
7295 && aggregate->summary_only)
7296 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
7297 safi, true);
7298 } else
7299 bgp_aggregate_med_match(aggregate, bgp, pi);
7300
7301 /* No mismatches, just quit. */
7302 if (!aggregate->med_mismatched)
7303 return;
7304
7305 /* Route summarization is disabled. */
7306 if (!aggregate->summary_only)
7307 return;
7308
7309 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7310 }
7311
7312 /* Update an aggregate as routes are added/removed from the BGP table */
7313 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7314 safi_t safi, struct bgp_aggregate *aggregate)
7315 {
7316 struct bgp_table *table;
7317 struct bgp_dest *top;
7318 struct bgp_dest *dest;
7319 uint8_t origin;
7320 struct aspath *aspath = NULL;
7321 struct community *community = NULL;
7322 struct ecommunity *ecommunity = NULL;
7323 struct lcommunity *lcommunity = NULL;
7324 struct bgp_path_info *pi;
7325 unsigned long match = 0;
7326 uint8_t atomic_aggregate = 0;
7327
7328 /* If the bgp instance is being deleted or self peer is deleted
7329 * then do not create aggregate route
7330 */
7331 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7332 || (bgp->peer_self == NULL))
7333 return;
7334
7335 /* Initialize and test routes for MED difference. */
7336 if (aggregate->match_med)
7337 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7338
7339 /*
7340 * Reset aggregate count: we might've been called from route map
7341 * update so in that case we must retest all more specific routes.
7342 *
7343 * \see `bgp_route_map_process_update`.
7344 */
7345 aggregate->count = 0;
7346 aggregate->incomplete_origin_count = 0;
7347 aggregate->incomplete_origin_count = 0;
7348 aggregate->egp_origin_count = 0;
7349
7350 /* ORIGIN attribute: If at least one route among routes that are
7351 aggregated has ORIGIN with the value INCOMPLETE, then the
7352 aggregated route must have the ORIGIN attribute with the value
7353 INCOMPLETE. Otherwise, if at least one route among routes that
7354 are aggregated has ORIGIN with the value EGP, then the aggregated
7355 route must have the origin attribute with the value EGP. In all
7356 other case the value of the ORIGIN attribute of the aggregated
7357 route is INTERNAL. */
7358 origin = BGP_ORIGIN_IGP;
7359
7360 table = bgp->rib[afi][safi];
7361
7362 top = bgp_node_get(table, p);
7363 for (dest = bgp_node_get(table, p); dest;
7364 dest = bgp_route_next_until(dest, top)) {
7365 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7366
7367 if (dest_p->prefixlen <= p->prefixlen)
7368 continue;
7369
7370 /* If suppress fib is enabled and route not installed
7371 * in FIB, skip the route
7372 */
7373 if (!bgp_check_advertise(bgp, dest))
7374 continue;
7375
7376 match = 0;
7377
7378 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7379 if (BGP_PATH_HOLDDOWN(pi))
7380 continue;
7381
7382 if (pi->attr->flag
7383 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7384 atomic_aggregate = 1;
7385
7386 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7387 continue;
7388
7389 /*
7390 * summary-only aggregate route suppress
7391 * aggregated route announcements.
7392 *
7393 * MED matching:
7394 * Don't create summaries if MED didn't match
7395 * otherwise neither the specific routes and the
7396 * aggregation will be announced.
7397 */
7398 if (aggregate->summary_only
7399 && AGGREGATE_MED_VALID(aggregate)) {
7400 if (aggr_suppress_path(aggregate, pi))
7401 match++;
7402 }
7403
7404 /*
7405 * Suppress more specific routes that match the route
7406 * map results.
7407 *
7408 * MED matching:
7409 * Don't suppress routes if MED matching is enabled and
7410 * it mismatched otherwise we might end up with no
7411 * routes for this path.
7412 */
7413 if (aggregate->suppress_map_name
7414 && AGGREGATE_MED_VALID(aggregate)
7415 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7416 if (aggr_suppress_path(aggregate, pi))
7417 match++;
7418 }
7419
7420 aggregate->count++;
7421
7422 /*
7423 * If at least one route among routes that are
7424 * aggregated has ORIGIN with the value INCOMPLETE,
7425 * then the aggregated route MUST have the ORIGIN
7426 * attribute with the value INCOMPLETE. Otherwise, if
7427 * at least one route among routes that are aggregated
7428 * has ORIGIN with the value EGP, then the aggregated
7429 * route MUST have the ORIGIN attribute with the value
7430 * EGP.
7431 */
7432 switch (pi->attr->origin) {
7433 case BGP_ORIGIN_INCOMPLETE:
7434 aggregate->incomplete_origin_count++;
7435 break;
7436 case BGP_ORIGIN_EGP:
7437 aggregate->egp_origin_count++;
7438 break;
7439 default:
7440 /*Do nothing.
7441 */
7442 break;
7443 }
7444
7445 if (!aggregate->as_set)
7446 continue;
7447
7448 /*
7449 * as-set aggregate route generate origin, as path,
7450 * and community aggregation.
7451 */
7452 /* Compute aggregate route's as-path.
7453 */
7454 bgp_compute_aggregate_aspath_hash(aggregate,
7455 pi->attr->aspath);
7456
7457 /* Compute aggregate route's community.
7458 */
7459 if (pi->attr->community)
7460 bgp_compute_aggregate_community_hash(
7461 aggregate,
7462 pi->attr->community);
7463
7464 /* Compute aggregate route's extended community.
7465 */
7466 if (pi->attr->ecommunity)
7467 bgp_compute_aggregate_ecommunity_hash(
7468 aggregate,
7469 pi->attr->ecommunity);
7470
7471 /* Compute aggregate route's large community.
7472 */
7473 if (pi->attr->lcommunity)
7474 bgp_compute_aggregate_lcommunity_hash(
7475 aggregate,
7476 pi->attr->lcommunity);
7477 }
7478 if (match)
7479 bgp_process(bgp, dest, afi, safi);
7480 }
7481 if (aggregate->as_set) {
7482 bgp_compute_aggregate_aspath_val(aggregate);
7483 bgp_compute_aggregate_community_val(aggregate);
7484 bgp_compute_aggregate_ecommunity_val(aggregate);
7485 bgp_compute_aggregate_lcommunity_val(aggregate);
7486 }
7487
7488
7489 bgp_dest_unlock_node(top);
7490
7491
7492 if (aggregate->incomplete_origin_count > 0)
7493 origin = BGP_ORIGIN_INCOMPLETE;
7494 else if (aggregate->egp_origin_count > 0)
7495 origin = BGP_ORIGIN_EGP;
7496
7497 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7498 origin = aggregate->origin;
7499
7500 if (aggregate->as_set) {
7501 if (aggregate->aspath)
7502 /* Retrieve aggregate route's as-path.
7503 */
7504 aspath = aspath_dup(aggregate->aspath);
7505
7506 if (aggregate->community)
7507 /* Retrieve aggregate route's community.
7508 */
7509 community = community_dup(aggregate->community);
7510
7511 if (aggregate->ecommunity)
7512 /* Retrieve aggregate route's ecommunity.
7513 */
7514 ecommunity = ecommunity_dup(aggregate->ecommunity);
7515
7516 if (aggregate->lcommunity)
7517 /* Retrieve aggregate route's lcommunity.
7518 */
7519 lcommunity = lcommunity_dup(aggregate->lcommunity);
7520 }
7521
7522 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7523 ecommunity, lcommunity, atomic_aggregate,
7524 aggregate);
7525 }
7526
7527 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7528 safi_t safi, struct bgp_aggregate *aggregate)
7529 {
7530 struct bgp_table *table;
7531 struct bgp_dest *top;
7532 struct bgp_dest *dest;
7533 struct bgp_path_info *pi;
7534 unsigned long match;
7535
7536 table = bgp->rib[afi][safi];
7537
7538 /* If routes exists below this node, generate aggregate routes. */
7539 top = bgp_node_get(table, p);
7540 for (dest = bgp_node_get(table, p); dest;
7541 dest = bgp_route_next_until(dest, top)) {
7542 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7543
7544 if (dest_p->prefixlen <= p->prefixlen)
7545 continue;
7546 match = 0;
7547
7548 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7549 if (BGP_PATH_HOLDDOWN(pi))
7550 continue;
7551
7552 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7553 continue;
7554
7555 /*
7556 * This route is suppressed: attempt to unsuppress it.
7557 *
7558 * `aggr_unsuppress_path` will fail if this particular
7559 * aggregate route was not the suppressor.
7560 */
7561 if (pi->extra && pi->extra->aggr_suppressors &&
7562 listcount(pi->extra->aggr_suppressors)) {
7563 if (aggr_unsuppress_path(aggregate, pi))
7564 match++;
7565 }
7566
7567 aggregate->count--;
7568
7569 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7570 aggregate->incomplete_origin_count--;
7571 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7572 aggregate->egp_origin_count--;
7573
7574 if (aggregate->as_set) {
7575 /* Remove as-path from aggregate.
7576 */
7577 bgp_remove_aspath_from_aggregate_hash(
7578 aggregate,
7579 pi->attr->aspath);
7580
7581 if (pi->attr->community)
7582 /* Remove community from aggregate.
7583 */
7584 bgp_remove_comm_from_aggregate_hash(
7585 aggregate,
7586 pi->attr->community);
7587
7588 if (pi->attr->ecommunity)
7589 /* Remove ecommunity from aggregate.
7590 */
7591 bgp_remove_ecomm_from_aggregate_hash(
7592 aggregate,
7593 pi->attr->ecommunity);
7594
7595 if (pi->attr->lcommunity)
7596 /* Remove lcommunity from aggregate.
7597 */
7598 bgp_remove_lcomm_from_aggregate_hash(
7599 aggregate,
7600 pi->attr->lcommunity);
7601 }
7602 }
7603
7604 /* If this node was suppressed, process the change. */
7605 if (match)
7606 bgp_process(bgp, dest, afi, safi);
7607 }
7608 if (aggregate->as_set) {
7609 aspath_free(aggregate->aspath);
7610 aggregate->aspath = NULL;
7611 if (aggregate->community)
7612 community_free(&aggregate->community);
7613 if (aggregate->ecommunity)
7614 ecommunity_free(&aggregate->ecommunity);
7615 if (aggregate->lcommunity)
7616 lcommunity_free(&aggregate->lcommunity);
7617 }
7618
7619 bgp_dest_unlock_node(top);
7620 }
7621
7622 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7623 const struct prefix *aggr_p,
7624 struct bgp_path_info *pinew, afi_t afi,
7625 safi_t safi,
7626 struct bgp_aggregate *aggregate)
7627 {
7628 uint8_t origin;
7629 struct aspath *aspath = NULL;
7630 uint8_t atomic_aggregate = 0;
7631 struct community *community = NULL;
7632 struct ecommunity *ecommunity = NULL;
7633 struct lcommunity *lcommunity = NULL;
7634
7635 /* If the bgp instance is being deleted or self peer is deleted
7636 * then do not create aggregate route
7637 */
7638 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7639 || (bgp->peer_self == NULL))
7640 return;
7641
7642 /* ORIGIN attribute: If at least one route among routes that are
7643 * aggregated has ORIGIN with the value INCOMPLETE, then the
7644 * aggregated route must have the ORIGIN attribute with the value
7645 * INCOMPLETE. Otherwise, if at least one route among routes that
7646 * are aggregated has ORIGIN with the value EGP, then the aggregated
7647 * route must have the origin attribute with the value EGP. In all
7648 * other case the value of the ORIGIN attribute of the aggregated
7649 * route is INTERNAL.
7650 */
7651 origin = BGP_ORIGIN_IGP;
7652
7653 aggregate->count++;
7654
7655 /*
7656 * This must be called before `summary` check to avoid
7657 * "suppressing" twice.
7658 */
7659 if (aggregate->match_med)
7660 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7661 pinew, true);
7662
7663 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7664 aggr_suppress_path(aggregate, pinew);
7665
7666 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7667 && aggr_suppress_map_test(bgp, aggregate, pinew))
7668 aggr_suppress_path(aggregate, pinew);
7669
7670 switch (pinew->attr->origin) {
7671 case BGP_ORIGIN_INCOMPLETE:
7672 aggregate->incomplete_origin_count++;
7673 break;
7674 case BGP_ORIGIN_EGP:
7675 aggregate->egp_origin_count++;
7676 break;
7677 default:
7678 /* Do nothing.
7679 */
7680 break;
7681 }
7682
7683 if (aggregate->incomplete_origin_count > 0)
7684 origin = BGP_ORIGIN_INCOMPLETE;
7685 else if (aggregate->egp_origin_count > 0)
7686 origin = BGP_ORIGIN_EGP;
7687
7688 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7689 origin = aggregate->origin;
7690
7691 if (aggregate->as_set) {
7692 /* Compute aggregate route's as-path.
7693 */
7694 bgp_compute_aggregate_aspath(aggregate,
7695 pinew->attr->aspath);
7696
7697 /* Compute aggregate route's community.
7698 */
7699 if (pinew->attr->community)
7700 bgp_compute_aggregate_community(
7701 aggregate,
7702 pinew->attr->community);
7703
7704 /* Compute aggregate route's extended community.
7705 */
7706 if (pinew->attr->ecommunity)
7707 bgp_compute_aggregate_ecommunity(
7708 aggregate,
7709 pinew->attr->ecommunity);
7710
7711 /* Compute aggregate route's large community.
7712 */
7713 if (pinew->attr->lcommunity)
7714 bgp_compute_aggregate_lcommunity(
7715 aggregate,
7716 pinew->attr->lcommunity);
7717
7718 /* Retrieve aggregate route's as-path.
7719 */
7720 if (aggregate->aspath)
7721 aspath = aspath_dup(aggregate->aspath);
7722
7723 /* Retrieve aggregate route's community.
7724 */
7725 if (aggregate->community)
7726 community = community_dup(aggregate->community);
7727
7728 /* Retrieve aggregate route's ecommunity.
7729 */
7730 if (aggregate->ecommunity)
7731 ecommunity = ecommunity_dup(aggregate->ecommunity);
7732
7733 /* Retrieve aggregate route's lcommunity.
7734 */
7735 if (aggregate->lcommunity)
7736 lcommunity = lcommunity_dup(aggregate->lcommunity);
7737 }
7738
7739 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7740 aspath, community, ecommunity,
7741 lcommunity, atomic_aggregate, aggregate);
7742 }
7743
7744 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7745 safi_t safi,
7746 struct bgp_path_info *pi,
7747 struct bgp_aggregate *aggregate,
7748 const struct prefix *aggr_p)
7749 {
7750 uint8_t origin;
7751 struct aspath *aspath = NULL;
7752 uint8_t atomic_aggregate = 0;
7753 struct community *community = NULL;
7754 struct ecommunity *ecommunity = NULL;
7755 struct lcommunity *lcommunity = NULL;
7756 unsigned long match = 0;
7757
7758 /* If the bgp instance is being deleted or self peer is deleted
7759 * then do not create aggregate route
7760 */
7761 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7762 || (bgp->peer_self == NULL))
7763 return;
7764
7765 if (BGP_PATH_HOLDDOWN(pi))
7766 return;
7767
7768 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7769 return;
7770
7771 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7772 if (aggr_unsuppress_path(aggregate, pi))
7773 match++;
7774
7775 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7776 && aggr_suppress_map_test(bgp, aggregate, pi))
7777 if (aggr_unsuppress_path(aggregate, pi))
7778 match++;
7779
7780 /*
7781 * This must be called after `summary`, `suppress-map` check to avoid
7782 * "unsuppressing" twice.
7783 */
7784 if (aggregate->match_med)
7785 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
7786 true);
7787
7788 if (aggregate->count > 0)
7789 aggregate->count--;
7790
7791 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7792 aggregate->incomplete_origin_count--;
7793 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7794 aggregate->egp_origin_count--;
7795
7796 if (aggregate->as_set) {
7797 /* Remove as-path from aggregate.
7798 */
7799 bgp_remove_aspath_from_aggregate(aggregate,
7800 pi->attr->aspath);
7801
7802 if (pi->attr->community)
7803 /* Remove community from aggregate.
7804 */
7805 bgp_remove_community_from_aggregate(
7806 aggregate,
7807 pi->attr->community);
7808
7809 if (pi->attr->ecommunity)
7810 /* Remove ecommunity from aggregate.
7811 */
7812 bgp_remove_ecommunity_from_aggregate(
7813 aggregate,
7814 pi->attr->ecommunity);
7815
7816 if (pi->attr->lcommunity)
7817 /* Remove lcommunity from aggregate.
7818 */
7819 bgp_remove_lcommunity_from_aggregate(
7820 aggregate,
7821 pi->attr->lcommunity);
7822 }
7823
7824 /* If this node was suppressed, process the change. */
7825 if (match)
7826 bgp_process(bgp, pi->net, afi, safi);
7827
7828 origin = BGP_ORIGIN_IGP;
7829 if (aggregate->incomplete_origin_count > 0)
7830 origin = BGP_ORIGIN_INCOMPLETE;
7831 else if (aggregate->egp_origin_count > 0)
7832 origin = BGP_ORIGIN_EGP;
7833
7834 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7835 origin = aggregate->origin;
7836
7837 if (aggregate->as_set) {
7838 /* Retrieve aggregate route's as-path.
7839 */
7840 if (aggregate->aspath)
7841 aspath = aspath_dup(aggregate->aspath);
7842
7843 /* Retrieve aggregate route's community.
7844 */
7845 if (aggregate->community)
7846 community = community_dup(aggregate->community);
7847
7848 /* Retrieve aggregate route's ecommunity.
7849 */
7850 if (aggregate->ecommunity)
7851 ecommunity = ecommunity_dup(aggregate->ecommunity);
7852
7853 /* Retrieve aggregate route's lcommunity.
7854 */
7855 if (aggregate->lcommunity)
7856 lcommunity = lcommunity_dup(aggregate->lcommunity);
7857 }
7858
7859 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7860 aspath, community, ecommunity,
7861 lcommunity, atomic_aggregate, aggregate);
7862 }
7863
7864 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
7865 struct bgp_path_info *pi, afi_t afi, safi_t safi)
7866 {
7867 struct bgp_dest *child;
7868 struct bgp_dest *dest;
7869 struct bgp_aggregate *aggregate;
7870 struct bgp_table *table;
7871
7872 table = bgp->aggregate[afi][safi];
7873
7874 /* No aggregates configured. */
7875 if (bgp_table_top_nolock(table) == NULL)
7876 return;
7877
7878 if (p->prefixlen == 0)
7879 return;
7880
7881 if (BGP_PATH_HOLDDOWN(pi))
7882 return;
7883
7884 /* If suppress fib is enabled and route not installed
7885 * in FIB, do not update the aggregate route
7886 */
7887 if (!bgp_check_advertise(bgp, pi->net))
7888 return;
7889
7890 child = bgp_node_get(table, p);
7891
7892 /* Aggregate address configuration check. */
7893 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7894 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7895
7896 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7897 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7898 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
7899 aggregate);
7900 }
7901 }
7902 bgp_dest_unlock_node(child);
7903 }
7904
7905 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
7906 struct bgp_path_info *del, afi_t afi, safi_t safi)
7907 {
7908 struct bgp_dest *child;
7909 struct bgp_dest *dest;
7910 struct bgp_aggregate *aggregate;
7911 struct bgp_table *table;
7912
7913 table = bgp->aggregate[afi][safi];
7914
7915 /* No aggregates configured. */
7916 if (bgp_table_top_nolock(table) == NULL)
7917 return;
7918
7919 if (p->prefixlen == 0)
7920 return;
7921
7922 child = bgp_node_get(table, p);
7923
7924 /* Aggregate address configuration check. */
7925 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7926 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7927
7928 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7929 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7930 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
7931 aggregate, dest_p);
7932 }
7933 }
7934 bgp_dest_unlock_node(child);
7935 }
7936
7937 /* Aggregate route attribute. */
7938 #define AGGREGATE_SUMMARY_ONLY 1
7939 #define AGGREGATE_AS_SET 1
7940 #define AGGREGATE_AS_UNSET 0
7941
7942 static const char *bgp_origin2str(uint8_t origin)
7943 {
7944 switch (origin) {
7945 case BGP_ORIGIN_IGP:
7946 return "igp";
7947 case BGP_ORIGIN_EGP:
7948 return "egp";
7949 case BGP_ORIGIN_INCOMPLETE:
7950 return "incomplete";
7951 }
7952 return "n/a";
7953 }
7954
7955 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
7956 {
7957 switch (v_state) {
7958 case RPKI_NOT_BEING_USED:
7959 return "not used";
7960 case RPKI_VALID:
7961 return "valid";
7962 case RPKI_NOTFOUND:
7963 return "not found";
7964 case RPKI_INVALID:
7965 return "invalid";
7966 }
7967
7968 assert(!"We should never get here this is a dev escape");
7969 return "ERROR";
7970 }
7971
7972 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
7973 afi_t afi, safi_t safi)
7974 {
7975 VTY_DECLVAR_CONTEXT(bgp, bgp);
7976 int ret;
7977 struct prefix p;
7978 struct bgp_dest *dest;
7979 struct bgp_aggregate *aggregate;
7980
7981 /* Convert string to prefix structure. */
7982 ret = str2prefix(prefix_str, &p);
7983 if (!ret) {
7984 vty_out(vty, "Malformed prefix\n");
7985 return CMD_WARNING_CONFIG_FAILED;
7986 }
7987 apply_mask(&p);
7988
7989 /* Old configuration check. */
7990 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
7991 if (!dest) {
7992 vty_out(vty,
7993 "%% There is no aggregate-address configuration.\n");
7994 return CMD_WARNING_CONFIG_FAILED;
7995 }
7996
7997 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7998 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
7999 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
8000 NULL, NULL, 0, aggregate);
8001
8002 /* Unlock aggregate address configuration. */
8003 bgp_dest_set_bgp_aggregate_info(dest, NULL);
8004
8005 if (aggregate->community)
8006 community_free(&aggregate->community);
8007
8008 if (aggregate->community_hash) {
8009 /* Delete all communities in the hash.
8010 */
8011 hash_clean(aggregate->community_hash,
8012 bgp_aggr_community_remove);
8013 /* Free up the community_hash.
8014 */
8015 hash_free(aggregate->community_hash);
8016 }
8017
8018 if (aggregate->ecommunity)
8019 ecommunity_free(&aggregate->ecommunity);
8020
8021 if (aggregate->ecommunity_hash) {
8022 /* Delete all ecommunities in the hash.
8023 */
8024 hash_clean(aggregate->ecommunity_hash,
8025 bgp_aggr_ecommunity_remove);
8026 /* Free up the ecommunity_hash.
8027 */
8028 hash_free(aggregate->ecommunity_hash);
8029 }
8030
8031 if (aggregate->lcommunity)
8032 lcommunity_free(&aggregate->lcommunity);
8033
8034 if (aggregate->lcommunity_hash) {
8035 /* Delete all lcommunities in the hash.
8036 */
8037 hash_clean(aggregate->lcommunity_hash,
8038 bgp_aggr_lcommunity_remove);
8039 /* Free up the lcommunity_hash.
8040 */
8041 hash_free(aggregate->lcommunity_hash);
8042 }
8043
8044 if (aggregate->aspath)
8045 aspath_free(aggregate->aspath);
8046
8047 if (aggregate->aspath_hash) {
8048 /* Delete all as-paths in the hash.
8049 */
8050 hash_clean(aggregate->aspath_hash,
8051 bgp_aggr_aspath_remove);
8052 /* Free up the aspath_hash.
8053 */
8054 hash_free(aggregate->aspath_hash);
8055 }
8056
8057 bgp_aggregate_free(aggregate);
8058 bgp_dest_unlock_node(dest);
8059 bgp_dest_unlock_node(dest);
8060
8061 return CMD_SUCCESS;
8062 }
8063
8064 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
8065 safi_t safi, const char *rmap,
8066 uint8_t summary_only, uint8_t as_set,
8067 uint8_t origin, bool match_med,
8068 const char *suppress_map)
8069 {
8070 VTY_DECLVAR_CONTEXT(bgp, bgp);
8071 int ret;
8072 struct prefix p;
8073 struct bgp_dest *dest;
8074 struct bgp_aggregate *aggregate;
8075 uint8_t as_set_new = as_set;
8076
8077 if (suppress_map && summary_only) {
8078 vty_out(vty,
8079 "'summary-only' and 'suppress-map' can't be used at the same time\n");
8080 return CMD_WARNING_CONFIG_FAILED;
8081 }
8082
8083 /* Convert string to prefix structure. */
8084 ret = str2prefix(prefix_str, &p);
8085 if (!ret) {
8086 vty_out(vty, "Malformed prefix\n");
8087 return CMD_WARNING_CONFIG_FAILED;
8088 }
8089 apply_mask(&p);
8090
8091 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
8092 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
8093 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
8094 prefix_str);
8095 return CMD_WARNING_CONFIG_FAILED;
8096 }
8097
8098 /* Old configuration check. */
8099 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
8100 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
8101
8102 if (aggregate) {
8103 vty_out(vty, "There is already same aggregate network.\n");
8104 /* try to remove the old entry */
8105 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
8106 if (ret) {
8107 vty_out(vty, "Error deleting aggregate.\n");
8108 bgp_dest_unlock_node(dest);
8109 return CMD_WARNING_CONFIG_FAILED;
8110 }
8111 }
8112
8113 /* Make aggregate address structure. */
8114 aggregate = bgp_aggregate_new();
8115 aggregate->summary_only = summary_only;
8116 aggregate->match_med = match_med;
8117
8118 /* Network operators MUST NOT locally generate any new
8119 * announcements containing AS_SET or AS_CONFED_SET. If they have
8120 * announced routes with AS_SET or AS_CONFED_SET in them, then they
8121 * SHOULD withdraw those routes and re-announce routes for the
8122 * aggregate or component prefixes (i.e., the more-specific routes
8123 * subsumed by the previously aggregated route) without AS_SET
8124 * or AS_CONFED_SET in the updates.
8125 */
8126 if (bgp->reject_as_sets) {
8127 if (as_set == AGGREGATE_AS_SET) {
8128 as_set_new = AGGREGATE_AS_UNSET;
8129 zlog_warn(
8130 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
8131 __func__);
8132 vty_out(vty,
8133 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
8134 }
8135 }
8136
8137 aggregate->as_set = as_set_new;
8138 aggregate->safi = safi;
8139 /* Override ORIGIN attribute if defined.
8140 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
8141 * to IGP which is not what rfc4271 says.
8142 * This enables the same behavior, optionally.
8143 */
8144 aggregate->origin = origin;
8145
8146 if (rmap) {
8147 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
8148 route_map_counter_decrement(aggregate->rmap.map);
8149 aggregate->rmap.name =
8150 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
8151 aggregate->rmap.map = route_map_lookup_by_name(rmap);
8152 route_map_counter_increment(aggregate->rmap.map);
8153 }
8154
8155 if (suppress_map) {
8156 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
8157 route_map_counter_decrement(aggregate->suppress_map);
8158
8159 aggregate->suppress_map_name =
8160 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
8161 aggregate->suppress_map =
8162 route_map_lookup_by_name(aggregate->suppress_map_name);
8163 route_map_counter_increment(aggregate->suppress_map);
8164 }
8165
8166 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
8167
8168 /* Aggregate address insert into BGP routing table. */
8169 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
8170
8171 return CMD_SUCCESS;
8172 }
8173
8174 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
8175 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
8176 "as-set$as_set_s"
8177 "|summary-only$summary_only"
8178 "|route-map WORD$rmap_name"
8179 "|origin <egp|igp|incomplete>$origin_s"
8180 "|matching-MED-only$match_med"
8181 "|suppress-map WORD$suppress_map"
8182 "}]",
8183 NO_STR
8184 "Configure BGP aggregate entries\n"
8185 "Aggregate prefix\n" "Aggregate address\n" "Aggregate mask\n"
8186 "Generate AS set path information\n"
8187 "Filter more specific routes from updates\n"
8188 "Apply route map to aggregate network\n"
8189 "Route map name\n"
8190 "BGP origin code\n"
8191 "Remote EGP\n"
8192 "Local IGP\n"
8193 "Unknown heritage\n"
8194 "Only aggregate routes with matching MED\n"
8195 "Suppress the selected more specific routes\n"
8196 "Route map with the route selectors\n")
8197 {
8198 const char *prefix_s = NULL;
8199 safi_t safi = bgp_node_safi(vty);
8200 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8201 int as_set = AGGREGATE_AS_UNSET;
8202 char prefix_buf[PREFIX2STR_BUFFER];
8203
8204 if (addr_str) {
8205 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
8206 sizeof(prefix_buf))
8207 == 0) {
8208 vty_out(vty, "%% Inconsistent address and mask\n");
8209 return CMD_WARNING_CONFIG_FAILED;
8210 }
8211 prefix_s = prefix_buf;
8212 } else
8213 prefix_s = prefix_str;
8214
8215 if (origin_s) {
8216 if (strcmp(origin_s, "egp") == 0)
8217 origin = BGP_ORIGIN_EGP;
8218 else if (strcmp(origin_s, "igp") == 0)
8219 origin = BGP_ORIGIN_IGP;
8220 else if (strcmp(origin_s, "incomplete") == 0)
8221 origin = BGP_ORIGIN_INCOMPLETE;
8222 }
8223
8224 if (as_set_s)
8225 as_set = AGGREGATE_AS_SET;
8226
8227 /* Handle configuration removal, otherwise installation. */
8228 if (no)
8229 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8230
8231 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8232 summary_only != NULL, as_set, origin,
8233 match_med != NULL, suppress_map);
8234 }
8235
8236 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8237 "[no] aggregate-address X:X::X:X/M$prefix [{"
8238 "as-set$as_set_s"
8239 "|summary-only$summary_only"
8240 "|route-map WORD$rmap_name"
8241 "|origin <egp|igp|incomplete>$origin_s"
8242 "|matching-MED-only$match_med"
8243 "|suppress-map WORD$suppress_map"
8244 "}]",
8245 NO_STR
8246 "Configure BGP aggregate entries\n"
8247 "Aggregate prefix\n"
8248 "Generate AS set path information\n"
8249 "Filter more specific routes from updates\n"
8250 "Apply route map to aggregate network\n"
8251 "Route map name\n"
8252 "BGP origin code\n"
8253 "Remote EGP\n"
8254 "Local IGP\n"
8255 "Unknown heritage\n"
8256 "Only aggregate routes with matching MED\n"
8257 "Suppress the selected more specific routes\n"
8258 "Route map with the route selectors\n")
8259 {
8260 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8261 int as_set = AGGREGATE_AS_UNSET;
8262
8263 if (origin_s) {
8264 if (strcmp(origin_s, "egp") == 0)
8265 origin = BGP_ORIGIN_EGP;
8266 else if (strcmp(origin_s, "igp") == 0)
8267 origin = BGP_ORIGIN_IGP;
8268 else if (strcmp(origin_s, "incomplete") == 0)
8269 origin = BGP_ORIGIN_INCOMPLETE;
8270 }
8271
8272 if (as_set_s)
8273 as_set = AGGREGATE_AS_SET;
8274
8275 /* Handle configuration removal, otherwise installation. */
8276 if (no)
8277 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8278 SAFI_UNICAST);
8279
8280 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8281 rmap_name, summary_only != NULL, as_set,
8282 origin, match_med != NULL, suppress_map);
8283 }
8284
8285 /* Redistribute route treatment. */
8286 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8287 const union g_addr *nexthop, ifindex_t ifindex,
8288 enum nexthop_types_t nhtype, uint8_t distance,
8289 enum blackhole_type bhtype, uint32_t metric,
8290 uint8_t type, unsigned short instance,
8291 route_tag_t tag)
8292 {
8293 struct bgp_path_info *new;
8294 struct bgp_path_info *bpi;
8295 struct bgp_path_info rmap_path;
8296 struct bgp_dest *bn;
8297 struct attr attr;
8298 struct attr *new_attr;
8299 afi_t afi;
8300 route_map_result_t ret;
8301 struct bgp_redist *red;
8302
8303 /* Make default attribute. */
8304 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
8305 /*
8306 * This must not be NULL to satisfy Coverity SA
8307 */
8308 assert(attr.aspath);
8309
8310 switch (nhtype) {
8311 case NEXTHOP_TYPE_IFINDEX:
8312 break;
8313 case NEXTHOP_TYPE_IPV4:
8314 case NEXTHOP_TYPE_IPV4_IFINDEX:
8315 attr.nexthop = nexthop->ipv4;
8316 break;
8317 case NEXTHOP_TYPE_IPV6:
8318 case NEXTHOP_TYPE_IPV6_IFINDEX:
8319 attr.mp_nexthop_global = nexthop->ipv6;
8320 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8321 break;
8322 case NEXTHOP_TYPE_BLACKHOLE:
8323 switch (p->family) {
8324 case AF_INET:
8325 attr.nexthop.s_addr = INADDR_ANY;
8326 break;
8327 case AF_INET6:
8328 memset(&attr.mp_nexthop_global, 0,
8329 sizeof(attr.mp_nexthop_global));
8330 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8331 break;
8332 }
8333 attr.bh_type = bhtype;
8334 break;
8335 }
8336 attr.nh_type = nhtype;
8337 attr.nh_ifindex = ifindex;
8338
8339 attr.med = metric;
8340 attr.distance = distance;
8341 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8342 attr.tag = tag;
8343
8344 afi = family2afi(p->family);
8345
8346 red = bgp_redist_lookup(bgp, afi, type, instance);
8347 if (red) {
8348 struct attr attr_new;
8349
8350 /* Copy attribute for modification. */
8351 attr_new = attr;
8352
8353 if (red->redist_metric_flag)
8354 attr_new.med = red->redist_metric;
8355
8356 /* Apply route-map. */
8357 if (red->rmap.name) {
8358 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
8359 rmap_path.peer = bgp->peer_self;
8360 rmap_path.attr = &attr_new;
8361
8362 SET_FLAG(bgp->peer_self->rmap_type,
8363 PEER_RMAP_TYPE_REDISTRIBUTE);
8364
8365 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8366
8367 bgp->peer_self->rmap_type = 0;
8368
8369 if (ret == RMAP_DENYMATCH) {
8370 /* Free uninterned attribute. */
8371 bgp_attr_flush(&attr_new);
8372
8373 /* Unintern original. */
8374 aspath_unintern(&attr.aspath);
8375 bgp_redistribute_delete(bgp, p, type, instance);
8376 return;
8377 }
8378 }
8379
8380 if (bgp_in_graceful_shutdown(bgp))
8381 bgp_attr_add_gshut_community(&attr_new);
8382
8383 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8384 SAFI_UNICAST, p, NULL);
8385
8386 new_attr = bgp_attr_intern(&attr_new);
8387
8388 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8389 if (bpi->peer == bgp->peer_self
8390 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8391 break;
8392
8393 if (bpi) {
8394 /* Ensure the (source route) type is updated. */
8395 bpi->type = type;
8396 if (attrhash_cmp(bpi->attr, new_attr)
8397 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8398 bgp_attr_unintern(&new_attr);
8399 aspath_unintern(&attr.aspath);
8400 bgp_dest_unlock_node(bn);
8401 return;
8402 } else {
8403 /* The attribute is changed. */
8404 bgp_path_info_set_flag(bn, bpi,
8405 BGP_PATH_ATTR_CHANGED);
8406
8407 /* Rewrite BGP route information. */
8408 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8409 bgp_path_info_restore(bn, bpi);
8410 else
8411 bgp_aggregate_decrement(
8412 bgp, p, bpi, afi, SAFI_UNICAST);
8413 bgp_attr_unintern(&bpi->attr);
8414 bpi->attr = new_attr;
8415 bpi->uptime = bgp_clock();
8416
8417 /* Process change. */
8418 bgp_aggregate_increment(bgp, p, bpi, afi,
8419 SAFI_UNICAST);
8420 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8421 bgp_dest_unlock_node(bn);
8422 aspath_unintern(&attr.aspath);
8423
8424 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8425 || (bgp->inst_type
8426 == BGP_INSTANCE_TYPE_DEFAULT)) {
8427
8428 vpn_leak_from_vrf_update(
8429 bgp_get_default(), bgp, bpi);
8430 }
8431 return;
8432 }
8433 }
8434
8435 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8436 bgp->peer_self, new_attr, bn);
8437 SET_FLAG(new->flags, BGP_PATH_VALID);
8438
8439 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8440 bgp_path_info_add(bn, new);
8441 bgp_dest_unlock_node(bn);
8442 SET_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED);
8443 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8444
8445 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8446 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8447
8448 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8449 }
8450 }
8451
8452 /* Unintern original. */
8453 aspath_unintern(&attr.aspath);
8454 }
8455
8456 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8457 unsigned short instance)
8458 {
8459 afi_t afi;
8460 struct bgp_dest *dest;
8461 struct bgp_path_info *pi;
8462 struct bgp_redist *red;
8463
8464 afi = family2afi(p->family);
8465
8466 red = bgp_redist_lookup(bgp, afi, type, instance);
8467 if (red) {
8468 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8469 SAFI_UNICAST, p, NULL);
8470
8471 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8472 if (pi->peer == bgp->peer_self && pi->type == type)
8473 break;
8474
8475 if (pi) {
8476 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8477 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8478
8479 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8480 bgp, pi);
8481 }
8482 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8483 bgp_path_info_delete(dest, pi);
8484 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8485 }
8486 bgp_dest_unlock_node(dest);
8487 }
8488 }
8489
8490 /* Withdraw specified route type's route. */
8491 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8492 unsigned short instance)
8493 {
8494 struct bgp_dest *dest;
8495 struct bgp_path_info *pi;
8496 struct bgp_table *table;
8497
8498 table = bgp->rib[afi][SAFI_UNICAST];
8499
8500 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8501 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8502 if (pi->peer == bgp->peer_self && pi->type == type
8503 && pi->instance == instance)
8504 break;
8505
8506 if (pi) {
8507 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8508 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8509
8510 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8511 bgp, pi);
8512 }
8513 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8514 pi, afi, SAFI_UNICAST);
8515 bgp_path_info_delete(dest, pi);
8516 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8517 }
8518 }
8519 }
8520
8521 /* Static function to display route. */
8522 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8523 struct vty *vty, json_object *json, bool wide)
8524 {
8525 int len = 0;
8526 char buf[BUFSIZ];
8527
8528 if (p->family == AF_INET) {
8529 if (!json) {
8530 len = vty_out(vty, "%pFX", p);
8531 } else {
8532 json_object_string_add(json, "prefix",
8533 inet_ntop(p->family,
8534 &p->u.prefix, buf,
8535 BUFSIZ));
8536 json_object_int_add(json, "prefixLen", p->prefixlen);
8537 json_object_string_addf(json, "network", "%pFX", p);
8538 json_object_int_add(json, "version", dest->version);
8539 }
8540 } else if (p->family == AF_ETHERNET) {
8541 len = vty_out(vty, "%pFX", p);
8542 } else if (p->family == AF_EVPN) {
8543 if (!json)
8544 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8545 else
8546 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8547 } else if (p->family == AF_FLOWSPEC) {
8548 route_vty_out_flowspec(vty, p, NULL,
8549 json ?
8550 NLRI_STRING_FORMAT_JSON_SIMPLE :
8551 NLRI_STRING_FORMAT_MIN, json);
8552 } else {
8553 if (!json)
8554 len = vty_out(vty, "%pFX", p);
8555 else {
8556 json_object_string_add(json, "prefix",
8557 inet_ntop(p->family,
8558 &p->u.prefix, buf,
8559 BUFSIZ));
8560 json_object_int_add(json, "prefixLen", p->prefixlen);
8561 json_object_string_addf(json, "network", "%pFX", p);
8562 json_object_int_add(json, "version", dest->version);
8563 }
8564 }
8565
8566 if (!json) {
8567 len = wide ? (45 - len) : (17 - len);
8568 if (len < 1)
8569 vty_out(vty, "\n%*s", 20, " ");
8570 else
8571 vty_out(vty, "%*s", len, " ");
8572 }
8573 }
8574
8575 enum bgp_display_type {
8576 normal_list,
8577 };
8578
8579 const char *bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8580 {
8581 switch (reason) {
8582 case bgp_path_selection_none:
8583 return "Nothing to Select";
8584 case bgp_path_selection_first:
8585 return "First path received";
8586 case bgp_path_selection_evpn_sticky_mac:
8587 return "EVPN Sticky Mac";
8588 case bgp_path_selection_evpn_seq:
8589 return "EVPN sequence number";
8590 case bgp_path_selection_evpn_lower_ip:
8591 return "EVPN lower IP";
8592 case bgp_path_selection_evpn_local_path:
8593 return "EVPN local ES path";
8594 case bgp_path_selection_evpn_non_proxy:
8595 return "EVPN non proxy";
8596 case bgp_path_selection_weight:
8597 return "Weight";
8598 case bgp_path_selection_local_pref:
8599 return "Local Pref";
8600 case bgp_path_selection_local_route:
8601 return "Local Route";
8602 case bgp_path_selection_confed_as_path:
8603 return "Confederation based AS Path";
8604 case bgp_path_selection_as_path:
8605 return "AS Path";
8606 case bgp_path_selection_origin:
8607 return "Origin";
8608 case bgp_path_selection_med:
8609 return "MED";
8610 case bgp_path_selection_peer:
8611 return "Peer Type";
8612 case bgp_path_selection_confed:
8613 return "Confed Peer Type";
8614 case bgp_path_selection_igp_metric:
8615 return "IGP Metric";
8616 case bgp_path_selection_older:
8617 return "Older Path";
8618 case bgp_path_selection_router_id:
8619 return "Router ID";
8620 case bgp_path_selection_cluster_length:
8621 return "Cluster length";
8622 case bgp_path_selection_stale:
8623 return "Path Staleness";
8624 case bgp_path_selection_local_configured:
8625 return "Locally configured route";
8626 case bgp_path_selection_neighbor_ip:
8627 return "Neighbor IP";
8628 case bgp_path_selection_default:
8629 return "Nothing left to compare";
8630 }
8631 return "Invalid (internal error)";
8632 }
8633
8634 /* Print the short form route status for a bgp_path_info */
8635 static void route_vty_short_status_out(struct vty *vty,
8636 struct bgp_path_info *path,
8637 const struct prefix *p,
8638 json_object *json_path)
8639 {
8640 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8641
8642 if (json_path) {
8643
8644 /* Route status display. */
8645 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8646 json_object_boolean_true_add(json_path, "removed");
8647
8648 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8649 json_object_boolean_true_add(json_path, "stale");
8650
8651 if (path->extra && bgp_path_suppressed(path))
8652 json_object_boolean_true_add(json_path, "suppressed");
8653
8654 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8655 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8656 json_object_boolean_true_add(json_path, "valid");
8657
8658 /* Selected */
8659 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8660 json_object_boolean_true_add(json_path, "history");
8661
8662 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8663 json_object_boolean_true_add(json_path, "damped");
8664
8665 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8666 json_object_boolean_true_add(json_path, "bestpath");
8667 json_object_string_add(json_path, "selectionReason",
8668 bgp_path_selection_reason2str(
8669 path->net->reason));
8670 }
8671
8672 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8673 json_object_boolean_true_add(json_path, "multipath");
8674
8675 /* Internal route. */
8676 if ((path->peer->as)
8677 && (path->peer->as == path->peer->local_as))
8678 json_object_string_add(json_path, "pathFrom",
8679 "internal");
8680 else
8681 json_object_string_add(json_path, "pathFrom",
8682 "external");
8683
8684 return;
8685 }
8686
8687 /* RPKI validation state */
8688 rpki_state =
8689 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
8690
8691 if (rpki_state == RPKI_VALID)
8692 vty_out(vty, "V");
8693 else if (rpki_state == RPKI_INVALID)
8694 vty_out(vty, "I");
8695 else if (rpki_state == RPKI_NOTFOUND)
8696 vty_out(vty, "N");
8697
8698 /* Route status display. */
8699 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8700 vty_out(vty, "R");
8701 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8702 vty_out(vty, "S");
8703 else if (bgp_path_suppressed(path))
8704 vty_out(vty, "s");
8705 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8706 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8707 vty_out(vty, "*");
8708 else
8709 vty_out(vty, " ");
8710
8711 /* Selected */
8712 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8713 vty_out(vty, "h");
8714 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8715 vty_out(vty, "d");
8716 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8717 vty_out(vty, ">");
8718 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8719 vty_out(vty, "=");
8720 else
8721 vty_out(vty, " ");
8722
8723 /* Internal route. */
8724 if (path->peer && (path->peer->as)
8725 && (path->peer->as == path->peer->local_as))
8726 vty_out(vty, "i");
8727 else
8728 vty_out(vty, " ");
8729 }
8730
8731 static char *bgp_nexthop_hostname(struct peer *peer,
8732 struct bgp_nexthop_cache *bnc)
8733 {
8734 if (peer->hostname
8735 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8736 return peer->hostname;
8737 return NULL;
8738 }
8739
8740 /* called from terminal list command */
8741 void route_vty_out(struct vty *vty, const struct prefix *p,
8742 struct bgp_path_info *path, int display, safi_t safi,
8743 json_object *json_paths, bool wide)
8744 {
8745 int len;
8746 struct attr *attr = path->attr;
8747 json_object *json_path = NULL;
8748 json_object *json_nexthops = NULL;
8749 json_object *json_nexthop_global = NULL;
8750 json_object *json_nexthop_ll = NULL;
8751 json_object *json_ext_community = NULL;
8752 char vrf_id_str[VRF_NAMSIZ] = {0};
8753 bool nexthop_self =
8754 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8755 bool nexthop_othervrf = false;
8756 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8757 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8758 char *nexthop_hostname =
8759 bgp_nexthop_hostname(path->peer, path->nexthop);
8760 char esi_buf[ESI_STR_LEN];
8761
8762 if (json_paths)
8763 json_path = json_object_new_object();
8764
8765 /* short status lead text */
8766 route_vty_short_status_out(vty, path, p, json_path);
8767
8768 if (!json_paths) {
8769 /* print prefix and mask */
8770 if (!display)
8771 route_vty_out_route(path->net, p, vty, json_path, wide);
8772 else
8773 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8774 } else {
8775 route_vty_out_route(path->net, p, vty, json_path, wide);
8776 }
8777
8778 /*
8779 * If vrf id of nexthop is different from that of prefix,
8780 * set up printable string to append
8781 */
8782 if (path->extra && path->extra->bgp_orig) {
8783 const char *self = "";
8784
8785 if (nexthop_self)
8786 self = "<";
8787
8788 nexthop_othervrf = true;
8789 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8790
8791 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8792 snprintf(vrf_id_str, sizeof(vrf_id_str),
8793 "@%s%s", VRFID_NONE_STR, self);
8794 else
8795 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8796 path->extra->bgp_orig->vrf_id, self);
8797
8798 if (path->extra->bgp_orig->inst_type
8799 != BGP_INSTANCE_TYPE_DEFAULT)
8800
8801 nexthop_vrfname = path->extra->bgp_orig->name;
8802 } else {
8803 const char *self = "";
8804
8805 if (nexthop_self)
8806 self = "<";
8807
8808 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8809 }
8810
8811 /*
8812 * For ENCAP and EVPN routes, nexthop address family is not
8813 * neccessarily the same as the prefix address family.
8814 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
8815 * EVPN routes are also exchanged with a MP nexthop. Currently,
8816 * this
8817 * is only IPv4, the value will be present in either
8818 * attr->nexthop or
8819 * attr->mp_nexthop_global_in
8820 */
8821 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
8822 char buf[BUFSIZ];
8823 char nexthop[128];
8824 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8825
8826 switch (af) {
8827 case AF_INET:
8828 snprintf(nexthop, sizeof(nexthop), "%s",
8829 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
8830 BUFSIZ));
8831 break;
8832 case AF_INET6:
8833 snprintf(nexthop, sizeof(nexthop), "%s",
8834 inet_ntop(af, &attr->mp_nexthop_global, buf,
8835 BUFSIZ));
8836 break;
8837 default:
8838 snprintf(nexthop, sizeof(nexthop), "?");
8839 break;
8840 }
8841
8842 if (json_paths) {
8843 json_nexthop_global = json_object_new_object();
8844
8845 json_object_string_add(json_nexthop_global, "ip",
8846 nexthop);
8847
8848 if (path->peer->hostname)
8849 json_object_string_add(json_nexthop_global,
8850 "hostname",
8851 path->peer->hostname);
8852
8853 json_object_string_add(json_nexthop_global, "afi",
8854 (af == AF_INET) ? "ipv4"
8855 : "ipv6");
8856 json_object_boolean_true_add(json_nexthop_global,
8857 "used");
8858 } else {
8859 if (nexthop_hostname)
8860 len = vty_out(vty, "%s(%s)%s", nexthop,
8861 nexthop_hostname, vrf_id_str);
8862 else
8863 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
8864
8865 len = wide ? (41 - len) : (16 - len);
8866 if (len < 1)
8867 vty_out(vty, "\n%*s", 36, " ");
8868 else
8869 vty_out(vty, "%*s", len, " ");
8870 }
8871 } else if (safi == SAFI_EVPN) {
8872 if (json_paths) {
8873 json_nexthop_global = json_object_new_object();
8874
8875 json_object_string_addf(json_nexthop_global, "ip",
8876 "%pI4", &attr->nexthop);
8877
8878 if (path->peer->hostname)
8879 json_object_string_add(json_nexthop_global,
8880 "hostname",
8881 path->peer->hostname);
8882
8883 json_object_string_add(json_nexthop_global, "afi",
8884 "ipv4");
8885 json_object_boolean_true_add(json_nexthop_global,
8886 "used");
8887 } else {
8888 if (nexthop_hostname)
8889 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8890 nexthop_hostname, vrf_id_str);
8891 else
8892 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8893 vrf_id_str);
8894
8895 len = wide ? (41 - len) : (16 - len);
8896 if (len < 1)
8897 vty_out(vty, "\n%*s", 36, " ");
8898 else
8899 vty_out(vty, "%*s", len, " ");
8900 }
8901 } else if (safi == SAFI_FLOWSPEC) {
8902 if (attr->nexthop.s_addr != INADDR_ANY) {
8903 if (json_paths) {
8904 json_nexthop_global = json_object_new_object();
8905
8906 json_object_string_add(json_nexthop_global,
8907 "afi", "ipv4");
8908 json_object_string_addf(json_nexthop_global,
8909 "ip", "%pI4",
8910 &attr->nexthop);
8911
8912 if (path->peer->hostname)
8913 json_object_string_add(
8914 json_nexthop_global, "hostname",
8915 path->peer->hostname);
8916
8917 json_object_boolean_true_add(
8918 json_nexthop_global,
8919 "used");
8920 } else {
8921 if (nexthop_hostname)
8922 len = vty_out(vty, "%pI4(%s)%s",
8923 &attr->nexthop,
8924 nexthop_hostname,
8925 vrf_id_str);
8926 else
8927 len = vty_out(vty, "%pI4%s",
8928 &attr->nexthop,
8929 vrf_id_str);
8930
8931 len = wide ? (41 - len) : (16 - len);
8932 if (len < 1)
8933 vty_out(vty, "\n%*s", 36, " ");
8934 else
8935 vty_out(vty, "%*s", len, " ");
8936 }
8937 }
8938 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8939 if (json_paths) {
8940 json_nexthop_global = json_object_new_object();
8941
8942 json_object_string_addf(json_nexthop_global, "ip",
8943 "%pI4", &attr->nexthop);
8944
8945 if (path->peer->hostname)
8946 json_object_string_add(json_nexthop_global,
8947 "hostname",
8948 path->peer->hostname);
8949
8950 json_object_string_add(json_nexthop_global, "afi",
8951 "ipv4");
8952 json_object_boolean_true_add(json_nexthop_global,
8953 "used");
8954 } else {
8955 if (nexthop_hostname)
8956 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8957 nexthop_hostname, vrf_id_str);
8958 else
8959 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8960 vrf_id_str);
8961
8962 len = wide ? (41 - len) : (16 - len);
8963 if (len < 1)
8964 vty_out(vty, "\n%*s", 36, " ");
8965 else
8966 vty_out(vty, "%*s", len, " ");
8967 }
8968 }
8969
8970 /* IPv6 Next Hop */
8971 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8972 if (json_paths) {
8973 json_nexthop_global = json_object_new_object();
8974 json_object_string_addf(json_nexthop_global, "ip",
8975 "%pI6",
8976 &attr->mp_nexthop_global);
8977
8978 if (path->peer->hostname)
8979 json_object_string_add(json_nexthop_global,
8980 "hostname",
8981 path->peer->hostname);
8982
8983 json_object_string_add(json_nexthop_global, "afi",
8984 "ipv6");
8985 json_object_string_add(json_nexthop_global, "scope",
8986 "global");
8987
8988 /* We display both LL & GL if both have been
8989 * received */
8990 if ((attr->mp_nexthop_len
8991 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8992 || (path->peer->conf_if)) {
8993 json_nexthop_ll = json_object_new_object();
8994 json_object_string_addf(
8995 json_nexthop_ll, "ip", "%pI6",
8996 &attr->mp_nexthop_local);
8997
8998 if (path->peer->hostname)
8999 json_object_string_add(
9000 json_nexthop_ll, "hostname",
9001 path->peer->hostname);
9002
9003 json_object_string_add(json_nexthop_ll, "afi",
9004 "ipv6");
9005 json_object_string_add(json_nexthop_ll, "scope",
9006 "link-local");
9007
9008 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
9009 &attr->mp_nexthop_local)
9010 != 0)
9011 && !attr->mp_nexthop_prefer_global)
9012 json_object_boolean_true_add(
9013 json_nexthop_ll, "used");
9014 else
9015 json_object_boolean_true_add(
9016 json_nexthop_global, "used");
9017 } else
9018 json_object_boolean_true_add(
9019 json_nexthop_global, "used");
9020 } else {
9021 /* Display LL if LL/Global both in table unless
9022 * prefer-global is set */
9023 if (((attr->mp_nexthop_len
9024 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
9025 && !attr->mp_nexthop_prefer_global)
9026 || (path->peer->conf_if)) {
9027 if (path->peer->conf_if) {
9028 len = vty_out(vty, "%s",
9029 path->peer->conf_if);
9030 /* len of IPv6 addr + max len of def
9031 * ifname */
9032 len = wide ? (41 - len) : (16 - len);
9033
9034 if (len < 1)
9035 vty_out(vty, "\n%*s", 36, " ");
9036 else
9037 vty_out(vty, "%*s", len, " ");
9038 } else {
9039 if (nexthop_hostname)
9040 len = vty_out(
9041 vty, "%pI6(%s)%s",
9042 &attr->mp_nexthop_local,
9043 nexthop_hostname,
9044 vrf_id_str);
9045 else
9046 len = vty_out(
9047 vty, "%pI6%s",
9048 &attr->mp_nexthop_local,
9049 vrf_id_str);
9050
9051 len = wide ? (41 - len) : (16 - len);
9052
9053 if (len < 1)
9054 vty_out(vty, "\n%*s", 36, " ");
9055 else
9056 vty_out(vty, "%*s", len, " ");
9057 }
9058 } else {
9059 if (nexthop_hostname)
9060 len = vty_out(vty, "%pI6(%s)%s",
9061 &attr->mp_nexthop_global,
9062 nexthop_hostname,
9063 vrf_id_str);
9064 else
9065 len = vty_out(vty, "%pI6%s",
9066 &attr->mp_nexthop_global,
9067 vrf_id_str);
9068
9069 len = wide ? (41 - len) : (16 - len);
9070
9071 if (len < 1)
9072 vty_out(vty, "\n%*s", 36, " ");
9073 else
9074 vty_out(vty, "%*s", len, " ");
9075 }
9076 }
9077 }
9078
9079 /* MED/Metric */
9080 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9081 if (json_paths)
9082 json_object_int_add(json_path, "metric", attr->med);
9083 else if (wide)
9084 vty_out(vty, "%7u", attr->med);
9085 else
9086 vty_out(vty, "%10u", attr->med);
9087 else if (!json_paths) {
9088 if (wide)
9089 vty_out(vty, "%*s", 7, " ");
9090 else
9091 vty_out(vty, "%*s", 10, " ");
9092 }
9093
9094 /* Local Pref */
9095 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9096 if (json_paths)
9097 json_object_int_add(json_path, "locPrf",
9098 attr->local_pref);
9099 else
9100 vty_out(vty, "%7u", attr->local_pref);
9101 else if (!json_paths)
9102 vty_out(vty, " ");
9103
9104 if (json_paths)
9105 json_object_int_add(json_path, "weight", attr->weight);
9106 else
9107 vty_out(vty, "%7u ", attr->weight);
9108
9109 if (json_paths) {
9110 char buf[BUFSIZ];
9111 json_object_string_add(
9112 json_path, "peerId",
9113 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
9114 }
9115
9116 /* Print aspath */
9117 if (attr->aspath) {
9118 if (json_paths)
9119 json_object_string_add(json_path, "path",
9120 attr->aspath->str);
9121 else
9122 aspath_print_vty(vty, "%s", attr->aspath, " ");
9123 }
9124
9125 /* Print origin */
9126 if (json_paths)
9127 json_object_string_add(json_path, "origin",
9128 bgp_origin_long_str[attr->origin]);
9129 else
9130 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9131
9132 if (json_paths) {
9133 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9134 json_object_string_add(json_path, "esi",
9135 esi_to_str(&attr->esi,
9136 esi_buf, sizeof(esi_buf)));
9137 }
9138 if (safi == SAFI_EVPN &&
9139 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9140 json_ext_community = json_object_new_object();
9141 json_object_string_add(json_ext_community,
9142 "string",
9143 attr->ecommunity->str);
9144 json_object_object_add(json_path,
9145 "extendedCommunity",
9146 json_ext_community);
9147 }
9148
9149 if (nexthop_self)
9150 json_object_boolean_true_add(json_path,
9151 "announceNexthopSelf");
9152 if (nexthop_othervrf) {
9153 json_object_string_add(json_path, "nhVrfName",
9154 nexthop_vrfname);
9155
9156 json_object_int_add(json_path, "nhVrfId",
9157 ((nexthop_vrfid == VRF_UNKNOWN)
9158 ? -1
9159 : (int)nexthop_vrfid));
9160 }
9161 }
9162
9163 if (json_paths) {
9164 if (json_nexthop_global || json_nexthop_ll) {
9165 json_nexthops = json_object_new_array();
9166
9167 if (json_nexthop_global)
9168 json_object_array_add(json_nexthops,
9169 json_nexthop_global);
9170
9171 if (json_nexthop_ll)
9172 json_object_array_add(json_nexthops,
9173 json_nexthop_ll);
9174
9175 json_object_object_add(json_path, "nexthops",
9176 json_nexthops);
9177 }
9178
9179 json_object_array_add(json_paths, json_path);
9180 } else {
9181 vty_out(vty, "\n");
9182
9183 if (safi == SAFI_EVPN) {
9184 if (bgp_evpn_is_esi_valid(&attr->esi)) {
9185 /* XXX - add these params to the json out */
9186 vty_out(vty, "%*s", 20, " ");
9187 vty_out(vty, "ESI:%s",
9188 esi_to_str(&attr->esi, esi_buf,
9189 sizeof(esi_buf)));
9190
9191 vty_out(vty, "\n");
9192 }
9193 if (attr->flag &
9194 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
9195 vty_out(vty, "%*s", 20, " ");
9196 vty_out(vty, "%s\n", attr->ecommunity->str);
9197 }
9198 }
9199
9200 #ifdef ENABLE_BGP_VNC
9201 /* prints an additional line, indented, with VNC info, if
9202 * present */
9203 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9204 rfapi_vty_out_vncinfo(vty, p, path, safi);
9205 #endif
9206 }
9207 }
9208
9209 /* called from terminal list command */
9210 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9211 const struct prefix *p, struct attr *attr, safi_t safi,
9212 bool use_json, json_object *json_ar, bool wide)
9213 {
9214 json_object *json_status = NULL;
9215 json_object *json_net = NULL;
9216 int len;
9217 char buff[BUFSIZ];
9218
9219 /* Route status display. */
9220 if (use_json) {
9221 json_status = json_object_new_object();
9222 json_net = json_object_new_object();
9223 } else {
9224 vty_out(vty, "*");
9225 vty_out(vty, ">");
9226 vty_out(vty, " ");
9227 }
9228
9229 /* print prefix and mask */
9230 if (use_json) {
9231 if (safi == SAFI_EVPN)
9232 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9233 else if (p->family == AF_INET || p->family == AF_INET6) {
9234 json_object_string_add(
9235 json_net, "addrPrefix",
9236 inet_ntop(p->family, &p->u.prefix, buff,
9237 BUFSIZ));
9238 json_object_int_add(json_net, "prefixLen",
9239 p->prefixlen);
9240 json_object_string_addf(json_net, "network", "%pFX", p);
9241 }
9242 } else
9243 route_vty_out_route(dest, p, vty, NULL, wide);
9244
9245 /* Print attribute */
9246 if (attr) {
9247 if (use_json) {
9248 if (p->family == AF_INET
9249 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9250 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9251 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9252 json_object_string_addf(
9253 json_net, "nextHop", "%pI4",
9254 &attr->mp_nexthop_global_in);
9255 else
9256 json_object_string_addf(
9257 json_net, "nextHop", "%pI4",
9258 &attr->nexthop);
9259 } else if (p->family == AF_INET6
9260 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9261 json_object_string_addf(
9262 json_net, "nextHopGlobal", "%pI6",
9263 &attr->mp_nexthop_global);
9264 } else if (p->family == AF_EVPN
9265 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9266 json_object_string_addf(
9267 json_net, "nextHop", "%pI4",
9268 &attr->mp_nexthop_global_in);
9269 }
9270
9271 if (attr->flag
9272 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9273 json_object_int_add(json_net, "metric",
9274 attr->med);
9275
9276 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9277 json_object_int_add(json_net, "locPrf",
9278 attr->local_pref);
9279
9280 json_object_int_add(json_net, "weight", attr->weight);
9281
9282 /* Print aspath */
9283 if (attr->aspath)
9284 json_object_string_add(json_net, "path",
9285 attr->aspath->str);
9286
9287 /* Print origin */
9288 json_object_string_add(json_net, "bgpOriginCode",
9289 bgp_origin_str[attr->origin]);
9290 } else {
9291 if (p->family == AF_INET
9292 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9293 || safi == SAFI_EVPN
9294 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9295 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9296 || safi == SAFI_EVPN)
9297 vty_out(vty, "%-16pI4",
9298 &attr->mp_nexthop_global_in);
9299 else if (wide)
9300 vty_out(vty, "%-41pI4", &attr->nexthop);
9301 else
9302 vty_out(vty, "%-16pI4", &attr->nexthop);
9303 } else if (p->family == AF_INET6
9304 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9305 char buf[BUFSIZ];
9306
9307 len = vty_out(
9308 vty, "%s",
9309 inet_ntop(AF_INET6,
9310 &attr->mp_nexthop_global, buf,
9311 BUFSIZ));
9312 len = wide ? (41 - len) : (16 - len);
9313 if (len < 1)
9314 vty_out(vty, "\n%*s", 36, " ");
9315 else
9316 vty_out(vty, "%*s", len, " ");
9317 }
9318 if (attr->flag
9319 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9320 if (wide)
9321 vty_out(vty, "%7u", attr->med);
9322 else
9323 vty_out(vty, "%10u", attr->med);
9324 else if (wide)
9325 vty_out(vty, " ");
9326 else
9327 vty_out(vty, " ");
9328
9329 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9330 vty_out(vty, "%7u", attr->local_pref);
9331 else
9332 vty_out(vty, " ");
9333
9334 vty_out(vty, "%7u ", attr->weight);
9335
9336 /* Print aspath */
9337 if (attr->aspath)
9338 aspath_print_vty(vty, "%s", attr->aspath, " ");
9339
9340 /* Print origin */
9341 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9342 }
9343 }
9344 if (use_json) {
9345 json_object_boolean_true_add(json_status, "*");
9346 json_object_boolean_true_add(json_status, ">");
9347 json_object_object_add(json_net, "appliedStatusSymbols",
9348 json_status);
9349
9350 prefix2str(p, buff, PREFIX_STRLEN);
9351 json_object_object_add(json_ar, buff, json_net);
9352 } else
9353 vty_out(vty, "\n");
9354 }
9355
9356 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9357 struct bgp_path_info *path, int display, safi_t safi,
9358 json_object *json)
9359 {
9360 json_object *json_out = NULL;
9361 struct attr *attr;
9362 mpls_label_t label = MPLS_INVALID_LABEL;
9363
9364 if (!path->extra)
9365 return;
9366
9367 if (json)
9368 json_out = json_object_new_object();
9369
9370 /* short status lead text */
9371 route_vty_short_status_out(vty, path, p, json_out);
9372
9373 /* print prefix and mask */
9374 if (json == NULL) {
9375 if (!display)
9376 route_vty_out_route(path->net, p, vty, NULL, false);
9377 else
9378 vty_out(vty, "%*s", 17, " ");
9379 }
9380
9381 /* Print attribute */
9382 attr = path->attr;
9383 if (((p->family == AF_INET)
9384 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9385 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9386 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9387 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9388 || safi == SAFI_EVPN) {
9389 if (json)
9390 json_object_string_addf(
9391 json_out, "mpNexthopGlobalIn", "%pI4",
9392 &attr->mp_nexthop_global_in);
9393 else
9394 vty_out(vty, "%-16pI4",
9395 &attr->mp_nexthop_global_in);
9396 } else {
9397 if (json)
9398 json_object_string_addf(json_out, "nexthop",
9399 "%pI4", &attr->nexthop);
9400 else
9401 vty_out(vty, "%-16pI4", &attr->nexthop);
9402 }
9403 } else if (((p->family == AF_INET6)
9404 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9405 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9406 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9407 char buf_a[512];
9408
9409 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9410 if (json)
9411 json_object_string_addf(
9412 json_out, "mpNexthopGlobalIn", "%pI6",
9413 &attr->mp_nexthop_global);
9414 else
9415 vty_out(vty, "%s",
9416 inet_ntop(AF_INET6,
9417 &attr->mp_nexthop_global,
9418 buf_a, sizeof(buf_a)));
9419 } else if (attr->mp_nexthop_len
9420 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9421 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9422 &attr->mp_nexthop_global,
9423 &attr->mp_nexthop_local);
9424 if (json)
9425 json_object_string_add(json_out,
9426 "mpNexthopGlobalLocal",
9427 buf_a);
9428 else
9429 vty_out(vty, "%s", buf_a);
9430 }
9431 }
9432
9433 label = decode_label(&path->extra->label[0]);
9434
9435 if (bgp_is_valid_label(&label)) {
9436 if (json) {
9437 json_object_int_add(json_out, "notag", label);
9438 json_object_array_add(json, json_out);
9439 } else {
9440 vty_out(vty, "notag/%d", label);
9441 vty_out(vty, "\n");
9442 }
9443 } else if (!json)
9444 vty_out(vty, "\n");
9445 }
9446
9447 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9448 struct bgp_path_info *path, int display,
9449 json_object *json_paths)
9450 {
9451 struct attr *attr;
9452 char buf[BUFSIZ] = {0};
9453 json_object *json_path = NULL;
9454 json_object *json_nexthop = NULL;
9455 json_object *json_overlay = NULL;
9456
9457 if (!path->extra)
9458 return;
9459
9460 if (json_paths) {
9461 json_path = json_object_new_object();
9462 json_overlay = json_object_new_object();
9463 json_nexthop = json_object_new_object();
9464 }
9465
9466 /* short status lead text */
9467 route_vty_short_status_out(vty, path, p, json_path);
9468
9469 /* print prefix and mask */
9470 if (!display)
9471 route_vty_out_route(path->net, p, vty, json_path, false);
9472 else
9473 vty_out(vty, "%*s", 17, " ");
9474
9475 /* Print attribute */
9476 attr = path->attr;
9477 char buf1[BUFSIZ];
9478 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9479
9480 switch (af) {
9481 case AF_INET:
9482 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
9483 if (!json_path) {
9484 vty_out(vty, "%-16s", buf);
9485 } else {
9486 json_object_string_add(json_nexthop, "ip", buf);
9487
9488 json_object_string_add(json_nexthop, "afi", "ipv4");
9489
9490 json_object_object_add(json_path, "nexthop",
9491 json_nexthop);
9492 }
9493 break;
9494 case AF_INET6:
9495 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
9496 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
9497 if (!json_path) {
9498 vty_out(vty, "%s(%s)", buf, buf1);
9499 } else {
9500 json_object_string_add(json_nexthop, "ipv6Global", buf);
9501
9502 json_object_string_add(json_nexthop, "ipv6LinkLocal",
9503 buf1);
9504
9505 json_object_string_add(json_nexthop, "afi", "ipv6");
9506
9507 json_object_object_add(json_path, "nexthop",
9508 json_nexthop);
9509 }
9510 break;
9511 default:
9512 if (!json_path) {
9513 vty_out(vty, "?");
9514 } else {
9515 json_object_string_add(json_nexthop, "Error",
9516 "Unsupported address-family");
9517 }
9518 }
9519
9520 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9521
9522 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p))
9523 inet_ntop(AF_INET, &eo->gw_ip.ipv4, buf, BUFSIZ);
9524 else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p))
9525 inet_ntop(AF_INET6, &eo->gw_ip.ipv6, buf, BUFSIZ);
9526
9527 if (!json_path)
9528 vty_out(vty, "/%s", buf);
9529 else
9530 json_object_string_add(json_overlay, "gw", buf);
9531
9532 if (attr->ecommunity) {
9533 char *mac = NULL;
9534 struct ecommunity_val *routermac = ecommunity_lookup(
9535 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
9536 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9537
9538 if (routermac)
9539 mac = ecom_mac2str((char *)routermac->val);
9540 if (mac) {
9541 if (!json_path) {
9542 vty_out(vty, "/%s", mac);
9543 } else {
9544 json_object_string_add(json_overlay, "rmac",
9545 mac);
9546 }
9547 XFREE(MTYPE_TMP, mac);
9548 }
9549 }
9550
9551 if (!json_path) {
9552 vty_out(vty, "\n");
9553 } else {
9554 json_object_object_add(json_path, "overlay", json_overlay);
9555
9556 json_object_array_add(json_paths, json_path);
9557 }
9558 }
9559
9560 /* dampening route */
9561 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9562 struct bgp_path_info *path, int display,
9563 afi_t afi, safi_t safi, bool use_json,
9564 json_object *json_paths)
9565 {
9566 struct attr *attr = path->attr;
9567 int len;
9568 char timebuf[BGP_UPTIME_LEN];
9569 json_object *json_path = NULL;
9570
9571 if (use_json)
9572 json_path = json_object_new_object();
9573
9574 /* short status lead text */
9575 route_vty_short_status_out(vty, path, p, json_path);
9576
9577 /* print prefix and mask */
9578 if (!use_json) {
9579 if (!display)
9580 route_vty_out_route(path->net, p, vty, NULL, false);
9581 else
9582 vty_out(vty, "%*s", 17, " ");
9583
9584 len = vty_out(vty, "%s", path->peer->host);
9585 len = 17 - len;
9586
9587 if (len < 1)
9588 vty_out(vty, "\n%*s", 34, " ");
9589 else
9590 vty_out(vty, "%*s", len, " ");
9591
9592 vty_out(vty, "%s ",
9593 bgp_damp_reuse_time_vty(vty, path, timebuf,
9594 BGP_UPTIME_LEN, afi, safi,
9595 use_json, NULL));
9596
9597 if (attr->aspath)
9598 aspath_print_vty(vty, "%s", attr->aspath, " ");
9599
9600 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9601
9602 vty_out(vty, "\n");
9603 } else {
9604 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9605 safi, use_json, json_path);
9606
9607 if (attr->aspath)
9608 json_object_string_add(json_path, "asPath",
9609 attr->aspath->str);
9610
9611 json_object_string_add(json_path, "origin",
9612 bgp_origin_str[attr->origin]);
9613 json_object_string_add(json_path, "peerHost", path->peer->host);
9614
9615 json_object_array_add(json_paths, json_path);
9616 }
9617 }
9618
9619 /* flap route */
9620 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9621 struct bgp_path_info *path, int display,
9622 afi_t afi, safi_t safi, bool use_json,
9623 json_object *json_paths)
9624 {
9625 struct attr *attr = path->attr;
9626 struct bgp_damp_info *bdi;
9627 char timebuf[BGP_UPTIME_LEN];
9628 int len;
9629 json_object *json_path = NULL;
9630
9631 if (!path->extra)
9632 return;
9633
9634 if (use_json)
9635 json_path = json_object_new_object();
9636
9637 bdi = path->extra->damp_info;
9638
9639 /* short status lead text */
9640 route_vty_short_status_out(vty, path, p, json_path);
9641
9642 if (!use_json) {
9643 if (!display)
9644 route_vty_out_route(path->net, p, vty, NULL, false);
9645 else
9646 vty_out(vty, "%*s", 17, " ");
9647
9648 len = vty_out(vty, "%s", path->peer->host);
9649 len = 16 - len;
9650 if (len < 1)
9651 vty_out(vty, "\n%*s", 33, " ");
9652 else
9653 vty_out(vty, "%*s", len, " ");
9654
9655 len = vty_out(vty, "%d", bdi->flap);
9656 len = 5 - len;
9657 if (len < 1)
9658 vty_out(vty, " ");
9659 else
9660 vty_out(vty, "%*s", len, " ");
9661
9662 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9663 BGP_UPTIME_LEN, 0, NULL));
9664
9665 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9666 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9667 vty_out(vty, "%s ",
9668 bgp_damp_reuse_time_vty(vty, path, timebuf,
9669 BGP_UPTIME_LEN, afi,
9670 safi, use_json, NULL));
9671 else
9672 vty_out(vty, "%*s ", 8, " ");
9673
9674 if (attr->aspath)
9675 aspath_print_vty(vty, "%s", attr->aspath, " ");
9676
9677 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9678
9679 vty_out(vty, "\n");
9680 } else {
9681 json_object_string_add(json_path, "peerHost", path->peer->host);
9682 json_object_int_add(json_path, "bdiFlap", bdi->flap);
9683
9684 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9685 json_path);
9686
9687 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9688 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9689 bgp_damp_reuse_time_vty(vty, path, timebuf,
9690 BGP_UPTIME_LEN, afi, safi,
9691 use_json, json_path);
9692
9693 if (attr->aspath)
9694 json_object_string_add(json_path, "asPath",
9695 attr->aspath->str);
9696
9697 json_object_string_add(json_path, "origin",
9698 bgp_origin_str[attr->origin]);
9699
9700 json_object_array_add(json_paths, json_path);
9701 }
9702 }
9703
9704 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9705 int *first, const char *header,
9706 json_object *json_adv_to)
9707 {
9708 char buf1[INET6_ADDRSTRLEN];
9709 json_object *json_peer = NULL;
9710
9711 if (json_adv_to) {
9712 /* 'advertised-to' is a dictionary of peers we have advertised
9713 * this
9714 * prefix too. The key is the peer's IP or swpX, the value is
9715 * the
9716 * hostname if we know it and "" if not.
9717 */
9718 json_peer = json_object_new_object();
9719
9720 if (peer->hostname)
9721 json_object_string_add(json_peer, "hostname",
9722 peer->hostname);
9723
9724 if (peer->conf_if)
9725 json_object_object_add(json_adv_to, peer->conf_if,
9726 json_peer);
9727 else
9728 json_object_object_add(
9729 json_adv_to,
9730 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
9731 json_peer);
9732 } else {
9733 if (*first) {
9734 vty_out(vty, "%s", header);
9735 *first = 0;
9736 }
9737
9738 if (peer->hostname
9739 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9740 if (peer->conf_if)
9741 vty_out(vty, " %s(%s)", peer->hostname,
9742 peer->conf_if);
9743 else
9744 vty_out(vty, " %s(%s)", peer->hostname,
9745 sockunion2str(&peer->su, buf1,
9746 SU_ADDRSTRLEN));
9747 } else {
9748 if (peer->conf_if)
9749 vty_out(vty, " %s", peer->conf_if);
9750 else
9751 vty_out(vty, " %s",
9752 sockunion2str(&peer->su, buf1,
9753 SU_ADDRSTRLEN));
9754 }
9755 }
9756 }
9757
9758 static void route_vty_out_tx_ids(struct vty *vty,
9759 struct bgp_addpath_info_data *d)
9760 {
9761 int i;
9762
9763 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9764 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9765 d->addpath_tx_id[i],
9766 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9767 }
9768 }
9769
9770 static void route_vty_out_detail_es_info(struct vty *vty,
9771 struct bgp_path_info *pi,
9772 struct attr *attr,
9773 json_object *json_path)
9774 {
9775 char esi_buf[ESI_STR_LEN];
9776 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9777 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9778 ATTR_ES_PEER_ROUTER);
9779 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9780 ATTR_ES_PEER_ACTIVE);
9781 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9782 ATTR_ES_PEER_PROXY);
9783 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9784 if (json_path) {
9785 json_object *json_es_info = NULL;
9786
9787 json_object_string_add(
9788 json_path, "esi",
9789 esi_buf);
9790 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9791 json_es_info = json_object_new_object();
9792 if (es_local)
9793 json_object_boolean_true_add(
9794 json_es_info, "localEs");
9795 if (peer_active)
9796 json_object_boolean_true_add(
9797 json_es_info, "peerActive");
9798 if (peer_proxy)
9799 json_object_boolean_true_add(
9800 json_es_info, "peerProxy");
9801 if (peer_router)
9802 json_object_boolean_true_add(
9803 json_es_info, "peerRouter");
9804 if (attr->mm_sync_seqnum)
9805 json_object_int_add(
9806 json_es_info, "peerSeq",
9807 attr->mm_sync_seqnum);
9808 json_object_object_add(
9809 json_path, "es_info",
9810 json_es_info);
9811 }
9812 } else {
9813 if (bgp_evpn_attr_is_sync(attr))
9814 vty_out(vty,
9815 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9816 esi_buf,
9817 es_local ? "local-es":"",
9818 peer_proxy ? "proxy " : "",
9819 peer_active ? "active ":"",
9820 peer_router ? "router ":"",
9821 attr->mm_sync_seqnum);
9822 else
9823 vty_out(vty, " ESI %s %s\n",
9824 esi_buf,
9825 es_local ? "local-es":"");
9826 }
9827 }
9828
9829 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
9830 struct bgp_path_info *path, afi_t afi, safi_t safi,
9831 enum rpki_states rpki_curr_state,
9832 json_object *json_paths)
9833 {
9834 char buf[INET6_ADDRSTRLEN];
9835 char buf1[BUFSIZ];
9836 struct attr *attr = path->attr;
9837 int sockunion_vty_out(struct vty *, union sockunion *);
9838 time_t tbuf;
9839 json_object *json_bestpath = NULL;
9840 json_object *json_cluster_list = NULL;
9841 json_object *json_cluster_list_list = NULL;
9842 json_object *json_ext_community = NULL;
9843 json_object *json_last_update = NULL;
9844 json_object *json_pmsi = NULL;
9845 json_object *json_nexthop_global = NULL;
9846 json_object *json_nexthop_ll = NULL;
9847 json_object *json_nexthops = NULL;
9848 json_object *json_path = NULL;
9849 json_object *json_peer = NULL;
9850 json_object *json_string = NULL;
9851 json_object *json_adv_to = NULL;
9852 int first = 0;
9853 struct listnode *node, *nnode;
9854 struct peer *peer;
9855 int addpath_capable;
9856 int has_adj;
9857 unsigned int first_as;
9858 bool nexthop_self =
9859 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9860 int i;
9861 char *nexthop_hostname =
9862 bgp_nexthop_hostname(path->peer, path->nexthop);
9863
9864 if (json_paths) {
9865 json_path = json_object_new_object();
9866 json_peer = json_object_new_object();
9867 json_nexthop_global = json_object_new_object();
9868 }
9869
9870 if (safi == SAFI_EVPN) {
9871 if (!json_paths)
9872 vty_out(vty, " Route %pRN", bn);
9873 }
9874
9875 if (path->extra) {
9876 char tag_buf[30];
9877
9878 tag_buf[0] = '\0';
9879 if (path->extra && path->extra->num_labels) {
9880 bgp_evpn_label2str(path->extra->label,
9881 path->extra->num_labels, tag_buf,
9882 sizeof(tag_buf));
9883 }
9884 if (safi == SAFI_EVPN) {
9885 if (!json_paths) {
9886 if (tag_buf[0] != '\0')
9887 vty_out(vty, " VNI %s", tag_buf);
9888 } else {
9889 if (tag_buf[0])
9890 json_object_string_add(json_path, "VNI",
9891 tag_buf);
9892 }
9893 }
9894
9895 if (path->extra && path->extra->parent && !json_paths) {
9896 struct bgp_path_info *parent_ri;
9897 struct bgp_dest *dest, *pdest;
9898
9899 parent_ri = (struct bgp_path_info *)path->extra->parent;
9900 dest = parent_ri->net;
9901 if (dest && dest->pdest) {
9902 pdest = dest->pdest;
9903 prefix_rd2str(
9904 (struct prefix_rd *)bgp_dest_get_prefix(
9905 pdest),
9906 buf1, sizeof(buf1));
9907 if (is_pi_family_evpn(parent_ri)) {
9908 vty_out(vty,
9909 " Imported from %s:%pFX, VNI %s",
9910 buf1,
9911 (struct prefix_evpn *)
9912 bgp_dest_get_prefix(
9913 dest),
9914 tag_buf);
9915 if (attr->es_flags & ATTR_ES_L3_NHG)
9916 vty_out(vty, ", L3NHG %s",
9917 (attr->es_flags
9918 & ATTR_ES_L3_NHG_ACTIVE)
9919 ? "active"
9920 : "inactive");
9921 vty_out(vty, "\n");
9922
9923 } else
9924 vty_out(vty,
9925 " Imported from %s:%pFX\n",
9926 buf1,
9927 (struct prefix_evpn *)
9928 bgp_dest_get_prefix(
9929 dest));
9930 }
9931 }
9932 }
9933
9934 if (safi == SAFI_EVPN
9935 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
9936 char gwip_buf[INET6_ADDRSTRLEN];
9937
9938 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)&bn->p))
9939 inet_ntop(AF_INET, &attr->evpn_overlay.gw_ip.ipv4,
9940 gwip_buf, sizeof(gwip_buf));
9941 else
9942 inet_ntop(AF_INET6, &attr->evpn_overlay.gw_ip.ipv6,
9943 gwip_buf, sizeof(gwip_buf));
9944
9945 if (json_paths)
9946 json_object_string_add(json_path, "gatewayIP",
9947 gwip_buf);
9948 else
9949 vty_out(vty, " Gateway IP %s", gwip_buf);
9950 }
9951
9952 if (safi == SAFI_EVPN)
9953 vty_out(vty, "\n");
9954
9955 /* Line1 display AS-path, Aggregator */
9956 if (attr->aspath) {
9957 if (json_paths) {
9958 if (!attr->aspath->json)
9959 aspath_str_update(attr->aspath, true);
9960 json_object_lock(attr->aspath->json);
9961 json_object_object_add(json_path, "aspath",
9962 attr->aspath->json);
9963 } else {
9964 if (attr->aspath->segments)
9965 aspath_print_vty(vty, " %s", attr->aspath, "");
9966 else
9967 vty_out(vty, " Local");
9968 }
9969 }
9970
9971 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9972 if (json_paths)
9973 json_object_boolean_true_add(json_path, "removed");
9974 else
9975 vty_out(vty, ", (removed)");
9976 }
9977
9978 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9979 if (json_paths)
9980 json_object_boolean_true_add(json_path, "stale");
9981 else
9982 vty_out(vty, ", (stale)");
9983 }
9984
9985 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
9986 if (json_paths) {
9987 json_object_int_add(json_path, "aggregatorAs",
9988 attr->aggregator_as);
9989 json_object_string_addf(json_path, "aggregatorId",
9990 "%pI4", &attr->aggregator_addr);
9991 } else {
9992 vty_out(vty, ", (aggregated by %u %pI4)",
9993 attr->aggregator_as, &attr->aggregator_addr);
9994 }
9995 }
9996
9997 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9998 PEER_FLAG_REFLECTOR_CLIENT)) {
9999 if (json_paths)
10000 json_object_boolean_true_add(json_path,
10001 "rxedFromRrClient");
10002 else
10003 vty_out(vty, ", (Received from a RR-client)");
10004 }
10005
10006 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
10007 PEER_FLAG_RSERVER_CLIENT)) {
10008 if (json_paths)
10009 json_object_boolean_true_add(json_path,
10010 "rxedFromRsClient");
10011 else
10012 vty_out(vty, ", (Received from a RS-client)");
10013 }
10014
10015 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10016 if (json_paths)
10017 json_object_boolean_true_add(json_path,
10018 "dampeningHistoryEntry");
10019 else
10020 vty_out(vty, ", (history entry)");
10021 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
10022 if (json_paths)
10023 json_object_boolean_true_add(json_path,
10024 "dampeningSuppressed");
10025 else
10026 vty_out(vty, ", (suppressed due to dampening)");
10027 }
10028
10029 if (!json_paths)
10030 vty_out(vty, "\n");
10031
10032 /* Line2 display Next-hop, Neighbor, Router-id */
10033 /* Display the nexthop */
10034 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
10035
10036 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
10037 || bn_p->family == AF_EVPN)
10038 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
10039 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
10040 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
10041 || safi == SAFI_EVPN) {
10042 if (json_paths) {
10043 json_object_string_addf(
10044 json_nexthop_global, "ip", "%pI4",
10045 &attr->mp_nexthop_global_in);
10046
10047 if (path->peer->hostname)
10048 json_object_string_add(
10049 json_nexthop_global, "hostname",
10050 path->peer->hostname);
10051 } else {
10052 if (nexthop_hostname)
10053 vty_out(vty, " %pI4(%s)",
10054 &attr->mp_nexthop_global_in,
10055 nexthop_hostname);
10056 else
10057 vty_out(vty, " %pI4",
10058 &attr->mp_nexthop_global_in);
10059 }
10060 } else {
10061 if (json_paths) {
10062 json_object_string_addf(json_nexthop_global,
10063 "ip", "%pI4",
10064 &attr->nexthop);
10065
10066 if (path->peer->hostname)
10067 json_object_string_add(
10068 json_nexthop_global, "hostname",
10069 path->peer->hostname);
10070 } else {
10071 if (nexthop_hostname)
10072 vty_out(vty, " %pI4(%s)",
10073 &attr->nexthop,
10074 nexthop_hostname);
10075 else
10076 vty_out(vty, " %pI4",
10077 &attr->nexthop);
10078 }
10079 }
10080
10081 if (json_paths)
10082 json_object_string_add(json_nexthop_global, "afi",
10083 "ipv4");
10084 } else {
10085 if (json_paths) {
10086 json_object_string_addf(json_nexthop_global, "ip",
10087 "%pI6",
10088 &attr->mp_nexthop_global);
10089
10090 if (path->peer->hostname)
10091 json_object_string_add(json_nexthop_global,
10092 "hostname",
10093 path->peer->hostname);
10094
10095 json_object_string_add(json_nexthop_global, "afi",
10096 "ipv6");
10097 json_object_string_add(json_nexthop_global, "scope",
10098 "global");
10099 } else {
10100 if (nexthop_hostname)
10101 vty_out(vty, " %pI6(%s)",
10102 &attr->mp_nexthop_global,
10103 nexthop_hostname);
10104 else
10105 vty_out(vty, " %pI6",
10106 &attr->mp_nexthop_global);
10107 }
10108 }
10109
10110 /* Display the IGP cost or 'inaccessible' */
10111 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10112 if (json_paths)
10113 json_object_boolean_false_add(json_nexthop_global,
10114 "accessible");
10115 else
10116 vty_out(vty, " (inaccessible)");
10117 } else {
10118 if (path->extra && path->extra->igpmetric) {
10119 if (json_paths)
10120 json_object_int_add(json_nexthop_global,
10121 "metric",
10122 path->extra->igpmetric);
10123 else
10124 vty_out(vty, " (metric %u)",
10125 path->extra->igpmetric);
10126 }
10127
10128 /* IGP cost is 0, display this only for json */
10129 else {
10130 if (json_paths)
10131 json_object_int_add(json_nexthop_global,
10132 "metric", 0);
10133 }
10134
10135 if (json_paths)
10136 json_object_boolean_true_add(json_nexthop_global,
10137 "accessible");
10138 }
10139
10140 /* Display peer "from" output */
10141 /* This path was originated locally */
10142 if (path->peer == bgp->peer_self) {
10143
10144 if (safi == SAFI_EVPN
10145 || (bn_p->family == AF_INET
10146 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
10147 if (json_paths)
10148 json_object_string_add(json_peer, "peerId",
10149 "0.0.0.0");
10150 else
10151 vty_out(vty, " from 0.0.0.0 ");
10152 } else {
10153 if (json_paths)
10154 json_object_string_add(json_peer, "peerId",
10155 "::");
10156 else
10157 vty_out(vty, " from :: ");
10158 }
10159
10160 if (json_paths)
10161 json_object_string_addf(json_peer, "routerId", "%pI4",
10162 &bgp->router_id);
10163 else
10164 vty_out(vty, "(%pI4)", &bgp->router_id);
10165 }
10166
10167 /* We RXed this path from one of our peers */
10168 else {
10169
10170 if (json_paths) {
10171 json_object_string_add(json_peer, "peerId",
10172 sockunion2str(&path->peer->su,
10173 buf,
10174 SU_ADDRSTRLEN));
10175 json_object_string_addf(json_peer, "routerId", "%pI4",
10176 &path->peer->remote_id);
10177
10178 if (path->peer->hostname)
10179 json_object_string_add(json_peer, "hostname",
10180 path->peer->hostname);
10181
10182 if (path->peer->domainname)
10183 json_object_string_add(json_peer, "domainname",
10184 path->peer->domainname);
10185
10186 if (path->peer->conf_if)
10187 json_object_string_add(json_peer, "interface",
10188 path->peer->conf_if);
10189 } else {
10190 if (path->peer->conf_if) {
10191 if (path->peer->hostname
10192 && CHECK_FLAG(path->peer->bgp->flags,
10193 BGP_FLAG_SHOW_HOSTNAME))
10194 vty_out(vty, " from %s(%s)",
10195 path->peer->hostname,
10196 path->peer->conf_if);
10197 else
10198 vty_out(vty, " from %s",
10199 path->peer->conf_if);
10200 } else {
10201 if (path->peer->hostname
10202 && CHECK_FLAG(path->peer->bgp->flags,
10203 BGP_FLAG_SHOW_HOSTNAME))
10204 vty_out(vty, " from %s(%s)",
10205 path->peer->hostname,
10206 path->peer->host);
10207 else
10208 vty_out(vty, " from %s",
10209 sockunion2str(&path->peer->su,
10210 buf,
10211 SU_ADDRSTRLEN));
10212 }
10213
10214 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10215 vty_out(vty, " (%pI4)", &attr->originator_id);
10216 else
10217 vty_out(vty, " (%s)",
10218 inet_ntop(AF_INET,
10219 &path->peer->remote_id, buf1,
10220 sizeof(buf1)));
10221 }
10222 }
10223
10224 /*
10225 * Note when vrfid of nexthop is different from that of prefix
10226 */
10227 if (path->extra && path->extra->bgp_orig) {
10228 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10229
10230 if (json_paths) {
10231 const char *vn;
10232
10233 if (path->extra->bgp_orig->inst_type
10234 == BGP_INSTANCE_TYPE_DEFAULT)
10235 vn = VRF_DEFAULT_NAME;
10236 else
10237 vn = path->extra->bgp_orig->name;
10238
10239 json_object_string_add(json_path, "nhVrfName", vn);
10240
10241 if (nexthop_vrfid == VRF_UNKNOWN) {
10242 json_object_int_add(json_path, "nhVrfId", -1);
10243 } else {
10244 json_object_int_add(json_path, "nhVrfId",
10245 (int)nexthop_vrfid);
10246 }
10247 } else {
10248 if (nexthop_vrfid == VRF_UNKNOWN)
10249 vty_out(vty, " vrf ?");
10250 else {
10251 struct vrf *vrf;
10252
10253 vrf = vrf_lookup_by_id(nexthop_vrfid);
10254 vty_out(vty, " vrf %s(%u)",
10255 VRF_LOGNAME(vrf), nexthop_vrfid);
10256 }
10257 }
10258 }
10259
10260 if (nexthop_self) {
10261 if (json_paths) {
10262 json_object_boolean_true_add(json_path,
10263 "announceNexthopSelf");
10264 } else {
10265 vty_out(vty, " announce-nh-self");
10266 }
10267 }
10268
10269 if (!json_paths)
10270 vty_out(vty, "\n");
10271
10272 /* display the link-local nexthop */
10273 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10274 if (json_paths) {
10275 json_nexthop_ll = json_object_new_object();
10276 json_object_string_addf(json_nexthop_ll, "ip", "%pI6",
10277 &attr->mp_nexthop_local);
10278
10279 if (path->peer->hostname)
10280 json_object_string_add(json_nexthop_ll,
10281 "hostname",
10282 path->peer->hostname);
10283
10284 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10285 json_object_string_add(json_nexthop_ll, "scope",
10286 "link-local");
10287
10288 json_object_boolean_true_add(json_nexthop_ll,
10289 "accessible");
10290
10291 if (!attr->mp_nexthop_prefer_global)
10292 json_object_boolean_true_add(json_nexthop_ll,
10293 "used");
10294 else
10295 json_object_boolean_true_add(
10296 json_nexthop_global, "used");
10297 } else {
10298 vty_out(vty, " (%s) %s\n",
10299 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10300 buf, INET6_ADDRSTRLEN),
10301 attr->mp_nexthop_prefer_global
10302 ? "(prefer-global)"
10303 : "(used)");
10304 }
10305 }
10306 /* If we do not have a link-local nexthop then we must flag the
10307 global as "used" */
10308 else {
10309 if (json_paths)
10310 json_object_boolean_true_add(json_nexthop_global,
10311 "used");
10312 }
10313
10314 if (safi == SAFI_EVPN &&
10315 bgp_evpn_is_esi_valid(&attr->esi)) {
10316 route_vty_out_detail_es_info(vty, path, attr, json_path);
10317 }
10318
10319 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10320 * Int/Ext/Local, Atomic, best */
10321 if (json_paths)
10322 json_object_string_add(json_path, "origin",
10323 bgp_origin_long_str[attr->origin]);
10324 else
10325 vty_out(vty, " Origin %s",
10326 bgp_origin_long_str[attr->origin]);
10327
10328 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10329 if (json_paths)
10330 json_object_int_add(json_path, "metric", attr->med);
10331 else
10332 vty_out(vty, ", metric %u", attr->med);
10333 }
10334
10335 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10336 if (json_paths)
10337 json_object_int_add(json_path, "locPrf",
10338 attr->local_pref);
10339 else
10340 vty_out(vty, ", localpref %u", attr->local_pref);
10341 }
10342
10343 if (attr->weight != 0) {
10344 if (json_paths)
10345 json_object_int_add(json_path, "weight", attr->weight);
10346 else
10347 vty_out(vty, ", weight %u", attr->weight);
10348 }
10349
10350 if (attr->tag != 0) {
10351 if (json_paths)
10352 json_object_int_add(json_path, "tag", attr->tag);
10353 else
10354 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10355 }
10356
10357 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10358 if (json_paths)
10359 json_object_boolean_false_add(json_path, "valid");
10360 else
10361 vty_out(vty, ", invalid");
10362 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10363 if (json_paths)
10364 json_object_boolean_true_add(json_path, "valid");
10365 else
10366 vty_out(vty, ", valid");
10367 }
10368
10369 if (json_paths)
10370 json_object_int_add(json_path, "version", bn->version);
10371
10372 if (path->peer != bgp->peer_self) {
10373 if (path->peer->as == path->peer->local_as) {
10374 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10375 if (json_paths)
10376 json_object_string_add(
10377 json_peer, "type",
10378 "confed-internal");
10379 else
10380 vty_out(vty, ", confed-internal");
10381 } else {
10382 if (json_paths)
10383 json_object_string_add(
10384 json_peer, "type", "internal");
10385 else
10386 vty_out(vty, ", internal");
10387 }
10388 } else {
10389 if (bgp_confederation_peers_check(bgp,
10390 path->peer->as)) {
10391 if (json_paths)
10392 json_object_string_add(
10393 json_peer, "type",
10394 "confed-external");
10395 else
10396 vty_out(vty, ", confed-external");
10397 } else {
10398 if (json_paths)
10399 json_object_string_add(
10400 json_peer, "type", "external");
10401 else
10402 vty_out(vty, ", external");
10403 }
10404 }
10405 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10406 if (json_paths) {
10407 json_object_boolean_true_add(json_path, "aggregated");
10408 json_object_boolean_true_add(json_path, "local");
10409 } else {
10410 vty_out(vty, ", aggregated, local");
10411 }
10412 } else if (path->type != ZEBRA_ROUTE_BGP) {
10413 if (json_paths)
10414 json_object_boolean_true_add(json_path, "sourced");
10415 else
10416 vty_out(vty, ", sourced");
10417 } else {
10418 if (json_paths) {
10419 json_object_boolean_true_add(json_path, "sourced");
10420 json_object_boolean_true_add(json_path, "local");
10421 } else {
10422 vty_out(vty, ", sourced, local");
10423 }
10424 }
10425
10426 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10427 if (json_paths)
10428 json_object_boolean_true_add(json_path,
10429 "atomicAggregate");
10430 else
10431 vty_out(vty, ", atomic-aggregate");
10432 }
10433
10434 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10435 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10436 && bgp_path_info_mpath_count(path))) {
10437 if (json_paths)
10438 json_object_boolean_true_add(json_path, "multipath");
10439 else
10440 vty_out(vty, ", multipath");
10441 }
10442
10443 // Mark the bestpath(s)
10444 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10445 first_as = aspath_get_first_as(attr->aspath);
10446
10447 if (json_paths) {
10448 if (!json_bestpath)
10449 json_bestpath = json_object_new_object();
10450 json_object_int_add(json_bestpath, "bestpathFromAs",
10451 first_as);
10452 } else {
10453 if (first_as)
10454 vty_out(vty, ", bestpath-from-AS %u", first_as);
10455 else
10456 vty_out(vty, ", bestpath-from-AS Local");
10457 }
10458 }
10459
10460 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10461 if (json_paths) {
10462 if (!json_bestpath)
10463 json_bestpath = json_object_new_object();
10464 json_object_boolean_true_add(json_bestpath, "overall");
10465 json_object_string_add(
10466 json_bestpath, "selectionReason",
10467 bgp_path_selection_reason2str(bn->reason));
10468 } else {
10469 vty_out(vty, ", best");
10470 vty_out(vty, " (%s)",
10471 bgp_path_selection_reason2str(bn->reason));
10472 }
10473 }
10474
10475 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10476 if (json_paths)
10477 json_object_string_add(
10478 json_path, "rpkiValidationState",
10479 bgp_rpki_validation2str(rpki_curr_state));
10480 else
10481 vty_out(vty, ", rpki validation-state: %s",
10482 bgp_rpki_validation2str(rpki_curr_state));
10483 }
10484
10485 if (json_bestpath)
10486 json_object_object_add(json_path, "bestpath", json_bestpath);
10487
10488 if (!json_paths)
10489 vty_out(vty, "\n");
10490
10491 /* Line 4 display Community */
10492 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10493 if (json_paths) {
10494 if (!attr->community->json)
10495 community_str(attr->community, true);
10496 json_object_lock(attr->community->json);
10497 json_object_object_add(json_path, "community",
10498 attr->community->json);
10499 } else {
10500 vty_out(vty, " Community: %s\n",
10501 attr->community->str);
10502 }
10503 }
10504
10505 /* Line 5 display Extended-community */
10506 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10507 if (json_paths) {
10508 json_ext_community = json_object_new_object();
10509 json_object_string_add(json_ext_community, "string",
10510 attr->ecommunity->str);
10511 json_object_object_add(json_path, "extendedCommunity",
10512 json_ext_community);
10513 } else {
10514 vty_out(vty, " Extended Community: %s\n",
10515 attr->ecommunity->str);
10516 }
10517 }
10518
10519 /* Line 6 display Large community */
10520 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10521 if (json_paths) {
10522 if (!attr->lcommunity->json)
10523 lcommunity_str(attr->lcommunity, true);
10524 json_object_lock(attr->lcommunity->json);
10525 json_object_object_add(json_path, "largeCommunity",
10526 attr->lcommunity->json);
10527 } else {
10528 vty_out(vty, " Large Community: %s\n",
10529 attr->lcommunity->str);
10530 }
10531 }
10532
10533 /* Line 7 display Originator, Cluster-id */
10534 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10535 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10536 char buf[BUFSIZ] = {0};
10537
10538 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10539 if (json_paths)
10540 json_object_string_addf(json_path,
10541 "originatorId", "%pI4",
10542 &attr->originator_id);
10543 else
10544 vty_out(vty, " Originator: %pI4",
10545 &attr->originator_id);
10546 }
10547
10548 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10549 struct cluster_list *cluster =
10550 bgp_attr_get_cluster(attr);
10551 int i;
10552
10553 if (json_paths) {
10554 json_cluster_list = json_object_new_object();
10555 json_cluster_list_list =
10556 json_object_new_array();
10557
10558 for (i = 0; i < cluster->length / 4; i++) {
10559 json_string = json_object_new_string(
10560 inet_ntop(AF_INET,
10561 &cluster->list[i],
10562 buf, sizeof(buf)));
10563 json_object_array_add(
10564 json_cluster_list_list,
10565 json_string);
10566 }
10567
10568 /*
10569 * struct cluster_list does not have
10570 * "str" variable like aspath and community
10571 * do. Add this someday if someone asks
10572 * for it.
10573 * json_object_string_add(json_cluster_list,
10574 * "string", cluster->str);
10575 */
10576 json_object_object_add(json_cluster_list,
10577 "list",
10578 json_cluster_list_list);
10579 json_object_object_add(json_path, "clusterList",
10580 json_cluster_list);
10581 } else {
10582 vty_out(vty, ", Cluster list: ");
10583
10584 for (i = 0; i < cluster->length / 4; i++) {
10585 vty_out(vty, "%pI4 ",
10586 &cluster->list[i]);
10587 }
10588 }
10589 }
10590
10591 if (!json_paths)
10592 vty_out(vty, "\n");
10593 }
10594
10595 if (path->extra && path->extra->damp_info)
10596 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10597
10598 /* Remote Label */
10599 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10600 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10601 mpls_label_t label = label_pton(&path->extra->label[0]);
10602
10603 if (json_paths)
10604 json_object_int_add(json_path, "remoteLabel", label);
10605 else
10606 vty_out(vty, " Remote label: %d\n", label);
10607 }
10608
10609 /* Remote SID */
10610 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10611 inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf));
10612 if (json_paths)
10613 json_object_string_add(json_path, "remoteSid", buf);
10614 else
10615 vty_out(vty, " Remote SID: %s\n", buf);
10616 }
10617
10618 /* Label Index */
10619 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10620 if (json_paths)
10621 json_object_int_add(json_path, "labelIndex",
10622 attr->label_index);
10623 else
10624 vty_out(vty, " Label Index: %d\n",
10625 attr->label_index);
10626 }
10627
10628 /* Line 8 display Addpath IDs */
10629 if (path->addpath_rx_id
10630 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10631 if (json_paths) {
10632 json_object_int_add(json_path, "addpathRxId",
10633 path->addpath_rx_id);
10634
10635 /* Keep backwards compatibility with the old API
10636 * by putting TX All's ID in the old field
10637 */
10638 json_object_int_add(
10639 json_path, "addpathTxId",
10640 path->tx_addpath
10641 .addpath_tx_id[BGP_ADDPATH_ALL]);
10642
10643 /* ... but create a specific field for each
10644 * strategy
10645 */
10646 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10647 json_object_int_add(
10648 json_path,
10649 bgp_addpath_names(i)->id_json_name,
10650 path->tx_addpath.addpath_tx_id[i]);
10651 }
10652 } else {
10653 vty_out(vty, " AddPath ID: RX %u, ",
10654 path->addpath_rx_id);
10655
10656 route_vty_out_tx_ids(vty, &path->tx_addpath);
10657 }
10658 }
10659
10660 /* If we used addpath to TX a non-bestpath we need to display
10661 * "Advertised to" on a path-by-path basis
10662 */
10663 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10664 first = 1;
10665
10666 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10667 addpath_capable =
10668 bgp_addpath_encode_tx(peer, afi, safi);
10669 has_adj = bgp_adj_out_lookup(
10670 peer, path->net,
10671 bgp_addpath_id_for_peer(peer, afi, safi,
10672 &path->tx_addpath));
10673
10674 if ((addpath_capable && has_adj)
10675 || (!addpath_capable && has_adj
10676 && CHECK_FLAG(path->flags,
10677 BGP_PATH_SELECTED))) {
10678 if (json_path && !json_adv_to)
10679 json_adv_to = json_object_new_object();
10680
10681 route_vty_out_advertised_to(
10682 vty, peer, &first,
10683 " Advertised to:", json_adv_to);
10684 }
10685 }
10686
10687 if (json_path) {
10688 if (json_adv_to) {
10689 json_object_object_add(
10690 json_path, "advertisedTo", json_adv_to);
10691 }
10692 } else {
10693 if (!first) {
10694 vty_out(vty, "\n");
10695 }
10696 }
10697 }
10698
10699 /* Line 9 display Uptime */
10700 tbuf = time(NULL) - (bgp_clock() - path->uptime);
10701 if (json_paths) {
10702 json_last_update = json_object_new_object();
10703 json_object_int_add(json_last_update, "epoch", tbuf);
10704 json_object_string_add(json_last_update, "string",
10705 ctime(&tbuf));
10706 json_object_object_add(json_path, "lastUpdate",
10707 json_last_update);
10708 } else
10709 vty_out(vty, " Last update: %s", ctime(&tbuf));
10710
10711 /* Line 10 display PMSI tunnel attribute, if present */
10712 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10713 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10714 bgp_attr_get_pmsi_tnl_type(attr),
10715 PMSI_TNLTYPE_STR_DEFAULT);
10716
10717 if (json_paths) {
10718 json_pmsi = json_object_new_object();
10719 json_object_string_add(json_pmsi, "tunnelType", str);
10720 json_object_int_add(json_pmsi, "label",
10721 label2vni(&attr->label));
10722 json_object_object_add(json_path, "pmsi", json_pmsi);
10723 } else
10724 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10725 str, label2vni(&attr->label));
10726 }
10727
10728 if (path->peer->t_gr_restart &&
10729 CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
10730 unsigned long gr_remaining =
10731 thread_timer_remain_second(path->peer->t_gr_restart);
10732
10733 if (json_paths) {
10734 json_object_int_add(json_path,
10735 "gracefulRestartSecondsRemaining",
10736 gr_remaining);
10737 } else
10738 vty_out(vty,
10739 " Time until Graceful Restart stale route deleted: %lu\n",
10740 gr_remaining);
10741 }
10742
10743 if (path->peer->t_llgr_stale[afi][safi] && attr->community &&
10744 community_include(attr->community, COMMUNITY_LLGR_STALE)) {
10745 unsigned long llgr_remaining = thread_timer_remain_second(
10746 path->peer->t_llgr_stale[afi][safi]);
10747
10748 if (json_paths) {
10749 json_object_int_add(json_path, "llgrSecondsRemaining",
10750 llgr_remaining);
10751 } else
10752 vty_out(vty,
10753 " Time until Long-lived stale route deleted: %lu\n",
10754 llgr_remaining);
10755 }
10756
10757 /* Output some debug about internal state of the dest flags */
10758 if (json_paths) {
10759 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10760 json_object_boolean_true_add(json_path, "processScheduled");
10761 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10762 json_object_boolean_true_add(json_path, "userCleared");
10763 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10764 json_object_boolean_true_add(json_path, "labelChanged");
10765 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10766 json_object_boolean_true_add(json_path, "registeredForLabel");
10767 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10768 json_object_boolean_true_add(json_path, "selectDefered");
10769 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10770 json_object_boolean_true_add(json_path, "fibInstalled");
10771 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10772 json_object_boolean_true_add(json_path, "fibPending");
10773
10774 if (json_nexthop_global || json_nexthop_ll) {
10775 json_nexthops = json_object_new_array();
10776
10777 if (json_nexthop_global)
10778 json_object_array_add(json_nexthops,
10779 json_nexthop_global);
10780
10781 if (json_nexthop_ll)
10782 json_object_array_add(json_nexthops,
10783 json_nexthop_ll);
10784
10785 json_object_object_add(json_path, "nexthops",
10786 json_nexthops);
10787 }
10788
10789 json_object_object_add(json_path, "peer", json_peer);
10790 json_object_array_add(json_paths, json_path);
10791 }
10792 }
10793
10794 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10795 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10796 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10797
10798 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10799 afi_t afi, safi_t safi, enum bgp_show_type type,
10800 bool use_json);
10801 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10802 const char *comstr, int exact, afi_t afi,
10803 safi_t safi, uint16_t show_flags);
10804
10805 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10806 struct bgp_table *table, enum bgp_show_type type,
10807 void *output_arg, const char *rd, int is_last,
10808 unsigned long *output_cum, unsigned long *total_cum,
10809 unsigned long *json_header_depth, uint16_t show_flags,
10810 enum rpki_states rpki_target_state)
10811 {
10812 struct bgp_path_info *pi;
10813 struct bgp_dest *dest;
10814 bool header = true;
10815 bool json_detail_header = false;
10816 int display;
10817 unsigned long output_count = 0;
10818 unsigned long total_count = 0;
10819 struct prefix *p;
10820 json_object *json_paths = NULL;
10821 int first = 1;
10822 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10823 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10824 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10825
10826 if (output_cum && *output_cum != 0)
10827 header = false;
10828
10829 if (use_json && !*json_header_depth) {
10830 if (all)
10831 *json_header_depth = 1;
10832 else {
10833 vty_out(vty, "{\n");
10834 *json_header_depth = 2;
10835 }
10836
10837 vty_out(vty,
10838 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10839 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10840 " \"localAS\": %u,\n \"routes\": { ",
10841 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10842 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
10843 ? VRF_DEFAULT_NAME
10844 : bgp->name,
10845 table->version, &bgp->router_id,
10846 bgp->default_local_pref, bgp->as);
10847 if (rd) {
10848 vty_out(vty, " \"routeDistinguishers\" : {");
10849 ++*json_header_depth;
10850 }
10851 }
10852
10853 if (use_json && rd) {
10854 vty_out(vty, " \"%s\" : { ", rd);
10855 }
10856
10857 /* Check for 'json detail', where we need header output once per dest */
10858 if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
10859 type != bgp_show_type_dampend_paths &&
10860 type != bgp_show_type_damp_neighbor &&
10861 type != bgp_show_type_flap_statistics &&
10862 type != bgp_show_type_flap_neighbor)
10863 json_detail_header = true;
10864
10865 /* Start processing of routes. */
10866 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
10867 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10868 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
10869 bool json_detail = json_detail_header;
10870
10871 pi = bgp_dest_get_bgp_path_info(dest);
10872 if (pi == NULL)
10873 continue;
10874
10875 display = 0;
10876 if (use_json)
10877 json_paths = json_object_new_array();
10878 else
10879 json_paths = NULL;
10880
10881 for (; pi; pi = pi->next) {
10882 total_count++;
10883
10884 if (type == bgp_show_type_prefix_version) {
10885 uint32_t version =
10886 strtoul(output_arg, NULL, 10);
10887 if (dest->version < version)
10888 continue;
10889 }
10890
10891 if (type == bgp_show_type_community_alias) {
10892 char *alias = output_arg;
10893 char **communities;
10894 int num;
10895 bool found = false;
10896
10897 if (pi->attr->community) {
10898 frrstr_split(pi->attr->community->str,
10899 " ", &communities, &num);
10900 for (int i = 0; i < num; i++) {
10901 const char *com2alias =
10902 bgp_community2alias(
10903 communities[i]);
10904 if (!found
10905 && strcmp(alias, com2alias)
10906 == 0)
10907 found = true;
10908 XFREE(MTYPE_TMP,
10909 communities[i]);
10910 }
10911 XFREE(MTYPE_TMP, communities);
10912 }
10913
10914 if (!found && pi->attr->lcommunity) {
10915 frrstr_split(pi->attr->lcommunity->str,
10916 " ", &communities, &num);
10917 for (int i = 0; i < num; i++) {
10918 const char *com2alias =
10919 bgp_community2alias(
10920 communities[i]);
10921 if (!found
10922 && strcmp(alias, com2alias)
10923 == 0)
10924 found = true;
10925 XFREE(MTYPE_TMP,
10926 communities[i]);
10927 }
10928 XFREE(MTYPE_TMP, communities);
10929 }
10930
10931 if (!found)
10932 continue;
10933 }
10934
10935 if (type == bgp_show_type_rpki) {
10936 if (dest_p->family == AF_INET
10937 || dest_p->family == AF_INET6)
10938 rpki_curr_state = hook_call(
10939 bgp_rpki_prefix_status,
10940 pi->peer, pi->attr, dest_p);
10941 if (rpki_target_state != RPKI_NOT_BEING_USED
10942 && rpki_curr_state != rpki_target_state)
10943 continue;
10944 }
10945
10946 if (type == bgp_show_type_flap_statistics
10947 || type == bgp_show_type_flap_neighbor
10948 || type == bgp_show_type_dampend_paths
10949 || type == bgp_show_type_damp_neighbor) {
10950 if (!(pi->extra && pi->extra->damp_info))
10951 continue;
10952 }
10953 if (type == bgp_show_type_regexp) {
10954 regex_t *regex = output_arg;
10955
10956 if (bgp_regexec(regex, pi->attr->aspath)
10957 == REG_NOMATCH)
10958 continue;
10959 }
10960 if (type == bgp_show_type_prefix_list) {
10961 struct prefix_list *plist = output_arg;
10962
10963 if (prefix_list_apply(plist, dest_p)
10964 != PREFIX_PERMIT)
10965 continue;
10966 }
10967 if (type == bgp_show_type_filter_list) {
10968 struct as_list *as_list = output_arg;
10969
10970 if (as_list_apply(as_list, pi->attr->aspath)
10971 != AS_FILTER_PERMIT)
10972 continue;
10973 }
10974 if (type == bgp_show_type_route_map) {
10975 struct route_map *rmap = output_arg;
10976 struct bgp_path_info path;
10977 struct attr dummy_attr;
10978 route_map_result_t ret;
10979
10980 dummy_attr = *pi->attr;
10981
10982 path.peer = pi->peer;
10983 path.attr = &dummy_attr;
10984
10985 ret = route_map_apply(rmap, dest_p, &path);
10986 bgp_attr_flush(&dummy_attr);
10987 if (ret == RMAP_DENYMATCH)
10988 continue;
10989 }
10990 if (type == bgp_show_type_neighbor
10991 || type == bgp_show_type_flap_neighbor
10992 || type == bgp_show_type_damp_neighbor) {
10993 union sockunion *su = output_arg;
10994
10995 if (pi->peer == NULL
10996 || pi->peer->su_remote == NULL
10997 || !sockunion_same(pi->peer->su_remote, su))
10998 continue;
10999 }
11000 if (type == bgp_show_type_cidr_only) {
11001 uint32_t destination;
11002
11003 destination = ntohl(dest_p->u.prefix4.s_addr);
11004 if (IN_CLASSC(destination)
11005 && dest_p->prefixlen == 24)
11006 continue;
11007 if (IN_CLASSB(destination)
11008 && dest_p->prefixlen == 16)
11009 continue;
11010 if (IN_CLASSA(destination)
11011 && dest_p->prefixlen == 8)
11012 continue;
11013 }
11014 if (type == bgp_show_type_prefix_longer) {
11015 p = output_arg;
11016 if (!prefix_match(p, dest_p))
11017 continue;
11018 }
11019 if (type == bgp_show_type_community_all) {
11020 if (!pi->attr->community)
11021 continue;
11022 }
11023 if (type == bgp_show_type_community) {
11024 struct community *com = output_arg;
11025
11026 if (!pi->attr->community
11027 || !community_match(pi->attr->community,
11028 com))
11029 continue;
11030 }
11031 if (type == bgp_show_type_community_exact) {
11032 struct community *com = output_arg;
11033
11034 if (!pi->attr->community
11035 || !community_cmp(pi->attr->community, com))
11036 continue;
11037 }
11038 if (type == bgp_show_type_community_list) {
11039 struct community_list *list = output_arg;
11040
11041 if (!community_list_match(pi->attr->community,
11042 list))
11043 continue;
11044 }
11045 if (type == bgp_show_type_community_list_exact) {
11046 struct community_list *list = output_arg;
11047
11048 if (!community_list_exact_match(
11049 pi->attr->community, list))
11050 continue;
11051 }
11052 if (type == bgp_show_type_lcommunity) {
11053 struct lcommunity *lcom = output_arg;
11054
11055 if (!pi->attr->lcommunity
11056 || !lcommunity_match(pi->attr->lcommunity,
11057 lcom))
11058 continue;
11059 }
11060
11061 if (type == bgp_show_type_lcommunity_exact) {
11062 struct lcommunity *lcom = output_arg;
11063
11064 if (!pi->attr->lcommunity
11065 || !lcommunity_cmp(pi->attr->lcommunity,
11066 lcom))
11067 continue;
11068 }
11069 if (type == bgp_show_type_lcommunity_list) {
11070 struct community_list *list = output_arg;
11071
11072 if (!lcommunity_list_match(pi->attr->lcommunity,
11073 list))
11074 continue;
11075 }
11076 if (type
11077 == bgp_show_type_lcommunity_list_exact) {
11078 struct community_list *list = output_arg;
11079
11080 if (!lcommunity_list_exact_match(
11081 pi->attr->lcommunity, list))
11082 continue;
11083 }
11084 if (type == bgp_show_type_lcommunity_all) {
11085 if (!pi->attr->lcommunity)
11086 continue;
11087 }
11088 if (type == bgp_show_type_dampend_paths
11089 || type == bgp_show_type_damp_neighbor) {
11090 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
11091 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
11092 continue;
11093 }
11094
11095 if (!use_json && header) {
11096 vty_out(vty,
11097 "BGP table version is %" PRIu64
11098 ", local router ID is %pI4, vrf id ",
11099 table->version, &bgp->router_id);
11100 if (bgp->vrf_id == VRF_UNKNOWN)
11101 vty_out(vty, "%s", VRFID_NONE_STR);
11102 else
11103 vty_out(vty, "%u", bgp->vrf_id);
11104 vty_out(vty, "\n");
11105 vty_out(vty, "Default local pref %u, ",
11106 bgp->default_local_pref);
11107 vty_out(vty, "local AS %u\n", bgp->as);
11108 vty_out(vty, BGP_SHOW_SCODE_HEADER);
11109 vty_out(vty, BGP_SHOW_NCODE_HEADER);
11110 vty_out(vty, BGP_SHOW_OCODE_HEADER);
11111 vty_out(vty, BGP_SHOW_RPKI_HEADER);
11112 if (type == bgp_show_type_dampend_paths
11113 || type == bgp_show_type_damp_neighbor)
11114 vty_out(vty, BGP_SHOW_DAMP_HEADER);
11115 else if (type == bgp_show_type_flap_statistics
11116 || type == bgp_show_type_flap_neighbor)
11117 vty_out(vty, BGP_SHOW_FLAP_HEADER);
11118 else
11119 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
11120 : BGP_SHOW_HEADER));
11121 header = false;
11122
11123 } else if (json_detail && json_paths != NULL) {
11124 const struct prefix_rd *prd;
11125 json_object *jtemp;
11126
11127 /* Use common detail header, for most types;
11128 * need a json 'object'.
11129 */
11130
11131 jtemp = json_object_new_object();
11132 prd = bgp_rd_from_dest(dest, safi);
11133
11134 route_vty_out_detail_header(
11135 vty, bgp, dest, prd, table->afi,
11136 safi, jtemp);
11137
11138 json_object_array_add(json_paths, jtemp);
11139
11140 json_detail = false;
11141 }
11142
11143 if (rd != NULL && !display && !output_count) {
11144 if (!use_json)
11145 vty_out(vty,
11146 "Route Distinguisher: %s\n",
11147 rd);
11148 }
11149 if (type == bgp_show_type_dampend_paths
11150 || type == bgp_show_type_damp_neighbor)
11151 damp_route_vty_out(vty, dest_p, pi, display,
11152 AFI_IP, safi, use_json,
11153 json_paths);
11154 else if (type == bgp_show_type_flap_statistics
11155 || type == bgp_show_type_flap_neighbor)
11156 flap_route_vty_out(vty, dest_p, pi, display,
11157 AFI_IP, safi, use_json,
11158 json_paths);
11159 else {
11160 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
11161 route_vty_out_detail(
11162 vty, bgp, dest, pi,
11163 family2afi(dest_p->family),
11164 safi, RPKI_NOT_BEING_USED,
11165 json_paths);
11166 else
11167 route_vty_out(vty, dest_p, pi, display,
11168 safi, json_paths, wide);
11169 }
11170 display++;
11171 }
11172
11173 if (display) {
11174 output_count++;
11175 if (!use_json)
11176 continue;
11177
11178 /* encode prefix */
11179 if (dest_p->family == AF_FLOWSPEC) {
11180 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
11181
11182
11183 bgp_fs_nlri_get_string(
11184 (unsigned char *)
11185 dest_p->u.prefix_flowspec.ptr,
11186 dest_p->u.prefix_flowspec.prefixlen,
11187 retstr, NLRI_STRING_FORMAT_MIN, NULL,
11188 family2afi(dest_p->u
11189 .prefix_flowspec.family));
11190 if (first)
11191 vty_out(vty, "\"%s/%d\": ", retstr,
11192 dest_p->u.prefix_flowspec
11193 .prefixlen);
11194 else
11195 vty_out(vty, ",\"%s/%d\": ", retstr,
11196 dest_p->u.prefix_flowspec
11197 .prefixlen);
11198 } else {
11199 if (first)
11200 vty_out(vty, "\"%pFX\": ", dest_p);
11201 else
11202 vty_out(vty, ",\"%pFX\": ", dest_p);
11203 }
11204 vty_out(vty, "%s",
11205 json_object_to_json_string_ext(
11206 json_paths, JSON_C_TO_STRING_PRETTY));
11207 json_object_free(json_paths);
11208 json_paths = NULL;
11209 first = 0;
11210 } else
11211 json_object_free(json_paths);
11212 }
11213
11214 if (output_cum) {
11215 output_count += *output_cum;
11216 *output_cum = output_count;
11217 }
11218 if (total_cum) {
11219 total_count += *total_cum;
11220 *total_cum = total_count;
11221 }
11222 if (use_json) {
11223 if (rd) {
11224 vty_out(vty, " }%s ", (is_last ? "" : ","));
11225 }
11226 if (is_last) {
11227 unsigned long i;
11228 for (i = 0; i < *json_header_depth; ++i)
11229 vty_out(vty, " } ");
11230 if (!all)
11231 vty_out(vty, "\n");
11232 }
11233 } else {
11234 if (is_last) {
11235 /* No route is displayed */
11236 if (output_count == 0) {
11237 if (type == bgp_show_type_normal)
11238 vty_out(vty,
11239 "No BGP prefixes displayed, %ld exist\n",
11240 total_count);
11241 } else
11242 vty_out(vty,
11243 "\nDisplayed %ld routes and %ld total paths\n",
11244 output_count, total_count);
11245 }
11246 }
11247
11248 return CMD_SUCCESS;
11249 }
11250
11251 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11252 struct bgp_table *table, struct prefix_rd *prd_match,
11253 enum bgp_show_type type, void *output_arg, bool use_json)
11254 {
11255 struct bgp_dest *dest, *next;
11256 unsigned long output_cum = 0;
11257 unsigned long total_cum = 0;
11258 unsigned long json_header_depth = 0;
11259 struct bgp_table *itable;
11260 bool show_msg;
11261 uint16_t show_flags = 0;
11262
11263 show_msg = (!use_json && type == bgp_show_type_normal);
11264
11265 if (use_json)
11266 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11267
11268 for (dest = bgp_table_top(table); dest; dest = next) {
11269 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11270
11271 next = bgp_route_next(dest);
11272 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11273 continue;
11274
11275 itable = bgp_dest_get_bgp_table_info(dest);
11276 if (itable != NULL) {
11277 struct prefix_rd prd;
11278 char rd[RD_ADDRSTRLEN];
11279
11280 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11281 prefix_rd2str(&prd, rd, sizeof(rd));
11282 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11283 rd, next == NULL, &output_cum,
11284 &total_cum, &json_header_depth,
11285 show_flags, RPKI_NOT_BEING_USED);
11286 if (next == NULL)
11287 show_msg = false;
11288 }
11289 }
11290 if (show_msg) {
11291 if (output_cum == 0)
11292 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11293 total_cum);
11294 else
11295 vty_out(vty,
11296 "\nDisplayed %ld routes and %ld total paths\n",
11297 output_cum, total_cum);
11298 }
11299 return CMD_SUCCESS;
11300 }
11301
11302 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11303 enum bgp_show_type type, void *output_arg,
11304 uint16_t show_flags, enum rpki_states rpki_target_state)
11305 {
11306 struct bgp_table *table;
11307 unsigned long json_header_depth = 0;
11308 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11309
11310 if (bgp == NULL) {
11311 bgp = bgp_get_default();
11312 }
11313
11314 if (bgp == NULL) {
11315 if (!use_json)
11316 vty_out(vty, "No BGP process is configured\n");
11317 else
11318 vty_out(vty, "{}\n");
11319 return CMD_WARNING;
11320 }
11321
11322 /* Labeled-unicast routes live in the unicast table. */
11323 if (safi == SAFI_LABELED_UNICAST)
11324 safi = SAFI_UNICAST;
11325
11326 table = bgp->rib[afi][safi];
11327 /* use MPLS and ENCAP specific shows until they are merged */
11328 if (safi == SAFI_MPLS_VPN) {
11329 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11330 output_arg, use_json);
11331 }
11332
11333 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11334 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11335 output_arg, use_json,
11336 1, NULL, NULL);
11337 }
11338
11339 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11340 NULL, NULL, &json_header_depth, show_flags,
11341 rpki_target_state);
11342 }
11343
11344 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11345 safi_t safi, uint16_t show_flags)
11346 {
11347 struct listnode *node, *nnode;
11348 struct bgp *bgp;
11349 int is_first = 1;
11350 bool route_output = false;
11351 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11352
11353 if (use_json)
11354 vty_out(vty, "{\n");
11355
11356 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11357 route_output = true;
11358 if (use_json) {
11359 if (!is_first)
11360 vty_out(vty, ",\n");
11361 else
11362 is_first = 0;
11363
11364 vty_out(vty, "\"%s\":",
11365 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11366 ? VRF_DEFAULT_NAME
11367 : bgp->name);
11368 } else {
11369 vty_out(vty, "\nInstance %s:\n",
11370 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11371 ? VRF_DEFAULT_NAME
11372 : bgp->name);
11373 }
11374 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11375 show_flags, RPKI_NOT_BEING_USED);
11376 }
11377
11378 if (use_json)
11379 vty_out(vty, "}\n");
11380 else if (!route_output)
11381 vty_out(vty, "%% BGP instance not found\n");
11382 }
11383
11384 /* Header of detailed BGP route information */
11385 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11386 struct bgp_dest *dest,
11387 const struct prefix_rd *prd,
11388 afi_t afi, safi_t safi, json_object *json)
11389 {
11390 struct bgp_path_info *pi;
11391 const struct prefix *p;
11392 struct peer *peer;
11393 struct listnode *node, *nnode;
11394 char buf1[RD_ADDRSTRLEN];
11395 int count = 0;
11396 int best = 0;
11397 int suppress = 0;
11398 int accept_own = 0;
11399 int route_filter_translated_v4 = 0;
11400 int route_filter_v4 = 0;
11401 int route_filter_translated_v6 = 0;
11402 int route_filter_v6 = 0;
11403 int llgr_stale = 0;
11404 int no_llgr = 0;
11405 int accept_own_nexthop = 0;
11406 int blackhole = 0;
11407 int no_export = 0;
11408 int no_advertise = 0;
11409 int local_as = 0;
11410 int no_peer = 0;
11411 int first = 1;
11412 int has_valid_label = 0;
11413 mpls_label_t label = 0;
11414 json_object *json_adv_to = NULL;
11415
11416 p = bgp_dest_get_prefix(dest);
11417 has_valid_label = bgp_is_valid_label(&dest->local_label);
11418
11419 if (has_valid_label)
11420 label = label_pton(&dest->local_label);
11421
11422 if (safi == SAFI_EVPN) {
11423
11424 if (!json) {
11425 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11426 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11427 : "",
11428 prd ? ":" : "", (struct prefix_evpn *)p);
11429 } else {
11430 json_object_string_add(json, "rd",
11431 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11432 "");
11433 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11434 }
11435 } else {
11436 if (!json) {
11437 vty_out(vty,
11438 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11439 "\n",
11440 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11441 ? prefix_rd2str(prd, buf1,
11442 sizeof(buf1))
11443 : ""),
11444 safi == SAFI_MPLS_VPN ? ":" : "", p,
11445 dest->version);
11446
11447 } else {
11448 json_object_string_addf(json, "prefix", "%pFX", p);
11449 json_object_int_add(json, "version", dest->version);
11450
11451 }
11452 }
11453
11454 if (has_valid_label) {
11455 if (json)
11456 json_object_int_add(json, "localLabel", label);
11457 else
11458 vty_out(vty, "Local label: %d\n", label);
11459 }
11460
11461 if (!json)
11462 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11463 vty_out(vty, "not allocated\n");
11464
11465 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11466 count++;
11467 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11468 best = count;
11469 if (bgp_path_suppressed(pi))
11470 suppress = 1;
11471
11472 if (pi->attr->community == NULL)
11473 continue;
11474
11475 no_advertise += community_include(
11476 pi->attr->community, COMMUNITY_NO_ADVERTISE);
11477 no_export += community_include(pi->attr->community,
11478 COMMUNITY_NO_EXPORT);
11479 local_as += community_include(pi->attr->community,
11480 COMMUNITY_LOCAL_AS);
11481 accept_own += community_include(pi->attr->community,
11482 COMMUNITY_ACCEPT_OWN);
11483 route_filter_translated_v4 += community_include(
11484 pi->attr->community,
11485 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11486 route_filter_translated_v6 += community_include(
11487 pi->attr->community,
11488 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11489 route_filter_v4 += community_include(
11490 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
11491 route_filter_v6 += community_include(
11492 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
11493 llgr_stale += community_include(pi->attr->community,
11494 COMMUNITY_LLGR_STALE);
11495 no_llgr += community_include(pi->attr->community,
11496 COMMUNITY_NO_LLGR);
11497 accept_own_nexthop +=
11498 community_include(pi->attr->community,
11499 COMMUNITY_ACCEPT_OWN_NEXTHOP);
11500 blackhole += community_include(pi->attr->community,
11501 COMMUNITY_BLACKHOLE);
11502 no_peer += community_include(pi->attr->community,
11503 COMMUNITY_NO_PEER);
11504 }
11505 }
11506
11507 if (!json) {
11508 vty_out(vty, "Paths: (%d available", count);
11509 if (best) {
11510 vty_out(vty, ", best #%d", best);
11511 if (safi == SAFI_UNICAST) {
11512 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11513 vty_out(vty, ", table %s",
11514 VRF_DEFAULT_NAME);
11515 else
11516 vty_out(vty, ", vrf %s",
11517 bgp->name);
11518 }
11519 } else
11520 vty_out(vty, ", no best path");
11521
11522 if (accept_own)
11523 vty_out(vty,
11524 ", accept own local route exported and imported in different VRF");
11525 else if (route_filter_translated_v4)
11526 vty_out(vty,
11527 ", mark translated RTs for VPNv4 route filtering");
11528 else if (route_filter_v4)
11529 vty_out(vty,
11530 ", attach RT as-is for VPNv4 route filtering");
11531 else if (route_filter_translated_v6)
11532 vty_out(vty,
11533 ", mark translated RTs for VPNv6 route filtering");
11534 else if (route_filter_v6)
11535 vty_out(vty,
11536 ", attach RT as-is for VPNv6 route filtering");
11537 else if (llgr_stale)
11538 vty_out(vty,
11539 ", mark routes to be retained for a longer time. Requires support for Long-lived BGP Graceful Restart");
11540 else if (no_llgr)
11541 vty_out(vty,
11542 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11543 else if (accept_own_nexthop)
11544 vty_out(vty,
11545 ", accept local nexthop");
11546 else if (blackhole)
11547 vty_out(vty, ", inform peer to blackhole prefix");
11548 else if (no_export)
11549 vty_out(vty, ", not advertised to EBGP peer");
11550 else if (no_advertise)
11551 vty_out(vty, ", not advertised to any peer");
11552 else if (local_as)
11553 vty_out(vty, ", not advertised outside local AS");
11554 else if (no_peer)
11555 vty_out(vty,
11556 ", inform EBGP peer not to advertise to their EBGP peers");
11557
11558 if (suppress)
11559 vty_out(vty,
11560 ", Advertisements suppressed by an aggregate.");
11561 vty_out(vty, ")\n");
11562 }
11563
11564 /* If we are not using addpath then we can display Advertised to and
11565 * that will
11566 * show what peers we advertised the bestpath to. If we are using
11567 * addpath
11568 * though then we must display Advertised to on a path-by-path basis. */
11569 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11570 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11571 if (bgp_adj_out_lookup(peer, dest, 0)) {
11572 if (json && !json_adv_to)
11573 json_adv_to = json_object_new_object();
11574
11575 route_vty_out_advertised_to(
11576 vty, peer, &first,
11577 " Advertised to non peer-group peers:\n ",
11578 json_adv_to);
11579 }
11580 }
11581
11582 if (json) {
11583 if (json_adv_to) {
11584 json_object_object_add(json, "advertisedTo",
11585 json_adv_to);
11586 }
11587 } else {
11588 if (first)
11589 vty_out(vty, " Not advertised to any peer");
11590 vty_out(vty, "\n");
11591 }
11592 }
11593 }
11594
11595 static void bgp_show_path_info(const struct prefix_rd *pfx_rd,
11596 struct bgp_dest *bgp_node, struct vty *vty,
11597 struct bgp *bgp, afi_t afi, safi_t safi,
11598 json_object *json, enum bgp_path_type pathtype,
11599 int *display, enum rpki_states rpki_target_state)
11600 {
11601 struct bgp_path_info *pi;
11602 int header = 1;
11603 char rdbuf[RD_ADDRSTRLEN];
11604 json_object *json_header = NULL;
11605 json_object *json_paths = NULL;
11606 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11607
11608 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11609 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11610
11611 if (p->family == AF_INET || p->family == AF_INET6)
11612 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11613 pi->peer, pi->attr, p);
11614
11615 if (rpki_target_state != RPKI_NOT_BEING_USED
11616 && rpki_curr_state != rpki_target_state)
11617 continue;
11618
11619 if (json && !json_paths) {
11620 /* Instantiate json_paths only if path is valid */
11621 json_paths = json_object_new_array();
11622 if (pfx_rd) {
11623 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11624 json_header = json_object_new_object();
11625 } else
11626 json_header = json;
11627 }
11628
11629 if (header) {
11630 route_vty_out_detail_header(
11631 vty, bgp, bgp_node, pfx_rd,
11632 AFI_IP, safi, json_header);
11633 header = 0;
11634 }
11635 (*display)++;
11636
11637 if (pathtype == BGP_PATH_SHOW_ALL
11638 || (pathtype == BGP_PATH_SHOW_BESTPATH
11639 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11640 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11641 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11642 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11643 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
11644 safi, rpki_curr_state, json_paths);
11645 }
11646
11647 if (json && json_paths) {
11648 json_object_object_add(json_header, "paths", json_paths);
11649
11650 if (pfx_rd)
11651 json_object_object_add(json, rdbuf, json_header);
11652 }
11653 }
11654
11655 /*
11656 * Return rd based on safi
11657 */
11658 static const struct prefix_rd *bgp_rd_from_dest(const struct bgp_dest *dest,
11659 safi_t safi)
11660 {
11661 switch (safi) {
11662 case SAFI_MPLS_VPN:
11663 case SAFI_ENCAP:
11664 case SAFI_EVPN:
11665 return (struct prefix_rd *)(bgp_dest_get_prefix(dest));
11666 default:
11667 return NULL;
11668
11669 }
11670 }
11671
11672 /* Display specified route of BGP table. */
11673 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11674 struct bgp_table *rib, const char *ip_str,
11675 afi_t afi, safi_t safi,
11676 enum rpki_states rpki_target_state,
11677 struct prefix_rd *prd, int prefix_check,
11678 enum bgp_path_type pathtype, bool use_json)
11679 {
11680 int ret;
11681 int display = 0;
11682 struct prefix match;
11683 struct bgp_dest *dest;
11684 struct bgp_dest *rm;
11685 struct bgp_table *table;
11686 json_object *json = NULL;
11687 json_object *json_paths = NULL;
11688
11689 /* Check IP address argument. */
11690 ret = str2prefix(ip_str, &match);
11691 if (!ret) {
11692 vty_out(vty, "address is malformed\n");
11693 return CMD_WARNING;
11694 }
11695
11696 match.family = afi2family(afi);
11697
11698 if (use_json)
11699 json = json_object_new_object();
11700
11701 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11702 for (dest = bgp_table_top(rib); dest;
11703 dest = bgp_route_next(dest)) {
11704 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11705
11706 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11707 continue;
11708 table = bgp_dest_get_bgp_table_info(dest);
11709 if (!table)
11710 continue;
11711
11712 rm = bgp_node_match(table, &match);
11713 if (rm == NULL)
11714 continue;
11715
11716 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11717 if (prefix_check
11718 && rm_p->prefixlen != match.prefixlen) {
11719 bgp_dest_unlock_node(rm);
11720 continue;
11721 }
11722
11723 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11724 bgp, afi, safi, json, pathtype,
11725 &display, rpki_target_state);
11726
11727 bgp_dest_unlock_node(rm);
11728 }
11729 } else if (safi == SAFI_EVPN) {
11730 struct bgp_dest *longest_pfx;
11731 bool is_exact_pfxlen_match = false;
11732
11733 for (dest = bgp_table_top(rib); dest;
11734 dest = bgp_route_next(dest)) {
11735 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11736
11737 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11738 continue;
11739 table = bgp_dest_get_bgp_table_info(dest);
11740 if (!table)
11741 continue;
11742
11743 longest_pfx = NULL;
11744 is_exact_pfxlen_match = false;
11745 /*
11746 * Search through all the prefixes for a match. The
11747 * pfx's are enumerated in ascending order of pfxlens.
11748 * So, the last pfx match is the longest match. Set
11749 * is_exact_pfxlen_match when we get exact pfxlen match
11750 */
11751 for (rm = bgp_table_top(table); rm;
11752 rm = bgp_route_next(rm)) {
11753 const struct prefix *rm_p =
11754 bgp_dest_get_prefix(rm);
11755 /*
11756 * Get prefixlen of the ip-prefix within type5
11757 * evpn route
11758 */
11759 if (evpn_type5_prefix_match(rm_p, &match)
11760 && rm->info) {
11761 longest_pfx = rm;
11762 int type5_pfxlen =
11763 bgp_evpn_get_type5_prefixlen(
11764 rm_p);
11765 if (type5_pfxlen == match.prefixlen) {
11766 is_exact_pfxlen_match = true;
11767 bgp_dest_unlock_node(rm);
11768 break;
11769 }
11770 }
11771 }
11772
11773 if (!longest_pfx)
11774 continue;
11775
11776 if (prefix_check && !is_exact_pfxlen_match)
11777 continue;
11778
11779 rm = longest_pfx;
11780 bgp_dest_lock_node(rm);
11781
11782 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11783 bgp, afi, safi, json, pathtype,
11784 &display, rpki_target_state);
11785
11786 bgp_dest_unlock_node(rm);
11787 }
11788 } else if (safi == SAFI_FLOWSPEC) {
11789 if (use_json)
11790 json_paths = json_object_new_array();
11791
11792 display = bgp_flowspec_display_match_per_ip(afi, rib,
11793 &match, prefix_check,
11794 vty,
11795 use_json,
11796 json_paths);
11797 if (use_json) {
11798 if (display)
11799 json_object_object_add(json, "paths",
11800 json_paths);
11801 else
11802 json_object_free(json_paths);
11803 }
11804 } else {
11805 dest = bgp_node_match(rib, &match);
11806 if (dest != NULL) {
11807 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11808 if (!prefix_check
11809 || dest_p->prefixlen == match.prefixlen) {
11810 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11811 safi, json, pathtype,
11812 &display, rpki_target_state);
11813 }
11814
11815 bgp_dest_unlock_node(dest);
11816 }
11817 }
11818
11819 if (use_json) {
11820 vty_json(vty, json);
11821 } else {
11822 if (!display) {
11823 vty_out(vty, "%% Network not in table\n");
11824 return CMD_WARNING;
11825 }
11826 }
11827
11828 return CMD_SUCCESS;
11829 }
11830
11831 /* Display specified route of Main RIB */
11832 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
11833 afi_t afi, safi_t safi, struct prefix_rd *prd,
11834 int prefix_check, enum bgp_path_type pathtype,
11835 enum rpki_states rpki_target_state, bool use_json)
11836 {
11837 if (!bgp) {
11838 bgp = bgp_get_default();
11839 if (!bgp) {
11840 if (!use_json)
11841 vty_out(vty, "No BGP process is configured\n");
11842 else
11843 vty_out(vty, "{}\n");
11844 return CMD_WARNING;
11845 }
11846 }
11847
11848 /* labeled-unicast routes live in the unicast table */
11849 if (safi == SAFI_LABELED_UNICAST)
11850 safi = SAFI_UNICAST;
11851
11852 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
11853 afi, safi, rpki_target_state, prd,
11854 prefix_check, pathtype, use_json);
11855 }
11856
11857 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
11858 struct cmd_token **argv, bool exact, afi_t afi,
11859 safi_t safi, bool uj)
11860 {
11861 struct lcommunity *lcom;
11862 struct buffer *b;
11863 int i;
11864 char *str;
11865 int first = 0;
11866 uint16_t show_flags = 0;
11867 int ret;
11868
11869 if (uj)
11870 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11871
11872 b = buffer_new(1024);
11873 for (i = 0; i < argc; i++) {
11874 if (first)
11875 buffer_putc(b, ' ');
11876 else {
11877 if (strmatch(argv[i]->text, "AA:BB:CC")) {
11878 first = 1;
11879 buffer_putstr(b, argv[i]->arg);
11880 }
11881 }
11882 }
11883 buffer_putc(b, '\0');
11884
11885 str = buffer_getstr(b);
11886 buffer_free(b);
11887
11888 lcom = lcommunity_str2com(str);
11889 XFREE(MTYPE_TMP, str);
11890 if (!lcom) {
11891 vty_out(vty, "%% Large-community malformed\n");
11892 return CMD_WARNING;
11893 }
11894
11895 ret = bgp_show(vty, bgp, afi, safi,
11896 (exact ? bgp_show_type_lcommunity_exact
11897 : bgp_show_type_lcommunity),
11898 lcom, show_flags, RPKI_NOT_BEING_USED);
11899
11900 lcommunity_free(&lcom);
11901 return ret;
11902 }
11903
11904 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
11905 const char *lcom, bool exact, afi_t afi,
11906 safi_t safi, bool uj)
11907 {
11908 struct community_list *list;
11909 uint16_t show_flags = 0;
11910
11911 if (uj)
11912 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11913
11914
11915 list = community_list_lookup(bgp_clist, lcom, 0,
11916 LARGE_COMMUNITY_LIST_MASTER);
11917 if (list == NULL) {
11918 vty_out(vty, "%% %s is not a valid large-community-list name\n",
11919 lcom);
11920 return CMD_WARNING;
11921 }
11922
11923 return bgp_show(vty, bgp, afi, safi,
11924 (exact ? bgp_show_type_lcommunity_list_exact
11925 : bgp_show_type_lcommunity_list),
11926 list, show_flags, RPKI_NOT_BEING_USED);
11927 }
11928
11929 DEFUN (show_ip_bgp_large_community_list,
11930 show_ip_bgp_large_community_list_cmd,
11931 "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]",
11932 SHOW_STR
11933 IP_STR
11934 BGP_STR
11935 BGP_INSTANCE_HELP_STR
11936 BGP_AFI_HELP_STR
11937 BGP_SAFI_WITH_LABEL_HELP_STR
11938 "Display routes matching the large-community-list\n"
11939 "large-community-list number\n"
11940 "large-community-list name\n"
11941 "Exact match of the large-communities\n"
11942 JSON_STR)
11943 {
11944 afi_t afi = AFI_IP6;
11945 safi_t safi = SAFI_UNICAST;
11946 int idx = 0;
11947 bool exact_match = 0;
11948 struct bgp *bgp = NULL;
11949 bool uj = use_json(argc, argv);
11950
11951 if (uj)
11952 argc--;
11953
11954 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11955 &bgp, uj);
11956 if (!idx)
11957 return CMD_WARNING;
11958
11959 argv_find(argv, argc, "large-community-list", &idx);
11960
11961 const char *clist_number_or_name = argv[++idx]->arg;
11962
11963 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11964 exact_match = 1;
11965
11966 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
11967 exact_match, afi, safi, uj);
11968 }
11969 DEFUN (show_ip_bgp_large_community,
11970 show_ip_bgp_large_community_cmd,
11971 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
11972 SHOW_STR
11973 IP_STR
11974 BGP_STR
11975 BGP_INSTANCE_HELP_STR
11976 BGP_AFI_HELP_STR
11977 BGP_SAFI_WITH_LABEL_HELP_STR
11978 "Display routes matching the large-communities\n"
11979 "List of large-community numbers\n"
11980 "Exact match of the large-communities\n"
11981 JSON_STR)
11982 {
11983 afi_t afi = AFI_IP6;
11984 safi_t safi = SAFI_UNICAST;
11985 int idx = 0;
11986 bool exact_match = 0;
11987 struct bgp *bgp = NULL;
11988 bool uj = use_json(argc, argv);
11989 uint16_t show_flags = 0;
11990
11991 if (uj) {
11992 argc--;
11993 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11994 }
11995
11996 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11997 &bgp, uj);
11998 if (!idx)
11999 return CMD_WARNING;
12000
12001 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
12002 if (argv_find(argv, argc, "exact-match", &idx))
12003 exact_match = 1;
12004 return bgp_show_lcommunity(vty, bgp, argc, argv,
12005 exact_match, afi, safi, uj);
12006 } else
12007 return bgp_show(vty, bgp, afi, safi,
12008 bgp_show_type_lcommunity_all, NULL, show_flags,
12009 RPKI_NOT_BEING_USED);
12010 }
12011
12012 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12013 safi_t safi, struct json_object *json_array);
12014 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12015 safi_t safi, struct json_object *json);
12016
12017
12018 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
12019 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
12020 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
12021 "Display number of prefixes for all afi/safi\n" JSON_STR)
12022 {
12023 bool uj = use_json(argc, argv);
12024 struct bgp *bgp = NULL;
12025 safi_t safi = SAFI_UNICAST;
12026 afi_t afi = AFI_IP6;
12027 int idx = 0;
12028 struct json_object *json_all = NULL;
12029 struct json_object *json_afi_safi = NULL;
12030
12031 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12032 &bgp, false);
12033 if (!idx)
12034 return CMD_WARNING;
12035
12036 if (uj)
12037 json_all = json_object_new_object();
12038
12039 FOREACH_AFI_SAFI (afi, safi) {
12040 /*
12041 * So limit output to those afi/safi pairs that
12042 * actually have something interesting in them
12043 */
12044 if (strmatch(get_afi_safi_str(afi, safi, true),
12045 "Unknown")) {
12046 continue;
12047 }
12048 if (uj) {
12049 json_afi_safi = json_object_new_array();
12050 json_object_object_add(
12051 json_all,
12052 get_afi_safi_str(afi, safi, true),
12053 json_afi_safi);
12054 } else {
12055 json_afi_safi = NULL;
12056 }
12057
12058 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12059 }
12060
12061 if (uj) {
12062 vty_out(vty, "%s",
12063 json_object_to_json_string_ext(
12064 json_all, JSON_C_TO_STRING_PRETTY));
12065 json_object_free(json_all);
12066 }
12067
12068 return CMD_SUCCESS;
12069 }
12070
12071 /* BGP route print out function without JSON */
12072 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
12073 show_ip_bgp_l2vpn_evpn_statistics_cmd,
12074 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
12075 SHOW_STR
12076 IP_STR
12077 BGP_STR
12078 BGP_INSTANCE_HELP_STR
12079 L2VPN_HELP_STR
12080 EVPN_HELP_STR
12081 "BGP RIB advertisement statistics\n"
12082 JSON_STR)
12083 {
12084 afi_t afi = AFI_IP6;
12085 safi_t safi = SAFI_UNICAST;
12086 struct bgp *bgp = NULL;
12087 int idx = 0, ret;
12088 bool uj = use_json(argc, argv);
12089 struct json_object *json_afi_safi = NULL, *json = NULL;
12090
12091 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12092 &bgp, false);
12093 if (!idx)
12094 return CMD_WARNING;
12095
12096 if (uj)
12097 json_afi_safi = json_object_new_array();
12098 else
12099 json_afi_safi = NULL;
12100
12101 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12102
12103 if (uj) {
12104 json = json_object_new_object();
12105 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12106 json_afi_safi);
12107 vty_out(vty, "%s", json_object_to_json_string_ext(
12108 json, JSON_C_TO_STRING_PRETTY));
12109 json_object_free(json);
12110 }
12111 return ret;
12112 }
12113
12114 /* BGP route print out function without JSON */
12115 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
12116 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12117 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12118 "]]\
12119 statistics [json]",
12120 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12121 BGP_SAFI_WITH_LABEL_HELP_STR
12122 "BGP RIB advertisement statistics\n" JSON_STR)
12123 {
12124 afi_t afi = AFI_IP6;
12125 safi_t safi = SAFI_UNICAST;
12126 struct bgp *bgp = NULL;
12127 int idx = 0, ret;
12128 bool uj = use_json(argc, argv);
12129 struct json_object *json_afi_safi = NULL, *json = NULL;
12130
12131 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12132 &bgp, false);
12133 if (!idx)
12134 return CMD_WARNING;
12135
12136 if (uj)
12137 json_afi_safi = json_object_new_array();
12138 else
12139 json_afi_safi = NULL;
12140
12141 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
12142
12143 if (uj) {
12144 json = json_object_new_object();
12145 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
12146 json_afi_safi);
12147 vty_out(vty, "%s",
12148 json_object_to_json_string_ext(
12149 json, JSON_C_TO_STRING_PRETTY));
12150 json_object_free(json);
12151 }
12152 return ret;
12153 }
12154
12155 DEFPY(show_ip_bgp_dampening_params, show_ip_bgp_dampening_params_cmd,
12156 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12157 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12158 "]] [all$all] dampening parameters [json]",
12159 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12160 BGP_SAFI_WITH_LABEL_HELP_STR
12161 "Display the entries for all address families\n"
12162 "Display detailed information about dampening\n"
12163 "Display detail of configured dampening parameters\n"
12164 JSON_STR)
12165 {
12166 afi_t afi = AFI_IP6;
12167 safi_t safi = SAFI_UNICAST;
12168 struct bgp *bgp = NULL;
12169 int idx = 0;
12170 uint16_t show_flags = 0;
12171 bool uj = use_json(argc, argv);
12172
12173 if (uj) {
12174 argc--;
12175 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12176 }
12177
12178 /* [<ipv4|ipv6> [all]] */
12179 if (all) {
12180 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12181 if (argv_find(argv, argc, "ipv4", &idx))
12182 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12183
12184 if (argv_find(argv, argc, "ipv6", &idx))
12185 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12186 }
12187
12188 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12189 &bgp, false);
12190 if (!idx)
12191 return CMD_WARNING;
12192
12193 return bgp_show_dampening_parameters(vty, afi, safi, show_flags);
12194 }
12195
12196 /* BGP route print out function */
12197 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
12198 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12199 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12200 "]]\
12201 [all$all]\
12202 [cidr-only\
12203 |dampening <flap-statistics|dampened-paths>\
12204 |community [AA:NN|local-AS|no-advertise|no-export\
12205 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12206 |accept-own|accept-own-nexthop|route-filter-v6\
12207 |route-filter-v4|route-filter-translated-v6\
12208 |route-filter-translated-v4] [exact-match]\
12209 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
12210 |filter-list AS_PATH_FILTER_NAME\
12211 |prefix-list WORD\
12212 |route-map WORD\
12213 |rpki <invalid|valid|notfound>\
12214 |version (1-4294967295)\
12215 |alias ALIAS_NAME\
12216 |A.B.C.D/M longer-prefixes\
12217 |X:X::X:X/M longer-prefixes\
12218 ] [json$uj [detail$detail] | wide$wide]",
12219 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12220 BGP_SAFI_WITH_LABEL_HELP_STR
12221 "Display the entries for all address families\n"
12222 "Display only routes with non-natural netmasks\n"
12223 "Display detailed information about dampening\n"
12224 "Display flap statistics of routes\n"
12225 "Display paths suppressed due to dampening\n"
12226 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12227 "Do not send outside local AS (well-known community)\n"
12228 "Do not advertise to any peer (well-known community)\n"
12229 "Do not export to next AS (well-known community)\n"
12230 "Graceful shutdown (well-known community)\n"
12231 "Do not export to any peer (well-known community)\n"
12232 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12233 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12234 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12235 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12236 "Should accept VPN route with local nexthop (well-known community)\n"
12237 "RT VPNv6 route filtering (well-known community)\n"
12238 "RT VPNv4 route filtering (well-known community)\n"
12239 "RT translated VPNv6 route filtering (well-known community)\n"
12240 "RT translated VPNv4 route filtering (well-known community)\n"
12241 "Exact match of the communities\n"
12242 "Community-list number\n"
12243 "Community-list name\n"
12244 "Display routes matching the community-list\n"
12245 "Exact match of the communities\n"
12246 "Display routes conforming to the filter-list\n"
12247 "Regular expression access list name\n"
12248 "Display routes conforming to the prefix-list\n"
12249 "Prefix-list name\n"
12250 "Display routes matching the route-map\n"
12251 "A route-map to match on\n"
12252 "RPKI route types\n"
12253 "A valid path as determined by rpki\n"
12254 "A invalid path as determined by rpki\n"
12255 "A path that has no rpki data\n"
12256 "Display prefixes with matching version numbers\n"
12257 "Version number and above\n"
12258 "Display prefixes with matching BGP community alias\n"
12259 "BGP community alias\n"
12260 "IPv4 prefix\n"
12261 "Display route and more specific routes\n"
12262 "IPv6 prefix\n"
12263 "Display route and more specific routes\n"
12264 JSON_STR
12265 "Display detailed version of JSON output\n"
12266 "Increase table width for longer prefixes\n")
12267 {
12268 afi_t afi = AFI_IP6;
12269 safi_t safi = SAFI_UNICAST;
12270 enum bgp_show_type sh_type = bgp_show_type_normal;
12271 void *output_arg = NULL;
12272 struct bgp *bgp = NULL;
12273 int idx = 0;
12274 int exact_match = 0;
12275 char *community = NULL;
12276 bool first = true;
12277 uint16_t show_flags = 0;
12278 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12279
12280 if (uj) {
12281 argc--;
12282 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12283 }
12284
12285 if (detail)
12286 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12287
12288 /* [<ipv4|ipv6> [all]] */
12289 if (all) {
12290 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12291
12292 if (argv_find(argv, argc, "ipv4", &idx))
12293 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12294
12295 if (argv_find(argv, argc, "ipv6", &idx))
12296 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12297 }
12298
12299 if (wide)
12300 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12301
12302 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12303 &bgp, uj);
12304 if (!idx)
12305 return CMD_WARNING;
12306
12307 if (argv_find(argv, argc, "cidr-only", &idx))
12308 sh_type = bgp_show_type_cidr_only;
12309
12310 if (argv_find(argv, argc, "dampening", &idx)) {
12311 if (argv_find(argv, argc, "dampened-paths", &idx))
12312 sh_type = bgp_show_type_dampend_paths;
12313 else if (argv_find(argv, argc, "flap-statistics", &idx))
12314 sh_type = bgp_show_type_flap_statistics;
12315 }
12316
12317 if (argv_find(argv, argc, "community", &idx)) {
12318 char *maybecomm = NULL;
12319
12320 if (idx + 1 < argc) {
12321 if (argv[idx + 1]->type == VARIABLE_TKN)
12322 maybecomm = argv[idx + 1]->arg;
12323 else
12324 maybecomm = argv[idx + 1]->text;
12325 }
12326
12327 if (maybecomm && !strmatch(maybecomm, "json")
12328 && !strmatch(maybecomm, "exact-match"))
12329 community = maybecomm;
12330
12331 if (argv_find(argv, argc, "exact-match", &idx))
12332 exact_match = 1;
12333
12334 if (!community)
12335 sh_type = bgp_show_type_community_all;
12336 }
12337
12338 if (argv_find(argv, argc, "community-list", &idx)) {
12339 const char *clist_number_or_name = argv[++idx]->arg;
12340 struct community_list *list;
12341
12342 if (argv_find(argv, argc, "exact-match", &idx))
12343 exact_match = 1;
12344
12345 list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
12346 COMMUNITY_LIST_MASTER);
12347 if (list == NULL) {
12348 vty_out(vty,
12349 "%% %s is not a valid community-list name\n",
12350 clist_number_or_name);
12351 return CMD_WARNING;
12352 }
12353
12354 if (exact_match)
12355 sh_type = bgp_show_type_community_list_exact;
12356 else
12357 sh_type = bgp_show_type_community_list;
12358 output_arg = list;
12359 }
12360
12361 if (argv_find(argv, argc, "filter-list", &idx)) {
12362 const char *filter = argv[++idx]->arg;
12363 struct as_list *as_list;
12364
12365 as_list = as_list_lookup(filter);
12366 if (as_list == NULL) {
12367 vty_out(vty,
12368 "%% %s is not a valid AS-path access-list name\n",
12369 filter);
12370 return CMD_WARNING;
12371 }
12372
12373 sh_type = bgp_show_type_filter_list;
12374 output_arg = as_list;
12375 }
12376
12377 if (argv_find(argv, argc, "prefix-list", &idx)) {
12378 const char *prefix_list_str = argv[++idx]->arg;
12379 struct prefix_list *plist;
12380
12381 plist = prefix_list_lookup(afi, prefix_list_str);
12382 if (plist == NULL) {
12383 vty_out(vty, "%% %s is not a valid prefix-list name\n",
12384 prefix_list_str);
12385 return CMD_WARNING;
12386 }
12387
12388 sh_type = bgp_show_type_prefix_list;
12389 output_arg = plist;
12390 }
12391
12392 if (argv_find(argv, argc, "route-map", &idx)) {
12393 const char *rmap_str = argv[++idx]->arg;
12394 struct route_map *rmap;
12395
12396 rmap = route_map_lookup_by_name(rmap_str);
12397 if (!rmap) {
12398 vty_out(vty, "%% %s is not a valid route-map name\n",
12399 rmap_str);
12400 return CMD_WARNING;
12401 }
12402
12403 sh_type = bgp_show_type_route_map;
12404 output_arg = rmap;
12405 }
12406
12407 if (argv_find(argv, argc, "rpki", &idx)) {
12408 sh_type = bgp_show_type_rpki;
12409 if (argv_find(argv, argc, "valid", &idx))
12410 rpki_target_state = RPKI_VALID;
12411 else if (argv_find(argv, argc, "invalid", &idx))
12412 rpki_target_state = RPKI_INVALID;
12413 }
12414
12415 /* Display prefixes with matching version numbers */
12416 if (argv_find(argv, argc, "version", &idx)) {
12417 sh_type = bgp_show_type_prefix_version;
12418 output_arg = argv[idx + 1]->arg;
12419 }
12420
12421 /* Display prefixes with matching BGP community alias */
12422 if (argv_find(argv, argc, "alias", &idx)) {
12423 sh_type = bgp_show_type_community_alias;
12424 output_arg = argv[idx + 1]->arg;
12425 }
12426
12427 /* prefix-longer */
12428 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12429 || argv_find(argv, argc, "X:X::X:X/M", &idx)) {
12430 const char *prefix_str = argv[idx]->arg;
12431 struct prefix p;
12432
12433 if (!str2prefix(prefix_str, &p)) {
12434 vty_out(vty, "%% Malformed Prefix\n");
12435 return CMD_WARNING;
12436 }
12437
12438 sh_type = bgp_show_type_prefix_longer;
12439 output_arg = &p;
12440 }
12441
12442 if (!all) {
12443 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12444 if (community)
12445 return bgp_show_community(vty, bgp, community,
12446 exact_match, afi, safi,
12447 show_flags);
12448 else
12449 return bgp_show(vty, bgp, afi, safi, sh_type,
12450 output_arg, show_flags,
12451 rpki_target_state);
12452 } else {
12453 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12454 * AFI_IP6 */
12455
12456 if (uj)
12457 vty_out(vty, "{\n");
12458
12459 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12460 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12461 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12462 ? AFI_IP
12463 : AFI_IP6;
12464 FOREACH_SAFI (safi) {
12465 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12466 continue;
12467
12468 if (uj) {
12469 if (first)
12470 first = false;
12471 else
12472 vty_out(vty, ",\n");
12473 vty_out(vty, "\"%s\":{\n",
12474 get_afi_safi_str(afi, safi,
12475 true));
12476 } else
12477 vty_out(vty,
12478 "\nFor address family: %s\n",
12479 get_afi_safi_str(afi, safi,
12480 false));
12481
12482 if (community)
12483 bgp_show_community(vty, bgp, community,
12484 exact_match, afi,
12485 safi, show_flags);
12486 else
12487 bgp_show(vty, bgp, afi, safi, sh_type,
12488 output_arg, show_flags,
12489 rpki_target_state);
12490 if (uj)
12491 vty_out(vty, "}\n");
12492 }
12493 } else {
12494 /* show <ip> bgp all: for each AFI and SAFI*/
12495 FOREACH_AFI_SAFI (afi, safi) {
12496 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12497 continue;
12498
12499 if (uj) {
12500 if (first)
12501 first = false;
12502 else
12503 vty_out(vty, ",\n");
12504
12505 vty_out(vty, "\"%s\":{\n",
12506 get_afi_safi_str(afi, safi,
12507 true));
12508 } else
12509 vty_out(vty,
12510 "\nFor address family: %s\n",
12511 get_afi_safi_str(afi, safi,
12512 false));
12513
12514 if (community)
12515 bgp_show_community(vty, bgp, community,
12516 exact_match, afi,
12517 safi, show_flags);
12518 else
12519 bgp_show(vty, bgp, afi, safi, sh_type,
12520 output_arg, show_flags,
12521 rpki_target_state);
12522 if (uj)
12523 vty_out(vty, "}\n");
12524 }
12525 }
12526 if (uj)
12527 vty_out(vty, "}\n");
12528 }
12529 return CMD_SUCCESS;
12530 }
12531
12532 DEFUN (show_ip_bgp_route,
12533 show_ip_bgp_route_cmd,
12534 "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]",
12535 SHOW_STR
12536 IP_STR
12537 BGP_STR
12538 BGP_INSTANCE_HELP_STR
12539 BGP_AFI_HELP_STR
12540 BGP_SAFI_WITH_LABEL_HELP_STR
12541 "Network in the BGP routing table to display\n"
12542 "IPv4 prefix\n"
12543 "Network in the BGP routing table to display\n"
12544 "IPv6 prefix\n"
12545 "Display only the bestpath\n"
12546 "Display only multipaths\n"
12547 "Display only paths that match the specified rpki state\n"
12548 "A valid path as determined by rpki\n"
12549 "A invalid path as determined by rpki\n"
12550 "A path that has no rpki data\n"
12551 JSON_STR)
12552 {
12553 int prefix_check = 0;
12554
12555 afi_t afi = AFI_IP6;
12556 safi_t safi = SAFI_UNICAST;
12557 char *prefix = NULL;
12558 struct bgp *bgp = NULL;
12559 enum bgp_path_type path_type;
12560 bool uj = use_json(argc, argv);
12561
12562 int idx = 0;
12563
12564 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12565 &bgp, uj);
12566 if (!idx)
12567 return CMD_WARNING;
12568
12569 if (!bgp) {
12570 vty_out(vty,
12571 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12572 return CMD_WARNING;
12573 }
12574
12575 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12576 if (argv_find(argv, argc, "A.B.C.D", &idx)
12577 || argv_find(argv, argc, "X:X::X:X", &idx))
12578 prefix_check = 0;
12579 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12580 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12581 prefix_check = 1;
12582
12583 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12584 && afi != AFI_IP6) {
12585 vty_out(vty,
12586 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12587 return CMD_WARNING;
12588 }
12589 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12590 && afi != AFI_IP) {
12591 vty_out(vty,
12592 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12593 return CMD_WARNING;
12594 }
12595
12596 prefix = argv[idx]->arg;
12597
12598 /* [<bestpath|multipath>] */
12599 if (argv_find(argv, argc, "bestpath", &idx))
12600 path_type = BGP_PATH_SHOW_BESTPATH;
12601 else if (argv_find(argv, argc, "multipath", &idx))
12602 path_type = BGP_PATH_SHOW_MULTIPATH;
12603 else
12604 path_type = BGP_PATH_SHOW_ALL;
12605
12606 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12607 path_type, RPKI_NOT_BEING_USED, uj);
12608 }
12609
12610 DEFUN (show_ip_bgp_regexp,
12611 show_ip_bgp_regexp_cmd,
12612 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12613 SHOW_STR
12614 IP_STR
12615 BGP_STR
12616 BGP_INSTANCE_HELP_STR
12617 BGP_AFI_HELP_STR
12618 BGP_SAFI_WITH_LABEL_HELP_STR
12619 "Display routes matching the AS path regular expression\n"
12620 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12621 JSON_STR)
12622 {
12623 afi_t afi = AFI_IP6;
12624 safi_t safi = SAFI_UNICAST;
12625 struct bgp *bgp = NULL;
12626 bool uj = use_json(argc, argv);
12627 char *regstr = NULL;
12628
12629 int idx = 0;
12630 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12631 &bgp, false);
12632 if (!idx)
12633 return CMD_WARNING;
12634
12635 // get index of regex
12636 if (argv_find(argv, argc, "REGEX", &idx))
12637 regstr = argv[idx]->arg;
12638
12639 assert(regstr);
12640 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12641 bgp_show_type_regexp, uj);
12642 }
12643
12644 DEFPY (show_ip_bgp_instance_all,
12645 show_ip_bgp_instance_all_cmd,
12646 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12647 SHOW_STR
12648 IP_STR
12649 BGP_STR
12650 BGP_INSTANCE_ALL_HELP_STR
12651 BGP_AFI_HELP_STR
12652 BGP_SAFI_WITH_LABEL_HELP_STR
12653 JSON_STR
12654 "Increase table width for longer prefixes\n")
12655 {
12656 afi_t afi = AFI_IP6;
12657 safi_t safi = SAFI_UNICAST;
12658 struct bgp *bgp = NULL;
12659 int idx = 0;
12660 uint16_t show_flags = 0;
12661
12662 if (uj) {
12663 argc--;
12664 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12665 }
12666
12667 if (wide)
12668 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12669
12670 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12671 &bgp, uj);
12672 if (!idx)
12673 return CMD_WARNING;
12674
12675 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12676 return CMD_SUCCESS;
12677 }
12678
12679 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12680 afi_t afi, safi_t safi, enum bgp_show_type type,
12681 bool use_json)
12682 {
12683 regex_t *regex;
12684 int rc;
12685 uint16_t show_flags = 0;
12686
12687 if (use_json)
12688 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12689
12690 if (!config_bgp_aspath_validate(regstr)) {
12691 vty_out(vty, "Invalid character in REGEX %s\n",
12692 regstr);
12693 return CMD_WARNING_CONFIG_FAILED;
12694 }
12695
12696 regex = bgp_regcomp(regstr);
12697 if (!regex) {
12698 vty_out(vty, "Can't compile regexp %s\n", regstr);
12699 return CMD_WARNING;
12700 }
12701
12702 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
12703 RPKI_NOT_BEING_USED);
12704 bgp_regex_free(regex);
12705 return rc;
12706 }
12707
12708 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12709 const char *comstr, int exact, afi_t afi,
12710 safi_t safi, uint16_t show_flags)
12711 {
12712 struct community *com;
12713 int ret = 0;
12714
12715 com = community_str2com(comstr);
12716 if (!com) {
12717 vty_out(vty, "%% Community malformed: %s\n", comstr);
12718 return CMD_WARNING;
12719 }
12720
12721 ret = bgp_show(vty, bgp, afi, safi,
12722 (exact ? bgp_show_type_community_exact
12723 : bgp_show_type_community),
12724 com, show_flags, RPKI_NOT_BEING_USED);
12725 community_free(&com);
12726
12727 return ret;
12728 }
12729
12730 enum bgp_stats {
12731 BGP_STATS_MAXBITLEN = 0,
12732 BGP_STATS_RIB,
12733 BGP_STATS_PREFIXES,
12734 BGP_STATS_TOTPLEN,
12735 BGP_STATS_UNAGGREGATEABLE,
12736 BGP_STATS_MAX_AGGREGATEABLE,
12737 BGP_STATS_AGGREGATES,
12738 BGP_STATS_SPACE,
12739 BGP_STATS_ASPATH_COUNT,
12740 BGP_STATS_ASPATH_MAXHOPS,
12741 BGP_STATS_ASPATH_TOTHOPS,
12742 BGP_STATS_ASPATH_MAXSIZE,
12743 BGP_STATS_ASPATH_TOTSIZE,
12744 BGP_STATS_ASN_HIGHEST,
12745 BGP_STATS_MAX,
12746 };
12747
12748 #define TABLE_STATS_IDX_VTY 0
12749 #define TABLE_STATS_IDX_JSON 1
12750
12751 static const char *table_stats_strs[][2] = {
12752 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12753 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12754 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12755 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12756 "unaggregateablePrefixes"},
12757 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12758 "maximumAggregateablePrefixes"},
12759 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12760 "bgpAggregateAdvertisements"},
12761 [BGP_STATS_SPACE] = {"Address space advertised",
12762 "addressSpaceAdvertised"},
12763 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12764 "advertisementsWithPaths"},
12765 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12766 "longestAsPath"},
12767 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12768 "largestAsPath"},
12769 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12770 "averageAsPathLengthHops"},
12771 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12772 "averageAsPathSizeBytes"},
12773 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12774 [BGP_STATS_MAX] = {NULL, NULL}
12775 };
12776
12777 struct bgp_table_stats {
12778 struct bgp_table *table;
12779 unsigned long long counts[BGP_STATS_MAX];
12780 double total_space;
12781 };
12782
12783 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12784 struct bgp_table_stats *ts, unsigned int space)
12785 {
12786 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12787 struct bgp_path_info *pi;
12788 const struct prefix *rn_p;
12789
12790 if (!bgp_dest_has_bgp_path_info_data(dest))
12791 return;
12792
12793 rn_p = bgp_dest_get_prefix(dest);
12794 ts->counts[BGP_STATS_PREFIXES]++;
12795 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12796
12797 /* check if the prefix is included by any other announcements */
12798 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12799 pdest = bgp_dest_parent_nolock(pdest);
12800
12801 if (pdest == NULL || pdest == top) {
12802 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12803 /* announced address space */
12804 if (space)
12805 ts->total_space += pow(2.0, space - rn_p->prefixlen);
12806 } else if (bgp_dest_has_bgp_path_info_data(pdest))
12807 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
12808
12809
12810 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
12811 ts->counts[BGP_STATS_RIB]++;
12812
12813 if (CHECK_FLAG(pi->attr->flag,
12814 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
12815 ts->counts[BGP_STATS_AGGREGATES]++;
12816
12817 /* as-path stats */
12818 if (pi->attr->aspath) {
12819 unsigned int hops = aspath_count_hops(pi->attr->aspath);
12820 unsigned int size = aspath_size(pi->attr->aspath);
12821 as_t highest = aspath_highest(pi->attr->aspath);
12822
12823 ts->counts[BGP_STATS_ASPATH_COUNT]++;
12824
12825 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
12826 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
12827
12828 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
12829 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
12830
12831 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
12832 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
12833 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
12834 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
12835 }
12836 }
12837 }
12838
12839 static int bgp_table_stats_walker(struct thread *t)
12840 {
12841 struct bgp_dest *dest, *ndest;
12842 struct bgp_dest *top;
12843 struct bgp_table_stats *ts = THREAD_ARG(t);
12844 unsigned int space = 0;
12845
12846 if (!(top = bgp_table_top(ts->table)))
12847 return 0;
12848
12849 switch (ts->table->afi) {
12850 case AFI_IP:
12851 space = IPV4_MAX_BITLEN;
12852 break;
12853 case AFI_IP6:
12854 space = IPV6_MAX_BITLEN;
12855 break;
12856 case AFI_L2VPN:
12857 space = EVPN_ROUTE_PREFIXLEN;
12858 break;
12859 default:
12860 return 0;
12861 }
12862
12863 ts->counts[BGP_STATS_MAXBITLEN] = space;
12864
12865 for (dest = top; dest; dest = bgp_route_next(dest)) {
12866 if (ts->table->safi == SAFI_MPLS_VPN
12867 || ts->table->safi == SAFI_ENCAP
12868 || ts->table->safi == SAFI_EVPN) {
12869 struct bgp_table *table;
12870
12871 table = bgp_dest_get_bgp_table_info(dest);
12872 if (!table)
12873 continue;
12874
12875 top = bgp_table_top(table);
12876 for (ndest = bgp_table_top(table); ndest;
12877 ndest = bgp_route_next(ndest))
12878 bgp_table_stats_rn(ndest, top, ts, space);
12879 } else {
12880 bgp_table_stats_rn(dest, top, ts, space);
12881 }
12882 }
12883
12884 return 0;
12885 }
12886
12887 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
12888 struct json_object *json_array)
12889 {
12890 struct listnode *node, *nnode;
12891 struct bgp *bgp;
12892
12893 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
12894 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12895 }
12896
12897 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12898 safi_t safi, struct json_object *json_array)
12899 {
12900 struct bgp_table_stats ts;
12901 unsigned int i;
12902 int ret = CMD_SUCCESS;
12903 char temp_buf[20];
12904 struct json_object *json = NULL;
12905
12906 if (json_array)
12907 json = json_object_new_object();
12908
12909 if (!bgp->rib[afi][safi]) {
12910 char warning_msg[50];
12911
12912 snprintf(warning_msg, sizeof(warning_msg),
12913 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
12914 safi);
12915
12916 if (!json)
12917 vty_out(vty, "%s\n", warning_msg);
12918 else
12919 json_object_string_add(json, "warning", warning_msg);
12920
12921 ret = CMD_WARNING;
12922 goto end_table_stats;
12923 }
12924
12925 if (!json)
12926 vty_out(vty, "BGP %s RIB statistics (%s)\n",
12927 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
12928 else
12929 json_object_string_add(json, "instance", bgp->name_pretty);
12930
12931 /* labeled-unicast routes live in the unicast table */
12932 if (safi == SAFI_LABELED_UNICAST)
12933 safi = SAFI_UNICAST;
12934
12935 memset(&ts, 0, sizeof(ts));
12936 ts.table = bgp->rib[afi][safi];
12937 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
12938
12939 for (i = 0; i < BGP_STATS_MAX; i++) {
12940 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
12941 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
12942 continue;
12943
12944 switch (i) {
12945 case BGP_STATS_ASPATH_TOTHOPS:
12946 case BGP_STATS_ASPATH_TOTSIZE:
12947 if (!json) {
12948 snprintf(
12949 temp_buf, sizeof(temp_buf), "%12.2f",
12950 ts.counts[i]
12951 ? (float)ts.counts[i]
12952 / (float)ts.counts
12953 [BGP_STATS_ASPATH_COUNT]
12954 : 0);
12955 vty_out(vty, "%-30s: %s",
12956 table_stats_strs[i]
12957 [TABLE_STATS_IDX_VTY],
12958 temp_buf);
12959 } else {
12960 json_object_double_add(
12961 json,
12962 table_stats_strs[i]
12963 [TABLE_STATS_IDX_JSON],
12964 ts.counts[i]
12965 ? (double)ts.counts[i]
12966 / (double)ts.counts
12967 [BGP_STATS_ASPATH_COUNT]
12968 : 0);
12969 }
12970 break;
12971 case BGP_STATS_TOTPLEN:
12972 if (!json) {
12973 snprintf(
12974 temp_buf, sizeof(temp_buf), "%12.2f",
12975 ts.counts[i]
12976 ? (float)ts.counts[i]
12977 / (float)ts.counts
12978 [BGP_STATS_PREFIXES]
12979 : 0);
12980 vty_out(vty, "%-30s: %s",
12981 table_stats_strs[i]
12982 [TABLE_STATS_IDX_VTY],
12983 temp_buf);
12984 } else {
12985 json_object_double_add(
12986 json,
12987 table_stats_strs[i]
12988 [TABLE_STATS_IDX_JSON],
12989 ts.counts[i]
12990 ? (double)ts.counts[i]
12991 / (double)ts.counts
12992 [BGP_STATS_PREFIXES]
12993 : 0);
12994 }
12995 break;
12996 case BGP_STATS_SPACE:
12997 if (!json) {
12998 snprintf(temp_buf, sizeof(temp_buf), "%12g",
12999 ts.total_space);
13000 vty_out(vty, "%-30s: %s\n",
13001 table_stats_strs[i]
13002 [TABLE_STATS_IDX_VTY],
13003 temp_buf);
13004 } else {
13005 json_object_double_add(
13006 json,
13007 table_stats_strs[i]
13008 [TABLE_STATS_IDX_JSON],
13009 (double)ts.total_space);
13010 }
13011 if (afi == AFI_IP6) {
13012 if (!json) {
13013 snprintf(temp_buf, sizeof(temp_buf),
13014 "%12g",
13015 ts.total_space
13016 * pow(2.0, -128 + 32));
13017 vty_out(vty, "%30s: %s\n",
13018 "/32 equivalent %s\n",
13019 temp_buf);
13020 } else {
13021 json_object_double_add(
13022 json, "/32equivalent",
13023 (double)(ts.total_space
13024 * pow(2.0,
13025 -128 + 32)));
13026 }
13027 if (!json) {
13028 snprintf(temp_buf, sizeof(temp_buf),
13029 "%12g",
13030 ts.total_space
13031 * pow(2.0, -128 + 48));
13032 vty_out(vty, "%30s: %s\n",
13033 "/48 equivalent %s\n",
13034 temp_buf);
13035 } else {
13036 json_object_double_add(
13037 json, "/48equivalent",
13038 (double)(ts.total_space
13039 * pow(2.0,
13040 -128 + 48)));
13041 }
13042 } else {
13043 if (!json) {
13044 snprintf(temp_buf, sizeof(temp_buf),
13045 "%12.2f",
13046 ts.total_space * 100.
13047 * pow(2.0, -32));
13048 vty_out(vty, "%30s: %s\n",
13049 "% announced ", temp_buf);
13050 } else {
13051 json_object_double_add(
13052 json, "%announced",
13053 (double)(ts.total_space * 100.
13054 * pow(2.0, -32)));
13055 }
13056 if (!json) {
13057 snprintf(temp_buf, sizeof(temp_buf),
13058 "%12.2f",
13059 ts.total_space
13060 * pow(2.0, -32 + 8));
13061 vty_out(vty, "%30s: %s\n",
13062 "/8 equivalent ", temp_buf);
13063 } else {
13064 json_object_double_add(
13065 json, "/8equivalent",
13066 (double)(ts.total_space
13067 * pow(2.0, -32 + 8)));
13068 }
13069 if (!json) {
13070 snprintf(temp_buf, sizeof(temp_buf),
13071 "%12.2f",
13072 ts.total_space
13073 * pow(2.0, -32 + 24));
13074 vty_out(vty, "%30s: %s\n",
13075 "/24 equivalent ", temp_buf);
13076 } else {
13077 json_object_double_add(
13078 json, "/24equivalent",
13079 (double)(ts.total_space
13080 * pow(2.0, -32 + 24)));
13081 }
13082 }
13083 break;
13084 default:
13085 if (!json) {
13086 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
13087 ts.counts[i]);
13088 vty_out(vty, "%-30s: %s",
13089 table_stats_strs[i]
13090 [TABLE_STATS_IDX_VTY],
13091 temp_buf);
13092 } else {
13093 json_object_int_add(
13094 json,
13095 table_stats_strs[i]
13096 [TABLE_STATS_IDX_JSON],
13097 ts.counts[i]);
13098 }
13099 }
13100 if (!json)
13101 vty_out(vty, "\n");
13102 }
13103 end_table_stats:
13104 if (json)
13105 json_object_array_add(json_array, json);
13106 return ret;
13107 }
13108
13109 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
13110 safi_t safi, struct json_object *json_array)
13111 {
13112 if (!bgp) {
13113 bgp_table_stats_all(vty, afi, safi, json_array);
13114 return CMD_SUCCESS;
13115 }
13116
13117 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
13118 }
13119
13120 enum bgp_pcounts {
13121 PCOUNT_ADJ_IN = 0,
13122 PCOUNT_DAMPED,
13123 PCOUNT_REMOVED,
13124 PCOUNT_HISTORY,
13125 PCOUNT_STALE,
13126 PCOUNT_VALID,
13127 PCOUNT_ALL,
13128 PCOUNT_COUNTED,
13129 PCOUNT_BPATH_SELECTED,
13130 PCOUNT_PFCNT, /* the figure we display to users */
13131 PCOUNT_MAX,
13132 };
13133
13134 static const char *const pcount_strs[] = {
13135 [PCOUNT_ADJ_IN] = "Adj-in",
13136 [PCOUNT_DAMPED] = "Damped",
13137 [PCOUNT_REMOVED] = "Removed",
13138 [PCOUNT_HISTORY] = "History",
13139 [PCOUNT_STALE] = "Stale",
13140 [PCOUNT_VALID] = "Valid",
13141 [PCOUNT_ALL] = "All RIB",
13142 [PCOUNT_COUNTED] = "PfxCt counted",
13143 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
13144 [PCOUNT_PFCNT] = "Useable",
13145 [PCOUNT_MAX] = NULL,
13146 };
13147
13148 struct peer_pcounts {
13149 unsigned int count[PCOUNT_MAX];
13150 const struct peer *peer;
13151 const struct bgp_table *table;
13152 safi_t safi;
13153 };
13154
13155 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13156 {
13157 const struct bgp_adj_in *ain;
13158 const struct bgp_path_info *pi;
13159 const struct peer *peer = pc->peer;
13160
13161 for (ain = rn->adj_in; ain; ain = ain->next)
13162 if (ain->peer == peer)
13163 pc->count[PCOUNT_ADJ_IN]++;
13164
13165 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13166
13167 if (pi->peer != peer)
13168 continue;
13169
13170 pc->count[PCOUNT_ALL]++;
13171
13172 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13173 pc->count[PCOUNT_DAMPED]++;
13174 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13175 pc->count[PCOUNT_HISTORY]++;
13176 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13177 pc->count[PCOUNT_REMOVED]++;
13178 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13179 pc->count[PCOUNT_STALE]++;
13180 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13181 pc->count[PCOUNT_VALID]++;
13182 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13183 pc->count[PCOUNT_PFCNT]++;
13184 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13185 pc->count[PCOUNT_BPATH_SELECTED]++;
13186
13187 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13188 pc->count[PCOUNT_COUNTED]++;
13189 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13190 flog_err(
13191 EC_LIB_DEVELOPMENT,
13192 "Attempting to count but flags say it is unusable");
13193 } else {
13194 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13195 flog_err(
13196 EC_LIB_DEVELOPMENT,
13197 "Not counted but flags say we should");
13198 }
13199 }
13200 }
13201
13202 static int bgp_peer_count_walker(struct thread *t)
13203 {
13204 struct bgp_dest *rn, *rm;
13205 const struct bgp_table *table;
13206 struct peer_pcounts *pc = THREAD_ARG(t);
13207
13208 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13209 || pc->safi == SAFI_EVPN) {
13210 /* Special handling for 2-level routing tables. */
13211 for (rn = bgp_table_top(pc->table); rn;
13212 rn = bgp_route_next(rn)) {
13213 table = bgp_dest_get_bgp_table_info(rn);
13214 if (table != NULL)
13215 for (rm = bgp_table_top(table); rm;
13216 rm = bgp_route_next(rm))
13217 bgp_peer_count_proc(rm, pc);
13218 }
13219 } else
13220 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13221 bgp_peer_count_proc(rn, pc);
13222
13223 return 0;
13224 }
13225
13226 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13227 safi_t safi, bool use_json)
13228 {
13229 struct peer_pcounts pcounts = {.peer = peer};
13230 unsigned int i;
13231 json_object *json = NULL;
13232 json_object *json_loop = NULL;
13233
13234 if (use_json) {
13235 json = json_object_new_object();
13236 json_loop = json_object_new_object();
13237 }
13238
13239 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13240 || !peer->bgp->rib[afi][safi]) {
13241 if (use_json) {
13242 json_object_string_add(
13243 json, "warning",
13244 "No such neighbor or address family");
13245 vty_out(vty, "%s\n", json_object_to_json_string(json));
13246 json_object_free(json);
13247 json_object_free(json_loop);
13248 } else
13249 vty_out(vty, "%% No such neighbor or address family\n");
13250
13251 return CMD_WARNING;
13252 }
13253
13254 memset(&pcounts, 0, sizeof(pcounts));
13255 pcounts.peer = peer;
13256 pcounts.table = peer->bgp->rib[afi][safi];
13257 pcounts.safi = safi;
13258
13259 /* in-place call via thread subsystem so as to record execution time
13260 * stats for the thread-walk (i.e. ensure this can't be blamed on
13261 * on just vty_read()).
13262 */
13263 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13264
13265 if (use_json) {
13266 json_object_string_add(json, "prefixCountsFor", peer->host);
13267 json_object_string_add(json, "multiProtocol",
13268 get_afi_safi_str(afi, safi, true));
13269 json_object_int_add(json, "pfxCounter",
13270 peer->pcount[afi][safi]);
13271
13272 for (i = 0; i < PCOUNT_MAX; i++)
13273 json_object_int_add(json_loop, pcount_strs[i],
13274 pcounts.count[i]);
13275
13276 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13277
13278 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13279 json_object_string_add(json, "pfxctDriftFor",
13280 peer->host);
13281 json_object_string_add(
13282 json, "recommended",
13283 "Please report this bug, with the above command output");
13284 }
13285 vty_json(vty, json);
13286 } else {
13287
13288 if (peer->hostname
13289 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13290 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13291 peer->hostname, peer->host,
13292 get_afi_safi_str(afi, safi, false));
13293 } else {
13294 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13295 get_afi_safi_str(afi, safi, false));
13296 }
13297
13298 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13299 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13300
13301 for (i = 0; i < PCOUNT_MAX; i++)
13302 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13303 pcounts.count[i]);
13304
13305 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13306 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13307 vty_out(vty,
13308 "Please report this bug, with the above command output\n");
13309 }
13310 }
13311
13312 return CMD_SUCCESS;
13313 }
13314
13315 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13316 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13317 "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]",
13318 SHOW_STR
13319 IP_STR
13320 BGP_STR
13321 BGP_INSTANCE_HELP_STR
13322 BGP_AFI_HELP_STR
13323 BGP_SAFI_HELP_STR
13324 "Detailed information on TCP and BGP neighbor connections\n"
13325 "Neighbor to display information about\n"
13326 "Neighbor to display information about\n"
13327 "Neighbor on BGP configured interface\n"
13328 "Display detailed prefix count information\n"
13329 JSON_STR)
13330 {
13331 afi_t afi = AFI_IP6;
13332 safi_t safi = SAFI_UNICAST;
13333 struct peer *peer;
13334 int idx = 0;
13335 struct bgp *bgp = NULL;
13336 bool uj = use_json(argc, argv);
13337
13338 if (uj)
13339 argc--;
13340
13341 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13342 &bgp, uj);
13343 if (!idx)
13344 return CMD_WARNING;
13345
13346 argv_find(argv, argc, "neighbors", &idx);
13347 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13348 if (!peer)
13349 return CMD_WARNING;
13350
13351 return bgp_peer_counts(vty, peer, afi, safi, uj);
13352 }
13353
13354 #ifdef KEEP_OLD_VPN_COMMANDS
13355 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13356 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13357 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13358 SHOW_STR
13359 IP_STR
13360 BGP_STR
13361 BGP_VPNVX_HELP_STR
13362 "Display information about all VPNv4 NLRIs\n"
13363 "Detailed information on TCP and BGP neighbor connections\n"
13364 "Neighbor to display information about\n"
13365 "Neighbor to display information about\n"
13366 "Neighbor on BGP configured interface\n"
13367 "Display detailed prefix count information\n"
13368 JSON_STR)
13369 {
13370 int idx_peer = 6;
13371 struct peer *peer;
13372 bool uj = use_json(argc, argv);
13373
13374 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13375 if (!peer)
13376 return CMD_WARNING;
13377
13378 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13379 }
13380
13381 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13382 show_ip_bgp_vpn_all_route_prefix_cmd,
13383 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13384 SHOW_STR
13385 IP_STR
13386 BGP_STR
13387 BGP_VPNVX_HELP_STR
13388 "Display information about all VPNv4 NLRIs\n"
13389 "Network in the BGP routing table to display\n"
13390 "Network in the BGP routing table to display\n"
13391 JSON_STR)
13392 {
13393 int idx = 0;
13394 char *network = NULL;
13395 struct bgp *bgp = bgp_get_default();
13396 if (!bgp) {
13397 vty_out(vty, "Can't find default instance\n");
13398 return CMD_WARNING;
13399 }
13400
13401 if (argv_find(argv, argc, "A.B.C.D", &idx))
13402 network = argv[idx]->arg;
13403 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13404 network = argv[idx]->arg;
13405 else {
13406 vty_out(vty, "Unable to figure out Network\n");
13407 return CMD_WARNING;
13408 }
13409
13410 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13411 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13412 use_json(argc, argv));
13413 }
13414 #endif /* KEEP_OLD_VPN_COMMANDS */
13415
13416 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13417 show_bgp_l2vpn_evpn_route_prefix_cmd,
13418 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13419 SHOW_STR
13420 BGP_STR
13421 L2VPN_HELP_STR
13422 EVPN_HELP_STR
13423 "Network in the BGP routing table to display\n"
13424 "Network in the BGP routing table to display\n"
13425 "Network in the BGP routing table to display\n"
13426 "Network in the BGP routing table to display\n"
13427 JSON_STR)
13428 {
13429 int idx = 0;
13430 char *network = NULL;
13431 int prefix_check = 0;
13432
13433 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13434 argv_find(argv, argc, "X:X::X:X", &idx))
13435 network = argv[idx]->arg;
13436 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13437 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13438 network = argv[idx]->arg;
13439 prefix_check = 1;
13440 } else {
13441 vty_out(vty, "Unable to figure out Network\n");
13442 return CMD_WARNING;
13443 }
13444 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13445 prefix_check, BGP_PATH_SHOW_ALL,
13446 RPKI_NOT_BEING_USED, use_json(argc, argv));
13447 }
13448
13449 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
13450 struct bgp_table *table, int *header1,
13451 int *header2, json_object *json,
13452 json_object *json_scode,
13453 json_object *json_ocode, bool wide)
13454 {
13455 uint64_t version = table ? table->version : 0;
13456
13457 if (*header1) {
13458 if (json) {
13459 json_object_int_add(json, "bgpTableVersion", version);
13460 json_object_string_addf(json, "bgpLocalRouterId",
13461 "%pI4", &bgp->router_id);
13462 json_object_int_add(json, "defaultLocPrf",
13463 bgp->default_local_pref);
13464 json_object_int_add(json, "localAS", bgp->as);
13465 json_object_object_add(json, "bgpStatusCodes",
13466 json_scode);
13467 json_object_object_add(json, "bgpOriginCodes",
13468 json_ocode);
13469 } else {
13470 vty_out(vty,
13471 "BGP table version is %" PRIu64
13472 ", local router ID is %pI4, vrf id ",
13473 version, &bgp->router_id);
13474 if (bgp->vrf_id == VRF_UNKNOWN)
13475 vty_out(vty, "%s", VRFID_NONE_STR);
13476 else
13477 vty_out(vty, "%u", bgp->vrf_id);
13478 vty_out(vty, "\n");
13479 vty_out(vty, "Default local pref %u, ",
13480 bgp->default_local_pref);
13481 vty_out(vty, "local AS %u\n", bgp->as);
13482 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13483 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13484 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13485 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13486 }
13487 *header1 = 0;
13488 }
13489 if (*header2) {
13490 if (!json)
13491 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13492 : BGP_SHOW_HEADER));
13493 *header2 = 0;
13494 }
13495 }
13496
13497 static void
13498 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13499 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13500 const char *rmap_name, json_object *json, json_object *json_ar,
13501 json_object *json_scode, json_object *json_ocode,
13502 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13503 unsigned long *output_count, unsigned long *filtered_count)
13504 {
13505 struct bgp_adj_in *ain;
13506 struct bgp_adj_out *adj;
13507 struct bgp_dest *dest;
13508 struct bgp *bgp;
13509 struct attr attr;
13510 int ret;
13511 struct update_subgroup *subgrp;
13512 struct peer_af *paf;
13513 bool route_filtered;
13514 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13515 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13516 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13517 || (safi == SAFI_EVPN))
13518 ? true
13519 : false;
13520
13521 bgp = peer->bgp;
13522
13523 subgrp = peer_subgroup(peer, afi, safi);
13524
13525 if (type == bgp_show_adj_route_advertised && subgrp
13526 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13527 if (use_json) {
13528 json_object_int_add(json, "bgpTableVersion",
13529 table->version);
13530 json_object_string_addf(json, "bgpLocalRouterId",
13531 "%pI4", &bgp->router_id);
13532 json_object_int_add(json, "defaultLocPrf",
13533 bgp->default_local_pref);
13534 json_object_int_add(json, "localAS", bgp->as);
13535 json_object_object_add(json, "bgpStatusCodes",
13536 json_scode);
13537 json_object_object_add(json, "bgpOriginCodes",
13538 json_ocode);
13539 json_object_string_add(
13540 json, "bgpOriginatingDefaultNetwork",
13541 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13542 } else {
13543 vty_out(vty,
13544 "BGP table version is %" PRIu64
13545 ", local router ID is %pI4, vrf id ",
13546 table->version, &bgp->router_id);
13547 if (bgp->vrf_id == VRF_UNKNOWN)
13548 vty_out(vty, "%s", VRFID_NONE_STR);
13549 else
13550 vty_out(vty, "%u", bgp->vrf_id);
13551 vty_out(vty, "\n");
13552 vty_out(vty, "Default local pref %u, ",
13553 bgp->default_local_pref);
13554 vty_out(vty, "local AS %u\n", bgp->as);
13555 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13556 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13557 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13558 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13559
13560 vty_out(vty, "Originating default network %s\n\n",
13561 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13562 }
13563 *header1 = 0;
13564 }
13565
13566 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13567 if (type == bgp_show_adj_route_received
13568 || type == bgp_show_adj_route_filtered) {
13569 for (ain = dest->adj_in; ain; ain = ain->next) {
13570 if (ain->peer != peer)
13571 continue;
13572
13573 show_adj_route_header(vty, bgp, table, header1,
13574 header2, json, json_scode,
13575 json_ocode, wide);
13576
13577 if ((safi == SAFI_MPLS_VPN)
13578 || (safi == SAFI_ENCAP)
13579 || (safi == SAFI_EVPN)) {
13580 if (use_json)
13581 json_object_string_add(
13582 json_ar, "rd", rd_str);
13583 else if (show_rd && rd_str) {
13584 vty_out(vty,
13585 "Route Distinguisher: %s\n",
13586 rd_str);
13587 show_rd = false;
13588 }
13589 }
13590
13591 attr = *ain->attr;
13592 route_filtered = false;
13593
13594 /* Filter prefix using distribute list,
13595 * filter list or prefix list
13596 */
13597 const struct prefix *rn_p =
13598 bgp_dest_get_prefix(dest);
13599 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13600 safi))
13601 == FILTER_DENY)
13602 route_filtered = true;
13603
13604 /* Filter prefix using route-map */
13605 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13606 safi, rmap_name, NULL,
13607 0, NULL);
13608
13609 if (type == bgp_show_adj_route_filtered &&
13610 !route_filtered && ret != RMAP_DENY) {
13611 bgp_attr_undup(&attr, ain->attr);
13612 continue;
13613 }
13614
13615 if (type == bgp_show_adj_route_received
13616 && (route_filtered || ret == RMAP_DENY))
13617 (*filtered_count)++;
13618
13619 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
13620 use_json, json_ar, wide);
13621 bgp_attr_undup(&attr, ain->attr);
13622 (*output_count)++;
13623 }
13624 } else if (type == bgp_show_adj_route_advertised) {
13625 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13626 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13627 if (paf->peer != peer || !adj->attr)
13628 continue;
13629
13630 show_adj_route_header(vty, bgp, table,
13631 header1, header2,
13632 json, json_scode,
13633 json_ocode, wide);
13634
13635 const struct prefix *rn_p =
13636 bgp_dest_get_prefix(dest);
13637
13638 attr = *adj->attr;
13639 ret = bgp_output_modifier(
13640 peer, rn_p, &attr, afi, safi,
13641 rmap_name);
13642
13643 if (ret != RMAP_DENY) {
13644 if ((safi == SAFI_MPLS_VPN)
13645 || (safi == SAFI_ENCAP)
13646 || (safi == SAFI_EVPN)) {
13647 if (use_json)
13648 json_object_string_add(
13649 json_ar,
13650 "rd",
13651 rd_str);
13652 else if (show_rd
13653 && rd_str) {
13654 vty_out(vty,
13655 "Route Distinguisher: %s\n",
13656 rd_str);
13657 show_rd = false;
13658 }
13659 }
13660 route_vty_out_tmp(
13661 vty, dest, rn_p, &attr,
13662 safi, use_json, json_ar,
13663 wide);
13664 (*output_count)++;
13665 } else {
13666 (*filtered_count)++;
13667 }
13668
13669 bgp_attr_undup(&attr, adj->attr);
13670 }
13671 } else if (type == bgp_show_adj_route_bestpath) {
13672 struct bgp_path_info *pi;
13673
13674 show_adj_route_header(vty, bgp, table, header1, header2,
13675 json, json_scode, json_ocode,
13676 wide);
13677
13678 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13679 pi = pi->next) {
13680 if (pi->peer != peer)
13681 continue;
13682
13683 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13684 continue;
13685
13686 route_vty_out_tmp(vty, dest,
13687 bgp_dest_get_prefix(dest),
13688 pi->attr, safi, use_json,
13689 json_ar, wide);
13690 (*output_count)++;
13691 }
13692 }
13693 }
13694 }
13695
13696 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13697 safi_t safi, enum bgp_show_adj_route_type type,
13698 const char *rmap_name, uint16_t show_flags)
13699 {
13700 struct bgp *bgp;
13701 struct bgp_table *table;
13702 json_object *json = NULL;
13703 json_object *json_scode = NULL;
13704 json_object *json_ocode = NULL;
13705 json_object *json_ar = NULL;
13706 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13707
13708 /* Init BGP headers here so they're only displayed once
13709 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13710 */
13711 int header1 = 1;
13712 int header2 = 1;
13713
13714 /*
13715 * Initialize variables for each RD
13716 * All prefixes under an RD is aggregated within "json_routes"
13717 */
13718 char rd_str[BUFSIZ] = {0};
13719 json_object *json_routes = NULL;
13720
13721
13722 /* For 2-tier tables, prefix counts need to be
13723 * maintained across multiple runs of show_adj_route()
13724 */
13725 unsigned long output_count_per_rd;
13726 unsigned long filtered_count_per_rd;
13727 unsigned long output_count = 0;
13728 unsigned long filtered_count = 0;
13729
13730 if (use_json) {
13731 json = json_object_new_object();
13732 json_ar = json_object_new_object();
13733 json_scode = json_object_new_object();
13734 json_ocode = json_object_new_object();
13735
13736 json_object_string_add(json_scode, "suppressed", "s");
13737 json_object_string_add(json_scode, "damped", "d");
13738 json_object_string_add(json_scode, "history", "h");
13739 json_object_string_add(json_scode, "valid", "*");
13740 json_object_string_add(json_scode, "best", ">");
13741 json_object_string_add(json_scode, "multipath", "=");
13742 json_object_string_add(json_scode, "internal", "i");
13743 json_object_string_add(json_scode, "ribFailure", "r");
13744 json_object_string_add(json_scode, "stale", "S");
13745 json_object_string_add(json_scode, "removed", "R");
13746
13747 json_object_string_add(json_ocode, "igp", "i");
13748 json_object_string_add(json_ocode, "egp", "e");
13749 json_object_string_add(json_ocode, "incomplete", "?");
13750 }
13751
13752 if (!peer || !peer->afc[afi][safi]) {
13753 if (use_json) {
13754 json_object_string_add(
13755 json, "warning",
13756 "No such neighbor or address family");
13757 vty_out(vty, "%s\n", json_object_to_json_string(json));
13758 json_object_free(json);
13759 json_object_free(json_ar);
13760 json_object_free(json_scode);
13761 json_object_free(json_ocode);
13762 } else
13763 vty_out(vty, "%% No such neighbor or address family\n");
13764
13765 return CMD_WARNING;
13766 }
13767
13768 if ((type == bgp_show_adj_route_received
13769 || type == bgp_show_adj_route_filtered)
13770 && !CHECK_FLAG(peer->af_flags[afi][safi],
13771 PEER_FLAG_SOFT_RECONFIG)) {
13772 if (use_json) {
13773 json_object_string_add(
13774 json, "warning",
13775 "Inbound soft reconfiguration not enabled");
13776 vty_out(vty, "%s\n", json_object_to_json_string(json));
13777 json_object_free(json);
13778 json_object_free(json_ar);
13779 json_object_free(json_scode);
13780 json_object_free(json_ocode);
13781 } else
13782 vty_out(vty,
13783 "%% Inbound soft reconfiguration not enabled\n");
13784
13785 return CMD_WARNING;
13786 }
13787
13788 bgp = peer->bgp;
13789
13790 /* labeled-unicast routes live in the unicast table */
13791 if (safi == SAFI_LABELED_UNICAST)
13792 table = bgp->rib[afi][SAFI_UNICAST];
13793 else
13794 table = bgp->rib[afi][safi];
13795
13796 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13797 || (safi == SAFI_EVPN)) {
13798
13799 struct bgp_dest *dest;
13800
13801 for (dest = bgp_table_top(table); dest;
13802 dest = bgp_route_next(dest)) {
13803 table = bgp_dest_get_bgp_table_info(dest);
13804 if (!table)
13805 continue;
13806
13807 output_count_per_rd = 0;
13808 filtered_count_per_rd = 0;
13809
13810 if (use_json)
13811 json_routes = json_object_new_object();
13812
13813 const struct prefix_rd *prd;
13814 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13815 dest);
13816
13817 prefix_rd2str(prd, rd_str, sizeof(rd_str));
13818
13819 show_adj_route(vty, peer, table, afi, safi, type,
13820 rmap_name, json, json_routes, json_scode,
13821 json_ocode, show_flags, &header1,
13822 &header2, rd_str, &output_count_per_rd,
13823 &filtered_count_per_rd);
13824
13825 /* Don't include an empty RD in the output! */
13826 if (json_routes && (output_count_per_rd > 0))
13827 json_object_object_add(json_ar, rd_str,
13828 json_routes);
13829
13830 output_count += output_count_per_rd;
13831 filtered_count += filtered_count_per_rd;
13832 }
13833 } else
13834 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
13835 json, json_ar, json_scode, json_ocode,
13836 show_flags, &header1, &header2, rd_str,
13837 &output_count, &filtered_count);
13838
13839 if (use_json) {
13840 if (type == bgp_show_adj_route_advertised)
13841 json_object_object_add(json, "advertisedRoutes",
13842 json_ar);
13843 else
13844 json_object_object_add(json, "receivedRoutes", json_ar);
13845 json_object_int_add(json, "totalPrefixCounter", output_count);
13846 json_object_int_add(json, "filteredPrefixCounter",
13847 filtered_count);
13848
13849 /*
13850 * These fields only give up ownership to `json` when `header1`
13851 * is used (set to zero). See code in `show_adj_route` and
13852 * `show_adj_route_header`.
13853 */
13854 if (header1 == 1) {
13855 json_object_free(json_scode);
13856 json_object_free(json_ocode);
13857 }
13858
13859 vty_json(vty, json);
13860 } else if (output_count > 0) {
13861 if (filtered_count > 0)
13862 vty_out(vty,
13863 "\nTotal number of prefixes %ld (%ld filtered)\n",
13864 output_count, filtered_count);
13865 else
13866 vty_out(vty, "\nTotal number of prefixes %ld\n",
13867 output_count);
13868 }
13869
13870 return CMD_SUCCESS;
13871 }
13872
13873 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
13874 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
13875 "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]",
13876 SHOW_STR
13877 IP_STR
13878 BGP_STR
13879 BGP_INSTANCE_HELP_STR
13880 BGP_AFI_HELP_STR
13881 BGP_SAFI_WITH_LABEL_HELP_STR
13882 "Detailed information on TCP and BGP neighbor connections\n"
13883 "Neighbor to display information about\n"
13884 "Neighbor to display information about\n"
13885 "Neighbor on BGP configured interface\n"
13886 "Display the routes selected by best path\n"
13887 JSON_STR
13888 "Increase table width for longer prefixes\n")
13889 {
13890 afi_t afi = AFI_IP6;
13891 safi_t safi = SAFI_UNICAST;
13892 char *rmap_name = NULL;
13893 char *peerstr = NULL;
13894 struct bgp *bgp = NULL;
13895 struct peer *peer;
13896 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
13897 int idx = 0;
13898 uint16_t show_flags = 0;
13899
13900 if (uj)
13901 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13902
13903 if (wide)
13904 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13905
13906 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13907 &bgp, uj);
13908
13909 if (!idx)
13910 return CMD_WARNING;
13911
13912 argv_find(argv, argc, "neighbors", &idx);
13913 peerstr = argv[++idx]->arg;
13914
13915 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13916 if (!peer)
13917 return CMD_WARNING;
13918
13919 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13920 show_flags);
13921 }
13922
13923 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
13924 show_ip_bgp_instance_neighbor_advertised_route_cmd,
13925 "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]",
13926 SHOW_STR
13927 IP_STR
13928 BGP_STR
13929 BGP_INSTANCE_HELP_STR
13930 BGP_AFI_HELP_STR
13931 BGP_SAFI_WITH_LABEL_HELP_STR
13932 "Display the entries for all address families\n"
13933 "Detailed information on TCP and BGP neighbor connections\n"
13934 "Neighbor to display information about\n"
13935 "Neighbor to display information about\n"
13936 "Neighbor on BGP configured interface\n"
13937 "Display the routes advertised to a BGP neighbor\n"
13938 "Display the received routes from neighbor\n"
13939 "Display the filtered routes received from neighbor\n"
13940 "Route-map to modify the attributes\n"
13941 "Name of the route map\n"
13942 JSON_STR
13943 "Increase table width for longer prefixes\n")
13944 {
13945 afi_t afi = AFI_IP6;
13946 safi_t safi = SAFI_UNICAST;
13947 char *rmap_name = NULL;
13948 char *peerstr = NULL;
13949 struct bgp *bgp = NULL;
13950 struct peer *peer;
13951 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
13952 int idx = 0;
13953 bool first = true;
13954 uint16_t show_flags = 0;
13955
13956 if (uj) {
13957 argc--;
13958 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13959 }
13960
13961 if (all) {
13962 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
13963 if (argv_find(argv, argc, "ipv4", &idx))
13964 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
13965
13966 if (argv_find(argv, argc, "ipv6", &idx))
13967 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
13968 }
13969
13970 if (wide)
13971 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13972
13973 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13974 &bgp, uj);
13975 if (!idx)
13976 return CMD_WARNING;
13977
13978 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13979 argv_find(argv, argc, "neighbors", &idx);
13980 peerstr = argv[++idx]->arg;
13981
13982 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13983 if (!peer)
13984 return CMD_WARNING;
13985
13986 if (argv_find(argv, argc, "advertised-routes", &idx))
13987 type = bgp_show_adj_route_advertised;
13988 else if (argv_find(argv, argc, "received-routes", &idx))
13989 type = bgp_show_adj_route_received;
13990 else if (argv_find(argv, argc, "filtered-routes", &idx))
13991 type = bgp_show_adj_route_filtered;
13992
13993 if (argv_find(argv, argc, "route-map", &idx))
13994 rmap_name = argv[++idx]->arg;
13995
13996 if (!all)
13997 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13998 show_flags);
13999 if (uj)
14000 vty_out(vty, "{\n");
14001
14002 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
14003 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
14004 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
14005 : AFI_IP6;
14006 FOREACH_SAFI (safi) {
14007 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
14008 continue;
14009
14010 if (uj) {
14011 if (first)
14012 first = false;
14013 else
14014 vty_out(vty, ",\n");
14015 vty_out(vty, "\"%s\":",
14016 get_afi_safi_str(afi, safi, true));
14017 } else
14018 vty_out(vty, "\nFor address family: %s\n",
14019 get_afi_safi_str(afi, safi, false));
14020
14021 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14022 show_flags);
14023 }
14024 } else {
14025 FOREACH_AFI_SAFI (afi, safi) {
14026 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
14027 continue;
14028
14029 if (uj) {
14030 if (first)
14031 first = false;
14032 else
14033 vty_out(vty, ",\n");
14034 vty_out(vty, "\"%s\":",
14035 get_afi_safi_str(afi, safi, true));
14036 } else
14037 vty_out(vty, "\nFor address family: %s\n",
14038 get_afi_safi_str(afi, safi, false));
14039
14040 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
14041 show_flags);
14042 }
14043 }
14044 if (uj)
14045 vty_out(vty, "}\n");
14046
14047 return CMD_SUCCESS;
14048 }
14049
14050 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
14051 show_ip_bgp_neighbor_received_prefix_filter_cmd,
14052 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
14053 SHOW_STR
14054 IP_STR
14055 BGP_STR
14056 BGP_INSTANCE_HELP_STR
14057 "Address Family\n"
14058 "Address Family\n"
14059 "Address Family modifier\n"
14060 "Detailed information on TCP and BGP neighbor connections\n"
14061 "Neighbor to display information about\n"
14062 "Neighbor to display information about\n"
14063 "Neighbor on BGP configured interface\n"
14064 "Display information received from a BGP neighbor\n"
14065 "Display the prefixlist filter\n"
14066 JSON_STR)
14067 {
14068 afi_t afi = AFI_IP6;
14069 safi_t safi = SAFI_UNICAST;
14070 char *peerstr = NULL;
14071 char name[BUFSIZ];
14072 struct peer *peer;
14073 int count;
14074 int idx = 0;
14075 struct bgp *bgp = NULL;
14076 bool uj = use_json(argc, argv);
14077
14078 if (uj)
14079 argc--;
14080
14081 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14082 &bgp, uj);
14083 if (!idx)
14084 return CMD_WARNING;
14085
14086 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14087 argv_find(argv, argc, "neighbors", &idx);
14088 peerstr = argv[++idx]->arg;
14089
14090 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14091 if (!peer)
14092 return CMD_WARNING;
14093
14094 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
14095 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
14096 if (count) {
14097 if (!uj)
14098 vty_out(vty, "Address Family: %s\n",
14099 get_afi_safi_str(afi, safi, false));
14100 prefix_bgp_show_prefix_list(vty, afi, name, uj);
14101 } else {
14102 if (uj)
14103 vty_out(vty, "{}\n");
14104 else
14105 vty_out(vty, "No functional output\n");
14106 }
14107
14108 return CMD_SUCCESS;
14109 }
14110
14111 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
14112 afi_t afi, safi_t safi,
14113 enum bgp_show_type type, bool use_json)
14114 {
14115 uint16_t show_flags = 0;
14116
14117 if (use_json)
14118 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14119
14120 if (!peer || !peer->afc[afi][safi]) {
14121 if (use_json) {
14122 json_object *json_no = NULL;
14123 json_no = json_object_new_object();
14124 json_object_string_add(
14125 json_no, "warning",
14126 "No such neighbor or address family");
14127 vty_out(vty, "%s\n",
14128 json_object_to_json_string(json_no));
14129 json_object_free(json_no);
14130 } else
14131 vty_out(vty, "%% No such neighbor or address family\n");
14132 return CMD_WARNING;
14133 }
14134
14135 /* labeled-unicast routes live in the unicast table */
14136 if (safi == SAFI_LABELED_UNICAST)
14137 safi = SAFI_UNICAST;
14138
14139 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14140 RPKI_NOT_BEING_USED);
14141 }
14142
14143 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14144 show_ip_bgp_flowspec_routes_detailed_cmd,
14145 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14146 SHOW_STR
14147 IP_STR
14148 BGP_STR
14149 BGP_INSTANCE_HELP_STR
14150 BGP_AFI_HELP_STR
14151 "SAFI Flowspec\n"
14152 "Detailed information on flowspec entries\n"
14153 JSON_STR)
14154 {
14155 afi_t afi = AFI_IP6;
14156 safi_t safi = SAFI_UNICAST;
14157 struct bgp *bgp = NULL;
14158 int idx = 0;
14159 bool uj = use_json(argc, argv);
14160 uint16_t show_flags = 0;
14161
14162 if (uj) {
14163 argc--;
14164 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14165 }
14166
14167 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14168 &bgp, uj);
14169 if (!idx)
14170 return CMD_WARNING;
14171
14172 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14173 show_flags, RPKI_NOT_BEING_USED);
14174 }
14175
14176 DEFUN (show_ip_bgp_neighbor_routes,
14177 show_ip_bgp_neighbor_routes_cmd,
14178 "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]",
14179 SHOW_STR
14180 IP_STR
14181 BGP_STR
14182 BGP_INSTANCE_HELP_STR
14183 BGP_AFI_HELP_STR
14184 BGP_SAFI_WITH_LABEL_HELP_STR
14185 "Detailed information on TCP and BGP neighbor connections\n"
14186 "Neighbor to display information about\n"
14187 "Neighbor to display information about\n"
14188 "Neighbor on BGP configured interface\n"
14189 "Display flap statistics of the routes learned from neighbor\n"
14190 "Display the dampened routes received from neighbor\n"
14191 "Display routes learned from neighbor\n"
14192 JSON_STR)
14193 {
14194 char *peerstr = NULL;
14195 struct bgp *bgp = NULL;
14196 afi_t afi = AFI_IP6;
14197 safi_t safi = SAFI_UNICAST;
14198 struct peer *peer;
14199 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14200 int idx = 0;
14201 bool uj = use_json(argc, argv);
14202
14203 if (uj)
14204 argc--;
14205
14206 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14207 &bgp, uj);
14208 if (!idx)
14209 return CMD_WARNING;
14210
14211 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14212 argv_find(argv, argc, "neighbors", &idx);
14213 peerstr = argv[++idx]->arg;
14214
14215 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14216 if (!peer)
14217 return CMD_WARNING;
14218
14219 if (argv_find(argv, argc, "flap-statistics", &idx))
14220 sh_type = bgp_show_type_flap_neighbor;
14221 else if (argv_find(argv, argc, "dampened-routes", &idx))
14222 sh_type = bgp_show_type_damp_neighbor;
14223 else if (argv_find(argv, argc, "routes", &idx))
14224 sh_type = bgp_show_type_neighbor;
14225
14226 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14227 }
14228
14229 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14230
14231 struct bgp_distance {
14232 /* Distance value for the IP source prefix. */
14233 uint8_t distance;
14234
14235 /* Name of the access-list to be matched. */
14236 char *access_list;
14237 };
14238
14239 DEFUN (show_bgp_afi_vpn_rd_route,
14240 show_bgp_afi_vpn_rd_route_cmd,
14241 "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]",
14242 SHOW_STR
14243 BGP_STR
14244 BGP_AFI_HELP_STR
14245 "Address Family modifier\n"
14246 "Display information for a route distinguisher\n"
14247 "Route Distinguisher\n"
14248 "All Route Distinguishers\n"
14249 "Network in the BGP routing table to display\n"
14250 "Network in the BGP routing table to display\n"
14251 JSON_STR)
14252 {
14253 int ret;
14254 struct prefix_rd prd;
14255 afi_t afi = AFI_MAX;
14256 int idx = 0;
14257
14258 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14259 vty_out(vty, "%% Malformed Address Family\n");
14260 return CMD_WARNING;
14261 }
14262
14263 if (!strcmp(argv[5]->arg, "all"))
14264 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14265 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14266 RPKI_NOT_BEING_USED,
14267 use_json(argc, argv));
14268
14269 ret = str2prefix_rd(argv[5]->arg, &prd);
14270 if (!ret) {
14271 vty_out(vty, "%% Malformed Route Distinguisher\n");
14272 return CMD_WARNING;
14273 }
14274
14275 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14276 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14277 use_json(argc, argv));
14278 }
14279
14280 static struct bgp_distance *bgp_distance_new(void)
14281 {
14282 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14283 }
14284
14285 static void bgp_distance_free(struct bgp_distance *bdistance)
14286 {
14287 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14288 }
14289
14290 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14291 const char *ip_str, const char *access_list_str)
14292 {
14293 int ret;
14294 afi_t afi;
14295 safi_t safi;
14296 struct prefix p;
14297 uint8_t distance;
14298 struct bgp_dest *dest;
14299 struct bgp_distance *bdistance;
14300
14301 afi = bgp_node_afi(vty);
14302 safi = bgp_node_safi(vty);
14303
14304 ret = str2prefix(ip_str, &p);
14305 if (ret == 0) {
14306 vty_out(vty, "Malformed prefix\n");
14307 return CMD_WARNING_CONFIG_FAILED;
14308 }
14309
14310 distance = atoi(distance_str);
14311
14312 /* Get BGP distance node. */
14313 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14314 bdistance = bgp_dest_get_bgp_distance_info(dest);
14315 if (bdistance)
14316 bgp_dest_unlock_node(dest);
14317 else {
14318 bdistance = bgp_distance_new();
14319 bgp_dest_set_bgp_distance_info(dest, bdistance);
14320 }
14321
14322 /* Set distance value. */
14323 bdistance->distance = distance;
14324
14325 /* Reset access-list configuration. */
14326 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14327 if (access_list_str)
14328 bdistance->access_list =
14329 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14330
14331 return CMD_SUCCESS;
14332 }
14333
14334 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14335 const char *ip_str, const char *access_list_str)
14336 {
14337 int ret;
14338 afi_t afi;
14339 safi_t safi;
14340 struct prefix p;
14341 int distance;
14342 struct bgp_dest *dest;
14343 struct bgp_distance *bdistance;
14344
14345 afi = bgp_node_afi(vty);
14346 safi = bgp_node_safi(vty);
14347
14348 ret = str2prefix(ip_str, &p);
14349 if (ret == 0) {
14350 vty_out(vty, "Malformed prefix\n");
14351 return CMD_WARNING_CONFIG_FAILED;
14352 }
14353
14354 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14355 if (!dest) {
14356 vty_out(vty, "Can't find specified prefix\n");
14357 return CMD_WARNING_CONFIG_FAILED;
14358 }
14359
14360 bdistance = bgp_dest_get_bgp_distance_info(dest);
14361 distance = atoi(distance_str);
14362
14363 if (bdistance->distance != distance) {
14364 vty_out(vty, "Distance does not match configured\n");
14365 bgp_dest_unlock_node(dest);
14366 return CMD_WARNING_CONFIG_FAILED;
14367 }
14368
14369 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14370 bgp_distance_free(bdistance);
14371
14372 bgp_dest_set_bgp_path_info(dest, NULL);
14373 bgp_dest_unlock_node(dest);
14374 bgp_dest_unlock_node(dest);
14375
14376 return CMD_SUCCESS;
14377 }
14378
14379 /* Apply BGP information to distance method. */
14380 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14381 afi_t afi, safi_t safi, struct bgp *bgp)
14382 {
14383 struct bgp_dest *dest;
14384 struct prefix q = {0};
14385 struct peer *peer;
14386 struct bgp_distance *bdistance;
14387 struct access_list *alist;
14388 struct bgp_static *bgp_static;
14389
14390 if (!bgp)
14391 return 0;
14392
14393 peer = pinfo->peer;
14394
14395 if (pinfo->attr->distance)
14396 return pinfo->attr->distance;
14397
14398 /* Check source address.
14399 * Note: for aggregate route, peer can have unspec af type.
14400 */
14401 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14402 && !sockunion2hostprefix(&peer->su, &q))
14403 return 0;
14404
14405 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14406 if (dest) {
14407 bdistance = bgp_dest_get_bgp_distance_info(dest);
14408 bgp_dest_unlock_node(dest);
14409
14410 if (bdistance->access_list) {
14411 alist = access_list_lookup(afi, bdistance->access_list);
14412 if (alist
14413 && access_list_apply(alist, p) == FILTER_PERMIT)
14414 return bdistance->distance;
14415 } else
14416 return bdistance->distance;
14417 }
14418
14419 /* Backdoor check. */
14420 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14421 if (dest) {
14422 bgp_static = bgp_dest_get_bgp_static_info(dest);
14423 bgp_dest_unlock_node(dest);
14424
14425 if (bgp_static->backdoor) {
14426 if (bgp->distance_local[afi][safi])
14427 return bgp->distance_local[afi][safi];
14428 else
14429 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14430 }
14431 }
14432
14433 if (peer->sort == BGP_PEER_EBGP) {
14434 if (bgp->distance_ebgp[afi][safi])
14435 return bgp->distance_ebgp[afi][safi];
14436 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14437 } else if (peer->sort == BGP_PEER_IBGP) {
14438 if (bgp->distance_ibgp[afi][safi])
14439 return bgp->distance_ibgp[afi][safi];
14440 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14441 } else {
14442 if (bgp->distance_local[afi][safi])
14443 return bgp->distance_local[afi][safi];
14444 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14445 }
14446 }
14447
14448 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14449 * we should tell ZEBRA update the routes for a specific
14450 * AFI/SAFI to reflect changes in RIB.
14451 */
14452 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14453 afi_t update_afi,
14454 safi_t update_safi)
14455 {
14456 afi_t afi;
14457 safi_t safi;
14458
14459 FOREACH_AFI_SAFI (afi, safi) {
14460 if (!bgp_fibupd_safi(safi))
14461 continue;
14462
14463 if (afi != update_afi && safi != update_safi)
14464 continue;
14465
14466 if (BGP_DEBUG(zebra, ZEBRA))
14467 zlog_debug(
14468 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14469 __func__, afi, safi);
14470 bgp_zebra_announce_table(bgp, afi, safi);
14471 }
14472 }
14473
14474 DEFUN (bgp_distance,
14475 bgp_distance_cmd,
14476 "distance bgp (1-255) (1-255) (1-255)",
14477 "Define an administrative distance\n"
14478 "BGP distance\n"
14479 "Distance for routes external to the AS\n"
14480 "Distance for routes internal to the AS\n"
14481 "Distance for local routes\n")
14482 {
14483 VTY_DECLVAR_CONTEXT(bgp, bgp);
14484 int idx_number = 2;
14485 int idx_number_2 = 3;
14486 int idx_number_3 = 4;
14487 int distance_ebgp = atoi(argv[idx_number]->arg);
14488 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14489 int distance_local = atoi(argv[idx_number_3]->arg);
14490 afi_t afi;
14491 safi_t safi;
14492
14493 afi = bgp_node_afi(vty);
14494 safi = bgp_node_safi(vty);
14495
14496 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14497 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14498 || bgp->distance_local[afi][safi] != distance_local) {
14499 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14500 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14501 bgp->distance_local[afi][safi] = distance_local;
14502 bgp_announce_routes_distance_update(bgp, afi, safi);
14503 }
14504 return CMD_SUCCESS;
14505 }
14506
14507 DEFUN (no_bgp_distance,
14508 no_bgp_distance_cmd,
14509 "no distance bgp [(1-255) (1-255) (1-255)]",
14510 NO_STR
14511 "Define an administrative distance\n"
14512 "BGP distance\n"
14513 "Distance for routes external to the AS\n"
14514 "Distance for routes internal to the AS\n"
14515 "Distance for local routes\n")
14516 {
14517 VTY_DECLVAR_CONTEXT(bgp, bgp);
14518 afi_t afi;
14519 safi_t safi;
14520
14521 afi = bgp_node_afi(vty);
14522 safi = bgp_node_safi(vty);
14523
14524 if (bgp->distance_ebgp[afi][safi] != 0
14525 || bgp->distance_ibgp[afi][safi] != 0
14526 || bgp->distance_local[afi][safi] != 0) {
14527 bgp->distance_ebgp[afi][safi] = 0;
14528 bgp->distance_ibgp[afi][safi] = 0;
14529 bgp->distance_local[afi][safi] = 0;
14530 bgp_announce_routes_distance_update(bgp, afi, safi);
14531 }
14532 return CMD_SUCCESS;
14533 }
14534
14535
14536 DEFUN (bgp_distance_source,
14537 bgp_distance_source_cmd,
14538 "distance (1-255) A.B.C.D/M",
14539 "Define an administrative distance\n"
14540 "Administrative distance\n"
14541 "IP source prefix\n")
14542 {
14543 int idx_number = 1;
14544 int idx_ipv4_prefixlen = 2;
14545 bgp_distance_set(vty, argv[idx_number]->arg,
14546 argv[idx_ipv4_prefixlen]->arg, NULL);
14547 return CMD_SUCCESS;
14548 }
14549
14550 DEFUN (no_bgp_distance_source,
14551 no_bgp_distance_source_cmd,
14552 "no distance (1-255) A.B.C.D/M",
14553 NO_STR
14554 "Define an administrative distance\n"
14555 "Administrative distance\n"
14556 "IP source prefix\n")
14557 {
14558 int idx_number = 2;
14559 int idx_ipv4_prefixlen = 3;
14560 bgp_distance_unset(vty, argv[idx_number]->arg,
14561 argv[idx_ipv4_prefixlen]->arg, NULL);
14562 return CMD_SUCCESS;
14563 }
14564
14565 DEFUN (bgp_distance_source_access_list,
14566 bgp_distance_source_access_list_cmd,
14567 "distance (1-255) A.B.C.D/M WORD",
14568 "Define an administrative distance\n"
14569 "Administrative distance\n"
14570 "IP source prefix\n"
14571 "Access list name\n")
14572 {
14573 int idx_number = 1;
14574 int idx_ipv4_prefixlen = 2;
14575 int idx_word = 3;
14576 bgp_distance_set(vty, argv[idx_number]->arg,
14577 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14578 return CMD_SUCCESS;
14579 }
14580
14581 DEFUN (no_bgp_distance_source_access_list,
14582 no_bgp_distance_source_access_list_cmd,
14583 "no distance (1-255) A.B.C.D/M WORD",
14584 NO_STR
14585 "Define an administrative distance\n"
14586 "Administrative distance\n"
14587 "IP source prefix\n"
14588 "Access list name\n")
14589 {
14590 int idx_number = 2;
14591 int idx_ipv4_prefixlen = 3;
14592 int idx_word = 4;
14593 bgp_distance_unset(vty, argv[idx_number]->arg,
14594 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14595 return CMD_SUCCESS;
14596 }
14597
14598 DEFUN (ipv6_bgp_distance_source,
14599 ipv6_bgp_distance_source_cmd,
14600 "distance (1-255) X:X::X:X/M",
14601 "Define an administrative distance\n"
14602 "Administrative distance\n"
14603 "IP source prefix\n")
14604 {
14605 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
14606 return CMD_SUCCESS;
14607 }
14608
14609 DEFUN (no_ipv6_bgp_distance_source,
14610 no_ipv6_bgp_distance_source_cmd,
14611 "no distance (1-255) X:X::X:X/M",
14612 NO_STR
14613 "Define an administrative distance\n"
14614 "Administrative distance\n"
14615 "IP source prefix\n")
14616 {
14617 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
14618 return CMD_SUCCESS;
14619 }
14620
14621 DEFUN (ipv6_bgp_distance_source_access_list,
14622 ipv6_bgp_distance_source_access_list_cmd,
14623 "distance (1-255) X:X::X:X/M WORD",
14624 "Define an administrative distance\n"
14625 "Administrative distance\n"
14626 "IP source prefix\n"
14627 "Access list name\n")
14628 {
14629 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
14630 return CMD_SUCCESS;
14631 }
14632
14633 DEFUN (no_ipv6_bgp_distance_source_access_list,
14634 no_ipv6_bgp_distance_source_access_list_cmd,
14635 "no distance (1-255) X:X::X:X/M WORD",
14636 NO_STR
14637 "Define an administrative distance\n"
14638 "Administrative distance\n"
14639 "IP source prefix\n"
14640 "Access list name\n")
14641 {
14642 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
14643 return CMD_SUCCESS;
14644 }
14645
14646 DEFUN (bgp_damp_set,
14647 bgp_damp_set_cmd,
14648 "bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14649 "BGP Specific commands\n"
14650 "Enable route-flap dampening\n"
14651 "Half-life time for the penalty\n"
14652 "Value to start reusing a route\n"
14653 "Value to start suppressing a route\n"
14654 "Maximum duration to suppress a stable route\n")
14655 {
14656 VTY_DECLVAR_CONTEXT(bgp, bgp);
14657 int idx_half_life = 2;
14658 int idx_reuse = 3;
14659 int idx_suppress = 4;
14660 int idx_max_suppress = 5;
14661 int half = DEFAULT_HALF_LIFE * 60;
14662 int reuse = DEFAULT_REUSE;
14663 int suppress = DEFAULT_SUPPRESS;
14664 int max = 4 * half;
14665
14666 if (argc == 6) {
14667 half = atoi(argv[idx_half_life]->arg) * 60;
14668 reuse = atoi(argv[idx_reuse]->arg);
14669 suppress = atoi(argv[idx_suppress]->arg);
14670 max = atoi(argv[idx_max_suppress]->arg) * 60;
14671 } else if (argc == 3) {
14672 half = atoi(argv[idx_half_life]->arg) * 60;
14673 max = 4 * half;
14674 }
14675
14676 /*
14677 * These can't be 0 but our SA doesn't understand the
14678 * way our cli is constructed
14679 */
14680 assert(reuse);
14681 assert(half);
14682 if (suppress < reuse) {
14683 vty_out(vty,
14684 "Suppress value cannot be less than reuse value \n");
14685 return 0;
14686 }
14687
14688 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
14689 reuse, suppress, max);
14690 }
14691
14692 DEFUN (bgp_damp_unset,
14693 bgp_damp_unset_cmd,
14694 "no bgp dampening [(1-45) [(1-20000) (1-50000) (1-255)]]",
14695 NO_STR
14696 "BGP Specific commands\n"
14697 "Enable route-flap dampening\n"
14698 "Half-life time for the penalty\n"
14699 "Value to start reusing a route\n"
14700 "Value to start suppressing a route\n"
14701 "Maximum duration to suppress a stable route\n")
14702 {
14703 VTY_DECLVAR_CONTEXT(bgp, bgp);
14704 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
14705 }
14706
14707 /* Display specified route of BGP table. */
14708 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14709 const char *ip_str, afi_t afi, safi_t safi,
14710 struct prefix_rd *prd, int prefix_check)
14711 {
14712 int ret;
14713 struct prefix match;
14714 struct bgp_dest *dest;
14715 struct bgp_dest *rm;
14716 struct bgp_path_info *pi;
14717 struct bgp_path_info *pi_temp;
14718 struct bgp *bgp;
14719 struct bgp_table *table;
14720
14721 /* BGP structure lookup. */
14722 if (view_name) {
14723 bgp = bgp_lookup_by_name(view_name);
14724 if (bgp == NULL) {
14725 vty_out(vty, "%% Can't find BGP instance %s\n",
14726 view_name);
14727 return CMD_WARNING;
14728 }
14729 } else {
14730 bgp = bgp_get_default();
14731 if (bgp == NULL) {
14732 vty_out(vty, "%% No BGP process is configured\n");
14733 return CMD_WARNING;
14734 }
14735 }
14736
14737 /* Check IP address argument. */
14738 ret = str2prefix(ip_str, &match);
14739 if (!ret) {
14740 vty_out(vty, "%% address is malformed\n");
14741 return CMD_WARNING;
14742 }
14743
14744 match.family = afi2family(afi);
14745
14746 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14747 || (safi == SAFI_EVPN)) {
14748 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14749 dest = bgp_route_next(dest)) {
14750 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14751
14752 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14753 continue;
14754 table = bgp_dest_get_bgp_table_info(dest);
14755 if (!table)
14756 continue;
14757 rm = bgp_node_match(table, &match);
14758 if (rm == NULL)
14759 continue;
14760
14761 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
14762
14763 if (!prefix_check
14764 || rm_p->prefixlen == match.prefixlen) {
14765 pi = bgp_dest_get_bgp_path_info(rm);
14766 while (pi) {
14767 if (pi->extra && pi->extra->damp_info) {
14768 pi_temp = pi->next;
14769 bgp_damp_info_free(
14770 pi->extra->damp_info,
14771 1, afi, safi);
14772 pi = pi_temp;
14773 } else
14774 pi = pi->next;
14775 }
14776 }
14777
14778 bgp_dest_unlock_node(rm);
14779 }
14780 } else {
14781 dest = bgp_node_match(bgp->rib[afi][safi], &match);
14782 if (dest != NULL) {
14783 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14784
14785 if (!prefix_check
14786 || dest_p->prefixlen == match.prefixlen) {
14787 pi = bgp_dest_get_bgp_path_info(dest);
14788 while (pi) {
14789 if (pi->extra && pi->extra->damp_info) {
14790 pi_temp = pi->next;
14791 bgp_damp_info_free(
14792 pi->extra->damp_info,
14793 1, afi, safi);
14794 pi = pi_temp;
14795 } else
14796 pi = pi->next;
14797 }
14798 }
14799
14800 bgp_dest_unlock_node(dest);
14801 }
14802 }
14803
14804 return CMD_SUCCESS;
14805 }
14806
14807 DEFUN (clear_ip_bgp_dampening,
14808 clear_ip_bgp_dampening_cmd,
14809 "clear ip bgp dampening",
14810 CLEAR_STR
14811 IP_STR
14812 BGP_STR
14813 "Clear route flap dampening information\n")
14814 {
14815 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
14816 return CMD_SUCCESS;
14817 }
14818
14819 DEFUN (clear_ip_bgp_dampening_prefix,
14820 clear_ip_bgp_dampening_prefix_cmd,
14821 "clear ip bgp dampening A.B.C.D/M",
14822 CLEAR_STR
14823 IP_STR
14824 BGP_STR
14825 "Clear route flap dampening information\n"
14826 "IPv4 prefix\n")
14827 {
14828 int idx_ipv4_prefixlen = 4;
14829 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
14830 AFI_IP, SAFI_UNICAST, NULL, 1);
14831 }
14832
14833 DEFUN (clear_ip_bgp_dampening_address,
14834 clear_ip_bgp_dampening_address_cmd,
14835 "clear ip bgp dampening A.B.C.D",
14836 CLEAR_STR
14837 IP_STR
14838 BGP_STR
14839 "Clear route flap dampening information\n"
14840 "Network to clear damping information\n")
14841 {
14842 int idx_ipv4 = 4;
14843 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
14844 SAFI_UNICAST, NULL, 0);
14845 }
14846
14847 DEFUN (clear_ip_bgp_dampening_address_mask,
14848 clear_ip_bgp_dampening_address_mask_cmd,
14849 "clear ip bgp dampening A.B.C.D A.B.C.D",
14850 CLEAR_STR
14851 IP_STR
14852 BGP_STR
14853 "Clear route flap dampening information\n"
14854 "Network to clear damping information\n"
14855 "Network mask\n")
14856 {
14857 int idx_ipv4 = 4;
14858 int idx_ipv4_2 = 5;
14859 int ret;
14860 char prefix_str[BUFSIZ];
14861
14862 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
14863 prefix_str, sizeof(prefix_str));
14864 if (!ret) {
14865 vty_out(vty, "%% Inconsistent address and mask\n");
14866 return CMD_WARNING;
14867 }
14868
14869 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
14870 NULL, 0);
14871 }
14872
14873 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
14874 {
14875 struct vty *vty = arg;
14876 struct peer *peer = bucket->data;
14877 char buf[SU_ADDRSTRLEN];
14878
14879 vty_out(vty, "\tPeer: %s %s\n", peer->host,
14880 sockunion2str(&peer->su, buf, sizeof(buf)));
14881 }
14882
14883 DEFUN (show_bgp_listeners,
14884 show_bgp_listeners_cmd,
14885 "show bgp listeners",
14886 SHOW_STR
14887 BGP_STR
14888 "Display Listen Sockets and who created them\n")
14889 {
14890 bgp_dump_listener_info(vty);
14891
14892 return CMD_SUCCESS;
14893 }
14894
14895 DEFUN (show_bgp_peerhash,
14896 show_bgp_peerhash_cmd,
14897 "show bgp peerhash",
14898 SHOW_STR
14899 BGP_STR
14900 "Display information about the BGP peerhash\n")
14901 {
14902 struct list *instances = bm->bgp;
14903 struct listnode *node;
14904 struct bgp *bgp;
14905
14906 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
14907 vty_out(vty, "BGP: %s\n", bgp->name);
14908 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
14909 vty);
14910 }
14911
14912 return CMD_SUCCESS;
14913 }
14914
14915 /* also used for encap safi */
14916 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
14917 afi_t afi, safi_t safi)
14918 {
14919 struct bgp_dest *pdest;
14920 struct bgp_dest *dest;
14921 struct bgp_table *table;
14922 const struct prefix *p;
14923 const struct prefix_rd *prd;
14924 struct bgp_static *bgp_static;
14925 mpls_label_t label;
14926 char rdbuf[RD_ADDRSTRLEN];
14927
14928 /* Network configuration. */
14929 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14930 pdest = bgp_route_next(pdest)) {
14931 table = bgp_dest_get_bgp_table_info(pdest);
14932 if (!table)
14933 continue;
14934
14935 for (dest = bgp_table_top(table); dest;
14936 dest = bgp_route_next(dest)) {
14937 bgp_static = bgp_dest_get_bgp_static_info(dest);
14938 if (bgp_static == NULL)
14939 continue;
14940
14941 p = bgp_dest_get_prefix(dest);
14942 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14943 pdest);
14944
14945 /* "network" configuration display. */
14946 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14947 label = decode_label(&bgp_static->label);
14948
14949 vty_out(vty, " network %pFX rd %s", p, rdbuf);
14950 if (safi == SAFI_MPLS_VPN)
14951 vty_out(vty, " label %u", label);
14952
14953 if (bgp_static->rmap.name)
14954 vty_out(vty, " route-map %s",
14955 bgp_static->rmap.name);
14956
14957 if (bgp_static->backdoor)
14958 vty_out(vty, " backdoor");
14959
14960 vty_out(vty, "\n");
14961 }
14962 }
14963 }
14964
14965 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
14966 afi_t afi, safi_t safi)
14967 {
14968 struct bgp_dest *pdest;
14969 struct bgp_dest *dest;
14970 struct bgp_table *table;
14971 const struct prefix *p;
14972 const struct prefix_rd *prd;
14973 struct bgp_static *bgp_static;
14974 char buf[PREFIX_STRLEN * 2];
14975 char buf2[SU_ADDRSTRLEN];
14976 char rdbuf[RD_ADDRSTRLEN];
14977 char esi_buf[ESI_BYTES];
14978
14979 /* Network configuration. */
14980 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14981 pdest = bgp_route_next(pdest)) {
14982 table = bgp_dest_get_bgp_table_info(pdest);
14983 if (!table)
14984 continue;
14985
14986 for (dest = bgp_table_top(table); dest;
14987 dest = bgp_route_next(dest)) {
14988 bgp_static = bgp_dest_get_bgp_static_info(dest);
14989 if (bgp_static == NULL)
14990 continue;
14991
14992 char *macrouter = NULL;
14993
14994 if (bgp_static->router_mac)
14995 macrouter = prefix_mac2str(
14996 bgp_static->router_mac, NULL, 0);
14997 if (bgp_static->eth_s_id)
14998 esi_to_str(bgp_static->eth_s_id,
14999 esi_buf, sizeof(esi_buf));
15000 p = bgp_dest_get_prefix(dest);
15001 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
15002
15003 /* "network" configuration display. */
15004 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
15005 if (p->u.prefix_evpn.route_type == 5) {
15006 char local_buf[PREFIX_STRLEN];
15007 uint8_t family = is_evpn_prefix_ipaddr_v4((
15008 struct prefix_evpn *)p)
15009 ? AF_INET
15010 : AF_INET6;
15011 inet_ntop(family,
15012 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
15013 local_buf, PREFIX_STRLEN);
15014 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
15015 p->u.prefix_evpn.prefix_addr
15016 .ip_prefix_length);
15017 } else {
15018 prefix2str(p, buf, sizeof(buf));
15019 }
15020
15021 if (bgp_static->gatewayIp.family == AF_INET
15022 || bgp_static->gatewayIp.family == AF_INET6)
15023 inet_ntop(bgp_static->gatewayIp.family,
15024 &bgp_static->gatewayIp.u.prefix, buf2,
15025 sizeof(buf2));
15026 vty_out(vty,
15027 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
15028 buf, rdbuf,
15029 p->u.prefix_evpn.prefix_addr.eth_tag,
15030 decode_label(&bgp_static->label), esi_buf, buf2,
15031 macrouter);
15032
15033 XFREE(MTYPE_TMP, macrouter);
15034 }
15035 }
15036 }
15037
15038 /* Configuration of static route announcement and aggregate
15039 information. */
15040 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
15041 safi_t safi)
15042 {
15043 struct bgp_dest *dest;
15044 const struct prefix *p;
15045 struct bgp_static *bgp_static;
15046 struct bgp_aggregate *bgp_aggregate;
15047
15048 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
15049 bgp_config_write_network_vpn(vty, bgp, afi, safi);
15050 return;
15051 }
15052
15053 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
15054 bgp_config_write_network_evpn(vty, bgp, afi, safi);
15055 return;
15056 }
15057
15058 /* Network configuration. */
15059 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
15060 dest = bgp_route_next(dest)) {
15061 bgp_static = bgp_dest_get_bgp_static_info(dest);
15062 if (bgp_static == NULL)
15063 continue;
15064
15065 p = bgp_dest_get_prefix(dest);
15066
15067 vty_out(vty, " network %pFX", p);
15068
15069 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
15070 vty_out(vty, " label-index %u",
15071 bgp_static->label_index);
15072
15073 if (bgp_static->rmap.name)
15074 vty_out(vty, " route-map %s", bgp_static->rmap.name);
15075
15076 if (bgp_static->backdoor)
15077 vty_out(vty, " backdoor");
15078
15079 vty_out(vty, "\n");
15080 }
15081
15082 /* Aggregate-address configuration. */
15083 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
15084 dest = bgp_route_next(dest)) {
15085 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
15086 if (bgp_aggregate == NULL)
15087 continue;
15088
15089 p = bgp_dest_get_prefix(dest);
15090
15091 vty_out(vty, " aggregate-address %pFX", p);
15092
15093 if (bgp_aggregate->as_set)
15094 vty_out(vty, " as-set");
15095
15096 if (bgp_aggregate->summary_only)
15097 vty_out(vty, " summary-only");
15098
15099 if (bgp_aggregate->rmap.name)
15100 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
15101
15102 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
15103 vty_out(vty, " origin %s",
15104 bgp_origin2str(bgp_aggregate->origin));
15105
15106 if (bgp_aggregate->match_med)
15107 vty_out(vty, " matching-MED-only");
15108
15109 if (bgp_aggregate->suppress_map_name)
15110 vty_out(vty, " suppress-map %s",
15111 bgp_aggregate->suppress_map_name);
15112
15113 vty_out(vty, "\n");
15114 }
15115 }
15116
15117 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
15118 safi_t safi)
15119 {
15120 struct bgp_dest *dest;
15121 struct bgp_distance *bdistance;
15122
15123 /* Distance configuration. */
15124 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15125 && bgp->distance_local[afi][safi]
15126 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15127 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15128 || bgp->distance_local[afi][safi]
15129 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15130 vty_out(vty, " distance bgp %d %d %d\n",
15131 bgp->distance_ebgp[afi][safi],
15132 bgp->distance_ibgp[afi][safi],
15133 bgp->distance_local[afi][safi]);
15134 }
15135
15136 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15137 dest = bgp_route_next(dest)) {
15138 bdistance = bgp_dest_get_bgp_distance_info(dest);
15139 if (bdistance != NULL)
15140 vty_out(vty, " distance %d %pBD %s\n",
15141 bdistance->distance, dest,
15142 bdistance->access_list ? bdistance->access_list
15143 : "");
15144 }
15145 }
15146
15147 /* Allocate routing table structure and install commands. */
15148 void bgp_route_init(void)
15149 {
15150 afi_t afi;
15151 safi_t safi;
15152
15153 /* Init BGP distance table. */
15154 FOREACH_AFI_SAFI (afi, safi)
15155 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15156
15157 /* IPv4 BGP commands. */
15158 install_element(BGP_NODE, &bgp_table_map_cmd);
15159 install_element(BGP_NODE, &bgp_network_cmd);
15160 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15161
15162 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15163
15164 /* IPv4 unicast configuration. */
15165 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15166 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15167 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15168
15169 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15170
15171 /* IPv4 multicast configuration. */
15172 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15173 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15174 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15175 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15176
15177 /* IPv4 labeled-unicast configuration. */
15178 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15179 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15180
15181 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15182 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15183 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15184 install_element(VIEW_NODE, &show_ip_bgp_dampening_params_cmd);
15185 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15186 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15187 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15188 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15189
15190 install_element(VIEW_NODE,
15191 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15192 install_element(VIEW_NODE,
15193 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15194 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15195 install_element(VIEW_NODE,
15196 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15197 #ifdef KEEP_OLD_VPN_COMMANDS
15198 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15199 #endif /* KEEP_OLD_VPN_COMMANDS */
15200 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15201 install_element(VIEW_NODE,
15202 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15203
15204 /* BGP dampening clear commands */
15205 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15206 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15207
15208 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15209 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15210
15211 /* prefix count */
15212 install_element(ENABLE_NODE,
15213 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15214 #ifdef KEEP_OLD_VPN_COMMANDS
15215 install_element(ENABLE_NODE,
15216 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15217 #endif /* KEEP_OLD_VPN_COMMANDS */
15218
15219 /* New config IPv6 BGP commands. */
15220 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15221 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15222 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15223
15224 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15225
15226 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15227
15228 /* IPv6 labeled unicast address family. */
15229 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15230 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15231
15232 install_element(BGP_NODE, &bgp_distance_cmd);
15233 install_element(BGP_NODE, &no_bgp_distance_cmd);
15234 install_element(BGP_NODE, &bgp_distance_source_cmd);
15235 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15236 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15237 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15238 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15239 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15240 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15241 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15242 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15243 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15244 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15245 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15246 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15247 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15248 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15249 install_element(BGP_IPV4M_NODE,
15250 &no_bgp_distance_source_access_list_cmd);
15251 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15252 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15253 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15254 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15255 install_element(BGP_IPV6_NODE,
15256 &ipv6_bgp_distance_source_access_list_cmd);
15257 install_element(BGP_IPV6_NODE,
15258 &no_ipv6_bgp_distance_source_access_list_cmd);
15259 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15260 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15261 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15262 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15263 install_element(BGP_IPV6M_NODE,
15264 &ipv6_bgp_distance_source_access_list_cmd);
15265 install_element(BGP_IPV6M_NODE,
15266 &no_ipv6_bgp_distance_source_access_list_cmd);
15267
15268 /* BGP dampening */
15269 install_element(BGP_NODE, &bgp_damp_set_cmd);
15270 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15271 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15272 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15273 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15274 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15275 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15276 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15277 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15278 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15279 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15280 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15281 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15282 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15283
15284 /* Large Communities */
15285 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15286 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15287
15288 /* show bgp ipv4 flowspec detailed */
15289 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15290
15291 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15292 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15293 }
15294
15295 void bgp_route_finish(void)
15296 {
15297 afi_t afi;
15298 safi_t safi;
15299
15300 FOREACH_AFI_SAFI (afi, safi) {
15301 bgp_table_unlock(bgp_distance_table[afi][safi]);
15302 bgp_distance_table[afi][safi] = NULL;
15303 }
15304 }