]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
Merge pull request #8815 from idryzhov/fix-ospf-aggr
[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 #include "northbound.h"
92 #include "northbound_cli.h"
93 #include "bgpd/bgp_nb.h"
94
95 #ifndef VTYSH_EXTRACT_PL
96 #include "bgpd/bgp_route_clippy.c"
97 #endif
98
99 DEFINE_HOOK(bgp_snmp_update_stats,
100 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
101 (rn, pi, added));
102
103 DEFINE_HOOK(bgp_rpki_prefix_status,
104 (struct peer *peer, struct attr *attr,
105 const struct prefix *prefix),
106 (peer, attr, prefix));
107
108 /* Extern from bgp_dump.c */
109 extern const char *bgp_origin_str[];
110 extern const char *bgp_origin_long_str[];
111
112 /* PMSI strings. */
113 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
114 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
115 static const struct message bgp_pmsi_tnltype_str[] = {
116 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
117 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
118 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
119 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
120 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
121 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
122 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
123 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
124 {0}
125 };
126
127 #define VRFID_NONE_STR "-"
128
129 DEFINE_HOOK(bgp_process,
130 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
131 struct peer *peer, bool withdraw),
132 (bgp, afi, safi, bn, peer, withdraw));
133
134 /** Test if path is suppressed. */
135 static bool bgp_path_suppressed(struct bgp_path_info *pi)
136 {
137 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
138 return false;
139
140 return listcount(pi->extra->aggr_suppressors) > 0;
141 }
142
143 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
144 safi_t safi, const struct prefix *p,
145 struct prefix_rd *prd)
146 {
147 struct bgp_dest *dest;
148 struct bgp_dest *pdest = NULL;
149
150 assert(table);
151
152 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
153 || (safi == SAFI_EVPN)) {
154 pdest = bgp_node_get(table, (struct prefix *)prd);
155
156 if (!bgp_dest_has_bgp_path_info_data(pdest))
157 bgp_dest_set_bgp_table_info(
158 pdest, bgp_table_init(table->bgp, afi, safi));
159 else
160 bgp_dest_unlock_node(pdest);
161 table = bgp_dest_get_bgp_table_info(pdest);
162 }
163
164 dest = bgp_node_get(table, p);
165
166 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
167 || (safi == SAFI_EVPN))
168 dest->pdest = pdest;
169
170 return dest;
171 }
172
173 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
174 safi_t safi, const struct prefix *p,
175 struct prefix_rd *prd)
176 {
177 struct bgp_dest *dest;
178 struct bgp_dest *pdest = NULL;
179
180 if (!table)
181 return NULL;
182
183 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
184 || (safi == SAFI_EVPN)) {
185 pdest = bgp_node_lookup(table, (struct prefix *)prd);
186 if (!pdest)
187 return NULL;
188
189 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
190 bgp_dest_unlock_node(pdest);
191 return NULL;
192 }
193
194 table = bgp_dest_get_bgp_table_info(pdest);
195 }
196
197 dest = bgp_node_lookup(table, p);
198
199 return dest;
200 }
201
202 /* Allocate bgp_path_info_extra */
203 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
204 {
205 struct bgp_path_info_extra *new;
206 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
207 sizeof(struct bgp_path_info_extra));
208 new->label[0] = MPLS_INVALID_LABEL;
209 new->num_labels = 0;
210 new->bgp_fs_pbr = NULL;
211 new->bgp_fs_iprule = NULL;
212 return new;
213 }
214
215 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
216 {
217 struct bgp_path_info_extra *e;
218
219 if (!extra || !*extra)
220 return;
221
222 e = *extra;
223
224 e->damp_info = NULL;
225 if (e->parent) {
226 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
227
228 if (bpi->net) {
229 /* FIXME: since multiple e may have the same e->parent
230 * and e->parent->net is holding a refcount for each
231 * of them, we need to do some fudging here.
232 *
233 * WARNING: if bpi->net->lock drops to 0, bpi may be
234 * freed as well (because bpi->net was holding the
235 * last reference to bpi) => write after free!
236 */
237 unsigned refcount;
238
239 bpi = bgp_path_info_lock(bpi);
240 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
241 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
242 if (!refcount)
243 bpi->net = NULL;
244 bgp_path_info_unlock(bpi);
245 }
246 bgp_path_info_unlock(e->parent);
247 e->parent = NULL;
248 }
249
250 if (e->bgp_orig)
251 bgp_unlock(e->bgp_orig);
252
253 if (e->aggr_suppressors)
254 list_delete(&e->aggr_suppressors);
255
256 if (e->mh_info)
257 bgp_evpn_path_mh_info_free(e->mh_info);
258
259 if ((*extra)->bgp_fs_iprule)
260 list_delete(&((*extra)->bgp_fs_iprule));
261 if ((*extra)->bgp_fs_pbr)
262 list_delete(&((*extra)->bgp_fs_pbr));
263 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
264 }
265
266 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
267 * allocated if required.
268 */
269 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
270 {
271 if (!pi->extra)
272 pi->extra = bgp_path_info_extra_new();
273 return pi->extra;
274 }
275
276 /* Free bgp route information. */
277 static void bgp_path_info_free(struct bgp_path_info *path)
278 {
279 bgp_attr_unintern(&path->attr);
280
281 bgp_unlink_nexthop(path);
282 bgp_path_info_extra_free(&path->extra);
283 bgp_path_info_mpath_free(&path->mpath);
284 if (path->net)
285 bgp_addpath_free_info_data(&path->tx_addpath,
286 &path->net->tx_addpath);
287
288 peer_unlock(path->peer); /* bgp_path_info peer reference */
289
290 XFREE(MTYPE_BGP_ROUTE, path);
291 }
292
293 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
294 {
295 path->lock++;
296 return path;
297 }
298
299 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
300 {
301 assert(path && path->lock > 0);
302 path->lock--;
303
304 if (path->lock == 0) {
305 #if 0
306 zlog_debug ("%s: unlocked and freeing", __func__);
307 zlog_backtrace (LOG_DEBUG);
308 #endif
309 bgp_path_info_free(path);
310 return NULL;
311 }
312
313 #if 0
314 if (path->lock == 1)
315 {
316 zlog_debug ("%s: unlocked to 1", __func__);
317 zlog_backtrace (LOG_DEBUG);
318 }
319 #endif
320
321 return path;
322 }
323
324 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
325 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
326 {
327 struct peer *peer;
328 struct bgp_path_info *old_pi, *nextpi;
329 bool set_flag = false;
330 struct bgp *bgp = NULL;
331 struct bgp_table *table = NULL;
332 afi_t afi = 0;
333 safi_t safi = 0;
334
335 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
336 * then the route selection is deferred
337 */
338 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
339 return 0;
340
341 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
342 if (BGP_DEBUG(update, UPDATE_OUT))
343 zlog_debug(
344 "Route %pBD is in workqueue and being processed, not deferred.",
345 dest);
346
347 return 0;
348 }
349
350 table = bgp_dest_table(dest);
351 if (table) {
352 bgp = table->bgp;
353 afi = table->afi;
354 safi = table->safi;
355 }
356
357 for (old_pi = bgp_dest_get_bgp_path_info(dest);
358 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
359 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
360 continue;
361
362 /* Route selection is deferred if there is a stale path which
363 * which indicates peer is in restart mode
364 */
365 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
366 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
367 set_flag = true;
368 } else {
369 /* If the peer is graceful restart capable and peer is
370 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
371 */
372 peer = old_pi->peer;
373 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
374 && BGP_PEER_RESTARTING_MODE(peer)
375 && (old_pi
376 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
377 set_flag = true;
378 }
379 }
380 if (set_flag)
381 break;
382 }
383
384 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
385 * is active
386 */
387 if (set_flag && table) {
388 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
389 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
390 bgp->gr_info[afi][safi].gr_deferred++;
391 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
392 if (BGP_DEBUG(update, UPDATE_OUT))
393 zlog_debug("DEFER route %pBD, dest %p", dest,
394 dest);
395 return 0;
396 }
397 }
398 return -1;
399 }
400
401 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
402 {
403 struct bgp_path_info *top;
404
405 top = bgp_dest_get_bgp_path_info(dest);
406
407 pi->next = top;
408 pi->prev = NULL;
409 if (top)
410 top->prev = pi;
411 bgp_dest_set_bgp_path_info(dest, pi);
412
413 bgp_path_info_lock(pi);
414 bgp_dest_lock_node(dest);
415 peer_lock(pi->peer); /* bgp_path_info peer reference */
416 bgp_dest_set_defer_flag(dest, false);
417 hook_call(bgp_snmp_update_stats, dest, pi, true);
418 }
419
420 /* Do the actual removal of info from RIB, for use by bgp_process
421 completion callback *only* */
422 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
423 {
424 if (pi->next)
425 pi->next->prev = pi->prev;
426 if (pi->prev)
427 pi->prev->next = pi->next;
428 else
429 bgp_dest_set_bgp_path_info(dest, pi->next);
430
431 bgp_path_info_mpath_dequeue(pi);
432 bgp_path_info_unlock(pi);
433 hook_call(bgp_snmp_update_stats, dest, pi, false);
434 bgp_dest_unlock_node(dest);
435 }
436
437 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
438 {
439 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
440 /* set of previous already took care of pcount */
441 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
442 }
443
444 /* undo the effects of a previous call to bgp_path_info_delete; typically
445 called when a route is deleted and then quickly re-added before the
446 deletion has been processed */
447 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
448 {
449 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
450 /* unset of previous already took care of pcount */
451 SET_FLAG(pi->flags, BGP_PATH_VALID);
452 }
453
454 /* Adjust pcount as required */
455 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
456 {
457 struct bgp_table *table;
458
459 assert(dest && bgp_dest_table(dest));
460 assert(pi && pi->peer && pi->peer->bgp);
461
462 table = bgp_dest_table(dest);
463
464 if (pi->peer == pi->peer->bgp->peer_self)
465 return;
466
467 if (!BGP_PATH_COUNTABLE(pi)
468 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
469
470 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
471
472 /* slight hack, but more robust against errors. */
473 if (pi->peer->pcount[table->afi][table->safi])
474 pi->peer->pcount[table->afi][table->safi]--;
475 else
476 flog_err(EC_LIB_DEVELOPMENT,
477 "Asked to decrement 0 prefix count for peer");
478 } else if (BGP_PATH_COUNTABLE(pi)
479 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
480 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
481 pi->peer->pcount[table->afi][table->safi]++;
482 }
483 }
484
485 static int bgp_label_index_differs(struct bgp_path_info *pi1,
486 struct bgp_path_info *pi2)
487 {
488 return (!(pi1->attr->label_index == pi2->attr->label_index));
489 }
490
491 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
492 * This is here primarily to keep prefix-count in check.
493 */
494 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
495 uint32_t flag)
496 {
497 SET_FLAG(pi->flags, flag);
498
499 /* early bath if we know it's not a flag that changes countability state
500 */
501 if (!CHECK_FLAG(flag,
502 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
503 return;
504
505 bgp_pcount_adjust(dest, pi);
506 }
507
508 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
509 uint32_t flag)
510 {
511 UNSET_FLAG(pi->flags, flag);
512
513 /* early bath if we know it's not a flag that changes countability state
514 */
515 if (!CHECK_FLAG(flag,
516 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
517 return;
518
519 bgp_pcount_adjust(dest, pi);
520 }
521
522 /* Get MED value. If MED value is missing and "bgp bestpath
523 missing-as-worst" is specified, treat it as the worst value. */
524 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
525 {
526 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
527 return attr->med;
528 else {
529 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
530 return BGP_MED_MAX;
531 else
532 return 0;
533 }
534 }
535
536 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
537 size_t buf_len)
538 {
539 if (pi->addpath_rx_id)
540 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
541 pi->peer->host, pi->addpath_rx_id);
542 else
543 snprintf(buf, buf_len, "path %s", pi->peer->host);
544 }
545
546 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
547 */
548 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
549 struct bgp_path_info *exist, int *paths_eq,
550 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
551 char *pfx_buf, afi_t afi, safi_t safi,
552 enum bgp_path_selection_reason *reason)
553 {
554 const struct prefix *new_p;
555 struct attr *newattr, *existattr;
556 bgp_peer_sort_t new_sort;
557 bgp_peer_sort_t exist_sort;
558 uint32_t new_pref;
559 uint32_t exist_pref;
560 uint32_t new_med;
561 uint32_t exist_med;
562 uint32_t new_weight;
563 uint32_t exist_weight;
564 uint32_t newm, existm;
565 struct in_addr new_id;
566 struct in_addr exist_id;
567 int new_cluster;
568 int exist_cluster;
569 int internal_as_route;
570 int confed_as_route;
571 int ret = 0;
572 int igp_metric_ret = 0;
573 int peer_sort_ret = -1;
574 char new_buf[PATH_ADDPATH_STR_BUFFER];
575 char exist_buf[PATH_ADDPATH_STR_BUFFER];
576 uint32_t new_mm_seq;
577 uint32_t exist_mm_seq;
578 int nh_cmp;
579 esi_t *exist_esi;
580 esi_t *new_esi;
581 bool same_esi;
582 bool old_proxy;
583 bool new_proxy;
584 bool new_origin, exist_origin;
585
586 *paths_eq = 0;
587
588 /* 0. Null check. */
589 if (new == NULL) {
590 *reason = bgp_path_selection_none;
591 if (debug)
592 zlog_debug("%s: new is NULL", pfx_buf);
593 return 0;
594 }
595
596 if (debug)
597 bgp_path_info_path_with_addpath_rx_str(new, new_buf,
598 sizeof(new_buf));
599
600 if (exist == NULL) {
601 *reason = bgp_path_selection_first;
602 if (debug)
603 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
604 new_buf);
605 return 1;
606 }
607
608 if (debug) {
609 bgp_path_info_path_with_addpath_rx_str(exist, exist_buf,
610 sizeof(exist_buf));
611 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
612 pfx_buf, new_buf, new->flags, exist_buf,
613 exist->flags);
614 }
615
616 newattr = new->attr;
617 existattr = exist->attr;
618
619 new_p = bgp_dest_get_prefix(new->net);
620
621 /* For EVPN routes, we cannot just go by local vs remote, we have to
622 * look at the MAC mobility sequence number, if present.
623 */
624 if ((safi == SAFI_EVPN)
625 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
626 /* This is an error condition described in RFC 7432 Section
627 * 15.2. The RFC
628 * states that in this scenario "the PE MUST alert the operator"
629 * but it
630 * does not state what other action to take. In order to provide
631 * some
632 * consistency in this scenario we are going to prefer the path
633 * with the
634 * sticky flag.
635 */
636 if (newattr->sticky != existattr->sticky) {
637 if (!debug) {
638 prefix2str(new_p, pfx_buf,
639 sizeof(*pfx_buf)
640 * PREFIX2STR_BUFFER);
641 bgp_path_info_path_with_addpath_rx_str(
642 new, new_buf, sizeof(new_buf));
643 bgp_path_info_path_with_addpath_rx_str(
644 exist, exist_buf, sizeof(exist_buf));
645 }
646
647 if (newattr->sticky && !existattr->sticky) {
648 *reason = bgp_path_selection_evpn_sticky_mac;
649 if (debug)
650 zlog_debug(
651 "%s: %s wins over %s due to sticky MAC flag",
652 pfx_buf, new_buf, exist_buf);
653 return 1;
654 }
655
656 if (!newattr->sticky && existattr->sticky) {
657 *reason = bgp_path_selection_evpn_sticky_mac;
658 if (debug)
659 zlog_debug(
660 "%s: %s loses to %s due to sticky MAC flag",
661 pfx_buf, new_buf, exist_buf);
662 return 0;
663 }
664 }
665
666 new_esi = bgp_evpn_attr_get_esi(newattr);
667 exist_esi = bgp_evpn_attr_get_esi(existattr);
668 if (bgp_evpn_is_esi_valid(new_esi) &&
669 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
670 same_esi = true;
671 } else {
672 same_esi = false;
673 }
674
675 /* If both paths have the same non-zero ES and
676 * one path is local it wins.
677 * PS: Note the local path wins even if the remote
678 * has the higher MM seq. The local path's
679 * MM seq will be fixed up to match the highest
680 * rem seq, subsequently.
681 */
682 if (same_esi) {
683 char esi_buf[ESI_STR_LEN];
684
685 if (bgp_evpn_is_path_local(bgp, new)) {
686 *reason = bgp_path_selection_evpn_local_path;
687 if (debug)
688 zlog_debug(
689 "%s: %s wins over %s as ES %s is same and local",
690 pfx_buf, new_buf, exist_buf,
691 esi_to_str(new_esi, esi_buf,
692 sizeof(esi_buf)));
693 return 1;
694 }
695 if (bgp_evpn_is_path_local(bgp, exist)) {
696 *reason = bgp_path_selection_evpn_local_path;
697 if (debug)
698 zlog_debug(
699 "%s: %s loses to %s as ES %s is same and local",
700 pfx_buf, new_buf, exist_buf,
701 esi_to_str(new_esi, esi_buf,
702 sizeof(esi_buf)));
703 return 0;
704 }
705 }
706
707 new_mm_seq = mac_mobility_seqnum(newattr);
708 exist_mm_seq = mac_mobility_seqnum(existattr);
709
710 if (new_mm_seq > exist_mm_seq) {
711 *reason = bgp_path_selection_evpn_seq;
712 if (debug)
713 zlog_debug(
714 "%s: %s wins over %s due to MM seq %u > %u",
715 pfx_buf, new_buf, exist_buf, new_mm_seq,
716 exist_mm_seq);
717 return 1;
718 }
719
720 if (new_mm_seq < exist_mm_seq) {
721 *reason = bgp_path_selection_evpn_seq;
722 if (debug)
723 zlog_debug(
724 "%s: %s loses to %s due to MM seq %u < %u",
725 pfx_buf, new_buf, exist_buf, new_mm_seq,
726 exist_mm_seq);
727 return 0;
728 }
729
730 /* if the sequence numbers and ESI are the same and one path
731 * is non-proxy it wins (over proxy)
732 */
733 new_proxy = bgp_evpn_attr_is_proxy(newattr);
734 old_proxy = bgp_evpn_attr_is_proxy(existattr);
735 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
736 old_proxy != new_proxy) {
737 if (!new_proxy) {
738 *reason = bgp_path_selection_evpn_non_proxy;
739 if (debug)
740 zlog_debug(
741 "%s: %s wins over %s, same seq/es and non-proxy",
742 pfx_buf, new_buf, exist_buf);
743 return 1;
744 }
745
746 *reason = bgp_path_selection_evpn_non_proxy;
747 if (debug)
748 zlog_debug(
749 "%s: %s loses to %s, same seq/es and non-proxy",
750 pfx_buf, new_buf, exist_buf);
751 return 0;
752 }
753
754 /*
755 * if sequence numbers are the same path with the lowest IP
756 * wins
757 */
758 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
759 if (nh_cmp < 0) {
760 *reason = bgp_path_selection_evpn_lower_ip;
761 if (debug)
762 zlog_debug(
763 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
764 pfx_buf, new_buf, exist_buf, new_mm_seq,
765 &new->attr->nexthop);
766 return 1;
767 }
768 if (nh_cmp > 0) {
769 *reason = bgp_path_selection_evpn_lower_ip;
770 if (debug)
771 zlog_debug(
772 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
773 pfx_buf, new_buf, exist_buf, new_mm_seq,
774 &new->attr->nexthop);
775 return 0;
776 }
777 }
778
779 /* 1. Weight check. */
780 new_weight = newattr->weight;
781 exist_weight = existattr->weight;
782
783 if (new_weight > exist_weight) {
784 *reason = bgp_path_selection_weight;
785 if (debug)
786 zlog_debug("%s: %s wins over %s due to weight %d > %d",
787 pfx_buf, new_buf, exist_buf, new_weight,
788 exist_weight);
789 return 1;
790 }
791
792 if (new_weight < exist_weight) {
793 *reason = bgp_path_selection_weight;
794 if (debug)
795 zlog_debug("%s: %s loses to %s due to weight %d < %d",
796 pfx_buf, new_buf, exist_buf, new_weight,
797 exist_weight);
798 return 0;
799 }
800
801 /* 2. Local preference check. */
802 new_pref = exist_pref = bgp->default_local_pref;
803
804 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
805 new_pref = newattr->local_pref;
806 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
807 exist_pref = existattr->local_pref;
808
809 if (new_pref > exist_pref) {
810 *reason = bgp_path_selection_local_pref;
811 if (debug)
812 zlog_debug(
813 "%s: %s wins over %s due to localpref %d > %d",
814 pfx_buf, new_buf, exist_buf, new_pref,
815 exist_pref);
816 return 1;
817 }
818
819 if (new_pref < exist_pref) {
820 *reason = bgp_path_selection_local_pref;
821 if (debug)
822 zlog_debug(
823 "%s: %s loses to %s due to localpref %d < %d",
824 pfx_buf, new_buf, exist_buf, new_pref,
825 exist_pref);
826 return 0;
827 }
828
829 /* 3. Local route check. We prefer:
830 * - BGP_ROUTE_STATIC
831 * - BGP_ROUTE_AGGREGATE
832 * - BGP_ROUTE_REDISTRIBUTE
833 */
834 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
835 new->sub_type == BGP_ROUTE_IMPORTED);
836 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
837 exist->sub_type == BGP_ROUTE_IMPORTED);
838
839 if (new_origin && !exist_origin) {
840 *reason = bgp_path_selection_local_route;
841 if (debug)
842 zlog_debug(
843 "%s: %s wins over %s due to preferred BGP_ROUTE type",
844 pfx_buf, new_buf, exist_buf);
845 return 1;
846 }
847
848 if (!new_origin && exist_origin) {
849 *reason = bgp_path_selection_local_route;
850 if (debug)
851 zlog_debug(
852 "%s: %s loses to %s due to preferred BGP_ROUTE type",
853 pfx_buf, new_buf, exist_buf);
854 return 0;
855 }
856
857 /* 4. AS path length check. */
858 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
859 int exist_hops = aspath_count_hops(existattr->aspath);
860 int exist_confeds = aspath_count_confeds(existattr->aspath);
861
862 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
863 int aspath_hops;
864
865 aspath_hops = aspath_count_hops(newattr->aspath);
866 aspath_hops += aspath_count_confeds(newattr->aspath);
867
868 if (aspath_hops < (exist_hops + exist_confeds)) {
869 *reason = bgp_path_selection_confed_as_path;
870 if (debug)
871 zlog_debug(
872 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
873 pfx_buf, new_buf, exist_buf,
874 aspath_hops,
875 (exist_hops + exist_confeds));
876 return 1;
877 }
878
879 if (aspath_hops > (exist_hops + exist_confeds)) {
880 *reason = bgp_path_selection_confed_as_path;
881 if (debug)
882 zlog_debug(
883 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
884 pfx_buf, new_buf, exist_buf,
885 aspath_hops,
886 (exist_hops + exist_confeds));
887 return 0;
888 }
889 } else {
890 int newhops = aspath_count_hops(newattr->aspath);
891
892 if (newhops < exist_hops) {
893 *reason = bgp_path_selection_as_path;
894 if (debug)
895 zlog_debug(
896 "%s: %s wins over %s due to aspath hopcount %d < %d",
897 pfx_buf, new_buf, exist_buf,
898 newhops, exist_hops);
899 return 1;
900 }
901
902 if (newhops > exist_hops) {
903 *reason = bgp_path_selection_as_path;
904 if (debug)
905 zlog_debug(
906 "%s: %s loses to %s due to aspath hopcount %d > %d",
907 pfx_buf, new_buf, exist_buf,
908 newhops, exist_hops);
909 return 0;
910 }
911 }
912 }
913
914 /* 5. Origin check. */
915 if (newattr->origin < existattr->origin) {
916 *reason = bgp_path_selection_origin;
917 if (debug)
918 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
919 pfx_buf, new_buf, exist_buf,
920 bgp_origin_long_str[newattr->origin],
921 bgp_origin_long_str[existattr->origin]);
922 return 1;
923 }
924
925 if (newattr->origin > existattr->origin) {
926 *reason = bgp_path_selection_origin;
927 if (debug)
928 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
929 pfx_buf, new_buf, exist_buf,
930 bgp_origin_long_str[newattr->origin],
931 bgp_origin_long_str[existattr->origin]);
932 return 0;
933 }
934
935 /* 6. MED check. */
936 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
937 && aspath_count_hops(existattr->aspath) == 0);
938 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
939 && aspath_count_confeds(existattr->aspath) > 0
940 && aspath_count_hops(newattr->aspath) == 0
941 && aspath_count_hops(existattr->aspath) == 0);
942
943 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
944 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
945 || aspath_cmp_left(newattr->aspath, existattr->aspath)
946 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
947 || internal_as_route) {
948 new_med = bgp_med_value(new->attr, bgp);
949 exist_med = bgp_med_value(exist->attr, bgp);
950
951 if (new_med < exist_med) {
952 *reason = bgp_path_selection_med;
953 if (debug)
954 zlog_debug(
955 "%s: %s wins over %s due to MED %d < %d",
956 pfx_buf, new_buf, exist_buf, new_med,
957 exist_med);
958 return 1;
959 }
960
961 if (new_med > exist_med) {
962 *reason = bgp_path_selection_med;
963 if (debug)
964 zlog_debug(
965 "%s: %s loses to %s due to MED %d > %d",
966 pfx_buf, new_buf, exist_buf, new_med,
967 exist_med);
968 return 0;
969 }
970 }
971
972 /* 7. Peer type check. */
973 new_sort = new->peer->sort;
974 exist_sort = exist->peer->sort;
975
976 if (new_sort == BGP_PEER_EBGP
977 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
978 *reason = bgp_path_selection_peer;
979 if (debug)
980 zlog_debug(
981 "%s: %s wins over %s due to eBGP peer > iBGP peer",
982 pfx_buf, new_buf, exist_buf);
983 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
984 return 1;
985 peer_sort_ret = 1;
986 }
987
988 if (exist_sort == BGP_PEER_EBGP
989 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
990 *reason = bgp_path_selection_peer;
991 if (debug)
992 zlog_debug(
993 "%s: %s loses to %s due to iBGP peer < eBGP peer",
994 pfx_buf, new_buf, exist_buf);
995 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
996 return 0;
997 peer_sort_ret = 0;
998 }
999
1000 /* 8. IGP metric check. */
1001 newm = existm = 0;
1002
1003 if (new->extra)
1004 newm = new->extra->igpmetric;
1005 if (exist->extra)
1006 existm = exist->extra->igpmetric;
1007
1008 if (newm < existm) {
1009 if (debug && peer_sort_ret < 0)
1010 zlog_debug(
1011 "%s: %s wins over %s due to IGP metric %u < %u",
1012 pfx_buf, new_buf, exist_buf, newm, existm);
1013 igp_metric_ret = 1;
1014 }
1015
1016 if (newm > existm) {
1017 if (debug && peer_sort_ret < 0)
1018 zlog_debug(
1019 "%s: %s loses to %s due to IGP metric %u > %u",
1020 pfx_buf, new_buf, exist_buf, newm, existm);
1021 igp_metric_ret = 0;
1022 }
1023
1024 /* 9. Same IGP metric. Compare the cluster list length as
1025 representative of IGP hops metric. Rewrite the metric value
1026 pair (newm, existm) with the cluster list length. Prefer the
1027 path with smaller cluster list length. */
1028 if (newm == existm) {
1029 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
1030 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
1031 && (mpath_cfg == NULL
1032 || CHECK_FLAG(
1033 mpath_cfg->ibgp_flags,
1034 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
1035 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1036 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1037
1038 if (newm < existm) {
1039 if (debug && peer_sort_ret < 0)
1040 zlog_debug(
1041 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1042 pfx_buf, new_buf, exist_buf,
1043 newm, existm);
1044 igp_metric_ret = 1;
1045 }
1046
1047 if (newm > existm) {
1048 if (debug && peer_sort_ret < 0)
1049 zlog_debug(
1050 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1051 pfx_buf, new_buf, exist_buf,
1052 newm, existm);
1053 igp_metric_ret = 0;
1054 }
1055 }
1056 }
1057
1058 /* 10. confed-external vs. confed-internal */
1059 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1060 if (new_sort == BGP_PEER_CONFED
1061 && exist_sort == BGP_PEER_IBGP) {
1062 *reason = bgp_path_selection_confed;
1063 if (debug)
1064 zlog_debug(
1065 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1066 pfx_buf, new_buf, exist_buf);
1067 if (!CHECK_FLAG(bgp->flags,
1068 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1069 return 1;
1070 peer_sort_ret = 1;
1071 }
1072
1073 if (exist_sort == BGP_PEER_CONFED
1074 && new_sort == BGP_PEER_IBGP) {
1075 *reason = bgp_path_selection_confed;
1076 if (debug)
1077 zlog_debug(
1078 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1079 pfx_buf, new_buf, exist_buf);
1080 if (!CHECK_FLAG(bgp->flags,
1081 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1082 return 0;
1083 peer_sort_ret = 0;
1084 }
1085 }
1086
1087 /* 11. Maximum path check. */
1088 if (newm == existm) {
1089 /* If one path has a label but the other does not, do not treat
1090 * them as equals for multipath
1091 */
1092 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1093 != (exist->extra
1094 && bgp_is_valid_label(&exist->extra->label[0]))) {
1095 if (debug)
1096 zlog_debug(
1097 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1098 pfx_buf, new_buf, exist_buf);
1099 } else if (CHECK_FLAG(bgp->flags,
1100 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1101
1102 /*
1103 * For the two paths, all comparison steps till IGP
1104 * metric
1105 * have succeeded - including AS_PATH hop count. Since
1106 * 'bgp
1107 * bestpath as-path multipath-relax' knob is on, we
1108 * don't need
1109 * an exact match of AS_PATH. Thus, mark the paths are
1110 * equal.
1111 * That will trigger both these paths to get into the
1112 * multipath
1113 * array.
1114 */
1115 *paths_eq = 1;
1116
1117 if (debug)
1118 zlog_debug(
1119 "%s: %s and %s are equal via multipath-relax",
1120 pfx_buf, new_buf, exist_buf);
1121 } else if (new->peer->sort == BGP_PEER_IBGP) {
1122 if (aspath_cmp(new->attr->aspath,
1123 exist->attr->aspath)) {
1124 *paths_eq = 1;
1125
1126 if (debug)
1127 zlog_debug(
1128 "%s: %s and %s are equal via matching aspaths",
1129 pfx_buf, new_buf, exist_buf);
1130 }
1131 } else if (new->peer->as == exist->peer->as) {
1132 *paths_eq = 1;
1133
1134 if (debug)
1135 zlog_debug(
1136 "%s: %s and %s are equal via same remote-as",
1137 pfx_buf, new_buf, exist_buf);
1138 }
1139 } else {
1140 /*
1141 * TODO: If unequal cost ibgp multipath is enabled we can
1142 * mark the paths as equal here instead of returning
1143 */
1144
1145 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1146 * if either step 7 or 10 (peer type checks) yielded a winner,
1147 * that result was returned immediately. Returning from step 10
1148 * ignored the return value computed in steps 8 and 9 (IGP
1149 * metric checks). In order to preserve that behavior, if
1150 * peer_sort_ret is set, return that rather than igp_metric_ret.
1151 */
1152 ret = peer_sort_ret;
1153 if (peer_sort_ret < 0) {
1154 ret = igp_metric_ret;
1155 if (debug) {
1156 if (ret == 1)
1157 zlog_debug(
1158 "%s: %s wins over %s after IGP metric comparison",
1159 pfx_buf, new_buf, exist_buf);
1160 else
1161 zlog_debug(
1162 "%s: %s loses to %s after IGP metric comparison",
1163 pfx_buf, new_buf, exist_buf);
1164 }
1165 *reason = bgp_path_selection_igp_metric;
1166 }
1167 return ret;
1168 }
1169
1170 /*
1171 * At this point, the decision whether to set *paths_eq = 1 has been
1172 * completed. If we deferred returning because of bestpath peer-type
1173 * relax configuration, return now.
1174 */
1175 if (peer_sort_ret >= 0)
1176 return peer_sort_ret;
1177
1178 /* 12. If both paths are external, prefer the path that was received
1179 first (the oldest one). This step minimizes route-flap, since a
1180 newer path won't displace an older one, even if it was the
1181 preferred route based on the additional decision criteria below. */
1182 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1183 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1184 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1185 *reason = bgp_path_selection_older;
1186 if (debug)
1187 zlog_debug(
1188 "%s: %s wins over %s due to oldest external",
1189 pfx_buf, new_buf, exist_buf);
1190 return 1;
1191 }
1192
1193 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1194 *reason = bgp_path_selection_older;
1195 if (debug)
1196 zlog_debug(
1197 "%s: %s loses to %s due to oldest external",
1198 pfx_buf, new_buf, exist_buf);
1199 return 0;
1200 }
1201 }
1202
1203 /* 13. Router-ID comparision. */
1204 /* If one of the paths is "stale", the corresponding peer router-id will
1205 * be 0 and would always win over the other path. If originator id is
1206 * used for the comparision, it will decide which path is better.
1207 */
1208 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1209 new_id.s_addr = newattr->originator_id.s_addr;
1210 else
1211 new_id.s_addr = new->peer->remote_id.s_addr;
1212 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1213 exist_id.s_addr = existattr->originator_id.s_addr;
1214 else
1215 exist_id.s_addr = exist->peer->remote_id.s_addr;
1216
1217 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1218 *reason = bgp_path_selection_router_id;
1219 if (debug)
1220 zlog_debug(
1221 "%s: %s wins over %s due to Router-ID comparison",
1222 pfx_buf, new_buf, exist_buf);
1223 return 1;
1224 }
1225
1226 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1227 *reason = bgp_path_selection_router_id;
1228 if (debug)
1229 zlog_debug(
1230 "%s: %s loses to %s due to Router-ID comparison",
1231 pfx_buf, new_buf, exist_buf);
1232 return 0;
1233 }
1234
1235 /* 14. Cluster length comparision. */
1236 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1237 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1238
1239 if (new_cluster < exist_cluster) {
1240 *reason = bgp_path_selection_cluster_length;
1241 if (debug)
1242 zlog_debug(
1243 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1244 pfx_buf, new_buf, exist_buf, new_cluster,
1245 exist_cluster);
1246 return 1;
1247 }
1248
1249 if (new_cluster > exist_cluster) {
1250 *reason = bgp_path_selection_cluster_length;
1251 if (debug)
1252 zlog_debug(
1253 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1254 pfx_buf, new_buf, exist_buf, new_cluster,
1255 exist_cluster);
1256 return 0;
1257 }
1258
1259 /* 15. Neighbor address comparision. */
1260 /* Do this only if neither path is "stale" as stale paths do not have
1261 * valid peer information (as the connection may or may not be up).
1262 */
1263 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1264 *reason = bgp_path_selection_stale;
1265 if (debug)
1266 zlog_debug(
1267 "%s: %s wins over %s due to latter path being STALE",
1268 pfx_buf, new_buf, exist_buf);
1269 return 1;
1270 }
1271
1272 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1273 *reason = bgp_path_selection_stale;
1274 if (debug)
1275 zlog_debug(
1276 "%s: %s loses to %s due to former path being STALE",
1277 pfx_buf, new_buf, exist_buf);
1278 return 0;
1279 }
1280
1281 /* locally configured routes to advertise do not have su_remote */
1282 if (new->peer->su_remote == NULL) {
1283 *reason = bgp_path_selection_local_configured;
1284 return 0;
1285 }
1286 if (exist->peer->su_remote == NULL) {
1287 *reason = bgp_path_selection_local_configured;
1288 return 1;
1289 }
1290
1291 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1292
1293 if (ret == 1) {
1294 *reason = bgp_path_selection_neighbor_ip;
1295 if (debug)
1296 zlog_debug(
1297 "%s: %s loses to %s due to Neighor IP comparison",
1298 pfx_buf, new_buf, exist_buf);
1299 return 0;
1300 }
1301
1302 if (ret == -1) {
1303 *reason = bgp_path_selection_neighbor_ip;
1304 if (debug)
1305 zlog_debug(
1306 "%s: %s wins over %s due to Neighor IP comparison",
1307 pfx_buf, new_buf, exist_buf);
1308 return 1;
1309 }
1310
1311 *reason = bgp_path_selection_default;
1312 if (debug)
1313 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1314 pfx_buf, new_buf, exist_buf);
1315
1316 return 1;
1317 }
1318
1319
1320 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1321 struct bgp_path_info *exist, int *paths_eq)
1322 {
1323 enum bgp_path_selection_reason reason;
1324 char pfx_buf[PREFIX2STR_BUFFER];
1325
1326 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1327 AFI_L2VPN, SAFI_EVPN, &reason);
1328 }
1329
1330 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1331 * is preferred, or 0 if they are the same (usually will only occur if
1332 * multipath is enabled
1333 * This version is compatible with */
1334 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1335 struct bgp_path_info *exist, char *pfx_buf,
1336 afi_t afi, safi_t safi,
1337 enum bgp_path_selection_reason *reason)
1338 {
1339 int paths_eq;
1340 int ret;
1341 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1342 afi, safi, reason);
1343
1344 if (paths_eq)
1345 ret = 0;
1346 else {
1347 if (ret == 1)
1348 ret = -1;
1349 else
1350 ret = 1;
1351 }
1352 return ret;
1353 }
1354
1355 static enum filter_type bgp_input_filter(struct peer *peer,
1356 const struct prefix *p,
1357 struct attr *attr, afi_t afi,
1358 safi_t safi)
1359 {
1360 struct bgp_filter *filter;
1361 enum filter_type ret = FILTER_PERMIT;
1362
1363 filter = &peer->filter[afi][safi];
1364
1365 #define FILTER_EXIST_WARN(F, f, filter) \
1366 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1367 zlog_debug("%s: Could not find configured input %s-list %s!", \
1368 peer->host, #f, F##_IN_NAME(filter));
1369
1370 if (DISTRIBUTE_IN_NAME(filter)) {
1371 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1372
1373 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1374 == FILTER_DENY) {
1375 ret = FILTER_DENY;
1376 goto done;
1377 }
1378 }
1379
1380 if (PREFIX_LIST_IN_NAME(filter)) {
1381 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1382
1383 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1384 == PREFIX_DENY) {
1385 ret = FILTER_DENY;
1386 goto done;
1387 }
1388 }
1389
1390 if (FILTER_LIST_IN_NAME(filter)) {
1391 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1392
1393 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1394 == AS_FILTER_DENY) {
1395 ret = FILTER_DENY;
1396 goto done;
1397 }
1398 }
1399
1400 done:
1401 if (frrtrace_enabled(frr_bgp, input_filter)) {
1402 char pfxprint[PREFIX2STR_BUFFER];
1403
1404 prefix2str(p, pfxprint, sizeof(pfxprint));
1405 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1406 ret == FILTER_PERMIT ? "permit" : "deny");
1407 }
1408
1409 return ret;
1410 #undef FILTER_EXIST_WARN
1411 }
1412
1413 static enum filter_type bgp_output_filter(struct peer *peer,
1414 const struct prefix *p,
1415 struct attr *attr, afi_t afi,
1416 safi_t safi)
1417 {
1418 struct bgp_filter *filter;
1419 enum filter_type ret = FILTER_PERMIT;
1420
1421 filter = &peer->filter[afi][safi];
1422
1423 #define FILTER_EXIST_WARN(F, f, filter) \
1424 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1425 zlog_debug("%s: Could not find configured output %s-list %s!", \
1426 peer->host, #f, F##_OUT_NAME(filter));
1427
1428 if (DISTRIBUTE_OUT_NAME(filter)) {
1429 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1430
1431 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1432 == FILTER_DENY) {
1433 ret = FILTER_DENY;
1434 goto done;
1435 }
1436 }
1437
1438 if (PREFIX_LIST_OUT_NAME(filter)) {
1439 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1440
1441 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1442 == PREFIX_DENY) {
1443 ret = FILTER_DENY;
1444 goto done;
1445 }
1446 }
1447
1448 if (FILTER_LIST_OUT_NAME(filter)) {
1449 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1450
1451 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1452 == AS_FILTER_DENY) {
1453 ret = FILTER_DENY;
1454 goto done;
1455 }
1456 }
1457
1458 if (frrtrace_enabled(frr_bgp, output_filter)) {
1459 char pfxprint[PREFIX2STR_BUFFER];
1460
1461 prefix2str(p, pfxprint, sizeof(pfxprint));
1462 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1463 ret == FILTER_PERMIT ? "permit" : "deny");
1464 }
1465
1466 done:
1467 return ret;
1468 #undef FILTER_EXIST_WARN
1469 }
1470
1471 /* If community attribute includes no_export then return 1. */
1472 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1473 {
1474 if (attr->community) {
1475 /* NO_ADVERTISE check. */
1476 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1477 return true;
1478
1479 /* NO_EXPORT check. */
1480 if (peer->sort == BGP_PEER_EBGP
1481 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1482 return true;
1483
1484 /* NO_EXPORT_SUBCONFED check. */
1485 if (peer->sort == BGP_PEER_EBGP
1486 || peer->sort == BGP_PEER_CONFED)
1487 if (community_include(attr->community,
1488 COMMUNITY_NO_EXPORT_SUBCONFED))
1489 return true;
1490 }
1491 return false;
1492 }
1493
1494 /* Route reflection loop check. */
1495 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1496 {
1497 struct in_addr cluster_id;
1498 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1499
1500 if (cluster) {
1501 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1502 cluster_id = peer->bgp->cluster_id;
1503 else
1504 cluster_id = peer->bgp->router_id;
1505
1506 if (cluster_loop_check(cluster, cluster_id))
1507 return true;
1508 }
1509 return false;
1510 }
1511
1512 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1513 struct attr *attr, afi_t afi, safi_t safi,
1514 const char *rmap_name, mpls_label_t *label,
1515 uint32_t num_labels, struct bgp_dest *dest)
1516 {
1517 struct bgp_filter *filter;
1518 struct bgp_path_info rmap_path = { 0 };
1519 struct bgp_path_info_extra extra = { 0 };
1520 route_map_result_t ret;
1521 struct route_map *rmap = NULL;
1522
1523 filter = &peer->filter[afi][safi];
1524
1525 /* Apply default weight value. */
1526 if (peer->weight[afi][safi])
1527 attr->weight = peer->weight[afi][safi];
1528
1529 if (rmap_name) {
1530 rmap = route_map_lookup_by_name(rmap_name);
1531
1532 if (rmap == NULL)
1533 return RMAP_DENY;
1534 } else {
1535 if (ROUTE_MAP_IN_NAME(filter)) {
1536 rmap = ROUTE_MAP_IN(filter);
1537
1538 if (rmap == NULL)
1539 return RMAP_DENY;
1540 }
1541 }
1542
1543 /* Route map apply. */
1544 if (rmap) {
1545 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1546 /* Duplicate current value to new strucutre for modification. */
1547 rmap_path.peer = peer;
1548 rmap_path.attr = attr;
1549 rmap_path.extra = &extra;
1550 rmap_path.net = dest;
1551
1552 extra.num_labels = num_labels;
1553 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1554 memcpy(extra.label, label,
1555 num_labels * sizeof(mpls_label_t));
1556
1557 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1558
1559 /* Apply BGP route map to the attribute. */
1560 ret = route_map_apply(rmap, p, &rmap_path);
1561
1562 peer->rmap_type = 0;
1563
1564 if (ret == RMAP_DENYMATCH)
1565 return RMAP_DENY;
1566 }
1567 return RMAP_PERMIT;
1568 }
1569
1570 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1571 struct attr *attr, afi_t afi, safi_t safi,
1572 const char *rmap_name)
1573 {
1574 struct bgp_path_info rmap_path;
1575 route_map_result_t ret;
1576 struct route_map *rmap = NULL;
1577 uint8_t rmap_type;
1578
1579 /*
1580 * So if we get to this point and have no rmap_name
1581 * we want to just show the output as it currently
1582 * exists.
1583 */
1584 if (!rmap_name)
1585 return RMAP_PERMIT;
1586
1587 /* Apply default weight value. */
1588 if (peer->weight[afi][safi])
1589 attr->weight = peer->weight[afi][safi];
1590
1591 rmap = route_map_lookup_by_name(rmap_name);
1592
1593 /*
1594 * If we have a route map name and we do not find
1595 * the routemap that means we have an implicit
1596 * deny.
1597 */
1598 if (rmap == NULL)
1599 return RMAP_DENY;
1600
1601 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1602 /* Route map apply. */
1603 /* Duplicate current value to new strucutre for modification. */
1604 rmap_path.peer = peer;
1605 rmap_path.attr = attr;
1606
1607 rmap_type = peer->rmap_type;
1608 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1609
1610 /* Apply BGP route map to the attribute. */
1611 ret = route_map_apply(rmap, p, &rmap_path);
1612
1613 peer->rmap_type = rmap_type;
1614
1615 if (ret == RMAP_DENYMATCH)
1616 /*
1617 * caller has multiple error paths with bgp_attr_flush()
1618 */
1619 return RMAP_DENY;
1620
1621 return RMAP_PERMIT;
1622 }
1623
1624 /* If this is an EBGP peer with remove-private-AS */
1625 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1626 struct peer *peer, struct attr *attr)
1627 {
1628 if (peer->sort == BGP_PEER_EBGP
1629 && (peer_af_flag_check(peer, afi, safi,
1630 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1631 || peer_af_flag_check(peer, afi, safi,
1632 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1633 || peer_af_flag_check(peer, afi, safi,
1634 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1635 || peer_af_flag_check(peer, afi, safi,
1636 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1637 // Take action on the entire aspath
1638 if (peer_af_flag_check(peer, afi, safi,
1639 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1640 || peer_af_flag_check(peer, afi, safi,
1641 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1642 if (peer_af_flag_check(
1643 peer, afi, safi,
1644 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1645 attr->aspath = aspath_replace_private_asns(
1646 attr->aspath, bgp->as, peer->as);
1647
1648 // The entire aspath consists of private ASNs so create
1649 // an empty aspath
1650 else if (aspath_private_as_check(attr->aspath))
1651 attr->aspath = aspath_empty_get();
1652
1653 // There are some public and some private ASNs, remove
1654 // the private ASNs
1655 else
1656 attr->aspath = aspath_remove_private_asns(
1657 attr->aspath, peer->as);
1658 }
1659
1660 // 'all' was not specified so the entire aspath must be private
1661 // ASNs
1662 // for us to do anything
1663 else if (aspath_private_as_check(attr->aspath)) {
1664 if (peer_af_flag_check(
1665 peer, afi, safi,
1666 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1667 attr->aspath = aspath_replace_private_asns(
1668 attr->aspath, bgp->as, peer->as);
1669 else
1670 attr->aspath = aspath_empty_get();
1671 }
1672 }
1673 }
1674
1675 /* If this is an EBGP peer with as-override */
1676 static void bgp_peer_as_override(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, PEER_FLAG_AS_OVERRIDE)) {
1681 if (aspath_single_asn_check(attr->aspath, peer->as))
1682 attr->aspath = aspath_replace_specific_asn(
1683 attr->aspath, peer->as, bgp->as);
1684 }
1685 }
1686
1687 void bgp_attr_add_gshut_community(struct attr *attr)
1688 {
1689 struct community *old;
1690 struct community *new;
1691 struct community *merge;
1692 struct community *gshut;
1693
1694 old = attr->community;
1695 gshut = community_str2com("graceful-shutdown");
1696
1697 assert(gshut);
1698
1699 if (old) {
1700 merge = community_merge(community_dup(old), gshut);
1701
1702 if (old->refcnt == 0)
1703 community_free(&old);
1704
1705 new = community_uniq_sort(merge);
1706 community_free(&merge);
1707 } else {
1708 new = community_dup(gshut);
1709 }
1710
1711 community_free(&gshut);
1712 attr->community = new;
1713 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1714
1715 /* When we add the graceful-shutdown community we must also
1716 * lower the local-preference */
1717 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1718 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1719 }
1720
1721
1722 /* Notify BGP Conditional advertisement scanner process. */
1723 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1724 {
1725 struct peer *temp_peer;
1726 struct peer *peer = SUBGRP_PEER(subgrp);
1727 struct listnode *temp_node, *temp_nnode = NULL;
1728 afi_t afi = SUBGRP_AFI(subgrp);
1729 safi_t safi = SUBGRP_SAFI(subgrp);
1730 struct bgp *bgp = SUBGRP_INST(subgrp);
1731 struct bgp_filter *filter = &peer->filter[afi][safi];
1732
1733 if (!ADVERTISE_MAP_NAME(filter))
1734 return;
1735
1736 for (ALL_LIST_ELEMENTS(bgp->peer, temp_node, temp_nnode, temp_peer)) {
1737 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1738 continue;
1739
1740 if (peer != temp_peer)
1741 continue;
1742
1743 temp_peer->advmap_table_change = true;
1744 break;
1745 }
1746 }
1747
1748
1749 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1750 {
1751 if (family == AF_INET) {
1752 attr->nexthop.s_addr = INADDR_ANY;
1753 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1754 }
1755 if (family == AF_INET6)
1756 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1757 if (family == AF_EVPN)
1758 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1759 }
1760
1761 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1762 struct update_subgroup *subgrp,
1763 const struct prefix *p, struct attr *attr,
1764 bool skip_rmap_check)
1765 {
1766 struct bgp_filter *filter;
1767 struct peer *from;
1768 struct peer *peer;
1769 struct peer *onlypeer;
1770 struct bgp *bgp;
1771 struct attr *piattr;
1772 route_map_result_t ret;
1773 int transparent;
1774 int reflect;
1775 afi_t afi;
1776 safi_t safi;
1777 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1778 bool nh_reset = false;
1779 uint64_t cum_bw;
1780
1781 if (DISABLE_BGP_ANNOUNCE)
1782 return false;
1783
1784 afi = SUBGRP_AFI(subgrp);
1785 safi = SUBGRP_SAFI(subgrp);
1786 peer = SUBGRP_PEER(subgrp);
1787 onlypeer = NULL;
1788 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1789 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1790
1791 from = pi->peer;
1792 filter = &peer->filter[afi][safi];
1793 bgp = SUBGRP_INST(subgrp);
1794 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1795 : pi->attr;
1796
1797 #ifdef ENABLE_BGP_VNC
1798 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1799 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1800 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1801
1802 /*
1803 * direct and direct_ext type routes originate internally even
1804 * though they can have peer pointers that reference other
1805 * systems
1806 */
1807 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1808 __func__, p);
1809 samepeer_safe = 1;
1810 }
1811 #endif
1812
1813 if (((afi == AFI_IP) || (afi == AFI_IP6))
1814 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1815 && (pi->type == ZEBRA_ROUTE_BGP)
1816 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1817
1818 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1819
1820 samepeer_safe = 1;
1821 }
1822
1823 /* With addpath we may be asked to TX all kinds of paths so make sure
1824 * pi is valid */
1825 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1826 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1827 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1828 return false;
1829 }
1830
1831 /* If this is not the bestpath then check to see if there is an enabled
1832 * addpath
1833 * feature that requires us to advertise it */
1834 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1835 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1836 return false;
1837 }
1838 }
1839
1840 /* Aggregate-address suppress check. */
1841 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1842 return false;
1843
1844 /*
1845 * If we are doing VRF 2 VRF leaking via the import
1846 * statement, we want to prevent the route going
1847 * off box as that the RT and RD created are localy
1848 * significant and globaly useless.
1849 */
1850 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1851 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1852 return false;
1853
1854 /* If it's labeled safi, make sure the route has a valid label. */
1855 if (safi == SAFI_LABELED_UNICAST) {
1856 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1857 if (!bgp_is_valid_label(&label)) {
1858 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1859 zlog_debug("u%" PRIu64 ":s%" PRIu64
1860 " %pFX is filtered - no label (%p)",
1861 subgrp->update_group->id, subgrp->id,
1862 p, &label);
1863 return false;
1864 }
1865 }
1866
1867 /* Do not send back route to sender. */
1868 if (onlypeer && from == onlypeer) {
1869 return false;
1870 }
1871
1872 /* Do not send the default route in the BGP table if the neighbor is
1873 * configured for default-originate */
1874 if (CHECK_FLAG(peer->af_flags[afi][safi],
1875 PEER_FLAG_DEFAULT_ORIGINATE)) {
1876 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1877 return false;
1878 else if (p->family == AF_INET6 && p->prefixlen == 0)
1879 return false;
1880 }
1881
1882 /* Transparency check. */
1883 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1884 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1885 transparent = 1;
1886 else
1887 transparent = 0;
1888
1889 /* If community is not disabled check the no-export and local. */
1890 if (!transparent && bgp_community_filter(peer, piattr)) {
1891 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1892 zlog_debug("%s: community filter check fail for %pFX",
1893 __func__, p);
1894 return false;
1895 }
1896
1897 /* If the attribute has originator-id and it is same as remote
1898 peer's id. */
1899 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1900 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1901 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1902 zlog_debug(
1903 "%s [Update:SEND] %pFX originator-id is same as remote router-id",
1904 onlypeer->host, p);
1905 return false;
1906 }
1907
1908 /* ORF prefix-list filter check */
1909 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1910 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1911 || CHECK_FLAG(peer->af_cap[afi][safi],
1912 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1913 if (peer->orf_plist[afi][safi]) {
1914 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1915 == PREFIX_DENY) {
1916 if (bgp_debug_update(NULL, p,
1917 subgrp->update_group, 0))
1918 zlog_debug(
1919 "%s [Update:SEND] %pFX is filtered via ORF",
1920 peer->host, p);
1921 return false;
1922 }
1923 }
1924
1925 /* Output filter check. */
1926 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1927 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1928 zlog_debug("%s [Update:SEND] %pFX is filtered",
1929 peer->host, p);
1930 return false;
1931 }
1932
1933 /* AS path loop check. */
1934 if (onlypeer && onlypeer->as_path_loop_detection
1935 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
1936 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1937 zlog_debug(
1938 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
1939 onlypeer->host, onlypeer->as);
1940 return false;
1941 }
1942
1943 /* If we're a CONFED we need to loop check the CONFED ID too */
1944 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1945 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
1946 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1947 zlog_debug(
1948 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
1949 peer->host, bgp->confed_id);
1950 return false;
1951 }
1952 }
1953
1954 /* Route-Reflect check. */
1955 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1956 reflect = 1;
1957 else
1958 reflect = 0;
1959
1960 /* IBGP reflection check. */
1961 if (reflect && !samepeer_safe) {
1962 /* A route from a Client peer. */
1963 if (CHECK_FLAG(from->af_flags[afi][safi],
1964 PEER_FLAG_REFLECTOR_CLIENT)) {
1965 /* Reflect to all the Non-Client peers and also to the
1966 Client peers other than the originator. Originator
1967 check
1968 is already done. So there is noting to do. */
1969 /* no bgp client-to-client reflection check. */
1970 if (CHECK_FLAG(bgp->flags,
1971 BGP_FLAG_NO_CLIENT_TO_CLIENT))
1972 if (CHECK_FLAG(peer->af_flags[afi][safi],
1973 PEER_FLAG_REFLECTOR_CLIENT))
1974 return false;
1975 } else {
1976 /* A route from a Non-client peer. Reflect to all other
1977 clients. */
1978 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1979 PEER_FLAG_REFLECTOR_CLIENT))
1980 return false;
1981 }
1982 }
1983
1984 /* For modify attribute, copy it to temporary structure. */
1985 *attr = *piattr;
1986
1987 /* If local-preference is not set. */
1988 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1989 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1990 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1991 attr->local_pref = bgp->default_local_pref;
1992 }
1993
1994 /* If originator-id is not set and the route is to be reflected,
1995 set the originator id */
1996 if (reflect
1997 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1998 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
1999 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2000 }
2001
2002 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2003 */
2004 if (peer->sort == BGP_PEER_EBGP
2005 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2006 if (from != bgp->peer_self && !transparent
2007 && !CHECK_FLAG(peer->af_flags[afi][safi],
2008 PEER_FLAG_MED_UNCHANGED))
2009 attr->flag &=
2010 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2011 }
2012
2013 /* Since the nexthop attribute can vary per peer, it is not explicitly
2014 * set
2015 * in announce check, only certain flags and length (or number of
2016 * nexthops
2017 * -- for IPv6/MP_REACH) are set here in order to guide the update
2018 * formation
2019 * code in setting the nexthop(s) on a per peer basis in
2020 * reformat_peer().
2021 * Typically, the source nexthop in the attribute is preserved but in
2022 * the
2023 * scenarios where we know it will always be overwritten, we reset the
2024 * nexthop to "0" in an attempt to achieve better Update packing. An
2025 * example of this is when a prefix from each of 2 IBGP peers needs to
2026 * be
2027 * announced to an EBGP peer (and they have the same attributes barring
2028 * their nexthop).
2029 */
2030 if (reflect)
2031 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2032
2033 #define NEXTHOP_IS_V6 \
2034 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2035 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2036 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2037 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2038
2039 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2040 * if
2041 * the peer (group) is configured to receive link-local nexthop
2042 * unchanged
2043 * and it is available in the prefix OR we're not reflecting the route,
2044 * link-local nexthop address is valid and
2045 * the peer (group) to whom we're going to announce is on a shared
2046 * network
2047 * and this is either a self-originated route or the peer is EBGP.
2048 * By checking if nexthop LL address is valid we are sure that
2049 * we do not announce LL address as `::`.
2050 */
2051 if (NEXTHOP_IS_V6) {
2052 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2053 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2054 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2055 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2056 || (!reflect
2057 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2058 && peer->shared_network
2059 && (from == bgp->peer_self
2060 || peer->sort == BGP_PEER_EBGP))) {
2061 attr->mp_nexthop_len =
2062 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2063 }
2064
2065 /* Clear off link-local nexthop in source, whenever it is not
2066 * needed to
2067 * ensure more prefixes share the same attribute for
2068 * announcement.
2069 */
2070 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2071 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2072 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2073 }
2074
2075 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2076 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2077
2078 /* Route map & unsuppress-map apply. */
2079 if (!skip_rmap_check
2080 && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2081 struct bgp_path_info rmap_path = {0};
2082 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2083 struct attr dummy_attr = {0};
2084
2085 /* Fill temp path_info */
2086 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2087 pi, peer, attr);
2088
2089 /* don't confuse inbound and outbound setting */
2090 RESET_FLAG(attr->rmap_change_flags);
2091
2092 /*
2093 * The route reflector is not allowed to modify the attributes
2094 * of the reflected IBGP routes unless explicitly allowed.
2095 */
2096 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2097 && !CHECK_FLAG(bgp->flags,
2098 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2099 dummy_attr = *attr;
2100 rmap_path.attr = &dummy_attr;
2101 }
2102
2103 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2104
2105 if (bgp_path_suppressed(pi))
2106 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2107 &rmap_path);
2108 else
2109 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2110 &rmap_path);
2111
2112 peer->rmap_type = 0;
2113
2114 if (ret == RMAP_DENYMATCH) {
2115 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2116 zlog_debug(
2117 "%s [Update:SEND] %pFX is filtered by route-map",
2118 peer->host, p);
2119
2120 bgp_attr_flush(attr);
2121 return false;
2122 }
2123 }
2124
2125 /* RFC 8212 to prevent route leaks.
2126 * This specification intends to improve this situation by requiring the
2127 * explicit configuration of both BGP Import and Export Policies for any
2128 * External BGP (EBGP) session such as customers, peers, or
2129 * confederation boundaries for all enabled address families. Through
2130 * codification of the aforementioned requirement, operators will
2131 * benefit from consistent behavior across different BGP
2132 * implementations.
2133 */
2134 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2135 if (!bgp_outbound_policy_exists(peer, filter))
2136 return false;
2137
2138 /* draft-ietf-idr-deprecate-as-set-confed-set
2139 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2140 * Eventually, This document (if approved) updates RFC 4271
2141 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2142 * and obsoletes RFC 6472.
2143 */
2144 if (peer->bgp->reject_as_sets)
2145 if (aspath_check_as_sets(attr->aspath))
2146 return false;
2147
2148 /* Codification of AS 0 Processing */
2149 if (aspath_check_as_zero(attr->aspath))
2150 return false;
2151
2152 if (bgp_in_graceful_shutdown(bgp)) {
2153 if (peer->sort == BGP_PEER_IBGP
2154 || peer->sort == BGP_PEER_CONFED) {
2155 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2156 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2157 } else {
2158 bgp_attr_add_gshut_community(attr);
2159 }
2160 }
2161
2162 /* After route-map has been applied, we check to see if the nexthop to
2163 * be carried in the attribute (that is used for the announcement) can
2164 * be cleared off or not. We do this in all cases where we would be
2165 * setting the nexthop to "ourselves". For IPv6, we only need to
2166 * consider
2167 * the global nexthop here; the link-local nexthop would have been
2168 * cleared
2169 * already, and if not, it is required by the update formation code.
2170 * Also see earlier comments in this function.
2171 */
2172 /*
2173 * If route-map has performed some operation on the nexthop or the peer
2174 * configuration says to pass it unchanged, we cannot reset the nexthop
2175 * here, so only attempt to do it if these aren't true. Note that the
2176 * route-map handler itself might have cleared the nexthop, if for
2177 * example,
2178 * it is configured as 'peer-address'.
2179 */
2180 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2181 piattr->rmap_change_flags)
2182 && !transparent
2183 && !CHECK_FLAG(peer->af_flags[afi][safi],
2184 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2185 /* We can reset the nexthop, if setting (or forcing) it to
2186 * 'self' */
2187 if (CHECK_FLAG(peer->af_flags[afi][safi],
2188 PEER_FLAG_NEXTHOP_SELF)
2189 || CHECK_FLAG(peer->af_flags[afi][safi],
2190 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2191 if (!reflect
2192 || CHECK_FLAG(peer->af_flags[afi][safi],
2193 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2194 subgroup_announce_reset_nhop(
2195 (peer_cap_enhe(peer, afi, safi)
2196 ? AF_INET6
2197 : p->family),
2198 attr);
2199 nh_reset = true;
2200 }
2201 } else if (peer->sort == BGP_PEER_EBGP) {
2202 /* Can also reset the nexthop if announcing to EBGP, but
2203 * only if
2204 * no peer in the subgroup is on a shared subnet.
2205 * Note: 3rd party nexthop currently implemented for
2206 * IPv4 only.
2207 */
2208 if ((p->family == AF_INET) &&
2209 (!bgp_subgrp_multiaccess_check_v4(
2210 piattr->nexthop,
2211 subgrp, from))) {
2212 subgroup_announce_reset_nhop(
2213 (peer_cap_enhe(peer, afi, safi)
2214 ? AF_INET6
2215 : p->family),
2216 attr);
2217 nh_reset = true;
2218 }
2219
2220 if ((p->family == AF_INET6) &&
2221 (!bgp_subgrp_multiaccess_check_v6(
2222 piattr->mp_nexthop_global,
2223 subgrp, from))) {
2224 subgroup_announce_reset_nhop(
2225 (peer_cap_enhe(peer, afi, safi)
2226 ? AF_INET6
2227 : p->family),
2228 attr);
2229 nh_reset = true;
2230 }
2231
2232
2233
2234 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2235 /*
2236 * This flag is used for leaked vpn-vrf routes
2237 */
2238 int family = p->family;
2239
2240 if (peer_cap_enhe(peer, afi, safi))
2241 family = AF_INET6;
2242
2243 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2244 zlog_debug(
2245 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2246 __func__, family2str(family));
2247 subgroup_announce_reset_nhop(family, attr);
2248 nh_reset = true;
2249 }
2250 }
2251
2252 /* If IPv6/MP and nexthop does not have any override and happens
2253 * to
2254 * be a link-local address, reset it so that we don't pass along
2255 * the
2256 * source's link-local IPv6 address to recipients who may not be
2257 * on
2258 * the same interface.
2259 */
2260 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2261 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2262 subgroup_announce_reset_nhop(AF_INET6, attr);
2263 nh_reset = true;
2264 }
2265 }
2266
2267 /*
2268 * When the next hop is set to ourselves, if all multipaths have
2269 * link-bandwidth announce the cumulative bandwidth as that makes
2270 * the most sense. However, don't modify if the link-bandwidth has
2271 * been explicitly set by user policy.
2272 */
2273 if (nh_reset &&
2274 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2275 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2276 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2277 attr->ecommunity = ecommunity_replace_linkbw(
2278 bgp->as, attr->ecommunity, cum_bw);
2279
2280 return true;
2281 }
2282
2283 static int bgp_route_select_timer_expire(struct thread *thread)
2284 {
2285 struct afi_safi_info *info;
2286 afi_t afi;
2287 safi_t safi;
2288 struct bgp *bgp;
2289
2290 info = THREAD_ARG(thread);
2291 afi = info->afi;
2292 safi = info->safi;
2293 bgp = info->bgp;
2294
2295 if (BGP_DEBUG(update, UPDATE_OUT))
2296 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2297 safi);
2298
2299 bgp->gr_info[afi][safi].t_route_select = NULL;
2300
2301 XFREE(MTYPE_TMP, info);
2302
2303 /* Best path selection */
2304 return bgp_best_path_select_defer(bgp, afi, safi);
2305 }
2306
2307 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2308 struct bgp_maxpaths_cfg *mpath_cfg,
2309 struct bgp_path_info_pair *result, afi_t afi,
2310 safi_t safi)
2311 {
2312 struct bgp_path_info *new_select;
2313 struct bgp_path_info *old_select;
2314 struct bgp_path_info *pi;
2315 struct bgp_path_info *pi1;
2316 struct bgp_path_info *pi2;
2317 struct bgp_path_info *nextpi = NULL;
2318 int paths_eq, do_mpath, debug;
2319 struct list mp_list;
2320 char pfx_buf[PREFIX2STR_BUFFER];
2321 char path_buf[PATH_ADDPATH_STR_BUFFER];
2322
2323 bgp_mp_list_init(&mp_list);
2324 do_mpath =
2325 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2326
2327 debug = bgp_debug_bestpath(dest);
2328
2329 if (debug)
2330 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2331
2332 dest->reason = bgp_path_selection_none;
2333 /* bgp deterministic-med */
2334 new_select = NULL;
2335 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2336
2337 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2338 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2339 pi1 = pi1->next)
2340 bgp_path_info_unset_flag(dest, pi1,
2341 BGP_PATH_DMED_SELECTED);
2342
2343 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2344 pi1 = pi1->next) {
2345 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2346 continue;
2347 if (BGP_PATH_HOLDDOWN(pi1))
2348 continue;
2349 if (pi1->peer != bgp->peer_self)
2350 if (!peer_established(pi1->peer))
2351 continue;
2352
2353 new_select = pi1;
2354 if (pi1->next) {
2355 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2356 if (CHECK_FLAG(pi2->flags,
2357 BGP_PATH_DMED_CHECK))
2358 continue;
2359 if (BGP_PATH_HOLDDOWN(pi2))
2360 continue;
2361 if (pi2->peer != bgp->peer_self
2362 && !CHECK_FLAG(
2363 pi2->peer->sflags,
2364 PEER_STATUS_NSF_WAIT))
2365 if (pi2->peer->status
2366 != Established)
2367 continue;
2368
2369 if (!aspath_cmp_left(pi1->attr->aspath,
2370 pi2->attr->aspath)
2371 && !aspath_cmp_left_confed(
2372 pi1->attr->aspath,
2373 pi2->attr->aspath))
2374 continue;
2375
2376 if (bgp_path_info_cmp(
2377 bgp, pi2, new_select,
2378 &paths_eq, mpath_cfg, debug,
2379 pfx_buf, afi, safi,
2380 &dest->reason)) {
2381 bgp_path_info_unset_flag(
2382 dest, new_select,
2383 BGP_PATH_DMED_SELECTED);
2384 new_select = pi2;
2385 }
2386
2387 bgp_path_info_set_flag(
2388 dest, pi2, BGP_PATH_DMED_CHECK);
2389 }
2390 }
2391 bgp_path_info_set_flag(dest, new_select,
2392 BGP_PATH_DMED_CHECK);
2393 bgp_path_info_set_flag(dest, new_select,
2394 BGP_PATH_DMED_SELECTED);
2395
2396 if (debug) {
2397 bgp_path_info_path_with_addpath_rx_str(
2398 new_select, path_buf, sizeof(path_buf));
2399 zlog_debug(
2400 "%pBD: %s is the bestpath from AS %u",
2401 dest, path_buf,
2402 aspath_get_first_as(
2403 new_select->attr->aspath));
2404 }
2405 }
2406 }
2407
2408 /* Check old selected route and new selected route. */
2409 old_select = NULL;
2410 new_select = NULL;
2411 for (pi = bgp_dest_get_bgp_path_info(dest);
2412 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2413 enum bgp_path_selection_reason reason;
2414
2415 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2416 old_select = pi;
2417
2418 if (BGP_PATH_HOLDDOWN(pi)) {
2419 /* reap REMOVED routes, if needs be
2420 * selected route must stay for a while longer though
2421 */
2422 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2423 && (pi != old_select))
2424 bgp_path_info_reap(dest, pi);
2425
2426 if (debug)
2427 zlog_debug("%s: pi %p in holddown", __func__,
2428 pi);
2429
2430 continue;
2431 }
2432
2433 if (pi->peer && pi->peer != bgp->peer_self
2434 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2435 if (!peer_established(pi->peer)) {
2436
2437 if (debug)
2438 zlog_debug(
2439 "%s: pi %p non self peer %s not estab state",
2440 __func__, pi, pi->peer->host);
2441
2442 continue;
2443 }
2444
2445 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2446 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2447 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2448 if (debug)
2449 zlog_debug("%s: pi %p dmed", __func__, pi);
2450 continue;
2451 }
2452
2453 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2454
2455 reason = dest->reason;
2456 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2457 debug, pfx_buf, afi, safi,
2458 &dest->reason)) {
2459 if (new_select == NULL &&
2460 reason != bgp_path_selection_none)
2461 dest->reason = reason;
2462 new_select = pi;
2463 }
2464 }
2465
2466 /* Now that we know which path is the bestpath see if any of the other
2467 * paths
2468 * qualify as multipaths
2469 */
2470 if (debug) {
2471 if (new_select)
2472 bgp_path_info_path_with_addpath_rx_str(
2473 new_select, path_buf, sizeof(path_buf));
2474 else
2475 snprintf(path_buf, sizeof(path_buf), "NONE");
2476 zlog_debug(
2477 "%pBD: After path selection, newbest is %s oldbest was %s",
2478 dest, path_buf,
2479 old_select ? old_select->peer->host : "NONE");
2480 }
2481
2482 if (do_mpath && new_select) {
2483 for (pi = bgp_dest_get_bgp_path_info(dest);
2484 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2485
2486 if (debug)
2487 bgp_path_info_path_with_addpath_rx_str(
2488 pi, path_buf, sizeof(path_buf));
2489
2490 if (pi == new_select) {
2491 if (debug)
2492 zlog_debug(
2493 "%pBD: %s is the bestpath, add to the multipath list",
2494 dest, path_buf);
2495 bgp_mp_list_add(&mp_list, pi);
2496 continue;
2497 }
2498
2499 if (BGP_PATH_HOLDDOWN(pi))
2500 continue;
2501
2502 if (pi->peer && pi->peer != bgp->peer_self
2503 && !CHECK_FLAG(pi->peer->sflags,
2504 PEER_STATUS_NSF_WAIT))
2505 if (!peer_established(pi->peer))
2506 continue;
2507
2508 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2509 if (debug)
2510 zlog_debug(
2511 "%pBD: %s has the same nexthop as the bestpath, skip it",
2512 dest, path_buf);
2513 continue;
2514 }
2515
2516 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2517 mpath_cfg, debug, pfx_buf, afi, safi,
2518 &dest->reason);
2519
2520 if (paths_eq) {
2521 if (debug)
2522 zlog_debug(
2523 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2524 dest, path_buf);
2525 bgp_mp_list_add(&mp_list, pi);
2526 }
2527 }
2528 }
2529
2530 bgp_path_info_mpath_update(dest, new_select, old_select, &mp_list,
2531 mpath_cfg);
2532 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2533 bgp_mp_list_clear(&mp_list);
2534
2535 bgp_addpath_update_ids(bgp, dest, afi, safi);
2536
2537 result->old = old_select;
2538 result->new = new_select;
2539
2540 return;
2541 }
2542
2543 /*
2544 * A new route/change in bestpath of an existing route. Evaluate the path
2545 * for advertisement to the subgroup.
2546 */
2547 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2548 struct bgp_path_info *selected,
2549 struct bgp_dest *dest,
2550 uint32_t addpath_tx_id)
2551 {
2552 const struct prefix *p;
2553 struct peer *onlypeer;
2554 struct attr attr;
2555 afi_t afi;
2556 safi_t safi;
2557 struct bgp *bgp;
2558 bool advertise;
2559
2560 p = bgp_dest_get_prefix(dest);
2561 afi = SUBGRP_AFI(subgrp);
2562 safi = SUBGRP_SAFI(subgrp);
2563 bgp = SUBGRP_INST(subgrp);
2564 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2565 : NULL);
2566
2567 if (BGP_DEBUG(update, UPDATE_OUT))
2568 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2569
2570 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2571 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2572 PEER_STATUS_ORF_WAIT_REFRESH))
2573 return;
2574
2575 memset(&attr, 0, sizeof(struct attr));
2576 /* It's initialized in bgp_announce_check() */
2577
2578 /* Announcement to the subgroup. If the route is filtered withdraw it.
2579 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2580 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2581 * route
2582 */
2583 advertise = bgp_check_advertise(bgp, dest);
2584
2585 if (selected) {
2586 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2587 false)) {
2588 /* Route is selected, if the route is already installed
2589 * in FIB, then it is advertised
2590 */
2591 if (advertise)
2592 bgp_adj_out_set_subgroup(dest, subgrp, &attr,
2593 selected);
2594 } else
2595 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2596 addpath_tx_id);
2597 }
2598
2599 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2600 else {
2601 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2602 }
2603 }
2604
2605 /*
2606 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2607 * This is called at the end of route processing.
2608 */
2609 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2610 {
2611 struct bgp_path_info *pi;
2612
2613 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2614 if (BGP_PATH_HOLDDOWN(pi))
2615 continue;
2616 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2617 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2618 }
2619 }
2620
2621 /*
2622 * Has the route changed from the RIB's perspective? This is invoked only
2623 * if the route selection returns the same best route as earlier - to
2624 * determine if we need to update zebra or not.
2625 */
2626 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2627 {
2628 struct bgp_path_info *mpinfo;
2629
2630 /* If this is multipath, check all selected paths for any nexthop
2631 * change or attribute change. Some attribute changes (e.g., community)
2632 * aren't of relevance to the RIB, but we'll update zebra to ensure
2633 * we handle the case of BGP nexthop change. This is the behavior
2634 * when the best path has an attribute change anyway.
2635 */
2636 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2637 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2638 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2639 return true;
2640
2641 /*
2642 * If this is multipath, check all selected paths for any nexthop change
2643 */
2644 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2645 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2646 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2647 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2648 return true;
2649 }
2650
2651 /* Nothing has changed from the RIB's perspective. */
2652 return false;
2653 }
2654
2655 struct bgp_process_queue {
2656 struct bgp *bgp;
2657 STAILQ_HEAD(, bgp_dest) pqueue;
2658 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2659 unsigned int flags;
2660 unsigned int queued;
2661 };
2662
2663 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2664 safi_t safi, struct bgp_dest *dest,
2665 struct bgp_path_info *new_select,
2666 struct bgp_path_info *old_select)
2667 {
2668 const struct prefix *p = bgp_dest_get_prefix(dest);
2669
2670 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2671 return;
2672
2673 if (advertise_type5_routes(bgp, afi) && new_select
2674 && is_route_injectable_into_evpn(new_select)) {
2675
2676 /* apply the route-map */
2677 if (bgp->adv_cmd_rmap[afi][safi].map) {
2678 route_map_result_t ret;
2679 struct bgp_path_info rmap_path;
2680 struct bgp_path_info_extra rmap_path_extra;
2681 struct attr dummy_attr;
2682
2683 dummy_attr = *new_select->attr;
2684
2685 /* Fill temp path_info */
2686 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2687 new_select, new_select->peer,
2688 &dummy_attr);
2689
2690 RESET_FLAG(dummy_attr.rmap_change_flags);
2691
2692 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2693 p, &rmap_path);
2694
2695 if (ret == RMAP_DENYMATCH) {
2696 bgp_attr_flush(&dummy_attr);
2697 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2698 safi);
2699 } else
2700 bgp_evpn_advertise_type5_route(
2701 bgp, p, &dummy_attr, afi, safi);
2702 } else {
2703 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2704 afi, safi);
2705 }
2706 } else if (advertise_type5_routes(bgp, afi) && old_select
2707 && is_route_injectable_into_evpn(old_select))
2708 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2709 }
2710
2711 /*
2712 * old_select = The old best path
2713 * new_select = the new best path
2714 *
2715 * if (!old_select && new_select)
2716 * We are sending new information on.
2717 *
2718 * if (old_select && new_select) {
2719 * if (new_select != old_select)
2720 * We have a new best path send a change
2721 * else
2722 * We've received a update with new attributes that needs
2723 * to be passed on.
2724 * }
2725 *
2726 * if (old_select && !new_select)
2727 * We have no eligible route that we can announce or the rn
2728 * is being removed.
2729 */
2730 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2731 afi_t afi, safi_t safi)
2732 {
2733 struct bgp_path_info *new_select;
2734 struct bgp_path_info *old_select;
2735 struct bgp_path_info_pair old_and_new;
2736 int debug = 0;
2737
2738 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2739 if (dest)
2740 debug = bgp_debug_bestpath(dest);
2741 if (debug)
2742 zlog_debug(
2743 "%s: bgp delete in progress, ignoring event, p=%pBD",
2744 __func__, dest);
2745 return;
2746 }
2747 /* Is it end of initial update? (after startup) */
2748 if (!dest) {
2749 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2750 sizeof(bgp->update_delay_zebra_resume_time));
2751
2752 bgp->main_zebra_update_hold = 0;
2753 FOREACH_AFI_SAFI (afi, safi) {
2754 if (bgp_fibupd_safi(safi))
2755 bgp_zebra_announce_table(bgp, afi, safi);
2756 }
2757 bgp->main_peers_update_hold = 0;
2758
2759 bgp_start_routeadv(bgp);
2760 return;
2761 }
2762
2763 const struct prefix *p = bgp_dest_get_prefix(dest);
2764
2765 debug = bgp_debug_bestpath(dest);
2766 if (debug)
2767 zlog_debug("%s: p=%pBD afi=%s, safi=%s start", __func__, dest,
2768 afi2str(afi), safi2str(safi));
2769
2770 /* The best path calculation for the route is deferred if
2771 * BGP_NODE_SELECT_DEFER is set
2772 */
2773 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2774 if (BGP_DEBUG(update, UPDATE_OUT))
2775 zlog_debug("SELECT_DEFER flag set for route %p", dest);
2776 return;
2777 }
2778
2779 /* Best path selection. */
2780 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2781 afi, safi);
2782 old_select = old_and_new.old;
2783 new_select = old_and_new.new;
2784
2785 /* Do we need to allocate or free labels?
2786 * Right now, since we only deal with per-prefix labels, it is not
2787 * necessary to do this upon changes to best path. Exceptions:
2788 * - label index has changed -> recalculate resulting label
2789 * - path_info sub_type changed -> switch to/from implicit-null
2790 * - no valid label (due to removed static label binding) -> get new one
2791 */
2792 if (bgp->allocate_mpls_labels[afi][safi]) {
2793 if (new_select) {
2794 if (!old_select
2795 || bgp_label_index_differs(new_select, old_select)
2796 || new_select->sub_type != old_select->sub_type
2797 || !bgp_is_valid_label(&dest->local_label)) {
2798 /* Enforced penultimate hop popping:
2799 * implicit-null for local routes, aggregate
2800 * and redistributed routes
2801 */
2802 if (new_select->sub_type == BGP_ROUTE_STATIC
2803 || new_select->sub_type
2804 == BGP_ROUTE_AGGREGATE
2805 || new_select->sub_type
2806 == BGP_ROUTE_REDISTRIBUTE) {
2807 if (CHECK_FLAG(
2808 dest->flags,
2809 BGP_NODE_REGISTERED_FOR_LABEL)
2810 || CHECK_FLAG(
2811 dest->flags,
2812 BGP_NODE_LABEL_REQUESTED))
2813 bgp_unregister_for_label(dest);
2814 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2815 &dest->local_label);
2816 bgp_set_valid_label(&dest->local_label);
2817 } else
2818 bgp_register_for_label(dest,
2819 new_select);
2820 }
2821 } else if (CHECK_FLAG(dest->flags,
2822 BGP_NODE_REGISTERED_FOR_LABEL)
2823 || CHECK_FLAG(dest->flags,
2824 BGP_NODE_LABEL_REQUESTED)) {
2825 bgp_unregister_for_label(dest);
2826 }
2827 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
2828 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
2829 bgp_unregister_for_label(dest);
2830 }
2831
2832 if (debug)
2833 zlog_debug(
2834 "%s: p=%pBD afi=%s, safi=%s, old_select=%p, new_select=%p",
2835 __func__, dest, afi2str(afi), safi2str(safi),
2836 old_select, new_select);
2837
2838 /* If best route remains the same and this is not due to user-initiated
2839 * clear, see exactly what needs to be done.
2840 */
2841 if (old_select && old_select == new_select
2842 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2843 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2844 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2845 if (bgp_zebra_has_route_changed(old_select)) {
2846 #ifdef ENABLE_BGP_VNC
2847 vnc_import_bgp_add_route(bgp, p, old_select);
2848 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2849 #endif
2850 if (bgp_fibupd_safi(safi)
2851 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2852
2853 if (new_select->type == ZEBRA_ROUTE_BGP
2854 && (new_select->sub_type == BGP_ROUTE_NORMAL
2855 || new_select->sub_type
2856 == BGP_ROUTE_IMPORTED))
2857
2858 bgp_zebra_announce(dest, p, old_select,
2859 bgp, afi, safi);
2860 }
2861 }
2862
2863 /* If there is a change of interest to peers, reannounce the
2864 * route. */
2865 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2866 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2867 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
2868 group_announce_route(bgp, afi, safi, dest, new_select);
2869
2870 /* unicast routes must also be annouced to
2871 * labeled-unicast update-groups */
2872 if (safi == SAFI_UNICAST)
2873 group_announce_route(bgp, afi,
2874 SAFI_LABELED_UNICAST, dest,
2875 new_select);
2876
2877 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2878 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
2879 }
2880
2881 /* advertise/withdraw type-5 routes */
2882 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2883 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
2884 bgp_process_evpn_route_injection(
2885 bgp, afi, safi, dest, old_select, old_select);
2886
2887 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
2888 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
2889 bgp_zebra_clear_route_change_flags(dest);
2890 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2891 return;
2892 }
2893
2894 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2895 */
2896 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
2897
2898 /* bestpath has changed; bump version */
2899 if (old_select || new_select) {
2900 bgp_bump_version(dest);
2901
2902 if (!bgp->t_rmap_def_originate_eval) {
2903 bgp_lock(bgp);
2904 thread_add_timer(
2905 bm->master,
2906 update_group_refresh_default_originate_route_map,
2907 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2908 &bgp->t_rmap_def_originate_eval);
2909 }
2910 }
2911
2912 if (old_select)
2913 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
2914 if (new_select) {
2915 if (debug)
2916 zlog_debug("%s: setting SELECTED flag", __func__);
2917 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
2918 bgp_path_info_unset_flag(dest, new_select,
2919 BGP_PATH_ATTR_CHANGED);
2920 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
2921 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
2922 }
2923
2924 #ifdef ENABLE_BGP_VNC
2925 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2926 if (old_select != new_select) {
2927 if (old_select) {
2928 vnc_import_bgp_exterior_del_route(bgp, p,
2929 old_select);
2930 vnc_import_bgp_del_route(bgp, p, old_select);
2931 }
2932 if (new_select) {
2933 vnc_import_bgp_exterior_add_route(bgp, p,
2934 new_select);
2935 vnc_import_bgp_add_route(bgp, p, new_select);
2936 }
2937 }
2938 }
2939 #endif
2940
2941 group_announce_route(bgp, afi, safi, dest, new_select);
2942
2943 /* unicast routes must also be annouced to labeled-unicast update-groups
2944 */
2945 if (safi == SAFI_UNICAST)
2946 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
2947 new_select);
2948
2949 /* FIB update. */
2950 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2951 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2952 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2953 && (new_select->sub_type == BGP_ROUTE_NORMAL
2954 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2955 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
2956
2957 /* if this is an evpn imported type-5 prefix,
2958 * we need to withdraw the route first to clear
2959 * the nh neigh and the RMAC entry.
2960 */
2961 if (old_select &&
2962 is_route_parent_evpn(old_select))
2963 bgp_zebra_withdraw(p, old_select, bgp, safi);
2964
2965 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
2966 } else {
2967 /* Withdraw the route from the kernel. */
2968 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2969 && (old_select->sub_type == BGP_ROUTE_NORMAL
2970 || old_select->sub_type == BGP_ROUTE_AGGREGATE
2971 || old_select->sub_type == BGP_ROUTE_IMPORTED))
2972
2973 bgp_zebra_withdraw(p, old_select, bgp, safi);
2974 }
2975 }
2976
2977 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
2978 old_select);
2979
2980 /* Clear any route change flags. */
2981 bgp_zebra_clear_route_change_flags(dest);
2982
2983 /* Reap old select bgp_path_info, if it has been removed */
2984 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
2985 bgp_path_info_reap(dest, old_select);
2986
2987 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2988 return;
2989 }
2990
2991 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
2992 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
2993 {
2994 struct bgp_dest *dest;
2995 int cnt = 0;
2996 struct afi_safi_info *thread_info;
2997
2998 if (bgp->gr_info[afi][safi].t_route_select) {
2999 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3000
3001 thread_info = THREAD_ARG(t);
3002 XFREE(MTYPE_TMP, thread_info);
3003 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
3004 }
3005
3006 if (BGP_DEBUG(update, UPDATE_OUT)) {
3007 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3008 get_afi_safi_str(afi, safi, false),
3009 bgp->gr_info[afi][safi].gr_deferred);
3010 }
3011
3012 /* Process the route list */
3013 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3014 dest && bgp->gr_info[afi][safi].gr_deferred != 0;
3015 dest = bgp_route_next(dest)) {
3016 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3017 continue;
3018
3019 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3020 bgp->gr_info[afi][safi].gr_deferred--;
3021 bgp_process_main_one(bgp, dest, afi, safi);
3022 cnt++;
3023 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) {
3024 bgp_dest_unlock_node(dest);
3025 break;
3026 }
3027 }
3028
3029 /* Send EOR message when all routes are processed */
3030 if (!bgp->gr_info[afi][safi].gr_deferred) {
3031 bgp_send_delayed_eor(bgp);
3032 /* Send route processing complete message to RIB */
3033 bgp_zebra_update(afi, safi, bgp->vrf_id,
3034 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3035 return 0;
3036 }
3037
3038 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3039
3040 thread_info->afi = afi;
3041 thread_info->safi = safi;
3042 thread_info->bgp = bgp;
3043
3044 /* If there are more routes to be processed, start the
3045 * selection timer
3046 */
3047 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3048 BGP_ROUTE_SELECT_DELAY,
3049 &bgp->gr_info[afi][safi].t_route_select);
3050 return 0;
3051 }
3052
3053 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3054 {
3055 struct bgp_process_queue *pqnode = data;
3056 struct bgp *bgp = pqnode->bgp;
3057 struct bgp_table *table;
3058 struct bgp_dest *dest;
3059
3060 /* eoiu marker */
3061 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3062 bgp_process_main_one(bgp, NULL, 0, 0);
3063 /* should always have dedicated wq call */
3064 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3065 return WQ_SUCCESS;
3066 }
3067
3068 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3069 dest = STAILQ_FIRST(&pqnode->pqueue);
3070 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3071 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3072 table = bgp_dest_table(dest);
3073 /* note, new DESTs may be added as part of processing */
3074 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3075
3076 bgp_dest_unlock_node(dest);
3077 bgp_table_unlock(table);
3078 }
3079
3080 return WQ_SUCCESS;
3081 }
3082
3083 static void bgp_processq_del(struct work_queue *wq, void *data)
3084 {
3085 struct bgp_process_queue *pqnode = data;
3086
3087 bgp_unlock(pqnode->bgp);
3088
3089 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3090 }
3091
3092 void bgp_process_queue_init(struct bgp *bgp)
3093 {
3094 if (!bgp->process_queue) {
3095 char name[BUFSIZ];
3096
3097 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3098 bgp->process_queue = work_queue_new(bm->master, name);
3099 }
3100
3101 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3102 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3103 bgp->process_queue->spec.max_retries = 0;
3104 bgp->process_queue->spec.hold = 50;
3105 /* Use a higher yield value of 50ms for main queue processing */
3106 bgp->process_queue->spec.yield = 50 * 1000L;
3107 }
3108
3109 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3110 {
3111 struct bgp_process_queue *pqnode;
3112
3113 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3114 sizeof(struct bgp_process_queue));
3115
3116 /* unlocked in bgp_processq_del */
3117 pqnode->bgp = bgp_lock(bgp);
3118 STAILQ_INIT(&pqnode->pqueue);
3119
3120 return pqnode;
3121 }
3122
3123 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3124 {
3125 #define ARBITRARY_PROCESS_QLEN 10000
3126 struct work_queue *wq = bgp->process_queue;
3127 struct bgp_process_queue *pqnode;
3128 int pqnode_reuse = 0;
3129
3130 /* already scheduled for processing? */
3131 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3132 return;
3133
3134 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3135 * the workqueue
3136 */
3137 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3138 if (BGP_DEBUG(update, UPDATE_OUT))
3139 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3140 dest);
3141 return;
3142 }
3143
3144 if (wq == NULL)
3145 return;
3146
3147 /* Add route nodes to an existing work queue item until reaching the
3148 limit only if is from the same BGP view and it's not an EOIU marker
3149 */
3150 if (work_queue_item_count(wq)) {
3151 struct work_queue_item *item = work_queue_last_item(wq);
3152 pqnode = item->data;
3153
3154 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3155 || pqnode->bgp != bgp
3156 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3157 pqnode = bgp_processq_alloc(bgp);
3158 else
3159 pqnode_reuse = 1;
3160 } else
3161 pqnode = bgp_processq_alloc(bgp);
3162 /* all unlocked in bgp_process_wq */
3163 bgp_table_lock(bgp_dest_table(dest));
3164
3165 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3166 bgp_dest_lock_node(dest);
3167
3168 /* can't be enqueued twice */
3169 assert(STAILQ_NEXT(dest, pq) == NULL);
3170 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3171 pqnode->queued++;
3172
3173 if (!pqnode_reuse)
3174 work_queue_add(wq, pqnode);
3175
3176 return;
3177 }
3178
3179 void bgp_add_eoiu_mark(struct bgp *bgp)
3180 {
3181 struct bgp_process_queue *pqnode;
3182
3183 if (bgp->process_queue == NULL)
3184 return;
3185
3186 pqnode = bgp_processq_alloc(bgp);
3187
3188 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3189 work_queue_add(bgp->process_queue, pqnode);
3190 }
3191
3192 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
3193 {
3194 struct peer *peer;
3195
3196 peer = THREAD_ARG(thread);
3197 peer->t_pmax_restart = NULL;
3198
3199 if (bgp_debug_neighbor_events(peer))
3200 zlog_debug(
3201 "%s Maximum-prefix restart timer expired, restore peering",
3202 peer->host);
3203
3204 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3205 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3206
3207 return 0;
3208 }
3209
3210 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3211 safi_t safi)
3212 {
3213 uint32_t count = 0;
3214 bool filtered = false;
3215 struct bgp_dest *dest;
3216 struct bgp_adj_in *ain;
3217 struct attr attr = {};
3218 struct bgp_table *table = peer->bgp->rib[afi][safi];
3219
3220 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3221 for (ain = dest->adj_in; ain; ain = ain->next) {
3222 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3223
3224 attr = *ain->attr;
3225
3226 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3227 == FILTER_DENY)
3228 filtered = true;
3229
3230 if (bgp_input_modifier(
3231 peer, rn_p, &attr, afi, safi,
3232 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3233 NULL, 0, NULL)
3234 == RMAP_DENY)
3235 filtered = true;
3236
3237 if (filtered)
3238 count++;
3239
3240 bgp_attr_undup(&attr, ain->attr);
3241 }
3242 }
3243
3244 return count;
3245 }
3246
3247 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3248 int always)
3249 {
3250 iana_afi_t pkt_afi;
3251 iana_safi_t pkt_safi;
3252 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3253 PEER_FLAG_MAX_PREFIX_FORCE))
3254 ? bgp_filtered_routes_count(peer, afi, safi)
3255 + peer->pcount[afi][safi]
3256 : peer->pcount[afi][safi];
3257
3258 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3259 return false;
3260
3261 if (pcount > peer->pmax[afi][safi]) {
3262 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3263 PEER_STATUS_PREFIX_LIMIT)
3264 && !always)
3265 return false;
3266
3267 zlog_info(
3268 "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u",
3269 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3270 peer->pmax[afi][safi]);
3271 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3272
3273 if (CHECK_FLAG(peer->af_flags[afi][safi],
3274 PEER_FLAG_MAX_PREFIX_WARNING))
3275 return false;
3276
3277 /* Convert AFI, SAFI to values for packet. */
3278 pkt_afi = afi_int2iana(afi);
3279 pkt_safi = safi_int2iana(safi);
3280 {
3281 uint8_t ndata[7];
3282
3283 ndata[0] = (pkt_afi >> 8);
3284 ndata[1] = pkt_afi;
3285 ndata[2] = pkt_safi;
3286 ndata[3] = (peer->pmax[afi][safi] >> 24);
3287 ndata[4] = (peer->pmax[afi][safi] >> 16);
3288 ndata[5] = (peer->pmax[afi][safi] >> 8);
3289 ndata[6] = (peer->pmax[afi][safi]);
3290
3291 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3292 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3293 BGP_NOTIFY_CEASE_MAX_PREFIX,
3294 ndata, 7);
3295 }
3296
3297 /* Dynamic peers will just close their connection. */
3298 if (peer_dynamic_neighbor(peer))
3299 return true;
3300
3301 /* restart timer start */
3302 if (peer->pmax_restart[afi][safi]) {
3303 peer->v_pmax_restart =
3304 peer->pmax_restart[afi][safi] * 60;
3305
3306 if (bgp_debug_neighbor_events(peer))
3307 zlog_debug(
3308 "%s Maximum-prefix restart timer started for %d secs",
3309 peer->host, peer->v_pmax_restart);
3310
3311 BGP_TIMER_ON(peer->t_pmax_restart,
3312 bgp_maximum_prefix_restart_timer,
3313 peer->v_pmax_restart);
3314 }
3315
3316 return true;
3317 } else
3318 UNSET_FLAG(peer->af_sflags[afi][safi],
3319 PEER_STATUS_PREFIX_LIMIT);
3320
3321 if (pcount
3322 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3323 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3324 PEER_STATUS_PREFIX_THRESHOLD)
3325 && !always)
3326 return false;
3327
3328 zlog_info(
3329 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3330 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3331 peer->pmax[afi][safi]);
3332 SET_FLAG(peer->af_sflags[afi][safi],
3333 PEER_STATUS_PREFIX_THRESHOLD);
3334 } else
3335 UNSET_FLAG(peer->af_sflags[afi][safi],
3336 PEER_STATUS_PREFIX_THRESHOLD);
3337 return false;
3338 }
3339
3340 /* Unconditionally remove the route from the RIB, without taking
3341 * damping into consideration (eg, because the session went down)
3342 */
3343 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3344 struct peer *peer, afi_t afi, safi_t safi)
3345 {
3346
3347 struct bgp *bgp = NULL;
3348 bool delete_route = false;
3349
3350 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3351 safi);
3352
3353 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3354 bgp_path_info_delete(dest, pi); /* keep historical info */
3355
3356 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3357 * flag
3358 */
3359 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3360 delete_route = true;
3361 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3362 delete_route = true;
3363 if (delete_route) {
3364 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3365 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3366 bgp = pi->peer->bgp;
3367 bgp->gr_info[afi][safi].gr_deferred--;
3368 }
3369 }
3370 }
3371
3372 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3373 bgp_process(peer->bgp, dest, afi, safi);
3374 }
3375
3376 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3377 struct peer *peer, afi_t afi, safi_t safi,
3378 struct prefix_rd *prd)
3379 {
3380 const struct prefix *p = bgp_dest_get_prefix(dest);
3381
3382 /* apply dampening, if result is suppressed, we'll be retaining
3383 * the bgp_path_info in the RIB for historical reference.
3384 */
3385 if (peer->sort == BGP_PEER_EBGP) {
3386 if (get_active_bdc_from_pi(pi, afi, safi)) {
3387 if (bgp_damp_withdraw(pi, dest, afi, safi, 0)
3388 == BGP_DAMP_SUPPRESSED) {
3389 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3390 safi);
3391 return;
3392 }
3393 }
3394 }
3395
3396 #ifdef ENABLE_BGP_VNC
3397 if (safi == SAFI_MPLS_VPN) {
3398 struct bgp_dest *pdest = NULL;
3399 struct bgp_table *table = NULL;
3400
3401 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3402 (struct prefix *)prd);
3403 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3404 table = bgp_dest_get_bgp_table_info(pdest);
3405
3406 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3407 peer->bgp, prd, table, p, pi);
3408 }
3409 bgp_dest_unlock_node(pdest);
3410 }
3411 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3412 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3413
3414 vnc_import_bgp_del_route(peer->bgp, p, pi);
3415 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3416 }
3417 }
3418 #endif
3419
3420 /* If this is an EVPN route, process for un-import. */
3421 if (safi == SAFI_EVPN)
3422 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3423
3424 bgp_rib_remove(dest, pi, peer, afi, safi);
3425 }
3426
3427 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3428 struct peer *peer, struct attr *attr,
3429 struct bgp_dest *dest)
3430 {
3431 struct bgp_path_info *new;
3432
3433 /* Make new BGP info. */
3434 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3435 new->type = type;
3436 new->instance = instance;
3437 new->sub_type = sub_type;
3438 new->peer = peer;
3439 new->attr = attr;
3440 new->uptime = bgp_clock();
3441 new->net = dest;
3442 return new;
3443 }
3444
3445 static void overlay_index_update(struct attr *attr,
3446 union gw_addr *gw_ip)
3447 {
3448 if (!attr)
3449 return;
3450 if (gw_ip == NULL) {
3451 struct bgp_route_evpn eo;
3452
3453 memset(&eo, 0, sizeof(eo));
3454 bgp_attr_set_evpn_overlay(attr, &eo);
3455 } else {
3456 struct bgp_route_evpn eo = {.gw_ip = *gw_ip};
3457
3458 bgp_attr_set_evpn_overlay(attr, &eo);
3459 }
3460 }
3461
3462 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3463 union gw_addr *gw_ip)
3464 {
3465 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(path->attr);
3466 union gw_addr path_gw_ip, *path_gw_ip_remote;
3467 union {
3468 esi_t esi;
3469 union gw_addr ip;
3470 } temp;
3471
3472 if (afi != AFI_L2VPN)
3473 return true;
3474
3475 path_gw_ip = eo->gw_ip;
3476
3477 if (gw_ip == NULL) {
3478 memset(&temp, 0, sizeof(temp));
3479 path_gw_ip_remote = &temp.ip;
3480 } else
3481 path_gw_ip_remote = gw_ip;
3482
3483 return !!memcmp(&path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
3484 }
3485
3486 /* Check if received nexthop is valid or not. */
3487 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3488 uint8_t type, uint8_t stype, struct attr *attr,
3489 struct bgp_dest *dest)
3490 {
3491 bool ret = false;
3492 bool is_bgp_static_route =
3493 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3494 : false;
3495
3496 /*
3497 * Only validated for unicast and multicast currently.
3498 * Also valid for EVPN where the nexthop is an IP address.
3499 * If we are a bgp static route being checked then there is
3500 * no need to check to see if the nexthop is martian as
3501 * that it should be ok.
3502 */
3503 if (is_bgp_static_route ||
3504 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3505 return false;
3506
3507 /* If NEXT_HOP is present, validate it. */
3508 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3509 if (attr->nexthop.s_addr == INADDR_ANY
3510 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3511 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3512 return true;
3513 }
3514
3515 /* If MP_NEXTHOP is present, validate it. */
3516 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3517 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3518 * it is not an IPv6 link-local address.
3519 *
3520 * If we receive an UPDATE with nexthop length set to 32 bytes
3521 * we shouldn't discard an UPDATE if it's set to (::).
3522 * The link-local (2st) is validated along the code path later.
3523 */
3524 if (attr->mp_nexthop_len) {
3525 switch (attr->mp_nexthop_len) {
3526 case BGP_ATTR_NHLEN_IPV4:
3527 case BGP_ATTR_NHLEN_VPNV4:
3528 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3529 || IPV4_CLASS_DE(
3530 ntohl(attr->mp_nexthop_global_in.s_addr))
3531 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3532 dest));
3533 break;
3534
3535 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3536 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3537 ret = (IN6_IS_ADDR_UNSPECIFIED(
3538 &attr->mp_nexthop_global)
3539 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3540 || IN6_IS_ADDR_MULTICAST(
3541 &attr->mp_nexthop_global)
3542 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3543 dest));
3544 break;
3545 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3546 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3547 || IN6_IS_ADDR_MULTICAST(
3548 &attr->mp_nexthop_global)
3549 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3550 dest));
3551 break;
3552
3553 default:
3554 ret = true;
3555 break;
3556 }
3557 }
3558
3559 return ret;
3560 }
3561
3562 static void bgp_attr_add_no_export_community(struct attr *attr)
3563 {
3564 struct community *old;
3565 struct community *new;
3566 struct community *merge;
3567 struct community *no_export;
3568
3569 old = attr->community;
3570 no_export = community_str2com("no-export");
3571
3572 assert(no_export);
3573
3574 if (old) {
3575 merge = community_merge(community_dup(old), no_export);
3576
3577 if (!old->refcnt)
3578 community_free(&old);
3579
3580 new = community_uniq_sort(merge);
3581 community_free(&merge);
3582 } else {
3583 new = community_dup(no_export);
3584 }
3585
3586 community_free(&no_export);
3587
3588 attr->community = new;
3589 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
3590 }
3591
3592 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3593 struct attr *attr, afi_t afi, safi_t safi, int type,
3594 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3595 uint32_t num_labels, int soft_reconfig,
3596 struct bgp_route_evpn *evpn)
3597 {
3598 int ret;
3599 int aspath_loop_count = 0;
3600 struct bgp_dest *dest;
3601 struct bgp *bgp;
3602 struct attr new_attr;
3603 struct attr *attr_new;
3604 struct bgp_path_info *pi;
3605 struct bgp_path_info *new;
3606 struct bgp_path_info_extra *extra;
3607 const char *reason;
3608 char pfx_buf[BGP_PRD_PATH_STRLEN];
3609 int connected = 0;
3610 int do_loop_check = 1;
3611 int has_valid_label = 0;
3612 afi_t nh_afi;
3613 uint8_t pi_type = 0;
3614 uint8_t pi_sub_type = 0;
3615
3616 if (frrtrace_enabled(frr_bgp, process_update)) {
3617 char pfxprint[PREFIX2STR_BUFFER];
3618
3619 prefix2str(p, pfxprint, sizeof(pfxprint));
3620 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3621 afi, safi, attr);
3622 }
3623
3624 #ifdef ENABLE_BGP_VNC
3625 int vnc_implicit_withdraw = 0;
3626 #endif
3627 int same_attr = 0;
3628
3629 memset(&new_attr, 0, sizeof(struct attr));
3630 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3631 new_attr.label = MPLS_INVALID_LABEL;
3632
3633 bgp = peer->bgp;
3634 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3635 /* TODO: Check to see if we can get rid of "is_valid_label" */
3636 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3637 has_valid_label = (num_labels > 0) ? 1 : 0;
3638 else
3639 has_valid_label = bgp_is_valid_label(label);
3640
3641 if (has_valid_label)
3642 assert(label != NULL);
3643
3644 /* When peer's soft reconfiguration enabled. Record input packet in
3645 Adj-RIBs-In. */
3646 if (!soft_reconfig
3647 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3648 && peer != bgp->peer_self)
3649 bgp_adj_in_set(dest, peer, attr, addpath_id);
3650
3651 /* Check previously received route. */
3652 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3653 if (pi->peer == peer && pi->type == type
3654 && pi->sub_type == sub_type
3655 && pi->addpath_rx_id == addpath_id)
3656 break;
3657
3658 /* AS path local-as loop check. */
3659 if (peer->change_local_as) {
3660 if (peer->allowas_in[afi][safi])
3661 aspath_loop_count = peer->allowas_in[afi][safi];
3662 else if (!CHECK_FLAG(peer->flags,
3663 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3664 aspath_loop_count = 1;
3665
3666 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3667 > aspath_loop_count) {
3668 peer->stat_pfx_aspath_loop++;
3669 reason = "as-path contains our own AS A;";
3670 goto filtered;
3671 }
3672 }
3673
3674 /* If the peer is configured for "allowas-in origin" and the last ASN in
3675 * the
3676 * as-path is our ASN then we do not need to call aspath_loop_check
3677 */
3678 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3679 if (aspath_get_last_as(attr->aspath) == bgp->as)
3680 do_loop_check = 0;
3681
3682 /* AS path loop check. */
3683 if (do_loop_check) {
3684 if (aspath_loop_check(attr->aspath, bgp->as)
3685 > peer->allowas_in[afi][safi]
3686 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3687 && aspath_loop_check(attr->aspath, bgp->confed_id)
3688 > peer->allowas_in[afi][safi])) {
3689 peer->stat_pfx_aspath_loop++;
3690 reason = "as-path contains our own AS;";
3691 goto filtered;
3692 }
3693 }
3694
3695 /* Route reflector originator ID check. */
3696 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3697 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3698 peer->stat_pfx_originator_loop++;
3699 reason = "originator is us;";
3700 goto filtered;
3701 }
3702
3703 /* Route reflector cluster ID check. */
3704 if (bgp_cluster_filter(peer, attr)) {
3705 peer->stat_pfx_cluster_loop++;
3706 reason = "reflected from the same cluster;";
3707 goto filtered;
3708 }
3709
3710 /* Apply incoming filter. */
3711 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3712 peer->stat_pfx_filter++;
3713 reason = "filter;";
3714 goto filtered;
3715 }
3716
3717 /* RFC 8212 to prevent route leaks.
3718 * This specification intends to improve this situation by requiring the
3719 * explicit configuration of both BGP Import and Export Policies for any
3720 * External BGP (EBGP) session such as customers, peers, or
3721 * confederation boundaries for all enabled address families. Through
3722 * codification of the aforementioned requirement, operators will
3723 * benefit from consistent behavior across different BGP
3724 * implementations.
3725 */
3726 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3727 if (!bgp_inbound_policy_exists(peer,
3728 &peer->filter[afi][safi])) {
3729 reason = "inbound policy missing";
3730 goto filtered;
3731 }
3732
3733 /* draft-ietf-idr-deprecate-as-set-confed-set
3734 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3735 * Eventually, This document (if approved) updates RFC 4271
3736 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3737 * and obsoletes RFC 6472.
3738 */
3739 if (peer->bgp->reject_as_sets)
3740 if (aspath_check_as_sets(attr->aspath)) {
3741 reason =
3742 "as-path contains AS_SET or AS_CONFED_SET type;";
3743 goto filtered;
3744 }
3745
3746 new_attr = *attr;
3747
3748 /* Apply incoming route-map.
3749 * NB: new_attr may now contain newly allocated values from route-map
3750 * "set"
3751 * commands, so we need bgp_attr_flush in the error paths, until we
3752 * intern
3753 * the attr (which takes over the memory references) */
3754 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL, label,
3755 num_labels, dest)
3756 == RMAP_DENY) {
3757 peer->stat_pfx_filter++;
3758 reason = "route-map;";
3759 bgp_attr_flush(&new_attr);
3760 goto filtered;
3761 }
3762
3763 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3764 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3765 /* remove from RIB previous entry */
3766 bgp_zebra_withdraw(p, pi, bgp, safi);
3767 }
3768
3769 if (peer->sort == BGP_PEER_EBGP) {
3770
3771 /* rfc7999:
3772 * A BGP speaker receiving an announcement tagged with the
3773 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
3774 * NO_EXPORT community as defined in RFC1997, or a
3775 * similar community, to prevent propagation of the
3776 * prefix outside the local AS. The community to prevent
3777 * propagation SHOULD be chosen according to the operator's
3778 * routing policy.
3779 */
3780 if (new_attr.community
3781 && community_include(new_attr.community,
3782 COMMUNITY_BLACKHOLE))
3783 bgp_attr_add_no_export_community(&new_attr);
3784
3785 /* If we receive the graceful-shutdown community from an eBGP
3786 * peer we must lower local-preference */
3787 if (new_attr.community
3788 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3789 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3790 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3791
3792 /* If graceful-shutdown is configured then add the GSHUT
3793 * community to all paths received from eBGP peers */
3794 } else if (bgp_in_graceful_shutdown(peer->bgp))
3795 bgp_attr_add_gshut_community(&new_attr);
3796 }
3797
3798 if (pi) {
3799 pi_type = pi->type;
3800 pi_sub_type = pi->sub_type;
3801 }
3802
3803 /* next hop check. */
3804 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3805 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3806 &new_attr, dest)) {
3807 peer->stat_pfx_nh_invalid++;
3808 reason = "martian or self next-hop;";
3809 bgp_attr_flush(&new_attr);
3810 goto filtered;
3811 }
3812
3813 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3814 peer->stat_pfx_nh_invalid++;
3815 reason = "self mac;";
3816 goto filtered;
3817 }
3818
3819 /* Update Overlay Index */
3820 if (afi == AFI_L2VPN) {
3821 overlay_index_update(&new_attr,
3822 evpn == NULL ? NULL : &evpn->gw_ip);
3823 }
3824
3825 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
3826 * condition :
3827 * Suppress fib is enabled
3828 * BGP_OPT_NO_FIB is not enabled
3829 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
3830 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
3831 */
3832 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
3833 && (sub_type == BGP_ROUTE_NORMAL)
3834 && (!bgp_option_check(BGP_OPT_NO_FIB))
3835 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
3836 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
3837
3838 attr_new = bgp_attr_intern(&new_attr);
3839
3840 /* If maximum prefix count is configured and current prefix
3841 * count exeed it.
3842 */
3843 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3844 return -1;
3845
3846 /* If the update is implicit withdraw. */
3847 if (pi) {
3848 pi->uptime = bgp_clock();
3849 same_attr = attrhash_cmp(pi->attr, attr_new);
3850
3851 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3852
3853 /* Same attribute comes in. */
3854 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3855 && same_attr
3856 && (!has_valid_label
3857 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3858 num_labels * sizeof(mpls_label_t))
3859 == 0)
3860 && (overlay_index_equal(
3861 afi, pi,
3862 evpn == NULL ? NULL : &evpn->gw_ip))) {
3863 if (get_active_bdc_from_pi(pi, afi, safi)
3864 && peer->sort == BGP_PEER_EBGP
3865 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3866 if (bgp_debug_update(peer, p, NULL, 1)) {
3867 bgp_debug_rdpfxpath2str(
3868 afi, safi, prd, p, label,
3869 num_labels, addpath_id ? 1 : 0,
3870 addpath_id, pfx_buf,
3871 sizeof(pfx_buf));
3872 zlog_debug("%s rcvd %s", peer->host,
3873 pfx_buf);
3874 }
3875
3876 if (bgp_damp_update(pi, dest, afi, safi)
3877 != BGP_DAMP_SUPPRESSED) {
3878 bgp_aggregate_increment(bgp, p, pi, afi,
3879 safi);
3880 bgp_process(bgp, dest, afi, safi);
3881 }
3882 } else /* Duplicate - odd */
3883 {
3884 if (bgp_debug_update(peer, p, NULL, 1)) {
3885 if (!peer->rcvd_attr_printed) {
3886 zlog_debug(
3887 "%s rcvd UPDATE w/ attr: %s",
3888 peer->host,
3889 peer->rcvd_attr_str);
3890 peer->rcvd_attr_printed = 1;
3891 }
3892
3893 bgp_debug_rdpfxpath2str(
3894 afi, safi, prd, p, label,
3895 num_labels, addpath_id ? 1 : 0,
3896 addpath_id, pfx_buf,
3897 sizeof(pfx_buf));
3898 zlog_debug(
3899 "%s rcvd %s...duplicate ignored",
3900 peer->host, pfx_buf);
3901 }
3902
3903 /* graceful restart STALE flag unset. */
3904 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3905 bgp_path_info_unset_flag(
3906 dest, pi, BGP_PATH_STALE);
3907 bgp_dest_set_defer_flag(dest, false);
3908 bgp_process(bgp, dest, afi, safi);
3909 }
3910 }
3911
3912 bgp_dest_unlock_node(dest);
3913 bgp_attr_unintern(&attr_new);
3914
3915 return 0;
3916 }
3917
3918 /* Withdraw/Announce before we fully processed the withdraw */
3919 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3920 if (bgp_debug_update(peer, p, NULL, 1)) {
3921 bgp_debug_rdpfxpath2str(
3922 afi, safi, prd, p, label, num_labels,
3923 addpath_id ? 1 : 0, addpath_id, pfx_buf,
3924 sizeof(pfx_buf));
3925 zlog_debug(
3926 "%s rcvd %s, flapped quicker than processing",
3927 peer->host, pfx_buf);
3928 }
3929
3930 bgp_path_info_restore(dest, pi);
3931 }
3932
3933 /* Received Logging. */
3934 if (bgp_debug_update(peer, p, NULL, 1)) {
3935 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3936 num_labels, addpath_id ? 1 : 0,
3937 addpath_id, pfx_buf,
3938 sizeof(pfx_buf));
3939 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3940 }
3941
3942 /* graceful restart STALE flag unset. */
3943 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3944 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
3945 bgp_dest_set_defer_flag(dest, false);
3946 }
3947
3948 /* The attribute is changed. */
3949 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
3950
3951 /* implicit withdraw, decrement aggregate and pcount here.
3952 * only if update is accepted, they'll increment below.
3953 */
3954 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3955
3956 /* Update bgp route dampening information. */
3957 if (get_active_bdc_from_pi(pi, afi, safi)
3958 && peer->sort == BGP_PEER_EBGP) {
3959 /* This is implicit withdraw so we should update
3960 * dampening information.
3961 */
3962 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3963 bgp_damp_withdraw(pi, dest, afi, safi, 1);
3964 }
3965 #ifdef ENABLE_BGP_VNC
3966 if (safi == SAFI_MPLS_VPN) {
3967 struct bgp_dest *pdest = NULL;
3968 struct bgp_table *table = NULL;
3969
3970 pdest = bgp_node_get(bgp->rib[afi][safi],
3971 (struct prefix *)prd);
3972 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3973 table = bgp_dest_get_bgp_table_info(pdest);
3974
3975 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3976 bgp, prd, table, p, pi);
3977 }
3978 bgp_dest_unlock_node(pdest);
3979 }
3980 if ((afi == AFI_IP || afi == AFI_IP6)
3981 && (safi == SAFI_UNICAST)) {
3982 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3983 /*
3984 * Implicit withdraw case.
3985 */
3986 ++vnc_implicit_withdraw;
3987 vnc_import_bgp_del_route(bgp, p, pi);
3988 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3989 }
3990 }
3991 #endif
3992
3993 /* Special handling for EVPN update of an existing route. If the
3994 * extended community attribute has changed, we need to
3995 * un-import
3996 * the route using its existing extended community. It will be
3997 * subsequently processed for import with the new extended
3998 * community.
3999 */
4000 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
4001 && !same_attr) {
4002 if ((pi->attr->flag
4003 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4004 && (attr_new->flag
4005 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4006 int cmp;
4007
4008 cmp = ecommunity_cmp(pi->attr->ecommunity,
4009 attr_new->ecommunity);
4010 if (!cmp) {
4011 if (bgp_debug_update(peer, p, NULL, 1))
4012 zlog_debug(
4013 "Change in EXT-COMM, existing %s new %s",
4014 ecommunity_str(
4015 pi->attr->ecommunity),
4016 ecommunity_str(
4017 attr_new->ecommunity));
4018 if (safi == SAFI_EVPN)
4019 bgp_evpn_unimport_route(
4020 bgp, afi, safi, p, pi);
4021 else /* SAFI_MPLS_VPN */
4022 vpn_leak_to_vrf_withdraw(bgp,
4023 pi);
4024 }
4025 }
4026 }
4027
4028 /* Update to new attribute. */
4029 bgp_attr_unintern(&pi->attr);
4030 pi->attr = attr_new;
4031
4032 /* Update MPLS label */
4033 if (has_valid_label) {
4034 extra = bgp_path_info_extra_get(pi);
4035 if (extra->label != label) {
4036 memcpy(&extra->label, label,
4037 num_labels * sizeof(mpls_label_t));
4038 extra->num_labels = num_labels;
4039 }
4040 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4041 bgp_set_valid_label(&extra->label[0]);
4042 }
4043
4044 /* Update SRv6 SID */
4045 if (attr->srv6_l3vpn) {
4046 extra = bgp_path_info_extra_get(pi);
4047 if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) {
4048 sid_copy(&extra->sid[0],
4049 &attr->srv6_l3vpn->sid);
4050 extra->num_sids = 1;
4051 }
4052 } else if (attr->srv6_vpn) {
4053 extra = bgp_path_info_extra_get(pi);
4054 if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) {
4055 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4056 extra->num_sids = 1;
4057 }
4058 }
4059
4060 #ifdef ENABLE_BGP_VNC
4061 if ((afi == AFI_IP || afi == AFI_IP6)
4062 && (safi == SAFI_UNICAST)) {
4063 if (vnc_implicit_withdraw) {
4064 /*
4065 * Add back the route with its new attributes
4066 * (e.g., nexthop).
4067 * The route is still selected, until the route
4068 * selection
4069 * queued by bgp_process actually runs. We have
4070 * to make this
4071 * update to the VNC side immediately to avoid
4072 * racing against
4073 * configuration changes (e.g., route-map
4074 * changes) which
4075 * trigger re-importation of the entire RIB.
4076 */
4077 vnc_import_bgp_add_route(bgp, p, pi);
4078 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4079 }
4080 }
4081 #endif
4082
4083 /* Update bgp route dampening information. */
4084 if (get_active_bdc_from_pi(pi, afi, safi)
4085 && peer->sort == BGP_PEER_EBGP) {
4086 /* Now we do normal update dampening. */
4087 ret = bgp_damp_update(pi, dest, afi, safi);
4088 if (ret == BGP_DAMP_SUPPRESSED) {
4089 bgp_dest_unlock_node(dest);
4090 return 0;
4091 }
4092 }
4093
4094 /* Nexthop reachability check - for unicast and
4095 * labeled-unicast.. */
4096 if (((afi == AFI_IP || afi == AFI_IP6)
4097 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4098 || (safi == SAFI_EVPN &&
4099 bgp_evpn_is_prefix_nht_supported(p))) {
4100 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4101 && peer->ttl == BGP_DEFAULT_TTL
4102 && !CHECK_FLAG(peer->flags,
4103 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4104 && !CHECK_FLAG(bgp->flags,
4105 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4106 connected = 1;
4107 else
4108 connected = 0;
4109
4110 struct bgp *bgp_nexthop = bgp;
4111
4112 if (pi->extra && pi->extra->bgp_orig)
4113 bgp_nexthop = pi->extra->bgp_orig;
4114
4115 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4116
4117 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4118 safi, pi, NULL, connected)
4119 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4120 bgp_path_info_set_flag(dest, pi,
4121 BGP_PATH_VALID);
4122 else {
4123 if (BGP_DEBUG(nht, NHT)) {
4124 zlog_debug("%s(%pI4): NH unresolved",
4125 __func__,
4126 (in_addr_t *)&attr_new->nexthop);
4127 }
4128 bgp_path_info_unset_flag(dest, pi,
4129 BGP_PATH_VALID);
4130 }
4131 } else
4132 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4133
4134 #ifdef ENABLE_BGP_VNC
4135 if (safi == SAFI_MPLS_VPN) {
4136 struct bgp_dest *pdest = NULL;
4137 struct bgp_table *table = NULL;
4138
4139 pdest = bgp_node_get(bgp->rib[afi][safi],
4140 (struct prefix *)prd);
4141 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4142 table = bgp_dest_get_bgp_table_info(pdest);
4143
4144 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4145 bgp, prd, table, p, pi);
4146 }
4147 bgp_dest_unlock_node(pdest);
4148 }
4149 #endif
4150
4151 /* If this is an EVPN route and some attribute has changed,
4152 * process
4153 * route for import. If the extended community has changed, we
4154 * would
4155 * have done the un-import earlier and the import would result
4156 * in the
4157 * route getting injected into appropriate L2 VNIs. If it is
4158 * just
4159 * some other attribute change, the import will result in
4160 * updating
4161 * the attributes for the route in the VNI(s).
4162 */
4163 if (safi == SAFI_EVPN && !same_attr &&
4164 CHECK_FLAG(pi->flags, BGP_PATH_VALID))
4165 bgp_evpn_import_route(bgp, afi, safi, p, pi);
4166
4167 /* Process change. */
4168 bgp_aggregate_increment(bgp, p, pi, afi, safi);
4169
4170 bgp_process(bgp, dest, afi, safi);
4171 bgp_dest_unlock_node(dest);
4172
4173 if (SAFI_UNICAST == safi
4174 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4175 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4176
4177 vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
4178 }
4179 if ((SAFI_MPLS_VPN == safi)
4180 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4181
4182 vpn_leak_to_vrf_update(bgp, pi);
4183 }
4184
4185 #ifdef ENABLE_BGP_VNC
4186 if (SAFI_MPLS_VPN == safi) {
4187 mpls_label_t label_decoded = decode_label(label);
4188
4189 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4190 type, sub_type, &label_decoded);
4191 }
4192 if (SAFI_ENCAP == safi) {
4193 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
4194 type, sub_type, NULL);
4195 }
4196 #endif
4197
4198 return 0;
4199 } // End of implicit withdraw
4200
4201 /* Received Logging. */
4202 if (bgp_debug_update(peer, p, NULL, 1)) {
4203 if (!peer->rcvd_attr_printed) {
4204 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4205 peer->rcvd_attr_str);
4206 peer->rcvd_attr_printed = 1;
4207 }
4208
4209 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4210 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4211 sizeof(pfx_buf));
4212 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
4213 }
4214
4215 /* Make new BGP info. */
4216 new = info_make(type, sub_type, 0, peer, attr_new, dest);
4217
4218 /* Update MPLS label */
4219 if (has_valid_label) {
4220 extra = bgp_path_info_extra_get(new);
4221 if (extra->label != label) {
4222 memcpy(&extra->label, label,
4223 num_labels * sizeof(mpls_label_t));
4224 extra->num_labels = num_labels;
4225 }
4226 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4227 bgp_set_valid_label(&extra->label[0]);
4228 }
4229
4230 /* Update SRv6 SID */
4231 if (safi == SAFI_MPLS_VPN) {
4232 extra = bgp_path_info_extra_get(new);
4233 if (attr->srv6_l3vpn) {
4234 sid_copy(&extra->sid[0], &attr->srv6_l3vpn->sid);
4235 extra->num_sids = 1;
4236 } else if (attr->srv6_vpn) {
4237 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4238 extra->num_sids = 1;
4239 }
4240 }
4241
4242 /* Update Overlay Index */
4243 if (afi == AFI_L2VPN) {
4244 overlay_index_update(new->attr,
4245 evpn == NULL ? NULL : &evpn->gw_ip);
4246 }
4247 /* Nexthop reachability check. */
4248 if (((afi == AFI_IP || afi == AFI_IP6)
4249 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4250 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4251 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4252 && peer->ttl == BGP_DEFAULT_TTL
4253 && !CHECK_FLAG(peer->flags,
4254 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4255 && !CHECK_FLAG(bgp->flags,
4256 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4257 connected = 1;
4258 else
4259 connected = 0;
4260
4261 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4262
4263 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4264 connected)
4265 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4266 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4267 else {
4268 if (BGP_DEBUG(nht, NHT)) {
4269 char buf1[INET6_ADDRSTRLEN];
4270 inet_ntop(AF_INET,
4271 (const void *)&attr_new->nexthop,
4272 buf1, INET6_ADDRSTRLEN);
4273 zlog_debug("%s(%s): NH unresolved", __func__,
4274 buf1);
4275 }
4276 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4277 }
4278 } else
4279 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4280
4281 /* Addpath ID */
4282 new->addpath_rx_id = addpath_id;
4283
4284 /* Increment prefix */
4285 bgp_aggregate_increment(bgp, p, new, afi, safi);
4286
4287 /* Register new BGP information. */
4288 bgp_path_info_add(dest, new);
4289
4290 /* route_node_get lock */
4291 bgp_dest_unlock_node(dest);
4292
4293 #ifdef ENABLE_BGP_VNC
4294 if (safi == SAFI_MPLS_VPN) {
4295 struct bgp_dest *pdest = NULL;
4296 struct bgp_table *table = NULL;
4297
4298 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4299 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4300 table = bgp_dest_get_bgp_table_info(pdest);
4301
4302 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4303 bgp, prd, table, p, new);
4304 }
4305 bgp_dest_unlock_node(pdest);
4306 }
4307 #endif
4308
4309 /* If this is an EVPN route, process for import. */
4310 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4311 bgp_evpn_import_route(bgp, afi, safi, p, new);
4312
4313 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4314
4315 /* Process change. */
4316 bgp_process(bgp, dest, afi, safi);
4317
4318 if (SAFI_UNICAST == safi
4319 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4320 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4321 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4322 }
4323 if ((SAFI_MPLS_VPN == safi)
4324 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4325
4326 vpn_leak_to_vrf_update(bgp, new);
4327 }
4328 #ifdef ENABLE_BGP_VNC
4329 if (SAFI_MPLS_VPN == safi) {
4330 mpls_label_t label_decoded = decode_label(label);
4331
4332 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4333 sub_type, &label_decoded);
4334 }
4335 if (SAFI_ENCAP == safi) {
4336 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4337 sub_type, NULL);
4338 }
4339 #endif
4340
4341 return 0;
4342
4343 /* This BGP update is filtered. Log the reason then update BGP
4344 entry. */
4345 filtered:
4346 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4347
4348 if (bgp_debug_update(peer, p, NULL, 1)) {
4349 if (!peer->rcvd_attr_printed) {
4350 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4351 peer->rcvd_attr_str);
4352 peer->rcvd_attr_printed = 1;
4353 }
4354
4355 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4356 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4357 sizeof(pfx_buf));
4358 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4359 peer->host, pfx_buf, reason);
4360 }
4361
4362 if (pi) {
4363 /* If this is an EVPN route, un-import it as it is now filtered.
4364 */
4365 if (safi == SAFI_EVPN)
4366 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4367
4368 if (SAFI_UNICAST == safi
4369 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4370 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4371
4372 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4373 }
4374 if ((SAFI_MPLS_VPN == safi)
4375 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4376
4377 vpn_leak_to_vrf_withdraw(bgp, pi);
4378 }
4379
4380 bgp_rib_remove(dest, pi, peer, afi, safi);
4381 }
4382
4383 bgp_dest_unlock_node(dest);
4384
4385 #ifdef ENABLE_BGP_VNC
4386 /*
4387 * Filtered update is treated as an implicit withdrawal (see
4388 * bgp_rib_remove()
4389 * a few lines above)
4390 */
4391 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4392 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4393 0);
4394 }
4395 #endif
4396
4397 return 0;
4398 }
4399
4400 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4401 struct attr *attr, afi_t afi, safi_t safi, int type,
4402 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4403 uint32_t num_labels, struct bgp_route_evpn *evpn)
4404 {
4405 struct bgp *bgp;
4406 char pfx_buf[BGP_PRD_PATH_STRLEN];
4407 struct bgp_dest *dest;
4408 struct bgp_path_info *pi;
4409
4410 #ifdef ENABLE_BGP_VNC
4411 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4412 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4413 0);
4414 }
4415 #endif
4416
4417 bgp = peer->bgp;
4418
4419 /* Lookup node. */
4420 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4421
4422 /* If peer is soft reconfiguration enabled. Record input packet for
4423 * further calculation.
4424 *
4425 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4426 * routes that are filtered. This tanks out Quagga RS pretty badly due
4427 * to
4428 * the iteration over all RS clients.
4429 * Since we need to remove the entry from adj_in anyway, do that first
4430 * and
4431 * if there was no entry, we don't need to do anything more.
4432 */
4433 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4434 && peer != bgp->peer_self)
4435 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4436 peer->stat_pfx_dup_withdraw++;
4437
4438 if (bgp_debug_update(peer, p, NULL, 1)) {
4439 bgp_debug_rdpfxpath2str(
4440 afi, safi, prd, p, label, num_labels,
4441 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4442 sizeof(pfx_buf));
4443 zlog_debug(
4444 "%s withdrawing route %s not in adj-in",
4445 peer->host, pfx_buf);
4446 }
4447 bgp_dest_unlock_node(dest);
4448 return 0;
4449 }
4450
4451 /* Lookup withdrawn route. */
4452 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4453 if (pi->peer == peer && pi->type == type
4454 && pi->sub_type == sub_type
4455 && pi->addpath_rx_id == addpath_id)
4456 break;
4457
4458 /* Logging. */
4459 if (bgp_debug_update(peer, p, NULL, 1)) {
4460 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4461 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4462 sizeof(pfx_buf));
4463 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4464 pfx_buf);
4465 }
4466
4467 /* Withdraw specified route from routing table. */
4468 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4469 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4470 if (SAFI_UNICAST == safi
4471 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4472 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4473 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4474 }
4475 if ((SAFI_MPLS_VPN == safi)
4476 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4477
4478 vpn_leak_to_vrf_withdraw(bgp, pi);
4479 }
4480 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4481 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4482 addpath_id ? 1 : 0, addpath_id, pfx_buf,
4483 sizeof(pfx_buf));
4484 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4485 }
4486
4487 /* Unlock bgp_node_get() lock. */
4488 bgp_dest_unlock_node(dest);
4489
4490 return 0;
4491 }
4492
4493 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4494 int withdraw)
4495 {
4496 struct update_subgroup *subgrp;
4497 subgrp = peer_subgroup(peer, afi, safi);
4498 subgroup_default_originate(subgrp, withdraw);
4499 }
4500
4501
4502 /*
4503 * bgp_stop_announce_route_timer
4504 */
4505 void bgp_stop_announce_route_timer(struct peer_af *paf)
4506 {
4507 if (!paf->t_announce_route)
4508 return;
4509
4510 thread_cancel(&paf->t_announce_route);
4511 }
4512
4513 /*
4514 * bgp_announce_route_timer_expired
4515 *
4516 * Callback that is invoked when the route announcement timer for a
4517 * peer_af expires.
4518 */
4519 static int bgp_announce_route_timer_expired(struct thread *t)
4520 {
4521 struct peer_af *paf;
4522 struct peer *peer;
4523
4524 paf = THREAD_ARG(t);
4525 peer = paf->peer;
4526
4527 if (!peer_established(peer))
4528 return 0;
4529
4530 if (!peer->afc_nego[paf->afi][paf->safi])
4531 return 0;
4532
4533 peer_af_announce_route(paf, 1);
4534
4535 /* Notify BGP conditional advertisement scanner percess */
4536 peer->advmap_config_change[paf->afi][paf->safi] = true;
4537
4538 return 0;
4539 }
4540
4541 /*
4542 * bgp_announce_route
4543 *
4544 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4545 */
4546 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4547 {
4548 struct peer_af *paf;
4549 struct update_subgroup *subgrp;
4550
4551 paf = peer_af_find(peer, afi, safi);
4552 if (!paf)
4553 return;
4554 subgrp = PAF_SUBGRP(paf);
4555
4556 /*
4557 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4558 * or a refresh has already been triggered.
4559 */
4560 if (!subgrp || paf->t_announce_route)
4561 return;
4562
4563 /*
4564 * Start a timer to stagger/delay the announce. This serves
4565 * two purposes - announcement can potentially be combined for
4566 * multiple peers and the announcement doesn't happen in the
4567 * vty context.
4568 */
4569 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4570 (subgrp->peer_count == 1)
4571 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4572 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4573 &paf->t_announce_route);
4574 }
4575
4576 /*
4577 * Announce routes from all AF tables to a peer.
4578 *
4579 * This should ONLY be called when there is a need to refresh the
4580 * routes to the peer based on a policy change for this peer alone
4581 * or a route refresh request received from the peer.
4582 * The operation will result in splitting the peer from its existing
4583 * subgroups and putting it in new subgroups.
4584 */
4585 void bgp_announce_route_all(struct peer *peer)
4586 {
4587 afi_t afi;
4588 safi_t safi;
4589
4590 FOREACH_AFI_SAFI (afi, safi)
4591 bgp_announce_route(peer, afi, safi);
4592 }
4593
4594 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4595 struct bgp_table *table,
4596 struct prefix_rd *prd)
4597 {
4598 int ret;
4599 struct bgp_dest *dest;
4600 struct bgp_adj_in *ain;
4601
4602 if (!table)
4603 table = peer->bgp->rib[afi][safi];
4604
4605 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4606 for (ain = dest->adj_in; ain; ain = ain->next) {
4607 if (ain->peer != peer)
4608 continue;
4609
4610 struct bgp_path_info *pi;
4611 uint32_t num_labels = 0;
4612 mpls_label_t *label_pnt = NULL;
4613 struct bgp_route_evpn evpn;
4614
4615 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4616 pi = pi->next)
4617 if (pi->peer == peer)
4618 break;
4619
4620 if (pi && pi->extra)
4621 num_labels = pi->extra->num_labels;
4622 if (num_labels)
4623 label_pnt = &pi->extra->label[0];
4624 if (pi)
4625 memcpy(&evpn,
4626 bgp_attr_get_evpn_overlay(pi->attr),
4627 sizeof(evpn));
4628 else
4629 memset(&evpn, 0, sizeof(evpn));
4630
4631 ret = bgp_update(peer, bgp_dest_get_prefix(dest),
4632 ain->addpath_rx_id, ain->attr, afi,
4633 safi, ZEBRA_ROUTE_BGP,
4634 BGP_ROUTE_NORMAL, prd, label_pnt,
4635 num_labels, 1, &evpn);
4636
4637 if (ret < 0) {
4638 bgp_dest_unlock_node(dest);
4639 return;
4640 }
4641 }
4642 }
4643
4644 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4645 {
4646 struct bgp_dest *dest;
4647 struct bgp_table *table;
4648
4649 if (!peer_established(peer))
4650 return;
4651
4652 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4653 && (safi != SAFI_EVPN))
4654 bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
4655 else
4656 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4657 dest = bgp_route_next(dest)) {
4658 table = bgp_dest_get_bgp_table_info(dest);
4659
4660 if (table == NULL)
4661 continue;
4662
4663 const struct prefix *p = bgp_dest_get_prefix(dest);
4664 struct prefix_rd prd;
4665
4666 prd.family = AF_UNSPEC;
4667 prd.prefixlen = 64;
4668 memcpy(&prd.val, p->u.val, 8);
4669
4670 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
4671 }
4672 }
4673
4674
4675 struct bgp_clear_node_queue {
4676 struct bgp_dest *dest;
4677 };
4678
4679 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4680 {
4681 struct bgp_clear_node_queue *cnq = data;
4682 struct bgp_dest *dest = cnq->dest;
4683 struct peer *peer = wq->spec.data;
4684 struct bgp_path_info *pi;
4685 struct bgp *bgp;
4686 afi_t afi = bgp_dest_table(dest)->afi;
4687 safi_t safi = bgp_dest_table(dest)->safi;
4688
4689 assert(dest && peer);
4690 bgp = peer->bgp;
4691
4692 /* It is possible that we have multiple paths for a prefix from a peer
4693 * if that peer is using AddPath.
4694 */
4695 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
4696 if (pi->peer != peer)
4697 continue;
4698
4699 /* graceful restart STALE flag set. */
4700 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4701 && peer->nsf[afi][safi])
4702 || CHECK_FLAG(peer->af_sflags[afi][safi],
4703 PEER_STATUS_ENHANCED_REFRESH))
4704 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4705 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4706 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
4707 else {
4708 /* If this is an EVPN route, process for
4709 * un-import. */
4710 if (safi == SAFI_EVPN)
4711 bgp_evpn_unimport_route(
4712 bgp, afi, safi,
4713 bgp_dest_get_prefix(dest), pi);
4714 /* Handle withdraw for VRF route-leaking and L3VPN */
4715 if (SAFI_UNICAST == safi
4716 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4717 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4718 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4719 bgp, pi);
4720 }
4721 if (SAFI_MPLS_VPN == safi &&
4722 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4723 vpn_leak_to_vrf_withdraw(bgp, pi);
4724 }
4725
4726 bgp_rib_remove(dest, pi, peer, afi, safi);
4727 }
4728 }
4729 return WQ_SUCCESS;
4730 }
4731
4732 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4733 {
4734 struct bgp_clear_node_queue *cnq = data;
4735 struct bgp_dest *dest = cnq->dest;
4736 struct bgp_table *table = bgp_dest_table(dest);
4737
4738 bgp_dest_unlock_node(dest);
4739 bgp_table_unlock(table);
4740 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4741 }
4742
4743 static void bgp_clear_node_complete(struct work_queue *wq)
4744 {
4745 struct peer *peer = wq->spec.data;
4746
4747 /* Tickle FSM to start moving again */
4748 BGP_EVENT_ADD(peer, Clearing_Completed);
4749
4750 peer_unlock(peer); /* bgp_clear_route */
4751 }
4752
4753 static void bgp_clear_node_queue_init(struct peer *peer)
4754 {
4755 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4756
4757 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4758 #undef CLEAR_QUEUE_NAME_LEN
4759
4760 peer->clear_node_queue = work_queue_new(bm->master, wname);
4761 peer->clear_node_queue->spec.hold = 10;
4762 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4763 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4764 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4765 peer->clear_node_queue->spec.max_retries = 0;
4766
4767 /* we only 'lock' this peer reference when the queue is actually active
4768 */
4769 peer->clear_node_queue->spec.data = peer;
4770 }
4771
4772 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4773 struct bgp_table *table)
4774 {
4775 struct bgp_dest *dest;
4776 int force = peer->bgp->process_queue ? 0 : 1;
4777
4778 if (!table)
4779 table = peer->bgp->rib[afi][safi];
4780
4781 /* If still no table => afi/safi isn't configured at all or smth. */
4782 if (!table)
4783 return;
4784
4785 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4786 struct bgp_path_info *pi, *next;
4787 struct bgp_adj_in *ain;
4788 struct bgp_adj_in *ain_next;
4789
4790 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4791 * queued for every clearing peer, regardless of whether it is
4792 * relevant to the peer at hand.
4793 *
4794 * Overview: There are 3 different indices which need to be
4795 * scrubbed, potentially, when a peer is removed:
4796 *
4797 * 1 peer's routes visible via the RIB (ie accepted routes)
4798 * 2 peer's routes visible by the (optional) peer's adj-in index
4799 * 3 other routes visible by the peer's adj-out index
4800 *
4801 * 3 there is no hurry in scrubbing, once the struct peer is
4802 * removed from bgp->peer, we could just GC such deleted peer's
4803 * adj-outs at our leisure.
4804 *
4805 * 1 and 2 must be 'scrubbed' in some way, at least made
4806 * invisible via RIB index before peer session is allowed to be
4807 * brought back up. So one needs to know when such a 'search' is
4808 * complete.
4809 *
4810 * Ideally:
4811 *
4812 * - there'd be a single global queue or a single RIB walker
4813 * - rather than tracking which route_nodes still need to be
4814 * examined on a peer basis, we'd track which peers still
4815 * aren't cleared
4816 *
4817 * Given that our per-peer prefix-counts now should be reliable,
4818 * this may actually be achievable. It doesn't seem to be a huge
4819 * problem at this time,
4820 *
4821 * It is possible that we have multiple paths for a prefix from
4822 * a peer
4823 * if that peer is using AddPath.
4824 */
4825 ain = dest->adj_in;
4826 while (ain) {
4827 ain_next = ain->next;
4828
4829 if (ain->peer == peer) {
4830 bgp_adj_in_remove(dest, ain);
4831 bgp_dest_unlock_node(dest);
4832 }
4833
4834 ain = ain_next;
4835 }
4836
4837 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
4838 next = pi->next;
4839 if (pi->peer != peer)
4840 continue;
4841
4842 if (force)
4843 bgp_path_info_reap(dest, pi);
4844 else {
4845 struct bgp_clear_node_queue *cnq;
4846
4847 /* both unlocked in bgp_clear_node_queue_del */
4848 bgp_table_lock(bgp_dest_table(dest));
4849 bgp_dest_lock_node(dest);
4850 cnq = XCALLOC(
4851 MTYPE_BGP_CLEAR_NODE_QUEUE,
4852 sizeof(struct bgp_clear_node_queue));
4853 cnq->dest = dest;
4854 work_queue_add(peer->clear_node_queue, cnq);
4855 break;
4856 }
4857 }
4858 }
4859 return;
4860 }
4861
4862 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
4863 {
4864 struct bgp_dest *dest;
4865 struct bgp_table *table;
4866
4867 if (peer->clear_node_queue == NULL)
4868 bgp_clear_node_queue_init(peer);
4869
4870 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
4871 * Idle until it receives a Clearing_Completed event. This protects
4872 * against peers which flap faster than we can we clear, which could
4873 * lead to:
4874 *
4875 * a) race with routes from the new session being installed before
4876 * clear_route_node visits the node (to delete the route of that
4877 * peer)
4878 * b) resource exhaustion, clear_route_node likely leads to an entry
4879 * on the process_main queue. Fast-flapping could cause that queue
4880 * to grow and grow.
4881 */
4882
4883 /* lock peer in assumption that clear-node-queue will get nodes; if so,
4884 * the unlock will happen upon work-queue completion; other wise, the
4885 * unlock happens at the end of this function.
4886 */
4887 if (!peer->clear_node_queue->thread)
4888 peer_lock(peer);
4889
4890 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
4891 bgp_clear_route_table(peer, afi, safi, NULL);
4892 else
4893 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4894 dest = bgp_route_next(dest)) {
4895 table = bgp_dest_get_bgp_table_info(dest);
4896 if (!table)
4897 continue;
4898
4899 bgp_clear_route_table(peer, afi, safi, table);
4900 }
4901
4902 /* unlock if no nodes got added to the clear-node-queue. */
4903 if (!peer->clear_node_queue->thread)
4904 peer_unlock(peer);
4905 }
4906
4907 void bgp_clear_route_all(struct peer *peer)
4908 {
4909 afi_t afi;
4910 safi_t safi;
4911
4912 FOREACH_AFI_SAFI (afi, safi)
4913 bgp_clear_route(peer, afi, safi);
4914
4915 #ifdef ENABLE_BGP_VNC
4916 rfapiProcessPeerDown(peer);
4917 #endif
4918 }
4919
4920 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
4921 {
4922 struct bgp_table *table;
4923 struct bgp_dest *dest;
4924 struct bgp_adj_in *ain;
4925 struct bgp_adj_in *ain_next;
4926
4927 table = peer->bgp->rib[afi][safi];
4928
4929 /* It is possible that we have multiple paths for a prefix from a peer
4930 * if that peer is using AddPath.
4931 */
4932 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4933 ain = dest->adj_in;
4934
4935 while (ain) {
4936 ain_next = ain->next;
4937
4938 if (ain->peer == peer) {
4939 bgp_adj_in_remove(dest, ain);
4940 bgp_dest_unlock_node(dest);
4941 }
4942
4943 ain = ain_next;
4944 }
4945 }
4946 }
4947
4948 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4949 {
4950 struct bgp_dest *dest;
4951 struct bgp_path_info *pi;
4952 struct bgp_table *table;
4953
4954 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
4955 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4956 dest = bgp_route_next(dest)) {
4957 struct bgp_dest *rm;
4958
4959 /* look for neighbor in tables */
4960 table = bgp_dest_get_bgp_table_info(dest);
4961 if (!table)
4962 continue;
4963
4964 for (rm = bgp_table_top(table); rm;
4965 rm = bgp_route_next(rm))
4966 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
4967 pi = pi->next) {
4968 if (pi->peer != peer)
4969 continue;
4970 if (!CHECK_FLAG(pi->flags,
4971 BGP_PATH_STALE))
4972 break;
4973
4974 bgp_rib_remove(rm, pi, peer, afi, safi);
4975 break;
4976 }
4977 }
4978 } else {
4979 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4980 dest = bgp_route_next(dest))
4981 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
4982 pi = pi->next) {
4983 if (pi->peer != peer)
4984 continue;
4985 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
4986 break;
4987 bgp_rib_remove(dest, pi, peer, afi, safi);
4988 break;
4989 }
4990 }
4991 }
4992
4993 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
4994 {
4995 struct bgp_dest *dest, *ndest;
4996 struct bgp_path_info *pi;
4997 struct bgp_table *table;
4998
4999 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5000 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5001 dest = bgp_route_next(dest)) {
5002 table = bgp_dest_get_bgp_table_info(dest);
5003 if (!table)
5004 continue;
5005
5006 for (ndest = bgp_table_top(table); ndest;
5007 ndest = bgp_route_next(ndest)) {
5008 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5009 pi = pi->next) {
5010 if (pi->peer != peer)
5011 continue;
5012
5013 if ((CHECK_FLAG(
5014 peer->af_sflags[afi][safi],
5015 PEER_STATUS_ENHANCED_REFRESH))
5016 && !CHECK_FLAG(pi->flags,
5017 BGP_PATH_STALE)
5018 && !CHECK_FLAG(
5019 pi->flags,
5020 BGP_PATH_UNUSEABLE)) {
5021 if (bgp_debug_neighbor_events(
5022 peer))
5023 zlog_debug(
5024 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5025 peer->host,
5026 afi2str(afi),
5027 safi2str(safi),
5028 bgp_dest_get_prefix(
5029 ndest));
5030
5031 bgp_path_info_set_flag(
5032 ndest, pi,
5033 BGP_PATH_STALE);
5034 }
5035 }
5036 }
5037 }
5038 } else {
5039 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5040 dest = bgp_route_next(dest)) {
5041 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5042 pi = pi->next) {
5043 if (pi->peer != peer)
5044 continue;
5045
5046 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5047 PEER_STATUS_ENHANCED_REFRESH))
5048 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5049 && !CHECK_FLAG(pi->flags,
5050 BGP_PATH_UNUSEABLE)) {
5051 if (bgp_debug_neighbor_events(peer))
5052 zlog_debug(
5053 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5054 peer->host,
5055 afi2str(afi),
5056 safi2str(safi),
5057 bgp_dest_get_prefix(
5058 dest));
5059
5060 bgp_path_info_set_flag(dest, pi,
5061 BGP_PATH_STALE);
5062 }
5063 }
5064 }
5065 }
5066 }
5067
5068 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5069 {
5070 if (peer->sort == BGP_PEER_IBGP)
5071 return true;
5072
5073 if (peer->sort == BGP_PEER_EBGP
5074 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5075 || FILTER_LIST_OUT_NAME(filter)
5076 || DISTRIBUTE_OUT_NAME(filter)))
5077 return true;
5078 return false;
5079 }
5080
5081 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5082 {
5083 if (peer->sort == BGP_PEER_IBGP)
5084 return true;
5085
5086 if (peer->sort == BGP_PEER_EBGP
5087 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5088 || FILTER_LIST_IN_NAME(filter)
5089 || DISTRIBUTE_IN_NAME(filter)))
5090 return true;
5091 return false;
5092 }
5093
5094 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5095 safi_t safi)
5096 {
5097 struct bgp_dest *dest;
5098 struct bgp_path_info *pi;
5099 struct bgp_path_info *next;
5100
5101 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5102 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5103 const struct prefix *p = bgp_dest_get_prefix(dest);
5104
5105 next = pi->next;
5106
5107 /* Unimport EVPN routes from VRFs */
5108 if (safi == SAFI_EVPN)
5109 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5110 SAFI_EVPN, p, pi);
5111
5112 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5113 && pi->type == ZEBRA_ROUTE_BGP
5114 && (pi->sub_type == BGP_ROUTE_NORMAL
5115 || pi->sub_type == BGP_ROUTE_AGGREGATE
5116 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5117
5118 if (bgp_fibupd_safi(safi))
5119 bgp_zebra_withdraw(p, pi, bgp, safi);
5120 }
5121
5122 bgp_path_info_reap(dest, pi);
5123 }
5124 }
5125
5126 /* Delete all kernel routes. */
5127 void bgp_cleanup_routes(struct bgp *bgp)
5128 {
5129 afi_t afi;
5130 struct bgp_dest *dest;
5131 struct bgp_table *table;
5132
5133 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5134 if (afi == AFI_L2VPN)
5135 continue;
5136 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5137 SAFI_UNICAST);
5138 /*
5139 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5140 */
5141 if (afi != AFI_L2VPN) {
5142 safi_t safi;
5143 safi = SAFI_MPLS_VPN;
5144 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5145 dest = bgp_route_next(dest)) {
5146 table = bgp_dest_get_bgp_table_info(dest);
5147 if (table != NULL) {
5148 bgp_cleanup_table(bgp, table, safi);
5149 bgp_table_finish(&table);
5150 bgp_dest_set_bgp_table_info(dest, NULL);
5151 bgp_dest_unlock_node(dest);
5152 }
5153 }
5154 safi = SAFI_ENCAP;
5155 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5156 dest = bgp_route_next(dest)) {
5157 table = bgp_dest_get_bgp_table_info(dest);
5158 if (table != NULL) {
5159 bgp_cleanup_table(bgp, table, safi);
5160 bgp_table_finish(&table);
5161 bgp_dest_set_bgp_table_info(dest, NULL);
5162 bgp_dest_unlock_node(dest);
5163 }
5164 }
5165 }
5166 }
5167 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5168 dest = bgp_route_next(dest)) {
5169 table = bgp_dest_get_bgp_table_info(dest);
5170 if (table != NULL) {
5171 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5172 bgp_table_finish(&table);
5173 bgp_dest_set_bgp_table_info(dest, NULL);
5174 bgp_dest_unlock_node(dest);
5175 }
5176 }
5177 }
5178
5179 void bgp_reset(void)
5180 {
5181 vty_reset();
5182 bgp_zclient_reset();
5183 access_list_reset();
5184 prefix_list_reset();
5185 }
5186
5187 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5188 {
5189 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5190 && CHECK_FLAG(peer->af_cap[afi][safi],
5191 PEER_CAP_ADDPATH_AF_TX_RCV));
5192 }
5193
5194 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5195 value. */
5196 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5197 struct bgp_nlri *packet)
5198 {
5199 uint8_t *pnt;
5200 uint8_t *lim;
5201 struct prefix p;
5202 int psize;
5203 int ret;
5204 afi_t afi;
5205 safi_t safi;
5206 int addpath_encoded;
5207 uint32_t addpath_id;
5208
5209 pnt = packet->nlri;
5210 lim = pnt + packet->length;
5211 afi = packet->afi;
5212 safi = packet->safi;
5213 addpath_id = 0;
5214 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
5215
5216 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5217 syntactic validity. If the field is syntactically incorrect,
5218 then the Error Subcode is set to Invalid Network Field. */
5219 for (; pnt < lim; pnt += psize) {
5220 /* Clear prefix structure. */
5221 memset(&p, 0, sizeof(struct prefix));
5222
5223 if (addpath_encoded) {
5224
5225 /* When packet overflow occurs return immediately. */
5226 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5227 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5228
5229 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5230 addpath_id = ntohl(addpath_id);
5231 pnt += BGP_ADDPATH_ID_LEN;
5232 }
5233
5234 /* Fetch prefix length. */
5235 p.prefixlen = *pnt++;
5236 /* afi/safi validity already verified by caller,
5237 * bgp_update_receive */
5238 p.family = afi2family(afi);
5239
5240 /* Prefix length check. */
5241 if (p.prefixlen > prefix_blen(&p) * 8) {
5242 flog_err(
5243 EC_BGP_UPDATE_RCV,
5244 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5245 peer->host, p.prefixlen, packet->afi);
5246 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5247 }
5248
5249 /* Packet size overflow check. */
5250 psize = PSIZE(p.prefixlen);
5251
5252 /* When packet overflow occur return immediately. */
5253 if (pnt + psize > lim) {
5254 flog_err(
5255 EC_BGP_UPDATE_RCV,
5256 "%s [Error] Update packet error (prefix length %d overflows packet)",
5257 peer->host, p.prefixlen);
5258 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5259 }
5260
5261 /* Defensive coding, double-check the psize fits in a struct
5262 * prefix */
5263 if (psize > (ssize_t)sizeof(p.u)) {
5264 flog_err(
5265 EC_BGP_UPDATE_RCV,
5266 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5267 peer->host, p.prefixlen, sizeof(p.u));
5268 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5269 }
5270
5271 /* Fetch prefix from NLRI packet. */
5272 memcpy(p.u.val, pnt, psize);
5273
5274 /* Check address. */
5275 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5276 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5277 /* From RFC4271 Section 6.3:
5278 *
5279 * If a prefix in the NLRI field is semantically
5280 * incorrect
5281 * (e.g., an unexpected multicast IP address),
5282 * an error SHOULD
5283 * be logged locally, and the prefix SHOULD be
5284 * ignored.
5285 */
5286 flog_err(
5287 EC_BGP_UPDATE_RCV,
5288 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5289 peer->host, &p.u.prefix4);
5290 continue;
5291 }
5292 }
5293
5294 /* Check address. */
5295 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5296 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5297 flog_err(
5298 EC_BGP_UPDATE_RCV,
5299 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
5300 peer->host, &p.u.prefix6);
5301
5302 continue;
5303 }
5304 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5305 flog_err(
5306 EC_BGP_UPDATE_RCV,
5307 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
5308 peer->host, &p.u.prefix6);
5309
5310 continue;
5311 }
5312 }
5313
5314 /* Normal process. */
5315 if (attr)
5316 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5317 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5318 NULL, NULL, 0, 0, NULL);
5319 else
5320 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5321 safi, ZEBRA_ROUTE_BGP,
5322 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5323 NULL);
5324
5325 /* Do not send BGP notification twice when maximum-prefix count
5326 * overflow. */
5327 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5328 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5329
5330 /* Address family configuration mismatch. */
5331 if (ret < 0)
5332 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5333 }
5334
5335 /* Packet length consistency check. */
5336 if (pnt != lim) {
5337 flog_err(
5338 EC_BGP_UPDATE_RCV,
5339 "%s [Error] Update packet error (prefix length mismatch with total length)",
5340 peer->host);
5341 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5342 }
5343
5344 return BGP_NLRI_PARSE_OK;
5345 }
5346
5347 static struct bgp_static *bgp_static_new(void)
5348 {
5349 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5350 }
5351
5352 static void bgp_static_free(struct bgp_static *bgp_static)
5353 {
5354 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5355 route_map_counter_decrement(bgp_static->rmap.map);
5356
5357 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5358 XFREE(MTYPE_BGP_STATIC, bgp_static);
5359 }
5360
5361 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5362 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5363 {
5364 struct bgp_dest *dest;
5365 struct bgp_path_info *pi;
5366 struct bgp_path_info *new;
5367 struct bgp_path_info rmap_path;
5368 struct attr attr;
5369 struct attr *attr_new;
5370 route_map_result_t ret;
5371 #ifdef ENABLE_BGP_VNC
5372 int vnc_implicit_withdraw = 0;
5373 #endif
5374
5375 assert(bgp_static);
5376
5377 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5378
5379 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5380
5381 attr.nexthop = bgp_static->igpnexthop;
5382 attr.med = bgp_static->igpmetric;
5383 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5384
5385 if (bgp_static->atomic)
5386 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5387
5388 /* Store label index, if required. */
5389 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5390 attr.label_index = bgp_static->label_index;
5391 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5392 }
5393
5394 /* Apply route-map. */
5395 if (bgp_static->rmap.name) {
5396 struct attr attr_tmp = attr;
5397
5398 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5399 rmap_path.peer = bgp->peer_self;
5400 rmap_path.attr = &attr_tmp;
5401
5402 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5403
5404 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5405
5406 bgp->peer_self->rmap_type = 0;
5407
5408 if (ret == RMAP_DENYMATCH) {
5409 /* Free uninterned attribute. */
5410 bgp_attr_flush(&attr_tmp);
5411
5412 /* Unintern original. */
5413 aspath_unintern(&attr.aspath);
5414 bgp_static_withdraw(bgp, p, afi, safi);
5415 return;
5416 }
5417
5418 if (bgp_in_graceful_shutdown(bgp))
5419 bgp_attr_add_gshut_community(&attr_tmp);
5420
5421 attr_new = bgp_attr_intern(&attr_tmp);
5422 } else {
5423
5424 if (bgp_in_graceful_shutdown(bgp))
5425 bgp_attr_add_gshut_community(&attr);
5426
5427 attr_new = bgp_attr_intern(&attr);
5428 }
5429
5430 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5431 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5432 && pi->sub_type == BGP_ROUTE_STATIC)
5433 break;
5434
5435 if (pi) {
5436 if (attrhash_cmp(pi->attr, attr_new)
5437 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5438 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5439 bgp_dest_unlock_node(dest);
5440 bgp_attr_unintern(&attr_new);
5441 aspath_unintern(&attr.aspath);
5442 return;
5443 } else {
5444 /* The attribute is changed. */
5445 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5446
5447 /* Rewrite BGP route information. */
5448 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5449 bgp_path_info_restore(dest, pi);
5450 else
5451 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5452 #ifdef ENABLE_BGP_VNC
5453 if ((afi == AFI_IP || afi == AFI_IP6)
5454 && (safi == SAFI_UNICAST)) {
5455 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5456 /*
5457 * Implicit withdraw case.
5458 * We have to do this before pi is
5459 * changed
5460 */
5461 ++vnc_implicit_withdraw;
5462 vnc_import_bgp_del_route(bgp, p, pi);
5463 vnc_import_bgp_exterior_del_route(
5464 bgp, p, pi);
5465 }
5466 }
5467 #endif
5468 bgp_attr_unintern(&pi->attr);
5469 pi->attr = attr_new;
5470 pi->uptime = bgp_clock();
5471 #ifdef ENABLE_BGP_VNC
5472 if ((afi == AFI_IP || afi == AFI_IP6)
5473 && (safi == SAFI_UNICAST)) {
5474 if (vnc_implicit_withdraw) {
5475 vnc_import_bgp_add_route(bgp, p, pi);
5476 vnc_import_bgp_exterior_add_route(
5477 bgp, p, pi);
5478 }
5479 }
5480 #endif
5481
5482 /* Nexthop reachability check. */
5483 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5484 && (safi == SAFI_UNICAST
5485 || safi == SAFI_LABELED_UNICAST)) {
5486
5487 struct bgp *bgp_nexthop = bgp;
5488
5489 if (pi->extra && pi->extra->bgp_orig)
5490 bgp_nexthop = pi->extra->bgp_orig;
5491
5492 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5493 afi, safi, pi, NULL,
5494 0))
5495 bgp_path_info_set_flag(dest, pi,
5496 BGP_PATH_VALID);
5497 else {
5498 if (BGP_DEBUG(nht, NHT)) {
5499 char buf1[INET6_ADDRSTRLEN];
5500 inet_ntop(p->family,
5501 &p->u.prefix, buf1,
5502 INET6_ADDRSTRLEN);
5503 zlog_debug(
5504 "%s(%s): Route not in table, not advertising",
5505 __func__, buf1);
5506 }
5507 bgp_path_info_unset_flag(
5508 dest, pi, BGP_PATH_VALID);
5509 }
5510 } else {
5511 /* Delete the NHT structure if any, if we're
5512 * toggling between
5513 * enabling/disabling import check. We
5514 * deregister the route
5515 * from NHT to avoid overloading NHT and the
5516 * process interaction
5517 */
5518 bgp_unlink_nexthop(pi);
5519 bgp_path_info_set_flag(dest, pi,
5520 BGP_PATH_VALID);
5521 }
5522 /* Process change. */
5523 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5524 bgp_process(bgp, dest, afi, safi);
5525
5526 if (SAFI_UNICAST == safi
5527 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5528 || bgp->inst_type
5529 == BGP_INSTANCE_TYPE_DEFAULT)) {
5530 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5531 pi);
5532 }
5533
5534 bgp_dest_unlock_node(dest);
5535 aspath_unintern(&attr.aspath);
5536 return;
5537 }
5538 }
5539
5540 /* Make new BGP info. */
5541 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5542 attr_new, dest);
5543 /* Nexthop reachability check. */
5544 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5545 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5546 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0))
5547 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5548 else {
5549 if (BGP_DEBUG(nht, NHT)) {
5550 char buf1[INET6_ADDRSTRLEN];
5551 inet_ntop(p->family, &p->u.prefix, buf1,
5552 INET6_ADDRSTRLEN);
5553 zlog_debug(
5554 "%s(%s): Route not in table, not advertising",
5555 __func__, buf1);
5556 }
5557 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5558 }
5559 } else {
5560 /* Delete the NHT structure if any, if we're toggling between
5561 * enabling/disabling import check. We deregister the route
5562 * from NHT to avoid overloading NHT and the process interaction
5563 */
5564 bgp_unlink_nexthop(new);
5565
5566 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5567 }
5568
5569 /* Aggregate address increment. */
5570 bgp_aggregate_increment(bgp, p, new, afi, safi);
5571
5572 /* Register new BGP information. */
5573 bgp_path_info_add(dest, new);
5574
5575 /* route_node_get lock */
5576 bgp_dest_unlock_node(dest);
5577
5578 /* Process change. */
5579 bgp_process(bgp, dest, afi, safi);
5580
5581 if (SAFI_UNICAST == safi
5582 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5583 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5584 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5585 }
5586
5587 /* Unintern original. */
5588 aspath_unintern(&attr.aspath);
5589 }
5590
5591 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
5592 safi_t safi)
5593 {
5594 struct bgp_dest *dest;
5595 struct bgp_path_info *pi;
5596
5597 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5598
5599 /* Check selected route and self inserted route. */
5600 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5601 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5602 && pi->sub_type == BGP_ROUTE_STATIC)
5603 break;
5604
5605 /* Withdraw static BGP route from routing table. */
5606 if (pi) {
5607 if (SAFI_UNICAST == safi
5608 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5609 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5610 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5611 }
5612 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5613 bgp_unlink_nexthop(pi);
5614 bgp_path_info_delete(dest, pi);
5615 bgp_process(bgp, dest, afi, safi);
5616 }
5617
5618 /* Unlock bgp_node_lookup. */
5619 bgp_dest_unlock_node(dest);
5620 }
5621
5622 /*
5623 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5624 */
5625 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
5626 afi_t afi, safi_t safi,
5627 struct prefix_rd *prd)
5628 {
5629 struct bgp_dest *dest;
5630 struct bgp_path_info *pi;
5631
5632 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5633
5634 /* Check selected route and self inserted route. */
5635 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5636 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5637 && pi->sub_type == BGP_ROUTE_STATIC)
5638 break;
5639
5640 /* Withdraw static BGP route from routing table. */
5641 if (pi) {
5642 #ifdef ENABLE_BGP_VNC
5643 rfapiProcessWithdraw(
5644 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5645 1); /* Kill, since it is an administrative change */
5646 #endif
5647 if (SAFI_MPLS_VPN == safi
5648 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5649 vpn_leak_to_vrf_withdraw(bgp, pi);
5650 }
5651 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5652 bgp_path_info_delete(dest, pi);
5653 bgp_process(bgp, dest, afi, safi);
5654 }
5655
5656 /* Unlock bgp_node_lookup. */
5657 bgp_dest_unlock_node(dest);
5658 }
5659
5660 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
5661 struct bgp_static *bgp_static, afi_t afi,
5662 safi_t safi)
5663 {
5664 struct bgp_dest *dest;
5665 struct bgp_path_info *new;
5666 struct attr *attr_new;
5667 struct attr attr = {0};
5668 struct bgp_path_info *pi;
5669 #ifdef ENABLE_BGP_VNC
5670 mpls_label_t label = 0;
5671 #endif
5672 uint32_t num_labels = 0;
5673 union gw_addr add;
5674
5675 assert(bgp_static);
5676
5677 if (bgp_static->label != MPLS_INVALID_LABEL)
5678 num_labels = 1;
5679 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5680 &bgp_static->prd);
5681
5682 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5683
5684 attr.nexthop = bgp_static->igpnexthop;
5685 attr.med = bgp_static->igpmetric;
5686 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5687
5688 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5689 || (safi == SAFI_ENCAP)) {
5690 if (afi == AFI_IP) {
5691 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5692 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5693 }
5694 }
5695 if (afi == AFI_L2VPN) {
5696 if (bgp_static->gatewayIp.family == AF_INET)
5697 add.ipv4.s_addr =
5698 bgp_static->gatewayIp.u.prefix4.s_addr;
5699 else if (bgp_static->gatewayIp.family == AF_INET6)
5700 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5701 sizeof(struct in6_addr));
5702 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
5703 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5704 struct bgp_encap_type_vxlan bet;
5705 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5706 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5707 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5708 }
5709 if (bgp_static->router_mac) {
5710 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5711 }
5712 }
5713 /* Apply route-map. */
5714 if (bgp_static->rmap.name) {
5715 struct attr attr_tmp = attr;
5716 struct bgp_path_info rmap_path;
5717 route_map_result_t ret;
5718
5719 rmap_path.peer = bgp->peer_self;
5720 rmap_path.attr = &attr_tmp;
5721
5722 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5723
5724 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5725
5726 bgp->peer_self->rmap_type = 0;
5727
5728 if (ret == RMAP_DENYMATCH) {
5729 /* Free uninterned attribute. */
5730 bgp_attr_flush(&attr_tmp);
5731
5732 /* Unintern original. */
5733 aspath_unintern(&attr.aspath);
5734 bgp_static_withdraw_safi(bgp, p, afi, safi,
5735 &bgp_static->prd);
5736 return;
5737 }
5738
5739 attr_new = bgp_attr_intern(&attr_tmp);
5740 } else {
5741 attr_new = bgp_attr_intern(&attr);
5742 }
5743
5744 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5745 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5746 && pi->sub_type == BGP_ROUTE_STATIC)
5747 break;
5748
5749 if (pi) {
5750 memset(&add, 0, sizeof(union gw_addr));
5751 if (attrhash_cmp(pi->attr, attr_new)
5752 && overlay_index_equal(afi, pi, &add)
5753 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5754 bgp_dest_unlock_node(dest);
5755 bgp_attr_unintern(&attr_new);
5756 aspath_unintern(&attr.aspath);
5757 return;
5758 } else {
5759 /* The attribute is changed. */
5760 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5761
5762 /* Rewrite BGP route information. */
5763 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5764 bgp_path_info_restore(dest, pi);
5765 else
5766 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5767 bgp_attr_unintern(&pi->attr);
5768 pi->attr = attr_new;
5769 pi->uptime = bgp_clock();
5770 #ifdef ENABLE_BGP_VNC
5771 if (pi->extra)
5772 label = decode_label(&pi->extra->label[0]);
5773 #endif
5774
5775 /* Process change. */
5776 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5777 bgp_process(bgp, dest, afi, safi);
5778
5779 if (SAFI_MPLS_VPN == safi
5780 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5781 vpn_leak_to_vrf_update(bgp, pi);
5782 }
5783 #ifdef ENABLE_BGP_VNC
5784 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5785 pi->attr, afi, safi, pi->type,
5786 pi->sub_type, &label);
5787 #endif
5788 bgp_dest_unlock_node(dest);
5789 aspath_unintern(&attr.aspath);
5790 return;
5791 }
5792 }
5793
5794
5795 /* Make new BGP info. */
5796 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5797 attr_new, dest);
5798 SET_FLAG(new->flags, BGP_PATH_VALID);
5799 new->extra = bgp_path_info_extra_new();
5800 if (num_labels) {
5801 new->extra->label[0] = bgp_static->label;
5802 new->extra->num_labels = num_labels;
5803 }
5804 #ifdef ENABLE_BGP_VNC
5805 label = decode_label(&bgp_static->label);
5806 #endif
5807
5808 /* Aggregate address increment. */
5809 bgp_aggregate_increment(bgp, p, new, afi, safi);
5810
5811 /* Register new BGP information. */
5812 bgp_path_info_add(dest, new);
5813 /* route_node_get lock */
5814 bgp_dest_unlock_node(dest);
5815
5816 /* Process change. */
5817 bgp_process(bgp, dest, afi, safi);
5818
5819 if (SAFI_MPLS_VPN == safi
5820 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5821 vpn_leak_to_vrf_update(bgp, new);
5822 }
5823 #ifdef ENABLE_BGP_VNC
5824 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
5825 safi, new->type, new->sub_type, &label);
5826 #endif
5827
5828 /* Unintern original. */
5829 aspath_unintern(&attr.aspath);
5830 }
5831
5832 /* Configure static BGP network. When user don't run zebra, static
5833 route should be installed as valid. */
5834 int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
5835 afi_t afi, safi_t safi, const char *rmap, int backdoor,
5836 uint32_t label_index, char *errmsg, size_t errmsg_len)
5837 {
5838 struct prefix p;
5839 struct bgp_static *bgp_static;
5840 struct bgp_dest *dest;
5841 uint8_t need_update = 0;
5842
5843 prefix_copy(&p, pfx);
5844 apply_mask(&p);
5845
5846 if (negate) {
5847
5848 /* Set BGP static route configuration. */
5849 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
5850
5851 if (!dest) {
5852 snprintf(errmsg, errmsg_len,
5853 "Can't find static route specified\n");
5854 return -1;
5855 }
5856
5857 bgp_static = bgp_dest_get_bgp_static_info(dest);
5858
5859 if ((label_index != BGP_INVALID_LABEL_INDEX)
5860 && (label_index != bgp_static->label_index)) {
5861 snprintf(errmsg, errmsg_len,
5862 "label-index doesn't match static route\n");
5863 return -1;
5864 }
5865
5866 if ((rmap && bgp_static->rmap.name)
5867 && strcmp(rmap, bgp_static->rmap.name)) {
5868 snprintf(errmsg, errmsg_len,
5869 "route-map name doesn't match static route\n");
5870 return -1;
5871 }
5872
5873 /* Update BGP RIB. */
5874 if (!bgp_static->backdoor)
5875 bgp_static_withdraw(bgp, &p, afi, safi);
5876
5877 /* Clear configuration. */
5878 bgp_static_free(bgp_static);
5879 bgp_dest_set_bgp_static_info(dest, NULL);
5880 bgp_dest_unlock_node(dest);
5881 bgp_dest_unlock_node(dest);
5882 } else {
5883
5884 /* Set BGP static route configuration. */
5885 dest = bgp_node_get(bgp->route[afi][safi], &p);
5886 bgp_static = bgp_dest_get_bgp_static_info(dest);
5887 if (bgp_static) {
5888 /* Configuration change. */
5889 /* Label index cannot be changed. */
5890 if (bgp_static->label_index != label_index) {
5891 snprintf(errmsg, errmsg_len,
5892 "cannot change label-index\n");
5893 return -1;
5894 }
5895
5896 /* Check previous routes are installed into BGP. */
5897 if (bgp_static->valid
5898 && bgp_static->backdoor != backdoor)
5899 need_update = 1;
5900
5901 bgp_static->backdoor = backdoor;
5902
5903 if (rmap) {
5904 XFREE(MTYPE_ROUTE_MAP_NAME,
5905 bgp_static->rmap.name);
5906 route_map_counter_decrement(
5907 bgp_static->rmap.map);
5908 bgp_static->rmap.name =
5909 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5910 bgp_static->rmap.map =
5911 route_map_lookup_by_name(rmap);
5912 route_map_counter_increment(
5913 bgp_static->rmap.map);
5914 } else {
5915 XFREE(MTYPE_ROUTE_MAP_NAME,
5916 bgp_static->rmap.name);
5917 route_map_counter_decrement(
5918 bgp_static->rmap.map);
5919 bgp_static->rmap.map = NULL;
5920 bgp_static->valid = 0;
5921 }
5922 bgp_dest_unlock_node(dest);
5923 } else {
5924 /* New configuration. */
5925 bgp_static = bgp_static_new();
5926 bgp_static->backdoor = backdoor;
5927 bgp_static->valid = 0;
5928 bgp_static->igpmetric = 0;
5929 bgp_static->igpnexthop.s_addr = INADDR_ANY;
5930 bgp_static->label_index = label_index;
5931
5932 if (rmap) {
5933 XFREE(MTYPE_ROUTE_MAP_NAME,
5934 bgp_static->rmap.name);
5935 route_map_counter_decrement(
5936 bgp_static->rmap.map);
5937 bgp_static->rmap.name =
5938 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
5939 bgp_static->rmap.map =
5940 route_map_lookup_by_name(rmap);
5941 route_map_counter_increment(
5942 bgp_static->rmap.map);
5943 }
5944 bgp_dest_set_bgp_static_info(dest, bgp_static);
5945 }
5946
5947 bgp_static->valid = 1;
5948 if (need_update)
5949 bgp_static_withdraw(bgp, &p, afi, safi);
5950
5951 if (!bgp_static->backdoor)
5952 bgp_static_update(bgp, &p, bgp_static, afi, safi);
5953 }
5954
5955 return 0;
5956 }
5957
5958 void bgp_static_add(struct bgp *bgp)
5959 {
5960 afi_t afi;
5961 safi_t safi;
5962 struct bgp_dest *dest;
5963 struct bgp_dest *rm;
5964 struct bgp_table *table;
5965 struct bgp_static *bgp_static;
5966
5967 FOREACH_AFI_SAFI (afi, safi)
5968 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
5969 dest = bgp_route_next(dest)) {
5970 if (!bgp_dest_has_bgp_path_info_data(dest))
5971 continue;
5972
5973 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
5974 || (safi == SAFI_EVPN)) {
5975 table = bgp_dest_get_bgp_table_info(dest);
5976
5977 for (rm = bgp_table_top(table); rm;
5978 rm = bgp_route_next(rm)) {
5979 bgp_static =
5980 bgp_dest_get_bgp_static_info(
5981 rm);
5982 bgp_static_update_safi(
5983 bgp, bgp_dest_get_prefix(rm),
5984 bgp_static, afi, safi);
5985 }
5986 } else {
5987 bgp_static_update(
5988 bgp, bgp_dest_get_prefix(dest),
5989 bgp_dest_get_bgp_static_info(dest), afi,
5990 safi);
5991 }
5992 }
5993 }
5994
5995 /* Called from bgp_delete(). Delete all static routes from the BGP
5996 instance. */
5997 void bgp_static_delete(struct bgp *bgp)
5998 {
5999 afi_t afi;
6000 safi_t safi;
6001 struct bgp_dest *dest;
6002 struct bgp_dest *rm;
6003 struct bgp_table *table;
6004 struct bgp_static *bgp_static;
6005
6006 FOREACH_AFI_SAFI (afi, safi)
6007 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6008 dest = bgp_route_next(dest)) {
6009 if (!bgp_dest_has_bgp_path_info_data(dest))
6010 continue;
6011
6012 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6013 || (safi == SAFI_EVPN)) {
6014 table = bgp_dest_get_bgp_table_info(dest);
6015
6016 for (rm = bgp_table_top(table); rm;
6017 rm = bgp_route_next(rm)) {
6018 bgp_static =
6019 bgp_dest_get_bgp_static_info(
6020 rm);
6021 if (!bgp_static)
6022 continue;
6023
6024 bgp_static_withdraw_safi(
6025 bgp, bgp_dest_get_prefix(rm),
6026 AFI_IP, safi,
6027 (struct prefix_rd *)
6028 bgp_dest_get_prefix(
6029 dest));
6030 bgp_static_free(bgp_static);
6031 bgp_dest_set_bgp_static_info(rm,
6032 NULL);
6033 bgp_dest_unlock_node(rm);
6034 }
6035 } else {
6036 bgp_static = bgp_dest_get_bgp_static_info(dest);
6037 bgp_static_withdraw(bgp,
6038 bgp_dest_get_prefix(dest),
6039 afi, safi);
6040 bgp_static_free(bgp_static);
6041 bgp_dest_set_bgp_static_info(dest, NULL);
6042 bgp_dest_unlock_node(dest);
6043 }
6044 }
6045 }
6046
6047 void bgp_static_redo_import_check(struct bgp *bgp)
6048 {
6049 afi_t afi;
6050 safi_t safi;
6051 struct bgp_dest *dest;
6052 struct bgp_dest *rm;
6053 struct bgp_table *table;
6054 struct bgp_static *bgp_static;
6055
6056 /* Use this flag to force reprocessing of the route */
6057 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6058 FOREACH_AFI_SAFI (afi, safi) {
6059 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6060 dest = bgp_route_next(dest)) {
6061 if (!bgp_dest_has_bgp_path_info_data(dest))
6062 continue;
6063
6064 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6065 || (safi == SAFI_EVPN)) {
6066 table = bgp_dest_get_bgp_table_info(dest);
6067
6068 for (rm = bgp_table_top(table); rm;
6069 rm = bgp_route_next(rm)) {
6070 bgp_static =
6071 bgp_dest_get_bgp_static_info(
6072 rm);
6073 bgp_static_update_safi(
6074 bgp, bgp_dest_get_prefix(rm),
6075 bgp_static, afi, safi);
6076 }
6077 } else {
6078 bgp_static = bgp_dest_get_bgp_static_info(dest);
6079 bgp_static_update(bgp,
6080 bgp_dest_get_prefix(dest),
6081 bgp_static, afi, safi);
6082 }
6083 }
6084 }
6085 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6086 }
6087
6088 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6089 safi_t safi)
6090 {
6091 struct bgp_table *table;
6092 struct bgp_dest *dest;
6093 struct bgp_path_info *pi;
6094
6095 /* Do not install the aggregate route if BGP is in the
6096 * process of termination.
6097 */
6098 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6099 || (bgp->peer_self == NULL))
6100 return;
6101
6102 table = bgp->rib[afi][safi];
6103 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6104 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6105 if (pi->peer == bgp->peer_self
6106 && ((pi->type == ZEBRA_ROUTE_BGP
6107 && pi->sub_type == BGP_ROUTE_STATIC)
6108 || (pi->type != ZEBRA_ROUTE_BGP
6109 && pi->sub_type
6110 == BGP_ROUTE_REDISTRIBUTE))) {
6111 bgp_aggregate_decrement(
6112 bgp, bgp_dest_get_prefix(dest), pi, afi,
6113 safi);
6114 bgp_unlink_nexthop(pi);
6115 bgp_path_info_delete(dest, pi);
6116 bgp_process(bgp, dest, afi, safi);
6117 }
6118 }
6119 }
6120 }
6121
6122 /*
6123 * Purge all networks and redistributed routes from routing table.
6124 * Invoked upon the instance going down.
6125 */
6126 void bgp_purge_static_redist_routes(struct bgp *bgp)
6127 {
6128 afi_t afi;
6129 safi_t safi;
6130
6131 FOREACH_AFI_SAFI (afi, safi)
6132 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6133 }
6134
6135 /*
6136 * gpz 110624
6137 * Currently this is used to set static routes for VPN and ENCAP.
6138 * I think it can probably be factored with bgp_static_set.
6139 */
6140 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6141 const char *ip_str, const char *rd_str,
6142 const char *label_str, const char *rmap_str,
6143 int evpn_type, const char *esi, const char *gwip,
6144 const char *ethtag, const char *routermac)
6145 {
6146 VTY_DECLVAR_CONTEXT(bgp, bgp);
6147 int ret;
6148 struct prefix p;
6149 struct prefix_rd prd;
6150 struct bgp_dest *pdest;
6151 struct bgp_dest *dest;
6152 struct bgp_table *table;
6153 struct bgp_static *bgp_static;
6154 mpls_label_t label = MPLS_INVALID_LABEL;
6155 struct prefix gw_ip;
6156
6157 /* validate ip prefix */
6158 ret = str2prefix(ip_str, &p);
6159 if (!ret) {
6160 vty_out(vty, "%% Malformed prefix\n");
6161 return CMD_WARNING_CONFIG_FAILED;
6162 }
6163 apply_mask(&p);
6164 if ((afi == AFI_L2VPN)
6165 && (bgp_build_evpn_prefix(evpn_type,
6166 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6167 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6168 return CMD_WARNING_CONFIG_FAILED;
6169 }
6170
6171 ret = str2prefix_rd(rd_str, &prd);
6172 if (!ret) {
6173 vty_out(vty, "%% Malformed rd\n");
6174 return CMD_WARNING_CONFIG_FAILED;
6175 }
6176
6177 if (label_str) {
6178 unsigned long label_val;
6179 label_val = strtoul(label_str, NULL, 10);
6180 encode_label(label_val, &label);
6181 }
6182
6183 if (safi == SAFI_EVPN) {
6184 if (esi && str2esi(esi, NULL) == 0) {
6185 vty_out(vty, "%% Malformed ESI\n");
6186 return CMD_WARNING_CONFIG_FAILED;
6187 }
6188 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6189 vty_out(vty, "%% Malformed Router MAC\n");
6190 return CMD_WARNING_CONFIG_FAILED;
6191 }
6192 if (gwip) {
6193 memset(&gw_ip, 0, sizeof(struct prefix));
6194 ret = str2prefix(gwip, &gw_ip);
6195 if (!ret) {
6196 vty_out(vty, "%% Malformed GatewayIp\n");
6197 return CMD_WARNING_CONFIG_FAILED;
6198 }
6199 if ((gw_ip.family == AF_INET
6200 && is_evpn_prefix_ipaddr_v6(
6201 (struct prefix_evpn *)&p))
6202 || (gw_ip.family == AF_INET6
6203 && is_evpn_prefix_ipaddr_v4(
6204 (struct prefix_evpn *)&p))) {
6205 vty_out(vty,
6206 "%% GatewayIp family differs with IP prefix\n");
6207 return CMD_WARNING_CONFIG_FAILED;
6208 }
6209 }
6210 }
6211 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6212 if (!bgp_dest_has_bgp_path_info_data(pdest))
6213 bgp_dest_set_bgp_table_info(pdest,
6214 bgp_table_init(bgp, afi, safi));
6215 table = bgp_dest_get_bgp_table_info(pdest);
6216
6217 dest = bgp_node_get(table, &p);
6218
6219 if (bgp_dest_has_bgp_path_info_data(dest)) {
6220 vty_out(vty, "%% Same network configuration exists\n");
6221 bgp_dest_unlock_node(dest);
6222 } else {
6223 /* New configuration. */
6224 bgp_static = bgp_static_new();
6225 bgp_static->backdoor = 0;
6226 bgp_static->valid = 0;
6227 bgp_static->igpmetric = 0;
6228 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6229 bgp_static->label = label;
6230 bgp_static->prd = prd;
6231
6232 if (rmap_str) {
6233 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6234 route_map_counter_decrement(bgp_static->rmap.map);
6235 bgp_static->rmap.name =
6236 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6237 bgp_static->rmap.map =
6238 route_map_lookup_by_name(rmap_str);
6239 route_map_counter_increment(bgp_static->rmap.map);
6240 }
6241
6242 if (safi == SAFI_EVPN) {
6243 if (esi) {
6244 bgp_static->eth_s_id =
6245 XCALLOC(MTYPE_ATTR,
6246 sizeof(esi_t));
6247 str2esi(esi, bgp_static->eth_s_id);
6248 }
6249 if (routermac) {
6250 bgp_static->router_mac =
6251 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6252 (void)prefix_str2mac(routermac,
6253 bgp_static->router_mac);
6254 }
6255 if (gwip)
6256 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6257 }
6258 bgp_dest_set_bgp_static_info(dest, bgp_static);
6259
6260 bgp_static->valid = 1;
6261 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6262 }
6263
6264 return CMD_SUCCESS;
6265 }
6266
6267 /* Configure static BGP network. */
6268 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6269 const char *ip_str, const char *rd_str,
6270 const char *label_str, int evpn_type, const char *esi,
6271 const char *gwip, const char *ethtag)
6272 {
6273 VTY_DECLVAR_CONTEXT(bgp, bgp);
6274 int ret;
6275 struct prefix p;
6276 struct prefix_rd prd;
6277 struct bgp_dest *pdest;
6278 struct bgp_dest *dest;
6279 struct bgp_table *table;
6280 struct bgp_static *bgp_static;
6281 mpls_label_t label = MPLS_INVALID_LABEL;
6282
6283 /* Convert IP prefix string to struct prefix. */
6284 ret = str2prefix(ip_str, &p);
6285 if (!ret) {
6286 vty_out(vty, "%% Malformed prefix\n");
6287 return CMD_WARNING_CONFIG_FAILED;
6288 }
6289 apply_mask(&p);
6290 if ((afi == AFI_L2VPN)
6291 && (bgp_build_evpn_prefix(evpn_type,
6292 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6293 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6294 return CMD_WARNING_CONFIG_FAILED;
6295 }
6296 ret = str2prefix_rd(rd_str, &prd);
6297 if (!ret) {
6298 vty_out(vty, "%% Malformed rd\n");
6299 return CMD_WARNING_CONFIG_FAILED;
6300 }
6301
6302 if (label_str) {
6303 unsigned long label_val;
6304 label_val = strtoul(label_str, NULL, 10);
6305 encode_label(label_val, &label);
6306 }
6307
6308 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6309 if (!bgp_dest_has_bgp_path_info_data(pdest))
6310 bgp_dest_set_bgp_table_info(pdest,
6311 bgp_table_init(bgp, afi, safi));
6312 else
6313 bgp_dest_unlock_node(pdest);
6314 table = bgp_dest_get_bgp_table_info(pdest);
6315
6316 dest = bgp_node_lookup(table, &p);
6317
6318 if (dest) {
6319 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6320
6321 bgp_static = bgp_dest_get_bgp_static_info(dest);
6322 bgp_static_free(bgp_static);
6323 bgp_dest_set_bgp_static_info(dest, NULL);
6324 bgp_dest_unlock_node(dest);
6325 bgp_dest_unlock_node(dest);
6326 } else
6327 vty_out(vty, "%% Can't find the route\n");
6328
6329 return CMD_SUCCESS;
6330 }
6331
6332 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6333 const char *rmap_name)
6334 {
6335 VTY_DECLVAR_CONTEXT(bgp, bgp);
6336 struct bgp_rmap *rmap;
6337
6338 rmap = &bgp->table_map[afi][safi];
6339 if (rmap_name) {
6340 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6341 route_map_counter_decrement(rmap->map);
6342 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6343 rmap->map = route_map_lookup_by_name(rmap_name);
6344 route_map_counter_increment(rmap->map);
6345 } else {
6346 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6347 route_map_counter_decrement(rmap->map);
6348 rmap->map = NULL;
6349 }
6350
6351 if (bgp_fibupd_safi(safi))
6352 bgp_zebra_announce_table(bgp, afi, safi);
6353
6354 return CMD_SUCCESS;
6355 }
6356
6357 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6358 const char *rmap_name)
6359 {
6360 VTY_DECLVAR_CONTEXT(bgp, bgp);
6361 struct bgp_rmap *rmap;
6362
6363 rmap = &bgp->table_map[afi][safi];
6364 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6365 route_map_counter_decrement(rmap->map);
6366 rmap->map = NULL;
6367
6368 if (bgp_fibupd_safi(safi))
6369 bgp_zebra_announce_table(bgp, afi, safi);
6370
6371 return CMD_SUCCESS;
6372 }
6373
6374 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6375 safi_t safi)
6376 {
6377 if (bgp->table_map[afi][safi].name) {
6378 vty_out(vty, " table-map %s\n",
6379 bgp->table_map[afi][safi].name);
6380 }
6381 }
6382
6383 DEFUN (bgp_table_map,
6384 bgp_table_map_cmd,
6385 "table-map WORD",
6386 "BGP table to RIB route download filter\n"
6387 "Name of the route map\n")
6388 {
6389 int idx_word = 1;
6390 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6391 argv[idx_word]->arg);
6392 }
6393 DEFUN (no_bgp_table_map,
6394 no_bgp_table_map_cmd,
6395 "no table-map WORD",
6396 NO_STR
6397 "BGP table to RIB route download filter\n"
6398 "Name of the route map\n")
6399 {
6400 int idx_word = 2;
6401 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6402 argv[idx_word]->arg);
6403 }
6404
6405 DEFPY_YANG (bgp_network, bgp_network_cmd,
6406 "[no] network \
6407 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6408 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6409 backdoor$backdoor}]",
6410 NO_STR
6411 "Specify a network to announce via BGP\n"
6412 "IPv4 prefix\n"
6413 "Network number\n"
6414 "Network mask\n"
6415 "Network mask\n"
6416 "Route-map to modify the attributes\n"
6417 "Name of the route map\n"
6418 "Label index to associate with the prefix\n"
6419 "Label index value\n"
6420 "Specify a BGP backdoor route\n")
6421 {
6422 char addr_prefix_str[PREFIX_STRLEN];
6423 char base_xpath[XPATH_MAXLEN];
6424 afi_t afi;
6425 safi_t safi;
6426
6427 if (address_str) {
6428 int ret;
6429
6430 ret = netmask_str2prefix_str(address_str, netmask_str,
6431 addr_prefix_str,
6432 sizeof(addr_prefix_str));
6433 if (!ret) {
6434 vty_out(vty, "%% Inconsistent address and mask\n");
6435 return CMD_WARNING_CONFIG_FAILED;
6436 }
6437 }
6438
6439 afi = bgp_node_afi(vty);
6440 safi = bgp_node_safi(vty);
6441
6442 if (no) {
6443 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
6444 } else {
6445 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
6446
6447 if (map_name)
6448 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6449 NB_OP_CREATE, map_name);
6450 else
6451 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6452 NB_OP_DESTROY, NULL);
6453
6454 if (label_index_str)
6455 nb_cli_enqueue_change(vty, "./label-index",
6456 NB_OP_MODIFY, label_index_str);
6457
6458 nb_cli_enqueue_change(vty, "./backdoor", NB_OP_MODIFY,
6459 backdoor ? "true" : "false");
6460 }
6461
6462 snprintf(
6463 base_xpath, sizeof(base_xpath),
6464 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
6465 yang_afi_safi_value2identity(afi, safi),
6466 bgp_afi_safi_get_container_str(afi, safi),
6467 address_str ? addr_prefix_str : prefix_str);
6468
6469 return nb_cli_apply_changes(vty, base_xpath);
6470 }
6471
6472 DEFPY_YANG (ipv6_bgp_network,
6473 ipv6_bgp_network_cmd,
6474 "[no] network X:X::X:X/M$prefix \
6475 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6476 NO_STR
6477 "Specify a network to announce via BGP\n"
6478 "IPv6 prefix\n"
6479 "Route-map to modify the attributes\n"
6480 "Name of the route map\n"
6481 "Label index to associate with the prefix\n"
6482 "Label index value\n")
6483 {
6484 char base_xpath[XPATH_MAXLEN];
6485 afi_t afi;
6486 safi_t safi;
6487
6488 afi = bgp_node_afi(vty);
6489 safi = bgp_node_safi(vty);
6490
6491 if (no) {
6492 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
6493 } else {
6494 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
6495
6496 if (map_name)
6497 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6498 NB_OP_MODIFY, map_name);
6499 else
6500 nb_cli_enqueue_change(vty, "./rmap-policy-export",
6501 NB_OP_DESTROY, NULL);
6502
6503 if (label_index_str)
6504 nb_cli_enqueue_change(vty, "./label-index",
6505 NB_OP_MODIFY, label_index_str);
6506 }
6507
6508 snprintf(
6509 base_xpath, sizeof(base_xpath),
6510 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
6511 yang_afi_safi_value2identity(afi, safi),
6512 bgp_afi_safi_get_container_str(afi, safi), prefix_str);
6513
6514 return nb_cli_apply_changes(vty, base_xpath);
6515 }
6516
6517 void cli_show_bgp_global_afi_safi_network_config(struct vty *vty,
6518 struct lyd_node *dnode,
6519 bool show_defaults)
6520 {
6521 vty_out(vty, " network %s", yang_dnode_get_string(dnode, "./prefix"));
6522
6523 if (yang_dnode_exists(dnode, "./label-index"))
6524 vty_out(vty, " label-index %s",
6525 yang_dnode_get_string(dnode, "./label-index"));
6526
6527 if (yang_dnode_exists(dnode, "./rmap-policy-export"))
6528 vty_out(vty, " route-map %s",
6529 yang_dnode_get_string(dnode, "./rmap-policy-export"));
6530
6531 if (yang_dnode_get_bool(dnode, "./backdoor"))
6532 vty_out(vty, " backdoor");
6533
6534 vty_out(vty, "\n");
6535 }
6536
6537 static struct bgp_aggregate *bgp_aggregate_new(void)
6538 {
6539 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6540 }
6541
6542 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6543 {
6544 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
6545 route_map_counter_decrement(aggregate->suppress_map);
6546 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6547 route_map_counter_decrement(aggregate->rmap.map);
6548 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6549 }
6550
6551 /**
6552 * Helper function to avoid repeated code: prepare variables for a
6553 * `route_map_apply` call.
6554 *
6555 * \returns `true` on route map match, otherwise `false`.
6556 */
6557 static bool aggr_suppress_map_test(struct bgp *bgp,
6558 struct bgp_aggregate *aggregate,
6559 struct bgp_path_info *pi)
6560 {
6561 const struct prefix *p = bgp_dest_get_prefix(pi->net);
6562 route_map_result_t rmr = RMAP_DENYMATCH;
6563 struct bgp_path_info rmap_path = {};
6564 struct attr attr = {};
6565
6566 /* No route map entries created, just don't match. */
6567 if (aggregate->suppress_map == NULL)
6568 return false;
6569
6570 /* Call route map matching and return result. */
6571 attr.aspath = aspath_empty();
6572 rmap_path.peer = bgp->peer_self;
6573 rmap_path.attr = &attr;
6574
6575 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
6576 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
6577 bgp->peer_self->rmap_type = 0;
6578
6579 bgp_attr_flush(&attr);
6580
6581 return rmr == RMAP_PERMITMATCH;
6582 }
6583
6584 /** Test whether the aggregation has suppressed this path or not. */
6585 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
6586 struct bgp_path_info *pi)
6587 {
6588 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
6589 return false;
6590
6591 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
6592 }
6593
6594 /**
6595 * Suppress this path and keep the reference.
6596 *
6597 * \returns `true` if needs processing otherwise `false`.
6598 */
6599 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
6600 struct bgp_path_info *pi)
6601 {
6602 struct bgp_path_info_extra *pie;
6603
6604 /* Path is already suppressed by this aggregation. */
6605 if (aggr_suppress_exists(aggregate, pi))
6606 return false;
6607
6608 pie = bgp_path_info_extra_get(pi);
6609
6610 /* This is the first suppression, allocate memory and list it. */
6611 if (pie->aggr_suppressors == NULL)
6612 pie->aggr_suppressors = list_new();
6613
6614 listnode_add(pie->aggr_suppressors, aggregate);
6615
6616 /* Only mark for processing if suppressed. */
6617 if (listcount(pie->aggr_suppressors) == 1) {
6618 if (BGP_DEBUG(update, UPDATE_OUT))
6619 zlog_debug("aggregate-address suppressing: %pFX",
6620 bgp_dest_get_prefix(pi->net));
6621
6622 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6623 return true;
6624 }
6625
6626 return false;
6627 }
6628
6629 /**
6630 * Unsuppress this path and remove the reference.
6631 *
6632 * \returns `true` if needs processing otherwise `false`.
6633 */
6634 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
6635 struct bgp_path_info *pi)
6636 {
6637 /* Path wasn't suppressed. */
6638 if (!aggr_suppress_exists(aggregate, pi))
6639 return false;
6640
6641 listnode_delete(pi->extra->aggr_suppressors, aggregate);
6642
6643 /* Unsuppress and free extra memory if last item. */
6644 if (listcount(pi->extra->aggr_suppressors) == 0) {
6645 if (BGP_DEBUG(update, UPDATE_OUT))
6646 zlog_debug("aggregate-address unsuppressing: %pFX",
6647 bgp_dest_get_prefix(pi->net));
6648
6649 list_delete(&pi->extra->aggr_suppressors);
6650 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6651 return true;
6652 }
6653
6654 return false;
6655 }
6656
6657 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
6658 struct aspath *aspath,
6659 struct community *comm,
6660 struct ecommunity *ecomm,
6661 struct lcommunity *lcomm)
6662 {
6663 static struct aspath *ae = NULL;
6664
6665 if (!ae)
6666 ae = aspath_empty();
6667
6668 if (!pi)
6669 return false;
6670
6671 if (origin != pi->attr->origin)
6672 return false;
6673
6674 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6675 return false;
6676
6677 if (!community_cmp(pi->attr->community, comm))
6678 return false;
6679
6680 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6681 return false;
6682
6683 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6684 return false;
6685
6686 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6687 return false;
6688
6689 return true;
6690 }
6691
6692 static void bgp_aggregate_install(
6693 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
6694 uint8_t origin, struct aspath *aspath, struct community *community,
6695 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
6696 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
6697 {
6698 struct bgp_dest *dest;
6699 struct bgp_table *table;
6700 struct bgp_path_info *pi, *orig, *new;
6701 struct attr *attr;
6702
6703 table = bgp->rib[afi][safi];
6704
6705 dest = bgp_node_get(table, p);
6706
6707 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6708 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6709 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6710 break;
6711
6712 /*
6713 * If we have paths with different MEDs, then don't install
6714 * (or uninstall) the aggregate route.
6715 */
6716 if (aggregate->match_med && aggregate->med_mismatched)
6717 goto uninstall_aggregate_route;
6718
6719 if (aggregate->count > 0) {
6720 /*
6721 * If the aggregate information has not changed
6722 * no need to re-install it again.
6723 */
6724 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6725 ecommunity, lcommunity)) {
6726 bgp_dest_unlock_node(dest);
6727
6728 if (aspath)
6729 aspath_free(aspath);
6730 if (community)
6731 community_free(&community);
6732 if (ecommunity)
6733 ecommunity_free(&ecommunity);
6734 if (lcommunity)
6735 lcommunity_free(&lcommunity);
6736
6737 return;
6738 }
6739
6740 /*
6741 * Mark the old as unusable
6742 */
6743 if (pi)
6744 bgp_path_info_delete(dest, pi);
6745
6746 attr = bgp_attr_aggregate_intern(
6747 bgp, origin, aspath, community, ecommunity, lcommunity,
6748 aggregate, atomic_aggregate, p);
6749
6750 if (!attr) {
6751 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6752 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
6753 zlog_debug("%s: %pFX null attribute", __func__,
6754 p);
6755 return;
6756 }
6757
6758 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6759 bgp->peer_self, attr, dest);
6760
6761 SET_FLAG(new->flags, BGP_PATH_VALID);
6762
6763 bgp_path_info_add(dest, new);
6764 bgp_process(bgp, dest, afi, safi);
6765 } else {
6766 uninstall_aggregate_route:
6767 for (pi = orig; pi; pi = pi->next)
6768 if (pi->peer == bgp->peer_self
6769 && pi->type == ZEBRA_ROUTE_BGP
6770 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6771 break;
6772
6773 /* Withdraw static BGP route from routing table. */
6774 if (pi) {
6775 bgp_path_info_delete(dest, pi);
6776 bgp_process(bgp, dest, afi, safi);
6777 }
6778 }
6779
6780 bgp_dest_unlock_node(dest);
6781 }
6782
6783 /**
6784 * Check if the current path has different MED than other known paths.
6785 *
6786 * \returns `true` if the MED matched the others else `false`.
6787 */
6788 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
6789 struct bgp *bgp, struct bgp_path_info *pi)
6790 {
6791 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
6792
6793 /* This is the first route being analyzed. */
6794 if (!aggregate->med_initialized) {
6795 aggregate->med_initialized = true;
6796 aggregate->med_mismatched = false;
6797 aggregate->med_matched_value = cur_med;
6798 } else {
6799 /* Check if routes with different MED showed up. */
6800 if (cur_med != aggregate->med_matched_value)
6801 aggregate->med_mismatched = true;
6802 }
6803
6804 return !aggregate->med_mismatched;
6805 }
6806
6807 /**
6808 * Initializes and tests all routes in the aggregate address path for MED
6809 * values.
6810 *
6811 * \returns `true` if all MEDs are the same otherwise `false`.
6812 */
6813 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
6814 struct bgp *bgp, const struct prefix *p,
6815 afi_t afi, safi_t safi)
6816 {
6817 struct bgp_table *table = bgp->rib[afi][safi];
6818 const struct prefix *dest_p;
6819 struct bgp_dest *dest, *top;
6820 struct bgp_path_info *pi;
6821 bool med_matched = true;
6822
6823 aggregate->med_initialized = false;
6824
6825 top = bgp_node_get(table, p);
6826 for (dest = bgp_node_get(table, p); dest;
6827 dest = bgp_route_next_until(dest, top)) {
6828 dest_p = bgp_dest_get_prefix(dest);
6829 if (dest_p->prefixlen <= p->prefixlen)
6830 continue;
6831
6832 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6833 if (BGP_PATH_HOLDDOWN(pi))
6834 continue;
6835 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6836 continue;
6837 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
6838 med_matched = false;
6839 break;
6840 }
6841 }
6842 if (!med_matched)
6843 break;
6844 }
6845 bgp_dest_unlock_node(top);
6846
6847 return med_matched;
6848 }
6849
6850 /**
6851 * Toggles the route suppression status for this aggregate address
6852 * configuration.
6853 */
6854 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
6855 struct bgp *bgp, const struct prefix *p,
6856 afi_t afi, safi_t safi, bool suppress)
6857 {
6858 struct bgp_table *table = bgp->rib[afi][safi];
6859 const struct prefix *dest_p;
6860 struct bgp_dest *dest, *top;
6861 struct bgp_path_info *pi;
6862 bool toggle_suppression;
6863
6864 /* We've found a different MED we must revert any suppressed routes. */
6865 top = bgp_node_get(table, p);
6866 for (dest = bgp_node_get(table, p); dest;
6867 dest = bgp_route_next_until(dest, top)) {
6868 dest_p = bgp_dest_get_prefix(dest);
6869 if (dest_p->prefixlen <= p->prefixlen)
6870 continue;
6871
6872 toggle_suppression = false;
6873 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6874 if (BGP_PATH_HOLDDOWN(pi))
6875 continue;
6876 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6877 continue;
6878
6879 /* We are toggling suppression back. */
6880 if (suppress) {
6881 /* Suppress route if not suppressed already. */
6882 if (aggr_suppress_path(aggregate, pi))
6883 toggle_suppression = true;
6884 continue;
6885 }
6886
6887 /* Install route if there is no more suppression. */
6888 if (aggr_unsuppress_path(aggregate, pi))
6889 toggle_suppression = true;
6890 }
6891
6892 if (toggle_suppression)
6893 bgp_process(bgp, dest, afi, safi);
6894 }
6895 bgp_dest_unlock_node(top);
6896 }
6897
6898 /**
6899 * Aggregate address MED matching incremental test: this function is called
6900 * when the initial aggregation occurred and we are only testing a single
6901 * new path.
6902 *
6903 * In addition to testing and setting the MED validity it also installs back
6904 * suppressed routes (if summary is configured).
6905 *
6906 * Must not be called in `bgp_aggregate_route`.
6907 */
6908 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
6909 struct bgp *bgp, const struct prefix *p,
6910 afi_t afi, safi_t safi,
6911 struct bgp_path_info *pi, bool is_adding)
6912 {
6913 /* MED matching disabled. */
6914 if (!aggregate->match_med)
6915 return;
6916
6917 /* Aggregation with different MED, nothing to do. */
6918 if (aggregate->med_mismatched)
6919 return;
6920
6921 /*
6922 * Test the current entry:
6923 *
6924 * is_adding == true: if the new entry doesn't match then we must
6925 * install all suppressed routes.
6926 *
6927 * is_adding == false: if the entry being removed was the last
6928 * unmatching entry then we can suppress all routes.
6929 */
6930 if (!is_adding) {
6931 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
6932 && aggregate->summary_only)
6933 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
6934 safi, true);
6935 } else
6936 bgp_aggregate_med_match(aggregate, bgp, pi);
6937
6938 /* No mismatches, just quit. */
6939 if (!aggregate->med_mismatched)
6940 return;
6941
6942 /* Route summarization is disabled. */
6943 if (!aggregate->summary_only)
6944 return;
6945
6946 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
6947 }
6948
6949 /* Update an aggregate as routes are added/removed from the BGP table */
6950 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
6951 safi_t safi, struct bgp_aggregate *aggregate)
6952 {
6953 struct bgp_table *table;
6954 struct bgp_dest *top;
6955 struct bgp_dest *dest;
6956 uint8_t origin;
6957 struct aspath *aspath = NULL;
6958 struct community *community = NULL;
6959 struct ecommunity *ecommunity = NULL;
6960 struct lcommunity *lcommunity = NULL;
6961 struct bgp_path_info *pi;
6962 unsigned long match = 0;
6963 uint8_t atomic_aggregate = 0;
6964
6965 /* If the bgp instance is being deleted or self peer is deleted
6966 * then do not create aggregate route
6967 */
6968 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6969 || (bgp->peer_self == NULL))
6970 return;
6971
6972 /* Initialize and test routes for MED difference. */
6973 if (aggregate->match_med)
6974 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
6975
6976 /*
6977 * Reset aggregate count: we might've been called from route map
6978 * update so in that case we must retest all more specific routes.
6979 *
6980 * \see `bgp_route_map_process_update`.
6981 */
6982 aggregate->count = 0;
6983 aggregate->incomplete_origin_count = 0;
6984 aggregate->incomplete_origin_count = 0;
6985 aggregate->egp_origin_count = 0;
6986
6987 /* ORIGIN attribute: If at least one route among routes that are
6988 aggregated has ORIGIN with the value INCOMPLETE, then the
6989 aggregated route must have the ORIGIN attribute with the value
6990 INCOMPLETE. Otherwise, if at least one route among routes that
6991 are aggregated has ORIGIN with the value EGP, then the aggregated
6992 route must have the origin attribute with the value EGP. In all
6993 other case the value of the ORIGIN attribute of the aggregated
6994 route is INTERNAL. */
6995 origin = BGP_ORIGIN_IGP;
6996
6997 table = bgp->rib[afi][safi];
6998
6999 top = bgp_node_get(table, p);
7000 for (dest = bgp_node_get(table, p); dest;
7001 dest = bgp_route_next_until(dest, top)) {
7002 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7003
7004 if (dest_p->prefixlen <= p->prefixlen)
7005 continue;
7006
7007 /* If suppress fib is enabled and route not installed
7008 * in FIB, skip the route
7009 */
7010 if (!bgp_check_advertise(bgp, dest))
7011 continue;
7012
7013 match = 0;
7014
7015 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7016 if (BGP_PATH_HOLDDOWN(pi))
7017 continue;
7018
7019 if (pi->attr->flag
7020 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7021 atomic_aggregate = 1;
7022
7023 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7024 continue;
7025
7026 /*
7027 * summary-only aggregate route suppress
7028 * aggregated route announcements.
7029 *
7030 * MED matching:
7031 * Don't create summaries if MED didn't match
7032 * otherwise neither the specific routes and the
7033 * aggregation will be announced.
7034 */
7035 if (aggregate->summary_only
7036 && AGGREGATE_MED_VALID(aggregate)) {
7037 if (aggr_suppress_path(aggregate, pi))
7038 match++;
7039 }
7040
7041 /*
7042 * Suppress more specific routes that match the route
7043 * map results.
7044 *
7045 * MED matching:
7046 * Don't suppress routes if MED matching is enabled and
7047 * it mismatched otherwise we might end up with no
7048 * routes for this path.
7049 */
7050 if (aggregate->suppress_map_name
7051 && AGGREGATE_MED_VALID(aggregate)
7052 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7053 if (aggr_suppress_path(aggregate, pi))
7054 match++;
7055 }
7056
7057 aggregate->count++;
7058
7059 /*
7060 * If at least one route among routes that are
7061 * aggregated has ORIGIN with the value INCOMPLETE,
7062 * then the aggregated route MUST have the ORIGIN
7063 * attribute with the value INCOMPLETE. Otherwise, if
7064 * at least one route among routes that are aggregated
7065 * has ORIGIN with the value EGP, then the aggregated
7066 * route MUST have the ORIGIN attribute with the value
7067 * EGP.
7068 */
7069 switch (pi->attr->origin) {
7070 case BGP_ORIGIN_INCOMPLETE:
7071 aggregate->incomplete_origin_count++;
7072 break;
7073 case BGP_ORIGIN_EGP:
7074 aggregate->egp_origin_count++;
7075 break;
7076 default:
7077 /*Do nothing.
7078 */
7079 break;
7080 }
7081
7082 if (!aggregate->as_set)
7083 continue;
7084
7085 /*
7086 * as-set aggregate route generate origin, as path,
7087 * and community aggregation.
7088 */
7089 /* Compute aggregate route's as-path.
7090 */
7091 bgp_compute_aggregate_aspath_hash(aggregate,
7092 pi->attr->aspath);
7093
7094 /* Compute aggregate route's community.
7095 */
7096 if (pi->attr->community)
7097 bgp_compute_aggregate_community_hash(
7098 aggregate,
7099 pi->attr->community);
7100
7101 /* Compute aggregate route's extended community.
7102 */
7103 if (pi->attr->ecommunity)
7104 bgp_compute_aggregate_ecommunity_hash(
7105 aggregate,
7106 pi->attr->ecommunity);
7107
7108 /* Compute aggregate route's large community.
7109 */
7110 if (pi->attr->lcommunity)
7111 bgp_compute_aggregate_lcommunity_hash(
7112 aggregate,
7113 pi->attr->lcommunity);
7114 }
7115 if (match)
7116 bgp_process(bgp, dest, afi, safi);
7117 }
7118 if (aggregate->as_set) {
7119 bgp_compute_aggregate_aspath_val(aggregate);
7120 bgp_compute_aggregate_community_val(aggregate);
7121 bgp_compute_aggregate_ecommunity_val(aggregate);
7122 bgp_compute_aggregate_lcommunity_val(aggregate);
7123 }
7124
7125
7126 bgp_dest_unlock_node(top);
7127
7128
7129 if (aggregate->incomplete_origin_count > 0)
7130 origin = BGP_ORIGIN_INCOMPLETE;
7131 else if (aggregate->egp_origin_count > 0)
7132 origin = BGP_ORIGIN_EGP;
7133
7134 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7135 origin = aggregate->origin;
7136
7137 if (aggregate->as_set) {
7138 if (aggregate->aspath)
7139 /* Retrieve aggregate route's as-path.
7140 */
7141 aspath = aspath_dup(aggregate->aspath);
7142
7143 if (aggregate->community)
7144 /* Retrieve aggregate route's community.
7145 */
7146 community = community_dup(aggregate->community);
7147
7148 if (aggregate->ecommunity)
7149 /* Retrieve aggregate route's ecommunity.
7150 */
7151 ecommunity = ecommunity_dup(aggregate->ecommunity);
7152
7153 if (aggregate->lcommunity)
7154 /* Retrieve aggregate route's lcommunity.
7155 */
7156 lcommunity = lcommunity_dup(aggregate->lcommunity);
7157 }
7158
7159 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7160 ecommunity, lcommunity, atomic_aggregate,
7161 aggregate);
7162 }
7163
7164 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7165 safi_t safi, struct bgp_aggregate *aggregate)
7166 {
7167 struct bgp_table *table;
7168 struct bgp_dest *top;
7169 struct bgp_dest *dest;
7170 struct bgp_path_info *pi;
7171 unsigned long match;
7172
7173 table = bgp->rib[afi][safi];
7174
7175 /* If routes exists below this node, generate aggregate routes. */
7176 top = bgp_node_get(table, p);
7177 for (dest = bgp_node_get(table, p); dest;
7178 dest = bgp_route_next_until(dest, top)) {
7179 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7180
7181 if (dest_p->prefixlen <= p->prefixlen)
7182 continue;
7183 match = 0;
7184
7185 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7186 if (BGP_PATH_HOLDDOWN(pi))
7187 continue;
7188
7189 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7190 continue;
7191
7192 if (aggregate->summary_only && pi->extra
7193 && AGGREGATE_MED_VALID(aggregate)) {
7194 if (aggr_unsuppress_path(aggregate, pi))
7195 match++;
7196 }
7197
7198 if (aggregate->suppress_map_name
7199 && AGGREGATE_MED_VALID(aggregate)
7200 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7201 if (aggr_unsuppress_path(aggregate, pi))
7202 match++;
7203 }
7204
7205 aggregate->count--;
7206
7207 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7208 aggregate->incomplete_origin_count--;
7209 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7210 aggregate->egp_origin_count--;
7211
7212 if (aggregate->as_set) {
7213 /* Remove as-path from aggregate.
7214 */
7215 bgp_remove_aspath_from_aggregate_hash(
7216 aggregate,
7217 pi->attr->aspath);
7218
7219 if (pi->attr->community)
7220 /* Remove community from aggregate.
7221 */
7222 bgp_remove_comm_from_aggregate_hash(
7223 aggregate,
7224 pi->attr->community);
7225
7226 if (pi->attr->ecommunity)
7227 /* Remove ecommunity from aggregate.
7228 */
7229 bgp_remove_ecomm_from_aggregate_hash(
7230 aggregate,
7231 pi->attr->ecommunity);
7232
7233 if (pi->attr->lcommunity)
7234 /* Remove lcommunity from aggregate.
7235 */
7236 bgp_remove_lcomm_from_aggregate_hash(
7237 aggregate,
7238 pi->attr->lcommunity);
7239 }
7240 }
7241
7242 /* If this node was suppressed, process the change. */
7243 if (match)
7244 bgp_process(bgp, dest, afi, safi);
7245 }
7246 if (aggregate->as_set) {
7247 aspath_free(aggregate->aspath);
7248 aggregate->aspath = NULL;
7249 if (aggregate->community)
7250 community_free(&aggregate->community);
7251 if (aggregate->ecommunity)
7252 ecommunity_free(&aggregate->ecommunity);
7253 if (aggregate->lcommunity)
7254 lcommunity_free(&aggregate->lcommunity);
7255 }
7256
7257 bgp_dest_unlock_node(top);
7258 }
7259
7260 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7261 const struct prefix *aggr_p,
7262 struct bgp_path_info *pinew, afi_t afi,
7263 safi_t safi,
7264 struct bgp_aggregate *aggregate)
7265 {
7266 uint8_t origin;
7267 struct aspath *aspath = NULL;
7268 uint8_t atomic_aggregate = 0;
7269 struct community *community = NULL;
7270 struct ecommunity *ecommunity = NULL;
7271 struct lcommunity *lcommunity = NULL;
7272
7273 /* If the bgp instance is being deleted or self peer is deleted
7274 * then do not create aggregate route
7275 */
7276 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7277 || (bgp->peer_self == NULL))
7278 return;
7279
7280 /* ORIGIN attribute: If at least one route among routes that are
7281 * aggregated has ORIGIN with the value INCOMPLETE, then the
7282 * aggregated route must have the ORIGIN attribute with the value
7283 * INCOMPLETE. Otherwise, if at least one route among routes that
7284 * are aggregated has ORIGIN with the value EGP, then the aggregated
7285 * route must have the origin attribute with the value EGP. In all
7286 * other case the value of the ORIGIN attribute of the aggregated
7287 * route is INTERNAL.
7288 */
7289 origin = BGP_ORIGIN_IGP;
7290
7291 aggregate->count++;
7292
7293 /*
7294 * This must be called before `summary` check to avoid
7295 * "suppressing" twice.
7296 */
7297 if (aggregate->match_med)
7298 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7299 pinew, true);
7300
7301 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7302 aggr_suppress_path(aggregate, pinew);
7303
7304 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7305 && aggr_suppress_map_test(bgp, aggregate, pinew))
7306 aggr_suppress_path(aggregate, pinew);
7307
7308 switch (pinew->attr->origin) {
7309 case BGP_ORIGIN_INCOMPLETE:
7310 aggregate->incomplete_origin_count++;
7311 break;
7312 case BGP_ORIGIN_EGP:
7313 aggregate->egp_origin_count++;
7314 break;
7315 default:
7316 /* Do nothing.
7317 */
7318 break;
7319 }
7320
7321 if (aggregate->incomplete_origin_count > 0)
7322 origin = BGP_ORIGIN_INCOMPLETE;
7323 else if (aggregate->egp_origin_count > 0)
7324 origin = BGP_ORIGIN_EGP;
7325
7326 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7327 origin = aggregate->origin;
7328
7329 if (aggregate->as_set) {
7330 /* Compute aggregate route's as-path.
7331 */
7332 bgp_compute_aggregate_aspath(aggregate,
7333 pinew->attr->aspath);
7334
7335 /* Compute aggregate route's community.
7336 */
7337 if (pinew->attr->community)
7338 bgp_compute_aggregate_community(
7339 aggregate,
7340 pinew->attr->community);
7341
7342 /* Compute aggregate route's extended community.
7343 */
7344 if (pinew->attr->ecommunity)
7345 bgp_compute_aggregate_ecommunity(
7346 aggregate,
7347 pinew->attr->ecommunity);
7348
7349 /* Compute aggregate route's large community.
7350 */
7351 if (pinew->attr->lcommunity)
7352 bgp_compute_aggregate_lcommunity(
7353 aggregate,
7354 pinew->attr->lcommunity);
7355
7356 /* Retrieve aggregate route's as-path.
7357 */
7358 if (aggregate->aspath)
7359 aspath = aspath_dup(aggregate->aspath);
7360
7361 /* Retrieve aggregate route's community.
7362 */
7363 if (aggregate->community)
7364 community = community_dup(aggregate->community);
7365
7366 /* Retrieve aggregate route's ecommunity.
7367 */
7368 if (aggregate->ecommunity)
7369 ecommunity = ecommunity_dup(aggregate->ecommunity);
7370
7371 /* Retrieve aggregate route's lcommunity.
7372 */
7373 if (aggregate->lcommunity)
7374 lcommunity = lcommunity_dup(aggregate->lcommunity);
7375 }
7376
7377 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7378 aspath, community, ecommunity,
7379 lcommunity, atomic_aggregate, aggregate);
7380 }
7381
7382 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7383 safi_t safi,
7384 struct bgp_path_info *pi,
7385 struct bgp_aggregate *aggregate,
7386 const struct prefix *aggr_p)
7387 {
7388 uint8_t origin;
7389 struct aspath *aspath = NULL;
7390 uint8_t atomic_aggregate = 0;
7391 struct community *community = NULL;
7392 struct ecommunity *ecommunity = NULL;
7393 struct lcommunity *lcommunity = NULL;
7394 unsigned long match = 0;
7395
7396 /* If the bgp instance is being deleted or self peer is deleted
7397 * then do not create aggregate route
7398 */
7399 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7400 || (bgp->peer_self == NULL))
7401 return;
7402
7403 if (BGP_PATH_HOLDDOWN(pi))
7404 return;
7405
7406 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7407 return;
7408
7409 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7410 if (aggr_unsuppress_path(aggregate, pi))
7411 match++;
7412
7413 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7414 && aggr_suppress_map_test(bgp, aggregate, pi))
7415 if (aggr_unsuppress_path(aggregate, pi))
7416 match++;
7417
7418 /*
7419 * This must be called after `summary`, `suppress-map` check to avoid
7420 * "unsuppressing" twice.
7421 */
7422 if (aggregate->match_med)
7423 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
7424 true);
7425
7426 if (aggregate->count > 0)
7427 aggregate->count--;
7428
7429 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7430 aggregate->incomplete_origin_count--;
7431 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7432 aggregate->egp_origin_count--;
7433
7434 if (aggregate->as_set) {
7435 /* Remove as-path from aggregate.
7436 */
7437 bgp_remove_aspath_from_aggregate(aggregate,
7438 pi->attr->aspath);
7439
7440 if (pi->attr->community)
7441 /* Remove community from aggregate.
7442 */
7443 bgp_remove_community_from_aggregate(
7444 aggregate,
7445 pi->attr->community);
7446
7447 if (pi->attr->ecommunity)
7448 /* Remove ecommunity from aggregate.
7449 */
7450 bgp_remove_ecommunity_from_aggregate(
7451 aggregate,
7452 pi->attr->ecommunity);
7453
7454 if (pi->attr->lcommunity)
7455 /* Remove lcommunity from aggregate.
7456 */
7457 bgp_remove_lcommunity_from_aggregate(
7458 aggregate,
7459 pi->attr->lcommunity);
7460 }
7461
7462 /* If this node was suppressed, process the change. */
7463 if (match)
7464 bgp_process(bgp, pi->net, afi, safi);
7465
7466 origin = BGP_ORIGIN_IGP;
7467 if (aggregate->incomplete_origin_count > 0)
7468 origin = BGP_ORIGIN_INCOMPLETE;
7469 else if (aggregate->egp_origin_count > 0)
7470 origin = BGP_ORIGIN_EGP;
7471
7472 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7473 origin = aggregate->origin;
7474
7475 if (aggregate->as_set) {
7476 /* Retrieve aggregate route's as-path.
7477 */
7478 if (aggregate->aspath)
7479 aspath = aspath_dup(aggregate->aspath);
7480
7481 /* Retrieve aggregate route's community.
7482 */
7483 if (aggregate->community)
7484 community = community_dup(aggregate->community);
7485
7486 /* Retrieve aggregate route's ecommunity.
7487 */
7488 if (aggregate->ecommunity)
7489 ecommunity = ecommunity_dup(aggregate->ecommunity);
7490
7491 /* Retrieve aggregate route's lcommunity.
7492 */
7493 if (aggregate->lcommunity)
7494 lcommunity = lcommunity_dup(aggregate->lcommunity);
7495 }
7496
7497 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7498 aspath, community, ecommunity,
7499 lcommunity, atomic_aggregate, aggregate);
7500 }
7501
7502 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
7503 struct bgp_path_info *pi, afi_t afi, safi_t safi)
7504 {
7505 struct bgp_dest *child;
7506 struct bgp_dest *dest;
7507 struct bgp_aggregate *aggregate;
7508 struct bgp_table *table;
7509
7510 table = bgp->aggregate[afi][safi];
7511
7512 /* No aggregates configured. */
7513 if (bgp_table_top_nolock(table) == NULL)
7514 return;
7515
7516 if (p->prefixlen == 0)
7517 return;
7518
7519 if (BGP_PATH_HOLDDOWN(pi))
7520 return;
7521
7522 /* If suppress fib is enabled and route not installed
7523 * in FIB, do not update the aggregate route
7524 */
7525 if (!bgp_check_advertise(bgp, pi->net))
7526 return;
7527
7528 child = bgp_node_get(table, p);
7529
7530 /* Aggregate address configuration check. */
7531 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7532 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7533
7534 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7535 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7536 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
7537 aggregate);
7538 }
7539 }
7540 bgp_dest_unlock_node(child);
7541 }
7542
7543 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
7544 struct bgp_path_info *del, afi_t afi, safi_t safi)
7545 {
7546 struct bgp_dest *child;
7547 struct bgp_dest *dest;
7548 struct bgp_aggregate *aggregate;
7549 struct bgp_table *table;
7550
7551 table = bgp->aggregate[afi][safi];
7552
7553 /* No aggregates configured. */
7554 if (bgp_table_top_nolock(table) == NULL)
7555 return;
7556
7557 if (p->prefixlen == 0)
7558 return;
7559
7560 child = bgp_node_get(table, p);
7561
7562 /* Aggregate address configuration check. */
7563 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7564 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7565
7566 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7567 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7568 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
7569 aggregate, dest_p);
7570 }
7571 }
7572 bgp_dest_unlock_node(child);
7573 }
7574
7575 /* Aggregate route attribute. */
7576 #define AGGREGATE_SUMMARY_ONLY 1
7577 #define AGGREGATE_AS_SET 1
7578 #define AGGREGATE_AS_UNSET 0
7579
7580 static const char *bgp_origin2str(uint8_t origin)
7581 {
7582 switch (origin) {
7583 case BGP_ORIGIN_IGP:
7584 return "igp";
7585 case BGP_ORIGIN_EGP:
7586 return "egp";
7587 case BGP_ORIGIN_INCOMPLETE:
7588 return "incomplete";
7589 }
7590 return "n/a";
7591 }
7592
7593 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
7594 {
7595 switch (v_state) {
7596 case RPKI_NOT_BEING_USED:
7597 return "not used";
7598 case RPKI_VALID:
7599 return "valid";
7600 case RPKI_NOTFOUND:
7601 return "not found";
7602 case RPKI_INVALID:
7603 return "invalid";
7604 }
7605
7606 assert(!"We should never get here this is a dev escape");
7607 return "ERROR";
7608 }
7609
7610 int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi,
7611 safi_t safi, char *errmsg, size_t errmsg_len)
7612 {
7613 struct bgp_dest *dest;
7614 struct bgp_aggregate *aggregate;
7615
7616 /* If the bgp instance is being deleted or self peer is deleted
7617 * then do not create aggregate route
7618 */
7619 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7620 || (bgp->peer_self == NULL))
7621 return 0;
7622
7623 apply_mask(prefix);
7624 /* Old configuration check. */
7625 dest = bgp_node_lookup(bgp->aggregate[afi][safi], prefix);
7626 if (!dest) {
7627 snprintf(errmsg, errmsg_len,
7628 "There is no aggregate-address configuration.\n");
7629 return -1;
7630 }
7631
7632 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7633 bgp_aggregate_delete(bgp, prefix, afi, safi, aggregate);
7634 bgp_aggregate_install(bgp, afi, safi, prefix, 0, NULL, NULL, NULL, NULL,
7635 0, aggregate);
7636
7637 /* Unlock aggregate address configuration. */
7638 bgp_dest_set_bgp_aggregate_info(dest, NULL);
7639
7640 if (aggregate->community)
7641 community_free(&aggregate->community);
7642
7643 if (aggregate->community_hash) {
7644 /* Delete all communities in the hash.
7645 */
7646 hash_clean(aggregate->community_hash,
7647 bgp_aggr_community_remove);
7648 /* Free up the community_hash.
7649 */
7650 hash_free(aggregate->community_hash);
7651 }
7652
7653 if (aggregate->ecommunity)
7654 ecommunity_free(&aggregate->ecommunity);
7655
7656 if (aggregate->ecommunity_hash) {
7657 /* Delete all ecommunities in the hash.
7658 */
7659 hash_clean(aggregate->ecommunity_hash,
7660 bgp_aggr_ecommunity_remove);
7661 /* Free up the ecommunity_hash.
7662 */
7663 hash_free(aggregate->ecommunity_hash);
7664 }
7665
7666 if (aggregate->lcommunity)
7667 lcommunity_free(&aggregate->lcommunity);
7668
7669 if (aggregate->lcommunity_hash) {
7670 /* Delete all lcommunities in the hash.
7671 */
7672 hash_clean(aggregate->lcommunity_hash,
7673 bgp_aggr_lcommunity_remove);
7674 /* Free up the lcommunity_hash.
7675 */
7676 hash_free(aggregate->lcommunity_hash);
7677 }
7678
7679 if (aggregate->aspath)
7680 aspath_free(aggregate->aspath);
7681
7682 if (aggregate->aspath_hash) {
7683 /* Delete all as-paths in the hash.
7684 */
7685 hash_clean(aggregate->aspath_hash,
7686 bgp_aggr_aspath_remove);
7687 /* Free up the aspath_hash.
7688 */
7689 hash_free(aggregate->aspath_hash);
7690 }
7691
7692 bgp_aggregate_free(aggregate);
7693 bgp_dest_unlock_node(dest);
7694 bgp_dest_unlock_node(dest);
7695
7696 return 0;
7697 }
7698
7699 int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
7700 safi_t safi, const char *rmap, uint8_t summary_only,
7701 uint8_t as_set, uint8_t origin, bool match_med,
7702 const char *suppress_map,
7703 char *errmsg, size_t errmsg_len)
7704 {
7705 int ret;
7706 struct bgp_dest *dest;
7707 struct bgp_aggregate *aggregate;
7708 uint8_t as_set_new = as_set;
7709 char buf[PREFIX2STR_BUFFER];
7710
7711 if (suppress_map && summary_only) {
7712 snprintf(errmsg, errmsg_len,
7713 "'summary-only' and 'suppress-map' can't be used at the same time\n");
7714 return -1;
7715 }
7716
7717 apply_mask(prefix);
7718
7719 if ((afi == AFI_IP && prefix->prefixlen == IPV4_MAX_BITLEN)
7720 || (afi == AFI_IP6 && prefix->prefixlen == IPV6_MAX_BITLEN)) {
7721 snprintf(
7722 errmsg, errmsg_len,
7723 "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
7724 prefix2str(prefix, buf, PREFIX_STRLEN));
7725 return -1;
7726 }
7727
7728 /* Old configuration check. */
7729 dest = bgp_node_get(bgp->aggregate[afi][safi], prefix);
7730 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7731
7732 if (aggregate) {
7733 snprintf(errmsg, errmsg_len,
7734 "There is already same aggregate network.\n");
7735 /* try to remove the old entry */
7736 ret = bgp_aggregate_unset(bgp, prefix, afi, safi, errmsg,
7737 errmsg_len);
7738 if (ret) {
7739 snprintf(errmsg, errmsg_len,
7740 "Error deleting aggregate.\n");
7741 bgp_dest_unlock_node(dest);
7742 return -1;
7743 }
7744 }
7745
7746 /* Make aggregate address structure. */
7747 aggregate = bgp_aggregate_new();
7748 aggregate->summary_only = summary_only;
7749 aggregate->match_med = match_med;
7750
7751 /* Network operators MUST NOT locally generate any new
7752 * announcements containing AS_SET or AS_CONFED_SET. If they have
7753 * announced routes with AS_SET or AS_CONFED_SET in them, then they
7754 * SHOULD withdraw those routes and re-announce routes for the
7755 * aggregate or component prefixes (i.e., the more-specific routes
7756 * subsumed by the previously aggregated route) without AS_SET
7757 * or AS_CONFED_SET in the updates.
7758 */
7759 if (bgp->reject_as_sets) {
7760 if (as_set == AGGREGATE_AS_SET) {
7761 as_set_new = AGGREGATE_AS_UNSET;
7762 zlog_warn(
7763 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
7764 __func__);
7765 snprintf(
7766 errmsg, errmsg_len,
7767 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
7768 }
7769 }
7770
7771 aggregate->as_set = as_set_new;
7772 aggregate->safi = safi;
7773 /* Override ORIGIN attribute if defined.
7774 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
7775 * to IGP which is not what rfc4271 says.
7776 * This enables the same behavior, optionally.
7777 */
7778 aggregate->origin = origin;
7779
7780 if (rmap) {
7781 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7782 route_map_counter_decrement(aggregate->rmap.map);
7783 aggregate->rmap.name =
7784 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
7785 aggregate->rmap.map = route_map_lookup_by_name(rmap);
7786 route_map_counter_increment(aggregate->rmap.map);
7787 }
7788
7789 if (suppress_map) {
7790 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7791 route_map_counter_decrement(aggregate->suppress_map);
7792
7793 aggregate->suppress_map_name =
7794 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
7795 aggregate->suppress_map =
7796 route_map_lookup_by_name(aggregate->suppress_map_name);
7797 route_map_counter_increment(aggregate->suppress_map);
7798 }
7799
7800 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
7801
7802 /* Aggregate address insert into BGP routing table. */
7803 bgp_aggregate_route(bgp, prefix, afi, safi, aggregate);
7804
7805 return 0;
7806 }
7807
7808 DEFPY_YANG(
7809 aggregate_addressv4, aggregate_addressv4_cmd,
7810 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
7811 "as-set$as_set_s"
7812 "|summary-only$summary_only"
7813 "|route-map WORD$rmap_name"
7814 "|origin <egp|igp|incomplete>$origin_s"
7815 "|matching-MED-only$match_med"
7816 "|suppress-map WORD$suppress_map"
7817 "}]",
7818 NO_STR
7819 "Configure BGP aggregate entries\n"
7820 "Aggregate prefix\n"
7821 "Aggregate address\n"
7822 "Aggregate mask\n"
7823 "Generate AS set path information\n"
7824 "Filter more specific routes from updates\n"
7825 "Apply route map to aggregate network\n"
7826 "Route map name\n"
7827 "BGP origin code\n"
7828 "Remote EGP\n"
7829 "Local IGP\n"
7830 "Unknown heritage\n"
7831 "Only aggregate routes with matching MED\n"
7832 "Suppress the selected more specific routes\n"
7833 "Route map with the route selectors\n")
7834 {
7835 char base_xpath[XPATH_MAXLEN];
7836 safi_t safi = bgp_node_safi(vty);
7837 char prefix_buf[PREFIX2STR_BUFFER];
7838
7839 if (addr_str) {
7840 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
7841 sizeof(prefix_buf))
7842 == 0) {
7843 vty_out(vty, "%% Inconsistent address and mask\n");
7844 return CMD_WARNING_CONFIG_FAILED;
7845 }
7846 } else {
7847 strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf));
7848 }
7849
7850 if (!no && origin_s)
7851 nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
7852
7853 if (!no && as_set_s)
7854 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
7855 else
7856 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
7857
7858 if (!no && summary_only)
7859 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7860 "true");
7861 else
7862 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7863 "false");
7864
7865 if (!no && match_med)
7866 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
7867 else
7868 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
7869 "false");
7870
7871 if (rmap_name)
7872 nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
7873 rmap_name);
7874 else
7875 nb_cli_enqueue_change(vty, "./rmap-policy-export",
7876 NB_OP_DESTROY, NULL);
7877
7878 if (suppress_map)
7879 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
7880 suppress_map);
7881 else
7882 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
7883 NULL);
7884
7885 snprintf(
7886 base_xpath, sizeof(base_xpath),
7887 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
7888 yang_afi_safi_value2identity(AFI_IP, safi),
7889 bgp_afi_safi_get_container_str(AFI_IP, safi), prefix_buf);
7890
7891 if (no)
7892 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
7893 else
7894 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
7895
7896 return nb_cli_apply_changes(vty, base_xpath);
7897 }
7898
7899 DEFPY_YANG(aggregate_addressv6, aggregate_addressv6_cmd,
7900 "[no] aggregate-address X:X::X:X/M$prefix [{"
7901 "as-set$as_set_s"
7902 "|summary-only$summary_only"
7903 "|route-map WORD$rmap_name"
7904 "|origin <egp|igp|incomplete>$origin_s"
7905 "|matching-MED-only$match_med"
7906 "|suppress-map WORD$suppress_map"
7907 "}]",
7908 NO_STR
7909 "Configure BGP aggregate entries\n"
7910 "Aggregate prefix\n"
7911 "Generate AS set path information\n"
7912 "Filter more specific routes from updates\n"
7913 "Apply route map to aggregate network\n"
7914 "Route map name\n"
7915 "BGP origin code\n"
7916 "Remote EGP\n"
7917 "Local IGP\n"
7918 "Unknown heritage\n"
7919 "Only aggregate routes with matching MED\n"
7920 "Suppress the selected more specific routes\n"
7921 "Route map with the route selectors\n")
7922 {
7923 char base_xpath[XPATH_MAXLEN];
7924 safi_t safi = bgp_node_safi(vty);
7925
7926 if (!no && origin_s)
7927 nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
7928
7929 if (!no && as_set_s)
7930 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
7931 else
7932 nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
7933
7934 if (!no && summary_only)
7935 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7936 "true");
7937 else
7938 nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
7939 "false");
7940
7941 if (!no && match_med)
7942 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
7943 else
7944 nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
7945 "false");
7946
7947 if (rmap_name)
7948 nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
7949 rmap_name);
7950
7951 if (suppress_map)
7952 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
7953 suppress_map);
7954 else
7955 nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
7956 NULL);
7957
7958 snprintf(
7959 base_xpath, sizeof(base_xpath),
7960 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
7961 yang_afi_safi_value2identity(AFI_IP6, safi),
7962 bgp_afi_safi_get_container_str(AFI_IP6, safi), prefix_str);
7963
7964 if (no)
7965 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
7966 else
7967 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
7968
7969 return nb_cli_apply_changes(vty, base_xpath);
7970 }
7971
7972 void cli_show_bgp_global_afi_safi_unicast_aggregate_route(
7973 struct vty *vty, struct lyd_node *dnode, bool show_defaults)
7974 {
7975 uint8_t origin;
7976
7977 vty_out(vty, " aggregate-address %s",
7978 yang_dnode_get_string(dnode, "./prefix"));
7979
7980 if (yang_dnode_get_bool(dnode, "./as-set"))
7981 vty_out(vty, " as-set");
7982
7983 if (yang_dnode_get_bool(dnode, "./summary-only"))
7984 vty_out(vty, " summary-only");
7985
7986 if (yang_dnode_exists(dnode, "./rmap-policy-export"))
7987 vty_out(vty, " route-map %s",
7988 yang_dnode_get_string(dnode, "./rmap-policy-export"));
7989
7990 origin = yang_dnode_get_enum(dnode, "./origin");
7991 if (origin != BGP_ORIGIN_UNSPECIFIED)
7992 vty_out(vty, " origin %s", bgp_origin2str(origin));
7993
7994 if (yang_dnode_get_bool(dnode, "./match-med"))
7995 vty_out(vty, " matching-MED-only");
7996
7997 vty_out(vty, "\n");
7998 }
7999
8000 /* Redistribute route treatment. */
8001 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8002 const union g_addr *nexthop, ifindex_t ifindex,
8003 enum nexthop_types_t nhtype, uint32_t metric,
8004 uint8_t type, unsigned short instance,
8005 route_tag_t tag)
8006 {
8007 struct bgp_path_info *new;
8008 struct bgp_path_info *bpi;
8009 struct bgp_path_info rmap_path;
8010 struct bgp_dest *bn;
8011 struct attr attr;
8012 struct attr *new_attr;
8013 afi_t afi;
8014 route_map_result_t ret;
8015 struct bgp_redist *red;
8016
8017 /* Make default attribute. */
8018 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
8019 /*
8020 * This must not be NULL to satisfy Coverity SA
8021 */
8022 assert(attr.aspath);
8023
8024 switch (nhtype) {
8025 case NEXTHOP_TYPE_IFINDEX:
8026 break;
8027 case NEXTHOP_TYPE_IPV4:
8028 case NEXTHOP_TYPE_IPV4_IFINDEX:
8029 attr.nexthop = nexthop->ipv4;
8030 break;
8031 case NEXTHOP_TYPE_IPV6:
8032 case NEXTHOP_TYPE_IPV6_IFINDEX:
8033 attr.mp_nexthop_global = nexthop->ipv6;
8034 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8035 break;
8036 case NEXTHOP_TYPE_BLACKHOLE:
8037 switch (p->family) {
8038 case AF_INET:
8039 attr.nexthop.s_addr = INADDR_ANY;
8040 break;
8041 case AF_INET6:
8042 memset(&attr.mp_nexthop_global, 0,
8043 sizeof(attr.mp_nexthop_global));
8044 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8045 break;
8046 }
8047 break;
8048 }
8049 attr.nh_ifindex = ifindex;
8050
8051 attr.med = metric;
8052 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8053 attr.tag = tag;
8054
8055 afi = family2afi(p->family);
8056
8057 red = bgp_redist_lookup(bgp, afi, type, instance);
8058 if (red) {
8059 struct attr attr_new;
8060
8061 /* Copy attribute for modification. */
8062 attr_new = attr;
8063
8064 if (red->redist_metric_flag)
8065 attr_new.med = red->redist_metric;
8066
8067 /* Apply route-map. */
8068 if (red->rmap.name) {
8069 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
8070 rmap_path.peer = bgp->peer_self;
8071 rmap_path.attr = &attr_new;
8072
8073 SET_FLAG(bgp->peer_self->rmap_type,
8074 PEER_RMAP_TYPE_REDISTRIBUTE);
8075
8076 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8077
8078 bgp->peer_self->rmap_type = 0;
8079
8080 if (ret == RMAP_DENYMATCH) {
8081 /* Free uninterned attribute. */
8082 bgp_attr_flush(&attr_new);
8083
8084 /* Unintern original. */
8085 aspath_unintern(&attr.aspath);
8086 bgp_redistribute_delete(bgp, p, type, instance);
8087 return;
8088 }
8089 }
8090
8091 if (bgp_in_graceful_shutdown(bgp))
8092 bgp_attr_add_gshut_community(&attr_new);
8093
8094 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8095 SAFI_UNICAST, p, NULL);
8096
8097 new_attr = bgp_attr_intern(&attr_new);
8098
8099 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8100 if (bpi->peer == bgp->peer_self
8101 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8102 break;
8103
8104 if (bpi) {
8105 /* Ensure the (source route) type is updated. */
8106 bpi->type = type;
8107 if (attrhash_cmp(bpi->attr, new_attr)
8108 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8109 bgp_attr_unintern(&new_attr);
8110 aspath_unintern(&attr.aspath);
8111 bgp_dest_unlock_node(bn);
8112 return;
8113 } else {
8114 /* The attribute is changed. */
8115 bgp_path_info_set_flag(bn, bpi,
8116 BGP_PATH_ATTR_CHANGED);
8117
8118 /* Rewrite BGP route information. */
8119 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8120 bgp_path_info_restore(bn, bpi);
8121 else
8122 bgp_aggregate_decrement(
8123 bgp, p, bpi, afi, SAFI_UNICAST);
8124 bgp_attr_unintern(&bpi->attr);
8125 bpi->attr = new_attr;
8126 bpi->uptime = bgp_clock();
8127
8128 /* Process change. */
8129 bgp_aggregate_increment(bgp, p, bpi, afi,
8130 SAFI_UNICAST);
8131 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8132 bgp_dest_unlock_node(bn);
8133 aspath_unintern(&attr.aspath);
8134
8135 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8136 || (bgp->inst_type
8137 == BGP_INSTANCE_TYPE_DEFAULT)) {
8138
8139 vpn_leak_from_vrf_update(
8140 bgp_get_default(), bgp, bpi);
8141 }
8142 return;
8143 }
8144 }
8145
8146 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8147 bgp->peer_self, new_attr, bn);
8148 SET_FLAG(new->flags, BGP_PATH_VALID);
8149
8150 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8151 bgp_path_info_add(bn, new);
8152 bgp_dest_unlock_node(bn);
8153 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8154
8155 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8156 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8157
8158 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8159 }
8160 }
8161
8162 /* Unintern original. */
8163 aspath_unintern(&attr.aspath);
8164 }
8165
8166 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8167 unsigned short instance)
8168 {
8169 afi_t afi;
8170 struct bgp_dest *dest;
8171 struct bgp_path_info *pi;
8172 struct bgp_redist *red;
8173
8174 afi = family2afi(p->family);
8175
8176 red = bgp_redist_lookup(bgp, afi, type, instance);
8177 if (red) {
8178 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8179 SAFI_UNICAST, p, NULL);
8180
8181 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8182 if (pi->peer == bgp->peer_self && pi->type == type)
8183 break;
8184
8185 if (pi) {
8186 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8187 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8188
8189 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8190 bgp, pi);
8191 }
8192 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8193 bgp_path_info_delete(dest, pi);
8194 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8195 }
8196 bgp_dest_unlock_node(dest);
8197 }
8198 }
8199
8200 /* Withdraw specified route type's route. */
8201 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8202 unsigned short instance)
8203 {
8204 struct bgp_dest *dest;
8205 struct bgp_path_info *pi;
8206 struct bgp_table *table;
8207
8208 table = bgp->rib[afi][SAFI_UNICAST];
8209
8210 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8211 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8212 if (pi->peer == bgp->peer_self && pi->type == type
8213 && pi->instance == instance)
8214 break;
8215
8216 if (pi) {
8217 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8218 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8219
8220 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8221 bgp, pi);
8222 }
8223 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8224 pi, afi, SAFI_UNICAST);
8225 bgp_path_info_delete(dest, pi);
8226 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8227 }
8228 }
8229 }
8230
8231 /* Static function to display route. */
8232 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8233 struct vty *vty, json_object *json, bool wide)
8234 {
8235 int len = 0;
8236 char buf[BUFSIZ];
8237 char buf2[BUFSIZ];
8238
8239 if (p->family == AF_INET) {
8240 if (!json) {
8241 len = vty_out(vty, "%pFX", p);
8242 } else {
8243 json_object_string_add(json, "prefix",
8244 inet_ntop(p->family,
8245 &p->u.prefix, buf,
8246 BUFSIZ));
8247 json_object_int_add(json, "prefixLen", p->prefixlen);
8248 prefix2str(p, buf2, PREFIX_STRLEN);
8249 json_object_string_add(json, "network", buf2);
8250 json_object_int_add(json, "version", dest->version);
8251 }
8252 } else if (p->family == AF_ETHERNET) {
8253 len = vty_out(vty, "%pFX", p);
8254 } else if (p->family == AF_EVPN) {
8255 if (!json)
8256 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8257 else
8258 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8259 } else if (p->family == AF_FLOWSPEC) {
8260 route_vty_out_flowspec(vty, p, NULL,
8261 json ?
8262 NLRI_STRING_FORMAT_JSON_SIMPLE :
8263 NLRI_STRING_FORMAT_MIN, json);
8264 } else {
8265 if (!json)
8266 len = vty_out(vty, "%pFX", p);
8267 else {
8268 json_object_string_add(json, "prefix",
8269 inet_ntop(p->family,
8270 &p->u.prefix, buf,
8271 BUFSIZ));
8272 json_object_int_add(json, "prefixLen", p->prefixlen);
8273 prefix2str(p, buf2, PREFIX_STRLEN);
8274 json_object_string_add(json, "network", buf2);
8275 json_object_int_add(json, "version", dest->version);
8276 }
8277 }
8278
8279 if (!json) {
8280 len = wide ? (45 - len) : (17 - len);
8281 if (len < 1)
8282 vty_out(vty, "\n%*s", 20, " ");
8283 else
8284 vty_out(vty, "%*s", len, " ");
8285 }
8286 }
8287
8288 enum bgp_display_type {
8289 normal_list,
8290 };
8291
8292 static const char *
8293 bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8294 {
8295 switch (reason) {
8296 case bgp_path_selection_none:
8297 return "Nothing to Select";
8298 case bgp_path_selection_first:
8299 return "First path received";
8300 case bgp_path_selection_evpn_sticky_mac:
8301 return "EVPN Sticky Mac";
8302 case bgp_path_selection_evpn_seq:
8303 return "EVPN sequence number";
8304 case bgp_path_selection_evpn_lower_ip:
8305 return "EVPN lower IP";
8306 case bgp_path_selection_evpn_local_path:
8307 return "EVPN local ES path";
8308 case bgp_path_selection_evpn_non_proxy:
8309 return "EVPN non proxy";
8310 case bgp_path_selection_weight:
8311 return "Weight";
8312 case bgp_path_selection_local_pref:
8313 return "Local Pref";
8314 case bgp_path_selection_local_route:
8315 return "Local Route";
8316 case bgp_path_selection_confed_as_path:
8317 return "Confederation based AS Path";
8318 case bgp_path_selection_as_path:
8319 return "AS Path";
8320 case bgp_path_selection_origin:
8321 return "Origin";
8322 case bgp_path_selection_med:
8323 return "MED";
8324 case bgp_path_selection_peer:
8325 return "Peer Type";
8326 case bgp_path_selection_confed:
8327 return "Confed Peer Type";
8328 case bgp_path_selection_igp_metric:
8329 return "IGP Metric";
8330 case bgp_path_selection_older:
8331 return "Older Path";
8332 case bgp_path_selection_router_id:
8333 return "Router ID";
8334 case bgp_path_selection_cluster_length:
8335 return "Cluster length";
8336 case bgp_path_selection_stale:
8337 return "Path Staleness";
8338 case bgp_path_selection_local_configured:
8339 return "Locally configured route";
8340 case bgp_path_selection_neighbor_ip:
8341 return "Neighbor IP";
8342 case bgp_path_selection_default:
8343 return "Nothing left to compare";
8344 }
8345 return "Invalid (internal error)";
8346 }
8347
8348 /* Print the short form route status for a bgp_path_info */
8349 static void route_vty_short_status_out(struct vty *vty,
8350 struct bgp_path_info *path,
8351 const struct prefix *p,
8352 json_object *json_path)
8353 {
8354 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8355
8356 if (json_path) {
8357
8358 /* Route status display. */
8359 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8360 json_object_boolean_true_add(json_path, "removed");
8361
8362 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8363 json_object_boolean_true_add(json_path, "stale");
8364
8365 if (path->extra && bgp_path_suppressed(path))
8366 json_object_boolean_true_add(json_path, "suppressed");
8367
8368 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8369 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8370 json_object_boolean_true_add(json_path, "valid");
8371
8372 /* Selected */
8373 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8374 json_object_boolean_true_add(json_path, "history");
8375
8376 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8377 json_object_boolean_true_add(json_path, "damped");
8378
8379 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8380 json_object_boolean_true_add(json_path, "bestpath");
8381 json_object_string_add(json_path, "selectionReason",
8382 bgp_path_selection_reason2str(
8383 path->net->reason));
8384 }
8385
8386 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8387 json_object_boolean_true_add(json_path, "multipath");
8388
8389 /* Internal route. */
8390 if ((path->peer->as)
8391 && (path->peer->as == path->peer->local_as))
8392 json_object_string_add(json_path, "pathFrom",
8393 "internal");
8394 else
8395 json_object_string_add(json_path, "pathFrom",
8396 "external");
8397
8398 return;
8399 }
8400
8401 /* RPKI validation state */
8402 rpki_state =
8403 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
8404
8405 if (rpki_state == RPKI_VALID)
8406 vty_out(vty, "V");
8407 else if (rpki_state == RPKI_INVALID)
8408 vty_out(vty, "I");
8409 else if (rpki_state == RPKI_NOTFOUND)
8410 vty_out(vty, "N");
8411
8412 /* Route status display. */
8413 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8414 vty_out(vty, "R");
8415 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8416 vty_out(vty, "S");
8417 else if (bgp_path_suppressed(path))
8418 vty_out(vty, "s");
8419 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8420 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8421 vty_out(vty, "*");
8422 else
8423 vty_out(vty, " ");
8424
8425 /* Selected */
8426 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8427 vty_out(vty, "h");
8428 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8429 vty_out(vty, "d");
8430 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8431 vty_out(vty, ">");
8432 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8433 vty_out(vty, "=");
8434 else
8435 vty_out(vty, " ");
8436
8437 /* Internal route. */
8438 if (path->peer && (path->peer->as)
8439 && (path->peer->as == path->peer->local_as))
8440 vty_out(vty, "i");
8441 else
8442 vty_out(vty, " ");
8443 }
8444
8445 static char *bgp_nexthop_hostname(struct peer *peer,
8446 struct bgp_nexthop_cache *bnc)
8447 {
8448 if (peer->hostname
8449 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8450 return peer->hostname;
8451 return NULL;
8452 }
8453
8454 /* called from terminal list command */
8455 void route_vty_out(struct vty *vty, const struct prefix *p,
8456 struct bgp_path_info *path, int display, safi_t safi,
8457 json_object *json_paths, bool wide)
8458 {
8459 int len;
8460 struct attr *attr = path->attr;
8461 json_object *json_path = NULL;
8462 json_object *json_nexthops = NULL;
8463 json_object *json_nexthop_global = NULL;
8464 json_object *json_nexthop_ll = NULL;
8465 json_object *json_ext_community = NULL;
8466 char vrf_id_str[VRF_NAMSIZ] = {0};
8467 bool nexthop_self =
8468 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8469 bool nexthop_othervrf = false;
8470 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8471 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8472 char *nexthop_hostname =
8473 bgp_nexthop_hostname(path->peer, path->nexthop);
8474 char esi_buf[ESI_STR_LEN];
8475
8476 if (json_paths)
8477 json_path = json_object_new_object();
8478
8479 /* short status lead text */
8480 route_vty_short_status_out(vty, path, p, json_path);
8481
8482 if (!json_paths) {
8483 /* print prefix and mask */
8484 if (!display)
8485 route_vty_out_route(path->net, p, vty, json_path, wide);
8486 else
8487 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8488 } else {
8489 route_vty_out_route(path->net, p, vty, json_path, wide);
8490 }
8491
8492 /*
8493 * If vrf id of nexthop is different from that of prefix,
8494 * set up printable string to append
8495 */
8496 if (path->extra && path->extra->bgp_orig) {
8497 const char *self = "";
8498
8499 if (nexthop_self)
8500 self = "<";
8501
8502 nexthop_othervrf = true;
8503 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8504
8505 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8506 snprintf(vrf_id_str, sizeof(vrf_id_str),
8507 "@%s%s", VRFID_NONE_STR, self);
8508 else
8509 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8510 path->extra->bgp_orig->vrf_id, self);
8511
8512 if (path->extra->bgp_orig->inst_type
8513 != BGP_INSTANCE_TYPE_DEFAULT)
8514
8515 nexthop_vrfname = path->extra->bgp_orig->name;
8516 } else {
8517 const char *self = "";
8518
8519 if (nexthop_self)
8520 self = "<";
8521
8522 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8523 }
8524
8525 /*
8526 * For ENCAP and EVPN routes, nexthop address family is not
8527 * neccessarily the same as the prefix address family.
8528 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
8529 * EVPN routes are also exchanged with a MP nexthop. Currently,
8530 * this
8531 * is only IPv4, the value will be present in either
8532 * attr->nexthop or
8533 * attr->mp_nexthop_global_in
8534 */
8535 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
8536 char buf[BUFSIZ];
8537 char nexthop[128];
8538 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8539
8540 switch (af) {
8541 case AF_INET:
8542 snprintf(nexthop, sizeof(nexthop), "%s",
8543 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
8544 BUFSIZ));
8545 break;
8546 case AF_INET6:
8547 snprintf(nexthop, sizeof(nexthop), "%s",
8548 inet_ntop(af, &attr->mp_nexthop_global, buf,
8549 BUFSIZ));
8550 break;
8551 default:
8552 snprintf(nexthop, sizeof(nexthop), "?");
8553 break;
8554 }
8555
8556 if (json_paths) {
8557 json_nexthop_global = json_object_new_object();
8558
8559 json_object_string_add(json_nexthop_global, "ip",
8560 nexthop);
8561
8562 if (path->peer->hostname)
8563 json_object_string_add(json_nexthop_global,
8564 "hostname",
8565 path->peer->hostname);
8566
8567 json_object_string_add(json_nexthop_global, "afi",
8568 (af == AF_INET) ? "ipv4"
8569 : "ipv6");
8570 json_object_boolean_true_add(json_nexthop_global,
8571 "used");
8572 } else {
8573 if (nexthop_hostname)
8574 len = vty_out(vty, "%s(%s)%s", nexthop,
8575 nexthop_hostname, vrf_id_str);
8576 else
8577 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
8578
8579 len = wide ? (41 - len) : (16 - len);
8580 if (len < 1)
8581 vty_out(vty, "\n%*s", 36, " ");
8582 else
8583 vty_out(vty, "%*s", len, " ");
8584 }
8585 } else if (safi == SAFI_EVPN) {
8586 if (json_paths) {
8587 char buf[BUFSIZ] = {0};
8588
8589 json_nexthop_global = json_object_new_object();
8590
8591 json_object_string_add(json_nexthop_global, "ip",
8592 inet_ntop(AF_INET,
8593 &attr->nexthop, buf,
8594 sizeof(buf)));
8595
8596 if (path->peer->hostname)
8597 json_object_string_add(json_nexthop_global,
8598 "hostname",
8599 path->peer->hostname);
8600
8601 json_object_string_add(json_nexthop_global, "afi",
8602 "ipv4");
8603 json_object_boolean_true_add(json_nexthop_global,
8604 "used");
8605 } else {
8606 if (nexthop_hostname)
8607 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8608 nexthop_hostname, vrf_id_str);
8609 else
8610 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8611 vrf_id_str);
8612
8613 len = wide ? (41 - len) : (16 - len);
8614 if (len < 1)
8615 vty_out(vty, "\n%*s", 36, " ");
8616 else
8617 vty_out(vty, "%*s", len, " ");
8618 }
8619 } else if (safi == SAFI_FLOWSPEC) {
8620 if (attr->nexthop.s_addr != INADDR_ANY) {
8621 if (json_paths) {
8622 char buf[BUFSIZ] = {0};
8623
8624 json_nexthop_global = json_object_new_object();
8625
8626 json_object_string_add(json_nexthop_global,
8627 "afi", "ipv4");
8628 json_object_string_add(
8629 json_nexthop_global, "ip",
8630 inet_ntop(AF_INET, &attr->nexthop, buf,
8631 sizeof(buf)));
8632
8633 if (path->peer->hostname)
8634 json_object_string_add(
8635 json_nexthop_global, "hostname",
8636 path->peer->hostname);
8637
8638 json_object_boolean_true_add(
8639 json_nexthop_global,
8640 "used");
8641 } else {
8642 if (nexthop_hostname)
8643 len = vty_out(vty, "%pI4(%s)%s",
8644 &attr->nexthop,
8645 nexthop_hostname,
8646 vrf_id_str);
8647 else
8648 len = vty_out(vty, "%pI4%s",
8649 &attr->nexthop,
8650 vrf_id_str);
8651
8652 len = wide ? (41 - len) : (16 - len);
8653 if (len < 1)
8654 vty_out(vty, "\n%*s", 36, " ");
8655 else
8656 vty_out(vty, "%*s", len, " ");
8657 }
8658 }
8659 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8660 if (json_paths) {
8661 char buf[BUFSIZ] = {0};
8662
8663 json_nexthop_global = json_object_new_object();
8664
8665 json_object_string_add(json_nexthop_global, "ip",
8666 inet_ntop(AF_INET,
8667 &attr->nexthop, buf,
8668 sizeof(buf)));
8669
8670 if (path->peer->hostname)
8671 json_object_string_add(json_nexthop_global,
8672 "hostname",
8673 path->peer->hostname);
8674
8675 json_object_string_add(json_nexthop_global, "afi",
8676 "ipv4");
8677 json_object_boolean_true_add(json_nexthop_global,
8678 "used");
8679 } else {
8680 if (nexthop_hostname)
8681 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8682 nexthop_hostname, vrf_id_str);
8683 else
8684 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8685 vrf_id_str);
8686
8687 len = wide ? (41 - len) : (16 - len);
8688 if (len < 1)
8689 vty_out(vty, "\n%*s", 36, " ");
8690 else
8691 vty_out(vty, "%*s", len, " ");
8692 }
8693 }
8694
8695 /* IPv6 Next Hop */
8696 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8697 char buf[BUFSIZ];
8698
8699 if (json_paths) {
8700 json_nexthop_global = json_object_new_object();
8701 json_object_string_add(
8702 json_nexthop_global, "ip",
8703 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8704 buf, BUFSIZ));
8705
8706 if (path->peer->hostname)
8707 json_object_string_add(json_nexthop_global,
8708 "hostname",
8709 path->peer->hostname);
8710
8711 json_object_string_add(json_nexthop_global, "afi",
8712 "ipv6");
8713 json_object_string_add(json_nexthop_global, "scope",
8714 "global");
8715
8716 /* We display both LL & GL if both have been
8717 * received */
8718 if ((attr->mp_nexthop_len
8719 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8720 || (path->peer->conf_if)) {
8721 json_nexthop_ll = json_object_new_object();
8722 json_object_string_add(
8723 json_nexthop_ll, "ip",
8724 inet_ntop(AF_INET6,
8725 &attr->mp_nexthop_local, buf,
8726 BUFSIZ));
8727
8728 if (path->peer->hostname)
8729 json_object_string_add(
8730 json_nexthop_ll, "hostname",
8731 path->peer->hostname);
8732
8733 json_object_string_add(json_nexthop_ll, "afi",
8734 "ipv6");
8735 json_object_string_add(json_nexthop_ll, "scope",
8736 "link-local");
8737
8738 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
8739 &attr->mp_nexthop_local)
8740 != 0)
8741 && !attr->mp_nexthop_prefer_global)
8742 json_object_boolean_true_add(
8743 json_nexthop_ll, "used");
8744 else
8745 json_object_boolean_true_add(
8746 json_nexthop_global, "used");
8747 } else
8748 json_object_boolean_true_add(
8749 json_nexthop_global, "used");
8750 } else {
8751 /* Display LL if LL/Global both in table unless
8752 * prefer-global is set */
8753 if (((attr->mp_nexthop_len
8754 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8755 && !attr->mp_nexthop_prefer_global)
8756 || (path->peer->conf_if)) {
8757 if (path->peer->conf_if) {
8758 len = vty_out(vty, "%s",
8759 path->peer->conf_if);
8760 /* len of IPv6 addr + max len of def
8761 * ifname */
8762 len = wide ? (41 - len) : (16 - len);
8763
8764 if (len < 1)
8765 vty_out(vty, "\n%*s", 36, " ");
8766 else
8767 vty_out(vty, "%*s", len, " ");
8768 } else {
8769 if (nexthop_hostname)
8770 len = vty_out(
8771 vty, "%pI6(%s)%s",
8772 &attr->mp_nexthop_local,
8773 nexthop_hostname,
8774 vrf_id_str);
8775 else
8776 len = vty_out(
8777 vty, "%pI6%s",
8778 &attr->mp_nexthop_local,
8779 vrf_id_str);
8780
8781 len = wide ? (41 - len) : (16 - len);
8782
8783 if (len < 1)
8784 vty_out(vty, "\n%*s", 36, " ");
8785 else
8786 vty_out(vty, "%*s", len, " ");
8787 }
8788 } else {
8789 if (nexthop_hostname)
8790 len = vty_out(vty, "%pI6(%s)%s",
8791 &attr->mp_nexthop_global,
8792 nexthop_hostname,
8793 vrf_id_str);
8794 else
8795 len = vty_out(vty, "%pI6%s",
8796 &attr->mp_nexthop_global,
8797 vrf_id_str);
8798
8799 len = wide ? (41 - len) : (16 - len);
8800
8801 if (len < 1)
8802 vty_out(vty, "\n%*s", 36, " ");
8803 else
8804 vty_out(vty, "%*s", len, " ");
8805 }
8806 }
8807 }
8808
8809 /* MED/Metric */
8810 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8811 if (json_paths)
8812 json_object_int_add(json_path, "metric", attr->med);
8813 else if (wide)
8814 vty_out(vty, "%7u", attr->med);
8815 else
8816 vty_out(vty, "%10u", attr->med);
8817 else if (!json_paths) {
8818 if (wide)
8819 vty_out(vty, "%*s", 7, " ");
8820 else
8821 vty_out(vty, "%*s", 10, " ");
8822 }
8823
8824 /* Local Pref */
8825 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8826 if (json_paths)
8827 json_object_int_add(json_path, "locPrf",
8828 attr->local_pref);
8829 else
8830 vty_out(vty, "%7u", attr->local_pref);
8831 else if (!json_paths)
8832 vty_out(vty, " ");
8833
8834 if (json_paths)
8835 json_object_int_add(json_path, "weight", attr->weight);
8836 else
8837 vty_out(vty, "%7u ", attr->weight);
8838
8839 if (json_paths) {
8840 char buf[BUFSIZ];
8841 json_object_string_add(
8842 json_path, "peerId",
8843 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
8844 }
8845
8846 /* Print aspath */
8847 if (attr->aspath) {
8848 if (json_paths)
8849 json_object_string_add(json_path, "path",
8850 attr->aspath->str);
8851 else
8852 aspath_print_vty(vty, "%s", attr->aspath, " ");
8853 }
8854
8855 /* Print origin */
8856 if (json_paths)
8857 json_object_string_add(json_path, "origin",
8858 bgp_origin_long_str[attr->origin]);
8859 else
8860 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8861
8862 if (json_paths) {
8863 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8864 json_object_string_add(json_path, "esi",
8865 esi_to_str(&attr->esi,
8866 esi_buf, sizeof(esi_buf)));
8867 }
8868 if (safi == SAFI_EVPN &&
8869 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8870 json_ext_community = json_object_new_object();
8871 json_object_string_add(json_ext_community,
8872 "string",
8873 attr->ecommunity->str);
8874 json_object_object_add(json_path,
8875 "extendedCommunity",
8876 json_ext_community);
8877 }
8878
8879 if (nexthop_self)
8880 json_object_boolean_true_add(json_path,
8881 "announceNexthopSelf");
8882 if (nexthop_othervrf) {
8883 json_object_string_add(json_path, "nhVrfName",
8884 nexthop_vrfname);
8885
8886 json_object_int_add(json_path, "nhVrfId",
8887 ((nexthop_vrfid == VRF_UNKNOWN)
8888 ? -1
8889 : (int)nexthop_vrfid));
8890 }
8891 }
8892
8893 if (json_paths) {
8894 if (json_nexthop_global || json_nexthop_ll) {
8895 json_nexthops = json_object_new_array();
8896
8897 if (json_nexthop_global)
8898 json_object_array_add(json_nexthops,
8899 json_nexthop_global);
8900
8901 if (json_nexthop_ll)
8902 json_object_array_add(json_nexthops,
8903 json_nexthop_ll);
8904
8905 json_object_object_add(json_path, "nexthops",
8906 json_nexthops);
8907 }
8908
8909 json_object_array_add(json_paths, json_path);
8910 } else {
8911 vty_out(vty, "\n");
8912
8913 if (safi == SAFI_EVPN) {
8914 struct bgp_path_es_info *path_es_info = NULL;
8915
8916 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8917 /* XXX - add these params to the json out */
8918 vty_out(vty, "%*s", 20, " ");
8919 vty_out(vty, "ESI:%s",
8920 esi_to_str(&attr->esi, esi_buf,
8921 sizeof(esi_buf)));
8922
8923 if (path->extra && path->extra->mh_info)
8924 path_es_info =
8925 path->extra->mh_info->es_info;
8926
8927 if (path_es_info && path_es_info->es)
8928 vty_out(vty, " VNI: %u",
8929 path_es_info->vni);
8930 vty_out(vty, "\n");
8931 }
8932 if (attr->flag &
8933 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8934 vty_out(vty, "%*s", 20, " ");
8935 vty_out(vty, "%s\n", attr->ecommunity->str);
8936 }
8937 }
8938
8939 #ifdef ENABLE_BGP_VNC
8940 /* prints an additional line, indented, with VNC info, if
8941 * present */
8942 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
8943 rfapi_vty_out_vncinfo(vty, p, path, safi);
8944 #endif
8945 }
8946 }
8947
8948 /* called from terminal list command */
8949 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
8950 const struct prefix *p, struct attr *attr, safi_t safi,
8951 bool use_json, json_object *json_ar, bool wide)
8952 {
8953 json_object *json_status = NULL;
8954 json_object *json_net = NULL;
8955 int len;
8956 char buff[BUFSIZ];
8957
8958 /* Route status display. */
8959 if (use_json) {
8960 json_status = json_object_new_object();
8961 json_net = json_object_new_object();
8962 } else {
8963 vty_out(vty, "*");
8964 vty_out(vty, ">");
8965 vty_out(vty, " ");
8966 }
8967
8968 /* print prefix and mask */
8969 if (use_json) {
8970 if (safi == SAFI_EVPN)
8971 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
8972 else if (p->family == AF_INET || p->family == AF_INET6) {
8973 json_object_string_add(
8974 json_net, "addrPrefix",
8975 inet_ntop(p->family, &p->u.prefix, buff,
8976 BUFSIZ));
8977 json_object_int_add(json_net, "prefixLen",
8978 p->prefixlen);
8979 prefix2str(p, buff, PREFIX_STRLEN);
8980 json_object_string_add(json_net, "network", buff);
8981 }
8982 } else
8983 route_vty_out_route(dest, p, vty, NULL, wide);
8984
8985 /* Print attribute */
8986 if (attr) {
8987 if (use_json) {
8988 char buf[BUFSIZ] = {0};
8989
8990 if (p->family == AF_INET
8991 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
8992 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
8993 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
8994 json_object_string_add(
8995 json_net, "nextHop",
8996 inet_ntop(
8997 AF_INET,
8998 &attr->mp_nexthop_global_in,
8999 buf, sizeof(buf)));
9000 else
9001 json_object_string_add(
9002 json_net, "nextHop",
9003 inet_ntop(AF_INET,
9004 &attr->nexthop, buf,
9005 sizeof(buf)));
9006 } else if (p->family == AF_INET6
9007 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9008 char buf[BUFSIZ];
9009
9010 json_object_string_add(
9011 json_net, "nextHopGlobal",
9012 inet_ntop(AF_INET6,
9013 &attr->mp_nexthop_global, buf,
9014 BUFSIZ));
9015 } else if (p->family == AF_EVPN
9016 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9017 char buf[BUFSIZ] = {0};
9018
9019 json_object_string_add(
9020 json_net, "nextHop",
9021 inet_ntop(AF_INET,
9022 &attr->mp_nexthop_global_in,
9023 buf, sizeof(buf)));
9024 }
9025
9026 if (attr->flag
9027 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9028 json_object_int_add(json_net, "metric",
9029 attr->med);
9030
9031 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9032 json_object_int_add(json_net, "locPrf",
9033 attr->local_pref);
9034
9035 json_object_int_add(json_net, "weight", attr->weight);
9036
9037 /* Print aspath */
9038 if (attr->aspath)
9039 json_object_string_add(json_net, "path",
9040 attr->aspath->str);
9041
9042 /* Print origin */
9043 json_object_string_add(json_net, "bgpOriginCode",
9044 bgp_origin_str[attr->origin]);
9045 } else {
9046 if (p->family == AF_INET
9047 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9048 || safi == SAFI_EVPN
9049 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9050 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9051 || safi == SAFI_EVPN)
9052 vty_out(vty, "%-16pI4",
9053 &attr->mp_nexthop_global_in);
9054 else if (wide)
9055 vty_out(vty, "%-41pI4", &attr->nexthop);
9056 else
9057 vty_out(vty, "%-16pI4", &attr->nexthop);
9058 } else if (p->family == AF_INET6
9059 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9060 char buf[BUFSIZ];
9061
9062 len = vty_out(
9063 vty, "%s",
9064 inet_ntop(AF_INET6,
9065 &attr->mp_nexthop_global, buf,
9066 BUFSIZ));
9067 len = wide ? (41 - len) : (16 - len);
9068 if (len < 1)
9069 vty_out(vty, "\n%*s", 36, " ");
9070 else
9071 vty_out(vty, "%*s", len, " ");
9072 }
9073 if (attr->flag
9074 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9075 if (wide)
9076 vty_out(vty, "%7u", attr->med);
9077 else
9078 vty_out(vty, "%10u", attr->med);
9079 else if (wide)
9080 vty_out(vty, " ");
9081 else
9082 vty_out(vty, " ");
9083
9084 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9085 vty_out(vty, "%7u", attr->local_pref);
9086 else
9087 vty_out(vty, " ");
9088
9089 vty_out(vty, "%7u ", attr->weight);
9090
9091 /* Print aspath */
9092 if (attr->aspath)
9093 aspath_print_vty(vty, "%s", attr->aspath, " ");
9094
9095 /* Print origin */
9096 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9097 }
9098 }
9099 if (use_json) {
9100 json_object_boolean_true_add(json_status, "*");
9101 json_object_boolean_true_add(json_status, ">");
9102 json_object_object_add(json_net, "appliedStatusSymbols",
9103 json_status);
9104
9105 prefix2str(p, buff, PREFIX_STRLEN);
9106 json_object_object_add(json_ar, buff, json_net);
9107 } else
9108 vty_out(vty, "\n");
9109 }
9110
9111 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9112 struct bgp_path_info *path, int display, safi_t safi,
9113 json_object *json)
9114 {
9115 json_object *json_out = NULL;
9116 struct attr *attr;
9117 mpls_label_t label = MPLS_INVALID_LABEL;
9118
9119 if (!path->extra)
9120 return;
9121
9122 if (json)
9123 json_out = json_object_new_object();
9124
9125 /* short status lead text */
9126 route_vty_short_status_out(vty, path, p, json_out);
9127
9128 /* print prefix and mask */
9129 if (json == NULL) {
9130 if (!display)
9131 route_vty_out_route(path->net, p, vty, NULL, false);
9132 else
9133 vty_out(vty, "%*s", 17, " ");
9134 }
9135
9136 /* Print attribute */
9137 attr = path->attr;
9138 if (((p->family == AF_INET)
9139 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9140 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9141 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9142 char buf[BUFSIZ] = {0};
9143
9144 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9145 || safi == SAFI_EVPN) {
9146 if (json)
9147 json_object_string_add(
9148 json_out, "mpNexthopGlobalIn",
9149 inet_ntop(AF_INET,
9150 &attr->mp_nexthop_global_in,
9151 buf, sizeof(buf)));
9152 else
9153 vty_out(vty, "%-16pI4",
9154 &attr->mp_nexthop_global_in);
9155 } else {
9156 if (json)
9157 json_object_string_add(
9158 json_out, "nexthop",
9159 inet_ntop(AF_INET, &attr->nexthop, buf,
9160 sizeof(buf)));
9161 else
9162 vty_out(vty, "%-16pI4", &attr->nexthop);
9163 }
9164 } else if (((p->family == AF_INET6)
9165 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9166 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9167 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9168 char buf_a[512];
9169
9170 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9171 if (json)
9172 json_object_string_add(
9173 json_out, "mpNexthopGlobalIn",
9174 inet_ntop(AF_INET6,
9175 &attr->mp_nexthop_global,
9176 buf_a, sizeof(buf_a)));
9177 else
9178 vty_out(vty, "%s",
9179 inet_ntop(AF_INET6,
9180 &attr->mp_nexthop_global,
9181 buf_a, sizeof(buf_a)));
9182 } else if (attr->mp_nexthop_len
9183 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9184 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9185 &attr->mp_nexthop_global,
9186 &attr->mp_nexthop_local);
9187 if (json)
9188 json_object_string_add(json_out,
9189 "mpNexthopGlobalLocal",
9190 buf_a);
9191 else
9192 vty_out(vty, "%s", buf_a);
9193 }
9194 }
9195
9196 label = decode_label(&path->extra->label[0]);
9197
9198 if (bgp_is_valid_label(&label)) {
9199 if (json) {
9200 json_object_int_add(json_out, "notag", label);
9201 json_object_array_add(json, json_out);
9202 } else {
9203 vty_out(vty, "notag/%d", label);
9204 vty_out(vty, "\n");
9205 }
9206 }
9207 }
9208
9209 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9210 struct bgp_path_info *path, int display,
9211 json_object *json_paths)
9212 {
9213 struct attr *attr;
9214 char buf[BUFSIZ] = {0};
9215 json_object *json_path = NULL;
9216 json_object *json_nexthop = NULL;
9217 json_object *json_overlay = NULL;
9218
9219 if (!path->extra)
9220 return;
9221
9222 if (json_paths) {
9223 json_path = json_object_new_object();
9224 json_overlay = json_object_new_object();
9225 json_nexthop = json_object_new_object();
9226 }
9227
9228 /* short status lead text */
9229 route_vty_short_status_out(vty, path, p, json_path);
9230
9231 /* print prefix and mask */
9232 if (!display)
9233 route_vty_out_route(path->net, p, vty, json_path, false);
9234 else
9235 vty_out(vty, "%*s", 17, " ");
9236
9237 /* Print attribute */
9238 attr = path->attr;
9239 char buf1[BUFSIZ];
9240 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9241
9242 switch (af) {
9243 case AF_INET:
9244 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
9245 if (!json_path) {
9246 vty_out(vty, "%-16s", buf);
9247 } else {
9248 json_object_string_add(json_nexthop, "ip", buf);
9249
9250 json_object_string_add(json_nexthop, "afi", "ipv4");
9251
9252 json_object_object_add(json_path, "nexthop",
9253 json_nexthop);
9254 }
9255 break;
9256 case AF_INET6:
9257 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
9258 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
9259 if (!json_path) {
9260 vty_out(vty, "%s(%s)", buf, buf1);
9261 } else {
9262 json_object_string_add(json_nexthop, "ipv6Global", buf);
9263
9264 json_object_string_add(json_nexthop, "ipv6LinkLocal",
9265 buf1);
9266
9267 json_object_string_add(json_nexthop, "afi", "ipv6");
9268
9269 json_object_object_add(json_path, "nexthop",
9270 json_nexthop);
9271 }
9272 break;
9273 default:
9274 if (!json_path) {
9275 vty_out(vty, "?");
9276 } else {
9277 json_object_string_add(json_nexthop, "Error",
9278 "Unsupported address-family");
9279 }
9280 }
9281
9282 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9283
9284 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p))
9285 inet_ntop(AF_INET, &eo->gw_ip.ipv4, buf, BUFSIZ);
9286 else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p))
9287 inet_ntop(AF_INET6, &eo->gw_ip.ipv6, buf, BUFSIZ);
9288
9289 if (!json_path)
9290 vty_out(vty, "/%s", buf);
9291 else
9292 json_object_string_add(json_overlay, "gw", buf);
9293
9294 if (attr->ecommunity) {
9295 char *mac = NULL;
9296 struct ecommunity_val *routermac = ecommunity_lookup(
9297 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
9298 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9299
9300 if (routermac)
9301 mac = ecom_mac2str((char *)routermac->val);
9302 if (mac) {
9303 if (!json_path) {
9304 vty_out(vty, "/%s", mac);
9305 } else {
9306 json_object_string_add(json_overlay, "rmac",
9307 mac);
9308 }
9309 XFREE(MTYPE_TMP, mac);
9310 }
9311 }
9312
9313 if (!json_path) {
9314 vty_out(vty, "\n");
9315 } else {
9316 json_object_object_add(json_path, "overlay", json_overlay);
9317
9318 json_object_array_add(json_paths, json_path);
9319 }
9320 }
9321
9322 /* dampening route */
9323 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9324 struct bgp_path_info *path, int display,
9325 afi_t afi, safi_t safi, bool use_json,
9326 json_object *json)
9327 {
9328 struct attr *attr;
9329 int len;
9330 char timebuf[BGP_UPTIME_LEN];
9331
9332 /* short status lead text */
9333 route_vty_short_status_out(vty, path, p, json);
9334
9335 /* print prefix and mask */
9336 if (!use_json) {
9337 if (!display)
9338 route_vty_out_route(path->net, p, vty, NULL, false);
9339 else
9340 vty_out(vty, "%*s", 17, " ");
9341 }
9342
9343 len = vty_out(vty, "%s", path->peer->host);
9344 len = 17 - len;
9345 if (len < 1) {
9346 if (!use_json)
9347 vty_out(vty, "\n%*s", 34, " ");
9348 } else {
9349 if (use_json)
9350 json_object_int_add(json, "peerHost", len);
9351 else
9352 vty_out(vty, "%*s", len, " ");
9353 }
9354
9355 if (use_json)
9356 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9357 safi, use_json, json);
9358 else
9359 vty_out(vty, "%s ",
9360 bgp_damp_reuse_time_vty(vty, path, timebuf,
9361 BGP_UPTIME_LEN, afi, safi,
9362 use_json, json));
9363
9364 /* Print attribute */
9365 attr = path->attr;
9366
9367 /* Print aspath */
9368 if (attr->aspath) {
9369 if (use_json)
9370 json_object_string_add(json, "asPath",
9371 attr->aspath->str);
9372 else
9373 aspath_print_vty(vty, "%s", attr->aspath, " ");
9374 }
9375
9376 /* Print origin */
9377 if (use_json)
9378 json_object_string_add(json, "origin",
9379 bgp_origin_str[attr->origin]);
9380 else
9381 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9382
9383 if (!use_json)
9384 vty_out(vty, "\n");
9385 }
9386
9387 /* flap route */
9388 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9389 struct bgp_path_info *path, int display,
9390 afi_t afi, safi_t safi, bool use_json,
9391 json_object *json)
9392 {
9393 struct attr *attr;
9394 struct bgp_damp_info *bdi;
9395 char timebuf[BGP_UPTIME_LEN];
9396 int len;
9397
9398 if (!path->extra)
9399 return;
9400
9401 bdi = path->extra->damp_info;
9402
9403 /* short status lead text */
9404 route_vty_short_status_out(vty, path, p, json);
9405
9406 /* print prefix and mask */
9407 if (!use_json) {
9408 if (!display)
9409 route_vty_out_route(path->net, p, vty, NULL, false);
9410 else
9411 vty_out(vty, "%*s", 17, " ");
9412 }
9413
9414 len = vty_out(vty, "%s", path->peer->host);
9415 len = 16 - len;
9416 if (len < 1) {
9417 if (!use_json)
9418 vty_out(vty, "\n%*s", 33, " ");
9419 } else {
9420 if (use_json)
9421 json_object_int_add(json, "peerHost", len);
9422 else
9423 vty_out(vty, "%*s", len, " ");
9424 }
9425
9426 len = vty_out(vty, "%d", bdi->flap);
9427 len = 5 - len;
9428 if (len < 1) {
9429 if (!use_json)
9430 vty_out(vty, " ");
9431 } else {
9432 if (use_json)
9433 json_object_int_add(json, "bdiFlap", len);
9434 else
9435 vty_out(vty, "%*s", len, " ");
9436 }
9437
9438 if (use_json)
9439 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9440 json);
9441 else
9442 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9443 BGP_UPTIME_LEN, 0, NULL));
9444
9445 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9446 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9447 if (use_json)
9448 bgp_damp_reuse_time_vty(vty, path, timebuf,
9449 BGP_UPTIME_LEN, afi, safi,
9450 use_json, json);
9451 else
9452 vty_out(vty, "%s ",
9453 bgp_damp_reuse_time_vty(vty, path, timebuf,
9454 BGP_UPTIME_LEN, afi,
9455 safi, use_json, json));
9456 } else {
9457 if (!use_json)
9458 vty_out(vty, "%*s ", 8, " ");
9459 }
9460
9461 /* Print attribute */
9462 attr = path->attr;
9463
9464 /* Print aspath */
9465 if (attr->aspath) {
9466 if (use_json)
9467 json_object_string_add(json, "asPath",
9468 attr->aspath->str);
9469 else
9470 aspath_print_vty(vty, "%s", attr->aspath, " ");
9471 }
9472
9473 /* Print origin */
9474 if (use_json)
9475 json_object_string_add(json, "origin",
9476 bgp_origin_str[attr->origin]);
9477 else
9478 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9479
9480 if (!use_json)
9481 vty_out(vty, "\n");
9482 }
9483
9484 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9485 int *first, const char *header,
9486 json_object *json_adv_to)
9487 {
9488 char buf1[INET6_ADDRSTRLEN];
9489 json_object *json_peer = NULL;
9490
9491 if (json_adv_to) {
9492 /* 'advertised-to' is a dictionary of peers we have advertised
9493 * this
9494 * prefix too. The key is the peer's IP or swpX, the value is
9495 * the
9496 * hostname if we know it and "" if not.
9497 */
9498 json_peer = json_object_new_object();
9499
9500 if (peer->hostname)
9501 json_object_string_add(json_peer, "hostname",
9502 peer->hostname);
9503
9504 if (peer->conf_if)
9505 json_object_object_add(json_adv_to, peer->conf_if,
9506 json_peer);
9507 else
9508 json_object_object_add(
9509 json_adv_to,
9510 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
9511 json_peer);
9512 } else {
9513 if (*first) {
9514 vty_out(vty, "%s", header);
9515 *first = 0;
9516 }
9517
9518 if (peer->hostname
9519 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9520 if (peer->conf_if)
9521 vty_out(vty, " %s(%s)", peer->hostname,
9522 peer->conf_if);
9523 else
9524 vty_out(vty, " %s(%s)", peer->hostname,
9525 sockunion2str(&peer->su, buf1,
9526 SU_ADDRSTRLEN));
9527 } else {
9528 if (peer->conf_if)
9529 vty_out(vty, " %s", peer->conf_if);
9530 else
9531 vty_out(vty, " %s",
9532 sockunion2str(&peer->su, buf1,
9533 SU_ADDRSTRLEN));
9534 }
9535 }
9536 }
9537
9538 static void route_vty_out_tx_ids(struct vty *vty,
9539 struct bgp_addpath_info_data *d)
9540 {
9541 int i;
9542
9543 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9544 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9545 d->addpath_tx_id[i],
9546 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9547 }
9548 }
9549
9550 static void route_vty_out_detail_es_info(struct vty *vty,
9551 struct bgp_path_info *pi,
9552 struct attr *attr,
9553 json_object *json_path)
9554 {
9555 char esi_buf[ESI_STR_LEN];
9556 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9557 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9558 ATTR_ES_PEER_ROUTER);
9559 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9560 ATTR_ES_PEER_ACTIVE);
9561 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9562 ATTR_ES_PEER_PROXY);
9563 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9564 if (json_path) {
9565 json_object *json_es_info = NULL;
9566
9567 json_object_string_add(
9568 json_path, "esi",
9569 esi_buf);
9570 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9571 json_es_info = json_object_new_object();
9572 if (es_local)
9573 json_object_boolean_true_add(
9574 json_es_info, "localEs");
9575 if (peer_active)
9576 json_object_boolean_true_add(
9577 json_es_info, "peerActive");
9578 if (peer_proxy)
9579 json_object_boolean_true_add(
9580 json_es_info, "peerProxy");
9581 if (peer_router)
9582 json_object_boolean_true_add(
9583 json_es_info, "peerRouter");
9584 if (attr->mm_sync_seqnum)
9585 json_object_int_add(
9586 json_es_info, "peerSeq",
9587 attr->mm_sync_seqnum);
9588 json_object_object_add(
9589 json_path, "es_info",
9590 json_es_info);
9591 }
9592 } else {
9593 if (bgp_evpn_attr_is_sync(attr))
9594 vty_out(vty,
9595 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9596 esi_buf,
9597 es_local ? "local-es":"",
9598 peer_proxy ? "proxy " : "",
9599 peer_active ? "active ":"",
9600 peer_router ? "router ":"",
9601 attr->mm_sync_seqnum);
9602 else
9603 vty_out(vty, " ESI %s %s\n",
9604 esi_buf,
9605 es_local ? "local-es":"");
9606 }
9607 }
9608
9609 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
9610 struct bgp_path_info *path, afi_t afi, safi_t safi,
9611 enum rpki_states rpki_curr_state,
9612 json_object *json_paths)
9613 {
9614 char buf[INET6_ADDRSTRLEN];
9615 char buf1[BUFSIZ];
9616 struct attr *attr = path->attr;
9617 int sockunion_vty_out(struct vty *, union sockunion *);
9618 time_t tbuf;
9619 json_object *json_bestpath = NULL;
9620 json_object *json_cluster_list = NULL;
9621 json_object *json_cluster_list_list = NULL;
9622 json_object *json_ext_community = NULL;
9623 json_object *json_last_update = NULL;
9624 json_object *json_pmsi = NULL;
9625 json_object *json_nexthop_global = NULL;
9626 json_object *json_nexthop_ll = NULL;
9627 json_object *json_nexthops = NULL;
9628 json_object *json_path = NULL;
9629 json_object *json_peer = NULL;
9630 json_object *json_string = NULL;
9631 json_object *json_adv_to = NULL;
9632 int first = 0;
9633 struct listnode *node, *nnode;
9634 struct peer *peer;
9635 int addpath_capable;
9636 int has_adj;
9637 unsigned int first_as;
9638 bool nexthop_self =
9639 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9640 int i;
9641 char *nexthop_hostname =
9642 bgp_nexthop_hostname(path->peer, path->nexthop);
9643
9644 if (json_paths) {
9645 json_path = json_object_new_object();
9646 json_peer = json_object_new_object();
9647 json_nexthop_global = json_object_new_object();
9648 }
9649
9650 if (path->extra) {
9651 char tag_buf[30];
9652
9653 tag_buf[0] = '\0';
9654 if (path->extra && path->extra->num_labels) {
9655 bgp_evpn_label2str(path->extra->label,
9656 path->extra->num_labels, tag_buf,
9657 sizeof(tag_buf));
9658 }
9659 if (safi == SAFI_EVPN) {
9660 if (!json_paths) {
9661 vty_out(vty, " Route %pFX",
9662 (struct prefix_evpn *)
9663 bgp_dest_get_prefix(bn));
9664 if (tag_buf[0] != '\0')
9665 vty_out(vty, " VNI %s", tag_buf);
9666 vty_out(vty, "\n");
9667 } else {
9668 if (tag_buf[0])
9669 json_object_string_add(json_path, "VNI",
9670 tag_buf);
9671 }
9672 }
9673
9674 if (path->extra && path->extra->parent && !json_paths) {
9675 struct bgp_path_info *parent_ri;
9676 struct bgp_dest *dest, *pdest;
9677
9678 parent_ri = (struct bgp_path_info *)path->extra->parent;
9679 dest = parent_ri->net;
9680 if (dest && dest->pdest) {
9681 pdest = dest->pdest;
9682 prefix_rd2str(
9683 (struct prefix_rd *)bgp_dest_get_prefix(
9684 pdest),
9685 buf1, sizeof(buf1));
9686 if (is_pi_family_evpn(parent_ri)) {
9687 vty_out(vty,
9688 " Imported from %s:%pFX, VNI %s",
9689 buf1,
9690 (struct prefix_evpn *)
9691 bgp_dest_get_prefix(
9692 dest),
9693 tag_buf);
9694 if (attr->es_flags & ATTR_ES_L3_NHG)
9695 vty_out(vty, ", L3NHG %s",
9696 (attr->es_flags
9697 & ATTR_ES_L3_NHG_ACTIVE)
9698 ? "active"
9699 : "inactive");
9700 vty_out(vty, "\n");
9701
9702 } else
9703 vty_out(vty,
9704 " Imported from %s:%pFX\n",
9705 buf1,
9706 (struct prefix_evpn *)
9707 bgp_dest_get_prefix(
9708 dest));
9709 }
9710 }
9711 }
9712
9713 /* Line1 display AS-path, Aggregator */
9714 if (attr->aspath) {
9715 if (json_paths) {
9716 if (!attr->aspath->json)
9717 aspath_str_update(attr->aspath, true);
9718 json_object_lock(attr->aspath->json);
9719 json_object_object_add(json_path, "aspath",
9720 attr->aspath->json);
9721 } else {
9722 if (attr->aspath->segments)
9723 aspath_print_vty(vty, " %s", attr->aspath, "");
9724 else
9725 vty_out(vty, " Local");
9726 }
9727 }
9728
9729 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9730 if (json_paths)
9731 json_object_boolean_true_add(json_path, "removed");
9732 else
9733 vty_out(vty, ", (removed)");
9734 }
9735
9736 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9737 if (json_paths)
9738 json_object_boolean_true_add(json_path, "stale");
9739 else
9740 vty_out(vty, ", (stale)");
9741 }
9742
9743 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
9744 if (json_paths) {
9745 char buf[BUFSIZ] = {0};
9746
9747 json_object_int_add(json_path, "aggregatorAs",
9748 attr->aggregator_as);
9749 json_object_string_add(json_path, "aggregatorId",
9750 inet_ntop(AF_INET,
9751 &attr->aggregator_addr,
9752 buf, sizeof(buf)));
9753 } else {
9754 vty_out(vty, ", (aggregated by %u %pI4)",
9755 attr->aggregator_as, &attr->aggregator_addr);
9756 }
9757 }
9758
9759 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9760 PEER_FLAG_REFLECTOR_CLIENT)) {
9761 if (json_paths)
9762 json_object_boolean_true_add(json_path,
9763 "rxedFromRrClient");
9764 else
9765 vty_out(vty, ", (Received from a RR-client)");
9766 }
9767
9768 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9769 PEER_FLAG_RSERVER_CLIENT)) {
9770 if (json_paths)
9771 json_object_boolean_true_add(json_path,
9772 "rxedFromRsClient");
9773 else
9774 vty_out(vty, ", (Received from a RS-client)");
9775 }
9776
9777 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9778 if (json_paths)
9779 json_object_boolean_true_add(json_path,
9780 "dampeningHistoryEntry");
9781 else
9782 vty_out(vty, ", (history entry)");
9783 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
9784 if (json_paths)
9785 json_object_boolean_true_add(json_path,
9786 "dampeningSuppressed");
9787 else
9788 vty_out(vty, ", (suppressed due to dampening)");
9789 }
9790
9791 if (!json_paths)
9792 vty_out(vty, "\n");
9793
9794 /* Line2 display Next-hop, Neighbor, Router-id */
9795 /* Display the nexthop */
9796 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
9797
9798 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
9799 || bn_p->family == AF_EVPN)
9800 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
9801 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9802 char buf[BUFSIZ] = {0};
9803
9804 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9805 || safi == SAFI_EVPN) {
9806 if (json_paths) {
9807 json_object_string_add(
9808 json_nexthop_global, "ip",
9809 inet_ntop(AF_INET,
9810 &attr->mp_nexthop_global_in,
9811 buf, sizeof(buf)));
9812
9813 if (path->peer->hostname)
9814 json_object_string_add(
9815 json_nexthop_global, "hostname",
9816 path->peer->hostname);
9817 } else {
9818 if (nexthop_hostname)
9819 vty_out(vty, " %pI4(%s)",
9820 &attr->mp_nexthop_global_in,
9821 nexthop_hostname);
9822 else
9823 vty_out(vty, " %pI4",
9824 &attr->mp_nexthop_global_in);
9825 }
9826 } else {
9827 if (json_paths) {
9828 json_object_string_add(
9829 json_nexthop_global, "ip",
9830 inet_ntop(AF_INET, &attr->nexthop, buf,
9831 sizeof(buf)));
9832
9833 if (path->peer->hostname)
9834 json_object_string_add(
9835 json_nexthop_global, "hostname",
9836 path->peer->hostname);
9837 } else {
9838 if (nexthop_hostname)
9839 vty_out(vty, " %pI4(%s)",
9840 &attr->nexthop,
9841 nexthop_hostname);
9842 else
9843 vty_out(vty, " %pI4",
9844 &attr->nexthop);
9845 }
9846 }
9847
9848 if (json_paths)
9849 json_object_string_add(json_nexthop_global, "afi",
9850 "ipv4");
9851 } else {
9852 if (json_paths) {
9853 json_object_string_add(
9854 json_nexthop_global, "ip",
9855 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
9856 buf, INET6_ADDRSTRLEN));
9857
9858 if (path->peer->hostname)
9859 json_object_string_add(json_nexthop_global,
9860 "hostname",
9861 path->peer->hostname);
9862
9863 json_object_string_add(json_nexthop_global, "afi",
9864 "ipv6");
9865 json_object_string_add(json_nexthop_global, "scope",
9866 "global");
9867 } else {
9868 if (nexthop_hostname)
9869 vty_out(vty, " %pI6(%s)",
9870 &attr->mp_nexthop_global,
9871 nexthop_hostname);
9872 else
9873 vty_out(vty, " %pI6",
9874 &attr->mp_nexthop_global);
9875 }
9876 }
9877
9878 /* Display the IGP cost or 'inaccessible' */
9879 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9880 if (json_paths)
9881 json_object_boolean_false_add(json_nexthop_global,
9882 "accessible");
9883 else
9884 vty_out(vty, " (inaccessible)");
9885 } else {
9886 if (path->extra && path->extra->igpmetric) {
9887 if (json_paths)
9888 json_object_int_add(json_nexthop_global,
9889 "metric",
9890 path->extra->igpmetric);
9891 else
9892 vty_out(vty, " (metric %u)",
9893 path->extra->igpmetric);
9894 }
9895
9896 /* IGP cost is 0, display this only for json */
9897 else {
9898 if (json_paths)
9899 json_object_int_add(json_nexthop_global,
9900 "metric", 0);
9901 }
9902
9903 if (json_paths)
9904 json_object_boolean_true_add(json_nexthop_global,
9905 "accessible");
9906 }
9907
9908 /* Display peer "from" output */
9909 /* This path was originated locally */
9910 if (path->peer == bgp->peer_self) {
9911
9912 if (safi == SAFI_EVPN
9913 || (bn_p->family == AF_INET
9914 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9915 if (json_paths)
9916 json_object_string_add(json_peer, "peerId",
9917 "0.0.0.0");
9918 else
9919 vty_out(vty, " from 0.0.0.0 ");
9920 } else {
9921 if (json_paths)
9922 json_object_string_add(json_peer, "peerId",
9923 "::");
9924 else
9925 vty_out(vty, " from :: ");
9926 }
9927
9928 if (json_paths) {
9929 char buf[BUFSIZ] = {0};
9930
9931 json_object_string_add(json_peer, "routerId",
9932 inet_ntop(AF_INET,
9933 &bgp->router_id, buf,
9934 sizeof(buf)));
9935 } else {
9936 vty_out(vty, "(%pI4)", &bgp->router_id);
9937 }
9938 }
9939
9940 /* We RXed this path from one of our peers */
9941 else {
9942
9943 if (json_paths) {
9944 json_object_string_add(json_peer, "peerId",
9945 sockunion2str(&path->peer->su,
9946 buf,
9947 SU_ADDRSTRLEN));
9948 json_object_string_add(json_peer, "routerId",
9949 inet_ntop(AF_INET,
9950 &path->peer->remote_id,
9951 buf1, sizeof(buf1)));
9952
9953 if (path->peer->hostname)
9954 json_object_string_add(json_peer, "hostname",
9955 path->peer->hostname);
9956
9957 if (path->peer->domainname)
9958 json_object_string_add(json_peer, "domainname",
9959 path->peer->domainname);
9960
9961 if (path->peer->conf_if)
9962 json_object_string_add(json_peer, "interface",
9963 path->peer->conf_if);
9964 } else {
9965 if (path->peer->conf_if) {
9966 if (path->peer->hostname
9967 && CHECK_FLAG(path->peer->bgp->flags,
9968 BGP_FLAG_SHOW_HOSTNAME))
9969 vty_out(vty, " from %s(%s)",
9970 path->peer->hostname,
9971 path->peer->conf_if);
9972 else
9973 vty_out(vty, " from %s",
9974 path->peer->conf_if);
9975 } else {
9976 if (path->peer->hostname
9977 && CHECK_FLAG(path->peer->bgp->flags,
9978 BGP_FLAG_SHOW_HOSTNAME))
9979 vty_out(vty, " from %s(%s)",
9980 path->peer->hostname,
9981 path->peer->host);
9982 else
9983 vty_out(vty, " from %s",
9984 sockunion2str(&path->peer->su,
9985 buf,
9986 SU_ADDRSTRLEN));
9987 }
9988
9989 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
9990 vty_out(vty, " (%pI4)", &attr->originator_id);
9991 else
9992 vty_out(vty, " (%s)",
9993 inet_ntop(AF_INET,
9994 &path->peer->remote_id, buf1,
9995 sizeof(buf1)));
9996 }
9997 }
9998
9999 /*
10000 * Note when vrfid of nexthop is different from that of prefix
10001 */
10002 if (path->extra && path->extra->bgp_orig) {
10003 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10004
10005 if (json_paths) {
10006 const char *vn;
10007
10008 if (path->extra->bgp_orig->inst_type
10009 == BGP_INSTANCE_TYPE_DEFAULT)
10010 vn = VRF_DEFAULT_NAME;
10011 else
10012 vn = path->extra->bgp_orig->name;
10013
10014 json_object_string_add(json_path, "nhVrfName", vn);
10015
10016 if (nexthop_vrfid == VRF_UNKNOWN) {
10017 json_object_int_add(json_path, "nhVrfId", -1);
10018 } else {
10019 json_object_int_add(json_path, "nhVrfId",
10020 (int)nexthop_vrfid);
10021 }
10022 } else {
10023 if (nexthop_vrfid == VRF_UNKNOWN)
10024 vty_out(vty, " vrf ?");
10025 else {
10026 struct vrf *vrf;
10027
10028 vrf = vrf_lookup_by_id(nexthop_vrfid);
10029 vty_out(vty, " vrf %s(%u)",
10030 VRF_LOGNAME(vrf), nexthop_vrfid);
10031 }
10032 }
10033 }
10034
10035 if (nexthop_self) {
10036 if (json_paths) {
10037 json_object_boolean_true_add(json_path,
10038 "announceNexthopSelf");
10039 } else {
10040 vty_out(vty, " announce-nh-self");
10041 }
10042 }
10043
10044 if (!json_paths)
10045 vty_out(vty, "\n");
10046
10047 /* display the link-local nexthop */
10048 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10049 if (json_paths) {
10050 json_nexthop_ll = json_object_new_object();
10051 json_object_string_add(
10052 json_nexthop_ll, "ip",
10053 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10054 buf, INET6_ADDRSTRLEN));
10055
10056 if (path->peer->hostname)
10057 json_object_string_add(json_nexthop_ll,
10058 "hostname",
10059 path->peer->hostname);
10060
10061 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10062 json_object_string_add(json_nexthop_ll, "scope",
10063 "link-local");
10064
10065 json_object_boolean_true_add(json_nexthop_ll,
10066 "accessible");
10067
10068 if (!attr->mp_nexthop_prefer_global)
10069 json_object_boolean_true_add(json_nexthop_ll,
10070 "used");
10071 else
10072 json_object_boolean_true_add(
10073 json_nexthop_global, "used");
10074 } else {
10075 vty_out(vty, " (%s) %s\n",
10076 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10077 buf, INET6_ADDRSTRLEN),
10078 attr->mp_nexthop_prefer_global
10079 ? "(prefer-global)"
10080 : "(used)");
10081 }
10082 }
10083 /* If we do not have a link-local nexthop then we must flag the
10084 global as "used" */
10085 else {
10086 if (json_paths)
10087 json_object_boolean_true_add(json_nexthop_global,
10088 "used");
10089 }
10090
10091 if (safi == SAFI_EVPN &&
10092 bgp_evpn_is_esi_valid(&attr->esi)) {
10093 route_vty_out_detail_es_info(vty, path, attr, json_path);
10094 }
10095
10096 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10097 * Int/Ext/Local, Atomic, best */
10098 if (json_paths)
10099 json_object_string_add(json_path, "origin",
10100 bgp_origin_long_str[attr->origin]);
10101 else
10102 vty_out(vty, " Origin %s",
10103 bgp_origin_long_str[attr->origin]);
10104
10105 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10106 if (json_paths)
10107 json_object_int_add(json_path, "metric", attr->med);
10108 else
10109 vty_out(vty, ", metric %u", attr->med);
10110 }
10111
10112 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10113 if (json_paths)
10114 json_object_int_add(json_path, "locPrf",
10115 attr->local_pref);
10116 else
10117 vty_out(vty, ", localpref %u", attr->local_pref);
10118 }
10119
10120 if (attr->weight != 0) {
10121 if (json_paths)
10122 json_object_int_add(json_path, "weight", attr->weight);
10123 else
10124 vty_out(vty, ", weight %u", attr->weight);
10125 }
10126
10127 if (attr->tag != 0) {
10128 if (json_paths)
10129 json_object_int_add(json_path, "tag", attr->tag);
10130 else
10131 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10132 }
10133
10134 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10135 if (json_paths)
10136 json_object_boolean_false_add(json_path, "valid");
10137 else
10138 vty_out(vty, ", invalid");
10139 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10140 if (json_paths)
10141 json_object_boolean_true_add(json_path, "valid");
10142 else
10143 vty_out(vty, ", valid");
10144 }
10145
10146 if (json_paths)
10147 json_object_int_add(json_path, "version", bn->version);
10148
10149 if (path->peer != bgp->peer_self) {
10150 if (path->peer->as == path->peer->local_as) {
10151 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10152 if (json_paths)
10153 json_object_string_add(
10154 json_peer, "type",
10155 "confed-internal");
10156 else
10157 vty_out(vty, ", confed-internal");
10158 } else {
10159 if (json_paths)
10160 json_object_string_add(
10161 json_peer, "type", "internal");
10162 else
10163 vty_out(vty, ", internal");
10164 }
10165 } else {
10166 if (bgp_confederation_peers_check(bgp,
10167 path->peer->as)) {
10168 if (json_paths)
10169 json_object_string_add(
10170 json_peer, "type",
10171 "confed-external");
10172 else
10173 vty_out(vty, ", confed-external");
10174 } else {
10175 if (json_paths)
10176 json_object_string_add(
10177 json_peer, "type", "external");
10178 else
10179 vty_out(vty, ", external");
10180 }
10181 }
10182 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10183 if (json_paths) {
10184 json_object_boolean_true_add(json_path, "aggregated");
10185 json_object_boolean_true_add(json_path, "local");
10186 } else {
10187 vty_out(vty, ", aggregated, local");
10188 }
10189 } else if (path->type != ZEBRA_ROUTE_BGP) {
10190 if (json_paths)
10191 json_object_boolean_true_add(json_path, "sourced");
10192 else
10193 vty_out(vty, ", sourced");
10194 } else {
10195 if (json_paths) {
10196 json_object_boolean_true_add(json_path, "sourced");
10197 json_object_boolean_true_add(json_path, "local");
10198 } else {
10199 vty_out(vty, ", sourced, local");
10200 }
10201 }
10202
10203 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10204 if (json_paths)
10205 json_object_boolean_true_add(json_path,
10206 "atomicAggregate");
10207 else
10208 vty_out(vty, ", atomic-aggregate");
10209 }
10210
10211 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10212 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10213 && bgp_path_info_mpath_count(path))) {
10214 if (json_paths)
10215 json_object_boolean_true_add(json_path, "multipath");
10216 else
10217 vty_out(vty, ", multipath");
10218 }
10219
10220 // Mark the bestpath(s)
10221 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10222 first_as = aspath_get_first_as(attr->aspath);
10223
10224 if (json_paths) {
10225 if (!json_bestpath)
10226 json_bestpath = json_object_new_object();
10227 json_object_int_add(json_bestpath, "bestpathFromAs",
10228 first_as);
10229 } else {
10230 if (first_as)
10231 vty_out(vty, ", bestpath-from-AS %u", first_as);
10232 else
10233 vty_out(vty, ", bestpath-from-AS Local");
10234 }
10235 }
10236
10237 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10238 if (json_paths) {
10239 if (!json_bestpath)
10240 json_bestpath = json_object_new_object();
10241 json_object_boolean_true_add(json_bestpath, "overall");
10242 json_object_string_add(
10243 json_bestpath, "selectionReason",
10244 bgp_path_selection_reason2str(bn->reason));
10245 } else {
10246 vty_out(vty, ", best");
10247 vty_out(vty, " (%s)",
10248 bgp_path_selection_reason2str(bn->reason));
10249 }
10250 }
10251
10252 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10253 if (json_paths)
10254 json_object_string_add(
10255 json_path, "rpkiValidationState",
10256 bgp_rpki_validation2str(rpki_curr_state));
10257 else
10258 vty_out(vty, ", rpki validation-state: %s",
10259 bgp_rpki_validation2str(rpki_curr_state));
10260 }
10261
10262 if (json_bestpath)
10263 json_object_object_add(json_path, "bestpath", json_bestpath);
10264
10265 if (!json_paths)
10266 vty_out(vty, "\n");
10267
10268 /* Line 4 display Community */
10269 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10270 if (json_paths) {
10271 if (!attr->community->json)
10272 community_str(attr->community, true);
10273 json_object_lock(attr->community->json);
10274 json_object_object_add(json_path, "community",
10275 attr->community->json);
10276 } else {
10277 vty_out(vty, " Community: %s\n",
10278 attr->community->str);
10279 }
10280 }
10281
10282 /* Line 5 display Extended-community */
10283 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10284 if (json_paths) {
10285 json_ext_community = json_object_new_object();
10286 json_object_string_add(json_ext_community, "string",
10287 attr->ecommunity->str);
10288 json_object_object_add(json_path, "extendedCommunity",
10289 json_ext_community);
10290 } else {
10291 vty_out(vty, " Extended Community: %s\n",
10292 attr->ecommunity->str);
10293 }
10294 }
10295
10296 /* Line 6 display Large community */
10297 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10298 if (json_paths) {
10299 if (!attr->lcommunity->json)
10300 lcommunity_str(attr->lcommunity, true);
10301 json_object_lock(attr->lcommunity->json);
10302 json_object_object_add(json_path, "largeCommunity",
10303 attr->lcommunity->json);
10304 } else {
10305 vty_out(vty, " Large Community: %s\n",
10306 attr->lcommunity->str);
10307 }
10308 }
10309
10310 /* Line 7 display Originator, Cluster-id */
10311 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10312 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10313 char buf[BUFSIZ] = {0};
10314
10315 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10316 if (json_paths)
10317 json_object_string_add(
10318 json_path, "originatorId",
10319 inet_ntop(AF_INET, &attr->originator_id,
10320 buf, sizeof(buf)));
10321 else
10322 vty_out(vty, " Originator: %pI4",
10323 &attr->originator_id);
10324 }
10325
10326 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10327 struct cluster_list *cluster =
10328 bgp_attr_get_cluster(attr);
10329 int i;
10330
10331 if (json_paths) {
10332 json_cluster_list = json_object_new_object();
10333 json_cluster_list_list =
10334 json_object_new_array();
10335
10336 for (i = 0; i < cluster->length / 4; i++) {
10337 json_string = json_object_new_string(
10338 inet_ntop(AF_INET,
10339 &cluster->list[i],
10340 buf, sizeof(buf)));
10341 json_object_array_add(
10342 json_cluster_list_list,
10343 json_string);
10344 }
10345
10346 /*
10347 * struct cluster_list does not have
10348 * "str" variable like aspath and community
10349 * do. Add this someday if someone asks
10350 * for it.
10351 * json_object_string_add(json_cluster_list,
10352 * "string", cluster->str);
10353 */
10354 json_object_object_add(json_cluster_list,
10355 "list",
10356 json_cluster_list_list);
10357 json_object_object_add(json_path, "clusterList",
10358 json_cluster_list);
10359 } else {
10360 vty_out(vty, ", Cluster list: ");
10361
10362 for (i = 0; i < cluster->length / 4; i++) {
10363 vty_out(vty, "%pI4 ",
10364 &cluster->list[i]);
10365 }
10366 }
10367 }
10368
10369 if (!json_paths)
10370 vty_out(vty, "\n");
10371 }
10372
10373 if (path->extra && path->extra->damp_info)
10374 bgp_damp_info_vty(vty, bgp, path, afi, safi, json_path);
10375
10376 /* Remote Label */
10377 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10378 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10379 mpls_label_t label = label_pton(&path->extra->label[0]);
10380
10381 if (json_paths)
10382 json_object_int_add(json_path, "remoteLabel", label);
10383 else
10384 vty_out(vty, " Remote label: %d\n", label);
10385 }
10386
10387 /* Remote SID */
10388 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10389 inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf));
10390 if (json_paths)
10391 json_object_string_add(json_path, "remoteSid", buf);
10392 else
10393 vty_out(vty, " Remote SID: %s\n", buf);
10394 }
10395
10396 /* Label Index */
10397 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10398 if (json_paths)
10399 json_object_int_add(json_path, "labelIndex",
10400 attr->label_index);
10401 else
10402 vty_out(vty, " Label Index: %d\n",
10403 attr->label_index);
10404 }
10405
10406 /* Line 8 display Addpath IDs */
10407 if (path->addpath_rx_id
10408 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10409 if (json_paths) {
10410 json_object_int_add(json_path, "addpathRxId",
10411 path->addpath_rx_id);
10412
10413 /* Keep backwards compatibility with the old API
10414 * by putting TX All's ID in the old field
10415 */
10416 json_object_int_add(
10417 json_path, "addpathTxId",
10418 path->tx_addpath
10419 .addpath_tx_id[BGP_ADDPATH_ALL]);
10420
10421 /* ... but create a specific field for each
10422 * strategy
10423 */
10424 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10425 json_object_int_add(
10426 json_path,
10427 bgp_addpath_names(i)->id_json_name,
10428 path->tx_addpath.addpath_tx_id[i]);
10429 }
10430 } else {
10431 vty_out(vty, " AddPath ID: RX %u, ",
10432 path->addpath_rx_id);
10433
10434 route_vty_out_tx_ids(vty, &path->tx_addpath);
10435 }
10436 }
10437
10438 /* If we used addpath to TX a non-bestpath we need to display
10439 * "Advertised to" on a path-by-path basis
10440 */
10441 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10442 first = 1;
10443
10444 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10445 addpath_capable =
10446 bgp_addpath_encode_tx(peer, afi, safi);
10447 has_adj = bgp_adj_out_lookup(
10448 peer, path->net,
10449 bgp_addpath_id_for_peer(peer, afi, safi,
10450 &path->tx_addpath));
10451
10452 if ((addpath_capable && has_adj)
10453 || (!addpath_capable && has_adj
10454 && CHECK_FLAG(path->flags,
10455 BGP_PATH_SELECTED))) {
10456 if (json_path && !json_adv_to)
10457 json_adv_to = json_object_new_object();
10458
10459 route_vty_out_advertised_to(
10460 vty, peer, &first,
10461 " Advertised to:", json_adv_to);
10462 }
10463 }
10464
10465 if (json_path) {
10466 if (json_adv_to) {
10467 json_object_object_add(
10468 json_path, "advertisedTo", json_adv_to);
10469 }
10470 } else {
10471 if (!first) {
10472 vty_out(vty, "\n");
10473 }
10474 }
10475 }
10476
10477 /* Line 9 display Uptime */
10478 tbuf = time(NULL) - (bgp_clock() - path->uptime);
10479 if (json_paths) {
10480 json_last_update = json_object_new_object();
10481 json_object_int_add(json_last_update, "epoch", tbuf);
10482 json_object_string_add(json_last_update, "string",
10483 ctime(&tbuf));
10484 json_object_object_add(json_path, "lastUpdate",
10485 json_last_update);
10486 } else
10487 vty_out(vty, " Last update: %s", ctime(&tbuf));
10488
10489 /* Line 10 display PMSI tunnel attribute, if present */
10490 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10491 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10492 bgp_attr_get_pmsi_tnl_type(attr),
10493 PMSI_TNLTYPE_STR_DEFAULT);
10494
10495 if (json_paths) {
10496 json_pmsi = json_object_new_object();
10497 json_object_string_add(json_pmsi, "tunnelType", str);
10498 json_object_int_add(json_pmsi, "label",
10499 label2vni(&attr->label));
10500 json_object_object_add(json_path, "pmsi", json_pmsi);
10501 } else
10502 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10503 str, label2vni(&attr->label));
10504 }
10505
10506 /* Output some debug about internal state of the dest flags */
10507 if (json_paths) {
10508 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10509 json_object_boolean_true_add(json_path, "processScheduled");
10510 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10511 json_object_boolean_true_add(json_path, "userCleared");
10512 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10513 json_object_boolean_true_add(json_path, "labelChanged");
10514 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10515 json_object_boolean_true_add(json_path, "registeredForLabel");
10516 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10517 json_object_boolean_true_add(json_path, "selectDefered");
10518 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10519 json_object_boolean_true_add(json_path, "fibInstalled");
10520 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10521 json_object_boolean_true_add(json_path, "fibPending");
10522 }
10523
10524 /* We've constructed the json object for this path, add it to the json
10525 * array of paths
10526 */
10527 if (json_paths) {
10528 if (json_nexthop_global || json_nexthop_ll) {
10529 json_nexthops = json_object_new_array();
10530
10531 if (json_nexthop_global)
10532 json_object_array_add(json_nexthops,
10533 json_nexthop_global);
10534
10535 if (json_nexthop_ll)
10536 json_object_array_add(json_nexthops,
10537 json_nexthop_ll);
10538
10539 json_object_object_add(json_path, "nexthops",
10540 json_nexthops);
10541 }
10542
10543 json_object_object_add(json_path, "peer", json_peer);
10544 json_object_array_add(json_paths, json_path);
10545 }
10546 }
10547
10548 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10549 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10550 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10551
10552 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10553 const char *prefix_list_str, afi_t afi,
10554 safi_t safi, enum bgp_show_type type);
10555 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10556 const char *filter, afi_t afi, safi_t safi,
10557 enum bgp_show_type type);
10558 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10559 const char *rmap_str, afi_t afi, safi_t safi,
10560 enum bgp_show_type type);
10561 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10562 const char *com, int exact, afi_t afi,
10563 safi_t safi);
10564 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10565 const char *prefix, afi_t afi, safi_t safi,
10566 enum bgp_show_type type);
10567 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10568 afi_t afi, safi_t safi, enum bgp_show_type type,
10569 bool use_json);
10570 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10571 const char *comstr, int exact, afi_t afi,
10572 safi_t safi, uint8_t show_flags);
10573
10574 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10575 struct bgp_table *table, enum bgp_show_type type,
10576 void *output_arg, char *rd, int is_last,
10577 unsigned long *output_cum, unsigned long *total_cum,
10578 unsigned long *json_header_depth, uint8_t show_flags,
10579 enum rpki_states rpki_target_state)
10580 {
10581 struct bgp_path_info *pi;
10582 struct bgp_dest *dest;
10583 int header = 1;
10584 int display;
10585 unsigned long output_count = 0;
10586 unsigned long total_count = 0;
10587 struct prefix *p;
10588 json_object *json_paths = NULL;
10589 int first = 1;
10590 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10591 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10592 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10593
10594 if (output_cum && *output_cum != 0)
10595 header = 0;
10596
10597 if (use_json && !*json_header_depth) {
10598 if (all)
10599 *json_header_depth = 1;
10600 else {
10601 vty_out(vty, "{\n");
10602 *json_header_depth = 2;
10603 }
10604
10605 vty_out(vty,
10606 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10607 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10608 " \"localAS\": %u,\n \"routes\": { ",
10609 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10610 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
10611 ? VRF_DEFAULT_NAME
10612 : bgp->name,
10613 table->version, &bgp->router_id,
10614 bgp->default_local_pref, bgp->as);
10615 if (rd) {
10616 vty_out(vty, " \"routeDistinguishers\" : {");
10617 ++*json_header_depth;
10618 }
10619 }
10620
10621 if (use_json && rd) {
10622 vty_out(vty, " \"%s\" : { ", rd);
10623 }
10624
10625 /* Start processing of routes. */
10626 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
10627 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10628 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
10629
10630 pi = bgp_dest_get_bgp_path_info(dest);
10631 if (pi == NULL)
10632 continue;
10633
10634 display = 0;
10635 if (use_json)
10636 json_paths = json_object_new_array();
10637 else
10638 json_paths = NULL;
10639
10640 for (; pi; pi = pi->next) {
10641 total_count++;
10642
10643 if (type == bgp_show_type_prefix_version) {
10644 uint32_t version =
10645 strtoul(output_arg, NULL, 10);
10646 if (dest->version < version)
10647 continue;
10648 }
10649
10650 if (type == bgp_show_type_community_alias) {
10651 char *alias = output_arg;
10652 char **communities;
10653 int num;
10654 bool found = false;
10655
10656 if (pi->attr->community) {
10657 frrstr_split(pi->attr->community->str,
10658 " ", &communities, &num);
10659 for (int i = 0; i < num; i++) {
10660 const char *com2alias =
10661 bgp_community2alias(
10662 communities[i]);
10663 if (strncmp(alias, com2alias,
10664 strlen(com2alias))
10665 == 0) {
10666 found = true;
10667 break;
10668 }
10669 }
10670 }
10671
10672 if (!found && pi->attr->lcommunity) {
10673 frrstr_split(pi->attr->lcommunity->str,
10674 " ", &communities, &num);
10675 for (int i = 0; i < num; i++) {
10676 const char *com2alias =
10677 bgp_community2alias(
10678 communities[i]);
10679 if (strncmp(alias, com2alias,
10680 strlen(com2alias))
10681 == 0) {
10682 found = true;
10683 break;
10684 }
10685 }
10686 }
10687
10688 if (!found)
10689 continue;
10690 }
10691
10692 if (type == bgp_show_type_rpki) {
10693 if (dest_p->family == AF_INET
10694 || dest_p->family == AF_INET6)
10695 rpki_curr_state = hook_call(
10696 bgp_rpki_prefix_status,
10697 pi->peer, pi->attr, dest_p);
10698 if (rpki_target_state != RPKI_NOT_BEING_USED
10699 && rpki_curr_state != rpki_target_state)
10700 continue;
10701 }
10702
10703 if (type == bgp_show_type_flap_statistics
10704 || type == bgp_show_type_flap_neighbor
10705 || type == bgp_show_type_dampend_paths
10706 || type == bgp_show_type_damp_neighbor) {
10707 if (!(pi->extra && pi->extra->damp_info))
10708 continue;
10709 }
10710 if (type == bgp_show_type_regexp) {
10711 regex_t *regex = output_arg;
10712
10713 if (bgp_regexec(regex, pi->attr->aspath)
10714 == REG_NOMATCH)
10715 continue;
10716 }
10717 if (type == bgp_show_type_prefix_list) {
10718 struct prefix_list *plist = output_arg;
10719
10720 if (prefix_list_apply(plist, dest_p)
10721 != PREFIX_PERMIT)
10722 continue;
10723 }
10724 if (type == bgp_show_type_filter_list) {
10725 struct as_list *as_list = output_arg;
10726
10727 if (as_list_apply(as_list, pi->attr->aspath)
10728 != AS_FILTER_PERMIT)
10729 continue;
10730 }
10731 if (type == bgp_show_type_route_map) {
10732 struct route_map *rmap = output_arg;
10733 struct bgp_path_info path;
10734 struct attr dummy_attr;
10735 route_map_result_t ret;
10736
10737 dummy_attr = *pi->attr;
10738
10739 path.peer = pi->peer;
10740 path.attr = &dummy_attr;
10741
10742 ret = route_map_apply(rmap, dest_p, &path);
10743 if (ret == RMAP_DENYMATCH)
10744 continue;
10745 }
10746 if (type == bgp_show_type_neighbor
10747 || type == bgp_show_type_flap_neighbor
10748 || type == bgp_show_type_damp_neighbor) {
10749 union sockunion *su = output_arg;
10750
10751 if (pi->peer == NULL
10752 || pi->peer->su_remote == NULL
10753 || !sockunion_same(pi->peer->su_remote, su))
10754 continue;
10755 }
10756 if (type == bgp_show_type_cidr_only) {
10757 uint32_t destination;
10758
10759 destination = ntohl(dest_p->u.prefix4.s_addr);
10760 if (IN_CLASSC(destination)
10761 && dest_p->prefixlen == 24)
10762 continue;
10763 if (IN_CLASSB(destination)
10764 && dest_p->prefixlen == 16)
10765 continue;
10766 if (IN_CLASSA(destination)
10767 && dest_p->prefixlen == 8)
10768 continue;
10769 }
10770 if (type == bgp_show_type_prefix_longer) {
10771 p = output_arg;
10772 if (!prefix_match(p, dest_p))
10773 continue;
10774 }
10775 if (type == bgp_show_type_community_all) {
10776 if (!pi->attr->community)
10777 continue;
10778 }
10779 if (type == bgp_show_type_community) {
10780 struct community *com = output_arg;
10781
10782 if (!pi->attr->community
10783 || !community_match(pi->attr->community,
10784 com))
10785 continue;
10786 }
10787 if (type == bgp_show_type_community_exact) {
10788 struct community *com = output_arg;
10789
10790 if (!pi->attr->community
10791 || !community_cmp(pi->attr->community, com))
10792 continue;
10793 }
10794 if (type == bgp_show_type_community_list) {
10795 struct community_list *list = output_arg;
10796
10797 if (!community_list_match(pi->attr->community,
10798 list))
10799 continue;
10800 }
10801 if (type == bgp_show_type_community_list_exact) {
10802 struct community_list *list = output_arg;
10803
10804 if (!community_list_exact_match(
10805 pi->attr->community, list))
10806 continue;
10807 }
10808 if (type == bgp_show_type_lcommunity) {
10809 struct lcommunity *lcom = output_arg;
10810
10811 if (!pi->attr->lcommunity
10812 || !lcommunity_match(pi->attr->lcommunity,
10813 lcom))
10814 continue;
10815 }
10816
10817 if (type == bgp_show_type_lcommunity_exact) {
10818 struct lcommunity *lcom = output_arg;
10819
10820 if (!pi->attr->lcommunity
10821 || !lcommunity_cmp(pi->attr->lcommunity,
10822 lcom))
10823 continue;
10824 }
10825 if (type == bgp_show_type_lcommunity_list) {
10826 struct community_list *list = output_arg;
10827
10828 if (!lcommunity_list_match(pi->attr->lcommunity,
10829 list))
10830 continue;
10831 }
10832 if (type
10833 == bgp_show_type_lcommunity_list_exact) {
10834 struct community_list *list = output_arg;
10835
10836 if (!lcommunity_list_exact_match(
10837 pi->attr->lcommunity, list))
10838 continue;
10839 }
10840 if (type == bgp_show_type_lcommunity_all) {
10841 if (!pi->attr->lcommunity)
10842 continue;
10843 }
10844 if (type == bgp_show_type_dampend_paths
10845 || type == bgp_show_type_damp_neighbor) {
10846 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
10847 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10848 continue;
10849 }
10850
10851 if (!use_json && header) {
10852 vty_out(vty,
10853 "BGP table version is %" PRIu64
10854 ", local router ID is %pI4, vrf id ",
10855 table->version, &bgp->router_id);
10856 if (bgp->vrf_id == VRF_UNKNOWN)
10857 vty_out(vty, "%s", VRFID_NONE_STR);
10858 else
10859 vty_out(vty, "%u", bgp->vrf_id);
10860 vty_out(vty, "\n");
10861 vty_out(vty, "Default local pref %u, ",
10862 bgp->default_local_pref);
10863 vty_out(vty, "local AS %u\n", bgp->as);
10864 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10865 vty_out(vty, BGP_SHOW_NCODE_HEADER);
10866 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10867 vty_out(vty, BGP_SHOW_RPKI_HEADER);
10868 if (type == bgp_show_type_dampend_paths
10869 || type == bgp_show_type_damp_neighbor)
10870 vty_out(vty, BGP_SHOW_DAMP_HEADER);
10871 else if (type == bgp_show_type_flap_statistics
10872 || type == bgp_show_type_flap_neighbor)
10873 vty_out(vty, BGP_SHOW_FLAP_HEADER);
10874 else
10875 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
10876 : BGP_SHOW_HEADER));
10877 header = 0;
10878 }
10879 if (rd != NULL && !display && !output_count) {
10880 if (!use_json)
10881 vty_out(vty,
10882 "Route Distinguisher: %s\n",
10883 rd);
10884 }
10885 if (type == bgp_show_type_dampend_paths
10886 || type == bgp_show_type_damp_neighbor)
10887 damp_route_vty_out(vty, dest_p, pi, display,
10888 AFI_IP, safi, use_json,
10889 json_paths);
10890 else if (type == bgp_show_type_flap_statistics
10891 || type == bgp_show_type_flap_neighbor)
10892 flap_route_vty_out(vty, dest_p, pi, display,
10893 AFI_IP, safi, use_json,
10894 json_paths);
10895 else {
10896 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
10897 route_vty_out_detail(
10898 vty, bgp, dest, pi,
10899 family2afi(dest_p->family),
10900 safi, RPKI_NOT_BEING_USED,
10901 json_paths);
10902 else
10903 route_vty_out(vty, dest_p, pi, display,
10904 safi, json_paths, wide);
10905 }
10906 display++;
10907 }
10908
10909 if (display) {
10910 output_count++;
10911 if (!use_json)
10912 continue;
10913
10914 /* encode prefix */
10915 if (dest_p->family == AF_FLOWSPEC) {
10916 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
10917
10918
10919 bgp_fs_nlri_get_string(
10920 (unsigned char *)
10921 dest_p->u.prefix_flowspec.ptr,
10922 dest_p->u.prefix_flowspec.prefixlen,
10923 retstr, NLRI_STRING_FORMAT_MIN, NULL,
10924 family2afi(dest_p->u
10925 .prefix_flowspec.family));
10926 if (first)
10927 vty_out(vty, "\"%s/%d\": ", retstr,
10928 dest_p->u.prefix_flowspec
10929 .prefixlen);
10930 else
10931 vty_out(vty, ",\"%s/%d\": ", retstr,
10932 dest_p->u.prefix_flowspec
10933 .prefixlen);
10934 } else {
10935 if (first)
10936 vty_out(vty, "\"%pFX\": ", dest_p);
10937 else
10938 vty_out(vty, ",\"%pFX\": ", dest_p);
10939 }
10940 vty_out(vty, "%s",
10941 json_object_to_json_string_ext(
10942 json_paths, JSON_C_TO_STRING_PRETTY));
10943 json_object_free(json_paths);
10944 json_paths = NULL;
10945 first = 0;
10946 } else
10947 json_object_free(json_paths);
10948 }
10949
10950 if (output_cum) {
10951 output_count += *output_cum;
10952 *output_cum = output_count;
10953 }
10954 if (total_cum) {
10955 total_count += *total_cum;
10956 *total_cum = total_count;
10957 }
10958 if (use_json) {
10959 if (rd) {
10960 vty_out(vty, " }%s ", (is_last ? "" : ","));
10961 }
10962 if (is_last) {
10963 unsigned long i;
10964 for (i = 0; i < *json_header_depth; ++i)
10965 vty_out(vty, " } ");
10966 if (!all)
10967 vty_out(vty, "\n");
10968 }
10969 } else {
10970 if (is_last) {
10971 /* No route is displayed */
10972 if (output_count == 0) {
10973 if (type == bgp_show_type_normal)
10974 vty_out(vty,
10975 "No BGP prefixes displayed, %ld exist\n",
10976 total_count);
10977 } else
10978 vty_out(vty,
10979 "\nDisplayed %ld routes and %ld total paths\n",
10980 output_count, total_count);
10981 }
10982 }
10983
10984 return CMD_SUCCESS;
10985 }
10986
10987 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
10988 struct bgp_table *table, struct prefix_rd *prd_match,
10989 enum bgp_show_type type, void *output_arg, bool use_json)
10990 {
10991 struct bgp_dest *dest, *next;
10992 unsigned long output_cum = 0;
10993 unsigned long total_cum = 0;
10994 unsigned long json_header_depth = 0;
10995 struct bgp_table *itable;
10996 bool show_msg;
10997 uint8_t show_flags = 0;
10998
10999 show_msg = (!use_json && type == bgp_show_type_normal);
11000
11001 if (use_json)
11002 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11003
11004 for (dest = bgp_table_top(table); dest; dest = next) {
11005 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11006
11007 next = bgp_route_next(dest);
11008 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11009 continue;
11010
11011 itable = bgp_dest_get_bgp_table_info(dest);
11012 if (itable != NULL) {
11013 struct prefix_rd prd;
11014 char rd[RD_ADDRSTRLEN];
11015
11016 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11017 prefix_rd2str(&prd, rd, sizeof(rd));
11018 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11019 rd, next == NULL, &output_cum,
11020 &total_cum, &json_header_depth,
11021 show_flags, RPKI_NOT_BEING_USED);
11022 if (next == NULL)
11023 show_msg = false;
11024 }
11025 }
11026 if (show_msg) {
11027 if (output_cum == 0)
11028 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11029 total_cum);
11030 else
11031 vty_out(vty,
11032 "\nDisplayed %ld routes and %ld total paths\n",
11033 output_cum, total_cum);
11034 }
11035 return CMD_SUCCESS;
11036 }
11037 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11038 enum bgp_show_type type, void *output_arg,
11039 uint8_t show_flags, enum rpki_states rpki_target_state)
11040 {
11041 struct bgp_table *table;
11042 unsigned long json_header_depth = 0;
11043 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11044
11045 if (bgp == NULL) {
11046 bgp = bgp_get_default();
11047 }
11048
11049 if (bgp == NULL) {
11050 if (!use_json)
11051 vty_out(vty, "No BGP process is configured\n");
11052 else
11053 vty_out(vty, "{}\n");
11054 return CMD_WARNING;
11055 }
11056
11057 table = bgp->rib[afi][safi];
11058 /* use MPLS and ENCAP specific shows until they are merged */
11059 if (safi == SAFI_MPLS_VPN) {
11060 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11061 output_arg, use_json);
11062 }
11063
11064 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11065 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11066 output_arg, use_json,
11067 1, NULL, NULL);
11068 }
11069 /* labeled-unicast routes live in the unicast table */
11070 else if (safi == SAFI_LABELED_UNICAST)
11071 safi = SAFI_UNICAST;
11072
11073 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11074 NULL, NULL, &json_header_depth, show_flags,
11075 rpki_target_state);
11076 }
11077
11078 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11079 safi_t safi, uint8_t show_flags)
11080 {
11081 struct listnode *node, *nnode;
11082 struct bgp *bgp;
11083 int is_first = 1;
11084 bool route_output = false;
11085 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11086
11087 if (use_json)
11088 vty_out(vty, "{\n");
11089
11090 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11091 route_output = true;
11092 if (use_json) {
11093 if (!is_first)
11094 vty_out(vty, ",\n");
11095 else
11096 is_first = 0;
11097
11098 vty_out(vty, "\"%s\":",
11099 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11100 ? VRF_DEFAULT_NAME
11101 : bgp->name);
11102 } else {
11103 vty_out(vty, "\nInstance %s:\n",
11104 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11105 ? VRF_DEFAULT_NAME
11106 : bgp->name);
11107 }
11108 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11109 show_flags, RPKI_NOT_BEING_USED);
11110 }
11111
11112 if (use_json)
11113 vty_out(vty, "}\n");
11114 else if (!route_output)
11115 vty_out(vty, "%% BGP instance not found\n");
11116 }
11117
11118 /* Header of detailed BGP route information */
11119 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11120 struct bgp_dest *dest, struct prefix_rd *prd,
11121 afi_t afi, safi_t safi, json_object *json)
11122 {
11123 struct bgp_path_info *pi;
11124 const struct prefix *p;
11125 struct peer *peer;
11126 struct listnode *node, *nnode;
11127 char buf1[RD_ADDRSTRLEN];
11128 char prefix_str[BUFSIZ];
11129 int count = 0;
11130 int best = 0;
11131 int suppress = 0;
11132 int accept_own = 0;
11133 int route_filter_translated_v4 = 0;
11134 int route_filter_v4 = 0;
11135 int route_filter_translated_v6 = 0;
11136 int route_filter_v6 = 0;
11137 int llgr_stale = 0;
11138 int no_llgr = 0;
11139 int accept_own_nexthop = 0;
11140 int blackhole = 0;
11141 int no_export = 0;
11142 int no_advertise = 0;
11143 int local_as = 0;
11144 int no_peer = 0;
11145 int first = 1;
11146 int has_valid_label = 0;
11147 mpls_label_t label = 0;
11148 json_object *json_adv_to = NULL;
11149
11150 p = bgp_dest_get_prefix(dest);
11151 has_valid_label = bgp_is_valid_label(&dest->local_label);
11152
11153 if (has_valid_label)
11154 label = label_pton(&dest->local_label);
11155
11156 if (safi == SAFI_EVPN) {
11157
11158 if (!json) {
11159 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11160 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11161 : "",
11162 prd ? ":" : "", (struct prefix_evpn *)p);
11163 } else {
11164 json_object_string_add(json, "rd",
11165 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11166 "");
11167 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11168 }
11169 } else {
11170 if (!json) {
11171 vty_out(vty,
11172 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11173 "\n",
11174 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11175 ? prefix_rd2str(prd, buf1,
11176 sizeof(buf1))
11177 : ""),
11178 safi == SAFI_MPLS_VPN ? ":" : "", p,
11179 dest->version);
11180
11181 } else {
11182 json_object_string_add(json, "prefix",
11183 prefix2str(p, prefix_str, sizeof(prefix_str)));
11184 json_object_int_add(json, "version", dest->version);
11185
11186 }
11187 }
11188
11189 if (has_valid_label) {
11190 if (json)
11191 json_object_int_add(json, "localLabel", label);
11192 else
11193 vty_out(vty, "Local label: %d\n", label);
11194 }
11195
11196 if (!json)
11197 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11198 vty_out(vty, "not allocated\n");
11199
11200 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11201 count++;
11202 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11203 best = count;
11204 if (bgp_path_suppressed(pi))
11205 suppress = 1;
11206
11207 if (pi->attr->community == NULL)
11208 continue;
11209
11210 no_advertise += community_include(
11211 pi->attr->community, COMMUNITY_NO_ADVERTISE);
11212 no_export += community_include(pi->attr->community,
11213 COMMUNITY_NO_EXPORT);
11214 local_as += community_include(pi->attr->community,
11215 COMMUNITY_LOCAL_AS);
11216 accept_own += community_include(pi->attr->community,
11217 COMMUNITY_ACCEPT_OWN);
11218 route_filter_translated_v4 += community_include(
11219 pi->attr->community,
11220 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11221 route_filter_translated_v6 += community_include(
11222 pi->attr->community,
11223 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11224 route_filter_v4 += community_include(
11225 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
11226 route_filter_v6 += community_include(
11227 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
11228 llgr_stale += community_include(pi->attr->community,
11229 COMMUNITY_LLGR_STALE);
11230 no_llgr += community_include(pi->attr->community,
11231 COMMUNITY_NO_LLGR);
11232 accept_own_nexthop +=
11233 community_include(pi->attr->community,
11234 COMMUNITY_ACCEPT_OWN_NEXTHOP);
11235 blackhole += community_include(pi->attr->community,
11236 COMMUNITY_BLACKHOLE);
11237 no_peer += community_include(pi->attr->community,
11238 COMMUNITY_NO_PEER);
11239 }
11240 }
11241
11242 if (!json) {
11243 vty_out(vty, "Paths: (%d available", count);
11244 if (best) {
11245 vty_out(vty, ", best #%d", best);
11246 if (safi == SAFI_UNICAST) {
11247 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11248 vty_out(vty, ", table %s",
11249 VRF_DEFAULT_NAME);
11250 else
11251 vty_out(vty, ", vrf %s",
11252 bgp->name);
11253 }
11254 } else
11255 vty_out(vty, ", no best path");
11256
11257 if (accept_own)
11258 vty_out(vty,
11259 ", accept own local route exported and imported in different VRF");
11260 else if (route_filter_translated_v4)
11261 vty_out(vty,
11262 ", mark translated RTs for VPNv4 route filtering");
11263 else if (route_filter_v4)
11264 vty_out(vty,
11265 ", attach RT as-is for VPNv4 route filtering");
11266 else if (route_filter_translated_v6)
11267 vty_out(vty,
11268 ", mark translated RTs for VPNv6 route filtering");
11269 else if (route_filter_v6)
11270 vty_out(vty,
11271 ", attach RT as-is for VPNv6 route filtering");
11272 else if (llgr_stale)
11273 vty_out(vty,
11274 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
11275 else if (no_llgr)
11276 vty_out(vty,
11277 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11278 else if (accept_own_nexthop)
11279 vty_out(vty,
11280 ", accept local nexthop");
11281 else if (blackhole)
11282 vty_out(vty, ", inform peer to blackhole prefix");
11283 else if (no_export)
11284 vty_out(vty, ", not advertised to EBGP peer");
11285 else if (no_advertise)
11286 vty_out(vty, ", not advertised to any peer");
11287 else if (local_as)
11288 vty_out(vty, ", not advertised outside local AS");
11289 else if (no_peer)
11290 vty_out(vty,
11291 ", inform EBGP peer not to advertise to their EBGP peers");
11292
11293 if (suppress)
11294 vty_out(vty,
11295 ", Advertisements suppressed by an aggregate.");
11296 vty_out(vty, ")\n");
11297 }
11298
11299 /* If we are not using addpath then we can display Advertised to and
11300 * that will
11301 * show what peers we advertised the bestpath to. If we are using
11302 * addpath
11303 * though then we must display Advertised to on a path-by-path basis. */
11304 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11305 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11306 if (bgp_adj_out_lookup(peer, dest, 0)) {
11307 if (json && !json_adv_to)
11308 json_adv_to = json_object_new_object();
11309
11310 route_vty_out_advertised_to(
11311 vty, peer, &first,
11312 " Advertised to non peer-group peers:\n ",
11313 json_adv_to);
11314 }
11315 }
11316
11317 if (json) {
11318 if (json_adv_to) {
11319 json_object_object_add(json, "advertisedTo",
11320 json_adv_to);
11321 }
11322 } else {
11323 if (first)
11324 vty_out(vty, " Not advertised to any peer");
11325 vty_out(vty, "\n");
11326 }
11327 }
11328 }
11329
11330 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
11331 struct bgp_dest *bgp_node, struct vty *vty,
11332 struct bgp *bgp, afi_t afi, safi_t safi,
11333 json_object *json, enum bgp_path_type pathtype,
11334 int *display, enum rpki_states rpki_target_state)
11335 {
11336 struct bgp_path_info *pi;
11337 int header = 1;
11338 char rdbuf[RD_ADDRSTRLEN];
11339 json_object *json_header = NULL;
11340 json_object *json_paths = NULL;
11341 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11342
11343 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11344 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11345
11346 if (p->family == AF_INET || p->family == AF_INET6)
11347 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11348 pi->peer, pi->attr, p);
11349
11350 if (rpki_target_state != RPKI_NOT_BEING_USED
11351 && rpki_curr_state != rpki_target_state)
11352 continue;
11353
11354 if (json && !json_paths) {
11355 /* Instantiate json_paths only if path is valid */
11356 json_paths = json_object_new_array();
11357 if (pfx_rd) {
11358 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11359 json_header = json_object_new_object();
11360 } else
11361 json_header = json;
11362 }
11363
11364 if (header) {
11365 route_vty_out_detail_header(
11366 vty, bgp, bgp_node, pfx_rd,
11367 AFI_IP, safi, json_header);
11368 header = 0;
11369 }
11370 (*display)++;
11371
11372 if (pathtype == BGP_PATH_SHOW_ALL
11373 || (pathtype == BGP_PATH_SHOW_BESTPATH
11374 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11375 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11376 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11377 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11378 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
11379 safi, rpki_curr_state, json_paths);
11380 }
11381
11382 if (json && json_paths) {
11383 json_object_object_add(json_header, "paths", json_paths);
11384
11385 if (pfx_rd)
11386 json_object_object_add(json, rdbuf, json_header);
11387 }
11388 }
11389
11390 /* Display specified route of BGP table. */
11391 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11392 struct bgp_table *rib, const char *ip_str,
11393 afi_t afi, safi_t safi,
11394 enum rpki_states rpki_target_state,
11395 struct prefix_rd *prd, int prefix_check,
11396 enum bgp_path_type pathtype, bool use_json)
11397 {
11398 int ret;
11399 int display = 0;
11400 struct prefix match;
11401 struct bgp_dest *dest;
11402 struct bgp_dest *rm;
11403 struct bgp_table *table;
11404 json_object *json = NULL;
11405 json_object *json_paths = NULL;
11406
11407 /* Check IP address argument. */
11408 ret = str2prefix(ip_str, &match);
11409 if (!ret) {
11410 vty_out(vty, "address is malformed\n");
11411 return CMD_WARNING;
11412 }
11413
11414 match.family = afi2family(afi);
11415
11416 if (use_json)
11417 json = json_object_new_object();
11418
11419 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11420 for (dest = bgp_table_top(rib); dest;
11421 dest = bgp_route_next(dest)) {
11422 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11423
11424 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11425 continue;
11426 table = bgp_dest_get_bgp_table_info(dest);
11427 if (!table)
11428 continue;
11429
11430 if ((rm = bgp_node_match(table, &match)) == NULL)
11431 continue;
11432
11433 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11434 if (prefix_check
11435 && rm_p->prefixlen != match.prefixlen) {
11436 bgp_dest_unlock_node(rm);
11437 continue;
11438 }
11439
11440 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11441 bgp, afi, safi, json, pathtype,
11442 &display, rpki_target_state);
11443
11444 bgp_dest_unlock_node(rm);
11445 }
11446 } else if (safi == SAFI_EVPN) {
11447 struct bgp_dest *longest_pfx;
11448 bool is_exact_pfxlen_match = false;
11449
11450 for (dest = bgp_table_top(rib); dest;
11451 dest = bgp_route_next(dest)) {
11452 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11453
11454 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11455 continue;
11456 table = bgp_dest_get_bgp_table_info(dest);
11457 if (!table)
11458 continue;
11459
11460 longest_pfx = NULL;
11461 is_exact_pfxlen_match = false;
11462 /*
11463 * Search through all the prefixes for a match. The
11464 * pfx's are enumerated in ascending order of pfxlens.
11465 * So, the last pfx match is the longest match. Set
11466 * is_exact_pfxlen_match when we get exact pfxlen match
11467 */
11468 for (rm = bgp_table_top(table); rm;
11469 rm = bgp_route_next(rm)) {
11470 const struct prefix *rm_p =
11471 bgp_dest_get_prefix(rm);
11472 /*
11473 * Get prefixlen of the ip-prefix within type5
11474 * evpn route
11475 */
11476 if (evpn_type5_prefix_match(rm_p, &match)
11477 && rm->info) {
11478 longest_pfx = rm;
11479 int type5_pfxlen =
11480 bgp_evpn_get_type5_prefixlen(
11481 rm_p);
11482 if (type5_pfxlen == match.prefixlen) {
11483 is_exact_pfxlen_match = true;
11484 bgp_dest_unlock_node(rm);
11485 break;
11486 }
11487 }
11488 }
11489
11490 if (!longest_pfx)
11491 continue;
11492
11493 if (prefix_check && !is_exact_pfxlen_match)
11494 continue;
11495
11496 rm = longest_pfx;
11497 bgp_dest_lock_node(rm);
11498
11499 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11500 bgp, afi, safi, json, pathtype,
11501 &display, rpki_target_state);
11502
11503 bgp_dest_unlock_node(rm);
11504 }
11505 } else if (safi == SAFI_FLOWSPEC) {
11506 if (use_json)
11507 json_paths = json_object_new_array();
11508
11509 display = bgp_flowspec_display_match_per_ip(afi, rib,
11510 &match, prefix_check,
11511 vty,
11512 use_json,
11513 json_paths);
11514 if (use_json) {
11515 if (display)
11516 json_object_object_add(json, "paths",
11517 json_paths);
11518 else
11519 json_object_free(json_paths);
11520 }
11521 } else {
11522 if ((dest = bgp_node_match(rib, &match)) != NULL) {
11523 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11524 if (!prefix_check
11525 || dest_p->prefixlen == match.prefixlen) {
11526 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11527 safi, json, pathtype,
11528 &display, rpki_target_state);
11529 }
11530
11531 bgp_dest_unlock_node(dest);
11532 }
11533 }
11534
11535 if (use_json) {
11536 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11537 json, JSON_C_TO_STRING_PRETTY |
11538 JSON_C_TO_STRING_NOSLASHESCAPE));
11539 json_object_free(json);
11540 } else {
11541 if (!display) {
11542 vty_out(vty, "%% Network not in table\n");
11543 return CMD_WARNING;
11544 }
11545 }
11546
11547 return CMD_SUCCESS;
11548 }
11549
11550 /* Display specified route of Main RIB */
11551 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
11552 afi_t afi, safi_t safi, struct prefix_rd *prd,
11553 int prefix_check, enum bgp_path_type pathtype,
11554 enum rpki_states rpki_target_state, bool use_json)
11555 {
11556 if (!bgp) {
11557 bgp = bgp_get_default();
11558 if (!bgp) {
11559 if (!use_json)
11560 vty_out(vty, "No BGP process is configured\n");
11561 else
11562 vty_out(vty, "{}\n");
11563 return CMD_WARNING;
11564 }
11565 }
11566
11567 /* labeled-unicast routes live in the unicast table */
11568 if (safi == SAFI_LABELED_UNICAST)
11569 safi = SAFI_UNICAST;
11570
11571 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
11572 afi, safi, rpki_target_state, prd,
11573 prefix_check, pathtype, use_json);
11574 }
11575
11576 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
11577 struct cmd_token **argv, bool exact, afi_t afi,
11578 safi_t safi, bool uj)
11579 {
11580 struct lcommunity *lcom;
11581 struct buffer *b;
11582 int i;
11583 char *str;
11584 int first = 0;
11585 uint8_t show_flags = 0;
11586 int ret;
11587
11588 if (uj)
11589 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11590
11591 b = buffer_new(1024);
11592 for (i = 0; i < argc; i++) {
11593 if (first)
11594 buffer_putc(b, ' ');
11595 else {
11596 if (strmatch(argv[i]->text, "AA:BB:CC")) {
11597 first = 1;
11598 buffer_putstr(b, argv[i]->arg);
11599 }
11600 }
11601 }
11602 buffer_putc(b, '\0');
11603
11604 str = buffer_getstr(b);
11605 buffer_free(b);
11606
11607 lcom = lcommunity_str2com(str);
11608 XFREE(MTYPE_TMP, str);
11609 if (!lcom) {
11610 vty_out(vty, "%% Large-community malformed\n");
11611 return CMD_WARNING;
11612 }
11613
11614 ret = bgp_show(vty, bgp, afi, safi,
11615 (exact ? bgp_show_type_lcommunity_exact
11616 : bgp_show_type_lcommunity),
11617 lcom, show_flags, RPKI_NOT_BEING_USED);
11618
11619 lcommunity_free(&lcom);
11620 return ret;
11621 }
11622
11623 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
11624 const char *lcom, bool exact, afi_t afi,
11625 safi_t safi, bool uj)
11626 {
11627 struct community_list *list;
11628 uint8_t show_flags = 0;
11629
11630 if (uj)
11631 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11632
11633
11634 list = community_list_lookup(bgp_clist, lcom, 0,
11635 LARGE_COMMUNITY_LIST_MASTER);
11636 if (list == NULL) {
11637 vty_out(vty, "%% %s is not a valid large-community-list name\n",
11638 lcom);
11639 return CMD_WARNING;
11640 }
11641
11642 return bgp_show(vty, bgp, afi, safi,
11643 (exact ? bgp_show_type_lcommunity_list_exact
11644 : bgp_show_type_lcommunity_list),
11645 list, show_flags, RPKI_NOT_BEING_USED);
11646 }
11647
11648 DEFUN (show_ip_bgp_large_community_list,
11649 show_ip_bgp_large_community_list_cmd,
11650 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|WORD> [exact-match] [json]",
11651 SHOW_STR
11652 IP_STR
11653 BGP_STR
11654 BGP_INSTANCE_HELP_STR
11655 BGP_AFI_HELP_STR
11656 BGP_SAFI_WITH_LABEL_HELP_STR
11657 "Display routes matching the large-community-list\n"
11658 "large-community-list number\n"
11659 "large-community-list name\n"
11660 "Exact match of the large-communities\n"
11661 JSON_STR)
11662 {
11663 afi_t afi = AFI_IP6;
11664 safi_t safi = SAFI_UNICAST;
11665 int idx = 0;
11666 bool exact_match = 0;
11667 struct bgp *bgp = NULL;
11668 bool uj = use_json(argc, argv);
11669
11670 if (uj)
11671 argc--;
11672
11673 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11674 &bgp, uj);
11675 if (!idx)
11676 return CMD_WARNING;
11677
11678 argv_find(argv, argc, "large-community-list", &idx);
11679
11680 const char *clist_number_or_name = argv[++idx]->arg;
11681
11682 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11683 exact_match = 1;
11684
11685 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
11686 exact_match, afi, safi, uj);
11687 }
11688 DEFUN (show_ip_bgp_large_community,
11689 show_ip_bgp_large_community_cmd,
11690 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
11691 SHOW_STR
11692 IP_STR
11693 BGP_STR
11694 BGP_INSTANCE_HELP_STR
11695 BGP_AFI_HELP_STR
11696 BGP_SAFI_WITH_LABEL_HELP_STR
11697 "Display routes matching the large-communities\n"
11698 "List of large-community numbers\n"
11699 "Exact match of the large-communities\n"
11700 JSON_STR)
11701 {
11702 afi_t afi = AFI_IP6;
11703 safi_t safi = SAFI_UNICAST;
11704 int idx = 0;
11705 bool exact_match = 0;
11706 struct bgp *bgp = NULL;
11707 bool uj = use_json(argc, argv);
11708 uint8_t show_flags = 0;
11709
11710 if (uj) {
11711 argc--;
11712 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11713 }
11714
11715 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11716 &bgp, uj);
11717 if (!idx)
11718 return CMD_WARNING;
11719
11720 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
11721 if (argv_find(argv, argc, "exact-match", &idx))
11722 exact_match = 1;
11723 return bgp_show_lcommunity(vty, bgp, argc, argv,
11724 exact_match, afi, safi, uj);
11725 } else
11726 return bgp_show(vty, bgp, afi, safi,
11727 bgp_show_type_lcommunity_all, NULL, show_flags,
11728 RPKI_NOT_BEING_USED);
11729 }
11730
11731 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
11732 safi_t safi, struct json_object *json_array);
11733 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
11734 safi_t safi, struct json_object *json);
11735
11736
11737 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
11738 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
11739 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
11740 "Display number of prefixes for all afi/safi\n" JSON_STR)
11741 {
11742 bool uj = use_json(argc, argv);
11743 struct bgp *bgp = NULL;
11744 safi_t safi = SAFI_UNICAST;
11745 afi_t afi = AFI_IP6;
11746 int idx = 0;
11747 struct json_object *json_all = NULL;
11748 struct json_object *json_afi_safi = NULL;
11749
11750 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11751 &bgp, false);
11752 if (!idx)
11753 return CMD_WARNING;
11754
11755 if (uj)
11756 json_all = json_object_new_object();
11757
11758 FOREACH_AFI_SAFI (afi, safi) {
11759 /*
11760 * So limit output to those afi/safi pairs that
11761 * actually have something interesting in them
11762 */
11763 if (strmatch(get_afi_safi_str(afi, safi, true),
11764 "Unknown")) {
11765 continue;
11766 }
11767 if (uj) {
11768 json_afi_safi = json_object_new_array();
11769 json_object_object_add(
11770 json_all,
11771 get_afi_safi_str(afi, safi, true),
11772 json_afi_safi);
11773 } else {
11774 json_afi_safi = NULL;
11775 }
11776
11777 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11778 }
11779
11780 if (uj) {
11781 vty_out(vty, "%s",
11782 json_object_to_json_string_ext(
11783 json_all, JSON_C_TO_STRING_PRETTY));
11784 json_object_free(json_all);
11785 }
11786
11787 return CMD_SUCCESS;
11788 }
11789
11790 /* BGP route print out function without JSON */
11791 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
11792 show_ip_bgp_l2vpn_evpn_statistics_cmd,
11793 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
11794 SHOW_STR
11795 IP_STR
11796 BGP_STR
11797 BGP_INSTANCE_HELP_STR
11798 L2VPN_HELP_STR
11799 EVPN_HELP_STR
11800 "BGP RIB advertisement statistics\n"
11801 JSON_STR)
11802 {
11803 afi_t afi = AFI_IP6;
11804 safi_t safi = SAFI_UNICAST;
11805 struct bgp *bgp = NULL;
11806 int idx = 0, ret;
11807 bool uj = use_json(argc, argv);
11808 struct json_object *json_afi_safi = NULL, *json = NULL;
11809
11810 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11811 &bgp, false);
11812 if (!idx)
11813 return CMD_WARNING;
11814
11815 if (uj)
11816 json_afi_safi = json_object_new_array();
11817 else
11818 json_afi_safi = NULL;
11819
11820 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11821
11822 if (uj) {
11823 json = json_object_new_object();
11824 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11825 json_afi_safi);
11826 vty_out(vty, "%s", json_object_to_json_string_ext(
11827 json, JSON_C_TO_STRING_PRETTY));
11828 json_object_free(json);
11829 }
11830 return ret;
11831 }
11832
11833 /* BGP route print out function without JSON */
11834 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
11835 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11836 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11837 "]]\
11838 statistics [json]",
11839 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11840 BGP_SAFI_WITH_LABEL_HELP_STR
11841 "BGP RIB advertisement statistics\n" JSON_STR)
11842 {
11843 afi_t afi = AFI_IP6;
11844 safi_t safi = SAFI_UNICAST;
11845 struct bgp *bgp = NULL;
11846 int idx = 0, ret;
11847 bool uj = use_json(argc, argv);
11848 struct json_object *json_afi_safi = NULL, *json = NULL;
11849
11850 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11851 &bgp, false);
11852 if (!idx)
11853 return CMD_WARNING;
11854
11855 if (uj)
11856 json_afi_safi = json_object_new_array();
11857 else
11858 json_afi_safi = NULL;
11859
11860 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11861
11862 if (uj) {
11863 json = json_object_new_object();
11864 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11865 json_afi_safi);
11866 vty_out(vty, "%s",
11867 json_object_to_json_string_ext(
11868 json, JSON_C_TO_STRING_PRETTY));
11869 json_object_free(json);
11870 }
11871 return ret;
11872 }
11873
11874 /* BGP route print out function without JSON */
11875 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
11876 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11877 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11878 "]]\
11879 <[all$all] dampening <parameters>\
11880 |route-map WORD\
11881 |prefix-list WORD\
11882 |filter-list WORD\
11883 |community-list <(1-500)|WORD> [exact-match]\
11884 |A.B.C.D/M longer-prefixes\
11885 |X:X::X:X/M longer-prefixes\
11886 >",
11887 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11888 BGP_SAFI_WITH_LABEL_HELP_STR
11889 "Display the entries for all address families\n"
11890 "Display detailed information about dampening\n"
11891 "Display detail of configured dampening parameters\n"
11892 "Display routes matching the route-map\n"
11893 "A route-map to match on\n"
11894 "Display routes conforming to the prefix-list\n"
11895 "Prefix-list name\n"
11896 "Display routes conforming to the filter-list\n"
11897 "Regular expression access list name\n"
11898 "Display routes matching the community-list\n"
11899 "community-list number\n"
11900 "community-list name\n"
11901 "Exact match of the communities\n"
11902 "IPv4 prefix\n"
11903 "Display route and more specific routes\n"
11904 "IPv6 prefix\n"
11905 "Display route and more specific routes\n")
11906 {
11907 afi_t afi = AFI_IP6;
11908 safi_t safi = SAFI_UNICAST;
11909 int exact_match = 0;
11910 struct bgp *bgp = NULL;
11911 int idx = 0;
11912 uint8_t show_flags = 0;
11913
11914 /* [<ipv4|ipv6> [all]] */
11915 if (all) {
11916 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11917 if (argv_find(argv, argc, "ipv4", &idx))
11918 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
11919
11920 if (argv_find(argv, argc, "ipv6", &idx))
11921 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
11922 }
11923
11924 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11925 &bgp, false);
11926 if (!idx)
11927 return CMD_WARNING;
11928
11929 if (argv_find(argv, argc, "dampening", &idx)) {
11930 if (argv_find(argv, argc, "parameters", &idx))
11931 return bgp_show_dampening_parameters(vty, afi, safi,
11932 show_flags);
11933 }
11934
11935 if (argv_find(argv, argc, "prefix-list", &idx))
11936 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
11937 safi, bgp_show_type_prefix_list);
11938
11939 if (argv_find(argv, argc, "filter-list", &idx))
11940 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
11941 safi, bgp_show_type_filter_list);
11942
11943 if (argv_find(argv, argc, "route-map", &idx))
11944 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
11945 safi, bgp_show_type_route_map);
11946
11947 if (argv_find(argv, argc, "community-list", &idx)) {
11948 const char *clist_number_or_name = argv[++idx]->arg;
11949 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11950 exact_match = 1;
11951 return bgp_show_community_list(vty, bgp, clist_number_or_name,
11952 exact_match, afi, safi);
11953 }
11954 /* prefix-longer */
11955 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
11956 || argv_find(argv, argc, "X:X::X:X/M", &idx))
11957 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
11958 safi,
11959 bgp_show_type_prefix_longer);
11960
11961 return CMD_WARNING;
11962 }
11963
11964 /* BGP route print out function with JSON */
11965 DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd,
11966 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11967 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11968 "]]\
11969 [all$all]\
11970 [cidr-only\
11971 |dampening <flap-statistics|dampened-paths>\
11972 |community [AA:NN|local-AS|no-advertise|no-export\
11973 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
11974 |accept-own|accept-own-nexthop|route-filter-v6\
11975 |route-filter-v4|route-filter-translated-v6\
11976 |route-filter-translated-v4] [exact-match]\
11977 |rpki <invalid|valid|notfound>\
11978 |version (1-4294967295)\
11979 |alias WORD\
11980 ] [json$uj [detail$detail] | wide$wide]",
11981 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11982 BGP_SAFI_WITH_LABEL_HELP_STR
11983 "Display the entries for all address families\n"
11984 "Display only routes with non-natural netmasks\n"
11985 "Display detailed information about dampening\n"
11986 "Display flap statistics of routes\n"
11987 "Display paths suppressed due to dampening\n"
11988 "Display routes matching the communities\n" COMMUNITY_AANN_STR
11989 "Do not send outside local AS (well-known community)\n"
11990 "Do not advertise to any peer (well-known community)\n"
11991 "Do not export to next AS (well-known community)\n"
11992 "Graceful shutdown (well-known community)\n"
11993 "Do not export to any peer (well-known community)\n"
11994 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
11995 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
11996 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
11997 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
11998 "Should accept VPN route with local nexthop (well-known community)\n"
11999 "RT VPNv6 route filtering (well-known community)\n"
12000 "RT VPNv4 route filtering (well-known community)\n"
12001 "RT translated VPNv6 route filtering (well-known community)\n"
12002 "RT translated VPNv4 route filtering (well-known community)\n"
12003 "Exact match of the communities\n"
12004 "RPKI route types\n"
12005 "A valid path as determined by rpki\n"
12006 "A invalid path as determined by rpki\n"
12007 "A path that has no rpki data\n"
12008 "Display prefixes with matching version numbers\n"
12009 "Version number and above\n"
12010 "Display prefixes with matching BGP community alias\n"
12011 "BGP community alias\n" JSON_STR
12012 "Display detailed version of JSON output\n"
12013 "Increase table width for longer prefixes\n")
12014 {
12015 afi_t afi = AFI_IP6;
12016 safi_t safi = SAFI_UNICAST;
12017 enum bgp_show_type sh_type = bgp_show_type_normal;
12018 struct bgp *bgp = NULL;
12019 int idx = 0;
12020 int exact_match = 0;
12021 char *community = NULL;
12022 char *prefix_version = NULL;
12023 char *bgp_community_alias = NULL;
12024 bool first = true;
12025 uint8_t show_flags = 0;
12026 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12027
12028 if (uj) {
12029 argc--;
12030 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12031 }
12032
12033 if (detail)
12034 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12035
12036 /* [<ipv4|ipv6> [all]] */
12037 if (all) {
12038 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12039
12040 if (argv_find(argv, argc, "ipv4", &idx))
12041 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12042
12043 if (argv_find(argv, argc, "ipv6", &idx))
12044 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12045 }
12046
12047 if (wide)
12048 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12049
12050 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12051 &bgp, uj);
12052 if (!idx)
12053 return CMD_WARNING;
12054
12055 if (argv_find(argv, argc, "cidr-only", &idx))
12056 sh_type = bgp_show_type_cidr_only;
12057
12058 if (argv_find(argv, argc, "dampening", &idx)) {
12059 if (argv_find(argv, argc, "dampened-paths", &idx))
12060 sh_type = bgp_show_type_dampend_paths;
12061 else if (argv_find(argv, argc, "flap-statistics", &idx))
12062 sh_type = bgp_show_type_flap_statistics;
12063 }
12064
12065 if (argv_find(argv, argc, "community", &idx)) {
12066 char *maybecomm = NULL;
12067
12068 if (idx + 1 < argc) {
12069 if (argv[idx + 1]->type == VARIABLE_TKN)
12070 maybecomm = argv[idx + 1]->arg;
12071 else
12072 maybecomm = argv[idx + 1]->text;
12073 }
12074
12075 if (maybecomm && !strmatch(maybecomm, "json")
12076 && !strmatch(maybecomm, "exact-match"))
12077 community = maybecomm;
12078
12079 if (argv_find(argv, argc, "exact-match", &idx))
12080 exact_match = 1;
12081
12082 if (!community)
12083 sh_type = bgp_show_type_community_all;
12084 }
12085
12086 if (argv_find(argv, argc, "rpki", &idx)) {
12087 sh_type = bgp_show_type_rpki;
12088 if (argv_find(argv, argc, "valid", &idx))
12089 rpki_target_state = RPKI_VALID;
12090 else if (argv_find(argv, argc, "invalid", &idx))
12091 rpki_target_state = RPKI_INVALID;
12092 }
12093
12094 /* Display prefixes with matching version numbers */
12095 if (argv_find(argv, argc, "version", &idx)) {
12096 sh_type = bgp_show_type_prefix_version;
12097 prefix_version = argv[idx + 1]->arg;
12098 }
12099
12100 /* Display prefixes with matching BGP community alias */
12101 if (argv_find(argv, argc, "alias", &idx)) {
12102 sh_type = bgp_show_type_community_alias;
12103 bgp_community_alias = argv[idx + 1]->arg;
12104 }
12105
12106 if (!all) {
12107 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12108 if (community)
12109 return bgp_show_community(vty, bgp, community,
12110 exact_match, afi, safi,
12111 show_flags);
12112 else if (prefix_version)
12113 return bgp_show(vty, bgp, afi, safi, sh_type,
12114 prefix_version, show_flags,
12115 rpki_target_state);
12116 else if (bgp_community_alias)
12117 return bgp_show(vty, bgp, afi, safi, sh_type,
12118 bgp_community_alias, show_flags,
12119 rpki_target_state);
12120 else
12121 return bgp_show(vty, bgp, afi, safi, sh_type, NULL,
12122 show_flags, rpki_target_state);
12123 } else {
12124 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12125 * AFI_IP6 */
12126
12127 if (uj)
12128 vty_out(vty, "{\n");
12129
12130 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12131 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12132 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12133 ? AFI_IP
12134 : AFI_IP6;
12135 FOREACH_SAFI (safi) {
12136 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12137 continue;
12138
12139 if (uj) {
12140 if (first)
12141 first = false;
12142 else
12143 vty_out(vty, ",\n");
12144 vty_out(vty, "\"%s\":{\n",
12145 get_afi_safi_str(afi, safi,
12146 true));
12147 } else
12148 vty_out(vty,
12149 "\nFor address family: %s\n",
12150 get_afi_safi_str(afi, safi,
12151 false));
12152
12153 if (community)
12154 bgp_show_community(vty, bgp, community,
12155 exact_match, afi,
12156 safi, show_flags);
12157 else if (prefix_version)
12158 return bgp_show(vty, bgp, afi, safi,
12159 sh_type, prefix_version,
12160 show_flags,
12161 rpki_target_state);
12162 else if (bgp_community_alias)
12163 return bgp_show(
12164 vty, bgp, afi, safi, sh_type,
12165 bgp_community_alias, show_flags,
12166 rpki_target_state);
12167 else
12168 bgp_show(vty, bgp, afi, safi, sh_type,
12169 NULL, show_flags,
12170 rpki_target_state);
12171 if (uj)
12172 vty_out(vty, "}\n");
12173 }
12174 } else {
12175 /* show <ip> bgp all: for each AFI and SAFI*/
12176 FOREACH_AFI_SAFI (afi, safi) {
12177 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12178 continue;
12179
12180 if (uj) {
12181 if (first)
12182 first = false;
12183 else
12184 vty_out(vty, ",\n");
12185
12186 vty_out(vty, "\"%s\":{\n",
12187 get_afi_safi_str(afi, safi,
12188 true));
12189 } else
12190 vty_out(vty,
12191 "\nFor address family: %s\n",
12192 get_afi_safi_str(afi, safi,
12193 false));
12194
12195 if (community)
12196 bgp_show_community(vty, bgp, community,
12197 exact_match, afi,
12198 safi, show_flags);
12199 else if (prefix_version)
12200 return bgp_show(vty, bgp, afi, safi,
12201 sh_type, prefix_version,
12202 show_flags,
12203 rpki_target_state);
12204 else
12205 bgp_show(vty, bgp, afi, safi, sh_type,
12206 NULL, show_flags,
12207 rpki_target_state);
12208 if (uj)
12209 vty_out(vty, "}\n");
12210 }
12211 }
12212 if (uj)
12213 vty_out(vty, "}\n");
12214 }
12215 return CMD_SUCCESS;
12216 }
12217
12218 DEFUN (show_ip_bgp_route,
12219 show_ip_bgp_route_cmd,
12220 "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]",
12221 SHOW_STR
12222 IP_STR
12223 BGP_STR
12224 BGP_INSTANCE_HELP_STR
12225 BGP_AFI_HELP_STR
12226 BGP_SAFI_WITH_LABEL_HELP_STR
12227 "Network in the BGP routing table to display\n"
12228 "IPv4 prefix\n"
12229 "Network in the BGP routing table to display\n"
12230 "IPv6 prefix\n"
12231 "Display only the bestpath\n"
12232 "Display only multipaths\n"
12233 "Display only paths that match the specified rpki state\n"
12234 "A valid path as determined by rpki\n"
12235 "A invalid path as determined by rpki\n"
12236 "A path that has no rpki data\n"
12237 JSON_STR)
12238 {
12239 int prefix_check = 0;
12240
12241 afi_t afi = AFI_IP6;
12242 safi_t safi = SAFI_UNICAST;
12243 char *prefix = NULL;
12244 struct bgp *bgp = NULL;
12245 enum bgp_path_type path_type;
12246 bool uj = use_json(argc, argv);
12247
12248 int idx = 0;
12249
12250 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12251 &bgp, uj);
12252 if (!idx)
12253 return CMD_WARNING;
12254
12255 if (!bgp) {
12256 vty_out(vty,
12257 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12258 return CMD_WARNING;
12259 }
12260
12261 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12262 if (argv_find(argv, argc, "A.B.C.D", &idx)
12263 || argv_find(argv, argc, "X:X::X:X", &idx))
12264 prefix_check = 0;
12265 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12266 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12267 prefix_check = 1;
12268
12269 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12270 && afi != AFI_IP6) {
12271 vty_out(vty,
12272 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12273 return CMD_WARNING;
12274 }
12275 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12276 && afi != AFI_IP) {
12277 vty_out(vty,
12278 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12279 return CMD_WARNING;
12280 }
12281
12282 prefix = argv[idx]->arg;
12283
12284 /* [<bestpath|multipath>] */
12285 if (argv_find(argv, argc, "bestpath", &idx))
12286 path_type = BGP_PATH_SHOW_BESTPATH;
12287 else if (argv_find(argv, argc, "multipath", &idx))
12288 path_type = BGP_PATH_SHOW_MULTIPATH;
12289 else
12290 path_type = BGP_PATH_SHOW_ALL;
12291
12292 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12293 path_type, RPKI_NOT_BEING_USED, uj);
12294 }
12295
12296 DEFUN (show_ip_bgp_regexp,
12297 show_ip_bgp_regexp_cmd,
12298 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12299 SHOW_STR
12300 IP_STR
12301 BGP_STR
12302 BGP_INSTANCE_HELP_STR
12303 BGP_AFI_HELP_STR
12304 BGP_SAFI_WITH_LABEL_HELP_STR
12305 "Display routes matching the AS path regular expression\n"
12306 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12307 JSON_STR)
12308 {
12309 afi_t afi = AFI_IP6;
12310 safi_t safi = SAFI_UNICAST;
12311 struct bgp *bgp = NULL;
12312 bool uj = use_json(argc, argv);
12313 char *regstr = NULL;
12314
12315 int idx = 0;
12316 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12317 &bgp, false);
12318 if (!idx)
12319 return CMD_WARNING;
12320
12321 // get index of regex
12322 if (argv_find(argv, argc, "REGEX", &idx))
12323 regstr = argv[idx]->arg;
12324
12325 assert(regstr);
12326 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12327 bgp_show_type_regexp, uj);
12328 }
12329
12330 DEFPY (show_ip_bgp_instance_all,
12331 show_ip_bgp_instance_all_cmd,
12332 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12333 SHOW_STR
12334 IP_STR
12335 BGP_STR
12336 BGP_INSTANCE_ALL_HELP_STR
12337 BGP_AFI_HELP_STR
12338 BGP_SAFI_WITH_LABEL_HELP_STR
12339 JSON_STR
12340 "Increase table width for longer prefixes\n")
12341 {
12342 afi_t afi = AFI_IP;
12343 safi_t safi = SAFI_UNICAST;
12344 struct bgp *bgp = NULL;
12345 int idx = 0;
12346 uint8_t show_flags = 0;
12347
12348 if (uj) {
12349 argc--;
12350 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12351 }
12352
12353 if (wide)
12354 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12355
12356 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12357 &bgp, uj);
12358 if (!idx)
12359 return CMD_WARNING;
12360
12361 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12362 return CMD_SUCCESS;
12363 }
12364
12365 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12366 afi_t afi, safi_t safi, enum bgp_show_type type,
12367 bool use_json)
12368 {
12369 regex_t *regex;
12370 int rc;
12371 uint8_t show_flags = 0;
12372
12373 if (use_json)
12374 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12375
12376 if (!config_bgp_aspath_validate(regstr)) {
12377 vty_out(vty, "Invalid character in REGEX %s\n",
12378 regstr);
12379 return CMD_WARNING_CONFIG_FAILED;
12380 }
12381
12382 regex = bgp_regcomp(regstr);
12383 if (!regex) {
12384 vty_out(vty, "Can't compile regexp %s\n", regstr);
12385 return CMD_WARNING;
12386 }
12387
12388 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
12389 RPKI_NOT_BEING_USED);
12390 bgp_regex_free(regex);
12391 return rc;
12392 }
12393
12394 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
12395 const char *prefix_list_str, afi_t afi,
12396 safi_t safi, enum bgp_show_type type)
12397 {
12398 struct prefix_list *plist;
12399 uint8_t show_flags = 0;
12400
12401 plist = prefix_list_lookup(afi, prefix_list_str);
12402 if (plist == NULL) {
12403 vty_out(vty, "%% %s is not a valid prefix-list name\n",
12404 prefix_list_str);
12405 return CMD_WARNING;
12406 }
12407
12408 return bgp_show(vty, bgp, afi, safi, type, plist, show_flags,
12409 RPKI_NOT_BEING_USED);
12410 }
12411
12412 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
12413 const char *filter, afi_t afi, safi_t safi,
12414 enum bgp_show_type type)
12415 {
12416 struct as_list *as_list;
12417 uint8_t show_flags = 0;
12418
12419 as_list = as_list_lookup(filter);
12420 if (as_list == NULL) {
12421 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
12422 filter);
12423 return CMD_WARNING;
12424 }
12425
12426 return bgp_show(vty, bgp, afi, safi, type, as_list, show_flags,
12427 RPKI_NOT_BEING_USED);
12428 }
12429
12430 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
12431 const char *rmap_str, afi_t afi, safi_t safi,
12432 enum bgp_show_type type)
12433 {
12434 struct route_map *rmap;
12435 uint8_t show_flags = 0;
12436
12437 rmap = route_map_lookup_by_name(rmap_str);
12438 if (!rmap) {
12439 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
12440 return CMD_WARNING;
12441 }
12442
12443 return bgp_show(vty, bgp, afi, safi, type, rmap, show_flags,
12444 RPKI_NOT_BEING_USED);
12445 }
12446
12447 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12448 const char *comstr, int exact, afi_t afi,
12449 safi_t safi, uint8_t show_flags)
12450 {
12451 struct community *com;
12452 int ret = 0;
12453
12454 com = community_str2com(comstr);
12455 if (!com) {
12456 vty_out(vty, "%% Community malformed: %s\n", comstr);
12457 return CMD_WARNING;
12458 }
12459
12460 ret = bgp_show(vty, bgp, afi, safi,
12461 (exact ? bgp_show_type_community_exact
12462 : bgp_show_type_community),
12463 com, show_flags, RPKI_NOT_BEING_USED);
12464 community_free(&com);
12465
12466 return ret;
12467 }
12468
12469 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
12470 const char *com, int exact, afi_t afi,
12471 safi_t safi)
12472 {
12473 struct community_list *list;
12474 uint8_t show_flags = 0;
12475
12476 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
12477 if (list == NULL) {
12478 vty_out(vty, "%% %s is not a valid community-list name\n", com);
12479 return CMD_WARNING;
12480 }
12481
12482 return bgp_show(vty, bgp, afi, safi,
12483 (exact ? bgp_show_type_community_list_exact
12484 : bgp_show_type_community_list),
12485 list, show_flags, RPKI_NOT_BEING_USED);
12486 }
12487
12488 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
12489 const char *prefix, afi_t afi, safi_t safi,
12490 enum bgp_show_type type)
12491 {
12492 int ret;
12493 struct prefix *p;
12494 uint8_t show_flags = 0;
12495
12496 p = prefix_new();
12497
12498 ret = str2prefix(prefix, p);
12499 if (!ret) {
12500 vty_out(vty, "%% Malformed Prefix\n");
12501 return CMD_WARNING;
12502 }
12503
12504 ret = bgp_show(vty, bgp, afi, safi, type, p, show_flags,
12505 RPKI_NOT_BEING_USED);
12506 prefix_free(&p);
12507 return ret;
12508 }
12509
12510 enum bgp_stats {
12511 BGP_STATS_MAXBITLEN = 0,
12512 BGP_STATS_RIB,
12513 BGP_STATS_PREFIXES,
12514 BGP_STATS_TOTPLEN,
12515 BGP_STATS_UNAGGREGATEABLE,
12516 BGP_STATS_MAX_AGGREGATEABLE,
12517 BGP_STATS_AGGREGATES,
12518 BGP_STATS_SPACE,
12519 BGP_STATS_ASPATH_COUNT,
12520 BGP_STATS_ASPATH_MAXHOPS,
12521 BGP_STATS_ASPATH_TOTHOPS,
12522 BGP_STATS_ASPATH_MAXSIZE,
12523 BGP_STATS_ASPATH_TOTSIZE,
12524 BGP_STATS_ASN_HIGHEST,
12525 BGP_STATS_MAX,
12526 };
12527
12528 #define TABLE_STATS_IDX_VTY 0
12529 #define TABLE_STATS_IDX_JSON 1
12530
12531 static const char *table_stats_strs[][2] = {
12532 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12533 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12534 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12535 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12536 "unaggregateablePrefixes"},
12537 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12538 "maximumAggregateablePrefixes"},
12539 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12540 "bgpAggregateAdvertisements"},
12541 [BGP_STATS_SPACE] = {"Address space advertised",
12542 "addressSpaceAdvertised"},
12543 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12544 "advertisementsWithPaths"},
12545 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12546 "longestAsPath"},
12547 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12548 "largestAsPath"},
12549 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12550 "averageAsPathLengthHops"},
12551 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12552 "averageAsPathSizeBytes"},
12553 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12554 [BGP_STATS_MAX] = {NULL, NULL}
12555 };
12556
12557 struct bgp_table_stats {
12558 struct bgp_table *table;
12559 unsigned long long counts[BGP_STATS_MAX];
12560 double total_space;
12561 };
12562
12563 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12564 struct bgp_table_stats *ts, unsigned int space)
12565 {
12566 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12567 struct bgp_path_info *pi;
12568 const struct prefix *rn_p;
12569
12570 if (!bgp_dest_has_bgp_path_info_data(dest))
12571 return;
12572
12573 rn_p = bgp_dest_get_prefix(dest);
12574 ts->counts[BGP_STATS_PREFIXES]++;
12575 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12576
12577 /* check if the prefix is included by any other announcements */
12578 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12579 pdest = bgp_dest_parent_nolock(pdest);
12580
12581 if (pdest == NULL || pdest == top) {
12582 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12583 /* announced address space */
12584 if (space)
12585 ts->total_space += pow(2.0, space - rn_p->prefixlen);
12586 } else if (bgp_dest_has_bgp_path_info_data(pdest))
12587 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
12588
12589
12590 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
12591 ts->counts[BGP_STATS_RIB]++;
12592
12593 if (CHECK_FLAG(pi->attr->flag,
12594 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
12595 ts->counts[BGP_STATS_AGGREGATES]++;
12596
12597 /* as-path stats */
12598 if (pi->attr->aspath) {
12599 unsigned int hops = aspath_count_hops(pi->attr->aspath);
12600 unsigned int size = aspath_size(pi->attr->aspath);
12601 as_t highest = aspath_highest(pi->attr->aspath);
12602
12603 ts->counts[BGP_STATS_ASPATH_COUNT]++;
12604
12605 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
12606 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
12607
12608 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
12609 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
12610
12611 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
12612 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
12613 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
12614 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
12615 }
12616 }
12617 }
12618
12619 static int bgp_table_stats_walker(struct thread *t)
12620 {
12621 struct bgp_dest *dest, *ndest;
12622 struct bgp_dest *top;
12623 struct bgp_table_stats *ts = THREAD_ARG(t);
12624 unsigned int space = 0;
12625
12626 if (!(top = bgp_table_top(ts->table)))
12627 return 0;
12628
12629 switch (ts->table->afi) {
12630 case AFI_IP:
12631 space = IPV4_MAX_BITLEN;
12632 break;
12633 case AFI_IP6:
12634 space = IPV6_MAX_BITLEN;
12635 break;
12636 case AFI_L2VPN:
12637 space = EVPN_ROUTE_PREFIXLEN;
12638 break;
12639 default:
12640 return 0;
12641 }
12642
12643 ts->counts[BGP_STATS_MAXBITLEN] = space;
12644
12645 for (dest = top; dest; dest = bgp_route_next(dest)) {
12646 if (ts->table->safi == SAFI_MPLS_VPN
12647 || ts->table->safi == SAFI_ENCAP
12648 || ts->table->safi == SAFI_EVPN) {
12649 struct bgp_table *table;
12650
12651 table = bgp_dest_get_bgp_table_info(dest);
12652 if (!table)
12653 continue;
12654
12655 top = bgp_table_top(table);
12656 for (ndest = bgp_table_top(table); ndest;
12657 ndest = bgp_route_next(ndest))
12658 bgp_table_stats_rn(ndest, top, ts, space);
12659 } else {
12660 bgp_table_stats_rn(dest, top, ts, space);
12661 }
12662 }
12663
12664 return 0;
12665 }
12666
12667 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
12668 struct json_object *json_array)
12669 {
12670 struct listnode *node, *nnode;
12671 struct bgp *bgp;
12672
12673 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
12674 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12675 }
12676
12677 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12678 safi_t safi, struct json_object *json_array)
12679 {
12680 struct bgp_table_stats ts;
12681 unsigned int i;
12682 int ret = CMD_SUCCESS;
12683 char temp_buf[20];
12684 struct json_object *json = NULL;
12685
12686 if (json_array)
12687 json = json_object_new_object();
12688
12689 if (!bgp->rib[afi][safi]) {
12690 char warning_msg[50];
12691
12692 snprintf(warning_msg, sizeof(warning_msg),
12693 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
12694 safi);
12695
12696 if (!json)
12697 vty_out(vty, "%s\n", warning_msg);
12698 else
12699 json_object_string_add(json, "warning", warning_msg);
12700
12701 ret = CMD_WARNING;
12702 goto end_table_stats;
12703 }
12704
12705 if (!json)
12706 vty_out(vty, "BGP %s RIB statistics (%s)\n",
12707 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
12708 else
12709 json_object_string_add(json, "instance", bgp->name_pretty);
12710
12711 /* labeled-unicast routes live in the unicast table */
12712 if (safi == SAFI_LABELED_UNICAST)
12713 safi = SAFI_UNICAST;
12714
12715 memset(&ts, 0, sizeof(ts));
12716 ts.table = bgp->rib[afi][safi];
12717 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
12718
12719 for (i = 0; i < BGP_STATS_MAX; i++) {
12720 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
12721 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
12722 continue;
12723
12724 switch (i) {
12725 case BGP_STATS_ASPATH_TOTHOPS:
12726 case BGP_STATS_ASPATH_TOTSIZE:
12727 if (!json) {
12728 snprintf(
12729 temp_buf, sizeof(temp_buf), "%12.2f",
12730 ts.counts[i]
12731 ? (float)ts.counts[i]
12732 / (float)ts.counts
12733 [BGP_STATS_ASPATH_COUNT]
12734 : 0);
12735 vty_out(vty, "%-30s: %s",
12736 table_stats_strs[i]
12737 [TABLE_STATS_IDX_VTY],
12738 temp_buf);
12739 } else {
12740 json_object_double_add(
12741 json,
12742 table_stats_strs[i]
12743 [TABLE_STATS_IDX_JSON],
12744 ts.counts[i]
12745 ? (double)ts.counts[i]
12746 / (double)ts.counts
12747 [BGP_STATS_ASPATH_COUNT]
12748 : 0);
12749 }
12750 break;
12751 case BGP_STATS_TOTPLEN:
12752 if (!json) {
12753 snprintf(
12754 temp_buf, sizeof(temp_buf), "%12.2f",
12755 ts.counts[i]
12756 ? (float)ts.counts[i]
12757 / (float)ts.counts
12758 [BGP_STATS_PREFIXES]
12759 : 0);
12760 vty_out(vty, "%-30s: %s",
12761 table_stats_strs[i]
12762 [TABLE_STATS_IDX_VTY],
12763 temp_buf);
12764 } else {
12765 json_object_double_add(
12766 json,
12767 table_stats_strs[i]
12768 [TABLE_STATS_IDX_JSON],
12769 ts.counts[i]
12770 ? (double)ts.counts[i]
12771 / (double)ts.counts
12772 [BGP_STATS_PREFIXES]
12773 : 0);
12774 }
12775 break;
12776 case BGP_STATS_SPACE:
12777 if (!json) {
12778 snprintf(temp_buf, sizeof(temp_buf), "%12g",
12779 ts.total_space);
12780 vty_out(vty, "%-30s: %s\n",
12781 table_stats_strs[i]
12782 [TABLE_STATS_IDX_VTY],
12783 temp_buf);
12784 } else {
12785 json_object_double_add(
12786 json,
12787 table_stats_strs[i]
12788 [TABLE_STATS_IDX_JSON],
12789 (double)ts.total_space);
12790 }
12791 if (afi == AFI_IP6) {
12792 if (!json) {
12793 snprintf(temp_buf, sizeof(temp_buf),
12794 "%12g",
12795 ts.total_space
12796 * pow(2.0, -128 + 32));
12797 vty_out(vty, "%30s: %s\n",
12798 "/32 equivalent %s\n",
12799 temp_buf);
12800 } else {
12801 json_object_double_add(
12802 json, "/32equivalent",
12803 (double)(ts.total_space
12804 * pow(2.0,
12805 -128 + 32)));
12806 }
12807 if (!json) {
12808 snprintf(temp_buf, sizeof(temp_buf),
12809 "%12g",
12810 ts.total_space
12811 * pow(2.0, -128 + 48));
12812 vty_out(vty, "%30s: %s\n",
12813 "/48 equivalent %s\n",
12814 temp_buf);
12815 } else {
12816 json_object_double_add(
12817 json, "/48equivalent",
12818 (double)(ts.total_space
12819 * pow(2.0,
12820 -128 + 48)));
12821 }
12822 } else {
12823 if (!json) {
12824 snprintf(temp_buf, sizeof(temp_buf),
12825 "%12.2f",
12826 ts.total_space * 100.
12827 * pow(2.0, -32));
12828 vty_out(vty, "%30s: %s\n",
12829 "% announced ", temp_buf);
12830 } else {
12831 json_object_double_add(
12832 json, "%announced",
12833 (double)(ts.total_space * 100.
12834 * pow(2.0, -32)));
12835 }
12836 if (!json) {
12837 snprintf(temp_buf, sizeof(temp_buf),
12838 "%12.2f",
12839 ts.total_space
12840 * pow(2.0, -32 + 8));
12841 vty_out(vty, "%30s: %s\n",
12842 "/8 equivalent ", temp_buf);
12843 } else {
12844 json_object_double_add(
12845 json, "/8equivalent",
12846 (double)(ts.total_space
12847 * pow(2.0, -32 + 8)));
12848 }
12849 if (!json) {
12850 snprintf(temp_buf, sizeof(temp_buf),
12851 "%12.2f",
12852 ts.total_space
12853 * pow(2.0, -32 + 24));
12854 vty_out(vty, "%30s: %s\n",
12855 "/24 equivalent ", temp_buf);
12856 } else {
12857 json_object_double_add(
12858 json, "/24equivalent",
12859 (double)(ts.total_space
12860 * pow(2.0, -32 + 24)));
12861 }
12862 }
12863 break;
12864 default:
12865 if (!json) {
12866 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
12867 ts.counts[i]);
12868 vty_out(vty, "%-30s: %s",
12869 table_stats_strs[i]
12870 [TABLE_STATS_IDX_VTY],
12871 temp_buf);
12872 } else {
12873 json_object_int_add(
12874 json,
12875 table_stats_strs[i]
12876 [TABLE_STATS_IDX_JSON],
12877 ts.counts[i]);
12878 }
12879 }
12880 if (!json)
12881 vty_out(vty, "\n");
12882 }
12883 end_table_stats:
12884 if (json)
12885 json_object_array_add(json_array, json);
12886 return ret;
12887 }
12888
12889 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12890 safi_t safi, struct json_object *json_array)
12891 {
12892 if (!bgp) {
12893 bgp_table_stats_all(vty, afi, safi, json_array);
12894 return CMD_SUCCESS;
12895 }
12896
12897 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12898 }
12899
12900 enum bgp_pcounts {
12901 PCOUNT_ADJ_IN = 0,
12902 PCOUNT_DAMPED,
12903 PCOUNT_REMOVED,
12904 PCOUNT_HISTORY,
12905 PCOUNT_STALE,
12906 PCOUNT_VALID,
12907 PCOUNT_ALL,
12908 PCOUNT_COUNTED,
12909 PCOUNT_BPATH_SELECTED,
12910 PCOUNT_PFCNT, /* the figure we display to users */
12911 PCOUNT_MAX,
12912 };
12913
12914 static const char *const pcount_strs[] = {
12915 [PCOUNT_ADJ_IN] = "Adj-in",
12916 [PCOUNT_DAMPED] = "Damped",
12917 [PCOUNT_REMOVED] = "Removed",
12918 [PCOUNT_HISTORY] = "History",
12919 [PCOUNT_STALE] = "Stale",
12920 [PCOUNT_VALID] = "Valid",
12921 [PCOUNT_ALL] = "All RIB",
12922 [PCOUNT_COUNTED] = "PfxCt counted",
12923 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
12924 [PCOUNT_PFCNT] = "Useable",
12925 [PCOUNT_MAX] = NULL,
12926 };
12927
12928 struct peer_pcounts {
12929 unsigned int count[PCOUNT_MAX];
12930 const struct peer *peer;
12931 const struct bgp_table *table;
12932 safi_t safi;
12933 };
12934
12935 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
12936 {
12937 const struct bgp_adj_in *ain;
12938 const struct bgp_path_info *pi;
12939 const struct peer *peer = pc->peer;
12940
12941 for (ain = rn->adj_in; ain; ain = ain->next)
12942 if (ain->peer == peer)
12943 pc->count[PCOUNT_ADJ_IN]++;
12944
12945 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
12946
12947 if (pi->peer != peer)
12948 continue;
12949
12950 pc->count[PCOUNT_ALL]++;
12951
12952 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
12953 pc->count[PCOUNT_DAMPED]++;
12954 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
12955 pc->count[PCOUNT_HISTORY]++;
12956 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
12957 pc->count[PCOUNT_REMOVED]++;
12958 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
12959 pc->count[PCOUNT_STALE]++;
12960 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
12961 pc->count[PCOUNT_VALID]++;
12962 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12963 pc->count[PCOUNT_PFCNT]++;
12964 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
12965 pc->count[PCOUNT_BPATH_SELECTED]++;
12966
12967 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
12968 pc->count[PCOUNT_COUNTED]++;
12969 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12970 flog_err(
12971 EC_LIB_DEVELOPMENT,
12972 "Attempting to count but flags say it is unusable");
12973 } else {
12974 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
12975 flog_err(
12976 EC_LIB_DEVELOPMENT,
12977 "Not counted but flags say we should");
12978 }
12979 }
12980 }
12981
12982 static int bgp_peer_count_walker(struct thread *t)
12983 {
12984 struct bgp_dest *rn, *rm;
12985 const struct bgp_table *table;
12986 struct peer_pcounts *pc = THREAD_ARG(t);
12987
12988 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
12989 || pc->safi == SAFI_EVPN) {
12990 /* Special handling for 2-level routing tables. */
12991 for (rn = bgp_table_top(pc->table); rn;
12992 rn = bgp_route_next(rn)) {
12993 table = bgp_dest_get_bgp_table_info(rn);
12994 if (table != NULL)
12995 for (rm = bgp_table_top(table); rm;
12996 rm = bgp_route_next(rm))
12997 bgp_peer_count_proc(rm, pc);
12998 }
12999 } else
13000 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13001 bgp_peer_count_proc(rn, pc);
13002
13003 return 0;
13004 }
13005
13006 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13007 safi_t safi, bool use_json)
13008 {
13009 struct peer_pcounts pcounts = {.peer = peer};
13010 unsigned int i;
13011 json_object *json = NULL;
13012 json_object *json_loop = NULL;
13013
13014 if (use_json) {
13015 json = json_object_new_object();
13016 json_loop = json_object_new_object();
13017 }
13018
13019 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13020 || !peer->bgp->rib[afi][safi]) {
13021 if (use_json) {
13022 json_object_string_add(
13023 json, "warning",
13024 "No such neighbor or address family");
13025 vty_out(vty, "%s\n", json_object_to_json_string(json));
13026 json_object_free(json);
13027 json_object_free(json_loop);
13028 } else
13029 vty_out(vty, "%% No such neighbor or address family\n");
13030
13031 return CMD_WARNING;
13032 }
13033
13034 memset(&pcounts, 0, sizeof(pcounts));
13035 pcounts.peer = peer;
13036 pcounts.table = peer->bgp->rib[afi][safi];
13037 pcounts.safi = safi;
13038
13039 /* in-place call via thread subsystem so as to record execution time
13040 * stats for the thread-walk (i.e. ensure this can't be blamed on
13041 * on just vty_read()).
13042 */
13043 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13044
13045 if (use_json) {
13046 json_object_string_add(json, "prefixCountsFor", peer->host);
13047 json_object_string_add(json, "multiProtocol",
13048 get_afi_safi_str(afi, safi, true));
13049 json_object_int_add(json, "pfxCounter",
13050 peer->pcount[afi][safi]);
13051
13052 for (i = 0; i < PCOUNT_MAX; i++)
13053 json_object_int_add(json_loop, pcount_strs[i],
13054 pcounts.count[i]);
13055
13056 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13057
13058 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13059 json_object_string_add(json, "pfxctDriftFor",
13060 peer->host);
13061 json_object_string_add(
13062 json, "recommended",
13063 "Please report this bug, with the above command output");
13064 }
13065 vty_out(vty, "%s\n", json_object_to_json_string_ext(
13066 json, JSON_C_TO_STRING_PRETTY));
13067 json_object_free(json);
13068 } else {
13069
13070 if (peer->hostname
13071 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13072 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13073 peer->hostname, peer->host,
13074 get_afi_safi_str(afi, safi, false));
13075 } else {
13076 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13077 get_afi_safi_str(afi, safi, false));
13078 }
13079
13080 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13081 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13082
13083 for (i = 0; i < PCOUNT_MAX; i++)
13084 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13085 pcounts.count[i]);
13086
13087 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13088 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13089 vty_out(vty,
13090 "Please report this bug, with the above command output\n");
13091 }
13092 }
13093
13094 return CMD_SUCCESS;
13095 }
13096
13097 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13098 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13099 "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]",
13100 SHOW_STR
13101 IP_STR
13102 BGP_STR
13103 BGP_INSTANCE_HELP_STR
13104 BGP_AFI_HELP_STR
13105 BGP_SAFI_HELP_STR
13106 "Detailed information on TCP and BGP neighbor connections\n"
13107 "Neighbor to display information about\n"
13108 "Neighbor to display information about\n"
13109 "Neighbor on BGP configured interface\n"
13110 "Display detailed prefix count information\n"
13111 JSON_STR)
13112 {
13113 afi_t afi = AFI_IP6;
13114 safi_t safi = SAFI_UNICAST;
13115 struct peer *peer;
13116 int idx = 0;
13117 struct bgp *bgp = NULL;
13118 bool uj = use_json(argc, argv);
13119
13120 if (uj)
13121 argc--;
13122
13123 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13124 &bgp, uj);
13125 if (!idx)
13126 return CMD_WARNING;
13127
13128 argv_find(argv, argc, "neighbors", &idx);
13129 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13130 if (!peer)
13131 return CMD_WARNING;
13132
13133 return bgp_peer_counts(vty, peer, afi, safi, uj);
13134 }
13135
13136 #ifdef KEEP_OLD_VPN_COMMANDS
13137 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13138 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13139 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13140 SHOW_STR
13141 IP_STR
13142 BGP_STR
13143 BGP_VPNVX_HELP_STR
13144 "Display information about all VPNv4 NLRIs\n"
13145 "Detailed information on TCP and BGP neighbor connections\n"
13146 "Neighbor to display information about\n"
13147 "Neighbor to display information about\n"
13148 "Neighbor on BGP configured interface\n"
13149 "Display detailed prefix count information\n"
13150 JSON_STR)
13151 {
13152 int idx_peer = 6;
13153 struct peer *peer;
13154 bool uj = use_json(argc, argv);
13155
13156 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13157 if (!peer)
13158 return CMD_WARNING;
13159
13160 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13161 }
13162
13163 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13164 show_ip_bgp_vpn_all_route_prefix_cmd,
13165 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13166 SHOW_STR
13167 IP_STR
13168 BGP_STR
13169 BGP_VPNVX_HELP_STR
13170 "Display information about all VPNv4 NLRIs\n"
13171 "Network in the BGP routing table to display\n"
13172 "Network in the BGP routing table to display\n"
13173 JSON_STR)
13174 {
13175 int idx = 0;
13176 char *network = NULL;
13177 struct bgp *bgp = bgp_get_default();
13178 if (!bgp) {
13179 vty_out(vty, "Can't find default instance\n");
13180 return CMD_WARNING;
13181 }
13182
13183 if (argv_find(argv, argc, "A.B.C.D", &idx))
13184 network = argv[idx]->arg;
13185 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13186 network = argv[idx]->arg;
13187 else {
13188 vty_out(vty, "Unable to figure out Network\n");
13189 return CMD_WARNING;
13190 }
13191
13192 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13193 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13194 use_json(argc, argv));
13195 }
13196 #endif /* KEEP_OLD_VPN_COMMANDS */
13197
13198 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13199 show_bgp_l2vpn_evpn_route_prefix_cmd,
13200 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13201 SHOW_STR
13202 BGP_STR
13203 L2VPN_HELP_STR
13204 EVPN_HELP_STR
13205 "Network in the BGP routing table to display\n"
13206 "Network in the BGP routing table to display\n"
13207 "Network in the BGP routing table to display\n"
13208 "Network in the BGP routing table to display\n"
13209 JSON_STR)
13210 {
13211 int idx = 0;
13212 char *network = NULL;
13213 int prefix_check = 0;
13214
13215 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13216 argv_find(argv, argc, "X:X::X:X", &idx))
13217 network = argv[idx]->arg;
13218 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13219 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13220 network = argv[idx]->arg;
13221 prefix_check = 1;
13222 } else {
13223 vty_out(vty, "Unable to figure out Network\n");
13224 return CMD_WARNING;
13225 }
13226 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13227 prefix_check, BGP_PATH_SHOW_ALL,
13228 RPKI_NOT_BEING_USED, use_json(argc, argv));
13229 }
13230
13231 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
13232 struct bgp_table *table, int *header1,
13233 int *header2, json_object *json,
13234 json_object *json_scode,
13235 json_object *json_ocode, bool wide)
13236 {
13237 uint64_t version = table ? table->version : 0;
13238 char buf[BUFSIZ] = {0};
13239
13240 if (*header1) {
13241 if (json) {
13242 json_object_int_add(json, "bgpTableVersion", version);
13243 json_object_string_add(json, "bgpLocalRouterId",
13244 inet_ntop(AF_INET,
13245 &bgp->router_id, buf,
13246 sizeof(buf)));
13247 json_object_int_add(json, "defaultLocPrf",
13248 bgp->default_local_pref);
13249 json_object_int_add(json, "localAS", bgp->as);
13250 json_object_object_add(json, "bgpStatusCodes",
13251 json_scode);
13252 json_object_object_add(json, "bgpOriginCodes",
13253 json_ocode);
13254 } else {
13255 vty_out(vty,
13256 "BGP table version is %" PRIu64
13257 ", local router ID is %pI4, vrf id ",
13258 version, &bgp->router_id);
13259 if (bgp->vrf_id == VRF_UNKNOWN)
13260 vty_out(vty, "%s", VRFID_NONE_STR);
13261 else
13262 vty_out(vty, "%u", bgp->vrf_id);
13263 vty_out(vty, "\n");
13264 vty_out(vty, "Default local pref %u, ",
13265 bgp->default_local_pref);
13266 vty_out(vty, "local AS %u\n", bgp->as);
13267 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13268 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13269 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13270 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13271 }
13272 *header1 = 0;
13273 }
13274 if (*header2) {
13275 if (!json)
13276 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13277 : BGP_SHOW_HEADER));
13278 *header2 = 0;
13279 }
13280 }
13281
13282 static void
13283 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13284 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13285 const char *rmap_name, json_object *json, json_object *json_ar,
13286 json_object *json_scode, json_object *json_ocode,
13287 uint8_t show_flags, int *header1, int *header2, char *rd_str,
13288 unsigned long *output_count, unsigned long *filtered_count)
13289 {
13290 struct bgp_adj_in *ain;
13291 struct bgp_adj_out *adj;
13292 struct bgp_dest *dest;
13293 struct bgp *bgp;
13294 struct attr attr;
13295 int ret;
13296 struct update_subgroup *subgrp;
13297 struct peer_af *paf;
13298 bool route_filtered;
13299 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13300 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13301 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13302 || (safi == SAFI_EVPN))
13303 ? true
13304 : false;
13305
13306 bgp = peer->bgp;
13307
13308 if (!bgp) {
13309 if (use_json) {
13310 json_object_string_add(json, "alert", "no BGP");
13311 vty_out(vty, "%s\n", json_object_to_json_string(json));
13312 json_object_free(json);
13313 } else
13314 vty_out(vty, "%% No bgp\n");
13315 return;
13316 }
13317
13318 subgrp = peer_subgroup(peer, afi, safi);
13319
13320 if (type == bgp_show_adj_route_advertised && subgrp
13321 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13322 char buf[BUFSIZ] = {0};
13323
13324 if (use_json) {
13325 json_object_int_add(json, "bgpTableVersion",
13326 table->version);
13327 json_object_string_add(json, "bgpLocalRouterId",
13328 inet_ntop(AF_INET,
13329 &bgp->router_id, buf,
13330 sizeof(buf)));
13331 json_object_int_add(json, "defaultLocPrf",
13332 bgp->default_local_pref);
13333 json_object_int_add(json, "localAS", bgp->as);
13334 json_object_object_add(json, "bgpStatusCodes",
13335 json_scode);
13336 json_object_object_add(json, "bgpOriginCodes",
13337 json_ocode);
13338 json_object_string_add(
13339 json, "bgpOriginatingDefaultNetwork",
13340 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13341 } else {
13342 vty_out(vty,
13343 "BGP table version is %" PRIu64
13344 ", local router ID is %pI4, vrf id ",
13345 table->version, &bgp->router_id);
13346 if (bgp->vrf_id == VRF_UNKNOWN)
13347 vty_out(vty, "%s", VRFID_NONE_STR);
13348 else
13349 vty_out(vty, "%u", bgp->vrf_id);
13350 vty_out(vty, "\n");
13351 vty_out(vty, "Default local pref %u, ",
13352 bgp->default_local_pref);
13353 vty_out(vty, "local AS %u\n", bgp->as);
13354 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13355 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13356 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13357 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13358
13359 vty_out(vty, "Originating default network %s\n\n",
13360 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13361 }
13362 *header1 = 0;
13363 }
13364
13365 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13366 if (type == bgp_show_adj_route_received
13367 || type == bgp_show_adj_route_filtered) {
13368 for (ain = dest->adj_in; ain; ain = ain->next) {
13369 if (ain->peer != peer)
13370 continue;
13371
13372 show_adj_route_header(vty, bgp, table, header1,
13373 header2, json, json_scode,
13374 json_ocode, wide);
13375
13376 if ((safi == SAFI_MPLS_VPN)
13377 || (safi == SAFI_ENCAP)
13378 || (safi == SAFI_EVPN)) {
13379 if (use_json)
13380 json_object_string_add(
13381 json_ar, "rd", rd_str);
13382 else if (show_rd && rd_str) {
13383 vty_out(vty,
13384 "Route Distinguisher: %s\n",
13385 rd_str);
13386 show_rd = false;
13387 }
13388 }
13389
13390 attr = *ain->attr;
13391 route_filtered = false;
13392
13393 /* Filter prefix using distribute list,
13394 * filter list or prefix list
13395 */
13396 const struct prefix *rn_p =
13397 bgp_dest_get_prefix(dest);
13398 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13399 safi))
13400 == FILTER_DENY)
13401 route_filtered = true;
13402
13403 /* Filter prefix using route-map */
13404 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13405 safi, rmap_name, NULL,
13406 0, NULL);
13407
13408 if (type == bgp_show_adj_route_filtered &&
13409 !route_filtered && ret != RMAP_DENY) {
13410 bgp_attr_undup(&attr, ain->attr);
13411 continue;
13412 }
13413
13414 if (type == bgp_show_adj_route_received
13415 && (route_filtered || ret == RMAP_DENY))
13416 (*filtered_count)++;
13417
13418 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
13419 use_json, json_ar, wide);
13420 bgp_attr_undup(&attr, ain->attr);
13421 (*output_count)++;
13422 }
13423 } else if (type == bgp_show_adj_route_advertised) {
13424 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13425 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13426 if (paf->peer != peer || !adj->attr)
13427 continue;
13428
13429 show_adj_route_header(vty, bgp, table,
13430 header1, header2,
13431 json, json_scode,
13432 json_ocode, wide);
13433
13434 const struct prefix *rn_p =
13435 bgp_dest_get_prefix(dest);
13436
13437 attr = *adj->attr;
13438 ret = bgp_output_modifier(
13439 peer, rn_p, &attr, afi, safi,
13440 rmap_name);
13441
13442 if (ret != RMAP_DENY) {
13443 if ((safi == SAFI_MPLS_VPN)
13444 || (safi == SAFI_ENCAP)
13445 || (safi == SAFI_EVPN)) {
13446 if (use_json)
13447 json_object_string_add(
13448 json_ar,
13449 "rd",
13450 rd_str);
13451 else if (show_rd
13452 && rd_str) {
13453 vty_out(vty,
13454 "Route Distinguisher: %s\n",
13455 rd_str);
13456 show_rd = false;
13457 }
13458 }
13459 route_vty_out_tmp(
13460 vty, dest, rn_p, &attr,
13461 safi, use_json, json_ar,
13462 wide);
13463 (*output_count)++;
13464 } else {
13465 (*filtered_count)++;
13466 }
13467
13468 bgp_attr_undup(&attr, adj->attr);
13469 }
13470 } else if (type == bgp_show_adj_route_bestpath) {
13471 struct bgp_path_info *pi;
13472
13473 show_adj_route_header(vty, bgp, table, header1, header2,
13474 json, json_scode, json_ocode,
13475 wide);
13476
13477 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13478 pi = pi->next) {
13479 if (pi->peer != peer)
13480 continue;
13481
13482 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13483 continue;
13484
13485 route_vty_out_tmp(vty, dest,
13486 bgp_dest_get_prefix(dest),
13487 pi->attr, safi, use_json,
13488 json_ar, wide);
13489 (*output_count)++;
13490 }
13491 }
13492 }
13493 }
13494
13495 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13496 safi_t safi, enum bgp_show_adj_route_type type,
13497 const char *rmap_name, uint8_t show_flags)
13498 {
13499 struct bgp *bgp;
13500 struct bgp_table *table;
13501 json_object *json = NULL;
13502 json_object *json_scode = NULL;
13503 json_object *json_ocode = NULL;
13504 json_object *json_ar = NULL;
13505 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13506
13507 /* Init BGP headers here so they're only displayed once
13508 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13509 */
13510 int header1 = 1;
13511 int header2 = 1;
13512
13513 /*
13514 * Initialize variables for each RD
13515 * All prefixes under an RD is aggregated within "json_routes"
13516 */
13517 char rd_str[BUFSIZ] = {0};
13518 json_object *json_routes = NULL;
13519
13520
13521 /* For 2-tier tables, prefix counts need to be
13522 * maintained across multiple runs of show_adj_route()
13523 */
13524 unsigned long output_count_per_rd;
13525 unsigned long filtered_count_per_rd;
13526 unsigned long output_count = 0;
13527 unsigned long filtered_count = 0;
13528
13529 if (use_json) {
13530 json = json_object_new_object();
13531 json_ar = json_object_new_object();
13532 json_scode = json_object_new_object();
13533 json_ocode = json_object_new_object();
13534
13535 json_object_string_add(json_scode, "suppressed", "s");
13536 json_object_string_add(json_scode, "damped", "d");
13537 json_object_string_add(json_scode, "history", "h");
13538 json_object_string_add(json_scode, "valid", "*");
13539 json_object_string_add(json_scode, "best", ">");
13540 json_object_string_add(json_scode, "multipath", "=");
13541 json_object_string_add(json_scode, "internal", "i");
13542 json_object_string_add(json_scode, "ribFailure", "r");
13543 json_object_string_add(json_scode, "stale", "S");
13544 json_object_string_add(json_scode, "removed", "R");
13545
13546 json_object_string_add(json_ocode, "igp", "i");
13547 json_object_string_add(json_ocode, "egp", "e");
13548 json_object_string_add(json_ocode, "incomplete", "?");
13549 }
13550
13551 if (!peer || !peer->afc[afi][safi]) {
13552 if (use_json) {
13553 json_object_string_add(
13554 json, "warning",
13555 "No such neighbor or address family");
13556 vty_out(vty, "%s\n", json_object_to_json_string(json));
13557 json_object_free(json);
13558 } else
13559 vty_out(vty, "%% No such neighbor or address family\n");
13560
13561 return CMD_WARNING;
13562 }
13563
13564 if ((type == bgp_show_adj_route_received
13565 || type == bgp_show_adj_route_filtered)
13566 && !CHECK_FLAG(peer->af_flags[afi][safi],
13567 PEER_FLAG_SOFT_RECONFIG)) {
13568 if (use_json) {
13569 json_object_string_add(
13570 json, "warning",
13571 "Inbound soft reconfiguration not enabled");
13572 vty_out(vty, "%s\n", json_object_to_json_string(json));
13573 json_object_free(json);
13574 } else
13575 vty_out(vty,
13576 "%% Inbound soft reconfiguration not enabled\n");
13577
13578 return CMD_WARNING;
13579 }
13580
13581 bgp = peer->bgp;
13582
13583 /* labeled-unicast routes live in the unicast table */
13584 if (safi == SAFI_LABELED_UNICAST)
13585 table = bgp->rib[afi][SAFI_UNICAST];
13586 else
13587 table = bgp->rib[afi][safi];
13588
13589 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13590 || (safi == SAFI_EVPN)) {
13591
13592 struct bgp_dest *dest;
13593
13594 for (dest = bgp_table_top(table); dest;
13595 dest = bgp_route_next(dest)) {
13596 table = bgp_dest_get_bgp_table_info(dest);
13597 if (!table)
13598 continue;
13599
13600 output_count_per_rd = 0;
13601 filtered_count_per_rd = 0;
13602
13603 if (use_json)
13604 json_routes = json_object_new_object();
13605
13606 const struct prefix_rd *prd;
13607 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13608 dest);
13609
13610 prefix_rd2str(prd, rd_str, sizeof(rd_str));
13611
13612 show_adj_route(vty, peer, table, afi, safi, type,
13613 rmap_name, json, json_routes, json_scode,
13614 json_ocode, show_flags, &header1,
13615 &header2, rd_str, &output_count_per_rd,
13616 &filtered_count_per_rd);
13617
13618 /* Don't include an empty RD in the output! */
13619 if (json_routes && (output_count_per_rd > 0))
13620 json_object_object_add(json_ar, rd_str,
13621 json_routes);
13622
13623 output_count += output_count_per_rd;
13624 filtered_count += filtered_count_per_rd;
13625 }
13626 } else
13627 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
13628 json, json_ar, json_scode, json_ocode,
13629 show_flags, &header1, &header2, rd_str,
13630 &output_count, &filtered_count);
13631
13632 if (use_json) {
13633 json_object_object_add(json, "advertisedRoutes", json_ar);
13634 json_object_int_add(json, "totalPrefixCounter", output_count);
13635 json_object_int_add(json, "filteredPrefixCounter",
13636 filtered_count);
13637
13638 vty_out(vty, "%s\n",
13639 json_object_to_json_string_ext(
13640 json, JSON_C_TO_STRING_PRETTY));
13641
13642 if (!output_count && !filtered_count) {
13643 json_object_free(json_scode);
13644 json_object_free(json_ocode);
13645 }
13646
13647 if (json)
13648 json_object_free(json);
13649
13650 } else if (output_count > 0) {
13651 if (filtered_count > 0)
13652 vty_out(vty,
13653 "\nTotal number of prefixes %ld (%ld filtered)\n",
13654 output_count, filtered_count);
13655 else
13656 vty_out(vty, "\nTotal number of prefixes %ld\n",
13657 output_count);
13658 }
13659
13660 return CMD_SUCCESS;
13661 }
13662
13663 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
13664 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
13665 "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]",
13666 SHOW_STR
13667 IP_STR
13668 BGP_STR
13669 BGP_INSTANCE_HELP_STR
13670 BGP_AFI_HELP_STR
13671 BGP_SAFI_WITH_LABEL_HELP_STR
13672 "Detailed information on TCP and BGP neighbor connections\n"
13673 "Neighbor to display information about\n"
13674 "Neighbor to display information about\n"
13675 "Neighbor on BGP configured interface\n"
13676 "Display the routes selected by best path\n"
13677 JSON_STR
13678 "Increase table width for longer prefixes\n")
13679 {
13680 afi_t afi = AFI_IP6;
13681 safi_t safi = SAFI_UNICAST;
13682 char *rmap_name = NULL;
13683 char *peerstr = NULL;
13684 struct bgp *bgp = NULL;
13685 struct peer *peer;
13686 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
13687 int idx = 0;
13688 uint8_t show_flags = 0;
13689
13690 if (uj)
13691 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13692
13693 if (wide)
13694 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13695
13696 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13697 &bgp, uj);
13698
13699 if (!idx)
13700 return CMD_WARNING;
13701
13702 argv_find(argv, argc, "neighbors", &idx);
13703 peerstr = argv[++idx]->arg;
13704
13705 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13706 if (!peer)
13707 return CMD_WARNING;
13708
13709 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13710 show_flags);
13711 }
13712
13713 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
13714 show_ip_bgp_instance_neighbor_advertised_route_cmd,
13715 "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]",
13716 SHOW_STR
13717 IP_STR
13718 BGP_STR
13719 BGP_INSTANCE_HELP_STR
13720 BGP_AFI_HELP_STR
13721 BGP_SAFI_WITH_LABEL_HELP_STR
13722 "Display the entries for all address families\n"
13723 "Detailed information on TCP and BGP neighbor connections\n"
13724 "Neighbor to display information about\n"
13725 "Neighbor to display information about\n"
13726 "Neighbor on BGP configured interface\n"
13727 "Display the routes advertised to a BGP neighbor\n"
13728 "Display the received routes from neighbor\n"
13729 "Display the filtered routes received from neighbor\n"
13730 "Route-map to modify the attributes\n"
13731 "Name of the route map\n"
13732 JSON_STR
13733 "Increase table width for longer prefixes\n")
13734 {
13735 afi_t afi = AFI_IP6;
13736 safi_t safi = SAFI_UNICAST;
13737 char *rmap_name = NULL;
13738 char *peerstr = NULL;
13739 struct bgp *bgp = NULL;
13740 struct peer *peer;
13741 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
13742 int idx = 0;
13743 bool first = true;
13744 uint8_t show_flags = 0;
13745
13746 if (uj) {
13747 argc--;
13748 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13749 }
13750
13751 if (all) {
13752 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
13753 if (argv_find(argv, argc, "ipv4", &idx))
13754 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
13755
13756 if (argv_find(argv, argc, "ipv6", &idx))
13757 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
13758 }
13759
13760 if (wide)
13761 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13762
13763 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13764 &bgp, uj);
13765 if (!idx)
13766 return CMD_WARNING;
13767
13768 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13769 argv_find(argv, argc, "neighbors", &idx);
13770 peerstr = argv[++idx]->arg;
13771
13772 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13773 if (!peer)
13774 return CMD_WARNING;
13775
13776 if (argv_find(argv, argc, "advertised-routes", &idx))
13777 type = bgp_show_adj_route_advertised;
13778 else if (argv_find(argv, argc, "received-routes", &idx))
13779 type = bgp_show_adj_route_received;
13780 else if (argv_find(argv, argc, "filtered-routes", &idx))
13781 type = bgp_show_adj_route_filtered;
13782
13783 if (argv_find(argv, argc, "route-map", &idx))
13784 rmap_name = argv[++idx]->arg;
13785
13786 if (!all)
13787 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13788 show_flags);
13789 if (uj)
13790 vty_out(vty, "{\n");
13791
13792 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13793 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
13794 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
13795 : AFI_IP6;
13796 FOREACH_SAFI (safi) {
13797 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
13798 continue;
13799
13800 if (uj) {
13801 if (first)
13802 first = false;
13803 else
13804 vty_out(vty, ",\n");
13805 vty_out(vty, "\"%s\":",
13806 get_afi_safi_str(afi, safi, true));
13807 } else
13808 vty_out(vty, "\nFor address family: %s\n",
13809 get_afi_safi_str(afi, safi, false));
13810
13811 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13812 show_flags);
13813 }
13814 } else {
13815 FOREACH_AFI_SAFI (afi, safi) {
13816 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
13817 continue;
13818
13819 if (uj) {
13820 if (first)
13821 first = false;
13822 else
13823 vty_out(vty, ",\n");
13824 vty_out(vty, "\"%s\":",
13825 get_afi_safi_str(afi, safi, true));
13826 } else
13827 vty_out(vty, "\nFor address family: %s\n",
13828 get_afi_safi_str(afi, safi, false));
13829
13830 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13831 show_flags);
13832 }
13833 }
13834 if (uj)
13835 vty_out(vty, "}\n");
13836
13837 return CMD_SUCCESS;
13838 }
13839
13840 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
13841 show_ip_bgp_neighbor_received_prefix_filter_cmd,
13842 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
13843 SHOW_STR
13844 IP_STR
13845 BGP_STR
13846 "Address Family\n"
13847 "Address Family\n"
13848 "Address Family modifier\n"
13849 "Detailed information on TCP and BGP neighbor connections\n"
13850 "Neighbor to display information about\n"
13851 "Neighbor to display information about\n"
13852 "Neighbor on BGP configured interface\n"
13853 "Display information received from a BGP neighbor\n"
13854 "Display the prefixlist filter\n"
13855 JSON_STR)
13856 {
13857 afi_t afi = AFI_IP6;
13858 safi_t safi = SAFI_UNICAST;
13859 char *peerstr = NULL;
13860
13861 char name[BUFSIZ];
13862 union sockunion su;
13863 struct peer *peer;
13864 int count, ret;
13865
13866 int idx = 0;
13867
13868 /* show [ip] bgp */
13869 if (argv_find(argv, argc, "ip", &idx))
13870 afi = AFI_IP;
13871 /* [<ipv4|ipv6> [unicast]] */
13872 if (argv_find(argv, argc, "ipv4", &idx))
13873 afi = AFI_IP;
13874 if (argv_find(argv, argc, "ipv6", &idx))
13875 afi = AFI_IP6;
13876 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13877 argv_find(argv, argc, "neighbors", &idx);
13878 peerstr = argv[++idx]->arg;
13879
13880 bool uj = use_json(argc, argv);
13881
13882 ret = str2sockunion(peerstr, &su);
13883 if (ret < 0) {
13884 peer = peer_lookup_by_conf_if(NULL, peerstr);
13885 if (!peer) {
13886 if (uj)
13887 vty_out(vty, "{}\n");
13888 else
13889 vty_out(vty,
13890 "%% Malformed address or name: %s\n",
13891 peerstr);
13892 return CMD_WARNING;
13893 }
13894 } else {
13895 peer = peer_lookup(NULL, &su);
13896 if (!peer) {
13897 if (uj)
13898 vty_out(vty, "{}\n");
13899 else
13900 vty_out(vty, "No peer\n");
13901 return CMD_WARNING;
13902 }
13903 }
13904
13905 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
13906 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
13907 if (count) {
13908 if (!uj)
13909 vty_out(vty, "Address Family: %s\n",
13910 get_afi_safi_str(afi, safi, false));
13911 prefix_bgp_show_prefix_list(vty, afi, name, uj);
13912 } else {
13913 if (uj)
13914 vty_out(vty, "{}\n");
13915 else
13916 vty_out(vty, "No functional output\n");
13917 }
13918
13919 return CMD_SUCCESS;
13920 }
13921
13922 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
13923 afi_t afi, safi_t safi,
13924 enum bgp_show_type type, bool use_json)
13925 {
13926 uint8_t show_flags = 0;
13927
13928 if (use_json)
13929 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13930
13931 if (!peer || !peer->afc[afi][safi]) {
13932 if (use_json) {
13933 json_object *json_no = NULL;
13934 json_no = json_object_new_object();
13935 json_object_string_add(
13936 json_no, "warning",
13937 "No such neighbor or address family");
13938 vty_out(vty, "%s\n",
13939 json_object_to_json_string(json_no));
13940 json_object_free(json_no);
13941 } else
13942 vty_out(vty, "%% No such neighbor or address family\n");
13943 return CMD_WARNING;
13944 }
13945
13946 /* labeled-unicast routes live in the unicast table */
13947 if (safi == SAFI_LABELED_UNICAST)
13948 safi = SAFI_UNICAST;
13949
13950 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
13951 RPKI_NOT_BEING_USED);
13952 }
13953
13954 DEFUN (show_ip_bgp_flowspec_routes_detailed,
13955 show_ip_bgp_flowspec_routes_detailed_cmd,
13956 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
13957 SHOW_STR
13958 IP_STR
13959 BGP_STR
13960 BGP_INSTANCE_HELP_STR
13961 BGP_AFI_HELP_STR
13962 "SAFI Flowspec\n"
13963 "Detailed information on flowspec entries\n"
13964 JSON_STR)
13965 {
13966 afi_t afi = AFI_IP;
13967 safi_t safi = SAFI_UNICAST;
13968 struct bgp *bgp = NULL;
13969 int idx = 0;
13970 bool uj = use_json(argc, argv);
13971 uint8_t show_flags = 0;
13972
13973 if (uj) {
13974 argc--;
13975 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13976 }
13977
13978 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13979 &bgp, uj);
13980 if (!idx)
13981 return CMD_WARNING;
13982
13983 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
13984 show_flags, RPKI_NOT_BEING_USED);
13985 }
13986
13987 DEFUN (show_ip_bgp_neighbor_routes,
13988 show_ip_bgp_neighbor_routes_cmd,
13989 "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]",
13990 SHOW_STR
13991 IP_STR
13992 BGP_STR
13993 BGP_INSTANCE_HELP_STR
13994 BGP_AFI_HELP_STR
13995 BGP_SAFI_WITH_LABEL_HELP_STR
13996 "Detailed information on TCP and BGP neighbor connections\n"
13997 "Neighbor to display information about\n"
13998 "Neighbor to display information about\n"
13999 "Neighbor on BGP configured interface\n"
14000 "Display flap statistics of the routes learned from neighbor\n"
14001 "Display the dampened routes received from neighbor\n"
14002 "Display routes learned from neighbor\n"
14003 JSON_STR)
14004 {
14005 char *peerstr = NULL;
14006 struct bgp *bgp = NULL;
14007 afi_t afi = AFI_IP6;
14008 safi_t safi = SAFI_UNICAST;
14009 struct peer *peer;
14010 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14011 int idx = 0;
14012 bool uj = use_json(argc, argv);
14013
14014 if (uj)
14015 argc--;
14016
14017 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14018 &bgp, uj);
14019 if (!idx)
14020 return CMD_WARNING;
14021
14022 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14023 argv_find(argv, argc, "neighbors", &idx);
14024 peerstr = argv[++idx]->arg;
14025
14026 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14027 if (!peer)
14028 return CMD_WARNING;
14029
14030 if (argv_find(argv, argc, "flap-statistics", &idx))
14031 sh_type = bgp_show_type_flap_neighbor;
14032 else if (argv_find(argv, argc, "dampened-routes", &idx))
14033 sh_type = bgp_show_type_damp_neighbor;
14034 else if (argv_find(argv, argc, "routes", &idx))
14035 sh_type = bgp_show_type_neighbor;
14036
14037 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14038 }
14039
14040 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14041
14042 struct bgp_distance {
14043 /* Distance value for the IP source prefix. */
14044 uint8_t distance;
14045
14046 /* Name of the access-list to be matched. */
14047 char *access_list;
14048 };
14049
14050 DEFUN (show_bgp_afi_vpn_rd_route,
14051 show_bgp_afi_vpn_rd_route_cmd,
14052 "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]",
14053 SHOW_STR
14054 BGP_STR
14055 BGP_AFI_HELP_STR
14056 "Address Family modifier\n"
14057 "Display information for a route distinguisher\n"
14058 "Route Distinguisher\n"
14059 "All Route Distinguishers\n"
14060 "Network in the BGP routing table to display\n"
14061 "Network in the BGP routing table to display\n"
14062 JSON_STR)
14063 {
14064 int ret;
14065 struct prefix_rd prd;
14066 afi_t afi = AFI_MAX;
14067 int idx = 0;
14068
14069 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14070 vty_out(vty, "%% Malformed Address Family\n");
14071 return CMD_WARNING;
14072 }
14073
14074 if (!strcmp(argv[5]->arg, "all"))
14075 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14076 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14077 RPKI_NOT_BEING_USED,
14078 use_json(argc, argv));
14079
14080 ret = str2prefix_rd(argv[5]->arg, &prd);
14081 if (!ret) {
14082 vty_out(vty, "%% Malformed Route Distinguisher\n");
14083 return CMD_WARNING;
14084 }
14085
14086 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14087 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14088 use_json(argc, argv));
14089 }
14090
14091 static struct bgp_distance *bgp_distance_new(void)
14092 {
14093 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14094 }
14095
14096 static void bgp_distance_free(struct bgp_distance *bdistance)
14097 {
14098 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14099 }
14100
14101 int bgp_distance_set(uint8_t distance, const char *ip_str,
14102 const char *access_list_str, afi_t afi, safi_t safi,
14103 char *errmsg, size_t errmsg_len)
14104 {
14105 int ret;
14106 struct prefix p;
14107 struct bgp_dest *dest;
14108 struct bgp_distance *bdistance;
14109
14110 ret = str2prefix(ip_str, &p);
14111 if (ret == 0) {
14112 snprintf(errmsg, errmsg_len, "Malformed prefix\n");
14113 return CMD_WARNING_CONFIG_FAILED;
14114 }
14115
14116 /* Get BGP distance node. */
14117 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14118 bdistance = bgp_dest_get_bgp_distance_info(dest);
14119 if (bdistance)
14120 bgp_dest_unlock_node(dest);
14121 else {
14122 bdistance = bgp_distance_new();
14123 bgp_dest_set_bgp_distance_info(dest, bdistance);
14124 }
14125
14126 /* Set distance value. */
14127 bdistance->distance = distance;
14128
14129 /* Reset access-list configuration. */
14130 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14131 if (access_list_str)
14132 bdistance->access_list =
14133 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14134
14135 return CMD_SUCCESS;
14136 }
14137
14138 int bgp_distance_unset(uint8_t distance, const char *ip_str,
14139 const char *access_list_str, afi_t afi, safi_t safi,
14140 char *errmsg, size_t errmsg_len)
14141 {
14142 int ret;
14143 struct prefix p;
14144 struct bgp_dest *dest;
14145 struct bgp_distance *bdistance;
14146
14147 ret = str2prefix(ip_str, &p);
14148 if (ret == 0) {
14149 snprintf(errmsg, errmsg_len, "Malformed prefix\n");
14150 return CMD_WARNING_CONFIG_FAILED;
14151 }
14152
14153 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14154 if (!dest) {
14155 snprintf(errmsg, errmsg_len, "Can't find specified prefix\n");
14156 return CMD_WARNING_CONFIG_FAILED;
14157 }
14158
14159 bdistance = bgp_dest_get_bgp_distance_info(dest);
14160
14161 if (bdistance->distance != distance) {
14162 snprintf(errmsg, errmsg_len,
14163 "Distance does not match configured\n");
14164 return CMD_WARNING_CONFIG_FAILED;
14165 }
14166
14167 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14168 bgp_distance_free(bdistance);
14169
14170 bgp_dest_set_bgp_path_info(dest, NULL);
14171 bgp_dest_unlock_node(dest);
14172 bgp_dest_unlock_node(dest);
14173
14174 return CMD_SUCCESS;
14175 }
14176
14177 /* Apply BGP information to distance method. */
14178 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14179 afi_t afi, safi_t safi, struct bgp *bgp)
14180 {
14181 struct bgp_dest *dest;
14182 struct prefix q = {0};
14183 struct peer *peer;
14184 struct bgp_distance *bdistance;
14185 struct access_list *alist;
14186 struct bgp_static *bgp_static;
14187
14188 if (!bgp)
14189 return 0;
14190
14191 peer = pinfo->peer;
14192
14193 if (pinfo->attr->distance)
14194 return pinfo->attr->distance;
14195
14196 /* Check source address.
14197 * Note: for aggregate route, peer can have unspec af type.
14198 */
14199 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14200 && !sockunion2hostprefix(&peer->su, &q))
14201 return 0;
14202
14203 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14204 if (dest) {
14205 bdistance = bgp_dest_get_bgp_distance_info(dest);
14206 bgp_dest_unlock_node(dest);
14207
14208 if (bdistance->access_list) {
14209 alist = access_list_lookup(afi, bdistance->access_list);
14210 if (alist
14211 && access_list_apply(alist, p) == FILTER_PERMIT)
14212 return bdistance->distance;
14213 } else
14214 return bdistance->distance;
14215 }
14216
14217 /* Backdoor check. */
14218 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14219 if (dest) {
14220 bgp_static = bgp_dest_get_bgp_static_info(dest);
14221 bgp_dest_unlock_node(dest);
14222
14223 if (bgp_static->backdoor) {
14224 if (bgp->distance_local[afi][safi])
14225 return bgp->distance_local[afi][safi];
14226 else
14227 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14228 }
14229 }
14230
14231 if (peer->sort == BGP_PEER_EBGP) {
14232 if (bgp->distance_ebgp[afi][safi])
14233 return bgp->distance_ebgp[afi][safi];
14234 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14235 } else if (peer->sort == BGP_PEER_IBGP) {
14236 if (bgp->distance_ibgp[afi][safi])
14237 return bgp->distance_ibgp[afi][safi];
14238 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14239 } else {
14240 if (bgp->distance_local[afi][safi])
14241 return bgp->distance_local[afi][safi];
14242 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14243 }
14244 }
14245
14246 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14247 * we should tell ZEBRA update the routes for a specific
14248 * AFI/SAFI to reflect changes in RIB.
14249 */
14250 void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi,
14251 safi_t update_safi)
14252 {
14253 afi_t afi;
14254 safi_t safi;
14255
14256 FOREACH_AFI_SAFI (afi, safi) {
14257 if (!bgp_fibupd_safi(safi))
14258 continue;
14259
14260 if (afi != update_afi && safi != update_safi)
14261 continue;
14262
14263 if (BGP_DEBUG(zebra, ZEBRA))
14264 zlog_debug(
14265 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14266 __func__, afi, safi);
14267 bgp_zebra_announce_table(bgp, afi, safi);
14268 }
14269 }
14270
14271 DEFUN_YANG(bgp_distance, bgp_distance_cmd,
14272 "distance bgp (1-255) (1-255) (1-255)",
14273 "Define an administrative distance\n"
14274 "BGP distance\n"
14275 "Distance for routes external to the AS\n"
14276 "Distance for routes internal to the AS\n"
14277 "Distance for local routes\n")
14278 {
14279 int idx_number = 2;
14280 int idx_number_2 = 3;
14281 int idx_number_3 = 4;
14282 afi_t afi;
14283 safi_t safi;
14284 char xpath[XPATH_MAXLEN];
14285
14286 afi = bgp_node_afi(vty);
14287 safi = bgp_node_safi(vty);
14288
14289 snprintf(
14290 xpath, sizeof(xpath),
14291 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
14292 yang_afi_safi_value2identity(afi, safi),
14293 bgp_afi_safi_get_container_str(afi, safi));
14294 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[idx_number]->arg);
14295 snprintf(
14296 xpath, sizeof(xpath),
14297 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
14298 yang_afi_safi_value2identity(afi, safi),
14299 bgp_afi_safi_get_container_str(afi, safi));
14300 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
14301 argv[idx_number_2]->arg);
14302 snprintf(
14303 xpath, sizeof(xpath),
14304 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
14305 yang_afi_safi_value2identity(afi, safi),
14306 bgp_afi_safi_get_container_str(afi, safi));
14307
14308 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
14309 argv[idx_number_3]->arg);
14310
14311 return nb_cli_apply_changes(vty, NULL);
14312 }
14313
14314 DEFUN_YANG(no_bgp_distance, no_bgp_distance_cmd,
14315 "no distance bgp [(1-255) (1-255) (1-255)]",
14316 NO_STR
14317 "Define an administrative distance\n"
14318 "BGP distance\n"
14319 "Distance for routes external to the AS\n"
14320 "Distance for routes internal to the AS\n"
14321 "Distance for local routes\n")
14322 {
14323 afi_t afi;
14324 safi_t safi;
14325 char xpath[XPATH_MAXLEN];
14326
14327 afi = bgp_node_afi(vty);
14328 safi = bgp_node_safi(vty);
14329
14330 snprintf(
14331 xpath, sizeof(xpath),
14332 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
14333 yang_afi_safi_value2identity(afi, safi),
14334 bgp_afi_safi_get_container_str(afi, safi));
14335 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
14336 snprintf(
14337 xpath, sizeof(xpath),
14338 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
14339 yang_afi_safi_value2identity(afi, safi),
14340 bgp_afi_safi_get_container_str(afi, safi));
14341 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
14342 snprintf(
14343 xpath, sizeof(xpath),
14344 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
14345 yang_afi_safi_value2identity(afi, safi),
14346 bgp_afi_safi_get_container_str(afi, safi));
14347
14348 nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
14349
14350 return nb_cli_apply_changes(vty, NULL);
14351 }
14352
14353 void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty,
14354 struct lyd_node *dnode,
14355 bool show_defaults)
14356 {
14357 uint8_t distance_ebgp, distance_ibgp, distance_local;
14358
14359 distance_ebgp = yang_dnode_get_uint8(dnode, "./external");
14360 distance_ibgp = yang_dnode_get_uint8(dnode, "./internal");
14361 distance_local = yang_dnode_get_uint8(dnode, "./local");
14362
14363 vty_out(vty, " distance bgp %d %d %d\n", distance_ebgp, distance_ibgp,
14364 distance_local);
14365 }
14366
14367 DEFPY_YANG(bgp_distance_source,
14368 bgp_distance_source_cmd,
14369 "[no] distance (1-255) <A.B.C.D/M | X:X::X:X/M>$prefix [WORD$acl]",
14370 NO_STR
14371 "Define an administrative distance\n"
14372 "Distance value\n"
14373 "IPv4 source prefix\n"
14374 "IPv6 source prefix\n"
14375 "Access list name\n")
14376 {
14377 afi_t afi;
14378 safi_t safi;
14379 char xpath[XPATH_MAXLEN];
14380
14381 afi = bgp_node_afi(vty);
14382 safi = bgp_node_safi(vty);
14383
14384 if (!no) {
14385 nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
14386 nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
14387 distance_str);
14388 if (acl)
14389 nb_cli_enqueue_change(vty,
14390 "./access-list-policy-export",
14391 NB_OP_CREATE, acl);
14392 else
14393 nb_cli_enqueue_change(vty,
14394 "./access-list-policy-export",
14395 NB_OP_DESTROY, NULL);
14396 } else {
14397 nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
14398 }
14399
14400 snprintf(
14401 xpath, sizeof(xpath),
14402 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance-route[prefix='%s']",
14403 yang_afi_safi_value2identity(afi, safi),
14404 bgp_afi_safi_get_container_str(afi, safi), prefix_str);
14405
14406 return nb_cli_apply_changes(vty, xpath);
14407 }
14408
14409 void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
14410 struct vty *vty, struct lyd_node *dnode, bool show_defaults)
14411 {
14412 vty_out(vty, " distance %d %s %s\n",
14413 yang_dnode_get_uint8(dnode, "./distance"),
14414 yang_dnode_get_string(dnode, "./prefix"),
14415 (yang_dnode_exists(dnode, "./access-list-policy-export"))
14416 ? yang_dnode_get_string(dnode,
14417 "./access-list-policy-export")
14418 : "");
14419 }
14420
14421 DEFPY_YANG(
14422 bgp_dampening, bgp_dampening_cmd,
14423 "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_suppress]]",
14424 NO_STR
14425 "BGP Specific commands\n"
14426 "Enable route-flap dampening\n"
14427 "Half-life time for the penalty\n"
14428 "Value to start reusing a route\n"
14429 "Value to start suppressing a route\n"
14430 "Maximum duration to suppress a stable route\n")
14431 {
14432 afi_t afi;
14433 safi_t safi;
14434 char xpath[XPATH_MAXLEN];
14435
14436 afi = bgp_node_afi(vty);
14437 safi = bgp_node_safi(vty);
14438
14439 if (!no) {
14440 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
14441 if (argc == 6) {
14442 nb_cli_enqueue_change(vty, "./reach-decay",
14443 NB_OP_MODIFY, halflife_str);
14444 nb_cli_enqueue_change(vty, "./reuse-above",
14445 NB_OP_MODIFY, reuse_str);
14446 nb_cli_enqueue_change(vty, "./suppress-above",
14447 NB_OP_MODIFY, suppress_str);
14448 nb_cli_enqueue_change(vty, "./unreach-decay",
14449 NB_OP_MODIFY, max_suppress_str);
14450 } if (argc == 3) {
14451 nb_cli_enqueue_change(vty, "./reach-decay",
14452 NB_OP_MODIFY, halflife_str);
14453 }
14454 } else {
14455 nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "false");
14456 }
14457
14458 snprintf(
14459 xpath, sizeof(xpath),
14460 "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/route-flap-dampening",
14461 yang_afi_safi_value2identity(afi, safi),
14462 bgp_afi_safi_get_container_str(afi, safi));
14463
14464 return nb_cli_apply_changes(vty, xpath);
14465 }
14466
14467 void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty,
14468 struct lyd_node *dnode,
14469 bool show_defaults)
14470 {
14471 if (!yang_dnode_get_bool(dnode, "./enable"))
14472 return;
14473
14474 int half = DEFAULT_HALF_LIFE * 60;
14475 int reuse = DEFAULT_REUSE;
14476 int suppress = DEFAULT_SUPPRESS;
14477 int max;
14478
14479 half = yang_dnode_get_uint8(dnode, "../reach-decay");
14480 reuse = yang_dnode_get_uint16(dnode, "../reuse-above");
14481 suppress = yang_dnode_get_uint16(dnode, "../suppress-above");
14482 max = yang_dnode_get_uint8(dnode, "../unreach-decay");
14483
14484 if (half == DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
14485 && suppress == DEFAULT_SUPPRESS && max == half * 4)
14486 vty_out(vty, " bgp dampening\n");
14487 else if (half != DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
14488 && suppress == DEFAULT_SUPPRESS && max == half * 4)
14489 vty_out(vty, " bgp dampening %u\n", half);
14490 else
14491 vty_out(vty, " bgp dampening %u %d %d %d\n", half, reuse,
14492 suppress, max);
14493 }
14494
14495 /* Display specified route of BGP table. */
14496 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14497 const char *ip_str, afi_t afi, safi_t safi,
14498 struct prefix_rd *prd, int prefix_check)
14499 {
14500 int ret;
14501 struct prefix match;
14502 struct bgp_dest *dest;
14503 struct bgp_dest *rm;
14504 struct bgp_path_info *pi;
14505 struct bgp_path_info *pi_temp;
14506 struct bgp *bgp;
14507 struct bgp_table *table;
14508
14509 /* BGP structure lookup. */
14510 if (view_name) {
14511 bgp = bgp_lookup_by_name(view_name);
14512 if (bgp == NULL) {
14513 vty_out(vty, "%% Can't find BGP instance %s\n",
14514 view_name);
14515 return CMD_WARNING;
14516 }
14517 } else {
14518 bgp = bgp_get_default();
14519 if (bgp == NULL) {
14520 vty_out(vty, "%% No BGP process is configured\n");
14521 return CMD_WARNING;
14522 }
14523 }
14524
14525 /* Check IP address argument. */
14526 ret = str2prefix(ip_str, &match);
14527 if (!ret) {
14528 vty_out(vty, "%% address is malformed\n");
14529 return CMD_WARNING;
14530 }
14531
14532 match.family = afi2family(afi);
14533
14534 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14535 || (safi == SAFI_EVPN)) {
14536 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14537 dest = bgp_route_next(dest)) {
14538 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14539
14540 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14541 continue;
14542 table = bgp_dest_get_bgp_table_info(dest);
14543 if (!table)
14544 continue;
14545 if ((rm = bgp_node_match(table, &match)) == NULL)
14546 continue;
14547
14548 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
14549
14550 if (!prefix_check
14551 || rm_p->prefixlen == match.prefixlen) {
14552 pi = bgp_dest_get_bgp_path_info(rm);
14553 while (pi) {
14554 if (pi->extra && pi->extra->damp_info) {
14555 pi_temp = pi->next;
14556 bgp_damp_info_free(
14557 &pi->extra->damp_info,
14558 &bgp->damp[afi][safi],
14559 1, afi, safi);
14560 pi = pi_temp;
14561 } else
14562 pi = pi->next;
14563 }
14564 }
14565
14566 bgp_dest_unlock_node(rm);
14567 }
14568 } else {
14569 if ((dest = bgp_node_match(bgp->rib[afi][safi], &match))
14570 != NULL) {
14571 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14572
14573 if (!prefix_check
14574 || dest_p->prefixlen == match.prefixlen) {
14575 pi = bgp_dest_get_bgp_path_info(dest);
14576 while (pi) {
14577 if (pi->extra && pi->extra->damp_info) {
14578 pi_temp = pi->next;
14579 struct bgp_damp_info *bdi =
14580 pi->extra->damp_info;
14581 if (bdi->lastrecord
14582 == BGP_RECORD_UPDATE) {
14583 bgp_aggregate_increment(
14584 bgp,
14585 &bdi->dest->p,
14586 bdi->path,
14587 bdi->afi,
14588 bdi->safi);
14589 bgp_process(bgp,
14590 bdi->dest,
14591 bdi->afi,
14592 bdi->safi);
14593 }
14594 bgp_damp_info_free(
14595 &pi->extra->damp_info,
14596 &bgp->damp[afi][safi],
14597 1, afi, safi);
14598 pi = pi_temp;
14599 } else
14600 pi = pi->next;
14601 }
14602 }
14603
14604 bgp_dest_unlock_node(dest);
14605 }
14606 }
14607
14608 return CMD_SUCCESS;
14609 }
14610
14611 DEFUN (clear_ip_bgp_dampening,
14612 clear_ip_bgp_dampening_cmd,
14613 "clear ip bgp dampening",
14614 CLEAR_STR
14615 IP_STR
14616 BGP_STR
14617 "Clear route flap dampening information\n")
14618 {
14619 VTY_DECLVAR_CONTEXT(bgp, bgp);
14620 bgp_damp_info_clean(bgp, &bgp->damp[AFI_IP][SAFI_UNICAST], AFI_IP,
14621 SAFI_UNICAST);
14622 return CMD_SUCCESS;
14623 }
14624
14625 DEFUN (clear_ip_bgp_dampening_prefix,
14626 clear_ip_bgp_dampening_prefix_cmd,
14627 "clear ip bgp dampening A.B.C.D/M",
14628 CLEAR_STR
14629 IP_STR
14630 BGP_STR
14631 "Clear route flap dampening information\n"
14632 "IPv4 prefix\n")
14633 {
14634 int idx_ipv4_prefixlen = 4;
14635 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
14636 AFI_IP, SAFI_UNICAST, NULL, 1);
14637 }
14638
14639 DEFUN (clear_ip_bgp_dampening_address,
14640 clear_ip_bgp_dampening_address_cmd,
14641 "clear ip bgp dampening A.B.C.D",
14642 CLEAR_STR
14643 IP_STR
14644 BGP_STR
14645 "Clear route flap dampening information\n"
14646 "Network to clear damping information\n")
14647 {
14648 int idx_ipv4 = 4;
14649 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
14650 SAFI_UNICAST, NULL, 0);
14651 }
14652
14653 DEFUN (clear_ip_bgp_dampening_address_mask,
14654 clear_ip_bgp_dampening_address_mask_cmd,
14655 "clear ip bgp dampening A.B.C.D A.B.C.D",
14656 CLEAR_STR
14657 IP_STR
14658 BGP_STR
14659 "Clear route flap dampening information\n"
14660 "Network to clear damping information\n"
14661 "Network mask\n")
14662 {
14663 int idx_ipv4 = 4;
14664 int idx_ipv4_2 = 5;
14665 int ret;
14666 char prefix_str[BUFSIZ];
14667
14668 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
14669 prefix_str, sizeof(prefix_str));
14670 if (!ret) {
14671 vty_out(vty, "%% Inconsistent address and mask\n");
14672 return CMD_WARNING;
14673 }
14674
14675 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
14676 NULL, 0);
14677 }
14678
14679 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
14680 {
14681 struct vty *vty = arg;
14682 struct peer *peer = bucket->data;
14683 char buf[SU_ADDRSTRLEN];
14684
14685 vty_out(vty, "\tPeer: %s %s\n", peer->host,
14686 sockunion2str(&peer->su, buf, sizeof(buf)));
14687 }
14688
14689 DEFUN (show_bgp_listeners,
14690 show_bgp_listeners_cmd,
14691 "show bgp listeners",
14692 SHOW_STR
14693 BGP_STR
14694 "Display Listen Sockets and who created them\n")
14695 {
14696 bgp_dump_listener_info(vty);
14697
14698 return CMD_SUCCESS;
14699 }
14700
14701 DEFUN (show_bgp_peerhash,
14702 show_bgp_peerhash_cmd,
14703 "show bgp peerhash",
14704 SHOW_STR
14705 BGP_STR
14706 "Display information about the BGP peerhash\n")
14707 {
14708 struct list *instances = bm->bgp;
14709 struct listnode *node;
14710 struct bgp *bgp;
14711
14712 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
14713 vty_out(vty, "BGP: %s\n", bgp->name);
14714 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
14715 vty);
14716 }
14717
14718 return CMD_SUCCESS;
14719 }
14720
14721 /* also used for encap safi */
14722 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
14723 afi_t afi, safi_t safi)
14724 {
14725 struct bgp_dest *pdest;
14726 struct bgp_dest *dest;
14727 struct bgp_table *table;
14728 const struct prefix *p;
14729 const struct prefix_rd *prd;
14730 struct bgp_static *bgp_static;
14731 mpls_label_t label;
14732 char rdbuf[RD_ADDRSTRLEN];
14733
14734 /* Network configuration. */
14735 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14736 pdest = bgp_route_next(pdest)) {
14737 table = bgp_dest_get_bgp_table_info(pdest);
14738 if (!table)
14739 continue;
14740
14741 for (dest = bgp_table_top(table); dest;
14742 dest = bgp_route_next(dest)) {
14743 bgp_static = bgp_dest_get_bgp_static_info(dest);
14744 if (bgp_static == NULL)
14745 continue;
14746
14747 p = bgp_dest_get_prefix(dest);
14748 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14749 pdest);
14750
14751 /* "network" configuration display. */
14752 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14753 label = decode_label(&bgp_static->label);
14754
14755 vty_out(vty, " network %pFX rd %s", p, rdbuf);
14756 if (safi == SAFI_MPLS_VPN)
14757 vty_out(vty, " label %u", label);
14758
14759 if (bgp_static->rmap.name)
14760 vty_out(vty, " route-map %s",
14761 bgp_static->rmap.name);
14762
14763 if (bgp_static->backdoor)
14764 vty_out(vty, " backdoor");
14765
14766 vty_out(vty, "\n");
14767 }
14768 }
14769 }
14770
14771 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
14772 afi_t afi, safi_t safi)
14773 {
14774 struct bgp_dest *pdest;
14775 struct bgp_dest *dest;
14776 struct bgp_table *table;
14777 const struct prefix *p;
14778 const struct prefix_rd *prd;
14779 struct bgp_static *bgp_static;
14780 char buf[PREFIX_STRLEN * 2];
14781 char buf2[SU_ADDRSTRLEN];
14782 char rdbuf[RD_ADDRSTRLEN];
14783 char esi_buf[ESI_BYTES];
14784
14785 /* Network configuration. */
14786 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14787 pdest = bgp_route_next(pdest)) {
14788 table = bgp_dest_get_bgp_table_info(pdest);
14789 if (!table)
14790 continue;
14791
14792 for (dest = bgp_table_top(table); dest;
14793 dest = bgp_route_next(dest)) {
14794 bgp_static = bgp_dest_get_bgp_static_info(dest);
14795 if (bgp_static == NULL)
14796 continue;
14797
14798 char *macrouter = NULL;
14799
14800 if (bgp_static->router_mac)
14801 macrouter = prefix_mac2str(
14802 bgp_static->router_mac, NULL, 0);
14803 if (bgp_static->eth_s_id)
14804 esi_to_str(bgp_static->eth_s_id,
14805 esi_buf, sizeof(esi_buf));
14806 p = bgp_dest_get_prefix(dest);
14807 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
14808
14809 /* "network" configuration display. */
14810 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14811 if (p->u.prefix_evpn.route_type == 5) {
14812 char local_buf[PREFIX_STRLEN];
14813 uint8_t family = is_evpn_prefix_ipaddr_v4((
14814 struct prefix_evpn *)p)
14815 ? AF_INET
14816 : AF_INET6;
14817 inet_ntop(family,
14818 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
14819 local_buf, PREFIX_STRLEN);
14820 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
14821 p->u.prefix_evpn.prefix_addr
14822 .ip_prefix_length);
14823 } else {
14824 prefix2str(p, buf, sizeof(buf));
14825 }
14826
14827 if (bgp_static->gatewayIp.family == AF_INET
14828 || bgp_static->gatewayIp.family == AF_INET6)
14829 inet_ntop(bgp_static->gatewayIp.family,
14830 &bgp_static->gatewayIp.u.prefix, buf2,
14831 sizeof(buf2));
14832 vty_out(vty,
14833 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
14834 buf, rdbuf,
14835 p->u.prefix_evpn.prefix_addr.eth_tag,
14836 decode_label(&bgp_static->label), esi_buf, buf2,
14837 macrouter);
14838
14839 XFREE(MTYPE_TMP, macrouter);
14840 }
14841 }
14842 }
14843
14844 /* Configuration of static route announcement and aggregate
14845 information. */
14846 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
14847 safi_t safi)
14848 {
14849 struct bgp_dest *dest;
14850 const struct prefix *p;
14851 struct bgp_static *bgp_static;
14852 struct bgp_aggregate *bgp_aggregate;
14853
14854 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
14855 bgp_config_write_network_vpn(vty, bgp, afi, safi);
14856 return;
14857 }
14858
14859 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
14860 bgp_config_write_network_evpn(vty, bgp, afi, safi);
14861 return;
14862 }
14863
14864 /* Network configuration. */
14865 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
14866 dest = bgp_route_next(dest)) {
14867 bgp_static = bgp_dest_get_bgp_static_info(dest);
14868 if (bgp_static == NULL)
14869 continue;
14870
14871 p = bgp_dest_get_prefix(dest);
14872
14873 vty_out(vty, " network %pFX", p);
14874
14875 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
14876 vty_out(vty, " label-index %u",
14877 bgp_static->label_index);
14878
14879 if (bgp_static->rmap.name)
14880 vty_out(vty, " route-map %s", bgp_static->rmap.name);
14881
14882 if (bgp_static->backdoor)
14883 vty_out(vty, " backdoor");
14884
14885 vty_out(vty, "\n");
14886 }
14887
14888 /* Aggregate-address configuration. */
14889 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
14890 dest = bgp_route_next(dest)) {
14891 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
14892 if (bgp_aggregate == NULL)
14893 continue;
14894
14895 p = bgp_dest_get_prefix(dest);
14896
14897 vty_out(vty, " aggregate-address %pFX", p);
14898
14899 if (bgp_aggregate->as_set)
14900 vty_out(vty, " as-set");
14901
14902 if (bgp_aggregate->summary_only)
14903 vty_out(vty, " summary-only");
14904
14905 if (bgp_aggregate->rmap.name)
14906 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
14907
14908 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
14909 vty_out(vty, " origin %s",
14910 bgp_origin2str(bgp_aggregate->origin));
14911
14912 if (bgp_aggregate->match_med)
14913 vty_out(vty, " matching-MED-only");
14914
14915 if (bgp_aggregate->suppress_map_name)
14916 vty_out(vty, " suppress-map %s",
14917 bgp_aggregate->suppress_map_name);
14918
14919 vty_out(vty, "\n");
14920 }
14921 }
14922
14923 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
14924 safi_t safi)
14925 {
14926 struct bgp_dest *dest;
14927 struct bgp_distance *bdistance;
14928
14929 /* Distance configuration. */
14930 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
14931 && bgp->distance_local[afi][safi]
14932 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
14933 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
14934 || bgp->distance_local[afi][safi]
14935 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
14936 vty_out(vty, " distance bgp %d %d %d\n",
14937 bgp->distance_ebgp[afi][safi],
14938 bgp->distance_ibgp[afi][safi],
14939 bgp->distance_local[afi][safi]);
14940 }
14941
14942 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
14943 dest = bgp_route_next(dest)) {
14944 bdistance = bgp_dest_get_bgp_distance_info(dest);
14945 if (bdistance != NULL)
14946 vty_out(vty, " distance %d %pBD %s\n",
14947 bdistance->distance, dest,
14948 bdistance->access_list ? bdistance->access_list
14949 : "");
14950 }
14951 }
14952
14953 /* Allocate routing table structure and install commands. */
14954 void bgp_route_init(void)
14955 {
14956 afi_t afi;
14957 safi_t safi;
14958
14959 /* Init BGP distance table. */
14960 FOREACH_AFI_SAFI (afi, safi)
14961 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
14962
14963 /* IPv4 BGP commands. */
14964 install_element(BGP_NODE, &bgp_table_map_cmd);
14965 install_element(BGP_NODE, &bgp_network_cmd);
14966 install_element(BGP_NODE, &no_bgp_table_map_cmd);
14967
14968 install_element(BGP_NODE, &aggregate_addressv4_cmd);
14969
14970 /* IPv4 unicast configuration. */
14971 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
14972 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
14973 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
14974
14975 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
14976
14977 /* IPv4 multicast configuration. */
14978 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
14979 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
14980 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
14981 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
14982
14983 /* IPv4 labeled-unicast configuration. */
14984 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
14985 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
14986
14987 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
14988 install_element(VIEW_NODE, &show_ip_bgp_cmd);
14989 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
14990 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
14991 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
14992 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
14993 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
14994 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
14995
14996 install_element(VIEW_NODE,
14997 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
14998 install_element(VIEW_NODE,
14999 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15000 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15001 install_element(VIEW_NODE,
15002 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15003 #ifdef KEEP_OLD_VPN_COMMANDS
15004 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15005 #endif /* KEEP_OLD_VPN_COMMANDS */
15006 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15007 install_element(VIEW_NODE,
15008 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15009
15010 /* BGP dampening clear commands */
15011 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15012 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15013
15014 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15015 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15016
15017 /* prefix count */
15018 install_element(ENABLE_NODE,
15019 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15020 #ifdef KEEP_OLD_VPN_COMMANDS
15021 install_element(ENABLE_NODE,
15022 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15023 #endif /* KEEP_OLD_VPN_COMMANDS */
15024
15025 /* New config IPv6 BGP commands. */
15026 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15027 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15028 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15029
15030 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15031
15032 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15033
15034 /* IPv6 labeled unicast address family. */
15035 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15036 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15037
15038 install_element(BGP_NODE, &bgp_distance_cmd);
15039 install_element(BGP_NODE, &no_bgp_distance_cmd);
15040 install_element(BGP_NODE, &bgp_distance_source_cmd);
15041 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15042 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15043 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15044 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15045 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15046 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15047 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15048 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15049 install_element(BGP_IPV6_NODE, &bgp_distance_source_cmd);
15050 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15051 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15052 install_element(BGP_IPV6M_NODE, &bgp_distance_source_cmd);
15053
15054 /* BGP dampening */
15055 install_element(BGP_NODE, &bgp_dampening_cmd);
15056 install_element(BGP_IPV4_NODE, &bgp_dampening_cmd);
15057 install_element(BGP_IPV4M_NODE, &bgp_dampening_cmd);
15058 install_element(BGP_IPV4L_NODE, &bgp_dampening_cmd);
15059 install_element(BGP_IPV6_NODE, &bgp_dampening_cmd);
15060 install_element(BGP_IPV6M_NODE, &bgp_dampening_cmd);
15061 install_element(BGP_IPV6L_NODE, &bgp_dampening_cmd);
15062
15063 /* Large Communities */
15064 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15065 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15066
15067 /* show bgp ipv4 flowspec detailed */
15068 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15069
15070 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15071 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15072 }
15073
15074 void bgp_route_finish(void)
15075 {
15076 afi_t afi;
15077 safi_t safi;
15078
15079 FOREACH_AFI_SAFI (afi, safi) {
15080 bgp_table_unlock(bgp_distance_table[afi][safi]);
15081 bgp_distance_table[afi][safi] = NULL;
15082 }
15083 }