]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_route.c
bgpd: Allow v6 LL peers to work when connected to as well
[mirror_frr.git] / bgpd / bgp_route.c
1 /* BGP routing information
2 * Copyright (C) 1996, 97, 98, 99 Kunihiro Ishiguro
3 * Copyright (C) 2016 Job Snijders <job@instituut.net>
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include <zebra.h>
23 #include <math.h>
24
25 #include "printfrr.h"
26 #include "frrstr.h"
27 #include "prefix.h"
28 #include "linklist.h"
29 #include "memory.h"
30 #include "command.h"
31 #include "stream.h"
32 #include "filter.h"
33 #include "log.h"
34 #include "routemap.h"
35 #include "buffer.h"
36 #include "sockunion.h"
37 #include "plist.h"
38 #include "thread.h"
39 #include "workqueue.h"
40 #include "queue.h"
41 #include "memory.h"
42 #include "srv6.h"
43 #include "lib/json.h"
44 #include "lib_errors.h"
45 #include "zclient.h"
46 #include "bgpd/bgpd.h"
47 #include "bgpd/bgp_table.h"
48 #include "bgpd/bgp_route.h"
49 #include "bgpd/bgp_attr.h"
50 #include "bgpd/bgp_debug.h"
51 #include "bgpd/bgp_errors.h"
52 #include "bgpd/bgp_aspath.h"
53 #include "bgpd/bgp_regex.h"
54 #include "bgpd/bgp_community.h"
55 #include "bgpd/bgp_community_alias.h"
56 #include "bgpd/bgp_ecommunity.h"
57 #include "bgpd/bgp_lcommunity.h"
58 #include "bgpd/bgp_clist.h"
59 #include "bgpd/bgp_packet.h"
60 #include "bgpd/bgp_filter.h"
61 #include "bgpd/bgp_fsm.h"
62 #include "bgpd/bgp_mplsvpn.h"
63 #include "bgpd/bgp_nexthop.h"
64 #include "bgpd/bgp_damp.h"
65 #include "bgpd/bgp_advertise.h"
66 #include "bgpd/bgp_zebra.h"
67 #include "bgpd/bgp_vty.h"
68 #include "bgpd/bgp_mpath.h"
69 #include "bgpd/bgp_nht.h"
70 #include "bgpd/bgp_updgrp.h"
71 #include "bgpd/bgp_label.h"
72 #include "bgpd/bgp_addpath.h"
73 #include "bgpd/bgp_mac.h"
74 #include "bgpd/bgp_network.h"
75 #include "bgpd/bgp_trace.h"
76 #include "bgpd/bgp_rpki.h"
77
78 #ifdef ENABLE_BGP_VNC
79 #include "bgpd/rfapi/rfapi_backend.h"
80 #include "bgpd/rfapi/vnc_import_bgp.h"
81 #include "bgpd/rfapi/vnc_export_bgp.h"
82 #endif
83 #include "bgpd/bgp_encap_types.h"
84 #include "bgpd/bgp_encap_tlv.h"
85 #include "bgpd/bgp_evpn.h"
86 #include "bgpd/bgp_evpn_mh.h"
87 #include "bgpd/bgp_evpn_vty.h"
88 #include "bgpd/bgp_flowspec.h"
89 #include "bgpd/bgp_flowspec_util.h"
90 #include "bgpd/bgp_pbr.h"
91
92 #ifndef VTYSH_EXTRACT_PL
93 #include "bgpd/bgp_route_clippy.c"
94 #endif
95
96 DEFINE_HOOK(bgp_snmp_update_stats,
97 (struct bgp_node *rn, struct bgp_path_info *pi, bool added),
98 (rn, pi, added));
99
100 DEFINE_HOOK(bgp_rpki_prefix_status,
101 (struct peer *peer, struct attr *attr,
102 const struct prefix *prefix),
103 (peer, attr, prefix));
104
105 /* Extern from bgp_dump.c */
106 extern const char *bgp_origin_str[];
107 extern const char *bgp_origin_long_str[];
108
109 /* PMSI strings. */
110 #define PMSI_TNLTYPE_STR_NO_INFO "No info"
111 #define PMSI_TNLTYPE_STR_DEFAULT PMSI_TNLTYPE_STR_NO_INFO
112 static const struct message bgp_pmsi_tnltype_str[] = {
113 {PMSI_TNLTYPE_NO_INFO, PMSI_TNLTYPE_STR_NO_INFO},
114 {PMSI_TNLTYPE_RSVP_TE_P2MP, "RSVP-TE P2MP"},
115 {PMSI_TNLTYPE_MLDP_P2MP, "mLDP P2MP"},
116 {PMSI_TNLTYPE_PIM_SSM, "PIM-SSM"},
117 {PMSI_TNLTYPE_PIM_SM, "PIM-SM"},
118 {PMSI_TNLTYPE_PIM_BIDIR, "PIM-BIDIR"},
119 {PMSI_TNLTYPE_INGR_REPL, "Ingress Replication"},
120 {PMSI_TNLTYPE_MLDP_MP2MP, "mLDP MP2MP"},
121 {0}
122 };
123
124 #define VRFID_NONE_STR "-"
125 #define SOFT_RECONFIG_TASK_MAX_PREFIX 25000
126
127 DEFINE_HOOK(bgp_process,
128 (struct bgp * bgp, afi_t afi, safi_t safi, struct bgp_dest *bn,
129 struct peer *peer, bool withdraw),
130 (bgp, afi, safi, bn, peer, withdraw));
131
132 /** Test if path is suppressed. */
133 static bool bgp_path_suppressed(struct bgp_path_info *pi)
134 {
135 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
136 return false;
137
138 return listcount(pi->extra->aggr_suppressors) > 0;
139 }
140
141 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
142 safi_t safi, const struct prefix *p,
143 struct prefix_rd *prd)
144 {
145 struct bgp_dest *dest;
146 struct bgp_dest *pdest = NULL;
147
148 assert(table);
149
150 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
151 || (safi == SAFI_EVPN)) {
152 pdest = bgp_node_get(table, (struct prefix *)prd);
153
154 if (!bgp_dest_has_bgp_path_info_data(pdest))
155 bgp_dest_set_bgp_table_info(
156 pdest, bgp_table_init(table->bgp, afi, safi));
157 else
158 bgp_dest_unlock_node(pdest);
159 table = bgp_dest_get_bgp_table_info(pdest);
160 }
161
162 dest = bgp_node_get(table, p);
163
164 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
165 || (safi == SAFI_EVPN))
166 dest->pdest = pdest;
167
168 return dest;
169 }
170
171 struct bgp_dest *bgp_afi_node_lookup(struct bgp_table *table, afi_t afi,
172 safi_t safi, const struct prefix *p,
173 struct prefix_rd *prd)
174 {
175 struct bgp_dest *dest;
176 struct bgp_dest *pdest = NULL;
177
178 if (!table)
179 return NULL;
180
181 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
182 || (safi == SAFI_EVPN)) {
183 pdest = bgp_node_lookup(table, (struct prefix *)prd);
184 if (!pdest)
185 return NULL;
186
187 if (!bgp_dest_has_bgp_path_info_data(pdest)) {
188 bgp_dest_unlock_node(pdest);
189 return NULL;
190 }
191
192 table = bgp_dest_get_bgp_table_info(pdest);
193 }
194
195 dest = bgp_node_lookup(table, p);
196
197 return dest;
198 }
199
200 /* Allocate bgp_path_info_extra */
201 static struct bgp_path_info_extra *bgp_path_info_extra_new(void)
202 {
203 struct bgp_path_info_extra *new;
204 new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA,
205 sizeof(struct bgp_path_info_extra));
206 new->label[0] = MPLS_INVALID_LABEL;
207 new->num_labels = 0;
208 new->bgp_fs_pbr = NULL;
209 new->bgp_fs_iprule = NULL;
210 return new;
211 }
212
213 void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
214 {
215 struct bgp_path_info_extra *e;
216
217 if (!extra || !*extra)
218 return;
219
220 e = *extra;
221 if (e->damp_info)
222 bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
223 e->damp_info->safi);
224
225 e->damp_info = NULL;
226 if (e->parent) {
227 struct bgp_path_info *bpi = (struct bgp_path_info *)e->parent;
228
229 if (bpi->net) {
230 /* FIXME: since multiple e may have the same e->parent
231 * and e->parent->net is holding a refcount for each
232 * of them, we need to do some fudging here.
233 *
234 * WARNING: if bpi->net->lock drops to 0, bpi may be
235 * freed as well (because bpi->net was holding the
236 * last reference to bpi) => write after free!
237 */
238 unsigned refcount;
239
240 bpi = bgp_path_info_lock(bpi);
241 refcount = bgp_dest_get_lock_count(bpi->net) - 1;
242 bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
243 if (!refcount)
244 bpi->net = NULL;
245 bgp_path_info_unlock(bpi);
246 }
247 bgp_path_info_unlock(e->parent);
248 e->parent = NULL;
249 }
250
251 if (e->bgp_orig)
252 bgp_unlock(e->bgp_orig);
253
254 if (e->aggr_suppressors)
255 list_delete(&e->aggr_suppressors);
256
257 if (e->mh_info)
258 bgp_evpn_path_mh_info_free(e->mh_info);
259
260 if ((*extra)->bgp_fs_iprule)
261 list_delete(&((*extra)->bgp_fs_iprule));
262 if ((*extra)->bgp_fs_pbr)
263 list_delete(&((*extra)->bgp_fs_pbr));
264 XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
265 }
266
267 /* Get bgp_path_info extra information for the given bgp_path_info, lazy
268 * allocated if required.
269 */
270 struct bgp_path_info_extra *bgp_path_info_extra_get(struct bgp_path_info *pi)
271 {
272 if (!pi->extra)
273 pi->extra = bgp_path_info_extra_new();
274 return pi->extra;
275 }
276
277 /* Free bgp route information. */
278 static void bgp_path_info_free(struct bgp_path_info *path)
279 {
280 bgp_attr_unintern(&path->attr);
281
282 bgp_unlink_nexthop(path);
283 bgp_path_info_extra_free(&path->extra);
284 bgp_path_info_mpath_free(&path->mpath);
285 if (path->net)
286 bgp_addpath_free_info_data(&path->tx_addpath,
287 &path->net->tx_addpath);
288
289 peer_unlock(path->peer); /* bgp_path_info peer reference */
290
291 XFREE(MTYPE_BGP_ROUTE, path);
292 }
293
294 struct bgp_path_info *bgp_path_info_lock(struct bgp_path_info *path)
295 {
296 path->lock++;
297 return path;
298 }
299
300 struct bgp_path_info *bgp_path_info_unlock(struct bgp_path_info *path)
301 {
302 assert(path && path->lock > 0);
303 path->lock--;
304
305 if (path->lock == 0) {
306 #if 0
307 zlog_debug ("%s: unlocked and freeing", __func__);
308 zlog_backtrace (LOG_DEBUG);
309 #endif
310 bgp_path_info_free(path);
311 return NULL;
312 }
313
314 #if 0
315 if (path->lock == 1)
316 {
317 zlog_debug ("%s: unlocked to 1", __func__);
318 zlog_backtrace (LOG_DEBUG);
319 }
320 #endif
321
322 return path;
323 }
324
325 /* This function sets flag BGP_NODE_SELECT_DEFER based on condition */
326 static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
327 {
328 struct peer *peer;
329 struct bgp_path_info *old_pi, *nextpi;
330 bool set_flag = false;
331 struct bgp *bgp = NULL;
332 struct bgp_table *table = NULL;
333 afi_t afi = 0;
334 safi_t safi = 0;
335
336 /* If the flag BGP_NODE_SELECT_DEFER is set and new path is added
337 * then the route selection is deferred
338 */
339 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER) && (!delete))
340 return 0;
341
342 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
343 if (BGP_DEBUG(update, UPDATE_OUT))
344 zlog_debug(
345 "Route %pBD is in workqueue and being processed, not deferred.",
346 dest);
347
348 return 0;
349 }
350
351 table = bgp_dest_table(dest);
352 if (table) {
353 bgp = table->bgp;
354 afi = table->afi;
355 safi = table->safi;
356 }
357
358 for (old_pi = bgp_dest_get_bgp_path_info(dest);
359 (old_pi != NULL) && (nextpi = old_pi->next, 1); old_pi = nextpi) {
360 if (CHECK_FLAG(old_pi->flags, BGP_PATH_SELECTED))
361 continue;
362
363 /* Route selection is deferred if there is a stale path which
364 * which indicates peer is in restart mode
365 */
366 if (CHECK_FLAG(old_pi->flags, BGP_PATH_STALE)
367 && (old_pi->sub_type == BGP_ROUTE_NORMAL)) {
368 set_flag = true;
369 } else {
370 /* If the peer is graceful restart capable and peer is
371 * restarting mode, set the flag BGP_NODE_SELECT_DEFER
372 */
373 peer = old_pi->peer;
374 if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)
375 && BGP_PEER_RESTARTING_MODE(peer)
376 && (old_pi
377 && old_pi->sub_type == BGP_ROUTE_NORMAL)) {
378 set_flag = true;
379 }
380 }
381 if (set_flag)
382 break;
383 }
384
385 /* Set the flag BGP_NODE_SELECT_DEFER if route selection deferral timer
386 * is active
387 */
388 if (set_flag && table) {
389 if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
390 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
391 bgp->gr_info[afi][safi].gr_deferred++;
392 SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
393 if (BGP_DEBUG(update, UPDATE_OUT))
394 zlog_debug("DEFER route %pBD, dest %p", dest,
395 dest);
396 return 0;
397 }
398 }
399 return -1;
400 }
401
402 void bgp_path_info_add(struct bgp_dest *dest, struct bgp_path_info *pi)
403 {
404 struct bgp_path_info *top;
405
406 top = bgp_dest_get_bgp_path_info(dest);
407
408 pi->next = top;
409 pi->prev = NULL;
410 if (top)
411 top->prev = pi;
412 bgp_dest_set_bgp_path_info(dest, pi);
413
414 bgp_path_info_lock(pi);
415 bgp_dest_lock_node(dest);
416 peer_lock(pi->peer); /* bgp_path_info peer reference */
417 bgp_dest_set_defer_flag(dest, false);
418 hook_call(bgp_snmp_update_stats, dest, pi, true);
419 }
420
421 /* Do the actual removal of info from RIB, for use by bgp_process
422 completion callback *only* */
423 void bgp_path_info_reap(struct bgp_dest *dest, struct bgp_path_info *pi)
424 {
425 if (pi->next)
426 pi->next->prev = pi->prev;
427 if (pi->prev)
428 pi->prev->next = pi->next;
429 else
430 bgp_dest_set_bgp_path_info(dest, pi->next);
431
432 bgp_path_info_mpath_dequeue(pi);
433 bgp_path_info_unlock(pi);
434 hook_call(bgp_snmp_update_stats, dest, pi, false);
435 bgp_dest_unlock_node(dest);
436 }
437
438 void bgp_path_info_delete(struct bgp_dest *dest, struct bgp_path_info *pi)
439 {
440 bgp_path_info_set_flag(dest, pi, BGP_PATH_REMOVED);
441 /* set of previous already took care of pcount */
442 UNSET_FLAG(pi->flags, BGP_PATH_VALID);
443 }
444
445 /* undo the effects of a previous call to bgp_path_info_delete; typically
446 called when a route is deleted and then quickly re-added before the
447 deletion has been processed */
448 void bgp_path_info_restore(struct bgp_dest *dest, struct bgp_path_info *pi)
449 {
450 bgp_path_info_unset_flag(dest, pi, BGP_PATH_REMOVED);
451 /* unset of previous already took care of pcount */
452 SET_FLAG(pi->flags, BGP_PATH_VALID);
453 }
454
455 /* Adjust pcount as required */
456 static void bgp_pcount_adjust(struct bgp_dest *dest, struct bgp_path_info *pi)
457 {
458 struct bgp_table *table;
459
460 assert(dest && bgp_dest_table(dest));
461 assert(pi && pi->peer && pi->peer->bgp);
462
463 table = bgp_dest_table(dest);
464
465 if (pi->peer == pi->peer->bgp->peer_self)
466 return;
467
468 if (!BGP_PATH_COUNTABLE(pi)
469 && CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
470
471 UNSET_FLAG(pi->flags, BGP_PATH_COUNTED);
472
473 /* slight hack, but more robust against errors. */
474 if (pi->peer->pcount[table->afi][table->safi])
475 pi->peer->pcount[table->afi][table->safi]--;
476 else
477 flog_err(EC_LIB_DEVELOPMENT,
478 "Asked to decrement 0 prefix count for peer");
479 } else if (BGP_PATH_COUNTABLE(pi)
480 && !CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
481 SET_FLAG(pi->flags, BGP_PATH_COUNTED);
482 pi->peer->pcount[table->afi][table->safi]++;
483 }
484 }
485
486 static int bgp_label_index_differs(struct bgp_path_info *pi1,
487 struct bgp_path_info *pi2)
488 {
489 return (!(pi1->attr->label_index == pi2->attr->label_index));
490 }
491
492 /* Set/unset bgp_path_info flags, adjusting any other state as needed.
493 * This is here primarily to keep prefix-count in check.
494 */
495 void bgp_path_info_set_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
496 uint32_t flag)
497 {
498 SET_FLAG(pi->flags, flag);
499
500 /* early bath if we know it's not a flag that changes countability state
501 */
502 if (!CHECK_FLAG(flag,
503 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
504 return;
505
506 bgp_pcount_adjust(dest, pi);
507 }
508
509 void bgp_path_info_unset_flag(struct bgp_dest *dest, struct bgp_path_info *pi,
510 uint32_t flag)
511 {
512 UNSET_FLAG(pi->flags, flag);
513
514 /* early bath if we know it's not a flag that changes countability state
515 */
516 if (!CHECK_FLAG(flag,
517 BGP_PATH_VALID | BGP_PATH_HISTORY | BGP_PATH_REMOVED))
518 return;
519
520 bgp_pcount_adjust(dest, pi);
521 }
522
523 /* Get MED value. If MED value is missing and "bgp bestpath
524 missing-as-worst" is specified, treat it as the worst value. */
525 static uint32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
526 {
527 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
528 return attr->med;
529 else {
530 if (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST))
531 return BGP_MED_MAX;
532 else
533 return 0;
534 }
535 }
536
537 void bgp_path_info_path_with_addpath_rx_str(struct bgp_path_info *pi, char *buf,
538 size_t buf_len)
539 {
540 if (pi->addpath_rx_id)
541 snprintf(buf, buf_len, "path %s (addpath rxid %d)",
542 pi->peer->host, pi->addpath_rx_id);
543 else
544 snprintf(buf, buf_len, "path %s", pi->peer->host);
545 }
546
547 /* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
548 */
549 static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
550 struct bgp_path_info *exist, int *paths_eq,
551 struct bgp_maxpaths_cfg *mpath_cfg, int debug,
552 char *pfx_buf, afi_t afi, safi_t safi,
553 enum bgp_path_selection_reason *reason)
554 {
555 const struct prefix *new_p;
556 struct attr *newattr, *existattr;
557 bgp_peer_sort_t new_sort;
558 bgp_peer_sort_t exist_sort;
559 uint32_t new_pref;
560 uint32_t exist_pref;
561 uint32_t new_med;
562 uint32_t exist_med;
563 uint32_t new_weight;
564 uint32_t exist_weight;
565 uint32_t newm, existm;
566 struct in_addr new_id;
567 struct in_addr exist_id;
568 int new_cluster;
569 int exist_cluster;
570 int internal_as_route;
571 int confed_as_route;
572 int ret = 0;
573 int igp_metric_ret = 0;
574 int peer_sort_ret = -1;
575 char new_buf[PATH_ADDPATH_STR_BUFFER];
576 char exist_buf[PATH_ADDPATH_STR_BUFFER];
577 uint32_t new_mm_seq;
578 uint32_t exist_mm_seq;
579 int nh_cmp;
580 esi_t *exist_esi;
581 esi_t *new_esi;
582 bool same_esi;
583 bool old_proxy;
584 bool new_proxy;
585 bool new_origin, exist_origin;
586
587 *paths_eq = 0;
588
589 /* 0. Null check. */
590 if (new == NULL) {
591 *reason = bgp_path_selection_none;
592 if (debug)
593 zlog_debug("%s: new is NULL", pfx_buf);
594 return 0;
595 }
596
597 if (debug)
598 bgp_path_info_path_with_addpath_rx_str(new, new_buf,
599 sizeof(new_buf));
600
601 if (exist == NULL) {
602 *reason = bgp_path_selection_first;
603 if (debug)
604 zlog_debug("%s: %s is the initial bestpath", pfx_buf,
605 new_buf);
606 return 1;
607 }
608
609 if (debug) {
610 bgp_path_info_path_with_addpath_rx_str(exist, exist_buf,
611 sizeof(exist_buf));
612 zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
613 pfx_buf, new_buf, new->flags, exist_buf,
614 exist->flags);
615 }
616
617 newattr = new->attr;
618 existattr = exist->attr;
619
620 new_p = bgp_dest_get_prefix(new->net);
621
622 /* For EVPN routes, we cannot just go by local vs remote, we have to
623 * look at the MAC mobility sequence number, if present.
624 */
625 if ((safi == SAFI_EVPN)
626 && (new_p->u.prefix_evpn.route_type == BGP_EVPN_MAC_IP_ROUTE)) {
627 /* This is an error condition described in RFC 7432 Section
628 * 15.2. The RFC
629 * states that in this scenario "the PE MUST alert the operator"
630 * but it
631 * does not state what other action to take. In order to provide
632 * some
633 * consistency in this scenario we are going to prefer the path
634 * with the
635 * sticky flag.
636 */
637 if (newattr->sticky != existattr->sticky) {
638 if (!debug) {
639 prefix2str(new_p, pfx_buf,
640 sizeof(*pfx_buf)
641 * PREFIX2STR_BUFFER);
642 bgp_path_info_path_with_addpath_rx_str(
643 new, new_buf, sizeof(new_buf));
644 bgp_path_info_path_with_addpath_rx_str(
645 exist, exist_buf, sizeof(exist_buf));
646 }
647
648 if (newattr->sticky && !existattr->sticky) {
649 *reason = bgp_path_selection_evpn_sticky_mac;
650 if (debug)
651 zlog_debug(
652 "%s: %s wins over %s due to sticky MAC flag",
653 pfx_buf, new_buf, exist_buf);
654 return 1;
655 }
656
657 if (!newattr->sticky && existattr->sticky) {
658 *reason = bgp_path_selection_evpn_sticky_mac;
659 if (debug)
660 zlog_debug(
661 "%s: %s loses to %s due to sticky MAC flag",
662 pfx_buf, new_buf, exist_buf);
663 return 0;
664 }
665 }
666
667 new_esi = bgp_evpn_attr_get_esi(newattr);
668 exist_esi = bgp_evpn_attr_get_esi(existattr);
669 if (bgp_evpn_is_esi_valid(new_esi) &&
670 !memcmp(new_esi, exist_esi, sizeof(esi_t))) {
671 same_esi = true;
672 } else {
673 same_esi = false;
674 }
675
676 /* If both paths have the same non-zero ES and
677 * one path is local it wins.
678 * PS: Note the local path wins even if the remote
679 * has the higher MM seq. The local path's
680 * MM seq will be fixed up to match the highest
681 * rem seq, subsequently.
682 */
683 if (same_esi) {
684 char esi_buf[ESI_STR_LEN];
685
686 if (bgp_evpn_is_path_local(bgp, new)) {
687 *reason = bgp_path_selection_evpn_local_path;
688 if (debug)
689 zlog_debug(
690 "%s: %s wins over %s as ES %s is same and local",
691 pfx_buf, new_buf, exist_buf,
692 esi_to_str(new_esi, esi_buf,
693 sizeof(esi_buf)));
694 return 1;
695 }
696 if (bgp_evpn_is_path_local(bgp, exist)) {
697 *reason = bgp_path_selection_evpn_local_path;
698 if (debug)
699 zlog_debug(
700 "%s: %s loses to %s as ES %s is same and local",
701 pfx_buf, new_buf, exist_buf,
702 esi_to_str(new_esi, esi_buf,
703 sizeof(esi_buf)));
704 return 0;
705 }
706 }
707
708 new_mm_seq = mac_mobility_seqnum(newattr);
709 exist_mm_seq = mac_mobility_seqnum(existattr);
710
711 if (new_mm_seq > exist_mm_seq) {
712 *reason = bgp_path_selection_evpn_seq;
713 if (debug)
714 zlog_debug(
715 "%s: %s wins over %s due to MM seq %u > %u",
716 pfx_buf, new_buf, exist_buf, new_mm_seq,
717 exist_mm_seq);
718 return 1;
719 }
720
721 if (new_mm_seq < exist_mm_seq) {
722 *reason = bgp_path_selection_evpn_seq;
723 if (debug)
724 zlog_debug(
725 "%s: %s loses to %s due to MM seq %u < %u",
726 pfx_buf, new_buf, exist_buf, new_mm_seq,
727 exist_mm_seq);
728 return 0;
729 }
730
731 /* if the sequence numbers and ESI are the same and one path
732 * is non-proxy it wins (over proxy)
733 */
734 new_proxy = bgp_evpn_attr_is_proxy(newattr);
735 old_proxy = bgp_evpn_attr_is_proxy(existattr);
736 if (same_esi && bgp_evpn_attr_is_local_es(newattr) &&
737 old_proxy != new_proxy) {
738 if (!new_proxy) {
739 *reason = bgp_path_selection_evpn_non_proxy;
740 if (debug)
741 zlog_debug(
742 "%s: %s wins over %s, same seq/es and non-proxy",
743 pfx_buf, new_buf, exist_buf);
744 return 1;
745 }
746
747 *reason = bgp_path_selection_evpn_non_proxy;
748 if (debug)
749 zlog_debug(
750 "%s: %s loses to %s, same seq/es and non-proxy",
751 pfx_buf, new_buf, exist_buf);
752 return 0;
753 }
754
755 /*
756 * if sequence numbers are the same path with the lowest IP
757 * wins
758 */
759 nh_cmp = bgp_path_info_nexthop_cmp(new, exist);
760 if (nh_cmp < 0) {
761 *reason = bgp_path_selection_evpn_lower_ip;
762 if (debug)
763 zlog_debug(
764 "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
765 pfx_buf, new_buf, exist_buf, new_mm_seq,
766 &new->attr->nexthop);
767 return 1;
768 }
769 if (nh_cmp > 0) {
770 *reason = bgp_path_selection_evpn_lower_ip;
771 if (debug)
772 zlog_debug(
773 "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
774 pfx_buf, new_buf, exist_buf, new_mm_seq,
775 &new->attr->nexthop);
776 return 0;
777 }
778 }
779
780 /* 1. Weight check. */
781 new_weight = newattr->weight;
782 exist_weight = existattr->weight;
783
784 if (new_weight > exist_weight) {
785 *reason = bgp_path_selection_weight;
786 if (debug)
787 zlog_debug("%s: %s wins over %s due to weight %d > %d",
788 pfx_buf, new_buf, exist_buf, new_weight,
789 exist_weight);
790 return 1;
791 }
792
793 if (new_weight < exist_weight) {
794 *reason = bgp_path_selection_weight;
795 if (debug)
796 zlog_debug("%s: %s loses to %s due to weight %d < %d",
797 pfx_buf, new_buf, exist_buf, new_weight,
798 exist_weight);
799 return 0;
800 }
801
802 /* 2. Local preference check. */
803 new_pref = exist_pref = bgp->default_local_pref;
804
805 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
806 new_pref = newattr->local_pref;
807 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
808 exist_pref = existattr->local_pref;
809
810 if (new_pref > exist_pref) {
811 *reason = bgp_path_selection_local_pref;
812 if (debug)
813 zlog_debug(
814 "%s: %s wins over %s due to localpref %d > %d",
815 pfx_buf, new_buf, exist_buf, new_pref,
816 exist_pref);
817 return 1;
818 }
819
820 if (new_pref < exist_pref) {
821 *reason = bgp_path_selection_local_pref;
822 if (debug)
823 zlog_debug(
824 "%s: %s loses to %s due to localpref %d < %d",
825 pfx_buf, new_buf, exist_buf, new_pref,
826 exist_pref);
827 return 0;
828 }
829
830 /* 3. Local route check. We prefer:
831 * - BGP_ROUTE_STATIC
832 * - BGP_ROUTE_AGGREGATE
833 * - BGP_ROUTE_REDISTRIBUTE
834 */
835 new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
836 new->sub_type == BGP_ROUTE_IMPORTED);
837 exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
838 exist->sub_type == BGP_ROUTE_IMPORTED);
839
840 if (new_origin && !exist_origin) {
841 *reason = bgp_path_selection_local_route;
842 if (debug)
843 zlog_debug(
844 "%s: %s wins over %s due to preferred BGP_ROUTE type",
845 pfx_buf, new_buf, exist_buf);
846 return 1;
847 }
848
849 if (!new_origin && exist_origin) {
850 *reason = bgp_path_selection_local_route;
851 if (debug)
852 zlog_debug(
853 "%s: %s loses to %s due to preferred BGP_ROUTE type",
854 pfx_buf, new_buf, exist_buf);
855 return 0;
856 }
857
858 /* 4. AS path length check. */
859 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE)) {
860 int exist_hops = aspath_count_hops(existattr->aspath);
861 int exist_confeds = aspath_count_confeds(existattr->aspath);
862
863 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED)) {
864 int aspath_hops;
865
866 aspath_hops = aspath_count_hops(newattr->aspath);
867 aspath_hops += aspath_count_confeds(newattr->aspath);
868
869 if (aspath_hops < (exist_hops + exist_confeds)) {
870 *reason = bgp_path_selection_confed_as_path;
871 if (debug)
872 zlog_debug(
873 "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
874 pfx_buf, new_buf, exist_buf,
875 aspath_hops,
876 (exist_hops + exist_confeds));
877 return 1;
878 }
879
880 if (aspath_hops > (exist_hops + exist_confeds)) {
881 *reason = bgp_path_selection_confed_as_path;
882 if (debug)
883 zlog_debug(
884 "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
885 pfx_buf, new_buf, exist_buf,
886 aspath_hops,
887 (exist_hops + exist_confeds));
888 return 0;
889 }
890 } else {
891 int newhops = aspath_count_hops(newattr->aspath);
892
893 if (newhops < exist_hops) {
894 *reason = bgp_path_selection_as_path;
895 if (debug)
896 zlog_debug(
897 "%s: %s wins over %s due to aspath hopcount %d < %d",
898 pfx_buf, new_buf, exist_buf,
899 newhops, exist_hops);
900 return 1;
901 }
902
903 if (newhops > exist_hops) {
904 *reason = bgp_path_selection_as_path;
905 if (debug)
906 zlog_debug(
907 "%s: %s loses to %s due to aspath hopcount %d > %d",
908 pfx_buf, new_buf, exist_buf,
909 newhops, exist_hops);
910 return 0;
911 }
912 }
913 }
914
915 /* 5. Origin check. */
916 if (newattr->origin < existattr->origin) {
917 *reason = bgp_path_selection_origin;
918 if (debug)
919 zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
920 pfx_buf, new_buf, exist_buf,
921 bgp_origin_long_str[newattr->origin],
922 bgp_origin_long_str[existattr->origin]);
923 return 1;
924 }
925
926 if (newattr->origin > existattr->origin) {
927 *reason = bgp_path_selection_origin;
928 if (debug)
929 zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
930 pfx_buf, new_buf, exist_buf,
931 bgp_origin_long_str[newattr->origin],
932 bgp_origin_long_str[existattr->origin]);
933 return 0;
934 }
935
936 /* 6. MED check. */
937 internal_as_route = (aspath_count_hops(newattr->aspath) == 0
938 && aspath_count_hops(existattr->aspath) == 0);
939 confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
940 && aspath_count_confeds(existattr->aspath) > 0
941 && aspath_count_hops(newattr->aspath) == 0
942 && aspath_count_hops(existattr->aspath) == 0);
943
944 if (CHECK_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED)
945 || (CHECK_FLAG(bgp->flags, BGP_FLAG_MED_CONFED) && confed_as_route)
946 || aspath_cmp_left(newattr->aspath, existattr->aspath)
947 || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
948 || internal_as_route) {
949 new_med = bgp_med_value(new->attr, bgp);
950 exist_med = bgp_med_value(exist->attr, bgp);
951
952 if (new_med < exist_med) {
953 *reason = bgp_path_selection_med;
954 if (debug)
955 zlog_debug(
956 "%s: %s wins over %s due to MED %d < %d",
957 pfx_buf, new_buf, exist_buf, new_med,
958 exist_med);
959 return 1;
960 }
961
962 if (new_med > exist_med) {
963 *reason = bgp_path_selection_med;
964 if (debug)
965 zlog_debug(
966 "%s: %s loses to %s due to MED %d > %d",
967 pfx_buf, new_buf, exist_buf, new_med,
968 exist_med);
969 return 0;
970 }
971 }
972
973 /* 7. Peer type check. */
974 new_sort = new->peer->sort;
975 exist_sort = exist->peer->sort;
976
977 if (new_sort == BGP_PEER_EBGP
978 && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
979 *reason = bgp_path_selection_peer;
980 if (debug)
981 zlog_debug(
982 "%s: %s wins over %s due to eBGP peer > iBGP peer",
983 pfx_buf, new_buf, exist_buf);
984 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
985 return 1;
986 peer_sort_ret = 1;
987 }
988
989 if (exist_sort == BGP_PEER_EBGP
990 && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
991 *reason = bgp_path_selection_peer;
992 if (debug)
993 zlog_debug(
994 "%s: %s loses to %s due to iBGP peer < eBGP peer",
995 pfx_buf, new_buf, exist_buf);
996 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
997 return 0;
998 peer_sort_ret = 0;
999 }
1000
1001 /* 8. IGP metric check. */
1002 newm = existm = 0;
1003
1004 if (new->extra)
1005 newm = new->extra->igpmetric;
1006 if (exist->extra)
1007 existm = exist->extra->igpmetric;
1008
1009 if (newm < existm) {
1010 if (debug && peer_sort_ret < 0)
1011 zlog_debug(
1012 "%s: %s wins over %s due to IGP metric %u < %u",
1013 pfx_buf, new_buf, exist_buf, newm, existm);
1014 igp_metric_ret = 1;
1015 }
1016
1017 if (newm > existm) {
1018 if (debug && peer_sort_ret < 0)
1019 zlog_debug(
1020 "%s: %s loses to %s due to IGP metric %u > %u",
1021 pfx_buf, new_buf, exist_buf, newm, existm);
1022 igp_metric_ret = 0;
1023 }
1024
1025 /* 9. Same IGP metric. Compare the cluster list length as
1026 representative of IGP hops metric. Rewrite the metric value
1027 pair (newm, existm) with the cluster list length. Prefer the
1028 path with smaller cluster list length. */
1029 if (newm == existm) {
1030 if (peer_sort_lookup(new->peer) == BGP_PEER_IBGP
1031 && peer_sort_lookup(exist->peer) == BGP_PEER_IBGP
1032 && (mpath_cfg == NULL
1033 || CHECK_FLAG(
1034 mpath_cfg->ibgp_flags,
1035 BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
1036 newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
1037 existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1038
1039 if (newm < existm) {
1040 if (debug && peer_sort_ret < 0)
1041 zlog_debug(
1042 "%s: %s wins over %s due to CLUSTER_LIST length %u < %u",
1043 pfx_buf, new_buf, exist_buf,
1044 newm, existm);
1045 igp_metric_ret = 1;
1046 }
1047
1048 if (newm > existm) {
1049 if (debug && peer_sort_ret < 0)
1050 zlog_debug(
1051 "%s: %s loses to %s due to CLUSTER_LIST length %u > %u",
1052 pfx_buf, new_buf, exist_buf,
1053 newm, existm);
1054 igp_metric_ret = 0;
1055 }
1056 }
1057 }
1058
1059 /* 10. confed-external vs. confed-internal */
1060 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1061 if (new_sort == BGP_PEER_CONFED
1062 && exist_sort == BGP_PEER_IBGP) {
1063 *reason = bgp_path_selection_confed;
1064 if (debug)
1065 zlog_debug(
1066 "%s: %s wins over %s due to confed-external peer > confed-internal peer",
1067 pfx_buf, new_buf, exist_buf);
1068 if (!CHECK_FLAG(bgp->flags,
1069 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1070 return 1;
1071 peer_sort_ret = 1;
1072 }
1073
1074 if (exist_sort == BGP_PEER_CONFED
1075 && new_sort == BGP_PEER_IBGP) {
1076 *reason = bgp_path_selection_confed;
1077 if (debug)
1078 zlog_debug(
1079 "%s: %s loses to %s due to confed-internal peer < confed-external peer",
1080 pfx_buf, new_buf, exist_buf);
1081 if (!CHECK_FLAG(bgp->flags,
1082 BGP_FLAG_PEERTYPE_MULTIPATH_RELAX))
1083 return 0;
1084 peer_sort_ret = 0;
1085 }
1086 }
1087
1088 /* 11. Maximum path check. */
1089 if (newm == existm) {
1090 /* If one path has a label but the other does not, do not treat
1091 * them as equals for multipath
1092 */
1093 if ((new->extra &&bgp_is_valid_label(&new->extra->label[0]))
1094 != (exist->extra
1095 && bgp_is_valid_label(&exist->extra->label[0]))) {
1096 if (debug)
1097 zlog_debug(
1098 "%s: %s and %s cannot be multipath, one has a label while the other does not",
1099 pfx_buf, new_buf, exist_buf);
1100 } else if (CHECK_FLAG(bgp->flags,
1101 BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
1102
1103 /*
1104 * For the two paths, all comparison steps till IGP
1105 * metric
1106 * have succeeded - including AS_PATH hop count. Since
1107 * 'bgp
1108 * bestpath as-path multipath-relax' knob is on, we
1109 * don't need
1110 * an exact match of AS_PATH. Thus, mark the paths are
1111 * equal.
1112 * That will trigger both these paths to get into the
1113 * multipath
1114 * array.
1115 */
1116 *paths_eq = 1;
1117
1118 if (debug)
1119 zlog_debug(
1120 "%s: %s and %s are equal via multipath-relax",
1121 pfx_buf, new_buf, exist_buf);
1122 } else if (new->peer->sort == BGP_PEER_IBGP) {
1123 if (aspath_cmp(new->attr->aspath,
1124 exist->attr->aspath)) {
1125 *paths_eq = 1;
1126
1127 if (debug)
1128 zlog_debug(
1129 "%s: %s and %s are equal via matching aspaths",
1130 pfx_buf, new_buf, exist_buf);
1131 }
1132 } else if (new->peer->as == exist->peer->as) {
1133 *paths_eq = 1;
1134
1135 if (debug)
1136 zlog_debug(
1137 "%s: %s and %s are equal via same remote-as",
1138 pfx_buf, new_buf, exist_buf);
1139 }
1140 } else {
1141 /*
1142 * TODO: If unequal cost ibgp multipath is enabled we can
1143 * mark the paths as equal here instead of returning
1144 */
1145
1146 /* Prior to the addition of BGP_FLAG_PEERTYPE_MULTIPATH_RELAX,
1147 * if either step 7 or 10 (peer type checks) yielded a winner,
1148 * that result was returned immediately. Returning from step 10
1149 * ignored the return value computed in steps 8 and 9 (IGP
1150 * metric checks). In order to preserve that behavior, if
1151 * peer_sort_ret is set, return that rather than igp_metric_ret.
1152 */
1153 ret = peer_sort_ret;
1154 if (peer_sort_ret < 0) {
1155 ret = igp_metric_ret;
1156 if (debug) {
1157 if (ret == 1)
1158 zlog_debug(
1159 "%s: %s wins over %s after IGP metric comparison",
1160 pfx_buf, new_buf, exist_buf);
1161 else
1162 zlog_debug(
1163 "%s: %s loses to %s after IGP metric comparison",
1164 pfx_buf, new_buf, exist_buf);
1165 }
1166 *reason = bgp_path_selection_igp_metric;
1167 }
1168 return ret;
1169 }
1170
1171 /*
1172 * At this point, the decision whether to set *paths_eq = 1 has been
1173 * completed. If we deferred returning because of bestpath peer-type
1174 * relax configuration, return now.
1175 */
1176 if (peer_sort_ret >= 0)
1177 return peer_sort_ret;
1178
1179 /* 12. If both paths are external, prefer the path that was received
1180 first (the oldest one). This step minimizes route-flap, since a
1181 newer path won't displace an older one, even if it was the
1182 preferred route based on the additional decision criteria below. */
1183 if (!CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID)
1184 && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
1185 if (CHECK_FLAG(new->flags, BGP_PATH_SELECTED)) {
1186 *reason = bgp_path_selection_older;
1187 if (debug)
1188 zlog_debug(
1189 "%s: %s wins over %s due to oldest external",
1190 pfx_buf, new_buf, exist_buf);
1191 return 1;
1192 }
1193
1194 if (CHECK_FLAG(exist->flags, BGP_PATH_SELECTED)) {
1195 *reason = bgp_path_selection_older;
1196 if (debug)
1197 zlog_debug(
1198 "%s: %s loses to %s due to oldest external",
1199 pfx_buf, new_buf, exist_buf);
1200 return 0;
1201 }
1202 }
1203
1204 /* 13. Router-ID comparision. */
1205 /* If one of the paths is "stale", the corresponding peer router-id will
1206 * be 0 and would always win over the other path. If originator id is
1207 * used for the comparision, it will decide which path is better.
1208 */
1209 if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1210 new_id.s_addr = newattr->originator_id.s_addr;
1211 else
1212 new_id.s_addr = new->peer->remote_id.s_addr;
1213 if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
1214 exist_id.s_addr = existattr->originator_id.s_addr;
1215 else
1216 exist_id.s_addr = exist->peer->remote_id.s_addr;
1217
1218 if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
1219 *reason = bgp_path_selection_router_id;
1220 if (debug)
1221 zlog_debug(
1222 "%s: %s wins over %s due to Router-ID comparison",
1223 pfx_buf, new_buf, exist_buf);
1224 return 1;
1225 }
1226
1227 if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
1228 *reason = bgp_path_selection_router_id;
1229 if (debug)
1230 zlog_debug(
1231 "%s: %s loses to %s due to Router-ID comparison",
1232 pfx_buf, new_buf, exist_buf);
1233 return 0;
1234 }
1235
1236 /* 14. Cluster length comparision. */
1237 new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
1238 exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
1239
1240 if (new_cluster < exist_cluster) {
1241 *reason = bgp_path_selection_cluster_length;
1242 if (debug)
1243 zlog_debug(
1244 "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
1245 pfx_buf, new_buf, exist_buf, new_cluster,
1246 exist_cluster);
1247 return 1;
1248 }
1249
1250 if (new_cluster > exist_cluster) {
1251 *reason = bgp_path_selection_cluster_length;
1252 if (debug)
1253 zlog_debug(
1254 "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
1255 pfx_buf, new_buf, exist_buf, new_cluster,
1256 exist_cluster);
1257 return 0;
1258 }
1259
1260 /* 15. Neighbor address comparision. */
1261 /* Do this only if neither path is "stale" as stale paths do not have
1262 * valid peer information (as the connection may or may not be up).
1263 */
1264 if (CHECK_FLAG(exist->flags, BGP_PATH_STALE)) {
1265 *reason = bgp_path_selection_stale;
1266 if (debug)
1267 zlog_debug(
1268 "%s: %s wins over %s due to latter path being STALE",
1269 pfx_buf, new_buf, exist_buf);
1270 return 1;
1271 }
1272
1273 if (CHECK_FLAG(new->flags, BGP_PATH_STALE)) {
1274 *reason = bgp_path_selection_stale;
1275 if (debug)
1276 zlog_debug(
1277 "%s: %s loses to %s due to former path being STALE",
1278 pfx_buf, new_buf, exist_buf);
1279 return 0;
1280 }
1281
1282 /* locally configured routes to advertise do not have su_remote */
1283 if (new->peer->su_remote == NULL) {
1284 *reason = bgp_path_selection_local_configured;
1285 return 0;
1286 }
1287 if (exist->peer->su_remote == NULL) {
1288 *reason = bgp_path_selection_local_configured;
1289 return 1;
1290 }
1291
1292 ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
1293
1294 if (ret == 1) {
1295 *reason = bgp_path_selection_neighbor_ip;
1296 if (debug)
1297 zlog_debug(
1298 "%s: %s loses to %s due to Neighor IP comparison",
1299 pfx_buf, new_buf, exist_buf);
1300 return 0;
1301 }
1302
1303 if (ret == -1) {
1304 *reason = bgp_path_selection_neighbor_ip;
1305 if (debug)
1306 zlog_debug(
1307 "%s: %s wins over %s due to Neighor IP comparison",
1308 pfx_buf, new_buf, exist_buf);
1309 return 1;
1310 }
1311
1312 *reason = bgp_path_selection_default;
1313 if (debug)
1314 zlog_debug("%s: %s wins over %s due to nothing left to compare",
1315 pfx_buf, new_buf, exist_buf);
1316
1317 return 1;
1318 }
1319
1320
1321 int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
1322 struct bgp_path_info *exist, int *paths_eq)
1323 {
1324 enum bgp_path_selection_reason reason;
1325 char pfx_buf[PREFIX2STR_BUFFER];
1326
1327 return bgp_path_info_cmp(bgp, new, exist, paths_eq, NULL, 0, pfx_buf,
1328 AFI_L2VPN, SAFI_EVPN, &reason);
1329 }
1330
1331 /* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
1332 * is preferred, or 0 if they are the same (usually will only occur if
1333 * multipath is enabled
1334 * This version is compatible with */
1335 int bgp_path_info_cmp_compatible(struct bgp *bgp, struct bgp_path_info *new,
1336 struct bgp_path_info *exist, char *pfx_buf,
1337 afi_t afi, safi_t safi,
1338 enum bgp_path_selection_reason *reason)
1339 {
1340 int paths_eq;
1341 int ret;
1342 ret = bgp_path_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, pfx_buf,
1343 afi, safi, reason);
1344
1345 if (paths_eq)
1346 ret = 0;
1347 else {
1348 if (ret == 1)
1349 ret = -1;
1350 else
1351 ret = 1;
1352 }
1353 return ret;
1354 }
1355
1356 static enum filter_type bgp_input_filter(struct peer *peer,
1357 const struct prefix *p,
1358 struct attr *attr, afi_t afi,
1359 safi_t safi)
1360 {
1361 struct bgp_filter *filter;
1362 enum filter_type ret = FILTER_PERMIT;
1363
1364 filter = &peer->filter[afi][safi];
1365
1366 #define FILTER_EXIST_WARN(F, f, filter) \
1367 if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
1368 zlog_debug("%s: Could not find configured input %s-list %s!", \
1369 peer->host, #f, F##_IN_NAME(filter));
1370
1371 if (DISTRIBUTE_IN_NAME(filter)) {
1372 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1373
1374 if (access_list_apply(DISTRIBUTE_IN(filter), p)
1375 == FILTER_DENY) {
1376 ret = FILTER_DENY;
1377 goto done;
1378 }
1379 }
1380
1381 if (PREFIX_LIST_IN_NAME(filter)) {
1382 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1383
1384 if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
1385 == PREFIX_DENY) {
1386 ret = FILTER_DENY;
1387 goto done;
1388 }
1389 }
1390
1391 if (FILTER_LIST_IN_NAME(filter)) {
1392 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1393
1394 if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
1395 == AS_FILTER_DENY) {
1396 ret = FILTER_DENY;
1397 goto done;
1398 }
1399 }
1400
1401 done:
1402 if (frrtrace_enabled(frr_bgp, input_filter)) {
1403 char pfxprint[PREFIX2STR_BUFFER];
1404
1405 prefix2str(p, pfxprint, sizeof(pfxprint));
1406 frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
1407 ret == FILTER_PERMIT ? "permit" : "deny");
1408 }
1409
1410 return ret;
1411 #undef FILTER_EXIST_WARN
1412 }
1413
1414 static enum filter_type bgp_output_filter(struct peer *peer,
1415 const struct prefix *p,
1416 struct attr *attr, afi_t afi,
1417 safi_t safi)
1418 {
1419 struct bgp_filter *filter;
1420 enum filter_type ret = FILTER_PERMIT;
1421
1422 filter = &peer->filter[afi][safi];
1423
1424 #define FILTER_EXIST_WARN(F, f, filter) \
1425 if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
1426 zlog_debug("%s: Could not find configured output %s-list %s!", \
1427 peer->host, #f, F##_OUT_NAME(filter));
1428
1429 if (DISTRIBUTE_OUT_NAME(filter)) {
1430 FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
1431
1432 if (access_list_apply(DISTRIBUTE_OUT(filter), p)
1433 == FILTER_DENY) {
1434 ret = FILTER_DENY;
1435 goto done;
1436 }
1437 }
1438
1439 if (PREFIX_LIST_OUT_NAME(filter)) {
1440 FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
1441
1442 if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
1443 == PREFIX_DENY) {
1444 ret = FILTER_DENY;
1445 goto done;
1446 }
1447 }
1448
1449 if (FILTER_LIST_OUT_NAME(filter)) {
1450 FILTER_EXIST_WARN(FILTER_LIST, as, filter);
1451
1452 if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
1453 == AS_FILTER_DENY) {
1454 ret = FILTER_DENY;
1455 goto done;
1456 }
1457 }
1458
1459 if (frrtrace_enabled(frr_bgp, output_filter)) {
1460 char pfxprint[PREFIX2STR_BUFFER];
1461
1462 prefix2str(p, pfxprint, sizeof(pfxprint));
1463 frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
1464 ret == FILTER_PERMIT ? "permit" : "deny");
1465 }
1466
1467 done:
1468 return ret;
1469 #undef FILTER_EXIST_WARN
1470 }
1471
1472 /* If community attribute includes no_export then return 1. */
1473 static bool bgp_community_filter(struct peer *peer, struct attr *attr)
1474 {
1475 if (attr->community) {
1476 /* NO_ADVERTISE check. */
1477 if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
1478 return true;
1479
1480 /* NO_EXPORT check. */
1481 if (peer->sort == BGP_PEER_EBGP
1482 && community_include(attr->community, COMMUNITY_NO_EXPORT))
1483 return true;
1484
1485 /* NO_EXPORT_SUBCONFED check. */
1486 if (peer->sort == BGP_PEER_EBGP
1487 || peer->sort == BGP_PEER_CONFED)
1488 if (community_include(attr->community,
1489 COMMUNITY_NO_EXPORT_SUBCONFED))
1490 return true;
1491 }
1492 return false;
1493 }
1494
1495 /* Route reflection loop check. */
1496 static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
1497 {
1498 struct in_addr cluster_id;
1499 struct cluster_list *cluster = bgp_attr_get_cluster(attr);
1500
1501 if (cluster) {
1502 if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
1503 cluster_id = peer->bgp->cluster_id;
1504 else
1505 cluster_id = peer->bgp->router_id;
1506
1507 if (cluster_loop_check(cluster, cluster_id))
1508 return true;
1509 }
1510 return false;
1511 }
1512
1513 static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
1514 struct attr *attr, afi_t afi, safi_t safi,
1515 const char *rmap_name, mpls_label_t *label,
1516 uint32_t num_labels, struct bgp_dest *dest)
1517 {
1518 struct bgp_filter *filter;
1519 struct bgp_path_info rmap_path = { 0 };
1520 struct bgp_path_info_extra extra = { 0 };
1521 route_map_result_t ret;
1522 struct route_map *rmap = NULL;
1523
1524 filter = &peer->filter[afi][safi];
1525
1526 /* Apply default weight value. */
1527 if (peer->weight[afi][safi])
1528 attr->weight = peer->weight[afi][safi];
1529
1530 if (rmap_name) {
1531 rmap = route_map_lookup_by_name(rmap_name);
1532
1533 if (rmap == NULL)
1534 return RMAP_DENY;
1535 } else {
1536 if (ROUTE_MAP_IN_NAME(filter)) {
1537 rmap = ROUTE_MAP_IN(filter);
1538
1539 if (rmap == NULL)
1540 return RMAP_DENY;
1541 }
1542 }
1543
1544 /* Route map apply. */
1545 if (rmap) {
1546 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1547 /* Duplicate current value to new strucutre for modification. */
1548 rmap_path.peer = peer;
1549 rmap_path.attr = attr;
1550 rmap_path.extra = &extra;
1551 rmap_path.net = dest;
1552
1553 extra.num_labels = num_labels;
1554 if (label && num_labels && num_labels <= BGP_MAX_LABELS)
1555 memcpy(extra.label, label,
1556 num_labels * sizeof(mpls_label_t));
1557
1558 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
1559
1560 /* Apply BGP route map to the attribute. */
1561 ret = route_map_apply(rmap, p, &rmap_path);
1562
1563 peer->rmap_type = 0;
1564
1565 if (ret == RMAP_DENYMATCH)
1566 return RMAP_DENY;
1567 }
1568 return RMAP_PERMIT;
1569 }
1570
1571 static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
1572 struct attr *attr, afi_t afi, safi_t safi,
1573 const char *rmap_name)
1574 {
1575 struct bgp_path_info rmap_path;
1576 route_map_result_t ret;
1577 struct route_map *rmap = NULL;
1578 uint8_t rmap_type;
1579
1580 /*
1581 * So if we get to this point and have no rmap_name
1582 * we want to just show the output as it currently
1583 * exists.
1584 */
1585 if (!rmap_name)
1586 return RMAP_PERMIT;
1587
1588 /* Apply default weight value. */
1589 if (peer->weight[afi][safi])
1590 attr->weight = peer->weight[afi][safi];
1591
1592 rmap = route_map_lookup_by_name(rmap_name);
1593
1594 /*
1595 * If we have a route map name and we do not find
1596 * the routemap that means we have an implicit
1597 * deny.
1598 */
1599 if (rmap == NULL)
1600 return RMAP_DENY;
1601
1602 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
1603 /* Route map apply. */
1604 /* Duplicate current value to new strucutre for modification. */
1605 rmap_path.peer = peer;
1606 rmap_path.attr = attr;
1607
1608 rmap_type = peer->rmap_type;
1609 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
1610
1611 /* Apply BGP route map to the attribute. */
1612 ret = route_map_apply(rmap, p, &rmap_path);
1613
1614 peer->rmap_type = rmap_type;
1615
1616 if (ret == RMAP_DENYMATCH)
1617 /*
1618 * caller has multiple error paths with bgp_attr_flush()
1619 */
1620 return RMAP_DENY;
1621
1622 return RMAP_PERMIT;
1623 }
1624
1625 /* If this is an EBGP peer with remove-private-AS */
1626 static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
1627 struct peer *peer, struct attr *attr)
1628 {
1629 if (peer->sort == BGP_PEER_EBGP
1630 && (peer_af_flag_check(peer, afi, safi,
1631 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1632 || peer_af_flag_check(peer, afi, safi,
1633 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
1634 || peer_af_flag_check(peer, afi, safi,
1635 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
1636 || peer_af_flag_check(peer, afi, safi,
1637 PEER_FLAG_REMOVE_PRIVATE_AS))) {
1638 // Take action on the entire aspath
1639 if (peer_af_flag_check(peer, afi, safi,
1640 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
1641 || peer_af_flag_check(peer, afi, safi,
1642 PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
1643 if (peer_af_flag_check(
1644 peer, afi, safi,
1645 PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
1646 attr->aspath = aspath_replace_private_asns(
1647 attr->aspath, bgp->as, peer->as);
1648
1649 // The entire aspath consists of private ASNs so create
1650 // an empty aspath
1651 else if (aspath_private_as_check(attr->aspath))
1652 attr->aspath = aspath_empty_get();
1653
1654 // There are some public and some private ASNs, remove
1655 // the private ASNs
1656 else
1657 attr->aspath = aspath_remove_private_asns(
1658 attr->aspath, peer->as);
1659 }
1660
1661 // 'all' was not specified so the entire aspath must be private
1662 // ASNs
1663 // for us to do anything
1664 else if (aspath_private_as_check(attr->aspath)) {
1665 if (peer_af_flag_check(
1666 peer, afi, safi,
1667 PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
1668 attr->aspath = aspath_replace_private_asns(
1669 attr->aspath, bgp->as, peer->as);
1670 else
1671 attr->aspath = aspath_empty_get();
1672 }
1673 }
1674 }
1675
1676 /* If this is an EBGP peer with as-override */
1677 static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
1678 struct peer *peer, struct attr *attr)
1679 {
1680 if (peer->sort == BGP_PEER_EBGP
1681 && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
1682 if (aspath_single_asn_check(attr->aspath, peer->as))
1683 attr->aspath = aspath_replace_specific_asn(
1684 attr->aspath, peer->as, bgp->as);
1685 }
1686 }
1687
1688 void bgp_attr_add_gshut_community(struct attr *attr)
1689 {
1690 struct community *old;
1691 struct community *new;
1692 struct community *merge;
1693 struct community *gshut;
1694
1695 old = attr->community;
1696 gshut = community_str2com("graceful-shutdown");
1697
1698 assert(gshut);
1699
1700 if (old) {
1701 merge = community_merge(community_dup(old), gshut);
1702
1703 if (old->refcnt == 0)
1704 community_free(&old);
1705
1706 new = community_uniq_sort(merge);
1707 community_free(&merge);
1708 } else {
1709 new = community_dup(gshut);
1710 }
1711
1712 community_free(&gshut);
1713 attr->community = new;
1714 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
1715
1716 /* When we add the graceful-shutdown community we must also
1717 * lower the local-preference */
1718 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1719 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
1720 }
1721
1722
1723 /* Notify BGP Conditional advertisement scanner process. */
1724 void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
1725 {
1726 struct peer *temp_peer;
1727 struct peer *peer = SUBGRP_PEER(subgrp);
1728 struct listnode *temp_node, *temp_nnode = NULL;
1729 afi_t afi = SUBGRP_AFI(subgrp);
1730 safi_t safi = SUBGRP_SAFI(subgrp);
1731 struct bgp *bgp = SUBGRP_INST(subgrp);
1732 struct bgp_filter *filter = &peer->filter[afi][safi];
1733
1734 if (!ADVERTISE_MAP_NAME(filter))
1735 return;
1736
1737 for (ALL_LIST_ELEMENTS(bgp->peer, temp_node, temp_nnode, temp_peer)) {
1738 if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
1739 continue;
1740
1741 if (peer != temp_peer)
1742 continue;
1743
1744 temp_peer->advmap_table_change = true;
1745 break;
1746 }
1747 }
1748
1749
1750 void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
1751 {
1752 if (family == AF_INET) {
1753 attr->nexthop.s_addr = INADDR_ANY;
1754 attr->mp_nexthop_global_in.s_addr = INADDR_ANY;
1755 }
1756 if (family == AF_INET6)
1757 memset(&attr->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
1758 if (family == AF_EVPN)
1759 memset(&attr->mp_nexthop_global_in, 0, BGP_ATTR_NHLEN_IPV4);
1760 }
1761
1762 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
1763 struct update_subgroup *subgrp,
1764 const struct prefix *p, struct attr *attr,
1765 bool skip_rmap_check)
1766 {
1767 struct bgp_filter *filter;
1768 struct peer *from;
1769 struct peer *peer;
1770 struct peer *onlypeer;
1771 struct bgp *bgp;
1772 struct attr *piattr;
1773 route_map_result_t ret;
1774 int transparent;
1775 int reflect;
1776 afi_t afi;
1777 safi_t safi;
1778 int samepeer_safe = 0; /* for synthetic mplsvpns routes */
1779 bool nh_reset = false;
1780 uint64_t cum_bw;
1781
1782 if (DISABLE_BGP_ANNOUNCE)
1783 return false;
1784
1785 afi = SUBGRP_AFI(subgrp);
1786 safi = SUBGRP_SAFI(subgrp);
1787 peer = SUBGRP_PEER(subgrp);
1788 onlypeer = NULL;
1789 if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
1790 onlypeer = SUBGRP_PFIRST(subgrp)->peer;
1791
1792 from = pi->peer;
1793 filter = &peer->filter[afi][safi];
1794 bgp = SUBGRP_INST(subgrp);
1795 piattr = bgp_path_info_mpath_count(pi) ? bgp_path_info_mpath_attr(pi)
1796 : pi->attr;
1797
1798 #ifdef ENABLE_BGP_VNC
1799 if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
1800 && ((pi->type == ZEBRA_ROUTE_BGP_DIRECT)
1801 || (pi->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
1802
1803 /*
1804 * direct and direct_ext type routes originate internally even
1805 * though they can have peer pointers that reference other
1806 * systems
1807 */
1808 zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
1809 __func__, p);
1810 samepeer_safe = 1;
1811 }
1812 #endif
1813
1814 if (((afi == AFI_IP) || (afi == AFI_IP6))
1815 && ((safi == SAFI_MPLS_VPN) || (safi == SAFI_UNICAST))
1816 && (pi->type == ZEBRA_ROUTE_BGP)
1817 && (pi->sub_type == BGP_ROUTE_IMPORTED)) {
1818
1819 /* Applies to routes leaked vpn->vrf and vrf->vpn */
1820
1821 samepeer_safe = 1;
1822 }
1823
1824 /* With addpath we may be asked to TX all kinds of paths so make sure
1825 * pi is valid */
1826 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)
1827 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)
1828 || CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
1829 return false;
1830 }
1831
1832 /* If this is not the bestpath then check to see if there is an enabled
1833 * addpath
1834 * feature that requires us to advertise it */
1835 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
1836 if (!bgp_addpath_tx_path(peer->addpath_type[afi][safi], pi)) {
1837 return false;
1838 }
1839 }
1840
1841 /* Aggregate-address suppress check. */
1842 if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
1843 return false;
1844
1845 /*
1846 * If we are doing VRF 2 VRF leaking via the import
1847 * statement, we want to prevent the route going
1848 * off box as that the RT and RD created are localy
1849 * significant and globaly useless.
1850 */
1851 if (safi == SAFI_MPLS_VPN && pi->extra && pi->extra->num_labels
1852 && pi->extra->label[0] == BGP_PREVENT_VRF_2_VRF_LEAK)
1853 return false;
1854
1855 /* If it's labeled safi, make sure the route has a valid label. */
1856 if (safi == SAFI_LABELED_UNICAST) {
1857 mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
1858 if (!bgp_is_valid_label(&label)) {
1859 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1860 zlog_debug("u%" PRIu64 ":s%" PRIu64
1861 " %pFX is filtered - no label (%p)",
1862 subgrp->update_group->id, subgrp->id,
1863 p, &label);
1864 return false;
1865 }
1866 }
1867
1868 /* Do not send back route to sender. */
1869 if (onlypeer && from == onlypeer) {
1870 return false;
1871 }
1872
1873 /* Do not send the default route in the BGP table if the neighbor is
1874 * configured for default-originate */
1875 if (CHECK_FLAG(peer->af_flags[afi][safi],
1876 PEER_FLAG_DEFAULT_ORIGINATE)) {
1877 if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY)
1878 return false;
1879 else if (p->family == AF_INET6 && p->prefixlen == 0)
1880 return false;
1881 }
1882
1883 /* Transparency check. */
1884 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)
1885 && CHECK_FLAG(from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
1886 transparent = 1;
1887 else
1888 transparent = 0;
1889
1890 /* If community is not disabled check the no-export and local. */
1891 if (!transparent && bgp_community_filter(peer, piattr)) {
1892 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1893 zlog_debug("%s: community filter check fail for %pFX",
1894 __func__, p);
1895 return false;
1896 }
1897
1898 /* If the attribute has originator-id and it is same as remote
1899 peer's id. */
1900 if (onlypeer && piattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
1901 && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
1902 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1903 zlog_debug(
1904 "%s [Update:SEND] %pFX originator-id is same as remote router-id",
1905 onlypeer->host, p);
1906 return false;
1907 }
1908
1909 /* ORF prefix-list filter check */
1910 if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
1911 && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
1912 || CHECK_FLAG(peer->af_cap[afi][safi],
1913 PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
1914 if (peer->orf_plist[afi][safi]) {
1915 if (prefix_list_apply(peer->orf_plist[afi][safi], p)
1916 == PREFIX_DENY) {
1917 if (bgp_debug_update(NULL, p,
1918 subgrp->update_group, 0))
1919 zlog_debug(
1920 "%s [Update:SEND] %pFX is filtered via ORF",
1921 peer->host, p);
1922 return false;
1923 }
1924 }
1925
1926 /* Output filter check. */
1927 if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
1928 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1929 zlog_debug("%s [Update:SEND] %pFX is filtered",
1930 peer->host, p);
1931 return false;
1932 }
1933
1934 /* AS path loop check. */
1935 if (onlypeer && onlypeer->as_path_loop_detection
1936 && aspath_loop_check(piattr->aspath, onlypeer->as)) {
1937 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1938 zlog_debug(
1939 "%s [Update:SEND] suppress announcement to peer AS %u that is part of AS path.",
1940 onlypeer->host, onlypeer->as);
1941 return false;
1942 }
1943
1944 /* If we're a CONFED we need to loop check the CONFED ID too */
1945 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
1946 if (aspath_loop_check(piattr->aspath, bgp->confed_id)) {
1947 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
1948 zlog_debug(
1949 "%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
1950 peer->host, bgp->confed_id);
1951 return false;
1952 }
1953 }
1954
1955 /* Route-Reflect check. */
1956 if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
1957 reflect = 1;
1958 else
1959 reflect = 0;
1960
1961 /* IBGP reflection check. */
1962 if (reflect && !samepeer_safe) {
1963 /* A route from a Client peer. */
1964 if (CHECK_FLAG(from->af_flags[afi][safi],
1965 PEER_FLAG_REFLECTOR_CLIENT)) {
1966 /* Reflect to all the Non-Client peers and also to the
1967 Client peers other than the originator. Originator
1968 check
1969 is already done. So there is noting to do. */
1970 /* no bgp client-to-client reflection check. */
1971 if (CHECK_FLAG(bgp->flags,
1972 BGP_FLAG_NO_CLIENT_TO_CLIENT))
1973 if (CHECK_FLAG(peer->af_flags[afi][safi],
1974 PEER_FLAG_REFLECTOR_CLIENT))
1975 return false;
1976 } else {
1977 /* A route from a Non-client peer. Reflect to all other
1978 clients. */
1979 if (!CHECK_FLAG(peer->af_flags[afi][safi],
1980 PEER_FLAG_REFLECTOR_CLIENT))
1981 return false;
1982 }
1983 }
1984
1985 /* For modify attribute, copy it to temporary structure. */
1986 *attr = *piattr;
1987
1988 /* If local-preference is not set. */
1989 if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
1990 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
1991 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
1992 attr->local_pref = bgp->default_local_pref;
1993 }
1994
1995 /* If originator-id is not set and the route is to be reflected,
1996 set the originator id */
1997 if (reflect
1998 && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
1999 IPV4_ADDR_COPY(&(attr->originator_id), &(from->remote_id));
2000 SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
2001 }
2002
2003 /* Remove MED if its an EBGP peer - will get overwritten by route-maps
2004 */
2005 if (peer->sort == BGP_PEER_EBGP
2006 && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
2007 if (from != bgp->peer_self && !transparent
2008 && !CHECK_FLAG(peer->af_flags[afi][safi],
2009 PEER_FLAG_MED_UNCHANGED))
2010 attr->flag &=
2011 ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
2012 }
2013
2014 /* Since the nexthop attribute can vary per peer, it is not explicitly
2015 * set
2016 * in announce check, only certain flags and length (or number of
2017 * nexthops
2018 * -- for IPv6/MP_REACH) are set here in order to guide the update
2019 * formation
2020 * code in setting the nexthop(s) on a per peer basis in
2021 * reformat_peer().
2022 * Typically, the source nexthop in the attribute is preserved but in
2023 * the
2024 * scenarios where we know it will always be overwritten, we reset the
2025 * nexthop to "0" in an attempt to achieve better Update packing. An
2026 * example of this is when a prefix from each of 2 IBGP peers needs to
2027 * be
2028 * announced to an EBGP peer (and they have the same attributes barring
2029 * their nexthop).
2030 */
2031 if (reflect)
2032 SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
2033
2034 #define NEXTHOP_IS_V6 \
2035 ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
2036 && (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi))) \
2037 || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
2038 && attr->mp_nexthop_len >= IPV6_MAX_BYTELEN))
2039
2040 /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
2041 * if
2042 * the peer (group) is configured to receive link-local nexthop
2043 * unchanged
2044 * and it is available in the prefix OR we're not reflecting the route,
2045 * link-local nexthop address is valid and
2046 * the peer (group) to whom we're going to announce is on a shared
2047 * network
2048 * and this is either a self-originated route or the peer is EBGP.
2049 * By checking if nexthop LL address is valid we are sure that
2050 * we do not announce LL address as `::`.
2051 */
2052 if (NEXTHOP_IS_V6) {
2053 attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
2054 if ((CHECK_FLAG(peer->af_flags[afi][safi],
2055 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
2056 && IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_local))
2057 || (!reflect
2058 && IN6_IS_ADDR_LINKLOCAL(&peer->nexthop.v6_local)
2059 && peer->shared_network
2060 && (from == bgp->peer_self
2061 || peer->sort == BGP_PEER_EBGP))) {
2062 attr->mp_nexthop_len =
2063 BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
2064 }
2065
2066 /* Clear off link-local nexthop in source, whenever it is not
2067 * needed to
2068 * ensure more prefixes share the same attribute for
2069 * announcement.
2070 */
2071 if (!(CHECK_FLAG(peer->af_flags[afi][safi],
2072 PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
2073 memset(&attr->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
2074 }
2075
2076 bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
2077 bgp_peer_as_override(bgp, afi, safi, peer, attr);
2078
2079 /* Route map & unsuppress-map apply. */
2080 if (!skip_rmap_check
2081 && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
2082 struct bgp_path_info rmap_path = {0};
2083 struct bgp_path_info_extra dummy_rmap_path_extra = {0};
2084 struct attr dummy_attr = {0};
2085
2086 /* Fill temp path_info */
2087 prep_for_rmap_apply(&rmap_path, &dummy_rmap_path_extra, dest,
2088 pi, peer, attr);
2089
2090 /* don't confuse inbound and outbound setting */
2091 RESET_FLAG(attr->rmap_change_flags);
2092
2093 /*
2094 * The route reflector is not allowed to modify the attributes
2095 * of the reflected IBGP routes unless explicitly allowed.
2096 */
2097 if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
2098 && !CHECK_FLAG(bgp->flags,
2099 BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
2100 dummy_attr = *attr;
2101 rmap_path.attr = &dummy_attr;
2102 }
2103
2104 SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
2105
2106 if (bgp_path_suppressed(pi))
2107 ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
2108 &rmap_path);
2109 else
2110 ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
2111 &rmap_path);
2112
2113 peer->rmap_type = 0;
2114
2115 if (ret == RMAP_DENYMATCH) {
2116 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2117 zlog_debug(
2118 "%s [Update:SEND] %pFX is filtered by route-map",
2119 peer->host, p);
2120
2121 bgp_attr_flush(attr);
2122 return false;
2123 }
2124 }
2125
2126 /* RFC 8212 to prevent route leaks.
2127 * This specification intends to improve this situation by requiring the
2128 * explicit configuration of both BGP Import and Export Policies for any
2129 * External BGP (EBGP) session such as customers, peers, or
2130 * confederation boundaries for all enabled address families. Through
2131 * codification of the aforementioned requirement, operators will
2132 * benefit from consistent behavior across different BGP
2133 * implementations.
2134 */
2135 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
2136 if (!bgp_outbound_policy_exists(peer, filter))
2137 return false;
2138
2139 /* draft-ietf-idr-deprecate-as-set-confed-set
2140 * Filter routes having AS_SET or AS_CONFED_SET in the path.
2141 * Eventually, This document (if approved) updates RFC 4271
2142 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
2143 * and obsoletes RFC 6472.
2144 */
2145 if (peer->bgp->reject_as_sets)
2146 if (aspath_check_as_sets(attr->aspath))
2147 return false;
2148
2149 /* Codification of AS 0 Processing */
2150 if (aspath_check_as_zero(attr->aspath))
2151 return false;
2152
2153 if (bgp_in_graceful_shutdown(bgp)) {
2154 if (peer->sort == BGP_PEER_IBGP
2155 || peer->sort == BGP_PEER_CONFED) {
2156 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
2157 attr->local_pref = BGP_GSHUT_LOCAL_PREF;
2158 } else {
2159 bgp_attr_add_gshut_community(attr);
2160 }
2161 }
2162
2163 /* After route-map has been applied, we check to see if the nexthop to
2164 * be carried in the attribute (that is used for the announcement) can
2165 * be cleared off or not. We do this in all cases where we would be
2166 * setting the nexthop to "ourselves". For IPv6, we only need to
2167 * consider
2168 * the global nexthop here; the link-local nexthop would have been
2169 * cleared
2170 * already, and if not, it is required by the update formation code.
2171 * Also see earlier comments in this function.
2172 */
2173 /*
2174 * If route-map has performed some operation on the nexthop or the peer
2175 * configuration says to pass it unchanged, we cannot reset the nexthop
2176 * here, so only attempt to do it if these aren't true. Note that the
2177 * route-map handler itself might have cleared the nexthop, if for
2178 * example,
2179 * it is configured as 'peer-address'.
2180 */
2181 if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
2182 piattr->rmap_change_flags)
2183 && !transparent
2184 && !CHECK_FLAG(peer->af_flags[afi][safi],
2185 PEER_FLAG_NEXTHOP_UNCHANGED)) {
2186 /* We can reset the nexthop, if setting (or forcing) it to
2187 * 'self' */
2188 if (CHECK_FLAG(peer->af_flags[afi][safi],
2189 PEER_FLAG_NEXTHOP_SELF)
2190 || CHECK_FLAG(peer->af_flags[afi][safi],
2191 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2192 if (!reflect
2193 || CHECK_FLAG(peer->af_flags[afi][safi],
2194 PEER_FLAG_FORCE_NEXTHOP_SELF)) {
2195 subgroup_announce_reset_nhop(
2196 (peer_cap_enhe(peer, afi, safi)
2197 ? AF_INET6
2198 : p->family),
2199 attr);
2200 nh_reset = true;
2201 }
2202 } else if (peer->sort == BGP_PEER_EBGP) {
2203 /* Can also reset the nexthop if announcing to EBGP, but
2204 * only if
2205 * no peer in the subgroup is on a shared subnet.
2206 * Note: 3rd party nexthop currently implemented for
2207 * IPv4 only.
2208 */
2209 if ((p->family == AF_INET) &&
2210 (!bgp_subgrp_multiaccess_check_v4(
2211 piattr->nexthop,
2212 subgrp, from))) {
2213 subgroup_announce_reset_nhop(
2214 (peer_cap_enhe(peer, afi, safi)
2215 ? AF_INET6
2216 : p->family),
2217 attr);
2218 nh_reset = true;
2219 }
2220
2221 if ((p->family == AF_INET6) &&
2222 (!bgp_subgrp_multiaccess_check_v6(
2223 piattr->mp_nexthop_global,
2224 subgrp, from))) {
2225 subgroup_announce_reset_nhop(
2226 (peer_cap_enhe(peer, afi, safi)
2227 ? AF_INET6
2228 : p->family),
2229 attr);
2230 nh_reset = true;
2231 }
2232
2233
2234
2235 } else if (CHECK_FLAG(pi->flags, BGP_PATH_ANNC_NH_SELF)) {
2236 /*
2237 * This flag is used for leaked vpn-vrf routes
2238 */
2239 int family = p->family;
2240
2241 if (peer_cap_enhe(peer, afi, safi))
2242 family = AF_INET6;
2243
2244 if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
2245 zlog_debug(
2246 "%s: BGP_PATH_ANNC_NH_SELF, family=%s",
2247 __func__, family2str(family));
2248 subgroup_announce_reset_nhop(family, attr);
2249 nh_reset = true;
2250 }
2251 }
2252
2253 /* If IPv6/MP and nexthop does not have any override and happens
2254 * to
2255 * be a link-local address, reset it so that we don't pass along
2256 * the
2257 * source's link-local IPv6 address to recipients who may not be
2258 * on
2259 * the same interface.
2260 */
2261 if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
2262 if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
2263 subgroup_announce_reset_nhop(AF_INET6, attr);
2264 nh_reset = true;
2265 }
2266 }
2267
2268 /*
2269 * When the next hop is set to ourselves, if all multipaths have
2270 * link-bandwidth announce the cumulative bandwidth as that makes
2271 * the most sense. However, don't modify if the link-bandwidth has
2272 * been explicitly set by user policy.
2273 */
2274 if (nh_reset &&
2275 bgp_path_info_mpath_chkwtd(bgp, pi) &&
2276 (cum_bw = bgp_path_info_mpath_cumbw(pi)) != 0 &&
2277 !CHECK_FLAG(attr->rmap_change_flags, BATTR_RMAP_LINK_BW_SET))
2278 attr->ecommunity = ecommunity_replace_linkbw(
2279 bgp->as, attr->ecommunity, cum_bw,
2280 CHECK_FLAG(peer->flags,
2281 PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE));
2282
2283 return true;
2284 }
2285
2286 static int bgp_route_select_timer_expire(struct thread *thread)
2287 {
2288 struct afi_safi_info *info;
2289 afi_t afi;
2290 safi_t safi;
2291 struct bgp *bgp;
2292
2293 info = THREAD_ARG(thread);
2294 afi = info->afi;
2295 safi = info->safi;
2296 bgp = info->bgp;
2297
2298 if (BGP_DEBUG(update, UPDATE_OUT))
2299 zlog_debug("afi %d, safi %d : route select timer expired", afi,
2300 safi);
2301
2302 bgp->gr_info[afi][safi].t_route_select = NULL;
2303
2304 XFREE(MTYPE_TMP, info);
2305
2306 /* Best path selection */
2307 return bgp_best_path_select_defer(bgp, afi, safi);
2308 }
2309
2310 void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
2311 struct bgp_maxpaths_cfg *mpath_cfg,
2312 struct bgp_path_info_pair *result, afi_t afi,
2313 safi_t safi)
2314 {
2315 struct bgp_path_info *new_select;
2316 struct bgp_path_info *old_select;
2317 struct bgp_path_info *pi;
2318 struct bgp_path_info *pi1;
2319 struct bgp_path_info *pi2;
2320 struct bgp_path_info *nextpi = NULL;
2321 int paths_eq, do_mpath, debug;
2322 struct list mp_list;
2323 char pfx_buf[PREFIX2STR_BUFFER];
2324 char path_buf[PATH_ADDPATH_STR_BUFFER];
2325
2326 bgp_mp_list_init(&mp_list);
2327 do_mpath =
2328 (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
2329
2330 debug = bgp_debug_bestpath(dest);
2331
2332 if (debug)
2333 prefix2str(bgp_dest_get_prefix(dest), pfx_buf, sizeof(pfx_buf));
2334
2335 dest->reason = bgp_path_selection_none;
2336 /* bgp deterministic-med */
2337 new_select = NULL;
2338 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
2339
2340 /* Clear BGP_PATH_DMED_SELECTED for all paths */
2341 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2342 pi1 = pi1->next)
2343 bgp_path_info_unset_flag(dest, pi1,
2344 BGP_PATH_DMED_SELECTED);
2345
2346 for (pi1 = bgp_dest_get_bgp_path_info(dest); pi1;
2347 pi1 = pi1->next) {
2348 if (CHECK_FLAG(pi1->flags, BGP_PATH_DMED_CHECK))
2349 continue;
2350 if (BGP_PATH_HOLDDOWN(pi1))
2351 continue;
2352 if (pi1->peer != bgp->peer_self)
2353 if (!peer_established(pi1->peer))
2354 continue;
2355
2356 new_select = pi1;
2357 if (pi1->next) {
2358 for (pi2 = pi1->next; pi2; pi2 = pi2->next) {
2359 if (CHECK_FLAG(pi2->flags,
2360 BGP_PATH_DMED_CHECK))
2361 continue;
2362 if (BGP_PATH_HOLDDOWN(pi2))
2363 continue;
2364 if (pi2->peer != bgp->peer_self
2365 && !CHECK_FLAG(
2366 pi2->peer->sflags,
2367 PEER_STATUS_NSF_WAIT))
2368 if (pi2->peer->status
2369 != Established)
2370 continue;
2371
2372 if (!aspath_cmp_left(pi1->attr->aspath,
2373 pi2->attr->aspath)
2374 && !aspath_cmp_left_confed(
2375 pi1->attr->aspath,
2376 pi2->attr->aspath))
2377 continue;
2378
2379 if (bgp_path_info_cmp(
2380 bgp, pi2, new_select,
2381 &paths_eq, mpath_cfg, debug,
2382 pfx_buf, afi, safi,
2383 &dest->reason)) {
2384 bgp_path_info_unset_flag(
2385 dest, new_select,
2386 BGP_PATH_DMED_SELECTED);
2387 new_select = pi2;
2388 }
2389
2390 bgp_path_info_set_flag(
2391 dest, pi2, BGP_PATH_DMED_CHECK);
2392 }
2393 }
2394 bgp_path_info_set_flag(dest, new_select,
2395 BGP_PATH_DMED_CHECK);
2396 bgp_path_info_set_flag(dest, new_select,
2397 BGP_PATH_DMED_SELECTED);
2398
2399 if (debug) {
2400 bgp_path_info_path_with_addpath_rx_str(
2401 new_select, path_buf, sizeof(path_buf));
2402 zlog_debug(
2403 "%pBD: %s is the bestpath from AS %u",
2404 dest, path_buf,
2405 aspath_get_first_as(
2406 new_select->attr->aspath));
2407 }
2408 }
2409 }
2410
2411 /* Check old selected route and new selected route. */
2412 old_select = NULL;
2413 new_select = NULL;
2414 for (pi = bgp_dest_get_bgp_path_info(dest);
2415 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2416 enum bgp_path_selection_reason reason;
2417
2418 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
2419 old_select = pi;
2420
2421 if (BGP_PATH_HOLDDOWN(pi)) {
2422 /* reap REMOVED routes, if needs be
2423 * selected route must stay for a while longer though
2424 */
2425 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
2426 && (pi != old_select))
2427 bgp_path_info_reap(dest, pi);
2428
2429 if (debug)
2430 zlog_debug("%s: pi %p in holddown", __func__,
2431 pi);
2432
2433 continue;
2434 }
2435
2436 if (pi->peer && pi->peer != bgp->peer_self
2437 && !CHECK_FLAG(pi->peer->sflags, PEER_STATUS_NSF_WAIT))
2438 if (!peer_established(pi->peer)) {
2439
2440 if (debug)
2441 zlog_debug(
2442 "%s: pi %p non self peer %s not estab state",
2443 __func__, pi, pi->peer->host);
2444
2445 continue;
2446 }
2447
2448 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)
2449 && (!CHECK_FLAG(pi->flags, BGP_PATH_DMED_SELECTED))) {
2450 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2451 if (debug)
2452 zlog_debug("%s: pi %p dmed", __func__, pi);
2453 continue;
2454 }
2455
2456 bgp_path_info_unset_flag(dest, pi, BGP_PATH_DMED_CHECK);
2457
2458 reason = dest->reason;
2459 if (bgp_path_info_cmp(bgp, pi, new_select, &paths_eq, mpath_cfg,
2460 debug, pfx_buf, afi, safi,
2461 &dest->reason)) {
2462 if (new_select == NULL &&
2463 reason != bgp_path_selection_none)
2464 dest->reason = reason;
2465 new_select = pi;
2466 }
2467 }
2468
2469 /* Now that we know which path is the bestpath see if any of the other
2470 * paths
2471 * qualify as multipaths
2472 */
2473 if (debug) {
2474 if (new_select)
2475 bgp_path_info_path_with_addpath_rx_str(
2476 new_select, path_buf, sizeof(path_buf));
2477 else
2478 snprintf(path_buf, sizeof(path_buf), "NONE");
2479 zlog_debug(
2480 "%pBD: After path selection, newbest is %s oldbest was %s",
2481 dest, path_buf,
2482 old_select ? old_select->peer->host : "NONE");
2483 }
2484
2485 if (do_mpath && new_select) {
2486 for (pi = bgp_dest_get_bgp_path_info(dest);
2487 (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
2488
2489 if (debug)
2490 bgp_path_info_path_with_addpath_rx_str(
2491 pi, path_buf, sizeof(path_buf));
2492
2493 if (pi == new_select) {
2494 if (debug)
2495 zlog_debug(
2496 "%pBD: %s is the bestpath, add to the multipath list",
2497 dest, path_buf);
2498 bgp_mp_list_add(&mp_list, pi);
2499 continue;
2500 }
2501
2502 if (BGP_PATH_HOLDDOWN(pi))
2503 continue;
2504
2505 if (pi->peer && pi->peer != bgp->peer_self
2506 && !CHECK_FLAG(pi->peer->sflags,
2507 PEER_STATUS_NSF_WAIT))
2508 if (!peer_established(pi->peer))
2509 continue;
2510
2511 if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
2512 if (debug)
2513 zlog_debug(
2514 "%pBD: %s has the same nexthop as the bestpath, skip it",
2515 dest, path_buf);
2516 continue;
2517 }
2518
2519 bgp_path_info_cmp(bgp, pi, new_select, &paths_eq,
2520 mpath_cfg, debug, pfx_buf, afi, safi,
2521 &dest->reason);
2522
2523 if (paths_eq) {
2524 if (debug)
2525 zlog_debug(
2526 "%pBD: %s is equivalent to the bestpath, add to the multipath list",
2527 dest, path_buf);
2528 bgp_mp_list_add(&mp_list, pi);
2529 }
2530 }
2531 }
2532
2533 bgp_path_info_mpath_update(dest, new_select, old_select, &mp_list,
2534 mpath_cfg);
2535 bgp_path_info_mpath_aggregate_update(new_select, old_select);
2536 bgp_mp_list_clear(&mp_list);
2537
2538 bgp_addpath_update_ids(bgp, dest, afi, safi);
2539
2540 result->old = old_select;
2541 result->new = new_select;
2542
2543 return;
2544 }
2545
2546 /*
2547 * A new route/change in bestpath of an existing route. Evaluate the path
2548 * for advertisement to the subgroup.
2549 */
2550 void subgroup_process_announce_selected(struct update_subgroup *subgrp,
2551 struct bgp_path_info *selected,
2552 struct bgp_dest *dest,
2553 uint32_t addpath_tx_id)
2554 {
2555 const struct prefix *p;
2556 struct peer *onlypeer;
2557 struct attr attr;
2558 afi_t afi;
2559 safi_t safi;
2560 struct bgp *bgp;
2561 bool advertise;
2562
2563 p = bgp_dest_get_prefix(dest);
2564 afi = SUBGRP_AFI(subgrp);
2565 safi = SUBGRP_SAFI(subgrp);
2566 bgp = SUBGRP_INST(subgrp);
2567 onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
2568 : NULL);
2569
2570 if (BGP_DEBUG(update, UPDATE_OUT))
2571 zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
2572
2573 /* First update is deferred until ORF or ROUTE-REFRESH is received */
2574 if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
2575 PEER_STATUS_ORF_WAIT_REFRESH))
2576 return;
2577
2578 memset(&attr, 0, sizeof(struct attr));
2579 /* It's initialized in bgp_announce_check() */
2580
2581 /* Announcement to the subgroup. If the route is filtered withdraw it.
2582 * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
2583 * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
2584 * route
2585 */
2586 advertise = bgp_check_advertise(bgp, dest);
2587
2588 if (selected) {
2589 if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
2590 false)) {
2591 /* Route is selected, if the route is already installed
2592 * in FIB, then it is advertised
2593 */
2594 if (advertise)
2595 bgp_adj_out_set_subgroup(dest, subgrp, &attr,
2596 selected);
2597 } else
2598 bgp_adj_out_unset_subgroup(dest, subgrp, 1,
2599 addpath_tx_id);
2600 }
2601
2602 /* If selected is NULL we must withdraw the path using addpath_tx_id */
2603 else {
2604 bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id);
2605 }
2606 }
2607
2608 /*
2609 * Clear IGP changed flag and attribute changed flag for a route (all paths).
2610 * This is called at the end of route processing.
2611 */
2612 void bgp_zebra_clear_route_change_flags(struct bgp_dest *dest)
2613 {
2614 struct bgp_path_info *pi;
2615
2616 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
2617 if (BGP_PATH_HOLDDOWN(pi))
2618 continue;
2619 UNSET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
2620 UNSET_FLAG(pi->flags, BGP_PATH_ATTR_CHANGED);
2621 }
2622 }
2623
2624 /*
2625 * Has the route changed from the RIB's perspective? This is invoked only
2626 * if the route selection returns the same best route as earlier - to
2627 * determine if we need to update zebra or not.
2628 */
2629 bool bgp_zebra_has_route_changed(struct bgp_path_info *selected)
2630 {
2631 struct bgp_path_info *mpinfo;
2632
2633 /* If this is multipath, check all selected paths for any nexthop
2634 * change or attribute change. Some attribute changes (e.g., community)
2635 * aren't of relevance to the RIB, but we'll update zebra to ensure
2636 * we handle the case of BGP nexthop change. This is the behavior
2637 * when the best path has an attribute change anyway.
2638 */
2639 if (CHECK_FLAG(selected->flags, BGP_PATH_IGP_CHANGED)
2640 || CHECK_FLAG(selected->flags, BGP_PATH_MULTIPATH_CHG)
2641 || CHECK_FLAG(selected->flags, BGP_PATH_LINK_BW_CHG))
2642 return true;
2643
2644 /*
2645 * If this is multipath, check all selected paths for any nexthop change
2646 */
2647 for (mpinfo = bgp_path_info_mpath_first(selected); mpinfo;
2648 mpinfo = bgp_path_info_mpath_next(mpinfo)) {
2649 if (CHECK_FLAG(mpinfo->flags, BGP_PATH_IGP_CHANGED)
2650 || CHECK_FLAG(mpinfo->flags, BGP_PATH_ATTR_CHANGED))
2651 return true;
2652 }
2653
2654 /* Nothing has changed from the RIB's perspective. */
2655 return false;
2656 }
2657
2658 struct bgp_process_queue {
2659 struct bgp *bgp;
2660 STAILQ_HEAD(, bgp_dest) pqueue;
2661 #define BGP_PROCESS_QUEUE_EOIU_MARKER (1 << 0)
2662 unsigned int flags;
2663 unsigned int queued;
2664 };
2665
2666 static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
2667 safi_t safi, struct bgp_dest *dest,
2668 struct bgp_path_info *new_select,
2669 struct bgp_path_info *old_select)
2670 {
2671 const struct prefix *p = bgp_dest_get_prefix(dest);
2672
2673 if ((afi != AFI_IP && afi != AFI_IP6) || (safi != SAFI_UNICAST))
2674 return;
2675
2676 if (advertise_type5_routes(bgp, afi) && new_select
2677 && is_route_injectable_into_evpn(new_select)) {
2678
2679 /* apply the route-map */
2680 if (bgp->adv_cmd_rmap[afi][safi].map) {
2681 route_map_result_t ret;
2682 struct bgp_path_info rmap_path;
2683 struct bgp_path_info_extra rmap_path_extra;
2684 struct attr dummy_attr;
2685
2686 dummy_attr = *new_select->attr;
2687
2688 /* Fill temp path_info */
2689 prep_for_rmap_apply(&rmap_path, &rmap_path_extra, dest,
2690 new_select, new_select->peer,
2691 &dummy_attr);
2692
2693 RESET_FLAG(dummy_attr.rmap_change_flags);
2694
2695 ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
2696 p, &rmap_path);
2697
2698 if (ret == RMAP_DENYMATCH) {
2699 bgp_attr_flush(&dummy_attr);
2700 bgp_evpn_withdraw_type5_route(bgp, p, afi,
2701 safi);
2702 } else
2703 bgp_evpn_advertise_type5_route(
2704 bgp, p, &dummy_attr, afi, safi);
2705 } else {
2706 bgp_evpn_advertise_type5_route(bgp, p, new_select->attr,
2707 afi, safi);
2708 }
2709 } else if (advertise_type5_routes(bgp, afi) && old_select
2710 && is_route_injectable_into_evpn(old_select))
2711 bgp_evpn_withdraw_type5_route(bgp, p, afi, safi);
2712 }
2713
2714 /*
2715 * old_select = The old best path
2716 * new_select = the new best path
2717 *
2718 * if (!old_select && new_select)
2719 * We are sending new information on.
2720 *
2721 * if (old_select && new_select) {
2722 * if (new_select != old_select)
2723 * We have a new best path send a change
2724 * else
2725 * We've received a update with new attributes that needs
2726 * to be passed on.
2727 * }
2728 *
2729 * if (old_select && !new_select)
2730 * We have no eligible route that we can announce or the rn
2731 * is being removed.
2732 */
2733 static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
2734 afi_t afi, safi_t safi)
2735 {
2736 struct bgp_path_info *new_select;
2737 struct bgp_path_info *old_select;
2738 struct bgp_path_info_pair old_and_new;
2739 int debug = 0;
2740
2741 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) {
2742 if (dest)
2743 debug = bgp_debug_bestpath(dest);
2744 if (debug)
2745 zlog_debug(
2746 "%s: bgp delete in progress, ignoring event, p=%pBD",
2747 __func__, dest);
2748 return;
2749 }
2750 /* Is it end of initial update? (after startup) */
2751 if (!dest) {
2752 quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
2753 sizeof(bgp->update_delay_zebra_resume_time));
2754
2755 bgp->main_zebra_update_hold = 0;
2756 FOREACH_AFI_SAFI (afi, safi) {
2757 if (bgp_fibupd_safi(safi))
2758 bgp_zebra_announce_table(bgp, afi, safi);
2759 }
2760 bgp->main_peers_update_hold = 0;
2761
2762 bgp_start_routeadv(bgp);
2763 return;
2764 }
2765
2766 const struct prefix *p = bgp_dest_get_prefix(dest);
2767
2768 debug = bgp_debug_bestpath(dest);
2769 if (debug)
2770 zlog_debug("%s: p=%pBD afi=%s, safi=%s start", __func__, dest,
2771 afi2str(afi), safi2str(safi));
2772
2773 /* The best path calculation for the route is deferred if
2774 * BGP_NODE_SELECT_DEFER is set
2775 */
2776 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
2777 if (BGP_DEBUG(update, UPDATE_OUT))
2778 zlog_debug("SELECT_DEFER flag set for route %p", dest);
2779 return;
2780 }
2781
2782 /* Best path selection. */
2783 bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
2784 afi, safi);
2785 old_select = old_and_new.old;
2786 new_select = old_and_new.new;
2787
2788 /* Do we need to allocate or free labels?
2789 * Right now, since we only deal with per-prefix labels, it is not
2790 * necessary to do this upon changes to best path. Exceptions:
2791 * - label index has changed -> recalculate resulting label
2792 * - path_info sub_type changed -> switch to/from implicit-null
2793 * - no valid label (due to removed static label binding) -> get new one
2794 */
2795 if (bgp->allocate_mpls_labels[afi][safi]) {
2796 if (new_select) {
2797 if (!old_select
2798 || bgp_label_index_differs(new_select, old_select)
2799 || new_select->sub_type != old_select->sub_type
2800 || !bgp_is_valid_label(&dest->local_label)) {
2801 /* Enforced penultimate hop popping:
2802 * implicit-null for local routes, aggregate
2803 * and redistributed routes
2804 */
2805 if (new_select->sub_type == BGP_ROUTE_STATIC
2806 || new_select->sub_type
2807 == BGP_ROUTE_AGGREGATE
2808 || new_select->sub_type
2809 == BGP_ROUTE_REDISTRIBUTE) {
2810 if (CHECK_FLAG(
2811 dest->flags,
2812 BGP_NODE_REGISTERED_FOR_LABEL)
2813 || CHECK_FLAG(
2814 dest->flags,
2815 BGP_NODE_LABEL_REQUESTED))
2816 bgp_unregister_for_label(dest);
2817 label_ntop(MPLS_LABEL_IMPLICIT_NULL, 1,
2818 &dest->local_label);
2819 bgp_set_valid_label(&dest->local_label);
2820 } else
2821 bgp_register_for_label(dest,
2822 new_select);
2823 }
2824 } else if (CHECK_FLAG(dest->flags,
2825 BGP_NODE_REGISTERED_FOR_LABEL)
2826 || CHECK_FLAG(dest->flags,
2827 BGP_NODE_LABEL_REQUESTED)) {
2828 bgp_unregister_for_label(dest);
2829 }
2830 } else if (CHECK_FLAG(dest->flags, BGP_NODE_REGISTERED_FOR_LABEL)
2831 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_REQUESTED)) {
2832 bgp_unregister_for_label(dest);
2833 }
2834
2835 if (debug)
2836 zlog_debug(
2837 "%s: p=%pBD afi=%s, safi=%s, old_select=%p, new_select=%p",
2838 __func__, dest, afi2str(afi), safi2str(safi),
2839 old_select, new_select);
2840
2841 /* If best route remains the same and this is not due to user-initiated
2842 * clear, see exactly what needs to be done.
2843 */
2844 if (old_select && old_select == new_select
2845 && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
2846 && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2847 && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
2848 if (bgp_zebra_has_route_changed(old_select)) {
2849 #ifdef ENABLE_BGP_VNC
2850 vnc_import_bgp_add_route(bgp, p, old_select);
2851 vnc_import_bgp_exterior_add_route(bgp, p, old_select);
2852 #endif
2853 if (bgp_fibupd_safi(safi)
2854 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2855
2856 if (new_select->type == ZEBRA_ROUTE_BGP
2857 && (new_select->sub_type == BGP_ROUTE_NORMAL
2858 || new_select->sub_type
2859 == BGP_ROUTE_IMPORTED))
2860
2861 bgp_zebra_announce(dest, p, old_select,
2862 bgp, afi, safi);
2863 }
2864 }
2865
2866 /* If there is a change of interest to peers, reannounce the
2867 * route. */
2868 if (CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
2869 || CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2870 || CHECK_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED)) {
2871 group_announce_route(bgp, afi, safi, dest, new_select);
2872
2873 /* unicast routes must also be annouced to
2874 * labeled-unicast update-groups */
2875 if (safi == SAFI_UNICAST)
2876 group_announce_route(bgp, afi,
2877 SAFI_LABELED_UNICAST, dest,
2878 new_select);
2879
2880 UNSET_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED);
2881 UNSET_FLAG(dest->flags, BGP_NODE_LABEL_CHANGED);
2882 }
2883
2884 /* advertise/withdraw type-5 routes */
2885 if (CHECK_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG)
2886 || CHECK_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG))
2887 bgp_process_evpn_route_injection(
2888 bgp, afi, safi, dest, old_select, old_select);
2889
2890 UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
2891 UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
2892 bgp_zebra_clear_route_change_flags(dest);
2893 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2894 return;
2895 }
2896
2897 /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
2898 */
2899 UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
2900
2901 /* bestpath has changed; bump version */
2902 if (old_select || new_select) {
2903 bgp_bump_version(dest);
2904
2905 if (!bgp->t_rmap_def_originate_eval) {
2906 bgp_lock(bgp);
2907 thread_add_timer(
2908 bm->master,
2909 update_group_refresh_default_originate_route_map,
2910 bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER,
2911 &bgp->t_rmap_def_originate_eval);
2912 }
2913 }
2914
2915 if (old_select)
2916 bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
2917 if (new_select) {
2918 if (debug)
2919 zlog_debug("%s: setting SELECTED flag", __func__);
2920 bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
2921 bgp_path_info_unset_flag(dest, new_select,
2922 BGP_PATH_ATTR_CHANGED);
2923 UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
2924 UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
2925 }
2926
2927 #ifdef ENABLE_BGP_VNC
2928 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
2929 if (old_select != new_select) {
2930 if (old_select) {
2931 vnc_import_bgp_exterior_del_route(bgp, p,
2932 old_select);
2933 vnc_import_bgp_del_route(bgp, p, old_select);
2934 }
2935 if (new_select) {
2936 vnc_import_bgp_exterior_add_route(bgp, p,
2937 new_select);
2938 vnc_import_bgp_add_route(bgp, p, new_select);
2939 }
2940 }
2941 }
2942 #endif
2943
2944 group_announce_route(bgp, afi, safi, dest, new_select);
2945
2946 /* unicast routes must also be annouced to labeled-unicast update-groups
2947 */
2948 if (safi == SAFI_UNICAST)
2949 group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest,
2950 new_select);
2951
2952 /* FIB update. */
2953 if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
2954 && !bgp_option_check(BGP_OPT_NO_FIB)) {
2955 if (new_select && new_select->type == ZEBRA_ROUTE_BGP
2956 && (new_select->sub_type == BGP_ROUTE_NORMAL
2957 || new_select->sub_type == BGP_ROUTE_AGGREGATE
2958 || new_select->sub_type == BGP_ROUTE_IMPORTED)) {
2959
2960 /* if this is an evpn imported type-5 prefix,
2961 * we need to withdraw the route first to clear
2962 * the nh neigh and the RMAC entry.
2963 */
2964 if (old_select &&
2965 is_route_parent_evpn(old_select))
2966 bgp_zebra_withdraw(p, old_select, bgp, safi);
2967
2968 bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
2969 } else {
2970 /* Withdraw the route from the kernel. */
2971 if (old_select && old_select->type == ZEBRA_ROUTE_BGP
2972 && (old_select->sub_type == BGP_ROUTE_NORMAL
2973 || old_select->sub_type == BGP_ROUTE_AGGREGATE
2974 || old_select->sub_type == BGP_ROUTE_IMPORTED))
2975
2976 bgp_zebra_withdraw(p, old_select, bgp, safi);
2977 }
2978 }
2979
2980 bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select,
2981 old_select);
2982
2983 /* Clear any route change flags. */
2984 bgp_zebra_clear_route_change_flags(dest);
2985
2986 /* Reap old select bgp_path_info, if it has been removed */
2987 if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
2988 bgp_path_info_reap(dest, old_select);
2989
2990 UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
2991 return;
2992 }
2993
2994 /* Process the routes with the flag BGP_NODE_SELECT_DEFER set */
2995 int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
2996 {
2997 struct bgp_dest *dest;
2998 int cnt = 0;
2999 struct afi_safi_info *thread_info;
3000
3001 if (bgp->gr_info[afi][safi].t_route_select) {
3002 struct thread *t = bgp->gr_info[afi][safi].t_route_select;
3003
3004 thread_info = THREAD_ARG(t);
3005 XFREE(MTYPE_TMP, thread_info);
3006 BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
3007 }
3008
3009 if (BGP_DEBUG(update, UPDATE_OUT)) {
3010 zlog_debug("%s: processing route for %s : cnt %d", __func__,
3011 get_afi_safi_str(afi, safi, false),
3012 bgp->gr_info[afi][safi].gr_deferred);
3013 }
3014
3015 /* Process the route list */
3016 for (dest = bgp_table_top(bgp->rib[afi][safi]);
3017 dest && bgp->gr_info[afi][safi].gr_deferred != 0;
3018 dest = bgp_route_next(dest)) {
3019 if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
3020 continue;
3021
3022 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3023 bgp->gr_info[afi][safi].gr_deferred--;
3024 bgp_process_main_one(bgp, dest, afi, safi);
3025 cnt++;
3026 if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) {
3027 bgp_dest_unlock_node(dest);
3028 break;
3029 }
3030 }
3031
3032 /* Send EOR message when all routes are processed */
3033 if (!bgp->gr_info[afi][safi].gr_deferred) {
3034 bgp_send_delayed_eor(bgp);
3035 /* Send route processing complete message to RIB */
3036 bgp_zebra_update(afi, safi, bgp->vrf_id,
3037 ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE);
3038 return 0;
3039 }
3040
3041 thread_info = XMALLOC(MTYPE_TMP, sizeof(struct afi_safi_info));
3042
3043 thread_info->afi = afi;
3044 thread_info->safi = safi;
3045 thread_info->bgp = bgp;
3046
3047 /* If there are more routes to be processed, start the
3048 * selection timer
3049 */
3050 thread_add_timer(bm->master, bgp_route_select_timer_expire, thread_info,
3051 BGP_ROUTE_SELECT_DELAY,
3052 &bgp->gr_info[afi][safi].t_route_select);
3053 return 0;
3054 }
3055
3056 static wq_item_status bgp_process_wq(struct work_queue *wq, void *data)
3057 {
3058 struct bgp_process_queue *pqnode = data;
3059 struct bgp *bgp = pqnode->bgp;
3060 struct bgp_table *table;
3061 struct bgp_dest *dest;
3062
3063 /* eoiu marker */
3064 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)) {
3065 bgp_process_main_one(bgp, NULL, 0, 0);
3066 /* should always have dedicated wq call */
3067 assert(STAILQ_FIRST(&pqnode->pqueue) == NULL);
3068 return WQ_SUCCESS;
3069 }
3070
3071 while (!STAILQ_EMPTY(&pqnode->pqueue)) {
3072 dest = STAILQ_FIRST(&pqnode->pqueue);
3073 STAILQ_REMOVE_HEAD(&pqnode->pqueue, pq);
3074 STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
3075 table = bgp_dest_table(dest);
3076 /* note, new DESTs may be added as part of processing */
3077 bgp_process_main_one(bgp, dest, table->afi, table->safi);
3078
3079 bgp_dest_unlock_node(dest);
3080 bgp_table_unlock(table);
3081 }
3082
3083 return WQ_SUCCESS;
3084 }
3085
3086 static void bgp_processq_del(struct work_queue *wq, void *data)
3087 {
3088 struct bgp_process_queue *pqnode = data;
3089
3090 bgp_unlock(pqnode->bgp);
3091
3092 XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
3093 }
3094
3095 void bgp_process_queue_init(struct bgp *bgp)
3096 {
3097 if (!bgp->process_queue) {
3098 char name[BUFSIZ];
3099
3100 snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
3101 bgp->process_queue = work_queue_new(bm->master, name);
3102 }
3103
3104 bgp->process_queue->spec.workfunc = &bgp_process_wq;
3105 bgp->process_queue->spec.del_item_data = &bgp_processq_del;
3106 bgp->process_queue->spec.max_retries = 0;
3107 bgp->process_queue->spec.hold = 50;
3108 /* Use a higher yield value of 50ms for main queue processing */
3109 bgp->process_queue->spec.yield = 50 * 1000L;
3110 }
3111
3112 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
3113 {
3114 struct bgp_process_queue *pqnode;
3115
3116 pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
3117 sizeof(struct bgp_process_queue));
3118
3119 /* unlocked in bgp_processq_del */
3120 pqnode->bgp = bgp_lock(bgp);
3121 STAILQ_INIT(&pqnode->pqueue);
3122
3123 return pqnode;
3124 }
3125
3126 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
3127 {
3128 #define ARBITRARY_PROCESS_QLEN 10000
3129 struct work_queue *wq = bgp->process_queue;
3130 struct bgp_process_queue *pqnode;
3131 int pqnode_reuse = 0;
3132
3133 /* already scheduled for processing? */
3134 if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED))
3135 return;
3136
3137 /* If the flag BGP_NODE_SELECT_DEFER is set, do not add route to
3138 * the workqueue
3139 */
3140 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3141 if (BGP_DEBUG(update, UPDATE_OUT))
3142 zlog_debug("BGP_NODE_SELECT_DEFER set for route %p",
3143 dest);
3144 return;
3145 }
3146
3147 if (CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG)) {
3148 if (BGP_DEBUG(update, UPDATE_OUT))
3149 zlog_debug(
3150 "Soft reconfigure table in progress for route %p",
3151 dest);
3152 return;
3153 }
3154
3155 if (wq == NULL)
3156 return;
3157
3158 /* Add route nodes to an existing work queue item until reaching the
3159 limit only if is from the same BGP view and it's not an EOIU marker
3160 */
3161 if (work_queue_item_count(wq)) {
3162 struct work_queue_item *item = work_queue_last_item(wq);
3163 pqnode = item->data;
3164
3165 if (CHECK_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER)
3166 || pqnode->bgp != bgp
3167 || pqnode->queued >= ARBITRARY_PROCESS_QLEN)
3168 pqnode = bgp_processq_alloc(bgp);
3169 else
3170 pqnode_reuse = 1;
3171 } else
3172 pqnode = bgp_processq_alloc(bgp);
3173 /* all unlocked in bgp_process_wq */
3174 bgp_table_lock(bgp_dest_table(dest));
3175
3176 SET_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED);
3177 bgp_dest_lock_node(dest);
3178
3179 /* can't be enqueued twice */
3180 assert(STAILQ_NEXT(dest, pq) == NULL);
3181 STAILQ_INSERT_TAIL(&pqnode->pqueue, dest, pq);
3182 pqnode->queued++;
3183
3184 if (!pqnode_reuse)
3185 work_queue_add(wq, pqnode);
3186
3187 return;
3188 }
3189
3190 void bgp_add_eoiu_mark(struct bgp *bgp)
3191 {
3192 struct bgp_process_queue *pqnode;
3193
3194 if (bgp->process_queue == NULL)
3195 return;
3196
3197 pqnode = bgp_processq_alloc(bgp);
3198
3199 SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
3200 work_queue_add(bgp->process_queue, pqnode);
3201 }
3202
3203 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
3204 {
3205 struct peer *peer;
3206
3207 peer = THREAD_ARG(thread);
3208 peer->t_pmax_restart = NULL;
3209
3210 if (bgp_debug_neighbor_events(peer))
3211 zlog_debug(
3212 "%s Maximum-prefix restart timer expired, restore peering",
3213 peer->host);
3214
3215 if ((peer_clear(peer, NULL) < 0) && bgp_debug_neighbor_events(peer))
3216 zlog_debug("%s: %s peer_clear failed", __func__, peer->host);
3217
3218 return 0;
3219 }
3220
3221 static uint32_t bgp_filtered_routes_count(struct peer *peer, afi_t afi,
3222 safi_t safi)
3223 {
3224 uint32_t count = 0;
3225 bool filtered = false;
3226 struct bgp_dest *dest;
3227 struct bgp_adj_in *ain;
3228 struct attr attr = {};
3229 struct bgp_table *table = peer->bgp->rib[afi][safi];
3230
3231 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
3232 for (ain = dest->adj_in; ain; ain = ain->next) {
3233 const struct prefix *rn_p = bgp_dest_get_prefix(dest);
3234
3235 attr = *ain->attr;
3236
3237 if (bgp_input_filter(peer, rn_p, &attr, afi, safi)
3238 == FILTER_DENY)
3239 filtered = true;
3240
3241 if (bgp_input_modifier(
3242 peer, rn_p, &attr, afi, safi,
3243 ROUTE_MAP_IN_NAME(&peer->filter[afi][safi]),
3244 NULL, 0, NULL)
3245 == RMAP_DENY)
3246 filtered = true;
3247
3248 if (filtered)
3249 count++;
3250
3251 bgp_attr_undup(&attr, ain->attr);
3252 }
3253 }
3254
3255 return count;
3256 }
3257
3258 bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
3259 int always)
3260 {
3261 iana_afi_t pkt_afi;
3262 iana_safi_t pkt_safi;
3263 uint32_t pcount = (CHECK_FLAG(peer->af_flags[afi][safi],
3264 PEER_FLAG_MAX_PREFIX_FORCE))
3265 ? bgp_filtered_routes_count(peer, afi, safi)
3266 + peer->pcount[afi][safi]
3267 : peer->pcount[afi][safi];
3268
3269 if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
3270 return false;
3271
3272 if (pcount > peer->pmax[afi][safi]) {
3273 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3274 PEER_STATUS_PREFIX_LIMIT)
3275 && !always)
3276 return false;
3277
3278 zlog_info(
3279 "%%MAXPFXEXCEED: No. of %s prefix received from %s %u exceed, limit %u",
3280 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3281 peer->pmax[afi][safi]);
3282 SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
3283
3284 if (CHECK_FLAG(peer->af_flags[afi][safi],
3285 PEER_FLAG_MAX_PREFIX_WARNING))
3286 return false;
3287
3288 /* Convert AFI, SAFI to values for packet. */
3289 pkt_afi = afi_int2iana(afi);
3290 pkt_safi = safi_int2iana(safi);
3291 {
3292 uint8_t ndata[7];
3293
3294 ndata[0] = (pkt_afi >> 8);
3295 ndata[1] = pkt_afi;
3296 ndata[2] = pkt_safi;
3297 ndata[3] = (peer->pmax[afi][safi] >> 24);
3298 ndata[4] = (peer->pmax[afi][safi] >> 16);
3299 ndata[5] = (peer->pmax[afi][safi] >> 8);
3300 ndata[6] = (peer->pmax[afi][safi]);
3301
3302 SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
3303 bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
3304 BGP_NOTIFY_CEASE_MAX_PREFIX,
3305 ndata, 7);
3306 }
3307
3308 /* Dynamic peers will just close their connection. */
3309 if (peer_dynamic_neighbor(peer))
3310 return true;
3311
3312 /* restart timer start */
3313 if (peer->pmax_restart[afi][safi]) {
3314 peer->v_pmax_restart =
3315 peer->pmax_restart[afi][safi] * 60;
3316
3317 if (bgp_debug_neighbor_events(peer))
3318 zlog_debug(
3319 "%s Maximum-prefix restart timer started for %d secs",
3320 peer->host, peer->v_pmax_restart);
3321
3322 BGP_TIMER_ON(peer->t_pmax_restart,
3323 bgp_maximum_prefix_restart_timer,
3324 peer->v_pmax_restart);
3325 }
3326
3327 return true;
3328 } else
3329 UNSET_FLAG(peer->af_sflags[afi][safi],
3330 PEER_STATUS_PREFIX_LIMIT);
3331
3332 if (pcount
3333 > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
3334 if (CHECK_FLAG(peer->af_sflags[afi][safi],
3335 PEER_STATUS_PREFIX_THRESHOLD)
3336 && !always)
3337 return false;
3338
3339 zlog_info(
3340 "%%MAXPFX: No. of %s prefix received from %s reaches %u, max %u",
3341 get_afi_safi_str(afi, safi, false), peer->host, pcount,
3342 peer->pmax[afi][safi]);
3343 SET_FLAG(peer->af_sflags[afi][safi],
3344 PEER_STATUS_PREFIX_THRESHOLD);
3345 } else
3346 UNSET_FLAG(peer->af_sflags[afi][safi],
3347 PEER_STATUS_PREFIX_THRESHOLD);
3348 return false;
3349 }
3350
3351 /* Unconditionally remove the route from the RIB, without taking
3352 * damping into consideration (eg, because the session went down)
3353 */
3354 void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
3355 struct peer *peer, afi_t afi, safi_t safi)
3356 {
3357
3358 struct bgp *bgp = NULL;
3359 bool delete_route = false;
3360
3361 bgp_aggregate_decrement(peer->bgp, bgp_dest_get_prefix(dest), pi, afi,
3362 safi);
3363
3364 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3365 bgp_path_info_delete(dest, pi); /* keep historical info */
3366
3367 /* If the selected path is removed, reset BGP_NODE_SELECT_DEFER
3368 * flag
3369 */
3370 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3371 delete_route = true;
3372 else if (bgp_dest_set_defer_flag(dest, true) < 0)
3373 delete_route = true;
3374 if (delete_route) {
3375 if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
3376 UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
3377 bgp = pi->peer->bgp;
3378 bgp->gr_info[afi][safi].gr_deferred--;
3379 }
3380 }
3381 }
3382
3383 hook_call(bgp_process, peer->bgp, afi, safi, dest, peer, true);
3384 bgp_process(peer->bgp, dest, afi, safi);
3385 }
3386
3387 static void bgp_rib_withdraw(struct bgp_dest *dest, struct bgp_path_info *pi,
3388 struct peer *peer, afi_t afi, safi_t safi,
3389 struct prefix_rd *prd)
3390 {
3391 const struct prefix *p = bgp_dest_get_prefix(dest);
3392
3393 /* apply dampening, if result is suppressed, we'll be retaining
3394 * the bgp_path_info in the RIB for historical reference.
3395 */
3396 if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3397 && peer->sort == BGP_PEER_EBGP)
3398 if ((bgp_damp_withdraw(pi, dest, afi, safi, 0))
3399 == BGP_DAMP_SUPPRESSED) {
3400 bgp_aggregate_decrement(peer->bgp, p, pi, afi,
3401 safi);
3402 return;
3403 }
3404
3405 #ifdef ENABLE_BGP_VNC
3406 if (safi == SAFI_MPLS_VPN) {
3407 struct bgp_dest *pdest = NULL;
3408 struct bgp_table *table = NULL;
3409
3410 pdest = bgp_node_get(peer->bgp->rib[afi][safi],
3411 (struct prefix *)prd);
3412 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3413 table = bgp_dest_get_bgp_table_info(pdest);
3414
3415 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3416 peer->bgp, prd, table, p, pi);
3417 }
3418 bgp_dest_unlock_node(pdest);
3419 }
3420 if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
3421 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3422
3423 vnc_import_bgp_del_route(peer->bgp, p, pi);
3424 vnc_import_bgp_exterior_del_route(peer->bgp, p, pi);
3425 }
3426 }
3427 #endif
3428
3429 /* If this is an EVPN route, process for un-import. */
3430 if (safi == SAFI_EVPN)
3431 bgp_evpn_unimport_route(peer->bgp, afi, safi, p, pi);
3432
3433 bgp_rib_remove(dest, pi, peer, afi, safi);
3434 }
3435
3436 struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance,
3437 struct peer *peer, struct attr *attr,
3438 struct bgp_dest *dest)
3439 {
3440 struct bgp_path_info *new;
3441
3442 /* Make new BGP info. */
3443 new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_path_info));
3444 new->type = type;
3445 new->instance = instance;
3446 new->sub_type = sub_type;
3447 new->peer = peer;
3448 new->attr = attr;
3449 new->uptime = bgp_clock();
3450 new->net = dest;
3451 return new;
3452 }
3453
3454 static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
3455 union gw_addr *gw_ip)
3456 {
3457 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(path->attr);
3458 union gw_addr path_gw_ip, *path_gw_ip_remote;
3459 union {
3460 esi_t esi;
3461 union gw_addr ip;
3462 } temp;
3463
3464 if (afi != AFI_L2VPN)
3465 return true;
3466
3467 path_gw_ip = eo->gw_ip;
3468
3469 if (gw_ip == NULL) {
3470 memset(&temp, 0, sizeof(temp));
3471 path_gw_ip_remote = &temp.ip;
3472 } else
3473 path_gw_ip_remote = gw_ip;
3474
3475 return !!memcmp(&path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
3476 }
3477
3478 /* Check if received nexthop is valid or not. */
3479 bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
3480 uint8_t type, uint8_t stype, struct attr *attr,
3481 struct bgp_dest *dest)
3482 {
3483 bool ret = false;
3484 bool is_bgp_static_route =
3485 (type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
3486 : false;
3487
3488 /*
3489 * Only validated for unicast and multicast currently.
3490 * Also valid for EVPN where the nexthop is an IP address.
3491 * If we are a bgp static route being checked then there is
3492 * no need to check to see if the nexthop is martian as
3493 * that it should be ok.
3494 */
3495 if (is_bgp_static_route ||
3496 (safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
3497 return false;
3498
3499 /* If NEXT_HOP is present, validate it. */
3500 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
3501 if (attr->nexthop.s_addr == INADDR_ANY
3502 || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
3503 || bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
3504 return true;
3505 }
3506
3507 /* If MP_NEXTHOP is present, validate it. */
3508 /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
3509 * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
3510 * it is not an IPv6 link-local address.
3511 *
3512 * If we receive an UPDATE with nexthop length set to 32 bytes
3513 * we shouldn't discard an UPDATE if it's set to (::).
3514 * The link-local (2st) is validated along the code path later.
3515 */
3516 if (attr->mp_nexthop_len) {
3517 switch (attr->mp_nexthop_len) {
3518 case BGP_ATTR_NHLEN_IPV4:
3519 case BGP_ATTR_NHLEN_VPNV4:
3520 ret = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY
3521 || IPV4_CLASS_DE(
3522 ntohl(attr->mp_nexthop_global_in.s_addr))
3523 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3524 dest));
3525 break;
3526
3527 case BGP_ATTR_NHLEN_IPV6_GLOBAL:
3528 case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
3529 ret = (IN6_IS_ADDR_UNSPECIFIED(
3530 &attr->mp_nexthop_global)
3531 || IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3532 || IN6_IS_ADDR_MULTICAST(
3533 &attr->mp_nexthop_global)
3534 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3535 dest));
3536 break;
3537 case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
3538 ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
3539 || IN6_IS_ADDR_MULTICAST(
3540 &attr->mp_nexthop_global)
3541 || bgp_nexthop_self(bgp, afi, type, stype, attr,
3542 dest));
3543 break;
3544
3545 default:
3546 ret = true;
3547 break;
3548 }
3549 }
3550
3551 return ret;
3552 }
3553
3554 static void bgp_attr_add_no_export_community(struct attr *attr)
3555 {
3556 struct community *old;
3557 struct community *new;
3558 struct community *merge;
3559 struct community *no_export;
3560
3561 old = attr->community;
3562 no_export = community_str2com("no-export");
3563
3564 assert(no_export);
3565
3566 if (old) {
3567 merge = community_merge(community_dup(old), no_export);
3568
3569 if (!old->refcnt)
3570 community_free(&old);
3571
3572 new = community_uniq_sort(merge);
3573 community_free(&merge);
3574 } else {
3575 new = community_dup(no_export);
3576 }
3577
3578 community_free(&no_export);
3579
3580 attr->community = new;
3581 attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
3582 }
3583
3584 int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
3585 struct attr *attr, afi_t afi, safi_t safi, int type,
3586 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
3587 uint32_t num_labels, int soft_reconfig,
3588 struct bgp_route_evpn *evpn)
3589 {
3590 int ret;
3591 int aspath_loop_count = 0;
3592 struct bgp_dest *dest;
3593 struct bgp *bgp;
3594 struct attr new_attr;
3595 struct attr *attr_new;
3596 struct bgp_path_info *pi;
3597 struct bgp_path_info *new;
3598 struct bgp_path_info_extra *extra;
3599 const char *reason;
3600 char pfx_buf[BGP_PRD_PATH_STRLEN];
3601 int connected = 0;
3602 int do_loop_check = 1;
3603 int has_valid_label = 0;
3604 afi_t nh_afi;
3605 uint8_t pi_type = 0;
3606 uint8_t pi_sub_type = 0;
3607 bool force_evpn_import = false;
3608
3609 if (frrtrace_enabled(frr_bgp, process_update)) {
3610 char pfxprint[PREFIX2STR_BUFFER];
3611
3612 prefix2str(p, pfxprint, sizeof(pfxprint));
3613 frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
3614 afi, safi, attr);
3615 }
3616
3617 #ifdef ENABLE_BGP_VNC
3618 int vnc_implicit_withdraw = 0;
3619 #endif
3620 int same_attr = 0;
3621
3622 memset(&new_attr, 0, sizeof(struct attr));
3623 new_attr.label_index = BGP_INVALID_LABEL_INDEX;
3624 new_attr.label = MPLS_INVALID_LABEL;
3625
3626 bgp = peer->bgp;
3627 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
3628 /* TODO: Check to see if we can get rid of "is_valid_label" */
3629 if (afi == AFI_L2VPN && safi == SAFI_EVPN)
3630 has_valid_label = (num_labels > 0) ? 1 : 0;
3631 else
3632 has_valid_label = bgp_is_valid_label(label);
3633
3634 if (has_valid_label)
3635 assert(label != NULL);
3636
3637 /* Update overlay index of the attribute */
3638 if (afi == AFI_L2VPN && evpn)
3639 memcpy(&attr->evpn_overlay, evpn,
3640 sizeof(struct bgp_route_evpn));
3641
3642 /* When peer's soft reconfiguration enabled. Record input packet in
3643 Adj-RIBs-In. */
3644 if (!soft_reconfig
3645 && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
3646 && peer != bgp->peer_self)
3647 bgp_adj_in_set(dest, peer, attr, addpath_id);
3648
3649 /* Check previously received route. */
3650 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
3651 if (pi->peer == peer && pi->type == type
3652 && pi->sub_type == sub_type
3653 && pi->addpath_rx_id == addpath_id)
3654 break;
3655
3656 /* AS path local-as loop check. */
3657 if (peer->change_local_as) {
3658 if (peer->allowas_in[afi][safi])
3659 aspath_loop_count = peer->allowas_in[afi][safi];
3660 else if (!CHECK_FLAG(peer->flags,
3661 PEER_FLAG_LOCAL_AS_NO_PREPEND))
3662 aspath_loop_count = 1;
3663
3664 if (aspath_loop_check(attr->aspath, peer->change_local_as)
3665 > aspath_loop_count) {
3666 peer->stat_pfx_aspath_loop++;
3667 reason = "as-path contains our own AS;";
3668 goto filtered;
3669 }
3670 }
3671
3672 /* If the peer is configured for "allowas-in origin" and the last ASN in
3673 * the
3674 * as-path is our ASN then we do not need to call aspath_loop_check
3675 */
3676 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
3677 if (aspath_get_last_as(attr->aspath) == bgp->as)
3678 do_loop_check = 0;
3679
3680 /* AS path loop check. */
3681 if (do_loop_check) {
3682 if (aspath_loop_check(attr->aspath, bgp->as)
3683 > peer->allowas_in[afi][safi]
3684 || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
3685 && aspath_loop_check(attr->aspath, bgp->confed_id)
3686 > peer->allowas_in[afi][safi])) {
3687 peer->stat_pfx_aspath_loop++;
3688 reason = "as-path contains our own AS;";
3689 goto filtered;
3690 }
3691 }
3692
3693 /* Route reflector originator ID check. */
3694 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
3695 && IPV4_ADDR_SAME(&bgp->router_id, &attr->originator_id)) {
3696 peer->stat_pfx_originator_loop++;
3697 reason = "originator is us;";
3698 goto filtered;
3699 }
3700
3701 /* Route reflector cluster ID check. */
3702 if (bgp_cluster_filter(peer, attr)) {
3703 peer->stat_pfx_cluster_loop++;
3704 reason = "reflected from the same cluster;";
3705 goto filtered;
3706 }
3707
3708 /* Apply incoming filter. */
3709 if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
3710 peer->stat_pfx_filter++;
3711 reason = "filter;";
3712 goto filtered;
3713 }
3714
3715 /* RFC 8212 to prevent route leaks.
3716 * This specification intends to improve this situation by requiring the
3717 * explicit configuration of both BGP Import and Export Policies for any
3718 * External BGP (EBGP) session such as customers, peers, or
3719 * confederation boundaries for all enabled address families. Through
3720 * codification of the aforementioned requirement, operators will
3721 * benefit from consistent behavior across different BGP
3722 * implementations.
3723 */
3724 if (CHECK_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY))
3725 if (!bgp_inbound_policy_exists(peer,
3726 &peer->filter[afi][safi])) {
3727 reason = "inbound policy missing";
3728 goto filtered;
3729 }
3730
3731 /* draft-ietf-idr-deprecate-as-set-confed-set
3732 * Filter routes having AS_SET or AS_CONFED_SET in the path.
3733 * Eventually, This document (if approved) updates RFC 4271
3734 * and RFC 5065 by eliminating AS_SET and AS_CONFED_SET types,
3735 * and obsoletes RFC 6472.
3736 */
3737 if (peer->bgp->reject_as_sets)
3738 if (aspath_check_as_sets(attr->aspath)) {
3739 reason =
3740 "as-path contains AS_SET or AS_CONFED_SET type;";
3741 goto filtered;
3742 }
3743
3744 new_attr = *attr;
3745
3746 /* Apply incoming route-map.
3747 * NB: new_attr may now contain newly allocated values from route-map
3748 * "set"
3749 * commands, so we need bgp_attr_flush in the error paths, until we
3750 * intern
3751 * the attr (which takes over the memory references) */
3752 if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL, label,
3753 num_labels, dest)
3754 == RMAP_DENY) {
3755 peer->stat_pfx_filter++;
3756 reason = "route-map;";
3757 bgp_attr_flush(&new_attr);
3758 goto filtered;
3759 }
3760
3761 if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
3762 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
3763 /* remove from RIB previous entry */
3764 bgp_zebra_withdraw(p, pi, bgp, safi);
3765 }
3766
3767 if (peer->sort == BGP_PEER_EBGP) {
3768
3769 /* rfc7999:
3770 * A BGP speaker receiving an announcement tagged with the
3771 * BLACKHOLE community SHOULD add the NO_ADVERTISE or
3772 * NO_EXPORT community as defined in RFC1997, or a
3773 * similar community, to prevent propagation of the
3774 * prefix outside the local AS. The community to prevent
3775 * propagation SHOULD be chosen according to the operator's
3776 * routing policy.
3777 */
3778 if (new_attr.community
3779 && community_include(new_attr.community,
3780 COMMUNITY_BLACKHOLE))
3781 bgp_attr_add_no_export_community(&new_attr);
3782
3783 /* If we receive the graceful-shutdown community from an eBGP
3784 * peer we must lower local-preference */
3785 if (new_attr.community
3786 && community_include(new_attr.community, COMMUNITY_GSHUT)) {
3787 new_attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
3788 new_attr.local_pref = BGP_GSHUT_LOCAL_PREF;
3789
3790 /* If graceful-shutdown is configured then add the GSHUT
3791 * community to all paths received from eBGP peers */
3792 } else if (bgp_in_graceful_shutdown(peer->bgp))
3793 bgp_attr_add_gshut_community(&new_attr);
3794 }
3795
3796 if (pi) {
3797 pi_type = pi->type;
3798 pi_sub_type = pi->sub_type;
3799 }
3800
3801 /* next hop check. */
3802 if (!CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)
3803 && bgp_update_martian_nexthop(bgp, afi, safi, pi_type, pi_sub_type,
3804 &new_attr, dest)) {
3805 peer->stat_pfx_nh_invalid++;
3806 reason = "martian or self next-hop;";
3807 bgp_attr_flush(&new_attr);
3808 goto filtered;
3809 }
3810
3811 if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
3812 peer->stat_pfx_nh_invalid++;
3813 reason = "self mac;";
3814 goto filtered;
3815 }
3816
3817 /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
3818 * condition :
3819 * Suppress fib is enabled
3820 * BGP_OPT_NO_FIB is not enabled
3821 * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
3822 * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
3823 */
3824 if (bgp_fibupd_safi(safi) && BGP_SUPPRESS_FIB_ENABLED(bgp)
3825 && (sub_type == BGP_ROUTE_NORMAL)
3826 && (!bgp_option_check(BGP_OPT_NO_FIB))
3827 && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
3828 SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
3829
3830 attr_new = bgp_attr_intern(&new_attr);
3831
3832 /* If maximum prefix count is configured and current prefix
3833 * count exeed it.
3834 */
3835 if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
3836 return -1;
3837
3838 /* If the update is implicit withdraw. */
3839 if (pi) {
3840 pi->uptime = bgp_clock();
3841 same_attr = attrhash_cmp(pi->attr, attr_new);
3842
3843 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
3844
3845 /* Same attribute comes in. */
3846 if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
3847 && same_attr
3848 && (!has_valid_label
3849 || memcmp(&(bgp_path_info_extra_get(pi))->label, label,
3850 num_labels * sizeof(mpls_label_t))
3851 == 0)) {
3852 if (CHECK_FLAG(bgp->af_flags[afi][safi],
3853 BGP_CONFIG_DAMPENING)
3854 && peer->sort == BGP_PEER_EBGP
3855 && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
3856 if (bgp_debug_update(peer, p, NULL, 1)) {
3857 bgp_debug_rdpfxpath2str(
3858 afi, safi, prd, p, label,
3859 num_labels, addpath_id ? 1 : 0,
3860 addpath_id, evpn, pfx_buf,
3861 sizeof(pfx_buf));
3862 zlog_debug("%s rcvd %s", peer->host,
3863 pfx_buf);
3864 }
3865
3866 if (bgp_damp_update(pi, dest, afi, safi)
3867 != BGP_DAMP_SUPPRESSED) {
3868 bgp_aggregate_increment(bgp, p, pi, afi,
3869 safi);
3870 bgp_process(bgp, dest, afi, safi);
3871 }
3872 } else /* Duplicate - odd */
3873 {
3874 if (bgp_debug_update(peer, p, NULL, 1)) {
3875 if (!peer->rcvd_attr_printed) {
3876 zlog_debug(
3877 "%s rcvd UPDATE w/ attr: %s",
3878 peer->host,
3879 peer->rcvd_attr_str);
3880 peer->rcvd_attr_printed = 1;
3881 }
3882
3883 bgp_debug_rdpfxpath2str(
3884 afi, safi, prd, p, label,
3885 num_labels, addpath_id ? 1 : 0,
3886 addpath_id, evpn, pfx_buf,
3887 sizeof(pfx_buf));
3888 zlog_debug(
3889 "%s rcvd %s...duplicate ignored",
3890 peer->host, pfx_buf);
3891 }
3892
3893 /* graceful restart STALE flag unset. */
3894 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3895 bgp_path_info_unset_flag(
3896 dest, pi, BGP_PATH_STALE);
3897 bgp_dest_set_defer_flag(dest, false);
3898 bgp_process(bgp, dest, afi, safi);
3899 }
3900 }
3901
3902 bgp_dest_unlock_node(dest);
3903 bgp_attr_unintern(&attr_new);
3904
3905 return 0;
3906 }
3907
3908 /* Withdraw/Announce before we fully processed the withdraw */
3909 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
3910 if (bgp_debug_update(peer, p, NULL, 1)) {
3911 bgp_debug_rdpfxpath2str(
3912 afi, safi, prd, p, label, num_labels,
3913 addpath_id ? 1 : 0, addpath_id, evpn,
3914 pfx_buf, sizeof(pfx_buf));
3915 zlog_debug(
3916 "%s rcvd %s, flapped quicker than processing",
3917 peer->host, pfx_buf);
3918 }
3919
3920 bgp_path_info_restore(dest, pi);
3921
3922 /*
3923 * If the BGP_PATH_REMOVED flag is set, then EVPN
3924 * routes would have been unimported already when a
3925 * prior BGP withdraw processing happened. Such routes
3926 * need to be imported again, so flag accordingly.
3927 */
3928 force_evpn_import = true;
3929 }
3930
3931 /* Received Logging. */
3932 if (bgp_debug_update(peer, p, NULL, 1)) {
3933 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
3934 num_labels, addpath_id ? 1 : 0,
3935 addpath_id, evpn, pfx_buf,
3936 sizeof(pfx_buf));
3937 zlog_debug("%s rcvd %s", peer->host, pfx_buf);
3938 }
3939
3940 /* graceful restart STALE flag unset. */
3941 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE)) {
3942 bgp_path_info_unset_flag(dest, pi, BGP_PATH_STALE);
3943 bgp_dest_set_defer_flag(dest, false);
3944 }
3945
3946 /* The attribute is changed. */
3947 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
3948
3949 /* implicit withdraw, decrement aggregate and pcount here.
3950 * only if update is accepted, they'll increment below.
3951 */
3952 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
3953
3954 /* Update bgp route dampening information. */
3955 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
3956 && peer->sort == BGP_PEER_EBGP) {
3957 /* This is implicit withdraw so we should update
3958 dampening
3959 information. */
3960 if (!CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
3961 bgp_damp_withdraw(pi, dest, afi, safi, 1);
3962 }
3963 #ifdef ENABLE_BGP_VNC
3964 if (safi == SAFI_MPLS_VPN) {
3965 struct bgp_dest *pdest = NULL;
3966 struct bgp_table *table = NULL;
3967
3968 pdest = bgp_node_get(bgp->rib[afi][safi],
3969 (struct prefix *)prd);
3970 if (bgp_dest_has_bgp_path_info_data(pdest)) {
3971 table = bgp_dest_get_bgp_table_info(pdest);
3972
3973 vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
3974 bgp, prd, table, p, pi);
3975 }
3976 bgp_dest_unlock_node(pdest);
3977 }
3978 if ((afi == AFI_IP || afi == AFI_IP6)
3979 && (safi == SAFI_UNICAST)) {
3980 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
3981 /*
3982 * Implicit withdraw case.
3983 */
3984 ++vnc_implicit_withdraw;
3985 vnc_import_bgp_del_route(bgp, p, pi);
3986 vnc_import_bgp_exterior_del_route(bgp, p, pi);
3987 }
3988 }
3989 #endif
3990
3991 /* Special handling for EVPN update of an existing route. If the
3992 * extended community attribute has changed, we need to
3993 * un-import
3994 * the route using its existing extended community. It will be
3995 * subsequently processed for import with the new extended
3996 * community.
3997 */
3998 if (((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN))
3999 && !same_attr) {
4000 if ((pi->attr->flag
4001 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
4002 && (attr_new->flag
4003 & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) {
4004 int cmp;
4005
4006 cmp = ecommunity_cmp(pi->attr->ecommunity,
4007 attr_new->ecommunity);
4008 if (!cmp) {
4009 if (bgp_debug_update(peer, p, NULL, 1))
4010 zlog_debug(
4011 "Change in EXT-COMM, existing %s new %s",
4012 ecommunity_str(
4013 pi->attr->ecommunity),
4014 ecommunity_str(
4015 attr_new->ecommunity));
4016 if (safi == SAFI_EVPN)
4017 bgp_evpn_unimport_route(
4018 bgp, afi, safi, p, pi);
4019 else /* SAFI_MPLS_VPN */
4020 vpn_leak_to_vrf_withdraw(bgp,
4021 pi);
4022 }
4023 }
4024 }
4025
4026 /* Update to new attribute. */
4027 bgp_attr_unintern(&pi->attr);
4028 pi->attr = attr_new;
4029
4030 /* Update MPLS label */
4031 if (has_valid_label) {
4032 extra = bgp_path_info_extra_get(pi);
4033 if (extra->label != label) {
4034 memcpy(&extra->label, label,
4035 num_labels * sizeof(mpls_label_t));
4036 extra->num_labels = num_labels;
4037 }
4038 if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
4039 bgp_set_valid_label(&extra->label[0]);
4040 }
4041
4042 /* Update SRv6 SID */
4043 if (attr->srv6_l3vpn) {
4044 extra = bgp_path_info_extra_get(pi);
4045 if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) {
4046 sid_copy(&extra->sid[0],
4047 &attr->srv6_l3vpn->sid);
4048 extra->num_sids = 1;
4049 }
4050 } else if (attr->srv6_vpn) {
4051 extra = bgp_path_info_extra_get(pi);
4052 if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) {
4053 sid_copy(&extra->sid[0], &attr->srv6_vpn->sid);
4054 extra->num_sids = 1;
4055 }
4056 }
4057
4058 #ifdef ENABLE_BGP_VNC
4059 if ((afi == AFI_IP || afi == AFI_IP6)
4060 && (safi == SAFI_UNICAST)) {
4061 if (vnc_implicit_withdraw) {
4062 /*
4063 * Add back the route with its new attributes
4064 * (e.g., nexthop).
4065 * The route is still selected, until the route
4066 * selection
4067 * queued by bgp_process actually runs. We have
4068 * to make this
4069 * update to the VNC side immediately to avoid
4070 * racing against
4071 * configuration changes (e.g., route-map
4072 * changes) which
4073 * trigger re-importation of the entire RIB.
4074 */
4075 vnc_import_bgp_add_route(bgp, p, pi);
4076 vnc_import_bgp_exterior_add_route(bgp, p, pi);
4077 }
4078 }
4079 #endif
4080
4081 /* Update bgp route dampening information. */
4082 if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
4083 && peer->sort == BGP_PEER_EBGP) {
4084 /* Now we do normal update dampening. */
4085 ret = bgp_damp_update(pi, dest, afi, safi);
4086 if (ret == BGP_DAMP_SUPPRESSED) {
4087 bgp_dest_unlock_node(dest);
4088 return 0;
4089 }
4090 }
4091
4092 /* Nexthop reachability check - for unicast and
4093 * labeled-unicast.. */
4094 if (((afi == AFI_IP || afi == AFI_IP6)
4095 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4096 || (safi == SAFI_EVPN &&
4097 bgp_evpn_is_prefix_nht_supported(p))) {
4098 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4099 && peer->ttl == BGP_DEFAULT_TTL
4100 && !CHECK_FLAG(peer->flags,
4101 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4102 && !CHECK_FLAG(bgp->flags,
4103 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4104 connected = 1;
4105 else
4106 connected = 0;
4107
4108 struct bgp *bgp_nexthop = bgp;
4109
4110 if (pi->extra && pi->extra->bgp_orig)
4111 bgp_nexthop = pi->extra->bgp_orig;
4112
4113 nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
4114
4115 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
4116 safi, pi, NULL, connected,
4117 p)
4118 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4119 bgp_path_info_set_flag(dest, pi,
4120 BGP_PATH_VALID);
4121 else {
4122 if (BGP_DEBUG(nht, NHT)) {
4123 zlog_debug("%s(%pI4): NH unresolved",
4124 __func__,
4125 (in_addr_t *)&attr_new->nexthop);
4126 }
4127 bgp_path_info_unset_flag(dest, pi,
4128 BGP_PATH_VALID);
4129 }
4130 } else
4131 bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
4132
4133 #ifdef ENABLE_BGP_VNC
4134 if (safi == SAFI_MPLS_VPN) {
4135 struct bgp_dest *pdest = NULL;
4136 struct bgp_table *table = NULL;
4137
4138 pdest = bgp_node_get(bgp->rib[afi][safi],
4139 (struct prefix *)prd);
4140 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4141 table = bgp_dest_get_bgp_table_info(pdest);
4142
4143 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4144 bgp, prd, table, p, pi);
4145 }
4146 bgp_dest_unlock_node(pdest);
4147 }
4148 #endif
4149
4150 /* If this is an EVPN route and some attribute has changed,
4151 * or we are explicitly told to perform a route import, process
4152 * route for import. If the extended community has changed, we
4153 * would
4154 * have done the un-import earlier and the import would result
4155 * in the
4156 * route getting injected into appropriate L2 VNIs. If it is
4157 * just
4158 * some other attribute change, the import will result in
4159 * updating
4160 * the attributes for the route in the VNI(s).
4161 */
4162 if (safi == SAFI_EVPN &&
4163 (!same_attr || force_evpn_import) &&
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, evpn,
4211 pfx_buf, 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 /* Nexthop reachability check. */
4243 if (((afi == AFI_IP || afi == AFI_IP6)
4244 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
4245 || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
4246 if (safi != SAFI_EVPN && peer->sort == BGP_PEER_EBGP
4247 && peer->ttl == BGP_DEFAULT_TTL
4248 && !CHECK_FLAG(peer->flags,
4249 PEER_FLAG_DISABLE_CONNECTED_CHECK)
4250 && !CHECK_FLAG(bgp->flags,
4251 BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
4252 connected = 1;
4253 else
4254 connected = 0;
4255
4256 nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
4257
4258 if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, safi, new, NULL,
4259 connected, p)
4260 || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
4261 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4262 else {
4263 if (BGP_DEBUG(nht, NHT)) {
4264 char buf1[INET6_ADDRSTRLEN];
4265 inet_ntop(AF_INET,
4266 (const void *)&attr_new->nexthop,
4267 buf1, INET6_ADDRSTRLEN);
4268 zlog_debug("%s(%s): NH unresolved", __func__,
4269 buf1);
4270 }
4271 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
4272 }
4273 } else
4274 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
4275
4276 /* Addpath ID */
4277 new->addpath_rx_id = addpath_id;
4278
4279 /* Increment prefix */
4280 bgp_aggregate_increment(bgp, p, new, afi, safi);
4281
4282 /* Register new BGP information. */
4283 bgp_path_info_add(dest, new);
4284
4285 /* route_node_get lock */
4286 bgp_dest_unlock_node(dest);
4287
4288 #ifdef ENABLE_BGP_VNC
4289 if (safi == SAFI_MPLS_VPN) {
4290 struct bgp_dest *pdest = NULL;
4291 struct bgp_table *table = NULL;
4292
4293 pdest = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
4294 if (bgp_dest_has_bgp_path_info_data(pdest)) {
4295 table = bgp_dest_get_bgp_table_info(pdest);
4296
4297 vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
4298 bgp, prd, table, p, new);
4299 }
4300 bgp_dest_unlock_node(pdest);
4301 }
4302 #endif
4303
4304 /* If this is an EVPN route, process for import. */
4305 if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
4306 bgp_evpn_import_route(bgp, afi, safi, p, new);
4307
4308 hook_call(bgp_process, bgp, afi, safi, dest, peer, false);
4309
4310 /* Process change. */
4311 bgp_process(bgp, dest, afi, safi);
4312
4313 if (SAFI_UNICAST == safi
4314 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4315 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4316 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
4317 }
4318 if ((SAFI_MPLS_VPN == safi)
4319 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4320
4321 vpn_leak_to_vrf_update(bgp, new);
4322 }
4323 #ifdef ENABLE_BGP_VNC
4324 if (SAFI_MPLS_VPN == safi) {
4325 mpls_label_t label_decoded = decode_label(label);
4326
4327 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4328 sub_type, &label_decoded);
4329 }
4330 if (SAFI_ENCAP == safi) {
4331 rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
4332 sub_type, NULL);
4333 }
4334 #endif
4335
4336 return 0;
4337
4338 /* This BGP update is filtered. Log the reason then update BGP
4339 entry. */
4340 filtered:
4341 hook_call(bgp_process, bgp, afi, safi, dest, peer, true);
4342
4343 if (bgp_debug_update(peer, p, NULL, 1)) {
4344 if (!peer->rcvd_attr_printed) {
4345 zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
4346 peer->rcvd_attr_str);
4347 peer->rcvd_attr_printed = 1;
4348 }
4349
4350 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4351 addpath_id ? 1 : 0, addpath_id, evpn,
4352 pfx_buf, sizeof(pfx_buf));
4353 zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
4354 peer->host, pfx_buf, reason);
4355 }
4356
4357 if (pi) {
4358 /* If this is an EVPN route, un-import it as it is now filtered.
4359 */
4360 if (safi == SAFI_EVPN)
4361 bgp_evpn_unimport_route(bgp, afi, safi, p, pi);
4362
4363 if (SAFI_UNICAST == safi
4364 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4365 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4366
4367 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4368 }
4369 if ((SAFI_MPLS_VPN == safi)
4370 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4371
4372 vpn_leak_to_vrf_withdraw(bgp, pi);
4373 }
4374
4375 bgp_rib_remove(dest, pi, peer, afi, safi);
4376 }
4377
4378 bgp_dest_unlock_node(dest);
4379
4380 #ifdef ENABLE_BGP_VNC
4381 /*
4382 * Filtered update is treated as an implicit withdrawal (see
4383 * bgp_rib_remove()
4384 * a few lines above)
4385 */
4386 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4387 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4388 0);
4389 }
4390 #endif
4391
4392 return 0;
4393 }
4394
4395 int bgp_withdraw(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
4396 struct attr *attr, afi_t afi, safi_t safi, int type,
4397 int sub_type, struct prefix_rd *prd, mpls_label_t *label,
4398 uint32_t num_labels, struct bgp_route_evpn *evpn)
4399 {
4400 struct bgp *bgp;
4401 char pfx_buf[BGP_PRD_PATH_STRLEN];
4402 struct bgp_dest *dest;
4403 struct bgp_path_info *pi;
4404
4405 #ifdef ENABLE_BGP_VNC
4406 if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
4407 rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
4408 0);
4409 }
4410 #endif
4411
4412 bgp = peer->bgp;
4413
4414 /* Lookup node. */
4415 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
4416
4417 /* If peer is soft reconfiguration enabled. Record input packet for
4418 * further calculation.
4419 *
4420 * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
4421 * routes that are filtered. This tanks out Quagga RS pretty badly due
4422 * to
4423 * the iteration over all RS clients.
4424 * Since we need to remove the entry from adj_in anyway, do that first
4425 * and
4426 * if there was no entry, we don't need to do anything more.
4427 */
4428 if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4429 && peer != bgp->peer_self)
4430 if (!bgp_adj_in_unset(dest, peer, addpath_id)) {
4431 peer->stat_pfx_dup_withdraw++;
4432
4433 if (bgp_debug_update(peer, p, NULL, 1)) {
4434 bgp_debug_rdpfxpath2str(
4435 afi, safi, prd, p, label, num_labels,
4436 addpath_id ? 1 : 0, addpath_id, NULL,
4437 pfx_buf, sizeof(pfx_buf));
4438 zlog_debug(
4439 "%s withdrawing route %s not in adj-in",
4440 peer->host, pfx_buf);
4441 }
4442 bgp_dest_unlock_node(dest);
4443 return 0;
4444 }
4445
4446 /* Lookup withdrawn route. */
4447 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4448 if (pi->peer == peer && pi->type == type
4449 && pi->sub_type == sub_type
4450 && pi->addpath_rx_id == addpath_id)
4451 break;
4452
4453 /* Logging. */
4454 if (bgp_debug_update(peer, p, NULL, 1)) {
4455 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4456 addpath_id ? 1 : 0, addpath_id, NULL,
4457 pfx_buf, sizeof(pfx_buf));
4458 zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
4459 pfx_buf);
4460 }
4461
4462 /* Withdraw specified route from routing table. */
4463 if (pi && !CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) {
4464 bgp_rib_withdraw(dest, pi, peer, afi, safi, prd);
4465 if (SAFI_UNICAST == safi
4466 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
4467 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4468 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
4469 }
4470 if ((SAFI_MPLS_VPN == safi)
4471 && (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4472
4473 vpn_leak_to_vrf_withdraw(bgp, pi);
4474 }
4475 } else if (bgp_debug_update(peer, p, NULL, 1)) {
4476 bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels,
4477 addpath_id ? 1 : 0, addpath_id, NULL,
4478 pfx_buf, sizeof(pfx_buf));
4479 zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
4480 }
4481
4482 /* Unlock bgp_node_get() lock. */
4483 bgp_dest_unlock_node(dest);
4484
4485 return 0;
4486 }
4487
4488 void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
4489 int withdraw)
4490 {
4491 struct update_subgroup *subgrp;
4492 subgrp = peer_subgroup(peer, afi, safi);
4493 subgroup_default_originate(subgrp, withdraw);
4494 }
4495
4496
4497 /*
4498 * bgp_stop_announce_route_timer
4499 */
4500 void bgp_stop_announce_route_timer(struct peer_af *paf)
4501 {
4502 if (!paf->t_announce_route)
4503 return;
4504
4505 thread_cancel(&paf->t_announce_route);
4506 }
4507
4508 /*
4509 * bgp_announce_route_timer_expired
4510 *
4511 * Callback that is invoked when the route announcement timer for a
4512 * peer_af expires.
4513 */
4514 static int bgp_announce_route_timer_expired(struct thread *t)
4515 {
4516 struct peer_af *paf;
4517 struct peer *peer;
4518
4519 paf = THREAD_ARG(t);
4520 peer = paf->peer;
4521
4522 if (!peer_established(peer))
4523 return 0;
4524
4525 if (!peer->afc_nego[paf->afi][paf->safi])
4526 return 0;
4527
4528 peer_af_announce_route(paf, 1);
4529
4530 /* Notify BGP conditional advertisement scanner percess */
4531 peer->advmap_config_change[paf->afi][paf->safi] = true;
4532
4533 return 0;
4534 }
4535
4536 /*
4537 * bgp_announce_route
4538 *
4539 * *Triggers* announcement of routes of a given AFI/SAFI to a peer.
4540 */
4541 void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
4542 {
4543 struct peer_af *paf;
4544 struct update_subgroup *subgrp;
4545
4546 paf = peer_af_find(peer, afi, safi);
4547 if (!paf)
4548 return;
4549 subgrp = PAF_SUBGRP(paf);
4550
4551 /*
4552 * Ignore if subgroup doesn't exist (implies AF is not negotiated)
4553 * or a refresh has already been triggered.
4554 */
4555 if (!subgrp || paf->t_announce_route)
4556 return;
4557
4558 /*
4559 * Start a timer to stagger/delay the announce. This serves
4560 * two purposes - announcement can potentially be combined for
4561 * multiple peers and the announcement doesn't happen in the
4562 * vty context.
4563 */
4564 thread_add_timer_msec(bm->master, bgp_announce_route_timer_expired, paf,
4565 (subgrp->peer_count == 1)
4566 ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
4567 : BGP_ANNOUNCE_ROUTE_DELAY_MS,
4568 &paf->t_announce_route);
4569 }
4570
4571 /*
4572 * Announce routes from all AF tables to a peer.
4573 *
4574 * This should ONLY be called when there is a need to refresh the
4575 * routes to the peer based on a policy change for this peer alone
4576 * or a route refresh request received from the peer.
4577 * The operation will result in splitting the peer from its existing
4578 * subgroups and putting it in new subgroups.
4579 */
4580 void bgp_announce_route_all(struct peer *peer)
4581 {
4582 afi_t afi;
4583 safi_t safi;
4584
4585 FOREACH_AFI_SAFI (afi, safi)
4586 bgp_announce_route(peer, afi, safi);
4587 }
4588
4589 /* Flag or unflag bgp_dest to determine whether it should be treated by
4590 * bgp_soft_reconfig_table_task.
4591 * Flag if flag is true. Unflag if flag is false.
4592 */
4593 static void bgp_soft_reconfig_table_flag(struct bgp_table *table, bool flag)
4594 {
4595 struct bgp_dest *dest;
4596 struct bgp_adj_in *ain;
4597
4598 if (!table)
4599 return;
4600
4601 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4602 for (ain = dest->adj_in; ain; ain = ain->next) {
4603 if (ain->peer != NULL)
4604 break;
4605 }
4606 if (flag && ain != NULL && ain->peer != NULL)
4607 SET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4608 else
4609 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4610 }
4611 }
4612
4613 static int bgp_soft_reconfig_table_update(struct peer *peer,
4614 struct bgp_dest *dest,
4615 struct bgp_adj_in *ain, afi_t afi,
4616 safi_t safi, struct prefix_rd *prd)
4617 {
4618 struct bgp_path_info *pi;
4619 uint32_t num_labels = 0;
4620 mpls_label_t *label_pnt = NULL;
4621 struct bgp_route_evpn evpn;
4622
4623 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
4624 if (pi->peer == peer)
4625 break;
4626
4627 if (pi && pi->extra)
4628 num_labels = pi->extra->num_labels;
4629 if (num_labels)
4630 label_pnt = &pi->extra->label[0];
4631 if (pi)
4632 memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
4633 sizeof(evpn));
4634 else
4635 memset(&evpn, 0, sizeof(evpn));
4636
4637 return bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
4638 ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
4639 BGP_ROUTE_NORMAL, prd, label_pnt, num_labels, 1,
4640 &evpn);
4641 }
4642
4643 static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
4644 struct bgp_table *table,
4645 struct prefix_rd *prd)
4646 {
4647 int ret;
4648 struct bgp_dest *dest;
4649 struct bgp_adj_in *ain;
4650
4651 if (!table)
4652 table = peer->bgp->rib[afi][safi];
4653
4654 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
4655 for (ain = dest->adj_in; ain; ain = ain->next) {
4656 if (ain->peer != peer)
4657 continue;
4658
4659 ret = bgp_soft_reconfig_table_update(peer, dest, ain,
4660 afi, safi, prd);
4661
4662 if (ret < 0) {
4663 bgp_dest_unlock_node(dest);
4664 return;
4665 }
4666 }
4667 }
4668
4669 /* Do soft reconfig table per bgp table.
4670 * Walk on SOFT_RECONFIG_TASK_MAX_PREFIX bgp_dest,
4671 * when BGP_NODE_SOFT_RECONFIG is set,
4672 * reconfig bgp_dest for list of table->soft_reconfig_peers peers.
4673 * Schedule a new thread to continue the job.
4674 * Without splitting the full job into several part,
4675 * vtysh waits for the job to finish before responding to a BGP command
4676 */
4677 static int bgp_soft_reconfig_table_task(struct thread *thread)
4678 {
4679 uint32_t iter, max_iter;
4680 int ret;
4681 struct bgp_dest *dest;
4682 struct bgp_adj_in *ain;
4683 struct peer *peer;
4684 struct bgp_table *table;
4685 struct prefix_rd *prd;
4686 struct listnode *node, *nnode;
4687
4688 table = THREAD_ARG(thread);
4689 prd = NULL;
4690
4691 max_iter = SOFT_RECONFIG_TASK_MAX_PREFIX;
4692 if (table->soft_reconfig_init) {
4693 /* first call of the function with a new srta structure.
4694 * Don't do any treatment this time on nodes
4695 * in order vtysh to respond quickly
4696 */
4697 max_iter = 0;
4698 }
4699
4700 for (iter = 0, dest = bgp_table_top(table); (dest && iter < max_iter);
4701 dest = bgp_route_next(dest)) {
4702 if (!CHECK_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG))
4703 continue;
4704
4705 UNSET_FLAG(dest->flags, BGP_NODE_SOFT_RECONFIG);
4706
4707 for (ain = dest->adj_in; ain; ain = ain->next) {
4708 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node,
4709 nnode, peer)) {
4710 if (ain->peer != peer)
4711 continue;
4712
4713 ret = bgp_soft_reconfig_table_update(
4714 peer, dest, ain, table->afi,
4715 table->safi, prd);
4716 iter++;
4717
4718 if (ret < 0) {
4719 bgp_dest_unlock_node(dest);
4720 listnode_delete(
4721 table->soft_reconfig_peers,
4722 peer);
4723 bgp_announce_route(peer, table->afi,
4724 table->safi);
4725 if (list_isempty(
4726 table->soft_reconfig_peers)) {
4727 list_delete(
4728 &table->soft_reconfig_peers);
4729 bgp_soft_reconfig_table_flag(
4730 table, false);
4731 return 0;
4732 }
4733 }
4734 }
4735 }
4736 }
4737
4738 /* we're either starting the initial iteration,
4739 * or we're going to continue an ongoing iteration
4740 */
4741 if (dest || table->soft_reconfig_init) {
4742 table->soft_reconfig_init = false;
4743 thread_add_event(bm->master, bgp_soft_reconfig_table_task,
4744 table, 0, &table->soft_reconfig_thread);
4745 return 0;
4746 }
4747 /* we're done, clean up the background iteration context info and
4748 schedule route annoucement
4749 */
4750 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode, peer)) {
4751 listnode_delete(table->soft_reconfig_peers, peer);
4752 bgp_announce_route(peer, table->afi, table->safi);
4753 }
4754
4755 list_delete(&table->soft_reconfig_peers);
4756
4757 return 0;
4758 }
4759
4760
4761 /* Cancel soft_reconfig_table task matching bgp instance, bgp_table
4762 * and peer.
4763 * - bgp cannot be NULL
4764 * - if table and peer are NULL, cancel all threads within the bgp instance
4765 * - if table is NULL and peer is not,
4766 * remove peer in all threads within the bgp instance
4767 * - if peer is NULL, cancel all threads matching table within the bgp instance
4768 */
4769 void bgp_soft_reconfig_table_task_cancel(const struct bgp *bgp,
4770 const struct bgp_table *table,
4771 const struct peer *peer)
4772 {
4773 struct peer *npeer;
4774 struct listnode *node, *nnode;
4775 int afi, safi;
4776 struct bgp_table *ntable;
4777
4778 if (!bgp)
4779 return;
4780
4781 FOREACH_AFI_SAFI (afi, safi) {
4782 ntable = bgp->rib[afi][safi];
4783 if (!ntable)
4784 continue;
4785 if (table && table != ntable)
4786 continue;
4787
4788 for (ALL_LIST_ELEMENTS(ntable->soft_reconfig_peers, node, nnode,
4789 npeer)) {
4790 if (peer && peer != npeer)
4791 continue;
4792 listnode_delete(ntable->soft_reconfig_peers, npeer);
4793 }
4794
4795 if (!ntable->soft_reconfig_peers
4796 || !list_isempty(ntable->soft_reconfig_peers))
4797 continue;
4798
4799 list_delete(&ntable->soft_reconfig_peers);
4800 bgp_soft_reconfig_table_flag(ntable, false);
4801 BGP_TIMER_OFF(ntable->soft_reconfig_thread);
4802 }
4803 }
4804
4805 void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
4806 {
4807 struct bgp_dest *dest;
4808 struct bgp_table *table;
4809 struct listnode *node, *nnode;
4810 struct peer *npeer;
4811 struct peer_af *paf;
4812
4813 if (!peer_established(peer))
4814 return;
4815
4816 if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
4817 && (safi != SAFI_EVPN)) {
4818 table = peer->bgp->rib[afi][safi];
4819 if (!table)
4820 return;
4821
4822 table->soft_reconfig_init = true;
4823
4824 if (!table->soft_reconfig_peers)
4825 table->soft_reconfig_peers = list_new();
4826 npeer = NULL;
4827 /* add peer to the table soft_reconfig_peers if not already
4828 * there
4829 */
4830 for (ALL_LIST_ELEMENTS(table->soft_reconfig_peers, node, nnode,
4831 npeer)) {
4832 if (peer == npeer)
4833 break;
4834 }
4835 if (peer != npeer)
4836 listnode_add(table->soft_reconfig_peers, peer);
4837
4838 /* (re)flag all bgp_dest in table. Existing soft_reconfig_in job
4839 * on table would start back at the beginning.
4840 */
4841 bgp_soft_reconfig_table_flag(table, true);
4842
4843 if (!table->soft_reconfig_thread)
4844 thread_add_event(bm->master,
4845 bgp_soft_reconfig_table_task, table, 0,
4846 &table->soft_reconfig_thread);
4847 /* Cancel bgp_announce_route_timer_expired threads.
4848 * bgp_announce_route_timer_expired threads have been scheduled
4849 * to announce routes as soon as the soft_reconfigure process
4850 * finishes.
4851 * In this case, soft_reconfigure is also scheduled by using
4852 * a thread but is planned after the
4853 * bgp_announce_route_timer_expired threads. It means that,
4854 * without cancelling the threads, the route announcement task
4855 * would run before the soft reconfiguration one. That would
4856 * useless and would block vtysh during several seconds. Route
4857 * announcements are rescheduled as soon as the soft_reconfigure
4858 * process finishes.
4859 */
4860 paf = peer_af_find(peer, afi, safi);
4861 if (paf)
4862 bgp_stop_announce_route_timer(paf);
4863 } else
4864 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
4865 dest = bgp_route_next(dest)) {
4866 table = bgp_dest_get_bgp_table_info(dest);
4867
4868 if (table == NULL)
4869 continue;
4870
4871 const struct prefix *p = bgp_dest_get_prefix(dest);
4872 struct prefix_rd prd;
4873
4874 prd.family = AF_UNSPEC;
4875 prd.prefixlen = 64;
4876 memcpy(&prd.val, p->u.val, 8);
4877
4878 bgp_soft_reconfig_table(peer, afi, safi, table, &prd);
4879 }
4880 }
4881
4882
4883 struct bgp_clear_node_queue {
4884 struct bgp_dest *dest;
4885 };
4886
4887 static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
4888 {
4889 struct bgp_clear_node_queue *cnq = data;
4890 struct bgp_dest *dest = cnq->dest;
4891 struct peer *peer = wq->spec.data;
4892 struct bgp_path_info *pi;
4893 struct bgp *bgp;
4894 afi_t afi = bgp_dest_table(dest)->afi;
4895 safi_t safi = bgp_dest_table(dest)->safi;
4896
4897 assert(dest && peer);
4898 bgp = peer->bgp;
4899
4900 /* It is possible that we have multiple paths for a prefix from a peer
4901 * if that peer is using AddPath.
4902 */
4903 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
4904 if (pi->peer != peer)
4905 continue;
4906
4907 /* graceful restart STALE flag set. */
4908 if (((CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
4909 && peer->nsf[afi][safi])
4910 || CHECK_FLAG(peer->af_sflags[afi][safi],
4911 PEER_STATUS_ENHANCED_REFRESH))
4912 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
4913 && !CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
4914 bgp_path_info_set_flag(dest, pi, BGP_PATH_STALE);
4915 else {
4916 /* If this is an EVPN route, process for
4917 * un-import. */
4918 if (safi == SAFI_EVPN)
4919 bgp_evpn_unimport_route(
4920 bgp, afi, safi,
4921 bgp_dest_get_prefix(dest), pi);
4922 /* Handle withdraw for VRF route-leaking and L3VPN */
4923 if (SAFI_UNICAST == safi
4924 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
4925 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
4926 vpn_leak_from_vrf_withdraw(bgp_get_default(),
4927 bgp, pi);
4928 }
4929 if (SAFI_MPLS_VPN == safi &&
4930 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
4931 vpn_leak_to_vrf_withdraw(bgp, pi);
4932 }
4933
4934 bgp_rib_remove(dest, pi, peer, afi, safi);
4935 }
4936 }
4937 return WQ_SUCCESS;
4938 }
4939
4940 static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
4941 {
4942 struct bgp_clear_node_queue *cnq = data;
4943 struct bgp_dest *dest = cnq->dest;
4944 struct bgp_table *table = bgp_dest_table(dest);
4945
4946 bgp_dest_unlock_node(dest);
4947 bgp_table_unlock(table);
4948 XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
4949 }
4950
4951 static void bgp_clear_node_complete(struct work_queue *wq)
4952 {
4953 struct peer *peer = wq->spec.data;
4954
4955 /* Tickle FSM to start moving again */
4956 BGP_EVENT_ADD(peer, Clearing_Completed);
4957
4958 peer_unlock(peer); /* bgp_clear_route */
4959 }
4960
4961 static void bgp_clear_node_queue_init(struct peer *peer)
4962 {
4963 char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
4964
4965 snprintf(wname, sizeof(wname), "clear %s", peer->host);
4966 #undef CLEAR_QUEUE_NAME_LEN
4967
4968 peer->clear_node_queue = work_queue_new(bm->master, wname);
4969 peer->clear_node_queue->spec.hold = 10;
4970 peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
4971 peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
4972 peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
4973 peer->clear_node_queue->spec.max_retries = 0;
4974
4975 /* we only 'lock' this peer reference when the queue is actually active
4976 */
4977 peer->clear_node_queue->spec.data = peer;
4978 }
4979
4980 static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
4981 struct bgp_table *table)
4982 {
4983 struct bgp_dest *dest;
4984 int force = peer->bgp->process_queue ? 0 : 1;
4985
4986 if (!table)
4987 table = peer->bgp->rib[afi][safi];
4988
4989 /* If still no table => afi/safi isn't configured at all or smth. */
4990 if (!table)
4991 return;
4992
4993 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
4994 struct bgp_path_info *pi, *next;
4995 struct bgp_adj_in *ain;
4996 struct bgp_adj_in *ain_next;
4997
4998 /* XXX:TODO: This is suboptimal, every non-empty route_node is
4999 * queued for every clearing peer, regardless of whether it is
5000 * relevant to the peer at hand.
5001 *
5002 * Overview: There are 3 different indices which need to be
5003 * scrubbed, potentially, when a peer is removed:
5004 *
5005 * 1 peer's routes visible via the RIB (ie accepted routes)
5006 * 2 peer's routes visible by the (optional) peer's adj-in index
5007 * 3 other routes visible by the peer's adj-out index
5008 *
5009 * 3 there is no hurry in scrubbing, once the struct peer is
5010 * removed from bgp->peer, we could just GC such deleted peer's
5011 * adj-outs at our leisure.
5012 *
5013 * 1 and 2 must be 'scrubbed' in some way, at least made
5014 * invisible via RIB index before peer session is allowed to be
5015 * brought back up. So one needs to know when such a 'search' is
5016 * complete.
5017 *
5018 * Ideally:
5019 *
5020 * - there'd be a single global queue or a single RIB walker
5021 * - rather than tracking which route_nodes still need to be
5022 * examined on a peer basis, we'd track which peers still
5023 * aren't cleared
5024 *
5025 * Given that our per-peer prefix-counts now should be reliable,
5026 * this may actually be achievable. It doesn't seem to be a huge
5027 * problem at this time,
5028 *
5029 * It is possible that we have multiple paths for a prefix from
5030 * a peer
5031 * if that peer is using AddPath.
5032 */
5033 ain = dest->adj_in;
5034 while (ain) {
5035 ain_next = ain->next;
5036
5037 if (ain->peer == peer)
5038 bgp_adj_in_remove(dest, ain);
5039
5040 ain = ain_next;
5041 }
5042
5043 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5044 next = pi->next;
5045 if (pi->peer != peer)
5046 continue;
5047
5048 if (force)
5049 bgp_path_info_reap(dest, pi);
5050 else {
5051 struct bgp_clear_node_queue *cnq;
5052
5053 /* both unlocked in bgp_clear_node_queue_del */
5054 bgp_table_lock(bgp_dest_table(dest));
5055 bgp_dest_lock_node(dest);
5056 cnq = XCALLOC(
5057 MTYPE_BGP_CLEAR_NODE_QUEUE,
5058 sizeof(struct bgp_clear_node_queue));
5059 cnq->dest = dest;
5060 work_queue_add(peer->clear_node_queue, cnq);
5061 break;
5062 }
5063 }
5064 }
5065 return;
5066 }
5067
5068 void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
5069 {
5070 struct bgp_dest *dest;
5071 struct bgp_table *table;
5072
5073 if (peer->clear_node_queue == NULL)
5074 bgp_clear_node_queue_init(peer);
5075
5076 /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
5077 * Idle until it receives a Clearing_Completed event. This protects
5078 * against peers which flap faster than we can we clear, which could
5079 * lead to:
5080 *
5081 * a) race with routes from the new session being installed before
5082 * clear_route_node visits the node (to delete the route of that
5083 * peer)
5084 * b) resource exhaustion, clear_route_node likely leads to an entry
5085 * on the process_main queue. Fast-flapping could cause that queue
5086 * to grow and grow.
5087 */
5088
5089 /* lock peer in assumption that clear-node-queue will get nodes; if so,
5090 * the unlock will happen upon work-queue completion; other wise, the
5091 * unlock happens at the end of this function.
5092 */
5093 if (!peer->clear_node_queue->thread)
5094 peer_lock(peer);
5095
5096 if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
5097 bgp_clear_route_table(peer, afi, safi, NULL);
5098 else
5099 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5100 dest = bgp_route_next(dest)) {
5101 table = bgp_dest_get_bgp_table_info(dest);
5102 if (!table)
5103 continue;
5104
5105 bgp_clear_route_table(peer, afi, safi, table);
5106 }
5107
5108 /* unlock if no nodes got added to the clear-node-queue. */
5109 if (!peer->clear_node_queue->thread)
5110 peer_unlock(peer);
5111 }
5112
5113 void bgp_clear_route_all(struct peer *peer)
5114 {
5115 afi_t afi;
5116 safi_t safi;
5117
5118 FOREACH_AFI_SAFI (afi, safi)
5119 bgp_clear_route(peer, afi, safi);
5120
5121 #ifdef ENABLE_BGP_VNC
5122 rfapiProcessPeerDown(peer);
5123 #endif
5124 }
5125
5126 void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
5127 {
5128 struct bgp_table *table;
5129 struct bgp_dest *dest;
5130 struct bgp_adj_in *ain;
5131 struct bgp_adj_in *ain_next;
5132
5133 table = peer->bgp->rib[afi][safi];
5134
5135 /* It is possible that we have multiple paths for a prefix from a peer
5136 * if that peer is using AddPath.
5137 */
5138 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
5139 ain = dest->adj_in;
5140
5141 while (ain) {
5142 ain_next = ain->next;
5143
5144 if (ain->peer == peer)
5145 bgp_adj_in_remove(dest, ain);
5146
5147 ain = ain_next;
5148 }
5149 }
5150 }
5151
5152 void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5153 {
5154 struct bgp_dest *dest;
5155 struct bgp_path_info *pi;
5156 struct bgp_table *table;
5157
5158 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5159 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5160 dest = bgp_route_next(dest)) {
5161 struct bgp_dest *rm;
5162
5163 /* look for neighbor in tables */
5164 table = bgp_dest_get_bgp_table_info(dest);
5165 if (!table)
5166 continue;
5167
5168 for (rm = bgp_table_top(table); rm;
5169 rm = bgp_route_next(rm))
5170 for (pi = bgp_dest_get_bgp_path_info(rm); pi;
5171 pi = pi->next) {
5172 if (pi->peer != peer)
5173 continue;
5174 if (!CHECK_FLAG(pi->flags,
5175 BGP_PATH_STALE))
5176 break;
5177
5178 bgp_rib_remove(rm, pi, peer, afi, safi);
5179 break;
5180 }
5181 }
5182 } else {
5183 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5184 dest = bgp_route_next(dest))
5185 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5186 pi = pi->next) {
5187 if (pi->peer != peer)
5188 continue;
5189 if (!CHECK_FLAG(pi->flags, BGP_PATH_STALE))
5190 break;
5191 bgp_rib_remove(dest, pi, peer, afi, safi);
5192 break;
5193 }
5194 }
5195 }
5196
5197 void bgp_set_stale_route(struct peer *peer, afi_t afi, safi_t safi)
5198 {
5199 struct bgp_dest *dest, *ndest;
5200 struct bgp_path_info *pi;
5201 struct bgp_table *table;
5202
5203 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
5204 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5205 dest = bgp_route_next(dest)) {
5206 table = bgp_dest_get_bgp_table_info(dest);
5207 if (!table)
5208 continue;
5209
5210 for (ndest = bgp_table_top(table); ndest;
5211 ndest = bgp_route_next(ndest)) {
5212 for (pi = bgp_dest_get_bgp_path_info(ndest); pi;
5213 pi = pi->next) {
5214 if (pi->peer != peer)
5215 continue;
5216
5217 if ((CHECK_FLAG(
5218 peer->af_sflags[afi][safi],
5219 PEER_STATUS_ENHANCED_REFRESH))
5220 && !CHECK_FLAG(pi->flags,
5221 BGP_PATH_STALE)
5222 && !CHECK_FLAG(
5223 pi->flags,
5224 BGP_PATH_UNUSEABLE)) {
5225 if (bgp_debug_neighbor_events(
5226 peer))
5227 zlog_debug(
5228 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5229 peer->host,
5230 afi2str(afi),
5231 safi2str(safi),
5232 bgp_dest_get_prefix(
5233 ndest));
5234
5235 bgp_path_info_set_flag(
5236 ndest, pi,
5237 BGP_PATH_STALE);
5238 }
5239 }
5240 }
5241 }
5242 } else {
5243 for (dest = bgp_table_top(peer->bgp->rib[afi][safi]); dest;
5244 dest = bgp_route_next(dest)) {
5245 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
5246 pi = pi->next) {
5247 if (pi->peer != peer)
5248 continue;
5249
5250 if ((CHECK_FLAG(peer->af_sflags[afi][safi],
5251 PEER_STATUS_ENHANCED_REFRESH))
5252 && !CHECK_FLAG(pi->flags, BGP_PATH_STALE)
5253 && !CHECK_FLAG(pi->flags,
5254 BGP_PATH_UNUSEABLE)) {
5255 if (bgp_debug_neighbor_events(peer))
5256 zlog_debug(
5257 "%s: route-refresh for %s/%s, marking prefix %pFX as stale",
5258 peer->host,
5259 afi2str(afi),
5260 safi2str(safi),
5261 bgp_dest_get_prefix(
5262 dest));
5263
5264 bgp_path_info_set_flag(dest, pi,
5265 BGP_PATH_STALE);
5266 }
5267 }
5268 }
5269 }
5270 }
5271
5272 bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5273 {
5274 if (peer->sort == BGP_PEER_IBGP)
5275 return true;
5276
5277 if (peer->sort == BGP_PEER_EBGP
5278 && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
5279 || FILTER_LIST_OUT_NAME(filter)
5280 || DISTRIBUTE_OUT_NAME(filter)))
5281 return true;
5282 return false;
5283 }
5284
5285 bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
5286 {
5287 if (peer->sort == BGP_PEER_IBGP)
5288 return true;
5289
5290 if (peer->sort == BGP_PEER_EBGP
5291 && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
5292 || FILTER_LIST_IN_NAME(filter)
5293 || DISTRIBUTE_IN_NAME(filter)))
5294 return true;
5295 return false;
5296 }
5297
5298 static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
5299 safi_t safi)
5300 {
5301 struct bgp_dest *dest;
5302 struct bgp_path_info *pi;
5303 struct bgp_path_info *next;
5304
5305 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
5306 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = next) {
5307 const struct prefix *p = bgp_dest_get_prefix(dest);
5308
5309 next = pi->next;
5310
5311 /* Unimport EVPN routes from VRFs */
5312 if (safi == SAFI_EVPN)
5313 bgp_evpn_unimport_route(bgp, AFI_L2VPN,
5314 SAFI_EVPN, p, pi);
5315
5316 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
5317 && pi->type == ZEBRA_ROUTE_BGP
5318 && (pi->sub_type == BGP_ROUTE_NORMAL
5319 || pi->sub_type == BGP_ROUTE_AGGREGATE
5320 || pi->sub_type == BGP_ROUTE_IMPORTED)) {
5321
5322 if (bgp_fibupd_safi(safi))
5323 bgp_zebra_withdraw(p, pi, bgp, safi);
5324 }
5325
5326 bgp_path_info_reap(dest, pi);
5327 }
5328 }
5329
5330 /* Delete all kernel routes. */
5331 void bgp_cleanup_routes(struct bgp *bgp)
5332 {
5333 afi_t afi;
5334 struct bgp_dest *dest;
5335 struct bgp_table *table;
5336
5337 for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
5338 if (afi == AFI_L2VPN)
5339 continue;
5340 bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
5341 SAFI_UNICAST);
5342 /*
5343 * VPN and ENCAP and EVPN tables are two-level (RD is top level)
5344 */
5345 if (afi != AFI_L2VPN) {
5346 safi_t safi;
5347 safi = SAFI_MPLS_VPN;
5348 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5349 dest = bgp_route_next(dest)) {
5350 table = bgp_dest_get_bgp_table_info(dest);
5351 if (table != NULL) {
5352 bgp_cleanup_table(bgp, table, safi);
5353 bgp_table_finish(&table);
5354 bgp_dest_set_bgp_table_info(dest, NULL);
5355 bgp_dest_unlock_node(dest);
5356 }
5357 }
5358 safi = SAFI_ENCAP;
5359 for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
5360 dest = bgp_route_next(dest)) {
5361 table = bgp_dest_get_bgp_table_info(dest);
5362 if (table != NULL) {
5363 bgp_cleanup_table(bgp, table, safi);
5364 bgp_table_finish(&table);
5365 bgp_dest_set_bgp_table_info(dest, NULL);
5366 bgp_dest_unlock_node(dest);
5367 }
5368 }
5369 }
5370 }
5371 for (dest = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); dest;
5372 dest = bgp_route_next(dest)) {
5373 table = bgp_dest_get_bgp_table_info(dest);
5374 if (table != NULL) {
5375 bgp_cleanup_table(bgp, table, SAFI_EVPN);
5376 bgp_table_finish(&table);
5377 bgp_dest_set_bgp_table_info(dest, NULL);
5378 bgp_dest_unlock_node(dest);
5379 }
5380 }
5381 }
5382
5383 void bgp_reset(void)
5384 {
5385 vty_reset();
5386 bgp_zclient_reset();
5387 access_list_reset();
5388 prefix_list_reset();
5389 }
5390
5391 static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
5392 {
5393 return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
5394 && CHECK_FLAG(peer->af_cap[afi][safi],
5395 PEER_CAP_ADDPATH_AF_TX_RCV));
5396 }
5397
5398 /* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
5399 value. */
5400 int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
5401 struct bgp_nlri *packet)
5402 {
5403 uint8_t *pnt;
5404 uint8_t *lim;
5405 struct prefix p;
5406 int psize;
5407 int ret;
5408 afi_t afi;
5409 safi_t safi;
5410 int addpath_encoded;
5411 uint32_t addpath_id;
5412
5413 pnt = packet->nlri;
5414 lim = pnt + packet->length;
5415 afi = packet->afi;
5416 safi = packet->safi;
5417 addpath_id = 0;
5418 addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
5419
5420 /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
5421 syntactic validity. If the field is syntactically incorrect,
5422 then the Error Subcode is set to Invalid Network Field. */
5423 for (; pnt < lim; pnt += psize) {
5424 /* Clear prefix structure. */
5425 memset(&p, 0, sizeof(struct prefix));
5426
5427 if (addpath_encoded) {
5428
5429 /* When packet overflow occurs return immediately. */
5430 if (pnt + BGP_ADDPATH_ID_LEN >= lim)
5431 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5432
5433 memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
5434 addpath_id = ntohl(addpath_id);
5435 pnt += BGP_ADDPATH_ID_LEN;
5436 }
5437
5438 /* Fetch prefix length. */
5439 p.prefixlen = *pnt++;
5440 /* afi/safi validity already verified by caller,
5441 * bgp_update_receive */
5442 p.family = afi2family(afi);
5443
5444 /* Prefix length check. */
5445 if (p.prefixlen > prefix_blen(&p) * 8) {
5446 flog_err(
5447 EC_BGP_UPDATE_RCV,
5448 "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
5449 peer->host, p.prefixlen, packet->afi);
5450 return BGP_NLRI_PARSE_ERROR_PREFIX_LENGTH;
5451 }
5452
5453 /* Packet size overflow check. */
5454 psize = PSIZE(p.prefixlen);
5455
5456 /* When packet overflow occur return immediately. */
5457 if (pnt + psize > lim) {
5458 flog_err(
5459 EC_BGP_UPDATE_RCV,
5460 "%s [Error] Update packet error (prefix length %d overflows packet)",
5461 peer->host, p.prefixlen);
5462 return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
5463 }
5464
5465 /* Defensive coding, double-check the psize fits in a struct
5466 * prefix */
5467 if (psize > (ssize_t)sizeof(p.u)) {
5468 flog_err(
5469 EC_BGP_UPDATE_RCV,
5470 "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
5471 peer->host, p.prefixlen, sizeof(p.u));
5472 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5473 }
5474
5475 /* Fetch prefix from NLRI packet. */
5476 memcpy(p.u.val, pnt, psize);
5477
5478 /* Check address. */
5479 if (afi == AFI_IP && safi == SAFI_UNICAST) {
5480 if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
5481 /* From RFC4271 Section 6.3:
5482 *
5483 * If a prefix in the NLRI field is semantically
5484 * incorrect
5485 * (e.g., an unexpected multicast IP address),
5486 * an error SHOULD
5487 * be logged locally, and the prefix SHOULD be
5488 * ignored.
5489 */
5490 flog_err(
5491 EC_BGP_UPDATE_RCV,
5492 "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
5493 peer->host, &p.u.prefix4);
5494 continue;
5495 }
5496 }
5497
5498 /* Check address. */
5499 if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
5500 if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
5501 flog_err(
5502 EC_BGP_UPDATE_RCV,
5503 "%s: IPv6 unicast NLRI is link-local address %pI6, ignoring",
5504 peer->host, &p.u.prefix6);
5505
5506 continue;
5507 }
5508 if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
5509 flog_err(
5510 EC_BGP_UPDATE_RCV,
5511 "%s: IPv6 unicast NLRI is multicast address %pI6, ignoring",
5512 peer->host, &p.u.prefix6);
5513
5514 continue;
5515 }
5516 }
5517
5518 /* Normal process. */
5519 if (attr)
5520 ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
5521 ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
5522 NULL, NULL, 0, 0, NULL);
5523 else
5524 ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
5525 safi, ZEBRA_ROUTE_BGP,
5526 BGP_ROUTE_NORMAL, NULL, NULL, 0,
5527 NULL);
5528
5529 /* Do not send BGP notification twice when maximum-prefix count
5530 * overflow. */
5531 if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW))
5532 return BGP_NLRI_PARSE_ERROR_PREFIX_OVERFLOW;
5533
5534 /* Address family configuration mismatch. */
5535 if (ret < 0)
5536 return BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY;
5537 }
5538
5539 /* Packet length consistency check. */
5540 if (pnt != lim) {
5541 flog_err(
5542 EC_BGP_UPDATE_RCV,
5543 "%s [Error] Update packet error (prefix length mismatch with total length)",
5544 peer->host);
5545 return BGP_NLRI_PARSE_ERROR_PACKET_LENGTH;
5546 }
5547
5548 return BGP_NLRI_PARSE_OK;
5549 }
5550
5551 static struct bgp_static *bgp_static_new(void)
5552 {
5553 return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
5554 }
5555
5556 static void bgp_static_free(struct bgp_static *bgp_static)
5557 {
5558 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
5559 route_map_counter_decrement(bgp_static->rmap.map);
5560
5561 XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
5562 XFREE(MTYPE_BGP_STATIC, bgp_static);
5563 }
5564
5565 void bgp_static_update(struct bgp *bgp, const struct prefix *p,
5566 struct bgp_static *bgp_static, afi_t afi, safi_t safi)
5567 {
5568 struct bgp_dest *dest;
5569 struct bgp_path_info *pi;
5570 struct bgp_path_info *new;
5571 struct bgp_path_info rmap_path;
5572 struct attr attr;
5573 struct attr *attr_new;
5574 route_map_result_t ret;
5575 #ifdef ENABLE_BGP_VNC
5576 int vnc_implicit_withdraw = 0;
5577 #endif
5578
5579 assert(bgp_static);
5580
5581 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5582
5583 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5584
5585 attr.nexthop = bgp_static->igpnexthop;
5586 attr.med = bgp_static->igpmetric;
5587 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5588
5589 if (bgp_static->atomic)
5590 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
5591
5592 /* Store label index, if required. */
5593 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX) {
5594 attr.label_index = bgp_static->label_index;
5595 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PREFIX_SID);
5596 }
5597
5598 /* Apply route-map. */
5599 if (bgp_static->rmap.name) {
5600 struct attr attr_tmp = attr;
5601
5602 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
5603 rmap_path.peer = bgp->peer_self;
5604 rmap_path.attr = &attr_tmp;
5605
5606 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5607
5608 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5609
5610 bgp->peer_self->rmap_type = 0;
5611
5612 if (ret == RMAP_DENYMATCH) {
5613 /* Free uninterned attribute. */
5614 bgp_attr_flush(&attr_tmp);
5615
5616 /* Unintern original. */
5617 aspath_unintern(&attr.aspath);
5618 bgp_static_withdraw(bgp, p, afi, safi);
5619 return;
5620 }
5621
5622 if (bgp_in_graceful_shutdown(bgp))
5623 bgp_attr_add_gshut_community(&attr_tmp);
5624
5625 attr_new = bgp_attr_intern(&attr_tmp);
5626 } else {
5627
5628 if (bgp_in_graceful_shutdown(bgp))
5629 bgp_attr_add_gshut_community(&attr);
5630
5631 attr_new = bgp_attr_intern(&attr);
5632 }
5633
5634 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5635 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5636 && pi->sub_type == BGP_ROUTE_STATIC)
5637 break;
5638
5639 if (pi) {
5640 if (attrhash_cmp(pi->attr, attr_new)
5641 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
5642 && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
5643 bgp_dest_unlock_node(dest);
5644 bgp_attr_unintern(&attr_new);
5645 aspath_unintern(&attr.aspath);
5646 return;
5647 } else {
5648 /* The attribute is changed. */
5649 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5650
5651 /* Rewrite BGP route information. */
5652 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5653 bgp_path_info_restore(dest, pi);
5654 else
5655 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5656 #ifdef ENABLE_BGP_VNC
5657 if ((afi == AFI_IP || afi == AFI_IP6)
5658 && (safi == SAFI_UNICAST)) {
5659 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
5660 /*
5661 * Implicit withdraw case.
5662 * We have to do this before pi is
5663 * changed
5664 */
5665 ++vnc_implicit_withdraw;
5666 vnc_import_bgp_del_route(bgp, p, pi);
5667 vnc_import_bgp_exterior_del_route(
5668 bgp, p, pi);
5669 }
5670 }
5671 #endif
5672 bgp_attr_unintern(&pi->attr);
5673 pi->attr = attr_new;
5674 pi->uptime = bgp_clock();
5675 #ifdef ENABLE_BGP_VNC
5676 if ((afi == AFI_IP || afi == AFI_IP6)
5677 && (safi == SAFI_UNICAST)) {
5678 if (vnc_implicit_withdraw) {
5679 vnc_import_bgp_add_route(bgp, p, pi);
5680 vnc_import_bgp_exterior_add_route(
5681 bgp, p, pi);
5682 }
5683 }
5684 #endif
5685
5686 /* Nexthop reachability check. */
5687 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5688 && (safi == SAFI_UNICAST
5689 || safi == SAFI_LABELED_UNICAST)) {
5690
5691 struct bgp *bgp_nexthop = bgp;
5692
5693 if (pi->extra && pi->extra->bgp_orig)
5694 bgp_nexthop = pi->extra->bgp_orig;
5695
5696 if (bgp_find_or_add_nexthop(bgp, bgp_nexthop,
5697 afi, safi, pi, NULL,
5698 0, p))
5699 bgp_path_info_set_flag(dest, pi,
5700 BGP_PATH_VALID);
5701 else {
5702 if (BGP_DEBUG(nht, NHT)) {
5703 char buf1[INET6_ADDRSTRLEN];
5704 inet_ntop(p->family,
5705 &p->u.prefix, buf1,
5706 INET6_ADDRSTRLEN);
5707 zlog_debug(
5708 "%s(%s): Route not in table, not advertising",
5709 __func__, buf1);
5710 }
5711 bgp_path_info_unset_flag(
5712 dest, pi, BGP_PATH_VALID);
5713 }
5714 } else {
5715 /* Delete the NHT structure if any, if we're
5716 * toggling between
5717 * enabling/disabling import check. We
5718 * deregister the route
5719 * from NHT to avoid overloading NHT and the
5720 * process interaction
5721 */
5722 bgp_unlink_nexthop(pi);
5723 bgp_path_info_set_flag(dest, pi,
5724 BGP_PATH_VALID);
5725 }
5726 /* Process change. */
5727 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5728 bgp_process(bgp, dest, afi, safi);
5729
5730 if (SAFI_UNICAST == safi
5731 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5732 || bgp->inst_type
5733 == BGP_INSTANCE_TYPE_DEFAULT)) {
5734 vpn_leak_from_vrf_update(bgp_get_default(), bgp,
5735 pi);
5736 }
5737
5738 bgp_dest_unlock_node(dest);
5739 aspath_unintern(&attr.aspath);
5740 return;
5741 }
5742 }
5743
5744 /* Make new BGP info. */
5745 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
5746 attr_new, dest);
5747 /* Nexthop reachability check. */
5748 if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)
5749 && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
5750 if (bgp_find_or_add_nexthop(bgp, bgp, afi, safi, new, NULL, 0,
5751 p))
5752 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5753 else {
5754 if (BGP_DEBUG(nht, NHT)) {
5755 char buf1[INET6_ADDRSTRLEN];
5756 inet_ntop(p->family, &p->u.prefix, buf1,
5757 INET6_ADDRSTRLEN);
5758 zlog_debug(
5759 "%s(%s): Route not in table, not advertising",
5760 __func__, buf1);
5761 }
5762 bgp_path_info_unset_flag(dest, new, BGP_PATH_VALID);
5763 }
5764 } else {
5765 /* Delete the NHT structure if any, if we're toggling between
5766 * enabling/disabling import check. We deregister the route
5767 * from NHT to avoid overloading NHT and the process interaction
5768 */
5769 bgp_unlink_nexthop(new);
5770
5771 bgp_path_info_set_flag(dest, new, BGP_PATH_VALID);
5772 }
5773
5774 /* Aggregate address increment. */
5775 bgp_aggregate_increment(bgp, p, new, afi, safi);
5776
5777 /* Register new BGP information. */
5778 bgp_path_info_add(dest, new);
5779
5780 /* route_node_get lock */
5781 bgp_dest_unlock_node(dest);
5782
5783 /* Process change. */
5784 bgp_process(bgp, dest, afi, safi);
5785
5786 if (SAFI_UNICAST == safi
5787 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5788 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5789 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
5790 }
5791
5792 /* Unintern original. */
5793 aspath_unintern(&attr.aspath);
5794 }
5795
5796 void bgp_static_withdraw(struct bgp *bgp, const struct prefix *p, afi_t afi,
5797 safi_t safi)
5798 {
5799 struct bgp_dest *dest;
5800 struct bgp_path_info *pi;
5801
5802 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
5803
5804 /* Check selected route and self inserted route. */
5805 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5806 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5807 && pi->sub_type == BGP_ROUTE_STATIC)
5808 break;
5809
5810 /* Withdraw static BGP route from routing table. */
5811 if (pi) {
5812 if (SAFI_UNICAST == safi
5813 && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF
5814 || bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
5815 vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, pi);
5816 }
5817 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5818 bgp_unlink_nexthop(pi);
5819 bgp_path_info_delete(dest, pi);
5820 bgp_process(bgp, dest, afi, safi);
5821 }
5822
5823 /* Unlock bgp_node_lookup. */
5824 bgp_dest_unlock_node(dest);
5825 }
5826
5827 /*
5828 * Used for SAFI_MPLS_VPN and SAFI_ENCAP
5829 */
5830 static void bgp_static_withdraw_safi(struct bgp *bgp, const struct prefix *p,
5831 afi_t afi, safi_t safi,
5832 struct prefix_rd *prd)
5833 {
5834 struct bgp_dest *dest;
5835 struct bgp_path_info *pi;
5836
5837 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
5838
5839 /* Check selected route and self inserted route. */
5840 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5841 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5842 && pi->sub_type == BGP_ROUTE_STATIC)
5843 break;
5844
5845 /* Withdraw static BGP route from routing table. */
5846 if (pi) {
5847 #ifdef ENABLE_BGP_VNC
5848 rfapiProcessWithdraw(
5849 pi->peer, NULL, p, prd, pi->attr, afi, safi, pi->type,
5850 1); /* Kill, since it is an administrative change */
5851 #endif
5852 if (SAFI_MPLS_VPN == safi
5853 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5854 vpn_leak_to_vrf_withdraw(bgp, pi);
5855 }
5856 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5857 bgp_path_info_delete(dest, pi);
5858 bgp_process(bgp, dest, afi, safi);
5859 }
5860
5861 /* Unlock bgp_node_lookup. */
5862 bgp_dest_unlock_node(dest);
5863 }
5864
5865 static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
5866 struct bgp_static *bgp_static, afi_t afi,
5867 safi_t safi)
5868 {
5869 struct bgp_dest *dest;
5870 struct bgp_path_info *new;
5871 struct attr *attr_new;
5872 struct attr attr = {0};
5873 struct bgp_path_info *pi;
5874 #ifdef ENABLE_BGP_VNC
5875 mpls_label_t label = 0;
5876 #endif
5877 uint32_t num_labels = 0;
5878 union gw_addr add;
5879
5880 assert(bgp_static);
5881
5882 if (bgp_static->label != MPLS_INVALID_LABEL)
5883 num_labels = 1;
5884 dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
5885 &bgp_static->prd);
5886
5887 bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
5888
5889 attr.nexthop = bgp_static->igpnexthop;
5890 attr.med = bgp_static->igpmetric;
5891 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
5892
5893 if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
5894 || (safi == SAFI_ENCAP)) {
5895 if (afi == AFI_IP) {
5896 attr.mp_nexthop_global_in = bgp_static->igpnexthop;
5897 attr.mp_nexthop_len = IPV4_MAX_BYTELEN;
5898 }
5899 }
5900 if (afi == AFI_L2VPN) {
5901 if (bgp_static->gatewayIp.family == AF_INET)
5902 add.ipv4.s_addr =
5903 bgp_static->gatewayIp.u.prefix4.s_addr;
5904 else if (bgp_static->gatewayIp.family == AF_INET6)
5905 memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
5906 sizeof(struct in6_addr));
5907 memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
5908 if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
5909 struct bgp_encap_type_vxlan bet;
5910 memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
5911 bet.vnid = p->u.prefix_evpn.prefix_addr.eth_tag;
5912 bgp_encap_type_vxlan_to_tlv(&bet, &attr);
5913 }
5914 if (bgp_static->router_mac) {
5915 bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
5916 }
5917 }
5918 /* Apply route-map. */
5919 if (bgp_static->rmap.name) {
5920 struct attr attr_tmp = attr;
5921 struct bgp_path_info rmap_path;
5922 route_map_result_t ret;
5923
5924 rmap_path.peer = bgp->peer_self;
5925 rmap_path.attr = &attr_tmp;
5926
5927 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
5928
5929 ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
5930
5931 bgp->peer_self->rmap_type = 0;
5932
5933 if (ret == RMAP_DENYMATCH) {
5934 /* Free uninterned attribute. */
5935 bgp_attr_flush(&attr_tmp);
5936
5937 /* Unintern original. */
5938 aspath_unintern(&attr.aspath);
5939 bgp_static_withdraw_safi(bgp, p, afi, safi,
5940 &bgp_static->prd);
5941 return;
5942 }
5943
5944 attr_new = bgp_attr_intern(&attr_tmp);
5945 } else {
5946 attr_new = bgp_attr_intern(&attr);
5947 }
5948
5949 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
5950 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
5951 && pi->sub_type == BGP_ROUTE_STATIC)
5952 break;
5953
5954 if (pi) {
5955 memset(&add, 0, sizeof(union gw_addr));
5956 if (attrhash_cmp(pi->attr, attr_new)
5957 && overlay_index_equal(afi, pi, &add)
5958 && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
5959 bgp_dest_unlock_node(dest);
5960 bgp_attr_unintern(&attr_new);
5961 aspath_unintern(&attr.aspath);
5962 return;
5963 } else {
5964 /* The attribute is changed. */
5965 bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
5966
5967 /* Rewrite BGP route information. */
5968 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
5969 bgp_path_info_restore(dest, pi);
5970 else
5971 bgp_aggregate_decrement(bgp, p, pi, afi, safi);
5972 bgp_attr_unintern(&pi->attr);
5973 pi->attr = attr_new;
5974 pi->uptime = bgp_clock();
5975 #ifdef ENABLE_BGP_VNC
5976 if (pi->extra)
5977 label = decode_label(&pi->extra->label[0]);
5978 #endif
5979
5980 /* Process change. */
5981 bgp_aggregate_increment(bgp, p, pi, afi, safi);
5982 bgp_process(bgp, dest, afi, safi);
5983
5984 if (SAFI_MPLS_VPN == safi
5985 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
5986 vpn_leak_to_vrf_update(bgp, pi);
5987 }
5988 #ifdef ENABLE_BGP_VNC
5989 rfapiProcessUpdate(pi->peer, NULL, p, &bgp_static->prd,
5990 pi->attr, afi, safi, pi->type,
5991 pi->sub_type, &label);
5992 #endif
5993 bgp_dest_unlock_node(dest);
5994 aspath_unintern(&attr.aspath);
5995 return;
5996 }
5997 }
5998
5999
6000 /* Make new BGP info. */
6001 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
6002 attr_new, dest);
6003 SET_FLAG(new->flags, BGP_PATH_VALID);
6004 new->extra = bgp_path_info_extra_new();
6005 if (num_labels) {
6006 new->extra->label[0] = bgp_static->label;
6007 new->extra->num_labels = num_labels;
6008 }
6009 #ifdef ENABLE_BGP_VNC
6010 label = decode_label(&bgp_static->label);
6011 #endif
6012
6013 /* Aggregate address increment. */
6014 bgp_aggregate_increment(bgp, p, new, afi, safi);
6015
6016 /* Register new BGP information. */
6017 bgp_path_info_add(dest, new);
6018 /* route_node_get lock */
6019 bgp_dest_unlock_node(dest);
6020
6021 /* Process change. */
6022 bgp_process(bgp, dest, afi, safi);
6023
6024 if (SAFI_MPLS_VPN == safi
6025 && bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
6026 vpn_leak_to_vrf_update(bgp, new);
6027 }
6028 #ifdef ENABLE_BGP_VNC
6029 rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
6030 safi, new->type, new->sub_type, &label);
6031 #endif
6032
6033 /* Unintern original. */
6034 aspath_unintern(&attr.aspath);
6035 }
6036
6037 /* Configure static BGP network. When user don't run zebra, static
6038 route should be installed as valid. */
6039 static int bgp_static_set(struct vty *vty, const char *negate,
6040 const char *ip_str, afi_t afi, safi_t safi,
6041 const char *rmap, int backdoor, uint32_t label_index)
6042 {
6043 VTY_DECLVAR_CONTEXT(bgp, bgp);
6044 int ret;
6045 struct prefix p;
6046 struct bgp_static *bgp_static;
6047 struct bgp_dest *dest;
6048 uint8_t need_update = 0;
6049
6050 /* Convert IP prefix string to struct prefix. */
6051 ret = str2prefix(ip_str, &p);
6052 if (!ret) {
6053 vty_out(vty, "%% Malformed prefix\n");
6054 return CMD_WARNING_CONFIG_FAILED;
6055 }
6056 if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
6057 vty_out(vty, "%% Malformed prefix (link-local address)\n");
6058 return CMD_WARNING_CONFIG_FAILED;
6059 }
6060
6061 apply_mask(&p);
6062
6063 if (negate) {
6064
6065 /* Set BGP static route configuration. */
6066 dest = bgp_node_lookup(bgp->route[afi][safi], &p);
6067
6068 if (!dest) {
6069 vty_out(vty, "%% Can't find static route specified\n");
6070 return CMD_WARNING_CONFIG_FAILED;
6071 }
6072
6073 bgp_static = bgp_dest_get_bgp_static_info(dest);
6074
6075 if ((label_index != BGP_INVALID_LABEL_INDEX)
6076 && (label_index != bgp_static->label_index)) {
6077 vty_out(vty,
6078 "%% label-index doesn't match static route\n");
6079 bgp_dest_unlock_node(dest);
6080 return CMD_WARNING_CONFIG_FAILED;
6081 }
6082
6083 if ((rmap && bgp_static->rmap.name)
6084 && strcmp(rmap, bgp_static->rmap.name)) {
6085 vty_out(vty,
6086 "%% route-map name doesn't match static route\n");
6087 bgp_dest_unlock_node(dest);
6088 return CMD_WARNING_CONFIG_FAILED;
6089 }
6090
6091 /* Update BGP RIB. */
6092 if (!bgp_static->backdoor)
6093 bgp_static_withdraw(bgp, &p, afi, safi);
6094
6095 /* Clear configuration. */
6096 bgp_static_free(bgp_static);
6097 bgp_dest_set_bgp_static_info(dest, NULL);
6098 bgp_dest_unlock_node(dest);
6099 bgp_dest_unlock_node(dest);
6100 } else {
6101
6102 /* Set BGP static route configuration. */
6103 dest = bgp_node_get(bgp->route[afi][safi], &p);
6104 bgp_static = bgp_dest_get_bgp_static_info(dest);
6105 if (bgp_static) {
6106 /* Configuration change. */
6107 /* Label index cannot be changed. */
6108 if (bgp_static->label_index != label_index) {
6109 vty_out(vty, "%% cannot change label-index\n");
6110 return CMD_WARNING_CONFIG_FAILED;
6111 }
6112
6113 /* Check previous routes are installed into BGP. */
6114 if (bgp_static->valid
6115 && bgp_static->backdoor != backdoor)
6116 need_update = 1;
6117
6118 bgp_static->backdoor = backdoor;
6119
6120 if (rmap) {
6121 XFREE(MTYPE_ROUTE_MAP_NAME,
6122 bgp_static->rmap.name);
6123 route_map_counter_decrement(
6124 bgp_static->rmap.map);
6125 bgp_static->rmap.name =
6126 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6127 bgp_static->rmap.map =
6128 route_map_lookup_by_name(rmap);
6129 route_map_counter_increment(
6130 bgp_static->rmap.map);
6131 } else {
6132 XFREE(MTYPE_ROUTE_MAP_NAME,
6133 bgp_static->rmap.name);
6134 route_map_counter_decrement(
6135 bgp_static->rmap.map);
6136 bgp_static->rmap.map = NULL;
6137 bgp_static->valid = 0;
6138 }
6139 bgp_dest_unlock_node(dest);
6140 } else {
6141 /* New configuration. */
6142 bgp_static = bgp_static_new();
6143 bgp_static->backdoor = backdoor;
6144 bgp_static->valid = 0;
6145 bgp_static->igpmetric = 0;
6146 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6147 bgp_static->label_index = label_index;
6148
6149 if (rmap) {
6150 XFREE(MTYPE_ROUTE_MAP_NAME,
6151 bgp_static->rmap.name);
6152 route_map_counter_decrement(
6153 bgp_static->rmap.map);
6154 bgp_static->rmap.name =
6155 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
6156 bgp_static->rmap.map =
6157 route_map_lookup_by_name(rmap);
6158 route_map_counter_increment(
6159 bgp_static->rmap.map);
6160 }
6161 bgp_dest_set_bgp_static_info(dest, bgp_static);
6162 }
6163
6164 bgp_static->valid = 1;
6165 if (need_update)
6166 bgp_static_withdraw(bgp, &p, afi, safi);
6167
6168 if (!bgp_static->backdoor)
6169 bgp_static_update(bgp, &p, bgp_static, afi, safi);
6170 }
6171
6172 return CMD_SUCCESS;
6173 }
6174
6175 void bgp_static_add(struct bgp *bgp)
6176 {
6177 afi_t afi;
6178 safi_t safi;
6179 struct bgp_dest *dest;
6180 struct bgp_dest *rm;
6181 struct bgp_table *table;
6182 struct bgp_static *bgp_static;
6183
6184 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6185 FOREACH_AFI_SAFI (afi, safi)
6186 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6187 dest = bgp_route_next(dest)) {
6188 if (!bgp_dest_has_bgp_path_info_data(dest))
6189 continue;
6190
6191 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6192 || (safi == SAFI_EVPN)) {
6193 table = bgp_dest_get_bgp_table_info(dest);
6194
6195 for (rm = bgp_table_top(table); rm;
6196 rm = bgp_route_next(rm)) {
6197 bgp_static =
6198 bgp_dest_get_bgp_static_info(
6199 rm);
6200 bgp_static_update_safi(
6201 bgp, bgp_dest_get_prefix(rm),
6202 bgp_static, afi, safi);
6203 }
6204 } else {
6205 bgp_static_update(
6206 bgp, bgp_dest_get_prefix(dest),
6207 bgp_dest_get_bgp_static_info(dest), afi,
6208 safi);
6209 }
6210 }
6211 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6212 }
6213
6214 /* Called from bgp_delete(). Delete all static routes from the BGP
6215 instance. */
6216 void bgp_static_delete(struct bgp *bgp)
6217 {
6218 afi_t afi;
6219 safi_t safi;
6220 struct bgp_dest *dest;
6221 struct bgp_dest *rm;
6222 struct bgp_table *table;
6223 struct bgp_static *bgp_static;
6224
6225 FOREACH_AFI_SAFI (afi, safi)
6226 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6227 dest = bgp_route_next(dest)) {
6228 if (!bgp_dest_has_bgp_path_info_data(dest))
6229 continue;
6230
6231 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6232 || (safi == SAFI_EVPN)) {
6233 table = bgp_dest_get_bgp_table_info(dest);
6234
6235 for (rm = bgp_table_top(table); rm;
6236 rm = bgp_route_next(rm)) {
6237 bgp_static =
6238 bgp_dest_get_bgp_static_info(
6239 rm);
6240 if (!bgp_static)
6241 continue;
6242
6243 bgp_static_withdraw_safi(
6244 bgp, bgp_dest_get_prefix(rm),
6245 AFI_IP, safi,
6246 (struct prefix_rd *)
6247 bgp_dest_get_prefix(
6248 dest));
6249 bgp_static_free(bgp_static);
6250 bgp_dest_set_bgp_static_info(rm,
6251 NULL);
6252 bgp_dest_unlock_node(rm);
6253 }
6254 } else {
6255 bgp_static = bgp_dest_get_bgp_static_info(dest);
6256 bgp_static_withdraw(bgp,
6257 bgp_dest_get_prefix(dest),
6258 afi, safi);
6259 bgp_static_free(bgp_static);
6260 bgp_dest_set_bgp_static_info(dest, NULL);
6261 bgp_dest_unlock_node(dest);
6262 }
6263 }
6264 }
6265
6266 void bgp_static_redo_import_check(struct bgp *bgp)
6267 {
6268 afi_t afi;
6269 safi_t safi;
6270 struct bgp_dest *dest;
6271 struct bgp_dest *rm;
6272 struct bgp_table *table;
6273 struct bgp_static *bgp_static;
6274
6275 /* Use this flag to force reprocessing of the route */
6276 SET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6277 FOREACH_AFI_SAFI (afi, safi) {
6278 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
6279 dest = bgp_route_next(dest)) {
6280 if (!bgp_dest_has_bgp_path_info_data(dest))
6281 continue;
6282
6283 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
6284 || (safi == SAFI_EVPN)) {
6285 table = bgp_dest_get_bgp_table_info(dest);
6286
6287 for (rm = bgp_table_top(table); rm;
6288 rm = bgp_route_next(rm)) {
6289 bgp_static =
6290 bgp_dest_get_bgp_static_info(
6291 rm);
6292 bgp_static_update_safi(
6293 bgp, bgp_dest_get_prefix(rm),
6294 bgp_static, afi, safi);
6295 }
6296 } else {
6297 bgp_static = bgp_dest_get_bgp_static_info(dest);
6298 bgp_static_update(bgp,
6299 bgp_dest_get_prefix(dest),
6300 bgp_static, afi, safi);
6301 }
6302 }
6303 }
6304 UNSET_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS);
6305 }
6306
6307 static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
6308 safi_t safi)
6309 {
6310 struct bgp_table *table;
6311 struct bgp_dest *dest;
6312 struct bgp_path_info *pi;
6313
6314 /* Do not install the aggregate route if BGP is in the
6315 * process of termination.
6316 */
6317 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
6318 || (bgp->peer_self == NULL))
6319 return;
6320
6321 table = bgp->rib[afi][safi];
6322 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
6323 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6324 if (pi->peer == bgp->peer_self
6325 && ((pi->type == ZEBRA_ROUTE_BGP
6326 && pi->sub_type == BGP_ROUTE_STATIC)
6327 || (pi->type != ZEBRA_ROUTE_BGP
6328 && pi->sub_type
6329 == BGP_ROUTE_REDISTRIBUTE))) {
6330 bgp_aggregate_decrement(
6331 bgp, bgp_dest_get_prefix(dest), pi, afi,
6332 safi);
6333 bgp_unlink_nexthop(pi);
6334 bgp_path_info_delete(dest, pi);
6335 bgp_process(bgp, dest, afi, safi);
6336 }
6337 }
6338 }
6339 }
6340
6341 /*
6342 * Purge all networks and redistributed routes from routing table.
6343 * Invoked upon the instance going down.
6344 */
6345 void bgp_purge_static_redist_routes(struct bgp *bgp)
6346 {
6347 afi_t afi;
6348 safi_t safi;
6349
6350 FOREACH_AFI_SAFI (afi, safi)
6351 bgp_purge_af_static_redist_routes(bgp, afi, safi);
6352 }
6353
6354 /*
6355 * gpz 110624
6356 * Currently this is used to set static routes for VPN and ENCAP.
6357 * I think it can probably be factored with bgp_static_set.
6358 */
6359 int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
6360 const char *ip_str, const char *rd_str,
6361 const char *label_str, const char *rmap_str,
6362 int evpn_type, const char *esi, const char *gwip,
6363 const char *ethtag, const char *routermac)
6364 {
6365 VTY_DECLVAR_CONTEXT(bgp, bgp);
6366 int ret;
6367 struct prefix p;
6368 struct prefix_rd prd;
6369 struct bgp_dest *pdest;
6370 struct bgp_dest *dest;
6371 struct bgp_table *table;
6372 struct bgp_static *bgp_static;
6373 mpls_label_t label = MPLS_INVALID_LABEL;
6374 struct prefix gw_ip;
6375
6376 /* validate ip prefix */
6377 ret = str2prefix(ip_str, &p);
6378 if (!ret) {
6379 vty_out(vty, "%% Malformed prefix\n");
6380 return CMD_WARNING_CONFIG_FAILED;
6381 }
6382 apply_mask(&p);
6383 if ((afi == AFI_L2VPN)
6384 && (bgp_build_evpn_prefix(evpn_type,
6385 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6386 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6387 return CMD_WARNING_CONFIG_FAILED;
6388 }
6389
6390 ret = str2prefix_rd(rd_str, &prd);
6391 if (!ret) {
6392 vty_out(vty, "%% Malformed rd\n");
6393 return CMD_WARNING_CONFIG_FAILED;
6394 }
6395
6396 if (label_str) {
6397 unsigned long label_val;
6398 label_val = strtoul(label_str, NULL, 10);
6399 encode_label(label_val, &label);
6400 }
6401
6402 if (safi == SAFI_EVPN) {
6403 if (esi && str2esi(esi, NULL) == 0) {
6404 vty_out(vty, "%% Malformed ESI\n");
6405 return CMD_WARNING_CONFIG_FAILED;
6406 }
6407 if (routermac && prefix_str2mac(routermac, NULL) == 0) {
6408 vty_out(vty, "%% Malformed Router MAC\n");
6409 return CMD_WARNING_CONFIG_FAILED;
6410 }
6411 if (gwip) {
6412 memset(&gw_ip, 0, sizeof(struct prefix));
6413 ret = str2prefix(gwip, &gw_ip);
6414 if (!ret) {
6415 vty_out(vty, "%% Malformed GatewayIp\n");
6416 return CMD_WARNING_CONFIG_FAILED;
6417 }
6418 if ((gw_ip.family == AF_INET
6419 && is_evpn_prefix_ipaddr_v6(
6420 (struct prefix_evpn *)&p))
6421 || (gw_ip.family == AF_INET6
6422 && is_evpn_prefix_ipaddr_v4(
6423 (struct prefix_evpn *)&p))) {
6424 vty_out(vty,
6425 "%% GatewayIp family differs with IP prefix\n");
6426 return CMD_WARNING_CONFIG_FAILED;
6427 }
6428 }
6429 }
6430 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6431 if (!bgp_dest_has_bgp_path_info_data(pdest))
6432 bgp_dest_set_bgp_table_info(pdest,
6433 bgp_table_init(bgp, afi, safi));
6434 table = bgp_dest_get_bgp_table_info(pdest);
6435
6436 dest = bgp_node_get(table, &p);
6437
6438 if (bgp_dest_has_bgp_path_info_data(dest)) {
6439 vty_out(vty, "%% Same network configuration exists\n");
6440 bgp_dest_unlock_node(dest);
6441 } else {
6442 /* New configuration. */
6443 bgp_static = bgp_static_new();
6444 bgp_static->backdoor = 0;
6445 bgp_static->valid = 0;
6446 bgp_static->igpmetric = 0;
6447 bgp_static->igpnexthop.s_addr = INADDR_ANY;
6448 bgp_static->label = label;
6449 bgp_static->prd = prd;
6450
6451 if (rmap_str) {
6452 XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
6453 route_map_counter_decrement(bgp_static->rmap.map);
6454 bgp_static->rmap.name =
6455 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
6456 bgp_static->rmap.map =
6457 route_map_lookup_by_name(rmap_str);
6458 route_map_counter_increment(bgp_static->rmap.map);
6459 }
6460
6461 if (safi == SAFI_EVPN) {
6462 if (esi) {
6463 bgp_static->eth_s_id =
6464 XCALLOC(MTYPE_ATTR,
6465 sizeof(esi_t));
6466 str2esi(esi, bgp_static->eth_s_id);
6467 }
6468 if (routermac) {
6469 bgp_static->router_mac =
6470 XCALLOC(MTYPE_ATTR, ETH_ALEN + 1);
6471 (void)prefix_str2mac(routermac,
6472 bgp_static->router_mac);
6473 }
6474 if (gwip)
6475 prefix_copy(&bgp_static->gatewayIp, &gw_ip);
6476 }
6477 bgp_dest_set_bgp_static_info(dest, bgp_static);
6478
6479 bgp_static->valid = 1;
6480 bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
6481 }
6482
6483 return CMD_SUCCESS;
6484 }
6485
6486 /* Configure static BGP network. */
6487 int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
6488 const char *ip_str, const char *rd_str,
6489 const char *label_str, int evpn_type, const char *esi,
6490 const char *gwip, const char *ethtag)
6491 {
6492 VTY_DECLVAR_CONTEXT(bgp, bgp);
6493 int ret;
6494 struct prefix p;
6495 struct prefix_rd prd;
6496 struct bgp_dest *pdest;
6497 struct bgp_dest *dest;
6498 struct bgp_table *table;
6499 struct bgp_static *bgp_static;
6500 mpls_label_t label = MPLS_INVALID_LABEL;
6501
6502 /* Convert IP prefix string to struct prefix. */
6503 ret = str2prefix(ip_str, &p);
6504 if (!ret) {
6505 vty_out(vty, "%% Malformed prefix\n");
6506 return CMD_WARNING_CONFIG_FAILED;
6507 }
6508 apply_mask(&p);
6509 if ((afi == AFI_L2VPN)
6510 && (bgp_build_evpn_prefix(evpn_type,
6511 ethtag != NULL ? atol(ethtag) : 0, &p))) {
6512 vty_out(vty, "%% L2VPN prefix could not be forged\n");
6513 return CMD_WARNING_CONFIG_FAILED;
6514 }
6515 ret = str2prefix_rd(rd_str, &prd);
6516 if (!ret) {
6517 vty_out(vty, "%% Malformed rd\n");
6518 return CMD_WARNING_CONFIG_FAILED;
6519 }
6520
6521 if (label_str) {
6522 unsigned long label_val;
6523 label_val = strtoul(label_str, NULL, 10);
6524 encode_label(label_val, &label);
6525 }
6526
6527 pdest = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
6528 if (!bgp_dest_has_bgp_path_info_data(pdest))
6529 bgp_dest_set_bgp_table_info(pdest,
6530 bgp_table_init(bgp, afi, safi));
6531 else
6532 bgp_dest_unlock_node(pdest);
6533 table = bgp_dest_get_bgp_table_info(pdest);
6534
6535 dest = bgp_node_lookup(table, &p);
6536
6537 if (dest) {
6538 bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
6539
6540 bgp_static = bgp_dest_get_bgp_static_info(dest);
6541 bgp_static_free(bgp_static);
6542 bgp_dest_set_bgp_static_info(dest, NULL);
6543 bgp_dest_unlock_node(dest);
6544 bgp_dest_unlock_node(dest);
6545 } else
6546 vty_out(vty, "%% Can't find the route\n");
6547
6548 return CMD_SUCCESS;
6549 }
6550
6551 static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
6552 const char *rmap_name)
6553 {
6554 VTY_DECLVAR_CONTEXT(bgp, bgp);
6555 struct bgp_rmap *rmap;
6556
6557 rmap = &bgp->table_map[afi][safi];
6558 if (rmap_name) {
6559 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6560 route_map_counter_decrement(rmap->map);
6561 rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
6562 rmap->map = route_map_lookup_by_name(rmap_name);
6563 route_map_counter_increment(rmap->map);
6564 } else {
6565 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6566 route_map_counter_decrement(rmap->map);
6567 rmap->map = NULL;
6568 }
6569
6570 if (bgp_fibupd_safi(safi))
6571 bgp_zebra_announce_table(bgp, afi, safi);
6572
6573 return CMD_SUCCESS;
6574 }
6575
6576 static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
6577 const char *rmap_name)
6578 {
6579 VTY_DECLVAR_CONTEXT(bgp, bgp);
6580 struct bgp_rmap *rmap;
6581
6582 rmap = &bgp->table_map[afi][safi];
6583 XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
6584 route_map_counter_decrement(rmap->map);
6585 rmap->map = NULL;
6586
6587 if (bgp_fibupd_safi(safi))
6588 bgp_zebra_announce_table(bgp, afi, safi);
6589
6590 return CMD_SUCCESS;
6591 }
6592
6593 void bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
6594 safi_t safi)
6595 {
6596 if (bgp->table_map[afi][safi].name) {
6597 vty_out(vty, " table-map %s\n",
6598 bgp->table_map[afi][safi].name);
6599 }
6600 }
6601
6602 DEFUN (bgp_table_map,
6603 bgp_table_map_cmd,
6604 "table-map WORD",
6605 "BGP table to RIB route download filter\n"
6606 "Name of the route map\n")
6607 {
6608 int idx_word = 1;
6609 return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6610 argv[idx_word]->arg);
6611 }
6612 DEFUN (no_bgp_table_map,
6613 no_bgp_table_map_cmd,
6614 "no table-map WORD",
6615 NO_STR
6616 "BGP table to RIB route download filter\n"
6617 "Name of the route map\n")
6618 {
6619 int idx_word = 2;
6620 return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
6621 argv[idx_word]->arg);
6622 }
6623
6624 DEFPY(bgp_network,
6625 bgp_network_cmd,
6626 "[no] network \
6627 <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
6628 [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
6629 backdoor$backdoor}]",
6630 NO_STR
6631 "Specify a network to announce via BGP\n"
6632 "IPv4 prefix\n"
6633 "Network number\n"
6634 "Network mask\n"
6635 "Network mask\n"
6636 "Route-map to modify the attributes\n"
6637 "Name of the route map\n"
6638 "Label index to associate with the prefix\n"
6639 "Label index value\n"
6640 "Specify a BGP backdoor route\n")
6641 {
6642 char addr_prefix_str[BUFSIZ];
6643
6644 if (address_str) {
6645 int ret;
6646
6647 ret = netmask_str2prefix_str(address_str, netmask_str,
6648 addr_prefix_str,
6649 sizeof(addr_prefix_str));
6650 if (!ret) {
6651 vty_out(vty, "%% Inconsistent address and mask\n");
6652 return CMD_WARNING_CONFIG_FAILED;
6653 }
6654 }
6655
6656 return bgp_static_set(
6657 vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
6658 bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
6659 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6660 }
6661
6662 DEFPY(ipv6_bgp_network,
6663 ipv6_bgp_network_cmd,
6664 "[no] network X:X::X:X/M$prefix \
6665 [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
6666 NO_STR
6667 "Specify a network to announce via BGP\n"
6668 "IPv6 prefix\n"
6669 "Route-map to modify the attributes\n"
6670 "Name of the route map\n"
6671 "Label index to associate with the prefix\n"
6672 "Label index value\n")
6673 {
6674 return bgp_static_set(
6675 vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
6676 label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
6677 }
6678
6679 static struct bgp_aggregate *bgp_aggregate_new(void)
6680 {
6681 return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
6682 }
6683
6684 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
6685 {
6686 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
6687 route_map_counter_decrement(aggregate->suppress_map);
6688 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
6689 route_map_counter_decrement(aggregate->rmap.map);
6690 XFREE(MTYPE_BGP_AGGREGATE, aggregate);
6691 }
6692
6693 /**
6694 * Helper function to avoid repeated code: prepare variables for a
6695 * `route_map_apply` call.
6696 *
6697 * \returns `true` on route map match, otherwise `false`.
6698 */
6699 static bool aggr_suppress_map_test(struct bgp *bgp,
6700 struct bgp_aggregate *aggregate,
6701 struct bgp_path_info *pi)
6702 {
6703 const struct prefix *p = bgp_dest_get_prefix(pi->net);
6704 route_map_result_t rmr = RMAP_DENYMATCH;
6705 struct bgp_path_info rmap_path = {};
6706 struct attr attr = {};
6707
6708 /* No route map entries created, just don't match. */
6709 if (aggregate->suppress_map == NULL)
6710 return false;
6711
6712 /* Call route map matching and return result. */
6713 attr.aspath = aspath_empty();
6714 rmap_path.peer = bgp->peer_self;
6715 rmap_path.attr = &attr;
6716
6717 SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
6718 rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
6719 bgp->peer_self->rmap_type = 0;
6720
6721 bgp_attr_flush(&attr);
6722
6723 return rmr == RMAP_PERMITMATCH;
6724 }
6725
6726 /** Test whether the aggregation has suppressed this path or not. */
6727 static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
6728 struct bgp_path_info *pi)
6729 {
6730 if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
6731 return false;
6732
6733 return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
6734 }
6735
6736 /**
6737 * Suppress this path and keep the reference.
6738 *
6739 * \returns `true` if needs processing otherwise `false`.
6740 */
6741 static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
6742 struct bgp_path_info *pi)
6743 {
6744 struct bgp_path_info_extra *pie;
6745
6746 /* Path is already suppressed by this aggregation. */
6747 if (aggr_suppress_exists(aggregate, pi))
6748 return false;
6749
6750 pie = bgp_path_info_extra_get(pi);
6751
6752 /* This is the first suppression, allocate memory and list it. */
6753 if (pie->aggr_suppressors == NULL)
6754 pie->aggr_suppressors = list_new();
6755
6756 listnode_add(pie->aggr_suppressors, aggregate);
6757
6758 /* Only mark for processing if suppressed. */
6759 if (listcount(pie->aggr_suppressors) == 1) {
6760 if (BGP_DEBUG(update, UPDATE_OUT))
6761 zlog_debug("aggregate-address suppressing: %pFX",
6762 bgp_dest_get_prefix(pi->net));
6763
6764 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6765 return true;
6766 }
6767
6768 return false;
6769 }
6770
6771 /**
6772 * Unsuppress this path and remove the reference.
6773 *
6774 * \returns `true` if needs processing otherwise `false`.
6775 */
6776 static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
6777 struct bgp_path_info *pi)
6778 {
6779 /* Path wasn't suppressed. */
6780 if (!aggr_suppress_exists(aggregate, pi))
6781 return false;
6782
6783 listnode_delete(pi->extra->aggr_suppressors, aggregate);
6784
6785 /* Unsuppress and free extra memory if last item. */
6786 if (listcount(pi->extra->aggr_suppressors) == 0) {
6787 if (BGP_DEBUG(update, UPDATE_OUT))
6788 zlog_debug("aggregate-address unsuppressing: %pFX",
6789 bgp_dest_get_prefix(pi->net));
6790
6791 list_delete(&pi->extra->aggr_suppressors);
6792 bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
6793 return true;
6794 }
6795
6796 return false;
6797 }
6798
6799 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
6800 struct aspath *aspath,
6801 struct community *comm,
6802 struct ecommunity *ecomm,
6803 struct lcommunity *lcomm)
6804 {
6805 static struct aspath *ae = NULL;
6806
6807 if (!ae)
6808 ae = aspath_empty();
6809
6810 if (!pi)
6811 return false;
6812
6813 if (origin != pi->attr->origin)
6814 return false;
6815
6816 if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae))
6817 return false;
6818
6819 if (!community_cmp(pi->attr->community, comm))
6820 return false;
6821
6822 if (!ecommunity_cmp(pi->attr->ecommunity, ecomm))
6823 return false;
6824
6825 if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
6826 return false;
6827
6828 if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
6829 return false;
6830
6831 return true;
6832 }
6833
6834 static void bgp_aggregate_install(
6835 struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p,
6836 uint8_t origin, struct aspath *aspath, struct community *community,
6837 struct ecommunity *ecommunity, struct lcommunity *lcommunity,
6838 uint8_t atomic_aggregate, struct bgp_aggregate *aggregate)
6839 {
6840 struct bgp_dest *dest;
6841 struct bgp_table *table;
6842 struct bgp_path_info *pi, *orig, *new;
6843 struct attr *attr;
6844
6845 table = bgp->rib[afi][safi];
6846
6847 dest = bgp_node_get(table, p);
6848
6849 for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
6850 if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP
6851 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6852 break;
6853
6854 /*
6855 * If we have paths with different MEDs, then don't install
6856 * (or uninstall) the aggregate route.
6857 */
6858 if (aggregate->match_med && aggregate->med_mismatched)
6859 goto uninstall_aggregate_route;
6860
6861 if (aggregate->count > 0) {
6862 /*
6863 * If the aggregate information has not changed
6864 * no need to re-install it again.
6865 */
6866 if (bgp_aggregate_info_same(orig, origin, aspath, community,
6867 ecommunity, lcommunity)) {
6868 bgp_dest_unlock_node(dest);
6869
6870 if (aspath)
6871 aspath_free(aspath);
6872 if (community)
6873 community_free(&community);
6874 if (ecommunity)
6875 ecommunity_free(&ecommunity);
6876 if (lcommunity)
6877 lcommunity_free(&lcommunity);
6878
6879 return;
6880 }
6881
6882 /*
6883 * Mark the old as unusable
6884 */
6885 if (pi)
6886 bgp_path_info_delete(dest, pi);
6887
6888 attr = bgp_attr_aggregate_intern(
6889 bgp, origin, aspath, community, ecommunity, lcommunity,
6890 aggregate, atomic_aggregate, p);
6891
6892 if (!attr) {
6893 bgp_aggregate_delete(bgp, p, afi, safi, aggregate);
6894 if (BGP_DEBUG(update_groups, UPDATE_GROUPS))
6895 zlog_debug("%s: %pFX null attribute", __func__,
6896 p);
6897 return;
6898 }
6899
6900 new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0,
6901 bgp->peer_self, attr, dest);
6902
6903 SET_FLAG(new->flags, BGP_PATH_VALID);
6904
6905 bgp_path_info_add(dest, new);
6906 bgp_process(bgp, dest, afi, safi);
6907 } else {
6908 uninstall_aggregate_route:
6909 for (pi = orig; pi; pi = pi->next)
6910 if (pi->peer == bgp->peer_self
6911 && pi->type == ZEBRA_ROUTE_BGP
6912 && pi->sub_type == BGP_ROUTE_AGGREGATE)
6913 break;
6914
6915 /* Withdraw static BGP route from routing table. */
6916 if (pi) {
6917 bgp_path_info_delete(dest, pi);
6918 bgp_process(bgp, dest, afi, safi);
6919 }
6920 }
6921
6922 bgp_dest_unlock_node(dest);
6923 }
6924
6925 /**
6926 * Check if the current path has different MED than other known paths.
6927 *
6928 * \returns `true` if the MED matched the others else `false`.
6929 */
6930 static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
6931 struct bgp *bgp, struct bgp_path_info *pi)
6932 {
6933 uint32_t cur_med = bgp_med_value(pi->attr, bgp);
6934
6935 /* This is the first route being analyzed. */
6936 if (!aggregate->med_initialized) {
6937 aggregate->med_initialized = true;
6938 aggregate->med_mismatched = false;
6939 aggregate->med_matched_value = cur_med;
6940 } else {
6941 /* Check if routes with different MED showed up. */
6942 if (cur_med != aggregate->med_matched_value)
6943 aggregate->med_mismatched = true;
6944 }
6945
6946 return !aggregate->med_mismatched;
6947 }
6948
6949 /**
6950 * Initializes and tests all routes in the aggregate address path for MED
6951 * values.
6952 *
6953 * \returns `true` if all MEDs are the same otherwise `false`.
6954 */
6955 static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
6956 struct bgp *bgp, const struct prefix *p,
6957 afi_t afi, safi_t safi)
6958 {
6959 struct bgp_table *table = bgp->rib[afi][safi];
6960 const struct prefix *dest_p;
6961 struct bgp_dest *dest, *top;
6962 struct bgp_path_info *pi;
6963 bool med_matched = true;
6964
6965 aggregate->med_initialized = false;
6966
6967 top = bgp_node_get(table, p);
6968 for (dest = bgp_node_get(table, p); dest;
6969 dest = bgp_route_next_until(dest, top)) {
6970 dest_p = bgp_dest_get_prefix(dest);
6971 if (dest_p->prefixlen <= p->prefixlen)
6972 continue;
6973
6974 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
6975 if (BGP_PATH_HOLDDOWN(pi))
6976 continue;
6977 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
6978 continue;
6979 if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
6980 med_matched = false;
6981 break;
6982 }
6983 }
6984 if (!med_matched)
6985 break;
6986 }
6987 bgp_dest_unlock_node(top);
6988
6989 return med_matched;
6990 }
6991
6992 /**
6993 * Toggles the route suppression status for this aggregate address
6994 * configuration.
6995 */
6996 void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
6997 struct bgp *bgp, const struct prefix *p,
6998 afi_t afi, safi_t safi, bool suppress)
6999 {
7000 struct bgp_table *table = bgp->rib[afi][safi];
7001 const struct prefix *dest_p;
7002 struct bgp_dest *dest, *top;
7003 struct bgp_path_info *pi;
7004 bool toggle_suppression;
7005
7006 /* We've found a different MED we must revert any suppressed routes. */
7007 top = bgp_node_get(table, p);
7008 for (dest = bgp_node_get(table, p); dest;
7009 dest = bgp_route_next_until(dest, top)) {
7010 dest_p = bgp_dest_get_prefix(dest);
7011 if (dest_p->prefixlen <= p->prefixlen)
7012 continue;
7013
7014 toggle_suppression = false;
7015 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7016 if (BGP_PATH_HOLDDOWN(pi))
7017 continue;
7018 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7019 continue;
7020
7021 /* We are toggling suppression back. */
7022 if (suppress) {
7023 /* Suppress route if not suppressed already. */
7024 if (aggr_suppress_path(aggregate, pi))
7025 toggle_suppression = true;
7026 continue;
7027 }
7028
7029 /* Install route if there is no more suppression. */
7030 if (aggr_unsuppress_path(aggregate, pi))
7031 toggle_suppression = true;
7032 }
7033
7034 if (toggle_suppression)
7035 bgp_process(bgp, dest, afi, safi);
7036 }
7037 bgp_dest_unlock_node(top);
7038 }
7039
7040 /**
7041 * Aggregate address MED matching incremental test: this function is called
7042 * when the initial aggregation occurred and we are only testing a single
7043 * new path.
7044 *
7045 * In addition to testing and setting the MED validity it also installs back
7046 * suppressed routes (if summary is configured).
7047 *
7048 * Must not be called in `bgp_aggregate_route`.
7049 */
7050 static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
7051 struct bgp *bgp, const struct prefix *p,
7052 afi_t afi, safi_t safi,
7053 struct bgp_path_info *pi, bool is_adding)
7054 {
7055 /* MED matching disabled. */
7056 if (!aggregate->match_med)
7057 return;
7058
7059 /* Aggregation with different MED, nothing to do. */
7060 if (aggregate->med_mismatched)
7061 return;
7062
7063 /*
7064 * Test the current entry:
7065 *
7066 * is_adding == true: if the new entry doesn't match then we must
7067 * install all suppressed routes.
7068 *
7069 * is_adding == false: if the entry being removed was the last
7070 * unmatching entry then we can suppress all routes.
7071 */
7072 if (!is_adding) {
7073 if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
7074 && aggregate->summary_only)
7075 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
7076 safi, true);
7077 } else
7078 bgp_aggregate_med_match(aggregate, bgp, pi);
7079
7080 /* No mismatches, just quit. */
7081 if (!aggregate->med_mismatched)
7082 return;
7083
7084 /* Route summarization is disabled. */
7085 if (!aggregate->summary_only)
7086 return;
7087
7088 bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
7089 }
7090
7091 /* Update an aggregate as routes are added/removed from the BGP table */
7092 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
7093 safi_t safi, struct bgp_aggregate *aggregate)
7094 {
7095 struct bgp_table *table;
7096 struct bgp_dest *top;
7097 struct bgp_dest *dest;
7098 uint8_t origin;
7099 struct aspath *aspath = NULL;
7100 struct community *community = NULL;
7101 struct ecommunity *ecommunity = NULL;
7102 struct lcommunity *lcommunity = NULL;
7103 struct bgp_path_info *pi;
7104 unsigned long match = 0;
7105 uint8_t atomic_aggregate = 0;
7106
7107 /* If the bgp instance is being deleted or self peer is deleted
7108 * then do not create aggregate route
7109 */
7110 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7111 || (bgp->peer_self == NULL))
7112 return;
7113
7114 /* Initialize and test routes for MED difference. */
7115 if (aggregate->match_med)
7116 bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
7117
7118 /*
7119 * Reset aggregate count: we might've been called from route map
7120 * update so in that case we must retest all more specific routes.
7121 *
7122 * \see `bgp_route_map_process_update`.
7123 */
7124 aggregate->count = 0;
7125 aggregate->incomplete_origin_count = 0;
7126 aggregate->incomplete_origin_count = 0;
7127 aggregate->egp_origin_count = 0;
7128
7129 /* ORIGIN attribute: If at least one route among routes that are
7130 aggregated has ORIGIN with the value INCOMPLETE, then the
7131 aggregated route must have the ORIGIN attribute with the value
7132 INCOMPLETE. Otherwise, if at least one route among routes that
7133 are aggregated has ORIGIN with the value EGP, then the aggregated
7134 route must have the origin attribute with the value EGP. In all
7135 other case the value of the ORIGIN attribute of the aggregated
7136 route is INTERNAL. */
7137 origin = BGP_ORIGIN_IGP;
7138
7139 table = bgp->rib[afi][safi];
7140
7141 top = bgp_node_get(table, p);
7142 for (dest = bgp_node_get(table, p); dest;
7143 dest = bgp_route_next_until(dest, top)) {
7144 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7145
7146 if (dest_p->prefixlen <= p->prefixlen)
7147 continue;
7148
7149 /* If suppress fib is enabled and route not installed
7150 * in FIB, skip the route
7151 */
7152 if (!bgp_check_advertise(bgp, dest))
7153 continue;
7154
7155 match = 0;
7156
7157 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7158 if (BGP_PATH_HOLDDOWN(pi))
7159 continue;
7160
7161 if (pi->attr->flag
7162 & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
7163 atomic_aggregate = 1;
7164
7165 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7166 continue;
7167
7168 /*
7169 * summary-only aggregate route suppress
7170 * aggregated route announcements.
7171 *
7172 * MED matching:
7173 * Don't create summaries if MED didn't match
7174 * otherwise neither the specific routes and the
7175 * aggregation will be announced.
7176 */
7177 if (aggregate->summary_only
7178 && AGGREGATE_MED_VALID(aggregate)) {
7179 if (aggr_suppress_path(aggregate, pi))
7180 match++;
7181 }
7182
7183 /*
7184 * Suppress more specific routes that match the route
7185 * map results.
7186 *
7187 * MED matching:
7188 * Don't suppress routes if MED matching is enabled and
7189 * it mismatched otherwise we might end up with no
7190 * routes for this path.
7191 */
7192 if (aggregate->suppress_map_name
7193 && AGGREGATE_MED_VALID(aggregate)
7194 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7195 if (aggr_suppress_path(aggregate, pi))
7196 match++;
7197 }
7198
7199 aggregate->count++;
7200
7201 /*
7202 * If at least one route among routes that are
7203 * aggregated has ORIGIN with the value INCOMPLETE,
7204 * then the aggregated route MUST have the ORIGIN
7205 * attribute with the value INCOMPLETE. Otherwise, if
7206 * at least one route among routes that are aggregated
7207 * has ORIGIN with the value EGP, then the aggregated
7208 * route MUST have the ORIGIN attribute with the value
7209 * EGP.
7210 */
7211 switch (pi->attr->origin) {
7212 case BGP_ORIGIN_INCOMPLETE:
7213 aggregate->incomplete_origin_count++;
7214 break;
7215 case BGP_ORIGIN_EGP:
7216 aggregate->egp_origin_count++;
7217 break;
7218 default:
7219 /*Do nothing.
7220 */
7221 break;
7222 }
7223
7224 if (!aggregate->as_set)
7225 continue;
7226
7227 /*
7228 * as-set aggregate route generate origin, as path,
7229 * and community aggregation.
7230 */
7231 /* Compute aggregate route's as-path.
7232 */
7233 bgp_compute_aggregate_aspath_hash(aggregate,
7234 pi->attr->aspath);
7235
7236 /* Compute aggregate route's community.
7237 */
7238 if (pi->attr->community)
7239 bgp_compute_aggregate_community_hash(
7240 aggregate,
7241 pi->attr->community);
7242
7243 /* Compute aggregate route's extended community.
7244 */
7245 if (pi->attr->ecommunity)
7246 bgp_compute_aggregate_ecommunity_hash(
7247 aggregate,
7248 pi->attr->ecommunity);
7249
7250 /* Compute aggregate route's large community.
7251 */
7252 if (pi->attr->lcommunity)
7253 bgp_compute_aggregate_lcommunity_hash(
7254 aggregate,
7255 pi->attr->lcommunity);
7256 }
7257 if (match)
7258 bgp_process(bgp, dest, afi, safi);
7259 }
7260 if (aggregate->as_set) {
7261 bgp_compute_aggregate_aspath_val(aggregate);
7262 bgp_compute_aggregate_community_val(aggregate);
7263 bgp_compute_aggregate_ecommunity_val(aggregate);
7264 bgp_compute_aggregate_lcommunity_val(aggregate);
7265 }
7266
7267
7268 bgp_dest_unlock_node(top);
7269
7270
7271 if (aggregate->incomplete_origin_count > 0)
7272 origin = BGP_ORIGIN_INCOMPLETE;
7273 else if (aggregate->egp_origin_count > 0)
7274 origin = BGP_ORIGIN_EGP;
7275
7276 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7277 origin = aggregate->origin;
7278
7279 if (aggregate->as_set) {
7280 if (aggregate->aspath)
7281 /* Retrieve aggregate route's as-path.
7282 */
7283 aspath = aspath_dup(aggregate->aspath);
7284
7285 if (aggregate->community)
7286 /* Retrieve aggregate route's community.
7287 */
7288 community = community_dup(aggregate->community);
7289
7290 if (aggregate->ecommunity)
7291 /* Retrieve aggregate route's ecommunity.
7292 */
7293 ecommunity = ecommunity_dup(aggregate->ecommunity);
7294
7295 if (aggregate->lcommunity)
7296 /* Retrieve aggregate route's lcommunity.
7297 */
7298 lcommunity = lcommunity_dup(aggregate->lcommunity);
7299 }
7300
7301 bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
7302 ecommunity, lcommunity, atomic_aggregate,
7303 aggregate);
7304 }
7305
7306 void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
7307 safi_t safi, struct bgp_aggregate *aggregate)
7308 {
7309 struct bgp_table *table;
7310 struct bgp_dest *top;
7311 struct bgp_dest *dest;
7312 struct bgp_path_info *pi;
7313 unsigned long match;
7314
7315 table = bgp->rib[afi][safi];
7316
7317 /* If routes exists below this node, generate aggregate routes. */
7318 top = bgp_node_get(table, p);
7319 for (dest = bgp_node_get(table, p); dest;
7320 dest = bgp_route_next_until(dest, top)) {
7321 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7322
7323 if (dest_p->prefixlen <= p->prefixlen)
7324 continue;
7325 match = 0;
7326
7327 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
7328 if (BGP_PATH_HOLDDOWN(pi))
7329 continue;
7330
7331 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7332 continue;
7333
7334 if (aggregate->summary_only && pi->extra
7335 && AGGREGATE_MED_VALID(aggregate)) {
7336 if (aggr_unsuppress_path(aggregate, pi))
7337 match++;
7338 }
7339
7340 if (aggregate->suppress_map_name
7341 && AGGREGATE_MED_VALID(aggregate)
7342 && aggr_suppress_map_test(bgp, aggregate, pi)) {
7343 if (aggr_unsuppress_path(aggregate, pi))
7344 match++;
7345 }
7346
7347 aggregate->count--;
7348
7349 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7350 aggregate->incomplete_origin_count--;
7351 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7352 aggregate->egp_origin_count--;
7353
7354 if (aggregate->as_set) {
7355 /* Remove as-path from aggregate.
7356 */
7357 bgp_remove_aspath_from_aggregate_hash(
7358 aggregate,
7359 pi->attr->aspath);
7360
7361 if (pi->attr->community)
7362 /* Remove community from aggregate.
7363 */
7364 bgp_remove_comm_from_aggregate_hash(
7365 aggregate,
7366 pi->attr->community);
7367
7368 if (pi->attr->ecommunity)
7369 /* Remove ecommunity from aggregate.
7370 */
7371 bgp_remove_ecomm_from_aggregate_hash(
7372 aggregate,
7373 pi->attr->ecommunity);
7374
7375 if (pi->attr->lcommunity)
7376 /* Remove lcommunity from aggregate.
7377 */
7378 bgp_remove_lcomm_from_aggregate_hash(
7379 aggregate,
7380 pi->attr->lcommunity);
7381 }
7382 }
7383
7384 /* If this node was suppressed, process the change. */
7385 if (match)
7386 bgp_process(bgp, dest, afi, safi);
7387 }
7388 if (aggregate->as_set) {
7389 aspath_free(aggregate->aspath);
7390 aggregate->aspath = NULL;
7391 if (aggregate->community)
7392 community_free(&aggregate->community);
7393 if (aggregate->ecommunity)
7394 ecommunity_free(&aggregate->ecommunity);
7395 if (aggregate->lcommunity)
7396 lcommunity_free(&aggregate->lcommunity);
7397 }
7398
7399 bgp_dest_unlock_node(top);
7400 }
7401
7402 static void bgp_add_route_to_aggregate(struct bgp *bgp,
7403 const struct prefix *aggr_p,
7404 struct bgp_path_info *pinew, afi_t afi,
7405 safi_t safi,
7406 struct bgp_aggregate *aggregate)
7407 {
7408 uint8_t origin;
7409 struct aspath *aspath = NULL;
7410 uint8_t atomic_aggregate = 0;
7411 struct community *community = NULL;
7412 struct ecommunity *ecommunity = NULL;
7413 struct lcommunity *lcommunity = NULL;
7414
7415 /* If the bgp instance is being deleted or self peer is deleted
7416 * then do not create aggregate route
7417 */
7418 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7419 || (bgp->peer_self == NULL))
7420 return;
7421
7422 /* ORIGIN attribute: If at least one route among routes that are
7423 * aggregated has ORIGIN with the value INCOMPLETE, then the
7424 * aggregated route must have the ORIGIN attribute with the value
7425 * INCOMPLETE. Otherwise, if at least one route among routes that
7426 * are aggregated has ORIGIN with the value EGP, then the aggregated
7427 * route must have the origin attribute with the value EGP. In all
7428 * other case the value of the ORIGIN attribute of the aggregated
7429 * route is INTERNAL.
7430 */
7431 origin = BGP_ORIGIN_IGP;
7432
7433 aggregate->count++;
7434
7435 /*
7436 * This must be called before `summary` check to avoid
7437 * "suppressing" twice.
7438 */
7439 if (aggregate->match_med)
7440 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
7441 pinew, true);
7442
7443 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7444 aggr_suppress_path(aggregate, pinew);
7445
7446 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7447 && aggr_suppress_map_test(bgp, aggregate, pinew))
7448 aggr_suppress_path(aggregate, pinew);
7449
7450 switch (pinew->attr->origin) {
7451 case BGP_ORIGIN_INCOMPLETE:
7452 aggregate->incomplete_origin_count++;
7453 break;
7454 case BGP_ORIGIN_EGP:
7455 aggregate->egp_origin_count++;
7456 break;
7457 default:
7458 /* Do nothing.
7459 */
7460 break;
7461 }
7462
7463 if (aggregate->incomplete_origin_count > 0)
7464 origin = BGP_ORIGIN_INCOMPLETE;
7465 else if (aggregate->egp_origin_count > 0)
7466 origin = BGP_ORIGIN_EGP;
7467
7468 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7469 origin = aggregate->origin;
7470
7471 if (aggregate->as_set) {
7472 /* Compute aggregate route's as-path.
7473 */
7474 bgp_compute_aggregate_aspath(aggregate,
7475 pinew->attr->aspath);
7476
7477 /* Compute aggregate route's community.
7478 */
7479 if (pinew->attr->community)
7480 bgp_compute_aggregate_community(
7481 aggregate,
7482 pinew->attr->community);
7483
7484 /* Compute aggregate route's extended community.
7485 */
7486 if (pinew->attr->ecommunity)
7487 bgp_compute_aggregate_ecommunity(
7488 aggregate,
7489 pinew->attr->ecommunity);
7490
7491 /* Compute aggregate route's large community.
7492 */
7493 if (pinew->attr->lcommunity)
7494 bgp_compute_aggregate_lcommunity(
7495 aggregate,
7496 pinew->attr->lcommunity);
7497
7498 /* Retrieve aggregate route's as-path.
7499 */
7500 if (aggregate->aspath)
7501 aspath = aspath_dup(aggregate->aspath);
7502
7503 /* Retrieve aggregate route's community.
7504 */
7505 if (aggregate->community)
7506 community = community_dup(aggregate->community);
7507
7508 /* Retrieve aggregate route's ecommunity.
7509 */
7510 if (aggregate->ecommunity)
7511 ecommunity = ecommunity_dup(aggregate->ecommunity);
7512
7513 /* Retrieve aggregate route's lcommunity.
7514 */
7515 if (aggregate->lcommunity)
7516 lcommunity = lcommunity_dup(aggregate->lcommunity);
7517 }
7518
7519 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7520 aspath, community, ecommunity,
7521 lcommunity, atomic_aggregate, aggregate);
7522 }
7523
7524 static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
7525 safi_t safi,
7526 struct bgp_path_info *pi,
7527 struct bgp_aggregate *aggregate,
7528 const struct prefix *aggr_p)
7529 {
7530 uint8_t origin;
7531 struct aspath *aspath = NULL;
7532 uint8_t atomic_aggregate = 0;
7533 struct community *community = NULL;
7534 struct ecommunity *ecommunity = NULL;
7535 struct lcommunity *lcommunity = NULL;
7536 unsigned long match = 0;
7537
7538 /* If the bgp instance is being deleted or self peer is deleted
7539 * then do not create aggregate route
7540 */
7541 if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)
7542 || (bgp->peer_self == NULL))
7543 return;
7544
7545 if (BGP_PATH_HOLDDOWN(pi))
7546 return;
7547
7548 if (pi->sub_type == BGP_ROUTE_AGGREGATE)
7549 return;
7550
7551 if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
7552 if (aggr_unsuppress_path(aggregate, pi))
7553 match++;
7554
7555 if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
7556 && aggr_suppress_map_test(bgp, aggregate, pi))
7557 if (aggr_unsuppress_path(aggregate, pi))
7558 match++;
7559
7560 /*
7561 * This must be called after `summary`, `suppress-map` check to avoid
7562 * "unsuppressing" twice.
7563 */
7564 if (aggregate->match_med)
7565 bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
7566 true);
7567
7568 if (aggregate->count > 0)
7569 aggregate->count--;
7570
7571 if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
7572 aggregate->incomplete_origin_count--;
7573 else if (pi->attr->origin == BGP_ORIGIN_EGP)
7574 aggregate->egp_origin_count--;
7575
7576 if (aggregate->as_set) {
7577 /* Remove as-path from aggregate.
7578 */
7579 bgp_remove_aspath_from_aggregate(aggregate,
7580 pi->attr->aspath);
7581
7582 if (pi->attr->community)
7583 /* Remove community from aggregate.
7584 */
7585 bgp_remove_community_from_aggregate(
7586 aggregate,
7587 pi->attr->community);
7588
7589 if (pi->attr->ecommunity)
7590 /* Remove ecommunity from aggregate.
7591 */
7592 bgp_remove_ecommunity_from_aggregate(
7593 aggregate,
7594 pi->attr->ecommunity);
7595
7596 if (pi->attr->lcommunity)
7597 /* Remove lcommunity from aggregate.
7598 */
7599 bgp_remove_lcommunity_from_aggregate(
7600 aggregate,
7601 pi->attr->lcommunity);
7602 }
7603
7604 /* If this node was suppressed, process the change. */
7605 if (match)
7606 bgp_process(bgp, pi->net, afi, safi);
7607
7608 origin = BGP_ORIGIN_IGP;
7609 if (aggregate->incomplete_origin_count > 0)
7610 origin = BGP_ORIGIN_INCOMPLETE;
7611 else if (aggregate->egp_origin_count > 0)
7612 origin = BGP_ORIGIN_EGP;
7613
7614 if (aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
7615 origin = aggregate->origin;
7616
7617 if (aggregate->as_set) {
7618 /* Retrieve aggregate route's as-path.
7619 */
7620 if (aggregate->aspath)
7621 aspath = aspath_dup(aggregate->aspath);
7622
7623 /* Retrieve aggregate route's community.
7624 */
7625 if (aggregate->community)
7626 community = community_dup(aggregate->community);
7627
7628 /* Retrieve aggregate route's ecommunity.
7629 */
7630 if (aggregate->ecommunity)
7631 ecommunity = ecommunity_dup(aggregate->ecommunity);
7632
7633 /* Retrieve aggregate route's lcommunity.
7634 */
7635 if (aggregate->lcommunity)
7636 lcommunity = lcommunity_dup(aggregate->lcommunity);
7637 }
7638
7639 bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
7640 aspath, community, ecommunity,
7641 lcommunity, atomic_aggregate, aggregate);
7642 }
7643
7644 void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
7645 struct bgp_path_info *pi, afi_t afi, safi_t safi)
7646 {
7647 struct bgp_dest *child;
7648 struct bgp_dest *dest;
7649 struct bgp_aggregate *aggregate;
7650 struct bgp_table *table;
7651
7652 table = bgp->aggregate[afi][safi];
7653
7654 /* No aggregates configured. */
7655 if (bgp_table_top_nolock(table) == NULL)
7656 return;
7657
7658 if (p->prefixlen == 0)
7659 return;
7660
7661 if (BGP_PATH_HOLDDOWN(pi))
7662 return;
7663
7664 /* If suppress fib is enabled and route not installed
7665 * in FIB, do not update the aggregate route
7666 */
7667 if (!bgp_check_advertise(bgp, pi->net))
7668 return;
7669
7670 child = bgp_node_get(table, p);
7671
7672 /* Aggregate address configuration check. */
7673 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7674 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7675
7676 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7677 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7678 bgp_add_route_to_aggregate(bgp, dest_p, pi, afi, safi,
7679 aggregate);
7680 }
7681 }
7682 bgp_dest_unlock_node(child);
7683 }
7684
7685 void bgp_aggregate_decrement(struct bgp *bgp, const struct prefix *p,
7686 struct bgp_path_info *del, afi_t afi, safi_t safi)
7687 {
7688 struct bgp_dest *child;
7689 struct bgp_dest *dest;
7690 struct bgp_aggregate *aggregate;
7691 struct bgp_table *table;
7692
7693 table = bgp->aggregate[afi][safi];
7694
7695 /* No aggregates configured. */
7696 if (bgp_table_top_nolock(table) == NULL)
7697 return;
7698
7699 if (p->prefixlen == 0)
7700 return;
7701
7702 child = bgp_node_get(table, p);
7703
7704 /* Aggregate address configuration check. */
7705 for (dest = child; dest; dest = bgp_dest_parent_nolock(dest)) {
7706 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
7707
7708 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7709 if (aggregate != NULL && dest_p->prefixlen < p->prefixlen) {
7710 bgp_remove_route_from_aggregate(bgp, afi, safi, del,
7711 aggregate, dest_p);
7712 }
7713 }
7714 bgp_dest_unlock_node(child);
7715 }
7716
7717 /* Aggregate route attribute. */
7718 #define AGGREGATE_SUMMARY_ONLY 1
7719 #define AGGREGATE_AS_SET 1
7720 #define AGGREGATE_AS_UNSET 0
7721
7722 static const char *bgp_origin2str(uint8_t origin)
7723 {
7724 switch (origin) {
7725 case BGP_ORIGIN_IGP:
7726 return "igp";
7727 case BGP_ORIGIN_EGP:
7728 return "egp";
7729 case BGP_ORIGIN_INCOMPLETE:
7730 return "incomplete";
7731 }
7732 return "n/a";
7733 }
7734
7735 static const char *bgp_rpki_validation2str(enum rpki_states v_state)
7736 {
7737 switch (v_state) {
7738 case RPKI_NOT_BEING_USED:
7739 return "not used";
7740 case RPKI_VALID:
7741 return "valid";
7742 case RPKI_NOTFOUND:
7743 return "not found";
7744 case RPKI_INVALID:
7745 return "invalid";
7746 }
7747
7748 assert(!"We should never get here this is a dev escape");
7749 return "ERROR";
7750 }
7751
7752 static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
7753 afi_t afi, safi_t safi)
7754 {
7755 VTY_DECLVAR_CONTEXT(bgp, bgp);
7756 int ret;
7757 struct prefix p;
7758 struct bgp_dest *dest;
7759 struct bgp_aggregate *aggregate;
7760
7761 /* Convert string to prefix structure. */
7762 ret = str2prefix(prefix_str, &p);
7763 if (!ret) {
7764 vty_out(vty, "Malformed prefix\n");
7765 return CMD_WARNING_CONFIG_FAILED;
7766 }
7767 apply_mask(&p);
7768
7769 /* Old configuration check. */
7770 dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
7771 if (!dest) {
7772 vty_out(vty,
7773 "%% There is no aggregate-address configuration.\n");
7774 return CMD_WARNING_CONFIG_FAILED;
7775 }
7776
7777 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7778 bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
7779 bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
7780 NULL, NULL, 0, aggregate);
7781
7782 /* Unlock aggregate address configuration. */
7783 bgp_dest_set_bgp_aggregate_info(dest, NULL);
7784
7785 if (aggregate->community)
7786 community_free(&aggregate->community);
7787
7788 if (aggregate->community_hash) {
7789 /* Delete all communities in the hash.
7790 */
7791 hash_clean(aggregate->community_hash,
7792 bgp_aggr_community_remove);
7793 /* Free up the community_hash.
7794 */
7795 hash_free(aggregate->community_hash);
7796 }
7797
7798 if (aggregate->ecommunity)
7799 ecommunity_free(&aggregate->ecommunity);
7800
7801 if (aggregate->ecommunity_hash) {
7802 /* Delete all ecommunities in the hash.
7803 */
7804 hash_clean(aggregate->ecommunity_hash,
7805 bgp_aggr_ecommunity_remove);
7806 /* Free up the ecommunity_hash.
7807 */
7808 hash_free(aggregate->ecommunity_hash);
7809 }
7810
7811 if (aggregate->lcommunity)
7812 lcommunity_free(&aggregate->lcommunity);
7813
7814 if (aggregate->lcommunity_hash) {
7815 /* Delete all lcommunities in the hash.
7816 */
7817 hash_clean(aggregate->lcommunity_hash,
7818 bgp_aggr_lcommunity_remove);
7819 /* Free up the lcommunity_hash.
7820 */
7821 hash_free(aggregate->lcommunity_hash);
7822 }
7823
7824 if (aggregate->aspath)
7825 aspath_free(aggregate->aspath);
7826
7827 if (aggregate->aspath_hash) {
7828 /* Delete all as-paths in the hash.
7829 */
7830 hash_clean(aggregate->aspath_hash,
7831 bgp_aggr_aspath_remove);
7832 /* Free up the aspath_hash.
7833 */
7834 hash_free(aggregate->aspath_hash);
7835 }
7836
7837 bgp_aggregate_free(aggregate);
7838 bgp_dest_unlock_node(dest);
7839 bgp_dest_unlock_node(dest);
7840
7841 return CMD_SUCCESS;
7842 }
7843
7844 static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
7845 safi_t safi, const char *rmap,
7846 uint8_t summary_only, uint8_t as_set,
7847 uint8_t origin, bool match_med,
7848 const char *suppress_map)
7849 {
7850 VTY_DECLVAR_CONTEXT(bgp, bgp);
7851 int ret;
7852 struct prefix p;
7853 struct bgp_dest *dest;
7854 struct bgp_aggregate *aggregate;
7855 uint8_t as_set_new = as_set;
7856
7857 if (suppress_map && summary_only) {
7858 vty_out(vty,
7859 "'summary-only' and 'suppress-map' can't be used at the same time\n");
7860 return CMD_WARNING_CONFIG_FAILED;
7861 }
7862
7863 /* Convert string to prefix structure. */
7864 ret = str2prefix(prefix_str, &p);
7865 if (!ret) {
7866 vty_out(vty, "Malformed prefix\n");
7867 return CMD_WARNING_CONFIG_FAILED;
7868 }
7869 apply_mask(&p);
7870
7871 if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
7872 (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
7873 vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
7874 prefix_str);
7875 return CMD_WARNING_CONFIG_FAILED;
7876 }
7877
7878 /* Old configuration check. */
7879 dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
7880 aggregate = bgp_dest_get_bgp_aggregate_info(dest);
7881
7882 if (aggregate) {
7883 vty_out(vty, "There is already same aggregate network.\n");
7884 /* try to remove the old entry */
7885 ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
7886 if (ret) {
7887 vty_out(vty, "Error deleting aggregate.\n");
7888 bgp_dest_unlock_node(dest);
7889 return CMD_WARNING_CONFIG_FAILED;
7890 }
7891 }
7892
7893 /* Make aggregate address structure. */
7894 aggregate = bgp_aggregate_new();
7895 aggregate->summary_only = summary_only;
7896 aggregate->match_med = match_med;
7897
7898 /* Network operators MUST NOT locally generate any new
7899 * announcements containing AS_SET or AS_CONFED_SET. If they have
7900 * announced routes with AS_SET or AS_CONFED_SET in them, then they
7901 * SHOULD withdraw those routes and re-announce routes for the
7902 * aggregate or component prefixes (i.e., the more-specific routes
7903 * subsumed by the previously aggregated route) without AS_SET
7904 * or AS_CONFED_SET in the updates.
7905 */
7906 if (bgp->reject_as_sets) {
7907 if (as_set == AGGREGATE_AS_SET) {
7908 as_set_new = AGGREGATE_AS_UNSET;
7909 zlog_warn(
7910 "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
7911 __func__);
7912 vty_out(vty,
7913 "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
7914 }
7915 }
7916
7917 aggregate->as_set = as_set_new;
7918 aggregate->safi = safi;
7919 /* Override ORIGIN attribute if defined.
7920 * E.g.: Cisco and Juniper set ORIGIN for aggregated address
7921 * to IGP which is not what rfc4271 says.
7922 * This enables the same behavior, optionally.
7923 */
7924 aggregate->origin = origin;
7925
7926 if (rmap) {
7927 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
7928 route_map_counter_decrement(aggregate->rmap.map);
7929 aggregate->rmap.name =
7930 XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
7931 aggregate->rmap.map = route_map_lookup_by_name(rmap);
7932 route_map_counter_increment(aggregate->rmap.map);
7933 }
7934
7935 if (suppress_map) {
7936 XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
7937 route_map_counter_decrement(aggregate->suppress_map);
7938
7939 aggregate->suppress_map_name =
7940 XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
7941 aggregate->suppress_map =
7942 route_map_lookup_by_name(aggregate->suppress_map_name);
7943 route_map_counter_increment(aggregate->suppress_map);
7944 }
7945
7946 bgp_dest_set_bgp_aggregate_info(dest, aggregate);
7947
7948 /* Aggregate address insert into BGP routing table. */
7949 bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
7950
7951 return CMD_SUCCESS;
7952 }
7953
7954 DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
7955 "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> [{"
7956 "as-set$as_set_s"
7957 "|summary-only$summary_only"
7958 "|route-map WORD$rmap_name"
7959 "|origin <egp|igp|incomplete>$origin_s"
7960 "|matching-MED-only$match_med"
7961 "|suppress-map WORD$suppress_map"
7962 "}]",
7963 NO_STR
7964 "Configure BGP aggregate entries\n"
7965 "Aggregate prefix\n" "Aggregate address\n" "Aggregate mask\n"
7966 "Generate AS set path information\n"
7967 "Filter more specific routes from updates\n"
7968 "Apply route map to aggregate network\n"
7969 "Route map name\n"
7970 "BGP origin code\n"
7971 "Remote EGP\n"
7972 "Local IGP\n"
7973 "Unknown heritage\n"
7974 "Only aggregate routes with matching MED\n"
7975 "Suppress the selected more specific routes\n"
7976 "Route map with the route selectors\n")
7977 {
7978 const char *prefix_s = NULL;
7979 safi_t safi = bgp_node_safi(vty);
7980 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
7981 int as_set = AGGREGATE_AS_UNSET;
7982 char prefix_buf[PREFIX2STR_BUFFER];
7983
7984 if (addr_str) {
7985 if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf,
7986 sizeof(prefix_buf))
7987 == 0) {
7988 vty_out(vty, "%% Inconsistent address and mask\n");
7989 return CMD_WARNING_CONFIG_FAILED;
7990 }
7991 prefix_s = prefix_buf;
7992 } else
7993 prefix_s = prefix_str;
7994
7995 if (origin_s) {
7996 if (strcmp(origin_s, "egp") == 0)
7997 origin = BGP_ORIGIN_EGP;
7998 else if (strcmp(origin_s, "igp") == 0)
7999 origin = BGP_ORIGIN_IGP;
8000 else if (strcmp(origin_s, "incomplete") == 0)
8001 origin = BGP_ORIGIN_INCOMPLETE;
8002 }
8003
8004 if (as_set_s)
8005 as_set = AGGREGATE_AS_SET;
8006
8007 /* Handle configuration removal, otherwise installation. */
8008 if (no)
8009 return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
8010
8011 return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
8012 summary_only != NULL, as_set, origin,
8013 match_med != NULL, suppress_map);
8014 }
8015
8016 DEFPY(aggregate_addressv6, aggregate_addressv6_cmd,
8017 "[no] aggregate-address X:X::X:X/M$prefix [{"
8018 "as-set$as_set_s"
8019 "|summary-only$summary_only"
8020 "|route-map WORD$rmap_name"
8021 "|origin <egp|igp|incomplete>$origin_s"
8022 "|matching-MED-only$match_med"
8023 "|suppress-map WORD$suppress_map"
8024 "}]",
8025 NO_STR
8026 "Configure BGP aggregate entries\n"
8027 "Aggregate prefix\n"
8028 "Generate AS set path information\n"
8029 "Filter more specific routes from updates\n"
8030 "Apply route map to aggregate network\n"
8031 "Route map name\n"
8032 "BGP origin code\n"
8033 "Remote EGP\n"
8034 "Local IGP\n"
8035 "Unknown heritage\n"
8036 "Only aggregate routes with matching MED\n"
8037 "Suppress the selected more specific routes\n"
8038 "Route map with the route selectors\n")
8039 {
8040 uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
8041 int as_set = AGGREGATE_AS_UNSET;
8042
8043 if (origin_s) {
8044 if (strcmp(origin_s, "egp") == 0)
8045 origin = BGP_ORIGIN_EGP;
8046 else if (strcmp(origin_s, "igp") == 0)
8047 origin = BGP_ORIGIN_IGP;
8048 else if (strcmp(origin_s, "incomplete") == 0)
8049 origin = BGP_ORIGIN_INCOMPLETE;
8050 }
8051
8052 if (as_set_s)
8053 as_set = AGGREGATE_AS_SET;
8054
8055 /* Handle configuration removal, otherwise installation. */
8056 if (no)
8057 return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
8058 SAFI_UNICAST);
8059
8060 return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
8061 rmap_name, summary_only != NULL, as_set,
8062 origin, match_med != NULL, suppress_map);
8063 }
8064
8065 /* Redistribute route treatment. */
8066 void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
8067 const union g_addr *nexthop, ifindex_t ifindex,
8068 enum nexthop_types_t nhtype, uint8_t distance,
8069 enum blackhole_type bhtype, uint32_t metric,
8070 uint8_t type, unsigned short instance,
8071 route_tag_t tag)
8072 {
8073 struct bgp_path_info *new;
8074 struct bgp_path_info *bpi;
8075 struct bgp_path_info rmap_path;
8076 struct bgp_dest *bn;
8077 struct attr attr;
8078 struct attr *new_attr;
8079 afi_t afi;
8080 route_map_result_t ret;
8081 struct bgp_redist *red;
8082
8083 /* Make default attribute. */
8084 bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
8085 /*
8086 * This must not be NULL to satisfy Coverity SA
8087 */
8088 assert(attr.aspath);
8089
8090 switch (nhtype) {
8091 case NEXTHOP_TYPE_IFINDEX:
8092 break;
8093 case NEXTHOP_TYPE_IPV4:
8094 case NEXTHOP_TYPE_IPV4_IFINDEX:
8095 attr.nexthop = nexthop->ipv4;
8096 break;
8097 case NEXTHOP_TYPE_IPV6:
8098 case NEXTHOP_TYPE_IPV6_IFINDEX:
8099 attr.mp_nexthop_global = nexthop->ipv6;
8100 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8101 break;
8102 case NEXTHOP_TYPE_BLACKHOLE:
8103 switch (p->family) {
8104 case AF_INET:
8105 attr.nexthop.s_addr = INADDR_ANY;
8106 break;
8107 case AF_INET6:
8108 memset(&attr.mp_nexthop_global, 0,
8109 sizeof(attr.mp_nexthop_global));
8110 attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
8111 break;
8112 }
8113 attr.bh_type = bhtype;
8114 break;
8115 }
8116 attr.nh_type = nhtype;
8117 attr.nh_ifindex = ifindex;
8118
8119 attr.med = metric;
8120 attr.distance = distance;
8121 attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
8122 attr.tag = tag;
8123
8124 afi = family2afi(p->family);
8125
8126 red = bgp_redist_lookup(bgp, afi, type, instance);
8127 if (red) {
8128 struct attr attr_new;
8129
8130 /* Copy attribute for modification. */
8131 attr_new = attr;
8132
8133 if (red->redist_metric_flag)
8134 attr_new.med = red->redist_metric;
8135
8136 /* Apply route-map. */
8137 if (red->rmap.name) {
8138 memset(&rmap_path, 0, sizeof(struct bgp_path_info));
8139 rmap_path.peer = bgp->peer_self;
8140 rmap_path.attr = &attr_new;
8141
8142 SET_FLAG(bgp->peer_self->rmap_type,
8143 PEER_RMAP_TYPE_REDISTRIBUTE);
8144
8145 ret = route_map_apply(red->rmap.map, p, &rmap_path);
8146
8147 bgp->peer_self->rmap_type = 0;
8148
8149 if (ret == RMAP_DENYMATCH) {
8150 /* Free uninterned attribute. */
8151 bgp_attr_flush(&attr_new);
8152
8153 /* Unintern original. */
8154 aspath_unintern(&attr.aspath);
8155 bgp_redistribute_delete(bgp, p, type, instance);
8156 return;
8157 }
8158 }
8159
8160 if (bgp_in_graceful_shutdown(bgp))
8161 bgp_attr_add_gshut_community(&attr_new);
8162
8163 bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8164 SAFI_UNICAST, p, NULL);
8165
8166 new_attr = bgp_attr_intern(&attr_new);
8167
8168 for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next)
8169 if (bpi->peer == bgp->peer_self
8170 && bpi->sub_type == BGP_ROUTE_REDISTRIBUTE)
8171 break;
8172
8173 if (bpi) {
8174 /* Ensure the (source route) type is updated. */
8175 bpi->type = type;
8176 if (attrhash_cmp(bpi->attr, new_attr)
8177 && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
8178 bgp_attr_unintern(&new_attr);
8179 aspath_unintern(&attr.aspath);
8180 bgp_dest_unlock_node(bn);
8181 return;
8182 } else {
8183 /* The attribute is changed. */
8184 bgp_path_info_set_flag(bn, bpi,
8185 BGP_PATH_ATTR_CHANGED);
8186
8187 /* Rewrite BGP route information. */
8188 if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED))
8189 bgp_path_info_restore(bn, bpi);
8190 else
8191 bgp_aggregate_decrement(
8192 bgp, p, bpi, afi, SAFI_UNICAST);
8193 bgp_attr_unintern(&bpi->attr);
8194 bpi->attr = new_attr;
8195 bpi->uptime = bgp_clock();
8196
8197 /* Process change. */
8198 bgp_aggregate_increment(bgp, p, bpi, afi,
8199 SAFI_UNICAST);
8200 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8201 bgp_dest_unlock_node(bn);
8202 aspath_unintern(&attr.aspath);
8203
8204 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8205 || (bgp->inst_type
8206 == BGP_INSTANCE_TYPE_DEFAULT)) {
8207
8208 vpn_leak_from_vrf_update(
8209 bgp_get_default(), bgp, bpi);
8210 }
8211 return;
8212 }
8213 }
8214
8215 new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
8216 bgp->peer_self, new_attr, bn);
8217 SET_FLAG(new->flags, BGP_PATH_VALID);
8218
8219 bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
8220 bgp_path_info_add(bn, new);
8221 bgp_dest_unlock_node(bn);
8222 bgp_process(bgp, bn, afi, SAFI_UNICAST);
8223
8224 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8225 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8226
8227 vpn_leak_from_vrf_update(bgp_get_default(), bgp, new);
8228 }
8229 }
8230
8231 /* Unintern original. */
8232 aspath_unintern(&attr.aspath);
8233 }
8234
8235 void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, uint8_t type,
8236 unsigned short instance)
8237 {
8238 afi_t afi;
8239 struct bgp_dest *dest;
8240 struct bgp_path_info *pi;
8241 struct bgp_redist *red;
8242
8243 afi = family2afi(p->family);
8244
8245 red = bgp_redist_lookup(bgp, afi, type, instance);
8246 if (red) {
8247 dest = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
8248 SAFI_UNICAST, p, NULL);
8249
8250 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8251 if (pi->peer == bgp->peer_self && pi->type == type)
8252 break;
8253
8254 if (pi) {
8255 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8256 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8257
8258 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8259 bgp, pi);
8260 }
8261 bgp_aggregate_decrement(bgp, p, pi, afi, SAFI_UNICAST);
8262 bgp_path_info_delete(dest, pi);
8263 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8264 }
8265 bgp_dest_unlock_node(dest);
8266 }
8267 }
8268
8269 /* Withdraw specified route type's route. */
8270 void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
8271 unsigned short instance)
8272 {
8273 struct bgp_dest *dest;
8274 struct bgp_path_info *pi;
8275 struct bgp_table *table;
8276
8277 table = bgp->rib[afi][SAFI_UNICAST];
8278
8279 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
8280 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
8281 if (pi->peer == bgp->peer_self && pi->type == type
8282 && pi->instance == instance)
8283 break;
8284
8285 if (pi) {
8286 if ((bgp->inst_type == BGP_INSTANCE_TYPE_VRF)
8287 || (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) {
8288
8289 vpn_leak_from_vrf_withdraw(bgp_get_default(),
8290 bgp, pi);
8291 }
8292 bgp_aggregate_decrement(bgp, bgp_dest_get_prefix(dest),
8293 pi, afi, SAFI_UNICAST);
8294 bgp_path_info_delete(dest, pi);
8295 bgp_process(bgp, dest, afi, SAFI_UNICAST);
8296 }
8297 }
8298 }
8299
8300 /* Static function to display route. */
8301 static void route_vty_out_route(struct bgp_dest *dest, const struct prefix *p,
8302 struct vty *vty, json_object *json, bool wide)
8303 {
8304 int len = 0;
8305 char buf[BUFSIZ];
8306 char buf2[BUFSIZ];
8307
8308 if (p->family == AF_INET) {
8309 if (!json) {
8310 len = vty_out(vty, "%pFX", p);
8311 } else {
8312 json_object_string_add(json, "prefix",
8313 inet_ntop(p->family,
8314 &p->u.prefix, buf,
8315 BUFSIZ));
8316 json_object_int_add(json, "prefixLen", p->prefixlen);
8317 prefix2str(p, buf2, PREFIX_STRLEN);
8318 json_object_string_add(json, "network", buf2);
8319 json_object_int_add(json, "version", dest->version);
8320 }
8321 } else if (p->family == AF_ETHERNET) {
8322 len = vty_out(vty, "%pFX", p);
8323 } else if (p->family == AF_EVPN) {
8324 if (!json)
8325 len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
8326 else
8327 bgp_evpn_route2json((struct prefix_evpn *)p, json);
8328 } else if (p->family == AF_FLOWSPEC) {
8329 route_vty_out_flowspec(vty, p, NULL,
8330 json ?
8331 NLRI_STRING_FORMAT_JSON_SIMPLE :
8332 NLRI_STRING_FORMAT_MIN, json);
8333 } else {
8334 if (!json)
8335 len = vty_out(vty, "%pFX", p);
8336 else {
8337 json_object_string_add(json, "prefix",
8338 inet_ntop(p->family,
8339 &p->u.prefix, buf,
8340 BUFSIZ));
8341 json_object_int_add(json, "prefixLen", p->prefixlen);
8342 prefix2str(p, buf2, PREFIX_STRLEN);
8343 json_object_string_add(json, "network", buf2);
8344 json_object_int_add(json, "version", dest->version);
8345 }
8346 }
8347
8348 if (!json) {
8349 len = wide ? (45 - len) : (17 - len);
8350 if (len < 1)
8351 vty_out(vty, "\n%*s", 20, " ");
8352 else
8353 vty_out(vty, "%*s", len, " ");
8354 }
8355 }
8356
8357 enum bgp_display_type {
8358 normal_list,
8359 };
8360
8361 static const char *
8362 bgp_path_selection_reason2str(enum bgp_path_selection_reason reason)
8363 {
8364 switch (reason) {
8365 case bgp_path_selection_none:
8366 return "Nothing to Select";
8367 case bgp_path_selection_first:
8368 return "First path received";
8369 case bgp_path_selection_evpn_sticky_mac:
8370 return "EVPN Sticky Mac";
8371 case bgp_path_selection_evpn_seq:
8372 return "EVPN sequence number";
8373 case bgp_path_selection_evpn_lower_ip:
8374 return "EVPN lower IP";
8375 case bgp_path_selection_evpn_local_path:
8376 return "EVPN local ES path";
8377 case bgp_path_selection_evpn_non_proxy:
8378 return "EVPN non proxy";
8379 case bgp_path_selection_weight:
8380 return "Weight";
8381 case bgp_path_selection_local_pref:
8382 return "Local Pref";
8383 case bgp_path_selection_local_route:
8384 return "Local Route";
8385 case bgp_path_selection_confed_as_path:
8386 return "Confederation based AS Path";
8387 case bgp_path_selection_as_path:
8388 return "AS Path";
8389 case bgp_path_selection_origin:
8390 return "Origin";
8391 case bgp_path_selection_med:
8392 return "MED";
8393 case bgp_path_selection_peer:
8394 return "Peer Type";
8395 case bgp_path_selection_confed:
8396 return "Confed Peer Type";
8397 case bgp_path_selection_igp_metric:
8398 return "IGP Metric";
8399 case bgp_path_selection_older:
8400 return "Older Path";
8401 case bgp_path_selection_router_id:
8402 return "Router ID";
8403 case bgp_path_selection_cluster_length:
8404 return "Cluster length";
8405 case bgp_path_selection_stale:
8406 return "Path Staleness";
8407 case bgp_path_selection_local_configured:
8408 return "Locally configured route";
8409 case bgp_path_selection_neighbor_ip:
8410 return "Neighbor IP";
8411 case bgp_path_selection_default:
8412 return "Nothing left to compare";
8413 }
8414 return "Invalid (internal error)";
8415 }
8416
8417 /* Print the short form route status for a bgp_path_info */
8418 static void route_vty_short_status_out(struct vty *vty,
8419 struct bgp_path_info *path,
8420 const struct prefix *p,
8421 json_object *json_path)
8422 {
8423 enum rpki_states rpki_state = RPKI_NOT_BEING_USED;
8424
8425 if (json_path) {
8426
8427 /* Route status display. */
8428 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8429 json_object_boolean_true_add(json_path, "removed");
8430
8431 if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8432 json_object_boolean_true_add(json_path, "stale");
8433
8434 if (path->extra && bgp_path_suppressed(path))
8435 json_object_boolean_true_add(json_path, "suppressed");
8436
8437 if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8438 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8439 json_object_boolean_true_add(json_path, "valid");
8440
8441 /* Selected */
8442 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8443 json_object_boolean_true_add(json_path, "history");
8444
8445 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8446 json_object_boolean_true_add(json_path, "damped");
8447
8448 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
8449 json_object_boolean_true_add(json_path, "bestpath");
8450 json_object_string_add(json_path, "selectionReason",
8451 bgp_path_selection_reason2str(
8452 path->net->reason));
8453 }
8454
8455 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8456 json_object_boolean_true_add(json_path, "multipath");
8457
8458 /* Internal route. */
8459 if ((path->peer->as)
8460 && (path->peer->as == path->peer->local_as))
8461 json_object_string_add(json_path, "pathFrom",
8462 "internal");
8463 else
8464 json_object_string_add(json_path, "pathFrom",
8465 "external");
8466
8467 return;
8468 }
8469
8470 /* RPKI validation state */
8471 rpki_state =
8472 hook_call(bgp_rpki_prefix_status, path->peer, path->attr, p);
8473
8474 if (rpki_state == RPKI_VALID)
8475 vty_out(vty, "V");
8476 else if (rpki_state == RPKI_INVALID)
8477 vty_out(vty, "I");
8478 else if (rpki_state == RPKI_NOTFOUND)
8479 vty_out(vty, "N");
8480
8481 /* Route status display. */
8482 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED))
8483 vty_out(vty, "R");
8484 else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
8485 vty_out(vty, "S");
8486 else if (bgp_path_suppressed(path))
8487 vty_out(vty, "s");
8488 else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
8489 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8490 vty_out(vty, "*");
8491 else
8492 vty_out(vty, " ");
8493
8494 /* Selected */
8495 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
8496 vty_out(vty, "h");
8497 else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED))
8498 vty_out(vty, "d");
8499 else if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED))
8500 vty_out(vty, ">");
8501 else if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH))
8502 vty_out(vty, "=");
8503 else
8504 vty_out(vty, " ");
8505
8506 /* Internal route. */
8507 if (path->peer && (path->peer->as)
8508 && (path->peer->as == path->peer->local_as))
8509 vty_out(vty, "i");
8510 else
8511 vty_out(vty, " ");
8512 }
8513
8514 static char *bgp_nexthop_hostname(struct peer *peer,
8515 struct bgp_nexthop_cache *bnc)
8516 {
8517 if (peer->hostname
8518 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME))
8519 return peer->hostname;
8520 return NULL;
8521 }
8522
8523 /* called from terminal list command */
8524 void route_vty_out(struct vty *vty, const struct prefix *p,
8525 struct bgp_path_info *path, int display, safi_t safi,
8526 json_object *json_paths, bool wide)
8527 {
8528 int len;
8529 struct attr *attr = path->attr;
8530 json_object *json_path = NULL;
8531 json_object *json_nexthops = NULL;
8532 json_object *json_nexthop_global = NULL;
8533 json_object *json_nexthop_ll = NULL;
8534 json_object *json_ext_community = NULL;
8535 char vrf_id_str[VRF_NAMSIZ] = {0};
8536 bool nexthop_self =
8537 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
8538 bool nexthop_othervrf = false;
8539 vrf_id_t nexthop_vrfid = VRF_DEFAULT;
8540 const char *nexthop_vrfname = VRF_DEFAULT_NAME;
8541 char *nexthop_hostname =
8542 bgp_nexthop_hostname(path->peer, path->nexthop);
8543 char esi_buf[ESI_STR_LEN];
8544
8545 if (json_paths)
8546 json_path = json_object_new_object();
8547
8548 /* short status lead text */
8549 route_vty_short_status_out(vty, path, p, json_path);
8550
8551 if (!json_paths) {
8552 /* print prefix and mask */
8553 if (!display)
8554 route_vty_out_route(path->net, p, vty, json_path, wide);
8555 else
8556 vty_out(vty, "%*s", (wide ? 45 : 17), " ");
8557 } else {
8558 route_vty_out_route(path->net, p, vty, json_path, wide);
8559 }
8560
8561 /*
8562 * If vrf id of nexthop is different from that of prefix,
8563 * set up printable string to append
8564 */
8565 if (path->extra && path->extra->bgp_orig) {
8566 const char *self = "";
8567
8568 if (nexthop_self)
8569 self = "<";
8570
8571 nexthop_othervrf = true;
8572 nexthop_vrfid = path->extra->bgp_orig->vrf_id;
8573
8574 if (path->extra->bgp_orig->vrf_id == VRF_UNKNOWN)
8575 snprintf(vrf_id_str, sizeof(vrf_id_str),
8576 "@%s%s", VRFID_NONE_STR, self);
8577 else
8578 snprintf(vrf_id_str, sizeof(vrf_id_str), "@%u%s",
8579 path->extra->bgp_orig->vrf_id, self);
8580
8581 if (path->extra->bgp_orig->inst_type
8582 != BGP_INSTANCE_TYPE_DEFAULT)
8583
8584 nexthop_vrfname = path->extra->bgp_orig->name;
8585 } else {
8586 const char *self = "";
8587
8588 if (nexthop_self)
8589 self = "<";
8590
8591 snprintf(vrf_id_str, sizeof(vrf_id_str), "%s", self);
8592 }
8593
8594 /*
8595 * For ENCAP and EVPN routes, nexthop address family is not
8596 * neccessarily the same as the prefix address family.
8597 * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
8598 * EVPN routes are also exchanged with a MP nexthop. Currently,
8599 * this
8600 * is only IPv4, the value will be present in either
8601 * attr->nexthop or
8602 * attr->mp_nexthop_global_in
8603 */
8604 if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)) {
8605 char buf[BUFSIZ];
8606 char nexthop[128];
8607 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
8608
8609 switch (af) {
8610 case AF_INET:
8611 snprintf(nexthop, sizeof(nexthop), "%s",
8612 inet_ntop(af, &attr->mp_nexthop_global_in, buf,
8613 BUFSIZ));
8614 break;
8615 case AF_INET6:
8616 snprintf(nexthop, sizeof(nexthop), "%s",
8617 inet_ntop(af, &attr->mp_nexthop_global, buf,
8618 BUFSIZ));
8619 break;
8620 default:
8621 snprintf(nexthop, sizeof(nexthop), "?");
8622 break;
8623 }
8624
8625 if (json_paths) {
8626 json_nexthop_global = json_object_new_object();
8627
8628 json_object_string_add(json_nexthop_global, "ip",
8629 nexthop);
8630
8631 if (path->peer->hostname)
8632 json_object_string_add(json_nexthop_global,
8633 "hostname",
8634 path->peer->hostname);
8635
8636 json_object_string_add(json_nexthop_global, "afi",
8637 (af == AF_INET) ? "ipv4"
8638 : "ipv6");
8639 json_object_boolean_true_add(json_nexthop_global,
8640 "used");
8641 } else {
8642 if (nexthop_hostname)
8643 len = vty_out(vty, "%s(%s)%s", nexthop,
8644 nexthop_hostname, vrf_id_str);
8645 else
8646 len = vty_out(vty, "%s%s", nexthop, vrf_id_str);
8647
8648 len = wide ? (41 - len) : (16 - len);
8649 if (len < 1)
8650 vty_out(vty, "\n%*s", 36, " ");
8651 else
8652 vty_out(vty, "%*s", len, " ");
8653 }
8654 } else if (safi == SAFI_EVPN) {
8655 if (json_paths) {
8656 char buf[BUFSIZ] = {0};
8657
8658 json_nexthop_global = json_object_new_object();
8659
8660 json_object_string_add(json_nexthop_global, "ip",
8661 inet_ntop(AF_INET,
8662 &attr->nexthop, buf,
8663 sizeof(buf)));
8664
8665 if (path->peer->hostname)
8666 json_object_string_add(json_nexthop_global,
8667 "hostname",
8668 path->peer->hostname);
8669
8670 json_object_string_add(json_nexthop_global, "afi",
8671 "ipv4");
8672 json_object_boolean_true_add(json_nexthop_global,
8673 "used");
8674 } else {
8675 if (nexthop_hostname)
8676 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8677 nexthop_hostname, vrf_id_str);
8678 else
8679 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8680 vrf_id_str);
8681
8682 len = wide ? (41 - len) : (16 - len);
8683 if (len < 1)
8684 vty_out(vty, "\n%*s", 36, " ");
8685 else
8686 vty_out(vty, "%*s", len, " ");
8687 }
8688 } else if (safi == SAFI_FLOWSPEC) {
8689 if (attr->nexthop.s_addr != INADDR_ANY) {
8690 if (json_paths) {
8691 char buf[BUFSIZ] = {0};
8692
8693 json_nexthop_global = json_object_new_object();
8694
8695 json_object_string_add(json_nexthop_global,
8696 "afi", "ipv4");
8697 json_object_string_add(
8698 json_nexthop_global, "ip",
8699 inet_ntop(AF_INET, &attr->nexthop, buf,
8700 sizeof(buf)));
8701
8702 if (path->peer->hostname)
8703 json_object_string_add(
8704 json_nexthop_global, "hostname",
8705 path->peer->hostname);
8706
8707 json_object_boolean_true_add(
8708 json_nexthop_global,
8709 "used");
8710 } else {
8711 if (nexthop_hostname)
8712 len = vty_out(vty, "%pI4(%s)%s",
8713 &attr->nexthop,
8714 nexthop_hostname,
8715 vrf_id_str);
8716 else
8717 len = vty_out(vty, "%pI4%s",
8718 &attr->nexthop,
8719 vrf_id_str);
8720
8721 len = wide ? (41 - len) : (16 - len);
8722 if (len < 1)
8723 vty_out(vty, "\n%*s", 36, " ");
8724 else
8725 vty_out(vty, "%*s", len, " ");
8726 }
8727 }
8728 } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8729 if (json_paths) {
8730 char buf[BUFSIZ] = {0};
8731
8732 json_nexthop_global = json_object_new_object();
8733
8734 json_object_string_add(json_nexthop_global, "ip",
8735 inet_ntop(AF_INET,
8736 &attr->nexthop, buf,
8737 sizeof(buf)));
8738
8739 if (path->peer->hostname)
8740 json_object_string_add(json_nexthop_global,
8741 "hostname",
8742 path->peer->hostname);
8743
8744 json_object_string_add(json_nexthop_global, "afi",
8745 "ipv4");
8746 json_object_boolean_true_add(json_nexthop_global,
8747 "used");
8748 } else {
8749 if (nexthop_hostname)
8750 len = vty_out(vty, "%pI4(%s)%s", &attr->nexthop,
8751 nexthop_hostname, vrf_id_str);
8752 else
8753 len = vty_out(vty, "%pI4%s", &attr->nexthop,
8754 vrf_id_str);
8755
8756 len = wide ? (41 - len) : (16 - len);
8757 if (len < 1)
8758 vty_out(vty, "\n%*s", 36, " ");
8759 else
8760 vty_out(vty, "%*s", len, " ");
8761 }
8762 }
8763
8764 /* IPv6 Next Hop */
8765 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
8766 char buf[BUFSIZ];
8767
8768 if (json_paths) {
8769 json_nexthop_global = json_object_new_object();
8770 json_object_string_add(
8771 json_nexthop_global, "ip",
8772 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
8773 buf, BUFSIZ));
8774
8775 if (path->peer->hostname)
8776 json_object_string_add(json_nexthop_global,
8777 "hostname",
8778 path->peer->hostname);
8779
8780 json_object_string_add(json_nexthop_global, "afi",
8781 "ipv6");
8782 json_object_string_add(json_nexthop_global, "scope",
8783 "global");
8784
8785 /* We display both LL & GL if both have been
8786 * received */
8787 if ((attr->mp_nexthop_len
8788 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8789 || (path->peer->conf_if)) {
8790 json_nexthop_ll = json_object_new_object();
8791 json_object_string_add(
8792 json_nexthop_ll, "ip",
8793 inet_ntop(AF_INET6,
8794 &attr->mp_nexthop_local, buf,
8795 BUFSIZ));
8796
8797 if (path->peer->hostname)
8798 json_object_string_add(
8799 json_nexthop_ll, "hostname",
8800 path->peer->hostname);
8801
8802 json_object_string_add(json_nexthop_ll, "afi",
8803 "ipv6");
8804 json_object_string_add(json_nexthop_ll, "scope",
8805 "link-local");
8806
8807 if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
8808 &attr->mp_nexthop_local)
8809 != 0)
8810 && !attr->mp_nexthop_prefer_global)
8811 json_object_boolean_true_add(
8812 json_nexthop_ll, "used");
8813 else
8814 json_object_boolean_true_add(
8815 json_nexthop_global, "used");
8816 } else
8817 json_object_boolean_true_add(
8818 json_nexthop_global, "used");
8819 } else {
8820 /* Display LL if LL/Global both in table unless
8821 * prefer-global is set */
8822 if (((attr->mp_nexthop_len
8823 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
8824 && !attr->mp_nexthop_prefer_global)
8825 || (path->peer->conf_if)) {
8826 if (path->peer->conf_if) {
8827 len = vty_out(vty, "%s",
8828 path->peer->conf_if);
8829 /* len of IPv6 addr + max len of def
8830 * ifname */
8831 len = wide ? (41 - len) : (16 - len);
8832
8833 if (len < 1)
8834 vty_out(vty, "\n%*s", 36, " ");
8835 else
8836 vty_out(vty, "%*s", len, " ");
8837 } else {
8838 if (nexthop_hostname)
8839 len = vty_out(
8840 vty, "%pI6(%s)%s",
8841 &attr->mp_nexthop_local,
8842 nexthop_hostname,
8843 vrf_id_str);
8844 else
8845 len = vty_out(
8846 vty, "%pI6%s",
8847 &attr->mp_nexthop_local,
8848 vrf_id_str);
8849
8850 len = wide ? (41 - len) : (16 - len);
8851
8852 if (len < 1)
8853 vty_out(vty, "\n%*s", 36, " ");
8854 else
8855 vty_out(vty, "%*s", len, " ");
8856 }
8857 } else {
8858 if (nexthop_hostname)
8859 len = vty_out(vty, "%pI6(%s)%s",
8860 &attr->mp_nexthop_global,
8861 nexthop_hostname,
8862 vrf_id_str);
8863 else
8864 len = vty_out(vty, "%pI6%s",
8865 &attr->mp_nexthop_global,
8866 vrf_id_str);
8867
8868 len = wide ? (41 - len) : (16 - len);
8869
8870 if (len < 1)
8871 vty_out(vty, "\n%*s", 36, " ");
8872 else
8873 vty_out(vty, "%*s", len, " ");
8874 }
8875 }
8876 }
8877
8878 /* MED/Metric */
8879 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
8880 if (json_paths)
8881 json_object_int_add(json_path, "metric", attr->med);
8882 else if (wide)
8883 vty_out(vty, "%7u", attr->med);
8884 else
8885 vty_out(vty, "%10u", attr->med);
8886 else if (!json_paths) {
8887 if (wide)
8888 vty_out(vty, "%*s", 7, " ");
8889 else
8890 vty_out(vty, "%*s", 10, " ");
8891 }
8892
8893 /* Local Pref */
8894 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
8895 if (json_paths)
8896 json_object_int_add(json_path, "locPrf",
8897 attr->local_pref);
8898 else
8899 vty_out(vty, "%7u", attr->local_pref);
8900 else if (!json_paths)
8901 vty_out(vty, " ");
8902
8903 if (json_paths)
8904 json_object_int_add(json_path, "weight", attr->weight);
8905 else
8906 vty_out(vty, "%7u ", attr->weight);
8907
8908 if (json_paths) {
8909 char buf[BUFSIZ];
8910 json_object_string_add(
8911 json_path, "peerId",
8912 sockunion2str(&path->peer->su, buf, SU_ADDRSTRLEN));
8913 }
8914
8915 /* Print aspath */
8916 if (attr->aspath) {
8917 if (json_paths)
8918 json_object_string_add(json_path, "path",
8919 attr->aspath->str);
8920 else
8921 aspath_print_vty(vty, "%s", attr->aspath, " ");
8922 }
8923
8924 /* Print origin */
8925 if (json_paths)
8926 json_object_string_add(json_path, "origin",
8927 bgp_origin_long_str[attr->origin]);
8928 else
8929 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
8930
8931 if (json_paths) {
8932 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8933 json_object_string_add(json_path, "esi",
8934 esi_to_str(&attr->esi,
8935 esi_buf, sizeof(esi_buf)));
8936 }
8937 if (safi == SAFI_EVPN &&
8938 attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8939 json_ext_community = json_object_new_object();
8940 json_object_string_add(json_ext_community,
8941 "string",
8942 attr->ecommunity->str);
8943 json_object_object_add(json_path,
8944 "extendedCommunity",
8945 json_ext_community);
8946 }
8947
8948 if (nexthop_self)
8949 json_object_boolean_true_add(json_path,
8950 "announceNexthopSelf");
8951 if (nexthop_othervrf) {
8952 json_object_string_add(json_path, "nhVrfName",
8953 nexthop_vrfname);
8954
8955 json_object_int_add(json_path, "nhVrfId",
8956 ((nexthop_vrfid == VRF_UNKNOWN)
8957 ? -1
8958 : (int)nexthop_vrfid));
8959 }
8960 }
8961
8962 if (json_paths) {
8963 if (json_nexthop_global || json_nexthop_ll) {
8964 json_nexthops = json_object_new_array();
8965
8966 if (json_nexthop_global)
8967 json_object_array_add(json_nexthops,
8968 json_nexthop_global);
8969
8970 if (json_nexthop_ll)
8971 json_object_array_add(json_nexthops,
8972 json_nexthop_ll);
8973
8974 json_object_object_add(json_path, "nexthops",
8975 json_nexthops);
8976 }
8977
8978 json_object_array_add(json_paths, json_path);
8979 } else {
8980 vty_out(vty, "\n");
8981
8982 if (safi == SAFI_EVPN) {
8983 if (bgp_evpn_is_esi_valid(&attr->esi)) {
8984 /* XXX - add these params to the json out */
8985 vty_out(vty, "%*s", 20, " ");
8986 vty_out(vty, "ESI:%s",
8987 esi_to_str(&attr->esi, esi_buf,
8988 sizeof(esi_buf)));
8989
8990 vty_out(vty, "\n");
8991 }
8992 if (attr->flag &
8993 ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
8994 vty_out(vty, "%*s", 20, " ");
8995 vty_out(vty, "%s\n", attr->ecommunity->str);
8996 }
8997 }
8998
8999 #ifdef ENABLE_BGP_VNC
9000 /* prints an additional line, indented, with VNC info, if
9001 * present */
9002 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
9003 rfapi_vty_out_vncinfo(vty, p, path, safi);
9004 #endif
9005 }
9006 }
9007
9008 /* called from terminal list command */
9009 void route_vty_out_tmp(struct vty *vty, struct bgp_dest *dest,
9010 const struct prefix *p, struct attr *attr, safi_t safi,
9011 bool use_json, json_object *json_ar, bool wide)
9012 {
9013 json_object *json_status = NULL;
9014 json_object *json_net = NULL;
9015 int len;
9016 char buff[BUFSIZ];
9017
9018 /* Route status display. */
9019 if (use_json) {
9020 json_status = json_object_new_object();
9021 json_net = json_object_new_object();
9022 } else {
9023 vty_out(vty, "*");
9024 vty_out(vty, ">");
9025 vty_out(vty, " ");
9026 }
9027
9028 /* print prefix and mask */
9029 if (use_json) {
9030 if (safi == SAFI_EVPN)
9031 bgp_evpn_route2json((struct prefix_evpn *)p, json_net);
9032 else if (p->family == AF_INET || p->family == AF_INET6) {
9033 json_object_string_add(
9034 json_net, "addrPrefix",
9035 inet_ntop(p->family, &p->u.prefix, buff,
9036 BUFSIZ));
9037 json_object_int_add(json_net, "prefixLen",
9038 p->prefixlen);
9039 prefix2str(p, buff, PREFIX_STRLEN);
9040 json_object_string_add(json_net, "network", buff);
9041 }
9042 } else
9043 route_vty_out_route(dest, p, vty, NULL, wide);
9044
9045 /* Print attribute */
9046 if (attr) {
9047 if (use_json) {
9048 char buf[BUFSIZ] = {0};
9049
9050 if (p->family == AF_INET
9051 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9052 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9053 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
9054 json_object_string_add(
9055 json_net, "nextHop",
9056 inet_ntop(
9057 AF_INET,
9058 &attr->mp_nexthop_global_in,
9059 buf, sizeof(buf)));
9060 else
9061 json_object_string_add(
9062 json_net, "nextHop",
9063 inet_ntop(AF_INET,
9064 &attr->nexthop, buf,
9065 sizeof(buf)));
9066 } else if (p->family == AF_INET6
9067 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9068 char buf[BUFSIZ];
9069
9070 json_object_string_add(
9071 json_net, "nextHopGlobal",
9072 inet_ntop(AF_INET6,
9073 &attr->mp_nexthop_global, buf,
9074 BUFSIZ));
9075 } else if (p->family == AF_EVPN
9076 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9077 char buf[BUFSIZ] = {0};
9078
9079 json_object_string_add(
9080 json_net, "nextHop",
9081 inet_ntop(AF_INET,
9082 &attr->mp_nexthop_global_in,
9083 buf, sizeof(buf)));
9084 }
9085
9086 if (attr->flag
9087 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9088 json_object_int_add(json_net, "metric",
9089 attr->med);
9090
9091 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9092 json_object_int_add(json_net, "locPrf",
9093 attr->local_pref);
9094
9095 json_object_int_add(json_net, "weight", attr->weight);
9096
9097 /* Print aspath */
9098 if (attr->aspath)
9099 json_object_string_add(json_net, "path",
9100 attr->aspath->str);
9101
9102 /* Print origin */
9103 json_object_string_add(json_net, "bgpOriginCode",
9104 bgp_origin_str[attr->origin]);
9105 } else {
9106 if (p->family == AF_INET
9107 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9108 || safi == SAFI_EVPN
9109 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9110 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9111 || safi == SAFI_EVPN)
9112 vty_out(vty, "%-16pI4",
9113 &attr->mp_nexthop_global_in);
9114 else if (wide)
9115 vty_out(vty, "%-41pI4", &attr->nexthop);
9116 else
9117 vty_out(vty, "%-16pI4", &attr->nexthop);
9118 } else if (p->family == AF_INET6
9119 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
9120 char buf[BUFSIZ];
9121
9122 len = vty_out(
9123 vty, "%s",
9124 inet_ntop(AF_INET6,
9125 &attr->mp_nexthop_global, buf,
9126 BUFSIZ));
9127 len = wide ? (41 - len) : (16 - len);
9128 if (len < 1)
9129 vty_out(vty, "\n%*s", 36, " ");
9130 else
9131 vty_out(vty, "%*s", len, " ");
9132 }
9133 if (attr->flag
9134 & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
9135 if (wide)
9136 vty_out(vty, "%7u", attr->med);
9137 else
9138 vty_out(vty, "%10u", attr->med);
9139 else if (wide)
9140 vty_out(vty, " ");
9141 else
9142 vty_out(vty, " ");
9143
9144 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
9145 vty_out(vty, "%7u", attr->local_pref);
9146 else
9147 vty_out(vty, " ");
9148
9149 vty_out(vty, "%7u ", attr->weight);
9150
9151 /* Print aspath */
9152 if (attr->aspath)
9153 aspath_print_vty(vty, "%s", attr->aspath, " ");
9154
9155 /* Print origin */
9156 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9157 }
9158 }
9159 if (use_json) {
9160 json_object_boolean_true_add(json_status, "*");
9161 json_object_boolean_true_add(json_status, ">");
9162 json_object_object_add(json_net, "appliedStatusSymbols",
9163 json_status);
9164
9165 prefix2str(p, buff, PREFIX_STRLEN);
9166 json_object_object_add(json_ar, buff, json_net);
9167 } else
9168 vty_out(vty, "\n");
9169 }
9170
9171 void route_vty_out_tag(struct vty *vty, const struct prefix *p,
9172 struct bgp_path_info *path, int display, safi_t safi,
9173 json_object *json)
9174 {
9175 json_object *json_out = NULL;
9176 struct attr *attr;
9177 mpls_label_t label = MPLS_INVALID_LABEL;
9178
9179 if (!path->extra)
9180 return;
9181
9182 if (json)
9183 json_out = json_object_new_object();
9184
9185 /* short status lead text */
9186 route_vty_short_status_out(vty, path, p, json_out);
9187
9188 /* print prefix and mask */
9189 if (json == NULL) {
9190 if (!display)
9191 route_vty_out_route(path->net, p, vty, NULL, false);
9192 else
9193 vty_out(vty, "%*s", 17, " ");
9194 }
9195
9196 /* Print attribute */
9197 attr = path->attr;
9198 if (((p->family == AF_INET)
9199 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9200 || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9201 || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9202 char buf[BUFSIZ] = {0};
9203
9204 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9205 || safi == SAFI_EVPN) {
9206 if (json)
9207 json_object_string_add(
9208 json_out, "mpNexthopGlobalIn",
9209 inet_ntop(AF_INET,
9210 &attr->mp_nexthop_global_in,
9211 buf, sizeof(buf)));
9212 else
9213 vty_out(vty, "%-16pI4",
9214 &attr->mp_nexthop_global_in);
9215 } else {
9216 if (json)
9217 json_object_string_add(
9218 json_out, "nexthop",
9219 inet_ntop(AF_INET, &attr->nexthop, buf,
9220 sizeof(buf)));
9221 else
9222 vty_out(vty, "%-16pI4", &attr->nexthop);
9223 }
9224 } else if (((p->family == AF_INET6)
9225 && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
9226 || (safi == SAFI_EVPN && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
9227 || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9228 char buf_a[512];
9229
9230 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
9231 if (json)
9232 json_object_string_add(
9233 json_out, "mpNexthopGlobalIn",
9234 inet_ntop(AF_INET6,
9235 &attr->mp_nexthop_global,
9236 buf_a, sizeof(buf_a)));
9237 else
9238 vty_out(vty, "%s",
9239 inet_ntop(AF_INET6,
9240 &attr->mp_nexthop_global,
9241 buf_a, sizeof(buf_a)));
9242 } else if (attr->mp_nexthop_len
9243 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
9244 snprintfrr(buf_a, sizeof(buf_a), "%pI6(%pI6)",
9245 &attr->mp_nexthop_global,
9246 &attr->mp_nexthop_local);
9247 if (json)
9248 json_object_string_add(json_out,
9249 "mpNexthopGlobalLocal",
9250 buf_a);
9251 else
9252 vty_out(vty, "%s", buf_a);
9253 }
9254 }
9255
9256 label = decode_label(&path->extra->label[0]);
9257
9258 if (bgp_is_valid_label(&label)) {
9259 if (json) {
9260 json_object_int_add(json_out, "notag", label);
9261 json_object_array_add(json, json_out);
9262 } else {
9263 vty_out(vty, "notag/%d", label);
9264 vty_out(vty, "\n");
9265 }
9266 }
9267 }
9268
9269 void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
9270 struct bgp_path_info *path, int display,
9271 json_object *json_paths)
9272 {
9273 struct attr *attr;
9274 char buf[BUFSIZ] = {0};
9275 json_object *json_path = NULL;
9276 json_object *json_nexthop = NULL;
9277 json_object *json_overlay = NULL;
9278
9279 if (!path->extra)
9280 return;
9281
9282 if (json_paths) {
9283 json_path = json_object_new_object();
9284 json_overlay = json_object_new_object();
9285 json_nexthop = json_object_new_object();
9286 }
9287
9288 /* short status lead text */
9289 route_vty_short_status_out(vty, path, p, json_path);
9290
9291 /* print prefix and mask */
9292 if (!display)
9293 route_vty_out_route(path->net, p, vty, json_path, false);
9294 else
9295 vty_out(vty, "%*s", 17, " ");
9296
9297 /* Print attribute */
9298 attr = path->attr;
9299 char buf1[BUFSIZ];
9300 int af = NEXTHOP_FAMILY(attr->mp_nexthop_len);
9301
9302 switch (af) {
9303 case AF_INET:
9304 inet_ntop(af, &attr->mp_nexthop_global_in, buf, BUFSIZ);
9305 if (!json_path) {
9306 vty_out(vty, "%-16s", buf);
9307 } else {
9308 json_object_string_add(json_nexthop, "ip", buf);
9309
9310 json_object_string_add(json_nexthop, "afi", "ipv4");
9311
9312 json_object_object_add(json_path, "nexthop",
9313 json_nexthop);
9314 }
9315 break;
9316 case AF_INET6:
9317 inet_ntop(af, &attr->mp_nexthop_global, buf, BUFSIZ);
9318 inet_ntop(af, &attr->mp_nexthop_local, buf1, BUFSIZ);
9319 if (!json_path) {
9320 vty_out(vty, "%s(%s)", buf, buf1);
9321 } else {
9322 json_object_string_add(json_nexthop, "ipv6Global", buf);
9323
9324 json_object_string_add(json_nexthop, "ipv6LinkLocal",
9325 buf1);
9326
9327 json_object_string_add(json_nexthop, "afi", "ipv6");
9328
9329 json_object_object_add(json_path, "nexthop",
9330 json_nexthop);
9331 }
9332 break;
9333 default:
9334 if (!json_path) {
9335 vty_out(vty, "?");
9336 } else {
9337 json_object_string_add(json_nexthop, "Error",
9338 "Unsupported address-family");
9339 }
9340 }
9341
9342 const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
9343
9344 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p))
9345 inet_ntop(AF_INET, &eo->gw_ip.ipv4, buf, BUFSIZ);
9346 else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p))
9347 inet_ntop(AF_INET6, &eo->gw_ip.ipv6, buf, BUFSIZ);
9348
9349 if (!json_path)
9350 vty_out(vty, "/%s", buf);
9351 else
9352 json_object_string_add(json_overlay, "gw", buf);
9353
9354 if (attr->ecommunity) {
9355 char *mac = NULL;
9356 struct ecommunity_val *routermac = ecommunity_lookup(
9357 attr->ecommunity, ECOMMUNITY_ENCODE_EVPN,
9358 ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
9359
9360 if (routermac)
9361 mac = ecom_mac2str((char *)routermac->val);
9362 if (mac) {
9363 if (!json_path) {
9364 vty_out(vty, "/%s", mac);
9365 } else {
9366 json_object_string_add(json_overlay, "rmac",
9367 mac);
9368 }
9369 XFREE(MTYPE_TMP, mac);
9370 }
9371 }
9372
9373 if (!json_path) {
9374 vty_out(vty, "\n");
9375 } else {
9376 json_object_object_add(json_path, "overlay", json_overlay);
9377
9378 json_object_array_add(json_paths, json_path);
9379 }
9380 }
9381
9382 /* dampening route */
9383 static void damp_route_vty_out(struct vty *vty, const struct prefix *p,
9384 struct bgp_path_info *path, int display,
9385 afi_t afi, safi_t safi, bool use_json,
9386 json_object *json_paths)
9387 {
9388 struct attr *attr = path->attr;
9389 int len;
9390 char timebuf[BGP_UPTIME_LEN];
9391 json_object *json_path = NULL;
9392
9393 if (use_json)
9394 json_path = json_object_new_object();
9395
9396 /* short status lead text */
9397 route_vty_short_status_out(vty, path, p, json_path);
9398
9399 /* print prefix and mask */
9400 if (!use_json) {
9401 if (!display)
9402 route_vty_out_route(path->net, p, vty, NULL, false);
9403 else
9404 vty_out(vty, "%*s", 17, " ");
9405
9406 len = vty_out(vty, "%s", path->peer->host);
9407 len = 17 - len;
9408
9409 if (len < 1)
9410 vty_out(vty, "\n%*s", 34, " ");
9411 else
9412 vty_out(vty, "%*s", len, " ");
9413
9414 vty_out(vty, "%s ",
9415 bgp_damp_reuse_time_vty(vty, path, timebuf,
9416 BGP_UPTIME_LEN, afi, safi,
9417 use_json, NULL));
9418
9419 if (attr->aspath)
9420 aspath_print_vty(vty, "%s", attr->aspath, " ");
9421
9422 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9423
9424 vty_out(vty, "\n");
9425 } else {
9426 bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
9427 safi, use_json, json_path);
9428
9429 if (attr->aspath)
9430 json_object_string_add(json_path, "asPath",
9431 attr->aspath->str);
9432
9433 json_object_string_add(json_path, "origin",
9434 bgp_origin_str[attr->origin]);
9435 json_object_string_add(json_path, "peerHost", path->peer->host);
9436
9437 json_object_array_add(json_paths, json_path);
9438 }
9439 }
9440
9441 /* flap route */
9442 static void flap_route_vty_out(struct vty *vty, const struct prefix *p,
9443 struct bgp_path_info *path, int display,
9444 afi_t afi, safi_t safi, bool use_json,
9445 json_object *json_paths)
9446 {
9447 struct attr *attr = path->attr;
9448 struct bgp_damp_info *bdi;
9449 char timebuf[BGP_UPTIME_LEN];
9450 int len;
9451 json_object *json_path = NULL;
9452
9453 if (!path->extra)
9454 return;
9455
9456 if (use_json)
9457 json_path = json_object_new_object();
9458
9459 bdi = path->extra->damp_info;
9460
9461 /* short status lead text */
9462 route_vty_short_status_out(vty, path, p, json_path);
9463
9464 if (!use_json) {
9465 if (!display)
9466 route_vty_out_route(path->net, p, vty, NULL, false);
9467 else
9468 vty_out(vty, "%*s", 17, " ");
9469
9470 len = vty_out(vty, "%s", path->peer->host);
9471 len = 16 - len;
9472 if (len < 1)
9473 vty_out(vty, "\n%*s", 33, " ");
9474 else
9475 vty_out(vty, "%*s", len, " ");
9476
9477 len = vty_out(vty, "%d", bdi->flap);
9478 len = 5 - len;
9479 if (len < 1)
9480 vty_out(vty, " ");
9481 else
9482 vty_out(vty, "%*s", len, " ");
9483
9484 vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
9485 BGP_UPTIME_LEN, 0, NULL));
9486
9487 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9488 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9489 vty_out(vty, "%s ",
9490 bgp_damp_reuse_time_vty(vty, path, timebuf,
9491 BGP_UPTIME_LEN, afi,
9492 safi, use_json, NULL));
9493 else
9494 vty_out(vty, "%*s ", 8, " ");
9495
9496 if (attr->aspath)
9497 aspath_print_vty(vty, "%s", attr->aspath, " ");
9498
9499 vty_out(vty, "%s", bgp_origin_str[attr->origin]);
9500
9501 vty_out(vty, "\n");
9502 } else {
9503 json_object_string_add(json_path, "peerHost", path->peer->host);
9504 json_object_int_add(json_path, "bdiFlap", bdi->flap);
9505
9506 peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
9507 json_path);
9508
9509 if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)
9510 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
9511 bgp_damp_reuse_time_vty(vty, path, timebuf,
9512 BGP_UPTIME_LEN, afi, safi,
9513 use_json, json_path);
9514
9515 if (attr->aspath)
9516 json_object_string_add(json_path, "asPath",
9517 attr->aspath->str);
9518
9519 json_object_string_add(json_path, "origin",
9520 bgp_origin_str[attr->origin]);
9521
9522 json_object_array_add(json_paths, json_path);
9523 }
9524 }
9525
9526 static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
9527 int *first, const char *header,
9528 json_object *json_adv_to)
9529 {
9530 char buf1[INET6_ADDRSTRLEN];
9531 json_object *json_peer = NULL;
9532
9533 if (json_adv_to) {
9534 /* 'advertised-to' is a dictionary of peers we have advertised
9535 * this
9536 * prefix too. The key is the peer's IP or swpX, the value is
9537 * the
9538 * hostname if we know it and "" if not.
9539 */
9540 json_peer = json_object_new_object();
9541
9542 if (peer->hostname)
9543 json_object_string_add(json_peer, "hostname",
9544 peer->hostname);
9545
9546 if (peer->conf_if)
9547 json_object_object_add(json_adv_to, peer->conf_if,
9548 json_peer);
9549 else
9550 json_object_object_add(
9551 json_adv_to,
9552 sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
9553 json_peer);
9554 } else {
9555 if (*first) {
9556 vty_out(vty, "%s", header);
9557 *first = 0;
9558 }
9559
9560 if (peer->hostname
9561 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
9562 if (peer->conf_if)
9563 vty_out(vty, " %s(%s)", peer->hostname,
9564 peer->conf_if);
9565 else
9566 vty_out(vty, " %s(%s)", peer->hostname,
9567 sockunion2str(&peer->su, buf1,
9568 SU_ADDRSTRLEN));
9569 } else {
9570 if (peer->conf_if)
9571 vty_out(vty, " %s", peer->conf_if);
9572 else
9573 vty_out(vty, " %s",
9574 sockunion2str(&peer->su, buf1,
9575 SU_ADDRSTRLEN));
9576 }
9577 }
9578 }
9579
9580 static void route_vty_out_tx_ids(struct vty *vty,
9581 struct bgp_addpath_info_data *d)
9582 {
9583 int i;
9584
9585 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
9586 vty_out(vty, "TX-%s %u%s", bgp_addpath_names(i)->human_name,
9587 d->addpath_tx_id[i],
9588 i < BGP_ADDPATH_MAX - 1 ? " " : "\n");
9589 }
9590 }
9591
9592 static void route_vty_out_detail_es_info(struct vty *vty,
9593 struct bgp_path_info *pi,
9594 struct attr *attr,
9595 json_object *json_path)
9596 {
9597 char esi_buf[ESI_STR_LEN];
9598 bool es_local = !!CHECK_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
9599 bool peer_router = !!CHECK_FLAG(attr->es_flags,
9600 ATTR_ES_PEER_ROUTER);
9601 bool peer_active = !!CHECK_FLAG(attr->es_flags,
9602 ATTR_ES_PEER_ACTIVE);
9603 bool peer_proxy = !!CHECK_FLAG(attr->es_flags,
9604 ATTR_ES_PEER_PROXY);
9605 esi_to_str(&attr->esi, esi_buf, sizeof(esi_buf));
9606 if (json_path) {
9607 json_object *json_es_info = NULL;
9608
9609 json_object_string_add(
9610 json_path, "esi",
9611 esi_buf);
9612 if (es_local || bgp_evpn_attr_is_sync(attr)) {
9613 json_es_info = json_object_new_object();
9614 if (es_local)
9615 json_object_boolean_true_add(
9616 json_es_info, "localEs");
9617 if (peer_active)
9618 json_object_boolean_true_add(
9619 json_es_info, "peerActive");
9620 if (peer_proxy)
9621 json_object_boolean_true_add(
9622 json_es_info, "peerProxy");
9623 if (peer_router)
9624 json_object_boolean_true_add(
9625 json_es_info, "peerRouter");
9626 if (attr->mm_sync_seqnum)
9627 json_object_int_add(
9628 json_es_info, "peerSeq",
9629 attr->mm_sync_seqnum);
9630 json_object_object_add(
9631 json_path, "es_info",
9632 json_es_info);
9633 }
9634 } else {
9635 if (bgp_evpn_attr_is_sync(attr))
9636 vty_out(vty,
9637 " ESI %s %s peer-info: (%s%s%sMM: %d)\n",
9638 esi_buf,
9639 es_local ? "local-es":"",
9640 peer_proxy ? "proxy " : "",
9641 peer_active ? "active ":"",
9642 peer_router ? "router ":"",
9643 attr->mm_sync_seqnum);
9644 else
9645 vty_out(vty, " ESI %s %s\n",
9646 esi_buf,
9647 es_local ? "local-es":"");
9648 }
9649 }
9650
9651 void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
9652 struct bgp_path_info *path, afi_t afi, safi_t safi,
9653 enum rpki_states rpki_curr_state,
9654 json_object *json_paths)
9655 {
9656 char buf[INET6_ADDRSTRLEN];
9657 char buf1[BUFSIZ];
9658 struct attr *attr = path->attr;
9659 int sockunion_vty_out(struct vty *, union sockunion *);
9660 time_t tbuf;
9661 json_object *json_bestpath = NULL;
9662 json_object *json_cluster_list = NULL;
9663 json_object *json_cluster_list_list = NULL;
9664 json_object *json_ext_community = NULL;
9665 json_object *json_last_update = NULL;
9666 json_object *json_pmsi = NULL;
9667 json_object *json_nexthop_global = NULL;
9668 json_object *json_nexthop_ll = NULL;
9669 json_object *json_nexthops = NULL;
9670 json_object *json_path = NULL;
9671 json_object *json_peer = NULL;
9672 json_object *json_string = NULL;
9673 json_object *json_adv_to = NULL;
9674 int first = 0;
9675 struct listnode *node, *nnode;
9676 struct peer *peer;
9677 int addpath_capable;
9678 int has_adj;
9679 unsigned int first_as;
9680 bool nexthop_self =
9681 CHECK_FLAG(path->flags, BGP_PATH_ANNC_NH_SELF) ? true : false;
9682 int i;
9683 char *nexthop_hostname =
9684 bgp_nexthop_hostname(path->peer, path->nexthop);
9685
9686 if (json_paths) {
9687 json_path = json_object_new_object();
9688 json_peer = json_object_new_object();
9689 json_nexthop_global = json_object_new_object();
9690 }
9691
9692 if (safi == SAFI_EVPN) {
9693 if (!json_paths)
9694 vty_out(vty, " Route %pRN", bn);
9695 }
9696
9697 if (path->extra) {
9698 char tag_buf[30];
9699
9700 tag_buf[0] = '\0';
9701 if (path->extra && path->extra->num_labels) {
9702 bgp_evpn_label2str(path->extra->label,
9703 path->extra->num_labels, tag_buf,
9704 sizeof(tag_buf));
9705 }
9706 if (safi == SAFI_EVPN) {
9707 if (!json_paths) {
9708 if (tag_buf[0] != '\0')
9709 vty_out(vty, " VNI %s", tag_buf);
9710 } else {
9711 if (tag_buf[0])
9712 json_object_string_add(json_path, "VNI",
9713 tag_buf);
9714 }
9715 }
9716
9717 if (path->extra && path->extra->parent && !json_paths) {
9718 struct bgp_path_info *parent_ri;
9719 struct bgp_dest *dest, *pdest;
9720
9721 parent_ri = (struct bgp_path_info *)path->extra->parent;
9722 dest = parent_ri->net;
9723 if (dest && dest->pdest) {
9724 pdest = dest->pdest;
9725 prefix_rd2str(
9726 (struct prefix_rd *)bgp_dest_get_prefix(
9727 pdest),
9728 buf1, sizeof(buf1));
9729 if (is_pi_family_evpn(parent_ri)) {
9730 vty_out(vty,
9731 " Imported from %s:%pFX, VNI %s",
9732 buf1,
9733 (struct prefix_evpn *)
9734 bgp_dest_get_prefix(
9735 dest),
9736 tag_buf);
9737 if (attr->es_flags & ATTR_ES_L3_NHG)
9738 vty_out(vty, ", L3NHG %s",
9739 (attr->es_flags
9740 & ATTR_ES_L3_NHG_ACTIVE)
9741 ? "active"
9742 : "inactive");
9743 vty_out(vty, "\n");
9744
9745 } else
9746 vty_out(vty,
9747 " Imported from %s:%pFX\n",
9748 buf1,
9749 (struct prefix_evpn *)
9750 bgp_dest_get_prefix(
9751 dest));
9752 }
9753 }
9754 }
9755
9756 if (safi == SAFI_EVPN
9757 && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
9758 char gwip_buf[INET6_ADDRSTRLEN];
9759
9760 if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)&bn->p))
9761 inet_ntop(AF_INET, &attr->evpn_overlay.gw_ip.ipv4,
9762 gwip_buf, sizeof(gwip_buf));
9763 else
9764 inet_ntop(AF_INET6, &attr->evpn_overlay.gw_ip.ipv6,
9765 gwip_buf, sizeof(gwip_buf));
9766
9767 if (json_paths)
9768 json_object_string_add(json_path, "gatewayIP",
9769 gwip_buf);
9770 else
9771 vty_out(vty, " Gateway IP %s", gwip_buf);
9772 }
9773
9774 if (safi == SAFI_EVPN)
9775 vty_out(vty, "\n");
9776
9777 /* Line1 display AS-path, Aggregator */
9778 if (attr->aspath) {
9779 if (json_paths) {
9780 if (!attr->aspath->json)
9781 aspath_str_update(attr->aspath, true);
9782 json_object_lock(attr->aspath->json);
9783 json_object_object_add(json_path, "aspath",
9784 attr->aspath->json);
9785 } else {
9786 if (attr->aspath->segments)
9787 aspath_print_vty(vty, " %s", attr->aspath, "");
9788 else
9789 vty_out(vty, " Local");
9790 }
9791 }
9792
9793 if (CHECK_FLAG(path->flags, BGP_PATH_REMOVED)) {
9794 if (json_paths)
9795 json_object_boolean_true_add(json_path, "removed");
9796 else
9797 vty_out(vty, ", (removed)");
9798 }
9799
9800 if (CHECK_FLAG(path->flags, BGP_PATH_STALE)) {
9801 if (json_paths)
9802 json_object_boolean_true_add(json_path, "stale");
9803 else
9804 vty_out(vty, ", (stale)");
9805 }
9806
9807 if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
9808 if (json_paths) {
9809 char buf[BUFSIZ] = {0};
9810
9811 json_object_int_add(json_path, "aggregatorAs",
9812 attr->aggregator_as);
9813 json_object_string_add(json_path, "aggregatorId",
9814 inet_ntop(AF_INET,
9815 &attr->aggregator_addr,
9816 buf, sizeof(buf)));
9817 } else {
9818 vty_out(vty, ", (aggregated by %u %pI4)",
9819 attr->aggregator_as, &attr->aggregator_addr);
9820 }
9821 }
9822
9823 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9824 PEER_FLAG_REFLECTOR_CLIENT)) {
9825 if (json_paths)
9826 json_object_boolean_true_add(json_path,
9827 "rxedFromRrClient");
9828 else
9829 vty_out(vty, ", (Received from a RR-client)");
9830 }
9831
9832 if (CHECK_FLAG(path->peer->af_flags[afi][safi],
9833 PEER_FLAG_RSERVER_CLIENT)) {
9834 if (json_paths)
9835 json_object_boolean_true_add(json_path,
9836 "rxedFromRsClient");
9837 else
9838 vty_out(vty, ", (Received from a RS-client)");
9839 }
9840
9841 if (CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
9842 if (json_paths)
9843 json_object_boolean_true_add(json_path,
9844 "dampeningHistoryEntry");
9845 else
9846 vty_out(vty, ", (history entry)");
9847 } else if (CHECK_FLAG(path->flags, BGP_PATH_DAMPED)) {
9848 if (json_paths)
9849 json_object_boolean_true_add(json_path,
9850 "dampeningSuppressed");
9851 else
9852 vty_out(vty, ", (suppressed due to dampening)");
9853 }
9854
9855 if (!json_paths)
9856 vty_out(vty, "\n");
9857
9858 /* Line2 display Next-hop, Neighbor, Router-id */
9859 /* Display the nexthop */
9860 const struct prefix *bn_p = bgp_dest_get_prefix(bn);
9861
9862 if ((bn_p->family == AF_INET || bn_p->family == AF_ETHERNET
9863 || bn_p->family == AF_EVPN)
9864 && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
9865 || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9866 char buf[BUFSIZ] = {0};
9867
9868 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
9869 || safi == SAFI_EVPN) {
9870 if (json_paths) {
9871 json_object_string_add(
9872 json_nexthop_global, "ip",
9873 inet_ntop(AF_INET,
9874 &attr->mp_nexthop_global_in,
9875 buf, sizeof(buf)));
9876
9877 if (path->peer->hostname)
9878 json_object_string_add(
9879 json_nexthop_global, "hostname",
9880 path->peer->hostname);
9881 } else {
9882 if (nexthop_hostname)
9883 vty_out(vty, " %pI4(%s)",
9884 &attr->mp_nexthop_global_in,
9885 nexthop_hostname);
9886 else
9887 vty_out(vty, " %pI4",
9888 &attr->mp_nexthop_global_in);
9889 }
9890 } else {
9891 if (json_paths) {
9892 json_object_string_add(
9893 json_nexthop_global, "ip",
9894 inet_ntop(AF_INET, &attr->nexthop, buf,
9895 sizeof(buf)));
9896
9897 if (path->peer->hostname)
9898 json_object_string_add(
9899 json_nexthop_global, "hostname",
9900 path->peer->hostname);
9901 } else {
9902 if (nexthop_hostname)
9903 vty_out(vty, " %pI4(%s)",
9904 &attr->nexthop,
9905 nexthop_hostname);
9906 else
9907 vty_out(vty, " %pI4",
9908 &attr->nexthop);
9909 }
9910 }
9911
9912 if (json_paths)
9913 json_object_string_add(json_nexthop_global, "afi",
9914 "ipv4");
9915 } else {
9916 if (json_paths) {
9917 json_object_string_add(
9918 json_nexthop_global, "ip",
9919 inet_ntop(AF_INET6, &attr->mp_nexthop_global,
9920 buf, INET6_ADDRSTRLEN));
9921
9922 if (path->peer->hostname)
9923 json_object_string_add(json_nexthop_global,
9924 "hostname",
9925 path->peer->hostname);
9926
9927 json_object_string_add(json_nexthop_global, "afi",
9928 "ipv6");
9929 json_object_string_add(json_nexthop_global, "scope",
9930 "global");
9931 } else {
9932 if (nexthop_hostname)
9933 vty_out(vty, " %pI6(%s)",
9934 &attr->mp_nexthop_global,
9935 nexthop_hostname);
9936 else
9937 vty_out(vty, " %pI6",
9938 &attr->mp_nexthop_global);
9939 }
9940 }
9941
9942 /* Display the IGP cost or 'inaccessible' */
9943 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
9944 if (json_paths)
9945 json_object_boolean_false_add(json_nexthop_global,
9946 "accessible");
9947 else
9948 vty_out(vty, " (inaccessible)");
9949 } else {
9950 if (path->extra && path->extra->igpmetric) {
9951 if (json_paths)
9952 json_object_int_add(json_nexthop_global,
9953 "metric",
9954 path->extra->igpmetric);
9955 else
9956 vty_out(vty, " (metric %u)",
9957 path->extra->igpmetric);
9958 }
9959
9960 /* IGP cost is 0, display this only for json */
9961 else {
9962 if (json_paths)
9963 json_object_int_add(json_nexthop_global,
9964 "metric", 0);
9965 }
9966
9967 if (json_paths)
9968 json_object_boolean_true_add(json_nexthop_global,
9969 "accessible");
9970 }
9971
9972 /* Display peer "from" output */
9973 /* This path was originated locally */
9974 if (path->peer == bgp->peer_self) {
9975
9976 if (safi == SAFI_EVPN
9977 || (bn_p->family == AF_INET
9978 && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
9979 if (json_paths)
9980 json_object_string_add(json_peer, "peerId",
9981 "0.0.0.0");
9982 else
9983 vty_out(vty, " from 0.0.0.0 ");
9984 } else {
9985 if (json_paths)
9986 json_object_string_add(json_peer, "peerId",
9987 "::");
9988 else
9989 vty_out(vty, " from :: ");
9990 }
9991
9992 if (json_paths) {
9993 char buf[BUFSIZ] = {0};
9994
9995 json_object_string_add(json_peer, "routerId",
9996 inet_ntop(AF_INET,
9997 &bgp->router_id, buf,
9998 sizeof(buf)));
9999 } else {
10000 vty_out(vty, "(%pI4)", &bgp->router_id);
10001 }
10002 }
10003
10004 /* We RXed this path from one of our peers */
10005 else {
10006
10007 if (json_paths) {
10008 json_object_string_add(json_peer, "peerId",
10009 sockunion2str(&path->peer->su,
10010 buf,
10011 SU_ADDRSTRLEN));
10012 json_object_string_add(json_peer, "routerId",
10013 inet_ntop(AF_INET,
10014 &path->peer->remote_id,
10015 buf1, sizeof(buf1)));
10016
10017 if (path->peer->hostname)
10018 json_object_string_add(json_peer, "hostname",
10019 path->peer->hostname);
10020
10021 if (path->peer->domainname)
10022 json_object_string_add(json_peer, "domainname",
10023 path->peer->domainname);
10024
10025 if (path->peer->conf_if)
10026 json_object_string_add(json_peer, "interface",
10027 path->peer->conf_if);
10028 } else {
10029 if (path->peer->conf_if) {
10030 if (path->peer->hostname
10031 && CHECK_FLAG(path->peer->bgp->flags,
10032 BGP_FLAG_SHOW_HOSTNAME))
10033 vty_out(vty, " from %s(%s)",
10034 path->peer->hostname,
10035 path->peer->conf_if);
10036 else
10037 vty_out(vty, " from %s",
10038 path->peer->conf_if);
10039 } else {
10040 if (path->peer->hostname
10041 && CHECK_FLAG(path->peer->bgp->flags,
10042 BGP_FLAG_SHOW_HOSTNAME))
10043 vty_out(vty, " from %s(%s)",
10044 path->peer->hostname,
10045 path->peer->host);
10046 else
10047 vty_out(vty, " from %s",
10048 sockunion2str(&path->peer->su,
10049 buf,
10050 SU_ADDRSTRLEN));
10051 }
10052
10053 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10054 vty_out(vty, " (%pI4)", &attr->originator_id);
10055 else
10056 vty_out(vty, " (%s)",
10057 inet_ntop(AF_INET,
10058 &path->peer->remote_id, buf1,
10059 sizeof(buf1)));
10060 }
10061 }
10062
10063 /*
10064 * Note when vrfid of nexthop is different from that of prefix
10065 */
10066 if (path->extra && path->extra->bgp_orig) {
10067 vrf_id_t nexthop_vrfid = path->extra->bgp_orig->vrf_id;
10068
10069 if (json_paths) {
10070 const char *vn;
10071
10072 if (path->extra->bgp_orig->inst_type
10073 == BGP_INSTANCE_TYPE_DEFAULT)
10074 vn = VRF_DEFAULT_NAME;
10075 else
10076 vn = path->extra->bgp_orig->name;
10077
10078 json_object_string_add(json_path, "nhVrfName", vn);
10079
10080 if (nexthop_vrfid == VRF_UNKNOWN) {
10081 json_object_int_add(json_path, "nhVrfId", -1);
10082 } else {
10083 json_object_int_add(json_path, "nhVrfId",
10084 (int)nexthop_vrfid);
10085 }
10086 } else {
10087 if (nexthop_vrfid == VRF_UNKNOWN)
10088 vty_out(vty, " vrf ?");
10089 else {
10090 struct vrf *vrf;
10091
10092 vrf = vrf_lookup_by_id(nexthop_vrfid);
10093 vty_out(vty, " vrf %s(%u)",
10094 VRF_LOGNAME(vrf), nexthop_vrfid);
10095 }
10096 }
10097 }
10098
10099 if (nexthop_self) {
10100 if (json_paths) {
10101 json_object_boolean_true_add(json_path,
10102 "announceNexthopSelf");
10103 } else {
10104 vty_out(vty, " announce-nh-self");
10105 }
10106 }
10107
10108 if (!json_paths)
10109 vty_out(vty, "\n");
10110
10111 /* display the link-local nexthop */
10112 if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
10113 if (json_paths) {
10114 json_nexthop_ll = json_object_new_object();
10115 json_object_string_add(
10116 json_nexthop_ll, "ip",
10117 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10118 buf, INET6_ADDRSTRLEN));
10119
10120 if (path->peer->hostname)
10121 json_object_string_add(json_nexthop_ll,
10122 "hostname",
10123 path->peer->hostname);
10124
10125 json_object_string_add(json_nexthop_ll, "afi", "ipv6");
10126 json_object_string_add(json_nexthop_ll, "scope",
10127 "link-local");
10128
10129 json_object_boolean_true_add(json_nexthop_ll,
10130 "accessible");
10131
10132 if (!attr->mp_nexthop_prefer_global)
10133 json_object_boolean_true_add(json_nexthop_ll,
10134 "used");
10135 else
10136 json_object_boolean_true_add(
10137 json_nexthop_global, "used");
10138 } else {
10139 vty_out(vty, " (%s) %s\n",
10140 inet_ntop(AF_INET6, &attr->mp_nexthop_local,
10141 buf, INET6_ADDRSTRLEN),
10142 attr->mp_nexthop_prefer_global
10143 ? "(prefer-global)"
10144 : "(used)");
10145 }
10146 }
10147 /* If we do not have a link-local nexthop then we must flag the
10148 global as "used" */
10149 else {
10150 if (json_paths)
10151 json_object_boolean_true_add(json_nexthop_global,
10152 "used");
10153 }
10154
10155 if (safi == SAFI_EVPN &&
10156 bgp_evpn_is_esi_valid(&attr->esi)) {
10157 route_vty_out_detail_es_info(vty, path, attr, json_path);
10158 }
10159
10160 /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
10161 * Int/Ext/Local, Atomic, best */
10162 if (json_paths)
10163 json_object_string_add(json_path, "origin",
10164 bgp_origin_long_str[attr->origin]);
10165 else
10166 vty_out(vty, " Origin %s",
10167 bgp_origin_long_str[attr->origin]);
10168
10169 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
10170 if (json_paths)
10171 json_object_int_add(json_path, "metric", attr->med);
10172 else
10173 vty_out(vty, ", metric %u", attr->med);
10174 }
10175
10176 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
10177 if (json_paths)
10178 json_object_int_add(json_path, "locPrf",
10179 attr->local_pref);
10180 else
10181 vty_out(vty, ", localpref %u", attr->local_pref);
10182 }
10183
10184 if (attr->weight != 0) {
10185 if (json_paths)
10186 json_object_int_add(json_path, "weight", attr->weight);
10187 else
10188 vty_out(vty, ", weight %u", attr->weight);
10189 }
10190
10191 if (attr->tag != 0) {
10192 if (json_paths)
10193 json_object_int_add(json_path, "tag", attr->tag);
10194 else
10195 vty_out(vty, ", tag %" ROUTE_TAG_PRI, attr->tag);
10196 }
10197
10198 if (!CHECK_FLAG(path->flags, BGP_PATH_VALID)) {
10199 if (json_paths)
10200 json_object_boolean_false_add(json_path, "valid");
10201 else
10202 vty_out(vty, ", invalid");
10203 } else if (!CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
10204 if (json_paths)
10205 json_object_boolean_true_add(json_path, "valid");
10206 else
10207 vty_out(vty, ", valid");
10208 }
10209
10210 if (json_paths)
10211 json_object_int_add(json_path, "version", bn->version);
10212
10213 if (path->peer != bgp->peer_self) {
10214 if (path->peer->as == path->peer->local_as) {
10215 if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
10216 if (json_paths)
10217 json_object_string_add(
10218 json_peer, "type",
10219 "confed-internal");
10220 else
10221 vty_out(vty, ", confed-internal");
10222 } else {
10223 if (json_paths)
10224 json_object_string_add(
10225 json_peer, "type", "internal");
10226 else
10227 vty_out(vty, ", internal");
10228 }
10229 } else {
10230 if (bgp_confederation_peers_check(bgp,
10231 path->peer->as)) {
10232 if (json_paths)
10233 json_object_string_add(
10234 json_peer, "type",
10235 "confed-external");
10236 else
10237 vty_out(vty, ", confed-external");
10238 } else {
10239 if (json_paths)
10240 json_object_string_add(
10241 json_peer, "type", "external");
10242 else
10243 vty_out(vty, ", external");
10244 }
10245 }
10246 } else if (path->sub_type == BGP_ROUTE_AGGREGATE) {
10247 if (json_paths) {
10248 json_object_boolean_true_add(json_path, "aggregated");
10249 json_object_boolean_true_add(json_path, "local");
10250 } else {
10251 vty_out(vty, ", aggregated, local");
10252 }
10253 } else if (path->type != ZEBRA_ROUTE_BGP) {
10254 if (json_paths)
10255 json_object_boolean_true_add(json_path, "sourced");
10256 else
10257 vty_out(vty, ", sourced");
10258 } else {
10259 if (json_paths) {
10260 json_object_boolean_true_add(json_path, "sourced");
10261 json_object_boolean_true_add(json_path, "local");
10262 } else {
10263 vty_out(vty, ", sourced, local");
10264 }
10265 }
10266
10267 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
10268 if (json_paths)
10269 json_object_boolean_true_add(json_path,
10270 "atomicAggregate");
10271 else
10272 vty_out(vty, ", atomic-aggregate");
10273 }
10274
10275 if (CHECK_FLAG(path->flags, BGP_PATH_MULTIPATH)
10276 || (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)
10277 && bgp_path_info_mpath_count(path))) {
10278 if (json_paths)
10279 json_object_boolean_true_add(json_path, "multipath");
10280 else
10281 vty_out(vty, ", multipath");
10282 }
10283
10284 // Mark the bestpath(s)
10285 if (CHECK_FLAG(path->flags, BGP_PATH_DMED_SELECTED)) {
10286 first_as = aspath_get_first_as(attr->aspath);
10287
10288 if (json_paths) {
10289 if (!json_bestpath)
10290 json_bestpath = json_object_new_object();
10291 json_object_int_add(json_bestpath, "bestpathFromAs",
10292 first_as);
10293 } else {
10294 if (first_as)
10295 vty_out(vty, ", bestpath-from-AS %u", first_as);
10296 else
10297 vty_out(vty, ", bestpath-from-AS Local");
10298 }
10299 }
10300
10301 if (CHECK_FLAG(path->flags, BGP_PATH_SELECTED)) {
10302 if (json_paths) {
10303 if (!json_bestpath)
10304 json_bestpath = json_object_new_object();
10305 json_object_boolean_true_add(json_bestpath, "overall");
10306 json_object_string_add(
10307 json_bestpath, "selectionReason",
10308 bgp_path_selection_reason2str(bn->reason));
10309 } else {
10310 vty_out(vty, ", best");
10311 vty_out(vty, " (%s)",
10312 bgp_path_selection_reason2str(bn->reason));
10313 }
10314 }
10315
10316 if (rpki_curr_state != RPKI_NOT_BEING_USED) {
10317 if (json_paths)
10318 json_object_string_add(
10319 json_path, "rpkiValidationState",
10320 bgp_rpki_validation2str(rpki_curr_state));
10321 else
10322 vty_out(vty, ", rpki validation-state: %s",
10323 bgp_rpki_validation2str(rpki_curr_state));
10324 }
10325
10326 if (json_bestpath)
10327 json_object_object_add(json_path, "bestpath", json_bestpath);
10328
10329 if (!json_paths)
10330 vty_out(vty, "\n");
10331
10332 /* Line 4 display Community */
10333 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) {
10334 if (json_paths) {
10335 if (!attr->community->json)
10336 community_str(attr->community, true);
10337 json_object_lock(attr->community->json);
10338 json_object_object_add(json_path, "community",
10339 attr->community->json);
10340 } else {
10341 vty_out(vty, " Community: %s\n",
10342 attr->community->str);
10343 }
10344 }
10345
10346 /* Line 5 display Extended-community */
10347 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
10348 if (json_paths) {
10349 json_ext_community = json_object_new_object();
10350 json_object_string_add(json_ext_community, "string",
10351 attr->ecommunity->str);
10352 json_object_object_add(json_path, "extendedCommunity",
10353 json_ext_community);
10354 } else {
10355 vty_out(vty, " Extended Community: %s\n",
10356 attr->ecommunity->str);
10357 }
10358 }
10359
10360 /* Line 6 display Large community */
10361 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
10362 if (json_paths) {
10363 if (!attr->lcommunity->json)
10364 lcommunity_str(attr->lcommunity, true);
10365 json_object_lock(attr->lcommunity->json);
10366 json_object_object_add(json_path, "largeCommunity",
10367 attr->lcommunity->json);
10368 } else {
10369 vty_out(vty, " Large Community: %s\n",
10370 attr->lcommunity->str);
10371 }
10372 }
10373
10374 /* Line 7 display Originator, Cluster-id */
10375 if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
10376 || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
10377 char buf[BUFSIZ] = {0};
10378
10379 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
10380 if (json_paths)
10381 json_object_string_add(
10382 json_path, "originatorId",
10383 inet_ntop(AF_INET, &attr->originator_id,
10384 buf, sizeof(buf)));
10385 else
10386 vty_out(vty, " Originator: %pI4",
10387 &attr->originator_id);
10388 }
10389
10390 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
10391 struct cluster_list *cluster =
10392 bgp_attr_get_cluster(attr);
10393 int i;
10394
10395 if (json_paths) {
10396 json_cluster_list = json_object_new_object();
10397 json_cluster_list_list =
10398 json_object_new_array();
10399
10400 for (i = 0; i < cluster->length / 4; i++) {
10401 json_string = json_object_new_string(
10402 inet_ntop(AF_INET,
10403 &cluster->list[i],
10404 buf, sizeof(buf)));
10405 json_object_array_add(
10406 json_cluster_list_list,
10407 json_string);
10408 }
10409
10410 /*
10411 * struct cluster_list does not have
10412 * "str" variable like aspath and community
10413 * do. Add this someday if someone asks
10414 * for it.
10415 * json_object_string_add(json_cluster_list,
10416 * "string", cluster->str);
10417 */
10418 json_object_object_add(json_cluster_list,
10419 "list",
10420 json_cluster_list_list);
10421 json_object_object_add(json_path, "clusterList",
10422 json_cluster_list);
10423 } else {
10424 vty_out(vty, ", Cluster list: ");
10425
10426 for (i = 0; i < cluster->length / 4; i++) {
10427 vty_out(vty, "%pI4 ",
10428 &cluster->list[i]);
10429 }
10430 }
10431 }
10432
10433 if (!json_paths)
10434 vty_out(vty, "\n");
10435 }
10436
10437 if (path->extra && path->extra->damp_info)
10438 bgp_damp_info_vty(vty, path, afi, safi, json_path);
10439
10440 /* Remote Label */
10441 if (path->extra && bgp_is_valid_label(&path->extra->label[0])
10442 && (safi != SAFI_EVPN && !is_route_parent_evpn(path))) {
10443 mpls_label_t label = label_pton(&path->extra->label[0]);
10444
10445 if (json_paths)
10446 json_object_int_add(json_path, "remoteLabel", label);
10447 else
10448 vty_out(vty, " Remote label: %d\n", label);
10449 }
10450
10451 /* Remote SID */
10452 if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) {
10453 inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf));
10454 if (json_paths)
10455 json_object_string_add(json_path, "remoteSid", buf);
10456 else
10457 vty_out(vty, " Remote SID: %s\n", buf);
10458 }
10459
10460 /* Label Index */
10461 if (attr->label_index != BGP_INVALID_LABEL_INDEX) {
10462 if (json_paths)
10463 json_object_int_add(json_path, "labelIndex",
10464 attr->label_index);
10465 else
10466 vty_out(vty, " Label Index: %d\n",
10467 attr->label_index);
10468 }
10469
10470 /* Line 8 display Addpath IDs */
10471 if (path->addpath_rx_id
10472 || bgp_addpath_info_has_ids(&path->tx_addpath)) {
10473 if (json_paths) {
10474 json_object_int_add(json_path, "addpathRxId",
10475 path->addpath_rx_id);
10476
10477 /* Keep backwards compatibility with the old API
10478 * by putting TX All's ID in the old field
10479 */
10480 json_object_int_add(
10481 json_path, "addpathTxId",
10482 path->tx_addpath
10483 .addpath_tx_id[BGP_ADDPATH_ALL]);
10484
10485 /* ... but create a specific field for each
10486 * strategy
10487 */
10488 for (i = 0; i < BGP_ADDPATH_MAX; i++) {
10489 json_object_int_add(
10490 json_path,
10491 bgp_addpath_names(i)->id_json_name,
10492 path->tx_addpath.addpath_tx_id[i]);
10493 }
10494 } else {
10495 vty_out(vty, " AddPath ID: RX %u, ",
10496 path->addpath_rx_id);
10497
10498 route_vty_out_tx_ids(vty, &path->tx_addpath);
10499 }
10500 }
10501
10502 /* If we used addpath to TX a non-bestpath we need to display
10503 * "Advertised to" on a path-by-path basis
10504 */
10505 if (bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
10506 first = 1;
10507
10508 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
10509 addpath_capable =
10510 bgp_addpath_encode_tx(peer, afi, safi);
10511 has_adj = bgp_adj_out_lookup(
10512 peer, path->net,
10513 bgp_addpath_id_for_peer(peer, afi, safi,
10514 &path->tx_addpath));
10515
10516 if ((addpath_capable && has_adj)
10517 || (!addpath_capable && has_adj
10518 && CHECK_FLAG(path->flags,
10519 BGP_PATH_SELECTED))) {
10520 if (json_path && !json_adv_to)
10521 json_adv_to = json_object_new_object();
10522
10523 route_vty_out_advertised_to(
10524 vty, peer, &first,
10525 " Advertised to:", json_adv_to);
10526 }
10527 }
10528
10529 if (json_path) {
10530 if (json_adv_to) {
10531 json_object_object_add(
10532 json_path, "advertisedTo", json_adv_to);
10533 }
10534 } else {
10535 if (!first) {
10536 vty_out(vty, "\n");
10537 }
10538 }
10539 }
10540
10541 /* Line 9 display Uptime */
10542 tbuf = time(NULL) - (bgp_clock() - path->uptime);
10543 if (json_paths) {
10544 json_last_update = json_object_new_object();
10545 json_object_int_add(json_last_update, "epoch", tbuf);
10546 json_object_string_add(json_last_update, "string",
10547 ctime(&tbuf));
10548 json_object_object_add(json_path, "lastUpdate",
10549 json_last_update);
10550 } else
10551 vty_out(vty, " Last update: %s", ctime(&tbuf));
10552
10553 /* Line 10 display PMSI tunnel attribute, if present */
10554 if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
10555 const char *str = lookup_msg(bgp_pmsi_tnltype_str,
10556 bgp_attr_get_pmsi_tnl_type(attr),
10557 PMSI_TNLTYPE_STR_DEFAULT);
10558
10559 if (json_paths) {
10560 json_pmsi = json_object_new_object();
10561 json_object_string_add(json_pmsi, "tunnelType", str);
10562 json_object_int_add(json_pmsi, "label",
10563 label2vni(&attr->label));
10564 json_object_object_add(json_path, "pmsi", json_pmsi);
10565 } else
10566 vty_out(vty, " PMSI Tunnel Type: %s, label: %d\n",
10567 str, label2vni(&attr->label));
10568 }
10569
10570 /* Output some debug about internal state of the dest flags */
10571 if (json_paths) {
10572 if (CHECK_FLAG(bn->flags, BGP_NODE_PROCESS_SCHEDULED))
10573 json_object_boolean_true_add(json_path, "processScheduled");
10574 if (CHECK_FLAG(bn->flags, BGP_NODE_USER_CLEAR))
10575 json_object_boolean_true_add(json_path, "userCleared");
10576 if (CHECK_FLAG(bn->flags, BGP_NODE_LABEL_CHANGED))
10577 json_object_boolean_true_add(json_path, "labelChanged");
10578 if (CHECK_FLAG(bn->flags, BGP_NODE_REGISTERED_FOR_LABEL))
10579 json_object_boolean_true_add(json_path, "registeredForLabel");
10580 if (CHECK_FLAG(bn->flags, BGP_NODE_SELECT_DEFER))
10581 json_object_boolean_true_add(json_path, "selectDefered");
10582 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALLED))
10583 json_object_boolean_true_add(json_path, "fibInstalled");
10584 if (CHECK_FLAG(bn->flags, BGP_NODE_FIB_INSTALL_PENDING))
10585 json_object_boolean_true_add(json_path, "fibPending");
10586 }
10587
10588 /* We've constructed the json object for this path, add it to the json
10589 * array of paths
10590 */
10591 if (json_paths) {
10592 if (json_nexthop_global || json_nexthop_ll) {
10593 json_nexthops = json_object_new_array();
10594
10595 if (json_nexthop_global)
10596 json_object_array_add(json_nexthops,
10597 json_nexthop_global);
10598
10599 if (json_nexthop_ll)
10600 json_object_array_add(json_nexthops,
10601 json_nexthop_ll);
10602
10603 json_object_object_add(json_path, "nexthops",
10604 json_nexthops);
10605 }
10606
10607 json_object_object_add(json_path, "peer", json_peer);
10608 json_object_array_add(json_paths, json_path);
10609 }
10610 }
10611
10612 #define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path"
10613 #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path\n"
10614 #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path\n"
10615
10616 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
10617 const char *prefix_list_str, afi_t afi,
10618 safi_t safi, enum bgp_show_type type);
10619 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
10620 const char *filter, afi_t afi, safi_t safi,
10621 enum bgp_show_type type);
10622 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
10623 const char *rmap_str, afi_t afi, safi_t safi,
10624 enum bgp_show_type type);
10625 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
10626 const char *com, int exact, afi_t afi,
10627 safi_t safi);
10628 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
10629 const char *prefix, afi_t afi, safi_t safi,
10630 enum bgp_show_type type);
10631 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
10632 afi_t afi, safi_t safi, enum bgp_show_type type,
10633 bool use_json);
10634 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
10635 const char *comstr, int exact, afi_t afi,
10636 safi_t safi, uint16_t show_flags);
10637
10638 static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
10639 struct bgp_table *table, enum bgp_show_type type,
10640 void *output_arg, char *rd, int is_last,
10641 unsigned long *output_cum, unsigned long *total_cum,
10642 unsigned long *json_header_depth, uint16_t show_flags,
10643 enum rpki_states rpki_target_state)
10644 {
10645 struct bgp_path_info *pi;
10646 struct bgp_dest *dest;
10647 int header = 1;
10648 int display;
10649 unsigned long output_count = 0;
10650 unsigned long total_count = 0;
10651 struct prefix *p;
10652 json_object *json_paths = NULL;
10653 int first = 1;
10654 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
10655 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
10656 bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
10657
10658 if (output_cum && *output_cum != 0)
10659 header = 0;
10660
10661 if (use_json && !*json_header_depth) {
10662 if (all)
10663 *json_header_depth = 1;
10664 else {
10665 vty_out(vty, "{\n");
10666 *json_header_depth = 2;
10667 }
10668
10669 vty_out(vty,
10670 " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
10671 ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
10672 " \"localAS\": %u,\n \"routes\": { ",
10673 bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
10674 bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
10675 ? VRF_DEFAULT_NAME
10676 : bgp->name,
10677 table->version, &bgp->router_id,
10678 bgp->default_local_pref, bgp->as);
10679 if (rd) {
10680 vty_out(vty, " \"routeDistinguishers\" : {");
10681 ++*json_header_depth;
10682 }
10683 }
10684
10685 if (use_json && rd) {
10686 vty_out(vty, " \"%s\" : { ", rd);
10687 }
10688
10689 /* Start processing of routes. */
10690 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
10691 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
10692 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
10693
10694 pi = bgp_dest_get_bgp_path_info(dest);
10695 if (pi == NULL)
10696 continue;
10697
10698 display = 0;
10699 if (use_json)
10700 json_paths = json_object_new_array();
10701 else
10702 json_paths = NULL;
10703
10704 for (; pi; pi = pi->next) {
10705 total_count++;
10706
10707 if (type == bgp_show_type_prefix_version) {
10708 uint32_t version =
10709 strtoul(output_arg, NULL, 10);
10710 if (dest->version < version)
10711 continue;
10712 }
10713
10714 if (type == bgp_show_type_community_alias) {
10715 char *alias = output_arg;
10716 char **communities;
10717 int num;
10718 bool found = false;
10719
10720 if (pi->attr->community) {
10721 frrstr_split(pi->attr->community->str,
10722 " ", &communities, &num);
10723 for (int i = 0; i < num; i++) {
10724 const char *com2alias =
10725 bgp_community2alias(
10726 communities[i]);
10727 if (!found
10728 && strcmp(alias, com2alias)
10729 == 0)
10730 found = true;
10731 XFREE(MTYPE_TMP,
10732 communities[i]);
10733 }
10734 XFREE(MTYPE_TMP, communities);
10735 }
10736
10737 if (!found && pi->attr->lcommunity) {
10738 frrstr_split(pi->attr->lcommunity->str,
10739 " ", &communities, &num);
10740 for (int i = 0; i < num; i++) {
10741 const char *com2alias =
10742 bgp_community2alias(
10743 communities[i]);
10744 if (!found
10745 && strcmp(alias, com2alias)
10746 == 0)
10747 found = true;
10748 XFREE(MTYPE_TMP,
10749 communities[i]);
10750 }
10751 XFREE(MTYPE_TMP, communities);
10752 }
10753
10754 if (!found)
10755 continue;
10756 }
10757
10758 if (type == bgp_show_type_rpki) {
10759 if (dest_p->family == AF_INET
10760 || dest_p->family == AF_INET6)
10761 rpki_curr_state = hook_call(
10762 bgp_rpki_prefix_status,
10763 pi->peer, pi->attr, dest_p);
10764 if (rpki_target_state != RPKI_NOT_BEING_USED
10765 && rpki_curr_state != rpki_target_state)
10766 continue;
10767 }
10768
10769 if (type == bgp_show_type_flap_statistics
10770 || type == bgp_show_type_flap_neighbor
10771 || type == bgp_show_type_dampend_paths
10772 || type == bgp_show_type_damp_neighbor) {
10773 if (!(pi->extra && pi->extra->damp_info))
10774 continue;
10775 }
10776 if (type == bgp_show_type_regexp) {
10777 regex_t *regex = output_arg;
10778
10779 if (bgp_regexec(regex, pi->attr->aspath)
10780 == REG_NOMATCH)
10781 continue;
10782 }
10783 if (type == bgp_show_type_prefix_list) {
10784 struct prefix_list *plist = output_arg;
10785
10786 if (prefix_list_apply(plist, dest_p)
10787 != PREFIX_PERMIT)
10788 continue;
10789 }
10790 if (type == bgp_show_type_filter_list) {
10791 struct as_list *as_list = output_arg;
10792
10793 if (as_list_apply(as_list, pi->attr->aspath)
10794 != AS_FILTER_PERMIT)
10795 continue;
10796 }
10797 if (type == bgp_show_type_route_map) {
10798 struct route_map *rmap = output_arg;
10799 struct bgp_path_info path;
10800 struct attr dummy_attr;
10801 route_map_result_t ret;
10802
10803 dummy_attr = *pi->attr;
10804
10805 path.peer = pi->peer;
10806 path.attr = &dummy_attr;
10807
10808 ret = route_map_apply(rmap, dest_p, &path);
10809 if (ret == RMAP_DENYMATCH)
10810 continue;
10811 }
10812 if (type == bgp_show_type_neighbor
10813 || type == bgp_show_type_flap_neighbor
10814 || type == bgp_show_type_damp_neighbor) {
10815 union sockunion *su = output_arg;
10816
10817 if (pi->peer == NULL
10818 || pi->peer->su_remote == NULL
10819 || !sockunion_same(pi->peer->su_remote, su))
10820 continue;
10821 }
10822 if (type == bgp_show_type_cidr_only) {
10823 uint32_t destination;
10824
10825 destination = ntohl(dest_p->u.prefix4.s_addr);
10826 if (IN_CLASSC(destination)
10827 && dest_p->prefixlen == 24)
10828 continue;
10829 if (IN_CLASSB(destination)
10830 && dest_p->prefixlen == 16)
10831 continue;
10832 if (IN_CLASSA(destination)
10833 && dest_p->prefixlen == 8)
10834 continue;
10835 }
10836 if (type == bgp_show_type_prefix_longer) {
10837 p = output_arg;
10838 if (!prefix_match(p, dest_p))
10839 continue;
10840 }
10841 if (type == bgp_show_type_community_all) {
10842 if (!pi->attr->community)
10843 continue;
10844 }
10845 if (type == bgp_show_type_community) {
10846 struct community *com = output_arg;
10847
10848 if (!pi->attr->community
10849 || !community_match(pi->attr->community,
10850 com))
10851 continue;
10852 }
10853 if (type == bgp_show_type_community_exact) {
10854 struct community *com = output_arg;
10855
10856 if (!pi->attr->community
10857 || !community_cmp(pi->attr->community, com))
10858 continue;
10859 }
10860 if (type == bgp_show_type_community_list) {
10861 struct community_list *list = output_arg;
10862
10863 if (!community_list_match(pi->attr->community,
10864 list))
10865 continue;
10866 }
10867 if (type == bgp_show_type_community_list_exact) {
10868 struct community_list *list = output_arg;
10869
10870 if (!community_list_exact_match(
10871 pi->attr->community, list))
10872 continue;
10873 }
10874 if (type == bgp_show_type_lcommunity) {
10875 struct lcommunity *lcom = output_arg;
10876
10877 if (!pi->attr->lcommunity
10878 || !lcommunity_match(pi->attr->lcommunity,
10879 lcom))
10880 continue;
10881 }
10882
10883 if (type == bgp_show_type_lcommunity_exact) {
10884 struct lcommunity *lcom = output_arg;
10885
10886 if (!pi->attr->lcommunity
10887 || !lcommunity_cmp(pi->attr->lcommunity,
10888 lcom))
10889 continue;
10890 }
10891 if (type == bgp_show_type_lcommunity_list) {
10892 struct community_list *list = output_arg;
10893
10894 if (!lcommunity_list_match(pi->attr->lcommunity,
10895 list))
10896 continue;
10897 }
10898 if (type
10899 == bgp_show_type_lcommunity_list_exact) {
10900 struct community_list *list = output_arg;
10901
10902 if (!lcommunity_list_exact_match(
10903 pi->attr->lcommunity, list))
10904 continue;
10905 }
10906 if (type == bgp_show_type_lcommunity_all) {
10907 if (!pi->attr->lcommunity)
10908 continue;
10909 }
10910 if (type == bgp_show_type_dampend_paths
10911 || type == bgp_show_type_damp_neighbor) {
10912 if (!CHECK_FLAG(pi->flags, BGP_PATH_DAMPED)
10913 || CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
10914 continue;
10915 }
10916
10917 if (!use_json && header) {
10918 vty_out(vty,
10919 "BGP table version is %" PRIu64
10920 ", local router ID is %pI4, vrf id ",
10921 table->version, &bgp->router_id);
10922 if (bgp->vrf_id == VRF_UNKNOWN)
10923 vty_out(vty, "%s", VRFID_NONE_STR);
10924 else
10925 vty_out(vty, "%u", bgp->vrf_id);
10926 vty_out(vty, "\n");
10927 vty_out(vty, "Default local pref %u, ",
10928 bgp->default_local_pref);
10929 vty_out(vty, "local AS %u\n", bgp->as);
10930 vty_out(vty, BGP_SHOW_SCODE_HEADER);
10931 vty_out(vty, BGP_SHOW_NCODE_HEADER);
10932 vty_out(vty, BGP_SHOW_OCODE_HEADER);
10933 vty_out(vty, BGP_SHOW_RPKI_HEADER);
10934 if (type == bgp_show_type_dampend_paths
10935 || type == bgp_show_type_damp_neighbor)
10936 vty_out(vty, BGP_SHOW_DAMP_HEADER);
10937 else if (type == bgp_show_type_flap_statistics
10938 || type == bgp_show_type_flap_neighbor)
10939 vty_out(vty, BGP_SHOW_FLAP_HEADER);
10940 else
10941 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
10942 : BGP_SHOW_HEADER));
10943 header = 0;
10944 }
10945 if (rd != NULL && !display && !output_count) {
10946 if (!use_json)
10947 vty_out(vty,
10948 "Route Distinguisher: %s\n",
10949 rd);
10950 }
10951 if (type == bgp_show_type_dampend_paths
10952 || type == bgp_show_type_damp_neighbor)
10953 damp_route_vty_out(vty, dest_p, pi, display,
10954 AFI_IP, safi, use_json,
10955 json_paths);
10956 else if (type == bgp_show_type_flap_statistics
10957 || type == bgp_show_type_flap_neighbor)
10958 flap_route_vty_out(vty, dest_p, pi, display,
10959 AFI_IP, safi, use_json,
10960 json_paths);
10961 else {
10962 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
10963 route_vty_out_detail(
10964 vty, bgp, dest, pi,
10965 family2afi(dest_p->family),
10966 safi, RPKI_NOT_BEING_USED,
10967 json_paths);
10968 else
10969 route_vty_out(vty, dest_p, pi, display,
10970 safi, json_paths, wide);
10971 }
10972 display++;
10973 }
10974
10975 if (display) {
10976 output_count++;
10977 if (!use_json)
10978 continue;
10979
10980 /* encode prefix */
10981 if (dest_p->family == AF_FLOWSPEC) {
10982 char retstr[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
10983
10984
10985 bgp_fs_nlri_get_string(
10986 (unsigned char *)
10987 dest_p->u.prefix_flowspec.ptr,
10988 dest_p->u.prefix_flowspec.prefixlen,
10989 retstr, NLRI_STRING_FORMAT_MIN, NULL,
10990 family2afi(dest_p->u
10991 .prefix_flowspec.family));
10992 if (first)
10993 vty_out(vty, "\"%s/%d\": ", retstr,
10994 dest_p->u.prefix_flowspec
10995 .prefixlen);
10996 else
10997 vty_out(vty, ",\"%s/%d\": ", retstr,
10998 dest_p->u.prefix_flowspec
10999 .prefixlen);
11000 } else {
11001 if (first)
11002 vty_out(vty, "\"%pFX\": ", dest_p);
11003 else
11004 vty_out(vty, ",\"%pFX\": ", dest_p);
11005 }
11006 vty_out(vty, "%s",
11007 json_object_to_json_string_ext(
11008 json_paths, JSON_C_TO_STRING_PRETTY));
11009 json_object_free(json_paths);
11010 json_paths = NULL;
11011 first = 0;
11012 } else
11013 json_object_free(json_paths);
11014 }
11015
11016 if (output_cum) {
11017 output_count += *output_cum;
11018 *output_cum = output_count;
11019 }
11020 if (total_cum) {
11021 total_count += *total_cum;
11022 *total_cum = total_count;
11023 }
11024 if (use_json) {
11025 if (rd) {
11026 vty_out(vty, " }%s ", (is_last ? "" : ","));
11027 }
11028 if (is_last) {
11029 unsigned long i;
11030 for (i = 0; i < *json_header_depth; ++i)
11031 vty_out(vty, " } ");
11032 if (!all)
11033 vty_out(vty, "\n");
11034 }
11035 } else {
11036 if (is_last) {
11037 /* No route is displayed */
11038 if (output_count == 0) {
11039 if (type == bgp_show_type_normal)
11040 vty_out(vty,
11041 "No BGP prefixes displayed, %ld exist\n",
11042 total_count);
11043 } else
11044 vty_out(vty,
11045 "\nDisplayed %ld routes and %ld total paths\n",
11046 output_count, total_count);
11047 }
11048 }
11049
11050 return CMD_SUCCESS;
11051 }
11052
11053 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
11054 struct bgp_table *table, struct prefix_rd *prd_match,
11055 enum bgp_show_type type, void *output_arg, bool use_json)
11056 {
11057 struct bgp_dest *dest, *next;
11058 unsigned long output_cum = 0;
11059 unsigned long total_cum = 0;
11060 unsigned long json_header_depth = 0;
11061 struct bgp_table *itable;
11062 bool show_msg;
11063 uint16_t show_flags = 0;
11064
11065 show_msg = (!use_json && type == bgp_show_type_normal);
11066
11067 if (use_json)
11068 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11069
11070 for (dest = bgp_table_top(table); dest; dest = next) {
11071 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11072
11073 next = bgp_route_next(dest);
11074 if (prd_match && memcmp(dest_p->u.val, prd_match->val, 8) != 0)
11075 continue;
11076
11077 itable = bgp_dest_get_bgp_table_info(dest);
11078 if (itable != NULL) {
11079 struct prefix_rd prd;
11080 char rd[RD_ADDRSTRLEN];
11081
11082 memcpy(&prd, dest_p, sizeof(struct prefix_rd));
11083 prefix_rd2str(&prd, rd, sizeof(rd));
11084 bgp_show_table(vty, bgp, safi, itable, type, output_arg,
11085 rd, next == NULL, &output_cum,
11086 &total_cum, &json_header_depth,
11087 show_flags, RPKI_NOT_BEING_USED);
11088 if (next == NULL)
11089 show_msg = false;
11090 }
11091 }
11092 if (show_msg) {
11093 if (output_cum == 0)
11094 vty_out(vty, "No BGP prefixes displayed, %ld exist\n",
11095 total_cum);
11096 else
11097 vty_out(vty,
11098 "\nDisplayed %ld routes and %ld total paths\n",
11099 output_cum, total_cum);
11100 }
11101 return CMD_SUCCESS;
11102 }
11103 static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
11104 enum bgp_show_type type, void *output_arg,
11105 uint16_t show_flags, enum rpki_states rpki_target_state)
11106 {
11107 struct bgp_table *table;
11108 unsigned long json_header_depth = 0;
11109 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11110
11111 if (bgp == NULL) {
11112 bgp = bgp_get_default();
11113 }
11114
11115 if (bgp == NULL) {
11116 if (!use_json)
11117 vty_out(vty, "No BGP process is configured\n");
11118 else
11119 vty_out(vty, "{}\n");
11120 return CMD_WARNING;
11121 }
11122
11123 table = bgp->rib[afi][safi];
11124 /* use MPLS and ENCAP specific shows until they are merged */
11125 if (safi == SAFI_MPLS_VPN) {
11126 return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
11127 output_arg, use_json);
11128 }
11129
11130 if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
11131 return bgp_show_table_flowspec(vty, bgp, afi, table, type,
11132 output_arg, use_json,
11133 1, NULL, NULL);
11134 }
11135 /* labeled-unicast routes live in the unicast table */
11136 else if (safi == SAFI_LABELED_UNICAST)
11137 safi = SAFI_UNICAST;
11138
11139 return bgp_show_table(vty, bgp, safi, table, type, output_arg, NULL, 1,
11140 NULL, NULL, &json_header_depth, show_flags,
11141 rpki_target_state);
11142 }
11143
11144 static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
11145 safi_t safi, uint16_t show_flags)
11146 {
11147 struct listnode *node, *nnode;
11148 struct bgp *bgp;
11149 int is_first = 1;
11150 bool route_output = false;
11151 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11152
11153 if (use_json)
11154 vty_out(vty, "{\n");
11155
11156 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
11157 route_output = true;
11158 if (use_json) {
11159 if (!is_first)
11160 vty_out(vty, ",\n");
11161 else
11162 is_first = 0;
11163
11164 vty_out(vty, "\"%s\":",
11165 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11166 ? VRF_DEFAULT_NAME
11167 : bgp->name);
11168 } else {
11169 vty_out(vty, "\nInstance %s:\n",
11170 (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11171 ? VRF_DEFAULT_NAME
11172 : bgp->name);
11173 }
11174 bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
11175 show_flags, RPKI_NOT_BEING_USED);
11176 }
11177
11178 if (use_json)
11179 vty_out(vty, "}\n");
11180 else if (!route_output)
11181 vty_out(vty, "%% BGP instance not found\n");
11182 }
11183
11184 /* Header of detailed BGP route information */
11185 void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
11186 struct bgp_dest *dest, struct prefix_rd *prd,
11187 afi_t afi, safi_t safi, json_object *json)
11188 {
11189 struct bgp_path_info *pi;
11190 const struct prefix *p;
11191 struct peer *peer;
11192 struct listnode *node, *nnode;
11193 char buf1[RD_ADDRSTRLEN];
11194 char prefix_str[BUFSIZ];
11195 int count = 0;
11196 int best = 0;
11197 int suppress = 0;
11198 int accept_own = 0;
11199 int route_filter_translated_v4 = 0;
11200 int route_filter_v4 = 0;
11201 int route_filter_translated_v6 = 0;
11202 int route_filter_v6 = 0;
11203 int llgr_stale = 0;
11204 int no_llgr = 0;
11205 int accept_own_nexthop = 0;
11206 int blackhole = 0;
11207 int no_export = 0;
11208 int no_advertise = 0;
11209 int local_as = 0;
11210 int no_peer = 0;
11211 int first = 1;
11212 int has_valid_label = 0;
11213 mpls_label_t label = 0;
11214 json_object *json_adv_to = NULL;
11215
11216 p = bgp_dest_get_prefix(dest);
11217 has_valid_label = bgp_is_valid_label(&dest->local_label);
11218
11219 if (has_valid_label)
11220 label = label_pton(&dest->local_label);
11221
11222 if (safi == SAFI_EVPN) {
11223
11224 if (!json) {
11225 vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
11226 prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
11227 : "",
11228 prd ? ":" : "", (struct prefix_evpn *)p);
11229 } else {
11230 json_object_string_add(json, "rd",
11231 prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
11232 "");
11233 bgp_evpn_route2json((struct prefix_evpn *)p, json);
11234 }
11235 } else {
11236 if (!json) {
11237 vty_out(vty,
11238 "BGP routing table entry for %s%s%pFX, version %" PRIu64
11239 "\n",
11240 ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
11241 ? prefix_rd2str(prd, buf1,
11242 sizeof(buf1))
11243 : ""),
11244 safi == SAFI_MPLS_VPN ? ":" : "", p,
11245 dest->version);
11246
11247 } else {
11248 json_object_string_add(json, "prefix",
11249 prefix2str(p, prefix_str, sizeof(prefix_str)));
11250 json_object_int_add(json, "version", dest->version);
11251
11252 }
11253 }
11254
11255 if (has_valid_label) {
11256 if (json)
11257 json_object_int_add(json, "localLabel", label);
11258 else
11259 vty_out(vty, "Local label: %d\n", label);
11260 }
11261
11262 if (!json)
11263 if (bgp_labeled_safi(safi) && safi != SAFI_EVPN)
11264 vty_out(vty, "not allocated\n");
11265
11266 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
11267 count++;
11268 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
11269 best = count;
11270 if (bgp_path_suppressed(pi))
11271 suppress = 1;
11272
11273 if (pi->attr->community == NULL)
11274 continue;
11275
11276 no_advertise += community_include(
11277 pi->attr->community, COMMUNITY_NO_ADVERTISE);
11278 no_export += community_include(pi->attr->community,
11279 COMMUNITY_NO_EXPORT);
11280 local_as += community_include(pi->attr->community,
11281 COMMUNITY_LOCAL_AS);
11282 accept_own += community_include(pi->attr->community,
11283 COMMUNITY_ACCEPT_OWN);
11284 route_filter_translated_v4 += community_include(
11285 pi->attr->community,
11286 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4);
11287 route_filter_translated_v6 += community_include(
11288 pi->attr->community,
11289 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6);
11290 route_filter_v4 += community_include(
11291 pi->attr->community, COMMUNITY_ROUTE_FILTER_v4);
11292 route_filter_v6 += community_include(
11293 pi->attr->community, COMMUNITY_ROUTE_FILTER_v6);
11294 llgr_stale += community_include(pi->attr->community,
11295 COMMUNITY_LLGR_STALE);
11296 no_llgr += community_include(pi->attr->community,
11297 COMMUNITY_NO_LLGR);
11298 accept_own_nexthop +=
11299 community_include(pi->attr->community,
11300 COMMUNITY_ACCEPT_OWN_NEXTHOP);
11301 blackhole += community_include(pi->attr->community,
11302 COMMUNITY_BLACKHOLE);
11303 no_peer += community_include(pi->attr->community,
11304 COMMUNITY_NO_PEER);
11305 }
11306 }
11307
11308 if (!json) {
11309 vty_out(vty, "Paths: (%d available", count);
11310 if (best) {
11311 vty_out(vty, ", best #%d", best);
11312 if (safi == SAFI_UNICAST) {
11313 if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
11314 vty_out(vty, ", table %s",
11315 VRF_DEFAULT_NAME);
11316 else
11317 vty_out(vty, ", vrf %s",
11318 bgp->name);
11319 }
11320 } else
11321 vty_out(vty, ", no best path");
11322
11323 if (accept_own)
11324 vty_out(vty,
11325 ", accept own local route exported and imported in different VRF");
11326 else if (route_filter_translated_v4)
11327 vty_out(vty,
11328 ", mark translated RTs for VPNv4 route filtering");
11329 else if (route_filter_v4)
11330 vty_out(vty,
11331 ", attach RT as-is for VPNv4 route filtering");
11332 else if (route_filter_translated_v6)
11333 vty_out(vty,
11334 ", mark translated RTs for VPNv6 route filtering");
11335 else if (route_filter_v6)
11336 vty_out(vty,
11337 ", attach RT as-is for VPNv6 route filtering");
11338 else if (llgr_stale)
11339 vty_out(vty,
11340 ", mark routes to be retained for a longer time. Requeres support for Long-lived BGP Graceful Restart");
11341 else if (no_llgr)
11342 vty_out(vty,
11343 ", mark routes to not be treated according to Long-lived BGP Graceful Restart operations");
11344 else if (accept_own_nexthop)
11345 vty_out(vty,
11346 ", accept local nexthop");
11347 else if (blackhole)
11348 vty_out(vty, ", inform peer to blackhole prefix");
11349 else if (no_export)
11350 vty_out(vty, ", not advertised to EBGP peer");
11351 else if (no_advertise)
11352 vty_out(vty, ", not advertised to any peer");
11353 else if (local_as)
11354 vty_out(vty, ", not advertised outside local AS");
11355 else if (no_peer)
11356 vty_out(vty,
11357 ", inform EBGP peer not to advertise to their EBGP peers");
11358
11359 if (suppress)
11360 vty_out(vty,
11361 ", Advertisements suppressed by an aggregate.");
11362 vty_out(vty, ")\n");
11363 }
11364
11365 /* If we are not using addpath then we can display Advertised to and
11366 * that will
11367 * show what peers we advertised the bestpath to. If we are using
11368 * addpath
11369 * though then we must display Advertised to on a path-by-path basis. */
11370 if (!bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
11371 for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
11372 if (bgp_adj_out_lookup(peer, dest, 0)) {
11373 if (json && !json_adv_to)
11374 json_adv_to = json_object_new_object();
11375
11376 route_vty_out_advertised_to(
11377 vty, peer, &first,
11378 " Advertised to non peer-group peers:\n ",
11379 json_adv_to);
11380 }
11381 }
11382
11383 if (json) {
11384 if (json_adv_to) {
11385 json_object_object_add(json, "advertisedTo",
11386 json_adv_to);
11387 }
11388 } else {
11389 if (first)
11390 vty_out(vty, " Not advertised to any peer");
11391 vty_out(vty, "\n");
11392 }
11393 }
11394 }
11395
11396 static void bgp_show_path_info(struct prefix_rd *pfx_rd,
11397 struct bgp_dest *bgp_node, struct vty *vty,
11398 struct bgp *bgp, afi_t afi, safi_t safi,
11399 json_object *json, enum bgp_path_type pathtype,
11400 int *display, enum rpki_states rpki_target_state)
11401 {
11402 struct bgp_path_info *pi;
11403 int header = 1;
11404 char rdbuf[RD_ADDRSTRLEN];
11405 json_object *json_header = NULL;
11406 json_object *json_paths = NULL;
11407 const struct prefix *p = bgp_dest_get_prefix(bgp_node);
11408
11409 for (pi = bgp_dest_get_bgp_path_info(bgp_node); pi; pi = pi->next) {
11410 enum rpki_states rpki_curr_state = RPKI_NOT_BEING_USED;
11411
11412 if (p->family == AF_INET || p->family == AF_INET6)
11413 rpki_curr_state = hook_call(bgp_rpki_prefix_status,
11414 pi->peer, pi->attr, p);
11415
11416 if (rpki_target_state != RPKI_NOT_BEING_USED
11417 && rpki_curr_state != rpki_target_state)
11418 continue;
11419
11420 if (json && !json_paths) {
11421 /* Instantiate json_paths only if path is valid */
11422 json_paths = json_object_new_array();
11423 if (pfx_rd) {
11424 prefix_rd2str(pfx_rd, rdbuf, sizeof(rdbuf));
11425 json_header = json_object_new_object();
11426 } else
11427 json_header = json;
11428 }
11429
11430 if (header) {
11431 route_vty_out_detail_header(
11432 vty, bgp, bgp_node, pfx_rd,
11433 AFI_IP, safi, json_header);
11434 header = 0;
11435 }
11436 (*display)++;
11437
11438 if (pathtype == BGP_PATH_SHOW_ALL
11439 || (pathtype == BGP_PATH_SHOW_BESTPATH
11440 && CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
11441 || (pathtype == BGP_PATH_SHOW_MULTIPATH
11442 && (CHECK_FLAG(pi->flags, BGP_PATH_MULTIPATH)
11443 || CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))))
11444 route_vty_out_detail(vty, bgp, bgp_node, pi, AFI_IP,
11445 safi, rpki_curr_state, json_paths);
11446 }
11447
11448 if (json && json_paths) {
11449 json_object_object_add(json_header, "paths", json_paths);
11450
11451 if (pfx_rd)
11452 json_object_object_add(json, rdbuf, json_header);
11453 }
11454 }
11455
11456 /* Display specified route of BGP table. */
11457 static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
11458 struct bgp_table *rib, const char *ip_str,
11459 afi_t afi, safi_t safi,
11460 enum rpki_states rpki_target_state,
11461 struct prefix_rd *prd, int prefix_check,
11462 enum bgp_path_type pathtype, bool use_json)
11463 {
11464 int ret;
11465 int display = 0;
11466 struct prefix match;
11467 struct bgp_dest *dest;
11468 struct bgp_dest *rm;
11469 struct bgp_table *table;
11470 json_object *json = NULL;
11471 json_object *json_paths = NULL;
11472
11473 /* Check IP address argument. */
11474 ret = str2prefix(ip_str, &match);
11475 if (!ret) {
11476 vty_out(vty, "address is malformed\n");
11477 return CMD_WARNING;
11478 }
11479
11480 match.family = afi2family(afi);
11481
11482 if (use_json)
11483 json = json_object_new_object();
11484
11485 if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP) {
11486 for (dest = bgp_table_top(rib); dest;
11487 dest = bgp_route_next(dest)) {
11488 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11489
11490 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
11491 continue;
11492 table = bgp_dest_get_bgp_table_info(dest);
11493 if (!table)
11494 continue;
11495
11496 rm = bgp_node_match(table, &match);
11497 if (rm == NULL)
11498 continue;
11499
11500 const struct prefix *rm_p = bgp_dest_get_prefix(rm);
11501 if (prefix_check
11502 && rm_p->prefixlen != match.prefixlen) {
11503 bgp_dest_unlock_node(rm);
11504 continue;
11505 }
11506
11507 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11508 bgp, afi, safi, json, pathtype,
11509 &display, rpki_target_state);
11510
11511 bgp_dest_unlock_node(rm);
11512 }
11513 } else if (safi == SAFI_EVPN) {
11514 struct bgp_dest *longest_pfx;
11515 bool is_exact_pfxlen_match = false;
11516
11517 for (dest = bgp_table_top(rib); dest;
11518 dest = bgp_route_next(dest)) {
11519 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11520
11521 if (prd && memcmp(&dest_p->u.val, prd->val, 8) != 0)
11522 continue;
11523 table = bgp_dest_get_bgp_table_info(dest);
11524 if (!table)
11525 continue;
11526
11527 longest_pfx = NULL;
11528 is_exact_pfxlen_match = false;
11529 /*
11530 * Search through all the prefixes for a match. The
11531 * pfx's are enumerated in ascending order of pfxlens.
11532 * So, the last pfx match is the longest match. Set
11533 * is_exact_pfxlen_match when we get exact pfxlen match
11534 */
11535 for (rm = bgp_table_top(table); rm;
11536 rm = bgp_route_next(rm)) {
11537 const struct prefix *rm_p =
11538 bgp_dest_get_prefix(rm);
11539 /*
11540 * Get prefixlen of the ip-prefix within type5
11541 * evpn route
11542 */
11543 if (evpn_type5_prefix_match(rm_p, &match)
11544 && rm->info) {
11545 longest_pfx = rm;
11546 int type5_pfxlen =
11547 bgp_evpn_get_type5_prefixlen(
11548 rm_p);
11549 if (type5_pfxlen == match.prefixlen) {
11550 is_exact_pfxlen_match = true;
11551 bgp_dest_unlock_node(rm);
11552 break;
11553 }
11554 }
11555 }
11556
11557 if (!longest_pfx)
11558 continue;
11559
11560 if (prefix_check && !is_exact_pfxlen_match)
11561 continue;
11562
11563 rm = longest_pfx;
11564 bgp_dest_lock_node(rm);
11565
11566 bgp_show_path_info((struct prefix_rd *)dest_p, rm, vty,
11567 bgp, afi, safi, json, pathtype,
11568 &display, rpki_target_state);
11569
11570 bgp_dest_unlock_node(rm);
11571 }
11572 } else if (safi == SAFI_FLOWSPEC) {
11573 if (use_json)
11574 json_paths = json_object_new_array();
11575
11576 display = bgp_flowspec_display_match_per_ip(afi, rib,
11577 &match, prefix_check,
11578 vty,
11579 use_json,
11580 json_paths);
11581 if (use_json) {
11582 if (display)
11583 json_object_object_add(json, "paths",
11584 json_paths);
11585 else
11586 json_object_free(json_paths);
11587 }
11588 } else {
11589 dest = bgp_node_match(rib, &match);
11590 if (dest != NULL) {
11591 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
11592 if (!prefix_check
11593 || dest_p->prefixlen == match.prefixlen) {
11594 bgp_show_path_info(NULL, dest, vty, bgp, afi,
11595 safi, json, pathtype,
11596 &display, rpki_target_state);
11597 }
11598
11599 bgp_dest_unlock_node(dest);
11600 }
11601 }
11602
11603 if (use_json) {
11604 vty_out(vty, "%s\n", json_object_to_json_string_ext(
11605 json, JSON_C_TO_STRING_PRETTY |
11606 JSON_C_TO_STRING_NOSLASHESCAPE));
11607 json_object_free(json);
11608 } else {
11609 if (!display) {
11610 vty_out(vty, "%% Network not in table\n");
11611 return CMD_WARNING;
11612 }
11613 }
11614
11615 return CMD_SUCCESS;
11616 }
11617
11618 /* Display specified route of Main RIB */
11619 static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
11620 afi_t afi, safi_t safi, struct prefix_rd *prd,
11621 int prefix_check, enum bgp_path_type pathtype,
11622 enum rpki_states rpki_target_state, bool use_json)
11623 {
11624 if (!bgp) {
11625 bgp = bgp_get_default();
11626 if (!bgp) {
11627 if (!use_json)
11628 vty_out(vty, "No BGP process is configured\n");
11629 else
11630 vty_out(vty, "{}\n");
11631 return CMD_WARNING;
11632 }
11633 }
11634
11635 /* labeled-unicast routes live in the unicast table */
11636 if (safi == SAFI_LABELED_UNICAST)
11637 safi = SAFI_UNICAST;
11638
11639 return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
11640 afi, safi, rpki_target_state, prd,
11641 prefix_check, pathtype, use_json);
11642 }
11643
11644 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
11645 struct cmd_token **argv, bool exact, afi_t afi,
11646 safi_t safi, bool uj)
11647 {
11648 struct lcommunity *lcom;
11649 struct buffer *b;
11650 int i;
11651 char *str;
11652 int first = 0;
11653 uint16_t show_flags = 0;
11654 int ret;
11655
11656 if (uj)
11657 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11658
11659 b = buffer_new(1024);
11660 for (i = 0; i < argc; i++) {
11661 if (first)
11662 buffer_putc(b, ' ');
11663 else {
11664 if (strmatch(argv[i]->text, "AA:BB:CC")) {
11665 first = 1;
11666 buffer_putstr(b, argv[i]->arg);
11667 }
11668 }
11669 }
11670 buffer_putc(b, '\0');
11671
11672 str = buffer_getstr(b);
11673 buffer_free(b);
11674
11675 lcom = lcommunity_str2com(str);
11676 XFREE(MTYPE_TMP, str);
11677 if (!lcom) {
11678 vty_out(vty, "%% Large-community malformed\n");
11679 return CMD_WARNING;
11680 }
11681
11682 ret = bgp_show(vty, bgp, afi, safi,
11683 (exact ? bgp_show_type_lcommunity_exact
11684 : bgp_show_type_lcommunity),
11685 lcom, show_flags, RPKI_NOT_BEING_USED);
11686
11687 lcommunity_free(&lcom);
11688 return ret;
11689 }
11690
11691 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
11692 const char *lcom, bool exact, afi_t afi,
11693 safi_t safi, bool uj)
11694 {
11695 struct community_list *list;
11696 uint16_t show_flags = 0;
11697
11698 if (uj)
11699 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11700
11701
11702 list = community_list_lookup(bgp_clist, lcom, 0,
11703 LARGE_COMMUNITY_LIST_MASTER);
11704 if (list == NULL) {
11705 vty_out(vty, "%% %s is not a valid large-community-list name\n",
11706 lcom);
11707 return CMD_WARNING;
11708 }
11709
11710 return bgp_show(vty, bgp, afi, safi,
11711 (exact ? bgp_show_type_lcommunity_list_exact
11712 : bgp_show_type_lcommunity_list),
11713 list, show_flags, RPKI_NOT_BEING_USED);
11714 }
11715
11716 DEFUN (show_ip_bgp_large_community_list,
11717 show_ip_bgp_large_community_list_cmd,
11718 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community-list <(1-500)|LCOMMUNITY_LIST_NAME> [exact-match] [json]",
11719 SHOW_STR
11720 IP_STR
11721 BGP_STR
11722 BGP_INSTANCE_HELP_STR
11723 BGP_AFI_HELP_STR
11724 BGP_SAFI_WITH_LABEL_HELP_STR
11725 "Display routes matching the large-community-list\n"
11726 "large-community-list number\n"
11727 "large-community-list name\n"
11728 "Exact match of the large-communities\n"
11729 JSON_STR)
11730 {
11731 afi_t afi = AFI_IP6;
11732 safi_t safi = SAFI_UNICAST;
11733 int idx = 0;
11734 bool exact_match = 0;
11735 struct bgp *bgp = NULL;
11736 bool uj = use_json(argc, argv);
11737
11738 if (uj)
11739 argc--;
11740
11741 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11742 &bgp, uj);
11743 if (!idx)
11744 return CMD_WARNING;
11745
11746 argv_find(argv, argc, "large-community-list", &idx);
11747
11748 const char *clist_number_or_name = argv[++idx]->arg;
11749
11750 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
11751 exact_match = 1;
11752
11753 return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
11754 exact_match, afi, safi, uj);
11755 }
11756 DEFUN (show_ip_bgp_large_community,
11757 show_ip_bgp_large_community_cmd,
11758 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] large-community [<AA:BB:CC> [exact-match]] [json]",
11759 SHOW_STR
11760 IP_STR
11761 BGP_STR
11762 BGP_INSTANCE_HELP_STR
11763 BGP_AFI_HELP_STR
11764 BGP_SAFI_WITH_LABEL_HELP_STR
11765 "Display routes matching the large-communities\n"
11766 "List of large-community numbers\n"
11767 "Exact match of the large-communities\n"
11768 JSON_STR)
11769 {
11770 afi_t afi = AFI_IP6;
11771 safi_t safi = SAFI_UNICAST;
11772 int idx = 0;
11773 bool exact_match = 0;
11774 struct bgp *bgp = NULL;
11775 bool uj = use_json(argc, argv);
11776 uint16_t show_flags = 0;
11777
11778 if (uj) {
11779 argc--;
11780 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
11781 }
11782
11783 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11784 &bgp, uj);
11785 if (!idx)
11786 return CMD_WARNING;
11787
11788 if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
11789 if (argv_find(argv, argc, "exact-match", &idx))
11790 exact_match = 1;
11791 return bgp_show_lcommunity(vty, bgp, argc, argv,
11792 exact_match, afi, safi, uj);
11793 } else
11794 return bgp_show(vty, bgp, afi, safi,
11795 bgp_show_type_lcommunity_all, NULL, show_flags,
11796 RPKI_NOT_BEING_USED);
11797 }
11798
11799 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
11800 safi_t safi, struct json_object *json_array);
11801 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
11802 safi_t safi, struct json_object *json);
11803
11804
11805 DEFUN(show_ip_bgp_statistics_all, show_ip_bgp_statistics_all_cmd,
11806 "show [ip] bgp [<view|vrf> VIEWVRFNAME] statistics-all [json]",
11807 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR
11808 "Display number of prefixes for all afi/safi\n" JSON_STR)
11809 {
11810 bool uj = use_json(argc, argv);
11811 struct bgp *bgp = NULL;
11812 safi_t safi = SAFI_UNICAST;
11813 afi_t afi = AFI_IP6;
11814 int idx = 0;
11815 struct json_object *json_all = NULL;
11816 struct json_object *json_afi_safi = NULL;
11817
11818 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11819 &bgp, false);
11820 if (!idx)
11821 return CMD_WARNING;
11822
11823 if (uj)
11824 json_all = json_object_new_object();
11825
11826 FOREACH_AFI_SAFI (afi, safi) {
11827 /*
11828 * So limit output to those afi/safi pairs that
11829 * actually have something interesting in them
11830 */
11831 if (strmatch(get_afi_safi_str(afi, safi, true),
11832 "Unknown")) {
11833 continue;
11834 }
11835 if (uj) {
11836 json_afi_safi = json_object_new_array();
11837 json_object_object_add(
11838 json_all,
11839 get_afi_safi_str(afi, safi, true),
11840 json_afi_safi);
11841 } else {
11842 json_afi_safi = NULL;
11843 }
11844
11845 bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11846 }
11847
11848 if (uj) {
11849 vty_out(vty, "%s",
11850 json_object_to_json_string_ext(
11851 json_all, JSON_C_TO_STRING_PRETTY));
11852 json_object_free(json_all);
11853 }
11854
11855 return CMD_SUCCESS;
11856 }
11857
11858 /* BGP route print out function without JSON */
11859 DEFUN (show_ip_bgp_l2vpn_evpn_statistics,
11860 show_ip_bgp_l2vpn_evpn_statistics_cmd,
11861 "show [ip] bgp [<view|vrf> VIEWVRFNAME] l2vpn evpn statistics [json]",
11862 SHOW_STR
11863 IP_STR
11864 BGP_STR
11865 BGP_INSTANCE_HELP_STR
11866 L2VPN_HELP_STR
11867 EVPN_HELP_STR
11868 "BGP RIB advertisement statistics\n"
11869 JSON_STR)
11870 {
11871 afi_t afi = AFI_IP6;
11872 safi_t safi = SAFI_UNICAST;
11873 struct bgp *bgp = NULL;
11874 int idx = 0, ret;
11875 bool uj = use_json(argc, argv);
11876 struct json_object *json_afi_safi = NULL, *json = NULL;
11877
11878 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11879 &bgp, false);
11880 if (!idx)
11881 return CMD_WARNING;
11882
11883 if (uj)
11884 json_afi_safi = json_object_new_array();
11885 else
11886 json_afi_safi = NULL;
11887
11888 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11889
11890 if (uj) {
11891 json = json_object_new_object();
11892 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11893 json_afi_safi);
11894 vty_out(vty, "%s", json_object_to_json_string_ext(
11895 json, JSON_C_TO_STRING_PRETTY));
11896 json_object_free(json);
11897 }
11898 return ret;
11899 }
11900
11901 /* BGP route print out function without JSON */
11902 DEFUN(show_ip_bgp_afi_safi_statistics, show_ip_bgp_afi_safi_statistics_cmd,
11903 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11904 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11905 "]]\
11906 statistics [json]",
11907 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11908 BGP_SAFI_WITH_LABEL_HELP_STR
11909 "BGP RIB advertisement statistics\n" JSON_STR)
11910 {
11911 afi_t afi = AFI_IP6;
11912 safi_t safi = SAFI_UNICAST;
11913 struct bgp *bgp = NULL;
11914 int idx = 0, ret;
11915 bool uj = use_json(argc, argv);
11916 struct json_object *json_afi_safi = NULL, *json = NULL;
11917
11918 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11919 &bgp, false);
11920 if (!idx)
11921 return CMD_WARNING;
11922
11923 if (uj)
11924 json_afi_safi = json_object_new_array();
11925 else
11926 json_afi_safi = NULL;
11927
11928 ret = bgp_table_stats(vty, bgp, afi, safi, json_afi_safi);
11929
11930 if (uj) {
11931 json = json_object_new_object();
11932 json_object_object_add(json, get_afi_safi_str(afi, safi, true),
11933 json_afi_safi);
11934 vty_out(vty, "%s",
11935 json_object_to_json_string_ext(
11936 json, JSON_C_TO_STRING_PRETTY));
11937 json_object_free(json);
11938 }
11939 return ret;
11940 }
11941
11942 /* BGP route print out function without JSON */
11943 DEFPY(show_ip_bgp, show_ip_bgp_cmd,
11944 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
11945 " [" BGP_SAFI_WITH_LABEL_CMD_STR
11946 "]]\
11947 <[all$all] dampening <parameters>\
11948 |route-map WORD\
11949 |prefix-list WORD\
11950 |filter-list WORD\
11951 |community-list <(1-500)|COMMUNITY_LIST_NAME> [exact-match]\
11952 |A.B.C.D/M longer-prefixes\
11953 |X:X::X:X/M longer-prefixes\
11954 >",
11955 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
11956 BGP_SAFI_WITH_LABEL_HELP_STR
11957 "Display the entries for all address families\n"
11958 "Display detailed information about dampening\n"
11959 "Display detail of configured dampening parameters\n"
11960 "Display routes matching the route-map\n"
11961 "A route-map to match on\n"
11962 "Display routes conforming to the prefix-list\n"
11963 "Prefix-list name\n"
11964 "Display routes conforming to the filter-list\n"
11965 "Regular expression access list name\n"
11966 "Display routes matching the community-list\n"
11967 "community-list number\n"
11968 "community-list name\n"
11969 "Exact match of the communities\n"
11970 "IPv4 prefix\n"
11971 "Display route and more specific routes\n"
11972 "IPv6 prefix\n"
11973 "Display route and more specific routes\n")
11974 {
11975 afi_t afi = AFI_IP6;
11976 safi_t safi = SAFI_UNICAST;
11977 int exact_match = 0;
11978 struct bgp *bgp = NULL;
11979 int idx = 0;
11980 uint16_t show_flags = 0;
11981
11982 /* [<ipv4|ipv6> [all]] */
11983 if (all) {
11984 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
11985 if (argv_find(argv, argc, "ipv4", &idx))
11986 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
11987
11988 if (argv_find(argv, argc, "ipv6", &idx))
11989 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
11990 }
11991
11992 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
11993 &bgp, false);
11994 if (!idx)
11995 return CMD_WARNING;
11996
11997 if (argv_find(argv, argc, "dampening", &idx)) {
11998 if (argv_find(argv, argc, "parameters", &idx))
11999 return bgp_show_dampening_parameters(vty, afi, safi,
12000 show_flags);
12001 }
12002
12003 if (argv_find(argv, argc, "prefix-list", &idx))
12004 return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
12005 safi, bgp_show_type_prefix_list);
12006
12007 if (argv_find(argv, argc, "filter-list", &idx))
12008 return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
12009 safi, bgp_show_type_filter_list);
12010
12011 if (argv_find(argv, argc, "route-map", &idx))
12012 return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
12013 safi, bgp_show_type_route_map);
12014
12015 if (argv_find(argv, argc, "community-list", &idx)) {
12016 const char *clist_number_or_name = argv[++idx]->arg;
12017 if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
12018 exact_match = 1;
12019 return bgp_show_community_list(vty, bgp, clist_number_or_name,
12020 exact_match, afi, safi);
12021 }
12022 /* prefix-longer */
12023 if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12024 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12025 return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
12026 safi,
12027 bgp_show_type_prefix_longer);
12028
12029 return CMD_WARNING;
12030 }
12031
12032 /* BGP route print out function with JSON */
12033 DEFPY(show_ip_bgp_json, show_ip_bgp_json_cmd,
12034 "show [ip] bgp [<view|vrf> VIEWVRFNAME] [" BGP_AFI_CMD_STR
12035 " [" BGP_SAFI_WITH_LABEL_CMD_STR
12036 "]]\
12037 [all$all]\
12038 [cidr-only\
12039 |dampening <flap-statistics|dampened-paths>\
12040 |community [AA:NN|local-AS|no-advertise|no-export\
12041 |graceful-shutdown|no-peer|blackhole|llgr-stale|no-llgr\
12042 |accept-own|accept-own-nexthop|route-filter-v6\
12043 |route-filter-v4|route-filter-translated-v6\
12044 |route-filter-translated-v4] [exact-match]\
12045 |rpki <invalid|valid|notfound>\
12046 |version (1-4294967295)\
12047 |alias ALIAS_NAME\
12048 ] [json$uj [detail$detail] | wide$wide]",
12049 SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
12050 BGP_SAFI_WITH_LABEL_HELP_STR
12051 "Display the entries for all address families\n"
12052 "Display only routes with non-natural netmasks\n"
12053 "Display detailed information about dampening\n"
12054 "Display flap statistics of routes\n"
12055 "Display paths suppressed due to dampening\n"
12056 "Display routes matching the communities\n" COMMUNITY_AANN_STR
12057 "Do not send outside local AS (well-known community)\n"
12058 "Do not advertise to any peer (well-known community)\n"
12059 "Do not export to next AS (well-known community)\n"
12060 "Graceful shutdown (well-known community)\n"
12061 "Do not export to any peer (well-known community)\n"
12062 "Inform EBGP peers to blackhole traffic to prefix (well-known community)\n"
12063 "Staled Long-lived Graceful Restart VPN route (well-known community)\n"
12064 "Removed because Long-lived Graceful Restart was not enabled for VPN route (well-known community)\n"
12065 "Should accept local VPN route if exported and imported into different VRF (well-known community)\n"
12066 "Should accept VPN route with local nexthop (well-known community)\n"
12067 "RT VPNv6 route filtering (well-known community)\n"
12068 "RT VPNv4 route filtering (well-known community)\n"
12069 "RT translated VPNv6 route filtering (well-known community)\n"
12070 "RT translated VPNv4 route filtering (well-known community)\n"
12071 "Exact match of the communities\n"
12072 "RPKI route types\n"
12073 "A valid path as determined by rpki\n"
12074 "A invalid path as determined by rpki\n"
12075 "A path that has no rpki data\n"
12076 "Display prefixes with matching version numbers\n"
12077 "Version number and above\n"
12078 "Display prefixes with matching BGP community alias\n"
12079 "BGP community alias\n" JSON_STR
12080 "Display detailed version of JSON output\n"
12081 "Increase table width for longer prefixes\n")
12082 {
12083 afi_t afi = AFI_IP6;
12084 safi_t safi = SAFI_UNICAST;
12085 enum bgp_show_type sh_type = bgp_show_type_normal;
12086 struct bgp *bgp = NULL;
12087 int idx = 0;
12088 int exact_match = 0;
12089 char *community = NULL;
12090 char *prefix_version = NULL;
12091 char *bgp_community_alias = NULL;
12092 bool first = true;
12093 uint16_t show_flags = 0;
12094 enum rpki_states rpki_target_state = RPKI_NOT_BEING_USED;
12095
12096 if (uj) {
12097 argc--;
12098 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12099 }
12100
12101 if (detail)
12102 SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
12103
12104 /* [<ipv4|ipv6> [all]] */
12105 if (all) {
12106 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
12107
12108 if (argv_find(argv, argc, "ipv4", &idx))
12109 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
12110
12111 if (argv_find(argv, argc, "ipv6", &idx))
12112 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
12113 }
12114
12115 if (wide)
12116 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12117
12118 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12119 &bgp, uj);
12120 if (!idx)
12121 return CMD_WARNING;
12122
12123 if (argv_find(argv, argc, "cidr-only", &idx))
12124 sh_type = bgp_show_type_cidr_only;
12125
12126 if (argv_find(argv, argc, "dampening", &idx)) {
12127 if (argv_find(argv, argc, "dampened-paths", &idx))
12128 sh_type = bgp_show_type_dampend_paths;
12129 else if (argv_find(argv, argc, "flap-statistics", &idx))
12130 sh_type = bgp_show_type_flap_statistics;
12131 }
12132
12133 if (argv_find(argv, argc, "community", &idx)) {
12134 char *maybecomm = NULL;
12135
12136 if (idx + 1 < argc) {
12137 if (argv[idx + 1]->type == VARIABLE_TKN)
12138 maybecomm = argv[idx + 1]->arg;
12139 else
12140 maybecomm = argv[idx + 1]->text;
12141 }
12142
12143 if (maybecomm && !strmatch(maybecomm, "json")
12144 && !strmatch(maybecomm, "exact-match"))
12145 community = maybecomm;
12146
12147 if (argv_find(argv, argc, "exact-match", &idx))
12148 exact_match = 1;
12149
12150 if (!community)
12151 sh_type = bgp_show_type_community_all;
12152 }
12153
12154 if (argv_find(argv, argc, "rpki", &idx)) {
12155 sh_type = bgp_show_type_rpki;
12156 if (argv_find(argv, argc, "valid", &idx))
12157 rpki_target_state = RPKI_VALID;
12158 else if (argv_find(argv, argc, "invalid", &idx))
12159 rpki_target_state = RPKI_INVALID;
12160 }
12161
12162 /* Display prefixes with matching version numbers */
12163 if (argv_find(argv, argc, "version", &idx)) {
12164 sh_type = bgp_show_type_prefix_version;
12165 prefix_version = argv[idx + 1]->arg;
12166 }
12167
12168 /* Display prefixes with matching BGP community alias */
12169 if (argv_find(argv, argc, "alias", &idx)) {
12170 sh_type = bgp_show_type_community_alias;
12171 bgp_community_alias = argv[idx + 1]->arg;
12172 }
12173
12174 if (!all) {
12175 /* show bgp: AFI_IP6, show ip bgp: AFI_IP */
12176 if (community)
12177 return bgp_show_community(vty, bgp, community,
12178 exact_match, afi, safi,
12179 show_flags);
12180 else if (prefix_version)
12181 return bgp_show(vty, bgp, afi, safi, sh_type,
12182 prefix_version, show_flags,
12183 rpki_target_state);
12184 else if (bgp_community_alias)
12185 return bgp_show(vty, bgp, afi, safi, sh_type,
12186 bgp_community_alias, show_flags,
12187 rpki_target_state);
12188 else
12189 return bgp_show(vty, bgp, afi, safi, sh_type, NULL,
12190 show_flags, rpki_target_state);
12191 } else {
12192 /* show <ip> bgp ipv4 all: AFI_IP, show <ip> bgp ipv6 all:
12193 * AFI_IP6 */
12194
12195 if (uj)
12196 vty_out(vty, "{\n");
12197
12198 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12199 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
12200 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
12201 ? AFI_IP
12202 : AFI_IP6;
12203 FOREACH_SAFI (safi) {
12204 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12205 continue;
12206
12207 if (uj) {
12208 if (first)
12209 first = false;
12210 else
12211 vty_out(vty, ",\n");
12212 vty_out(vty, "\"%s\":{\n",
12213 get_afi_safi_str(afi, safi,
12214 true));
12215 } else
12216 vty_out(vty,
12217 "\nFor address family: %s\n",
12218 get_afi_safi_str(afi, safi,
12219 false));
12220
12221 if (community)
12222 bgp_show_community(vty, bgp, community,
12223 exact_match, afi,
12224 safi, show_flags);
12225 else if (prefix_version)
12226 return bgp_show(vty, bgp, afi, safi,
12227 sh_type, prefix_version,
12228 show_flags,
12229 rpki_target_state);
12230 else if (bgp_community_alias)
12231 return bgp_show(
12232 vty, bgp, afi, safi, sh_type,
12233 bgp_community_alias, show_flags,
12234 rpki_target_state);
12235 else
12236 bgp_show(vty, bgp, afi, safi, sh_type,
12237 NULL, show_flags,
12238 rpki_target_state);
12239 if (uj)
12240 vty_out(vty, "}\n");
12241 }
12242 } else {
12243 /* show <ip> bgp all: for each AFI and SAFI*/
12244 FOREACH_AFI_SAFI (afi, safi) {
12245 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
12246 continue;
12247
12248 if (uj) {
12249 if (first)
12250 first = false;
12251 else
12252 vty_out(vty, ",\n");
12253
12254 vty_out(vty, "\"%s\":{\n",
12255 get_afi_safi_str(afi, safi,
12256 true));
12257 } else
12258 vty_out(vty,
12259 "\nFor address family: %s\n",
12260 get_afi_safi_str(afi, safi,
12261 false));
12262
12263 if (community)
12264 bgp_show_community(vty, bgp, community,
12265 exact_match, afi,
12266 safi, show_flags);
12267 else if (prefix_version)
12268 return bgp_show(vty, bgp, afi, safi,
12269 sh_type, prefix_version,
12270 show_flags,
12271 rpki_target_state);
12272 else
12273 bgp_show(vty, bgp, afi, safi, sh_type,
12274 NULL, show_flags,
12275 rpki_target_state);
12276 if (uj)
12277 vty_out(vty, "}\n");
12278 }
12279 }
12280 if (uj)
12281 vty_out(vty, "}\n");
12282 }
12283 return CMD_SUCCESS;
12284 }
12285
12286 DEFUN (show_ip_bgp_route,
12287 show_ip_bgp_route_cmd,
12288 "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]",
12289 SHOW_STR
12290 IP_STR
12291 BGP_STR
12292 BGP_INSTANCE_HELP_STR
12293 BGP_AFI_HELP_STR
12294 BGP_SAFI_WITH_LABEL_HELP_STR
12295 "Network in the BGP routing table to display\n"
12296 "IPv4 prefix\n"
12297 "Network in the BGP routing table to display\n"
12298 "IPv6 prefix\n"
12299 "Display only the bestpath\n"
12300 "Display only multipaths\n"
12301 "Display only paths that match the specified rpki state\n"
12302 "A valid path as determined by rpki\n"
12303 "A invalid path as determined by rpki\n"
12304 "A path that has no rpki data\n"
12305 JSON_STR)
12306 {
12307 int prefix_check = 0;
12308
12309 afi_t afi = AFI_IP6;
12310 safi_t safi = SAFI_UNICAST;
12311 char *prefix = NULL;
12312 struct bgp *bgp = NULL;
12313 enum bgp_path_type path_type;
12314 bool uj = use_json(argc, argv);
12315
12316 int idx = 0;
12317
12318 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12319 &bgp, uj);
12320 if (!idx)
12321 return CMD_WARNING;
12322
12323 if (!bgp) {
12324 vty_out(vty,
12325 "Specified 'all' vrf's but this command currently only works per view/vrf\n");
12326 return CMD_WARNING;
12327 }
12328
12329 /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
12330 if (argv_find(argv, argc, "A.B.C.D", &idx)
12331 || argv_find(argv, argc, "X:X::X:X", &idx))
12332 prefix_check = 0;
12333 else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
12334 || argv_find(argv, argc, "X:X::X:X/M", &idx))
12335 prefix_check = 1;
12336
12337 if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
12338 && afi != AFI_IP6) {
12339 vty_out(vty,
12340 "%% Cannot specify IPv6 address or prefix with IPv4 AFI\n");
12341 return CMD_WARNING;
12342 }
12343 if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
12344 && afi != AFI_IP) {
12345 vty_out(vty,
12346 "%% Cannot specify IPv4 address or prefix with IPv6 AFI\n");
12347 return CMD_WARNING;
12348 }
12349
12350 prefix = argv[idx]->arg;
12351
12352 /* [<bestpath|multipath>] */
12353 if (argv_find(argv, argc, "bestpath", &idx))
12354 path_type = BGP_PATH_SHOW_BESTPATH;
12355 else if (argv_find(argv, argc, "multipath", &idx))
12356 path_type = BGP_PATH_SHOW_MULTIPATH;
12357 else
12358 path_type = BGP_PATH_SHOW_ALL;
12359
12360 return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
12361 path_type, RPKI_NOT_BEING_USED, uj);
12362 }
12363
12364 DEFUN (show_ip_bgp_regexp,
12365 show_ip_bgp_regexp_cmd,
12366 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] regexp REGEX [json]",
12367 SHOW_STR
12368 IP_STR
12369 BGP_STR
12370 BGP_INSTANCE_HELP_STR
12371 BGP_AFI_HELP_STR
12372 BGP_SAFI_WITH_LABEL_HELP_STR
12373 "Display routes matching the AS path regular expression\n"
12374 "A regular-expression (1234567890_^|[,{}() ]$*+.?-\\) to match the BGP AS paths\n"
12375 JSON_STR)
12376 {
12377 afi_t afi = AFI_IP6;
12378 safi_t safi = SAFI_UNICAST;
12379 struct bgp *bgp = NULL;
12380 bool uj = use_json(argc, argv);
12381 char *regstr = NULL;
12382
12383 int idx = 0;
12384 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12385 &bgp, false);
12386 if (!idx)
12387 return CMD_WARNING;
12388
12389 // get index of regex
12390 if (argv_find(argv, argc, "REGEX", &idx))
12391 regstr = argv[idx]->arg;
12392
12393 assert(regstr);
12394 return bgp_show_regexp(vty, bgp, (const char *)regstr, afi, safi,
12395 bgp_show_type_regexp, uj);
12396 }
12397
12398 DEFPY (show_ip_bgp_instance_all,
12399 show_ip_bgp_instance_all_cmd,
12400 "show [ip] bgp <view|vrf> all ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] [json$uj | wide$wide]",
12401 SHOW_STR
12402 IP_STR
12403 BGP_STR
12404 BGP_INSTANCE_ALL_HELP_STR
12405 BGP_AFI_HELP_STR
12406 BGP_SAFI_WITH_LABEL_HELP_STR
12407 JSON_STR
12408 "Increase table width for longer prefixes\n")
12409 {
12410 afi_t afi = AFI_IP;
12411 safi_t safi = SAFI_UNICAST;
12412 struct bgp *bgp = NULL;
12413 int idx = 0;
12414 uint16_t show_flags = 0;
12415
12416 if (uj) {
12417 argc--;
12418 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12419 }
12420
12421 if (wide)
12422 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
12423
12424 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
12425 &bgp, uj);
12426 if (!idx)
12427 return CMD_WARNING;
12428
12429 bgp_show_all_instances_routes_vty(vty, afi, safi, show_flags);
12430 return CMD_SUCCESS;
12431 }
12432
12433 static int bgp_show_regexp(struct vty *vty, struct bgp *bgp, const char *regstr,
12434 afi_t afi, safi_t safi, enum bgp_show_type type,
12435 bool use_json)
12436 {
12437 regex_t *regex;
12438 int rc;
12439 uint16_t show_flags = 0;
12440
12441 if (use_json)
12442 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
12443
12444 if (!config_bgp_aspath_validate(regstr)) {
12445 vty_out(vty, "Invalid character in REGEX %s\n",
12446 regstr);
12447 return CMD_WARNING_CONFIG_FAILED;
12448 }
12449
12450 regex = bgp_regcomp(regstr);
12451 if (!regex) {
12452 vty_out(vty, "Can't compile regexp %s\n", regstr);
12453 return CMD_WARNING;
12454 }
12455
12456 rc = bgp_show(vty, bgp, afi, safi, type, regex, show_flags,
12457 RPKI_NOT_BEING_USED);
12458 bgp_regex_free(regex);
12459 return rc;
12460 }
12461
12462 static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
12463 const char *prefix_list_str, afi_t afi,
12464 safi_t safi, enum bgp_show_type type)
12465 {
12466 struct prefix_list *plist;
12467 uint16_t show_flags = 0;
12468
12469 plist = prefix_list_lookup(afi, prefix_list_str);
12470 if (plist == NULL) {
12471 vty_out(vty, "%% %s is not a valid prefix-list name\n",
12472 prefix_list_str);
12473 return CMD_WARNING;
12474 }
12475
12476 return bgp_show(vty, bgp, afi, safi, type, plist, show_flags,
12477 RPKI_NOT_BEING_USED);
12478 }
12479
12480 static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
12481 const char *filter, afi_t afi, safi_t safi,
12482 enum bgp_show_type type)
12483 {
12484 struct as_list *as_list;
12485 uint16_t show_flags = 0;
12486
12487 as_list = as_list_lookup(filter);
12488 if (as_list == NULL) {
12489 vty_out(vty, "%% %s is not a valid AS-path access-list name\n",
12490 filter);
12491 return CMD_WARNING;
12492 }
12493
12494 return bgp_show(vty, bgp, afi, safi, type, as_list, show_flags,
12495 RPKI_NOT_BEING_USED);
12496 }
12497
12498 static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
12499 const char *rmap_str, afi_t afi, safi_t safi,
12500 enum bgp_show_type type)
12501 {
12502 struct route_map *rmap;
12503 uint16_t show_flags = 0;
12504
12505 rmap = route_map_lookup_by_name(rmap_str);
12506 if (!rmap) {
12507 vty_out(vty, "%% %s is not a valid route-map name\n", rmap_str);
12508 return CMD_WARNING;
12509 }
12510
12511 return bgp_show(vty, bgp, afi, safi, type, rmap, show_flags,
12512 RPKI_NOT_BEING_USED);
12513 }
12514
12515 static int bgp_show_community(struct vty *vty, struct bgp *bgp,
12516 const char *comstr, int exact, afi_t afi,
12517 safi_t safi, uint16_t show_flags)
12518 {
12519 struct community *com;
12520 int ret = 0;
12521
12522 com = community_str2com(comstr);
12523 if (!com) {
12524 vty_out(vty, "%% Community malformed: %s\n", comstr);
12525 return CMD_WARNING;
12526 }
12527
12528 ret = bgp_show(vty, bgp, afi, safi,
12529 (exact ? bgp_show_type_community_exact
12530 : bgp_show_type_community),
12531 com, show_flags, RPKI_NOT_BEING_USED);
12532 community_free(&com);
12533
12534 return ret;
12535 }
12536
12537 static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
12538 const char *com, int exact, afi_t afi,
12539 safi_t safi)
12540 {
12541 struct community_list *list;
12542 uint16_t show_flags = 0;
12543
12544 list = community_list_lookup(bgp_clist, com, 0, COMMUNITY_LIST_MASTER);
12545 if (list == NULL) {
12546 vty_out(vty, "%% %s is not a valid community-list name\n", com);
12547 return CMD_WARNING;
12548 }
12549
12550 return bgp_show(vty, bgp, afi, safi,
12551 (exact ? bgp_show_type_community_list_exact
12552 : bgp_show_type_community_list),
12553 list, show_flags, RPKI_NOT_BEING_USED);
12554 }
12555
12556 static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
12557 const char *prefix, afi_t afi, safi_t safi,
12558 enum bgp_show_type type)
12559 {
12560 int ret;
12561 struct prefix *p;
12562 uint16_t show_flags = 0;
12563
12564 p = prefix_new();
12565
12566 ret = str2prefix(prefix, p);
12567 if (!ret) {
12568 vty_out(vty, "%% Malformed Prefix\n");
12569 return CMD_WARNING;
12570 }
12571
12572 ret = bgp_show(vty, bgp, afi, safi, type, p, show_flags,
12573 RPKI_NOT_BEING_USED);
12574 prefix_free(&p);
12575 return ret;
12576 }
12577
12578 enum bgp_stats {
12579 BGP_STATS_MAXBITLEN = 0,
12580 BGP_STATS_RIB,
12581 BGP_STATS_PREFIXES,
12582 BGP_STATS_TOTPLEN,
12583 BGP_STATS_UNAGGREGATEABLE,
12584 BGP_STATS_MAX_AGGREGATEABLE,
12585 BGP_STATS_AGGREGATES,
12586 BGP_STATS_SPACE,
12587 BGP_STATS_ASPATH_COUNT,
12588 BGP_STATS_ASPATH_MAXHOPS,
12589 BGP_STATS_ASPATH_TOTHOPS,
12590 BGP_STATS_ASPATH_MAXSIZE,
12591 BGP_STATS_ASPATH_TOTSIZE,
12592 BGP_STATS_ASN_HIGHEST,
12593 BGP_STATS_MAX,
12594 };
12595
12596 #define TABLE_STATS_IDX_VTY 0
12597 #define TABLE_STATS_IDX_JSON 1
12598
12599 static const char *table_stats_strs[][2] = {
12600 [BGP_STATS_PREFIXES] = {"Total Prefixes", "totalPrefixes"},
12601 [BGP_STATS_TOTPLEN] = {"Average prefix length", "averagePrefixLength"},
12602 [BGP_STATS_RIB] = {"Total Advertisements", "totalAdvertisements"},
12603 [BGP_STATS_UNAGGREGATEABLE] = {"Unaggregateable prefixes",
12604 "unaggregateablePrefixes"},
12605 [BGP_STATS_MAX_AGGREGATEABLE] = {"Maximum aggregateable prefixes",
12606 "maximumAggregateablePrefixes"},
12607 [BGP_STATS_AGGREGATES] = {"BGP Aggregate advertisements",
12608 "bgpAggregateAdvertisements"},
12609 [BGP_STATS_SPACE] = {"Address space advertised",
12610 "addressSpaceAdvertised"},
12611 [BGP_STATS_ASPATH_COUNT] = {"Advertisements with paths",
12612 "advertisementsWithPaths"},
12613 [BGP_STATS_ASPATH_MAXHOPS] = {"Longest AS-Path (hops)",
12614 "longestAsPath"},
12615 [BGP_STATS_ASPATH_MAXSIZE] = {"Largest AS-Path (bytes)",
12616 "largestAsPath"},
12617 [BGP_STATS_ASPATH_TOTHOPS] = {"Average AS-Path length (hops)",
12618 "averageAsPathLengthHops"},
12619 [BGP_STATS_ASPATH_TOTSIZE] = {"Average AS-Path size (bytes)",
12620 "averageAsPathSizeBytes"},
12621 [BGP_STATS_ASN_HIGHEST] = {"Highest public ASN", "highestPublicAsn"},
12622 [BGP_STATS_MAX] = {NULL, NULL}
12623 };
12624
12625 struct bgp_table_stats {
12626 struct bgp_table *table;
12627 unsigned long long counts[BGP_STATS_MAX];
12628 double total_space;
12629 };
12630
12631 static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
12632 struct bgp_table_stats *ts, unsigned int space)
12633 {
12634 struct bgp_dest *pdest = bgp_dest_parent_nolock(dest);
12635 struct bgp_path_info *pi;
12636 const struct prefix *rn_p;
12637
12638 if (!bgp_dest_has_bgp_path_info_data(dest))
12639 return;
12640
12641 rn_p = bgp_dest_get_prefix(dest);
12642 ts->counts[BGP_STATS_PREFIXES]++;
12643 ts->counts[BGP_STATS_TOTPLEN] += rn_p->prefixlen;
12644
12645 /* check if the prefix is included by any other announcements */
12646 while (pdest && !bgp_dest_has_bgp_path_info_data(pdest))
12647 pdest = bgp_dest_parent_nolock(pdest);
12648
12649 if (pdest == NULL || pdest == top) {
12650 ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
12651 /* announced address space */
12652 if (space)
12653 ts->total_space += pow(2.0, space - rn_p->prefixlen);
12654 } else if (bgp_dest_has_bgp_path_info_data(pdest))
12655 ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
12656
12657
12658 for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
12659 ts->counts[BGP_STATS_RIB]++;
12660
12661 if (CHECK_FLAG(pi->attr->flag,
12662 ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)))
12663 ts->counts[BGP_STATS_AGGREGATES]++;
12664
12665 /* as-path stats */
12666 if (pi->attr->aspath) {
12667 unsigned int hops = aspath_count_hops(pi->attr->aspath);
12668 unsigned int size = aspath_size(pi->attr->aspath);
12669 as_t highest = aspath_highest(pi->attr->aspath);
12670
12671 ts->counts[BGP_STATS_ASPATH_COUNT]++;
12672
12673 if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
12674 ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
12675
12676 if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
12677 ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
12678
12679 ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
12680 ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
12681 if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
12682 ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
12683 }
12684 }
12685 }
12686
12687 static int bgp_table_stats_walker(struct thread *t)
12688 {
12689 struct bgp_dest *dest, *ndest;
12690 struct bgp_dest *top;
12691 struct bgp_table_stats *ts = THREAD_ARG(t);
12692 unsigned int space = 0;
12693
12694 if (!(top = bgp_table_top(ts->table)))
12695 return 0;
12696
12697 switch (ts->table->afi) {
12698 case AFI_IP:
12699 space = IPV4_MAX_BITLEN;
12700 break;
12701 case AFI_IP6:
12702 space = IPV6_MAX_BITLEN;
12703 break;
12704 case AFI_L2VPN:
12705 space = EVPN_ROUTE_PREFIXLEN;
12706 break;
12707 default:
12708 return 0;
12709 }
12710
12711 ts->counts[BGP_STATS_MAXBITLEN] = space;
12712
12713 for (dest = top; dest; dest = bgp_route_next(dest)) {
12714 if (ts->table->safi == SAFI_MPLS_VPN
12715 || ts->table->safi == SAFI_ENCAP
12716 || ts->table->safi == SAFI_EVPN) {
12717 struct bgp_table *table;
12718
12719 table = bgp_dest_get_bgp_table_info(dest);
12720 if (!table)
12721 continue;
12722
12723 top = bgp_table_top(table);
12724 for (ndest = bgp_table_top(table); ndest;
12725 ndest = bgp_route_next(ndest))
12726 bgp_table_stats_rn(ndest, top, ts, space);
12727 } else {
12728 bgp_table_stats_rn(dest, top, ts, space);
12729 }
12730 }
12731
12732 return 0;
12733 }
12734
12735 static void bgp_table_stats_all(struct vty *vty, afi_t afi, safi_t safi,
12736 struct json_object *json_array)
12737 {
12738 struct listnode *node, *nnode;
12739 struct bgp *bgp;
12740
12741 for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
12742 bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12743 }
12744
12745 static int bgp_table_stats_single(struct vty *vty, struct bgp *bgp, afi_t afi,
12746 safi_t safi, struct json_object *json_array)
12747 {
12748 struct bgp_table_stats ts;
12749 unsigned int i;
12750 int ret = CMD_SUCCESS;
12751 char temp_buf[20];
12752 struct json_object *json = NULL;
12753
12754 if (json_array)
12755 json = json_object_new_object();
12756
12757 if (!bgp->rib[afi][safi]) {
12758 char warning_msg[50];
12759
12760 snprintf(warning_msg, sizeof(warning_msg),
12761 "%% No RIB exist's for the AFI(%d)/SAFI(%d)", afi,
12762 safi);
12763
12764 if (!json)
12765 vty_out(vty, "%s\n", warning_msg);
12766 else
12767 json_object_string_add(json, "warning", warning_msg);
12768
12769 ret = CMD_WARNING;
12770 goto end_table_stats;
12771 }
12772
12773 if (!json)
12774 vty_out(vty, "BGP %s RIB statistics (%s)\n",
12775 get_afi_safi_str(afi, safi, false), bgp->name_pretty);
12776 else
12777 json_object_string_add(json, "instance", bgp->name_pretty);
12778
12779 /* labeled-unicast routes live in the unicast table */
12780 if (safi == SAFI_LABELED_UNICAST)
12781 safi = SAFI_UNICAST;
12782
12783 memset(&ts, 0, sizeof(ts));
12784 ts.table = bgp->rib[afi][safi];
12785 thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
12786
12787 for (i = 0; i < BGP_STATS_MAX; i++) {
12788 if ((!json && !table_stats_strs[i][TABLE_STATS_IDX_VTY])
12789 || (json && !table_stats_strs[i][TABLE_STATS_IDX_JSON]))
12790 continue;
12791
12792 switch (i) {
12793 case BGP_STATS_ASPATH_TOTHOPS:
12794 case BGP_STATS_ASPATH_TOTSIZE:
12795 if (!json) {
12796 snprintf(
12797 temp_buf, sizeof(temp_buf), "%12.2f",
12798 ts.counts[i]
12799 ? (float)ts.counts[i]
12800 / (float)ts.counts
12801 [BGP_STATS_ASPATH_COUNT]
12802 : 0);
12803 vty_out(vty, "%-30s: %s",
12804 table_stats_strs[i]
12805 [TABLE_STATS_IDX_VTY],
12806 temp_buf);
12807 } else {
12808 json_object_double_add(
12809 json,
12810 table_stats_strs[i]
12811 [TABLE_STATS_IDX_JSON],
12812 ts.counts[i]
12813 ? (double)ts.counts[i]
12814 / (double)ts.counts
12815 [BGP_STATS_ASPATH_COUNT]
12816 : 0);
12817 }
12818 break;
12819 case BGP_STATS_TOTPLEN:
12820 if (!json) {
12821 snprintf(
12822 temp_buf, sizeof(temp_buf), "%12.2f",
12823 ts.counts[i]
12824 ? (float)ts.counts[i]
12825 / (float)ts.counts
12826 [BGP_STATS_PREFIXES]
12827 : 0);
12828 vty_out(vty, "%-30s: %s",
12829 table_stats_strs[i]
12830 [TABLE_STATS_IDX_VTY],
12831 temp_buf);
12832 } else {
12833 json_object_double_add(
12834 json,
12835 table_stats_strs[i]
12836 [TABLE_STATS_IDX_JSON],
12837 ts.counts[i]
12838 ? (double)ts.counts[i]
12839 / (double)ts.counts
12840 [BGP_STATS_PREFIXES]
12841 : 0);
12842 }
12843 break;
12844 case BGP_STATS_SPACE:
12845 if (!json) {
12846 snprintf(temp_buf, sizeof(temp_buf), "%12g",
12847 ts.total_space);
12848 vty_out(vty, "%-30s: %s\n",
12849 table_stats_strs[i]
12850 [TABLE_STATS_IDX_VTY],
12851 temp_buf);
12852 } else {
12853 json_object_double_add(
12854 json,
12855 table_stats_strs[i]
12856 [TABLE_STATS_IDX_JSON],
12857 (double)ts.total_space);
12858 }
12859 if (afi == AFI_IP6) {
12860 if (!json) {
12861 snprintf(temp_buf, sizeof(temp_buf),
12862 "%12g",
12863 ts.total_space
12864 * pow(2.0, -128 + 32));
12865 vty_out(vty, "%30s: %s\n",
12866 "/32 equivalent %s\n",
12867 temp_buf);
12868 } else {
12869 json_object_double_add(
12870 json, "/32equivalent",
12871 (double)(ts.total_space
12872 * pow(2.0,
12873 -128 + 32)));
12874 }
12875 if (!json) {
12876 snprintf(temp_buf, sizeof(temp_buf),
12877 "%12g",
12878 ts.total_space
12879 * pow(2.0, -128 + 48));
12880 vty_out(vty, "%30s: %s\n",
12881 "/48 equivalent %s\n",
12882 temp_buf);
12883 } else {
12884 json_object_double_add(
12885 json, "/48equivalent",
12886 (double)(ts.total_space
12887 * pow(2.0,
12888 -128 + 48)));
12889 }
12890 } else {
12891 if (!json) {
12892 snprintf(temp_buf, sizeof(temp_buf),
12893 "%12.2f",
12894 ts.total_space * 100.
12895 * pow(2.0, -32));
12896 vty_out(vty, "%30s: %s\n",
12897 "% announced ", temp_buf);
12898 } else {
12899 json_object_double_add(
12900 json, "%announced",
12901 (double)(ts.total_space * 100.
12902 * pow(2.0, -32)));
12903 }
12904 if (!json) {
12905 snprintf(temp_buf, sizeof(temp_buf),
12906 "%12.2f",
12907 ts.total_space
12908 * pow(2.0, -32 + 8));
12909 vty_out(vty, "%30s: %s\n",
12910 "/8 equivalent ", temp_buf);
12911 } else {
12912 json_object_double_add(
12913 json, "/8equivalent",
12914 (double)(ts.total_space
12915 * pow(2.0, -32 + 8)));
12916 }
12917 if (!json) {
12918 snprintf(temp_buf, sizeof(temp_buf),
12919 "%12.2f",
12920 ts.total_space
12921 * pow(2.0, -32 + 24));
12922 vty_out(vty, "%30s: %s\n",
12923 "/24 equivalent ", temp_buf);
12924 } else {
12925 json_object_double_add(
12926 json, "/24equivalent",
12927 (double)(ts.total_space
12928 * pow(2.0, -32 + 24)));
12929 }
12930 }
12931 break;
12932 default:
12933 if (!json) {
12934 snprintf(temp_buf, sizeof(temp_buf), "%12llu",
12935 ts.counts[i]);
12936 vty_out(vty, "%-30s: %s",
12937 table_stats_strs[i]
12938 [TABLE_STATS_IDX_VTY],
12939 temp_buf);
12940 } else {
12941 json_object_int_add(
12942 json,
12943 table_stats_strs[i]
12944 [TABLE_STATS_IDX_JSON],
12945 ts.counts[i]);
12946 }
12947 }
12948 if (!json)
12949 vty_out(vty, "\n");
12950 }
12951 end_table_stats:
12952 if (json)
12953 json_object_array_add(json_array, json);
12954 return ret;
12955 }
12956
12957 static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
12958 safi_t safi, struct json_object *json_array)
12959 {
12960 if (!bgp) {
12961 bgp_table_stats_all(vty, afi, safi, json_array);
12962 return CMD_SUCCESS;
12963 }
12964
12965 return bgp_table_stats_single(vty, bgp, afi, safi, json_array);
12966 }
12967
12968 enum bgp_pcounts {
12969 PCOUNT_ADJ_IN = 0,
12970 PCOUNT_DAMPED,
12971 PCOUNT_REMOVED,
12972 PCOUNT_HISTORY,
12973 PCOUNT_STALE,
12974 PCOUNT_VALID,
12975 PCOUNT_ALL,
12976 PCOUNT_COUNTED,
12977 PCOUNT_BPATH_SELECTED,
12978 PCOUNT_PFCNT, /* the figure we display to users */
12979 PCOUNT_MAX,
12980 };
12981
12982 static const char *const pcount_strs[] = {
12983 [PCOUNT_ADJ_IN] = "Adj-in",
12984 [PCOUNT_DAMPED] = "Damped",
12985 [PCOUNT_REMOVED] = "Removed",
12986 [PCOUNT_HISTORY] = "History",
12987 [PCOUNT_STALE] = "Stale",
12988 [PCOUNT_VALID] = "Valid",
12989 [PCOUNT_ALL] = "All RIB",
12990 [PCOUNT_COUNTED] = "PfxCt counted",
12991 [PCOUNT_BPATH_SELECTED] = "PfxCt Best Selected",
12992 [PCOUNT_PFCNT] = "Useable",
12993 [PCOUNT_MAX] = NULL,
12994 };
12995
12996 struct peer_pcounts {
12997 unsigned int count[PCOUNT_MAX];
12998 const struct peer *peer;
12999 const struct bgp_table *table;
13000 safi_t safi;
13001 };
13002
13003 static void bgp_peer_count_proc(struct bgp_dest *rn, struct peer_pcounts *pc)
13004 {
13005 const struct bgp_adj_in *ain;
13006 const struct bgp_path_info *pi;
13007 const struct peer *peer = pc->peer;
13008
13009 for (ain = rn->adj_in; ain; ain = ain->next)
13010 if (ain->peer == peer)
13011 pc->count[PCOUNT_ADJ_IN]++;
13012
13013 for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next) {
13014
13015 if (pi->peer != peer)
13016 continue;
13017
13018 pc->count[PCOUNT_ALL]++;
13019
13020 if (CHECK_FLAG(pi->flags, BGP_PATH_DAMPED))
13021 pc->count[PCOUNT_DAMPED]++;
13022 if (CHECK_FLAG(pi->flags, BGP_PATH_HISTORY))
13023 pc->count[PCOUNT_HISTORY]++;
13024 if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
13025 pc->count[PCOUNT_REMOVED]++;
13026 if (CHECK_FLAG(pi->flags, BGP_PATH_STALE))
13027 pc->count[PCOUNT_STALE]++;
13028 if (CHECK_FLAG(pi->flags, BGP_PATH_VALID))
13029 pc->count[PCOUNT_VALID]++;
13030 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13031 pc->count[PCOUNT_PFCNT]++;
13032 if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13033 pc->count[PCOUNT_BPATH_SELECTED]++;
13034
13035 if (CHECK_FLAG(pi->flags, BGP_PATH_COUNTED)) {
13036 pc->count[PCOUNT_COUNTED]++;
13037 if (CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13038 flog_err(
13039 EC_LIB_DEVELOPMENT,
13040 "Attempting to count but flags say it is unusable");
13041 } else {
13042 if (!CHECK_FLAG(pi->flags, BGP_PATH_UNUSEABLE))
13043 flog_err(
13044 EC_LIB_DEVELOPMENT,
13045 "Not counted but flags say we should");
13046 }
13047 }
13048 }
13049
13050 static int bgp_peer_count_walker(struct thread *t)
13051 {
13052 struct bgp_dest *rn, *rm;
13053 const struct bgp_table *table;
13054 struct peer_pcounts *pc = THREAD_ARG(t);
13055
13056 if (pc->safi == SAFI_MPLS_VPN || pc->safi == SAFI_ENCAP
13057 || pc->safi == SAFI_EVPN) {
13058 /* Special handling for 2-level routing tables. */
13059 for (rn = bgp_table_top(pc->table); rn;
13060 rn = bgp_route_next(rn)) {
13061 table = bgp_dest_get_bgp_table_info(rn);
13062 if (table != NULL)
13063 for (rm = bgp_table_top(table); rm;
13064 rm = bgp_route_next(rm))
13065 bgp_peer_count_proc(rm, pc);
13066 }
13067 } else
13068 for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn))
13069 bgp_peer_count_proc(rn, pc);
13070
13071 return 0;
13072 }
13073
13074 static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
13075 safi_t safi, bool use_json)
13076 {
13077 struct peer_pcounts pcounts = {.peer = peer};
13078 unsigned int i;
13079 json_object *json = NULL;
13080 json_object *json_loop = NULL;
13081
13082 if (use_json) {
13083 json = json_object_new_object();
13084 json_loop = json_object_new_object();
13085 }
13086
13087 if (!peer || !peer->bgp || !peer->afc[afi][safi]
13088 || !peer->bgp->rib[afi][safi]) {
13089 if (use_json) {
13090 json_object_string_add(
13091 json, "warning",
13092 "No such neighbor or address family");
13093 vty_out(vty, "%s\n", json_object_to_json_string(json));
13094 json_object_free(json);
13095 json_object_free(json_loop);
13096 } else
13097 vty_out(vty, "%% No such neighbor or address family\n");
13098
13099 return CMD_WARNING;
13100 }
13101
13102 memset(&pcounts, 0, sizeof(pcounts));
13103 pcounts.peer = peer;
13104 pcounts.table = peer->bgp->rib[afi][safi];
13105 pcounts.safi = safi;
13106
13107 /* in-place call via thread subsystem so as to record execution time
13108 * stats for the thread-walk (i.e. ensure this can't be blamed on
13109 * on just vty_read()).
13110 */
13111 thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
13112
13113 if (use_json) {
13114 json_object_string_add(json, "prefixCountsFor", peer->host);
13115 json_object_string_add(json, "multiProtocol",
13116 get_afi_safi_str(afi, safi, true));
13117 json_object_int_add(json, "pfxCounter",
13118 peer->pcount[afi][safi]);
13119
13120 for (i = 0; i < PCOUNT_MAX; i++)
13121 json_object_int_add(json_loop, pcount_strs[i],
13122 pcounts.count[i]);
13123
13124 json_object_object_add(json, "ribTableWalkCounters", json_loop);
13125
13126 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13127 json_object_string_add(json, "pfxctDriftFor",
13128 peer->host);
13129 json_object_string_add(
13130 json, "recommended",
13131 "Please report this bug, with the above command output");
13132 }
13133 vty_out(vty, "%s\n", json_object_to_json_string_ext(
13134 json, JSON_C_TO_STRING_PRETTY));
13135 json_object_free(json);
13136 } else {
13137
13138 if (peer->hostname
13139 && CHECK_FLAG(peer->bgp->flags, BGP_FLAG_SHOW_HOSTNAME)) {
13140 vty_out(vty, "Prefix counts for %s/%s, %s\n",
13141 peer->hostname, peer->host,
13142 get_afi_safi_str(afi, safi, false));
13143 } else {
13144 vty_out(vty, "Prefix counts for %s, %s\n", peer->host,
13145 get_afi_safi_str(afi, safi, false));
13146 }
13147
13148 vty_out(vty, "PfxCt: %u\n", peer->pcount[afi][safi]);
13149 vty_out(vty, "\nCounts from RIB table walk:\n\n");
13150
13151 for (i = 0; i < PCOUNT_MAX; i++)
13152 vty_out(vty, "%20s: %-10d\n", pcount_strs[i],
13153 pcounts.count[i]);
13154
13155 if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
13156 vty_out(vty, "%s [pcount] PfxCt drift!\n", peer->host);
13157 vty_out(vty,
13158 "Please report this bug, with the above command output\n");
13159 }
13160 }
13161
13162 return CMD_SUCCESS;
13163 }
13164
13165 DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
13166 show_ip_bgp_instance_neighbor_prefix_counts_cmd,
13167 "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]",
13168 SHOW_STR
13169 IP_STR
13170 BGP_STR
13171 BGP_INSTANCE_HELP_STR
13172 BGP_AFI_HELP_STR
13173 BGP_SAFI_HELP_STR
13174 "Detailed information on TCP and BGP neighbor connections\n"
13175 "Neighbor to display information about\n"
13176 "Neighbor to display information about\n"
13177 "Neighbor on BGP configured interface\n"
13178 "Display detailed prefix count information\n"
13179 JSON_STR)
13180 {
13181 afi_t afi = AFI_IP6;
13182 safi_t safi = SAFI_UNICAST;
13183 struct peer *peer;
13184 int idx = 0;
13185 struct bgp *bgp = NULL;
13186 bool uj = use_json(argc, argv);
13187
13188 if (uj)
13189 argc--;
13190
13191 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13192 &bgp, uj);
13193 if (!idx)
13194 return CMD_WARNING;
13195
13196 argv_find(argv, argc, "neighbors", &idx);
13197 peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
13198 if (!peer)
13199 return CMD_WARNING;
13200
13201 return bgp_peer_counts(vty, peer, afi, safi, uj);
13202 }
13203
13204 #ifdef KEEP_OLD_VPN_COMMANDS
13205 DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
13206 show_ip_bgp_vpn_neighbor_prefix_counts_cmd,
13207 "show [ip] bgp <vpnv4|vpnv6> all neighbors <A.B.C.D|X:X::X:X|WORD> prefix-counts [json]",
13208 SHOW_STR
13209 IP_STR
13210 BGP_STR
13211 BGP_VPNVX_HELP_STR
13212 "Display information about all VPNv4 NLRIs\n"
13213 "Detailed information on TCP and BGP neighbor connections\n"
13214 "Neighbor to display information about\n"
13215 "Neighbor to display information about\n"
13216 "Neighbor on BGP configured interface\n"
13217 "Display detailed prefix count information\n"
13218 JSON_STR)
13219 {
13220 int idx_peer = 6;
13221 struct peer *peer;
13222 bool uj = use_json(argc, argv);
13223
13224 peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
13225 if (!peer)
13226 return CMD_WARNING;
13227
13228 return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
13229 }
13230
13231 DEFUN (show_ip_bgp_vpn_all_route_prefix,
13232 show_ip_bgp_vpn_all_route_prefix_cmd,
13233 "show [ip] bgp <vpnv4|vpnv6> all <A.B.C.D|A.B.C.D/M> [json]",
13234 SHOW_STR
13235 IP_STR
13236 BGP_STR
13237 BGP_VPNVX_HELP_STR
13238 "Display information about all VPNv4 NLRIs\n"
13239 "Network in the BGP routing table to display\n"
13240 "Network in the BGP routing table to display\n"
13241 JSON_STR)
13242 {
13243 int idx = 0;
13244 char *network = NULL;
13245 struct bgp *bgp = bgp_get_default();
13246 if (!bgp) {
13247 vty_out(vty, "Can't find default instance\n");
13248 return CMD_WARNING;
13249 }
13250
13251 if (argv_find(argv, argc, "A.B.C.D", &idx))
13252 network = argv[idx]->arg;
13253 else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
13254 network = argv[idx]->arg;
13255 else {
13256 vty_out(vty, "Unable to figure out Network\n");
13257 return CMD_WARNING;
13258 }
13259
13260 return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
13261 BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
13262 use_json(argc, argv));
13263 }
13264 #endif /* KEEP_OLD_VPN_COMMANDS */
13265
13266 DEFUN (show_bgp_l2vpn_evpn_route_prefix,
13267 show_bgp_l2vpn_evpn_route_prefix_cmd,
13268 "show bgp l2vpn evpn <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> [json]",
13269 SHOW_STR
13270 BGP_STR
13271 L2VPN_HELP_STR
13272 EVPN_HELP_STR
13273 "Network in the BGP routing table to display\n"
13274 "Network in the BGP routing table to display\n"
13275 "Network in the BGP routing table to display\n"
13276 "Network in the BGP routing table to display\n"
13277 JSON_STR)
13278 {
13279 int idx = 0;
13280 char *network = NULL;
13281 int prefix_check = 0;
13282
13283 if (argv_find(argv, argc, "A.B.C.D", &idx) ||
13284 argv_find(argv, argc, "X:X::X:X", &idx))
13285 network = argv[idx]->arg;
13286 else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
13287 argv_find(argv, argc, "X:X::X:X/M", &idx)) {
13288 network = argv[idx]->arg;
13289 prefix_check = 1;
13290 } else {
13291 vty_out(vty, "Unable to figure out Network\n");
13292 return CMD_WARNING;
13293 }
13294 return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL,
13295 prefix_check, BGP_PATH_SHOW_ALL,
13296 RPKI_NOT_BEING_USED, use_json(argc, argv));
13297 }
13298
13299 static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
13300 struct bgp_table *table, int *header1,
13301 int *header2, json_object *json,
13302 json_object *json_scode,
13303 json_object *json_ocode, bool wide)
13304 {
13305 uint64_t version = table ? table->version : 0;
13306 char buf[BUFSIZ] = {0};
13307
13308 if (*header1) {
13309 if (json) {
13310 json_object_int_add(json, "bgpTableVersion", version);
13311 json_object_string_add(json, "bgpLocalRouterId",
13312 inet_ntop(AF_INET,
13313 &bgp->router_id, buf,
13314 sizeof(buf)));
13315 json_object_int_add(json, "defaultLocPrf",
13316 bgp->default_local_pref);
13317 json_object_int_add(json, "localAS", bgp->as);
13318 json_object_object_add(json, "bgpStatusCodes",
13319 json_scode);
13320 json_object_object_add(json, "bgpOriginCodes",
13321 json_ocode);
13322 } else {
13323 vty_out(vty,
13324 "BGP table version is %" PRIu64
13325 ", local router ID is %pI4, vrf id ",
13326 version, &bgp->router_id);
13327 if (bgp->vrf_id == VRF_UNKNOWN)
13328 vty_out(vty, "%s", VRFID_NONE_STR);
13329 else
13330 vty_out(vty, "%u", bgp->vrf_id);
13331 vty_out(vty, "\n");
13332 vty_out(vty, "Default local pref %u, ",
13333 bgp->default_local_pref);
13334 vty_out(vty, "local AS %u\n", bgp->as);
13335 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13336 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13337 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13338 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13339 }
13340 *header1 = 0;
13341 }
13342 if (*header2) {
13343 if (!json)
13344 vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
13345 : BGP_SHOW_HEADER));
13346 *header2 = 0;
13347 }
13348 }
13349
13350 static void
13351 show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
13352 afi_t afi, safi_t safi, enum bgp_show_adj_route_type type,
13353 const char *rmap_name, json_object *json, json_object *json_ar,
13354 json_object *json_scode, json_object *json_ocode,
13355 uint16_t show_flags, int *header1, int *header2, char *rd_str,
13356 unsigned long *output_count, unsigned long *filtered_count)
13357 {
13358 struct bgp_adj_in *ain;
13359 struct bgp_adj_out *adj;
13360 struct bgp_dest *dest;
13361 struct bgp *bgp;
13362 struct attr attr;
13363 int ret;
13364 struct update_subgroup *subgrp;
13365 struct peer_af *paf;
13366 bool route_filtered;
13367 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13368 bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13369 bool show_rd = ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13370 || (safi == SAFI_EVPN))
13371 ? true
13372 : false;
13373
13374 bgp = peer->bgp;
13375
13376 if (!bgp) {
13377 if (use_json) {
13378 json_object_string_add(json, "alert", "no BGP");
13379 vty_out(vty, "%s\n", json_object_to_json_string(json));
13380 json_object_free(json);
13381 } else
13382 vty_out(vty, "%% No bgp\n");
13383 return;
13384 }
13385
13386 subgrp = peer_subgroup(peer, afi, safi);
13387
13388 if (type == bgp_show_adj_route_advertised && subgrp
13389 && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
13390 char buf[BUFSIZ] = {0};
13391
13392 if (use_json) {
13393 json_object_int_add(json, "bgpTableVersion",
13394 table->version);
13395 json_object_string_add(json, "bgpLocalRouterId",
13396 inet_ntop(AF_INET,
13397 &bgp->router_id, buf,
13398 sizeof(buf)));
13399 json_object_int_add(json, "defaultLocPrf",
13400 bgp->default_local_pref);
13401 json_object_int_add(json, "localAS", bgp->as);
13402 json_object_object_add(json, "bgpStatusCodes",
13403 json_scode);
13404 json_object_object_add(json, "bgpOriginCodes",
13405 json_ocode);
13406 json_object_string_add(
13407 json, "bgpOriginatingDefaultNetwork",
13408 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13409 } else {
13410 vty_out(vty,
13411 "BGP table version is %" PRIu64
13412 ", local router ID is %pI4, vrf id ",
13413 table->version, &bgp->router_id);
13414 if (bgp->vrf_id == VRF_UNKNOWN)
13415 vty_out(vty, "%s", VRFID_NONE_STR);
13416 else
13417 vty_out(vty, "%u", bgp->vrf_id);
13418 vty_out(vty, "\n");
13419 vty_out(vty, "Default local pref %u, ",
13420 bgp->default_local_pref);
13421 vty_out(vty, "local AS %u\n", bgp->as);
13422 vty_out(vty, BGP_SHOW_SCODE_HEADER);
13423 vty_out(vty, BGP_SHOW_NCODE_HEADER);
13424 vty_out(vty, BGP_SHOW_OCODE_HEADER);
13425 vty_out(vty, BGP_SHOW_RPKI_HEADER);
13426
13427 vty_out(vty, "Originating default network %s\n\n",
13428 (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
13429 }
13430 *header1 = 0;
13431 }
13432
13433 for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
13434 if (type == bgp_show_adj_route_received
13435 || type == bgp_show_adj_route_filtered) {
13436 for (ain = dest->adj_in; ain; ain = ain->next) {
13437 if (ain->peer != peer)
13438 continue;
13439
13440 show_adj_route_header(vty, bgp, table, header1,
13441 header2, json, json_scode,
13442 json_ocode, wide);
13443
13444 if ((safi == SAFI_MPLS_VPN)
13445 || (safi == SAFI_ENCAP)
13446 || (safi == SAFI_EVPN)) {
13447 if (use_json)
13448 json_object_string_add(
13449 json_ar, "rd", rd_str);
13450 else if (show_rd && rd_str) {
13451 vty_out(vty,
13452 "Route Distinguisher: %s\n",
13453 rd_str);
13454 show_rd = false;
13455 }
13456 }
13457
13458 attr = *ain->attr;
13459 route_filtered = false;
13460
13461 /* Filter prefix using distribute list,
13462 * filter list or prefix list
13463 */
13464 const struct prefix *rn_p =
13465 bgp_dest_get_prefix(dest);
13466 if ((bgp_input_filter(peer, rn_p, &attr, afi,
13467 safi))
13468 == FILTER_DENY)
13469 route_filtered = true;
13470
13471 /* Filter prefix using route-map */
13472 ret = bgp_input_modifier(peer, rn_p, &attr, afi,
13473 safi, rmap_name, NULL,
13474 0, NULL);
13475
13476 if (type == bgp_show_adj_route_filtered &&
13477 !route_filtered && ret != RMAP_DENY) {
13478 bgp_attr_undup(&attr, ain->attr);
13479 continue;
13480 }
13481
13482 if (type == bgp_show_adj_route_received
13483 && (route_filtered || ret == RMAP_DENY))
13484 (*filtered_count)++;
13485
13486 route_vty_out_tmp(vty, dest, rn_p, &attr, safi,
13487 use_json, json_ar, wide);
13488 bgp_attr_undup(&attr, ain->attr);
13489 (*output_count)++;
13490 }
13491 } else if (type == bgp_show_adj_route_advertised) {
13492 RB_FOREACH (adj, bgp_adj_out_rb, &dest->adj_out)
13493 SUBGRP_FOREACH_PEER (adj->subgroup, paf) {
13494 if (paf->peer != peer || !adj->attr)
13495 continue;
13496
13497 show_adj_route_header(vty, bgp, table,
13498 header1, header2,
13499 json, json_scode,
13500 json_ocode, wide);
13501
13502 const struct prefix *rn_p =
13503 bgp_dest_get_prefix(dest);
13504
13505 attr = *adj->attr;
13506 ret = bgp_output_modifier(
13507 peer, rn_p, &attr, afi, safi,
13508 rmap_name);
13509
13510 if (ret != RMAP_DENY) {
13511 if ((safi == SAFI_MPLS_VPN)
13512 || (safi == SAFI_ENCAP)
13513 || (safi == SAFI_EVPN)) {
13514 if (use_json)
13515 json_object_string_add(
13516 json_ar,
13517 "rd",
13518 rd_str);
13519 else if (show_rd
13520 && rd_str) {
13521 vty_out(vty,
13522 "Route Distinguisher: %s\n",
13523 rd_str);
13524 show_rd = false;
13525 }
13526 }
13527 route_vty_out_tmp(
13528 vty, dest, rn_p, &attr,
13529 safi, use_json, json_ar,
13530 wide);
13531 (*output_count)++;
13532 } else {
13533 (*filtered_count)++;
13534 }
13535
13536 bgp_attr_undup(&attr, adj->attr);
13537 }
13538 } else if (type == bgp_show_adj_route_bestpath) {
13539 struct bgp_path_info *pi;
13540
13541 show_adj_route_header(vty, bgp, table, header1, header2,
13542 json, json_scode, json_ocode,
13543 wide);
13544
13545 for (pi = bgp_dest_get_bgp_path_info(dest); pi;
13546 pi = pi->next) {
13547 if (pi->peer != peer)
13548 continue;
13549
13550 if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
13551 continue;
13552
13553 route_vty_out_tmp(vty, dest,
13554 bgp_dest_get_prefix(dest),
13555 pi->attr, safi, use_json,
13556 json_ar, wide);
13557 (*output_count)++;
13558 }
13559 }
13560 }
13561 }
13562
13563 static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
13564 safi_t safi, enum bgp_show_adj_route_type type,
13565 const char *rmap_name, uint16_t show_flags)
13566 {
13567 struct bgp *bgp;
13568 struct bgp_table *table;
13569 json_object *json = NULL;
13570 json_object *json_scode = NULL;
13571 json_object *json_ocode = NULL;
13572 json_object *json_ar = NULL;
13573 bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13574
13575 /* Init BGP headers here so they're only displayed once
13576 * even if 'table' is 2-tier (MPLS_VPN, ENCAP, EVPN).
13577 */
13578 int header1 = 1;
13579 int header2 = 1;
13580
13581 /*
13582 * Initialize variables for each RD
13583 * All prefixes under an RD is aggregated within "json_routes"
13584 */
13585 char rd_str[BUFSIZ] = {0};
13586 json_object *json_routes = NULL;
13587
13588
13589 /* For 2-tier tables, prefix counts need to be
13590 * maintained across multiple runs of show_adj_route()
13591 */
13592 unsigned long output_count_per_rd;
13593 unsigned long filtered_count_per_rd;
13594 unsigned long output_count = 0;
13595 unsigned long filtered_count = 0;
13596
13597 if (use_json) {
13598 json = json_object_new_object();
13599 json_ar = json_object_new_object();
13600 json_scode = json_object_new_object();
13601 json_ocode = json_object_new_object();
13602
13603 json_object_string_add(json_scode, "suppressed", "s");
13604 json_object_string_add(json_scode, "damped", "d");
13605 json_object_string_add(json_scode, "history", "h");
13606 json_object_string_add(json_scode, "valid", "*");
13607 json_object_string_add(json_scode, "best", ">");
13608 json_object_string_add(json_scode, "multipath", "=");
13609 json_object_string_add(json_scode, "internal", "i");
13610 json_object_string_add(json_scode, "ribFailure", "r");
13611 json_object_string_add(json_scode, "stale", "S");
13612 json_object_string_add(json_scode, "removed", "R");
13613
13614 json_object_string_add(json_ocode, "igp", "i");
13615 json_object_string_add(json_ocode, "egp", "e");
13616 json_object_string_add(json_ocode, "incomplete", "?");
13617 }
13618
13619 if (!peer || !peer->afc[afi][safi]) {
13620 if (use_json) {
13621 json_object_string_add(
13622 json, "warning",
13623 "No such neighbor or address family");
13624 vty_out(vty, "%s\n", json_object_to_json_string(json));
13625 json_object_free(json);
13626 } else
13627 vty_out(vty, "%% No such neighbor or address family\n");
13628
13629 return CMD_WARNING;
13630 }
13631
13632 if ((type == bgp_show_adj_route_received
13633 || type == bgp_show_adj_route_filtered)
13634 && !CHECK_FLAG(peer->af_flags[afi][safi],
13635 PEER_FLAG_SOFT_RECONFIG)) {
13636 if (use_json) {
13637 json_object_string_add(
13638 json, "warning",
13639 "Inbound soft reconfiguration not enabled");
13640 vty_out(vty, "%s\n", json_object_to_json_string(json));
13641 json_object_free(json);
13642 } else
13643 vty_out(vty,
13644 "%% Inbound soft reconfiguration not enabled\n");
13645
13646 return CMD_WARNING;
13647 }
13648
13649 bgp = peer->bgp;
13650
13651 /* labeled-unicast routes live in the unicast table */
13652 if (safi == SAFI_LABELED_UNICAST)
13653 table = bgp->rib[afi][SAFI_UNICAST];
13654 else
13655 table = bgp->rib[afi][safi];
13656
13657 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
13658 || (safi == SAFI_EVPN)) {
13659
13660 struct bgp_dest *dest;
13661
13662 for (dest = bgp_table_top(table); dest;
13663 dest = bgp_route_next(dest)) {
13664 table = bgp_dest_get_bgp_table_info(dest);
13665 if (!table)
13666 continue;
13667
13668 output_count_per_rd = 0;
13669 filtered_count_per_rd = 0;
13670
13671 if (use_json)
13672 json_routes = json_object_new_object();
13673
13674 const struct prefix_rd *prd;
13675 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
13676 dest);
13677
13678 prefix_rd2str(prd, rd_str, sizeof(rd_str));
13679
13680 show_adj_route(vty, peer, table, afi, safi, type,
13681 rmap_name, json, json_routes, json_scode,
13682 json_ocode, show_flags, &header1,
13683 &header2, rd_str, &output_count_per_rd,
13684 &filtered_count_per_rd);
13685
13686 /* Don't include an empty RD in the output! */
13687 if (json_routes && (output_count_per_rd > 0))
13688 json_object_object_add(json_ar, rd_str,
13689 json_routes);
13690
13691 output_count += output_count_per_rd;
13692 filtered_count += filtered_count_per_rd;
13693 }
13694 } else
13695 show_adj_route(vty, peer, table, afi, safi, type, rmap_name,
13696 json, json_ar, json_scode, json_ocode,
13697 show_flags, &header1, &header2, rd_str,
13698 &output_count, &filtered_count);
13699
13700 if (use_json) {
13701 json_object_object_add(json, "advertisedRoutes", json_ar);
13702 json_object_int_add(json, "totalPrefixCounter", output_count);
13703 json_object_int_add(json, "filteredPrefixCounter",
13704 filtered_count);
13705
13706 vty_out(vty, "%s\n",
13707 json_object_to_json_string_ext(
13708 json, JSON_C_TO_STRING_PRETTY));
13709
13710 if (!output_count && !filtered_count) {
13711 json_object_free(json_scode);
13712 json_object_free(json_ocode);
13713 }
13714
13715 if (json)
13716 json_object_free(json);
13717
13718 } else if (output_count > 0) {
13719 if (filtered_count > 0)
13720 vty_out(vty,
13721 "\nTotal number of prefixes %ld (%ld filtered)\n",
13722 output_count, filtered_count);
13723 else
13724 vty_out(vty, "\nTotal number of prefixes %ld\n",
13725 output_count);
13726 }
13727
13728 return CMD_SUCCESS;
13729 }
13730
13731 DEFPY (show_ip_bgp_instance_neighbor_bestpath_route,
13732 show_ip_bgp_instance_neighbor_bestpath_route_cmd,
13733 "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]",
13734 SHOW_STR
13735 IP_STR
13736 BGP_STR
13737 BGP_INSTANCE_HELP_STR
13738 BGP_AFI_HELP_STR
13739 BGP_SAFI_WITH_LABEL_HELP_STR
13740 "Detailed information on TCP and BGP neighbor connections\n"
13741 "Neighbor to display information about\n"
13742 "Neighbor to display information about\n"
13743 "Neighbor on BGP configured interface\n"
13744 "Display the routes selected by best path\n"
13745 JSON_STR
13746 "Increase table width for longer prefixes\n")
13747 {
13748 afi_t afi = AFI_IP6;
13749 safi_t safi = SAFI_UNICAST;
13750 char *rmap_name = NULL;
13751 char *peerstr = NULL;
13752 struct bgp *bgp = NULL;
13753 struct peer *peer;
13754 enum bgp_show_adj_route_type type = bgp_show_adj_route_bestpath;
13755 int idx = 0;
13756 uint16_t show_flags = 0;
13757
13758 if (uj)
13759 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13760
13761 if (wide)
13762 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13763
13764 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13765 &bgp, uj);
13766
13767 if (!idx)
13768 return CMD_WARNING;
13769
13770 argv_find(argv, argc, "neighbors", &idx);
13771 peerstr = argv[++idx]->arg;
13772
13773 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13774 if (!peer)
13775 return CMD_WARNING;
13776
13777 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13778 show_flags);
13779 }
13780
13781 DEFPY (show_ip_bgp_instance_neighbor_advertised_route,
13782 show_ip_bgp_instance_neighbor_advertised_route_cmd,
13783 "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]",
13784 SHOW_STR
13785 IP_STR
13786 BGP_STR
13787 BGP_INSTANCE_HELP_STR
13788 BGP_AFI_HELP_STR
13789 BGP_SAFI_WITH_LABEL_HELP_STR
13790 "Display the entries for all address families\n"
13791 "Detailed information on TCP and BGP neighbor connections\n"
13792 "Neighbor to display information about\n"
13793 "Neighbor to display information about\n"
13794 "Neighbor on BGP configured interface\n"
13795 "Display the routes advertised to a BGP neighbor\n"
13796 "Display the received routes from neighbor\n"
13797 "Display the filtered routes received from neighbor\n"
13798 "Route-map to modify the attributes\n"
13799 "Name of the route map\n"
13800 JSON_STR
13801 "Increase table width for longer prefixes\n")
13802 {
13803 afi_t afi = AFI_IP6;
13804 safi_t safi = SAFI_UNICAST;
13805 char *rmap_name = NULL;
13806 char *peerstr = NULL;
13807 struct bgp *bgp = NULL;
13808 struct peer *peer;
13809 enum bgp_show_adj_route_type type = bgp_show_adj_route_advertised;
13810 int idx = 0;
13811 bool first = true;
13812 uint16_t show_flags = 0;
13813
13814 if (uj) {
13815 argc--;
13816 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13817 }
13818
13819 if (all) {
13820 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
13821 if (argv_find(argv, argc, "ipv4", &idx))
13822 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP);
13823
13824 if (argv_find(argv, argc, "ipv6", &idx))
13825 SET_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6);
13826 }
13827
13828 if (wide)
13829 SET_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
13830
13831 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
13832 &bgp, uj);
13833 if (!idx)
13834 return CMD_WARNING;
13835
13836 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13837 argv_find(argv, argc, "neighbors", &idx);
13838 peerstr = argv[++idx]->arg;
13839
13840 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
13841 if (!peer)
13842 return CMD_WARNING;
13843
13844 if (argv_find(argv, argc, "advertised-routes", &idx))
13845 type = bgp_show_adj_route_advertised;
13846 else if (argv_find(argv, argc, "received-routes", &idx))
13847 type = bgp_show_adj_route_received;
13848 else if (argv_find(argv, argc, "filtered-routes", &idx))
13849 type = bgp_show_adj_route_filtered;
13850
13851 if (argv_find(argv, argc, "route-map", &idx))
13852 rmap_name = argv[++idx]->arg;
13853
13854 if (!all)
13855 return peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13856 show_flags);
13857 if (uj)
13858 vty_out(vty, "{\n");
13859
13860 if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP)
13861 || CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP6)) {
13862 afi = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_IP) ? AFI_IP
13863 : AFI_IP6;
13864 FOREACH_SAFI (safi) {
13865 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
13866 continue;
13867
13868 if (uj) {
13869 if (first)
13870 first = false;
13871 else
13872 vty_out(vty, ",\n");
13873 vty_out(vty, "\"%s\":",
13874 get_afi_safi_str(afi, safi, true));
13875 } else
13876 vty_out(vty, "\nFor address family: %s\n",
13877 get_afi_safi_str(afi, safi, false));
13878
13879 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13880 show_flags);
13881 }
13882 } else {
13883 FOREACH_AFI_SAFI (afi, safi) {
13884 if (!bgp_afi_safi_peer_exists(bgp, afi, safi))
13885 continue;
13886
13887 if (uj) {
13888 if (first)
13889 first = false;
13890 else
13891 vty_out(vty, ",\n");
13892 vty_out(vty, "\"%s\":",
13893 get_afi_safi_str(afi, safi, true));
13894 } else
13895 vty_out(vty, "\nFor address family: %s\n",
13896 get_afi_safi_str(afi, safi, false));
13897
13898 peer_adj_routes(vty, peer, afi, safi, type, rmap_name,
13899 show_flags);
13900 }
13901 }
13902 if (uj)
13903 vty_out(vty, "}\n");
13904
13905 return CMD_SUCCESS;
13906 }
13907
13908 DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
13909 show_ip_bgp_neighbor_received_prefix_filter_cmd,
13910 "show [ip] bgp [<ipv4|ipv6> [unicast]] neighbors <A.B.C.D|X:X::X:X|WORD> received prefix-filter [json]",
13911 SHOW_STR
13912 IP_STR
13913 BGP_STR
13914 "Address Family\n"
13915 "Address Family\n"
13916 "Address Family modifier\n"
13917 "Detailed information on TCP and BGP neighbor connections\n"
13918 "Neighbor to display information about\n"
13919 "Neighbor to display information about\n"
13920 "Neighbor on BGP configured interface\n"
13921 "Display information received from a BGP neighbor\n"
13922 "Display the prefixlist filter\n"
13923 JSON_STR)
13924 {
13925 afi_t afi = AFI_IP6;
13926 safi_t safi = SAFI_UNICAST;
13927 char *peerstr = NULL;
13928
13929 char name[BUFSIZ];
13930 union sockunion su;
13931 struct peer *peer;
13932 int count, ret;
13933
13934 int idx = 0;
13935
13936 /* show [ip] bgp */
13937 if (argv_find(argv, argc, "ip", &idx))
13938 afi = AFI_IP;
13939 /* [<ipv4|ipv6> [unicast]] */
13940 if (argv_find(argv, argc, "ipv4", &idx))
13941 afi = AFI_IP;
13942 if (argv_find(argv, argc, "ipv6", &idx))
13943 afi = AFI_IP6;
13944 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
13945 argv_find(argv, argc, "neighbors", &idx);
13946 peerstr = argv[++idx]->arg;
13947
13948 bool uj = use_json(argc, argv);
13949
13950 ret = str2sockunion(peerstr, &su);
13951 if (ret < 0) {
13952 peer = peer_lookup_by_conf_if(NULL, peerstr);
13953 if (!peer) {
13954 if (uj)
13955 vty_out(vty, "{}\n");
13956 else
13957 vty_out(vty,
13958 "%% Malformed address or name: %s\n",
13959 peerstr);
13960 return CMD_WARNING;
13961 }
13962 } else {
13963 peer = peer_lookup(NULL, &su);
13964 if (!peer) {
13965 if (uj)
13966 vty_out(vty, "{}\n");
13967 else
13968 vty_out(vty, "No peer\n");
13969 return CMD_WARNING;
13970 }
13971 }
13972
13973 snprintf(name, sizeof(name), "%s.%d.%d", peer->host, afi, safi);
13974 count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
13975 if (count) {
13976 if (!uj)
13977 vty_out(vty, "Address Family: %s\n",
13978 get_afi_safi_str(afi, safi, false));
13979 prefix_bgp_show_prefix_list(vty, afi, name, uj);
13980 } else {
13981 if (uj)
13982 vty_out(vty, "{}\n");
13983 else
13984 vty_out(vty, "No functional output\n");
13985 }
13986
13987 return CMD_SUCCESS;
13988 }
13989
13990 static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
13991 afi_t afi, safi_t safi,
13992 enum bgp_show_type type, bool use_json)
13993 {
13994 uint16_t show_flags = 0;
13995
13996 if (use_json)
13997 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
13998
13999 if (!peer || !peer->afc[afi][safi]) {
14000 if (use_json) {
14001 json_object *json_no = NULL;
14002 json_no = json_object_new_object();
14003 json_object_string_add(
14004 json_no, "warning",
14005 "No such neighbor or address family");
14006 vty_out(vty, "%s\n",
14007 json_object_to_json_string(json_no));
14008 json_object_free(json_no);
14009 } else
14010 vty_out(vty, "%% No such neighbor or address family\n");
14011 return CMD_WARNING;
14012 }
14013
14014 /* labeled-unicast routes live in the unicast table */
14015 if (safi == SAFI_LABELED_UNICAST)
14016 safi = SAFI_UNICAST;
14017
14018 return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags,
14019 RPKI_NOT_BEING_USED);
14020 }
14021
14022 DEFUN (show_ip_bgp_flowspec_routes_detailed,
14023 show_ip_bgp_flowspec_routes_detailed_cmd,
14024 "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" flowspec] detail [json]",
14025 SHOW_STR
14026 IP_STR
14027 BGP_STR
14028 BGP_INSTANCE_HELP_STR
14029 BGP_AFI_HELP_STR
14030 "SAFI Flowspec\n"
14031 "Detailed information on flowspec entries\n"
14032 JSON_STR)
14033 {
14034 afi_t afi = AFI_IP;
14035 safi_t safi = SAFI_UNICAST;
14036 struct bgp *bgp = NULL;
14037 int idx = 0;
14038 bool uj = use_json(argc, argv);
14039 uint16_t show_flags = 0;
14040
14041 if (uj) {
14042 argc--;
14043 SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
14044 }
14045
14046 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14047 &bgp, uj);
14048 if (!idx)
14049 return CMD_WARNING;
14050
14051 return bgp_show(vty, bgp, afi, safi, bgp_show_type_detail, NULL,
14052 show_flags, RPKI_NOT_BEING_USED);
14053 }
14054
14055 DEFUN (show_ip_bgp_neighbor_routes,
14056 show_ip_bgp_neighbor_routes_cmd,
14057 "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]",
14058 SHOW_STR
14059 IP_STR
14060 BGP_STR
14061 BGP_INSTANCE_HELP_STR
14062 BGP_AFI_HELP_STR
14063 BGP_SAFI_WITH_LABEL_HELP_STR
14064 "Detailed information on TCP and BGP neighbor connections\n"
14065 "Neighbor to display information about\n"
14066 "Neighbor to display information about\n"
14067 "Neighbor on BGP configured interface\n"
14068 "Display flap statistics of the routes learned from neighbor\n"
14069 "Display the dampened routes received from neighbor\n"
14070 "Display routes learned from neighbor\n"
14071 JSON_STR)
14072 {
14073 char *peerstr = NULL;
14074 struct bgp *bgp = NULL;
14075 afi_t afi = AFI_IP6;
14076 safi_t safi = SAFI_UNICAST;
14077 struct peer *peer;
14078 enum bgp_show_type sh_type = bgp_show_type_neighbor;
14079 int idx = 0;
14080 bool uj = use_json(argc, argv);
14081
14082 if (uj)
14083 argc--;
14084
14085 bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
14086 &bgp, uj);
14087 if (!idx)
14088 return CMD_WARNING;
14089
14090 /* neighbors <A.B.C.D|X:X::X:X|WORD> */
14091 argv_find(argv, argc, "neighbors", &idx);
14092 peerstr = argv[++idx]->arg;
14093
14094 peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
14095 if (!peer)
14096 return CMD_WARNING;
14097
14098 if (argv_find(argv, argc, "flap-statistics", &idx))
14099 sh_type = bgp_show_type_flap_neighbor;
14100 else if (argv_find(argv, argc, "dampened-routes", &idx))
14101 sh_type = bgp_show_type_damp_neighbor;
14102 else if (argv_find(argv, argc, "routes", &idx))
14103 sh_type = bgp_show_type_neighbor;
14104
14105 return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
14106 }
14107
14108 struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
14109
14110 struct bgp_distance {
14111 /* Distance value for the IP source prefix. */
14112 uint8_t distance;
14113
14114 /* Name of the access-list to be matched. */
14115 char *access_list;
14116 };
14117
14118 DEFUN (show_bgp_afi_vpn_rd_route,
14119 show_bgp_afi_vpn_rd_route_cmd,
14120 "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]",
14121 SHOW_STR
14122 BGP_STR
14123 BGP_AFI_HELP_STR
14124 "Address Family modifier\n"
14125 "Display information for a route distinguisher\n"
14126 "Route Distinguisher\n"
14127 "All Route Distinguishers\n"
14128 "Network in the BGP routing table to display\n"
14129 "Network in the BGP routing table to display\n"
14130 JSON_STR)
14131 {
14132 int ret;
14133 struct prefix_rd prd;
14134 afi_t afi = AFI_MAX;
14135 int idx = 0;
14136
14137 if (!argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
14138 vty_out(vty, "%% Malformed Address Family\n");
14139 return CMD_WARNING;
14140 }
14141
14142 if (!strcmp(argv[5]->arg, "all"))
14143 return bgp_show_route(vty, NULL, argv[6]->arg, afi,
14144 SAFI_MPLS_VPN, NULL, 0, BGP_PATH_SHOW_ALL,
14145 RPKI_NOT_BEING_USED,
14146 use_json(argc, argv));
14147
14148 ret = str2prefix_rd(argv[5]->arg, &prd);
14149 if (!ret) {
14150 vty_out(vty, "%% Malformed Route Distinguisher\n");
14151 return CMD_WARNING;
14152 }
14153
14154 return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
14155 0, BGP_PATH_SHOW_ALL, RPKI_NOT_BEING_USED,
14156 use_json(argc, argv));
14157 }
14158
14159 static struct bgp_distance *bgp_distance_new(void)
14160 {
14161 return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
14162 }
14163
14164 static void bgp_distance_free(struct bgp_distance *bdistance)
14165 {
14166 XFREE(MTYPE_BGP_DISTANCE, bdistance);
14167 }
14168
14169 static int bgp_distance_set(struct vty *vty, const char *distance_str,
14170 const char *ip_str, const char *access_list_str)
14171 {
14172 int ret;
14173 afi_t afi;
14174 safi_t safi;
14175 struct prefix p;
14176 uint8_t distance;
14177 struct bgp_dest *dest;
14178 struct bgp_distance *bdistance;
14179
14180 afi = bgp_node_afi(vty);
14181 safi = bgp_node_safi(vty);
14182
14183 ret = str2prefix(ip_str, &p);
14184 if (ret == 0) {
14185 vty_out(vty, "Malformed prefix\n");
14186 return CMD_WARNING_CONFIG_FAILED;
14187 }
14188
14189 distance = atoi(distance_str);
14190
14191 /* Get BGP distance node. */
14192 dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
14193 bdistance = bgp_dest_get_bgp_distance_info(dest);
14194 if (bdistance)
14195 bgp_dest_unlock_node(dest);
14196 else {
14197 bdistance = bgp_distance_new();
14198 bgp_dest_set_bgp_distance_info(dest, bdistance);
14199 }
14200
14201 /* Set distance value. */
14202 bdistance->distance = distance;
14203
14204 /* Reset access-list configuration. */
14205 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14206 if (access_list_str)
14207 bdistance->access_list =
14208 XSTRDUP(MTYPE_AS_LIST, access_list_str);
14209
14210 return CMD_SUCCESS;
14211 }
14212
14213 static int bgp_distance_unset(struct vty *vty, const char *distance_str,
14214 const char *ip_str, const char *access_list_str)
14215 {
14216 int ret;
14217 afi_t afi;
14218 safi_t safi;
14219 struct prefix p;
14220 int distance;
14221 struct bgp_dest *dest;
14222 struct bgp_distance *bdistance;
14223
14224 afi = bgp_node_afi(vty);
14225 safi = bgp_node_safi(vty);
14226
14227 ret = str2prefix(ip_str, &p);
14228 if (ret == 0) {
14229 vty_out(vty, "Malformed prefix\n");
14230 return CMD_WARNING_CONFIG_FAILED;
14231 }
14232
14233 dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
14234 if (!dest) {
14235 vty_out(vty, "Can't find specified prefix\n");
14236 return CMD_WARNING_CONFIG_FAILED;
14237 }
14238
14239 bdistance = bgp_dest_get_bgp_distance_info(dest);
14240 distance = atoi(distance_str);
14241
14242 if (bdistance->distance != distance) {
14243 vty_out(vty, "Distance does not match configured\n");
14244 bgp_dest_unlock_node(dest);
14245 return CMD_WARNING_CONFIG_FAILED;
14246 }
14247
14248 XFREE(MTYPE_AS_LIST, bdistance->access_list);
14249 bgp_distance_free(bdistance);
14250
14251 bgp_dest_set_bgp_path_info(dest, NULL);
14252 bgp_dest_unlock_node(dest);
14253 bgp_dest_unlock_node(dest);
14254
14255 return CMD_SUCCESS;
14256 }
14257
14258 /* Apply BGP information to distance method. */
14259 uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
14260 afi_t afi, safi_t safi, struct bgp *bgp)
14261 {
14262 struct bgp_dest *dest;
14263 struct prefix q = {0};
14264 struct peer *peer;
14265 struct bgp_distance *bdistance;
14266 struct access_list *alist;
14267 struct bgp_static *bgp_static;
14268
14269 if (!bgp)
14270 return 0;
14271
14272 peer = pinfo->peer;
14273
14274 if (pinfo->attr->distance)
14275 return pinfo->attr->distance;
14276
14277 /* Check source address.
14278 * Note: for aggregate route, peer can have unspec af type.
14279 */
14280 if (pinfo->sub_type != BGP_ROUTE_AGGREGATE
14281 && !sockunion2hostprefix(&peer->su, &q))
14282 return 0;
14283
14284 dest = bgp_node_match(bgp_distance_table[afi][safi], &q);
14285 if (dest) {
14286 bdistance = bgp_dest_get_bgp_distance_info(dest);
14287 bgp_dest_unlock_node(dest);
14288
14289 if (bdistance->access_list) {
14290 alist = access_list_lookup(afi, bdistance->access_list);
14291 if (alist
14292 && access_list_apply(alist, p) == FILTER_PERMIT)
14293 return bdistance->distance;
14294 } else
14295 return bdistance->distance;
14296 }
14297
14298 /* Backdoor check. */
14299 dest = bgp_node_lookup(bgp->route[afi][safi], p);
14300 if (dest) {
14301 bgp_static = bgp_dest_get_bgp_static_info(dest);
14302 bgp_dest_unlock_node(dest);
14303
14304 if (bgp_static->backdoor) {
14305 if (bgp->distance_local[afi][safi])
14306 return bgp->distance_local[afi][safi];
14307 else
14308 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14309 }
14310 }
14311
14312 if (peer->sort == BGP_PEER_EBGP) {
14313 if (bgp->distance_ebgp[afi][safi])
14314 return bgp->distance_ebgp[afi][safi];
14315 return ZEBRA_EBGP_DISTANCE_DEFAULT;
14316 } else if (peer->sort == BGP_PEER_IBGP) {
14317 if (bgp->distance_ibgp[afi][safi])
14318 return bgp->distance_ibgp[afi][safi];
14319 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14320 } else {
14321 if (bgp->distance_local[afi][safi])
14322 return bgp->distance_local[afi][safi];
14323 return ZEBRA_IBGP_DISTANCE_DEFAULT;
14324 }
14325 }
14326
14327 /* If we enter `distance bgp (1-255) (1-255) (1-255)`,
14328 * we should tell ZEBRA update the routes for a specific
14329 * AFI/SAFI to reflect changes in RIB.
14330 */
14331 static void bgp_announce_routes_distance_update(struct bgp *bgp,
14332 afi_t update_afi,
14333 safi_t update_safi)
14334 {
14335 afi_t afi;
14336 safi_t safi;
14337
14338 FOREACH_AFI_SAFI (afi, safi) {
14339 if (!bgp_fibupd_safi(safi))
14340 continue;
14341
14342 if (afi != update_afi && safi != update_safi)
14343 continue;
14344
14345 if (BGP_DEBUG(zebra, ZEBRA))
14346 zlog_debug(
14347 "%s: Announcing routes due to distance change afi/safi (%d/%d)",
14348 __func__, afi, safi);
14349 bgp_zebra_announce_table(bgp, afi, safi);
14350 }
14351 }
14352
14353 DEFUN (bgp_distance,
14354 bgp_distance_cmd,
14355 "distance bgp (1-255) (1-255) (1-255)",
14356 "Define an administrative distance\n"
14357 "BGP distance\n"
14358 "Distance for routes external to the AS\n"
14359 "Distance for routes internal to the AS\n"
14360 "Distance for local routes\n")
14361 {
14362 VTY_DECLVAR_CONTEXT(bgp, bgp);
14363 int idx_number = 2;
14364 int idx_number_2 = 3;
14365 int idx_number_3 = 4;
14366 int distance_ebgp = atoi(argv[idx_number]->arg);
14367 int distance_ibgp = atoi(argv[idx_number_2]->arg);
14368 int distance_local = atoi(argv[idx_number_3]->arg);
14369 afi_t afi;
14370 safi_t safi;
14371
14372 afi = bgp_node_afi(vty);
14373 safi = bgp_node_safi(vty);
14374
14375 if (bgp->distance_ebgp[afi][safi] != distance_ebgp
14376 || bgp->distance_ibgp[afi][safi] != distance_ibgp
14377 || bgp->distance_local[afi][safi] != distance_local) {
14378 bgp->distance_ebgp[afi][safi] = distance_ebgp;
14379 bgp->distance_ibgp[afi][safi] = distance_ibgp;
14380 bgp->distance_local[afi][safi] = distance_local;
14381 bgp_announce_routes_distance_update(bgp, afi, safi);
14382 }
14383 return CMD_SUCCESS;
14384 }
14385
14386 DEFUN (no_bgp_distance,
14387 no_bgp_distance_cmd,
14388 "no distance bgp [(1-255) (1-255) (1-255)]",
14389 NO_STR
14390 "Define an administrative distance\n"
14391 "BGP distance\n"
14392 "Distance for routes external to the AS\n"
14393 "Distance for routes internal to the AS\n"
14394 "Distance for local routes\n")
14395 {
14396 VTY_DECLVAR_CONTEXT(bgp, bgp);
14397 afi_t afi;
14398 safi_t safi;
14399
14400 afi = bgp_node_afi(vty);
14401 safi = bgp_node_safi(vty);
14402
14403 if (bgp->distance_ebgp[afi][safi] != 0
14404 || bgp->distance_ibgp[afi][safi] != 0
14405 || bgp->distance_local[afi][safi] != 0) {
14406 bgp->distance_ebgp[afi][safi] = 0;
14407 bgp->distance_ibgp[afi][safi] = 0;
14408 bgp->distance_local[afi][safi] = 0;
14409 bgp_announce_routes_distance_update(bgp, afi, safi);
14410 }
14411 return CMD_SUCCESS;
14412 }
14413
14414
14415 DEFUN (bgp_distance_source,
14416 bgp_distance_source_cmd,
14417 "distance (1-255) A.B.C.D/M",
14418 "Define an administrative distance\n"
14419 "Administrative distance\n"
14420 "IP source prefix\n")
14421 {
14422 int idx_number = 1;
14423 int idx_ipv4_prefixlen = 2;
14424 bgp_distance_set(vty, argv[idx_number]->arg,
14425 argv[idx_ipv4_prefixlen]->arg, NULL);
14426 return CMD_SUCCESS;
14427 }
14428
14429 DEFUN (no_bgp_distance_source,
14430 no_bgp_distance_source_cmd,
14431 "no distance (1-255) A.B.C.D/M",
14432 NO_STR
14433 "Define an administrative distance\n"
14434 "Administrative distance\n"
14435 "IP source prefix\n")
14436 {
14437 int idx_number = 2;
14438 int idx_ipv4_prefixlen = 3;
14439 bgp_distance_unset(vty, argv[idx_number]->arg,
14440 argv[idx_ipv4_prefixlen]->arg, NULL);
14441 return CMD_SUCCESS;
14442 }
14443
14444 DEFUN (bgp_distance_source_access_list,
14445 bgp_distance_source_access_list_cmd,
14446 "distance (1-255) A.B.C.D/M WORD",
14447 "Define an administrative distance\n"
14448 "Administrative distance\n"
14449 "IP source prefix\n"
14450 "Access list name\n")
14451 {
14452 int idx_number = 1;
14453 int idx_ipv4_prefixlen = 2;
14454 int idx_word = 3;
14455 bgp_distance_set(vty, argv[idx_number]->arg,
14456 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14457 return CMD_SUCCESS;
14458 }
14459
14460 DEFUN (no_bgp_distance_source_access_list,
14461 no_bgp_distance_source_access_list_cmd,
14462 "no distance (1-255) A.B.C.D/M WORD",
14463 NO_STR
14464 "Define an administrative distance\n"
14465 "Administrative distance\n"
14466 "IP source prefix\n"
14467 "Access list name\n")
14468 {
14469 int idx_number = 2;
14470 int idx_ipv4_prefixlen = 3;
14471 int idx_word = 4;
14472 bgp_distance_unset(vty, argv[idx_number]->arg,
14473 argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
14474 return CMD_SUCCESS;
14475 }
14476
14477 DEFUN (ipv6_bgp_distance_source,
14478 ipv6_bgp_distance_source_cmd,
14479 "distance (1-255) X:X::X:X/M",
14480 "Define an administrative distance\n"
14481 "Administrative distance\n"
14482 "IP source prefix\n")
14483 {
14484 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
14485 return CMD_SUCCESS;
14486 }
14487
14488 DEFUN (no_ipv6_bgp_distance_source,
14489 no_ipv6_bgp_distance_source_cmd,
14490 "no distance (1-255) X:X::X:X/M",
14491 NO_STR
14492 "Define an administrative distance\n"
14493 "Administrative distance\n"
14494 "IP source prefix\n")
14495 {
14496 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
14497 return CMD_SUCCESS;
14498 }
14499
14500 DEFUN (ipv6_bgp_distance_source_access_list,
14501 ipv6_bgp_distance_source_access_list_cmd,
14502 "distance (1-255) X:X::X:X/M WORD",
14503 "Define an administrative distance\n"
14504 "Administrative distance\n"
14505 "IP source prefix\n"
14506 "Access list name\n")
14507 {
14508 bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
14509 return CMD_SUCCESS;
14510 }
14511
14512 DEFUN (no_ipv6_bgp_distance_source_access_list,
14513 no_ipv6_bgp_distance_source_access_list_cmd,
14514 "no distance (1-255) X:X::X:X/M WORD",
14515 NO_STR
14516 "Define an administrative distance\n"
14517 "Administrative distance\n"
14518 "IP source prefix\n"
14519 "Access list name\n")
14520 {
14521 bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
14522 return CMD_SUCCESS;
14523 }
14524
14525 DEFUN (bgp_damp_set,
14526 bgp_damp_set_cmd,
14527 "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
14528 "BGP Specific commands\n"
14529 "Enable route-flap dampening\n"
14530 "Half-life time for the penalty\n"
14531 "Value to start reusing a route\n"
14532 "Value to start suppressing a route\n"
14533 "Maximum duration to suppress a stable route\n")
14534 {
14535 VTY_DECLVAR_CONTEXT(bgp, bgp);
14536 int idx_half_life = 2;
14537 int idx_reuse = 3;
14538 int idx_suppress = 4;
14539 int idx_max_suppress = 5;
14540 int half = DEFAULT_HALF_LIFE * 60;
14541 int reuse = DEFAULT_REUSE;
14542 int suppress = DEFAULT_SUPPRESS;
14543 int max = 4 * half;
14544
14545 if (argc == 6) {
14546 half = atoi(argv[idx_half_life]->arg) * 60;
14547 reuse = atoi(argv[idx_reuse]->arg);
14548 suppress = atoi(argv[idx_suppress]->arg);
14549 max = atoi(argv[idx_max_suppress]->arg) * 60;
14550 } else if (argc == 3) {
14551 half = atoi(argv[idx_half_life]->arg) * 60;
14552 max = 4 * half;
14553 }
14554
14555 /*
14556 * These can't be 0 but our SA doesn't understand the
14557 * way our cli is constructed
14558 */
14559 assert(reuse);
14560 assert(half);
14561 if (suppress < reuse) {
14562 vty_out(vty,
14563 "Suppress value cannot be less than reuse value \n");
14564 return 0;
14565 }
14566
14567 return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
14568 reuse, suppress, max);
14569 }
14570
14571 DEFUN (bgp_damp_unset,
14572 bgp_damp_unset_cmd,
14573 "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
14574 NO_STR
14575 "BGP Specific commands\n"
14576 "Enable route-flap dampening\n"
14577 "Half-life time for the penalty\n"
14578 "Value to start reusing a route\n"
14579 "Value to start suppressing a route\n"
14580 "Maximum duration to suppress a stable route\n")
14581 {
14582 VTY_DECLVAR_CONTEXT(bgp, bgp);
14583 return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
14584 }
14585
14586 /* Display specified route of BGP table. */
14587 static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
14588 const char *ip_str, afi_t afi, safi_t safi,
14589 struct prefix_rd *prd, int prefix_check)
14590 {
14591 int ret;
14592 struct prefix match;
14593 struct bgp_dest *dest;
14594 struct bgp_dest *rm;
14595 struct bgp_path_info *pi;
14596 struct bgp_path_info *pi_temp;
14597 struct bgp *bgp;
14598 struct bgp_table *table;
14599
14600 /* BGP structure lookup. */
14601 if (view_name) {
14602 bgp = bgp_lookup_by_name(view_name);
14603 if (bgp == NULL) {
14604 vty_out(vty, "%% Can't find BGP instance %s\n",
14605 view_name);
14606 return CMD_WARNING;
14607 }
14608 } else {
14609 bgp = bgp_get_default();
14610 if (bgp == NULL) {
14611 vty_out(vty, "%% No BGP process is configured\n");
14612 return CMD_WARNING;
14613 }
14614 }
14615
14616 /* Check IP address argument. */
14617 ret = str2prefix(ip_str, &match);
14618 if (!ret) {
14619 vty_out(vty, "%% address is malformed\n");
14620 return CMD_WARNING;
14621 }
14622
14623 match.family = afi2family(afi);
14624
14625 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
14626 || (safi == SAFI_EVPN)) {
14627 for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
14628 dest = bgp_route_next(dest)) {
14629 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14630
14631 if (prd && memcmp(dest_p->u.val, prd->val, 8) != 0)
14632 continue;
14633 table = bgp_dest_get_bgp_table_info(dest);
14634 if (!table)
14635 continue;
14636 rm = bgp_node_match(table, &match);
14637 if (rm == NULL)
14638 continue;
14639
14640 const struct prefix *rm_p = bgp_dest_get_prefix(dest);
14641
14642 if (!prefix_check
14643 || rm_p->prefixlen == match.prefixlen) {
14644 pi = bgp_dest_get_bgp_path_info(rm);
14645 while (pi) {
14646 if (pi->extra && pi->extra->damp_info) {
14647 pi_temp = pi->next;
14648 bgp_damp_info_free(
14649 pi->extra->damp_info,
14650 1, afi, safi);
14651 pi = pi_temp;
14652 } else
14653 pi = pi->next;
14654 }
14655 }
14656
14657 bgp_dest_unlock_node(rm);
14658 }
14659 } else {
14660 dest = bgp_node_match(bgp->rib[afi][safi], &match);
14661 if (dest != NULL) {
14662 const struct prefix *dest_p = bgp_dest_get_prefix(dest);
14663
14664 if (!prefix_check
14665 || dest_p->prefixlen == match.prefixlen) {
14666 pi = bgp_dest_get_bgp_path_info(dest);
14667 while (pi) {
14668 if (pi->extra && pi->extra->damp_info) {
14669 pi_temp = pi->next;
14670 bgp_damp_info_free(
14671 pi->extra->damp_info,
14672 1, afi, safi);
14673 pi = pi_temp;
14674 } else
14675 pi = pi->next;
14676 }
14677 }
14678
14679 bgp_dest_unlock_node(dest);
14680 }
14681 }
14682
14683 return CMD_SUCCESS;
14684 }
14685
14686 DEFUN (clear_ip_bgp_dampening,
14687 clear_ip_bgp_dampening_cmd,
14688 "clear ip bgp dampening",
14689 CLEAR_STR
14690 IP_STR
14691 BGP_STR
14692 "Clear route flap dampening information\n")
14693 {
14694 bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
14695 return CMD_SUCCESS;
14696 }
14697
14698 DEFUN (clear_ip_bgp_dampening_prefix,
14699 clear_ip_bgp_dampening_prefix_cmd,
14700 "clear ip bgp dampening A.B.C.D/M",
14701 CLEAR_STR
14702 IP_STR
14703 BGP_STR
14704 "Clear route flap dampening information\n"
14705 "IPv4 prefix\n")
14706 {
14707 int idx_ipv4_prefixlen = 4;
14708 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
14709 AFI_IP, SAFI_UNICAST, NULL, 1);
14710 }
14711
14712 DEFUN (clear_ip_bgp_dampening_address,
14713 clear_ip_bgp_dampening_address_cmd,
14714 "clear ip bgp dampening A.B.C.D",
14715 CLEAR_STR
14716 IP_STR
14717 BGP_STR
14718 "Clear route flap dampening information\n"
14719 "Network to clear damping information\n")
14720 {
14721 int idx_ipv4 = 4;
14722 return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
14723 SAFI_UNICAST, NULL, 0);
14724 }
14725
14726 DEFUN (clear_ip_bgp_dampening_address_mask,
14727 clear_ip_bgp_dampening_address_mask_cmd,
14728 "clear ip bgp dampening A.B.C.D A.B.C.D",
14729 CLEAR_STR
14730 IP_STR
14731 BGP_STR
14732 "Clear route flap dampening information\n"
14733 "Network to clear damping information\n"
14734 "Network mask\n")
14735 {
14736 int idx_ipv4 = 4;
14737 int idx_ipv4_2 = 5;
14738 int ret;
14739 char prefix_str[BUFSIZ];
14740
14741 ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
14742 prefix_str, sizeof(prefix_str));
14743 if (!ret) {
14744 vty_out(vty, "%% Inconsistent address and mask\n");
14745 return CMD_WARNING;
14746 }
14747
14748 return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
14749 NULL, 0);
14750 }
14751
14752 static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
14753 {
14754 struct vty *vty = arg;
14755 struct peer *peer = bucket->data;
14756 char buf[SU_ADDRSTRLEN];
14757
14758 vty_out(vty, "\tPeer: %s %s\n", peer->host,
14759 sockunion2str(&peer->su, buf, sizeof(buf)));
14760 }
14761
14762 DEFUN (show_bgp_listeners,
14763 show_bgp_listeners_cmd,
14764 "show bgp listeners",
14765 SHOW_STR
14766 BGP_STR
14767 "Display Listen Sockets and who created them\n")
14768 {
14769 bgp_dump_listener_info(vty);
14770
14771 return CMD_SUCCESS;
14772 }
14773
14774 DEFUN (show_bgp_peerhash,
14775 show_bgp_peerhash_cmd,
14776 "show bgp peerhash",
14777 SHOW_STR
14778 BGP_STR
14779 "Display information about the BGP peerhash\n")
14780 {
14781 struct list *instances = bm->bgp;
14782 struct listnode *node;
14783 struct bgp *bgp;
14784
14785 for (ALL_LIST_ELEMENTS_RO(instances, node, bgp)) {
14786 vty_out(vty, "BGP: %s\n", bgp->name);
14787 hash_iterate(bgp->peerhash, show_bgp_peerhash_entry,
14788 vty);
14789 }
14790
14791 return CMD_SUCCESS;
14792 }
14793
14794 /* also used for encap safi */
14795 static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
14796 afi_t afi, safi_t safi)
14797 {
14798 struct bgp_dest *pdest;
14799 struct bgp_dest *dest;
14800 struct bgp_table *table;
14801 const struct prefix *p;
14802 const struct prefix_rd *prd;
14803 struct bgp_static *bgp_static;
14804 mpls_label_t label;
14805 char rdbuf[RD_ADDRSTRLEN];
14806
14807 /* Network configuration. */
14808 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14809 pdest = bgp_route_next(pdest)) {
14810 table = bgp_dest_get_bgp_table_info(pdest);
14811 if (!table)
14812 continue;
14813
14814 for (dest = bgp_table_top(table); dest;
14815 dest = bgp_route_next(dest)) {
14816 bgp_static = bgp_dest_get_bgp_static_info(dest);
14817 if (bgp_static == NULL)
14818 continue;
14819
14820 p = bgp_dest_get_prefix(dest);
14821 prd = (const struct prefix_rd *)bgp_dest_get_prefix(
14822 pdest);
14823
14824 /* "network" configuration display. */
14825 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14826 label = decode_label(&bgp_static->label);
14827
14828 vty_out(vty, " network %pFX rd %s", p, rdbuf);
14829 if (safi == SAFI_MPLS_VPN)
14830 vty_out(vty, " label %u", label);
14831
14832 if (bgp_static->rmap.name)
14833 vty_out(vty, " route-map %s",
14834 bgp_static->rmap.name);
14835
14836 if (bgp_static->backdoor)
14837 vty_out(vty, " backdoor");
14838
14839 vty_out(vty, "\n");
14840 }
14841 }
14842 }
14843
14844 static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
14845 afi_t afi, safi_t safi)
14846 {
14847 struct bgp_dest *pdest;
14848 struct bgp_dest *dest;
14849 struct bgp_table *table;
14850 const struct prefix *p;
14851 const struct prefix_rd *prd;
14852 struct bgp_static *bgp_static;
14853 char buf[PREFIX_STRLEN * 2];
14854 char buf2[SU_ADDRSTRLEN];
14855 char rdbuf[RD_ADDRSTRLEN];
14856 char esi_buf[ESI_BYTES];
14857
14858 /* Network configuration. */
14859 for (pdest = bgp_table_top(bgp->route[afi][safi]); pdest;
14860 pdest = bgp_route_next(pdest)) {
14861 table = bgp_dest_get_bgp_table_info(pdest);
14862 if (!table)
14863 continue;
14864
14865 for (dest = bgp_table_top(table); 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 char *macrouter = NULL;
14872
14873 if (bgp_static->router_mac)
14874 macrouter = prefix_mac2str(
14875 bgp_static->router_mac, NULL, 0);
14876 if (bgp_static->eth_s_id)
14877 esi_to_str(bgp_static->eth_s_id,
14878 esi_buf, sizeof(esi_buf));
14879 p = bgp_dest_get_prefix(dest);
14880 prd = (struct prefix_rd *)bgp_dest_get_prefix(pdest);
14881
14882 /* "network" configuration display. */
14883 prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
14884 if (p->u.prefix_evpn.route_type == 5) {
14885 char local_buf[PREFIX_STRLEN];
14886 uint8_t family = is_evpn_prefix_ipaddr_v4((
14887 struct prefix_evpn *)p)
14888 ? AF_INET
14889 : AF_INET6;
14890 inet_ntop(family,
14891 &p->u.prefix_evpn.prefix_addr.ip.ip.addr,
14892 local_buf, PREFIX_STRLEN);
14893 snprintf(buf, sizeof(buf), "%s/%u", local_buf,
14894 p->u.prefix_evpn.prefix_addr
14895 .ip_prefix_length);
14896 } else {
14897 prefix2str(p, buf, sizeof(buf));
14898 }
14899
14900 if (bgp_static->gatewayIp.family == AF_INET
14901 || bgp_static->gatewayIp.family == AF_INET6)
14902 inet_ntop(bgp_static->gatewayIp.family,
14903 &bgp_static->gatewayIp.u.prefix, buf2,
14904 sizeof(buf2));
14905 vty_out(vty,
14906 " network %s rd %s ethtag %u label %u esi %s gwip %s routermac %s\n",
14907 buf, rdbuf,
14908 p->u.prefix_evpn.prefix_addr.eth_tag,
14909 decode_label(&bgp_static->label), esi_buf, buf2,
14910 macrouter);
14911
14912 XFREE(MTYPE_TMP, macrouter);
14913 }
14914 }
14915 }
14916
14917 /* Configuration of static route announcement and aggregate
14918 information. */
14919 void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
14920 safi_t safi)
14921 {
14922 struct bgp_dest *dest;
14923 const struct prefix *p;
14924 struct bgp_static *bgp_static;
14925 struct bgp_aggregate *bgp_aggregate;
14926
14927 if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
14928 bgp_config_write_network_vpn(vty, bgp, afi, safi);
14929 return;
14930 }
14931
14932 if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
14933 bgp_config_write_network_evpn(vty, bgp, afi, safi);
14934 return;
14935 }
14936
14937 /* Network configuration. */
14938 for (dest = bgp_table_top(bgp->route[afi][safi]); dest;
14939 dest = bgp_route_next(dest)) {
14940 bgp_static = bgp_dest_get_bgp_static_info(dest);
14941 if (bgp_static == NULL)
14942 continue;
14943
14944 p = bgp_dest_get_prefix(dest);
14945
14946 vty_out(vty, " network %pFX", p);
14947
14948 if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
14949 vty_out(vty, " label-index %u",
14950 bgp_static->label_index);
14951
14952 if (bgp_static->rmap.name)
14953 vty_out(vty, " route-map %s", bgp_static->rmap.name);
14954
14955 if (bgp_static->backdoor)
14956 vty_out(vty, " backdoor");
14957
14958 vty_out(vty, "\n");
14959 }
14960
14961 /* Aggregate-address configuration. */
14962 for (dest = bgp_table_top(bgp->aggregate[afi][safi]); dest;
14963 dest = bgp_route_next(dest)) {
14964 bgp_aggregate = bgp_dest_get_bgp_aggregate_info(dest);
14965 if (bgp_aggregate == NULL)
14966 continue;
14967
14968 p = bgp_dest_get_prefix(dest);
14969
14970 vty_out(vty, " aggregate-address %pFX", p);
14971
14972 if (bgp_aggregate->as_set)
14973 vty_out(vty, " as-set");
14974
14975 if (bgp_aggregate->summary_only)
14976 vty_out(vty, " summary-only");
14977
14978 if (bgp_aggregate->rmap.name)
14979 vty_out(vty, " route-map %s", bgp_aggregate->rmap.name);
14980
14981 if (bgp_aggregate->origin != BGP_ORIGIN_UNSPECIFIED)
14982 vty_out(vty, " origin %s",
14983 bgp_origin2str(bgp_aggregate->origin));
14984
14985 if (bgp_aggregate->match_med)
14986 vty_out(vty, " matching-MED-only");
14987
14988 if (bgp_aggregate->suppress_map_name)
14989 vty_out(vty, " suppress-map %s",
14990 bgp_aggregate->suppress_map_name);
14991
14992 vty_out(vty, "\n");
14993 }
14994 }
14995
14996 void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
14997 safi_t safi)
14998 {
14999 struct bgp_dest *dest;
15000 struct bgp_distance *bdistance;
15001
15002 /* Distance configuration. */
15003 if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
15004 && bgp->distance_local[afi][safi]
15005 && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
15006 || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
15007 || bgp->distance_local[afi][safi]
15008 != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
15009 vty_out(vty, " distance bgp %d %d %d\n",
15010 bgp->distance_ebgp[afi][safi],
15011 bgp->distance_ibgp[afi][safi],
15012 bgp->distance_local[afi][safi]);
15013 }
15014
15015 for (dest = bgp_table_top(bgp_distance_table[afi][safi]); dest;
15016 dest = bgp_route_next(dest)) {
15017 bdistance = bgp_dest_get_bgp_distance_info(dest);
15018 if (bdistance != NULL)
15019 vty_out(vty, " distance %d %pBD %s\n",
15020 bdistance->distance, dest,
15021 bdistance->access_list ? bdistance->access_list
15022 : "");
15023 }
15024 }
15025
15026 /* Allocate routing table structure and install commands. */
15027 void bgp_route_init(void)
15028 {
15029 afi_t afi;
15030 safi_t safi;
15031
15032 /* Init BGP distance table. */
15033 FOREACH_AFI_SAFI (afi, safi)
15034 bgp_distance_table[afi][safi] = bgp_table_init(NULL, afi, safi);
15035
15036 /* IPv4 BGP commands. */
15037 install_element(BGP_NODE, &bgp_table_map_cmd);
15038 install_element(BGP_NODE, &bgp_network_cmd);
15039 install_element(BGP_NODE, &no_bgp_table_map_cmd);
15040
15041 install_element(BGP_NODE, &aggregate_addressv4_cmd);
15042
15043 /* IPv4 unicast configuration. */
15044 install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
15045 install_element(BGP_IPV4_NODE, &bgp_network_cmd);
15046 install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
15047
15048 install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
15049
15050 /* IPv4 multicast configuration. */
15051 install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
15052 install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
15053 install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
15054 install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
15055
15056 /* IPv4 labeled-unicast configuration. */
15057 install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
15058 install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
15059
15060 install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
15061 install_element(VIEW_NODE, &show_ip_bgp_cmd);
15062 install_element(VIEW_NODE, &show_ip_bgp_afi_safi_statistics_cmd);
15063 install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_statistics_cmd);
15064 install_element(VIEW_NODE, &show_ip_bgp_json_cmd);
15065 install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
15066 install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
15067 install_element(VIEW_NODE, &show_ip_bgp_statistics_all_cmd);
15068
15069 install_element(VIEW_NODE,
15070 &show_ip_bgp_instance_neighbor_advertised_route_cmd);
15071 install_element(VIEW_NODE,
15072 &show_ip_bgp_instance_neighbor_bestpath_route_cmd);
15073 install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
15074 install_element(VIEW_NODE,
15075 &show_ip_bgp_neighbor_received_prefix_filter_cmd);
15076 #ifdef KEEP_OLD_VPN_COMMANDS
15077 install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
15078 #endif /* KEEP_OLD_VPN_COMMANDS */
15079 install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
15080 install_element(VIEW_NODE,
15081 &show_bgp_l2vpn_evpn_route_prefix_cmd);
15082
15083 /* BGP dampening clear commands */
15084 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
15085 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
15086
15087 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
15088 install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
15089
15090 /* prefix count */
15091 install_element(ENABLE_NODE,
15092 &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
15093 #ifdef KEEP_OLD_VPN_COMMANDS
15094 install_element(ENABLE_NODE,
15095 &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
15096 #endif /* KEEP_OLD_VPN_COMMANDS */
15097
15098 /* New config IPv6 BGP commands. */
15099 install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
15100 install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
15101 install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
15102
15103 install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
15104
15105 install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
15106
15107 /* IPv6 labeled unicast address family. */
15108 install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
15109 install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
15110
15111 install_element(BGP_NODE, &bgp_distance_cmd);
15112 install_element(BGP_NODE, &no_bgp_distance_cmd);
15113 install_element(BGP_NODE, &bgp_distance_source_cmd);
15114 install_element(BGP_NODE, &no_bgp_distance_source_cmd);
15115 install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
15116 install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
15117 install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
15118 install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
15119 install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
15120 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
15121 install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
15122 install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
15123 install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
15124 install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
15125 install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
15126 install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
15127 install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
15128 install_element(BGP_IPV4M_NODE,
15129 &no_bgp_distance_source_access_list_cmd);
15130 install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
15131 install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
15132 install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
15133 install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
15134 install_element(BGP_IPV6_NODE,
15135 &ipv6_bgp_distance_source_access_list_cmd);
15136 install_element(BGP_IPV6_NODE,
15137 &no_ipv6_bgp_distance_source_access_list_cmd);
15138 install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
15139 install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
15140 install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
15141 install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
15142 install_element(BGP_IPV6M_NODE,
15143 &ipv6_bgp_distance_source_access_list_cmd);
15144 install_element(BGP_IPV6M_NODE,
15145 &no_ipv6_bgp_distance_source_access_list_cmd);
15146
15147 /* BGP dampening */
15148 install_element(BGP_NODE, &bgp_damp_set_cmd);
15149 install_element(BGP_NODE, &bgp_damp_unset_cmd);
15150 install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
15151 install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
15152 install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
15153 install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
15154 install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
15155 install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
15156 install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
15157 install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
15158 install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
15159 install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
15160 install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
15161 install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
15162
15163 /* Large Communities */
15164 install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
15165 install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
15166
15167 /* show bgp ipv4 flowspec detailed */
15168 install_element(VIEW_NODE, &show_ip_bgp_flowspec_routes_detailed_cmd);
15169
15170 install_element(VIEW_NODE, &show_bgp_listeners_cmd);
15171 install_element(VIEW_NODE, &show_bgp_peerhash_cmd);
15172 }
15173
15174 void bgp_route_finish(void)
15175 {
15176 afi_t afi;
15177 safi_t safi;
15178
15179 FOREACH_AFI_SAFI (afi, safi) {
15180 bgp_table_unlock(bgp_distance_table[afi][safi]);
15181 bgp_distance_table[afi][safi] = NULL;
15182 }
15183 }